List:Commits« Previous MessageNext Message »
From:Dmitry Lenev Date:January 28 2010 5:45pm
Subject:bzr commit into mysql-5.6-next-mr branch (dlenev:3075) Bug#46272
View as plain text  
#At file:///home/dlenev/src/bzr/mysql-next-4284-nl-review/ based on revid:kostja@stripped

 3075 Dmitry Lenev	2010-01-28
      Tentative patch implementing new type-of-operation-aware metadata locks.
      Fixes bug #46272 "MySQL 5.4.4, new MDL: unnecessary deadlock" and bug
      #37346 "innodb does not detect deadlock between update and alter table".
      
      After-review fixes in progress.

    modified:
      sql/sql_base.cc
=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc	2010-01-28 12:08:24 +0000
+++ b/sql/sql_base.cc	2010-01-28 17:45:43 +0000
@@ -4343,6 +4343,70 @@ end:
 
 
 /**
+  Acquire upgradable (SNW, SNRW) metadata locks on tables to be opened
+  for LOCK TABLES or a DDL statement.
+
+  @param thd           Thread context.
+  @param tables_start  Start of list of tables on which upgradable locks
+                       should be acquired.
+  @param tables_end    End of list of tables.
+  @param ot_ctx        Context of open_tables() operation.
+
+  @retval FALSE  Success.
+  @retval TRUE   Failure (e.g. connection was killed)
+*/
+
+static bool
+open_tables_acquire_upgradable_mdl(THD *thd, TABLE_LIST *tables_start,
+                                   TABLE_LIST *tables_end,
+                                   Open_table_context *ot_ctx)
+{
+  MDL_request_list mdl_requests;
+  TABLE_LIST *table;
+
+  for (table= tables_start; table && table != tables_end;
+       table= table->next_global)
+  {
+    if (table->lock_type >= TL_WRITE_ALLOW_WRITE)
+    {
+      table->mdl_request.set_type(table->lock_type > TL_WRITE_ALLOW_READ ?
+                                  MDL_SHARED_NO_READ_WRITE :
+                                  MDL_SHARED_NO_WRITE);
+      mdl_requests.push_front(&table->mdl_request);
+    }
+  }
+
+  if (! mdl_requests.is_empty())
+  {
+    MDL_request *global_request;
+
+    if (!(global_request= ot_ctx->get_global_mdl_request(thd)))
+      return TRUE;
+    if (! global_request->ticket)
+    {
+      if (thd->mdl_context.acquire_global_intention_exclusive_lock(global_request))
+        return TRUE;
+    }
+  }
+
+  if (thd->mdl_context.acquire_exclusive_locks(&mdl_requests))
+    return TRUE;
+
+  for (table= tables_start; table && table != tables_end;
+       table= table->next_global)
+  {
+    if (table->lock_type >= TL_WRITE_ALLOW_WRITE)
+    {
+      table->mdl_request.ticket= NULL;
+      table->mdl_request.set_type(MDL_SHARED_WRITE);
+    }
+  }
+
+  return FALSE;
+}
+
+
+/**
   Open all tables in list
 
   @param[in]     thd      Thread context.
@@ -4426,52 +4490,16 @@ restart:
     we will be opening corresponding table pre-acquired metadata
     lock will be reused (thanks to the fact that in recursive case
     metadata locks are acquired without waiting).
-
-    QQ: Is there a better place or a way to do this?
-        I am reluctant to put code into Prelocking_strategy as this
-        has nothing to do with extending of prelocking set and is
-        rather about the order in which we acquire MDL locks...
   */
   if ((flags & MYSQL_OPEN_TAKE_UPGRADABLE_MDL) &&
       ! thd->locked_tables_mode)
   {
-    MDL_request_list mdl_requests;
-
-    for (tables= *start; tables && tables != thd->lex->first_not_own_table();
-         tables= tables->next_global)
+    if (open_tables_acquire_upgradable_mdl(thd, *start,
+                                           thd->lex->first_not_own_table(),
+                                           &ot_ctx))
     {
-      if (tables->lock_type >= TL_WRITE_ALLOW_WRITE)
-      {
-        tables->mdl_request.set_type(tables->lock_type > TL_WRITE_ALLOW_READ ?
-                                     MDL_SHARED_NO_READ_WRITE :
-                                     MDL_SHARED_NO_WRITE);
-        mdl_requests.push_front(&tables->mdl_request);
-      }
-    }
-
-    if (! mdl_requests.is_empty())
-    {
-      MDL_request *global_request;
-
-      if (!(global_request= ot_ctx.get_global_mdl_request(thd)))
-        return 1;
-      if (! global_request->ticket)
-      {
-        if (thd->mdl_context.acquire_global_intention_exclusive_lock(global_request))
-          return 1;
-      }
-    }
-
-    thd->mdl_context.acquire_exclusive_locks(&mdl_requests);
-
-    for (tables= *start; tables && tables != thd->lex->first_not_own_table();
-         tables= tables->next_global)
-    {
-      if (tables->lock_type >= TL_WRITE_ALLOW_WRITE)
-      {
-        tables->mdl_request.ticket= NULL;
-        tables->mdl_request.set_type(MDL_SHARED_WRITE);
-      }
+      error= TRUE;
+      goto err;
     }
   }
 


Attachment: [text/bzr-bundle] bzr/dlenev@mysql.com-20100128174543-xlnj29ub4iua0sjz.bundle
Thread
bzr commit into mysql-5.6-next-mr branch (dlenev:3075) Bug#46272Dmitry Lenev28 Jan