mysql性能优化问题定位-待解决

1 问题背景:

在程序启动时,数据处理时间很快,运行9h之后,对单张数据表处理时间长达5s。在对程序各个部分计时测量之后,发现时间主要消耗在mysql交互上,其中delete所占时间比例大概为90%。

2 具体信息

2.1 表结构&sql语句

mysql性能优化问题定位-待解决_第1张图片

服务中有9个进程按照固定周期写表:
其中8个进程执行语句:load data local infile ‘filename’ into test;
1个进程执行语句:insert into test (content) select content from temp_table;

其中的temp_table与test表结构相同,用来存储部分数据,按照指定周期更新。

处理test表的进程执行(服务中有8张test表,依次为test0-test7)

对于单张表执行
select content from test_n where seqno > lowThreshold;
process data
delete from test_n seqno where seqno < 处理完的数据的最大seqno
遍历8张表,重复执行上述操作

2.2 出现的问题现象:
当设置为2000qps时,服务在刚开始启动运行时,一切正常,单条数据处理时间约为0.0002s。
随着运行时间增加,单条数据处理时间逐渐减慢,大约1-2小时变化一次,在随后的一段时间保持在一个稳定数值。当运行时间达到9小时后,单条数据处理时间变为0.001s,为初始时间的5-6倍。

2.3 问题解决过程
2.3.1分析sql语句
在已知delete消耗时间增加的情况下:

当前引擎为innodb,行锁,在MySQL中,行级锁并不是直接锁记录,而是锁索引。索引分为主键索引和非主键索引两种,如果sql语句操作了主键索引,mysql就会锁定这条主键索引   http://blog.csdn.net/zhanghongzheng3213/article/details/51721903

怀疑在delete的时候锁定了过多的数据,同时对单表而言,有9个进程在同时插入,怀疑delete锁表,导致其他进程在插入的时候阻塞,在delete完之后才能执行,从而导致随着时间的运行,现象越来越严重。

使用EXPLAIN分析语句,explain参考https://www.cnblogs.com/yycc/p/7338894.html
当前表结构主键索引为自增的seqno,在select和delete时均使用了该索引,在插入进程中insert语句未填写seqno,会在插入时由mysql自动补全改字段,在使用load data local infile插入时,原始程序在文件中将seqno填写0,由mysql导入数据时自动更改,怀疑这里导致了删除时的锁定(delete from where seqo<),将文件中的seqno去掉之后,情况没有改善。

2.3.2
1 没有mysql机器的权限,没能查看mysql的慢查询日志(蠢哭)
2 在mysql客户端判断是否有锁的产生:
2.1  因为在程序运行9小时之后,单张表的处理时间长达5秒。这里可以直接查看相关信息,而不用脚本一直去检测
查看information_schema下面的三张表:INNODB_TRX、INNODB_LOCKS、INNODB_LOCK_WAITS,寻找锁的信息,无果。
参考http://blog.itpub.net/12679300/viewspace-1420031/
使用show engine innodb status来查看信息,查看时设置pager grep "locked";   pager cat > test.txt ;
查看方法参考:https://www.cnblogs.com/xiaoboluo768/p/5171425.html

查询的结果:
---TRANSACTION 1F0C3F3587, ACTIVE 0 sec starting index read
mysql tables in use 1, locked 1
18021 lock struct(s), heap size 1620408, 820319 row lock(s)
MySQL thread id 90570605, OS thread handle 0x7f64e7ad4700, query id 160038277928 ip user updating
delete from  test_0   where seqno <= 139812240
发现在delete的时候有表锁产生,同时锁定的行数过多为18021,但是当前qps远小于这个数值。

问题并不知道怎么进一步分析----  求指导

2.3.3
sx的解决方式:
1 尝试将delete拆分,原服务直接删除处理的所有数据,增加判断删除条数的逻辑,拆分为每次删除1000条=== 结果,操作没有改善,反而恶化,服务在运行大约4小时候之后,单表处理时间达到5秒。
2 尝试修改select的条件,原始服务select所有大于指定seqno的数值,此处加上limit 1000,无效。
3 在原始服务之外添加py脚本,不在c++的服务里面执行删除,使用脚本定时删除过期的mysql数据。服务能够长时间稳定运行,单条数据处理时间始终保持在0.0002s以下。

3 todo
1 分析锁的行数增加 和delete时间增加的具体原因
2 慢查询日志的使用

没有能够从本质上解决问题。。  羞愧   ---  待续
 

 

你可能感兴趣的:(mysql)