2011년 1월 30일 일요일

MySQL 5.1.42 SELECT 쿼리의 SharedLock 관련 버그


MySQL 5.1.42 버전에서 SELECT 쿼리가 Shared(Read) Lock을 거는 버그가 있었다.
모든 쿼리가 그런 것이 아니라, 확인된 쿼리는 아래 형태의 SubQuery로 Counting하는 쿼리이다.

간단히 재현하는 방법은 아래와 같다.

-------------------------------------------------------------
Session 1
-------------------------------------------------------------
CREATE TABLE lock_test (
  fd1 int not null,
  fd2 int not null,
  fd3 int not null,
  INDEX ix_12 (fd1, fd2),
  INDEX ix_21 (fd2, fd1)
) ENGINE=InnoDB;

INSERT INTO lock_test VALUES (1,2), (2,1);

COMMIT;

BEGIN;
SELECT (
  (SELECT COUNT(*) FROM lock_test WHERE fd1=1) +
  (SELECT COUNT(*) FROM lock_test WHERE fd2=1)
) AS cnt;


-------------------------------------------------------------
Session 2
-------------------------------------------------------------
SHOW ENGINE INNODB STATUS;


...
---TRANSACTION 1 3051889568, ACTIVE 5 sec, process no 9090, OS thread id 1261443392
19 lock struct(s), heap size 6752, 2 row lock(s)
MySQL thread id 178344, query id 17362465365 localhost root
Trx read view will not see trx with id >= 1 3051889569, sees < 1 3051889555
...

이 버그는 MySQL 5.0.68 이나 MySQL 5.1.54 버전에서는 발견되지 않았으며,
MySQL 5.1.42에서만 나타났고, MySQL 5.1.45 버전에서 Fix되었다.

그리고 관련해서 SHOW INNODB STATUS ENGINE에서 Deadlock을 보고하는 경우가 있는데,
실제로 이 내용은 Deadlock이 아니라, InnoDB가 CPU 사용률을 줄이기 위해서
ShortPath로 Deadlock으로 간주하도록 하는 부분도 있었다.

Bug #49001 (http://bugs.mysql.com/49001)

댓글 없음:

댓글 쓰기