在 MySQLdump 文件中將表類型從 MyISAM 更改為 InnoDB
我有幾百個系統在 MariaDB 10.1.x 上執行。在這些系統上,有一個主數據庫,由於各種遺留原因,它必須有 MyISAM 表。我希望為這些擁有所有主 MyISAM 表的 InnoDB 版本的主伺服器生產從屬伺服器。出於操作原因,我寧願不必對
ALTER TABLE
從屬設備執行各種操作。我正在考慮(可能很簡單)從主伺服器獲取 MySQLdump 文件作為初始從屬設置的一部分,然後使用某種腳本簡單地更改其
CREATE TABLE
命令以指定 InnoDB 的表類型而不是 MyISAM。這是一種明智的方法嗎,還有其他人嘗試過嗎?有沒有更好的方法可以讓我成為一個使用 InnoDB 而不必做大量
ALTER TABLE
s 的奴隸。我很希望這是可以自動化/基於腳本的東西,因為我們在該領域實際上有數百個這樣的系統,因此手動升級過程將是勞動密集型的並且非常容易出錯。
順便說一句,我注意到 MySQL/MariaDB 本身在內部使用了許多 MyISAM 表,例如
mysql.user
表。他們是否出於任何特定原因使用 MyISAM,或者這些表是否也可以安全地轉換為 InnoDB。還是我更好地確保我用來進行轉換的任何腳本都mysql
完全避免了數據庫中的表?
我創建了腳本,將儲存引擎從 MyISAM 翻轉到 InnoDB,如下所示:
mysqldump ... | sed 's/ENGINE=MyISAM/ENGINE=InnoDB/' > dump.sql
如果你想看看這是否真的有效,只需如下轉儲模式:
mysqldump --no-data ... | sed 's/ENGINE=MyISAM/ENGINE=InnoDB/' > schema.sql
參考mysql schema,請勿觸碰。為什麼 ???
在 MySQL 5.5 中,mysql 模式中的所有表都是 MyISAM。
mysql> select count(1) table_count,ifnull(engine,'Total') eng -> from information_schema.tables where table_schema='mysql' -> group by engine with rollup; +-------------+--------+ | table_count | eng | +-------------+--------+ | 22 | MyISAM | | 22 | Total | +-------------+--------+ 2 rows in set (0.03 sec)
在 MySQL 5.6 中,這種情況開始發生變化
mysql> select count(1) table_count,ifnull(engine,'Total') eng -> from information_schema.tables where table_schema='mysql' -> group by engine with rollup; +-------------+--------+ | table_count | eng | +-------------+--------+ | 2 | CSV | | 5 | InnoDB | | 21 | MyISAM | | 28 | Total | +-------------+--------+ 4 rows in set (0.00 sec)
以下是 MySQL 5.6 的非 MyISAM 表:
mysql> select table_name,engine from information_schema.tables -> where table_schema='mysql' and engine in ('InnoDB','CSV') -> order by engine,table_name; +----------------------+--------+ | table_name | engine | +----------------------+--------+ | general_log | CSV | | slow_log | CSV | | innodb_index_stats | InnoDB | | innodb_table_stats | InnoDB | | slave_master_info | InnoDB | | slave_relay_log_info | InnoDB | | slave_worker_info | InnoDB | +----------------------+--------+ 7 rows in set (0.00 sec)
如果您將log_output更改為 FILE ,則這兩個 CSV 表是慢速日誌和錯誤日誌。引入了 5 個 InnoDB 表來支持崩潰安全複製(參見文件)。
它不止於此。MySQL 5.7 引入了更多的 InnoDB 表。
mysql> select count(1) table_count,ifnull(engine,'Total') eng -> from information_schema.tables where table_schema='mysql' -> group by engine with rollup; +-------------+--------+ | table_count | eng | +-------------+--------+ | 2 | CSV | | 19 | InnoDB | | 10 | MyISAM | | 31 | Total | +-------------+--------+ 4 rows in set (0.01 sec)
以下是 MySQL 5.7 的非 MyISAM 表:
mysql> select table_name,engine from information_schema.tables -> where table_schema='mysql' and engine in ('InnoDB','CSV') -> order by engine,table_name; +---------------------------+--------+ | table_name | engine | +---------------------------+--------+ | general_log | CSV | | slow_log | CSV | | engine_cost | InnoDB | | gtid_executed | InnoDB | | help_category | InnoDB | | help_keyword | InnoDB | | help_relation | InnoDB | | help_topic | InnoDB | | innodb_index_stats | InnoDB | | innodb_table_stats | InnoDB | | plugin | InnoDB | | servers | InnoDB | | server_cost | InnoDB | | slave_master_info | InnoDB | | slave_relay_log_info | InnoDB | | slave_worker_info | InnoDB | | time_zone | InnoDB | | time_zone_leap_second | InnoDB | | time_zone_name | InnoDB | | time_zone_transition | InnoDB | | time_zone_transition_type | InnoDB | +---------------------------+--------+ 21 rows in set (0.17 sec)
請注意,在 MySQL 5.7 中仍有 10 個 MyISAM。他們來了:
mysql> select table_name,engine from information_schema.tables -> where table_schema='mysql' and engine='MyISAM'; +------------------+--------+ | table_name | engine | +------------------+--------+ | columns_priv | MyISAM | | db | MyISAM | | event | MyISAM | | func | MyISAM | | ndb_binlog_index | MyISAM | | proc | MyISAM | | procs_priv | MyISAM | | proxies_priv | MyISAM | | tables_priv | MyISAM | | user | MyISAM | +------------------+--------+ 10 rows in set (0.00 sec)
為什麼 MyISAM 中還有 10 個表?
- 表
user
、db
、procs_priv
、proxies_priv
、tables_priv
和columns_priv
是儲存使用者授權的表。func
包含儲存的函式proc
包含儲存過程event
包含執行事件的時間表ndb_binlog_index
包含 NDB 儲存引擎(MySQL 集群)所需的資訊這 10 個表很少使用。它們的內容在啟動時載入到 RAM 中,然後從 RAM 中引用。它們不需要是 InnoDB,因為它們是不應通過事務更改的系統級表。
看看如果這 10 個表是 InnoDB 可能會出現的潛在問題:
- 在事務中執行 GRANT 命令並回滾
- 在事務中創建儲存過程並回滾
- 創建一個新使用者,
user
表崩潰並損壞可能會導致這些和其他問題,您甚至不會知道它,直到 mysqld 重新啟動並且沒有人可以登錄、執行儲存過程或安排 cron’d 事件。
因此,有充分的理由將這 10 個表保留為 MyISAM。同樣,請不要更改
mysql
架構中任何內容的儲存引擎。