diff options
author | Yasufumi Kinoshita <yasufumi.kinoshita@oracle.com> | 2012-11-26 15:57:26 +0900 |
---|---|---|
committer | Yasufumi Kinoshita <yasufumi.kinoshita@oracle.com> | 2012-11-26 15:57:26 +0900 |
commit | c257dbe60cbb64edf64116743cd811cdb3d534e5 (patch) | |
tree | 1df70c303fcb76381bba51c48da83467021c605c /storage | |
parent | 43062dba3ac0d1887a890ddbd364aa81a3a0208f (diff) | |
download | mariadb-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.c | 3 | ||||
-rw-r--r-- | storage/innodb_plugin/row/row0undo.c | 2 | ||||
-rw-r--r-- | storage/innodb_plugin/srv/srv0srv.c | 12 | ||||
-rw-r--r-- | storage/innodb_plugin/trx/trx0rec.c | 20 |
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 |