[Commits] 75c244fc2e9: MDEV-17066: Bytes lost or Assertion `status_var.local_memory_used == 0 after DELETE with subquery with ROLLUP
revision-id: 75c244fc2e9d964f114f270cd0065fc879e04cd3 (mariadb-10.1.43-219-g75c244fc2e9) parent(s): 62d73df6b270cc94ba577e96d3bf325170f306fe author: Varun Gupta committer: Varun Gupta timestamp: 2020-07-22 16:02:39 +0530 message: MDEV-17066: Bytes lost or Assertion `status_var.local_memory_used == 0 after DELETE with subquery with ROLLUP The issue here is when records are read from the temp table via a cache(rr_from_cache), the cache is allocated for each execution of the correlated subquery. But the deallocation of the cache only happened after the entire execution of the parent select was done. The fix here would be free the cache on each execution of the subquery. --- mysql-test/r/subselect4.result | 25 +++++++++++++++++++++++++ mysql-test/t/subselect4.test | 22 ++++++++++++++++++++++ sql/records.cc | 25 +++++++++++++++++++------ sql/records.h | 1 + sql/sql_select.cc | 1 + 5 files changed, 68 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/subselect4.result b/mysql-test/r/subselect4.result index 606ab847028..441ee8acff8 100644 --- a/mysql-test/r/subselect4.result +++ b/mysql-test/r/subselect4.result @@ -2608,3 +2608,28 @@ region area population Central America and the Caribbean 442 66422 SET @@optimizer_switch= @save_optimizer_switch; DROP TABLE t1; +# +# MDEV-17066: Bytes lost or Assertion `status_var.local_memory_used == 0 after DELETE +# with subquery with ROLLUP +# +CREATE TABLE t1 (i INT DEFAULT 0, c VARCHAR(2048)); +INSERT INTO t1 SELECT 0, seq FROM seq_1_to_6000; +CREATE TABLE t2 (f VARCHAR(2048) DEFAULT ''); +INSERT INTO t2 VALUES ('1'),('bar'); +EXPLAIN +SELECT * FROM t2 WHERE f IN ( SELECT MAX(c) FROM t1 GROUP BY c WITH ROLLUP); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 6000 Using filesort +SELECT * FROM t2 WHERE f IN ( SELECT MAX(c) FROM t1 GROUP BY c WITH ROLLUP); +f +1 +SELECT * FROM t2; +f +1 +bar +DELETE FROM t2 WHERE f IN ( SELECT MAX(c) FROM t1 GROUP BY c WITH ROLLUP ); +SELECT * FROM t2; +f +bar +DROP TABLE t1, t2; diff --git a/mysql-test/t/subselect4.test b/mysql-test/t/subselect4.test index 21ec28b1c03..3333668f554 100644 --- a/mysql-test/t/subselect4.test +++ b/mysql-test/t/subselect4.test @@ -4,6 +4,7 @@ drop table if exists t0,t1,t2,t3,t4,t5,t6; drop view if exists v1, v2; --enable_warnings +--source include/have_sequence.inc set @subselect4_tmp= @@optimizer_switch; set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on'; @@ -2138,3 +2139,24 @@ WHERE population/area = (SELECT MAX(population/area) from t1 B where A.region = SET @@optimizer_switch= @save_optimizer_switch; DROP TABLE t1; + +--echo # +--echo # MDEV-17066: Bytes lost or Assertion `status_var.local_memory_used == 0 after DELETE +--echo # with subquery with ROLLUP +--echo # + +CREATE TABLE t1 (i INT DEFAULT 0, c VARCHAR(2048)); +INSERT INTO t1 SELECT 0, seq FROM seq_1_to_6000; + +CREATE TABLE t2 (f VARCHAR(2048) DEFAULT ''); +INSERT INTO t2 VALUES ('1'),('bar'); + +EXPLAIN +SELECT * FROM t2 WHERE f IN ( SELECT MAX(c) FROM t1 GROUP BY c WITH ROLLUP); +SELECT * FROM t2 WHERE f IN ( SELECT MAX(c) FROM t1 GROUP BY c WITH ROLLUP); + +SELECT * FROM t2; +DELETE FROM t2 WHERE f IN ( SELECT MAX(c) FROM t1 GROUP BY c WITH ROLLUP ); +SELECT * FROM t2; + +DROP TABLE t1, t2; diff --git a/sql/records.cc b/sql/records.cc index 795f1197840..c8cec7759f2 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -304,12 +304,9 @@ bool init_read_record(READ_RECORD *info,THD *thd, TABLE *table, void end_read_record(READ_RECORD *info) -{ /* free cache if used */ - if (info->cache) - { - my_free_lock(info->cache); - info->cache=0; - } +{ + /* free cache if used */ + free_cache(info); if (info->table) { filesort_free_buffers(info->table,0); @@ -321,6 +318,22 @@ void end_read_record(READ_RECORD *info) } } + +/* + @brief + Free the cache used for reading records via rr_from_cache +*/ + +void free_cache(READ_RECORD *info) +{ + if (info->cache) + { + my_free_lock(info->cache); + info->cache= NULL; + } +} + + static int rr_handle_error(READ_RECORD *info, int error) { if (info->thd->killed) diff --git a/sql/records.h b/sql/records.h index fe3e9556bcf..ad940640217 100644 --- a/sql/records.h +++ b/sql/records.h @@ -77,6 +77,7 @@ bool init_read_record(READ_RECORD *info, THD *thd, TABLE *reg_form, bool init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table, bool print_error, uint idx, bool reverse); void end_read_record(READ_RECORD *info); +void free_cache(READ_RECORD *info); void rr_unlock_row(st_join_table *tab); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 647dee80188..2311fbb5017 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -12225,6 +12225,7 @@ void JOIN::cleanup(bool full) tab->table->s->table_name.str, tab->table->alias.c_ptr())); tab->table->file->ha_index_or_rnd_end(); + free_cache(&tab->read_record); } } }
participants (1)
-
Varun