summaryrefslogtreecommitdiff
path: root/sql/sql_handler.cc
diff options
context:
space:
mode:
authorDmitry Lenev <dlenev@mysql.com>2010-02-12 10:05:43 +0300
committerDmitry Lenev <dlenev@mysql.com>2010-02-12 10:05:43 +0300
commit0ec868ca0e2d3ea60835d7c8fa7b951182b497b1 (patch)
treef6e21136e22b3d22043de386166d177cb5f3a4eb /sql/sql_handler.cc
parentbca1fec83e3e9abbf5cd36e4c7be3f340aaba5b7 (diff)
downloadmariadb-git-0ec868ca0e2d3ea60835d7c8fa7b951182b497b1.tar.gz
Fix for bug #50908 "Assertion `handler_tables_hash.records == 0'
failed in enter_locked_tables_mode". Server was aborted due to assertion failure when one tried to execute statement requiring prelocking (i.e. firing triggers or using stored functions) while having open HANDLERs. The problem was that THD::enter_locked_tables_mode() method which was called at the beginning of execution of prelocked statement assumed there are no open HANDLERs. It had to do so because corresponding THD::leave_locked_tables_mode() method was unable to properly restore MDL sentinel when leaving LOCK TABLES/prelocked mode in the presence of open HANDLERs. This patch solves this problem by changing the latter method to properly restore MDL sentinel and thus removing need for this assumption. As a side-effect, it lifts unjustified limitation by allowing to keep HANDLERs open when entering LOCK TABLES mode.
Diffstat (limited to 'sql/sql_handler.cc')
-rw-r--r--sql/sql_handler.cc24
1 files changed, 24 insertions, 0 deletions
diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc
index 9f365d0cf2f..4a69b46ddb7 100644
--- a/sql/sql_handler.cc
+++ b/sql/sql_handler.cc
@@ -837,3 +837,27 @@ void mysql_ha_cleanup(THD *thd)
DBUG_VOID_RETURN;
}
+
+/**
+ Move tickets for metadata locks corresponding to open HANDLERs
+ after transaction sentinel in order to protect them from being
+ released at the end of transaction.
+
+ @param thd Thread identifier.
+*/
+
+void mysql_ha_move_tickets_after_trans_sentinel(THD *thd)
+{
+ TABLE_LIST *hash_tables;
+ DBUG_ENTER("mysql_ha_move_tickets_after_trans_sentinel");
+
+ for (uint i= 0; i < thd->handler_tables_hash.records; i++)
+ {
+ hash_tables= (TABLE_LIST*) my_hash_element(&thd->handler_tables_hash, i);
+ if (hash_tables->table && hash_tables->table->mdl_ticket)
+ thd->mdl_context.
+ move_ticket_after_trans_sentinel(hash_tables->table->mdl_ticket);
+ }
+ DBUG_VOID_RETURN;
+}
+