From fbcdc3437c94314f69d255a303d791f704916653 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 17 Jan 2017 22:08:19 +0100 Subject: [PATCH 1/5] connect zip bug fix --- storage/connect/filamzip.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/connect/filamzip.cpp b/storage/connect/filamzip.cpp index 22fe95aebad82..6aca4631f32da 100644 --- a/storage/connect/filamzip.cpp +++ b/storage/connect/filamzip.cpp @@ -97,7 +97,7 @@ bool ZIPUTIL::WildMatch(PSZ pat, PSZ str) { if (!*++pat) return TRUE; goto loopStart; default: - if (mapCaseTable[(unsigned)*s] != mapCaseTable[(unsigned)*p]) + if (mapCaseTable[(uchar)*s] != mapCaseTable[(uchar)*p]) goto starCheck; break; } /* endswitch */ From 18ef02b04dfae21148c7397d088c7ffdfcd23c4e Mon Sep 17 00:00:00 2001 From: Sachin Setiya Date: Tue, 10 Jan 2017 10:08:04 +0530 Subject: [PATCH 2/5] MDEV-4774 Strangeness with max_binlog_stmt_cache_size Settings Problem:- When setting max_binlog_stmt_cache_size=18446744073709547520 from either command line or .cnf file, server fails to start. Solution:- Added one more function eval_num_suffix_ull , which uses strtoull to get unsigned ulonglong from string. And getopt_ull calls this function instead of eval_num_suffix. Also changed previous eval_num_suffix to eval_num_suffix_ll to remain consistent. --- .../binlog_max_binlog_stmt_cache_size.result | 31 ++++++++ .../t/binlog_max_binlog_stmt_cache_size.opt | 1 + .../t/binlog_max_binlog_stmt_cache_size.test | 22 ++++++ mysys/my_getopt.c | 72 +++++++++++++++---- 4 files changed, 114 insertions(+), 12 deletions(-) create mode 100644 mysql-test/suite/binlog/r/binlog_max_binlog_stmt_cache_size.result create mode 100644 mysql-test/suite/binlog/t/binlog_max_binlog_stmt_cache_size.opt create mode 100644 mysql-test/suite/binlog/t/binlog_max_binlog_stmt_cache_size.test diff --git a/mysql-test/suite/binlog/r/binlog_max_binlog_stmt_cache_size.result b/mysql-test/suite/binlog/r/binlog_max_binlog_stmt_cache_size.result new file mode 100644 index 0000000000000..cf4d7004195da --- /dev/null +++ b/mysql-test/suite/binlog/r/binlog_max_binlog_stmt_cache_size.result @@ -0,0 +1,31 @@ +select @@max_binlog_stmt_cache_size; +@@max_binlog_stmt_cache_size +18446744073709547520 +set global max_binlog_stmt_cache_size= 18446744073709547520; +select @@max_binlog_stmt_cache_size; +@@max_binlog_stmt_cache_size +18446744073709547520 +set global max_binlog_stmt_cache_size= 18446744073709547519; +Warnings: +Warning 1292 Truncated incorrect max_binlog_stmt_cache_size value: '18446744073709547519' +select @@max_binlog_stmt_cache_size; +@@max_binlog_stmt_cache_size +18446744073709543424 +set global max_binlog_stmt_cache_size= 18446744073709551615; +Warnings: +Warning 1292 Truncated incorrect max_binlog_stmt_cache_size value: '18446744073709551615' +select @@max_binlog_stmt_cache_size; +@@max_binlog_stmt_cache_size +18446744073709547520 +set global max_binlog_stmt_cache_size= 18446744073709551614; +Warnings: +Warning 1292 Truncated incorrect max_binlog_stmt_cache_size value: '18446744073709551614' +select @@max_binlog_stmt_cache_size; +@@max_binlog_stmt_cache_size +18446744073709547520 +set global max_binlog_stmt_cache_size= 18446744073709551616; +ERROR 42000: Incorrect argument type to variable 'max_binlog_stmt_cache_size' +select @@max_binlog_stmt_cache_size; +@@max_binlog_stmt_cache_size +18446744073709547520 +set global max_binlog_stmt_cache_size= 18446744073709547520; diff --git a/mysql-test/suite/binlog/t/binlog_max_binlog_stmt_cache_size.opt b/mysql-test/suite/binlog/t/binlog_max_binlog_stmt_cache_size.opt new file mode 100644 index 0000000000000..c52ef14d5d082 --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_max_binlog_stmt_cache_size.opt @@ -0,0 +1 @@ +--max_binlog_stmt_cache_size=18446744073709547520 diff --git a/mysql-test/suite/binlog/t/binlog_max_binlog_stmt_cache_size.test b/mysql-test/suite/binlog/t/binlog_max_binlog_stmt_cache_size.test new file mode 100644 index 0000000000000..f85eed3cea83e --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_max_binlog_stmt_cache_size.test @@ -0,0 +1,22 @@ +source include/have_log_bin.inc; +select @@max_binlog_stmt_cache_size; + +--let $cache_size=`select @@max_binlog_stmt_cache_size;` + +set global max_binlog_stmt_cache_size= 18446744073709547520; +select @@max_binlog_stmt_cache_size; + +set global max_binlog_stmt_cache_size= 18446744073709547519; +select @@max_binlog_stmt_cache_size; + +set global max_binlog_stmt_cache_size= 18446744073709551615; +select @@max_binlog_stmt_cache_size; + +set global max_binlog_stmt_cache_size= 18446744073709551614; +select @@max_binlog_stmt_cache_size; + +--error ER_WRONG_TYPE_FOR_VAR +set global max_binlog_stmt_cache_size= 18446744073709551616; +select @@max_binlog_stmt_cache_size; + +--eval set global max_binlog_stmt_cache_size= $cache_size diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index 2a4557118b0c5..e68a08ee7359b 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -895,15 +895,39 @@ my_bool getopt_compare_strings(register const char *s, register const char *t, /* function: eval_num_suffix + Transforms suffix like k/m/g to their real value. +*/ + +static inline long eval_num_suffix(char *suffix, int *error) +{ + long num= 1; + if (*suffix == 'k' || *suffix == 'K') + num*= 1024L; + else if (*suffix == 'm' || *suffix == 'M') + num*= 1024L * 1024L; + else if (*suffix == 'g' || *suffix == 'G') + num*= 1024L * 1024L * 1024L; + else if (*suffix) + { + *error= 1; + return 0; + } + return num; +} + +/* + function: eval_num_suffix_ll + Transforms a number with a suffix to real number. Suffix can be k|K for kilo, m|M for mega or g|G for giga. */ -static longlong eval_num_suffix(char *argument, int *error, char *option_name) +static longlong eval_num_suffix_ll(char *argument, + int *error, char *option_name) { char *endchar; longlong num; - DBUG_ENTER("eval_num_suffix"); + DBUG_ENTER("eval_num_suffix_ll"); *error= 0; @@ -916,23 +940,47 @@ static longlong eval_num_suffix(char *argument, int *error, char *option_name) *error= 1; DBUG_RETURN(0); } - if (*endchar == 'k' || *endchar == 'K') - num*= 1024L; - else if (*endchar == 'm' || *endchar == 'M') - num*= 1024L * 1024L; - else if (*endchar == 'g' || *endchar == 'G') - num*= 1024L * 1024L * 1024L; - else if (*endchar) - { + num*= eval_num_suffix(endchar, error); + if (*error) fprintf(stderr, "Unknown suffix '%c' used for variable '%s' (value '%s')\n", *endchar, option_name, argument); + DBUG_RETURN(num); +} + +/* + function: eval_num_suffix_ull + + Transforms a number with a suffix to positive Integer. Suffix can + be k|K for kilo, m|M for mega or g|G for giga. +*/ + +static ulonglong eval_num_suffix_ull(char *argument, + int *error, char *option_name) +{ + char *endchar; + ulonglong num; + DBUG_ENTER("eval_num_suffix_ull"); + + *error= 0; + errno= 0; + num= strtoull(argument, &endchar, 10); + if (errno == ERANGE) + { + my_getopt_error_reporter(ERROR_LEVEL, + "Incorrect integer value: '%s'", argument); *error= 1; DBUG_RETURN(0); } + num*= eval_num_suffix(endchar, error); + if (*error) + fprintf(stderr, + "Unknown suffix '%c' used for variable '%s' (value '%s')\n", + *endchar, option_name, argument); DBUG_RETURN(num); } + /* function: getopt_ll @@ -946,7 +994,7 @@ static longlong eval_num_suffix(char *argument, int *error, char *option_name) static longlong getopt_ll(char *arg, const struct my_option *optp, int *err) { - longlong num=eval_num_suffix(arg, err, (char*) optp->name); + longlong num=eval_num_suffix_ll(arg, err, (char*) optp->name); return getopt_ll_limit_value(num, optp, NULL); } @@ -1023,7 +1071,7 @@ longlong getopt_ll_limit_value(longlong num, const struct my_option *optp, static ulonglong getopt_ull(char *arg, const struct my_option *optp, int *err) { - ulonglong num= eval_num_suffix(arg, err, (char*) optp->name); + ulonglong num= eval_num_suffix_ull(arg, err, (char*) optp->name); return getopt_ull_limit_value(num, optp, NULL); } From 8725b35d897cfad6e55217ae80e7c387e8dfe8da Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Tue, 24 Jan 2017 01:25:50 +0530 Subject: [PATCH 3/5] MDEV-11108: Assertion `uniq_tuple_length_arg <= table->file->max_key_length()' failed in SJ_TMP_TABLE::create_sj_weedout_tmp_table Removed the assert from the if clause to the else clause. --- sql/opt_subselect.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index a81b091461f7a..564a108c7660c 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -4044,13 +4044,13 @@ SJ_TMP_TABLE::create_sj_weedout_tmp_table(THD *thd) share->db_plugin= ha_lock_engine(0, TMP_ENGINE_HTON); table->file= get_new_handler(share, &table->mem_root, share->db_type()); - DBUG_ASSERT(uniq_tuple_length_arg <= table->file->max_key_length()); } else { share->db_plugin= ha_lock_engine(0, heap_hton); table->file= get_new_handler(share, &table->mem_root, share->db_type()); + DBUG_ASSERT(uniq_tuple_length_arg <= table->file->max_key_length()); } if (!table->file) goto err; From 49fe9bad01cbd7f66efd52171c4234636ba61276 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 25 Jan 2017 15:11:46 +0200 Subject: [PATCH 4/5] MDEV-11814 Refuse innodb_read_only startup if crash recovery is needed recv_scan_log_recs(): Remember if redo log apply is needed, even if starting up in innodb_read_only mode. recv_recovery_from_checkpoint_start_func(): Refuse innodb_read_only startup if redo log apply is needed. --- .../include/kill_and_restart_mysqld.inc | 19 ++ mysql-test/include/kill_mysqld.inc | 7 + mysql-test/include/search_pattern_in_file.inc | 41 ++-- mysql-test/include/start_mysqld.inc | 9 +- .../suite/innodb/r/log_file_size.result | 35 ++++ mysql-test/suite/innodb/t/log_file_size.test | 185 ++++++++++++++++++ storage/innobase/log/log0recv.cc | 14 +- storage/xtradb/log/log0recv.cc | 15 +- 8 files changed, 299 insertions(+), 26 deletions(-) create mode 100644 mysql-test/include/kill_and_restart_mysqld.inc create mode 100644 mysql-test/include/kill_mysqld.inc create mode 100644 mysql-test/suite/innodb/r/log_file_size.result create mode 100644 mysql-test/suite/innodb/t/log_file_size.test diff --git a/mysql-test/include/kill_and_restart_mysqld.inc b/mysql-test/include/kill_and_restart_mysqld.inc new file mode 100644 index 0000000000000..f2ac9b504d226 --- /dev/null +++ b/mysql-test/include/kill_and_restart_mysqld.inc @@ -0,0 +1,19 @@ +--let $_server_id= `SELECT @@server_id` +--let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.$_server_id.expect + +if ($restart_parameters) +{ + --echo # Kill and restart: $restart_parameters + --exec echo "restart: $restart_parameters" > $_expect_file_name +} +if (!$restart_parameters) +{ + --echo # Kill and restart + --exec echo "restart" > $_expect_file_name +} + +--shutdown_server 0 +--source include/wait_until_disconnected.inc +--enable_reconnect +--source include/wait_until_connected_again.inc +--disable_reconnect diff --git a/mysql-test/include/kill_mysqld.inc b/mysql-test/include/kill_mysqld.inc new file mode 100644 index 0000000000000..86ee048a0f18c --- /dev/null +++ b/mysql-test/include/kill_mysqld.inc @@ -0,0 +1,7 @@ +--let $_server_id= `SELECT @@server_id` +--let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.$_server_id.expect + +--echo # Kill the server +--exec echo "wait" > $_expect_file_name +--shutdown_server 0 +--source include/wait_until_disconnected.inc diff --git a/mysql-test/include/search_pattern_in_file.inc b/mysql-test/include/search_pattern_in_file.inc index 84237026ed06e..f77a7c6091607 100644 --- a/mysql-test/include/search_pattern_in_file.inc +++ b/mysql-test/include/search_pattern_in_file.inc @@ -60,25 +60,36 @@ perl; use strict; - my $search_file= $ENV{'SEARCH_FILE'} or die "SEARCH_FILE not set"; + die "SEARCH_FILE not set" unless $ENV{'SEARCH_FILE'}; + my @search_files= glob($ENV{'SEARCH_FILE'}); my $search_pattern= $ENV{'SEARCH_PATTERN'} or die "SEARCH_PATTERN not set"; my $search_range= $ENV{'SEARCH_RANGE'}; - my $file_content; + my $content; $search_range= 50000 unless $search_range =~ /-?[0-9]+/; - open(FILE, '<', $search_file) or die("Unable to open '$search_file': $!\n"); - if ($search_range >= 0) { - read(FILE, $file_content, $search_range, 0); - } else { - my $size= -s $search_file; - $search_range = -$size if $size > -$search_range; - seek(FILE, $search_range, 2); - read(FILE, $file_content, -$search_range, 0); + foreach my $search_file (@search_files) { + open(FILE, '<', $search_file) or die("Unable to open '$search_file': $!\n"); + my $file_content; + if ($search_range >= 0) { + read(FILE, $file_content, $search_range, 0); + } else { + my $size= -s $search_file; + $search_range = -$size if $size > -$search_range; + seek(FILE, $search_range, 2); + read(FILE, $file_content, -$search_range, 0); + } + close(FILE); + $content.= $file_content; } - close(FILE); - $search_file =~ s{^.*?([^/\\]+)$}{$1}; - if ($file_content =~ m{$search_pattern}) { - print "FOUND /$search_pattern/ in $search_file\n" + $ENV{'SEARCH_FILE'} =~ s{^.*?([^/\\]+)$}{$1}; + if ($content =~ m{$search_pattern}) { + die "FOUND /$search_pattern/ in $ENV{'SEARCH_FILE'}\n" + if $ENV{SEARCH_ABORT} eq 'FOUND'; + print "FOUND /$search_pattern/ in $ENV{'SEARCH_FILE'}\n" + unless defined $ENV{SEARCH_ABORT}; } else { - print "NOT FOUND /$search_pattern/ in $search_file\n" + die "NOT FOUND /$search_pattern/ in $ENV{'SEARCH_FILE'}\n" + if $ENV{SEARCH_ABORT} eq 'NOT FOUND'; + print "NOT FOUND /$search_pattern/ in $ENV{'SEARCH_FILE'}\n" + unless defined $ENV{SEARCH_ABORT}; } EOF diff --git a/mysql-test/include/start_mysqld.inc b/mysql-test/include/start_mysqld.inc index 983c566821e85..e31f26aad8c85 100644 --- a/mysql-test/include/start_mysqld.inc +++ b/mysql-test/include/start_mysqld.inc @@ -1,7 +1,14 @@ # Include this script only after using shutdown_mysqld.inc # where $_expect_file_name was initialized. # Write file to make mysql-test-run.pl start up the server again ---exec echo "restart" > $_expect_file_name +if ($restart_parameters) +{ + --exec echo "restart: $restart_parameters" > $_expect_file_name +} +if (!$restart_parameters) +{ + --exec echo "restart" > $_expect_file_name +} # Turn on reconnect --enable_reconnect diff --git a/mysql-test/suite/innodb/r/log_file_size.result b/mysql-test/suite/innodb/r/log_file_size.result new file mode 100644 index 0000000000000..1519f02a8c8a4 --- /dev/null +++ b/mysql-test/suite/innodb/r/log_file_size.result @@ -0,0 +1,35 @@ +call mtr.add_suppression("InnoDB: Resizing redo log"); +call mtr.add_suppression("InnoDB: Starting to delete and rewrite log files"); +call mtr.add_suppression("InnoDB: New log files created"); +call mtr.add_suppression("InnoDB: The log sequence numbers [0-9]+ and [0-9]+ in ibdata files do not match the log sequence number [0-9]+ in the ib_logfiles"); +CREATE TABLE t1(a INT PRIMARY KEY) ENGINE=InnoDB; +BEGIN; +INSERT INTO t1 VALUES (42); +# Kill and restart: --innodb-log-file-size=6M +SELECT * FROM t1; +a +INSERT INTO t1 VALUES (42); +BEGIN; +DELETE FROM t1; +# Kill and restart: --innodb-log-files-in-group=3 --innodb-log-file-size=5M +SELECT * FROM t1; +a +42 +INSERT INTO t1 VALUES (123); +BEGIN; +DELETE FROM t1; +# Kill the server +--innodb-force-recovery-crash=1 +--innodb-force-recovery-crash=3 +--innodb-force-recovery-crash=4 +--innodb-force-recovery-crash=5 +--innodb-force-recovery-crash=6 +--innodb-force-recovery-crash=7 +--innodb-force-recovery-crash=8 +--innodb-force-recovery-crash=9 +--innodb-force-recovery-crash=10 +SELECT * FROM t1; +a +42 +123 +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/log_file_size.test b/mysql-test/suite/innodb/t/log_file_size.test new file mode 100644 index 0000000000000..95a7bcc143af3 --- /dev/null +++ b/mysql-test/suite/innodb/t/log_file_size.test @@ -0,0 +1,185 @@ +# Test resizing the InnoDB redo log. + +--source include/have_innodb.inc + +# Embedded server does not support crashing +--source include/not_embedded.inc +# Avoid CrashReporter popup on Mac +--source include/not_crashrep.inc +# innodb-force-recovery-crash needs debug +--source include/have_debug.inc + +if (`SELECT @@innodb_log_file_size = 1048576`) { + --skip Test requires innodb_log_file_size>1M. +} + +call mtr.add_suppression("InnoDB: Resizing redo log"); +call mtr.add_suppression("InnoDB: Starting to delete and rewrite log files"); +call mtr.add_suppression("InnoDB: New log files created"); +call mtr.add_suppression("InnoDB: The log sequence numbers [0-9]+ and [0-9]+ in ibdata files do not match the log sequence number [0-9]+ in the ib_logfiles"); + +CREATE TABLE t1(a INT PRIMARY KEY) ENGINE=InnoDB; +BEGIN; +INSERT INTO t1 VALUES (42); + +let $restart_parameters = --innodb-log-file-size=6M; +--source include/kill_and_restart_mysqld.inc + +SELECT * FROM t1; + +INSERT INTO t1 VALUES (42); +BEGIN; +DELETE FROM t1; + +let $restart_parameters = --innodb-log-files-in-group=3 --innodb-log-file-size=5M; +--source include/kill_and_restart_mysqld.inc + +SELECT * FROM t1; + +INSERT INTO t1 VALUES (123); + +let MYSQLD_DATADIR= `select @@datadir`; +let SEARCH_ABORT = NOT FOUND; +let SEARCH_FILE= $MYSQLTEST_VARDIR/log/my_restart.err; +let $args=--innodb --unknown-option --loose-console --core-file > $SEARCH_FILE 2>&1; +let $crash=--innodb --unknown-option --loose-console > $SEARCH_FILE 2>&1 --innodb-force-recovery-crash; + +BEGIN; +DELETE FROM t1; + +--source include/kill_mysqld.inc + +--error 2 +--exec $MYSQLD_CMD $args --innodb-log-group-home-dir=foo\;bar +let SEARCH_PATTERN= syntax error in innodb_log_group_home_dir; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE + +--echo --innodb-force-recovery-crash=1 +--error 3 +--exec $MYSQLD_CMD $crash=1 +let SEARCH_PATTERN= InnoDB: Starting an apply batch of log records; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE +--echo --innodb-force-recovery-crash=3 +--error 3 +--exec $MYSQLD_CMD $crash=3 +let SEARCH_PATTERN= InnoDB: Starting an apply batch of log records; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE + +--error 2 +--exec $MYSQLD_CMD $args --innodb-read-only +let SEARCH_PATTERN= InnoDB: innodb_read_only prevents crash recovery; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE + +--echo --innodb-force-recovery-crash=4 +--error 3 +--exec $MYSQLD_CMD $crash=4 +let SEARCH_PATTERN= InnoDB: Starting an apply batch of log records; +--source include/search_pattern_in_file.inc +let SEARCH_PATTERN= InnoDB: Resizing redo log from 3\*[0-9]+ to 2\*[0-9]+ pages; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE +--echo --innodb-force-recovery-crash=5 +--error 3 +--exec $MYSQLD_CMD $crash=5 +let SEARCH_PATTERN= InnoDB: Starting an apply batch of log records; +--source include/search_pattern_in_file.inc +let SEARCH_PATTERN= InnoDB: Resizing redo log from 3\*[0-9]+ to 2\*[0-9]+ pages; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE + +--error 2 +--exec $MYSQLD_CMD $args --innodb-read-only +let SEARCH_PATTERN= InnoDB: innodb_read_only prevents crash recovery; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE + +--echo --innodb-force-recovery-crash=6 +--error 3 +--exec $MYSQLD_CMD $crash=6 +let SEARCH_PATTERN= InnoDB: Starting an apply batch of log records; +--source include/search_pattern_in_file.inc +let SEARCH_PATTERN= InnoDB: Resizing redo log from 3\*[0-9]+ to 2\*[0-9]+ pages; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE +--echo --innodb-force-recovery-crash=7 +--error 3 +--exec $MYSQLD_CMD $crash=7 +# this crashes right after deleting all log files +--remove_file $SEARCH_FILE + +--error 2 +--exec $MYSQLD_CMD $args --innodb-read-only +let SEARCH_PATTERN= InnoDB: Cannot create log files in read-only mode; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE + +--echo --innodb-force-recovery-crash=8 +--error 3 +--exec $MYSQLD_CMD $crash=8 +let SEARCH_PATTERN= InnoDB: Setting log file .*ib_logfile[0-9]+ size to; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE +--echo --innodb-force-recovery-crash=9 +--error 3 +--exec $MYSQLD_CMD $crash=9 +let SEARCH_PATTERN= InnoDB: Setting log file .*ib_logfile[0-9]+ size to; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE + +# We should have perfectly synced files here. +# Rename the log files, and trigger an error in recovery. +--move_file $MYSQLD_DATADIR/ib_logfile101 $MYSQLD_DATADIR/ib_logfile0 +--move_file $MYSQLD_DATADIR/ib_logfile1 $MYSQLD_DATADIR/ib_logfile1_hidden +--error 2 +--exec $MYSQLD_CMD $args +let SEARCH_PATTERN= InnoDB: Only one log file found; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE +--move_file $MYSQLD_DATADIR/ib_logfile0 $MYSQLD_DATADIR/ib_logfile101 + +perl; +die unless open(FILE, ">$ENV{MYSQLD_DATADIR}/ib_logfile0"); +print FILE "garbage"; +close(FILE); +EOF +--error 2 +--exec $MYSQLD_CMD $args +let SEARCH_PATTERN= InnoDB: Log file .*ib_logfile0 size 7 is not a multiple of innodb_page_size; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE +--remove_file $MYSQLD_DATADIR/ib_logfile0 +--move_file $MYSQLD_DATADIR/ib_logfile101 $MYSQLD_DATADIR/ib_logfile0 + +perl; +die unless open(FILE, ">$ENV{MYSQLD_DATADIR}/ib_logfile1"); +print FILE "junkfill" x 131072; +close(FILE); +EOF + +--error 2 +--exec $MYSQLD_CMD $args +let SEARCH_PATTERN= InnoDB: Log file .*ib_logfile1 is of different size 1048576 bytes than other log files; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE +--remove_file $MYSQLD_DATADIR/ib_logfile1 +--move_file $MYSQLD_DATADIR/ib_logfile0 $MYSQLD_DATADIR/ib_logfile101 +--move_file $MYSQLD_DATADIR/ib_logfile1_hidden $MYSQLD_DATADIR/ib_logfile1 + +--echo --innodb-force-recovery-crash=10 +--error 3 +--exec $MYSQLD_CMD $crash=10 +let SEARCH_PATTERN= InnoDB: Setting log file .*ib_logfile[0-9]+ size to; +--source include/search_pattern_in_file.inc +let SEARCH_PATTERN= InnoDB: Renaming log file .*ib_logfile101 to .*ib_logfile0; +--source include/search_pattern_in_file.inc +--remove_file $SEARCH_FILE + +--let $restart_parameters= +--source include/start_mysqld.inc + +SELECT * FROM t1; +DROP TABLE t1; diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index aed94d0083456..e52448c87f634 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -2806,11 +2806,10 @@ recv_scan_log_recs( recv_init_crash_recovery(); } else { - - ib_logf(IB_LOG_LEVEL_WARN, - "Recovery skipped, " - "--innodb-read-only set!"); - + ib_logf(IB_LOG_LEVEL_ERROR, + "innodb_read_only prevents" + " crash recovery"); + recv_needed_recovery = TRUE; return(TRUE); } } @@ -3227,6 +3226,11 @@ recv_recovery_from_checkpoint_start_func( /* Done with startup scan. Clear the flag. */ recv_log_scan_is_startup_type = FALSE; + + if (srv_read_only_mode && recv_needed_recovery) { + return(DB_READ_ONLY); + } + if (TYPE_CHECKPOINT) { /* NOTE: we always do a 'recovery' at startup, but only if there is something wrong we will print a message to the diff --git a/storage/xtradb/log/log0recv.cc b/storage/xtradb/log/log0recv.cc index 9e42fb5cc1ccd..a66172ac86162 100644 --- a/storage/xtradb/log/log0recv.cc +++ b/storage/xtradb/log/log0recv.cc @@ -2,6 +2,7 @@ Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. +Copyright (c) 2017, MariaDB Corporation. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -2895,11 +2896,10 @@ recv_scan_log_recs( recv_init_crash_recovery(); } else { - - ib_logf(IB_LOG_LEVEL_WARN, - "Recovery skipped, " - "--innodb-read-only set!"); - + ib_logf(IB_LOG_LEVEL_ERROR, + "innodb_read_only prevents" + " crash recovery"); + recv_needed_recovery = TRUE; return(TRUE); } } @@ -3323,6 +3323,11 @@ recv_recovery_from_checkpoint_start_func( /* Done with startup scan. Clear the flag. */ recv_log_scan_is_startup_type = FALSE; + + if (srv_read_only_mode && recv_needed_recovery) { + return(DB_READ_ONLY); + } + if (TYPE_CHECKPOINT) { /* NOTE: we always do a 'recovery' at startup, but only if there is something wrong we will print a message to the From afb461587c0b7dea2e5e70a165e8d4d437c3f964 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 26 Jan 2017 14:05:00 +0200 Subject: [PATCH 5/5] MDEV-11915 Detect InnoDB system tablespace size mismatch early InnoDB would refuse to start up if there is a mismatch on the size of the system tablespace files. However, before this check is conducted, the system tablespace may already have been heavily modified. InnoDB should perform the size check as early as possible. recv_recovery_from_checkpoint_finish(): Move the recv_apply_hashed_log_recs() call to innobase_start_or_create_for_mysql(). innobase_start_or_create_for_mysql(): Test the mutex functionality before doing anything else. Use a compile_time_assert() for a sizeof() constraint. Check the size of the system tablespace as early as possible. --- storage/innobase/log/log0recv.cc | 9 -- storage/innobase/srv/srv0start.cc | 252 +++++++++++------------------- storage/xtradb/log/log0recv.cc | 9 -- storage/xtradb/srv/srv0start.cc | 251 +++++++++++------------------ 4 files changed, 182 insertions(+), 339 deletions(-) diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index e52448c87f634..70913bd49cee5 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -3381,15 +3381,6 @@ void recv_recovery_from_checkpoint_finish(void) /*======================================*/ { - /* Apply the hashed log records to the respective file pages */ - - if (srv_force_recovery < SRV_FORCE_NO_LOG_REDO) { - - recv_apply_hashed_log_recs(TRUE); - } - - DBUG_PRINT("ib_log", ("apply completed")); - if (recv_needed_recovery) { trx_sys_print_mysql_master_log_pos(); trx_sys_print_mysql_binlog_offset(); diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 5c3bee5e0b70c..0e7d4b6c51197 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -3,6 +3,7 @@ Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved. Copyright (c) 2008, Google Inc. Copyright (c) 2009, Percona Inc. +Copyright (c) 2013, 2017, MariaDB Corporation Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -1550,8 +1551,6 @@ innobase_start_or_create_for_mysql(void) ulint max_arch_log_no; #endif /* UNIV_LOG_ARCHIVE */ ulint sum_of_new_sizes; - ulint sum_of_data_file_sizes; - ulint tablespace_size_in_header; dberr_t err; unsigned i; ulint srv_n_log_files_found = srv_n_log_files; @@ -1564,6 +1563,19 @@ innobase_start_or_create_for_mysql(void) size_t dirnamelen; bool sys_datafiles_created = false; + /* Check that os_fast_mutexes work as expected */ + os_fast_mutex_init(PFS_NOT_INSTRUMENTED, &srv_os_test_mutex); + + ut_a(0 == os_fast_mutex_trylock(&srv_os_test_mutex)); + + os_fast_mutex_unlock(&srv_os_test_mutex); + + os_fast_mutex_lock(&srv_os_test_mutex); + + os_fast_mutex_unlock(&srv_os_test_mutex); + + os_fast_mutex_free(&srv_os_test_mutex); + high_level_read_only = srv_read_only_mode || srv_force_recovery > SRV_FORCE_NO_TRX_UNDO; @@ -1606,22 +1618,7 @@ innobase_start_or_create_for_mysql(void) #endif /* PAGE_ATOMIC_REF_COUNT */ ); - - if (sizeof(ulint) != sizeof(void*)) { - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: Error: size of InnoDB's ulint is %lu, " - "but size of void*\n", (ulong) sizeof(ulint)); - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: is %lu. The sizes should be the same " - "so that on a 64-bit\n", - (ulong) sizeof(void*)); - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: platforms you can allocate more than 4 GB " - "of memory.\n"); - } + compile_time_assert(sizeof(ulint) == sizeof(void*)); #ifdef UNIV_DEBUG ut_print_timestamp(stderr); @@ -2332,7 +2329,6 @@ innobase_start_or_create_for_mysql(void) trx_sys_create(); if (create_new_db) { - ut_a(!srv_read_only_mode); mtr_start(&mtr); @@ -2446,24 +2442,89 @@ innobase_start_or_create_for_mysql(void) LOG_CHECKPOINT, LSN_MAX, min_flushed_lsn, max_flushed_lsn); + if (err == DB_SUCCESS) { + /* Initialize the change buffer. */ + err = dict_boot(); + } + if (err != DB_SUCCESS) { + return(err); + } - return(DB_ERROR); + if (!srv_read_only_mode) { + if (sum_of_new_sizes > 0) { + /* New data file(s) were added */ + mtr_start(&mtr); + fsp_header_inc_size(0, sum_of_new_sizes, &mtr); + mtr_commit(&mtr); + /* Immediately write the log record about + increased tablespace size to disk, so that it + is durable even if mysqld would crash + quickly */ + log_buffer_flush_to_disk(); + } } - /* Since the insert buffer init is in dict_boot, and the - insert buffer is needed in any disk i/o, first we call - dict_boot(). Note that trx_sys_init_at_db_start() only needs - to access space 0, and the insert buffer at this stage already - works for space 0. */ + const ulint tablespace_size_in_header + = fsp_header_get_tablespace_size(); - err = dict_boot(); +#ifdef UNIV_DEBUG + /* buf_debug_prints = TRUE; */ +#endif /* UNIV_DEBUG */ + ulint sum_of_data_file_sizes = 0; + + for (ulint d = 0; d < srv_n_data_files; d++) { + sum_of_data_file_sizes += srv_data_file_sizes[d]; + } + + /* Compare the system tablespace file size to what is + stored in FSP_SIZE. In open_or_create_data_files() + we already checked that the file sizes match the + innodb_data_file_path specification. */ + if (srv_read_only_mode + || sum_of_data_file_sizes == tablespace_size_in_header) { + /* Do not complain about the size. */ + } else if (!srv_auto_extend_last_data_file + || sum_of_data_file_sizes + < tablespace_size_in_header) { + ib_logf(IB_LOG_LEVEL_ERROR, + "Tablespace size stored in header is " ULINTPF + " pages, but the sum of data file sizes is " + ULINTPF " pages", + tablespace_size_in_header, + sum_of_data_file_sizes); + + if (srv_force_recovery == 0 + && sum_of_data_file_sizes + < tablespace_size_in_header) { + ib_logf(IB_LOG_LEVEL_ERROR, + "Cannot start InnoDB. The tail of" + " the system tablespace is" + " missing. Have you edited" + " innodb_data_file_path in my.cnf" + " in an inappropriate way, removing" + " data files from there?" + " You can set innodb_force_recovery=1" + " in my.cnf to force" + " a startup if you are trying to" + " recover a badly corrupt database."); - if (err != DB_SUCCESS) { - return(err); + return(DB_ERROR); + } } + /* This must precede recv_apply_hashed_log_recs(TRUE). */ ib_bh = trx_sys_init_at_db_start(); + + if (srv_force_recovery < SRV_FORCE_NO_LOG_REDO) { + /* Apply the hashed log records to the + respective file pages, for the last batch of + recv_group_scan_log_recs(). */ + + recv_apply_hashed_log_recs(TRUE); + DBUG_PRINT("ib_log", ("apply completed")); + } + n_recovered_trx = UT_LIST_GET_LEN(trx_sys->rw_trx_list); /* The purge system needs to create the purge view and @@ -2610,20 +2671,8 @@ innobase_start_or_create_for_mysql(void) trx_sys_file_format_tag_init(); } - if (!create_new_db && sum_of_new_sizes > 0) { - /* New data file(s) were added */ - mtr_start(&mtr); - - fsp_header_inc_size(0, sum_of_new_sizes, &mtr); - - mtr_commit(&mtr); - - /* Immediately write the log record about increased tablespace - size to disk, so that it is durable even if mysqld would crash - quickly */ - - log_buffer_flush_to_disk(); - } + ut_ad(err == DB_SUCCESS); + ut_a(sum_of_new_sizes != ULINT_UNDEFINED); #ifdef UNIV_LOG_ARCHIVE /* Archiving is always off under MySQL */ @@ -2766,125 +2815,6 @@ innobase_start_or_create_for_mysql(void) buf_flush_page_cleaner_thread_started = true; } -#ifdef UNIV_DEBUG - /* buf_debug_prints = TRUE; */ -#endif /* UNIV_DEBUG */ - sum_of_data_file_sizes = 0; - - for (i = 0; i < srv_n_data_files; i++) { - sum_of_data_file_sizes += srv_data_file_sizes[i]; - } - - tablespace_size_in_header = fsp_header_get_tablespace_size(); - - if (!srv_read_only_mode - && !srv_auto_extend_last_data_file - && sum_of_data_file_sizes != tablespace_size_in_header) { - - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: Error: tablespace size" - " stored in header is %lu pages, but\n", - (ulong) tablespace_size_in_header); - ut_print_timestamp(stderr); - fprintf(stderr, - "InnoDB: the sum of data file sizes is %lu pages\n", - (ulong) sum_of_data_file_sizes); - - if (srv_force_recovery == 0 - && sum_of_data_file_sizes < tablespace_size_in_header) { - /* This is a fatal error, the tail of a tablespace is - missing */ - - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: Cannot start InnoDB." - " The tail of the system tablespace is\n"); - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: missing. Have you edited" - " innodb_data_file_path in my.cnf in an\n"); - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: inappropriate way, removing" - " ibdata files from there?\n"); - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: You can set innodb_force_recovery=1" - " in my.cnf to force\n"); - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: a startup if you are trying" - " to recover a badly corrupt database.\n"); - - return(DB_ERROR); - } - } - - if (!srv_read_only_mode - && srv_auto_extend_last_data_file - && sum_of_data_file_sizes < tablespace_size_in_header) { - - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: Error: tablespace size stored in header" - " is %lu pages, but\n", - (ulong) tablespace_size_in_header); - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: the sum of data file sizes" - " is only %lu pages\n", - (ulong) sum_of_data_file_sizes); - - if (srv_force_recovery == 0) { - - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: Cannot start InnoDB. The tail of" - " the system tablespace is\n"); - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: missing. Have you edited" - " innodb_data_file_path in my.cnf in an\n"); - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: inappropriate way, removing" - " ibdata files from there?\n"); - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: You can set innodb_force_recovery=1" - " in my.cnf to force\n"); - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: a startup if you are trying to" - " recover a badly corrupt database.\n"); - - return(DB_ERROR); - } - } - - /* Check that os_fast_mutexes work as expected */ - os_fast_mutex_init(PFS_NOT_INSTRUMENTED, &srv_os_test_mutex); - - if (0 != os_fast_mutex_trylock(&srv_os_test_mutex)) { - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: Error: pthread_mutex_trylock returns" - " an unexpected value on\n"); - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: success! Cannot continue.\n"); - exit(1); - } - - os_fast_mutex_unlock(&srv_os_test_mutex); - - os_fast_mutex_lock(&srv_os_test_mutex); - - os_fast_mutex_unlock(&srv_os_test_mutex); - - os_fast_mutex_free(&srv_os_test_mutex); - if (srv_print_verbose_log) { ib_logf(IB_LOG_LEVEL_INFO, "%s started; log sequence number " LSN_PF "", diff --git a/storage/xtradb/log/log0recv.cc b/storage/xtradb/log/log0recv.cc index a66172ac86162..e355c25318c6b 100644 --- a/storage/xtradb/log/log0recv.cc +++ b/storage/xtradb/log/log0recv.cc @@ -3478,15 +3478,6 @@ void recv_recovery_from_checkpoint_finish(void) /*======================================*/ { - /* Apply the hashed log records to the respective file pages */ - - if (srv_force_recovery < SRV_FORCE_NO_LOG_REDO) { - - recv_apply_hashed_log_recs(TRUE); - } - - DBUG_PRINT("ib_log", ("apply completed")); - if (recv_needed_recovery) { trx_sys_print_mysql_master_log_pos(); trx_sys_print_mysql_binlog_offset(); diff --git a/storage/xtradb/srv/srv0start.cc b/storage/xtradb/srv/srv0start.cc index 9f426a8b51331..a19f120a7d880 100644 --- a/storage/xtradb/srv/srv0start.cc +++ b/storage/xtradb/srv/srv0start.cc @@ -1609,8 +1609,6 @@ innobase_start_or_create_for_mysql(void) lsn_t max_arch_log_no = LSN_MAX; #endif /* UNIV_LOG_ARCHIVE */ ulint sum_of_new_sizes; - ulint sum_of_data_file_sizes; - ulint tablespace_size_in_header; dberr_t err; unsigned i; ulint srv_n_log_files_found = srv_n_log_files; @@ -1623,6 +1621,19 @@ innobase_start_or_create_for_mysql(void) size_t dirnamelen; bool sys_datafiles_created = false; + /* Check that os_fast_mutexes work as expected */ + os_fast_mutex_init(PFS_NOT_INSTRUMENTED, &srv_os_test_mutex); + + ut_a(0 == os_fast_mutex_trylock(&srv_os_test_mutex)); + + os_fast_mutex_unlock(&srv_os_test_mutex); + + os_fast_mutex_lock(&srv_os_test_mutex); + + os_fast_mutex_unlock(&srv_os_test_mutex); + + os_fast_mutex_free(&srv_os_test_mutex); + high_level_read_only = srv_read_only_mode || srv_force_recovery > SRV_FORCE_NO_TRX_UNDO; @@ -1665,22 +1676,7 @@ innobase_start_or_create_for_mysql(void) #endif /* PAGE_ATOMIC_REF_COUNT */ ); - - if (sizeof(ulint) != sizeof(void*)) { - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: Error: size of InnoDB's ulint is %lu, " - "but size of void*\n", (ulong) sizeof(ulint)); - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: is %lu. The sizes should be the same " - "so that on a 64-bit\n", - (ulong) sizeof(void*)); - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: platforms you can allocate more than 4 GB " - "of memory.\n"); - } + compile_time_assert(sizeof(ulint) == sizeof(void*)); /* If stacktrace is used we set up signal handler for SIGUSR2 signal here. If signal handler set fails we report that and disable @@ -2411,7 +2407,6 @@ innobase_start_or_create_for_mysql(void) trx_sys_create(); if (create_new_db) { - ut_a(!srv_read_only_mode); init_log_online(); @@ -2493,25 +2488,92 @@ innobase_start_or_create_for_mysql(void) min_flushed_lsn, max_flushed_lsn); if (err != DB_SUCCESS) { - - return(DB_ERROR); + return(err); } init_log_online(); - /* Since the insert buffer init is in dict_boot, and the - insert buffer is needed in any disk i/o, first we call - dict_boot(). Note that trx_sys_init_at_db_start() only needs - to access space 0, and the insert buffer at this stage already - works for space 0. */ - + /* Initialize the change buffer. */ err = dict_boot(); if (err != DB_SUCCESS) { return(err); } + if (!srv_read_only_mode) { + if (sum_of_new_sizes > 0) { + /* New data file(s) were added */ + mtr_start(&mtr); + fsp_header_inc_size(0, sum_of_new_sizes, &mtr); + mtr_commit(&mtr); + /* Immediately write the log record about + increased tablespace size to disk, so that it + is durable even if mysqld would crash + quickly */ + log_buffer_flush_to_disk(); + } + } + + const ulint tablespace_size_in_header + = fsp_header_get_tablespace_size(); + +#ifdef UNIV_DEBUG + /* buf_debug_prints = TRUE; */ +#endif /* UNIV_DEBUG */ + ulint sum_of_data_file_sizes = 0; + + for (ulint d = 0; d < srv_n_data_files; d++) { + sum_of_data_file_sizes += srv_data_file_sizes[d]; + } + + /* Compare the system tablespace file size to what is + stored in FSP_SIZE. In open_or_create_data_files() + we already checked that the file sizes match the + innodb_data_file_path specification. */ + if (srv_read_only_mode + || sum_of_data_file_sizes == tablespace_size_in_header) { + /* Do not complain about the size. */ + } else if (!srv_auto_extend_last_data_file + || sum_of_data_file_sizes + < tablespace_size_in_header) { + ib_logf(IB_LOG_LEVEL_ERROR, + "Tablespace size stored in header is " ULINTPF + " pages, but the sum of data file sizes is " + ULINTPF " pages", + tablespace_size_in_header, + sum_of_data_file_sizes); + + if (srv_force_recovery == 0 + && sum_of_data_file_sizes + < tablespace_size_in_header) { + ib_logf(IB_LOG_LEVEL_ERROR, + "Cannot start InnoDB. The tail of" + " the system tablespace is" + " missing. Have you edited" + " innodb_data_file_path in my.cnf" + " in an inappropriate way, removing" + " data files from there?" + " You can set innodb_force_recovery=1" + " in my.cnf to force" + " a startup if you are trying to" + " recover a badly corrupt database."); + + return(DB_ERROR); + } + } + + /* This must precede recv_apply_hashed_log_recs(TRUE). */ ib_bh = trx_sys_init_at_db_start(); + + if (srv_force_recovery < SRV_FORCE_NO_LOG_REDO) { + /* Apply the hashed log records to the + respective file pages, for the last batch of + recv_group_scan_log_recs(). */ + + recv_apply_hashed_log_recs(TRUE); + DBUG_PRINT("ib_log", ("apply completed")); + } + n_recovered_trx = UT_LIST_GET_LEN(trx_sys->rw_trx_list); /* The purge system needs to create the purge view and @@ -2664,20 +2726,8 @@ innobase_start_or_create_for_mysql(void) trx_sys_file_format_tag_init(); } - if (!create_new_db && sum_of_new_sizes > 0) { - /* New data file(s) were added */ - mtr_start(&mtr); - - fsp_header_inc_size(0, sum_of_new_sizes, &mtr); - - mtr_commit(&mtr); - - /* Immediately write the log record about increased tablespace - size to disk, so that it is durable even if mysqld would crash - quickly */ - - log_buffer_flush_to_disk(); - } + ut_ad(err == DB_SUCCESS); + ut_a(sum_of_new_sizes != ULINT_UNDEFINED); #ifdef UNIV_LOG_ARCHIVE if (!srv_read_only_mode) { @@ -2826,125 +2876,6 @@ innobase_start_or_create_for_mysql(void) buf_flush_lru_manager_thread_handle = os_thread_create(buf_flush_lru_manager_thread, NULL, NULL); buf_flush_lru_manager_thread_started = true; -#ifdef UNIV_DEBUG - /* buf_debug_prints = TRUE; */ -#endif /* UNIV_DEBUG */ - sum_of_data_file_sizes = 0; - - for (i = 0; i < srv_n_data_files; i++) { - sum_of_data_file_sizes += srv_data_file_sizes[i]; - } - - tablespace_size_in_header = fsp_header_get_tablespace_size(); - - if (!srv_read_only_mode - && !srv_auto_extend_last_data_file - && sum_of_data_file_sizes != tablespace_size_in_header) { - - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: Error: tablespace size" - " stored in header is %lu pages, but\n", - (ulong) tablespace_size_in_header); - ut_print_timestamp(stderr); - fprintf(stderr, - "InnoDB: the sum of data file sizes is %lu pages\n", - (ulong) sum_of_data_file_sizes); - - if (srv_force_recovery == 0 - && sum_of_data_file_sizes < tablespace_size_in_header) { - /* This is a fatal error, the tail of a tablespace is - missing */ - - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: Cannot start InnoDB." - " The tail of the system tablespace is\n"); - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: missing. Have you edited" - " innodb_data_file_path in my.cnf in an\n"); - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: inappropriate way, removing" - " ibdata files from there?\n"); - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: You can set innodb_force_recovery=1" - " in my.cnf to force\n"); - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: a startup if you are trying" - " to recover a badly corrupt database.\n"); - - return(DB_ERROR); - } - } - - if (!srv_read_only_mode - && srv_auto_extend_last_data_file - && sum_of_data_file_sizes < tablespace_size_in_header) { - - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: Error: tablespace size stored in header" - " is %lu pages, but\n", - (ulong) tablespace_size_in_header); - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: the sum of data file sizes" - " is only %lu pages\n", - (ulong) sum_of_data_file_sizes); - - if (srv_force_recovery == 0) { - - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: Cannot start InnoDB. The tail of" - " the system tablespace is\n"); - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: missing. Have you edited" - " innodb_data_file_path in my.cnf in an\n"); - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: inappropriate way, removing" - " ibdata files from there?\n"); - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: You can set innodb_force_recovery=1" - " in my.cnf to force\n"); - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: a startup if you are trying to" - " recover a badly corrupt database.\n"); - - return(DB_ERROR); - } - } - - /* Check that os_fast_mutexes work as expected */ - os_fast_mutex_init(PFS_NOT_INSTRUMENTED, &srv_os_test_mutex); - - if (0 != os_fast_mutex_trylock(&srv_os_test_mutex)) { - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: Error: pthread_mutex_trylock returns" - " an unexpected value on\n"); - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: success! Cannot continue.\n"); - exit(1); - } - - os_fast_mutex_unlock(&srv_os_test_mutex); - - os_fast_mutex_lock(&srv_os_test_mutex); - - os_fast_mutex_unlock(&srv_os_test_mutex); - - os_fast_mutex_free(&srv_os_test_mutex); - if (!srv_file_per_table && srv_pass_corrupt_table) { fprintf(stderr, "InnoDB: Warning:" " The option innodb_file_per_table is disabled,"