From: Georgi Kodinov Date: February 19 2009 3:30pm Subject: bzr commit into mysql-5.0-bugteam branch (joro:2742) Bug#42419 List-Archive: http://lists.mysql.com/commits/66933 X-Bug: 42419 Message-Id: <200902191530.n1JFUfH4015496@magare.gmz> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============1407118049636171450==" --===============1407118049636171450== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///home/kgeorge/mysql/work/B42419-5.0-bugteam/ based on revid:matthias.leich@stripped 2742 Georgi Kodinov 2009-02-19 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. @ mysql-test/r/innodb_mysql.result Bug #42419: test case @ mysql-test/t/innodb_mysql-master.opt Bug #42419: increase the timeout so it covers te conservative sleep 3 in the test @ mysql-test/t/innodb_mysql.test Bug #42419: test case @ sql/sql_select.cc Bug #42419: clean up the members of TABLE on failure in make_join_statisitcs() modified: mysql-test/r/innodb_mysql.result mysql-test/t/innodb_mysql-master.opt mysql-test/t/innodb_mysql.test sql/sql_select.cc === modified file 'mysql-test/r/innodb_mysql.result' --- a/mysql-test/r/innodb_mysql.result 2008-11-27 14:54:23 +0000 +++ b/mysql-test/r/innodb_mysql.result 2009-02-19 15:30:03 +0000 @@ -1267,4 +1267,20 @@ CREATE INDEX i1 on t1 (a(3)); SELECT * FROM t1 WHERE a = 'abcde'; a DROP TABLE t1; +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); +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; +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; +UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 2; +INSERT INTO t1_tmp SELECT b FROM t1 WHERE a = 1; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 3; +DROP TABLE t1; End of 5.0 tests === modified file 'mysql-test/t/innodb_mysql-master.opt' --- a/mysql-test/t/innodb_mysql-master.opt 2006-12-19 23:57:51 +0000 +++ b/mysql-test/t/innodb_mysql-master.opt 2009-02-19 15:30:03 +0000 @@ -1 +1 @@ ---innodb-lock-wait-timeout=2 +--innodb-lock-wait-timeout=3 === modified file 'mysql-test/t/innodb_mysql.test' --- a/mysql-test/t/innodb_mysql.test 2008-11-27 14:54:23 +0000 +++ b/mysql-test/t/innodb_mysql.test 2009-02-19 15:30:03 +0000 @@ -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 === modified file 'sql/sql_select.cc' --- a/sql/sql_select.cc 2009-02-05 09:30:39 +0000 +++ b/sql/sql_select.cc 2009-02-19 15:30:03 +0000 @@ -2373,11 +2373,12 @@ typedef struct st_sargable_param */ static bool -make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, +make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds, DYNAMIC_ARRAY *keyuse_array) { int error; TABLE *table; + TABLE_LIST *tables= tables_arg; uint i,table_count,const_count,key; table_map found_const_table_map, all_table_map, found_ref, refs; key_map const_ref, eq_part; @@ -2415,10 +2416,10 @@ make_join_statistics(JOIN *join, TABLE_L table_vector[i]=s->table=table=tables->table; table->pos_in_table_list= tables; error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); - if(error) + if (error) { - table->file->print_error(error, MYF(0)); - DBUG_RETURN(1); + table->file->print_error(error, MYF(0)); + goto error; } table->quick_keys.clear_all(); table->reginfo.join_tab=s; @@ -2503,7 +2504,7 @@ make_join_statistics(JOIN *join, TABLE_L { join->tables=0; // Don't use join->table my_message(ER_WRONG_OUTER_JOIN, ER(ER_WRONG_OUTER_JOIN), MYF(0)); - DBUG_RETURN(1); + goto error; } s->key_dependent= s->dependent; } @@ -2513,7 +2514,7 @@ make_join_statistics(JOIN *join, TABLE_L if (update_ref_and_keys(join->thd, keyuse_array, stat, join->tables, conds, join->cond_equal, ~outer_join, join->select_lex, &sargables)) - DBUG_RETURN(1); + goto error; /* Read tables with 0 or 1 rows (system tables) */ join->const_table_map= 0; @@ -2529,7 +2530,7 @@ make_join_statistics(JOIN *join, TABLE_L if ((tmp=join_read_const_table(s, p_pos))) { if (tmp > 0) - DBUG_RETURN(1); // Fatal error + goto error; // Fatal error } else found_const_table_map|= s->table->map; @@ -2601,7 +2602,7 @@ make_join_statistics(JOIN *join, TABLE_L if ((tmp= join_read_const_table(s, join->positions+const_count-1))) { if (tmp > 0) - DBUG_RETURN(1); // Fatal error + goto error; // Fatal error } else found_const_table_map|= table->map; @@ -2650,12 +2651,12 @@ make_join_statistics(JOIN *join, TABLE_L set_position(join,const_count++,s,start_keyuse); if (create_ref_for_key(join, s, start_keyuse, found_const_table_map)) - DBUG_RETURN(1); + goto error; if ((tmp=join_read_const_table(s, join->positions+const_count-1))) { if (tmp > 0) - DBUG_RETURN(1); // Fatal error + goto error; // Fatal error } else found_const_table_map|= table->map; @@ -2732,7 +2733,7 @@ make_join_statistics(JOIN *join, TABLE_L *s->on_expr_ref ? *s->on_expr_ref : conds, 1, &error); if (!select) - DBUG_RETURN(1); + goto error; records= get_quick_record_count(join->thd, select, s->table, &s->const_keys, join->row_limit); s->quick=select->quick; @@ -2778,7 +2779,7 @@ make_join_statistics(JOIN *join, TABLE_L { optimize_keyuse(join, keyuse_array); if (choose_plan(join, all_table_map & ~join->const_table_map)) - DBUG_RETURN(TRUE); + goto error; } else { @@ -2788,6 +2789,17 @@ make_join_statistics(JOIN *join, TABLE_L } /* Generate an execution plan from the found optimal join order. */ DBUG_RETURN(join->thd->killed || get_best_combination(join)); + +error: + /* + Need to clean up join_tab from TABLEs in case of error. + They won't get cleaned up by JOIN::cleanup() because JOIN::join_tab + may not be assigned yet by this function (which is building join_tab). + Dangling TABLE::reginfo.join_tab may cause part_of_refkey to choke. + */ + for (tables= tables_arg; tables; tables= tables->next_leaf) + tables->table->reginfo.join_tab= NULL; + DBUG_RETURN (1); } --===============1407118049636171450== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/joro@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: joro@stripped # target_branch: file:///home/kgeorge/mysql/work/B42419-5.0-bugteam/ # testament_sha1: 15ce048808ceda8eb5ceed9745b7e2cc6207eb49 # timestamp: 2009-02-19 17:30:41 +0200 # base_revision_id: matthias.leich@stripped\ # oznlhyq5c50ej39f # # Begin bundle IyBCYXphYXIgcmV2aXNpb24gYnVuZGxlIHY0CiMKQlpoOTFBWSZTWRSJy58ABjxfgFQxWff//3// 36C////wYA2dXdn3vd7y8tu2uq7YhB7tH3kLX3eFHXrvaWdvZq6XO4+7K9b4SSEmhkMmpjRTyaeI p5Q9E8UAMgBoBk0CSQQGQCk/TSAI1PU9Q9Mmpk09TEMQNAGQaARUzSPKND0mhoAANAAAAAACRTSZ AhKfpNT9Gmyij0nqPNSMj1GQBpsUD1GRtQRSKZNNCeqb1NlTYmk0ekekZBiBoAAAGgJIggNCAAhq TzTKn6TRNQzU9Q0M0gPUDQ11SWRV1Umn5FCNuyQFeV89Z8T8jXgNuxjNd0B9+r9dx2/6eqvm0tC5 NK8rYpZtcH2WsD8M+N7LkTmkcOCHoiPLK6k5vBtVslWcuxqTTGaTGI7X7fbQsSRNkPsyJAdoa16u qvMdGxIScOhwJSdptZCmRAUVedV6n4cPwiVoAwXkZMyF+5SLn1Pv9wd4syBcYPwyu9NnvI86P6Xm TbbbAK6A8BLm25xwW6mZTsgeU53Aywzavdrht1fM/M6PGuEEmXh8JjNzmF2He7tGNWLqWt9BaQYQ MHzO32bPX2ceYrBeqYcGC0R04b9v4MV+MMzGcWcUxZ7jrLoWtuKTsjCeQjN7hhmZgYQFaBOAXML8 tLev3UU9tq67IKkSwmhsGiLgMwcQwycy7A2QRf10pzUv3S4CVIhm2PcmSdqC+WFwe/kd/vlGx54O nOVpHOg+fS3dx010ut15Nh8ODTHWA2RAuDeKwntkxSBd3Vkos4Pc1KsYWUqFheVXsxfqucD6H0F4 igEBMMQE4pzozz+4Ys2E6AQww1btl19m3OmuFpk7votgYWK6Dhq6iT2kM6tvo7OLHsn5u2/0fdyS Ll1c95zYbs4R8OPPCflSHcmzVDaMAuAOFU2HQOKqV1vRsAe5C2sm5fB5msFvWHEFgaYSx6LTdD04 h5L6MGybPvIXStOAmBIcQIkxw4caof0KKW9c28QdvL48WG23rhwTk1+LgutCyNSCfG4rVF2kqlCp TVm7ddW+lqrkUT8/fomtxCpFKiVXmSUmo7rMwZVIi2I6rF0fgmjRR6MdAdyJuAvg5eHPXgJSYLcz Ozp9U48rcvRQ3grZAlBOn5ELrgCRM4kgVkVvJekmFMa6wnVtARUSkRC4RFhw4vAIpFeQ50c04XyB ke6pfmCmq2Sgwq2NgxY2kgJcPQqNvZgeQraYKwZN+2rovkSxY2NQ8UFUqhp5PqtqdkqZHLJDlZaP dOIsQTvi3HLZx5WEDPiAULSXcpihVMu1bMGc5OxQ8DQ0KSRcdSApGrJhOinGewxdsGWSEtduJe6S cMjWRWBQlEMUZi4rIFaTD7E4rrQkWCYSN6wJEIHM25PWtJOpK7G1LXe22agHKYFZgcbDyAKv5l3V 3z0HtzkNhtgZby8E6ZgU068Il+gHLdBXUa64eHC2xE3wKthdGavYcoOQgZUmYGtSgHIrMppzV3di +Csvtwal1zvCdaLkDunImf5CqF7CdbB4riQtWPEuPWZ3wHRu5TMTQj9Sz+LJvICZWZePiy4Hbtr8 TfAvI3FHVkt3QT4JYirKpUkFe4xEFBpB2RUDXCetw3GPxClnO0WZdzHy1XiJGyh0rQqMM9YNe92E 8oiZKY4HsQOaIZ1nEPHijpUMQWBoRLCIx6uAqwXMsFjWSHWlup1hxhMc4RXv+clAYbhqqZXs7nNX 1LI3WB93x46oi0OEzWeHNbpKeN+2GdoLKWU3gd0HC/aaatxcaScyRaZ6SIFJDkTMPccIwdrpvGCe CwwAHJIXEYTsQiPlBUMiKsLBxUN5qIjFxOHeMetdgrk/yP2LG2JLm0QvfPHEkEEVNKAohJMQZEnv nXJyKdBMFM9SYw0ZkS7AJQrWF6ZhmeaqIAQ2PQS7P0zPn9Rl9MkHa1mJHxsVyw7HaneSOGJNh5w5 wTy4Hb4h9tzwnCLVtGPwdg6Z+fY9E4L5AFPzD95+AQL2C2C5NSYNbZSczwAHSlOoPYKKi3lAT7Ra izxwqemfwC1AusJCYpCavNUCrMF3goKBWzWe4QSoIn7wkIr/Bcv2okq4luXiILjiC06SoTECYywP iT+MPTBEUPOjoBhrLG+W6FwL4lJMHg4LMIigxAgOBOGEDltsImMHyCoFehlxBqRLTAUwtNSCLhBY BhYVfgG0y4VLRhMY5hsEvCY5iDSSCkKhKSwgmNgMgMNUCRDWDATEyjTRdRcF+FoG7ENIpkHEXado mYM/uA4nk1h3GQSAI5VYJ+yji96UPehKQghfKcwEC2iHiHWPAQTW5iAvK88CYjznsPUOLTEzLh57 Tw9+aSPae4hWrzjJklpPWfqQrCgvzSvUG71r8UTXaYnczlNuOYqxi0FJ7jf31J8WUPwo0BcqaySt qYrKbhWDHnVVFYQeErljVGWNbojUuhsJfA1Dk9ql9Ss1FhpHR/QmN9rrVxHl9ekqNDrJG32iokXX M3tOVPXCmq9s22n43oZXiR7OHRlwmmZOcDI/LzuPBZjuOxaWGkdJt4/oG8aPZTO2XEfTkwa/asjv wioXzZRF4NDBIHX+N5vGRBmVgxfUdWotKCknScx9SJnBoyyGgyaDrrHSEN5jKZvKWCbiNIas82rF PoSBYBTGQrayoJutK5YjRscJpcTkcPCD29FuQzwGKOPPN2UxmYGZ1skD+NIBYaSeW05mg+qo3lZg eT57Ws7i44l5ErIdA29RSLSTbGM6DSEktWYY1+varqWuBM7jYYhFDJf01ZQUR61USs+NtQ2Uy+Hm mCKnUsDeiGim3Rmw0XVkGDk4U4DugZlV9BdaJ+z8qKlFmY+z1HObILi+oVf3jaDzKOLqMvCOkUjW 0iUpMVeuikWDmkZiKIN2ypW7Bp8cvky60JjHA3Ap+5TO9VESv3+/xOBKo7Kw6IxRxXH6B/KnINoM qZchw9d3hoXaYbWqWpvp4RhZ8u+S+7BqbHEsxBki3InqINIKF0jKZn/z2/t3Y3a51BWsX9oWPjgP 1dTmN9Y7o4JwgIbdEdQ3pyAfgwU6kY7QUlDI6DD0xFuHSEFefzKJWAjxQNy1qupQatPrniXjAGK8 mhFPAFsoWjWkGPOSIuo2AmypUZK6Qjyz7K47mmCq6/5Z07unZV78Ph7cMrhbWYQxrM8WTWkFMATT cpzPZiKWdPokF/kB6N1raHz9YNmyyCIsenOaBgMZkdiHo0WBdwdg53WWrTx8V5xNbQ54LBCwWUkV Ul2W7xgxtiWGsDhRgXnGqgsTBdL2sGWC8+BdlBoQqmL3NUo12E/YZbOkjdoYEfpVlnwxOpprItVf L0FHZNSE8HSIhz9b4jaqS4eTS9X909QFq1IpYdSy5ixeMkLSsOBsYNl7bHiEOCDVKcZCCNm9c4KE FEjiF6LYtsL5xNKJydUiwzrQeMxKJTQ681EFYkf1HALRBYPtuZbKiwbpT0qrQ2mwJnCoXIvRdvhD Yixx8yYZTMULEbasmDaZpAHcvnV4KtHHSvMF2uqOqQZ21AdCtumJgdMKSIK2ppIW8hvIi2SBjXPg cKLDZJYleS+s1oLJWk3MNneuF4VDC5MAyTC4CBoaEefnzFBgpNGjOVslnyVcqUr8gXlMwwTE7jLy 7GHql71AepU7iL1S1Gt3pu6ZVuIYLpPRwOIIyYcIZkssai5GljYbRzkbLXiKwVa40bczwyZP6lR0 saLRp7OevYt/mehR1zJlcEsUI1LUIbWLHd0EBe18qmQx46ClOjvwnMfi47py6pTh23bgnNYLQoqU UUGBuhX1OYtN5pL2ZakcuSsltKNUSRUjyutBesQ8l7TMLD6npisOh70eTZO7u7u7lnYAeEFGIqxZ 2VjchgVuIPJGZXJSIizCAqzt3BOU7CMLYy1nB7WA7iIbPWw+dAPIdzFAhyUqSmaMiCvAE3jKeFrS 7FF/PU4BiaVi8Oty7mPR6WcwVFYlnjdKOrKrGKO+FZ7Q7k9Sg4D3BIIJcmKky2kn+/fVctZunRi3 CW9BWiw2gKaqRBA2G0krFWRc9w4sYVt0leyiVdyqHh10q3ppLyM6c+z5irIHpNGDJA+jAM2ceU9a rhh/cyU1ZbexDfevyOOiCC6zmc0+QqZlPQ1NrLuhWaVNDma3vPMY5asIGrBQVpz2LBQRwVB8rNH2 q9I8DfhvreFpGEJkxMPcER0FkreNQ4d60Eh2hJbhq1gjtowNVjpE3WLKTL/i7kinChICkTlz4A== --===============1407118049636171450==--