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 2077 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, ReplicationSlotsDropDBSlots(), 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.

2078 {
2079  uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
2080 
2081  /* Backup blocks are not used in dbase records */
2082  Assert(!XLogRecHasAnyBlockRefs(record));
2083 
2084  if (info == XLOG_DBASE_CREATE)
2085  {
2087  char *src_path;
2088  char *dst_path;
2089  struct stat st;
2090 
2091  src_path = GetDatabasePath(xlrec->src_db_id, xlrec->src_tablespace_id);
2092  dst_path = GetDatabasePath(xlrec->db_id, xlrec->tablespace_id);
2093 
2094  /*
2095  * Our theory for replaying a CREATE is to forcibly drop the target
2096  * subdirectory if present, then re-copy the source data. This may be
2097  * more work than needed, but it is simple to implement.
2098  */
2099  if (stat(dst_path, &st) == 0 && S_ISDIR(st.st_mode))
2100  {
2101  if (!rmtree(dst_path, true))
2102  /* If this failed, copydir() below is going to error. */
2103  ereport(WARNING,
2104  (errmsg("some useless files may be left behind in old database directory \"%s\"",
2105  dst_path)));
2106  }
2107 
2108  /*
2109  * Force dirty buffers out to disk, to ensure source database is
2110  * up-to-date for the copy.
2111  */
2113 
2114  /*
2115  * Copy this subdirectory to the new location
2116  *
2117  * We don't need to copy subdirectories
2118  */
2119  copydir(src_path, dst_path, false);
2120  }
2121  else if (info == XLOG_DBASE_DROP)
2122  {
2123  xl_dbase_drop_rec *xlrec = (xl_dbase_drop_rec *) XLogRecGetData(record);
2124  char *dst_path;
2125 
2126  dst_path = GetDatabasePath(xlrec->db_id, xlrec->tablespace_id);
2127 
2128  if (InHotStandby)
2129  {
2130  /*
2131  * Lock database while we resolve conflicts to ensure that
2132  * InitPostgres() cannot fully re-execute concurrently. This
2133  * avoids backends re-connecting automatically to same database,
2134  * which can happen in some cases.
2135  *
2136  * This will lock out walsenders trying to connect to db-specific
2137  * slots for logical decoding too, so it's safe for us to drop slots.
2138  */
2141  }
2142 
2143  /* Drop any database-specific replication slots */
2145 
2146  /* Drop pages for this database that are in the shared buffer cache */
2147  DropDatabaseBuffers(xlrec->db_id);
2148 
2149  /* Also, clean out any fsync requests that might be pending in md.c */
2151 
2152  /* Clean out the xlog relcache too */
2153  XLogDropDatabase(xlrec->db_id);
2154 
2155  /* And remove the physical files */
2156  if (!rmtree(dst_path, true))
2157  ereport(WARNING,
2158  (errmsg("some useless files may be left behind in old database directory \"%s\"",
2159  dst_path)));
2160 
2161  if (InHotStandby)
2162  {
2163  /*
2164  * Release locks prior to commit. XXX There is a race condition
2165  * here that may allow backends to reconnect, but the window for
2166  * this is small because the gap between here and commit is mostly
2167  * fairly small and it is unlikely that people will be dropping
2168  * databases that we are trying to connect to anyway.
2169  */
2171  }
2172  }
2173  else
2174  elog(PANIC, "dbase_redo: unknown op code %u", info);
2175 }
#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
void ReplicationSlotsDropDBSlots(Oid dboid)
Definition: slot.c:813