Обсуждение: OID question

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

OID question

От
Chris Kratz
Дата:
Hello all,

We have a live server running on PG 8.0.3 which we backup on a regular bases
by doing a pg_dumpall --oids.  We have a test server currently running 8.1.1
where we reload that dumpall using psql.

Now we have a history tracking system in the db which via triggers and rules
keeps track of changes to certain tables via OID and logs them in history
tables.  Now our problem is that when we load the db from 8.0.3 into the
8.1.1 db, the current data with all the oids is loaded correctly.  But, as
soon as we try to add rows (new data created during testing), we run into a
problem where the OID on the testing machine has collisions with data that
was loaded from the live server.

I've been searching for awhile on further information about OID and haven't
been real successfull.   Any pointers would be helpfull...

1.  Is OID stored per cluster, or is it per database?  I assume it's per
cluster since databases appear to have an OID.

2. Is there any way to get the test machine to have it's OID reset to the
current live server OID after a reload so we don't get OID collisions?

We aren't sure at this point if the problem we are having has to do with the
fact that we drop and reload the test db quite often and so we are running
into OID wraparound, or if it has to do with the fact that we recently went
to 8.1 on this test machine and OID is now handled differently on reload.

Anyt thoughts or suggestions?

-Chris

Re: OID question

От
Tom Lane
Дата:
Chris Kratz <chris.kratz@vistashare.com> writes:
> We aren't sure at this point if the problem we are having has to do with the
> fact that we drop and reload the test db quite often and so we are running
> into OID wraparound, or if it has to do with the fact that we recently went
> to 8.1 on this test machine and OID is now handled differently on reload.

We did change the handling of OIDs in 8.1, specifically this patch:
http://archives.postgresql.org/pgsql-committers/2005-08/msg00109.php
which ensued from this discussion:
http://archives.postgresql.org/pgsql-hackers/2005-08/msg00074.php

Pre-8.1 versions contained a kluge that made COPY FROM ... WITH OIDS
increase the OID counter to be at least the maximum of the OIDs loaded
into the table.  The lack of this hack is what's making the collision
problem manifest almost immediately for you.  However, you would have
had a problem eventually anyway, because the OID counter is only 32 bits
and will eventually wrap around.

So the first thing to ask yourself is whether depending on OID
uniqueness is a sane design decision at all.  IMHO the answer is
no unless (1) the tables you need OIDs for will never exceed 2^32
rows, or even reach any significant fraction of that, and (2) you
aren't assuming global uniqueness of OIDs but only per-table uniqueness.
(NOTE: you can create a database-wide unique identifier by combining
tableoid and row OID, if necessary.)

Assuming you meet those sanity checks, the way to do this in 8.1 is
to create a unique index on OID for each table you need unique OIDs
in.  This not only is needed anyway to enforce the design assumption,
but the presence of such an index triggers the code we added to 8.1
to select an unused OID.
http://developer.postgresql.org/cvsweb.cgi/pgsql/doc/src/sgml/ddl.sgml.diff?r1=1.42&r2=1.43

            regards, tom lane

Re: OID question

От
Chris Kratz
Дата:
Thank you Tom for your concise response.  Your explanation is very helpfull.
We were aware of the wraparound issues, but this has worked so well for us
that we haven't explored changing it yet.  Having a unique identifier per row
is most usefull in our situation and we didn't think we were anywhere near
wraparound on our live machine, hence we've let it ride.

It sounds like we will need to start thinking about migrating to the
tableoid+rowoid at some point.

Thanks again,

-Chris

On Wednesday 01 February 2006 09:53 am, you wrote:
> Chris Kratz <chris.kratz@vistashare.com> writes:
> > We aren't sure at this point if the problem we are having has to do with
> > the fact that we drop and reload the test db quite often and so we are
> > running into OID wraparound, or if it has to do with the fact that we
> > recently went to 8.1 on this test machine and OID is now handled
> > differently on reload.
>
> We did change the handling of OIDs in 8.1, specifically this patch:
> http://archives.postgresql.org/pgsql-committers/2005-08/msg00109.php
> which ensued from this discussion:
> http://archives.postgresql.org/pgsql-hackers/2005-08/msg00074.php
>
> Pre-8.1 versions contained a kluge that made COPY FROM ... WITH OIDS
> increase the OID counter to be at least the maximum of the OIDs loaded
> into the table.  The lack of this hack is what's making the collision
> problem manifest almost immediately for you.  However, you would have
> had a problem eventually anyway, because the OID counter is only 32 bits
> and will eventually wrap around.
>
> So the first thing to ask yourself is whether depending on OID
> uniqueness is a sane design decision at all.  IMHO the answer is
> no unless (1) the tables you need OIDs for will never exceed 2^32
> rows, or even reach any significant fraction of that, and (2) you
> aren't assuming global uniqueness of OIDs but only per-table uniqueness.
> (NOTE: you can create a database-wide unique identifier by combining
> tableoid and row OID, if necessary.)
>
> Assuming you meet those sanity checks, the way to do this in 8.1 is
> to create a unique index on OID for each table you need unique OIDs
> in.  This not only is needed anyway to enforce the design assumption,
> but the presence of such an index triggers the code we added to 8.1
> to select an unused OID.
> http://developer.postgresql.org/cvsweb.cgi/pgsql/doc/src/sgml/ddl.sgml.diff
>?r1=1.42&r2=1.43
>
>             regards, tom lane