一、安装 percona 包

1.安装仓库的包

https://www.percona.com/doc/percona-repo-config/yum-repo.html

sudo yum install http://www.percona.com/downloads/percona-release/redhat/0.1-4/percona-release-0.1-4.noarch.rpm
如果成功将看下如下信息
[root@node1 ~]# sudo yum install http://www.percona.com/downloads/percona-release/redhat/0.1-4/percona-release-0.1-4.noarch.rpm
Loaded plugins: fastestmirror
percona-release-0.1-4.noarch.rpm | 6.4 kB 00:00:00
Examining /var/tmp/yum-root-NKCxiN/percona-release-0.1-4.noarch.rpm: percona-release-0.1-4.noarch
Marking /var/tmp/yum-root-NKCxiN/percona-release-0.1-4.noarch.rpm to be installed
Resolving Dependencies
--> Running transaction check
---> Package percona-release.noarch 0:0.1-4 will be installed
--> Finished Dependency Resolution Dependencies Resolved =============================================================================================
Package Arch Version Repository Size
=============================================================================================
Installing:
percona-release noarch 0.1-4 /percona-release-0.1-4.noarch 5.8 k Transaction Summary
=============================================================================================
Install 1 Package Total size: 5.8 k
Installed size: 5.8 k
Is this ok [y/d/N]: y
Downloading packages:
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Installing : percona-release-0.1-4.noarch 1/1
Verifying : percona-release-0.1-4.noarch 1/1 Installed:
percona-release.noarch 0:0.1-4 Complete!
 

2.确保 Percona 的包是可用的

 
sudo yum list | grep percona-toolkit
如果执行成功会看到
percona-toolkit.noarch                     2.2.20-1               percona-release-noarch
percona-toolkit.x86_64 3.0.9-1.el7 percona-release-x86_64
percona-toolkit-debuginfo.x86_64 3.0.9-1.el7 percona-release-x86_64

3. 安装 Percona Toolkit 工具包

 
sudo yum install percona-toolkit
出现如下信息表示安装成功
Installed:
percona-toolkit.x86_64 0:3.0.9-1.el7 Dependency Installed:
perl-Compress-Raw-Bzip2.x86_64 0:2.061-3.el7 perl-Compress-Raw-Zlib.x86_64 1:2.061-4.el7
perl-DBD-MySQL.x86_64 0:4.023-5.el7 perl-DBI.x86_64 0:1.627-4.el7
perl-Data-Dumper.x86_64 0:2.145-3.el7 perl-Digest.noarch 0:1.17-245.el7
perl-Digest-MD5.x86_64 0:2.52-3.el7 perl-IO-Compress.noarch 0:2.061-2.el7
perl-IO-Socket-IP.noarch 0:0.21-4.el7 perl-IO-Socket-SSL.noarch 0:1.94-6.el7
perl-Net-Daemon.noarch 0:0.48-5.el7 perl-Net-LibIDN.x86_64 0:0.12-15.el7
perl-Net-SSLeay.x86_64 0:1.55-6.el7 perl-PlRPC.noarch 0:0.2020-14.el7 Complete!

安装了很多命令

pt-align                  pt-ioprofile              pt-slave-delay
pt-archiver               pt-kill                   pt-slave-find
pt-config-diff            pt-mext                   pt-slave-restart
pt-deadlock-logger        pt-mongodb-query-digest   pt-stalk
pt-diskstats              pt-mongodb-summary        pt-summary
pt-duplicate-key-checker  pt-mysql-summary          pt-table-checksum
pt-fifo-split             pt-online-schema-change   pt-table-sync
pt-find                   pt-pmp                    pt-table-usage
pt-fingerprint            pt-query-digest           pt-upgrade
pt-fk-error-logger        pt-secure-collect         pt-variable-advisor
pt-heartbeat              pt-show-grants            pt-visual-explain
pt-index-usage            pt-sift                   ptx
 
 
有的32个命令,可以分为7大类
 
 
工具类别
工具命令
工具作用
备注
开发类
pt-duplicate-key-checker
列出并删除重复的索引和外键
 
pt-online-schema-change
在线修改表结构
 
pt-query-advisor
分析查询语句,并给出建议,有bug
已废弃
pt-show-grants
规范化和打印权限
 
pt-upgrade
在多个服务器上执行查询,并比较不同
 
性能类
pt-index-usage
分析日志中索引使用情况,并出报告
 
pt-pmp
为查询结果跟踪,并汇总跟踪结果
 
pt-visual-explain
格式化执行计划
 
pt-table-usage
分析日志中查询并分析表使用情况
pt 2.2新增命令
配置类
pt-config-diff
比较配置文件和参数
 
pt-mysql-summary
对mysql配置和status进行汇总
 
pt-variable-advisor
分析参数,并提出建议
 
监控类
pt-deadlock-logger
提取和记录mysql死锁信息
 
pt-fk-error-logger
提取和记录外键信息
 
pt-mext
并行查看status样本信息
 
pt-query-digest
分析查询日志,并产生报告
常用命令
pt-trend
按照时间段读取slow日志信息
已废弃
复制类
pt-heartbeat
监控mysql复制延迟
 
pt-slave-delay
设定从落后主的时间
 
pt-slave-find
查找和打印所有mysql复制层级关系
 
pt-slave-restart
监控salve错误,并尝试重启salve
 
pt-table-checksum
校验主从复制一致性
 
pt-table-sync
高效同步表数据
 
系统类
pt-diskstats
查看系统磁盘状态
 
pt-fifo-split
模拟切割文件并输出
 
pt-summary
收集和显示系统概况
 
pt-stalk
出现问题时,收集诊断数据
 
pt-sift
浏览由pt-stalk创建的文件
pt 2.2新增命令
pt-ioprofile
查询进程IO并打印一个IO活动表
pt 2.2新增命令
实用类
pt-archiver
将表数据归档到另一个表或文件中
 
pt-find
查找表并执行命令
 
pt-kill
Kill掉符合条件的sql
常用命令
pt-align
对齐其他工具的输出
pt 2.2新增命令
pt-fingerprint
将查询转成密文
pt 2.2新增命令
 
这次我们主要用这两个命令  pt-table-checksum 和  pt-table-sync
 
  pt-table-checksum 是 Percona-Toolkit 的组件之一,用于检测MySQL主、从库的数据是否一致。其原理是在主库执行基于statement的sql语句来生成主库数据块的checksum,把相同的sql语句传递到从库执行,并在从库上计算相同数据块的checksum,最后,比较主从库上相同数据块的checksum值,由此判断主从数据是否一致。检测过程根据唯一索引将表按row切分为块(chunk),以为单位计算,可以避免锁表。检测时会自动判断复制延迟、 master的负载, 超过阀值后会自动将检测暂停,减小对线上服务的影响。
  pt-table-checksum 默认情况下可以应对绝大部分场景,官方说,即使上千个库、上万亿的行,它依然可以很好的工作,这源自于设计很简单,一次检查一个表,不需要太多的内存和多余的操作;必要时,pt-table-checksum 会根据服务器负载动态改变 chunk 大小,减少从库的延迟。
  为了减少对数据库的干预,pt-table-checksum还会自动侦测并连接到从库,当然如果失败,可以指定--recursion-method选项来告诉从库在哪里。它的易用性还体现在,复制若有延迟,在从库 checksum 会暂停直到赶上主库的计算时间点(也通过选项--设定一个可容忍的延迟最大值,超过这个值也认为不一致)。
 
为了保证主数据库服务的安全,该工具实现了许多保护措施:
  1. 自动设置 innodb_lock_wait_timeout 为1s,避免引起
  2. 默认当数据库有25个以上的并发查询时,pt-table-checksum会暂停。可以设置 --max-load 选项来设置这个阀值
  3. 当用 Ctrl+C 停止任务后,工具会正常的完成当前 chunk 检测,下次使用 --resume 选项启动可以恢复继续下一个 chunk
 

工作过程

1\. 连接到主库:pt工具连接到主库,然后自动发现主库的所有从库。默认采用show full processlist来查找从库,但是这只有在主从实例端口相同的情况下才有效。
3\. 查找主库或者从库是否有复制过滤规则:这是为了安全而默认检查的选项。你可以关闭这个检查,但是这可能导致checksum的sql语句要么不会同步到从库,要么到了从库发现从库没有要被checksum的表,这都会导致从库同步卡库。
5\. 开始获取表,一个个的计算。
6\. 如果是表的第一个chunk,那么chunk-size一般为1000;如果不是表的第一个chunk,那么采用19步中分析出的结果。
7\. 检查表结构,进行数据类型转换等,生成checksum的sql语句。
8\. 根据表上的索引和数据的分布,选择最合适的split表的方法。
9\. 开始checksum表。
10\. 默认在chunk一个表之前,先删除上次这个表相关的计算结果。除非–resume。
14\. 根据explain的结果,判断chunk的size是否超过了你定义的chunk-size的上限。如果超过了,为了不影响线上性能,这个chunk将被忽略。
15\. 把要checksum的行加上for update锁,并计算。
17-18\. 把计算结果存储到master_crc master_count列中。
19\. 调整下一个chunk的大小。
20\. 等待从库追上主库。如果没有延迟备份的从库在运行,最好检查所有的从库,如果发现延迟最大的从库延迟超过max-lag秒,pt工具在这里将暂停。
21\. 如果发现主库的max-load超过某个阈值,pt工具在这里将暂停。
22\. 继续下一个chunk,直到这个table被chunk完毕。
23-24\. 等待从库执行完checksum,便于生成汇总的统计结果。每个表汇总并统计一次。
25-26\. 循环每个表,直到结束。
 
校验结束后,在每个从库上,执行如下的sql语句即可看到是否有主从不一致发生:
 
select * from percona.checksums where master_cnt <> this_cnt OR master_crc <> this_crc OR ISNULL(master_crc) <> ISNULL(this_crc) \G
 
检查使用的mysql用户一般是没有 create table 权限的,所以你可能需要先手动创建:
 
CREATE DATABASE IF NOT EXISTS percona;
CREATE TABLE IF NOT EXISTS percona.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,
ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (db,tbl,chunk),
INDEX ts_db_tbl(ts,db,tbl)
) ENGINE=InnoDB;

  

二、具体实验过程:

修复 Mysql 数据库不一致及 1032 错误

主库 node1 192.168.112.128 3306 root 123456
从库 node2 192.168.112.131 3306 root 123456
 
先做mysql的主从,过程略
 
数据库操作语句主要用到如下:
 
建库
create database school;
use school;
建表
CREATE TABLE `students` (
`SID` tinyint(4) NOT NULL AUTO_INCREMENT,
`Name` varchar(50) NOT NULL,
`Age` tinyint(4) NOT NULL,
`Gender` enum('M','F') NOT NULL,
`Mobile` char(11) NOT NULL,
`Address` varchar(255) DEFAULT NULL,
PRIMARY KEY (`SID`),
UNIQUE KEY `Name` (`Name`),
UNIQUE KEY `Name_2` (`Name`),
UNIQUE KEY `index_name` (`Name`),
KEY `Mobile` (`Mobile`)
) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=latin1;
 
插入数据
INSERT INTO students (Name, Age, Gender, Mobile, Address) VALUES ('w1',41,'F',1111111,'doagnagv');
INSERT INTO students (Name, Age, Gender, Mobile, Address) VALUES ('w2',42,'F',2222222,'dagongws');
INSERT INTO students (Name, Age, Gender, Mobile, Address) VALUES ('w3',43,'F',3333333,'doagdnga');
INSERT INTO students (Name, Age, Gender, Mobile, Address) VALUES ('w4',44,'F',4444444,'dvzxonga');
INSERT INTO students (Name, Age, Gender, Mobile, Address) VALUES ('w5',45,'F',5555555,'dozgngas');
INSERT INTO students (Name, Age, Gender, Mobile, Address) VALUES ('w6',46,'F',6666666,'dagongzg');
INSERT INTO students (Name, Age, Gender, Mobile, Address) VALUES ('w7',47,'F',7777777,'vsdgdong');
INSERT INTO students (Name, Age, Gender, Mobile, Address) VALUES ('w8',48,'F',8888888,'vsdgdong');
INSERT INTO students (Name, Age, Gender, Mobile, Address) VALUES ('w9',49,'F',9999999,'vsgagaga'); 
 
更新
UPDATE students SET age = 43 WHERE Name = 'w3';
删除
DELETE FROM students WHERE Name = 'w4';

开始实验可以看到主从是正常的状态

现在开始搞事情,将从库的一条数据删除:

 

可以看到主从数据已经不一样了,现在咱们来检测下主从的一致性。
 
[root@node1 ~]# pt-table-checksum h='192.168.112.128',u='root',p='123456',P=3306 -d school --recursion-method=processlist --nocheck-replication-filters --replicate=percona.checksums --no-check-binlog-format --ignore-databases=mysql  --engines=innodb
Checking if all tables can be checksummed ...
Starting checksum ...
TS ERRORS DIFFS ROWS CHUNKS SKIPPED TIME TABLE
-08T14:: 0.030 school.students
  • TS :完成检查的时间戳。
  • ERRORS :检查时候发生错误和警告的数量。
  • DIFFS :不一致的chunk数量。当指定 --no-replicate-check 即检查完但不立即输出结果时,会一直为0;当指定 --replicate-check-only 即不检查只从checksums表中计算crc32,且只显示不一致的信息(毕竟输出的大部分应该是一致的,容易造成干扰)。
  • ROWS :比对的表行数。
  • CHUNKS :被划分到表中的块的数目。
  • SKIPPED :由于错误或警告或过大,则跳过块的数目。
  • TIME :执行的时间。
  • TABLE :被检查的表名
 
但是并没有看到 DIFFS 这个值是 1,暂时先跳过这个未解决的问题
 
官网给的解释如下
" The number of chunks that differ from the master on one or more replicas. If --no-replicate-check is specified, this column will always have zeros. If --replicate-check-only is specified, then only tables with differences are printed."  
 
那我们用恢复的命令来预同步检查一下
[root@node1 ~]# pt-table-sync --print --sync-to-master h=192.168.112.131,u=root,p='',P= --verbose --wait= --transaction --engines=innodb -d school --tables=students --recursion-method=processlist --check-triggers --foreign-key-checks -unique-checks --charset=utf8mb4

从返回的结果来看已经发现了被我们删掉的语句,此时将 命令种的 --print 换成 --execute即可同步过去
 
执行完同步之后我们去查看看一致性是否恢复
 
已经恢复过来。
 
我们继续搞事情 将从库的 w4数据删除,然后update主库的这条数据看一下
 
先看主从状态是否正常
 

然后
从库执行==>   mysql> DELETE FROM students WHERE Name = 'w4';
主库执行==>   mysql> UPDATE students SET age = 54 WHERE Name = 'w4'; 将原来的 44 换成 54
 

可以看到主库的数据更改了,从库没有该条数据,
并且主从也断开了
 

【ERROR】1032:删除或更新数据,从库找不到记录

先解决主从问题 ,让它恢复正常
mysql> stop slave;
Query OK, 0 rows affected, 1 warning (0.00 sec) mysql> CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000017', MASTER_LOG_POS=62376;
Query OK, 0 rows affected (0.01 sec) mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
 
或者用
 
mysql> stop slave;
mysql> set global sql_slave_skip_counter=1;
mysql> start slave;

  

然后我们再次对主库的这条数据修改
主库执行==>   mysql> UPDATE students SET age = 64 WHERE Name = 'w4'; 将原来修改过的 54 换成 64
 

主从又出现了这个问题

 

去主库看下这个binlog文件到底发生了什么操作
记录下 end_log_pos ,根据pos值,找到那条数据,进行insert插入
 
mysql> show binlog events in 'mysql-bin.000017' from 62696  limit 10;
+------------------+-------+------------+-----------+-------------+-----------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+-------+------------+-----------+-------------+-----------------------+
| mysql-bin.000017 | 62696 | Xid | 1 | 62727 | COMMIT /* xid=3230 */ |
+------------------+-------+------------+-----------+-------------+-----------------------+
1 row in set (0.00 sec)
 
没看出来,还是直接用percona 的工具吧
 

这个问题是由于主从状态不是两个 YES 导致的,那我们先跳过对应的错误,恢复主从
 
如果update的行数过多可能会执行很多次 CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000017', MASTER_LOG_POS=62376; 这种操作,很影响效率,
在这直接用 set global sql_slave_skip_counter=1; 这个命令可以一次跳过很多
 
接着执行percona 的语句
[root@node1 lyj]# pt-table-checksum h='192.168.112.128',u='root',p='',P= -d schooursion-method=processlist --nocheck-replication-filters --replicate=percona.checksums --no-inlog-format --ignore-databases=mysql  --engines=innodb
Checking if all tables can be checksummed ...
Starting checksum ...
TS ERRORS DIFFS ROWS CHUNKS SKIPPED TIME TABLE
-08T15:: 0.021 school.students [root@node1 lyj]# pt-table-sync --execute --sync-to-master h=192.168.112.131,u=root,p='123456',P=3306 --verbose --wait=10 --transaction --engines=innodb -d school --tables=students --recursion-method=processlist --check-triggers --foreign-key-checks -unique-checks --charset=utf8mb4
# Syncing A=utf8mb4,P=,h=192.168.112.131,p=...,u=root
# DELETE REPLACE INSERT UPDATE ALGORITHM START END EXIT DATABASE.TABLE
# Chunk :: :: school.students
 
可以看到数据已经恢复过来了。
 

常见错误:
  1. Diffs cannot be detected because no slaves were found
            不能自动找到从库,确认processlist或host或dsns方式用对了。
         2. Waiting for the --replicate table to replicate to XXX
            问题出在 percona.checksums 表在从库不存在,根本原因是没有从主库同步过来,所以看一下从库是否延迟严重。
  1. Pausing because Threads_running=25
            反复打印出类似上面停止检查的信息。这是因为当前数据库正在运行的线程数大于默认25,pt-table-checksum 为了减少对库的压力暂停检查了。等数据库压力过了就好了,或者也可以直接 Ctrl+C 终端,下一次加上--resume继续执行,或者加大--max-load=值。
    
 
 
 
 
 
 
 
 
 
 
 
 

Mysql: pt-table-checksum 和 pt-table-sync 检查主从一致性,实验过程的更多相关文章

  1. mysql主从一致性校验工具-pt

    一.环境 1.系统环境 系统 IP 主机名 说明 server_id centos6.7 MasterIP master 数据库:主 177  centos6.7 SlaveIP slave 数据库: ...

  2. MySQL ERROR 1005: Can't create table (errno: 150)的错误解决办法

    在mysql 中建立引用约束的时候会出现MySQL ERROR 1005: Can't create table (errno: 150)的错误信息结果是不能建立 引用约束. 出现问题的大致情况 1. ...

  3. mysql 命令重命名表RENAME TABLE 句法

    mysql 命令重命名表RENAME TABLE 句法 RENAME TABLE tbl_name TO new_tbl_name[, tbl_name2 TO new_tbl_name2,...]更 ...

  4. mysql distinct field1,field2,field3, .... from table

    mysql distinct field1,field2,field3, .... from table 我们知道 这样的sql可以去掉重复项 (field1的重复项); select distinc ...

  5. mysqldump导出报错"mysqldump: Error 2013: Lost connection to MySQL server during query when dumping table `file_storage` at row: 29"

    今天mysql备份的crontab自动运行的时候,出现了报警,报警内容如下 mysqldump: Error 2013: Lost connection to MySQL server during ...

  6. NXP ARM Vector Table CheckSum

    Signature Creator for NXP Cortex-M Devices Algorithm for creating the checksum The reserved Cortex-M ...

  7. Mysql官方文档中争对安全添加列的处理方法。Mysql Add a Column to a table if not exists

    Add a Column to a table if not exists MySQL allows you to create a table if it does not exist, but d ...

  8. MySQL 优化 之 Copying to tmp table on disk

    项目中遇到了慢查询问题 Sql语句 SELECT sum(price) AS price, `member_id` FROM `crm_upload` GROUP BY member_id ORDER ...

  9. mysql You can't specify target table for update in FROM clause解决方法

    mysql You can't specify target table for update in FROM clause解决方法出现这个错误的原因是不能在同一个sql语句中,先select同一个表 ...

随机推荐

  1. Mvc内建功能(DefaultModelBinder)自动绑定。

    在做Asp.Net MVC项目中,都知道View负责页面展示数据或者提供页面收集数据,而所展示的数据或者收集的数据都是从Controller的Action中获取或提交到Controller的Actio ...

  2. 【转】带你正确的使用List的retainAll方法求交集

    一. retainAll 方法 public boolean retainAll(Collection<?> c) { //调用自己的私有方法 return batchRemove(c, ...

  3. Java-Excel写与读

    很多时候,一个软件应用程序需要生成Microsoft Excel文件格式的报告.有时,一个应用程序甚至希望将Excel文件作为输入数据.例如,一个公司开发的应用程序将财务部门需要所有输出生成自己的Ex ...

  4. laravel下的ORM数据映射之自由畅想

    此处以Model::get()方法和Model::first()方法为例 public static function get($data=[]){//默认是空数组 if(count($data)== ...

  5. mongodb客户端操作常用命令

    一启动mongodb数据库mongod --dbpath E:\mongo\data\db(这里些自己的mongodb数据库存放目录)二客户端操作1.显示数据库集合show dbs2.新建数据库use ...

  6. hp zbook15G2 nVidia K1100M显卡在ubuntu linux下闪屏问题

    我的hp zbook15G2有一块nVidia K1100M显卡. 故障现象 安装ubuntu 16.4之后,屏幕出现闪烁现象. 重启后,进入bios,屏幕依然在闪烁. 再重启,进入另一块硬盘的win ...

  7. 动态原型模式 js

    动态原型模式 function Person(name,age){ this.name = name; this.age = age; if(typeof this.sayName != " ...

  8. mysql索引和正确使用方式

    一.索引类型 B树索引:大部分都是,因此B树的特性限制了索引如何使用:必须看看索引的正确使用限制(含组合索引的限制)http://blog.csdn.net/lovemdx/article/detai ...

  9. php一个类引用另一个类的方法的写法

    default.php: <?php namespace SiteInfo{ class Site{ var $url; var $title; function setUrl($par){ $ ...

  10. Codeforces 760B Frodo and pillows

    题目链接:http://codeforces.com/problemset/problem/760/B 题意:n个床位,m个枕头,第k个位置最多有多少个枕头,其中相邻之间的差<=1; 第k个位置 ...