📄 row0umod.c
字号:
return(err); } err = row_undo_mod_del_mark_or_remove_sec_low(node, thr, index, entry, BTR_MODIFY_TREE); return(err);}/***************************************************************Delete unmarks a secondary index entry which must be found. It might not bedelete-marked at the moment, but it does not harm to unmark it anyway. We alsoneed to update the fields of the secondary index record if we updated itsfields but alphabetically they stayed the same, e.g., 'abc' -> 'aBc'. */staticulintrow_undo_mod_del_unmark_sec_and_undo_update(/*========================================*/ /* out: DB_FAIL or DB_SUCCESS or DB_OUT_OF_FILE_SPACE */ ulint mode, /* in: search mode: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */ que_thr_t* thr, /* in: query thread */ dict_index_t* index, /* in: index */ dtuple_t* entry) /* in: index entry */{ mem_heap_t* heap; btr_pcur_t pcur; upd_t* update; ulint err = DB_SUCCESS; ibool found; big_rec_t* dummy_big_rec; mtr_t mtr; trx_t* trx = thr_get_trx(thr); log_free_check(); mtr_start(&mtr); found = row_search_index_entry(index, entry, mode, &pcur, &mtr); if (!found) { fputs("InnoDB: error in sec index entry del undo in\n" "InnoDB: ", stderr); dict_index_name_print(stderr, trx, index); fputs("\n" "InnoDB: tuple ", stderr); dtuple_print(stderr, entry); fputs("\n" "InnoDB: record ", stderr); rec_print(stderr, btr_pcur_get_rec(&pcur), index); putc('\n', stderr); trx_print(stderr, trx, 0); fputs("\n""InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", stderr); } else { btr_cur_t* btr_cur = btr_pcur_get_btr_cur(&pcur); err = btr_cur_del_mark_set_sec_rec(BTR_NO_LOCKING_FLAG, btr_cur, FALSE, thr, &mtr); ut_a(err == DB_SUCCESS); heap = mem_heap_create(100); update = row_upd_build_sec_rec_difference_binary(index, entry, btr_cur_get_rec(btr_cur), trx, heap); if (upd_get_n_fields(update) == 0) { /* Do nothing */ } else if (mode == BTR_MODIFY_LEAF) { /* Try an optimistic updating of the record, keeping changes within the page */ err = btr_cur_optimistic_update(BTR_KEEP_SYS_FLAG | BTR_NO_LOCKING_FLAG, btr_cur, update, 0, thr, &mtr); if (err == DB_OVERFLOW || err == DB_UNDERFLOW) { err = DB_FAIL; } } else { ut_a(mode == BTR_MODIFY_TREE); err = btr_cur_pessimistic_update(BTR_KEEP_SYS_FLAG | BTR_NO_LOCKING_FLAG, btr_cur, &dummy_big_rec, update, 0, thr, &mtr); } mem_heap_free(heap); } btr_pcur_close(&pcur); mtr_commit(&mtr); return(err);}/***************************************************************Undoes a modify in secondary indexes when undo record type is UPD_DEL. */staticulintrow_undo_mod_upd_del_sec(/*=====================*/ /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */ undo_node_t* node, /* in: row undo node */ que_thr_t* thr) /* in: query thread */{ mem_heap_t* heap; dtuple_t* entry; dict_index_t* index; ulint err; heap = mem_heap_create(1024); while (node->index != NULL) { index = node->index; entry = row_build_index_entry(node->row, index, heap); err = row_undo_mod_del_mark_or_remove_sec(node, thr, index, entry); if (err != DB_SUCCESS) { mem_heap_free(heap); return(err); } node->index = dict_table_get_next_index(node->index); } mem_heap_free(heap); return(DB_SUCCESS);}/***************************************************************Undoes a modify in secondary indexes when undo record type is DEL_MARK. */staticulintrow_undo_mod_del_mark_sec(/*======================*/ /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */ undo_node_t* node, /* in: row undo node */ que_thr_t* thr) /* in: query thread */{ mem_heap_t* heap; dtuple_t* entry; dict_index_t* index; ulint err; heap = mem_heap_create(1024); while (node->index != NULL) { index = node->index; entry = row_build_index_entry(node->row, index, heap); err = row_undo_mod_del_unmark_sec_and_undo_update( BTR_MODIFY_LEAF, thr, index, entry); if (err == DB_FAIL) { err = row_undo_mod_del_unmark_sec_and_undo_update( BTR_MODIFY_TREE, thr, index, entry); } if (err != DB_SUCCESS) { mem_heap_free(heap); return(err); } node->index = dict_table_get_next_index(node->index); } mem_heap_free(heap); return(DB_SUCCESS);}/***************************************************************Undoes a modify in secondary indexes when undo record type is UPD_EXIST. */staticulintrow_undo_mod_upd_exist_sec(/*=======================*/ /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */ undo_node_t* node, /* in: row undo node */ que_thr_t* thr) /* in: query thread */{ mem_heap_t* heap; dtuple_t* entry; dict_index_t* index; ulint err; if (node->cmpl_info & UPD_NODE_NO_ORD_CHANGE) { /* No change in secondary indexes */ return(DB_SUCCESS); } heap = mem_heap_create(1024); while (node->index != NULL) { index = node->index; if (row_upd_changes_ord_field_binary(node->row, node->index, node->update)) { /* Build the newest version of the index entry */ entry = row_build_index_entry(node->row, index, heap); /* NOTE that if we updated the fields of a delete-marked secondary index record so that alphabetically they stayed the same, e.g., 'abc' -> 'aBc', we cannot return to the original values because we do not know them. But this should not cause problems because in row0sel.c, in queries we always retrieve the clustered index record or an earlier version of it, if the secondary index record through which we do the search is delete-marked. */ err = row_undo_mod_del_mark_or_remove_sec(node, thr, index, entry); if (err != DB_SUCCESS) { mem_heap_free(heap); return(err); } /* We may have to update the delete mark in the secondary index record of the previous version of the row. We also need to update the fields of the secondary index record if we updated its fields but alphabetically they stayed the same, e.g., 'abc' -> 'aBc'. */ row_upd_index_replace_new_col_vals(entry, index, node->update, NULL); err = row_undo_mod_del_unmark_sec_and_undo_update( BTR_MODIFY_LEAF, thr, index, entry); if (err == DB_FAIL) { err = row_undo_mod_del_unmark_sec_and_undo_update( BTR_MODIFY_TREE, thr, index, entry); } if (err != DB_SUCCESS) { mem_heap_free(heap); return(err); } } node->index = dict_table_get_next_index(node->index); } mem_heap_free(heap); return(DB_SUCCESS);}/***************************************************************Parses the row reference and other info in a modify undo log record. */staticvoidrow_undo_mod_parse_undo_rec(/*========================*/ undo_node_t* node, /* in: row undo node */ que_thr_t* thr) /* in: query thread */{ dict_index_t* clust_index; byte* ptr; dulint undo_no; dulint table_id; dulint trx_id; dulint roll_ptr; ulint info_bits; ulint type; ulint cmpl_info; ibool dummy_extern; trx_t* trx; ut_ad(node && thr); trx = thr_get_trx(thr); ptr = trx_undo_rec_get_pars(node->undo_rec, &type, &cmpl_info, &dummy_extern, &undo_no, &table_id); node->rec_type = type; node->table = dict_table_get_on_id(table_id, trx); /* TODO: other fixes associated with DROP TABLE + rollback in the same table by another user */ if (node->table == NULL) { /* Table was dropped */ return; } if (node->table->ibd_file_missing) { /* We skip undo operations to missing .ibd files */ node->table = NULL; return; } clust_index = dict_table_get_first_index(node->table); ptr = trx_undo_update_rec_get_sys_cols(ptr, &trx_id, &roll_ptr, &info_bits); ptr = trx_undo_rec_get_row_ref(ptr, clust_index, &(node->ref), node->heap); trx_undo_update_rec_get_update(ptr, clust_index, type, trx_id, roll_ptr, info_bits, trx, node->heap, &(node->update)); node->new_roll_ptr = roll_ptr; node->new_trx_id = trx_id; node->cmpl_info = cmpl_info;} /***************************************************************Undoes a modify operation on a row of a table. */ulintrow_undo_mod(/*=========*/ /* out: DB_SUCCESS or error code */ undo_node_t* node, /* in: row undo node */ que_thr_t* thr) /* in: query thread */{ ibool found; ulint err; ut_ad(node && thr); ut_ad(node->state == UNDO_NODE_MODIFY); row_undo_mod_parse_undo_rec(node, thr); if (node->table == NULL) { found = FALSE; } else { found = row_undo_search_clust_to_pcur(node); } if (!found) { /* It is already undone, or will be undone by another query thread, or table was dropped */ trx_undo_rec_release(node->trx, node->undo_no); node->state = UNDO_NODE_FETCH_NEXT; return(DB_SUCCESS); } node->index = dict_table_get_next_index( dict_table_get_first_index(node->table)); if (node->rec_type == TRX_UNDO_UPD_EXIST_REC) { err = row_undo_mod_upd_exist_sec(node, thr); } else if (node->rec_type == TRX_UNDO_DEL_MARK_REC) { err = row_undo_mod_del_mark_sec(node, thr); } else { ut_ad(node->rec_type == TRX_UNDO_UPD_DEL_REC); err = row_undo_mod_upd_del_sec(node, thr); } if (err != DB_SUCCESS) { return(err); } err = row_undo_mod_clust(node, thr); return(err);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -