1
0
mirror of https://github.com/MariaDB/server.git synced 2025-09-11 05:52:26 +03:00

Merge branch '10.7' into bb-10.7-release

This commit is contained in:
Oleksandr Byelkin
2021-11-08 19:43:43 +01:00
26 changed files with 199 additions and 343 deletions

View File

@@ -1,4 +1,4 @@
MYSQL_VERSION_MAJOR=10
MYSQL_VERSION_MINOR=7
MYSQL_VERSION_PATCH=1
MYSQL_VERSION_PATCH=2
SERVER_MATURITY=gamma

View File

@@ -1,3 +1,9 @@
init:
# Install bison
- choco feature disable --name showDownloadProgress
- choco install -y winflexbison
- C:\ProgramData\chocolatey\lib\winflexbison\tools\win_bison.exe --version
version: build-{build}~branch-{branch}
clone_depth: 1
@@ -17,7 +23,7 @@ build_script:
- set BUILD_TYPE=MinSizeRel
- set GENERATOR=-GNinja
- call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"
- cmake -E time cmake %GENERATOR% .. -DCMAKE_BUILD_TYPE=%BUILD_TYPE% -DMYSQL_MAINTAINER_MODE=ERR -DFAST_BUILD=1 -DBISON_EXECUTABLE=C:\cygwin64\bin\bison -DPLUGIN_PERFSCHEMA=NO -DPLUGIN_FEEDBACK=NO
- cmake -E time cmake %GENERATOR% .. -DCMAKE_BUILD_TYPE=%BUILD_TYPE% -DMYSQL_MAINTAINER_MODE=ERR -DFAST_BUILD=1 -DBISON_EXECUTABLE=C:\ProgramData\chocolatey\lib\winflexbison\tools\win_bison.exe -DPLUGIN_PERFSCHEMA=NO -DPLUGIN_FEEDBACK=NO
- set /A jobs=2*%NUMBER_OF_PROCESSORS%
- cmake -E time cmake --build . -j %jobs% --config %BUILD_TYPE% --target minbuild

View File

@@ -11,7 +11,7 @@ InnoDB 0 transactions not purged
connection default;
# Cleanly shutdown mysqld
disconnect con1;
# Corrupt FIL_PAGE_OFFSET in bug16720368.ibd,
# Corrupt FIL_PAGE_TYPE in bug16720368.ibd,
# and recompute innodb_checksum_algorithm=crc32
# restart
SELECT COUNT(*) FROM bug16720368;

View File

@@ -182,3 +182,43 @@ CREATE TABLE t (i INT) ENGINE=InnoDB PARTITION BY HASH (i) PARTITIONS 2;
INSERT INTO t VALUES (0);
INSERT INTO t VALUES (1),(0),(1);
DROP TABLE t;
#
# MDEV-26947 UNIQUE column checks fail in InnoDB resulting
# in table corruption
#
CREATE TABLE t (c1 INT KEY,c2 INT UNIQUE) ENGINE=InnoDB;
BEGIN;
INSERT INTO t VALUES (1,0),(2,0);
ERROR HY000: Got error 1 "Operation not permitted" during COMMIT
CHECK TABLE t;
Table Op Msg_type Msg_text
test.t check status OK
COMMIT;
DROP TABLE t;
CREATE TABLE t (i INT UNIQUE)ENGINE=InnoDB;
INSERT INTO t VALUES (0),(0);
ERROR HY000: Got error 1 "Operation not permitted" during COMMIT
CHECK TABLE t;
Table Op Msg_type Msg_text
test.t check status OK
DROP TABLE t;
CREATE TABLE t (c INT PRIMARY KEY,c2 CHAR(1) UNIQUE)ENGINE=InnoDB;
BEGIN;
INSERT INTO t VALUES(1, ''),(2, '');
ERROR HY000: Got error 1 "Operation not permitted" during COMMIT
SELECT * FROM t;
c c2
DELETE FROM t;
COMMIT;
DROP TABLE t;
#
# MDEV-26956 LeakSanitizer/Valgrind errors in
# trx_mod_table_time_t::start_bulk_insert
# upon adding system versioning
#
CREATE TABLE t1(id INT, s DATE, e DATE, PERIOD FOR p(s,e),
PRIMARY KEY(id, p WITHOUT OVERLAPS)) ENGINE=InnoDB;
ALTER TABLE t1 ADD COLUMN row_start BIGINT UNSIGNED AS ROW START,
ADD COLUMN row_end BIGINT UNSIGNED AS ROW END,
ADD PERIOD FOR SYSTEM_TIME(row_start,row_end), WITH SYSTEM VERSIONING;
DROP TABLE t1;

View File

@@ -43,7 +43,7 @@ connection default;
disconnect con1;
-- echo # Corrupt FIL_PAGE_OFFSET in bug16720368.ibd,
-- echo # Corrupt FIL_PAGE_TYPE in bug16720368.ibd,
-- echo # and recompute innodb_checksum_algorithm=crc32
perl;
do "$ENV{MTR_SUITE_DIR}/include/crc32.pl";
@@ -56,7 +56,7 @@ die "Unable to read $file" unless sysread(FILE, $page, $ps) == $ps;
my $full_crc32 = unpack("N",substr($page,54,4)) & 0x10; # FIL_SPACE_FLAGS
sysseek(FILE, 3*$ps, 0) || die "Unable to seek $file\n";
die "Unable to read $file" unless sysread(FILE, $page, $ps) == $ps;
substr($page,4,4)=pack("N",0xc001cafe);
substr($page,24,2)='42';
my $polynomial = 0x82f63b78; # CRC-32C
if ($full_crc32)
{
@@ -86,7 +86,7 @@ INSERT INTO bug16720368_1 VALUES(1);
-- echo # Shut down the server to uncorrupt the data.
-- source include/shutdown_mysqld.inc
# Uncorrupt the FIL_PAGE_OFFSET.
# Uncorrupt the FIL_PAGE_TYPE.
perl;
do "$ENV{MTR_SUITE_DIR}/include/crc32.pl";
my $file = "$ENV{MYSQLD_DATADIR}/test/bug16720368.ibd";
@@ -98,7 +98,7 @@ die "Unable to read $file" unless sysread(FILE, $page, $ps) == $ps;
my $full_crc32 = unpack("N",substr($page,54,4)) & 0x10; # FIL_SPACE_FLAGS
sysseek(FILE, 3*$ps, 0) || die "Unable to seek $file\n";
die "Unable to read $file" unless sysread(FILE, $page, $ps) == $ps;
substr($page,4,4)=pack("N",3);
substr($page,24,2)=pack("H*","45BF");
my $polynomial = 0x82f63b78; # CRC-32C
if ($full_crc32)
{

View File

@@ -193,3 +193,43 @@ CREATE TABLE t (i INT) ENGINE=InnoDB PARTITION BY HASH (i) PARTITIONS 2;
INSERT INTO t VALUES (0);
INSERT INTO t VALUES (1),(0),(1);
DROP TABLE t;
--echo #
--echo # MDEV-26947 UNIQUE column checks fail in InnoDB resulting
--echo # in table corruption
--echo #
CREATE TABLE t (c1 INT KEY,c2 INT UNIQUE) ENGINE=InnoDB;
BEGIN;
--error ER_ERROR_DURING_COMMIT
INSERT INTO t VALUES (1,0),(2,0);
CHECK TABLE t;
COMMIT;
DROP TABLE t;
CREATE TABLE t (i INT UNIQUE)ENGINE=InnoDB;
--error ER_ERROR_DURING_COMMIT
INSERT INTO t VALUES (0),(0);
CHECK TABLE t;
DROP TABLE t;
CREATE TABLE t (c INT PRIMARY KEY,c2 CHAR(1) UNIQUE)ENGINE=InnoDB;
BEGIN;
--error ER_ERROR_DURING_COMMIT
INSERT INTO t VALUES(1, ''),(2, '');
SELECT * FROM t;
DELETE FROM t;
COMMIT;
DROP TABLE t;
--echo #
--echo # MDEV-26956 LeakSanitizer/Valgrind errors in
--echo # trx_mod_table_time_t::start_bulk_insert
--echo # upon adding system versioning
--echo #
CREATE TABLE t1(id INT, s DATE, e DATE, PERIOD FOR p(s,e),
PRIMARY KEY(id, p WITHOUT OVERLAPS)) ENGINE=InnoDB;
ALTER TABLE t1 ADD COLUMN row_start BIGINT UNSIGNED AS ROW START,
ADD COLUMN row_end BIGINT UNSIGNED AS ROW END,
ADD PERIOD FOR SYSTEM_TIME(row_start,row_end), WITH SYSTEM VERSIONING;
DROP TABLE t1;

View File

@@ -57,7 +57,14 @@ my $body = pack("x[8]Nx[10]Nx[16312]", 768, 97937874);
my $ck = mycrc32($head, 0, $polynomial) ^ mycrc32($body, 0, $polynomial);
print OUT pack("N",$ck).$head.pack("x[12]").$body.pack("Nx[4]",$ck);
# Dummy pages 1..6.
print OUT chr(0) x (6 * 16384);
$body = pack("x[16338]");
for (my($page) = 1; $page < 7; $page++)
{
## FIL_PAGE_OFFSET
$head = pack("Nx[18]", $page);
$ck = mycrc32($head, 0, $polynomial) ^ mycrc32($body, 0, $polynomial);
print OUT pack("N",$ck).$head.pack("x[16350]Nx[4]",$ck);
}
# Dictionary header page (page 7).
## FIL_PAGE_OFFSET
$head = pack("Nx[18]", 7);

View File

@@ -61,5 +61,9 @@ let SEARCH_PATTERN=page id mismatch;
--source include/search_pattern_in_file.inc
--remove_file $resultlog
# prevent purge from crashing on page ID mismatch
let $restart_parameters=--innodb-force-recovery=2;
--source include/start_mysqld.inc
drop table t1;
let $restart_parameters=;
--source include/restart_mysqld.inc

View File

@@ -1,53 +0,0 @@
'#---------------------BS_STVARS_031_01----------------------#'
SELECT COUNT(@@GLOBAL.innodb_force_load_corrupted);
COUNT(@@GLOBAL.innodb_force_load_corrupted)
1
1 Expected
'#---------------------BS_STVARS_031_02----------------------#'
SET @@GLOBAL.innodb_force_load_corrupted=1;
ERROR HY000: Variable 'innodb_force_load_corrupted' is a read only variable
Expected error 'Read only variable'
SELECT COUNT(@@GLOBAL.innodb_force_load_corrupted);
COUNT(@@GLOBAL.innodb_force_load_corrupted)
1
1 Expected
'#---------------------BS_STVARS_031_03----------------------#'
SELECT IF(@@GLOBAL.innodb_force_load_corrupted, "ON", "OFF") = VARIABLE_VALUE
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
WHERE VARIABLE_NAME='innodb_force_load_corrupted';
IF(@@GLOBAL.innodb_force_load_corrupted, "ON", "OFF") = VARIABLE_VALUE
1
1 Expected
SELECT COUNT(@@GLOBAL.innodb_force_load_corrupted);
COUNT(@@GLOBAL.innodb_force_load_corrupted)
1
1 Expected
SELECT COUNT(VARIABLE_VALUE)
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
WHERE VARIABLE_NAME='innodb_force_load_corrupted';
COUNT(VARIABLE_VALUE)
1
1 Expected
'#---------------------BS_STVARS_031_04----------------------#'
SELECT @@innodb_force_load_corrupted = @@GLOBAL.innodb_force_load_corrupted;
@@innodb_force_load_corrupted = @@GLOBAL.innodb_force_load_corrupted
1
1 Expected
'#---------------------BS_STVARS_031_05----------------------#'
SELECT COUNT(@@innodb_force_load_corrupted);
COUNT(@@innodb_force_load_corrupted)
1
1 Expected
SELECT COUNT(@@local.innodb_force_load_corrupted);
ERROR HY000: Variable 'innodb_force_load_corrupted' is a GLOBAL variable
Expected error 'Variable is a GLOBAL variable'
SELECT COUNT(@@SESSION.innodb_force_load_corrupted);
ERROR HY000: Variable 'innodb_force_load_corrupted' is a GLOBAL variable
Expected error 'Variable is a GLOBAL variable'
SELECT COUNT(@@GLOBAL.innodb_force_load_corrupted);
COUNT(@@GLOBAL.innodb_force_load_corrupted)
1
1 Expected
SELECT innodb_force_load_corrupted = @@SESSION.innodb_force_load_corrupted;
ERROR 42S22: Unknown column 'innodb_force_load_corrupted' in 'field list'
Expected error 'Readonly variable'

View File

@@ -765,18 +765,6 @@ NUMERIC_BLOCK_SIZE NULL
ENUM_VALUE_LIST OFF,ON
READ_ONLY NO
COMMAND_LINE_ARGUMENT NONE
VARIABLE_NAME INNODB_FORCE_LOAD_CORRUPTED
SESSION_VALUE NULL
DEFAULT_VALUE OFF
VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE BOOLEAN
VARIABLE_COMMENT Force InnoDB to load metadata of corrupted table.
NUMERIC_MIN_VALUE NULL
NUMERIC_MAX_VALUE NULL
NUMERIC_BLOCK_SIZE NULL
ENUM_VALUE_LIST OFF,ON
READ_ONLY YES
COMMAND_LINE_ARGUMENT NONE
VARIABLE_NAME INNODB_FORCE_PRIMARY_KEY
SESSION_VALUE NULL
DEFAULT_VALUE OFF

View File

@@ -1,106 +0,0 @@
################## mysql-test\t\innodb_force_load_corrupted_basic.test #####
# #
# Variable Name: innodb_force_load_corrupted #
# Scope: Global #
# Access Type: Static #
# Data Type: boolean #
# #
# #
# Creation Date: 2008-02-07 #
# Author : Sharique Abdullah #
# #
# #
# Description:Test Cases of Dynamic System Variable innodb_force_load_corrupted#
# that checks the behavior of this variable in the following ways #
# * Value Check #
# * Scope Check #
# #
# Reference: http://dev.mysql.com/doc/refman/5.1/en/ #
# server-system-variables.html #
# #
###############################################################################
--source include/have_innodb.inc
--echo '#---------------------BS_STVARS_031_01----------------------#'
####################################################################
# Displaying default value #
####################################################################
SELECT COUNT(@@GLOBAL.innodb_force_load_corrupted);
--echo 1 Expected
--echo '#---------------------BS_STVARS_031_02----------------------#'
####################################################################
# Check if Value can set #
####################################################################
--error ER_INCORRECT_GLOBAL_LOCAL_VAR
SET @@GLOBAL.innodb_force_load_corrupted=1;
--echo Expected error 'Read only variable'
SELECT COUNT(@@GLOBAL.innodb_force_load_corrupted);
--echo 1 Expected
--echo '#---------------------BS_STVARS_031_03----------------------#'
#################################################################
# Check if the value in GLOBAL Table matches value in variable #
#################################################################
--disable_warnings
SELECT IF(@@GLOBAL.innodb_force_load_corrupted, "ON", "OFF") = VARIABLE_VALUE
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
WHERE VARIABLE_NAME='innodb_force_load_corrupted';
--enable_warnings
--echo 1 Expected
SELECT COUNT(@@GLOBAL.innodb_force_load_corrupted);
--echo 1 Expected
--disable_warnings
SELECT COUNT(VARIABLE_VALUE)
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
WHERE VARIABLE_NAME='innodb_force_load_corrupted';
--enable_warnings
--echo 1 Expected
--echo '#---------------------BS_STVARS_031_04----------------------#'
################################################################################
# Check if accessing variable with and without GLOBAL point to same variable #
################################################################################
SELECT @@innodb_force_load_corrupted = @@GLOBAL.innodb_force_load_corrupted;
--echo 1 Expected
--echo '#---------------------BS_STVARS_031_05----------------------#'
################################################################################
# Check if innodb_force_load_corrupted can be accessed with and without @@ sign #
################################################################################
SELECT COUNT(@@innodb_force_load_corrupted);
--echo 1 Expected
--Error ER_INCORRECT_GLOBAL_LOCAL_VAR
SELECT COUNT(@@local.innodb_force_load_corrupted);
--echo Expected error 'Variable is a GLOBAL variable'
--Error ER_INCORRECT_GLOBAL_LOCAL_VAR
SELECT COUNT(@@SESSION.innodb_force_load_corrupted);
--echo Expected error 'Variable is a GLOBAL variable'
SELECT COUNT(@@GLOBAL.innodb_force_load_corrupted);
--echo 1 Expected
--Error ER_BAD_FIELD_ERROR
SELECT innodb_force_load_corrupted = @@SESSION.innodb_force_load_corrupted;
--echo Expected error 'Readonly variable'

View File

@@ -27,25 +27,25 @@ protected:
{ return MY_UUID_BARE_STRING_LENGTH + with_dashes*MY_UUID_SEPARATORS; }
public:
Item_func_sys_guid(THD *thd): Item_str_func(thd), with_dashes(false) {}
bool fix_length_and_dec()
bool fix_length_and_dec() override
{
collation.set(DTCollation_numeric());
fix_char_length(uuid_len());
return FALSE;
}
bool const_item() const { return false; }
table_map used_tables() const { return RAND_TABLE_BIT; }
bool const_item() const override { return false; }
table_map used_tables() const override { return RAND_TABLE_BIT; }
LEX_CSTRING func_name_cstring() const override
{
static LEX_CSTRING name= {STRING_WITH_LEN("sys_guid") };
return name;
}
String *val_str(String *) override;
bool check_vcol_func_processor(void *arg)
bool check_vcol_func_processor(void *arg) override
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_NON_DETERMINISTIC);
}
Item *get_copy(THD *thd)
Item *get_copy(THD *thd) override
{ return get_item_copy<Item_func_sys_guid>(thd, this); }
};
@@ -60,7 +60,7 @@ public:
return name;
}
bool val_native(THD *thd, Native *to) override;
Item *get_copy(THD *thd)
Item *get_copy(THD *thd) override
{ return get_item_copy<Item_func_uuid>(thd, this); }
};

View File

@@ -5142,6 +5142,9 @@ static int init_server_components()
MYSQL_COMPATIBILITY_OPTION("new"),
MYSQL_COMPATIBILITY_OPTION("show_compatibility_56"),
/* The following options were removed in 10.6 */
MARIADB_REMOVED_OPTION("innodb-force-load-corrupted"),
/* The following options were removed in 10.5 */
#if defined(__linux__)
MARIADB_REMOVED_OPTION("super-large-pages"),

View File

@@ -1428,7 +1428,7 @@ public:
item->type_handler() == type_handler());
return true;
}
void hash(ulong *nr, ulong *nr2)
void hash(ulong *nr, ulong *nr2) override
{
if (is_null())
*nr^= (*nr << 1) | 1;

View File

@@ -9711,6 +9711,9 @@ bool TR_table::update(ulonglong start_id, ulonglong end_id)
int error= table->file->ha_write_row(table->record[0]);
if (unlikely(error))
table->file->print_error(error, MYF(0));
/* extra() is used to apply the bulk insert operation
on mysql/transaction_registry table */
table->file->extra(HA_EXTRA_IGNORE_INSERT);
return error;
}

View File

@@ -80,6 +80,7 @@ static const char *removed_variables[] =
"innodb_file_format_check",
"innodb_file_format_max",
"innodb_flush_neighbor_pages",
"innodb_force_load_corrupted",
"innodb_foreground_preflush",
"innodb_ibuf_accel_rate",
"innodb_ibuf_active_contract",

View File

@@ -3260,7 +3260,7 @@ loop:
free_block->page.set_state(BUF_BLOCK_FILE_PAGE);
buf_unzip_LRU_add_block(free_block, FALSE);
hash_lock.unlock();
buf_page_free_descriptor(&block->page);
buf_page_free_descriptor(reinterpret_cast<buf_page_t*>(block));
block= free_block;
buf_block_buf_fix_inc(block);
mtr_memo_push(mtr, block, MTR_MEMO_PAGE_X_FIX);

View File

@@ -654,7 +654,7 @@ dict_build_index_def_step(
index = node->index;
table = dict_table_open_on_name(
node->table_name, true, DICT_ERR_IGNORE_DROP);
node->table_name, true, DICT_ERR_IGNORE_TABLESPACE);
if (!table) {
return DB_TABLE_NOT_FOUND;

View File

@@ -145,10 +145,6 @@ dict_load_field_low(
for temporary storage */
const rec_t* rec); /*!< in: SYS_FIELDS record */
/* If this flag is TRUE, then we will load the cluster index's (and tables')
metadata even if it is marked as "corrupted". */
my_bool srv_load_corrupted;
#ifdef UNIV_DEBUG
/****************************************************************//**
Compare the name of an index column.
@@ -1831,31 +1827,11 @@ dict_load_indexes(
btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE,
BTR_SEARCH_LEAF, &pcur, &mtr);
for (;;) {
while (btr_pcur_is_on_user_rec(&pcur)) {
dict_index_t* index = NULL;
const char* err_msg;
if (!btr_pcur_is_on_user_rec(&pcur)) {
/* We should allow the table to open even
without index when DICT_ERR_IGNORE_CORRUPT is set.
DICT_ERR_IGNORE_CORRUPT is currently only set
for drop table */
if (dict_table_get_first_index(table) == NULL
&& !(ignore_err & DICT_ERR_IGNORE_CORRUPT)) {
ib::warn() << "Cannot load table "
<< table->name
<< " because it has no indexes in"
" InnoDB internal data dictionary.";
error = DB_CORRUPTION;
goto func_exit;
}
break;
}
rec = btr_pcur_get_rec(&pcur);
if ((ignore_err & DICT_ERR_IGNORE_RECOVER_LOCK)
&& (rec_get_n_fields_old(rec)
== DICT_NUM_FIELDS__SYS_INDEXES
@@ -1880,27 +1856,11 @@ dict_load_indexes(
}
err_msg = dict_load_index_low(buf, heap, rec, TRUE, &index);
ut_ad((index == NULL && err_msg != NULL)
|| (index != NULL && err_msg == NULL));
ut_ad(!index == !!err_msg);
if (err_msg == dict_load_index_id_err) {
/* TABLE_ID mismatch means that we have
run out of index definitions for the table. */
if (dict_table_get_first_index(table) == NULL
&& !(ignore_err & DICT_ERR_IGNORE_CORRUPT)) {
ib::warn() << "Failed to load the"
" clustered index for table "
<< table->name
<< " because of TABLE_ID mismatch."
" Refusing to load the rest of the"
" indexes (if any) and the whole table"
" altogether.";
error = DB_CORRUPTION;
goto func_exit;
}
/* We have ran out of index definitions for
the table. */
break;
}
@@ -1912,7 +1872,7 @@ dict_load_indexes(
goto next_rec;
} else if (err_msg) {
ib::error() << err_msg;
if (ignore_err & DICT_ERR_IGNORE_CORRUPT) {
if (ignore_err & DICT_ERR_IGNORE_INDEX) {
goto next_rec;
}
error = DB_CORRUPTION;
@@ -1931,29 +1891,11 @@ dict_load_indexes(
ut_ad(!dict_index_is_online_ddl(index));
/* Check whether the index is corrupted */
if (index->is_corrupted()) {
ib::error() << "Index " << index->name
<< " of table " << table->name
<< " is corrupted";
if (!srv_load_corrupted
&& !(ignore_err & DICT_ERR_IGNORE_CORRUPT)
&& dict_index_is_clust(index)) {
dict_mem_index_free(index);
error = DB_INDEX_CORRUPT;
goto func_exit;
} else {
/* We will load the index if
1) srv_load_corrupted is TRUE
2) ignore_err is set with
DICT_ERR_IGNORE_CORRUPT
3) if the index corrupted is a secondary
index */
ib::info() << "Load corrupted index "
<< index->name
<< " of table " << table->name;
}
if (ignore_err != DICT_ERR_IGNORE_DROP
&& index->is_corrupted() && index->is_clust()) {
dict_mem_index_free(index);
error = DB_INDEX_CORRUPT;
goto func_exit;
}
if (index->type & DICT_FTS
@@ -1979,31 +1921,30 @@ dict_load_indexes(
} else if (index->page == FIL_NULL
&& table->is_readable()
&& (!(index->type & DICT_FTS))) {
if (ignore_err != DICT_ERR_IGNORE_DROP) {
ib::error_or_warn(!(ignore_err
& DICT_ERR_IGNORE_INDEX))
<< "Index " << index->name
<< " for table " << table->name
<< " has been freed!";
}
ib::error() << "Trying to load index " << index->name
<< " for table " << table->name
<< ", but the index tree has been freed!";
if (ignore_err & DICT_ERR_IGNORE_INDEX_ROOT) {
/* If caller can tolerate this error,
we will continue to load the index and
let caller deal with this error. However
mark the index and table corrupted. We
only need to mark such in the index
dictionary cache for such metadata corruption,
since we would always be able to set it
when loading the dictionary cache */
index->table = table;
dict_set_corrupted_index_cache_only(index);
ib::info() << "Index is corrupt but forcing"
" load into data dictionary";
} else {
if (!(ignore_err & DICT_ERR_IGNORE_INDEX)) {
corrupted:
dict_mem_index_free(index);
error = DB_CORRUPTION;
goto func_exit;
}
/* If caller can tolerate this error,
we will continue to load the index and
let caller deal with this error. However
mark the index and table corrupted. We
only need to mark such in the index
dictionary cache for such metadata corruption,
since we would always be able to set it
when loading the dictionary cache */
index->table = table;
dict_set_corrupted_index_cache_only(index);
} else if (!dict_index_is_clust(index)
&& NULL == dict_table_get_first_index(table)) {
@@ -2052,6 +1993,13 @@ next_rec:
btr_pcur_move_to_next_user_rec(&pcur, &mtr);
}
if (!dict_table_get_first_index(table)
&& !(ignore_err & DICT_ERR_IGNORE_INDEX)) {
ib::warn() << "No indexes found for table " << table->name;
error = DB_CORRUPTION;
goto func_exit;
}
ut_ad(table->fts_doc_id_index == NULL);
if (table->fts != NULL) {
@@ -2219,7 +2167,7 @@ dict_load_tablespace(
return;
}
if (ignore_err == DICT_ERR_IGNORE_DROP) {
if (ignore_err >= DICT_ERR_IGNORE_TABLESPACE) {
table->file_unreadable = true;
return;
}
@@ -2382,32 +2330,31 @@ err_exit:
if (err == DB_INDEX_CORRUPT) {
/* Refuse to load the table if the table has a corrupted
cluster index */
if (!srv_load_corrupted) {
ib::error() << "Load table " << table->name
<< " failed, the table has"
" corrupted clustered indexes. Turn on"
" 'innodb_force_load_corrupted' to drop it";
dict_sys.remove(table);
table = NULL;
goto func_exit;
} else {
if (table->indexes.start->is_corrupted()) {
table->corrupted = true;
}
}
ut_ad(index_load_err != DICT_ERR_IGNORE_DROP);
ib::error() << "Refusing to load corrupted table "
<< table->name;
evict:
dict_sys.remove(table);
table = NULL;
goto func_exit;
}
if (err == DB_SUCCESS && table->is_readable()) {
const auto root = dict_table_get_first_index(table)->page;
if (root >= table->space->get_size()) {
if (err != DB_SUCCESS || !table->is_readable()) {
} else if (dict_index_t* pk = dict_table_get_first_index(table)) {
ut_ad(pk->is_primary());
if (pk->is_corrupted()
|| pk->page >= table->space->get_size()) {
corrupted:
table->corrupted = true;
table->file_unreadable = true;
err = DB_CORRUPTION;
} else if (table->space->id
&& ignore_err == DICT_ERR_IGNORE_DROP) {
/* Do not bother to load data from .ibd files
only to delete the .ibd files. */
goto corrupted;
} else {
const page_id_t page_id(table->space->id, root);
const page_id_t page_id{table->space->id, pk->page};
mtr.start();
buf_block_t* block = buf_page_get(
page_id, table->space->zip_size(),
@@ -2432,6 +2379,12 @@ corrupted:
err = btr_cur_instant_init(table);
}
}
} else {
ut_ad(ignore_err & DICT_ERR_IGNORE_INDEX);
if (ignore_err != DICT_ERR_IGNORE_DROP) {
err = DB_CORRUPTION;
goto evict;
}
}
/* Initialize table foreign_child value. Its value could be
@@ -2454,33 +2407,11 @@ corrupted:
<< " failed, the table has missing"
" foreign key indexes. Turn off"
" 'foreign_key_checks' and try again.";
evict:
dict_sys.remove(table);
table = NULL;
goto evict;
} else {
dict_mem_table_fill_foreign_vcol_set(table);
table->fk_max_recusive_level = 0;
}
} else {
dict_index_t* index;
/* Make sure that at least the clustered index was loaded.
Otherwise refuse to load the table */
index = dict_table_get_first_index(table);
if (!srv_force_recovery
|| !index
|| !index->is_primary()) {
ib::warn() << "Failed to load table " << table->name
<< ":" << err;
goto evict;
} else if (index->is_corrupted()
&& table->is_readable()) {
/* It is possible we force to load a corrupted
clustered index if srv_load_corrupted is set.
Mark the table as corrupted in this case */
table->corrupted = true;
}
}
func_exit:

View File

@@ -1373,7 +1373,7 @@ fts_cache_add_doc(
static dberr_t fts_drop_table(trx_t *trx, const char *table_name, bool rename)
{
if (dict_table_t *table= dict_table_open_on_name(table_name, true,
DICT_ERR_IGNORE_DROP))
DICT_ERR_IGNORE_TABLESPACE))
{
table->release();
if (rename)
@@ -1505,7 +1505,7 @@ static dberr_t fts_lock_table(trx_t *trx, const char *table_name)
ut_ad(purge_sys.must_wait_FTS());
if (dict_table_t *table= dict_table_open_on_name(table_name, false,
DICT_ERR_IGNORE_DROP))
DICT_ERR_IGNORE_TABLESPACE))
{
dberr_t err= lock_table_for_trx(table, trx, LOCK_X);
/* Wait for purge threads to stop using the table. */

View File

@@ -4547,6 +4547,10 @@ innobase_commit(
SQL statement */
trx_mark_sql_stat_end(trx);
if (UNIV_UNLIKELY(trx->error_state != DB_SUCCESS)) {
trx_rollback_for_mysql(trx);
DBUG_RETURN(1);
}
}
/* Reset the number AUTO-INC rows required */
@@ -18883,11 +18887,6 @@ static MYSQL_SYSVAR_ENUM(flush_method, srv_file_flush_method,
NULL, NULL, IF_WIN(SRV_ALL_O_DIRECT_FSYNC, SRV_O_DIRECT),
&innodb_flush_method_typelib);
static MYSQL_SYSVAR_BOOL(force_load_corrupted, srv_load_corrupted,
PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
"Force InnoDB to load metadata of corrupted table.",
NULL, NULL, FALSE);
static MYSQL_SYSVAR_STR(log_group_home_dir, srv_log_group_home_dir,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"Path to InnoDB log files.", NULL, NULL, NULL);
@@ -19785,7 +19784,6 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(ft_min_token_size),
MYSQL_SYSVAR(ft_num_word_optimize),
MYSQL_SYSVAR(ft_sort_pll_degree),
MYSQL_SYSVAR(force_load_corrupted),
MYSQL_SYSVAR(lock_wait_timeout),
MYSQL_SYSVAR(deadlock_detect),
MYSQL_SYSVAR(deadlock_report),

View File

@@ -341,8 +341,6 @@ static buf_block_t *ibuf_tree_root_get(mtr_t *mtr)
page_id_t(IBUF_SPACE_ID, FSP_IBUF_TREE_ROOT_PAGE_NO),
0, RW_SX_LATCH, mtr);
ut_ad(page_get_space_id(block->frame) == IBUF_SPACE_ID);
ut_ad(page_get_page_no(block->frame) == FSP_IBUF_TREE_ROOT_PAGE_NO);
ut_ad(ibuf.empty == page_is_empty(block->frame));
return block;

View File

@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2018, 2020, MariaDB Corporation.
Copyright (c) 2018, 2021, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -109,10 +109,7 @@ btr_cur_position(
buf_block_t* block, /*!< in: buffer block of rec */
btr_cur_t* cursor) /*!< out: cursor */
{
ut_ad(page_align(rec) == block->frame);
page_cur_position(rec, block, btr_cur_get_page_cur(cursor));
cursor->index = index;
}

View File

@@ -71,18 +71,20 @@ enum dict_err_ignore_t {
DICT_ERR_IGNORE_NONE = 0, /*!< no error to ignore */
DICT_ERR_IGNORE_FK_NOKEY = 1, /*!< ignore error if any foreign
key is missing */
DICT_ERR_IGNORE_INDEX_ROOT = 2, /*!< ignore error if index root
page is FIL_NULL or incorrect value */
DICT_ERR_IGNORE_CORRUPT = 4, /*!< skip corrupted indexes */
DICT_ERR_IGNORE_RECOVER_LOCK = 8,
DICT_ERR_IGNORE_INDEX = 2, /*!< ignore corrupted indexes */
DICT_ERR_IGNORE_RECOVER_LOCK = 4,
/*!< Used when recovering table locks
for resurrected transactions.
Silently load a missing
tablespace, and do not load
incomplete index definitions. */
/** ignore all errors above */
DICT_ERR_IGNORE_ALL = 15,
/** prepare to drop the table; do not attempt to load tablespace */
DICT_ERR_IGNORE_ALL = 7,
/** prepare some DDL operation;
do not attempt to load tablespace */
DICT_ERR_IGNORE_TABLESPACE = 15,
/** prepare to drop the table; do not attempt to load tablespace
or the metadata */
DICT_ERR_IGNORE_DROP = 31
};

View File

@@ -307,11 +307,6 @@ void innodb_wait_allow_writes();
# define innodb_wait_allow_writes() do {} while (0)
#endif /* WITH_INNODB_DISALLOW_WRITES */
/* If this flag is TRUE, then we will load the indexes' (and tables') metadata
even if they are marked as "corrupted". Mostly it is for DBA to process
corrupted index and table */
extern my_bool srv_load_corrupted;
/** Requested size in bytes */
extern ulint srv_buf_pool_size;
/** Minimum pool size in bytes */

View File

@@ -1195,6 +1195,8 @@ void mtr_t::page_lock(buf_block_t *block, ulint rw_latch)
#endif /* BTR_CUR_HASH_ADAPT */
done:
ut_ad(page_id_t(page_get_space_id(block->frame),
page_get_page_no(block->frame)) == block->page.id());
memo_push(block, fix_type);
}