summaryrefslogtreecommitdiff
path: root/storage/xtradb/row
diff options
context:
space:
mode:
authorMichael Widenius <monty@askmonty.org>2011-05-10 18:17:43 +0300
committerMichael Widenius <monty@askmonty.org>2011-05-10 18:17:43 +0300
commitf34be1893892745b5b1a7a099eab4ad8e9ac8641 (patch)
treed7eed818fd8b648e5eabe0dbad53e61665d8dc37 /storage/xtradb/row
parente843297d128b165125d17aab8958f7ca91808923 (diff)
parent8882d71f3f1dd03ef98d072def39b29e6a03f5b8 (diff)
downloadmariadb-git-f34be1893892745b5b1a7a099eab4ad8e9ac8641.tar.gz
Merge with MariaDB 5.2
Diffstat (limited to 'storage/xtradb/row')
-rw-r--r--storage/xtradb/row/row0ins.c4
-rw-r--r--storage/xtradb/row/row0mysql.c27
-rw-r--r--storage/xtradb/row/row0purge.c68
-rw-r--r--storage/xtradb/row/row0row.c16
-rw-r--r--storage/xtradb/row/row0umod.c35
-rw-r--r--storage/xtradb/row/row0upd.c65
-rw-r--r--storage/xtradb/row/row0vers.c10
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. */