MariaDB comenzando con 10.0.5

La replicación paralela se introdujo en MariaDB 10.0.5.

De MariaDB 10.0.5, algunas escrituras, replicadas desde el maestro se pueden ejecutar en paralelo (simultáneamente) en el esclavo. Tenga en cuenta que para que funcione la replicacin en paralelo, tanto el maestro como el esclavo deben MariaDB 10.0.5 o después.

Descripción general de la replicación paralela

La replicación de MariaDB en general se lleva a cabo en tres partes:

  • Los eventos de replicación se leen del maestro mediante el subproceso de E / S y se ponen en cola en el registro de retransmisión.
  • Los eventos de replicación se obtienen uno a la vez por el subproceso SQL del registro de retransmisión
  • Cada evento se aplica al esclavo para replicar todos los cambios realizados en el maestro.

Antes de MariaDB 10, el tercer paso también lo realizaba el hilo SQL; esto significaba que solo se podía ejecutar un evento a la vez, y la replicación era esencialmente de un solo subproceso. Desde MariaDB 10, el tercer paso puede realizarse opcionalmente mediante un grupo de subprocesos de trabajo de replicación separados y, por lo tanto, aumentar potencialmente el rendimiento de la replicación mediante la aplicación de varios eventos en paralelo.

Cómo habilitar el esclavo paralelo

Para habilitarlo, especifique esclavo-paralelos-hilos = # en su archivo my.cnf como un argumento para mysql. La replicación en paralelo también se puede deshabilitar en una conexión por fuente múltiple configurando @@ nombre_conexión.slave-modo-paralelo en “ninguno”.

El valor (#) de slave_parallel_threads especifica cuántos subprocesos se crearán en un grupo de subprocesos de trabajo utilizados para aplicar eventos en paralelo para * todos * sus esclavos (esto incluye la replicación de múltiples fuentes). Si el valor es cero, no se crean subprocesos de trabajo y se usa la replicación de estilo antiguo cuando se aplican eventos dentro del subproceso SQL. Por lo general, el valor, si no es cero, debe ser al menos dos veces el número de conexiones maestras de múltiples fuentes utilizadas. Tiene poco sentido utilizar un solo hilo de trabajo para una conexión; esto incurrirá en algunos gastos generales en la comunicación entre subprocesos entre el subproceso SQL y el subproceso de trabajo, pero con un solo subproceso de trabajo, los eventos no se pueden aplicar en paralelo de todos modos.

slave-parallel-threads=# es una variable dinámica que se puede cambiar sin reiniciar mysqld. Sin embargo, todas las conexiones de esclavos deben detenerse al cambiar el valor.

Configuración del modo paralelo esclavo

La replicación en paralelo puede estar en orden o fuera de orden:

  • In-order ejecuta transacciones en paralelo, pero ordena que el paso de confirmación de las transacciones suceda exactamente en el mismo orden que en el maestro. Las transacciones solo se ejecutan en paralelo en la medida en que se pueda verificar automáticamente que sea posible sin ningún conflicto. Esto significa que el uso del paralelismo es completamente transparente para la aplicación.
  • Fuera de servicio puede ejecutar y confirmar transacciones en un orden diferente en el esclavo que originalmente en el maestro. Esto significa que la aplicación debe tolerar que las actualizaciones se produzcan en un orden diferente. La aplicación también es responsable de garantizar que no haya conflictos entre las transacciones que se replican fuera de orden. Fuera de servicio solo se usa en modo GTID y solo cuando la aplicación lo habilita explícitamente, usando el dominio de replicación que es parte de GTID.

Replicación paralela en orden

Modo optimista de replicación paralela en orden

MariaDB comenzando con 10.1.3

El modo optimista de replicación paralela en orden se introdujo en MariaDB 10.1.3.

El modo optimista de replicación paralela en orden ofrece muchas oportunidades para la aplicación en paralelo en el esclavo, al tiempo que conserva la semántica exacta de las transacciones desde el punto de vista de las aplicaciones.

El modo optimista de replicación paralela en orden se puede configurar configurando el slave_parallel_mode variable de sistema a optimistic en el esclavo.

Cualquier DML transaccional (INSERT / UPDATE / DELETE) puede ejecutarse en paralelo, hasta el límite de @@ slave_domain_parallel_threads. Esto puede causar conflictos en el esclavo, por ejemplo. si dos transacciones intentan modificar la misma fila. Se detecta cualquier conflicto de este tipo y se revierte la última de las dos transacciones, lo que permite que prosiga la primera. La última transacción se vuelve a intentar una vez que se ha completado la primera.

El término “optimista” se utiliza para este modo, porque el servidor asume de manera optimista que se producirán pocos conflictos y que el trabajo adicional invertido en deshacer y reintentar transacciones conflictivas se justifica por la ganancia de ejecutar la mayoría de las transacciones en paralelo.

Hay algunas heurísticas para tratar de evitar conflictos innecesarios. Si una transacción ejecutó una espera de bloqueo de fila en el maestro, no se ejecutará en paralelo en el esclavo. Las transacciones también se pueden marcar explícitamente como potencialmente conflictivas en el maestro, estableciendo la variable @@ skip_parallel_replication. Se pueden agregar más heurísticas de este tipo en versiones posteriores de MariaDB. Hay un modo paralelo esclavo llamado “agresivo”, donde estas heurísticas están deshabilitadas, lo que permite que se apliquen aún más transacciones en paralelo.

No es seguro aplicar DML y DDL no transaccionales en paralelo de manera optimista, ya que no se puede revertir en caso de conflictos. Por lo tanto, en modo optimista, las actualizaciones no transaccionales (como MyISAM) no se aplican en paralelo con eventos anteriores (sin embargo, es posible aplicar una actualización MyISAM en paralelo con una actualización InnoDB posterior). Las declaraciones DDL no se aplican en paralelo con otras transacciones, antes o después.

Los diferentes tipos de transacciones se pueden identificar en la salida de mysqlbinlog. Por ejemplo:

#150324 13:06:26 server id 1  end_log_pos 6881 	GTID 0-1-42 ddl...#150324 13:06:26 server id 1  end_log_pos 7816 	GTID 0-1-47...#150324 13:06:26 server id 1  end_log_pos 8177  GTID 0-1-49 trans/*!100101 SET @@session.skip_parallel_replication=1*//*!*/;...#150324 13:06:26 server id 1  end_log_pos 9836 	GTID 0-1-59 trans waited

GTID 0-1-42 está marcado como DDL. GTID 0-1-47 está marcado como DML no transaccional, mientras que GTID 0-1-49 es DML transaccional (visto en la palabra clave “trans”). GTID 0-1-49 se ejecutó adicionalmente con @@ skip_parallel_replication configurado en el maestro. GTID 0-1-59 es DML transaccional que tenía un bloqueo de fila en espera cuando se ejecuta en el maestro (la palabra clave “espera”).

Modo agresivo de replicación paralela en orden

MariaDB comenzando con 10.1.3

El modo agresivo de replicación paralela en orden se introdujo en MariaDB 10.1.3.

El modo agresivo de replicación paralela en orden es muy similar al modo optimista. La principal diferencia es que el esclavo no considera si las transacciones entraron en conflicto con el maestro al decidir si aplicar las transacciones en paralelo.

El modo agresivo de replicación paralela en orden se puede configurar configurando el slave_parallel_mode variable de sistema a aggressive en el esclavo.

Modo conservador de replicación paralela en orden

MariaDB comenzando con 10.0

El modo conservador de replicación paralela en orden se introdujo en MariaDB 10.0.

El modo conservador de replicación paralela en orden utiliza el compromiso de grupo en el maestro para descubrir el potencial de aplicación paralela de eventos en el esclavo. Si dos transacciones se comprometen juntas en un grupo se comprometen en el maestro, se escriben en el binlog con el mismo ID de confirmación. Es seguro que dichos eventos no entrarán en conflicto entre sí, y la replicación paralela puede programarlos para que se ejecuten en diferentes subprocesos de trabajo.

El modo conservador de replicación paralela en orden es actualmente el modo predeterminado, pero también se puede configurar estableciendo el slave_parallel_mode variable de sistema a conservative en el esclavo.

Dos transacciones que se confirmaron por separado en el maestro pueden potencialmente entrar en conflicto (por ejemplo, modificar la misma fila de una tabla). Por lo tanto, el trabajador que aplica la segunda transacción no se iniciará inmediatamente, sino que esperará hasta que la primera transacción comience el paso de confirmación; en este punto, es seguro iniciar la segunda transacción, ya que ya no puede interrumpir la ejecución de la primera.

Aquí hay un resultado de ejemplo de mysqlbinlog que muestra cómo los eventos GTID se marcan con el ID de confirmación. El GTID 0-1-47 no tiene ID de confirmación y no se puede ejecutar en paralelo. Los GTID 0-1-48 y 0-1-49 tienen el mismo ID de confirmación 630 y, por lo tanto, pueden replicarse en paralelo entre sí en un esclavo:

#150324 12:54:24 server id 1  end_log_pos 20052 	GTID 0-1-47 trans...#150324 12:54:24 server id 1  end_log_pos 20212 	GTID 0-1-48 cid=630 trans...#150324 12:54:24 server id 1  end_log_pos 20372 	GTID 0-1-49 cid=630 trans

En cualquier caso, cuando las dos transacciones alcanzan el punto donde ocurre la confirmación de bajo nivel y se determina el orden de confirmación, las dos confirmaciones se secuencian para que sucedan en el mismo orden que en el maestro, de modo que la operación sea transparente para las aplicaciones.

Las oportunidades para la replicación en paralelo en esclavos pueden aumentar considerablemente si se realizan más transacciones en un compromiso de grupo en el maestro. Esto se puede ajustar usando las variables binlog_commit_wait_count y binlog_commit_wait_usec. Si, por ejemplo, la aplicación puede tolerar hasta 50 milisegundos de retraso adicional para las transacciones en el maestro, se puede configurar binlog_commit_wait_usec=50000 y binlog_commit_wait_count=20 para obtener hasta 20 transacciones a la vez disponibles para replicar en paralelo. Sin embargo, se debe tener cuidado de no configurar binlog_commit_wait_usec demasiado alto, ya que esto podría causar una desaceleración significativa para las aplicaciones que ejecutan muchas transacciones pequeñas en serie una tras otra.

Tenga en cuenta que incluso si no hay paralelismo disponible en la confirmación del grupo maestro, todavía existe la oportunidad de acelerar la replicación paralela en orden, ya que los pasos de confirmación reales de diferentes transacciones pueden ejecutarse en paralelo. Esto puede ser particularmente efectivo en un esclavo con binlog habilitado (log_slave_updates = 1), y más aún si el esclavo está configurado para ser seguro contra fallas (sync_binlog = 1 e innodb_flush_log_at_trx_commit = 1), ya que esto hace posible la confirmación grupal en el esclavo.

Modo mínimo de replicación paralela en orden

MariaDB comenzando con 10.1.3

El modo mínimo de replicación paralela en orden se introdujo en MariaDB 10.1.3.

Modo mínimo de replicación paralela en orden solamentepermite que el paso de confirmación de transacciones se aplique en paralelo; todos los demás pasos se aplican en serie.

El modo mínimo de replicación paralela en orden se puede configurar configurando el slave_parallel_mode variable de sistema a minimal en el esclavo.

Replicación paralela fuera de servicio

La replicación paralela fuera de orden ocurre (solo) cuando se usa el modo GTID, cuando se usan GTID con diferentes dominios de replicación. El dominio de replicación lo establece el DBA / la aplicación utilizando la variable gtid_domain_id.

Dos transacciones que tienen GTID con diferente domain_id se programan en diferentes subprocesos de trabajo mediante replicación paralela y se les permite ejecutarse de forma completamente independiente entre sí. Es responsabilidad de la aplicación solo establezca diferentes domain_ids para transacciones que sean verdaderamente independientes, y se garantice que no entrarán en conflicto entre sí. La aplicación también debe poder funcionar correctamente aunque se considere que las transacciones con un domain_id diferente se confirman en un orden diferente entre el esclavo y el maestro, y entre diferentes esclavos.

La replicación paralela fuera de orden puede potencialmente brindar más ganancias de rendimiento que la replicación paralela en orden, ya que la aplicación puede brindar explícitamente más oportunidades para ejecutar transacciones en paralelo de las que el servidor puede determinar por sí solo de forma automática.

Un uso simple pero efectivo es ejecutar declaraciones de larga ejecución, como ALTER TABLE, en un dominio de replicación separado. Esto permite que la replicación de otras transacciones se realice sin interrupciones:

SETSESSION gtid_domain_id=1ALTERTABLE t ADDINDEX myidx(b)SETSESSION gtid_domain_id=0

Normalmente, una ALTER TABLE de larga ejecución u otra consulta paralizará todas las transacciones siguientes, lo que hará que el esclavo se quede detrás del maestro al menos tanto tiempo como sea necesario para ejecutar la consulta de larga duración. Esto puede evitarse si se utiliza la replicación en paralelo desordenada mediante la configuración del ID del dominio de replicación. El DBA / aplicación debe garantizar que no se replicarán transacciones en conflicto mientras se ejecuta ALTER TABLE.

Otra oportunidad común para la replicación paralela fuera de orden se presenta en conexión con la replicación de múltiples fuentes. Supongamos que tenemos dos maestros diferentes M1 y M2, y estamos usando la replicación de múltiples fuentes para tener S1 como esclavo tanto de M1 como de M2. S1 aplicará los eventos recibidos de M1 en paralelo con los eventos recibidos de M2. Si ahora tenemos un esclavo de tercer nivel S2 que se replica desde S1 como maestro, queremos que S2 también pueda aplicar eventos que se originaron en M1 en paralelo con eventos que se originaron en M2. Esto se puede lograr con la replicación paralela desordenada, estableciendo gtid_domain_id diferente en M1 y M2.

Tenga en cuenta que no existen restricciones especiales sobre las operaciones que se pueden replicar en paralelo utilizando fuera de servicio; tales operaciones pueden estar en la misma base de datos / esquema o incluso en la misma tabla. La única restricción es que las operaciones no deben entrar en conflicto, es decir, deben poder aplicarse en cualquier orden y aun así terminar con el mismo resultado.

Cuando se usa la replicación en paralelo desordenada, la posición del esclavo actual en el binlog del maestro se vuelve multidimensional: cada dominio de replicación puede haber alcanzado un punto diferente en el binlog maestro en cualquier momento. La posición actual se puede ver en la variable gtid_slave_pos. Cuando el esclavo se detiene, reinicia o cambia para replicar desde un maestro diferente usando CHANGE MASTER, MariaDB maneja automáticamente el reinicio de cada dominio de replicación en el punto apropiado en el binlog.

La replicación en paralelo fuera de orden está deshabilitada cuando –slave-parallel-mode = mínimo (o ninguno).

Comprobación del estado del hilo de trabajo en MOSTRAR LISTA DE PROCESOS

Los subprocesos de trabajo se enumerarán como “usuario del sistema” en MOSTRAR LISTA DE PROCESOS. Su estado mostrará la consulta en la que están trabajando actualmente, o puede mostrar una de estas:

  • “Esperando trabajo desde los principales subprocesos SQL”. Esto significa que el hilo de trabajo está inactivo, no hay trabajo disponible para él en este momento.
  • “Esperando que la transacción anterior comience a confirmarse antes de comenzar la siguiente transacción”. Esto significa que el lote anterior de transacciones que se comprometieron juntas en el maestro maestro debe completarse primero. Este hilo de trabajo está esperando que eso suceda antes de que pueda comenzar a trabajar en el siguiente lote.
  • “Esperando que se confirme la transacción anterior”. Esto significa que la transacción ha sido ejecutada por el hilo de trabajo. Para garantizar la confirmación en orden, el hilo de trabajo está esperando para confirmarse hasta que la transacción anterior esté lista para confirmarse antes.

Aumento de rendimiento esperado

Aquí hay un artículo que muestra una mejora de hasta diez veces cuando se usa la replicación paralela: http://kristiannielsen.livejournal.com/18435.html.

Configuración del tamaño máximo de la cola de esclavos en paralelo

los slave_parallel_max_queued La variable del sistema se puede utilizar para configurar el tamaño máximo de la cola esclava paralela. Esta variable del sistema solo es significativa cuando se configura la replicación en paralelo (es decir, cuando slave_parallel_threads > 0).

Cuando se usa la replicación en paralelo, el subproceso SQL leerá por adelantado en los registros de retransmisión, poniendo en cola los eventos en la memoria mientras busca oportunidades para ejecutar eventos en paralelo. los slave_parallel_max_queued La variable de sistema establece un límite para la cantidad de memoria que utilizará para esto.

El valor configurado del slave_parallel_max_queued La variable del sistema se asigna realmente para cada subproceso de trabajo, por lo que la asignación total es en realidad equivalente a lo siguiente:

slave_parallel_max_queued * slave_parallel_threads

Si este valor se establece demasiado alto, y el esclavo está muy por detrás del maestro (por ejemplo, gigabytes de binlog), entonces el hilo SQL puede leer rápidamente todo eso y llenar la memoria con grandes cantidades de eventos binlog más rápido que los hilos de trabajo. consumirlos.

Por otro lado, si se establece demasiado bajo, es posible que el subproceso SQL no tenga suficiente espacio para poner en cola suficientes eventos para mantener ocupados los subprocesos de trabajo, lo que podría reducir el rendimiento. En este caso, el hilo SQL tendrá el estado del hilo que indica Waiting for room in worker thread event queue. Por ejemplo:

+----+-------------+-----------+------+---------+--------+-----------------------------------------------+------------------+----------+| Id |User| Host      | db   | Command |Time| State                                         | Info             | Progress |+----+-------------+-----------+------+---------+--------+-----------------------------------------------+------------------+----------+|3| system user||NULL|Connect|139| closing tables|NULL|0.000||4| system user||NULL|Connect|139| Waiting forworkfromSQL thread              |NULL|0.000||6| system user||NULL|Connect|264274| Waiting for master to send event              |NULL|0.000||10| root        | localhost |NULL| Sleep   |43||NULL|0.000||21| system user||NULL|Connect|45| Waiting for room in worker thread event queue |NULL|0.000||54| root        | localhost |NULL| Query   |0| init                                          |SHOW PROCESSLIST |0.000|+----+-------------+-----------+------+---------+--------+-----------------------------------------------+------------------+----------+

los slave_parallel_max_queued La variable del sistema no define un límite estricto, ya que los eventos de registro binario que se están ejecutando actualmente siempre deben mantenerse en la memoria. Esto significa que al menos dos eventos por subproceso de trabajo siempre se pueden poner en cola en la memoria, independientemente del valor de slave_parallel_threads.

Por lo general, el slave_parallel_threads La variable del sistema debe establecerse lo suficientemente grande como para que el subproceso SQL pueda leer con suficiente anticipación en el registro binario para explotar todo el paralelismo posible. En funcionamiento normal, es de esperar que el esclavo no se quede muy atrás, por lo que no será necesario poner en cola muchos datos en la memoria. los slave_parallel_max_queued La variable del sistema podría establecerse bastante alta (por ejemplo, algunos cientos de kilobytes) para no limitar el rendimiento. Debe establecerse lo suficientemente bajo como para que la asignación total de la cola esclava paralela no provoque que el servidor se quede sin memoria.

Variable de configuración slave_domain_parallel_threads

El grupo de subprocesos de trabajo de replicación se comparte entre todas las conexiones maestras de múltiples fuentes y entre todos los dominios de replicación que pueden replicarse en paralelo usando fuera de servicio.

Si una conexión maestra o un dominio de replicación está procesando actualmente una consulta de ejecución prolongada, es posible que asigne todos los subprocesos de trabajo en el grupo, solo para que esperen a que se complete la consulta de ejecución prolongada, deteniendo cualquier otra conexión maestra o dominio de replicación, que tendrá que esperar a que se libere un hilo de trabajo.

Esto se puede evitar configurando slave_domain_parallel_threads en un número menor que slave_parallel_threads. Cuando se establece diferente de cero, cada dominio de replicación en una conexión maestra puede reservar como máximo esa cantidad de subprocesos de trabajo en cualquier momento, dejando el resto (hasta el valor de slave_parallel_threads) libre para que otras conexiones maestras o dominios de replicación lo usen en paralelo.

los slave_domain_parallel_threads la variable es dinámica y se puede cambiar sin reiniciar el servidor; Sin embargo, todos los esclavos deben detenerse mientras se cambia.

Detalles de implementacion

La implementación se describe en MDEV-4506.

Ver también

El contenido reproducido en este sitio es propiedad de sus respectivos dueños, y MariaDB no revisa este contenido con anticipación. Los puntos de vista, la información y las opiniones expresadas por este contenido no representan necesariamente las de MariaDB o de cualquier otra parte.