smgr.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:9k
源码类别:

数据库系统

开发平台:

Unix_Linux

  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.  * Copyright (c) 1994, Regents of the University of California
  10.  *
  11.  *
  12.  * IDENTIFICATION
  13.  *   $Header: /usr/local/cvsroot/pgsql/src/backend/storage/smgr/smgr.c,v 1.24.2.1 1999/09/02 04:07:17 tgl Exp $
  14.  *
  15.  *-------------------------------------------------------------------------
  16.  */
  17. #include "postgres.h"
  18. #include "storage/smgr.h"
  19. static void smgrshutdown(int dummy);
  20. typedef struct f_smgr
  21. {
  22. int (*smgr_init) ();/* may be NULL */
  23. int (*smgr_shutdown) (); /* may be NULL */
  24. int (*smgr_create) ();
  25. int (*smgr_unlink) ();
  26. int (*smgr_extend) ();
  27. int (*smgr_open) ();
  28. int (*smgr_close) ();
  29. int (*smgr_read) ();
  30. int (*smgr_write) ();
  31. int (*smgr_flush) ();
  32. int (*smgr_blindwrt) ();
  33. int (*smgr_nblocks) ();
  34. int (*smgr_truncate) ();
  35. int (*smgr_commit) (); /* may be NULL */
  36. int (*smgr_abort) (); /* may be NULL */
  37. } f_smgr;
  38. /*
  39.  * The weird placement of commas in this init block is to keep the compiler
  40.  * happy, regardless of what storage managers we have (or don't have).
  41.  */
  42. static f_smgr smgrsw[] = {
  43. /* magnetic disk */
  44. {mdinit, NULL, mdcreate, mdunlink, mdextend, mdopen, mdclose,
  45. mdread, mdwrite, mdflush, mdblindwrt, mdnblocks, mdtruncate,
  46. mdcommit, mdabort},
  47. #ifdef STABLE_MEMORY_STORAGE
  48. /* main memory */
  49. {mminit, mmshutdown, mmcreate, mmunlink, mmextend, mmopen, mmclose,
  50. mmread, mmwrite, mmflush, mmblindwrt, mmnblocks, NULL,
  51. mmcommit, mmabort},
  52. #endif
  53. };
  54. /*
  55.  * This array records which storage managers are write-once, and which
  56.  * support overwrite. A 'true' entry means that the storage manager is
  57.  * write-once.  In the best of all possible worlds, there would be no
  58.  * write-once storage managers.
  59.  */
  60. #ifdef NOT_USED
  61. static bool smgrwo[] = {
  62. false, /* magnetic disk */
  63. #ifdef STABLE_MEMORY_STORAGE
  64. false, /* main memory */
  65. #endif
  66. };
  67. #endif
  68. static int NSmgr = lengthof(smgrsw);
  69. /*
  70.  * smgrinit(), smgrshutdown() -- Initialize or shut down all storage
  71.  *   managers.
  72.  *
  73.  */
  74. int
  75. smgrinit()
  76. {
  77. int i;
  78. for (i = 0; i < NSmgr; i++)
  79. {
  80. if (smgrsw[i].smgr_init)
  81. {
  82. if ((*(smgrsw[i].smgr_init)) () == SM_FAIL)
  83. elog(FATAL, "initialization failed on %s", smgrout(i));
  84. }
  85. }
  86. /* register the shutdown proc */
  87. on_proc_exit(smgrshutdown, NULL);
  88. return SM_SUCCESS;
  89. }
  90. static void
  91. smgrshutdown(int dummy)
  92. {
  93. int i;
  94. for (i = 0; i < NSmgr; i++)
  95. {
  96. if (smgrsw[i].smgr_shutdown)
  97. {
  98. if ((*(smgrsw[i].smgr_shutdown)) () == SM_FAIL)
  99. elog(FATAL, "shutdown failed on %s", smgrout(i));
  100. }
  101. }
  102. }
  103. /*
  104.  * smgrcreate() -- Create a new relation.
  105.  *
  106.  * This routine takes a reldesc, creates the relation on the appropriate
  107.  * device, and returns a file descriptor for it.
  108.  */
  109. int
  110. smgrcreate(int16 which, Relation reln)
  111. {
  112. int fd;
  113. if ((fd = (*(smgrsw[which].smgr_create)) (reln)) < 0)
  114. elog(ERROR, "cannot create %s", reln->rd_rel->relname.data);
  115. return fd;
  116. }
  117. /*
  118.  * smgrunlink() -- Unlink a relation.
  119.  *
  120.  * The relation is removed from the store.
  121.  */
  122. int
  123. smgrunlink(int16 which, Relation reln)
  124. {
  125. int status;
  126. if ((status = (*(smgrsw[which].smgr_unlink)) (reln)) == SM_FAIL)
  127. elog(ERROR, "cannot unlink %s", reln->rd_rel->relname.data);
  128. return status;
  129. }
  130. /*
  131.  * smgrextend() -- Add a new block to a file.
  132.  *
  133.  * Returns SM_SUCCESS on success; aborts the current transaction on
  134.  * failure.
  135.  */
  136. int
  137. smgrextend(int16 which, Relation reln, char *buffer)
  138. {
  139. int status;
  140. status = (*(smgrsw[which].smgr_extend)) (reln, buffer);
  141. if (status == SM_FAIL)
  142. elog(ERROR, "%s: cannot extend.  Check free disk space.", reln->rd_rel->relname.data);
  143. return status;
  144. }
  145. /*
  146.  * smgropen() -- Open a relation using a particular storage manager.
  147.  *
  148.  * Returns the fd for the open relation on success, aborts the
  149.  * transaction on failure.
  150.  */
  151. int
  152. smgropen(int16 which, Relation reln)
  153. {
  154. int fd;
  155. if ((fd = (*(smgrsw[which].smgr_open)) (reln)) < 0)
  156. elog(ERROR, "cannot open %s", reln->rd_rel->relname.data);
  157. return fd;
  158. }
  159. /*
  160.  * smgrclose() -- Close a relation.
  161.  *
  162.  * NOTE: underlying manager should allow case where relation is
  163.  * already closed.  Indeed relation may have been unlinked!
  164.  * This is currently called only from RelationFlushRelation() when
  165.  * the relation cache entry is about to be dropped; could be doing
  166.  * simple relation cache clear, or finishing up DROP TABLE.
  167.  *
  168.  * Returns SM_SUCCESS on success, aborts on failure.
  169.  */
  170. int
  171. smgrclose(int16 which, Relation reln)
  172. {
  173. if ((*(smgrsw[which].smgr_close)) (reln) == SM_FAIL)
  174. elog(ERROR, "cannot close %s", reln->rd_rel->relname.data);
  175. return SM_SUCCESS;
  176. }
  177. /*
  178.  * smgrread() -- read a particular block from a relation into the supplied
  179.  *   buffer.
  180.  *
  181.  * This routine is called from the buffer manager in order to
  182.  * instantiate pages in the shared buffer cache.  All storage managers
  183.  * return pages in the format that POSTGRES expects.  This routine
  184.  * dispatches the read.  On success, it returns SM_SUCCESS.  On failure,
  185.  * the current transaction is aborted.
  186.  */
  187. int
  188. smgrread(int16 which, Relation reln, BlockNumber blocknum, char *buffer)
  189. {
  190. int status;
  191. status = (*(smgrsw[which].smgr_read)) (reln, blocknum, buffer);
  192. if (status == SM_FAIL)
  193. elog(ERROR, "cannot read block %d of %s",
  194.  blocknum, reln->rd_rel->relname.data);
  195. return status;
  196. }
  197. /*
  198.  * smgrwrite() -- Write the supplied buffer out.
  199.  *
  200.  * This is not a synchronous write -- the interface for that is
  201.  * smgrflush().  The buffer is written out via the appropriate
  202.  * storage manager.  This routine returns SM_SUCCESS or aborts
  203.  * the current transaction.
  204.  */
  205. int
  206. smgrwrite(int16 which, Relation reln, BlockNumber blocknum, char *buffer)
  207. {
  208. int status;
  209. status = (*(smgrsw[which].smgr_write)) (reln, blocknum, buffer);
  210. if (status == SM_FAIL)
  211. elog(ERROR, "cannot write block %d of %s",
  212.  blocknum, reln->rd_rel->relname.data);
  213. return status;
  214. }
  215. /*
  216.  * smgrflush() -- A synchronous smgrwrite().
  217.  */
  218. int
  219. smgrflush(int16 which, Relation reln, BlockNumber blocknum, char *buffer)
  220. {
  221. int status;
  222. status = (*(smgrsw[which].smgr_flush)) (reln, blocknum, buffer);
  223. if (status == SM_FAIL)
  224. elog(ERROR, "cannot flush block %d of %s to stable store",
  225.  blocknum, reln->rd_rel->relname.data);
  226. return status;
  227. }
  228. /*
  229.  * smgrblindwrt() -- Write a page out blind.
  230.  *
  231.  * In some cases, we may find a page in the buffer cache that we
  232.  * can't make a reldesc for.  This happens, for example, when we
  233.  * want to reuse a dirty page that was written by a transaction
  234.  * that has not yet committed, which created a new relation.  In
  235.  * this case, the buffer manager will call smgrblindwrt() with
  236.  * the name and OID of the database and the relation to which the
  237.  * buffer belongs.  Every storage manager must be able to force
  238.  * this page down to stable storage in this circumstance.
  239.  */
  240. int
  241. smgrblindwrt(int16 which,
  242.  char *dbname,
  243.  char *relname,
  244.  Oid dbid,
  245.  Oid relid,
  246.  BlockNumber blkno,
  247.  char *buffer)
  248. {
  249. char    *dbstr;
  250. char    *relstr;
  251. int status;
  252. dbstr = pstrdup(dbname);
  253. relstr = pstrdup(relname);
  254. status = (*(smgrsw[which].smgr_blindwrt)) (dbstr, relstr, dbid, relid,
  255.    blkno, buffer);
  256. if (status == SM_FAIL)
  257. elog(ERROR, "cannot write block %d of %s [%s] blind",
  258.  blkno, relstr, dbstr);
  259. pfree(dbstr);
  260. pfree(relstr);
  261. return status;
  262. }
  263. /*
  264.  * smgrnblocks() -- Calculate the number of POSTGRES blocks in the
  265.  *  supplied relation.
  266.  *
  267.  * Returns the number of blocks on success, aborts the current
  268.  * transaction on failure.
  269.  */
  270. int
  271. smgrnblocks(int16 which, Relation reln)
  272. {
  273. int nblocks;
  274. if ((nblocks = (*(smgrsw[which].smgr_nblocks)) (reln)) < 0)
  275. elog(ERROR, "cannot count blocks for %s", reln->rd_rel->relname.data);
  276. return nblocks;
  277. }
  278. /*
  279.  * smgrtruncate() -- Truncate supplied relation to a specified number
  280.  * of blocks
  281.  *
  282.  * Returns the number of blocks on success, aborts the current
  283.  * transaction on failure.
  284.  */
  285. int
  286. smgrtruncate(int16 which, Relation reln, int nblocks)
  287. {
  288. int newblks;
  289. newblks = nblocks;
  290. if (smgrsw[which].smgr_truncate)
  291. {
  292. if ((newblks = (*(smgrsw[which].smgr_truncate)) (reln, nblocks)) < 0)
  293. elog(ERROR, "cannot truncate %s to %d blocks",
  294.  reln->rd_rel->relname.data, nblocks);
  295. }
  296. return newblks;
  297. }
  298. /*
  299.  * smgrcommit(), smgrabort() -- Commit or abort changes made during the
  300.  *  current transaction.
  301.  */
  302. int
  303. smgrcommit()
  304. {
  305. int i;
  306. for (i = 0; i < NSmgr; i++)
  307. {
  308. if (smgrsw[i].smgr_commit)
  309. {
  310. if ((*(smgrsw[i].smgr_commit)) () == SM_FAIL)
  311. elog(FATAL, "transaction commit failed on %s", smgrout(i));
  312. }
  313. }
  314. return SM_SUCCESS;
  315. }
  316. #ifdef NOT_USED
  317. int
  318. smgrabort()
  319. {
  320. int i;
  321. for (i = 0; i < NSmgr; i++)
  322. {
  323. if (smgrsw[i].smgr_abort)
  324. {
  325. if ((*(smgrsw[i].smgr_abort)) () == SM_FAIL)
  326. elog(FATAL, "transaction abort failed on %s", smgrout(i));
  327. }
  328. }
  329. return SM_SUCCESS;
  330. }
  331. #endif
  332. #ifdef NOT_USED
  333. bool
  334. smgriswo(int16 smgrno)
  335. {
  336. if (smgrno < 0 || smgrno >= NSmgr)
  337. elog(ERROR, "illegal storage manager number %d", smgrno);
  338. return smgrwo[smgrno];
  339. }
  340. #endif