MDEV-36487 Fix ha_innobase::check() for sequences
InnoDB does the following check for sequence table during check table command: - There should be only one index should exist on sequence table - There should be only one row should exist on sequence table - The leaf page must be the root page for the sequence table - Delete marked record should not exist - DB_TRX_ID and DB_ROLL_PTR of the record should be 0 and 1U << 55
This commit is contained in:
parent
37274ae01f
commit
6a2afb42ba
17
mysql-test/suite/innodb/r/check_sequence,debug.rdiff
Normal file
17
mysql-test/suite/innodb/r/check_sequence,debug.rdiff
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
--- check_sequence.result
|
||||||
|
+++ check_sequence,debug.result
|
||||||
|
@@ -112,3 +112,14 @@
|
||||||
|
3
|
||||||
|
disconnect prevent_purge;
|
||||||
|
DROP SEQUENCE s1;
|
||||||
|
+CREATE SEQUENCE s ENGINE=InnoDB;
|
||||||
|
+ALTER TABLE s SEQUENCE=0;
|
||||||
|
+FLUSH TABLES;
|
||||||
|
+SET STATEMENT DEBUG_DBUG="+d,fail_root_page" FOR
|
||||||
|
+CHECK TABLE s;
|
||||||
|
+Table Op Msg_type Msg_text
|
||||||
|
+test.s check Warning InnoDB: Sequence table test/s is corrupted.
|
||||||
|
+test.s check error Corrupt
|
||||||
|
+ALTER TABLE s SEQUENCE=1;
|
||||||
|
+ERROR HY000: InnoDB: Table `test`.`s` is corrupted.
|
||||||
|
+DROP SEQUENCE s;
|
114
mysql-test/suite/innodb/r/check_sequence.result
Normal file
114
mysql-test/suite/innodb/r/check_sequence.result
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
#
|
||||||
|
# MDEV-36487 Fix ha_innobase::check() for sequences
|
||||||
|
#
|
||||||
|
call mtr.add_suppression("InnoDB: Table test/s2 contains 1 indexes .*");
|
||||||
|
call mtr.add_suppression("Table test/s2 has a primary key in InnoDB .*");
|
||||||
|
CREATE SEQUENCE s ENGINE=InnoDB;
|
||||||
|
ALTER TABLE s SEQUENCE=0, ALGORITHM=INPLACE;
|
||||||
|
ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: SEQUENCE. Try ALGORITHM=COPY
|
||||||
|
ALTER TABLE s SEQUENCE=0, ALGORITHM=COPY;
|
||||||
|
FLUSH TABLES;
|
||||||
|
CHECK TABLE s;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.s check Warning InnoDB: Sequence table test/s has ROLLBACK enabled.
|
||||||
|
test.s check error Corrupt
|
||||||
|
ALTER TABLE s SEQUENCE=1;
|
||||||
|
ERROR HY000: InnoDB: Table `test`.`s` is corrupted.
|
||||||
|
DROP SEQUENCE s;
|
||||||
|
CREATE SEQUENCE s ENGINE=InnoDB;
|
||||||
|
CREATE TABLE s2 LIKE s;
|
||||||
|
ALTER TABLE s2 sequence=0;
|
||||||
|
INSERT INTO s2 VALUES (3,1,9223372036854775806,1,1,1000,0,0);
|
||||||
|
ALTER TABLE s2 ADD INDEX idx(start_value);
|
||||||
|
FLUSH TABLES;
|
||||||
|
CHECK TABLE s2;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.s2 check Warning InnoDB: Table test/s2 contains 1 indexes inside InnoDB, which is different from the number of indexes 0 defined in the MariaDB
|
||||||
|
test.s2 check Warning InnoDB: Sequence table test/s2 does have more than one indexes.
|
||||||
|
test.s2 check error Corrupt
|
||||||
|
ALTER TABLE s2 SEQUENCE=1;
|
||||||
|
ERROR HY000: InnoDB: Table `test`.`s2` is corrupted.
|
||||||
|
DROP SEQUENCE s;
|
||||||
|
DROP SEQUENCE s2;
|
||||||
|
CREATE SEQUENCE s ENGINE=InnoDB;
|
||||||
|
CREATE TABLE s2 LIKE s;
|
||||||
|
ALTER TABLE s2 sequence=0;
|
||||||
|
INSERT INTO s2 VALUES (3,2,9223372036854775806,2,2,1000,0,0);
|
||||||
|
ALTER TABLE s2 ADD PRIMARY KEY(start_value);
|
||||||
|
FLUSH TABLES;
|
||||||
|
CHECK TABLE s2;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.s2 check Warning InnoDB: Table test/s2 has a primary key in InnoDB data dictionary, but not in MariaDB!
|
||||||
|
test.s2 check Warning InnoDB: Table test/s2 contains 1 indexes inside InnoDB, which is different from the number of indexes 0 defined in the MariaDB
|
||||||
|
test.s2 check Warning InnoDB: Sequence table test/s2 does not have generated clustered index.
|
||||||
|
test.s2 check error Corrupt
|
||||||
|
ALTER TABLE s2 SEQUENCE=1;
|
||||||
|
ERROR HY000: InnoDB: Table `test`.`s2` is corrupted.
|
||||||
|
DROP SEQUENCE s;
|
||||||
|
DROP SEQUENCE s2;
|
||||||
|
CREATE SEQUENCE s ENGINE=InnoDB;
|
||||||
|
CREATE TABLE s2 LIKE s;
|
||||||
|
ALTER TABLE s2 sequence=0;
|
||||||
|
INSERT INTO s2 VALUES (3,1,9223372036854775806,1,1,1000,0,0);
|
||||||
|
DELETE FROM s2;
|
||||||
|
InnoDB 0 transactions not purged
|
||||||
|
FLUSH TABLES;
|
||||||
|
CHECK TABLE s2;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.s2 check Warning InnoDB: Should have only one record in sequence table test/s2. But it has 0 records.
|
||||||
|
test.s2 check error Corrupt
|
||||||
|
ALTER TABLE s2 SEQUENCE=1;
|
||||||
|
ERROR HY000: InnoDB: Table `test`.`s2` is corrupted.
|
||||||
|
DROP SEQUENCE s;
|
||||||
|
DROP SEQUENCE s2;
|
||||||
|
CREATE SEQUENCE s ENGINE=InnoDB;
|
||||||
|
CREATE TABLE s2 LIKE s;
|
||||||
|
ALTER TABLE s2 sequence=0;
|
||||||
|
INSERT INTO s2 select seq, seq, seq, seq, seq, seq, 1, seq from
|
||||||
|
seq_1_to_200;
|
||||||
|
FLUSH TABLES;
|
||||||
|
CHECK TABLE s2;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.s2 check Warning InnoDB: Non leaf page exists for sequence table test/s2.
|
||||||
|
test.s2 check error Corrupt
|
||||||
|
ALTER TABLE s2 SEQUENCE=1;
|
||||||
|
ERROR HY000: InnoDB: Table `test`.`s2` is corrupted.
|
||||||
|
DROP SEQUENCE s;
|
||||||
|
DROP SEQUENCE s2;
|
||||||
|
CREATE SEQUENCE s ENGINE=InnoDB;
|
||||||
|
CREATE TABLE s2 LIKE s;
|
||||||
|
ALTER TABLE s2 sequence=0;
|
||||||
|
DELETE FROM s2;
|
||||||
|
InnoDB 0 transactions not purged
|
||||||
|
connect prevent_purge,localhost,root;
|
||||||
|
START TRANSACTION WITH CONSISTENT SNAPSHOT;
|
||||||
|
connection default;
|
||||||
|
INSERT INTO s2 VALUES (3,1,9223372036854775806,1,1,1000,0,0);
|
||||||
|
FLUSH TABLES;
|
||||||
|
CHECK TABLE s2;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.s2 check Warning InnoDB: Record in sequence table test/s2 is corrupted.
|
||||||
|
test.s2 check error Corrupt
|
||||||
|
ALTER TABLE s2 SEQUENCE=1;
|
||||||
|
ERROR HY000: InnoDB: Table `test`.`s2` is corrupted.
|
||||||
|
DROP SEQUENCE s;
|
||||||
|
DROP SEQUENCE s2;
|
||||||
|
CREATE SEQUENCE s1 ENGINE=InnoDB;
|
||||||
|
CHECK TABLE s1;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.s1 check status OK
|
||||||
|
connection prevent_purge;
|
||||||
|
START TRANSACTION WITH CONSISTENT SNAPSHOT;
|
||||||
|
connection default;
|
||||||
|
INSERT INTO s1 VALUES (3,1,9223372036854775806,1,1,1000,0,0);
|
||||||
|
SELECT * FROM s1;
|
||||||
|
next_not_cached_value minimum_value maximum_value start_value increment cache_size cycle_option cycle_count
|
||||||
|
3 1 9223372036854775806 1 1 1000 0 0
|
||||||
|
CHECK TABLE s1;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.s1 check status OK
|
||||||
|
select nextval(s1);
|
||||||
|
nextval(s1)
|
||||||
|
3
|
||||||
|
disconnect prevent_purge;
|
||||||
|
DROP SEQUENCE s1;
|
136
mysql-test/suite/innodb/t/check_sequence.test
Normal file
136
mysql-test/suite/innodb/t/check_sequence.test
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
--source include/have_innodb.inc
|
||||||
|
--source include/have_sequence.inc
|
||||||
|
--source include/maybe_debug.inc
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-36487 Fix ha_innobase::check() for sequences
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
call mtr.add_suppression("InnoDB: Table test/s2 contains 1 indexes .*");
|
||||||
|
call mtr.add_suppression("Table test/s2 has a primary key in InnoDB .*");
|
||||||
|
# Sequence table which has NO_ROLLBACK flag set
|
||||||
|
let $datadir=`select @@datadir`;
|
||||||
|
CREATE SEQUENCE s ENGINE=InnoDB;
|
||||||
|
copy_file $datadir/test/s.frm $datadir/test/s1.frm;
|
||||||
|
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
|
||||||
|
ALTER TABLE s SEQUENCE=0, ALGORITHM=INPLACE;
|
||||||
|
ALTER TABLE s SEQUENCE=0, ALGORITHM=COPY;
|
||||||
|
FLUSH TABLES;
|
||||||
|
remove_file $datadir/test/s.frm;
|
||||||
|
move_file $datadir/test/s1.frm $datadir/test/s.frm;
|
||||||
|
CHECK TABLE s;
|
||||||
|
--error ER_TABLE_CORRUPT
|
||||||
|
ALTER TABLE s SEQUENCE=1;
|
||||||
|
DROP SEQUENCE s;
|
||||||
|
|
||||||
|
# Checks for more than one index
|
||||||
|
CREATE SEQUENCE s ENGINE=InnoDB;
|
||||||
|
copy_file $datadir/test/s.frm $datadir/test/orig.frm;
|
||||||
|
CREATE TABLE s2 LIKE s;
|
||||||
|
ALTER TABLE s2 sequence=0;
|
||||||
|
INSERT INTO s2 VALUES (3,1,9223372036854775806,1,1,1000,0,0);
|
||||||
|
ALTER TABLE s2 ADD INDEX idx(start_value);
|
||||||
|
FLUSH TABLES;
|
||||||
|
move_file $datadir/test/orig.frm $datadir/test/s2.frm;
|
||||||
|
CHECK TABLE s2;
|
||||||
|
--error ER_TABLE_CORRUPT
|
||||||
|
ALTER TABLE s2 SEQUENCE=1;
|
||||||
|
DROP SEQUENCE s;
|
||||||
|
DROP SEQUENCE s2;
|
||||||
|
|
||||||
|
# Checks for generated clustered index
|
||||||
|
CREATE SEQUENCE s ENGINE=InnoDB;
|
||||||
|
copy_file $datadir/test/s.frm $datadir/test/orig.frm;
|
||||||
|
CREATE TABLE s2 LIKE s;
|
||||||
|
ALTER TABLE s2 sequence=0;
|
||||||
|
INSERT INTO s2 VALUES (3,2,9223372036854775806,2,2,1000,0,0);
|
||||||
|
ALTER TABLE s2 ADD PRIMARY KEY(start_value);
|
||||||
|
FLUSH TABLES;
|
||||||
|
move_file $datadir/test/orig.frm $datadir/test/s2.frm;
|
||||||
|
CHECK TABLE s2;
|
||||||
|
--error ER_TABLE_CORRUPT
|
||||||
|
ALTER TABLE s2 SEQUENCE=1;
|
||||||
|
DROP SEQUENCE s;
|
||||||
|
DROP SEQUENCE s2;
|
||||||
|
|
||||||
|
# Should contain only one record
|
||||||
|
CREATE SEQUENCE s ENGINE=InnoDB;
|
||||||
|
copy_file $datadir/test/s.frm $datadir/test/orig.frm;
|
||||||
|
CREATE TABLE s2 LIKE s;
|
||||||
|
ALTER TABLE s2 sequence=0;
|
||||||
|
INSERT INTO s2 VALUES (3,1,9223372036854775806,1,1,1000,0,0);
|
||||||
|
DELETE FROM s2;
|
||||||
|
--source include/wait_all_purged.inc
|
||||||
|
FLUSH TABLES;
|
||||||
|
move_file $datadir/test/orig.frm $datadir/test/s2.frm;
|
||||||
|
CHECK TABLE s2;
|
||||||
|
--error ER_TABLE_CORRUPT
|
||||||
|
ALTER TABLE s2 SEQUENCE=1;
|
||||||
|
DROP SEQUENCE s;
|
||||||
|
DROP SEQUENCE s2;
|
||||||
|
|
||||||
|
# More than one page
|
||||||
|
CREATE SEQUENCE s ENGINE=InnoDB;
|
||||||
|
copy_file $datadir/test/s.frm $datadir/test/orig.frm;
|
||||||
|
CREATE TABLE s2 LIKE s;
|
||||||
|
ALTER TABLE s2 sequence=0;
|
||||||
|
INSERT INTO s2 select seq, seq, seq, seq, seq, seq, 1, seq from
|
||||||
|
seq_1_to_200;
|
||||||
|
FLUSH TABLES;
|
||||||
|
move_file $datadir/test/orig.frm $datadir/test/s2.frm;
|
||||||
|
CHECK TABLE s2;
|
||||||
|
--error ER_TABLE_CORRUPT
|
||||||
|
ALTER TABLE s2 SEQUENCE=1;
|
||||||
|
DROP SEQUENCE s;
|
||||||
|
DROP SEQUENCE s2;
|
||||||
|
|
||||||
|
# Checks for DB_TRX_ID & DB_ROLL_PTR in the record
|
||||||
|
CREATE SEQUENCE s ENGINE=InnoDB;
|
||||||
|
copy_file $datadir/test/s.frm $datadir/test/orig.frm;
|
||||||
|
CREATE TABLE s2 LIKE s;
|
||||||
|
ALTER TABLE s2 sequence=0;
|
||||||
|
DELETE FROM s2;
|
||||||
|
--source include/wait_all_purged.inc
|
||||||
|
--connect (prevent_purge,localhost,root)
|
||||||
|
START TRANSACTION WITH CONSISTENT SNAPSHOT;
|
||||||
|
--connection default
|
||||||
|
INSERT INTO s2 VALUES (3,1,9223372036854775806,1,1,1000,0,0);
|
||||||
|
FLUSH TABLES;
|
||||||
|
move_file $datadir/test/orig.frm $datadir/test/s2.frm;
|
||||||
|
CHECK TABLE s2;
|
||||||
|
--error ER_TABLE_CORRUPT
|
||||||
|
ALTER TABLE s2 SEQUENCE=1;
|
||||||
|
DROP SEQUENCE s;
|
||||||
|
DROP SEQUENCE s2;
|
||||||
|
|
||||||
|
# Insert a row into a sequence table updates that row
|
||||||
|
CREATE SEQUENCE s1 ENGINE=InnoDB;
|
||||||
|
CHECK TABLE s1;
|
||||||
|
|
||||||
|
--connection prevent_purge
|
||||||
|
START TRANSACTION WITH CONSISTENT SNAPSHOT;
|
||||||
|
|
||||||
|
--connection default
|
||||||
|
INSERT INTO s1 VALUES (3,1,9223372036854775806,1,1,1000,0,0);
|
||||||
|
SELECT * FROM s1;
|
||||||
|
CHECK TABLE s1;
|
||||||
|
--disable_ps2_protocol
|
||||||
|
select nextval(s1);
|
||||||
|
--enable_ps2_protocol
|
||||||
|
--disconnect prevent_purge
|
||||||
|
DROP SEQUENCE s1;
|
||||||
|
|
||||||
|
if ($have_debug)
|
||||||
|
{
|
||||||
|
# Root page is corrupted
|
||||||
|
CREATE SEQUENCE s ENGINE=InnoDB;
|
||||||
|
copy_file $datadir/test/s.frm $datadir/test/s1.frm;
|
||||||
|
ALTER TABLE s SEQUENCE=0;
|
||||||
|
FLUSH TABLES;
|
||||||
|
remove_file $datadir/test/s.frm;
|
||||||
|
move_file $datadir/test/s1.frm $datadir/test/s.frm;
|
||||||
|
SET STATEMENT DEBUG_DBUG="+d,fail_root_page" FOR
|
||||||
|
CHECK TABLE s;
|
||||||
|
--error ER_TABLE_CORRUPT
|
||||||
|
ALTER TABLE s SEQUENCE=1;
|
||||||
|
DROP SEQUENCE s;
|
||||||
|
}
|
@ -120,12 +120,16 @@ drop sequence s;
|
|||||||
#
|
#
|
||||||
CREATE SEQUENCE s engine=innodb;
|
CREATE SEQUENCE s engine=innodb;
|
||||||
ALTER TABLE s sequence=0;
|
ALTER TABLE s sequence=0;
|
||||||
|
connect prevent_purge,localhost,root;
|
||||||
|
START TRANSACTION WITH CONSISTENT SNAPSHOT;
|
||||||
|
connection default;
|
||||||
delete from s;
|
delete from s;
|
||||||
FLUSH TABLES;
|
FLUSH TABLES;
|
||||||
CHECK TABLE s;
|
CHECK TABLE s;
|
||||||
Table Op Msg_type Msg_text
|
Table Op Msg_type Msg_text
|
||||||
test.s check Error Fewer than one row in the table
|
test.s check Warning InnoDB: Encountered delete marked record in sequence table test/s.
|
||||||
test.s check error Corrupt
|
test.s check error Corrupt
|
||||||
|
disconnect prevent_purge;
|
||||||
DROP SEQUENCE s;
|
DROP SEQUENCE s;
|
||||||
CREATE SEQUENCE s engine=innodb;
|
CREATE SEQUENCE s engine=innodb;
|
||||||
CHECK TABLE s;
|
CHECK TABLE s;
|
||||||
@ -138,6 +142,6 @@ insert into s values (2,1,9223372036854775806,1,1,1000,0,0);
|
|||||||
FLUSH TABLES;
|
FLUSH TABLES;
|
||||||
CHECK TABLE s;
|
CHECK TABLE s;
|
||||||
Table Op Msg_type Msg_text
|
Table Op Msg_type Msg_text
|
||||||
test.s check Warning More than one row in the table
|
test.s check Warning InnoDB: Should have only one record in sequence table test/s. But it has 2 records.
|
||||||
test.s check status OK
|
test.s check error Corrupt
|
||||||
DROP SEQUENCE s;
|
DROP SEQUENCE s;
|
||||||
|
@ -147,11 +147,16 @@ let $datadir=`select @@datadir`;
|
|||||||
CREATE SEQUENCE s engine=innodb;
|
CREATE SEQUENCE s engine=innodb;
|
||||||
copy_file $datadir/test/s.frm $datadir/test/s1.frm;
|
copy_file $datadir/test/s.frm $datadir/test/s1.frm;
|
||||||
ALTER TABLE s sequence=0;
|
ALTER TABLE s sequence=0;
|
||||||
|
--connect (prevent_purge,localhost,root)
|
||||||
|
START TRANSACTION WITH CONSISTENT SNAPSHOT;
|
||||||
|
|
||||||
|
--connection default
|
||||||
delete from s;
|
delete from s;
|
||||||
FLUSH TABLES;
|
FLUSH TABLES;
|
||||||
remove_file $datadir/test/s.frm;
|
remove_file $datadir/test/s.frm;
|
||||||
move_file $datadir/test/s1.frm $datadir/test/s.frm;
|
move_file $datadir/test/s1.frm $datadir/test/s.frm;
|
||||||
CHECK TABLE s;
|
CHECK TABLE s;
|
||||||
|
--disconnect prevent_purge
|
||||||
DROP SEQUENCE s;
|
DROP SEQUENCE s;
|
||||||
|
|
||||||
# Just one row, check ok
|
# Just one row, check ok
|
||||||
|
@ -15197,6 +15197,117 @@ ha_innobase::optimize(
|
|||||||
return try_alter ? HA_ADMIN_TRY_ALTER : HA_ADMIN_OK;
|
return try_alter ? HA_ADMIN_TRY_ALTER : HA_ADMIN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Does the following validation check for the sequence table
|
||||||
|
1) Check whether the InnoDB table has no_rollback flags
|
||||||
|
2) Should have only one primary index
|
||||||
|
3) Root index page must be leaf page
|
||||||
|
4) There should be only one record in leaf page
|
||||||
|
5) There shouldn't be delete marked record in leaf page
|
||||||
|
6) DB_TRX_ID, DB_ROLL_PTR in the record should be 0 and 1U << 55
|
||||||
|
@param thd Thread
|
||||||
|
@param table InnoDB table
|
||||||
|
@retval true if validation succeeds or false if validation fails */
|
||||||
|
static bool innobase_sequence_table_check(THD *thd, dict_table_t *table)
|
||||||
|
{
|
||||||
|
fil_space_t *space= table->space;
|
||||||
|
dict_index_t *clust_index= dict_table_get_first_index(table);
|
||||||
|
mtr_t mtr;
|
||||||
|
bool corruption= false;
|
||||||
|
const rec_t *rec= nullptr;
|
||||||
|
buf_block_t *root_block= nullptr;
|
||||||
|
|
||||||
|
if (UT_LIST_GET_LEN(table->indexes) != 1)
|
||||||
|
{
|
||||||
|
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_NOT_KEYFILE,
|
||||||
|
"InnoDB: Sequence table %s does have more than one "
|
||||||
|
"indexes.", table->name.m_name);
|
||||||
|
corruption= true;
|
||||||
|
goto func_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!clust_index->is_gen_clust())
|
||||||
|
{
|
||||||
|
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_NOT_KEYFILE,
|
||||||
|
"InnoDB: Sequence table %s does not have generated "
|
||||||
|
"clustered index.", table->name.m_name);
|
||||||
|
corruption= true;
|
||||||
|
goto func_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
mtr.start();
|
||||||
|
mtr.set_named_space(space);
|
||||||
|
root_block= buf_page_get_gen(page_id_t(space->id, clust_index->page),
|
||||||
|
space->zip_size(), RW_S_LATCH, nullptr, BUF_GET,
|
||||||
|
&mtr);
|
||||||
|
DBUG_EXECUTE_IF("fail_root_page", root_block= nullptr;);
|
||||||
|
if (!root_block)
|
||||||
|
{
|
||||||
|
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_NOT_KEYFILE,
|
||||||
|
"InnoDB: Sequence table %s is corrupted.",
|
||||||
|
table->name.m_name);
|
||||||
|
corruption= true;
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!page_is_leaf(root_block->page.frame))
|
||||||
|
{
|
||||||
|
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_NOT_KEYFILE,
|
||||||
|
"InnoDB: Non leaf page exists for sequence table %s.",
|
||||||
|
table->name.m_name);
|
||||||
|
corruption= true;
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (page_get_n_recs(root_block->page.frame) != 1)
|
||||||
|
{
|
||||||
|
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_NOT_KEYFILE,
|
||||||
|
"InnoDB: Should have only one record in sequence "
|
||||||
|
"table %s. But it has %u records.", table->name.m_name,
|
||||||
|
page_get_n_recs(root_block->page.frame));
|
||||||
|
corruption= true;
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
rec= page_rec_get_next(page_get_infimum_rec(root_block->page.frame));
|
||||||
|
|
||||||
|
if (rec_get_deleted_flag(rec, dict_table_is_comp(table)))
|
||||||
|
{
|
||||||
|
corruption= true;
|
||||||
|
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_NOT_KEYFILE,
|
||||||
|
"InnoDB: Encountered delete marked record in sequence "
|
||||||
|
"table %s.", table->name.m_name);
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trx_read_trx_id(rec + clust_index->trx_id_offset) != 0 ||
|
||||||
|
trx_read_roll_ptr(rec + clust_index->trx_id_offset + DATA_TRX_ID_LEN) !=
|
||||||
|
roll_ptr_t{1} << ROLL_PTR_INSERT_FLAG_POS)
|
||||||
|
{
|
||||||
|
corruption= true;
|
||||||
|
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_NOT_KEYFILE,
|
||||||
|
"InnoDB: Record in sequence table %s is corrupted.",
|
||||||
|
table->name.m_name);
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!table->no_rollback())
|
||||||
|
{
|
||||||
|
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_NOT_KEYFILE,
|
||||||
|
"InnoDB: Sequence table %s has ROLLBACK enabled.",
|
||||||
|
table->name.m_name);
|
||||||
|
corruption= true;
|
||||||
|
}
|
||||||
|
err_exit:
|
||||||
|
mtr.commit();
|
||||||
|
func_exit:
|
||||||
|
if (corruption)
|
||||||
|
{
|
||||||
|
dict_set_corrupted(clust_index, "Table corruption");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************************//**
|
/*******************************************************************//**
|
||||||
Tries to check that an InnoDB table is not corrupted. If corruption is
|
Tries to check that an InnoDB table is not corrupted. If corruption is
|
||||||
noticed, prints to stderr information about it. In case of corruption
|
noticed, prints to stderr information about it. In case of corruption
|
||||||
@ -15265,6 +15376,11 @@ ha_innobase::check(
|
|||||||
table->s->table_name.str);
|
table->s->table_name.str);
|
||||||
|
|
||||||
DBUG_RETURN(HA_ADMIN_CORRUPT);
|
DBUG_RETURN(HA_ADMIN_CORRUPT);
|
||||||
|
} else if (table->s->table_type == TABLE_TYPE_SEQUENCE) {
|
||||||
|
DBUG_RETURN(
|
||||||
|
innobase_sequence_table_check(thd, m_prebuilt->table)
|
||||||
|
? HA_ADMIN_OK
|
||||||
|
: HA_ADMIN_CORRUPT);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_prebuilt->trx->op_info = "checking table";
|
m_prebuilt->trx->op_info = "checking table";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user