On Wed, 2022-09-21 at 16:22 +0000, Dirschel, Steve wrote: > > > > > We are troubleshooting an issue where autovacuum is not cleaning up a table. > > > > > The application using this database runs with autocommit turned off. > > > > > We can see in pg_stat_activity lots of sessions “idle in transaction” > > > > > even though those sessions have not executed any DML- they have > > > > > executed selects but no DML. The database’s isolation level is set to read committed. > > > > > > > > "backend_xmin" is set when the session has an active snapshot. Such a snapshot is held > > > > for the whole duration of a transaction in the REPEATABLE READ isolation level, but > > > > there are cases where you can see that in READ COMMITTED isolation level as well: > > > > > > > > - if there is a long running query > > > > > > > > - if there is a cursor open > > > > > > > > Perhaps you could ask your developers if they have long running read-only transactions with cursors. > > > > > > Thanks for the reply Laurenz. For an application session in this "state" pg_stat_activity > > > shows the state of "idle in transaction" and backend_xmin is populated. The query shows the > > > last select query it ran. It is not currently executing a query. And dev has said they are > > > not using a cursor for the query. So it does not appear they have long running read-only > > > transactions with cursors. That does not follow. You can execute: DECLARE c CURSOR FOR SELECT /* whatever */; FETCH 50 FROM c; SELECT /* something entirely different */ So you have an open cursor (portal), even though the last statement executed does not use a cursor at all. > > > Outside that scenario can you think of any others where a session: > > > 1. Login to the database > > > 2. Set autocommit off > > > 3. Run select query, query completes, session does nothing after that query completes. > > > 4. transaction isolation level is read committed No. > > > That session sitting there idle in transaction has backend_xmin populated. When I run that > > > test backend_xmin does not get populated unless I set my transaction isolation level to > > > repeatable read. We have enabled statement logging so we can see if their sessions are > > > changing that transaction isolation level behind the scenes that they are not aware of > > > but so far we have not seen that type of command logged. > > > > What stack is the application using? Anything like Spring or Hibernate involved? > > Java is the stack. I'm not saying that you shouldn't trust your developers, but they may be using a cursor without being aware of it. If they use "setFetchSize()" to set a fetch size different from 0, they *are* using a cursor. Yours, Laurenz Albe -- Cybertec | https://www.cybertec-postgresql.com