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