Header And Logo

PostgreSQL
| The world's most advanced open source database.

varsup.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * varsup.c
00004  *    postgres OID & XID variables support routines
00005  *
00006  * Copyright (c) 2000-2013, PostgreSQL Global Development Group
00007  *
00008  * IDENTIFICATION
00009  *    src/backend/access/transam/varsup.c
00010  *
00011  *-------------------------------------------------------------------------
00012  */
00013 
00014 #include "postgres.h"
00015 
00016 #include "access/clog.h"
00017 #include "access/subtrans.h"
00018 #include "access/transam.h"
00019 #include "access/xact.h"
00020 #include "commands/dbcommands.h"
00021 #include "miscadmin.h"
00022 #include "postmaster/autovacuum.h"
00023 #include "storage/pmsignal.h"
00024 #include "storage/proc.h"
00025 #include "utils/syscache.h"
00026 
00027 
00028 /* Number of OIDs to prefetch (preallocate) per XLOG write */
00029 #define VAR_OID_PREFETCH        8192
00030 
00031 /* pointer to "variable cache" in shared memory (set up by shmem.c) */
00032 VariableCache ShmemVariableCache = NULL;
00033 
00034 
00035 /*
00036  * Allocate the next XID for a new transaction or subtransaction.
00037  *
00038  * The new XID is also stored into MyPgXact before returning.
00039  *
00040  * Note: when this is called, we are actually already inside a valid
00041  * transaction, since XIDs are now not allocated until the transaction
00042  * does something.  So it is safe to do a database lookup if we want to
00043  * issue a warning about XID wrap.
00044  */
00045 TransactionId
00046 GetNewTransactionId(bool isSubXact)
00047 {
00048     TransactionId xid;
00049 
00050     /*
00051      * During bootstrap initialization, we return the special bootstrap
00052      * transaction id.
00053      */
00054     if (IsBootstrapProcessingMode())
00055     {
00056         Assert(!isSubXact);
00057         MyPgXact->xid = BootstrapTransactionId;
00058         return BootstrapTransactionId;
00059     }
00060 
00061     /* safety check, we should never get this far in a HS slave */
00062     if (RecoveryInProgress())
00063         elog(ERROR, "cannot assign TransactionIds during recovery");
00064 
00065     LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
00066 
00067     xid = ShmemVariableCache->nextXid;
00068 
00069     /*----------
00070      * Check to see if it's safe to assign another XID.  This protects against
00071      * catastrophic data loss due to XID wraparound.  The basic rules are:
00072      *
00073      * If we're past xidVacLimit, start trying to force autovacuum cycles.
00074      * If we're past xidWarnLimit, start issuing warnings.
00075      * If we're past xidStopLimit, refuse to execute transactions, unless
00076      * we are running in a standalone backend (which gives an escape hatch
00077      * to the DBA who somehow got past the earlier defenses).
00078      *
00079      * Note that this coding also appears in GetNewMultiXactId.
00080      *----------
00081      */
00082     if (TransactionIdFollowsOrEquals(xid, ShmemVariableCache->xidVacLimit))
00083     {
00084         /*
00085          * For safety's sake, we release XidGenLock while sending signals,
00086          * warnings, etc.  This is not so much because we care about
00087          * preserving concurrency in this situation, as to avoid any
00088          * possibility of deadlock while doing get_database_name(). First,
00089          * copy all the shared values we'll need in this path.
00090          */
00091         TransactionId xidWarnLimit = ShmemVariableCache->xidWarnLimit;
00092         TransactionId xidStopLimit = ShmemVariableCache->xidStopLimit;
00093         TransactionId xidWrapLimit = ShmemVariableCache->xidWrapLimit;
00094         Oid         oldest_datoid = ShmemVariableCache->oldestXidDB;
00095 
00096         LWLockRelease(XidGenLock);
00097 
00098         /*
00099          * To avoid swamping the postmaster with signals, we issue the autovac
00100          * request only once per 64K transaction starts.  This still gives
00101          * plenty of chances before we get into real trouble.
00102          */
00103         if (IsUnderPostmaster && (xid % 65536) == 0)
00104             SendPostmasterSignal(PMSIGNAL_START_AUTOVAC_LAUNCHER);
00105 
00106         if (IsUnderPostmaster &&
00107             TransactionIdFollowsOrEquals(xid, xidStopLimit))
00108         {
00109             char       *oldest_datname = get_database_name(oldest_datoid);
00110 
00111             /* complain even if that DB has disappeared */
00112             if (oldest_datname)
00113                 ereport(ERROR,
00114                         (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
00115                          errmsg("database is not accepting commands to avoid wraparound data loss in database \"%s\"",
00116                                 oldest_datname),
00117                          errhint("Stop the postmaster and use a standalone backend to vacuum that database.\n"
00118                                  "You might also need to commit or roll back old prepared transactions.")));
00119             else
00120                 ereport(ERROR,
00121                         (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
00122                          errmsg("database is not accepting commands to avoid wraparound data loss in database with OID %u",
00123                                 oldest_datoid),
00124                          errhint("Stop the postmaster and use a standalone backend to vacuum that database.\n"
00125                                  "You might also need to commit or roll back old prepared transactions.")));
00126         }
00127         else if (TransactionIdFollowsOrEquals(xid, xidWarnLimit))
00128         {
00129             char       *oldest_datname = get_database_name(oldest_datoid);
00130 
00131             /* complain even if that DB has disappeared */
00132             if (oldest_datname)
00133                 ereport(WARNING,
00134                         (errmsg("database \"%s\" must be vacuumed within %u transactions",
00135                                 oldest_datname,
00136                                 xidWrapLimit - xid),
00137                          errhint("To avoid a database shutdown, execute a database-wide VACUUM in that database.\n"
00138                                  "You might also need to commit or roll back old prepared transactions.")));
00139             else
00140                 ereport(WARNING,
00141                         (errmsg("database with OID %u must be vacuumed within %u transactions",
00142                                 oldest_datoid,
00143                                 xidWrapLimit - xid),
00144                          errhint("To avoid a database shutdown, execute a database-wide VACUUM in that database.\n"
00145                                  "You might also need to commit or roll back old prepared transactions.")));
00146         }
00147 
00148         /* Re-acquire lock and start over */
00149         LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
00150         xid = ShmemVariableCache->nextXid;
00151     }
00152 
00153     /*
00154      * If we are allocating the first XID of a new page of the commit log,
00155      * zero out that commit-log page before returning. We must do this while
00156      * holding XidGenLock, else another xact could acquire and commit a later
00157      * XID before we zero the page.  Fortunately, a page of the commit log
00158      * holds 32K or more transactions, so we don't have to do this very often.
00159      *
00160      * Extend pg_subtrans too.
00161      */
00162     ExtendCLOG(xid);
00163     ExtendSUBTRANS(xid);
00164 
00165     /*
00166      * Now advance the nextXid counter.  This must not happen until after we
00167      * have successfully completed ExtendCLOG() --- if that routine fails, we
00168      * want the next incoming transaction to try it again.  We cannot assign
00169      * more XIDs until there is CLOG space for them.
00170      */
00171     TransactionIdAdvance(ShmemVariableCache->nextXid);
00172 
00173     /*
00174      * We must store the new XID into the shared ProcArray before releasing
00175      * XidGenLock.  This ensures that every active XID older than
00176      * latestCompletedXid is present in the ProcArray, which is essential for
00177      * correct OldestXmin tracking; see src/backend/access/transam/README.
00178      *
00179      * XXX by storing xid into MyPgXact without acquiring ProcArrayLock, we
00180      * are relying on fetch/store of an xid to be atomic, else other backends
00181      * might see a partially-set xid here.  But holding both locks at once
00182      * would be a nasty concurrency hit.  So for now, assume atomicity.
00183      *
00184      * Note that readers of PGXACT xid fields should be careful to fetch the
00185      * value only once, rather than assume they can read a value multiple
00186      * times and get the same answer each time.
00187      *
00188      * The same comments apply to the subxact xid count and overflow fields.
00189      *
00190      * A solution to the atomic-store problem would be to give each PGXACT its
00191      * own spinlock used only for fetching/storing that PGXACT's xid and
00192      * related fields.
00193      *
00194      * If there's no room to fit a subtransaction XID into PGPROC, set the
00195      * cache-overflowed flag instead.  This forces readers to look in
00196      * pg_subtrans to map subtransaction XIDs up to top-level XIDs. There is a
00197      * race-condition window, in that the new XID will not appear as running
00198      * until its parent link has been placed into pg_subtrans. However, that
00199      * will happen before anyone could possibly have a reason to inquire about
00200      * the status of the XID, so it seems OK.  (Snapshots taken during this
00201      * window *will* include the parent XID, so they will deliver the correct
00202      * answer later on when someone does have a reason to inquire.)
00203      */
00204     {
00205         /*
00206          * Use volatile pointer to prevent code rearrangement; other backends
00207          * could be examining my subxids info concurrently, and we don't want
00208          * them to see an invalid intermediate state, such as incrementing
00209          * nxids before filling the array entry.  Note we are assuming that
00210          * TransactionId and int fetch/store are atomic.
00211          */
00212         volatile PGPROC *myproc = MyProc;
00213         volatile PGXACT *mypgxact = MyPgXact;
00214 
00215         if (!isSubXact)
00216             mypgxact->xid = xid;
00217         else
00218         {
00219             int         nxids = mypgxact->nxids;
00220 
00221             if (nxids < PGPROC_MAX_CACHED_SUBXIDS)
00222             {
00223                 myproc->subxids.xids[nxids] = xid;
00224                 mypgxact->nxids = nxids + 1;
00225             }
00226             else
00227                 mypgxact->overflowed = true;
00228         }
00229     }
00230 
00231     LWLockRelease(XidGenLock);
00232 
00233     return xid;
00234 }
00235 
00236 /*
00237  * Read nextXid but don't allocate it.
00238  */
00239 TransactionId
00240 ReadNewTransactionId(void)
00241 {
00242     TransactionId xid;
00243 
00244     LWLockAcquire(XidGenLock, LW_SHARED);
00245     xid = ShmemVariableCache->nextXid;
00246     LWLockRelease(XidGenLock);
00247 
00248     return xid;
00249 }
00250 
00251 /*
00252  * Determine the last safe XID to allocate given the currently oldest
00253  * datfrozenxid (ie, the oldest XID that might exist in any database
00254  * of our cluster), and the OID of the (or a) database with that value.
00255  */
00256 void
00257 SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid)
00258 {
00259     TransactionId xidVacLimit;
00260     TransactionId xidWarnLimit;
00261     TransactionId xidStopLimit;
00262     TransactionId xidWrapLimit;
00263     TransactionId curXid;
00264 
00265     Assert(TransactionIdIsNormal(oldest_datfrozenxid));
00266 
00267     /*
00268      * The place where we actually get into deep trouble is halfway around
00269      * from the oldest potentially-existing XID.  (This calculation is
00270      * probably off by one or two counts, because the special XIDs reduce the
00271      * size of the loop a little bit.  But we throw in plenty of slop below,
00272      * so it doesn't matter.)
00273      */
00274     xidWrapLimit = oldest_datfrozenxid + (MaxTransactionId >> 1);
00275     if (xidWrapLimit < FirstNormalTransactionId)
00276         xidWrapLimit += FirstNormalTransactionId;
00277 
00278     /*
00279      * We'll refuse to continue assigning XIDs in interactive mode once we get
00280      * within 1M transactions of data loss.  This leaves lots of room for the
00281      * DBA to fool around fixing things in a standalone backend, while not
00282      * being significant compared to total XID space. (Note that since
00283      * vacuuming requires one transaction per table cleaned, we had better be
00284      * sure there's lots of XIDs left...)
00285      */
00286     xidStopLimit = xidWrapLimit - 1000000;
00287     if (xidStopLimit < FirstNormalTransactionId)
00288         xidStopLimit -= FirstNormalTransactionId;
00289 
00290     /*
00291      * We'll start complaining loudly when we get within 10M transactions of
00292      * the stop point.  This is kind of arbitrary, but if you let your gas
00293      * gauge get down to 1% of full, would you be looking for the next gas
00294      * station?  We need to be fairly liberal about this number because there
00295      * are lots of scenarios where most transactions are done by automatic
00296      * clients that won't pay attention to warnings. (No, we're not gonna make
00297      * this configurable.  If you know enough to configure it, you know enough
00298      * to not get in this kind of trouble in the first place.)
00299      */
00300     xidWarnLimit = xidStopLimit - 10000000;
00301     if (xidWarnLimit < FirstNormalTransactionId)
00302         xidWarnLimit -= FirstNormalTransactionId;
00303 
00304     /*
00305      * We'll start trying to force autovacuums when oldest_datfrozenxid gets
00306      * to be more than autovacuum_freeze_max_age transactions old.
00307      *
00308      * Note: guc.c ensures that autovacuum_freeze_max_age is in a sane range,
00309      * so that xidVacLimit will be well before xidWarnLimit.
00310      *
00311      * Note: autovacuum_freeze_max_age is a PGC_POSTMASTER parameter so that
00312      * we don't have to worry about dealing with on-the-fly changes in its
00313      * value.  It doesn't look practical to update shared state from a GUC
00314      * assign hook (too many processes would try to execute the hook,
00315      * resulting in race conditions as well as crashes of those not connected
00316      * to shared memory).  Perhaps this can be improved someday.
00317      */
00318     xidVacLimit = oldest_datfrozenxid + autovacuum_freeze_max_age;
00319     if (xidVacLimit < FirstNormalTransactionId)
00320         xidVacLimit += FirstNormalTransactionId;
00321 
00322     /* Grab lock for just long enough to set the new limit values */
00323     LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
00324     ShmemVariableCache->oldestXid = oldest_datfrozenxid;
00325     ShmemVariableCache->xidVacLimit = xidVacLimit;
00326     ShmemVariableCache->xidWarnLimit = xidWarnLimit;
00327     ShmemVariableCache->xidStopLimit = xidStopLimit;
00328     ShmemVariableCache->xidWrapLimit = xidWrapLimit;
00329     ShmemVariableCache->oldestXidDB = oldest_datoid;
00330     curXid = ShmemVariableCache->nextXid;
00331     LWLockRelease(XidGenLock);
00332 
00333     /* Log the info */
00334     ereport(DEBUG1,
00335             (errmsg("transaction ID wrap limit is %u, limited by database with OID %u",
00336                     xidWrapLimit, oldest_datoid)));
00337 
00338     /*
00339      * If past the autovacuum force point, immediately signal an autovac
00340      * request.  The reason for this is that autovac only processes one
00341      * database per invocation.  Once it's finished cleaning up the oldest
00342      * database, it'll call here, and we'll signal the postmaster to start
00343      * another iteration immediately if there are still any old databases.
00344      */
00345     if (TransactionIdFollowsOrEquals(curXid, xidVacLimit) &&
00346         IsUnderPostmaster && !InRecovery)
00347         SendPostmasterSignal(PMSIGNAL_START_AUTOVAC_LAUNCHER);
00348 
00349     /* Give an immediate warning if past the wrap warn point */
00350     if (TransactionIdFollowsOrEquals(curXid, xidWarnLimit) && !InRecovery)
00351     {
00352         char       *oldest_datname;
00353 
00354         /*
00355          * We can be called when not inside a transaction, for example during
00356          * StartupXLOG().  In such a case we cannot do database access, so we
00357          * must just report the oldest DB's OID.
00358          *
00359          * Note: it's also possible that get_database_name fails and returns
00360          * NULL, for example because the database just got dropped.  We'll
00361          * still warn, even though the warning might now be unnecessary.
00362          */
00363         if (IsTransactionState())
00364             oldest_datname = get_database_name(oldest_datoid);
00365         else
00366             oldest_datname = NULL;
00367 
00368         if (oldest_datname)
00369             ereport(WARNING,
00370             (errmsg("database \"%s\" must be vacuumed within %u transactions",
00371                     oldest_datname,
00372                     xidWrapLimit - curXid),
00373              errhint("To avoid a database shutdown, execute a database-wide VACUUM in that database.\n"
00374                      "You might also need to commit or roll back old prepared transactions.")));
00375         else
00376             ereport(WARNING,
00377                     (errmsg("database with OID %u must be vacuumed within %u transactions",
00378                             oldest_datoid,
00379                             xidWrapLimit - curXid),
00380                      errhint("To avoid a database shutdown, execute a database-wide VACUUM in that database.\n"
00381                              "You might also need to commit or roll back old prepared transactions.")));
00382     }
00383 }
00384 
00385 
00386 /*
00387  * ForceTransactionIdLimitUpdate -- does the XID wrap-limit data need updating?
00388  *
00389  * We primarily check whether oldestXidDB is valid.  The cases we have in
00390  * mind are that that database was dropped, or the field was reset to zero
00391  * by pg_resetxlog.  In either case we should force recalculation of the
00392  * wrap limit.  Also do it if oldestXid is old enough to be forcing
00393  * autovacuums or other actions; this ensures we update our state as soon
00394  * as possible once extra overhead is being incurred.
00395  */
00396 bool
00397 ForceTransactionIdLimitUpdate(void)
00398 {
00399     TransactionId nextXid;
00400     TransactionId xidVacLimit;
00401     TransactionId oldestXid;
00402     Oid         oldestXidDB;
00403 
00404     /* Locking is probably not really necessary, but let's be careful */
00405     LWLockAcquire(XidGenLock, LW_SHARED);
00406     nextXid = ShmemVariableCache->nextXid;
00407     xidVacLimit = ShmemVariableCache->xidVacLimit;
00408     oldestXid = ShmemVariableCache->oldestXid;
00409     oldestXidDB = ShmemVariableCache->oldestXidDB;
00410     LWLockRelease(XidGenLock);
00411 
00412     if (!TransactionIdIsNormal(oldestXid))
00413         return true;            /* shouldn't happen, but just in case */
00414     if (!TransactionIdIsValid(xidVacLimit))
00415         return true;            /* this shouldn't happen anymore either */
00416     if (TransactionIdFollowsOrEquals(nextXid, xidVacLimit))
00417         return true;            /* past VacLimit, don't delay updating */
00418     if (!SearchSysCacheExists1(DATABASEOID, ObjectIdGetDatum(oldestXidDB)))
00419         return true;            /* could happen, per comments above */
00420     return false;
00421 }
00422 
00423 
00424 /*
00425  * GetNewObjectId -- allocate a new OID
00426  *
00427  * OIDs are generated by a cluster-wide counter.  Since they are only 32 bits
00428  * wide, counter wraparound will occur eventually, and therefore it is unwise
00429  * to assume they are unique unless precautions are taken to make them so.
00430  * Hence, this routine should generally not be used directly.  The only
00431  * direct callers should be GetNewOid() and GetNewRelFileNode() in
00432  * catalog/catalog.c.
00433  */
00434 Oid
00435 GetNewObjectId(void)
00436 {
00437     Oid         result;
00438 
00439     /* safety check, we should never get this far in a HS slave */
00440     if (RecoveryInProgress())
00441         elog(ERROR, "cannot assign OIDs during recovery");
00442 
00443     LWLockAcquire(OidGenLock, LW_EXCLUSIVE);
00444 
00445     /*
00446      * Check for wraparound of the OID counter.  We *must* not return 0
00447      * (InvalidOid); and as long as we have to check that, it seems a good
00448      * idea to skip over everything below FirstNormalObjectId too. (This
00449      * basically just avoids lots of collisions with bootstrap-assigned OIDs
00450      * right after a wrap occurs, so as to avoid a possibly large number of
00451      * iterations in GetNewOid.)  Note we are relying on unsigned comparison.
00452      *
00453      * During initdb, we start the OID generator at FirstBootstrapObjectId, so
00454      * we only enforce wrapping to that point when in bootstrap or standalone
00455      * mode.  The first time through this routine after normal postmaster
00456      * start, the counter will be forced up to FirstNormalObjectId. This
00457      * mechanism leaves the OIDs between FirstBootstrapObjectId and
00458      * FirstNormalObjectId available for automatic assignment during initdb,
00459      * while ensuring they will never conflict with user-assigned OIDs.
00460      */
00461     if (ShmemVariableCache->nextOid < ((Oid) FirstNormalObjectId))
00462     {
00463         if (IsPostmasterEnvironment)
00464         {
00465             /* wraparound in normal environment */
00466             ShmemVariableCache->nextOid = FirstNormalObjectId;
00467             ShmemVariableCache->oidCount = 0;
00468         }
00469         else
00470         {
00471             /* we may be bootstrapping, so don't enforce the full range */
00472             if (ShmemVariableCache->nextOid < ((Oid) FirstBootstrapObjectId))
00473             {
00474                 /* wraparound in standalone environment? */
00475                 ShmemVariableCache->nextOid = FirstBootstrapObjectId;
00476                 ShmemVariableCache->oidCount = 0;
00477             }
00478         }
00479     }
00480 
00481     /* If we run out of logged for use oids then we must log more */
00482     if (ShmemVariableCache->oidCount == 0)
00483     {
00484         XLogPutNextOid(ShmemVariableCache->nextOid + VAR_OID_PREFETCH);
00485         ShmemVariableCache->oidCount = VAR_OID_PREFETCH;
00486     }
00487 
00488     result = ShmemVariableCache->nextOid;
00489 
00490     (ShmemVariableCache->nextOid)++;
00491     (ShmemVariableCache->oidCount)--;
00492 
00493     LWLockRelease(OidGenLock);
00494 
00495     return result;
00496 }