ha_innodb.h, ha_innodb.cc:

  Make InnoDB to restore old active_index value after a table scan: MySQL may assume that a scan does NOT change active_index; this partially fixes bug 241 of UPDATE ... ORDER BY ... but it still remains that MySQL actually ignores the ORDER BY for both MyISAM and InnoDB tables
log0recv.c:
  Use fflush to make sure report of a corrupt log record is printed to .err log before mysqld crashes
parent f787cb14
...@@ -1825,7 +1825,12 @@ recv_report_corrupt_log( ...@@ -1825,7 +1825,12 @@ recv_report_corrupt_log(
"InnoDB: WARNING: the log file may have been corrupt and it\n" "InnoDB: WARNING: the log file may have been corrupt and it\n"
"InnoDB: is possible that the log scan did not proceed\n" "InnoDB: is possible that the log scan did not proceed\n"
"InnoDB: far enough in recovery! Please run CHECK TABLE\n" "InnoDB: far enough in recovery! Please run CHECK TABLE\n"
"InnoDB: on your InnoDB tables to check that they are ok!\n"); "InnoDB: on your InnoDB tables to check that they are ok!\n"
"InnoDB: If mysqld crashes after this recovery, look at\n"
"InnoDB: section 6.1 of http://www.innodb.com/ibman.html\n"
"InnoDB: about forcing recovery.\n");
fflush(stderr);
} }
/*********************************************************** /***********************************************************
...@@ -2462,7 +2467,7 @@ recv_recovery_from_checkpoint_start( ...@@ -2462,7 +2467,7 @@ recv_recovery_from_checkpoint_start(
log_hdr_buf, max_cp_group); log_hdr_buf, max_cp_group);
if (0 == ut_memcmp(log_hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP, if (0 == ut_memcmp(log_hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP,
"ibbackup", ut_strlen("ibbackup"))) { (byte*)"ibbackup", ut_strlen((char*)"ibbackup"))) {
/* This log file was created by ibbackup --restore: print /* This log file was created by ibbackup --restore: print
a note to the user about it */ a note to the user about it */
...@@ -2473,7 +2478,7 @@ recv_recovery_from_checkpoint_start( ...@@ -2473,7 +2478,7 @@ recv_recovery_from_checkpoint_start(
/* Wipe over the label now */ /* Wipe over the label now */
ut_memcpy(log_hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP, ut_memcpy(log_hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP,
" ", 4); (char*)" ", 4);
/* Write to the log file to wipe over the label */ /* Write to the log file to wipe over the label */
fil_io(OS_FILE_WRITE | OS_FILE_LOG, TRUE, fil_io(OS_FILE_WRITE | OS_FILE_LOG, TRUE,
max_cp_group->space_id, max_cp_group->space_id,
......
...@@ -2026,7 +2026,8 @@ calc_row_difference( ...@@ -2026,7 +2026,8 @@ calc_row_difference(
upd_t* uvect, /* in/out: update vector */ upd_t* uvect, /* in/out: update vector */
mysql_byte* old_row, /* in: old row in MySQL format */ mysql_byte* old_row, /* in: old row in MySQL format */
mysql_byte* new_row, /* in: new row in MySQL format */ mysql_byte* new_row, /* in: new row in MySQL format */
struct st_table* table, /* in: table in MySQL data dictionary */ struct st_table* table, /* in: table in MySQL data
dictionary */
mysql_byte* upd_buff, /* in: buffer to use */ mysql_byte* upd_buff, /* in: buffer to use */
row_prebuilt_t* prebuilt, /* in: InnoDB prebuilt struct */ row_prebuilt_t* prebuilt, /* in: InnoDB prebuilt struct */
THD* thd) /* in: user thread */ THD* thd) /* in: user thread */
...@@ -2076,8 +2077,10 @@ calc_row_difference( ...@@ -2076,8 +2077,10 @@ calc_row_difference(
case DATA_VARCHAR: case DATA_VARCHAR:
case DATA_BINARY: case DATA_BINARY:
case DATA_VARMYSQL: case DATA_VARMYSQL:
o_ptr = row_mysql_read_var_ref_noninline(&o_len, o_ptr); o_ptr = row_mysql_read_var_ref_noninline(&o_len,
n_ptr = row_mysql_read_var_ref_noninline(&n_len, n_ptr); o_ptr);
n_ptr = row_mysql_read_var_ref_noninline(&n_len,
n_ptr);
default: default:
; ;
} }
...@@ -2489,46 +2492,48 @@ ha_innobase::change_active_index( ...@@ -2489,46 +2492,48 @@ ha_innobase::change_active_index(
index, even if it was internally generated by index, even if it was internally generated by
InnoDB */ InnoDB */
{ {
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
KEY* key=0; KEY* key=0;
statistic_increment(ha_read_key_count, &LOCK_status); statistic_increment(ha_read_key_count, &LOCK_status);
DBUG_ENTER("change_active_index"); DBUG_ENTER("change_active_index");
ut_a(prebuilt->trx == ut_a(prebuilt->trx ==
(trx_t*) current_thd->transaction.all.innobase_tid); (trx_t*) current_thd->transaction.all.innobase_tid);
active_index = keynr; active_index = keynr;
if (keynr != MAX_KEY && table->keys > 0) { if (keynr != MAX_KEY && table->keys > 0) {
key = table->key_info + active_index; key = table->key_info + active_index;
prebuilt->index = dict_table_get_index_noninline( prebuilt->index = dict_table_get_index_noninline(
prebuilt->table, prebuilt->table,
key->name); key->name);
} else { } else {
prebuilt->index = dict_table_get_first_index_noninline( prebuilt->index = dict_table_get_first_index_noninline(
prebuilt->table); prebuilt->table);
} }
if (!prebuilt->index) { if (!prebuilt->index) {
sql_print_error("Innodb could not find key n:o %u with name %s from dict cache for table %s", keynr, key ? key->name : "NULL", prebuilt->table->name); sql_print_error(
DBUG_RETURN(1); "Innodb could not find key n:o %u with name %s from dict cache for table %s",
} keynr, key ? key->name : "NULL", prebuilt->table->name);
DBUG_RETURN(1);
}
assert(prebuilt->search_tuple != 0); assert(prebuilt->search_tuple != 0);
dtuple_set_n_fields(prebuilt->search_tuple, prebuilt->index->n_fields); dtuple_set_n_fields(prebuilt->search_tuple, prebuilt->index->n_fields);
dict_index_copy_types(prebuilt->search_tuple, prebuilt->index, dict_index_copy_types(prebuilt->search_tuple, prebuilt->index,
prebuilt->index->n_fields); prebuilt->index->n_fields);
/* Maybe MySQL changes the active index for a handle also /* Maybe MySQL changes the active index for a handle also
during some queries, we do not know: then it is safest to build during some queries, we do not know: then it is safest to build
the template such that all columns will be fetched. */ the template such that all columns will be fetched. */
build_template(prebuilt, NULL, table, ROW_MYSQL_WHOLE_ROW); build_template(prebuilt, NULL, table, ROW_MYSQL_WHOLE_ROW);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
/************************************************************************** /**************************************************************************
...@@ -2721,6 +2726,11 @@ ha_innobase::rnd_init( ...@@ -2721,6 +2726,11 @@ ha_innobase::rnd_init(
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
/* Store the active index value so that we can restore the original
value after a scan */
active_index_before_scan = active_index;
if (prebuilt->clust_index_was_generated) { if (prebuilt->clust_index_was_generated) {
err = change_active_index(MAX_KEY); err = change_active_index(MAX_KEY);
} else { } else {
...@@ -2733,13 +2743,18 @@ ha_innobase::rnd_init( ...@@ -2733,13 +2743,18 @@ ha_innobase::rnd_init(
} }
/********************************************************************* /*********************************************************************
Ends a table scan ???????????????? */ Ends a table scan. */
int int
ha_innobase::rnd_end(void) ha_innobase::rnd_end(void)
/*======================*/ /*======================*/
/* out: 0 or error number */ /* out: 0 or error number */
{ {
/* Restore the old active_index back; MySQL may assume that a table
scan does not change active_index */
change_active_index(active_index_before_scan);
return(index_end()); return(index_end());
} }
......
...@@ -58,7 +58,15 @@ class ha_innobase: public handler ...@@ -58,7 +58,15 @@ class ha_innobase: public handler
ulong start_of_scan; /* this is set to 1 when we are ulong start_of_scan; /* this is set to 1 when we are
starting a table scan but have not starting a table scan but have not
yet fetched any row, else 0 */ yet fetched any row, else 0 */
uint active_index_before_scan;
/* since a table scan in InnoDB is
always done through an index, a table
scan may change active_index; but
MySQL may assume that active_index
after a table scan is the same as
before; we store the value here so
that we can restore the value after
a scan */
uint last_match_mode;/* match mode of the latest search: uint last_match_mode;/* match mode of the latest search:
ROW_SEL_EXACT, ROW_SEL_EXACT_PREFIX, ROW_SEL_EXACT, ROW_SEL_EXACT_PREFIX,
or undefined */ or undefined */
......
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