IO Wait causando tanta desaceleración (EXT4 JDB2 al 99% IO) durante Mysql Commit


14

Estoy escribiendo un indexador, usando python, que indexa los documentos y los inserta en la base de datos, antes era un proceso único, pero ahora llegué al multiprocesamiento con 4 procesos paralelos en ejecución. Después de cada extracción de texto, se inserta en la base de datos y se compromete.

Ahora que está llegando al problema IO, el principal problema IO no es mi proceso, sino el sistema de diario jdb2 de EXT4. Está en 99.99% y CPU en espera para esperar IO en cada MySQL Commit.

Vi a muchos que tenían ese problema en Internet y su solución es montar usando barrera = 0. ¿Eso deshabilitaría totalmente el diario? Mis servidores tienen UPS y son tentadores, ¿debería?


¿Todos sus datos son InnoDB?
RolandoMySQLDBA

Respuestas:


4

Coloque la base de datos en un sistema de archivos que no esté en diario. Al menos los servidores más grandes (Oracle, SQL Server) tienen su propia función de diario (registro de transacciones) y optimizan su IO en consecuencia. Tiene un registro y una base de datos en discos y sistemas de archivos separados y confía en la funcionalidad interna de la base de datos para manejar las E / S incorrectas. Normalmente no hay cambios en el sistema de archivos (configuración más grande), excepto la fecha de escritura de todos modos porque los archivos no se expanden; se generarían con su tamaño "final" (bueno, los administradores pueden cambiar eso), y los cambios son como dije, rastreados por la base de datos nivel de registro de transacciones.

También puede decirnos cuál es su capa de hardware. La mayoría de las personas subestiman que IOPS es el factor limitante para una base de datos y piensan que un conjunto de discos pequeños es un entorno adecuado para una base de datos grande. Si bien algunos de nosotros trabajamos en bases de datos que usan una mayor cantidad de discos, lo que potencialmente admite una mayor cantidad de IOPS.


Modificaría esto para usar un sistema de archivos que no use el diario para datos sino solo metadatos. Ext4 también se puede configurar de esta manera.
the-wabbit

Si. Al final, el diario duplica el IO, y el registro de la base de datos volverá a hacer lo mismo, por lo que acumulará muchos más IOPS de los necesarios. Y redundancia que básicamente no es necesaria. El sistema jouirnalling es NICE para proteger el archivo ... pero es inútil cuando la aplicación ya lo hace, qué bases de datos lo hacen.
TomTom

¿Cuál ofrece el mejor rendimiento en el no diario? ¡Gracias!
Phyo Arkar Lwin

4

Siempre habrá una compensación entre resistencia y rendimiento.

Con MySQL en ext4, el valor predeterminado de barreras = 1 en realidad causa una desaceleración, sin embargo, la primera acción no debe ser desactivar el registro en diario o activar data = writeback.

Primero, si la capacidad de recuperación es de gran importancia, un RAID respaldado por batería ciertamente vale la pena.

Las opciones de montaje que he elegido, especialmente en RAID sin batería son:

/dev/mapper/vg-mysql--data  /var/lib/mysql/data ext4  defaults,noatime,nodiratime,barrier=1,data=ordered  0 0

Esto intencionalmente no está utilizando data = writeback porque no quiero arriesgarme a la corrupción del sistema de archivos que resulte en "datos antiguos que aparecerán en los archivos después de un bloqueo y recuperación del diario" (la cita es de man mount).

La configuración ideal en my.cnf para una resistencia total en torno a las configuraciones relacionadas con E / S son:

[mysqld]
sync_binlog = 1
innodb_flush_log_at_trx_commit = 1

He optado por la siguiente secuencia de compensaciones para aumentar el rendimiento:

  1. sync_binlog = 0: esta es la primera configuración de MySQL que cambio de la resistencia total. La razón de esto es que proporciona una mejora significativa en el rendimiento, especialmente donde binlog_format=row(desafortunadamente se requiere para Jira). Estoy usando suficientes réplicas de MySQL en el clúster para que si el binlog se corrompe por un escenario de pérdida de energía, haría una copia binaria de otra réplica.
  2. innodb_flush_log_at_trx_commit = 2: Si bien se requiere un valor de 1 para el cumplimiento total de ACID, con un valor de 2 ", el búfer de registro se escribe en el archivo en cada confirmación, pero no se realiza la operación de vaciado al disco. Sin embargo, el vaciado en el el archivo de registro se realiza una vez por segundo también cuando el valor es 2. Tenga en cuenta que el vaciado de una vez por segundo no está 100% garantizado que ocurra cada segundo, debido a problemas de programación del proceso ". (cita de documentos de MySQL)
  3. Actualice las opciones de montaje para usar data=writeback. Tenga en cuenta que si este es su sistema de archivos raíz, también deberá pasar una opción de línea de comandos del núcleo. Puse algunos pasos sobre eso en coderwall .
  4. Prueba varios valores de innodb_flush_method. Se muestra que O_DIRECT mejora el rendimiento en algunas cargas de trabajo, pero no es seguro que esto funcione en su entorno.
  5. Actualizar a los SSD, en cuyo caso usted también desea aumentar innodb_io_capacity, y ajustar la configuración, tales como innodb_adaptive_flushing, innodb_read_io_threads, innodb_write_io_threads, innodb_purge_threads, y otras configuraciones posibles.

3

Es muy probable que su backend de E / S no esté haciendo frente a la carga tan bien. Debe asegurarse de que su sistema de archivos no registre datos. Sugeriría usar los data=writeback,relatime,nobarrierparámetros para montar la partición de datos de su base de datos como la primera optimización rápida y sucia.

Además, deduciendo de sus síntomas, aparentemente no está utilizando el almacenamiento en caché de escritura con su controlador. Debe asegurarse de que está utilizando una memoria caché de escritura respaldada por batería o flash en su controlador y habilitarla; esto debería brindarle un aumento significativo del rendimiento sin aumentar enormemente el riesgo de pérdida de datos o corrupción. Tenga en cuenta que el uso de caché de escritura sin batería o copia de seguridad flash aumenta significativamente el riesgo de pérdida de datos o corrupción , por lo que solo debe hacerlo con fines de prueba y / o si puede asumir la pérdida.


Entonces, ¿qué tal: datos = reescritura, relatime, nobarrier y luego deshabilitar totalmente el registro de mysql? ¿Creo que esto aceleraría mucho las cosas?
Phyo Arkar Lwin

hdpram -i muestra que estoy usando el almacenamiento en caché de escritura. entonces hmm ??
Phyo Arkar Lwin

@ V3ss0n no puede deshabilitar el registro para un motor transaccional, es el corazón de todo. Puede elegir mover el registro de transacciones a un conjunto diferente de discos, ya que tiene un patrón de acceso totalmente diferente (principalmente escrituras lineales) que los datos de su base de datos principal (lectura / escritura aleatoria): esta es una configuración comúnmente recomendada. En cuanto a su configuración de almacenamiento: ¿no está utilizando un controlador RAID sino simplemente discos individuales con caché de escritura? Esto no ayudaría a ninguna de sus escrituras síncronas, ya que vienen con solicitudes de vaciado de caché explícitas.
the-wabbit

¿Es nobarrierlo mismo que barrier=0?
Nic Cottrell

@NicCottrell sí, son lo mismo.
kouton

3

Esta es una vieja pregunta, pero enfrentamos los mismos problemas (altas esperas de E / S y velocidades de inserción / actualización terribles) la semana pasada en un nuevo servidor dedicado y esta solución aborda este problema directamente.

Deshabilitar el registro en diario tune2fs -O "^has_journal" /dev/<drive>fue la solución más rápida, ya que elimina la espera de E / S debido al proceso JDB2. Pero esto no se recomienda a menos que tenga una unidad con batería de respaldo porque perderá datos en caso de un bloqueo. Las tablas de InnoDB son seguras si ha doublewritehabilitado en MySQL. Pero los archivos como .frm, registros, etc. no son seguros. Intentamos mover estos archivos a otra unidad (especialmente los registros de bin) pero el jdb2 IO wait todavía persistió. Entonces no nos dejó muy cómodos.

data=writeback,relatime,nobarrierno ayudó a acelerar las escrituras / lecturas tanto como deshabilitar el diario en toda la partición. Más opciones para ext4 están en el documento EXT4 .

El verdadero culpable en nuestro caso fue sync_binlog. Habíamos establecido que estaba como 1en /etc/mysql/my.cnfy estaba matando el rendimiento.

Percona valida esto aquí . Lo configuramos como predeterminado 0y el rendimiento se disparó en más de un 500%.


0

¿En qué motor de base de datos está utilizando para insertar estos datos?

Si es MyISAM: eso debe bloquear toda la tabla durante una escritura, por lo que ejecutar hilos de inserción concurrentes matará CUALQUIER sistema, sin importar cuán poderoso sea.

Asegúrese de estar usando InnoDB para estas tablas.


Como está realizando transacciones, el motor no sería MyISAM ya que MyISAM no admite transacciones.
the-wabbit

Arr, brainfart.
Adaptr

Estoy usando innodb, mysql5.5 por defecto es innodb.
Phyo Arkar Lwin

0

Además, no está directamente relacionado con mysql, pero algunos HD tienen problemas con ext4 debido a la administración agresiva de energía ... cuando eso sucede, la carga de la máquina aumenta sin actividad aparente.

Intenta deshabilitarlo. primero verifique el valor que tenga (si necesita volver a ponerlo sin reiniciar) y luego desactívelo.

Verifique el valor actual:

    hdparm -B /dev/sda

Deshabilitarlo

   hdparm -B 255 /dev/sda

(o lo que sea tu HD) y prueba. Probablemente no ayudará para la mayoría de los problemas, pero podría ayudar a algunos usuarios. El reinicio restablecerá el valor o reemplazará manualmente el 255 por el valor anterior.

Si ayuda, verifique /etc/default/hdparmo /etc/hdparm.confpara una configuración más permanente, configurándola en el arranque.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.