1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
|
#!/bin/bash
set -f
set +e
. ./include/ptb_core.inc
######################################################
# Percona Test Bench - XtraBackup performance matrix #
######################################################
declare -A PTB_OPTION_DESCRIPTORS=(\
[mysql-rootdir]="REQ 1 PATHEXISTS Parent or install directory where mysql client and server binaries can be found. Ex: /usr/bin/mysql" \
[include]="OPT 0 FILEEXISTS Script(s) to source after options have been processed and before testing starts that will declare and populate the required internal variables (PTB_mysql_matrix variable, PTB_xtrabackup_matrix). Ex: ps55-xb21-bitmap.cfg" \
[cache-dir]="OPT 1 PATHCREATE Directory where server databases may be cached to save time during prepare phase." \
[test-rootdir]="OPT 1 PATHEXISTS Directory where test tool binaries can be found (RQG, sysbench, tpcc, etc..)." \
[test-prepare]="OPT 1 FILEEXISTS Script to call that will prepare the database server prior to each test. Ex: sysbench_oltp_prepare_sh" \
[test-prepare-opt]="OPT 0 STR Option to be passed to prepare tool. Ex: --test-prepare-opt=--oltp-table-count=16 --test-prepare-opt=--oltp-table-size=100000" \
[test-load]="OPT 1 FILEEXISTS Script to call that will run load on the server during each test. Ex: sysbench_oltp_load.sh" \
[test-load-opt]="OPT 0 STR Option to be passed to load tool. Ex: --test-load-opt=--oltp-table-count=16 --test-load-opt=--oltp-table-size=100000" \
[test-backup-wait]="OPT 1 INT 0 9999 0 Amount of time (in seconds) to wait after load has started before starting backup cycles." \
[test-backup-delay]="OPT 1 INT 0 9999 0 Amount of time (in seconds) to wait in between each full backup." \
[test-backup-count]="OPT 1 INT 1 9999 1 Number of full backups to perform." \
[test-backup-destination]="OPT 1 INT 0 2 2 Defines where to send backup to. 0=xbstream to /dev/null (incompatible with incremental backup); 1=xbstream to local file(incompatible with incremental backup); 2=native to local backup directory." \
[test-incremental-wait]="OPT 1 INT 0 9999 0 Amount of time (in seconds) to wait before performing each subsequent incremental backups. Can not be used with test-incremental-schedule." \
[test-incremental-count]="OPT 1 INT 0 9999 0 Number of incremental backups to perform after each full backup. Can not be used with test-incremental-schedule." \
[test-incremental-schedule]="OPT 1 STR Schedule of time delays to perform incremental backups after each full backup delimited by ':'. Use in place of test-incremental-count and test-incremental-wait. Ex: A value of 0:20:60:120 will perform the first incremental 0 seconds after completing a full backup, the second incremental will be performed 20 seconds after completion of the previous incremental, etc.." \
[test-cleanup]="OPT 1 FILEEXISTS Script to call that will clean up or analyze the server after each test. Ex: sysbench_oltp_cleanup.sh" \
[test-retry]="OPT 1 INT 0 9999 0 Number of attempts to retry backup test after initial failure." \
[test-force]="OPT 1 INT 0 1 0 Force continuation of other tests after test-retry has been exhausted." \
[vardir]="OPT 1 STRDEF ./var Directory where individual test data and results should be located." \
[verbosity]="OPT 1 INT 0 4 2 Output verbosity filter: ERROR=4; WARNING=3; INFO=2; DEBUG=1; IDEBUG=0." \
[xtrabackup-rootdir]="REQ 1 PATHEXISTS Directory where the XtraBackup binaries are located."
)
################################################################################
# Shows usage prolog
function usage()
{
echo "XtraBackup performance matrix test."
}
################################################################################
# Validation callback for options parsing
# $1 - option name
# $2 - proposed option value
function getoption()
{
case "$1" in
"test_incremental_count" | "test_incremental_wait" )
if [ -n "$PTB_OPT_test_incremental_schedule" ]; then
ptb_report_error "test-incremental-schedule and $1 are mutually exclusive."
return 2
elif [ -n "$PTB_OPT_test_backup_destination" ] && [ $PTB_OPT_test_backup_destination -lt 2 ]; then
ptb_report_error "test-backup-destination != 2 and $1 are mutually exclusive."
return 2
fi
;;
"test_incremental_schedule" )
if [ -n "$PTB_OPT_test_incremental_count" ]; then
ptb_report_error "test-incremental-count and $1 are mutually exclusive."
return 2
elif [ -n "$PTB_OPT_test_incremental_wait" ]; then
ptb_report_error "test-incremental-wait and $1 are mutually exclusive."
return 2
elif [ -n "$PTB_OPT_test_backup_destination" ] && [ "$PTB_OPT_test_backup_destination" != "2" ]; then
ptb_report_error "test-backup-destination != 2 and $1 are mutually exclusive."
return 2
fi
;;
"test_backup_destination" )
if [ "$2" != "2" ]; then
if [ -n "$PTB_OPT_test_incremental_count" ]; then
ptb_report_error "test-backup-destination != 2 and test-incremental-count are mutually exclusive."
return 2
elif [ -n "$PTB_OPT_test_incremental_schedule" ]; then
ptb_report_error "test-backup-destination != 2 and test-incremental-schedule are mutually exclusive."
return 2
fi
fi
;;
* )
;;
esac
return 0
}
###############################################################################
# Performs backups
#
# $1 required, test number
# $2 required, test base dir
# $3 required, server id
# $4 required, load log file
# $5 required, result file
# $6 required, server options
# $7 required, xtrabackup options
function backup()
{
local test_number=$1
local test_dir=$2
local server_id=$3
local load_logfile=$4
local result_file=$5
local server_options="$6"
local xtrabackup_options="$7"
local rpt_prefix="backup($1, $2, $3, $4, $5, $6, $7)"
# build out the proper path to use for callng innobackupex
local xtrabackup_path="${S_BINDIR[$server_id]}/bin:${S_BINDIR[$server_id]}/libexec:$PTB_OPT_xtrabackup_rootdir"
#parse the options and build out the correct innobackupex command line
local encrypt=
local encrypt_threads=1
local encrypt_chunk_size=64
local encrypt_key=
local compress=0
local compress_threads=1
local compress_chunk_size=64
local throttle=0
local option=
for option in $xtrabackup_options; do
ptb_parse_server_option $option backup_optname backup_optvalue
case "$backup_optname" in
"encrypt" )
encrypt=$backup_optvalue
case $encrypt in
"AES128" ) encrypt_key="1234567812345678";;
"AES192" ) encrypt_key="123456781234567812345678";;
"AES256" ) encrypt_key="12345678123456781234567812345678";;
* )
ptb_report_error "$rpt_prefix - invalid encryption algo. [$encrypt]"
return 1
;;
esac
;;
"encrypt-threads" | "encrypt_threads" ) encrypt_threads=$backup_optvalue;;
"encrypt-chunk-size" | "encrypt_chunk_size" ) encrypt_chunk_size=$backup_optvalue;;
"compress" )
if [ -z "$backup_optvalue" ]; then
compress=1
else
compress=$backup_optvalue
fi
;;
"compress-threads" | "compress_threads" ) compress_threads=$backup_optvalue;;
"compress-chunk-size" | "compress_chunk_size" ) compress_chunk_size=$backup_optvalue;;
"throttle" ) throttle=$backup_optvalue;;
esac
done
local backup_command=
backup_command="$backup_command --defaults-file=${S_DEFAULTSFILE[$server_id]}"
backup_command="$backup_command --no-timestamp"
backup_command="$backup_command --tmpdir=$test_dir"
if [ -n "$encrypt" ]; then
backup_command="$backup_command --encrypt=$encrypt"
backup_command="$backup_command --encrypt-key=$encrypt_key"
backup_command="$backup_command --encrypt-threads=$encrypt_threads"
backup_command="$backup_command --encyrpt-chunk-size=$encrypt_chunk_size"
fi
if [ -n "$compress" ] && [ "$compress" != "0" ]; then
backup_command="$backup_command --compress"
backup_command="$backup_command --compress-threads=$compress_threads"
backup_command="$backup_command --compress-chunk-size=$compress_chunk_size"
fi
# loop through full backups
local full_cycle=0
while [ $full_cycle -lt $PTB_OPT_test_backup_count ]; do
# loop through 1 + incremental count making either a full or incremental backup for each cycle
local current_cycle=0
local previous_cycle=0
while [ $current_cycle -lt ${#PTB_OPT_sleep_schedule[@]} ]; do
local backup_current_dir=${test_dir}/backup-${full_cycle}.${current_cycle}
local backup_previous_dir=${test_dir}/backup-${full_cycle}.${previous_cycle}
local backup_logfile=${test_dir}/backup-${full_cycle}.${current_cycle}.log
local inc_backup_command=""
if [ $current_cycle -ne 0 ]; then
inc_backup_command="--incremental --incremental-basedir=${backup_previous_dir}"
fi
ptb_report_info "$rpt_prefix - Sleeping for ${PTB_OPT_sleep_schedule[$current_cycle]} seconds before starting cycle $current_cycle"
sleep ${PTB_OPT_sleep_schedule[$current_cycle]}
echo "XtraBackup options: $xtrabackup_options" >> $backup_logfile
echo "XtraBackup command: $backup_command $inc_backup_command" >> $backup_logfile
if [ -n "$load_logfile" ]; then
echo "Starting XtraBackup full_cycle[$full_cycle] current_cycle[$current_cycle] with command: $backup_command $inc_backup_command" >> $load_logfile
fi
#ptb_sql $serverid "SHOW STATUS LIKE 'innodb_buffer_pool%'"
local backup_start_time=$SECONDS
case "$PTB_OPT_test_backup_destination" in
"0" ) # xbstream > /dev/null
ptb_report_info "PATH=${xtrabackup_path}:$PATH; innobackupex $backup_command $inc_backup_command $backup_current_dir --stream=xbstream 1>/dev/null 2>> $backup_logfile"
( PATH=${xtrabackup_path}:$PATH; innobackupex $backup_command $inc_backup_command $backup_current_dir --stream=xbstream 1>/dev/null 2>> $backup_logfile )
rc=$?
;;
"1" ) # xbstream > ${backup_current_dir}/backup
ptb_runcmd mkdir -p ${backup_current_dir}
ptb_report_info "PATH=${xtrabackup_path}:$PATH; innobackupex $backup_command $inc_backup_command $backup_current_dir --stream=xbstream 1>${backup_current_dir}/backup 2>> $backup_logfile"
( PATH=${xtrabackup_path}:$PATH; innobackupex $backup_command $inc_backup_command $backup_current_dir --stream=xbstream 1>${backup_current_dir}/backup 2>> $backup_logfile )
rc=$?
;;
"2" ) # ${backup_current_dir}
ptb_report_info "PATH=${xtrabackup_path}:$PATH; innobackupex $backup_command $inc_backup_command $backup_current_dir &>> $backup_logfile"
( PATH=${xtrabackup_path}:$PATH; innobackupex $backup_command $inc_backup_command $backup_current_dir 2>> $backup_logfile )
rc=$?
;;
* )
ptb_report_error "$rpt_prefix - invalid backup destination option [$PTB_OPT_test_backup_destination]."
rc=1
;;
esac
local backup_total_time=`expr $SECONDS - $backup_start_time`
if [ $rc -ne 0 ]; then
ptb_report_error "$rpt_prefix - innobackupex($xbopts) failed with $rc"
break
fi
if [ -n "$load_logfile" ]; then
echo "Finished XtraBackup full_cycle[$full_cycle] current_cycle[$current_cycle] with command: $backup_command $inc_backup_command" >> $load_logfile
fi
echo -n "$test_number,$full_cycle,$current_cycle,$backup_total_time,$rc" >> $result_file
for option in ${server_options}; do
ptb_parse_server_option $option backup_optname backup_optvalue
echo -n ",$backup_optvalue" >> $result_file
done
for option in ${xtrabackup_options}; do
ptb_parse_server_option $option backup_optname backup_optvalue
echo -n ",$backup_optvalue" >> $result_file
done
echo "" >> $result_file
previous_cycle=$current_cycle
current_cycle=`expr ${current_cycle} + 1`
done
if [ $rc -ne 0 ]; then
break
fi
full_cycle=`expr ${full_cycle} + 1`
done
return $rc
}
###############################################################################
# Performs restores
#
# $1 required, test number
# $2 required, test base dir
# $3 required, server id
# $4 required, load log file
# $5 required, result file
# $6 required, server options
# $7 required, xtrabackup options
function restore()
{
local test_number=$1
local test_dir=$2
local server_id=$3
local load_logfile=$4
local result_file=$5
local server_options="$6"
local xtrabackup_options="$7"
local rpt_prefix="restore($1, $2, $3, $4, $5, $6, $7)"
# build out the proper path to use for callng innobackupex
local xtrabackup_path="${S_BINDIR[$server_id]}/bin:${S_BINDIR[$server_id]}/libexec:$PTB_OPT_xtrabackup_rootdir"
}
###############################################################################
# Cleanup
#
# $1 required, test number
# $2 required, test base dir
# $3 required, server id
function cleanup()
{
local test_number=$1
local test_dir=$2
local server_id=$3
local full_cycle=0
while [ $full_cycle -lt $PTB_OPT_test_backup_count ]; do
local current_cycle=0
while [ $current_cycle -lt ${#PTB_OPT_sleep_schedule[@]} ]; do
local backup_current_dir=${test_dir}/backup-${full_cycle}.${current_cycle}
ptb_runcmd rm -rf $backup_current_dir
current_cycle=`expr ${current_cycle} + 1`
done
full_cycle=`expr ${full_cycle} + 1`
done
# remove data dir if success
ptb_delete_server_data $server_id
}
###############################################################################
# Runs a single test with a single combination of server and xtrabackup
# options
#
# $1 - required, test number
# $2 - required, test base dir
# $3 - required, base port
# $4 - required, result file
# $5 - required, server options
# $6 - required, xtrabackup options
function runonetest()
{
local test_number=$1
local test_dir=$2
local base_port=$3
local result_file=$4
local server_options="$5"
local xtrabackup_options="$6"
local rpt_prefix="runonetest($1, $2, $3, $4, $5, $6)"
local server_id=1
local load_id=1
local server_port=$base_port
local load_logfile=${test_dir}/load.log
ptb_report_info "$rpt_prefix - starting test"
# initialize the sandbox and variables
ptb_init $test_dir $PTB_OPT_verbosity
# create a server instance
ptb_create_server_instance $server_id $PTB_OPT_mysql_rootdir $server_port
rc=$?
if [ $rc -ne 0 ]; then
ptb_report_error "$rpt_prefix - ptb_create_server_instance($server_id, $PTB_OPT_mysql_rootdir, $server_port) failed with $rc"
return $rc
fi
# set the server options
ptb_set_all_server_options $server_id "$server_options"
rc=$?
if [ $rc -ne 0 ]; then
ptb_report_error "$rpt_prefix - ptb_set_all_server_options($server_id, $server_options) failed with $rc"
return $rc
fi
# prepare the database
ptb_prepare_server_data $server_id "$PTB_OPT_cache_dir" "$PTB_OPT_test_prepare" "$PTB_OPT_test_rootdir" "${PTB_OPT_test_prepare_opt[@]}"
rc=$?
if [ $rc -ne 0 ]; then
ptb_report_error "$rpt_prefix - ptb_prepare_server_data($server_id, \"$PTB_OPT_cache_dir\", \"$PTB_OPT_test_prepare\", $PTB_OPT_test_rootdir) failed with $rc."
ptb_cleanup 1
return $rc
fi
# start any parallel load
if [ -n "$PTB_OPT_test_load" ]; then
ptb_start_test_load $server_id $load_id $PTB_OPT_test_load $PTB_OPT_test_rootdir $load_logfile "${PTB_OPT_test_load_opt[@]}"
rc=$?
if [ $rc -ne 0 ]; then
ptb_report_error "$rpt_prefix - ptb_start_test_load($server_id, $load_id, $PTB_OPT_test_load, $PTB_OPT_test_rootdir, $load_logfile, ${PTB_OPT_test_load_opt[@]}) failed with $rc"
ptb_cleanup 1
return $rc
fi
fi
# sleep while load loads up
ptb_report_info "$rpt_prefix - Sleeping for ${PTB_OPT_test_backup_wait} seconds before starting backups."
sleep $PTB_OPT_test_backup_wait
# do the backup
backup $test_number $test_dir $server_id $load_logfile $result_file "$server_options" "$xtrabackup_options"
rc=$?
# shut 'er down
if [ -n "$PTB_OPT_test_load" ]; then
ptb_kill_task $load_id
fi
ptb_stop_server $server_id
# cleanup server data and backups on success
if [ $rc -eq 0 ]; then
cleanup $test_number $test_dir $server_id
fi
# cleanup the sandbox and variables
ptb_cleanup 1
return $rc
}
###############################################################################
# The main event
function main()
{
local rpt_prefix="main()"
# set up working directory
if [ -z "$PTB_OPT_vardir" ]; then
PTB_OPT_vardir="$PWD/var"
fi
if [ -d "$PTB_OPT_vardir" ]; then
local newdiridx=1
local newdirname="$PTB_OPT_vardir"
while [ -d "${newdirname}" ]; do
newdirname="${PTB_OPT_vardir}.${newdiridx}"
newdiridx=`expr $newdiridx + 1`
done
ptb_runcmd mv "$PTB_OPT_vardir" "$newdirname"
rc=$?
if [ $rc -ne 0 ]; then
ptb_report_error "$rpt_prefix - unable to move old vardir \"${PTB_OPT_vardir}\" out of the way to \"${newdirname}\", failed with $rc."
return $rc
fi
fi
ptb_runcmd mkdir $PTB_OPT_vardir
rc=$?
if [ $rc -ne 0 ]; then
ptb_report_error "$rpt_prefix - unable to create vardir \"${PTB_OPT_vardir}\", failed with $rc."
return $rc
fi
# set up result csv file
local result_file=${PTB_OPT_vardir}/result.csv
echo -n "testnum,full_cycle,inc_cycle,backuptime,rc" > $result_file
for opt in ${server_options[0]}; do
ptb_parse_server_option $opt optname optvalue
echo -n ",$optname" >> $result_file
done
for opt in ${xb_options[0]}; do
ptb_parse_server_option $opt optname optvalue
echo -n ",$optname" >> $result_file
done
echo "" >> $result_file
# build out the sleep schedule
PTB_OPT_sleep_schedule[0]=$PTB_OPT_test_backup_delay
if [ -z "$PTB_OPT_test_incremental_schedule" ]; then
local i=
for i in `seq 1 $PTB_OPT_test_incremental_count`; do
PTB_OPT_sleep_schedule[$i]=$PTB_OPT_test_incremental_wait
done
else
local i=1
local startpos=0
local colonpos=0
while [ 1 -eq 1 ]; do
colonpos=`expr index ${PTB_OPT_test_incremental_schedule:$startpos} :`
colonpos=`expr $startpos + $colonpos`
if [ $colonpos -eq $startpos ]; then
PTB_OPT_sleep_schedule[$i]=${PTB_OPT_test_incremental_schedule:$startpos}
break
else
PTB_OPT_sleep_schedule[$i]=${PTB_OPT_test_incremental_schedule:$startpos:`expr $colonpos - $startpos - 1`}
fi
i=`expr $i + 1`
startpos=$colonpos
done
fi
# loop through the combinations and run each test
local server_option=
local test_number=0
local base_port=10000
for server_option in "${server_options[@]}"; do
local xtrabackup_option=
for xtrabackup_option in "${xb_options[@]}"; do
local test_dir=${PTB_OPT_vardir}/test-${test_number}
local test_logfile="${test_dir}/test.log"
local trys_remaining=`expr $PTB_OPT_test_retry + 1`
local rc=1
ptb_report_info "$rpt_prefix - Starting test $test_number with [$server_option] and [$xtrabackup_option]"
while [ $rc -ne 0 ] && [ $trys_remaining -gt 0 ]; do
if [ ! -d "$test_dir" ]; then
ptb_runcmd mkdir -p $test_dir
rc=$?
if [ $rc -ne 0 ]; then
ptb_report_error "$rpt_prefix - unable to create test directory $test_dir, failed with $rc."
return $rc
fi
fi
runonetest $test_number $test_dir $base_port $result_file "$server_option" "$xtrabackup_option" > $test_logfile
rc=$?
if [ $rc -ne 0 ]; then
local newdiridx=2
local newdirname="${test_dir}.failure.1"
while [ -d "${newdirname}" ]; do
newdirname="${test_dir}.failure.${newdiridx}"
newdiridx=`expr $newdiridx + 1`
done
ptb_report_info "$rpt_prefix - Test $test_num with [$server_option] and [$xtrabackup_option] FAILED with $rc."
ptb_runcmd mv "$test_dir" "$newdirname"
rc=$?
if [ $rc -ne 0 ]; then
ptb_report_error "$rpt_prefix - unable to move old testdir \"${test_dir}\" out of the way to \"${newdirname}\", failed with $rc."
return $rc
fi
fi
trys_remaining=`expr $trys_remaining - 1`
done
if [ $rc -ne 0 ] && [ $PTB_OPT_test_force -ne 0 ]; then
return 1
fi
test_number=`expr $test_number + 1`
done
done
return 0
}
###############################################################################
# main
###############################################################################
# parse and validate command line args
ptb_parse_options getoption usage $@
# debugging
#ptb_show_option_values
# source in our include configurations
for i in "${PTB_OPT_include[@]}"; do
. $i
done
ptb_report_info "Total: `expr ${#server_options[@]} * ${#xb_options[@]}` combinations"
main
exit 0
|