summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <ingo@mysql.com>2006-06-10 12:24:44 +0200
committerunknown <ingo@mysql.com>2006-06-10 12:24:44 +0200
commit2dd1dc62462a9b7348d1c815acacddedb5a62d88 (patch)
treeecb80e61dc5f282b391823c7a37a6ee02753cada /sql
parenta74154f4de0b4f3765eb06932fb9ec3e79f764e0 (diff)
parent8efe592d58f657800c7c4e00f2c85815f7ae03d8 (diff)
downloadmariadb-git-2dd1dc62462a9b7348d1c815acacddedb5a62d88.tar.gz
Merge mysql.com:/home/mydev/mysql-5.0
into mysql.com:/home/mydev/mysql-5.0-amerge mysql-test/r/lock_multi.result: Merging 5.0-engines to 5.0 master. mysql-test/t/lock_multi.test: Merging 5.0-engines to 5.0 master.
Diffstat (limited to 'sql')
-rw-r--r--sql/ha_myisammrg.h3
-rw-r--r--sql/sql_db.cc60
2 files changed, 48 insertions, 15 deletions
diff --git a/sql/ha_myisammrg.h b/sql/ha_myisammrg.h
index c762b7c286e..a73f368c51d 100644
--- a/sql/ha_myisammrg.h
+++ b/sql/ha_myisammrg.h
@@ -37,7 +37,8 @@ class ha_myisammrg: public handler
{
return (HA_REC_NOT_IN_SEQ | HA_AUTO_PART_KEY | HA_READ_RND_SAME |
HA_NULL_IN_KEY | HA_CAN_INDEX_BLOBS | HA_FILE_BASED |
- HA_CAN_INSERT_DELAYED | HA_ANY_INDEX_MAY_BE_UNIQUE);
+ HA_CAN_INSERT_DELAYED | HA_ANY_INDEX_MAY_BE_UNIQUE |
+ HA_CAN_BIT_FIELD);
}
ulong index_flags(uint inx, uint part, bool all_parts) const
{
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index 4caa0076c60..a52972753a7 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -424,16 +424,27 @@ bool mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info,
my_error(ER_DB_CREATE_EXISTS, MYF(0), db);
DBUG_RETURN(-1);
}
-
- VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
- /* do not create database if another thread is holding read lock */
+ /*
+ Do not create database if another thread is holding read lock.
+ Wait for global read lock before acquiring LOCK_mysql_create_db.
+ After wait_if_global_read_lock() we have protection against another
+ global read lock. If we would acquire LOCK_mysql_create_db first,
+ another thread could step in and get the global read lock before we
+ reach wait_if_global_read_lock(). If this thread tries the same as we
+ (admin a db), it would then go and wait on LOCK_mysql_create_db...
+ Furthermore wait_if_global_read_lock() checks if the current thread
+ has the global read lock and refuses the operation with
+ ER_CANT_UPDATE_WITH_READLOCK if applicable.
+ */
if (wait_if_global_read_lock(thd, 0, 1))
{
error= -1;
goto exit2;
}
+ VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
+
/* Check directory */
strxmov(path, mysql_data_home, "/", db, NullS);
path_len= unpack_dirname(path,path); // Convert if not unix
@@ -537,9 +548,9 @@ bool mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info,
}
exit:
+ VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
start_waiting_global_read_lock(thd);
exit2:
- VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
DBUG_RETURN(error);
}
@@ -553,12 +564,23 @@ bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info)
int error= 0;
DBUG_ENTER("mysql_alter_db");
- VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
-
- /* do not alter database if another thread is holding read lock */
+ /*
+ Do not alter database if another thread is holding read lock.
+ Wait for global read lock before acquiring LOCK_mysql_create_db.
+ After wait_if_global_read_lock() we have protection against another
+ global read lock. If we would acquire LOCK_mysql_create_db first,
+ another thread could step in and get the global read lock before we
+ reach wait_if_global_read_lock(). If this thread tries the same as we
+ (admin a db), it would then go and wait on LOCK_mysql_create_db...
+ Furthermore wait_if_global_read_lock() checks if the current thread
+ has the global read lock and refuses the operation with
+ ER_CANT_UPDATE_WITH_READLOCK if applicable.
+ */
if ((error=wait_if_global_read_lock(thd,0,1)))
goto exit2;
+ VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
+
/* Check directory */
strxmov(path, mysql_data_home, "/", db, "/", MY_DB_OPT_FILE, NullS);
fn_format(path, path, "", "", MYF(MY_UNPACK_FILENAME));
@@ -596,9 +618,9 @@ bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info)
send_ok(thd, result);
exit:
+ VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
start_waiting_global_read_lock(thd);
exit2:
- VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
DBUG_RETURN(error);
}
@@ -630,15 +652,26 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
TABLE_LIST* dropped_tables= 0;
DBUG_ENTER("mysql_rm_db");
- VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
-
- /* do not drop database if another thread is holding read lock */
+ /*
+ Do not drop database if another thread is holding read lock.
+ Wait for global read lock before acquiring LOCK_mysql_create_db.
+ After wait_if_global_read_lock() we have protection against another
+ global read lock. If we would acquire LOCK_mysql_create_db first,
+ another thread could step in and get the global read lock before we
+ reach wait_if_global_read_lock(). If this thread tries the same as we
+ (admin a db), it would then go and wait on LOCK_mysql_create_db...
+ Furthermore wait_if_global_read_lock() checks if the current thread
+ has the global read lock and refuses the operation with
+ ER_CANT_UPDATE_WITH_READLOCK if applicable.
+ */
if (wait_if_global_read_lock(thd, 0, 1))
{
error= -1;
goto exit2;
}
+ VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
+
(void) sprintf(path,"%s/%s",mysql_data_home,db);
length= unpack_dirname(path,path); // Convert if not unix
strmov(path+length, MY_DB_OPT_FILE); // Append db option file name
@@ -747,7 +780,6 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
exit:
(void)sp_drop_db_routines(thd, db); /* QQ Ignore errors for now */
- start_waiting_global_read_lock(thd);
/*
If this database was the client's selected database, we silently change the
client's selected database to nothing (to have an empty SELECT DATABASE()
@@ -776,9 +808,9 @@ exit:
thd->db= 0;
thd->db_length= 0;
}
-exit2:
VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
-
+ start_waiting_global_read_lock(thd);
+exit2:
DBUG_RETURN(error);
}