Copiar tabla de registros de información | Comprensión completa de la biblioteca del sistema mysql


En el último número de "Tabla de registro de información de zona horaria | Una comprensión completa de la biblioteca del sistema MySQL", presentamos en detalle la tabla de registro de información de zona horaria en la biblioteca del sistema mysql. En este número, le presentaremos la séptima parte de la serie "Tabla de registro de información de replicación" | Una comprensión completa de la biblioteca del sistema mysql ", síganos para comenzar el viaje de aprender juntos la biblioteca del sistema mysql.

1. Descripción general de la tabla de información de copia

La tabla de información de replicación se utiliza para guardar los eventos de registro binario enviados desde la biblioteca maestra a la biblioteca esclava y registrar información sobre el estado actual y la ubicación del registro de relés durante el período en el que la biblioteca esclava está copiando los datos de la biblioteca maestra. Hay tres tipos de registros, como se indica a continuación:

  • archivo master.info o tabla mysql.slave_master_info: se usa para guardar el estado de conexión, cuenta, IP, puerto, contraseña del subproceso IO de la biblioteca esclava en la biblioteca principal, y el subproceso IO actualmente lee el archivo y la información de posición del binlog de la biblioteca principal (llamado Es el registro de información del subproceso de IO. De forma predeterminada, la información de conexión y el estado del subproceso de IO se guardan en el archivo master.info (la ubicación predeterminada está en datadir, puede usar la opción master_info_file para ejecutar la ruta del archivo master.info), si necesita guardarlo en mysql.slave_master_info En la tabla, debe establecer master-info-repository = TABLE antes de que se inicie el servidor).

  • El archivo relay-log.info o la tabla mysql.slave_relay_log_info: La última información del evento binlog obtenida de la biblioteca principal del subproceso IO de la biblioteca se escribirá en el registro de retransmisión local de la biblioteca esclava, y el subproceso SQL leerá el registro de retransmisión y lo analizará. El archivo relay_log.info o la tabla mysql.slave_relay_log_info se utiliza para registrar el archivo y la posición del último registro de retransmisión y el evento de reproducción actual del subproceso SQL corresponde al archivo y la posición del binlog de la biblioteca principal (el registro de retransmisión se denomina registro de retransmisión La ubicación del subproceso SQL se llama registro de información del subproceso SQL. De forma predeterminada, la información de ubicación del registro de retransmisión y la información de ubicación del subproceso SQL se guardan en el archivo relay-log.info (la ubicación predeterminada está en datadir, y puede usar la opción relay_log_info_file para ejecutar relay- log.info ruta del archivo), si necesita guardarlo en la tabla mysql.slave_relay_log_info, debe configurar relay-log-info-repository = TABLE antes de que se inicie el servidor).

La configuración de relay_log_info_repository y master_info_repository en TABLE puede mejorar la capacidad de recuperación tras el bloqueo después de la base de datos o el host donde el host termina inesperadamente (las dos tablas son tablas innodb, que pueden garantizar que la información de ubicación en la tabla después del bloqueo no se pierda) y puede garantizar la coherencia de los datos.

Cuando la biblioteca esclava falla, el subproceso SQL todavía puede tener una parte del retardo de reproducción del registro de retransmisión. Además, la posición del subproceso IO también puede estar en el medio de una transacción y no está completa, por lo que el parámetro relay-log-recovery = debe estar habilitado en la biblioteca esclava. ENCENDIDO, cuando este parámetro está habilitado, el registro de retransmisión no reproducido del subproceso SQL se limpiará durante la recuperación de fallas de la biblioteca, y la posición del subproceso IO se restablecerá en función de la posición del subproceso SQL para solicitar nuevamente desde la biblioteca principal.

Si mysqld no puede inicializar estas dos tablas cuando se inicia la instancia de la base de datos, se permite que mysqld continúe iniciando, pero escribirá un mensaje de advertencia en el registro de errores. En este caso, MySQL nunca admite la actualización de la versión de la tabla para admitir la tabla. A menudo se encuentra al crear versiones.

PD:

  • No intente actualizar manualmente las tablas slave_master_info o slave_relay_log_info, de lo contrario, será bajo su propio riesgo.

  • Cuando el subproceso de copia de la biblioteca continúa funcionando, no se permite ejecutar ninguna instrucción que pueda bloquear las dos tablas, pero se permite ejecutar declaraciones de solo lectura en estas dos tablas.

2. Explicación detallada de la tabla de información de copia

Dado que la información de replicación almacenada en las tablas introducidas en este número es particularmente importante en nuestro proceso de mantenimiento diario de la base de datos, ampliaremos moderadamente la introducción de cada tabla a continuación.

2.1. Slave_master_info

Esta tabla proporciona el hilo de consulta IO para leer la información de ubicación de la biblioteca principal, así como la IP, cuenta, puerto, contraseña y otra información de la biblioteca esclava para conectarse a la biblioteca principal.

La siguiente es la información almacenada en la tabla.

root@localhost : mysql 01:08:29> select * from slave_master_info\G;
*************************** 1. row ***************************
       Number_of_lines: 25
       Master_log_name: mysql-bin.000292
        Master_log_pos: 194
                  Host: 192.168.2.148
             User_name: qfsys
         User_password: letsg0
                  Port: 3306
         Connect_retry: 60
           Enabled_ssl: 0
                Ssl_ca:
            Ssl_capath:
              Ssl_cert:
            Ssl_cipher:
               Ssl_key:
Ssl_verify_server_cert: 0
             Heartbeat: 5
                  Bind:
    Ignored_server_ids: 0
                  Uuid: ec123678-5e26-11e7-9d38-000c295e08a0
           Retry_count: 86400
               Ssl_crl:
           Ssl_crlpath:
 Enabled_auto_position: 0
          Channel_name:
           Tls_version:
1 row in set (0.00 sec)

La relación correspondiente entre los campos de la tabla y los campos de salida de mostrar estado del esclavo, la información de la fila en el archivo master.info y los significados de los campos de la tabla son los siguientes:

Número de líneas en el archivo master.info campos de tabla mysql.slave_master_info muestre el campo de salida del comando de estado del esclavo Campo Descripción
1 Número de líneas [Ninguna] Indica el número de filas de información en master.info o el número de campos de información en la tabla slave_master_info
2 Master_log_name Master_Log_File Indica que el nombre del archivo binlog más reciente de la biblioteca principal se lee actualmente desde el subproceso de E / S de la biblioteca
3 Master_log_pos Read_Master_Log_Pos Indica que la última posición de binlog de la biblioteca principal se lee actualmente desde el subproceso de E / S de la biblioteca
4 Anfitrión Master_Host Indica la E / S de la biblioteca principal o el nombre de host al que está conectado actualmente el subproceso de E / S de la biblioteca esclava
5 Nombre de usuario Master_User Indica el nombre de usuario del subproceso de E / S de la biblioteca esclava que se utiliza para conectarse a la biblioteca principal
6 Contraseña de usuario [Ninguna] Indica la contraseña de usuario utilizada por el subproceso de E / S de la biblioteca esclava para conectarse a la biblioteca principal
7 Puerto Master_Port Representa el puerto de red de la biblioteca principal conectada al hilo IO de la biblioteca esclava
8 Connect_retry Connect_Retry Indica el intervalo de tiempo entre la desconexión del subproceso IO de la biblioteca y la reconexión a la biblioteca principal, en segundos, el valor predeterminado es 60
9 Enabled_ssl Master_SSL_Allowed Indica si la conexión entre maestro y esclavo admite SSL
10 Ssl_ca Master_SSL_CA_File Representa el nombre del archivo de certificación de CA (autoridad de certificación)
11 Ssl_capath Master_SSL_CA_Path Representa la ruta del archivo de certificación de CA (autoridad de certificación)
12 Ssl_cert Master_SSL_Cert Indica el nombre del archivo del certificado SSL
13 Ssl_cipher Master_SSL_Cipher Indica la lista de cifrados que se pueden utilizar en el protocolo de enlace de la conexión SSL
14 Ssl_key Master_SSL_Key Indica el nombre del archivo de claves para la autenticación SSL
15 Ssl_verify_server_cert Master_SSL_Verify_Server_Cert Indica si se debe verificar el certificado del servidor
dieciséis Latido del corazón [Ninguna] Indica el tiempo de intervalo de copia de paquetes de latidos entre el maestro y el esclavo, en segundos
17 Enlazar Master_Bind Indica que la biblioteca esclava se puede usar para conectarse a la interfaz de red de la biblioteca maestra, el valor predeterminado está vacío
18 Ignored_server_ids Replicate_Ignore_Server_Ids Indica qué ID de servidor se debe ignorar al copiar de la biblioteca. Nota: Esta es una lista. El primer número indica el número total de ID de servidor de instancia que se deben ignorar.
19 Uuid Master_UUID Indica el UUID de la biblioteca principal
20 Retry_count Master_Retry_Count Indica el número máximo de veces que la biblioteca esclava puede volver a conectarse a la biblioteca principal
21 Ssl_crl [Ninguna] Ruta al archivo de lista de revocación de certificados SSL
22 Ssl_crl_path [Ninguna] La ruta del directorio que contiene el archivo de lista de revocación de certificados SSL
23 Enabled_auto_position Auto_position Indica si la biblioteca esclava habilita la función de búsqueda automática de ubicación en la biblioteca principal (la búsqueda automática de ubicación se activa cuando se usa 1, y si se usa auto_position = 0, no encontrará automáticamente la ubicación)
24 Nombre del Canal Nombre del Canal Indica el nombre del canal de copia de la biblioteca, un canal representa una fuente de copia
25 Tls_Version Master_TLS_Version 表示在Master上的TLS版本号

2.2. slave_relay_log_info

该表提供查询SQL线程重放的二进制文件对应的主库位置和relay log当前最新的位置。

下面是该表中存储的信息内容。

root@localhost : mysql 10:39:31> select * from slave_relay_log_info\G
*************************** 1. row ***************************
  Number_of_lines: 7
   Relay_log_name: /home/mysql/data/mysqldata1/relaylog/mysql-relay-bin.000205
    Relay_log_pos: 14097976
  Master_log_name: mysql-bin.000060
   Master_log_pos: 21996812
        Sql_delay: 0
Number_of_workers: 16
               Id: 1
     Channel_name:
1 row in set (0.00 sec)

表字段与show slave status输出字段、relay-log.info文件中的行信息对应关系及其表字段含义如下:

relay-log.info文件中的行数 mysql.slave_relay_log_info表字段 show slave status命令输出字段 字段含义描述
1 Number_of_lines [None] 表示relay-log.info中的信息行数或者slave_relay_log_info表中的信息字段数,用于版本化表定义
2 Relay_log_name Relay_Log_File 表示当前最新的relay log文件名称
3 Relay_log_pos Relay_Log_Pos 表示当前最新的relay log文件对应的最近一次完整接收的event的位置
4 Master_log_name Relay_Master_Log_File 表示SQL线程当前正在重放的中继日志对应的主库binlog 文件名
5 Master_log_pos Exec_Master_Log_Pos 表示SQL线程当前正在重放的中继日志对应主库binlog 文件中的位置
6 Sql_delay SQL_Delay 表示延迟复制指定的从库必须延迟主库多少秒
7 Number_of_workers [None] 表示从库当前并行复制有多少个worker线程
8 Id [None] 用于内部唯一标记表中的每一行记录,目前总是1
9 Channel_name Channel_name 表示从库复制通道名称,用于多源复制,一个通道对应一个主库源

什么是中继日志:

  • 中继日志(relay log)与二进制日志(binlog,即,binary log)中,保存的event数据是一样的(但中继日志中还保存了更多的信息),也是由一组包含描述数据库变更的事件数据的文件组成,这些文件名后缀带连续编号,此外,还有一个包含所有正在使用的中继日志文件名称的索引文件。

  • 中继日志中的数据存放格式与二进制日志相同,都可以使用mysqlbinlog命令来提取数据,默认情况下,中继日志保存在datadir下,文件名格式为:host_name-relay-bin.nnnnnn,其中host_name是从库服务器主机名,nnnnnn是文件后缀序列号。连续的中继日志文件从000001开始的连续序列号创建。使用索引文件来跟踪当前正在使用的中继日志文件。默认的中继日志索引文件名保存在datadir下,文件名格式为:host_name-relay-bin.index。

    * 中继日志文件和中继日志索引文件名称可分别使用--relay-log和--relay-log-index参数选项指定值覆盖默认值,如果文件名使用默认值,则要注意主机名称不能修改,否则会报无法打开中继日志的错误,建议使用参数选项指定固定的文件名称前缀。如果已经出现了这种情况发生报错了,那么需要修改index文件中的中继日志文件名和datadir下的中继日志文件名前缀为新的主机名,然后重启从库。

在什么情况下会产生新的中继日志文件。

  • I/O线程启动时。

  • 使用语句:FLUSH LOGS或mysqladmin flush-logs命令时。

  • 当前中继日志文件的大小变得“太大”时,日志滚动规则如下:

    * 如果max_relay_log_size系统变量的值大于0,那么中继日志按照此参数指定的大小进行滚动。

    * 如果max_relay_log_size系统变量的值为0,则中继日志按照max_binlog_size系统变量指定的大小进行滚动。

SQL线程在执行完relay log之后,会自行决定何时清理掉这些已经执行完成的relay log文件,但如果使用FLUSH LOGS语句或mysqladmin flush-logs命令强制滚动中继日志时,SQL线程可能会同时清理掉已经执行完成的relay log文件。

2.3. slave_worker_info

该表提供查询多线程复制时的worker线程状态信息,与performance_schema.replication_applier_status_by_worker表的区别是:slave_worker_info表记录worker线程重放的relay log和主库binlog位置信息,而performance_schema.replication_applier_status_by_worker表记录的是worker线程重放的GTID位置信息。

下面是该表中存储的信息内容。

root@localhost : mysql 01:09:39> select * from slave_worker_info limit 1\G;
*************************** 1. row ***************************
                        Id: 1
            Relay_log_name:
             Relay_log_pos: 0
           Master_log_name:
            Master_log_pos: 0
 Checkpoint_relay_log_name:
  Checkpoint_relay_log_pos: 0
Checkpoint_master_log_name:
 Checkpoint_master_log_pos: 0
          Checkpoint_seqno: 0
     Checkpoint_group_size: 64
   Checkpoint_group_bitmap:
              Channel_name:
1 row in set (0.00 sec)

表字段含义。

  • Id:表中数据的ID,也是worker线程的ID,对应着performance_schema.replication_applier_status_by_worker表的WORKER_ID字段(如果复制停止,则该字段值仍然存在,不像performance_schema.replication_applier_status_by_worker表中THREAD_ID字段值会清空)。

  • Relay_log_name:每个worker线程当前最新执行到的relay log文件名。

  • Relay_log_pos:每个worker线程当前最新执行到的relay log文件中的position。

  • Master_log_name:每个worker线程当前最新执行到的主库binary log文件名。

  • Master_log_pos:每个worker线程当前最新执行到的主库binary log文件中的position。

  • Checkpoint_relay_log_name:每个worker线程最新检查点的relay log文件名。

  • Checkpoint_relay_log_pos:每个worker线程最新检查点的relay log文件中的position。

  • Checkpoint_master_log_name:每个worker线程最新检查点对应主库的binary log文件名。

  • Checkpoint_master_log_pos:每个worker线程最新检查点对应主库的binary log文件中的position。

  • Checkpoint_seqno:每个worker线程当前最新执行完成的事务号,这个事务号的大小值是相对于每个worker线程自己的最新检查点而言的,并不是真正的事务号。

  • Checkpoint_group_size:表示每个worker线程的执行队列大于这个字段值时,就会触发当前worker线程执行一次检查点。

  • Checkpoint_group_bitmap:用于从库crash之后recovery的关键值,它是一个位图值,表示每个worker线程在自己的最新检查点中已经执行的事务。

  • Channel_name:复制通道名称,多主复制时,显示指定的复制通道名称,单主复制时该字段为空。


该表中记录的内容对从库多线程复制crash recovery至关重要,所以下文对该表中记录的内容如何作用于crash recovery过程进行一些必要的说明。


从库多线程复制如何做复制分发。

  • 我们知道在MySQL 5.7中加入了基于事务的并行复制(基于行),主库在binlog的GTID事件中新加入了last_commit和sequence_number标记,用于表示在每个binlog中的每个group中的提交顺序(每个binlog中重置这两个计数标记),在每个给定的binlog中,每个group中的last_commit总是为上一个group中最大的sequence_number、总是为当前group中最小的sequence_number - 1(在每个binlog中,last_commit总是从0开始计数,sequence_number总是从1开始计数)。

  • 从库relay log中记录的主库binlog,不会改变主库的server id、时间戳信息以及last_commit和sequence_number值,这样,从库SQL线程在执行binlog重放时,就可以依据这些信息决定从库是否需要严格按照主库提交顺序进行提交(从库重放的事务只是分发顺序按照主库提交顺序,但是从库自己在提交这些事务时是否按照主库提交顺序进行提交,还需要看从库自己的slave_preserve_commit_order变量设置,设置为1则严格按照relay log中的顺序进行提交,设置为0从库会自行决定提交顺序)。

  • SQL线程并行分发原理。

    * SQL协调器线程读取到一个新的事务,取出last_commit和sequence_number值。

    * SQL协调器线程判断取出的新事务的当前last_commit是否大于当前已执行完成的sequence_number中的最小值(Low water mark,简称LWM,也叫低水位线标记)。

    * 如果SQL协调器线程读取到的当前事务的last_commit大于当前已执行完成的sequence_number值,则说明上一个group中的事务还没有全部执行完成,此时SQL协调器线程需要等待所有的worker线程执行完成上一个group中的事务,等待LWM变大,直到当前读取到的事务的last_commit与当前已执行完成的事务的最小sequence_number值相等才可以继续分发新的事务给空闲的worker线程(并行复制是针对每个group内的事务才可以并行复制,所以,group之间是串行的,一个group未执行完成之前,下一个group的事务是需要进行等待的。只有同一个group内的事务之间才可以并行执行。根据上文中的描述,每个group中的事务的last_commit总是为当前group中最小的sequence_number - 1,即,如果SQL协调器线程读取到的当前事务的last_commit小于当前已执行完成事务的最小的sequence_number 就说明当前所有worker线程正在执行的事务处于同一个group中,那么也就是说SQL协调器线程可以继续往下寻找空闲的worker线程进行分发,否则SQL协调器线程就需要进行等待)。

    * SQL协调器线程通过统计worker线程返回的状态信息,寻找一个空闲的worker线程,如果没有空闲的线程,则SQL协调器线程需要进行等待,知道找到一个空闲的worker线程为止(如果有多个worker线程,则SQL协调器线程随机选择一个空闲的worker线程进行分发)。

    * 将当前读取到的事务的binlog event分发给选定的空闲worker线程,之后worker线程会去应用这个事务,然后SQL协调器线程继续读取新的binlog event(注意,SQL协调器线程分发是按照event为单位的,不是事务单位,所以,如果当一个事务的第一个event分发给了给定worker线程之后,后续读取到的新的event如果同属于一个事务,则进入下一个事务之前的所有event都会分发给同一个worker线程处理。当一个事务中所有的binlog event组分发完成,读取到下一个新的事务时,SQL协调器线程会重复以上判断流程)。

从库多线程复制的crash recovery。

  • 从前面多线程复制分发的原理我们可以知道,处于同一个group中的事务是并行应用的,且事务是随机分配的,在从库正常运行过程当中,如果任意掐一刻下去,那么所有worker线程正在执行的事务中,哪些是已经执行完成的,哪些还未执行完成其实是无法使用单个位置来确定(因为从库并行复制时有可能是乱序提交:需要看slave_preserve_commit_order变量如何设置),也就是说所有worker线程中正在执行的最大位置和最小位置之间可能有断点。那MySQL是如何解决从库crash recovery的断点续做问题的呢?

  • MySQL 为了解决这个问题,对worker线程的执行状态做了很多记录工作,首先,维护了一个队列,这个队列叫做GAQ(Group Assigned Queue),当SQL协调器线程在分配某一个事务时,首先会将这个事务加入到这个队列,然后,才会去按照规则来寻找一个空闲的worker线程来执行,如下图(郑重声明:该图来自书籍《MySQL 运维内参》):

每一个事务在分发到worker线程之后,都会分配一个编号,这个编号在某一段时间内,都是相对固定的,这个编号一旦被分配,就不会再改变。在事务被某个worker线程执行完成之后,它的位置信息就会被flush一次,这与5.5版本中的relay_log_info记录的原理是类似的(relay_log_info中存放了从库当前SQL线程重放的位置),但是现在是多线程,每个worker线程的执行位置不能直接存放在relay_log_info中了,relay_log_info中存放的是所有worker线程汇总之后的位置,每个worker线程独立的位置信息存放在了mysql.slave_worker_info表中,在该表中,有多少个并行复制线程,就有多少行记录(如果是多主复制,则每个复制通道都有slave_parallel_workers变量指定的记录数)。

mysql.slave_worker_info表中,Checkpoint开头的字段记录了每个worker线程的检查点相关的信息(这里与innodb存储引擎的检查点不同,但是概念相通),worker线程的检查点的作用是什么呢?

  • 前面说了SQL协调器线程在分配事务给worker线程之前会将事务先存放到GAQ队列中,但是这个队列的长度是有限的(是不是很熟悉?跟redo log的总大小是有限的概念类似),不可能无限制的增长下去,所以必须要在这个队列中,找到一个位置点,这个位置点就是GAQ的起点位置,这个位置点之前的binlog就表示已经执行完成了。确定这个位置的过程,就叫做检查点。在多线程复制的执行过程中,随着每个worker线程不断第应用事务的binlog,检查点在GAQ中被不断地向前推进,每个worker线程通过Checkpoint_point_bitmap字段记录自己已经执行过的事务和每个已执行事务与之对应的当时的最新检查点的相对位置,这样一来,当复制意外终端之后,重新开始复制时,就可以通过所有的worker线程记录的Checkpoint_point_bitmap字段来计算出哪些事务是已经执行过的,哪些事务是还未执行的,即通过所有worker线程记录的Checkpoint_point_bitmap信息执行一次检查点操作就可以找到一个合适的恢复位置,执行检查点的大概过程如下(注意:这里是执行检查点的过程,与从库crash recovery过程无关):

    * 在GAQ队列中,从尾部开始扫描,如果是已经执行过的事务,则直接将其从队列中删除。

    * 持续扫描GAQ队列,直到找到一个未执行过的事务为止即停止扫描。

    * 上述步骤中扫描动作停止前扫描到的最后一个事务被确定为检查点的最新位置,并且别标记为LWM(低水位线标记)。

    * 将当前LWM这个事务对应的位置(master_log_pos和relay_log_pos位置)设置为此次检查点对应的位置。

    * 通过所有的worker线程检查自己的检查点,也就是查看每个worker线程自己的Checkpoint_seqno字段值,这个字段值是每个worker线程在执行事务提交时更新的,更新的字段值为每个worker线程在做事务提交时对应的最新检查点的相对位置。

    * 将本次执行检查点的位置记录到mysql.slave_relay_log_info表中,作为全局binlog应用的位置。

  • 现在,我们来看从库crash recovery的过程:

    * 首先,读取mysql.slave_master_info、mysql.slave_relay_log_info、mysql.slave_worker_info表中的信息读取出来,从mysql.slave_master_info表中找到连接主库的信息,从mysql.slave_relay_log_info表中找到全局最新的复制位置以及worker线程个数,从mysql.slave_worker_info表中找到每一个worker线程对应的复制信息位置。

    * 然后,根据mysql.slave_relay_log_info表中的位置(这个位置就是全局最新的检查点位置)为准来判断所有worker线程的位置,在这个位置之前的worker线程位置就表示已经执行过的了,直接剔除,在这个位置之后的worker线程位置就表示这些事务是还没有执行过的(根据每个worker线程在mysql.slave_worker_info表中记录的Checkpoint_seqno和Checkpoint_group_bitmap字段计算出自己哪些事务没有执行过,然后通过每个worker线程在mysql.slave_worker_info表中记录的其他checkpoint字段信息转换为对应的全局检查点的位置。然后根据所有worker线程的转换位置信息汇总为一个共同的bitmap,根据这个共同的bitmap来比对mysql.slave_relay_log_info表中的位置就可以提取出哪些事务还没有执行过),找出了哪些事务还没有执行之后,把这些事务串行地一个一个地去重新应用(应用一个更新一次mysql.slave_relay_log_info表,为什么要串行,这是为了在恢复过程中如果再次跪了,还可以正确地恢复位置),应用完成之后清空mysql.slave_worker_info表。然后启动复制线程,继续从主库拉取最新的binlog进行数据复制。

PS:如果在主从复制架构中,有2个以上的从库,且从库永远不做提升主库的操作时,可以使用如下方法优化从库延迟(在该场景下,从库无需担心数据丢失问题,因为有另外一个从库兜底+不做主从切换,只需要专心提供快速应用主库binlog与只读业务即可)。

  • 关闭log_slave_updates参数,减少从库binlog写入量(如果不做级联复制甚至可以同时关闭binlog)。

  • 设置innodb_flush_log_at_trx_commit为0或者2,减少事务提交时redo log的等待频率。

  • 设置sync_binlog为默认值或者更大的值,减少事务提交时binlog的等待频率。

  • 设置slave_preserve_commit_order参数为OFF(默认为OFF,设置为ON时要求开启binlog和log_slave_updates参数),减少事务严格按照主库顺序提交时的提交等待时间。

2.4. gtid_executed

前面介绍的三张表中,存放的都不包括GTID信息,在数据库运行过程中,GTID相关的信息是保存在performance_schema下的相关表中,详见"全方位认识 performance_schema"系列文章《复制状态与变量记录表 | performance_schema全方位介绍》。但是performance_schema下的表都是内存表,记录的信息是易失的。gtid_executed表才是GTID信息的持久表,该表提供查询与当前实例中的数据一致的GTID集合(该表用于存储所有事务分配的 GTID集合,GTID集合由UUID集合构成,每个UUID集合的组成为:uuid:interval[:interval]...,例如 :28b13b49-3dfb-11e8-a76d-5254002a54f2:1-600401,3ff62ef2-3dfb-11e8-a448-525400c33752:1-110133)

  • GTID是在整个复制拓扑中是全局唯一的,GTID中的事务号是一个单调递增的无间隙数字。正常情况下,客户端的数据修改在执行commit时会分配一个GTID,且会记录到binlog中,这些GTID通过复制组件在其他实例中进行重放时也会保留GTID来源不变。但是如果客户端自行使用sql_log_bin变量关闭了binlog记录或者客户端执行的是一个只读事务,那么server不会分配GTID,在binlog中也不会有GTID记录。

  • 当某个从库接受到自己的GTID集合中已经包含的GTID时,会忽略这个已存在的GTID,并且不会报错,事务也不会被执行。

从MySQL 5.7.5开始,GTID存储在mysql数据库的名为gtid_executed的表中。对于每个GTID集合,默认情况下值记录每个GTID集合的起始和结束的事务号对应的GTID,该表只在数据库初始化或者执行update_grade升级的时候创建,不允许手工创建于修改。当实例本身有客户端访问数据写入或者有从其他主库通过复制插件同步数据的时候,该表中会有新的GTID记录写入,另外,该表中的记录还会在binlog滚动或者实例重启的时候被更新(日志滚动时该表需要把除了最新的binlog之外其他binlog中的所有GTID结合记录到该表中,实例重启时,需要把所有的binlog中的GTID集合记录到该表中)。

由于有mysql.gtid_executed表记录GTID(避免了binlog丢失的时候丢失GTID历史记录),所以,从5.7.5版本开始,在复制拓扑中的从库允许关闭binlog,也允许在binlog开启的情况下关闭log_slave_updates变量。

由于GTID必须要再gtid_mode为ON或者为ON_PERMISSIVE时才会生成,所以自然该表中的记录也需要依赖于gtid_mode变量为ON或ON_PERMISSIVE时才会进行记录,另外,该表中是否实时存储GTID,取决于binlog日志是否开启,或者binlog启用时是否启用log_slave_updates变量,如下:

  • 当禁用二进制日志记录(log_bin为OFF),或者启用binlog但禁用log_slave_updates,则Server会在每个事物提交时把属于该事物的GTID同时更新到该表中。此时,该表的GTID周期性自动压缩功能激活,每达到gtid_executed_compression_period系统变量指定的事物数量压缩一次该表中的GTID集合(也就是把每个UUID对应的事务号的记录取一个最大值,取一个最小值,删除中间值),要注意:周期性自动压缩功能仅针对从库,对主库无效,因为主库必须启用binlog,且log_slave_updates参数不影响主库。

  • 如果启用二进制日志记录(log_bin为ON)且log_slave_updates参数也启用,则周期性自动压缩功能失效,该表中的记录只会在binlog日志滚动或者服务器关闭时才会进行压缩,且会把除了最后一个binlog之外,其他所有binlog中包含的GTID集合写入该表中。

  • 注意:

    * 如果启用二进制日志记录(log_bin为ON)且log_slave_updates参数也启用,那么该表不会实时记录GTID,也就是说,完整的GTID集合,有一部分记录在该表中,有一部分是记录在binlog中的,如果一旦server发生crash,那么在crash recovery时会读取binlog中最新的GTID集合并合并到该表中。

    * 该表中的记录在执行reset master语句时会被清空。

该表中的记录周期性执行压缩示例。

# 假设表中有如下实时记录的GTID记录
mysql> SELECT * FROM mysql.gtid_executed;
+ -------------------------------------- + ---------- ------ + -------------- +
| source_uuid | interval_start | interval_end |
| -------------------------------------- + ---------- ------ + -------------- |
| 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 37 | 37 |
| 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 38 | 38 |
| 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 39 | 39 |
| 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 40 | 40 |
| 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 41 | 41 |
| 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 42 | 42 |
| 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 43 | 43 |
...
# 那么,每达到gtid_executed_compression_period变量定义的事务个数时,激活压缩功能,GTID被压缩为一行记录,如下
+ -------------------------------------- + ---------- ------ + -------------- +
| source_uuid | interval_start | interval_end |
| -------------------------------------- + ---------- ------ + -------------- |
| 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 37 | 43 |
...
# 注意:当gtid_executed_compression_period系统变量设置为0时,周期性自动压缩功能失效,你需要预防该表被撑爆的风险

表字段含义。

  • source_uuid:代表数据来源的GTID集合。

  • interval_start:每个UUID集合的最小事务号。

  • interval_end:每个UUID集合的最大事务号。

La función de compresión para esta tabla la realiza un hilo de primer plano dedicado llamado thread / sql / compress_gtid_table. Este hilo no se puede ver usando SHOW PROCESSLIST, pero se puede ver en la tabla performance_schema.threads (thread thread / sql / compress_gtid_table la mayor parte del tiempo está inactivo hasta que después de cada gtid_executed_compression_period completo, el hilo se despierta para ejecutar el anterior Compresión de la tabla mysql.gtid_executed descrita anteriormente. Luego continúe ingresando al estado de suspensión hasta las siguientes transacciones completas gtid_executed_compression_period, y luego se despierte para realizar la compresión nuevamente, y así sucesivamente, repita este ciclo indefinidamente. Pero si apaga binlog o habilita binlog pero lo apaga Log_slave_updates variable, la variable gtid_executed_compression_period se establece en 0, lo que significa que el hilo siempre estará inactivo y nunca se activará), como se muestra a continuación:

mysql> SELECT * FROM performance_schema.threads WHERE NAME LIKE '%gtid%'\G
*************************** 1. row ***************************
          THREAD_ID: 26
               NAME: thread/sql/compress_gtid_table
               TYPE: FOREGROUND
     PROCESSLIST_ID: 1
   PROCESSLIST_USER: NULL
   PROCESSLIST_HOST: NULL
     PROCESSLIST_DB: NULL
PROCESSLIST_COMMAND: Daemon
   PROCESSLIST_TIME: 1509
  PROCESSLIST_STATE: Suspending
   PROCESSLIST_INFO: NULL
   PARENT_THREAD_ID: 1
               ROLE: NULL
       INSTRUMENTED: YES
            HISTORY: YES
    CONNECTION_TYPE: NULL
       THREAD_OS_ID: 18677

2.5. ndb_binlog_index

Esta tabla proporciona estadísticas de consultas relacionadas con el motor de clúster de ndb. Dado que el motor de almacenamiento de NDB rara vez se usa en China, no introduciré demasiado aquí. Los interesados ​​pueden estudiarlo por sí mismos.

El contenido de este número se presenta aquí, y el enlace de referencia para el contenido de este número es el siguiente:

https://dev.mysql.com/doc/refman/5.7/en/replication-gtids-concepts.html#replication-gtids-gtid-executed-table

"¡Escalando esta montaña, puedes ver un trozo de mar!". Siga leyendo nuestra serie de artículos "Comprensión completa de la biblioteca del sistema MySQL" para compartir, y podrá aprenderlos sistemáticamente. Gracias por leer, ¡nos vemos en el próximo número!

"

| Sobre el autor

Luo Xiaobo · Experto en tecnología de base de datos ScaleFlux

Uno de los autores de "A Thousand Golden Recipes-MySQL Performance Optimization Pyramid Rule", "Data Ecology: MySQL Replication Technology and Production Practice".

熟悉MySQL体系结构,擅长数据库的整体调优,喜好专研开源技术,并热衷于开源技术的推广,在线上线下做过多次公开的数据库专题分享,发表过近100篇数据库相关的研究文章。

全文完。

Enjoy MySQL :)

叶老师的「MySQL核心优化」大课已升级到MySQL 8.0,扫码开启MySQL 8.0修行之旅吧

Supongo que te gusta

Origin blog.csdn.net/n88Lpo/article/details/110600179
Recomendado
Clasificación