本文通过笔者经历的一个真实案例来介绍一个MySQL中的重要参数innodb_buffer_pool_size,希望能给大家带来些许收获,当遇到类似性能问题时可以多一种思考方式。

图片拍摄于大唐不夜城


问题背景

有个广西的客户,之前系统一直用的很流畅,最近反馈系统响应极慢,卡顿严重,希望我们尽快解决。

收到反馈以后我立马去查看服务器各项指标,微服务所在机器各项指标正常,但是数据库服务器已不堪重负,看一下top的输出:

数据库服务器的硬件配置为8核16G内存,最繁忙的时候系统负载已经达到了16,cpu利用率700%,可想而知系统当前服务质量有多糟糕。


自我思考

使用量突然上来了吗?

观察了使用人数的趋势图,是多了一些,但还在同一个数量级(toB的客户,一般都在一个可控的量)。

数据量突然上来了吗?

确实是多了一些,有几张表,之前一年多才30多万数据,最近一个月已经长到1百万级别,到底是业务上量了还是程序bug呢,还需要持续排查。

慢查多了吗?

是的,慢查很多,而且最近几天猛涨,怀疑是不是增加了新功能,根据慢SQL去查业务代码,确实增加了七八张报表,我尝试点了一下,确实很慢,高峰期前端几乎全是超时,太慢了。

toB系统业务复杂,OLTP和OLAP都兼备,MySQL应付OLTP很擅长,但是OLAP就有点捉襟见肘了,也许有人会说为什么不用大数据的那一套东西来解决OLAP的问题呢?

成本、成本、成本太高了,toB业务,大多数都部署在客户的自建机房中,最好能少引入或者不引入其他组件,最大限度降低各项成本,包括和客户的沟通成本,客户要付出的财力成本,后期的运维成本等等。


解决过程

铺垫了这么多,具体怎么解决呢?短期来看就是先采用垂直扩容的方式抵御一波,俗称升配置,长期来看的话需要梳理&优化慢查,采用读写分离等手段逐步优化。

话不多说,先联系客户升配置,8核16G变16核32G,希望第二天早高峰能给客户带来丝滑般的用户体验。

第二天我盯着数据库观察负载,确实好了一些,但终归还是凉凉了,只是来的比以往稍晚一些,一时间不知道怎么处理了,客户严重质疑我们的能力。

问题究竟出在哪里了呢?现在这个硬件配置已经很强悍了,感觉完全没有发挥出来,cpu最高才跑到800%。过往的工作中,有专门的DBA负责数据库的运维,遇到过一次升配的场景,升完以后有很明显的性能提升,那感觉刷刷的。

穷途末路的时候我拨通了老板的电话,和他沟通了目前的境遇,希望老同志能指点迷津,快速帮我捅破窗户纸,他有句话提醒了我,“为什么浙江客户的数据库没这个问题呢,配置一样,浙江客户的业务量还要更大一些,区别就是他们用的阿里云RDS,广西客户是自建MySQL,会不会有什么数据库的参数咱没有意识到”。

跟他聊完我立马去对比了阿里云RDS和自建MySQL的相关参数,有一个值非常可疑“innodb_buffer_pool_size“,浙江客户RDS中这个值为12G,而广西客户自建MySQL这个值才为128M,相差接近百倍,好奇心驱使着我快速一探究竟。

看下官方文档对于innodb_buffer_pool的解释:

  • The buffer pool is a memory area that holds cached data for tables, indexes, and other auxiliary buffers. For efficiency of high-volume read operations, the buffer pool is divided into pages that can potentially hold multiple rows. For efficiency of cache management, the buffer pool is implemented as a linked list of pages; data that is rarely used is aged out of the cache, using a variation of the LRU algorithm. For more information, see Section 15.5.1, “Buffer Pool”. InnoDBInnoDB

    The size of the buffer pool is important for system performance:

    • InnoDB allocates memory for the entire buffer pool at server startup, using operations. The innodb_buffer_pool_size system variable defines the buffer pool size. Typically, a recommended innodb_buffer_pool_size value is 50 to 75 percent of system memoryinnodb_buffer_pool_size can be configured dynamically, while the server is running. For more information, see Section 15.8.3.1, “Configuring InnoDB Buffer Pool Size”. malloc()

    • On systems with a large amount of memory, you can improve concurrency by dividing the buffer pool into multiple buffer pool instances. The innodb_buffer_pool_instances system variable defines the number of buffer pool instances.

    • A buffer pool that is too small may cause excessive churning as pages are flushed from the buffer pool only to be required again a short time later.

    • A buffer pool that is too large may cause swapping due to competition for memory.

提取出这么几个重要信息:

1.缓冲池是保存表、索引和其他辅助缓冲区的缓存数据的内存区域;

2.缓冲池的大小对MySQL的性能很重要;

3.推荐的大小是物理内存的50%到75%;

4.inndb_buffer_pool_size可以在MySQL运行时动态调整;

5."Configuring InnoDB Buffer Pool Size"这个配置手册中提到默认值为128兆。

再看看《MySQL技术内幕InnoDB存储引擎》这本书中关于缓冲池的介绍:

缓冲池简单来说就是一块内存区域,通过内存的速度来弥补磁盘速度较慢对数据库性能的影响。在数据库中进行读取页的操作,首先将从磁盘读到的页放在缓冲池中,这个过程称为将页“FIX“到缓冲池中。下一次再读相同的页时,首先判断该页是否在缓冲池中,若在缓冲池中,称该页在缓冲池中被命中,直接读取该页,否则,读取磁盘上的页。

做了一定的了解之后我决定动手去改一下这个值看看效果,之前提到客户已经把数据库服务器的配置扩到了16核32G,那我就把inndb_buffer_pool_size设置为32G*0.75=24G。

--注意:

--1.这里的单位是字节

--2.这是动态调整,长远来看这个配置应该放到配置文件中,防止重启丢失

set global innodb_buffer_pool_size = 25769803776

调完以后效果显著,我拿了几个耗时严重的SQL做了对比,查询时间减少一半以上,慢查数量明显下降,看看此时的数据库负载情况

调整缓冲池大小之前cpu和负载都很高,但是内存占用很低,调整完以后cpu和负载明显下降,内存占用高了,这正是我们所期待的效果。

看看客户给我们的反馈


总结

问题暂时告一段落,虽说没有100%的解决问题,但也解决了70%-80%的问题,那些剩余的20%-30%需要开发人员去优化代码,硬件扩容并不是银弹,庆幸的是,经过这次调整应该能给开发人员争取一些时间来优化代码。

另一方面也折射出自己对数据库的认识只是停留在开发视角的一些知识,比如SQL优化、索引的匹配、慢查优化等等,对于底层原理性的东西欠缺太多,有人会说这类东西应该交给DBA负责,这么说倒也没什么问题,但现实情况是有些团队就是没有配备DBA的,只能开发顶,再者说,作为开发而言,对于这类知识不一定要熟练掌握,但起码应该有一些初步的认识。


推荐阅读

MySQL如何使用内存 (oracle.com)

https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/memory-use.html

调整innodb_buffer_pool_size

Configuring InnoDB Buffer Pool Size (oracle.com)

终于做了一把MySQL调参boy的更多相关文章

  1. Python中Gradient Boosting Machine(GBM)调参方法详解

    原文地址:Complete Guide to Parameter Tuning in Gradient Boosting (GBM) in Python by Aarshay Jain 原文翻译与校对 ...

  2. hyperopt自动调参

    hyperopt自动调参 在传统机器学习和深度学习领域经常需要调参,调参有些是通过通过对数据和算法的理解进行的,这当然是上上策,但还有相当一部分属于"黑盒" hyperopt可以帮 ...

  3. GBDT调参总结

    一.GBDT类库弱学习器参数 二.回归 数据集:已知用户的30个特征,预测用户的信用值 from sklearn.ensemble import GradientBoostingRegressor f ...

  4. [调参]CV炼丹技巧/经验

    转自:https://www.zhihu.com/question/25097993 我和@杨军类似, 也是半路出家. 现在的工作内容主要就是使用CNN做CV任务. 干调参这种活也有两年时间了. 我的 ...

  5. scikit-learn 梯度提升树(GBDT)调参小结

    在梯度提升树(GBDT)原理小结中,我们对GBDT的原理做了总结,本文我们就从scikit-learn里GBDT的类库使用方法作一个总结,主要会关注调参中的一些要点. 1. scikit-learn ...

  6. gbdt调参的小结

    关键部分转自http://www.cnblogs.com/pinard/p/6143927.html 第一次知道网格搜索这个方法,不知道在工业中是不是用这种方式 1.首先从步长和迭代次数入手,选择一个 ...

  7. scikit-learn 梯度提升树(GBDT)调参笔记

    在梯度提升树(GBDT)原理小结中,我们对GBDT的原理做了总结,本文我们就从scikit-learn里GBDT的类库使用方法作一个总结,主要会关注调参中的一些要点. 1. scikit-learn ...

  8. scikit-learn随机森林调参小结

    在Bagging与随机森林算法原理小结中,我们对随机森林(Random Forest, 以下简称RF)的原理做了总结.本文就从实践的角度对RF做一个总结.重点讲述scikit-learn中RF的调参注 ...

  9. word2vec参数调整 及lda调参

     一.word2vec调参   ./word2vec -train resultbig.txt -output vectors.bin -cbow 0 -size 200 -window 5 -neg ...

随机推荐

  1. 『学了就忘』Linux文件系统管理 — 64、磁盘配额的配置步骤

    目录 1.手工建立一个5GB的分区 2.建立需要做限制的三个用户 3.在分区上开启磁盘配额功能 4.建立磁盘配额的配置文件 5.开始设置用户和组的配额限制 6.启动和关闭配额 7.磁盘配额的查询 8. ...

  2. Java中static关键字声明的静态内部类与非静态内部类的区别

    (1)内部静态类不需要有指向外部类的引用.但非静态内部类需要持有对外部类的引用.(2)非静态内部类能够访问外部类的静态和非静态成员.静态类不能访问外部类的非静态成员.他只能访问外部类的静态成员.(3) ...

  3. A Child's History of England.44

    At this period of his reign, when his troubles seemed so few and his prospects so bright, those dome ...

  4. CSS基础语法(一)

    目录 CSS基础语法(一) 一.CSS简介 1.CSS语法规范 2.CSS代码风格 二.CSS基础选择器 1.标签选择器 2.类选择器 3.id选择器 4.通配符选择器 5.总结 三.CSS字体属性 ...

  5. dbeaver可视化工具-连接clickhouse

    下载地址 https://dbeaver.io/download/ 本次下载的是ZIP包,这种方式方便移动/备份软件 此软件可连接多种数据库,这里是连接clickhouse 新建连接 点击 上面的倒三 ...

  6. Playing with Destructors in C++

    Predict the output of the below code snippet. 1 #include <iostream> 2 using namespace std; 3 4 ...

  7. Oracle删除重复数据记录

    删除重复记录,利用ROWID 和MIN(或MAX)函数, ROWID在整个数据库中是唯一的,由Oracle自己产生和维护,并唯一标识一行(无论该表中是否有主键和唯一性约束),ROWID确定了每条记录在 ...

  8. Linux 下使用rtcwake实现定时休眠和唤醒设备

    查看是否安装rtcwake whereis rtcwake rtcwake: /usr/sbin/rtcwake /usr/share/man/man8/rtcwake.8.gz 查看rtcwake帮 ...

  9. 记一次ssh连接慢

    2020-03-28日机房搬迁完后,发现有一台60服务器ssh连接特别慢,但是其他服务器正常; 下面是解决过程: vim /etc/ssh/sshd_config       (编辑配置文件) 查找F ...

  10. 有了代码变更分解提交工具SmartCommit,再也不担心复合提交了

    摘要:文将介绍一个代码提交辅助工具SmartCommit,其主要功能是通过杂糅变更分解算法自动生成分组提交方案,接受开发者的反馈和交互式调整,渐进式地引导和辅助开发者做出符合最佳实践的原子提交. 本文 ...