On 12/20/10 10:59 AM, Jon Olav Hauglid wrote:
> #At file:///export/home/x/mysql-trunk-bugfixing-bug53322/ based on
> 3450 Jon Olav Hauglid 2010-12-20
> Bug #53322 deadlock with FLUSH TABLES WITH READ LOCK and DROP FUNCTION
> This deadlock could occur between two connections if one connection
> first locked the mysql.func table (using either FLUSH TABLES WITH
> READ LOCK or LOCK TABLE mysql.func WRITE). If the second connection
> then tried to either CREATE or DROP an UDF function, a deadlock would
> occur when the first connection tried to use an UDF function.
> The reason for the deadlock was the way the THR_LOCK_udf rwlock was
> used in the UDF handling code. For CREATE or DROP FUNCTION (UDF),
> THR_LOCK_udf was write locked before mysql.func was locked and opened.
> This meant that another connection first locking mysql.func and later
> using an UDF function (and thus locking THR_LOCK_udf), could cause
> a deadlock.
> This patch fixes the problem by changing the CREATE FUNCTION (UDF)
> implementation to open mysql.func before locking THR_LOCK_udf. The
> DROP FUNCTION (UDF) implementation is changed so that THR_LOCK_udf
> is unlocked before opening mysql.func.
> Test case added to udf.test.
OK to push given that the comment below is addressed (if possible).
> restore_record(table, s->default_values); // Default values for fields
> @@ -557,6 +559,7 @@ int mysql_drop_function(THD *thd,const L
> char *exact_name_str;
> uint exact_name_len;
> bool save_binlog_row_based;
> + int error= 1;
> if (!initialized)
> @@ -580,7 +583,8 @@ int mysql_drop_function(THD *thd,const L
> (uint) udf_name->length)))
> my_error(ER_FUNCTION_NOT_DEFINED, MYF(0), udf_name->str);
> - goto err;
> + mysql_rwlock_unlock(&THR_LOCK_udf);
It would be nicer if the same pattern used in mysql_create_function is
used in mysql_drop_function. That is, the table is opened and locked
before THR_LOCK_udf is locked.
Otherwise, looks good.