使用MySQL中的缓冲池,低可用内存和许多NULL索引

时间:2019-01-18 10:11:37

标签: mysql innodb rds

我目前有一个(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是这么低。

Index list

这是RDS控制台最近2周的图表

RDS monitoring charts

在新的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;

查询顶部:

First part of the query result

在这两个捕获之间,所有page_type都是INDEX,所有page_state都是FILE_PAGE

Second part of the query result

3 个答案:

答案 0 :(得分:0)

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


@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 |

答案 1 :(得分:0)

有问题吗?当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等操作时,它们将被重用。

(注意:根据我的经验,很多答案都是“猜测”。)

答案 2 :(得分:0)

关于NULL表名,MySQL在这里记录:https://dev.mysql.com/doc/refman/8.0/en/innodb-information-schema-buffer-pool-tables.html

此查询提供包含系统的页面的大概数量 通过排除TABLE_NAME值为NULL或NULL的页面来数据 包括一个斜杠/或句号。在表格名称中,表示 用户定义的表。

也可以从Oracle编辑:(这很复杂)

当table_name为NULL时,表示这些页面可用于 分配。是免费的,或由系统使用。但总是可用 要求时。 NULL用于所有不是 索引页或免费。