Merge lp:~gl-az/percona-xtrabackup/BT23557-2.1-lp1160788 into lp:percona-xtrabackup/2.1

Proposed by George Ormond Lorch III
Status: Merged
Approved by: Alexey Kopytov
Approved revision: no longer in the source branch.
Merged at revision: 650
Proposed branch: lp:~gl-az/percona-xtrabackup/BT23557-2.1-lp1160788
Merge into: lp:percona-xtrabackup/2.1
Diff against target: 712 lines (+327/-78) (has conflicts)
12 files modified
innobackupex (+294/-38)
test/inc/ib_stream_common.sh (+9/-3)
test/inc/xb_local.sh (+7/-3)
test/t/ib_compress_basic.sh (+1/-2)
test/t/ib_stream_compress.sh (+1/-2)
test/t/ib_stream_compress_encrypt.sh (+1/-2)
test/t/xb_compress.sh (+1/-2)
test/t/xb_compress_encrypt.sh (+2/-9)
test/t/xb_encrypt.sh (+8/-0)
test/t/xb_parallel_compress.sh (+1/-2)
test/t/xb_parallel_compress_encrypt.sh (+1/-9)
test/t/xb_parallel_encrypt.sh (+1/-6)
Text conflict in innobackupex
Text conflict in test/t/xb_encrypt.sh
To merge this branch: bzr merge lp:~gl-az/percona-xtrabackup/BT23557-2.1-lp1160788
Reviewer Review Type Date Requested Status
Alexey Kopytov (community) Approve
Vlad Lesin g2 Pending
Review via email: mp+177057@code.launchpad.net

This proposal supersedes a proposal from 2013-07-12.

Description of the change

Added --decompress and --decrypt options both with functioning --parallel to innobackupex based on lp1160788. These options options will decrypt and/or decompress a backup made with the --compress and/or --encrypt options.

When decrypting, the encryption algorithm and key used when the backup was taken MUST be provided via the --decrypt=ALGORITHM and --encrypt-key=LITERAL-KEY or --encrypt-key-file=KEY-FILE.

For decompression to work, the qpress binary must be present within the path.

--decrypt and --decompress may be used together at the same time to completely normalize a previously compressed and encrypted backup but in some rare instances there may be io buffer overflow issues which would require calling innobackupex twice instead of a combined single call (once for decryption and once for decompression).

The --parallel option will allow multiple files to be decrypted and/or decompressed simultaneously.

Use of these options will remove the original compressed/encrypted files and leave the results in the same location.

test suite cases have been modified to make use of these new options where appropriate:
  test/t/ib_compress_basic.sh --decompress
  test/t/ib_stream_compress.sh --decompress
  test/t/ib_stream_compress_encrypt.sh --decompress
  test/t/xb_compress.sh --decompress
  test/t/xb_compress_encrypt.sh --decrypt --decompress in two individual invocations of innobackupex
  test/t/xb_encrypt.sh --decrypt
  test/t/xb_parallel_compress.sh --decompress --parallel
  test/t/xb_parallel_compress_encrypt.sh --decrypt --decompress --parallel in a single invocation of innobackupex
  test/t/xb_parallel_encrypt.sh --decrypt --parallel

-----
Rebased on trunk and fixed previous MP issue.

jenkins http://jenkins.percona.com/view/XtraBackup/job/percona-xtrabackup-2.1-param/376/
-----
Rebased on trunk again and fixed more review issues.

jenkins http://jenkins.percona.com/view/XtraBackup/job/percona-xtrabackup-2.1-param/403/

To post a comment you must log in.
Revision history for this message
George Ormond Lorch III (gl-az) wrote : Posted in a previous version of this proposal
Revision history for this message
George Ormond Lorch III (gl-az) wrote : Posted in a previous version of this proposal

Some metrics from HP Clout instance:

$ lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 2
On-line CPU(s) list: 0,1
Thread(s) per core: 1
Core(s) per socket: 1
CPU socket(s): 2
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 2
Stepping: 3
CPU MHz: 2666.760
BogoMIPS: 5333.52
Hypervisor vendor: KVM
Virtualization type: full
L1d cache: 32K
L1i cache: 32K
L2 cache: 4096K
NUMA node0 CPU(s): 0,1

Database was prepped with sysbench parallel-prepare, 16 tables and 5000000 rows for about ~20GB.

Backup was performed with --compress --encrypt=AES256

Serial, no parallel decrypt/decompress:
  $time innobackupex --decrypt=AES256 --encrypt-key=12345678123456781234567812345678 --decompress ./backup

  real 10m50.492s
  user 9m51.688s
  sys 0m53.628s

Parallel with 2 forks decrypt/decompress:
  $time innobackupex --decrypt=AES256 --encrypt-key=12345678123456781234567812345678 --decompress --parallel=2 ./backup

  real 5m38.778s
  user 9m50.381s
  sys 0m56.072s

Parallel with 4 forks decrypt/decompress:
  $time innobackupex --decrypt=AES256 --encrypt-key=12345678123456781234567812345678 --decompress --parallel=4 ./backup

  real 5m38.861s
  user 9m50.900s
  sys 0m56.473s

So we see a linear improvement here with CPU availability as long as i/o can keep up

Revision history for this message
George Ormond Lorch III (gl-az) wrote : Posted in a previous version of this proposal

Some metrics from some monster machine provided by Vadim:

$ lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 32
On-line CPU(s) list: 0-31
Thread(s) per core: 2
Core(s) per socket: 8
Socket(s): 2
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 45
Stepping: 7
CPU MHz: 2100.000
BogoMIPS: 4199.43
Virtualization: VT-x
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 20480K
NUMA node0 CPU(s): 0-31

Database was prepped with sysbench parallel-prepare, 32 tables and 2500000 rows for about ~20GB.

Backup was performed with --compress --encrypt=AES256

Serial, no parallel decrypt/decompress:
  $time innobackupex --decrypt=AES256 --encrypt-key=12345678123456781234567812345678 --decompress ./backup

  real 7m57.206s
  user 8m14.755s
  sys 0m33.522s

Parallel with 16 forks decrypt/decompress:
  $time innobackupex --decrypt=AES256 --encrypt-key=12345678123456781234567812345678 --decompress --parallel=16 ./backup

  real 2m30.460s
  user 9m50.874s
  sys 11m32.019s

Parallel with 24 forks decrypt/decompress:
  $time innobackupex --decrypt=AES256 --encrypt-key=12345678123456781234567812345678 --decompress --parallel=24 ./backup

  real 2m1.898s
  user 9m58.801s
  sys 14m12.701s

Parallel with 32 forks decrypt/decompress:
  $time innobackupex --decrypt=AES256 --encrypt-key=12345678123456781234567812345678 --decompress --parallel=32 ./backup

  real 2m4.559s
  user 10m20.132s
  sys 21m29.176s

Again, we see a nice improvement up to the point we hit i/o limits...

Revision history for this message
Stewart Smith (stewart) wrote : Posted in a previous version of this proposal

George Ormond Lorch III <email address hidden> writes:
> Some metrics from some monster machine provided by Vadim:

Blog post coming in 5..4..3..2..1 ? :)

--
Stewart Smith

Revision history for this message
Vlad Lesin (vlad-lesin) wrote : Posted in a previous version of this proposal

Looks good. Two minor remarks:

1) I think there should be test which uses --decrypt and --decompress options in one innobackupex call.

2) Lines 498-500: Why there is "DECRYPT AND DECOMPRESS" log output if only decompression is used?

review: Needs Fixing (g2)
Revision history for this message
Raghavendra D Prabhu (raghavendra-prabhu) wrote : Posted in a previous version of this proposal

Parallel decompression/decryption are nice. However, are there plans to
add this for streaming? From the tests I see, the decompress/decrypt
are being run on non-streamed backups and since it looks for files with
extensions (qp/xbcrypt), it is not possible to use this on streaming
backups (or earlier streamed backups in case of --encrypt since
decryption needs to be done before xbstream extraction there)

Revision history for this message
George Ormond Lorch III (gl-az) wrote : Posted in a previous version of this proposal

No because qpress is not stored in a streaming compatible format.
xbcrypt can be handled via stream but not qp.
On 7/12/2013 2:09 AM, Raghavendra D Prabhu wrote:
> Parallel decompression/decryption are nice. However, are there plans to
> add this for streaming? From the tests I see, the decompress/decrypt
> are being run on non-streamed backups and since it looks for files with
> extensions (qp/xbcrypt), it is not possible to use this on streaming
> backups (or earlier streamed backups in case of --encrypt since
> decryption needs to be done before xbstream extraction there)
>

--
George O. Lorch III
Software Engineer, Percona
+1-888-401-3401 x542 US/Arizona (GMT -7)
skype: george.ormond.lorch.iii

Revision history for this message
George Ormond Lorch III (gl-az) wrote : Posted in a previous version of this proposal

I shouldn't respond until I have had my full coffee...

There are really two problems in doing this right now. One is that
inobackupex --compress only passes the --compress option(s) down into
xtrabackup where only InnoDB files get compressed, all other files
currently go into the archive uncompressed so doing something like
"... xbcrypt -d ... | xbstream -x | qpress -di ..." can't work in a
pure stream since not all files in the stream are .qp. The other is that
qpress does not store the filename/directory structure within the .qp
and as such can't recreate the same output structure as say xbcrypt and
xbstream can, it basically just a block compress/decompresser.

Maybe one day when all of the decryption | decompression | destreaming
is included in a single executable that is aware of the full structure
and format it would be possible. Alexey might have some ideas on an easy
way to pull this off within innobackupex using some of his mad linux skills.

On 7/12/2013 7:37 AM, George Ormond Lorch III wrote:
> No because qpress is not stored in a streaming compatible format.
> xbcrypt can be handled via stream but not qp.
> On 7/12/2013 2:09 AM, Raghavendra D Prabhu wrote:
>> Parallel decompression/decryption are nice. However, are there plans to
>> add this for streaming? From the tests I see, the decompress/decrypt
>> are being run on non-streamed backups and since it looks for files with
>> extensions (qp/xbcrypt), it is not possible to use this on streaming
>> backups (or earlier streamed backups in case of --encrypt since
>> decryption needs to be done before xbstream extraction there)
>>
>

--
George O. Lorch III
Software Engineer, Percona
+1-888-401-3401 x542 US/Arizona (GMT -7)
skype: george.ormond.lorch.iii

Revision history for this message
Vlad Lesin (vlad-lesin) wrote : Posted in a previous version of this proposal

1) Misprint in 477: "oarallel" instead of "parallel";

2) "DECRYPTING AND/OR DECOMPRESSING" in 524;

3) I have not found checking $option_parallel on positive value.

'parallel=i' => \$option_parallel,

It is supposed $option_parallel is integer. In the case if $option_parallel is less then 0 decrypt_decompress() will not work correctly. It seems there will be infinite loop in:

while ($freepidindex >= $option_parallel)

It should be checked somewhere.

review: Needs Fixing (g2)
Revision history for this message
Alexey Kopytov (akopytov) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'innobackupex'
2--- innobackupex 2013-07-08 09:28:05 +0000
3+++ innobackupex 2013-07-25 22:07:27 +0000
4@@ -89,15 +89,16 @@
5 my $option_throttle = '';
6 my $option_sleep = '';
7 my $option_compress = 999;
8+my $option_decompress = '';
9 my $option_compress_threads = 1;
10 my $option_compress_chunk_size = '';
11 my $option_encrypt = '';
12+my $option_decrypt = '';
13 my $option_encrypt_key = '';
14 my $option_encrypt_key_file = '';
15 my $encrypt_cmd = '';
16 my $option_encrypt_threads = 1;
17 my $option_encrypt_chunk_size = '';
18-my $option_uncompress = '';
19 my $option_export = '';
20 my $option_use_memory = '';
21 my $option_mysql_password = '';
22@@ -315,7 +316,27 @@
23
24 my $ibbackup_exit_code = 0;
25
26-if ($option_copy_back) {
27+if ($option_decompress || $option_decrypt) {
28+ # decrypt/decompress files
29+ if ($option_decompress && $option_decrypt) {
30+ # Call mode 0 first as it is fastest but may cause stream buffer overruns
31+ # requiring user invoke innobackupex twice, once for decrypt and again
32+ # for decompress. Mode 0 will take .qb.xbcrypt and run it through
33+ # xbcrypt | qpress > result. This should get all InnoDB files but any
34+ # metadata or MyISAM, etc. will not be .qp.xbcrypt, only .xbcrypt
35+ decrypt_decompress(0);
36+ # Now call mode 1 to decrypt any uncompressed files, those with only a
37+ # .xbcrypt extension
38+ decrypt_decompress(1);
39+ # Now, just in case there were any compressed files only, run throuh and
40+ # decompress any .qp files
41+ decrypt_decompress(2);
42+ } elsif ($option_decompress) {
43+ decrypt_decompress(2);
44+ } else {
45+ decrypt_decompress(1);
46+ }
47+} elsif ($option_copy_back) {
48 # copy files from backup directory back to their original locations
49 copy_back(0);
50 } elsif ($option_move_back) {
51@@ -409,7 +430,180 @@
52 die "$prefix Error: $message";
53 }
54
55-
56+#
57+# Finds all files that match the given pattern recursively beneath
58+# the given directory. Returns a list of files with their paths relative
59+# to the starting search directory.
60+#
61+sub find_all_matching_files {
62+ my $dir = shift;
63+ my $pattern = shift;
64+ my $child;
65+ my @dirlist;
66+ my @retlist;
67+
68+ opendir(FINDDIR, $dir)
69+ || Die "Can't open directory '$dir': $!\n";
70+
71+ while (defined($child = readdir(FINDDIR))) {
72+ next if $child eq "." || $child eq "..";
73+ if ($child =~ m/$pattern/) { push(@retlist, "$dir/$child"); }
74+ elsif ( -d "$dir/$child") { push(@dirlist, "$dir/$child"); }
75+ }
76+ closedir(FINDDIR);
77+
78+ foreach $child (@dirlist) {
79+ push(@retlist, find_all_matching_files("$child", "$pattern"));
80+ }
81+ return (@retlist);
82+}
83+
84+#
85+# decrypts and/or decompresses an individual file amd removes the source
86+# on success.
87+# mode is same mode as defined for sub decrypt_decompress()
88+sub decrypt_decompress_file {
89+ my $mode = shift;
90+ my $file = shift;
91+ my $file_ext = shift;
92+ my $decrypt_opts = shift;
93+
94+ my $file_cmd;
95+ my $dest_file=substr($file, 0, length($file) - length($file_ext));
96+
97+ if ($mode == 0) {
98+ $file_cmd = "xbcrypt --decrypt $decrypt_opts --input=" . $file . " | qpress -dio > " . $dest_file;
99+ } elsif ($mode == 1) {
100+ $file_cmd = "xbcrypt --decrypt $decrypt_opts --input=" . $file . " --output=" . $dest_file;
101+ } elsif ($mode == 2) {
102+ $file_cmd = "qpress -do " . $file . " > " . $dest_file;
103+ } else {
104+ Die("Unknown decrypt_decompress mode : $mode\n");
105+ }
106+ print STDERR "$prefix $file_cmd\n";
107+ system("$file_cmd") && Die "$file_cmd failed with $!\n";
108+ system("rm -f $file");
109+}
110+
111+#
112+# Decrypts and decompresses a backup made with --compress and/or --encrypt
113+#
114+# mode 0 = decrypt and decompress .qp.xbcrypt files
115+# mode 1 = decrypt .xbcrypt files
116+# mode 2 = decompress .qp files
117+#
118+sub decrypt_decompress {
119+ my $mode = shift;
120+ my $file_ext;
121+ my $decrypt_opts = '';
122+ my @files;
123+
124+ # first, build out the decryption opts. They will not be used and option
125+ # values may not be specified if doing decompress only.
126+ if ($mode != 2) {
127+ if ($option_decrypt) {
128+ $decrypt_opts = "--encrypt-algo=$option_decrypt"
129+ }
130+ if ($option_encrypt_key) {
131+ $decrypt_opts = $decrypt_opts . " --encrypt-key=$option_encrypt_key";
132+ } elsif ($option_encrypt_key_file) {
133+ $decrypt_opts = $decrypt_opts . " --encrypt-key-file=$option_encrypt_key_file";
134+ }
135+ }
136+
137+ # based on the mode, determine which files we are interested in
138+ if ($mode == 0) {
139+ $file_ext = ".qp.xbcrypt";
140+ } elsif ($mode == 1) {
141+ $file_ext = ".xbcrypt";
142+ } elsif ($mode == 2) {
143+ $file_ext = ".qp";
144+ } else {
145+ Die("Unknown decrypt_decompress mode : $mode\n");
146+ }
147+
148+ # recursively find all files of interest in the backup set
149+ @files = find_all_matching_files("$backup_dir", "\\$file_ext\$");
150+
151+ # runing serially
152+ if (!$option_parallel) {
153+ my $file;
154+ foreach $file (@files) {
155+ decrypt_decompress_file($mode, $file, $file_ext, $decrypt_opts);
156+ }
157+ # running parallel, FUN!
158+ } else {
159+ my @pids;
160+ my @workingfiles;
161+ my $file;
162+ my $freepidindex;
163+
164+ # this will maintain the list of forks so we can wait for completion
165+ # and check return status as well as stay within the limits of the
166+ # --parallel value
167+ $pids[$option_parallel - 1] = undef;
168+
169+ # this is the file for which each fork is currently working on. just
170+ # used for logging/reporting purposed in case of a failure.
171+ $workingfiles[$option_parallel - 1] = undef;
172+
173+ foreach $file (@files) {
174+ # this while loop below tries to find an unused child/fork slot, ie, one
175+ # that is not currently working/running. it will loop indefinitely,
176+ # iterating the number of slots and watching for a child to finish
177+ # and use that now vacant slot.
178+ $freepidindex=$option_parallel;
179+ while ($freepidindex >= $option_parallel) {
180+ for ($freepidindex = 0; $freepidindex < $option_parallel; $freepidindex++) {
181+ last if not defined $pids[$freepidindex];
182+
183+ my $status = waitpid($pids[$freepidindex], WNOHANG);
184+ if ($status == $pids[$freepidindex]) {
185+ my $childretcode = $? >> 8;
186+ if ($childretcode != 0) {
187+ Die("Child failed on $workingfiles[$freepidindex] : $childretcode");
188+ }
189+ last;
190+ } elsif ($status == -1) {
191+ Die("waitpid failed on $workingfiles[$freepidindex] : $status");
192+ }
193+ }
194+ # couldn't find a free slot yet so sleep for 1/10 th of a second or so.
195+ # sleeping for a much longer (even a second) can make the whole process
196+ # take longer when there are a lot of smaller files to process as they
197+ # can be done very quickly. 1/10th doesn't seem to add any real overhead
198+ # to this controlling process when compared to letting it spin freely.
199+ if ($freepidindex >= $option_parallel) {
200+ usleep(100000);
201+ }
202+ }
203+ # so now we have a slot identified by freepidindex, set up the workingfiles,
204+ # fork and do the work.
205+ $workingfiles[$freepidindex] = $file;
206+ $pids[$freepidindex] = fork();
207+ if ($pids[$freepidindex] == 0) {
208+ decrypt_decompress_file($mode, $file, $file_ext, $decrypt_opts);
209+ exit 0;
210+ }
211+ }
212+ # we've started processing of all files that we know about, now just need
213+ # to wait for the last bunch to finish up and check for any errors before
214+ # returning.
215+ for ($freepidindex = 0; $freepidindex < $option_parallel; $freepidindex++) {
216+ next if not defined $pids[$freepidindex];
217+ my $status = waitpid($pids[$freepidindex], 0);
218+ my $childretcode = $? >> 8;
219+ if ($status == $pids[$freepidindex]) {
220+ if ($childretcode != 0) {
221+ Die("Child failed on $workingfiles[$freepidindex] : $childretcode");
222+ }
223+ } else {
224+ Die("waitpid failed on $workingfiles[$freepidindex] : $status");
225+ }
226+ }
227+ }
228+}
229+
230 #
231 # backup subroutine makes a backup of InnoDB and MyISAM tables, indexes and
232 # .frm files. It connects to the database server and runs ibbackup as a child
233@@ -896,8 +1090,25 @@
234 Die "Backup data file '$backup_dir/$c->{filename}' "
235 . "does not exist, but "
236 . "its compressed copy '$c->{path}.ibz' exists. Check "
237- . "that you have run "
238- . "'$innobackup_script --apply-log --uncompress "
239+ . "that you have decompressed "
240+ . " before attempting "
241+ . "'$innobackup_script --copy-back ...' "
242+ . "or '$innobackup_script --move-back ...' !";
243+ } elsif (-e "$backup_dir/$c->{filename}.qp") {
244+ Die "Backup data file '$backup_dir/$c->{filename}' "
245+ . "does not exist, but "
246+ . "its compressed copy '$c->{path}.qp' exists. Check "
247+ . "that you have run "
248+ . "'$innobackup_script --decompress "
249+ . "...' before attempting "
250+ . "'$innobackup_script --copy-back ...' "
251+ . "or '$innobackup_script --move-back ...' !";
252+ } elsif (-e "$backup_dir/$c->{filename}.xbcrypt") {
253+ Die "Backup data file '$backup_dir/$c->{filename}' "
254+ . "does not exist, but "
255+ . "its compressed copy '$c->{path}.xbcrypt' exists. Check "
256+ . "that you have run "
257+ . "'$innobackup_script --decrypt "
258 . "...' before attempting "
259 . "'$innobackup_script --copy-back ...' "
260 . "or '$innobackup_script --move-back ...' !";
261@@ -990,9 +1201,6 @@
262
263 $options = $options . "--prepare --target-dir=$backup_dir";
264
265- if ($option_uncompress) {
266- $options = $options . ' --uncompress';
267- }
268 if ($option_export) {
269 $options = $options . ' --export';
270 }
271@@ -1994,8 +2202,11 @@
272 my $run = '';
273
274 # print some instructions to the user
275- if (!$option_apply_log && !$option_copy_back && !$option_move_back) {
276+ if (!$option_apply_log && !$option_copy_back && !$option_move_back
277+ && !$option_decrypt && !$option_decompress) {
278 $run = 'backup';
279+ } elsif ($option_decrypt || $option_decompress) {
280+ $run = 'decryption and decompression';
281 } elsif ($option_copy_back) {
282 $run = 'copy-back';
283 } elsif ($option_move_back) {
284@@ -2007,7 +2218,8 @@
285 print STDERR " At the end of a successful $run run $innobackup_script\n";
286 print STDERR " prints \"completed OK!\".\n\n";
287
288- if (!$option_copy_back && !$option_move_back) {
289+ if (!$option_copy_back && !$option_move_back
290+ && !$option_decrypt && !$option_decompress) {
291 # we are making a backup or applying log to backup
292 if (!$option_apply_log) {
293 # we are making a backup, we need mysql server
294@@ -2030,19 +2242,22 @@
295 }
296 }
297
298- # read MySQL options file
299- #read_config_file($config_file, \%config);
300- read_config_file(\%config);
301+ if (!$option_decrypt && !$option_decompress) {
302+ # read MySQL options file
303+ #read_config_file($config_file, \%config);
304+ read_config_file(\%config);
305
306- if(!$option_tmpdir) {
307- $option_tmpdir = get_option(\%config, $option_defaults_group, 'tmpdir');
308+ if(!$option_tmpdir) {
309+ $option_tmpdir = get_option(\%config, $option_defaults_group, 'tmpdir');
310+ }
311 }
312
313 # get innodb log home directory from options file
314 #$innodb_log_group_home_dir =
315 # get_option(\%config, 'mysqld', 'innodb_log_group_home_dir');
316
317- if (!$option_apply_log && !$option_copy_back && !$option_move_back) {
318+ if (!$option_apply_log && !$option_copy_back && !$option_move_back
319+ && !$option_decrypt && !$option_decompress) {
320 # we are making a backup, create a new backup directory
321 $backup_dir = File::Spec->rel2abs(make_backup_dir());
322 print STDERR "$prefix Created backup directory $backup_dir\n";
323@@ -2167,9 +2382,11 @@
324
325 # read command line options
326 $rcode = GetOptions('compress' => \$option_compress,
327+ 'decompress' => \$option_decompress,
328 'compress-threads=i' => \$option_compress_threads,
329 'compress-chunk-size=s' => \$option_compress_chunk_size,
330 'encrypt=s' => \$option_encrypt,
331+ 'decrypt=s' => \$option_decrypt,
332 'encrypt-key=s' => \$option_encrypt_key,
333 'encrypt-key-file=s' => \$option_encrypt_key_file,
334 'encrypt-threads=i' => \$option_encrypt_threads,
335@@ -2187,7 +2404,6 @@
336 'databases=s' => \$option_databases,
337 'tables-file=s', => \$option_tables_file,
338 'use-memory=s' => \$option_use_memory,
339- 'uncompress' => \$option_uncompress,
340 'export' => \$option_export,
341 'password:s' => \$option_mysql_password,
342 'user=s' => \$option_mysql_user,
343@@ -2266,6 +2482,7 @@
344 $option_compress = 0;
345 }
346
347+<<<<<<< TREE
348 # validate lock-wait-query-type and kill-long-query-type values
349 if (!(grep {$_ eq $option_lock_wait_query_type} qw/all update/)) {
350 Die "Wrong value of lock-wait-query-type. ".
351@@ -2278,6 +2495,14 @@
352 "is specified.";
353 }
354
355+=======
356+ if ($option_parallel && $option_parallel < 1) {
357+ print STDERR "$prefix --parallel must be a positive numerical value" .
358+ "greater than 0";
359+ exit(1);
360+ }
361+
362+>>>>>>> MERGE-SOURCE
363 if ($option_stream eq 'tar') {
364 $stream_cmd = 'tar chf -';
365 } elsif ($option_stream eq 'xbstream') {
366@@ -2304,7 +2529,8 @@
367 exit(1);
368 }
369
370- if (!$option_apply_log && !$option_copy_back && !$option_move_back) {
371+ if (!$option_apply_log && !$option_copy_back && !$option_move_back
372+ && !$option_decrypt && !$option_decompress) {
373 # we are making a backup, get backup root directory
374 $option_backup = "1";
375 $backup_root = $ARGV[0];
376@@ -2335,6 +2561,13 @@
377 exit(1);
378 }
379
380+ if ($option_decompress) {
381+ if (system("which qpress &>/dev/null") >> 8 != 0) {
382+ print STDERR "--decompress requires qpress\n";
383+ exit(1);
384+ }
385+ }
386+
387 print STDERR "\n";
388
389 parse_databases_option_value();
390@@ -3197,8 +3430,8 @@
391 =head1 SYNOPOSIS
392
393 innobackupex [--compress] [--compress-threads=NUMBER-OF-THREADS] [--compress-chunk-size=CHUNK-SIZE]
394- [--encrypt=encryption_algorithm] [--encrypt-threads=NUMBER-OF-THREADS] [--encrypt-chunk-size=CHUNK-SIZE]
395- [--encrypt-key=literal_encryption_key] | [--encryption-key-file=MY.KEY]
396+ [--encrypt=ENCRYPTION-ALGORITHM] [--encrypt-threads=NUMBER-OF-THREADS] [--encrypt-chunk-size=CHUNK-SIZE]
397+ [--encrypt-key=LITERAL-ENCRYPTION-KEY] | [--encryption-key-file=MY.KEY]
398 [--include=REGEXP] [--user=NAME]
399 [--password=WORD] [--port=PORT] [--socket=SOCKET]
400 [--no-timestamp] [--ibbackup=IBBACKUP-BINARY]
401@@ -3211,7 +3444,7 @@
402 [--compact]
403 BACKUP-ROOT-DIR
404
405-innobackupex --apply-log [--use-memory=B] [--uncompress]
406+innobackupex --apply-log [--use-memory=B]
407 [--defaults-file=MY.CNF]
408 [--export] [--redo-only] [--ibbackup=IBBACKUP-BINARY]
409 BACKUP-DIR
410@@ -3220,6 +3453,10 @@
411
412 innobackupex --move-back [--defaults-file=MY.CNF] [--defaults-group=GROUP-NAME] BACKUP-DIR
413
414+innobackupex [--decompress] [--decrypt=ENCRYPTION-ALGORITHM]
415+ [--encrypt-key=LITERAL-ENCRYPTION-KEY] | [--encryption-key-file=MY.KEY]
416+ [--parallel=NUMBER-OF-FORKS] BACKUP-DIR
417+
418 =head1 DESCRIPTION
419
420 The first command line above makes a hot backup of a MySQL database.
421@@ -3254,6 +3491,16 @@
422 option removes backup files, it must be used with caution. It may be useful in
423 cases when there is not enough free disk space to copy files.
424
425+The --decompress --decrypt command will decrypt and/or decompress a backup made
426+with the --compress and/or --encrypt options. When decrypting, the encryption
427+algorithm and key used when the backup was taken MUST be provided via the
428+specified options. --decrypt and --decompress may be used together at the same
429+time to completely normalize a previously compressed and encrypted backup. The
430+--parallel option will allow multiple files to be decrypted and/or decompressed
431+simultaneously. In order to decompress, the qpress utility MUST be installed
432+and accessable within the path. This process will remove the original
433+compressed/encrypted files and leave the results in the same location.
434+
435 On success the exit code innobackupex is 0. A non-zero exit code
436 indicates an error.
437
438@@ -3296,6 +3543,14 @@
439
440 This option specifies the list of databases that innobackupex should back up. The option accepts a string argument or path to file that contains the list of databases to back up. The list is of the form "databasename1[.table_name1] databasename2[.table_name2] . . .". If this option is not specified, all databases containing MyISAM and InnoDB tables will be backed up. Please make sure that --databases contains all of the InnoDB databases and tables, so that all of the innodb.frm files are also backed up. In case the list is very long, this can be specified in a file, and the full path of the file can be specified instead of the list. (See option --tables-file.)
441
442+=item --decompress
443+
444+Decompresses all files with the .qp extension in a backup previously made with the --compress option.
445+
446+=item --decrypt=ENCRYPTION-ALGORITHM
447+
448+Decrypts all files with the .xbcrypt extension in a backup previously made with --encrypt option.
449+
450 =item --debug-sleep-before-unlock=SECONDS
451
452 This is a debug-only option used by the XtraBackup test suite.
453@@ -3308,23 +3563,23 @@
454
455 This option specifies what extra file to read the default MySQL options from before the standard defaults-file. The option accepts a string argument. It is also passed directly to xtrabackup's --defaults-extra-file option. See the xtrabackup documentation for details.
456
457-=item --encrypt=ENCRYPTION_ALGORITHM
458+=item --encrypt=ENCRYPTION-ALGORITHM
459
460 This option instructs xtrabackup to encrypt backup copies of InnoDB data
461-files using the algorithm specified in the ENCRYPTION_ALGORITHM.
462-It is passed directly to the xtrabackup child process.
463-Try 'xtrabackup --help' for more details.
464-
465-=item --encrypt-key=ENCRYPTION_KEY
466-
467-This option instructs xtrabackup to use the given ENCRYPTION_KEY when using the --encrypt option.
468-It is passed directly to the xtrabackup child process.
469-Try 'xtrabackup --help' for more details.
470-
471-=item --encrypt-key-file=ENCRYPTION_KEY_FILE
472-
473-This option instructs xtrabackup to use the encryption key stored in the given ENCRYPTION_KEY_FILE when using the --encrypt option.
474-It is passed directly to the xtrabackup child process.
475+files using the algorithm specified in the ENCRYPTION-ALGORITHM.
476+It is passed directly to the xtrabackup child process.
477+Try 'xtrabackup --help' for more details.
478+
479+=item --encrypt-key=ENCRYPTION-KEY
480+
481+This option instructs xtrabackup to use the given ENCRYPTION-KEY when using the --encrypt or --decrypt options.
482+During backup it is passed directly to the xtrabackup child process.
483+Try 'xtrabackup --help' for more details.
484+
485+=item --encrypt-key-file=ENCRYPTION-KEY-FILE
486+
487+This option instructs xtrabackup to use the encryption key stored in the given ENCRYPTION-KEY-FILE when using the --encrypt or --decrypt options.
488+
489 Try 'xtrabackup --help' for more details.
490
491 =item --encrypt-threads
492@@ -3426,8 +3681,9 @@
493
494 =item --parallel=NUMBER-OF-THREADS
495
496-This option specifies the number of threads the xtrabackup child process should use to back up files concurrently. The option accepts an integer argument. It is passed directly to xtrabackup's --parallel option. See the xtrabackup documentation for details.
497-
498+On backup, this option specifies the number of threads the xtrabackup child process should use to back up files concurrently. The option accepts an integer argument. It is passed directly to xtrabackup's --parallel option. See the xtrabackup documentation for details.
499+
500+On --decrypt or --decompress it specifies the number of parallel forks that should be used to process the backup files.
501
502 =item --password=WORD
503
504
505=== modified file 'test/inc/ib_stream_common.sh'
506--- test/inc/ib_stream_common.sh 2012-10-15 16:18:40 +0000
507+++ test/inc/ib_stream_common.sh 2013-07-25 22:07:27 +0000
508@@ -29,17 +29,23 @@
509 rm -r $mysql_datadir
510
511 # Restore sakila
512-vlog "Applying log"
513+vlog "#####################"
514+vlog "# EXTRACTING STREAM #"
515+vlog "#####################"
516 backup_dir=$topdir/backup
517 cd $backup_dir
518 run_cmd bash -c "$stream_extract_cmd out"
519-test -n "${stream_uncompress_cmd:-""}" && run_cmd bash -c "$stream_uncompress_cmd";
520+if [ -n "${stream_uncompress_cmd:=""}" ]; then
521+ vlog "################################"
522+ vlog "# DECRYPTING AND DECOMPRESSING #"
523+ vlog "################################"
524+ run_cmd bash -c "$stream_uncompress_cmd";
525+fi
526 cd - >/dev/null 2>&1
527 vlog "###########"
528 vlog "# PREPARE #"
529 vlog "###########"
530 innobackupex --apply-log $backup_dir
531-vlog "Restoring MySQL datadir"
532 mkdir -p $mysql_datadir
533 vlog "###########"
534 vlog "# RESTORE #"
535
536=== modified file 'test/inc/xb_local.sh'
537--- test/inc/xb_local.sh 2013-03-11 19:11:29 +0000
538+++ test/inc/xb_local.sh 2013-07-25 22:07:27 +0000
539@@ -31,14 +31,18 @@
540 # Restore sakila
541 vlog "Applying log"
542 cd $backup_dir
543-test -n "${data_decrypt_cmd:=""}" && run_cmd bash -c "$data_decrypt_cmd"
544-test -n "${data_decompress_cmd:-""}" && run_cmd bash -c "$data_decompress_cmd";
545+if [ -n "${data_decrypt_cmd:=""}" ] || [ -n "${data_decompress_cmd:=""}" ]; then
546+ vlog "###################################"
547+ vlog "# DECRYPTING AND/OR DECOMPRESSING #"
548+ vlog "###################################"
549+ test -n "${data_decrypt_cmd:=""}" && run_cmd bash -c "$data_decrypt_cmd"
550+ test -n "${data_decompress_cmd:-""}" && run_cmd bash -c "$data_decompress_cmd";
551+fi
552 cd - >/dev/null 2>&1
553 vlog "###########"
554 vlog "# PREPARE #"
555 vlog "###########"
556 innobackupex --apply-log $backup_dir
557-vlog "Restoring MySQL datadir"
558 mkdir -p $mysql_datadir
559 vlog "###########"
560 vlog "# RESTORE #"
561
562=== modified file 'test/t/ib_compress_basic.sh'
563--- test/t/ib_compress_basic.sh 2013-01-07 06:17:40 +0000
564+++ test/t/ib_compress_basic.sh 2013-07-25 22:07:27 +0000
565@@ -19,8 +19,7 @@
566
567 cd $topdir/backup
568
569-for i in *.qp; do qpress -d $i ./; done; \
570-for i in sakila/*.qp; do qpress -d $i sakila/; done
571+innobackupex --decompress $topdir/backup
572
573 innobackupex --apply-log $topdir/backup
574
575
576=== modified file 'test/t/ib_stream_compress.sh'
577--- test/t/ib_stream_compress.sh 2013-03-11 19:11:29 +0000
578+++ test/t/ib_stream_compress.sh 2013-07-25 22:07:27 +0000
579@@ -9,8 +9,7 @@
580
581 stream_format=xbstream
582 stream_extract_cmd="xbstream -xv <"
583-stream_uncompress_cmd="for i in *.qp; do qpress -d \$i ./; done; \
584-for i in sakila/*.qp; do qpress -d \$i sakila/; done"
585+stream_uncompress_cmd="innobackupex --decompress ./"
586 innobackupex_options="--compress --compress-threads=4 --compress-chunk-size=8K"
587
588 . inc/ib_stream_common.sh
589
590=== modified file 'test/t/ib_stream_compress_encrypt.sh'
591--- test/t/ib_stream_compress_encrypt.sh 2013-03-11 19:11:29 +0000
592+++ test/t/ib_stream_compress_encrypt.sh 2013-07-25 22:07:27 +0000
593@@ -11,8 +11,7 @@
594 encrypt_key="percona_xtrabackup_is_awesome___"
595 stream_format=xbstream
596 stream_extract_cmd="(xbcrypt -d -a $encrypt_algo -k $encrypt_key | xbstream -xv) <"
597-stream_uncompress_cmd="for i in *.qp; do qpress -d \$i ./; done; \
598-for i in sakila/*.qp; do qpress -d \$i sakila/; done"
599+stream_uncompress_cmd="innobackupex --decompress ./"
600 innobackupex_options="--compress --compress-threads=4 --compress-chunk-size=8K --encrypt=$encrypt_algo --encrypt-key=$encrypt_key --encrypt-threads=4 --encrypt-chunk-size=8K"
601
602 . inc/ib_stream_common.sh
603
604=== modified file 'test/t/xb_compress.sh'
605--- test/t/xb_compress.sh 2013-03-11 19:11:29 +0000
606+++ test/t/xb_compress.sh 2013-07-25 22:07:27 +0000
607@@ -8,7 +8,6 @@
608 fi
609
610 innobackupex_options="--compress --compress-threads=4 --compress-chunk-size=8K"
611-data_decompress_cmd="for i in *.qp; do qpress -d \$i ./; done; \
612-for i in sakila/*.qp; do qpress -d \$i sakila/; done"
613+data_decompress_cmd="innobackupex --decompress ./"
614
615 . inc/xb_local.sh
616
617=== modified file 'test/t/xb_compress_encrypt.sh'
618--- test/t/xb_compress_encrypt.sh 2013-03-11 19:11:29 +0000
619+++ test/t/xb_compress_encrypt.sh 2013-07-25 22:07:27 +0000
620@@ -13,14 +13,7 @@
621
622 innobackupex_options="--compress --compress-threads=4 --compress-chunk-size=8K --encrypt=$encrypt_algo --encrypt-key=$encrypt_key --encrypt-threads=4 --encrypt-chunk-size=8K"
623
624-data_decrypt_cmd="for i in *.xbcrypt; do \
625-xbcrypt -d -a $encrypt_algo -k $encrypt_key < \$i > \${i:0:\${#i}-8}; \
626-rm -f \$i; done; \
627-for i in ./sakila/*.xbcrypt; do \
628-xbcrypt -d -a $encrypt_algo -k $encrypt_key < \$i > \${i:0:\${#i}-8}; \
629-rm -f \$i; done;"
630-
631-data_decompress_cmd="for i in *.qp; do qpress -d \$i ./; done; \
632-for i in sakila/*.qp; do qpress -d \$i sakila/; done"
633+data_decrypt_cmd="innobackupex --decrypt=${encrypt_algo} --encrypt-key=${encrypt_key} ./"
634+data_decompress_cmd="innobackupex --decompress ./"
635
636 . inc/xb_local.sh
637
638=== modified file 'test/t/xb_encrypt.sh'
639--- test/t/xb_encrypt.sh 2013-07-09 15:03:03 +0000
640+++ test/t/xb_encrypt.sh 2013-07-25 22:07:27 +0000
641@@ -4,6 +4,7 @@
642
643 encrypt_algo="AES256"
644 encrypt_key="percona_xtrabackup_is_awesome___"
645+<<<<<<< TREE
646 encrypt_key_file=${TEST_VAR_ROOT}/xb_encrypt.key
647
648 echo -n $encrypt_key > $encrypt_key_file
649@@ -15,6 +16,13 @@
650 for i in ./sakila/*.xbcrypt; do \
651 xbcrypt -d -a $encrypt_algo -f $encrypt_key_file < \$i > \${i:0:\${#i}-8}; \
652 rm -f \$i; done;"
653+=======
654+
655+echo -n "Percona XtraBackup is awesome!!!" > $encrypt_key_file
656+
657+innobackupex_options="--encrypt=$encrypt_algo --encrypt-key=$encrypt_key --encrypt-threads=4 --encrypt-chunk-size=8K"
658+data_decrypt_cmd="innobackupex --decrypt=${encrypt_algo} --encrypt-key=${encrypt_key} ./"
659+>>>>>>> MERGE-SOURCE
660
661 . inc/xb_local.sh
662
663
664=== modified file 'test/t/xb_parallel_compress.sh'
665--- test/t/xb_parallel_compress.sh 2013-03-11 19:11:29 +0000
666+++ test/t/xb_parallel_compress.sh 2013-07-25 22:07:27 +0000
667@@ -8,7 +8,6 @@
668 fi
669
670 innobackupex_options="--parallel=8 --compress --compress-threads=4 --compress-chunk-size=8K"
671-data_decompress_cmd="for i in *.qp; do qpress -d \$i ./; done; \
672-for i in sakila/*.qp; do qpress -d \$i sakila/; done"
673+data_decompress_cmd="innobackupex --decompress --parallel=8 ./"
674
675 . inc/xb_local.sh
676
677=== modified file 'test/t/xb_parallel_compress_encrypt.sh'
678--- test/t/xb_parallel_compress_encrypt.sh 2013-03-11 19:11:29 +0000
679+++ test/t/xb_parallel_compress_encrypt.sh 2013-07-25 22:07:27 +0000
680@@ -12,14 +12,6 @@
681
682 innobackupex_options="--parallel=8 --compress --compress-threads=4 --compress-chunk-size=8K --encrypt=$encrypt_algo --encrypt-key=$encrypt_key --encrypt-threads=4 --encrypt-chunk-size=8K"
683
684-data_decrypt_cmd="for i in *.xbcrypt; do \
685-xbcrypt -d -a $encrypt_algo -k $encrypt_key < \$i > \${i:0:\${#i}-8}; \
686-rm -f \$i; done; \
687-for i in ./sakila/*.xbcrypt; do \
688-xbcrypt -d -a $encrypt_algo -k $encrypt_key < \$i > \${i:0:\${#i}-8}; \
689-rm -f \$i; done;"
690-
691-data_decompress_cmd="for i in *.qp; do qpress -d \$i ./; done; \
692-for i in sakila/*.qp; do qpress -d \$i sakila/; done"
693+data_decrypt_cmd="innobackupex --decrypt=${encrypt_algo} --encrypt-key=${encrypt_key} --decompress --parallel=8 ./"
694
695 . inc/xb_local.sh
696
697=== modified file 'test/t/xb_parallel_encrypt.sh'
698--- test/t/xb_parallel_encrypt.sh 2013-03-11 19:11:29 +0000
699+++ test/t/xb_parallel_encrypt.sh 2013-07-25 22:07:27 +0000
700@@ -7,11 +7,6 @@
701 encrypt_key="percona_xtrabackup_is_awesome___"
702
703 innobackupex_options="--parallel=4 --encrypt=$encrypt_algo --encrypt-key=$encrypt_key --encrypt-threads=4 --encrypt-chunk-size=8K"
704-data_decrypt_cmd="for i in *.xbcrypt; do \
705-xbcrypt -d -a $encrypt_algo -k $encrypt_key < \$i > \${i:0:\${#i}-8}; \
706-rm -f \$i; done; \
707-for i in ./sakila/*.xbcrypt; do \
708-xbcrypt -d -a $encrypt_algo -k $encrypt_key < \$i > \${i:0:\${#i}-8}; \
709-rm -f \$i; done;"
710+data_decrypt_cmd="innobackupex --decrypt=${encrypt_algo} --encrypt-key=${encrypt_key} --parallel=4 ./"
711
712 . inc/xb_local.sh

Subscribers

People subscribed via source and target branches