0%

使用MySQL的性能问题和紧急处理手段

短连接风暴问题#

解决方案:#
  • 调高max_connections
    让更多的连接都可以进来,那么系统的负载可能会进一步加大,大量的资源耗费在权限验证等逻辑
    上,结果可能是适得其反,已经连接的线程拿不到CPU资源去执行业务的SQL请求。
  • 先处理掉那些占着连接但是不工作的线程
    • 设置wait_timeout参数表示的是,一个线程空闲wait_timeout这么多秒之后,就会被MySQL直接断开连接。
    • 从数据库端主动断开连接可能是有损的,尤其是有的应用端收到这个错误后,不重新连接,而是
      直接用这个已经不能用的句柄重试查询。这会导致从应用端看上去,“MySQL一直没恢复”。
  • 减少连接过程的消耗
    让数据库跳过权限验证阶段
    这种方法风险极高,是我特别不建议使用的方案。尤其你的库外网可访问的话,就更不能这么做了。

慢查询性能问题#

索引没有设计好#
  • 解决方案:通过紧急创建索引来解决.
    假设你现在的服务是一主一备,主库A、备库B,这个方案的大致流程是这样的:
    I. 在备库B上执行 set sql_log_bin=off,也就是不写binlog,然后执行alter table 语句加上索
    引;
    II. 执行主备切换;
    III. 这时候主库是B,备库是A。在A上执行 set sql_log_bin=off,然后执行alter table 语句加上
    索引。
SQL语句没写好#
  • 解决方案:MySQL 5.7提供了query_rewrite功能,可以把输入的一种语句改写成另外一种模式。
MySQL选错了索引#
  • 解决方案:给这个语句加上force index
避免1和2两个问题的预案#
  1. 上线前,在测试环境,把慢查询日志(slow log)打开,并且把long_query_time设置成0,
    确保每个语句都会被记录入慢查询日志;
  2. 在测试表里插入模拟线上的数据,做一遍回归测试;
  3. 观察慢查询日志里每类语句的输出,特别留意Rows_examined字段是否与预期一致。

QPS突增问题#

  • 解决的方案
    • 如果能够确定业务方会下掉这个功能,只是时间上没那么快,那么就可以从数据库端直接把白名单去掉
    • 可以用管理员账号把这个用户删掉,然后断开现有连接。 这样,这个新功能的连接不成功,由它引发的QPS就会变成0。
    • 把压力最大的SQL语句直接重写成”select 1”返回。
      这个操作的风险很高, 所有选项里优先级最低的一个方案。

总结:#

要避免一些低效的方法,比如避免大量地使用短连接
连接异常断开是常有的事,代码里要有正确地重连并重试的机制。

参考:#

  1. 《MySQL实战45讲》 MySQL有哪些“饮鸩止渴”提高性能的方法? 丁奇