¿Por qué MySQL produce tantos archivos MYD temporales?

9

En un servidor Debian Linux, que aloja muchos sitios web PHP / MySQL (galerías de fotos), a veces tengo "muchos" archivos como /tmp/#sql_6405_58.MYD.

Por ejemplo hoy:

[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 archivos al mismo tiempo, durante más de 6 GB ... sí, monitorizo ​​archivos grandes en / tmp)

Desafortunadamente, /tmpestá en la misma partición que /y temporalmente rompe el servidor web, porque /está lleno, supongo. Luego los archivos desaparecen y el servidor vuelve a la normalidad.

Todos los nombres de archivo siguen el #sql_6405_*.MYDpatrón. Me gustaría entender qué operación de MySQL implica tantos archivos temporales. Tengo aproximadamente 2000 bases de datos en este servidor. ¿Es posible saber qué base de datos se refiere?

RolandoMySQLDBA
fuente
1
Supongo que son datos temporales para operaciones grandes que usan filesort, y 6405 es el PID de mysql para mantener separados los archivos temporales de diferentes instancias de servidor.
¿Debo pedirle a un administrador que mueva mi pregunta?

Respuestas:

14

Hay algunas opciones que pueden hacer que las tablas temporales se materialicen como tablas MyISAM o pueden configurarse para retrasarlo. Tenga en cuenta que para las tablas temporales basados en disco, no hay .frmarchivos, pero sólo .MYDy .MYIarchivos (por supuesto. .MYI el archivo no se usa nunca, ya que es imposible índice de una tabla de temperatura interna).

Aquí están las opciones:

También debe considerar la documentación de MySQL sobre el uso interno de la tabla temporal

Las situaciones en las que se hacen tablas temporales en memoria son

  • Si hay una cláusula ORDER BY y una cláusula GROUP BY diferente, o si ORDER BY o GROUP BY contiene columnas de tablas distintas de la primera tabla en la cola de unión, se crea una tabla temporal.
  • DISTINCT combinado con ORDER BY puede requerir una tabla temporal.
  • Si usa la opción SQL_SMALL_RESULT, MySQL usa una tabla temporal en memoria, a menos que la consulta también contenga elementos (descritos más adelante) que requieren almacenamiento en disco.

Cuando una tabla temporal en memoria excedió el mínimo de (tmp_table_size o max_heap_table_size), mysqld hace lo siguiente:

  • Suspende la consulta.
  • Copia el contenido de la tabla en memoria en una tabla temporal MyISAM
  • Descarta la tabla en memoria
  • Continúa la consulta, enviando los datos temporales a la tabla temporal MyISAM

Las situaciones en las que las tablas temporales en memoria se omiten en favor del disco son

  • Presencia de una columna BLOB o TEXT en la tabla
  • Presencia de cualquier columna en una cláusula GROUP BY o DISTINCT de más de 512 bytes
  • Presencia de cualquier columna de más de 512 bytes en la lista SELECT, si se utiliza UNION o UNION ALL

Se requiere cierta diligencia debida para reducir la creación de la tabla temporal en el disco

  • Configuración de join_buffer_size más grande
  • Establecer sort_buffer_size más grande
  • Establecer tmp_table_size y max_heap_table_size más grande
  • Ajuste de consultas para minimizar o incluso prevenir tablas temporales
  • Crear índices para crear una vista preestablecida de datos de tablas individuales
  • Instalación de RAM adicional para acomodar grandes tablas temporales en memoria

Si después de dicha diligencia debida, todavía se están formando tablas temporales en el Disco, aquí hay un movimiento desesperado: Mapear la creación de la tabla temporal basada en disco a la memoria.

Aquí hay una manera rápida y sucia de configurar un disco RAM de 16GB usando tmpdir

PASO01) Crear carpeta de disco RAM

mkdir /var/mysql_tmpfs

STEP02) Añadir esto a my.cnf

[mysqld]
tmpdir=/var/mysql_tmpfs

PASO03) Agregue esto a / etc / fstab

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

PASO04) Recargar / etc / fstab

mount -a

PASO05) service mysql restart

Después de esto, todas las tablas temporales que se convierten en MyISAM se escriben en el disco RAM. Esto debería acelerar la creación de la tabla temporal basada en disco.

Darle una oportunidad !!!

RolandoMySQLDBA
fuente
1

Estas son consultas que se transfieren al disco porque los resultados son demasiado grandes para la memoria.

Cuando finaliza la consulta, el espacio se borra.

No hay forma de hacer coincidir estos archivos temporales definitivamente con las consultas, pero puede obtener pistas para adivinar en SHOW FULL PROCESSLIST; o MOSTRAR ESTADO INNODB; o mirando en su registro de errores si las consultas fallan.

Valerie Parham-Thompson
fuente
1

Cada vez que utilizamos las declaraciones alter en la tabla, crea los archivos de temporay # sql_6405_3.MYD y una vez hecho esto arroja la salida y desaparece.

Alterar las tablas hace que MySQL copie datos completos en archivos temporales # sql.xxx.MYD y realice cambios en los archivos temporales creados, luego suelte los archivos de datos originales tablename.MYD y cambie el nombre de los archivos temporay al nombre de la tabla.

También para algunas consultas de clasificación crea archivos temporales.

Como lo rastreé. Esta cosa pasa.

Vinay
fuente
0

Creo que puede encontrar las consultas en cuestión en el registro lento de consultas, ya que las consultas que crean grandes tablas temporales generalmente se ejecutan durante mucho tiempo, así es como eso me ayudó hoy en un servidor donde encontré que la /tmppartición está llena debido a un problema similar gran archivo temporal de MySQL, era un archivo 4G, encontré la consulta en el registro lento de consultas e informé la consulta a los desarrolladores y encontraron la corrupción en la consulta y la solucionarán, parece que no hay una instrucción MySQL limitada, por lo que se ejecutó durante mucho tiempo y escribió un archivo temporal 4G y completó la /tmppartición.

Y hay otra forma en que puede encontrar la causa de este gran archivo temporal, es binario, por lo que no puede leerlo directamente, pero descubrí que puede manipular el texto que contiene usando el comando Linux de cadenas como este,

strings name-of-mysql-temp-file

Me aseguré de las palabras de texto que ejecutaba la consulta MySQL y la creé.

linuxman1
fuente