]> granicus.if.org Git - postgresql/blob - src/backend/access/transam/varsup.c
Remove NEXTXID xlog record type to avoid three-way deadlock risk.
[postgresql] / src / backend / access / transam / varsup.c
1 /*-------------------------------------------------------------------------
2  *
3  * varsup.c
4  *        postgres OID & XID variables support routines
5  *
6  * Copyright (c) 2000, PostgreSQL Global Development Group
7  *
8  * IDENTIFICATION
9  *        $Header: /cvsroot/pgsql/src/backend/access/transam/varsup.c,v 1.37 2001/03/18 20:18:59 tgl Exp $
10  *
11  *-------------------------------------------------------------------------
12  */
13
14 #include "postgres.h"
15
16 #include "access/transam.h"
17 #include "access/xlog.h"
18 #include "storage/proc.h"
19
20
21 /* Number of XIDs and OIDs to prefetch (preallocate) per XLOG write */
22 #define VAR_XID_PREFETCH                1024
23 #define VAR_OID_PREFETCH                8192
24
25 /* Spinlocks for serializing generation of XIDs and OIDs, respectively */
26 SPINLOCK XidGenLockId;
27 SPINLOCK OidGenLockId;
28
29 /* pointer to "variable cache" in shared memory (set up by shmem.c) */
30 VariableCache ShmemVariableCache = NULL;
31
32 void
33 GetNewTransactionId(TransactionId *xid)
34 {
35         /*
36          * During bootstrap initialization, we return the special
37          * bootstrap transaction id.
38          */
39         if (AMI_OVERRIDE)
40         {
41                 *xid = AmiTransactionId;
42                 return;
43         }
44
45         SpinAcquire(XidGenLockId);
46
47         *xid = ShmemVariableCache->nextXid;
48
49         (ShmemVariableCache->nextXid)++;
50
51         SpinRelease(XidGenLockId);
52
53         if (MyProc != (PROC *) NULL)
54                 MyProc->xid = *xid;
55 }
56
57 /*
58  * Read nextXid but don't allocate it.
59  */
60 void
61 ReadNewTransactionId(TransactionId *xid)
62 {
63         /*
64          * During bootstrap initialization, we return the special
65          * bootstrap transaction id.
66          */
67         if (AMI_OVERRIDE)
68         {
69                 *xid = AmiTransactionId;
70                 return;
71         }
72
73         SpinAcquire(XidGenLockId);
74         *xid = ShmemVariableCache->nextXid;
75         SpinRelease(XidGenLockId);
76 }
77
78 /* ----------------------------------------------------------------
79  *                                      object id generation support
80  * ----------------------------------------------------------------
81  */
82
83 static Oid lastSeenOid = InvalidOid;
84
85 void
86 GetNewObjectId(Oid *oid_return)
87 {
88         SpinAcquire(OidGenLockId);
89
90         /* If we run out of logged for use oids then we must log more */
91         if (ShmemVariableCache->oidCount == 0)
92         {
93                 XLogPutNextOid(ShmemVariableCache->nextOid + VAR_OID_PREFETCH);
94                 ShmemVariableCache->oidCount = VAR_OID_PREFETCH;
95         }
96
97         if (PointerIsValid(oid_return))
98                 lastSeenOid = (*oid_return) = ShmemVariableCache->nextOid;
99
100         (ShmemVariableCache->nextOid)++;
101         (ShmemVariableCache->oidCount)--;
102
103         SpinRelease(OidGenLockId);
104 }
105
106 void
107 CheckMaxObjectId(Oid assigned_oid)
108 {
109         if (lastSeenOid != InvalidOid && assigned_oid < lastSeenOid)
110                 return;
111
112         SpinAcquire(OidGenLockId);
113
114         if (assigned_oid < ShmemVariableCache->nextOid)
115         {
116                 lastSeenOid = ShmemVariableCache->nextOid - 1;
117                 SpinRelease(OidGenLockId);
118                 return;
119         }
120
121         /* If we are in the logged oid range, just bump nextOid up */
122         if (assigned_oid <= ShmemVariableCache->nextOid + 
123                                                 ShmemVariableCache->oidCount - 1)
124         {
125                 ShmemVariableCache->oidCount -= 
126                         assigned_oid - ShmemVariableCache->nextOid + 1;
127                 ShmemVariableCache->nextOid = assigned_oid + 1;
128                 SpinRelease(OidGenLockId);
129                 return;
130         }
131
132         /*
133          * We have exceeded the logged oid range.
134          * We should lock the database and kill all other backends
135          * but we are loading oid's that we can not guarantee are unique
136          * anyway, so we must rely on the user.
137          */
138
139         XLogPutNextOid(assigned_oid + VAR_OID_PREFETCH);
140         ShmemVariableCache->oidCount = VAR_OID_PREFETCH - 1;
141         ShmemVariableCache->nextOid = assigned_oid + 1;
142
143         SpinRelease(OidGenLockId);
144 }