1.生产环境中应该给Buffer Pool设置多少内存
在生产环境中,给Buffer Pool设置的内存不是占满整个机器的内存量,而是有一个合理、健康的比例,也就是给Buffer Pool 设置当前的机器内存的50%~60%左右。
比如当前有32G的机器,那么给Buffer 设置个20GB的内存,剩下的留给OS和其他人使用,就比较合理了。
2.buffer pool总大小=(chunk大小 * buffer pool数量)的2倍数
在确定了Buffer Pool的大小之后,就得考虑设置多少个Buffer Pool,以及chunk的大小了。
这里有个关键的公式: buffer pool总大小=(chunk大小 * buffer pool 数量)的倍数。
比如默认的chunk大小是128MB,那么此时如果机器的内存是32GB,给buffer pool总大小在20GB左右。
假设buffer pool的数量为16个,那么chunk大小 * buffer pool的数量 = 16 * 128MB = 2048MB,正好此时buffer pool总大小是20GB,那么buffer pool总大小就是2048MB的10倍,这就符合规则了。
此时也可以设置多一些buffer pool数量,比如设置32个buffer pool,那么此时buffer pool总大小(20GB)就是 (chunk大小128MB * 32个buffer pool) 的5倍,也是可以的。
3.阶段总结
当数据库在生产环境运行的时候,必须根据机器的内存设置合理的buffer pool的大小,然后设置buffer pool的数量,这样的话,就可以尽可能的保证数据库的高性能和高并发能力。
然后在线上运行的时候,buffer pool是有多个的,每个buffer pool里有多个chunk但是共用一套链表数据结构,然后执行crud的时候,就会不停的加载磁盘上的数据页到缓存页里来,然后会查询和更新缓存页里的数据,同时维护一系列的链表结构。
然后后台线程定时根据lru链表和flush链表,去把一批缓存页刷入磁盘释放掉这些缓存页,同时更新free链表。
如果执行crud的时候发现缓存页都满了,没法加载自己需要的数据页进缓存,此时就会把lru链表冷数据区域的缓存页刷入磁盘,然后加载自己需要的数据页进来。
以上就是整个buffer pool的结构设计以及工作原理。了解上述的原理机制,对于MySQL运行crud的时候,是如何在内存里查询和更新数据的,就彻底明白了。
4. SHOW ENGIN INNODB STATUS
当数据库启动之后,可以通过以下命令 “SHOW ENGINE INNODB STATUS” 去查看当前 innodb里的一些具体情况。
执行上述命令,可以看到如下一系列的东西:
Total large memory allocated 137363456
Dictionary memory allocated 386132
Buffer pool size 8192
Free buffers 6988
Database pages 1199
Old database pages 462
Modified db pages 0
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 0, not young 0
0.00 youngs/s, 0.00 non-youngs/s
Pages read 1057, created 142, written 155
0.00 reads/s, 0.00 creates/s, 0.00 writes/s
Buffer pool hit rate xxx/ 1000,young-making rate xxx / 1000 not xx / 1000
No buffer pool page gets since the last printout
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: 1199, unzip_LRU len: 0
I/O sum[0]:cur[0], unzip sum[0]:cur[0]
--------------
ROW OPERATIONS
--------------
0 queries inside InnoDB, 0 queries in queue
0 read views open inside InnoDB
Process ID=6428, Main thread ID=0000000000001A34 , state=sleeping
Number of rows inserted 0, updated 314, deleted 0, read 5335
0.00 inserts/s, 0.00 updates/s, 0.00 deletes/s, 0.00 reads/s
----------------------------
END OF INNODB MONITOR OUTPUT
============================
下面对上面的内容进行解释:
(1)Total large memory allocated,说的是buffer pool 最终的总大小是多少;
(2)Buffer Pool Size,是说buffer pool一共能容纳多少个缓存页;
(3)Free buffers,是说free链表中一共有多少个空闲的缓存页是可用的;
(4)Database pages 和 Old database pages,是说 lru 链表中一共有多少个缓存页,以及冷数据区域里的缓存页数量;
(5)Modified db pages,是说flush链表中的缓存页数量;
(6)Pending reads 和 Pending writes,等待从磁盘上加载进缓存页的数量,还有就是即将从lru链表中刷入磁盘的数量,即将从flush链表中刷入磁盘的数量;
(7)Pages made young 和 not young,是说已经lru冷数据区域里访问之后转移到热数据区域的缓存页的数量,以及在lru冷数据区域里1s内被访问了没进入热数据区域的缓存页的数量
(8)youngs/s 和 not youngs/s,这就是说每秒从冷数据区域进入热数据区域的缓存页的数量,以及每秒在冷数据区域里被访问了但是不能进入热数据区域的缓存页的数量;
(9)Pages read 1057,created 142,written 1550 ,00 reads/s,0.00 creates/s,0.00 writes/s,这里就是说已经读取、创建和写入了多少个缓存页,以及每秒钟读取、创建和写入的缓存页数量
(10)Buffer pool hit rate xxx/ 1000,这是说每1000次访问,有多少次是直接命中了buffer pool里的缓存的;
(11)young-making rate xxx / 1000 not xx / 1000,每1000次访问,有多少次访问让缓存页从冷数据区域移动到了热数据区域,以及没移动的缓存页数量
(12)LRU len:这是 lru 链表里的缓存页的数量;
(13)I/O sum:最近50s读取磁盘页的总数;
(14)I/O cur:现在正在读取磁盘页的数量。