List:Commits« Previous MessageNext Message »
From:Alfranio Correia Date:October 4 2009 11:28am
Subject:bzr commit into mysql-pe branch (alfranio.correia:3519) Bug#47327
View as plain text  
#At file:///home/acorreia/workspace.sun/repository.mysql/bzrwork/bug-40278/mysql-pe-wl2687-push/ based on revid:alfranio.correia@stripped

 3519 Alfranio Correia	2009-10-04
      BUG#47327 ROLLBACK TO SAVEPOINT binlogged if trx contains non-trx updates before savepoint
      
      Draft of a patch based on the WL#2687.

    modified:
      sql/log.cc
=== modified file 'sql/log.cc'
--- a/sql/log.cc	2009-10-04 01:04:30 +0000
+++ b/sql/log.cc	2009-10-04 11:28:18 +0000
@@ -341,7 +341,7 @@ private:
 
 class binlog_cache_mngr {
 public:
-  binlog_cache_mngr() {}
+  binlog_cache_mngr(): pos_stmt_committed(0), has_stmt_committed(FALSE) {}
 
   void reset_cache(binlog_cache_data* cache_data)
   {
@@ -358,12 +358,49 @@ public:
     return (is_transactional ? &trx_cache.cache_log : &stmt_cache.cache_log);
   }
 
+  void calc_pos_stmt_committed()
+  {
+    pos_stmt_committed= (has_stmt_committed ? pos_stmt_committed :
+                        trx_cache.get_byte_position());
+    has_stmt_committed= TRUE;
+  }
+
+  void recalc_pos_stmt_committed()
+  {
+    if (has_stmt_committed)
+    {
+      my_off_t pos=  trx_cache.get_byte_position();
+      has_stmt_committed=  pos > pos_stmt_committed ? TRUE : FALSE;
+      pos_stmt_committed=  pos > pos_stmt_committed ? pos_stmt_committed : 0;
+    }
+  }
+
+  my_off_t get_pos_stmt_committed()
+  {
+    return (pos_stmt_committed);
+  }
+
+  bool is_stmt_committed()
+  {
+    return (has_stmt_committed);
+  }
+
+  void clear_stmt_committed()
+  {
+    pos_stmt_committed= 0;
+    has_stmt_committed= FALSE;
+  }
+
   binlog_cache_data stmt_cache;
 
   binlog_cache_data trx_cache;
 
 private:
 
+  my_off_t pos_stmt_committed;
+
+  bool has_stmt_committed;
+
   binlog_cache_mngr& operator=(const binlog_cache_mngr& info);
   binlog_cache_mngr(const binlog_cache_mngr& info);
 };
@@ -2680,6 +2717,7 @@ binlog_flush_trx_cache(THD *thd, binlog_
   error= mysql_bin_log.write(thd, &cache_mngr->trx_cache.cache_log, end_ev,
                              cache_mngr->trx_cache.has_incident());
   cache_mngr->reset_cache(&cache_mngr->trx_cache);
+  cache_mngr->clear_stmt_committed();
 
   /*
     We need to step the table map version after writing the
@@ -2726,7 +2764,7 @@ binlog_truncate_trx_cache(THD *thd, binl
                       all ? "all" : "stmt"));
   /*
     If rolling back an entire transaction or a single statement not
-    inside a transaction, we reset the transaction cache.
+    inside a transaction, we reset the transactional cache.
   */
   thd->binlog_remove_pending_rows_event(TRUE, is_transactional);
   if (all || !thd->in_multi_stmt_transaction())
@@ -2735,6 +2773,7 @@ binlog_truncate_trx_cache(THD *thd, binl
       error= mysql_bin_log.write_incident(thd, TRUE);
 
     cache_mngr->reset_cache(&cache_mngr->trx_cache);
+    cache_mngr->clear_stmt_committed();
 
     thd->clear_binlog_table_maps();
   }
@@ -2743,7 +2782,10 @@ binlog_truncate_trx_cache(THD *thd, binl
     transaction cache to remove the statement.
   */
   else
+  {
       cache_mngr->trx_cache.restore_prev_position();
+      cache_mngr->recalc_pos_stmt_committed();
+  }
 
   /*
     We need to step the table map version on a rollback to ensure that a new
@@ -2854,6 +2896,7 @@ static int binlog_commit(handlerton *hto
     */
     // Alfranio
     cache_mngr->reset_cache(&cache_mngr->trx_cache);
+    cache_mngr->clear_stmt_committed();
     DBUG_RETURN(0);
   }
 
@@ -2920,6 +2963,7 @@ static int binlog_rollback(handlerton *h
     */
     // Alfranio
     cache_mngr->reset_cache(&cache_mngr->trx_cache);
+    cache_mngr->clear_stmt_committed();
     DBUG_RETURN(0);
   }
 
@@ -2950,10 +2994,11 @@ static int binlog_rollback(handlerton *h
         . the OPTION_KEEP_LOG is activate.
     */
     if (thd->variables.binlog_format == BINLOG_FORMAT_STMT &&
-        ((all && thd->transaction.all.modified_non_trans_table) ||
-        (!all && thd->transaction.stmt.modified_non_trans_table &&
-        !thd->in_multi_stmt_transaction()) ||
-        (thd->options & OPTION_KEEP_LOG)))
+        ((all && thd->transaction.all.modified_non_trans_table &&
+          cache_mngr->is_stmt_committed()) ||
+         (!all && thd->transaction.stmt.modified_non_trans_table &&
+          cache_mngr->is_stmt_committed() && !thd->in_multi_stmt_transaction()) ||
+         (thd->options & OPTION_KEEP_LOG)))
     {
       Query_log_event qev(thd, STRING_WITH_LEN("ROLLBACK"), TRUE, TRUE, 0);
       error= binlog_flush_trx_cache(thd, cache_mngr, &qev);
@@ -2964,7 +3009,7 @@ static int binlog_rollback(handlerton *h
     */
     else if (all || (!all &&
                      (!thd->transaction.stmt.modified_non_trans_table ||
-                      !thd->in_multi_stmt_transaction() || 
+                      !thd->in_multi_stmt_transaction() ||
                       thd->variables.binlog_format != BINLOG_FORMAT_STMT)))
       error= binlog_truncate_trx_cache(thd, cache_mngr, all);
   }
@@ -2973,7 +3018,7 @@ static int binlog_rollback(handlerton *h
     This is part of the stmt rollback.
   */
   if (!all)
-    cache_mngr->trx_cache.set_prev_position(MY_OFF_T_UNDEF); 
+    cache_mngr->trx_cache.set_prev_position(MY_OFF_T_UNDEF);
   DBUG_RETURN(error);
 }
 
@@ -3058,12 +3103,15 @@ static int binlog_savepoint_rollback(han
 {
   DBUG_ENTER("binlog_savepoint_rollback");
 
+  binlog_cache_mngr *const cache_mngr=
+    (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton);
+
   /*
     Write ROLLBACK TO SAVEPOINT to the binlog cache if we have updated some
     non-transactional table. Otherwise, truncate the binlog cache starting
     from the SAVEPOINT command.
   */
-  if (unlikely(thd->transaction.all.modified_non_trans_table || 
+  if (unlikely(cache_mngr->is_stmt_committed() ||
                (thd->options & OPTION_KEEP_LOG)))
   {
     int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
@@ -6168,6 +6216,9 @@ bool MYSQL_BIN_LOG::write(Log_event *eve
       {
         file= &cache_mngr->trx_cache.cache_log;
         cache_data= &cache_mngr->trx_cache;
+        if (thd->variables.binlog_format == BINLOG_FORMAT_STMT &&
+            thd->transaction.stmt.modified_non_trans_table)
+          cache_mngr->calc_pos_stmt_committed();
       }
    
       thd->binlog_start_trans_and_stmt();


Attachment: [text/bzr-bundle]
Thread
bzr commit into mysql-pe branch (alfranio.correia:3519) Bug#47327Alfranio Correia4 Oct