Bug #30473 2 "rename database" can crash (assertation) mysql
Submitted: 17 Aug 2007 13:26 Modified: 21 Nov 2007 19:51
Reporter: Martin Friebe (Gold Quality Contributor) (OCA) Email Updates:
Status: Can't repeat Impact on me:
None 
Category:MySQL Server: DDL Severity:S3 (Non-critical)
Version:5.1.21 OS:FreeBSD (32-bit)
Assigned to: CPU Architecture:Any
Tags: rename database assert

[17 Aug 2007 13:26] Martin Friebe
Description:
see testcase below.

if two "rename database" statements waiting to rename the same db, the server will crash with:

safe_mutex: Got error: 22 (0) when doing a safe_mutex_wait at sql_base.cc, line 1937
070817 14:04:26 - mysqld got signal 6;

How to repeat:
--disable warnings
drop database if exists d1;
drop database if exists d2;
--enable warnings

create database d1;
use d1;
create table t1 (a int);
lock table t1 write;

connect (con1,localhost,root,,);
connection con1;

send rename database d1 to d2;

connect (con2,localhost,root,,);
connection con2;

rename database d1 to d2;

Suggested fix:
-
[20 Aug 2007 21:05] Martin Friebe
ok, I ve done some research.
<quote>
The pthread_cond_wait() and pthread_cond_timedwait() functions may fail if:
[EINVAL]    The value specified by cond, mutex, or abstime is invalid. 
[EINVAL]    Different mutexes were supplied for concurrent pthread_cond_wait() or pthread_cond_timedwait() operations on the same condition variable. 
[EINVAL]    The mutex was not owned by the current thread at the time of the call. 
</quote>

in the given example pthread condition wait is called by the first "rename" thread from 
#1  0x0812fdbc in wait_for_condition (thd=0x87a1000, mutex=0x85c50bc, 
    cond=0x85c527c) at sql_base.cc:1937
#2  0x080eac53 in wait_for_locked_table_names (thd=0x87a1000, 
    table_list=0x87b5100) at lock.cc:1083
#3  0x080eacf1 in lock_table_names (thd=0x87a1000, table_list=0x87b5100)
    at lock.cc:1125
#4  0x080ead2b in lock_table_names_exclusively (thd=0x87a1000, 
    table_list=0x87b5100) at lock.cc:1155
#5  0x081e27ff in mysql_rename_tables (thd=0x87a1000, table_list=0x87b5100, 
    silent=true) at sql_rename.cc:135

with COND_refresh and LOCK_open

the 2nd rename thread calls it from 
#1  0x0812fdbc in wait_for_condition (thd=0x87b2000, mutex=0x85c9174, 
    cond=0x85c527c) at sql_base.cc:1937
#2  0x081d414b in lock_databases (thd=0x87b2000, db1=0x87cc090 "d1", 
    length1=2, db2=0x87cc098 "d2", length2=2) at sql_db.cc:1537
#3  0x081d4327 in mysql_rename_db (thd=0x87b2000, old_db=0x87cc0a0, 
    new_db=0x87cc0b0) at sql_db.cc:1627

with COND_refresh and LOCK_lock_db

so COND_refresh is used to wait for 2 different mutexes, and pthread_mutex_lock fails.

The error only happens for a debug server, as it needs to be compilled with SAFE_MUTEX.

I havent tested it on a none debug server, but looking at the code I would expect the 2nd thread to eat all available CPU time in the loop at the start of lock_databases (sql_db.cc)
[27 Aug 2007 11:15] Sveta Smirnova
Thank you for the report.

I can not repeat described behaviour neither on Linux, nor on 64-bit FreeBSD.

Please indicate accurate version of your operating system and compiler (uname -a and gcc --version)
[29 Aug 2007 10:22] Martin Friebe
I have tested on 3 versions of freebsd:
All three stop on the same assertation in safe_mutex (so it must be a debug build)

1)
FreeBSD  6.2-RELEASE FreeBSD 6.2-RELEASE #0: Fri Jan 12 10:40:27 UTC 2007     root@dessler.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC  i386

gcc (GCC) 3.4.6 [FreeBSD] 20060305
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

build from latest bk source with:
 ./configure --with-debug --with-federated-storage-engine --with-blackhole-storage-engine --with-csv-storage-engine --with-archive-storage-engine  --with-example-storage-engine --with-big-tables   --with-extra-charsets=all --with-innodb --with-federated --with-partition --with-plugin-partition 

2)
FreeBSD mfr1.uk.hy.net 5.5-PRERELEASE FreeBSD 5.5-PRERELEASE #0: Thu Feb 23 12:16:30 UTC 2006     root@mfr1.uk.hy.net:/usr/obj/usr/src/sys/KERNEL  i386

gcc (GCC) 3.4.2 [FreeBSD] 20040728
Copyright (C) 2004 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

latest bk source, same configure

3)
FreeBSD london.hy.com 5.4-RELEASE-p8 FreeBSD 5.4-RELEASE-p8 #1: Thu Oct 13 16:08:43 UTC 2005     root@london.hy.com:/usr/obj/usr/src/sys/HELIOS  i386

gcc (GCC) 3.4.2 [FreeBSD] 20040728
Copyright (C) 2004 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

built from freebsd ports (with optimize and with DEBUG, but NOT with linux-threads)

-----
I have also tested the bk build on fedora linux. the linux build does work. but all 3 freebsd versions show the problem.

looking at  the pthread implementation in the FreeBSD source (http://www.freebsd.org/cgi/cvsweb.cgi/src/lib/libpthread/thread/thr_cond.c?rev=1.56;conten... or /usr/src/lib/libpthread/thread/thr_cond.c) you can verify that (at least the FreeBSD version of pthread expects only one mutex per variable.

line 222:
	if ((mutex == NULL) || (((*cond)->c_mutex != NULL) &&
			    ((*cond)->c_mutex != *mutex))) 

follow the 2 stack traces supplied earlier, and you can see that COND_refresh is used with 2 different mutexes.
[6 Sep 2007 6:28] Sveta Smirnova
Thank you for the feedback.

Verified as described.

To repeat: compile as described on 32-bit FreeBSD machine
[6 Oct 2007 2:04] Marc ALFF
See related:
- bug#17565
- bug#28360

The RENAME DATABASE statement is to be removed from the code,
because the implementation is not robust enough,
which leads to bugs like the one reported here.
[9 Nov 2007 20:12] Konstantin Osipov
This needs to be reverified: whether the new syntax can lead to a crash.
[13 Nov 2007 22:24] Sveta Smirnova
New syntax lead to " 1064: You have an error in your SQL syntax; ..." error. So bug should be closed.
[21 Nov 2007 19:52] Sveta Smirnova
Closed as "Can't repeat" because last comment.