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 "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 76 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 72 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 302 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().

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

Definition at line 422 of file relmapper.c.

References merge_map_updates(), and RelMapFile::num_mappings.

Referenced by AtCCI_LocalCache().

423 {
425  {
428  true);
430  }
432  {
435  true);
437  }
438 }
static void merge_map_updates(RelMapFile *map, const RelMapFile *updates, bool add_okay)
Definition: relmapper.c:334
static RelMapFile pending_shared_updates
Definition: relmapper.c:116
static RelMapFile active_local_updates
Definition: relmapper.c:115
static RelMapFile pending_local_updates
Definition: relmapper.c:117
static RelMapFile active_shared_updates
Definition: relmapper.c:114
int32 num_mappings
Definition: relmapper.c:87
void AtEOXact_RelationMap ( bool  isCommit)

Definition at line 456 of file relmapper.c.

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

Referenced by AbortTransaction(), and CommitTransaction().

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

Definition at line 500 of file relmapper.c.

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

Referenced by PrepareTransaction().

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

Definition at line 523 of file relmapper.c.

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

Referenced by CheckPointGuts().

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

Definition at line 625 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, read, RELMAPPER_FILEMAGIC, RELMAPPER_FILENAME, shared_map, and snprintf().

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

626 {
627  RelMapFile *map;
628  char mapfilename[MAXPGPATH];
629  pg_crc32c crc;
630  int fd;
631 
632  if (shared)
633  {
634  snprintf(mapfilename, sizeof(mapfilename), "global/%s",
636  map = &shared_map;
637  }
638  else
639  {
640  snprintf(mapfilename, sizeof(mapfilename), "%s/%s",
642  map = &local_map;
643  }
644 
645  /* Read data ... */
646  fd = OpenTransientFile(mapfilename,
647  O_RDONLY | PG_BINARY, S_IRUSR | S_IWUSR);
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  */
661  if (read(fd, map, sizeof(RelMapFile)) != sizeof(RelMapFile))
662  ereport(FATAL,
664  errmsg("could not read relation mapping file \"%s\": %m",
665  mapfilename)));
666 
667  CloseTransientFile(fd);
668 
669  /* check for correct magic number, etc */
670  if (map->magic != RELMAPPER_FILEMAGIC ||
671  map->num_mappings < 0 ||
672  map->num_mappings > MAX_MAPPINGS)
673  ereport(FATAL,
674  (errmsg("relation mapping file \"%s\" contains invalid data",
675  mapfilename)));
676 
677  /* verify the CRC */
678  INIT_CRC32C(crc);
679  COMP_CRC32C(crc, (char *) map, offsetof(RelMapFile, crc));
680  FIN_CRC32C(crc);
681 
682  if (!EQ_CRC32C(crc, map->crc))
683  ereport(FATAL,
684  (errmsg("relation mapping file \"%s\" contains incorrect checksum",
685  mapfilename)));
686 }
#define INIT_CRC32C(crc)
Definition: pg_crc32c.h:41
int32 magic
Definition: relmapper.c:86
static RelMapFile local_map
Definition: relmapper.c:99
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:76
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1037
#define RELMAPPER_FILEMAGIC
Definition: relmapper.c:74
static RelMapFile shared_map
Definition: relmapper.c:98
pg_crc32c crc
Definition: relmapper.c:89
#define FATAL
Definition: elog.h:52
#define MAXPGPATH
int OpenTransientFile(FileName fileName, int fileFlags, int fileMode)
Definition: fd.c:2016
int errcode_for_file_access(void)
Definition: elog.c:598
#define EQ_CRC32C(c1, c2)
Definition: pg_crc32c.h:42
#define ereport(elevel, rest)
Definition: elog.h:122
#define RELMAPPER_FILENAME
Definition: relmapper.c:72
int CloseTransientFile(int fd)
Definition: fd.c:2177
char * DatabasePath
Definition: globals.c:84
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:87
#define read(a, b, c)
Definition: win32.h:18
#define offsetof(type, field)
Definition: c.h:550
static void merge_map_updates ( RelMapFile map,
const RelMapFile updates,
bool  add_okay 
)
static

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

335 {
336  int32 i;
337 
338  for (i = 0; i < updates->num_mappings; i++)
339  {
340  apply_map_update(map,
341  updates->mappings[i].mapoid,
342  updates->mappings[i].mapfilenode,
343  add_okay);
344  }
345 }
Oid mapoid
Definition: relmapper.c:80
signed int int32
Definition: c.h:253
RelMapping mappings[MAX_MAPPINGS]
Definition: relmapper.c:88
Oid mapfilenode
Definition: relmapper.c:81
int i
int32 num_mappings
Definition: relmapper.c:87
static void apply_map_update(RelMapFile *map, Oid relationId, Oid fileNode, bool add_okay)
Definition: relmapper.c:302
static void perform_relmap_update ( bool  shared,
const RelMapFile updates 
)
static

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

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

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

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

Definition at line 537 of file relmapper.c.

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

Referenced by BootstrapModeMain().

538 {
540 
541  /* Shouldn't be anything "pending" ... */
546 
547  /* Write the files; no WAL or sinval needed */
548  write_relmap_file(true, &shared_map, false, false, false,
550  write_relmap_file(false, &local_map, false, false, false,
552 }
static RelMapFile local_map
Definition: relmapper.c:99
#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:709
Oid MyDatabaseTableSpace
Definition: globals.c:78
static RelMapFile pending_shared_updates
Definition: relmapper.c:116
static RelMapFile shared_map
Definition: relmapper.c:98
static RelMapFile active_local_updates
Definition: relmapper.c:115
static RelMapFile pending_local_updates
Definition: relmapper.c:117
static RelMapFile active_shared_updates
Definition: relmapper.c:114
Oid MyDatabaseId
Definition: globals.c:76
#define InvalidOid
Definition: postgres_ext.h:36
char * DatabasePath
Definition: globals.c:84
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:670
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:365
int32 num_mappings
Definition: relmapper.c:87
void RelationMapInitialize ( void  )

Definition at line 561 of file relmapper.c.

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

Referenced by RelationCacheInitialize().

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

Definition at line 581 of file relmapper.c.

References IsBootstrapProcessingMode, and load_relmap_file().

Referenced by RelationCacheInitializePhase2().

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

Definition at line 602 of file relmapper.c.

References IsBootstrapProcessingMode, and load_relmap_file().

Referenced by RelationCacheInitializePhase3().

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

Definition at line 386 of file relmapper.c.

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

Referenced by LocalExecuteInvalidationMessage().

387 {
388  if (shared)
389  {
391  load_relmap_file(true);
392  }
393  else
394  {
396  load_relmap_file(false);
397  }
398 }
int32 magic
Definition: relmapper.c:86
static RelMapFile local_map
Definition: relmapper.c:99
#define RELMAPPER_FILEMAGIC
Definition: relmapper.c:74
static RelMapFile shared_map
Definition: relmapper.c:98
static void load_relmap_file(bool shared)
Definition: relmapper.c:625
void RelationMapInvalidateAll ( void  )

Definition at line 408 of file relmapper.c.

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

Referenced by RelationCacheInvalidate().

409 {
411  load_relmap_file(true);
413  load_relmap_file(false);
414 }
int32 magic
Definition: relmapper.c:86
static RelMapFile local_map
Definition: relmapper.c:99
#define RELMAPPER_FILEMAGIC
Definition: relmapper.c:74
static RelMapFile shared_map
Definition: relmapper.c:98
static void load_relmap_file(bool shared)
Definition: relmapper.c:625
Oid RelationMapOidToFilenode ( Oid  relationId,
bool  shared 
)

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

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

Definition at line 356 of file relmapper.c.

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

Referenced by finish_heap_swap().

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

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

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

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

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

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

712 {
713  int fd;
714  RelMapFile *realmap;
715  char mapfilename[MAXPGPATH];
716 
717  /*
718  * Fill in the overhead fields and update CRC.
719  */
720  newmap->magic = RELMAPPER_FILEMAGIC;
721  if (newmap->num_mappings < 0 || newmap->num_mappings > MAX_MAPPINGS)
722  elog(ERROR, "attempt to write bogus relation mapping");
723 
724  INIT_CRC32C(newmap->crc);
725  COMP_CRC32C(newmap->crc, (char *) newmap, offsetof(RelMapFile, crc));
726  FIN_CRC32C(newmap->crc);
727 
728  /*
729  * Open the target file. We prefer to do this before entering the
730  * critical section, so that an open() failure need not force PANIC.
731  */
732  if (shared)
733  {
734  snprintf(mapfilename, sizeof(mapfilename), "global/%s",
736  realmap = &shared_map;
737  }
738  else
739  {
740  snprintf(mapfilename, sizeof(mapfilename), "%s/%s",
741  dbpath, RELMAPPER_FILENAME);
742  realmap = &local_map;
743  }
744 
745  fd = OpenTransientFile(mapfilename,
746  O_WRONLY | O_CREAT | PG_BINARY,
747  S_IRUSR | S_IWUSR);
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;
777  if (write(fd, newmap, sizeof(RelMapFile)) != sizeof(RelMapFile))
778  {
779  /* if write didn't set errno, assume problem is no disk space */
780  if (errno == 0)
781  errno = ENOSPC;
782  ereport(ERROR,
784  errmsg("could not write to relation mapping file \"%s\": %m",
785  mapfilename)));
786  }
787 
788  /*
789  * We choose to fsync the data to disk before considering the task done.
790  * It would be possible to relax this if it turns out to be a performance
791  * issue, but it would complicate checkpointing --- see notes for
792  * CheckPointRelationMap.
793  */
794  if (pg_fsync(fd) != 0)
795  ereport(ERROR,
797  errmsg("could not fsync relation mapping file \"%s\": %m",
798  mapfilename)));
799 
800  if (CloseTransientFile(fd))
801  ereport(ERROR,
803  errmsg("could not close relation mapping file \"%s\": %m",
804  mapfilename)));
805 
806  /*
807  * Now that the file is safely on disk, send sinval message to let other
808  * backends know to re-read it. We must do this inside the critical
809  * section: if for some reason we fail to send the message, we have to
810  * force a database-wide PANIC. Otherwise other backends might continue
811  * execution with stale mapping information, which would be catastrophic
812  * as soon as others began to use the now-committed data.
813  */
814  if (send_sinval)
815  CacheInvalidateRelmap(dbid);
816 
817  /*
818  * Make sure that the files listed in the map are not deleted if the outer
819  * transaction aborts. This had better be within the critical section
820  * too: it's not likely to fail, but if it did, we'd arrive at transaction
821  * abort with the files still vulnerable. PANICing will leave things in a
822  * good state on-disk.
823  *
824  * Note: we're cheating a little bit here by assuming that mapped files
825  * are either in pg_global or the database's default tablespace.
826  */
827  if (preserve_files)
828  {
829  int32 i;
830 
831  for (i = 0; i < newmap->num_mappings; i++)
832  {
833  RelFileNode rnode;
834 
835  rnode.spcNode = tsid;
836  rnode.dbNode = dbid;
837  rnode.relNode = newmap->mappings[i].mapfilenode;
838  RelationPreserveStorage(rnode, false);
839  }
840  }
841 
842  /* Success, update permanent copy */
843  memcpy(realmap, newmap, sizeof(RelMapFile));
844 
845  /* Critical section done */
846  if (write_wal)
848 }
#define INIT_CRC32C(crc)
Definition: pg_crc32c.h:41
void RelationPreserveStorage(RelFileNode rnode, bool atCommit)
Definition: storage.c:190
int32 magic
Definition: relmapper.c:86
#define write(a, b, c)
Definition: win32.h:19
static RelMapFile local_map
Definition: relmapper.c:99
#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:1352
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
#define MAX_MAPPINGS
Definition: relmapper.c:76
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2744
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1037
signed int int32
Definition: c.h:253
#define RELMAPPER_FILEMAGIC
Definition: relmapper.c:74
static RelMapFile shared_map
Definition: relmapper.c:98
#define ERROR
Definition: elog.h:43
pg_crc32c crc
Definition: relmapper.c:89
#define MAXPGPATH
int OpenTransientFile(FileName fileName, int fileFlags, int fileMode)
Definition: fd.c:2016
int errcode_for_file_access(void)
Definition: elog.c:598
RelMapping mappings[MAX_MAPPINGS]
Definition: relmapper.c:88
#define ereport(elevel, rest)
Definition: elog.h:122
#define RELMAPPER_FILENAME
Definition: relmapper.c:72
int CloseTransientFile(int fd)
Definition: fd.c:2177
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:81
uint64 XLogRecPtr
Definition: xlogdefs.h:21
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
int pg_fsync(int fd)
Definition: fd.c:326
#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:87
#define offsetof(type, field)
Definition: c.h:550

Variable Documentation

RelMapFile active_local_updates
static
RelMapFile active_shared_updates
static
RelMapFile pending_local_updates
static

Definition at line 117 of file relmapper.c.

Referenced by RelationMapUpdateMap().

RelMapFile pending_shared_updates
static

Definition at line 116 of file relmapper.c.

Referenced by RelationMapUpdateMap().