Commit 597ee039 authored by unknown's avatar unknown
Browse files

Merge mysql.com:/home/mydev/mysql-5.0-tmp_merge

into  mysql.com:/home/mydev/mysql-5.1-amerge


mysys/thr_lock.c:
  Auto merged
sql/mysql_priv.h:
  Auto merged
sql/sql_handler.cc:
  Auto merged
sql/sql_insert.cc:
  Auto merged
mysql-test/r/lock_multi.result:
  Manual merge
mysql-test/t/lock_multi.test:
  Manual merge
sql/lock.cc:
  Manual merge
sql/sql_base.cc:
  Manual merge
sql/sql_parse.cc:
  Manual merge
sql/sql_table.cc:
  Manual merge
parents 2ef57b83 0f93a64e
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -66,6 +66,21 @@ Select_priv
N
use test;
use test;
CREATE TABLE t1 (c1 int);
LOCK TABLE t1 WRITE;
 FLUSH TABLES WITH READ LOCK;
CREATE TABLE t2 (c1 int);
UNLOCK TABLES;
UNLOCK TABLES;
DROP TABLE t1, t2;
CREATE TABLE t1 (c1 int);
LOCK TABLE t1 WRITE;
 FLUSH TABLES WITH READ LOCK;
CREATE TABLE t2 AS SELECT * FROM t1;
ERROR HY000: Table 't2' was not locked with LOCK TABLES
UNLOCK TABLES;
UNLOCK TABLES;
DROP TABLE t1;
CREATE DATABASE mysqltest_1;
FLUSH TABLES WITH READ LOCK;
 DROP DATABASE mysqltest_1;
+77 −26
Original line number Diff line number Diff line
@@ -192,32 +192,6 @@ disconnect con2;
DROP DATABASE mysqltest_1;

#
# Bug #17264: MySQL Server freeze
#
connection locker;
create table t1 (f1 int(12) unsigned not null auto_increment, primary key(f1)) engine=innodb;
lock tables t1 write;
connection writer;
--sleep 2
delimiter //;
send alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; //
delimiter ;//
connection reader;
--sleep 2
delimiter //;
send alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; //
delimiter ;//
connection locker;
--sleep 2
unlock tables;
connection writer;
reap;
connection reader;
reap;
connection locker;
drop table t1;

# End of 5.0 tests
# Bug#16986 - Deadlock condition with MyISAM tables
#
connection locker;
@@ -246,4 +220,81 @@ connection locker;
use test;
#
connection default;
#
# Test if CREATE TABLE with LOCK TABLE deadlocks.
#
connection writer;
CREATE TABLE t1 (c1 int);
LOCK TABLE t1 WRITE;
#
# This waits until t1 is unlocked.
connection locker;
send FLUSH TABLES WITH READ LOCK;
--sleep 1
#
# This must not block.
connection writer;
CREATE TABLE t2 (c1 int);
UNLOCK TABLES;
#
# This awakes now.
connection locker;
reap;
UNLOCK TABLES;
#
connection default;
DROP TABLE t1, t2;
#
# Test if CREATE TABLE SELECT with LOCK TABLE deadlocks.
#
connection writer;
CREATE TABLE t1 (c1 int);
LOCK TABLE t1 WRITE;
#
# This waits until t1 is unlocked.
connection locker;
send FLUSH TABLES WITH READ LOCK;
--sleep 1
#
# This must not block.
connection writer;
--error 1100
CREATE TABLE t2 AS SELECT * FROM t1;
UNLOCK TABLES;
#
# This awakes now.
connection locker;
reap;
UNLOCK TABLES;
#
connection default;
DROP TABLE t1;

#
# Bug #17264: MySQL Server freeze
#
connection locker;
create table t1 (f1 int(12) unsigned not null auto_increment, primary key(f1)) engine=innodb;
lock tables t1 write;
connection writer;
--sleep 2
delimiter //;
send alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; //
delimiter ;//
connection reader;
--sleep 2
delimiter //;
send alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; //
delimiter ;//
connection locker;
--sleep 2
unlock tables;
connection writer;
reap;
connection reader;
reap;
connection locker;
drop table t1;

# End of 5.0 tests
+2 −0
Original line number Diff line number Diff line
@@ -204,6 +204,8 @@ static void check_locks(THR_LOCK *lock, const char *where,
      {
	if ((int) data->type == (int) TL_READ_NO_INSERT)
	  count++;
        /* Protect against infinite loop. */
        DBUG_ASSERT(count <= lock->read_no_write_count);
      }
      if (count != lock->read_no_write_count)
      {
+41 −5
Original line number Diff line number Diff line
@@ -935,7 +935,7 @@ void unlock_table_name(THD *thd, TABLE_LIST *table_list)
  if (table_list->table)
  {
    hash_delete(&open_cache, (byte*) table_list->table);
    (void) pthread_cond_broadcast(&COND_refresh);
    broadcast_refresh();
  }
}

@@ -1037,9 +1037,9 @@ bool lock_table_names(THD *thd, TABLE_LIST *table_list)
			(default 0, which will unlock all tables)

  NOTES
    One must have a lock on LOCK_open when calling this
    This function will send a COND_refresh signal to inform other threads
    that the name locks are removed
    One must have a lock on LOCK_open when calling this.
    This function will broadcast refresh signals to inform other threads
    that the name locks are removed.

  RETURN
    0	ok
@@ -1054,7 +1054,7 @@ void unlock_table_names(THD *thd, TABLE_LIST *table_list,
       table != last_table;
       table= table->next_local)
    unlock_table_name(thd,table);
  pthread_cond_broadcast(&COND_refresh);
  broadcast_refresh();
  DBUG_VOID_RETURN;
}

@@ -1344,3 +1344,39 @@ bool make_global_read_lock_block_commit(THD *thd)
  thd->exit_cond(old_message); // this unlocks LOCK_global_read_lock
  DBUG_RETURN(error);
}


/*
  Broadcast COND_refresh and COND_global_read_lock.

  SYNOPSIS
    broadcast_refresh()
      void                      No parameters.

  DESCRIPTION
    Due to a bug in a threading library it could happen that a signal
    did not reach its target. A condition for this was that the same
    condition variable was used with different mutexes in
    pthread_cond_wait(). Some time ago we changed LOCK_open to
    LOCK_global_read_lock in global read lock handling. So COND_refresh
    was used with LOCK_open and LOCK_global_read_lock.

    We did now also change from COND_refresh to COND_global_read_lock
    in global read lock handling. But now it is necessary to signal
    both conditions at the same time.

  NOTE
    When signalling COND_global_read_lock within the global read lock
    handling, it is not necessary to also signal COND_refresh.

  RETURN
    void
*/

void broadcast_refresh(void)
{
  VOID(pthread_cond_broadcast(&COND_refresh));
  VOID(pthread_cond_broadcast(&COND_global_read_lock));
}

+1 −0
Original line number Diff line number Diff line
@@ -1696,6 +1696,7 @@ void start_waiting_global_read_lock(THD *thd);
bool make_global_read_lock_block_commit(THD *thd);
bool set_protect_against_global_read_lock(void);
void unset_protect_against_global_read_lock(void);
void broadcast_refresh(void);

/* Lock based on name */
int lock_and_wait_for_table_name(THD *thd, TABLE_LIST *table_list);
Loading