summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorYasufumi Kinoshita <yasufumi.kinoshita@oracle.com>2012-11-26 15:57:26 +0900
committerYasufumi Kinoshita <yasufumi.kinoshita@oracle.com>2012-11-26 15:57:26 +0900
commitc257dbe60cbb64edf64116743cd811cdb3d534e5 (patch)
tree1df70c303fcb76381bba51c48da83467021c605c /storage
parent43062dba3ac0d1887a890ddbd364aa81a3a0208f (diff)
downloadmariadb-git-c257dbe60cbb64edf64116743cd811cdb3d534e5.tar.gz
Bug #14676249 : ROW_VERS_IMPL_X_LOCKED_LOW() MIGHT HIT !BPAGE->FILE_PAGE_WAS_FREED ASSERTION
trx_undo_prev_version_build() should confirm existence of inherited (not-own) external pages. Bug #14676084 : ROW_UNDO_MOD_UPD_DEL_SEC() DOESN'T NEED UNDO_ROW AND UNDO_EXT INITIALIZED mtr script could hit the assertion error !bpage->file_page_was_freed using this path. So, also fixed rb://1337 approved by Marko Makela.
Diffstat (limited to 'storage')
-rw-r--r--storage/innodb_plugin/row/row0umod.c3
-rw-r--r--storage/innodb_plugin/row/row0undo.c2
-rw-r--r--storage/innodb_plugin/srv/srv0srv.c12
-rw-r--r--storage/innodb_plugin/trx/trx0rec.c20
4 files changed, 36 insertions, 1 deletions
diff --git a/storage/innodb_plugin/row/row0umod.c b/storage/innodb_plugin/row/row0umod.c
index 31f7c9f4888..a1c86424625 100644
--- a/storage/innodb_plugin/row/row0umod.c
+++ b/storage/innodb_plugin/row/row0umod.c
@@ -493,6 +493,7 @@ row_undo_mod_upd_del_sec(
ulint err = DB_SUCCESS;
ut_ad(node->rec_type == TRX_UNDO_UPD_DEL_REC);
+ ut_ad(!node->undo_row);
heap = mem_heap_create(1024);
while (node->index != NULL) {
@@ -546,6 +547,8 @@ row_undo_mod_del_mark_sec(
dict_index_t* index;
ulint err;
+ ut_ad(!node->undo_row);
+
heap = mem_heap_create(1024);
while (node->index != NULL) {
diff --git a/storage/innodb_plugin/row/row0undo.c b/storage/innodb_plugin/row/row0undo.c
index b1606bda5ef..f07d8013919 100644
--- a/storage/innodb_plugin/row/row0undo.c
+++ b/storage/innodb_plugin/row/row0undo.c
@@ -217,7 +217,7 @@ row_undo_search_clust_to_pcur(
node->row = row_build(ROW_COPY_DATA, clust_index, rec,
offsets, NULL, ext, node->heap);
- if (node->update) {
+ if (node->rec_type == TRX_UNDO_UPD_EXIST_REC) {
node->undo_row = dtuple_copy(node->row, node->heap);
row_upd_replace(node->undo_row, &node->undo_ext,
clust_index, node->update, node->heap);
diff --git a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0srv.c
index 2d48fcc6b18..da5861d8c87 100644
--- a/storage/innodb_plugin/srv/srv0srv.c
+++ b/storage/innodb_plugin/srv/srv0srv.c
@@ -86,6 +86,14 @@ Created 10/8/1995 Heikki Tuuri
#include "trx0i_s.h"
#include "os0sync.h" /* for HAVE_ATOMIC_BUILTINS */
+#ifdef __WIN__
+/* error LNK2001: unresolved external symbol _debug_sync_C_callback_ptr */
+# define DEBUG_SYNC_C(dummy) ((void) 0)
+#else
+# include "m_string.h" /* for my_sys.h */
+# include "my_sys.h" /* DEBUG_SYNC_C */
+#endif
+
/* This is set to TRUE if the MySQL user has set it in MySQL; currently
affects only FOREIGN KEY definition parsing */
UNIV_INTERN ibool srv_lower_case_table_names = FALSE;
@@ -1474,6 +1482,10 @@ srv_suspend_mysql_thread(
trx = thr_get_trx(thr);
+ if (trx->mysql_thd != 0) {
+ DEBUG_SYNC_C("srv_suspend_mysql_thread_enter");
+ }
+
os_event_set(srv_lock_timeout_thread_event);
mutex_enter(&kernel_mutex);
diff --git a/storage/innodb_plugin/trx/trx0rec.c b/storage/innodb_plugin/trx/trx0rec.c
index dc55690c9c3..4de0ed8f9b8 100644
--- a/storage/innodb_plugin/trx/trx0rec.c
+++ b/storage/innodb_plugin/trx/trx0rec.c
@@ -36,6 +36,7 @@ Created 3/26/1996 Heikki Tuuri
#ifndef UNIV_HOTBACKUP
#include "dict0dict.h"
#include "ut0mem.h"
+#include "read0read.h"
#include "row0ext.h"
#include "row0upd.h"
#include "que0que.h"
@@ -1617,6 +1618,25 @@ trx_undo_prev_version_build(
if (row_upd_changes_field_size_or_external(index, offsets, update)) {
ulint n_ext;
+ /* We should confirm the existence of disowned external data,
+ if the previous version record is delete marked. If the trx_id
+ of the previous record is seen by purge view, we should treat
+ it as missing history, because the disowned external data
+ might be purged already.
+
+ The inherited external data (BLOBs) can be freed (purged)
+ after trx_id was committed, provided that no view was started
+ before trx_id. If the purge view can see the committed
+ delete-marked record by trx_id, no transactions need to access
+ the BLOB. */
+
+ if ((update->info_bits & REC_INFO_DELETED_FLAG)
+ && read_view_sees_trx_id(purge_sys->view, trx_id)) {
+ /* treat as a fresh insert, not to
+ cause assertion error at the caller. */
+ return(DB_SUCCESS);
+ }
+
/* We have to set the appropriate extern storage bits in the
old version of the record: the extern bits in rec for those
fields that update does NOT update, as well as the bits for