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

MySQL数据库

开发平台:

Visual C++

  1. /******************************************************
  2. Fresh insert undo
  3. (c) 1996 Innobase Oy
  4. Created 2/25/1997 Heikki Tuuri
  5. *******************************************************/
  6. #include "row0uins.h"
  7. #ifdef UNIV_NONINL
  8. #include "row0uins.ic"
  9. #endif
  10. #include "dict0dict.h"
  11. #include "dict0boot.h"
  12. #include "dict0crea.h"
  13. #include "trx0undo.h"
  14. #include "trx0roll.h"
  15. #include "btr0btr.h"
  16. #include "mach0data.h"
  17. #include "row0undo.h"
  18. #include "row0vers.h"
  19. #include "trx0trx.h"
  20. #include "trx0rec.h"
  21. #include "row0row.h"
  22. #include "row0upd.h"
  23. #include "que0que.h"
  24. #include "ibuf0ibuf.h"
  25. #include "log0log.h"
  26. /*******************************************************************
  27. Removes a clustered index record. The pcur in node was positioned on the
  28. record, now it is detached. */
  29. static
  30. ulint
  31. row_undo_ins_remove_clust_rec(
  32. /*==========================*/
  33. /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
  34. undo_node_t* node) /* in: undo node */
  35. {
  36. btr_cur_t* btr_cur;
  37. ibool success;
  38. ulint err;
  39. ulint n_tries = 0;
  40. mtr_t mtr;
  41. mtr_start(&mtr);
  42. success = btr_pcur_restore_position(BTR_MODIFY_LEAF, &(node->pcur),
  43. &mtr);
  44. ut_a(success);
  45. if (ut_dulint_cmp(node->table->id, DICT_INDEXES_ID) == 0) {
  46. /* Drop the index tree associated with the row in
  47. SYS_INDEXES table: */
  48. dict_drop_index_tree(btr_pcur_get_rec(&(node->pcur)), &mtr);
  49. mtr_commit(&mtr);
  50. mtr_start(&mtr);
  51. success = btr_pcur_restore_position(BTR_MODIFY_LEAF,
  52. &(node->pcur), &mtr);
  53. ut_a(success);
  54. }
  55. btr_cur = btr_pcur_get_btr_cur(&(node->pcur));
  56. success = btr_cur_optimistic_delete(btr_cur, &mtr);
  57. btr_pcur_commit_specify_mtr(&(node->pcur), &mtr);
  58. if (success) {
  59. trx_undo_rec_release(node->trx, node->undo_no);
  60. return(DB_SUCCESS);
  61. }
  62. retry:
  63. /* If did not succeed, try pessimistic descent to tree */
  64. mtr_start(&mtr);
  65. success = btr_pcur_restore_position(BTR_MODIFY_TREE,
  66. &(node->pcur), &mtr);
  67. ut_a(success);
  68. btr_cur_pessimistic_delete(&err, FALSE, btr_cur, TRUE, &mtr);
  69. /* The delete operation may fail if we have little
  70. file space left: TODO: easiest to crash the database
  71. and restart with more file space */
  72. if (err == DB_OUT_OF_FILE_SPACE
  73. && n_tries < BTR_CUR_RETRY_DELETE_N_TIMES) {
  74. btr_pcur_commit_specify_mtr(&(node->pcur), &mtr);
  75. n_tries++;
  76. os_thread_sleep(BTR_CUR_RETRY_SLEEP_TIME);
  77. goto retry;
  78. }
  79. btr_pcur_commit_specify_mtr(&(node->pcur), &mtr);
  80. trx_undo_rec_release(node->trx, node->undo_no);
  81. return(err);
  82. }
  83. /*******************************************************************
  84. Removes a secondary index entry if found. */
  85. static
  86. ulint
  87. row_undo_ins_remove_sec_low(
  88. /*========================*/
  89. /* out: DB_SUCCESS, DB_FAIL, or
  90. DB_OUT_OF_FILE_SPACE */
  91. ulint mode, /* in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
  92. depending on whether we wish optimistic or
  93. pessimistic descent down the index tree */
  94. dict_index_t* index, /* in: index */
  95. dtuple_t* entry) /* in: index entry to remove */
  96. {
  97. btr_pcur_t pcur;
  98. btr_cur_t* btr_cur;
  99. ibool found;
  100. ibool success;
  101. ulint err;
  102. mtr_t mtr;
  103. log_free_check();
  104. mtr_start(&mtr);
  105. found = row_search_index_entry(index, entry, mode, &pcur, &mtr);
  106. btr_cur = btr_pcur_get_btr_cur(&pcur);
  107. if (!found) {
  108. /* Not found */
  109. btr_pcur_close(&pcur);
  110. mtr_commit(&mtr);
  111. return(DB_SUCCESS);
  112. }
  113. if (mode == BTR_MODIFY_LEAF) {
  114. success = btr_cur_optimistic_delete(btr_cur, &mtr);
  115. if (success) {
  116. err = DB_SUCCESS;
  117. } else {
  118. err = DB_FAIL;
  119. }
  120. } else {
  121. ut_ad(mode == BTR_MODIFY_TREE);
  122. btr_cur_pessimistic_delete(&err, FALSE, btr_cur, TRUE, &mtr);
  123. }
  124. btr_pcur_close(&pcur);
  125. mtr_commit(&mtr);
  126. return(err);
  127. }
  128. /*******************************************************************
  129. Removes a secondary index entry from the index if found. Tries first
  130. optimistic, then pessimistic descent down the tree. */
  131. static
  132. ulint
  133. row_undo_ins_remove_sec(
  134. /*====================*/
  135. /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
  136. dict_index_t* index, /* in: index */
  137. dtuple_t* entry) /* in: index entry to insert */
  138. {
  139. ulint err;
  140. ulint n_tries = 0;
  141. /* Try first optimistic descent to the B-tree */
  142. err = row_undo_ins_remove_sec_low(BTR_MODIFY_LEAF, index, entry);
  143. if (err == DB_SUCCESS) {
  144. return(err);
  145. }
  146. /* Try then pessimistic descent to the B-tree */
  147. retry:
  148. err = row_undo_ins_remove_sec_low(BTR_MODIFY_TREE, index, entry);
  149. /* The delete operation may fail if we have little
  150. file space left: TODO: easiest to crash the database
  151. and restart with more file space */
  152. if (err != DB_SUCCESS && n_tries < BTR_CUR_RETRY_DELETE_N_TIMES) {
  153. n_tries++;
  154. os_thread_sleep(BTR_CUR_RETRY_SLEEP_TIME);
  155. goto retry;
  156. }
  157. return(err);
  158. }
  159. /***************************************************************
  160. Parses the row reference and other info in a fresh insert undo record. */
  161. static
  162. void
  163. row_undo_ins_parse_undo_rec(
  164. /*========================*/
  165. undo_node_t* node) /* in: row undo node */
  166. {
  167. dict_index_t* clust_index;
  168. byte* ptr;
  169. dulint undo_no;
  170. dulint table_id;
  171. ulint type;
  172. ulint dummy;
  173. ibool dummy_extern;
  174. ut_ad(node);
  175. ptr = trx_undo_rec_get_pars(node->undo_rec, &type, &dummy,
  176. &dummy_extern, &undo_no, &table_id);
  177. ut_ad(type == TRX_UNDO_INSERT_REC);
  178. node->rec_type = type;
  179. node->table = dict_table_get_on_id(table_id, node->trx);
  180. if (node->table == NULL) {
  181. return;
  182. }
  183. if (node->table->ibd_file_missing) {
  184. /* We skip undo operations to missing .ibd files */
  185. node->table = NULL;
  186. return;
  187. }
  188. clust_index = dict_table_get_first_index(node->table);
  189. ptr = trx_undo_rec_get_row_ref(ptr, clust_index, &(node->ref),
  190. node->heap);
  191. }
  192. /***************************************************************
  193. Undoes a fresh insert of a row to a table. A fresh insert means that
  194. the same clustered index unique key did not have any record, even delete
  195. marked, at the time of the insert. */
  196. ulint
  197. row_undo_ins(
  198. /*=========*/
  199. /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
  200. undo_node_t* node) /* in: row undo node */
  201. {
  202. dtuple_t* entry;
  203. ibool found;
  204. ulint err;
  205. ut_ad(node);
  206. ut_ad(node->state == UNDO_NODE_INSERT);
  207. row_undo_ins_parse_undo_rec(node);
  208. if (node->table == NULL) {
  209.    found = FALSE;
  210. } else {
  211.    found = row_undo_search_clust_to_pcur(node);
  212. }
  213. if (!found) {
  214.         trx_undo_rec_release(node->trx, node->undo_no);
  215. return(DB_SUCCESS);
  216. }
  217. node->index = dict_table_get_next_index(
  218. dict_table_get_first_index(node->table));
  219. while (node->index != NULL) {
  220. entry = row_build_index_entry(node->row, node->index,
  221. node->heap);
  222. err = row_undo_ins_remove_sec(node->index, entry);
  223. if (err != DB_SUCCESS) {
  224. return(err);
  225. }
  226. node->index = dict_table_get_next_index(node->index);
  227. }
  228. err = row_undo_ins_remove_clust_rec(node);
  229. return(err);
  230. }