MySQL checksum了解
2440 ワード
プライマリ・スレーブ・レプリケーションでは、Checksumはしばしば、いくつかの重要なテーブルの一貫性チェックを必要とします.
Checksum Tableが論理バックアップの前後で可能かどうか
データ整合性の検証に使用します.拡張すると興味深い問題があります
例えば、データの挿入順序が異なり、テーブルエンジンが異なり、オペレーティングシステムのビット数が異なるなどです.
挿入順序の違いに影響があるかどうか
全テーブルスキャンには多くの順序があることを知っています.特にテーブルにdelete動作が現れた後、論理的にエクスポートして別のテーブルにインポートした後、
2つのテーブルの全テーブルスキャンの結果は異なる場合があります.
Checksum tableは戻り値を計算する論理は大体以下の通りである.
行の合計数と行の内容が同じであれば、読み出し行の順序に関係なく表示されます.
この論理からいくつかの結論が得られます.
1)
使用するエンジンに関係なく、つまりホストが同じエンジンを使用しなくてもchecksumはチェックに使用できます.InnoDBには隠し行がありますが、ここでは無視します.
2)
インデックスがあるかどうかは関係ありません.row_crcは行自体のデータだけで計算し、
インデックスデータは含まれません.
つまり
2つのテーブルの中のデータが同じで、テーブル構造(列の内容と順序が同じ)、オペレーティングシステムが同じで、MySQLバージョンが一致していることを保証できれば、checksumの結果を保証することができます.
フィールドの順序の違いに影響があるかどうか
rowでrowを計算するcrcの場合、
は、フィールドごとに順次計算されます.ただし、計算中に前のフィールドの結果が次の値を計算する入力として使用されます.
したがって
フィールドの順序は結果に影響します.
フィールドの長さに影響があるかどうか
同じ内容を見ても、異なるchecksumが得られる可能性があります.
各fieldを計算するcrcから見ると、変長フィールド(varcharなど)であれば、実際の長さを計算するために使用されるため、影響はありません.
たとえば、テーブルのvarchar(20)フィールドをvarchar(25)に変更しても、checksumの値は変更されません.
ただしchar(20)をchar(25)に変更したり、intをbigintに変更したりするとchecksumが変更される.
OSのビット数が異なる
戻り値がunsigned longであるため,32ビットと64ビットマシンのオーバーフロー問題が懸念される.幸い計算中のha_myisamはuint 32と直接定義され、戻るときにunsigned longに移行するだけで、
したがって影響はありません.
文字セットが異なる
この問題は実はずっとあいまいだ.実際には、入力文字セットに関連しています.しかし、テーブル内のフィールドのunhex()値が同じであれば、checksumは同じであるという結論があります.
次のコードでテーブルをチェックして一意の値を返します.
Checksum Tableが論理バックアップの前後で可能かどうか
データ整合性の検証に使用します.拡張すると興味深い問題があります
例えば、データの挿入順序が異なり、テーブルエンジンが異なり、オペレーティングシステムのビット数が異なるなどです.
挿入順序の違いに影響があるかどうか
全テーブルスキャンには多くの順序があることを知っています.特にテーブルにdelete動作が現れた後、論理的にエクスポートして別のテーブルにインポートした後、
2つのテーブルの全テーブルスキャンの結果は異なる場合があります.
Checksum tableは戻り値を計算する論理は大体以下の通りである.
ha_checksum crc= 0;
foreach(row in table)
{
row_crc= get_crc(row);
crc+= row_crc;
}
return crc;
行の合計数と行の内容が同じであれば、読み出し行の順序に関係なく表示されます.
この論理からいくつかの結論が得られます.
1)
使用するエンジンに関係なく、つまりホストが同じエンジンを使用しなくてもchecksumはチェックに使用できます.InnoDBには隠し行がありますが、ここでは無視します.
2)
インデックスがあるかどうかは関係ありません.row_crcは行自体のデータだけで計算し、
インデックスデータは含まれません.
つまり
2つのテーブルの中のデータが同じで、テーブル構造(列の内容と順序が同じ)、オペレーティングシステムが同じで、MySQLバージョンが一致していることを保証できれば、checksumの結果を保証することができます.
フィールドの順序の違いに影響があるかどうか
rowでrowを計算するcrcの場合、
は、フィールドごとに順次計算されます.ただし、計算中に前のフィールドの結果が次の値を計算する入力として使用されます.
switch (f->type()) {
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_VARCHAR:
case MYSQL_TYPE_GEOMETRY:
case MYSQL_TYPE_BIT:
{
String tmp;
f->val_str(&tmp);
row_crc= my_checksum(row_crc, (uchar*) tmp.ptr(),
tmp.length());
break;
}
default:
row_crc= my_checksum(row_crc, f->ptr, f->pack_length());
break;
}
したがって
フィールドの順序は結果に影響します.
フィールドの長さに影響があるかどうか
同じ内容を見ても、異なるchecksumが得られる可能性があります.
各fieldを計算するcrcから見ると、変長フィールド(varcharなど)であれば、実際の長さを計算するために使用されるため、影響はありません.
たとえば、テーブルのvarchar(20)フィールドをvarchar(25)に変更しても、checksumの値は変更されません.
ただしchar(20)をchar(25)に変更したり、intをbigintに変更したりするとchecksumが変更される.
OSのビット数が異なる
戻り値がunsigned longであるため,32ビットと64ビットマシンのオーバーフロー問題が懸念される.幸い計算中のha_myisamはuint 32と直接定義され、戻るときにunsigned longに移行するだけで、
したがって影響はありません.
文字セットが異なる
この問題は実はずっとあいまいだ.実際には、入力文字セットに関連しています.しかし、テーブル内のフィールドのunhex()値が同じであれば、checksumは同じであるという結論があります.
次のコードでテーブルをチェックして一意の値を返します.
mysql > checksum table test ;