################################################################################ # # DELETE # # DELETE existing rows and commit. Above 900 (initial insert inserted 1000 pk's). # # DO NOT DELETE ROWS WITH (PK MOD 5) = 0 (PK's evenly divisible by 5). We # count these as a consistency check in other tests. # # This test runs a number of consecutive transactions (to allow for high # concurrency): # # Tx 1: # - DELETE a row and INSERT it immediately with same pk. # Tx 2: # - DELETE a row and INSERT it immediately with pk = NULL. # # Tx 3: # - DELETE two rows so that the total table sum does not change. # # Net effect: 2 fewer rows (if no errors) # # Roll back the entire transaction if a statement upon subsequent statements # depend result in error. This is to maintain consistency (zero-sum tx). # ################################################################################ SET autocommit = 0; START TRANSACTION; --echo --echo *** Delete a row and re-insert with same `pk`: --echo # # Get pk and unique ints of an existing row that is internally consistent. # (Note: If any int field values may be NULL, handle this by e.g. using COALESCE) # Re-using unique values in an effort to avoid rollbacks due to duplicate keys. # # NOTE: Because we maintain 0-sum consistency by "cancelling out" the deleted row with a new # row later, we need to make sure we knoe exactly what we are deleting, thus using # FOR UPDATE clause. --echo *** Disabling result log --disable_result_log --error 0, ER_LOCK_DEADLOCK, ER_LOCK_WAIT_TIMEOUT, ER_CHECKREAD SELECT @pk:=`pk`, @unique1:=`int1_unique`, @unique2:=`int2_unique` FROM t1 WHERE `pk` MOD 5 = 4 AND `pk` > 900 AND `is_consistent` = 1 LIMIT 1 FOR UPDATE; --echo *** Enabling result log --enable_result_log --source suite/engines/rr_trx/include/check_for_error_rollback_skip.inc # Delete the row. We maintain 0-sum tx consistency by inserting ints that will cancel out # the unique values (which we are keeping) later in this transaction. --error 0, ER_LOCK_DEADLOCK, ER_LOCK_WAIT_TIMEOUT, ER_CHECKREAD DELETE FROM t1 WHERE `pk` = @pk; --source suite/engines/rr_trx/include/check_for_error_rollback_skip.inc --echo *** Doing insert of row with pk = @pk if above statement succeeded (query log disabled)... # Note that affected rows may be 0 if some other thread changed the row in the meantime - still # we get no error. We work around this by using FOR UPDATE to lock the row (see above). if(!$error) { # Insert a new row with the same sum of integers. # This is conditional, so skip it the query log. --disable_query_log # If some other thread is doing the same thing at the same time, we may get duplicate key error --error 0, ER_LOCK_DEADLOCK, ER_LOCK_WAIT_TIMEOUT, ER_DUP_ENTRY INSERT INTO t1 (`pk`, `id`, `int1`, `int1_key`, `int1_unique`, `int2`, `int2_key`, `int2_unique`, `for_update`, `connection_id`, `thread_id`, `is_uncommitted`, `is_consistent`) VALUES (@pk, 900, 900, -900, @unique1, -(@unique1+@unique2), 0, @unique2, 0, CONNECTION_ID(), 0, 0, 1); --source suite/engines/rr_trx/include/check_for_error_rollback_skip.inc --enable_query_log } COMMIT; ######################## # TRANSACTION 2 ######################## START TRANSACTION; --echo --echo *** Delete a row and re-insert with `pk` = NULL: --echo --echo *** Disabling result log --disable_result_log # In order not to pick the same row as above, try to pick a different pk. # Use FOR UPDATE to make sure we maintain 0-sum consistency througout the transaction. --error 0, ER_LOCK_DEADLOCK, ER_LOCK_WAIT_TIMEOUT, ER_CHECKREAD SELECT @pk:=`pk`, @unique1:=`int1_unique`, @unique2:=`int2_unique` FROM t1 WHERE `pk` MOD 5 = 4 AND `pk` > 901 AND `is_consistent` = 1 LIMIT 1 FOR UPDATE; --echo *** Enabling result log --enable_result_log --source suite/engines/rr_trx/include/check_for_error_rollback_skip.inc # Delete the row. We maintain 0-sum tx consistency by inserting ints that will cancel out # the unique values (which we are keeping) later in this transaction. --error 0, ER_LOCK_DEADLOCK, ER_LOCK_WAIT_TIMEOUT, ER_CHECKREAD DELETE FROM t1 WHERE `pk` = @pk; --source suite/engines/rr_trx/include/check_for_error_rollback.inc --echo *** Doing insert of row with pk = NULL if above statement succeeded (query log disabled)... if(!$error) { # Insert a new row with the same sum of integers. # This is conditional, so skip it the query log. --disable_query_log --error 0, ER_LOCK_DEADLOCK, ER_LOCK_WAIT_TIMEOUT, ER_DUP_ENTRY INSERT INTO t1 (`pk`, `id`, `int1`, `int1_key`, `int1_unique`, `int2`, `int2_key`, `int2_unique`, `for_update`, `connection_id`, `thread_id`, `is_uncommitted`, `is_consistent`) VALUES (NULL, 901, 901, -901, @unique1, -(@unique1+@unique2), 0, @unique2, 0, CONNECTION_ID(), 0, 0, 1); --source suite/engines/rr_trx/include/check_for_error_rollback.inc --enable_query_log } COMMIT; ######################## # TRANSACTION 3 ######################## START TRANSACTION; # By identifying rows with total row sum = 0, we know that deleting such rows # won't affect the total table sum (used for consistency check). # Such rows should have been marked with `is_consistent` = 0; --echo --echo *** Delete up to two (2) "consistent" rows (zero-sum; table sum unchanged) --echo # We get Warning "1592: Statement is not safe to log in statement mode" with server 5.1 # due to LIMIT (see Bug#42415 and Bug#42851). --disable_warnings --error 0, ER_LOCK_DEADLOCK, ER_LOCK_WAIT_TIMEOUT, ER_CHECKREAD DELETE FROM t1 WHERE `pk` > 902 AND `pk` MOD 5 = 3 AND `is_consistent` = 1 LIMIT 2; --enable_warnings COMMIT;