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

MySQL数据库

开发平台:

Visual C++

  1. /******************************************************
  2. Cursor read
  3. (c) 1997 Innobase Oy
  4. Created 2/16/1997 Heikki Tuuri
  5. *******************************************************/
  6. #include "read0read.h"
  7. #ifdef UNIV_NONINL
  8. #include "read0read.ic"
  9. #endif
  10. #include "srv0srv.h"
  11. #include "trx0sys.h"
  12. /*************************************************************************
  13. Creates a read view object. */
  14. UNIV_INLINE
  15. read_view_t*
  16. read_view_create_low(
  17. /*=================*/
  18. /* out, own: read view struct */
  19. ulint n, /* in: number of cells in the trx_ids array */
  20. mem_heap_t* heap) /* in: memory heap from which allocated */
  21. {
  22. read_view_t* view;
  23. view = mem_heap_alloc(heap, sizeof(read_view_t));
  24. view->n_trx_ids = n;
  25. view->trx_ids = mem_heap_alloc(heap, n * sizeof(dulint));
  26. return(view);
  27. }
  28. /*************************************************************************
  29. Makes a copy of the oldest existing read view, with the exception that also
  30. the creating trx of the oldest view is set as not visible in the 'copied'
  31. view. Opens a new view if no views currently exist. The view must be closed
  32. with ..._close. This is used in purge. */
  33. read_view_t*
  34. read_view_oldest_copy_or_open_new(
  35. /*==============================*/
  36. /* out, own: read view struct */
  37. trx_t* cr_trx, /* in: creating transaction, or NULL */
  38. mem_heap_t* heap) /* in: memory heap from which allocated */
  39. {
  40. read_view_t* old_view;
  41. read_view_t* view_copy;
  42. ibool needs_insert = TRUE;
  43. ulint insert_done = 0;
  44. ulint n;
  45. ulint i;
  46. #ifdef UNIV_SYNC_DEBUG
  47. ut_ad(mutex_own(&kernel_mutex));
  48. #endif /* UNIV_SYNC_DEBUG */
  49. old_view = UT_LIST_GET_LAST(trx_sys->view_list);
  50. if (old_view == NULL) {
  51. return(read_view_open_now(cr_trx, heap));
  52. }
  53. n = old_view->n_trx_ids;
  54. if (old_view->creator) {
  55. n++;
  56. } else {
  57. needs_insert = FALSE;
  58. }
  59. view_copy = read_view_create_low(n, heap);
  60. /* Insert the id of the creator in the right place of the descending
  61. array of ids, if needs_insert is TRUE: */
  62. i = 0;
  63. while (i < n) {
  64. if (needs_insert
  65.     && (i >= old_view->n_trx_ids
  66.      || ut_dulint_cmp(old_view->creator->id,
  67. read_view_get_nth_trx_id(old_view, i))
  68. > 0)) {
  69. read_view_set_nth_trx_id(view_copy, i,
  70. old_view->creator->id);
  71. needs_insert = FALSE;
  72. insert_done = 1;
  73. } else {
  74. read_view_set_nth_trx_id(view_copy, i,
  75. read_view_get_nth_trx_id(old_view,
  76. i - insert_done));
  77. }
  78. i++;
  79. }
  80. view_copy->creator = cr_trx;
  81.    view_copy->low_limit_no = old_view->low_limit_no;
  82. view_copy->low_limit_id = old_view->low_limit_id;
  83. view_copy->can_be_too_old = FALSE;
  84. if (n > 0) {
  85. /* The last active transaction has the smallest id: */
  86. view_copy->up_limit_id = read_view_get_nth_trx_id(
  87. view_copy, n - 1);
  88. } else {
  89. view_copy->up_limit_id = old_view->up_limit_id;
  90. }
  91. UT_LIST_ADD_LAST(view_list, trx_sys->view_list, view_copy);
  92. return(view_copy);
  93. }
  94. /*************************************************************************
  95. Opens a read view where exactly the transactions serialized before this
  96. point in time are seen in the view. */
  97. read_view_t*
  98. read_view_open_now(
  99. /*===============*/
  100. /* out, own: read view struct */
  101. trx_t* cr_trx, /* in: creating transaction, or NULL */
  102. mem_heap_t* heap) /* in: memory heap from which allocated */
  103. {
  104. read_view_t* view;
  105. trx_t* trx;
  106. ulint n;
  107. #ifdef UNIV_SYNC_DEBUG
  108. ut_ad(mutex_own(&kernel_mutex));
  109. #endif /* UNIV_SYNC_DEBUG */
  110. view = read_view_create_low(UT_LIST_GET_LEN(trx_sys->trx_list), heap);
  111. view->creator = cr_trx;
  112. /* No future transactions should be visible in the view */
  113.    view->low_limit_no = trx_sys->max_trx_id;
  114. view->low_limit_id = view->low_limit_no;
  115. view->can_be_too_old = FALSE;
  116. n = 0;
  117. trx = UT_LIST_GET_FIRST(trx_sys->trx_list);
  118. /* No active transaction should be visible, except cr_trx */
  119. while (trx) {
  120. if (trx != cr_trx && trx->conc_state == TRX_ACTIVE) {
  121. read_view_set_nth_trx_id(view, n, trx->id);
  122. n++;
  123. /* NOTE that a transaction whose trx number is <
  124. trx_sys->max_trx_id can still be active, if it is
  125. in the middle of its commit! Note that when a
  126. transaction starts, we initialize trx->no to
  127. ut_dulint_max. */
  128. if (ut_dulint_cmp(view->low_limit_no, trx->no) > 0) {
  129. view->low_limit_no = trx->no;
  130. }
  131. }
  132. trx = UT_LIST_GET_NEXT(trx_list, trx);
  133. }
  134. view->n_trx_ids = n;
  135. if (n > 0) {
  136. /* The last active transaction has the smallest id: */
  137. view->up_limit_id = read_view_get_nth_trx_id(view, n - 1);
  138. } else {
  139. view->up_limit_id = view->low_limit_id;
  140. }
  141. UT_LIST_ADD_FIRST(view_list, trx_sys->view_list, view);
  142. return(view);
  143. }
  144. /*************************************************************************
  145. Closes a read view. */
  146. void
  147. read_view_close(
  148. /*============*/
  149. read_view_t* view) /* in: read view */
  150. {
  151. #ifdef UNIV_SYNC_DEBUG
  152. ut_ad(mutex_own(&kernel_mutex));
  153. #endif /* UNIV_SYNC_DEBUG */
  154. UT_LIST_REMOVE(view_list, trx_sys->view_list, view);
  155. /*************************************************************************
  156. Closes a consistent read view for MySQL. This function is called at an SQL
  157. statement end if the trx isolation level is <= TRX_ISO_READ_COMMITTED. */
  158. void
  159. read_view_close_for_mysql(
  160. /*======================*/
  161. trx_t* trx) /* in: trx which has a read view */
  162. {
  163. ut_a(trx->read_view);
  164. mutex_enter(&kernel_mutex);
  165. read_view_close(trx->read_view);
  166. mem_heap_empty(trx->read_view_heap);
  167. trx->read_view = NULL;
  168. mutex_exit(&kernel_mutex);
  169. }
  170. /*************************************************************************
  171. Prints a read view to stderr. */
  172. void
  173. read_view_print(
  174. /*============*/
  175. read_view_t* view) /* in: read view */
  176. {
  177. ulint n_ids;
  178. ulint i;
  179. fprintf(stderr, "Read view low limit trx n:o %lu %lun",
  180. (ulong) ut_dulint_get_high(view->low_limit_no),
  181. (ulong) ut_dulint_get_low(view->low_limit_no));
  182. fprintf(stderr, "Read view up limit trx id %lu %lun",
  183. (ulong) ut_dulint_get_high(view->up_limit_id),
  184. (ulong) ut_dulint_get_low(view->up_limit_id));
  185. fprintf(stderr, "Read view low limit trx id %lu %lun",
  186. (ulong) ut_dulint_get_high(view->low_limit_id),
  187. (ulong) ut_dulint_get_low(view->low_limit_id));
  188. fprintf(stderr, "Read view individually stored trx ids:n");
  189. n_ids = view->n_trx_ids;
  190. for (i = 0; i < n_ids; i++) {
  191. fprintf(stderr, "Read view trx id %lu %lun",
  192. (ulong) ut_dulint_get_high(read_view_get_nth_trx_id(view, i)),
  193. (ulong) ut_dulint_get_low(read_view_get_nth_trx_id(view, i)));
  194. }
  195. }