diff options
author | Annamalai Gurusami <annamalai.gurusami@oracle.com> | 2012-10-08 19:40:30 +0530 |
---|---|---|
committer | Annamalai Gurusami <annamalai.gurusami@oracle.com> | 2012-10-08 19:40:30 +0530 |
commit | bd7c9815cee8f9bcf6ebd7d87cce6ee045732e42 (patch) | |
tree | f4b66e0e1aa0556afbaf7190a833dc54c0792585 /sql/opt_range.cc | |
parent | 5d9e863faf9867bc4639af77e73767ac856fe3ed (diff) | |
download | mariadb-git-bd7c9815cee8f9bcf6ebd7d87cce6ee045732e42.tar.gz |
Bug #14036214 MYSQLD CRASHES WHEN EXECUTING UPDATE IN TRX WITH
CONSISTENT SNAPSHOT OPTION
A transaction is started with a consistent snapshot. After
the transaction is started new indexes are added to the
table. Now when we issue an update statement, the optimizer
chooses an index. When the index scan is being initialized
via ha_innobase::change_active_index(), InnoDB reports
the error code HA_ERR_TABLE_DEF_CHANGED, with message
stating that "insufficient history for index".
This error message is propagated up to the SQL layer. But
the my_error() api is never called. The statement level
diagnostics area is not updated with the correct error
status (it remains in Diagnostics_area::DA_EMPTY).
Hence the following check in the Protocol::end_statement()
fails.
516 case Diagnostics_area::DA_EMPTY:
517 default:
518 DBUG_ASSERT(0);
519 error= send_ok(thd->server_status, 0, 0, 0, NULL);
520 break;
The fix is to backport the fix of bugs 14365043, 11761652
and 11746399.
14365043 PROTOCOL::END_STATEMENT(): ASSERTION `0' FAILED
11761652 HA_RND_INIT() RESULT CODE NOT CHECKED
11746399 RETURN VALUES OF HA_INDEX_INIT() AND INDEX_INIT() IGNORED
rb://1227 approved by guilhem and mattiasj.
Diffstat (limited to 'sql/opt_range.cc')
-rw-r--r-- | sql/opt_range.cc | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/sql/opt_range.cc b/sql/opt_range.cc index ce48a8da958..ffd66253eaa 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1183,7 +1183,7 @@ int QUICK_RANGE_SELECT::init() { DBUG_ENTER("QUICK_RANGE_SELECT::init"); - if (file->inited != handler::NONE) + if (file->inited) file->ha_index_or_rnd_end(); DBUG_RETURN(FALSE); } @@ -1191,7 +1191,7 @@ int QUICK_RANGE_SELECT::init() void QUICK_RANGE_SELECT::range_end() { - if (file->inited != handler::NONE) + if (file->inited) file->ha_index_or_rnd_end(); } @@ -1450,8 +1450,9 @@ int QUICK_ROR_INTERSECT_SELECT::init_ror_merged_scan(bool reuse_handler) There is no use of this->file. Use it for the first of merged range selects. */ - if (quick->init_ror_merged_scan(TRUE)) - DBUG_RETURN(1); + int error= quick->init_ror_merged_scan(TRUE); + if (error) + DBUG_RETURN(error); quick->file->extra(HA_EXTRA_KEYREAD_PRESERVE_FIELDS); } while ((quick= quick_it++)) @@ -1522,7 +1523,7 @@ QUICK_ROR_INTERSECT_SELECT::~QUICK_ROR_INTERSECT_SELECT() quick_selects.delete_elements(); delete cpk_quick; free_root(&alloc,MYF(0)); - if (need_to_fetch_row && head->file->inited != handler::NONE) + if (need_to_fetch_row && head->file->inited) head->file->ha_rnd_end(); DBUG_VOID_RETURN; } @@ -1626,8 +1627,8 @@ int QUICK_ROR_UNION_SELECT::reset() List_iterator_fast<QUICK_SELECT_I> it(quick_selects); while ((quick= it++)) { - if (quick->reset()) - DBUG_RETURN(1); + if ((error= quick->reset())) + DBUG_RETURN(error); if ((error= quick->get_next())) { if (error == HA_ERR_END_OF_FILE) @@ -1638,10 +1639,10 @@ int QUICK_ROR_UNION_SELECT::reset() queue_insert(&queue, (uchar*)quick); } - if (head->file->ha_rnd_init(1)) + if ((error= head->file->ha_rnd_init(1))) { DBUG_PRINT("error", ("ROR index_merge rnd_init call failed")); - DBUG_RETURN(1); + DBUG_RETURN(error); } DBUG_RETURN(0); @@ -1659,7 +1660,7 @@ QUICK_ROR_UNION_SELECT::~QUICK_ROR_UNION_SELECT() DBUG_ENTER("QUICK_ROR_UNION_SELECT::~QUICK_ROR_UNION_SELECT"); delete_queue(&queue); quick_selects.delete_elements(); - if (head->file->inited != handler::NONE) + if (head->file->inited) head->file->ha_rnd_end(); free_root(&alloc,MYF(0)); DBUG_VOID_RETURN; @@ -8316,7 +8317,7 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge() if (!cur_quick) break; - if (cur_quick->file->inited != handler::NONE) + if (cur_quick->file->inited) cur_quick->file->ha_index_end(); if (cur_quick->init() || cur_quick->reset()) DBUG_RETURN(1); @@ -8568,8 +8569,14 @@ int QUICK_RANGE_SELECT::reset() { if (in_ror_merged_scan) head->column_bitmaps_set_no_signal(&column_bitmap, &column_bitmap); + + DBUG_EXECUTE_IF("bug14365043_2", + DBUG_SET("+d,ha_index_init_fail");); if ((error= file->ha_index_init(index,1))) + { + file->print_error(error, MYF(0)); DBUG_RETURN(error); + } } /* Do not allocate the buffers twice. */ @@ -10783,7 +10790,10 @@ int QUICK_GROUP_MIN_MAX_SELECT::reset(void) head->set_keyread(TRUE); /* We need only the key attributes */ if ((result= file->ha_index_init(index,1))) + { + head->file->print_error(result, MYF(0)); DBUG_RETURN(result); + } if (quick_prefix_select && quick_prefix_select->reset()) DBUG_RETURN(1); result= file->index_last(record); |