《Mysql - 為什么表數據刪掉一半,表文件大小不變?》


一:概念

  - 這里,我們還是針對 MySQL 中應用最廣泛的 InnoDB 引擎展開討論

  - 一個 InnoDB 表包含兩部分,即:表結構定義和數據

    - 在 MySQL 8.0 版本以前,表結構是存在以.frm 為后綴的文件里。

    - 而 MySQL 8.0 版本,則已經允許把表結構定義放在系統數據表中了。

    - 因為表結構定義占用的空間很小,所以我們今天主要討論的是表數據。 

 

二:表數據既可以存在共享表空間里,也可以是單獨的文件。由參數 innodb_file_per_table 控制。

  - 概念

    - 這個參數設置為 OFF 表示的是,表的數據放在系統共享表空間,也就是跟數據字典放在一起。

    - 這個參數設置為 ON 表示的是,每個 InnoDB 表數據存儲在一個以 .ibd 為后綴的文件中。

 

  - 從 MySQL 5.6.6 版本開始,它的默認值就是 ON 了。

    - 因為,一個表單獨存儲為一個文件更容易管理,而且在你不需要這個表的時候,通過 drop table 命令,系統就會直接刪除這個文件。

    - 而如果是放在共享表空間中,即使表刪掉了,空間也是不會回收的。 

 

三:數據刪除流程

  - 數據

    - 

 

  - 刪除

    - 假設,我們要刪掉 300 的記錄,InnoDB 引擎只會把 300 這個記錄標記為刪除。

    - 但是, 如果之后要再插入一個 在 300-500 之間的記錄時,可能會復用這個位置。(磁盤文件的大小並不會縮小)。

    - 如果我們刪掉了一個數據頁上的所有記錄,整個數據頁就可以被復用了。(如果相鄰的兩個數據頁利用率都很小,會整合兩個數據頁,一個數據頁就被標記為可復用。)

 

  - 如果我們用 delete 命令把整個表的數據刪除呢?

    - 結果就是,所有的數據頁都會被標記為可復用。但是磁盤上,文件不會變小。

 

  - 結論

    - Delete 命令其實只是把記錄的位置,或者數據頁標記為了“可復用”,但磁盤文件的大小是不會變的。

    - 也就是說,通過 Delete 命令是不能回收表空間的。

    - 這些可以復用,而沒有被使用的空間,看起來就像是“空洞”。

    - 實際上,不止是刪除數據會造成空洞,插入數據也會。

      - 如果數據是按照索引遞增順序插入的,那么索引是緊湊的。但如果數據是隨機插入的,就可能造成索引的數據頁分裂。

      - 假設我要寫入的 page A 已經滿了,在插入一行數據,也會導致頁分裂。 

      - 另外,更新索引上的值,可以理解為刪除一個舊的值,再插入一個新值。不難理解,這也是會造成空洞的。

    - 也就是說,經過大量增刪改的表,都是可能是存在空洞的。

    - 所以,如果能夠把這些空洞去掉,就能達到收縮表空間的目的。 

 

四:重建表(去除空洞)

  - 如果需要重建表,那么你能想出他是如何構建表的?

    - 建立 臨時表B,把 A 表數據根據遞增的關系,放入 B 中,最后用 B 替換 A。完成重構。(A 的空間收縮,空洞消失)

 

  - 而在MySQL 5.6 版本開始引入的 Online DDL,對這個重建操作流程做了優化。

    - 流程

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

      - 用數據頁中表 A 的記錄生成 B+ 樹,存儲到臨時文件中。

      - 生成臨時文件的過程中,將所有對 A 的操作記錄在一個日志文件(row log)中。

      - 臨時文件生成后,將日志文件中的操作應用到臨時文件,得到一個邏輯數據上與表 A 相同的數據文件。

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

 

    - 區別

      - 不同之處在於,由於日志文件記錄和重放操作這個功能的存在,這個方案在重建表的過程中,允許對表 A 做增刪改操作。

      - 這也就是 Online DDL 名字的來源。 

 

五:如何重建表?

  - alter table t engine = InnoDB(也就是 recreate)

    - OnLine DDL

 

  - analyze table t

    - 其實不是重建表,只是對表的索引信息做重新統計,沒有修改數據,這個過程中加了 MDL 讀鎖;

 

  - optimize table t

    - 等於 recreate+analyze。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM