mirror of
https://github.com/MariaDB/server.git
synced 2026-10-23 18:49:29 +03:00
MDEV-40930: binlog-in-engine: seek() on invalid handle during change_user()
When using binlog-in-engine, the binlog trx cache is memory-only and does not have an underlying temporary file backing the cache. The binlog code must handle this and avoid calling into IO_CACHE code that manipulates the underlying file. However, one case was forgotten where the binlog caches are truncated during COM_CHANGE_USER / THD::change_user() (connection pool reset), and the code would try to seek() on an invalid file handle. This crashes on Windows and is just plain wrong on any platform. Thanks to Vlad for analysis and test case. Reviewed-by: Brandon Nesterenko <brandon.nesterenko@mariadb.com> Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
This commit is contained in:
19
mysql-test/suite/binlog_in_engine/trx_cache_truncate.result
Normal file
19
mysql-test/suite/binlog_in_engine/trx_cache_truncate.result
Normal file
@@ -0,0 +1,19 @@
|
||||
#
|
||||
# MDEV-40930: my_seek() on invalid file handle during COM_CHANGE_USER /
|
||||
# COM_RESET_CONNECTION (connection pool reset) with
|
||||
# binlog_storage_engine=innodb.
|
||||
#
|
||||
CREATE TABLE t1 (a INT, b VARCHAR(100)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (1, 'x');
|
||||
# COM_CHANGE_USER
|
||||
change_user root,,test;
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
a b
|
||||
1 x
|
||||
INSERT INTO t1 VALUES (2, 'y');
|
||||
# COM_RESET_CONNECTION -- dispatches to the same THD::change_user()
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
a b
|
||||
1 x
|
||||
2 y
|
||||
DROP TABLE t1;
|
||||
23
mysql-test/suite/binlog_in_engine/trx_cache_truncate.test
Normal file
23
mysql-test/suite/binlog_in_engine/trx_cache_truncate.test
Normal file
@@ -0,0 +1,23 @@
|
||||
--source include/have_binlog_format_row.inc
|
||||
--source include/have_innodb_binlog.inc
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-40930: my_seek() on invalid file handle during COM_CHANGE_USER /
|
||||
--echo # COM_RESET_CONNECTION (connection pool reset) with
|
||||
--echo # binlog_storage_engine=innodb.
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (a INT, b VARCHAR(100)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (1, 'x');
|
||||
|
||||
--echo # COM_CHANGE_USER
|
||||
--change_user root,,test
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
|
||||
INSERT INTO t1 VALUES (2, 'y');
|
||||
|
||||
--echo # COM_RESET_CONNECTION -- dispatches to the same THD::change_user()
|
||||
reset_connection;
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
|
||||
DROP TABLE t1;
|
||||
@@ -123,6 +123,7 @@ static void reset_tracking_io_cache(IO_CACHE *info)
|
||||
|
||||
void truncate_io_cache(IO_CACHE *info)
|
||||
{
|
||||
DBUG_ASSERT(info->file >= (File)0);
|
||||
if (mysql_file_seek(info->file, 0L, MY_SEEK_END, MYF(0)) != 0 &&
|
||||
my_chsize(info->file, 0, 0, MYF(MY_WME)) == 0)
|
||||
reset_tracking_io_cache(info);
|
||||
|
||||
@@ -580,8 +580,11 @@ public:
|
||||
/* Truncate temporary files if needed. Used with change_user */
|
||||
void truncate_tmp_files()
|
||||
{
|
||||
stmt_cache.truncate_cache_file();
|
||||
trx_cache.truncate_cache_file();
|
||||
if (!opt_binlog_engine_hton)
|
||||
{
|
||||
stmt_cache.truncate_cache_file();
|
||||
trx_cache.truncate_cache_file();
|
||||
}
|
||||
}
|
||||
|
||||
binlog_cache_data* get_binlog_cache_data(bool is_transactional)
|
||||
|
||||
Reference in New Issue
Block a user