From 43d86e64a4ce73d69c4d9c73f32ef5cff23d5344 Mon Sep 17 00:00:00 2001 From: David Steele Date: Tue, 7 Apr 2015 18:36:59 -0400 Subject: [PATCH] First pass at tests comparing rsync to backrest. Decent results, but room for improvement. All tests local over SSH with rsync default compression, 4 threads and default compression on backrest. Backrest default is gzip = 6, assuming rsync is the same. On a 1GB DB: rsync time = 32.82 backrest time = 19.48 backrest is 171% faster. On a 5GB DB: rsync time = 171.16 backrest time = 86.97 backrest is 196% faster. --- lib/BackRest/BackupFile.pm | 4 +- lib/BackRest/Config.pm | 11 ++- test/lib/BackRestTest/BackupTest.pm | 20 ++-- test/lib/BackRestTest/CommonTest.pm | 50 ++++++++-- test/lib/BackRestTest/CompareTest.pm | 139 +++++++++++++++++++++++++++ test/test.pl | 6 ++ 6 files changed, 208 insertions(+), 22 deletions(-) create mode 100755 test/lib/BackRestTest/CompareTest.pm diff --git a/lib/BackRest/BackupFile.pm b/lib/BackRest/BackupFile.pm index 79d0b15fc..6457ba3d1 100644 --- a/lib/BackRest/BackupFile.pm +++ b/lib/BackRest/BackupFile.pm @@ -115,10 +115,10 @@ sub backupFile # Output information about the file to be checksummed if (!defined($strLog)) { - $strLog = "checksum-only ${strLogProgress}"; + $strLog = "checksum-only"; } - &log(INFO, $strLog . " checksum ${strCopyChecksum}"); + &log(INFO, $strLog . " ${strLogProgress} checksum ${strCopyChecksum}"); } else { diff --git a/lib/BackRest/Config.pm b/lib/BackRest/Config.pm index ba1d9df91..eba513abe 100644 --- a/lib/BackRest/Config.pm +++ b/lib/BackRest/Config.pm @@ -194,8 +194,8 @@ push @EXPORT, qw(OPTION_CONFIG OPTION_DELTA OPTION_FORCE OPTION_NO_START_STOP OP #################################################################################################################################### use constant { - OPTION_DEFAULT_BUFFER_SIZE => 1048576, - OPTION_DEFAULT_BUFFER_SIZE_MIN => 4096, + OPTION_DEFAULT_BUFFER_SIZE => 4194304, + OPTION_DEFAULT_BUFFER_SIZE_MIN => 16384, OPTION_DEFAULT_BUFFER_SIZE_MAX => 8388608, OPTION_DEFAULT_COMPRESS => true, @@ -666,6 +666,7 @@ my %oOptionRule = &OPTION_BACKUP_ARCHIVE_CHECK => { + &OPTION_RULE_NEGATE => true, &OPTION_RULE_TYPE => OPTION_TYPE_BOOLEAN, &OPTION_RULE_DEFAULT => OPTION_DEFAULT_BACKUP_ARCHIVE_CHECK, &OPTION_RULE_SECTION => true, @@ -695,6 +696,7 @@ my %oOptionRule = &OPTION_COMPRESS => { + &OPTION_RULE_NEGATE => true, &OPTION_RULE_TYPE => OPTION_TYPE_BOOLEAN, &OPTION_RULE_DEFAULT => OPTION_DEFAULT_COMPRESS, &OPTION_RULE_SECTION => true, @@ -1137,6 +1139,11 @@ sub optionValid { confess &log(ERROR, "option '${strOption}' cannot be both set and negated", ERROR_OPTION_NEGATE); } + + if ($bNegate) + { + $strValue = false; + } } diff --git a/test/lib/BackRestTest/BackupTest.pm b/test/lib/BackRestTest/BackupTest.pm index 91df4f8fb..9a48e4670 100755 --- a/test/lib/BackRestTest/BackupTest.pm +++ b/test/lib/BackRestTest/BackupTest.pm @@ -30,7 +30,8 @@ use BackRest::Archive; use BackRestTest::CommonTest; use Exporter qw(import); -our @EXPORT = qw(BackRestTestBackup_Test); +our @EXPORT = qw(BackRestTestBackup_Test BackRestTestBackup_Create BackRestTestBackup_Drop BackRestTestBackup_ClusterStop + BackRestTestBackup_PgSelectOne BackRestTestBackup_PgExecute); my $strTestPath; my $strHost; @@ -276,6 +277,10 @@ sub BackRestTestBackup_ClusterStart } } } + else + { + $strCommand .= " -c archive_mode=on -c wal_level=archive -c archive_command=true"; + } $strCommand .= " -c unix_socket_director" . (BackRestTestCommon_DbVersion() < '9.3' ? "y='" : "ies='") . BackRestTestCommon_DbPathGet() . "'\" " . @@ -359,6 +364,7 @@ sub BackRestTestBackup_Create { my $bRemote = shift; my $bCluster = shift; + my $bArchive = shift; # Set defaults $bRemote = defined($bRemote) ? $bRemote : false; @@ -388,20 +394,12 @@ sub BackRestTestBackup_Create BackRestTestCommon_PathCreate(BackRestTestCommon_LocalPathGet()); } - # Create the backup directory - if ($bRemote) - { - BackRestTestCommon_Execute('mkdir -m 700 ' . BackRestTestCommon_RepoPathGet(), true); - } - else - { - BackRestTestCommon_PathCreate(BackRestTestCommon_RepoPathGet()); - } + BackRestTestCommon_CreateRepo(); # Create the cluster if ($bCluster) { - BackRestTestBackup_ClusterCreate(); + BackRestTestBackup_ClusterCreate(undef, undef, $bArchive); } } diff --git a/test/lib/BackRestTest/CommonTest.pm b/test/lib/BackRestTest/CommonTest.pm index c3a7f7e33..e233dd64b 100755 --- a/test/lib/BackRestTest/CommonTest.pm +++ b/test/lib/BackRestTest/CommonTest.pm @@ -39,7 +39,8 @@ our @EXPORT = qw(BackRestTestCommon_Create BackRestTestCommon_Drop BackRestTestC BackRestTestCommon_UserBackRestGet BackRestTestCommon_TestPathGet BackRestTestCommon_DataPathGet BackRestTestCommon_RepoPathGet BackRestTestCommon_LocalPathGet BackRestTestCommon_DbPathGet BackRestTestCommon_DbCommonPathGet BackRestTestCommon_ClusterStop BackRestTestCommon_DbTablespacePathGet - BackRestTestCommon_DbPortGet BackRestTestCommon_iniLoad BackRestTestCommon_iniSave BackRestTestCommon_DbVersion); + BackRestTestCommon_DbPortGet BackRestTestCommon_iniLoad BackRestTestCommon_iniSave BackRestTestCommon_DbVersion + BackRestTestCommon_CommandPsqlGet BackRestTestCommon_DropRepo BackRestTestCommon_CreateRepo); my $strPgSqlBin; my $strCommonStanza; @@ -91,6 +92,41 @@ sub BackRestTestCommon_ClusterStop } } +#################################################################################################################################### +# BackRestTestCommon_DropRepo +#################################################################################################################################### +sub BackRestTestCommon_DropRepo +{ + # Remove the backrest private directory + while (-e BackRestTestCommon_RepoPathGet()) + { + BackRestTestCommon_PathRemove(BackRestTestCommon_RepoPathGet(), true, true); + BackRestTestCommon_PathRemove(BackRestTestCommon_RepoPathGet(), false, true); + hsleep(.1); + } +} + + +#################################################################################################################################### +# BackRestTestCommon_CreateRepo +#################################################################################################################################### +sub BackRestTestCommon_CreateRepo +{ + my $bRemote = shift; + + BackRestTestCommon_DropRepo(); + + # Create the backup directory + if ($bRemote) + { + BackRestTestCommon_Execute('mkdir -m 700 ' . BackRestTestCommon_RepoPathGet(), true); + } + else + { + BackRestTestCommon_PathCreate(BackRestTestCommon_RepoPathGet()); + } +} + #################################################################################################################################### # BackRestTestCommon_Drop #################################################################################################################################### @@ -100,12 +136,7 @@ sub BackRestTestCommon_Drop BackRestTestCommon_ClusterStop(BackRestTestCommon_DbCommonPathGet(), true); # Remove the backrest private directory - while (-e BackRestTestCommon_RepoPathGet()) - { - BackRestTestCommon_PathRemove(BackRestTestCommon_RepoPathGet(), true, true); - BackRestTestCommon_PathRemove(BackRestTestCommon_RepoPathGet(), false, true); - hsleep(.1); - } + BackRestTestCommon_DropRepo(); # Remove the test directory BackRestTestCommon_PathRemove(BackRestTestCommon_TestPathGet()); @@ -787,6 +818,11 @@ sub BackRestTestCommon_StanzaGet return $strCommonStanza; } +sub BackRestTestCommon_CommandPsqlGet +{ + return $strCommonCommandPsql; +} + sub BackRestTestCommon_CommandMainGet { return $strCommonCommandMain; diff --git a/test/lib/BackRestTest/CompareTest.pm b/test/lib/BackRestTest/CompareTest.pm new file mode 100755 index 000000000..8f8fe9e68 --- /dev/null +++ b/test/lib/BackRestTest/CompareTest.pm @@ -0,0 +1,139 @@ +#!/usr/bin/perl +#################################################################################################################################### +# CompareTest.pl - Performance comparison tests between rsync and backrest +#################################################################################################################################### +package BackRestTest::CompareTest; + +#################################################################################################################################### +# Perl includes +#################################################################################################################################### +use strict; +use warnings FATAL => qw(all); +use Carp qw(confess); + +use File::Basename qw(dirname); +use Time::HiRes qw(gettimeofday); +use File::stat; +use Exporter qw(import); + +use lib dirname($0) . '/../lib'; +use BackRest::Utility; +use BackRestTest::CommonTest; +use BackRestTest::BackupTest; + +#################################################################################################################################### +# Exports +#################################################################################################################################### +our @EXPORT = qw(BackRestTestCompare_Test); + +#################################################################################################################################### +# BackRestTestCompare_BuildDb +#################################################################################################################################### +sub BackRestTestCompare_BuildDb +{ + my $iTableTotal = shift; + my $iTableSize = shift; + + my $iDbOid = BackRestTestBackup_PgSelectOne("select oid from pg_database where datname = 'postgres'"); + + for (my $iTableIdx = 0; $iTableIdx < $iTableTotal; $iTableIdx++) + { + my $strTableName = "test_${iTableIdx}"; + + BackRestTestBackup_PgExecute("create table ${strTableName} (id int)"); + my $iTableOid = BackRestTestBackup_PgSelectOne("select oid from pg_class where relname = '${strTableName}'"); + my $strTableFile = BackRestTestCommon_DbCommonPathGet() . "/base/${iDbOid}/${iTableOid}"; + + my $lSize; + + do + { + BackRestTestBackup_PgExecute("do \$\$ declare iIndex int; begin for iIndex in 1..289000 loop insert into ${strTableName} values (1); end loop; end \$\$;"); + BackRestTestBackup_PgExecute("checkpoint"); + my $oStat = stat($strTableFile); + + # Evaluate error + if (!defined($oStat)) + { + confess "cannot stat ${strTableFile}"; + } + + $lSize = $oStat->size; + } + while ($lSize < $iTableSize * 1024 * 1024); + } +} + +#################################################################################################################################### +# BackRestTestCompare_Test +#################################################################################################################################### +sub BackRestTestCompare_Test +{ + my $strTest = shift; + + #------------------------------------------------------------------------------------------------------------------------------- + # Test rsync + #------------------------------------------------------------------------------------------------------------------------------- + if ($strTest eq 'all' || $strTest eq 'rsync') + { + my $iRun = 0; + my $bRemote = false; + + &log(INFO, "Test rsync\n"); + + # Increment the run, log, and decide whether this unit test should be run + if (!BackRestTestCommon_Run(++$iRun, + "rmt ${bRemote}")) {next} + + # Create the cluster and paths + BackRestTestBackup_Create($bRemote, undef, false); + BackRestTestCompare_BuildDb(48, 10); + BackRestTestBackup_ClusterStop(); + + for (my $bRemote = true; $bRemote <= true; $bRemote++) + { + for (my $bRsync = true; $bRsync >= false; $bRsync--) + { + my $strCommand; + BackRestTestCommon_CreateRepo($bRemote); + + if ($bRsync) + { + $strCommand = 'rsync -zvlhprtogHS --delete ' . BackRestTestCommon_DbCommonPathGet() . '/ ' . + ($bRemote ? BackRestTestCommon_UserBackRestGet . '@' . BackRestTestCommon_HostGet . ':' : '') . + BackRestTestCommon_RepoPathGet(); + } + else + { + $strCommand = BackRestTestCommon_CommandMainGet() . + ' --stanza=main' . + # ' "--cmd-psql=' . BackRestTestCommon_CommandPsqlGet() . '"' . + # ' "--cmd-psql-option= -p ' . BackRestTestCommon_DbPortGet . '"' . + ($bRemote ? ' "--db-host=' . BackRestTestCommon_HostGet . '"' . + ' "--db-user=' . BackRestTestCommon_UserGet . '"' : '') . + ' --log-level-file=debug' . + ' --no-start-stop' . +# ' --no-compress' . + ' --thread-max=4' . + ' "--db-path=' . BackRestTestCommon_DbCommonPathGet() . '"' . + ' "--repo-path=' . BackRestTestCommon_RepoPathGet() . '"' . + ' --type=full backup'; + } + + my $fTimeBegin = gettimeofday(); + BackRestTestCommon_Execute($strCommand, !$bRsync && $bRemote); + my $fTimeEnd = gettimeofday(); + + &log(INFO, ($bRsync ? 'rsync' : 'backrest') . " time = " . (int(($fTimeEnd - $fTimeBegin) * 100) / 100)); + } + } + + if (BackRestTestCommon_Cleanup()) + { + &log(INFO, 'cleanup'); + BackRestTestBackup_Drop(true); + } + } +} + +1; diff --git a/test/test.pl b/test/test.pl index a9cb0cadc..08b542b3b 100755 --- a/test/test.pl +++ b/test/test.pl @@ -26,6 +26,7 @@ use BackRestTest::UtilityTest; use BackRestTest::ConfigTest; use BackRestTest::FileTest; use BackRestTest::BackupTest; +use BackRestTest::CompareTest; #################################################################################################################################### # Usage @@ -277,6 +278,11 @@ do } } } + + if ($strModule eq 'compare') + { + BackRestTestCompare_Test($strModuleTest); + } } while ($bInfinite);