From: Date: October 23 2008 6:30pm Subject: bzr commit into mysql-6.0 branch (monty:2747) Bug#39396 List-Archive: http://lists.mysql.com/commits/56918 X-Bug: 39396 Message-Id: <20081023163012.3CBE61CCCEDC@mysql.fi> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit #At file:///home/my/mysql-6.0-maria/ 2747 Michael Widenius 2008-10-23 Fix for Bug#39396 Maria: ha_maria.cc:2415: assertion in ha_maria::store_lock() - Problem was wrong cleanup of mysql_lock_tables() in MySQL 6.0 Fixed bug in my_vsnprintf in handling of %lld and %llu Removed warnings about usage of depricated mysqld options in mysql-test-run modified: mysql-test/mysql-test-run.pl mysql-test/suite/maria/r/maria-lock.result mysql-test/suite/maria/t/maria-lock.test sql/lock.cc sql/mysqld.cc storage/maria/ma_close.c storage/maria/ma_locking.c storage/maria/ma_open.c strings/my_vsnprintf.c per-file messages: mysql-test/mysql-test-run.pl Change to use new mysqld options instead of depricated onces mysql-test/suite/maria/r/maria-lock.result Added testcase for Bug#39396 mysql-test/suite/maria/t/maria-lock.test Added testcase for Bug#39396 sql/lock.cc Fixed wrong cleanup of mysql_lock_tables() - We must call read_lock_data() BEFORE we set lock_count to 0 Added DBUG statements sql/mysqld.cc Make warning messages for depricated options easier to understand. storage/maria/ma_close.c Updated DBUG_PRINT statement storage/maria/ma_locking.c Updated DBUG_PRINT statement storage/maria/ma_open.c Added DBUG_PRINT statement strings/my_vsnprintf.c Fixed bug in my_vsnprintf in handling of %lld and %llu Fixed wrong indentation === modified file 'mysql-test/mysql-test-run.pl' --- a/mysql-test/mysql-test-run.pl 2008-10-20 19:13:22 +0000 +++ b/mysql-test/mysql-test-run.pl 2008-10-23 16:29:52 +0000 @@ -2829,7 +2829,7 @@ sub run_benchmarks ($) { if ( ! $benchmark ) { - mtr_add_arg($args, "--log"); + mtr_add_arg($args, "--general-log"); mtr_run("$glob_mysql_bench_dir/run-all-tests", $args, "", "", "", ""); # FIXME check result code?! } @@ -3766,9 +3766,11 @@ sub mysqld_arguments ($$$$) { } my $log_base_path= "$opt_vardir/log/$mysqld->{'type'}$sidx"; - mtr_add_arg($args, "%s--log=%s.log", $prefix, $log_base_path); + mtr_add_arg($args, "%s--general-log", $prefix); + mtr_add_arg($args, "%s--general-log-file=%s.log", $prefix, $log_base_path); + mtr_add_arg($args, "%s--slow-query-log", $prefix); mtr_add_arg($args, - "%s--log-slow-queries=%s-slow.log", $prefix, $log_base_path); + "%s--slow-query-log-file=%s-slow.log", $prefix, $log_base_path); # Check if "extra_opt" contains --skip-log-bin my $skip_binlog= grep(/^--skip-log-bin/, @$extra_opt, @opt_extra_mysqld_opt); === modified file 'mysql-test/suite/maria/r/maria-lock.result' --- a/mysql-test/suite/maria/r/maria-lock.result 2008-10-21 23:23:23 +0000 +++ b/mysql-test/suite/maria/r/maria-lock.result 2008-10-23 16:29:52 +0000 @@ -1,4 +1,5 @@ drop table if exists t1,t2,t3; +drop view if exists v1; create table t1 (c1 int) engine=maria; create table t2 (c1 int) engine=maria; create table t3 (c1 int) engine=maria; @@ -33,3 +34,24 @@ insert t1 select * from t2; drop table t2; ERROR 42S02: Table 'test.t2' doesn't exist drop table t1; +create table t1 (a int, b int) engine=maria; +insert into t1 values (1, 2), (2, 3), (3, 4); +create table t2 (a int) engine=maria; +insert into t2 values (10), (20), (30); +create view v1 as select a as b, a/10 as a from t2; +lock table t1 write; +alter table t1 add column c int default 100 after a; +update t1, v1 set t1.b=t1.a+t1.b+v1.b where t1.a=v1.a; +unlock tables; +select * from t1; +a c b +1 100 13 +2 100 25 +3 100 37 +select * from t2; +a +10 +20 +30 +drop view v1; +drop table t1, t2; === modified file 'mysql-test/suite/maria/t/maria-lock.test' --- a/mysql-test/suite/maria/t/maria-lock.test 2008-10-21 23:23:23 +0000 +++ b/mysql-test/suite/maria/t/maria-lock.test 2008-10-23 16:29:52 +0000 @@ -6,6 +6,7 @@ --disable_warnings drop table if exists t1,t2,t3; +drop view if exists v1; --enable_warnings # Check that a lock merge works. @@ -96,3 +97,48 @@ connection default; disconnect locker; disconnect reader; disconnect writer; + +# +# Bug#39396 Maria: ha_maria.cc:2415: assertion in ha_maria::store_lock() +# +# Test alter table and a concurrent multi update +# (This will force update to reopen tables) +# + +create table t1 (a int, b int) engine=maria; +insert into t1 values (1, 2), (2, 3), (3, 4); +create table t2 (a int) engine=maria; +insert into t2 values (10), (20), (30); +create view v1 as select a as b, a/10 as a from t2; + +connect (locker,localhost,root,,test); +connection locker; +lock table t1 write; + +connect (changer,localhost,root,,test); +connection changer; +send alter table t1 add column c int default 100 after a; + +connect (updater,localhost,root,,test); +connection updater; +sleep 2; +send update t1, v1 set t1.b=t1.a+t1.b+v1.b where t1.a=v1.a; + +connection locker; +sleep 2; +unlock tables; + +connection changer; +reap; + +connection updater; +reap; +select * from t1; +select * from t2; +drop view v1; +drop table t1, t2; + +connection default; +disconnect updater; +disconnect changer; +disconnect locker; === modified file 'sql/lock.cc' --- a/sql/lock.cc 2008-10-20 19:13:22 +0000 +++ b/sql/lock.cc 2008-10-23 16:29:52 +0000 @@ -169,9 +169,8 @@ int mysql_lock_tables_check(THD *thd, TA DBUG_RETURN(0); } - /** - Reset lock type in lock data and free. + Reset lock type in lock data @param mysql_lock Lock structures to reset. @@ -190,10 +189,11 @@ int mysql_lock_tables_check(THD *thd, TA lock request will set its lock type properly. */ -static void reset_lock_data_and_free(MYSQL_LOCK **mysql_lock) + +static void reset_lock_data(MYSQL_LOCK *sql_lock) { - MYSQL_LOCK *sql_lock= *mysql_lock; THR_LOCK_DATA **ldata, **ldata_end; + DBUG_ENTER("reset_lock_data"); /* Clear the lock type of all lock data to avoid reusage. */ for (ldata= sql_lock->locks, ldata_end= ldata + sql_lock->lock_count; @@ -203,7 +203,21 @@ static void reset_lock_data_and_free(MYS /* Reset lock type. */ (*ldata)->type= TL_UNLOCK; } - my_free((uchar*) sql_lock, MYF(0)); + DBUG_VOID_RETURN; +} + + +/** + Reset lock type in lock data and free. + + @param mysql_lock Lock structures to reset. + +*/ + +static void reset_lock_data_and_free(MYSQL_LOCK **mysql_lock) +{ + reset_lock_data(*mysql_lock); + my_free(*mysql_lock, MYF(0)); *mysql_lock= 0; } @@ -315,6 +329,13 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, } else if (rc == 1) /* aborted or killed */ { + /* + reset_lock_data is required here. If thr_multi_lock fails it + resets lock type for tables, which were locked before (and + including) one that caused error. Lock type for other tables + preserved. + */ + reset_lock_data(sql_lock); thd->some_tables_deleted=1; // Try again sql_lock->lock_count= 0; // Locks are already freed // Fall through: unlock, reset lock data, free and retry === modified file 'sql/mysqld.cc' --- a/sql/mysqld.cc 2008-10-20 19:13:22 +0000 +++ b/sql/mysqld.cc 2008-10-23 16:29:52 +0000 @@ -8071,7 +8071,7 @@ mysqld_get_one_option(int optid, default_collation_name= 0; break; case 'l': - WARN_DEPRECATED(NULL, 7,0, "--log", "'--general_log'/'--general_log_file'"); + WARN_DEPRECATED(NULL, 7,0, "--log", "'--general-log --general-log-file'"); opt_log=1; break; case 'B': @@ -8256,7 +8256,8 @@ mysqld_get_one_option(int optid, } #endif /* HAVE_REPLICATION */ case (int) OPT_SLOW_QUERY_LOG: - WARN_DEPRECATED(NULL, 7,0, "--log_slow_queries", "'--slow_query_log'/'--slow_query_log_file'"); + WARN_DEPRECATED(NULL, 7,0, "--log-slow-queries", + "'--slow-query-log --slow-query-log-file'"); opt_slow_log= 1; break; #ifdef WITH_CSV_STORAGE_ENGINE === modified file 'storage/maria/ma_close.c' --- a/storage/maria/ma_close.c 2008-10-20 13:03:34 +0000 +++ b/storage/maria/ma_close.c 2008-10-23 16:29:52 +0000 @@ -28,9 +28,8 @@ int maria_close(register MARIA_HA *info) my_bool share_can_be_freed= FALSE; MARIA_SHARE *share= info->s; DBUG_ENTER("maria_close"); - DBUG_PRINT("enter",("base: 0x%lx reopen: %u locks: %u", - (long) info, (uint) share->reopen, - (uint) share->tot_locks)); + DBUG_PRINT("enter",("maria_handler: %p reopen: %u locks: %u", + info, (uint) share->reopen, (uint) share->tot_locks)); /* Check that we have unlocked key delete-links properly */ DBUG_ASSERT(info->key_del_used == 0); === modified file 'storage/maria/ma_locking.c' --- a/storage/maria/ma_locking.c 2008-08-25 18:23:18 +0000 +++ b/storage/maria/ma_locking.c 2008-10-23 16:29:52 +0000 @@ -29,7 +29,7 @@ int maria_lock_database(MARIA_HA *info, uint count; MARIA_SHARE *share= info->s; DBUG_ENTER("maria_lock_database"); - DBUG_PRINT("enter",("lock_type: %d old lock %d r_locks: %u w_locks: %u " + DBUG_PRINT("enter",("lock_type: %d old lock %d r_locks: %u w_locks: %u " "global_changed: %d open_count: %u name: '%s'", lock_type, info->lock_type, share->r_locks, share->w_locks, === modified file 'storage/maria/ma_open.c' --- a/storage/maria/ma_open.c 2008-10-20 09:16:47 +0000 +++ b/storage/maria/ma_open.c 2008-10-23 16:29:52 +0000 @@ -896,6 +896,7 @@ MARIA_HA *maria_open(const char *name, i goto err; pthread_mutex_unlock(&THR_LOCK_maria); + DBUG_PRINT("exit", ("maria_handler: %p", m_info)); DBUG_RETURN(m_info); err: === modified file 'strings/my_vsnprintf.c' --- a/strings/my_vsnprintf.c 2008-07-09 07:12:43 +0000 +++ b/strings/my_vsnprintf.c 2008-10-23 16:29:52 +0000 @@ -55,9 +55,9 @@ size_t my_vsnprintf(char *to, size_t n, { if (*fmt != '%') { - if (to == end) /* End of buffer */ + if (to == end) /* End of buffer */ break; - *to++= *fmt; /* Copy ordinary char */ + *to++= *fmt; /* Copy ordinary char */ continue; } fmt++; /* skip '%' */ @@ -76,7 +76,7 @@ size_t my_vsnprintf(char *to, size_t n, { length= length * 10 + (uint)(*fmt - '0'); if (!length) - pre_zero= 1; /* first digit was 0 */ + pre_zero= 1; /* first digit was 0 */ } if (*fmt == '.') { @@ -87,15 +87,17 @@ size_t my_vsnprintf(char *to, size_t n, width= va_arg(ap, int); } else + { for (; my_isdigit(&my_charset_latin1, *fmt); fmt++) width= width * 10 + (uint)(*fmt - '0'); + } } else width= SIZE_T_MAX; if (*fmt == 'l') { fmt++; - if (fmt[1] != 'l') + if (*fmt != 'l') have_longlong= (sizeof(long) == sizeof(longlong)); else { @@ -103,20 +105,21 @@ size_t my_vsnprintf(char *to, size_t n, have_longlong= 1; } } - else if(*fmt == 'z') + else if (*fmt == 'z') { fmt++; have_longlong= (sizeof(size_t) == sizeof(longlong)); } if (*fmt == 's') /* String parameter */ { - reg2 char *par = va_arg(ap, char *); - size_t plen,left_len = (size_t) (end - to) + 1; - if (!par) par = (char*)"(null)"; - plen= (uint) strnlen(par, width); + reg2 char *par= va_arg(ap, char *); + size_t plen, left_len= (size_t) (end - to) + 1; + if (!par) + par = (char*) "(null)"; + plen= strnlen(par, width); if (left_len <= plen) plen = left_len - 1; - to=strnmov(to,par,plen); + to= strnmov(to,par,plen); continue; } else if (*fmt == 'b') /* Buffer parameter */ @@ -143,9 +146,10 @@ size_t my_vsnprintf(char *to, size_t n, else to+= my_gcvt(d, MY_GCVT_ARG_DOUBLE, (int) width , to, NULL); } - else if (*fmt == 'd' || *fmt == 'u'|| *fmt== 'x' || *fmt =='X' || *fmt =='p') - /* Integer parameter */ + else if (*fmt == 'd' || *fmt == 'u' || *fmt == 'x' || *fmt == 'X' || + *fmt == 'p') { + /* Integer parameter */ longlong larg; size_t res_length, to_length; char *store_start= to, *store_end; @@ -159,27 +163,25 @@ size_t my_vsnprintf(char *to, size_t n, store_start= buff; if (have_longlong) larg = va_arg(ap,longlong); + else if (*fmt == 'd') + larg = va_arg(ap, int); else - if (*fmt == 'd') - larg = va_arg(ap, int); - else - larg= va_arg(ap, uint); + larg= va_arg(ap, uint); if (*fmt == 'd') store_end= longlong10_to_str(larg, store_start, -10); + else if (*fmt == 'u') + store_end= longlong10_to_str(larg, store_start, 10); + else if (*fmt == 'p') + { + store_start[0]= '0'; + store_start[1]= 'x'; + store_end= ll2str(larg, store_start + 2, 16, 0); + } else - if (*fmt== 'u') - store_end= longlong10_to_str(larg, store_start, 10); - else if(*fmt == 'p') - { - store_start[0]= '0'; - store_start[1]= 'x'; - store_end= ll2str(larg, store_start + 2, 16, 0); - } - else - { - DBUG_ASSERT(*fmt == 'X' || *fmt =='x'); - store_end= ll2str(larg, store_start, 16, (*fmt == 'X')); - } + { + DBUG_ASSERT(*fmt == 'X' || *fmt =='x'); + store_end= ll2str(larg, store_start, 16, (*fmt == 'X')); + } if ((res_length= (size_t) (store_end - store_start)) > to_length) break; /* num doesn't fit in output */