Обсуждение: BUG #1814: Cancelling a CLUSTER changes the OID counter
The following bug has been logged online: Bug reference: 1814 Logged by: Ian Burrell Email address: ianburrell@gmail.com PostgreSQL version: 7.4.6 Operating system: RHEL 3 x86_64 Description: Cancelling a CLUSTER changes the OID counter Details: Cancelling a CLUSTER is causing the OID counter to jump forwards. In the test below, it goes from 108 million to 4286 million (close to 2^32). We recently wrapped the OID counter. vodlive=# insert into foo values (1) ; INSERT 108817614 1 Time: 0.675 ms vodlive=# select oid, * from foo ; oid | bar -----------+----- 108817614 | 1 vodlive=# CLUSTER idx_daily_by_cs_ti_wk_wk_cs_ti ON daily_xtns_by_cable_sys_title_wk ; Cancel request sent ERROR: canceling query due to user request vodlive=# abort ; ROLLBACK vodlive=# insert into foo values (1) ; INSERT 4286822632 1 Time: 0.475 ms vodlive=# select oid, * from foo ; oid | bar ------------+----- 4286822632 | 1 (1 row)
"Ian Burrell" <ianburrell@gmail.com> writes: > Cancelling a CLUSTER is causing the OID counter to jump forwards. In the > test below, it goes from 108 million to 4286 million (close to 2^32). [ scratches head... ] Cannot duplicate this here. Does anyone else see it? regards, tom lane
"Ian Burrell" <ianburrell@gmail.com> writes: > Cancelling a CLUSTER is causing the OID counter to jump forwards. In the > test below, it goes from 108 million to 4286 million (close to 2^32). > We recently wrapped the OID counter. Uh, does the same thing happen if you *don't* cancel it? It looks to me like this could possibly happen due to CheckMaxObjectId() being applied to each OID found in the existing table. CheckMaxObjectId was always a kluge, and I'm not sure that it still has any redeeming social value at all. Can anyone think of a good reason to keep it? regards, tom lane
Ian Burrell <ianburrell@gmail.com> writes: > On 8/8/05, Tom Lane <tgl@sss.pgh.pa.us> wrote: >> It looks to me like this could possibly happen due to CheckMaxObjectId() >> being applied to each OID found in the existing table. >> >> CheckMaxObjectId was always a kluge, and I'm not sure that it still has >> any redeeming social value at all. Can anyone think of a good reason >> to keep it? > From looking in the code, I am pretty sure CheckMaxObjectId is the > culprit. It sets the nextOID to the oid in the row if the > assigned_oid is greater than the nextOID. Yeah. This is closely related to my recent speculations about putting in a more direct defense against duplicate OIDs: http://archives.postgresql.org/pgsql-hackers/2005-08/msg00074.php I think if we did that, particularly in the general any-unique-OID-index form suggested here http://archives.postgresql.org/pgsql-hackers/2005-08/msg00247.php then we could feel justified in simply discarding CheckMaxObjectId. We would then have a mechanism that guaranteed OID uniqueness on a per-table basis, but not at all on a cluster-wide basis, which is the mindset that CheckMaxObjectId comes from. In environments where databases live long enough to have OID wraparound, CheckMaxObjectId is worse than useless --- it creates uniqueness problems rather than avoiding them, because it tends to force the OID counter to hover near the high end of the range. Comments? regards, tom lane
On 8/8/05, Tom Lane <tgl@sss.pgh.pa.us> wrote: >=20 > Uh, does the same thing happen if you *don't* cancel it? >=20 Yes. In that case, it change the OID counter to the maximum OID in the table if the OID counter was less than the maximum. This is only a problem when the OID counter has wrapped because until then there are no OID higher than the counter. I have verified it with a couple of different tables different maximum OID; the counter went from 28 million, to 690 million, to 4286 million, to 4294 million. > It looks to me like this could possibly happen due to CheckMaxObjectId() > being applied to each OID found in the existing table. >=20 > CheckMaxObjectId was always a kluge, and I'm not sure that it still has > any redeeming social value at all. Can anyone think of a good reason > to keep it? >=20 =46rom looking in the code, I am pretty sure CheckMaxObjectId is the culprit. It sets the nextOID to the oid in the row if the assigned_oid is greater than the nextOID. We are using PostgreSQL 7.4.6 but it looks like the same code is in 8.0.3. - Ian