2

実稼働の mysql テーブルのバックアップを作成するための cron セットアップがあり、定期的にテーブルからデータを削除しようとしています。ID で参照される複数のテーブルのデータを削除する必要があります。

いくつかの背景: 約 200 万行を削除する必要があり、アプリはデータベースに対して継続的に読み取り/書き込みを行います (通常、削除される行にアクセスするべきではありません)。

私の質問は、次のパラメーターで削除クエリをどのように構成する必要があるかです。

  1. 単一の一括クエリで削除するか、バッチで削除しますか?
  2. トランザクションを使用せずに削除するのに対し、単一のトランザクションで異なるテーブル間で削除します。バッチで削除しても、トランザクションで削除を使用すると、テーブル レベルのロックは発生しますか?
  3. パーティションを設定していませんが、断片化は問題になりますか?
4

1 に答える 1

0

予測:

  1. 分離レベル: 反復可能読み取り -- デフォルトの Mysql 分離レベル。
  2. プライマリ インデックスではなく範囲に基づいているクエリを削除します。

  3. 1 つのトランザクションですべての行を削除すると、トランザクションが非常に長くなり、ロックが大きくなります。これにより、レプリケーション ラグが増加します。レプリケーション ラグはひどいものです。新しい DC は、それを本当に悪化させます。ロックを大きくすると、書き込みスループットも低下します。(Isolation Level Serializable の場合、読み取りスループットも低下する可能性があります。)

  4. 一括削除。すべてを削除するよりはましですが、範囲に対して削除が行われるため、各削除のロック数が多くなります (ギャップ ロックと次の行ロックが必要になります)。したがって、範囲内のバッチで削除すると、同じ問題がさらに小さくなります。

まとめて削除するよりも、一括で削除する方が望ましいです。

他の方法: (ある時間の前に行を削除する必要があります) 1.すべてのconfigured_timeを実行するデーモンを用意します。私。パージ時間 < パージ時間のテーブルから pk を選択します。-- ロックなし ii. 複数のスレッドを使用して、pk に基づいて削除します。-- 行レベルのロック、小さなトランザクション (テーブル全体)。

このアプローチにより、トランザクションが小さくなり、行レベルのロックのみが保証されます。(主キーに基づく削除は、行レベルのロックのみを取得します)。また、クエリは単純なので、削除の一部が成功した場合でも再実行できます。そして、これらのアトミックを持つことは必須ではないと感じています。

または

  1. 分離レベルを下げてください: READ_COMMITED でも、バッチ削除で問題ないはずです。Read COMMITED 分離では、セカンダリ キーを介してアクセスしている場合でも、ロックは行に対してのみ行われます。

または

  1. モデルが時間に基づいてシャードを許可し、データベース自体をドロップする場合:)
于 2015-04-18T10:28:37.620 に答える