Merge lp:~gl-az/percona-xtrabackup/BT-32889-history-on-server into lp:percona-xtrabackup/2.1

Proposed by George Ormond Lorch III on 2013-09-10
Status: Rejected
Rejected by: Alexey Kopytov on 2013-09-12
Proposed branch: lp:~gl-az/percona-xtrabackup/BT-32889-history-on-server
Merge into: lp:percona-xtrabackup/2.1
Diff against target: 678 lines (+553/-1)
2 files modified
innobackupex (+354/-1)
test/t/history_on_server.sh (+199/-0)
To merge this branch: bzr merge lp:~gl-az/percona-xtrabackup/BT-32889-history-on-server
Reviewer Review Type Date Requested Status
Registry Administrators 2013-09-10 Pending
Review via email: mp+184853@code.launchpad.net
To post a comment you must log in.
Alexey Kopytov (akopytov) wrote :

George, this should go to 2.2 only. I will update blueprints and branches.

Unmerged revisions

676. By George Ormond Lorch III on 2013-09-10

Implementation of xtrabackup http://blueprints.launchpad.net/percona-xtrabackup/+spec/history-on-the-server and test case.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'innobackupex'
2--- innobackupex 2013-08-30 09:55:04 +0000
3+++ innobackupex 2013-09-10 19:03:04 +0000
4@@ -145,6 +145,10 @@
5 my %mysql;
6 my $option_backup = '';
7
8+my $option_history;
9+my $option_incremental_history_name = '';
10+my $option_incremental_history_uuid = '';
11+
12 # name of the my.cnf configuration file
13 #my $config_file = '';
14
15@@ -193,6 +197,9 @@
16 # name of the file where slave info is written
17 my $slave_info;
18
19+# name of the file where version and backup history is written
20+my $backup_history;
21+
22 # mysql binlog position as given by "SHOW MASTER STATUS" command
23 my $mysql_binlog_position = '';
24
25@@ -268,6 +275,11 @@
26 my $copy_dir_overwrite;
27 my $copy_dir_resolve_isl;
28
29+# for history on server record
30+my $history_start_time = current_time_mysql();
31+my $history_lock_time = 0;
32+my $history_delete_checkpoints = 0;
33+
34 ######################################################################
35 # program execution begins here
36 ######################################################################
37@@ -404,6 +416,14 @@
38 }
39
40 #
41+# return current local time as mysql friendly string in form
42+# "2013-08-27 17:30:00"
43+#
44+sub current_time_mysql {
45+ return strftime("%Y-%m-%d %H:%M:%S", localtime());
46+}
47+
48+#
49 # Global initialization:
50 # 1. Override the 'die' builtin to customize the format of error messages
51 #
52@@ -651,6 +671,37 @@
53 detect_mysql_capabilities_for_backup(\%mysql);
54 }
55
56+ #
57+ # if one of the history incrementals is being used, try to grab the
58+ # innodb_to_lsn from the history table and set the option_incremental_lsn
59+ #
60+ if ($option_incremental && !$option_incremental_lsn) {
61+ if ($option_incremental_history_name) {
62+ my $query = "SELECT innodb_to_lsn ".
63+ "FROM PERCONA_SCHEMA.xtrabackup_history ".
64+ "WHERE name = '$option_incremental_history_name' ".
65+ "AND innodb_to_lsn IS NOT NULL ".
66+ "ORDER BY innodb_to_lsn DESC LIMIT 1";
67+
68+ eval {
69+ $option_incremental_lsn =
70+ $mysql{dbh}->selectrow_hashref($query)->{innodb_to_lsn};
71+ } || die("Error while attempting to find history record for name ".
72+ "'$option_incremental_history_name'\n");
73+ } elsif ($option_incremental_history_uuid) {
74+ my $query = "SELECT innodb_to_lsn ".
75+ "FROM PERCONA_SCHEMA.xtrabackup_history ".
76+ "WHERE uuid = '$option_incremental_history_uuid' ".
77+ "AND innodb_to_lsn IS NOT NULL";
78+
79+ eval {
80+ $option_incremental_lsn =
81+ $mysql{dbh}->selectrow_hashref($query)->{innodb_to_lsn};
82+ } || die("Error while attempting to find history record for uuid ".
83+ "'$option_incremental_history_uuid'\n");
84+ }
85+ }
86+
87 # start ibbackup as a child process
88 start_ibbackup();
89
90@@ -675,6 +726,9 @@
91 # make a prep copy before locking tables, if using rsync
92 backup_files(1);
93
94+ # start counting how long lock is held for history
95+ $history_lock_time = time();
96+
97 # flush tables with read lock
98 mysql_lockall(\%mysql);
99
100@@ -708,6 +762,13 @@
101 # release read locks on all tables
102 mysql_unlockall(\%mysql) if !$option_no_lock;
103
104+ # calculate how long lock was held for history
105+ if ($option_no_lock) {
106+ $history_lock_time = 0;
107+ } else {
108+ $history_lock_time = time() - $history_lock_time;
109+ }
110+
111 my $ibbackup_exit_code = wait_for_ibbackup_finish();
112
113 if ( $option_safe_slave_backup && $sql_thread_started) {
114@@ -731,6 +792,8 @@
115 print STDERR "$prefix MySQL slave binlog position: $mysql_slave_position\n";
116 }
117
118+ update_history(\%mysql);
119+
120 return $ibbackup_exit_code;
121 }
122
123@@ -2242,8 +2305,14 @@
124 $binlog_info = $work_dir . '/xtrabackup_binlog_info';
125 $galera_info = $work_dir . '/xtrabackup_galera_info';
126 $slave_info = $work_dir . '/xtrabackup_slave_info';
127+ $backup_history = $work_dir . '/xtrabackup_history';
128 write_backup_config_file($backup_config_file);
129
130+ if (!$option_extra_lsndir && defined($option_history)) {
131+ $option_extra_lsndir = $option_tmpdir;
132+ $history_delete_checkpoints = 1;
133+ }
134+
135 foreach (@xb_suspend_files) {
136 my $suspend_file = $work_dir . "$_";
137 if ( -e "$suspend_file" ) {
138@@ -2347,6 +2416,7 @@
139 'encrypt-threads=i' => \$option_encrypt_threads,
140 'encrypt-chunk-size=s' => \$option_encrypt_chunk_size,
141 'help' => \$option_help,
142+ 'history:s' => \$option_history,
143 'version' => \$option_version,
144 'throttle=i' => \$option_throttle,
145 'log-copy-interval=i', \$option_log_copy_interval,
146@@ -2374,6 +2444,8 @@
147 'incremental' => \$option_incremental,
148 'incremental-basedir=s' => \$option_incremental_basedir,
149 'incremental-force-scan' => \$option_incremental_force_scan,
150+ 'incremental-history-name=s' => \$option_incremental_history_name,
151+ 'incremental-history-uuid=s' => \$option_incremental_history_uuid,
152 'incremental-lsn=s' => \$option_incremental_lsn,
153 'incremental-dir=s' => \$option_incremental_dir,
154 'extra-lsndir=s' => \$option_extra_lsndir,
155@@ -2481,7 +2553,9 @@
156 # we are making a backup, get backup root directory
157 $option_backup = "1";
158 $backup_root = $ARGV[0];
159- if ($option_incremental && !$option_incremental_lsn) {
160+ if ($option_incremental && !$option_incremental_lsn &&
161+ !$option_incremental_history_name &&
162+ !$option_incremental_history_uuid) {
163 if ($option_incremental_basedir) {
164 $incremental_basedir = $option_incremental_basedir;
165 } else {
166@@ -3448,6 +3522,267 @@
167 'WHERE PLUGIN_NAME LIKE "INNODB_CHANGED_PAGES"')
168 }
169
170+#
171+# scrubs (replaces with ...) the value for the specified option
172+# Example:
173+# scrub_option("--user=fred --password=mypassword", "--password")
174+# returns "--user=fred --password=..."
175+#
176+sub scrub_option {
177+ my $scrub = shift;
178+ my $command = shift;
179+ $scrub = "--$scrub=";
180+
181+ my $pos = index($command, $scrub, 0);
182+ if ($pos >= 0) {
183+ substr($command, $pos, index($command, " ", $pos) - $pos, "$scrub...");
184+ }
185+ return $command;
186+}
187+
188+#
189+# Creates PERCONA_SCHEMA.xtrabackup_history and Writes a new history
190+# record to the table containg all the history info particular to the
191+# just completed backup.
192+#
193+sub update_history {
194+ my $con = shift;
195+ my $tmp;
196+ my $uuid;
197+ my $insert_vals = '';
198+ my $insert_query = '';
199+ my $file_content = '';
200+
201+ if (!defined($option_history)) {
202+ return;
203+ }
204+
205+ mysql_query($con, "CREATE DATABASE IF NOT EXISTS PERCONA_SCHEMA");
206+ mysql_query($con, "CREATE TABLE IF NOT EXISTS PERCONA_SCHEMA.xtrabackup_history(".
207+ "uuid VARCHAR(40) NOT NULL PRIMARY KEY,".
208+ "name VARCHAR(255) DEFAULT NULL,".
209+ "tool_name VARCHAR(255) DEFAULT NULL,".
210+ "tool_command TEXT DEFAULT NULL,".
211+ "tool_version VARCHAR(255) DEFAULT NULL,".
212+ "ibbackup_version VARCHAR(255) DEFAULT NULL,".
213+ "mysql_version VARCHAR(255) DEFAULT NULL,".
214+ "start_time TIMESTAMP NULL DEFAULT NULL,".
215+ "end_time TIMESTAMP NULL DEFAULT NULL,".
216+ "lock_time BIGINT UNSIGNED DEFAULT NULL,".
217+ "binlog_pos VARCHAR(128) DEFAULT NULL,".
218+ "innodb_from_lsn BIGINT UNSIGNED DEFAULT NULL,".
219+ "innodb_to_lsn BIGINT UNSIGNED DEFAULT NULL,".
220+ "partial ENUM('Y', 'N') DEFAULT NULL,".
221+ "incremental ENUM('Y', 'N') DEFAULT NULL,".
222+ "format ENUM('file', 'tar', 'xbstream') DEFAULT NULL,".
223+ "compact ENUM('Y', 'N') DEFAULT NULL,".
224+ "compressed ENUM('Y', 'N') DEFAULT NULL,".
225+ "encrypted ENUM('Y', 'N') DEFAULT NULL".
226+ ") ENGINE=innodb");
227+
228+ # uuid
229+ # we use the mysql UUID() function to avoid platform dependencies with uuidgen
230+ # and Data::UUID. We select uuid here individually here so that it can be
231+ # reported to stderr after successful history record insertion
232+ $tmp = "SELECT UUID() AS uuid";
233+ eval {
234+ $uuid = $mysql{dbh}->selectrow_hashref($tmp)->{uuid};
235+ } || die("Error while attempting to create UUID for history record.\n");
236+ $insert_vals = "'$uuid'";
237+ $file_content = "uuid = $uuid";
238+
239+ # name
240+ if ($option_history) {
241+ $insert_vals .= ", '$option_history'";
242+ $file_content .= "\nname = $option_history";
243+ } else {
244+ $insert_vals .= ", NULL";
245+ $file_content .= "\nname = ";
246+ }
247+
248+ # tool_name
249+ $tmp = basename($0);
250+ $insert_vals .= ", '$tmp'";
251+ $file_content .= "\ntool_name = $tmp";
252+
253+ # tool_command
254+ # there is probably a better way to do this but at this point ARGV has been
255+ # consumed/shifted and I don't think that trying to recompose the command
256+ # line from all of the $option_* variables is a great idea, besides, the
257+ # purpose of this particular field is mainly for debugging so giving a very
258+ # accurate/uninterpreted representation is highly desirable.
259+ $tmp = sprintf("cat /proc/%d/cmdline", $$);
260+ $tmp = qx($tmp);
261+ system("cp /proc/$$/cmdline /tmp");
262+ $tmp =~ s/\0/ /g; # transform embedded nulls between args to spaces
263+
264+ # scrub --password, --encrypt, --encrypt-key, and --encrypt-key-file
265+ # from tool_command
266+ $tmp = scrub_option("password", $tmp);
267+ $tmp = scrub_option("encrypt", $tmp);
268+ $tmp = scrub_option("encrypt-key", $tmp);
269+ $tmp = scrub_option("encrypt-key-file", $tmp);
270+ $insert_vals .= ",'$tmp'";
271+ $file_content .="\ntool_command = $tmp";
272+
273+ # tool_version
274+ $insert_vals .= ", '$innobackup_version'";
275+ $file_content .= "\ntool_version = $innobackup_version";
276+
277+ # ibbackup_version
278+ $tmp = "$option_ibbackup_binary -v 2>&1";
279+ $tmp = qx($tmp);
280+ chomp($tmp);
281+ $insert_vals .= ", '$tmp'";
282+ $file_content .= "\nibbackup_version = $tmp";
283+
284+ # mysql_version
285+ $tmp =
286+ $con->{dbh}->selectrow_hashref("SELECT VERSION() as version")->{version};
287+ $insert_vals .= ", '$tmp'";
288+ $file_content .= "\nmysql_version = $tmp";
289+
290+ # start_time
291+ $insert_vals .= ", '$history_start_time'";
292+ $file_content .= "\nstart_time = $history_start_time";
293+
294+ # end_time
295+ $tmp = current_time_mysql();
296+ $insert_vals .= ", '$tmp'";
297+ $file_content .= "\nend_time = $tmp";
298+
299+ # lock_time
300+ $insert_vals .= ", $history_lock_time";
301+ $file_content .= "\nlock_time = $history_lock_time";
302+
303+ # binlog_pos
304+ if ($mysql_binlog_position) {
305+ $tmp =$mysql_binlog_position;
306+ $tmp =~ s/'/\\'/g; # escape single quotes
307+ $insert_vals .= ", '$tmp'";
308+ $file_content .= "\nbinlog_pos = $mysql_binlog_position";
309+ } else {
310+ $insert_vals .= ", NULL";
311+ $file_content .= "\nbinlog_pos = ";
312+ }
313+
314+ # innodb_from_lsn
315+ # grab the from_lsn from the extra checkpoints file, parse and delete it
316+ # if necessary. This could generate an error if the checkpoints file
317+ # isn't 100% correct in the format.
318+ $tmp = "cat $option_extra_lsndir/xtrabackup_checkpoints | grep from_lsn";
319+ $tmp = qx($tmp);
320+ chomp($tmp);
321+ substr($tmp, 0, 11, ""); # strip "from_lsn = "
322+ if (length $tmp) {
323+ $insert_vals .= ", $tmp";
324+ $file_content .= "\ninnodb_from_lsn = $tmp";
325+ } else {
326+ print STDERR "WARNING : Unable to obtain from_lsn from " .
327+ "$option_extra_lsndir/xtrabackup_checkpoints, " .
328+ "writing NULL to history record.\n";
329+ $insert_vals .= ", NULL";
330+ $file_content .= "\ninnodb_from_lsn = ";
331+ }
332+
333+ # innodb_to_lsn
334+ # grab the to_lsn from the extra checkpoints file, parse and delete it
335+ # if necessary. This could generate an error if the checkpoints file
336+ # isn't 100% correct in the format.
337+ $tmp = "cat $option_extra_lsndir/xtrabackup_checkpoints | grep to_lsn";
338+ $tmp = qx($tmp);
339+ chomp($tmp);
340+ substr($tmp, 0, 9, ""); # strip "to_lsn = "
341+ if (length $tmp) {
342+ $insert_vals .= ", $tmp";
343+ $file_content .= "\ninnodb_to_lsn = $tmp";
344+ } else {
345+ print STDERR "WARNING : Unable to obtain to_lsn from " .
346+ "$option_extra_lsndir/xtrabackup_checkpoints, " .
347+ "writing NULL to history record.\n";
348+ $insert_vals .= ", NULL";
349+ $file_content .= "\ninnodb_to_lsn = ";
350+ }
351+
352+ # we're finished with the checkpoints file, delete it if it was a temp
353+ # only for the history
354+ if ($history_delete_checkpoints > 0) {
355+ system("rm -f $option_extra_lsndir/xtrabackup_checkpoints");
356+ }
357+
358+ # partial (Y | N)
359+ if ($option_include || $option_databases || $option_tables_file || $option_export) {
360+ $insert_vals .= ", 'Y'";
361+ $file_content .= "\npartial = Y";
362+ } else {
363+ $insert_vals .= ", 'N'";
364+ $file_content .= "\npartial = N";
365+ }
366+
367+ # incremental (Y | N)
368+ if ($option_incremental) {
369+ $insert_vals .= ", 'Y'";
370+ $file_content .= "\nincremental = Y";
371+ } else {
372+ $insert_vals .= ", 'N'";
373+ $file_content .= "\nincremental = N";
374+ }
375+
376+ # format (file | tar | xbsream)
377+ if ($option_stream eq 'tar') {
378+ $insert_vals .= ", 'tar'";
379+ $file_content .= "\nformat = tar";
380+ } elsif ($option_stream eq 'xbstream') {
381+ $insert_vals .= ", 'xbstream'";
382+ $file_content .= "\nformat = xbstream";
383+ } else {
384+ $insert_vals .= ", 'file'";
385+ $file_content .= "\nformat = file";
386+ }
387+
388+ # compact (Y | N)
389+ if ($option_compact) {
390+ $insert_vals .= ", 'Y'";
391+ $file_content .= "\ncompact = Y";
392+ } else {
393+ $insert_vals .= ", 'N'";
394+ $file_content .= "\ncompact = N";
395+ }
396+
397+ # compressed (Y | N)
398+ if ($option_compress) {
399+ $insert_vals .= ", 'Y'";
400+ $file_content .= "\ncompressed = Y";
401+ } else {
402+ $insert_vals .= ", 'N'";
403+ $file_content .= "\ncompressed = N";
404+ }
405+
406+ # encrypted (Y | N)
407+ if ($option_encrypt) {
408+ $insert_vals .= ", 'Y'";
409+ $file_content .= "\nencrypted = Y";
410+ } else {
411+ $insert_vals .= ", 'N'";
412+ $file_content .= "\nencrypted = N";
413+ }
414+
415+ # build and execute the query
416+ $insert_query = "INSERT INTO PERCONA_SCHEMA.xtrabackup_history(".
417+ "uuid, name, tool_name, tool_command, tool_version, ".
418+ "ibbackup_version, mysql_version, start_time, end_time, ".
419+ "lock_time, binlog_pos, innodb_from_lsn, innodb_to_lsn, ".
420+ "partial, incremental, format, compact, compressed, ".
421+ "encrypted) VALUES($insert_vals)";
422+
423+ mysql_query($con, $insert_query);
424+
425+ print STDERR "$prefix Backup history record uuid $uuid successfully written\n";
426+
427+ # create the backup history file
428+ write_to_backup_file("$backup_history", "$file_content");
429+}
430+
431 =pod
432
433 =head1 NAME
434@@ -3466,8 +3801,10 @@
435 [--defaults-file=MY.CNF] [--defaults-group=GROUP-NAME]
436 [--databases=LIST] [--no-lock]
437 [--tmpdir=DIRECTORY] [--tables-file=FILE]
438+ [--no-history] [--history-name=NAME]
439 [--incremental] [--incremental-basedir]
440 [--incremental-dir] [--incremental-force-scan] [--incremental-lsn]
441+ [--incremental-history-name=NAME] [--incremental-history-uuid=UUID]
442 [--compact]
443 BACKUP-ROOT-DIR
444
445@@ -3637,6 +3974,14 @@
446
447 This option displays a help screen and exits.
448
449+=item --history-name
450+
451+This option specifies a backup name that will be placed within the history record.
452+
453+=item --no-history
454+
455+This option disables the creation of a backup history record and file.
456+
457 =item --host=HOST
458
459 This option specifies the host to use when connecting to the database server with TCP/IP. The option accepts a string argument. It is passed to the mysql child process without alteration. See mysql --help for details.
460@@ -3661,6 +4006,14 @@
461
462 This option specifies the directory where the incremental backup will be combined with the full backup to make a new full backup. The option accepts a string argument. It is used with the --incremental option.
463
464+=item --incremental-history-name=NAME
465+
466+This option specifies the name of the backup series stored in the PERCONA_SCHEMA.xtrabackup_history history record to base an incremental backup on. Xtrabackup will search the history table looking for the most recent (highest innodb_to_lsn), successful backup in the series and take the to_lsn value to use as the starting lsn for the incremental backup. This will be mutually exclusive with --incremental-history-uuid, --incremental-basedir and --incremental-lsn. If no valid lsn can be found (no series by that name, no successful backups by that name) xtrabackup will return with an error. It is used with the --incremental option.
467+
468+=item --incremental-history-uuid=UUID
469+
470+This option specifies the UUID of the specific history record stored in the PERCONA_SCHEMA.xtrabackup_history to base an incremental backup on. --incremental-history-name, --incremental-basedir and --incremental-lsn. If no valid lsn can be found (no success record with that uuid) xtrabackup will return with an error. It is used with the --incremental option.
471+
472 =item --incremental-force-scan
473
474 This options tells xtrabackup to perform full scan of data files for taking an incremental backup even if full changed page bitmap data is available to enable the backup without the full scan.
475
476=== added file 'test/t/history_on_server.sh'
477--- test/t/history_on_server.sh 1970-01-01 00:00:00 +0000
478+++ test/t/history_on_server.sh 2013-09-10 19:03:04 +0000
479@@ -0,0 +1,199 @@
480+###############################################################################
481+# Test history-on-server feature
482+###############################################################################
483+
484+. inc/common.sh
485+
486+
487+###############################################################################
488+# Gets a single column value from the last history record added
489+function get_one_value()
490+{
491+ local column=$1
492+ shift
493+ val=`${MYSQL} ${MYSQL_ARGS} -Ns -e "SELECT $column FROM PERCONA_SCHEMA.xtrabackup_history ORDER BY start_time DESC LIMIT 1"`
494+}
495+
496+###############################################################################
497+# Checks a single column from the last history record added for some value and
498+# not NULL.
499+function check_for_not_NULL()
500+{
501+ local column=$1
502+ shift
503+ get_one_value "$column"
504+ if [ -z "$val" ] || [ "$val" = "NULL" ];
505+ then
506+ vlog "Error: $column in history record invalid, expected NULL"
507+ exit 1
508+ fi
509+}
510+
511+
512+###############################################################################
513+# Checks a single column from the last history record added to see if is a
514+# specific value.
515+function check_for_value()
516+{
517+ local column=$1
518+ shift
519+ get_one_value "$column"
520+ if [ -z "$val" ] || [ "$val" != "$@" ];
521+ then
522+ vlog "Error: $column in history record invalid, expected $@"
523+ exit 1
524+ fi
525+}
526+
527+
528+###############################################################################
529+vlog "Prepping server"
530+start_server
531+load_dbase_schema incremental_sample
532+multi_row_insert incremental_sample.test \({1..100},100\)
533+backup_dir=$topdir/backups
534+mkdir $backup_dir
535+
536+
537+###############################################################################
538+# This tests the to make sure that no xtrabackup_history unless --history is
539+# specified
540+vlog "Testing no --history"
541+innobackupex --stream=tar $backup_dir > /dev/null
542+
543+run_cmd_expect_failure get_one_value "uuid"
544+
545+
546+###############################################################################
547+# This tests the basic creation of a history record and that fields are
548+# populated with some data. It also tests specifically that
549+# partial, incremental, compact, compressed, encrypted and format are exactly
550+# the correct values after the backup.
551+# Missing is a test that binlog_pos is NULL, that would require restarting the
552+# server without the log-bin option in the .cnf file but that has been tested
553+# manually and doesn't seem to be something that would be required to be
554+# validated.
555+vlog "Testing basic history record"
556+innobackupex --history=test1 --stream=tar $backup_dir > /dev/null
557+
558+for column in uuid name tool_name tool_command tool_version ibbackup_version \
559+mysql_version start_time end_time lock_time binlog_pos innodb_from_lsn \
560+innodb_to_lsn
561+do
562+ check_for_not_NULL "$column"
563+done
564+
565+for column in partial incremental compact compressed encrypted
566+do
567+ check_for_value "$column" "N"
568+done
569+
570+check_for_value "format" "tar"
571+
572+# saving for later
573+get_one_value "innodb_to_lsn"
574+first_to_lsn=$val
575+
576+
577+###############################################################################
578+# This tests the taking of an incremental backup based on the last record
579+# of a history series and validates that the lsns in the record are correct.
580+# It also tests that format, incremental and compact are exactly the correct
581+# values after the backup.
582+vlog "Testing incremental based on history name"
583+
584+multi_row_insert incremental_sample.test \({101..200},100\)
585+
586+innobackupex --history=test1 --incremental \
587+--incremental-history-name=test1 --compact $backup_dir > /dev/null
588+
589+# saving for later
590+get_one_value "uuid"
591+second_uuid=$val
592+get_one_value "innodb_from_lsn"
593+second_from_lsn=$val
594+get_one_value "innodb_to_lsn"
595+second_to_lsn=$val
596+
597+check_for_value "format" "file"
598+check_for_value "incremental" "Y"
599+check_for_value "compact" "Y"
600+
601+if [ -z "$second_from_lsn" ] || [ "$second_from_lsn" != "$first_to_lsn" ]
602+then
603+ vlog "Second backup was not properly based on the to_lsn of the first"
604+ exit 1
605+fi
606+
607+multi_row_insert incremental_sample.test \({201..300},100\)
608+
609+# This will be a backup based on the last incremental just done, so, its
610+# innodb_from_lsn (third_from_lsn) should be the same as the value in
611+# second_to_lsn. This tests that we find the right record in the test1 series
612+# out of the two records that should be present before the backup is done.
613+innobackupex --history=test1 --incremental \
614+--incremental-history-name=test1 $backup_dir > /dev/null
615+
616+# saving for later
617+get_one_value "uuid"
618+third_uuid=$val
619+get_one_value "innodb_from_lsn"
620+third_from_lsn=$val
621+get_one_value "innodb_to_lsn"
622+third_to_lsn=$val
623+
624+if [ -z "$third_from_lsn" ] || [ "$third_from_lsn" != "$second_to_lsn" ]
625+then
626+ vlog "Third backup was not properly based on the to_lsn of the second"
627+ exit 1
628+fi
629+
630+
631+###############################################################################
632+# This tests that we can base an incremental on a specific history record
633+# identified by its uuid that we captured earlier from a history record or it
634+# could be scraped from the output of innobackupex at some point in the past.
635+# It also tests specifically that incremental, compressed, encrypted and format
636+# are exactly the correct values after the backup.
637+# It tests that --history can be specified, resulting in a history record with
638+# no name
639+vlog "Testing incremental based on history uuid"
640+multi_row_insert incremental_sample.test \({301..400},100\)
641+
642+innobackupex --history --incremental --incremental-history-uuid=$third_uuid \
643+--stream=xbstream --compress --encrypt=AES256 \
644+--encrypt-key=percona_xtrabackup_is_awesome___ $backup_dir > /dev/null
645+
646+get_one_value "innodb_from_lsn"
647+fourth_from_lsn=$val
648+
649+for column in incremental compressed encrypted
650+do
651+ check_for_value "$column" "Y"
652+done
653+
654+check_for_value "format" "xbstream"
655+check_for_value "name" "NULL"
656+
657+if [ -z "$fourth_from_lsn" ] || [ "$fourth_from_lsn" != "$third_to_lsn" ]
658+then
659+ vlog "Fourth backup was not properly based on the to_lsn of the third"
660+ exit 1
661+fi
662+
663+
664+###############################################################################
665+# This tests that innobackupex fails when an invalid --incremental-history-name
666+# is given.
667+vlog "Testing bad --incremental-history-name"
668+run_cmd_expect_failure $IB_BIN $IB_ARGS --incremental \
669+--incremental-history-name=foo --stream=tar $backup_dir > /dev/null
670+
671+
672+
673+###############################################################################
674+# This tests that innobackupex fails when an invalid --incremental-history-uuid
675+# is given.
676+vlog "Testing bad --incremental-history-uuid"
677+run_cmd_expect_failure $IB_BIN $IB_ARGS --incremental \
678+--incremental-history-uuid=foo --stream=tar $backup_dir > /dev/null

Subscribers

People subscribed via source and target branches