マスタースレーブが同期されていることを確認するためにpt-table-checksumを使用しています。
Pt-table-checksumを実行すると、employee_profile.trigger_logにいくつかの違いが見られますが、-printを指定してpt-table-syncを使用すると、何も表示されません。
Pt-table-syncを使用して一部のテーブルのいくつかの違いを解決しましたが、pt-table-checksumを使用して再テストすると、このツールはまだ違いがあると表示します。
では、pt-table-checksumの問題は何ですか?精度ですか?
[更新]
私が使う
pt-table-checksum -h <masterip> -u <the_user> -p '<passwd of the user>' --recursion-method dsn=h=<slaveip>,P=3306,u=<the_userr>,p=<passwd of the user>,D=check_db,t=dsns --nocheck-binlog-format --set-vars innodb_lock_wait_timeout=50 > ~/stats_check_db_<slaveip>.txt
その後、コマンドを実行してフィルタリングします。
cat ~/stats_check_db_<slaveip>.txt | awk '{print "*"$3"*" " -- " $8}' | grep -Fv "*0*"
これは出力されます:
*DIFFS* -- TABLE
*1* -- mysql.user
*1* -- employee_profile.entry
*1* -- employee_profile.ip
*1* -- employee_profile.thread
Pt-table-syncを実行すると:
pt-table-sync --print h=<slaveip>,P=3306,u=<the user>,p=<passwd of the user> --sync-to-master --databases employee_profile --tables entry
何も見えません。しばらくして、pt-table-checksumで再確認すると、employee_profile.entryに違いが見られません。
解決されたテーブルについては、次の再チェックでまだいくつかの違いがあります。これらは、3番目のチェックサムのpt-table-checksumの結果から消えます。
[更新2]
私はperconaツールキットバージョン2.2.13を使用しています-最新バージョン http://www.percona.com/
チェックサムを行ったdbサーバーのすべての実装を確認しました。これらは、誰かが作成したmysqlまたはmariadbの古い実装です。
マスターがMariaDB5.5.34でスレーブがMariaDB5.5.37のように、マスターとスレーブ間の実装が異なる場合に問題が発生することがわかります(誤検知エラーが表示されます:MySQLがPRIMARYインデックスの代わりにインデックスを選択しなかったため、テーブルをニブルできません-それを無視してpt-table-syncを実行する)またはマスターがmysql 5.5.35で、スレーブがmysql 5.5.37(pt-table-checksumは違いがあると言っていますが、pt-table-sync --printは何もありません-確実に再テストしてください)。
それが誤検知の原因だと思います。
どうもありがとうございます !
古いバージョンのpt-table-checksumには誤検知がありました。古いバージョンを実行しないように注意してください。
違いを確認するには、次のscript()を使用することもできます。
#./compare_table.sh <db> <table> <master> <slave>
#!/bin/bash
# Usage:
# $0 database table master slave
set -eux
db=$1
tbl=$2
master=$3
slave=$4
tmpdir=`mktemp -d`
checksum_table="percona.checksums"
chunks=`mysql -h $slave -NBe "select chunk from $checksum_table where (this_crc<>master_crc or this_cnt<>master_cnt) AND db='$db' AND tbl='$tbl'"`
for c in $chunks
do
echo "# $db.$tbl, chunk $c"
chunk_index=`mysql -h $slave -NBe "SELECT chunk_index FROM $checksum_table WHERE db='$db' AND tbl='$tbl' AND chunk = '$c'"`
index_fields=`mysql -h $slave -NBe "SELECT COLUMN_NAME FROM information_schema.STATISTICS WHERE TABLE_SCHEMA='$db' AND TABLE_NAME='$tbl' AND INDEX_NAME='$chunk_index' ORDER BY SEQ_IN_INDEX"`
index_field_last=`mysql -h $slave -NBe "SELECT COLUMN_NAME FROM information_schema.STATISTICS WHERE TABLE_SCHEMA='$db' AND TABLE_NAME='$tbl' AND INDEX_NAME='$chunk_index' ORDER BY SEQ_IN_INDEX DESC LIMIT 1"`
# EXAMPLE:
#
#WHERE
# (
# (`user_id` > ?)
# OR
# (`user_id` = ? AND `activity_id` > ?)
# OR
# (`user_id` = ? AND `activity_id` = ? AND `activity_type_id` >= ?)
# )
#AND
# (
# (`user_id` < ?)
# OR
# (`user_id` < ?)
# OR
# (`user_id` = ? AND `activity_id` < ?)
# OR
# (`user_id` = ? AND `activity_id` = ? AND `activity_type_id` <= ?)
# )
if [ "$chunk_index" != "NULL" ]
then
where="WHERE"
v_num=1
lower_boundary=`mysql -h $slave -NBe "SELECT lower_boundary FROM $checksum_table WHERE db='$db' AND tbl='$tbl' AND chunk = '$c'"`
upper_boundary=`mysql -h $slave -NBe "SELECT upper_boundary FROM $checksum_table WHERE db='$db' AND tbl='$tbl' AND chunk = '$c'"`
clause_fields=""
where="$where (0 "
for f in $index_fields
do
clause_fields="$f $clause_fields"
op=""
where="$where OR ( 1"
for cf in $clause_fields
do
if test -z "$op"
then
if [ $cf == $index_field_last ]
then
op=">="
else
op=">"
fi
else
op="="
fi
v=`echo $lower_boundary | awk -F, "{ print \\\$$v_num}"`
v_num=$(( $v_num + 1))
where="$where AND \`$cf\` $op '$v'"
done
where="$where )"
done
where="$where )"
v_num=1
clause_fields=""
where="$where AND ( 0"
for f in $index_fields
do
clause_fields="$f $clause_fields"
op=""
where="$where OR ( 1"
for cf in $clause_fields
do
if test -z "$op"
then
if [ $cf == $index_field_last ]
then
op="<="
else
op="<"
fi
else
op="="
fi
v=`echo $upper_boundary | awk -F, "{ print \\\$$v_num}"`
v_num=$(( $v_num + 1))
where="$where AND \`$cf\` $op '$v'"
done
where="$where )"
done
where="$where )"
else
where="WHERE 1 "
fi
echo $where
mysql -h $master -NBe "SELECT * FROM $db.$tbl $where" >> "$tmpdir/master"
mysql -h $slave -NBe "SELECT * FROM $db.$tbl $where" >> "$tmpdir/slave"
set +e
diff -u "$tmpdir/master" "$tmpdir/slave" | less -S
set -e
done
rm -r "$tmpdir"