Bug #38294 Backup: server crash if no database set when issuing backup
Submitted: 22 Jul 2008 19:34 Modified: 3 Apr 2009 3:09
Reporter: Hema Sridharan Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Backup Severity:S2 (Serious)
Version:mysql-6.0-backup OS:Linux
Assigned to: Jørgen Løland CPU Architecture:Any

[22 Jul 2008 19:34] Hema Sridharan
Description:
1) I create database and tables in the database.
2) I create function defined using order by clause and sum function operator
3) I backup the database and it results in server crash.
This crash is seen for Myisam and Innodb engines. Use of falcon engine does not result in crash.

SET NAMES utf8;
SET CHARACTER_SET_SERVER=utf8;
CREATE DATABASE sp CHARACTER SET utf8;
CREATE TABLE sp.t1( special_character char(16) not null default '', data int not null);
INSERT INTO sp.t1 VALUES('&&&', 1),('***',10),('$$$',40),('@@@',100);
CREATE FUNCTION sp.f1() RETURNS INT
RETURN (SELECT data FROM sp.t1 WHERE data <= (SELECT SUM(data) FROM sp.t1) ORDER BY data LIMIT 1);
BACKUP DATABASE sp to 'sp.bak';

How to repeat:
mysql> SET NAMES utf8;
Query OK, 0 rows affected (0.00 sec)

mysql> SET CHARACTER_SET_SERVER=utf8;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE DATABASE sp CHARACTER SET utf8;
Query OK, 1 row affected (0.01 sec)

mysql> CREATE TABLE sp.t1( special_character char(16) not null default '', data int not null);
Query OK, 0 rows affected (0.01 sec)

mysql> INSERT INTO sp.t1 VALUES('&&&', 1),('***',10),('$$$',40),('@@@',100);
CREATE FUNCTION sp.f1() RETURNS INT
RETURN (SELECT data FROM sp.t1 WHERE data <= (SELECT SUM(data) FROM sp.t1) ORDER BY data LIMIT 1);
Query OK, 4 rows affected (0.00 sec)
Records: 4  Duplicates: 0  Warnings: 0

mysql> CREATE FUNCTION sp.f1() RETURNS INT
    -> RETURN (SELECT data FROM sp.t1 WHERE data <= (SELECT SUM(data) FROM sp.t1) ORDER BY data LIMIT 1);
Query OK, 0 rows affected (0.01 sec)

mysql> BACKUP DATABASE sp to 'sp.bak';
ERROR 2013 (HY000): Lost connection to MySQL server during query
===============================================================================

STACK TRACE
===========

080722 21:54:14 [Note] Backup: Starting backup process
080722 21:54:14 [Note] Backup: Backing up selected databases
mysqld: item_cmpfunc.cc:3816: virtual longlong Item_func_in::val_int(): Assertion `fixed == 1' failed.
/home/hs221732/backupjul21p/libexec/mysqld(my_print_stacktrace+0x32)[0xd41e5a]
/home/hs221732/backupjul21p/libexec/mysqld(handle_segfault+0x2a6)[0x6ff692]
/lib64/libpthread.so.0[0x31d720de60]
/lib64/libc.so.6(gsignal+0x35)[0x31d6630045]
/lib64/libc.so.6(abort+0x110)[0x31d6631ae0]
/lib64/libc.so.6(__assert_fail+0xf6)[0x31d6629756]
/home/hs221732/backupjul21p/libexec/mysqld(_ZN12Item_func_in7val_intEv+0x31)[0x6716b5]
/home/hs221732/backupjul21p/libexec/mysqld(_Z14get_all_tablesP3THDP10TABLE_LISTP4Item+0x67a)[0x885aae]
/home/hs221732/backupjul21p/libexec/mysqld[0x9005d3]
/home/hs221732/backupjul21p/libexec/mysqld(_ZN3obs25InformationSchemaIterator16prepare_is_tableEP3THDPP8st_tablePP7handlerPPj18enum_schema_tables4ListI19st_mysql_lex_stringE+0xb1)[0x900701]
/home/hs221732/backupjul21p/libexec/mysqld(_ZN3obs18create_is_iteratorINS_15DbViewsIteratorEEEPT_P3THD18enum_schema_tablesPK6String+0xc8)[0x9027c0]
/home/hs221732/backupjul21p/libexec/mysqld(_ZN3obs12get_db_viewsEP3THDPK6String+0x22)[0x90088a]
/home/hs221732/backupjul21p/libexec/mysqld(_ZN11Backup_info12add_db_itemsERN6backup10Image_info2DbE+0x353)[0xdf1191]
/home/hs221732/backupjul21p/libexec/mysqld(_ZN11Backup_info7add_dbsER4ListI19st_mysql_lex_stringE+0x15e)[0xdf16de]
/home/hs221732/backupjul21p/libexec/mysqld(_Z22execute_backup_commandP3THDP6st_lex+0x272)[0xddb9ba]
/home/hs221732/backupjul21p/libexec/mysqld(_Z21mysql_execute_commandP3THD+0x96a)[0x71118e]
/home/hs221732/backupjul21p/libexec/mysqld(_Z11mysql_parseP3THDPKcjPS2_+0x275)[0x71966b]
/home/hs221732/backupjul21p/libexec/mysqld(_Z16dispatch_command19enum_server_commandP3THDPcj+0x9c5)[0x71a1c1]
/home/hs221732/backupjul21p/libexec/mysqld(_Z10do_commandP3THD+0x220)[0x71b670]
/home/hs221732/backupjul21p/libexec/mysqld(handle_one_connection+0x11a)[0x708314]
/lib64/libpthread.so.0[0x31d72062e7]
/lib64/libc.so.6(clone+0x6d)[0x31d66ce3bd]
080722 21:54:14 - mysqld got signal 6 ;
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.
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.

key_buffer_size=1048576
read_buffer_size=131072
max_used_connections=1
max_threads=151
thread_count=1
connection_count=1
It is possible that mysqld could use up to
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = 60646 K
bytes of memory
Hope that's ok; if not, decrease some variables in the equation.

thd: 0x3e521d8
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 = 0x419160f0 thread_stack 0x40000
Trying to get some variables.
Some pointers may be invalid and cause the dump to abort...
thd->query at 0x3ebe8e0 = BACKUP DATABASE sp to 'sp.bak'
thd->thread_id=1
thd->killed=NOT_KILLED
[19 Nov 2008 9:55] Jørgen Løland
The problem seemingly occurs with any function if the database to backup is not the active database. Views and procedures do not have the same problem.

'use db' before calling backup is a workaround. Of course, this workaround is not satisfactory.

A simpler test script that also reproduces the problem:

CREATE DATABASE db;
CREATE FUNCTION db.f1() RETURNS INT RETURN (SELECT 1);
# USE db; <- removes crash
BACKUP DATABASE db TO 'db.bak';
# crash

Before the crash, an error is reported: "No database selected". The error is the direct reason for the crash because 

item_func.cc:fix_fields@line201

  fix_length_and_dec();
  if (thd->is_error()) // An error inside fix_length_and_dec occured
    return TRUE;
  fixed= 1;

However, the assumption in the comment is not correct. The error occurred earlier. Hence, the item is not "fixed" as it should be, resulting in a crash when this later happens:

item_cmpfunc.cc@line3924
bool
Item_cond::fix_fields(THD *thd, Item **ref)
{
  DBUG_ASSERT(fixed == 0); //<- CRASH

Stack trace when thd->set_error_status is called reveals this:

#0  Diagnostics_area::set_error_status (this=0x9708f38, thd=0x9708138, 
    sql_errno_arg=1046, message_arg=0x96acdbf "No database selected")
    at sql_class.cc:488
#1  0x0833548b in my_message_sql (error=1046, 
    str=0x96acdbf "No database selected", MyFlags=0) at mysqld.cc:3054
#2  0x08983af5 in my_message (error=1046, 
    str=0x96acdbf "No database selected", MyFlags=158368056) at my_error.c:161
#3  0x082535ee in THD::copy_db_to (this=0x9708138, p_db=0xaf8a8200, 
    p_db_length=0xaf8a8204) at sql_class.h:2374
#4  0x0824e237 in LEX::copy_db_to (this=0xaf8a9024, p_db=0xaf8a8200, 
    p_db_length=0xaf8a8204) at sql_lex.cc:2462
#5  0x0836879f in MYSQLparse (yythd=0x9708138) at sql_yacc.yy:2202
#6  0x08341d89 in parse_sql (thd=0x9708138, parser_state=0xaf8a8e8c, 
    creation_ctx=0x978c410) at sql_parse.cc:7693
#7  0x0851b66c in sp_compile (thd=0x9708138, defstr=0xaf8a8fdc, sql_mode=0, 
    creation_ctx=0x978c410) at sp.cc:547
#8  0x0851deef in sp_load_for_information_schema (thd=0x9708138, 
    proc_table=0x976b2c0, db=0xaf8aa0a0, name=0xaf8aa08c, sql_mode=0, type=1, 
    returns=0x97b8348 "int(11)", params=0x8b23baf "", free_sp_head=0xaf8aa0e3)
    at sp.cc:2021
#9  0x084bb53f in store_schema_proc (thd=0x9708138, table=0x978a5b0, 
    proc_table=0x976b2c0, wild=0x0, full_access=true, 
    sp_user=0xaf8aa7e6 "root@localhost") at sql_show.cc:4410
#10 0x084bcec2 in fill_schema_proc (thd=0x9708138, tables=0xaf8aa8b0, 
    cond=0x9797730) at sql_show.cc:4532
#11 0x085479f4 in open_schema_table (thd=0x9708138, st=0x8c51c30, 
    db_list=0xaf8aab28) at si_objects.cc:327
#12 0x08547ab7 in obs::InformationSchemaIterator::prepare_is_table (
    thd=0x9708138, is_table=0xaf8aab50, ha=0xaf8aab4c, 
    orig_columns=0xaf8aab48, is_table_idx=SCH_PROCEDURES, db_list=@0xaf8aab28)
    at si_objects.cc:1276
#13 0x0854bae9 in obs::create_is_iterator<obs::DbStoredProcIterator> (
    thd=0x9708138, is_table_idx=SCH_PROCEDURES, db_name=0x97659b0)
    at si_objects.cc:1836
#14 0x08547d24 in obs::get_db_stored_procedures (thd=0x9708138, 
    db_name=0x97659b0) at si_objects.cc:1899
#15 0x08a5ef14 in Backup_info::add_db_items (this=0x97883e0, db=@0x97659a8)
    at backup_info.cc:751
#16 0x08a5f6b1 in Backup_info::add_dbs (this=0x97883e0, dbs=@0x97099d0)
    at backup_info.cc:575
[19 Nov 2008 13:26] Jørgen Løland
Replacing BACKUP with SHOW CREATE FUNCTION does not crash the server even if database is not set:

SHOW CREATE FUNCTION db.f1; <- works

When SHOW CREATE is executed, MySQL internally set 'db' as active database, performs SHOW CREATE and then resets active database to \0. 

(gdb) watch thd->db
-------------------

SET ACTIVE DATABASE

Old value = 0x0
New value = 0xb282a78 "db"
THD::reset_db (this=0xb241dc0, new_db=0xb282a78 "db", new_db_len=2)
    at sql_class.h:2363

stack trace:
#0  THD::reset_db (this=0xb241dc0, new_db=0xb282a78 "db", new_db_len=2)
    at sql_class.h:2363
#1  0x0843d65e in mysql_change_db_impl (thd=0xb241dc0, new_db_name=0xaf97cdf0, 
    new_db_access=233258047, new_db_charset=0x8bc9ce0) at sql_db.cc:1384
#2  0x08440593 in mysql_change_db (thd=0xb241dc0, new_db_name=0xb298118, 
    force_switch=true) at sql_db.cc:1671
#3  0x08440619 in mysql_opt_change_db (thd=0xb241dc0, new_db_name=0xb298118, 
    saved_db_name=0xaf97cedc, force_switch=true, cur_db_changed=0xaf97ceef)
    at sql_db.cc:1710
#4  0x084c9a1e in db_load_routine (thd=0xb241dc0, type=1, name=0xb298118, 
    sphp=0xaf97dbb4, sql_mode=0, params=0x89e7b4f "", 
    returns=0xb2983a0 "int(11)", body=0xb2983a8 "RETURN (SELECT 1)", 
    chistics=@0xaf97da5c, definer=0xb2983c0 "root@localhost", 
    created=20081119160355, modified=20081119160355, creation_ctx=0xb298418)
    at sp.cc:624
#5  0x084cc57a in db_find_routine (thd=0xb241dc0, type=1, name=0xb298118, 
    sphp=0xaf97dbb4) at sp.cc:478
#6  0x084cd18d in sp_find_routine (thd=0xb241dc0, type=1, name=0xb298118, 
    cp=0xb242eac, cache_only=false) at sp.cc:1293
#7  0x084cd5a4 in sp_show_create_routine (thd=0xb241dc0, type=1, 
    name=0xb298118) at sp.cc:1185
#8  0x08302ac7 in mysql_execute_command (thd=0xb241dc0) at sql_parse.cc:4435

RESET ACTIVE DATABASE

Old value = 0x9c2b8e0 "\217\217\217h4z\025\025("
New value = 0x0
THD::set_db (this=0x9c6adc0, new_db=0x0, new_db_len=0) at sql_class.h:2345
2345        db_length= db ? new_db_len : 0;

#0  THD::set_db (this=0x9c6adc0, new_db=0x0, new_db_len=0) at sql_class.h:2345
#1  0x0843d5ef in mysql_change_db_impl (thd=0x9c6adc0, new_db_name=0x0, 
    new_db_access=0, new_db_charset=0x8bc9ce0) at sql_db.cc:1363
#2  0x0844010e in mysql_change_db (thd=0x9c6adc0, new_db_name=0xaf9daedc, 
    force_switch=true) at sql_db.cc:1547
#3  0x084c9a92 in db_load_routine (thd=0x9c6adc0, type=1, name=0x9cc0d78, 
    sphp=0xaf9dbbb4, sql_mode=0, params=0x89e7b4f "", 
    returns=0x9cc1000 "int(11)", body=0x9cc1008 "RETURN (SELECT 1)", 
    chistics=@0xaf9dba5c, definer=0x9cc1020 "root@localhost", 
    created=20081119162519, modified=20081119162519, creation_ctx=0x9cc1078)
    at sp.cc:639
<then same stack trace as above>
[19 Nov 2008 13:57] Jørgen Løland
Suggested fix:
--------------
In si_objects.cc: Set active database (thd->db), get functions, then reset active database.
[19 Nov 2008 13:59] Jørgen Løland
A new service interface for backup is underway - see WL#4264. Will wait for the new interface before continuing to fix this bug.
[16 Dec 2008 12:22] Jørgen Løland
The new si_object has now been pushed. The script no longer crash the server, but backup is still not able to handle the function:

(same simple database as created above)
mysql> BACKUP DATABASE db TO 'db.bak';
ERROR 1716 (HY000): Can't enumerate stored routines in database `db`

The problem is that no database is in use. si_objects creates the following SQL to get the function:

"SELECT 'db', routine_name FROM INFORMATION_SCHEMA.ROUTINES WHERE routine_schema = 'db' AND routine_type = 'PROCEDURE'"

When running this query in a normal client, you get:

mysql> SELECT 'db', routine_name FROM INFORMATION_SCHEMA.ROUTINES WHERE routine_schema = 'db' AND routine_type = 'PROCEDURE';
ERROR 1046 (3D000): No database selected

Strangely, using *any* database makes both the select and the backup statement work, e.g.:

mysql> use test
Database changed
mysql> BACKUP DATABASE db TO 'db.bak';
+-----------+
| backup_id |
+-----------+
| 272       | 
+-----------+
1 row in set (3.41 sec)
[16 Dec 2008 13:07] Jørgen Løland
This bug is caused by bug#38916
[30 Jan 2009 9:07] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/64591

2756 Jorgen Loland	2009-01-30
      Bug#38294 - Backup: server crash if no database set when issuing backup.
      
      Previously, backup crashed when called without setting a database first ('use db'); making any database the active database was a workaround. The reason for this was bug 38916 - "Select from I_S.ROUTINES results in "No database selected" error". 
      
      This patch contains a regression test for the originally reported problem.
[4 Feb 2009 13:40] Chuck Bell
Patch approved.
[5 Feb 2009 10:10] Rafal Somla
Good to push after updating test as agreed on IRC.
[6 Feb 2009 8:38] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/65437

2761 Jorgen Loland	2009-02-06
      Bug#38294 - Backup: server crash if no database set when issuing backup.
            
      Previously, backup crashed when called without setting a database first ('use db');
      making any database the active database was a workaround. The reason for this was bug
      38916 - "Select from I_S.ROUTINES results in "No database selected" error". 
      
      This patch contains a regression test for the originally reported problem.
[26 Mar 2009 12:34] Bugs System
Pushed into 6.0.11-alpha (revid:alik@sun.com-20090326121822-pt84kzxxayzho4mn) (version source revid:rafal.somla@sun.com-20090206175321-gekdgu0f60n6oh9p) (merge vers: 6.0.10-alpha) (pib:6)
[3 Apr 2009 3:09] Paul DuBois
Noted in 6.0.11 changelog.

BACKUP DATABASE crashed if there was no default database.