1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

MDEV-32350 Can't selectively restore sequences using innodb tables from backup

Added support for sequences to do  discard and import tablespace
This commit is contained in:
Monty
2024-10-08 18:20:46 +03:00
parent ee908140ac
commit 2c52fdd28a
5 changed files with 131 additions and 4 deletions

View File

@ -301,3 +301,44 @@ drop sequence s;
# #
# End of 10.4 tests # End of 10.4 tests
# #
#
# MDEV-32350 Can't selectively restore sequences using innodb tables from
# backup
#
create sequence s2 engine=innodb;
alter table s2 discard tablespace;
SELECT NEXTVAL(s2);
ERROR HY000: Got error 194 "Tablespace is missing for a table" from storage engine InnoDB
create sequence s1 engine=innodb;
select * from s1;
next_not_cached_value minimum_value maximum_value start_value increment cache_size cycle_option cycle_count
1 1 9223372036854775806 1 1 1000 0 0
flush tables s1 for export;
unlock tables;
select * from s2;
ERROR HY000: Got error 194 "Tablespace is missing for a table" from storage engine InnoDB
SELECT NEXTVAL(s2);
ERROR HY000: Got error 194 "Tablespace is missing for a table" from storage engine InnoDB
alter sequence s2 restart;
ERROR HY000: Got error 194 "Tablespace is missing for a table" from storage engine InnoDB
alter table s2 import tablespace;
select * from s2;
next_not_cached_value minimum_value maximum_value start_value increment cache_size cycle_option cycle_count
1 1 9223372036854775806 1 1 1000 0 0
SELECT NEXTVAL(s2);
NEXTVAL(s2)
1
select NEXTVAL(s1);
NEXTVAL(s1)
1
flush table s1,s2;
select * from s1;
next_not_cached_value minimum_value maximum_value start_value increment cache_size cycle_option cycle_count
1001 1 9223372036854775806 1 1 1000 0 0
select * from s2;
next_not_cached_value minimum_value maximum_value start_value increment cache_size cycle_option cycle_count
1001 1 9223372036854775806 1 1 1000 0 0
drop sequence s1,s2;
#
# End of 10.5 tests
#

View File

@ -202,3 +202,42 @@ drop sequence s;
--echo # --echo #
--echo # End of 10.4 tests --echo # End of 10.4 tests
--echo # --echo #
--echo #
--echo # MDEV-32350 Can't selectively restore sequences using innodb tables from
--echo # backup
--echo #
--disable_ps_protocol
create sequence s2 engine=innodb;
alter table s2 discard tablespace;
--error ER_GET_ERRNO
SELECT NEXTVAL(s2);
create sequence s1 engine=innodb;
select * from s1;
flush tables s1 for export;
--let $MYSQLD_DATADIR= `select @@datadir`
--move_file $MYSQLD_DATADIR/test/s1.cfg $MYSQLD_DATADIR/test/s2.cfg
--copy_file $MYSQLD_DATADIR/test/s1.ibd $MYSQLD_DATADIR/test/s2.ibd
unlock tables;
--error ER_GET_ERRNO
select * from s2;
--error ER_GET_ERRNO
SELECT NEXTVAL(s2);
--error ER_GET_ERRNO
alter sequence s2 restart;
alter table s2 import tablespace;
select * from s2;
SELECT NEXTVAL(s2);
select NEXTVAL(s1);
flush table s1,s2;
select * from s1;
select * from s2;
drop sequence s1,s2;
--enable_ps_protocol
--echo #
--echo # End of 10.5 tests
--echo #

View File

@ -367,6 +367,21 @@ int ha_sequence::external_lock(THD *thd, int lock_type)
return error; return error;
} }
int ha_sequence::discard_or_import_tablespace(my_bool discard)
{
int error= file->discard_or_import_tablespace(discard);
if (!error && !discard)
{
/* Doing import table space. Read the imported values */
if (!(error= table->s->sequence->read_stored_values(table)))
{
table->s->sequence->initialized= SEQUENCE::SEQ_READY_TO_USE;
memcpy(table->record[1], table->s->default_values, table->s->reclength);
}
}
return error;
}
/* /*
Squence engine error deal method Squence engine error deal method
*/ */

View File

@ -143,7 +143,7 @@ public:
{ file->unbind_psi(); } { file->unbind_psi(); }
void rebind_psi() override void rebind_psi() override
{ file->rebind_psi(); } { file->rebind_psi(); }
int discard_or_import_tablespace(my_bool discard) override;
bool auto_repair(int error) const override bool auto_repair(int error) const override
{ return file->auto_repair(error); } { return file->auto_repair(error); }
int repair(THD* thd, HA_CHECK_OPT* check_opt) override int repair(THD* thd, HA_CHECK_OPT* check_opt) override

View File

@ -529,7 +529,30 @@ int SEQUENCE::read_initial_values(TABLE *table)
/* /*
Do the actiual reading of data from sequence table and This class is here to allow one to use import table space on sequences
*/
class Silence_table_space_errors : public Internal_error_handler
{
public:
Silence_table_space_errors() {}
~Silence_table_space_errors() override = default;
bool handle_condition(THD *thd,
uint sql_errno,
const char* sql_state,
Sql_condition::enum_warning_level *level,
const char* msg,
Sql_condition ** cond_hdl) override
{
if (sql_errno == ER_TABLESPACE_DISCARDED || HA_ERR_TABLESPACE_MISSING)
return true; // Silence it
return false;
}
};
/*
Do the actual reading of data from sequence table and
update values in the sequence object. update values in the sequence object.
Called once from when table is opened Called once from when table is opened
@ -538,14 +561,21 @@ int SEQUENCE::read_initial_values(TABLE *table)
int SEQUENCE::read_stored_values(TABLE *table) int SEQUENCE::read_stored_values(TABLE *table)
{ {
int error; int error;
Silence_table_space_errors error_handler;
THD *thd= table->in_use;
DBUG_ENTER("SEQUENCE::read_stored_values"); DBUG_ENTER("SEQUENCE::read_stored_values");
thd->push_internal_handler(&error_handler);
MY_BITMAP *save_read_set= tmp_use_all_columns(table, &table->read_set); MY_BITMAP *save_read_set= tmp_use_all_columns(table, &table->read_set);
error= table->file->ha_read_first_row(table->record[0], MAX_KEY); error= table->file->ha_read_first_row(table->record[0], MAX_KEY);
tmp_restore_column_map(&table->read_set, save_read_set); tmp_restore_column_map(&table->read_set, save_read_set);
if (unlikely(error)) if (unlikely(error))
{ {
thd->pop_internal_handler();
if (error == HA_ERR_TABLESPACE_MISSING && thd->tablespace_op)
DBUG_RETURN(0); // Ignore error for ALTER TABLESPACE
table->file->print_error(error, MYF(0)); table->file->print_error(error, MYF(0));
DBUG_RETURN(error); DBUG_RETURN(error);
} }
@ -553,6 +583,7 @@ int SEQUENCE::read_stored_values(TABLE *table)
adjust_values(reserved_until); adjust_values(reserved_until);
all_values_used= 0; all_values_used= 0;
thd->pop_internal_handler();
DBUG_RETURN(0); DBUG_RETURN(0);
} }
@ -775,8 +806,9 @@ longlong SEQUENCE::next_value(TABLE *table, bool second_round, int *error)
DBUG_RETURN(next_value(table, 1, error)); DBUG_RETURN(next_value(table, 1, error));
} }
if (unlikely((*error= write(table, thd->variables.binlog_row_image != if (unlikely((*error= write(table,
BINLOG_ROW_IMAGE_MINIMAL)))) (thd->variables.binlog_row_image !=
BINLOG_ROW_IMAGE_MINIMAL)))))
{ {
reserved_until= org_reserved_until; reserved_until= org_reserved_until;
next_free_value= res_value; next_free_value= res_value;