行がトランザクションで追加される (更新も削除もされない) だけのテーブルがあります (これが重要である理由を説明します)。クローン。
どうすればいいですか?どのプログラミング言語でも (私は Perl を使用していますが、それは関係ありません。)
この問題を解決する方法について私が考えた方法をリストアップし、正しい方法を教えてください (あるはずです...)。
私の頭に浮かんだ最初の方法は、フェッチされた行の最大の auto_incrementing ID を (ファイルに) 保存することでしたWHERE id > $last_id
。しかし、それは行を見逃す可能性があります。新しい行がトランザクションに挿入されるため、id = 4 の行を保存するトランザクションよりも前に、id = 5 の行を保存するトランザクションがコミットされる可能性があります。行 4 が 1 秒後にコミットされると、フェッチされることはありません (4 は $last_id である 5 よりも大きいため)。
次に、過去 2 分間に日付フィールドを持つすべての行を cron ジョブで取得できると考えました。これらの行のうち、前回の cron ジョブの実行で再度取得された行を確認します (これを行うには、どこかに保存する必要があります)。どの行 ID が取得されたか)、比較し、新しいものだけを処理します。残念ながら、これは複雑であり、特定の挿入トランザクションが奇妙なデータベースの理由でコミットするのに 2 分半かかる場合に発生する問題も解決しません。取得する cron ジョブ。
次に、RabbitMQ などのメッセージ キュー (MQ) をインストールすることを考えました。トランザクションの挿入を行う同じプロセスが、RabbitMQ に新しい行を通知し、RabbitMQ が新しい行を処理する常時実行プロセスに通知します。そのため、直前に挿入された行のバッチを取得する代わりに、そのプロセスは新しい行が書き込まれるたびに 1 つずつ取得します。これは良さそうに思えますが、障害点が多すぎます。RabbitMQ が (再起動などで) 一瞬ダウンする可能性があり、その場合、受信プロセスが新しい行を受信することなく挿入トランザクションがコミットされます。したがって、新しい行は見逃されます。良くない。
もう1つの解決策を考えました.受信プロセス(30個あり、まったく同じデータに対してまったく同じジョブを実行しているため、同じ行が各受信プロセスで1回ずつ30回処理されます)は別のテーブルに書き込むことができます処理時に行 X を処理した後、時が来たら、OUTER JOIN クエリを使用して、「have_processed」テーブルに存在しないメイン テーブルのすべての行を要求できます。しかし、新しいエントリを見つけるために 2 つのテーブルの ID のリスト全体を比較する必要があるため (およびテーブルは巨大で、毎分大きくなっています)。受信プロセスが 1 つしかない場合は高速でした。その場合、「have_read」という名前のインデックス付きフィールドを追加できたはずです。
それを行う正しい方法は何ですか?何を指示してるんですか?質問は簡単ですが、(私にとって) 解決策を見つけるのは難しいようです。
ありがとうございました。