PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
dbcommands_xlog.h File Reference
#include "access/xlogreader.h"
#include "lib/stringinfo.h"
Include dependency graph for dbcommands_xlog.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  xl_dbase_create_rec
 
struct  xl_dbase_drop_rec
 

Macros

#define XLOG_DBASE_CREATE   0x00
 
#define XLOG_DBASE_DROP   0x10
 

Typedefs

typedef struct xl_dbase_create_rec xl_dbase_create_rec
 
typedef struct xl_dbase_drop_rec xl_dbase_drop_rec
 

Functions

void dbase_redo (XLogReaderState *rptr)
 
void dbase_desc (StringInfo buf, XLogReaderState *rptr)
 
const char * dbase_identify (uint8 info)
 

Macro Definition Documentation

#define XLOG_DBASE_CREATE   0x00
#define XLOG_DBASE_DROP   0x10

Typedef Documentation

Function Documentation

void dbase_desc ( StringInfo  buf,
XLogReaderState rptr 
)

Definition at line 22 of file dbasedesc.c.

References appendStringInfo(), xl_dbase_create_rec::db_id, xl_dbase_drop_rec::db_id, xl_dbase_create_rec::src_db_id, xl_dbase_create_rec::src_tablespace_id, xl_dbase_create_rec::tablespace_id, xl_dbase_drop_rec::tablespace_id, XLOG_DBASE_CREATE, XLOG_DBASE_DROP, XLogRecGetData, XLogRecGetInfo, and XLR_INFO_MASK.

23 {
24  char *rec = XLogRecGetData(record);
25  uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
26 
27  if (info == XLOG_DBASE_CREATE)
28  {
30 
31  appendStringInfo(buf, "copy dir %u/%u to %u/%u",
32  xlrec->src_db_id, xlrec->src_tablespace_id,
33  xlrec->db_id, xlrec->tablespace_id);
34  }
35  else if (info == XLOG_DBASE_DROP)
36  {
37  xl_dbase_drop_rec *xlrec = (xl_dbase_drop_rec *) rec;
38 
39  appendStringInfo(buf, "dir %u/%u",
40  xlrec->db_id, xlrec->tablespace_id);
41  }
42 }
unsigned char uint8
Definition: c.h:266
#define XLogRecGetData(decoder)
Definition: xlogreader.h:218
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:110
#define XLOG_DBASE_DROP
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:214
#define XLR_INFO_MASK
Definition: xlogrecord.h:62
#define XLOG_DBASE_CREATE
const char* dbase_identify ( uint8  info)

Definition at line 45 of file dbasedesc.c.

References NULL, XLOG_DBASE_CREATE, XLOG_DBASE_DROP, and XLR_INFO_MASK.

46 {
47  const char *id = NULL;
48 
49  switch (info & ~XLR_INFO_MASK)
50  {
51  case XLOG_DBASE_CREATE:
52  id = "CREATE";
53  break;
54  case XLOG_DBASE_DROP:
55  id = "DROP";
56  break;
57  }
58 
59  return id;
60 }
#define XLOG_DBASE_DROP
#define NULL
Definition: c.h:229
#define XLR_INFO_MASK
Definition: xlogrecord.h:62
#define XLOG_DBASE_CREATE
void dbase_redo ( XLogReaderState rptr)

Definition at line 2069 of file dbcommands.c.

References AccessExclusiveLock, Assert, copydir(), DatabaseRelationId, xl_dbase_create_rec::db_id, xl_dbase_drop_rec::db_id, DropDatabaseBuffers(), elog, ereport, errmsg(), FlushDatabaseBuffers(), ForgetDatabaseFsyncRequests(), GetDatabasePath(), InHotStandby, LockSharedObjectForSession(), PANIC, ResolveRecoveryConflictWithDatabase(), rmtree(), xl_dbase_create_rec::src_db_id, xl_dbase_create_rec::src_tablespace_id, xl_dbase_create_rec::tablespace_id, xl_dbase_drop_rec::tablespace_id, UnlockSharedObjectForSession(), WARNING, XLOG_DBASE_CREATE, XLOG_DBASE_DROP, XLogDropDatabase(), XLogRecGetData, XLogRecGetInfo, XLogRecHasAnyBlockRefs, and XLR_INFO_MASK.

2070 {
2071  uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
2072 
2073  /* Backup blocks are not used in dbase records */
2074  Assert(!XLogRecHasAnyBlockRefs(record));
2075 
2076  if (info == XLOG_DBASE_CREATE)
2077  {
2079  char *src_path;
2080  char *dst_path;
2081  struct stat st;
2082 
2083  src_path = GetDatabasePath(xlrec->src_db_id, xlrec->src_tablespace_id);
2084  dst_path = GetDatabasePath(xlrec->db_id, xlrec->tablespace_id);
2085 
2086  /*
2087  * Our theory for replaying a CREATE is to forcibly drop the target
2088  * subdirectory if present, then re-copy the source data. This may be
2089  * more work than needed, but it is simple to implement.
2090  */
2091  if (stat(dst_path, &st) == 0 && S_ISDIR(st.st_mode))
2092  {
2093  if (!rmtree(dst_path, true))
2094  /* If this failed, copydir() below is going to error. */
2095  ereport(WARNING,
2096  (errmsg("some useless files may be left behind in old database directory \"%s\"",
2097  dst_path)));
2098  }
2099 
2100  /*
2101  * Force dirty buffers out to disk, to ensure source database is
2102  * up-to-date for the copy.
2103  */
2105 
2106  /*
2107  * Copy this subdirectory to the new location
2108  *
2109  * We don't need to copy subdirectories
2110  */
2111  copydir(src_path, dst_path, false);
2112  }
2113  else if (info == XLOG_DBASE_DROP)
2114  {
2115  xl_dbase_drop_rec *xlrec = (xl_dbase_drop_rec *) XLogRecGetData(record);
2116  char *dst_path;
2117 
2118  dst_path = GetDatabasePath(xlrec->db_id, xlrec->tablespace_id);
2119 
2120  if (InHotStandby)
2121  {
2122  /*
2123  * Lock database while we resolve conflicts to ensure that
2124  * InitPostgres() cannot fully re-execute concurrently. This
2125  * avoids backends re-connecting automatically to same database,
2126  * which can happen in some cases.
2127  */
2130  }
2131 
2132  /* Drop pages for this database that are in the shared buffer cache */
2133  DropDatabaseBuffers(xlrec->db_id);
2134 
2135  /* Also, clean out any fsync requests that might be pending in md.c */
2137 
2138  /* Clean out the xlog relcache too */
2139  XLogDropDatabase(xlrec->db_id);
2140 
2141  /* And remove the physical files */
2142  if (!rmtree(dst_path, true))
2143  ereport(WARNING,
2144  (errmsg("some useless files may be left behind in old database directory \"%s\"",
2145  dst_path)));
2146 
2147  if (InHotStandby)
2148  {
2149  /*
2150  * Release locks prior to commit. XXX There is a race condition
2151  * here that may allow backends to reconnect, but the window for
2152  * this is small because the gap between here and commit is mostly
2153  * fairly small and it is unlikely that people will be dropping
2154  * databases that we are trying to connect to anyway.
2155  */
2157  }
2158  }
2159  else
2160  elog(PANIC, "dbase_redo: unknown op code %u", info);
2161 }
#define DatabaseRelationId
Definition: pg_database.h:29
unsigned char uint8
Definition: c.h:266
#define InHotStandby
Definition: xlog.h:74
void copydir(char *fromdir, char *todir, bool recurse)
Definition: copydir.c:37
#define PANIC
Definition: elog.h:53
void LockSharedObjectForSession(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:913
#define XLogRecGetData(decoder)
Definition: xlogreader.h:218
#define XLOG_DBASE_DROP
void UnlockSharedObjectForSession(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:931
void FlushDatabaseBuffers(Oid dbid)
Definition: bufmgr.c:3246
#define ereport(elevel, rest)
Definition: elog.h:122
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:214
char * GetDatabasePath(Oid dbNode, Oid spcNode)
Definition: relpath.c:108
#define WARNING
Definition: elog.h:40
bool rmtree(const char *path, bool rmtopdir)
Definition: rmtree.c:36
void ForgetDatabaseFsyncRequests(Oid dbid)
Definition: md.c:1685
void ResolveRecoveryConflictWithDatabase(Oid dbid)
Definition: standby.c:319
#define Assert(condition)
Definition: c.h:675
#define XLR_INFO_MASK
Definition: xlogrecord.h:62
#define XLOG_DBASE_CREATE
#define AccessExclusiveLock
Definition: lockdefs.h:46
int errmsg(const char *fmt,...)
Definition: elog.c:797
void XLogDropDatabase(Oid dbid)
Definition: xlogutils.c:618
#define XLogRecHasAnyBlockRefs(decoder)
Definition: xlogreader.h:220
#define elog
Definition: elog.h:219
void DropDatabaseBuffers(Oid dbid)
Definition: bufmgr.c:3043