Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
f4fe2c3b
Commit
f4fe2c3b
authored
Jul 21, 2005
by
ndbdev@dl145b.mysql.com
Browse files
Options
Browse Files
Download
Plain Diff
Merge tulin@bk-internal.mysql.com:/home/bk/mysql-5.0
into dl145b.mysql.com:/home/ndbdev/tomas/mysql-5.1
parents
98a26f0c
5cdaf463
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
168 additions
and
76 deletions
+168
-76
include/thr_lock.h
include/thr_lock.h
+1
-1
mysys/thr_lock.c
mysys/thr_lock.c
+5
-2
sql/handler.cc
sql/handler.cc
+2
-0
sql/lock.cc
sql/lock.cc
+17
-6
sql/mysql_priv.h
sql/mysql_priv.h
+6
-2
sql/sql_base.cc
sql/sql_base.cc
+80
-42
sql/sql_table.cc
sql/sql_table.cc
+12
-23
tests/mysql_client_test.c
tests/mysql_client_test.c
+45
-0
No files found.
include/thr_lock.h
View file @
f4fe2c3b
...
...
@@ -144,7 +144,7 @@ enum enum_thr_lock_result thr_multi_lock(THR_LOCK_DATA **data,
uint
count
,
THR_LOCK_OWNER
*
owner
);
void
thr_multi_unlock
(
THR_LOCK_DATA
**
data
,
uint
count
);
void
thr_abort_locks
(
THR_LOCK
*
lock
);
void
thr_abort_locks_for_thread
(
THR_LOCK
*
lock
,
pthread_t
thread
);
bool
thr_abort_locks_for_thread
(
THR_LOCK
*
lock
,
pthread_t
thread
);
void
thr_print_locks
(
void
);
/* For debugging */
my_bool
thr_upgrade_write_delay_lock
(
THR_LOCK_DATA
*
data
);
my_bool
thr_reschedule_write_lock
(
THR_LOCK_DATA
*
data
);
...
...
mysys/thr_lock.c
View file @
f4fe2c3b
...
...
@@ -1048,9 +1048,10 @@ void thr_abort_locks(THR_LOCK *lock)
This is used to abort all locks for a specific thread
*/
void
thr_abort_locks_for_thread
(
THR_LOCK
*
lock
,
pthread_t
thread
)
bool
thr_abort_locks_for_thread
(
THR_LOCK
*
lock
,
pthread_t
thread
)
{
THR_LOCK_DATA
*
data
;
bool
found
=
FALSE
;
DBUG_ENTER
(
"thr_abort_locks_for_thread"
);
pthread_mutex_lock
(
&
lock
->
mutex
);
...
...
@@ -1061,6 +1062,7 @@ void thr_abort_locks_for_thread(THR_LOCK *lock, pthread_t thread)
DBUG_PRINT
(
"info"
,(
"Aborting read-wait lock"
));
data
->
type
=
TL_UNLOCK
;
/* Mark killed */
/* It's safe to signal the cond first: we're still holding the mutex. */
found
=
TRUE
;
pthread_cond_signal
(
data
->
cond
);
data
->
cond
=
0
;
/* Removed from list */
...
...
@@ -1076,6 +1078,7 @@ void thr_abort_locks_for_thread(THR_LOCK *lock, pthread_t thread)
{
DBUG_PRINT
(
"info"
,(
"Aborting write-wait lock"
));
data
->
type
=
TL_UNLOCK
;
found
=
TRUE
;
pthread_cond_signal
(
data
->
cond
);
data
->
cond
=
0
;
...
...
@@ -1086,7 +1089,7 @@ void thr_abort_locks_for_thread(THR_LOCK *lock, pthread_t thread)
}
}
pthread_mutex_unlock
(
&
lock
->
mutex
);
DBUG_
VOID_RETURN
;
DBUG_
RETURN
(
found
)
;
}
...
...
sql/handler.cc
View file @
f4fe2c3b
...
...
@@ -2268,6 +2268,8 @@ int ha_discover(THD *thd, const char *db, const char *name,
int
error
=
-
1
;
// Table does not exist in any handler
DBUG_ENTER
(
"ha_discover"
);
DBUG_PRINT
(
"enter"
,
(
"db: %s, name: %s"
,
db
,
name
));
if
(
is_prefix
(
name
,
tmp_file_prefix
))
/* skip temporary tables */
DBUG_RETURN
(
error
);
#ifdef HAVE_NDBCLUSTER_DB
if
(
have_ndbcluster
==
SHOW_OPTION_YES
)
error
=
ndbcluster_discover
(
thd
,
db
,
name
,
frmblob
,
frmlen
);
...
...
sql/lock.cc
View file @
f4fe2c3b
...
...
@@ -349,20 +349,25 @@ void mysql_lock_abort(THD *thd, TABLE *table)
/* Abort one thread / table combination */
void
mysql_lock_abort_for_thread
(
THD
*
thd
,
TABLE
*
table
)
bool
mysql_lock_abort_for_thread
(
THD
*
thd
,
TABLE
*
table
)
{
MYSQL_LOCK
*
locked
;
TABLE
*
write_lock_used
;
bool
result
=
FALSE
;
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
,
{
bool
found
;
found
=
thr_abort_locks_for_thread
(
locked
->
locks
[
i
]
->
lock
,
table
->
in_use
->
real_id
);
result
|=
found
;
}
my_free
((
gptr
)
locked
,
MYF
(
0
));
}
DBUG_
VOID_RETURN
;
DBUG_
RETURN
(
result
)
;
}
...
...
@@ -605,8 +610,14 @@ 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
,
db
,
table_list
->
table_name
,
0
))
{
if
(
remove_table_from_cache
(
thd
,
db
,
table_list
->
table_name
,
RTFC_NO_FLAG
))
{
DBUG_RETURN
(
1
);
// Table is in use
}
}
DBUG_RETURN
(
0
);
}
...
...
sql/mysql_priv.h
View file @
f4fe2c3b
...
...
@@ -966,8 +966,12 @@ bool rename_temporary_table(THD* thd, TABLE *table, const char *new_db,
const
char
*
table_name
);
void
remove_db_from_cache
(
const
char
*
db
);
void
flush_tables
();
#define RTFC_NO_FLAG 0x0000
#define RTFC_OWNED_BY_THD_FLAG 0x0001
#define RTFC_WAIT_OTHER_THREAD_FLAG 0x0002
#define RTFC_CHECK_KILLED_FLAG 0x0004
bool
remove_table_from_cache
(
THD
*
thd
,
const
char
*
db
,
const
char
*
table
,
bool
return_if_owned_by_thd
);
uint
flags
);
bool
close_cached_tables
(
THD
*
thd
,
bool
wait_for_refresh
,
TABLE_LIST
*
tables
);
void
copy_field_from_tmp_record
(
Field
*
field
,
int
offset
);
bool
fill_record
(
THD
*
thd
,
Field
**
field
,
List
<
Item
>
&
values
,
...
...
@@ -1231,7 +1235,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_lock_remove
(
THD
*
thd
,
MYSQL_LOCK
*
locked
,
TABLE
*
table
);
void
mysql_lock_abort
(
THD
*
thd
,
TABLE
*
table
);
void
mysql_lock_abort_for_thread
(
THD
*
thd
,
TABLE
*
table
);
bool
mysql_lock_abort_for_thread
(
THD
*
thd
,
TABLE
*
table
);
MYSQL_LOCK
*
mysql_lock_merge
(
MYSQL_LOCK
*
a
,
MYSQL_LOCK
*
b
);
bool
lock_global_read_lock
(
THD
*
thd
);
void
unlock_global_read_lock
(
THD
*
thd
);
...
...
sql/sql_base.cc
View file @
f4fe2c3b
...
...
@@ -292,7 +292,8 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
bool
found
=
0
;
for
(
TABLE_LIST
*
table
=
tables
;
table
;
table
=
table
->
next_local
)
{
if
(
remove_table_from_cache
(
thd
,
table
->
db
,
table
->
table_name
,
1
))
if
(
remove_table_from_cache
(
thd
,
table
->
db
,
table
->
table_name
,
RTFC_OWNED_BY_THD_FLAG
))
found
=
1
;
}
if
(
!
found
)
...
...
@@ -4134,21 +4135,25 @@ void flush_tables()
*/
bool
remove_table_from_cache
(
THD
*
thd
,
const
char
*
db
,
const
char
*
table_name
,
bool
return_if_owned_by_thd
)
uint
flags
)
{
char
key
[
MAX_DBKEY_LENGTH
];
uint
key_length
;
TABLE
*
table
;
bool
result
=
0
;
bool
result
=
0
,
signalled
=
0
;
DBUG_ENTER
(
"remove_table_from_cache"
);
key_length
=
(
uint
)
(
strmov
(
strmov
(
key
,
db
)
+
1
,
table_name
)
-
key
)
+
1
;
for
(;;)
{
result
=
signalled
=
0
;
for
(
table
=
(
TABLE
*
)
hash_search
(
&
open_cache
,(
byte
*
)
key
,
key_length
)
;
table
;
table
=
(
TABLE
*
)
hash_next
(
&
open_cache
,(
byte
*
)
key
,
key_length
))
{
THD
*
in_use
;
table
->
s
->
version
=
0L
;
/* Free when thread is ready */
table
->
s
->
version
=
0L
;
/* Free when thread is ready */
if
(
!
(
in_use
=
table
->
in_use
))
{
DBUG_PRINT
(
"info"
,(
"Table was not in use"
));
...
...
@@ -4168,6 +4173,7 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name,
if
(
in_use
->
mysys_var
->
current_cond
)
{
pthread_mutex_lock
(
in_use
->
mysys_var
->
current_mutex
);
signalled
=
1
;
pthread_cond_broadcast
(
in_use
->
mysys_var
->
current_cond
);
pthread_mutex_unlock
(
in_use
->
mysys_var
->
current_mutex
);
}
...
...
@@ -4182,14 +4188,46 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name,
thd_table
=
thd_table
->
next
)
{
if
(
thd_table
->
db_stat
)
// If table is open
mysql_lock_abort_for_thread
(
thd
,
thd_table
);
signalled
|=
mysql_lock_abort_for_thread
(
thd
,
thd_table
);
}
}
else
result
=
result
||
return_if_owned_by_thd
;
result
=
result
||
(
flags
&
RTFC_OWNED_BY_THD_FLAG
)
;
}
while
(
unused_tables
&&
!
unused_tables
->
s
->
version
)
VOID
(
hash_delete
(
&
open_cache
,(
byte
*
)
unused_tables
));
if
(
result
&&
(
flags
&
RTFC_WAIT_OTHER_THREAD_FLAG
))
{
if
(
!
(
flags
&
RTFC_CHECK_KILLED_FLAG
)
||
!
thd
->
killed
)
{
if
(
likely
(
signalled
))
{
dropping_tables
++
;
(
void
)
pthread_cond_wait
(
&
COND_refresh
,
&
LOCK_open
);
dropping_tables
--
;
continue
;
}
else
{
/*
It can happen that another thread has opened the
table but has not yet locked any table at all. Since
it can be locked waiting for a table that our thread
has done LOCK TABLE x WRITE on previously, we need to
ensure that the thread actually hears our signal
before we go to sleep. Thus we wait for a short time
and then we retry another loop in the
remove_table_from_cache routine.
*/
pthread_mutex_unlock
(
&
LOCK_open
);
my_sleep
(
10
);
pthread_mutex_lock
(
&
LOCK_open
);
continue
;
}
}
}
break
;
}
DBUG_RETURN
(
result
);
}
...
...
sql/sql_table.cc
View file @
f4fe2c3b
...
...
@@ -230,6 +230,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
for
(
table
=
tables
;
table
;
table
=
table
->
next_local
)
{
char
*
db
=
table
->
db
;
uint
flags
;
mysql_ha_flush
(
thd
,
table
,
MYSQL_HA_CLOSE_FINAL
);
if
(
!
close_temporary_table
(
thd
,
db
,
table
->
table_name
))
{
...
...
@@ -241,13 +242,8 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
if
(
!
drop_temporary
)
{
abort_locked_tables
(
thd
,
db
,
table
->
table_name
);
while
(
remove_table_from_cache
(
thd
,
db
,
table
->
table_name
,
0
)
&&
!
thd
->
killed
)
{
dropping_tables
++
;
(
void
)
pthread_cond_wait
(
&
COND_refresh
,
&
LOCK_open
);
dropping_tables
--
;
}
flags
=
RTFC_WAIT_OTHER_THREAD_FLAG
|
RTFC_CHECK_KILLED_FLAG
;
remove_table_from_cache
(
thd
,
db
,
table
->
table_name
,
flags
);
drop_locked_tables
(
thd
,
db
,
table
->
table_name
);
if
(
thd
->
killed
)
{
...
...
@@ -1938,12 +1934,8 @@ static void wait_while_table_is_used(THD *thd,TABLE *table,
mysql_lock_abort
(
thd
,
table
);
// end threads waiting on lock
/* Wait until all there are no other threads that has this table open */
while
(
remove_table_from_cache
(
thd
,
table
->
s
->
db
,
table
->
s
->
table_name
,
0
))
{
dropping_tables
++
;
(
void
)
pthread_cond_wait
(
&
COND_refresh
,
&
LOCK_open
);
dropping_tables
--
;
}
remove_table_from_cache
(
thd
,
table
->
s
->
db
,
table
->
s
->
table_name
,
RTFC_WAIT_OTHER_THREAD_FLAG
);
DBUG_VOID_RETURN
;
}
...
...
@@ -2326,18 +2318,14 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
/* Close all instances of the table to allow repair to rename files */
if
(
lock_type
==
TL_WRITE
&&
table
->
table
->
s
->
version
)
{
uint
flags
;
pthread_mutex_lock
(
&
LOCK_open
);
const
char
*
old_message
=
thd
->
enter_cond
(
&
COND_refresh
,
&
LOCK_open
,
"Waiting to get writelock"
);
mysql_lock_abort
(
thd
,
table
->
table
);
while
(
remove_table_from_cache
(
thd
,
table
->
table
->
s
->
db
,
table
->
table
->
s
->
table_name
,
0
)
&&
!
thd
->
killed
)
{
dropping_tables
++
;
(
void
)
pthread_cond_wait
(
&
COND_refresh
,
&
LOCK_open
);
dropping_tables
--
;
}
flags
=
RTFC_WAIT_OTHER_THREAD_FLAG
|
RTFC_CHECK_KILLED_FLAG
;
remove_table_from_cache
(
thd
,
table
->
table
->
s
->
db
,
table
->
table
->
s
->
table_name
,
flags
);
thd
->
exit_cond
(
old_message
);
if
(
thd
->
killed
)
goto
err
;
...
...
@@ -2482,7 +2470,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
{
pthread_mutex_lock
(
&
LOCK_open
);
remove_table_from_cache
(
thd
,
table
->
table
->
s
->
db
,
table
->
table
->
s
->
table_name
,
0
);
table
->
table
->
s
->
table_name
,
RTFC_NO_FLAG
);
pthread_mutex_unlock
(
&
LOCK_open
);
/* May be something modified consequently we have to invalidate cache */
query_cache_invalidate3
(
thd
,
table
->
table
,
0
);
...
...
@@ -3862,7 +3850,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
if
(
table
)
{
VOID
(
table
->
file
->
extra
(
HA_EXTRA_FORCE_REOPEN
));
// Use new file
remove_table_from_cache
(
thd
,
db
,
table_name
,
0
);
// Mark in-use copies old
remove_table_from_cache
(
thd
,
db
,
table_name
,
RTFC_NO_FLAG
);
// Mark in-use copies old
mysql_lock_abort
(
thd
,
table
);
// end threads waiting on lock
}
VOID
(
quick_rm_table
(
old_db_type
,
db
,
old_name
));
...
...
tests/mysql_client_test.c
View file @
f4fe2c3b
...
...
@@ -13888,6 +13888,50 @@ static void test_bug10760()
mysql_autocommit
(
mysql
,
TRUE
);
/* restore default */
}
static
void
test_bug12001
()
{
MYSQL
*
mysql_local
;
MYSQL_RES
*
result
;
const
char
*
query
=
"DROP TABLE IF EXISTS test_table;"
"CREATE TABLE test_table(id INT);"
"INSERT INTO test_table VALUES(10);"
"UPDATE test_table SET id=20 WHERE id=10;"
"SELECT * FROM test_table;"
"INSERT INTO non_existent_table VALUES(11);"
;
int
rc
,
res
;
myheader
(
"test_bug12001"
);
if
(
!
(
mysql_local
=
mysql_init
(
NULL
)))
{
fprintf
(
stdout
,
"
\n
mysql_init() failed"
);
exit
(
1
);
}
/* Create connection that supports multi statements */
if
(
!
mysql_real_connect
(
mysql_local
,
opt_host
,
opt_user
,
opt_password
,
current_db
,
opt_port
,
opt_unix_socket
,
CLIENT_MULTI_STATEMENTS
|
CLIENT_MULTI_RESULTS
))
{
fprintf
(
stdout
,
"
\n
mysql_real_connect() failed"
);
exit
(
1
);
}
rc
=
mysql_query
(
mysql_local
,
query
);
myquery
(
rc
);
do
{
if
(
mysql_field_count
(
mysql_local
)
&&
(
result
=
mysql_use_result
(
mysql_local
)))
{
mysql_free_result
(
result
);
}
}
while
(
!
(
res
=
mysql_next_result
(
mysql_local
)));
rc
=
mysql_query
(
mysql_local
,
"DROP TABLE IF EXISTS test_table"
);
myquery
(
rc
);
mysql_close
(
mysql_local
);
DIE_UNLESS
(
res
==
1
);
}
/*
Read and parse arguments and MySQL options from my.cnf
*/
...
...
@@ -14133,6 +14177,7 @@ static struct my_tests_st my_tests[]= {
{
"test_bug11183"
,
test_bug11183
},
{
"test_bug11037"
,
test_bug11037
},
{
"test_bug10760"
,
test_bug10760
},
{
"test_bug12001"
,
test_bug12001
},
{
0
,
0
}
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment