Обсуждение: BUG #1814: Cancelling a CLUSTER changes the OID counter

Поиск
Список
Период
Сортировка

BUG #1814: Cancelling a CLUSTER changes the OID counter

От
"Ian Burrell"
Дата:
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)

Re: BUG #1814: Cancelling a CLUSTER changes the OID counter

От
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).

[ scratches head... ]  Cannot duplicate this here.  Does anyone else
see it?

            regards, tom lane

Re: BUG #1814: Cancelling a CLUSTER changes the OID counter

От
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

Re: BUG #1814: Cancelling a CLUSTER changes the OID counter

От
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

Re: BUG #1814: Cancelling a CLUSTER changes the OID counter

От
Ian Burrell
Дата:
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