1. はじめに
プロジェクトアドレス: https://github.com/seanlook/p...
pt-table-checksum ツールは、マスター/スレーブ環境でのデータの整合性検証によく使用されます。プロセス 以前に記事を書きました: pt-table-checksum を使用して本番環境で MySQL データの整合性をチェックします。ただし、DBA の作業では、2 つのテーブル間の整合性についていくつかのチェックが行われますが、2 つのテーブル間にマスターとスレーブの関係はありません。pt ツールは、binlog に基づいてマスター データベースで実行されたチェック アクションをスレーブで再生します。データベースは適用されなくなりました。
Alibaba Cloud RDS インスタンスから自社構築の mysql インスタンスへの移行などの特別なニーズが常に存在します。そのデータ送信サービスの実装方法はテーブルベースのバッチデータ抽出と binlog サブスクリプションですが、行モードを強制すると pt が発生します。 -table-checksum には、セッションを一時的にステートメントに変更する権限がありません。もう 1 つの要件は、ライブラリ全体の文字セットを変換することです。ライブラリ テーブル定義はすべて utf8 ですが、アプリケーション接続ではデフォルトの latin1 が使用され、接続文字セットとテーブル文字セットを統一するために、データは latin1 でのみエクスポートできます。 、次に UTF8 インポートを使用すると、この場合はデータの整合性チェックが行われます。言うまでもなく、binlog 解析プログラムがステートメント (canal など) をサポートしていないこと、古いライブラリと新しいライブラリの内容が異なること、および pt によって計算されたチェック値-table-checksum は異なり、無効になります。
だからこそ、pt-table-checksum を参照するというアイデアを思いつき、自分で px-table-checksum を書きました。
2. 実装方法
全体的なアイデアは、pt-table-checksum から学習し、ソース ライブラリから 1000 行などのデータをバッチ (つまり、チャンク) で取り出し、CRC32 値を計算し、同じものを実行することです。ステートメントをターゲットライブラリに追加し、結果を保存します。別のライブラリは、対応する数値のチャンク crc 値が一致しているかどうかを最終的にチェックします。不整合を把握するだけでは十分ではありません。そのため、ターゲット ライブラリとソース ライブラリに移動し、それらの不整合なチャンクが欠落しているかどうかに基づいて不整合な行を見つけます。 、または変更され、次に従って修復 SQL が生成されます。 自動的に修復するかどうかを示します。
それでは、問題は次のとおりです:
バッチを決定する方法、つまり次のチャンクを取得する方法? pt-table-checksum が行うことは、負荷に応じてチャンク サイズを動的に調整したり、アクティブなスレッドの数がしきい値を超えたときにチェックを一時停止したりすることは、負荷が高すぎるため、実行したくありませんでした。現在、毎回計算されるチャンク行数は固定されており、1000 や 2000 などに構成できます。
そのため、(自動インクリメントまたはユニオン) 主キーと一意のインデックスに従って、1000 の各制限の後、最後のキーが次のバッチの開始として昇順で取得されます。そのため、テーブル上のキーの状況を分析し、クエリ条件を組み合わせる必要があります。現在、主キーまたは一意キーを持つテーブルのみをチェックできます。
ソース ライブラリとターゲット ライブラリが同じ SQL を実行することを確認するにはどうすればよいですか?以前のバージョンでは、ターゲット ライブラリとソース ライブラリはチャンクを計算してライブラリに格納するために複数のスレッドを使用していました。後で、重大なバグに気づきました。たとえば、ターゲット ライブラリのデータが少ない場合に 1000 行もフェッチされた場合です。 、次のチャンクの開始が異なる場合、比較結果は単純に混乱します。
そこで、同じ番号のチャンクと開始点が同じでなければならないことを確認する必要があるため、ソースライブラリで実行されたすべての検証SQLをキューを使用して保存し、ptをシミュレートすることを考えましたツールを使用してターゲット ライブラリで再生します。複数のスレッドが複数のテーブルを同時に比較する必要があることを考慮すると、キューが大量のメモリを消費する可能性があるため、redis キューが使用されます。
crc32 をデータベース内で直接計算しますか、それともデータを取り出してメモリ内で計算しますか? pt-table-checksum のソースコードを確認したところ、データベース内で計算されていることがわかりました。ただし、最初のセクションで説明したように、ターゲット ライブラリとソース ライブラリで正しいデータを読み取るために異なる文字セットを使用する必要がある場合は、クエリを実行してから比較するしかありません。したがって、px-table-checksum は両方をサポートしており、1 つの構成項目を指定するだけで済みます。
複数のテーブルを同時にチェックすると、ソースデータベースのSQLがキューに混み合い、ターゲットデータベースが実行のために取り出されるまでに1秒が経過します。このとき、ソースデータベースのデータは再度変更され、ターゲット データベースに同期されるため、計算結果に一貫性がなくなり、実際には一貫性がありますが、それを処理することができません。これが、pt-table-checksum と比較した px-table-checksum の最大の欠点です。
しかし、そのような問題をできるだけ減らすために(たとえば、マスターとスレーブの遅延も発生する可能性があります)、複数のredisキューが特別に設計されており、ターゲットライブラリには複数のチェックスレッドがあります。たとえば、8つのテーブルが指定されている場合。同時にチェックする場合、8 つのソース ライブラリ チェックが対応しますが、テーブルの書き込み状況に応じて、4 つの Redis キュー (現在はランダムに追加されます) と 10 のターゲット ライブラリ チェック スレッドを構成して、不正確な要因を減らすことができます。しかし、私の観点からは、矛盾したデータが記録されている場合は手動でチェックされ、同じデータが 2 回矛盾している場合は、何かが間違っていると考えられます。 。
3. 制限事項
チェック中にソーステーブルのデータが頻繁に変更される場合、チェック結果が不正確になる可能性があり、これが上記のポイント 4 の問題です。明らかに、このプログラムによってチェックされる各トランザクションは、各チェック SQL のトランザクション順序を厳密に保証できる pt ツールとは異なり、別個のものです。ただし、データに矛盾がある場合は、もう一度確認すれば問題ありません。実際、オンラインで使用したところ、99.9% の精度でした。
テーブルに主キーまたは一意のインデックスが存在する必要があります。存在しない場合、プログラムはチェックして終了します。
Varbinay、blob、その他のバイナリフィールドは修復をサポートしていません
実際には、それはまったくサポートされておらず、使い方に依存します。開発中に文字が最初にバイトに変換されてから mysql に保存される場合、これは修復をサポートしません。対処方法としては、ソースライブラリからチェックする際に hex() 関数を使用し、SQL 内の unhex() を修復して書き戻す方法があります。
4. 使用説明
この Python プログラムは 2.7 に基づいて開発されており、2.6 および 3.x ではテストされていません。使用する前に MySQLdb と hotqueue をインストールする必要があります:
$ sudo pip install MySQL-python hotqueue
比較するテーブルとオプションは完全に設定されている必要があります。つまり、コマンド ラインで指定する必要はありません (追加の使用を許可します)。コマンドラインパラメータ)コード量が増加します)。
4.1 px-table-checksum.py
メインプログラムでは、python px-table-checksum.py を実行して整合性チェックを実行しますが、次の設定ファイルのオプションを必ず理解してください。
4.2 settings_checksum.py
設定オプション
CHUNK_SIZE: 毎回抽出されるチャンク行の数
REDIS_INFO: 使用する Redis キューのアドレスを指定します
REDIS_QUEUE_CNT: コンシューマー (ターゲット ライブラリ) が持つ Redis キューの数1 対 1 のスレッド キューの保護
REDIS_POOL_CNT: プロデューサー (ソース ライブラリ) Redis クライアント接続プール。この設計は、GIL によって引き起こされる問題を軽減し、キューイング側とデキュー側を分離するためのものです。これは、テーブルが多数ある場合、ホットキューの競合を避けるために大量の SQL が短時間にキューに入れられる可能性があるためです。 CALC_CRC32_DB: True は計算することを意味します。 db 内のチェックサム値、False はチャンクデータを取り出して Python で計算することを意味します。デフォルト値は接続文字セットに基づきます。
DO_COMPARE: 動作モード
0: 計算のためのデータのみを抽出し、一貫性のための比較は行いません。後で比較できるのはモード 2 のみです
1: 計算して比較します。一般的に使用されるのは、各計算の前にチェックされるテーブルの最後の結果が削除されることです。比較結果は、どのチャンク番号が矛盾しているかを示すだけです。
2: 計算は行わず、t_checkum の結果からの比較のみを行います。一般的に使用される計算ではデータベース リソースが消費され、既存のチェックサム計算結果の不一致のみを比較できます。 pt ツールの --replicate-check-only オプションと同様です。
GEN_DATAFIX:
DO_COMPARE と組み合わせて使用し、True に設定すると、矛盾したチャンクに対する特定の矛盾した行が検索され、False に設定された修復 SQL が生成されます。
RUN_DATAFIX:
DB_CHECKSUM: チェックサム結果の保存場所を指定する辞書。
4.3 settings_cs_tables.py
上記の設定ファイルは、検証するソースおよびターゲットのライブラリ情報と、どのテーブルを検証するかを指定するために使用されると考えられます。
TABLES_CHECK: 整合性をチェックするテーブルを指定するディクショナリ。データベース名がキーで、複数のテーブル名のリストが値です。データベース全体のチェックは現在サポートされておらず、同時に比較するテーブルの数が 8 を超えることは推奨されません
DB_SOURCE: ディクショナリ、ソース ライブラリの接続情報を指定します
DB_SOURCE: ディクショナリ、ソース ライブラリの接続情報を指定します対象のライブラリ