[英]Changing Large MySQL InnoDB Tables
對於MySQL中具有超過1000萬行的大型innodb表,添加新列或添加新索引可能要花費數小時和數天的時間。 在這兩種情況下,提高大型innodb表性能的最佳方法是什么? 更存儲器,調整上述結構(例如增加sort_buffer_size的值或innodb_buffer_pool_size ),或某種特技的? 與其直接更改一個表,不如創建一個新表,對其進行更改,然后將舊數據復制為新數據,這樣對ISAM表和多項更改非常有用:
CREATE TABLE tablename_tmp LIKE tablename;
ALTER TABLE tablename_tmp ADD fieldname fieldtype;
INSERT INTO tablename_tmp SELECT * FROM tablename;
ALTER TABLE tablename RENAME tablename_old;
ALTER TABLE tablename_tmp RENAME tablename;
它是否也推薦用於innodb表,或者只是ALTER TABLE命令執行的操作?
Edit 2016:我們最近(2016年8月)發布了gh-ost
,修改了我的回答以反映出來。
今天,有幾種工具可讓您為MySQL做在線更改表。 這些是:
大桌子需要很長時間才能ALTER
。 innodb_buffer_pool_size
很重要,其他變量也很重要,但是在很大的表上,它們都可以忽略不計。 這只需要時間。
MySQL ALTER
表的作用是創建具有新格式的新表,復制所有行,然后切換。 在此期間,表被完全鎖定。
它最有可能在所有選項中表現最差。 這是為什么? 因為您使用的是InnoDB表,所以INSERT INTO tablename_tmp SELECT * FROM tablename
可以進行事務處理。 一筆巨大的交易。 與正常的ALTER TABLE
相比,它將產生更多的負載。
而且,您此時必須關閉您的應用程序,以使其不向表寫入( INSERT
, DELETE
, UPDATE
)。 如果可以,那么您的整個交易毫無意義。
這些工具並非都一樣。 但是,基本知識是共享的:
RENAME
交換兩者。 openark-kit工具已經使用了3.5年。 Percona工具已經使用了幾個月,但可能比前者經過了更多的測試。 據說Facebook的工具很適合Facebook,但沒有為普通用戶提供通用的解決方案。 我自己沒有用過。
編輯2016年: gh-ost
是一種無觸發的解決方案,可顯着減少主服務器上的主服務器寫入負載,從而將遷移寫入負載與正常負載分離。 它是可審核,可控制,可測試的。 我們已經在GitHub內部進行了開發,並將其作為開源發布。 我們今天通過gh-ost
進行所有生產遷移。 在這里查看更多。
每個工具都有其自身的局限性,請仔細閱讀文檔。
保守的方法是使用主動-被動主-主復制,在備用(被動)服務器上執行ALTER
,然后切換角色,然后對以前變為主動(現在變為被動)的服務器再次執行ALTER
。 這也是一個不錯的選擇,但是需要額外的服務器和更深的復制知識。
重命名參考表的螺絲。
如果您說出table_2
是tablename
子級,則在ALTER TABLE tablename RENAME tablename_old;
table_2
將開始指向tablename_old
。
現在,無需更改table_2,您就無法將其指向tablename
。 您必須繼續在每個子表和引用表中進行更改。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.