web-dev-qa-db-ja.com

大規模なライブ(ほぼ同一)データベースで違いを見つける

レプリケートされたデータベース(SQLではなくトリプルストアですが、詳細はそれほど重要ではありません)を複数のホストで実行しています。それらのそれぞれは、特定の外部ソースからのフィードによって更新されるデータベースのコピーを保持しており、コピーは同一である必要があります。ただし、それらは完全に同一ではないことが判明しました。データベース間でレコード数に差異があります。各データベースには約20億のエントリがあり、その差は比較的小さく(約0.05%)、それはどういうわけか間違っている約100万のレコードがあることを意味します。おそらく更新プロセスのバグが原因ですが、正確に何が間違っているのかを見つけるのに苦労しています。ラグは小さく(秒)、1秒あたりに更新されるレコードの数(数十、ビジー状態の場合は数百)はサイズの違いよりもはるかに小さいため、変更はレプリケーションのラグによるものではありません。

どのレコードが一致しないかを知ることは非常に役立ちますが、毎秒変化する本番DBの20億レコードをどのように比較するかは正確にはわかりません。ダンプを作成し(少なくとも数時間かかる場合があります)、それを別のDBと比較すると(これも時間がかかります)、違いはDBがそれ以降変更されたためである可能性があります。

だから、私はそれらの異なるレコードを見つける方法についてのアイデアを探しています。私はそれらすべてを必要としません-インスタンスが1つでもあれば、すでに役に立ちます-しかし、1つでも効率的に見つける方法がわかりません。

4
StasM

それを行うには複数の方法があり、おそらくあなたが言及していないことを行うには実際的な制約があります。小さな情報を与えられて、これが私がそれをする方法です。

いくつかの仮定から始めましょう:

  • このデータベースは適度に使用頻度が高く、ある程度の負荷を追加することは許容されますが、システムに大きな負荷をかけることは許容されません。
  • 実際に要求された、一致しないレコードをすぐに見つけることができます。
  • レコードは通常のレコードです。つまり、追加の作業なしで両方のストアのレコードを比較できます。
  • 各レコードのシーケンス番号は、それを読むとわかります。たとえば、「これはレコード1,242,423,231または3,234,422,413です」。すべてではありませんが、多くのデータベースがこれをサポートします。
  • これは1回限りのことであり、重要です。

だから、ここに1つの解決策があります:

  • エントリは数十億しかないため、チェックされたすべてのレコードのビットセットをRAMのビットセットに収めることができます。 40億ビットは約0.5ギガバイトのRAMです。最初はゼロに設定されていますが、レコードが比較されたことがあれば、これらは1に設定されます。
  • レコードをフェッチするたびに、他のデータストアから同等のレコードをフェッチして比較し、すべてが正常であると仮定して、「この1つをチェック」ビットを1に設定します。時間の経過とともに、この方法でチェックする必要のある一般的なレコードは少なくなります。
  • 負荷が「低い」ときはいつでも、データベースからランダムまたはシーケンシャルのチェックされていないレコードのプルを開始します。あなたの店に未使用の週末がある場合、あなたはたくさんの記録をチェックするでしょう。

レコード番号のない別のソリューションは次のとおりです。

  • まず、ライブレコードを要求するたびに比較をトリガーします。これにより、データの整合性が維持されます。
  • 次に、包括的なインデックスでスロースキャンを開始します。

最後に、これが私の推奨される解決策です。

  • やめる。コーヒーを飲みに行きなさい。それがどのように起こったのかをよく考えてください。間違っている可能性のある仮定を書き留めます。レプリケーション中に変更されたレコードのログについて考えてみてください。あなたがそれを解決できるかどうか見てください。
  • これに必要な時間の裏側を実行します。数テラバイトであっても、ネットワークを介してディスクの内容全体を読み取るには、永遠に時間がかかる場合があります。アドホックネットワークを作成し、ラックごとに確認できますか?どれくらい悪い?
2
Charles Merriam

他のメタデータとして持っているのは、各データベースのレコード数だけだと思われますか?

それだけを使用して、おそらく、外部ソースからの更新の各ラウンドで、レコード数が(すでにあるよりも)発散しているかどうかを確認できます。もしそうなら、少なくともあなたは疑わしいレコード(更新)セットを持っており、それらのレコードが両方でそれを作ったかどうかを確認するために各データベースで綿密に調べる必要があります。必要に応じて、更新を遅くして、各更新セットからレコード数を取得し、不良な更新を絞り込む必要がある場合があります。

1
Erik Eidt

それらをメモリにロードすることはできません。100バイトの20億レコードが約200GBのRAMになります。

通常、このようなセットを比較する方法は、特定の並べ替えに基づいてページでセットを確認することです。たとえば、電話帳を持っている場合は、電話番号に基づいて並べ替えることができます(または姓はどの並べ替えを行うかは問題ではありません)。

Database 1         | Database 2
555- 1234 anderson | 555 - 1234 anderson
555  1235 smith    | 555 - 1235 johnson
555  1236 miller   | 555 - 1236 miller

次に、ページ(たとえば、1000レコードまたはある程度妥当なもの)をロードしてから、それらを直線的に調べます。ポインタを保持し、一方の電話番号をもう一方の電話番号と比較するだけです。

注:ydifferが差を出力し、ポインターを左右にインクリメントする場合は、挿入がある可能性があるため、ポインターのインデックスだけを確認しないでください。

注:レコードには一意のIDがないとおっしゃいました。彼らが同じレコードについていつ話しているかを判断する必要があります。たとえば、姓と生年月日は個人を特定するものと見なされ、正しく処理されていない住所の変更を探している場合があります。

0
Batavia