Skip to content

Commit 53dd0e4

Browse files
committed
MDEV-16222 Assertion `0' failed in row_purge_remove_sec_if_poss_leaf on table with virtual columns and indexes
Cause Stale thd->m_stmt_da->m_sql_errno which is from different invocation. Fix Reset error state before attempt to open table.
1 parent 0fe212a commit 53dd0e4

File tree

7 files changed

+118
-0
lines changed

7 files changed

+118
-0
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#
2+
# MDEV-16222 Assertion `0' failed in row_purge_remove_sec_if_poss_leaf on table with virtual columns and indexes
3+
#
4+
set @saved_frequency= @@global.innodb_purge_rseg_truncate_frequency;
5+
set global innodb_purge_rseg_truncate_frequency= 1;
6+
set @saved_dbug= @@global.debug_dbug;
7+
set global debug_dbug= "+d,ib_purge_virtual_mdev_16222_1,ib_purge_virtual_mdev_16222_2";
8+
create table t1 (
9+
pk serial, vb tinyblob as (b) virtual, b tinyblob,
10+
primary key(pk), index (vb(64)))
11+
engine innodb;
12+
insert ignore into t1 (b) values ('foo');
13+
select * into outfile 'load.data' from t1;
14+
load data infile 'load.data' replace into table t1;
15+
set debug_sync= "now WAIT_FOR latch_released";
16+
set global debug_dbug= "-d,ib_purge_virtual_mdev_16222_1";
17+
drop table t1;
18+
set debug_sync= "now SIGNAL drop_started WAIT_FOR got_no_such_table";
19+
create table t1 (
20+
pk serial, vb tinyblob as (b) virtual, b tinyblob,
21+
primary key(pk), index (vb(64)))
22+
engine innodb;
23+
insert ignore into t1 (b) values ('foo');
24+
select * into outfile 'load.data' from t1;
25+
load data infile 'load.data' replace into table t1;
26+
set debug_sync= "now WAIT_FOR got_no_such_table";
27+
set global debug_dbug= @saved_dbug;
28+
drop table t1;
29+
set global innodb_purge_rseg_truncate_frequency= @saved_frequency;
30+
set debug_sync= "RESET";
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--innodb-purge-threads=1
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
--source include/have_debug.inc
2+
--source include/have_innodb.inc
3+
4+
--echo #
5+
--echo # MDEV-16222 Assertion `0' failed in row_purge_remove_sec_if_poss_leaf on table with virtual columns and indexes
6+
--echo #
7+
8+
--let $datadir= `select @@datadir`
9+
set @saved_frequency= @@global.innodb_purge_rseg_truncate_frequency;
10+
set global innodb_purge_rseg_truncate_frequency= 1;
11+
set @saved_dbug= @@global.debug_dbug;
12+
set global debug_dbug= "+d,ib_purge_virtual_mdev_16222_1,ib_purge_virtual_mdev_16222_2";
13+
14+
create table t1 (
15+
pk serial, vb tinyblob as (b) virtual, b tinyblob,
16+
primary key(pk), index (vb(64)))
17+
engine innodb;
18+
19+
insert ignore into t1 (b) values ('foo');
20+
21+
select * into outfile 'load.data' from t1;
22+
load data infile 'load.data' replace into table t1;
23+
24+
set debug_sync= "now WAIT_FOR latch_released";
25+
set global debug_dbug= "-d,ib_purge_virtual_mdev_16222_1";
26+
drop table t1;
27+
--remove_file $datadir/test/load.data
28+
29+
set debug_sync= "now SIGNAL drop_started WAIT_FOR got_no_such_table";
30+
31+
create table t1 (
32+
pk serial, vb tinyblob as (b) virtual, b tinyblob,
33+
primary key(pk), index (vb(64)))
34+
engine innodb;
35+
36+
insert ignore into t1 (b) values ('foo');
37+
38+
select * into outfile 'load.data' from t1;
39+
load data infile 'load.data' replace into table t1;
40+
41+
set debug_sync= "now WAIT_FOR got_no_such_table";
42+
# FIXME: Racing condition here:
43+
# 1. purge thread goes into sending got_no_such_table
44+
# 2. test thread finishes debug_sync= "RESET" below
45+
# 3. purge thread sends got_no_such_table
46+
set global debug_dbug= @saved_dbug;
47+
48+
# cleanup
49+
drop table t1;
50+
--remove_file $datadir/test/load.data
51+
52+
set global innodb_purge_rseg_truncate_frequency= @saved_frequency;
53+
set debug_sync= "RESET";

sql/sql_class.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4491,6 +4491,11 @@ unsigned long long thd_get_query_id(const MYSQL_THD thd)
44914491
return((unsigned long long)thd->query_id);
44924492
}
44934493

4494+
void thd_clear_error(MYSQL_THD thd)
4495+
{
4496+
thd->clear_error();
4497+
}
4498+
44944499
extern "C" const struct charset_info_st *thd_charset(MYSQL_THD thd)
44954500
{
44964501
return(thd->charset());

sql/sql_table.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2077,6 +2077,11 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
20772077
}
20782078
}
20792079

2080+
DBUG_EXECUTE_IF("ib_purge_virtual_mdev_16222_1",
2081+
DBUG_ASSERT(!debug_sync_set_action(
2082+
thd,
2083+
STRING_WITH_LEN("now SIGNAL drop_started"))););
2084+
20802085
/* mark for close and remove all cached entries */
20812086
thd->push_internal_handler(&err_handler);
20822087
error= mysql_rm_table_no_locks(thd, tables, if_exists, drop_temporary,

sql/table.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7682,6 +7682,7 @@ int TABLE::update_virtual_fields(handler *h, enum_vcol_update_mode update_mode)
76827682

76837683
int TABLE::update_virtual_field(Field *vf)
76847684
{
7685+
DBUG_ASSERT(!in_use->is_error());
76857686
Query_arena backup_arena;
76867687
DBUG_ENTER("TABLE::update_virtual_field");
76877688
in_use->set_n_backup_active_arena(expr_arena, &backup_arena);

storage/innobase/handler/ha_innodb.cc

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ this program; if not, write to the Free Software Foundation, Inc.,
119119

120120
extern "C" void thd_mark_transaction_to_rollback(MYSQL_THD thd, bool all);
121121
unsigned long long thd_get_query_id(const MYSQL_THD thd);
122+
void thd_clear_error(MYSQL_THD thd);
123+
122124
TABLE *find_fk_open_table(THD *thd, const char *db, size_t db_len,
123125
const char *table, size_t table_len);
124126
MYSQL_THD create_thd();
@@ -21493,6 +21495,8 @@ static TABLE* innodb_acquire_mdl(THD* thd, dict_table_t* table)
2149321495
return NULL;
2149421496
}
2149521497

21498+
DEBUG_SYNC(thd, "ib_purge_virtual_latch_released");
21499+
2149621500
const table_id_t table_id = table->id;
2149721501
retry_mdl:
2149821502
const bool unaccessible = !table->is_readable() || table->corrupted;
@@ -21504,6 +21508,10 @@ static TABLE* innodb_acquire_mdl(THD* thd, dict_table_t* table)
2150421508

2150521509
TABLE* mariadb_table = open_purge_table(thd, db_buf, db_buf_len,
2150621510
tbl_buf, tbl_buf_len);
21511+
if (!mariadb_table)
21512+
thd_clear_error(thd);
21513+
21514+
DEBUG_SYNC(thd, "ib_purge_virtual_got_no_such_table");
2150721515

2150821516
table = dict_table_open_on_id(table_id, false, DICT_TABLE_OP_NORMAL);
2150921517

@@ -21553,6 +21561,20 @@ static TABLE* innodb_acquire_mdl(THD* thd, dict_table_t* table)
2155321561
for purge thread */
2155421562
static TABLE* innodb_find_table_for_vc(THD* thd, dict_table_t* table)
2155521563
{
21564+
DBUG_EXECUTE_IF(
21565+
"ib_purge_virtual_mdev_16222_1",
21566+
DBUG_ASSERT(!debug_sync_set_action(
21567+
thd,
21568+
STRING_WITH_LEN("ib_purge_virtual_latch_released "
21569+
"SIGNAL latch_released "
21570+
"WAIT_FOR drop_started"))););
21571+
DBUG_EXECUTE_IF(
21572+
"ib_purge_virtual_mdev_16222_2",
21573+
DBUG_ASSERT(!debug_sync_set_action(
21574+
thd,
21575+
STRING_WITH_LEN("ib_purge_virtual_got_no_such_table "
21576+
"SIGNAL got_no_such_table"))););
21577+
2155621578
if (THDVAR(thd, background_thread)) {
2155721579
/* Purge thread acquires dict_operation_lock while
2155821580
processing undo log record. Release the dict_operation_lock
@@ -21888,6 +21910,7 @@ innobase_get_computed_value(
2188821910
dbug_tmp_restore_column_map(mysql_table->write_set, old_write_set);
2188921911

2189021912
if (ret != 0) {
21913+
// FIXME: Why this error message is macro-hidden?
2189121914
#ifdef INNODB_VIRTUAL_DEBUG
2189221915
ib::warn() << "Compute virtual column values failed ";
2189321916
fputs("InnoDB: Cannot compute value for following record ",

0 commit comments

Comments
 (0)