¿Es seguro usar innodb_flush_log_at_trx_commit = 2

54

Me di vuelta innodb_flush_log_at_trx_commit = 2y obtuve una velocidad de escritura muy rápida. ¿Pero es seguro ser utilizado en el sitio web de producción?

Bruce Dou
fuente

Respuestas:

57

Puede perder hasta un segundo de transacciones. El valor predeterminado es 1, lo que ayuda a mantener InnoDB ACID Compliant .

De acuerdo con la documentación de MySQL en innodb_flush_log_at_trx_commit

Si el valor de innodb_flush_log_at_trx_commit es 0, el búfer de registro se escribe en el archivo de registro una vez por segundo y la operación de vaciado al disco se realiza en el archivo de registro, pero no se hace nada en una confirmación de transacción. Cuando el valor es 1 (el valor predeterminado), el búfer de registro se escribe en el archivo de registro en cada confirmación de transacción y la operación de vaciado al disco se realiza en el archivo de registro. Cuando el valor es 2, el búfer de registro se escribe en el archivo en cada confirmación, pero la operación de vaciado al disco no se realiza en él. Sin embargo, el enjuague en el archivo de registro se realiza una vez por segundo también cuando el valor es 2. Tenga en cuenta que el enjuague de una vez por segundo no está garantizado al 100% cada segundo, debido a problemas de programación del proceso.

Se requiere el valor predeterminado de 1 para el pleno cumplimiento de ACID. Puede lograr un mejor rendimiento estableciendo un valor diferente de 1, pero luego puede perder hasta un segundo de transacciones en un bloqueo. Con un valor de 0, cualquier caída del proceso mysqld puede borrar el último segundo de las transacciones. Con un valor de 2, solo un bloqueo del sistema operativo o un corte de energía pueden borrar el último segundo de las transacciones. La recuperación de fallos de InnoDB funciona independientemente del valor.

Para obtener la mayor durabilidad y consistencia posibles en una configuración de replicación usando InnoDB con transacciones, use innodb_flush_log_at_trx_commit = 1 y sync_binlog = 1 en el archivo my.cnf de su servidor maestro.

Precaución

Muchos sistemas operativos y algunos hardware de disco engañan la operación de vaciado de disco. Pueden decirle a mysqld que el enjuague ha tenido lugar, aunque no lo haya hecho. Entonces, la durabilidad de las transacciones no está garantizada incluso con la configuración 1, y en el peor de los casos, un corte de energía puede incluso dañar la base de datos InnoDB. El uso de una memoria caché de disco con respaldo de batería en el controlador de disco SCSI o en el disco mismo acelera la descarga de archivos y hace que la operación sea más segura. También puede intentar usar el comando hdparm de Unix para deshabilitar el almacenamiento en caché de las escrituras de disco en cachés de hardware, o usar algún otro comando específico para el proveedor de hardware.

En base a esto, los valores distintos de 1 ponen a InnoDB en riesgo de perder el valor de 1 segundo de las transacciones, o el valor de los datos de un compromiso de transacción.

La documentación también dice uso sync_binlog=1.

De acuerdo con la documentación de MySQL en sync_binlog

Un valor de 1 es la opción más segura porque, en caso de bloqueo, pierde como máximo una declaración o transacción del registro binario. Sin embargo, también es la opción más lenta (a menos que el disco tenga una memoria caché respaldada por batería, lo que hace que la sincronización sea muy rápida).

Su opción más segura es

[mysqld]
innodb_flush_log_at_trx_commit=1
sync_binlog=1

Si no le importa la posible pérdida de datos (hasta 1 segundo), puede usar 0 o 2 bajo su propio riesgo si las recompensas (mayor velocidad de escritura) valen la pena.

RolandoMySQLDBA
fuente
3
Rolando: +1 para las últimas líneas sync_binlog = 1 ...
Abdul Manaf
@AbdulManaf, siempre busca la integridad de los datos que la velocidad. Si desea sacrificar la velocidad por la integridad de los datos, perderá mucho más tiempo lidiando con problemas de datos.
Pacerier
1
@RolandoMySQLDBA, Al "perder el valor de una transacción de un segundo", ¿quiere decir que podría perderse un éxito commit ?
Pacerier
1
Pacerier, sí. Se garantiza que los datos solo se escribirán en el disco después de que se "vacíen en el disco". Hasta entonces, podría estar solo en la memoria RAM.
Emil Vikström
2
@RolandoMySQLDBA eres el hombre, en serio. Si haces algo más que conciertos de consultoría mysql a tiempo completo, posiblemente deberías cambiar tu trayectoria profesional.
sjas
25

El innodb_flush_log_at_trx_commitse utiliza con el propósito de ..

Si el valor de innodb_flush_log_at_trx_commit es 0, el búfer de registro se escribe en el archivo de registro una vez por segundo y la operación de vaciado al disco se realiza en el archivo de registro, pero no se hace nada en una confirmación de transacción.

Cuando el valor es 1 (el valor predeterminado), el búfer de registro se escribe en el archivo de registro en cada confirmación de transacción y la operación de vaciado al disco se realiza en el archivo de registro.

Cuando el valor es 2, el búfer de registro se escribe en el archivo en cada confirmación, pero la operación de vaciado al disco no se realiza en él. Sin embargo, el enjuague en el archivo de registro se realiza una vez por segundo también cuando el valor es 2. Tenga en cuenta que el enjuague de una vez por segundo no está garantizado al 100% cada segundo, debido a problemas de programación del proceso.

Se requiere el valor predeterminado de 1 para el pleno cumplimiento de ACID. Puede lograr un mejor rendimiento estableciendo un valor diferente de 1, pero luego puede perder hasta un segundo de transacciones en un bloqueo. Con un valor de 0, cualquier caída del proceso mysqld puede borrar el último segundo de las transacciones. Con un valor de 2, solo un bloqueo del sistema operativo o un corte de energía pueden borrar el último segundo de las transacciones. La recuperación de fallos de InnoDB funciona independientemente del valor.

En mi opinión, usar innodb_flush_log_at_trx_commit2 no debería ser un problema, pero usar 1 es el más seguro.

Abdul Manaf
fuente
3
Acabo de notar que respondiste solo 18 segundos después de mí con esencialmente la misma respuesta. +1 !!!
RolandoMySQLDBA
24

Mi opinión difiere de otra. innodb_flush_log_at_trx_commit = 0 if: es mi computadora de desarrollo o mi mini base de datos donde no hay datos confidenciales.

innodb_flush_log_at_trx_commit = 2 if: es blog / stats / e-commerce (con ~ 100x compras en el día), etc.

innodb_flush_log_at_trx_commit = 1 si: tiene muchos clientes o necesita trabajar con transacciones de dinero como el banco. así que esta vez debes dividir tu flujo de datos entre varios servidores para tener velocidad y seguridad.

Prefiero 2, porque tiene una velocidad de escritura ~ 75x más rápida y falla SOLO si falla el hardware.

De todos modos, debe saber qué necesita más, mucha más velocidad de escritura o información de hasta 1 segundo.

Sertekmedia
fuente
1
+1 para75x faster write speed and it fails ONLY if hardware fails.
Naman Gala el
3
75 veces más rápido? Cita necesaria.
Pacerier
55
Mi propio punto de referencia: 5000 UPDATEcon innodb_flush_log_at_trx_commit = 1: 179 segundos. Con innodb_flush_log_at_trx_commit = 2: 1.12 segundos. Es una velocidad de escritura 160x más rápida en mi caso.
Kevin
Buena respuesta. Una cosa a tener en cuenta es que, si su máquina se bloquea después de una transacción exitosa, es posible que la transacción no se haya escrito en el disco con innodb_flush_log_at_trx_commit = 2, y aún así se indicó el éxito a su aplicación (es decir, mysqld logra enviar un paquete de red que indica que la transacción finalizó con éxito para el conductor en su aplicación), esa posibilidad es muy baja
Vladislav Vaintroub
¿puedes mejorar tu respuesta especificando qué quieren decir los documentos?crash
shareef
2

Estoy tratando de responder, cuál es el propósito de innodb_flush_log_at_trx_commit?

InnoDB realiza la mayoría de sus operaciones en la memoria ( InnoDB Buffer Pool). Todos los datos modificados se escriben InnoDB transaction log filey luego se vacían (se escriben) en un almacenamiento duradero (disco duro).

Para la seguridad de los datos ( Durability from ACID), InnoDB tiene que almacenar datos modificados de cada transacción en un almacenamiento permanente. Al mismo tiempo, comprometerse en el disco para cada transacción es un proceso costoso.

Disk I / O es un proceso de bloqueo y es muy lento, es un disco lento, además reducirá la cantidad de InnoDB transaction per seconds(rendimiento del disco).

InnoDB proporciona una innodb_flush_log_at_trx_commitvariable para controlar la frecuencia de esta operación de descarga. Según el valor, la operación de vaciado de InnoDB se comporta de manera diferente.

(Ya explicado en otras respuestas)

0: escriba en el archivo de registro y vacíelo en el disco cada segundo (los datos se encuentran en el grupo de búferes no escritos en el archivo de registro, para aumentar el rendimiento). 1 - Vaciar en el disco cuando se confirma una transacción - predeterminado (por seguridad de los datos - Cumplimiento con ACID) 2 - escribir en el archivo de registro para cada transacción y vaciar en el disco en cada segundo. (Para ganar rendimiento)

Depende del requisito de la aplicación ( Performance Vs data safety), puede establecer esta variable. La diferencia entre 0 y 2: ambos aumentarán el rendimiento, el valor 2 almacena los datos en el archivo de transacción y puede ser recuperable, en caso de bloqueo o falla, pero no en 0.

En muchos casos, vaciar en el disco significa que los datos se escriben desde InnoDB buffer pool (memory) to Operating systems cacheno escritos en el disco de almacenamiento (almacenamiento permanente). En caso de falla, en el peor de los casos, puede perder datos hasta un segundo)

La ganancia de rendimiento depende del entorno y puede comparar e identificar. En un entorno de replicación, para seguridad y consistencia de los datos, establezca innodb_flush_log_trx_commit = 1y sync_binlog=1.

Si el rendimiento es el objetivo principal de la aplicación, InnoDB proporciona una variable para controlar la frecuencia del enjuague de registros innodb_flush_log_at_timeout, que le permite establecer el rango de frecuencia de enjuague de registros 1 to 2700 seconds, de forma predeterminada es 1.

Tenga en cuenta que cuando aumenta el intervalo de descarga hasta N segundos, la ganancia de rendimiento conlleva un compromiso en la seguridad de los datos de hasta N segundos. Por ejemplo, si configura el enjuague cada 5 segundos, la ganancia de rendimiento es muy alta, pero en caso de falla de energía o caída del sistema, perderá datos que valen 5 segundos.

Este artículo discute sobre el vaciado de InnoDB y las operaciones de confirmación de transacción .

Puede cambiar después de hacer el modo 2 en aws rds:

puede cambiar después de hacer el modo 2 en aws

vista previa de cambios

Inmodificable en algunos casos, como si tiene replicación multi az:

FYI inmodificable en algunos casos

rathishDBA
fuente
1

Si su hardware falla, puede perder todos sus datos, por lo que uso param = 2 sin ninguna preocupación. De todos modos, puede dividir sus datos confidenciales (pedido, dinero virtual, ...) y regulares (estadísticas, carrito, ...) entre servidores de 2 db y mantenerlos seguros y rápidos. Para transacciones entre bases de datos, puede usar http://dev.mysql.com/doc/refman/5.7/en/xa.html

Karolis Mačiulskis
fuente
"Perder todos sus datos", ¿o quiere decir las transacciones que fueron consultadas en los últimos segundos?
NiCk Newman
1
Una falla de hardware puede significar perder un disco duro completo, por lo tanto, "perder todos sus datos". Entonces, a menos que tenga una configuración de replicación, sus datos estarán a merced de la frecuencia con la que haga copias de seguridad de todos modos, por lo que el punto que esta respuesta estaba haciendo es que un segundo o dos de datos perdidos no es nada de qué preocuparse en comparación
thomasrutter