久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

MySQL的碎片有哪些

144次閱讀
沒有評論

共計 6383 個字符,預計需要花費 16 分鐘才能閱讀完成。

本篇內容主要講解“MySQL 的碎片有哪些”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓丸趣 TV 小編來帶大家學習“MySQL 的碎片有哪些”吧!

MySQL 的幾種碎片整理方案總結(解決 delete 大量數據后空間不釋放的問題)1. 背景知識?1.1 為什么會有碎片?

MySQL 中 insert 與 update 都可能導致頁分裂,這樣就存在碎片。

對于大量的 UPDATE,也會產生文件碎片化,Innodb 的最小物理存儲分配單位是頁(page),而 UPDATE 也可能導致頁分裂(page split),頻繁的頁分裂,頁會變得稀疏,并且被不規則的填充,所以最終數據會有碎片。

delete 語句實際上只是給數據打個標記,并且記錄到一個鏈表中,這樣就形成了留白空間。

在 InnoDB 中,刪除一些行,這些行只是被標記為“已刪除”,而不是真的從索引中物理刪除了,因而空間也沒有真的被釋放回收。InnoDB 的 Purge 線程會異步的來清理這些沒用的索引鍵和行。

當執行插入操作時,MySQL 會嘗試使用空白空間,但如果某個空白空間一直沒有被大小合適的數據占用,仍然無法將其徹底占用,就形成了碎片;

總結:

truncate table 其實有點類似于 drop table 然后 creat, 只不過這個 create table 的過程做了優化,比如表結構文件之前已經有了等等。所以速度上應該是接近 drop table 的速度;

drop,truncate 立刻釋放磁盤空間,不管是 Innodb 和 MyISAM ;

delete from table_name 刪除表的全部數據, 對于 MyISAM 會立刻釋放磁盤空間(應該是做了特別處理,也比較合理),InnoDB 不會釋放磁盤空間;

對于 delete from table_name where xxx; 帶條件的刪除, 不管是 innodb 還是 MyISAM 都不會釋放磁盤空間;

delete 操作以后使用 optimize table table_name 會立刻釋放磁盤空間。不管是 innodb 還是 myisam。所以要想達到釋放磁盤空間的目的,delete 以后執行 optimize table 操作。

delete from 表以后雖然未釋放磁盤空間,但是下次插入數據的時候,仍然可以使用這部分空間。

表的增刪改操作,可能會造成數據空洞的,當對表進行大量的增刪改操作后,數據空洞存在的可能性比較大。

MySQL 刪除數據幾種情況以及是否釋放磁盤空間:

1.2 碎片帶來的問題

當 MySQL 對數據進行掃描時,它掃描的對象實際是列表的容量需求上限,也就是數據被寫入的區域中處于峰值位置的部分;

MySQL 數據庫中的表在進行了多次 delete、update 和 insert 后,表空間會出現碎片。定期進行表空間整理,消除碎片可以提高訪問表空間的性能。

這種碎片不僅額外增加了存儲代價,同時也因為數據碎片化降低了表的掃描效率。

碎片若不整理,那么可能會長期占據磁盤空間,導致磁盤使用率越來越高。

2. 如何清理碎片?

修復問題的前提是要先找到問題,這樣才能對癥下藥。

2.1. 查看表的碎片情況

查看數據庫中每個存在碎片的表

mysql  select concat(optimize table  ,table_schema, . ,table_name,),data_free,engine from information_schema.tables where data_free 0 and engine != MEMORY 
+-----------------------------------------------------------+-----------+--------+
| concat(optimize table  ,table_schema, . ,table_name,) | DATA_FREE | ENGINE |
+-----------------------------------------------------------+-----------+--------+
| optimize table abc.t_user_answer;  | 2097152 | InnoDB |
| optimize table mysql.time_zone_transition; | 4194304 | InnoDB |
| optimize table mysql.time_zone_transition_type; | 4194304 | InnoDB |
| optimize table mysql.user; | 4194304 | InnoDB |。。。。

查看指定表的碎片情況

 mysql  show table status like  t_user \G
 *************************** 1. row ***************************
 Name: t_user
 Engine: InnoDB
 Version: 10
 Row_format: Dynamic
 Rows: 4333
 Avg_row_length: 589
 Data_length: 2555904
 Max_data_length: 0
 Index_length: 2719744
 Data_free: 4194304
 Auto_increment: NULL
 Create_time: 2021-11-19 10:13:31
 Update_time: 2022-04-20 14:28:42
 Check_time: NULL
 Collation: utf8mb4_general_ci
 Checksum: NULL
 Create_options:
 Comment:
 1 row in set (0.00 sec)

Data_free: 4194304 就代表碎片的 byte 數。如果經常刪改數據表,會造成大量的 Data_free 頻繁 刪除記錄 或修改有可變長度字段的表。

找到碎片化最嚴重的表

SELECT table_schema, TABLE_NAME, concat(data_free/1024/1024,  M) as data_free
FROM `information_schema`.tables
WHERE data_free   3 * 1024 * 1024
 AND ENGINE =  innodb 
ORDER BY data_free DESC

2.2 清理碎片 (回收空間) 的方法

官方文檔參考

通常有這幾種做法

alter table tb_test engine=innodb;(本質上是 recreate)

optimize table tb_test;(本質上是 recreate,但是在不同創建下會有區別)

ALTER TABLE tablename FORCE (在 InnoDB 表中等價于 alter table tb_test engine=innodb;)

mysqlcheck 批量表空間優化

gh-ost/pt-osc

pt-online-schema-change(本質上也是 先備份舊表數據,然后 truncate 舊表)

1. alter table tb_test engine=innodb 原理介紹

這其實是一個 NULL 操作, 表面上看什么也不做, 實際上重新整理碎片了. 當執行優化操作時, 實際執行的是一個空的 ALTER 命令, 但是這個命令也會起到優化的作用, 它會重建整個表, 刪掉未使用的空白空間.

Running ALTER TABLE tbl_name ENGINE=INNODB on an existing InnoDB table performs a“null”ALTER TABLE operation, which can be used to defragment an InnoDB table, as described in Section 15.11.4,“Defragmenting a Table”. Running ALTER TABLE tbl_name FORCE on an InnoDB table performs the same function.

 MySQL5.6  開始采用  Inplace  方式重建表,Alter  期間,支持  DML  查詢和更新操作,語句為  alter table t engine=innodb, ALGORITHM=inplace; 之所以支持  DML  更新操作,是因為數據拷貝期間會將  DML  更新操作記錄到  Row log  中。  重建過程中最耗時的就是拷貝數據的過程,這個過程中支持  DML  查詢和更新操作,對于整個  DDL  來說,鎖時間很短,就可以近似認為是  Online DDL。  執行過程: 1、獲取  MDL(Meta Data Lock)寫鎖,innodb  內部創建與原表結構相同的臨時文件
 2、拷貝數據之前,MDL  寫鎖退化成  MDL  讀鎖,支持  DML  更新操作
 3、根據主鍵遞增順序,將一行一行的數據讀出并寫入到臨時文件,直至全部寫入完成。并且,會將拷貝期間的  DML  更新操作記錄到  Row log  中
 4、上鎖,再將  Row log  中的數據應用到臨時文件
 5、互換原表和臨時表表名
 6、刪除臨時表

2. optimize table xxx;

OPTIMIZE TABLE 語句可以重新組織表、索引的物理存儲,減少存儲空間,提高訪問的 I / O 效率。類似于碎片整理功能。

MySQL 可以通過 optimize table 語句釋放表空間,重組表數據和索引的物理頁,減少表所占空間和優化讀寫性能

使用語法

OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_n 說 ame [, tbl_name] …

對于主從架構,LOCAL 參數可以讓這個過程不寫入 binlog , 這樣在主庫上執行時就不會同步給從庫了

默認情況下,MySQL 將 OPTIMIZE TABLE 語句寫入二進制日志,以便它們復制到 slave 服務器。如果不想寫二進制日志,使用命令時加上 NO_WRITE_To_BINLOG 或 LOCAL 關鍵字即可。

使用這個語句需要具有對目標表的 SELECT、INSERT 權限。

注意:

需要有足夠的空間才能進行 OPTIMIZE TABLE。(剩余空間必須 被 OPTIMIZE 的表的大小)

OPTIMIZE 只對獨立表空間 (innodb_file_per_table=1) 才有用,對共享表空間不起作用。

對于共享表空間,如果需要瘦身:必須將數據導出,刪除 ibdata1,然后將 innodb_file_per_table 設置為獨立表空間,然后將數據導入進來。

對于 InnoDB 的表,OPTIMIZE TABLE 的工作原理如下

對于 InnoDB 表,OPTIMIZE TABLE 映射到 ALTER TABLE … FORCE(或者這樣翻譯:在 InnoDB 表中等價 ALTER TABLE … FORCE),它重建表以更新索引統計信息并釋放聚簇索引中未使用的空間。

當您在 InnoDB 表上運行時,它會顯示在 OPTIMIZE TABLE 的輸出中,如下所示:mysql  OPTIMIZE TABLE foo; 
+----------+----------+----------+---------------------------------------+ 
| Table | Op | Msg_type | Msg_text | 
+----------+----------+----------+---------------------------------------+ 
| test.foo | optimize | note | Table does not support optimize, doing recreate + analyze instead | 
| test.foo | optimize | status | OK | 
+----------+----------+----------+---------------------------------------+ 
#  但這個提示語可以忽略,從嚴格的意義講,說 InnoDB 不支持 optimize table,其實不太準確。  因為  MYSQL 的文檔說明了,當 INNODB  的表,MYSQL 會以  ALTER TABLE force + analyze  去執行這個命令(相當于做了 recreate 和 analyze)。  所以最終還是會看到  OK  的狀態。 
# https://stackoverflow.com/questions/30635603/what-does-table-does-not-support-optimize-doing-recreate-analyze-instead-me

對于 MYISAM 表,OPTIMIZE TABLE 的工作原理:
1. 如果表已刪除或分隔行,就修復該表。
2. 如果索引頁沒有排序,就排序它們。
3. 如果表的統計信息不是最新的(而且修復不能通過對索引進行排序),就更新它們。

** 執行時也可以發現報錯:Temporary file write failure. **

建議參考這片文章:
Mysql optimize table 時報錯 Temporary file write failure. 的解決方案

optimize 語句的官網介紹

如果您已經刪除了表的一大部分,或者如果您已經對含有可變長度行的表(含有 VARCHAR, BLOB 或 TEXT 列的表)進行了很多更改,則應使用 OPTIMIZE TABLE。

被刪除的記錄被保持在鏈接清單中,后續的 INSERT 操作會重新使用舊的記錄位置。您可以使用 OPTIMIZE TABLE 來重新利用未使用的空間,并整理數據文件的碎片。

在多數的設置中,您根本不需要運行 OPTIMIZE TABLE。即使您對可變長度的行進行了大量的更新,您也不需要經常運行,每周一次或每月一次 即可,只對特定的表運行。

Mysql 5.6 之前 在 OPTIMIZE TABLE 運行過程中,MySQL 會鎖定表,5.6 之后有了 Online DDL 則大大減少了鎖表時間。

3. alter table、analyze table 和 optimize table 區別

alter table tb_test engine = innodb;

(也就是 recreate)MySQL 5.5 以前用 Offline 的方式重建表,5.6 以后用 Online 的方式重建表;

analyze table tb_test;

重新統計表的索引信息,不會修改數據,不會重建表,整個過程加 MDL 讀

optimize table tb_test;

是 alter table xxx = innodb;+ analyze table xxx; 的過程。

4. OPTIMIZE TABLE 和 ALTER TABLE xxxx ENGINE= INNODB 哪個更好

OPTIMIZE TABLE 還是 ALTER TABLE xxxx ENGINE= INNODB 基本上是一樣的。但是在有些情況下,ALTER TABLE xxxx ENGINE= INNODB 更好。

例如: old_alter_table 系統變量沒有啟用等等。

另外:對于 MyISAM 類型表,使用 ALTER TABLE xxxx ENGINE= INNODB 是明顯要優于 OPTIMIZE TABLE 這種方法的。

2.3 官方建議

MySQL 官方建議不要經常 (每小時或每天) 進行碎片整理,一般根據實際情況,只需要每周或者每月整理一次即可(我們現在是每月凌晨 4 點清理 mysql 所有實例下的表碎片)

到此,相信大家對“MySQL 的碎片有哪些”有了更深的了解,不妨來實際操作一番吧!這里是丸趣 TV 網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-07-13發表,共計6383字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 巩义市| 方正县| 山阴县| 白朗县| 台南县| 连州市| 苏尼特右旗| 额尔古纳市| 乡宁县| 栾城县| 五华县| 义马市| 博爱县| 赣州市| 平罗县| 景谷| 商南县| 玛曲县| 宁陕县| 隆德县| 稻城县| 鹿邑县| 高阳县| 长岛县| 紫云| 延吉市| 浮山县| 青铜峡市| 什邡市| 庆元县| 乃东县| 荔波县| 厦门市| 昌平区| 东山县| 崇信县| 宜春市| 宜宾市| 施秉县| 塘沽区| 安陆市|