Bug #45365 Subquery keeps the mysqld server in preparing phase
Submitted: 8 Jun 2009 8:40 Modified: 24 Nov 2011 13:20
Reporter: Alexander Yu Email Updates:
Status: Can't repeat Impact on me:
None 
Category:MySQL Cluster: Cluster (NDB) storage engine Severity:S3 (Non-critical)
Version:mysql-5.1-telco-7.0 OS:Any
Assigned to: Martin Skold CPU Architecture:Any
Tags: 5.1.30-ndb-6.3.20 & 5.1.34-ndb-7.07, MySQL, MySQL Cluster, subquery

[8 Jun 2009 8:40] Alexander Yu
Description:
This particular subquery: 
select count(*) from user_rights where user_rights.uid in ( select reg_user.mobile from reg_user where status = '0' )

hangs the mysqld server, i.e., it gets "stuck" in preparing phase. This subquery only gets stuck when the storage engine is NDB.

mysql> explain select count(*) from user_rights where user_rights.uid in ( select reg_user.mobile from reg_user where status = '0' );
+----+--------------------+-------------+----------------+-----------------------------+---------+---------+------+------+-------------+
| id | select_type        | table       | type           | possible_keys               | key     | key_len | ref  | rows | Extra       |
+----+--------------------+-------------+----------------+-----------------------------+---------+---------+------+------+-------------+
|  1 | PRIMARY            | user_rights | ALL            | NULL                        | NULL    | NULL    | NULL |  799 | Using where | 
|  2 | DEPENDENT SUBQUERY | reg_user    | index_subquery | Index_1,reg_user_status_idx | Index_1 | 153     | func |    1 | Using where | 
+----+--------------------+-------------+----------------+-----------------------------+---------+---------+------+------+-------------+
2 rows in set (0.00 sec)

mysql> mysql> show processlist;
+----+-------------+-----------+-------+---------+------+-----------------------------------+------------------------------------------------------------------------------------------------------+
| Id | User        | Host      | db    | Command | Time | State                             | Info                                                                                                 |
+----+-------------+-----------+-------+---------+------+-----------------------------------+------------------------------------------------------------------------------------------------------+
|  1 | system user |           |       | Daemon  |    0 | Waiting for event from ndbcluster | NULL                                                                                                 | 
|  2 | root        | localhost | green | Query   |  226 | preparing                         | select count(*) from user_rights where user_rights.uid in ( select reg_user.mobile from reg_user whe | 
| 19 | root        | localhost | NULL  | Query   |    0 | NULL                              | show processlist                                                                                     | 
+----+-------------+-----------+-------+---------+------+-----------------------------------+------------------------------------------------------------------------------------------------------+
3 rows in set (0.00 sec)

It's been verified on 5.1.30-ndb-6.3.20 and 5.1.34-ndb-7.07 with the same result.

A workaround is using a join: 

mysql> select count(*) from user_rights left join reg_user on user_rights.uid = reg_user.mobile where reg_user.status = '0';
+----------+
| count(*) |
+----------+
|      527 | 
+----------+
1 row in set (0.02 sec)

How to repeat:
Use attached schema and data dump file. You probably will get: Error 783 - "Too many schema operations" when loading/creating the schema. Do the index creation for the 'reg_user' table separately using alter table.

mysql> select count(*) from user_rights where user_rights.uid in ( select reg_user.mobile from reg_user where status = '0' );

Expected Result: 527

A workaround is using a join: 

mysql> select count(*) from user_rights left join reg_user on user_rights.uid = reg_user.mobile where reg_user.status = '0';
+----------+
| count(*) |
+----------+
|      527 | 
+----------+
1 row in set (0.02 sec)

Suggested fix:
Make the subquery not hang the mysqld server.
[8 Jun 2009 17:33] Sveta Smirnova
Thank you for the report.

Verified as described.
[5 Mar 2010 13:01] Jonas Oreland
looks similar to the delete+left outer join you fixed quite recently
[24 Nov 2011 13:20] Martin Skold
This bug no longer is possible to reproduce in 5.1.56_ndb-6.3.48 and
5.1.56-ndb-7.0.29