summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@oracle.com>2011-01-31 09:56:51 +0200
committerMarko Mäkelä <marko.makela@oracle.com>2011-01-31 09:56:51 +0200
commite952ee1158be7611f3443bf9e1919652eb3b4602 (patch)
tree494b2a4e293dbf6c75f1d0f44803920fc159604d /storage
parent7751e38cd08e3a53315f195fdf71935e3d2ebbc3 (diff)
downloadmariadb-git-e952ee1158be7611f3443bf9e1919652eb3b4602.tar.gz
Bug#59230 assert 0 row_upd_changes_ord_field_binary() in post-crash
trx rollback or purge This patch does not relax the failing debug assertion during purge. That will be revisited once we have managed to repeat the assertion failure. row_upd_changes_ord_field_binary_func(): Renamed from row_upd_changes_ord_field_binary(). Add the parameter que_thr_t* in UNIV_DEBUG builds. When the off-page column cannot be retrieved, assert that the current transaction is a recovered one and that it is the one that is currently being rolled back. row_upd_changes_ord_field_binary(): A wrapper macro for row_upd_changes_ord_field_binary_func() that discards the que_thr_t* parameter unless UNIV_DEBUG is defined. row_purge_upd_exist_or_extern_func(): Renamed from row_purge_upd_exist_or_extern(). Add the parameter que_thr_t* in UNIV_DEBUG builds. row_purge_upd_exist_or_extern(): A wrapper macro for row_purge_upd_exist_or_extern_func() that discards the que_thr_t* parameter unless UNIV_DEBUG is defined. Make trx_roll_crash_recv_trx const. If there were a 'do not dereference' attribute, it would be appropriate as well. rb://588 approved by Jimmy Yang
Diffstat (limited to 'storage')
-rw-r--r--storage/innodb_plugin/ChangeLog7
-rw-r--r--storage/innodb_plugin/btr/btr0cur.c4
-rw-r--r--storage/innodb_plugin/include/row0upd.h26
-rw-r--r--storage/innodb_plugin/row/row0purge.c21
-rw-r--r--storage/innodb_plugin/row/row0umod.c5
-rw-r--r--storage/innodb_plugin/row/row0upd.c41
-rw-r--r--storage/innodb_plugin/trx/trx0roll.c4
7 files changed, 74 insertions, 34 deletions
diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog
index 18ab48f32a5..0cbdc8ed9d2 100644
--- a/storage/innodb_plugin/ChangeLog
+++ b/storage/innodb_plugin/ChangeLog
@@ -1,3 +1,10 @@
+2011-01-31 The InnoDB Team
+
+ * btr/btr0cur.c, include/row0upd.h,
+ row/row0purge.c, row/row0umod.c, row/row0upd.c:
+ Bug#59230 assert 0 row_upd_changes_ord_field_binary()
+ in post-crash rollback or purge
+
2011-01-27 The InnoDB Team
* btr/btr0cur.c:
diff --git a/storage/innodb_plugin/btr/btr0cur.c b/storage/innodb_plugin/btr/btr0cur.c
index 874db3066b5..143135ef24c 100644
--- a/storage/innodb_plugin/btr/btr0cur.c
+++ b/storage/innodb_plugin/btr/btr0cur.c
@@ -1768,8 +1768,8 @@ btr_cur_update_in_place(
NOT call it if index is secondary */
if (!dict_index_is_clust(index)
- || row_upd_changes_ord_field_binary(NULL, NULL,
- index, update)) {
+ || row_upd_changes_ord_field_binary(index, update, thr,
+ NULL, NULL)) {
/* Remove possible hash index pointer to this record */
btr_search_update_hash_on_delete(cursor);
diff --git a/storage/innodb_plugin/include/row0upd.h b/storage/innodb_plugin/include/row0upd.h
index b61e6b6dca1..97b7ec49a17 100644
--- a/storage/innodb_plugin/include/row0upd.h
+++ b/storage/innodb_plugin/include/row0upd.h
@@ -280,19 +280,29 @@ 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! */
- __attribute__((nonnull(3,4), warn_unused_result));
+ __attribute__((nonnull(1,2), warn_unused_result));
+#ifdef UNIV_DEBUG
+# define row_upd_changes_ord_field_binary(index,update,thr,row,ext) \
+ row_upd_changes_ord_field_binary_func(index,update,thr,row,ext)
+#else /* UNIV_DEBUG */
+# define row_upd_changes_ord_field_binary(index,update,thr,row,ext) \
+ row_upd_changes_ord_field_binary_func(index,update,row,ext)
+#endif /* UNIV_DEBUG */
/***********************************************************//**
Checks if an update vector changes an ordering field of an index record.
This function is fast if the update vector is short or the number of ordering
diff --git a/storage/innodb_plugin/row/row0purge.c b/storage/innodb_plugin/row/row0purge.c
index 8bf2ae0f458..c91ec2e8a3b 100644
--- a/storage/innodb_plugin/row/row0purge.c
+++ b/storage/innodb_plugin/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
@@ -654,7 +665,7 @@ 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) {
diff --git a/storage/innodb_plugin/row/row0umod.c b/storage/innodb_plugin/row/row0umod.c
index 562f8093c38..f7736935489 100644
--- a/storage/innodb_plugin/row/row0umod.c
+++ b/storage/innodb_plugin/row/row0umod.c
@@ -668,8 +668,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/innodb_plugin/row/row0upd.c b/storage/innodb_plugin/row/row0upd.c
index 691d263e6ed..b5d4aeb434e 100644
--- a/storage/innodb_plugin/row/row0upd.c
+++ b/storage/innodb_plugin/row/row0upd.c
@@ -1192,25 +1192,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);
@@ -1263,9 +1269,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);
}
@@ -1612,8 +1623,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));
}
@@ -2140,8 +2151,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/innodb_plugin/trx/trx0roll.c b/storage/innodb_plugin/trx/trx0roll.c
index 1a43e419214..a4bbf7fd652 100644
--- a/storage/innodb_plugin/trx/trx0roll.c
+++ b/storage/innodb_plugin/trx/trx0roll.c
@@ -48,8 +48,8 @@ Created 3/26/1996 Heikki Tuuri
rollback */
#define TRX_ROLL_TRUNC_THRESHOLD 1
-/** In crash recovery, the current trx to be rolled back */
-static trx_t* trx_roll_crash_recv_trx = NULL;
+/** In crash recovery, the current trx to be rolled back; NULL otherwise */
+static const trx_t* trx_roll_crash_recv_trx = NULL;
/** In crash recovery we set this to the undo n:o of the current trx to be
rolled back. Then we can print how many % the rollback has progressed. */