List:Commits« Previous MessageNext Message »
From:Oystein Grovlen Date:August 1 2008 1:29pm
Subject:bzr commit into mysql-6.0-backup branch (oystein.grovlen:2674) Bug#36795
View as plain text  
#At file:///export/home/tmp/oysteing/mysql/mysql-6.0-backup/

 2674 Oystein Grovlen	2008-08-01
      Bug#36795 Concurrency issues when starting backups in parallel.
      
      Raise condition on Backup_restore_ctx::mem_alloc since it is static.
      The failing backup will set mem_alloc to null when terminating.  The
      next time the running backup wants to allocate memory, an assert will
      fail.
      
      Makes mem_alloc non-static.  That way, concurrent backups will not
      interfere.  This requires that it is possible to bstream_alloc to find
      the right Backup_restore_ctx to use.  Fixes that by changing the
      static is_running flag to a static pointer to the Backup_restore_ctx
      of the currently running backup.  If the pointer is null, it means
      that no backup is currently running.
added:
  mysql-test/r/backup_concurrent.result
  mysql-test/t/backup_concurrent.test
modified:
  mysql-test/lib/mtr_report.pl
  sql/backup/backup_kernel.h
  sql/backup/kernel.cc

per-file comments:
  mysql-test/lib/mtr_report.pl
    Filter out expected backup error in backup_concurrent test.
  mysql-test/r/backup_concurrent.result
    New result file.
  mysql-test/t/backup_concurrent.test
    Test starting backups in parallel.
  sql/backup/backup_kernel.h
    Change is_running flag into a pointer (current) to the
    Backup_restore_ctx of the running operation.  Make mem_alloc an
    instance variable to avoid concurrency issues.
  sql/backup/kernel.cc
    Change is_running flag into a pointer (current) to the
    Backup_restore_ctx of the running operation.  Make mem_alloc an
    instance variable to avoid concurrency issues.
=== modified file 'mysql-test/lib/mtr_report.pl'

=== modified file 'mysql-test/lib/mtr_report.pl'
--- a/mysql-test/lib/mtr_report.pl	2008-07-09 07:12:43 +0000
+++ b/mysql-test/lib/mtr_report.pl	2008-08-01 13:29:53 +0000
@@ -334,6 +334,12 @@
 		  /Backup:/ or /Restore:/ or /Can't open the online backup progress tables/
 		) or
                 
+		# backup_concurrent performs a backup that should fail
+		($testname eq 'main.backup_concurrent') and
+		(
+		  /Backup: Can't execute this command because another BACKUP\/RESTORE operation is in progress/
+		) or
+                
 		# The tablespace test triggers error below on purpose
 		($testname eq 'main.backup_tablespace') and
 		(

=== added file 'mysql-test/r/backup_concurrent.result'
--- a/mysql-test/r/backup_concurrent.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/backup_concurrent.result	2008-08-01 13:29:53 +0000
@@ -0,0 +1,29 @@
+DROP DATABASE IF EXISTS backup_concurrent;
+CREATE DATABASE backup_concurrent;
+USE backup_concurrent;
+Creating Table
+CREATE TABLE t (
+t1 INTEGER NOT NULL,
+t2 CHAR(36),
+PRIMARY KEY (t1)
+);
+First Backup
+USE backup_concurrent;
+BACKUP DATABASE backup_concurrent TO 'backup1';
+Starting second backup in another connection.  
+(Should fail because another backup is running.)
+BACKUP DATABASE backup_concurrent TO 'backup2';
+ERROR HY000: Can't execute this command because another BACKUP/RESTORE operation is in progress
+Insert Data
+INSERT INTO t VALUES (1, 'test');
+Wait for first backup to complete
+backup_id
+#
+Starting a third backup when first backup has completed
+BACKUP DATABASE backup_concurrent TO 'backup3';
+backup_id
+#
+
+Test completed. Cleaning up.
+
+DROP DATABASE backup_concurrent;

=== added file 'mysql-test/t/backup_concurrent.test'
--- a/mysql-test/t/backup_concurrent.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/backup_concurrent.test	2008-08-01 13:29:53 +0000
@@ -0,0 +1,59 @@
+###########################################################################
+# Author: Oystein Grovlen
+# Date: 2008-07-31
+# Purpose: To test starting backups in parallel
+###############################################################################
+--source include/not_embedded.inc
+
+#Create Database and object view for this test.
+
+--disable_warnings
+DROP DATABASE IF EXISTS backup_concurrent;
+--enable_warnings
+
+CREATE DATABASE backup_concurrent;
+USE backup_concurrent;
+
+#Create table
+
+--echo Creating Table
+CREATE TABLE t (
+t1 INTEGER NOT NULL,
+t2 CHAR(36),
+PRIMARY KEY (t1)
+);
+
+--echo First Backup
+connect (backup,localhost,root,,);
+USE backup_concurrent;
+send BACKUP DATABASE backup_concurrent TO 'backup1';
+
+--echo Starting second backup in another connection.  
+--echo (Should fail because another backup is running.)
+connection default;
+--error ER_BACKUP_RUNNING
+BACKUP DATABASE backup_concurrent TO 'backup2';
+
+--echo Insert Data
+INSERT INTO t VALUES (1, 'test');
+
+--echo Wait for first backup to complete
+connection backup;
+replace_column 1 #;
+reap;
+
+--echo Starting a third backup when first backup has completed
+replace_column 1 #;
+BACKUP DATABASE backup_concurrent TO 'backup3';
+
+# Test cleanup section
+
+--echo
+--echo Test completed. Cleaning up.
+--echo
+
+DROP DATABASE backup_concurrent;
+
+--remove_file $MYSQLTEST_VARDIR/master-data/backup1
+--remove_file $MYSQLTEST_VARDIR/master-data/backup3
+

=== modified file 'sql/backup/backup_kernel.h'
--- a/sql/backup/backup_kernel.h	2008-07-07 12:51:56 +0000
+++ b/sql/backup/backup_kernel.h	2008-08-01 13:29:53 +0000
@@ -79,9 +79,9 @@
 
  private:
 
-  /** Indicates if a backup/restore operation is in progress. */
-  static bool is_running;
-  static pthread_mutex_t  run_lock; ///< To guard @c is_running flag.
+  /** Indicates if and which backup/restore operation is in progress. */
+  static Backup_restore_ctx *current;
+  static pthread_mutex_t  run_lock; ///< To guard @c current pointer.
 
   /** 
     @brief State of a context object. 
@@ -109,7 +109,7 @@
   backup::Image_info *m_catalog;  ///< Pointer to the image catalogue object.
 
   /** Memory allocator for backup stream library. */
-  static backup::Mem_allocator *mem_alloc;
+  backup::Mem_allocator *mem_alloc;
 
   int prepare(LEX_STRING location);
   void disable_fkey_constraints();

=== modified file 'sql/backup/kernel.cc'
--- a/sql/backup/kernel.cc	2008-07-31 10:45:02 +0000
+++ b/sql/backup/kernel.cc	2008-08-01 13:29:53 +0000
@@ -344,15 +344,14 @@
 
 // static members
 
-bool Backup_restore_ctx::is_running= FALSE;
+Backup_restore_ctx *Backup_restore_ctx::current= NULL;
 pthread_mutex_t Backup_restore_ctx::run_lock;
-backup::Mem_allocator *Backup_restore_ctx::mem_alloc= NULL;
 
 
 Backup_restore_ctx::Backup_restore_ctx(THD *thd)
  :Logger(thd), m_state(CREATED), m_thd_options(thd->options),
   m_error(0), m_path(NULL), m_remove_loc(FALSE), m_stream(NULL),
-  m_catalog(NULL), m_tables_locked(FALSE)
+  m_catalog(NULL), mem_alloc(NULL), m_tables_locked(FALSE)
 {
   /*
     Check for progress tables.
@@ -365,6 +364,7 @@
 {
   close();
   
+  delete mem_alloc;
   delete m_catalog;  
   delete m_stream;
 }
@@ -412,8 +412,8 @@
 
   pthread_mutex_lock(&run_lock);
 
-  if (!is_running)
-    is_running= TRUE;
+  if (!current)
+    current= this;
   else
     fatal_error(ER_BACKUP_RUNNING);
 
@@ -802,10 +802,11 @@
   delete mem_alloc;
   mem_alloc= NULL;
   
-  // deregister this operation
-
+  // deregister this operation if it was running
   pthread_mutex_lock(&run_lock);
-  is_running= FALSE;
+  if (current == this) {
+    current= NULL;
+  }
   pthread_mutex_unlock(&run_lock);
 
   /* 
@@ -1194,9 +1195,10 @@
 {
   using namespace backup;
 
-  DBUG_ASSERT(Backup_restore_ctx::mem_alloc);
+  DBUG_ASSERT(Backup_restore_ctx::current 
+              && Backup_restore_ctx::current->mem_alloc);
 
-  return (bstream_byte*)Backup_restore_ctx::mem_alloc->alloc(size);
+  return (bstream_byte*)Backup_restore_ctx::current->mem_alloc->alloc(size);
 }
 
 /**
@@ -1206,8 +1208,8 @@
 void bstream_free(bstream_byte *ptr)
 {
   using namespace backup;
-  if (Backup_restore_ctx::mem_alloc)
-    Backup_restore_ctx::mem_alloc->free(ptr);
+  if (Backup_restore_ctx::current && Backup_restore_ctx::current->mem_alloc)
+    Backup_restore_ctx::current->mem_alloc->free(ptr);
 }
 
 /**

Thread
bzr commit into mysql-6.0-backup branch (oystein.grovlen:2674) Bug#36795Oystein Grovlen1 Aug
  • RE: bzr commit into mysql-6.0-backup branch (oystein.grovlen:2674) Bug#36795Chuck Bell4 Aug
    • Re: bzr commit into mysql-6.0-backup branch (oystein.grovlen:2674)Bug#36795Øystein Grøvlen5 Aug
      • RE: bzr commit into mysql-6.0-backup branch (oystein.grovlen:2674) Bug#36795Chuck Bell5 Aug
        • Re: bzr commit into mysql-6.0-backup branch (oystein.grovlen:2674)Bug#36795Øystein Grøvlen5 Aug