List:Commits« Previous MessageNext Message »
From:Lars Thalmann Date:March 30 2006 7:23pm
Subject:bk commit into 5.0 tree (lars:1.2108) BUG#18116
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of lthalmann. When lthalmann does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet
  1.2108 06/03/30 19:23:22 lars@stripped +2 -0
  BUG#18116: Experimental patch only for discussion (needs more work)

  sql/sql_class.h
    1.284 06/03/30 19:23:14 lars@stripped +2 -0
    Experimental patch only for discussion

  sql/log.cc
    1.188 06/03/30 19:23:14 lars@stripped +78 -33
    Experimental patch only for discussion

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	lars
# Host:	dl145k.mysql.com
# Root:	/users/lthalmann/bk/mysql-5.0-bug18116

--- 1.187/sql/log.cc	2006-02-18 17:19:10 +01:00
+++ 1.188/sql/log.cc	2006-03-30 19:23:14 +02:00
@@ -1302,6 +1302,7 @@
 {
   char new_name[FN_REFLEN], *new_name_ptr, *old_name;
   enum_log_type save_log_type;
+  int error=0;
 
   DBUG_ENTER("MYSQL_LOG::new_file");
   if (!is_open())
@@ -1317,24 +1318,6 @@
   safe_mutex_assert_owner(&LOCK_log);
   safe_mutex_assert_owner(&LOCK_index);
 
-  /*
-    if binlog is used as tc log, be sure all xids are "unlogged",
-    so that on recover we only need to scan one - latest - binlog file
-    for prepared xids. As this is expected to be a rare event,
-    simple wait strategy is enough. We're locking LOCK_log to be sure no
-    new Xid_log_event's are added to the log (and prepared_xids is not
-    increased), and waiting on COND_prep_xids for late threads to
-    catch up.
-  */
-  if (prepared_xids)
-  {
-    tc_log_page_waits++;
-    pthread_mutex_lock(&LOCK_prep_xids);
-    while (prepared_xids)
-      pthread_cond_wait(&COND_prep_xids, &LOCK_prep_xids);
-    pthread_mutex_unlock(&LOCK_prep_xids);
-  }
-
   /* Reuse old name if not binlog and not update log */
   new_name_ptr= name;
 
@@ -1374,6 +1357,26 @@
   close(LOG_CLOSE_TO_BE_OPENED);
 
   /*
+    if binlog is used as tc log, be sure all xids are "unlogged",
+    so that on recover we only need to scan one - latest - binlog file
+    for prepared xids. As this is expected to be a rare event,
+    simple wait strategy is enough. We're locking LOCK_log to be sure no
+    new Xid_log_event's are added to the log (and prepared_xids is not
+    increased), and waiting on COND_prep_xids for late threads to
+    catch up.
+  */
+/*
+  if (prepared_xids)
+  {
+    tc_log_page_waits++;
+    pthread_mutex_lock(&LOCK_prep_xids);
+    while (prepared_xids)
+      pthread_cond_wait(&COND_prep_xids, &LOCK_prep_xids);
+    pthread_mutex_unlock(&LOCK_prep_xids);
+  }
+*/
+
+  /*
      Note that at this point, log_type != LOG_CLOSED (important for is_open()).
   */
 
@@ -1390,6 +1393,34 @@
        io_cache_type, no_auto_events, max_size, 1);
   my_free(old_name,MYF(0));
 
+  if (prepared_xids)
+  {
+    pthread_mutex_lock(&LOCK_prep_xids);
+    while (prepared_xids)
+    {
+      List_iterator<my_xid> it(prepared_xid_list);
+      my_xid *t;
+
+      while ((t= it++))
+      {
+        DBUG_PRINT("info", ("Adding extra commit for xid %d in new file", *t));
+        THD dummy_thd;
+        dummy_thd.server_id= 0;
+        dummy_thd.start_time= 0;
+        Xid_log_event xle(&dummy_thd, *t);
+
+        /* TODO: NEED TO FIX PROPER LOCKING */
+
+        need_lock=0;
+        if ((error= write(&xle))) goto end;
+        need_lock=1; 
+
+        /* TODO: WE NEED ERROR HANDLING HERE */
+      }
+    }
+    pthread_mutex_unlock(&LOCK_prep_xids);
+  }
+
 end:
   if (need_lock)
     pthread_mutex_unlock(&LOCK_log);
@@ -1586,6 +1617,8 @@
   Write an event to the binary log
 */
 
+bool need_lock= 1;
+
 bool MYSQL_LOG::write(Log_event *event_info)
 {
   THD *thd= event_info->thd;
@@ -1603,7 +1636,7 @@
     DBUG_RETURN(0);
   }
   
-  pthread_mutex_lock(&LOCK_log);
+  if (need_lock) pthread_mutex_lock(&LOCK_log);
 
   /*
      In most cases this is only called if 'is_open()' is true; in fact this is
@@ -1623,7 +1656,7 @@
     if ((thd && !(thd->options & OPTION_BIN_LOG)) ||
 	(!db_ok(local_db, binlog_do_db, binlog_ignore_db)))
     {
-      VOID(pthread_mutex_unlock(&LOCK_log));
+      if (need_lock) VOID(pthread_mutex_unlock(&LOCK_log));
       DBUG_PRINT("error",("!db_ok('%s')", local_db));
       DBUG_RETURN(0);
     }
@@ -1752,7 +1785,7 @@
     }
   }
 
-  pthread_mutex_unlock(&LOCK_log);
+  if (need_lock) pthread_mutex_unlock(&LOCK_log);
   DBUG_RETURN(error);
 }
 
@@ -1873,18 +1906,7 @@
       goto err;
     }
     signal_update();
-    /*
-      if commit_event is Xid_log_event, increase the number of
-      prepared_xids (it's decreasd in ::unlog()). Binlog cannot be rotated
-      if there're prepared xids in it - see the comment in new_file() for
-      an explanation.
-      If the commit_event is not Xid_log_event (then it's a Query_log_event)
-      rotate binlog, if necessary.
-    */
-    if (commit_event->get_type_code() == XID_EVENT)
-      thread_safe_increment(prepared_xids, &LOCK_prep_xids);
-    else
-      rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED);
+    rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED);
   }
   VOID(pthread_mutex_unlock(&LOCK_log));
 
@@ -3009,12 +3031,35 @@
 {
   Xid_log_event xle(thd, xid);
   IO_CACHE *trans_log= (IO_CACHE*)thd->ha_data[binlog_hton.slot];
+
+  /*
+    Increase the number of prepared_xids (it's decreased in
+    ::unlog()).
+  */
+  prepared_xid_list.push_back(new my_xid(xid));
+  thread_safe_increment(prepared_xids, &LOCK_prep_xids);
   return !binlog_end_trans(thd, trans_log, &xle);  // invert return value
 }
 
 void TC_LOG_BINLOG::unlog(ulong cookie, my_xid xid)
 {
   pthread_mutex_lock(&LOCK_prep_xids);
+
+  List_iterator<my_xid> it(prepared_xid_list);
+  my_xid *t;
+
+  while ((t= it++))
+  {
+    DBUG_PRINT("info", ("Unlogging xid %d\n", *t));
+    if (xid == *t)
+    {
+      it.remove();
+      goto end;
+    }
+  }
+  DBUG_ASSERT(0);  // Trying to remove non-logged xid
+
+end:
   if (--prepared_xids == 0)
     pthread_cond_signal(&COND_prep_xids);
   pthread_mutex_unlock(&LOCK_prep_xids);

--- 1.283/sql/sql_class.h	2006-03-10 15:47:43 +01:00
+++ 1.284/sql/sql_class.h	2006-03-30 19:23:14 +02:00
@@ -213,6 +213,8 @@
   */
   ulong max_size;
   ulong prepared_xids; /* for tc log - number of xids to remember */
+  List<my_xid> prepared_xid_list;
+
   volatile enum_log_type log_type;
   enum cache_type io_cache_type;
   // current file sequence number for load data infile binary logging
Thread
bk commit into 5.0 tree (lars:1.2108) BUG#18116Lars Thalmann30 Mar