Merge work:/my/mysql-4.0 into narttu.mysql.fi:/my/mysql-4.0
client/mysqltest.c: Auto merged mysql-test/mysql-test-run.sh: Auto merged sql/handler.cc: Auto merged
This commit is contained in:
commit
7a88d2ccbd
@ -2477,6 +2477,7 @@ int main(int argc, char** argv)
|
|||||||
}
|
}
|
||||||
case Q_COMMENT: /* Ignore row */
|
case Q_COMMENT: /* Ignore row */
|
||||||
case Q_COMMENT_WITH_COMMAND:
|
case Q_COMMENT_WITH_COMMAND:
|
||||||
|
break;
|
||||||
case Q_PING:
|
case Q_PING:
|
||||||
(void) mysql_ping(&cur_con->mysql);
|
(void) mysql_ping(&cur_con->mysql);
|
||||||
break;
|
break;
|
||||||
|
@ -107,6 +107,7 @@ void thr_unlock(THR_LOCK_DATA *data);
|
|||||||
int thr_multi_lock(THR_LOCK_DATA **data,uint count);
|
int thr_multi_lock(THR_LOCK_DATA **data,uint count);
|
||||||
void thr_multi_unlock(THR_LOCK_DATA **data,uint count);
|
void thr_multi_unlock(THR_LOCK_DATA **data,uint count);
|
||||||
void thr_abort_locks(THR_LOCK *lock);
|
void thr_abort_locks(THR_LOCK *lock);
|
||||||
|
void thr_abort_locks_for_thread(THR_LOCK *lock, pthread_t thread);
|
||||||
void thr_print_locks(void); /* For debugging */
|
void thr_print_locks(void); /* For debugging */
|
||||||
my_bool thr_upgrade_write_delay_lock(THR_LOCK_DATA *data);
|
my_bool thr_upgrade_write_delay_lock(THR_LOCK_DATA *data);
|
||||||
my_bool thr_reschedule_write_lock(THR_LOCK_DATA *data);
|
my_bool thr_reschedule_write_lock(THR_LOCK_DATA *data);
|
||||||
|
@ -349,7 +349,8 @@ while test $# -gt 0; do
|
|||||||
--debug=d:t:i:A,$MYSQL_TEST_DIR/var/log/master.trace"
|
--debug=d:t:i:A,$MYSQL_TEST_DIR/var/log/master.trace"
|
||||||
EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT \
|
EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT \
|
||||||
--debug=d:t:i:A,$MYSQL_TEST_DIR/var/log/slave.trace"
|
--debug=d:t:i:A,$MYSQL_TEST_DIR/var/log/slave.trace"
|
||||||
EXTRA_MYSQL_TEST_OPT="$EXTRA_MYSQL_TEST_OPT --debug"
|
EXTRA_MYSQL_TEST_OPT="$EXTRA_MYSQL_TEST_OPT \
|
||||||
|
--debug=d:t:A,$MYSQL_TEST_DIR/var/log/mysqltest.trace"
|
||||||
;;
|
;;
|
||||||
--fast)
|
--fast)
|
||||||
FAST_START=1
|
FAST_START=1
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
drop table if exists t1;
|
drop table if exists t1,t2;
|
||||||
create table t1(n int);
|
create table t1(n int);
|
||||||
insert into t1 values (1);
|
insert into t1 values (1);
|
||||||
lock tables t1 write;
|
lock tables t1 write;
|
||||||
@ -17,3 +17,10 @@ unlock tables;
|
|||||||
n
|
n
|
||||||
1
|
1
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
create table t1 (a int);
|
||||||
|
create table t2 (a int);
|
||||||
|
lock table t1 write, t2 write;
|
||||||
|
insert t1 select * from t2;
|
||||||
|
drop table t2;
|
||||||
|
Table 'test.t2' doesn't exist
|
||||||
|
drop table t1;
|
||||||
|
@ -6,7 +6,8 @@
|
|||||||
#
|
#
|
||||||
-- source include/not_embedded.inc
|
-- source include/not_embedded.inc
|
||||||
|
|
||||||
drop table if exists t1;
|
drop table if exists t1,t2;
|
||||||
|
|
||||||
# test to see if select will get the lock ahead of low priority update
|
# test to see if select will get the lock ahead of low priority update
|
||||||
|
|
||||||
connect (locker,localhost,root,,);
|
connect (locker,localhost,root,,);
|
||||||
@ -48,3 +49,22 @@ reap;
|
|||||||
connection reader;
|
connection reader;
|
||||||
reap;
|
reap;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test problem when using locks on many tables and droping a table that
|
||||||
|
# is to-be-locked by another thread
|
||||||
|
#
|
||||||
|
|
||||||
|
connection locker;
|
||||||
|
create table t1 (a int);
|
||||||
|
create table t2 (a int);
|
||||||
|
lock table t1 write, t2 write;
|
||||||
|
connection reader;
|
||||||
|
send insert t1 select * from t2;
|
||||||
|
connection locker;
|
||||||
|
drop table t2;
|
||||||
|
connection reader;
|
||||||
|
--error 1146
|
||||||
|
reap;
|
||||||
|
connection locker;
|
||||||
|
drop table t1;
|
||||||
|
@ -945,6 +945,54 @@ void thr_abort_locks(THR_LOCK *lock)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Abort all locks for specific table/thread combination
|
||||||
|
|
||||||
|
This is used to abort all locks for a specific thread
|
||||||
|
*/
|
||||||
|
|
||||||
|
void thr_abort_locks_for_thread(THR_LOCK *lock, pthread_t thread)
|
||||||
|
{
|
||||||
|
THR_LOCK_DATA *data;
|
||||||
|
DBUG_ENTER("thr_abort_locks_for_thread");
|
||||||
|
|
||||||
|
pthread_mutex_lock(&lock->mutex);
|
||||||
|
for (data= lock->read_wait.data; data ; data= data->next)
|
||||||
|
{
|
||||||
|
if (pthread_equal(thread, data->thread))
|
||||||
|
{
|
||||||
|
DBUG_PRINT("info",("Aborting read-wait lock"));
|
||||||
|
data->type= TL_UNLOCK; /* Mark killed */
|
||||||
|
pthread_cond_signal(data->cond);
|
||||||
|
data->cond= 0; /* Removed from list */
|
||||||
|
|
||||||
|
if (((*data->prev)= data->next))
|
||||||
|
data->next->prev= data->prev;
|
||||||
|
else
|
||||||
|
lock->read_wait.last= data->prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (data= lock->write_wait.data; data ; data= data->next)
|
||||||
|
{
|
||||||
|
if (pthread_equal(thread, data->thread))
|
||||||
|
{
|
||||||
|
DBUG_PRINT("info",("Aborting write-wait lock"));
|
||||||
|
data->type= TL_UNLOCK;
|
||||||
|
pthread_cond_signal(data->cond);
|
||||||
|
data->cond= 0;
|
||||||
|
|
||||||
|
if (((*data->prev)= data->next))
|
||||||
|
data->next->prev= data->prev;
|
||||||
|
else
|
||||||
|
lock->write_wait.last= data->prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&lock->mutex);
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Upgrade a WRITE_DELAY lock to a WRITE_LOCK */
|
/* Upgrade a WRITE_DELAY lock to a WRITE_LOCK */
|
||||||
|
|
||||||
my_bool thr_upgrade_write_delay_lock(THR_LOCK_DATA *data)
|
my_bool thr_upgrade_write_delay_lock(THR_LOCK_DATA *data)
|
||||||
|
@ -503,7 +503,8 @@ int handler::ha_open(const char *name, int mode, int test_if_locked)
|
|||||||
int error;
|
int error;
|
||||||
DBUG_ENTER("handler::open");
|
DBUG_ENTER("handler::open");
|
||||||
DBUG_PRINT("enter",("name: %s db_type: %d db_stat: %d mode: %d lock_test: %d",
|
DBUG_PRINT("enter",("name: %s db_type: %d db_stat: %d mode: %d lock_test: %d",
|
||||||
name, table->db_type, table->db_stat, mode, test_if_locked));
|
name, table->db_type, table->db_stat, mode,
|
||||||
|
test_if_locked));
|
||||||
|
|
||||||
if ((error=open(name,mode,test_if_locked)))
|
if ((error=open(name,mode,test_if_locked)))
|
||||||
{
|
{
|
||||||
|
19
sql/lock.cc
19
sql/lock.cc
@ -313,6 +313,25 @@ void mysql_lock_abort(THD *thd, TABLE *table)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Abort one thread / table combination */
|
||||||
|
|
||||||
|
void mysql_lock_abort_for_thread(THD *thd, TABLE *table)
|
||||||
|
{
|
||||||
|
MYSQL_LOCK *locked;
|
||||||
|
TABLE *write_lock_used;
|
||||||
|
DBUG_ENTER("mysql_lock_abort_for_thread");
|
||||||
|
|
||||||
|
if ((locked = get_lock_data(thd,&table,1,1,&write_lock_used)))
|
||||||
|
{
|
||||||
|
for (uint i=0; i < locked->lock_count; i++)
|
||||||
|
thr_abort_locks_for_thread(locked->locks[i]->lock,
|
||||||
|
table->in_use->real_id);
|
||||||
|
my_free((gptr) locked,MYF(0));
|
||||||
|
}
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b)
|
MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b)
|
||||||
{
|
{
|
||||||
MYSQL_LOCK *sql_lock;
|
MYSQL_LOCK *sql_lock;
|
||||||
|
@ -711,6 +711,7 @@ void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock);
|
|||||||
void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count);
|
void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count);
|
||||||
void mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table);
|
void mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table);
|
||||||
void mysql_lock_abort(THD *thd, TABLE *table);
|
void mysql_lock_abort(THD *thd, TABLE *table);
|
||||||
|
void mysql_lock_abort_for_thread(THD *thd, TABLE *table);
|
||||||
MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b);
|
MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b);
|
||||||
bool lock_global_read_lock(THD *thd);
|
bool lock_global_read_lock(THD *thd);
|
||||||
void unlock_global_read_lock(THD *thd);
|
void unlock_global_read_lock(THD *thd);
|
||||||
|
@ -4416,8 +4416,8 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
|||||||
case (int) OPT_SAFE:
|
case (int) OPT_SAFE:
|
||||||
opt_specialflag|= SPECIAL_SAFE_MODE;
|
opt_specialflag|= SPECIAL_SAFE_MODE;
|
||||||
delay_key_write_options= (uint) DELAY_KEY_WRITE_NONE;
|
delay_key_write_options= (uint) DELAY_KEY_WRITE_NONE;
|
||||||
myisam_recover_options= HA_RECOVER_NONE; // To be changed
|
myisam_recover_options= HA_RECOVER_DEFAULT;
|
||||||
ha_open_options&= ~(HA_OPEN_ABORT_IF_CRASHED | HA_OPEN_DELAY_KEY_WRITE);
|
ha_open_options&= ~(HA_OPEN_DELAY_KEY_WRITE);
|
||||||
break;
|
break;
|
||||||
case (int) OPT_SKIP_PRIOR:
|
case (int) OPT_SKIP_PRIOR:
|
||||||
opt_specialflag|= SPECIAL_NO_PRIOR;
|
opt_specialflag|= SPECIAL_NO_PRIOR;
|
||||||
|
@ -1244,7 +1244,11 @@ bool drop_locked_tables(THD *thd,const char *db, const char *table_name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* lock table to force abort of any threads trying to use table */
|
/*
|
||||||
|
If we have the table open, which only happens when a LOCK TABLE has been
|
||||||
|
done on the table, change the lock type to a lock that will abort all
|
||||||
|
other threads trying to get the lock.
|
||||||
|
*/
|
||||||
|
|
||||||
void abort_locked_tables(THD *thd,const char *db, const char *table_name)
|
void abort_locked_tables(THD *thd,const char *db, const char *table_name)
|
||||||
{
|
{
|
||||||
@ -1253,16 +1257,31 @@ void abort_locked_tables(THD *thd,const char *db, const char *table_name)
|
|||||||
{
|
{
|
||||||
if (!strcmp(table->real_name,table_name) &&
|
if (!strcmp(table->real_name,table_name) &&
|
||||||
!strcmp(table->table_cache_key,db))
|
!strcmp(table->table_cache_key,db))
|
||||||
|
{
|
||||||
mysql_lock_abort(thd,table);
|
mysql_lock_abort(thd,table);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
** open_unireg_entry
|
/*
|
||||||
** Purpose : Load a table definition from file and open unireg table
|
Load a table definition from file and open unireg table
|
||||||
** Args : entry with DB and table given
|
|
||||||
** Returns : 0 if ok
|
SYNOPSIS
|
||||||
** Note that the extra argument for open is taken from thd->open_options
|
open_unireg_entry()
|
||||||
|
thd Thread handle
|
||||||
|
entry Store open table definition here
|
||||||
|
db Database name
|
||||||
|
name Table name
|
||||||
|
alias Alias name
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
Extra argument for open is taken from thd->open_options
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0 ok
|
||||||
|
# Error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
|
static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
|
||||||
@ -2277,6 +2296,17 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name,
|
|||||||
}
|
}
|
||||||
pthread_mutex_unlock(&in_use->mysys_var->mutex);
|
pthread_mutex_unlock(&in_use->mysys_var->mutex);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
Now we must abort all tables locks used by this thread
|
||||||
|
as the thread may be waiting to get a lock for another table
|
||||||
|
*/
|
||||||
|
for (TABLE *thd_table= in_use->open_tables;
|
||||||
|
thd_table ;
|
||||||
|
thd_table= thd_table->next)
|
||||||
|
{
|
||||||
|
if (thd_table->db_stat) // If table is open
|
||||||
|
mysql_lock_abort_for_thread(thd, thd_table);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
result= result || return_if_owned_by_thd;
|
result= result || return_if_owned_by_thd;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user