2015-11-19 3 views
6

Я нашел ошибку в своем коде приложения, где я начал транзакцию, но никогда не совершаю или откатываю. Соединение используется периодически, просто считывая некоторые данные каждые 10 или около того. В таблице pg_stat_activity его состояние сообщается как «незанятое в транзакции», а его время backend_start составляет более недели назад.Каковы последствия неисполнения транзакции базы данных?

Какое влияние оказывает на базу данных? Это вызывает дополнительное использование ЦП и ОЗУ? Будет ли это влиять на другие соединения? Как долго он может сохраняться в этом состоянии?

Я использую postgresql 9.1 и 9.4.

+0

Удары: 1. Ваши данные не видны другим транзакциям 2.если вы в конечном итоге не совершаете - вы теряете свои данные. – zerkms

+0

@zerkms Меня больше интересует влияние обработки на сервере: я понимаю, что любые внесенные изменения не будут видны другим соединениям (хотя в этом случае это только чтение данных, никогда не изменяющее ничего) – wolfcastle

+0

Потеря данных не в конце концов, вы можете всегда использовать SAVEPOINTS. – Madthew

ответ

10

Поскольку вы только SELECT, воздействие ограничено. Это более тяжело для любых операций записи, когда изменения не видны для какой-либо другой транзакции до тех пор, пока они не будут совершены, и потеряны, если они не будут совершены.

Это делает стоимость некоторых RAM и постоянно занимает один из ваших разрешенных соединений (которые могут иметь или не иметь значения).

Один из наиболее тяжелых последствий очень длительных транзакций: он блокирует VACUUM от выполнения его работы, поскольку по-прежнему существует старая транзакция, которая может видеть старые строки. Система начнет раздуваться.

В частности, SELECT приобретает блокировку ACCESS SHARE (наименьшая блокировка всех) на всех ссылочных таблицах. Это не мешает другим DML команды, как INSERT, UPDATE или DELETE, но это будет команды блок-DDL-, а также TRUNCATE или VACUUM (в том числе рабочих мест автовакуума). See "Table-level Locks" in the manual.

Он также может мешать различные репликации решений и привести к идентификатор транзакции оберточного в долгосрочной перспективе, если он остается открытым достаточно долго/вы сжигаете достаточно XIDs достаточно быстро. Подробнее об этом in the manual on "Routine Vacuuming".

Блокирующие эффекты могут быть заблокированы из-за того, что другие транзакции заблокированы и у них есть собственные замки. Etc.

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

+0

Он просто блокирует VACUUM для таблиц, используемых в транзакции, или всех таблиц? – wolfcastle

+0

@wolfcastle: Только те, которые указаны в транзакции (в любом случае!). Имейте в виду, что эффект может гриб ... Я добавил еще несколько выше. –

+2

Фактически, 'VACUUM' может обрабатывать таблицу, которая заблокирована для' ACCESS SHARE', с помощью виртуального xid. Однако он не может усечь его, чтобы освободить место обратно в ОС. Если транзакция является «SERIALIZABLE» или имеет текущее выполнение, она не может удалить мертвые строки, созданные параллельными обновлениями/удалениями. Попробуй сам. Создайте таблицу с фиктивными строками. Запустите xact и выберите из таблицы, чтобы заблокировать его. Начните новый xact и удалите половину строк, но еще не зафиксируйте. 'VACUUM VERBOSE' с другого сеанса. Он удалит мертвые строки. –

3

В системе действуют два основных воздействия.

Таблицы, которые были использованы в этих операциях:

  1. не vacuumed означает, что они не «очищены» и их статистика не обновляется, которые могут привести к плохим (= медленные) планы выполнения
  2. не могут быть изменены с помощью ALTER TABLE
Смежные вопросы