今天碰到奇怪的事情,数据库里的update或delete执行经常超时,有问题的表涉及到不同库的不同表,这些库、表之间没有任何业务关联。
发现的共性如下:
1. 表的id都是自增字段,2. id字段的数据不知为什么基本不连续,比如1,2,12,33,124,137...,问了一下,没人删除过数据
2. 超时的语句非常简单,就是update table set col="xxx" where id = 1,获得delete from table where id=1,单独执行select * from table where id=1,数据可以查询到;
3. 调用show processlist,显示这些语句一直是updating,后来把有问题的表整个TRUNCATE,重新生成数据,再update或delete,可以正常执行,不再卡死。
4. 数据库是5.7,innodb引擎
这是当时show processlist的截图执行的语句是:UPDATE logintoken  SET token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJERVMifQ==.eyJpZCI6MjcsImV4cCI6IjE1MDg3NDg4NjY0MDIiLCJsb2dpbk5hbWUiOiIxMzU3MTgzMDYyNSJ9.7b01517332f630d897893322f51e6a2d47d123d1ec73de38a2b4d7f3de732269cd3c6c3f23ae54064aec6d84f00adccf968da94ae4a07f0130ec872b4ebacd0b2687bd1d098989f7dcea03d59aa050d004e8ea3165075ff5162c247e4cd80a93d3e25039dd177c0dbf11599472fbadbeddc02afd1f0ef8fd',tokenExpiredTime = '2017-11-22 16:54:26.402' WHERE  Id = 118表结构是:
CREATE TABLE `logintoken` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`type` CHAR(1) NOT NULL DEFAULT '0' ,
`loginName` VARCHAR(20) NULL DEFAULT NULL,
`token` VARCHAR(2000) NULL DEFAULT NULL,
`tokenExpiredTime` TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE INDEX `loginName` (`loginName`, `type`) USING BTREE
)
COMMENT='登录Token'
COLLATE='utf8mb4_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=15
;
表被TRUNCATE了,所以有问题的数据没有办法截图

解决方案 »

  1.   

    不连续id是因为唯一索引,冲突后id自增1长时间updateing 应该是有事务锁住了相应的id造成等待锁
    可以看下事务的情况 select * from information_schem.INNODB_TRX
      

  2.   

    1、自增字段id不连续是正常的, 中间的空号很多,说明包含该插入语句的事务不成功的比例很多。
    2、出现很多不相干语句的update等待,有可能系统出现故障,比如磁盘错误,或其他错误, 最好查下mysql的错误记录
      

  3.   

    不连续就不说了,很多情况导致,处境的设计也不是以连续为目标,不纠结
    删除的问题,你可以试一下 select ,如果 select 同样慢,应该考虑系统问题,如果只是 update / delete 慢,那检查是否锁的问题,比如把所有的进程都断开,在没有其他人操作的情况下,如果操作慢,那么是并发冲突导致
      

  4.   

    INNODB_TRX 确实有记录,杀掉trx_mysql_thread_id的对应值就好了。
    但是其trx_mysql_thread_id在processlist表里对应的id,command都是sleep,且state、info两列都是空
      

  5.   

    select没有问题。并发应该不至于,因为数据库是刚清的,总共只有不到10条数据,现在还在测试阶段,2个测试人员。innodb_trx确实有东西,科室processlist里是sleep,且info里没有sql语句
      

  6.   

    你把语句单独拿出来执行看看是否也慢
    如果也慢,开 PROFILE 看看
    SET PROFILING = 1
      

  7.   

    阻塞是trx表里有一条数据在running,但是相应的线程在processlist表里的数据是sleep,可是info一列没有SQL语句。我有什么办法能看到什么东西阻塞了?
      

  8.   

    查下 information_schema.innodb_locks  ,如果这个没有数据,只在 trx 中有数据,那么你需要 PROFILE