Skip to content
Permalink
Browse files

MDEV-19055 Failures with temporary tables and Aria

There was two separate problems:
- Aria pagecache didn't properly handle re-reading of blocks
  that have given errors before (this triggered an assert)
- temporary tables that where opened several times where
  not properly closed in ALTER, REPAIR or OPTIMIZE table

Other things
- Added a couple of asserts that will make it easier to
  find problems like this in the future.
  • Loading branch information...
montywi committed Jun 17, 2019
1 parent 2b660fb commit c8b5fa4afc6c233101b8163ef19c1abc1be0373d
@@ -47,3 +47,46 @@ t1 CREATE TABLE `t1` (
) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1
CREATE TABLE t2 SELECT * FROM t1;
DROP TABLE t1, t2;
#
# MDEV-19055 Assertion `(_my_thread_var())->thr_errno != 0' failed in pagecache_read
#
CREATE OR REPLACE TABLE t1 (x INT) ENGINE=Aria;
CREATE TEMPORARY TABLE t2 (a TIME) ENGINE=Aria;
ALTER TABLE t2 ADD b DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP;
ALTER TABLE t2 ADD CHECK (b = 4);
INSERT IGNORE INTO t2 () VALUES (),(),(),();
ALTER IGNORE TABLE t2 ADD c INT;
SELECT count(a),sum(a) FROM t2;
count(a) sum(a)
0 NULL
DELETE FROM t2 ORDER BY c LIMIT 1;
INSERT IGNORE INTO t2 SELECT * FROM t2;
OPTIMIZE TABLE t2;
Table Op Msg_type Msg_text
test.t2 optimize status OK
SELECT count(a),sum(a) FROM t2;
count(a) sum(a)
0 NULL
INSERT IGNORE INTO t2 SELECT * FROM t2;
SET SQL_MODE= 'STRICT_ALL_TABLES';
SELECT count(a),sum(a) FROM t2;
count(a) sum(a)
0 NULL
ALTER TABLE t2 CHANGE IF EXISTS d c INT;
ERROR 22007: Incorrect datetime value: '4'
SELECT count(a),sum(a) FROM t2;
count(a) sum(a)
0 NULL
ALTER IGNORE TABLE t2 ADD IF NOT EXISTS e BIT;
ALTER TABLE t1 MODIFY IF EXISTS xx INT;
INSERT IGNORE INTO t2 () VALUES (),(),(),();
SELECT count(a),sum(a) FROM t2;
count(a) sum(a)
0 NULL
check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
check table t2;
Table Op Msg_type Msg_text
test.t2 check status OK
DROP TABLE t1,t2;
@@ -42,3 +42,38 @@ ALTER TABLE t1 ORDER BY unknown_column;
SHOW CREATE TABLE t1;
CREATE TABLE t2 SELECT * FROM t1;
DROP TABLE t1, t2;

--echo #
--echo # MDEV-19055 Assertion `(_my_thread_var())->thr_errno != 0' failed in pagecache_read
--echo #

--disable_warnings
CREATE OR REPLACE TABLE t1 (x INT) ENGINE=Aria;
CREATE TEMPORARY TABLE t2 (a TIME) ENGINE=Aria;
ALTER TABLE t2 ADD b DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP;
ALTER TABLE t2 ADD CHECK (b = 4);
INSERT IGNORE INTO t2 () VALUES (),(),(),();
ALTER IGNORE TABLE t2 ADD c INT;
SELECT count(a),sum(a) FROM t2;
DELETE FROM t2 ORDER BY c LIMIT 1;
INSERT IGNORE INTO t2 SELECT * FROM t2;
OPTIMIZE TABLE t2;
SELECT count(a),sum(a) FROM t2;
INSERT IGNORE INTO t2 SELECT * FROM t2;
SET SQL_MODE= 'STRICT_ALL_TABLES';
SELECT count(a),sum(a) FROM t2;
--error ER_TRUNCATED_WRONG_VALUE
ALTER TABLE t2 CHANGE IF EXISTS d c INT;
SELECT count(a),sum(a) FROM t2;
ALTER IGNORE TABLE t2 ADD IF NOT EXISTS e BIT;
ALTER TABLE t1 MODIFY IF EXISTS xx INT;
INSERT IGNORE INTO t2 () VALUES (),(),(),();
SELECT count(a),sum(a) FROM t2;
--enable_warnings
check table t1;
check table t2;
DROP TABLE t1,t2;

#
# End of 10.2 tests
#
@@ -68,6 +68,8 @@ size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset,

if (readbytes != Count)
{
/* We should never read with wrong file descriptor! */
DBUG_ASSERT(my_errno != 9);
my_errno= errno;
if (errno == 0 || (readbytes != (size_t) -1 &&
(MyFlags & (MY_NABP | MY_FNABP))))
@@ -697,19 +697,23 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
MDL_SHARED_NO_READ_WRITE lock (MDL_SHARED_WRITE cannot be upgraded)
by *not* having HA_CONCURRENT_OPTIMIZE table_flag.
*/
if (lock_type == TL_WRITE && !table->table->s->tmp_table &&
table->mdl_request.type > MDL_SHARED_WRITE)
if (lock_type == TL_WRITE && table->mdl_request.type > MDL_SHARED_WRITE)
{
if (wait_while_table_is_used(thd, table->table, HA_EXTRA_NOT_USED))
goto err;
DEBUG_SYNC(thd, "after_admin_flush");
/* Flush entries in the query cache involving this table. */
query_cache_invalidate3(thd, table->table, 0);
/*
XXX: hack: switch off open_for_modify to skip the
flush that is made later in the execution flow.
*/
open_for_modify= 0;
if (table->table->s->tmp_table)
thd->close_unused_temporary_table_instances(tables);
else
{
if (wait_while_table_is_used(thd, table->table, HA_EXTRA_NOT_USED))
goto err;
DEBUG_SYNC(thd, "after_admin_flush");
/* Flush entries in the query cache involving this table. */
query_cache_invalidate3(thd, table->table, 0);
/*
XXX: hack: switch off open_for_modify to skip the
flush that is made later in the execution flow.
*/
open_for_modify= 0;
}
}

if (table->table->s->crashed && operator_func == &handler::ha_check)
@@ -9536,6 +9536,8 @@ do_continue:;

DEBUG_SYNC(thd, "alter_table_copy_after_lock_upgrade");
}
else
thd->close_unused_temporary_table_instances(table_list);

// It's now safe to take the table level lock.
if (lock_tables(thd, table_list, alter_ctx.tables_opened, 0))
@@ -5244,6 +5244,8 @@ my_bool _ma_scan_init_block_record(MARIA_HA *info)
{
MARIA_SHARE *share= info->s;
DBUG_ENTER("_ma_scan_init_block_record");
DBUG_ASSERT(info->dfile.file == share->bitmap.file.file);

/*
bitmap_buff may already be allocated if this is the second call to
rnd_init() without a rnd_end() in between, see sql/handler.h
@@ -3464,8 +3464,6 @@ uchar *pagecache_read(PAGECACHE *pagecache,
pagecache_pthread_mutex_lock(&pagecache->cache_lock);
#endif
}
if (status & PCBLOCK_ERROR)
my_errno= block->error;
}

remove_reader(block);
@@ -3497,6 +3495,7 @@ uchar *pagecache_read(PAGECACHE *pagecache,

if (status & PCBLOCK_ERROR)
{
my_errno= block->error;
DBUG_ASSERT(my_errno != 0);
DBUG_PRINT("error", ("Got error %d when doing page read", my_errno));
DBUG_RETURN((uchar *) 0);

0 comments on commit c8b5fa4

Please sign in to comment.
You can’t perform that action at this time.