PostgreSQL Source Code  git master
storage.c File Reference
#include "postgres.h"
#include "access/visibilitymap.h"
#include "access/xact.h"
#include "access/xlog.h"
#include "access/xloginsert.h"
#include "access/xlogutils.h"
#include "catalog/storage.h"
#include "catalog/storage_xlog.h"
#include "storage/freespace.h"
#include "storage/smgr.h"
#include "utils/memutils.h"
#include "utils/rel.h"
Include dependency graph for storage.c:

Go to the source code of this file.

Data Structures

struct  PendingRelDelete
 

Typedefs

typedef struct PendingRelDelete PendingRelDelete
 

Functions

void RelationCreateStorage (RelFileNode rnode, char relpersistence)
 
void log_smgrcreate (RelFileNode *rnode, ForkNumber forkNum)
 
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 PostPrepare_smgr (void)
 
void AtSubCommit_smgr (void)
 
void AtSubAbort_smgr (void)
 
void smgr_redo (XLogReaderState *record)
 

Variables

static PendingRelDeletependingDeletes = NULL
 

Typedef Documentation

◆ PendingRelDelete

Function Documentation

◆ AtSubAbort_smgr()

void AtSubAbort_smgr ( void  )

Definition at line 470 of file storage.c.

References smgrDoPendingDeletes().

Referenced by AbortSubTransaction().

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

◆ AtSubCommit_smgr()

void AtSubCommit_smgr ( void  )

Definition at line 450 of file storage.c.

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

Referenced by CommitSubTransaction().

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

◆ log_smgrcreate()

void log_smgrcreate ( RelFileNode rnode,
ForkNumber  forkNum 
)

Definition at line 124 of file storage.c.

References xl_smgr_create::forkNum, xl_smgr_create::rnode, XLOG_SMGR_CREATE, XLogBeginInsert(), XLogInsert(), XLogRegisterData(), and XLR_SPECIAL_REL_UPDATE.

Referenced by ATExecSetTableSpace(), heap_create_init_fork(), and RelationCreateStorage().

125 {
126  xl_smgr_create xlrec;
127 
128  /*
129  * Make an XLOG entry reporting the file creation.
130  */
131  xlrec.rnode = *rnode;
132  xlrec.forkNum = forkNum;
133 
134  XLogBeginInsert();
135  XLogRegisterData((char *) &xlrec, sizeof(xlrec));
137 }
#define XLR_SPECIAL_REL_UPDATE
Definition: xlogrecord.h:71
#define XLOG_SMGR_CREATE
Definition: storage_xlog.h:30
void XLogRegisterData(char *data, int len)
Definition: xloginsert.c:323
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:415
ForkNumber forkNum
Definition: storage_xlog.h:36
void XLogBeginInsert(void)
Definition: xloginsert.c:120
RelFileNode rnode
Definition: storage_xlog.h:35

◆ PostPrepare_smgr()

void PostPrepare_smgr ( void  )

Definition at line 429 of file storage.c.

References PendingRelDelete::next, and pfree().

Referenced by PrepareTransaction().

430 {
431  PendingRelDelete *pending;
433 
434  for (pending = pendingDeletes; pending != NULL; pending = next)
435  {
436  next = pending->next;
438  /* must explicitly free the list entry */
439  pfree(pending);
440  }
441 }
static int32 next
Definition: blutils.c:211
void pfree(void *pointer)
Definition: mcxt.c:1031
struct PendingRelDelete * next
Definition: storage.c:60
static PendingRelDelete * pendingDeletes
Definition: storage.c:63

◆ RelationCreateStorage()

void RelationCreateStorage ( RelFileNode  rnode,
char  relpersistence 
)

Definition at line 77 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, SMgrRelationData::smgr_rnode, smgrcreate(), smgropen(), and TopMemoryContext.

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

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

◆ RelationDropStorage()

void RelationDropStorage ( Relation  rel)

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

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

◆ RelationPreserveStorage()

void RelationPreserveStorage ( RelFileNode  rnode,
bool  atCommit 
)

Definition at line 189 of file storage.c.

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

Referenced by ATExecAddIndex(), and write_relmap_file().

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

◆ RelationTruncate()

void RelationTruncate ( Relation  rel,
BlockNumber  nblocks 
)

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

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

◆ smgr_redo()

void smgr_redo ( XLogReaderState record)

Definition at line 476 of file storage.c.

References Assert, xl_smgr_truncate::blkno, CreateFakeRelcacheEntry(), elog, XLogReaderState::EndRecPtr, xl_smgr_truncate::flags, xl_smgr_create::forkNum, FreeFakeRelcacheEntry(), FreeSpaceMapTruncateRel(), FSM_FORKNUM, InvalidBackendId, MAIN_FORKNUM, PANIC, xl_smgr_create::rnode, xl_smgr_truncate::rnode, SMGR_TRUNCATE_FSM, SMGR_TRUNCATE_HEAP, SMGR_TRUNCATE_VM, smgrcreate(), smgrexists(), smgropen(), smgrtruncate(), VISIBILITYMAP_FORKNUM, visibilitymap_truncate(), XLOG_SMGR_CREATE, XLOG_SMGR_TRUNCATE, XLogFlush(), XLogRecGetData, XLogRecGetInfo, XLogRecHasAnyBlockRefs, XLogTruncateRelation(), and XLR_INFO_MASK.

477 {
478  XLogRecPtr lsn = record->EndRecPtr;
479  uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
480 
481  /* Backup blocks are not used in smgr records */
482  Assert(!XLogRecHasAnyBlockRefs(record));
483 
484  if (info == XLOG_SMGR_CREATE)
485  {
486  xl_smgr_create *xlrec = (xl_smgr_create *) XLogRecGetData(record);
487  SMgrRelation reln;
488 
489  reln = smgropen(xlrec->rnode, InvalidBackendId);
490  smgrcreate(reln, xlrec->forkNum, true);
491  }
492  else if (info == XLOG_SMGR_TRUNCATE)
493  {
494  xl_smgr_truncate *xlrec = (xl_smgr_truncate *) XLogRecGetData(record);
495  SMgrRelation reln;
496  Relation rel;
497 
498  reln = smgropen(xlrec->rnode, InvalidBackendId);
499 
500  /*
501  * Forcibly create relation if it doesn't exist (which suggests that
502  * it was dropped somewhere later in the WAL sequence). As in
503  * XLogReadBufferForRedo, we prefer to recreate the rel and replay the
504  * log as best we can until the drop is seen.
505  */
506  smgrcreate(reln, MAIN_FORKNUM, true);
507 
508  /*
509  * Before we perform the truncation, update minimum recovery point to
510  * cover this WAL record. Once the relation is truncated, there's no
511  * going back. The buffer manager enforces the WAL-first rule for
512  * normal updates to relation files, so that the minimum recovery
513  * point is always updated before the corresponding change in the data
514  * file is flushed to disk. We have to do the same manually here.
515  *
516  * Doing this before the truncation means that if the truncation fails
517  * for some reason, you cannot start up the system even after restart,
518  * until you fix the underlying situation so that the truncation will
519  * succeed. Alternatively, we could update the minimum recovery point
520  * after truncation, but that would leave a small window where the
521  * WAL-first rule could be violated.
522  */
523  XLogFlush(lsn);
524 
525  if ((xlrec->flags & SMGR_TRUNCATE_HEAP) != 0)
526  {
527  smgrtruncate(reln, MAIN_FORKNUM, xlrec->blkno);
528 
529  /* Also tell xlogutils.c about it */
530  XLogTruncateRelation(xlrec->rnode, MAIN_FORKNUM, xlrec->blkno);
531  }
532 
533  /* Truncate FSM and VM too */
534  rel = CreateFakeRelcacheEntry(xlrec->rnode);
535 
536  if ((xlrec->flags & SMGR_TRUNCATE_FSM) != 0 &&
537  smgrexists(reln, FSM_FORKNUM))
538  FreeSpaceMapTruncateRel(rel, xlrec->blkno);
539  if ((xlrec->flags & SMGR_TRUNCATE_VM) != 0 &&
541  visibilitymap_truncate(rel, xlrec->blkno);
542 
544  }
545  else
546  elog(PANIC, "smgr_redo: unknown op code %u", info);
547 }
void XLogTruncateRelation(RelFileNode rnode, ForkNumber forkNum, BlockNumber nblocks)
Definition: xlogutils.c:636
#define SMGR_TRUNCATE_HEAP
Definition: storage_xlog.h:40
void smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo)
Definition: smgr.c:376
unsigned char uint8
Definition: c.h:323
#define SMGR_TRUNCATE_FSM
Definition: storage_xlog.h:42
void smgrtruncate(SMgrRelation reln, ForkNumber forknum, BlockNumber nblocks)
Definition: smgr.c:684
RelFileNode rnode
Definition: storage_xlog.h:49
bool smgrexists(SMgrRelation reln, ForkNumber forknum)
Definition: smgr.c:287
#define PANIC
Definition: elog.h:53
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2783
#define XLOG_SMGR_CREATE
Definition: storage_xlog.h:30
XLogRecPtr EndRecPtr
Definition: xlogreader.h:120
#define XLogRecGetData(decoder)
Definition: xlogreader.h:226
Relation CreateFakeRelcacheEntry(RelFileNode rnode)
Definition: xlogutils.c:550
void FreeSpaceMapTruncateRel(Relation rel, BlockNumber nblocks)
Definition: freespace.c:259
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:222
SMgrRelation smgropen(RelFileNode rnode, BackendId backend)
Definition: smgr.c:137
#define XLOG_SMGR_TRUNCATE
Definition: storage_xlog.h:31
void FreeFakeRelcacheEntry(Relation fakerel)
Definition: xlogutils.c:591
#define InvalidBackendId
Definition: backendid.h:23
ForkNumber forkNum
Definition: storage_xlog.h:36
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:699
#define XLR_INFO_MASK
Definition: xlogrecord.h:62
void visibilitymap_truncate(Relation rel, BlockNumber nheapblocks)
#define SMGR_TRUNCATE_VM
Definition: storage_xlog.h:41
#define XLogRecHasAnyBlockRefs(decoder)
Definition: xlogreader.h:228
BlockNumber blkno
Definition: storage_xlog.h:48
#define elog
Definition: elog.h:219
RelFileNode rnode
Definition: storage_xlog.h:35

◆ smgrDoPendingDeletes()

void smgrDoPendingDeletes ( bool  isCommit)

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

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

◆ smgrGetPendingDeletes()

int smgrGetPendingDeletes ( bool  forCommit,
RelFileNode **  ptr 
)

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

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

Variable Documentation

◆ pendingDeletes

PendingRelDelete* pendingDeletes = NULL
static

Definition at line 63 of file storage.c.

Referenced by RelationCreateStorage(), and RelationDropStorage().