PostgreSQL Source Code  git master
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
 
#define MinSizeOfDbaseDropRec   offsetof(xl_dbase_drop_rec, tablespace_ids)
 

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

◆ MinSizeOfDbaseDropRec

#define MinSizeOfDbaseDropRec   offsetof(xl_dbase_drop_rec, tablespace_ids)

Definition at line 39 of file dbcommands_xlog.h.

Referenced by remove_dbtablespaces().

◆ XLOG_DBASE_CREATE

#define XLOG_DBASE_CREATE   0x00

◆ XLOG_DBASE_DROP

#define XLOG_DBASE_DROP   0x10

Typedef Documentation

◆ xl_dbase_create_rec

◆ xl_dbase_drop_rec

Function Documentation

◆ dbase_desc()

void dbase_desc ( StringInfo  buf,
XLogReaderState rptr 
)

Definition at line 22 of file dbasedesc.c.

References appendStringInfo(), appendStringInfoString(), xl_dbase_create_rec::db_id, xl_dbase_drop_rec::db_id, i, xl_dbase_drop_rec::ntablespaces, 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_ids, 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_tablespace_id, xlrec->src_db_id,
33  xlrec->tablespace_id, xlrec->db_id);
34  }
35  else if (info == XLOG_DBASE_DROP)
36  {
37  xl_dbase_drop_rec *xlrec = (xl_dbase_drop_rec *) rec;
38  int i;
39 
40  appendStringInfoString(buf, "dir");
41  for (i = 0; i < xlrec->ntablespaces; i++)
42  appendStringInfo(buf, " %u/%u",
43  xlrec->tablespace_ids[i], xlrec->db_id);
44  }
45 }
unsigned char uint8
Definition: c.h:439
#define XLogRecGetData(decoder)
Definition: xlogreader.h:310
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
#define XLOG_DBASE_DROP
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:305
#define XLR_INFO_MASK
Definition: xlogrecord.h:62
#define XLOG_DBASE_CREATE
Oid tablespace_ids[FLEXIBLE_ARRAY_MEMBER]
int i

◆ dbase_identify()

const char* dbase_identify ( uint8  info)

Definition at line 48 of file dbasedesc.c.

References XLOG_DBASE_CREATE, XLOG_DBASE_DROP, and XLR_INFO_MASK.

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

◆ dbase_redo()

void dbase_redo ( XLogReaderState rptr)

Definition at line 2134 of file dbcommands.c.

References AccessExclusiveLock, Assert, copydir(), xl_dbase_create_rec::db_id, xl_dbase_drop_rec::db_id, DropDatabaseBuffers(), elog, ereport, errmsg(), FlushDatabaseBuffers(), ForgetDatabaseSyncRequests(), GetDatabasePath(), i, InHotStandby, LockSharedObjectForSession(), xl_dbase_drop_rec::ntablespaces, PANIC, pfree(), ReplicationSlotsDropDBSlots(), ResolveRecoveryConflictWithDatabase(), rmtree(), S_ISDIR, xl_dbase_create_rec::src_db_id, xl_dbase_create_rec::src_tablespace_id, stat::st_mode, stat, xl_dbase_create_rec::tablespace_id, xl_dbase_drop_rec::tablespace_ids, UnlockSharedObjectForSession(), WARNING, XLOG_DBASE_CREATE, XLOG_DBASE_DROP, XLogDropDatabase(), XLogRecGetData, XLogRecGetInfo, XLogRecHasAnyBlockRefs, and XLR_INFO_MASK.

2135 {
2136  uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
2137 
2138  /* Backup blocks are not used in dbase records */
2139  Assert(!XLogRecHasAnyBlockRefs(record));
2140 
2141  if (info == XLOG_DBASE_CREATE)
2142  {
2144  char *src_path;
2145  char *dst_path;
2146  struct stat st;
2147 
2148  src_path = GetDatabasePath(xlrec->src_db_id, xlrec->src_tablespace_id);
2149  dst_path = GetDatabasePath(xlrec->db_id, xlrec->tablespace_id);
2150 
2151  /*
2152  * Our theory for replaying a CREATE is to forcibly drop the target
2153  * subdirectory if present, then re-copy the source data. This may be
2154  * more work than needed, but it is simple to implement.
2155  */
2156  if (stat(dst_path, &st) == 0 && S_ISDIR(st.st_mode))
2157  {
2158  if (!rmtree(dst_path, true))
2159  /* If this failed, copydir() below is going to error. */
2160  ereport(WARNING,
2161  (errmsg("some useless files may be left behind in old database directory \"%s\"",
2162  dst_path)));
2163  }
2164 
2165  /*
2166  * Force dirty buffers out to disk, to ensure source database is
2167  * up-to-date for the copy.
2168  */
2170 
2171  /*
2172  * Copy this subdirectory to the new location
2173  *
2174  * We don't need to copy subdirectories
2175  */
2176  copydir(src_path, dst_path, false);
2177  }
2178  else if (info == XLOG_DBASE_DROP)
2179  {
2180  xl_dbase_drop_rec *xlrec = (xl_dbase_drop_rec *) XLogRecGetData(record);
2181  char *dst_path;
2182  int i;
2183 
2184  if (InHotStandby)
2185  {
2186  /*
2187  * Lock database while we resolve conflicts to ensure that
2188  * InitPostgres() cannot fully re-execute concurrently. This
2189  * avoids backends re-connecting automatically to same database,
2190  * which can happen in some cases.
2191  *
2192  * This will lock out walsenders trying to connect to db-specific
2193  * slots for logical decoding too, so it's safe for us to drop
2194  * slots.
2195  */
2196  LockSharedObjectForSession(DatabaseRelationId, xlrec->db_id, 0, AccessExclusiveLock);
2198  }
2199 
2200  /* Drop any database-specific replication slots */
2202 
2203  /* Drop pages for this database that are in the shared buffer cache */
2204  DropDatabaseBuffers(xlrec->db_id);
2205 
2206  /* Also, clean out any fsync requests that might be pending in md.c */
2208 
2209  /* Clean out the xlog relcache too */
2210  XLogDropDatabase(xlrec->db_id);
2211 
2212  for (i = 0; i < xlrec->ntablespaces; i++)
2213  {
2214  dst_path = GetDatabasePath(xlrec->db_id, xlrec->tablespace_ids[i]);
2215 
2216  /* And remove the physical files */
2217  if (!rmtree(dst_path, true))
2218  ereport(WARNING,
2219  (errmsg("some useless files may be left behind in old database directory \"%s\"",
2220  dst_path)));
2221  pfree(dst_path);
2222  }
2223 
2224  if (InHotStandby)
2225  {
2226  /*
2227  * Release locks prior to commit. XXX There is a race condition
2228  * here that may allow backends to reconnect, but the window for
2229  * this is small because the gap between here and commit is mostly
2230  * fairly small and it is unlikely that people will be dropping
2231  * databases that we are trying to connect to anyway.
2232  */
2233  UnlockSharedObjectForSession(DatabaseRelationId, xlrec->db_id, 0, AccessExclusiveLock);
2234  }
2235  }
2236  else
2237  elog(PANIC, "dbase_redo: unknown op code %u", info);
2238 }
unsigned char uint8
Definition: c.h:439
void copydir(char *fromdir, char *todir, bool recurse)
Definition: copydir.c:37
#define PANIC
Definition: elog.h:50
void LockSharedObjectForSession(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:1059
void pfree(void *pointer)
Definition: mcxt.c:1169
#define XLogRecGetData(decoder)
Definition: xlogreader.h:310
#define XLOG_DBASE_DROP
void UnlockSharedObjectForSession(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:1077
void FlushDatabaseBuffers(Oid dbid)
Definition: bufmgr.c:3705
#define InHotStandby
Definition: xlogutils.h:57
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:305
char * GetDatabasePath(Oid dbNode, Oid spcNode)
Definition: relpath.c:110
#define WARNING
Definition: elog.h:40
bool rmtree(const char *path, bool rmtopdir)
Definition: rmtree.c:42
#define ereport(elevel,...)
Definition: elog.h:157
void ForgetDatabaseSyncRequests(Oid dbid)
Definition: md.c:1032
void ResolveRecoveryConflictWithDatabase(Oid dbid)
Definition: standby.c:529
#define Assert(condition)
Definition: c.h:804
#define XLR_INFO_MASK
Definition: xlogrecord.h:62
#define XLOG_DBASE_CREATE
Oid tablespace_ids[FLEXIBLE_ARRAY_MEMBER]
#define S_ISDIR(m)
Definition: win32_port.h:316
#define AccessExclusiveLock
Definition: lockdefs.h:45
int errmsg(const char *fmt,...)
Definition: elog.c:909
void XLogDropDatabase(Oid dbid)
Definition: xlogutils.c:643
#define elog(elevel,...)
Definition: elog.h:232
int i
#define XLogRecHasAnyBlockRefs(decoder)
Definition: xlogreader.h:312
void DropDatabaseBuffers(Oid dbid)
Definition: bufmgr.c:3408
void ReplicationSlotsDropDBSlots(Oid dboid)
Definition: slot.c:968
#define stat
Definition: win32_port.h:275