diff options
author | unknown <sasha@mysql.sashanet.com> | 2001-06-21 15:59:51 -0600 |
---|---|---|
committer | unknown <sasha@mysql.sashanet.com> | 2001-06-21 15:59:51 -0600 |
commit | a7fa56c1736a19ae968bdf536e563a86bcb17c61 (patch) | |
tree | f90722a876cbb527957b82b81c5f4ebc17aa7864 | |
parent | 066eddd86208ff7aff062efce1957a66618de854 (diff) | |
download | mariadb-git-a7fa56c1736a19ae968bdf536e563a86bcb17c61.tar.gz |
fixed drop/create database bug when holding global read lock
preserve originating server id in Intvar events to avoid inifinite loops
include/mysqld_error.h:
new error messages
mysql-test/r/drop.result:
updated result
mysql-test/r/flush.result:
updated result
mysql-test/t/drop.test:
test for proper handling of drop/create database when holding
global read lock
mysql-test/t/flush.test:
test to see if other thread would block on drop database if we
are holding global read lock
sql/log.cc:
preserve originating server id in Intvar log event
sql/share/czech/errmsg.txt:
new error messages
sql/share/danish/errmsg.txt:
new error messages
sql/share/dutch/errmsg.txt:
new error messages
sql/share/english/errmsg.txt:
new error messages
sql/share/estonian/errmsg.txt:
new error messages
sql/share/french/errmsg.txt:
new error messages
sql/share/german/errmsg.txt:
new error messages
sql/share/greek/errmsg.txt:
new error messages
sql/share/hungarian/errmsg.txt:
new error messages
sql/share/italian/errmsg.txt:
new error messages
sql/share/japanese/errmsg.txt:
new error messages
sql/share/korean/errmsg.txt:
new error messages
sql/share/norwegian-ny/errmsg.txt:
new error messages
sql/share/norwegian/errmsg.txt:
new error messages
sql/share/polish/errmsg.txt:
new error messages
sql/share/portuguese/errmsg.txt:
new error messages
sql/share/romanian/errmsg.txt:
new error messages
sql/share/russian/errmsg.txt:
new error messages
sql/share/slovak/errmsg.txt:
new error messages
sql/share/spanish/errmsg.txt:
new error messages
sql/share/swedish/errmsg.txt:
new error messages
sql/slave.cc:
fixed typo in comment
sql/sql_db.cc:
global read lock should block drop/create database
29 files changed, 133 insertions, 2 deletions
diff --git a/include/mysqld_error.h b/include/mysqld_error.h index e412f95a8e4..cfcf7672013 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -208,4 +208,6 @@ #define ER_LOCK_WAIT_TIMEOUT 1205 #define ER_LOCK_TABLE_FULL 1206 #define ER_READ_ONLY_TRANSACTION 1207 -#define ER_ERROR_MESSAGES 208 +#define ER_DROP_DB_WITH_READ_LOCK 1208 +#define ER_CREATE_DB_WITH_READ_LOCK 1209 +#define ER_ERROR_MESSAGES 210 diff --git a/mysql-test/r/drop.result b/mysql-test/r/drop.result index 67923fe903c..c7a4ca9e0d2 100644 --- a/mysql-test/r/drop.result +++ b/mysql-test/r/drop.result @@ -1,2 +1,9 @@ n 1 +Database +foo +mysql +test +Database +mysql +test diff --git a/mysql-test/r/flush.result b/mysql-test/r/flush.result index e34f4f67195..fca84de710c 100644 --- a/mysql-test/r/flush.result +++ b/mysql-test/r/flush.result @@ -1,4 +1,6 @@ n 3 n +23 +n 345 diff --git a/mysql-test/t/drop.test b/mysql-test/t/drop.test index 1de387f6e4c..8f9aa852e8b 100644 --- a/mysql-test/t/drop.test +++ b/mysql-test/t/drop.test @@ -10,3 +10,16 @@ insert into t1 values(2); create table t1(n int); drop table t1; select * from t1; +drop database if exists foo; +flush tables with read lock; +--error 1209 +create database foo; +unlock tables; +create database foo; +show databases; +flush tables with read lock; +--error 1208 +drop database foo; +unlock tables; +drop database foo; +show databases; diff --git a/mysql-test/t/flush.test b/mysql-test/t/flush.test index b7293307605..4491de1f82b 100644 --- a/mysql-test/t/flush.test +++ b/mysql-test/t/flush.test @@ -33,6 +33,21 @@ unlock tables; connection con1; reap; +#test if drop database will wait until we release the global read lock +connection con1; +drop database if exists foo; +create database foo; +create table foo.t1(n int); +insert into foo.t1 values (23); +flush tables with read lock; +connection con2; +send drop database foo; +connection con1; +select * from foo.t1; +unlock tables; +connection con2; +reap; + # test if dirty close releases global read lock connection con1; create table t1 (n int); diff --git a/sql/log.cc b/sql/log.cc index 4cd93261973..1654f711af8 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -652,12 +652,16 @@ bool MYSQL_LOG::write(Query_log_event* event_info) if (thd->last_insert_id_used) { Intvar_log_event e((uchar)LAST_INSERT_ID_EVENT, thd->last_insert_id); + if(thd->server_id) + e.server_id = thd->server_id; if (e.write(file)) goto err; } if (thd->insert_id_used) { Intvar_log_event e((uchar)INSERT_ID_EVENT, thd->last_insert_id); + if(thd->server_id) + e.server_id = thd->server_id; if (e.write(file)) goto err; } diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index 35a428273c7..6d35e913ffd 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -218,3 +218,5 @@ "Lock wait timeout exceeded", "The total number of locks exceeds the lock table size", "Update locks cannot be acquired during a READ UNCOMMITTED transaction", +"DROP DATABASE not allowed while thread is holding global read lock", +"CREATE DATABASE not allowed while thread is holding global read lock", diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index b2fe6c4e800..d1e0ea71175 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -212,3 +212,5 @@ "Lock wait timeout exceeded", "The total number of locks exceeds the lock table size", "Update locks cannot be acquired during a READ UNCOMMITTED transaction", +"DROP DATABASE not allowed while thread is holding global read lock", +"CREATE DATABASE not allowed while thread is holding global read lock", diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 616f832bee8..7ae6c564283 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -209,3 +209,5 @@ "Lock wait timeout exceeded", "The total number of locks exceeds the lock table size", "Update locks cannot be acquired during a READ UNCOMMITTED transaction", +"DROP DATABASE not allowed while thread is holding global read lock", +"CREATE DATABASE not allowed while thread is holding global read lock", diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 018d558d7de..2a6e23b6281 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -209,3 +209,5 @@ "Lock wait timeout exceeded", "The total number of locks exceeds the lock table size", "Update locks cannot be acquired during a READ UNCOMMITTED transaction", +"DROP DATABASE not allowed while thread is holding global read lock", +"CREATE DATABASE not allowed while thread is holding global read lock", diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index e1e03e4a596..264badebe38 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -213,3 +213,5 @@ "Lock wait timeout exceeded", "The total number of locks exceeds the lock table size", "Update locks cannot be acquired during a READ UNCOMMITTED transaction", +"DROP DATABASE not allowed while thread is holding global read lock", +"CREATE DATABASE not allowed while thread is holding global read lock", diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index aadfecbc8a1..0da5cf94ed8 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -209,3 +209,5 @@ "Lock wait timeout exceeded", "The total number of locks exceeds the lock table size", "Update locks cannot be acquired during a READ UNCOMMITTED transaction", +"DROP DATABASE not allowed while thread is holding global read lock", +"CREATE DATABASE not allowed while thread is holding global read lock", diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index 2f41fbf30c2..9abbb3a8a2f 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -212,3 +212,5 @@ "Lock wait timeout exceeded", "The total number of locks exceeds the lock table size", "Update locks cannot be acquired during a READ UNCOMMITTED transaction", +"DROP DATABASE not allowed while thread is holding global read lock", +"CREATE DATABASE not allowed while thread is holding global read lock", diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 5022bb65792..8f81fcfda31 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -209,3 +209,5 @@ "Lock wait timeout exceeded", "The total number of locks exceeds the lock table size", "Update locks cannot be acquired during a READ UNCOMMITTED transaction", +"DROP DATABASE not allowed while thread is holding global read lock", +"CREATE DATABASE not allowed while thread is holding global read lock", diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index cfdd4b7fe75..84d8c56cd04 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -211,3 +211,5 @@ "Lock wait timeout exceeded", "The total number of locks exceeds the lock table size", "Update locks cannot be acquired during a READ UNCOMMITTED transaction", +"DROP DATABASE not allowed while thread is holding global read lock", +"CREATE DATABASE not allowed while thread is holding global read lock", diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index d1b17bc8f2e..ab31fa279c4 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -209,3 +209,5 @@ "Lock wait timeout exceeded", "The total number of locks exceeds the lock table size", "Update locks cannot be acquired during a READ UNCOMMITTED transaction", +"DROP DATABASE not allowed while thread is holding global read lock", +"CREATE DATABASE not allowed while thread is holding global read lock", diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 9dfe9bb3efb..49e58079588 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -211,3 +211,5 @@ "Lock wait timeout exceeded", "The total number of locks exceeds the lock table size", "Update locks cannot be acquired during a READ UNCOMMITTED transaction", +"DROP DATABASE not allowed while thread is holding global read lock", +"CREATE DATABASE not allowed while thread is holding global read lock", diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 4f0f90f88ce..2e278dbd129 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -209,3 +209,5 @@ "Lock wait timeout exceeded", "The total number of locks exceeds the lock table size", "Update locks cannot be acquired during a READ UNCOMMITTED transaction", +"DROP DATABASE not allowed while thread is holding global read lock", +"CREATE DATABASE not allowed while thread is holding global read lock", diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index 99238d61e3e..df9efbd28a4 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -211,3 +211,5 @@ "Lock wait timeout exceeded", "The total number of locks exceeds the lock table size", "Update locks cannot be acquired during a READ UNCOMMITTED transaction", +"DROP DATABASE not allowed while thread is holding global read lock", +"CREATE DATABASE not allowed while thread is holding global read lock", diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 473d297b649..c95669aa016 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -211,3 +211,5 @@ "Lock wait timeout exceeded", "The total number of locks exceeds the lock table size", "Update locks cannot be acquired during a READ UNCOMMITTED transaction", +"DROP DATABASE not allowed while thread is holding global read lock", +"CREATE DATABASE not allowed while thread is holding global read lock", diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 253d4afd2b7..d708bc6fffb 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -213,3 +213,5 @@ "Lock wait timeout exceeded", "The total number of locks exceeds the lock table size", "Update locks cannot be acquired during a READ UNCOMMITTED transaction", +"DROP DATABASE not allowed while thread is holding global read lock", +"CREATE DATABASE not allowed while thread is holding global read lock", diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index a1247a1f1b3..b1cab63c0a0 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -209,3 +209,5 @@ "Lock wait timeout exceeded", "The total number of locks exceeds the lock table size", "Update locks cannot be acquired during a READ UNCOMMITTED transaction", +"DROP DATABASE not allowed while thread is holding global read lock", +"CREATE DATABASE not allowed while thread is holding global read lock", diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 384df0c864e..8069f9907bb 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -213,3 +213,5 @@ "Lock wait timeout exceeded", "The total number of locks exceeds the lock table size", "Update locks cannot be acquired during a READ UNCOMMITTED transaction", +"DROP DATABASE not allowed while thread is holding global read lock", +"CREATE DATABASE not allowed while thread is holding global read lock", diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index 7dd24c743bb..6bc845d5599 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -212,3 +212,5 @@ "Lock wait timeout exceeded", "The total number of locks exceeds the lock table size", "Update locks cannot be acquired during a READ UNCOMMITTED transaction", +"DROP DATABASE not allowed while thread is holding global read lock", +"CREATE DATABASE not allowed while thread is holding global read lock", diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 2a6063b6aee..8631ee6bdeb 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -217,3 +217,5 @@ "Lock wait timeout exceeded", "The total number of locks exceeds the lock table size", "Update locks cannot be acquired during a READ UNCOMMITTED transaction", +"DROP DATABASE not allowed while thread is holding global read lock", +"CREATE DATABASE not allowed while thread is holding global read lock", diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index dbf7caf585d..ea97a282c83 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -210,3 +210,5 @@ "Lock wait timeout exceeded", "The total number of locks exceeds the lock table size", "Update locks cannot be acquired during a READ UNCOMMITTED transaction", +"DROP DATABASE not allowed while thread is holding global read lock", +"CREATE DATABASE not allowed while thread is holding global read lock", diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index fc26a08e9ee..7f43afd04b6 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -209,3 +209,5 @@ "Lock wait timeout exceeded", "The total number of locks exceeds the lock table size", "Update locks cannot be acquired during a READ UNCOMMITTED transaction", +"DROP DATABASE not allowed while thread is holding global read lock", +"CREATE DATABASE not allowed while thread is holding global read lock", diff --git a/sql/slave.cc b/sql/slave.cc index 5f3f37d2cb8..a768e8494a0 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1367,7 +1367,7 @@ the slave thread with \"mysqladmin start-slave\". We stopped at log \ { // show a little mercy, allow slave to read one more event // before cutting him off - otherwise he gets stuck - // on Invar events, since they do not advance the offset + // on Intvar events, since they do not advance the offset // immediately if (++stuck_count > 2) events_till_disconnect++; diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 5243498f7fc..7cd892f6079 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -38,6 +38,32 @@ void mysql_create_db(THD *thd, char *db, uint create_options) DBUG_ENTER("mysql_create_db"); VOID(pthread_mutex_lock(&LOCK_mysql_create_db)); + VOID(pthread_mutex_lock(&LOCK_open)); + + // do not create database if another thread is holding read lock + if (global_read_lock) + { + if (thd->global_read_lock) + { + net_printf(&thd->net, ER_CREATE_DB_WITH_READ_LOCK); + VOID(pthread_mutex_unlock(&LOCK_open)); + goto exit; + } + while (global_read_lock && ! thd->killed) + { + (void) pthread_cond_wait(&COND_refresh,&LOCK_open); + } + + if (thd->killed) + { + net_printf(&thd->net, ER_SERVER_SHUTDOWN); + VOID(pthread_mutex_unlock(&LOCK_open)); + goto exit; + } + + } + + VOID(pthread_mutex_unlock(&LOCK_open)); /* Check directory */ (void)sprintf(path,"%s/%s", mysql_data_home, db); @@ -105,6 +131,26 @@ void mysql_rm_db(THD *thd,char *db,bool if_exists) VOID(pthread_mutex_lock(&LOCK_mysql_create_db)); VOID(pthread_mutex_lock(&LOCK_open)); + // do not drop database if another thread is holding read lock + if (global_read_lock) + { + if (thd->global_read_lock) + { + net_printf(&thd->net, ER_DROP_DB_WITH_READ_LOCK); + goto exit; + } + while (global_read_lock && ! thd->killed) + { + (void) pthread_cond_wait(&COND_refresh,&LOCK_open); + } + + if (thd->killed) + { + net_printf(&thd->net, ER_SERVER_SHUTDOWN); + goto exit; + } + } + (void) sprintf(path,"%s/%s",mysql_data_home,db); unpack_dirname(path,path); // Convert if not unix /* See if the directory exists */ |