Гость
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Всем привет! Поговорим про отключение триггеров / 17 сообщений из 17, страница 1 из 1
17.01.2019, 04:14
    #39760593
PCContra
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Всем привет! Поговорим про отключение триггеров
Всем привет!

У меня вопрос такой (возможности самому проверить нет) Вот что начитал в мануале:
The ability to temporarily enable or disable a trigger is provided by ALTER TABLE, not by
ALTER
TRIGGER
, because
ALTER TRIGGER
has no convenient way to express the option of enabling or
disabling all of a table’s triggers at once.
ALTER TABLE
DISABLE TRIGGER [trigger_name| ALL | USER ]
ENABLE TRIGGER [trigger_name| ALL | USER ]
ENABLE REPLICA TRIGGERtrigger_name
ENABLE ALWAYS TRIGGERtrigger_name
DISABLE
/
ENABLE [ REPLICA | ALWAYS ] TRIGGER
These forms configure the firing of trigger(s) belonging to the table. A disabled trigger is still
known to the system, but is not executed when its triggering event occurs. For a deferred trigger,
the enable status is checked when the event occurs, not when the trigger function is actually
executed. One can disable or enable a single trigger specified by name, or all triggers on the
table, or only user triggers (this option excludes internally generated constraint triggers such as
those that are used to implement foreign key constraints or deferrable uniqueness and exclusion
constraints). Disabling or enabling internally generated constraint triggers requires superuser
privileges; it should be done with caution since of course the integrity of the constraint cannot
be guaranteed if the triggers are not executed. The trigger firing mechanism is also affected by
the configuration variable session_replication_role. Simply enabled triggers will fire when the
replication role is “origin” (the default) or “local”. Triggers configured as
ENABLE REPLICA

will only fire if the session is in “replica” mode, and triggers configured as
ENABLE ALWAYS
will fire regardless of the current replication mode.
This command acquires a
SHARE ROW EXCLUSIVE
lock

trigger_name
Name of a single trigger to disable or enable.
ALL
Disable or enable all triggers belonging to the table. (This requires superuser privilege if any of
the triggers are internally generated constraint triggers such as those that are used to implement
foreign key constraints or deferrable uniqueness and exclusion constraints.)
USER
Disable or enable all triggers belonging to the table except for internally generated constraint
triggers such as those that are used to implement foreign key constraints or deferrable uniqueness
and exclusion constraints


в принципе все понятно. Мне надо отключить триггер на одну транзакцию, затем включить его снова.
Я что боюсь: если я отключу триггер, в процессе выполнения транзакции кто-то будет менять данные в таблице паралельно со мной (начнет транзакцию свою позже, а затем завершит ее раньше) на него отключенный тригер не подействует? Я хочу чтобы на остальных отключенный триггер действовал .
Вот код:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
CREATE TABLE a(x INT); -- рабочая таблица
CREATE TABLE logs.a(time TIMESTAMP, x INT); --таблица логов

CREATE OR REPLACE FUNCTION logs.a () RETURNS TRIGGER AS $$
DECLARE
VAL RECORD;
BEGIN
IF TG_OP = 'INSERT' THEN VAL := NEW; ELSE VAL := OLD; END IF;


INSERT  INTO logs.a (time, x)
SELECT  NOW(), VAL.x

RETURN CASE WHEN TG_OP = 'DELETE' THEN OLD ELSE NEW END; 
END;
$$ LANGUAGE plpgsql;	

CREATE  TRIGGER  log BEFORE
INSERT OR UPDATE OR DELETE
ON  a
FOR  EACH  ROW  EXECUTE  PROCEDURE  
logs.a ();


Надо отключить на 1 транзакцию триггер "log".

Подействует ли отключение на другие транзакции?
Код: sql
1.
2.
3.
ALTER TABLE a DISABLE TRIGGER log;
INSERT INTO a(x) VALUES (1), (2), (3);
ALTER TABLE ENABLE TRIGGER log;



Спасибо за ответы!!
--
Россия - отличная страна!
...
Рейтинг: 0 / 0
17.01.2019, 04:26
    #39760594
Maxim Boguk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Всем привет! Поговорим про отключение триггеров
PCContra,

После ALTER TABLE a DISABLE TRIGGER log; - никто ничего с этой таблицей сделать не сможет.
Она эксклюзивно заблокирована на вашу сессию.
С нее даже select из другой сессии не сделать не то что запись.

Кстати мог бы и сам проверить.
...
Рейтинг: 0 / 0
17.01.2019, 09:28
    #39760625
tunknown
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Всем привет! Поговорим про отключение триггеров
PCContraНадо отключить на 1 транзакцию триггер "log".Можно создать отдельную таблицу, в которой для каждой сессии сделать настройку и эту настройку проверять в триггере, однако, это путь в никуда. Лучше сделать доступ к таблицам через хранимые процедуры. Если же у вас ORM, то уже ничего не поможет.
...
Рейтинг: 0 / 0
20.01.2019, 22:54
    #39762161
Garik888
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Всем привет! Поговорим про отключение триггеров
Я для таких случаев я сделал отдельное поле trigger_off
По дефолту оно равно нулю, но если я ставлю туда 1, то в триггере проверяю, если равно 1, то игнорирую всю работу триггера.
Но в этом варианте нужно в этом же триггере менять значение trigger_off всегда на 0
...
Рейтинг: 0 / 0
21.01.2019, 06:57
    #39762197
qwwq
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Всем привет! Поговорим про отключение триггеров
не знаю , как нынче, а раньше в пж всегда можно было отальтерить тело триггерной функции на старте транзы, сделать тёмное, и вернуть тело ф-ии взад в конце. чем это теоретицки чревато с т.з. консистентностей и т.п., в т.ч. при смене уровней изоляции у конкурентов -- остаёцца догадываться. но работает. и много дешевле чем альтер триггер. к тому же тип активности триггера не меняется.
...
Рейтинг: 0 / 0
21.01.2019, 07:46
    #39762202
fte
fte
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Всем привет! Поговорим про отключение триггеров
А может вообще без альтеров
Код: plsql
1.
2.
3.
4.
if not pg_has_role(session_user,'__wo_trigger__','usage') then
    INSERT  INTO logs.a (time, x)
    SELECT  NOW(), VAL.x
end if
...
Рейтинг: 0 / 0
21.01.2019, 07:54
    #39762203
fte
fte
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Всем привет! Поговорим про отключение триггеров
fte,
Или лучше так:
Код: plsql
1.
2.
3.
4.
5.
6.
CREATE  TRIGGER  log BEFORE
INSERT OR UPDATE OR DELETE
ON  a
FOR  EACH  ROW  EXECUTE  PROCEDURE  
logs.a ()
WHEN (not pg_has_role(session_user,'__wo_trigger__','usage'));
...
Рейтинг: 0 / 0
21.01.2019, 10:03
    #39762239
Maxim Boguk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Всем привет! Поговорим про отключение триггеров
fte,

Тогда уж
set session_replication_role to 'replica';
и делай чего хочешь триггера не будут вызываться нормальные в этой сессии вообще ;).
...
Рейтинг: 0 / 0
21.01.2019, 12:18
    #39762295
256k
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Всем привет! Поговорим про отключение триггеров
Garik888Я для таких случаев я сделал отдельное поле trigger_off
По дефолту оно равно нулю, но если я ставлю туда 1, то в триггере проверяю, если равно 1, то игнорирую всю работу триггера.
Но в этом варианте нужно в этом же триггере менять значение trigger_off всегда на 0

хорошее решение, так можно самому себе сделать головняк
...
Рейтинг: 0 / 0
21.01.2019, 22:21
    #39762555
Garik888
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Всем привет! Поговорим про отключение триггеров
256k хорошее решение, так можно самому себе сделать головняк
Интересно узнать, в чём именно головные? И чем решения с отключением триггера вообще являются НЕ головняком

Сказать по чесноку, желание отключить триггер это не правильно построенная структура базы и не верно построенная логика работы.
Да, бывают исключения которые возникают в процессе работы и мой вариант позволяет учитывать эту логику и контролировать её в случае необходимости. А что будет, если отключать триггер!?!? Это вообще противоречит нормальной работе СУБД!
...
Рейтинг: 0 / 0
22.01.2019, 12:26
    #39762731
gav21
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Всем привет! Поговорим про отключение триггеров
Maxim Boguk,
к сожалению не работает на truncate :(
так же как и alter table t2 disable trigger all;
...
Рейтинг: 0 / 0
22.01.2019, 14:02
    #39762827
Maxim Boguk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Всем привет! Поговорим про отключение триггеров
gav21Maxim Boguk,
к сожалению не работает на truncate :(
так же как и alter table t2 disable trigger all;

А можете минимальный тестовый пример составить и прислать? Или очень странно или баг.

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
...
Рейтинг: 0 / 0
22.01.2019, 15:01
    #39762881
Melkij
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Всем привет! Поговорим про отключение триггеров
gav21Maxim Boguk,
к сожалению не работает на truncate :(
так же как и alter table t2 disable trigger all;
Можете пояснить что именно "не работает на truncate"?
Проверил сейчас, after truncate trigger не вызывается как для session_replication_role=replica так и при disable trigger
...
Рейтинг: 0 / 0
22.01.2019, 15:09
    #39762893
gav21
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Всем привет! Поговорим про отключение триггеров
Melkij,
речь про truncate таблицы с внешним ключем:
postgres=# truncate table t1;
ERROR: cannot truncate a table referenced in a foreign key constraint
DETAIL: Table "t2" references "t1".
HINT: Truncate table "t2" at the same time, or use TRUNCATE ... CASCADE.
...
Рейтинг: 0 / 0
22.01.2019, 15:14
    #39762899
Melkij
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Всем привет! Поговорим про отключение триггеров
gav21,

ну так и должно быть. Триггеры тут ни при чём. Это сам truncate проверяет зависимости.
...
Рейтинг: 0 / 0
31.01.2019, 03:07
    #39767356
PCContra
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Всем привет! Поговорим про отключение триггеров
Maxim BogukPCContra,

После ALTER TABLE a DISABLE TRIGGER log; - никто ничего с этой таблицей сделать не сможет.
Она эксклюзивно заблокирована на вашу сессию.
С нее даже select из другой сессии не сделать не то что запись.

Кстати мог бы и сам проверить.
SELECT делает. UPDATE нет (из под другой сессии). В таблицу логов (под другой сессией) добавилась 1 запись (как и нужно)

Как я тестировал:
Запустил
Код: sql
1.
2.
3.
ALTER TABLE a DISABLE TRIGGER log;
INSERT INTO a(x) VALUES (1), (2), (3);--делается порядка 14 секунд
ALTER TABLE ENABLE TRIGGER log;


Успел переключиться на другую вкладку (под приватным просмотром, сессия другая 100%). Изменил данные в той же таблице. Сравнил количесво строк до и после в таблице логов.

Если кто вообще гуру, то может разобраться почему select делает
...
Рейтинг: 0 / 0
31.01.2019, 04:43
    #39767357
Maxim Boguk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Всем привет! Поговорим про отключение триггеров
PCContraMaxim BogukPCContra,

После ALTER TABLE a DISABLE TRIGGER log; - никто ничего с этой таблицей сделать не сможет.
Она эксклюзивно заблокирована на вашу сессию.
С нее даже select из другой сессии не сделать не то что запись.

Кстати мог бы и сам проверить.
SELECT делает. UPDATE нет (из под другой сессии). В таблицу логов (под другой сессией) добавилась 1 запись (как и нужно)

Как я тестировал:
Запустил
Код: sql
1.
2.
3.
ALTER TABLE a DISABLE TRIGGER log;
INSERT INTO a(x) VALUES (1), (2), (3);--делается порядка 14 секунд
ALTER TABLE ENABLE TRIGGER log;


Успел переключиться на другую вкладку (под приватным просмотром, сессия другая 100%). Изменил данные в той же таблице. Сравнил количесво строк до и после в таблице логов.

Если кто вообще гуру, то может разобраться почему select делает

begin/commit Где? ("Мне надо отключить триггер на одну транзакцию, затем включить его снова." - вот куда вы тут транзакцию потеряли запрошенную).
без Begin/commit у вас каждый запрос - завершенная транзакция.
И вы отключили триггера на таблице не для себя а для всех таким образом.

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Всем привет! Поговорим про отключение триггеров / 17 сообщений из 17, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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