El impacto de la configuración de los parámetros de transmisión de datos de MySQL en la consistencia de los datos

A través de una prueba integral y sistemática, el autor revela el impacto de la configuración de lower_case_table_names en la consistencia de los datos.

Autor: Liu An

Miembro del equipo de pruebas de Acson, principalmente responsable de las tareas de prueba relacionadas con el proyecto de código abierto DTLE, y es bueno en el desarrollo de pruebas automatizadas de Python.

Fuente de este artículo: contribución original

  • Producido por la comunidad de código abierto de Aikesheng, no se permite usar el contenido original sin autorización, comuníquese con el editor e indique la fuente para la reimpresión.

fondo

Recientemente, un cliente preguntó: ¿DTLE puede sincronizar datos normalmente cuando las configuraciones de MySQL de origen y MySQL de destino son inconsistentes?lower_case_table_names

Este artículo prueba lower_case_table_namesel impacto de la configuración en los datos de sincronización DTLE en este problema.

lower_case_table_namesPara simplificar el escenario, aquí solo discutimos la configuración de 0o en el entorno Linux 1.

Preparación ambiental

  1. Implementar DTLE 4.23.04.2
  2. Dos instancias de MySQL con lower_case_table_namesdiferentes configuraciones
# lower_case_table_names=0
$ dbdeployer deploy single 5.7 --port 3306 --sandbox-directory sandbox --port-as-server-id --remote-access % --bind-address 0.0.0.0 -c skip-name-resolve -c binlog_format=ROW -c binlog_row_image=FULL -c log_slave_updates=ON --gtid -c lower_case_table_names=0

# lower_case_table_names=1
$ dbdeployer deploy single 5.7 --port 3306 --sandbox-directory sandbox --port-as-server-id --remote-access % --bind-address 0.0.0.0 -c skip-name-resolve -c binlog_format=ROW -c binlog_row_image=FULL -c log_slave_updates=ON --gtid -c lower_case_table_names=1

el primer caso

  • Fuente MySQL@@lctn=0
  • Objetivo MySQL@@lctn=1

Según la documentación de desarrollo de DTLE , el comportamiento de DTLE en este caso:

  • El origen se ejecuta en el caso original.
  • El extremo de destino recibe BinlogEntry: DML/DDL se ejecuta en el caso original y MySQL lo convertirá automáticamente a minúsculas.

Los siguientes son los resultados de la sincronización de datos de ejecutar algunos SQL típicos:

Fuente SQL y datos datos del segmento objetivo
CREAR BASE DE DATOS ACTION_DB;

mysql> MOSTRAR BASES DE DATOS\G
** 1. fila **
Base de datos: ACTION_DB
mysql> MOSTRAR BASES DE DATOS\G
** 1. fila **
Base de datos: action_db
** 2. fila **
Base de datos: dtle
CREAR TABLA ACTION_DB.A(id int(11))
MOTOR=InnoDB DEFAULT CHARSET=utf8;

mysql> MOSTRAR TABLAS\G
** 1. fila **
Tablas_en_ACTION_DB: A
mysql> MOSTRAR TABLAS\G
** 1. fila **
Tables_in_action_db: a
INSERTAR EN ACTION_DB.A VALORES (1);

mysql> SELECCIONE * DESDE ACTION_DB.A\G
** 1. fila **
id: 1
mysql> SELECCIONE * DESDE ACTION_DB.A\G
** 1. fila **
id: 1
ALTER TABLE ACTION_DB.A ADD D CHAR(20);

mysql> MOSTRAR CREAR TABLA ACCIÓN_DB.A\G
** 1. fila **
Tabla: A

Crear tabla: CREAR TABLA `A` (
`id` int(11) NULO POR DEFECTO,
`D` char(20) NULO POR DEFECTO
) MOTOR =CONJUNTO DE CARACTERES POR DEFECTO InnoDB=utf8
mysql> MOSTRAR CREAR TABLA ACTION_DB.A\G
** 1. fila **
Tabla: A

Crear tabla: CREAR TABLA `a` (
`id` int(11) NULO POR DEFECTO,
`D` char(20) NULO POR DEFECTO
) MOTOR =CONJUNTO DE CARACTERES POR DEFECTO InnoDB=utf8
ALTERAR TABLA ACTION_DB.A RENOMBRAR A ACTION_DB.B;

mysql> MOSTRAR TABLAS\G
** 1. fila **
Tablas_en_ACTION_DB: B
mysql> MOSTRAR TABLAS\G
** 1. fila **
Tables_in_action_db: b
DROP TABLE ACTION_DB.B;

mysql> MOSTRAR TABLAS\G
Conjunto vacío (0.00 seg)
mysql> MOSTRAR TABLAS\G
Conjunto vacío (0.00 seg)

Se puede ver que los datos después de la sincronización DTLE están en línea con las expectativas. El caso de MySQL en el lado de origen es el mismo que el de SQL, y MySQL en el lado de destino se convierte automáticamente a minúsculas.


Veamos algunos casos extremos:

Datos y SQL del lado del origen datos objetivo
CREAR BASE DE DATOS ACTION_DB;

mysql> MOSTRAR BASES DE DATOS\G
** 1. fila **
Base de datos: ACTION_DB
mysql> MOSTRAR BASES DE DATOS\G
** 1. fila **
Base de datos: action_db
** 2. fila **
Base de datos: dtle
CREATE DATABASE action_db;

mysql> SHOW DATABASES\G
** 1. row **
Database: ACTION_DB
** 2. row **
Database: action_db
mysql> SHOW DATABASES\G
** 1. row **
Database: action_db
** 2. row **
Database: dtle
CREATE TABLE ACTION_DB.A(id int(11))
ENGINE=InnoDB DEFAULT CHARSET=utf8;

mysql> use ACTION_DB
mysql> SHOW TABLES\G
** 1. row **
Tables_in_ACTION_DB: A
mysql> use action_db
mysql> SHOW TABLES\G
** 1. row **
Tables_in_action_db: a
CREATE TABLE ACTION_DB.a(id int(11))
ENGINE=InnoDB DEFAULT CHARSET=utf8;

mysql> use ACTION_DB
mysql> SHOW TABLES\G
** 1. row **
Tables_in_ACTION_DB: A
** 2. row **
Tables_in_ACTION_DB: a
mysql> SHOW TABLES\G
** 1. row **
Tables_in_action_db: a
CREATE TABLE action_db.A(id int(11))
ENGINE=InnoDB DEFAULT CHARSET=utf8;

mysql> USE action_db
mysql> SHOW TABLES\G
** 1. row **
Tables_in_action_db: A
mysql> SHOW TABLES\G
** 1. row **
Tables_in_action_db: a
CREATE TABLE action_db.a(id int(11))
ENGINE=InnoDB DEFAULT CHARSET=utf8;

mysql> USE action_db
mysql> SHOW TABLES\G
** 1. row **
Tables_in_action_db: A
** 2. row **
Tables_in_action_db: a
mysql> SHOW TABLES\G
** 1. row **
Tables_in_action_db: a
INSERT INTO ACTION_DB.A VALUES (1);

mysql> SELECT * FROM ACTION_DB.A\G
** 1. row **
id: 1
mysql> SELECT * FROM action_db.a\G
** 1. row **
id: 1
INSERT INTO ACTION_DB.a VALUES (2);

mysql> SELECT * FROM ACTION_DB.a\G
** 1. row **
id: 2
mysql> SELECT * FROM action_db.a\G
** 1. row **
id: 1
** 2. row **
id: 2
INSERT INTO action_db.A VALUES (3);

mysql> SELECT * FROM action_db.A\G
** 1. row **
id: 3
mysql> SELECT * FROM action_db.a\G
** 1. row **
id: 1
** 2. row **
id: 2
** 3. row **
id: 3
INSERT INTO action_db.a VALUES (4);

mysql> SELECT * FROM action_db.a\G
** 1. row **
id: 4
mysql> SELECT * FROM action_db.a\G
** 1. row **
id: 1
** 2. row **
id: 2
** 3. row **
id: 3
** 4. row **
id: 4

可以看到此时 DTLE 的行为,相当于把 ACTION_DB.AACTION_DB.aaction_db.Aaction_db.a 四个表的数据合并到一张表。

所以为了避免此种情况,可以通过在创建 DTLE 作业的时候,为每个重名的库配置 TableSchemaRename 属性、重名表配置 Table.TableRename 属性的方式来解决。

第二种情况

  • 源端 MySQL @@lctn=1
  • 目标端MySQL @@lctn=0

根据 DTLE 的开发文档 里面介绍,此种情况下的 DTLE 行为:

  • 用户填写的复制范围,应转化为小写。
  • 不复制已有的大写 SCHEMA.TABLE
  • 新增的 Schema.Table,转化为小写后,加入复制范围。
  • 目标端无论 @@lctn=0@@lctn=1,都应该复制源端的效果,即小写。
  • 目标端收到的 BinlogEntry 中,schema.tableName 已为小写。

以下是执行一些典型 SQL 的数据同步结果:

源端 SQL 和数据 目标端数据
CREATE DATABASE ACTION_DB;

mysql> SHOW DATABASES\G
** 1. row **
Database: action_db
mysql> SHOW DATABASES\G
** 1. row **
Database: action_db
** 2. row **
Database: dtle
CREATE TABLE ACTION_DB.A(id int(11))
ENGINE=InnoDB DEFAULT CHARSET=utf8;

mysql> SHOW TABLES\G
** 1. row **
Tables_in_action_db: a
mysql> SHOW TABLES\G
** 1. row **
Tables_in_action_db: a
INSERT INTO ACTION_DB.A VALUES (1);

mysql> SELECT * FROM ACTION_DB.A\G
** 1. row **
id: 1
mysql> SELECT * FROM action_db.a\G
** 1. row **
id: 1
ALTER TABLE ACTION_DB.A ADD D CHAR(20);

mysql> SHOW CREATE TABLE ACTION_DB.A\G
** 1. row **
Table: A

Create Table: CREATE TABLE `a` (
`id` int(11) DEFAULT NULL,
`D` char(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
mysql> SHOW CREATE TABLE action_db.a\G
** 1. row **
Table: a

Create Table: CREATE TABLE `a` (
id int(11) DEFAULT NULL,
`D` char(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
ALTER TABLE ACTION_DB.A RENAME TO ACTION_DB.B;

mysql> SHOW TABLES\G
** 1. row **
Tables_in_action_db: b
mysql> SHOW TABLES\G
** 1. row **
Tables_in_action_db: b
DROP TABLE ACTION_DB.B;

mysql> SHOW TABLES\G
Empty set (0.00 sec)
mysql> SHOW TABLES\G
Empty set (0.00 sec)

可以看到 DTLE 同步后的数据是符合预期。在源端 MySQL 自动转为小写,在目标端 MySQL 同步的数据也是小写的。

其他限制

通过观察 general log 可以得知,DTLE 作业是在初始化作业的时候获取源端以及目标端 MySQL 的 lower_case_table_names 配置的,所以在 DTLE 作业存续期间更改 MySQL 的该参数是 DTLE 无法感知并处理的。因此禁止在 DTLE 作业存续期间更改此配置。

总结

  1. 原则上 DTLE 还是建议源端和目标端设置相同。
  2. 当源端 MySQL @@lctn=0 且目标端 MySQL @@lctn=1 时,需要注意源端仅大小写不同的同名库表在目标端会汇聚到同一个表中的问题。
  3. DTLE 作业存续期间,MySQL 上的 lower_case_table_names 配置不可改变。

关于 SQLE

爱可生开源社区的 SQLE 是一款面向数据库使用者和管理者,支持多场景审核,支持标准化上线流程,原生支持 MySQL 审核且数据库类型可扩展的 SQL 审核工具。

SQLE 获取

类型 地址
版本库 https://github.com/actiontech/sqle
文档 https://actiontech.github.io/sqle-docs/
发布信息 https://github.com/actiontech/sqle/releases
Documentación de desarrollo del complemento de auditoría de datos https://actiontech.github.io/sqle-docs-cn/3.modules/3.7_auditplugin/auditplugin_development.html

Supongo que te gusta

Origin blog.csdn.net/ActionTech/article/details/131580202
Recomendado
Clasificación