1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

Bug #42419: Server crash with "Pure virtual method called" on two concurrent

connections
The problem is that tables can enter open table cache for a thread without 
being properly cleaned up. This can happen if make_join_statistics() fails 
to read a const table because of e.g. a deadlock. It does set a member of 
TABLE structure to a value it allocates, but doesn't clean-up this setting 
on error nor does it set the rest of the members in JOIN to allow for 
automatic cleanup.
As a result when such an error occurs and the next statement depends re-uses 
the table from the open tables cache it will get it with this 
TABLE::reginfo.join_tab pointing to a memory area that's freed.
Fixed by making sure make_join_statistics() cleans up TABLE::reginfo.join_tab 
on error.
This commit is contained in:
Georgi Kodinov
2009-02-19 17:30:03 +02:00
parent 2a162ef3b1
commit b2c161c192
4 changed files with 92 additions and 13 deletions

View File

@ -1025,4 +1025,55 @@ CREATE INDEX i1 on t1 (a(3));
SELECT * FROM t1 WHERE a = 'abcde';
DROP TABLE t1;
#
# Bug #42419: Server crash with "Pure virtual method called" on two
# concurrent connections
#
connect (c1, localhost, root,,);
connect (c2, localhost, root,,);
CREATE TABLE t1 (a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b INT)
ENGINE=InnoDB;
INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
connection c1;
SET AUTOCOMMIT = 0;
CREATE TEMPORARY TABLE t1_tmp (b INT);
INSERT INTO t1_tmp SELECT b FROM t1 WHERE a = 3;
INSERT INTO t1_tmp SELECT b FROM t1 WHERE a = 2;
connection c2;
SET AUTOCOMMIT = 0;
CREATE TEMPORARY TABLE t2_tmp ( a INT, new_a INT);
INSERT INTO t2_tmp VALUES (1,51),(2,52),(3,53);
UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 1;
--send
UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 2;
--sleep 3
connection c1;
--error ER_LOCK_DEADLOCK
INSERT INTO t1_tmp SELECT b FROM t1 WHERE a = 1;
connection c2;
--reap
UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 3;
connection default;
disconnect c1;
disconnect c2;
DROP TABLE t1;
--echo End of 5.0 tests