今天碰到奇怪的事情,数据库里的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都是自增字段,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了,所以有问题的数据没有办法截图
可以看下事务的情况 select * from information_schem.INNODB_TRX
2、出现很多不相干语句的update等待,有可能系统出现故障,比如磁盘错误,或其他错误, 最好查下mysql的错误记录
删除的问题,你可以试一下 select ,如果 select 同样慢,应该考虑系统问题,如果只是 update / delete 慢,那检查是否锁的问题,比如把所有的进程都断开,在没有其他人操作的情况下,如果操作慢,那么是并发冲突导致
但是其trx_mysql_thread_id在processlist表里对应的id,command都是sleep,且state、info两列都是空
如果也慢,开 PROFILE 看看
SET PROFILING = 1