MYSQL 5.7 到底 OPTIMIZE Table 塞不塞 DML

  • 2020 年 3 月 31 日
  • 筆記

問題的起因是另外某篇文字中,對於optimize table 理解不深,說出optimize table 時會和 vacuum full 一樣阻塞表的DML操作,馬上就有好友指出,你說的不對,並拿出evidence.

所以藉此篇,1來證明optimize table 不阻塞DML 2 表示對好友lmongo的感謝, 有一個能指出你錯誤,並大膽友善說出來的人,不多,要感謝。

先寫一段半吊子的python,來作為測試時針對這張表不斷地 DML

測試的方式是通過python來儘可能的插入數據,並且在創造另外的3個Python來玩命的update 表中的任意的記錄。然後對一個有上千萬資料庫的表進行optimize , alter table engine = innodb; alter table force;的操作。

這個操作的主要的重點是優化表重新組織表數據和相關索引數據的物理存儲,減少存儲空間,提高訪問表時的I/O效率。

在操作之前我們也要知道, 1 optimize table 僅僅支援 innodb , myisam archive 等類型資料庫引起的表。optimize 支援分區表。

這就是我錯誤的地方,optimize table 是支援在線DDL ,並且加鎖只在perpare 和 commit 兩個階段。使用在線DDL優化表不支援包含全文索引的InnoDB表。而是使用表複製方法。

驗證開始,執行python 程式,表開始灌入數據,同時也進行3個執行緒的update操作。

操作中,從PYTHON 插入和UPDATE 資料庫的情況,基本上沒有延遲和明顯的抖動。

這也是證明了上述整理磁碟碎片的方法,是DDL online。

而我為什麼會有這個錯誤的概念,主要還是對MYSQL 的部分知識停留在MYSQL 5.6 或更早的知識記憶中。所以相關的知識還是要不斷更新,和學習,尤其MYSQL 8 具有更多的新技能和技術,更應該去更新知識。避免犯一些低級錯誤。

另外如果是大表,需要做optimize table 時如果表中包含大量的索引,也可以直接先清理一些,不常用的索引,加速optimize table 的速度。另外也對比了 MYSQL 5.7 和 8.0 的文檔,目前暫無特別的改變。

下圖證明在操作時會產生新的臨時 frm 和 ibd文件

通過gdb跟蹤,在操作時會與以下文件有關。InnoDB makes considerable effort to make such locks unnecessary, by using techniques such as online DDL, row locks and consistent reads for processing DML

之所以DDL online 也是因為使用row lock 和一致性讀等技術,避免了table lock。