diff options
author | Michael Widenius <monty@askmonty.org> | 2011-05-10 18:17:43 +0300 |
---|---|---|
committer | Michael Widenius <monty@askmonty.org> | 2011-05-10 18:17:43 +0300 |
commit | f34be1893892745b5b1a7a099eab4ad8e9ac8641 (patch) | |
tree | d7eed818fd8b648e5eabe0dbad53e61665d8dc37 /storage/xtradb/row | |
parent | e843297d128b165125d17aab8958f7ca91808923 (diff) | |
parent | 8882d71f3f1dd03ef98d072def39b29e6a03f5b8 (diff) | |
download | mariadb-git-f34be1893892745b5b1a7a099eab4ad8e9ac8641.tar.gz |
Merge with MariaDB 5.2
Diffstat (limited to 'storage/xtradb/row')
-rw-r--r-- | storage/xtradb/row/row0ins.c | 4 | ||||
-rw-r--r-- | storage/xtradb/row/row0mysql.c | 27 | ||||
-rw-r--r-- | storage/xtradb/row/row0purge.c | 68 | ||||
-rw-r--r-- | storage/xtradb/row/row0row.c | 16 | ||||
-rw-r--r-- | storage/xtradb/row/row0umod.c | 35 | ||||
-rw-r--r-- | storage/xtradb/row/row0upd.c | 65 | ||||
-rw-r--r-- | storage/xtradb/row/row0vers.c | 10 |
7 files changed, 140 insertions, 85 deletions
diff --git a/storage/xtradb/row/row0ins.c b/storage/xtradb/row/row0ins.c index 3372e1480b5..efcea62f212 100644 --- a/storage/xtradb/row/row0ins.c +++ b/storage/xtradb/row/row0ins.c @@ -2026,6 +2026,8 @@ row_ins_index_entry_low( } #ifdef UNIV_DEBUG + if (!srv_use_sys_stats_table + || index != UT_LIST_GET_FIRST(dict_sys->sys_stats->indexes)) { page_t* page = btr_cur_get_page(&cursor); rec_t* first_rec = page_rec_get_next( @@ -2136,7 +2138,7 @@ function_exit: err = btr_store_big_rec_extern_fields( index, btr_cur_get_block(&cursor), - rec, offsets, big_rec, &mtr); + rec, offsets, &mtr, FALSE, big_rec); if (modify) { dtuple_big_rec_free(big_rec); diff --git a/storage/xtradb/row/row0mysql.c b/storage/xtradb/row/row0mysql.c index 205aead8efe..1b97cbb0009 100644 --- a/storage/xtradb/row/row0mysql.c +++ b/storage/xtradb/row/row0mysql.c @@ -52,6 +52,7 @@ Created 9/17/2000 Heikki Tuuri #include "btr0sea.h" #include "fil0fil.h" #include "ibuf0ibuf.h" +#include "ha_prototypes.h" /** Provide optional 4.x backwards compatibility for 5.0 and above */ UNIV_INTERN ibool row_rollback_on_timeout = FALSE; @@ -2096,6 +2097,32 @@ row_insert_stats_for_mysql( } /*********************************************************************//** +*/ +UNIV_INTERN +int +row_delete_stats_for_mysql( +/*=============================*/ + dict_index_t* index, + trx_t* trx) +{ + pars_info_t* info = pars_info_create(); + + trx->op_info = "delete rows from SYS_STATS"; + + trx_start_if_not_started(trx); + trx->error_state = DB_SUCCESS; + + pars_info_add_dulint_literal(info, "indexid", index->id); + + return((int) que_eval_sql(info, + "PROCEDURE DELETE_STATISTICS_PROC () IS\n" + "BEGIN\n" + "DELETE FROM SYS_STATS WHERE INDEX_ID = :indexid;\n" + "END;\n" + , TRUE, trx)); +} + +/*********************************************************************//** Scans a table create SQL string and adds to the data dictionary the foreign key constraints declared in the string. This function should be called after the indexes for a table have been created. diff --git a/storage/xtradb/row/row0purge.c b/storage/xtradb/row/row0purge.c index 8bf2ae0f458..752a2ec9e83 100644 --- a/storage/xtradb/row/row0purge.c +++ b/storage/xtradb/row/row0purge.c @@ -387,8 +387,11 @@ Purges an update of an existing record. Also purges an update of a delete marked record if that record contained an externally stored field. */ static void -row_purge_upd_exist_or_extern( -/*==========================*/ +row_purge_upd_exist_or_extern_func( +/*===============================*/ +#ifdef UNIV_DEBUG + const que_thr_t*thr, /*!< in: query thread */ +#endif /* UNIV_DEBUG */ purge_node_t* node) /*!< in: row purge node */ { mem_heap_t* heap; @@ -413,8 +416,8 @@ row_purge_upd_exist_or_extern( while (node->index != NULL) { index = node->index; - if (row_upd_changes_ord_field_binary(NULL, NULL, node->index, - node->update)) { + if (row_upd_changes_ord_field_binary(node->index, node->update, + thr, NULL, NULL)) { /* Build the older version of the index entry */ entry = row_build_index_entry(node->row, NULL, index, heap); @@ -496,6 +499,14 @@ skip_secondaries: } } +#ifdef UNIV_DEBUG +# define row_purge_upd_exist_or_extern(thr,node) \ + row_purge_upd_exist_or_extern_func(thr,node) +#else /* UNIV_DEBUG */ +# define row_purge_upd_exist_or_extern(thr,node) \ + row_purge_upd_exist_or_extern_func(node) +#endif /* UNIV_DEBUG */ + /***********************************************************//** Parses the row reference and other info in a modify undo log record. @return TRUE if purge operation required: NOTE that then the CALLER @@ -602,47 +613,32 @@ err_exit: /***********************************************************//** Fetches an undo log record and does the purge for the recorded operation. If none left, or the current purge completed, returns the control to the -parent node, which is always a query thread node. -@return DB_SUCCESS if operation successfully completed, else error code */ -static -ulint +parent node, which is always a query thread node. */ +static __attribute__((nonnull)) +void row_purge( /*======*/ purge_node_t* node, /*!< in: row purge node */ que_thr_t* thr) /*!< in: query thread */ { - roll_ptr_t roll_ptr; - ibool purge_needed; ibool updated_extern; - trx_t* trx; - ut_ad(node && thr); - - trx = thr_get_trx(thr); + ut_ad(node); + ut_ad(thr); - node->undo_rec = trx_purge_fetch_next_rec(&roll_ptr, - &(node->reservation), + node->undo_rec = trx_purge_fetch_next_rec(&node->roll_ptr, + &node->reservation, node->heap); if (!node->undo_rec) { /* Purge completed for this query thread */ thr->run_node = que_node_get_parent(node); - return(DB_SUCCESS); - } - - node->roll_ptr = roll_ptr; - - if (node->undo_rec == &trx_purge_dummy_rec) { - purge_needed = FALSE; - } else { - purge_needed = row_purge_parse_undo_rec(node, &updated_extern, - thr); - /* If purge_needed == TRUE, we must also remember to unfreeze - data dictionary! */ + return; } - if (purge_needed) { + if (node->undo_rec != &trx_purge_dummy_rec + && row_purge_parse_undo_rec(node, &updated_extern, thr)) { node->found_clust = FALSE; node->index = dict_table_get_next_index( @@ -654,14 +650,14 @@ row_purge( } else if (updated_extern || node->rec_type == TRX_UNDO_UPD_EXIST_REC) { - row_purge_upd_exist_or_extern(node); + row_purge_upd_exist_or_extern(thr, node); } if (node->found_clust) { btr_pcur_close(&(node->pcur)); } - row_mysql_unfreeze_data_dictionary(trx); + row_mysql_unfreeze_data_dictionary(thr_get_trx(thr)); } /* Do some cleanup */ @@ -669,8 +665,6 @@ row_purge( mem_heap_empty(node->heap); thr->run_node = node; - - return(DB_SUCCESS); } /***********************************************************//** @@ -684,9 +678,6 @@ row_purge_step( que_thr_t* thr) /*!< in: query thread */ { purge_node_t* node; -#ifdef UNIV_DEBUG - ulint err; -#endif /* UNIV_DEBUG */ ut_ad(thr); @@ -694,12 +685,7 @@ row_purge_step( ut_ad(que_node_get_type(node) == QUE_NODE_PURGE); -#ifdef UNIV_DEBUG - err = -#endif /* UNIV_DEBUG */ row_purge(node, thr); - ut_ad(err == DB_SUCCESS); - return(thr); } diff --git a/storage/xtradb/row/row0row.c b/storage/xtradb/row/row0row.c index 8e806a14a98..0783d482f76 100644 --- a/storage/xtradb/row/row0row.c +++ b/storage/xtradb/row/row0row.c @@ -347,6 +347,14 @@ row_rec_to_index_entry_low( rec_len = rec_offs_n_fields(offsets); + if (srv_use_sys_stats_table + && index == UT_LIST_GET_FIRST(dict_sys->sys_stats->indexes)) { + if (rec_len < dict_index_get_n_fields(index)) { + /* the new record should be extended */ + rec_len = dict_index_get_n_fields(index); + } + } + entry = dtuple_create(heap, rec_len); dtuple_set_n_fields_cmp(entry, @@ -358,6 +366,14 @@ row_rec_to_index_entry_low( for (i = 0; i < rec_len; i++) { dfield = dtuple_get_nth_field(entry, i); + + if (srv_use_sys_stats_table + && index == UT_LIST_GET_FIRST(dict_sys->sys_stats->indexes) + && i >= rec_offs_n_fields(offsets)) { + dfield_set_null(dfield); + continue; + } + field = rec_get_nth_field(rec, offsets, i, &len); dfield_set_data(dfield, field, len); diff --git a/storage/xtradb/row/row0umod.c b/storage/xtradb/row/row0umod.c index 562f8093c38..5202a498eed 100644 --- a/storage/xtradb/row/row0umod.c +++ b/storage/xtradb/row/row0umod.c @@ -173,40 +173,26 @@ row_undo_mod_remove_clust_low( mtr_t* mtr, /*!< in: mtr */ ulint mode) /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */ { - btr_pcur_t* pcur; btr_cur_t* btr_cur; ulint err; - ibool success; ut_ad(node->rec_type == TRX_UNDO_UPD_DEL_REC); - pcur = &(node->pcur); - btr_cur = btr_pcur_get_btr_cur(pcur); - success = btr_pcur_restore_position(mode, pcur, mtr); + /* Find out if the record has been purged already + or if we can remove it. */ - if (!success) { + if (!btr_pcur_restore_position(mode, &node->pcur, mtr) + || row_vers_must_preserve_del_marked(node->new_trx_id, mtr)) { return(DB_SUCCESS); } - /* Find out if we can remove the whole clustered index record */ - - if (node->rec_type == TRX_UNDO_UPD_DEL_REC - && !row_vers_must_preserve_del_marked(node->new_trx_id, mtr)) { - - /* Ok, we can remove */ - } else { - return(DB_SUCCESS); - } + btr_cur = btr_pcur_get_btr_cur(&node->pcur); if (mode == BTR_MODIFY_LEAF) { - success = btr_cur_optimistic_delete(btr_cur, mtr); - - if (success) { - err = DB_SUCCESS; - } else { - err = DB_FAIL; - } + err = btr_cur_optimistic_delete(btr_cur, mtr) + ? DB_SUCCESS + : DB_FAIL; } else { ut_ad(mode == BTR_MODIFY_TREE); @@ -668,8 +654,9 @@ row_undo_mod_upd_exist_sec( while (node->index != NULL) { index = node->index; - if (row_upd_changes_ord_field_binary( - node->row, node->ext, node->index, node->update)) { + if (row_upd_changes_ord_field_binary(node->index, node->update, + thr, + node->row, node->ext)) { /* Build the newest version of the index entry */ entry = row_build_index_entry(node->row, node->ext, diff --git a/storage/xtradb/row/row0upd.c b/storage/xtradb/row/row0upd.c index e1c78949603..a6fb266c4ed 100644 --- a/storage/xtradb/row/row0upd.c +++ b/storage/xtradb/row/row0upd.c @@ -439,6 +439,12 @@ row_upd_changes_field_size_or_external( 0); } + if (srv_use_sys_stats_table + && index == UT_LIST_GET_FIRST(dict_sys->sys_stats->indexes) + && upd_field->field_no >= rec_offs_n_fields(offsets)) { + return(TRUE); + } + old_len = rec_offs_nth_size(offsets, upd_field->field_no); if (rec_offs_comp(offsets) @@ -844,6 +850,18 @@ row_upd_build_difference_binary( for (i = 0; i < dtuple_get_n_fields(entry); i++) { + if (srv_use_sys_stats_table + && index == UT_LIST_GET_FIRST(dict_sys->sys_stats->indexes) + && i >= rec_offs_n_fields(offsets)) { + dfield = dtuple_get_nth_field(entry, i); + + upd_field = upd_get_nth_field(update, n_diff); + dfield_copy(&(upd_field->new_val), dfield); + upd_field_set_field_no(upd_field, i, index, trx); + n_diff++; + goto skip_compare; + } + data = rec_get_nth_field(rec, offsets, i, &len); dfield = dtuple_get_nth_field(entry, i); @@ -1192,25 +1210,31 @@ NOTE: we compare the fields as binary strings! @return TRUE if update vector changes an ordering field in the index record */ UNIV_INTERN ibool -row_upd_changes_ord_field_binary( -/*=============================*/ +row_upd_changes_ord_field_binary_func( +/*==================================*/ + dict_index_t* index, /*!< in: index of the record */ + const upd_t* update, /*!< in: update vector for the row; NOTE: the + field numbers in this MUST be clustered index + positions! */ +#ifdef UNIV_DEBUG + const que_thr_t*thr, /*!< in: query thread */ +#endif /* UNIV_DEBUG */ const dtuple_t* row, /*!< in: old value of row, or NULL if the row and the data values in update are not known when this function is called, e.g., at compile time */ - const row_ext_t*ext, /*!< NULL, or prefixes of the externally + const row_ext_t*ext) /*!< NULL, or prefixes of the externally stored columns in the old row */ - dict_index_t* index, /*!< in: index of the record */ - const upd_t* update) /*!< in: update vector for the row; NOTE: the - field numbers in this MUST be clustered index - positions! */ { ulint n_unique; ulint i; const dict_index_t* clust_index; - ut_ad(update); ut_ad(index); + ut_ad(update); + ut_ad(thr); + ut_ad(thr->graph); + ut_ad(thr->graph->trx); n_unique = dict_index_get_n_unique(index); @@ -1252,6 +1276,10 @@ row_upd_changes_ord_field_binary( || dfield_is_null(dfield)) { /* do nothing special */ } else if (UNIV_LIKELY_NULL(ext)) { + /* Silence a compiler warning without + silencing a Valgrind error. */ + dfield_len = 0; + UNIV_MEM_INVALID(&dfield_len, sizeof dfield_len); /* See if the column is stored externally. */ buf = row_ext_lookup(ext, col_no, &dfield_len); @@ -1259,9 +1287,14 @@ row_upd_changes_ord_field_binary( if (UNIV_LIKELY_NULL(buf)) { if (UNIV_UNLIKELY(buf == field_ref_zero)) { - /* This should never happen, but - we try to fail safe here. */ - ut_ad(0); + /* The externally stored field + was not written yet. This + record should only be seen by + recv_recovery_rollback_active(), + when the server had crashed before + storing the field. */ + ut_ad(thr->graph->trx->is_recovered); + ut_ad(trx_is_recv(thr->graph->trx)); return(TRUE); } @@ -1608,8 +1641,8 @@ row_upd_sec_step( ut_ad(!dict_index_is_clust(node->index)); if (node->state == UPD_NODE_UPDATE_ALL_SEC - || row_upd_changes_ord_field_binary(node->row, node->ext, - node->index, node->update)) { + || row_upd_changes_ord_field_binary(node->index, node->update, + thr, node->row, node->ext)) { return(row_upd_sec_index_entry(node, thr)); } @@ -1937,7 +1970,7 @@ row_upd_clust_rec( index, btr_cur_get_block(btr_cur), rec, rec_get_offsets(rec, index, offsets_, ULINT_UNDEFINED, &heap), - big_rec, mtr); + mtr, TRUE, big_rec); mtr_commit(mtr); } @@ -2136,8 +2169,8 @@ exit_func: row_upd_store_row(node); - if (row_upd_changes_ord_field_binary(node->row, node->ext, index, - node->update)) { + if (row_upd_changes_ord_field_binary(index, node->update, thr, + node->row, node->ext)) { /* Update causes an ordering field (ordering fields within the B-tree) of the clustered index record to change: perform diff --git a/storage/xtradb/row/row0vers.c b/storage/xtradb/row/row0vers.c index b6d35363f08..d4fde0b939b 100644 --- a/storage/xtradb/row/row0vers.c +++ b/storage/xtradb/row/row0vers.c @@ -669,11 +669,15 @@ row_vers_build_for_semi_consistent_read( mutex_enter(&kernel_mutex); version_trx = trx_get_on_id(version_trx_id); + if (version_trx + && (version_trx->conc_state == TRX_COMMITTED_IN_MEMORY + || version_trx->conc_state == TRX_NOT_STARTED)) { + + version_trx = NULL; + } mutex_exit(&kernel_mutex); - if (!version_trx - || version_trx->conc_state == TRX_NOT_STARTED - || version_trx->conc_state == TRX_COMMITTED_IN_MEMORY) { + if (!version_trx) { /* We found a version that belongs to a committed transaction: return it. */ |