MySQL非プライマリ環境でのデータ整合性チェックサム修復プログラム

5356 ワード

1.概要
プロジェクトのアドレス:https://github.com/seanlook/p...
メインスレーブ環境でのデータ整合性チェックでは、pt-table-checksumツールがよく使用されます.その原理と実施過程の前に、生産環境ではpt-table-checksumを使用してMySQLデータ整合性をチェックする文章を書いたことがあります.しかし、DBAでは、2つのテーブルに対して一致しているかどうかをチェックするものもありますが、この2つのテーブルの間に主従関係はありません.ptツールはbinlogに基づいてメインライブラリで行うチェック動作で、ライブラリから一度再生すると適用されません.
アリクラウドRDSインスタンスから自己構築mysqlインスタンスに移行するなど、データ転送サービスの実装方法はテーブルベースの一括データ抽出にbinlogサブスクリプションを加えるが、rowモードを強制するとpt-table-checksumがセッションを一時的にstatementに変更する権限がないという特殊なニーズがある.もう1つの要件は、ライブラリ全体を文字セット変換することです.ライブラリテーブル定義はutf 8ですが、アプリケーション接続にはデフォルトのlatin 1が使用されています.接続文字セットとテーブル文字セットを統一するには、latin 1でデータをエクスポートしてutf 8でインポートするしかありません.この場合、データ整合性チェックはbinlog解析プログラムがstatement(canalなど)をサポートしていないことは言うまでもなく、新旧ライブラリ自体の内容は異なります.pt-table-checksumで算出したチェック値も異なり、失効します.
だからpt-table-checksumを参考に自分で書いた:px-table-checksum.
2.実現方法
全体的な考え方はpt-table-checksumを参考にして、ソースライブラリのロット(すなわちchunk)から1000行のようなデータを取り出し、CRC 32値を計算し、同じ文をターゲットライブラリで1回実行した結果、別のライブラリに格納し、最後に対応番号のchunk crc値が一致しているかどうかを確認することです.一致しないことを知っているのはまだだめで、迅速で便利な違いを修復しなければならないので、それらの一致しないchunkに基づいて、ターゲットライブラリとソースライブラリに行って一致しない行を見つけて、欠落しているのか、それとも余分なのか、それとも修正されているのか、それから修復sqlを生成して、指示によって自動的に修復するかどうかを示します.
問題は次のとおりです.
  • ロット、つまり次のchunkはどうやって取りますか?pt-table-checksumのように、負荷に応じてchunkサイズを動的に調整したり、アクティブスレッド数がバルブ値を超えたりして検査を一時停止したりするのは、作業量が大きすぎます.現在、計算されるchunkの行数は固定されており、1000や2000などを構成することができます.

  • したがって、ページングクエリを使用して、(自己増加または結合)プライマリ・キー、一意インデックスに基づいて、limit 1000のたびに最後のエントリを次のバッチの開始として昇順に取得します.したがって、テーブル上のキーの状況を分析するには、クエリー条件を組み合わせます.現在は、プライマリ・キーまたはユニークなテーブルのみがチェックできます.
  • ソースライブラリとターゲットライブラリを保証するには、sqlと同じように実行しますか?以前の版はターゲットライブラリとソースライブラリで、マルチスレッドでそれぞれchunkを計算して入庫したが、その後、深刻なバグに気づいた.例えば、同じ1000行を取っても、ターゲットライブラリにデータが少なければ、次のchunkは最初から違って、比較の結果はまるでぼろぼろだ.

  • したがって、同じ番号のchunkを保証し、起点を同じにしなければならないので、キューを使用して、ソースライブラリで走ったすべての検証sqlを保存し、ptツールをシミュレートしてターゲットライブラリで再生したいと思っています.マルチスレッドで複数のテーブルを同時に比較することを考慮すると、キューがメモリを食べすぎている可能性があるため、redisキューを使用します.
  • は直接データベースでcrc 32を計算しますか?それともデータを取り出してメモリで計算しますか?pt-table-checksumのソースコードをひっくり返し、データベースで計算されます.しかし、第1節では、ターゲットライブラリとソースライブラリが異なる文字セットを使用して正しいデータを読み出す場合は、クエリーしてから比較するしかないと述べています.したがってpx-table-checksumは両方ともサポートされており、構成項目を1つ指定するだけです.
  • 同時に複数のテーブルをチェックし、ソースライブラリsqlがキューに押し込まれ、ターゲットライブラリが実行時に1 sを超えた場合、ソースライブラリのデータが一度変更されてターゲットライブラリに同期され、計算結果が一致せず、実際に一致し、どのように処理できないかは、px-table-checksumがpt-table-checksumより最大の欠陥である.

  • ただし、主従の遅延など、このような問題を最小限に抑えるために、ターゲットライブラリの複数のチェックスレッド、すなわち8つのテーブルを同時にチェックするように指定すると、ソースライブラリのチェックには8つのスレッドが対応しますが、テーブルの書き込み状況に応じて4つのredisキュー(現在はランダムに入力されています)、10のターゲットライブラリのチェックスレッドを配置することができます.不正確な要素を減らすことができますしかし、私の立場に立つと、一致しないデータが記録され、多くなければ、人工的にチェックします.多い場合は、もう一度走って検査し、2回とも同じデータが一致しない場合は、状況があります.
    3.制限
  • 検査期間中にソーステーブルデータが頻繁に変化した場合、検査の結果が不正確である可能性があるのは上記の4点目の問題である.明らかに、このプログラムはチェックされたトランザクションごとに分離されており、ptツールがsqlをチェックするトランザクションの順序を厳格に保証するわけではありません.しかし、一致しないデータがあれば、もう一度調べてOKです.実際に私のオンラインで使用する過程で、99.9%は正確です.
  • テーブルにプライマリ・キーまたはユニーク・インデックス・プログラムがチェックされ、終了しない場合はチェックされます.
  • varbinay,blobなどのバイナリフィールドが修復をサポートしていないのは、実際には完全にサポートされていないわけではありません.どのように使うかによって異なります.開発では文字をバイトに変換してmysqlに格納すると修復はサポートされません.ソースライブラリから調べるときにhex()関数を使って、sqlの中のunhex()を修復して書く方法があります.

  • 4.使用説明
    このpythonプログラムは2.7に基づいて開発され、2.6、3.xにテストはありません.使用前にMySQLdbhotqueueを取り付ける必要があります.
    $ sudo pip install MySQL-python hotqueue

    比較するテーブルとオプションは、全構成化を使用します.すなわち、コマンドラインで指定しない(コマンドラインパラメータの使用を許可すると、コード量が追加されます).
    4.1 px-table-checksum.py
    メインプログラムは、python px-table-checksum.pyを実行してコンシステンシチェックを実行しますが、次のプロファイルオプションについては必ずご理解ください.
    4.2 settings_checksum.py
    構成オプション
  • CHUNK_SIZE:抽出ごとのchunk行数
  • REDIS_INFO:redisキューアドレス
  • の使用を指定する.
  • REDIS_QUEUE_CNT:redisキューの数、消費者(ターゲットライブラリ)は1つ1つの対応するスレッドがキュー
  • を守っている.
  • REDIS_POOL_CNT:生産者(ソースライブラリ)redisクライアント接続プール.この設計はGILがもたらす問題を緩和するために、入列端と出列端を分離する.なぜなら、テーブルが短時間で大量のsqlがキューに入る可能性が高い場合、hotqueue競合
  • を避けるためである.
  • CALC_CRC32_DB:Trueはdbでchecksum値を計算することを表し、Falseはchunkデータを取り出してpythonで計算することを表す.デフォルトの値は、接続文字セットに基づいて設定されます.
  • DO_COMPARE:運転モード
  • 0:データ計算のみ抽出し、一致するかどうかは比較しない.その後モード2で
  • のみ比較することができる.
  • :計算し、比較します.通常、計算するたびに前回のチェック対象テーブルの結果が削除され、比較結果はどのchunk番号が一致していないかだけを示します.
  • 2:計算せず、t_からのみcheckum結果比較.一般的に、計算はデータベースリソースを消費し、既存のchecksumの計算結果が比較的一致しない場所だけを使用できます.ptツールの--replicate-check-onlyオプションに似ています.

  • GEN_DATAFIX:DO_COMPAREと組み合わせて使用し、Trueに不一致のchunkに対して具体的な不一致行を見つけ、修復sqlを生成することを示す.Falseのためなら何もしない.
  • RUN_DATAFIX:GEN_DATAFIXと組み合わせて使用され、Trueに対して生成された修復sqlを表し、ターゲットライブラリで実行される.注意が必要です.いつ修復を設定したか、完了したらFalseに戻ってください.そうしないと、今度別のテーブルをチェックすると意外なことになりますので、わざわざこのオプションに確認のヒントを追加しました.
  • DB_CHECKSUM:checksumの結果がどこに保存されるかを指定する辞書の例です.db_nameを指定する必要があります.テーブルが自動的に作成されます.

  • 4.3 settings_cs_tables.py
    上記のプロファイルは、検証するソース・ライブラリとターゲット・ライブラリ情報、およびどのテーブルを検証するかを指定する制御プログラムに使用されると考えられます.
  • TABLES_CHECK:辞書は、db名がkey、複数のtable名の構成リストがvalueであるテーブルの一貫性をチェックするかを指定します.db全体のチェックはしばらくサポートされていませんが、比較するテーブルの数は8つの
  • を超えることは推奨されません.
  • DB_SOURCE:辞書、指定ソースライブラリの接続情報
  • DB_SOURCE:辞書、指定先ライブラリの接続情報
  • 原文リンク先:http://seanlook.com/2016/11/2...