Skip to content
Permalink
Browse files
Improve error reporting in Aria
This patch fixes the following issues in Aria error reporting in case
of read errors & crashed tables:
- Added the table name to the most error messages, including in case of
  read errors or when encrypting/decrypting a table. The format for
  error messages was changed sligtly to accomodate logging of errors
  from lower level routines.
- If we got an read error from storage (hard disk, ssd, S3 etc) we only
  reported 'table is crashed'. Now the error number from the storage
  is reported.
- Added checking of read failure from records_in_range()
- Calls to ma_set_fatal_error() did not inform the SQL level of
  errors (to not spam the user with multiple error messages).
  Now the first error message and any fatal error messages are reported
  to the user.
  • Loading branch information
montywi authored and spetrunia committed Jun 7, 2022
1 parent 1de18a8 commit 3d241eb
Show file tree
Hide file tree
Showing 30 changed files with 235 additions and 151 deletions.
@@ -3,7 +3,7 @@ call mtr.add_suppression("mysql.user");
flush tables;
flush privileges;
Warnings:
Error 145 Table './mysql/user' is marked as crashed and should be repaired
Error 145 Got error '145 "Table was marked as crashed and should be repaired"' for './mysql/user'
Warning 1034 12544 clients are using or haven't closed the table properly
Note 1034 Table is fixed
# switching back from mysql.user to mysql.global_priv
@@ -1,15 +1,17 @@
call mtr.add_suppression('Unknown key id 1. Can''t continue');
call mtr.add_suppression('Unknown key id 1');
call mtr.add_suppression('try to repair it');
call mtr.add_suppression('Index is corrupted');
set global aria_encrypt_tables= 1;
create table t1 (pk int primary key, a int, key(a)) engine=aria transactional=1;
alter table t1 disable keys;
insert into t1 values (1,1);
alter table t1 enable keys;
ERROR HY000: Unknown key id 1. Can't continue!
ERROR HY000: Unknown key id 1 for ./test/t1. Can't continue!
repair table t1 use_frm;
Table Op Msg_type Msg_text
test.t1 repair warning Number of rows changed from 0 to 1
test.t1 repair Error Unknown key id 1. Can't continue!
test.t1 repair Error Unknown key id 1. Can't continue!
test.t1 repair Error Unknown key id 1 for ./test/t1. Can't continue!
test.t1 repair Error Unknown key id 1 for ./test/t1. Can't continue!
test.t1 repair status OK
drop table t1;
set global aria_encrypt_tables= default;
@@ -1,14 +1,18 @@
#
# MDEV-18496 Crash when Aria encryption is enabled but plugin not available
#
call mtr.add_suppression('Unknown key id 1. Can''t continue');
call mtr.add_suppression('Unknown key id 1');
call mtr.add_suppression('try to repair it');
call mtr.add_suppression('Index is corrupted');

set global aria_encrypt_tables= 1;
create table t1 (pk int primary key, a int, key(a)) engine=aria transactional=1;
alter table t1 disable keys;
insert into t1 values (1,1);
error 192;
--replace_result \\ /
--error 192
alter table t1 enable keys;
--replace_result \\ /
repair table t1 use_frm;
drop table t1;
set global aria_encrypt_tables= default;
@@ -26,9 +26,10 @@ a
ThursdayMorningsMarket
ThursdayMorningsMarketb
Warnings:
Error 145 t_corrupted2' is marked as crashed and should be repaired
Error 145 Got error '145 "Table was marked as crashed and should be repaired"' for './mysqltest/t_corrupted2'
Warning 1034 1 client is using or hasn't closed the table properly
Error 1034 Wrong base information on indexpage at page: 1
Error 176 Got error '176 "Read page with wrong checksum"' for './mysqltest/t_corrupted2.MAI'
Error 1034 Can't read indexpage from page: 1, error: 176
select * from t_corrupted2;
a
ThursdayMorningsMarket
@@ -20,8 +20,8 @@ select count(*) from mysql.proc;
# account for Unix and Windows variation.
call mtr.add_suppression("Checking table: '\\..mysqltest.t_corrupted2'");
call mtr.add_suppression("Recovering table: '\\..mysqltest.t_corrupted2'");
call mtr.add_suppression("Table '\\..mysqltest.t_corrupted2' is marked as crashed and should be repaired");
call mtr.add_suppression("Table 't_corrupted2' is marked as crashed and should be repaired");
call mtr.add_suppression("Table was marked as crashed and should be repaired");
call mtr.add_suppression("Read page with wrong checksum");

let $def_checkinterval=`select @@global.aria_checkpoint_interval`;

@@ -78,7 +78,7 @@ perl;
syswrite (FILE, $whatever) or die;
close FILE;
EOF
replace_regex /Table.*t_corrupted2/t_corrupted2/ ;
--replace_result \\ /
--enable_prepare_warnings
select * from t_corrupted2; # should show corruption and repair messages
--disable_prepare_warnings
@@ -1,4 +1,4 @@
call mtr.add_suppression("Table '.*' is marked as crashed and should be repaired");
call mtr.add_suppression("Table was marked as crashed");
call mtr.add_suppression("Checking table: .*");
create table t1 (a int primary key auto_increment, b int) engine=aria transactional= 1;
create table t2 (a int primary key auto_increment, b int) engine=aria transactional= 0;
@@ -54,7 +54,7 @@ a b
10 11
11 12
Warnings:
Error 145 Table './test/t2' is marked as crashed and should be repaired
Error 145 Got error '145 "Table was marked as crashed and should be repaired"' for './test/t2'
Warning 1034 1 client is using or hasn't closed the table properly
Note 1034 Table is fixed
insert into t1 (b) values (100),(200);
@@ -92,15 +92,15 @@ NEXT VALUE for s1 seq
11 3
12 4
Warnings:
Error 145 Table './test/s1' is marked as crashed and should be repaired
Error 145 Got error '145 "Table was marked as crashed and should be repaired"' for './test/s1'
Warning 1034 1 client is using or hasn't closed the table properly
Note 1034 Table is fixed
drop table t1,t2;
drop sequence s1;
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Query # # use `mtr`; INSERT INTO test_suppressions (pattern) VALUES ( NAME_CONST('pattern',_latin1'Table \'.*\' is marked as crashed and should be repaired' COLLATE 'latin1_swedish_ci'))
master-bin.000001 # Query # # use `mtr`; INSERT INTO test_suppressions (pattern) VALUES ( NAME_CONST('pattern',_latin1'Table was marked as crashed' COLLATE 'latin1_swedish_ci'))
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Query # # use `mtr`; INSERT INTO test_suppressions (pattern) VALUES ( NAME_CONST('pattern',_latin1'Checking table: .*' COLLATE 'latin1_swedish_ci'))
@@ -3,7 +3,7 @@
# no-protocol doesn't print warnings about repaired tables
--source include/no_protocol.inc

call mtr.add_suppression("Table '.*' is marked as crashed and should be repaired");
call mtr.add_suppression("Table was marked as crashed");
call mtr.add_suppression("Checking table: .*");

#
@@ -179,6 +179,8 @@ handler::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
{
/* Can't scan one range => can't do MRR scan at all */
total_rows= HA_POS_ERROR;
if (thd->is_error())
DBUG_RETURN(HA_POS_ERROR);
break;
}
if (pages.first_page == UNUSED_PAGE_NO)
@@ -1477,6 +1477,7 @@ int ha_maria::repair(THD * thd, HA_CHECK_OPT *check_opt)
maria_chk_init(param);
param->thd= thd;
param->op_name= "repair";
file->error_count=0;

/*
The following can only be true if the table was marked as STATE_MOVED
@@ -1082,6 +1082,10 @@ static my_bool _ma_read_bitmap_page(MARIA_HA *info,
bitmap->used_size= (uint) ((data + 1) - end);
DBUG_ASSERT(bitmap->used_size <= bitmap->total_size);
}
else
{
_ma_set_fatal_error(info, my_errno);
}
/*
We can't check maria_bitmap_marker here as if the bitmap page
previously had a true checksum and the user switched mode to not checksum
@@ -3204,6 +3208,7 @@ _ma_bitmap_create_missing_into_pagecache(MARIA_SHARE *share,
*/
return FALSE;
err:
_ma_set_fatal_error_with_share(share, my_errno);
return TRUE;
}

@@ -921,7 +921,7 @@ static my_bool extend_area_on_page(MARIA_HA *info,
DBUG_PRINT("error", ("Not enough space: "
"length: %u request_length: %u",
length, request_length));
_ma_set_fatal_error(share, HA_ERR_WRONG_IN_RECORD);
_ma_set_fatal_error(info, HA_ERR_WRONG_IN_RECORD);
DBUG_RETURN(1); /* Error in block */
}
*empty_space= length; /* All space is here */
@@ -1788,7 +1788,10 @@ static my_bool get_head_or_tail_page(MARIA_HA *info,
page_link.changed= res->buff != 0;
push_dynamic(&info->pinned_pages, (void*) &page_link);
if (!page_link.changed)
goto crashed;
{
_ma_set_fatal_error(info, my_errno);
DBUG_RETURN(1);
}

DBUG_ASSERT((uint) (res->buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) ==
page_type);
@@ -1826,7 +1829,7 @@ static my_bool get_head_or_tail_page(MARIA_HA *info,

crashed:
DBUG_ASSERT(!maria_assert_if_crashed_table);
_ma_set_fatal_error(share, HA_ERR_WRONG_IN_RECORD); /* File crashed */
_ma_set_fatal_error(info, HA_ERR_WRONG_IN_RECORD); /* File crashed */
DBUG_RETURN(1);
}

@@ -1884,7 +1887,10 @@ static my_bool get_rowpos_in_head_or_tail_page(MARIA_HA *info,
page_link.changed= buff != 0;
push_dynamic(&info->pinned_pages, (void*) &page_link);
if (!page_link.changed) /* Read error */
goto err;
{
_ma_set_fatal_error(info, my_errno);
DBUG_RETURN(1);
}
DBUG_ASSERT((buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) ==
(uchar) page_type);
if ((buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) != (uchar) page_type)
@@ -1921,7 +1927,7 @@ static my_bool get_rowpos_in_head_or_tail_page(MARIA_HA *info,

err:
DBUG_ASSERT(!maria_assert_if_crashed_table);
_ma_set_fatal_error(share, HA_ERR_WRONG_IN_RECORD); /* File crashed */
_ma_set_fatal_error(info, HA_ERR_WRONG_IN_RECORD); /* File crashed */
DBUG_RETURN(1);
}

@@ -2146,7 +2152,7 @@ static my_bool write_full_pages(MARIA_HA *info,
{
if (!--sub_blocks)
{
_ma_set_fatal_error(share, HA_ERR_WRONG_IN_RECORD);
_ma_set_fatal_error(info, HA_ERR_WRONG_IN_RECORD);
DBUG_RETURN(1);
}

@@ -3475,7 +3481,7 @@ static my_bool write_block_record(MARIA_HA *info,
crashed:
DBUG_ASSERT(!maria_assert_if_crashed_table);
/* Something was wrong with data on page */
_ma_set_fatal_error(share, HA_ERR_WRONG_IN_RECORD);
_ma_set_fatal_error(info, HA_ERR_WRONG_IN_RECORD);

disk_err:
/**
@@ -3759,7 +3765,10 @@ static my_bool _ma_update_block_record2(MARIA_HA *info,
page_link.changed= buff != 0;
push_dynamic(&info->pinned_pages, (void*) &page_link);
if (!buff)
{
_ma_set_fatal_error(info, my_errno);
goto err;
}

org_empty_size= uint2korr(buff + EMPTY_SPACE_OFFSET);
rownr= ma_recordpos_to_dir_entry(record_pos);
@@ -3947,7 +3956,10 @@ static my_bool _ma_update_at_original_place(MARIA_HA *info,
page_link.changed= buff != 0;
push_dynamic(&info->pinned_pages, (void*) &page_link);
if (!buff)
{
_ma_set_fatal_error(info, my_errno);
goto err;
}

org_empty_size= uint2korr(buff + EMPTY_SPACE_OFFSET);
dir= dir_entry_pos(buff, block_size, rownr);
@@ -3958,7 +3970,7 @@ static my_bool _ma_update_at_original_place(MARIA_HA *info,
("org_empty_size: %u head_length: %u length_on_page: %u",
org_empty_size, (uint) cur_row->head_length,
length_on_head_page));
_ma_set_fatal_error(share, HA_ERR_WRONG_IN_RECORD);
_ma_set_fatal_error(info, HA_ERR_WRONG_IN_RECORD);
goto err;
}

@@ -4200,7 +4212,10 @@ static my_bool delete_head_or_tail(MARIA_HA *info,
page_link.changed= buff != 0;
push_dynamic(&info->pinned_pages, (void*) &page_link);
if (!buff)
{
_ma_set_fatal_error(info, my_errno);
DBUG_RETURN(1);
}
DBUG_ASSERT((buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) ==
(head ? HEAD_PAGE : TAIL_PAGE));

@@ -4608,7 +4623,7 @@ static uchar *read_next_extent(MARIA_HA *info, MARIA_EXTENT_CURSOR *extent,

crashed:
DBUG_ASSERT(!maria_assert_if_crashed_table);
_ma_set_fatal_error(share, HA_ERR_WRONG_IN_RECORD);
_ma_set_fatal_error(info, HA_ERR_WRONG_IN_RECORD);
DBUG_PRINT("error", ("wrong extent information"));
DBUG_RETURN(0);
}
@@ -4754,7 +4769,7 @@ int _ma_read_block_record2(MARIA_HA *info, uchar *record,
{
/* File crashed */
DBUG_ASSERT(!maria_assert_if_crashed_table);
_ma_set_fatal_error(share, HA_ERR_WRONG_IN_RECORD);
_ma_set_fatal_error(info, HA_ERR_WRONG_IN_RECORD);
DBUG_RETURN(HA_ERR_WRONG_IN_RECORD);
}
if (!trnman_can_read_from(info->trn, cur_row->trid))
@@ -5042,7 +5057,7 @@ int _ma_read_block_record2(MARIA_HA *info, uchar *record,
DBUG_ASSERT(!maria_assert_if_crashed_table);
/* Something was wrong with data on record */
DBUG_PRINT("error", ("Found record with wrong data"));
_ma_set_fatal_error(share, HA_ERR_WRONG_IN_RECORD);
_ma_set_fatal_error(info, HA_ERR_WRONG_IN_RECORD);
DBUG_RETURN(HA_ERR_WRONG_IN_RECORD);
}

@@ -5554,7 +5569,7 @@ int _ma_scan_block_record(MARIA_HA *info, uchar *record,
(uint) (uchar) info->scan.page_buff[DIR_COUNT_OFFSET]) == 0)
{
DBUG_PRINT("error", ("Wrong page header"));
_ma_set_fatal_error(share, HA_ERR_WRONG_IN_RECORD);
_ma_set_fatal_error(info, HA_ERR_WRONG_IN_RECORD);
DBUG_RETURN(HA_ERR_WRONG_IN_RECORD);
}
DBUG_PRINT("info", ("Page %lu has %u rows",
@@ -5601,7 +5616,7 @@ int _ma_scan_block_record(MARIA_HA *info, uchar *record,
err:
DBUG_ASSERT(!maria_assert_if_crashed_table);
DBUG_PRINT("error", ("Wrong data on page"));
_ma_set_fatal_error(share, HA_ERR_WRONG_IN_RECORD);
_ma_set_fatal_error(info, HA_ERR_WRONG_IN_RECORD);
DBUG_RETURN(HA_ERR_WRONG_IN_RECORD);
}

@@ -6523,7 +6538,7 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
DBUG_RETURN(result);

crashed_file:
_ma_set_fatal_error(share, HA_ERR_WRONG_IN_RECORD);
_ma_set_fatal_error(info, HA_ERR_WRONG_IN_RECORD);
err:
error= my_errno;
if (lock_method == PAGECACHE_LOCK_LEFT_WRITELOCKED)
@@ -6611,7 +6626,7 @@ uint _ma_apply_redo_purge_row_head_or_tail(MARIA_HA *info, LSN lsn,

if (delete_dir_entry(share, buff, rownr, &empty_space) < 0)
{
_ma_set_fatal_error(share, HA_ERR_WRONG_IN_RECORD);
_ma_set_fatal_error(info, HA_ERR_WRONG_IN_RECORD);
goto err;
}

@@ -107,7 +107,7 @@ my_bool _ma_read_cache(MARIA_HA *handler, IO_CACHE *info, uchar *buff,
if (!my_errno || my_errno == HA_ERR_FILE_TOO_SHORT)
{
if (!handler->in_check_table)
_ma_set_fatal_error(handler->s, HA_ERR_FILE_TOO_SHORT);
_ma_set_fatal_error(handler, HA_ERR_FILE_TOO_SHORT);
if (!my_errno)
my_errno= HA_ERR_WRONG_IN_RECORD;
}
@@ -470,9 +470,10 @@ static int ma_encrypt(MARIA_SHARE *share, MARIA_CRYPT_DATA *crypt_data,
*/
my_errno= HA_ERR_DECRYPTION_FAILED;
my_printf_error(HA_ERR_DECRYPTION_FAILED,
"Unknown key id %u. Can't continue!",
"Unknown key id %u for %s. Can't continue!",
MYF(ME_FATAL|ME_ERROR_LOG),
crypt_data->scheme.key_id);
crypt_data->scheme.key_id,
share->open_file_name.str);
return 1;
}

0 comments on commit 3d241eb

Please sign in to comment.