短连接风暴问题#
解决方案:#
- 调高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两个问题的预案#
- 上线前,在测试环境,把慢查询日志(slow log)打开,并且把long_query_time设置成0,
确保每个语句都会被记录入慢查询日志; - 在测试表里插入模拟线上的数据,做一遍回归测试;
- 观察慢查询日志里每类语句的输出,特别留意Rows_examined字段是否与预期一致。
QPS突增问题#
- 解决的方案
- 如果能够确定业务方会下掉这个功能,只是时间上没那么快,那么就可以从数据库端直接把白名单去掉。
- 可以用管理员账号把这个用户删掉,然后断开现有连接。 这样,这个新功能的连接不成功,由它引发的QPS就会变成0。
- 把压力最大的SQL语句直接重写成”select 1”返回。
这个操作的风险很高, 所有选项里优先级最低的一个方案。
总结:#
要避免一些低效的方法,比如避免大量地使用短连接。
连接异常断开是常有的事,代码里要有正确地重连并重试的机制。
参考:#
- 《MySQL实战45讲》 MySQL有哪些“饮鸩止渴”提高性能的方法? 丁奇