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:
@ -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
|
||||||
|
#
|
||||||
|
@ -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 #
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
Reference in New Issue
Block a user