[MDEV-5037] Server crash on a JOIN on a derived table with join_cache_level > 2 Created: 2013-09-19  Updated: 2013-09-23  Resolved: 2013-09-23

Status: Closed
Project: MariaDB Server
Component/s: None
Affects Version/s: 5.5.32, 5.5.33
Fix Version/s: 5.5.34

Type: Bug Priority: Critical
Reporter: Jean Weisbuch Assignee: Sergei Petrunia
Resolution: Fixed Votes: 0
Labels: crash, join, optimizer
Environment:

Debian Squeeze amd64 5.5.32 & Debian Squeeze amd64 5.5.33
(packaged versions)


Attachments: File crash_join_cache_level.sql    

 Description   

While the join_cache_level variable is set to a value > 2, a query with a join on a derived table with a TEXT column in it could result to a server crash when LIMIT x OFFSET x is used on the derived table.

To reproduce the crash, import the attached SQL then execute the following query :

EXPLAIN SELECT 1 FROM (SELECT url, id FROM t2 LIMIT 1 OFFSET 20) derived RIGHT JOIN t1 ON t1.id = derived.id;

Here is the error log output :

mysqld: 130919 14:11:26 [ERROR] mysqld got signal 11 ;
mysqld: This could be because you hit a bug. It is also possible that this binary
mysqld: or one of the libraries it was linked against is corrupt, improperly built,
mysqld: or misconfigured. This error can also be caused by malfunctioning hardware.
mysqld: 
mysqld: To report this bug, see http://kb.askmonty.org/en/reporting-bugs
mysqld: 
mysqld: We will try our best to scrape up some info that will hopefully help
mysqld: diagnose the problem, but since we have already crashed, 
mysqld: something is definitely wrong and this may fail.
mysqld: 
mysqld: Server version: 5.5.33-MariaDB-1~squeeze
mysqld: key_buffer_size=2147483648
mysqld: read_buffer_size=2097152
mysqld: max_used_connections=1
mysqld: max_threads=252
mysqld: thread_count=1
mysqld: It is possible that mysqld could use up to 
mysqld: key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = 3133826 K  bytes of memory
mysqld: Hope that's ok; if not, decrease some variables in the equation.
mysqld: 
mysqld: Thread pointer: 0x0x7fb69bcfb5f0
mysqld: Attempting backtrace. You can use the following information to find out
mysqld: where mysqld died. If you see no messages after this, something went
mysqld: terribly wrong...
mysqld: stack_bottom = 0x7fb37714ae58 thread_stack 0x48000
mysqld: /usr/sbin/mysqld(my_print_stacktrace+0x2e)[0x7fb69035d80e]
mysqld: /usr/sbin/mysqld(handle_fatal_signal+0x4ac)[0x7fb68ff5cd7c]
mysqld: /lib/libpthread.so.0(+0xeff0)[0x7fb68f659ff0]
mysqld: /usr/sbin/mysqld(_ZN10DsMrr_impl15choose_mrr_implEjyPjS0_P9COST_VECT+0x54)[0x7fb68feff724]
mysqld: /usr/sbin/mysqld(_ZN10DsMrr_impl10dsmrr_infoEjjjjPjS0_P9COST_VECT+0xe3)[0x7fb68feffad3]
mysqld: /usr/sbin/mysqld(_Z33check_join_cache_usage_for_tablesP4JOINyj+0x694)[0x7fb68fe40ed4]
mysqld: /usr/sbin/mysqld(_ZN4JOIN8optimizeEv+0x16c7)[0x7fb68fe4f477]
mysqld: /usr/sbin/mysqld(_Z12mysql_selectP3THDPPP4ItemP10TABLE_LISTjR4ListIS1_ES2_jP8st_orderSB_S2_SB_yP13select_resultP18st_select_lex_unitP13st_select_lex+0xd2)[0x7fb68fe568e2]
mysqld: /usr/sbin/mysqld(_Z19mysql_explain_unionP3THDP18st_select_lex_unitP13select_result+0x10c)[0x7fb68fe5726c]
mysqld: /usr/sbin/mysqld(+0x37771f)[0x7fb68fdfe71f]
mysqld: /usr/sbin/mysqld(_Z21mysql_execute_commandP3THD+0x35f9)[0x7fb68fe05539]
mysqld: /usr/sbin/mysqld(_Z11mysql_parseP3THDPcjP12Parser_state+0x1cc)[0x7fb68fe080ec]
mysqld: /usr/sbin/mysqld(_Z16dispatch_command19enum_server_commandP3THDPcj+0x1792)[0x7fb68fe09892]
mysqld: /usr/sbin/mysqld(_Z24do_handle_one_connectionP3THD+0x419)[0x7fb68fece809]
mysqld: /usr/sbin/mysqld(handle_one_connection+0x51)[0x7fb68fece8c1]
mysqld: /lib/libpthread.so.0(+0x68ca)[0x7fb68f6518ca]
mysqld: /lib/libc.so.6(clone+0x6d)[0x7fb68dfd0b6d]
mysqld: 
mysqld: Trying to get some variables.
mysqld: Some pointers may be invalid and cause the dump to abort.
mysqld: Query (0x7fb69bd467f8): EXPLAIN SELECT 1 FROM (SELECT url, id FROM t2 LIMIT 1 OFFSET 20) derived RIGHT JOIN t1 ON t1.id = derived.id
mysqld: 
mysqld: Connection ID (thread ID): 1
mysqld: Status: NOT_KILLED
mysqld: 
mysqld: Optimizer switch: index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=off
mysqld: 
mysqld: The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains
mysqld: information that should help you find out what is causing the crash.
mysqld_safe: Number of processes running now: 0
mysqld_safe: mysqld restarted



 Comments   
Comment by Sergei Petrunia [ 2013-09-20 ]

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff7f8d700 (LWP 8548)]
0x0000000000742b3c in DsMrr_impl::check_cpk_scan (this=0x7fffb4ced4b8, thd=0x7fffc3fe9060, keyno=0, mrr_flags=129) at /home/psergey/dev2/5.5/sql/multi_range_read.cc:1523
Missing separate debuginfos, use: debuginfo-install zlib-1.2.5-6.fc16.x86_64
(gdb) p this
$2 = (DsMrr_impl * const) 0x7fffb4ced4b8
(gdb) print table
$4 = (TABLE *) 0x0

up
up
up

#4 0x00000000006524fe in check_join_cache_usage (tab=0x7fffb4c62800, options=4, no_jbuf_after=2, table_index=1, prev_tab=0x7fffb4c624e0) at /home/psergey/dev2/5.5/sql/sql_select.cc:9798

(gdb) list
9793 flags= HA_MRR_NO_NULL_ENDPOINTS | HA_MRR_SINGLE_POINT;
9794 if (tab->table->covering_keys.is_set(tab->ref.key))
9795 flags|= HA_MRR_INDEX_ONLY;
9796 rows= tab->table->file->multi_range_read_info(tab->ref.key, 10, 20,
9797 tab->ref.key_parts,
9798 &bufsz, &flags, &cost);
9799 }

(gdb) p tab->table
$18 = (TABLE *) 0x7fffb4c9d078

(gdb) p tab->table->alias.Ptr
$22 = 0x7fffb4c46c78 "derived"

Comment by Sergei Petrunia [ 2013-09-20 ]

(gdb) p tab->table->file->table
$25 = (TABLE *) 0x0
(gdb) p tab->table
$27 = (TABLE *) 0x7fffb4c9d078

So, table->file->multi_range_read_info() is called on a temporary table. The temporary table has handler::table==NULL. This causes a crash in DS-MRR implementation (DS-MRR needs various information from TABLE object, e.g. it needs information about whether a clustered key is present)

Comment by Sergei Petrunia [ 2013-09-20 ]

For regular tables, handler::table is assigned here:

#0 handler::ha_open
#1 0x00000000006cfd4b in open_table_from_share
#2 0x00000000005af7ad in open_table
#3 0x00000000005b1b91 in open_and_process_table
#4 0x00000000005b2b8c in open_tables
...

As for the temporary table, it is created by the

create_tmp_table( .... do_not_open= true, ...)

call. When do_not_open==true, the table is created but not opened.

handler::handler() accepts a TABLE_SHARE argument. A temporary table will
receive a pointer to valid TABLE_SHARE object.

handler::ha_open will be called for the temporary table from here:

#0 handler::ha_open
#1 0x00000000006601fe in open_tmp_table
#2 0x00000000005e71ea in mysql_derived_create
#3 0x00000000005e60c2 in mysql_handle_single_derived
#4 0x0000000000653fcb in st_join_table::preread_init
#5 0x0000000000662185 in sub_select
#6 0x00000000006629fd in evaluate_join_record
#7 0x0000000000662336 in sub_select
#8 0x0000000000661be7 in do_select

Comment by Sergei Petrunia [ 2013-09-20 ]

Directions for the solution (not sure if all of them are actually feasible):

1. Make handler::table be assigned in hander::handler(), not when the table is
opened.

2. Make DsMrr_impl::dsmrr_info() only access the TABLE_SHARE, not TABLE object.

3. Disable DS-MRR for temporary tables (at least, for those that don't have a
TABLE object yet. This way, tables created with CREATE TEMPORARY TABLE will
still work).

Comment by Sergei Petrunia [ 2013-09-20 ]

The patch is here: http://lists.askmonty.org/pipermail/commits/2013-September/005411.html

Comment by Sergei Petrunia [ 2013-09-23 ]

Fix pushed.

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