00001 /*------------------------------------------------------------------------- 00002 * 00003 * smgr.c 00004 * public interface routines to storage manager switch. 00005 * 00006 * All file system operations in POSTGRES dispatch through these 00007 * routines. 00008 * 00009 * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group 00010 * Portions Copyright (c) 1994, Regents of the University of California 00011 * 00012 * 00013 * IDENTIFICATION 00014 * src/backend/storage/smgr/smgr.c 00015 * 00016 *------------------------------------------------------------------------- 00017 */ 00018 #include "postgres.h" 00019 00020 #include "commands/tablespace.h" 00021 #include "storage/bufmgr.h" 00022 #include "storage/ipc.h" 00023 #include "storage/smgr.h" 00024 #include "utils/hsearch.h" 00025 #include "utils/inval.h" 00026 00027 00028 /* 00029 * This struct of function pointers defines the API between smgr.c and 00030 * any individual storage manager module. Note that smgr subfunctions are 00031 * generally expected to report problems via elog(ERROR). An exception is 00032 * that smgr_unlink should use elog(WARNING), rather than erroring out, 00033 * because we normally unlink relations during post-commit/abort cleanup, 00034 * and so it's too late to raise an error. Also, various conditions that 00035 * would normally be errors should be allowed during bootstrap and/or WAL 00036 * recovery --- see comments in md.c for details. 00037 */ 00038 typedef struct f_smgr 00039 { 00040 void (*smgr_init) (void); /* may be NULL */ 00041 void (*smgr_shutdown) (void); /* may be NULL */ 00042 void (*smgr_close) (SMgrRelation reln, ForkNumber forknum); 00043 void (*smgr_create) (SMgrRelation reln, ForkNumber forknum, 00044 bool isRedo); 00045 bool (*smgr_exists) (SMgrRelation reln, ForkNumber forknum); 00046 void (*smgr_unlink) (RelFileNodeBackend rnode, ForkNumber forknum, 00047 bool isRedo); 00048 void (*smgr_extend) (SMgrRelation reln, ForkNumber forknum, 00049 BlockNumber blocknum, char *buffer, bool skipFsync); 00050 void (*smgr_prefetch) (SMgrRelation reln, ForkNumber forknum, 00051 BlockNumber blocknum); 00052 void (*smgr_read) (SMgrRelation reln, ForkNumber forknum, 00053 BlockNumber blocknum, char *buffer); 00054 void (*smgr_write) (SMgrRelation reln, ForkNumber forknum, 00055 BlockNumber blocknum, char *buffer, bool skipFsync); 00056 BlockNumber (*smgr_nblocks) (SMgrRelation reln, ForkNumber forknum); 00057 void (*smgr_truncate) (SMgrRelation reln, ForkNumber forknum, 00058 BlockNumber nblocks); 00059 void (*smgr_immedsync) (SMgrRelation reln, ForkNumber forknum); 00060 void (*smgr_pre_ckpt) (void); /* may be NULL */ 00061 void (*smgr_sync) (void); /* may be NULL */ 00062 void (*smgr_post_ckpt) (void); /* may be NULL */ 00063 } f_smgr; 00064 00065 00066 static const f_smgr smgrsw[] = { 00067 /* magnetic disk */ 00068 {mdinit, NULL, mdclose, mdcreate, mdexists, mdunlink, mdextend, 00069 mdprefetch, mdread, mdwrite, mdnblocks, mdtruncate, mdimmedsync, 00070 mdpreckpt, mdsync, mdpostckpt 00071 } 00072 }; 00073 00074 static const int NSmgr = lengthof(smgrsw); 00075 00076 00077 /* 00078 * Each backend has a hashtable that stores all extant SMgrRelation objects. 00079 * In addition, "unowned" SMgrRelation objects are chained together in a list. 00080 */ 00081 static HTAB *SMgrRelationHash = NULL; 00082 00083 static SMgrRelation first_unowned_reln = NULL; 00084 00085 /* local function prototypes */ 00086 static void smgrshutdown(int code, Datum arg); 00087 static void remove_from_unowned_list(SMgrRelation reln); 00088 00089 00090 /* 00091 * smgrinit(), smgrshutdown() -- Initialize or shut down storage 00092 * managers. 00093 * 00094 * Note: smgrinit is called during backend startup (normal or standalone 00095 * case), *not* during postmaster start. Therefore, any resources created 00096 * here or destroyed in smgrshutdown are backend-local. 00097 */ 00098 void 00099 smgrinit(void) 00100 { 00101 int i; 00102 00103 for (i = 0; i < NSmgr; i++) 00104 { 00105 if (smgrsw[i].smgr_init) 00106 (*(smgrsw[i].smgr_init)) (); 00107 } 00108 00109 /* register the shutdown proc */ 00110 on_proc_exit(smgrshutdown, 0); 00111 } 00112 00113 /* 00114 * on_proc_exit hook for smgr cleanup during backend shutdown 00115 */ 00116 static void 00117 smgrshutdown(int code, Datum arg) 00118 { 00119 int i; 00120 00121 for (i = 0; i < NSmgr; i++) 00122 { 00123 if (smgrsw[i].smgr_shutdown) 00124 (*(smgrsw[i].smgr_shutdown)) (); 00125 } 00126 } 00127 00128 /* 00129 * smgropen() -- Return an SMgrRelation object, creating it if need be. 00130 * 00131 * This does not attempt to actually open the underlying file. 00132 */ 00133 SMgrRelation 00134 smgropen(RelFileNode rnode, BackendId backend) 00135 { 00136 RelFileNodeBackend brnode; 00137 SMgrRelation reln; 00138 bool found; 00139 00140 if (SMgrRelationHash == NULL) 00141 { 00142 /* First time through: initialize the hash table */ 00143 HASHCTL ctl; 00144 00145 MemSet(&ctl, 0, sizeof(ctl)); 00146 ctl.keysize = sizeof(RelFileNodeBackend); 00147 ctl.entrysize = sizeof(SMgrRelationData); 00148 ctl.hash = tag_hash; 00149 SMgrRelationHash = hash_create("smgr relation table", 400, 00150 &ctl, HASH_ELEM | HASH_FUNCTION); 00151 first_unowned_reln = NULL; 00152 } 00153 00154 /* Look up or create an entry */ 00155 brnode.node = rnode; 00156 brnode.backend = backend; 00157 reln = (SMgrRelation) hash_search(SMgrRelationHash, 00158 (void *) &brnode, 00159 HASH_ENTER, &found); 00160 00161 /* Initialize it if not present before */ 00162 if (!found) 00163 { 00164 int forknum; 00165 00166 /* hash_search already filled in the lookup key */ 00167 reln->smgr_owner = NULL; 00168 reln->smgr_targblock = InvalidBlockNumber; 00169 reln->smgr_fsm_nblocks = InvalidBlockNumber; 00170 reln->smgr_vm_nblocks = InvalidBlockNumber; 00171 reln->smgr_which = 0; /* we only have md.c at present */ 00172 00173 /* mark it not open */ 00174 for (forknum = 0; forknum <= MAX_FORKNUM; forknum++) 00175 reln->md_fd[forknum] = NULL; 00176 00177 /* place it at head of unowned list (to make smgrsetowner cheap) */ 00178 reln->next_unowned_reln = first_unowned_reln; 00179 first_unowned_reln = reln; 00180 } 00181 00182 return reln; 00183 } 00184 00185 /* 00186 * smgrsetowner() -- Establish a long-lived reference to an SMgrRelation object 00187 * 00188 * There can be only one owner at a time; this is sufficient since currently 00189 * the only such owners exist in the relcache. 00190 */ 00191 void 00192 smgrsetowner(SMgrRelation *owner, SMgrRelation reln) 00193 { 00194 /* We don't currently support "disowning" an SMgrRelation here */ 00195 Assert(owner != NULL); 00196 00197 /* 00198 * First, unhook any old owner. (Normally there shouldn't be any, but it 00199 * seems possible that this can happen during swap_relation_files() 00200 * depending on the order of processing. It's ok to close the old 00201 * relcache entry early in that case.) 00202 * 00203 * If there isn't an old owner, then the reln should be in the unowned 00204 * list, and we need to remove it. 00205 */ 00206 if (reln->smgr_owner) 00207 *(reln->smgr_owner) = NULL; 00208 else 00209 remove_from_unowned_list(reln); 00210 00211 /* Now establish the ownership relationship. */ 00212 reln->smgr_owner = owner; 00213 *owner = reln; 00214 } 00215 00216 /* 00217 * remove_from_unowned_list -- unlink an SMgrRelation from the unowned list 00218 * 00219 * If the reln is not present in the list, nothing happens. Typically this 00220 * would be caller error, but there seems no reason to throw an error. 00221 * 00222 * In the worst case this could be rather slow; but in all the cases that seem 00223 * likely to be performance-critical, the reln being sought will actually be 00224 * first in the list. Furthermore, the number of unowned relns touched in any 00225 * one transaction shouldn't be all that high typically. So it doesn't seem 00226 * worth expending the additional space and management logic needed for a 00227 * doubly-linked list. 00228 */ 00229 static void 00230 remove_from_unowned_list(SMgrRelation reln) 00231 { 00232 SMgrRelation *link; 00233 SMgrRelation cur; 00234 00235 for (link = &first_unowned_reln, cur = *link; 00236 cur != NULL; 00237 link = &cur->next_unowned_reln, cur = *link) 00238 { 00239 if (cur == reln) 00240 { 00241 *link = cur->next_unowned_reln; 00242 cur->next_unowned_reln = NULL; 00243 break; 00244 } 00245 } 00246 } 00247 00248 /* 00249 * smgrexists() -- Does the underlying file for a fork exist? 00250 */ 00251 bool 00252 smgrexists(SMgrRelation reln, ForkNumber forknum) 00253 { 00254 return (*(smgrsw[reln->smgr_which].smgr_exists)) (reln, forknum); 00255 } 00256 00257 /* 00258 * smgrclose() -- Close and delete an SMgrRelation object. 00259 */ 00260 void 00261 smgrclose(SMgrRelation reln) 00262 { 00263 SMgrRelation *owner; 00264 ForkNumber forknum; 00265 00266 for (forknum = 0; forknum <= MAX_FORKNUM; forknum++) 00267 (*(smgrsw[reln->smgr_which].smgr_close)) (reln, forknum); 00268 00269 owner = reln->smgr_owner; 00270 00271 if (!owner) 00272 remove_from_unowned_list(reln); 00273 00274 if (hash_search(SMgrRelationHash, 00275 (void *) &(reln->smgr_rnode), 00276 HASH_REMOVE, NULL) == NULL) 00277 elog(ERROR, "SMgrRelation hashtable corrupted"); 00278 00279 /* 00280 * Unhook the owner pointer, if any. We do this last since in the remote 00281 * possibility of failure above, the SMgrRelation object will still exist. 00282 */ 00283 if (owner) 00284 *owner = NULL; 00285 } 00286 00287 /* 00288 * smgrcloseall() -- Close all existing SMgrRelation objects. 00289 */ 00290 void 00291 smgrcloseall(void) 00292 { 00293 HASH_SEQ_STATUS status; 00294 SMgrRelation reln; 00295 00296 /* Nothing to do if hashtable not set up */ 00297 if (SMgrRelationHash == NULL) 00298 return; 00299 00300 hash_seq_init(&status, SMgrRelationHash); 00301 00302 while ((reln = (SMgrRelation) hash_seq_search(&status)) != NULL) 00303 smgrclose(reln); 00304 } 00305 00306 /* 00307 * smgrclosenode() -- Close SMgrRelation object for given RelFileNode, 00308 * if one exists. 00309 * 00310 * This has the same effects as smgrclose(smgropen(rnode)), but it avoids 00311 * uselessly creating a hashtable entry only to drop it again when no 00312 * such entry exists already. 00313 */ 00314 void 00315 smgrclosenode(RelFileNodeBackend rnode) 00316 { 00317 SMgrRelation reln; 00318 00319 /* Nothing to do if hashtable not set up */ 00320 if (SMgrRelationHash == NULL) 00321 return; 00322 00323 reln = (SMgrRelation) hash_search(SMgrRelationHash, 00324 (void *) &rnode, 00325 HASH_FIND, NULL); 00326 if (reln != NULL) 00327 smgrclose(reln); 00328 } 00329 00330 /* 00331 * smgrcreate() -- Create a new relation. 00332 * 00333 * Given an already-created (but presumably unused) SMgrRelation, 00334 * cause the underlying disk file or other storage for the fork 00335 * to be created. 00336 * 00337 * If isRedo is true, it is okay for the underlying file to exist 00338 * already because we are in a WAL replay sequence. 00339 */ 00340 void 00341 smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo) 00342 { 00343 /* 00344 * Exit quickly in WAL replay mode if we've already opened the file. If 00345 * it's open, it surely must exist. 00346 */ 00347 if (isRedo && reln->md_fd[forknum] != NULL) 00348 return; 00349 00350 /* 00351 * We may be using the target table space for the first time in this 00352 * database, so create a per-database subdirectory if needed. 00353 * 00354 * XXX this is a fairly ugly violation of module layering, but this seems 00355 * to be the best place to put the check. Maybe TablespaceCreateDbspace 00356 * should be here and not in commands/tablespace.c? But that would imply 00357 * importing a lot of stuff that smgr.c oughtn't know, either. 00358 */ 00359 TablespaceCreateDbspace(reln->smgr_rnode.node.spcNode, 00360 reln->smgr_rnode.node.dbNode, 00361 isRedo); 00362 00363 (*(smgrsw[reln->smgr_which].smgr_create)) (reln, forknum, isRedo); 00364 } 00365 00366 /* 00367 * smgrdounlink() -- Immediately unlink all forks of a relation. 00368 * 00369 * All forks of the relation are removed from the store. This should 00370 * not be used during transactional operations, since it can't be undone. 00371 * 00372 * If isRedo is true, it is okay for the underlying file(s) to be gone 00373 * already. 00374 * 00375 * This is equivalent to calling smgrdounlinkfork for each fork, but 00376 * it's significantly quicker so should be preferred when possible. 00377 */ 00378 void 00379 smgrdounlink(SMgrRelation reln, bool isRedo) 00380 { 00381 RelFileNodeBackend rnode = reln->smgr_rnode; 00382 int which = reln->smgr_which; 00383 ForkNumber forknum; 00384 00385 /* Close the forks at smgr level */ 00386 for (forknum = 0; forknum <= MAX_FORKNUM; forknum++) 00387 (*(smgrsw[which].smgr_close)) (reln, forknum); 00388 00389 /* 00390 * Get rid of any remaining buffers for the relation. bufmgr will just 00391 * drop them without bothering to write the contents. 00392 */ 00393 DropRelFileNodesAllBuffers(&rnode, 1); 00394 00395 /* 00396 * It'd be nice to tell the stats collector to forget it immediately, too. 00397 * But we can't because we don't know the OID (and in cases involving 00398 * relfilenode swaps, it's not always clear which table OID to forget, 00399 * anyway). 00400 */ 00401 00402 /* 00403 * Send a shared-inval message to force other backends to close any 00404 * dangling smgr references they may have for this rel. We should do this 00405 * before starting the actual unlinking, in case we fail partway through 00406 * that step. Note that the sinval message will eventually come back to 00407 * this backend, too, and thereby provide a backstop that we closed our 00408 * own smgr rel. 00409 */ 00410 CacheInvalidateSmgr(rnode); 00411 00412 /* 00413 * Delete the physical file(s). 00414 * 00415 * Note: smgr_unlink must treat deletion failure as a WARNING, not an 00416 * ERROR, because we've already decided to commit or abort the current 00417 * xact. 00418 */ 00419 (*(smgrsw[which].smgr_unlink)) (rnode, InvalidForkNumber, isRedo); 00420 } 00421 00422 /* 00423 * smgrdounlinkall() -- Immediately unlink all forks of all given relations 00424 * 00425 * All forks of all given relations are removed from the store. This 00426 * should not be used during transactional operations, since it can't be 00427 * undone. 00428 * 00429 * If isRedo is true, it is okay for the underlying file(s) to be gone 00430 * already. 00431 * 00432 * This is equivalent to calling smgrdounlink for each relation, but it's 00433 * significantly quicker so should be preferred when possible. 00434 */ 00435 void 00436 smgrdounlinkall(SMgrRelation *rels, int nrels, bool isRedo) 00437 { 00438 int i = 0; 00439 RelFileNodeBackend *rnodes; 00440 ForkNumber forknum; 00441 00442 if (nrels == 0) 00443 return; 00444 00445 /* 00446 * create an array which contains all relations to be dropped, and 00447 * close each relation's forks at the smgr level while at it 00448 */ 00449 rnodes = palloc(sizeof(RelFileNodeBackend) * nrels); 00450 for (i = 0; i < nrels; i++) 00451 { 00452 RelFileNodeBackend rnode = rels[i]->smgr_rnode; 00453 int which = rels[i]->smgr_which; 00454 00455 rnodes[i] = rnode; 00456 00457 /* Close the forks at smgr level */ 00458 for (forknum = 0; forknum <= MAX_FORKNUM; forknum++) 00459 (*(smgrsw[which].smgr_close)) (rels[i], forknum); 00460 } 00461 00462 /* 00463 * Get rid of any remaining buffers for the relations. bufmgr will just 00464 * drop them without bothering to write the contents. 00465 */ 00466 DropRelFileNodesAllBuffers(rnodes, nrels); 00467 00468 /* 00469 * It'd be nice to tell the stats collector to forget them immediately, too. 00470 * But we can't because we don't know the OIDs. 00471 */ 00472 00473 /* 00474 * Send a shared-inval message to force other backends to close any 00475 * dangling smgr references they may have for these rels. We should do 00476 * this before starting the actual unlinking, in case we fail partway 00477 * through that step. Note that the sinval messages will eventually come 00478 * back to this backend, too, and thereby provide a backstop that we closed 00479 * our own smgr rel. 00480 */ 00481 for (i = 0; i < nrels; i++) 00482 CacheInvalidateSmgr(rnodes[i]); 00483 00484 /* 00485 * Delete the physical file(s). 00486 * 00487 * Note: smgr_unlink must treat deletion failure as a WARNING, not an 00488 * ERROR, because we've already decided to commit or abort the current 00489 * xact. 00490 */ 00491 00492 for (i = 0; i < nrels; i++) 00493 { 00494 int which = rels[i]->smgr_which; 00495 for (forknum = 0; forknum <= MAX_FORKNUM; forknum++) 00496 (*(smgrsw[which].smgr_unlink)) (rnodes[i], forknum, isRedo); 00497 } 00498 00499 pfree(rnodes); 00500 } 00501 00502 /* 00503 * smgrdounlinkfork() -- Immediately unlink one fork of a relation. 00504 * 00505 * The specified fork of the relation is removed from the store. This 00506 * should not be used during transactional operations, since it can't be 00507 * undone. 00508 * 00509 * If isRedo is true, it is okay for the underlying file to be gone 00510 * already. 00511 */ 00512 void 00513 smgrdounlinkfork(SMgrRelation reln, ForkNumber forknum, bool isRedo) 00514 { 00515 RelFileNodeBackend rnode = reln->smgr_rnode; 00516 int which = reln->smgr_which; 00517 00518 /* Close the fork at smgr level */ 00519 (*(smgrsw[which].smgr_close)) (reln, forknum); 00520 00521 /* 00522 * Get rid of any remaining buffers for the fork. bufmgr will just drop 00523 * them without bothering to write the contents. 00524 */ 00525 DropRelFileNodeBuffers(rnode, forknum, 0); 00526 00527 /* 00528 * It'd be nice to tell the stats collector to forget it immediately, too. 00529 * But we can't because we don't know the OID (and in cases involving 00530 * relfilenode swaps, it's not always clear which table OID to forget, 00531 * anyway). 00532 */ 00533 00534 /* 00535 * Send a shared-inval message to force other backends to close any 00536 * dangling smgr references they may have for this rel. We should do this 00537 * before starting the actual unlinking, in case we fail partway through 00538 * that step. Note that the sinval message will eventually come back to 00539 * this backend, too, and thereby provide a backstop that we closed our 00540 * own smgr rel. 00541 */ 00542 CacheInvalidateSmgr(rnode); 00543 00544 /* 00545 * Delete the physical file(s). 00546 * 00547 * Note: smgr_unlink must treat deletion failure as a WARNING, not an 00548 * ERROR, because we've already decided to commit or abort the current 00549 * xact. 00550 */ 00551 (*(smgrsw[which].smgr_unlink)) (rnode, forknum, isRedo); 00552 } 00553 00554 /* 00555 * smgrextend() -- Add a new block to a file. 00556 * 00557 * The semantics are nearly the same as smgrwrite(): write at the 00558 * specified position. However, this is to be used for the case of 00559 * extending a relation (i.e., blocknum is at or beyond the current 00560 * EOF). Note that we assume writing a block beyond current EOF 00561 * causes intervening file space to become filled with zeroes. 00562 */ 00563 void 00564 smgrextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, 00565 char *buffer, bool skipFsync) 00566 { 00567 (*(smgrsw[reln->smgr_which].smgr_extend)) (reln, forknum, blocknum, 00568 buffer, skipFsync); 00569 } 00570 00571 /* 00572 * smgrprefetch() -- Initiate asynchronous read of the specified block of a relation. 00573 */ 00574 void 00575 smgrprefetch(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum) 00576 { 00577 (*(smgrsw[reln->smgr_which].smgr_prefetch)) (reln, forknum, blocknum); 00578 } 00579 00580 /* 00581 * smgrread() -- read a particular block from a relation into the supplied 00582 * buffer. 00583 * 00584 * This routine is called from the buffer manager in order to 00585 * instantiate pages in the shared buffer cache. All storage managers 00586 * return pages in the format that POSTGRES expects. 00587 */ 00588 void 00589 smgrread(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, 00590 char *buffer) 00591 { 00592 (*(smgrsw[reln->smgr_which].smgr_read)) (reln, forknum, blocknum, buffer); 00593 } 00594 00595 /* 00596 * smgrwrite() -- Write the supplied buffer out. 00597 * 00598 * This is to be used only for updating already-existing blocks of a 00599 * relation (ie, those before the current EOF). To extend a relation, 00600 * use smgrextend(). 00601 * 00602 * This is not a synchronous write -- the block is not necessarily 00603 * on disk at return, only dumped out to the kernel. However, 00604 * provisions will be made to fsync the write before the next checkpoint. 00605 * 00606 * skipFsync indicates that the caller will make other provisions to 00607 * fsync the relation, so we needn't bother. Temporary relations also 00608 * do not require fsync. 00609 */ 00610 void 00611 smgrwrite(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, 00612 char *buffer, bool skipFsync) 00613 { 00614 (*(smgrsw[reln->smgr_which].smgr_write)) (reln, forknum, blocknum, 00615 buffer, skipFsync); 00616 } 00617 00618 /* 00619 * smgrnblocks() -- Calculate the number of blocks in the 00620 * supplied relation. 00621 */ 00622 BlockNumber 00623 smgrnblocks(SMgrRelation reln, ForkNumber forknum) 00624 { 00625 return (*(smgrsw[reln->smgr_which].smgr_nblocks)) (reln, forknum); 00626 } 00627 00628 /* 00629 * smgrtruncate() -- Truncate supplied relation to the specified number 00630 * of blocks 00631 * 00632 * The truncation is done immediately, so this can't be rolled back. 00633 */ 00634 void 00635 smgrtruncate(SMgrRelation reln, ForkNumber forknum, BlockNumber nblocks) 00636 { 00637 /* 00638 * Get rid of any buffers for the about-to-be-deleted blocks. bufmgr will 00639 * just drop them without bothering to write the contents. 00640 */ 00641 DropRelFileNodeBuffers(reln->smgr_rnode, forknum, nblocks); 00642 00643 /* 00644 * Send a shared-inval message to force other backends to close any smgr 00645 * references they may have for this rel. This is useful because they 00646 * might have open file pointers to segments that got removed, and/or 00647 * smgr_targblock variables pointing past the new rel end. (The inval 00648 * message will come back to our backend, too, causing a 00649 * probably-unnecessary local smgr flush. But we don't expect that this 00650 * is a performance-critical path.) As in the unlink code, we want to be 00651 * sure the message is sent before we start changing things on-disk. 00652 */ 00653 CacheInvalidateSmgr(reln->smgr_rnode); 00654 00655 /* 00656 * Do the truncation. 00657 */ 00658 (*(smgrsw[reln->smgr_which].smgr_truncate)) (reln, forknum, nblocks); 00659 } 00660 00661 /* 00662 * smgrimmedsync() -- Force the specified relation to stable storage. 00663 * 00664 * Synchronously force all previous writes to the specified relation 00665 * down to disk. 00666 * 00667 * This is useful for building completely new relations (eg, new 00668 * indexes). Instead of incrementally WAL-logging the index build 00669 * steps, we can just write completed index pages to disk with smgrwrite 00670 * or smgrextend, and then fsync the completed index file before 00671 * committing the transaction. (This is sufficient for purposes of 00672 * crash recovery, since it effectively duplicates forcing a checkpoint 00673 * for the completed index. But it is *not* sufficient if one wishes 00674 * to use the WAL log for PITR or replication purposes: in that case 00675 * we have to make WAL entries as well.) 00676 * 00677 * The preceding writes should specify skipFsync = true to avoid 00678 * duplicative fsyncs. 00679 * 00680 * Note that you need to do FlushRelationBuffers() first if there is 00681 * any possibility that there are dirty buffers for the relation; 00682 * otherwise the sync is not very meaningful. 00683 */ 00684 void 00685 smgrimmedsync(SMgrRelation reln, ForkNumber forknum) 00686 { 00687 (*(smgrsw[reln->smgr_which].smgr_immedsync)) (reln, forknum); 00688 } 00689 00690 00691 /* 00692 * smgrpreckpt() -- Prepare for checkpoint. 00693 */ 00694 void 00695 smgrpreckpt(void) 00696 { 00697 int i; 00698 00699 for (i = 0; i < NSmgr; i++) 00700 { 00701 if (smgrsw[i].smgr_pre_ckpt) 00702 (*(smgrsw[i].smgr_pre_ckpt)) (); 00703 } 00704 } 00705 00706 /* 00707 * smgrsync() -- Sync files to disk during checkpoint. 00708 */ 00709 void 00710 smgrsync(void) 00711 { 00712 int i; 00713 00714 for (i = 0; i < NSmgr; i++) 00715 { 00716 if (smgrsw[i].smgr_sync) 00717 (*(smgrsw[i].smgr_sync)) (); 00718 } 00719 } 00720 00721 /* 00722 * smgrpostckpt() -- Post-checkpoint cleanup. 00723 */ 00724 void 00725 smgrpostckpt(void) 00726 { 00727 int i; 00728 00729 for (i = 0; i < NSmgr; i++) 00730 { 00731 if (smgrsw[i].smgr_post_ckpt) 00732 (*(smgrsw[i].smgr_post_ckpt)) (); 00733 } 00734 } 00735 00736 /* 00737 * AtEOXact_SMgr 00738 * 00739 * This routine is called during transaction commit or abort (it doesn't 00740 * particularly care which). All transient SMgrRelation objects are closed. 00741 * 00742 * We do this as a compromise between wanting transient SMgrRelations to 00743 * live awhile (to amortize the costs of blind writes of multiple blocks) 00744 * and needing them to not live forever (since we're probably holding open 00745 * a kernel file descriptor for the underlying file, and we need to ensure 00746 * that gets closed reasonably soon if the file gets deleted). 00747 */ 00748 void 00749 AtEOXact_SMgr(void) 00750 { 00751 /* 00752 * Zap all unowned SMgrRelations. We rely on smgrclose() to remove each 00753 * one from the list. 00754 */ 00755 while (first_unowned_reln != NULL) 00756 { 00757 Assert(first_unowned_reln->smgr_owner == NULL); 00758 smgrclose(first_unowned_reln); 00759 } 00760 }