sql >> Base de Datos >  >> RDS >> Mysql

En MySQL, ¿por qué es seguro desactivar innodb_support_xa para actualizaciones de un solo subproceso?

Para empezar...

http://yoshinorimatsunobu.blogspot.com/2009 /08/gran-rendimiento-efecto-de-fijación.html

Antes del complemento InnoDB 1.0.4, era como:

obtain mutex
  write innodb log and fsync, for prepare-phase (skip if innodb_support_xa=0)
  write binlog (fsync as appropriate if sync_binlog > 0)
  write innodb log and fsync, for commit-phase
release mutex

En y después del complemento InnoDB 1.0.4 (y MySQL 5.5), ahora es:

write innodb log and fsync, for prepare-phase (skip if innodb_support_xa=0)
obtain mutex
  write binlog (fsync as appropriate if sync_binlog > 0)
  write innodb log, for commit-phase
release mutex
fsync innodb log, for commit-phase

Como puede ver, en la nueva versión, nada (excepto en el caso de sync_binlog> 0) está fsync en la sección crítica. De esa forma, la confirmación de grupo ahora funciona y garantiza un rendimiento simultáneo mucho mejor.

Por ejemplo, con la versión "rota" anterior, si tenía 100 subprocesos de confirmaciones simultáneas, todos los fsyncs se serializaban y obtendría 100 fsyncs para preparar y otros 100 fsyncs para confirmar. Por lo tanto, la confirmación del grupo se rompió por completo.

Ahora, con la implementación más nueva, los fsyncs se agrupan según la concurrencia de transacciones, al tiempo que garantizan el orden de las operaciones entre innodb log y binlog. También significa que si solo hay un subproceso, no hay ganancia de rendimiento.

En cuanto a su pregunta, cuando se produce un bloqueo después de escribir una transacción en el binlog, pero antes de que se escriba en el registro de transacciones, estoy en la misma página que usted.

Si el servidor falla antes del paso final, existe una pequeña posibilidad de que tenga una discrepancia entre innodb log y binlog (cualquiera de los dos podría estar antes que el otro), pero se garantiza que tiene toda la información sobre qué examinar en el registro de innodb, tal como se registra en la fase de preparación.

Sin embargo, qué hacer con los no comprometidos aún no es determinista. Por ejemplo, a menos que sync_binlog = 1 existe la posibilidad de que un esclavo haya recibido los datos pero aún no haya sincronizado completamente el binlog en el maestro. No puede simplemente rehacer la transacción fallida, ya que es posible que ya se haya ejecutado en uno de los esclavos.

Lo que también significa que el binlog podría ser más corto que el registro de innodb, devolviendo "El registro binario [nombre_archivo] es más corto que su tamaño esperado". como se describe en el documento oficial, y debe reconstruir el esclavo desde cero. No muy amigable con los humanos.

http://dev.mysql.com/doc/refman /5.1/es/binary-log.html

Como la consistencia en términos de ordenamiento de operaciones está garantizada independientemente del innodb_support_xa configuración (que contradice lo que se dice en el documento oficial en innodb_support_xa , tal vez porque se escribió sobre el stock innodb 5.0.3 mucho antes de la corrección de concurrencia), y la coherencia entre el registro de innodb en el maestro y el registro de retransmisión en el esclavo no está estrictamente garantizado incluso con innodb_support_xa , no veo ningún sentido en usar innodb_support_xa . Sin embargo, da miedo no seguir la recomendación oficial, sin embargo, parece obsoleta y equivocada en muchos puntos.

Me pregunto si hay alguna correlación entre innodb_flush_log_at_trx_commit configuración y el innodb_support_xa comportamiento cuando el primero se establece en 2 o 0.

Una forma práctica de pensar es que la conmutación por error al esclavo es segura; después de todo, la transacción fallida era algo que usted quería hacer, pero nunca vuelva a conmutar por recuperación al maestro, ya que podría haber alguna discrepancia en los datos. Debe copiar completamente los datos del esclavo antes de convertir al maestro en un nuevo esclavo. En otras palabras, cuando el maestro falla, confíe en el esclavo a partir de ese momento; de esa manera, no necesita meterse con el registro de innodb para la recuperación del bloqueo.

También tenga en cuenta que MySQL 5.5 admite la replicación semisincrónica, en la misma línea que "confiar en el esclavo"; pensé que podría estar interesado.

http://dev.mysql.com/doc/refman /5.5/en/replication-semisync.html