나는 종종 그 자체를 보여주는 이노 교착 상태 주위에 내 머리를 정리하려고 해요 :InnoDB CREATE ... SELECT가 독점적 인 락을 사용하는 이유는 무엇입니까?
------------------------
LATEST DETECTED DEADLOCK
------------------------
110511 10:45:59
*** (1) TRANSACTION:
TRANSACTION 0 959459752, ACTIVE 0 sec, process no 24148, OS thread id 2958613424 starting index read
mysql tables in use 16, locked 16
LOCK WAIT 2 lock struct(s), heap size 320
MySQL thread id 13029007, query id 85826239 localhost andrew updating
DELETE FROM `clients_permission_assignments` WHERE permission_assignment_id = 3761 AND client_id IN (52621)
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 1490959 n bits 864 index `unique_index` of table `test/clients_permission_assignments` trx id 0 959459752 lock_mode X waiting
Record lock, heap no 202 PHYSICAL RECORD: n_fields 3; compact format; info bits 32
0: len 4; hex 8000cd8d; asc ;; 1: len 4; hex 80000eb1; asc ;; 2: len 6; hex 0000006b7d5c; asc k}\;;
*** (2) TRANSACTION:
TRANSACTION 0 959459751, ACTIVE 0 sec, process no 24148, OS thread id 1996331952 fetching rows, thread declared inside InnoDB 354
mysql tables in use 16, locked 16
20 lock struct(s), heap size 2496, undo log entries 1
MySQL thread id 13019094, query id 85826237 localhost andrew Copying to tmp table
CREATE TEMPORARY TABLE tmp_tests_people_cleanup_table (SELECT unit_code FROM (
SELECT u.unit_code, COUNT(u.unit_code) AS cnt FROM staging.client_test_utilization u
LEFT JOIN permission_assignments pa ON pa.person_id =
(SELECT person_id FROM permission_assignments pa WHERE pa.id = OLD.permission_assignment_id)
LEFT JOIN permissions p ON pa.permission_id = p.id
LEFT JOIN clients_permission_assignments cpa ON cpa.permission_assignment_id = pa.id
LEFT JOIN clients c ON c.id = cpa.client_id
LEFT JOIN staging.client_test_utilization u2 ON CONCAT('C',u2.client_number) = c.number
AND u2.unit_code = u.unit_code
WHERE p.label = 'Receive Test Updates'
AND CONCAT('C',u.client_number) = (SELECT number from clients WHERE id = OLD.client_id)
AND u2.id IS NULL GROUP BY u.unit_code
) tbl
WHERE cnt = (SELECT COUNT(*) FROM permission_assignments pa
LEFT JOIN permissions p ON pa.permission_id = p.id
LEFT JOIN clients_permission_assignments cpa ON cpa.permission_assignment_id = pa.id
WHERE p.label = 'Receive Test Updates' AND pa.person_id =
(SELECT person_id FROM permission_assignments pa WHERE pa.id = OLD.permission_assignment_id))
OR (SELECT COUNT(*) FROM permission_assignments pa
LEFT JOIN permissions p ON pa.permission_id = p.id
LEFT JOIN clients_permission_assignments cpa ON cpa.permission_assignment_id = pa.id
WHERE p.label = 'Receive Test Updates' AND pa.person_id =
(SELECT person_id FROM permission_assignments pa WHERE pa.id = OLD.permission_assignment_id)) = 0)
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 0 page no 1490959 n bits 864 index `unique_index` of table `test/clients_permission_assignments` trx id 0 959459751 lock_mode X locks rec but not gap
Record lock, heap no 202 PHYSICAL RECORD: n_fields 3; compact format; info bits 32
0: len 4; hex 8000cd8d; asc ;; 1: len 4; hex 80000eb1; asc ;; 2: len 6; hex 0000006b7d5c; asc k}\;;
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 1490959 n bits 864 index `unique_index` of table `test/clients_permission_assignments` trx id 0 959459751 lock mode S waiting
Record lock, heap no 202 PHYSICAL RECORD: n_fields 3; compact format; info bits 32
0: len 4; hex 8000cd8d; asc ;; 1: len 4; hex 80000eb1; asc ;; 2: len 6; hex 0000006b7d5c; asc k}\;;
*** WE ROLL BACK TRANSACTION (1)
내가 시간에 알지 못했다하지만 INSERT 것 같아 ... SELECT, CREATE ... SELECT SELECT 쿼리의 모든 테이블을 잠급니다. 보시다시피 조인과 하위 쿼리가있는 테이블이 많이 있습니다. 나는 자물쇠가 공유 (S) 자물쇠 일 것이라고 생각했지만 위의 데이터에서 자물쇠 (X) 자물쇠를 보유하고있는 것으로 보인다. 나는 왜 그런지 이해하지 못한다.
아마도 누군가가 CREATE ... SELECT 쿼리에 독점 (X) 잠금이있는 이유를 알면이 교착 상태를 해결할 수 있습니다. 또는 교착 상태에 대한 도움을받을 수 있습니다.
감사합니다.
어떤 격리 수준을 사용하고 있습니까? –
MySQL의 기본값 (REPEATABLE READ) 인 것 같습니다. 과거에 INSERT ... SELECT 문제를 해결하기 위해'SET TRANSACTION ISOLATION LEVEL READ COMMITTED; '를 사용했습니다; 이것이 여기에서도 유용 할 것이라고 생각합니까? –