微吼云上線多路互動直播服務 加速多場景互動直播落地
979
2025-03-31
官方文檔參考:
https://dev.mysql.com/doc/refman/5.7/en/innodb-disk-management.html
14.12 InnoDB Disk I/O and File Space Management
ACID設計模型需要預留一定量的? I/O,來保證數據的可靠性。在一些限制下,?在InnoDB中,優化數據庫工作和磁盤文件的組織,以最大程度地減少磁盤I / O。有時,I / O會推遲到數據庫空閑,或者直到所有內容都需要進入一致狀態為止,例如在快速關閉后重新啟動數據庫期間。
本節討論默認類型的MySQL表(也稱為InnoDB表)對I / O和磁盤空間的主要注意事項?:
控制用于提高查詢性能的后臺I / O數量。
啟用或禁用可提供額外持久性的功能,但需要付出額外的I / O代價。
將表組織成許多小文件,一些大文件或兩者的組合。
平衡重做日志文件的大小與日志文件已滿時發生的?? I/O活動。
如何重組表以獲得最佳查詢性能。
InnoDB有時使用異步磁盤? I/O,方法是創建多個線程來處理?? I/O操作,同時可以進行其他數據庫操作。在Linux和Windows平臺上,InnoDB使用可用的OS和庫函數來執行 “native” 異步? I/O。在其他平臺上,InnoDB仍然使用? I/O線程,但是這些線程實際上可能會等待? I/O 請求完成。該技術稱為“模擬”?異步I / O。
如果InnoDB可以確定即將有大的數據請求,它將執行預讀操作,將數據加載到緩沖池,以便可以在內存中使用。對持續的、大的讀取請求要比個較小的、散布的請求更為有效。對于innodb有以下兩種預讀:
在順序預讀中,如果InnoDB?注意到對表空間中某個段的訪問模式是順序的,則它會將一批數據庫頁提前讀取到 I/O系統中。
在隨機預讀中,如果InnoDB注意到表空間中的某些區域似乎正在被完全讀取到緩沖池中,則它將剩余的讀取到? I/O系統中。
有關配置預讀啟發式方法的信息,請參見?第14.8.3.4節“配置InnoDB緩沖池預取(預讀)”。
InnoDB使用一種新的文件刷新技術,該技術涉及一種稱為doublewrite緩沖區的結構?,在大多數情況下(innodb_doublewrite=ON)默認啟用。它為意外退出或停電后的恢復增加了安全性,并通過減少fsync()操作需求來提高了大多數Unix類型的性能。
在將頁面InnoDB?寫到數據文件之前,首先將它們寫到稱為doublewrite緩沖區的連續表空間區域中。僅在完成對雙InnoDB?寫緩沖區的寫入和刷新之后,才將頁面寫入數據文件中。如果在頁面寫入過程中存在操作系統,存儲或意外的?mysqld進程退出(導致頁面損壞的?情況),InnoDB則稍后可以在恢復期間從doublewrite緩沖區中找到該頁面的未損壞副本。
如果系統表空間文件(“?ibdata文件”)位于支持原子寫的Fusion-io設備上,則自動禁用雙寫緩沖,并且將Fusion-io原子寫用于所有數據文件。由于doublewrite緩沖區設置是全局的,因此對于非Fusion-io硬件上駐留的數據文件,還將禁用doublewrite緩沖。此功能僅在Fusion-io硬件上受支持,并且僅在Linux上的Fusion-io NVMFS中啟用。要充分利用此功能,?建議innodb_flush_method設置?O_DIRECT為。
您使用innodb_data_file_path?配置選項在配置文件中定義的文件形成InnoDB?系統表空間。這些文件在邏輯上串聯在一起以組成系統表空間。沒有使用的條帶化。您無法定義表在系統表空間中的分配位置。在新創建的系統表空間中,InnoDB從第一個數據文件開始分配空間。
為避免將所有表和索引存儲在系統表空間內所帶來的問題,可以啟用?innodb_file_per_table?配置選項(默認開啟),該選項將每個新創建的表存儲在單獨的表空間文件中(擴展名為?.ibd)。對于以這種方式存儲的表,磁盤文件中的碎片較少,并且當表被truncate時,該空間將釋放給操作系統,而不是仍由InnoDB在系統表空間中保留。有關更多信息,請參見?第14.6.3.2節“每表文件表空間”。
您還可以將表存儲在 普通表空間中。普通表空間是使用CREATE TABLESPACE?語法創建的共享表空間。它們可以在MySQL數據目錄之外創建,能夠容納多個表,并支持所有行格式的表。有關更多信息,請參見?第14.6.3.3節“常規表空間”。
每個表空間由數據庫pages組成?。MySQL實例中的每個表空間都具有相同的page size。默認情況下,所有表空間的page size均為16KB;可以通過innodb_page_size參數,在創建MySQL實例時將page size 改為8KB或4KB ,32KB或64KB。有關更多信息,請參閱?innodb_page_size文檔。
這些頁面分為大小為1MB的extents,用于最大16KB的頁面(64個連續的16KB頁面,128個8KB頁面或256個4KB頁面)。對于32KB的pages,extents大小為2MB。對于64KB的pages,extents大小為4MB。表空間內的”files”被稱為 InnoDB的segments。(這些段與回滾段不同,?回滾段實際上包含許多表空間段。)
當段在表空間內增長時,?InnoDB一次將前32 pages分配給它。之后,InnoDB開始將整個extents分配給該段。InnoDB 一次最多可以向一個segments 中添加4個extents,以確保數據的順序性。
對于每個索引,會分配兩個 InnoDB segments。一個用于?B樹的非葉節點,另一個用于葉節點。將葉節點保持在磁盤上連續可以實現更好的順序I / O操作,因為這些葉節點包含實際的表數據。
表空間中的某些頁面包含其他頁面的位圖,因此表空間中的某些擴展數據InnoDB塊無法整體分配給段,而只能分配給各個頁面。
當您通過發出一條SHOW TABLE STATUS語句在表空間中請求可用空間 時,請?InnoDB報告表空間中絕對可用的extents。InnoDB始終保留一定程度的清理空間和其他內部用途;這些保留的范圍不包括在可用空間中。
從表中刪除數據時,InnoDB 將收縮相應的B樹索引。釋放的空間是否可供其他用戶使用取決于刪除模式是否將單個page或extents釋放到表空間中。刪除表或刪除表中的所有行可以保證將空間釋放給其他用戶,但請記住,刪除的行僅通過perge操作才能物理刪除, purge操作會在不再需要事務回滾或一致讀取后的一段時間自動發生。 。(請參見?第14.3節“ InnoDB多版本”。)
對于4KB,8KB,16KB和32KB的innodb_page_size設置,最大行長度略小于數據庫頁面的一半?。例如,對于默認的16KBInnoDB頁面大小,最大行長度略小于8KB?。對于64KB頁面,最大行長度略小于16KB。
如果某行未超過最大行長,則所有行都將存儲在本地頁面內。如果某行超出最大行長,則選擇可變長度列進行外部頁外存儲,直到該行適合最大行長限制。可變長度列的外部頁外存儲因行格式而異:
緊湊和冗余行格式
當將可變長度列選擇用于外部頁外存儲時,InnoDB將前768個字節本地存儲在該行中,其余部分從外部存儲到溢出頁中。每個此類列都有其自己的溢出頁面列表。768字節的前綴附帶一個20字節的值,該值存儲列的真實長度,并指向溢出列表,該值的其余部分存儲在溢出列表中。請參見?第14.11節“ InnoDB行格式”。
動態和壓縮行格式
如果將可變長度列選擇用于外部頁外存儲,則InnoDB在該行中本地存儲一個20字節的指針,其余部分在外部存儲到溢出頁中。請參見第14.11節“ InnoDB行格式”。
LONGBLOB和?LONGTEXT列必須小于4GB,并且總行長度(包括?BLOB和?TEXT列)必須小于4GB。
增大日志文件可以減少磁盤 I/O的?檢查點。通常將日志文件的總大小設置為與等于或者大于緩沖池。盡管從MySQL 5.5開始,過去大日志文件可能會使崩潰恢復花費更多時間,但是崩潰恢復的性能增強使得崩潰后可以快速啟動使用大型日志文件。(嚴格來說,對于具有InnoDB Plugin 1.0.7和更高版本的MySQL 5.1,可以實現這種性能改進。對于MySQL 5.5,可以在默認的InnoDB存儲引擎中進行此改進。)
InnoDB的?檢查點機制稱為模糊檢查點。小批量地從緩沖池中刷新已修改的數據庫頁面。無需單批刷新緩沖池,因為這個會在檢查點過程中中斷用戶SQL語句的處理。
在崩潰恢復期間,?InnoDB查找寫入日志文件的檢查點標簽。標簽之前的修改都已存在于磁盤中。然后InnoDB從檢查點向前掃描日志文件,將記錄的修改應用于數據庫。
隨機插入二級索引或從二級索引中刪除可能導致索引碎片化。碎片意味著磁盤上索引頁的物理排序與頁上記錄的索引排序連續,或者64頁塊中有許多未使用的頁已分配給索引。
碎片的一個癥狀是表占用的空間超過了它應“占用”的空間。確切的數量是很難確定的。所有InnoDB數據和索引都存儲在B樹中,它們的填充因子可能在50%到100%之間變化。碎片化的另一個癥狀是,這樣的表掃描花費的時間比“應該”花費的時間更多?:
SELECT COUNT(*) FROM t WHERE non_indexed_column <> 12345;
前面的查詢要求MySQL執行全表掃描,這是大型表的最慢查詢類型。
為了加快索引掃描的速度,您可以定期執行?“?null?”?ALTER TABLE?操作,這會導致MySQL重建表:
ALTER TABLE tbl_name ENGINE=INNODB
您還可以?用來執行?“?null?”更改操作以重建表。?ALTER TABLE?tbl_name?FORCE
以上兩者,都使用?在線DDL。有關更多信息,請參見第14.13節“ InnoDB和在線DDL”。
執行碎片整理操作的另一種方法是使用?mysqldump將表轉儲到文本文件,刪除表并從轉儲文件重新加載它。
如果對索引的插入總是遞增的,并且記錄僅從末尾刪除,則InnoDB?文件空間管理算法可確保不會發生索引中的碎片。
14.12.5 Reclaiming Disk Space with TRUNCATE TABLE
當 truncate 表去回收操作系統的磁盤空間時,該表必須存放在自己的的.ibd文件。若要將表存儲在其自己的.ibd?文件中,innodb_file_per_table必須在創建表時啟用。此外,被truncate 的表和其他表之間不能有?外鍵約束,否則?TRUNCATE TABLE操作將失敗。但是,允許在同一表的兩列之間使用外鍵約束。
truncate 表后,將其刪除并在新.ibd文件中重新創建?,并將釋放的空間返回給操作系統。這與truncate 存儲在?InnoDB?系統表空間?(在中創建的表innodb_file_per_table=OFF)中的表和存儲在共享通用表InnoDB空間中的表(在表被truncate 后只能使用釋放的空間)?相反?。
truncate 表并將磁盤空間返回給操作系統的功能還意味著?物理備份可以更小。truncate 存儲在系統表空間(在時創建的表?innodb_file_per_table=OFF)或共享表空間中的表,會將表空間中未使用的空間塊保留下來。
MySQL 數據庫
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。