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

Proposed by George Ormond Lorch III
Status: Rejected
Rejected by: Alexey Kopytov
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 Pending
Review via email: mp+184853@code.launchpad.net
To post a comment you must log in.
Revision history for this message
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

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
=== modified file 'innobackupex'
--- innobackupex 2013-08-30 09:55:04 +0000
+++ innobackupex 2013-09-10 19:03:04 +0000
@@ -145,6 +145,10 @@
145my %mysql;145my %mysql;
146my $option_backup = '';146my $option_backup = '';
147147
148my $option_history;
149my $option_incremental_history_name = '';
150my $option_incremental_history_uuid = '';
151
148# name of the my.cnf configuration file152# name of the my.cnf configuration file
149#my $config_file = '';153#my $config_file = '';
150154
@@ -193,6 +197,9 @@
193# name of the file where slave info is written197# name of the file where slave info is written
194my $slave_info;198my $slave_info;
195199
200# name of the file where version and backup history is written
201my $backup_history;
202
196# mysql binlog position as given by "SHOW MASTER STATUS" command203# mysql binlog position as given by "SHOW MASTER STATUS" command
197my $mysql_binlog_position = '';204my $mysql_binlog_position = '';
198205
@@ -268,6 +275,11 @@
268my $copy_dir_overwrite;275my $copy_dir_overwrite;
269my $copy_dir_resolve_isl;276my $copy_dir_resolve_isl;
270277
278# for history on server record
279my $history_start_time = current_time_mysql();
280my $history_lock_time = 0;
281my $history_delete_checkpoints = 0;
282
271######################################################################283######################################################################
272# program execution begins here284# program execution begins here
273######################################################################285######################################################################
@@ -404,6 +416,14 @@
404}416}
405417
406#418#
419# return current local time as mysql friendly string in form
420# "2013-08-27 17:30:00"
421#
422sub current_time_mysql {
423 return strftime("%Y-%m-%d %H:%M:%S", localtime());
424}
425
426#
407# Global initialization:427# Global initialization:
408# 1. Override the 'die' builtin to customize the format of error messages428# 1. Override the 'die' builtin to customize the format of error messages
409#429#
@@ -651,6 +671,37 @@
651 detect_mysql_capabilities_for_backup(\%mysql);671 detect_mysql_capabilities_for_backup(\%mysql);
652 }672 }
653673
674 #
675 # if one of the history incrementals is being used, try to grab the
676 # innodb_to_lsn from the history table and set the option_incremental_lsn
677 #
678 if ($option_incremental && !$option_incremental_lsn) {
679 if ($option_incremental_history_name) {
680 my $query = "SELECT innodb_to_lsn ".
681 "FROM PERCONA_SCHEMA.xtrabackup_history ".
682 "WHERE name = '$option_incremental_history_name' ".
683 "AND innodb_to_lsn IS NOT NULL ".
684 "ORDER BY innodb_to_lsn DESC LIMIT 1";
685
686 eval {
687 $option_incremental_lsn =
688 $mysql{dbh}->selectrow_hashref($query)->{innodb_to_lsn};
689 } || die("Error while attempting to find history record for name ".
690 "'$option_incremental_history_name'\n");
691 } elsif ($option_incremental_history_uuid) {
692 my $query = "SELECT innodb_to_lsn ".
693 "FROM PERCONA_SCHEMA.xtrabackup_history ".
694 "WHERE uuid = '$option_incremental_history_uuid' ".
695 "AND innodb_to_lsn IS NOT NULL";
696
697 eval {
698 $option_incremental_lsn =
699 $mysql{dbh}->selectrow_hashref($query)->{innodb_to_lsn};
700 } || die("Error while attempting to find history record for uuid ".
701 "'$option_incremental_history_uuid'\n");
702 }
703 }
704
654 # start ibbackup as a child process705 # start ibbackup as a child process
655 start_ibbackup();706 start_ibbackup();
656707
@@ -675,6 +726,9 @@
675 # make a prep copy before locking tables, if using rsync726 # make a prep copy before locking tables, if using rsync
676 backup_files(1);727 backup_files(1);
677728
729 # start counting how long lock is held for history
730 $history_lock_time = time();
731
678 # flush tables with read lock732 # flush tables with read lock
679 mysql_lockall(\%mysql);733 mysql_lockall(\%mysql);
680734
@@ -708,6 +762,13 @@
708 # release read locks on all tables762 # release read locks on all tables
709 mysql_unlockall(\%mysql) if !$option_no_lock;763 mysql_unlockall(\%mysql) if !$option_no_lock;
710764
765 # calculate how long lock was held for history
766 if ($option_no_lock) {
767 $history_lock_time = 0;
768 } else {
769 $history_lock_time = time() - $history_lock_time;
770 }
771
711 my $ibbackup_exit_code = wait_for_ibbackup_finish();772 my $ibbackup_exit_code = wait_for_ibbackup_finish();
712773
713 if ( $option_safe_slave_backup && $sql_thread_started) {774 if ( $option_safe_slave_backup && $sql_thread_started) {
@@ -731,6 +792,8 @@
731 print STDERR "$prefix MySQL slave binlog position: $mysql_slave_position\n";792 print STDERR "$prefix MySQL slave binlog position: $mysql_slave_position\n";
732 }793 }
733794
795 update_history(\%mysql);
796
734 return $ibbackup_exit_code;797 return $ibbackup_exit_code;
735}798}
736799
@@ -2242,8 +2305,14 @@
2242 $binlog_info = $work_dir . '/xtrabackup_binlog_info';2305 $binlog_info = $work_dir . '/xtrabackup_binlog_info';
2243 $galera_info = $work_dir . '/xtrabackup_galera_info';2306 $galera_info = $work_dir . '/xtrabackup_galera_info';
2244 $slave_info = $work_dir . '/xtrabackup_slave_info';2307 $slave_info = $work_dir . '/xtrabackup_slave_info';
2308 $backup_history = $work_dir . '/xtrabackup_history';
2245 write_backup_config_file($backup_config_file);2309 write_backup_config_file($backup_config_file);
22462310
2311 if (!$option_extra_lsndir && defined($option_history)) {
2312 $option_extra_lsndir = $option_tmpdir;
2313 $history_delete_checkpoints = 1;
2314 }
2315
2247 foreach (@xb_suspend_files) {2316 foreach (@xb_suspend_files) {
2248 my $suspend_file = $work_dir . "$_";2317 my $suspend_file = $work_dir . "$_";
2249 if ( -e "$suspend_file" ) {2318 if ( -e "$suspend_file" ) {
@@ -2347,6 +2416,7 @@
2347 'encrypt-threads=i' => \$option_encrypt_threads,2416 'encrypt-threads=i' => \$option_encrypt_threads,
2348 'encrypt-chunk-size=s' => \$option_encrypt_chunk_size,2417 'encrypt-chunk-size=s' => \$option_encrypt_chunk_size,
2349 'help' => \$option_help,2418 'help' => \$option_help,
2419 'history:s' => \$option_history,
2350 'version' => \$option_version,2420 'version' => \$option_version,
2351 'throttle=i' => \$option_throttle,2421 'throttle=i' => \$option_throttle,
2352 'log-copy-interval=i', \$option_log_copy_interval,2422 'log-copy-interval=i', \$option_log_copy_interval,
@@ -2374,6 +2444,8 @@
2374 'incremental' => \$option_incremental,2444 'incremental' => \$option_incremental,
2375 'incremental-basedir=s' => \$option_incremental_basedir,2445 'incremental-basedir=s' => \$option_incremental_basedir,
2376 'incremental-force-scan' => \$option_incremental_force_scan,2446 'incremental-force-scan' => \$option_incremental_force_scan,
2447 'incremental-history-name=s' => \$option_incremental_history_name,
2448 'incremental-history-uuid=s' => \$option_incremental_history_uuid,
2377 'incremental-lsn=s' => \$option_incremental_lsn,2449 'incremental-lsn=s' => \$option_incremental_lsn,
2378 'incremental-dir=s' => \$option_incremental_dir,2450 'incremental-dir=s' => \$option_incremental_dir,
2379 'extra-lsndir=s' => \$option_extra_lsndir,2451 'extra-lsndir=s' => \$option_extra_lsndir,
@@ -2481,7 +2553,9 @@
2481 # we are making a backup, get backup root directory2553 # we are making a backup, get backup root directory
2482 $option_backup = "1";2554 $option_backup = "1";
2483 $backup_root = $ARGV[0];2555 $backup_root = $ARGV[0];
2484 if ($option_incremental && !$option_incremental_lsn) {2556 if ($option_incremental && !$option_incremental_lsn &&
2557 !$option_incremental_history_name &&
2558 !$option_incremental_history_uuid) {
2485 if ($option_incremental_basedir) {2559 if ($option_incremental_basedir) {
2486 $incremental_basedir = $option_incremental_basedir;2560 $incremental_basedir = $option_incremental_basedir;
2487 } else {2561 } else {
@@ -3448,6 +3522,267 @@
3448 'WHERE PLUGIN_NAME LIKE "INNODB_CHANGED_PAGES"')3522 'WHERE PLUGIN_NAME LIKE "INNODB_CHANGED_PAGES"')
3449}3523}
34503524
3525#
3526# scrubs (replaces with ...) the value for the specified option
3527# Example:
3528# scrub_option("--user=fred --password=mypassword", "--password")
3529# returns "--user=fred --password=..."
3530#
3531sub scrub_option {
3532 my $scrub = shift;
3533 my $command = shift;
3534 $scrub = "--$scrub=";
3535
3536 my $pos = index($command, $scrub, 0);
3537 if ($pos >= 0) {
3538 substr($command, $pos, index($command, " ", $pos) - $pos, "$scrub...");
3539 }
3540 return $command;
3541}
3542
3543#
3544# Creates PERCONA_SCHEMA.xtrabackup_history and Writes a new history
3545# record to the table containg all the history info particular to the
3546# just completed backup.
3547#
3548sub update_history {
3549 my $con = shift;
3550 my $tmp;
3551 my $uuid;
3552 my $insert_vals = '';
3553 my $insert_query = '';
3554 my $file_content = '';
3555
3556 if (!defined($option_history)) {
3557 return;
3558 }
3559
3560 mysql_query($con, "CREATE DATABASE IF NOT EXISTS PERCONA_SCHEMA");
3561 mysql_query($con, "CREATE TABLE IF NOT EXISTS PERCONA_SCHEMA.xtrabackup_history(".
3562 "uuid VARCHAR(40) NOT NULL PRIMARY KEY,".
3563 "name VARCHAR(255) DEFAULT NULL,".
3564 "tool_name VARCHAR(255) DEFAULT NULL,".
3565 "tool_command TEXT DEFAULT NULL,".
3566 "tool_version VARCHAR(255) DEFAULT NULL,".
3567 "ibbackup_version VARCHAR(255) DEFAULT NULL,".
3568 "mysql_version VARCHAR(255) DEFAULT NULL,".
3569 "start_time TIMESTAMP NULL DEFAULT NULL,".
3570 "end_time TIMESTAMP NULL DEFAULT NULL,".
3571 "lock_time BIGINT UNSIGNED DEFAULT NULL,".
3572 "binlog_pos VARCHAR(128) DEFAULT NULL,".
3573 "innodb_from_lsn BIGINT UNSIGNED DEFAULT NULL,".
3574 "innodb_to_lsn BIGINT UNSIGNED DEFAULT NULL,".
3575 "partial ENUM('Y', 'N') DEFAULT NULL,".
3576 "incremental ENUM('Y', 'N') DEFAULT NULL,".
3577 "format ENUM('file', 'tar', 'xbstream') DEFAULT NULL,".
3578 "compact ENUM('Y', 'N') DEFAULT NULL,".
3579 "compressed ENUM('Y', 'N') DEFAULT NULL,".
3580 "encrypted ENUM('Y', 'N') DEFAULT NULL".
3581 ") ENGINE=innodb");
3582
3583 # uuid
3584 # we use the mysql UUID() function to avoid platform dependencies with uuidgen
3585 # and Data::UUID. We select uuid here individually here so that it can be
3586 # reported to stderr after successful history record insertion
3587 $tmp = "SELECT UUID() AS uuid";
3588 eval {
3589 $uuid = $mysql{dbh}->selectrow_hashref($tmp)->{uuid};
3590 } || die("Error while attempting to create UUID for history record.\n");
3591 $insert_vals = "'$uuid'";
3592 $file_content = "uuid = $uuid";
3593
3594 # name
3595 if ($option_history) {
3596 $insert_vals .= ", '$option_history'";
3597 $file_content .= "\nname = $option_history";
3598 } else {
3599 $insert_vals .= ", NULL";
3600 $file_content .= "\nname = ";
3601 }
3602
3603 # tool_name
3604 $tmp = basename($0);
3605 $insert_vals .= ", '$tmp'";
3606 $file_content .= "\ntool_name = $tmp";
3607
3608 # tool_command
3609 # there is probably a better way to do this but at this point ARGV has been
3610 # consumed/shifted and I don't think that trying to recompose the command
3611 # line from all of the $option_* variables is a great idea, besides, the
3612 # purpose of this particular field is mainly for debugging so giving a very
3613 # accurate/uninterpreted representation is highly desirable.
3614 $tmp = sprintf("cat /proc/%d/cmdline", $$);
3615 $tmp = qx($tmp);
3616 system("cp /proc/$$/cmdline /tmp");
3617 $tmp =~ s/\0/ /g; # transform embedded nulls between args to spaces
3618
3619 # scrub --password, --encrypt, --encrypt-key, and --encrypt-key-file
3620 # from tool_command
3621 $tmp = scrub_option("password", $tmp);
3622 $tmp = scrub_option("encrypt", $tmp);
3623 $tmp = scrub_option("encrypt-key", $tmp);
3624 $tmp = scrub_option("encrypt-key-file", $tmp);
3625 $insert_vals .= ",'$tmp'";
3626 $file_content .="\ntool_command = $tmp";
3627
3628 # tool_version
3629 $insert_vals .= ", '$innobackup_version'";
3630 $file_content .= "\ntool_version = $innobackup_version";
3631
3632 # ibbackup_version
3633 $tmp = "$option_ibbackup_binary -v 2>&1";
3634 $tmp = qx($tmp);
3635 chomp($tmp);
3636 $insert_vals .= ", '$tmp'";
3637 $file_content .= "\nibbackup_version = $tmp";
3638
3639 # mysql_version
3640 $tmp =
3641 $con->{dbh}->selectrow_hashref("SELECT VERSION() as version")->{version};
3642 $insert_vals .= ", '$tmp'";
3643 $file_content .= "\nmysql_version = $tmp";
3644
3645 # start_time
3646 $insert_vals .= ", '$history_start_time'";
3647 $file_content .= "\nstart_time = $history_start_time";
3648
3649 # end_time
3650 $tmp = current_time_mysql();
3651 $insert_vals .= ", '$tmp'";
3652 $file_content .= "\nend_time = $tmp";
3653
3654 # lock_time
3655 $insert_vals .= ", $history_lock_time";
3656 $file_content .= "\nlock_time = $history_lock_time";
3657
3658 # binlog_pos
3659 if ($mysql_binlog_position) {
3660 $tmp =$mysql_binlog_position;
3661 $tmp =~ s/'/\\'/g; # escape single quotes
3662 $insert_vals .= ", '$tmp'";
3663 $file_content .= "\nbinlog_pos = $mysql_binlog_position";
3664 } else {
3665 $insert_vals .= ", NULL";
3666 $file_content .= "\nbinlog_pos = ";
3667 }
3668
3669 # innodb_from_lsn
3670 # grab the from_lsn from the extra checkpoints file, parse and delete it
3671 # if necessary. This could generate an error if the checkpoints file
3672 # isn't 100% correct in the format.
3673 $tmp = "cat $option_extra_lsndir/xtrabackup_checkpoints | grep from_lsn";
3674 $tmp = qx($tmp);
3675 chomp($tmp);
3676 substr($tmp, 0, 11, ""); # strip "from_lsn = "
3677 if (length $tmp) {
3678 $insert_vals .= ", $tmp";
3679 $file_content .= "\ninnodb_from_lsn = $tmp";
3680 } else {
3681 print STDERR "WARNING : Unable to obtain from_lsn from " .
3682 "$option_extra_lsndir/xtrabackup_checkpoints, " .
3683 "writing NULL to history record.\n";
3684 $insert_vals .= ", NULL";
3685 $file_content .= "\ninnodb_from_lsn = ";
3686 }
3687
3688 # innodb_to_lsn
3689 # grab the to_lsn from the extra checkpoints file, parse and delete it
3690 # if necessary. This could generate an error if the checkpoints file
3691 # isn't 100% correct in the format.
3692 $tmp = "cat $option_extra_lsndir/xtrabackup_checkpoints | grep to_lsn";
3693 $tmp = qx($tmp);
3694 chomp($tmp);
3695 substr($tmp, 0, 9, ""); # strip "to_lsn = "
3696 if (length $tmp) {
3697 $insert_vals .= ", $tmp";
3698 $file_content .= "\ninnodb_to_lsn = $tmp";
3699 } else {
3700 print STDERR "WARNING : Unable to obtain to_lsn from " .
3701 "$option_extra_lsndir/xtrabackup_checkpoints, " .
3702 "writing NULL to history record.\n";
3703 $insert_vals .= ", NULL";
3704 $file_content .= "\ninnodb_to_lsn = ";
3705 }
3706
3707 # we're finished with the checkpoints file, delete it if it was a temp
3708 # only for the history
3709 if ($history_delete_checkpoints > 0) {
3710 system("rm -f $option_extra_lsndir/xtrabackup_checkpoints");
3711 }
3712
3713 # partial (Y | N)
3714 if ($option_include || $option_databases || $option_tables_file || $option_export) {
3715 $insert_vals .= ", 'Y'";
3716 $file_content .= "\npartial = Y";
3717 } else {
3718 $insert_vals .= ", 'N'";
3719 $file_content .= "\npartial = N";
3720 }
3721
3722 # incremental (Y | N)
3723 if ($option_incremental) {
3724 $insert_vals .= ", 'Y'";
3725 $file_content .= "\nincremental = Y";
3726 } else {
3727 $insert_vals .= ", 'N'";
3728 $file_content .= "\nincremental = N";
3729 }
3730
3731 # format (file | tar | xbsream)
3732 if ($option_stream eq 'tar') {
3733 $insert_vals .= ", 'tar'";
3734 $file_content .= "\nformat = tar";
3735 } elsif ($option_stream eq 'xbstream') {
3736 $insert_vals .= ", 'xbstream'";
3737 $file_content .= "\nformat = xbstream";
3738 } else {
3739 $insert_vals .= ", 'file'";
3740 $file_content .= "\nformat = file";
3741 }
3742
3743 # compact (Y | N)
3744 if ($option_compact) {
3745 $insert_vals .= ", 'Y'";
3746 $file_content .= "\ncompact = Y";
3747 } else {
3748 $insert_vals .= ", 'N'";
3749 $file_content .= "\ncompact = N";
3750 }
3751
3752 # compressed (Y | N)
3753 if ($option_compress) {
3754 $insert_vals .= ", 'Y'";
3755 $file_content .= "\ncompressed = Y";
3756 } else {
3757 $insert_vals .= ", 'N'";
3758 $file_content .= "\ncompressed = N";
3759 }
3760
3761 # encrypted (Y | N)
3762 if ($option_encrypt) {
3763 $insert_vals .= ", 'Y'";
3764 $file_content .= "\nencrypted = Y";
3765 } else {
3766 $insert_vals .= ", 'N'";
3767 $file_content .= "\nencrypted = N";
3768 }
3769
3770 # build and execute the query
3771 $insert_query = "INSERT INTO PERCONA_SCHEMA.xtrabackup_history(".
3772 "uuid, name, tool_name, tool_command, tool_version, ".
3773 "ibbackup_version, mysql_version, start_time, end_time, ".
3774 "lock_time, binlog_pos, innodb_from_lsn, innodb_to_lsn, ".
3775 "partial, incremental, format, compact, compressed, ".
3776 "encrypted) VALUES($insert_vals)";
3777
3778 mysql_query($con, $insert_query);
3779
3780 print STDERR "$prefix Backup history record uuid $uuid successfully written\n";
3781
3782 # create the backup history file
3783 write_to_backup_file("$backup_history", "$file_content");
3784}
3785
3451=pod3786=pod
34523787
3453=head1 NAME3788=head1 NAME
@@ -3466,8 +3801,10 @@
3466 [--defaults-file=MY.CNF] [--defaults-group=GROUP-NAME]3801 [--defaults-file=MY.CNF] [--defaults-group=GROUP-NAME]
3467 [--databases=LIST] [--no-lock] 3802 [--databases=LIST] [--no-lock]
3468 [--tmpdir=DIRECTORY] [--tables-file=FILE]3803 [--tmpdir=DIRECTORY] [--tables-file=FILE]
3804 [--no-history] [--history-name=NAME]
3469 [--incremental] [--incremental-basedir]3805 [--incremental] [--incremental-basedir]
3470 [--incremental-dir] [--incremental-force-scan] [--incremental-lsn]3806 [--incremental-dir] [--incremental-force-scan] [--incremental-lsn]
3807 [--incremental-history-name=NAME] [--incremental-history-uuid=UUID]
3471 [--compact] 3808 [--compact]
3472 BACKUP-ROOT-DIR3809 BACKUP-ROOT-DIR
34733810
@@ -3637,6 +3974,14 @@
36373974
3638This option displays a help screen and exits.3975This option displays a help screen and exits.
36393976
3977=item --history-name
3978
3979This option specifies a backup name that will be placed within the history record.
3980
3981=item --no-history
3982
3983This option disables the creation of a backup history record and file.
3984
3640=item --host=HOST3985=item --host=HOST
36413986
3642This 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.3987This 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.
@@ -3661,6 +4006,14 @@
36614006
3662This 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.4007This 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.
36634008
4009=item --incremental-history-name=NAME
4010
4011This 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.
4012
4013=item --incremental-history-uuid=UUID
4014
4015This 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.
4016
3664=item --incremental-force-scan4017=item --incremental-force-scan
36654018
3666This 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.4019This 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.
36674020
=== added file 'test/t/history_on_server.sh'
--- test/t/history_on_server.sh 1970-01-01 00:00:00 +0000
+++ test/t/history_on_server.sh 2013-09-10 19:03:04 +0000
@@ -0,0 +1,199 @@
1###############################################################################
2# Test history-on-server feature
3###############################################################################
4
5. inc/common.sh
6
7
8###############################################################################
9# Gets a single column value from the last history record added
10function get_one_value()
11{
12 local column=$1
13 shift
14 val=`${MYSQL} ${MYSQL_ARGS} -Ns -e "SELECT $column FROM PERCONA_SCHEMA.xtrabackup_history ORDER BY start_time DESC LIMIT 1"`
15}
16
17###############################################################################
18# Checks a single column from the last history record added for some value and
19# not NULL.
20function check_for_not_NULL()
21{
22 local column=$1
23 shift
24 get_one_value "$column"
25 if [ -z "$val" ] || [ "$val" = "NULL" ];
26 then
27 vlog "Error: $column in history record invalid, expected NULL"
28 exit 1
29 fi
30}
31
32
33###############################################################################
34# Checks a single column from the last history record added to see if is a
35# specific value.
36function check_for_value()
37{
38 local column=$1
39 shift
40 get_one_value "$column"
41 if [ -z "$val" ] || [ "$val" != "$@" ];
42 then
43 vlog "Error: $column in history record invalid, expected $@"
44 exit 1
45 fi
46}
47
48
49###############################################################################
50vlog "Prepping server"
51start_server
52load_dbase_schema incremental_sample
53multi_row_insert incremental_sample.test \({1..100},100\)
54backup_dir=$topdir/backups
55mkdir $backup_dir
56
57
58###############################################################################
59# This tests the to make sure that no xtrabackup_history unless --history is
60# specified
61vlog "Testing no --history"
62innobackupex --stream=tar $backup_dir > /dev/null
63
64run_cmd_expect_failure get_one_value "uuid"
65
66
67###############################################################################
68# This tests the basic creation of a history record and that fields are
69# populated with some data. It also tests specifically that
70# partial, incremental, compact, compressed, encrypted and format are exactly
71# the correct values after the backup.
72# Missing is a test that binlog_pos is NULL, that would require restarting the
73# server without the log-bin option in the .cnf file but that has been tested
74# manually and doesn't seem to be something that would be required to be
75# validated.
76vlog "Testing basic history record"
77innobackupex --history=test1 --stream=tar $backup_dir > /dev/null
78
79for column in uuid name tool_name tool_command tool_version ibbackup_version \
80mysql_version start_time end_time lock_time binlog_pos innodb_from_lsn \
81innodb_to_lsn
82do
83 check_for_not_NULL "$column"
84done
85
86for column in partial incremental compact compressed encrypted
87do
88 check_for_value "$column" "N"
89done
90
91check_for_value "format" "tar"
92
93# saving for later
94get_one_value "innodb_to_lsn"
95first_to_lsn=$val
96
97
98###############################################################################
99# This tests the taking of an incremental backup based on the last record
100# of a history series and validates that the lsns in the record are correct.
101# It also tests that format, incremental and compact are exactly the correct
102# values after the backup.
103vlog "Testing incremental based on history name"
104
105multi_row_insert incremental_sample.test \({101..200},100\)
106
107innobackupex --history=test1 --incremental \
108--incremental-history-name=test1 --compact $backup_dir > /dev/null
109
110# saving for later
111get_one_value "uuid"
112second_uuid=$val
113get_one_value "innodb_from_lsn"
114second_from_lsn=$val
115get_one_value "innodb_to_lsn"
116second_to_lsn=$val
117
118check_for_value "format" "file"
119check_for_value "incremental" "Y"
120check_for_value "compact" "Y"
121
122if [ -z "$second_from_lsn" ] || [ "$second_from_lsn" != "$first_to_lsn" ]
123then
124 vlog "Second backup was not properly based on the to_lsn of the first"
125 exit 1
126fi
127
128multi_row_insert incremental_sample.test \({201..300},100\)
129
130# This will be a backup based on the last incremental just done, so, its
131# innodb_from_lsn (third_from_lsn) should be the same as the value in
132# second_to_lsn. This tests that we find the right record in the test1 series
133# out of the two records that should be present before the backup is done.
134innobackupex --history=test1 --incremental \
135--incremental-history-name=test1 $backup_dir > /dev/null
136
137# saving for later
138get_one_value "uuid"
139third_uuid=$val
140get_one_value "innodb_from_lsn"
141third_from_lsn=$val
142get_one_value "innodb_to_lsn"
143third_to_lsn=$val
144
145if [ -z "$third_from_lsn" ] || [ "$third_from_lsn" != "$second_to_lsn" ]
146then
147 vlog "Third backup was not properly based on the to_lsn of the second"
148 exit 1
149fi
150
151
152###############################################################################
153# This tests that we can base an incremental on a specific history record
154# identified by its uuid that we captured earlier from a history record or it
155# could be scraped from the output of innobackupex at some point in the past.
156# It also tests specifically that incremental, compressed, encrypted and format
157# are exactly the correct values after the backup.
158# It tests that --history can be specified, resulting in a history record with
159# no name
160vlog "Testing incremental based on history uuid"
161multi_row_insert incremental_sample.test \({301..400},100\)
162
163innobackupex --history --incremental --incremental-history-uuid=$third_uuid \
164--stream=xbstream --compress --encrypt=AES256 \
165--encrypt-key=percona_xtrabackup_is_awesome___ $backup_dir > /dev/null
166
167get_one_value "innodb_from_lsn"
168fourth_from_lsn=$val
169
170for column in incremental compressed encrypted
171do
172 check_for_value "$column" "Y"
173done
174
175check_for_value "format" "xbstream"
176check_for_value "name" "NULL"
177
178if [ -z "$fourth_from_lsn" ] || [ "$fourth_from_lsn" != "$third_to_lsn" ]
179then
180 vlog "Fourth backup was not properly based on the to_lsn of the third"
181 exit 1
182fi
183
184
185###############################################################################
186# This tests that innobackupex fails when an invalid --incremental-history-name
187# is given.
188vlog "Testing bad --incremental-history-name"
189run_cmd_expect_failure $IB_BIN $IB_ARGS --incremental \
190--incremental-history-name=foo --stream=tar $backup_dir > /dev/null
191
192
193
194###############################################################################
195# This tests that innobackupex fails when an invalid --incremental-history-uuid
196# is given.
197vlog "Testing bad --incremental-history-uuid"
198run_cmd_expect_failure $IB_BIN $IB_ARGS --incremental \
199--incremental-history-uuid=foo --stream=tar $backup_dir > /dev/null

Subscribers

People subscribed via source and target branches