trx0rseg.c
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:6k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /******************************************************
  2. Rollback segment
  3. (c) 1996 Innobase Oy
  4. Created 3/26/1996 Heikki Tuuri
  5. *******************************************************/
  6. #include "trx0rseg.h"
  7. #ifdef UNIV_NONINL
  8. #include "trx0rseg.ic"
  9. #endif
  10. #include "trx0undo.h"
  11. #include "fut0lst.h"
  12. #include "srv0srv.h"
  13. #include "trx0purge.h"
  14. /**********************************************************************
  15. Looks for a rollback segment, based on the rollback segment id. */
  16. trx_rseg_t*
  17. trx_rseg_get_on_id(
  18. /*===============*/
  19. /* out: rollback segment */
  20. ulint id) /* in: rollback segment id */
  21. {
  22. trx_rseg_t* rseg;
  23. rseg = UT_LIST_GET_FIRST(trx_sys->rseg_list);
  24. ut_ad(rseg);
  25. while (rseg->id != id) {
  26. rseg = UT_LIST_GET_NEXT(rseg_list, rseg);
  27. ut_ad(rseg);
  28. }
  29. return(rseg);
  30. }
  31. /********************************************************************
  32. Creates a rollback segment header. This function is called only when
  33. a new rollback segment is created in the database. */
  34. ulint
  35. trx_rseg_header_create(
  36. /*===================*/
  37. /* out: page number of the created segment,
  38. FIL_NULL if fail */
  39. ulint space, /* in: space id */
  40. ulint max_size, /* in: max size in pages */
  41. ulint* slot_no, /* out: rseg id == slot number in trx sys */
  42. mtr_t* mtr) /* in: mtr */
  43. {
  44. ulint page_no;
  45. trx_rsegf_t* rsegf;
  46. trx_sysf_t* sys_header;
  47. ulint i;
  48. page_t* page;
  49. ut_ad(mtr);
  50. ut_ad(mutex_own(&kernel_mutex));
  51. ut_ad(mtr_memo_contains(mtr, fil_space_get_latch(space),
  52. MTR_MEMO_X_LOCK));
  53. sys_header = trx_sysf_get(mtr);
  54. *slot_no = trx_sysf_rseg_find_free(mtr);
  55. if (*slot_no == ULINT_UNDEFINED) {
  56. return(FIL_NULL);
  57. }
  58. /* Allocate a new file segment for the rollback segment */
  59. page = fseg_create(space, 0, TRX_RSEG + TRX_RSEG_FSEG_HEADER, mtr);
  60. if (page == NULL) {
  61. /* No space left */
  62. return(FIL_NULL);
  63. }
  64. buf_page_dbg_add_level(page, SYNC_RSEG_HEADER_NEW);
  65. page_no = buf_frame_get_page_no(page);
  66. /* Get the rollback segment file page */
  67. rsegf = trx_rsegf_get_new(space, page_no, mtr);
  68.     
  69. /* Initialize max size field */
  70. mlog_write_ulint(rsegf + TRX_RSEG_MAX_SIZE, max_size, MLOG_4BYTES, mtr);
  71. /* Initialize the history list */
  72. mlog_write_ulint(rsegf + TRX_RSEG_HISTORY_SIZE, 0, MLOG_4BYTES, mtr);
  73. flst_init(rsegf + TRX_RSEG_HISTORY, mtr);
  74. /* Reset the undo log slots */
  75. for (i = 0; i < TRX_RSEG_N_SLOTS; i++) {
  76. trx_rsegf_set_nth_undo(rsegf, i, FIL_NULL, mtr);
  77. }
  78. /* Add the rollback segment info to the free slot in the trx system
  79. header */
  80. trx_sysf_rseg_set_space(sys_header, *slot_no, space, mtr);
  81. trx_sysf_rseg_set_page_no(sys_header, *slot_no, page_no, mtr);
  82. return(page_no);
  83. }
  84. /***************************************************************************
  85. Creates and initializes a rollback segment object. The values for the
  86. fields are read from the header. The object is inserted to the rseg
  87. list of the trx system object and a pointer is inserted in the rseg
  88. array in the trx system object. */
  89. static
  90. trx_rseg_t*
  91. trx_rseg_mem_create(
  92. /*================*/
  93. /* out, own: rollback segment object */
  94. ulint id, /* in: rollback segment id */
  95. ulint space, /* in: space where the segment placed */
  96. ulint page_no, /* in: page number of the segment header */
  97. mtr_t* mtr) /* in: mtr */
  98. {
  99. trx_rsegf_t* rseg_header;
  100. trx_rseg_t* rseg;
  101. trx_ulogf_t* undo_log_hdr;
  102. fil_addr_t node_addr;
  103. ulint sum_of_undo_sizes;
  104. ut_ad(mutex_own(&kernel_mutex));
  105. rseg = mem_alloc(sizeof(trx_rseg_t));
  106. rseg->id = id;
  107. rseg->space = space;
  108. rseg->page_no = page_no;
  109. mutex_create(&(rseg->mutex));
  110. mutex_set_level(&(rseg->mutex), SYNC_RSEG);
  111. UT_LIST_ADD_LAST(rseg_list, trx_sys->rseg_list, rseg);
  112. trx_sys_set_nth_rseg(trx_sys, id, rseg);
  113. rseg_header = trx_rsegf_get_new(space, page_no, mtr);
  114. rseg->max_size = mtr_read_ulint(rseg_header + TRX_RSEG_MAX_SIZE,
  115. MLOG_4BYTES, mtr);
  116. /* Initialize the undo log lists according to the rseg header */
  117. sum_of_undo_sizes = trx_undo_lists_init(rseg);
  118. rseg->curr_size = mtr_read_ulint(rseg_header + TRX_RSEG_HISTORY_SIZE,
  119. MLOG_4BYTES, mtr)
  120.   + 1 + sum_of_undo_sizes;
  121. if (flst_get_len(rseg_header + TRX_RSEG_HISTORY, mtr) > 0) {
  122. node_addr = trx_purge_get_log_from_hist(
  123.       flst_get_last(rseg_header + TRX_RSEG_HISTORY,
  124. mtr));
  125. rseg->last_page_no = node_addr.page;
  126. rseg->last_offset = node_addr.boffset;
  127. undo_log_hdr = trx_undo_page_get(rseg->space, node_addr.page,
  128. mtr)
  129.        + node_addr.boffset;
  130.        
  131. rseg->last_trx_no = mtr_read_dulint(
  132. undo_log_hdr + TRX_UNDO_TRX_NO,
  133. MLOG_8BYTES, mtr);
  134. rseg->last_del_marks = mtr_read_ulint(
  135. undo_log_hdr + TRX_UNDO_DEL_MARKS,
  136. MLOG_2BYTES, mtr);
  137. } else {
  138. rseg->last_page_no = FIL_NULL;
  139. }
  140. return(rseg);
  141. }
  142. /*************************************************************************
  143. Creates the memory copies for rollback segments and initializes the
  144. rseg list and array in trx_sys at a database startup. */
  145. void
  146. trx_rseg_list_and_array_init(
  147. /*=========================*/
  148. trx_sysf_t* sys_header, /* in: trx system header */
  149. mtr_t* mtr) /* in: mtr */
  150. {
  151. ulint i;
  152. ulint page_no;
  153. ulint space;
  154. UT_LIST_INIT(trx_sys->rseg_list);
  155. for (i = 0; i < TRX_SYS_N_RSEGS; i++) {
  156. page_no = trx_sysf_rseg_get_page_no(sys_header, i, mtr);
  157. if (page_no == FIL_NULL) {
  158. trx_sys_set_nth_rseg(trx_sys, i, NULL);
  159. } else {
  160. space = trx_sysf_rseg_get_space(sys_header, i, mtr);
  161. trx_rseg_mem_create(i, space, page_no, mtr);
  162. }
  163. }
  164. }
  165. /********************************************************************
  166. Creates a new rollback segment to the database. */
  167. trx_rseg_t*
  168. trx_rseg_create(
  169. /*============*/
  170. /* out: the created segment object, NULL if
  171. fail */
  172. ulint space, /* in: space id */
  173. ulint max_size, /* in: max size in pages */
  174. ulint* id, /* out: rseg id */
  175. mtr_t* mtr) /* in: mtr */
  176. {
  177. ulint page_no;
  178. trx_rseg_t* rseg;
  179. mtr_x_lock(fil_space_get_latch(space), mtr);
  180. mutex_enter(&kernel_mutex);
  181. page_no = trx_rseg_header_create(space, max_size, id, mtr);
  182. if (page_no == FIL_NULL) {
  183. mutex_exit(&kernel_mutex);
  184. return(NULL);
  185. }
  186. rseg = trx_rseg_mem_create(*id, space, page_no, mtr);
  187. mutex_exit(&kernel_mutex);
  188. return(rseg);
  189. }