18910140161

记录一次奇葩的mysql性能调优经历

顺晟科技

2021-06-16 10:34:59

309

今天在写Koa2程序的时候,不小心扫了一眼日志,发现一个简单的保存表单的API居然平均用了900ms,900ms!这个需求的正常时间消耗应该再除以10

SQL概要文件分析

首先,我们需要知道sql语句的哪个阶段比较慢。mysql提供了配置文件工具来帮助我们进行性能分析:

MYSQL集分析=1

MYSQL插入t_test_table值(' hello ')

MYSQL显示查询1的配置文件

输入上述sql语句后,您会发现主要的时间消耗是在一个称为查询结束的阶段。本文对此阶段描述如下

在谷歌上得到答案,在mysql配置文件中的my.conf上加一句innodb _ flush _ log _ at _ Trx _ commit=0。经过验证,问题成功解决,速度明显提高(以上改动也起到了插入操作的作用)。同时留下一个问题:查询结束是什么状态,为什么要这么久,为什么添加innodb _ flush _ log _ at _ Trx _ commit=0后性能提升这么多?

查询结束是什么状态?官方的mysql文档解释说:这种状态发生在处理查询之后,但是在冻结项目状态之前。我的理解是语句执行时的状态,但是还有一些后续工作没有完成。

那么释放物品是什么状态呢?线程已经执行了一个命令。在这种状态下,一些项目的释放涉及到查询缓存。这个状态后面通常是clean u p,就是释放查询缓存中的空间(因为是更新操作,相应缓存中的记录无效,所以需要这个步骤进行处理)。

innodb_flush_log_at_trx_commit的默认值为1,此时的行为是:每次事务提交时,将日志缓冲区写入日志文件,并对日志文件执行刷新到磁盘操作。日志缓冲区:的功能允许事务在执行完成后向磁盘写入日志(事务需要维护一个日志),时间应该主要花在磁盘IO上?

将innodb_flush_log_at_trx_commit的值更改为0后,行为如下:如果innodb _ flush _ log _ at _ Trx _ commit的值为0,则每秒将日志缓冲区写入日志文件一次,并对日志文件执行刷新到磁盘操作,但在事务提交时不会执行任何操作。可以看出,更改为0后,每次提交应该执行的操作更改为每秒一次,大大节省了时间。

将innodb_flush_log_at_trx_commit的值设置为0会产生副作用:任何服务器端mysql程序的崩溃都会导致最后一秒的事务丢失(在到达日志文件之前)。但是,考虑到该应用对交易没有如此严格的要求,这是可以接受的。

但是这个参数太暴力,可能会掉号。不建议这么做,慢的SQL可能是IO压力太大。让我们用一些工具来检查机器的负载

检查硬盘负载

Iostat命令可以查看磁盘负载并输入命令

$ sudo iostat -d -x -k 1 40

%util字段指示一秒钟内用于I/O操作的时间百分比,即io消耗的cpu百分比。如果%util接近,说明生成的I/O请求过多,I/O系统已经满负荷,磁盘可能出现瓶颈。

检查进程IO占用率

那么怎么知道哪个程序占用的IO多呢?你对Linux下的iotop命令包很满意,可以用yum安装。在机器上运行iotop的结果如下图所示

结果表明,读IO过程主要是一个rsync脚本,写IO过程是一堆爬虫和橡皮筋

解决办法

因此.最后让另一个爬虫慢慢爬,insert语句的速度有了明显的提高

相关文章
我们已经准备好了,你呢?
2024我们与您携手共赢,为您的企业形象保驾护航