Pull to refresh

Comments 18

Начинали за здравие, закончили за упокой. Основное применение в логировании, но нельзя использовать, так как проблемы с производительностью. И чтоб не выстрелить себе в ногу в самом начале проекта, возьмите лучше вместо PostgreSQL Oracle.
Отчего же, использовать стоит, просто не забывайте о том, что эта операция относительно дорогая.
А причем тут вообще savepoint? Это точка сохранения внутри одной транзакции. Автономная транзакция независима от родительской.
Ну, условно говоря, если у вас случилась ошибка вы прыгаете к сохраненному значению, а потом врубаете обработку ошибки (либо сперва вставляете обработку ошибки, а ву случае успешного прохождения этапа эту обработку ошибки удаляете).
Хотя я тут посмотрел — в функциях использование savepoint может вызывать (либо вызывает — тут уже смотреть надо) ошибку. Обходится RAISE EXCEPTION и блоком
EXCEPTION
WHEN RAISE_EXCEPTION THEN…
Вы сейчас о конкретной задаче, применение автономных транзакций много шире. Конечно же вы можете логировать разными способами и обходить описанную проблему по-разному. Просто savepoint и автономные транзакции это разные вещи, они никак не связаны.
Они разные, разумеется. Просто мой подход (он, вообще говоря, как мне кажется годится не только для логирования)))) позволяет обойтись без PERFORM dblink_exec — а я подозреваю, что именно эта штука и тормозит. Причем тормозит за счет perform. Хотя, опять же, я могу и ошибаться.
Собственно — к сути разговора, когда вы пишете про проблемы с производительностью — какого они плана? Насколько оно тормозит? И на каком железе?
Исключительно шкурный интерес — если вы эту штуку тестировали, вы можете серьезно сэкономить мое время))))
dblink_exec работает медленно из-за того, что создается новое соединение с БД — а это процесс намного более дорогостоящий чем простая запись в таблицу. Поэтому использовать необходимо с умом. Приведу пример: предположим ваша функция состоит из следующих шагов: начало, большой длинный цикл, конец, обработка ошибок.
Вы логируете начало, конец и обработку ошибок с уровнями логирования «INFO» и «ERROR», а внутри цикла с уровнем «DEBUG». Чтобы функция работала как можно быстрее, вы можете отключить логирование с уровнем «DEBUG» (доработать функцию «log» для такого поведения не составит большого труда), и включать логирование «DEBUG» только если приперло и необходимо какое-то серьезное разбирательство.

То есть вы можете избежать потерь производительности просто с умом применяя этот прием, на это я и хотел обратить внимание в конце топика.
Понятно.

Кстати (подозрвеаю, что вам эта информация известна, а вот кому-то из читателей может помочь) — dblink позволяет открыть постоянное соединение — если соответствующим образом скомпоновать функцию, можно дополнительно увеличить производительность.
Да, действительно, dblink_connect для создания persistent соединения и в дальнейшем его использование ощутимо ускорит работу.

Спасибо что указали на это, действительно важный момент.
Что значит «прыгаете к сохраненному значению а потом врубаете обработку ошибок»? Вы по-моему не представляете себе ни как работает rollback to savepoint, ни вообще как обрабатываются исключения.

Вообще говоря — представляю. очень даже.
Там все вообще говоря просто — в блоке (если мы говорим о функции) мы присваиваем переменной некие значения. Например — про то, что следующий блок у нас завершился ошибкой. В следующем блоке мы меняем значение переменной. Как-то примерно так.
Либо, перед окончанием транзакции проверяем (по определенным, напрямую зависящим от транзакции критериям), что именно у нас сработало, а что — нет — (этот способ сравнительно легко гуглится) и обрабатываем результаты.

Но, как я уже писал выше, savepoint в функциях может вызывать (либо вызывает — еще раз вынужден повториться — поскольку сам я эту штуку не тестировал а из найденных обсуждений четкого вывода сделать тоже нельзя — я не знаю, может вызывать, или вызывает) ошибку SPI, посему правильнее и надежнее пользоваться
RAISE EXCEPTION
WHEN RAISE_EXCEPTION THEN
Что-то либо я не понимаю, либо вы бредите.
1. Как мы можем узнать текущем блоке узнать, «что следующий блок завершился ошибкой»?
Нужно в будущее заглядывать?
2. «Либо, перед окончанием транзакции проверяем (по определенным, напрямую зависящим от транзакции критериям), что именно у нас сработало, а что — нет — (этот способ сравнительно легко гуглится) „
Что такое “ перед окончанием транзакции»? Каким образом вы это определите? Вы в курсе, что если возникает исключение, то обработка прерывается, и переходит в блок исключений? Вы в курсе, что rollback to savepoint — это не «прыжок», как вы выразились, а откат изменений?
Вы в курсе, что нельзя переходить из блока исключений обратно в блок операторов?

Возможно, это я вас не понимаю. Может, если вы напишете код, то ситуация прояснится.
Например простая задача: вставить запись в таблицу, записать при этом в лог-таблицу — успешно она вставилась или нет.
Вот за что люблю хабру — если в статье не очень круто ясен смысл, то в комментах всё разрулят и еще кучу всего расскажут ;)
У вас source и message не экранируются, можно легко словить exception там, где не ожидаешь.
За статью спасибо, когда пару месяцев назад жалел об отсутствии автономных транзакций — думали в сторону dbms_pipe (есть в составе какого-то contrib-модуля) и постоянно запускающегося задания для job'а для получения и записи лога, про dblink не подумали.
Увы, job'ы в postgresql реализованы тоже так себе, чаще раза в две минуты штатными средствами запустить не удаётся. Данное решение отмели как либо ненадёжное (теряются сообщения при переполнении очереди), либо вызывающее проблемы с производительностью (sleep от процесса, записывающего лог, при переполнении очереди).
В итоге написали c-функцию, которая пишет лог в файл. Для нашей задачи это решение подходило, проблем с производительностью вроде нет :)
Да, pgagent не радует. Этот его 2-х минутный период сильно обламывает, не понимаю что им мешает добавить секунды в шедулер.

А насчет c-функции — мне логи все-таки хочется видеть в таблице. Это, конечно, вопрос вкуса, но мне например лень лезть в шелл и грепать файл вместо того, чтобы написать селект.
UFO just landed and posted this here
Хорошая штука, сохранил в закладках, спасибо.
Sign up to leave a comment.

Articles