Mysql
刪除記憶體表後 MySQL 不釋放記憶體
在創建了幾個記憶體引擎表並刪除它們之後,
mysqld
並沒有釋放所有相應的記憶體。以下是重現該問題的確切步驟。
htop
使用(RES 列)觀察記憶體使用情況。
- 禁用交換
sudo swapoff -a
- 啟動記憶體限制為 4GB 的 mysql
docker run -d -m 4g --shm-size 4g --name mysql_test \ -e MYSQL_ALLOW_EMPTY_PASSWORD=yes mysql:5.7.25 docker exec -it mysql_test bash # test to allocate 3G memory in /dev/shm dd if=/dev/zero of=/dev/shm/dummy bs=1M count=3K rm /dev/shm/dummy # create a named pipe for loading data mkfifo /var/lib/mysql-files/tmp.pipe # launch mysql client mysql -uroot
- 創建數據庫
create database if not exists mem; use mem; -- allow memory table of max size 4GB for this session set max_heap_table_size = 1024 * 1024 * 1024 * 4;
mysqld記憶體使用:193M
- 創建表並載入數據
在 mysql 外殼中:
create temporary table memory_tbl ( idx varchar(1000) ) engine=memory; load data infile '/var/lib/mysql-files/tmp.pipe' into table memory_tbl (idx);
在另一個終端:
docker exec -it mysql_test sh -c 'yes 0 | head -1048576 > /var/lib/mysql-files/tmp.pipe'
mysqld記憶體使用:1210M
回到 mysql shell 複製表:
create temporary table memory_tbl2 like memory_tbl; insert into memory_tbl2 select * from memory_tbl;
mysqld記憶體使用量:2227M
再次復製表格:
create temporary table memory_tbl3 like memory_tbl; insert into memory_tbl3 select * from memory_tbl;
mysqld記憶體使用量:3243M
- 刪除表
drop table memory_tbl;
mysqld記憶體使用:3244M
drop table memory_tbl2;
mysqld記憶體使用:3244M
drop table memory_tbl3;
mysqld記憶體使用:2302M
- 嘗試分配記憶體
在另一個外殼中:
docker exec -it mysql_test bash # allocate 1.5G memory dd if=/dev/zero of=/dev/shm/dummy bs=1M count=1536 rm /dev/shm/dummy # allocate 2G memory dd if=/dev/zero of=/dev/shm/dummy bs=1M count=2K # error occurs # dd: error writing '/dev/shm/dummy': Cannot allocate memory rm /dev/shm/dummy
我想知道這是否是 MySQL 伺服器的錯誤。否則,有什麼方法可以讓 MySQL 在不重啟的情況下釋放記憶體
mysqld
?測試環境:
- Ubuntu 18.04.1 LTS
- 核心 4.15.0-34-generic
- Docker 18.06.1-ce
- mysql-5.7.25
- glibc 2.24
根據 MariaDB 伺服器錯誤中的建議Memory not freeed on memory table drop,用 jemalloc 替換預設 glibc 可以解決問題。
以下步驟顯示瞭如何使用 jemalloc 啟動 mysqld:
docker run -it -m 4g --shm-size 4g --name mysql_test \ -e MYSQL_ALLOW_EMPTY_PASSWORD=yes mysql:5.7.25 bash apt-get update apt-get install -y libjemalloc-dev # adhoc preload jemalloc for ease of testing # updating /etc/mysql/my.cnf is preferred for permanent setting LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.1 docker-entrypoint.sh mysqld
然後我們可以在另一個 shell 中從第 3 步開始進行測試。請注意,
mysqld
每個 drop table 語句的記憶體使用量下降約 1G。最後,記憶體使用量下降到與初始階段相似的水平,並且/dev/shm
可以在其中創建 3G 文件。更新:
libjemalloc1
在這種情況下 ,實際需要的庫是。libjemalloc-dev
包含libjemalloc1
作為依賴項,這就是它起作用的原因,但代價是安裝了一堆我們不需要的文件。感謝Michael - sqlbot指出這一點。