Arquivo chave incorreto do MySQL para a tabela tmp ao fazer várias junções

Eu não venho aqui pedir ajuda frequentemente, mas estou muito frustrado com isso e espero que alguém tenha encontrado isso antes.

Sempre que eu tento buscar registros de uma tabela usando mais de uma junit, recebo este erro:

#126 - Incorrect key file for table '/tmp/#sql_64d_0.MYI'; try to repair it 

Portanto, esta consulta produzirá o erro:

 SELECT * FROM `core_username` INNER JOIN `core_person` ON (`core_username`.`person_id` = `core_person`.`id`) INNER JOIN `core_site` ON (`core_username`.`site_id` = `core_site`.`id`) ORDER BY `core_username`.`name` ASC LIMIT 1 

Mas este não vai:

 SELECT * FROM `core_username` INNER JOIN `core_person` ON (`core_username`.`person_id` = `core_person`.`id`) ORDER BY `core_username`.`name` ASC LIMIT 1 

E nem este vai:

 SELECT * FROM `core_username` INNER JOIN `core_site` ON (`core_username`.`site_id` = `core_site`.`id`) ORDER BY `core_username`.`name` ASC LIMIT 1 

O que poderia estar causando isso? Eu realmente não sei como ir sobre como reparar uma tabela de tmp, mas eu realmente não acho que é o problema, pois é uma nova tabela de tmp cada vez. A tabela de nome de usuário é bastante grande (233.718 registros agora), mas duvido que tenha algo a ver com isso.

Qualquer ajuda seria muito apreciada.

ATUALIZAÇÃO : Depois de alguns testes adicionais, parece que o erro só acontece quando tento pedir os resultados. Ou seja, essa consulta me dará o que eu espero:

 SELECT * FROM `core_username` INNER JOIN `core_person` ON (`core_username`.`person_id` = `core_person`.`id`) INNER JOIN `core_site` ON (`core_username`.`site_id` = `core_site`.`id`) LIMIT 1 

Mas se eu adicionar o:

 ORDER BY `core_username`.`name` ASC 

O erro é acionado. Isso está acontecendo apenas no servidor da Web específico que estou usando no momento. Se eu baixar o database e tentar a mesma coisa no meu localhost, bem como outros servidores, ele funcionará bem. A versão do MySQL é 5.0.77.

Sabendo disso, estou bastante confiante de que o que está acontecendo é que a tabela tmp que está sendo criada é muito grande e o MySQL engasga como descrito neste post do blog . Ainda não tenho certeza qual seria a solução, embora …

Às vezes, quando esse erro acontece com tabelas temporárias:

 #126 - Incorrect key file for table '/tmp/#sql_64d_0.MYI'; try to repair it 

Pode ser porque a pasta /tmp está ficando sem espaço. Em algumas instalações do Linux, o /tmp está em sua própria partição e não tem muito espaço – grandes consultas do MySQL irão preenchê-lo.

Você pode usar df -h para verificar se o \tmp está em sua própria partição e quanto espaço está alocado para ele.

Se estiver em sua própria partição e com pouco espaço, você poderá:

(a) modificar / tmp para que sua parição tenha mais espaço (seja realocando ou movendo para a partição principal – por exemplo, veja aqui )
(b) alterar a configuração do MySql para que use uma pasta temporária diferente em uma partição diferente, por exemplo, /var/tmp

Verifique o espaço disponível do MySQL tmpdir (/ tmp no seu caso) enquanto executa as consultas, já que ele pode consumir centenas de MBs ao trabalhar com tabelas grandes. Algo assim funcionou para mim:

 $ while true; do df -h /tmp; sleep .5; done 

Rode isto

 REPAIR TABLE `core_username`,`core_site`,`core_person`; 

ou faça isso:

 select * from ( SELECT * FROM `core_username` INNER JOIN `core_person` ON (`core_username`.`person_id` = `core_person`.`id`) INNER JOIN `core_site` ON (`core_username`.`site_id` = `core_site`.`id`) LIMIT 1) ORDER BY `name` ASC 

Eu tive esse problema com uma consulta em uma tabela que tinha 500 K + registros. Ele estava me dando o mesmo tipo exato de erro, apontando para um arquivo .MYI no diretório / tmp que raramente estava lá na verificação. Eu já tinha aumentado os tamanhos de arquivo heap e temporário no arquivo /etc/my.cnf.

O problema com a consulta foi o fato de ele conter uma cláusula ORDER no final, omitindo-a fez a consulta funcionar sem erros. Também tinha um limite. Eu estava tentando ver os 5 registros mais recentes da tabela. Com a cláusula ORDER incluída, engasgou e deu o erro.

O que estava acontecendo era que o mysqld estava criando uma tabela temporária interna com TODOS os registros da tabela gigante para aplicar o ORDER.

A maneira que eu tenho em torno disso é aplicar uma condição WHERE adicional, limitando os registros da tabela gigante para um conjunto menor. Eu convenientemente tive um campo de data e hora para fazer a filtragem de.

Espero que ajude alguém.

Você pode achar que a execução de “ANALYZE TABLE” ajuda.

Tivemos esse problema de repente aparecendo em uma tabela grande (~ 100M linhas) e o MySQL tentou usar / tmp para escrever uma tabela temporária de mais de 1GB, que falhou porque / tmp estava limitado a ~ 600M.

Descobriu-se que as statistics da tabela InnoDB eram bastante obsoletas. Depois de executar “ANALYZE TABLE …”, as statistics foram atualizadas e o problema foi resolvido. Com as statistics mais precisas, o MySQL foi capaz de otimizar a consulta corretamente e o grande arquivo tmp não era mais necessário.

Agora rodamos “mysqlcheck -Aa” periodicamente para manter todas as statistics da tabela atualizadas.

No Unix, o MySQL usa o valor da variável de ambiente TMPDIR como o nome do caminho do diretório no qual armazenar arquivos temporários. Se o TMPDIR não estiver configurado, o MySQL usa o padrão do sistema, que normalmente é / tmp, / var / tmp ou / usr / tmp.

No Windows, Netware e OS2, o MySQL verifica em ordem os valores das variables ​​de ambiente TMPDIR, TEMP e TMP. Para o primeiro encontrado para ser definido, o MySQL usa e não verifica os restantes. Se nenhum de TMPDIR, TEMP ou TMP estiver configurado, o MySQL utilizará o padrão do sistema Windows, que geralmente é C: \ windows \ temp.

Se o sistema de arquivos contendo seu diretório de arquivos temporários for muito pequeno, você pode usar a opção –tmpdir para o mysqld para especificar um diretório em um sistema de arquivos onde você tenha espaço suficiente .

No MySQL 5.0, a opção –tmpdir pode ser configurada para uma lista de vários caminhos que são usados ​​no modo round-robin. Os caminhos devem ser separados por caracteres de dois-pontos (“:”) nos caracteres Unix e ponto e vírgula (“;”) no Windows, NetWare e OS / 2.

Eu tenho o mesmo problema.

Aqui está a minha solução: 1. Não use “select *”. Basta selecionar o campo que você precisa. 2. Divida a consulta. Se o campo selecionado for muito, a divisão em alguma consulta pode ser um resultado. Você pode “array_merge ()” o resultado mais tarde se quiser que a variável que contém o resultado não seja alterada.

No meu caso, divido a consulta em 5 consultas e, em seguida, a matriz mescla usando o PHP.

O problema está no servidor mysql. É apenas uma coisa que o desenvolvedor de aplicativos (como eu) não tem um previlégio.

Eu tive problema semelhante. No meu próprio caso, o problema ocorreu devido ao proprietário / permissão incorreta. Eu só tive que mudar o dono do meu diretório de dados para o usuário mysql e isso resolveu o problema.

Apenas aumente o arquivo tmp, pois o mysql não tem espaço nele, para consultas …

 mount -o remount,size=[NEW MAX SIZE HERE] tmpfs /tmp 

Referência de links:

Erro geral: 126 Arquivo de chave incorreto para a tabela ‘/tmp/#sql_254c_0.MYI’; tente consertá-lo

[ERRO] / usr / sbin / mysqld: Arquivo de chaves incorreto para a tabela ‘/mysqltmp/#sql_ca1a_0.MYI’; tente consertá-lo

Como aumentar o tamanho da partição / tmp

as chaves de índice de uma das três tabelas podem estar ruins, tente executar um comando de reparo nas três tabelas.

Usar a palavra-chave EXPLAIN pode ajudar a descobrir como otimizar melhor essa consulta. Essencialmente, o que você precisa fazer é obter o conjunto de resultados o menor possível o mais rápido possível. Se você tiver um conjunto de resultados de cada linha no core_username até o final, quando você fizer o pedido, você corre o risco de … isso.

Se você puder fazer o pedido no core_username sozinho sem um problema, você pode querer obter a linha min () como uma subconsulta.