我目前有一个(AWS)DB.M1.LARGE
实例(7.5GB,2vCPU,40GiB SSD,MySQL 5.6.34),只有4GB的空间在使用少于100个数据库。
出于某种原因,我正在经历 高InnoDB buffer usage
,接近 98% 和低Freeable Memory
,小于 600MB。
innodb_buffer_pool_size
的当前值为 5.7GB
经过一些互联网研究,我发现此查询列出了按大小分组和排序的所有索引。
select table_name as Table_Name, index_name as Index_Name,
count(*) as Page_Count, sum(data_size)/1024/1024 as Size_in_MB
from information_schema.innodb_buffer_page
group by table_name, index_name
order by Size_in_MB desc;
这是我的查询结果,我不完全明白为什么 NULL 表和 NULL 索引的空间使用量如此之大,以及这是否是一个问题以及Freeable Memory
如此之低的原因。
索引列表
这是 RDS 控制台最近 2 周的图表
RDS监控图表
新innodb_buffer_page查询后更新
根据比尔的建议,我运行这个新查询,结果如下:
select page_type, page_state, table_name, index_name,
count(*) as Page_Count, sum(data_size)/1024/1024 as Size_in_MB
from information_schema.innodb_buffer_page
group by page_type, page_state, table_name, index_name
order by Size_in_MB desc;
查询顶部:
查询结果的第一部分
在这两个捕获之间,所有page_type
都INDEX
,所有page_state
都FILE_PAGE
查询结果的第二部分
关于空table_names,MySQL在这里记录了这一点: https://dev.mysql.com/doc/refman/8.0/en/innodb-information-schema-buffer-pool-tables.html
此查询提供包含系统的页面的近似计数 数据,通过排除TABLE_NAME值为 NULL 或 包括斜杠/或句点。在表名中,指示 用户定义的表。
也从甲骨文编辑:(这很复杂)
当table_name为 NULL 时,表示这些页面可用于 分配。要么是免费的,要么被系统使用。但始终可用 当声称。NULL 用于所有不是 索引页或免费。
有问题吗? 当MySQL运行时,它通常会分配整个buffer_pool。
5.7 buffer_pool
x.x various other tables and caches
y.y code (OS, MySQL, etc)
0.6 "freeable" memory
---
7.5 Total
600MB由操作系统控制,而不是MySQL。 它很可能是缓存在 RAM 中的磁盘块。 如果它们与磁盘上的内容匹配(即,不是"脏的"),那么它们可以立即重用。
您在该表中显示的3.7GB可能是InnoDB控制下的免费块。 如果是这样,它们将在您执行INSERTs
等时重复使用。
(警告:根据我的经验,这个答案的大部分都是"猜测"。
https://dev.mysql.com/doc/refman/8.0/en/innodb-buffer-page-table.html 说:
TABLE_NAME
页面所属表的名称。此栏目适用 仅适用于PAGE_TYPE值为 INDEX 的页面。
这同样适用于INDEX_NAME列。
请尝试此查询以获取详细信息:
select page_type, page_state, table_name, index_name,
count(*) as Page_Count, sum(data_size)/1024/1024 as Size_in_MB
from information_schema.innodb_buffer_page
group by page_type, page_state, table_name, index_name
order by Size_in_MB desc;
我在您的屏幕截图中看到,许多 INDEX 类型的缓冲池页面仍然显示表和索引名称的 NULL。
我不确定这意味着什么。我查看了MySQL源代码,如果无法在InnoDB数据字典中找到索引,似乎可以将这些值保留为NULL。但我不确定这是怎么发生的。
https://github.com/mysql/mysql-server/blob/5.6/storage/innobase/handler/i_s.cc#L5007
G-K@C的重新评论:
是的,你是对的,我测试过,我看到了不同。我想差异显示了页面的填充率。
select page_type, page_state, table_name, index_name,
count(*) as Page_Count,
count(*) * @@innodb_page_size /1024/1024 AS Total_Page_Size_in_MB,
sum(data_size)/1024/1024 as Size_in_MB
from information_schema.innodb_buffer_page
group by page_type, page_state, table_name, index_name
order by Size_in_MB desc
+-------------------+------------+--------------+------------+------------+-----------------------+-------------+
| page_type | page_state | table_name | index_name | Page_Count | Total_Page_Size_in_MB | Size_in_MB |
+-------------------+------------+--------------+------------+------------+-----------------------+-------------+
| INDEX | FILE_PAGE | `test`.`foo` | PRIMARY | 1940 | 30.31250000 | 27.87315369 |