轉載:https://tyoung.me/2016/09/use_dsn_method_to_connect_and_check_replicas_when_using_pt-table-checksum/
問題
在使用pt-table-checksum配置主從校驗的時候,本地和生產環境都可以正常校驗,而在測試環境校驗的時候,卻輸出以下警告信息:
Cannot connect to h=192.168.0.18,p=...,u=pt_table_check
Diffs cannot be detected because no slaves were found. Please read the --recursion-method documentation for information.
pt-table-checksum無法連接從庫。
由於沒有發現從庫,數據校驗時無法實時檢測從庫與主庫的數據是否一致(DIFFS列始終為0),需要通過--recursion-method選項指定其他的方式來搜索、連接從庫(此處--recursion-method使用的是默認值processlist,hosts)。
原因
執行的詳細命令及輸出如下:
shell> ./bin/pt-table-checksum --socket=/var/lib/mysql/mysql.sock --user=pt_table_check --password='checksum123' --tables=road_to_dba.test1 --replicate=percona_schema.checksums --no-check-binlog-format --no-check-replication-filters
Cannot connect to h=192.168.0.18,p=...,u=pt_table_check
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
09-21T20:57:37 0 0 972 1 0 0.033 road_to_dba.test1
雖然在校驗時pt-table-checksum沒有連接到從庫,但校驗能夠在主庫正常運行,而且能夠通過復制傳遞到從庫。校驗完成后,在從庫也可以通過checksums表查詢到數據校驗不一致的表信息。
本着嚴(qiang)謹(po)的(zheng)態度,決定還是對於上述警告信息徹底解決掉。經過分析,具體原因如下:
默認情況下,pt-table-checksum使用的從庫連接參數,是從主庫的連接參數繼承而來的,包括用戶名(--user)、密碼(--password)、端口(--port)等。
在本次校驗中,沒有顯式指定從庫的用戶名(--slave-user),密碼(--slave-password),及端口。
所以,在沒有顯式指定從庫的連接參數的情況下,默認是,主庫和從庫的用戶名、密碼、端口是相同的;但是在我的測試環境中,主從環境的端口是不同的。所以導致pt-table-checksum雖然搜索到了從庫,但是無法連接從庫(Cannot connect to h=192.168.0.18,p=...,u=pt_table_check),緊接着報沒有發現從庫的錯誤。
由於pt-table-checksum沒有參數可以用來指定從庫的端口,所以使用dsn方式來指定從庫的連接信息(--recursion-method dsn=D=percona,t=dsns,h=host,P=3309,u=username,p=passwd)。
dsn是什么
首先介紹倆名詞:
dsn方法:dsn是參數--recursion-method的一個參數值。注意是dsn,不是dns…
DSN:DSN,即DATA SOURCE NAME,數據源名稱。DSN包含從庫的各個連接參數(user、password、port等),由逗號分隔的多個option=value字符串組成。
如:h=host,P=3309,u=username,p=passwd。
dsn方法是指將從庫的DSN信息存儲在表(DSN表)里,然后將該表和DSN信息賦值給dsn,作為--recursion-method的參數值。
格式如:--recursion-method dsn=D=percona,t=dsns,h=host,P=3309,u=username,p=passwd。
當指定pt-table-checksum的--recursion-method參數值為dsn時,它只會連接和檢測這些指定的從庫。當從庫的MySQL用戶名、密碼、端口與主庫不相同時,也可以通過dsn的方式來指定。
DSN的部分選項如下:
D
DSN表所在的數據庫名。
h
從庫的host。
p
小寫p,從庫的密碼。當密碼包括逗號(,)時,需要使用反斜杠轉義。
P
大寫P,從庫的端口。
S
連接使用的socket文件。
t
存儲DSN信息的DSN表名。
u
從庫的MySQL用戶名。
每一個選項和其值的形式為option=value,=的前后不能空格,如果選項值有空格,則必須使用引號引起來。
將DSN作為--recursion-method的參數值時,必須包含D和t選項;或者只包含t選項,同時DSN表指定數據庫前綴(如percona.dsns)。
DSN表結構如下:
CREATE TABLE dsns
(
id
int(11) NOT NULL AUTO_INCREMENT,
parent_id
int(11) DEFAULT NULL,
dsn
varchar(255) NOT NULL,
PRIMARY KEY (id
)
);
存儲在表中的DSNs以id值排序,但是這里可以忽略id和parent_id列,只需將從庫的DSN信息存儲在dsn列即可。存儲的DSN格式如前面在命令行上指定DSN一樣,如:h=host,P=3309,u=username,p=passwd。
DSN的詳細介紹可參考Percona官方文檔:https://www.percona.com/doc/percona-toolkit/2.2/dsn_data_source_name_specifications.html
解決問題
上面繞的有點暈。。。其實只需要知道如何使用dsn指定從庫連接信息即可。
下面通過指定--recursion-method為dsn的方式,解決測試環境在數據校驗時無法連接從庫的問題。
在主庫新建DSN表
CREATE TABLE percona_schema.dsns
(
id
int(11) NOT NULL AUTO_INCREMENT,
parent_id
int(11) DEFAULT NULL,
dsn
varchar(255) NOT NULL,
PRIMARY KEY (id
)
);
這里為了測試,和主庫的MySQL賬號區分開,新建了一個賬號pt_table_check2專用於連接從庫
主庫賬號是pt_table_check
GRANT SELECT, PROCESS, SUPER, REPLICATION SLAVE ON . TO pt_table_check2@'192.168.0.%' IDENTIFIED BY 'checksum123';
將從庫的DSN信息寫入DSN表
INSERT INTO percona_schema.dsns(dsn) VALUES ("h=192.168.0.18,P=3309,u=pt_table_check2,p=checksum123");
在主庫使用dsn方式,重新運行pt-table-checksum進行校驗
shell> ./bin/pt-table-checksum --socket=/var/lib/mysql/mysql.sock --user=pt_table_check --password='checksum123' --tables=road_to_dba.test1 --replicate=percona_schema.checksums --no-check-binlog-format --no-check-replication-filters --recursion-method dsn=t=percona_schema.dsns,h=192.168.0.18,P=3309,u=pt_table_check2,p=checksum123
TS ERRORS DIFFS ROWS CHUNKS SKIPPED TIME TABLE
09-21T21:22:30 0 1 972 1 0 0.273 road_to_dba.test1
從第4步可以看到,pt-table-checksum已經能夠檢測到從庫,並且檢測到主從數據不一致(DIFFS = 1)。
問題解決。
無法連接/檢測從庫的影響
雖然在使用pt-table-checksum時,如果無法連接/檢測到從庫,仍可以完成主從一致性校驗。但是,這樣可能會產生一些其他的問題,如下:
1、pt-table-checksum在執行校驗時,無法實時檢測主從的數據是否一致。即,輸出的DIFFS列始終為0。
2、無法檢測到從庫是否有使用復制過濾,可能會造成從庫復制卡住。
3、當某個表在主庫上作為一個分塊進行校驗時,無法檢測其在從庫的數據量,當該表在從庫的數據量很大時,會造成從庫負載過高。
4、無法檢測到從庫的復制延遲狀態,造成從庫復制延遲過大。