PostgreSQL Source Code  git master
relmapper.c File Reference
#include "postgres.h"
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include "access/xact.h"
#include "access/xlog.h"
#include "access/xloginsert.h"
#include "catalog/catalog.h"
#include "catalog/pg_tablespace.h"
#include "catalog/storage.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "storage/fd.h"
#include "storage/lwlock.h"
#include "utils/inval.h"
#include "utils/relmapper.h"
Include dependency graph for relmapper.c:

Go to the source code of this file.

Data Structures

struct  RelMapping
 
struct  RelMapFile
 
struct  SerializedActiveRelMaps
 

Macros

#define RELMAPPER_FILENAME   "pg_filenode.map"
 
#define RELMAPPER_FILEMAGIC   0x592717 /* version ID value */
 
#define MAX_MAPPINGS   62 /* 62 * 8 + 16 = 512 */
 

Typedefs

typedef struct RelMapping RelMapping
 
typedef struct RelMapFile RelMapFile
 
typedef struct SerializedActiveRelMaps SerializedActiveRelMaps
 

Functions

static void apply_map_update (RelMapFile *map, Oid relationId, Oid fileNode, bool add_okay)
 
static void merge_map_updates (RelMapFile *map, const RelMapFile *updates, bool add_okay)
 
static void load_relmap_file (bool shared, bool lock_held)
 
static void write_relmap_file (bool shared, RelMapFile *newmap, bool write_wal, bool send_sinval, bool preserve_files, Oid dbid, Oid tsid, const char *dbpath)
 
static void perform_relmap_update (bool shared, const RelMapFile *updates)
 
Oid RelationMapOidToFilenode (Oid relationId, bool shared)
 
Oid RelationMapFilenodeToOid (Oid filenode, bool shared)
 
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)
 

Variables

static RelMapFile shared_map
 
static RelMapFile local_map
 
static RelMapFile active_shared_updates
 
static RelMapFile active_local_updates
 
static RelMapFile pending_shared_updates
 
static RelMapFile pending_local_updates
 

Macro Definition Documentation

◆ MAX_MAPPINGS

#define MAX_MAPPINGS   62 /* 62 * 8 + 16 = 512 */

Definition at line 77 of file relmapper.c.

Referenced by apply_map_update(), load_relmap_file(), and write_relmap_file().

◆ RELMAPPER_FILEMAGIC

#define RELMAPPER_FILEMAGIC   0x592717 /* version ID value */

◆ RELMAPPER_FILENAME

#define RELMAPPER_FILENAME   "pg_filenode.map"

Definition at line 73 of file relmapper.c.

Referenced by load_relmap_file(), and write_relmap_file().

Typedef Documentation

◆ RelMapFile

typedef struct RelMapFile RelMapFile

◆ RelMapping

typedef struct RelMapping RelMapping

◆ SerializedActiveRelMaps

Function Documentation

◆ apply_map_update()

static void apply_map_update ( RelMapFile map,
Oid  relationId,
Oid  fileNode,
bool  add_okay 
)
static

Definition at line 319 of file relmapper.c.

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

Referenced by merge_map_updates(), and RelationMapUpdateMap().

320 {
321  int32 i;
322 
323  /* Replace any existing mapping */
324  for (i = 0; i < map->num_mappings; i++)
325  {
326  if (relationId == map->mappings[i].mapoid)
327  {
328  map->mappings[i].mapfilenode = fileNode;
329  return;
330  }
331  }
332 
333  /* Nope, need to add a new mapping */
334  if (!add_okay)
335  elog(ERROR, "attempt to apply a mapping to unmapped relation %u",
336  relationId);
337  if (map->num_mappings >= MAX_MAPPINGS)
338  elog(ERROR, "ran out of space in relation map");
339  map->mappings[map->num_mappings].mapoid = relationId;
340  map->mappings[map->num_mappings].mapfilenode = fileNode;
341  map->num_mappings++;
342 }
Oid mapoid
Definition: relmapper.c:81
#define MAX_MAPPINGS
Definition: relmapper.c:77
signed int int32
Definition: c.h:429
#define ERROR
Definition: elog.h:46
RelMapping mappings[MAX_MAPPINGS]
Definition: relmapper.c:89
Oid mapfilenode
Definition: relmapper.c:82
#define elog(elevel,...)
Definition: elog.h:232
int i
int32 num_mappings
Definition: relmapper.c:88

◆ AtCCI_RelationMap()

void AtCCI_RelationMap ( void  )

Definition at line 439 of file relmapper.c.

References merge_map_updates(), and RelMapFile::num_mappings.

Referenced by AtCCI_LocalCache().

440 {
442  {
445  true);
447  }
449  {
452  true);
454  }
455 }
static void merge_map_updates(RelMapFile *map, const RelMapFile *updates, bool add_okay)
Definition: relmapper.c:351
static RelMapFile pending_shared_updates
Definition: relmapper.c:130
static RelMapFile active_local_updates
Definition: relmapper.c:129
static RelMapFile pending_local_updates
Definition: relmapper.c:131
static RelMapFile active_shared_updates
Definition: relmapper.c:128
int32 num_mappings
Definition: relmapper.c:88

◆ AtEOXact_RelationMap()

void AtEOXact_RelationMap ( bool  isCommit,
bool  isParallelWorker 
)

Definition at line 476 of file relmapper.c.

References Assert, RelMapFile::num_mappings, and perform_relmap_update().

Referenced by AbortTransaction(), and CommitTransaction().

477 {
478  if (isCommit && !isParallelWorker)
479  {
480  /*
481  * We should not get here with any "pending" updates. (We could
482  * logically choose to treat such as committed, but in the current
483  * code this should never happen.)
484  */
487 
488  /*
489  * Write any active updates to the actual map files, then reset them.
490  */
492  {
495  }
497  {
500  }
501  }
502  else
503  {
504  /* Abort or parallel worker --- drop all local and pending updates */
505  Assert(!isParallelWorker || pending_shared_updates.num_mappings == 0);
506  Assert(!isParallelWorker || pending_local_updates.num_mappings == 0);
507 
512  }
513 }
static RelMapFile pending_shared_updates
Definition: relmapper.c:130
static void perform_relmap_update(bool shared, const RelMapFile *updates)
Definition: relmapper.c:958
static RelMapFile active_local_updates
Definition: relmapper.c:129
static RelMapFile pending_local_updates
Definition: relmapper.c:131
static RelMapFile active_shared_updates
Definition: relmapper.c:128
#define Assert(condition)
Definition: c.h:804
int32 num_mappings
Definition: relmapper.c:88

◆ AtPrepare_RelationMap()

void AtPrepare_RelationMap ( void  )

Definition at line 523 of file relmapper.c.

References ereport, errcode(), errmsg(), ERROR, and RelMapFile::num_mappings.

Referenced by PrepareTransaction().

524 {
529  ereport(ERROR,
530  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
531  errmsg("cannot PREPARE a transaction that modified relation mapping")));
532 }
int errcode(int sqlerrcode)
Definition: elog.c:698
static RelMapFile pending_shared_updates
Definition: relmapper.c:130
#define ERROR
Definition: elog.h:46
static RelMapFile active_local_updates
Definition: relmapper.c:129
static RelMapFile pending_local_updates
Definition: relmapper.c:131
static RelMapFile active_shared_updates
Definition: relmapper.c:128
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909
int32 num_mappings
Definition: relmapper.c:88

◆ CheckPointRelationMap()

void CheckPointRelationMap ( void  )

Definition at line 546 of file relmapper.c.

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

Referenced by CheckPointGuts().

547 {
548  LWLockAcquire(RelationMappingLock, LW_SHARED);
549  LWLockRelease(RelationMappingLock);
550 }
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1803
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1199

◆ EstimateRelationMapSpace()

Size EstimateRelationMapSpace ( void  )

Definition at line 646 of file relmapper.c.

Referenced by InitializeParallelDSM(), and SerializeRelationMap().

647 {
648  return sizeof(SerializedActiveRelMaps);
649 }
struct SerializedActiveRelMaps SerializedActiveRelMaps

◆ load_relmap_file()

static void load_relmap_file ( bool  shared,
bool  lock_held 
)
static

Definition at line 698 of file relmapper.c.

References CloseTransientFile(), COMP_CRC32C, DatabasePath, EQ_CRC32C, ereport, errcode(), ERRCODE_DATA_CORRUPTED, errcode_for_file_access(), errmsg(), FATAL, fd(), FIN_CRC32C, INIT_CRC32C, local_map, LW_SHARED, LWLockAcquire(), LWLockRelease(), RelMapFile::magic, MAX_MAPPINGS, MAXPGPATH, RelMapFile::num_mappings, offsetof, OpenTransientFile(), PG_BINARY, pgstat_report_wait_end(), pgstat_report_wait_start(), read, RELMAPPER_FILEMAGIC, RELMAPPER_FILENAME, shared_map, snprintf, and WAIT_EVENT_RELATION_MAP_READ.

Referenced by perform_relmap_update(), RelationMapInitializePhase2(), RelationMapInitializePhase3(), RelationMapInvalidate(), and RelationMapInvalidateAll().

699 {
700  RelMapFile *map;
701  char mapfilename[MAXPGPATH];
702  pg_crc32c crc;
703  int fd;
704  int r;
705 
706  if (shared)
707  {
708  snprintf(mapfilename, sizeof(mapfilename), "global/%s",
710  map = &shared_map;
711  }
712  else
713  {
714  snprintf(mapfilename, sizeof(mapfilename), "%s/%s",
716  map = &local_map;
717  }
718 
719  /* Read data ... */
720  fd = OpenTransientFile(mapfilename, O_RDONLY | PG_BINARY);
721  if (fd < 0)
722  ereport(FATAL,
724  errmsg("could not open file \"%s\": %m",
725  mapfilename)));
726 
727  /*
728  * Grab the lock to prevent the file from being updated while we read it,
729  * unless the caller is already holding the lock. If the file is updated
730  * shortly after we look, the sinval signaling mechanism will make us
731  * re-read it before we are able to access any relation that's affected by
732  * the change.
733  */
734  if (!lock_held)
735  LWLockAcquire(RelationMappingLock, LW_SHARED);
736 
738  r = read(fd, map, sizeof(RelMapFile));
739  if (r != sizeof(RelMapFile))
740  {
741  if (r < 0)
742  ereport(FATAL,
744  errmsg("could not read file \"%s\": %m", mapfilename)));
745  else
746  ereport(FATAL,
748  errmsg("could not read file \"%s\": read %d of %zu",
749  mapfilename, r, sizeof(RelMapFile))));
750  }
752 
753  if (!lock_held)
754  LWLockRelease(RelationMappingLock);
755 
756  if (CloseTransientFile(fd) != 0)
757  ereport(FATAL,
759  errmsg("could not close file \"%s\": %m",
760  mapfilename)));
761 
762  /* check for correct magic number, etc */
763  if (map->magic != RELMAPPER_FILEMAGIC ||
764  map->num_mappings < 0 ||
765  map->num_mappings > MAX_MAPPINGS)
766  ereport(FATAL,
767  (errmsg("relation mapping file \"%s\" contains invalid data",
768  mapfilename)));
769 
770  /* verify the CRC */
771  INIT_CRC32C(crc);
772  COMP_CRC32C(crc, (char *) map, offsetof(RelMapFile, crc));
773  FIN_CRC32C(crc);
774 
775  if (!EQ_CRC32C(crc, map->crc))
776  ereport(FATAL,
777  (errmsg("relation mapping file \"%s\" contains incorrect checksum",
778  mapfilename)));
779 }
#define INIT_CRC32C(crc)
Definition: pg_crc32c.h:41
static void pgstat_report_wait_end(void)
Definition: wait_event.h:274
int32 magic
Definition: relmapper.c:87
static RelMapFile local_map
Definition: relmapper.c:110
uint32 pg_crc32c
Definition: pg_crc32c.h:38
int errcode(int sqlerrcode)
Definition: elog.c:698
#define MAX_MAPPINGS
Definition: relmapper.c:77
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1271
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1803
#define RELMAPPER_FILEMAGIC
Definition: relmapper.c:75
static RelMapFile shared_map
Definition: relmapper.c:109
int OpenTransientFile(const char *fileName, int fileFlags)
Definition: fd.c:2509
#define FATAL
Definition: elog.h:49
#define MAXPGPATH
int errcode_for_file_access(void)
Definition: elog.c:721
#define EQ_CRC32C(c1, c2)
Definition: pg_crc32c.h:42
#define RELMAPPER_FILENAME
Definition: relmapper.c:73
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:258
#define ERRCODE_DATA_CORRUPTED
Definition: pg_basebackup.c:47
int CloseTransientFile(int fd)
Definition: fd.c:2686
#define ereport(elevel,...)
Definition: elog.h:157
char * DatabasePath
Definition: globals.c:96
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1199
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define COMP_CRC32C(crc, data, len)
Definition: pg_crc32c.h:89
#define FIN_CRC32C(crc)
Definition: pg_crc32c.h:94
#define snprintf
Definition: port.h:217
int32 num_mappings
Definition: relmapper.c:88
#define read(a, b, c)
Definition: win32.h:13
#define offsetof(type, field)
Definition: c.h:727

◆ merge_map_updates()

static void merge_map_updates ( RelMapFile map,
const RelMapFile updates,
bool  add_okay 
)
static

Definition at line 351 of file relmapper.c.

References apply_map_update(), i, RelMapping::mapfilenode, RelMapping::mapoid, RelMapFile::mappings, and RelMapFile::num_mappings.

Referenced by AtCCI_RelationMap(), and perform_relmap_update().

352 {
353  int32 i;
354 
355  for (i = 0; i < updates->num_mappings; i++)
356  {
357  apply_map_update(map,
358  updates->mappings[i].mapoid,
359  updates->mappings[i].mapfilenode,
360  add_okay);
361  }
362 }
Oid mapoid
Definition: relmapper.c:81
signed int int32
Definition: c.h:429
RelMapping mappings[MAX_MAPPINGS]
Definition: relmapper.c:89
Oid mapfilenode
Definition: relmapper.c:82
int i
int32 num_mappings
Definition: relmapper.c:88
static void apply_map_update(RelMapFile *map, Oid relationId, Oid fileNode, bool add_okay)
Definition: relmapper.c:319

◆ perform_relmap_update()

static void perform_relmap_update ( bool  shared,
const RelMapFile updates 
)
static

Definition at line 958 of file relmapper.c.

References allowSystemTableMods, DatabasePath, InvalidOid, load_relmap_file(), LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), merge_map_updates(), MyDatabaseId, MyDatabaseTableSpace, and write_relmap_file().

Referenced by AtEOXact_RelationMap().

959 {
960  RelMapFile newmap;
961 
962  /*
963  * Anyone updating a relation's mapping info should take exclusive lock on
964  * that rel and hold it until commit. This ensures that there will not be
965  * concurrent updates on the same mapping value; but there could easily be
966  * concurrent updates on different values in the same file. We cover that
967  * by acquiring the RelationMappingLock, re-reading the target file to
968  * ensure it's up to date, applying the updates, and writing the data
969  * before releasing RelationMappingLock.
970  *
971  * There is only one RelationMappingLock. In principle we could try to
972  * have one per mapping file, but it seems unlikely to be worth the
973  * trouble.
974  */
975  LWLockAcquire(RelationMappingLock, LW_EXCLUSIVE);
976 
977  /* Be certain we see any other updates just made */
978  load_relmap_file(shared, true);
979 
980  /* Prepare updated data in a local variable */
981  if (shared)
982  memcpy(&newmap, &shared_map, sizeof(RelMapFile));
983  else
984  memcpy(&newmap, &local_map, sizeof(RelMapFile));
985 
986  /*
987  * Apply the updates to newmap. No new mappings should appear, unless
988  * somebody is adding indexes to system catalogs.
989  */
990  merge_map_updates(&newmap, updates, allowSystemTableMods);
991 
992  /* Write out the updated map and do other necessary tasks */
993  write_relmap_file(shared, &newmap, true, true, true,
994  (shared ? InvalidOid : MyDatabaseId),
995  (shared ? GLOBALTABLESPACE_OID : MyDatabaseTableSpace),
996  DatabasePath);
997 
998  /* Now we can release the lock */
999  LWLockRelease(RelationMappingLock);
1000 }
static void load_relmap_file(bool shared, bool lock_held)
Definition: relmapper.c:698
static void merge_map_updates(RelMapFile *map, const RelMapFile *updates, bool add_okay)
Definition: relmapper.c:351
static RelMapFile local_map
Definition: relmapper.c:110
static void write_relmap_file(bool shared, RelMapFile *newmap, bool write_wal, bool send_sinval, bool preserve_files, Oid dbid, Oid tsid, const char *dbpath)
Definition: relmapper.c:802
Oid MyDatabaseTableSpace
Definition: globals.c:90
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1803
static RelMapFile shared_map
Definition: relmapper.c:109
Oid MyDatabaseId
Definition: globals.c:88
bool allowSystemTableMods
Definition: globals.c:123
#define InvalidOid
Definition: postgres_ext.h:36
char * DatabasePath
Definition: globals.c:96
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1199

◆ RelationMapFilenodeToOid()

Oid RelationMapFilenodeToOid ( Oid  filenode,
bool  shared 
)

Definition at line 212 of file relmapper.c.

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().

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

◆ RelationMapFinishBootstrap()

void RelationMapFinishBootstrap ( void  )

Definition at line 560 of file relmapper.c.

References Assert, DatabasePath, InvalidOid, IsBootstrapProcessingMode, MyDatabaseId, MyDatabaseTableSpace, RelMapFile::num_mappings, and write_relmap_file().

Referenced by BootstrapModeMain().

561 {
563 
564  /* Shouldn't be anything "pending" ... */
569 
570  /* Write the files; no WAL or sinval needed */
571  write_relmap_file(true, &shared_map, false, false, false,
572  InvalidOid, GLOBALTABLESPACE_OID, NULL);
573  write_relmap_file(false, &local_map, false, false, false,
575 }
static RelMapFile local_map
Definition: relmapper.c:110
static void write_relmap_file(bool shared, RelMapFile *newmap, bool write_wal, bool send_sinval, bool preserve_files, Oid dbid, Oid tsid, const char *dbpath)
Definition: relmapper.c:802
Oid MyDatabaseTableSpace
Definition: globals.c:90
static RelMapFile pending_shared_updates
Definition: relmapper.c:130
static RelMapFile shared_map
Definition: relmapper.c:109
static RelMapFile active_local_updates
Definition: relmapper.c:129
static RelMapFile pending_local_updates
Definition: relmapper.c:131
static RelMapFile active_shared_updates
Definition: relmapper.c:128
Oid MyDatabaseId
Definition: globals.c:88
#define InvalidOid
Definition: postgres_ext.h:36
char * DatabasePath
Definition: globals.c:96
#define Assert(condition)
Definition: c.h:804
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:406
int32 num_mappings
Definition: relmapper.c:88

◆ RelationMapInitialize()

void RelationMapInitialize ( void  )

Definition at line 584 of file relmapper.c.

References RelMapFile::magic, and RelMapFile::num_mappings.

Referenced by RelationCacheInitialize().

585 {
586  /* The static variables should initialize to zeroes, but let's be sure */
587  shared_map.magic = 0; /* mark it not loaded */
588  local_map.magic = 0;
595 }
int32 magic
Definition: relmapper.c:87
static RelMapFile local_map
Definition: relmapper.c:110
static RelMapFile pending_shared_updates
Definition: relmapper.c:130
static RelMapFile shared_map
Definition: relmapper.c:109
static RelMapFile active_local_updates
Definition: relmapper.c:129
static RelMapFile pending_local_updates
Definition: relmapper.c:131
static RelMapFile active_shared_updates
Definition: relmapper.c:128
int32 num_mappings
Definition: relmapper.c:88

◆ RelationMapInitializePhase2()

void RelationMapInitializePhase2 ( void  )

Definition at line 604 of file relmapper.c.

References IsBootstrapProcessingMode, and load_relmap_file().

Referenced by RelationCacheInitializePhase2().

605 {
606  /*
607  * In bootstrap mode, the map file isn't there yet, so do nothing.
608  */
610  return;
611 
612  /*
613  * Load the shared map file, die on error.
614  */
615  load_relmap_file(true, false);
616 }
static void load_relmap_file(bool shared, bool lock_held)
Definition: relmapper.c:698
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:406

◆ RelationMapInitializePhase3()

void RelationMapInitializePhase3 ( void  )

Definition at line 625 of file relmapper.c.

References IsBootstrapProcessingMode, and load_relmap_file().

Referenced by RelationCacheInitializePhase3().

626 {
627  /*
628  * In bootstrap mode, the map file isn't there yet, so do nothing.
629  */
631  return;
632 
633  /*
634  * Load the local map file, die on error.
635  */
636  load_relmap_file(false, false);
637 }
static void load_relmap_file(bool shared, bool lock_held)
Definition: relmapper.c:698
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:406

◆ RelationMapInvalidate()

void RelationMapInvalidate ( bool  shared)

Definition at line 403 of file relmapper.c.

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

Referenced by LocalExecuteInvalidationMessage().

404 {
405  if (shared)
406  {
408  load_relmap_file(true, false);
409  }
410  else
411  {
413  load_relmap_file(false, false);
414  }
415 }
static void load_relmap_file(bool shared, bool lock_held)
Definition: relmapper.c:698
int32 magic
Definition: relmapper.c:87
static RelMapFile local_map
Definition: relmapper.c:110
#define RELMAPPER_FILEMAGIC
Definition: relmapper.c:75
static RelMapFile shared_map
Definition: relmapper.c:109

◆ RelationMapInvalidateAll()

void RelationMapInvalidateAll ( void  )

Definition at line 425 of file relmapper.c.

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

Referenced by RelationCacheInvalidate().

426 {
428  load_relmap_file(true, false);
430  load_relmap_file(false, false);
431 }
static void load_relmap_file(bool shared, bool lock_held)
Definition: relmapper.c:698
int32 magic
Definition: relmapper.c:87
static RelMapFile local_map
Definition: relmapper.c:110
#define RELMAPPER_FILEMAGIC
Definition: relmapper.c:75
static RelMapFile shared_map
Definition: relmapper.c:109

◆ RelationMapOidToFilenode()

Oid RelationMapOidToFilenode ( Oid  relationId,
bool  shared 
)

Definition at line 159 of file relmapper.c.

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().

160 {
161  const RelMapFile *map;
162  int32 i;
163 
164  /* If there are active updates, believe those over the main maps */
165  if (shared)
166  {
167  map = &active_shared_updates;
168  for (i = 0; i < map->num_mappings; i++)
169  {
170  if (relationId == map->mappings[i].mapoid)
171  return map->mappings[i].mapfilenode;
172  }
173  map = &shared_map;
174  for (i = 0; i < map->num_mappings; i++)
175  {
176  if (relationId == map->mappings[i].mapoid)
177  return map->mappings[i].mapfilenode;
178  }
179  }
180  else
181  {
182  map = &active_local_updates;
183  for (i = 0; i < map->num_mappings; i++)
184  {
185  if (relationId == map->mappings[i].mapoid)
186  return map->mappings[i].mapfilenode;
187  }
188  map = &local_map;
189  for (i = 0; i < map->num_mappings; i++)
190  {
191  if (relationId == map->mappings[i].mapoid)
192  return map->mappings[i].mapfilenode;
193  }
194  }
195 
196  return InvalidOid;
197 }
Oid mapoid
Definition: relmapper.c:81
static RelMapFile local_map
Definition: relmapper.c:110
signed int int32
Definition: c.h:429
static RelMapFile shared_map
Definition: relmapper.c:109
static RelMapFile active_local_updates
Definition: relmapper.c:129
RelMapping mappings[MAX_MAPPINGS]
Definition: relmapper.c:89
static RelMapFile active_shared_updates
Definition: relmapper.c:128
#define InvalidOid
Definition: postgres_ext.h:36
Oid mapfilenode
Definition: relmapper.c:82
int i
int32 num_mappings
Definition: relmapper.c:88

◆ RelationMapRemoveMapping()

void RelationMapRemoveMapping ( Oid  relationId)

Definition at line 373 of file relmapper.c.

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

Referenced by finish_heap_swap().

374 {
376  int32 i;
377 
378  for (i = 0; i < map->num_mappings; i++)
379  {
380  if (relationId == map->mappings[i].mapoid)
381  {
382  /* Found it, collapse it out */
383  map->mappings[i] = map->mappings[map->num_mappings - 1];
384  map->num_mappings--;
385  return;
386  }
387  }
388  elog(ERROR, "could not find temporary mapping for relation %u",
389  relationId);
390 }
Oid mapoid
Definition: relmapper.c:81
signed int int32
Definition: c.h:429
#define ERROR
Definition: elog.h:46
static RelMapFile active_local_updates
Definition: relmapper.c:129
RelMapping mappings[MAX_MAPPINGS]
Definition: relmapper.c:89
#define elog(elevel,...)
Definition: elog.h:232
int i
int32 num_mappings
Definition: relmapper.c:88

◆ RelationMapUpdateMap()

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

Definition at line 261 of file relmapper.c.

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().

263 {
264  RelMapFile *map;
265 
267  {
268  /*
269  * In bootstrap mode, the mapping gets installed in permanent map.
270  */
271  if (shared)
272  map = &shared_map;
273  else
274  map = &local_map;
275  }
276  else
277  {
278  /*
279  * We don't currently support map changes within subtransactions, or
280  * when in parallel mode. This could be done with more bookkeeping
281  * infrastructure, but it doesn't presently seem worth it.
282  */
284  elog(ERROR, "cannot change relation mapping within subtransaction");
285 
286  if (IsInParallelMode())
287  elog(ERROR, "cannot change relation mapping in parallel mode");
288 
289  if (immediate)
290  {
291  /* Make it active, but only locally */
292  if (shared)
293  map = &active_shared_updates;
294  else
295  map = &active_local_updates;
296  }
297  else
298  {
299  /* Make it pending */
300  if (shared)
301  map = &pending_shared_updates;
302  else
303  map = &pending_local_updates;
304  }
305  }
306  apply_map_update(map, relationId, fileNode, true);
307 }
static RelMapFile local_map
Definition: relmapper.c:110
static RelMapFile pending_shared_updates
Definition: relmapper.c:130
bool IsInParallelMode(void)
Definition: xact.c:1013
static RelMapFile shared_map
Definition: relmapper.c:109
#define ERROR
Definition: elog.h:46
static RelMapFile active_local_updates
Definition: relmapper.c:129
static RelMapFile pending_local_updates
Definition: relmapper.c:131
static RelMapFile active_shared_updates
Definition: relmapper.c:128
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:858
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:406
#define elog(elevel,...)
Definition: elog.h:232
static void apply_map_update(RelMapFile *map, Oid relationId, Oid fileNode, bool add_okay)
Definition: relmapper.c:319

◆ relmap_redo()

void relmap_redo ( XLogReaderState record)

Definition at line 1006 of file relmapper.c.

References Assert, xl_relmap_update::data, xl_relmap_update::dbid, elog, GetDatabasePath(), InvalidOid, 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.

1007 {
1008  uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
1009 
1010  /* Backup blocks are not used in relmap records */
1011  Assert(!XLogRecHasAnyBlockRefs(record));
1012 
1013  if (info == XLOG_RELMAP_UPDATE)
1014  {
1015  xl_relmap_update *xlrec = (xl_relmap_update *) XLogRecGetData(record);
1016  RelMapFile newmap;
1017  char *dbpath;
1018 
1019  if (xlrec->nbytes != sizeof(RelMapFile))
1020  elog(PANIC, "relmap_redo: wrong size %u in relmap update record",
1021  xlrec->nbytes);
1022  memcpy(&newmap, xlrec->data, sizeof(newmap));
1023 
1024  /* We need to construct the pathname for this database */
1025  dbpath = GetDatabasePath(xlrec->dbid, xlrec->tsid);
1026 
1027  /*
1028  * Write out the new map and send sinval, but of course don't write a
1029  * new WAL entry. There's no surrounding transaction to tell to
1030  * preserve files, either.
1031  *
1032  * There shouldn't be anyone else updating relmaps during WAL replay,
1033  * but grab the lock to interlock against load_relmap_file().
1034  */
1035  LWLockAcquire(RelationMappingLock, LW_EXCLUSIVE);
1036  write_relmap_file((xlrec->dbid == InvalidOid), &newmap,
1037  false, true, false,
1038  xlrec->dbid, xlrec->tsid, dbpath);
1039  LWLockRelease(RelationMappingLock);
1040 
1041  pfree(dbpath);
1042  }
1043  else
1044  elog(PANIC, "relmap_redo: unknown op code %u", info);
1045 }
unsigned char uint8
Definition: c.h:439
static void write_relmap_file(bool shared, RelMapFile *newmap, bool write_wal, bool send_sinval, bool preserve_files, Oid dbid, Oid tsid, const char *dbpath)
Definition: relmapper.c:802
#define PANIC
Definition: elog.h:50
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1803
void pfree(void *pointer)
Definition: mcxt.c:1169
#define XLogRecGetData(decoder)
Definition: xlogreader.h:320
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:315
char * GetDatabasePath(Oid dbNode, Oid spcNode)
Definition: relpath.c:110
#define XLOG_RELMAP_UPDATE
Definition: relmapper.h:25
#define InvalidOid
Definition: postgres_ext.h:36
#define Assert(condition)
Definition: c.h:804
#define XLR_INFO_MASK
Definition: xlogrecord.h:62
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1199
#define elog(elevel,...)
Definition: elog.h:232
#define XLogRecHasAnyBlockRefs(decoder)
Definition: xlogreader.h:322
char data[FLEXIBLE_ARRAY_MEMBER]
Definition: relmapper.h:32

◆ RestoreRelationMap()

void RestoreRelationMap ( char *  startAddress)

Definition at line 674 of file relmapper.c.

References SerializedActiveRelMaps::active_local_updates, SerializedActiveRelMaps::active_shared_updates, elog, ERROR, and RelMapFile::num_mappings.

Referenced by ParallelWorkerMain().

675 {
676  SerializedActiveRelMaps *relmaps;
677 
682  elog(ERROR, "parallel worker has existing mappings");
683 
684  relmaps = (SerializedActiveRelMaps *) startAddress;
687 }
static RelMapFile pending_shared_updates
Definition: relmapper.c:130
#define ERROR
Definition: elog.h:46
static RelMapFile active_local_updates
Definition: relmapper.c:129
static RelMapFile pending_local_updates
Definition: relmapper.c:131
static RelMapFile active_shared_updates
Definition: relmapper.c:128
RelMapFile active_shared_updates
Definition: relmapper.c:100
#define elog(elevel,...)
Definition: elog.h:232
RelMapFile active_local_updates
Definition: relmapper.c:101
int32 num_mappings
Definition: relmapper.c:88

◆ SerializeRelationMap()

void SerializeRelationMap ( Size  maxSize,
char *  startAddress 
)

Definition at line 657 of file relmapper.c.

References SerializedActiveRelMaps::active_local_updates, active_local_updates, SerializedActiveRelMaps::active_shared_updates, active_shared_updates, Assert, and EstimateRelationMapSpace().

Referenced by InitializeParallelDSM().

658 {
659  SerializedActiveRelMaps *relmaps;
660 
661  Assert(maxSize >= EstimateRelationMapSpace());
662 
663  relmaps = (SerializedActiveRelMaps *) startAddress;
666 }
static RelMapFile active_local_updates
Definition: relmapper.c:129
static RelMapFile active_shared_updates
Definition: relmapper.c:128
RelMapFile active_shared_updates
Definition: relmapper.c:100
#define Assert(condition)
Definition: c.h:804
Size EstimateRelationMapSpace(void)
Definition: relmapper.c:646
RelMapFile active_local_updates
Definition: relmapper.c:101

◆ write_relmap_file()

static void write_relmap_file ( bool  shared,
RelMapFile newmap,
bool  write_wal,
bool  send_sinval,
bool  preserve_files,
Oid  dbid,
Oid  tsid,
const char *  dbpath 
)
static

Definition at line 802 of file relmapper.c.

References Assert, CacheInvalidateRelmap(), CloseTransientFile(), COMP_CRC32C, RelMapFile::crc, data_sync_elevel(), xl_relmap_update::dbid, RelFileNode::dbNode, elog, END_CRIT_SECTION, ereport, errcode_for_file_access(), errmsg(), ERROR, fd(), FIN_CRC32C, i, INIT_CRC32C, local_map, RelMapFile::magic, MAX_MAPPINGS, MAXPGPATH, MinSizeOfRelmapUpdate, xl_relmap_update::nbytes, RelMapFile::num_mappings, offsetof, OpenTransientFile(), PG_BINARY, pg_fsync(), pgstat_report_wait_end(), pgstat_report_wait_start(), RelationPreserveStorage(), RELMAPPER_FILEMAGIC, RELMAPPER_FILENAME, RelFileNode::relNode, shared_map, snprintf, RelFileNode::spcNode, START_CRIT_SECTION, xl_relmap_update::tsid, WAIT_EVENT_RELATION_MAP_SYNC, WAIT_EVENT_RELATION_MAP_WRITE, write, XLOG_RELMAP_UPDATE, XLogBeginInsert(), XLogFlush(), XLogInsert(), and XLogRegisterData().

Referenced by perform_relmap_update(), RelationMapFinishBootstrap(), and relmap_redo().

805 {
806  int fd;
807  RelMapFile *realmap;
808  char mapfilename[MAXPGPATH];
809 
810  /*
811  * Fill in the overhead fields and update CRC.
812  */
813  newmap->magic = RELMAPPER_FILEMAGIC;
814  if (newmap->num_mappings < 0 || newmap->num_mappings > MAX_MAPPINGS)
815  elog(ERROR, "attempt to write bogus relation mapping");
816 
817  INIT_CRC32C(newmap->crc);
818  COMP_CRC32C(newmap->crc, (char *) newmap, offsetof(RelMapFile, crc));
819  FIN_CRC32C(newmap->crc);
820 
821  /*
822  * Open the target file. We prefer to do this before entering the
823  * critical section, so that an open() failure need not force PANIC.
824  */
825  if (shared)
826  {
827  snprintf(mapfilename, sizeof(mapfilename), "global/%s",
829  realmap = &shared_map;
830  }
831  else
832  {
833  snprintf(mapfilename, sizeof(mapfilename), "%s/%s",
834  dbpath, RELMAPPER_FILENAME);
835  realmap = &local_map;
836  }
837 
838  fd = OpenTransientFile(mapfilename, O_WRONLY | O_CREAT | PG_BINARY);
839  if (fd < 0)
840  ereport(ERROR,
842  errmsg("could not open file \"%s\": %m",
843  mapfilename)));
844 
845  if (write_wal)
846  {
847  xl_relmap_update xlrec;
848  XLogRecPtr lsn;
849 
850  /* now errors are fatal ... */
852 
853  xlrec.dbid = dbid;
854  xlrec.tsid = tsid;
855  xlrec.nbytes = sizeof(RelMapFile);
856 
857  XLogBeginInsert();
858  XLogRegisterData((char *) (&xlrec), MinSizeOfRelmapUpdate);
859  XLogRegisterData((char *) newmap, sizeof(RelMapFile));
860 
861  lsn = XLogInsert(RM_RELMAP_ID, XLOG_RELMAP_UPDATE);
862 
863  /* As always, WAL must hit the disk before the data update does */
864  XLogFlush(lsn);
865  }
866 
867  errno = 0;
869  if (write(fd, newmap, sizeof(RelMapFile)) != sizeof(RelMapFile))
870  {
871  /* if write didn't set errno, assume problem is no disk space */
872  if (errno == 0)
873  errno = ENOSPC;
874  ereport(ERROR,
876  errmsg("could not write file \"%s\": %m",
877  mapfilename)));
878  }
880 
881  /*
882  * We choose to fsync the data to disk before considering the task done.
883  * It would be possible to relax this if it turns out to be a performance
884  * issue, but it would complicate checkpointing --- see notes for
885  * CheckPointRelationMap.
886  */
888  if (pg_fsync(fd) != 0)
891  errmsg("could not fsync file \"%s\": %m",
892  mapfilename)));
894 
895  if (CloseTransientFile(fd) != 0)
896  ereport(ERROR,
898  errmsg("could not close file \"%s\": %m",
899  mapfilename)));
900 
901  /*
902  * Now that the file is safely on disk, send sinval message to let other
903  * backends know to re-read it. We must do this inside the critical
904  * section: if for some reason we fail to send the message, we have to
905  * force a database-wide PANIC. Otherwise other backends might continue
906  * execution with stale mapping information, which would be catastrophic
907  * as soon as others began to use the now-committed data.
908  */
909  if (send_sinval)
910  CacheInvalidateRelmap(dbid);
911 
912  /*
913  * Make sure that the files listed in the map are not deleted if the outer
914  * transaction aborts. This had better be within the critical section
915  * too: it's not likely to fail, but if it did, we'd arrive at transaction
916  * abort with the files still vulnerable. PANICing will leave things in a
917  * good state on-disk.
918  *
919  * Note: we're cheating a little bit here by assuming that mapped files
920  * are either in pg_global or the database's default tablespace.
921  */
922  if (preserve_files)
923  {
924  int32 i;
925 
926  for (i = 0; i < newmap->num_mappings; i++)
927  {
928  RelFileNode rnode;
929 
930  rnode.spcNode = tsid;
931  rnode.dbNode = dbid;
932  rnode.relNode = newmap->mappings[i].mapfilenode;
933  RelationPreserveStorage(rnode, false);
934  }
935  }
936 
937  /*
938  * Success, update permanent copy. During bootstrap, we might be working
939  * on the permanent copy itself, in which case skip the memcpy() to avoid
940  * invoking nominally-undefined behavior.
941  */
942  if (realmap != newmap)
943  memcpy(realmap, newmap, sizeof(RelMapFile));
944  else
945  Assert(!send_sinval); /* must be bootstrapping */
946 
947  /* Critical section done */
948  if (write_wal)
950 }
#define INIT_CRC32C(crc)
Definition: pg_crc32c.h:41
void RelationPreserveStorage(RelFileNode rnode, bool atCommit)
Definition: storage.c:240
static void pgstat_report_wait_end(void)
Definition: wait_event.h:274
int32 magic
Definition: relmapper.c:87
#define write(a, b, c)
Definition: win32.h:14
static RelMapFile local_map
Definition: relmapper.c:110
#define END_CRIT_SECTION()
Definition: miscadmin.h:149
#define MinSizeOfRelmapUpdate
Definition: relmapper.h:35
#define START_CRIT_SECTION()
Definition: miscadmin.h:147
void CacheInvalidateRelmap(Oid databaseId)
Definition: inval.c:1471
#define MAX_MAPPINGS
Definition: relmapper.c:77
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2887
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1271
signed int int32
Definition: c.h:429
#define RELMAPPER_FILEMAGIC
Definition: relmapper.c:75
static RelMapFile shared_map
Definition: relmapper.c:109
#define ERROR
Definition: elog.h:46
int OpenTransientFile(const char *fileName, int fileFlags)
Definition: fd.c:2509
pg_crc32c crc
Definition: relmapper.c:90
#define MAXPGPATH
int errcode_for_file_access(void)
Definition: elog.c:721
#define RELMAPPER_FILENAME
Definition: relmapper.c:73
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:258
int CloseTransientFile(int fd)
Definition: fd.c:2686
void XLogRegisterData(char *data, int len)
Definition: xloginsert.c:340
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:434
#define XLOG_RELMAP_UPDATE
Definition: relmapper.h:25
int data_sync_elevel(int elevel)
Definition: fd.c:3805
#define ereport(elevel,...)
Definition: elog.h:157
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:804
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
int i
int pg_fsync(int fd)
Definition: fd.c:357
struct RelMapFile RelMapFile
#define COMP_CRC32C(crc, data, len)
Definition: pg_crc32c.h:89
void XLogBeginInsert(void)
Definition: xloginsert.c:135
#define snprintf
Definition: port.h:217
#define FIN_CRC32C(crc)
Definition: pg_crc32c.h:94
int32 num_mappings
Definition: relmapper.c:88
#define offsetof(type, field)
Definition: c.h:727

Variable Documentation

◆ active_local_updates

◆ active_shared_updates

RelMapFile active_shared_updates
static

◆ local_map

◆ pending_local_updates

RelMapFile pending_local_updates
static

Definition at line 131 of file relmapper.c.

Referenced by RelationMapUpdateMap().

◆ pending_shared_updates

RelMapFile pending_shared_updates
static

Definition at line 130 of file relmapper.c.

Referenced by RelationMapUpdateMap().

◆ shared_map