わたしはレプリケーション(と、バイナリーログ)フィルターが嫌いです。
フィルターが評価されるルール が理解されないまま運用されてカレントデータベースがNULLのままUPDATEを実行したりする人がいたりするので嫌なんですが、ストレージとかスレーブの性能とかネットワークの帯域とかで使わなければならないことも多々あります。
そんな時によく使う、 pt-table-checksum のメモ。
こんなふうにマスターで流すと、
とまあこんな感じで、チェック対象のテーブルに入っている値をハッシュ計算してテーブルに入れ込んでくれます。
このREPLACE INTOやUPDATEはスレーブにも伝播され、スレーブ側で再実行(スレーブのテーブルに本当に入っている値をハッシュ計算してテーブルに入れ込む)されるので、スクリプトが流れ終わったあとにマスターとスレーブのこのテーブル(test.pt-tcs)の中身を比較してやれば、同じデータが入っているであろうことが判断できます。
pt-tcsを実行するサーバーからログインできるユーザーがいれば、pt-tcsの中でも直接比較してexit codeとかに反映してくれるようなことも書いてありますし、PMPを入れ込めば、この値に差分がないかどうかを定期的にNagiosから確認できたりもするようです。
http://www.percona.com/doc/percona-monitoring-plugins/1.1/nagios/pmp-check-pt-table-checksum.html
弱点は、RBRの環境下では使えないこと。マスターで計算されたハッシュ値がそのままスレーブに渡されてしまうので、意味を為さなくなってしまう。
が、PXC(Galera Cluster)でも使えるようなことが書いてあって、どうやって計算しているのだろう。SET SESSION binlog_format= STATEMENTを押し込むのかな?
PlanetMySQL Voting: Vote UP / Vote DOWN
フィルターが評価されるルール が理解されないまま運用されてカレントデータベースがNULLのままUPDATEを実行したりする人がいたりするので嫌なんですが、ストレージとかスレーブの性能とかネットワークの帯域とかで使わなければならないことも多々あります。
そんな時によく使う、 pt-table-checksum のメモ。
$ pt-table-checksum --socket /usr/mysql/5.6.17/data/mysql.sock --user root --password xxxx --tables d1.t1,d1.t2,d2.t1 --replicate test.pt-tcs --create-replicate-table
TS ERRORS DIFFS ROWS CHUNKS SKIPPED TIME TABLE
05-15T17:36:00 0 0 39028 4 0 0.289 d1.t1
05-15T17:36:01 0 0 173469 4 0 0.239 d1.t2
05-15T17:36:14 0 0 5105937 15 0 7.264 d2.t1
こんなふうにマスターで流すと、
# at 108042433
#140515 17:36:00 server id 33597 end_log_pos 108043217 CRC32 0x0ca8897e Query thread_id=420836 exec_time=0
error_code=0
use `test`/*!*/;
SET TIMESTAMP=1400142960/*!*/;
CREATE TABLE IF NOT EXISTS `test`.`pt-tcs` (
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
/*!*/;
..
# at 108043627
#140515 17:36:00 server id 33597 end_log_pos 108044746 CRC32 0x0a0d40d3 Query thread_id=420836 exec_time=0
error_code=0
SET TIMESTAMP=1400142960/*!*/;
REPLACE INTO `test`.`pt-tcs` (db, tbl, chunk, chunk_index, lower_boundary, upper_boundary, this_cnt, this_crc) SELECT 'd1', 't1', '1', 'PRIMARY', '1', '1000', COUNT(*) AS cnt, COALESCE(LOWER(CONV(BIT_XOR(CAST(CRC32(CONCAT_WS('#', `column1`, `column2`, ..,)) AS UNSIGNED)), 10, 16)), 0) AS crc FROM `d1`.`t1` FORCE INDEX(`PRIMARY`) WHERE ((`column1` >= '1')) AND ((`column1` <= '1000')) /*checksum chunk*/
/*!*/;
..
# at 108044864
#140515 17:36:00 server id 33597 end_log_pos 108045097 CRC32 0x4799fdd5 Query thread_id=420836 exec_time=0
error_code=0
SET TIMESTAMP=1400142960/*!*/;
UPDATE `test`.`pt-tcs` SET chunk_time = '0.011250', master_crc = '4173135a', master_cnt = '1000' WHERE db = 'd1' AND tbl = 't1' AND chunk = '1'
/*!*/;
..
とまあこんな感じで、チェック対象のテーブルに入っている値をハッシュ計算してテーブルに入れ込んでくれます。
このREPLACE INTOやUPDATEはスレーブにも伝播され、スレーブ側で再実行(スレーブのテーブルに本当に入っている値をハッシュ計算してテーブルに入れ込む)されるので、スクリプトが流れ終わったあとにマスターとスレーブのこのテーブル(test.pt-tcs)の中身を比較してやれば、同じデータが入っているであろうことが判断できます。
pt-tcsを実行するサーバーからログインできるユーザーがいれば、pt-tcsの中でも直接比較してexit codeとかに反映してくれるようなことも書いてありますし、PMPを入れ込めば、この値に差分がないかどうかを定期的にNagiosから確認できたりもするようです。
http://www.percona.com/doc/percona-monitoring-plugins/1.1/nagios/pmp-check-pt-table-checksum.html
弱点は、RBRの環境下では使えないこと。マスターで計算されたハッシュ値がそのままスレーブに渡されてしまうので、意味を為さなくなってしまう。
が、PXC(Galera Cluster)でも使えるようなことが書いてあって、どうやって計算しているのだろう。SET SESSION binlog_format= STATEMENTを押し込むのかな?
PlanetMySQL Voting: Vote UP / Vote DOWN