Fixed bug in redo handling of batch insert in Aria

The symptom of the bug was that one got the following in
the aria recovery log:
"Table 'xxx', id 57, has create_rename_lsn (1,0x12dee) more recent than LOGREC_FILE_ID's LSN (1,0x12dc4), ignoring open request"

After this all future redo entries was marked with
"For table of short id 57, table skipped, so skipping record"

Analyze:
When ending batch insert, create_rename_lsn for the table
is updated to signal that earlier redo entries for the
table can't be applied. The problem was that future redo
entries was also ignored as redo code assumed they where
for the old table.

Fixed by calling translog_dessign_id, which causes
future redo entries to be seen as belonging to the
updated table.
This commit is contained in:
Monty 2019-03-14 12:19:32 +02:00
parent f2f40a17ef
commit bb8c82c66a
3 changed files with 81 additions and 0 deletions

View file

@ -292,6 +292,44 @@ t1 CREATE TABLE `t1` (
) ENGINE=Aria AUTO_INCREMENT=17 DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1
insert into t1 values(null, "f");
drop table t1;
Test that bulk insert works with recovery
CREATE TABLE t1 (i int, key(i)) TRANSACTIONAL=1 ENGINE=ARIA;
CREATE TABLE t2 (i int, key(i)) TRANSACTIONAL=1 ENGINE=ARIA;
connection admin;
* copied t2 for feeding_recovery
* copied t1 for feeding_recovery
connection default;
insert into t2 values
(0), (1), (2), (3), (4), (5), (6), (7), (8), (9),
(0), (1), (2), (3), (4), (5), (6), (7), (8), (9),
(0), (1), (2), (3), (4), (5), (6), (7), (8), (9),
(0), (1), (2), (3), (4), (5), (6), (7), (8), (9),
(0), (1), (3), (3), (4), (5), (6), (7), (8), (9),
(0), (1), (2), (3), (4), (5), (6), (7), (8), (9),
(0), (1), (2), (3), (4), (5), (6), (7), (8), (9),
(0), (1), (2), (3), (4), (5), (6), (7), (8), (9),
(0), (1), (2), (3), (4), (5), (6), (7), (8), (9),
(0), (1), (2), (3), (4), (5), (6), (7), (8), (9);
insert into t1 select * from t2;
insert into t2 select * from t2;
connection admin;
SET SESSION debug_dbug="+d,maria_flush_whole_log,maria_crash";
* crashing mysqld intentionally
set global aria_checkpoint_interval=1;
ERROR HY000: Lost connection to MySQL server during query
* recovery happens
connection default;
use mysqltest;
select count(*) from t1;
count(*)
100
select count(*) from t2;
count(*)
200
check table t2;
Table Op Msg_type Msg_text
mysqltest.t2 check status OK
drop table t1,t2;
drop database mysqltest_for_feeding_recovery;
drop database mysqltest_for_comparison;
drop database mysqltest;

View file

@ -195,6 +195,36 @@ show create table t1;
insert into t1 values(null, "f");
drop table t1;
--echo Test that bulk insert works with recovery
let $mms_tables=2;
CREATE TABLE t1 (i int, key(i)) TRANSACTIONAL=1 ENGINE=ARIA;
CREATE TABLE t2 (i int, key(i)) TRANSACTIONAL=1 ENGINE=ARIA;
-- source include/maria_make_snapshot_for_feeding_recovery.inc
insert into t2 values
(0), (1), (2), (3), (4), (5), (6), (7), (8), (9),
(0), (1), (2), (3), (4), (5), (6), (7), (8), (9),
(0), (1), (2), (3), (4), (5), (6), (7), (8), (9),
(0), (1), (2), (3), (4), (5), (6), (7), (8), (9),
(0), (1), (3), (3), (4), (5), (6), (7), (8), (9),
(0), (1), (2), (3), (4), (5), (6), (7), (8), (9),
(0), (1), (2), (3), (4), (5), (6), (7), (8), (9),
(0), (1), (2), (3), (4), (5), (6), (7), (8), (9),
(0), (1), (2), (3), (4), (5), (6), (7), (8), (9),
(0), (1), (2), (3), (4), (5), (6), (7), (8), (9);
insert into t1 select * from t2;
insert into t2 select * from t2;
let $mvr_restore_old_snapshot=0;
let $mms_compare_physically=0;
let $mvr_debug_option="+d,maria_flush_whole_log,maria_crash";
let $mvr_crash_statement= set global aria_checkpoint_interval=1;
let $mms_tables=0;
-- source include/maria_verify_recovery.inc
select count(*) from t1;
select count(*) from t2;
check table t2;
drop table t1,t2;
# clean up everything
let $mms_purpose=feeding_recovery;
eval drop database mysqltest_for_$mms_purpose;

View file

@ -1403,6 +1403,11 @@ static int new_table(uint16 sid, const char *name, LSN lsn_of_file_id)
}
if (cmp_translog_addr(lsn_of_file_id, share->state.create_rename_lsn) <= 0)
{
/*
This can happen if the table was dropped and re-created since this
redo entry or if the table had a bulk insert directly after create,
in which case the create_rename_lsn changed.
*/
tprint(tracef, ", has create_rename_lsn " LSN_FMT " more recent than"
" LOGREC_FILE_ID's LSN " LSN_FMT ", ignoring open request",
LSN_IN_PARTS(share->state.create_rename_lsn),
@ -3616,8 +3621,16 @@ my_bool _ma_reenable_logging_for_table(MARIA_HA *info, my_bool flush_pages)
{
/* Ensure that recover is not executing any redo before this */
if (!maria_in_recovery)
{
if (share->id != 0)
{
mysql_mutex_lock(&share->intern_lock);
translog_deassign_id_from_share(share);
mysql_mutex_unlock(&share->intern_lock);
}
share->state.is_of_horizon= share->state.create_rename_lsn=
share->state.skip_redo_lsn= translog_get_horizon();
}
/*
We are going to change callbacks; if a page is flushed at this moment
this can cause race conditions, that's one reason to flush pages