日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

作者:宗楊

愛可生產品交付團隊成員,主要負責公司運維平臺和數據庫運維故障診斷。喜愛數據庫、容器等技術,愛好歷史、追劇。

本文來源:原創投稿

*愛可生開源社區出品,原創內容未經授權不得隨意使用,轉載請聯系小編并注明來源。


一、事件背景

我們的合作客戶,駐場人員報告說一個 RDS 實例出現磁盤不足的告警,需要排查。

告警信息:

MySQL 臨時表空間數據過多導致磁盤空間不足的問題排查

 

告警內容:

數據庫 data 磁盤不足,磁盤占用 80% 以上

數據庫 binlog 磁盤不足,磁盤占用 80% 以上

 

二、排查過程

登陸告警的服務器,查看磁盤空間,并尋找大容量文件后,發現端口號為 4675 的實例臨時表空間 ibtmp1 的大小有 955G,導致磁盤被使用了 86%;

MySQL 臨時表空間數據過多導致磁盤空間不足的問題排查

 

猜測和庫里執行長 SQL 有關系,產生了很多臨時數據,并寫入到臨時表空間。

MySQL 臨時表空間數據過多導致磁盤空間不足的問題排查

 

看到有這樣一條 SQL,繼續分析它的執行計劃;

MySQL 臨時表空間數據過多導致磁盤空間不足的問題排查

 

很明顯看到圖中標記的這一點為使用了臨時計算,說明臨時表空間的快速增長和它有關系。這條 SQL 進行了三表關聯,每個表都有幾十萬行數據,三表關聯并沒有在 where 條件中設置關聯字段,形成了笛卡爾積,所以會產生大量臨時數據;而且都是全表掃描,加載的臨時數據過多;還涉及到排序產生了臨時數據;這幾方面導致 ibtmp1 空間快速爆滿。

 

三、解決辦法

和項目組溝通后,殺掉這個會話解決問題;

MySQL 臨時表空間數據過多導致磁盤空間不足的問題排查

 


MySQL 臨時表空間數據過多導致磁盤空間不足的問題排查

 

但是這個 SQL 停下來了,臨時表空間中的臨時數據沒有釋放;

MySQL 臨時表空間數據過多導致磁盤空間不足的問題排查

 

最后通過重啟 MySQL 數據庫,釋放了臨時表空間中的臨時數據,這個只能通過重啟釋放。

MySQL 臨時表空間數據過多導致磁盤空間不足的問題排查

 

四、分析原理

通過查看官方文檔,官方是這么解釋的:

MySQL 臨時表空間數據過多導致磁盤空間不足的問題排查

 

翻譯:

MySQL 臨時表空間數據過多導致磁盤空間不足的問題排查

 

根據官網文檔的解釋,在正常關閉或初始化中止時,將刪除臨時表空間,并在每次啟動服務器時重新創建。重啟能夠釋放空間的原因在于正常關閉數據庫,臨時表空間就被刪除了,重新啟動后重新創建,也就是重啟引發了臨時表空間的重建,重新初始化,所以,重建后的大小為 12M。

從錯誤日志里可以驗證上面的觀點:

MySQL 臨時表空間數據過多導致磁盤空間不足的問題排查

 

五、官網對于 ibtmp1 大小的說明

 

MySQL 臨時表空間數據過多導致磁盤空間不足的問題排查

 


MySQL 臨時表空間數據過多導致磁盤空間不足的問題排查

 

 

六、如何避免

1. 對臨時表空間的大小進行限制,允許自動增長,但最大容量有上限,本例中由于 innodb_temp_data_file_path 設置的自動增長,但未設上限,所以導致 ibtmp1

有 955G。

正確方法配置參數 innodb_temp_data_file_path:

[mysqld]

innodb_temp_data_file_path=ibtmp1:12M:autoextend:max:500M

參考官方文檔:

MySQL 臨時表空間數據過多導致磁盤空間不足的問題排查

 


MySQL 臨時表空間數據過多導致磁盤空間不足的問題排查

 

設置了上限的大小,當數據文件達到最大大小時,查詢將失敗,并顯示一條錯誤消息,表明表已滿,查詢不能往下執行,避免 ibtmp1 過大。

2. 在發送例如本例中的多表關聯 SQL 時應確保有關聯字段而且有索引,避免笛卡爾積式的全表掃描,對存在 group by、order by、多表關聯的 SQL 要評估臨時數據量,對 SQL 進行審核,沒有審核不允許上線執行。

3. 在執行前通過 explain 查看執行計劃,對 Using temporary 需要格外關注。

 

七、其他補充

1> 通過字典表查看執行的 SQL 產生臨時表、使用臨時表空間的情況:

查詢字典表:sys.x$statements_with_temp_tables

select * from sys.x$statements_with_temp_tables where query like 'select%' and db='test' order by tmp_tables_to_disk_pct,disk_tmp_tables descG;

MySQL 臨時表空間數據過多導致磁盤空間不足的問題排查

 

查詢字典表:sys.statements_with_temp_tables

select * from sys.statements_with_temp_tables where query like 'select%' and db='test' order by tmp_tables_to_disk_pct,disk_tmp_tables descG;

MySQL 臨時表空間數據過多導致磁盤空間不足的問題排查

 

這兩個表查詢的結果是一樣的,各列含義如下:

query:規范化的語句字符串。

db:語句的默認數據庫, NULL 如果沒有。

exec_count:語句已執行的總次數。

total_latency:定時出現的語句的總等待時間。

memory_tmp_tables:由該語句的出現創建的內部內存臨時表的總數。

disk_tmp_tables:由該語句的出現創建的內部磁盤臨時表的總數。

avg_tmp_tables_per_query:每次出現該語句創建的內部臨時表的平均數量。

tmp_tables_to_disk_pct:內部內存臨時表已轉換為磁盤表的百分比。

first_seen:第一次看到該聲明的時間。

last_seen:最近一次發表該聲明的時間。

digest:語句摘要。

參考鏈接:https://dev.mysql.com/doc/refman/5.7/en/sys-statements-with-temp-tables.html

通過字典表 tmp_tables_to_disk_pct 這一列結果可知,內存臨時表已轉換為磁盤表的比例是 100%,說明通過復現這個查詢,它的臨時計算結果已經都放到磁盤上了,進一步證明這個查詢和臨時表空間容量的快速增長有關系。

2> 對于 mysql5.7 中 kill 掉運行長 SQL 的會話,ibtmp1 容量卻沒有收縮問題的調研;

來源鏈接:http://mysql.taobao.org/monthly/2019/04/01/

MySQL 臨時表空間數據過多導致磁盤空間不足的問題排查

 

從文章中的解釋看,會話被殺掉后,臨時表是釋放的,只是在 ibtmp1 中打了刪除標記,空間并沒有還給操作系統,只有重啟才可以釋放空間。

3> 下面,進一步用 mysql8.0 同樣跑一下這個查詢,看是否有什么不同;

mysql 版本:8.0.18

MySQL 臨時表空間數據過多導致磁盤空間不足的問題排查

 


MySQL 臨時表空間數據過多導致磁盤空間不足的問題排查

 


MySQL 臨時表空間數據過多導致磁盤空間不足的問題排查

 

當這個 sql 將磁盤跑滿之后,發現與 5.7 不同的是這個 SQL 產生的臨時數據保存到了 tmpdir,mysql5.7 是保存在 ibtmp1 中,而且由于磁盤滿,SQL 執行失敗,很快磁盤空間就釋放了;

問題:如何使用到 8.0 版本的臨時表空間?

通過查看 8.0 的官方文檔得知,8.0 的臨時表空間分為會話臨時表空間和全局臨時表空間,會話臨時表空間存儲用戶創建的臨時表和當 InnoDB 配置為磁盤內部臨時表的存儲引擎時由優化器創建的內部臨時表,當會話斷開連接時,其臨時表空間將被截斷并釋放回池中;也就是說,在 8.0 中有一個專門的會話臨時表空間,當會話被殺掉后,可以回收磁盤空間;而原來的 ibtmp1 是現在的全局臨時表空間,存放的是對用戶創建的臨時表進行更改的回滾段,在 5.7 中 ibtmp1 存放的是用戶創建的臨時表和磁盤內部臨時表;

也就是在 8.0 和 5.7 中 ibtmp1 的用途發生了變化,5.7 版本臨時表的數據存放在 ibtmp1 中,在 8.0 版本中臨時表的數據存放在會話臨時表空間,如果臨時表發生更改,更改的 undo 數據存放在 ibtmp1 中;

MySQL 臨時表空間數據過多導致磁盤空間不足的問題排查

 


MySQL 臨時表空間數據過多導致磁盤空間不足的問題排查

 


MySQL 臨時表空間數據過多導致磁盤空間不足的問題排查

 


MySQL 臨時表空間數據過多導致磁盤空間不足的問題排查

 


MySQL 臨時表空間數據過多導致磁盤空間不足的問題排查

 

實驗驗證:將之前的查詢結果保存成臨時表,對應會話是 45 號,通過查看對應字典表,可知 45 號會話使用了 temp_8.ibt 這個表空間,通過把查詢保存成臨時表,可以用到會話臨時表空間,如下圖:

MySQL 臨時表空間數據過多導致磁盤空間不足的問題排查

 

下一步殺掉 45 號會話,發現 temp_8.ibt 空間釋放了,變為了初始大小,狀態為非活動的,證明在 mysql8.0 中可以通過殺掉會話來釋放臨時表空間。

MySQL 臨時表空間數據過多導致磁盤空間不足的問題排查

 

總結:在 mysql5.7 時,殺掉會話,臨時表會釋放,但是僅僅是在 ibtmp 文件里標記一下,空間是不會釋放回操作系統的。如果要釋放空間,需要重啟數據庫;在 mysql8.0 中可以通過殺掉會話來釋放臨時表空間。

 

八、參考文檔

https://dev.mysql.com/doc/refman/5.7/en/innodb-temporary-tablespace.html

https://dev.mysql.com/doc/refman/8.0/en/innodb-temporary-tablespace.html

http://mysql.taobao.org/monthly/2019/04/01/

分享到:
標簽:臨時 MySQL
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定