Câu lệnh TRUNCATE TABLE đôi khi bị treo


7

Tại sao TRUNCATE TABLEđôi khi tuyên bố treo? Những lý do cho loại vấn đề này là gì?

Tôi đang chuyển từ MySQL sang MariaDB. Vấn đề này không xảy ra với MySQL, chỉ với MariaDB.

Tuyên bố treo chỉ đơn giản là:

TRUNCATE TABLE sampledb.datatable;

Điều gì có thể gây ra điều này xảy ra, và làm thế nào tôi có thể khắc phục nó?

Một quan sát khác là nếu bảng có một số dữ liệu, có thể là một hoặc hai hàng, thì truy vấn cắt ngắn hoạt động thành công. Khác bảng có nhiều dữ liệu, truy vấn trở thành treo.


1
Bạn có thể làm rõ những gì bạn di chuyển từ / đến? Có phải MyISAM cho InnoDB MySQL cho MariaDB không?
Mat

Xin lỗi, di chuyển từ MySQL sang MariaDB. Công cụ tìm kiếm được sử dụng trong cả hai là MyISAM
Haseena

Các quy trình khác có truy cập DB mục tiêu của bạn trong khi di chuyển đang chạy không?
dezso

Sau khi cắt ngắn truy vấn, chèn dữ liệu vào bảng. Trong MySQL, không có vấn đề gì.
Haseena

Câu trả lời:


13

Lý do tại sao bạn gặp phải sự suy giảm hiệu suất hoặc bị đình trệ trong khi thực hiện TRUNCATE TABLElà một vấn đề đã biết với tuyên bố này. Vui lòng tham khảo Bug # 68184: Bảng rút gọn gây ra các quầy hàng innodb. Có những số lỗi khác được mở cho các phiên bản trước.

Bạn có thể dùng:

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;

Sẽ khó khăn cho các bảng có AUTO_INCREMENTgiá trị: bảng mới được tạo với AUTO_INCREMENTgiá trị ngay lập tức được lấy trong bảng làm việc. Nếu bạn không muốn sử dụng cùng một giá trị, bạn có thể:

ALTER TABLE log_table_new AUTO_INCREMENT=some high enough value;

Trong câu trả lời của tôi, tôi đã nói tốt nhất là không đi qua hệ thống ống nước TRUNCATE TABLE. Có vẻ như bạn đã làm, và tìm thấy guốc. +1 !!!
RolandoMySQLDBA

1
Có vẻ như giải pháp này tương tự như postgres, trong đó các ràng buộc và chỉ mục khóa ngoài không được sao chép với likecâu lệnh. Hãy nhớ để tạo lại những người.
ps2goat

Tôi vừa thử điều này và DB bị treo ở bước RENAME ngay bây giờ. : / Đây sẽ là bằng chứng của tham nhũng? nó có thể được quản lý?
JPMC

6

Bạn phải nhớ rằng BẢNG TRUNCATE là DDL chứ không phải DML.

Thay vì tìm ra nơi trong hệ thống ống nước của TRUNCATE TABLE nó đang bị kẹt, bạn có thể phải đưa vấn đề vào tay mình bằng cách thay thế

TRUNCATE TABLE sampledb.datatable;

Với cái này

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;

Điều này có thể chỉ ngoại tuyến vấn đề (có thể treo trên DROP TABLE), nhưng bảng sẽ có sẵn một cách nhanh chóng. DROP TABLEđã được cải thiện trong MySQL 5.5.23 .

Tôi đã thảo luận về BẢNG TRUNCATE trong các bài viết trước đây của tôi

Hãy thử một lần !!!


1

Nếu không có thêm thông tin thì rất khó để nói và tôi không phải là chuyên gia về MySQL / MariaDB, nhưng những lý do chung cho một truy vấn bất ngờ mất nhiều thời gian hơn bình thường để chạy là:

  • Khóa trên bảng đó: truy vấn có thể được chờ đợi cho các giao dịch khác, giữ khóa trên bảng đó, để hoàn thành. Trong trường hợp này, câu lệnh sẽ tạm dừng, không sử dụng tài nguyên CPU hoặc I / O, cho đến khi các khóa cạnh tranh được giải phóng.
  • Khóa trên các bảng khác: nếu bạn có khóa ngoại ở nơi khác đề cập đến bảng đó, thao tác cắt ngắn sẽ cần đảm bảo rằng nó không bỏ các hàng vẫn được nhắc đến. Điều này có nghĩa là khóa trên các bảng khác cũng có thể khiến nó tạm dừng.
  • Sự khác biệt trong kiểm tra tính toàn vẹn tham chiếu: nếu DB mới của bạn có FK được xác định liên quan đến bảng đó mà bảng cũ không có, điều đó cũng có thể giải thích sự khác biệt về tốc độ cắt ngắn. Nếu bảng bị cắt ngắn và / hoặc các bảng giới thiệu rất lớn thì điều này có thể khác xa (nếu đây là lý do cho các hành vi được quan sát khác nhau của bạn, bạn sẽ thấy câu lệnh áp đặt một số tải IO và / hoặc CPU).

1

Trong bảng rút gọn mariadb hoạt động như một bảng thả và giải trí ngầm của bảng trống. Tuy nhiên, các thao tác cắt ngắn không thể được thực hiện nếu phiên giữ khóa bảng đang hoạt động.

Chỉ với bảng InnoDB, InnoDB xử lý TRUNCATE TABLEbằng cách xóa từng hàng một nếu có bất kỳ FOREIGN KEYràng buộc nào tham chiếu bảng. Nếu không có FOREIGN KEYràng buộc nào , InnoDB thực hiện cắt ngắn nhanh bằng cách bỏ bảng gốc và tạo một bảng trống có cùng định nghĩa. Như bạn nói rằng nếu một bảng có một vài bản ghi cắt thì nhanh và nếu bạn có nhiều bản ghi thì việc cắt là vô hạn, tôi có thể cho rằng bạn có InnoDB và FK.

Ngoài ra, trước khi cắt ngắn IS_FREE_LOCK(str)chức năng thử bảng của bạn để kiểm tra xem bảng có bị khóa hay không. Nếu vậy, có IS_USED_LOCKchức năng lấy lại chuỗi đang giữ khóa.


0

TRUNCATEthể bị treo, vì các quy trình khác có thể sử dụng bảng này, vì vậy để kiểm tra chạy trong shell:

mysqladmin proc

Sau đó, giết các truy vấn đang sử dụng nó (thay đổi 123thành Id của quá trình):

mysqladmin kill 123

Cũng đang chạy:

mysql -e "SHOW ENGINE INNODB STATUS\G"

cũng có thể giúp điều tra bất kỳ hangs.

Liên quan: Làm thế nào để gỡ lỗi Khóa chờ quá thời gian chờ?


-1

Tôi đã đối mặt với vấn đề tương tự, và nó đã được giải quyết bằng cách khởi động lại máy chủ mysql.

systemctl restart mysqld

Tôi biết đây không phải là một giải pháp mong đợi, nhưng nếu bạn gặp khó khăn thì bạn có thể khởi động lại máy chủ mysql.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.