mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Merge to get fix for LOCK TABLES + DROP TABLE in another thread
This commit is contained in:
14
.bzrignore
14
.bzrignore
@ -206,6 +206,7 @@ config.h.in
|
||||
config.log
|
||||
config.status
|
||||
configure
|
||||
configure.lineno
|
||||
core
|
||||
core.2430
|
||||
db-*.*.*
|
||||
@ -214,6 +215,7 @@ depcomp
|
||||
extra/comp_err
|
||||
extra/my_print_defaults
|
||||
extra/mysql_install
|
||||
extra/mysql_waitpid
|
||||
extra/perror
|
||||
extra/replace
|
||||
extra/resolve_stack_dump
|
||||
@ -232,6 +234,7 @@ innobase/autom4te.cache/*
|
||||
innobase/autom4te.cache/output.0
|
||||
innobase/autom4te.cache/requests
|
||||
innobase/autom4te.cache/traces.0
|
||||
innobase/configure.lineno
|
||||
innobase/conftest.s1
|
||||
innobase/conftest.subs
|
||||
innobase/ib_config.h
|
||||
@ -499,6 +502,11 @@ stamp-h1
|
||||
strings/conf_to_src
|
||||
strings/ctype_autoconf.c
|
||||
strings/ctype_extra_sources.c
|
||||
support-files/MacOSX/Description.plist
|
||||
support-files/MacOSX/Info.plist
|
||||
support-files/MacOSX/StartupParameters.plist
|
||||
support-files/MacOSX/postinstall
|
||||
support-files/MacOSX/preinstall
|
||||
support-files/binary-configure
|
||||
support-files/my-huge.cnf
|
||||
support-files/my-large.cnf
|
||||
@ -522,9 +530,3 @@ vio/test-ssl
|
||||
vio/test-sslclient
|
||||
vio/test-sslserver
|
||||
vio/viotest-ssl
|
||||
extra/mysql_waitpid
|
||||
support-files/MacOSX/Description.plist
|
||||
support-files/MacOSX/Info.plist
|
||||
support-files/MacOSX/StartupParameters.plist
|
||||
support-files/MacOSX/postinstall
|
||||
support-files/MacOSX/preinstall
|
||||
|
@ -27,7 +27,7 @@
|
||||
#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_LOCAL_FILES)
|
||||
|
||||
char server_version[SERVER_VERSION_LENGTH];
|
||||
uint32 server_id = 0;
|
||||
ulong server_id = 0;
|
||||
|
||||
// needed by net_serv.c
|
||||
ulong bytes_sent = 0L, bytes_received = 0L;
|
||||
|
@ -218,6 +218,9 @@ int my_connect(my_socket s, const struct sockaddr *name, uint namelen,
|
||||
* implementations of select that don't adjust tv upon
|
||||
* failure to reflect the time remaining
|
||||
*/
|
||||
#ifdef HAVE_POLL
|
||||
return(0);
|
||||
#endif
|
||||
start_time = time(NULL);
|
||||
for (;;)
|
||||
{
|
||||
|
@ -78,3 +78,24 @@ EXPLAIN SELECT * FROM t1 WHERE expedition='0001-00-00 00:00:00';
|
||||
table type possible_keys key key_len ref rows Extra
|
||||
t1 ref expedition expedition 8 const 1 Using where
|
||||
drop table t1;
|
||||
CREATE TABLE `t1` (
|
||||
`date` datetime NOT NULL default '0000-00-00 00:00:00',
|
||||
`numfacture` int(6) unsigned NOT NULL default '0',
|
||||
`expedition` datetime NOT NULL default '0000-00-00 00:00:00',
|
||||
PRIMARY KEY (`numfacture`),
|
||||
KEY `date` (`date`),
|
||||
KEY `expedition` (`expedition`)
|
||||
) TYPE=MyISAM;
|
||||
|
||||
INSERT INTO t1 (expedition) VALUES ('0001-00-00 00:00:00');
|
||||
SELECT * FROM t1 WHERE expedition='0001-00-00 00:00:00';
|
||||
INSERT INTO t1 (numfacture,expedition) VALUES ('1212','0001-00-00 00:00:00');
|
||||
SELECT * FROM t1 WHERE expedition='0001-00-00 00:00:00';
|
||||
EXPLAIN SELECT * FROM t1 WHERE expedition='0001-00-00 00:00:00';
|
||||
drop table t1;
|
||||
create table t1 (a datetime not null, b datetime not null);
|
||||
insert into t1 values (now(), now());
|
||||
insert into t1 values (now(), now());
|
||||
select * from t1 where a is null or b is null;
|
||||
a b
|
||||
drop table t1;
|
||||
|
@ -35,3 +35,23 @@ create table t1 (a bigint not null, primary key (a,a,a,a,a,a,a,a,a,a));
|
||||
insert into t1 values (2),(4),(6),(8),(10),(12),(14),(16),(18),(20),(22),(24),(26),(23),(27);
|
||||
delete from t1 where a=27;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# CHAR(0) bug - not actually DELETE bug, but anyway...
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (
|
||||
bool char(0) default NULL,
|
||||
not_null varchar(20) binary NOT NULL default '',
|
||||
misc integer not null,
|
||||
PRIMARY KEY (not_null)
|
||||
) TYPE=MyISAM;
|
||||
|
||||
INSERT INTO t1 VALUES (NULL,'a',4), (NULL,'b',5), (NULL,'c',6), (NULL,'d',7);
|
||||
|
||||
select * from t1 where misc > 5 and bool is null;
|
||||
delete from t1 where misc > 5 and bool is null;
|
||||
select * from t1 where misc > 5 and bool is null;
|
||||
|
||||
drop table t1;
|
||||
|
||||
|
@ -59,3 +59,8 @@ INSERT INTO t1 (numfacture,expedition) VALUES ('1212','0001-00-00 00:00:00');
|
||||
SELECT * FROM t1 WHERE expedition='0001-00-00 00:00:00';
|
||||
EXPLAIN SELECT * FROM t1 WHERE expedition='0001-00-00 00:00:00';
|
||||
drop table t1;
|
||||
create table t1 (a datetime not null, b datetime not null);
|
||||
insert into t1 values (now(), now());
|
||||
insert into t1 values (now(), now());
|
||||
select * from t1 where a is null or b is null;
|
||||
drop table t1;
|
||||
|
@ -65,7 +65,7 @@ public:
|
||||
virtual String *val_str(String*,String *)=0;
|
||||
virtual Item_result result_type () const=0;
|
||||
virtual Item_result cmp_type () const { return result_type(); }
|
||||
bool eq(Field *field) { return ptr == field->ptr; }
|
||||
bool eq(Field *field) { return ptr == field->ptr && null_ptr == field->null_ptr; }
|
||||
virtual bool eq_def(Field *field);
|
||||
virtual uint32 pack_length() const { return (uint32) field_length; }
|
||||
virtual void reset(void) { bzero(ptr,pack_length()); }
|
||||
|
76
sql/lock.cc
76
sql/lock.cc
@ -487,11 +487,12 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list)
|
||||
{
|
||||
TABLE *table;
|
||||
char key[MAX_DBKEY_LENGTH];
|
||||
char *db= table_list->db ? table_list->db : (thd->db ? thd->db : (char*) "");
|
||||
uint key_length;
|
||||
DBUG_ENTER("lock_table_name");
|
||||
safe_mutex_assert_owner(&LOCK_open);
|
||||
|
||||
key_length=(uint) (strmov(strmov(key,table_list->db)+1,table_list->real_name)
|
||||
key_length=(uint) (strmov(strmov(key,db)+1,table_list->real_name)
|
||||
-key)+ 1;
|
||||
|
||||
/* Only insert the table if we haven't insert it already */
|
||||
@ -520,7 +521,7 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list)
|
||||
my_free((gptr) table,MYF(0));
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
if (remove_table_from_cache(thd, table_list->db, table_list->real_name))
|
||||
if (remove_table_from_cache(thd, db, table_list->real_name))
|
||||
DBUG_RETURN(1); // Table is in use
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
@ -564,6 +565,77 @@ bool wait_for_locked_table_names(THD *thd, TABLE_LIST *table_list)
|
||||
DBUG_RETURN(result);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Lock all tables in list with a name lock
|
||||
|
||||
SYNOPSIS
|
||||
lock_table_names()
|
||||
thd Thread handle
|
||||
table_list Names of tables to lock
|
||||
|
||||
NOTES
|
||||
One must have a lock on LOCK_open when calling this
|
||||
|
||||
RETURN
|
||||
0 ok
|
||||
1 Fatal error (end of memory ?)
|
||||
*/
|
||||
|
||||
bool lock_table_names(THD *thd, TABLE_LIST *table_list)
|
||||
{
|
||||
bool got_all_locks=1;
|
||||
TABLE_LIST *lock_table;
|
||||
|
||||
for (lock_table=table_list ; lock_table ; lock_table=lock_table->next)
|
||||
{
|
||||
int got_lock;
|
||||
if ((got_lock=lock_table_name(thd,lock_table)) < 0)
|
||||
goto end; // Fatal error
|
||||
if (got_lock)
|
||||
got_all_locks=0; // Someone is using table
|
||||
}
|
||||
|
||||
/* If some table was in use, wait until we got the lock */
|
||||
if (!got_all_locks && wait_for_locked_table_names(thd, table_list))
|
||||
goto end;
|
||||
return 0;
|
||||
|
||||
end:
|
||||
unlock_table_names(thd, table_list, lock_table);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Unlock all tables in list with a name lock
|
||||
|
||||
SYNOPSIS
|
||||
unlock_table_names()
|
||||
thd Thread handle
|
||||
table_list Names of tables to unlock
|
||||
last_table Don't unlock any tables after this one.
|
||||
(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
|
||||
|
||||
RETURN
|
||||
0 ok
|
||||
1 Fatal error (end of memory ?)
|
||||
*/
|
||||
|
||||
void unlock_table_names(THD *thd, TABLE_LIST *table_list,
|
||||
TABLE_LIST *last_table)
|
||||
{
|
||||
for (TABLE_LIST *table=table_list ; table != last_table ; table=table->next)
|
||||
unlock_table_name(thd,table);
|
||||
pthread_cond_broadcast(&COND_refresh);
|
||||
}
|
||||
|
||||
|
||||
static void print_lock_error(int error)
|
||||
{
|
||||
int textno;
|
||||
|
@ -723,6 +723,9 @@ int lock_and_wait_for_table_name(THD *thd, TABLE_LIST *table_list);
|
||||
int lock_table_name(THD *thd, TABLE_LIST *table_list);
|
||||
void unlock_table_name(THD *thd, TABLE_LIST *table_list);
|
||||
bool wait_for_locked_table_names(THD *thd, TABLE_LIST *table_list);
|
||||
bool lock_table_names(THD *thd, TABLE_LIST *table_list);
|
||||
void unlock_table_names(THD *thd, TABLE_LIST *table_list,
|
||||
TABLE_LIST *last_table= 0);
|
||||
|
||||
|
||||
/* old unireg functions */
|
||||
|
@ -7,8 +7,8 @@
|
||||
|
||||
"hashchk",
|
||||
"isamchk",
|
||||
"TAK",
|
||||
"NIE",
|
||||
"TAK",
|
||||
"Nie mo<6D>na stworzy<7A> pliku '%-.64s' (Kod b<><62>du: %d)",
|
||||
"Nie mo<6D>na stworzy<7A> tabeli '%-.64s' (Kod b<><62>du: %d)",
|
||||
"Nie mo<6D>na stworzy<7A> bazy danych '%-.64s'. B<>?d %d",
|
||||
|
@ -31,8 +31,8 @@ static TABLE_LIST *rename_tables(THD *thd, TABLE_LIST *table_list,
|
||||
|
||||
bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list)
|
||||
{
|
||||
bool error=1,got_all_locks=1;
|
||||
TABLE_LIST *lock_table,*ren_table=0;
|
||||
bool error=1;
|
||||
TABLE_LIST *ren_table=0;
|
||||
DBUG_ENTER("mysql_rename_tables");
|
||||
|
||||
/*
|
||||
@ -47,23 +47,11 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list)
|
||||
}
|
||||
|
||||
VOID(pthread_mutex_lock(&LOCK_open));
|
||||
for (lock_table=table_list ; lock_table ; lock_table=lock_table->next)
|
||||
{
|
||||
int got_lock;
|
||||
if ((got_lock=lock_table_name(thd,lock_table)) < 0)
|
||||
goto end;
|
||||
if (got_lock)
|
||||
got_all_locks=0;
|
||||
}
|
||||
if (lock_table_names(thd, table_list))
|
||||
goto err;
|
||||
|
||||
if (!got_all_locks && wait_for_locked_table_names(thd,table_list))
|
||||
goto end;
|
||||
|
||||
if (!(ren_table=rename_tables(thd,table_list,0)))
|
||||
error= 0;
|
||||
|
||||
end:
|
||||
if (ren_table)
|
||||
if ((ren_table=rename_tables(thd,table_list,0)))
|
||||
{
|
||||
/* Rename didn't succeed; rename back the tables in reverse order */
|
||||
TABLE_LIST *prev=0,*table;
|
||||
@ -85,7 +73,7 @@ end:
|
||||
table=table->next->next; // Skip error table
|
||||
/* Revert to old names */
|
||||
rename_tables(thd, table, 1);
|
||||
/* Note that lock_table == 0 here, so the unlock loop will work */
|
||||
error= 1;
|
||||
}
|
||||
|
||||
/* Lets hope this doesn't fail as the result will be messy */
|
||||
@ -100,9 +88,9 @@ end:
|
||||
send_ok(&thd->net);
|
||||
}
|
||||
|
||||
for (TABLE_LIST *table=table_list ; table != lock_table ; table=table->next)
|
||||
unlock_table_name(thd,table);
|
||||
pthread_cond_broadcast(&COND_refresh);
|
||||
unlock_table_names(thd,table_list);
|
||||
|
||||
err:
|
||||
pthread_mutex_unlock(&LOCK_open);
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
@ -131,7 +119,7 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
|
||||
if (!access(name,F_OK))
|
||||
{
|
||||
my_error(ER_TABLE_EXISTS_ERROR,MYF(0),name);
|
||||
DBUG_RETURN(ren_table); // This can't be skipped
|
||||
DBUG_RETURN(ren_table); // This can't be skiped
|
||||
}
|
||||
sprintf(name,"%s/%s/%s%s",mysql_data_home,
|
||||
ren_table->db,ren_table->real_name,
|
||||
|
@ -3330,6 +3330,7 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value)
|
||||
== Item_func::COND_AND_FUNC;
|
||||
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
|
||||
Item::cond_result tmp_cond_value;
|
||||
bool should_fix_fields=0;
|
||||
|
||||
*cond_value=Item::COND_UNDEF;
|
||||
Item *item;
|
||||
@ -3349,6 +3350,7 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value)
|
||||
delete item; // This may be shared
|
||||
#endif
|
||||
VOID(li.replace(new_item));
|
||||
should_fix_fields=1;
|
||||
}
|
||||
if (*cond_value == Item::COND_UNDEF)
|
||||
*cond_value=tmp_cond_value;
|
||||
@ -3375,6 +3377,9 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value)
|
||||
break; /* purecov: deadcode */
|
||||
}
|
||||
}
|
||||
if (should_fix_fields)
|
||||
cond->fix_fields(current_thd,0);
|
||||
|
||||
if (!((Item_cond*) cond)->argument_list()->elements ||
|
||||
*cond_value != Item::COND_OK)
|
||||
return (COND*) 0;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
|
||||
/* Copyright (C) 2000-2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -80,7 +80,6 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists)
|
||||
{
|
||||
my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE,MYF(0),
|
||||
tables->real_name);
|
||||
error = 1;
|
||||
goto err;
|
||||
}
|
||||
while (global_read_lock && ! thd->killed)
|
||||
@ -93,7 +92,6 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists)
|
||||
|
||||
err:
|
||||
pthread_mutex_unlock(&LOCK_open);
|
||||
VOID(pthread_cond_broadcast(&COND_refresh)); // Signal to refresh
|
||||
|
||||
pthread_mutex_lock(&thd->mysys_var->mutex);
|
||||
thd->mysys_var->current_mutex= 0;
|
||||
@ -138,7 +136,6 @@ int mysql_rm_table_part2_with_lock(THD *thd,
|
||||
error=mysql_rm_table_part2(thd,tables, if_exists, dont_log_query);
|
||||
|
||||
pthread_mutex_unlock(&LOCK_open);
|
||||
VOID(pthread_cond_broadcast(&COND_refresh)); // Signal to refresh
|
||||
|
||||
pthread_mutex_lock(&thd->mysys_var->mutex);
|
||||
thd->mysys_var->current_mutex= 0;
|
||||
@ -171,6 +168,9 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
|
||||
bool some_tables_deleted=0, tmp_table_deleted=0;
|
||||
DBUG_ENTER("mysql_rm_table_part2");
|
||||
|
||||
if (lock_table_names(thd, tables))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
for (table=tables ; table ; table=table->next)
|
||||
{
|
||||
char *db=table->db ? table->db : thd->db;
|
||||
@ -242,6 +242,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
|
||||
}
|
||||
}
|
||||
|
||||
unlock_table_names(thd, tables);
|
||||
error= 0;
|
||||
if (wrong_tables.length())
|
||||
{
|
||||
|
Reference in New Issue
Block a user