在 MySQL 中使用缓冲池的低可用内存和许多 NULL 索引
Low Freeable memory and many NULL index using buffer pool in MySQL
我目前有一个 (AWS) DB.M1.LARGE
实例(7.5GB,2vCPU,40GiB SSD,MySQL 5.6.34)只有 4GB space 在使用中,少于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;
这是我的查询结果,我不完全理解为什么有那么多 space 用于 NULL 表和 NULL 索引,如果这是一个问题以及为什么Freeable Memory
这么低
Index list
这是最近 2 周来自 RDS 控制台的图表
RDS monitoring charts
在新 innodb_buffer_page 查询后更新
根据 Bill 的建议,我 运行 这个新查询,结果如下:
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;
查询顶部:
First part of the query result
在这两次捕获之间,所有 page_type
都是 INDEX
,所有 page_state
都是 FILE_PAGE
Second part of the query result
https://dev.mysql.com/doc/refman/8.0/en/innodb-buffer-page-table.html 说:
TABLE_NAME
The name of the table the page belongs to. This column is applicable
only to pages with a PAGE_TYPE value of 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 的缓冲池页面仍然显示 table 和索引名称为 NULL。
我不确定这是什么意思。我查看了 MySQL 来源,如果在 InnoDB 数据字典中找不到索引,它似乎可以将这些值保留为 NULL。但我不确定那是怎么发生的。
https://github.com/mysql/mysql-server/blob/5.6/storage/innobase/handler/i_s.cc#L5007
@C G-K 的回复:
是的,你是对的,我测试过,我看到了不同。我想差异显示了页面的填充率。
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 |
有问题吗?当 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 由 OS 控制,而不是 MySQL。它很可能是缓存在 RAM 中的磁盘块。如果它们匹配磁盘上的内容(即,不是 "dirty"),那么它们可以立即重复使用。
您在 table 中显示的 3.7GB 可能 是 InnoDB 控制下的空闲块。如果是这样,它们将在您执行 INSERTs
等操作时重复使用
(注意:根据我的经验,这个答案的大部分内容是 'guessing'。)
关于 NULL table_names,MySQL 在此处记录:https://dev.mysql.com/doc/refman/8.0/en/innodb-information-schema-buffer-pool-tables.html
This query provides an approximate count of pages that contain system
data by excluding pages where the TABLE_NAME value is either NULL or
includes a slash / or period . in the table name, which indicates a
user-defined table.
也从 Oracle 编辑:(这很复杂)
When table_name is NULL, it means that those pages are available for
allocation. Are either free, or used by system. But always available
when claimed. NULL is used for all buffer pool blocks that are not
index pages or free.
我目前有一个 (AWS) DB.M1.LARGE
实例(7.5GB,2vCPU,40GiB SSD,MySQL 5.6.34)只有 4GB space 在使用中,少于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;
这是我的查询结果,我不完全理解为什么有那么多 space 用于 NULL 表和 NULL 索引,如果这是一个问题以及为什么Freeable Memory
这么低
Index list
这是最近 2 周来自 RDS 控制台的图表
RDS monitoring charts
在新 innodb_buffer_page 查询后更新
根据 Bill 的建议,我 运行 这个新查询,结果如下:
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;
查询顶部:
First part of the query result
在这两次捕获之间,所有 page_type
都是 INDEX
,所有 page_state
都是 FILE_PAGE
Second part of the query result
https://dev.mysql.com/doc/refman/8.0/en/innodb-buffer-page-table.html 说:
TABLE_NAME
The name of the table the page belongs to. This column is applicable only to pages with a PAGE_TYPE value of 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 的缓冲池页面仍然显示 table 和索引名称为 NULL。
我不确定这是什么意思。我查看了 MySQL 来源,如果在 InnoDB 数据字典中找不到索引,它似乎可以将这些值保留为 NULL。但我不确定那是怎么发生的。
https://github.com/mysql/mysql-server/blob/5.6/storage/innobase/handler/i_s.cc#L5007
@C G-K 的回复:
是的,你是对的,我测试过,我看到了不同。我想差异显示了页面的填充率。
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 |
有问题吗?当 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 由 OS 控制,而不是 MySQL。它很可能是缓存在 RAM 中的磁盘块。如果它们匹配磁盘上的内容(即,不是 "dirty"),那么它们可以立即重复使用。
您在 table 中显示的 3.7GB 可能 是 InnoDB 控制下的空闲块。如果是这样,它们将在您执行 INSERTs
等操作时重复使用
(注意:根据我的经验,这个答案的大部分内容是 'guessing'。)
关于 NULL table_names,MySQL 在此处记录:https://dev.mysql.com/doc/refman/8.0/en/innodb-information-schema-buffer-pool-tables.html
This query provides an approximate count of pages that contain system data by excluding pages where the TABLE_NAME value is either NULL or includes a slash / or period . in the table name, which indicates a user-defined table.
也从 Oracle 编辑:(这很复杂)
When table_name is NULL, it means that those pages are available for allocation. Are either free, or used by system. But always available when claimed. NULL is used for all buffer pool blocks that are not index pages or free.