最近和系统部一起做了一个数据库迁移,把mysql从老旧狭小的服务器迁到了一个大内存的服务器上,不料迁移之后插入速度慢了不少,平均每4-5分钟slow query log就能出现4-5条,而且这4-5条绝大部分是insert,而且挨着,从日志来看,它们之间是在互相锁着。engine用的是myisam。
第一感觉,应该是锁的问题。但是查了很多状态和参数,并没找到合理的解释,也没有定位到异常的位置。
再仔细读读日志,发现连续的几条慢日志,并不都是因为锁的时间长。有些插入,没有人和它竞争,它自己就很慢;而它执行时,锁了表,就导致后面的几条很慢。由此猜想,应该是单条插入过慢,不是锁的问题。
在排除了网络、硬盘有问题的可能后,猜想应该是mysql配置本身有问题。第一步,发现了“concurrent_insert”这个参数。默认值是1,即可以并行读写,但是当表中数据有删除、造成前面的若干行有洞洞(碎片)时,就要优先往洞洞里插入,以确保碎片减少;当设置为2时,不管有没有碎片,都是往末尾插。因为导数据时,我手工删除了很多旧数据,所以感觉改成2会解决问题。但是试了之后,发现并无效果。猜想,我删除数据后,执行了optimize,可能碎片已经整理完了。
第二步,找到了“sync_binlog”这个参数。服务器上设置为1,即每当有任何一条insert或者update,都要同步到bin log上。我试着改成了100,即有100条修改后,才会同步到bin log文件。修改后果然见效,时隔16分钟,才连续出现了3条慢语句。之后,我决定赌一把,把它改成了0,即由操作系统决定何时同步。到现在已经有近40分钟,再也没有出现慢的insert。希望不只是神灵保佑的原因。
多说一句,sync_binlog这个参数我怀疑不会影响主从备份,因为从库来获取更新时,联系的是主库,而不是copy bin log文件,bin log有没有写到硬盘上,于此无干。






