PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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
 

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
 

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)
 
void AtPrepare_RelationMap (void)
 
void CheckPointRelationMap (void)
 
void RelationMapFinishBootstrap (void)
 
void RelationMapInitialize (void)
 
void RelationMapInitializePhase2 (void)
 
void RelationMapInitializePhase3 (void)
 
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

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

#define RELMAPPER_FILEMAGIC   0x592717 /* version ID value */
#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

Function Documentation

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

Definition at line 303 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().

304 {
305  int32 i;
306 
307  /* Replace any existing mapping */
308  for (i = 0; i < map->num_mappings; i++)
309  {
310  if (relationId == map->mappings[i].mapoid)
311  {
312  map->mappings[i].mapfilenode = fileNode;
313  return;
314  }
315  }
316 
317  /* Nope, need to add a new mapping */
318  if (!add_okay)
319  elog(ERROR, "attempt to apply a mapping to unmapped relation %u",
320  relationId);
321  if (map->num_mappings >= MAX_MAPPINGS)
322  elog(ERROR, "ran out of space in relation map");
323  map->mappings[map->num_mappings].mapoid = relationId;
324  map->mappings[map->num_mappings].mapfilenode = fileNode;
325  map->num_mappings++;
326 }
Oid mapoid
Definition: relmapper.c:81
#define MAX_MAPPINGS
Definition: relmapper.c:77
signed int int32
Definition: c.h:246
#define ERROR
Definition: elog.h:43
RelMapping mappings[MAX_MAPPINGS]
Definition: relmapper.c:89
Oid mapfilenode
Definition: relmapper.c:82
int i
#define elog
Definition: elog.h:219
int32 num_mappings
Definition: relmapper.c:88
void AtCCI_RelationMap ( void  )

Definition at line 423 of file relmapper.c.

References merge_map_updates(), and RelMapFile::num_mappings.

Referenced by AtCCI_LocalCache().

424 {
426  {
429  true);
431  }
433  {
436  true);
438  }
439 }
static void merge_map_updates(RelMapFile *map, const RelMapFile *updates, bool add_okay)
Definition: relmapper.c:335
static RelMapFile pending_shared_updates
Definition: relmapper.c:117
static RelMapFile active_local_updates
Definition: relmapper.c:116
static RelMapFile pending_local_updates
Definition: relmapper.c:118
static RelMapFile active_shared_updates
Definition: relmapper.c:115
int32 num_mappings
Definition: relmapper.c:88
void AtEOXact_RelationMap ( bool  isCommit)

Definition at line 457 of file relmapper.c.

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

Referenced by AbortTransaction(), and CommitTransaction().

458 {
459  if (isCommit)
460  {
461  /*
462  * We should not get here with any "pending" updates. (We could
463  * logically choose to treat such as committed, but in the current
464  * code this should never happen.)
465  */
468 
469  /*
470  * Write any active updates to the actual map files, then reset them.
471  */
473  {
476  }
478  {
481  }
482  }
483  else
484  {
485  /* Abort --- drop all local and pending updates */
490  }
491 }
static RelMapFile pending_shared_updates
Definition: relmapper.c:117
static void perform_relmap_update(bool shared, const RelMapFile *updates)
Definition: relmapper.c:860
static RelMapFile active_local_updates
Definition: relmapper.c:116
static RelMapFile pending_local_updates
Definition: relmapper.c:118
static RelMapFile active_shared_updates
Definition: relmapper.c:115
#define Assert(condition)
Definition: c.h:681
int32 num_mappings
Definition: relmapper.c:88
void AtPrepare_RelationMap ( void  )

Definition at line 501 of file relmapper.c.

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

Referenced by PrepareTransaction().

502 {
507  ereport(ERROR,
508  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
509  errmsg("cannot PREPARE a transaction that modified relation mapping")));
510 }
int errcode(int sqlerrcode)
Definition: elog.c:575
static RelMapFile pending_shared_updates
Definition: relmapper.c:117
#define ERROR
Definition: elog.h:43
static RelMapFile active_local_updates
Definition: relmapper.c:116
static RelMapFile pending_local_updates
Definition: relmapper.c:118
#define ereport(elevel, rest)
Definition: elog.h:122
static RelMapFile active_shared_updates
Definition: relmapper.c:115
int errmsg(const char *fmt,...)
Definition: elog.c:797
int32 num_mappings
Definition: relmapper.c:88
void CheckPointRelationMap ( void  )

Definition at line 524 of file relmapper.c.

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

Referenced by CheckPointGuts().

525 {
526  LWLockAcquire(RelationMappingLock, LW_SHARED);
527  LWLockRelease(RelationMappingLock);
528 }
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1721
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1117
static void load_relmap_file ( bool  shared)
static

Definition at line 626 of file relmapper.c.

References CloseTransientFile(), COMP_CRC32C, RelMapFile::crc, DatabasePath, EQ_CRC32C, ereport, 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().

627 {
628  RelMapFile *map;
629  char mapfilename[MAXPGPATH];
630  pg_crc32c crc;
631  int fd;
632 
633  if (shared)
634  {
635  snprintf(mapfilename, sizeof(mapfilename), "global/%s",
637  map = &shared_map;
638  }
639  else
640  {
641  snprintf(mapfilename, sizeof(mapfilename), "%s/%s",
643  map = &local_map;
644  }
645 
646  /* Read data ... */
647  fd = OpenTransientFile(mapfilename, O_RDONLY | PG_BINARY);
648  if (fd < 0)
649  ereport(FATAL,
651  errmsg("could not open relation mapping file \"%s\": %m",
652  mapfilename)));
653 
654  /*
655  * Note: we could take RelationMappingLock in shared mode here, but it
656  * seems unnecessary since our read() should be atomic against any
657  * concurrent updater's write(). If the file is updated shortly after we
658  * look, the sinval signaling mechanism will make us re-read it before we
659  * are able to access any relation that's affected by the change.
660  */
662  if (read(fd, map, sizeof(RelMapFile)) != sizeof(RelMapFile))
663  ereport(FATAL,
665  errmsg("could not read relation mapping file \"%s\": %m",
666  mapfilename)));
668 
669  CloseTransientFile(fd);
670 
671  /* check for correct magic number, etc */
672  if (map->magic != RELMAPPER_FILEMAGIC ||
673  map->num_mappings < 0 ||
674  map->num_mappings > MAX_MAPPINGS)
675  ereport(FATAL,
676  (errmsg("relation mapping file \"%s\" contains invalid data",
677  mapfilename)));
678 
679  /* verify the CRC */
680  INIT_CRC32C(crc);
681  COMP_CRC32C(crc, (char *) map, offsetof(RelMapFile, crc));
682  FIN_CRC32C(crc);
683 
684  if (!EQ_CRC32C(crc, map->crc))
685  ereport(FATAL,
686  (errmsg("relation mapping file \"%s\" contains incorrect checksum",
687  mapfilename)));
688 }
#define INIT_CRC32C(crc)
Definition: pg_crc32c.h:41
int32 magic
Definition: relmapper.c:87
static RelMapFile local_map
Definition: relmapper.c:100
uint32 pg_crc32c
Definition: pg_crc32c.h:38
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
#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:1044
#define RELMAPPER_FILEMAGIC
Definition: relmapper.c:75
static RelMapFile shared_map
Definition: relmapper.c:99
int OpenTransientFile(const char *fileName, int fileFlags)
Definition: fd.c:2167
pg_crc32c crc
Definition: relmapper.c:90
#define FATAL
Definition: elog.h:52
#define MAXPGPATH
int errcode_for_file_access(void)
Definition: elog.c:598
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1244
#define EQ_CRC32C(c1, c2)
Definition: pg_crc32c.h:42
#define ereport(elevel, rest)
Definition: elog.h:122
#define RELMAPPER_FILENAME
Definition: relmapper.c:73
int CloseTransientFile(int fd)
Definition: fd.c:2337
char * DatabasePath
Definition: globals.c:85
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1220
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define COMP_CRC32C(crc, data, len)
Definition: pg_crc32c.h:73
#define FIN_CRC32C(crc)
Definition: pg_crc32c.h:78
int32 num_mappings
Definition: relmapper.c:88
#define read(a, b, c)
Definition: win32.h:13
#define offsetof(type, field)
Definition: c.h:549
static void merge_map_updates ( RelMapFile map,
const RelMapFile updates,
bool  add_okay 
)
static

Definition at line 335 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().

336 {
337  int32 i;
338 
339  for (i = 0; i < updates->num_mappings; i++)
340  {
341  apply_map_update(map,
342  updates->mappings[i].mapoid,
343  updates->mappings[i].mapfilenode,
344  add_okay);
345  }
346 }
Oid mapoid
Definition: relmapper.c:81
signed int int32
Definition: c.h:246
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:303
static void perform_relmap_update ( bool  shared,
const RelMapFile updates 
)
static

Definition at line 860 of file relmapper.c.

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

Referenced by AtEOXact_RelationMap().

861 {
862  RelMapFile newmap;
863 
864  /*
865  * Anyone updating a relation's mapping info should take exclusive lock on
866  * that rel and hold it until commit. This ensures that there will not be
867  * concurrent updates on the same mapping value; but there could easily be
868  * concurrent updates on different values in the same file. We cover that
869  * by acquiring the RelationMappingLock, re-reading the target file to
870  * ensure it's up to date, applying the updates, and writing the data
871  * before releasing RelationMappingLock.
872  *
873  * There is only one RelationMappingLock. In principle we could try to
874  * have one per mapping file, but it seems unlikely to be worth the
875  * trouble.
876  */
877  LWLockAcquire(RelationMappingLock, LW_EXCLUSIVE);
878 
879  /* Be certain we see any other updates just made */
880  load_relmap_file(shared);
881 
882  /* Prepare updated data in a local variable */
883  if (shared)
884  memcpy(&newmap, &shared_map, sizeof(RelMapFile));
885  else
886  memcpy(&newmap, &local_map, sizeof(RelMapFile));
887 
888  /*
889  * Apply the updates to newmap. No new mappings should appear, unless
890  * somebody is adding indexes to system catalogs.
891  */
892  merge_map_updates(&newmap, updates, allowSystemTableMods);
893 
894  /* Write out the updated map and do other necessary tasks */
895  write_relmap_file(shared, &newmap, true, true, true,
896  (shared ? InvalidOid : MyDatabaseId),
898  DatabasePath);
899 
900  /* Now we can release the lock */
901  LWLockRelease(RelationMappingLock);
902 }
static void merge_map_updates(RelMapFile *map, const RelMapFile *updates, bool add_okay)
Definition: relmapper.c:335
static RelMapFile local_map
Definition: relmapper.c:100
#define GLOBALTABLESPACE_OID
Definition: pg_tablespace.h:64
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:711
Oid MyDatabaseTableSpace
Definition: globals.c:79
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1721
static RelMapFile shared_map
Definition: relmapper.c:99
static void load_relmap_file(bool shared)
Definition: relmapper.c:626
Oid MyDatabaseId
Definition: globals.c:77
bool allowSystemTableMods
Definition: globals.c:112
#define InvalidOid
Definition: postgres_ext.h:36
char * DatabasePath
Definition: globals.c:85
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1117
Oid RelationMapFilenodeToOid ( Oid  filenode,
bool  shared 
)

Definition at line 199 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().

200 {
201  const RelMapFile *map;
202  int32 i;
203 
204  /* If there are active updates, believe those over the main maps */
205  if (shared)
206  {
207  map = &active_shared_updates;
208  for (i = 0; i < map->num_mappings; i++)
209  {
210  if (filenode == map->mappings[i].mapfilenode)
211  return map->mappings[i].mapoid;
212  }
213  map = &shared_map;
214  for (i = 0; i < map->num_mappings; i++)
215  {
216  if (filenode == map->mappings[i].mapfilenode)
217  return map->mappings[i].mapoid;
218  }
219  }
220  else
221  {
222  map = &active_local_updates;
223  for (i = 0; i < map->num_mappings; i++)
224  {
225  if (filenode == map->mappings[i].mapfilenode)
226  return map->mappings[i].mapoid;
227  }
228  map = &local_map;
229  for (i = 0; i < map->num_mappings; i++)
230  {
231  if (filenode == map->mappings[i].mapfilenode)
232  return map->mappings[i].mapoid;
233  }
234  }
235 
236  return InvalidOid;
237 }
Oid mapoid
Definition: relmapper.c:81
static RelMapFile local_map
Definition: relmapper.c:100
signed int int32
Definition: c.h:246
static RelMapFile shared_map
Definition: relmapper.c:99
static RelMapFile active_local_updates
Definition: relmapper.c:116
RelMapping mappings[MAX_MAPPINGS]
Definition: relmapper.c:89
static RelMapFile active_shared_updates
Definition: relmapper.c:115
#define InvalidOid
Definition: postgres_ext.h:36
Oid mapfilenode
Definition: relmapper.c:82
int i
int32 num_mappings
Definition: relmapper.c:88
void RelationMapFinishBootstrap ( void  )

Definition at line 538 of file relmapper.c.

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

Referenced by BootstrapModeMain().

539 {
541 
542  /* Shouldn't be anything "pending" ... */
547 
548  /* Write the files; no WAL or sinval needed */
549  write_relmap_file(true, &shared_map, false, false, false,
551  write_relmap_file(false, &local_map, false, false, false,
553 }
static RelMapFile local_map
Definition: relmapper.c:100
#define GLOBALTABLESPACE_OID
Definition: pg_tablespace.h:64
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:711
Oid MyDatabaseTableSpace
Definition: globals.c:79
static RelMapFile pending_shared_updates
Definition: relmapper.c:117
static RelMapFile shared_map
Definition: relmapper.c:99
static RelMapFile active_local_updates
Definition: relmapper.c:116
static RelMapFile pending_local_updates
Definition: relmapper.c:118
static RelMapFile active_shared_updates
Definition: relmapper.c:115
Oid MyDatabaseId
Definition: globals.c:77
#define InvalidOid
Definition: postgres_ext.h:36
char * DatabasePath
Definition: globals.c:85
#define Assert(condition)
Definition: c.h:681
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:367
int32 num_mappings
Definition: relmapper.c:88
void RelationMapInitialize ( void  )

Definition at line 562 of file relmapper.c.

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

Referenced by RelationCacheInitialize().

563 {
564  /* The static variables should initialize to zeroes, but let's be sure */
565  shared_map.magic = 0; /* mark it not loaded */
566  local_map.magic = 0;
573 }
int32 magic
Definition: relmapper.c:87
static RelMapFile local_map
Definition: relmapper.c:100
static RelMapFile pending_shared_updates
Definition: relmapper.c:117
static RelMapFile shared_map
Definition: relmapper.c:99
static RelMapFile active_local_updates
Definition: relmapper.c:116
static RelMapFile pending_local_updates
Definition: relmapper.c:118
static RelMapFile active_shared_updates
Definition: relmapper.c:115
int32 num_mappings
Definition: relmapper.c:88
void RelationMapInitializePhase2 ( void  )

Definition at line 582 of file relmapper.c.

References IsBootstrapProcessingMode, and load_relmap_file().

Referenced by RelationCacheInitializePhase2().

583 {
584  /*
585  * In bootstrap mode, the map file isn't there yet, so do nothing.
586  */
588  return;
589 
590  /*
591  * Load the shared map file, die on error.
592  */
593  load_relmap_file(true);
594 }
static void load_relmap_file(bool shared)
Definition: relmapper.c:626
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:367
void RelationMapInitializePhase3 ( void  )

Definition at line 603 of file relmapper.c.

References IsBootstrapProcessingMode, and load_relmap_file().

Referenced by RelationCacheInitializePhase3().

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

Definition at line 387 of file relmapper.c.

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

Referenced by LocalExecuteInvalidationMessage().

388 {
389  if (shared)
390  {
392  load_relmap_file(true);
393  }
394  else
395  {
397  load_relmap_file(false);
398  }
399 }
int32 magic
Definition: relmapper.c:87
static RelMapFile local_map
Definition: relmapper.c:100
#define RELMAPPER_FILEMAGIC
Definition: relmapper.c:75
static RelMapFile shared_map
Definition: relmapper.c:99
static void load_relmap_file(bool shared)
Definition: relmapper.c:626
void RelationMapInvalidateAll ( void  )

Definition at line 409 of file relmapper.c.

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

Referenced by RelationCacheInvalidate().

410 {
412  load_relmap_file(true);
414  load_relmap_file(false);
415 }
int32 magic
Definition: relmapper.c:87
static RelMapFile local_map
Definition: relmapper.c:100
#define RELMAPPER_FILEMAGIC
Definition: relmapper.c:75
static RelMapFile shared_map
Definition: relmapper.c:99
static void load_relmap_file(bool shared)
Definition: relmapper.c:626
Oid RelationMapOidToFilenode ( Oid  relationId,
bool  shared 
)

Definition at line 146 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().

147 {
148  const RelMapFile *map;
149  int32 i;
150 
151  /* If there are active updates, believe those over the main maps */
152  if (shared)
153  {
154  map = &active_shared_updates;
155  for (i = 0; i < map->num_mappings; i++)
156  {
157  if (relationId == map->mappings[i].mapoid)
158  return map->mappings[i].mapfilenode;
159  }
160  map = &shared_map;
161  for (i = 0; i < map->num_mappings; i++)
162  {
163  if (relationId == map->mappings[i].mapoid)
164  return map->mappings[i].mapfilenode;
165  }
166  }
167  else
168  {
169  map = &active_local_updates;
170  for (i = 0; i < map->num_mappings; i++)
171  {
172  if (relationId == map->mappings[i].mapoid)
173  return map->mappings[i].mapfilenode;
174  }
175  map = &local_map;
176  for (i = 0; i < map->num_mappings; i++)
177  {
178  if (relationId == map->mappings[i].mapoid)
179  return map->mappings[i].mapfilenode;
180  }
181  }
182 
183  return InvalidOid;
184 }
Oid mapoid
Definition: relmapper.c:81
static RelMapFile local_map
Definition: relmapper.c:100
signed int int32
Definition: c.h:246
static RelMapFile shared_map
Definition: relmapper.c:99
static RelMapFile active_local_updates
Definition: relmapper.c:116
RelMapping mappings[MAX_MAPPINGS]
Definition: relmapper.c:89
static RelMapFile active_shared_updates
Definition: relmapper.c:115
#define InvalidOid
Definition: postgres_ext.h:36
Oid mapfilenode
Definition: relmapper.c:82
int i
int32 num_mappings
Definition: relmapper.c:88
void RelationMapRemoveMapping ( Oid  relationId)

Definition at line 357 of file relmapper.c.

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

Referenced by finish_heap_swap().

358 {
360  int32 i;
361 
362  for (i = 0; i < map->num_mappings; i++)
363  {
364  if (relationId == map->mappings[i].mapoid)
365  {
366  /* Found it, collapse it out */
367  map->mappings[i] = map->mappings[map->num_mappings - 1];
368  map->num_mappings--;
369  return;
370  }
371  }
372  elog(ERROR, "could not find temporary mapping for relation %u",
373  relationId);
374 }
Oid mapoid
Definition: relmapper.c:81
signed int int32
Definition: c.h:246
#define ERROR
Definition: elog.h:43
static RelMapFile active_local_updates
Definition: relmapper.c:116
RelMapping mappings[MAX_MAPPINGS]
Definition: relmapper.c:89
int i
#define elog
Definition: elog.h:219
int32 num_mappings
Definition: relmapper.c:88
void RelationMapUpdateMap ( Oid  relationId,
Oid  fileNode,
bool  shared,
bool  immediate 
)

Definition at line 248 of file relmapper.c.

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

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

250 {
251  RelMapFile *map;
252 
254  {
255  /*
256  * In bootstrap mode, the mapping gets installed in permanent map.
257  */
258  if (shared)
259  map = &shared_map;
260  else
261  map = &local_map;
262  }
263  else
264  {
265  /*
266  * We don't currently support map changes within subtransactions. This
267  * could be done with more bookkeeping infrastructure, but it doesn't
268  * presently seem worth it.
269  */
271  elog(ERROR, "cannot change relation mapping within subtransaction");
272 
273  if (immediate)
274  {
275  /* Make it active, but only locally */
276  if (shared)
277  map = &active_shared_updates;
278  else
279  map = &active_local_updates;
280  }
281  else
282  {
283  /* Make it pending */
284  if (shared)
285  map = &pending_shared_updates;
286  else
287  map = &pending_local_updates;
288  }
289  }
290  apply_map_update(map, relationId, fileNode, true);
291 }
static RelMapFile local_map
Definition: relmapper.c:100
static RelMapFile pending_shared_updates
Definition: relmapper.c:117
static RelMapFile shared_map
Definition: relmapper.c:99
#define ERROR
Definition: elog.h:43
static RelMapFile active_local_updates
Definition: relmapper.c:116
static RelMapFile pending_local_updates
Definition: relmapper.c:118
static RelMapFile active_shared_updates
Definition: relmapper.c:115
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:754
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:367
#define elog
Definition: elog.h:219
static void apply_map_update(RelMapFile *map, Oid relationId, Oid fileNode, bool add_okay)
Definition: relmapper.c:303
void relmap_redo ( XLogReaderState record)

Definition at line 908 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.

909 {
910  uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
911 
912  /* Backup blocks are not used in relmap records */
913  Assert(!XLogRecHasAnyBlockRefs(record));
914 
915  if (info == XLOG_RELMAP_UPDATE)
916  {
917  xl_relmap_update *xlrec = (xl_relmap_update *) XLogRecGetData(record);
918  RelMapFile newmap;
919  char *dbpath;
920 
921  if (xlrec->nbytes != sizeof(RelMapFile))
922  elog(PANIC, "relmap_redo: wrong size %u in relmap update record",
923  xlrec->nbytes);
924  memcpy(&newmap, xlrec->data, sizeof(newmap));
925 
926  /* We need to construct the pathname for this database */
927  dbpath = GetDatabasePath(xlrec->dbid, xlrec->tsid);
928 
929  /*
930  * Write out the new map and send sinval, but of course don't write a
931  * new WAL entry. There's no surrounding transaction to tell to
932  * preserve files, either.
933  *
934  * There shouldn't be anyone else updating relmaps during WAL replay,
935  * so we don't bother to take the RelationMappingLock. We would need
936  * to do so if load_relmap_file needed to interlock against writers.
937  */
938  write_relmap_file((xlrec->dbid == InvalidOid), &newmap,
939  false, true, false,
940  xlrec->dbid, xlrec->tsid, dbpath);
941 
942  pfree(dbpath);
943  }
944  else
945  elog(PANIC, "relmap_redo: unknown op code %u", info);
946 }
unsigned char uint8
Definition: c.h:256
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:711
#define PANIC
Definition: elog.h:53
void pfree(void *pointer)
Definition: mcxt.c:949
#define XLogRecGetData(decoder)
Definition: xlogreader.h:226
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:222
char * GetDatabasePath(Oid dbNode, Oid spcNode)
Definition: relpath.c:108
#define XLOG_RELMAP_UPDATE
Definition: relmapper.h:25
#define InvalidOid
Definition: postgres_ext.h:36
#define Assert(condition)
Definition: c.h:681
#define XLR_INFO_MASK
Definition: xlogrecord.h:62
#define XLogRecHasAnyBlockRefs(decoder)
Definition: xlogreader.h:228
#define elog
Definition: elog.h:219
char data[FLEXIBLE_ARRAY_MEMBER]
Definition: relmapper.h:32
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 711 of file relmapper.c.

References CacheInvalidateRelmap(), CloseTransientFile(), COMP_CRC32C, RelMapFile::crc, 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, RelMapping::mapfilenode, RelMapFile::mappings, 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().

714 {
715  int fd;
716  RelMapFile *realmap;
717  char mapfilename[MAXPGPATH];
718 
719  /*
720  * Fill in the overhead fields and update CRC.
721  */
722  newmap->magic = RELMAPPER_FILEMAGIC;
723  if (newmap->num_mappings < 0 || newmap->num_mappings > MAX_MAPPINGS)
724  elog(ERROR, "attempt to write bogus relation mapping");
725 
726  INIT_CRC32C(newmap->crc);
727  COMP_CRC32C(newmap->crc, (char *) newmap, offsetof(RelMapFile, crc));
728  FIN_CRC32C(newmap->crc);
729 
730  /*
731  * Open the target file. We prefer to do this before entering the
732  * critical section, so that an open() failure need not force PANIC.
733  */
734  if (shared)
735  {
736  snprintf(mapfilename, sizeof(mapfilename), "global/%s",
738  realmap = &shared_map;
739  }
740  else
741  {
742  snprintf(mapfilename, sizeof(mapfilename), "%s/%s",
743  dbpath, RELMAPPER_FILENAME);
744  realmap = &local_map;
745  }
746 
747  fd = OpenTransientFile(mapfilename, O_WRONLY | O_CREAT | PG_BINARY);
748  if (fd < 0)
749  ereport(ERROR,
751  errmsg("could not open relation mapping file \"%s\": %m",
752  mapfilename)));
753 
754  if (write_wal)
755  {
756  xl_relmap_update xlrec;
757  XLogRecPtr lsn;
758 
759  /* now errors are fatal ... */
761 
762  xlrec.dbid = dbid;
763  xlrec.tsid = tsid;
764  xlrec.nbytes = sizeof(RelMapFile);
765 
766  XLogBeginInsert();
767  XLogRegisterData((char *) (&xlrec), MinSizeOfRelmapUpdate);
768  XLogRegisterData((char *) newmap, sizeof(RelMapFile));
769 
770  lsn = XLogInsert(RM_RELMAP_ID, XLOG_RELMAP_UPDATE);
771 
772  /* As always, WAL must hit the disk before the data update does */
773  XLogFlush(lsn);
774  }
775 
776  errno = 0;
778  if (write(fd, newmap, sizeof(RelMapFile)) != sizeof(RelMapFile))
779  {
780  /* if write didn't set errno, assume problem is no disk space */
781  if (errno == 0)
782  errno = ENOSPC;
783  ereport(ERROR,
785  errmsg("could not write to relation mapping file \"%s\": %m",
786  mapfilename)));
787  }
789 
790  /*
791  * We choose to fsync the data to disk before considering the task done.
792  * It would be possible to relax this if it turns out to be a performance
793  * issue, but it would complicate checkpointing --- see notes for
794  * CheckPointRelationMap.
795  */
797  if (pg_fsync(fd) != 0)
798  ereport(ERROR,
800  errmsg("could not fsync relation mapping file \"%s\": %m",
801  mapfilename)));
803 
804  if (CloseTransientFile(fd))
805  ereport(ERROR,
807  errmsg("could not close relation mapping file \"%s\": %m",
808  mapfilename)));
809 
810  /*
811  * Now that the file is safely on disk, send sinval message to let other
812  * backends know to re-read it. We must do this inside the critical
813  * section: if for some reason we fail to send the message, we have to
814  * force a database-wide PANIC. Otherwise other backends might continue
815  * execution with stale mapping information, which would be catastrophic
816  * as soon as others began to use the now-committed data.
817  */
818  if (send_sinval)
819  CacheInvalidateRelmap(dbid);
820 
821  /*
822  * Make sure that the files listed in the map are not deleted if the outer
823  * transaction aborts. This had better be within the critical section
824  * too: it's not likely to fail, but if it did, we'd arrive at transaction
825  * abort with the files still vulnerable. PANICing will leave things in a
826  * good state on-disk.
827  *
828  * Note: we're cheating a little bit here by assuming that mapped files
829  * are either in pg_global or the database's default tablespace.
830  */
831  if (preserve_files)
832  {
833  int32 i;
834 
835  for (i = 0; i < newmap->num_mappings; i++)
836  {
837  RelFileNode rnode;
838 
839  rnode.spcNode = tsid;
840  rnode.dbNode = dbid;
841  rnode.relNode = newmap->mappings[i].mapfilenode;
842  RelationPreserveStorage(rnode, false);
843  }
844  }
845 
846  /* Success, update permanent copy */
847  memcpy(realmap, newmap, sizeof(RelMapFile));
848 
849  /* Critical section done */
850  if (write_wal)
852 }
#define INIT_CRC32C(crc)
Definition: pg_crc32c.h:41
void RelationPreserveStorage(RelFileNode rnode, bool atCommit)
Definition: storage.c:190
int32 magic
Definition: relmapper.c:87
#define write(a, b, c)
Definition: win32.h:14
static RelMapFile local_map
Definition: relmapper.c:100
#define END_CRIT_SECTION()
Definition: miscadmin.h:133
#define MinSizeOfRelmapUpdate
Definition: relmapper.h:35
#define START_CRIT_SECTION()
Definition: miscadmin.h:131
void CacheInvalidateRelmap(Oid databaseId)
Definition: inval.c:1362
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
#define MAX_MAPPINGS
Definition: relmapper.c:77
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2773
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1044
signed int int32
Definition: c.h:246
#define RELMAPPER_FILEMAGIC
Definition: relmapper.c:75
static RelMapFile shared_map
Definition: relmapper.c:99
#define ERROR
Definition: elog.h:43
int OpenTransientFile(const char *fileName, int fileFlags)
Definition: fd.c:2167
pg_crc32c crc
Definition: relmapper.c:90
#define MAXPGPATH
int errcode_for_file_access(void)
Definition: elog.c:598
RelMapping mappings[MAX_MAPPINGS]
Definition: relmapper.c:89
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1244
#define ereport(elevel, rest)
Definition: elog.h:122
#define RELMAPPER_FILENAME
Definition: relmapper.c:73
int CloseTransientFile(int fd)
Definition: fd.c:2337
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
Oid mapfilenode
Definition: relmapper.c:82
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1220
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
int pg_fsync(int fd)
Definition: fd.c:338
#define elog
Definition: elog.h:219
struct RelMapFile RelMapFile
#define COMP_CRC32C(crc, data, len)
Definition: pg_crc32c.h:73
void XLogBeginInsert(void)
Definition: xloginsert.c:120
#define FIN_CRC32C(crc)
Definition: pg_crc32c.h:78
int32 num_mappings
Definition: relmapper.c:88
#define offsetof(type, field)
Definition: c.h:549

Variable Documentation

RelMapFile active_local_updates
static
RelMapFile active_shared_updates
static
RelMapFile pending_local_updates
static

Definition at line 118 of file relmapper.c.

Referenced by RelationMapUpdateMap().

RelMapFile pending_shared_updates
static

Definition at line 117 of file relmapper.c.

Referenced by RelationMapUpdateMap().