Estamos ejecutando un sitio (Moodle) que los usuarios actualmente encuentran lento. Creo que he rastreado el problema hasta MySQL creando tablas temporales en el disco. Miro la variable created_tmp_disk_tables
en la administración del servidor Mysql Workbench y el número aumenta con aproximadamente 50 tablas / s. Después de un día de uso, created_tmp_disk_tables
es> 100k. Además, la memoria no parece ser liberada. El uso sigue aumentando hasta que el sistema se vuelve prácticamente inutilizable y tenemos que reiniciar MySQL. Necesito reiniciarlo casi todos los días y comienza con el uso de aproximadamente el 30-35% de la memoria disponible y termina el día con el 80%.
No tengo blobs en la base de datos y tampoco control sobre las consultas, así que no puedo intentar optimizarlas. También he usado el Asistente de confirmación de Percona para generar un archivo de configuración, pero my.ini tampoco resolvió mi problema.
Preguntas
¿Qué debo cambiar para evitar que MySQL cree tablas temporales en el disco? ¿Hay configuraciones que necesito cambiar? ¿Debería arrojarle más memoria?
¿Cómo puedo evitar que MySQL me coma la memoria?
Editar
Habilité el slow_queries
registro y descubrí que la consulta SELECT GET_LOCK()
se registró como lenta. Una búsqueda rápida reveló que había permitido conexiones persistentes en la configuración de PHP ( mysqli.allow_persistent = ON
). Apagué esto. Esto redujo la velocidad a la que MySQL consume memoria, aunque todavía está creando tablas temporales.
También verifiqué que key_buffer size
es lo suficientemente grande. Miré la variable key_writes
. Esto debería ser cero. Si no, aumente key_buffer_size
. Tengo cero key_reads
y cero, key_writes
así que supongo que key_buffer_size
es lo suficientemente grande.
Aumenté el tmp_table_size
y max-heap-table-size
al 1024M como un aumento en Created_tmp_disk_tables puede indicar que las tablas no pueden caber en la memoria. Esto no lo resolvió.
Editar 2
Si ve muchos sort_merge_passes
por segundo en la salida SHOW GLOBAL STATUS, puede considerar aumentar el sort_buffer_size
valor. Tenía 2 sort_merge_passes
en una hora, así que considero sort_buffer_size
que es lo suficientemente grande.
Ref: Mysql Manual sobre sort_buffer_size
Editar 3
He modificado la ordenación y unir buffers como lo sugiere @RolandoMySQLDBA. El resultado se muestra en la tabla a continuación, pero creo que created_tmp_tables_on_disk
todavía es alto. Reinicié el servidor mysql después de cambiar el valor y verifiqué created_tmp_tables_on_disk
después de un día (8h) y calculé el promedio. ¿Cualquier otra sugerencia? Me parece que hay algo que no cabe dentro de algún tipo de contenedor, pero no puedo entender qué es.
+---------------------+-------------+-------------+--------------------+
| Tmp_table_size, | Sort_buffer | Join_buffer | No of created |
| max_heap_table_size | | | tmp_tables on disk |
+---------------------+-------------+-------------+--------------------+
| 125M | 256K | 256K | 100k/h |
+---------------------+-------------+-------------+--------------------+
| 125M | 512K | 512K | 100k/h |
+---------------------+-------------+-------------+--------------------+
| 125M | 1M | 1M | 100k/h |
+---------------------+-------------+-------------+--------------------+
| 125M | 4M | 4M | 100k/h |
+---------------------+-------------+-------------+--------------------+
Esta es mi configuración:
+-----------------------+-----------------------+
|DATABASE SERVER |WEB SERVER |
+-----------------------+-----------------------+
|Windows Server 2008 R2 |Windows Server 2008 R2 |
+-----------------------+-----------------------+
|MySQL 5.1.48 |IIS 7.5 |
+-----------------------+-----------------------+
|4 Core CPU |4 Core CPU |
+-----------------------+-----------------------+
|4GB RAM |8GB RAM |
+-----------------------+-----------------------+
Información Adicional
+--------------------+---------+
|PARAM |VALUE |
+--------------------+---------+
|Num of tables in Db |361 |
+--------------------+---------+
|Size of database |2.5G |
+--------------------+---------+
|Database engine |InnoDB |
+--------------------+---------+
|Read/write ratio |3.5 |
|(Innodb_data_read/ | |
|innodb_data_written)| |
+--------------------+---------+
|Avg table size |15k rows |
+--------------------+---------+
|Max table size |744k rows|
+--------------------+---------+
Esta configuración me fue dada, así que tengo un control limitado sobre ella. El servidor web está usando muy poca CPU y RAM, así que he excluido esa máquina como un cuello de botella. La mayoría de la configuración de MySQL se origina en una herramienta de generación automática de configuración.
He monitoreado el sistema usando PerfMon durante algunos días representativos. A partir de eso, llego a la conclusión de que no es el sistema operativo el que está cambiando al disco.
My.ini
[client]
port=3306
[mysql]
default-character-set=utf8
[mysqld]
port=3306
basedir="C:/Program Files/MySQL/MySQL Server 5.1/"
datadir="D:/DBs/Data/"
default-character-set=utf8
default-storage-engine=INNODB
sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
max_connections=125
query_cache_size=350M
table_cache=1520
tmp_table_size=125M
table-definition-cache= 1024
max-heap-table-size= 32M
thread_cache_size=38
MyISAM Specific options
myisam_max_sort_file_size=100G
myisam_sort_buffer_size=125M
key_buffer_size=55M
read_buffer_size=1024K
read_rnd_buffer_size=256K
sort_buffer_size=1024K
join_buffer_size=1024K
INNODB Specific options
innodb_data_home_dir="D:/DBs/"
innodb_additional_mem_pool_size=32M
innodb_flush_log_at_trx_commit=1
innodb_log_buffer_size=16M
innodb_buffer_pool_size=2G
innodb_log_file_size=407M
innodb_thread_concurrency=8
fuente
Respuestas:
Mirando el
my.ini
, tengo dos sugerenciasSUGERENCIA # 1
Me gustaría subir la siguiente configuración en su
my.ini
Esto hará que algunas uniones y clasificaciones permanezcan en la memoria. Por supuesto, una vez que a
JOIN
o aORDER BY
necesite más que4M
, se paginará en el disco como una tabla MyISAM.Si no puede iniciar sesión como
root@localhost
, reinicie mysql conSi puede iniciar sesión como root @ localhost, no tiene que reiniciar mysql para usar esta configuración.
Simplemente ejecute esto en el cliente MySQL:
SUGERENCIA # 2
Como sus datos están en la unidad
D:
, es posible que tenga E / S de disco en la unidadC:
.Por favor ejecute esta consulta:
Como ejecuto mysql en mi escritorio con los valores predeterminados, mis tablas temporales se escriben en Drive
C:
. Si Drive D es un mejor disco que DriveC:
, quizás pueda asignar tablas temporales a DriveD:
configurando tmpdir de lamy.ini
siguiente manera:Deberá reiniciar mysql ya que tmpdir no es una variable dinámica.
Darle una oportunidad !!!
ACTUALIZACIÓN 2013-11-29 10:09 EST
SUGERENCIA # 3
Dado el hecho de que MySQL se está ejecutando en Windows y no puede tocar las consultas en el paquete principal, tengo dos ideas que deben hacerse juntas.
IDEA # 1: mover la base de datos a una máquina Linux
Deberias ser capaz de
IDEA # 2: reconfigurar Moodle para que apunte a la máquina Linux
Moodle fue diseñado para LAMP en primer lugar. Simplemente cambie los archivos de configuración para apuntar a la máquina Linux en lugar de localhost.
Aquí hay un enlace a un antiguo documento de Moodle 2.3 sobre la configuración de MySQL: http://docs.moodle.org/23/en/Installing_Moodle#Create_an_empty_database
Estoy seguro de que los últimos documentos también están disponibles.
¿Cuál es el punto de mover la base de datos a Linux?
¿Cómo ayuda esto a la situación de la tabla temporal?
Entonces sugeriría configurar un disco RAM como la carpeta de destino para sus tablas temporales
Jan 04, 2013
: ¿Existe un motor o truco MySQL para evitar escribir tantas tablas temporales en el disco?Dec 17, 2012
: ¿Por qué MySQL produce tantos archivos MYD temporales? (Instrucciones reales)Nov 30, 2012
: ¿Es malo crear muchas tablas temporales mysql simultáneamente?La creación de la tabla temporal seguirá sucediendo, pero se escribirá en la RAM en lugar de en el disco. Reducción de E / S de disco.
ACTUALIZACIÓN 2013-11-29 11:24 EST
SUGERENCIA # 4
Sugeriría volver a visitar la SUGERENCIA # 2 con un disco RAID-0 rápido (32+ GB), configurándolo como Unidad T: (T para Temp). Después de instalar dicho disco, agregue esto a
my.ini
:Se requeriría reiniciar MySQL, usando
Por cierto, dije RAID-0 a propósito para que pueda obtener un buen rendimiento de escritura sobre un RAID-1, RAID-10. Un disco de tabla tmp no es algo que haría redundante.
Sin optimizar las consultas como ha estado comentando @RaymondNijland, no puede reducir el recuento de creación de la tabla temporal de ninguna manera.
SUGGESTION #3
ySUGGESTION #4
ofrecen acelerar la creación de la tabla temporal y la E / S de la tabla temporal como la única alternativa.fuente
Respondo mi propia pregunta aquí para completar
Seleccionaré @RolandoMySQLDBA como la respuesta preferida porque me dio la mayor cantidad de pistas aunque en realidad no resolvió mi problema.
A continuación se muestran los resultados de mi investigación.
Conclusión
MySQL en Windows solo crea muchas tablas temporales y ajustar MySQL modificando el contenido de los archivos de configuración no ayudó.
Detalles
La tabla detalla los parámetros que he modificado en my.ini respectivamente antes de ejecutar cualquier consulta. MySQL se reinició entre cada prueba.
Usé el my.ini que se encuentra en la pregunta original como plantilla y luego cambié el valor de los parámetros uno por uno de acuerdo con la tabla a continuación.
Solía JMeter para generar 100 peticiones web concurrentes (como el representado nuestro uso) se repiten de 10 diez veces. Cada uno
Test
constaba de 1000 solicitudes en total. Esto dio lugar a posteriores llamadas a la base de datos. Esto demostró que MySQL crearía muchas tablas temporales independientemente de los parámetros de configuración que cambiémos.* Promedio de tres carreras
Las siguientes imágenes muestran la cantidad de memoria y CPU que el servidor de base de datos requiere para las diferentes configuraciones. Las líneas negras indican los valores mínimos y máximos y las barras azules indican los valores inicial y final. La memoria máxima fue la
4096M
indicada en la pregunta.fuente