103M +レコードのテーブルがあり、ディスクで70GBを消費します。レコードの70%を(1つのステートメントで)削除することにしました。
予想通り、実行に非常に長い時間がかかりました。そのDELETEコマンドは、完了する前に強制終了することにしました(SHOW PROCESSLISTで示されているように、約350K秒間実行されていました)。
コマンド(SHOW PROCESSLISTで示される)が「強制終了」に変更され、状態が「アイテムの解放」になりました。 450K秒の時間で、まだ実行されています。
私の質問はこれです、コマンドの実行を実際に停止するために何かできることはありますか?解放を止めるには? mysqld自体を再起動すると、その効果がありますか?
とにかく、解放プロセスがどこまで進んだかを判断する方法はありますか?
実際にマシンのリソースを大量に使用しており、残りのアプリケーションのパフォーマンスに影響を与えているためです。
show processlist;
| Command | Time | State | Info
| Killed | 449822 | freeing items | DELETE FROM *****
要求されたとおり、ここに問題のテーブルの作成と削除のステートメントがあります。
DELETE FROM adc_fetched_documents WHERE id <= 73097292
CREATE TABLE `adc_fetched_documents` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`adc_fetch_run_id` int(20) NOT NULL,
`adc_linked_from_id` int(20) DEFAULT NULL,
`adc_fetched_document_blob_id` int(20) DEFAULT NULL,
`adc_scraped_property_id` int(20) DEFAULT NULL,
`adc_duplicate_document_id` int(20) DEFAULT NULL,
`status` int(11) NOT NULL,
`document_type_id` int(4) NOT NULL,
`fetched_at` datetime NOT NULL,
`checksum` varchar(256) DEFAULT NULL,
`http_response_code` int(11) DEFAULT NULL,
`content_type` varchar(256) DEFAULT '',
`url` text,
`http_header` text,
`search_frag_id` int(11) DEFAULT NULL,
`adc_property_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`),
KEY `FK_ADC_DUPLICATE_OF` (`adc_duplicate_document_id`),
KEY `FK_ADC_FETCHED_DOCUMENT_BLOB` (`adc_fetched_document_blob_id`),
KEY `FK_ADC_FETCHED_DOCUMENT_SCRAPED` (`adc_scraped_property_id`),
KEY `FK_ADC_URL_FROM_RUN` (`adc_fetch_run_id`),
KEY `FK_SCR_URL_LINKED_FROM` (`adc_linked_from_id`),
KEY `index_adc_fetched_documents_on_adc_fetch_run_id` (`adc_fetch_run_id`),
KEY `index_adc_fetched_documents_on_adc_linked_from_id` (`adc_linked_from_id`),
KEY `index_adc_fetched_documents_on_adc_fetched_document_blob_id` (`adc_fetched_document_blob_id`),
KEY `index_adc_fetched_documents_on_adc_scraped_property_id` (`adc_scraped_property_id`),
KEY `index_adc_fetched_documents_on_adc_duplicate_document_id` (`adc_duplicate_document_id`),
KEY `index_adc_fetched_documents_on_document_type_id` (`document_type_id`),
KEY `index_adc_fetched_documents_on_checksum` (`checksum`),
KEY `index_adc_fetched_documents_on_search_frag_id` (`search_frag_id`),
KEY `index_adc_fetched_documents_on_adc_property_id` (`adc_property_id`),
CONSTRAINT `adc_fetched_documents_fetch_run` FOREIGN KEY (`adc_fetch_run_id`) REFERENCES `adc_fetch_runs` (`id`),
CONSTRAINT `adc_fetched_documents_parent` FOREIGN KEY (`adc_linked_from_id`) REFERENCES `adc_fetched_documents` (`id`) ON DELETE CASCADE,
CONSTRAINT `adc_fetched_documents_scraped_property` FOREIGN KEY (`adc_scraped_property_id`) REFERENCES `adc_scraped_properties` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=107925926 DEFAULT CHARSET=latin1
DELETEを実行するのに時間がかかりすぎているので、今のところあまり心配していません。微調整が必要なさまざまな変数があると思います。
助けてくれてありがとう。
まず、DELETEクエリとテーブルレイアウトを投稿していただきありがとうございます
質問に関しては、ロールバックがibdata1内のUNDOテーブルスペースを介して行われているため、実際にできることはありません(非常に大きくなっているはずです)。 mysqldプロセスを強制終了して再起動すると、クラッシュリカバリサイクルの一部として中断したところから再開されます。
将来、大規模および小規模の削除を処理する方法は次のとおりです。
テーブルの70%を削除して多くのロールバック情報を作成する代わりに、保持したいテーブルをコピーしてみてください。
CREATE TABLE adc_fetched_documents_new LIKE adc_fetched_documents;
INSERT INTO adc_fetched_documents_new
SELECT * FROM adc_fetched_documents
WHERE id > 73097292
;
ALTER TABLE adc_fetched_documents RENAME adc_fetched_documents_zap;
ALTER TABLE adc_fetched_documents_new RENAME adc_fetched_documents;
TRUNCATE TABLE adc_fetched_documents_zap;
テーブルの70%以上を削除する場合は常に、次のようにします。
小さなチャンクを削除する場合は、DELETE JOIN
:
CREATE TABLE deletion_ids (id INT NOT NULL PRIMARY KEY (id)) ENGINE=InnoDB;
INSERT INTO deletion_ids
SELECT id FROM adc_fetched_documents
WHERE id <= 73097292
;
DELETE B.* FROM deletion_ids A INNER JOIN adc_fetched_documents B USING (id);
試してみる !!!
正直なところ、実際には答えはありませんが、私の問題は解決されました。
基本的に約後。 5日間のロールバック「アイテムの解放」がついに終了しました。ロールバックのために実行された元のDELETEステートメントの長さの約1.5倍を要しましたが、これは長い時間ですが、前述の最悪のシナリオである30倍未満です こちら