I have found a bug in my application code where I have started a transaction, but never commit or do a rollback. The connection is used periodically, just reading some data every 10s or so. In the pg_stat_activity
table, its state is reported as "idle in transaction", and its backend_start
time is over a week ago.
What is the impact on the database of this? Does it cause additional CPU and RAM usage? Will it impact other connections? How long can it persist in this state?
I'm using postgresql 9.1 and 9.4.
A transaction ends when any of the following actions occurs: A user issues a COMMIT or ROLLBACK statement without a SAVEPOINT clause. In a commit, a user explicitly or implicitly requested that the changes in the transaction be made permanent. Changes made by the transaction are permanent and visible to other users only after a transaction commits.
After a transaction completes, the database ensures through its recovery mechanisms that changes from the transaction are not lost. The use of transactions is one of the most important ways that a database management system differs from a file system.
For example, if a transaction starts updating 100 rows, but the system fails after 20 updates, then the database rolls back the changes to these 20 rows. The transaction takes the database from one consistent state to another consistent state.
Following a communication failure, the database may still be running the submission and be unaware that the client disconnected. Checking the transaction state does not guarantee that an active transaction will not commit after being checked.
Since you only SELECT
, the impact is limited. It is more severe for any write operations, where the changes are not visible to any other transaction until committed - and lost if never committed.
It does cost some RAM and permanently occupies one of your allowed connections (which may or may not matter).
One of the more severe consequences of very long running transactions: It blocks VACUUM
from doing it's job, since there is still an old transaction that can see old rows. The system will start bloating.
In particular, SELECT
acquires an ACCESS SHARE
lock (the least blocking of all) on all referenced tables. This does not interfere with other DML commands like INSERT
, UPDATE
or DELETE
, but it will block DDL commands as well as TRUNCATE
or VACUUM
(including autovacuum jobs). See "Table-level Locks" in the manual.
It can also interfere with various replication solutions and lead to transaction ID wraparound in the long run if it stays open long enough / you burn enough XIDs fast enough. More about that in the manual on "Routine Vacuuming".
Blocking effects can mushroom if other transactions are blocked from committing and those have acquired locks of their own. Etc.
You can keep transactions open (almost) indefinitely - until the connection is closed (which also happens when the server is restarted, obviously.)
But never leave transactions open longer than needed.
There are two major impacts to the system.
The tables that have been used in those transactions:
ALTER TABLE
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With