Tôi đang làm việc với postgres 9.1 và nhận được ngoại lệ bế tắc dưới sự thực thi quá mức của một phương thức cập nhật đơn giản.bế tắc trong postgres trên truy vấn cập nhật đơn giản
Theo nhật ký, bế tắc xảy ra do thực hiện hai cập nhật giống hệt nhau cùng một lúc.
cập nhật public.vm_action_info thiết last_on_demand_task_id = $ 1, version = phiên bản + 1
Làm thế nào để hai bản cập nhật đơn giản giống hệt nhau có thể bế tắc lẫn nhau?
Các lỗi mà tôi nhận được trong nhật ký
2013-08-18 11:00:24 IDT HINT: See server log for query details.
2013-08-18 11:00:24 IDT STATEMENT: update public.vm_action_info set last_on_demand_task_id=$1, version=version+1 where id=$2
2013-08-18 11:00:25 IDT ERROR: deadlock detected
2013-08-18 11:00:25 IDT DETAIL: Process 31533 waits for ShareLock on transaction 4228275; blocked by process 31530.
Process 31530 waits for ExclusiveLock on tuple (0,68) of relation 70337 of database 69205; blocked by process 31533.
Process 31533: update public.vm_action_info set last_on_demand_task_id=$1, version=version+1 where id=$2
Process 31530: update public.vm_action_info set last_on_demand_task_id=$1, version=version+1 where id=$2
2013-08-18 11:00:25 IDT HINT: See server log for query details.
2013-08-18 11:00:25 IDT STATEMENT: update public.vm_action_info set last_on_demand_task_id=$1, version=version+1 where id=$2
2013-08-18 11:00:25 IDT ERROR: deadlock detected
2013-08-18 11:00:25 IDT DETAIL: Process 31530 waits for ExclusiveLock on tuple (0,68) of relation 70337 of database 69205; blocked by process 31876.
Process 31876 waits for ShareLock on transaction 4228275; blocked by process 31530.
Process 31530: update public.vm_action_info set last_on_demand_task_id=$1, version=version+1 where id=$2
Process 31876: update public.vm_action_info set last_on_demand_task_id=$1, version=version+1 where id=$2
schema là:
CREATE TABLE vm_action_info(
id integer NOT NULL,
version integer NOT NULL DEFAULT 0,
vm_info_id integer NOT NULL,
last_exit_code integer,
bundle_action_id integer NOT NULL,
last_result_change_time numeric NOT NULL,
last_completed_vm_task_id integer,
last_on_demand_task_id bigint,
CONSTRAINT vm_action_info_pkey PRIMARY KEY (id),
CONSTRAINT vm_action_info_bundle_action_id_fk FOREIGN KEY (bundle_action_id)
REFERENCES bundle_action (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE CASCADE,
CONSTRAINT vm_discovery_info_fk FOREIGN KEY (vm_info_id)
REFERENCES vm_info (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE CASCADE,
CONSTRAINT vm_task_last_on_demand_task_fk FOREIGN KEY (last_on_demand_task_id)
REFERENCES vm_task (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT vm_task_last_task_fk FOREIGN KEY (last_completed_vm_task_id)
REFERENCES vm_task (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITH (OIDS=FALSE);
ALTER TABLE vm_action_info
OWNER TO vadm;
-- Index: vm_action_info_vm_info_id_index
-- DROP INDEX vm_action_info_vm_info_id_index;
CREATE INDEX vm_action_info_vm_info_id_index
ON vm_action_info
USING btree (vm_info_id);
CREATE TABLE vm_task
(
id integer NOT NULL,
version integer NOT NULL DEFAULT 0,
vm_action_info_id integer NOT NULL,
creation_time numeric NOT NULL DEFAULT 0,
task_state text NOT NULL,
triggered_by text NOT NULL,
bundle_param_revision bigint NOT NULL DEFAULT 0,
execution_time bigint,
expiration_time bigint,
username text,
completion_time bigint,
completion_status text,
completion_error text,
CONSTRAINT vm_task_pkey PRIMARY KEY (id),
CONSTRAINT vm_action_info_fk FOREIGN KEY (vm_action_info_id)
REFERENCES vm_action_info (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE CASCADE
)
WITH (
OIDS=FALSE
);
ALTER TABLE vm_task
OWNER TO vadm;
-- Index: vm_task_creation_time_index
-- DROP INDEX vm_task_creation_time_index ;
CREATE INDEX vm_task_creation_time_index
ON vm_task
USING btree
(creation_time);
Họ không phải là đơn giản. Có một FK constrant trên lĩnh vực này (mà kết quả trong một chỉ số cần phải được cập nhật) Có lẽ thử trì hoãn ban đầu trì hoãn? (không nghĩ rằng nó có thể làm cho bất kỳ sự khác biệt) – wildplasser
Tôi không muốn thay đổi các hạn chế FK như tôi không hoàn toàn chắc chắn như thế nào nó sẽ có hiệu lực hệ thống trong genral. Thêm một hạn chế trong mã mà chỉ truy vấn duy nhất có thể thực hiện tại một thời điểm nhất định giải quyết vấn đề nhưng tôi không hiểu làm thế nào một truy vấn có thể gây ra một bế tắc với chính nó. Tất cả các ổ khóa đều được mua theo thứ tự như vậy về mặt tehoritically nó không nên xảy ra. Có khả năng rằng các hậu duệ bí ẩn phát hiện một bế tắc không thực sự tồn tại? – moshe
Bạn đã viết 'tất cả khóa được mua cùng thứ tự', có nghĩa là nó không chỉ là một bản cập nhật đơn giản, nhưng toàn bộ giao dịch bao gồm nhiều lệnh khóa hơn bản cập nhật đơn này? Nếu có, vui lòng cho chúng tôi biết toàn bộ mã. – krokodilko