MySQLの大規模なデータベースから多くの行をすばやく削除する方法

ご存知のように、すべてのシステム管理者は2つのカテゴリに分類されます。 すでにバックアップを行っている人とまだ行っていない人。



同様に、DBAも2つのカテゴリに分類されます。InnoDBテーブルのタイプを持つ大規模なデータベースで既に削除手順を開始している人と、まだしていない人です。







もちろん、理論的には、InnoDBの機能により削除が長くなることは誰もが知っていますが、この知識は「バックアップ」に似ています。 多くの人々は、これらの単純な真実を理解し、熊手を踏むだけです。



理解のために、500Mレコードのあるテーブルで350Mレコードを削除するには2日以上かかる場合があります。 多くの人が踏んでいる2番目のレーキは、リクエストをネイルしようとする試みです。 覚えているように、InnoDBはトランザクションエンジンであるため、リクエストをネイルしようとすると、変更のロールバックが試行され、リクエストの実行よりも時間がかかる場合があります



痛く痛くないようにする方法は? 猫へようこそ!



1.すでに削除を開始していて、すでにどれだけの処理が行われ、どれだけが残っているかを概算する場合は、SHOW ENGINE INNODB STATUSを使用します。 長い結論を得る。 その中のコマンドを探し、取り消しログエントリを確認します。これは、すでに処理されたレコードの数になります。



---TRANSACTION 1 4141054098, ACTIVE 191816 sec, OS thread id 36004918272 updating or deleting, thread declared inside InnoDB 84 mysql tables in use 1, locked 1 686063 lock struct(s), heap size 88520688, undo log entries 229144332 MySQL thread id 56087872, query id 2202164550 1.1.1.2 database updating DELETE FROM table WHERE UNIX_TIMESTAMP(moment) < 1498712335 - 365 * 86400 AND UNIX_TIMESTAMP(moment) > 0
      
      





さらに、すでに行われた量に応じて、終了まで待機するか、要求を中断するかを決定します。



2.アンインストールの開始のみを計画している場合は、LIMITを使用します。

レコードの数は経験的に選択されています。たとえば、私がLIMIT 5000を使用したあまり強力ではないサーバー、より強力なLIMIT 50000で使用されます。小さい値から始めて、必要に応じて増やします。



決定の短所:



a)必要な回数、手でリクエストを開始する必要があります(まあ、またはリクエストで必要な行数のテキストファイルを作成し、そこから実行する)

b)後続の各リクエストは、前のリクエストよりも時間がかかります



3. percona-toolsキットのpt- archiverを使用します。



いくつかの理由から、この特定の方法をお勧めします。



a) 高速です。

b)いつでも中断できます。

c)その中で、操作の進行状況を観察できます。



例:



 pt-archiver --source h=127.0.0.1,D=build4,t=b_iblock_element \ --optimize s --purge --where 'TAGS LIKE "%%"' \ --limit 1000 --commit-each --progress 500 --charset "CP1251"
      
      





原則として、キーは非常に明白ですが、それらを通過します。

--source-接続について説明します。 ホスト、ベース、およびテーブル。 必要に応じて、ユーザー名とパスワードを追加できます(この例では〜/ .my.cnfのクレジットを使用しています)。

--optimize-ソーステーブル、またはデータの転送先のテーブルを最適化します。 この場合、データを転送せずに削除するため、元のテーブルを最適化します。 原則として、これは必要ありません。

--purge-元々、データを別のテーブル(またはファイル)に転送するために設計されたユーティリティ。 ただし、単に行を削除できます。

--where-行が削除のために選択される通常のSQL条件。

--limit 1000-一度に1000行を処理します(サーバーのパフォーマンスに応じて、さらに多くの行を作成できます)。

--commit-each---limitで指定された行数の後にコミットします。

--progress 500-500行ごとに進行状況を表示します(このオプションを個別に選択するのが理にかなっています)。

--charset-エンコード。 ASCIIエンコードのみを使用する場合、-no-check-charsetを指定する方が簡単です。 コンソールロケールが指定された文字セットと一致する必要があることは別に言及します。そうしないと、エラーは表示されませんが、行は処理されません。


この短いメモがお役に立てれば幸いです(または、少なくとも興味深い)。

追加、修正、または発言するものがある場合は、書いてください!



別の行として、 LJユーザーmerkwurdigに感謝します。このユーザーは、この問題の議論を提起し、同じレーキでどのように走ったかを思い出させました。LJユーザーsvetasmirnova 。小さな記事。



All Articles