开发者学堂课程【云数据库优化经典案例:mem 100%场景优化】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/67/detail/1167
mem 100%场景优化
内存三个组成部分的最佳实践
最后一个案例是非常常见的内存问题,因为内存使用完会发生 OM, 所以要关注内存的使用。但一些情况下,用户会提出疑问,数据库90%或者85%、88%、91%、92%是不是正常的,大部分情况是正常的,因为你的数据总容量肯定是大于内存的容量,比如你的数据是200G,活跃的数据有50 G,你的内存是16个 G,那肯定内存会到80%、90%,因为有个 datapete 参数是可以配置的,默认是75%,当超过75%后内存会把章页内存刷到磁盘里去,所以这个时候内存使用率到80%、90%基本上是正常的,不要出现99%、95%否则会很危险,所以维持在90%都是正常的。
内存它主要包括三大部分,第一部分 Buffer pool size, 第二部分是数据字典,第三部分是每个线程所消耗的内存
1、Buffer pool size
(1)创建合适的索引,避免大量的数据扫描
(2)去除不必要的索引,降低内存的消耗;
Buffer pool size它是数据索引主要在这里消耗,因为所有的插入、更新、删除数据,它都会把对应的数据页读到内存里面,同时去更新相应的索引页,此时大部分的 Buffer pool size 是被数据和索引占据,比如 sico 没有全盘扫描,扫描大量无效数据,因为要找到这行数据,但是你没有索引,它必须把这个索引的数据页读到内存里,这个时候 Buffer pool size 就会被无效的数据页所占满,此时要创建合适的索引,同时如果表上有不必要的索引 ,因为更新插入的时候要去更新索引,必须要把这个索引读到内存里去,这个时候 Buffer pool size 的使用率就会很差,所以优化原理都是适合在内存上优化。
2、Thread cost memory
(1)创建合适的索引避免排序;
(2)只查询应用所需要的数据
第二个是每个线程所需要的内存,比如 sockdack、tablesize 这些都是每个线程在连接到数据库后它要初始化分配的,这个时候如果每个线程发放过来的查询没有合适的索引,要排序的,或者要查询的数据很多的,这个时候每个线程所消耗的内存也是非常大的,所以线程要控制每个线程消耗的内存数。
3、Dictionary memory
(1)不要过度分表;
第三个是不要过度分表,有个用户一个实例创建了3万张表,因为 Dictionary memory 最大内存试过一占到 Buffer pool 一半的,可以想象3万张表,如果每张表换一张所对应的数据字典它消耗的内存也是好几个 G,一定要注意不要过度分表,分表是因为要降低 detail 的实践,要合理设计表结构。这是内存最佳实践上的总结。前面讲了这么多问题包括索引优化、锁、延迟、磁盘、CPU、IOPS、连接数等这些,在日后工作中要从容慢慢去做优化,很多工作要提前做好,帮助用户更好的去使用数据库。