Below is the list of changes that have just been committed into a local
5.1 repository of davi. When davi does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2007-11-30 11:58:00-02:00, davi@stripped +21 -0
Bug#32395 Alter table under a impending global read lock causes a server crash
** FOR INTERNAL REVIEW ONLY **
The problem is that some DDS statements when under LOCK TABLES
need to momentarily drop the lock, reopen the table and grab
the write lock again (using reopen_tables). When grabbing the
lock again, reopen_tables doesn't pass a flag to mysql_lock_tables
in order to ignore the impending global read lock, which causes
a assertion because LOCK_open is being hold. Also dropping the
lock must not signal the flush thread that the table has been
relinquished (related to the locking/flushing protocol).
The solution is to correct the way the table is reopenned and
the locks grabbed. When reopening the table and under LOCK
TABLES, the table version should be set to 0 so other threads
have to wait for the table. When grabbing the lock, any other
flush should be ignored because it's theoretically a atomic
operation.
mysql-test/r/group_by.result@stripped, 2007-11-30 11:57:55-02:00, davi@stripped +2 -0
Backport fix for bug 25858.
mysql-test/r/insert_notembedded.result@stripped, 2007-11-30 11:57:55-02:00, davi@stripped +1 -0
Backport fix for bug 25858.
mysql-test/r/lock.result@stripped, 2007-11-30 11:57:55-02:00, davi@stripped +6 -0
Backport fix for bug 25858.
mysql-test/r/lock_multi.result@stripped, 2007-11-30 11:57:55-02:00, davi@stripped +1 -0
Backport fix for bug 25858.
mysql-test/r/myisam.result@stripped, 2007-11-30 11:57:55-02:00, davi@stripped +2 -0
Backport fix for bug 25858.
mysql-test/r/not_embedded_server.result@stripped, 2007-11-30 11:57:55-02:00, davi@stripped +29 -0
Add test case result for Bug#32395
mysql-test/r/query_cache_notembedded.result@stripped, 2007-11-30 11:57:55-02:00, davi@stripped +1 -0
Backport fix for bug 25858.
mysql-test/r/trigger_notembedded.result@stripped, 2007-11-30 11:57:55-02:00, davi@stripped +14 -0
Backport fix for bug 25858.
mysql-test/r/view.result@stripped, 2007-11-30 11:57:56-02:00, davi@stripped +3 -0
Backport fix for bug 25858.
mysql-test/t/group_by.test@stripped, 2007-11-30 11:57:56-02:00, davi@stripped +2 -1
Backport fix for bug 25858.
mysql-test/t/insert_notembedded.test@stripped, 2007-11-30 11:57:56-02:00, davi@stripped +1 -0
Backport fix for bug 25858.
mysql-test/t/lock.test@stripped, 2007-11-30 11:57:56-02:00, davi@stripped +6 -0
Backport fix for bug 25858.
mysql-test/t/lock_multi.test@stripped, 2007-11-30 11:57:56-02:00, davi@stripped +2 -1
Backport fix for bug 25858.
mysql-test/t/myisam.test@stripped, 2007-11-30 11:57:56-02:00, davi@stripped +2 -0
Backport fix for bug 25858.
mysql-test/t/not_embedded_server.test@stripped, 2007-11-30 11:57:56-02:00, davi@stripped +96 -0
Add test case for Bug#32395
mysql-test/t/query_cache_notembedded.test@stripped, 2007-11-30 11:57:56-02:00, davi@stripped +1 -0
Backport fix for bug 25858.
mysql-test/t/trigger_notembedded.test@stripped, 2007-11-30 11:57:56-02:00, davi@stripped +3 -3
Backport fix for bug 25858.
mysql-test/t/view.test@stripped, 2007-11-30 11:57:56-02:00, davi@stripped +3 -0
Backport fix for bug 25858.
sql/lock.cc@stripped, 2007-11-30 11:57:56-02:00, davi@stripped +34 -0
Backport fix for bug 25858.
sql/sql_base.cc@stripped, 2007-11-30 11:57:56-02:00, davi@stripped +19 -7
Preserve old version for write locked tables and ignore
pending flushes.
sql/sql_table.cc@stripped, 2007-11-30 11:57:57-02:00, davi@stripped +9 -6
Don't wait for the impending GRL if under LOCK TABLES.
diff -Nrup a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result
--- a/mysql-test/r/group_by.result 2007-11-10 17:27:30 -02:00
+++ b/mysql-test/r/group_by.result 2007-11-30 11:57:55 -02:00
@@ -108,7 +108,9 @@ cid CONCAT(firstname, ' ', surname) COUN
SELECT HIGH_PRIORITY cid, CONCAT(firstname, ' ', surname), COUNT(call_id) FROM t1 LEFT JOIN t2 ON cid=contact_id WHERE firstname like '%foo%' GROUP BY cid ORDER BY surname, firstname;
cid CONCAT(firstname, ' ', surname) COUNT(call_id)
drop table t1,t2;
+ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
unlock tables;
+drop table t1,t2;
CREATE TABLE t1 (
bug_id mediumint(9) NOT NULL auto_increment,
groupset bigint(20) DEFAULT '0' NOT NULL,
diff -Nrup a/mysql-test/r/insert_notembedded.result b/mysql-test/r/insert_notembedded.result
--- a/mysql-test/r/insert_notembedded.result 2007-09-06 13:22:31 -03:00
+++ b/mysql-test/r/insert_notembedded.result 2007-11-30 11:57:55 -02:00
@@ -122,5 +122,6 @@ a b
connection: default
select * from t1;
a b
+unlock tables;
drop table t1;
set low_priority_updates=default;
diff -Nrup a/mysql-test/r/lock.result b/mysql-test/r/lock.result
--- a/mysql-test/r/lock.result 2007-08-02 06:59:00 -03:00
+++ b/mysql-test/r/lock.result 2007-11-30 11:57:55 -02:00
@@ -48,6 +48,9 @@ unlock tables;
lock tables t1 write, t1 as t1_alias read;
insert into t1 select index1,nr from t1 as t1_alias;
drop table t1,t2;
+ERROR HY000: Table 't2' was not locked with LOCK TABLES
+unlock tables;
+drop table t1,t2;
create table t1 (c1 int);
create table t2 (c1 int);
create table t3 (c1 int);
@@ -69,6 +72,9 @@ ERROR HY000: Table 't2' was locked with
delete t2 from t1,t2 where t1.a=t2.a;
ERROR HY000: Table 't2' was locked with a READ lock and can't be updated
drop table t1,t2;
+ERROR HY000: Table 't2' was locked with a READ lock and can't be updated
+unlock tables;
+drop table t2,t1;
End of 4.1 tests.
drop table if exists t1;
create table t1 (a int);
diff -Nrup a/mysql-test/r/lock_multi.result b/mysql-test/r/lock_multi.result
--- a/mysql-test/r/lock_multi.result 2007-11-28 12:33:33 -02:00
+++ b/mysql-test/r/lock_multi.result 2007-11-30 11:57:55 -02:00
@@ -27,6 +27,7 @@ update t1,t2 set c=a where b=d;
select c from t2;
c
2
+unlock tables;
drop table t1;
drop table t2;
create table t1 (a int);
diff -Nrup a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result
--- a/mysql-test/r/myisam.result 2007-11-15 17:25:40 -02:00
+++ b/mysql-test/r/myisam.result 2007-11-30 11:57:55 -02:00
@@ -529,6 +529,7 @@ select straight_join * from t1,t2 force
a a b
1 1 1
2 2 1
+unlock tables;
drop table t1,t2;
CREATE TABLE t1 (c1 varchar(250) NOT NULL);
CREATE TABLE t2 (c1 varchar(250) NOT NULL, PRIMARY KEY (c1));
@@ -542,6 +543,7 @@ INSERT INTO t2 VALUES ('test000001'), ('
SELECT t1.c1 AS t1c1, t2.c1 AS t2c1 FROM t1, t2
WHERE t1.c1 = t2.c1 HAVING t1c1 != t2c1;
t1c1 t2c1
+UNLOCK TABLES;
DROP TABLE t1,t2;
CREATE TABLE t1 (`a` int(11) NOT NULL default '0', `b` int(11) NOT NULL default '0', UNIQUE KEY `a` USING RTREE (`a`,`b`)) ENGINE=MyISAM;
Got one of the listed errors
diff -Nrup a/mysql-test/r/not_embedded_server.result b/mysql-test/r/not_embedded_server.result
--- a/mysql-test/r/not_embedded_server.result 2006-09-06 09:32:43 -03:00
+++ b/mysql-test/r/not_embedded_server.result 2007-11-30 11:57:55 -02:00
@@ -3,3 +3,32 @@ execute stmt1;
ID USER HOST DB COMMAND TIME STATE INFO
number root localhost test Query time preparing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST WHERE COMMAND!='Daemon'
deallocate prepare stmt1;
+drop table if exists t1;
+create table t1 (i int);
+connection: default
+lock tables t1 write;
+connection: flush
+flush tables with read lock;;
+connection: default
+alter table t1 add column j int;
+connection: insert
+insert into t1 values (1,2);;
+connection: default
+unlock tables;
+connection: flush
+select * from t1;
+i j
+unlock tables;
+select * from t1;
+i j
+1 2
+drop table t1;
+drop table if exists t1;
+create table t1 (i int);
+connection: default
+lock tables t1 write;
+connection: flush
+flush tables with read lock;;
+connection: default
+flush tables;
+drop table t1;
diff -Nrup a/mysql-test/r/query_cache_notembedded.result b/mysql-test/r/query_cache_notembedded.result
--- a/mysql-test/r/query_cache_notembedded.result 2007-10-16 10:42:40 -02:00
+++ b/mysql-test/r/query_cache_notembedded.result 2007-11-30 11:57:55 -02:00
@@ -93,6 +93,7 @@ a
3
SELECT * FROM t1;
a
+UNLOCK TABLES;
drop table t1;
flush query cache;
reset query cache;
diff -Nrup a/mysql-test/r/trigger_notembedded.result b/mysql-test/r/trigger_notembedded.result
--- a/mysql-test/r/trigger_notembedded.result 2007-11-29 09:42:23 -02:00
+++ b/mysql-test/r/trigger_notembedded.result 2007-11-30 11:57:55 -02:00
@@ -448,4 +448,18 @@ DROP TABLE t1;
DROP DATABASE mysqltest_db1;
USE test;
End of 5.0 tests.
+drop table if exists t1;
+create table t1 (i int);
+connection: default
+lock tables t1 write;
+connection: flush
+flush tables with read lock;;
+connection: default
+create trigger t1_bi before insert on t1 for each row begin end;
+unlock tables;
+connection: flush
+unlock tables;
+select * from t1;
+i
+drop table t1;
End of 5.1 tests.
diff -Nrup a/mysql-test/r/view.result b/mysql-test/r/view.result
--- a/mysql-test/r/view.result 2007-10-10 07:22:19 -02:00
+++ b/mysql-test/r/view.result 2007-11-30 11:57:56 -02:00
@@ -1104,6 +1104,9 @@ select * from t2;
ERROR HY000: Table 't2' was not locked with LOCK TABLES
drop view v1;
drop table t1, t2;
+ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
+unlock tables;
+drop table t1, t2;
create table t1 (a int);
create view v1 as select * from t1 where a < 2 with check option;
insert into v1 values(1);
diff -Nrup a/mysql-test/t/group_by.test b/mysql-test/t/group_by.test
--- a/mysql-test/t/group_by.test 2007-11-10 17:27:30 -02:00
+++ b/mysql-test/t/group_by.test 2007-11-30 11:57:56 -02:00
@@ -119,9 +119,10 @@ INSERT INTO t2 VALUES (92,2);
SELECT cid, CONCAT(firstname, ' ', surname), COUNT(call_id) FROM t1 LEFT JOIN t2 ON cid=contact_id WHERE firstname like '%foo%' GROUP BY cid;
SELECT cid, CONCAT(firstname, ' ', surname), COUNT(call_id) FROM t1 LEFT JOIN t2 ON cid=contact_id WHERE firstname like '%foo%' GROUP BY cid ORDER BY NULL;
SELECT HIGH_PRIORITY cid, CONCAT(firstname, ' ', surname), COUNT(call_id) FROM t1 LEFT JOIN t2 ON cid=contact_id WHERE firstname like '%foo%' GROUP BY cid ORDER BY surname, firstname;
-
+--error ER_TABLE_NOT_LOCKED_FOR_WRITE
drop table t1,t2;
unlock tables;
+drop table t1,t2;
#
# Test of group by bug in bugzilla
diff -Nrup a/mysql-test/t/insert_notembedded.test b/mysql-test/t/insert_notembedded.test
--- a/mysql-test/t/insert_notembedded.test 2007-09-06 13:22:31 -03:00
+++ b/mysql-test/t/insert_notembedded.test 2007-11-30 11:57:56 -02:00
@@ -185,5 +185,6 @@ select * from t1;
connection default;
disconnect update;
disconnect select;
+unlock tables;
drop table t1;
set low_priority_updates=default;
diff -Nrup a/mysql-test/t/lock.test b/mysql-test/t/lock.test
--- a/mysql-test/t/lock.test 2007-08-02 06:59:00 -03:00
+++ b/mysql-test/t/lock.test 2007-11-30 11:57:56 -02:00
@@ -58,6 +58,9 @@ insert into t1 select index1,nr from t1;
unlock tables;
lock tables t1 write, t1 as t1_alias read;
insert into t1 select index1,nr from t1 as t1_alias;
+--error ER_TABLE_NOT_LOCKED
+drop table t1,t2;
+unlock tables;
drop table t1,t2;
#
@@ -90,7 +93,10 @@ delete t1 from t1,t2 where t1.a=t2.a;
delete from t2 using t1,t2 where t1.a=t2.a;
--error 1099
delete t2 from t1,t2 where t1.a=t2.a;
+--error ER_TABLE_NOT_LOCKED_FOR_WRITE
drop table t1,t2;
+unlock tables;
+drop table t2,t1;
--echo End of 4.1 tests.
diff -Nrup a/mysql-test/t/lock_multi.test b/mysql-test/t/lock_multi.test
--- a/mysql-test/t/lock_multi.test 2007-11-28 12:33:39 -02:00
+++ b/mysql-test/t/lock_multi.test 2007-11-30 11:57:56 -02:00
@@ -68,6 +68,7 @@ update t1,t2 set c=a where b=d;
connection reader;
select c from t2;
connection locker;
+unlock tables;
drop table t1;
drop table t2;
@@ -150,7 +151,7 @@ send SELECT user.Select_priv FROM user,
connection locker;
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Locked" and info =
+ where state = "Waiting for table" and info =
"SELECT user.Select_priv FROM user, db WHERE user.user = db.user LIMIT 1";
--source include/wait_condition.inc
# Make test case independent from earlier grants.
diff -Nrup a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test
--- a/mysql-test/t/myisam.test 2007-11-15 17:25:40 -02:00
+++ b/mysql-test/t/myisam.test 2007-11-30 11:57:56 -02:00
@@ -503,6 +503,7 @@ insert into t2 values(2,0);
disconnect root;
connection default;
select straight_join * from t1,t2 force index (primary) where t1.a=t2.a;
+unlock tables;
drop table t1,t2;
#
# Full key.
@@ -520,6 +521,7 @@ disconnect con1;
connection default;
SELECT t1.c1 AS t1c1, t2.c1 AS t2c1 FROM t1, t2
WHERE t1.c1 = t2.c1 HAVING t1c1 != t2c1;
+UNLOCK TABLES;
DROP TABLE t1,t2;
# End of 4.0 tests
diff -Nrup a/mysql-test/t/not_embedded_server.test b/mysql-test/t/not_embedded_server.test
--- a/mysql-test/t/not_embedded_server.test 2006-08-15 08:10:07 -03:00
+++ b/mysql-test/t/not_embedded_server.test 2007-11-30 11:57:56 -02:00
@@ -20,4 +20,100 @@ prepare stmt1 from ' SELECT * FROM INFOR
execute stmt1;
deallocate prepare stmt1;
+#
+# Bug#32395 Alter table under a impending global read lock causes a server crash
+#
+
+#
+# Test ALTER TABLE under LOCK TABLES and FLUSH TABLES WITH READ LOCK
+#
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (i int);
+connect (flush,localhost,root,,test,,);
+connection default;
+--echo connection: default
+lock tables t1 write;
+connection flush;
+--echo connection: flush
+--send flush tables with read lock;
+connection default;
+--echo connection: default
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Flushing tables";
+--source include/wait_condition.inc
+alter table t1 add column j int;
+connect (insert,localhost,root,,test,,);
+connection insert;
+--echo connection: insert
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Flushing tables";
+--source include/wait_condition.inc
+--send insert into t1 values (1,2);
+--echo connection: default
+connection default;
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for release of readlock";
+--source include/wait_condition.inc
+unlock tables;
+connection flush;
+--echo connection: flush
+--reap
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for release of readlock";
+--source include/wait_condition.inc
+select * from t1;
+unlock tables;
+connection insert;
+--reap
+connection default;
+select * from t1;
+drop table t1;
+disconnect flush;
+disconnect insert;
+
+#
+# Test that FLUSH TABLES under LOCK TABLES protects write locked tables
+# from a impending FLUSH TABLES WITH READ LOCK
+#
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (i int);
+connect (flush,localhost,root,,test,,);
+connection default;
+--echo connection: default
+lock tables t1 write;
+connection flush;
+--echo connection: flush
+--send flush tables with read lock;
+connection default;
+--echo connection: default
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Flushing tables";
+--source include/wait_condition.inc
+connection default;
+flush tables;
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Flushing tables";
+--source include/wait_condition.inc
+drop table t1;
+let $wait_condition=
+ select count(*) = 0 from information_schema.processlist
+ where state = "Flushing tables";
+--source include/wait_condition.inc
+connection flush;
+--reap
+connection default;
+disconnect flush;
+
# End of 5.1 tests
diff -Nrup a/mysql-test/t/query_cache_notembedded.test b/mysql-test/t/query_cache_notembedded.test
--- a/mysql-test/t/query_cache_notembedded.test 2007-10-16 10:42:41 -02:00
+++ b/mysql-test/t/query_cache_notembedded.test 2007-11-30 11:57:56 -02:00
@@ -95,6 +95,7 @@ connection root2;
SELECT * FROM t1;
connection root;
SELECT * FROM t1;
+UNLOCK TABLES;
drop table t1;
#
diff -Nrup a/mysql-test/t/trigger_notembedded.test b/mysql-test/t/trigger_notembedded.test
--- a/mysql-test/t/trigger_notembedded.test 2007-11-29 09:42:23 -02:00
+++ b/mysql-test/t/trigger_notembedded.test 2007-11-30 11:57:56 -02:00
@@ -880,8 +880,9 @@ USE test;
# Bug#23713 LOCK TABLES + CREATE TRIGGER + FLUSH TABLES WITH READ LOCK = deadlock
#
-# Test temporarily disable due to Bug#32395
---disable_parsing
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
create table t1 (i int);
connect (flush,localhost,root,,test,,);
connection default;
@@ -906,6 +907,5 @@ connection default;
select * from t1;
drop table t1;
disconnect flush;
---enable_parsing
--echo End of 5.1 tests.
diff -Nrup a/mysql-test/t/view.test b/mysql-test/t/view.test
--- a/mysql-test/t/view.test 2007-10-10 05:37:04 -02:00
+++ b/mysql-test/t/view.test 2007-11-30 11:57:56 -02:00
@@ -1017,6 +1017,9 @@ select * from v1;
-- error 1100
select * from t2;
drop view v1;
+--error ER_TABLE_NOT_LOCKED_FOR_WRITE
+drop table t1, t2;
+unlock tables;
drop table t1, t2;
#
diff -Nrup a/sql/lock.cc b/sql/lock.cc
--- a/sql/lock.cc 2007-08-27 10:19:53 -03:00
+++ b/sql/lock.cc 2007-11-30 11:57:56 -02:00
@@ -1015,6 +1015,7 @@ int lock_table_name(THD *thd, TABLE_LIST
char key[MAX_DBKEY_LENGTH];
char *db= table_list->db;
uint key_length;
+ bool found_locked_table= FALSE;
HASH_SEARCH_STATE state;
DBUG_ENTER("lock_table_name");
DBUG_PRINT("enter",("db: %s name: %s", db, table_list->table_name));
@@ -1030,6 +1031,13 @@ int lock_table_name(THD *thd, TABLE_LIST
table = (TABLE*) hash_next(&open_cache,(uchar*) key,
key_length, &state))
{
+ if (table->reginfo.lock_type < TL_WRITE)
+ {
+ if (table->in_use == thd)
+ found_locked_table= TRUE;
+ continue;
+ }
+
if (table->in_use == thd)
{
DBUG_PRINT("info", ("Table is in use"));
@@ -1040,6 +1048,17 @@ int lock_table_name(THD *thd, TABLE_LIST
}
}
+ if (thd->locked_tables && thd->locked_tables->table_count &&
+ ! find_temporary_table(thd, table_list->db, table_list->table_name))
+ {
+ if (found_locked_table)
+ my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0), table_list->alias);
+ else
+ my_error(ER_TABLE_NOT_LOCKED, MYF(0), table_list->alias);
+
+ DBUG_RETURN(-1);
+ }
+
if (!(table= table_cache_insert_placeholder(thd, key, key_length)))
DBUG_RETURN(-1);
@@ -1474,6 +1493,21 @@ bool wait_if_global_read_lock(THD *thd,
deadlock.
*/
safe_mutex_assert_not_owner(&LOCK_open);
+
+#ifdef EXTRA_DEBUG
+ /*
+ Assert that we do not own any write locked table. If we own any,
+ we would deadlock with the thread requesting the global read lock.
+ */
+ if (thd->locked_tables && (must_wait && !thd->killed &&
+ (!abort_on_refresh || thd->version == refresh_version)))
+ {
+ for (TABLE *table=thd->open_tables; table ; table=table->next)
+ {
+ DBUG_ASSERT(table->reginfo.lock_type < TL_WRITE_LOW_PRIORITY);
+ }
+ }
+#endif
(void) pthread_mutex_lock(&LOCK_global_read_lock);
if ((need_exit_cond= must_wait))
diff -Nrup a/sql/sql_base.cc b/sql/sql_base.cc
--- a/sql/sql_base.cc 2007-11-29 09:42:23 -02:00
+++ b/sql/sql_base.cc 2007-11-30 11:57:56 -02:00
@@ -1037,7 +1037,16 @@ bool close_cached_tables(THD *thd, bool
thd->in_lock_tables=0;
/* Set version for table */
for (TABLE *table=thd->open_tables; table ; table= table->next)
- table->s->version= refresh_version;
+ {
+ /*
+ Preserve the version (0) of write locked tables so that a impending
+ global read lock won't sneak in, since in a lot of places across the
+ code it's assumed that the GRL can be ignored if the table is write
+ locked.
+ */
+ if (table->reginfo.lock_type < TL_WRITE_LOW_PRIORITY)
+ table->s->version= refresh_version;
+ }
}
if (!have_lock)
VOID(pthread_mutex_unlock(&LOCK_open));
@@ -2204,7 +2213,7 @@ void wait_for_condition(THD *thd, pthrea
current thread.
@param thd current thread context
- @param tables able list containing one table to open.
+ @param tables table list containing one table to open.
@return FALSE on success, TRUE otherwise.
*/
@@ -3272,8 +3281,7 @@ static bool reattach_merge(THD *thd, TAB
@param thd Thread context
@param get_locks Should we get locks after reopening tables ?
- @param in_refresh Are we in FLUSH TABLES ? TODO: It seems that
- we can remove this parameter.
+ @param mark_old Mark share as old
@note Since this function can't properly handle prelocking and
create placeholders it should be used in very special
@@ -3287,13 +3295,17 @@ static bool reattach_merge(THD *thd, TAB
@return FALSE in case of success, TRUE - otherwise.
*/
-bool reopen_tables(THD *thd,bool get_locks,bool in_refresh)
+bool reopen_tables(THD *thd, bool get_locks, bool mark_old)
{
TABLE *table,*next,**prev;
TABLE **tables,**tables_ptr; // For locks
TABLE *err_tables= NULL;
bool error=0, not_used;
bool merge_table_found= FALSE;
+ const uint flags= MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN |
+ MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK |
+ MYSQL_LOCK_IGNORE_FLUSH;
+
DBUG_ENTER("reopen_tables");
if (!thd->open_tables)
@@ -3354,7 +3366,7 @@ bool reopen_tables(THD *thd,bool get_loc
/* Do not handle locks of MERGE children. */
if (get_locks && !db_stat && !table->parent)
*tables_ptr++= table; // need new lock on this
- if (in_refresh)
+ if (mark_old)
{
table->s->version=0;
table->open_placeholder= 0;
@@ -3387,7 +3399,7 @@ bool reopen_tables(THD *thd,bool get_loc
*/
thd->some_tables_deleted=0;
if ((lock= mysql_lock_tables(thd, tables, (uint) (tables_ptr - tables),
- MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN, ¬_used)))
+ flags, ¬_used)))
{
thd->locked_tables=mysql_lock_merge(thd->locked_tables,lock);
}
diff -Nrup a/sql/sql_table.cc b/sql/sql_table.cc
--- a/sql/sql_table.cc 2007-11-29 09:42:24 -02:00
+++ b/sql/sql_table.cc 2007-11-30 11:57:57 -02:00
@@ -1406,7 +1406,6 @@ void write_bin_log(THD *thd, bool clear_
}
}
-
/*
delete (drop) tables.
@@ -1422,7 +1421,8 @@ void write_bin_log(THD *thd, bool clear_
If a table is in use, we will wait for all users to free the table
before dropping it
- Wait if global_read_lock (FLUSH TABLES WITH READ LOCK) is set.
+ Wait if global_read_lock (FLUSH TABLES WITH READ LOCK) is set, but
+ not if under LOCK TABLES.
RETURN
FALSE OK. In this case ok packet is sent to user
@@ -1440,13 +1440,16 @@ bool mysql_rm_table(THD *thd,TABLE_LIST
if (!drop_temporary)
{
- if ((error= wait_if_global_read_lock(thd, 0, 1)))
+ /*
+ lock_table_name will error out if under LOCK TABLES and the tables
+ are not write locked.
+ */
+ if (!thd->locked_tables &&
+ !(need_start_waiters= !wait_if_global_read_lock(thd, 0, 1)))
{
my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0), tables->table_name);
DBUG_RETURN(TRUE);
}
- else
- need_start_waiters= TRUE;
}
/*
@@ -6665,7 +6668,7 @@ view_err:
if (thd->locked_tables && new_name == table_name && new_db == db)
{
thd->in_lock_tables= 1;
- error= reopen_tables(thd, 1, 0);
+ error= reopen_tables(thd, 1, 1);
thd->in_lock_tables= 0;
if (error)
goto err_with_placeholders;
| Thread |
|---|
| • bk commit into 5.1 tree (davi:1.2672) BUG#32395 | Davi Arnaut | 30 Nov |