Tăng tốc chuyển đổi MyISAM sang InnoDB


15

Tôi đã có một máy chủ mysql 5.1 với cơ sở dữ liệu khoảng 450 bảng, chiếm 4GB. Phần lớn các bảng này (tất cả trừ 2) là MyIsam. Điều này đã ổn đối với hầu hết các phần (không cần giao dịch), nhưng ứng dụng đã đạt được lưu lượng truy cập và một số bảng nhất định đã bị ảnh hưởng do khóa bảng trên các bản cập nhật. Đó là lý do 2 trong số các bảng là InnoDB.

Việc chuyển đổi trên các bảng nhỏ hơn (hàng 100 nghìn) hoàn toàn không mất nhiều thời gian, gây ra thời gian chết tối thiểu. Tuy nhiên, một vài trong số các bảng theo dõi của tôi đang tiếp cận 50 triệu hàng. Có cách nào để tăng tốc ALTER TABLE...ENGINE InnoDBtrên một cái bàn lớn không? Và nếu không, có phương pháp nào khác để chuyển đổi giảm thiểu thời gian chết trên các bảng nặng không?


1
Một điều cần lưu ý: nhiều câu hỏi trong một bài đăng có xu hướng làm nản lòng những người có thể trả lời một trong những câu hỏi từ việc đăng câu trả lời.
BenV

Tôi VtC vì điều này khá phức tạp để trả lời. Bạn nên mở như một số câu hỏi cá nhân.
jcolebrand

Tôi sẵn sàng nhận lời khuyên để biến nó thành một câu hỏi duy nhất, nhưng có nên xóa câu hỏi này không và chỉ mở một câu hỏi mới? việc viết lại chủ yếu sẽ loại bỏ 2 viên đạn thứ hai và thay đổi viên đạn thứ nhất (tôi cũng đã cập nhật tiêu đề để phản ánh công cụ lưu trữ nào)
Derek Downey

Hoặc là sẽ ổn thôi. Nó thường dễ dàng hơn để viết hai câu hỏi khác và xóa một câu hỏi. Tuy nhiên, bạn có thể dễ dàng bỏ cái này để "tham khảo" và để hai cái kia quay lại với nó, vì câu hỏi "đây là mục tiêu chung của tôi".
jcolebrand

chỉnh sửa cái này thành một viên đạn, sau đó đăng các câu hỏi tiếp theo.
Brian Ballsun-Stanton

Câu trả lời:


10

Hãy để tôi bắt đầu bằng cách nói, tôi ghét ALTER. Thật là ác, IMHO.

Nói, đây là lược đồ bảng hiện tại của bạn -

CREATE TABLE my_table_of_love (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
my_value VARCHAR(40),
date_created DATE,
PRIMARY KEY(id)
) ENGINE=MyISAM CHARSET=utf8;

Đây là con đường tôi khuyên dùng -

Tạo một đối tượng bảng mới sẽ thay thế đối tượng cũ:

CREATE TABLE my_table_of_love_NEW (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
my_value VARCHAR(40),
date_created DATE,
PRIMARY KEY(id)
) ENGINE=InnoDB CHARSET=utf8

Chèn tất cả các hàng từ bảng cũ theo tên vào bảng mới:

INSERT INTO my_table_of_love_NEW (id,my_value,date_created)
SELECT id,my_value,date_created FROM my_table_of_love;

Khói kiểm tra di chuyển của bạn:

SELECT COUNT(*) FROM my_table_of_love_NEW;
SELECT COUNT(*) FROM my_table_of_love;
SELECT a.id,a.my_value,a.date_created FROM my_table_of_love_NEW a
LEFT JOIN my_table_of_love b ON (b.id = a.id)
WHERE a.my_value != b.my_value;

Hoán đổi tên bảng để bạn có thể duy trì sao lưu trong trường hợp bạn cần quay lại.

RENAME TABLE my_table_of_love TO my_table_of_love_OLD;
RENAME TABLE my_table_of_love_NEW TO my_table_of_love;

Tiến hành kiểm tra hồi quy.

Cách tiếp cận này ngày càng trở nên thích hợp hơn với các bảng có nhiều chỉ mục và hàng triệu hàng.

Suy nghĩ?


1
Đồng ý ... mặc dù nếu giao dịch nhiều, bạn có thể cần phải gỡ cơ sở dữ liệu trong khi thực hiện việc này. (nhưng một bảng thay đổi sẽ cung cấp cho bạn thời gian ngừng hoạt động lâu hơn, rất có thể)
Joe

Vâng, tôi hình dung nó sẽ yêu cầu thời gian chết cho các bảng hoạt động nhiều hơn. Tôi sẽ phải chạy một số thử nghiệm, nhưng tại sao lại ALTER TABLEmất nhiều thời gian hơn INSERT INTO...SELECT50 triệu hàng?
Derek Downey

Nó sẽ không. Về cơ bản, MySQL thực hiện chính xác như nội dung này. Nó tạo ra một bản sao của định nghĩa và tải nhỏ giọt vào bản sao.
Morgan Tocker

Tôi thích phương pháp này vì nó bỏ qua phần "copy to tmp", có thể mất một chút thời gian cho các bảng lớn.
Haluk

Hãy để tôi thêm bây giờ, rằng trong MySQL 5.7, ALTERs nhanh hơn và dễ dàng hơn để đối phó.
Randomx

7

1) Bảo vệ mất mát là một chức năng của hoang tưởng. Luôn luôn tạo một bản sao lưu. Nếu bạn thực sự hoang tưởng, hãy tạo một bản sao lưu sau đó khôi phục từ bản sao lưu.

2) Trang này của hướng dẫn sử dụng MySQL có hướng dẫn để chuyển đổi các loại bảng.

Cách nhanh nhất để thay đổi bảng thành InnoDB là thực hiện chèn trực tiếp vào bảng InnoDB. Đó là, sử dụng ALTER TABLE ... Engine = INNODB hoặc tạo một bảng InnoDB trống với các định nghĩa giống hệt nhau và chèn các hàng với CHERTN VÀO ... CHỌN * TỪ ....

3) PostgreSQL thực hiện tìm kiếm toàn văn bản , Sphinx Engine dường như làm điều đó cho MySQL


Tôi chắc chắn sẽ xem xét nhân sư, vì tôi mới chỉ nghe nói về nó.
Derek Downey

3

Dễ dàng hơn gấp X lần để tối ưu hóa toàn bộ máy chủ (cấu hình bộ nhớ, bộ nhớ cache, chỉ mục) khi bạn chỉ có một công cụ được sử dụng. Trộn myisam với innodb trên cơ sở dữ liệu lớn sẽ luôn bị kẹt ở một số điểm bắt buộc bởi một số tính năng cho cả hai công cụ hoạt động tốt (nhưng không xuất sắc :)

Tôi khuyên bạn nên quan tâm đến một số công cụ tìm kiếm toàn văn chuyên dụng như nhân sư , lucene ( solr ) và loại bỏ nó khỏi lớp cơ sở dữ liệu.

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.