PostgreSQL Source Code  git master
storage.h File Reference
#include "storage/block.h"
#include "storage/relfilenode.h"
#include "utils/relcache.h"
Include dependency graph for storage.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void RelationCreateStorage (RelFileNode rnode, char relpersistence)
 
void RelationDropStorage (Relation rel)
 
void RelationPreserveStorage (RelFileNode rnode, bool atCommit)
 
void RelationTruncate (Relation rel, BlockNumber nblocks)
 
void smgrDoPendingDeletes (bool isCommit)
 
int smgrGetPendingDeletes (bool forCommit, RelFileNode **ptr)
 
void AtSubCommit_smgr (void)
 
void AtSubAbort_smgr (void)
 
void PostPrepare_smgr (void)
 

Function Documentation

◆ AtSubAbort_smgr()

void AtSubAbort_smgr ( void  )

Definition at line 471 of file storage.c.

References smgrDoPendingDeletes().

Referenced by AbortSubTransaction().

472 {
473  smgrDoPendingDeletes(false);
474 }
void smgrDoPendingDeletes(bool isCommit)
Definition: storage.c:306

◆ AtSubCommit_smgr()

void AtSubCommit_smgr ( void  )

Definition at line 451 of file storage.c.

References GetCurrentTransactionNestLevel(), PendingRelDelete::nestLevel, and PendingRelDelete::next.

Referenced by CommitSubTransaction().

452 {
453  int nestLevel = GetCurrentTransactionNestLevel();
454  PendingRelDelete *pending;
455 
456  for (pending = pendingDeletes; pending != NULL; pending = pending->next)
457  {
458  if (pending->nestLevel >= nestLevel)
459  pending->nestLevel = nestLevel - 1;
460  }
461 }
struct PendingRelDelete * next
Definition: storage.c:61
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:754
static PendingRelDelete * pendingDeletes
Definition: storage.c:64

◆ PostPrepare_smgr()

void PostPrepare_smgr ( void  )

Definition at line 430 of file storage.c.

References PendingRelDelete::next, and pfree().

Referenced by PrepareTransaction().

431 {
432  PendingRelDelete *pending;
434 
435  for (pending = pendingDeletes; pending != NULL; pending = next)
436  {
437  next = pending->next;
439  /* must explicitly free the list entry */
440  pfree(pending);
441  }
442 }
static int32 next
Definition: blutils.c:210
void pfree(void *pointer)
Definition: mcxt.c:949
struct PendingRelDelete * next
Definition: storage.c:61
static PendingRelDelete * pendingDeletes
Definition: storage.c:64

◆ RelationCreateStorage()

void RelationCreateStorage ( RelFileNode  rnode,
char  relpersistence 
)

Definition at line 78 of file storage.c.

References PendingRelDelete::atCommit, PendingRelDelete::backend, BackendIdForTempRelations, elog, ERROR, GetCurrentTransactionNestLevel(), InvalidBackendId, log_smgrcreate(), MAIN_FORKNUM, MemoryContextAlloc(), PendingRelDelete::nestLevel, PendingRelDelete::next, RelFileNodeBackend::node, pendingDeletes, PendingRelDelete::relnode, RELPERSISTENCE_PERMANENT, RELPERSISTENCE_TEMP, RELPERSISTENCE_UNLOGGED, SMgrRelationData::smgr_rnode, smgrcreate(), smgropen(), and TopMemoryContext.

Referenced by ATExecSetTableSpace(), heap_create(), and RelationSetNewRelfilenode().

79 {
80  PendingRelDelete *pending;
81  SMgrRelation srel;
82  BackendId backend;
83  bool needs_wal;
84 
85  switch (relpersistence)
86  {
88  backend = BackendIdForTempRelations();
89  needs_wal = false;
90  break;
92  backend = InvalidBackendId;
93  needs_wal = false;
94  break;
96  backend = InvalidBackendId;
97  needs_wal = true;
98  break;
99  default:
100  elog(ERROR, "invalid relpersistence: %c", relpersistence);
101  return; /* placate compiler */
102  }
103 
104  srel = smgropen(rnode, backend);
105  smgrcreate(srel, MAIN_FORKNUM, false);
106 
107  if (needs_wal)
109 
110  /* Add the relation to the list of stuff to delete at abort */
111  pending = (PendingRelDelete *)
113  pending->relnode = rnode;
114  pending->backend = backend;
115  pending->atCommit = false; /* delete if abort */
117  pending->next = pendingDeletes;
118  pendingDeletes = pending;
119 }
BackendId backend
Definition: storage.c:58
void smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo)
Definition: smgr.c:376
#define RELPERSISTENCE_UNLOGGED
Definition: pg_class.h:171
#define RELPERSISTENCE_PERMANENT
Definition: pg_class.h:170
#define ERROR
Definition: elog.h:43
RelFileNodeBackend smgr_rnode
Definition: smgr.h:43
#define BackendIdForTempRelations()
Definition: backendid.h:34
MemoryContext TopMemoryContext
Definition: mcxt.c:43
SMgrRelation smgropen(RelFileNode rnode, BackendId backend)
Definition: smgr.c:137
struct PendingRelDelete * next
Definition: storage.c:61
#define InvalidBackendId
Definition: backendid.h:23
int BackendId
Definition: backendid.h:21
RelFileNode node
Definition: relfilenode.h:74
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:754
static PendingRelDelete * pendingDeletes
Definition: storage.c:64
RelFileNode relnode
Definition: storage.c:57
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:706
void log_smgrcreate(RelFileNode *rnode, ForkNumber forkNum)
Definition: storage.c:125
#define elog
Definition: elog.h:219
#define RELPERSISTENCE_TEMP
Definition: pg_class.h:172

◆ RelationDropStorage()

void RelationDropStorage ( Relation  rel)

Definition at line 145 of file storage.c.

References PendingRelDelete::atCommit, PendingRelDelete::backend, GetCurrentTransactionNestLevel(), MemoryContextAlloc(), PendingRelDelete::nestLevel, PendingRelDelete::next, pendingDeletes, RelationData::rd_backend, RelationData::rd_node, RelationCloseSmgr, PendingRelDelete::relnode, and TopMemoryContext.

Referenced by ATExecSetTableSpace(), DefineQueryRewrite(), heap_drop_with_catalog(), index_drop(), and RelationSetNewRelfilenode().

146 {
147  PendingRelDelete *pending;
148 
149  /* Add the relation to the list of stuff to delete at commit */
150  pending = (PendingRelDelete *)
152  pending->relnode = rel->rd_node;
153  pending->backend = rel->rd_backend;
154  pending->atCommit = true; /* delete if commit */
156  pending->next = pendingDeletes;
157  pendingDeletes = pending;
158 
159  /*
160  * NOTE: if the relation was created in this transaction, it will now be
161  * present in the pending-delete list twice, once with atCommit true and
162  * once with atCommit false. Hence, it will be physically deleted at end
163  * of xact in either case (and the other entry will be ignored by
164  * smgrDoPendingDeletes, so no error will occur). We could instead remove
165  * the existing list entry and delete the physical file immediately, but
166  * for now I'll keep the logic simple.
167  */
168 
169  RelationCloseSmgr(rel);
170 }
BackendId backend
Definition: storage.c:58
#define RelationCloseSmgr(relation)
Definition: rel.h:481
MemoryContext TopMemoryContext
Definition: mcxt.c:43
struct PendingRelDelete * next
Definition: storage.c:61
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:754
RelFileNode rd_node
Definition: rel.h:85
BackendId rd_backend
Definition: rel.h:89
static PendingRelDelete * pendingDeletes
Definition: storage.c:64
RelFileNode relnode
Definition: storage.c:57
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:706

◆ RelationPreserveStorage()

void RelationPreserveStorage ( RelFileNode  rnode,
bool  atCommit 
)

Definition at line 190 of file storage.c.

References PendingRelDelete::atCommit, PendingRelDelete::next, pfree(), RelFileNodeEquals, and PendingRelDelete::relnode.

Referenced by ATExecAddIndex(), and write_relmap_file().

191 {
192  PendingRelDelete *pending;
193  PendingRelDelete *prev;
195 
196  prev = NULL;
197  for (pending = pendingDeletes; pending != NULL; pending = next)
198  {
199  next = pending->next;
200  if (RelFileNodeEquals(rnode, pending->relnode)
201  && pending->atCommit == atCommit)
202  {
203  /* unlink and delete list entry */
204  if (prev)
205  prev->next = next;
206  else
208  pfree(pending);
209  /* prev does not change */
210  }
211  else
212  {
213  /* unrelated entry, don't touch it */
214  prev = pending;
215  }
216  }
217 }
static int32 next
Definition: blutils.c:210
void pfree(void *pointer)
Definition: mcxt.c:949
struct PendingRelDelete * next
Definition: storage.c:61
static PendingRelDelete * pendingDeletes
Definition: storage.c:64
RelFileNode relnode
Definition: storage.c:57
#define RelFileNodeEquals(node1, node2)
Definition: relfilenode.h:88

◆ RelationTruncate()

void RelationTruncate ( Relation  rel,
BlockNumber  nblocks 
)

Definition at line 227 of file storage.c.

References xl_smgr_truncate::blkno, xl_smgr_truncate::flags, FreeSpaceMapTruncateRel(), FSM_FORKNUM, InvalidBlockNumber, MAIN_FORKNUM, RelationData::rd_node, RelationData::rd_smgr, RelationNeedsWAL, RelationOpenSmgr, xl_smgr_truncate::rnode, SMgrRelationData::smgr_fsm_nblocks, SMgrRelationData::smgr_targblock, SMGR_TRUNCATE_ALL, SMgrRelationData::smgr_vm_nblocks, smgrexists(), smgrtruncate(), VISIBILITYMAP_FORKNUM, visibilitymap_truncate(), XLOG_SMGR_TRUNCATE, XLogBeginInsert(), XLogFlush(), XLogInsert(), XLogRegisterData(), and XLR_SPECIAL_REL_UPDATE.

Referenced by heap_truncate_one_rel(), lazy_truncate_heap(), RelationTruncateIndexes(), and spgvacuumscan().

228 {
229  bool fsm;
230  bool vm;
231 
232  /* Open it at the smgr level if not already done */
233  RelationOpenSmgr(rel);
234 
235  /*
236  * Make sure smgr_targblock etc aren't pointing somewhere past new end
237  */
241 
242  /* Truncate the FSM first if it exists */
243  fsm = smgrexists(rel->rd_smgr, FSM_FORKNUM);
244  if (fsm)
245  FreeSpaceMapTruncateRel(rel, nblocks);
246 
247  /* Truncate the visibility map too if it exists. */
249  if (vm)
250  visibilitymap_truncate(rel, nblocks);
251 
252  /*
253  * We WAL-log the truncation before actually truncating, which means
254  * trouble if the truncation fails. If we then crash, the WAL replay
255  * likely isn't going to succeed in the truncation either, and cause a
256  * PANIC. It's tempting to put a critical section here, but that cure
257  * would be worse than the disease. It would turn a usually harmless
258  * failure to truncate, that might spell trouble at WAL replay, into a
259  * certain PANIC.
260  */
261  if (RelationNeedsWAL(rel))
262  {
263  /*
264  * Make an XLOG entry reporting the file truncation.
265  */
266  XLogRecPtr lsn;
267  xl_smgr_truncate xlrec;
268 
269  xlrec.blkno = nblocks;
270  xlrec.rnode = rel->rd_node;
271  xlrec.flags = SMGR_TRUNCATE_ALL;
272 
273  XLogBeginInsert();
274  XLogRegisterData((char *) &xlrec, sizeof(xlrec));
275 
276  lsn = XLogInsert(RM_SMGR_ID,
278 
279  /*
280  * Flush, because otherwise the truncation of the main relation might
281  * hit the disk before the WAL record, and the truncation of the FSM
282  * or visibility map. If we crashed during that window, we'd be left
283  * with a truncated heap, but the FSM or visibility map would still
284  * contain entries for the non-existent heap pages.
285  */
286  if (fsm || vm)
287  XLogFlush(lsn);
288  }
289 
290  /* Do the real work */
291  smgrtruncate(rel->rd_smgr, MAIN_FORKNUM, nblocks);
292 }
BlockNumber smgr_vm_nblocks
Definition: smgr.h:57
#define XLR_SPECIAL_REL_UPDATE
Definition: xlogrecord.h:71
struct SMgrRelationData * rd_smgr
Definition: rel.h:87
void smgrtruncate(SMgrRelation reln, ForkNumber forknum, BlockNumber nblocks)
Definition: smgr.c:684
BlockNumber smgr_fsm_nblocks
Definition: smgr.h:56
RelFileNode rnode
Definition: storage_xlog.h:49
bool smgrexists(SMgrRelation reln, ForkNumber forknum)
Definition: smgr.c:287
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2763
#define RelationOpenSmgr(relation)
Definition: rel.h:469
void FreeSpaceMapTruncateRel(Relation rel, BlockNumber nblocks)
Definition: freespace.c:299
#define XLOG_SMGR_TRUNCATE
Definition: storage_xlog.h:31
void XLogRegisterData(char *data, int len)
Definition: xloginsert.c:323
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:415
RelFileNode rd_node
Definition: rel.h:85
uint64 XLogRecPtr
Definition: xlogdefs.h:21
BlockNumber smgr_targblock
Definition: smgr.h:55
void visibilitymap_truncate(Relation rel, BlockNumber nheapblocks)
#define InvalidBlockNumber
Definition: block.h:33
#define RelationNeedsWAL(relation)
Definition: rel.h:514
BlockNumber blkno
Definition: storage_xlog.h:48
#define SMGR_TRUNCATE_ALL
Definition: storage_xlog.h:43
void XLogBeginInsert(void)
Definition: xloginsert.c:120

◆ smgrDoPendingDeletes()

void smgrDoPendingDeletes ( bool  isCommit)

Definition at line 306 of file storage.c.

References PendingRelDelete::atCommit, PendingRelDelete::backend, GetCurrentTransactionNestLevel(), i, PendingRelDelete::nestLevel, PendingRelDelete::next, palloc(), pfree(), PendingRelDelete::relnode, repalloc(), smgrclose(), smgrdounlinkall(), and smgropen().

Referenced by AbortTransaction(), AtSubAbort_smgr(), and CommitTransaction().

307 {
308  int nestLevel = GetCurrentTransactionNestLevel();
309  PendingRelDelete *pending;
310  PendingRelDelete *prev;
312  int nrels = 0,
313  i = 0,
314  maxrels = 0;
315  SMgrRelation *srels = NULL;
316 
317  prev = NULL;
318  for (pending = pendingDeletes; pending != NULL; pending = next)
319  {
320  next = pending->next;
321  if (pending->nestLevel < nestLevel)
322  {
323  /* outer-level entries should not be processed yet */
324  prev = pending;
325  }
326  else
327  {
328  /* unlink list entry first, so we don't retry on failure */
329  if (prev)
330  prev->next = next;
331  else
333  /* do deletion if called for */
334  if (pending->atCommit == isCommit)
335  {
336  SMgrRelation srel;
337 
338  srel = smgropen(pending->relnode, pending->backend);
339 
340  /* allocate the initial array, or extend it, if needed */
341  if (maxrels == 0)
342  {
343  maxrels = 8;
344  srels = palloc(sizeof(SMgrRelation) * maxrels);
345  }
346  else if (maxrels <= nrels)
347  {
348  maxrels *= 2;
349  srels = repalloc(srels, sizeof(SMgrRelation) * maxrels);
350  }
351 
352  srels[nrels++] = srel;
353  }
354  /* must explicitly free the list entry */
355  pfree(pending);
356  /* prev does not change */
357  }
358  }
359 
360  if (nrels > 0)
361  {
362  smgrdounlinkall(srels, nrels, false);
363 
364  for (i = 0; i < nrels; i++)
365  smgrclose(srels[i]);
366 
367  pfree(srels);
368  }
369 }
BackendId backend
Definition: storage.c:58
void smgrclose(SMgrRelation reln)
Definition: smgr.c:296
static int32 next
Definition: blutils.c:210
void smgrdounlinkall(SMgrRelation *rels, int nrels, bool isRedo)
Definition: smgr.c:471
void pfree(void *pointer)
Definition: mcxt.c:949
SMgrRelation smgropen(RelFileNode rnode, BackendId backend)
Definition: smgr.c:137
struct PendingRelDelete * next
Definition: storage.c:61
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:754
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:962
static PendingRelDelete * pendingDeletes
Definition: storage.c:64
void * palloc(Size size)
Definition: mcxt.c:848
RelFileNode relnode
Definition: storage.c:57
int i

◆ smgrGetPendingDeletes()

int smgrGetPendingDeletes ( bool  forCommit,
RelFileNode **  ptr 
)

Definition at line 389 of file storage.c.

References PendingRelDelete::atCommit, PendingRelDelete::backend, GetCurrentTransactionNestLevel(), InvalidBackendId, PendingRelDelete::nestLevel, PendingRelDelete::next, palloc(), and PendingRelDelete::relnode.

Referenced by RecordTransactionAbort(), RecordTransactionCommit(), and StartPrepare().

390 {
391  int nestLevel = GetCurrentTransactionNestLevel();
392  int nrels;
393  RelFileNode *rptr;
394  PendingRelDelete *pending;
395 
396  nrels = 0;
397  for (pending = pendingDeletes; pending != NULL; pending = pending->next)
398  {
399  if (pending->nestLevel >= nestLevel && pending->atCommit == forCommit
400  && pending->backend == InvalidBackendId)
401  nrels++;
402  }
403  if (nrels == 0)
404  {
405  *ptr = NULL;
406  return 0;
407  }
408  rptr = (RelFileNode *) palloc(nrels * sizeof(RelFileNode));
409  *ptr = rptr;
410  for (pending = pendingDeletes; pending != NULL; pending = pending->next)
411  {
412  if (pending->nestLevel >= nestLevel && pending->atCommit == forCommit
413  && pending->backend == InvalidBackendId)
414  {
415  *rptr = pending->relnode;
416  rptr++;
417  }
418  }
419  return nrels;
420 }
BackendId backend
Definition: storage.c:58
struct PendingRelDelete * next
Definition: storage.c:61
#define InvalidBackendId
Definition: backendid.h:23
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:754
static PendingRelDelete * pendingDeletes
Definition: storage.c:64
void * palloc(Size size)
Definition: mcxt.c:848
RelFileNode relnode
Definition: storage.c:57