powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Помогите разобраться с deadlock.
8 сообщений из 8, страница 1 из 1
Помогите разобраться с deadlock.
    #39077705
kalombo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Лог ошибки

автор2015-10-15 10:56:35 YEKT [30487-2] gottlieb@gottlieb DETAIL: Process 30487 waits for ShareLock on transaction 33423231; blocked by process 13160.
Process 13160 waits for ShareLock on transaction 33423251; blocked by process 30487.
Process 30487:
UPDATE snmp_ports SET oper = 2, admin = 1
WHERE id = 42251

Process 13160: DELETE FROM equipment_ids WHERE equipment_ids.id = 1986
2015-10-15 10:56:35 YEKT [30487-3] gottlieb@gottlieb HINT: See server log for query details.
2015-10-15 10:56:35 YEKT [30487-4] gottlieb@gottlieb CONTEXT: while locking tuple (246,56) in relation "equipment_ids"
SQL statement "SELECT 1 FROM ONLY "public"."equipment_ids" x WHERE "id" OPERATOR(pg_catalog.=) $1 FOR KEY SHARE OF x"
SQL statement "UPDATE snmp_ports SET flap_times=flap_times+1, last_down=now() WHERE id = OLD.id"
PL/pgSQL function snmp_oper_update() line 7 at SQL statement
2015-10-15 10:56:35 YEKT [30487-5] gottlieb@gottlieb STATEMENT:
UPDATE snmp_ports SET oper = 2, admin = 1
WHERE id = 42251

Краткое описание таблиц:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
CREATE TABLE equipment_ids
(
  id integer NOT NULL DEFAULT nextval('equipment_id_seq'::regclass),
  address character varying(50),
  CONSTRAINT equipment_pkey PRIMARY KEY (id)
)

CREATE TABLE snmp_ports
(
  id serial NOT NULL,
  equipment integer NOT NULL,
  oper integer NOT NULL DEFAULT 2,
  admin integer NOT NULL DEFAULT 2,
  last_up timestamp without time zone DEFAULT now(),
  last_down timestamp without time zone DEFAULT now(),
  flap_times integer DEFAULT 0,
  CONSTRAINT snmp_ports_pkey PRIMARY KEY (id),
  CONSTRAINT snmp_ports_equipment_fkey FOREIGN KEY (equipment)
      REFERENCES equipment_ids (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE CASCADE
)

CREATE TRIGGER update_snmp_oper
  AFTER UPDATE OF oper
  ON snmp_ports
  FOR EACH ROW
  EXECUTE PROCEDURE snmp_oper_update();


CREATE OR REPLACE FUNCTION snmp_oper_update()
  RETURNS trigger AS
$BODY$
BEGIN
		IF OLD.oper=2 AND NEW.oper=1 THEN
			UPDATE snmp_ports SET flap_times=flap_times+1, last_up=now() WHERE id = OLD.id;
		END IF;
		IF OLD.oper=1 AND NEW.oper=2 THEN
			UPDATE snmp_ports SET flap_times=flap_times+1, last_down=now() WHERE id = OLD.id;
		END IF;
	RETURN NEW;
END



Процесс 30487 непрерывно делает апдейты таблицы snmp_ports. Частота где-то 1-3 апдейта в секунду.
3-5 раз в день запускается процесс 13160, который пытается выполнить DELETE FROM equipment_ids WHERE equipment_ids.id = 1986 и соответственно каскадно удаляет порты. Ошибка возникает тогда, когда в первом процесе апдейтится тот же порт, что должен быть удален во втором процессе. Однако, если удалить триггер, то всё работает нормально. Подскажите как можно избежать этой ошибки?
...
Рейтинг: 0 / 0
Помогите разобраться с deadlock.
    #39077735
p2.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kalombo,

на апдейт порта сначала блокировать эквипмент или апдейтить по одной строчке на транзакцию. и это... нафиг в триггере делать апдейт той же таблицы, только заради, чтобы он был after?
...
Рейтинг: 0 / 0
Помогите разобраться с deadlock.
    #39078214
kalombo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
p2.
на апдейт порта сначала блокировать эквипмент

Сделал так:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
2015-10-16 08:56:31 YEKT LOG:  statement: begin
2015-10-16 08:56:31 YEKT LOG:  statement: LOCK TABLE equipment_ids IN ACCESS EXCLUSIVE MODE;
2015-10-16 08:56:31 YEKT LOG:  statement: 
	            UPDATE snmp_ports SET oper = 2, admin = 1
	            WHERE id = 152531
	        
2015-10-16 08:56:31 YEKT LOG:  statement: commit


Вроде работает, спасибо.

p2.или апдейтить по одной строчке на транзакцию.

Тут не понял, что ты имеешь в виду, объясни пожалуйста.

p2.и это... нафиг в триггере делать апдейт той же таблицы, только заради, чтобы он был after?
А какие варианты возможны еще? Мне нужно считать сколько раз флапнул(поменялось состояние поля oper) порт. Мне кажется выносить этот триггер во все апдейты портов всего приложения нецелесообразно, я не прав?
...
Рейтинг: 0 / 0
Помогите разобраться с deadlock.
    #39078221
kalombo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
И еще, можно как-то сэмулировать эту ошибку с помощью psql? Я пробовал по-разному - не вышло.
...
Рейтинг: 0 / 0
Помогите разобраться с deadlock.
    #39078259
p2.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kalomobp2.или апдейтить по одной строчке на транзакцию. Тут не понял, что ты имеешь в виду, объясни пожалуйста.понимание предполагает знакомство со сценариями, приводящими к дедлоку.
Код: plsql
1.
2015-10-16 08:56:31 YEKT LOG:  statement: LOCK TABLE equipment_ids IN ACCESS EXCLUSIVE MODE;

ну ты маханул...
...
Рейтинг: 0 / 0
Помогите разобраться с deadlock.
    #39078312
Ivan Durak
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kalomboА какие варианты возможны еще? Мне нужно считать сколько раз флапнул(поменялось состояние поля oper) порт. Мне кажется выносить этот триггер во все апдейты портов всего приложения нецелесообразно, я не прав?
да, апдейть flap_times сразу вместе с UPDATE snmp_ports SET oper = 2, admin = 1 !!!!!
Однозначно лучше и быстрее и локов меньше. Не целесообразно городить тригеры, там где они не нужны.
Это раз.

А два - лочить всю таблицу стейтментов это вообще жестко. Лучше не начинай навешивать костылей - это путь в тупик.
...
Рейтинг: 0 / 0
Помогите разобраться с deadlock.
    #39078516
kalombo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ivan DurakkalomboА какие варианты возможны еще? Мне нужно считать сколько раз флапнул(поменялось состояние поля oper) порт. Мне кажется выносить этот триггер во все апдейты портов всего приложения нецелесообразно, я не прав?
да, апдейть flap_times сразу вместе с UPDATE snmp_ports SET oper = 2, admin = 1 !!!!!
Однозначно лучше и быстрее и локов меньше. Не целесообразно городить тригеры, там где они не нужны.
Это раз.

А два - лочить всю таблицу стейтментов это вообще жестко. Лучше не начинай навешивать костылей - это путь в тупик.

Сделал так, спасибо всем.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
UPDATE  snmp_ports SET
              oper = %(oper)s,
              admin = %(admin)s,
              flap_times = CASE WHEN oper != %(oper)s THEN flap_times + 1 ELSE flap_times END,
              last_down = CASE WHEN oper = 1 and 2=%(oper)s THEN now() ELSE last_down END,
              last_up = CASE WHEN oper = 2 and 1=%(oper)s THEN now() ELSE last_down END
              WHERE id=%(port_id)s
...
Рейтинг: 0 / 0
Помогите разобраться с deadlock.
    #39078563
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kalombo,

а ещё триггера before бывают
...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Помогите разобраться с deadlock.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]