From 0d3039d49daa7e274d66db808b15eebe8cbd778e Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Sat, 7 Aug 2010 17:42:30 +0300 Subject: [PATCH] This patch fixes LP#613408 Memory corruption with (M)aria storage engine and virtual columns in MariaDB 5.2 Fixed compiler warnings Disabled some tests that doesn't work on windows (uses shell tools or strange characters) client/mysqlshow.c: Fixed compiler warnings client/mysqlslap.c: Fixed compiler warnings mysql-test/mysql-test-run.pl: Use an error file instead of /dev/null (Fixes problem on Windows and the output may be usefull) mysql-test/suite/maria/r/maria.result: Test case for bug LP#613408 (not complete) mysql-test/suite/maria/t/maria.test: Test case for bug LP#613408 (not complete) mysql-test/suite/percona/percona_log_slow_slave_statements-and-use_global_long_query_time.test: This test doesn't work one windows (needs shell tools) mysql-test/suite/percona/percona_log_slow_slave_statements.test: This test doesn't work one windows (needs shell tools) mysql-test/suite/percona/percona_slow_query_log-control_global_slow.test: This test doesn't work one windows (needs shell tools) mysql-test/suite/percona/percona_slow_query_log-log_slow_filter.test: This test doesn't work one windows (needs shell tools) mysql-test/suite/percona/percona_slow_query_log-log_slow_verbosity.test: This test doesn't work one windows (needs shell tools) mysql-test/suite/percona/percona_slow_query_log-long_query_time.test: This test doesn't work one windows (needs shell tools) mysql-test/suite/percona/percona_slow_query_log-microseconds_in_slow_query_log.test: This test doesn't work one windows (needs shell tools) mysql-test/suite/percona/percona_slow_query_log-min_examined_row_limit.test: This test doesn't work one windows (needs shell tools) mysql-test/suite/percona/percona_slow_query_log-use_global_long_query_time.test: This test doesn't work one windows (needs shell tools) mysql-test/t/ctype_filesystem.test: This test doesn't work one windows (problem with character sets) mysql-test/t/events_time_zone.test: Use longer times to get predictable tests mysql-test/t/show_check-master.opt: set long query time to get more predictable tests storage/maria/ma_check.c: Restore info->s->lock_key_trees after repair. Disable logging to temp tables for all repair cases (safety fix) storage/maria/ma_state.c: Ensurethat info->state_start doesn't point to freed memory. (Could happen after running an internal repair to fast create indexes) storage/maria/trnman.c: Added longer comment --- client/mysqlshow.c | 2 +- client/mysqlslap.c | 2 +- mysql-test/mysql-test-run.pl | 2 +- mysql-test/suite/maria/r/maria.result | 11 ++++ mysql-test/suite/maria/t/maria.test | 17 ++++++ ...ements-and-use_global_long_query_time.test | 2 + .../percona_log_slow_slave_statements.test | 2 + ...na_slow_query_log-control_global_slow.test | 2 + ...ercona_slow_query_log-log_slow_filter.test | 2 + ...ona_slow_query_log-log_slow_verbosity.test | 2 + ...ercona_slow_query_log-long_query_time.test | 1 + ...ry_log-microseconds_in_slow_query_log.test | 1 + ...slow_query_log-min_examined_row_limit.test | 1 + ..._query_log-use_global_long_query_time.test | 1 + mysql-test/t/ctype_filesystem.test | 2 + mysql-test/t/events_time_zone.test | 2 +- mysql-test/t/show_check-master.opt | 2 +- storage/maria/ma_check.c | 57 ++++++++++++++++--- storage/maria/ma_state.c | 1 + storage/maria/trnman.c | 3 +- 20 files changed, 101 insertions(+), 14 deletions(-) diff --git a/client/mysqlshow.c b/client/mysqlshow.c index 2f5582cb668..2c9a59a2d54 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -164,7 +164,7 @@ static struct my_option my_long_options[] = 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"character-sets-dir", 'c', "Directory for character set files.", - &charsets_dir, &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, + (char**) &charsets_dir, (char**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"default-character-set", OPT_DEFAULT_CHARSET, "Set the default character set.", &default_charset, diff --git a/client/mysqlslap.c b/client/mysqlslap.c index 7590ff35b5f..0b3ea2a0065 100644 --- a/client/mysqlslap.c +++ b/client/mysqlslap.c @@ -600,7 +600,7 @@ static struct my_option my_long_options[] = &debug_info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"delimiter", 'F', "Delimiter to use in SQL statements supplied in file or command line.", - &delimiter, &delimiter, 0, GET_STR, REQUIRED_ARG, + (char**) &delimiter, (char**) &delimiter, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"detach", OPT_SLAP_DETACH, "Detach (close and reopen) connections after X number of requests.", diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 4df5d04dac7..e409bab32f7 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -4540,7 +4540,7 @@ sub mysqld_stop { name => "mysqladmin shutdown ".$mysqld->name(), path => $exe_mysqladmin, args => \$args, - error => "/dev/null", + error => "$opt_vardir/log/mysqladmin.err", ); } diff --git a/mysql-test/suite/maria/r/maria.result b/mysql-test/suite/maria/r/maria.result index 76a115982f0..d418ae42080 100644 --- a/mysql-test/suite/maria/r/maria.result +++ b/mysql-test/suite/maria/r/maria.result @@ -2613,3 +2613,14 @@ INSERT t1 ( f1 , f2 , f3 , f4 ) VALUES ( 0 , f2 , 8 , f3 ) ; INSERT t1 ( f4 , f2 ) VALUES ( 4 , 92 ) ; DELETE FROM t1 WHERE v3 = 173 OR v4 = 9 ; drop table t1; +CREATE TABLE t1 ( +f1 CHAR(255) BINARY , +f2 CHAR(255) BINARY NOT NULL DEFAULT '0', +f3 CHAR(255) BINARY NOT NULL , +f4 CHAR(255) BINARY NOT NULL DEFAULT '0' , +v3 CHAR(255) BINARY NOT NULL DEFAULT '0' , +KEY (v3) +) ENGINE=Maria; +INSERT INTO t1 ( f1 , f2 , f3 , f4 ) SELECT f1 , f4 , f1 , f4 FROM t1; +DELETE FROM t1; +drop table t1; diff --git a/mysql-test/suite/maria/t/maria.test b/mysql-test/suite/maria/t/maria.test index a4498070390..4dde6364bb1 100644 --- a/mysql-test/suite/maria/t/maria.test +++ b/mysql-test/suite/maria/t/maria.test @@ -1893,6 +1893,23 @@ INSERT t1 ( f4 , f2 ) VALUES ( 4 , 92 ) ; DELETE FROM t1 WHERE v3 = 173 OR v4 = 9 ; drop table t1; +# +# Test for LP#61465 Memory corruption with (M)aria storage engine and +# virtual columns +# + +CREATE TABLE t1 ( + f1 CHAR(255) BINARY , + f2 CHAR(255) BINARY NOT NULL DEFAULT '0', + f3 CHAR(255) BINARY NOT NULL , + f4 CHAR(255) BINARY NOT NULL DEFAULT '0' , + v3 CHAR(255) BINARY NOT NULL DEFAULT '0' , + KEY (v3) +) ENGINE=Maria; +INSERT INTO t1 ( f1 , f2 , f3 , f4 ) SELECT f1 , f4 , f1 , f4 FROM t1; +DELETE FROM t1; +drop table t1; + # # End of test # diff --git a/mysql-test/suite/percona/percona_log_slow_slave_statements-and-use_global_long_query_time.test b/mysql-test/suite/percona/percona_log_slow_slave_statements-and-use_global_long_query_time.test index 7605218e463..8d4bb1e091c 100644 --- a/mysql-test/suite/percona/percona_log_slow_slave_statements-and-use_global_long_query_time.test +++ b/mysql-test/suite/percona/percona_log_slow_slave_statements-and-use_global_long_query_time.test @@ -1,3 +1,5 @@ +-- source include/not_windows.inc + -- echo # Activate master-slave replication -- source include/master-slave.inc diff --git a/mysql-test/suite/percona/percona_log_slow_slave_statements.test b/mysql-test/suite/percona/percona_log_slow_slave_statements.test index 37cb1ad2419..8c9c594e41c 100644 --- a/mysql-test/suite/percona/percona_log_slow_slave_statements.test +++ b/mysql-test/suite/percona/percona_log_slow_slave_statements.test @@ -1,3 +1,5 @@ +-- source include/not_windows.inc + -- echo # Activate master-slave replication -- source include/master-slave.inc diff --git a/mysql-test/suite/percona/percona_slow_query_log-control_global_slow.test b/mysql-test/suite/percona/percona_slow_query_log-control_global_slow.test index 79b94825821..1c3dc937937 100644 --- a/mysql-test/suite/percona/percona_slow_query_log-control_global_slow.test +++ b/mysql-test/suite/percona/percona_slow_query_log-control_global_slow.test @@ -1,3 +1,5 @@ +--source include/not_windows.inc + source include/have_innodb.inc; SELECT sleep(2); set global log_slow_verbosity=innodb; diff --git a/mysql-test/suite/percona/percona_slow_query_log-log_slow_filter.test b/mysql-test/suite/percona/percona_slow_query_log-log_slow_filter.test index 843567ae11a..44646de530a 100644 --- a/mysql-test/suite/percona/percona_slow_query_log-log_slow_filter.test +++ b/mysql-test/suite/percona/percona_slow_query_log-log_slow_filter.test @@ -1,3 +1,5 @@ +-- source include/not_windows.inc + source include/have_innodb.inc; SET GLOBAL SLOW_QUERY_LOG=OFF; diff --git a/mysql-test/suite/percona/percona_slow_query_log-log_slow_verbosity.test b/mysql-test/suite/percona/percona_slow_query_log-log_slow_verbosity.test index 62717c4ed6e..d1dc324fced 100644 --- a/mysql-test/suite/percona/percona_slow_query_log-log_slow_verbosity.test +++ b/mysql-test/suite/percona/percona_slow_query_log-log_slow_verbosity.test @@ -1,3 +1,5 @@ +-- source include/not_windows.inc + source include/have_innodb.inc; SELECT sleep(2); diff --git a/mysql-test/suite/percona/percona_slow_query_log-long_query_time.test b/mysql-test/suite/percona/percona_slow_query_log-long_query_time.test index 55f3e61cd09..4161690e2ef 100644 --- a/mysql-test/suite/percona/percona_slow_query_log-long_query_time.test +++ b/mysql-test/suite/percona/percona_slow_query_log-long_query_time.test @@ -1,3 +1,4 @@ +source include/not_windows.inc; source include/have_innodb.inc; SELECT sleep(1); diff --git a/mysql-test/suite/percona/percona_slow_query_log-microseconds_in_slow_query_log.test b/mysql-test/suite/percona/percona_slow_query_log-microseconds_in_slow_query_log.test index 67bf49400fa..bceada68d79 100644 --- a/mysql-test/suite/percona/percona_slow_query_log-microseconds_in_slow_query_log.test +++ b/mysql-test/suite/percona/percona_slow_query_log-microseconds_in_slow_query_log.test @@ -1,3 +1,4 @@ +source include/not_windows.inc; source include/have_innodb.inc; SELECT sleep(2); diff --git a/mysql-test/suite/percona/percona_slow_query_log-min_examined_row_limit.test b/mysql-test/suite/percona/percona_slow_query_log-min_examined_row_limit.test index 28287c4bcb2..61276423b4d 100644 --- a/mysql-test/suite/percona/percona_slow_query_log-min_examined_row_limit.test +++ b/mysql-test/suite/percona/percona_slow_query_log-min_examined_row_limit.test @@ -1,3 +1,4 @@ +source include/not_windows.inc; source include/have_innodb.inc; SET GLOBAL SLOW_QUERY_LOG=OFF; diff --git a/mysql-test/suite/percona/percona_slow_query_log-use_global_long_query_time.test b/mysql-test/suite/percona/percona_slow_query_log-use_global_long_query_time.test index 397526fccdd..70021da1e4c 100644 --- a/mysql-test/suite/percona/percona_slow_query_log-use_global_long_query_time.test +++ b/mysql-test/suite/percona/percona_slow_query_log-use_global_long_query_time.test @@ -1,3 +1,4 @@ +source include/not_windows.inc; source include/have_innodb.inc; SELECT sleep(1); diff --git a/mysql-test/t/ctype_filesystem.test b/mysql-test/t/ctype_filesystem.test index 2b993c2b924..42f1ef06478 100644 --- a/mysql-test/t/ctype_filesystem.test +++ b/mysql-test/t/ctype_filesystem.test @@ -1,3 +1,5 @@ +--source include/not_windows.inc + SET CHARACTER SET utf8; --replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR SHOW VARIABLES like 'character_sets_dir'; diff --git a/mysql-test/t/events_time_zone.test b/mysql-test/t/events_time_zone.test index cb2fbab29c6..5291eb96e6b 100644 --- a/mysql-test/t/events_time_zone.test +++ b/mysql-test/t/events_time_zone.test @@ -5,7 +5,7 @@ # to wait for operation to complete. Should be positive. Test runs # about 25*N seconds (it sleeps most of the time, so CPU speed is not # relevant). -let $N = 5; +let $N = 6; # # 2. Some subtests # - create a new time zone diff --git a/mysql-test/t/show_check-master.opt b/mysql-test/t/show_check-master.opt index 333b1d559e3..b6118d7db9f 100644 --- a/mysql-test/t/show_check-master.opt +++ b/mysql-test/t/show_check-master.opt @@ -1 +1 @@ ---log-output=file --slow-query-log --log-long-format --log-queries-not-using-indexes --myisam-recover="" --general-log --general-log-file="foo" --slow-query-log-file="" +--log-output=file --slow-query-log --log-long-format --log-queries-not-using-indexes --myisam-recover="" --general-log --general-log-file="foo" --slow-query-log-file="" --long_query_time=20 diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c index dd26046767f..2a19b5e9075 100644 --- a/storage/maria/ma_check.c +++ b/storage/maria/ma_check.c @@ -2270,10 +2270,14 @@ static int initialize_variables_for_repair(HA_CHECK *param, MARIA_SORT_INFO *sort_info, MARIA_SORT_PARAM *sort_param, MARIA_HA *info, - my_bool rep_quick) + my_bool rep_quick, + MARIA_SHARE *org_share) { MARIA_SHARE *share= info->s; + /* Ro allow us to restore state and check how state changed */ + memcpy(org_share, share, sizeof(*share)); + /* Repair code relies on share->state.state so we have to update it here */ if (share->lock.update_status) (*share->lock.update_status)(info); @@ -2333,6 +2337,23 @@ static int initialize_variables_for_repair(HA_CHECK *param, } +/* + During initialize_variables_for_repair and related functions we set some + variables to values that makes sence during repair. + This function restores these values to their original values so that we can + use the handler in MariaDB without having to close and open the table. +*/ + +static void restore_table_state_after_repair(MARIA_HA *info, + MARIA_SHARE *org_share) +{ + maria_versioning(info, info->s->have_versioning); + info->s->lock_key_trees= org_share->lock_key_trees; +} + + + + /** @brief Drop all indexes @@ -2481,11 +2502,11 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info, char llbuff[22],llbuff2[22]; MARIA_SORT_INFO sort_info; MARIA_SORT_PARAM sort_param; - my_bool block_record, scan_inited= 0, - reenable_logging= share->now_transactional; + my_bool block_record, scan_inited= 0, reenable_logging= 0; enum data_file_type org_data_file_type= share->data_file_type; myf sync_dir= ((share->now_transactional && !share->temporary) ? MY_SYNC_DIR : 0); + MARIA_SHARE backup_share; DBUG_ENTER("maria_repair"); got_error= 1; @@ -2498,10 +2519,10 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info, } if (initialize_variables_for_repair(param, &sort_info, &sort_param, info, - rep_quick)) + rep_quick, &backup_share)) goto err; - if (reenable_logging) + if ((reenable_logging= share->now_transactional)) _ma_tmp_disable_logging_for_table(info, 0); sort_param.current_filepos= sort_param.filepos= new_header_length= @@ -2780,6 +2801,7 @@ err: /* If caller had disabled logging it's not up to us to re-enable it */ if (reenable_logging) _ma_reenable_logging_for_table(info, FALSE); + restore_table_state_after_repair(info, &backup_share); my_free(sort_param.rec_buff, MYF(MY_ALLOW_ZERO_PTR)); my_free(sort_param.record,MYF(MY_ALLOW_ZERO_PTR)); @@ -3550,7 +3572,8 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info, ulonglong key_map; myf sync_dir= ((share->now_transactional && !share->temporary) ? MY_SYNC_DIR : 0); - my_bool scan_inited= 0; + my_bool scan_inited= 0, reenable_logging= 0; + MARIA_SHARE backup_share; DBUG_ENTER("maria_repair_by_sort"); LINT_INIT(key_map); @@ -3564,9 +3587,12 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info, } if (initialize_variables_for_repair(param, &sort_info, &sort_param, info, - rep_quick)) + rep_quick, &backup_share)) goto err; + if ((reenable_logging= share->now_transactional)) + _ma_tmp_disable_logging_for_table(info, 0); + org_header_length= share->pack.header_length; new_header_length= (param->testflag & T_UNPACK) ? 0 : org_header_length; sort_param.filepos= new_header_length; @@ -3972,6 +3998,11 @@ err: share->state.changed&= ~(STATE_NOT_OPTIMIZED_ROWS | STATE_NOT_ZEROFILLED | STATE_NOT_MOVABLE); + /* If caller had disabled logging it's not up to us to re-enable it */ + if (reenable_logging) + _ma_reenable_logging_for_table(info, FALSE); + restore_table_state_after_repair(info, &backup_share); + my_free(sort_param.rec_buff, MYF(MY_ALLOW_ZERO_PTR)); my_free(sort_param.record,MYF(MY_ALLOW_ZERO_PTR)); my_free(sort_info.key_block, MYF(MY_ALLOW_ZERO_PTR)); @@ -4042,10 +4073,12 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info, IO_CACHE new_data_cache; /* For non-quick repair. */ IO_CACHE_SHARE io_share; MARIA_SORT_INFO sort_info; + MARIA_SHARE backup_share; ulonglong key_map; pthread_attr_t thr_attr; myf sync_dir= ((share->now_transactional && !share->temporary) ? MY_SYNC_DIR : 0); + my_bool reenable_logging= 0; DBUG_ENTER("maria_repair_parallel"); LINT_INIT(key_map); @@ -4059,9 +4092,12 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info, } if (initialize_variables_for_repair(param, &sort_info, &tmp_sort_param, info, - rep_quick)) + rep_quick, &backup_share)) goto err; + if ((reenable_logging= share->now_transactional)) + _ma_tmp_disable_logging_for_table(info, 0); + new_header_length= ((param->testflag & T_UNPACK) ? 0 : share->pack.header_length); @@ -4489,6 +4525,11 @@ err: pthread_cond_destroy (&sort_info.cond); pthread_mutex_destroy(&sort_info.mutex); + /* If caller had disabled logging it's not up to us to re-enable it */ + if (reenable_logging) + _ma_reenable_logging_for_table(info, FALSE); + restore_table_state_after_repair(info, &backup_share); + my_free(sort_info.ft_buf, MYF(MY_ALLOW_ZERO_PTR)); my_free(sort_info.key_block,MYF(MY_ALLOW_ZERO_PTR)); my_free(sort_param,MYF(MY_ALLOW_ZERO_PTR)); diff --git a/storage/maria/ma_state.c b/storage/maria/ma_state.c index cc5eea578a5..c7eee7d511d 100644 --- a/storage/maria/ma_state.c +++ b/storage/maria/ma_state.c @@ -678,6 +678,7 @@ void maria_versioning(MARIA_HA *info, my_bool versioning) info->lock.type= versioning ? TL_WRITE_CONCURRENT_INSERT : TL_WRITE; _ma_block_get_status((void*) info, versioning); info->lock.type= save_lock_type; + info->state= info->state_start= &info->s->state.common; } } diff --git a/storage/maria/trnman.c b/storage/maria/trnman.c index 2e03606ca7c..0dbc8ed7fb3 100644 --- a/storage/maria/trnman.c +++ b/storage/maria/trnman.c @@ -176,7 +176,8 @@ int trnman_init(TrID initial_trid) trnman_active_transactions= 0; trnman_committed_transactions= 0; trnman_allocated_transactions= 0; - dummy_transaction_object.min_read_from= ~(TrID) 0; /* for recovery */ + /* This is needed for recovery and repair */ + dummy_transaction_object.min_read_from= ~(TrID) 0; pool= 0; global_trid_generator= initial_trid;