MySQL主從的一致性校驗及修復

主從的一致性校驗node

場景:mysql

有人會問道:如何驗證主從的一致性面試

又或者問:一個庫裏有幾十張表 主從結構數據是否一致?sql

簡單來說能夠在低峯期主從上分別使用select count(*)來看一下,這種方式是最古老的,準確度不是很高數據庫

盜貼 麻煩 說一聲,本文來自 yijiu.blog.51cto.comsession

 

主流方法:ide

使用pt-table-checksum驗證主從的一致性函數

 盜貼 麻煩 說一聲,本 文l來自 yijiu.blog.51cto.comui

Pt-table-checksum的工做流程:this

在某些數據不超過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的數據,直接將重建主從便可

若是全庫修復的話,量大的話則須要五、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

相關文章
相關標籤/搜索