0

0

MySQL主从的一致性校验及修复

php中文网

php中文网

发布时间:2016-06-07 14:55:48

|

2116人浏览过

|

来源于php中文网

原创

主从的一致性校验 场景: 有人会问道:如何验证主从的一致性 又或者问:一个库里有几十张表 主从结构数据是否一致? 简单来讲可以在低峰期主从上分别使用select count(*)来看一下,这种方式是最古老的,准确度不是很高 盗贴 麻烦 说一声,本文来自 yijiu.blo

主从的一致性校验

场景:

有人会问道:如何验证主从的一致性

又或者问:一个库里有几十张表 主从结构数据是否一致?

简单来讲可以在低峰期主从上分别使用select count(*)来看一下,这种方式是最古老的,准确度不是很高

盗贴 麻烦 说一声,本文来自 yijiu.blog.51cto.com

 

主流方法:

使用pt-table-checksum验证主从的一致性

 盗贴 麻烦 说一声,本 文l来自 yijiu.blog.51cto.com

Pt-table-checksum的工作流程:

在某些数据不超过1千行则立刻显示出;如果超过1千行,会进行分段,至于如何分段其内部有特定机制

计算之后会在主库建一个表。默认表名为checksums

 

生成表后将session 会话级别的binlog格式改为语句级别格式,而后对每张表进行以下语句:

select .. count (*), bit_xor(crc32(#id#col1#col2...))from tb where id > xxx and id 

而后执行以下函数

#主要是将一个列拼成了一个用#号隔开的字符串

replace into checksums select .. count(*), bit_xor(crc32(#id#col1#col2...))from tb where id>xxx and id 

将语句全部写到checksums表中,这样如果主库执行了crc32函数的话,那么从库再执这些列进行crc32匹配,如果值不一样的话,则数据不一致

因为语句级的复制,只是将语句传递到不同的库去执行,这样的话不管有多少个从库都会将在主库将此语句跑完而后在从库上也执行此条语句并在从库执行

执行完后将语句全部写chechksums中,而后通过pt-table-checksum去读这个表,是否跟主库的crc32去对比,如果不一样则认为数据是不正确的,而且会分段列出,而后尝试修复

 

pt-table-checksum修复的过程

依旧将语句改为行格式,而后在主库执行replace into,其作用是主要修复主库上存在的语句,而从库没有的数据,或者主从都有主键,但是从库和主库的数据有冲突

另外一种是从库存在数据,而主库没有数据,则在主库执行delete操作,而后将语句记录在binlog中,再将binlog同步到relay log使从库上删掉

 

盗贴  a麻烦 说一d声,本 文l来自 yijiu.blog.51cto.com

安装pt-table-checksum

下载pt-table-checksum

wget http://www.percona.com/get/percona-toolkit.tar.gz

或者使用yum安装,需要指定epel

[root@mysql_node1 ~]# yum install percona-toolkit

 

pt-table-checksum的参数

--recursion-method  指定找出从库的方法

--recursion-method

METHOD       USES
========================================================
processlist       SHOW PROCESSLIST
hosts               SHOW SLAVE HOSTS
cluster       SHOW STATUS LIKE 'wsrep\_incoming\_addresses'
dsn=DSN       DSNs from a table
none           Do not find slaves

 

盗贴 a麻烦 说一d声,本 文l来自 yijiu .blo g.51cto.com

--recursion-method=processlist

执行结果显示参数意义:  

TS    :完成检查的时间。  

ERRORS :检查时候发生错误和警告的数量。  

DIFFS  :0表示一致,大于0表示不一致。当指定--no-replicate-check时,会一直为0,当指定--replicate-check-only会显示不同的信息。  

ROWS  :表的行数。  

CHUNKS  :被划分到表中的块的数目。  比如个表N条记录,那么会分成几十个chunks 每个N行的去检测

SKIPPED :由于错误或警告或过大,则跳过块的数目。  

TIME   :执行的时间。  

TABLE  :被检查的表名。 

 

pt-table-checksum --nocheck-replication-filters --no-check-binlog-format --replicate=testdb.checksums --create-replicate-table --databases=testdb  --tables=t5 -h 1.1.1.1 -P 3306 -u testdb -p testdatabase --recursion-method="processlist"

 

参数解释:

nocheck-replication-filters            #不检查加载项

no-check-binlog-format                  不检查binlog

replicate = testdb.checksums            #checksums表在哪个库中

create-replicate-table                  #上面的库或表如果不存在则自动创建

databases=testdb                        #表示检查哪个库,如果检查整个库里面表,那么后面的--tables=t5 参数可以去掉,但是生产环境中表很多或者很大,或者每天晚上就跑一张表则需要加下面参数

tables=t5                          

 

盗贴 a麻烦 说一w声,本 文l来自 yijiu .blo g.51cto.com

执行完后最后查看结果,如果是diffs出现大于0则表示不一致

检测当前数据库test110库是否错误,并查看结果

[root@mysql_node1 ~]# pt-table-checksum --nocheck-replication-filters --no-check-binlog-format --replicate=testdb.checksums --create-replicate-table --databases=test110  -h 10.12.33.61 -P 3306 -u root -p mypass --recursion-method="processlist"

Diffs cannot be detected because no slaves were found.  Please read the --recursion-method documentation for information.

            TS ERRORS  DIFFS     ROWS  CHUNKS SKIPPED    TIME TABLE

11-12T14:03:11      0      0     1000       1       0   0.016 test110.yw

 

尝试模拟出错并使用pt-table-checksum进行检测

在从库删除某条信息然后再次检测

在从库上操作:

首先忽略错误

光子AI
光子AI

AI电商服饰商拍平台

下载

盗贴 a麻烦 说一w声,本 文al来自 yijiu.blo g.51 cto.com

mysql> stop slave;

Query OK, 0 rows affected (0.00 sec)

 

mysql> set global sql_slave_skip_counter = 1;

Query OK, 0 rows affected (0.00 sec)

主库执行

mysql> call insert_yw(1);

Query OK, 1 row affected (0.01 sec)

开启从库

mysql>start slave;

检测一致性

再次在主库上执行tp-table-checksum

[root@node1 tools]# pt-table-checksum --nocheck-replication-filters --no-check-binlog-format --replicate=testdb.checksums --create-replicate-table --databases=test110  -h 10.12.33.58 -P 3306 -u root -p mypass --recursion-method="processlist"

            TS ERRORS  DIFFS     ROWS  CHUNKS SKIPPED    TIME   TABLE

11-12T16:40:55      0      1     1011       1       0   0.044   test110.yw

 

修复不一致

修复不一致可以直接调用pt-table-sync脚本

 

pt-table-sync工作流程

首先将sql打印出来,然后再去执行execute

比如,之前的库发现不一致,那么接下来使用pt-table-sync进行修复

如下所示

#pt-table-sync --replicate=testdb.checksums --databases=testdb --charset=utf8 h=10.12.33.58,u=testdb,p=testdbtestdb -print

参数解释:

#指定哪个库、字符集以及连接进来的DSN

#DSN: h=10.12.33.58,u=testdb,p=testdbtestdb

#-print 表示只打印出来修复的SQL,但是不执行

 

尝试修复

pt-table-sync --replicate=testdb.checksums --databases=testdb --charset=utf8 h=10.12.33.58,u=testdb,p=testdbtestdb --execute

#主库完后在从库修改数据,并执行checksum

 

盗贴麻烦 说一w声,本 文来自 yijiu.blo g.51 cto.com

[root@node1 tools]# pt-table-sync --replicate=testdb.checksums --databases=test110   h=10.12.33.58,u=root,p=mypass --execute

[root@node1 tools]# echo $?

0

[root@node1 tools]# pt-table-checksum --nocheck-replication-filters --no-check-binlog-format --replicate=testdb.checksums --create-replicate-table --databases=test110  -h 10.12.33.58 -P 3306 -u root -p mypass --recursion-method="processlist"

            TS ERRORS  DIFFS     ROWS  CHUNKS SKIPPED    TIME TABLE

11-12T16:49:12      0      0     1011       1       0   0.068 test110.yw

 

 

案例

比如一个很大的库,白天发生数据的不一致,尝试着手动修复,比如1062 1032等

但是1032的数据非常的多,这个时间从库一方面可以下线并重做

(1062,1032 可以使用slave_skip_errors=all 方式,然后用check-sum 进行修复)

 

另一种方法将从库不提供服务,并执行顺序:

slave_skip_errors = all           #将所有的错误都跳过,让从库继续工作

pt-table-checksum              #在业务低峰期的时候执行,对出现错误的表进行检查并尝试修复

pt-table-sync                #把不一致的数据补上来

#将slave_skip_errors = all关闭

check-sum                      #唯一的不足是将数据全部读完,会将buffer pool热数据冲掉

 

盗贴麻烦 说一w声,本 文来自 yijiu.blog.51 cto.com

模拟场景

从库执行

mysql>  call insert_yw(1);

主库操作

mysql> call insert_yw(1);

Query OK, 1 row affected (0.01 sec)

 

再次查看从库

mysql> show slave status\G

*************************** 1. row ***************************

               Slave_IO_State: Waiting for master to send event

                  Master_Host: 10.12.33.58

                  Master_User: repl

                  Master_Port: 3306

                Connect_Retry: 60

              Master_Log_File: mysql-bin.000002

          Read_Master_Log_Pos: 573305

               Relay_Log_File: node2-relay-bin.000003

                Relay_Log_Pos: 564426

        Relay_Master_Log_File: mysql-bin.000002

             Slave_IO_Running: Yes

            Slave_SQL_Running: No

              Replicate_Do_DB:

          Replicate_Ignore_DB:

           Replicate_Do_Table:

       Replicate_Ignore_Table:

      Replicate_Wild_Do_Table:

  Replicate_Wild_Ignore_Table:

                   Last_Errno: 1062

                   Last_Error: Could not execute Write_rows event on table test110.yw; Duplicate entry '1013' for key 'PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log mysql-bin.000002, end_log_pos 572982

                 Skip_Counter: 0

如果线程不工作的话 pt-table-checksum是无法检测的,所以要将线程启动

 

盗贴麻烦 说一a声,本 文来自 yijiu.blog.51 cto.com

将所有错误跳过

[root@node2 mysql]# grep errors /etc/my.cnf

slave_skip_errors = all

并重启服务

 

使用pt-table-checksum检测

[root@node1 tools]# pt-table-checksum --nocheck-replication-filters --no-check-binlog-format --replicate=testdb.checksums --create-replicate-table --databases=test110  -h node1.test.com -P 3306 -u root -p mypass --recursion-method="processlist"

            TS ERRORS  DIFFS     ROWS  CHUNKS SKIPPED    TIME TABLE

11-12T17:19:33      0      1     1015       1       0   0.033 test110.yw

进行修复

[root@node1 tools]#  pt-table-sync --replicate=testdb.checksums --databases=test110   h=10.12.33.58,u=root,p=mypass --execute

[root@node1 tools]# echo $?

0

 

在双方都确认行数

mysql> select count(*) from yw;

+----------+

| count(*) |

+----------+

|     1015 |

+----------+

1 row in set (0.00 sec)

 

 

面试中会问到tp-check-sum的不足

1.会将所有数据重新读一遍

2.读数据的同时会将buffer池中的热数据冲掉

3.在主库有大量的读,但是不会锁表是个非常不错的功能

 

如果是库非常小的话,或者几百G的数据,直接将重建主从即可

如果全库修复的话,量大的话则需要5、6个小时,具体需要机器配置

 

 盗贴麻烦 说一a声,本文来自 yijiu.blog.51 cto.com

pt-table-checksum的工作过程

在主库将general log 将主从都打开并运行pt-table-checksum进行观察

mysql> set global general_log=1;

Query OK, 0 rows affected (0.00 sec)

 

mysql> show global variables like '%gen%';

+------------------+------------------------+

| Variable_name    | Value                  |

+------------------+------------------------+

| general_log      | ON                     |

| general_log_file | /mydata/data/node2.log |

+------------------+------------------------+

2 rows in set (0.00 sec)

 

Pt-table-checksum的工作流程:

在某些数据不超过1千行则立刻显示出;如果超过1千行,会进行分段,至于如何分段其内部有特定机制

 

开启general log后在主库执行tp-table-checksum

[root@node1 ~]# pt-table-checksum --nocheck-replication-filters --no-check-binlog-format --replicate=testdb.checksums --create-replicate-table --databases=test110  -h node1.test.com -P 3306 -u root -p mypass --recursion-method="processlist"

            TS ERRORS  DIFFS     ROWS  CHUNKS SKIPPED    TIME TABLE

11-13T16:25:47      0      0     1015       1       0   0.048 test110.yw

 

主库:

[root@node1 ~]# cat /mydata/data/node1.log

141113 16:25:47   63 Connect   root@node1.test.com on

           63 Queryset autocommit=1

           63 QuerySELECT @@SQL_MODE

           63 QuerySHOW VARIABLES LIKE 'innodb\_lock_wait_timeout'

           63 QuerySET SESSION innodb_lock_wait_timeout=1

           63 QuerySHOW VARIABLES LIKE 'wait\_timeout'

           63 QuerySET SESSION wait_timeout=10000

           63 QuerySET @@SQL_QUOTE_SHOW_CREATE = 1/*!40101, @@SQL_MODE='NO_AUTO_VALUE_ON_ZERO,STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION'*/

           63 QuerySELECT @@server_id /*!50038 , @@hostname*/

           63 QuerySHOW VARIABLES LIKE 'version%'

           63 QuerySHOW ENGINES

           63 QuerySHOW VARIABLES LIKE 'innodb_version'

           63 QuerySELECT @@binlog_format

 

#生成表后将session 会话级别的binlog格式改为语句级别格式

           63 Query/*!50108 SET @@binlog_format := 'STATEMENT'*/           #更改日志格式为STAEMENT

           63 QuerySET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ

           63 QuerySHOW VARIABLES LIKE 'wsrep_on'

           63 QuerySELECT @@SERVER_ID

           63 QuerySHOW GRANTS FOR CURRENT_USER()

           63 QuerySHOW PROCESSLIST

           63 QuerySELECT @@server_id

           63 QuerySELECT @@server_id

           63 QuerySHOW DATABASES LIKE 'testdb'

           63 QueryCREATE DATABASE IF NOT EXISTS `testdb` /* pt-table-checksum */

           63 QueryUSE `testdb`

           63 QuerySHOW TABLES FROM `testdb` LIKE 'checksums'

#经过上面一系列检测、创建库、进入库,接下来创建checksums表

           63 QueryCREATE TABLE IF NOT EXISTS `testdb`.`checksums` (

     db             char(64)     NOT NULL,

     tbl            char(64)     NOT NULL,

     chunk          int          NOT NULL,

     chunk_time     float            NULL,

     chunk_index    varchar(200)     NULL,

     lower_boundary text             NULL,

     upper_boundary text             NULL,

     this_crc       char(40)     NOT NULL,

     this_cnt       int          NOT NULL,

     master_crc     char(40)         NULL,

     master_cnt     int              NULL,

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

23

2026.03.06

Rust内存安全机制与所有权模型深度实践
Rust内存安全机制与所有权模型深度实践

本专题围绕 Rust 语言核心特性展开,深入讲解所有权机制、借用规则、生命周期管理以及智能指针等关键概念。通过系统级开发案例,分析内存安全保障原理与零成本抽象优势,并结合并发场景讲解 Send 与 Sync 特性实现机制。帮助开发者真正理解 Rust 的设计哲学,掌握在高性能与安全性并重场景中的工程实践能力。

68

2026.03.05

PHP高性能API设计与Laravel服务架构实践
PHP高性能API设计与Laravel服务架构实践

本专题围绕 PHP 在现代 Web 后端开发中的高性能实践展开,重点讲解基于 Laravel 框架构建可扩展 API 服务的核心方法。内容涵盖路由与中间件机制、服务容器与依赖注入、接口版本管理、缓存策略设计以及队列异步处理方案。同时结合高并发场景,深入分析性能瓶颈定位与优化思路,帮助开发者构建稳定、高效、易维护的 PHP 后端服务体系。

162

2026.03.04

AI安装教程大全
AI安装教程大全

2026最全AI工具安装教程专题:包含各版本AI绘图、AI视频、智能办公软件的本地化部署手册。全篇零基础友好,附带最新模型下载地址、一键安装脚本及常见报错修复方案。每日更新,收藏这一篇就够了,让AI安装不再报错!

84

2026.03.04

Swift iOS架构设计与MVVM模式实战
Swift iOS架构设计与MVVM模式实战

本专题聚焦 Swift 在 iOS 应用架构设计中的实践,系统讲解 MVVM 模式的核心思想、数据绑定机制、模块拆分策略以及组件化开发方法。内容涵盖网络层封装、状态管理、依赖注入与性能优化技巧。通过完整项目案例,帮助开发者构建结构清晰、可维护性强的 iOS 应用架构体系。

113

2026.03.03

C++高性能网络编程与Reactor模型实践
C++高性能网络编程与Reactor模型实践

本专题围绕 C++ 在高性能网络服务开发中的应用展开,深入讲解 Socket 编程、多路复用机制、Reactor 模型设计原理以及线程池协作策略。内容涵盖 epoll 实现机制、内存管理优化、连接管理策略与高并发场景下的性能调优方法。通过构建高并发网络服务器实战案例,帮助开发者掌握 C++ 在底层系统与网络通信领域的核心技术。

29

2026.03.03

Golang 测试体系与代码质量保障:工程级可靠性建设
Golang 测试体系与代码质量保障:工程级可靠性建设

Go语言测试体系与代码质量保障聚焦于构建工程级可靠性系统。本专题深入解析Go的测试工具链(如go test)、单元测试、集成测试及端到端测试实践,结合代码覆盖率分析、静态代码扫描(如go vet)和动态分析工具,建立全链路质量监控机制。通过自动化测试框架、持续集成(CI)流水线配置及代码审查规范,实现测试用例管理、缺陷追踪与质量门禁控制,确保代码健壮性与可维护性,为高可靠性工程系统提供质量保障。

79

2026.02.28

Golang 工程化架构设计:可维护与可演进系统构建
Golang 工程化架构设计:可维护与可演进系统构建

Go语言工程化架构设计专注于构建高可维护性、可演进的企业级系统。本专题深入探讨Go项目的目录结构设计、模块划分、依赖管理等核心架构原则,涵盖微服务架构、领域驱动设计(DDD)在Go中的实践应用。通过实战案例解析接口抽象、错误处理、配置管理、日志监控等关键工程化技术,帮助开发者掌握构建稳定、可扩展Go应用的最佳实践方法。

62

2026.02.28

Golang 性能分析与运行时机制:构建高性能程序
Golang 性能分析与运行时机制:构建高性能程序

Go语言以其高效的并发模型和优异的性能表现广泛应用于高并发、高性能场景。其运行时机制包括 Goroutine 调度、内存管理、垃圾回收等方面,深入理解这些机制有助于编写更高效稳定的程序。本专题将系统讲解 Golang 的性能分析工具使用、常见性能瓶颈定位及优化策略,并结合实际案例剖析 Go 程序的运行时行为,帮助开发者掌握构建高性能应用的关键技能。

51

2026.02.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
MySQL 教程
MySQL 教程

共48课时 | 2.5万人学习

MySQL 初学入门(mosh老师)
MySQL 初学入门(mosh老师)

共3课时 | 0.3万人学习

简单聊聊mysql8与网络通信
简单聊聊mysql8与网络通信

共1课时 | 845人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号