Mysql

將實時 MyISAM 表轉換為 InnoDB

  • August 28, 2015

我有一個跟踪網路流量的表。該表不斷地被寫入和讀取。由於表的大小相當大,我必須確保應用程序在從MyISAM -> InnoDB轉換錶的儲存引擎的過程中不會“凍結” 。以下是我根據從其他文章中收集到的資訊計劃做的事情。如果我遺漏了什麼,請告訴我。

  1. mysqldump -u -p --lock-tables=false mydb tracking > tracking.sql- 據我了解,這不應該鎖定“跟踪”表
  2. 將sql文件中的表名重命名為tracking_new
  3. mysql -u -p mydb < tracking.sql
  4. ALTER TABLE mydb.tracking_new ENGINE=InnoDB;
  5. 將新行插入到“tracking_new”表中,這些行在執行轉儲時寫入原始表
SELECT @last_id := tracking.id FROM mydb.tracking_new ORDER BY tracking.id DESC LIMIT 1;    
INSERT INTO mydb.tracking_new
SELECT * FROM mydb.tracking WHERE tracking.id > @last_id;

重命名表

RENAME TABLE 
   mydb.tracking TO mydb.tracking_old, 
   mydb.tracking_new TO mydb.tracking;

假設您在該表上沒有任何觸發器,在不鎖定表的情況下執行此操作的最簡單方法是使用pt-online-schema-change.

確保您有足夠的額外磁碟空間來容納此更改。轉換為 InnoDB 時表會變大,轉換過程中需要維護表的兩個副本。例如,如果您的表是 100 GB,請確保您至少有 200+ GB 的可用磁碟空間。

您應該首先在非生產環境中對其進行測試,以確保它適合您並準確了解您需要多少磁碟空間。

您的案例的語法非常簡單。

首先進行試執行以驗證它是否可以工作:

pt-online-schema-change --alter "ENGINE=InnoDB" D=mydb,t=tracking --dry-run

然後執行它:

pt-online-schema-change --alter "ENGINE=InnoDB" D=mydb,t=tracking --execute

如果跟踪表是 MyISAM,您可能不得不依賴concurrent_insert。這樣做是讓跟踪表添加新行而不鎖定 MyISAM 表中間的孔。它只會對所有傳入的行進行快速而骯髒的附加。

如果您將concurrent_insert設置為 2,您應該能夠寫入跟踪表並仍然複製數據。

這是一個替代建議:

步驟 01:啟動 concurrent_size 以始終追加

mysql -Dmydb -ANe"SET GLOBAL concurrent_insert = 2"

STEP 02 : 創建表的 InnoDB 版本

SQL="CREATE TABLE tracking_innodb LIKE tracking;"
SQL="${SQL} ALTER TABLE tracking_innodb ENGINE=InnoDB;"
mysql -Dmydb -ANe"${SQL}"

STEP 03 : 將跟踪表直接複製到新表中

mysqldump --no-create-info mydb tracking | sed 's/tracking/tracking_innodb' | mysql -Dmydb

STEP 04 : 重命名跟踪表以防止新插入

mysql -Dmydb -ANe"ALTER TABLE tracking RENAME tracking_old"

步驟 05:在 tracking_old 中檢索最後一個 ID

SQL="SELECT id FROM tracking_new ORDER BY tracking.id DESC LIMIT 1"
LASTID=`mysql -Dmydb -ANe"`

步驟 06:檢索剩餘數據

SQL="INSERT INTO tracking_new SELECT * FROM tracking_odl WHERE id > ${LASTID}"
mysql -Dmydb -ANe"${SQL}"

STEP 07 : 將 tracking_new 重命名為 tracking

mysql -Dmydb -ANe"ALTER TABLE tracking_new RENAME tracking"

警告

你原來的提議實際上也一樣好。無論如何,我的大部分答案看起來都像你。唯一的區別是我引入了一個中斷來保證沒有新的插入從STEP 04. 在您的計劃中稍早出現中斷 ( STEP 02)。

我添加了 concurrent_insert 以加快在 mysqldump 期間插入 MyISAM 表的速度。

您可以按照您的計劃或我的計劃進行。只需添加concurrent_insert=2到混合物中。

試一試 !!!

引用自:https://dba.stackexchange.com/questions/53641