Commit c257dbe6 authored by Yasufumi Kinoshita's avatar Yasufumi Kinoshita

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.
parent 43062dba
...@@ -493,6 +493,7 @@ row_undo_mod_upd_del_sec( ...@@ -493,6 +493,7 @@ row_undo_mod_upd_del_sec(
ulint err = DB_SUCCESS; ulint err = DB_SUCCESS;
ut_ad(node->rec_type == TRX_UNDO_UPD_DEL_REC); ut_ad(node->rec_type == TRX_UNDO_UPD_DEL_REC);
ut_ad(!node->undo_row);
heap = mem_heap_create(1024); heap = mem_heap_create(1024);
while (node->index != NULL) { while (node->index != NULL) {
...@@ -546,6 +547,8 @@ row_undo_mod_del_mark_sec( ...@@ -546,6 +547,8 @@ row_undo_mod_del_mark_sec(
dict_index_t* index; dict_index_t* index;
ulint err; ulint err;
ut_ad(!node->undo_row);
heap = mem_heap_create(1024); heap = mem_heap_create(1024);
while (node->index != NULL) { while (node->index != NULL) {
......
...@@ -217,7 +217,7 @@ row_undo_search_clust_to_pcur( ...@@ -217,7 +217,7 @@ row_undo_search_clust_to_pcur(
node->row = row_build(ROW_COPY_DATA, clust_index, rec, node->row = row_build(ROW_COPY_DATA, clust_index, rec,
offsets, NULL, ext, node->heap); 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); node->undo_row = dtuple_copy(node->row, node->heap);
row_upd_replace(node->undo_row, &node->undo_ext, row_upd_replace(node->undo_row, &node->undo_ext,
clust_index, node->update, node->heap); clust_index, node->update, node->heap);
......
...@@ -86,6 +86,14 @@ Created 10/8/1995 Heikki Tuuri ...@@ -86,6 +86,14 @@ Created 10/8/1995 Heikki Tuuri
#include "trx0i_s.h" #include "trx0i_s.h"
#include "os0sync.h" /* for HAVE_ATOMIC_BUILTINS */ #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 /* This is set to TRUE if the MySQL user has set it in MySQL; currently
affects only FOREIGN KEY definition parsing */ affects only FOREIGN KEY definition parsing */
UNIV_INTERN ibool srv_lower_case_table_names = FALSE; UNIV_INTERN ibool srv_lower_case_table_names = FALSE;
...@@ -1474,6 +1482,10 @@ srv_suspend_mysql_thread( ...@@ -1474,6 +1482,10 @@ srv_suspend_mysql_thread(
trx = thr_get_trx(thr); 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); os_event_set(srv_lock_timeout_thread_event);
mutex_enter(&kernel_mutex); mutex_enter(&kernel_mutex);
......
...@@ -36,6 +36,7 @@ Created 3/26/1996 Heikki Tuuri ...@@ -36,6 +36,7 @@ Created 3/26/1996 Heikki Tuuri
#ifndef UNIV_HOTBACKUP #ifndef UNIV_HOTBACKUP
#include "dict0dict.h" #include "dict0dict.h"
#include "ut0mem.h" #include "ut0mem.h"
#include "read0read.h"
#include "row0ext.h" #include "row0ext.h"
#include "row0upd.h" #include "row0upd.h"
#include "que0que.h" #include "que0que.h"
...@@ -1617,6 +1618,25 @@ trx_undo_prev_version_build( ...@@ -1617,6 +1618,25 @@ trx_undo_prev_version_build(
if (row_upd_changes_field_size_or_external(index, offsets, update)) { if (row_upd_changes_field_size_or_external(index, offsets, update)) {
ulint n_ext; 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 /* We have to set the appropriate extern storage bits in the
old version of the record: the extern bits in rec for those old version of the record: the extern bits in rec for those
fields that update does NOT update, as well as the bits for fields that update does NOT update, as well as the bits for
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment