3168 Dmitry Lenev 2010-10-19
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.
modified:
sql/lock.cc
sql/sql_class.cc
sql/sql_class.h
sql/sql_insert.cc
3167 Dmitry Lenev 2010-10-18
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.
removed:
mysql-test/t/flush_read_lock_kill-master.opt
added:
mysql-test/include/check_ftwrl_compatible.inc
mysql-test/include/check_ftwrl_incompatible.inc
mysql-test/r/flush_read_lock.result
mysql-test/t/flush_read_lock.test
modified:
mysql-test/include/handler.inc
mysql-test/include/wait_show_condition.inc
mysql-test/r/flush.result
mysql-test/r/flush_read_lock_kill.result
mysql-test/r/handler_innodb.result
mysql-test/r/handler_myisam.result
mysql-test/r/mdl_sync.result
mysql-test/suite/perfschema/r/dml_setup_instruments.result
mysql-test/suite/perfschema/r/global_read_lock.result
mysql-test/suite/perfschema/r/server_init.result
mysql-test/suite/perfschema/t/global_read_lock.test
mysql-test/suite/perfschema/t/server_init.test
mysql-test/t/flush.test
mysql-test/t/flush_block_commit.test
mysql-test/t/flush_block_commit_notembedded.test
mysql-test/t/flush_read_lock_kill.test
mysql-test/t/lock_multi.test
mysql-test/t/mdl_sync.test
mysql-test/t/trigger_notembedded.test
sql/ha_ndbcluster.cc
sql/handler.cc
sql/lock.cc
sql/lock.h
sql/log_event.cc
sql/mdl.cc
sql/mdl.h
sql/mysqld.cc
sql/mysqld.h
sql/rpl_rli.cc
sql/sp_head.cc
sql/sql_base.cc
sql/sql_base.h
sql/sql_class.cc
sql/sql_class.h
sql/sql_handler.cc
sql/sql_insert.cc
sql/sql_lex.cc
sql/sql_lex.h
sql/sql_parse.cc
sql/sql_parse.h
sql/sql_rename.cc
sql/sql_table.cc
sql/sql_trigger.cc
sql/sql_view.cc
sql/sql_yacc.yy
sql/transaction.cc
=== modified file 'sql/lock.cc'
--- a/sql/lock.cc 2010-10-18 12:33:49 +0000
+++ b/sql/lock.cc 2010-10-19 13:31:53 +0000
@@ -1137,10 +1137,6 @@ bool Global_read_lock::make_global_read_
thd->variables.lock_wait_timeout))
DBUG_RETURN(TRUE);
- /*
- TODO/FIXME Ensure that this ticket is correctly placed after sentinel
- when we are leaving LOCK TABLES mode.
- */
thd->mdl_context.move_ticket_after_trans_sentinel(mdl_request.ticket);
m_mdl_blocks_commits_lock= mdl_request.ticket;
m_state= GRL_ACQUIRED_AND_BLOCKS_COMMIT;
@@ -1148,6 +1144,22 @@ bool Global_read_lock::make_global_read_
DBUG_RETURN(FALSE);
}
+
+/**
+ Move tickets for metadata locks which are used to implement GRL after
+ transactional sentinel.
+
+ @param thd Reference to thread.
+*/
+
+void Global_read_lock::move_tickets_after_trans_sentinel(THD *thd)
+{
+ if (m_mdl_global_shared_lock)
+ thd->mdl_context.move_ticket_after_trans_sentinel(m_mdl_global_shared_lock);
+ if (m_mdl_blocks_commits_lock)
+ thd->mdl_context.move_ticket_after_trans_sentinel(m_mdl_blocks_commits_lock);
+}
+
/**
@} (end of group Locking)
*/
=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc 2010-10-18 12:33:49 +0000
+++ b/sql/sql_class.cc 2010-10-19 13:31:53 +0000
@@ -3458,11 +3458,12 @@ void THD::set_mysys_var(struct st_my_thr
void THD::leave_locked_tables_mode()
{
locked_tables_mode= LTM_NONE;
+ mdl_context.reset_trans_sentinel(NULL);
/*
- Make sure we don't release the global read lock when leaving LTM.
- TODO/FIXME: Add handling of commit blocker!
+ Make sure we don't release the global read lock and commit blocker
+ when leaving LTM.
*/
- mdl_context.reset_trans_sentinel(global_read_lock.global_shared_lock());
+ global_read_lock.move_tickets_after_trans_sentinel(this);
/* Also ensure that we don't release metadata locks for open HANDLERs. */
if (handler_tables_hash.records)
mysql_ha_move_tickets_after_trans_sentinel(this);
=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h 2010-10-18 12:33:49 +0000
+++ b/sql/sql_class.h 2010-10-19 13:31:53 +0000
@@ -1350,7 +1350,7 @@ public:
void release_protection_if_set(THD *thd);
bool make_global_read_lock_block_commit(THD *thd);
bool is_acquired() const { return m_state != GRL_NONE; }
- MDL_ticket *global_shared_lock() const { return m_mdl_global_shared_lock; }
+ void move_tickets_after_trans_sentinel(THD *thd);
private:
enum_grl_state m_state;
/**
=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc 2010-10-18 12:33:49 +0000
+++ b/sql/sql_insert.cc 2010-10-19 13:31:53 +0000
@@ -540,8 +540,6 @@ bool open_and_lock_for_insert_delayed(TH
table to being inserted into inside the connection thread.
If this goes ok, the tickets are cloned and added to the list of granted
locks held by the handler thread.
-
- TODO/FIXME: Handle release of protection against GRL.
*/
if (thd->global_read_lock.can_acquire_protection())
DBUG_RETURN(TRUE);
@@ -592,7 +590,12 @@ bool open_and_lock_for_insert_delayed(TH
this or another tables (updating the same table is of course illegal,
but such an attempt can be discovered only later during statement
execution).
+
+ Move ticket protecting from a GRL to the front of ticket list.
+ This allows to find it quickly when this lock has to be released
+ at the end of statement.
*/
+ thd->mdl_context.move_ticket_to_front(protection_request.ticket);
/*
Reset the ticket in case we end up having to use normal insert and
No bundle (reason: useless for push emails).
| Thread |
|---|
| • bzr push into mysql-5.5-runtime branch (Dmitry.Lenev:3167 to 3168) | Dmitry Lenev | 19 Oct |