pt-table-checksum 的使用(2個案列)


pt-table-checksum 的用法案例


原理&注意事項:

    1 使用的時候應選擇在業務低峯期運行,因爲運行的時候會造成表的部分記錄被鎖定。雖然操作是對trunk逐個進行的,但是它會對每個trunk做SELECT FOR UPDATE,這樣做主要是擔心做checksum的時候會有寫入,所以各個trunk都不適合太大。

    2 pt-table-checksum提供了多種手段以確保儘量不會對生產環境造成影響,你可以使用--max-load來指定最大負載,如果達到最大負載,就暫停運行。你也可以設置超時時間innodb_lock_wait_timeout。

    3 如果發現有不一致的數據,則可以使用pt-table-sync工具來進行修復。

    4 如果表中沒有主鍵或唯一索引,或者沒有合適的索引,或者處於其他不適合檢查的情況下,那麼工具可能會忽略這個表。

    5 pt-table-checksum 會忽略掉test庫下的表

    6 測試發現 pt-table-checksum 3.0.4 版本有bug, 不要用這個版本



參數說明:

    --host=主節點的IP地址

    --no-check-binlog-format        :因爲我們的日誌用的MIXED格式,所有這裏要加上不檢查複製的binlog模式

    --replicate-check-only          :只顯示不同步的信息,有時加該參數導致修復後明明數據已經一致了,但是使用pt-table-checksum 還會報不一致,因此不太建議加這個參數

    --replicate=percona.checksums   :把checksum的信息寫入到指定庫的指定表中,可以寫到test庫,或者建議直接寫到被檢查的數據庫當中。

    --databases=db1,db2             :指定需要被檢查的數據庫,多個則用逗號隔開。

    --tables=                           :指定需要被檢查的表,多個用逗號隔開[不寫就是檢查給出的庫裏涉及到的所有表]


    --replicate=percona.checksums  存放checksum表的庫名 表名

    --truncate-replicate-table 每次執行前 先清空下checksum表的內容

    --quiet 只列出校驗有問題的表



主庫:10.1.21.14  端口:3306

從庫:10.1.21.13  端口:3306


主庫:

    create database db1;

    CREATE TABLE `t1` (

      `id` int(11) NOT NULL AUTO_INCREMENT,

      `name` varchar(20) DEFAULT NULL,

      `createdate` datetime DEFAULT NULL,

      PRIMARY KEY (`id`)

    ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;


在主庫創建個checksum用的庫、賬號:

CREATE DATABASE IF NOT EXISTS percona;

use percona ;

CREATE TABLE IF NOT EXISTS 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;


GRANT ALL on percona.* to rdpops_checksum@'10.1.20.%' IDENTIFIED BY 'checksum_pass';

GRANT SELECT,LOCK TABLES,PROCESS,SUPER,REPLICATION SLAVE,REPLICATION CLIENT on *.* to rdpops_checksum@'10.1.20.%';



下面是我們的主庫數據:

    mysql> select * from t1;

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

    | id | name | createdate          |

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

    |  1 | aa   | 2017-02-12 11:00:00 |

    |  2 | bb   | 2017-02-12 11:00:00 |

    |  3 | cc   | 2017-02-12 11:00:00 |

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


從庫數據:

    mysql> select * from t1;

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

    | id | name | createdate          |

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

    |  1 | aa   | 2017-02-12 11:00:00 |

    |  2 | bb   | 2017-02-12 11:00:00 |

    |  3 | cc   | 2017-02-12 11:00:00 |

    |  4 | dd   | 2017-02-12 11:00:00 |

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



在主庫執行檢查操作:

pt-table-checksum \

h=10.1.21.13,u=rdpops_checksum,p='checksum_pass',P=3306 \

--databases=testdb --tables=students,scores \

--replicate=percona.checksums --truncate-replicate-table \

--nocheck-replication-filters \

--no-check-binlog-format --replicate-check-only --quiet


TS ERRORS  DIFFS     ROWS  DIFF_ROWS  CHUNKS SKIPPED    TIME TABLE

07-19T14:06:02      0      1       14        226       1       0   0.025 testdb.coc

07-19T14:06:02      0      1       15          0       1       0   0.020 testdb.scores

07-19T14:06:02      0      1       25          0       1       0   0.027 testdb.students




結果顯示:

TS            :完成檢查的時間。

ERRORS        :檢查時候發生錯誤和警告的數量。

DIFFS         :0表示一致,1表示不一致。當指定--no-replicate-check時,會一直爲0,當指定--replicate-check-only會只顯示不同的信息。

ROWS          :表的行數。

CHUNKS        :被劃分到表中的塊的數目。

SKIPPED       :由於錯誤或警告或過大,則跳過塊的數目。

TIME          :執行的時間。

TABLE         :被檢查的表名。





############################


對於一種複製情況下, 主庫是10.1.21.13:3306 從庫是10.1.21.14:3306 和 10.1.21.15:3307

這樣不同的端口,使用pt工具默認的--recursion-method=processlsit就無法識別出3307這個從庫。

這時候,只能採用dsn的方式配置從庫的連接,如下示例:


在某一箇中控機器(例如 10.1.20.110)執行:

    GRANT select on percona.* to rdpops_checksum@'10.1.20.%' IDENTIFIED BY 'checksum_pass';

    create database percona ;

    CREATE TABLE `percona`.`dsns` (

    `id` int(11) NOT NULL AUTO_INCREMENT,

    `parent_id` int(11) DEFAULT NULL,

    `dsn` varchar(255) NOT NULL,

    PRIMARY KEY (`id`)

    );

    

    -- 將2個從庫的信息插入到 percona.dsns裏面:

    insert into percona.dsns(dsn) values('h=10.1.21.15,P=3307,u=ops_checksum,p=checksum_pass');

    insert into percona.dsns(dsn) values('h=10.1.21.14,P=3306,u=ops_checksum,p=checksum_pass');



然後,在中控機器上執行如下命令:

## 之前已經創建好checksum檢測用的賬號

pt-table-checksum h=10.1.21.13,u=ops_checksum,p='checksum_pass',P=3306 \

--databases=testdb --replicate=percona.checksums --empty-replicate-table \

--nocheck-replication-filters --no-check-binlog-format --replicate-check-only \

--recursion-method dsn=h=10.1.20.110,u=ops_checksum,p='checksum_pass',P=3306,D=percona,t=dsns


結果如下,可以看到如下2個實例 都存在異常的地方:

Checking if all tables can be checksummed ...

Starting checksum ...

Differences on ops_db-21-15.uat

TABLE CHUNK CNT_DIFF CRC_DIFF CHUNK_INDEX LOWER_BOUNDARY UPPER_BOUNDARY

testdb.students 1 -3 1  

testdb.teachers 1 0 1  


Differences on ops_db-21-14.uat

TABLE CHUNK CNT_DIFF CRC_DIFF CHUNK_INDEX LOWER_BOUNDARY UPPER_BOUNDARY

testdb.coc 1 226 1  

testdb.scores 1 -2 1  

testdb.students 1 0 1  



說明:DSN的部分選項如下:

    D  DSN表所在的數據庫名。

    h  從庫的host。

    p  小寫p,從庫的密碼。當密碼包括逗號(,)時,需要使用反斜槓轉義。

    P  大寫P,從庫的端口。

    S  連接使用的socket文件。

    t  存儲DSN信息的DSN表名。

    u  從庫的MySQL用戶名。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章