为什么 `select ... for update` 语句锁定的行多于总行数?
Why `select ... for update` statement locks more rows then total number of rows?
我用的是mysql5.6。而我运行下面的查询。
CREATE TABLE `user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL,
`passport_id` varchar(20) NOT NULL,
`age` int(100) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `passport_id` (`passport_id`),
KEY `idx_user_age` (`age`)
) ENGINE=InnoDB ;
insert into user values(1, 'A', 'A1', 1), (2, 'B', 'B1', 1), (3, 'C', 'C3', 1),
(4, 'A', 'A4', 2), (5, 'B', 'B5', 2), (6, 'C', 'C6', 2);
set autocommit = 0;
select * from user where age = 1 for update;
我希望上面的 select...for update
查询锁定 3 行。因为查询了returns3行。但是select * from information_schema.innodb_trx;
查询的trx_rows_locked
数据是7条,连总行数是6条。
另外,下面查询returns只有一行。但是 trx_rows_locked
是 2.
select * from user where age = 1 and passport_id = 'A1' for update;
Mysql 文档解释 trx_row_locked
这样 The approximate number or rows locked by this transaction.
。但是我不明白为什么 trx_row_locked
有大概的数字。
我怎样才能得到正确的锁定行数?
trx_rows_locked
确实是本次交易的大概record locks
个数,注意不是table中的行记录数。由于 delete-marked
条记录可能会被删除,因此记录数将不准确。
select * from user where age = 1 for update;
使用完整的table扫描,我们可以通过explain看到执行计划,因此它锁定了所有table,6条记录,加上一个supremum record(其实就是一个gap lock),所以trx_rows_locked = 6 + 1 = 7
select * from user where age = 1 and passport_id = 'A1' for update;
使用唯一索引passport_id
,因此InnoDB会在passport_id
索引上获取记录锁,在PK上获取记录锁,所以trx_rows_locked = 2
我用的是mysql5.6。而我运行下面的查询。
CREATE TABLE `user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL,
`passport_id` varchar(20) NOT NULL,
`age` int(100) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `passport_id` (`passport_id`),
KEY `idx_user_age` (`age`)
) ENGINE=InnoDB ;
insert into user values(1, 'A', 'A1', 1), (2, 'B', 'B1', 1), (3, 'C', 'C3', 1),
(4, 'A', 'A4', 2), (5, 'B', 'B5', 2), (6, 'C', 'C6', 2);
set autocommit = 0;
select * from user where age = 1 for update;
我希望上面的 select...for update
查询锁定 3 行。因为查询了returns3行。但是select * from information_schema.innodb_trx;
查询的trx_rows_locked
数据是7条,连总行数是6条。
另外,下面查询returns只有一行。但是 trx_rows_locked
是 2.
select * from user where age = 1 and passport_id = 'A1' for update;
Mysql 文档解释 trx_row_locked
这样 The approximate number or rows locked by this transaction.
。但是我不明白为什么 trx_row_locked
有大概的数字。
我怎样才能得到正确的锁定行数?
trx_rows_locked
确实是本次交易的大概record locks
个数,注意不是table中的行记录数。由于 delete-marked
条记录可能会被删除,因此记录数将不准确。
select * from user where age = 1 for update;
使用完整的table扫描,我们可以通过explain看到执行计划,因此它锁定了所有table,6条记录,加上一个supremum record(其实就是一个gap lock),所以trx_rows_locked = 6 + 1 = 7
select * from user where age = 1 and passport_id = 'A1' for update;
使用唯一索引passport_id
,因此InnoDB会在passport_id
索引上获取记录锁,在PK上获取记录锁,所以trx_rows_locked = 2