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

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
  32. closed 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. ut_ad(mutex_own(&kernel_mutex));
  47. old_view = UT_LIST_GET_LAST(trx_sys->view_list);
  48. if (old_view == NULL) {
  49. return(read_view_open_now(cr_trx, heap));
  50. }
  51. n = old_view->n_trx_ids;
  52. if (old_view->creator) {
  53. n++;
  54. } else {
  55. needs_insert = FALSE;
  56. }
  57. view_copy = read_view_create_low(n, heap);
  58. /* Insert the id of the creator in the right place of the descending
  59. array of ids, if needs_insert is TRUE: */
  60. i = 0;
  61. while (i < n) {
  62. if (needs_insert
  63.     && (i >= old_view->n_trx_ids
  64.      || ut_dulint_cmp(old_view->creator->id,
  65. read_view_get_nth_trx_id(old_view, i))
  66. > 0)) {
  67. read_view_set_nth_trx_id(view_copy, i,
  68. old_view->creator->id);
  69. needs_insert = FALSE;
  70. insert_done = 1;
  71. } else {
  72. read_view_set_nth_trx_id(view_copy, i,
  73. read_view_get_nth_trx_id(old_view,
  74. i - insert_done));
  75. }
  76. i++;
  77. }
  78. view_copy->creator = cr_trx;
  79.    view_copy->low_limit_no = old_view->low_limit_no;
  80. view_copy->low_limit_id = old_view->low_limit_id;
  81. view_copy->can_be_too_old = FALSE;
  82. if (n > 0) {
  83. /* The last active transaction has the smallest id: */
  84. view_copy->up_limit_id = read_view_get_nth_trx_id(
  85. view_copy, n - 1);
  86. } else {
  87. view_copy->up_limit_id = old_view->up_limit_id;
  88. }
  89. UT_LIST_ADD_LAST(view_list, trx_sys->view_list, view_copy);
  90. return(view_copy);
  91. }
  92. /*************************************************************************
  93. Opens a read view where exactly the transactions serialized before this
  94. point in time are seen in the view. */
  95. read_view_t*
  96. read_view_open_now(
  97. /*===============*/
  98. /* out, own: read view struct */
  99. trx_t* cr_trx, /* in: creating transaction, or NULL */
  100. mem_heap_t* heap) /* in: memory heap from which allocated */
  101. {
  102. read_view_t* view;
  103. trx_t* trx;
  104. ulint n;
  105. ut_ad(mutex_own(&kernel_mutex));
  106. view = read_view_create_low(UT_LIST_GET_LEN(trx_sys->trx_list), heap);
  107. view->creator = cr_trx;
  108. /* No future transactions should be visible in the view */
  109.    view->low_limit_no = trx_sys->max_trx_id;
  110. view->low_limit_id = view->low_limit_no;
  111. view->can_be_too_old = FALSE;
  112. n = 0;
  113. trx = UT_LIST_GET_FIRST(trx_sys->trx_list);
  114. /* No active transaction should be visible, except cr_trx */
  115. while (trx) {
  116. if (trx != cr_trx && trx->conc_state == TRX_ACTIVE) {
  117. read_view_set_nth_trx_id(view, n, trx->id);
  118. n++;
  119. /* NOTE that a transaction whose trx number is <
  120. trx_sys->max_trx_id can still be active, if it is
  121. in the middle of the commit! Note that when a
  122. transaction starts, we initialize trx->no to
  123. ut_dulint_max. */
  124. if (ut_dulint_cmp(view->low_limit_no, trx->no) > 0) {
  125. view->low_limit_no = trx->no;
  126. }
  127. }
  128. trx = UT_LIST_GET_NEXT(trx_list, trx);
  129. }
  130. view->n_trx_ids = n;
  131. if (n > 0) {
  132. /* The last active transaction has the smallest id: */
  133. view->up_limit_id = read_view_get_nth_trx_id(view, n - 1);
  134. } else {
  135. view->up_limit_id = view->low_limit_id;
  136. }
  137. UT_LIST_ADD_FIRST(view_list, trx_sys->view_list, view);
  138. return(view);
  139. }
  140. /*************************************************************************
  141. Closes a read view. */
  142. void
  143. read_view_close(
  144. /*============*/
  145. read_view_t* view) /* in: read view */
  146. {
  147. ut_ad(mutex_own(&kernel_mutex));
  148. UT_LIST_REMOVE(view_list, trx_sys->view_list, view);