web-dev-qa-db-ja.com

TRUNCATE TABLEステートメントがハングすることがある

なぜTRUNCATE TABLEステートメントが時々ハングしますか?このタイプの問題の理由は何ですか?

MySQLからMariaDBに移行しています。この問題はMySQLでは発生せず、MariaDBでのみ発生します。

ぶら下げステートメントは単純です:

TRUNCATE TABLE sampledb.datatable;

これを引き起こす原因は何ですか?どのように修正できますか?

もう1つの観察は、テーブルにデータがあり、1行または2行の場合、切り捨てクエリは正常に機能します。そうしないと、テーブルに大量のデータが含まれ、クエリがハングします。

7
Haseena

TRUNCATE TABLEの実行中にパフォーマンスの低下または停止が発生する理由は、このステートメントの既知の問題です。参照してください Bug#68184:Truncate tableが原因でinnodbストールが発生します。 以前のバージョンで開かれた他のバグ番号もあります。

以下を使用できます。

CREATE TABLE log_table_new LIKE log_table;
RENAME TABLE log_table TO log_table_old, log_table_new TO log_table;
DROP TABLE log_table_old;

AUTO_INCREMENT値を持つテーブルの場合は注意が必要です。新しいテーブルは、作業テーブルですぐに使用されるAUTO_INCREMENT値で作成されます。同じ値を使用したくない場合は、次のことができます。

ALTER TABLE log_table_new AUTO_INCREMENT=some high enough value;
13
Stoleg

TRUNCATE TABLE はDMLではなくDDLであることを覚えておく必要があります。

TRUNCATE TABLE の配管のどこに行き詰まっているのかを把握するのではなく、問題をあなたのこれを交換して自分の手

TRUNCATE TABLE sampledb.datatable;

これとともに

CREATE TABLE sampledb.datatablenew LIKE sampledb.datatable;
ALTER TABLE sampledb.datatable RENAME sampledb.datatablezap;
ALTER TABLE sampledb.datatablenew RENAME sampledb.datatable;
DROP TABLE sampledb.datatablezap;

これは問題をオフラインにするかもしれません(おそらくDROP TABLE)、しかしテーブルはすぐに利用可能になります。 DROP TABLEはMySQL 5.5.23で改善されました

私は過去の投稿で TRUNCATE TABLE について説明しました

試してみる !!!

6
RolandoMySQLDBA

詳細な情報がないと言うのは難しく、私は特にMySQL/MariaDBの専門家ではありませんが、クエリの実行に通常よりも予想以上に時間がかかる一般的な理由は次のとおりです。

  • そのテーブルのロック:クエリは、そのテーブルのロックを保持している他のトランザクションが完了するのを待つことができます。この場合、競合するロックが解放されるまで、CPUまたはI/Oリソースを使用せずにステートメントが一時停止します。
  • 他のテーブルのロック:そのテーブルを参照している他の場所に外部キーがある場合、切り捨て操作では、まだ参照されている行が削除されないようにする必要があります。つまり、それらの他のテーブルをロックすると、テーブルも一時停止する可能性があります。
  • 参照整合性チェックの違い:新しいDBでFKが定義されていて、古いテーブルでは定義されていないテーブルを参照している場合、切り捨て速度の違いを説明することもできます。切り詰められるテーブルや参照テーブルが非常に大きい場合、これはすぐにはほど遠いかもしれません(これが、観察された異なる動作の理由である場合、ステートメントがいくつかのIO =および/またはCPU負荷)。
1
David Spillett

Mariadbでは、truncate tableはドロップテーブルとして機能し、空のテーブルを暗黙的に再作成します。ただし、セッションがアクティブなテーブルロックを保持している場合、切り捨て操作は実行できません。

InnoDBテーブルの場合のみ、InnoDBは、テーブルを参照する_TRUNCATE TABLE_制約がある場合、行を1つずつ削除して_FOREIGN KEY_を処理します。 _FOREIGN KEY_制約がない場合、InnoDBは元のテーブルを削除し、同じ定義で空のテーブルを作成することで高速トランケーションを実行します。テーブルに少数のレコードがある場合、切り捨ては高速であり、多くのレコードがある場合、切り捨ては無限であると述べているので、InnoDBとFKがあると仮定できます。

また、テーブルを切り捨てる前に、IS_FREE_LOCK(str)関数を試して、テーブルがロックされているかどうかを確認してください。その場合、スレッドを取得する_IS_USED_LOCK_関数がロックを保持しています。

1
Ste

他のプロセスがこのテーブルを使用できるため、TRUNCATEがハングする可能性があるため、シェルでの実行を確認します。

mysqladmin proc

次に、それを使用しているクエリを強制終了します(変更123からプロセスのIDへ):

mysqladmin kill 123

また実行中:

mysql -e "SHOW ENGINE INNODB STATUS\G"

ハングの調査にも役立ちます。

関連: ロック待機タイムアウトの超過をデバッグする方法?

0
kenorb