PostgreSQL Source Code  git master
relmapper.h File Reference
#include "access/xlogreader.h"
#include "lib/stringinfo.h"
Include dependency graph for relmapper.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  xl_relmap_update
 

Macros

#define XLOG_RELMAP_UPDATE   0x00
 
#define MinSizeOfRelmapUpdate   offsetof(xl_relmap_update, data)
 

Typedefs

typedef struct xl_relmap_update xl_relmap_update
 

Functions

Oid RelationMapOidToFilenode (Oid relationId, bool shared)
 
Oid RelationMapFilenodeToOid (Oid relationId, bool shared)
 
Oid RelationMapOidToFilenodeForDatabase (char *dbpath, Oid relationId)
 
void RelationMapCopy (Oid dbid, Oid tsid, char *srcdbpath, char *dstdbpath)
 
void RelationMapUpdateMap (Oid relationId, Oid fileNode, bool shared, bool immediate)
 
void RelationMapRemoveMapping (Oid relationId)
 
void RelationMapInvalidate (bool shared)
 
void RelationMapInvalidateAll (void)
 
void AtCCI_RelationMap (void)
 
void AtEOXact_RelationMap (bool isCommit, bool isParallelWorker)
 
void AtPrepare_RelationMap (void)
 
void CheckPointRelationMap (void)
 
void RelationMapFinishBootstrap (void)
 
void RelationMapInitialize (void)
 
void RelationMapInitializePhase2 (void)
 
void RelationMapInitializePhase3 (void)
 
Size EstimateRelationMapSpace (void)
 
void SerializeRelationMap (Size maxSize, char *startAddress)
 
void RestoreRelationMap (char *startAddress)
 
void relmap_redo (XLogReaderState *record)
 
void relmap_desc (StringInfo buf, XLogReaderState *record)
 
const char * relmap_identify (uint8 info)
 

Macro Definition Documentation

◆ MinSizeOfRelmapUpdate

#define MinSizeOfRelmapUpdate   offsetof(xl_relmap_update, data)

Definition at line 35 of file relmapper.h.

◆ XLOG_RELMAP_UPDATE

#define XLOG_RELMAP_UPDATE   0x00

Definition at line 25 of file relmapper.h.

Typedef Documentation

◆ xl_relmap_update

Function Documentation

◆ AtCCI_RelationMap()

void AtCCI_RelationMap ( void  )

Definition at line 498 of file relmapper.c.

499 {
501  {
504  true);
506  }
508  {
511  true);
513  }
514 }
static RelMapFile pending_local_updates
Definition: relmapper.c:131
static RelMapFile active_local_updates
Definition: relmapper.c:129
static RelMapFile pending_shared_updates
Definition: relmapper.c:130
static void merge_map_updates(RelMapFile *map, const RelMapFile *updates, bool add_okay)
Definition: relmapper.c:410
static RelMapFile active_shared_updates
Definition: relmapper.c:128
int32 num_mappings
Definition: relmapper.c:88

References active_local_updates, active_shared_updates, merge_map_updates(), RelMapFile::num_mappings, pending_local_updates, and pending_shared_updates.

Referenced by AtCCI_LocalCache().

◆ AtEOXact_RelationMap()

void AtEOXact_RelationMap ( bool  isCommit,
bool  isParallelWorker 
)

Definition at line 535 of file relmapper.c.

536 {
537  if (isCommit && !isParallelWorker)
538  {
539  /*
540  * We should not get here with any "pending" updates. (We could
541  * logically choose to treat such as committed, but in the current
542  * code this should never happen.)
543  */
546 
547  /*
548  * Write any active updates to the actual map files, then reset them.
549  */
551  {
554  }
556  {
559  }
560  }
561  else
562  {
563  /* Abort or parallel worker --- drop all local and pending updates */
564  Assert(!isParallelWorker || pending_shared_updates.num_mappings == 0);
565  Assert(!isParallelWorker || pending_local_updates.num_mappings == 0);
566 
571  }
572 }
Assert(fmt[strlen(fmt) - 1] !='\n')
static void perform_relmap_update(bool shared, const RelMapFile *updates)
Definition: relmapper.c:1006

References active_local_updates, active_shared_updates, Assert(), RelMapFile::num_mappings, pending_local_updates, pending_shared_updates, and perform_relmap_update().

Referenced by AbortTransaction(), and CommitTransaction().

◆ AtPrepare_RelationMap()

void AtPrepare_RelationMap ( void  )

Definition at line 582 of file relmapper.c.

583 {
588  ereport(ERROR,
589  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
590  errmsg("cannot PREPARE a transaction that modified relation mapping")));
591 }
int errcode(int sqlerrcode)
Definition: elog.c:693
int errmsg(const char *fmt,...)
Definition: elog.c:904
#define ERROR
Definition: elog.h:33
#define ereport(elevel,...)
Definition: elog.h:143

References active_local_updates, active_shared_updates, ereport, errcode(), errmsg(), ERROR, RelMapFile::num_mappings, pending_local_updates, and pending_shared_updates.

Referenced by PrepareTransaction().

◆ CheckPointRelationMap()

void CheckPointRelationMap ( void  )

Definition at line 605 of file relmapper.c.

606 {
607  LWLockAcquire(RelationMappingLock, LW_SHARED);
608  LWLockRelease(RelationMappingLock);
609 }
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1196
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1800
@ LW_SHARED
Definition: lwlock.h:105

References LW_SHARED, LWLockAcquire(), and LWLockRelease().

Referenced by CheckPointGuts().

◆ EstimateRelationMapSpace()

Size EstimateRelationMapSpace ( void  )

Definition at line 705 of file relmapper.c.

706 {
707  return sizeof(SerializedActiveRelMaps);
708 }
struct SerializedActiveRelMaps SerializedActiveRelMaps

Referenced by InitializeParallelDSM(), and SerializeRelationMap().

◆ RelationMapCopy()

void RelationMapCopy ( Oid  dbid,
Oid  tsid,
char *  srcdbpath,
char *  dstdbpath 
)

Definition at line 288 of file relmapper.c.

289 {
290  RelMapFile map;
291 
292  /*
293  * Read the relmap file from the source database.
294  */
295  read_relmap_file(&map, srcdbpath, false, ERROR);
296 
297  /*
298  * Write the same data into the destination database's relmap file.
299  *
300  * No sinval is needed because no one can be connected to the destination
301  * database yet. For the same reason, there is no need to acquire
302  * RelationMappingLock.
303  *
304  * There's no point in trying to preserve files here. The new database
305  * isn't usable yet anyway, and won't ever be if we can't install a relmap
306  * file.
307  */
308  write_relmap_file(&map, true, false, false, dbid, tsid, dstdbpath);
309 }
static void write_relmap_file(RelMapFile *newmap, bool write_wal, bool send_sinval, bool preserve_files, Oid dbid, Oid tsid, const char *dbpath)
Definition: relmapper.c:873
static void read_relmap_file(RelMapFile *map, char *dbpath, bool lock_held, int elevel)
Definition: relmapper.c:776

References ERROR, read_relmap_file(), and write_relmap_file().

Referenced by CreateDatabaseUsingWalLog().

◆ RelationMapFilenodeToOid()

Oid RelationMapFilenodeToOid ( Oid  relationId,
bool  shared 
)

Definition at line 214 of file relmapper.c.

215 {
216  const RelMapFile *map;
217  int32 i;
218 
219  /* If there are active updates, believe those over the main maps */
220  if (shared)
221  {
222  map = &active_shared_updates;
223  for (i = 0; i < map->num_mappings; i++)
224  {
225  if (filenode == map->mappings[i].mapfilenode)
226  return map->mappings[i].mapoid;
227  }
228  map = &shared_map;
229  for (i = 0; i < map->num_mappings; i++)
230  {
231  if (filenode == map->mappings[i].mapfilenode)
232  return map->mappings[i].mapoid;
233  }
234  }
235  else
236  {
237  map = &active_local_updates;
238  for (i = 0; i < map->num_mappings; i++)
239  {
240  if (filenode == map->mappings[i].mapfilenode)
241  return map->mappings[i].mapoid;
242  }
243  map = &local_map;
244  for (i = 0; i < map->num_mappings; i++)
245  {
246  if (filenode == map->mappings[i].mapfilenode)
247  return map->mappings[i].mapoid;
248  }
249  }
250 
251  return InvalidOid;
252 }
signed int int32
Definition: c.h:429
int i
Definition: isn.c:73
#define InvalidOid
Definition: postgres_ext.h:36
static RelMapFile shared_map
Definition: relmapper.c:109
static RelMapFile local_map
Definition: relmapper.c:110
RelMapping mappings[MAX_MAPPINGS]
Definition: relmapper.c:89
Oid mapoid
Definition: relmapper.c:81
Oid mapfilenode
Definition: relmapper.c:82

References active_local_updates, active_shared_updates, i, InvalidOid, local_map, RelMapping::mapfilenode, RelMapping::mapoid, RelMapFile::mappings, RelMapFile::num_mappings, and shared_map.

Referenced by RelidByRelfilenode().

◆ RelationMapFinishBootstrap()

void RelationMapFinishBootstrap ( void  )

Definition at line 619 of file relmapper.c.

620 {
622 
623  /* Shouldn't be anything "pending" ... */
628 
629  /* Write the files; no WAL or sinval needed */
630  write_relmap_file(&shared_map, false, false, false,
631  InvalidOid, GLOBALTABLESPACE_OID, "global");
632  write_relmap_file(&local_map, false, false, false,
634 }
Oid MyDatabaseTableSpace
Definition: globals.c:91
char * DatabasePath
Definition: globals.c:97
Oid MyDatabaseId
Definition: globals.c:89
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:406

References active_local_updates, active_shared_updates, Assert(), DatabasePath, InvalidOid, IsBootstrapProcessingMode, local_map, MyDatabaseId, MyDatabaseTableSpace, RelMapFile::num_mappings, pending_local_updates, pending_shared_updates, shared_map, and write_relmap_file().

Referenced by BootstrapModeMain().

◆ RelationMapInitialize()

void RelationMapInitialize ( void  )

Definition at line 643 of file relmapper.c.

644 {
645  /* The static variables should initialize to zeroes, but let's be sure */
646  shared_map.magic = 0; /* mark it not loaded */
647  local_map.magic = 0;
654 }
int32 magic
Definition: relmapper.c:87

References active_local_updates, active_shared_updates, local_map, RelMapFile::magic, RelMapFile::num_mappings, pending_local_updates, pending_shared_updates, and shared_map.

Referenced by RelationCacheInitialize().

◆ RelationMapInitializePhase2()

void RelationMapInitializePhase2 ( void  )

Definition at line 663 of file relmapper.c.

664 {
665  /*
666  * In bootstrap mode, the map file isn't there yet, so do nothing.
667  */
669  return;
670 
671  /*
672  * Load the shared map file, die on error.
673  */
674  load_relmap_file(true, false);
675 }
static void load_relmap_file(bool shared, bool lock_held)
Definition: relmapper.c:757

References IsBootstrapProcessingMode, and load_relmap_file().

Referenced by RelationCacheInitializePhase2().

◆ RelationMapInitializePhase3()

void RelationMapInitializePhase3 ( void  )

Definition at line 684 of file relmapper.c.

685 {
686  /*
687  * In bootstrap mode, the map file isn't there yet, so do nothing.
688  */
690  return;
691 
692  /*
693  * Load the local map file, die on error.
694  */
695  load_relmap_file(false, false);
696 }

References IsBootstrapProcessingMode, and load_relmap_file().

Referenced by RelationCacheInitializePhase3().

◆ RelationMapInvalidate()

void RelationMapInvalidate ( bool  shared)

Definition at line 462 of file relmapper.c.

463 {
464  if (shared)
465  {
467  load_relmap_file(true, false);
468  }
469  else
470  {
472  load_relmap_file(false, false);
473  }
474 }
#define RELMAPPER_FILEMAGIC
Definition: relmapper.c:75

References load_relmap_file(), local_map, RelMapFile::magic, RELMAPPER_FILEMAGIC, and shared_map.

Referenced by LocalExecuteInvalidationMessage().

◆ RelationMapInvalidateAll()

void RelationMapInvalidateAll ( void  )

Definition at line 484 of file relmapper.c.

485 {
487  load_relmap_file(true, false);
489  load_relmap_file(false, false);
490 }

References load_relmap_file(), local_map, RelMapFile::magic, RELMAPPER_FILEMAGIC, and shared_map.

Referenced by RelationCacheInvalidate().

◆ RelationMapOidToFilenode()

Oid RelationMapOidToFilenode ( Oid  relationId,
bool  shared 
)

Definition at line 161 of file relmapper.c.

162 {
163  const RelMapFile *map;
164  int32 i;
165 
166  /* If there are active updates, believe those over the main maps */
167  if (shared)
168  {
169  map = &active_shared_updates;
170  for (i = 0; i < map->num_mappings; i++)
171  {
172  if (relationId == map->mappings[i].mapoid)
173  return map->mappings[i].mapfilenode;
174  }
175  map = &shared_map;
176  for (i = 0; i < map->num_mappings; i++)
177  {
178  if (relationId == map->mappings[i].mapoid)
179  return map->mappings[i].mapfilenode;
180  }
181  }
182  else
183  {
184  map = &active_local_updates;
185  for (i = 0; i < map->num_mappings; i++)
186  {
187  if (relationId == map->mappings[i].mapoid)
188  return map->mappings[i].mapfilenode;
189  }
190  map = &local_map;
191  for (i = 0; i < map->num_mappings; i++)
192  {
193  if (relationId == map->mappings[i].mapoid)
194  return map->mappings[i].mapfilenode;
195  }
196  }
197 
198  return InvalidOid;
199 }

References active_local_updates, active_shared_updates, i, InvalidOid, local_map, RelMapping::mapfilenode, RelMapping::mapoid, RelMapFile::mappings, RelMapFile::num_mappings, and shared_map.

Referenced by pg_relation_filenode(), pg_relation_filepath(), RelationInitPhysicalAddr(), and swap_relation_files().

◆ RelationMapOidToFilenodeForDatabase()

Oid RelationMapOidToFilenodeForDatabase ( char *  dbpath,
Oid  relationId 
)

Definition at line 261 of file relmapper.c.

262 {
263  RelMapFile map;
264  int i;
265 
266  /* Read the relmap file from the source database. */
267  read_relmap_file(&map, dbpath, false, ERROR);
268 
269  /* Iterate over the relmap entries to find the input relation OID. */
270  for (i = 0; i < map.num_mappings; i++)
271  {
272  if (relationId == map.mappings[i].mapoid)
273  return map.mappings[i].mapfilenode;
274  }
275 
276  return InvalidOid;
277 }

References ERROR, i, InvalidOid, RelMapping::mapfilenode, RelMapping::mapoid, RelMapFile::mappings, RelMapFile::num_mappings, and read_relmap_file().

Referenced by ScanSourceDatabasePgClass(), and ScanSourceDatabasePgClassTuple().

◆ RelationMapRemoveMapping()

void RelationMapRemoveMapping ( Oid  relationId)

Definition at line 432 of file relmapper.c.

433 {
435  int32 i;
436 
437  for (i = 0; i < map->num_mappings; i++)
438  {
439  if (relationId == map->mappings[i].mapoid)
440  {
441  /* Found it, collapse it out */
442  map->mappings[i] = map->mappings[map->num_mappings - 1];
443  map->num_mappings--;
444  return;
445  }
446  }
447  elog(ERROR, "could not find temporary mapping for relation %u",
448  relationId);
449 }
#define elog(elevel,...)
Definition: elog.h:218

References active_local_updates, elog, ERROR, i, RelMapping::mapoid, RelMapFile::mappings, and RelMapFile::num_mappings.

Referenced by finish_heap_swap().

◆ RelationMapUpdateMap()

void RelationMapUpdateMap ( Oid  relationId,
Oid  fileNode,
bool  shared,
bool  immediate 
)

Definition at line 320 of file relmapper.c.

322 {
323  RelMapFile *map;
324 
326  {
327  /*
328  * In bootstrap mode, the mapping gets installed in permanent map.
329  */
330  if (shared)
331  map = &shared_map;
332  else
333  map = &local_map;
334  }
335  else
336  {
337  /*
338  * We don't currently support map changes within subtransactions, or
339  * when in parallel mode. This could be done with more bookkeeping
340  * infrastructure, but it doesn't presently seem worth it.
341  */
343  elog(ERROR, "cannot change relation mapping within subtransaction");
344 
345  if (IsInParallelMode())
346  elog(ERROR, "cannot change relation mapping in parallel mode");
347 
348  if (immediate)
349  {
350  /* Make it active, but only locally */
351  if (shared)
352  map = &active_shared_updates;
353  else
354  map = &active_local_updates;
355  }
356  else
357  {
358  /* Make it pending */
359  if (shared)
360  map = &pending_shared_updates;
361  else
362  map = &pending_local_updates;
363  }
364  }
365  apply_map_update(map, relationId, fileNode, true);
366 }
static void apply_map_update(RelMapFile *map, Oid relationId, Oid fileNode, bool add_okay)
Definition: relmapper.c:378
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:910
bool IsInParallelMode(void)
Definition: xact.c:1065

References active_local_updates, active_shared_updates, apply_map_update(), elog, ERROR, GetCurrentTransactionNestLevel(), IsBootstrapProcessingMode, IsInParallelMode(), local_map, pending_local_updates, pending_shared_updates, and shared_map.

Referenced by formrdesc(), RelationBuildLocalRelation(), RelationSetNewRelfilenode(), and swap_relation_files().

◆ relmap_desc()

void relmap_desc ( StringInfo  buf,
XLogReaderState record 
)

Definition at line 20 of file relmapdesc.c.

21 {
22  char *rec = XLogRecGetData(record);
23  uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
24 
25  if (info == XLOG_RELMAP_UPDATE)
26  {
27  xl_relmap_update *xlrec = (xl_relmap_update *) rec;
28 
29  appendStringInfo(buf, "database %u tablespace %u size %d",
30  xlrec->dbid, xlrec->tsid, xlrec->nbytes);
31  }
32 }
unsigned char uint8
Definition: c.h:439
static char * buf
Definition: pg_test_fsync.c:67
#define XLOG_RELMAP_UPDATE
Definition: relmapper.h:25
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:408
#define XLogRecGetData(decoder)
Definition: xlogreader.h:413
#define XLR_INFO_MASK
Definition: xlogrecord.h:62

References appendStringInfo(), buf, xl_relmap_update::dbid, xl_relmap_update::nbytes, xl_relmap_update::tsid, XLOG_RELMAP_UPDATE, XLogRecGetData, XLogRecGetInfo, and XLR_INFO_MASK.

◆ relmap_identify()

const char* relmap_identify ( uint8  info)

Definition at line 35 of file relmapdesc.c.

36 {
37  const char *id = NULL;
38 
39  switch (info & ~XLR_INFO_MASK)
40  {
41  case XLOG_RELMAP_UPDATE:
42  id = "UPDATE";
43  break;
44  }
45 
46  return id;
47 }

References XLOG_RELMAP_UPDATE, and XLR_INFO_MASK.

◆ relmap_redo()

void relmap_redo ( XLogReaderState record)

Definition at line 1063 of file relmapper.c.

1064 {
1065  uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
1066 
1067  /* Backup blocks are not used in relmap records */
1068  Assert(!XLogRecHasAnyBlockRefs(record));
1069 
1070  if (info == XLOG_RELMAP_UPDATE)
1071  {
1072  xl_relmap_update *xlrec = (xl_relmap_update *) XLogRecGetData(record);
1073  RelMapFile newmap;
1074  char *dbpath;
1075 
1076  if (xlrec->nbytes != sizeof(RelMapFile))
1077  elog(PANIC, "relmap_redo: wrong size %u in relmap update record",
1078  xlrec->nbytes);
1079  memcpy(&newmap, xlrec->data, sizeof(newmap));
1080 
1081  /* We need to construct the pathname for this database */
1082  dbpath = GetDatabasePath(xlrec->dbid, xlrec->tsid);
1083 
1084  /*
1085  * Write out the new map and send sinval, but of course don't write a
1086  * new WAL entry. There's no surrounding transaction to tell to
1087  * preserve files, either.
1088  *
1089  * There shouldn't be anyone else updating relmaps during WAL replay,
1090  * but grab the lock to interlock against load_relmap_file().
1091  *
1092  * Note that we use the same WAL record for updating the relmap of an
1093  * existing database as we do for creating a new database. In the
1094  * latter case, taking the relmap log and sending sinval messages is
1095  * unnecessary, but harmless. If we wanted to avoid it, we could add a
1096  * flag to the WAL record to indicate which operation is being
1097  * performed.
1098  */
1099  LWLockAcquire(RelationMappingLock, LW_EXCLUSIVE);
1100  write_relmap_file(&newmap, false, true, false,
1101  xlrec->dbid, xlrec->tsid, dbpath);
1102  LWLockRelease(RelationMappingLock);
1103 
1104  pfree(dbpath);
1105  }
1106  else
1107  elog(PANIC, "relmap_redo: unknown op code %u", info);
1108 }
#define PANIC
Definition: elog.h:36
@ LW_EXCLUSIVE
Definition: lwlock.h:104
void pfree(void *pointer)
Definition: mcxt.c:1175
char * GetDatabasePath(Oid dbNode, Oid spcNode)
Definition: relpath.c:110
char data[FLEXIBLE_ARRAY_MEMBER]
Definition: relmapper.h:32
#define XLogRecHasAnyBlockRefs(decoder)
Definition: xlogreader.h:415

References Assert(), xl_relmap_update::data, xl_relmap_update::dbid, elog, GetDatabasePath(), LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), xl_relmap_update::nbytes, PANIC, pfree(), xl_relmap_update::tsid, write_relmap_file(), XLOG_RELMAP_UPDATE, XLogRecGetData, XLogRecGetInfo, XLogRecHasAnyBlockRefs, and XLR_INFO_MASK.

◆ RestoreRelationMap()

void RestoreRelationMap ( char *  startAddress)

◆ SerializeRelationMap()

void SerializeRelationMap ( Size  maxSize,
char *  startAddress 
)