主从的一致性校验

场景:

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

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

简单来讲可以在低峰期主从上分别使用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 <xxxx;

而后执行以下函数

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

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

将语句全部写到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进行检测

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

在从库上操作:

首先忽略错误

盗贴 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,

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

63 QuerySHOW GLOBAL STATUS LIKE 'Threads_running'

63 QuerySELECT CONCAT(@@hostname, @@port)       #检测主机名

63 QuerySELECT CRC32('test-string')

63 QuerySELECT CRC32('a')

63 QuerySELECT CRC32('a')

63 QuerySHOW VARIABLES LIKE 'wsrep_on'

63 QuerySHOW DATABASES

63 QuerySHOW /*!50002 FULL*/ TABLES FROM `test110`

63 Query/*!40101 SET @OLD_SQL_MODE := @@SQL_MODE, @@SQL_MODE := '', @OLD_QUOTE := @@SQL_QUOTE_SHOW_CREATE, @@SQL_QUOTE_SHOW_CREATE := 1 */

63 QueryUSE `test110`

63 QuerySHOW CREATE TABLE `test110`.`yw`

63 Query/*!40101 SET @@SQL_MODE := @OLD_SQL_MODE, @@SQL_QUOTE_SHOW_CREATE := @OLD_QUOTE */

63 QueryEXPLAIN SELECT * FROM `test110`.`yw` WHERE 1=1

63 QueryUSE `testdb`

63 QueryDELETE FROM `testdb`.`checksums` WHERE db = 'test110' AND tbl = 'yw'

63 QueryUSE `test110`

#而后对每张表进行以下语句

63 QueryEXPLAIN SELECT COUNT(*) AS cnt, COALESCE(LOWER(CONV(BIT_XOR(CAST(CRC32(CONCAT_WS('#', `id`, `c1`, `c2`, `c3`, `c4`, `c5` + 0, `c6`)) AS UNSIGNED)), 10, 16)), 0) AS crc FROM `test110`.`yw` /*explain checksum table*/

#后执行以下函数,主要是将一个列拼成了一个用#号隔开的字符串

63 QueryREPLACE INTO `testdb`.`checksums` (db, tbl, chunk, chunk_index, lower_boundary, upper_boundary, this_cnt, this_crc) SELECT 'test110', 'yw', '1', NULL, NULL, NULL, COUNT(*) AS cnt, COALESCE(LOWER(CONV(BIT_XOR(CAST(CRC32(CONCAT_WS('#', `id`, `c1`, `c2`, `c3`, `c4`, `c5` + 0, `c6`)) AS UNSIGNED)), 10, 16)), 0) AS crc FROM `test110`.`yw` /*checksum table*/

63 QuerySHOW WARNINGS

63 QuerySELECT this_crc, this_cnt FROM `testdb`.`checksums` WHERE db = 'test110' AND tbl = 'yw' AND chunk = '1'

63 QueryUPDATE `testdb`.`checksums` SET chunk_time = '0.008188', master_crc = 'dea4b11d', master_cnt = '1015' WHERE db = 'test110' AND tbl = 'yw' AND chunk = '1'

63 QuerySHOW GLOBAL STATUS LIKE 'Threads_running'

63 Quit

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

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

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

pt-table-checksum修复的过程

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

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

模拟错误

从库执行

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.00 sec)

mysql> select count(*) from yw;

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

| count(*) |

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

|     1016 |

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

1 row in set (0.00 sec)

主库执行

mysql> use test110;

Database changed

mysql> call insert_yw(2);

Query OK, 1 row affected (0.02 sec)

mysql> select count(*) from yw;

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

| count(*) |

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

|     1017 |

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

1 row in set (0.00 sec)

尝试在主库修复不一致

[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"

# 2 software updates are available:

#   * The current version for MySQL Community Server (GPL) is 5.6.21.

#   * The current version for MySQL Community Server (GPL) is 5.6.21.

TS ERRORS  DIFFS     ROWS  CHUNKS SKIPPED    TIME TABLE

11-13T17:03:57      0      1     1017       1       0   0.070 test110.yw

观察general log

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

141113 17:07:45   67 Connect   root@node1.test.com on

67 Queryset autocommit=0

67 QuerySELECT @@SQL_MODE

67 QuerySHOW VARIABLES LIKE 'wait\_timeout'

67 QuerySET SESSION wait_timeout=10000

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

67 Query/*!40101 SET @@SQL_MODE := CONCAT(@@SQL_MODE, ',NO_AUTO_VALUE_ON_ZERO')*/

67 QuerySHOW VARIABLES LIKE 'version%'

67 QuerySHOW ENGINES

67 QuerySHOW VARIABLES LIKE 'innodb_version'

67 QuerySELECT @@binlog_format

67 Query/*!50108 SET @@binlog_format := 'STATEMENT'*/           #依旧将语句改为行格式,而后在主库执行replace into

67 QuerySET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ

67 QuerySELECT CONCAT(@@hostname, @@port)

67 Quit

68 Connect   root@node1.test.com on

68 Queryset autocommit=0

68 QuerySELECT @@SQL_MODE

68 QuerySHOW VARIABLES LIKE 'wait\_timeout'

68 QuerySET SESSION wait_timeout=10000

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

68 Query/*!40101 SET @@SQL_MODE := CONCAT(@@SQL_MODE, ',NO_AUTO_VALUE_ON_ZERO')*/

68 QuerySHOW VARIABLES LIKE 'version%'

68 QuerySHOW ENGINES

68 QuerySHOW VARIABLES LIKE 'innodb_version'

68 QuerySELECT @@binlog_format

68 Query/*!50108 SET @@binlog_format := 'STATEMENT'*/

68 QuerySET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ

69 Connect   root@node1.test.com on

69 Queryset autocommit=0

69 QuerySELECT @@SQL_MODE

69 QuerySHOW VARIABLES LIKE 'wait\_timeout'

69 QuerySET SESSION wait_timeout=10000

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

69 Query/*!40101 SET @@SQL_MODE := CONCAT(@@SQL_MODE, ',NO_AUTO_VALUE_ON_ZERO')*/

69 QuerySHOW VARIABLES LIKE 'version%'

69 QuerySHOW ENGINES

69 QuerySHOW VARIABLES LIKE 'innodb_version'

69 QuerySELECT @@binlog_format

69 Query/*!50108 SET @@binlog_format := 'STATEMENT'*/

69 QuerySET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ

68 QuerySELECT @@SERVER_ID

68 QuerySELECT db, tbl, CONCAT(db, '.', tbl) AS `table`, chunk, chunk_index, lower_boundary, upper_boundary, COALESCE(this_cnt-master_cnt, 0) AS cnt_diff, COALESCE(this_crc <> master_crc OR ISNULL(master_crc) <> ISNULL(this_crc), 0) AS crc_diff, this_cnt, master_cnt, this_crc, master_crc FROM testdb.checksums WHERE master_cnt <> this_cnt OR master_crc <> this_crc OR ISNULL(master_crc) <> ISNULL(this_crc)

68 QuerySHOW GRANTS FOR CURRENT_USER()

68 QuerySHOW PROCESSLIST

68 Query/*!40101 SET @OLD_SQL_MODE := @@SQL_MODE, @@SQL_MODE := '', @OLD_QUOTE := @@SQL_QUOTE_SHOW_CREATE, @@SQL_QUOTE_SHOW_CREATE := 1 */

68 QueryUSE `test110`

68 QuerySHOW CREATE TABLE `test110`.`yw`

68 Query/*!40101 SET @@SQL_MODE := @OLD_SQL_MODE, @@SQL_QUOTE_SHOW_CREATE := @OLD_QUOTE */

68 QuerySELECT table_schema, table_name FROM information_schema.key_column_usage WHERE constraint_schema='test110' AND referenced_table_name='yw'

68 QuerySELECT MIN(`id`), MAX(`id`) FROM `test110`.`yw` FORCE INDEX (`PRIMARY`)

68 QueryEXPLAIN SELECT * FROM `test110`.`yw` FORCE INDEX (`PRIMARY`)

68 QuerySELECT CRC32('test-string')

68 QuerySELECT CRC32('a')

68 QuerySELECT CRC32('a')

68 QueryUSE `test110`

68 QuerySET @crc := '', @cnt := 0

68 Querycommit

68 QuerySTART TRANSACTION /*!40108 WITH CONSISTENT SNAPSHOT */

68 QuerySELECT /*test110.yw:1/3*/ 0 AS chunk_num, COUNT(*) AS cnt, COALESCE(LOWER(CONV(BIT_XOR(CAST(CRC32(CONCAT_WS('#', `id`, `c1`, `c2`, `c3`, `c4`, `c5` + 0, `c6`)) AS UNSIGNED)), 10, 16)), 0) AS crc FROM `test110`.`yw` FORCE INDEX (`PRIMARY`) WHERE (`id` = 0) FOR UPDATE

69 QuerySHOW MASTER STATUS

68 QuerySET @crc := '', @cnt := 0

68 Querycommit

68 QuerySTART TRANSACTION /*!40108 WITH CONSISTENT SNAPSHOT */

68 QuerySELECT /*test110.yw:2/3*/ 1 AS chunk_num, COUNT(*) AS cnt, COALESCE(LOWER(CONV(BIT_XOR(CAST(CRC32(CONCAT_WS('#', `id`, `c1`, `c2`, `c3`, `c4`, `c5` + 0, `c6`)) AS UNSIGNED)), 10, 16)), 0) AS crc FROM `test110`.`yw` FORCE INDEX (`PRIMARY`) WHERE (`id` > 0 AND `id` < '1001') FOR UPDATE

69 QuerySHOW MASTER STATUS

68 QuerySET @crc := '', @cnt := 0

68 Querycommit

68 QuerySTART TRANSACTION /*!40108 WITH CONSISTENT SNAPSHOT */

68 QuerySELECT /*test110.yw:3/3*/ 2 AS chunk_num, COUNT(*) AS cnt, COALESCE(LOWER(CONV(BIT_XOR(CAST(CRC32(CONCAT_WS('#', `id`, `c1`, `c2`, `c3`, `c4`, `c5` + 0, `c6`)) AS UNSIGNED)), 10, 16)), 0) AS crc FROM `test110`.`yw` FORCE INDEX (`PRIMARY`) WHERE (`id` >= '1001') FOR UPDATE

69 QuerySHOW MASTER STATUS

68 QuerySET @crc := '', @cnt := 0

68 QuerySELECT /*rows in chunk*/ `id`, `c1`, `c2`, `c3`, `c4`, `c5` + 0 AS `c5`, `c6`, CRC32(CONCAT_WS('#', `id`, `c1`, `c2`, `c3`, `c4`, `c5` + 0, `c6`)) AS __crc FROM `test110`.`yw` FORCE INDEX (`PRIMARY`) WHERE (`id` >= '1001') ORDER BY `id` FOR UPDATE

68 QuerySELECT `id`, `c1`, `c2`, `c3`, `c4`, `c5`, `c6` FROM `test110`.`yw` WHERE `id`='1016' LIMIT 1

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

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

68 QueryREPLACE INTO `test110`.`yw`(`id`, `c1`, `c2`, `c3`, `c4`, `c5`, `c6`) VALUES ('1016', '1', '1', '1', '1', '2014-11-13 17:02:24', 'testdbtestdbtestdb') /*percona-toolkit src_db:test110 src_tbl:yw src_dsn:h=10.12.33.58,p=...,u=root dst_db:test110 dst_tbl:yw dst_dsn:h=node2.test.com,p=...,u=root lock:1 transaction:1 changing_src:testdb.checksums replicate:testdb.checksums bidirectional:0 pid:15761 user:root host:node1.test.com*/

68 QuerySELECT `id`, `c1`, `c2`, `c3`, `c4`, `c5`, `c6` FROM `test110`.`yw` WHERE `id`='1017' LIMIT 1

68 QueryREPLACE INTO `test110`.`yw`(`id`, `c1`, `c2`, `c3`, `c4`, `c5`, `c6`) VALUES ('1017', '1', '0', '1', '0', '2014-11-13 17:02:24', 'testdbtestdbtestdbtestdbtestdbtestdbtestdbtestdbtestdbtestdbtestdbtestdbtestdbtestdbtestdb') /*percona-toolkit src_db:test110 src_tbl:yw src_dsn:h=10.12.33.58,p=...,u=root dst_db:test110 dst_tbl:yw dst_dsn:h=node2.test.com,p=...,u=root lock:1 transaction:1 changing_src:testdb.checksums replicate:testdb.checksums bidirectional:0 pid:15761 user:root host:node1.test.com*/

68 Querycommit

68 Querycommit

68 Quit

69 Querycommit

69 Quit

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

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

修复完毕后再次检测

[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-13T17:13:45      0      0     1017       1       0   0.075 test110.yw

MySQL主从的一致性校验及修复相关推荐

  1. MySQL主从一致的校验

    MySQL主从一致的校验 pt-table-checksum是查看主从一致性的工具, 网上很多人说 pt-table-checksum 要在主库上执行,其实不是的,我的mysql实例比较多,只需在某一 ...

  2. mysql主从分离一致性_数据库主从数据一致性的几种解决方案

    DB主从一致性的几种解决方法 起源 现在基本所有的程序中都会用到数据库,而数据库其实就是对所有业务逻辑处理结果的保存,所以不论在什么情况下数据的丢失都不被允许的,最坏的情况也要最小化数据的丢失程度,所 ...

  3. 利用percona-toolkit工具检查MySQL数据库主从复制数据的一致性,以及修复。

    利用percona-toolkit工具检查MySQL数据库主从复制数据的一致性,以及修复. 一.pt-table-checksum检查主从库数据的一致性 pt-table-checksum在MASTE ...

  4. mysql数据库主备表校验与修复

    用pt-table-checksum校验数据一致性 主从数据的一致性校验是个头疼的问题,偶尔被业务投诉主从数据不一致,或者几个从库之间的数据不一致,这会令人沮丧.通常我们仅有一种办法,热备主库,然后替 ...

  5. Maatkit工具使用lt;一gt;之mysql主从数据校验工具

    mysql主从数据校验工具       mysql在5.1之前,其replication都是采用的STATEMENT模式,对表的数据是否一致要求并不严格,所以对数据一致性要求比较严格的应用,定期检查数 ...

  6. 使用Innobackupex快速搭建(修复)MySQL主从架构

    2019独角兽企业重金招聘Python工程师标准>>> 使用Innobackupex快速搭建(修复)MySQL主从架构 MySQL的主从搭建大家有很多种方式,传统的mysqldump ...

  7. shell脚本修复MySQL主从同步

    shell脚本修复MySQL主从同步 发布:thebaby   来源:net     [大 中 小] 分享一例shell脚本,用于修改mysql的主从同步问题,有需要的朋友参考下吧. 一个可以修改my ...

  8. percona mysql 主从_mysql之percona-toolkit安装与主从复制

    percona-toolkit是一组高级命令行工具的集合,用来执行各种通过手工执行非常复杂和麻烦的mysql和系统任务,这些任务包括: 1).检查master和slave数据的一致性 2).有效地对记 ...

  9. MySQL主从不一致问题处理

    一.背景     某业务采取mysql的主从架构,但因为存储的问题,导致备库一直无法存储,数据同步一致性问题一直也未恢复,某次安全检查要求完成主备倒换演练,必须限期恢复主备,但是在恢复过程中,同步显示 ...

最新文章

  1. 深度学习深陷可解释性泥淖,而这个研究领域正逐步焕发生机
  2. MATLAB:图像半色调技术简介
  3. XML Web Service 安全性
  4. nginx php7 fastcgi,Windows下搭建PHP7+FastCGI+Nginx环境
  5. [转]计算机类核心期刊投稿的一些资料汇总
  6. 二值图像快速细化算法
  7. 直播平台接入美颜SDK已成刚需,它将带来哪些影响?
  8. 数据库|ALTER命令
  9. DVWA-SQL Injection级别通关详解
  10. MATLAB Support Package for USB Webcams 的使用方法(MATLAB调用摄像头后的使用方法)
  11. 【科创人】瑞云创始人汪忠田:售后服务SaaS市场拓荒者
  12. SecureCRT的下载安装
  13. QRCode 二维码:生于日本,辉煌于中国,原理及(python)实现
  14. C#实现微信聊天对话框
  15. sybase函数用法之DateAdd
  16. 面试官:你知道Callback Hell(回调地狱)吗?
  17. 华为交换机ip地址与MAC地址绑定(全局/接口模式)
  18. Java图片识别技术
  19. Docker部署mqtt服务器(emqx),密码认证
  20. 韩顺平老师Java基础听课笔记(一)

热门文章

  1. 8种方案解决重复提交问题
  2. 125万奖金!“中国GPT-3”赛事来了
  3. 10000字的Pandas核心操作知识大全!
  4. PyTorch 1.7发布,支持CUDA 11、Windows分布式训练
  5. 精度45.9%,推理速度72.9FPS,百度飞桨推出工业级目标检测模型 PP-YOLO
  6. 机器学习中的优化方法小结
  7. 识别迷雾中的物体,谷歌提出最新目标检测算法Context R-CNN
  8. 看看函数名和注释,AI就能自动生成代码,程序员:这不真实,我要失业
  9. 网易是世界最好的公司
  10. 任正非:要感谢特朗普,他一吓唬,治好了华为人的富裕病,都努力工作了