2016-07-29 3 views
2

enter image description here이 innodb gap lock 버그가 있습니까?

TRX1 선택 * 테이블로 TRX2

업데이트

표 REFID = 4에서 인서트 (REFID)의 값 (2); 블록

trx2가 차단되며 trx1이 갭 잠금을 유지한다는 것을 알았습니다 [1,4], [4,7];

제 질문은 간격 잠금을 유지하는 이유입니까? "insert val 2"는 충돌이 아닙니다. "refId = 4 for update"를 선택하십시오. 왜 innodb가 간격 잠금을 유지할 것입니까? 왜 기록 잠금을 사용하지 않습니까?

이 질문은 나를 오랫동안 괴롭 혔습니다. 제발 기술 신이 나를 구 해주십시오.

답변

1

흥미로운 질문입니다.

phantom rows을 피하려면 간격 잠금이 필요합니다. MySQL은 REPEATABLE-READ 격리 수준에서 기본적으로 작동합니다. 거래에서 여러 번 select ... for update을 실행하면 항상 동일한 결과를 반환해야합니다. 갭 잠금이없고 trx2가 refId = 4 (인덱스가 고유하지 않음) 인 다른 행을 삽입했다고 가정합니다. 그런 다음 두 행을 반환합니다 TRX1의 선택 다음

MariaDB [test]> select * from t1 where refId=4 for update; 
+----+------+ 
| id | refId| 
+----+------+ 
| 2 | 4 | 
| 4 | 4 | 
+----+------+ 
2 rows in set (0.00 sec) 

그것은 첫 번째 선택과 같은 결과가 없습니다.

+0

네, 그렇습니다, 공허한 팬텀 행, 테스트를 따르고, refId = 4로 다른 행을 삽입하십시오. trx1이 행 레코드 잠금 (또는 갭 잠금)을 유지하고 refId = 4 삽입을 차단할 수 있고 공상 팬텀 행; 내 질문 왜 삽입 간격을 유지 refId = 1,2,3,5,6뿐만 아니라, 4.이 느낌은 MySQL의 버그입니까? –

+0

나는이 SQL에 대한 gap-lock 작업을 "select * from table"에서 refId <10 for update "라고 생각합니다. gap lock은 refId = 1,2,3,4,5,6,7 삽입을 차단합니다. 조건 검색 조건이 아니라 조건과 일치해야합니다. –

+0

답변 해 주셔서 감사합니다. –