List:Commits« Previous MessageNext Message »
From:Alfranio Correia Date:January 5 2010 12:15am
Subject:bzr commit into mysql-5.1-rep+3 branch (alfranio.correia:3130)
Bug#50038
View as plain text  
#At file:///home/acorreia/workspace.sun/repository.mysql/bzrwork/bug-50038/mysql-5.1-rep%2B3/ based on revid:dao-gang.qu@stripped

 3130 Alfranio Correia	2010-01-05
      BUG#50038 Deadlock on flush logs with concurrent DML and RBR
      
      In auto-commit mode, updating both trx and non-trx tables (i.e. issuing a mixed statement)
      causes the following sequence of events:
      
      1 - Flush trx changes (MYSQL_BIN_LOG::write):
        1.1 - mutex_lock (&LOCK_log)
        1.2 - mutex_lock (&LOCK_prep_xids)
        1.3 - increase prepared_xids
        1.4 - mutex_unlock (&LOCK_prep_xids)
        1.5 - mutex_unlock (&LOCK_log)
      
      2 - Flush non-trx changes (MYSQL_BIN_LOG::write):
        2.1 - mutex_lock (&LOCK_log)
        2.2 - mutex_unlock (&LOCK_log)
      
      If a FLUSH logs happens between the two flushes, a deadlock may arise due to the following
      sequence of events while processing the command:
      
      3 - FLUSH logs command (MYSQL_BIN_LOG::new_file_impl):
        3.1 - mutex_lock (&LOCK_log)
        3.2 - mutex_lock (&LOCK_prep_xids)
        3.3 - while (prepared_xids)  pthread_cond_wait(..., &LOCK_prep_xids);
        3.4 - mutex_unlock (&LOCK_prep_xids)
        3.5 - mutex_unlock (&LOCK_log)
      
      The execution will pass the while (item 3.3), when the prepared_xids is decreased what
      will happen after the non-trx changes are flushed. However, the transaction cannot
      progress because the mutex LOCK_log is grabbed on behalf of the FLUSH command.
      
      To fix the problem, we ensure that the non-trx changes are always flushed before the
      trx changes.

    modified:
      sql/log.cc
=== modified file 'sql/log.cc'
--- a/sql/log.cc	2009-12-14 10:40:42 +0000
+++ b/sql/log.cc	2010-01-05 00:15:27 +0000
@@ -5958,7 +5958,8 @@ int TC_LOG_BINLOG::log_xid(THD *thd, my_
     We always commit the entire transaction when writing an XID. Also
     note that the return value is inverted.
    */
-  DBUG_RETURN(!binlog_flush_trx_cache(thd, cache_mngr, &xle));
+  DBUG_RETURN(!binlog_flush_stmt_cache(thd, cache_mngr) |
+              !binlog_flush_trx_cache(thd, cache_mngr, &xle));
 }
 
 void TC_LOG_BINLOG::unlog(ulong cookie, my_xid xid)


Attachment: [text/bzr-bundle]
Thread
bzr commit into mysql-5.1-rep+3 branch (alfranio.correia:3130)Bug#50038Alfranio Correia5 Jan
  • Re: bzr commit into mysql-5.1-rep+3 branch (alfranio.correia:3130)Bug#50038Luís Soares5 Jan
    • Re: bzr commit into mysql-5.1-rep+3 branch (alfranio.correia:3130)Bug#50038Alfranio Correia5 Jan
      • Re: bzr commit into mysql-5.1-rep+3 branch (alfranio.correia:3130)Bug#50038Luís Soares5 Jan