Commit 54263173 authored by unknown's avatar unknown
Browse files

Merge monty@192.168.0.9:/my/mysql-5.0

into  mysql.com:/home/my/mysql-5.0


sql/mysqld.cc:
  Auto merged
parents d5df9342 8b670ee3
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -48,3 +48,10 @@ lock table t1 read, t2 read, t3 read;
flush tables with read lock;
unlock tables;
drop table t1, t2, t3;
create table t1 (c1 int);
create table t2 (c1 int);
lock table t1 write;
 flush tables with read lock;
 insert into t2 values(1);
unlock tables;
drop table t1, t2;
+16 −0
Original line number Diff line number Diff line
@@ -43,3 +43,19 @@ Field Type Null Key Default Extra
a	int(11)	YES		NULL	
unlock tables;
drop table t1;
use mysql;
LOCK TABLES columns_priv WRITE, db WRITE, host WRITE, user WRITE;
FLUSH TABLES;
use mysql;
 SELECT user.Select_priv FROM user, db WHERE user.user = db.user LIMIT 1;
OPTIMIZE TABLES columns_priv, db, host, user;
Table	Op	Msg_type	Msg_text
mysql.columns_priv	optimize	status	OK
mysql.db	optimize	status	OK
mysql.host	optimize	status	OK
mysql.user	optimize	status	OK
UNLOCK TABLES;
Select_priv
N
use test;
use test;
+40 −0
Original line number Diff line number Diff line
@@ -102,3 +102,43 @@ unlock tables;
drop table t1, t2, t3;

# End of 4.1 tests

#
# Test of deadlock problem when doing FLUSH TABLE with read lock
# (Bug was in NTPL threads in Linux when using different mutex while
#  waiting for a condtion variable)

create table t1 (c1 int);
create table t2 (c1 int);

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

connection con1;
lock table t1 write;

connection con2;
send flush tables with read lock;
--sleep 1

connection con3;
send insert into t2 values(1);
--sleep 1

connection con1;
unlock tables;
disconnect con1;

connection con2;
reap;
disconnect con2;

connection con3;
# It hangs here (insert into t2 does not end).
reap;
disconnect con3;

connection default;
drop table t1, t2;

# End of 5.0 tests
+32 −0
Original line number Diff line number Diff line
@@ -107,3 +107,35 @@ show columns from t1;
connection locker;
unlock tables;
drop table t1;

#
# Bug#16986 - Deadlock condition with MyISAM tables
#
connection locker;
use mysql;
LOCK TABLES columns_priv WRITE, db WRITE, host WRITE, user WRITE;
FLUSH TABLES;
--sleep 1
#
connection reader;
use mysql;
#NOTE:  This must be a multi-table select, otherwise the deadlock will not occur
send SELECT user.Select_priv FROM user, db WHERE user.user = db.user LIMIT 1;
--sleep 1
#
connection locker;
# Make test case independent from earlier grants.
--replace_result "Table is already up to date" "OK"
OPTIMIZE TABLES columns_priv, db, host, user;
UNLOCK TABLES;
#
connection reader;
reap;
use test;
#
connection locker;
use test;
#
connection default;

# End of 5.0 tests
+25 −9
Original line number Diff line number Diff line
@@ -1138,8 +1138,9 @@ bool lock_global_read_lock(THD *thd)

  if (!thd->global_read_lock)
  {
    const char *old_message;
    (void) pthread_mutex_lock(&LOCK_global_read_lock);
    const char *old_message=thd->enter_cond(&COND_refresh, &LOCK_global_read_lock,
    old_message=thd->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
                                "Waiting to get readlock");
    DBUG_PRINT("info",
	       ("waiting_for: %d  protect_against: %d",
@@ -1147,7 +1148,7 @@ bool lock_global_read_lock(THD *thd)

    waiting_for_read_lock++;
    while (protect_against_global_read_lock && !thd->killed)
      pthread_cond_wait(&COND_refresh, &LOCK_global_read_lock);
      pthread_cond_wait(&COND_global_read_lock, &LOCK_global_read_lock);
    waiting_for_read_lock--;
    if (thd->killed)
    {
@@ -1169,9 +1170,15 @@ bool lock_global_read_lock(THD *thd)
  DBUG_RETURN(0);
}


void unlock_global_read_lock(THD *thd)
{
  uint tmp;
  DBUG_ENTER("unlock_global_read_lock");
  DBUG_PRINT("info",
             ("global_read_lock: %u  global_read_lock_blocks_commit: %u",
              global_read_lock, global_read_lock_blocks_commit));

  pthread_mutex_lock(&LOCK_global_read_lock);
  tmp= --global_read_lock;
  if (thd->global_read_lock == MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT)
@@ -1179,8 +1186,13 @@ void unlock_global_read_lock(THD *thd)
  pthread_mutex_unlock(&LOCK_global_read_lock);
  /* Send the signal outside the mutex to avoid a context switch */
  if (!tmp)
    pthread_cond_broadcast(&COND_refresh);
  {
    DBUG_PRINT("signal", ("Broadcasting COND_global_read_lock"));
    pthread_cond_broadcast(&COND_global_read_lock);
  }
  thd->global_read_lock= 0;

  DBUG_VOID_RETURN;
}

#define must_wait (global_read_lock &&                             \
@@ -1218,11 +1230,15 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh,
      */
      DBUG_RETURN(is_not_commit);
    }
    old_message=thd->enter_cond(&COND_refresh, &LOCK_global_read_lock,
    old_message=thd->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
				"Waiting for release of readlock");
    while (must_wait && ! thd->killed &&
	   (!abort_on_refresh || thd->version == refresh_version))
      (void) pthread_cond_wait(&COND_refresh,&LOCK_global_read_lock);
    {
      DBUG_PRINT("signal", ("Waiting for COND_global_read_lock"));
      (void) pthread_cond_wait(&COND_global_read_lock, &LOCK_global_read_lock);
      DBUG_PRINT("signal", ("Got COND_global_read_lock"));
    }
    if (thd->killed)
      result=1;
  }
@@ -1251,7 +1267,7 @@ void start_waiting_global_read_lock(THD *thd)
        (waiting_for_read_lock || global_read_lock_blocks_commit));
  (void) pthread_mutex_unlock(&LOCK_global_read_lock);
  if (tmp)
    pthread_cond_broadcast(&COND_refresh);
    pthread_cond_broadcast(&COND_global_read_lock);
  DBUG_VOID_RETURN;
}

@@ -1273,10 +1289,10 @@ bool make_global_read_lock_block_commit(THD *thd)
  /* For testing we set up some blocking, to see if we can be killed */
  DBUG_EXECUTE_IF("make_global_read_lock_block_commit_loop",
                  protect_against_global_read_lock++;);
  old_message= thd->enter_cond(&COND_refresh, &LOCK_global_read_lock,
  old_message= thd->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
                               "Waiting for all running commits to finish");
  while (protect_against_global_read_lock && !thd->killed)
    pthread_cond_wait(&COND_refresh, &LOCK_global_read_lock);
    pthread_cond_wait(&COND_global_read_lock, &LOCK_global_read_lock);
  DBUG_EXECUTE_IF("make_global_read_lock_block_commit_loop",
                  protect_against_global_read_lock--;);
  if ((error= test(thd->killed)))
Loading