將實時 MyISAM 表轉換為 InnoDB
我有一個跟踪網路流量的表。該表不斷地被寫入和讀取。由於表的大小相當大,我必須確保應用程序在從MyISAM -> InnoDB轉換錶的儲存引擎的過程中不會“凍結” 。以下是我根據從其他文章中收集到的資訊計劃做的事情。如果我遺漏了什麼,請告訴我。
mysqldump -u -p --lock-tables=false mydb tracking > tracking.sql
- 據我了解,這不應該鎖定“跟踪”表- 將sql文件中的表名重命名為tracking_new
mysql -u -p mydb < tracking.sql
ALTER TABLE mydb.tracking_new ENGINE=InnoDB;
- 將新行插入到“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
到混合物中。試一試 !!!