フィルターが評価されるルール が理解されないまま運用されてカレントデータベースが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を押し込むのかな?
0 件のコメント :
コメントを投稿