MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
check_for_error_rollback_skip.inc
1 ################################################################################
2 #
3 # Checks if an error has occurred and if so rolls back the entire transaction.
4 # Only source this file when such behavior is needed.
5 #
6 # Since this file needs to be sourced _after_ the statement that we want to check
7 # for error, any unacceptable errors will have already caused the test to fail.
8 # If we get this far, we know that the error was a valid one.
9 #
10 # Typical usage in testcase:
11 # -------------------------------------------------------------------
12 # --error 0, ER_LOCK_DEADLOCK, ER_LOCK_WAIT_TIMEOUT
13 # UPDATE t1 SET `int1` = `int1` - 4 WHERE `pk` < 25 LIMIT 1;
14 # --source suite/stress_tx_rr/include/check_for_error_rollback.inc
15 # -------------------------------------------------------------------
16 #
17 # Examples of "valid" error types in transactional testing:
18 # 1205 - ER_LOCK_WAIT_TIMEOUT
19 # 1213 - ER_LOCK_DEADLOCK
20 # 1020 - ER_CHECKREAD (Falcon: "Record has changed since last read")
21 #
22 # In some situations duplicate key errors etc. are also valid.
23 #
24 # We keep an approximate count of the number of errors / rollbacks.
25 # We don't distinguish between error types, as this would require extra queries,
26 # reducing concurrency.
27 #
28 # We do an explicit rollback to make sure all engines have identical behavior on
29 # transactional errors (some engines only roll back the last statement in some
30 # cases).
31 # We don't show this in the result file because we don't know when it will
32 # occur and we don't want diffs because of legitimate ROLLBACKs. If, however
33 # we want to go back and trace ROLLBACKS of this kind, then we need another
34 # solution.
35 #
36 # At this time we skip the rest of the test to avoid rsult file diff problems
37 # in error situations vs. non-error situations in later parts of the test,
38 # e.g. repeatable read checking (requires some output to be useful).
39 #
40 ################################################################################
41 
42 --disable_query_log
43 
44 # (Re-) set the error variable in case it has been set to a different value previously.
45 # This value may be read by the wrapping test script to check if there really
46 # was an error or not.
47 let $error= 0;
48 if ($mysql_errno)
49 {
50  # Last statement sent to the server resulted in an error (0 means no error).
51 
52  # Set error variable, because this is used by wrapping tests to determine whether or not
53  # to continue with other statements in the same transaction. If set, this indicates that
54  # the last statement executed before calling this script resulted in an error.
55 
56  let $error= $mysql_errno;
57 
58  ## Old code for determining error type...
59  #let $deadlock= `SELECT IF($mysql_errno = 1213, 1, 0)`;
60  #let $timeout= `SELECT IF($mysql_errno = 1205, 1, 0)`;
61  #if ($deadlock) { ... } (etc.)
62 
63  # Do a full rollback of the current transaction.
64  ROLLBACK;
65 
66  # update statistics
67  # TODO: Only do this every n times (e.g. n = 10 or 100) to reduce contention.
68  # An idea is to use some MOD expression to determine this (e.g. mod of timestamp or conn_id).
69  --error 0, ER_LOCK_DEADLOCK, ER_LOCK_WAIT_TIMEOUT, ER_CHECKREAD
70  UPDATE statistics SET tx_errors = tx_errors + 1;
71 
72  --skip Skip rest of the test due to transactional error (deadlock, timeout, etc.)
73 }
74 
75 --enable_query_log
76