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
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
d099e6a2
Commit
d099e6a2
authored
Dec 13, 2007
by
davi@endora.local
Browse files
Options
Browse Files
Download
Plain Diff
Merge mysql.com:/Users/davi/mysql/bugs/32395-5.1
into mysql.com:/Users/davi/mysql/mysql-5.1-runtime
parents
93eef1ce
137e90ed
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
206 additions
and
41 deletions
+206
-41
mysql-test/r/lock_multi.result
mysql-test/r/lock_multi.result
+30
-0
mysql-test/r/trigger_notembedded.result
mysql-test/r/trigger_notembedded.result
+14
-0
mysql-test/t/lock_multi.test
mysql-test/t/lock_multi.test
+97
-1
mysql-test/t/trigger_notembedded.test
mysql-test/t/trigger_notembedded.test
+3
-3
sql/ha_ndbcluster.cc
sql/ha_ndbcluster.cc
+2
-2
sql/ha_ndbcluster_binlog.cc
sql/ha_ndbcluster_binlog.cc
+6
-6
sql/mysql_priv.h
sql/mysql_priv.h
+2
-1
sql/set_var.cc
sql/set_var.cc
+1
-1
sql/sql_base.cc
sql/sql_base.cc
+46
-23
sql/sql_parse.cc
sql/sql_parse.cc
+4
-3
sql/sql_table.cc
sql/sql_table.cc
+1
-1
No files found.
mysql-test/r/lock_multi.result
View file @
d099e6a2
...
@@ -113,4 +113,34 @@ handler t1 open;
...
@@ -113,4 +113,34 @@ handler t1 open;
ERROR HY000: Table storage engine for 't1' doesn't have this option
ERROR HY000: Table storage engine for 't1' doesn't have this option
--> client 1
--> client 1
drop table t1;
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
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;
unlock tables;
drop table t1;
End of 5.1 tests
End of 5.1 tests
mysql-test/r/trigger_notembedded.result
View file @
d099e6a2
...
@@ -448,4 +448,18 @@ DROP TABLE t1;
...
@@ -448,4 +448,18 @@ DROP TABLE t1;
DROP DATABASE mysqltest_db1;
DROP DATABASE mysqltest_db1;
USE test;
USE test;
End of 5.0 tests.
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.
End of 5.1 tests.
mysql-test/t/lock_multi.test
View file @
d099e6a2
...
@@ -150,7 +150,7 @@ send SELECT user.Select_priv FROM user, db WHERE user.user = db.user LIMIT 1;
...
@@ -150,7 +150,7 @@ send SELECT user.Select_priv FROM user, db WHERE user.user = db.user LIMIT 1;
connection
locker
;
connection
locker
;
let
$wait_condition
=
let
$wait_condition
=
select
count
(
*
)
=
1
from
information_schema
.
processlist
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"
;
"SELECT user.Select_priv FROM user, db WHERE user.user = db.user LIMIT 1"
;
--
source
include
/
wait_condition
.
inc
--
source
include
/
wait_condition
.
inc
# Make test case independent from earlier grants.
# Make test case independent from earlier grants.
...
@@ -343,4 +343,100 @@ handler t1 open;
...
@@ -343,4 +343,100 @@ handler t1 open;
connection
default
;
connection
default
;
drop
table
t1
;
drop
table
t1
;
#
# 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
flush
tables
;
let
$wait_condition
=
select
count
(
*
)
=
1
from
information_schema
.
processlist
where
state
=
"Flushing tables"
;
--
source
include
/
wait_condition
.
inc
unlock
tables
;
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
;
drop
table
t1
;
--
echo
End
of
5.1
tests
--
echo
End
of
5.1
tests
mysql-test/t/trigger_notembedded.test
View file @
d099e6a2
...
@@ -880,8 +880,9 @@ USE test;
...
@@ -880,8 +880,9 @@ USE test;
# Bug#23713 LOCK TABLES + CREATE TRIGGER + FLUSH TABLES WITH READ LOCK = deadlock
# Bug#23713 LOCK TABLES + CREATE TRIGGER + FLUSH TABLES WITH READ LOCK = deadlock
#
#
# Test temporarily disable due to Bug#32395
--
disable_warnings
--
disable_parsing
drop
table
if
exists
t1
;
--
enable_warnings
create
table
t1
(
i
int
);
create
table
t1
(
i
int
);
connect
(
flush
,
localhost
,
root
,,
test
,,);
connect
(
flush
,
localhost
,
root
,,
test
,,);
connection
default
;
connection
default
;
...
@@ -906,6 +907,5 @@ connection default;
...
@@ -906,6 +907,5 @@ connection default;
select
*
from
t1
;
select
*
from
t1
;
drop
table
t1
;
drop
table
t1
;
disconnect
flush
;
disconnect
flush
;
--
enable_parsing
--
echo
End
of
5.1
tests
.
--
echo
End
of
5.1
tests
.
sql/ha_ndbcluster.cc
View file @
d099e6a2
...
@@ -577,7 +577,7 @@ int ha_ndbcluster::ndb_err(NdbTransaction *trans)
...
@@ -577,7 +577,7 @@ int ha_ndbcluster::ndb_err(NdbTransaction *trans)
bzero
((
char
*
)
&
table_list
,
sizeof
(
table_list
));
bzero
((
char
*
)
&
table_list
,
sizeof
(
table_list
));
table_list
.
db
=
m_dbname
;
table_list
.
db
=
m_dbname
;
table_list
.
alias
=
table_list
.
table_name
=
m_tabname
;
table_list
.
alias
=
table_list
.
table_name
=
m_tabname
;
close_cached_tables
(
thd
,
0
,
&
table_list
);
close_cached_tables
(
thd
,
&
table_list
,
FALSE
,
FALSE
,
FALSE
);
break
;
break
;
}
}
default:
default:
...
@@ -8064,7 +8064,7 @@ int handle_trailing_share(NDB_SHARE *share)
...
@@ -8064,7 +8064,7 @@ int handle_trailing_share(NDB_SHARE *share)
table_list
.
db
=
share
->
db
;
table_list
.
db
=
share
->
db
;
table_list
.
alias
=
table_list
.
table_name
=
share
->
table_name
;
table_list
.
alias
=
table_list
.
table_name
=
share
->
table_name
;
safe_mutex_assert_owner
(
&
LOCK_open
);
safe_mutex_assert_owner
(
&
LOCK_open
);
close_cached_tables
(
thd
,
0
,
&
table_list
,
TRU
E
);
close_cached_tables
(
thd
,
&
table_list
,
TRUE
,
FALSE
,
FALS
E
);
pthread_mutex_lock
(
&
ndbcluster_mutex
);
pthread_mutex_lock
(
&
ndbcluster_mutex
);
/* ndb_share reference temporary free */
/* ndb_share reference temporary free */
...
...
sql/ha_ndbcluster_binlog.cc
View file @
d099e6a2
...
@@ -900,7 +900,7 @@ int ndbcluster_setup_binlog_table_shares(THD *thd)
...
@@ -900,7 +900,7 @@ int ndbcluster_setup_binlog_table_shares(THD *thd)
{
{
if
(
ndb_extra_logging
)
if
(
ndb_extra_logging
)
sql_print_information
(
"NDB Binlog: ndb tables writable"
);
sql_print_information
(
"NDB Binlog: ndb tables writable"
);
close_cached_tables
(
(
THD
*
)
0
,
0
,
(
TABLE_LIST
*
)
0
,
TRU
E
);
close_cached_tables
(
NULL
,
NULL
,
TRUE
,
FALSE
,
FALS
E
);
}
}
pthread_mutex_unlock
(
&
LOCK_open
);
pthread_mutex_unlock
(
&
LOCK_open
);
/* Signal injector thread that all is setup */
/* Signal injector thread that all is setup */
...
@@ -1700,7 +1700,7 @@ ndb_handle_schema_change(THD *thd, Ndb *ndb, NdbEventOperation *pOp,
...
@@ -1700,7 +1700,7 @@ ndb_handle_schema_change(THD *thd, Ndb *ndb, NdbEventOperation *pOp,
bzero
((
char
*
)
&
table_list
,
sizeof
(
table_list
));
bzero
((
char
*
)
&
table_list
,
sizeof
(
table_list
));
table_list
.
db
=
(
char
*
)
dbname
;
table_list
.
db
=
(
char
*
)
dbname
;
table_list
.
alias
=
table_list
.
table_name
=
(
char
*
)
tabname
;
table_list
.
alias
=
table_list
.
table_name
=
(
char
*
)
tabname
;
close_cached_tables
(
thd
,
0
,
&
table_list
,
TRU
E
);
close_cached_tables
(
thd
,
&
table_list
,
TRUE
,
FALSE
,
FALS
E
);
if
((
error
=
ndbcluster_binlog_open_table
(
thd
,
share
,
if
((
error
=
ndbcluster_binlog_open_table
(
thd
,
share
,
table_share
,
table
,
1
)))
table_share
,
table
,
1
)))
...
@@ -1806,7 +1806,7 @@ ndb_handle_schema_change(THD *thd, Ndb *ndb, NdbEventOperation *pOp,
...
@@ -1806,7 +1806,7 @@ ndb_handle_schema_change(THD *thd, Ndb *ndb, NdbEventOperation *pOp,
bzero
((
char
*
)
&
table_list
,
sizeof
(
table_list
));
bzero
((
char
*
)
&
table_list
,
sizeof
(
table_list
));
table_list
.
db
=
(
char
*
)
dbname
;
table_list
.
db
=
(
char
*
)
dbname
;
table_list
.
alias
=
table_list
.
table_name
=
(
char
*
)
tabname
;
table_list
.
alias
=
table_list
.
table_name
=
(
char
*
)
tabname
;
close_cached_tables
(
thd
,
0
,
&
table_list
);
close_cached_tables
(
thd
,
&
table_list
,
FALSE
,
FALSE
,
FALSE
);
/* ndb_share reference create free */
/* ndb_share reference create free */
DBUG_PRINT
(
"NDB_SHARE"
,
(
"%s create free use_count: %u"
,
DBUG_PRINT
(
"NDB_SHARE"
,
(
"%s create free use_count: %u"
,
share
->
key
,
share
->
use_count
));
share
->
key
,
share
->
use_count
));
...
@@ -1925,7 +1925,7 @@ ndb_binlog_thread_handle_schema_event(THD *thd, Ndb *ndb,
...
@@ -1925,7 +1925,7 @@ ndb_binlog_thread_handle_schema_event(THD *thd, Ndb *ndb,
bzero
((
char
*
)
&
table_list
,
sizeof
(
table_list
));
bzero
((
char
*
)
&
table_list
,
sizeof
(
table_list
));
table_list
.
db
=
schema
->
db
;
table_list
.
db
=
schema
->
db
;
table_list
.
alias
=
table_list
.
table_name
=
schema
->
name
;
table_list
.
alias
=
table_list
.
table_name
=
schema
->
name
;
close_cached_tables
(
thd
,
0
,
&
table_list
,
FALSE
);
close_cached_tables
(
thd
,
&
table_list
,
FALSE
,
FALSE
,
FALSE
);
}
}
/* ndb_share reference temporary free */
/* ndb_share reference temporary free */
if
(
share
)
if
(
share
)
...
@@ -2049,7 +2049,7 @@ ndb_binlog_thread_handle_schema_event(THD *thd, Ndb *ndb,
...
@@ -2049,7 +2049,7 @@ ndb_binlog_thread_handle_schema_event(THD *thd, Ndb *ndb,
pthread_mutex_unlock
(
&
ndb_schema_share_mutex
);
pthread_mutex_unlock
(
&
ndb_schema_share_mutex
);
/* end protect ndb_schema_share */
/* end protect ndb_schema_share */
close_cached_tables
(
(
THD
*
)
0
,
0
,
(
TABLE_LIST
*
)
0
,
FALSE
);
close_cached_tables
(
NULL
,
NULL
,
FALSE
,
FALSE
,
FALSE
);
// fall through
// fall through
case
NDBEVENT
:
:
TE_ALTER
:
case
NDBEVENT
:
:
TE_ALTER
:
ndb_handle_schema_change
(
thd
,
ndb
,
pOp
,
tmp_share
);
ndb_handle_schema_change
(
thd
,
ndb
,
pOp
,
tmp_share
);
...
@@ -2206,7 +2206,7 @@ ndb_binlog_thread_handle_schema_event_post_epoch(THD *thd,
...
@@ -2206,7 +2206,7 @@ ndb_binlog_thread_handle_schema_event_post_epoch(THD *thd,
bzero
((
char
*
)
&
table_list
,
sizeof
(
table_list
));
bzero
((
char
*
)
&
table_list
,
sizeof
(
table_list
));
table_list
.
db
=
schema
->
db
;
table_list
.
db
=
schema
->
db
;
table_list
.
alias
=
table_list
.
table_name
=
schema
->
name
;
table_list
.
alias
=
table_list
.
table_name
=
schema
->
name
;
close_cached_tables
(
thd
,
0
,
&
table_list
,
FALSE
);
close_cached_tables
(
thd
,
&
table_list
,
FALSE
,
FALSE
,
FALSE
);
}
}
if
(
schema_type
!=
SOT_ALTER_TABLE
)
if
(
schema_type
!=
SOT_ALTER_TABLE
)
break
;
break
;
...
...
sql/mysql_priv.h
View file @
d099e6a2
...
@@ -1595,7 +1595,8 @@ TABLE *open_performance_schema_table(THD *thd, TABLE_LIST *one_table,
...
@@ -1595,7 +1595,8 @@ TABLE *open_performance_schema_table(THD *thd, TABLE_LIST *one_table,
Open_tables_state
*
backup
);
Open_tables_state
*
backup
);
void
close_performance_schema_table
(
THD
*
thd
,
Open_tables_state
*
backup
);
void
close_performance_schema_table
(
THD
*
thd
,
Open_tables_state
*
backup
);
bool
close_cached_tables
(
THD
*
thd
,
bool
wait_for_refresh
,
TABLE_LIST
*
tables
,
bool
have_lock
=
FALSE
);
bool
close_cached_tables
(
THD
*
thd
,
TABLE_LIST
*
tables
,
bool
have_lock
,
bool
wait_for_refresh
,
bool
wait_for_placeholders
);
bool
close_cached_connection_tables
(
THD
*
thd
,
bool
wait_for_refresh
,
bool
close_cached_connection_tables
(
THD
*
thd
,
bool
wait_for_refresh
,
LEX_STRING
*
connect_string
,
LEX_STRING
*
connect_string
,
bool
have_lock
=
FALSE
);
bool
have_lock
=
FALSE
);
...
...
sql/set_var.cc
View file @
d099e6a2
...
@@ -3720,7 +3720,7 @@ bool sys_var_opt_readonly::update(THD *thd, set_var *var)
...
@@ -3720,7 +3720,7 @@ bool sys_var_opt_readonly::update(THD *thd, set_var *var)
can cause to wait on a read lock, it's required for the client application
can cause to wait on a read lock, it's required for the client application
to unlock everything, and acceptable for the server to wait on all locks.
to unlock everything, and acceptable for the server to wait on all locks.
*/
*/
if
(
result
=
close_cached_tables
(
thd
,
true
,
NULL
,
false
))
if
(
result
=
close_cached_tables
(
thd
,
NULL
,
FALSE
,
TRUE
,
TRUE
))
goto
end_with_read_lock
;
goto
end_with_read_lock
;
if
(
result
=
make_global_read_lock_block_commit
(
thd
))
if
(
result
=
make_global_read_lock_block_commit
(
thd
))
...
...
sql/sql_base.cc
View file @
d099e6a2
...
@@ -130,7 +130,7 @@ void table_cache_free(void)
...
@@ -130,7 +130,7 @@ void table_cache_free(void)
DBUG_ENTER
(
"table_cache_free"
);
DBUG_ENTER
(
"table_cache_free"
);
if
(
table_def_inited
)
if
(
table_def_inited
)
{
{
close_cached_tables
(
(
THD
*
)
0
,
0
,(
TABLE_LIST
*
)
0
);
close_cached_tables
(
NULL
,
NULL
,
FALSE
,
FALSE
,
FALSE
);
if
(
!
open_cache
.
records
)
// Safety first
if
(
!
open_cache
.
records
)
// Safety first
hash_free
(
&
open_cache
);
hash_free
(
&
open_cache
);
}
}
...
@@ -908,16 +908,24 @@ void free_io_cache(TABLE *table)
...
@@ -908,16 +908,24 @@ void free_io_cache(TABLE *table)
/*
/*
Close all tables which aren't in use by any thread
Close all tables which aren't in use by any thread
THD can be NULL, but then if_wait_for_refresh must be FALSE
@param thd Thread context
and tables must be NULL.
@param tables List of tables to remove from the cache
@param have_lock If LOCK_open is locked
@param wait_for_refresh Wait for a impending flush
@param wait_for_placeholders Wait for tables being reopened so that the GRL
won't proceed while write-locked tables are being reopened by other
threads.
@remark THD can be NULL, but then wait_for_refresh must be FALSE
and tables must be NULL.
*/
*/
bool
close_cached_tables
(
THD
*
thd
,
bool
if_wait_for_refresh
,
bool
close_cached_tables
(
THD
*
thd
,
TABLE_LIST
*
tables
,
bool
have_lock
,
TABLE_LIST
*
tables
,
bool
have_lock
)
bool
wait_for_refresh
,
bool
wait_for_placeholders
)
{
{
bool
result
=
0
;
bool
result
=
0
;
DBUG_ENTER
(
"close_cached_tables"
);
DBUG_ENTER
(
"close_cached_tables"
);
DBUG_ASSERT
(
thd
||
(
!
if_
wait_for_refresh
&&
!
tables
));
DBUG_ASSERT
(
thd
||
(
!
wait_for_refresh
&&
!
tables
));
if
(
!
have_lock
)
if
(
!
have_lock
)
VOID
(
pthread_mutex_lock
(
&
LOCK_open
));
VOID
(
pthread_mutex_lock
(
&
LOCK_open
));
...
@@ -941,7 +949,7 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
...
@@ -941,7 +949,7 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
}
}
DBUG_PRINT
(
"tcache"
,
(
"incremented global refresh_version to: %lu"
,
DBUG_PRINT
(
"tcache"
,
(
"incremented global refresh_version to: %lu"
,
refresh_version
));
refresh_version
));
if
(
if_
wait_for_refresh
)
if
(
wait_for_refresh
)
{
{
/*
/*
Other threads could wait in a loop in open_and_lock_tables(),
Other threads could wait in a loop in open_and_lock_tables(),
...
@@ -998,13 +1006,13 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
...
@@ -998,13 +1006,13 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
found
=
1
;
found
=
1
;
}
}
if
(
!
found
)
if
(
!
found
)
if_
wait_for_refresh
=
0
;
// Nothing to wait for
wait_for_refresh
=
0
;
// Nothing to wait for
}
}
#ifndef EMBEDDED_LIBRARY
#ifndef EMBEDDED_LIBRARY
if
(
!
tables
)
if
(
!
tables
)
kill_delayed_threads
();
kill_delayed_threads
();
#endif
#endif
if
(
if_
wait_for_refresh
)
if
(
wait_for_refresh
)
{
{
/*
/*
If there is any table that has a lower refresh_version, wait until
If there is any table that has a lower refresh_version, wait until
...
@@ -1027,6 +1035,9 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
...
@@ -1027,6 +1035,9 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
for
(
uint
idx
=
0
;
idx
<
open_cache
.
records
;
idx
++
)
for
(
uint
idx
=
0
;
idx
<
open_cache
.
records
;
idx
++
)
{
{
TABLE
*
table
=
(
TABLE
*
)
hash_element
(
&
open_cache
,
idx
);
TABLE
*
table
=
(
TABLE
*
)
hash_element
(
&
open_cache
,
idx
);
/* Avoid a self-deadlock. */
if
(
table
->
in_use
==
thd
)
continue
;
/*
/*
Note that we wait here only for tables which are actually open, and
Note that we wait here only for tables which are actually open, and
not for placeholders with TABLE::open_placeholder set. Waiting for
not for placeholders with TABLE::open_placeholder set. Waiting for
...
@@ -1041,7 +1052,8 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
...
@@ -1041,7 +1052,8 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
are employed by CREATE TABLE as in this case table simply does not
are employed by CREATE TABLE as in this case table simply does not
exist yet.
exist yet.
*/
*/
if
(
table
->
needs_reopen_or_name_lock
()
&&
table
->
db_stat
)
if
(
table
->
needs_reopen_or_name_lock
()
&&
(
table
->
db_stat
||
(
table
->
open_placeholder
&&
wait_for_placeholders
)))
{
{
found
=
1
;
found
=
1
;
DBUG_PRINT
(
"signal"
,
(
"Waiting for COND_refresh"
));
DBUG_PRINT
(
"signal"
,
(
"Waiting for COND_refresh"
));
...
@@ -1060,11 +1072,18 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
...
@@ -1060,11 +1072,18 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
thd
->
in_lock_tables
=
0
;
thd
->
in_lock_tables
=
0
;
/* Set version for table */
/* Set version for table */
for
(
TABLE
*
table
=
thd
->
open_tables
;
table
;
table
=
table
->
next
)
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.
*/
if
(
table
->
reginfo
.
lock_type
<
TL_WRITE_ALLOW_WRITE
)
table
->
s
->
version
=
refresh_version
;
}
}
}
if
(
!
have_lock
)
if
(
!
have_lock
)
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
if
(
if_
wait_for_refresh
)
if
(
wait_for_refresh
)
{
{
pthread_mutex_lock
(
&
thd
->
mysys_var
->
mutex
);
pthread_mutex_lock
(
&
thd
->
mysys_var
->
mutex
);
thd
->
mysys_var
->
current_mutex
=
0
;
thd
->
mysys_var
->
current_mutex
=
0
;
...
@@ -1091,10 +1110,10 @@ bool close_cached_connection_tables(THD *thd, bool if_wait_for_refresh,
...
@@ -1091,10 +1110,10 @@ bool close_cached_connection_tables(THD *thd, bool if_wait_for_refresh,
DBUG_ASSERT
(
thd
);
DBUG_ASSERT
(
thd
);
bzero
(
&
tmp
,
sizeof
(
TABLE_LIST
));
bzero
(
&
tmp
,
sizeof
(
TABLE_LIST
));
if
(
!
have_lock
)
if
(
!
have_lock
)
VOID
(
pthread_mutex_lock
(
&
LOCK_open
));
VOID
(
pthread_mutex_lock
(
&
LOCK_open
));
for
(
idx
=
0
;
idx
<
table_def_cache
.
records
;
idx
++
)
for
(
idx
=
0
;
idx
<
table_def_cache
.
records
;
idx
++
)
{
{
TABLE_SHARE
*
share
=
(
TABLE_SHARE
*
)
hash_element
(
&
table_def_cache
,
idx
);
TABLE_SHARE
*
share
=
(
TABLE_SHARE
*
)
hash_element
(
&
table_def_cache
,
idx
);
...
@@ -1123,11 +1142,11 @@ bool close_cached_connection_tables(THD *thd, bool if_wait_for_refresh,
...
@@ -1123,11 +1142,11 @@ bool close_cached_connection_tables(THD *thd, bool if_wait_for_refresh,
}
}
if
(
tables
)
if
(
tables
)
result
=
close_cached_tables
(
thd
,
FALSE
,
tables
,
TRU
E
);
result
=
close_cached_tables
(
thd
,
tables
,
TRUE
,
FALSE
,
FALS
E
);
if
(
!
have_lock
)
if
(
!
have_lock
)
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
if
(
if_wait_for_refresh
)
if
(
if_wait_for_refresh
)
{
{
pthread_mutex_lock
(
&
thd
->
mysys_var
->
mutex
);
pthread_mutex_lock
(
&
thd
->
mysys_var
->
mutex
);
...
@@ -2227,7 +2246,7 @@ void wait_for_condition(THD *thd, pthread_mutex_t *mutex, pthread_cond_t *cond)
...
@@ -2227,7 +2246,7 @@ void wait_for_condition(THD *thd, pthread_mutex_t *mutex, pthread_cond_t *cond)
current thread.
current thread.
@param thd current thread context
@param thd current thread context
@param tables able list containing one table to open.
@param tables
t
able list containing one table to open.
@return FALSE on success, TRUE otherwise.
@return FALSE on success, TRUE otherwise.
*/
*/
...
@@ -3295,8 +3314,8 @@ static bool reattach_merge(THD *thd, TABLE **err_tables_p)
...
@@ -3295,8 +3314,8 @@ static bool reattach_merge(THD *thd, TABLE **err_tables_p)
@param thd Thread context
@param thd Thread context
@param get_locks Should we get locks after reopening tables ?
@param get_locks Should we get locks after reopening tables ?
@param
in_refresh Are we in FLUSH TABLES ? TODO: It seems that
@param
mark_share_as_old Mark share as old to protect from a impending
we can remove this parameter
.
global read lock
.
@note Since this function can't properly handle prelocking and
@note Since this function can't properly handle prelocking and
create placeholders it should be used in very special
create placeholders it should be used in very special
...
@@ -3310,13 +3329,17 @@ static bool reattach_merge(THD *thd, TABLE **err_tables_p)
...
@@ -3310,13 +3329,17 @@ static bool reattach_merge(THD *thd, TABLE **err_tables_p)
@return FALSE in case of success, TRUE - otherwise.
@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_share_as_old
)
{
{
TABLE
*
table
,
*
next
,
**
prev
;
TABLE
*
table
,
*
next
,
**
prev
;
TABLE
**
tables
,
**
tables_ptr
;
// For locks
TABLE
**
tables
,
**
tables_ptr
;
// For locks
TABLE
*
err_tables
=
NULL
;
TABLE
*
err_tables
=
NULL
;
bool
error
=
0
,
not_used
;
bool
error
=
0
,
not_used
;
bool
merge_table_found
=
FALSE
;
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"
);
DBUG_ENTER
(
"reopen_tables"
);
if
(
!
thd
->
open_tables
)
if
(
!
thd
->
open_tables
)
...
@@ -3377,7 +3400,7 @@ bool reopen_tables(THD *thd,bool get_locks,bool in_refresh)
...
@@ -3377,7 +3400,7 @@ bool reopen_tables(THD *thd,bool get_locks,bool in_refresh)
/* Do not handle locks of MERGE children. */
/* Do not handle locks of MERGE children. */
if
(
get_locks
&&
!
db_stat
&&
!
table
->
parent
)
if
(
get_locks
&&
!
db_stat
&&
!
table
->
parent
)
*
tables_ptr
++=
table
;
// need new lock on this
*
tables_ptr
++=
table
;
// need new lock on this
if
(
in_refresh
)
if
(
mark_share_as_old
)
{
{
table
->
s
->
version
=
0
;
table
->
s
->
version
=
0
;
table
->
open_placeholder
=
0
;
table
->
open_placeholder
=
0
;
...
@@ -3410,7 +3433,7 @@ bool reopen_tables(THD *thd,bool get_locks,bool in_refresh)
...
@@ -3410,7 +3433,7 @@ bool reopen_tables(THD *thd,bool get_locks,bool in_refresh)
*/
*/
thd
->
some_tables_deleted
=
0
;
thd
->
some_tables_deleted
=
0
;
if
((
lock
=
mysql_lock_tables
(
thd
,
tables
,
(
uint
)
(
tables_ptr
-
tables
),
if
((
lock
=
mysql_lock_tables
(
thd
,
tables
,
(
uint
)
(
tables_ptr
-
tables
),
MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN
,
&
not_used
)))
flags
,
&
not_used
)))
{
{
thd
->
locked_tables
=
mysql_lock_merge
(
thd
->
locked_tables
,
lock
);
thd
->
locked_tables
=
mysql_lock_merge
(
thd
->
locked_tables
,
lock
);
}
}
...
...
sql/sql_parse.cc
View file @
d099e6a2
...
@@ -6527,8 +6527,8 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
...
@@ -6527,8 +6527,8 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
tmp_write_to_binlog
=
0
;
tmp_write_to_binlog
=
0
;
if
(
lock_global_read_lock
(
thd
))
if
(
lock_global_read_lock
(
thd
))
return
1
;
// Killed
return
1
;
// Killed
result
=
close_cached_tables
(
thd
,(
options
&
REFRESH_FAST
)
?
0
:
1
,
result
=
close_cached_tables
(
thd
,
tables
,
FALSE
,
(
options
&
REFRESH_FAST
)
?
tables
);
FALSE
:
TRUE
,
TRUE
);
if
(
make_global_read_lock_block_commit
(
thd
))
// Killed
if
(
make_global_read_lock_block_commit
(
thd
))
// Killed
{
{
/* Don't leave things in a half-locked state */
/* Don't leave things in a half-locked state */
...
@@ -6537,7 +6537,8 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
...
@@ -6537,7 +6537,8 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
}
}
}
}
else
else
result
=
close_cached_tables
(
thd
,(
options
&
REFRESH_FAST
)
?
0
:
1
,
tables
);
result
=
close_cached_tables
(
thd
,
tables
,
FALSE
,
(
options
&
REFRESH_FAST
)
?
FALSE
:
TRUE
,
FALSE
);
my_dbopt_cleanup
();
my_dbopt_cleanup
();
}
}
if
(
options
&
REFRESH_HOSTS
)
if
(
options
&
REFRESH_HOSTS
)
...
...
sql/sql_table.cc
View file @
d099e6a2
...
@@ -6690,7 +6690,7 @@ view_err:
...
@@ -6690,7 +6690,7 @@ view_err:
if
(
thd
->
locked_tables
&&
new_name
==
table_name
&&
new_db
==
db
)
if
(
thd
->
locked_tables
&&
new_name
==
table_name
&&
new_db
==
db
)
{
{
thd
->
in_lock_tables
=
1
;
thd
->
in_lock_tables
=
1
;
error
=
reopen_tables
(
thd
,
1
,
0
);
error
=
reopen_tables
(
thd
,
1
,
1
);
thd
->
in_lock_tables
=
0
;
thd
->
in_lock_tables
=
0
;
if
(
error
)
if
(
error
)
goto
err_with_placeholders
;
goto
err_with_placeholders
;
...
...
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