List:Commits« Previous MessageNext Message »
From:Mats Kindahl Date:February 20 2012 9:49pm
Subject:bzr push into mysql-trunk branch (mats.kindahl:3617 to 3618) WL#5223
View as plain text  
 3618 Mats Kindahl	2012-02-20
      WL#5223: Binary Log Group Commit
      
      Fixes for review comments by Luis.
      
      - Removing unecessary variables.
      - Adding comments to functions.
      - Simplifying an if-statement.
      - Removing debug printouts that are no longer needed.

    modified:
      sql/binlog.cc
 3617 Mats Kindahl	2012-02-20
      WL#5223: Binary Log Group Commit
      
      There were an error because when a statement was logged using
      THD::binlog_query inside a stored function, it was allocated
      space in the binary log, hence also queued for commit.  This
      committed the transaction, causing the subsequent top-level
      commit to trigger an assertion inside InnoDB.
      
      This patch solves the problem by not forcing a flush (and commit)
      of the statement cache inside THD::binlog_query if called while
      inside the execution of a stored function (or other stored routine).
      This accumulates all the logged queries, which are then flushed to
      the binary when the top-level statement commits.

    modified:
      sql/binlog.cc
=== modified file 'sql/binlog.cc'
--- a/sql/binlog.cc	2012-02-20 20:57:36 +0000
+++ b/sql/binlog.cc	2012-02-20 21:48:59 +0000
@@ -40,10 +40,8 @@
 #include "sql_connect.h"
 #include "sql_class.h"
 #include "debug_sync.h"
-#include "my_atomic.h"
 
 #include <utility>
-#include <algorithm>
 
 using std::max;
 using std::min;
@@ -116,9 +114,10 @@ private:
   structure). It will set up the PSI structures and other "globals"
   correctly (e.g., thread-specific variables).
 
-  On destruction, the original thread will be re-attached
-  automatically. For example, with this code, the value of current_thd
-  will be the same before and after execution of the code.
+  On destruction, the original thread (which is supplied to the
+  constructor) will be re-attached automatically. For example, with
+  this code, the value of current_thd will be the same before and
+  after execution of the code.
 
   @code
   {
@@ -127,6 +126,8 @@ private:
       excursion.attach_to(other_thd[i]);
   }
   @endcode
+
+  @note The class is not designed to be inherited from.
  */
 
 class Thread_excursion
@@ -1044,9 +1045,7 @@ MYSQL_BIN_LOG::force_flush_stmt_cache(TH
   mysql_mutex_lock(&LOCK_available);
 
   bool do_purge = false;
-  if (int err= allocate_space_in_log(thd, &do_purge))
-    error= err;
-  else
+  if (!(error= allocate_space_in_log(thd, &do_purge)))
   {
     /*
       Note that we queue the thread even in the case that there is
@@ -1142,6 +1141,24 @@ static int binlog_prepare(handlerton *ht
 }
 
 
+/**
+  This function is called when the binary log commit a transaction.
+
+  In the role as a transaction coordinator, the binary log will keep a
+  queue of outstanding transactions and ensure that they are committed
+  in order.
+
+  Caches are flushed and writes to the binary log queued before
+  starting to commit all outstranding transactions.
+
+  When the function returns, the session and all preceeding sessions
+  will be committed.
+
+  @param thd Session to commit.
+
+  @param all @c true if this is a real commit or a DDL commit, @c
+  false if it is a "statement commit".
+ */
 int MYSQL_BIN_LOG::commit(THD *thd, bool all)
 {
   DBUG_ENTER("MYSQL_BIN_LOG::commit");
@@ -1149,8 +1166,12 @@ int MYSQL_BIN_LOG::commit(THD *thd, bool
   binlog_cache_mngr *cache_mngr=
     (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton);
   int frozen_caches = 0;
-  int error= 0;
 
+  /*
+    Can be called from init phase, with no cache manager and hence no
+    caches. In that case, we just commit the handlertons that have
+    registered.
+  */
   if (cache_mngr == NULL)
     DBUG_RETURN(ha_commit_htons(thd, all));
 
@@ -1206,17 +1227,22 @@ int MYSQL_BIN_LOG::commit(THD *thd, bool
 
   cache_mngr->flush(thd);
   wait_and_reap(thd);
-  DBUG_RETURN(error);
+  DBUG_RETURN(0);
 }
 
 
+/**
+  Wait until session is committable and, if necessary, reap and commit
+  all outstanding commits.
+
+  Wait for the transaction to be complete and optionally durable (if
+  required by options). The LOCK_durable mutex also protect the commit
+  calls and reaping the binary log queue.
+
+  @param thd Session to commit.
+ */
 void MYSQL_BIN_LOG::wait_and_reap(THD *thd)
 {
-  /*
-    Wait for the transaction to be complete and optionally
-    durable. The LOCK_durable mutex also protect the commit calls and
-    reaping the binary log queue.
-   */
   wait_until_complete(thd);
   Mutex_sentry durable_sentry(&LOCK_durable);
   wait_until_durable(thd);
@@ -1233,7 +1259,12 @@ void MYSQL_BIN_LOG::wait_and_reap(THD *t
 /**
   This function is called once after each statement.
 
-  It has the responsibility to flush the caches to the binary log on commits.
+  All flushing of caches are done inside MYSQL_BIN_LOG::commit, so
+  this function only reset some basic information.
+
+  @todo Eliminate all handlerton functions and the binlog
+  handlerton. Instead move all the functionality into TC_LOG and
+  subclasses (including MYSQL_BIN_LOG).
 
   @param hton  The binlog handlerton.
   @param thd   The client thread that executes the transaction.
@@ -1241,6 +1272,7 @@ void MYSQL_BIN_LOG::wait_and_reap(THD *t
                @false otherwise.
 
   @see handlerton::commit
+  @see MYSQL_BIN_LOG::commit
 */
 static int binlog_commit(handlerton *hton, THD *thd, bool all)
 {
@@ -1248,17 +1280,6 @@ static int binlog_commit(handlerton *hto
   binlog_cache_mngr *const cache_mngr=
     (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton);
 
-  DBUG_PRINT("debug",
-             ("all: %s, all.empty: %s, stmt.empty: %s, in_transaction: %s",
-              YESNO(all),
-              YESNO(thd->transaction.all.is_empty()),
-              YESNO(thd->transaction.stmt.is_empty()),
-              YESNO(thd->in_multi_stmt_transaction_mode())));
-  DBUG_PRINT("debug",
-             ("all.cannot_safely_rollback(): %s, stmt.cannot_safely_rollback(): %s",
-              YESNO(thd->transaction.all.cannot_safely_rollback()),
-              YESNO(thd->transaction.stmt.cannot_safely_rollback())));
-
   if (all)
   {
     cache_mngr->trx_cache.reset();
@@ -2644,7 +2665,8 @@ int MYSQL_BIN_LOG::raw_get_current_log(L
   mysql_mutex_assert_owner(&LOCK_log);
   linfo->complete_pos = last_complete;
   /*
-    I would like to have this assertion here, but 
+    I would like to have this assertion here, but it seems
+    LOCK_durable is not always locked. See show_binlogs().
    */
   // mysql_mutex_assert_owner(&LOCK_durable);
   linfo->durable_pos = last_durable;

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-trunk branch (mats.kindahl:3617 to 3618) WL#5223Mats Kindahl21 Feb