trx0sys.ic
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:10k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /******************************************************
  2. Transaction system
  3. (c) 1996 Innobase Oy
  4. Created 3/26/1996 Heikki Tuuri
  5. *******************************************************/
  6. #include "srv0srv.h"
  7. #include "trx0trx.h"
  8. #include "data0type.h"
  9. /* The typedef for rseg slot in the file copy */
  10. typedef byte  trx_sysf_rseg_t;
  11. /* Rollback segment specification slot offsets */
  12. /*-------------------------------------------------------------*/
  13. #define TRX_SYS_RSEG_SPACE 0 /* space where the the segment
  14. header is placed */
  15. #define TRX_SYS_RSEG_PAGE_NO 4 /*  page number where the the segment
  16. header is placed; this is FIL_NULL
  17. if the slot is unused */
  18. /*-------------------------------------------------------------*/
  19. /* Size of a rollback segment specification slot */
  20. #define TRX_SYS_RSEG_SLOT_SIZE 8
  21. /*********************************************************************
  22. Writes the value of max_trx_id to the file based trx system header. */
  23. void
  24. trx_sys_flush_max_trx_id(void);
  25. /*==========================*/
  26. /*******************************************************************
  27. Checks if a page address is the trx sys header page. */
  28. UNIV_INLINE
  29. ibool
  30. trx_sys_hdr_page(
  31. /*=============*/
  32. /* out: TRUE if trx sys header page */
  33. ulint space, /* in: space */
  34. ulint page_no)/* in: page number */
  35. {
  36. if ((space == TRX_SYS_SPACE) && (page_no == TRX_SYS_PAGE_NO)) {
  37. return(TRUE);
  38. }
  39. return(FALSE);
  40. }
  41. /*******************************************************************
  42. Gets the pointer in the nth slot of the rseg array. */
  43. UNIV_INLINE
  44. trx_rseg_t*
  45. trx_sys_get_nth_rseg(
  46. /*=================*/
  47. /* out: pointer to rseg object, NULL if slot
  48. not in use */
  49. trx_sys_t* sys, /* in: trx system */
  50. ulint n) /* in: index of slot */
  51. {
  52. #ifdef UNIV_SYNC_DEBUG
  53. ut_ad(mutex_own(&(kernel_mutex)));
  54. #endif /* UNIV_SYNC_DEBUG */
  55. ut_ad(n < TRX_SYS_N_RSEGS);
  56. return(sys->rseg_array[n]);
  57. }
  58. /*******************************************************************
  59. Sets the pointer in the nth slot of the rseg array. */
  60. UNIV_INLINE
  61. void
  62. trx_sys_set_nth_rseg(
  63. /*=================*/
  64. trx_sys_t* sys, /* in: trx system */
  65. ulint n, /* in: index of slot */
  66. trx_rseg_t* rseg) /* in: pointer to rseg object, NULL if slot
  67. not in use */
  68. {
  69. ut_ad(n < TRX_SYS_N_RSEGS);
  70. sys->rseg_array[n] = rseg;
  71. }
  72. /**************************************************************************
  73. Gets a pointer to the transaction system header and x-latches its page. */
  74. UNIV_INLINE
  75. trx_sysf_t*
  76. trx_sysf_get(
  77. /*=========*/
  78. /* out: pointer to system header, page x-latched. */
  79. mtr_t* mtr) /* in: mtr */
  80. {
  81. trx_sysf_t* header;
  82. ut_ad(mtr);
  83. header = TRX_SYS + buf_page_get(TRX_SYS_SPACE, TRX_SYS_PAGE_NO,
  84. RW_X_LATCH, mtr);
  85. #ifdef UNIV_SYNC_DEBUG
  86. buf_page_dbg_add_level(header, SYNC_TRX_SYS_HEADER);
  87. #endif /* UNIV_SYNC_DEBUG */
  88. return(header);
  89. }
  90. /*********************************************************************
  91. Gets the space of the nth rollback segment slot in the trx system
  92. file copy. */
  93. UNIV_INLINE
  94. ulint
  95. trx_sysf_rseg_get_space(
  96. /*====================*/
  97. /* out: space id */
  98. trx_sysf_t* sys_header, /* in: trx sys header */
  99. ulint i, /* in: slot index == rseg id */
  100. mtr_t* mtr) /* in: mtr */
  101. {
  102. #ifdef UNIV_SYNC_DEBUG
  103. ut_ad(mutex_own(&(kernel_mutex)));
  104. #endif /* UNIV_SYNC_DEBUG */
  105. ut_ad(sys_header);
  106. ut_ad(i < TRX_SYS_N_RSEGS);
  107. return(mtr_read_ulint(sys_header + TRX_SYS_RSEGS
  108. + i * TRX_SYS_RSEG_SLOT_SIZE
  109. + TRX_SYS_RSEG_SPACE, MLOG_4BYTES, mtr));
  110. }
  111. /*********************************************************************
  112. Gets the page number of the nth rollback segment slot in the trx system
  113. header. */
  114. UNIV_INLINE
  115. ulint
  116. trx_sysf_rseg_get_page_no(
  117. /*======================*/
  118. /* out: page number, FIL_NULL
  119. if slot unused */
  120. trx_sysf_t* sys_header, /* in: trx system header */
  121. ulint i, /* in: slot index == rseg id */
  122. mtr_t* mtr) /* in: mtr */
  123. {
  124. ut_ad(sys_header);
  125. #ifdef UNIV_SYNC_DEBUG
  126. ut_ad(mutex_own(&(kernel_mutex)));
  127. #endif /* UNIV_SYNC_DEBUG */
  128. ut_ad(i < TRX_SYS_N_RSEGS);
  129. return(mtr_read_ulint(sys_header + TRX_SYS_RSEGS
  130. + i * TRX_SYS_RSEG_SLOT_SIZE
  131. + TRX_SYS_RSEG_PAGE_NO, MLOG_4BYTES, mtr));
  132. }
  133. /*********************************************************************
  134. Sets the space id of the nth rollback segment slot in the trx system
  135. file copy. */
  136. UNIV_INLINE
  137. void
  138. trx_sysf_rseg_set_space(
  139. /*====================*/
  140. trx_sysf_t* sys_header, /* in: trx sys file copy */
  141. ulint i, /* in: slot index == rseg id */
  142. ulint space, /* in: space id */
  143. mtr_t* mtr) /* in: mtr */
  144. {
  145. #ifdef UNIV_SYNC_DEBUG
  146. ut_ad(mutex_own(&(kernel_mutex)));
  147. #endif /* UNIV_SYNC_DEBUG */
  148. ut_ad(sys_header);
  149. ut_ad(i < TRX_SYS_N_RSEGS);
  150. mlog_write_ulint(sys_header + TRX_SYS_RSEGS
  151. + i * TRX_SYS_RSEG_SLOT_SIZE
  152. + TRX_SYS_RSEG_SPACE,
  153. space,
  154. MLOG_4BYTES, mtr);
  155. }
  156. /*********************************************************************
  157. Sets the page number of the nth rollback segment slot in the trx system
  158. header. */
  159. UNIV_INLINE
  160. void
  161. trx_sysf_rseg_set_page_no(
  162. /*======================*/
  163. trx_sysf_t* sys_header, /* in: trx sys header */
  164. ulint i, /* in: slot index == rseg id */
  165. ulint page_no, /* in: page number, FIL_NULL if the
  166. slot is reset to unused */
  167. mtr_t* mtr) /* in: mtr */
  168. {
  169. #ifdef UNIV_SYNC_DEBUG
  170. ut_ad(mutex_own(&(kernel_mutex)));
  171. #endif /* UNIV_SYNC_DEBUG */
  172. ut_ad(sys_header);
  173. ut_ad(i < TRX_SYS_N_RSEGS);
  174. mlog_write_ulint(sys_header + TRX_SYS_RSEGS
  175. + i * TRX_SYS_RSEG_SLOT_SIZE
  176. + TRX_SYS_RSEG_PAGE_NO,
  177. page_no,
  178. MLOG_4BYTES, mtr);
  179. }
  180. /*********************************************************************
  181. Writes a trx id to an index page. In case that the id size changes in
  182. some future version, this function should be used instead of
  183. mach_write_... */
  184. UNIV_INLINE
  185. void
  186. trx_write_trx_id(
  187. /*=============*/
  188. byte* ptr, /* in: pointer to memory where written */
  189. dulint id) /* in: id */
  190. {
  191. ut_ad(DATA_TRX_ID_LEN == 6);
  192. mach_write_to_6(ptr, id);
  193. }
  194. /*********************************************************************
  195. Reads a trx id from an index page. In case that the id size changes in
  196. some future version, this function should be used instead of
  197. mach_read_... */
  198. UNIV_INLINE
  199. dulint
  200. trx_read_trx_id(
  201. /*============*/
  202. /* out: id */
  203. byte* ptr) /* in: pointer to memory from where to read */
  204. {
  205. ut_ad(DATA_TRX_ID_LEN == 6);
  206. return(mach_read_from_6(ptr));
  207. }
  208. /********************************************************************
  209. Looks for the trx handle with the given id in trx_list. */
  210. UNIV_INLINE
  211. trx_t*
  212. trx_get_on_id(
  213. /*==========*/
  214. /* out: the trx handle or NULL if not found */
  215. dulint trx_id) /* in: trx id to search for */
  216. {
  217. trx_t* trx;
  218. #ifdef UNIV_SYNC_DEBUG
  219. ut_ad(mutex_own(&(kernel_mutex)));
  220. #endif /* UNIV_SYNC_DEBUG */
  221. trx = UT_LIST_GET_FIRST(trx_sys->trx_list);
  222. while (trx != NULL) {
  223. if (0 == ut_dulint_cmp(trx_id, trx->id)) {
  224. return(trx);
  225. }
  226. trx = UT_LIST_GET_NEXT(trx_list, trx);
  227. }
  228. return(NULL);
  229. }
  230. /********************************************************************
  231. Returns the minumum trx id in trx list. This is the smallest id for which
  232. the trx can possibly be active. (But, you must look at the trx->conc_state to
  233. find out if the minimum trx id transaction itself is active, or already
  234. committed.) */
  235. UNIV_INLINE
  236. dulint
  237. trx_list_get_min_trx_id(void)
  238. /*=========================*/
  239. /* out: the minimum trx id, or trx_sys->max_trx_id
  240. if the trx list is empty */
  241. {
  242. trx_t* trx;
  243. #ifdef UNIV_SYNC_DEBUG
  244. ut_ad(mutex_own(&(kernel_mutex)));
  245. #endif /* UNIV_SYNC_DEBUG */
  246. trx = UT_LIST_GET_LAST(trx_sys->trx_list);
  247. if (trx == NULL) {
  248. return(trx_sys->max_trx_id);
  249. }
  250. return(trx->id);
  251. }
  252. /********************************************************************
  253. Checks if a transaction with the given id is active. */
  254. UNIV_INLINE
  255. ibool
  256. trx_is_active(
  257. /*==========*/
  258. /* out: TRUE if active */
  259. dulint trx_id) /* in: trx id of the transaction */
  260. {
  261. trx_t* trx;
  262. #ifdef UNIV_SYNC_DEBUG
  263. ut_ad(mutex_own(&(kernel_mutex)));
  264. #endif /* UNIV_SYNC_DEBUG */
  265. if (ut_dulint_cmp(trx_id, trx_list_get_min_trx_id()) < 0) {
  266. return(FALSE);
  267. }
  268. if (ut_dulint_cmp(trx_id, trx_sys->max_trx_id) >= 0) {
  269. /* There must be corruption: we return TRUE because this
  270. function is only called by lock_clust_rec_some_has_impl()
  271. and row_vers_impl_x_locked_off_kernel() and they have
  272. diagnostic prints in this case */
  273. return(TRUE);
  274. }
  275. trx = trx_get_on_id(trx_id);
  276. if (trx && (trx->conc_state == TRX_ACTIVE)) {
  277. return(TRUE);
  278. }
  279. return(FALSE);
  280. }
  281. /*********************************************************************
  282. Allocates a new transaction id. */
  283. UNIV_INLINE
  284. dulint
  285. trx_sys_get_new_trx_id(void)
  286. /*========================*/
  287. /* out: new, allocated trx id */
  288. {
  289. dulint id;
  290. #ifdef UNIV_SYNC_DEBUG
  291. ut_ad(mutex_own(&kernel_mutex));
  292. #endif /* UNIV_SYNC_DEBUG */
  293. /* VERY important: after the database is started, max_trx_id value is
  294. divisible by TRX_SYS_TRX_ID_WRITE_MARGIN, and the following if
  295. will evaluate to TRUE when this function is first time called,
  296. and the value for trx id will be written to disk-based header!
  297. Thus trx id values will not overlap when the database is
  298. repeatedly started! */
  299. if (ut_dulint_get_low(trx_sys->max_trx_id)
  300. % TRX_SYS_TRX_ID_WRITE_MARGIN == 0) {
  301. trx_sys_flush_max_trx_id();
  302. }
  303. id = trx_sys->max_trx_id;
  304. UT_DULINT_INC(trx_sys->max_trx_id);
  305. return(id);
  306. }
  307. /*********************************************************************
  308. Allocates a new transaction number. */
  309. UNIV_INLINE
  310. dulint
  311. trx_sys_get_new_trx_no(void)
  312. /*========================*/
  313. /* out: new, allocated trx number */
  314. {
  315. #ifdef UNIV_SYNC_DEBUG
  316. ut_ad(mutex_own(&kernel_mutex));
  317. #endif /* UNIV_SYNC_DEBUG */
  318. return(trx_sys_get_new_trx_id());
  319. }