通過alter table 來實現重建表,同事大呼開眼界了

架構精進之路 發佈 2024-04-26T15:09:33.798633+00:00

hello,大家好,我是張張,「架構精進之路」公號作者。1、應用背景在日常工作開發中,在MySQL中,如果我們對大表頻繁進行insert和delete操作,那麼時間一長,這個表中會出現很多"空洞",也就是表碎片。

hello,大家好,我是張張,「架構精進之路」公號作者。

1、應用背景

在日常工作開發中,在MySQL中,如果我們對大表頻繁進行insert和delete操作,那麼時間一長,這個表中會出現很多"空洞",也就是表碎片。

碎片產生的原因是insert隨機值作為主鍵id,會產生很多數據頁分裂操作;而delete掉一些排列有序的主鍵值,這些被delete的空間不會直接釋放,而是僅僅進行delete的標記,這些空間如果不能被利用,那就會變成"空洞"。

2、重建表

關於重建表,這時候新建一張結構一樣的臨時表,把表內的數據導入到臨時表,直接刪除舊錶,然後將臨時表替換為舊錶,從而釋放這些空餘的空間,讓數據變得"緊湊些",完成重建操作。

我們其實可以通過如下命令來重建表:

alter table tableName engine=Innodb

在MySQL5.5版本之前,這個命令的執行流程跟1操作差不多,區別只是在於這個臨時表不需要你直接創建,MySQL會自動完成轉存數據、交換表名、刪除舊錶的操作。

這個重建表的過程,在MySQL5.5之前,它的執行邏輯是下面這樣的:

1、假設原表是A,新建一個表table B,和表A的表結構保持一致;

2、按照主鍵順序,將表A的數據一行一行的讀出來,插入到表B裡面;

3、交換表A和表B的名稱。

3、重建實現優化

通過上面的介紹可以發現,花時間最多的步驟是往臨時表插入數據的過程,如果在這個過程中,有新的數據要寫入到表 A 的話,就會造成數據丟失。

因此,在整個 DDL 過程中,舊錶中不能有更新(也就是說,這個 DDL 不是 Online 的)。

在MySQL5.6及以後的版本裡面,引入了Online DDL的方法,Online DDL的引入,使得上面的過程有了一點點不同,當執行如下命令的時候,

alter table tableName engine=innodb

MySQL5.6版本開始引入的Online DDL,對這個操作流程做了優化:

1、建立一個臨時文件,掃描表A主鍵的所有數據頁;

2、用數據頁中表A的記錄生產B+樹,存儲到臨時文件中;

3、生產臨時文件的過程中,將所有對A的操作記錄在一個日誌文件(row log)中,對應的是圖中state2的狀態;

4、臨時文件生成後,將日誌文件中的操作應用到臨時文件,得到一個邏輯數據上與表A相同的數據文件,對應的就是圖中state3的狀態;

5、用臨時文件替換表A的數據文件。

執行alter語句時,需要獲取MDL寫鎖,但是這個寫鎖在真正拷貝數據之前就退化成讀鎖。為了實現Online,MDL讀鎖不會阻塞增刪改操作。

那為什麼要從寫鎖退化成讀鎖而不乾脆直接解除鎖呢?為了保護自己,禁止其他線程對這個表同時做DDL。

4、答疑解惑

關於重建表,相信大家還會有其他的疑惑,一起來總結下。

Q1、在MySQL5.5之前,我們使用臨時表作為重建的中間介質,在MySQL5.6之後,我們使用臨時文件作為重建的中間介質,臨時表和臨時文件的區別是?

A:臨時表是創建在server層面的,臨時文件是創建在innodb層面的,所以Online DDL的整個過程都是在Innodb內部完成的,這種方法也稱之為"inplace",相對應的,需要藉助server層面臨時表的過程,稱之為"Copy"。

Q2、假設我們有一個1TB的表,磁碟只有1.2TB,那麼還可以做inplace的DDL呢?

A:不可以,因為inplace方案中的臨時文件也要占用一定的空間。

Q3、inplace 方案進行的表重建操作,都是Online DDL麼?

A:不一定,例如增加全文索引的操作,這個操作是inplace的,但是會阻塞增刪改查操作,因此不是Online DDL。應該說:Online DDL一定是inplace的,但是inplace方案進行的操作,不一定是Online的。

Q4、某個表的大小是1TB,進行alter table A engine=Innodb之後,表的空間沒有縮小,反而增大了一點,這是為什麼?

A:可能是因為表之前剛剛進行過一次alter table的操作,而且表上面的並發增刪改比較多,在進行alter table 的過程中,這些操作都寫進了log中,從而導致表的實際大小會增加。



希望今天的講解對大家有所幫助,謝謝!

Thanks for reading!

作者:架構精進之路,十年研發風雨路,大廠架構師,CSDN 博客專家,專注架構技術沉澱學習及分享,職業與認知升級,堅持分享接地氣兒的乾貨文章,期待與你一起成長。
關注並私信我回復「01」,送你一份程式設計師成長進階大禮包,歡迎勾搭。

關鍵字: