MySQL 轉儲和載入 InnoDB 緩衝池(資料預熱)
對於效能,擁有一個暖的 InnoDB 緩衝池非常重要。那是什麼意思 ?
暖緩衝池意味著生產工作負載所需的最常用的頁面(工作集)已經載入到記憶體中(在緩衝池中)。如果是這樣,MySQL 不需要在每次需要最常用的頁面時從磁碟讀取頁面,並在所需資料已經在記憶體中時加快程序。
當您啟動 MySQL 時,預設情況下 InnoDB 緩衝池是冷的,預熱過程有時甚至需要幾天時間……
因此,您已經可以推斷出重新啟動 mysqld 是具有冷緩衝池的來源,因為它將開始為空。使用非最佳緩衝池的另一個原因是載入不必要的頁面。這可能發生在邏輯轉儲或載入期間。如果你經常做一個mysqldump例子(不要忘記如果你做邏輯轉儲,MySQL Shell dump & load 會更好,但也會引入相同的效果)。
但是在 MySQL 中,也有可能處理這樣的問題:InnoDB 緩衝池的轉儲和載入!
有多種方法可以處理 InnoDB 緩衝池轉儲和載入,讓我解釋一些場景。
關機時轉儲,啟動時載入
我們必須處理緩衝池的第一個選項是在我們停止 MySQL 時轉儲其內容。我們並沒有真正轉儲完整的緩衝池,而是轉儲mysqld正確停止時其中的頁面的地址。
事實上,這是現在在 MySQL 中的預設設定,innodb_buffer_pool_dump_at_shutdown是啟用的。當然,當 MySQL 啟動時,它也會載入innodb_buffer_pool_load_at_startup同樣啟用的內容。
我們還將在這篇文章的後面看到與此相關的內容……但讓我們稍等一下……
按需轉儲和載入
在 MySQL 中,我們還可以使用innodb_buffer_pool_dump_now. 這將轉儲磁碟上的當前內容。然後也可以使用innodb_buffer_pool_load_now.
這在 崩潰的情況下也很有用mysqld,因為它不是乾淨的關閉,緩衝池的內容沒有正確轉儲到磁碟,但將載入手動完成的最新內容。
InnoDB 緩衝池的這種手動轉儲和載入的主要目的是當會有不同於通常的工作負載時,可以用工作集以外的資料填充緩衝池。例如轉儲一個完整的大型舊模式。
定期傾倒
可以每隔一段時間轉儲緩衝池的內容。這在發生崩潰以避免載入舊轉儲時很有用。
為此,您需要建立一個這樣的事件:
CREATEEVENT automatic_buffer_pool_dump ON SCHEDULE EVERY 1 HOUR DO SET global innodb_buffer_pool_dump_now=ON;
讓我們來看看如何玩這個以及如何控制它:
測試和示例
我們做的第一件事是控制緩衝池的內容,
mysql> SELECT CONCAT(FORMAT(A.num * 100.0 / B.num,2), '%') BufferPoolFull FROM ( SELECT variable_value num FROM performance_schema.global_status WHERE variable_name = 'Innodb_buffer_pool_pages_data') A, (SELECT variable_value num FROM performance_schema.global_status WHERE variable_name = 'Innodb_buffer_pool_pages_total') B; +----------------+ | BufferPoolFull | +----------------+ | 75.29% | +----------------+ 1 row in set (0.01 sec
我們甚至可以驗證緩衝池中載入了哪些模式:
mysql> SELECT object_schema, allocated, data FROM sys.innodb_buffer_stats_by_schema; +---------------+-----------+------------+ | object_schema | allocated | data | +---------------+-----------+------------+ | sbtest | 53.22 MiB | 46.97 MiB | | mysql | 5.36 MiB | 2.72 MiB | | query_rewrite | 16.00 KiB | 0 bytes | +---------------+-----------+------------+
現在我們轉儲內容:
mysql> SET global innodb_buffer_pool_dump_now=ON; Query OK, 0 rows affected (0.00 sec)
在錯誤日誌中,我們可以看到以下訊息:
mysql> select LOGGEND, DATA from performance_schema.error_log order by 1 desc limit 2; +-------------+---------------------------------------------------------+ | LOGGED | DATA | +-------------+---------------------------------------------------------+ | 2021-06-16. | Buffer pool(s) dump completed at 210616 14:25:39 | | 2021-06-16. | Dumping buffer pool(s) to /var/lib/mysql/ib_buffer_pool | +-------------+---------------------------------------------------------+
在檔案系統上:
[root@imac mysql]# ls -lh ib_buffer_pool -rw-r----- 1 mysql mysql 20K Jun 16 14:25 ib_buffer_pool
我們重新啟動 MySQL 並再次檢查:
+----------------+ | BufferPoolFull | +----------------+ | 26.12% | +----------------+
嗯……發生了什麼事?這不是我所期望的……
事實上,這是我的錯,我沒有仔細閱讀文件,我的同事 Marcin Babij 向我指出了原因:innodb_buffer_pool_dump_pct.
預設情況下的值innodb_buffer_pool_dump_pct是25!
為了讓它按預期工作,如果你想完全轉儲和載入它,你需要將它設定為100。
+----------------+ | BufferPoolFull | +----------------+ | 99.10% | +----------------+ 1 row in set (0.00 sec) mysql> SET GLOBAL innodb_buffer_pool_dump_pct = 100;
然後我重新啟動 MySQL(我在啟動時禁用了緩衝池的負載):
+----------------+ | BufferPoolFull | +----------------+ | 18.70% | +----------------+ 1 row in set (0.00 sec) mysql> SET global innodb_buffer_pool_load_now=ON; Query OK, 0 rows affected (0.00 sec) +----------------+ | BufferPoolFull | +----------------+ | 99.94% | +----------------+ 1 row in set (0.01 sec)
因此,現在您知道如何處理 MySQL InnoDB 緩衝池預熱以及如何進行是否計劃執行可能嚴重影響記憶體中工作集的異常查詢。
原文連結:https://lefred.be/content/mysql-dump-load-innodb-buffer-pool/