List:Commits« Previous MessageNext Message »
From:Jorgen Loland Date:November 20 2008 9:49am
Subject:bzr commit into mysql-6.0-backup branch (jorgen.loland:2739) Bug#32465
View as plain text  
#At file:///localhome/jl208045/mysql/mysql-6.0-backup-32465/

 2739 Jorgen Loland	2008-11-20
      Bug#32465 - Backup: Commit blocker does not block tables in default driver
                                    
      Patch (2/2): The patch contains new validity point tests written for the temporary commit blocker solution of setting Global Read Lock before backup prepare phase (fixed in bug#39602). The backup_vp* tests replace the old backup_commit_blocker tests.
added:
  mysql-test/suite/backup/r/backup_vp_nontx.result
  mysql-test/suite/backup/r/backup_vp_tx.result
  mysql-test/suite/backup/t/backup_vp_nontx.test
  mysql-test/suite/backup/t/backup_vp_tx.test

per-file messages:
  mysql-test/suite/backup/r/backup_vp_nontx.result
    Backup validity point test for non-transactional engine
  mysql-test/suite/backup/r/backup_vp_tx.result
    Backup validity point test for transactional engine
  mysql-test/suite/backup/t/backup_vp_nontx.test
    Backup validity point test for non-transactional engine
  mysql-test/suite/backup/t/backup_vp_tx.test
    Backup validity point test for transactional engine
=== added file 'mysql-test/suite/backup/r/backup_vp_nontx.result'
--- a/mysql-test/suite/backup/r/backup_vp_nontx.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup/r/backup_vp_nontx.result	2008-11-20 09:49:34 +0000
@@ -0,0 +1,115 @@
+SET DEBUG_SYNC= 'RESET';
+DROP DATABASE IF EXISTS bup_vp;
+CREATE DATABASE bup_vp;
+
+Starting Test
+
+con_bup: Creating tables
+CREATE TABLE bup_vp.t1 (col_a CHAR(40)) ENGINE=MEMORY;
+con_bup: Loading data
+con_bup: Scenario a) - commited before backup
+INSERT INTO bup_vp.t1 VALUES ("01 Some data to test");
+INSERT INTO bup_vp.t1 VALUES ("02 Some data to test");
+INSERT INTO bup_vp.t1 VALUES ("03 Some data to test");
+INSERT INTO bup_vp.t1 VALUES ("04 Some data to test");
+INSERT INTO bup_vp.t1 VALUES ("05 Some data to test");
+
+con_bup: Show the data before we start backup
+SELECT * FROM bup_vp.t1;
+col_a
+01 Some data to test
+02 Some data to test
+03 Some data to test
+04 Some data to test
+05 Some data to test
+
+Scenario (b): Insert in progress blocks CB and is included in backup
+con_ntx1: Start insert and stop it in the middle of processing
+con_ntx1: Make insert stop in the middle of execution
+SET DEBUG_SYNC= 'after_insert_locked_tables SIGNAL insert_started
+                   WAIT_FOR complete_insert';
+INSERT INTO bup_vp.t1 VALUES ("ntx1: 06 Some data to test");
+
+con_bup: Activate synchronization points for BACKUP.
+SET DEBUG_SYNC= 'wait_lock_global_read_lock SIGNAL sync_complete_insert';
+SET DEBUG_SYNC= 'before_backup_data_lock SIGNAL try_insert
+                 WAIT_FOR insert_blocked';
+SET DEBUG_SYNC= 'after_backup_binlog SIGNAL commit_unblocked
+                 WAIT_FOR finish_bup';
+con_bup: Backing up database -- will block with lock
+BACKUP DATABASE bup_vp TO "bup_vp.bak";
+
+SET DEBUG_SYNC= 'now WAIT_FOR sync_complete_insert';
+Backup has been blocked by ongoing insert
+SET DEBUG_SYNC= 'now SIGNAL complete_insert';
+
+con_ntx1: Reap insert
+Check that record has been inserted; Should be 1 record
+SELECT * FROM bup_vp.t1 WHERE col_a like 'ntx1%';
+col_a
+ntx1: 06 Some data to test
+
+con_ntx2: Wait until backup has set CB, then try to insert
+SET DEBUG_SYNC= 'now WAIT_FOR try_insert';
+SET DEBUG_SYNC= 'wait_if_global_read_lock SIGNAL sync_insert_blocked';
+INSERT INTO bup_vp.t1 VALUES ("ntx2: Should NOT be in backup");
+
+SET DEBUG_SYNC= 'now WAIT_FOR sync_insert_blocked';
+Insert in ntx2 is blocked and should not be in t1; Should be 0 records
+SELECT * FROM bup_vp.t1 WHERE col_a like 'ntx2%';
+col_a
+
+SET DEBUG_SYNC= 'now SIGNAL insert_blocked';
+
+con_ntx1: Backup has now released CB. Perform insert
+SET DEBUG_SYNC= 'now WAIT_FOR commit_unblocked';
+INSERT INTO bup_vp.t1 VALUES ("ntx1: Should NOT be in backup");
+SET DEBUG_SYNC= 'now SIGNAL finish_bup';
+
+con_ntx1: Reap backup
+backup_id
+#
+
+con_bup: Showing data after updates and backup
+SELECT * FROM bup_vp.t1;
+col_a
+01 Some data to test
+02 Some data to test
+03 Some data to test
+04 Some data to test
+05 Some data to test
+ntx1: 06 Some data to test
+ntx2: Should NOT be in backup
+ntx1: Should NOT be in backup
+con_bup: Dropping the database
+DROP TABLE bup_vp.t1;
+DROP DATABASE bup_vp;
+con_bup: Restoring the database
+RESTORE FROM "bup_vp.bak";
+backup_id
+#
+
+con_bup: Showing the data after restore
+SELECT * FROM bup_vp.t1;
+col_a
+01 Some data to test
+02 Some data to test
+03 Some data to test
+04 Some data to test
+05 Some data to test
+ntx1: 06 Some data to test
+
+Verifying results:
+
+T1 should have changes from con_ntx1; Should be 1 record
+SELECT * FROM bup_vp.t1 WHERE col_a like 'ntx1%';
+col_a
+ntx1: 06 Some data to test
+
+T1 should not have the changes from con_ntx2; Should be 0 records
+SELECT * FROM bup_vp.t1 WHERE col_a like 'ntx2%';
+col_a
+
+con_bup: Cleanup
+DROP DATABASE bup_vp;
+SET DEBUG_SYNC= 'RESET';

=== added file 'mysql-test/suite/backup/r/backup_vp_tx.result'
--- a/mysql-test/suite/backup/r/backup_vp_tx.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup/r/backup_vp_tx.result	2008-11-20 09:49:34 +0000
@@ -0,0 +1,203 @@
+SET DEBUG_SYNC= 'RESET';
+DROP DATABASE IF EXISTS bup_vp;
+CREATE DATABASE bup_vp;
+
+Starting Test
+
+con_bup: Creating tables
+CREATE TABLE bup_vp.t1 (col_a CHAR(40)) ENGINE=INNODB;
+CREATE TABLE bup_vp.t2 (col_a CHAR(40)) ENGINE=INNODB;
+CREATE TABLE bup_vp.t3 (col_a CHAR(40)) ENGINE=INNODB;
+
+con_bup: Loading data
+con_bup: Scenario a) - commited before backup
+INSERT INTO bup_vp.t1 VALUES ("01 Some data to test");
+INSERT INTO bup_vp.t1 VALUES ("02 Some data to test");
+INSERT INTO bup_vp.t1 VALUES ("03 Some data to test");
+INSERT INTO bup_vp.t1 VALUES ("04 Some data to test");
+INSERT INTO bup_vp.t1 VALUES ("05 Some data to test");
+INSERT INTO bup_vp.t2 VALUES ("01 Some data to test");
+INSERT INTO bup_vp.t2 VALUES ("02 Some data to test");
+INSERT INTO bup_vp.t2 VALUES ("03 Some data to test");
+INSERT INTO bup_vp.t2 VALUES ("04 Some data to test");
+INSERT INTO bup_vp.t2 VALUES ("05 Some data to test");
+INSERT INTO bup_vp.t3 VALUES ("01 Some data to test");
+INSERT INTO bup_vp.t3 VALUES ("02 Some data to test");
+INSERT INTO bup_vp.t3 VALUES ("03 Some data to test");
+INSERT INTO bup_vp.t3 VALUES ("04 Some data to test");
+INSERT INTO bup_vp.t3 VALUES ("05 Some data to test");
+
+con_bup: Show the data before we start backup
+SELECT * FROM bup_vp.t1;
+col_a
+01 Some data to test
+02 Some data to test
+03 Some data to test
+04 Some data to test
+05 Some data to test
+SELECT * FROM bup_vp.t2;
+col_a
+01 Some data to test
+02 Some data to test
+03 Some data to test
+04 Some data to test
+05 Some data to test
+SELECT * FROM bup_vp.t3;
+col_a
+01 Some data to test
+02 Some data to test
+03 Some data to test
+04 Some data to test
+05 Some data to test
+
+Scenario d) - commit after VP; tx not included in backup
+con_tx3: Start transaction but do not commit
+BEGIN;
+INSERT INTO bup_vp.t3 VALUES ("tx3: 06 Should NOT be in backup");
+
+Scenario b) - Commit in progress blocks CB; tx is included in backup
+con_tx1: Get a transaction going and stop in the middle of commit
+BEGIN;
+INSERT INTO bup_vp.t1 VALUES ("tx1: 06 Some data to test");
+con_tx1: Make commit stop in the middle of execution
+SET DEBUG_SYNC= 'within_ha_commit_trans SIGNAL commit_started
+                       WAIT_FOR complete_commit';
+COMMIT;
+
+Scenario c) - commit blocked by CB; tx not included in backup
+con_tx2: Wait until tx1 has started
+SET DEBUG_SYNC= 'now WAIT_FOR commit_started';
+con_tx2: Start transaction but do not commit
+BEGIN;
+INSERT INTO bup_vp.t2 VALUES ("tx2: 06 Should NOT be in backup");
+
+con_bup: Activate synchronization points for BACKUP.
+SET DEBUG_SYNC= 'wait_lock_global_read_lock SIGNAL sync_complete_commit';
+SET DEBUG_SYNC= 'before_backup_data_lock SIGNAL try_commit 
+                 WAIT_FOR commit_blocked';
+SET DEBUG_SYNC= 'after_backup_binlog SIGNAL commit_unblocked
+                 WAIT_FOR finish_bup';
+con_bup: Backing up database -- will block with lock
+BACKUP DATABASE bup_vp TO "bup_vp.bak";
+
+SET DEBUG_SYNC= 'now WAIT_FOR sync_complete_commit';
+Backup has been blocked by ongoing commit
+Check that con_tx1 has not committed; Should be 0 records
+SELECT * FROM bup_vp.t1 WHERE col_a like 'tx1%';
+col_a
+
+SET DEBUG_SYNC= 'now SIGNAL complete_commit';
+
+con_tx1: Reap commit
+Check that con_tx1 has committed; Should be 1 record
+SELECT * FROM bup_vp.t1 WHERE col_a like 'tx1%';
+col_a
+tx1: 06 Some data to test
+
+
+con_tx2: Commit request will be blocked by CB
+SET DEBUG_SYNC= 'now WAIT_FOR try_commit';
+SET DEBUG_SYNC= 'wait_if_global_read_lock SIGNAL sync_commit_blocked';
+COMMIT;
+
+SET DEBUG_SYNC= 'now WAIT_FOR sync_commit_blocked';
+Check that con_tx2 has not committed; Should be 0 records
+SELECT * FROM bup_vp.t2 WHERE col_a like 'tx2%';
+col_a
+
+SET DEBUG_SYNC= 'now SIGNAL commit_blocked';
+
+con_bup: Reap commit
+con_tx2: Backup has now released CB.
+Check that con_tx2 has committed; Should be 1 record
+SELECT * FROM bup_vp.t2 WHERE col_a like 'tx2%';
+col_a
+tx2: 06 Should NOT be in backup
+
+
+con_tx3: Backup has now released CB. Commit transaction
+SET DEBUG_SYNC= 'now WAIT_FOR commit_unblocked';
+COMMIT;
+SET DEBUG_SYNC= 'now SIGNAL finish_bup';
+
+con_bup: Reap backup
+backup_id
+#
+
+con_bup: Showing data after updates and backup
+SELECT * FROM bup_vp.t1;
+col_a
+01 Some data to test
+02 Some data to test
+03 Some data to test
+04 Some data to test
+05 Some data to test
+tx1: 06 Some data to test
+SELECT * FROM bup_vp.t2;
+col_a
+01 Some data to test
+02 Some data to test
+03 Some data to test
+04 Some data to test
+05 Some data to test
+tx2: 06 Should NOT be in backup
+SELECT * FROM bup_vp.t3;
+col_a
+01 Some data to test
+02 Some data to test
+03 Some data to test
+04 Some data to test
+05 Some data to test
+tx3: 06 Should NOT be in backup
+con_bup: Dropping the database
+DROP TABLE bup_vp.t1;
+DROP TABLE bup_vp.t2;
+DROP TABLE bup_vp.t3;
+DROP DATABASE bup_vp;
+con_bup: Restoring the database
+RESTORE FROM "bup_vp.bak";
+backup_id
+#
+
+con_bup: Showing the data after restore (tx2 and tx3 should not be there)
+SELECT * FROM bup_vp.t1;
+col_a
+01 Some data to test
+02 Some data to test
+03 Some data to test
+04 Some data to test
+05 Some data to test
+tx1: 06 Some data to test
+SELECT * FROM bup_vp.t2;
+col_a
+01 Some data to test
+02 Some data to test
+03 Some data to test
+04 Some data to test
+05 Some data to test
+SELECT * FROM bup_vp.t3;
+col_a
+01 Some data to test
+02 Some data to test
+03 Some data to test
+04 Some data to test
+05 Some data to test
+
+Verifying results:
+
+T1 should have changes from con_tx1; Should be 1 record
+SELECT * FROM bup_vp.t1 WHERE col_a like 'tx1%';
+col_a
+tx1: 06 Some data to test
+
+T2 should not have the changes from con_tx2; Should be 0 records
+SELECT * FROM bup_vp.t2 WHERE col_a like 'tx2%';
+col_a
+
+T3 should not have the changes from con_tx3; Should be 0 records
+SELECT * FROM bup_vp.t3 WHERE col_a like 'tx3%';
+col_a
+
+con_bup: Cleanup
+DROP DATABASE bup_vp;
+SET DEBUG_SYNC= 'RESET';

=== added file 'mysql-test/suite/backup/t/backup_vp_nontx.test'
--- a/mysql-test/suite/backup/t/backup_vp_nontx.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup/t/backup_vp_nontx.test	2008-11-20 09:49:34 +0000
@@ -0,0 +1,256 @@
+#
+# This test is one of two validity point tests. See:
+#    backup_vp_tx.test
+#
+# The goal of the test should be to ensure the following assumptions
+# for the behavior of validity point (VP) hold. Validity point is
+# implemented using commit blocker (CB).
+#
+# Note: in this file, "DML" refers to DML operations executed in
+#       non-transactional storage engines.
+#
+# a) DMLs that are executed before VP are in the backup image
+#
+# b) setting the validity point should not be done while DMLs are
+#    being processed in any table involved in the backup. An active
+#    DML therefore blocks backup from setting commit blocker. The DML
+#    has to complete before backup can set CB (and ultimately set the
+#    VP), and will therefore be in the backup image
+#
+# c) setting the validity point should not be done while DMLs are
+#    being processed in any table involved in the backup. A DML
+#    operation requested when backup is ready to set VP is therefore
+#    blocked by CB. The DML has to wait for CB to be released before
+#    it can continue, and will therefore not be in the backup image
+#
+# d) DMLs executed after VP are not in the backup image
+#
+#
+
+--source include/have_debug_sync.inc
+--source include/not_embedded.inc
+
+--disable_warnings
+SET DEBUG_SYNC= 'RESET';
+DROP DATABASE IF EXISTS bup_vp;
+
+let $bdir=`SELECT @@backupdir`;
+
+--error 0,1
+remove_file $bdir/bup_vp.bak;
+--enable_warnings
+
+
+CREATE DATABASE bup_vp;
+
+#
+# Connections used in this test
+#
+# con_bup  - used to create data, load data, and run the backup 
+# con_ntx1 - used for non-transactional execution
+# con_ntx2 - used for non-transactional execution
+# con_sync - used to make sync point work flow easier to read
+#
+
+connect (con_bup,localhost,root,,);
+connect (con_ntx1,localhost,root,,);
+connect (con_ntx2,localhost,root,,);
+connect (con_sync,localhost,root,,);
+
+connection con_bup;
+
+--echo 
+--echo Starting Test
+--echo 
+
+#
+# Sequence diagram (not UML), only relevant parts shown
+#
+#      bup     tx1      tx2
+#       |       |        | 
+#       a)      |        | 
+#    (setup)    |        | 
+#       |       b)       | 
+#       |    INSERT      | 
+#     BACKUP  <...>      | 
+#     SET CB  <...>      | 
+#     <###>   <...>      | 
+#     <...>     |        c)
+#       |       |     INSERT
+#    SET VP     |      <###>
+#   RELEASE CB  |      <###>
+#       |       d)     <...>
+#       |    INSERT      | 
+#    BUP DONE   |        | 
+#   (results)   |        | 
+#
+# Note: Ongoing operations are indicated with <...>
+#       Blocked operations are indicated with <###>
+#
+
+# Create transaction tables and load them with data.
+--echo con_bup: Creating tables
+CREATE TABLE bup_vp.t1 (col_a CHAR(40)) ENGINE=MEMORY;
+
+--echo con_bup: Loading data
+--echo con_bup: Scenario a) - commited before backup
+INSERT INTO bup_vp.t1 VALUES ("01 Some data to test");
+INSERT INTO bup_vp.t1 VALUES ("02 Some data to test");
+INSERT INTO bup_vp.t1 VALUES ("03 Some data to test");
+INSERT INTO bup_vp.t1 VALUES ("04 Some data to test");
+INSERT INTO bup_vp.t1 VALUES ("05 Some data to test");
+
+--echo 
+--echo con_bup: Show the data before we start backup
+SELECT * FROM bup_vp.t1;
+
+### CON 1 ###
+  --echo 
+  connection con_ntx1;
+
+  --echo Scenario (b): Insert in progress blocks CB and is included in backup
+  --echo con_ntx1: Start insert and stop it in the middle of processing
+
+  --echo con_ntx1: Make insert stop in the middle of execution
+  # Will continue once backup has been blocked from setting CB
+  SET DEBUG_SYNC= 'after_insert_locked_tables SIGNAL insert_started
+                   WAIT_FOR complete_insert';
+  send INSERT INTO bup_vp.t1 VALUES ("ntx1: 06 Some data to test");
+
+
+### CON BUP ###
+--echo 
+connection con_bup;
+
+# Backup will be blocked from setting CB by the ongoing insert in
+# con_ntx1. Backup will signal con_ntx1 that it has been blocked. The
+# insert will then finish, making backup able to set CB. When CB has
+# been set, ntx2 will be signaled to try to insert. ntx2 insert will
+# be blocked by the CB and send a signal that it has been blocked. CB
+# is then released, but backup is stopped immediately after releasing
+# CB. ntx2 will now be able to complete the insert, and ntx1 will
+# issue and complete another insert. Finally, backup is allowed to
+# complete.
+
+--echo con_bup: Activate synchronization points for BACKUP.
+# Signal when backup is blocked by ongoing insert in con_ntx1
+SET DEBUG_SYNC= 'wait_lock_global_read_lock SIGNAL sync_complete_insert';
+
+# ntx1 insert is completed, so backup can set CB. Just before reaching
+# VP, signal ntx2 should try to insert. Wait until ntx2 signals it has
+# been blocked
+SET DEBUG_SYNC= 'before_backup_data_lock SIGNAL try_insert
+                 WAIT_FOR insert_blocked';
+
+# ntx2 insert has been blocked. Create VP and release CB, and then wait
+# while ntx2 and ntx1 inserts.
+SET DEBUG_SYNC= 'after_backup_binlog SIGNAL commit_unblocked
+                 WAIT_FOR finish_bup';
+
+--echo con_bup: Backing up database -- will block with lock
+send BACKUP DATABASE bup_vp TO "bup_vp.bak";
+
+### CON SYNC ###
+--echo 
+connection con_sync;
+SET DEBUG_SYNC= 'now WAIT_FOR sync_complete_insert';
+--echo Backup has been blocked by ongoing insert
+
+# cannot test with select that insert has not completed ntx1 has X-lock
+SET DEBUG_SYNC= 'now SIGNAL complete_insert';
+
+### CON 1 ###
+  --echo 
+  connection con_ntx1;
+  --echo con_ntx1: Reap insert
+  reap;
+
+  --echo Check that record has been inserted; Should be 1 record
+  SELECT * FROM bup_vp.t1 WHERE col_a like 'ntx1%';
+  --echo 
+
+###########
+## Below this line happens after BACKUP has taken CB
+###########
+
+### CON 2 ###
+    connection con_ntx2;
+
+    --echo con_ntx2: Wait until backup has set CB, then try to insert
+    # Wait for backup to set CB
+    SET DEBUG_SYNC= 'now WAIT_FOR try_insert';
+    # Signal to backup that the insert is blocked
+    SET DEBUG_SYNC= 'wait_if_global_read_lock SIGNAL sync_insert_blocked';
+    send INSERT INTO bup_vp.t1 VALUES ("ntx2: Should NOT be in backup");
+
+    # INSERT is blocked until CB has been released
+
+### CON SYNC ###
+--echo 
+connection con_sync;
+SET DEBUG_SYNC= 'now WAIT_FOR sync_insert_blocked';
+
+--echo Insert in ntx2 is blocked and should not be in t1; Should be 0 records
+SELECT * FROM bup_vp.t1 WHERE col_a like 'ntx2%';
+--echo 
+
+SET DEBUG_SYNC= 'now SIGNAL insert_blocked';
+
+
+### CON 1 ###
+  --echo 
+  connection con_ntx1;
+
+  --echo con_ntx1: Backup has now released CB. Perform insert
+  # Double-check that backup has reached sync point after CB release
+  SET DEBUG_SYNC= 'now WAIT_FOR commit_unblocked';
+  INSERT INTO bup_vp.t1 VALUES ("ntx1: Should NOT be in backup");
+  SET DEBUG_SYNC= 'now SIGNAL finish_bup';
+
+
+### CON BUP ###
+--echo 
+connection con_bup;
+--echo con_ntx1: Reap backup
+--replace_column 1 #
+reap;
+
+
+###########
+## Verify results
+###########
+
+# Do selects to show that all changes got applied.
+--echo 
+--echo con_bup: Showing data after updates and backup
+SELECT * FROM bup_vp.t1;
+
+--echo con_bup: Dropping the database
+DROP TABLE bup_vp.t1;
+DROP DATABASE bup_vp;
+
+--echo con_bup: Restoring the database
+--replace_column 1 #
+RESTORE FROM "bup_vp.bak";
+
+--echo 
+--echo con_bup: Showing the data after restore
+SELECT * FROM bup_vp.t1;
+
+--echo
+--echo Verifying results:
+--echo
+
+--echo T1 should have changes from con_ntx1; Should be 1 record
+SELECT * FROM bup_vp.t1 WHERE col_a like 'ntx1%';
+--echo 
+
+--echo T1 should not have the changes from con_ntx2; Should be 0 records
+SELECT * FROM bup_vp.t1 WHERE col_a like 'ntx2%';
+--echo 
+
+--echo con_bup: Cleanup
+DROP DATABASE bup_vp;
+
+remove_file $bdir/bup_vp.bak;
+SET DEBUG_SYNC= 'RESET';

=== added file 'mysql-test/suite/backup/t/backup_vp_tx.test'
--- a/mysql-test/suite/backup/t/backup_vp_tx.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup/t/backup_vp_tx.test	2008-11-20 09:49:34 +0000
@@ -0,0 +1,329 @@
+#
+# This test is one of two validity point tests. See:
+#    backup_vp_nontx.test
+#
+# The goal of the test should be to ensure the following assumptions
+# for the behavior of validity point (VP) hold. Validity point is
+# implemented using commit blocker (CB).
+#
+# a) transactions that commit before VP are in the backup image
+#
+# b) setting the validity point should not be done while commits are
+#    being processed in any table involved in the backup. Transactions
+#    with ongoing commits therefore block backup from setting commit
+#    blocker. The commit has to complete before backup can set CB (and
+#    ultimately set the VP), and will therefore be in the backup image
+#
+# c) setting the validity point should not be done while commits are
+#    being processed in any table involved in the backup. Transactions
+#    that try to commit when backup is ready to set VP are therefore
+#    blocked by CB. The commit has to wait for CB to be released
+#    before it can continue, and will therefore not be in the backup
+#    image
+#
+# d) transactions that commit after VP are not in the backup image
+#
+# Note: the transactions have to modify data.
+#
+#
+#
+
+--source include/have_innodb.inc
+--source include/have_debug_sync.inc
+--source include/not_embedded.inc
+
+--disable_warnings
+SET DEBUG_SYNC= 'RESET';
+DROP DATABASE IF EXISTS bup_vp;
+
+let $bdir=`SELECT @@backupdir`;
+
+--error 0,1
+remove_file $bdir/bup_vp.bak;
+--enable_warnings
+
+CREATE DATABASE bup_vp;
+
+#
+# Connections used in this test
+#
+# con_bup  - used to create data, load data, and run the backup 
+# con_tx1  - used for transactional execution
+# con_tx2  - used for transactional execution
+# con_tx3  - used for transactional execution
+# con_sync - used to make sync point work flow easier to read
+#
+
+connect (con_bup,localhost,root,,);
+connect (con_tx1,localhost,root,,);
+connect (con_tx2,localhost,root,,);
+connect (con_tx3,localhost,root,,);
+connect (con_sync,localhost,root,,);
+
+connection con_bup;
+
+--echo 
+--echo Starting Test
+--echo 
+
+#
+# Sequence diagram (not UML), only relevant parts shown
+#
+#      bup     tx1      tx2      tx3
+#       |       |        |        |
+#       a)      |        |        |
+#    (setup)    |        |        |
+#     COMMIT    |        |        d)
+#       |       |        |      BEGIN
+#       |       b)       |    INSERT t3
+#       |     BEGIN      |        |
+#       |   INSERT t1    |        |
+#       |     COMMIT     c)       |
+#       |     <...>    BEGIN      |
+#       |     <...>  INSERT t2    |
+#       |     <...>      |        |   
+#     BACKUP  <...>      |        |
+#     SET CB  <...>      |        |   
+#     <###>   <...>      |        |  
+#     <...>     |        |        |  
+#       |       |     COMMIT      |  
+#    SET VP     |      <###>      |   
+#   RELEASE CB  |      <###>      |  
+#       |       |      <...>    COMMIT
+#       |       |        |        |  
+#    BUP DONE   |        |        |  
+#   (results)   |        |        |     
+#
+# Note: Ongoing operations are indicated with <...>
+#       Blocked operations are indicated with <###>
+#
+
+# Create transaction tables and load them with data.
+--echo con_bup: Creating tables
+CREATE TABLE bup_vp.t1 (col_a CHAR(40)) ENGINE=INNODB;
+CREATE TABLE bup_vp.t2 (col_a CHAR(40)) ENGINE=INNODB;
+CREATE TABLE bup_vp.t3 (col_a CHAR(40)) ENGINE=INNODB;
+
+--echo 
+--echo con_bup: Loading data
+--echo con_bup: Scenario a) - commited before backup
+INSERT INTO bup_vp.t1 VALUES ("01 Some data to test");
+INSERT INTO bup_vp.t1 VALUES ("02 Some data to test");
+INSERT INTO bup_vp.t1 VALUES ("03 Some data to test");
+INSERT INTO bup_vp.t1 VALUES ("04 Some data to test");
+INSERT INTO bup_vp.t1 VALUES ("05 Some data to test");
+
+INSERT INTO bup_vp.t2 VALUES ("01 Some data to test");
+INSERT INTO bup_vp.t2 VALUES ("02 Some data to test");
+INSERT INTO bup_vp.t2 VALUES ("03 Some data to test");
+INSERT INTO bup_vp.t2 VALUES ("04 Some data to test");
+INSERT INTO bup_vp.t2 VALUES ("05 Some data to test");
+
+INSERT INTO bup_vp.t3 VALUES ("01 Some data to test");
+INSERT INTO bup_vp.t3 VALUES ("02 Some data to test");
+INSERT INTO bup_vp.t3 VALUES ("03 Some data to test");
+INSERT INTO bup_vp.t3 VALUES ("04 Some data to test");
+INSERT INTO bup_vp.t3 VALUES ("05 Some data to test");
+
+--echo 
+--echo con_bup: Show the data before we start backup
+SELECT * FROM bup_vp.t1;
+SELECT * FROM bup_vp.t2;
+SELECT * FROM bup_vp.t3;
+
+### CON 3 ###
+      --echo 
+      connection con_tx3;
+
+      --echo Scenario d) - commit after VP; tx not included in backup
+      --echo con_tx3: Start transaction but do not commit
+      BEGIN;
+          INSERT INTO bup_vp.t3 VALUES ("tx3: 06 Should NOT be in backup");
+
+### CON 1 ###
+  --echo 
+  connection con_tx1;
+
+  --echo Scenario b) - Commit in progress blocks CB; tx is included in backup
+  --echo con_tx1: Get a transaction going and stop in the middle of commit
+  BEGIN;
+      INSERT INTO bup_vp.t1 VALUES ("tx1: 06 Some data to test");
+
+      --echo con_tx1: Make commit stop in the middle of execution
+      # Will continue once backup has been blocked from setting CB
+      SET DEBUG_SYNC= 'within_ha_commit_trans SIGNAL commit_started
+                       WAIT_FOR complete_commit';
+      send COMMIT;
+
+### CON 2 ###
+    --echo 
+    connection con_tx2;
+
+    --echo Scenario c) - commit blocked by CB; tx not included in backup
+    --echo con_tx2: Wait until tx1 has started
+    SET DEBUG_SYNC= 'now WAIT_FOR commit_started';
+    --echo con_tx2: Start transaction but do not commit
+    BEGIN;
+        INSERT INTO bup_vp.t2 VALUES ("tx2: 06 Should NOT be in backup");
+    
+### CON BUP ###
+--echo 
+connection con_bup;
+
+# Backup will be blocked from setting CB by the ongoing commit in
+# con_tx1. Backup will signal con_tx1 that it has been blocked. The
+# commit will then finish, making backup able to set CB. When CB has
+# been set, tx2 will be signaled to try to commit. tx2 commit will be
+# blocked by the CB and send a signal that it has been blocked. CB is
+# then released, but backup is stopped immediately after releasing CB.
+# tx2 will now be able to complete the commit, and tx3 will issue and
+# complete a commit. Finally, backup is allowed to complete.
+
+--echo con_bup: Activate synchronization points for BACKUP.
+# Signal when backup is blocked by ongoing commit in con_tx1
+SET DEBUG_SYNC= 'wait_lock_global_read_lock SIGNAL sync_complete_commit';
+
+# tx1 commit is completed, so backup can set CB. Just before reaching
+# VP, signal tx2 should try to commit. Wait until tx2 signals it has
+# been blocked
+SET DEBUG_SYNC= 'before_backup_data_lock SIGNAL try_commit 
+                 WAIT_FOR commit_blocked';
+
+# tx2 commit has been blocked. Create VP and release CB, and then wait
+# while tx2 and tx2 commits.
+SET DEBUG_SYNC= 'after_backup_binlog SIGNAL commit_unblocked
+                 WAIT_FOR finish_bup';
+
+--echo con_bup: Backing up database -- will block with lock
+send BACKUP DATABASE bup_vp TO "bup_vp.bak";
+
+
+### CON SYNC ###
+--echo 
+connection con_sync;
+SET DEBUG_SYNC= 'now WAIT_FOR sync_complete_commit';
+--echo Backup has been blocked by ongoing commit
+
+--echo Check that con_tx1 has not committed; Should be 0 records
+SELECT * FROM bup_vp.t1 WHERE col_a like 'tx1%';
+--echo 
+
+SET DEBUG_SYNC= 'now SIGNAL complete_commit';
+
+### CON 1 ###
+  --echo 
+  connection con_tx1;
+  --echo con_tx1: Reap commit
+  reap;
+  --echo Check that con_tx1 has committed; Should be 1 record
+  SELECT * FROM bup_vp.t1 WHERE col_a like 'tx1%';
+  --echo 
+
+###########
+## Below this line happens after BACKUP has taken CB
+###########
+
+### CON 2 ###
+    --echo 
+    connection con_tx2;
+    --echo con_tx2: Commit request will be blocked by CB
+
+    # Wait for backup to set CB
+    SET DEBUG_SYNC= 'now WAIT_FOR try_commit';
+
+    # Signal to backup that the commit is blocked
+    SET DEBUG_SYNC= 'wait_if_global_read_lock SIGNAL sync_commit_blocked';
+
+    send COMMIT;
+
+    # Test is blocked on COMMIT until CB has been released
+
+### CON SYNC ###
+--echo 
+connection con_sync;
+SET DEBUG_SYNC= 'now WAIT_FOR sync_commit_blocked';
+
+--echo Check that con_tx2 has not committed; Should be 0 records
+SELECT * FROM bup_vp.t2 WHERE col_a like 'tx2%';
+--echo 
+
+SET DEBUG_SYNC= 'now SIGNAL commit_blocked';
+
+### CON 2 ###
+    --echo 
+    connection con_tx2;
+    --echo con_bup: Reap commit
+    # commit completes only after CB has been released
+    reap;
+
+    --echo con_tx2: Backup has now released CB.
+    --echo Check that con_tx2 has committed; Should be 1 record
+    SELECT * FROM bup_vp.t2 WHERE col_a like 'tx2%';
+    --echo 
+
+### CON 3 ###
+      --echo 
+      connection con_tx3;
+      --echo con_tx3: Backup has now released CB. Commit transaction
+
+      # Double-check that backup has reached sync point after CB release
+      SET DEBUG_SYNC= 'now WAIT_FOR commit_unblocked';
+      COMMIT;
+      SET DEBUG_SYNC= 'now SIGNAL finish_bup';
+
+
+### CON BUP ###
+--echo 
+connection con_bup;
+--echo con_bup: Reap backup
+--replace_column 1 #
+reap;
+
+###########
+## Verify results
+###########
+
+# Do selects to show that all changes got applied.
+--echo 
+--echo con_bup: Showing data after updates and backup
+SELECT * FROM bup_vp.t1;
+SELECT * FROM bup_vp.t2;
+SELECT * FROM bup_vp.t3;
+
+--echo con_bup: Dropping the database
+DROP TABLE bup_vp.t1;
+DROP TABLE bup_vp.t2;
+DROP TABLE bup_vp.t3;
+DROP DATABASE bup_vp;
+
+--echo con_bup: Restoring the database
+--replace_column 1 #
+RESTORE FROM "bup_vp.bak";
+
+--echo 
+--echo con_bup: Showing the data after restore (tx2 and tx3 should not be there)
+SELECT * FROM bup_vp.t1;
+SELECT * FROM bup_vp.t2;
+SELECT * FROM bup_vp.t3;
+
+--echo
+--echo Verifying results:
+--echo
+
+--echo T1 should have changes from con_tx1; Should be 1 record
+SELECT * FROM bup_vp.t1 WHERE col_a like 'tx1%';
+
+--echo 
+--echo T2 should not have the changes from con_tx2; Should be 0 records
+SELECT * FROM bup_vp.t2 WHERE col_a like 'tx2%';
+
+--echo 
+--echo T3 should not have the changes from con_tx3; Should be 0 records
+SELECT * FROM bup_vp.t3 WHERE col_a like 'tx3%';
+
+--echo 
+--echo con_bup: Cleanup
+DROP DATABASE bup_vp;
+
+remove_file $bdir/bup_vp.bak;
+SET DEBUG_SYNC= 'RESET';

Thread
bzr commit into mysql-6.0-backup branch (jorgen.loland:2739) Bug#32465Jorgen Loland20 Nov