diff options
Diffstat (limited to 'storage/innobase/row')
-rw-r--r-- | storage/innobase/row/row0ins.cc | 8 | ||||
-rw-r--r-- | storage/innobase/row/row0merge.cc | 3 | ||||
-rw-r--r-- | storage/innobase/row/row0mysql.cc | 3 | ||||
-rw-r--r-- | storage/innobase/row/row0purge.cc | 42 | ||||
-rw-r--r-- | storage/innobase/row/row0sel.cc | 23 | ||||
-rw-r--r-- | storage/innobase/row/row0umod.cc | 4 | ||||
-rw-r--r-- | storage/innobase/row/row0upd.cc | 31 | ||||
-rw-r--r-- | storage/innobase/row/row0vers.cc | 3 |
8 files changed, 76 insertions, 41 deletions
diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 123566132f4..b0401485bab 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -970,11 +970,9 @@ row_ins_foreign_fill_virtual( innobase_init_vc_templ(index->table); } - if (innobase_allocate_row_for_vcol(thd, index, &v_heap, - &mysql_table, - &record, &vcol_storage)) { - if (v_heap) mem_heap_free(v_heap); - *err = DB_OUT_OF_MEMORY; + if ((*err = innobase_allocate_row_for_vcol(thd, index, v_heap, + &mysql_table, + &record, &vcol_storage))) { goto func_exit; } diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 8c8f1674374..99f866a732d 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -595,8 +595,7 @@ row_merge_buf_add( = dict_table_get_first_index(new_table); if (!vcol_storage && - innobase_allocate_row_for_vcol(trx->mysql_thd, clust_index, v_heap, &my_table, &record, &vcol_storage)) { - *err = DB_OUT_OF_MEMORY; + (*err = innobase_allocate_row_for_vcol(trx->mysql_thd, clust_index, *v_heap, &my_table, &record, &vcol_storage))) { goto error; } diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 9bbd531cb9a..5fc14c7fad2 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -781,6 +781,9 @@ handle_new_error: << FK_MAX_CASCADE_DEL << ". Please drop excessive" " foreign constraints and try again"; goto rollback_to_savept; + case DB_OUT_OF_MEMORY: + ib::fatal() << "Out of memory"; + break; default: ib::fatal() << "Unknown error code " << err << ": " << ut_strerr(err); diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc index f4fd617f154..8f9756bdc53 100644 --- a/storage/innobase/row/row0purge.cc +++ b/storage/innobase/row/row0purge.cc @@ -284,6 +284,7 @@ row_purge_poss_sec( purge_node_t* node, dict_index_t* index, const dtuple_t* entry, + dberr_t& err, btr_pcur_t* sec_pcur, mtr_t* sec_mtr, bool is_tree) @@ -318,7 +319,10 @@ retry_purge_sec: btr_pcur_get_rec(&node->pcur), &mtr, index, entry, node->roll_ptr, node->trx_id, - &node->vcol_info); + err, &node->vcol_info); + if (err) { + return false; + } if (node->vcol_info.is_first_fetch()) { ut_ad(store_cur); @@ -375,11 +379,11 @@ row_purge_remove_sec_if_poss_tree( /*==============================*/ purge_node_t* node, /*!< in: row purge node */ dict_index_t* index, /*!< in: index */ - const dtuple_t* entry) /*!< in: index entry */ + const dtuple_t* entry, /*!< in: index entry */ + dberr_t& err) { btr_pcur_t pcur; ibool success = TRUE; - dberr_t err; mtr_t mtr; enum row_search_result search_result; @@ -442,7 +446,7 @@ row_purge_remove_sec_if_poss_tree( which cannot be purged yet, requires its existence. If some requires, we should do nothing. */ - if (row_purge_poss_sec(node, index, entry, &pcur, &mtr, true)) { + if (row_purge_poss_sec(node, index, entry, err, &pcur, &mtr, true)) { /* Remove the index record, which should have been marked for deletion. */ @@ -476,6 +480,8 @@ row_purge_remove_sec_if_poss_tree( default: ut_error; } + } else { + success = false; } if (node->vcol_op_failed()) { @@ -510,6 +516,7 @@ row_purge_remove_sec_if_poss_leaf( btr_pcur_t pcur; enum btr_latch_mode mode; enum row_search_result search_result; + dberr_t err = DB_SUCCESS; bool success = true; log_free_check(); @@ -576,7 +583,7 @@ row_purge_remove_sec_if_poss_leaf( case ROW_FOUND: /* Before attempting to purge a record, check if it is safe to do so. */ - if (row_purge_poss_sec(node, index, entry, &pcur, &mtr, false)) { + if (row_purge_poss_sec(node, index, entry, err, &pcur, &mtr, false)) { btr_cur_t* btr_cur = btr_pcur_get_btr_cur(&pcur); /* Only delete-marked records should be purged. */ @@ -643,7 +650,7 @@ row_purge_remove_sec_if_poss_leaf( } } - if (node->vcol_op_failed()) { + if (err || node->vcol_op_failed()) { btr_pcur_close(&pcur); return false; } @@ -670,7 +677,7 @@ func_exit_no_pcur: /***********************************************************//** Removes a secondary index entry if possible. */ UNIV_INLINE MY_ATTRIBUTE((nonnull(1,2))) -void +dberr_t row_purge_remove_sec_if_poss( /*=========================*/ purge_node_t* node, /*!< in: row purge node */ @@ -678,6 +685,7 @@ row_purge_remove_sec_if_poss( const dtuple_t* entry) /*!< in: index entry */ { ibool success; + dberr_t err = DB_SUCCESS; ulint n_tries = 0; /* fputs("Purge: Removing secondary record\n", stderr); */ @@ -686,19 +694,19 @@ row_purge_remove_sec_if_poss( /* The node->row must have lacked some fields of this index. This is possible when the undo log record was written before this index was created. */ - return; + return err; } if (row_purge_remove_sec_if_poss_leaf(node, index, entry)) { - return; + return err; } retry: if (node->vcol_op_failed()) { - return; + return err; } - success = row_purge_remove_sec_if_poss_tree(node, index, entry); + success = row_purge_remove_sec_if_poss_tree(node, index, entry, err); /* The delete operation may fail if we have little file space left: TODO: easiest to crash the database and restart with more file space */ @@ -712,7 +720,8 @@ retry: goto retry; } - ut_a(success); + ut_a(success || err); + return err; } /** Skip uncommitted virtual indexes on newly added virtual column. @@ -763,9 +772,10 @@ row_purge_del_mark( dtuple_t* entry = row_build_index_entry_low( node->row, NULL, node->index, heap, ROW_BUILD_FOR_PURGE); - row_purge_remove_sec_if_poss(node, node->index, entry); - if (node->vcol_op_failed()) { + + if (row_purge_remove_sec_if_poss(node, node->index, entry) + || node->vcol_op_failed()) { mem_heap_free(heap); return false; } @@ -823,9 +833,9 @@ row_purge_upd_exist_or_extern_func( dtuple_t* entry = row_build_index_entry_low( node->row, NULL, node->index, heap, ROW_BUILD_FOR_PURGE); - row_purge_remove_sec_if_poss(node, node->index, entry); - if (node->vcol_op_failed()) { + if (row_purge_remove_sec_if_poss(node, node->index, entry) + || node->vcol_op_failed()) { ut_ad(!node->table); mem_heap_free(heap); return; diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc index 15486500b37..74b48bd799c 100644 --- a/storage/innobase/row/row0sel.cc +++ b/storage/innobase/row/row0sel.cc @@ -164,6 +164,7 @@ row_sel_sec_rec_is_for_clust_rec( dict_index_t* sec_index, const rec_t* clust_rec, dict_index_t* clust_index, + dberr_t& err, que_thr_t* thr) { const byte* sec_field; @@ -179,6 +180,7 @@ row_sel_sec_rec_is_for_clust_rec( ibool is_equal = TRUE; VCOL_STORAGE* vcol_storage= 0; byte* record; + err = DB_SUCCESS; rec_offs_init(clust_offsets_); rec_offs_init(sec_offsets_); @@ -228,12 +230,15 @@ row_sel_sec_rec_is_for_clust_rec( if (!vcol_storage) { TABLE *mysql_table= thr->prebuilt->m_mysql_table; - innobase_allocate_row_for_vcol(thr_get_trx(thr)->mysql_thd, + err = innobase_allocate_row_for_vcol(thr_get_trx(thr)->mysql_thd, clust_index, - &heap, + heap, &mysql_table, &record, &vcol_storage); + if (err) { + return false; + } } v_col = reinterpret_cast<const dict_v_col_t*>(col); @@ -1035,8 +1040,12 @@ row_sel_get_clust_rec( plan->table))) && !row_sel_sec_rec_is_for_clust_rec(rec, plan->index, clust_rec, index, - thr)) { - goto func_exit; + err, thr)) { + if (!err) { + goto func_exit; + } else { + goto err_exit; + } } } @@ -3581,8 +3590,12 @@ Row_sel_get_clust_rec_for_mysql::operator()( || rec_get_deleted_flag(rec, dict_table_is_comp( sec_index->table))) && !row_sel_sec_rec_is_for_clust_rec( - rec, sec_index, clust_rec, clust_index, thr)) { + rec, sec_index, clust_rec, clust_index, err, thr)) { clust_rec = NULL; + if (err) { + goto err_exit; + } + } err = DB_SUCCESS; diff --git a/storage/innobase/row/row0umod.cc b/storage/innobase/row/row0umod.cc index ac4500f5c3e..8b5c7aad8a3 100644 --- a/storage/innobase/row/row0umod.cc +++ b/storage/innobase/row/row0umod.cc @@ -511,11 +511,11 @@ row_undo_mod_del_mark_or_remove_sec_low( if (dict_table_is_temporary(node->table) || row_vers_old_has_index_entry( false, btr_pcur_get_rec(&(node->pcur)), - &mtr_vers, index, entry, 0, 0)) { + &mtr_vers, index, entry, 0, 0, err)) { err = btr_cur_del_mark_set_sec_rec(BTR_NO_LOCKING_FLAG, btr_cur, TRUE, thr, &mtr); ut_ad(err == DB_SUCCESS); - } else { + } else if (!err) { /* Remove the index record */ if (dict_index_is_spatial(index)) { diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc index a316041ed0e..1a47d27affc 100644 --- a/storage/innobase/row/row0upd.cc +++ b/storage/innobase/row/row0upd.cc @@ -1130,9 +1130,9 @@ row_upd_build_difference_binary( ut_ad(!update->old_vrow); - innobase_allocate_row_for_vcol(thd, index, &v_heap, - &mysql_table, - &record, &vcol_storage); + *error = innobase_allocate_row_for_vcol(thd, index, v_heap, + &mysql_table, + &record, &vcol_storage); for (i = 0; i < n_v_fld; i++) { const dict_v_col_t* col @@ -2117,7 +2117,7 @@ row_upd_eval_new_vals( @param[in] thd mysql thread handle @param[in,out] mysql_table mysql table object */ static -void +dberr_t row_upd_store_v_row( upd_node_t* node, const upd_t* update, @@ -2129,9 +2129,13 @@ row_upd_store_v_row( byte* record= 0; VCOL_STORAGE *vcol_storage= 0; - if (!update) - innobase_allocate_row_for_vcol(thd, index, &heap, &mysql_table, + if (!update) { + dberr_t err = innobase_allocate_row_for_vcol(thd, index, heap, &mysql_table, &record, &vcol_storage); + if (err) { + return err; + } + } for (ulint col_no = 0; col_no < dict_table_get_n_v_cols(node->table); col_no++) { @@ -2198,7 +2202,7 @@ row_upd_store_v_row( innobase_free_row_for_vcol(vcol_storage); mem_heap_free(heap); } - + return DB_SUCCESS; } /** Stores to the heap the row on which the node->pcur is positioned. @@ -2207,7 +2211,7 @@ row_upd_store_v_row( @param[in,out] mysql_table NULL, or mysql table object when user thread invokes dml */ static -void +dberr_t row_upd_store_row( upd_node_t* node, THD* thd, @@ -2219,6 +2223,7 @@ row_upd_store_row( row_ext_t** ext; rec_offs offsets_[REC_OFFS_NORMAL_SIZE]; const rec_offs* offsets; + dberr_t err = DB_SUCCESS; rec_offs_init(offsets_); ut_ad(node->pcur->latch_mode != BTR_NO_LATCHES); @@ -2251,8 +2256,11 @@ row_upd_store_row( NULL, NULL, NULL, ext, node->heap); if (node->table->n_v_cols) { - row_upd_store_v_row(node, node->is_delete ? NULL : node->update, + err = row_upd_store_v_row(node, node->is_delete ? NULL : node->update, thd, mysql_table); + if (err) { + goto err_exit; + } } if (node->is_delete) { @@ -2264,9 +2272,12 @@ row_upd_store_row( clust_index, node->update, node->heap); } + +err_exit: if (UNIV_LIKELY_NULL(heap)) { mem_heap_free(heap); } + return err; } /***********************************************************//** @@ -2982,7 +2993,7 @@ row_upd_del_mark_clust_rec( /* Store row because we have to build also the secondary index entries */ - row_upd_store_row(node, trx->mysql_thd, + err = row_upd_store_row(node, trx->mysql_thd, thr->prebuilt && thr->prebuilt->table == node->table ? thr->prebuilt->m_mysql_table : NULL); diff --git a/storage/innobase/row/row0vers.cc b/storage/innobase/row/row0vers.cc index 3627c659231..544c9aad313 100644 --- a/storage/innobase/row/row0vers.cc +++ b/storage/innobase/row/row0vers.cc @@ -470,7 +470,7 @@ row_vers_build_clust_v_col( } innobase_allocate_row_for_vcol(thd, index, - &local_heap, + local_heap, &maria_table, &record, &vcol_storage); @@ -887,6 +887,7 @@ row_vers_old_has_index_entry( const dtuple_t* ientry, roll_ptr_t roll_ptr, trx_id_t trx_id, + dberr_t& err, purge_vcol_info_t* vcol_info) { const rec_t* version; |