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


Reply via email to