Làm cách nào để chuyển đổi cơ sở dữ liệu từ MyISAM sang InnoDB?


9

Tôi sẽ chuyển đổi tất cả các bảng cơ sở dữ liệu 500MB từ MyISAM sang InnoDB để xem liệu nó có cải thiện hiệu suất tổng thể của một trang web Drupal 6 bận rộn hay không. Tôi đang tự hỏi đâu là cách tốt nhất (tức là an toàn nhất / dễ nhất / nhanh nhất) để thực hiện chuyển đổi.


Đây dường như không phải là một câu hỏi liên quan đến Drupal phải không?
tostinni

2
Không trực tiếp, nhưng đó là điều mà các quản trị viên Drupal cần phải làm trong dịp.
mpdon Arena

Tôi đã cập nhật câu trả lời của mình để sử dụng lệnh SQL mới để lọc ra các bảng MyISAM có chỉ mục FULLTEXT. Vui lòng chạy lại tất cả các bước từ đầu bằng cách sử dụng câu trả lời cập nhật của tôi.
RolandoMySQLDBA

Nếu trang web Drupal của bạn không được định cấu hình để tìm kiếm bằng các chỉ mục FULLTEXT, bạn có thể muốn đi đến tất cả các bảng có chỉ mục FULLTEXT và loại bỏ các chỉ mục đó ra khỏi các bảng đó. Để tìm tất cả các bảng có chỉ mục FULLTEXT, hãy chạy CHỌN bảng_schema, bảng TỪ information_schema.statistic WHERE index_type = 'FULLTEXT';
RolandoMySQLDBA

Câu trả lời:


7

Là một DBA của MySQL, tôi tin tưởng MySQL thực hiện chuyển đổi bằng cách nhờ MySQL viết kịch bản cho tôi.

Hình thành lệnh Linux chạy truy vấn này

mysql -h... -u... -p... -A --skip-column-names -e"SELECT CONCAT('ALTER TABLE ',db,'.',tb,' ENGINE=InnoDB;') FROM (SELECT A.db,A.tb,A.tbsize FROM (SELECT table_schema db,table_name tb,(data_length+index_length) tbsize FROM information_schema.tables WHERE engine='MyISAM' AND table_schema NOT IN ('information_schema','mysql')) A LEFT JOIN (SELECT table_schema db,table_name tb FROM information_schema.statistics WHERE index_type='FULLTEXT') B USING (db,tb) WHERE B.db IS NULL) AA ORDER BY tbsize" > /root/ConvertMyISAM2InnoDB.sql

Kịch bản sẽ chuyển đổi các bảng nhỏ nhất đầu tiên. Tập lệnh này cũng đã bỏ qua mọi bảng MyISAM có chỉ mục FULLTEXT.

Sau khi xem qua tập lệnh, bạn có thể chỉ cần chạy nó trong MySQL như sau:

mysql -h... -u... -p... -A < /root/ConvertMyISAM2InnoDB.sql

hoặc nếu bạn muốn xem thời gian của mỗi chuyển đổi, hãy đăng nhập vào mysql và chạy nó:

mysql> source /root/ConvertMyISAM2InnoDB.sql

Điều này không nên bị rối vì khóa bảng đầy đủ xảy ra khi chuyển đổi đang được thực hiện.

Khi tất cả các bảng được chuyển đổi, bạn cần điều chỉnh cài đặt MySQL để sử dụng InnoDB và thu nhỏ key_buffer.

Vui lòng đọc phần này để thiết lập Nhóm đệm InnoDB: /dba/1/what-are-the-main-differences-b between-sinodb-and-myisam / 194 # 23194

Vui lòng đọc phần này: /drupal/1715/what-would-the-optimal-mysql-configuration-for-a-drupal-7-site-be/2367#2367

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


Roland, tôi đã thử giải pháp của bạn nhưng sau khi nhập ConvertMyISAM2InnoDB.sql vào cơ sở dữ liệu, tôi gặp lỗi này: "ERROR 1214 (HY000) ở dòng 585: Loại bảng đã sử dụng không hỗ trợ các chỉ mục FULLTEXT". Vậy tôi có nên biết liệu việc chuyển đổi diễn ra trên một số bảng hay không và tôi nên khắc phục lỗi này như thế nào? Cảm ơn

Tôi sợ điều đó sẽ xảy ra. Điều đó chỉ có nghĩa là một bảng MyISAM có chỉ mục FULLTEXT. Đăng nhập vào mysql và chạy nếu như bạn muốn xem thời gian. Nói cách khác, chạy nguồn /root/ConvertMyISAM2InnoDB.sql
RolandoMyQueryDBA

Tôi sẽ thử cập nhật tập lệnh tạo SQL để bỏ qua các bảng có chỉ mục FULLTEXT.
RolandoMySQLDBA

Trong khi đó, lặp lại tất cả các bước này từ đầu. Dòng đầu tiên của tệp được lấy lại có tệp MyISAM với chỉ mục FULLTEXT. Đơn giản chỉ cần xóa dòng đầu tiên và chạy lại tập lệnh.
RolandoMySQLDBA

Chà, bằng cách chạy tập lệnh bash chuyển đổi thú vị này ( yoodey.com/ ,), tôi đã nhận ra rằng rõ ràng bảng duy nhất trên cơ sở dữ liệu của tôi sử dụng Toàn văn là 'search_index'. Điều này khiến việc chuyển đổi tạm dừng nhưng sau khi hủy chuyển đổi trên đó, phần còn lại đã diễn ra suôn sẻ. Bằng cách chạy nguồn ConvertMyISAM2InnoDB.sql tôi không thể xác định được thủ phạm. Dù sao tôi đánh giá cao sự giúp đỡ của bạn.

4

Tôi đã viết một lệnh drush cho điều này một thời gian trước đây.

<?php
/**
 * Implements hook_drush_command().
 */
function convert_drush_command() {
  $items = array();

  // the key in the $items array is the name of the command.
  $items['convert-engine'] = array(
    // a short description of your command
    'description' => "Convert MYSQL Table Type",
  );
  return $items;
}

function drush_convert_engine() {
  $args = func_get_args();
  $engine = $args[0];

  $result = db_query("SHOW TABLES");
  while ($row = db_fetch_array($result)) {
    $table = array_shift($row);
    drush_log(dt('Converting @table to @engine', array('@table' => $table, '@engine' => $engine)), 'success');
    db_query("ALTER TABLE $table ENGINE = $engine");
  }
}

Đã làm việc cho tôi một năm trước hoặc lâu hơn, không chắc API đã thay đổi kể từ đó.

Bạn có thể đặt nó trong convert.drush.inc chẳng hạn trong thư mục .drush hoặc thực thi nó bằng cách nào đó trên trang web của bạn, ví dụ như với khối php thực thi devel. Là một kịch bản drush, bạn có thể gọi nó như thế này:

drush convert-engine InnoDB

Cảnh báo : Nếu ai đó làm gì đó với cơ sở dữ liệu trong khi các lệnh này chạy, cơ sở dữ liệu của bạn sẽ bị rối hoàn toàn. Không thể phục hồi. Vì vậy, hãy đặt trang web của bạn vào chế độ bảo trì và tạo bản sao lưu trước khi thử điều này! Và tất nhiên, hãy thử trên một trang web phát triển / thử nghiệm đầu tiên :)


5
Đồng ý với Berdir, sao lưu trang web của bạn. Trong khi hoạt động này đang diễn ra, cơ sở dữ liệu của bạn sẽ bị KHÓA. Nếu bạn muốn một mô-đun có thể làm điều đó, hãy bắn DB Tuner .
mikeytown2

@ mikeytown2: Đó là một mô-đun khá thú vị :)
Berdir

1
Kịch bản đẹp nhưng có vẻ khá quá so với thực hiện trực tiếp máy khách MySQL này.
tostinni

2
Kịch bản chính xác là 5 dòng mã. Phần còn lại là tích hợp nó với drush. Có một cách để làm điều này trong một lệnh sql duy nhất trong MySQL. Bằng cách này hay cách khác, bạn phải viết một kịch bản.
Berdir
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.