diff --git a/mysql-test/suite/encryption/r/innodb_lotoftables.result b/mysql-test/suite/encryption/r/innodb_lotoftables.result index 9dadf13f039..45800c8cd0b 100644 --- a/mysql-test/suite/encryption/r/innodb_lotoftables.result +++ b/mysql-test/suite/encryption/r/innodb_lotoftables.result @@ -774,49 +774,37 @@ Innodb_pages0_read 4 # Success! # Restart mysqld --innodb_encrypt_tables=0 --innodb_encryption_threads=0 # Restart Success! -show status like 'innodb_pages0_read%'; -Variable_name Value -Innodb_pages0_read 304 -show status like 'innodb_pages0_read%'; -Variable_name Value -Innodb_pages0_read 304 +SELECT variable_value <= 303 FROM information_schema.global_status WHERE variable_name = 'innodb_pages0_read'; +variable_value <= 303 +1 use test; -show status like 'innodb_pages0_read%'; -Variable_name Value -Innodb_pages0_read 304 +SELECT variable_value <= 303 FROM information_schema.global_status WHERE variable_name = 'innodb_pages0_read'; +variable_value <= 303 +1 use innodb_encrypted_1; -show status like 'innodb_pages0_read%'; -Variable_name Value -Innodb_pages0_read 304 +SELECT variable_value <= 303 FROM information_schema.global_status WHERE variable_name = 'innodb_pages0_read'; +variable_value <= 303 +1 use innodb_encrypted_2; -show status like 'innodb_pages0_read%'; -Variable_name Value -Innodb_pages0_read 304 +SELECT variable_value <= 303 FROM information_schema.global_status WHERE variable_name = 'innodb_pages0_read'; +variable_value <= 303 +1 use innodb_encrypted_3; -show status like 'innodb_pages0_read%'; -Variable_name Value -Innodb_pages0_read 304 +SELECT variable_value <= 303 FROM information_schema.global_status WHERE variable_name = 'innodb_pages0_read'; +variable_value <= 303 +1 use innodb_encrypted_1; -show status like 'innodb_pages0_read%'; -Variable_name Value -Innodb_pages0_read 304 -show status like 'innodb_pages0_read%'; -Variable_name Value -Innodb_pages0_read 304 +SELECT variable_value <= 303 FROM information_schema.global_status WHERE variable_name = 'innodb_pages0_read'; +variable_value <= 303 +1 use innodb_encrypted_2; -show status like 'innodb_pages0_read%'; -Variable_name Value -Innodb_pages0_read 304 -show status like 'innodb_pages0_read%'; -Variable_name Value -Innodb_pages0_read 304 +SELECT variable_value <= 303 FROM information_schema.global_status WHERE variable_name = 'innodb_pages0_read'; +variable_value <= 303 +1 use innodb_encrypted_3; -show status like 'innodb_pages0_read%'; -Variable_name Value -Innodb_pages0_read 304 -show status like 'innodb_pages0_read%'; -Variable_name Value -Innodb_pages0_read 304 +SELECT variable_value <= 303 FROM information_schema.global_status WHERE variable_name = 'innodb_pages0_read'; +variable_value <= 303 +1 SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME; NAME innodb_encrypted_3/t_1 diff --git a/mysql-test/suite/encryption/t/innodb_lotoftables.test b/mysql-test/suite/encryption/t/innodb_lotoftables.test index cd3c6a30c07..4ccdc7d5c49 100644 --- a/mysql-test/suite/encryption/t/innodb_lotoftables.test +++ b/mysql-test/suite/encryption/t/innodb_lotoftables.test @@ -148,20 +148,19 @@ show status like 'innodb_pages0_read%'; -- source include/restart_mysqld.inc --echo # Restart Success! -show status like 'innodb_pages0_read%'; -show status like 'innodb_pages0_read%'; +SELECT variable_value <= 303 FROM information_schema.global_status WHERE variable_name = 'innodb_pages0_read'; use test; -show status like 'innodb_pages0_read%'; +SELECT variable_value <= 303 FROM information_schema.global_status WHERE variable_name = 'innodb_pages0_read'; use innodb_encrypted_1; -show status like 'innodb_pages0_read%'; +SELECT variable_value <= 303 FROM information_schema.global_status WHERE variable_name = 'innodb_pages0_read'; use innodb_encrypted_2; -show status like 'innodb_pages0_read%'; +SELECT variable_value <= 303 FROM information_schema.global_status WHERE variable_name = 'innodb_pages0_read'; use innodb_encrypted_3; -show status like 'innodb_pages0_read%'; +SELECT variable_value <= 303 FROM information_schema.global_status WHERE variable_name = 'innodb_pages0_read'; use innodb_encrypted_1; -show status like 'innodb_pages0_read%'; + --disable_result_log --disable_query_log let $tables = 100; @@ -173,10 +172,9 @@ while ($tables) --enable_query_log --enable_result_log -show status like 'innodb_pages0_read%'; +SELECT variable_value <= 303 FROM information_schema.global_status WHERE variable_name = 'innodb_pages0_read'; use innodb_encrypted_2; -show status like 'innodb_pages0_read%'; --disable_result_log --disable_query_log @@ -189,10 +187,10 @@ while ($tables) --enable_query_log --enable_result_log -show status like 'innodb_pages0_read%'; +SELECT variable_value <= 303 FROM information_schema.global_status WHERE variable_name = 'innodb_pages0_read'; use innodb_encrypted_3; -show status like 'innodb_pages0_read%'; + --disable_result_log --disable_query_log let $tables = 100; @@ -204,7 +202,7 @@ while ($tables) --enable_query_log --enable_result_log -show status like 'innodb_pages0_read%'; +SELECT variable_value <= 303 FROM information_schema.global_status WHERE variable_name = 'innodb_pages0_read'; SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME; SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME; diff --git a/mysql-test/suite/innodb/include/no_checkpoint_end.inc b/mysql-test/suite/innodb/include/no_checkpoint_end.inc index 7ca81f8ade0..4a00dadfd6e 100644 --- a/mysql-test/suite/innodb/include/no_checkpoint_end.inc +++ b/mysql-test/suite/innodb/include/no_checkpoint_end.inc @@ -1,7 +1,9 @@ # Check that the latest checkpoint in the redo log files # is not newer than the checkpoint sampled by no_checkpoint_start.inc +if (!$no_checkpoint_kill) { --source include/kill_mysqld.inc +} perl; my $cp = $ENV{CHECKPOINT_LSN}; @@ -22,7 +24,8 @@ my $cp2 = $cp2hi << 32 | $cp2lo; open(OUT, ">$ENV{MYSQLTEST_VARDIR}/log/check.txt") || die; if ($cp1 > $cp || $cp2 > $cp) { - print OUT "--source include/start_mysqld.inc\n"; + print OUT "--source include/start_mysqld.inc\n" + unless $ENV{no_checkpoint_kill}; print OUT "$ENV{CLEANUP_IF_CHECKPOINT}\n"; print OUT "--skip Extra checkpoint 1 after $cp"; print OUT " ($no1hi:$no1lo=$cp1,$no2hi:$no2lo=$cp2)\n"; diff --git a/mysql-test/suite/innodb/r/innodb_force_recovery.result b/mysql-test/suite/innodb/r/innodb_force_recovery.result index d71a6c4e8b0..bd533207ad2 100644 --- a/mysql-test/suite/innodb/r/innodb_force_recovery.result +++ b/mysql-test/suite/innodb/r/innodb_force_recovery.result @@ -12,11 +12,11 @@ ERROR HY000: Running in read-only mode alter table t1 add f3 int not null, algorithm=copy; ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 165 "Table is read only") alter table t1 add f3 int not null, algorithm=inplace; -ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Operation not allowed when innodb_forced_recovery > 0.. Try ALGORITHM=COPY +ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Running in read-only mode. Try ALGORITHM=COPY drop index idx on t1; ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 165 "Table is read only") alter table t1 drop index idx, algorithm=inplace; -ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Operation not allowed when innodb_forced_recovery > 0.. Try ALGORITHM=COPY +ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Running in read-only mode. Try ALGORITHM=COPY update t1 set f1=3 where f2=2; ERROR HY000: Running in read-only mode create table t3(f1 int not null)engine=innodb; @@ -40,7 +40,7 @@ ERROR HY000: Running in read-only mode alter table t2 add f3 int not null, algorithm=copy; ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 165 "Table is read only") alter table t2 add f3 int not null, algorithm=inplace; -ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Operation not allowed when innodb_forced_recovery > 0.. Try ALGORITHM=COPY +ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Running in read-only mode. Try ALGORITHM=COPY drop index idx on t2; ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 165 "Table is read only") update t2 set f1=3 where f2=2; @@ -67,7 +67,7 @@ ERROR HY000: Table 't2' is read only alter table t2 add f3 int not null, algorithm=copy; ERROR HY000: Table 't2' is read only alter table t2 add f3 int not null, algorithm=inplace; -ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Operation not allowed when innodb_forced_recovery > 0.. Try ALGORITHM=COPY +ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Running in read-only mode. Try ALGORITHM=COPY drop index idx on t2; ERROR HY000: Table 't2' is read only update t2 set f1=3 where f2=2; diff --git a/mysql-test/suite/mariabackup/unsupported_redo.result b/mysql-test/suite/mariabackup/unsupported_redo.result index 29f043fc643..543e564d8a8 100644 --- a/mysql-test/suite/mariabackup/unsupported_redo.result +++ b/mysql-test/suite/mariabackup/unsupported_redo.result @@ -5,8 +5,10 @@ call mtr.add_suppression("InnoDB: If you are installing InnoDB, remember that yo call mtr.add_suppression("InnoDB: Ignoring tablespace for `test`\\.`t21` because it could not be opened"); call mtr.add_suppression("InnoDB: Cannot open datafile for read-only: "); call mtr.add_suppression("Table .* in the InnoDB data dictionary has tablespace id .*, but tablespace with that id or name does not exist"); +SELECT @@GLOBAL.innodb_flush_log_at_trx_commit; +@@GLOBAL.innodb_flush_log_at_trx_commit +1 CREATE TABLE t1(i INT PRIMARY KEY auto_increment, a int) ENGINE INNODB; -SET GLOBAL INNODB_FAST_SHUTDOWN = 0; ALTER TABLE t1 FORCE, ALGORITHM=INPLACE; # Fails during full backup DROP TABLE t1; @@ -14,7 +16,6 @@ CREATE TABLE t1(i INT PRIMARY KEY auto_increment, a int) ENGINE INNODB; INSERT INTO t1(a) select 1 union select 2 union select 3; # Create full backup , modify table, then fails during creation of # incremental/differential backup -SET GLOBAL INNODB_FAST_SHUTDOWN = 0; ALTER TABLE t1 FORCE, ALGORITHM=INPLACE; DROP TABLE t1; CREATE TABLE t1(i INT) ENGINE INNODB; @@ -22,7 +23,6 @@ INSERT INTO t1 VALUES(1); CREATE TABLE t21(i INT) ENGINE INNODB; INSERT INTO t21 VALUES(1); CREATE TABLE t2(i int) ENGINE INNODB; -SET GLOBAL INNODB_FAST_SHUTDOWN = 0; ALTER TABLE t21 FORCE, ALGORITHM=INPLACE; # Create partial backup (excluding table t21), Ignore the # unsupported redo log for the table t21. diff --git a/mysql-test/suite/mariabackup/unsupported_redo.test b/mysql-test/suite/mariabackup/unsupported_redo.test index f54f97b6c8b..9d54c5bbe87 100644 --- a/mysql-test/suite/mariabackup/unsupported_redo.test +++ b/mysql-test/suite/mariabackup/unsupported_redo.test @@ -10,11 +10,9 @@ call mtr.add_suppression("Table .* in the InnoDB data dictionary has tablespace let $basedir=$MYSQLTEST_VARDIR/tmp/backup; let $incremental_dir=$MYSQLTEST_VARDIR/tmp/backup_inc1; +SELECT @@GLOBAL.innodb_flush_log_at_trx_commit; CREATE TABLE t1(i INT PRIMARY KEY auto_increment, a int) ENGINE INNODB; - -SET GLOBAL INNODB_FAST_SHUTDOWN = 0; ---source include/restart_mysqld.inc - +--source ../../suite/innodb/include/no_checkpoint_start.inc ALTER TABLE t1 FORCE, ALGORITHM=INPLACE; # Below mariabackup operation may complete successfully if checkpoint happens @@ -22,11 +20,25 @@ ALTER TABLE t1 FORCE, ALGORITHM=INPLACE; echo # Fails during full backup; --disable_result_log ---error 1 +--error 0,1 exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$basedir; --enable_result_log DROP TABLE t1; + +--let MYSQLD_DATADIR=$basedir/ +perl; +open(OUT, ">$ENV{MYSQLTEST_VARDIR}/log/check.txt") || die; +print OUT ' +--let no_checkpoint_end=1 +--let CLEANUP_IF_CHECKPOINT=rmdir $basedir; +--source ../../suite/innodb/include/no_checkpoint_end.inc +--exit Backup failed to fail despite MLOG_INDEX_LOAD record +' if (-f "$ENV{MYSQLD_DATADIR}/xtrabackup_info"); +close(OUT); +EOF +--source $MYSQLTEST_VARDIR/log/check.txt +--remove_file $MYSQLTEST_VARDIR/log/check.txt rmdir $basedir; CREATE TABLE t1(i INT PRIMARY KEY auto_increment, a int) ENGINE INNODB; @@ -39,18 +51,30 @@ INSERT INTO t1(a) select 1 union select 2 union select 3; exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$basedir; --enable_result_log -SET GLOBAL INNODB_FAST_SHUTDOWN = 0; ---source include/restart_mysqld.inc +--source ../../suite/innodb/include/no_checkpoint_start.inc ALTER TABLE t1 FORCE, ALGORITHM=INPLACE; --disable_result_log ---error 1 +--error 0,1 exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$incremental_dir --incremental-basedir=$basedir; --enable_result_log DROP TABLE t1; -rmdir $basedir; -rmdir $incremental_dir; + +--let MYSQLD_DATADIR=$incremental_dir/ +perl; +open(OUT, ">$ENV{MYSQLTEST_VARDIR}/log/check.txt") || die; +print OUT ' +--let no_checkpoint_end=1 +--let CLEANUP_IF_CHECKPOINT=rmdir $basedir;rmdir $incremental_dir; +--source ../../suite/innodb/include/no_checkpoint_end.inc +--exit Backup failed to fail despite MLOG_INDEX_LOAD record +' if (-f "$ENV{MYSQLD_DATADIR}/xtrabackup_info"); +close(OUT); +EOF +--source $MYSQLTEST_VARDIR/log/check.txt +--remove_file $MYSQLTEST_VARDIR/log/check.txt +rmdir $basedir;rmdir $incremental_dir; CREATE TABLE t1(i INT) ENGINE INNODB; INSERT INTO t1 VALUES(1); @@ -62,8 +86,6 @@ let $targetdir=$MYSQLTEST_VARDIR/tmp/bk; CREATE TABLE t2(i int) ENGINE INNODB; -SET GLOBAL INNODB_FAST_SHUTDOWN = 0; ---source include/restart_mysqld.inc ALTER TABLE t21 FORCE, ALGORITHM=INPLACE; --echo # Create partial backup (excluding table t21), Ignore the diff --git a/sql/sql_base.cc b/sql/sql_base.cc index e7be6ed4e90..bb61b8a6459 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -484,7 +484,7 @@ err_with_reopen: old locks. This should always succeed (unless some external process has removed the tables) */ - thd->locked_tables_list.reopen_tables(thd); + result= thd->locked_tables_list.reopen_tables(thd); /* Since downgrade_lock() won't do anything with shared metadata lock it is much simpler to go through all open tables rather diff --git a/storage/innobase/buf/buf0dump.cc b/storage/innobase/buf/buf0dump.cc index 3ccb014cae0..0998b1bc49c 100644 --- a/storage/innobase/buf/buf0dump.cc +++ b/storage/innobase/buf/buf0dump.cc @@ -360,18 +360,23 @@ buf_dump( for (bpage = UT_LIST_GET_FIRST(buf_pool->LRU), j = 0; bpage != NULL && j < n_pages; - bpage = UT_LIST_GET_NEXT(LRU, bpage), j++) { + bpage = UT_LIST_GET_NEXT(LRU, bpage)) { ut_a(buf_page_in_file(bpage)); + if (bpage->id.space() >= SRV_LOG_SPACE_FIRST_ID) { + /* Ignore the innodb_temporary tablespace. */ + continue; + } - dump[j] = BUF_DUMP_CREATE(bpage->id.space(), - bpage->id.page_no()); + dump[j++] = BUF_DUMP_CREATE(bpage->id.space(), + bpage->id.page_no()); } - ut_a(j == n_pages); - buf_pool_mutex_exit(buf_pool); + ut_a(j <= n_pages); + n_pages = j; + for (j = 0; j < n_pages && !SHOULD_QUIT(); j++) { ret = fprintf(f, ULINTPF "," ULINTPF "\n", BUF_DUMP_SPACE(dump[j]), @@ -677,6 +682,11 @@ buf_load() /* space_id for this iteration of the loop */ const ulint this_space_id = BUF_DUMP_SPACE(dump[i]); + if (this_space_id >= SRV_LOG_SPACE_FIRST_ID) { + /* Ignore the innodb_temporary tablespace. */ + continue; + } + if (this_space_id != cur_space_id) { if (space != NULL) { fil_space_release(space); diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index fa82b4456fb..08585d73d8d 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -686,7 +686,7 @@ retry: ib::error() << "Expected tablespace id " << space->id << " but found " << space_id - << "in the file" << node->name; + << " in the file" << node->name; return(false); } @@ -5159,7 +5159,7 @@ fil_io( break; } else { - if (space->id != srv_sys_space.space_id() + if (space->id != TRX_SYS_SPACE && UT_LIST_GET_LEN(space->chain) == 1 && (srv_is_tablespace_truncated(space->id) || space->is_being_truncated @@ -5211,7 +5211,7 @@ fil_io( /* Check that at least the start offset is within the bounds of a single-table tablespace, including rollback tablespaces. */ if (node->size <= cur_page_no - && space->id != srv_sys_space.space_id() + && space->id != TRX_SYS_SPACE && fil_type_is_data(space->purpose)) { if (req_type.ignore_missing()) { diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc index c8e71381491..50d5fc84384 100644 --- a/storage/innobase/fsp/fsp0fsp.cc +++ b/storage/innobase/fsp/fsp0fsp.cc @@ -942,7 +942,7 @@ fsp_try_extend_data_file(fil_space_t* space, fsp_header_t* header, mtr_t* mtr) ut_d(fsp_space_modify_check(space, mtr)); - if (space->id == srv_sys_space.space_id() + if (space->id == TRX_SYS_SPACE && !srv_sys_space.can_auto_extend_last_file()) { /* We print the error message only once to avoid @@ -956,7 +956,7 @@ fsp_try_extend_data_file(fil_space_t* space, fsp_header_t* header, mtr_t* mtr) srv_sys_space.set_tablespace_full_status(true); } return(0); - } else if (fsp_is_system_temporary(space->id) + } else if (space->id == SRV_TMP_SPACE_ID && !srv_tmp_space.can_auto_extend_last_file()) { /* We print the error message only once to avoid diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 682644ea3ac..f70a8544a10 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -711,11 +711,8 @@ ha_innobase::check_if_supported_inplace_alter( DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); } - if (high_level_read_only - || srv_sys_space.created_new_raw() - || srv_force_recovery) { - ha_alter_info->unsupported_reason = (srv_force_recovery)? - "Operation not allowed when innodb_forced_recovery > 0." : + if (high_level_read_only) { + ha_alter_info->unsupported_reason = innobase_get_err_msg(ER_READ_ONLY_MODE); DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index e483162d563..b83a5d4aa22 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -3003,12 +3003,11 @@ recv_validate_tablespace(bool rescan, bool& missing_tablespace) dberr_t err = DB_SUCCESS; for (ulint h = 0; h < hash_get_n_cells(recv_sys->addr_hash); h++) { - for (recv_addr_t* recv_addr = static_cast( - HASH_GET_FIRST(recv_sys->addr_hash, h)); - recv_addr != 0; - recv_addr = static_cast( - HASH_GET_NEXT(addr_hash, recv_addr))) { + HASH_GET_FIRST(recv_sys->addr_hash, h)); + recv_addr != 0; + recv_addr = static_cast( + HASH_GET_NEXT(addr_hash, recv_addr))) { const ulint space = recv_addr->space; @@ -3016,21 +3015,21 @@ recv_validate_tablespace(bool rescan, bool& missing_tablespace) continue; } - recv_spaces_t::iterator i - = recv_spaces.find(space); + recv_spaces_t::iterator i = recv_spaces.find(space); ut_ad(i != recv_spaces.end()); - switch(i->second.status) { + switch (i->second.status) { case file_name_t::MISSING: err = recv_init_missing_space(err, i); i->second.status = file_name_t::DELETED; + /* fall through */ case file_name_t::DELETED: recv_addr->state = RECV_DISCARDED; + /* fall through */ case file_name_t::NORMAL: - break; - default: - ut_ad(0); + continue; } + ut_ad(0); } } diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 4f1be7433a7..13350cc6cd5 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -3809,48 +3809,46 @@ defer: pars_info_add_str_literal(info, "table_name", name); - std::basic_string, - ut_allocator > sql; - sql.reserve(2000); - - sql = "PROCEDURE DROP_TABLE_PROC () IS\n" + err = que_eval_sql( + info, + "PROCEDURE DROP_TABLE_PROC () IS\n" "sys_foreign_id CHAR;\n" "table_id CHAR;\n" "index_id CHAR;\n" "foreign_id CHAR;\n" "space_id INT;\n" - "found INT;\n"; + "found INT;\n" - sql += "DECLARE CURSOR cur_fk IS\n" + "DECLARE CURSOR cur_fk IS\n" "SELECT ID FROM SYS_FOREIGN\n" "WHERE FOR_NAME = :table_name\n" "AND TO_BINARY(FOR_NAME)\n" " = TO_BINARY(:table_name)\n" - "LOCK IN SHARE MODE;\n"; + "LOCK IN SHARE MODE;\n" - sql += "DECLARE CURSOR cur_idx IS\n" + "DECLARE CURSOR cur_idx IS\n" "SELECT ID FROM SYS_INDEXES\n" "WHERE TABLE_ID = table_id\n" - "LOCK IN SHARE MODE;\n"; + "LOCK IN SHARE MODE;\n" - sql += "BEGIN\n"; + "BEGIN\n" - sql += "SELECT ID INTO table_id\n" + "SELECT ID INTO table_id\n" "FROM SYS_TABLES\n" "WHERE NAME = :table_name\n" "LOCK IN SHARE MODE;\n" "IF (SQL % NOTFOUND) THEN\n" " RETURN;\n" - "END IF;\n"; + "END IF;\n" - sql += "SELECT SPACE INTO space_id\n" + "SELECT SPACE INTO space_id\n" "FROM SYS_TABLES\n" "WHERE NAME = :table_name;\n" "IF (SQL % NOTFOUND) THEN\n" " RETURN;\n" - "END IF;\n"; + "END IF;\n" - sql += "found := 1;\n" + "found := 1;\n" "SELECT ID INTO sys_foreign_id\n" "FROM SYS_TABLES\n" "WHERE NAME = 'SYS_FOREIGN'\n" @@ -3864,9 +3862,9 @@ defer: "IF (:table_name = 'SYS_FOREIGN_COLS') \n" "THEN\n" " found := 0;\n" - "END IF;\n"; + "END IF;\n" - sql += "OPEN cur_fk;\n" + "OPEN cur_fk;\n" "WHILE found = 1 LOOP\n" " FETCH cur_fk INTO foreign_id;\n" " IF (SQL % NOTFOUND) THEN\n" @@ -3879,9 +3877,9 @@ defer: " WHERE ID = foreign_id;\n" " END IF;\n" "END LOOP;\n" - "CLOSE cur_fk;\n"; + "CLOSE cur_fk;\n" - sql += "found := 1;\n" + "found := 1;\n" "OPEN cur_idx;\n" "WHILE found = 1 LOOP\n" " FETCH cur_idx INTO index_id;\n" @@ -3895,25 +3893,22 @@ defer: " AND TABLE_ID = table_id;\n" " END IF;\n" "END LOOP;\n" - "CLOSE cur_idx;\n"; + "CLOSE cur_idx;\n" - sql += "DELETE FROM SYS_COLUMNS\n" + "DELETE FROM SYS_COLUMNS\n" "WHERE TABLE_ID = table_id;\n" "DELETE FROM SYS_TABLES\n" - "WHERE NAME = :table_name;\n"; + "WHERE NAME = :table_name;\n" - if (dict_table_is_file_per_table(table)) { - sql += "DELETE FROM SYS_TABLESPACES\n" - "WHERE SPACE = space_id;\n" - "DELETE FROM SYS_DATAFILES\n" - "WHERE SPACE = space_id;\n"; - } + "DELETE FROM SYS_TABLESPACES\n" + "WHERE SPACE = space_id;\n" + "DELETE FROM SYS_DATAFILES\n" + "WHERE SPACE = space_id;\n" - sql += "DELETE FROM SYS_VIRTUAL\n" + "DELETE FROM SYS_VIRTUAL\n" "WHERE TABLE_ID = table_id;\n" - "END;\n"; - - err = que_eval_sql(info, sql.c_str(), FALSE, trx); + "END;\n", + FALSE, trx); } else { page_no = page_nos; for (dict_index_t* index = dict_table_get_first_index(table); diff --git a/storage/innobase/row/row0quiesce.cc b/storage/innobase/row/row0quiesce.cc index 938f9156717..de71c786fd8 100644 --- a/storage/innobase/row/row0quiesce.cc +++ b/storage/innobase/row/row0quiesce.cc @@ -640,7 +640,7 @@ row_quiesce_set_state( ER_CANNOT_DISCARD_TEMPORARY_TABLE); return(DB_UNSUPPORTED); - } else if (table->space == srv_sys_space.space_id()) { + } else if (table->space == TRX_SYS_SPACE) { char table_name[MAX_FULL_NAME_LEN + 1]; diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 94b5f491c89..c28d1263fdc 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -1497,7 +1497,8 @@ innobase_start_or_create_for_mysql() } high_level_read_only = srv_read_only_mode - || srv_force_recovery > SRV_FORCE_NO_TRX_UNDO; + || srv_force_recovery > SRV_FORCE_NO_TRX_UNDO + || srv_sys_space.created_new_raw(); /* Reset the start state. */ srv_start_state = SRV_START_STATE_NONE; diff --git a/storage/rocksdb/ha_rocksdb.cc b/storage/rocksdb/ha_rocksdb.cc index 5eeaecc0b86..bd28b27576e 100644 --- a/storage/rocksdb/ha_rocksdb.cc +++ b/storage/rocksdb/ha_rocksdb.cc @@ -3957,14 +3957,25 @@ static rocksdb::Status check_rocksdb_options_compatibility( return status; } +bool prevent_myrocks_loading= false; + /* Storage Engine initialization function, invoked when plugin is loaded. */ static int rocksdb_init_func(void *const p) { + DBUG_ENTER_FUNC(); + if (prevent_myrocks_loading) + { + my_error(ER_INTERNAL_ERROR, MYF(0), + "Loading MyRocks plugin after it has been unloaded is not " + "supported. Please restart mysqld"); + DBUG_RETURN(1); + } + // Validate the assumption about the size of ROCKSDB_SIZEOF_HIDDEN_PK_COLUMN. static_assert(sizeof(longlong) == 8, "Assuming that longlong is 8 bytes."); @@ -4505,12 +4516,27 @@ static int rocksdb_done_func(void *const p) { } #endif /* HAVE_purify */ - rocksdb_db_options = nullptr; - rocksdb_tbl_options = nullptr; + /* + MariaDB: don't clear rocksdb_db_options and rocksdb_tbl_options. + MyRocks' plugin variables refer to them. + + The plugin cannot be loaded again (see prevent_myrocks_loading) but plugin + variables are processed before myrocks::rocksdb_init_func is invoked, so + they must point to valid memory. + */ + //rocksdb_db_options = nullptr; + rocksdb_db_options->statistics = nullptr; + //rocksdb_tbl_options = nullptr; rocksdb_stats = nullptr; my_error_unregister(HA_ERR_ROCKSDB_FIRST, HA_ERR_ROCKSDB_LAST); + /* + Prevent loading the plugin after it has been loaded and then unloaded. This + doesn't work currently. + */ + prevent_myrocks_loading= true; + DBUG_RETURN(error); } @@ -10031,6 +10057,7 @@ int ha_rocksdb::external_lock(THD *const thd, int lock_type) { thd->lex->sql_command != SQLCOM_LOCK_TABLES && // (*) thd->lex->sql_command != SQLCOM_ANALYZE && // (**) thd->lex->sql_command != SQLCOM_OPTIMIZE && // (**) + thd->lex->sql_command != SQLCOM_FLUSH && // (**) my_core::thd_binlog_filter_ok(thd)) { my_error(ER_REQUIRE_ROW_BINLOG_FORMAT, MYF(0)); DBUG_RETURN(HA_ERR_UNSUPPORTED); diff --git a/storage/rocksdb/ha_rocksdb.h b/storage/rocksdb/ha_rocksdb.h index d28cb7552ed..af5cc5c3024 100644 --- a/storage/rocksdb/ha_rocksdb.h +++ b/storage/rocksdb/ha_rocksdb.h @@ -1414,4 +1414,5 @@ private: const int MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL= MariaDB_PLUGIN_MATURITY_GAMMA; +extern bool prevent_myrocks_loading; } // namespace myrocks diff --git a/storage/rocksdb/mysql-test/rocksdb/r/mariadb_plugin.result b/storage/rocksdb/mysql-test/rocksdb/r/mariadb_plugin.result index bb06c4be2e5..6ab7ab003fd 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/mariadb_plugin.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/mariadb_plugin.result @@ -10,3 +10,22 @@ insert into test.t1 values (1); connection default; DROP TABLE t1; UNINSTALL SONAME 'ha_rocksdb'; +# +# MDEV-15686: Loading MyRocks plugin back after it has been unloaded causes a crash +# +call mtr.add_suppression("Plugin 'ROCKSDB.*' init function returned error."); +call mtr.add_suppression("Plugin 'ROCKSDB.*' registration as a INFORMATION SCHEMA failed."); +call mtr.add_suppression("Plugin 'ROCKSDB' registration as a STORAGE ENGINE failed"); +# +# There are two possible scenarios: +# ha_rocksdb.{dll,so} is still loaded into mysqld's address space. Its +# global variables are in the state that doesn't allow it to be +# initialized back (this is what MDEV-15686 is about). This is handled +# by intentionally returning an error from rocksdb_init_func. +# +# The second case is when ha_rocksdb.{ddl,so} has been fully unloaded +# and so it will be now loaded as if it happens for the first time. +INSTALL SONAME 'ha_rocksdb'; +# Whatever happened on the previous step, restore things to the way they +# were at testcase start. +UNINSTALL SONAME 'ha_rocksdb'; diff --git a/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_rpl.result b/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_rpl.result new file mode 100644 index 00000000000..98408c7864d --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_rpl.result @@ -0,0 +1,14 @@ +# +# MDEV-15472: Assertion `!is_set() || (m_status == DA_OK_BULK && is_bulk_op())' failure ... +# +select @@log_bin; +@@log_bin +1 +select @@binlog_format; +@@binlog_format +ROW +CREATE OR REPLACE TABLE t1 (i INT) ENGINE=RocksDB; +LOCK TABLE t1 WRITE; +FLUSH TABLES; +UNLOCK TABLES; +DROP TABLE t1; diff --git a/storage/rocksdb/mysql-test/rocksdb/t/mariadb_plugin.test b/storage/rocksdb/mysql-test/rocksdb/t/mariadb_plugin.test index 303c4a5e0f9..1a3d505f81a 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/mariadb_plugin.test +++ b/storage/rocksdb/mysql-test/rocksdb/t/mariadb_plugin.test @@ -5,7 +5,14 @@ --echo # MDEV-14843: Assertion `s_tx_list.size() == 0' failed in myrocks::Rdb_transaction::term_mutex --echo # +# +# On Linux, wsrep plugin is always loaded so XA is enabled at this point. +# On Windows, there is no wsrep, so we get this warning: +# Warning 1105 Cannot enable tc-log at run-time. XA features of ROCKSDB are disabled +# +--disable_warnings INSTALL SONAME 'ha_rocksdb'; +--enable_warnings CREATE TABLE t1 (i INT) ENGINE=RocksDB; insert into t1 values (1); @@ -19,3 +26,30 @@ connection default; # Cleanup DROP TABLE t1; UNINSTALL SONAME 'ha_rocksdb'; + +--echo # +--echo # MDEV-15686: Loading MyRocks plugin back after it has been unloaded causes a crash +--echo # +call mtr.add_suppression("Plugin 'ROCKSDB.*' init function returned error."); +call mtr.add_suppression("Plugin 'ROCKSDB.*' registration as a INFORMATION SCHEMA failed."); +call mtr.add_suppression("Plugin 'ROCKSDB' registration as a STORAGE ENGINE failed"); + +--echo # +--echo # There are two possible scenarios: + +--echo # ha_rocksdb.{dll,so} is still loaded into mysqld's address space. Its +--echo # global variables are in the state that doesn't allow it to be +--echo # initialized back (this is what MDEV-15686 is about). This is handled +--echo # by intentionally returning an error from rocksdb_init_func. +--echo # +--echo # The second case is when ha_rocksdb.{ddl,so} has been fully unloaded +--echo # and so it will be now loaded as if it happens for the first time. + +--error 0,ER_INTERNAL_ERROR +INSTALL SONAME 'ha_rocksdb'; + +--echo # Whatever happened on the previous step, restore things to the way they +--echo # were at testcase start. +--error 0,ER_SP_DOES_NOT_EXIST +UNINSTALL SONAME 'ha_rocksdb'; + diff --git a/storage/rocksdb/mysql-test/rocksdb/t/mariadb_port_rpl.test b/storage/rocksdb/mysql-test/rocksdb/t/mariadb_port_rpl.test new file mode 100644 index 00000000000..ed9eb0291c2 --- /dev/null +++ b/storage/rocksdb/mysql-test/rocksdb/t/mariadb_port_rpl.test @@ -0,0 +1,14 @@ +--source include/have_rocksdb.inc +--source include/have_binlog_format_row.inc + +--echo # +--echo # MDEV-15472: Assertion `!is_set() || (m_status == DA_OK_BULK && is_bulk_op())' failure ... +--echo # +select @@log_bin; +select @@binlog_format; +CREATE OR REPLACE TABLE t1 (i INT) ENGINE=RocksDB; +LOCK TABLE t1 WRITE; +FLUSH TABLES; +UNLOCK TABLES; +DROP TABLE t1; + diff --git a/storage/rocksdb/rdb_i_s.cc b/storage/rocksdb/rdb_i_s.cc index 8407f280d5c..57c1bcad3bb 100644 --- a/storage/rocksdb/rdb_i_s.cc +++ b/storage/rocksdb/rdb_i_s.cc @@ -142,6 +142,9 @@ static int rdb_i_s_cfstats_fill_table( static int rdb_i_s_cfstats_init(void *p) { DBUG_ENTER_FUNC(); + if (prevent_myrocks_loading) + DBUG_RETURN(1); + DBUG_ASSERT(p != nullptr); my_core::ST_SCHEMA_TABLE *schema; @@ -235,6 +238,9 @@ static int rdb_i_s_dbstats_fill_table( static int rdb_i_s_dbstats_init(void *const p) { DBUG_ENTER_FUNC(); + if (prevent_myrocks_loading) + DBUG_RETURN(1); + DBUG_ASSERT(p != nullptr); my_core::ST_SCHEMA_TABLE *schema; @@ -336,6 +342,8 @@ static int rdb_i_s_perf_context_fill_table( static int rdb_i_s_perf_context_init(void *const p) { DBUG_ENTER_FUNC(); + if (prevent_myrocks_loading) + DBUG_RETURN(1); DBUG_ASSERT(p != nullptr); my_core::ST_SCHEMA_TABLE *schema; @@ -403,6 +411,9 @@ static int rdb_i_s_perf_context_global_fill_table( static int rdb_i_s_perf_context_global_init(void *const p) { DBUG_ENTER_FUNC(); + if (prevent_myrocks_loading) + DBUG_RETURN(1); + DBUG_ASSERT(p != nullptr); my_core::ST_SCHEMA_TABLE *schema; @@ -1017,6 +1028,9 @@ static int rdb_i_s_ddl_fill_table(my_core::THD *const thd, static int rdb_i_s_ddl_init(void *const p) { DBUG_ENTER_FUNC(); + if (prevent_myrocks_loading) + DBUG_RETURN(1); + my_core::ST_SCHEMA_TABLE *schema; DBUG_ASSERT(p != nullptr); @@ -1032,6 +1046,9 @@ static int rdb_i_s_ddl_init(void *const p) { static int rdb_i_s_cfoptions_init(void *const p) { DBUG_ENTER_FUNC(); + if (prevent_myrocks_loading) + DBUG_RETURN(1); + DBUG_ASSERT(p != nullptr); my_core::ST_SCHEMA_TABLE *schema; @@ -1047,6 +1064,9 @@ static int rdb_i_s_cfoptions_init(void *const p) { static int rdb_i_s_global_info_init(void *const p) { DBUG_ENTER_FUNC(); + if (prevent_myrocks_loading) + DBUG_RETURN(1); + DBUG_ASSERT(p != nullptr); my_core::ST_SCHEMA_TABLE *schema; @@ -1063,6 +1083,10 @@ static int rdb_i_s_compact_stats_init(void *p) { my_core::ST_SCHEMA_TABLE *schema; DBUG_ENTER_FUNC(); + + if (prevent_myrocks_loading) + DBUG_RETURN(1); + DBUG_ASSERT(p != nullptr); schema = reinterpret_cast(p); @@ -1237,6 +1261,9 @@ static int rdb_i_s_index_file_map_fill_table( static int rdb_i_s_index_file_map_init(void *const p) { DBUG_ENTER_FUNC(); + if (prevent_myrocks_loading) + DBUG_RETURN(1); + DBUG_ASSERT(p != nullptr); my_core::ST_SCHEMA_TABLE *schema; @@ -1320,6 +1347,9 @@ static int rdb_i_s_lock_info_fill_table( static int rdb_i_s_lock_info_init(void *const p) { DBUG_ENTER_FUNC(); + if (prevent_myrocks_loading) + DBUG_RETURN(1); + DBUG_ASSERT(p != nullptr); my_core::ST_SCHEMA_TABLE *schema; @@ -1450,6 +1480,9 @@ static int rdb_i_s_trx_info_fill_table( static int rdb_i_s_trx_info_init(void *const p) { DBUG_ENTER_FUNC(); + if (prevent_myrocks_loading) + DBUG_RETURN(1); + DBUG_ASSERT(p != nullptr); my_core::ST_SCHEMA_TABLE *schema;