在 MySQL 8.0.12 中,我們引入了一種新的 DDL 算法,該算法在更改表的定義時不會阻塞表。第一個即時操作是在表格末尾添加一列,這是來自騰訊遊戲的貢獻。
然後在 MySQL 8.0.29 中,我們添加了在表中任意位置添加(或刪除)列的可能性。
在這篇文章中,我想重點討論盲目使用此功能時可能發生的一些危險。
默認算法
從 MySQL 8.0.12 開始,對於任何支持的 DDL,默認算法是 INSTANT。這意味着 ALTER 語句只會修改數據字典中表的元數據。在操作的準備和執行階段,不會對錶進行獨佔元數據鎖,表數據不受影響,使得操作是即時的。
另外兩種算法是 COPY 和 INPLACE,Online DDL 操作參見手冊。
然而,即使支持操作,Online DDL 也存在限制:一個表支持 64 次即時更改。到限制後,需要“重建”該表。
如果在 ALTER 語句(DDL 操作)期間未指定算法,則會默默地選擇適當的算法。當然,如果沒有預料到,這可能會導致生產中出現噩夢般的情況。
始終指定算法
因此,第一個建議始終是指定算法,即使它是執行 DDL 時的默認算法。當指定算法時,如果 MySQL 無法使用它,它將拋出錯誤,而不是使用其他算法執行操作:
SQL > ALTER TABLE t1 DROP col1, ALGORITHM=INSTANT;
ERROR: 4092 (HY000): Maximum row versions reached for table test/t1.
No more columns can be added or dropped instantly. Please use COPY/INPLACE.
監控即時變化
第二個建議也是監視對錶執行的即時更改的數量。
MySQL 在 information_schema
表中保留行版本:
SQL > SELECT NAME, TOTAL_ROW_VERSIONS
FROM INFORMATION_SCHEMA.INNODB_TABLES WHERE NAME LIKE 'test/t1';
+---------+--------------------+
| NAME | TOTAL_ROW_VERSIONS |
+---------+--------------------+
| test/t1 | 63 |
+---------+--------------------+
在上面的示例中,DBA 將能夠執行一項額外的 INSTANT DDL 操作,但在此之後,MySQL 將無法執行另一項操作。
作爲 DBA,監視所有表並決定何時需要重建表(以重置該計數器)是一個很好的做法。
這是添加到監控工具的建議查詢的示例:
SQL > SELECT NAME, TOTAL_ROW_VERSIONS, 64-TOTAL_ROW_VERSIONS AS
"REMAINING_INSTANT_DDLs",
ROUND(TOTAL_ROW_VERSIONS/64 * 100,2) AS "DDLs %"
FROM INFORMATION_SCHEMA.INNODB_TABLES
WHERE TOTAL_ROW_VERSIONS > 0 ORDER BY 2 DESC;
+--------------------------+--------------------+------------------------+--------+
| NAME | TOTAL_ROW_VERSIONS | REMAINING_INSTANT_DDLs | DDLs % |
+--------------------------+--------------------+------------------------+--------+
| test/t1 | 63 | 1 | 98.44 |
| test/t | 4 | 60 | 6.25 |
| test2/t1 | 3 | 61 | 4.69 |
| sbtest/sbtest1 | 2 | 62 | 3.13 |
| test/deprecation_warning | 1 | 63 | 1.56 |
+--------------------------+--------------------+------------------------+--------+
要重置計數器並重建表,可以使用 OPTIMIZE TABLE <table>
或 ALTER TABLE <table> ENGINE=InnoDB
結論
總之,MySQL 8.0 引入的 DDL 操作 INSTANT 算法通過避免阻塞更改徹底改變了模式更改。然而,由於 64 次即時更改的限制,在需要重建表之前,在 ALTER 語句期間顯式指定算法以避免意外行爲至關重要。還建議通過 information_schema
監視即時更改的數量,以避免在不知不覺中達到即時更改限制而出現意外情況,並仔細計劃將表重建。
享受 MySQL!
更多技術文章,請訪問:https://opensource.actionsky.com/
關於 SQLE
SQLE 是一款全方位的 SQL 質量管理平臺,覆蓋開發至生產環境的 SQL 審覈和管理。支持主流的開源、商業、國產數據庫,爲開發和運維提供流程自動化能力,提升上線效率,提高數據質量。