1
#ifndef _BACKUP_DEBUG_H
2
#define _BACKUP_DEBUG_H
4
#define BACKUP_BREAKPOINT_TIMEOUT 300
8
- decide how to configure DEBUG_BACKUP
18
Macros for debugging error (or other) conditions. Usage:
20
TEST_ERROR_IF(<condition deciding if TEST_ERROR should be true>);
22
if (<other conditions> || TEST_ERROR)
27
The additional TEST_ERROR condition will be set only if "backup_error_test"
28
error injection is set in the server.
31
- Whenever TEST_ERROR is used in a condition, TEST_ERROR_IF() should
32
be called before - otherwise TEST_ERROR might be unintentionally TRUE.
33
- This mechanism is not thread safe.
37
extern bool test_error_flag;
40
#define TEST_ERROR backup::test_error_flag
41
// FIXME: DBUG_EXECUTE_IF below doesn't work
42
#define TEST_ERROR_IF(X) \
44
backup::test_error_flag= FALSE; \
45
DBUG_EXECUTE_IF("backup_error_test", backup::test_error_flag= (X);); \
50
//#define BACKUP_BREAKPOINT(S)
51
#define TEST_ERROR FALSE
52
#define TEST_ERROR_IF(X)
57
@page BACKUP_BREAKPOINT Online Backup Breakpoints
58
Macros for creating breakpoints during testing.
60
@section WHAT What are breakpoints?
61
Breakpoints are devices used to pause the execution of the backup system
62
at a certain point in the code. There is a timeout that you can specify
63
when you set the lock for the breakpoint (from get_lock() see below)
64
which will enable execution to continue after the period in seconds
67
The best use of these breakpoints is for pausing execution at critical
68
points in the backup code to allow proper testing of certain features.
69
For example, suppose you wanted to ensure the Consistent Snapshot driver
70
was working properly. To do so, you would need to ensure no new @INSERT
71
statements are executed while the data is being backed up. If you use
72
a breakpoint, you can set the breakpoint to pause the backup kernel at
73
the point where it has set the consistent read and is reading rows.
74
You can then insert some rows and release the breakpoint. The result
75
should contain all of the rows in the table except those that were
76
inserted once the consistent read was set.
78
@section USAGE How to use breakpoints.
79
To make a breakpoint available, you must add a macro call to the code.
80
Simply insert the macro call as follows. The @c breakpoint_name is a
81
text string that must be unique among the breakpoints. It is used in
82
the macro as a means of tagging the code for pausing and resuming
83
execution. Once the code is compiled, you can use a client connection
84
to set and release the breakpoint. Be sure to use a separate connection
85
for getting, checking, and releasing locks.
87
<b><c>BACKUP_BREAKPOINT("<breakpoint_name>");</c></b>
89
Breakpoints use the user-defined locking functions @c get_lock() to set
90
the breakpoint and @c release_lock() to release it.
92
@subsection SET Setting breakpoints.
93
To set an existing breakpoint, issue the following command where @c
94
timeout is the number of seconds execution will pause once the breakpoint
95
is reached before continuing execution.
97
<b><c>SELECT get_lock("<breakpoint_name>",<timeout>);</c></b>
99
@subsection RELEASE Releasing breakpoints.
100
To release an existing breakpoint, issue the following command. This
101
releases execution allow the system to continue.
103
<b><c>SELECT release_lock("<breakpoint_name>");</c></b>
105
@subsection EXAMPLE Example - Testing the Consistent Snapshot Driver
106
To test the consistent snapshot driver, we can make use of the @c
107
backup_cs_locked breakpoint to pause execution after the consistent read
108
is initiated and before all of the rows from the table have been read.
109
Consider an InnoDB table with the following structure as our test table.
111
<c>CREATE TABLE t1 (a INT) ENGINE=INNODB;</c>
113
To perform this test using breakpoints, we need two client connections.
114
One will be used to execute the backup command and another to set and
115
release the breakpoint. In the first client, we set the breakpoint with
116
the <c>SELECT get_lock("backup_cs_locked", 100);</c> command. In the
117
second client, we start the execution of the backup. We can return to
118
the first client and issue several @INSERT statements then issue the
119
<c>SELECT release_lock("backup_cs_locked");</c> command to release the
122
We can then return to the second client, select all of the rows from the
123
table to verify the rows were inserted. We can verify that the consistent
124
snapshot worked by restoring the database (which is a destructive restore)
125
and then select all of the rows. This will show that the new rows
126
inserted while the backup was running were not inserted into the table.
127
The following shows the output of the commands as described.
130
@code mysql> SELECT * FROM t1;
138
3 rows in set (0.00 sec)
140
mysql> SELECT get_lock("backup_cs_locked", 100);
141
+-----------------------------------+
142
| get_lock("backup_cs_locked", 100) |
143
+-----------------------------------+
145
+-----------------------------------+
146
1 row in set (0.00 sec) @endcode
149
@code mysql> BACKUP DATABASE test TO 'test.bak'; @endcode
151
Note: The backup will pause while the breakpoint is set (the lock is held).
154
@code mysql> INSERT INTO t1 VALUES (101), (102), (103);
155
Query OK, 3 rows affected (0.02 sec)
156
Records: 3 Duplicates: 0 Warnings: 0
158
mysql> SELECT * FROM t1;
169
6 rows in set (0.00 sec)
171
mysql> SELECT release_lock("backup_cs_locked");
172
+----------------------------------+
173
| release_lock("backup_cs_locked") |
174
+----------------------------------+
176
+----------------------------------+
177
1 row in set (0.01 sec) @endcode
180
@code +------------------------------+
182
+------------------------------+
183
| header = 14 bytes |
184
| meta-data = 120 bytes |
188
+------------------------------+
189
5 rows in set (33.45 sec)
191
mysql> SELECT * FROM t1;
202
6 rows in set (0.00 sec)
204
mysql> RESTORE FROM 'test.bak';
205
+------------------------------+
207
+------------------------------+
208
| header = 14 bytes |
209
| meta-data = 120 bytes |
213
+------------------------------+
214
5 rows in set (0.08 sec)
216
mysql> SELECT * FROM t1;
224
3 rows in set (0.00 sec)@endcode
226
Note: The backup will complete once breakpoint is released (the lock is
229
@section BREAKPOINTS Breakpoints
230
The following are the available breakpoints included in the code.
232
- <b>backup_command</b> Occurs at the start of the backup operation.
233
- <b>data_init</b> Occurs at the start of the <b>INITIALIZE PHASE</b>.
234
- <b>data_prepare</b> Occurs at the start of the <b>PREPARE PHASE</b>.
235
- <b>data_lock</b> Occurs at the start of the <b>SYNC PHASE</b>.
236
- <b>data_unlock</b> Occurs before the unlock calls.
237
- <b>data_finish</b> Occurs at the start of the <b>FINISH PHASE</b>.
238
- <b>backup_meta</b> Occurs before the call to write_meta_data().
239
- <b>backup_data</b> Occurs before the call to write_table_data().
240
- <b>backup_done</b> Occurs after the call to write_table_data() returns.
241
- <b>backup_cs_locked</b> Consistent Snapshot - after the consistent
242
read has been initiated but before rows are read.
243
- <b>backup_cs_open_tables</b> Consistent Snapshot - before the call to
244
open and lock tables.
245
- <b>backup_cs_reading</b> Consistent Snapshot - occurs during read.
247
@section NOTES Developer Notes
248
- Breakpoints can be used in debug builds only. You must compile
249
the code using the @c DEBUG_EXTRA preprocessor directive.
250
- When adding breakpoints, you must add a list item for each breakpoint
251
to the documentation for breakpoints. See the code for the macro
252
definition in @ref debug.h for details.
253
- You must use a dedicated connection for getting and releasing locks. Do
254
not issue a get_lock() or release_lock() in the same connection (thread) as
255
code that calls BACKUP_BREAKPOINT(). Using the same connection to get/release
256
locks and run code that issues BACKUP_BREAKPOINTs will result in an
257
assertion using DEBUG_ASSERT(thd->ull == NULL) from debug_sync_point() in
263
Consider: set thd->proc_info when waiting on lock
265
#define BACKUP_BREAKPOINT(S) \
267
DBUG_PRINT("backup",("== breakpoint on '%s' ==",(S))); \
268
DBUG_EXECUTE_IF("backup_debug", DBUG_SYNC_POINT((S),BACKUP_BREAKPOINT_TIMEOUT);); \