Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit742cd87

Browse files
committed
Ensure that if the OID counter wraps around, we will not generate 0,
nor any OID in the reserved range (1-16383).
1 parent667d5ed commit742cd87

File tree

1 file changed

+83
-91
lines changed

1 file changed

+83
-91
lines changed

‎src/backend/access/transam/varsup.c

Lines changed: 83 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/access/transam/varsup.c,v 1.28 2000/04/12 17:14:53 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/access/transam/varsup.c,v 1.29 2000/07/25 20:18:19 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -22,16 +22,21 @@
2222
staticvoidGetNewObjectIdBlock(Oid*oid_return,intoid_block_size);
2323
staticvoidVariableRelationGetNextOid(Oid*oid_return);
2424
staticvoidVariableRelationGetNextXid(TransactionId*xidP);
25-
staticvoidVariableRelationPutNextOid(Oid*oidP);
25+
staticvoidVariableRelationPutNextOid(Oidoid);
2626

2727
/* ---------------------
2828
*spin lock for oid generation
2929
* ---------------------
3030
*/
3131
intOidGenLockId;
3232

33+
/* ---------------------
34+
*pointer to "variable cache" in shared memory (set up by shmem.c)
35+
* ---------------------
36+
*/
3337
VariableCacheShmemVariableCache=NULL;
3438

39+
3540
/* ----------------------------------------------------------------
3641
* variable relation query/update routines
3742
* ----------------------------------------------------------------
@@ -48,7 +53,7 @@ VariableRelationGetNextXid(TransactionId *xidP)
4853
VariableRelationContentsvar;
4954

5055
/* ----------------
51-
* We assume that a spinlock has beenacquire to guarantee
56+
* We assume that a spinlock has beenacquired to guarantee
5257
* exclusive access to the variable relation.
5358
* ----------------
5459
*/
@@ -76,6 +81,7 @@ VariableRelationGetNextXid(TransactionId *xidP)
7681
var= (VariableRelationContents)BufferGetBlock(buf);
7782

7883
TransactionIdStore(var->nextXidData,xidP);
84+
7985
ReleaseBuffer(buf);
8086
}
8187

@@ -90,7 +96,7 @@ VariableRelationPutNextXid(TransactionId xid)
9096
VariableRelationContentsvar;
9197

9298
/* ----------------
93-
* We assume that a spinlock has beenacquire to guarantee
99+
* We assume that a spinlock has beenacquired to guarantee
94100
* exclusive access to the variable relation.
95101
* ----------------
96102
*/
@@ -133,22 +139,20 @@ VariableRelationGetNextOid(Oid *oid_return)
133139
VariableRelationContentsvar;
134140

135141
/* ----------------
136-
* We assume that a spinlock has beenacquire to guarantee
142+
* We assume that a spinlock has beenacquired to guarantee
137143
* exclusive access to the variable relation.
138144
* ----------------
139145
*/
140146

141147
/* ----------------
142148
*if the variable relation is not initialized, then we
143149
*assume we are running at bootstrap time and so we return
144-
*an invalid object id -- during this time GetNextBootstrapObjectId
145-
*should be called instead..
150+
*an invalid object id (this path should never be taken, probably).
146151
* ----------------
147152
*/
148153
if (!RelationIsValid(VariableRelation))
149154
{
150-
if (PointerIsValid(oid_return))
151-
(*oid_return)=InvalidOid;
155+
(*oid_return)=InvalidOid;
152156
return;
153157
}
154158

@@ -162,32 +166,12 @@ VariableRelationGetNextOid(Oid *oid_return)
162166
if (!BufferIsValid(buf))
163167
{
164168
SpinRelease(OidGenLockId);
165-
elog(ERROR,"VariableRelationGetNextXid: ReadBuffer failed");
169+
elog(ERROR,"VariableRelationGetNextOid: ReadBuffer failed");
166170
}
167171

168172
var= (VariableRelationContents)BufferGetBlock(buf);
169173

170-
if (PointerIsValid(oid_return))
171-
{
172-
173-
/* ----------------
174-
* nothing up my sleeve...what's going on here is that this code
175-
* is guaranteed never to be called until all files in data/base/
176-
* are created, and the template database exists. at that point,
177-
* we want to append a pg_database tuple. the first time we do
178-
* this, the oid stored in pg_variable will be bogus, so we use
179-
* a bootstrap value defined at the top of this file.
180-
*
181-
* this comment no longer holds true. This code is called before
182-
* all of the files in data/base are created and you can't rely
183-
* on system oid's to be less than BootstrapObjectIdData. mer 9/18/91
184-
* ----------------
185-
*/
186-
if (OidIsValid(var->nextOid))
187-
(*oid_return)=var->nextOid;
188-
else
189-
(*oid_return)=BootstrapObjectIdData;
190-
}
174+
(*oid_return)=var->nextOid;
191175

192176
ReleaseBuffer(buf);
193177
}
@@ -197,13 +181,13 @@ VariableRelationGetNextOid(Oid *oid_return)
197181
* --------------------------------
198182
*/
199183
staticvoid
200-
VariableRelationPutNextOid(Oid*oidP)
184+
VariableRelationPutNextOid(Oidoid)
201185
{
202186
Bufferbuf;
203187
VariableRelationContentsvar;
204188

205189
/* ----------------
206-
* We assume that a spinlock has beenacquire to guarantee
190+
* We assume that a spinlock has beenacquired to guarantee
207191
* exclusive access to the variable relation.
208192
* ----------------
209193
*/
@@ -215,16 +199,6 @@ VariableRelationPutNextOid(Oid *oidP)
215199
if (!RelationIsValid(VariableRelation))
216200
return;
217201

218-
/* ----------------
219-
*sanity check
220-
* ----------------
221-
*/
222-
if (!PointerIsValid(oidP))
223-
{
224-
SpinRelease(OidGenLockId);
225-
elog(ERROR,"VariableRelationPutNextOid: invalid oid pointer");
226-
}
227-
228202
/* ----------------
229203
*read the variable page, update the nextXid field and
230204
*write the page back out to disk.
@@ -240,7 +214,7 @@ VariableRelationPutNextOid(Oid *oidP)
240214

241215
var= (VariableRelationContents)BufferGetBlock(buf);
242216

243-
var->nextOid=(*oidP);
217+
var->nextOid=oid;
244218

245219
WriteBuffer(buf);
246220
}
@@ -253,20 +227,20 @@ VariableRelationPutNextOid(Oid *oidP)
253227
/* ----------------
254228
*GetNewTransactionId
255229
*
256-
*In the version 2 transaction system, transaction id's are
257-
*restricted in several ways.
258-
*
259-
*-- Old comments removed
230+
*Transaction IDs are allocated via a cache in shared memory.
231+
*Each time we need more IDs, we advance the "next XID" value
232+
*in pg_variable by VAR_XID_PREFETCH and set the cache to
233+
*show that many XIDs as available. Then, allocating those XIDs
234+
*requires just a spinlock and not a buffer read/write cycle.
260235
*
261-
*Second, since we may someday preform compression of the data
262-
*in the log and time relations, we cause the numbering of the
263-
*transaction ids to begin at 512. This means that some space
264-
*on the page of the log and time relations corresponding to
265-
*transaction id's 0 - 510 will never be used. This space is
266-
*in fact used to store the version number of the postgres
267-
*transaction log and will someday store compression information
268-
*about the log.-- this is also old comments...
236+
*Since the cache is shared across all backends, cached but unused
237+
*XIDs are not lost when a backend exits, only when the postmaster
238+
*quits or forces shared memory reinit. So we can afford to have
239+
*a pretty big value of VAR_XID_PREFETCH.
269240
*
241+
*This code does not worry about initializing the transaction counter
242+
*(see transam.c's InitializeTransactionLog() for that). We also
243+
*ignore the possibility that the counter could someday wrap around.
270244
* ----------------
271245
*/
272246

@@ -352,44 +326,65 @@ ReadNewTransactionId(TransactionId *xid)
352326
*GetNewObjectIdBlock
353327
*
354328
*This support function is used to allocate a block of object ids
355-
*of the given size.applications wishing to do their own object
356-
*id assignments should use this
329+
*of the given size.
357330
* ----------------
358331
*/
359332
staticvoid
360-
GetNewObjectIdBlock(Oid*oid_return,/* place to return thenew object
361-
* id */
333+
GetNewObjectIdBlock(Oid*oid_return,/* place to return thefirst new
334+
*objectid */
362335
intoid_block_size)/* number of oids desired */
363336
{
337+
Oidfirstfreeoid;
364338
Oidnextoid;
365339

366340
/* ----------------
367-
*SOMEDAY obtain exclusive access to the variable relation page
368-
*That someday is today -mer 6 Aug 1992
341+
* Obtain exclusive access to the variable relation page
369342
* ----------------
370343
*/
371344
SpinAcquire(OidGenLockId);
372345

373346
/* ----------------
374347
*get the "next" oid from the variable relation
375-
*and give it to the caller.
376348
* ----------------
377349
*/
378-
VariableRelationGetNextOid(&nextoid);
379-
if (PointerIsValid(oid_return))
380-
(*oid_return)=nextoid;
350+
VariableRelationGetNextOid(&firstfreeoid);
351+
352+
/* ----------------
353+
*Allocate the range of OIDs to be returned to the caller.
354+
*
355+
*There are two things going on here.
356+
*
357+
*One: in a virgin database pg_variable will initially contain zeroes,
358+
*so we will read out firstfreeoid = InvalidOid. We want to start
359+
*allocating OIDs at BootstrapObjectIdData instead (OIDs below that
360+
*are reserved for static assignment in the initial catalog data).
361+
*
362+
*Two: if a database is run long enough, the OID counter will wrap
363+
*around. We must not generate an invalid OID when that happens,
364+
*and it seems wise not to generate anything in the reserved range.
365+
*Therefore we advance to BootstrapObjectIdData in this case too.
366+
*
367+
*The comparison here assumes that Oid is an unsigned type.
368+
*/
369+
nextoid=firstfreeoid+oid_block_size;
370+
371+
if (!OidIsValid(firstfreeoid)||nextoid<firstfreeoid)
372+
{
373+
/* Initialization or wraparound time, force it up to safe range */
374+
firstfreeoid=BootstrapObjectIdData;
375+
nextoid=firstfreeoid+oid_block_size;
376+
}
377+
378+
(*oid_return)=firstfreeoid;
381379

382380
/* ----------------
383-
*now increment the variable relation's next oid
384-
*field by the size of the oid block requested.
381+
*Update the variable relation to show the block range as used.
385382
* ----------------
386383
*/
387-
nextoid+=oid_block_size;
388-
VariableRelationPutNextOid(&nextoid);
384+
VariableRelationPutNextOid(nextoid);
389385

390386
/* ----------------
391-
*SOMEDAY relinquish our lock on the variable relation page
392-
*That someday is today -mer 6 Apr 1992
387+
*Relinquish our lock on the variable relation page
393388
* ----------------
394389
*/
395390
SpinRelease(OidGenLockId);
@@ -406,9 +401,14 @@ GetNewObjectIdBlock(Oid *oid_return,/* place to return the new object
406401
*relation by 32 for each backend.
407402
*
408403
*Note: 32 has no special significance.We don't want the
409-
* number to be too large becauseifwhen the backend
404+
* number to be too large because when the backend
410405
* terminates, we lose the oids we cached.
411406
*
407+
*Question: couldn't we use a shared-memory cache just like XIDs?
408+
*That would allow a larger interval between pg_variable updates
409+
*without cache losses. Note, however, that we can assign an OID
410+
*without even a spinlock from the backend-local OID cache.
411+
*Maybe two levels of caching would be good.
412412
* ----------------
413413
*/
414414

@@ -431,11 +431,7 @@ GetNewObjectId(Oid *oid_return) /* place to return the new object id */
431431
intoid_block_size=VAR_OID_PREFETCH;
432432

433433
/* ----------------
434-
*during bootstrap time, we want to allocate oids
435-
*one at a time.Otherwise there might be some
436-
*bootstrap oid's left in the block we prefetch which
437-
*would be passed out after the variable relation was
438-
*initialized. This would be bad.
434+
*Make sure pg_variable is open.
439435
* ----------------
440436
*/
441437
if (!RelationIsValid(VariableRelation))
@@ -469,12 +465,11 @@ GetNewObjectId(Oid *oid_return) /* place to return the new object id */
469465
void
470466
CheckMaxObjectId(Oidassigned_oid)
471467
{
472-
Oidpass_oid;
473-
468+
Oidtemp_oid;
474469

475470
if (prefetched_oid_count==0)/* make sure next/max is set, or
476471
* reload */
477-
GetNewObjectId(&pass_oid);
472+
GetNewObjectId(&temp_oid);
478473

479474
/* ----------------
480475
*If we are below prefetched limits, do nothing
@@ -488,7 +483,6 @@ CheckMaxObjectId(Oid assigned_oid)
488483
*If we are here, we are coming from a 'copy from' with oid's
489484
*
490485
*If we are in the prefetched oid range, just bump it up
491-
*
492486
* ----------------
493487
*/
494488

@@ -506,21 +500,19 @@ CheckMaxObjectId(Oid assigned_oid)
506500
*but we are loading oid's that we can not guarantee are unique
507501
*anyway, so we must rely on the user
508502
*
509-
*
510503
* We now:
511504
* set the variable relation with the new max oid
512505
* force the backend to reload its oid cache
513506
*
514-
* We use the oid cache so we don't have to update the variable
515-
* relation every time
516-
*
507+
* By reloading the oid cache, we don't have to update the variable
508+
* relation every time when sequential OIDs are being loaded by COPY.
517509
* ----------------
518510
*/
519511

520-
pass_oid=assigned_oid;
521-
VariableRelationPutNextOid(&pass_oid);/* not modified */
522-
prefetched_oid_count=0;/* force reload */
523-
pass_oid=assigned_oid;
524-
GetNewObjectId(&pass_oid);/* throw away returned oid */
512+
SpinAcquire(OidGenLockId);
513+
VariableRelationPutNextOid(assigned_oid);
514+
SpinRelease(OidGenLockId);
525515

516+
prefetched_oid_count=0;/* force reload */
517+
GetNewObjectId(&temp_oid);/* cause target OID to be allocated */
526518
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp