[MDEV-6484] Assertion `tab->ref.use_count' failed on query with joins, constant table, multi-part key Created: 2014-07-25  Updated: 2020-08-27  Resolved: 2014-10-14

Status: Closed
Project: MariaDB Server
Component/s: Optimizer
Affects Version/s: 5.3.12, 5.5.38, 10.0.12
Fix Version/s: 5.5.41

Type: Bug Priority: Major
Reporter: Elena Stepanova Assignee: Sergei Petrunia
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
relates to MDEV-23596 Assertion `tab->ref.use_count' failed... Closed

 Description   

mysqld: 5.5/sql/sql_select.cc:17536: void join_read_key_unlock_row(st_join_table*): Assertion `tab->ref.use_count' failed.
140725  1:26:23 [ERROR] mysqld got signal 6 ;
 
#6  0x00007fdb57762621 in *__GI___assert_fail (assertion=0xd98f8b "tab->ref.use_count", file=<optimized out>, line=17536, function=0xd9a660 "void join_read_key_unlock_row(st_join_table*)") at assert.c:81
#7  0x000000000068b280 in join_read_key_unlock_row (tab=0x7fdb521b8fe8) at 5.5/sql/sql_select.cc:17536
#8  0x000000000068a224 in evaluate_join_record (join=0x7fdb52181600, join_tab=0x7fdb521b8fe8, error=0) at 5.5/sql/sql_select.cc:17089
#9  0x0000000000689a1d in sub_select (join=0x7fdb52181600, join_tab=0x7fdb521b8fe8, end_of_records=false) at 5.5/sql/sql_select.cc:16839
#10 0x000000000068927b in do_select (join=0x7fdb52181600, fields=0x7fdb521819c0, table=0x0, procedure=0x0) at 5.5/sql/sql_select.cc:16501
#11 0x00000000006681af in JOIN::exec (this=0x7fdb52181600) at 5.5/sql/sql_select.cc:2873
#12 0x00000000006689b9 in mysql_select (thd=0x7fdb55f49060, rref_pointer_array=0x7fdb55f4ccc8, tables=0x7fdb52148358, wild_num=0, fields=..., conds=0x7fdb52181280, og_num=1, order=0x0, group=0x7fdb521814f8, having=0x0, proc_param=0x0, select_options=2147748608, result=0x7fdb521815e0, unit=0x7fdb55f4c380, select_lex=0x7fdb55f4ca58) at 5.5/sql/sql_select.cc:3094
#13 0x000000000065f489 in handle_select (thd=0x7fdb55f49060, lex=0x7fdb55f4c2d0, result=0x7fdb521815e0, setup_tables_done_option=0) at 5.5/sql/sql_select.cc:319
#14 0x0000000000638a9f in execute_sqlcom_select (thd=0x7fdb55f49060, all_tables=0x7fdb52148358) at 5.5/sql/sql_parse.cc:4688
#15 0x0000000000631c81 in mysql_execute_command (thd=0x7fdb55f49060) at 5.5/sql/sql_parse.cc:2233
#16 0x000000000063b1ae in mysql_parse (thd=0x7fdb55f49060, rawbuf=0x7fdb52148078 "SELECT i2 FROM t1 AS t1a STRAIGHT_JOIN ( t2 INNER JOIN t1 AS t1b ON (t1b.c1 = c2) ) ON (t1b.i1 = pk2 ) \nWHERE t1a.c1 = c2 GROUP BY i2", length=133, parser_state=0x7fdb52bb5630) at 5.5/sql/sql_parse.cc:5799
#17 0x000000000062f1f9 in dispatch_command (command=COM_QUERY, thd=0x7fdb55f49060, packet=0x7fdb532fa061 "", packet_length=133) at 5.5/sql/sql_parse.cc:1079
#18 0x000000000062e385 in do_command (thd=0x7fdb55f49060) at 5.5/sql/sql_parse.cc:793
#19 0x000000000072ffea in do_handle_one_connection (thd_arg=0x7fdb55f49060) at 5.5/sql/sql_connect.cc:1266
#20 0x000000000072faa9 in handle_one_connection (arg=0x7fdb55f49060) at 5.5/sql/sql_connect.cc:1181
#21 0x0000000000b64ee9 in pfs_spawn_thread (arg=0x7fdb53ffa8e0) at 5.5/storage/perfschema/pfs.cc:1015
#22 0x00007fdb58cc2b50 in start_thread (arg=<optimized out>) at pthread_create.c:304
#23 0x00007fdb57811a7d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112

Stack trace from:

revision-id: jplindst@mariadb.org-20140724113509-r06tvyhubva3gfgn
revno: 4237
branch-nick: 5.5

Test case:

 
CREATE TABLE t1 (i1 INT, c1 VARCHAR(1)) ENGINE=MyISAM;
INSERT INTO t1 VALUES (6,'b');
 
CREATE TABLE t2 (pk2 INT, i2 INT, c2 VARCHAR(1), PRIMARY KEY(pk2), KEY(pk2,i2)) ENGINE=MyISAM;
INSERT INTO t2 VALUES (1,2,'s'),(2,4,'r'),(3,8,'m'),(4,4,'b'),(5,4,'x'),(6,7,'g'),(7,4,'p');
 
SELECT i2 FROM t1 AS t1a STRAIGHT_JOIN ( t2 INNER JOIN t1 AS t1b ON (t1b.c1 = c2) ) ON (t1b.i1 = pk2 ) 
WHERE t1a.c1 = c2 GROUP BY i2;

EXPLAIN:

EXPLAIN EXTENDED
SELECT i2 FROM t1 AS t1a STRAIGHT_JOIN ( t2 INNER JOIN t1 AS t1b ON (t1b.c1 = c2) ) ON (t1b.i1 = pk2 ) 
WHERE t1a.c1 = c2 GROUP BY i2;
id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
1	SIMPLE	t1a	system	NULL	NULL	NULL	NULL	1	100.00	
1	SIMPLE	t1b	system	NULL	NULL	NULL	NULL	1	100.00	
1	SIMPLE	t2	ref	PRIMARY,pk2	pk2	4	const	1	100.00	Using where
Warnings:
Note	1003	select `test`.`t2`.`i2` AS `i2` from `test`.`t2` join `test`.`t1` `t1b` where ((`test`.`t2`.`c2` = 'b') and (`test`.`t2`.`pk2` = 6)) group by `test`.`t2`.`i2`



 Comments   
Comment by Sergei Petrunia [ 2014-10-14 ]

So, the assert is in join_read_key_unlock_row(), and it fails because tab->ref.use_count==0.

We read only one record from the table, and the record retrieval code doesn't set use_count.

Looking at the code, it seems that counting in tab->ref.use_count is only used for EQ_REF access. The query uses REF (see the EXPLAIN).

Comment by Sergei Petrunia [ 2014-10-14 ]

Initially, the query choses EQ_REF access.. then, test_if_skip_sort_order code changes the index and switches to REF. (Which is stupid. EQ_REF is guaranteed to read one row. A record set with one row is by definition already ordered. Why switch to a less-efficient index? I assume we can still live with this choice because it is very rare that the first table in the query uses EQ_REF, and it wasn't made to be a constant table).

so, it switches index to ref but doesnt' change join_tab->read_record.unlock_row.

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