]> granicus.if.org Git - postgresql/blob - src/backend/access/transam/varsup.c
Remove unnecessary #include references, per pgrminclude script.
[postgresql] / src / backend / access / transam / varsup.c
1 /*-------------------------------------------------------------------------
2  *
3  * varsup.c
4  *        postgres OID & XID variables support routines
5  *
6  * Copyright (c) 2000-2011, PostgreSQL Global Development Group
7  *
8  * IDENTIFICATION
9  *        src/backend/access/transam/varsup.c
10  *
11  *-------------------------------------------------------------------------
12  */
13
14 #include "postgres.h"
15
16 #include "access/clog.h"
17 #include "access/subtrans.h"
18 #include "access/transam.h"
19 #include "access/xact.h"
20 #include "commands/dbcommands.h"
21 #include "miscadmin.h"
22 #include "postmaster/autovacuum.h"
23 #include "storage/pmsignal.h"
24 #include "utils/syscache.h"
25
26
27 /* Number of OIDs to prefetch (preallocate) per XLOG write */
28 #define VAR_OID_PREFETCH                8192
29
30 /* pointer to "variable cache" in shared memory (set up by shmem.c) */
31 VariableCache ShmemVariableCache = NULL;
32
33
34 /*
35  * Allocate the next XID for a new transaction or subtransaction.
36  *
37  * The new XID is also stored into MyProc before returning.
38  *
39  * Note: when this is called, we are actually already inside a valid
40  * transaction, since XIDs are now not allocated until the transaction
41  * does something.      So it is safe to do a database lookup if we want to
42  * issue a warning about XID wrap.
43  */
44 TransactionId
45 GetNewTransactionId(bool isSubXact)
46 {
47         TransactionId xid;
48
49         /*
50          * During bootstrap initialization, we return the special bootstrap
51          * transaction id.
52          */
53         if (IsBootstrapProcessingMode())
54         {
55                 Assert(!isSubXact);
56                 MyProc->xid = BootstrapTransactionId;
57                 return BootstrapTransactionId;
58         }
59
60         /* safety check, we should never get this far in a HS slave */
61         if (RecoveryInProgress())
62                 elog(ERROR, "cannot assign TransactionIds during recovery");
63
64         LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
65
66         xid = ShmemVariableCache->nextXid;
67
68         /*----------
69          * Check to see if it's safe to assign another XID.  This protects against
70          * catastrophic data loss due to XID wraparound.  The basic rules are:
71          *
72          * If we're past xidVacLimit, start trying to force autovacuum cycles.
73          * If we're past xidWarnLimit, start issuing warnings.
74          * If we're past xidStopLimit, refuse to execute transactions, unless
75          * we are running in a standalone backend (which gives an escape hatch
76          * to the DBA who somehow got past the earlier defenses).
77          *----------
78          */
79         if (TransactionIdFollowsOrEquals(xid, ShmemVariableCache->xidVacLimit))
80         {
81                 /*
82                  * For safety's sake, we release XidGenLock while sending signals,
83                  * warnings, etc.  This is not so much because we care about
84                  * preserving concurrency in this situation, as to avoid any
85                  * possibility of deadlock while doing get_database_name(). First,
86                  * copy all the shared values we'll need in this path.
87                  */
88                 TransactionId xidWarnLimit = ShmemVariableCache->xidWarnLimit;
89                 TransactionId xidStopLimit = ShmemVariableCache->xidStopLimit;
90                 TransactionId xidWrapLimit = ShmemVariableCache->xidWrapLimit;
91                 Oid                     oldest_datoid = ShmemVariableCache->oldestXidDB;
92
93                 LWLockRelease(XidGenLock);
94
95                 /*
96                  * To avoid swamping the postmaster with signals, we issue the autovac
97                  * request only once per 64K transaction starts.  This still gives
98                  * plenty of chances before we get into real trouble.
99                  */
100                 if (IsUnderPostmaster && (xid % 65536) == 0)
101                         SendPostmasterSignal(PMSIGNAL_START_AUTOVAC_LAUNCHER);
102
103                 if (IsUnderPostmaster &&
104                         TransactionIdFollowsOrEquals(xid, xidStopLimit))
105                 {
106                         char       *oldest_datname = get_database_name(oldest_datoid);
107
108                         /* complain even if that DB has disappeared */
109                         if (oldest_datname)
110                                 ereport(ERROR,
111                                                 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
112                                                  errmsg("database is not accepting commands to avoid wraparound data loss in database \"%s\"",
113                                                                 oldest_datname),
114                                                  errhint("Stop the postmaster and use a standalone backend to vacuum that database.\n"
115                                                                  "You might also need to commit or roll back old prepared transactions.")));
116                         else
117                                 ereport(ERROR,
118                                                 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
119                                                  errmsg("database is not accepting commands to avoid wraparound data loss in database with OID %u",
120                                                                 oldest_datoid),
121                                                  errhint("Stop the postmaster and use a standalone backend to vacuum that database.\n"
122                                                                  "You might also need to commit or roll back old prepared transactions.")));
123                 }
124                 else if (TransactionIdFollowsOrEquals(xid, xidWarnLimit))
125                 {
126                         char       *oldest_datname = get_database_name(oldest_datoid);
127
128                         /* complain even if that DB has disappeared */
129                         if (oldest_datname)
130                                 ereport(WARNING,
131                                                 (errmsg("database \"%s\" must be vacuumed within %u transactions",
132                                                                 oldest_datname,
133                                                                 xidWrapLimit - xid),
134                                                  errhint("To avoid a database shutdown, execute a database-wide VACUUM in that database.\n"
135                                                                  "You might also need to commit or roll back old prepared transactions.")));
136                         else
137                                 ereport(WARNING,
138                                                 (errmsg("database with OID %u must be vacuumed within %u transactions",
139                                                                 oldest_datoid,
140                                                                 xidWrapLimit - xid),
141                                                  errhint("To avoid a database shutdown, execute a database-wide VACUUM in that database.\n"
142                                                                  "You might also need to commit or roll back old prepared transactions.")));
143                 }
144
145                 /* Re-acquire lock and start over */
146                 LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
147                 xid = ShmemVariableCache->nextXid;
148         }
149
150         /*
151          * If we are allocating the first XID of a new page of the commit log,
152          * zero out that commit-log page before returning. We must do this while
153          * holding XidGenLock, else another xact could acquire and commit a later
154          * XID before we zero the page.  Fortunately, a page of the commit log
155          * holds 32K or more transactions, so we don't have to do this very often.
156          *
157          * Extend pg_subtrans too.
158          */
159         ExtendCLOG(xid);
160         ExtendSUBTRANS(xid);
161
162         /*
163          * Now advance the nextXid counter.  This must not happen until after we
164          * have successfully completed ExtendCLOG() --- if that routine fails, we
165          * want the next incoming transaction to try it again.  We cannot assign
166          * more XIDs until there is CLOG space for them.
167          */
168         TransactionIdAdvance(ShmemVariableCache->nextXid);
169
170         /*
171          * We must store the new XID into the shared ProcArray before releasing
172          * XidGenLock.  This ensures that every active XID older than
173          * latestCompletedXid is present in the ProcArray, which is essential for
174          * correct OldestXmin tracking; see src/backend/access/transam/README.
175          *
176          * XXX by storing xid into MyProc without acquiring ProcArrayLock, we are
177          * relying on fetch/store of an xid to be atomic, else other backends
178          * might see a partially-set xid here.  But holding both locks at once
179          * would be a nasty concurrency hit.  So for now, assume atomicity.
180          *
181          * Note that readers of PGPROC xid fields should be careful to fetch the
182          * value only once, rather than assume they can read a value multiple
183          * times and get the same answer each time.
184          *
185          * The same comments apply to the subxact xid count and overflow fields.
186          *
187          * A solution to the atomic-store problem would be to give each PGPROC its
188          * own spinlock used only for fetching/storing that PGPROC's xid and
189          * related fields.
190          *
191          * If there's no room to fit a subtransaction XID into PGPROC, set the
192          * cache-overflowed flag instead.  This forces readers to look in
193          * pg_subtrans to map subtransaction XIDs up to top-level XIDs. There is a
194          * race-condition window, in that the new XID will not appear as running
195          * until its parent link has been placed into pg_subtrans. However, that
196          * will happen before anyone could possibly have a reason to inquire about
197          * the status of the XID, so it seems OK.  (Snapshots taken during this
198          * window *will* include the parent XID, so they will deliver the correct
199          * answer later on when someone does have a reason to inquire.)
200          */
201         {
202                 /*
203                  * Use volatile pointer to prevent code rearrangement; other backends
204                  * could be examining my subxids info concurrently, and we don't want
205                  * them to see an invalid intermediate state, such as incrementing
206                  * nxids before filling the array entry.  Note we are assuming that
207                  * TransactionId and int fetch/store are atomic.
208                  */
209                 volatile PGPROC *myproc = MyProc;
210
211                 if (!isSubXact)
212                         myproc->xid = xid;
213                 else
214                 {
215                         int                     nxids = myproc->subxids.nxids;
216
217                         if (nxids < PGPROC_MAX_CACHED_SUBXIDS)
218                         {
219                                 myproc->subxids.xids[nxids] = xid;
220                                 myproc->subxids.nxids = nxids + 1;
221                         }
222                         else
223                                 myproc->subxids.overflowed = true;
224                 }
225         }
226
227         LWLockRelease(XidGenLock);
228
229         return xid;
230 }
231
232 /*
233  * Read nextXid but don't allocate it.
234  */
235 TransactionId
236 ReadNewTransactionId(void)
237 {
238         TransactionId xid;
239
240         LWLockAcquire(XidGenLock, LW_SHARED);
241         xid = ShmemVariableCache->nextXid;
242         LWLockRelease(XidGenLock);
243
244         return xid;
245 }
246
247 /*
248  * Determine the last safe XID to allocate given the currently oldest
249  * datfrozenxid (ie, the oldest XID that might exist in any database
250  * of our cluster), and the OID of the (or a) database with that value.
251  */
252 void
253 SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid)
254 {
255         TransactionId xidVacLimit;
256         TransactionId xidWarnLimit;
257         TransactionId xidStopLimit;
258         TransactionId xidWrapLimit;
259         TransactionId curXid;
260
261         Assert(TransactionIdIsNormal(oldest_datfrozenxid));
262
263         /*
264          * The place where we actually get into deep trouble is halfway around
265          * from the oldest potentially-existing XID.  (This calculation is
266          * probably off by one or two counts, because the special XIDs reduce the
267          * size of the loop a little bit.  But we throw in plenty of slop below,
268          * so it doesn't matter.)
269          */
270         xidWrapLimit = oldest_datfrozenxid + (MaxTransactionId >> 1);
271         if (xidWrapLimit < FirstNormalTransactionId)
272                 xidWrapLimit += FirstNormalTransactionId;
273
274         /*
275          * We'll refuse to continue assigning XIDs in interactive mode once we get
276          * within 1M transactions of data loss.  This leaves lots of room for the
277          * DBA to fool around fixing things in a standalone backend, while not
278          * being significant compared to total XID space. (Note that since
279          * vacuuming requires one transaction per table cleaned, we had better be
280          * sure there's lots of XIDs left...)
281          */
282         xidStopLimit = xidWrapLimit - 1000000;
283         if (xidStopLimit < FirstNormalTransactionId)
284                 xidStopLimit -= FirstNormalTransactionId;
285
286         /*
287          * We'll start complaining loudly when we get within 10M transactions of
288          * the stop point.      This is kind of arbitrary, but if you let your gas
289          * gauge get down to 1% of full, would you be looking for the next gas
290          * station?  We need to be fairly liberal about this number because there
291          * are lots of scenarios where most transactions are done by automatic
292          * clients that won't pay attention to warnings. (No, we're not gonna make
293          * this configurable.  If you know enough to configure it, you know enough
294          * to not get in this kind of trouble in the first place.)
295          */
296         xidWarnLimit = xidStopLimit - 10000000;
297         if (xidWarnLimit < FirstNormalTransactionId)
298                 xidWarnLimit -= FirstNormalTransactionId;
299
300         /*
301          * We'll start trying to force autovacuums when oldest_datfrozenxid gets
302          * to be more than autovacuum_freeze_max_age transactions old.
303          *
304          * Note: guc.c ensures that autovacuum_freeze_max_age is in a sane range,
305          * so that xidVacLimit will be well before xidWarnLimit.
306          *
307          * Note: autovacuum_freeze_max_age is a PGC_POSTMASTER parameter so that
308          * we don't have to worry about dealing with on-the-fly changes in its
309          * value.  It doesn't look practical to update shared state from a GUC
310          * assign hook (too many processes would try to execute the hook,
311          * resulting in race conditions as well as crashes of those not connected
312          * to shared memory).  Perhaps this can be improved someday.
313          */
314         xidVacLimit = oldest_datfrozenxid + autovacuum_freeze_max_age;
315         if (xidVacLimit < FirstNormalTransactionId)
316                 xidVacLimit += FirstNormalTransactionId;
317
318         /* Grab lock for just long enough to set the new limit values */
319         LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
320         ShmemVariableCache->oldestXid = oldest_datfrozenxid;
321         ShmemVariableCache->xidVacLimit = xidVacLimit;
322         ShmemVariableCache->xidWarnLimit = xidWarnLimit;
323         ShmemVariableCache->xidStopLimit = xidStopLimit;
324         ShmemVariableCache->xidWrapLimit = xidWrapLimit;
325         ShmemVariableCache->oldestXidDB = oldest_datoid;
326         curXid = ShmemVariableCache->nextXid;
327         LWLockRelease(XidGenLock);
328
329         /* Log the info */
330         ereport(DEBUG1,
331                         (errmsg("transaction ID wrap limit is %u, limited by database with OID %u",
332                                         xidWrapLimit, oldest_datoid)));
333
334         /*
335          * If past the autovacuum force point, immediately signal an autovac
336          * request.  The reason for this is that autovac only processes one
337          * database per invocation.  Once it's finished cleaning up the oldest
338          * database, it'll call here, and we'll signal the postmaster to start
339          * another iteration immediately if there are still any old databases.
340          */
341         if (TransactionIdFollowsOrEquals(curXid, xidVacLimit) &&
342                 IsUnderPostmaster && !InRecovery)
343                 SendPostmasterSignal(PMSIGNAL_START_AUTOVAC_LAUNCHER);
344
345         /* Give an immediate warning if past the wrap warn point */
346         if (TransactionIdFollowsOrEquals(curXid, xidWarnLimit) && !InRecovery)
347         {
348                 char       *oldest_datname;
349
350                 /*
351                  * We can be called when not inside a transaction, for example during
352                  * StartupXLOG().  In such a case we cannot do database access, so we
353                  * must just report the oldest DB's OID.
354                  *
355                  * Note: it's also possible that get_database_name fails and returns
356                  * NULL, for example because the database just got dropped.  We'll
357                  * still warn, even though the warning might now be unnecessary.
358                  */
359                 if (IsTransactionState())
360                         oldest_datname = get_database_name(oldest_datoid);
361                 else
362                         oldest_datname = NULL;
363
364                 if (oldest_datname)
365                         ereport(WARNING,
366                         (errmsg("database \"%s\" must be vacuumed within %u transactions",
367                                         oldest_datname,
368                                         xidWrapLimit - curXid),
369                          errhint("To avoid a database shutdown, execute a database-wide VACUUM in that database.\n"
370                                          "You might also need to commit or roll back old prepared transactions.")));
371                 else
372                         ereport(WARNING,
373                                         (errmsg("database with OID %u must be vacuumed within %u transactions",
374                                                         oldest_datoid,
375                                                         xidWrapLimit - curXid),
376                                          errhint("To avoid a database shutdown, execute a database-wide VACUUM in that database.\n"
377                                                          "You might also need to commit or roll back old prepared transactions.")));
378         }
379 }
380
381
382 /*
383  * ForceTransactionIdLimitUpdate -- does the XID wrap-limit data need updating?
384  *
385  * We primarily check whether oldestXidDB is valid.  The cases we have in
386  * mind are that that database was dropped, or the field was reset to zero
387  * by pg_resetxlog.  In either case we should force recalculation of the
388  * wrap limit.  Also do it if oldestXid is old enough to be forcing
389  * autovacuums or other actions; this ensures we update our state as soon
390  * as possible once extra overhead is being incurred.
391  */
392 bool
393 ForceTransactionIdLimitUpdate(void)
394 {
395         TransactionId nextXid;
396         TransactionId xidVacLimit;
397         TransactionId oldestXid;
398         Oid                     oldestXidDB;
399
400         /* Locking is probably not really necessary, but let's be careful */
401         LWLockAcquire(XidGenLock, LW_SHARED);
402         nextXid = ShmemVariableCache->nextXid;
403         xidVacLimit = ShmemVariableCache->xidVacLimit;
404         oldestXid = ShmemVariableCache->oldestXid;
405         oldestXidDB = ShmemVariableCache->oldestXidDB;
406         LWLockRelease(XidGenLock);
407
408         if (!TransactionIdIsNormal(oldestXid))
409                 return true;                    /* shouldn't happen, but just in case */
410         if (!TransactionIdIsValid(xidVacLimit))
411                 return true;                    /* this shouldn't happen anymore either */
412         if (TransactionIdFollowsOrEquals(nextXid, xidVacLimit))
413                 return true;                    /* past VacLimit, don't delay updating */
414         if (!SearchSysCacheExists1(DATABASEOID, ObjectIdGetDatum(oldestXidDB)))
415                 return true;                    /* could happen, per comments above */
416         return false;
417 }
418
419
420 /*
421  * GetNewObjectId -- allocate a new OID
422  *
423  * OIDs are generated by a cluster-wide counter.  Since they are only 32 bits
424  * wide, counter wraparound will occur eventually, and therefore it is unwise
425  * to assume they are unique unless precautions are taken to make them so.
426  * Hence, this routine should generally not be used directly.  The only
427  * direct callers should be GetNewOid() and GetNewRelFileNode() in
428  * catalog/catalog.c.
429  */
430 Oid
431 GetNewObjectId(void)
432 {
433         Oid                     result;
434
435         /* safety check, we should never get this far in a HS slave */
436         if (RecoveryInProgress())
437                 elog(ERROR, "cannot assign OIDs during recovery");
438
439         LWLockAcquire(OidGenLock, LW_EXCLUSIVE);
440
441         /*
442          * Check for wraparound of the OID counter.  We *must* not return 0
443          * (InvalidOid); and as long as we have to check that, it seems a good
444          * idea to skip over everything below FirstNormalObjectId too. (This
445          * basically just avoids lots of collisions with bootstrap-assigned OIDs
446          * right after a wrap occurs, so as to avoid a possibly large number of
447          * iterations in GetNewOid.)  Note we are relying on unsigned comparison.
448          *
449          * During initdb, we start the OID generator at FirstBootstrapObjectId, so
450          * we only enforce wrapping to that point when in bootstrap or standalone
451          * mode.  The first time through this routine after normal postmaster
452          * start, the counter will be forced up to FirstNormalObjectId. This
453          * mechanism leaves the OIDs between FirstBootstrapObjectId and
454          * FirstNormalObjectId available for automatic assignment during initdb,
455          * while ensuring they will never conflict with user-assigned OIDs.
456          */
457         if (ShmemVariableCache->nextOid < ((Oid) FirstNormalObjectId))
458         {
459                 if (IsPostmasterEnvironment)
460                 {
461                         /* wraparound in normal environment */
462                         ShmemVariableCache->nextOid = FirstNormalObjectId;
463                         ShmemVariableCache->oidCount = 0;
464                 }
465                 else
466                 {
467                         /* we may be bootstrapping, so don't enforce the full range */
468                         if (ShmemVariableCache->nextOid < ((Oid) FirstBootstrapObjectId))
469                         {
470                                 /* wraparound in standalone environment? */
471                                 ShmemVariableCache->nextOid = FirstBootstrapObjectId;
472                                 ShmemVariableCache->oidCount = 0;
473                         }
474                 }
475         }
476
477         /* If we run out of logged for use oids then we must log more */
478         if (ShmemVariableCache->oidCount == 0)
479         {
480                 XLogPutNextOid(ShmemVariableCache->nextOid + VAR_OID_PREFETCH);
481                 ShmemVariableCache->oidCount = VAR_OID_PREFETCH;
482         }
483
484         result = ShmemVariableCache->nextOid;
485
486         (ShmemVariableCache->nextOid)++;
487         (ShmemVariableCache->oidCount)--;
488
489         LWLockRelease(OidGenLock);
490
491         return result;
492 }