mysql提高_mysql深入系列-mysql提高性能的方法(临时方案)

背景

业务高峰期,生产环境的mysql压力太大,没法正常响应,需要短时间内,临时地提示一些性能。

问题:

短连接风暴

1.正常的短连接模式,连接到数据库后,连接执行很少的sql就断开连接;下次需要的时候再重连,但是在业务高峰期间的时候,就可能出现连接突然暴涨的情况。

说明:mysql中的max_connections参数,控制一个mysql实例同时存在的连接数上限;如果>max_connections值,系统拒绝链接,并报错:“Too many connnecions”;

从业务角度看到是数据库链接不可用。

2.机器负载较高的时候,处理现有的请求时间变长,每个连接保持的时间也变长,这样有新的连接的话,有可能会超过max_connections的限制。

3.mysql建立连接的成本高,除了正常的3次握手外,还需要做登录权限判断和获取这个链接的数据的读和写的权限。

解决方案:

1.先处理掉那些占用着连接但是不工作的线程(如果是连接过多,考虑优先断开事务外空闲太久的连接;如果这样还不够,再考虑断开事务内空闲太久的连接。)

命令:show processlist

展示连接的详细信息:

c0e7fb351e0a911bed36d062ec6e42ae.png

命令:select * from information_schema.INNODB_TRX

查看事务的具体的状态:trx_mysql_thread_id = 6 表示id = 6的线程还在事务中;

开启事务,在t表中插入一条数据:

ff025a494d6600193e1ae624649e4c24.png

通过查询information_schema库中的INNODB_TRX的表发现多了trx_mysql_thread_id = 14的事务;

mysql> select *from INNODB_TRX \G;*************************** 1. row ***************************trx_id:102202trx_state: RUNNING

trx_started:2019-02-03 17:49:14trx_requested_lock_id: NULL

trx_wait_started: NULL

trx_weight:2trx_mysql_thread_id:14trx_query: NULL

trx_operation_state: NULL

trx_tables_in_use:0trx_tables_locked:1trx_lock_structs:1trx_lock_memory_bytes:1136trx_rows_locked:0trx_rows_modified:1trx_concurrency_tickets:0trx_isolation_level: REPEATABLE READ

trx_unique_checks:1trx_foreign_key_checks:1trx_last_foreign_key_error: NULL

trx_adaptive_hash_latched:0trx_adaptive_hash_timeout:0trx_is_read_only:0trx_autocommit_non_locking:0

*************************** 2. row ***************************trx_id:281479467028936trx_state: RUNNING

trx_started:2019-02-01 17:02:13trx_requested_lock_id: NULL

trx_wait_started: NULL

trx_weight:0trx_mysql_thread_id:9trx_query: NULL

trx_operation_state: NULL

trx_tables_in_use:0trx_tables_locked:0trx_lock_structs:0trx_lock_memory_bytes:1136trx_rows_locked:0trx_rows_modified:0trx_concurrency_tickets:0trx_isolation_level: REPEATABLE READ

trx_unique_checks:1trx_foreign_key_checks:1trx_last_foreign_key_error: NULL

trx_adaptive_hash_latched:0trx_adaptive_hash_timeout:0trx_is_read_only:0trx_autocommit_non_locking:0

2 rows in set (0.00 sec)

再开一个窗口使用kill connection id命令kill connection 14;然后再第一个未提交的事务中查询的时候,发现报错:“ERROR 2006 (HY000): MySQL server has gone away no connection”

ddddb9ba769f5868e868795267acf43b.png

从数据库端主动断开连接可能是有损的,尤其是有的应用端收到这个错误后,不重新连接而是直接用这个已经不能用的句柄重试查询。这会导致从应用端看上去,“mysql 一直没恢复”。

2.减少连接过程中的消耗(不推荐,风险高)

如果现在确认数据库被连接行为打挂了,可能的做法是跳过数据库的权限验证阶段;

跳过权限验证的方法:重启数据库,并使用-skip-grant-tables参数启动;整个mysql会跳过所有的权限验证阶段,包括连接过程和语句执行过程在内。

慢查询性能问题

1.索引没有设计好

mysql5.6版本以后,创建索引支持Online DDL 对于高峰期数据库被这个语句打挂了的情况,最高效的做法是直接执行 alter table;

备库上先执行alter增加索引的操作:假设服务是一主一备:主库是A,备库是B,这个方法大致流程是这样的:

在备库B执行 set sql_log_bin=off,也就是不写binlog,然后执行alter table add index 语句增加索引;

执行主备切换;

这时候主库变为B,备库是A。在A上执行set sql_log_bin=off,然后用alter table语句加上索引;

这是一个常用的DDL方案,平时变更的时候考虑类似的gh-ost这样的方案,更加稳妥。但是在紧急处理的时候,上面的方案效率是最高的;

2.sql语句没有写好

3.mysql选错了索引

前面的的1,2是经常会发生的,这两种是可以避免的。

上线前,在测试环境,把慢查询的日志(show log)打开,并且吧long_query_time设置成0,确保每个语句都会被记录到慢查询日志当中;

在测试表里面插入模拟线上的数据,做一遍回归测试;

观察慢查询日志里每类语句的输出,特别留意Rows_examined字段是否 与预期一致。

可用使用开源工具digest:https://www.percona.com/doc/percona-toolkit/3.0/pt-query-digest.html 检查所有sql语句的返回结果。

QPS突增的问题

由于业务突然出现高峰,或者应用程序的bug,导致某个SQL的QPS突然暴涨,也可能导致Mysql的压力过大,影响服务;

应急方法:

1. 一种是如果是由于全新业务bug导致的,假设你的DB运维比较规范的话,也就是白名单是一个个加的,这种如果能确定业务方会下掉这个功能,只是时间没那么快,那么直接可以从数据库端直接把白名单去掉。

2.如果这个新功能使用的是单独的数据库用户,可以用管理员账号把这个用户删掉,然后断开现有的链接。新功能的链接不成功,引发的qps就会变为0;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值