Se me presentaron algunos servidores MySQL dedicados que nunca usan más de un núcleo. Soy más desarrollador que DBA para MySQL, así que necesito ayuda
Preparar
Los servidores son bastante pesados con una carga de tipo OLAP / DataWarehouse (DW):
- Primario: 96 GB de RAM, 8 núcleos + matriz RAID 10 única
- Prueba: 32 GB de RAM con 4 núcleos
- El DB más grande es de 540 GB, el total es de alrededor de 1.1TB y en su mayoría tablas de InnoDB
- Solaris 10 Intel-64
- MySQL 5.5.x
Nota: El DB más grande es el replicado del servidor OLTP DR y el DW se carga desde este. No es un DW completo: solo dura entre 6 meses y 6 semanas, por lo que es más pequeño que el DB OLTP.
Observaciones en un servidor de prueba
- 3 conexiones separadas
- cada uno tiene un concurrente (y diferente)
ALTER TABLE...DROP KEY...ADD INDEX
- las 3 tablas tienen 2.5, 3.8 y 4.5 millones de filas
- El uso de la CPU sube al 25% (un núcleo está al máximo) y no más
- Los 3 ALTERS toman de 12 a 25 minutos (un solo en el más pequeño toma 4.5)
Preguntas
- ¿Qué configuración o parche se requiere para permitir que se use más de un núcleo?
Es decir, ¿por qué MySQL no usa todos los núcleos disponibles? (como otros RDBMS) - ¿Es consecuencia de la replicación?
Otras notas
- Entiendo la diferencia entre un "hilo" RDBMS y un "hilo" del sistema operativo
- No estoy preguntando sobre ninguna forma de paralelismo
- Algunas de las variables del sistema para InnoDB y los subprocesos son subóptimas
(en busca de una ganancia rápida) - A corto plazo, no puedo cambiar el diseño del disco
- El sistema operativo se puede modificar si es necesario
- Una sola TABLA DE ALTERACIÓN en la mesa más pequeña toma 4.5 minutos (IMO impactante)
Editar 1
- innodb_thread_concurrency se establece en 8 en ambos. Sí, está mal, pero no hará que MySQL use múltiples núcleos
- innodb_buffer_pool_size tiene 80 GB en primaria, 10 GB en una prueba (se cierra otra instancia). Esto está bien por ahora.
- innodb_file_per_table = ON
Editar 2
- innodb_flush_log_at_trx_commit = 2
- innodb_use_sys_malloc = ON
- innodb_flush_method debería ser O_DIRECT (pero SHOW VARIABLES no muestra esto)
- innodb_doublewrite = OFF
- Sistema de archivos = ZFS (y mi administrador de sistemas encontró esto: http://blogs.oracle.com/realneel/entry/mysql_innodb_zfs_best_practices )
Probar
- innodb_flush_method no se muestra como O_DIRECT cuando debería ser
- seguirá la configuración de RolandoMySQLDBA
Avísame si me he perdido algo importante
Salud
Actualizar
Cambió innodb_flush_method + 3 x configuraciones de hilo en la respuesta de RolandoMySQLDBA
Resultado:> 1 núcleo utilizado para las pruebas = resultado positivo
\G
. Además, creo queSHOW INNODB STATUS
está en desuso a favor deSHOW ENGINE INNODB STATUS
5.5 ( aparece un error al ejecutar el primero en la línea de comandos.)Respuestas:
De hecho, discutí innodb_thread_concurrency con un experto de MySQL en la conferencia Percona Live NYC en mayo de 2011 .
Aprendí algo sorprendente: a pesar de la documentación, es mejor dejarlo
innodb_thread_concurrency
en 0 (concurrencia infinita). De esa manera, InnoDB decide el mejor número deinnodb_concurrency_tickets
abrir para una configuración de instancia de MySQL dada.Una vez que establece
innodb_thread_concurrency
en 0, puede establecerinnodb_read_io_threads
yinnodb_write_io_threads
(ambos desde MySQL 5.1.38) al valor máximo de 64. Esto debería involucrar más núcleos.fuente
my.cnf
y reinicie mysqld. Por favor.MySQL usará automáticamente múltiples núcleos, por lo que su carga del 25% es coincidencia 1 o una posible configuración incorrecta en Solaris. No voy a pretender saber cómo sintonizar solaris, pero aquí hay un artículo que trata sobre información de ajuste específica de solaris .
Las páginas de ajuste de InnoDB han sido revisadas en MySQL 5.5, por lo que también hay buena información. Desde el disco InnoDB consejos de E / S :
Algunas otras cosas para verificar:
Vale la pena probar cambiar el innodb_flush_method a O_DIRECT. Si esto ayuda, es posible que deba montar el sistema de archivos con la
forcedirectio
opciónCambie innodb_flush_log_at_trx_commit de 1 a 0 (si no le importa perder el último segundo en el bloqueo de mysql) o 2 (si no le importa perder el último segundo en el bloqueo del sistema operativo).
Verifique el valor de innodb_use_sys_malloc . Este artículo tiene más información sobre la variable.
Pero hay algunas advertencias al final de la sección sobre lo que significa activar la variable (está activada por defecto en 5.5).
Es posible que la replicación esté causando parte del problema. Me doy cuenta de que no estás interesado en el paralelismo, pero de la descripción de este registro de trabajo :
En última instancia, InnoDB podría no ser el mejor motor para el almacenamiento de datos debido a las operaciones basadas en disco que ocurren. Podría considerar alterar las tablas de datawarehouse para que sean MyISAM comprimido .
1 Por coincidencia, quiero decir que hay un cuello de botella que impide que su carga aumente por encima del 25%, pero no es necesariamente un problema forzado de un solo núcleo.
fuente
Una sola conexión solo usará un solo núcleo. (OK, InnoDB usa otros hilos, por lo tanto, núcleos, para algunos procesos de E / S, pero eso no es significativo).
Tenías 3 ALTERS, por lo que no estabas usando mucho más de 3 núcleos.
Por desgracia, ni siquiera PARTITION usa múltiples núcleos.
Hasta hace poco, las conexiones múltiples alcanzarían su máximo después de 4-8 núcleos. El Xtradb de Percona (incluido en MariaDB) hace un mejor uso de múltiples núcleos, pero aún así solo uno por hilo. Llegan al máximo a unos 32 núcleos.
fuente
En mi humilde opinión y en el caso de uso descrito, nunca utilizará más de un núcleo. La razón es que su carga de trabajo está vinculada a IO, no a la CPU. Como sus 3 conexiones están creando un nuevo índice, cada una de ellas necesita leer la tabla completa del disco: esto es lo que lleva tiempo, no calcular los índices.
fuente
Tenga en cuenta que su cuello de botella podría ser el rendimiento IO de su sistema de archivos.
Además de la configuración sugerida por @RolandoMySQLDBA , también configuré la
noatime
configuración de montaje/etc/fstab
para la partición que contiene mi directorio de datos mysql (/data01/mysql
en mi caso, con/dev/sdb1
montado en/data01
).De forma predeterminada, Linux registra el tiempo de acceso para CADA lectura o escritura de discos que afecta negativamente el rendimiento de IO, especialmente para aplicaciones de IO altas como bases de datos. Esto significa que incluso leer datos de un archivo desencadena una escritura en el disco ... ¡WAT!
Para deshabilitar esto, agregue la
noatime
opción de montaje/etc/fstab
para el punto de montaje deseado de la siguiente manera (ejemplo en mi caso):Luego vuelva a montar la partición:
Esto debería aumentar el rendimiento de lectura / escritura de las aplicaciones que usan esa partición. PERO ... nada mejor que mantener todos sus datos en la memoria.
fuente