Por que o MySQL produz tantos arquivos MYD temporários?

9

Em um servidor Debian Linux, hospedando muitos sites PHP / MySQL (galerias de fotos), às vezes tenho "muitos" arquivos como /tmp/#sql_6405_58.MYD.

Por exemplo hoje:

[2012-12-15 15:18:11] /tmp/#sql_6405_6.MYD : 88MB
[2012-12-15 15:18:11] /tmp/#sql_6405_3.MYD : 22MB
[2012-12-15 15:18:11] /tmp/#sql_6405_4.MYD : 138MB
[2012-12-15 15:18:11] /tmp/#sql_6405_10.MYD : 88MB
...
[2012-12-15 15:18:11] /tmp/#sql_6405_9.MYD : 15MB
[2012-12-15 15:18:11] /tmp/#sql_6405_65.MYD : 49MB
[2012-12-15 15:18:11] /tmp/#sql_6405_44.MYD : 69MB

(59 arquivos ao mesmo tempo, por mais de 6 GB ... sim, eu monito arquivos grandes em / tmp)

Infelizmente, /tmpestá na mesma partição /e interrompe temporariamente o servidor web, porque /está cheio, suponho. Os arquivos desaparecem e o servidor volta ao normal.

Todos os nomes de arquivos seguem o #sql_6405_*.MYDpadrão. Gostaria de entender qual operação do MySQL implica tantos arquivos temporários. Eu tenho aproximadamente 2000 bancos de dados neste servidor. É possível saber qual banco de dados está em causa?

RolandoMySQLDBA
fonte
11
Suponho que sejam dados temporários para grandes operações que usam filesort, e 6405 é o PID do mysql para manter os arquivos temporários de diferentes instâncias do servidor separados.
Devo pedir a um administrador para mover minha pergunta?

Respostas:

14

Existem algumas opções que podem fazer com que as tabelas temporárias se materializem como tabelas MyISAM ou podem ser configuradas para atrasá-las. Tenha em mente que, para tabelas temporárias com base em disco, não há .frmarquivos, mas somente .MYDe .MYIarquivos (de curso. Arquivo .MYI nunca é usada, uma vez que é o índice impossível uma tabela temporária interna).

Aqui estão as opções:

Você também deve considerar a documentação do MySQL sobre o uso da tabela temporária interna

As situações em que são criadas tabelas temporárias na memória são

  • Se houver uma cláusula ORDER BY e uma cláusula GROUP BY diferente, ou se a ORDER BY ou GROUP BY contiver colunas de tabelas diferentes da primeira tabela na fila de junção, uma tabela temporária será criada.
  • DISTINCT combinado com ORDER BY pode exigir uma tabela temporária.
  • Se você usar a opção SQL_SMALL_RESULT, o MySQL usará uma tabela temporária na memória, a menos que a consulta também contenha elementos (descritos mais adiante) que requerem armazenamento em disco.

Quando uma tabela temporária na memória excede o mínimo de (tmp_table_size ou max_heap_table_size), o mysqld faz o seguinte:

  • Suspende a consulta
  • Copia o conteúdo da tabela na memória para uma tabela temporária MyISAM
  • Descarta a tabela na memória
  • Continua a consulta, enviando os dados temporários para a tabela temporária MyISAM

As situações em que as tabelas temporárias na memória são ignoradas em favor do disco são

  • Presença de uma coluna BLOB ou TEXT na tabela
  • Presença de qualquer coluna em uma cláusula GROUP BY ou DISTINCT maior que 512 bytes
  • Presença de qualquer coluna maior que 512 bytes na lista SELECT, se UNION ou UNION ALL for usado

É necessária alguma diligência para reduzir a criação da tabela temporária no disco

  • Definindo join_buffer_size maior
  • Definir sort_buffer_size maior
  • Definindo tmp_table_size e max_heap_table_size maior
  • Ajustando consultas para minimizar ou mesmo impedir tabelas temporárias
  • Criando índices para criar visualização pré-classificada de dados de tabelas individuais
  • Instalando RAM adicional para acomodar grandes tabelas temporárias na memória

Se após essa devida diligência, ainda houver tabelas temporárias sendo formadas no Disco, aqui está uma jogada desesperada: Mapeando a criação da tabela temporária baseada em disco na memória.

Aqui está uma maneira rápida e suja de configurar um disco de 16 GB de RAM usando tmpdir

PASSO01) Criar pasta de disco RAM

mkdir /var/mysql_tmpfs

STEP02) Adicione isso ao my.cnf

[mysqld]
tmpdir=/var/mysql_tmpfs

PASSO03) Adicione isso ao / etc / fstab

echo "none /var/mysql_tmpfs tmpfs defaults,size=16g 1 2" >> /etc/fstab

PASSO04) Recarregar / etc / fstab

mount -a

PASSO05) service mysql restart

Depois disso, todas as tabelas temporárias que se tornam MyISAM são gravadas no disco RAM. Isso deve acelerar a criação da tabela temporária baseada em disco.

De uma chance !!!

RolandoMySQLDBA
fonte
1

Essas são consultas que estão sendo transferidas para o disco porque os resultados são muito grandes para memória.

Quando a consulta é concluída, o espaço é limpo.

Não há como corresponder definitivamente esses arquivos temporários às consultas, mas você pode obter dicas para adivinhar em SHOW FULL PROCESSLIST; ou MOSTRAR ESTADO DE INNODB; ou procurando no seu log de erros se as consultas falharem.

Valerie Parham-Thompson
fonte
1

Sempre que usamos instruções alter na tabela, ele cria os arquivos temporários # sql_6405_3.MYD e, uma vez feito, lança a saída e desaparece.

As alterações nas tabelas fazem com que o MySQL copie dados inteiros em arquivos temporários # sql.xxx.MYD e faça alterações nos arquivos temporários criados, depois solte os arquivos de dados originais tablename.MYD e renomeie os arquivos temporários para o nome da tabela.

Também para algumas consultas de classificação, ele cria arquivos temporários.

Enquanto eu traçava. Isso acontece.

Vinay
fonte
0

Acho que você pode encontrar as consultas em questão no log de consultas lentas, uma vez que as consultas que criam grandes tabelas temporárias geralmente são executadas por um longo período de tempo, foi assim que isso me ajudou hoje em um servidor em que achei a /tmppartição cheia por causa de um problema semelhante. grande arquivo temporário do MySQL, era um arquivo 4G, eu encontrei a consulta no log de consultas lentas e relatei a consulta aos desenvolvedores e eles encontraram a corrupção na consulta e eles a corrigem, parece lagos para uma instrução MySQL com limite, por isso foi executada por um longo tempo e escreveu um arquivo temporário 4G e preencheu a /tmppartição.

E há outra maneira de descobrir o que causou esse grande arquivo temporário, que é binário, de modo que você não pode lê-lo diretamente, mas eu descobri que você pode fazer o grep do texto contido nele, usando o comando Linux como este,

strings name-of-mysql-temp-file

Assegurei-me das palavras do texto que a consulta MySQL executava e a criei.

linuxman1
fonte