大きなテーブルの構造を(それはInnoDB table btw)でコピーしました
CREATE TABLE tempTbl LIKE realTbl
次に、インデックスを変更し、テストを実行できるようにインデックスを埋めました。それを埋めることは使用して行われました:
INSERT INTO `tmpTbl`
SELECT *
FROM `realTbl`
これには時間がかかりすぎたため、このテストを中止したいと思いました。1
「データの送信中」の状態のプロセスを強制終了しました。現在は「強制終了」されており、まだ「データの送信中」の状態です。
いくつかの強制終了されたプロセスは変更を元に戻す必要があるため、実行時間と比較して強制終了までに時間がかかる可能性があることはわかっていますが、なぜこれが当てはまるのか想像できません:テーブル全体を空にする必要があります。
このような単純なクエリを非常に長く停止または中止するのに何が起こっているのか、私は興味があります。あなたにいくつかの数字を与えるために:挿入は1時間または3時間実行されました、キルはより近いです 5 今7。 DELETE
を実行するたびにINSERT
を実行しているように見えますが、削除は挿入よりも時間がかかりますか?それは論理的でしょうか?
(そして、誰かが私のテストサーバーを元に戻す方法を知っているなら、それもいくつかのリソースを消費しているので、それもいいことですが、現時点ではそれほど重要ではありません:))
1)理由はまだわかりません(これは大きなテーブル、1千万行ですが、それだけ時間がかかるはずですか?)。しかし、それは別の問題です/この質問の一部ではありません:)。それは私のテストがより賢くまたはより速くあったかもしれないかもしれませんが、それは今問題でもありません:D
キルに時間がかかる理由は、おそらくinnodbトランザクションによって発行されたロールバックが原因です。 InnoDBパフォーマンスのヒント から:
大量挿入の大きなロールバックに注意してください:InnoDBは挿入バッファーを使用して挿入のディスクI/Oを節約しますが、対応するロールバックではそのようなメカニズムは使用されません。ディスクにバインドされたロールバックは、対応する挿入の実行に30倍の時間がかかる場合があります。サーバーの起動時にロールバックが再開されるため、データベースプロセスを強制終了しても効果がありません。
編集:innodb force recovery メソッドが役立つかもしれません(テスト環境でこれを実行して良かった)
Mysqldプロセスを強制終了し、innodb_force_recoveryを3に設定して、ロールバックなしでデータベースを起動してから、暴走ロールバックを引き起こしているテーブルを削除します。
そして次回は、毎回データの小さなサブセットを挿入します。 1,000万行を挿入するのにそれほど長い時間はかかりませんが、複数の理由が考えられます。あなたの環境を知らなければ、私はそれについてアドバイスを提供することはできません。
これで面倒な操作がわかります。 tmpTblはInnoDBです。新しいデータをロードすると、いくつかの [〜#〜] mvcc [〜#〜] アクティビティが生成されます。これにより、変更がREDOログに積み重ねられます(ib_logfile0およびib_logfile1に格納され、おそらくibdata1にもいくつか含まれます)。
INSERTを強制終了すると、InnoDBテーブルに対するすべての変更(行ごとに、レコードがない代わりに新しいレコード)をロールバックする必要があります。
おそらく、mysqldを強制終了し、mysqldを再起動して、mysql起動のクラッシュリカバリフェーズでこれが発生する可能性があります。