Mysql
MySQL如何釋放SELECT使用的記憶體
我從大表中執行了一個
INSERT IGNORE
組合。SELECT
在SELECT
我用CTRL+C
.INSERT IGNORE INTO sid(sid) SELECT sid FROM data WHERE sid != "";
數據包含 6400 萬行。
的數據類型
sid
是VARCHAR(13)
。有 2820 萬條記錄匹配SELECT
(我後來執行它)。這導致大約 350MB 的數據需要SELECTed
和INSERTed
.是否可以釋放 MySQL 分配的記憶體?查詢已終止,不再需要該記憶體。為什麼它仍然揮之不去?
以下是一些配置細節:
max_allowed_packet=1024M # Memory Table max_heap_table_size=8192M
其他一切都是預設的。
MySQL 版本 5.5.25,使用 MyISAM
插入 ndbcluster 7.2.7
新數據庫配置
SharedGlobalMemory=256M DataMemory=2048M IndexMemory=512M
我的盒子執行1/3的SQL節點,管理節點。其他 2 台伺服器執行數據節點。
您可以執行
RESET QUERY CACHE
以消除查詢記憶體中收集的結果集。您還可以更積極地刪除查詢記憶體並重新創建不同的大小。例如,要將query_cache_size設置為 512M,請執行以下操作SET GLOBAL query_cache_size = 0; SELECT SLEEP(30); SET GLOBAL query_cache_size = 1024 * 1024 * 512;
不幸的是,你不能以同樣的方式釋放 MyISAM Key Buffer 和 InnoDB Buffer Pool。您必須在 /etc/my.cnf(或 Windows 的 my.ini)中調整它們的大小並重新啟動 mysql。
閱讀您的評論,我可以自信地說 MyISAM 不會記憶體數據頁。查詢記憶體是我能想到的唯一可以抓取並保存結果集的東西。如果您正在批量載入,應該有很多查詢記憶體失效正在發生。
我沒有通過集群認證,但我會說:由於您使用的是 MySQL 集群,您可能想嘗試關閉任何 mysqld 程序或讓集群斷開數據節點。此外,請注意數據在集群中跳躍的傳輸速度。
讓我們來複習…
- 16GB 記憶體。
- max_heap_table_size = 8G——這表示你讓每個程序創建一個記憶體表,它的大小只有 RAM 的一半!不安全。很可能導致交換。
- 查詢記憶體無關緊要,因為 SELECT 的結果集大於您為 QC 分配的 (16MB)。不要讓它變大,它不會有幫助。
- MyISAM 的 key_buffer_size 可以動態改變。但這無關緊要。您的 SELECT 將執行表掃描或索引掃描(如果
data
索引以 開頭sid
)。key_buffer 不用於表掃描。對於索引掃描,它需要足夠大,僅用於一個塊。更大也無濟於事。太大會擠滿 RAM。- 您還沒有說為 NDB 表進行了哪些分配
sid
。這很可能在 RAM 中。sid
此外,您還沒有說分佈在多少個節點上。- 您還沒有說 MyISAM 和 NDB 是否在同一個機器上執行。