解决主从复制数据不一致的情况

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介:

主从复制不一致的情况解决:

不一致的原因:
1、 主从切换时,出现的故障
2、 误操作
3、 机器故障等
方法一:利用MySQL原生的mysqldump就可以搞定,对于个别表有锁表的情况。
核心是 mysqldump –single-transaction --master-data=2

       Start slave until MASTER_LOG_FILE=’’, MASTER_LOG_POS=;

       直到sql_thread线程为NO,这之间的同步报错一律跳过即可

方法二:工具:pt-table-sync
有效的同步MySQL 表的数据。

操作前,最好先备份。对于主从结构来讲,它只需要在master上操作即可(无论是 使用的选项是 –reolicate 还是 –sync-to-master)这种方式往往是重新让master和slave保持同步的最安全的方式,直接修改replica可能会带来很多问题。

注意事项; --dry-run 查看该工具用那种算法进行操作。

           --print 如何具体解决主从的不一致的。

           对于主主复制的形式,要相当谨慎。

           当表含有外键,并且是 on delete 或 on update 约束的情况下,建议暂时不用,可能对子表造成意外的破坏。

           部分bug。 --lock-and-rename 对于小于MySQL 5.5 版本的DB是不起作用的(考虑用 pt-online-schema-change 代替?)。

详解:
Pt-table-sync 可以做到对表的数据进行单项或者双向同步。它并不同步表的结构、索引或者其他的数据库对象,仅仅是行记录。
下面先介绍下单向表数据同步

先介绍三个概念: --replicate , find differences , specifying

下面是简短的逻辑:
 
if DSN has a t part, sync only that table:
   if 1 DSN:
      if --sync-to-master:
         The DSN is a slave. Connect to its master and sync.
   if more than 1 DSN:
      The first DSN is the source. Sync each DSN in turn.
else if --replicate:
   if --sync-to-master:
      The DSN is a slave. Connect to its master, find records
      of differences, and fix.
   else:
      The DSN is the master. Find slaves and connect to each,
      find records of differences, and fix.
else:
   if only 1 DSN and --sync-to-master:
      The DSN is a slave. Connect to its master, find tables and
      filter with --databases etc, and sync each table to the master.
   else:
      find tables, filtering with --databases etc, and sync each
      DSN to the first
 

默认情况下, 没有—replicate 选项(该选项使用 几种算法自动发现master和slave之间的不同),另外该选项还能利用 pt-table-checksum 已经检查查来的问题。严格来讲,我们不需要使用 –replicate 选项,因为它可以自动发现表之间数据的不一致。 但人们结合两个工具的原因是: pt-table-checksum 定期的对表数据进行校验,当发现不一致时再用 pt-table-sync进行修复。

如何确定数据同步的方向; 使用 –sync-to-master 或者省略。该选项值需要一个 slave DSN 参数.自动发现该slave的master,并开始于master进行同步。实现的方式 是在 master端 做出改变,通过MySQL 的复制机制让slave与master 重新同步。 注意事项: 如果只有一台slave的 那没有问题,多台slave的话,可能也会受到同样的数据变更。

如果不使用 –sync-to-master 的话,第一个DSN参数则必须是 source host(有且只有一个),,没有 –replicate选项的话,我们必须在写一个 DSN参数作为 destination   host. 可以有多个 destination host Source 和 destination 必须是独立的,不能在同一个复制结构里面。 如果pt-table-sync 检测到目标host是一个同一个复制拓扑里面的slave,工具会报错。因为对数据所做的一些改变是直接写入到 目的 host的,(将修改数据直接写入一个slave ,如果在引用binlog 日志的话,可能会报错。) 或者如果 我们使用 –replicate 选项的话, pt-table-sync 会期望 DSN参数是 master,这样改工具就可以一次性的发现该master所有的slave,并让slave都重新和master进行同步。(--sync-to-master 只更新一个slave)

该工具的 第一个DSN参数 想对于其他的DSN 提供一些默认参数,比如DB 和table,我们可以手动全部写上,或者让工具自动发现。

比如:pt-table-sync --execute h=host1,u=msandbox,p=msandbox h=host2

Host 2 的 DSN参数 继承了 来自 host1 的 u 和 p 的属性。 使用 –explain-hosts 选项可以看到 pt-table-sync 是如何翻译 命令行上的参数的。

输出:

使用 –verbose 的情况,会显示出对每个操作表所做处理的详细信息:

# Syncing h=host1,D=test,t=test1
# DELETE REPLACE INSERT UPDATE ALGORITHM START    END      EXIT DATABASE.TABLE
#      0       0      3      0 Chunk     13:00:00 13:00:17 2    test.test1

Host1 上的 test db 中的test1 表被插入3条记录。并且使用的算法是 chunk, 时间从13:00:00开始持续了17秒。因为发现master和slave之间的不同,所以退出状态时2 。

复制 安全

一般情况下,最安全的方式是只在master端做出变更,利用mysql的复制机制来达到同步的目的。 前提是 在master端执行的是replace语句,而且表中必须有unique index . 否则的话,只是 原始的 insert 语句,可能有的slave 会出现重复信息。

如果表含有unique keys, 我们可以很轻松的 使用 –sync-to-master 或者 –replicate 选项,如果没有的话,我们只能在slave端进行操作。and pt-table-sync will detect that you’re trying to do so. It will complain and die unless you specify --no-check-slave (see --[no]check-slave).

如果在双主模式下的表中没有主键或者unique key,我们必须在目的主机进行操作。 所以呢,我们需要使用 –no-bin-log 选项。

在双主模式下,一般使用—sync –to-master 参数, You will also need to specify --no-check-slave to keep pt-table-sync from complaining that it is changing data on a slave.

 
pt-table-sync  的算法:

有一个多种算法来发现数据差异的框架,该工具自动选择最合适的算法,依据是表的索引,字段类型和算法的偏好设置。

chunk  算法:
找一个索引中第一个字段为整数型的索引( date time 类型也算),让后根据该索引中的值分解为多个 chunk ,每次通过 checksum  完整的 chunk 来并同步该 chunk 中的数据。如果某个 chunk  checksum  中的值在 source   destination 端不同,那么他会逐个的发现是哪些数据记录出现了问题。
如果有足够的基数就可以高效的为每个 chunk 设置合适的 size (行记录)。
在最初的对每个 chunk 进行  checksum 的时候校验值是相当的小,而且几乎不会浪费网络和内存的资源。在校验的时候,只有 primary key 和一个 checksum 在网络中传输,并不是整个 row ,如果发现某个 row source destination  不一致,这个时候才会取出整条记录。
如果某个字段是 char 类型的并且开始字母都相同,那么该算法就不会起作用,该工具就会退出并提示选择其他的算法。
 
Nibble 算法:

找到一个索引上升指数在固定大小的半字节 - chunk-size行,使用non-backtracking算法,它和chunk算法很类似,但是它不是跟觉表中索引的基数来确定chunk size的大小,而是使用LIMIT定义每个半字节的上限,和之前半字节的上限定义的下限。

它工作的步骤是:查询出一行记录,并且该记录可以定义下一个  nibble 的上限? 下一个  checksum  查询会校验整个 nibble 如果发现源端和目的端有差异,那么它会逐行比较。
 
GroupBy
该算法主要用于没有 primary key 或者  unique index 的情况。选择整个表,并对所有的字段进行排序,并使用 count(*)  计算出行数,比较所有列,如果他们是一样的,比较 COUNT * )列的值,以确定有多少行插入或删除的目标。
 
Stream
选择整个表格并放在一个大的数据流中,比较所有列。选择所有列的效率远低于其他算法,
 
双向同步:现在还处于试验阶段, 所以我们不做过多介绍,只谈谈该功能面临的困难:

1、不适用于 复制架构,只能同步到一台独立的server

2、只能使用chunk 算法,即表中必须有primary key 或者unique key
3、一次只能让两台机器之间同步数据
4、对于delete删除的数据,不能同步。!
 
选项:

至少使用以下选项: --print , --execute, 或者 –dry-run

--where 和 –replicate 是互相排斥的。

--algorithms :默认是 chunk .Nibble ,GroupBy ,Stream
              算法是用来比较表之间的不同,按顺序排列
--[no]bin-log 默认:yes 会控制会话级别变量: SQL_LOG_BIN=1/0

--buffer-in-mysql  该选项对于使用 GroupBy 和 Stream算法的时候,即 表没有primary key                     unique key 的时候特别有效。它开启MySQL SQL_BUFFER_RESULT 选项,

                  MySQL 会对查询的结果放到内存或者临时表里面。好处是:对于使用太多的    

                  Perl 程序使用太多的语言。但是由于MySQL的缓存的查询结果,也不会节省太多内存

--[no]buffer-to-client   默认 :yes 对于MySQLrow记录时 是一条一条对比。

                  该选项开启了MySQL mysql_use_result 选项,当该工具从MySQL获取到该数据的时候,MySQL将不在持有该数据。如果禁用该选项的话,MySQL会一次性发送所有的rows,所以呢,对于大表来说,你可能会禁用改选项

 
--charset 设置默认连接的字符集,

--[no]check-master 默认是 yes, 当使用 –sync-to-master  检测master是否是真正的master

--[no]check-slave 默认是yes:检测目标主机是否是一个slave 。如果直接在slave上操作时很危险的,会造成数据的不一致。
--[no]check-triggers 检测目标表 是否有触发器。
--chunk-column 根据指定的column来 对表 chunk

--chunk-index 根据指定的索引 对表进行chunk

--chunk-size 多少行记录,或者多大的size为一个chunk 。 参数为 K? M? G?数据的大小初一行的平均大小,可以得到行数
--columns  参数用逗号相隔,指定用来比较的columns
--config 读取配置文件,该选项必须设置为第一个参数。
--dry-run  分析、检测、的同步算法和具体实施过程
 
--engines  参数逗号相隔,只同步参数中含有的存储引擎

--execute 具体的去修改表数据。 结合-verbose 选项,我们可以看到执行过程。默认是在安静模式下进行的。

--float-precision FLOAT和DOUBLE数字到字符串的转换精度为。FLOAT和DOUBLE值被舍入到小数点后的指定位数的数字,在MySQL中使用ROUND()函数。这有助于避免由于不同的浮点表示相同的值在不同的MySQL版本和硬件的校验和不匹配。默认情况下是没有四舍五入; CONCAT()函数的值转换成字符串,和MySQL选择的字符串表示形式。如果你指定一个值,例如,1.008和1.009的值将被调整至1.01,并会进行校验和是相等的
--[no]foreign-key-checks  是否启用外键检查, 在MySQL内部是 set foreign_key_checks=1
--ignore-columns
--ignore-database
--ignore-tables
--ignore-engines
--lock :锁表, 0 none 1 per sync cycle(锁住每个chunk) 3 globallly 

          如果 使用—replicate 或者 –sync-to-master 参数时,slave端 是不会锁表的。

          锁表的时候使用的是 lock tables ,但是如果使用 –transaction 的话,就是在事务开始到提交这一段,开始锁表。

--recursioin-method    processlist 是首选的方法来找到slave
--replace 对于 insert 和 update 语句来说全部替换为 replace
--replicate
--sync-to-master  DSN参数为slave
 
举例:
同步 把主机host1 DB1中的 tb1 同步到 host2上
Pt-table-sync –execute h=host1,D=db,t=tb1 h=host2
 
把host1上的表全部都不到 host2 host3    
Pt-table-sync --execute host1 host2 host3
 
让slave从master端保持一致
Pt-table-sync --execute --sync-to-master slave1
 

解决有pt-table-checksum 产生所有slave 对master的 differ结果

Pt-table-sync --execute --replicate test.checksum master1
 
或者只让slave1得到修复:
Pt-table-sync –execute  --replicate test.checksum --sync-to-master slave1
 
在双主模式下,同步master2 中的损害的 db.tb1 上的数据
Pt-table-sync --execute –sync-to-master h=master2,D=db,t=tb1
 
比如下面这个 就不会成立,因为它会直接修改master2上的数据,并且会传递给master1,

Pt-table-sync --execute h=master1,D=db,t=tb1 master2






本文转自 位鹏飞 51CTO博客,原文链接:http://blog.51cto.com/weipengfei/1073340,如需转载请自行联系原作者

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
目录
相关文章
|
Web App开发 小程序 Android开发
uniapp TC-scroll-view 横向和纵向滚动 带滚动回调
uniapp TC-scroll-view 横向和纵向滚动 带滚动回调
310 0
|
安全 关系型数据库 MySQL
windows提权总结
windows提权总结
495 1
|
5月前
|
人工智能 自然语言处理 JavaScript
【CodeBuddy】三分钟开发一个实用小功能之:字体阴影实时预览工具
CodeBuddy是一款革命性AI编程助手,通过自然语言描述快速生成可运行代码。本文以实时更新文字阴影效果的交互界面为例,展示其智能上下文理解、全链路生成等核心功能。应用场景涵盖原型开发、教学辅助及日常提效,未来还将支持多模态交互与个性化风格。附完整HTML/CSS/JS代码,助开发者专注创意实现。
146 2
【CodeBuddy】三分钟开发一个实用小功能之:字体阴影实时预览工具
|
开发工具 数据中心 git
详解IDEA git 版本回滚
详解IDEA git 版本回滚
673 0
|
11月前
|
人工智能 Cloud Native 数据管理
媒体声音|阿里云王远:一站式数据管理平台的智能化跃迁
在DTCC 2024大会上,阿里云数据库产品管理与技术架构部负责人王远与IT168 & ITPUB特约嘉宾薛晓刚就数据库与AI技术的融合、云原生数据库的新趋势及向量数据库的支撑能力等热点话题进行了深入探讨。王远认为,Data+AI不仅是一个概念,已进入实际落地阶段。在智能化时代,单一数据库引擎难以满足多元业务需求,需要构建统一的数据管理能力,以支持不同工作负载。阿里云通过“瑶池”数据库品牌,提供云原生、平台化、一体化和智能化的数据库解决方案,助力用户应对复杂的数据管理挑战。
457 11
|
SQL 监控 关系型数据库
面试题MySQL问题之主从复制的数据一致性问题如何解决
面试题MySQL问题之主从复制的数据一致性问题如何解决
159 1
|
存储 缓存 程序员
C++一分钟之-缓存行与伪共享问题
【7月更文挑战第11天】在计算机科学中,缓存是一个至关重要的概念,它能够显著提高数据访问速度。然而,缓存的使用并非没有问题,其中最著名的问题之一就是伪共享。
151 1
|
安全 关系型数据库 MySQL
Mysql 8.0 安装和使用遇到的各种问题(持续更新)
MySQL 8.0 安装到 服务器时,遇到的一些问题;安装、远程访问、密码编码格式不对、大小写区分、密码重置、修改密码 等操作
|
机器学习/深度学习 数据可视化 数据挖掘
职场新技能:Python数据分析,你掌握了吗?
职场新技能:Python数据分析,你掌握了吗?
248 0
|
缓存 Linux
CentOS7系统配置国内yum源和epel源
1.首先进入/etc/yum.repos.d/目录下,新建一个repo_bak目录,用于保存系统中原来的repo文件 [root@bogon ~]# cd /etc/yum.repos.d/ [root@bogon yum.
11475 57