MySQL 数据传输参数设置对数据一致性的影响

这篇具有很好参考价值的文章主要介绍了MySQL 数据传输参数设置对数据一致性的影响。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

作者通过全面系统的测试,揭秘 lower_case_table_names 设置对数据一致性的影响。

作者:刘安

爱可生测试团队成员,主要负责 DTLE 开源项目相关测试任务,擅长 Python 自动化测试开发。

本文来源:原创投稿

  • 爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。

背景

最近有客户询问:源端 MySQL 和目标端 MySQL 的 lower_case_table_names 的配置不一致时,DTLE 是否能正常同步数据?

本文就这个问题测试一下 lower_case_table_names 的设置对 DTLE 同步数据的影响。

为了简化场景这里只讨论 Linux 环境下 lower_case_table_names 配置为 01 的情况。

环境准备

  1. 部署 DTLE 4.23.04.2
  2. 两个 MySQL 实例,lower_case_table_names 配置不同
# 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

第一种情况

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

根据 DTLE 的开发文档 可知,此种情况下的 DTLE 行为:

  • 源端按原大小写执行。
  • 目标端收到 BinlogEntry - DML/DDL 按原大小写执行,MySQL 会自动转为小写。

以下是执行一些典型 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 与 SQL 的大小写一致,在目标端 MySQL 自动转为小写。


接下来看一些极端情况:

源端 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 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 审核工具。文章来源地址https://www.toymoban.com/news/detail-529969.html

SQLE 获取

类型 地址
版本库 https://github.com/actiontech/sqle
文档 https://actiontech.github.io/sqle-docs/
发布信息 https://github.com/actiontech/sqle/releases
数据审核插件开发文档 https://actiontech.github.io/sqle-docs-cn/3.modules/3.7_auditplugin/auditplugin_development.html

到了这里,关于MySQL 数据传输参数设置对数据一致性的影响的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • MySQL和Redis如何保证数据一致性?

    由于缓存的高并发和高性能已经在各种项目中被广泛使用,在读取缓存这方面基本都是一致的,大概都是按照下图的流程进行操作: 但是在更新缓存方面,是更新完数据库再更新缓存还是直接删除缓存呢?又或者是先删除缓存再更新数据库?在这一点上就值得探讨了。 在实

    2024年02月01日
    浏览(51)
  • MySQL和Redis如何保证数据一致性

    MySQL与Redis都是常用的数据存储和缓存系统。为了提高应用程序的性能和可伸缩性,很多应用程序将MySQL和Redis一起使用,其中MySQL作为主要的持久存储,而Redis作为主要的缓存。在这种情况下,应用程序需要确保MySQL和Redis中的数据是同步的,以确保数据的一致性。 “数据一致

    2024年02月12日
    浏览(58)
  • 如何保障MySQL和Redis的数据一致性?

    先抛一下结论:在满足实时性的条件下,不存在两者完全保存一致的方案,只有最终一致性方案。根据网上的众多解决方案,总结出 6 种,直接看目录:     不好的方案   1、先写 MySQL,再写 Redis       如图所示:   这是一副时序图,描述请求的先后调用顺序;   橘黄色的

    2024年02月08日
    浏览(47)
  • mysql和redis如何保证数据库一致性

    如果对于小公司的单机服务器来说在更新和删除mysql数据的同时对redis缓存进行更新或者删除就行,一般有两个选择,例如: 先更新MySQL,后删除(或更新)Redis 先删除(或更新)Redis,后更新MySQL 但是不管使用其中哪种方式,都存在两个可能的问题: 由于第一步与第二步并不是原

    2023年04月24日
    浏览(47)
  • Redis缓存MySQL数据库存储二者如何保证数据一致性

    在大型互联网应用中,由于数据库读写频繁、压力大等原因,我们通常会使用缓存来减少数据库的访问次数,提高系统的性能。而Redis作为一个高性能的内存数据库,成为了缓存的首选方案之一。但是,缓存和数据库之间存在数据一致性的问题,如何解决这个问题呢?本文将

    2023年04月19日
    浏览(49)
  • 生产实践:Redis与Mysql的数据强一致性方案

    数据库和Redis如何保持强一致性,这篇文章告诉你 Redis和Msql来保持数据同步,并且强一致,以此来提高对应接口的响应速度,刚开始考虑是用mybatis的二级缓存,发现坑不少,于是决定自己搞 操作数据必须是唯一索引 如果更新数据不是唯一索引,则数据库更新后的值,与缓存

    2024年02月05日
    浏览(53)
  • Data Transfer Object-DTO,数据传输对象,前端参数设计多个数据表对象

    用于在业务逻辑层和持久层(数据库访问层)之间传输数据。 DTO的主要目的是将多个实体(Entity)的部分属性或多个实体关联属性封装成一个对象,以便在业务层进行数据传输和处理,从而避免直接暴露实体对象给上层或客户端,即前端的请求设计了多张表的内容 使用步骤

    2024年02月15日
    浏览(93)
  • MySQL 和 Redis 如何保证数据一致性,通过MySQL的binlog实现

    1、简介         MySQL 和 Redis 如何保证数据一致性,目前大多讨论的是先更新Redis后更新MySQL,还是先更新MySQL 后更新Redis,这两种方式在实际的应用场景中都不能确保数据的完全一致性,在某些情况下会出现问题,本文介绍使用 Canal 工具,通过将自己伪装成MySQL的从节点,读

    2024年02月02日
    浏览(55)
  • MySQL与Redis数据双写一致性工程落地案例

    多个线程同时去查询数据库的这条数据,那么我们可以在第一个查询数据的请求上使用一个 互斥锁来锁住它。 其他的线程走到这一步拿不到锁就等着,等第一个线程查询到了数据,然后做缓存。 后面的线程进来发现已经有缓存了,就直接走缓存。   canal [kə\\\'næl],中文翻译

    2024年02月03日
    浏览(88)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包