Commit f1f8ebc3 authored by Marko Mäkelä's avatar Marko Mäkelä

Merge 10.0 into 10.1

parents 6fbfb4c8 afb46158
--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
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;
--max_binlog_stmt_cache_size=18446744073709547520
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
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;
# 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;
......@@ -949,15 +949,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;
......@@ -970,23 +994,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
......@@ -1000,7 +1048,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);
}
......@@ -1077,7 +1125,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);
}
......
......@@ -4059,13 +4059,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;
......
......@@ -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 */
......
......@@ -2808,11 +2808,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);
}
}
......@@ -3252,6 +3251,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
......@@ -3406,15 +3410,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();
......
......@@ -3,7 +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, 2016, MariaDB Corporation
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
......@@ -601,7 +601,7 @@ create_log_file(
fprintf(stderr, "innodb_force_recovery_crash=%lu\n", \
srv_force_recovery_crash); \
fflush(stderr); \
abort(); \
exit(3); \
} \
} while (0)
#endif
......@@ -1573,8 +1573,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;
......@@ -1587,6 +1585,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);
/* This should be initialized early */
ut_init_timer();
......@@ -1632,22 +1643,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
ib_logf(IB_LOG_LEVEL_INFO,
......@@ -2358,7 +2354,6 @@ innobase_start_or_create_for_mysql(void)
trx_sys_create();
if (create_new_db) {
ut_a(!srv_read_only_mode);
mtr_start(&mtr);
......@@ -2472,24 +2467,100 @@ innobase_start_or_create_for_mysql(void)
LOG_CHECKPOINT, LSN_MAX,
min_flushed_lsn, max_flushed_lsn);
if (err != DB_SUCCESS) {
if (err == DB_SUCCESS) {
/* Initialize the change buffer. */
err = dict_boot();
}
return(DB_ERROR);
if (err != DB_SUCCESS) {
return(err);
}
/* 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. */
/* This must precede recv_apply_hashed_log_recs(TRUE). */
ib_bh = trx_sys_init_at_db_start();
err = dict_boot();
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(). */
err = recv_apply_hashed_log_recs(TRUE);
DBUG_PRINT("ib_log", ("apply completed"));
if (err != DB_SUCCESS) {
return(err);
}
}
if (!srv_read_only_mode) {
const ulint flags = FSP_FLAGS_PAGE_SSIZE();
for (ulint id = 0; id <= srv_undo_tablespaces; id++) {
if (fil_space_get(id)) {
fsp_flags_try_adjust(id, flags);
}
}
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);
}
}
ib_bh = trx_sys_init_at_db_start();
n_recovered_trx = UT_LIST_GET_LEN(trx_sys->rw_trx_list);
/* The purge system needs to create the purge view and
......@@ -2636,20 +2707,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 */
......@@ -2711,13 +2770,6 @@ innobase_start_or_create_for_mysql(void)
}
if (!srv_read_only_mode) {
const ulint flags = FSP_FLAGS_PAGE_SSIZE();
for (ulint id = 0; id <= srv_undo_tablespaces; id++) {
if (fil_space_get(id)) {
fsp_flags_try_adjust(id, flags);
}
}
/* Create the thread which watches the timeouts
for lock waits */
thread_handles[2 + SRV_MAX_N_IO_THREADS] = os_thread_create(
......@@ -2816,116 +2868,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);
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);
if (srv_print_verbose_log) {
ib_logf(IB_LOG_LEVEL_INFO,
"%s started; log sequence number " LSN_PF "",
......
......@@ -2,7 +2,7 @@
Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
Copyright (c) 2013, 2016, MariaDB Corporation. All Rights Reserved.
Copyright (c) 2013, 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
......@@ -2900,11 +2900,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);
}
}
......@@ -3351,6 +3350,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
......@@ -3505,15 +3509,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();
......
......@@ -631,7 +631,7 @@ create_log_file(
fprintf(stderr, "innodb_force_recovery_crash=%lu\n", \
srv_force_recovery_crash); \
fflush(stderr); \
abort(); \
exit(3); \
} \
} while (0)
#endif
......@@ -1631,8 +1631,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;
......@@ -1645,6 +1643,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);
/* This should be initialized early */
ut_init_timer();
......@@ -1690,22 +1701,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
......@@ -2437,7 +2433,6 @@ innobase_start_or_create_for_mysql(void)
trx_sys_create();
if (create_new_db) {
ut_a(!srv_read_only_mode);
init_log_online();
......@@ -2519,25 +2514,103 @@ 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);
}
/* 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(). */
err = recv_apply_hashed_log_recs(TRUE);
DBUG_PRINT("ib_log", ("apply completed"));
if (err != DB_SUCCESS) {
return(err);
}
}
if (!srv_read_only_mode) {
const ulint flags = FSP_FLAGS_PAGE_SSIZE();
for (ulint id = 0; id <= srv_undo_tablespaces; id++) {
if (fil_space_get(id)) {
fsp_flags_try_adjust(id, flags);
}
}
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);
}
}
n_recovered_trx = UT_LIST_GET_LEN(trx_sys->rw_trx_list);
/* The purge system needs to create the purge view and
......@@ -2690,20 +2763,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) {
......@@ -2768,13 +2829,6 @@ innobase_start_or_create_for_mysql(void)
}
if (!srv_read_only_mode) {
const ulint flags = FSP_FLAGS_PAGE_SSIZE();
for (ulint id = 0; id <= srv_undo_tablespaces; id++) {
if (fil_space_get(id)) {
fsp_flags_try_adjust(id, flags);
}
}
/* Create the thread which watches the timeouts
for lock waits */
thread_handles[2 + SRV_MAX_N_IO_THREADS] = os_thread_create(
......@@ -2877,116 +2931,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);
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);
if (!srv_file_per_table && srv_pass_corrupt_table) {
fprintf(stderr, "InnoDB: Warning:"
" The option innodb_file_per_table is disabled,"
......
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