[MDEV-31893] Valgrind reports issues in main.join_cache_notasan Created: 2023-08-10  Updated: 2023-10-09  Resolved: 2023-08-10

Status: Closed
Project: MariaDB Server
Component/s: Optimizer
Affects Version/s: None
Fix Version/s: 10.8.8, 10.4.31, 10.5.22, 10.6.15, 10.9.8, 10.10.6, 10.11.5

Type: Bug Priority: Blocker
Reporter: Michael Widenius Assignee: Michael Widenius
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
relates to MDEV-31348 Assertion `last_key_entry >= end_pos'... Closed

 Description   

Valgrind exposed a problem with the join_cache for hash joins:
=25636== Conditional jump or move depends on uninitialised value(s)
==25636== at 0xA8FF4E: JOIN_CACHE_HASHED::init_hash_table() (sql_join_cache.cc:2901)
==25636== by 0xA8FCEA: JOIN_CACHE_HASHED::init(bool) (sql_join_cache.cc:2841)
==25636== by 0xA91381: JOIN_CACHE_BNLH::init(bool) (sql_join_cache.cc:3940)
==25636== by 0x8FD85A: JOIN::init_join_caches() (sql_select.cc:1878)
==25636== by 0x902058: JOIN::optimize_stage2() (sql_select.cc:3111)
==25636== by 0x8FF7F0: JOIN::optimize_inner() (sql_select.cc:2394)
==25636== by 0x8FCF7D: JOIN::optimize() (sql_select.cc:1711)

The reason for this was that avg_record_length has a random value if one used
SET optimizer_switch='optimize_join_buffer_size=off';

This causes either 'random size' memory to be allocated (up to join_buffer_size) which can
increase memory usage or if avg_record_length is less than the row size, memory overwrites in thd->mem_root, which is bad.

Fixed by setting avg_record_length in JOIN_CACHE_HASHED::init() before it's used.



 Comments   
Comment by Michael Widenius [ 2023-08-10 ]

wrong assignment

Comment by Michael Widenius [ 2023-08-10 ]

Pushed into 10.4

Comment by Otto Kekäläinen [ 2023-10-09 ]

I saw a variation of this in https://buildd.debian.org/status/fetch.php?pkg=mariadb&arch=hppa&ver=1%3A10.11.5-2&stamp=1696821455&raw=0 (hppa build of Debian 1:10.11.5-2):

main.join_cache_notasan 'innodb'         w1 [ fail ]
        Test ended at 2023-10-09 03:16:39
 
CURRENT_TEST: main.join_cache_notasan
mysqltest: At line 30: query 'SELECT t1.i,t2.i FROM t2  LEFT  JOIN t1 ON t1.i = t2.i  WHERE t1.i' succeeded - should have failed with error ER_OUTOFMEMORY (1037)...
 
The result from queries just before the failure was:
#
# MDEV-28217 Incorrect Join Execution When Controlling Join Buffer Size
#
CREATE TABLE t1 (i int PRIMARY KEY)engine=innodb;
INSERT INTO t1 VALUES (1332945389);
CREATE TABLE t2 (i int PRIMARY KEY)engine=innodb;
INSERT INTO t2 VALUES (1180244875), (1951338178);
SET SESSION join_buffer_size= X;
Warnings:
Warning	X	Truncated incorrect join_buffer_size value: 'X'
SET SESSION join_cache_level = 4;
SET optimizer_switch='optimize_join_buffer_size=on';
SELECT t2.i FROM t2  LEFT  JOIN t1 ON t1.i = t2.i  WHERE t1.i;
i
SET optimizer_switch='optimize_join_buffer_size=off';
SELECT t1.i,t2.i FROM t2  LEFT  JOIN t1 ON t1.i = t2.i  WHERE t1.i;

Generated at Thu Feb 08 10:27:15 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.