OSDN Git Service

8.4 pgindent run, with new combined Linux/FreeBSD/MinGW typedef list
[pg-rex/syncrep.git] / src / backend / storage / smgr / smgr.c
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-2009, PostgreSQL Global Development Group
10  * Portions Copyright (c) 1994, Regents of the University of California
11  *
12  *
13  * IDENTIFICATION
14  *        $PostgreSQL: pgsql/src/backend/storage/smgr/smgr.c,v 1.117 2009/06/11 14:49:02 momjian Exp $
15  *
16  *-------------------------------------------------------------------------
17  */
18 #include "postgres.h"
19
20 #include "access/xlogutils.h"
21 #include "catalog/catalog.h"
22 #include "commands/tablespace.h"
23 #include "storage/bufmgr.h"
24 #include "storage/ipc.h"
25 #include "storage/smgr.h"
26 #include "utils/hsearch.h"
27
28
29 /*
30  * This struct of function pointers defines the API between smgr.c and
31  * any individual storage manager module.  Note that smgr subfunctions are
32  * generally expected to report problems via elog(ERROR).  An exception is
33  * that smgr_unlink should use elog(WARNING), rather than erroring out,
34  * because we normally unlink relations during post-commit/abort cleanup,
35  * and so it's too late to raise an error.  Also, various conditions that
36  * would normally be errors should be allowed during bootstrap and/or WAL
37  * recovery --- see comments in md.c for details.
38  */
39 typedef struct f_smgr
40 {
41         void            (*smgr_init) (void);    /* may be NULL */
42         void            (*smgr_shutdown) (void);                /* may be NULL */
43         void            (*smgr_close) (SMgrRelation reln, ForkNumber forknum);
44         void            (*smgr_create) (SMgrRelation reln, ForkNumber forknum,
45                                                                                         bool isRedo);
46         bool            (*smgr_exists) (SMgrRelation reln, ForkNumber forknum);
47         void            (*smgr_unlink) (RelFileNode rnode, ForkNumber forknum,
48                                                                                         bool isRedo);
49         void            (*smgr_extend) (SMgrRelation reln, ForkNumber forknum,
50                                                         BlockNumber blocknum, char *buffer, bool isTemp);
51         void            (*smgr_prefetch) (SMgrRelation reln, ForkNumber forknum,
52                                                                                           BlockNumber blocknum);
53         void            (*smgr_read) (SMgrRelation reln, ForkNumber forknum,
54                                                                                   BlockNumber blocknum, char *buffer);
55         void            (*smgr_write) (SMgrRelation reln, ForkNumber forknum,
56                                                         BlockNumber blocknum, char *buffer, bool isTemp);
57         BlockNumber (*smgr_nblocks) (SMgrRelation reln, ForkNumber forknum);
58         void            (*smgr_truncate) (SMgrRelation reln, ForkNumber forknum,
59                                                                                    BlockNumber nblocks, bool isTemp);
60         void            (*smgr_immedsync) (SMgrRelation reln, ForkNumber forknum);
61         void            (*smgr_pre_ckpt) (void);                /* may be NULL */
62         void            (*smgr_sync) (void);    /* may be NULL */
63         void            (*smgr_post_ckpt) (void);               /* may be NULL */
64 } f_smgr;
65
66
67 static const f_smgr smgrsw[] = {
68         /* magnetic disk */
69         {mdinit, NULL, mdclose, mdcreate, mdexists, mdunlink, mdextend,
70                 mdprefetch, mdread, mdwrite, mdnblocks, mdtruncate, mdimmedsync,
71                 mdpreckpt, mdsync, mdpostckpt
72         }
73 };
74
75 static const int NSmgr = lengthof(smgrsw);
76
77
78 /*
79  * Each backend has a hashtable that stores all extant SMgrRelation objects.
80  */
81 static HTAB *SMgrRelationHash = NULL;
82
83 /* local function prototypes */
84 static void smgrshutdown(int code, Datum arg);
85 static void smgr_internal_unlink(RelFileNode rnode, ForkNumber forknum,
86                                          int which, bool isTemp, bool isRedo);
87
88
89 /*
90  *      smgrinit(), smgrshutdown() -- Initialize or shut down storage
91  *                                                                managers.
92  *
93  * Note: smgrinit is called during backend startup (normal or standalone
94  * case), *not* during postmaster start.  Therefore, any resources created
95  * here or destroyed in smgrshutdown are backend-local.
96  */
97 void
98 smgrinit(void)
99 {
100         int                     i;
101
102         for (i = 0; i < NSmgr; i++)
103         {
104                 if (smgrsw[i].smgr_init)
105                         (*(smgrsw[i].smgr_init)) ();
106         }
107
108         /* register the shutdown proc */
109         on_proc_exit(smgrshutdown, 0);
110 }
111
112 /*
113  * on_proc_exit hook for smgr cleanup during backend shutdown
114  */
115 static void
116 smgrshutdown(int code, Datum arg)
117 {
118         int                     i;
119
120         for (i = 0; i < NSmgr; i++)
121         {
122                 if (smgrsw[i].smgr_shutdown)
123                         (*(smgrsw[i].smgr_shutdown)) ();
124         }
125 }
126
127 /*
128  *      smgropen() -- Return an SMgrRelation object, creating it if need be.
129  *
130  *              This does not attempt to actually open the object.
131  */
132 SMgrRelation
133 smgropen(RelFileNode rnode)
134 {
135         SMgrRelation reln;
136         bool            found;
137
138         if (SMgrRelationHash == NULL)
139         {
140                 /* First time through: initialize the hash table */
141                 HASHCTL         ctl;
142
143                 MemSet(&ctl, 0, sizeof(ctl));
144                 ctl.keysize = sizeof(RelFileNode);
145                 ctl.entrysize = sizeof(SMgrRelationData);
146                 ctl.hash = tag_hash;
147                 SMgrRelationHash = hash_create("smgr relation table", 400,
148                                                                            &ctl, HASH_ELEM | HASH_FUNCTION);
149         }
150
151         /* Look up or create an entry */
152         reln = (SMgrRelation) hash_search(SMgrRelationHash,
153                                                                           (void *) &rnode,
154                                                                           HASH_ENTER, &found);
155
156         /* Initialize it if not present before */
157         if (!found)
158         {
159                 int                     forknum;
160
161                 /* hash_search already filled in the lookup key */
162                 reln->smgr_owner = NULL;
163                 reln->smgr_which = 0;   /* we only have md.c at present */
164
165                 /* mark it not open */
166                 for (forknum = 0; forknum <= MAX_FORKNUM; forknum++)
167                         reln->md_fd[forknum] = NULL;
168         }
169
170         return reln;
171 }
172
173 /*
174  * smgrsetowner() -- Establish a long-lived reference to an SMgrRelation object
175  *
176  * There can be only one owner at a time; this is sufficient since currently
177  * the only such owners exist in the relcache.
178  */
179 void
180 smgrsetowner(SMgrRelation *owner, SMgrRelation reln)
181 {
182         /*
183          * First, unhook any old owner.  (Normally there shouldn't be any, but it
184          * seems possible that this can happen during swap_relation_files()
185          * depending on the order of processing.  It's ok to close the old
186          * relcache entry early in that case.)
187          */
188         if (reln->smgr_owner)
189                 *(reln->smgr_owner) = NULL;
190
191         /* Now establish the ownership relationship. */
192         reln->smgr_owner = owner;
193         *owner = reln;
194 }
195
196 /*
197  *      smgrexists() -- Does the underlying file for a fork exist?
198  */
199 bool
200 smgrexists(SMgrRelation reln, ForkNumber forknum)
201 {
202         return (*(smgrsw[reln->smgr_which].smgr_exists)) (reln, forknum);
203 }
204
205 /*
206  *      smgrclose() -- Close and delete an SMgrRelation object.
207  */
208 void
209 smgrclose(SMgrRelation reln)
210 {
211         SMgrRelation *owner;
212         ForkNumber      forknum;
213
214         for (forknum = 0; forknum <= MAX_FORKNUM; forknum++)
215                 (*(smgrsw[reln->smgr_which].smgr_close)) (reln, forknum);
216
217         owner = reln->smgr_owner;
218
219         if (hash_search(SMgrRelationHash,
220                                         (void *) &(reln->smgr_rnode),
221                                         HASH_REMOVE, NULL) == NULL)
222                 elog(ERROR, "SMgrRelation hashtable corrupted");
223
224         /*
225          * Unhook the owner pointer, if any.  We do this last since in the remote
226          * possibility of failure above, the SMgrRelation object will still exist.
227          */
228         if (owner)
229                 *owner = NULL;
230 }
231
232 /*
233  *      smgrcloseall() -- Close all existing SMgrRelation objects.
234  */
235 void
236 smgrcloseall(void)
237 {
238         HASH_SEQ_STATUS status;
239         SMgrRelation reln;
240
241         /* Nothing to do if hashtable not set up */
242         if (SMgrRelationHash == NULL)
243                 return;
244
245         hash_seq_init(&status, SMgrRelationHash);
246
247         while ((reln = (SMgrRelation) hash_seq_search(&status)) != NULL)
248                 smgrclose(reln);
249 }
250
251 /*
252  *      smgrclosenode() -- Close SMgrRelation object for given RelFileNode,
253  *                                         if one exists.
254  *
255  * This has the same effects as smgrclose(smgropen(rnode)), but it avoids
256  * uselessly creating a hashtable entry only to drop it again when no
257  * such entry exists already.
258  */
259 void
260 smgrclosenode(RelFileNode rnode)
261 {
262         SMgrRelation reln;
263
264         /* Nothing to do if hashtable not set up */
265         if (SMgrRelationHash == NULL)
266                 return;
267
268         reln = (SMgrRelation) hash_search(SMgrRelationHash,
269                                                                           (void *) &rnode,
270                                                                           HASH_FIND, NULL);
271         if (reln != NULL)
272                 smgrclose(reln);
273 }
274
275 /*
276  *      smgrcreate() -- Create a new relation.
277  *
278  *              Given an already-created (but presumably unused) SMgrRelation,
279  *              cause the underlying disk file or other storage for the fork
280  *              to be created.
281  *
282  *              If isRedo is true, it is okay for the underlying file to exist
283  *              already because we are in a WAL replay sequence.
284  */
285 void
286 smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo)
287 {
288         /*
289          * Exit quickly in WAL replay mode if we've already opened the file. If
290          * it's open, it surely must exist.
291          */
292         if (isRedo && reln->md_fd[forknum] != NULL)
293                 return;
294
295         /*
296          * We may be using the target table space for the first time in this
297          * database, so create a per-database subdirectory if needed.
298          *
299          * XXX this is a fairly ugly violation of module layering, but this seems
300          * to be the best place to put the check.  Maybe TablespaceCreateDbspace
301          * should be here and not in commands/tablespace.c?  But that would imply
302          * importing a lot of stuff that smgr.c oughtn't know, either.
303          */
304         TablespaceCreateDbspace(reln->smgr_rnode.spcNode,
305                                                         reln->smgr_rnode.dbNode,
306                                                         isRedo);
307
308         (*(smgrsw[reln->smgr_which].smgr_create)) (reln, forknum, isRedo);
309 }
310
311 /*
312  *      smgrdounlink() -- Immediately unlink a relation.
313  *
314  *              The specified fork of the relation is removed from the store.  This
315  *              should not be used during transactional operations, since it can't be
316  *              undone.
317  *
318  *              If isRedo is true, it is okay for the underlying file to be gone
319  *              already.
320  */
321 void
322 smgrdounlink(SMgrRelation reln, ForkNumber forknum, bool isTemp, bool isRedo)
323 {
324         RelFileNode rnode = reln->smgr_rnode;
325         int                     which = reln->smgr_which;
326
327         /* Close the fork */
328         (*(smgrsw[which].smgr_close)) (reln, forknum);
329
330         smgr_internal_unlink(rnode, forknum, which, isTemp, isRedo);
331 }
332
333 /*
334  * Shared subroutine that actually does the unlink ...
335  */
336 static void
337 smgr_internal_unlink(RelFileNode rnode, ForkNumber forknum,
338                                          int which, bool isTemp, bool isRedo)
339 {
340         /*
341          * Get rid of any remaining buffers for the relation.  bufmgr will just
342          * drop them without bothering to write the contents.
343          */
344         DropRelFileNodeBuffers(rnode, forknum, isTemp, 0);
345
346         /*
347          * It'd be nice to tell the stats collector to forget it immediately, too.
348          * But we can't because we don't know the OID (and in cases involving
349          * relfilenode swaps, it's not always clear which table OID to forget,
350          * anyway).
351          */
352
353         /*
354          * And delete the physical files.
355          *
356          * Note: smgr_unlink must treat deletion failure as a WARNING, not an
357          * ERROR, because we've already decided to commit or abort the current
358          * xact.
359          */
360         (*(smgrsw[which].smgr_unlink)) (rnode, forknum, isRedo);
361 }
362
363 /*
364  *      smgrextend() -- Add a new block to a file.
365  *
366  *              The semantics are nearly the same as smgrwrite(): write at the
367  *              specified position.  However, this is to be used for the case of
368  *              extending a relation (i.e., blocknum is at or beyond the current
369  *              EOF).  Note that we assume writing a block beyond current EOF
370  *              causes intervening file space to become filled with zeroes.
371  */
372 void
373 smgrextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
374                    char *buffer, bool isTemp)
375 {
376         (*(smgrsw[reln->smgr_which].smgr_extend)) (reln, forknum, blocknum,
377                                                                                            buffer, isTemp);
378 }
379
380 /*
381  *      smgrprefetch() -- Initiate asynchronous read of the specified block of a relation.
382  */
383 void
384 smgrprefetch(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum)
385 {
386         (*(smgrsw[reln->smgr_which].smgr_prefetch)) (reln, forknum, blocknum);
387 }
388
389 /*
390  *      smgrread() -- read a particular block from a relation into the supplied
391  *                                buffer.
392  *
393  *              This routine is called from the buffer manager in order to
394  *              instantiate pages in the shared buffer cache.  All storage managers
395  *              return pages in the format that POSTGRES expects.
396  */
397 void
398 smgrread(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
399                  char *buffer)
400 {
401         (*(smgrsw[reln->smgr_which].smgr_read)) (reln, forknum, blocknum, buffer);
402 }
403
404 /*
405  *      smgrwrite() -- Write the supplied buffer out.
406  *
407  *              This is to be used only for updating already-existing blocks of a
408  *              relation (ie, those before the current EOF).  To extend a relation,
409  *              use smgrextend().
410  *
411  *              This is not a synchronous write -- the block is not necessarily
412  *              on disk at return, only dumped out to the kernel.  However,
413  *              provisions will be made to fsync the write before the next checkpoint.
414  *
415  *              isTemp indicates that the relation is a temp table (ie, is managed
416  *              by the local-buffer manager).  In this case no provisions need be
417  *              made to fsync the write before checkpointing.
418  */
419 void
420 smgrwrite(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
421                   char *buffer, bool isTemp)
422 {
423         (*(smgrsw[reln->smgr_which].smgr_write)) (reln, forknum, blocknum,
424                                                                                           buffer, isTemp);
425 }
426
427 /*
428  *      smgrnblocks() -- Calculate the number of blocks in the
429  *                                       supplied relation.
430  */
431 BlockNumber
432 smgrnblocks(SMgrRelation reln, ForkNumber forknum)
433 {
434         return (*(smgrsw[reln->smgr_which].smgr_nblocks)) (reln, forknum);
435 }
436
437 /*
438  *      smgrtruncate() -- Truncate supplied relation to the specified number
439  *                                        of blocks
440  */
441 void
442 smgrtruncate(SMgrRelation reln, ForkNumber forknum, BlockNumber nblocks,
443                          bool isTemp)
444 {
445         /*
446          * Get rid of any buffers for the about-to-be-deleted blocks. bufmgr will
447          * just drop them without bothering to write the contents.
448          */
449         DropRelFileNodeBuffers(reln->smgr_rnode, forknum, isTemp, nblocks);
450
451         /* Do the truncation */
452         (*(smgrsw[reln->smgr_which].smgr_truncate)) (reln, forknum, nblocks,
453                                                                                                  isTemp);
454 }
455
456 /*
457  *      smgrimmedsync() -- Force the specified relation to stable storage.
458  *
459  *              Synchronously force all previous writes to the specified relation
460  *              down to disk.
461  *
462  *              This is useful for building completely new relations (eg, new
463  *              indexes).  Instead of incrementally WAL-logging the index build
464  *              steps, we can just write completed index pages to disk with smgrwrite
465  *              or smgrextend, and then fsync the completed index file before
466  *              committing the transaction.  (This is sufficient for purposes of
467  *              crash recovery, since it effectively duplicates forcing a checkpoint
468  *              for the completed index.  But it is *not* sufficient if one wishes
469  *              to use the WAL log for PITR or replication purposes: in that case
470  *              we have to make WAL entries as well.)
471  *
472  *              The preceding writes should specify isTemp = true to avoid
473  *              duplicative fsyncs.
474  *
475  *              Note that you need to do FlushRelationBuffers() first if there is
476  *              any possibility that there are dirty buffers for the relation;
477  *              otherwise the sync is not very meaningful.
478  */
479 void
480 smgrimmedsync(SMgrRelation reln, ForkNumber forknum)
481 {
482         (*(smgrsw[reln->smgr_which].smgr_immedsync)) (reln, forknum);
483 }
484
485
486 /*
487  *      smgrpreckpt() -- Prepare for checkpoint.
488  */
489 void
490 smgrpreckpt(void)
491 {
492         int                     i;
493
494         for (i = 0; i < NSmgr; i++)
495         {
496                 if (smgrsw[i].smgr_pre_ckpt)
497                         (*(smgrsw[i].smgr_pre_ckpt)) ();
498         }
499 }
500
501 /*
502  *      smgrsync() -- Sync files to disk during checkpoint.
503  */
504 void
505 smgrsync(void)
506 {
507         int                     i;
508
509         for (i = 0; i < NSmgr; i++)
510         {
511                 if (smgrsw[i].smgr_sync)
512                         (*(smgrsw[i].smgr_sync)) ();
513         }
514 }
515
516 /*
517  *      smgrpostckpt() -- Post-checkpoint cleanup.
518  */
519 void
520 smgrpostckpt(void)
521 {
522         int                     i;
523
524         for (i = 0; i < NSmgr; i++)
525         {
526                 if (smgrsw[i].smgr_post_ckpt)
527                         (*(smgrsw[i].smgr_post_ckpt)) ();
528         }
529 }