主頁 > 資料庫 > MySQL InnoDB表的碎片量化和整理(data free能否用來衡量碎片?)

MySQL InnoDB表的碎片量化和整理(data free能否用來衡量碎片?)

2020-09-17 21:02:03 資料庫


網路上有很多MySQL表碎片整理的問題,大多數是通過demo一個表然后參考data free來進行碎片整理,這種方式對myisam引擎或者其他引擎可能有效(本人沒有做詳細的測驗).
對Innodb引擎是不是準確的,或者data free是不是可以參考,還是值得商榷的,
本文基于MySQL的Innodb存盤引擎,資料庫版本是8.0.18,對碎片(fragment)做一個簡單的分析,來說明如何量化表的碎片化程度,


涉及的引數
1,information_schema_stats_expiry
information_schema是一個基于共享表空間的虛擬資料庫,存盤的是一些系統元資料資訊,某些系統表的資料并不是實時更新的,具體更新是基于引數information_schema_stats_expiry,
information_schema_stats_expiry默認值是86400秒,也就是24小時,意味著24小時重繪一次information_schema中的資料,做測驗的時候可以設定為0,實時重繪information_schema中的元資料資訊,
2,innodb_fast_shutdown
因為要基于磁盤做一些統計,需要將快取或者redo log中的資料在重啟實體的時候實時刷入磁盤,這里設定為0,在重啟資料庫的時候將快取或者redo log實時寫入表的物理檔案,
3,innodb_stats_persistent_sample_pages
因為涉及一些系統資料更新時對page的采樣比例,這里設定為一個較大的值,為100000,盡可能高比例采樣來生成系統資料,
4,innodb_flush_log_at_trx_commit sync_binlog 
因為涉及大量資料的寫操作,為加快測驗,關閉double 1模式,
5,innodb_fill_factor
頁面填充率保留默認的設定,默認值是100
以上涉及的引數僅針對本測驗,并不一定代表最優,同時測驗程序中(資料寫入或者洗掉后)會不斷地重啟實體,以重繪相對應的物理檔案,

碎片的概念
資料存盤在檔案系統上的時候,總是不能100%利用分配給它的物理空間:
比如洗掉資料會在頁面上留下一些”空洞”,或者隨機寫入(聚集索引非線性增加)會導致頁分裂,頁分裂導致頁面的利用空間少于50%;
另外對表進行增刪改會引起對應的二級索引值的隨機的增刪改,也會導致索引結構中的資料頁面上留下一些“空洞”;
雖然這些空洞有可能會被重復利用,但終究會導致部分物理空間未被使用,也就是碎片,
同時,即便是設定了填充因子為100%,Innodb也會主動留下page頁面1/16的空間作為預留使用(An innodb_fill_factor setting of 100 leaves 1/16 of the space in clustered index pages free for future index growth.),
關系資料庫的存盤結構原理上是類似的,理論上很簡單,就不過多啰嗦了,碎片是一個客觀存在的事實,

創建測驗表以及資料

做個簡單的測驗,表結構如下,

CREATE TABLE `fragment_test` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `c1` INT NULL DEFAULT NULL,
    `c2` INT NULL DEFAULT NULL,
    `c3` VARCHAR(50) NULL DEFAULT NULL,
    `c4` DATETIME(6) NULL DEFAULT NULL,
    PRIMARY KEY (`id`) 
);

CREATE INDEX idx_c1 ON fragment_test(c1);
CREATE INDEX idx_c2 ON fragment_test(c2);
CREATE INDEX idx_c3 ON fragment_test(c3);

生成200W測驗資料(CALL test_insertdata(2000000);)

CREATE DEFINER=`root`@`%` PROCEDURE `test_insertdata`(
    IN `loopcount` INT
)
BEGIN
  declare v_uuid  varchar(50);
    while loopcount>0 do
        set v_uuid = uuid();
        INSERT INTO fragment_test(c1,c2,c3,c4) VALUES (RAND()*200000000,RAND()*200000000,UUID(),NOW(6));
        set loopcount = loopcount -1;
    end while;
END

查詢陳述句,參考自最后的鏈接中的文章

SELECT NAME, 
        TABLE_ROWS,
        UPDATE_TIME, 
            format_bytes(data_length) DATA_SIZE,
       format_bytes(index_length) INDEX_SIZE,
       format_bytes(data_length+index_length) TOTAL_SIZE,
       format_bytes(data_free) DATA_FREE,
       format_bytes(FILE_SIZE) FILE_SIZE,
       format_bytes((FILE_SIZE/10 - (data_length/10 + 
                           index_length/10))*10) WASTED_SIZE  
FROM information_schema.TABLES as t 
JOIN information_schema.INNODB_TABLESPACES as it 
  ON it.name = concat(table_schema,"/",table_name) 
WHERE TABLE_NAME = 'fragment_test';

 

碎片的量化
上面說到資料在存盤的時候,總是無法100%利用物理存盤空間,Innodb甚至會自己主動預留一部分空閑的空間(1/16),那么如何衡量一個表究竟有多少尚未利用的空間?
這里從系統表information_schema.tables和information_schema.innodb_tablespaces,來對比實際使用空間和已分配空間來對比,來間接量化碎片或者說未利用空間的程度,

然后觀察資料空間的分配情況,盡管系統表中的資料不是完全準確的,但是也比較接近實際的200W,系統表顯示1971490,暫時拋開這一小點誤差,
可以很清楚地看到,資料和索引的空間是329MB,檔案空間是344MB,DATA_FREE空間是6MB,

隨機洗掉1/4的資料,也就是50W行(DELETE FROM fragment_test ORDER BY RAND() LIMIT 500000;)
然后重啟實體,并執行分析表(analyze table),繼續來觀察這個空間的分配,這里看到,
1,系統表顯示150000行,跟表中的資料完全一致(盡管更多的時候這個值是一個大概的值,并不一定準確,嚴格說可能非常不準確,這里歸因于innodb_stats_persistent_sample_pages的設定),
2,資料檔案空間沒有增加(344MB),可以理解,因為這里是刪資料操作,所以不用申請空間,
3,洗掉了1/4的資料,資料和索引的的大小基本上不變,這里就開始有疑問了,為什么沒有成比例減少?
4,data_free增加了3MB,顯然這不是跟洗掉的資料成比例增加的
那么怎么理解碎片?DATA_FREE怎么理解?碎片或者說可用空間又怎么衡量?

從200W資料中隨機洗掉50W,也就是1/4,表的空間沒有變化,可以肯定的是現在存在大量的碎片或者說可用空間,但是表的總的大小沒變化,data_free也基本上沒有變化到這里就有點說不通了,
那么data free到底是怎么計算的,看官方的解釋:

The number of allocated but unused bytes.
InnoDB tables report the free space of the tablespace to which the table belongs. For a table located in the shared tablespace, this is the free space of the shared tablespace.
If you are using multiple tablespaces and the table has its own tablespace, the free space is for only that table.
Free space means the number of bytes in completely free extents minus a safety margin. Even if free space displays as 0, it may be possible to insert rows as long as new extents need not be allocated.
data_free的計算方式或者說條件,是完全空閑的區(extents,每個區1MB,64個連續的16 kb 大小的page),只有一個完全沒有使用的區,才統計為data_free,因此data_free并不能反映出來真正的空閑空間,

同時測驗中發現,performance_schema.tables中的table_rows會受到innodb_stats_persistent_sample_pages的影響,但是data_length和index_length看起來是不會受innodb_stats_persistent_sample_pages的影響的
這里采樣比例已經足夠大,盡管table_rows已經是一個完全準確的數字了,但是data_length和index_length卻仍舊是一個誤差非常大的數字,
說到這里,那么這個碎片問題如何衡量?如果只是看performance_schema.tables或者information_schema.INNODB_TABLESPACES,其實依舊是一個無解的問題,因為無法通過這些資訊,得到一個相對準確的碎片化程度,
其實在這里(參考鏈接)的評論中也提到這個問題,我是比較贊同的,

如果要真正得到碎片程度,其實還是需要重建表來對比實作,這里洗掉了1/4的資料,理論上就有大概1/4的可用空間,但是上面的查詢結果并不能給出一個明確的答案,怎么驗證這個答案呢?
這里就要粗暴地優化表了(optimize table fragment_test+analyze table),優化表只是“重整”了碎片,但是系統表的資料并沒有更新,因此必須要再執行一次分析表 analyze table來更新元資料資訊
其實這里也能說明,analyze table只是更新元資料,如果存盤空間沒有更新(recreated),單純地analyze table也是沒有用的,
對標進行optimize和anlayze之后,這里可以看到,物理空間確實減少了大概1/4的量,

這里其實就是為了說明一個問題:Innodb表無法通過data free來判斷表的碎片化程度,

然而這里(參考鏈接)的測驗說明洗掉資料后data free有明顯的變化,這個又是為什么,剛特么說無法通過data free來判斷表的碎片化程度,現在又說洗掉資料后data free有明顯的變化???
其實(參考鏈接)中有另外一個比較有意思的測驗,相對用隨機洗掉的方式,采用連續洗掉的時候(或者是整個表的資料全部洗掉),這個data free確實會相對準確地體現出來洗掉資料后表size的變化情況,
這又是為什么?其實不難理解,上面已經說了,data free的計算方式,是按照完全“干凈”的區(extent)來做統計的,
如果按照聚集索引連續的方式洗掉(相對隨機洗掉),那些存盤連續資料的區(extent)是可以完全釋放出來的,這些區的空間釋放出來之后,會被認為是data free,所以data free此時又是相對來說準確的,
因此,很多測驗,如果想到得到客觀的資料,需要盡可能多地考慮到對應的場景和測驗資料情況,

碎片的衡量
實際業務中,對表的洗掉或者增刪改,很少是按照聚集索引進行批量洗掉,或者說一旦存在隨機性的洗掉或者更新(頁分裂),都會造成一定程度的碎片,而這個碎片化的程度是無法通過data free來衡量的,
那么又如何衡量這個碎片程度呢?
1,自己根據業務進行預估,在可接受程度內進行optimize table,記錄optimize table之后的table size變化程度,來衡量一個表在一定時間操作后的碎片化程度,從而來指導是否,或者多久對該表再次進行optimize table
2,采用上述連接中提到的innodb_ruby 這個工具,直接決議表的物理檔案,這種方式相對來說更加直接,不過這個工具本人沒來得及測驗,理論上是沒有問題的,
 這里盜用上述鏈接中的圖片,綠色的是實際使用的空間,中間的黑塊就是所謂的碎片或者說是空洞,


補充:
早上起來,又想到了另外一種case,就是說隨機洗掉后,剩余空間中出現了“空洞”,這些空洞在寫資料的時候,會不會被再次利用?
驗證其實很簡單,寫入200W資料,隨機洗掉50W后,analyze table更新performance_schema,然后繼續再寫入50W行的資料,如果會利用之前隨機洗掉的空洞空間,那么就不會重新分配物理空間,否則就會重新分配物理空間,
因為聚集索引的Id是自增的,相當于順序寫入,理論上是不會重用之前洗掉留下的空洞的,測驗的結果還是在預期之內的,重新寫入50W資料后,表對應的物理檔案會有一個很明顯的增加,

 

參考鏈接:
https://dev.mysql.com/doc/refman/5.7/en/innodb-file-defragmenting.html
https://dev.mysql.com/doc/refman/8.0/en/tables-table.html
https://lefred.be/content/overview-of-fragmented-mysql-innodb-tables/
https://lefred.be/content/mysql-innodb-disk-space/
https://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_innodb_fill_factor

 

轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/68466.html

標籤:MySQL

上一篇:【超詳細全程序】安裝MySQL+Navicat

下一篇:C# 制作火鍋店管理資料庫 要那些表呀 基礎的服務流程 我是新來的 求大佬照顧

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • GPU虛擬機創建時間深度優化

    **?桔妹導讀:**GPU虛擬機實體創建速度慢是公有云面臨的普遍問題,由于通常情況下創建虛擬機屬于低頻操作而未引起業界的重視,實際生產中還是存在對GPU實體創建時間有苛刻要求的業務場景。本文將介紹滴滴云在解決該問題時的思路、方法、并展示最終的優化成果。 從公有云服務商那里購買過虛擬主機的資深用戶,一 ......

    uj5u.com 2020-09-10 06:09:13 more
  • 可編程網卡芯片在滴滴云網路的應用實踐

    **?桔妹導讀:**隨著云規模不斷擴大以及業務層面對延遲、帶寬的要求越來越高,采用DPDK 加速網路報文處理的方式在橫向縱向擴展都出現了局限性。可編程芯片成為業界熱點。本文主要講述了可編程網卡芯片在滴滴云網路中的應用實踐,遇到的問題、帶來的收益以及開源社區貢獻。 #1. 資料中心面臨的問題 隨著滴滴 ......

    uj5u.com 2020-09-10 06:10:21 more
  • 滴滴資料通道服務演進之路

    **?桔妹導讀:**滴滴資料通道引擎承載著全公司的資料同步,為下游實時和離線場景提供了必不可少的源資料。隨著任務量的不斷增加,資料通道的整體架構也隨之發生改變。本文介紹了滴滴資料通道的發展歷程,遇到的問題以及今后的規劃。 #1. 背景 資料,對于任何一家互聯網公司來說都是非常重要的資產,公司的大資料 ......

    uj5u.com 2020-09-10 06:11:05 more
  • 滴滴AI Labs斬獲國際機器翻譯大賽中譯英方向世界第三

    **桔妹導讀:**深耕人工智能領域,致力于探索AI讓出行更美好的滴滴AI Labs再次斬獲國際大獎,這次獲獎的專案是什么呢?一起來看看詳細報道吧! 近日,由國際計算語言學協會ACL(The Association for Computational Linguistics)舉辦的世界最具影響力的機器 ......

    uj5u.com 2020-09-10 06:11:29 more
  • MPP (Massively Parallel Processing)大規模并行處理

    1、什么是mpp? MPP (Massively Parallel Processing),即大規模并行處理,在資料庫非共享集群中,每個節點都有獨立的磁盤存盤系統和記憶體系統,業務資料根據資料庫模型和應用特點劃分到各個節點上,每臺資料節點通過專用網路或者商業通用網路互相連接,彼此協同計算,作為整體提供 ......

    uj5u.com 2020-09-10 06:11:41 more
  • 滴滴資料倉庫指標體系建設實踐

    **桔妹導讀:**指標體系是什么?如何使用OSM模型和AARRR模型搭建指標體系?如何統一流程、規范化、工具化管理指標體系?本文會對建設的方法論結合滴滴資料指標體系建設實踐進行解答分析。 #1. 什么是指標體系 ##1.1 指標體系定義 指標體系是將零散單點的具有相互聯系的指標,系統化的組織起來,通 ......

    uj5u.com 2020-09-10 06:12:52 more
  • 單表千萬行資料庫 LIKE 搜索優化手記

    我們經常在資料庫中使用 LIKE 運算子來完成對資料的模糊搜索,LIKE 運算子用于在 WHERE 子句中搜索列中的指定模式。 如果需要查找客戶表中所有姓氏是“張”的資料,可以使用下面的 SQL 陳述句: SELECT * FROM Customer WHERE Name LIKE '張%' 如果需要 ......

    uj5u.com 2020-09-10 06:13:25 more
  • 滴滴Ceph分布式存盤系統優化之鎖優化

    **桔妹導讀:**Ceph是國際知名的開源分布式存盤系統,在工業界和學術界都有著重要的影響。Ceph的架構和演算法設計發表在國際系統領域頂級會議OSDI、SOSP、SC等上。Ceph社區得到Red Hat、SUSE、Intel等大公司的大力支持。Ceph是國際云計算領域應用最廣泛的開源分布式存盤系統, ......

    uj5u.com 2020-09-10 06:14:51 more
  • es~通過ElasticsearchTemplate進行聚合~嵌套聚合

    之前寫過《es~通過ElasticsearchTemplate進行聚合操作》的文章,這一次主要寫一個嵌套的聚合,例如先對sex集合,再對desc聚合,最后再對age求和,共三層嵌套。 Aggregations的部分特性類似于SQL語言中的group by,avg,sum等函式,Aggregation ......

    uj5u.com 2020-09-10 06:14:59 more
  • 爬蟲日志監控 -- Elastc Stack(ELK)部署

    傻瓜式部署,只需替換IP與用戶 導讀: 現ELK四大組件分別為:Elasticsearch(核心)、logstash(處理)、filebeat(采集)、kibana(可視化) 下載均在https://www.elastic.co/cn/downloads/下tar包,各組件版本最好一致,配合fdm會 ......

    uj5u.com 2020-09-10 06:15:05 more
最新发布
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:33:24 more
  • MySQL中binlog備份腳本分享

    關于MySQL的二進制日志(binlog),我們都知道二進制日志(binlog)非常重要,尤其當你需要point to point災難恢復的時侯,所以我們要對其進行備份。關于二進制日志(binlog)的備份,可以基于flush logs方式先切換binlog,然后拷貝&壓縮到到遠程服務器或本地服務器 ......

    uj5u.com 2023-04-20 08:28:06 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:27:27 more
  • 快取與資料庫雙寫一致性幾種策略分析

    本文將對幾種快取與資料庫保證資料一致性的使用方式進行分析。為保證高并發性能,以下分析場景不考慮執行的原子性及加鎖等強一致性要求的場景,僅追求最終一致性。 ......

    uj5u.com 2023-04-20 08:26:48 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:26:35 more
  • 云時代,MySQL到ClickHouse資料同步產品對比推薦

    ClickHouse 在執行分析查詢時的速度優勢很好的彌補了MySQL的不足,但是對于很多開發者和DBA來說,如何將MySQL穩定、高效、簡單的同步到 ClickHouse 卻很困難。本文對比了 NineData、MaterializeMySQL(ClickHouse自帶)、Bifrost 三款產品... ......

    uj5u.com 2023-04-20 08:26:29 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:25:13 more
  • Redis 報”OutOfDirectMemoryError“(堆外記憶體溢位)

    Redis 報錯“OutOfDirectMemoryError(堆外記憶體溢位) ”問題如下: 一、報錯資訊: 使用 Redis 的業務介面 ,產生 OutOfDirectMemoryError(堆外記憶體溢位),如圖: 格式化后的報錯資訊: { "timestamp": "2023-04-17 22: ......

    uj5u.com 2023-04-20 08:24:54 more
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:24:03 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:23:11 more