Sequence rows need to have FrozenTransactionId

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: pgsql-hackers(at)postgreSQL(dot)org
Cc: "Christian Meunier" <jelan(at)magelo(dot)com>
Subject: Sequence rows need to have FrozenTransactionId
Date: 2002-01-10 21:23:44
Message-ID: 22709.1010697824@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

I believe I see the mechanism for the 7.2b4 failure reported by
Christian Meunier this morning:

> pg_dump: query to get data of sequence "account_num_seq" failed: FATAL 2:
> open of /usr/local/pgsql/data/pg_clog/0000 failed: No such file or directory
> server closed the connection unexpectedly
> This probably means the server terminated abnormally
> before or while processing the request.
>
> The only file i got in directory pg_clog is : 0002

Here's what happened: when the sequence object was created, the single
row inserted in it was given the XID of the transaction creating the
sequence. Let's suppose that the only thing done with the sequence for
a long time was nextval()s, never a "select from account_num_seq". The
row would remain present with unmodified info bits --- ie, same XID,
not known committed. VACUUM ignores sequences, so VACUUMs wouldn't
change the state of the row either. However, in the fullness of time
VACUUM would decide that there could no longer be any unvacuumed
references to the sequence-creating XID, and it would delete the CLOG
segment holding the state of that XID. Later still (this must be more
than a million xacts after the sequence's creation), a pg_dump is done,
and it tries to do "select from account_num_seq", whereupon the CLOG
code is asked for the state of the long-ago transaction. Kaboom.

In short, VACUUM's assumption that it sees and marks every t_xmin in the
database is false, because it doesn't look at sequences, and every
sequence contains a t_xmin field.

I believe that the best way to fix this is for sequence creation to
forcibly mark the sequence's lone tuple with t_xmin =
FrozenTransactionId. In this way, the row will always be considered
good by SELECT with no further ado. This cannot cause any transaction
to see a row that it shouldn't see --- if it can see the sequence
object's entry in pg_class, then it should be able to see the sequence's
tuple.

The alternative, if anyone thinks that's unsafe, is for VACUUM to
process sequences along with plain relations so that it can mark/freeze
sequence rows along with regular rows. But that seems like an awful lot
of cycles expended to solve the problem.

Any objections to doing it the first way?

regards, tom lane

Browse pgsql-hackers by date

  From Date Subject
Next Message Bruce Momjian 2002-01-10 23:40:28 Re: [HACKERS] pg_upgrade
Previous Message Bruce Momjian 2002-01-10 20:08:26 Re: 7.1 vs. 7.2 on AIX 5L