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

RelFileNumber RelationMapOidToFilenumber (Oid relationId, bool shared)
 
Oid RelationMapFilenumberToOid (RelFileNumber filenumber, bool shared)
 
RelFileNumber RelationMapOidToFilenumberForDatabase (char *dbpath, Oid relationId)
 
void RelationMapCopy (Oid dbid, Oid tsid, char *srcdbpath, char *dstdbpath)
 
void RelationMapUpdateMap (Oid relationId, RelFileNumber fileNumber, 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 504 of file relmapper.c.

505 {
507  {
510  true);
512  }
514  {
517  true);
519  }
520 }
static RelMapFile pending_local_updates
Definition: relmapper.c:134
static RelMapFile active_local_updates
Definition: relmapper.c:132
static RelMapFile pending_shared_updates
Definition: relmapper.c:133
static void merge_map_updates(RelMapFile *map, const RelMapFile *updates, bool add_okay)
Definition: relmapper.c:416
static RelMapFile active_shared_updates
Definition: relmapper.c:131
int32 num_mappings
Definition: relmapper.c:92

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 541 of file relmapper.c.

542 {
543  if (isCommit && !isParallelWorker)
544  {
545  /*
546  * We should not get here with any "pending" updates. (We could
547  * logically choose to treat such as committed, but in the current
548  * code this should never happen.)
549  */
552 
553  /*
554  * Write any active updates to the actual map files, then reset them.
555  */
557  {
560  }
562  {
565  }
566  }
567  else
568  {
569  /* Abort or parallel worker --- drop all local and pending updates */
570  Assert(!isParallelWorker || pending_shared_updates.num_mappings == 0);
571  Assert(!isParallelWorker || pending_local_updates.num_mappings == 0);
572 
577  }
578 }
#define Assert(condition)
Definition: c.h:858
static void perform_relmap_update(bool shared, const RelMapFile *updates)
Definition: relmapper.c:1039

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 588 of file relmapper.c.

589 {
594  ereport(ERROR,
595  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
596  errmsg("cannot PREPARE a transaction that modified relation mapping")));
597 }
int errcode(int sqlerrcode)
Definition: elog.c:859
int errmsg(const char *fmt,...)
Definition: elog.c:1072
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149

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 611 of file relmapper.c.

612 {
613  LWLockAcquire(RelationMappingLock, LW_SHARED);
614  LWLockRelease(RelationMappingLock);
615 }
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1170
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1783
@ LW_SHARED
Definition: lwlock.h:115

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

Referenced by CheckPointGuts().

◆ EstimateRelationMapSpace()

Size EstimateRelationMapSpace ( void  )

Definition at line 713 of file relmapper.c.

714 {
715  return sizeof(SerializedActiveRelMaps);
716 }
struct SerializedActiveRelMaps SerializedActiveRelMaps

Referenced by InitializeParallelDSM(), and SerializeRelationMap().

◆ RelationMapCopy()

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

Definition at line 292 of file relmapper.c.

293 {
294  RelMapFile map;
295 
296  /*
297  * Read the relmap file from the source database.
298  */
299  read_relmap_file(&map, srcdbpath, false, ERROR);
300 
301  /*
302  * Write the same data into the destination database's relmap file.
303  *
304  * No sinval is needed because no one can be connected to the destination
305  * database yet.
306  *
307  * There's no point in trying to preserve files here. The new database
308  * isn't usable yet anyway, and won't ever be if we can't install a relmap
309  * file.
310  */
311  LWLockAcquire(RelationMappingLock, LW_EXCLUSIVE);
312  write_relmap_file(&map, true, false, false, dbid, tsid, dstdbpath);
313  LWLockRelease(RelationMappingLock);
314 }
@ LW_EXCLUSIVE
Definition: lwlock.h:114
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:889
static void read_relmap_file(RelMapFile *map, char *dbpath, bool lock_held, int elevel)
Definition: relmapper.c:784

References ERROR, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), read_relmap_file(), and write_relmap_file().

Referenced by CreateDatabaseUsingWalLog().

◆ RelationMapFilenumberToOid()

Oid RelationMapFilenumberToOid ( RelFileNumber  filenumber,
bool  shared 
)

Definition at line 218 of file relmapper.c.

219 {
220  const RelMapFile *map;
221  int32 i;
222 
223  /* If there are active updates, believe those over the main maps */
224  if (shared)
225  {
226  map = &active_shared_updates;
227  for (i = 0; i < map->num_mappings; i++)
228  {
229  if (filenumber == map->mappings[i].mapfilenumber)
230  return map->mappings[i].mapoid;
231  }
232  map = &shared_map;
233  for (i = 0; i < map->num_mappings; i++)
234  {
235  if (filenumber == map->mappings[i].mapfilenumber)
236  return map->mappings[i].mapoid;
237  }
238  }
239  else
240  {
241  map = &active_local_updates;
242  for (i = 0; i < map->num_mappings; i++)
243  {
244  if (filenumber == map->mappings[i].mapfilenumber)
245  return map->mappings[i].mapoid;
246  }
247  map = &local_map;
248  for (i = 0; i < map->num_mappings; i++)
249  {
250  if (filenumber == map->mappings[i].mapfilenumber)
251  return map->mappings[i].mapoid;
252  }
253  }
254 
255  return InvalidOid;
256 }
signed int int32
Definition: c.h:494
int i
Definition: isn.c:73
#define InvalidOid
Definition: postgres_ext.h:36
static RelMapFile shared_map
Definition: relmapper.c:112
static RelMapFile local_map
Definition: relmapper.c:113
RelMapping mappings[MAX_MAPPINGS]
Definition: relmapper.c:93
Oid mapoid
Definition: relmapper.c:85
RelFileNumber mapfilenumber
Definition: relmapper.c:86

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

Referenced by RelidByRelfilenumber().

◆ RelationMapFinishBootstrap()

void RelationMapFinishBootstrap ( void  )

Definition at line 625 of file relmapper.c.

626 {
628 
629  /* Shouldn't be anything "pending" ... */
634 
635  /* Write the files; no WAL or sinval needed */
636  LWLockAcquire(RelationMappingLock, LW_EXCLUSIVE);
637  write_relmap_file(&shared_map, false, false, false,
638  InvalidOid, GLOBALTABLESPACE_OID, "global");
639  write_relmap_file(&local_map, false, false, false,
641  LWLockRelease(RelationMappingLock);
642 }
Oid MyDatabaseTableSpace
Definition: globals.c:93
char * DatabasePath
Definition: globals.c:101
Oid MyDatabaseId
Definition: globals.c:91
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:454

References active_local_updates, active_shared_updates, Assert, DatabasePath, InvalidOid, IsBootstrapProcessingMode, local_map, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), 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 651 of file relmapper.c.

652 {
653  /* The static variables should initialize to zeroes, but let's be sure */
654  shared_map.magic = 0; /* mark it not loaded */
655  local_map.magic = 0;
662 }
int32 magic
Definition: relmapper.c:91

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 671 of file relmapper.c.

672 {
673  /*
674  * In bootstrap mode, the map file isn't there yet, so do nothing.
675  */
677  return;
678 
679  /*
680  * Load the shared map file, die on error.
681  */
682  load_relmap_file(true, false);
683 }
static void load_relmap_file(bool shared, bool lock_held)
Definition: relmapper.c:765

References IsBootstrapProcessingMode, and load_relmap_file().

Referenced by RelationCacheInitializePhase2().

◆ RelationMapInitializePhase3()

void RelationMapInitializePhase3 ( void  )

Definition at line 692 of file relmapper.c.

693 {
694  /*
695  * In bootstrap mode, the map file isn't there yet, so do nothing.
696  */
698  return;
699 
700  /*
701  * Load the local map file, die on error.
702  */
703  load_relmap_file(false, false);
704 }

References IsBootstrapProcessingMode, and load_relmap_file().

Referenced by RelationCacheInitializePhase3().

◆ RelationMapInvalidate()

void RelationMapInvalidate ( bool  shared)

Definition at line 468 of file relmapper.c.

469 {
470  if (shared)
471  {
473  load_relmap_file(true, false);
474  }
475  else
476  {
478  load_relmap_file(false, false);
479  }
480 }
#define RELMAPPER_FILEMAGIC
Definition: relmapper.c:73

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

Referenced by LocalExecuteInvalidationMessage().

◆ RelationMapInvalidateAll()

void RelationMapInvalidateAll ( void  )

Definition at line 490 of file relmapper.c.

491 {
493  load_relmap_file(true, false);
495  load_relmap_file(false, false);
496 }

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

Referenced by RelationCacheInvalidate().

◆ RelationMapOidToFilenumber()

RelFileNumber RelationMapOidToFilenumber ( Oid  relationId,
bool  shared 
)

Definition at line 165 of file relmapper.c.

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

References active_local_updates, active_shared_updates, i, InvalidRelFileNumber, local_map, RelMapping::mapfilenumber, RelMapping::mapoid, RelMapFile::mappings, RelMapFile::num_mappings, and shared_map.

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

◆ RelationMapOidToFilenumberForDatabase()

RelFileNumber RelationMapOidToFilenumberForDatabase ( char *  dbpath,
Oid  relationId 
)

Definition at line 265 of file relmapper.c.

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

References ERROR, i, InvalidRelFileNumber, RelMapping::mapfilenumber, RelMapping::mapoid, RelMapFile::mappings, RelMapFile::num_mappings, and read_relmap_file().

Referenced by ScanSourceDatabasePgClass(), and ScanSourceDatabasePgClassTuple().

◆ RelationMapRemoveMapping()

void RelationMapRemoveMapping ( Oid  relationId)

Definition at line 438 of file relmapper.c.

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

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,
RelFileNumber  fileNumber,
bool  shared,
bool  immediate 
)

Definition at line 325 of file relmapper.c.

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

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(), RelationSetNewRelfilenumber(), 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:504
static char * buf
Definition: pg_test_fsync.c:73
#define XLOG_RELMAP_UPDATE
Definition: relmapper.h:25
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:97
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:410
#define XLogRecGetData(decoder)
Definition: xlogreader.h:415
#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 1096 of file relmapper.c.

1097 {
1098  uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
1099 
1100  /* Backup blocks are not used in relmap records */
1101  Assert(!XLogRecHasAnyBlockRefs(record));
1102 
1103  if (info == XLOG_RELMAP_UPDATE)
1104  {
1105  xl_relmap_update *xlrec = (xl_relmap_update *) XLogRecGetData(record);
1106  RelMapFile newmap;
1107  char *dbpath;
1108 
1109  if (xlrec->nbytes != sizeof(RelMapFile))
1110  elog(PANIC, "relmap_redo: wrong size %u in relmap update record",
1111  xlrec->nbytes);
1112  memcpy(&newmap, xlrec->data, sizeof(newmap));
1113 
1114  /* We need to construct the pathname for this database */
1115  dbpath = GetDatabasePath(xlrec->dbid, xlrec->tsid);
1116 
1117  /*
1118  * Write out the new map and send sinval, but of course don't write a
1119  * new WAL entry. There's no surrounding transaction to tell to
1120  * preserve files, either.
1121  *
1122  * There shouldn't be anyone else updating relmaps during WAL replay,
1123  * but grab the lock to interlock against load_relmap_file().
1124  *
1125  * Note that we use the same WAL record for updating the relmap of an
1126  * existing database as we do for creating a new database. In the
1127  * latter case, taking the relmap log and sending sinval messages is
1128  * unnecessary, but harmless. If we wanted to avoid it, we could add a
1129  * flag to the WAL record to indicate which operation is being
1130  * performed.
1131  */
1132  LWLockAcquire(RelationMappingLock, LW_EXCLUSIVE);
1133  write_relmap_file(&newmap, false, true, false,
1134  xlrec->dbid, xlrec->tsid, dbpath);
1135  LWLockRelease(RelationMappingLock);
1136 
1137  pfree(dbpath);
1138  }
1139  else
1140  elog(PANIC, "relmap_redo: unknown op code %u", info);
1141 }
#define PANIC
Definition: elog.h:42
void pfree(void *pointer)
Definition: mcxt.c:1520
char * GetDatabasePath(Oid dbOid, Oid spcOid)
Definition: relpath.c:110
char data[FLEXIBLE_ARRAY_MEMBER]
Definition: relmapper.h:32
#define XLogRecHasAnyBlockRefs(decoder)
Definition: xlogreader.h:417

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 
)