#At file:///home/dlenev/src/bzr/mysql-5.5-rt-grl/ based on revid:dmitry.lenev@stripped
3189 Dmitry Lenev 2010-11-08
More changes to draft patch refactoring global read
lock implementation. Makes GRL yet another type of
metadata lock and thus exposes it to deadlock detector
in MDL subsystem.
Solves bugs #54673 "It takes too long to get readlock for
'FLUSH TABLES WITH READ LOCK'" and #57006 "Deadlock between
HANDLER and FLUSH TABLES WITH READ LOCK".
Work-in-progress. Minor after review fixes.
modified:
sql/lock.cc
sql/sql_base.cc
sql/sql_class.h
sql/sql_insert.cc
sql/sql_parse.cc
sql/sql_parse.h
=== modified file 'sql/lock.cc'
--- a/sql/lock.cc 2010-11-03 18:09:02 +0000
+++ b/sql/lock.cc 2010-11-08 09:55:43 +0000
@@ -779,17 +779,8 @@ bool lock_schema_name(THD *thd, const ch
if (thd->global_read_lock.can_acquire_protection())
return TRUE;
-
- /*
- This function can be only called during execution of a DDL statement.
- Since such statements release all metadata locks at its end we don't
- need to do anything special to ensure that protection against GRL is
- released.
- */
- DBUG_ASSERT(stmt_causes_implicit_commit(thd, CF_IMPLICIT_COMMIT_END));
-
- thd->global_read_lock.init_protection_request(&global_request);
-
+ global_request.init(MDL_key::GLOBAL, "", "", MDL_INTENTION_EXCLUSIVE,
+ MDL_STATEMENT);
mdl_request.init(MDL_key::SCHEMA, db, "", MDL_EXCLUSIVE, MDL_TRANSACTION);
mdl_requests.push_front(&mdl_request);
@@ -847,16 +838,8 @@ bool lock_object_name(THD *thd, MDL_key:
if (thd->global_read_lock.can_acquire_protection())
return TRUE;
-
- /*
- This function can be only called during execution of a DDL statement.
- Since such statements release all metadata locks at its end we don't
- need to do anything special to ensure that protection against GRL is
- released.
- */
- DBUG_ASSERT(stmt_causes_implicit_commit(thd, CF_IMPLICIT_COMMIT_END));
-
- thd->global_read_lock.init_protection_request(&global_request);
+ global_request.init(MDL_key::GLOBAL, "", "", MDL_INTENTION_EXCLUSIVE,
+ MDL_STATEMENT);
schema_request.init(MDL_key::SCHEMA, db, "", MDL_INTENTION_EXCLUSIVE,
MDL_TRANSACTION);
mdl_request.init(mdl_type, db, name, MDL_EXCLUSIVE, MDL_TRANSACTION);
@@ -1034,38 +1017,6 @@ void Global_read_lock::unlock_global_rea
/**
- Check if this connection can acquire protecting against GRL and
- emit error if otherwise.
-
- QQ: Does it make sense to make it inline?
-*/
-
-bool Global_read_lock::can_acquire_protection()
-{
- if (m_state)
- {
- my_error(ER_CANT_UPDATE_WITH_READLOCK, MYF(0));
- return TRUE;
- }
- return FALSE;
-}
-
-
-/**
- Initialize request for lock protecting normal statement from GRL
- (and vice versa).
-
- QQ: Does it make sense to make it inline?
-*/
-
-void Global_read_lock::init_protection_request(MDL_request *request)
-{
- request->init(MDL_key::GLOBAL, "", "", MDL_INTENTION_EXCLUSIVE,
- MDL_STATEMENT);
-}
-
-
-/**
Make global read lock also block commits.
The scenario is:
=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc 2010-11-03 14:30:33 +0000
+++ b/sql/sql_base.cc 2010-11-08 09:55:43 +0000
@@ -2822,7 +2822,8 @@ bool open_table(THD *thd, TABLE_LIST *ta
if (thd->global_read_lock.can_acquire_protection())
DBUG_RETURN(TRUE);
- thd->global_read_lock.init_protection_request(&protection_request);
+ protection_request.init(MDL_key::GLOBAL, "", "", MDL_INTENTION_EXCLUSIVE,
+ MDL_STATEMENT);
/*
Install error handler which if possible will convert deadlock error
into request to back-off and restart process of opening tables.
@@ -4579,18 +4580,15 @@ lock_table_names(THD *thd,
mdl_requests.push_front(schema_request);
}
- if (thd->global_read_lock.can_acquire_protection())
- return TRUE;
-
/*
- We can get here only during execution of code which will release
- all metadata locks by the statement's end. So we don't need to do
- anything special to ensure that protection against GRL is released.
-
- QQ: This assumption is kind of ugly and hard to enforce using asserts.
- Is there any nice way to get rid of it?
+ Protect this statement against concurrent global read lock
+ by acquiring global intention exclusive lock with statement
+ duration.
*/
- thd->global_read_lock.init_protection_request(&global_request);
+ if (thd->global_read_lock.can_acquire_protection())
+ return TRUE;
+ global_request.init(MDL_key::GLOBAL, "", "", MDL_INTENTION_EXCLUSIVE,
+ MDL_STATEMENT);
mdl_requests.push_front(&global_request);
}
=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h 2010-11-03 18:09:02 +0000
+++ b/sql/sql_class.h 2010-11-08 09:55:43 +0000
@@ -1343,9 +1343,19 @@ public:
bool lock_global_read_lock(THD *thd);
void unlock_global_read_lock(THD *thd);
- bool can_acquire_protection();
- bool has_read_lock() const { return (m_state != GRL_NONE); }
- void init_protection_request(MDL_request *request);
+ /**
+ Check if this connection can acquire protection against GRL and
+ emit error if otherwise.
+ */
+ bool can_acquire_protection() const
+ {
+ if (m_state)
+ {
+ my_error(ER_CANT_UPDATE_WITH_READLOCK, MYF(0));
+ return TRUE;
+ }
+ return FALSE;
+ }
bool make_global_read_lock_block_commit(THD *thd);
bool is_acquired() const { return m_state != GRL_NONE; }
void set_explicit_lock_duration(THD *thd);
=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc 2010-11-03 14:30:33 +0000
+++ b/sql/sql_insert.cc 2010-11-08 09:55:43 +0000
@@ -545,7 +545,8 @@ bool open_and_lock_for_insert_delayed(TH
if (thd->global_read_lock.can_acquire_protection())
DBUG_RETURN(TRUE);
- thd->global_read_lock.init_protection_request(&protection_request);
+ protection_request.init(MDL_key::GLOBAL, "", "", MDL_INTENTION_EXCLUSIVE,
+ MDL_STATEMENT);
if (thd->mdl_context.acquire_lock(&protection_request,
thd->variables.lock_wait_timeout))
=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc 2010-11-03 18:09:02 +0000
+++ b/sql/sql_parse.cc 2010-11-08 09:55:43 +0000
@@ -187,7 +187,7 @@ static bool some_non_temp_table_to_be_up
@param mask Bitmask used for the SQL command match.
*/
-bool stmt_causes_implicit_commit(THD *thd, uint mask)
+static bool stmt_causes_implicit_commit(THD *thd, uint mask)
{
LEX *lex= thd->lex;
bool skip= FALSE;
=== modified file 'sql/sql_parse.h'
--- a/sql/sql_parse.h 2010-10-18 12:33:49 +0000
+++ b/sql/sql_parse.h 2010-11-08 09:55:43 +0000
@@ -78,7 +78,6 @@ bool check_host_name(LEX_STRING *str);
bool check_identifier_name(LEX_STRING *str, uint max_char_length,
uint err_code, const char *param_for_err_msg);
bool mysql_test_parse_for_slave(THD *thd,char *inBuf,uint length);
-bool stmt_causes_implicit_commit(THD *thd, uint mask);
bool sqlcom_can_generate_row_events(const THD *thd);
bool is_update_query(enum enum_sql_command command);
bool is_log_table_write_query(enum enum_sql_command command);
Attachment: [text/bzr-bundle] bzr/dmitry.lenev@oracle.com-20101108095543-dx7wpum9xxf21pq8.bundle
| Thread |
|---|
| • bzr commit into mysql-5.5-runtime branch (Dmitry.Lenev:3189) | Dmitry Lenev | 8 Nov |