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:256
#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:863
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:675
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:1715
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1111
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,
648  O_RDONLY | PG_BINARY, S_IRUSR | S_IWUSR);
649  if (fd < 0)
650  ereport(FATAL,
652  errmsg("could not open relation mapping file \"%s\": %m",
653  mapfilename)));
654 
655  /*
656  * Note: we could take RelationMappingLock in shared mode here, but it
657  * seems unnecessary since our read() should be atomic against any
658  * concurrent updater's write(). If the file is updated shortly after we
659  * look, the sinval signaling mechanism will make us re-read it before we
660  * are able to access any relation that's affected by the change.
661  */
663  if (read(fd, map, sizeof(RelMapFile)) != sizeof(RelMapFile))
664  ereport(FATAL,
666  errmsg("could not read relation mapping file \"%s\": %m",
667  mapfilename)));
669 
670  CloseTransientFile(fd);
671 
672  /* check for correct magic number, etc */
673  if (map->magic != RELMAPPER_FILEMAGIC ||
674  map->num_mappings < 0 ||
675  map->num_mappings > MAX_MAPPINGS)
676  ereport(FATAL,
677  (errmsg("relation mapping file \"%s\" contains invalid data",
678  mapfilename)));
679 
680  /* verify the CRC */
681  INIT_CRC32C(crc);
682  COMP_CRC32C(crc, (char *) map, offsetof(RelMapFile, crc));
683  FIN_CRC32C(crc);
684 
685  if (!EQ_CRC32C(crc, map->crc))
686  ereport(FATAL,
687  (errmsg("relation mapping file \"%s\" contains incorrect checksum",
688  mapfilename)));
689 }
#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:1038
#define RELMAPPER_FILEMAGIC
Definition: relmapper.c:75
static RelMapFile shared_map
Definition: relmapper.c:99
pg_crc32c crc
Definition: relmapper.c:90
#define FATAL
Definition: elog.h:52
#define MAXPGPATH
int OpenTransientFile(FileName fileName, int fileFlags, int fileMode)
Definition: fd.c:2107
int errcode_for_file_access(void)
Definition: elog.c:598
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1205
#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:2268
char * DatabasePath
Definition: globals.c:84
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1181
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:18
#define offsetof(type, field)
Definition: c.h:555
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:256
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 863 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().

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

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

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

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