[MDEV-8701] Crash on derived query Created: 2015-08-29  Updated: 2015-11-06  Resolved: 2015-11-05

Status: Closed
Project: MariaDB Server
Component/s: Data Manipulation - Update, Optimizer
Affects Version/s: 10.0, 10.1
Fix Version/s: 10.0.23, 10.1.9

Type: Bug Priority: Critical
Reporter: mexi Assignee: Oleksandr Byelkin
Resolution: Fixed Votes: 0
Labels: MyISAM
Environment:

CentOS Linux 6.7, Nginx and PHP 5.6.12
Linux 2.6.32-573.3.1.el6.x86_64 on x86_64
Intel(R) Core(TM) i7-3630QM CPU @ 2.40GHz, 4 cores


Sprint: 10.0.22, 10.1.9-1, 10.1.9-2

 Description   

MariaDB crashes with this query

UPDATE 
	data_entry 
SET 
	data_entry_cost = (
		(
			SELECT 
				SUM(
					data_exit_entry_quantity * data_entry_cost
				)
			FROM 
				(
					SELECT 
						data_entry_exit_id, 
						data_exit_entry_quantity, 
						data_entry_cost 
					FROM 
						data_exit_entry 
						INNER JOIN data_entry ON data_entry.data_entry_id = data_exit_entry.data_entry_id
				) AS query 
			WHERE 
				data_entry_exit_id = data_entry.data_entry_id
		)
	) 

Reference
  • Not crashing when InnoDB is used.
  • Only tested on Centos 6.7, maybe is specific to this plataform.
  • Crash seems not memory related.

TABLES

 
CREATE TABLE IF NOT EXISTS data_exit_entry (
  data_exit_entry_id int(11) NOT NULL,
  data_entry_id int(11) NOT NULL,
  data_entry_exit_id int(11) NOT NULL,
  data_exit_entry_quantity double NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
 
CREATE TABLE IF NOT EXISTS data_entry (
  data_entry_id int(11) NOT NULL,
  data_entry_cost double NOT NULL,
  data_entry_quantity double NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
 

Mysqld.log

 
Version: '10.0.21-MariaDB-wsrep'  socket: '/var/lib/mysql/mysql.sock'  port: 3306  MariaDB Server, wsrep_25.10.r4144
150829 14:31:19 [ERROR] mysqld got signal 11 ;
This could be because you hit a bug. It is also possible that this binary
or one of the libraries it was linked against is corrupt, improperly built,
or misconfigured. This error can also be caused by malfunctioning hardware.
 
To report this bug, see http://kb.askmonty.org/en/reporting-bugs
 
We will try our best to scrape up some info that will hopefully help
diagnose the problem, but since we have already crashed, 
something is definitely wrong and this may fail.
 
Server version: 10.0.21-MariaDB-wsrep
key_buffer_size=402653184
read_buffer_size=2097152
max_used_connections=1
max_threads=153
thread_count=1
It is possible that mysqld could use up to 
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = 1022970 K  bytes of memory
Hope that's ok; if not, decrease some variables in the equation.
 
Thread pointer: 0x0x7f4b9ef66008
Attempting backtrace. You can use the following information to find out
where mysqld died. If you see no messages after this, something went
terribly wrong...
stack_bottom = 0x7f4bc5c21d00 thread_stack 0x48000
/usr/sbin/mysqld(my_print_stacktrace+0x2b)[0xba5fcb]
/usr/sbin/mysqld(handle_fatal_signal+0x398)[0x749158]
/lib64/libpthread.so.0(+0xf790)[0x7f4bc5853790]
/usr/sbin/mysqld[0x604aae]
/usr/sbin/mysqld[0x604f39]
/usr/sbin/mysqld[0x60bb80]
/usr/sbin/mysqld[0x60d75d]
/usr/sbin/mysqld[0x52e9a9]
/usr/sbin/mysqld(_ZN4JOIN14optimize_innerEv+0x6e1)[0x62d9d1]
/usr/sbin/mysqld(_ZN4JOIN8optimizeEv+0x28)[0x62ff08]
/usr/sbin/mysqld(_ZN13st_select_lex31optimize_unflattened_subqueriesEb+0x88)[0x5d4b28]
/usr/sbin/mysqld(_Z12mysql_updateP3THDP10TABLE_LISTR4ListI4ItemES6_PS4_jP8st_ordery15enum_duplicatesbPySB_+0x3d5)[0x6748f5]
/usr/sbin/mysqld(_Z21mysql_execute_commandP3THD+0x3b8b)[0x5e12cb]
/usr/sbin/mysqld[0x5e5a47]
/usr/sbin/mysqld[0x5e640b]
/usr/sbin/mysqld(_Z16dispatch_command19enum_server_commandP3THDPcj+0x19fb)[0x5e834b]
/usr/sbin/mysqld(_Z10do_commandP3THD+0x28a)[0x5e8cba]
/usr/sbin/mysqld(_Z24do_handle_one_connectionP3THD+0x55b)[0x6a71bb]
/usr/sbin/mysqld(handle_one_connection+0x42)[0x6a72b2]
/lib64/libpthread.so.0(+0x7a51)[0x7f4bc584ba51]
/lib64/libc.so.6(clone+0x6d)[0x7f4bc3f659ad]
 
Trying to get some variables.
Some pointers may be invalid and cause the dump to abort.
Query (0x7f4b85421020): is an invalid pointer
Connection ID (thread ID): 43
Status: NOT_KILLED
 
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=on,exists_to_in=on
 
The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains
information that should help you find out what is causing the crash.
150829 14:31:19 mysqld_safe Number of processes running now: 0
150829 14:31:19 mysqld_safe mysqld restarted
150829 14:31:19 mysqld_safe WSREP: Running position recovery with --log_error='/var/lib/mysql/wsrep_recovery.xDqdu2' --pid-file='/var/lib/mysql/backup.xenoncloud.com-recover.pid'
150829 14:31:19 [Warning] 'THREAD_CONCURRENCY' is deprecated and will be removed in a future release.
150829 14:31:19 [Note] /usr/sbin/mysqld (mysqld 10.0.21-MariaDB-wsrep) starting as process 8119 ...
150829 14:31:22 mysqld_safe WSREP: Recovered position 00000000-0000-0000-0000-000000000000:-1
150829 14:31:22 [Warning] 'THREAD_CONCURRENCY' is deprecated and will be removed in a future release.
150829 14:31:22 [Note] /usr/sbin/mysqld (mysqld 10.0.21-MariaDB-wsrep) starting as process 8152 ...
150829 14:31:22 [Note] InnoDB: Using mutexes to ref count buffer pool pages
150829 14:31:22 [Note] InnoDB: The InnoDB memory heap is disabled
150829 14:31:22 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
150829 14:31:22 [Note] InnoDB: Memory barrier is not used
150829 14:31:22 [Note] InnoDB: Compressed tables use zlib 1.2.3
150829 14:31:22 [Note] InnoDB: Using Linux native AIO
150829 14:31:22 [Note] InnoDB: Not using CPU crc32 instructions
150829 14:31:22 [Note] InnoDB: Initializing buffer pool, size = 128.0M
150829 14:31:22 [Note] InnoDB: Completed initialization of buffer pool
150829 14:31:22 [Note] InnoDB: Highest supported file format is Barracuda.
150829 14:31:22 [Note] InnoDB: 128 rollback segment(s) are active.
150829 14:31:22 [Note] InnoDB: Waiting for purge to start
150829 14:31:22 [Note] InnoDB:  Percona XtraDB (http://www.percona.com) 5.6.25-73.1 started; log sequence number 1766038
150829 14:31:22 [Note] Plugin 'FEEDBACK' is disabled.
150829 14:31:22 [Note] Server socket created on IP: '::'.
150829 14:31:22 [Note] Event Scheduler: Loaded 0 events
150829 14:31:22 [Note] WSREP: Read nil XID from storage engines, skipping position init
150829 14:31:22 [Note] WSREP: wsrep_load(): loading provider library 'none'
150829 14:31:22 [Note] Reading of all Master_info entries succeded
150829 14:31:22 [Note] Added new Master_info '' to hash table
150829 14:31:22 [Note] /usr/sbin/mysqld: ready for connections.
Version: '10.0.21-MariaDB-wsrep'  socket: '/var/lib/mysql/mysql.sock'  port: 3306  MariaDB Server, wsrep_25.10.r4144



 Comments   
Comment by Elena Stepanova [ 2015-08-30 ]

Thanks for the report.
We have a somewhat similar known crash MDEV-6219, but that one happens with prepared statements, and besides the only tentative bugfix I could find for it does not make this one go away; so it must be different.

Stack trace from 10.0 b66455f67da9b0bbe7fb7862c23a8283d766e149

#3  <signal handler called>
#4  0x000000000062bc32 in Bitmap<64u>::merge (this=0x180, map2=...) at 10.0/sql/sql_bitmap.h:158
#5  0x00000000006be956 in add_key_field (join=0x7fcb75a75568, key_fields=0x7fcb7f5b8170, and_level=0, cond=0x7fcb75a73578, field=0x7fcb75828b60, eq_func=true, value=0x7fcb75a73618, num_values=1, usable_tables=18446744073709551615, sargables=0x7fcb7f5b82c8) at 10.0/sql/sql_select.cc:4403
#6  0x00000000006bee20 in add_key_equal_fields (join=0x7fcb75a75568, key_fields=0x7fcb7f5b8170, and_level=0, cond=0x7fcb75a73578, field_item=0x7fcb758e1e70, eq_func=true, val=0x7fcb75a73618, num_values=1, usable_tables=18446744073709551615, sargables=0x7fcb7f5b82c8) at 10.0/sql/sql_select.cc:4552
#7  0x00000000006bf948 in add_key_fields (join=0x7fcb75a75568, key_fields=0x7fcb7f5b8170, and_level=0x7fcb7f5b817c, cond=0x7fcb75a73578, usable_tables=18446744073709551615, sargables=0x7fcb7f5b82c8) at 10.0/sql/sql_select.cc:4774
#8  0x00000000006c0eb2 in update_ref_and_keys (thd=0x7fcb787d4070, keyuse=0x7fcb75a75880, join_tab=0x7fcb759f1af8, tables=1, cond=0x7fcb75a73578, normal_tables=18446744073709551615, select_lex=0x7fcb758e0b20, sargables=0x7fcb7f5b82c8) at 10.0/sql/sql_select.cc:5255
#9  0x00000000006bc18e in make_join_statistics (join=0x7fcb75a75568, tables_list=..., conds=0x7fcb75a73578, keyuse_array=0x7fcb75a75880) at 10.0/sql/sql_select.cc:3593
#10 0x00000000006b46d5 in JOIN::optimize_inner (this=0x7fcb75a75568) at 10.0/sql/sql_select.cc:1337
#11 0x00000000006b3648 in JOIN::optimize (this=0x7fcb75a75568) at 10.0/sql/sql_select.cc:1022
#12 0x0000000000673081 in st_select_lex::optimize_unflattened_subqueries (this=0x7fcb787d80c0, const_only=false) at 10.0/sql/sql_lex.cc:3504
#13 0x000000000074654d in mysql_update (thd=0x7fcb787d4070, table_list=0x7fcb758e0410, fields=..., values=..., conds=0x0, order_num=0, order=0x0, limit=18446744073709551615, handle_duplicates=DUP_ERROR, ignore=false, found_return=0x7fcb7f5b9258, updated_return=0x7fcb7f5b9250) at 10.0/sql/sql_update.cc:369
#14 0x000000000068001a in mysql_execute_command (thd=0x7fcb787d4070) at 10.0/sql/sql_parse.cc:3312
#15 0x0000000000688ade in mysql_parse (thd=0x7fcb787d4070, rawbuf=0x7fcb758e0088 "UPDATE \ndata_entry \nSET \ndata_entry_cost = (\n(\nSELECT \nSUM(\ndata_exit_entry_quantity * data_entry_cost\n)\nFROM \n(\nSELECT \ndata_entry_exit_id, \ndata_exit_entry_quantity, \ndata_entry_cost \nFROM \ndata_exi"..., length=359, parser_state=0x7fcb7f5b9600) at 10.0/sql/sql_parse.cc:6531
#16 0x000000000067b4bf in dispatch_command (command=COM_QUERY, thd=0x7fcb787d4070, packet=0x7fcb787ca071 "UPDATE \ndata_entry \nSET \ndata_entry_cost = (\n(\nSELECT \nSUM(\ndata_exit_entry_quantity * data_entry_cost\n)\nFROM \n(\nSELECT \ndata_entry_exit_id, \ndata_exit_entry_quantity, \ndata_entry_cost \nFROM \ndata_exi"..., packet_length=360) at 10.0/sql/sql_parse.cc:1308
#17 0x000000000067a7a5 in do_command (thd=0x7fcb787d4070) at 10.0/sql/sql_parse.cc:999
#18 0x0000000000798d62 in do_handle_one_connection (thd_arg=0x7fcb787d4070) at 10.0/sql/sql_connect.cc:1378
#19 0x0000000000798ac1 in handle_one_connection (arg=0x7fcb787d4070) at 10.0/sql/sql_connect.cc:1293
#20 0x0000000000cdb3eb in pfs_spawn_thread (arg=0x7fcb771845f0) at 10.0/storage/perfschema/pfs.cc:1860
#21 0x00007fcb7f1f3b50 in start_thread (arg=<optimized out>) at pthread_create.c:304
#22 0x00007fcb7d4a995d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112

Comment by Oleksandr Byelkin [ 2015-10-22 ]

I remember something with add_key_field which try to add to 0 or malformed stat[0].
(in this case it is 0)

Comment by Oleksandr Byelkin [ 2015-10-27 ]

Corresponding SELECT work perfectly and of course subselect is optimized out as having zero result.

Comment by Oleksandr Byelkin [ 2015-10-30 ]

The problem connected to forced materialization of the derived due to usage the same table for update.

Comment by Oleksandr Byelkin [ 2015-10-30 ]

work around: change derived table with view using lgorithm=temptable :

create  algorithm=temptable view v1 as SELECT data_entry_exit_id, data_exit_entry_quantity, data_entry_cost 
          FROM data_exit_entry INNER JOIN data_entry as dt ON dt.data_entry_id = data_exit_entry.data_entry_id;
 
UPDATE data_entry 
SET data_entry_cost
  = ( ( SELECT SUM(data_exit_entry_quantity * data_entry_cost)
	FROM 
        v1 AS query 
        WHERE data_entry_exit_id = data_entry.data_entry_id
      )
    );
 

Comment by Oleksandr Byelkin [ 2015-11-02 ]

comparing to variant with VIEW condition looks different:
(VIEW)WHERE:(after remove) 0x7fffe8173068 (`query`.`data_entry_exit_id` = `data_entry`.`data_entry_id`)
(DERIVED)WHERE:(original) 0x7fffe8031ba0 (NULL = `data_entry`.`data_entry_id`)
but if in the second case constant tables were read it is OK

Comment by Oleksandr Byelkin [ 2015-11-02 ]

Problem is that we first change table to temporary and call TABLE_LIST::change_refs_to_fields() and only then it resolves fields which will not be turned to temporary table.

Comment by Oleksandr Byelkin [ 2015-11-03 ]

So if resolve items to temporary table checking is_materialized_derived() it lead to big problems...

Comment by Oleksandr Byelkin [ 2015-11-03 ]

decision to materialize made in checking tables duplicates, but subquery prepared later on setup fields. For SELECT-like it is done vice versa...

Comment by Oleksandr Byelkin [ 2015-11-03 ]

revision-id: 9c86f553afe911f822efda4b2e6004d432925c30 (mariadb-10.0.22-5-g9c86f55)
parent(s): fa1438cbf4307731a54ea4137d5f7d4b744cdfbc
committer: Oleksandr Byelkin
timestamp: 2015-11-03 09:31:20 +0100
message:

MDEV-8701 Crash on derived query

Make unique table check after setup_fields of update because unique table can materialize table and we do not need field resolving after materialization.

Comment by Sergei Petrunia [ 2015-11-05 ]

Ok to push.

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