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)
 
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:347
#define ERROR
Definition: elog.h:43
RelMapping mappings[MAX_MAPPINGS]
Definition: relmapper.c:89
Oid mapfilenode
Definition: relmapper.c:82
#define elog(elevel,...)
Definition: elog.h:228
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:945
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:739
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:608
static RelMapFile pending_shared_updates
Definition: relmapper.c:130
#define ERROR
Definition: elog.h:43
static RelMapFile active_local_updates
Definition: relmapper.c:129
static RelMapFile pending_local_updates
Definition: relmapper.c:131
#define ereport(elevel, rest)
Definition: elog.h:141
static RelMapFile active_shared_updates
Definition: relmapper.c:128
int errmsg(const char *fmt,...)
Definition: elog.c:822
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:1726
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1122

◆ 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)
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, 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  * Note: we could take RelationMappingLock in shared mode here, but it
729  * seems unnecessary since our read() should be atomic against any
730  * concurrent updater's write(). If the file is updated shortly after we
731  * look, the sinval signaling mechanism will make us re-read it before we
732  * are able to access any relation that's affected by the change.
733  */
735  r = read(fd, map, sizeof(RelMapFile));
736  if (r != sizeof(RelMapFile))
737  {
738  if (r < 0)
739  ereport(FATAL,
741  errmsg("could not read file \"%s\": %m", mapfilename)));
742  else
743  ereport(FATAL,
745  errmsg("could not read file \"%s\": read %d of %zu",
746  mapfilename, r, sizeof(RelMapFile))));
747  }
749 
750  if (CloseTransientFile(fd) != 0)
751  ereport(FATAL,
753  errmsg("could not close file \"%s\": %m",
754  mapfilename)));
755 
756  /* check for correct magic number, etc */
757  if (map->magic != RELMAPPER_FILEMAGIC ||
758  map->num_mappings < 0 ||
759  map->num_mappings > MAX_MAPPINGS)
760  ereport(FATAL,
761  (errmsg("relation mapping file \"%s\" contains invalid data",
762  mapfilename)));
763 
764  /* verify the CRC */
765  INIT_CRC32C(crc);
766  COMP_CRC32C(crc, (char *) map, offsetof(RelMapFile, crc));
767  FIN_CRC32C(crc);
768 
769  if (!EQ_CRC32C(crc, map->crc))
770  ereport(FATAL,
771  (errmsg("relation mapping file \"%s\" contains incorrect checksum",
772  mapfilename)));
773 }
#define INIT_CRC32C(crc)
Definition: pg_crc32c.h:41
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:608
#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:1222
#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:2292
#define FATAL
Definition: elog.h:52
#define MAXPGPATH
int errcode_for_file_access(void)
Definition: elog.c:631
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1342
#define EQ_CRC32C(c1, c2)
Definition: pg_crc32c.h:42
#define ereport(elevel, rest)
Definition: elog.h:141
#define RELMAPPER_FILENAME
Definition: relmapper.c:73
#define ERRCODE_DATA_CORRUPTED
Definition: pg_basebackup.c:45
int CloseTransientFile(int fd)
Definition: fd.c:2469
char * DatabasePath
Definition: globals.c:93
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1318
int errmsg(const char *fmt,...)
Definition: elog.c:822
#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:192
int32 num_mappings
Definition: relmapper.c:88
#define read(a, b, c)
Definition: win32.h:13
#define offsetof(type, field)
Definition: c.h:662

◆ 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:347
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 945 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().

946 {
947  RelMapFile newmap;
948 
949  /*
950  * Anyone updating a relation's mapping info should take exclusive lock on
951  * that rel and hold it until commit. This ensures that there will not be
952  * concurrent updates on the same mapping value; but there could easily be
953  * concurrent updates on different values in the same file. We cover that
954  * by acquiring the RelationMappingLock, re-reading the target file to
955  * ensure it's up to date, applying the updates, and writing the data
956  * before releasing RelationMappingLock.
957  *
958  * There is only one RelationMappingLock. In principle we could try to
959  * have one per mapping file, but it seems unlikely to be worth the
960  * trouble.
961  */
962  LWLockAcquire(RelationMappingLock, LW_EXCLUSIVE);
963 
964  /* Be certain we see any other updates just made */
965  load_relmap_file(shared);
966 
967  /* Prepare updated data in a local variable */
968  if (shared)
969  memcpy(&newmap, &shared_map, sizeof(RelMapFile));
970  else
971  memcpy(&newmap, &local_map, sizeof(RelMapFile));
972 
973  /*
974  * Apply the updates to newmap. No new mappings should appear, unless
975  * somebody is adding indexes to system catalogs.
976  */
977  merge_map_updates(&newmap, updates, allowSystemTableMods);
978 
979  /* Write out the updated map and do other necessary tasks */
980  write_relmap_file(shared, &newmap, true, true, true,
981  (shared ? InvalidOid : MyDatabaseId),
982  (shared ? GLOBALTABLESPACE_OID : MyDatabaseTableSpace),
983  DatabasePath);
984 
985  /* Now we can release the lock */
986  LWLockRelease(RelationMappingLock);
987 }
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:796
Oid MyDatabaseTableSpace
Definition: globals.c:87
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1726
static RelMapFile shared_map
Definition: relmapper.c:109
static void load_relmap_file(bool shared)
Definition: relmapper.c:698
Oid MyDatabaseId
Definition: globals.c:85
bool allowSystemTableMods
Definition: globals.c:120
#define InvalidOid
Definition: postgres_ext.h:36
char * DatabasePath
Definition: globals.c:93
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1122

◆ 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:347
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:796
Oid MyDatabaseTableSpace
Definition: globals.c:87
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:85
#define InvalidOid
Definition: postgres_ext.h:36
char * DatabasePath
Definition: globals.c:93
#define Assert(condition)
Definition: c.h:739
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:374
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);
616 }
static void load_relmap_file(bool shared)
Definition: relmapper.c:698
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:374

◆ 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);
637 }
static void load_relmap_file(bool shared)
Definition: relmapper.c:698
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:374

◆ 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);
409  }
410  else
411  {
413  load_relmap_file(false);
414  }
415 }
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
static void load_relmap_file(bool shared)
Definition: relmapper.c:698

◆ 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);
430  load_relmap_file(false);
431 }
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
static void load_relmap_file(bool shared)
Definition: relmapper.c:698

◆ 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:347
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:347
#define ERROR
Definition: elog.h:43
static RelMapFile active_local_updates
Definition: relmapper.c:129
RelMapping mappings[MAX_MAPPINGS]
Definition: relmapper.c:89
#define elog(elevel,...)
Definition: elog.h:228
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:996
static RelMapFile shared_map
Definition: relmapper.c:109
#define ERROR
Definition: elog.h:43
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:841
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:374
#define elog(elevel,...)
Definition: elog.h:228
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 993 of file relmapper.c.

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

994 {
995  uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
996 
997  /* Backup blocks are not used in relmap records */
998  Assert(!XLogRecHasAnyBlockRefs(record));
999 
1000  if (info == XLOG_RELMAP_UPDATE)
1001  {
1002  xl_relmap_update *xlrec = (xl_relmap_update *) XLogRecGetData(record);
1003  RelMapFile newmap;
1004  char *dbpath;
1005 
1006  if (xlrec->nbytes != sizeof(RelMapFile))
1007  elog(PANIC, "relmap_redo: wrong size %u in relmap update record",
1008  xlrec->nbytes);
1009  memcpy(&newmap, xlrec->data, sizeof(newmap));
1010 
1011  /* We need to construct the pathname for this database */
1012  dbpath = GetDatabasePath(xlrec->dbid, xlrec->tsid);
1013 
1014  /*
1015  * Write out the new map and send sinval, but of course don't write a
1016  * new WAL entry. There's no surrounding transaction to tell to
1017  * preserve files, either.
1018  *
1019  * There shouldn't be anyone else updating relmaps during WAL replay,
1020  * so we don't bother to take the RelationMappingLock. We would need
1021  * to do so if load_relmap_file needed to interlock against writers.
1022  */
1023  write_relmap_file((xlrec->dbid == InvalidOid), &newmap,
1024  false, true, false,
1025  xlrec->dbid, xlrec->tsid, dbpath);
1026 
1027  pfree(dbpath);
1028  }
1029  else
1030  elog(PANIC, "relmap_redo: unknown op code %u", info);
1031 }
unsigned char uint8
Definition: c.h:357
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:796
#define PANIC
Definition: elog.h:53
void pfree(void *pointer)
Definition: mcxt.c:1056
#define XLogRecGetData(decoder)
Definition: xlogreader.h:283
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:279
char * GetDatabasePath(Oid dbNode, Oid spcNode)
Definition: relpath.c:107
#define XLOG_RELMAP_UPDATE
Definition: relmapper.h:25
#define InvalidOid
Definition: postgres_ext.h:36
#define Assert(condition)
Definition: c.h:739
#define XLR_INFO_MASK
Definition: xlogrecord.h:62
#define elog(elevel,...)
Definition: elog.h:228
#define XLogRecHasAnyBlockRefs(decoder)
Definition: xlogreader.h:285
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:43
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:228
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:739
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 796 of file relmapper.c.

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

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

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