1
0
mirror of https://github.com/MariaDB/server.git synced 2026-10-23 18:49:29 +03:00

MDEV-35867 mariadb-check --repair does not repair sequences, only changes the status to OK

REPAIR of a sequence table with more or fewer than one row reported OK.
Now ha_sequence::repair() checks the row count after the engine repair
and reports the sequence as corrupt.

Also a failed table recreate in REPAIR was reported as
"Table is already up to date" (bool result taken as HA_ADMIN_ALREADY_DONE).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Oleksandr Byelkin
2026-10-15 12:27:16 +02:00
parent 8136047738
commit 62615edb97
6 changed files with 156 additions and 4 deletions

View File

@@ -414,3 +414,63 @@ create or replace sequence s;
insert into t values (default);
drop sequence s;
# End of 10.11 tests
#
# MDEV-35867 mariadb-check --repair does not repair sequences, only
# changes the status to OK
#
create table t1 (next_not_cached_value bigint(21) NOT NULL,
minimum_value bigint(21) NOT NULL, maximum_value bigint(21) NOT NULL,
start_value bigint(21) NOT NULL, increment bigint(21) NOT NULL,
cache_size bigint(21) unsigned NOT NULL,
cycle_option tinyint(1) unsigned NOT NULL,
cycle_count bigint(21) NOT NULL) engine=myisam;
insert into t1 values (1,1,9223372036854775806,1,1,1000,0,0),
(2,1,9223372036854775806,1,1,1000,0,0);
create sequence s1 engine=myisam;
repair table s1;
Table Op Msg_type Msg_text
test.s1 repair status OK
flush tables;
repair table s1;
Table Op Msg_type Msg_text
test.s1 repair Error Internal error: More than one row in the table
test.s1 repair error Corrupt
repair table s1 extended;
Table Op Msg_type Msg_text
test.s1 repair Error Internal error: More than one row in the table
test.s1 repair error Corrupt
repair table s1 use_frm;
Table Op Msg_type Msg_text
test.s1 repair Error Internal error: More than one row in the table
test.s1 repair error Corrupt
select next value for s1;
next value for s1
1
delete from t1;
flush tables;
repair table s1;
Table Op Msg_type Msg_text
test.s1 repair Error Internal error: Fewer than one row in the table
test.s1 repair error Corrupt
drop table t1;
drop sequence s1;
create table t1 (next_not_cached_value bigint(21) NOT NULL,
minimum_value bigint(21) NOT NULL, maximum_value bigint(21) NOT NULL,
start_value bigint(21) NOT NULL, increment bigint(21) NOT NULL,
cache_size bigint(21) unsigned NOT NULL,
cycle_option tinyint(1) unsigned NOT NULL,
cycle_count bigint(21) NOT NULL) engine=innodb;
insert into t1 values (1,1,9223372036854775806,1,1,1000,0,0),
(2,1,9223372036854775806,1,1,1000,0,0);
create sequence s1 engine=innodb;
alter table s1 discard tablespace;
flush tables t1 for export;
unlock tables;
alter table s1 import tablespace;
repair table s1;
Table Op Msg_type Msg_text
test.s1 repair Error Internal error: More than one row in the table
test.s1 repair status Operation failed
drop table t1;
drop sequence s1;
# End of 11.8 tests

View File

@@ -454,3 +454,60 @@ insert into t values (default);
drop sequence s;
--echo # End of 10.11 tests
--echo #
--echo # MDEV-35867 mariadb-check --repair does not repair sequences, only
--echo # changes the status to OK
--echo #
let $datadir=`select @@datadir`;
create table t1 (next_not_cached_value bigint(21) NOT NULL,
minimum_value bigint(21) NOT NULL, maximum_value bigint(21) NOT NULL,
start_value bigint(21) NOT NULL, increment bigint(21) NOT NULL,
cache_size bigint(21) unsigned NOT NULL,
cycle_option tinyint(1) unsigned NOT NULL,
cycle_count bigint(21) NOT NULL) engine=myisam;
insert into t1 values (1,1,9223372036854775806,1,1,1000,0,0),
(2,1,9223372036854775806,1,1,1000,0,0);
create sequence s1 engine=myisam;
repair table s1;
flush tables;
--remove_file $datadir/test/s1.MYD
--remove_file $datadir/test/s1.MYI
--copy_file $datadir/test/t1.MYD $datadir/test/s1.MYD
--copy_file $datadir/test/t1.MYI $datadir/test/s1.MYI
repair table s1;
repair table s1 extended;
repair table s1 use_frm;
select next value for s1;
delete from t1;
flush tables;
--remove_file $datadir/test/s1.MYD
--remove_file $datadir/test/s1.MYI
--copy_file $datadir/test/t1.MYD $datadir/test/s1.MYD
--copy_file $datadir/test/t1.MYI $datadir/test/s1.MYI
repair table s1;
drop table t1;
drop sequence s1;
create table t1 (next_not_cached_value bigint(21) NOT NULL,
minimum_value bigint(21) NOT NULL, maximum_value bigint(21) NOT NULL,
start_value bigint(21) NOT NULL, increment bigint(21) NOT NULL,
cache_size bigint(21) unsigned NOT NULL,
cycle_option tinyint(1) unsigned NOT NULL,
cycle_count bigint(21) NOT NULL) engine=innodb;
insert into t1 values (1,1,9223372036854775806,1,1,1000,0,0),
(2,1,9223372036854775806,1,1,1000,0,0);
create sequence s1 engine=innodb;
alter table s1 discard tablespace;
flush tables t1 for export;
--copy_file $datadir/test/t1.ibd $datadir/test/s1.ibd
unlock tables;
--disable_warnings
alter table s1 import tablespace;
--enable_warnings
repair table s1;
drop table t1;
drop sequence s1;
--echo # End of 11.8 tests

View File

@@ -3,5 +3,5 @@ ERROR HY000: Galera replication not supported
REPAIR TABLE performance_schema.setup_objects;
Table Op Msg_type Msg_text
performance_schema.setup_objects repair Error Storage engine PERFORMANCE_SCHEMA of the table `performance_schema`.`setup_objects` doesn't have this option
performance_schema.setup_objects repair status Table is already up to date
performance_schema.setup_objects repair status Operation failed
SET GLOBAL wsrep_on=OFF;

View File

@@ -418,6 +418,41 @@ void ha_sequence::print_error(int error, myf errflag)
DBUG_VOID_RETURN;
}
/*
Repair the underlying table, then check that exactly one row is left.
Removing extra rows is not supported, so report the sequence as corrupt
instead of OK.
*/
int ha_sequence::repair(THD *thd, HA_CHECK_OPT *check_opt)
{
int error;
ha_rows rows= 0;
DBUG_ENTER("ha_sequence::repair");
if ((error= file->repair(thd, check_opt)))
DBUG_RETURN(error);
if (file->ha_rnd_init_with_error(1))
DBUG_RETURN(HA_ADMIN_FAILED);
while (rows < 2 && !(error= file->ha_rnd_next(table->record[0])))
rows++;
file->ha_rnd_end();
if (error && error != HA_ERR_END_OF_FILE)
{
file->print_error(error, MYF(0));
DBUG_RETURN(HA_ADMIN_FAILED);
}
if (rows != 1)
{
my_error(ER_INTERNAL_ERROR, MYF(0),
rows ? "More than one row in the table" :
"Fewer than one row in the table");
DBUG_RETURN(HA_ADMIN_CORRUPT);
}
DBUG_RETURN(HA_ADMIN_OK);
}
/*****************************************************************************
Sequence plugin interface
*****************************************************************************/

View File

@@ -151,8 +151,7 @@ public:
int discard_or_import_tablespace(my_bool discard) override;
bool auto_repair(int error) const override
{ return file->auto_repair(error); }
int repair(THD* thd, HA_CHECK_OPT* check_opt) override
{ return file->repair(thd, check_opt); }
int repair(THD* thd, HA_CHECK_OPT* check_opt) override;
bool check_and_repair(THD *thd) override
{ return file->check_and_repair(thd); }
bool is_crashed() const override

View File

@@ -1121,7 +1121,8 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
repair was not implemented and we need to upgrade the table
to a new version so we recreate the table with ALTER TABLE
*/
result_code= admin_recreate_table(thd, table, &recreate_info, 1);
result_code= (admin_recreate_table(thd, table, &recreate_info, 1) ?
HA_ADMIN_FAILED : HA_ADMIN_OK);
recreate_used= 1;
}