PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
smgr.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * smgr.c
4  * public interface routines to storage manager switch.
5  *
6  * All file system operations in POSTGRES dispatch through these
7  * routines.
8  *
9  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
10  * Portions Copyright (c) 1994, Regents of the University of California
11  *
12  *
13  * IDENTIFICATION
14  * src/backend/storage/smgr/smgr.c
15  *
16  *-------------------------------------------------------------------------
17  */
18 #include "postgres.h"
19 
20 #include "commands/tablespace.h"
21 #include "storage/bufmgr.h"
22 #include "storage/ipc.h"
23 #include "storage/smgr.h"
24 #include "utils/hsearch.h"
25 #include "utils/inval.h"
26 
27 
28 /*
29  * This struct of function pointers defines the API between smgr.c and
30  * any individual storage manager module. Note that smgr subfunctions are
31  * generally expected to report problems via elog(ERROR). An exception is
32  * that smgr_unlink should use elog(WARNING), rather than erroring out,
33  * because we normally unlink relations during post-commit/abort cleanup,
34  * and so it's too late to raise an error. Also, various conditions that
35  * would normally be errors should be allowed during bootstrap and/or WAL
36  * recovery --- see comments in md.c for details.
37  */
38 typedef struct f_smgr
39 {
40  void (*smgr_init) (void); /* may be NULL */
41  void (*smgr_shutdown) (void); /* may be NULL */
42  void (*smgr_close) (SMgrRelation reln, ForkNumber forknum);
43  void (*smgr_create) (SMgrRelation reln, ForkNumber forknum,
44  bool isRedo);
46  void (*smgr_unlink) (RelFileNodeBackend rnode, ForkNumber forknum,
47  bool isRedo);
48  void (*smgr_extend) (SMgrRelation reln, ForkNumber forknum,
49  BlockNumber blocknum, char *buffer, bool skipFsync);
50  void (*smgr_prefetch) (SMgrRelation reln, ForkNumber forknum,
51  BlockNumber blocknum);
52  void (*smgr_read) (SMgrRelation reln, ForkNumber forknum,
53  BlockNumber blocknum, char *buffer);
54  void (*smgr_write) (SMgrRelation reln, ForkNumber forknum,
55  BlockNumber blocknum, char *buffer, bool skipFsync);
56  void (*smgr_writeback) (SMgrRelation reln, ForkNumber forknum,
57  BlockNumber blocknum, BlockNumber nblocks);
59  void (*smgr_truncate) (SMgrRelation reln, ForkNumber forknum,
60  BlockNumber nblocks);
61  void (*smgr_immedsync) (SMgrRelation reln, ForkNumber forknum);
62  void (*smgr_pre_ckpt) (void); /* may be NULL */
63  void (*smgr_sync) (void); /* may be NULL */
64  void (*smgr_post_ckpt) (void); /* may be NULL */
65 } f_smgr;
66 
67 
68 static const f_smgr smgrsw[] = {
69  /* magnetic disk */
73  }
74 };
75 
76 static const int NSmgr = lengthof(smgrsw);
77 
78 
79 /*
80  * Each backend has a hashtable that stores all extant SMgrRelation objects.
81  * In addition, "unowned" SMgrRelation objects are chained together in a list.
82  */
84 
86 
87 /* local function prototypes */
88 static void smgrshutdown(int code, Datum arg);
89 static void add_to_unowned_list(SMgrRelation reln);
90 static void remove_from_unowned_list(SMgrRelation reln);
91 
92 
93 /*
94  * smgrinit(), smgrshutdown() -- Initialize or shut down storage
95  * managers.
96  *
97  * Note: smgrinit is called during backend startup (normal or standalone
98  * case), *not* during postmaster start. Therefore, any resources created
99  * here or destroyed in smgrshutdown are backend-local.
100  */
101 void
102 smgrinit(void)
103 {
104  int i;
105 
106  for (i = 0; i < NSmgr; i++)
107  {
108  if (smgrsw[i].smgr_init)
109  (*(smgrsw[i].smgr_init)) ();
110  }
111 
112  /* register the shutdown proc */
114 }
115 
116 /*
117  * on_proc_exit hook for smgr cleanup during backend shutdown
118  */
119 static void
121 {
122  int i;
123 
124  for (i = 0; i < NSmgr; i++)
125  {
126  if (smgrsw[i].smgr_shutdown)
127  (*(smgrsw[i].smgr_shutdown)) ();
128  }
129 }
130 
131 /*
132  * smgropen() -- Return an SMgrRelation object, creating it if need be.
133  *
134  * This does not attempt to actually open the underlying file.
135  */
138 {
139  RelFileNodeBackend brnode;
140  SMgrRelation reln;
141  bool found;
142 
143  if (SMgrRelationHash == NULL)
144  {
145  /* First time through: initialize the hash table */
146  HASHCTL ctl;
147 
148  MemSet(&ctl, 0, sizeof(ctl));
149  ctl.keysize = sizeof(RelFileNodeBackend);
150  ctl.entrysize = sizeof(SMgrRelationData);
151  SMgrRelationHash = hash_create("smgr relation table", 400,
152  &ctl, HASH_ELEM | HASH_BLOBS);
153  first_unowned_reln = NULL;
154  }
155 
156  /* Look up or create an entry */
157  brnode.node = rnode;
158  brnode.backend = backend;
159  reln = (SMgrRelation) hash_search(SMgrRelationHash,
160  (void *) &brnode,
161  HASH_ENTER, &found);
162 
163  /* Initialize it if not present before */
164  if (!found)
165  {
166  int forknum;
167 
168  /* hash_search already filled in the lookup key */
169  reln->smgr_owner = NULL;
173  reln->smgr_which = 0; /* we only have md.c at present */
174 
175  /* mark it not open */
176  for (forknum = 0; forknum <= MAX_FORKNUM; forknum++)
177  reln->md_num_open_segs[forknum] = 0;
178 
179  /* it has no owner yet */
180  add_to_unowned_list(reln);
181  }
182 
183  return reln;
184 }
185 
186 /*
187  * smgrsetowner() -- Establish a long-lived reference to an SMgrRelation object
188  *
189  * There can be only one owner at a time; this is sufficient since currently
190  * the only such owners exist in the relcache.
191  */
192 void
194 {
195  /* We don't support "disowning" an SMgrRelation here, use smgrclearowner */
196  Assert(owner != NULL);
197 
198  /*
199  * First, unhook any old owner. (Normally there shouldn't be any, but it
200  * seems possible that this can happen during swap_relation_files()
201  * depending on the order of processing. It's ok to close the old
202  * relcache entry early in that case.)
203  *
204  * If there isn't an old owner, then the reln should be in the unowned
205  * list, and we need to remove it.
206  */
207  if (reln->smgr_owner)
208  *(reln->smgr_owner) = NULL;
209  else
211 
212  /* Now establish the ownership relationship. */
213  reln->smgr_owner = owner;
214  *owner = reln;
215 }
216 
217 /*
218  * smgrclearowner() -- Remove long-lived reference to an SMgrRelation object
219  * if one exists
220  */
221 void
223 {
224  /* Do nothing if the SMgrRelation object is not owned by the owner */
225  if (reln->smgr_owner != owner)
226  return;
227 
228  /* unset the owner's reference */
229  *owner = NULL;
230 
231  /* unset our reference to the owner */
232  reln->smgr_owner = NULL;
233 
234  add_to_unowned_list(reln);
235 }
236 
237 /*
238  * add_to_unowned_list -- link an SMgrRelation onto the unowned list
239  *
240  * Check remove_from_unowned_list()'s comments for performance
241  * considerations.
242  */
243 static void
245 {
246  /* place it at head of the list (to make smgrsetowner cheap) */
248  first_unowned_reln = reln;
249 }
250 
251 /*
252  * remove_from_unowned_list -- unlink an SMgrRelation from the unowned list
253  *
254  * If the reln is not present in the list, nothing happens. Typically this
255  * would be caller error, but there seems no reason to throw an error.
256  *
257  * In the worst case this could be rather slow; but in all the cases that seem
258  * likely to be performance-critical, the reln being sought will actually be
259  * first in the list. Furthermore, the number of unowned relns touched in any
260  * one transaction shouldn't be all that high typically. So it doesn't seem
261  * worth expending the additional space and management logic needed for a
262  * doubly-linked list.
263  */
264 static void
266 {
269 
270  for (link = &first_unowned_reln, cur = *link;
271  cur != NULL;
272  link = &cur->next_unowned_reln, cur = *link)
273  {
274  if (cur == reln)
275  {
276  *link = cur->next_unowned_reln;
277  cur->next_unowned_reln = NULL;
278  break;
279  }
280  }
281 }
282 
283 /*
284  * smgrexists() -- Does the underlying file for a fork exist?
285  */
286 bool
288 {
289  return (*(smgrsw[reln->smgr_which].smgr_exists)) (reln, forknum);
290 }
291 
292 /*
293  * smgrclose() -- Close and delete an SMgrRelation object.
294  */
295 void
297 {
298  SMgrRelation *owner;
299  ForkNumber forknum;
300 
301  for (forknum = 0; forknum <= MAX_FORKNUM; forknum++)
302  (*(smgrsw[reln->smgr_which].smgr_close)) (reln, forknum);
303 
304  owner = reln->smgr_owner;
305 
306  if (!owner)
308 
309  if (hash_search(SMgrRelationHash,
310  (void *) &(reln->smgr_rnode),
311  HASH_REMOVE, NULL) == NULL)
312  elog(ERROR, "SMgrRelation hashtable corrupted");
313 
314  /*
315  * Unhook the owner pointer, if any. We do this last since in the remote
316  * possibility of failure above, the SMgrRelation object will still exist.
317  */
318  if (owner)
319  *owner = NULL;
320 }
321 
322 /*
323  * smgrcloseall() -- Close all existing SMgrRelation objects.
324  */
325 void
327 {
329  SMgrRelation reln;
330 
331  /* Nothing to do if hashtable not set up */
332  if (SMgrRelationHash == NULL)
333  return;
334 
335  hash_seq_init(&status, SMgrRelationHash);
336 
337  while ((reln = (SMgrRelation) hash_seq_search(&status)) != NULL)
338  smgrclose(reln);
339 }
340 
341 /*
342  * smgrclosenode() -- Close SMgrRelation object for given RelFileNode,
343  * if one exists.
344  *
345  * This has the same effects as smgrclose(smgropen(rnode)), but it avoids
346  * uselessly creating a hashtable entry only to drop it again when no
347  * such entry exists already.
348  */
349 void
351 {
352  SMgrRelation reln;
353 
354  /* Nothing to do if hashtable not set up */
355  if (SMgrRelationHash == NULL)
356  return;
357 
358  reln = (SMgrRelation) hash_search(SMgrRelationHash,
359  (void *) &rnode,
360  HASH_FIND, NULL);
361  if (reln != NULL)
362  smgrclose(reln);
363 }
364 
365 /*
366  * smgrcreate() -- Create a new relation.
367  *
368  * Given an already-created (but presumably unused) SMgrRelation,
369  * cause the underlying disk file or other storage for the fork
370  * to be created.
371  *
372  * If isRedo is true, it is okay for the underlying file to exist
373  * already because we are in a WAL replay sequence.
374  */
375 void
376 smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo)
377 {
378  /*
379  * Exit quickly in WAL replay mode if we've already opened the file. If
380  * it's open, it surely must exist.
381  */
382  if (isRedo && reln->md_num_open_segs[forknum] > 0)
383  return;
384 
385  /*
386  * We may be using the target table space for the first time in this
387  * database, so create a per-database subdirectory if needed.
388  *
389  * XXX this is a fairly ugly violation of module layering, but this seems
390  * to be the best place to put the check. Maybe TablespaceCreateDbspace
391  * should be here and not in commands/tablespace.c? But that would imply
392  * importing a lot of stuff that smgr.c oughtn't know, either.
393  */
395  reln->smgr_rnode.node.dbNode,
396  isRedo);
397 
398  (*(smgrsw[reln->smgr_which].smgr_create)) (reln, forknum, isRedo);
399 }
400 
401 /*
402  * smgrdounlink() -- Immediately unlink all forks of a relation.
403  *
404  * All forks of the relation are removed from the store. This should
405  * not be used during transactional operations, since it can't be undone.
406  *
407  * If isRedo is true, it is okay for the underlying file(s) to be gone
408  * already.
409  *
410  * This is equivalent to calling smgrdounlinkfork for each fork, but
411  * it's significantly quicker so should be preferred when possible.
412  */
413 void
414 smgrdounlink(SMgrRelation reln, bool isRedo)
415 {
416  RelFileNodeBackend rnode = reln->smgr_rnode;
417  int which = reln->smgr_which;
418  ForkNumber forknum;
419 
420  /* Close the forks at smgr level */
421  for (forknum = 0; forknum <= MAX_FORKNUM; forknum++)
422  (*(smgrsw[which].smgr_close)) (reln, forknum);
423 
424  /*
425  * Get rid of any remaining buffers for the relation. bufmgr will just
426  * drop them without bothering to write the contents.
427  */
428  DropRelFileNodesAllBuffers(&rnode, 1);
429 
430  /*
431  * It'd be nice to tell the stats collector to forget it immediately, too.
432  * But we can't because we don't know the OID (and in cases involving
433  * relfilenode swaps, it's not always clear which table OID to forget,
434  * anyway).
435  */
436 
437  /*
438  * Send a shared-inval message to force other backends to close any
439  * dangling smgr references they may have for this rel. We should do this
440  * before starting the actual unlinking, in case we fail partway through
441  * that step. Note that the sinval message will eventually come back to
442  * this backend, too, and thereby provide a backstop that we closed our
443  * own smgr rel.
444  */
445  CacheInvalidateSmgr(rnode);
446 
447  /*
448  * Delete the physical file(s).
449  *
450  * Note: smgr_unlink must treat deletion failure as a WARNING, not an
451  * ERROR, because we've already decided to commit or abort the current
452  * xact.
453  */
454  (*(smgrsw[which].smgr_unlink)) (rnode, InvalidForkNumber, isRedo);
455 }
456 
457 /*
458  * smgrdounlinkall() -- Immediately unlink all forks of all given relations
459  *
460  * All forks of all given relations are removed from the store. This
461  * should not be used during transactional operations, since it can't be
462  * undone.
463  *
464  * If isRedo is true, it is okay for the underlying file(s) to be gone
465  * already.
466  *
467  * This is equivalent to calling smgrdounlink for each relation, but it's
468  * significantly quicker so should be preferred when possible.
469  */
470 void
471 smgrdounlinkall(SMgrRelation *rels, int nrels, bool isRedo)
472 {
473  int i = 0;
474  RelFileNodeBackend *rnodes;
475  ForkNumber forknum;
476 
477  if (nrels == 0)
478  return;
479 
480  /*
481  * create an array which contains all relations to be dropped, and close
482  * each relation's forks at the smgr level while at it
483  */
484  rnodes = palloc(sizeof(RelFileNodeBackend) * nrels);
485  for (i = 0; i < nrels; i++)
486  {
487  RelFileNodeBackend rnode = rels[i]->smgr_rnode;
488  int which = rels[i]->smgr_which;
489 
490  rnodes[i] = rnode;
491 
492  /* Close the forks at smgr level */
493  for (forknum = 0; forknum <= MAX_FORKNUM; forknum++)
494  (*(smgrsw[which].smgr_close)) (rels[i], forknum);
495  }
496 
497  /*
498  * Get rid of any remaining buffers for the relations. bufmgr will just
499  * drop them without bothering to write the contents.
500  */
501  DropRelFileNodesAllBuffers(rnodes, nrels);
502 
503  /*
504  * It'd be nice to tell the stats collector to forget them immediately,
505  * too. But we can't because we don't know the OIDs.
506  */
507 
508  /*
509  * Send a shared-inval message to force other backends to close any
510  * dangling smgr references they may have for these rels. We should do
511  * this before starting the actual unlinking, in case we fail partway
512  * through that step. Note that the sinval messages will eventually come
513  * back to this backend, too, and thereby provide a backstop that we
514  * closed our own smgr rel.
515  */
516  for (i = 0; i < nrels; i++)
517  CacheInvalidateSmgr(rnodes[i]);
518 
519  /*
520  * Delete the physical file(s).
521  *
522  * Note: smgr_unlink must treat deletion failure as a WARNING, not an
523  * ERROR, because we've already decided to commit or abort the current
524  * xact.
525  */
526 
527  for (i = 0; i < nrels; i++)
528  {
529  int which = rels[i]->smgr_which;
530 
531  for (forknum = 0; forknum <= MAX_FORKNUM; forknum++)
532  (*(smgrsw[which].smgr_unlink)) (rnodes[i], forknum, isRedo);
533  }
534 
535  pfree(rnodes);
536 }
537 
538 /*
539  * smgrdounlinkfork() -- Immediately unlink one fork of a relation.
540  *
541  * The specified fork of the relation is removed from the store. This
542  * should not be used during transactional operations, since it can't be
543  * undone.
544  *
545  * If isRedo is true, it is okay for the underlying file to be gone
546  * already.
547  */
548 void
549 smgrdounlinkfork(SMgrRelation reln, ForkNumber forknum, bool isRedo)
550 {
551  RelFileNodeBackend rnode = reln->smgr_rnode;
552  int which = reln->smgr_which;
553 
554  /* Close the fork at smgr level */
555  (*(smgrsw[which].smgr_close)) (reln, forknum);
556 
557  /*
558  * Get rid of any remaining buffers for the fork. bufmgr will just drop
559  * them without bothering to write the contents.
560  */
561  DropRelFileNodeBuffers(rnode, forknum, 0);
562 
563  /*
564  * It'd be nice to tell the stats collector to forget it immediately, too.
565  * But we can't because we don't know the OID (and in cases involving
566  * relfilenode swaps, it's not always clear which table OID to forget,
567  * anyway).
568  */
569 
570  /*
571  * Send a shared-inval message to force other backends to close any
572  * dangling smgr references they may have for this rel. We should do this
573  * before starting the actual unlinking, in case we fail partway through
574  * that step. Note that the sinval message will eventually come back to
575  * this backend, too, and thereby provide a backstop that we closed our
576  * own smgr rel.
577  */
578  CacheInvalidateSmgr(rnode);
579 
580  /*
581  * Delete the physical file(s).
582  *
583  * Note: smgr_unlink must treat deletion failure as a WARNING, not an
584  * ERROR, because we've already decided to commit or abort the current
585  * xact.
586  */
587  (*(smgrsw[which].smgr_unlink)) (rnode, forknum, isRedo);
588 }
589 
590 /*
591  * smgrextend() -- Add a new block to a file.
592  *
593  * The semantics are nearly the same as smgrwrite(): write at the
594  * specified position. However, this is to be used for the case of
595  * extending a relation (i.e., blocknum is at or beyond the current
596  * EOF). Note that we assume writing a block beyond current EOF
597  * causes intervening file space to become filled with zeroes.
598  */
599 void
601  char *buffer, bool skipFsync)
602 {
603  (*(smgrsw[reln->smgr_which].smgr_extend)) (reln, forknum, blocknum,
604  buffer, skipFsync);
605 }
606 
607 /*
608  * smgrprefetch() -- Initiate asynchronous read of the specified block of a relation.
609  */
610 void
612 {
613  (*(smgrsw[reln->smgr_which].smgr_prefetch)) (reln, forknum, blocknum);
614 }
615 
616 /*
617  * smgrread() -- read a particular block from a relation into the supplied
618  * buffer.
619  *
620  * This routine is called from the buffer manager in order to
621  * instantiate pages in the shared buffer cache. All storage managers
622  * return pages in the format that POSTGRES expects.
623  */
624 void
625 smgrread(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
626  char *buffer)
627 {
628  (*(smgrsw[reln->smgr_which].smgr_read)) (reln, forknum, blocknum, buffer);
629 }
630 
631 /*
632  * smgrwrite() -- Write the supplied buffer out.
633  *
634  * This is to be used only for updating already-existing blocks of a
635  * relation (ie, those before the current EOF). To extend a relation,
636  * use smgrextend().
637  *
638  * This is not a synchronous write -- the block is not necessarily
639  * on disk at return, only dumped out to the kernel. However,
640  * provisions will be made to fsync the write before the next checkpoint.
641  *
642  * skipFsync indicates that the caller will make other provisions to
643  * fsync the relation, so we needn't bother. Temporary relations also
644  * do not require fsync.
645  */
646 void
648  char *buffer, bool skipFsync)
649 {
650  (*(smgrsw[reln->smgr_which].smgr_write)) (reln, forknum, blocknum,
651  buffer, skipFsync);
652 }
653 
654 
655 /*
656  * smgrwriteback() -- Trigger kernel writeback for the supplied range of
657  * blocks.
658  */
659 void
661  BlockNumber nblocks)
662 {
663  (*(smgrsw[reln->smgr_which].smgr_writeback)) (reln, forknum, blocknum,
664  nblocks);
665 }
666 
667 /*
668  * smgrnblocks() -- Calculate the number of blocks in the
669  * supplied relation.
670  */
673 {
674  return (*(smgrsw[reln->smgr_which].smgr_nblocks)) (reln, forknum);
675 }
676 
677 /*
678  * smgrtruncate() -- Truncate supplied relation to the specified number
679  * of blocks
680  *
681  * The truncation is done immediately, so this can't be rolled back.
682  */
683 void
685 {
686  /*
687  * Get rid of any buffers for the about-to-be-deleted blocks. bufmgr will
688  * just drop them without bothering to write the contents.
689  */
690  DropRelFileNodeBuffers(reln->smgr_rnode, forknum, nblocks);
691 
692  /*
693  * Send a shared-inval message to force other backends to close any smgr
694  * references they may have for this rel. This is useful because they
695  * might have open file pointers to segments that got removed, and/or
696  * smgr_targblock variables pointing past the new rel end. (The inval
697  * message will come back to our backend, too, causing a
698  * probably-unnecessary local smgr flush. But we don't expect that this
699  * is a performance-critical path.) As in the unlink code, we want to be
700  * sure the message is sent before we start changing things on-disk.
701  */
703 
704  /*
705  * Do the truncation.
706  */
707  (*(smgrsw[reln->smgr_which].smgr_truncate)) (reln, forknum, nblocks);
708 }
709 
710 /*
711  * smgrimmedsync() -- Force the specified relation to stable storage.
712  *
713  * Synchronously force all previous writes to the specified relation
714  * down to disk.
715  *
716  * This is useful for building completely new relations (eg, new
717  * indexes). Instead of incrementally WAL-logging the index build
718  * steps, we can just write completed index pages to disk with smgrwrite
719  * or smgrextend, and then fsync the completed index file before
720  * committing the transaction. (This is sufficient for purposes of
721  * crash recovery, since it effectively duplicates forcing a checkpoint
722  * for the completed index. But it is *not* sufficient if one wishes
723  * to use the WAL log for PITR or replication purposes: in that case
724  * we have to make WAL entries as well.)
725  *
726  * The preceding writes should specify skipFsync = true to avoid
727  * duplicative fsyncs.
728  *
729  * Note that you need to do FlushRelationBuffers() first if there is
730  * any possibility that there are dirty buffers for the relation;
731  * otherwise the sync is not very meaningful.
732  */
733 void
735 {
736  (*(smgrsw[reln->smgr_which].smgr_immedsync)) (reln, forknum);
737 }
738 
739 
740 /*
741  * smgrpreckpt() -- Prepare for checkpoint.
742  */
743 void
745 {
746  int i;
747 
748  for (i = 0; i < NSmgr; i++)
749  {
750  if (smgrsw[i].smgr_pre_ckpt)
751  (*(smgrsw[i].smgr_pre_ckpt)) ();
752  }
753 }
754 
755 /*
756  * smgrsync() -- Sync files to disk during checkpoint.
757  */
758 void
759 smgrsync(void)
760 {
761  int i;
762 
763  for (i = 0; i < NSmgr; i++)
764  {
765  if (smgrsw[i].smgr_sync)
766  (*(smgrsw[i].smgr_sync)) ();
767  }
768 }
769 
770 /*
771  * smgrpostckpt() -- Post-checkpoint cleanup.
772  */
773 void
775 {
776  int i;
777 
778  for (i = 0; i < NSmgr; i++)
779  {
780  if (smgrsw[i].smgr_post_ckpt)
781  (*(smgrsw[i].smgr_post_ckpt)) ();
782  }
783 }
784 
785 /*
786  * AtEOXact_SMgr
787  *
788  * This routine is called during transaction commit or abort (it doesn't
789  * particularly care which). All transient SMgrRelation objects are closed.
790  *
791  * We do this as a compromise between wanting transient SMgrRelations to
792  * live awhile (to amortize the costs of blind writes of multiple blocks)
793  * and needing them to not live forever (since we're probably holding open
794  * a kernel file descriptor for the underlying file, and we need to ensure
795  * that gets closed reasonably soon if the file gets deleted).
796  */
797 void
799 {
800  /*
801  * Zap all unowned SMgrRelations. We rely on smgrclose() to remove each
802  * one from the list.
803  */
804  while (first_unowned_reln != NULL)
805  {
806  Assert(first_unowned_reln->smgr_owner == NULL);
807  smgrclose(first_unowned_reln);
808  }
809 }
void CacheInvalidateSmgr(RelFileNodeBackend rnode)
Definition: inval.c:1324
struct SMgrRelationData SMgrRelationData
BlockNumber smgr_vm_nblocks
Definition: smgr.h:57
void mdimmedsync(SMgrRelation reln, ForkNumber forknum)
Definition: md.c:1024
void(* smgr_init)(void)
Definition: smgr.c:40
void smgrclose(SMgrRelation reln)
Definition: smgr.c:296
void smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo)
Definition: smgr.c:376
void smgrclearowner(SMgrRelation *owner, SMgrRelation reln)
Definition: smgr.c:222
void(* smgr_unlink)(RelFileNodeBackend rnode, ForkNumber forknum, bool isRedo)
Definition: smgr.c:46
#define HASH_ELEM
Definition: hsearch.h:87
SMgrRelationData * SMgrRelation
Definition: smgr.h:78
void on_proc_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:292
BlockNumber mdnblocks(SMgrRelation reln, ForkNumber forknum)
Definition: md.c:872
struct f_smgr f_smgr
void mdsync(void)
Definition: md.c:1053
static const f_smgr smgrsw[]
Definition: smgr.c:68
void DropRelFileNodeBuffers(RelFileNodeBackend rnode, ForkNumber forkNum, BlockNumber firstDelBlock)
Definition: bufmgr.c:2866
static void smgrshutdown(int code, Datum arg)
Definition: smgr.c:120
void smgrdounlink(SMgrRelation reln, bool isRedo)
Definition: smgr.c:414
Size entrysize
Definition: hsearch.h:73
void smgrtruncate(SMgrRelation reln, ForkNumber forknum, BlockNumber nblocks)
Definition: smgr.c:684
static void remove_from_unowned_list(SMgrRelation reln)
Definition: smgr.c:265
struct cursor * cur
Definition: ecpg.c:28
void(* smgr_immedsync)(SMgrRelation reln, ForkNumber forknum)
Definition: smgr.c:61
static HTAB * SMgrRelationHash
Definition: smgr.c:83
void smgrdounlinkall(SMgrRelation *rels, int nrels, bool isRedo)
Definition: smgr.c:471
#define MemSet(start, val, len)
Definition: c.h:853
uint32 BlockNumber
Definition: block.h:31
BlockNumber smgr_fsm_nblocks
Definition: smgr.h:56
bool smgrexists(SMgrRelation reln, ForkNumber forknum)
Definition: smgr.c:287
#define lengthof(array)
Definition: c.h:558
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:885
void mdinit(void)
Definition: md.c:205
void mdpreckpt(void)
Definition: md.c:1345
void(* smgr_write)(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char *buffer, bool skipFsync)
Definition: smgr.c:54
char bool
Definition: c.h:199
void mdextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char *buffer, bool skipFsync)
Definition: md.c:494
void smgrcloseall(void)
Definition: smgr.c:326
void smgrread(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char *buffer)
Definition: smgr.c:625
Definition: dynahash.c:193
void AtEOXact_SMgr(void)
Definition: smgr.c:798
void pfree(void *pointer)
Definition: mcxt.c:992
void(* smgr_pre_ckpt)(void)
Definition: smgr.c:62
#define ERROR
Definition: elog.h:43
static const int NSmgr
Definition: smgr.c:76
void(* smgr_truncate)(SMgrRelation reln, ForkNumber forknum, BlockNumber nblocks)
Definition: smgr.c:59
void(* smgr_prefetch)(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum)
Definition: smgr.c:50
void(* smgr_sync)(void)
Definition: smgr.c:63
RelFileNodeBackend smgr_rnode
Definition: smgr.h:43
void mdunlink(RelFileNodeBackend rnode, ForkNumber forkNum, bool isRedo)
Definition: md.c:386
void smgrwrite(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char *buffer, bool skipFsync)
Definition: smgr.c:647
void(* smgr_extend)(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char *buffer, bool skipFsync)
Definition: smgr.c:48
void(* smgr_post_ckpt)(void)
Definition: smgr.c:64
void mdwriteback(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, BlockNumber nblocks)
Definition: md.c:681
void smgrwriteback(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, BlockNumber nblocks)
Definition: smgr.c:660
void smgrclosenode(RelFileNodeBackend rnode)
Definition: smgr.c:350
bool(* smgr_exists)(SMgrRelation reln, ForkNumber forknum)
Definition: smgr.c:45
static void add_to_unowned_list(SMgrRelation reln)
Definition: smgr.c:244
int link(const char *fromname, const char *toname)
SMgrRelation smgropen(RelFileNode rnode, BackendId backend)
Definition: smgr.c:137
ForkNumber
Definition: relpath.h:24
struct SMgrRelationData * next_unowned_reln
Definition: smgr.h:75
Definition: smgr.c:38
struct SMgrRelationData ** smgr_owner
Definition: smgr.h:46
#define HASH_BLOBS
Definition: hsearch.h:88
void smgrinit(void)
Definition: smgr.c:102
void smgrdounlinkfork(SMgrRelation reln, ForkNumber forknum, bool isRedo)
Definition: smgr.c:549
void DropRelFileNodesAllBuffers(RelFileNodeBackend *rnodes, int nnodes)
Definition: bufmgr.c:2923
HTAB * hash_create(const char *tabname, long nelem, HASHCTL *info, int flags)
Definition: dynahash.c:301
uintptr_t Datum
Definition: postgres.h:374
int smgr_which
Definition: smgr.h:65
int BackendId
Definition: backendid.h:21
struct RelFileNodeBackend RelFileNodeBackend
Size keysize
Definition: hsearch.h:72
void(* smgr_read)(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char *buffer)
Definition: smgr.c:52
void(* smgr_close)(SMgrRelation reln, ForkNumber forknum)
Definition: smgr.c:42
void mdtruncate(SMgrRelation reln, ForkNumber forknum, BlockNumber nblocks)
Definition: md.c:927
bool mdexists(SMgrRelation reln, ForkNumber forkNum)
Definition: md.c:276
RelFileNode node
Definition: relfilenode.h:74
void smgrpreckpt(void)
Definition: smgr.c:744
BlockNumber(* smgr_nblocks)(SMgrRelation reln, ForkNumber forknum)
Definition: smgr.c:58
BlockNumber smgrnblocks(SMgrRelation reln, ForkNumber forknum)
Definition: smgr.c:672
#define NULL
Definition: c.h:226
void mdwrite(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char *buffer, bool skipFsync)
Definition: md.c:801
#define Assert(condition)
Definition: c.h:671
void smgrsetowner(SMgrRelation *owner, SMgrRelation reln)
Definition: smgr.c:193
BlockNumber smgr_targblock
Definition: smgr.h:55
void TablespaceCreateDbspace(Oid spcNode, Oid dbNode, bool isRedo)
Definition: tablespace.c:115
void mdprefetch(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum)
Definition: md.c:658
BackendId backend
Definition: relfilenode.h:75
void(* smgr_create)(SMgrRelation reln, ForkNumber forknum, bool isRedo)
Definition: smgr.c:43
#define InvalidBlockNumber
Definition: block.h:33
#define MAX_FORKNUM
Definition: relpath.h:39
void * hash_seq_search(HASH_SEQ_STATUS *status)
Definition: dynahash.c:1353
void smgrsync(void)
Definition: smgr.c:759
void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)
Definition: dynahash.c:1343
void mdclose(SMgrRelation reln, ForkNumber forknum)
Definition: md.c:627
void smgrextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char *buffer, bool skipFsync)
Definition: smgr.c:600
void(* smgr_shutdown)(void)
Definition: smgr.c:41
void mdpostckpt(void)
Definition: md.c:1360
int md_num_open_segs[MAX_FORKNUM+1]
Definition: smgr.h:71
void * palloc(Size size)
Definition: mcxt.c:891
int i
void mdcreate(SMgrRelation reln, ForkNumber forkNum, bool isRedo)
Definition: md.c:293
void smgrprefetch(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum)
Definition: smgr.c:611
void * arg
#define elog
Definition: elog.h:219
static SMgrRelation first_unowned_reln
Definition: smgr.c:85
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:222
void smgrimmedsync(SMgrRelation reln, ForkNumber forknum)
Definition: smgr.c:734
void smgrpostckpt(void)
Definition: smgr.c:774
void(* smgr_writeback)(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, BlockNumber nblocks)
Definition: smgr.c:56
void mdread(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char *buffer)
Definition: md.c:730