探索MYSQL開啟大頁記憶體
1 開啟大頁記憶體的好處:
1.減少記憶體置換
2.減少TLB miss次數
3.減少swap
4 避免被系統OOM KILL 掉
2 在開啟MYSQL8 時系統記憶體使用情況
mysql> system free -m
total used free shared buff/cache available
Mem: 7821 5884 1225 14 711 1239
Swap: 8063 25 8038
-- 此時系統頁表 15.5MB
mysql> system cat /proc/meminfo |grep PageTable
PageTables: 15888 kB
關閉MYSQL後頁表大小和記憶體大小
PageTables: 4076 kB
[root@localhost ~]# free -m
total used free shared buff/cache available
Mem: 7821 202 6917 15 701 6920
Swap: 8063 25 8038
MYSQL 佔用了11812KB的系統頁表,對應記憶體5884-202=5480MB
3 計算需要多少 huge pages
啟用 huge page之前 首先我們要計算分配多少huge page給mysql 使用。
一般的建議是mysql使用的總記憶體大小加上10%。計算公式如下
S = (table_open_cache + innodb_buffer_pool_size + innodb_log_file_size + performance_schema.memory) + 10 %INNODB BUF 4096MB+LOG BUF 16MB+BINLOG CACHE 16MB + ..=4160 /2MB =2080頁 *1.1=2288=2290
SELECTROUND(@@table_open_cache/1024/1024,2) as TABLE_OPEN_MB,ROUND(@@innodb_buffer_pool_size/1024/1024,2) as BUF_POOL ,ROUND(@@innodb_log_buffer_size/1024/1024,2) as LOG_BUF,ROUND(@@binlog_cache_size/1024/1024,2) as BINLOG_CACHE,ROUND(@@tmp_table_size/1024/1024,2) as TMP_TABLE,ROUND(@@max_heap_table_size/1024/1024,2) as HEAP_TABLE_MEM;
4 系統設定
1 動態設定分配大頁記憶體:
echo 2290 > /proc/sys/vm/nr_hugepages
#此時系統記憶體狀態大頁記憶體已被使用.
[root@localhost ~]# free -m
total used free shared buff/cache available
Mem: 7821 4784 2305 15 730 2338
Swap: 8063 25 8038
#系統記憶體資訊 大頁記憶體裡面分配還未使用中
cat /proc/meminfo
PageTables: 4088 kB
HugePages_Total: 2290
HugePages_Free: 2290
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
2 透過 id mysql 獲取mysql所在的group id
[root@localhost ~]# id mysql
uid=27(mysql) gid=27(mysql) groups=27(mysql)
echo 27 > /proc/sys/vm/hugetlb_shm_group
[root@localhost ~]# sysctl -w vm.hugetlb_shm_group=27
vm.hugetlb_shm_group = 27
3 配置核心引數
設定核心引數kernel.shmmax和kernel.shmall
shmmax是最大的共享記憶體段的大小,單位是位元組,預設32M
shmall是共享記憶體的總大小,單位是頁
cat /etc/sysctl.conf
#-- kernel.shmmni這個核心引數用於設定系統範圍內共享記憶體段的最大數量。該引數的預設值是 4096.
#-- kernel.shmall 控制共享記憶體頁數
#-- kernel.shmmax 單個共享記憶體段的最大尺寸,設定為實體記憶體的 50%
#-- Increase total amount of shared memory. The value
#-- is the number of pages. At 4KB/page, 4194304 = 16GB.
#--echo 4194304 > /proc/sys/kernel/shmall
#--對於mysql的使用,最好是shmmax與shmall接近
#--7168MB
kernel.shmmax = 7516192768
kernel.shmall = 1835008
kernel.shmmni = 4096
vm.hugetlb_shm_group =27 #--MYSQL 所在的使用者組ID
vm.nr_hugepages=2290 ##--持久化大頁記憶體數量
4.修改ulimit
vim /etc/security/limits.conf
@mysql soft memlock unlimited
@mysql hard memlock unlimited
使用ulimit -l或設定/etc/security/limits.conf
5 配置 my.cnf
[mysqld]
large-pages
#Global Memon Set###### 4096MB, binlog_cache=16MB;logbuf=16MB
innodb_buffer_pool_size=4294967296
binlog_cache_size=16777216
innodb_log_buffer_size=16777216
innodb_buffer_pool_dump_at_shutdown = OFF
innodb_buffer_pool_load_at_startup = OFF
large-pages
#locked_in_memory=YES
#### Thread Memon Set
join_buffer_size=8388608
sort_buffer_size=8388608
read_buffer_size=8388608
read_rnd_buffer_size=8388608
tmp_table_size=16777216
#
bulk_insert_buffer_size=8388608
thread_cache_size = 32
thread_stack = 256K
(9) 啟動mysqld
6 觀察HugePages 使用情況
[root@localhost ~]# free -m
total used free shared buff/cache available
Mem: 7821 4784 2305 15 731 2338
Swap: 8063 25 8038
[root@localhost ~]# cat /proc/meminfo | grep Page
AnonPages: 66604 kB
PageTables: 4076 kB
AnonHugePages: 0 kB
HugePages_Total: 2290
HugePages_Free: 2290
HugePages_Rsvd: 0
HugePages_Surp: 0
[root@localhost ~]# service mysqld start
Redirecting to /bin/systemctl start mysqld.service
[root@localhost ~]# cat /proc/meminfo | grep Page
AnonPages: 406744 kB
PageTables: 5296 kB
AnonHugePages: 0 kB
HugePages_Total: 2290
HugePages_Free: 2217
HugePages_Rsvd: 2039
HugePages_Surp: 0
[root@localhost ~]# free -m
total used free shared buff/cache available
Mem: 7821 5117 1972 15 731 2005
Swap: 8063 25 8038
結果還是使用部分大頁記憶體 2290-2217 =146MB
傳統頁 5117-4784=333MB
MYSQL使用了333M記憶體,其中146MB使用了大頁記憶體,另外187MB使用傳統記憶體.
哎呀 這是為啥呢? 使用一部分大頁記憶體,又使用一部分傳統頁記憶體,
大頁記憶體還保留2039 大約 4078 這應該是INNODB BUF大小
這個是MYSQL 8.0.25 分支版本 PERCONA 8.0.25 錯誤日誌裡面沒有詳細的資訊.不知道是真使用還是假使用.
#後續查詢500條記錄 減少了3個大頁
[root@localhost ~]# cat /proc/meminfo | grep Page
AnonPages: 413920 kB
PageTables: 5380 kB
AnonHugePages: 0 kB
HugePages_Total: 2290
HugePages_Free: 2214
HugePages_Rsvd: 2036
HugePages_Surp: 0
#從這裡發現 大頁記憶體的保留頁確實給INNODB BUF裝備的,並且使用之.
#MYSQL 哪個部分不使用大頁記憶體的呢? 187MB
mysql> SELECT -> ROUND(@@key_buffer_size/1024/1024,2) as SHARE_KEY_BUF_MB, -> ROUND(@@innodb_buffer_pool_size/1024/1024,2) as SHARE_BUF_POOL , -> ROUND(@@innodb_log_buffer_size/1024/1024,2) as LOG_BUF, -> ROUND(@@tmp_table_size/1024/1024,2) as PRV_TMP_TABLE, -> ROUND(@@read_buffer_size/1024/1024,2) as PRV_READ_BUF, -> ROUND(@@sort_buffer_size/1024/1024,2) as PRV_SORT_BUF, -> ROUND(@@join_buffer_size/1024/1024,2) as PRV_JOIN_BUF, -> ROUND(@@read_rnd_buffer_size/1024/1024,2) as PRV_READ_RND_BUF, -> ROUND(@@binlog_cache_size/1024/1024,2) as PRV_BINLOG_CACHE, -> ROUND(@@thread_stack/1024/1024,2) as THREAD_STACK, -> (SELECT COUNT(host) FROM information_schema.processlist ) as connects;+------------------+----------------+---------+---------------+--------------+--------------+--------------+------------------+------------------+--------------+----------+| SHARE_KEY_BUF_MB | SHARE_BUF_POOL | LOG_BUF | PRV_TMP_TABLE | PRV_READ_BUF | PRV_SORT_BUF | PRV_JOIN_BUF | PRV_READ_RND_BUF | PRV_BINLOG_CACHE | THREAD_STACK | connects |+------------------+----------------+---------+---------------+--------------+--------------+--------------+------------------+------------------+--------------+----------+| 8.00 | 4096.00 | 16.00 | 16.00 | 8.00 | 8.00 | 8.00 | 8.00 | 16.00 | 0.25 | 4 |+------------------+----------------+---------+---------------+--------------+--------------+--------------+------------------+------------------+--------------+----------+1 row in set (0.00 sec)
#執行緒記憶體
64.25*4=257MB 大約哦
#mysql 5.73 查執行緒記憶體和共享記憶體
select VARIABLE_NAME, VARIABLE_VALUE,
concat(VARIABLE_VALUE/
1024/
1024,
' MB')
AS VARIABLE_VALUE_MB
from information_schema.SESSION_VARIABLES
where variable_name
in (
'innodb_buffer_pool_size',
'innodb_log_buffer_size',
'innodb_additional_mem_pool_size',
'key_buffer_size',
'query_cache_size');
select VARIABLE_NAME, VARIABLE_VALUE,
concat(VARIABLE_VALUE/
1024/
1024,
' MB')
AS VARIABLE_VALUE_MB
from information_schema.SESSION_VARIABLES
where variable_name
in(
'read_buffer_size',
'read_rnd_buffer_size',
'sort_buffer_size',
'join_buffer_size',
'binlog_cache_size',
'tmp_table_size');
#重複啟動測試
[root@localhost ~] # free -m
total used free shared buff/cache available
Mem: 7821 4771 2216 23 833 2350
Swap: 8063 25 8038
[root@localhost ~] # cat /proc/meminfo | grep Page
AnonPages: 53376 kB
PageTables: 3972 kB
AnonHugePages: 0 kB
HugePages_Total: 2290
HugePages_Free: 2290
HugePages_Rsvd: 0
HugePages_Surp: 0
[root@localhost ~] # service mysqld start
Redirecting to /bin/systemctl start mysqld.service
[root@localhost ~] # free -m
total used free shared buff/cache available
Mem: 7821 5104 1883 23 832 2017
Swap: 8063 25 8038
[root@localhost ~] # cat /proc/meminfo | grep Page
AnonPages: 393856 kB
PageTables: 5276 kB
AnonHugePages: 0 kB
HugePages_Total: 2290
HugePages_Free: 2217
HugePages_Rsvd: 2039
HugePages_Surp: 0
5104-4771=333MB
HTOP 1.2 顯示MYSQLD 佔用實體記憶體 RES項為 354MB
5119-4771=348
2290-1718=572*2=1144MB
#大查詢被超時被KILL 後
[root@localhost ~]# free -m
total used free shared buff/cache available
Mem: 7821 5119 1869 23 833 2002
Swap: 8063 25 8038
[root@localhost ~]# cat /proc/meminfo | grep Page
AnonPages: 405212 kB
PageTables: 5412 kB
AnonHugePages: 0 kB
HugePages_Total: 2290
HugePages_Free: 1718
HugePages_Rsvd: 1540
HugePages_Surp: 0
5119-4771=348
2290-1718=572*2=1144MB
證明 MYSQL繼續使用大頁記憶體 用在INNODB BUF上
#關閉大頁記憶體測試大表查詢
[root@localhost ~]# cat /proc/meminfo | grep Page
AnonPages: 54240 kB
PageTables: 4124 kB
AnonHugePages: 0 kB
HugePages_Total: 2290
HugePages_Free: 2290
HugePages_Rsvd: 0
HugePages_Surp: 0
[root@localhost ~]# cat /proc/meminfo | grep Page
AnonPages: 1530156 kB
PageTables: 7736 kB
AnonHugePages: 0 kB
HugePages_Total: 2290
HugePages_Free: 2290
HugePages_Rsvd: 0
HugePages_Surp: 0
#頁表增長
7736-4124=3612KB
開大頁記憶體
5412-3972=1440KB
OOM分數
大頁
[root@localhost etc]# sh look_mysql_oom.sh
Mysql Now OOM SCORE:
25
SCORE ADJ:
0
0
ADJ OOM
0
25
0
傳統頁
[root@localhost etc]# sh look_mysql_oom.sh
Mysql Now OOM SCORE:
29
SCORE ADJ:
0
0
ADJ OOM
0
29
0
生產環境的傳統頁
[fankun@_DC_CoreDB]sh look_mysql_oom.sh
Mysql Now OOM SCORE:
210
SCORE ADJ:
0
0
ADJ OOM
0
210
0
[fankun@paylabs_DC_CoreDB]free -m
total used free shared buff/cache available
Mem: 11852 8241 1207 40 2403 3256
Swap: 24571 32 24539
OOM得分也有所降低
最後總結 MYSQL 從5.7 就支援大頁記憶體,只支援共享記憶體單元,也就是全域性記憶體,執行緒記憶體不能使用大頁記憶體. MYSQL使用大頁記憶體是逐步使用的.不必ORACLE 有個PRE_SGA引數 先分配記憶體.ORACLE可以一下子就把大頁記憶體使用完.而不是
HugePages_Rsvd 保留多少.
另外PS庫的記憶體不太好估算.
另外CENTOS 7 TOP和HTOP RES顯示MYSQLD實際佔用實體記憶體, 這個應該是包含傳統頁和大頁兩部分.有些大佬說大頁記憶體不會被統計在程式使用中.
或許CENTOS 7以前的作業系統沒辦法統計吧.
最後我們還要估算出 最大執行緒X執行緒記憶體各項. 這些記憶體使用的4K頁的傳統記憶體. 傳統頁記憶體+大頁記憶體+系統自身佔用記憶體 不要超過90%或者80%報警線.避免運維瞎嗶嗶.
很多人說 MYSQL一般不開大頁記憶體
是的 此話非常政治正確, 一般嘛! 一般 也是隻那個年代下 記憶體+CPU+使用者併發執行緒量.
第一 MYSQL採用執行緒, 比ORACLE和PG採用程式 消耗系統頁表 非常小,不那麼明顯. 因為每個程式都要COPY一份共享記憶體,每份程式的共享記憶體都要佔用頁表, 而執行緒模型只有一份,執行緒之間是共享系統頁面.
第二 顯然當 INNODB BUF 達到一定程度後 它佔用的系統頁表也非常大的.
MYSQL 佔用了11812KB的系統頁表,對應記憶體 5884- 202 =5480 MB
11812/5480=2.155KB/MB 每兆記憶體要消耗2.15KB頁表
那麼140GB的INNODB BUF 呢?
308,940.8KB =301MB 加上強勁的CPU還是不那麼影響效能.
為此開大頁記憶體的MYSQL 還是一定程度有效率的提升, 沒有ORACLE和PG那麼立竿見影.
來自 “ ITPUB部落格 ” ,連結:https://blog.itpub.net/680758/viewspace-3007848/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 【大頁記憶體】Oracle資料庫配置大頁記憶體記憶體Oracle資料庫
- openGauss-大頁記憶體記憶體
- 探索Java記憶體模型Java記憶體模型
- windows10系統怎麼開啟記憶體鎖定頁Windows記憶體
- MySQL記憶體管理MySql記憶體
- Linux記憶體不夠了?看看如何開啟虛擬記憶體增加記憶體使用量Linux記憶體
- MySQL InnoDB記憶體配置MySql記憶體
- mysql最大表記憶體MySql記憶體
- Windows記憶體管理-分頁Windows記憶體
- ALLEGRO軟體開啟提示說沒有記憶體記憶體
- iOS記憶體深入探索之VM TrackeriOS記憶體
- C++記憶體模型實踐探索C++記憶體模型
- 探索JVM的垃圾回收(堆記憶體)JVM記憶體
- Spring Boot RCE到記憶體馬探索Spring Boot記憶體
- Linux 中的“大記憶體頁”(hugepage)是個什麼?Linux記憶體
- Linux 的記憶體分頁管理Linux記憶體
- Linux的記憶體分頁管理Linux記憶體
- golang 釋放記憶體機制的探索Golang記憶體
- iOS探索 記憶體對齊&malloc原始碼iOS記憶體原始碼
- Oracle在Linux下對記憶體大頁HugePage的實踐OracleLinux記憶體
- 遊戲記憶體對比普通記憶體區別 遊戲記憶體和普通記憶體相差大嗎?遊戲記憶體
- MySQL記憶體管理,記憶體分配器和作業系統MySql記憶體作業系統
- 告別記憶體OOM,解決MySQL記憶體增長問題記憶體OOMMySql
- 《深度探索c++記憶體模型》讀書筆記 (二)C++記憶體模型筆記
- Swift記憶體賦值探索一: 理解物件在記憶體中的儲存狀態Swift記憶體賦值物件
- MySQL入門--記憶體buffer poolMySql記憶體
- MYSQL的記憶體管理方法MySql記憶體
- 段頁式記憶體管理(轉載)記憶體
- optee記憶體管理和頁表建立記憶體
- 【記憶體管理】頁面分配機制記憶體
- dump檔案解析之探索.Net的記憶體記憶體
- 雲音樂 Android 記憶體監控探索篇Android記憶體
- 曹大談記憶體重排記憶體
- 電腦記憶體XMP是什麼意思?電腦記憶體XMP模式的作用與開啟教程記憶體模式
- Redis 記憶體優化神技,小記憶體儲存大資料Redis記憶體優化大資料
- linux記憶體管理(十)- 頁面回收(二)Linux記憶體
- linux記憶體管理(十一)- 頁面遷移Linux記憶體
- mysql記憶體引數分類大全MySql記憶體