8000 Solve the problem of OID collisions by probing for duplicate OIDs · postgrespro/postgres_cluster@721e537 · GitHub
[go: up one dir, main page]

Skip to content

Commit 721e537

Browse files
committed
Solve the problem of OID collisions by probing for duplicate OIDs
whenever we generate a new OID. This prevents occasional duplicate-OID errors that can otherwise occur once the OID counter has wrapped around. Duplicate relfilenode values are also checked for when creating new physical files. Per my recent proposal.
1 parent 9e4a2de commit 721e537

File tree

20 files changed

+411
-263
lines changed
  • commands
  • storage/large_object
  • utils/cache
  • bin/pg_dump
  • include
  • 20 files changed

    +411
    -263
    lines changed

    doc/src/sgml/ddl.sgml

    Lines changed: 11 additions & 6 deletions
    Original file line numberDiff line numberDiff line change
    @@ -1,4 +1,4 @@
    1-
    <!-- $PostgreSQL: pgsql/doc/src/sgml/ddl.sgml,v 1.42 2005/07/14 06:17:35 neilc Exp $ -->
    1+
    <!-- $PostgreSQL: pgsql/doc/src/sgml/ddl.sgml,v 1.43 2005/08/12 01:35:53 tgl Exp $ -->
    22

    33
    <chapter id="ddl">
    44
    <title>Data Definition</title>
    @@ -871,7 +871,7 @@ CREATE TABLE order_items (
    871871
    The object identifier (object ID) of a row. This column is only
    872872
    present if the table was created using <literal>WITH
    873873
    OIDS</literal>, or if the <xref linkend="guc-default-with-oids">
    874-
    configuration variable was enabled. This column is of type
    874+
    configuration variable was set. This column is of type
    875875
    <type>oid</type> (same name as the column); see <xref
    876876
    linkend="datatype-oid"> for more information about the type.
    877877
    </para>
    @@ -992,7 +992,13 @@ CREATE TABLE order_items (
    992992
    <listitem>
    993993
    <para>
    994994
    A unique constraint should be created on the OID column of each
    995-
    table for which the OID will be used to identify rows.
    995+
    table for which the OID will be used to identify rows. When such
    996+
    a unique constraint (or unique index) exists, the system takes
    997+
    care not to generate an OID matching an already-existing row.
    998+
    (Of course, this is only possible if the table contains fewer
    999+
    than 2<superscript>32</> (4 billion) rows, and in practice the
    1000+
    table size had better be much less than that, or performance
    1001+
    may suffer.)
    9961002
    </para>
    9971003
    </listitem>
    9981004
    <listitem>
    @@ -1005,9 +1011,8 @@ CREATE TABLE order_items (
    10051011
    <listitem>
    10061012
    <para>
    10071013
    The tables in question should be created using <literal>WITH
    1008-
    OIDS</literal> to ensure forward compatibility with future
    1009-
    releases of <productname>PostgreSQL</productname>. It is
    1010-
    planned that <literal>WITHOUT OIDS</> will become the default.
    1014+
    OIDS</literal>. As of <productname>PostgreSQL</productname> 8.1,
    1015+
    <literal>WITHOUT OIDS</> is the default.
    10111016
    </para>
    10121017
    </listitem>
    10131018
    </itemizedlist>

    src/backend/access/heap/heapam.c

    Lines changed: 2 additions & 4 deletions
    Original file line numberDiff line numberDiff line change
    @@ -8,7 +8,7 @@
    88
    *
    99
    *
    1010
    * IDENTIFICATION
    11-
    * $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.196 2005/08/01 20:31:05 tgl Exp $
    11+
    * $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.197 2005/08/12 01:35:54 tgl Exp $
    1212
    *
    1313
    *
    1414
    * INTERFACE ROUTINES
    @@ -1069,9 +1069,7 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid,
    10691069
    * pointers to one another).
    10701070
    */
    10711071
    if (!OidIsValid(HeapTupleGetOid(tup)))
    1072-
    HeapTupleSetOid(tup, newoid());
    1073-
    else
    1074-
    CheckMaxObjectId(HeapTupleGetOid(tup));
    1072+
    HeapTupleSetOid(tup, GetNewOid(relation));
    10751073
    }
    10761074
    else
    10771075
    {

    src/backend/access/heap/tuptoaster.c

    Lines changed: 14 additions & 7 deletions
    Original file line numberDiff line numberDiff line change
    @@ -8,7 +8,7 @@
    88
    *
    99
    *
    1010
    * IDENTIFICATION
    11-
    * $PostgreSQL: pgsql/src/backend/access/heap/tuptoaster.c,v 1.51 2005/08/02 16:11:57 tgl Exp $
    11+
    * $PostgreSQL: pgsql/src/backend/access/heap/tuptoaster.c,v 1.52 2005/08/12 01:35:54 tgl Exp $
    1212
    *
    1313
    *
    1414
    * INTERFACE ROUTINES
    @@ -1006,6 +1006,15 @@ toast_save_datum(Relation rel, Datum value)
    10061006
    char *data_p;
    10071007
    int32 data_todo;
    10081008

    1009+
    /*
    1010+
    * Open the toast relation and its index. We can use the index to
    1011+
    * check uniqueness of the OID we assign to the toasted item, even
    1012+
    * though it has additional columns besides OID.
    1013+
    */
    1014+
    toastrel = heap_open(rel->rd_rel->reltoastrelid, RowExclusiveLock);
    1015+
    toasttupDesc = toastrel->rd_att;
    1016+
    toastidx = index_open(toastrel->rd_rel->reltoastidxid);
    1017+
    10091018
    /*
    10101019
    * Create the varattrib reference
    10111020
    */
    @@ -1023,7 +1032,8 @@ toast_save_datum(Relation rel, Datum value)
    10231032

    10241033
    result->va_content.va_external.va_extsize =
    10251034
    VARATT_SIZE(value) - VARHDRSZ;
    1026-
    result->va_content.va_external.va_valueid = newoid();
    1035+
    result->va_content.va_external.va_valueid =
    1036+
    GetNewOidWithIndex(toastrel, toastidx);
    10271037
    result->va_content.va_external.va_toastrelid =
    10281038
    rel->rd_rel->reltoastrelid;
    10291039

    @@ -1043,12 +1053,9 @@ toast_save_datum(Relation rel, Datum value)
    10431053
    data_todo = VARATT_SIZE(value) - VARHDRSZ;
    10441054

    10451055
    /*
    1046-
    * Open the toast relation. We must explicitly lock the toast index
    1047-
    * because we aren't using an index scan here.
    1056+
    * We must explicitly lock the toast index because we aren't using an
    1057+
    * index scan here.
    10481058
    */
    1049-
    toastrel = heap_open(rel->rd_rel->reltoastrelid, RowExclusiveLock);
    1050-
    toasttupDesc = toastrel->rd_att;
    1051-
    toastidx = index_open(toastrel->rd_rel->reltoastidxid);
    10521059
    LockRelation(toastidx, RowExclusiveLock);
    10531060

    10541061
    /*

    src/backend/access/transam/varsup.c

    Lines changed: 13 additions & 50 deletions
    Original file line numberDiff line numberDiff line change
    @@ -6,7 +6,7 @@
    66
    * Copyright (c) 2000-2005, PostgreSQL Global Development Group
    77
    *
    88
    * IDENTIFICATION
    9-
    * $PostgreSQL: pgsql/src/backend/access/transam/varsup.c,v 1.64 2005/05/19 21:35:45 tgl Exp $
    9+
    * $PostgreSQL: pgsql/src/backend/access/transam/varsup.c,v 1.65 2005/08/12 01:35:55 tgl Exp $
    1010
    *
    1111
    *-------------------------------------------------------------------------
    1212
    */
    @@ -247,13 +247,16 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid,
    247247
    }
    248248

    249249

    250-
    /* ----------------------------------------------------------------
    251-
    * object id generation support
    252-
    * ----------------------------------------------------------------
    250+
    /*
    251+
    * GetNewObjectId -- allocate a new OID
    252+
    *
    253+
    * OIDs are generated by a cluster-wide counter. Since they are only 32 bits
    254+
    * wide, counter wraparound will occur eventually, and therefore it is unwise
    255+
    * to assume they are unique unless precautions are taken to make them so.
    256+
    * Hence, this routine should generally not be used directly. The only
    257+
    * direct callers should be GetNewOid() and GetNewRelFileNode() in
    258+
    * catalog/catalog.c.
    253259
    */
    254-
    255-
    static Oid lastSeenOid = InvalidOid;
    256-
    257260
    Oid
    258261
    GetNewObjectId(void)
    259262
    {
    @@ -265,8 +268,9 @@ GetNewObjectId(void)
    265268
    * Check for wraparound of the OID counter. We *must* not return 0
    266269
    * (InvalidOid); and as long as we have to check that, it seems a good
    267270
    * idea to skip over everything below FirstNormalObjectId too. (This
    268-
    * basically just reduces the odds of OID collision right after a wrap
    269-
    * occurs.) Note we are relying on unsigned comparison here.
    271+
    * basically just avoids lots of collisions with bootstrap-assigned OIDs
    272+
    * right after a wrap occurs, so as to avoid a possibly large number of
    273+
    * iterations in GetNewOid.) Note we are relying on unsigned comparison.
    270274
    *
    271275
    * During initdb, we start the OID generator at FirstBootstrapObjectId,
    272276
    * so we only enforce wrapping to that point when in bootstrap or
    @@ -310,46 +314,5 @@ GetNewObjectId(void)
    310314

    311315
    LWLockRelease(OidGenLock);
    312316

    313-
    lastSeenOid = result;
    314-
    315317
    return result;
    316318
    }
    317-
    318-
    void
    319-
    CheckMaxObjectId(Oid assigned_oid)
    320-
    {
    321-
    if (lastSeenOid != InvalidOid && assigned_oid < lastSeenOid)
    322-
    return;
    323-
    324-
    LWLockAcquire(OidGenLock, LW_EXCLUSIVE);
    325-
    326-
    if (assigned_oid < ShmemVariableCache->nextOid)
    327-
    {
    328-
    lastSeenOid = ShmemVariableCache->nextOid - 1;
    329-
    LWLockRelease(OidGenLock);
    330-
    return;
    331-
    }
    332-
    333-
    /* If we are in the logged oid range, just bump nextOid up */
    334-
    if (assigned_oid <= ShmemVariableCache->nextOid +
    335-
    ShmemVariableCache->oidCount - 1)
    336-
    {
    337-
    ShmemVariableCache->oidCount -=
    338-
    assigned_oid - ShmemVariableCache->nextOid + 1;
    339-
    ShmemVariableCache->nextOid = assigned_oid + 1;
    340-
    LWLockRelease(OidGenLock);
    341-
    return;
    342-
    }
    343-
    344-
    /*
    345-
    * We have exceeded the logged oid range. We should lock the database
    346-
    * and kill all other backends but we are loading oid's that we can
    347-
    * not guarantee are unique anyway, so we must rely on the user.
    348-
    */
    349-
    350-
    XLogPutNextOid(assigned_oid + VAR_OID_PREFETCH);
    351-
    ShmemVariableCache->nextOid = assigned_oid + 1;
    352-
    ShmemVariableCache->oidCount = VAR_OID_PREFETCH - 1;
    353-
    354-
    LWLockRelease(OidGenLock);
    355-
    }

    0 commit comments

    Comments
     (0)
    0