Merge lp:~laurynas-biveinis/percona-xtrabackup/xtrabackup-page-filters into lp:percona-xtrabackup/2.0
- xtrabackup-page-filters
- Merge into 2.0
Status: | Rejected |
---|---|
Rejected by: | Laurynas Biveinis |
Proposed branch: | lp:~laurynas-biveinis/percona-xtrabackup/xtrabackup-page-filters |
Merge into: | lp:percona-xtrabackup/2.0 |
Diff against target: |
6973 lines (+3263/-2355) (has conflicts) 31 files modified
doc/source/innobackupex/how_innobackupex_works.rst (+0/-4) doc/source/innobackupex/innobackupex_option_reference.rst (+2/-6) doc/source/innobackupex/innobackupex_script.rst (+0/-1) doc/xtrabackup.1 (+0/-15) innobackupex (+52/-113) src/Makefile (+14/-5) src/common.h (+41/-8) src/datasink.c (+113/-0) src/datasink.h (+46/-8) src/ds_compress.c (+31/-59) src/ds_compress.h (+2/-2) src/ds_local.c (+0/-3) src/ds_local.h (+2/-2) src/ds_stream.c (+4/-2) src/ds_stream.h (+2/-2) src/ds_tmpfile.c (+243/-0) src/ds_tmpfile.h (+28/-0) src/fil_cur.c (+266/-0) src/fil_cur.h (+95/-0) src/innodb_int.c (+791/-0) src/innodb_int.h (+632/-0) src/page_write_filt.c (+309/-0) src/page_write_filt.h (+74/-0) src/quicklz/quicklz.h (+1/-0) src/xbstream.c (+15/-19) src/xtrabackup.c (+388/-2096) test/disabled/compact.sh (+35/-0) test/disabled/compact_compressed.sh (+53/-0) test/inc/common.sh (+19/-0) test/run.sh (+2/-1) test/t/bug766033.sh (+3/-9) Text conflict in innobackupex Text conflict in src/xtrabackup.c |
To merge this branch: | bzr merge lp:~laurynas-biveinis/percona-xtrabackup/xtrabackup-page-filters |
Related bugs: | |
Related blueprints: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Laurynas Biveinis (community) | Needs Resubmitting | ||
Review via email: mp+105341@code.launchpad.net |
Commit message
Description of the change
First part of xtrabackup page filter refactoring: introduce source
file cursor.
- Move get_bit_shift() definition to common.h.
- New files fil_cur.h and fil_cur.c for source file cursor
implementation. New type xb_fil_cur_t to hold source file read state
instead of local variables in xtrabackup_
functions xb_fil_cur_open(), xb_fil_cur_read(), xb_fil_cur_close()
for opening, reading the next page batch and closing the source
file. Their definitions refactored out of
xtrabackup_
- New files innodb_int.h and innodb_int.c to introduce a portability
layer above the different InnoDB/XtraDB versions XtraBackup can be
compiled against. Move and simplify a bunch of definitions from
xtrabackup.c.
- Use the file cursor abstraction in xtrabackup_
Second part of xtrabackup page filter refactoring: introduce write
filters.
- Move XB_DELTA_
common.h.
- Move some more InnoDB portability layer macros to innodb_int.h.
- New files page_write_filt.h and page_write_filt.c for page writer
filter implementation. New types xb_page_
xb_page_
filters. Two new functions that return one of page write filters:
- pwf_make_
- pwf_make_
only pages whose LSN is later than a specified value.
Move xb_write_
xtrabackup_
- Remove unused method xtrabackup_
Laurynas Biveinis (laurynas-biveinis) wrote : | # |
Laurynas Biveinis (laurynas-biveinis) wrote : | # |
Pushed a few very minor fixes for various build configs.
New Jenkins results will be at
http://
Laurynas Biveinis (laurynas-biveinis) wrote : | # |
Jenkins testing completed.
http://
Alexey Kopytov (akopytov) wrote : | # |
As discussed elsewhere, no backporting is needed, since this code is only going to be used by new features in the new trunk.
Laurynas Biveinis (laurynas-biveinis) wrote : | # |
I believe the delta from the old compact-backups will need to be resubmitted against the new trunk.
(And here goes the 1st proper Review: Resubmit use :)
Alexey Kopytov (akopytov) wrote : | # |
Sure, but this will have to be another MP anyway, right?
Preview Diff
1 | === modified file 'doc/source/innobackupex/how_innobackupex_works.rst' |
2 | --- doc/source/innobackupex/how_innobackupex_works.rst 2012-02-14 08:31:46 +0000 |
3 | +++ doc/source/innobackupex/how_innobackupex_works.rst 2012-05-24 09:35:22 +0000 |
4 | @@ -53,10 +53,6 @@ |
5 | :file:`mysql-stdout` |
6 | containing the ``STDOUT`` of the server. |
7 | |
8 | -If the :option:`--remote-host` was set, |innobackupex| will test the connection to the host via :command:`ssh` and create the backup directories. Then the same process will be applied but the log will be written to a temporary file and will be copied via :command:`scp` with the options set by :option:`--scpopt` (``-Cp -c arcfour`` by default). |
9 | - |
10 | -After each copy the files will be deleted. The same rationale is for the :option:`--stream` mode. |
11 | - |
12 | Finally, the binary log position will be printed to ``STDERR`` and |innobackupex| will exit returning 0 if all went OK. |
13 | |
14 | Note that the ``STDERR`` of |innobackupex| is not written in any file. You will have to redirect it to a file, e.g., ``innobackupex OPTIONS 2> backupout.log``. |
15 | |
16 | === modified file 'doc/source/innobackupex/innobackupex_option_reference.rst' |
17 | --- doc/source/innobackupex/innobackupex_option_reference.rst 2012-05-18 11:19:17 +0000 |
18 | +++ doc/source/innobackupex/innobackupex_option_reference.rst 2012-05-24 09:35:22 +0000 |
19 | @@ -119,17 +119,13 @@ |
20 | |
21 | This option accepts a string argument that specifies the directory in which to save an extra copy of the :file:`xtrabackup_checkpoints` file. It is passed directly to |xtrabackup|'s :option:`--extra-lsndir` option. See the :program:`xtrabackup` documentation for details. |
22 | |
23 | -.. option:: --remote-host=HOSTNAME |
24 | - |
25 | - This option accepts a string argument that specifies the remote host on which the backup files will be created, by using an ssh connection. |
26 | - |
27 | .. option:: --stream=STREAMNAME |
28 | |
29 | This option accepts a string argument that specifies the format in which to do the streamed backup. The backup will be done to ``STDOUT`` in the specified format. Currently, the supported format is `xbstream`. Uses :doc:`xbstream <../xbstream/xbstream>`, which is available in *XtraBackup* distributions. If you specify a path after this option, it will be interpreted as the value of :option:`tmpdir`. |
30 | |
31 | .. option:: --tmpdir=DIRECTORY |
32 | |
33 | - This option accepts a string argument that specifies the location where a temporary file will be stored. It should be used when :option:`--remote-host` or :option:`--stream` is specified. For these options, the transaction log will first be stored to a temporary file, before streaming or copying to a remote host. This option specifies the location where that temporary file will be stored. If the option is not specifed, the default is to use the value of ``tmpdir`` read from the server configuration. |
34 | + This option accepts a string argument that specifies the location where a temporary file will be stored. It should be used when :option:`--stream` is specified. For these options, the transaction log will first be stored to a temporary file, before streaming. This option specifies the location where that temporary file will be stored. If the option is not specifed, the default is to use the value of ``tmpdir`` read from the server configuration. |
35 | |
36 | .. option:: --scpopt = '-Cp -c arcfour' |
37 | |
38 | @@ -153,4 +149,4 @@ |
39 | |
40 | .. option:: --rsync |
41 | |
42 | - Use the :program:`rsync` utility to optimize local file transfers. When this option is specified, :program:`innobackupex` uses :program:`rsync` to copy all non-InnoDB files instead of spawning a separate :program:`cp` for each file, which can be much faster for servers with a large number of databases or tables. This option cannot be used together with :option:`--remote-host` or :option:`--stream`. |
43 | + Use the :program:`rsync` utility to optimize local file transfers. When this option is specified, :program:`innobackupex` uses :program:`rsync` to copy all non-InnoDB files instead of spawning a separate :program:`cp` for each file, which can be much faster for servers with a large number of databases or tables. This option cannot be used together with :option:`--stream`. |
44 | |
45 | === modified file 'doc/source/innobackupex/innobackupex_script.rst' |
46 | --- doc/source/innobackupex/innobackupex_script.rst 2011-07-28 05:29:04 +0000 |
47 | +++ doc/source/innobackupex/innobackupex_script.rst 2012-05-24 09:35:22 +0000 |
48 | @@ -46,7 +46,6 @@ |
49 | replication_ibk |
50 | parallel_copy_ibk |
51 | throttling_ibk |
52 | - remote_backups_ibk |
53 | importing_exporting_tables_ibk |
54 | pit_recovery_ibk |
55 | |
56 | |
57 | === renamed file 'doc/source/innobackupex/remote_backups_ibk.rst' => 'doc/source/innobackupex/remote_backups_ibk.rst.THIS' |
58 | === modified file 'doc/xtrabackup.1' |
59 | --- doc/xtrabackup.1 2011-01-10 12:01:38 +0000 |
60 | +++ doc/xtrabackup.1 2012-05-24 09:35:22 +0000 |
61 | @@ -1392,21 +1392,6 @@ |
62 | .B "xtrabackup" |
63 | and your script are working on the same dataset. |
64 | |
65 | -.SS " Log Streaming " |
66 | - |
67 | - |
68 | -You can instruct |
69 | -.B "xtrabackup" |
70 | -to omit copying data files, and simply stream the log file to its standard output instead with |
71 | -.B "--log-stream" |
72 | -. This automatically adds the |
73 | -.B "--suspend-at-end" |
74 | -option. Your script can then perform tasks such as streaming remote backups by piping the log files into an SSH connection and copying the data files to another server with a tool such as |
75 | -.B "rsync" |
76 | -or |
77 | -.B "tar4ibd" |
78 | -. |
79 | - |
80 | .SH " XtraBackup Exit Codes " |
81 | |
82 | |
83 | |
84 | === modified file 'innobackupex' |
85 | --- innobackupex 2012-05-22 14:54:43 +0000 |
86 | +++ innobackupex 2012-05-24 09:35:22 +0000 |
87 | @@ -97,7 +97,6 @@ |
88 | my $option_incremental_dir = ''; |
89 | my $option_incremental_lsn = ''; |
90 | my $option_extra_lsndir = ''; |
91 | -my $option_remote_host = ''; |
92 | my $option_rsync = ''; |
93 | my $option_stream = ''; |
94 | my $stream_cmd = ''; |
95 | @@ -112,6 +111,8 @@ |
96 | my $option_safe_slave_backup = ''; |
97 | my $option_safe_slave_backup_timeout = 300; |
98 | |
99 | +my $option_compact = ''; |
100 | + |
101 | # name of the my.cnf configuration file |
102 | #my $config_file = ''; |
103 | |
104 | @@ -283,11 +284,7 @@ |
105 | } else { |
106 | # make a backup of InnoDB and MyISAM tables, indexes and .frm files. |
107 | $ibbackup_exit_code = backup(); |
108 | - if ($option_remote_host) { |
109 | - open(XTRABACKUP_BINARY, |
110 | - "| ssh $option_ssh_opt $option_remote_host 'cat > $backup_dir/$xtrabackup_binary_file'") |
111 | - || die "Failed to open file '$option_remote_host:$backup_dir/$xtrabackup_binary_file': $!"; |
112 | - } elsif ($option_stream) { |
113 | + if ($option_stream) { |
114 | open XTRABACKUP_BINARY, "> $option_tmpdir/$xtrabackup_binary_file" |
115 | || die "Cannot open file $option_tmpdir/$xtrabackup_binary_file: $!\n"; |
116 | } else { |
117 | @@ -389,9 +386,7 @@ |
118 | start_ibbackup(); |
119 | |
120 | # wait for ibbackup to suspend itself |
121 | - if (!$option_remote_host) { |
122 | - wait_for_ibbackup_suspend(); |
123 | - } |
124 | + wait_for_ibbackup_suspend(); |
125 | |
126 | # connect to database |
127 | mysql_open(); |
128 | @@ -434,11 +429,7 @@ |
129 | |
130 | # copy ib_lru_dump |
131 | if (-e "$orig_datadir/ib_lru_dump") { |
132 | - if ($option_remote_host) { |
133 | - print STDERR "$prefix Backing up file 'ib_lru_dump'\n"; |
134 | - system("scp $option_scp_opt '$orig_datadir/ib_lru_dump' '$option_remote_host:$backup_dir/ib_lru_dump'") |
135 | - and Die "Failed to scp file 'ib_lru_dump': $!"; |
136 | - } elsif ($option_stream) { |
137 | + if ($option_stream) { |
138 | print STDERR "$prefix Backing up as tar stream 'ib_lru_dump'\n"; |
139 | system("cd $orig_datadir; $stream_cmd ib_lru_dump") |
140 | and Die "Failed to stream 'ib_lru_dump': $!"; |
141 | @@ -450,16 +441,6 @@ |
142 | } |
143 | } |
144 | |
145 | - if ($option_remote_host) { |
146 | - system("scp $option_scp_opt '$tmp_logfile' '$option_remote_host:$backup_dir/xtrabackup_logfile'") |
147 | - and Die "Failed to scp file '$option_remote_host:$backup_dir/xtrabackup_logfile': $!"; |
148 | - unlink $tmp_logfile || Die "Failed to delete '$tmp_logfile': $!"; |
149 | - |
150 | - system("scp $option_scp_opt '$option_tmpdir/xtrabackup_checkpoints' '$option_remote_host:$backup_dir/xtrabackup_checkpoints'") |
151 | - and Die "Failed to scp file '$option_remote_host:$backup_dir/xtrabackup_checkpoints': $!"; |
152 | - unlink "$option_tmpdir/xtrabackup_checkpoints" || Die "Failed to delete '$option_tmpdir/xtrabackup_checkpoints': $!"; |
153 | - } |
154 | - |
155 | print STDERR "\n$prefix Backup created in directory '$backup_dir'\n"; |
156 | if ($mysql_binlog_position) { |
157 | print STDERR "$prefix MySQL binlog position: $mysql_binlog_position\n"; |
158 | @@ -875,14 +856,11 @@ |
159 | |
160 | $options = $options . "--backup --suspend-at-end"; |
161 | |
162 | - if (!$option_remote_host && !$option_stream) { |
163 | - $options = $options . " --target-dir=$backup_dir"; |
164 | - } else { |
165 | + if ($option_stream) { |
166 | #(datadir) for 'xtrabackup_suspended' and 'xtrabackup_checkpoints' |
167 | $options = $options . " --target-dir=" . $option_tmpdir; |
168 | - if ($option_remote_host) { |
169 | - $options = $options . " --log-stream"; |
170 | - } |
171 | + } else { |
172 | + $options = $options . " --target-dir=$backup_dir"; |
173 | } |
174 | |
175 | # prepare command line for running ibbackup |
176 | @@ -923,6 +901,10 @@ |
177 | if ($option_stream) { |
178 | $options = $options . " --stream=$option_stream"; |
179 | } |
180 | + if ($option_compact) { |
181 | + $options = $options. " --compact"; |
182 | + } |
183 | + |
184 | $cmdline = "$option_ibbackup_binary $options"; |
185 | |
186 | # run ibbackup as a child process |
187 | @@ -932,6 +914,7 @@ |
188 | if ($pid) { |
189 | # parent process |
190 | $ibbackup_pid = $pid; |
191 | +<<<<<<< TREE |
192 | |
193 | if($option_remote_host) { |
194 | #direct copy to remote |
195 | @@ -1017,12 +1000,9 @@ |
196 | } |
197 | closedir(DIR); |
198 | } |
199 | +======= |
200 | +>>>>>>> MERGE-SOURCE |
201 | } else { |
202 | - if($option_remote_host) { |
203 | - open(STDOUT, "> $tmp_logfile") |
204 | - || Die "Failed to open file '$tmp_logfile': $!" |
205 | - } |
206 | - |
207 | # child process |
208 | exec($cmdline) || Die "Failed to exec ibbackup: $!"; |
209 | } |
210 | @@ -1226,13 +1206,7 @@ |
211 | if (!defined $info_lines[1]) { |
212 | $info_lines[1] = ""; |
213 | } |
214 | - if (!$option_remote_host) { |
215 | - open(FILE, ">$binlog_info") || |
216 | - Die "Failed to open file '$binlog_info': $!"; |
217 | - } else { |
218 | - open(FILE, "| ssh $option_ssh_opt $option_remote_host 'cat > $binlog_info'") || |
219 | - Die "Failed to open file '$option_remote_host:$binlog_info': $!"; |
220 | - } |
221 | + open(FILE, ">$binlog_info") || Die "Failed to open file '$binlog_info': $!"; |
222 | print FILE "$info_lines[1]\n"; |
223 | close(FILE); |
224 | |
225 | @@ -1323,13 +1297,7 @@ |
226 | } |
227 | |
228 | # print slave status to a file |
229 | - if (!$option_remote_host) { |
230 | - open(FILE, ">$slave_info") || |
231 | - Die "Failed to open file '$slave_info': $!"; |
232 | - } else { |
233 | - open(FILE, "| ssh $option_ssh_opt $option_remote_host 'cat > $slave_info'") || |
234 | - Die "Failed to open file '$option_remote_host:$slave_info': $!"; |
235 | - } |
236 | + open(FILE, ">$slave_info") || Die "Failed to open file '$slave_info': $!"; |
237 | print FILE "CHANGE MASTER TO MASTER_LOG_FILE='$filename', MASTER_LOG_POS=$position\n"; |
238 | close(FILE); |
239 | |
240 | @@ -1601,32 +1569,20 @@ |
241 | |
242 | if (!$option_apply_log && !$option_copy_back) { |
243 | # we are making a backup, create a new backup directory |
244 | - if (!$option_remote_host) { |
245 | - $backup_dir = File::Spec->rel2abs(make_backup_dir()); |
246 | - } else { |
247 | - $backup_dir = make_backup_dir(); |
248 | - } |
249 | + $backup_dir = File::Spec->rel2abs(make_backup_dir()); |
250 | print STDERR "$prefix Created backup directory $backup_dir\n"; |
251 | - if (!$option_remote_host && !$option_stream) { |
252 | - $backup_config_file = $backup_dir . '/backup-my.cnf'; |
253 | - $suspend_file = $backup_dir . '/xtrabackup_suspended'; |
254 | - $binlog_info = $backup_dir . '/xtrabackup_binlog_info'; |
255 | - $galera_info = $backup_dir . '/xtrabackup_galera_info'; |
256 | - $slave_info = $backup_dir . '/xtrabackup_slave_info'; |
257 | - } else { |
258 | - $suspend_file = $option_tmpdir . '/xtrabackup_suspended'; |
259 | - $tmp_logfile = $option_tmpdir . '/xtrabackup_logfile'; |
260 | - if ($option_stream) { |
261 | - $backup_config_file = $option_tmpdir . '/backup-my.cnf'; |
262 | - $binlog_info = $option_tmpdir . '/xtrabackup_binlog_info'; |
263 | - $galera_info = $option_tmpdir . '/xtrabackup_galera_info'; |
264 | - $slave_info = $option_tmpdir . '/xtrabackup_slave_info'; |
265 | - } else { |
266 | + if (!$option_stream) { |
267 | $backup_config_file = $backup_dir . '/backup-my.cnf'; |
268 | + $suspend_file = $backup_dir . '/xtrabackup_suspended'; |
269 | $binlog_info = $backup_dir . '/xtrabackup_binlog_info'; |
270 | $galera_info = $backup_dir . '/xtrabackup_galera_info'; |
271 | $slave_info = $backup_dir . '/xtrabackup_slave_info'; |
272 | - } |
273 | + } else { |
274 | + $suspend_file = $option_tmpdir . '/xtrabackup_suspended'; |
275 | + $tmp_logfile = $option_tmpdir . '/xtrabackup_logfile'; |
276 | + $backup_config_file = $option_tmpdir . '/backup-my.cnf'; |
277 | + $binlog_info = $option_tmpdir . '/xtrabackup_binlog_info'; |
278 | + $slave_info = $option_tmpdir . '/xtrabackup_slave_info'; |
279 | } |
280 | write_backup_config_file($backup_config_file); |
281 | } elsif ($option_copy_back) { |
282 | @@ -1646,12 +1602,17 @@ |
283 | sub write_backup_config_file { |
284 | my $filename = shift; |
285 | |
286 | +<<<<<<< TREE |
287 | if (!$option_remote_host) { |
288 | open(FILE, "> $filename") || Die "Failed to open file '$filename': $!"; |
289 | } else { |
290 | open(FILE, "| ssh $option_ssh_opt $option_remote_host 'cat > $filename'") |
291 | || Die "Failed to open file '$option_remote_host:$filename': $!"; |
292 | } |
293 | +======= |
294 | + $root = $backup_dir; |
295 | + open(FILE, "> $filename") || Die "Failed to open file '$filename': $!"; |
296 | +>>>>>>> MERGE-SOURCE |
297 | |
298 | my @option_names = ( |
299 | "innodb_data_file_path", |
300 | @@ -1746,7 +1707,6 @@ |
301 | 'incremental-lsn=s' => \$option_incremental_lsn, |
302 | 'incremental-dir=s' => \$option_incremental_dir, |
303 | 'extra-lsndir=s' => \$option_extra_lsndir, |
304 | - 'remote-host=s' => \$option_remote_host, |
305 | 'stream=s' => \$option_stream, |
306 | 'rsync' => \$option_rsync, |
307 | 'tmpdir=s' => \$option_tmpdir, |
308 | @@ -1757,6 +1717,7 @@ |
309 | 'parallel=i' => \$option_parallel, |
310 | 'safe-slave-backup' => \$option_safe_slave_backup, |
311 | 'safe-slave-backup-timeout' => $option_safe_slave_backup_timeout, |
312 | + 'compact' => \$option_compact |
313 | ); |
314 | |
315 | if (!$rcode) { |
316 | @@ -1827,16 +1788,11 @@ |
317 | } |
318 | } |
319 | |
320 | - if ($option_rsync && ($option_remote_host || $option_stream)) { |
321 | - print STDERR "--rsync doesn't work with --remote-host or --stream\n"; |
322 | + if ($option_rsync && $option_stream) { |
323 | + print STDERR "--rsync doesn't work with --stream\n"; |
324 | exit(1); |
325 | } |
326 | |
327 | - if ($option_remote_host) { |
328 | - print STDERR "\nWARNING: --remote-host is DEPRECATED and will be ", |
329 | - "removed in Percona XtraBackup 2.1 in favor of streaming backups.\n"; |
330 | - } |
331 | - |
332 | print STDERR "\n"; |
333 | |
334 | parse_databases_option_value(); |
335 | @@ -1861,11 +1817,7 @@ |
336 | |
337 | $dir .= '/' . strftime("%Y-%m-%d_%H-%M-%S", localtime()) |
338 | unless $option_no_timestamp; |
339 | - if (!$option_remote_host) { |
340 | - mkdir($dir, 0777) || Die "Failed to create backup directory $dir: $!"; |
341 | - } else { |
342 | - system("ssh $option_ssh_opt $option_remote_host mkdir $dir"); |
343 | - } |
344 | + mkdir($dir, 0777) || Die "Failed to create backup directory $dir: $!"; |
345 | |
346 | # create subdirectories for ibdata files if needed |
347 | # foreach my $a (split(/;/, $innodb_data_file_path)) { |
348 | @@ -1901,15 +1853,9 @@ |
349 | $path = $root; |
350 | foreach $a (@{$relative_path}) { |
351 | $path = $path . "/" . $a; |
352 | - if (!$option_remote_host) { |
353 | - if (! -d $path) { |
354 | - # this directory does not exist, create it ! |
355 | - mkdir($path, 0777) || Die "Failed to create backup directory: $!"; |
356 | - } |
357 | - } else { |
358 | - if (system("ssh $option_ssh_opt $option_remote_host test -d $path") != 0) { |
359 | - system("ssh $option_ssh_opt $option_remote_host mkdir $path"); |
360 | - } |
361 | + if (! -d $path) { |
362 | + # this directory does not exist, create it ! |
363 | + mkdir($path, 0777) || Die "Failed to create backup directory: $!"; |
364 | } |
365 | } |
366 | } |
367 | @@ -1991,17 +1937,12 @@ |
368 | next unless -d "$source_dir/$database"; |
369 | next unless check_if_required($database); |
370 | |
371 | - if (!$option_remote_host && !$option_stream) { |
372 | + if (!$option_stream) { |
373 | if (! -e "$backup_dir/$database") { |
374 | # create database directory for the backup |
375 | mkdir("$backup_dir/$database", 0777) |
376 | || Die "Couldn't create directory '$backup_dir/$database': $!"; |
377 | } |
378 | - } elsif ($option_remote_host) { |
379 | - if (system("ssh $option_ssh_opt $option_remote_host test -e $backup_dir/$database") |
380 | - != 0) { |
381 | - system("ssh $option_ssh_opt $option_remote_host mkdir $backup_dir/$database"); |
382 | - } |
383 | } |
384 | |
385 | # copy files of this database |
386 | @@ -2035,16 +1976,13 @@ |
387 | if (!$prep_mode) { |
388 | $rsync_files_hash{"$database/$file"} = 1; |
389 | } |
390 | - } elsif (!$option_remote_host && !$option_stream) { |
391 | + } elsif (!$option_stream) { |
392 | $src_name = escape_path("$source_dir/$database/$file"); |
393 | $dst_name = escape_path("$backup_dir/$database"); |
394 | # Copy the file - If we get an error and the file actually exists, die with error msg |
395 | copy_if_exists("$src_name", "$dst_name") |
396 | or Die "Failed to copy file '$file': $!"; |
397 | - } elsif ($option_remote_host) { |
398 | - # Queue up files for one single scp per database. |
399 | - push(@scp_files, "'$file'"); |
400 | - } elsif($option_stream) { |
401 | + } else { |
402 | my $ret = 0; |
403 | my $file_name = substr($file, rindex($file, '/') + 1); |
404 | $file_name=~s/([\$\\\" ])/\\$1/g; |
405 | @@ -2064,11 +2002,6 @@ |
406 | } |
407 | } |
408 | } |
409 | - if ($option_remote_host and @scp_files) { |
410 | - my $scp_file_list = join(" ", map { "$source_dir/$database/$_" } @scp_files); |
411 | - system("scp $option_scp_opt $scp_file_list '$option_remote_host:$backup_dir/$database/'") |
412 | - and Die "Failed to execute \"scp $option_scp_opt $scp_file_list '$option_remote_host:$backup_dir/$database/'\": $!"; |
413 | - } |
414 | } |
415 | closedir(DIR); |
416 | |
417 | @@ -2630,12 +2563,18 @@ |
418 | [--password=WORD] [--port=PORT] [--socket=SOCKET] |
419 | [--no-timestamp] [--ibbackup=IBBACKUP-BINARY] |
420 | [--slave-info] [--stream=tar|xbstream] |
421 | +<<<<<<< TREE |
422 | [--scpopt=OPTIONS-FOR-SCP] [--sshopt=OPTIONS-FOR-SSH] |
423 | [--defaults-file=MY.CNF] [--defaults-group=GROUP-NAME] |
424 | [--databases=LIST] [--remote-host=HOSTNAME] [--no-lock] |
425 | +======= |
426 | + [--defaults-file=MY.CNF] |
427 | + [--databases=LIST] [--no-lock] |
428 | +>>>>>>> MERGE-SOURCE |
429 | [--tmpdir=DIRECTORY] [--tables-file=FILE] |
430 | [--incremental] [--incremental-basedir] |
431 | [--incremental-dir] [--incremental-lsn] |
432 | + [--compact] |
433 | BACKUP-ROOT-DIR |
434 | |
435 | innobackupex --apply-log [--use-memory=B] [--uncompress] |
436 | @@ -2685,6 +2624,10 @@ |
437 | |
438 | Prepare a backup in BACKUP-DIR by applying the transaction log file named "xtrabackup_logfile" located in the same directory. Also, create new transaction logs. The InnoDB configuration is read from the file "backup-my.cnf". |
439 | |
440 | +=item --compact |
441 | + |
442 | +Create a compact backup with all secondary index pages omitted. This option is passed directly to xtrabackup. See xtrabackup documentation for details. |
443 | + |
444 | =item --compress |
445 | |
446 | This option instructs xtrabackup to compress backup copies of InnoDB |
447 | @@ -2774,10 +2717,6 @@ |
448 | |
449 | This option is passed directly to xtrabackup's --apply-log-only option. This forces xtrabackup to skip the "rollback" phase and do a "redo" only. This is necessary if the backup will have incremental changes applied to it later. See the xtrabackup documentation for details. |
450 | |
451 | -=item --remote-host=HOSTNAME |
452 | - |
453 | -This option is DEPRECATED and will be removed in Percona XtraBackup 2.1. In Percona XtraBackup 2.0 and later, you should use streaming backups instead. This option specifies the remote host on which the backup files will be created, by using an ssh connection. The option accepts a string argument. |
454 | - |
455 | =item --safe-slave-backup |
456 | |
457 | Stop slave SQL thread and wait to start backup until Slave_open_temp_tables in "SHOW STATUS" is zero. If there are no open temporary tables, the backup will take place, otherwise the SQL thread will be started and stopped until there are no open temporary tables. The backup will fail if Slave_open_temp_tables does not become zero after --safe-slave-backup-timeout seconds. The slave SQL thread will be restarted when the backup finishes. |
458 | @@ -2816,7 +2755,7 @@ |
459 | |
460 | =item --tmpdir=DIRECTORY |
461 | |
462 | -This option specifies the location where a temporary file will be stored. The option accepts a string argument. It should be used when --remote-host or --stream is specified. For these options, the transaction log will first be stored to a temporary file, before streaming or copying to a remote host. This option specifies the location where that temporary file will be stored. If the option is not specifed, the default is to use the value of tmpdir read from the server configuration. |
463 | +This option specifies the location where a temporary file will be stored. The option accepts a string argument. It should be used when --stream is specified. For these options, the transaction log will first be stored to a temporary file, before streaming. This option specifies the location where that temporary file will be stored. If the option is not specifed, the default is to use the value of tmpdir read from the server configuration. |
464 | |
465 | =item --use-memory=B |
466 | |
467 | |
468 | === modified file 'src/Makefile' |
469 | --- src/Makefile 2012-02-10 20:05:56 +0000 |
470 | +++ src/Makefile 2012-05-24 09:35:22 +0000 |
471 | @@ -12,10 +12,10 @@ |
472 | LIBS += -lpthread |
473 | DEFS = -DUNIV_LINUX -DMYSQL_SERVER |
474 | |
475 | -CFLAGS += -DXTRABACKUP_VERSION=\"$(XTRABACKUP_VERSION)\" -pedantic -Wall -Wundef -Wshadow -fdiagnostics-show-option -fno-strict-aliasing -Wno-strict-aliasing -Wextra -Wformat -Wno-format-nonliteral -Wno-format-security -Wno-long-long -Wmissing-declarations -Wno-redundant-decls --std=gnu99 |
476 | +CFLAGS += -g -DXTRABACKUP_VERSION=\"$(XTRABACKUP_VERSION)\" -pedantic -Wall -fdiagnostics-show-option -fno-strict-aliasing -Wno-strict-aliasing -Wextra -Wformat -Wno-format-nonliteral -Wno-format-security -Wno-long-long -Wmissing-declarations -Wno-redundant-decls --std=gnu99 # -Wundef -Wshadow |
477 | |
478 | ifneq ($(DEBUG),) |
479 | -CFLAGS += -DXB_DEBUG=1 |
480 | +CFLAGS += -DXB_DEBUG=1 -DUNIV_DEBUG |
481 | endif |
482 | |
483 | TARGET=xtrabackup |
484 | @@ -23,7 +23,16 @@ |
485 | BIN_DIR=$(PREFIX)/bin |
486 | |
487 | COMMON_INC = -I. -I libarchive/libarchive -I quicklz |
488 | -XTRABACKUPOBJS = xtrabackup.o stream.o local.o compress.o xbstream_write.o \ |
489 | +XTRABACKUPOBJS = xtrabackup.o \ |
490 | + ds_stream.o \ |
491 | + ds_local.o \ |
492 | + ds_compress.o \ |
493 | + ds_tmpfile.o \ |
494 | + datasink.o \ |
495 | + page_write_filt.o \ |
496 | + fil_cur.o \ |
497 | + innodb_int.o \ |
498 | + xbstream_write.o \ |
499 | quicklz/quicklz.o |
500 | XBSTREAMOBJS = xbstream.o xbstream_write.o xbstream_read.o |
501 | |
502 | @@ -176,10 +185,10 @@ |
503 | xbstream.o xbstream_read.o: %.o: %.c |
504 | $(CC) $(CFLAGS) $(INC) $(DEFS) -c $< -o $@ |
505 | |
506 | -xbstream: $(XBSTREAMOBJS) $(MYSQLOBJS) local.o |
507 | +xbstream: $(XBSTREAMOBJS) $(MYSQLOBJS) ds_local.o datasink.o |
508 | $(CC) $(CFLAGS) $^ $(INC) $(MYSQLOBJS) $(LIBS) -o $@ |
509 | |
510 | -xtrabackup.o: xtrabackup.c xb_regex.h |
511 | +xtrabackup.o: xtrabackup.c xb_regex.h page_write_filt.h fil_cur.h |
512 | |
513 | $(TARGET): $(XTRABACKUPOBJS) $(INNODBOBJS) $(MYSQLOBJS) $(LIBARCHIVE_A) |
514 | $(CC) $(CFLAGS) $(XTRABACKUPOBJS) $(INNODBOBJS) $(MYSQLOBJS) $(LIBS) \ |
515 | |
516 | === modified file 'src/common.h' |
517 | --- src/common.h 2012-02-10 20:05:56 +0000 |
518 | +++ src/common.h 2012-05-24 09:35:22 +0000 |
519 | @@ -24,12 +24,14 @@ |
520 | #include <my_global.h> |
521 | #include <mysql_version.h> |
522 | #include <fcntl.h> |
523 | +#include <stdarg.h> |
524 | +#include "innodb_int.h" |
525 | |
526 | #define xb_a(expr) \ |
527 | do { \ |
528 | if (!(expr)) { \ |
529 | msg("Assertion \"%s\" failed at %s:%lu\n", \ |
530 | - #expr, __FILE__, (unsigned long) __LINE__); \ |
531 | + #expr, __FILE__, (ulint) __LINE__); \ |
532 | abort(); \ |
533 | } \ |
534 | } while (0); |
535 | @@ -40,6 +42,18 @@ |
536 | #define xb_ad(expr) |
537 | #endif |
538 | |
539 | +#define XB_DELTA_INFO_SUFFIX ".meta" |
540 | + |
541 | +typedef struct { |
542 | + ulint page_size; |
543 | +} xb_delta_info_t; |
544 | + |
545 | +typedef enum { |
546 | + XB_STREAM_FMT_NONE, |
547 | + XB_STREAM_FMT_TAR, |
548 | + XB_STREAM_FMT_XBSTREAM |
549 | +} xb_stream_fmt_t; |
550 | + |
551 | static inline int msg(const char *fmt, ...) ATTRIBUTE_FORMAT(printf, 1, 2); |
552 | static inline int msg(const char *fmt, ...) |
553 | { |
554 | @@ -61,13 +75,32 @@ |
555 | /* Use POSIX_FADV_NORMAL when available */ |
556 | |
557 | #ifdef POSIX_FADV_NORMAL |
558 | -#define USE_POSIX_FADVISE |
559 | +# define USE_POSIX_FADVISE |
560 | +#else |
561 | +# define POSIX_FADV_NORMAL |
562 | +# define POSIX_FADV_SEQUENTIAL |
563 | +# define POSIX_FADV_DONTNEED |
564 | + static inline int posix_fadvise(int, off_t, off_t, int) { } |
565 | #endif |
566 | |
567 | -typedef enum { |
568 | - XB_STREAM_FMT_NONE, |
569 | - XB_STREAM_FMT_TAR, |
570 | - XB_STREAM_FMT_XBSTREAM |
571 | -} xb_stream_fmt_t; |
572 | - |
573 | +/*********************************************************************** |
574 | +Computes bit shift for a given value. If the argument is not a power |
575 | +of 2, returns 0.*/ |
576 | +static inline ulint |
577 | +get_bit_shift(ulint value) |
578 | +{ |
579 | + ulint shift; |
580 | + |
581 | + if (value == 0) |
582 | + return 0; |
583 | + |
584 | + for (shift = 0; !(value & 1UL); shift++) { |
585 | + value >>= 1; |
586 | + } |
587 | + return (value >> 1) ? 0 : shift; |
588 | +} |
589 | + |
590 | +void xtrabackup_io_throttling(void); |
591 | +my_bool xb_write_delta_metadata(const char *filename, |
592 | + const xb_delta_info_t *info); |
593 | #endif |
594 | |
595 | === added file 'src/datasink.c' |
596 | --- src/datasink.c 1970-01-01 00:00:00 +0000 |
597 | +++ src/datasink.c 2012-05-24 09:35:22 +0000 |
598 | @@ -0,0 +1,113 @@ |
599 | +/****************************************************** |
600 | +Copyright (c) 2011 Percona Inc. |
601 | + |
602 | +Data sink interface. |
603 | + |
604 | +This program is free software; you can redistribute it and/or modify |
605 | +it under the terms of the GNU General Public License as published by |
606 | +the Free Software Foundation; version 2 of the License. |
607 | + |
608 | +This program is distributed in the hope that it will be useful, |
609 | +but WITHOUT ANY WARRANTY; without even the implied warranty of |
610 | +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
611 | +GNU General Public License for more details. |
612 | + |
613 | +You should have received a copy of the GNU General Public License |
614 | +along with this program; if not, write to the Free Software |
615 | +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
616 | + |
617 | +*******************************************************/ |
618 | + |
619 | +#include <my_base.h> |
620 | +#include "common.h" |
621 | +#include "datasink.h" |
622 | +#include "ds_compress.h" |
623 | +#include "ds_stream.h" |
624 | +#include "ds_local.h" |
625 | +#include "ds_tmpfile.h" |
626 | + |
627 | +/************************************************************************ |
628 | +Create a datasink of the specified type */ |
629 | +ds_ctxt_t * |
630 | +ds_create(const char *root, ds_type_t type) |
631 | +{ |
632 | + datasink_t *ds; |
633 | + ds_ctxt_t *ctxt; |
634 | + |
635 | + switch (type) { |
636 | + case DS_TYPE_LOCAL: |
637 | + ds = &datasink_local; |
638 | + break; |
639 | + case DS_TYPE_STREAM: |
640 | + ds = &datasink_stream; |
641 | + break; |
642 | + case DS_TYPE_COMPRESS: |
643 | + ds = &datasink_compress; |
644 | + break; |
645 | + case DS_TYPE_TMPFILE: |
646 | + ds = &datasink_tmpfile; |
647 | + break; |
648 | + default: |
649 | + msg("Unknown datasink type: %d\n", type); |
650 | + return NULL; |
651 | + } |
652 | + |
653 | + ctxt = ds->init(root); |
654 | + if (ctxt != NULL) { |
655 | + ctxt->datasink = ds; |
656 | + } else { |
657 | + msg("Error: failed to initialize datasink.\n"); |
658 | + exit(EXIT_FAILURE); |
659 | + } |
660 | + |
661 | + return ctxt; |
662 | +} |
663 | + |
664 | +/************************************************************************ |
665 | +Open a datasink file */ |
666 | +ds_file_t * |
667 | +ds_open(ds_ctxt_t *ctxt, const char *path, MY_STAT *stat) |
668 | +{ |
669 | + ds_file_t *file; |
670 | + |
671 | + file = ctxt->datasink->open(ctxt, path, stat); |
672 | + if (file != NULL) { |
673 | + file->datasink = ctxt->datasink; |
674 | + } |
675 | + |
676 | + return file; |
677 | +} |
678 | + |
679 | +/************************************************************************ |
680 | +Write to a datasink file. |
681 | +@return 0 on success, 1 on error. */ |
682 | +int |
683 | +ds_write(ds_file_t *file, const void *buf, size_t len) |
684 | +{ |
685 | + return file->datasink->write(file, buf, len); |
686 | +} |
687 | + |
688 | +/************************************************************************ |
689 | +Close a datasink file. |
690 | +@return 0 on success, 1, on error. */ |
691 | +int |
692 | +ds_close(ds_file_t *file) |
693 | +{ |
694 | + return file->datasink->close(file); |
695 | +} |
696 | + |
697 | +/************************************************************************ |
698 | +Destroy a datasink handle */ |
699 | +void |
700 | +ds_destroy(ds_ctxt_t *ctxt) |
701 | +{ |
702 | + ctxt->datasink->deinit(ctxt); |
703 | +} |
704 | + |
705 | +/************************************************************************ |
706 | +Set the destination pipe for a datasink (only makes sense for compress and |
707 | +tmpfile). */ |
708 | +void ds_set_pipe(ds_ctxt_t *ctxt, ds_ctxt_t *pipe_ctxt) |
709 | +{ |
710 | + ctxt->pipe_ctxt = pipe_ctxt; |
711 | +} |
712 | |
713 | === modified file 'src/datasink.h' |
714 | --- src/datasink.h 2012-02-10 20:05:56 +0000 |
715 | +++ src/datasink.h 2012-05-24 09:35:22 +0000 |
716 | @@ -25,24 +25,62 @@ |
717 | #include <my_dir.h> |
718 | |
719 | struct datasink_struct; |
720 | +typedef struct datasink_struct datasink_t; |
721 | |
722 | -typedef struct { |
723 | - struct datasink_struct *datasink; |
724 | - char *root; |
725 | - void *ptr; |
726 | +typedef struct ds_ctxt { |
727 | + datasink_t *datasink; |
728 | + char *root; |
729 | + void *ptr; |
730 | + struct ds_ctxt *pipe_ctxt; |
731 | } ds_ctxt_t; |
732 | |
733 | typedef struct { |
734 | - void *ptr; |
735 | - char *path; |
736 | + void *ptr; |
737 | + char *path; |
738 | + datasink_t *datasink; |
739 | } ds_file_t; |
740 | |
741 | -typedef struct datasink_struct { |
742 | +struct datasink_struct { |
743 | ds_ctxt_t *(*init)(const char *root); |
744 | ds_file_t *(*open)(ds_ctxt_t *ctxt, const char *path, MY_STAT *stat); |
745 | int (*write)(ds_file_t *file, const void *buf, size_t len); |
746 | int (*close)(ds_file_t *file); |
747 | void (*deinit)(ds_ctxt_t *ctxt); |
748 | -} datasink_t; |
749 | +}; |
750 | + |
751 | +/* Supported datasink types */ |
752 | +typedef enum { |
753 | + DS_TYPE_LOCAL, |
754 | + DS_TYPE_STREAM, |
755 | + DS_TYPE_COMPRESS, |
756 | + DS_TYPE_TMPFILE |
757 | +} ds_type_t; |
758 | + |
759 | +/************************************************************************ |
760 | +Create a datasink of the specified type */ |
761 | +ds_ctxt_t *ds_create(const char *root, ds_type_t type); |
762 | + |
763 | +/************************************************************************ |
764 | +Open a datasink file */ |
765 | +ds_file_t *ds_open(ds_ctxt_t *ctxt, const char *path, MY_STAT *stat); |
766 | + |
767 | +/************************************************************************ |
768 | +Write to a datasink file. |
769 | +@return 0 on success, 1 on error. */ |
770 | +int ds_write(ds_file_t *file, const void *buf, size_t len); |
771 | + |
772 | +/************************************************************************ |
773 | +Close a datasink file. |
774 | +@return 0 on success, 1, on error. */ |
775 | +int ds_close(ds_file_t *file); |
776 | + |
777 | +/************************************************************************ |
778 | +Destroy a datasink handle */ |
779 | +void ds_destroy(ds_ctxt_t *ctxt); |
780 | + |
781 | +/************************************************************************ |
782 | +Set the destination pipe for a datasink (only makes sense for compress and |
783 | +tmpfile). */ |
784 | +void ds_set_pipe(ds_ctxt_t *ctxt, ds_ctxt_t *pipe_ctxt); |
785 | |
786 | #endif /* XB_DATASINK_H */ |
787 | |
788 | === renamed file 'src/compress.c' => 'src/ds_compress.c' |
789 | --- src/compress.c 2012-02-10 20:05:56 +0000 |
790 | +++ src/ds_compress.c 2012-05-24 09:35:22 +0000 |
791 | @@ -25,8 +25,8 @@ |
792 | #include <zlib.h> |
793 | #include "common.h" |
794 | #include "datasink.h" |
795 | -#include "stream.h" |
796 | -#include "local.h" |
797 | +#include "ds_stream.h" |
798 | +#include "ds_local.h" |
799 | |
800 | #define COMPRESS_CHUNK_SIZE (64 * 1024UL) |
801 | #define MY_QLZ_COMPRESS_OVERHEAD 400 |
802 | @@ -50,20 +50,16 @@ |
803 | } comp_thread_ctxt_t; |
804 | |
805 | typedef struct { |
806 | - ds_ctxt_t *dest_ctxt; |
807 | comp_thread_ctxt_t *threads; |
808 | uint nthreads; |
809 | } ds_compress_ctxt_t; |
810 | |
811 | typedef struct { |
812 | - datasink_t *dest_ds; |
813 | ds_file_t *dest_file; |
814 | ds_compress_ctxt_t *comp_ctxt; |
815 | size_t bytes_processed; |
816 | } ds_compress_file_t; |
817 | |
818 | -extern ibool xtrabackup_stream; |
819 | -extern uint xtrabackup_parallel; |
820 | extern ibool xtrabackup_compress_threads; |
821 | |
822 | static ds_ctxt_t *compress_init(const char *root); |
823 | @@ -81,10 +77,8 @@ |
824 | &compress_deinit |
825 | }; |
826 | |
827 | -static inline int write_uint32_le(datasink_t *sink, ds_file_t *file, |
828 | - ulong n); |
829 | -static inline int write_uint64_le(datasink_t *sink, ds_file_t *file, |
830 | - ulonglong n); |
831 | +static inline int write_uint32_le(ds_file_t *file, ulong n); |
832 | +static inline int write_uint64_le(ds_file_t *file, ulonglong n); |
833 | |
834 | static comp_thread_ctxt_t *create_worker_threads(uint n); |
835 | static void destroy_worker_threads(comp_thread_ctxt_t *threads, uint n); |
836 | @@ -96,25 +90,12 @@ |
837 | { |
838 | ds_ctxt_t *ctxt; |
839 | ds_compress_ctxt_t *compress_ctxt; |
840 | - datasink_t *dest_ds; |
841 | - ds_ctxt_t *dest_ctxt; |
842 | comp_thread_ctxt_t *threads; |
843 | |
844 | - /* Decide whether the compressed data will be stored in local files or |
845 | - streamed to an archive */ |
846 | - dest_ds = xtrabackup_stream ? &datasink_stream : &datasink_local; |
847 | - |
848 | - dest_ctxt = dest_ds->init(root); |
849 | - if (dest_ctxt == NULL) { |
850 | - msg("compress: failed to initialize the target datasink.\n"); |
851 | - return NULL; |
852 | - } |
853 | - |
854 | /* Create and initialize the worker threads */ |
855 | threads = create_worker_threads(xtrabackup_compress_threads); |
856 | if (threads == NULL) { |
857 | msg("compress: failed to create worker threads.\n"); |
858 | - dest_ds->deinit(dest_ctxt); |
859 | return NULL; |
860 | } |
861 | |
862 | @@ -123,12 +104,11 @@ |
863 | MYF(MY_FAE)); |
864 | |
865 | compress_ctxt = (ds_compress_ctxt_t *) (ctxt + 1); |
866 | - compress_ctxt->dest_ctxt = dest_ctxt; |
867 | compress_ctxt->threads = threads; |
868 | compress_ctxt->nthreads = xtrabackup_compress_threads; |
869 | |
870 | - ctxt->datasink = &datasink_compress; |
871 | ctxt->ptr = compress_ctxt; |
872 | + ctxt->root = my_strdup(root, MYF(MY_FAE)); |
873 | |
874 | return ctxt; |
875 | } |
876 | @@ -138,7 +118,6 @@ |
877 | compress_open(ds_ctxt_t *ctxt, const char *path, MY_STAT *mystat) |
878 | { |
879 | ds_compress_ctxt_t *comp_ctxt; |
880 | - datasink_t *dest_ds; |
881 | ds_ctxt_t *dest_ctxt; |
882 | ds_file_t *dest_file; |
883 | char new_name[FN_REFLEN]; |
884 | @@ -146,21 +125,22 @@ |
885 | ds_file_t *file; |
886 | ds_compress_file_t *comp_file; |
887 | |
888 | + xb_a(ctxt->pipe_ctxt != NULL); |
889 | + dest_ctxt = ctxt->pipe_ctxt; |
890 | + |
891 | comp_ctxt = (ds_compress_ctxt_t *) ctxt->ptr; |
892 | - dest_ctxt = comp_ctxt->dest_ctxt; |
893 | - dest_ds = dest_ctxt->datasink; |
894 | |
895 | /* Append the .qp extension to the filename */ |
896 | fn_format(new_name, path, "", ".qp", MYF(MY_APPEND_EXT)); |
897 | |
898 | - dest_file = dest_ds->open(dest_ctxt, new_name, mystat); |
899 | + dest_file = ds_open(dest_ctxt, new_name, mystat); |
900 | if (dest_file == NULL) { |
901 | return NULL; |
902 | } |
903 | |
904 | /* Write the qpress archive header */ |
905 | - if (dest_ds->write(dest_file, "qpress10", 8) || |
906 | - write_uint64_le(dest_ds, dest_file, COMPRESS_CHUNK_SIZE)) { |
907 | + if (ds_write(dest_file, "qpress10", 8) || |
908 | + write_uint64_le(dest_file, COMPRESS_CHUNK_SIZE)) { |
909 | goto err; |
910 | } |
911 | |
912 | @@ -171,10 +151,10 @@ |
913 | |
914 | /* Write the qpress file header */ |
915 | name_len = strlen(new_name); |
916 | - if (dest_ds->write(dest_file, "F", 1) || |
917 | - write_uint32_le(dest_ds, dest_file, name_len) || |
918 | + if (ds_write(dest_file, "F", 1) || |
919 | + write_uint32_le(dest_file, name_len) || |
920 | /* we want to write the terminating \0 as well */ |
921 | - dest_ds->write(dest_file, new_name, name_len + 1)) { |
922 | + ds_write(dest_file, new_name, name_len + 1)) { |
923 | goto err; |
924 | } |
925 | |
926 | @@ -183,7 +163,6 @@ |
927 | MYF(MY_FAE)); |
928 | comp_file = (ds_compress_file_t *) (file + 1); |
929 | comp_file->dest_file = dest_file; |
930 | - comp_file->dest_ds = dest_ds; |
931 | comp_file->comp_ctxt = comp_ctxt; |
932 | comp_file->bytes_processed = 0; |
933 | |
934 | @@ -193,7 +172,7 @@ |
935 | return file; |
936 | |
937 | err: |
938 | - dest_ds->close(dest_file); |
939 | + ds_close(dest_file); |
940 | return NULL; |
941 | } |
942 | |
943 | @@ -208,12 +187,10 @@ |
944 | uint nthreads; |
945 | uint i; |
946 | const char *ptr; |
947 | - datasink_t *dest_ds; |
948 | ds_file_t *dest_file; |
949 | |
950 | comp_file = (ds_compress_file_t *) file->ptr; |
951 | comp_ctxt = comp_file->comp_ctxt; |
952 | - dest_ds = comp_file->dest_ds; |
953 | dest_file = comp_file->dest_file; |
954 | |
955 | threads = comp_ctxt->threads; |
956 | @@ -262,8 +239,8 @@ |
957 | |
958 | ut_a(threads[i].to_len > 0); |
959 | |
960 | - if (dest_ds->write(dest_file, "NEWBNEWB", 8) || |
961 | - write_uint64_le(dest_ds, dest_file, |
962 | + if (ds_write(dest_file, "NEWBNEWB", 8) || |
963 | + write_uint64_le(dest_file, |
964 | comp_file->bytes_processed)) { |
965 | msg("compress: write to the destination stream " |
966 | "failed.\n"); |
967 | @@ -272,9 +249,8 @@ |
968 | |
969 | comp_file->bytes_processed += threads[i].from_len; |
970 | |
971 | - if (write_uint32_le(dest_ds, dest_file, |
972 | - threads[i].adler) || |
973 | - dest_ds->write(dest_file, threads[i].to, |
974 | + if (write_uint32_le(dest_file, threads[i].adler) || |
975 | + ds_write(dest_file, threads[i].to, |
976 | threads[i].to_len)) { |
977 | msg("compress: write to the destination stream " |
978 | "failed.\n"); |
979 | @@ -294,23 +270,21 @@ |
980 | compress_close(ds_file_t *file) |
981 | { |
982 | ds_compress_file_t *comp_file; |
983 | - datasink_t *dest_ds; |
984 | ds_file_t *dest_file; |
985 | |
986 | comp_file = (ds_compress_file_t *) file->ptr; |
987 | - dest_ds = comp_file->dest_ds; |
988 | dest_file = comp_file->dest_file; |
989 | |
990 | /* Write the qpress file trailer */ |
991 | - dest_ds->write(dest_file, "ENDSENDS", 8); |
992 | + ds_write(dest_file, "ENDSENDS", 8); |
993 | |
994 | /* Supposedly the number of written bytes should be written as a |
995 | "recovery information" in the file trailer, but in reality qpress |
996 | always writes 8 zeros here. Let's do the same */ |
997 | |
998 | - write_uint64_le(dest_ds, dest_file, 0); |
999 | + write_uint64_le(dest_file, 0); |
1000 | |
1001 | - dest_ds->close(dest_file); |
1002 | + ds_close(dest_file); |
1003 | |
1004 | MY_FREE(file); |
1005 | |
1006 | @@ -322,39 +296,37 @@ |
1007 | compress_deinit(ds_ctxt_t *ctxt) |
1008 | { |
1009 | ds_compress_ctxt_t *comp_ctxt; |
1010 | - ds_ctxt_t *dest_ctxt; |
1011 | - datasink_t *dest_ds; |
1012 | + |
1013 | + xb_a(ctxt->pipe_ctxt != NULL); |
1014 | |
1015 | comp_ctxt = (ds_compress_ctxt_t *) ctxt->ptr;; |
1016 | |
1017 | destroy_worker_threads(comp_ctxt->threads, comp_ctxt->nthreads); |
1018 | |
1019 | - dest_ctxt = comp_ctxt->dest_ctxt; |
1020 | - dest_ds = dest_ctxt->datasink; |
1021 | - |
1022 | - dest_ds->deinit(dest_ctxt); |
1023 | - |
1024 | + ds_destroy(ctxt->pipe_ctxt); |
1025 | + |
1026 | + MY_FREE(ctxt->root); |
1027 | MY_FREE(ctxt); |
1028 | } |
1029 | |
1030 | static inline |
1031 | int |
1032 | -write_uint32_le(datasink_t *sink, ds_file_t *file, ulong n) |
1033 | +write_uint32_le(ds_file_t *file, ulong n) |
1034 | { |
1035 | char tmp[4]; |
1036 | |
1037 | int4store(tmp, n); |
1038 | - return sink->write(file, tmp, sizeof(tmp)); |
1039 | + return ds_write(file, tmp, sizeof(tmp)); |
1040 | } |
1041 | |
1042 | static inline |
1043 | int |
1044 | -write_uint64_le(datasink_t *sink, ds_file_t *file, ulonglong n) |
1045 | +write_uint64_le(ds_file_t *file, ulonglong n) |
1046 | { |
1047 | char tmp[8]; |
1048 | |
1049 | int8store(tmp, n); |
1050 | - return sink->write(file, tmp, sizeof(tmp)); |
1051 | + return ds_write(file, tmp, sizeof(tmp)); |
1052 | } |
1053 | |
1054 | static |
1055 | |
1056 | === renamed file 'src/compress.h' => 'src/ds_compress.h' |
1057 | --- src/compress.h 2012-02-10 20:05:56 +0000 |
1058 | +++ src/ds_compress.h 2012-05-24 09:35:22 +0000 |
1059 | @@ -18,8 +18,8 @@ |
1060 | |
1061 | *******************************************************/ |
1062 | |
1063 | -#ifndef XB_COMPRESS_H |
1064 | -#define XB_COMPRESS_H |
1065 | +#ifndef DS_COMPRESS_H |
1066 | +#define DS_COMPRESS_H |
1067 | |
1068 | #include "datasink.h" |
1069 | |
1070 | |
1071 | === renamed file 'src/local.c' => 'src/ds_local.c' |
1072 | --- src/local.c 2012-02-10 20:05:56 +0000 |
1073 | +++ src/ds_local.c 2012-05-24 09:35:22 +0000 |
1074 | @@ -57,7 +57,6 @@ |
1075 | |
1076 | ctxt = my_malloc(sizeof(ds_ctxt_t), MYF(MY_FAE)); |
1077 | |
1078 | - ctxt->datasink = &datasink_local; |
1079 | ctxt->root = my_strdup(root, MYF(MY_FAE)); |
1080 | |
1081 | return ctxt; |
1082 | @@ -117,9 +116,7 @@ |
1083 | File fd = ((ds_local_file_t *) file->ptr)->fd; |
1084 | |
1085 | if (!my_write(fd, buf, len, MYF(MY_WME | MY_NABP))) { |
1086 | -#ifdef USE_POSIX_FADVISE |
1087 | posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED); |
1088 | -#endif |
1089 | return 0; |
1090 | } |
1091 | |
1092 | |
1093 | === renamed file 'src/local.h' => 'src/ds_local.h' |
1094 | --- src/local.h 2012-02-10 20:05:56 +0000 |
1095 | +++ src/ds_local.h 2012-05-24 09:35:22 +0000 |
1096 | @@ -18,8 +18,8 @@ |
1097 | |
1098 | *******************************************************/ |
1099 | |
1100 | -#ifndef XB_LOCAL_H |
1101 | -#define XB_LOCAL_H |
1102 | +#ifndef DS_LOCAL_H |
1103 | +#define DS_LOCAL_H |
1104 | |
1105 | #include "datasink.h" |
1106 | |
1107 | |
1108 | === renamed file 'src/stream.c' => 'src/ds_stream.c' |
1109 | --- src/stream.c 2012-04-22 13:04:24 +0000 |
1110 | +++ src/ds_stream.c 2012-05-24 09:35:22 +0000 |
1111 | @@ -88,7 +88,10 @@ |
1112 | } |
1113 | |
1114 | if (archive_write_set_compression_none(a) != ARCHIVE_OK || |
1115 | - archive_write_set_format_pax_restricted(a) != ARCHIVE_OK) { |
1116 | + archive_write_set_format_pax_restricted(a) != ARCHIVE_OK || |
1117 | + /* disable internal buffering so we don't have to flush the |
1118 | + output in xtrabackup */ |
1119 | + archive_write_set_bytes_per_block(a, 0) != ARCHIVE_OK) { |
1120 | msg("failed to set libarchive stream options: %s\n", |
1121 | archive_error_string(a)); |
1122 | archive_write_finish(a); |
1123 | @@ -103,7 +106,6 @@ |
1124 | } |
1125 | |
1126 | |
1127 | - ctxt->datasink = &datasink_stream; |
1128 | ctxt->ptr = stream_ctxt; |
1129 | |
1130 | return ctxt; |
1131 | |
1132 | === renamed file 'src/stream.h' => 'src/ds_stream.h' |
1133 | --- src/stream.h 2012-02-10 20:05:56 +0000 |
1134 | +++ src/ds_stream.h 2012-05-24 09:35:22 +0000 |
1135 | @@ -18,8 +18,8 @@ |
1136 | |
1137 | *******************************************************/ |
1138 | |
1139 | -#ifndef XTRABACKUP_STREAM_H |
1140 | -#define XTRABACKUP_STREAM_H |
1141 | +#ifndef DS_STREAM_H |
1142 | +#define DS_STREAM_H |
1143 | |
1144 | #include "datasink.h" |
1145 | |
1146 | |
1147 | === added file 'src/ds_tmpfile.c' |
1148 | --- src/ds_tmpfile.c 1970-01-01 00:00:00 +0000 |
1149 | +++ src/ds_tmpfile.c 2012-05-24 09:35:22 +0000 |
1150 | @@ -0,0 +1,243 @@ |
1151 | +/****************************************************** |
1152 | +Copyright (c) 2012 Percona Inc. |
1153 | + |
1154 | +tmpfile datasink for XtraBackup. |
1155 | + |
1156 | +This program is free software; you can redistribute it and/or modify |
1157 | +it under the terms of the GNU General Public License as published by |
1158 | +the Free Software Foundation; version 2 of the License. |
1159 | + |
1160 | +This program is distributed in the hope that it will be useful, |
1161 | +but WITHOUT ANY WARRANTY; without even the implied warranty of |
1162 | +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1163 | +GNU General Public License for more details. |
1164 | + |
1165 | +You should have received a copy of the GNU General Public License |
1166 | +along with this program; if not, write to the Free Software |
1167 | +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
1168 | + |
1169 | +*******************************************************/ |
1170 | + |
1171 | +/* Do all writes to temporary files first, then pipe them to the specified |
1172 | +datasink in a serialized way in deinit(). */ |
1173 | + |
1174 | +#include <my_base.h> |
1175 | +#include "common.h" |
1176 | +#include "datasink.h" |
1177 | + |
1178 | +typedef struct { |
1179 | + pthread_mutex_t mutex; |
1180 | + LIST *file_list; |
1181 | +} ds_tmpfile_ctxt_t; |
1182 | + |
1183 | +typedef struct { |
1184 | + LIST list; |
1185 | + File fd; |
1186 | + char *orig_path; |
1187 | + MY_STAT mystat; |
1188 | + ds_file_t *file; |
1189 | +} ds_tmp_file_t; |
1190 | + |
1191 | +static ds_ctxt_t *tmpfile_init(const char *root); |
1192 | +static ds_file_t *tmpfile_open(ds_ctxt_t *ctxt, const char *path, |
1193 | + MY_STAT *mystat); |
1194 | +static int tmpfile_write(ds_file_t *file, const void *buf, size_t len); |
1195 | +static int tmpfile_close(ds_file_t *file); |
1196 | +static void tmpfile_deinit(ds_ctxt_t *ctxt); |
1197 | + |
1198 | +datasink_t datasink_tmpfile = { |
1199 | + &tmpfile_init, |
1200 | + &tmpfile_open, |
1201 | + &tmpfile_write, |
1202 | + &tmpfile_close, |
1203 | + &tmpfile_deinit |
1204 | +}; |
1205 | + |
1206 | +static ds_ctxt_t * |
1207 | +tmpfile_init(const char *root) |
1208 | +{ |
1209 | + ds_ctxt_t *ctxt; |
1210 | + ds_tmpfile_ctxt_t *tmpfile_ctxt; |
1211 | + |
1212 | + ctxt = my_malloc(sizeof(ds_ctxt_t) + sizeof(ds_tmpfile_ctxt_t), |
1213 | + MYF(MY_FAE)); |
1214 | + tmpfile_ctxt = (ds_tmpfile_ctxt_t *) (ctxt + 1); |
1215 | + tmpfile_ctxt->file_list = NULL; |
1216 | + if (pthread_mutex_init(&tmpfile_ctxt->mutex, NULL)) { |
1217 | + |
1218 | + MY_FREE(ctxt); |
1219 | + return NULL; |
1220 | + } |
1221 | + |
1222 | + ctxt->ptr = tmpfile_ctxt; |
1223 | + ctxt->root = my_strdup(root, MYF(MY_FAE)); |
1224 | + |
1225 | + return ctxt; |
1226 | +} |
1227 | + |
1228 | +static ds_file_t * |
1229 | +tmpfile_open(ds_ctxt_t *ctxt, const char *path, |
1230 | + MY_STAT *mystat) |
1231 | +{ |
1232 | + ds_tmpfile_ctxt_t *tmpfile_ctxt; |
1233 | + char tmp_path[FN_REFLEN]; |
1234 | + ds_tmp_file_t *tmp_file; |
1235 | + ds_file_t *file; |
1236 | + size_t path_len; |
1237 | + File fd; |
1238 | + |
1239 | + /* Create a temporary file in tmpdir. The file will be automatically |
1240 | + removed on close. Code copied from mysql_tmpfile(). */ |
1241 | + fd = create_temp_file(tmp_path, my_tmpdir(&mysql_tmpdir_list), |
1242 | + "xbtemp", |
1243 | +#ifdef __WIN__ |
1244 | + O_BINARY | O_TRUNC | O_SEQUENTIAL | |
1245 | + O_TEMPORARY | O_SHORT_LIVED | |
1246 | +#endif /* __WIN__ */ |
1247 | + O_CREAT | O_EXCL | O_RDWR, |
1248 | + MYF(MY_WME)); |
1249 | + |
1250 | +#ifndef __WIN__ |
1251 | + if (fd >= 0) { |
1252 | + /* On Windows, open files cannot be removed, but files can be |
1253 | + created with the O_TEMPORARY flag to the same effect |
1254 | + ("delete on close"). */ |
1255 | + unlink(path); |
1256 | + } |
1257 | +#endif /* !__WIN__ */ |
1258 | + |
1259 | + if (fd < 0) { |
1260 | + return NULL; |
1261 | + } |
1262 | + |
1263 | + path_len = strlen(path) + 1; /* terminating '\0' */ |
1264 | + |
1265 | + file = (ds_file_t *) my_malloc(sizeof(ds_file_t) + |
1266 | + sizeof(ds_tmp_file_t) + path_len, |
1267 | + MYF(MY_FAE)); |
1268 | + |
1269 | + tmp_file = (ds_tmp_file_t *) (file + 1); |
1270 | + tmp_file->file = file; |
1271 | + memcpy(&tmp_file->mystat, mystat, sizeof(MY_STAT)); |
1272 | + /* Save a copy of 'path', since it may not be accessible later */ |
1273 | + tmp_file->orig_path = (char *) tmp_file + sizeof(ds_tmp_file_t); |
1274 | + |
1275 | + tmp_file->fd = fd; |
1276 | + memcpy(tmp_file->orig_path, path, path_len); |
1277 | + |
1278 | + /* Store the real temporary file name in file->path */ |
1279 | + file->path = my_strdup(tmp_path, MYF(MY_FAE)); |
1280 | + file->ptr = tmp_file; |
1281 | + |
1282 | + /* Store the file object in the list to be piped later */ |
1283 | + tmpfile_ctxt = (ds_tmpfile_ctxt_t *) ctxt->ptr; |
1284 | + tmp_file->list.data = tmp_file; |
1285 | + |
1286 | + pthread_mutex_lock(&tmpfile_ctxt->mutex); |
1287 | + tmpfile_ctxt->file_list = list_add(tmpfile_ctxt->file_list, |
1288 | + &tmp_file->list); |
1289 | + pthread_mutex_unlock(&tmpfile_ctxt->mutex); |
1290 | + |
1291 | + return file; |
1292 | +} |
1293 | + |
1294 | +static int |
1295 | +tmpfile_write(ds_file_t *file, const void *buf, size_t len) |
1296 | +{ |
1297 | + File fd = ((ds_tmp_file_t *) file->ptr)->fd; |
1298 | + |
1299 | + if (!my_write(fd, buf, len, MYF(MY_WME | MY_NABP))) { |
1300 | + posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED); |
1301 | + return 0; |
1302 | + } |
1303 | + |
1304 | + return 1; |
1305 | +} |
1306 | + |
1307 | +static int |
1308 | +tmpfile_close(ds_file_t *file) |
1309 | +{ |
1310 | + /* Do nothing -- we will close (and thus remove) the file after piping |
1311 | + it to the destination datasink in tmpfile_deinit(). */ |
1312 | + |
1313 | + MY_FREE(file->path); |
1314 | + |
1315 | + return 0; |
1316 | +} |
1317 | + |
1318 | +static void |
1319 | +tmpfile_deinit(ds_ctxt_t *ctxt) |
1320 | +{ |
1321 | + LIST *list; |
1322 | + ds_tmpfile_ctxt_t *tmpfile_ctxt; |
1323 | + MY_STAT mystat; |
1324 | + ds_tmp_file_t *tmp_file; |
1325 | + ds_file_t *dst_file; |
1326 | + ds_ctxt_t *pipe_ctxt; |
1327 | + void *buf = NULL; |
1328 | + const size_t buf_size = 1024 * 1024; |
1329 | + size_t bytes; |
1330 | + |
1331 | + pipe_ctxt = ctxt->pipe_ctxt; |
1332 | + xb_a(pipe_ctxt != NULL); |
1333 | + |
1334 | + buf = my_malloc(buf_size, MYF(MY_FAE)); |
1335 | + |
1336 | + tmpfile_ctxt = (ds_tmpfile_ctxt_t *) ctxt->ptr; |
1337 | + list = tmpfile_ctxt->file_list; |
1338 | + |
1339 | + /* Walk the files in the order they have been added */ |
1340 | + list = list_reverse(list); |
1341 | + while (list != NULL) { |
1342 | + tmp_file = list->data; |
1343 | + /* Stat the file to replace size and mtime on the original |
1344 | + * mystat struct */ |
1345 | + if (my_fstat(tmp_file->fd, &mystat, MYF(0))) { |
1346 | + msg("error: my_fstat() failed.\n"); |
1347 | + exit(EXIT_FAILURE); |
1348 | + } |
1349 | + tmp_file->mystat.st_size = mystat.st_size; |
1350 | + tmp_file->mystat.st_mtime = mystat.st_mtime; |
1351 | + |
1352 | + dst_file = ds_open(pipe_ctxt, tmp_file->orig_path, |
1353 | + &tmp_file->mystat); |
1354 | + if (dst_file == NULL) { |
1355 | + msg("error: could not stream a temporary file to " |
1356 | + "'%s'\n", tmp_file->orig_path); |
1357 | + exit(EXIT_FAILURE); |
1358 | + } |
1359 | + |
1360 | + /* copy to the destination datasink */ |
1361 | + posix_fadvise(tmp_file->fd, 0, 0, POSIX_FADV_SEQUENTIAL); |
1362 | + if (my_seek(tmp_file->fd, 0, SEEK_SET, MYF(0)) == |
1363 | + MY_FILEPOS_ERROR) { |
1364 | + msg("error: my_seek() failed for '%s', errno = %d.\n", |
1365 | + tmp_file->file->path, my_errno); |
1366 | + exit(EXIT_FAILURE); |
1367 | + } |
1368 | + while ((bytes = my_read(tmp_file->fd, buf, buf_size, |
1369 | + MYF(MY_WME))) > 0) { |
1370 | + posix_fadvise(tmp_file->fd, 0, 0, POSIX_FADV_DONTNEED); |
1371 | + if (ds_write(dst_file, buf, bytes)) { |
1372 | + msg("error: cannot write to stream for '%s'.\n", |
1373 | + tmp_file->orig_path); |
1374 | + exit(EXIT_FAILURE); |
1375 | + } |
1376 | + } |
1377 | + if (bytes == (size_t) -1) { |
1378 | + exit(EXIT_FAILURE); |
1379 | + } |
1380 | + |
1381 | + my_close(tmp_file->fd, MYF(MY_WME)); |
1382 | + ds_close(dst_file); |
1383 | + |
1384 | + list = list_rest(list); |
1385 | + MY_FREE(tmp_file->file); |
1386 | + } |
1387 | + |
1388 | + pthread_mutex_destroy(&tmpfile_ctxt->mutex); |
1389 | + |
1390 | + MY_FREE(buf); |
1391 | + MY_FREE(ctxt->root); |
1392 | + MY_FREE(ctxt); |
1393 | +} |
1394 | |
1395 | === added file 'src/ds_tmpfile.h' |
1396 | --- src/ds_tmpfile.h 1970-01-01 00:00:00 +0000 |
1397 | +++ src/ds_tmpfile.h 2012-05-24 09:35:22 +0000 |
1398 | @@ -0,0 +1,28 @@ |
1399 | +/****************************************************** |
1400 | +Copyright (c) 2012 Percona Inc. |
1401 | + |
1402 | +tmpfile datasink for XtraBackup. |
1403 | + |
1404 | +This program is free software; you can redistribute it and/or modify |
1405 | +it under the terms of the GNU General Public License as published by |
1406 | +the Free Software Foundation; version 2 of the License. |
1407 | + |
1408 | +This program is distributed in the hope that it will be useful, |
1409 | +but WITHOUT ANY WARRANTY; without even the implied warranty of |
1410 | +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1411 | +GNU General Public License for more details. |
1412 | + |
1413 | +You should have received a copy of the GNU General Public License |
1414 | +along with this program; if not, write to the Free Software |
1415 | +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
1416 | + |
1417 | +*******************************************************/ |
1418 | + |
1419 | +#ifndef DS_TMPFILE_H |
1420 | +#define DS_TMPFILE_H |
1421 | + |
1422 | +#include "datasink.h" |
1423 | + |
1424 | +extern datasink_t datasink_tmpfile; |
1425 | + |
1426 | +#endif |
1427 | |
1428 | === added file 'src/fil_cur.c' |
1429 | --- src/fil_cur.c 1970-01-01 00:00:00 +0000 |
1430 | +++ src/fil_cur.c 2012-05-24 09:35:22 +0000 |
1431 | @@ -0,0 +1,266 @@ |
1432 | +/****************************************************** |
1433 | +XtraBackup: hot backup tool for InnoDB |
1434 | +(c) 2009-2012 Percona Inc. |
1435 | +Originally Created 3/3/2009 Yasufumi Kinoshita |
1436 | +Written by Alexey Kopytov, Aleksandr Kuzminsky, Stewart Smith, Vadim Tkachenko, |
1437 | +Yasufumi Kinoshita, Ignacio Nin and Baron Schwartz. |
1438 | + |
1439 | +This program is free software; you can redistribute it and/or modify |
1440 | +it under the terms of the GNU General Public License as published by |
1441 | +the Free Software Foundation; version 2 of the License. |
1442 | + |
1443 | +This program is distributed in the hope that it will be useful, |
1444 | +but WITHOUT ANY WARRANTY; without even the implied warranty of |
1445 | +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1446 | +GNU General Public License for more details. |
1447 | + |
1448 | +You should have received a copy of the GNU General Public License |
1449 | +along with this program; if not, write to the Free Software |
1450 | +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
1451 | + |
1452 | +*******************************************************/ |
1453 | + |
1454 | +/* Source file cursor implementation */ |
1455 | + |
1456 | +#include <my_base.h> |
1457 | +#include "innodb_int.h" |
1458 | +#include <buf0buf.h> |
1459 | +#include <fsp0types.h> |
1460 | +#include "fil_cur.h" |
1461 | +#include "common.h" |
1462 | + |
1463 | +/* Size of read buffer in pages */ |
1464 | +#define XB_FIL_CUR_PAGES 64 |
1465 | + |
1466 | +/************************************************************************ |
1467 | +Open a source file cursor. |
1468 | + |
1469 | +@return XB_FIL_CUR_SUCCESS on success, XB_FIL_CUR_SKIP if the source file must |
1470 | +be skipped and XB_FIL_CUR_ERROR on error. */ |
1471 | +xb_fil_cur_result_t |
1472 | +xb_fil_cur_open( |
1473 | +/*============*/ |
1474 | + xb_fil_cur_t* cursor, /*!< out: source file cursor */ |
1475 | + fil_node_t* node, /*!< in: source tablespace node */ |
1476 | + uint thread_n) /*!< thread number for diagnostics */ |
1477 | +{ |
1478 | + ulint page_size; |
1479 | + ulint page_size_shift; |
1480 | + ulint zip_size; |
1481 | + |
1482 | + /* Initialize these first so xb_fil_cur_close() handles them correctly |
1483 | + in case of error */ |
1484 | + cursor->orig_buf = NULL; |
1485 | + cursor->file = XB_FILE_UNDEFINED; |
1486 | + |
1487 | + cursor->is_system = trx_sys_sys_space(node->space->id); |
1488 | + |
1489 | + /* Determine the page size */ |
1490 | +#ifndef INNODB_VERSION_SHORT |
1491 | + zip_size = UNIV_PAGE_SIZE; |
1492 | + page_size = UNIV_PAGE_SIZE; |
1493 | + page_size_shift = UNIV_PAGE_SIZE_SHIFT; |
1494 | +#else |
1495 | + zip_size = fil_space_get_zip_size(node->space->id); |
1496 | + if (zip_size == ULINT_UNDEFINED) { |
1497 | + return(XB_FIL_CUR_SKIP); |
1498 | + } else if (zip_size) { |
1499 | + page_size = zip_size; |
1500 | + page_size_shift = get_bit_shift(page_size); |
1501 | + msg("[%02u] %s is compressed with page size = " |
1502 | + "%lu bytes\n", thread_n, node->name, page_size); |
1503 | + if (page_size_shift < 10 || page_size_shift > 14) { |
1504 | + msg("[%02u] xtrabackup: Error: Invalid " |
1505 | + "page size: %lu.\n", thread_n, page_size); |
1506 | + ut_error; |
1507 | + } |
1508 | + } else { |
1509 | + page_size = UNIV_PAGE_SIZE; |
1510 | + page_size_shift = UNIV_PAGE_SIZE_SHIFT; |
1511 | + } |
1512 | +#endif |
1513 | + cursor->page_size = page_size; |
1514 | + cursor->page_size_shift = page_size_shift; |
1515 | + cursor->zip_size = zip_size; |
1516 | + |
1517 | + /* Make the file path relative to the backup root, |
1518 | + i.e. "ibdata1" for system tablespace or database/table.ibd for |
1519 | + per-table spaces. */ |
1520 | + if (cursor->is_system) { |
1521 | + char *next, *p; |
1522 | + |
1523 | + p = node->name; |
1524 | + while ((next = strstr(p, SRV_PATH_SEPARATOR_STR)) != NULL) { |
1525 | + p = next + 1; |
1526 | + } |
1527 | + strncpy(cursor->path, p, sizeof(cursor->path)); |
1528 | + } else { |
1529 | + /* file per table style "./database/table.ibd" */ |
1530 | + strncpy(cursor->path, node->name, sizeof(cursor->path)); |
1531 | + } |
1532 | + |
1533 | + /* Open the file */ |
1534 | + |
1535 | + if (my_stat(node->name, &cursor->statinfo, MYF(MY_WME)) == NULL) { |
1536 | + msg("[%02u] xtrabackup: Warning: cannot stat %s\n", |
1537 | + thread_n, node->name); |
1538 | + return(XB_FIL_CUR_SKIP); |
1539 | + } |
1540 | + |
1541 | + if (!node->open) { |
1542 | + ibool success; |
1543 | + |
1544 | + cursor->file = |
1545 | + xb_file_create_no_error_handling(node->name, |
1546 | + OS_FILE_OPEN, |
1547 | + OS_FILE_READ_ONLY, |
1548 | + &success); |
1549 | + if (!success) { |
1550 | + /* The following call prints an error message */ |
1551 | + os_file_get_last_error(TRUE); |
1552 | + |
1553 | + msg("[%02u] xtrabackup: Warning: cannot open %s\n" |
1554 | + "[%02u] xtrabackup: Warning: We assume the " |
1555 | + "table was dropped or renamed during " |
1556 | + "xtrabackup execution and ignore the file.\n", |
1557 | + thread_n, node->name, thread_n); |
1558 | + return(XB_FIL_CUR_SKIP); |
1559 | + } |
1560 | + |
1561 | + xb_file_set_nocache(cursor->file, node->name, "OPEN"); |
1562 | + } else { |
1563 | + cursor->file = node->handle; |
1564 | + } |
1565 | + posix_fadvise(cursor->file, 0, 0, POSIX_FADV_SEQUENTIAL); |
1566 | + posix_fadvise(cursor->file, 0, 0, POSIX_FADV_DONTNEED); |
1567 | + |
1568 | + /* Allocate read buffer */ |
1569 | + cursor->buf_size = XB_FIL_CUR_PAGES * page_size; |
1570 | + cursor->orig_buf = ut_malloc(cursor->buf_size + UNIV_PAGE_SIZE); |
1571 | + cursor->buf = ut_align(cursor->orig_buf, UNIV_PAGE_SIZE); |
1572 | + |
1573 | + cursor->offset = 0; |
1574 | + cursor->buf_read = 0; |
1575 | + cursor->buf_npages = 0; |
1576 | + cursor->buf_offset = 0; |
1577 | + cursor->buf_page_no = 0; |
1578 | + cursor->thread_n = thread_n; |
1579 | + |
1580 | + return(XB_FIL_CUR_SUCCESS); |
1581 | +} |
1582 | + |
1583 | +/************************************************************************ |
1584 | +Reads and verifies the next block of pages from the source |
1585 | +file. Positions the cursor after the last read non-corrupted page. |
1586 | + |
1587 | +@return XB_FIL_CUR_SUCCESS if some have been read successfully, XB_FIL_CUR_EOF |
1588 | +if there are no more pages to read and XB_FIL_CUR_ERROR on error. */ |
1589 | +xb_fil_cur_result_t |
1590 | +xb_fil_cur_read( |
1591 | +/*============*/ |
1592 | + xb_fil_cur_t* cursor) /*!< in/out: source file cursor */ |
1593 | +{ |
1594 | + ibool success; |
1595 | + ulint page_size; |
1596 | + ulint offset_high; |
1597 | + ulint offset_low; |
1598 | + byte* page; |
1599 | + ulint i; |
1600 | + ulint npages; |
1601 | + ulint retry_count; |
1602 | + xb_fil_cur_result_t ret; |
1603 | + IB_INT64 to_read; |
1604 | + |
1605 | + page_size = cursor->page_size; |
1606 | + |
1607 | + offset_high = (ulint) (cursor->offset >> 32); |
1608 | + offset_low = (ulint) (cursor->offset & 0xFFFFFFFFUL); |
1609 | + |
1610 | + to_read = (IB_INT64) cursor->statinfo.st_size - cursor->offset; |
1611 | + |
1612 | + if (to_read == 0LL) { |
1613 | + return(XB_FIL_CUR_EOF); |
1614 | + } |
1615 | + |
1616 | + if (to_read > (IB_INT64) cursor->buf_size) { |
1617 | + to_read = (IB_INT64) cursor->buf_size; |
1618 | + } |
1619 | + ut_a(to_read > 0 && to_read <= 0xFFFFFFFFLL); |
1620 | + ut_a(to_read % page_size == 0); |
1621 | + |
1622 | + npages = (ulint) (to_read >> cursor->page_size_shift); |
1623 | + |
1624 | + retry_count = 10; |
1625 | + ret = XB_FIL_CUR_SUCCESS; |
1626 | + |
1627 | +read_retry: |
1628 | + xtrabackup_io_throttling(); |
1629 | + |
1630 | + cursor->buf_read = 0; |
1631 | + cursor->buf_npages = 0; |
1632 | + cursor->buf_offset = cursor->offset; |
1633 | + cursor->buf_page_no = (ulint) (cursor->offset >> |
1634 | + cursor->page_size_shift); |
1635 | + |
1636 | + success = os_file_read(cursor->file, cursor->buf, |
1637 | + offset_low, offset_high, to_read); |
1638 | + if (!success) { |
1639 | + return(XB_FIL_CUR_ERROR); |
1640 | + } |
1641 | + |
1642 | + /* check pages for corruption and re-read if necessary. i.e. in case of |
1643 | + partially written pages */ |
1644 | + for (page = cursor->buf, i = 0; i < npages; page += page_size, i++) { |
1645 | + if (xb_buf_page_is_corrupted(page, cursor->zip_size)) |
1646 | + { |
1647 | + ulint page_no = cursor->buf_page_no + i; |
1648 | + |
1649 | + if (cursor->is_system && |
1650 | + page_no >= FSP_EXTENT_SIZE && |
1651 | + page_no < FSP_EXTENT_SIZE * 3) { |
1652 | + /* skip doublewrite buffer pages */ |
1653 | + ut_a(page_size == UNIV_PAGE_SIZE); |
1654 | + msg("[%02lu] xtrabackup: " |
1655 | + "Page %lu is a doublewrite buffer page, " |
1656 | + "skipping.\n", cursor->thread_n, page_no); |
1657 | + } else { |
1658 | + retry_count--; |
1659 | + if (retry_count == 0) { |
1660 | + msg("[%02lu] xtrabackup: " |
1661 | + "Error: failed to read page after " |
1662 | + "10 retries. File %s seems to be " |
1663 | + "corrupted.\n", cursor->thread_n, |
1664 | + cursor->path); |
1665 | + ret = XB_FIL_CUR_ERROR; |
1666 | + break; |
1667 | + } |
1668 | + msg("[%02lu] xtrabackup: " |
1669 | + "Database page corruption detected at page " |
1670 | + "%lu, retrying...\n", cursor->thread_n, |
1671 | + page_no); |
1672 | + goto read_retry; |
1673 | + } |
1674 | + } |
1675 | + cursor->buf_read += page_size; |
1676 | + cursor->buf_npages++; |
1677 | + } |
1678 | + |
1679 | + cursor->offset += page_size * i; |
1680 | + |
1681 | + return(ret); |
1682 | +} |
1683 | + |
1684 | +/************************************************************************ |
1685 | +Close the source file cursor opened with xb_fil_cur_open(). */ |
1686 | +void |
1687 | +xb_fil_cur_close( |
1688 | +/*=============*/ |
1689 | + xb_fil_cur_t *cursor) /*!< in/out: source file cursor */ |
1690 | +{ |
1691 | + if (cursor->orig_buf != NULL) { |
1692 | + ut_free(cursor->orig_buf); |
1693 | + } |
1694 | + if (cursor->file != XB_FILE_UNDEFINED) { |
1695 | + os_file_close(cursor->file); |
1696 | + } |
1697 | +} |
1698 | |
1699 | === added file 'src/fil_cur.h' |
1700 | --- src/fil_cur.h 1970-01-01 00:00:00 +0000 |
1701 | +++ src/fil_cur.h 2012-05-24 09:35:22 +0000 |
1702 | @@ -0,0 +1,95 @@ |
1703 | +/****************************************************** |
1704 | +XtraBackup: hot backup tool for InnoDB |
1705 | +(c) 2009-2012 Percona Inc. |
1706 | +Originally Created 3/3/2009 Yasufumi Kinoshita |
1707 | +Written by Alexey Kopytov, Aleksandr Kuzminsky, Stewart Smith, Vadim Tkachenko, |
1708 | +Yasufumi Kinoshita, Ignacio Nin and Baron Schwartz. |
1709 | + |
1710 | +This program is free software; you can redistribute it and/or modify |
1711 | +it under the terms of the GNU General Public License as published by |
1712 | +the Free Software Foundation; version 2 of the License. |
1713 | + |
1714 | +This program is distributed in the hope that it will be useful, |
1715 | +but WITHOUT ANY WARRANTY; without even the implied warranty of |
1716 | +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1717 | +GNU General Public License for more details. |
1718 | + |
1719 | +You should have received a copy of the GNU General Public License |
1720 | +along with this program; if not, write to the Free Software |
1721 | +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
1722 | + |
1723 | +*******************************************************/ |
1724 | + |
1725 | +/* Source file cursor interface */ |
1726 | + |
1727 | +#ifndef FIL_CUR_H |
1728 | +#define FIL_CUR_H |
1729 | + |
1730 | +#include <my_dir.h> |
1731 | +#include "innodb_int.h" |
1732 | + |
1733 | +typedef struct { |
1734 | + os_file_t file; /*!< source file handle */ |
1735 | + char path[FN_REFLEN];/*!< normalized file path */ |
1736 | + MY_STAT statinfo; /*!< information about the file */ |
1737 | + ulint zip_size; /*!< compressed page size in bytes or 0 |
1738 | + for uncompressed pages */ |
1739 | + ulint page_size; /*!< = zip_size for compressed pages or |
1740 | + UNIV_PAGE_SIZE for uncompressed ones */ |
1741 | + ulint page_size_shift;/*!< bit shift corresponding to |
1742 | + page_size */ |
1743 | + IB_INT64 offset; /*!< current file offset in bytes */ |
1744 | + my_bool is_system; /*!< TRUE for system tablespace, FALSE |
1745 | + otherwise */ |
1746 | + byte* orig_buf; /*!< read buffer */ |
1747 | + byte* buf; /*!< aligned pointer for orig_buf */ |
1748 | + ulint buf_size; /*!< buffer size in bytes */ |
1749 | + ulint buf_read; /*!< number of read bytes in buffer |
1750 | + after the last cursor read */ |
1751 | + ulint buf_npages; /*!< number of pages in buffer after the |
1752 | + last cursor read */ |
1753 | + IB_INT64 buf_offset; /*!< file offset of the first page in |
1754 | + buffer */ |
1755 | + ulint buf_page_no; /*!< number of the first page in |
1756 | + buffer */ |
1757 | + ulint thread_n; /*!< thread number for diagnostics */ |
1758 | +} xb_fil_cur_t; |
1759 | + |
1760 | +typedef enum { |
1761 | + XB_FIL_CUR_SUCCESS, |
1762 | + XB_FIL_CUR_SKIP, |
1763 | + XB_FIL_CUR_ERROR, |
1764 | + XB_FIL_CUR_EOF |
1765 | +} xb_fil_cur_result_t; |
1766 | + |
1767 | +/************************************************************************ |
1768 | +Open a source file cursor. |
1769 | + |
1770 | +@return XB_FIL_CUR_SUCCESS on success, XB_FIL_CUR_SKIP if the source file must |
1771 | +be skipped and XB_FIL_CUR_ERROR on error. */ |
1772 | +xb_fil_cur_result_t |
1773 | +xb_fil_cur_open( |
1774 | +/*============*/ |
1775 | + xb_fil_cur_t* cursor, /*!< out: source file cursor */ |
1776 | + fil_node_t* node, /*!< in: source tablespace node */ |
1777 | + uint thread_n); /*!< thread number for diagnostics */ |
1778 | + |
1779 | +/************************************************************************ |
1780 | +Reads and verifies the next block of pages from the source |
1781 | +file. Positions the cursor after the last read non-corrupted page. |
1782 | + |
1783 | +@return XB_FIL_CUR_SUCCESS if some have been read successfully, XB_FIL_CUR_EOF |
1784 | +if there are no more pages to read and XB_FIL_CUR_ERROR on error. */ |
1785 | +xb_fil_cur_result_t |
1786 | +xb_fil_cur_read( |
1787 | +/*============*/ |
1788 | + xb_fil_cur_t* cursor); /*!< in/out: source file cursor */ |
1789 | + |
1790 | +/************************************************************************ |
1791 | +Close the source file cursor opened with xb_fil_cur_open(). */ |
1792 | +void |
1793 | +xb_fil_cur_close( |
1794 | +/*=============*/ |
1795 | + xb_fil_cur_t *cursor); /*!< in/out: source file cursor */ |
1796 | + |
1797 | +#endif |
1798 | |
1799 | === added file 'src/innodb_int.c' |
1800 | --- src/innodb_int.c 1970-01-01 00:00:00 +0000 |
1801 | +++ src/innodb_int.c 2012-05-24 09:35:22 +0000 |
1802 | @@ -0,0 +1,791 @@ |
1803 | +/****************************************************** |
1804 | +XtraBackup: hot backup tool for InnoDB |
1805 | +(c) 2009-2012 Percona Inc. |
1806 | +Originally Created 3/3/2009 Yasufumi Kinoshita |
1807 | +Written by Alexey Kopytov, Aleksandr Kuzminsky, Stewart Smith, Vadim Tkachenko, |
1808 | +Yasufumi Kinoshita, Ignacio Nin and Baron Schwartz. |
1809 | + |
1810 | +This program is free software; you can redistribute it and/or modify |
1811 | +it under the terms of the GNU General Public License as published by |
1812 | +the Free Software Foundation; version 2 of the License. |
1813 | + |
1814 | +This program is distributed in the hope that it will be useful, |
1815 | +but WITHOUT ANY WARRANTY; without even the implied warranty of |
1816 | +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1817 | +GNU General Public License for more details. |
1818 | + |
1819 | +You should have received a copy of the GNU General Public License |
1820 | +along with this program; if not, write to the Free Software |
1821 | +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
1822 | + |
1823 | +*******************************************************/ |
1824 | + |
1825 | +/* InnoDB portability helpers and interface to internal functions */ |
1826 | + |
1827 | +#include <my_base.h> |
1828 | +#include <mysql_com.h> |
1829 | +#include "innodb_int.h" |
1830 | +#include <srv0srv.h> |
1831 | +#include <ha_prototypes.h> |
1832 | +#include <trx0trx.h> |
1833 | +#include "common.h" |
1834 | + |
1835 | +extern long innobase_lock_wait_timeout; |
1836 | + |
1837 | +char *opt_mysql_tmpdir = NULL; |
1838 | +MY_TMPDIR mysql_tmpdir_list; |
1839 | + |
1840 | + |
1841 | +/****************************************************************//** |
1842 | +A simple function to open or create a file. |
1843 | +@return own: handle to the file, not defined if error, error number |
1844 | +can be retrieved with os_file_get_last_error */ |
1845 | +os_file_t |
1846 | +xb_file_create_no_error_handling( |
1847 | +/*=============================*/ |
1848 | + const char* name, /*!< in: name of the file or path as a |
1849 | + null-terminated string */ |
1850 | + ulint create_mode,/*!< in: OS_FILE_OPEN if an existing file |
1851 | + is opened (if does not exist, error), or |
1852 | + OS_FILE_CREATE if a new file is created |
1853 | + (if exists, error) */ |
1854 | + ulint access_type,/*!< in: OS_FILE_READ_ONLY, |
1855 | + OS_FILE_READ_WRITE, or |
1856 | + OS_FILE_READ_ALLOW_DELETE; the last option is |
1857 | + used by a backup program reading the file */ |
1858 | + ibool* success)/*!< out: TRUE if succeed, FALSE if error */ |
1859 | +{ |
1860 | +#if MYSQL_VERSION_ID > 50500 |
1861 | + return os_file_create_simple_no_error_handling( |
1862 | + 0, /* innodb_file_data_key */ |
1863 | + name, create_mode, access_type, success); |
1864 | +#else |
1865 | + return os_file_create_simple_no_error_handling( |
1866 | + name, create_mode, access_type, success); |
1867 | +#endif |
1868 | +} |
1869 | + |
1870 | +/****************************************************************//** |
1871 | +Opens an existing file or creates a new. |
1872 | +@return own: handle to the file, not defined if error, error number |
1873 | +can be retrieved with os_file_get_last_error */ |
1874 | +os_file_t |
1875 | +xb_file_create( |
1876 | +/*===========*/ |
1877 | + const char* name, /*!< in: name of the file or path as a |
1878 | + null-terminated string */ |
1879 | + ulint create_mode,/*!< in: OS_FILE_OPEN if an existing file |
1880 | + is opened (if does not exist, error), or |
1881 | + OS_FILE_CREATE if a new file is created |
1882 | + (if exists, error), |
1883 | + OS_FILE_OVERWRITE if a new file is created |
1884 | + or an old overwritten; |
1885 | + OS_FILE_OPEN_RAW, if a raw device or disk |
1886 | + partition should be opened */ |
1887 | + ulint purpose,/*!< in: OS_FILE_AIO, if asynchronous, |
1888 | + non-buffered i/o is desired, |
1889 | + OS_FILE_NORMAL, if any normal file; |
1890 | + NOTE that it also depends on type, os_aio_.. |
1891 | + and srv_.. variables whether we really use |
1892 | + async i/o or unbuffered i/o: look in the |
1893 | + function source code for the exact rules */ |
1894 | + ulint type, /*!< in: OS_DATA_FILE or OS_LOG_FILE */ |
1895 | + ibool* success)/*!< out: TRUE if succeed, FALSE if error */ |
1896 | +{ |
1897 | +#if MYSQL_VERSION_ID > 50500 |
1898 | + return os_file_create(0 /* innodb_file_data_key */, |
1899 | + name, create_mode, purpose, type, success); |
1900 | +#else |
1901 | + return os_file_create(name, create_mode, purpose, type, success); |
1902 | +#endif |
1903 | +} |
1904 | + |
1905 | +/***********************************************************************//** |
1906 | +Renames a file (can also move it to another directory). It is safest that the |
1907 | +file is closed before calling this function. |
1908 | +@return TRUE if success */ |
1909 | +ibool |
1910 | +xb_file_rename( |
1911 | +/*===========*/ |
1912 | + const char* oldpath,/*!< in: old file path as a null-terminated |
1913 | + string */ |
1914 | + const char* newpath)/*!< in: new file path */ |
1915 | +{ |
1916 | +#if MYSQL_VERSION_ID > 50500 |
1917 | + return os_file_rename( |
1918 | + 0 /* innodb_file_data_key */, oldpath, newpath); |
1919 | +#else |
1920 | + return os_file_rename(oldpath, newpath); |
1921 | +#endif |
1922 | +} |
1923 | + |
1924 | +void |
1925 | +xb_file_set_nocache( |
1926 | +/*================*/ |
1927 | + os_file_t fd, /* in: file descriptor to alter */ |
1928 | + const char* file_name, /* in: used in the diagnostic message */ |
1929 | + const char* operation_name) /* in: used in the diagnostic message, |
1930 | + we call os_file_set_nocache() |
1931 | + immediately after opening or creating |
1932 | + a file, so this is either "open" or |
1933 | + "create" */ |
1934 | +{ |
1935 | +#ifndef __WIN__ |
1936 | + if (srv_unix_file_flush_method == SRV_UNIX_O_DIRECT) { |
1937 | + os_file_set_nocache(fd, file_name, operation_name); |
1938 | + } |
1939 | +#endif |
1940 | +} |
1941 | + |
1942 | +/***********************************************************************//** |
1943 | +Compatibility wrapper around os_file_flush(). |
1944 | +@return TRUE if success */ |
1945 | +ibool |
1946 | +xb_file_flush( |
1947 | +/*==========*/ |
1948 | + os_file_t file) /*!< in, own: handle to a file */ |
1949 | +{ |
1950 | +#ifdef XTRADB_BASED |
1951 | + return os_file_flush(file, TRUE); |
1952 | +#else |
1953 | + return os_file_flush(file); |
1954 | +#endif |
1955 | +} |
1956 | + |
1957 | +void |
1958 | +innobase_invalidate_query_cache( |
1959 | + trx_t* trx, |
1960 | +#ifndef INNODB_VERSION_SHORT |
1961 | + char* full_name, |
1962 | +#else |
1963 | + const char* full_name, |
1964 | +#endif |
1965 | + ulint full_name_len) |
1966 | +{ |
1967 | + (void)trx; |
1968 | + (void)full_name; |
1969 | + (void)full_name_len; |
1970 | + /* do nothing */ |
1971 | +} |
1972 | + |
1973 | +int |
1974 | +mysql_get_identifier_quote_char( |
1975 | + trx_t* trx, |
1976 | + const char* name, |
1977 | + ulint namelen) |
1978 | +{ |
1979 | + (void)trx; |
1980 | + (void)name; |
1981 | + (void)namelen; |
1982 | + return '"'; |
1983 | +} |
1984 | + |
1985 | +void |
1986 | +innobase_print_identifier( |
1987 | + FILE* f, |
1988 | + trx_t* trx __attribute__((unused)), |
1989 | + ibool table_id __attribute__((unused)), |
1990 | + const char* name, |
1991 | + ulint namelen) |
1992 | +{ |
1993 | + const char* s = name; |
1994 | + const char* e = s + namelen; |
1995 | + int q; |
1996 | + |
1997 | + q = '"'; |
1998 | + |
1999 | + putc(q, f); |
2000 | + while (s < e) { |
2001 | + int c = *s++; |
2002 | + if (c == q) { |
2003 | + putc(c, f); |
2004 | + } |
2005 | + putc(c, f); |
2006 | + } |
2007 | + putc(q, f); |
2008 | +} |
2009 | + |
2010 | +/**********************************************************************//** |
2011 | +It should be safe to use lower_case_table_names=0 for xtrabackup. If it causes |
2012 | +any problems, we can add the lower_case_table_names option to xtrabackup |
2013 | +later. |
2014 | +@return 0 */ |
2015 | +ulint |
2016 | +innobase_get_lower_case_table_names(void) |
2017 | +/*=====================================*/ |
2018 | +{ |
2019 | + return(0); |
2020 | +} |
2021 | + |
2022 | +/******************************************************************//** |
2023 | +Strip dir name from a full path name and return only the file name |
2024 | +@return file name or "null" if no file name */ |
2025 | +const char* |
2026 | +innobase_basename( |
2027 | +/*==============*/ |
2028 | + const char* path_name) /*!< in: full path name */ |
2029 | +{ |
2030 | + const char* name = base_name(path_name); |
2031 | + |
2032 | + return((name) ? name : "null"); |
2033 | +} |
2034 | + |
2035 | +/*****************************************************************//** |
2036 | +Convert an SQL identifier to the MySQL system_charset_info (UTF-8) |
2037 | +and quote it if needed. |
2038 | +@return pointer to the end of buf */ |
2039 | +static |
2040 | +char* |
2041 | +innobase_convert_identifier( |
2042 | +/*========================*/ |
2043 | + char* buf, /*!< out: buffer for converted identifier */ |
2044 | + ulint buflen, /*!< in: length of buf, in bytes */ |
2045 | + const char* id, /*!< in: identifier to convert */ |
2046 | + ulint idlen, /*!< in: length of id, in bytes */ |
2047 | + void* thd __attribute__((unused)), |
2048 | + /*!< in: MySQL connection thread, or NULL */ |
2049 | + ibool file_id __attribute__((unused))) |
2050 | + /*!< in: TRUE=id is a table or database name; |
2051 | + FALSE=id is an UTF-8 string */ |
2052 | +{ |
2053 | + const char* s = id; |
2054 | + int q; |
2055 | + |
2056 | + /* See if the identifier needs to be quoted. */ |
2057 | + q = '"'; |
2058 | + |
2059 | + if (q == EOF) { |
2060 | + if (UNIV_UNLIKELY(idlen > buflen)) { |
2061 | + idlen = buflen; |
2062 | + } |
2063 | + memcpy(buf, s, idlen); |
2064 | + return(buf + idlen); |
2065 | + } |
2066 | + |
2067 | + /* Quote the identifier. */ |
2068 | + if (buflen < 2) { |
2069 | + return(buf); |
2070 | + } |
2071 | + |
2072 | + *buf++ = q; |
2073 | + buflen--; |
2074 | + |
2075 | + for (; idlen; idlen--) { |
2076 | + int c = *s++; |
2077 | + if (UNIV_UNLIKELY(c == q)) { |
2078 | + if (UNIV_UNLIKELY(buflen < 3)) { |
2079 | + break; |
2080 | + } |
2081 | + |
2082 | + *buf++ = c; |
2083 | + *buf++ = c; |
2084 | + buflen -= 2; |
2085 | + } else { |
2086 | + if (UNIV_UNLIKELY(buflen < 2)) { |
2087 | + break; |
2088 | + } |
2089 | + |
2090 | + *buf++ = c; |
2091 | + buflen--; |
2092 | + } |
2093 | + } |
2094 | + |
2095 | + *buf++ = q; |
2096 | + return(buf); |
2097 | +} |
2098 | + |
2099 | +/*****************************************************************//** |
2100 | +Convert a table or index name to the MySQL system_charset_info (UTF-8) |
2101 | +and quote it if needed. |
2102 | +@return pointer to the end of buf */ |
2103 | +char* |
2104 | +innobase_convert_name( |
2105 | +/*==================*/ |
2106 | + char* buf, /*!< out: buffer for converted identifier */ |
2107 | + ulint buflen, /*!< in: length of buf, in bytes */ |
2108 | + const char* id, /*!< in: identifier to convert */ |
2109 | + ulint idlen, /*!< in: length of id, in bytes */ |
2110 | + void* thd, /*!< in: MySQL connection thread, or NULL */ |
2111 | + ibool table_id)/*!< in: TRUE=id is a table or database name; |
2112 | + FALSE=id is an index name */ |
2113 | +{ |
2114 | + char* s = buf; |
2115 | + const char* bufend = buf + buflen; |
2116 | + |
2117 | + if (table_id) { |
2118 | + const char* slash = (const char*) memchr(id, '/', idlen); |
2119 | + if (!slash) { |
2120 | + |
2121 | + goto no_db_name; |
2122 | + } |
2123 | + |
2124 | + /* Print the database name and table name separately. */ |
2125 | + s = innobase_convert_identifier(s, bufend - s, id, slash - id, |
2126 | + thd, TRUE); |
2127 | + if (UNIV_LIKELY(s < bufend)) { |
2128 | + *s++ = '.'; |
2129 | + s = innobase_convert_identifier(s, bufend - s, |
2130 | + slash + 1, idlen |
2131 | + - (slash - id) - 1, |
2132 | + thd, TRUE); |
2133 | + } |
2134 | +#ifdef INNODB_VERSION_SHORT |
2135 | + } else if (UNIV_UNLIKELY(*id == TEMP_INDEX_PREFIX)) { |
2136 | + /* Temporary index name (smart ALTER TABLE) */ |
2137 | + const char temp_index_suffix[]= "--temporary--"; |
2138 | + |
2139 | + s = innobase_convert_identifier(buf, buflen, id + 1, idlen - 1, |
2140 | + thd, FALSE); |
2141 | + if (s - buf + (sizeof temp_index_suffix - 1) < buflen) { |
2142 | + memcpy(s, temp_index_suffix, |
2143 | + sizeof temp_index_suffix - 1); |
2144 | + s += sizeof temp_index_suffix - 1; |
2145 | + } |
2146 | +#endif |
2147 | + } else { |
2148 | +no_db_name: |
2149 | + s = innobase_convert_identifier(buf, buflen, id, idlen, |
2150 | + thd, table_id); |
2151 | + } |
2152 | + |
2153 | + return(s); |
2154 | + |
2155 | +} |
2156 | + |
2157 | +ibool |
2158 | +trx_is_interrupted( |
2159 | + trx_t* trx) |
2160 | +{ |
2161 | + (void)trx; |
2162 | + /* There are no mysql_thd */ |
2163 | + return(FALSE); |
2164 | +} |
2165 | + |
2166 | +int |
2167 | +innobase_mysql_cmp( |
2168 | + int mysql_type, |
2169 | + uint charset_number, |
2170 | + unsigned char* a, |
2171 | + unsigned int a_length, |
2172 | + unsigned char* b, |
2173 | + unsigned int b_length) |
2174 | +{ |
2175 | + CHARSET_INFO* charset; |
2176 | + enum enum_field_types mysql_tp; |
2177 | + int ret; |
2178 | + |
2179 | + DBUG_ASSERT(a_length != UNIV_SQL_NULL); |
2180 | + DBUG_ASSERT(b_length != UNIV_SQL_NULL); |
2181 | + |
2182 | + mysql_tp = (enum enum_field_types) mysql_type; |
2183 | + |
2184 | + switch (mysql_tp) { |
2185 | + |
2186 | + case MYSQL_TYPE_BIT: |
2187 | + case MYSQL_TYPE_STRING: |
2188 | + case MYSQL_TYPE_VAR_STRING: |
2189 | + case FIELD_TYPE_TINY_BLOB: |
2190 | + case FIELD_TYPE_MEDIUM_BLOB: |
2191 | + case FIELD_TYPE_BLOB: |
2192 | + case FIELD_TYPE_LONG_BLOB: |
2193 | + case MYSQL_TYPE_VARCHAR: |
2194 | + /* Use the charset number to pick the right charset struct for |
2195 | + the comparison. Since the MySQL function get_charset may be |
2196 | + slow before Bar removes the mutex operation there, we first |
2197 | + look at 2 common charsets directly. */ |
2198 | + |
2199 | + if (charset_number == default_charset_info->number) { |
2200 | + charset = default_charset_info; |
2201 | + } else if (charset_number == my_charset_latin1.number) { |
2202 | + charset = &my_charset_latin1; |
2203 | + } else { |
2204 | + charset = get_charset(charset_number, MYF(MY_WME)); |
2205 | + |
2206 | + if (charset == NULL) { |
2207 | + msg("xtrabackup: InnoDB needs charset %lu for " |
2208 | + "doing a comparison, but MySQL cannot " |
2209 | + "find that charset.\n", |
2210 | + (ulong) charset_number); |
2211 | + ut_a(0); |
2212 | + } |
2213 | + } |
2214 | + |
2215 | + /* Starting from 4.1.3, we use strnncollsp() in comparisons of |
2216 | + non-latin1_swedish_ci strings. NOTE that the collation order |
2217 | + changes then: 'b\0\0...' is ordered BEFORE 'b ...'. Users |
2218 | + having indexes on such data need to rebuild their tables! */ |
2219 | + |
2220 | + ret = charset->coll->strnncollsp(charset, |
2221 | + a, a_length, |
2222 | + b, b_length, 0); |
2223 | + if (ret < 0) { |
2224 | + return(-1); |
2225 | + } else if (ret > 0) { |
2226 | + return(1); |
2227 | + } else { |
2228 | + return(0); |
2229 | + } |
2230 | + default: |
2231 | + assert(0); |
2232 | + } |
2233 | + |
2234 | + return(0); |
2235 | +} |
2236 | + |
2237 | +ulint |
2238 | +innobase_get_at_most_n_mbchars( |
2239 | + ulint charset_id, |
2240 | + ulint prefix_len, |
2241 | + ulint data_len, |
2242 | + const char* str) |
2243 | +{ |
2244 | + ulint char_length; /* character length in bytes */ |
2245 | + ulint n_chars; /* number of characters in prefix */ |
2246 | + CHARSET_INFO* charset; /* charset used in the field */ |
2247 | + |
2248 | + charset = get_charset((uint) charset_id, MYF(MY_WME)); |
2249 | + |
2250 | + ut_ad(charset); |
2251 | + ut_ad(charset->mbmaxlen); |
2252 | + |
2253 | + /* Calculate how many characters at most the prefix index contains */ |
2254 | + |
2255 | + n_chars = prefix_len / charset->mbmaxlen; |
2256 | + |
2257 | + /* If the charset is multi-byte, then we must find the length of the |
2258 | + first at most n chars in the string. If the string contains less |
2259 | + characters than n, then we return the length to the end of the last |
2260 | + character. */ |
2261 | + |
2262 | + if (charset->mbmaxlen > 1) { |
2263 | + /* my_charpos() returns the byte length of the first n_chars |
2264 | + characters, or a value bigger than the length of str, if |
2265 | + there were not enough full characters in str. |
2266 | + |
2267 | + Why does the code below work: |
2268 | + Suppose that we are looking for n UTF-8 characters. |
2269 | + |
2270 | + 1) If the string is long enough, then the prefix contains at |
2271 | + least n complete UTF-8 characters + maybe some extra |
2272 | + characters + an incomplete UTF-8 character. No problem in |
2273 | + this case. The function returns the pointer to the |
2274 | + end of the nth character. |
2275 | + |
2276 | + 2) If the string is not long enough, then the string contains |
2277 | + the complete value of a column, that is, only complete UTF-8 |
2278 | + characters, and we can store in the column prefix index the |
2279 | + whole string. */ |
2280 | + |
2281 | + char_length = my_charpos(charset, str, |
2282 | + str + data_len, (int) n_chars); |
2283 | + if (char_length > data_len) { |
2284 | + char_length = data_len; |
2285 | + } |
2286 | + } else { |
2287 | + if (data_len < prefix_len) { |
2288 | + char_length = data_len; |
2289 | + } else { |
2290 | + char_length = prefix_len; |
2291 | + } |
2292 | + } |
2293 | + |
2294 | + return(char_length); |
2295 | +} |
2296 | + |
2297 | +ibool |
2298 | +innobase_query_is_update(void) |
2299 | +{ |
2300 | + msg("xtrabackup: innobase_query_is_update() is called\n"); |
2301 | + return(0); |
2302 | +} |
2303 | + |
2304 | +#ifdef INNODB_VERSION_SHORT |
2305 | +ulint |
2306 | +innobase_raw_format( |
2307 | +/*================*/ |
2308 | + const char* data, /*!< in: raw data */ |
2309 | + ulint data_len, /*!< in: raw data length |
2310 | + in bytes */ |
2311 | + ulint charset_coll, /*!< in: charset collation */ |
2312 | + char* buf, /*!< out: output buffer */ |
2313 | + ulint buf_size) /*!< in: output buffer size |
2314 | + in bytes */ |
2315 | +{ |
2316 | + (void)data; |
2317 | + (void)data_len; |
2318 | + (void)charset_coll; |
2319 | + (void)buf; |
2320 | + (void)buf_size; |
2321 | + |
2322 | + msg("xtrabackup: innobase_raw_format() is called\n"); |
2323 | + return(0); |
2324 | +} |
2325 | + |
2326 | +ulong |
2327 | +thd_lock_wait_timeout( |
2328 | +/*==================*/ |
2329 | + void* thd) /*!< in: thread handle (THD*), or NULL to query |
2330 | + the global innodb_lock_wait_timeout */ |
2331 | +{ |
2332 | + (void)thd; |
2333 | + return(innobase_lock_wait_timeout); |
2334 | +} |
2335 | + |
2336 | +ibool |
2337 | +thd_supports_xa( |
2338 | +/*============*/ |
2339 | + void* thd) /*!< in: thread handle (THD*), or NULL to query |
2340 | + the global innodb_supports_xa */ |
2341 | +{ |
2342 | + (void)thd; |
2343 | + return(FALSE); |
2344 | +} |
2345 | + |
2346 | +ibool |
2347 | +trx_is_strict( |
2348 | +/*==========*/ |
2349 | + trx_t* trx) /*!< in: transaction */ |
2350 | +{ |
2351 | + (void)trx; |
2352 | + return(FALSE); |
2353 | +} |
2354 | + |
2355 | +#ifdef XTRADB_BASED |
2356 | +trx_t* |
2357 | +innobase_get_trx() |
2358 | +{ |
2359 | + return(NULL); |
2360 | +} |
2361 | + |
2362 | +ibool |
2363 | +innobase_get_slow_log() |
2364 | +{ |
2365 | + return(FALSE); |
2366 | +} |
2367 | +#endif |
2368 | +#endif |
2369 | + |
2370 | +ibool |
2371 | +thd_is_replication_slave_thread( |
2372 | + void* thd) |
2373 | +{ |
2374 | + (void)thd; |
2375 | + msg("xtrabackup: thd_is_replication_slave_thread() is called\n"); |
2376 | + return(FALSE); |
2377 | +} |
2378 | + |
2379 | +ibool |
2380 | +thd_has_edited_nontrans_tables( |
2381 | + void* thd) |
2382 | +{ |
2383 | + (void)thd; |
2384 | + msg("xtrabackup: thd_has_edited_nontrans_tables() is called\n"); |
2385 | + return(FALSE); |
2386 | +} |
2387 | + |
2388 | +ibool |
2389 | +thd_is_select( |
2390 | + const void* thd) |
2391 | +{ |
2392 | + (void)thd; |
2393 | + msg("xtrabackup: thd_is_select() is called\n"); |
2394 | + return(FALSE); |
2395 | +} |
2396 | + |
2397 | +void |
2398 | +innobase_mysql_prepare_print_arbitrary_thd(void) |
2399 | +{ |
2400 | + /* do nothing */ |
2401 | +} |
2402 | + |
2403 | +void |
2404 | +innobase_mysql_end_print_arbitrary_thd(void) |
2405 | +{ |
2406 | + /* do nothing */ |
2407 | +} |
2408 | + |
2409 | +void |
2410 | +innobase_mysql_print_thd( |
2411 | + FILE* f, |
2412 | + void* input_thd, |
2413 | + uint max_query_len) |
2414 | +{ |
2415 | + (void)f; |
2416 | + (void)input_thd; |
2417 | + (void)max_query_len; |
2418 | + msg("xtrabackup: innobase_mysql_print_thd() is called\n"); |
2419 | +} |
2420 | + |
2421 | +void |
2422 | +innobase_get_cset_width( |
2423 | + ulint cset, |
2424 | + ulint* mbminlen, |
2425 | + ulint* mbmaxlen) |
2426 | +{ |
2427 | + CHARSET_INFO* cs; |
2428 | + ut_ad(cset < 256); |
2429 | + ut_ad(mbminlen); |
2430 | + ut_ad(mbmaxlen); |
2431 | + |
2432 | + cs = all_charsets[cset]; |
2433 | + if (cs) { |
2434 | + *mbminlen = cs->mbminlen; |
2435 | + *mbmaxlen = cs->mbmaxlen; |
2436 | + } else { |
2437 | + ut_a(cset == 0); |
2438 | + *mbminlen = *mbmaxlen = 0; |
2439 | + } |
2440 | +} |
2441 | + |
2442 | +void |
2443 | +innobase_convert_from_table_id( |
2444 | +#ifdef INNODB_VERSION_SHORT |
2445 | + struct charset_info_st* cs, |
2446 | +#endif |
2447 | + char* to, |
2448 | + const char* from, |
2449 | + ulint len) |
2450 | +{ |
2451 | +#ifdef INNODB_VERSION_SHORT |
2452 | + (void)cs; |
2453 | +#endif |
2454 | + (void)to; |
2455 | + (void)from; |
2456 | + (void)len; |
2457 | + |
2458 | + msg("xtrabackup: innobase_convert_from_table_id() is called\n"); |
2459 | +} |
2460 | + |
2461 | +void |
2462 | +innobase_convert_from_id( |
2463 | +#ifdef INNODB_VERSION_SHORT |
2464 | + struct charset_info_st* cs, |
2465 | +#endif |
2466 | + char* to, |
2467 | + const char* from, |
2468 | + ulint len) |
2469 | +{ |
2470 | +#ifdef INNODB_VERSION_SHORT |
2471 | + (void)cs; |
2472 | +#endif |
2473 | + (void)to; |
2474 | + (void)from; |
2475 | + (void)len; |
2476 | + msg("xtrabackup: innobase_convert_from_id() is called\n"); |
2477 | +} |
2478 | + |
2479 | +int |
2480 | +innobase_strcasecmp( |
2481 | + const char* a, |
2482 | + const char* b) |
2483 | +{ |
2484 | + return(my_strcasecmp(&my_charset_utf8_general_ci, a, b)); |
2485 | +} |
2486 | + |
2487 | +void |
2488 | +innobase_casedn_str( |
2489 | + char* a) |
2490 | +{ |
2491 | + my_casedn_str(&my_charset_utf8_general_ci, a); |
2492 | +} |
2493 | + |
2494 | +struct charset_info_st* |
2495 | +innobase_get_charset( |
2496 | + void* mysql_thd) |
2497 | +{ |
2498 | + (void)mysql_thd; |
2499 | + msg("xtrabackup: innobase_get_charset() is called\n"); |
2500 | + return(NULL); |
2501 | +} |
2502 | + |
2503 | +const char* |
2504 | +innobase_get_stmt( |
2505 | + void* mysql_thd, |
2506 | + size_t* length) |
2507 | +{ |
2508 | + (void)mysql_thd; |
2509 | + (void)length; |
2510 | + msg("xtrabackup: innobase_get_stmt() is called\n"); |
2511 | + return("nothing"); |
2512 | +} |
2513 | + |
2514 | +int |
2515 | +innobase_mysql_tmpfile(void) |
2516 | +{ |
2517 | + char filename[FN_REFLEN]; |
2518 | + int fd2 = -1; |
2519 | + File fd = create_temp_file(filename, my_tmpdir(&mysql_tmpdir_list), "ib", |
2520 | +#ifdef __WIN__ |
2521 | + O_BINARY | O_TRUNC | O_SEQUENTIAL | |
2522 | + O_TEMPORARY | O_SHORT_LIVED | |
2523 | +#endif /* __WIN__ */ |
2524 | + O_CREAT | O_EXCL | O_RDWR, |
2525 | + MYF(MY_WME)); |
2526 | + if (fd >= 0) { |
2527 | +#ifndef __WIN__ |
2528 | + /* On Windows, open files cannot be removed, but files can be |
2529 | + created with the O_TEMPORARY flag to the same effect |
2530 | + ("delete on close"). */ |
2531 | + unlink(filename); |
2532 | +#endif /* !__WIN__ */ |
2533 | + /* Copy the file descriptor, so that the additional resources |
2534 | + allocated by create_temp_file() can be freed by invoking |
2535 | + my_close(). |
2536 | + |
2537 | + Because the file descriptor returned by this function |
2538 | + will be passed to fdopen(), it will be closed by invoking |
2539 | + fclose(), which in turn will invoke close() instead of |
2540 | + my_close(). */ |
2541 | +#ifdef _WIN32 |
2542 | + /* Note that on Windows, the integer returned by mysql_tmpfile |
2543 | + has no relation to C runtime file descriptor. Here, we need |
2544 | + to call my_get_osfhandle to get the HANDLE and then convert it |
2545 | + to C runtime filedescriptor. */ |
2546 | + { |
2547 | + HANDLE hFile = my_get_osfhandle(fd); |
2548 | + HANDLE hDup; |
2549 | + BOOL bOK = |
2550 | + DuplicateHandle(GetCurrentProcess(), hFile, |
2551 | + GetCurrentProcess(), &hDup, 0, |
2552 | + FALSE, DUPLICATE_SAME_ACCESS); |
2553 | + if(bOK) { |
2554 | + fd2 = _open_osfhandle((intptr_t)hDup,0); |
2555 | + } |
2556 | + else { |
2557 | + my_osmaperr(GetLastError()); |
2558 | + fd2 = -1; |
2559 | + } |
2560 | + } |
2561 | +#else |
2562 | + fd2 = dup(fd); |
2563 | +#endif |
2564 | + if (fd2 < 0) { |
2565 | + msg("xtrabackup: Got error %d on dup\n",fd2); |
2566 | + } |
2567 | + my_close(fd, MYF(MY_WME)); |
2568 | + } |
2569 | + return(fd2); |
2570 | +} |
2571 | + |
2572 | +#if MYSQL_VERSION_ID >= 50507 |
2573 | +/* |
2574 | + As of MySQL 5.5.7, InnoDB uses thd_wait plugin service. |
2575 | + We have to provide mock functions to avoid linker errors. |
2576 | +*/ |
2577 | +#include <mysql/plugin.h> |
2578 | +#include <mysql/service_thd_wait.h> |
2579 | + |
2580 | +void thd_wait_begin(MYSQL_THD thd, int wait_type) |
2581 | +{ |
2582 | + (void)thd; |
2583 | + (void)wait_type; |
2584 | + return; |
2585 | +} |
2586 | + |
2587 | +void thd_wait_end(MYSQL_THD thd) |
2588 | +{ |
2589 | + (void)thd; |
2590 | + return; |
2591 | +} |
2592 | + |
2593 | +#endif /* MYSQL_VERSION_ID >= 50507 */ |
2594 | |
2595 | === added file 'src/innodb_int.h' |
2596 | --- src/innodb_int.h 1970-01-01 00:00:00 +0000 |
2597 | +++ src/innodb_int.h 2012-05-24 09:35:22 +0000 |
2598 | @@ -0,0 +1,632 @@ |
2599 | +/****************************************************** |
2600 | +XtraBackup: hot backup tool for InnoDB |
2601 | +(c) 2009-2012 Percona Inc. |
2602 | +Originally Created 3/3/2009 Yasufumi Kinoshita |
2603 | +Written by Alexey Kopytov, Aleksandr Kuzminsky, Stewart Smith, Vadim Tkachenko, |
2604 | +Yasufumi Kinoshita, Ignacio Nin and Baron Schwartz. |
2605 | + |
2606 | +This program is free software; you can redistribute it and/or modify |
2607 | +it under the terms of the GNU General Public License as published by |
2608 | +the Free Software Foundation; version 2 of the License. |
2609 | + |
2610 | +This program is distributed in the hope that it will be useful, |
2611 | +but WITHOUT ANY WARRANTY; without even the implied warranty of |
2612 | +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2613 | +GNU General Public License for more details. |
2614 | + |
2615 | +You should have received a copy of the GNU General Public License |
2616 | +along with this program; if not, write to the Free Software |
2617 | +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
2618 | + |
2619 | +*******************************************************/ |
2620 | + |
2621 | +/* InnoDB portability helpers and interface to internal functions */ |
2622 | + |
2623 | +#ifndef INNODB_INT_H |
2624 | +#define INNODB_INT_H |
2625 | + |
2626 | +#include <my_base.h> |
2627 | +#include <univ.i> |
2628 | +#include <fil0fil.h> |
2629 | +#include <os0file.h> |
2630 | +#include <hash0hash.h> |
2631 | +#include <btr0sea.h> |
2632 | +#include <log0log.h> |
2633 | +#include <log0recv.h> |
2634 | +#include <trx0sys.h> |
2635 | + |
2636 | +#ifndef INNODB_VERSION_SHORT |
2637 | +# define IB_INT64 ib_longlong |
2638 | +# define LSN64 dulint |
2639 | +# define MACH_READ_64 mach_read_from_8 |
2640 | +# define MACH_WRITE_64 mach_write_to_8 |
2641 | +# define OS_MUTEX_CREATE() os_mutex_create(NULL) |
2642 | +# define xb_buf_page_is_corrupted(page, zip_size) buf_page_is_corrupted(page) |
2643 | +#else |
2644 | +# define IB_INT64 ib_int64_t |
2645 | +# define LSN64 ib_uint64_t |
2646 | +# if (MYSQL_VERSION_ID < 50500) |
2647 | +# define MACH_READ_64 mach_read_ull |
2648 | +# define MACH_WRITE_64 mach_write_ull |
2649 | +# define OS_MUTEX_CREATE() os_mutex_create(NULL) |
2650 | +# else |
2651 | +# define MACH_READ_64 mach_read_from_8 |
2652 | +# define MACH_WRITE_64 mach_write_to_8 |
2653 | +# define OS_MUTEX_CREATE() os_mutex_create() |
2654 | +# endif |
2655 | +# define xb_buf_page_is_corrupted(page, zip_size) \ |
2656 | + buf_page_is_corrupted(page, zip_size) |
2657 | +# define ut_dulint_zero 0 |
2658 | +# define ut_dulint_cmp(A, B) (A > B ? 1 : (A == B ? 0 : -1)) |
2659 | +# define ut_dulint_add(A, B) (A + B) |
2660 | +# define ut_dulint_minus(A, B) (A - B) |
2661 | +# define ut_dulint_align_down(A, B) (A & ~((ib_int64_t)B - 1)) |
2662 | +# define ut_dulint_align_up(A, B) ((A + B - 1) & ~((ib_int64_t)B - 1)) |
2663 | +#endif |
2664 | + |
2665 | +#ifndef XTRADB_BASED |
2666 | +#define trx_sys_sys_space(id) (id == 0) |
2667 | +#endif |
2668 | + |
2669 | +#ifdef __WIN__ |
2670 | +#define SRV_PATH_SEPARATOR '\\' |
2671 | +#define SRV_PATH_SEPARATOR_STR "\\" |
2672 | +#else |
2673 | +#define SRV_PATH_SEPARATOR '/' |
2674 | +#define SRV_PATH_SEPARATOR_STR "/" |
2675 | +#endif |
2676 | + |
2677 | +#ifndef UNIV_PAGE_SIZE_MAX |
2678 | +#define UNIV_PAGE_SIZE_MAX UNIV_PAGE_SIZE |
2679 | +#endif |
2680 | +#ifndef UNIV_PAGE_SIZE_SHIFT_MAX |
2681 | +#define UNIV_PAGE_SIZE_SHIFT_MAX UNIV_PAGE_SIZE_SHIFT |
2682 | +#endif |
2683 | + |
2684 | +#ifdef __WIN__ |
2685 | +#define XB_FILE_UNDEFINED NULL |
2686 | +#else |
2687 | +#define XB_FILE_UNDEFINED (-1) |
2688 | +#endif |
2689 | + |
2690 | +#ifdef INNODB_VERSION_SHORT |
2691 | +#define XB_HASH_SEARCH(NAME, TABLE, FOLD, DATA, ASSERTION, TEST) \ |
2692 | + HASH_SEARCH(NAME, TABLE, FOLD, xtrabackup_tables_t*, DATA, ASSERTION, \ |
2693 | + TEST) |
2694 | +#else |
2695 | +#define XB_HASH_SEARCH(NAME, TABLE, FOLD, DATA, ASSERTION, TEST) \ |
2696 | + HASH_SEARCH(NAME, TABLE, FOLD, DATA, TEST) |
2697 | +#endif |
2698 | + |
2699 | +/* ==start === definition at fil0fil.c === */ |
2700 | +// ################################################################## |
2701 | +// NOTE: We should check the following definitions fit to the source. |
2702 | +// ################################################################## |
2703 | + |
2704 | +#ifndef INNODB_VERSION_SHORT |
2705 | +//5.0 5.1 |
2706 | +/* File node of a tablespace or the log data space */ |
2707 | +struct fil_node_struct { |
2708 | + fil_space_t* space; /* backpointer to the space where this node |
2709 | + belongs */ |
2710 | + char* name; /* path to the file */ |
2711 | + ibool open; /* TRUE if file open */ |
2712 | + os_file_t handle; /* OS handle to the file, if file open */ |
2713 | + ibool is_raw_disk;/* TRUE if the 'file' is actually a raw |
2714 | + device or a raw disk partition */ |
2715 | + ulint size; /* size of the file in database pages, 0 if |
2716 | + not known yet; the possible last incomplete |
2717 | + megabyte may be ignored if space == 0 */ |
2718 | + ulint n_pending; |
2719 | + /* count of pending i/o's on this file; |
2720 | + closing of the file is not allowed if |
2721 | + this is > 0 */ |
2722 | + ulint n_pending_flushes; |
2723 | + /* count of pending flushes on this file; |
2724 | + closing of the file is not allowed if |
2725 | + this is > 0 */ |
2726 | + ib_longlong modification_counter;/* when we write to the file we |
2727 | + increment this by one */ |
2728 | + ib_longlong flush_counter;/* up to what modification_counter value |
2729 | + we have flushed the modifications to disk */ |
2730 | + UT_LIST_NODE_T(fil_node_t) chain; |
2731 | + /* link field for the file chain */ |
2732 | + UT_LIST_NODE_T(fil_node_t) LRU; |
2733 | + /* link field for the LRU list */ |
2734 | + ulint magic_n; |
2735 | +}; |
2736 | + |
2737 | +struct fil_space_struct { |
2738 | + char* name; /* space name = the path to the first file in |
2739 | + it */ |
2740 | + ulint id; /* space id */ |
2741 | + ib_longlong tablespace_version; |
2742 | + /* in DISCARD/IMPORT this timestamp is used to |
2743 | + check if we should ignore an insert buffer |
2744 | + merge request for a page because it actually |
2745 | + was for the previous incarnation of the |
2746 | + space */ |
2747 | + ibool mark; /* this is set to TRUE at database startup if |
2748 | + the space corresponds to a table in the InnoDB |
2749 | + data dictionary; so we can print a warning of |
2750 | + orphaned tablespaces */ |
2751 | + ibool stop_ios;/* TRUE if we want to rename the .ibd file of |
2752 | + tablespace and want to stop temporarily |
2753 | + posting of new i/o requests on the file */ |
2754 | + ibool stop_ibuf_merges; |
2755 | + /* we set this TRUE when we start deleting a |
2756 | + single-table tablespace */ |
2757 | + ibool is_being_deleted; |
2758 | + /* this is set to TRUE when we start |
2759 | + deleting a single-table tablespace and its |
2760 | + file; when this flag is set no further i/o |
2761 | + or flush requests can be placed on this space, |
2762 | + though there may be such requests still being |
2763 | + processed on this space */ |
2764 | + ulint purpose;/* FIL_TABLESPACE, FIL_LOG, or FIL_ARCH_LOG */ |
2765 | + UT_LIST_BASE_NODE_T(fil_node_t) chain; |
2766 | + /* base node for the file chain */ |
2767 | + ulint size; /* space size in pages; 0 if a single-table |
2768 | + tablespace whose size we do not know yet; |
2769 | + last incomplete megabytes in data files may be |
2770 | + ignored if space == 0 */ |
2771 | + ulint n_reserved_extents; |
2772 | + /* number of reserved free extents for |
2773 | + ongoing operations like B-tree page split */ |
2774 | + ulint n_pending_flushes; /* this is > 0 when flushing |
2775 | + the tablespace to disk; dropping of the |
2776 | + tablespace is forbidden if this is > 0 */ |
2777 | + ulint n_pending_ibuf_merges;/* this is > 0 when merging |
2778 | + insert buffer entries to a page so that we |
2779 | + may need to access the ibuf bitmap page in the |
2780 | + tablespade: dropping of the tablespace is |
2781 | + forbidden if this is > 0 */ |
2782 | + hash_node_t hash; /* hash chain node */ |
2783 | + hash_node_t name_hash;/* hash chain the name_hash table */ |
2784 | + rw_lock_t latch; /* latch protecting the file space storage |
2785 | + allocation */ |
2786 | + UT_LIST_NODE_T(fil_space_t) unflushed_spaces; |
2787 | + /* list of spaces with at least one unflushed |
2788 | + file we have written to */ |
2789 | + ibool is_in_unflushed_spaces; /* TRUE if this space is |
2790 | + currently in the list above */ |
2791 | + UT_LIST_NODE_T(fil_space_t) space_list; |
2792 | + /* list of all spaces */ |
2793 | + ibuf_data_t* ibuf_data; |
2794 | + /* insert buffer data */ |
2795 | + ulint magic_n; |
2796 | +}; |
2797 | +typedef struct fil_system_struct fil_system_t; |
2798 | +struct fil_system_struct { |
2799 | + mutex_t mutex; /* The mutex protecting the cache */ |
2800 | + hash_table_t* spaces; /* The hash table of spaces in the |
2801 | + system; they are hashed on the space |
2802 | + id */ |
2803 | + hash_table_t* name_hash; /* hash table based on the space |
2804 | + name */ |
2805 | + UT_LIST_BASE_NODE_T(fil_node_t) LRU; |
2806 | + /* base node for the LRU list of the |
2807 | + most recently used open files with no |
2808 | + pending i/o's; if we start an i/o on |
2809 | + the file, we first remove it from this |
2810 | + list, and return it to the start of |
2811 | + the list when the i/o ends; |
2812 | + log files and the system tablespace are |
2813 | + not put to this list: they are opened |
2814 | + after the startup, and kept open until |
2815 | + shutdown */ |
2816 | + UT_LIST_BASE_NODE_T(fil_space_t) unflushed_spaces; |
2817 | + /* base node for the list of those |
2818 | + tablespaces whose files contain |
2819 | + unflushed writes; those spaces have |
2820 | + at least one file node where |
2821 | + modification_counter > flush_counter */ |
2822 | + ulint n_open; /* number of files currently open */ |
2823 | + ulint max_n_open; /* n_open is not allowed to exceed |
2824 | + this */ |
2825 | + ib_longlong modification_counter;/* when we write to a file we |
2826 | + increment this by one */ |
2827 | + ulint max_assigned_id;/* maximum space id in the existing |
2828 | + tables, or assigned during the time |
2829 | + mysqld has been up; at an InnoDB |
2830 | + startup we scan the data dictionary |
2831 | + and set here the maximum of the |
2832 | + space id's of the tables there */ |
2833 | + ib_longlong tablespace_version; |
2834 | + /* a counter which is incremented for |
2835 | + every space object memory creation; |
2836 | + every space mem object gets a |
2837 | + 'timestamp' from this; in DISCARD/ |
2838 | + IMPORT this is used to check if we |
2839 | + should ignore an insert buffer merge |
2840 | + request */ |
2841 | + UT_LIST_BASE_NODE_T(fil_space_t) space_list; |
2842 | + /* list of all file spaces */ |
2843 | +}; |
2844 | +#else |
2845 | +//Plugin ? |
2846 | +/** File node of a tablespace or the log data space */ |
2847 | +struct fil_node_struct { |
2848 | + fil_space_t* space; /*!< backpointer to the space where this node |
2849 | + belongs */ |
2850 | + char* name; /*!< path to the file */ |
2851 | + ibool open; /*!< TRUE if file open */ |
2852 | + os_file_t handle; /*!< OS handle to the file, if file open */ |
2853 | + ibool is_raw_disk;/*!< TRUE if the 'file' is actually a raw |
2854 | + device or a raw disk partition */ |
2855 | + ulint size; /*!< size of the file in database pages, 0 if |
2856 | + not known yet; the possible last incomplete |
2857 | + megabyte may be ignored if space == 0 */ |
2858 | + ulint n_pending; |
2859 | + /*!< count of pending i/o's on this file; |
2860 | + closing of the file is not allowed if |
2861 | + this is > 0 */ |
2862 | + ulint n_pending_flushes; |
2863 | + /*!< count of pending flushes on this file; |
2864 | + closing of the file is not allowed if |
2865 | + this is > 0 */ |
2866 | + ib_int64_t modification_counter;/*!< when we write to the file we |
2867 | + increment this by one */ |
2868 | + ib_int64_t flush_counter;/*!< up to what |
2869 | + modification_counter value we have |
2870 | + flushed the modifications to disk */ |
2871 | + UT_LIST_NODE_T(fil_node_t) chain; |
2872 | + /*!< link field for the file chain */ |
2873 | + UT_LIST_NODE_T(fil_node_t) LRU; |
2874 | + /*!< link field for the LRU list */ |
2875 | + ulint magic_n;/*!< FIL_NODE_MAGIC_N */ |
2876 | +}; |
2877 | + |
2878 | +struct fil_space_struct { |
2879 | + char* name; /*!< space name = the path to the first file in |
2880 | + it */ |
2881 | + ulint id; /*!< space id */ |
2882 | + ib_int64_t tablespace_version; |
2883 | + /*!< in DISCARD/IMPORT this timestamp |
2884 | + is used to check if we should ignore |
2885 | + an insert buffer merge request for a |
2886 | + page because it actually was for the |
2887 | + previous incarnation of the space */ |
2888 | + ibool mark; /*!< this is set to TRUE at database startup if |
2889 | + the space corresponds to a table in the InnoDB |
2890 | + data dictionary; so we can print a warning of |
2891 | + orphaned tablespaces */ |
2892 | + ibool stop_ios;/*!< TRUE if we want to rename the |
2893 | + .ibd file of tablespace and want to |
2894 | + stop temporarily posting of new i/o |
2895 | + requests on the file */ |
2896 | + ibool stop_ibuf_merges; |
2897 | + /*!< we set this TRUE when we start |
2898 | + deleting a single-table tablespace */ |
2899 | + ibool is_being_deleted; |
2900 | + /*!< this is set to TRUE when we start |
2901 | + deleting a single-table tablespace and its |
2902 | + file; when this flag is set no further i/o |
2903 | + or flush requests can be placed on this space, |
2904 | + though there may be such requests still being |
2905 | + processed on this space */ |
2906 | + ulint purpose;/*!< FIL_TABLESPACE, FIL_LOG, or |
2907 | + FIL_ARCH_LOG */ |
2908 | + UT_LIST_BASE_NODE_T(fil_node_t) chain; |
2909 | + /*!< base node for the file chain */ |
2910 | + ulint size; /*!< space size in pages; 0 if a single-table |
2911 | + tablespace whose size we do not know yet; |
2912 | + last incomplete megabytes in data files may be |
2913 | + ignored if space == 0 */ |
2914 | + ulint flags; /*!< compressed page size and file format, or 0 |
2915 | + */ |
2916 | + ulint n_reserved_extents; |
2917 | + /*!< number of reserved free extents for |
2918 | + ongoing operations like B-tree page split */ |
2919 | + ulint n_pending_flushes; /*!< this is positive when flushing |
2920 | + the tablespace to disk; dropping of the |
2921 | + tablespace is forbidden if this is positive */ |
2922 | + ulint n_pending_ibuf_merges;/*!< this is positive |
2923 | + when merging insert buffer entries to |
2924 | + a page so that we may need to access |
2925 | + the ibuf bitmap page in the |
2926 | + tablespade: dropping of the tablespace |
2927 | + is forbidden if this is positive */ |
2928 | + hash_node_t hash; /*!< hash chain node */ |
2929 | + hash_node_t name_hash;/*!< hash chain the name_hash table */ |
2930 | +#ifndef UNIV_HOTBACKUP |
2931 | + rw_lock_t latch; /*!< latch protecting the file space storage |
2932 | + allocation */ |
2933 | +#endif /* !UNIV_HOTBACKUP */ |
2934 | + UT_LIST_NODE_T(fil_space_t) unflushed_spaces; |
2935 | + /*!< list of spaces with at least one unflushed |
2936 | + file we have written to */ |
2937 | + ibool is_in_unflushed_spaces; /*!< TRUE if this space is |
2938 | + currently in unflushed_spaces */ |
2939 | +#ifdef XTRADB_BASED |
2940 | + ibool is_corrupt; |
2941 | +#endif |
2942 | + UT_LIST_NODE_T(fil_space_t) space_list; |
2943 | + /*!< list of all spaces */ |
2944 | + ulint magic_n;/*!< FIL_SPACE_MAGIC_N */ |
2945 | +}; |
2946 | + |
2947 | +typedef struct fil_system_struct fil_system_t; |
2948 | + |
2949 | +struct fil_system_struct { |
2950 | +#ifndef UNIV_HOTBACKUP |
2951 | + mutex_t mutex; /*!< The mutex protecting the cache */ |
2952 | +#ifdef XTRADB_BASED |
2953 | + mutex_t file_extend_mutex; |
2954 | +#endif |
2955 | +#endif /* !UNIV_HOTBACKUP */ |
2956 | + hash_table_t* spaces; /*!< The hash table of spaces in the |
2957 | + system; they are hashed on the space |
2958 | + id */ |
2959 | + hash_table_t* name_hash; /*!< hash table based on the space |
2960 | + name */ |
2961 | + UT_LIST_BASE_NODE_T(fil_node_t) LRU; |
2962 | + /*!< base node for the LRU list of the |
2963 | + most recently used open files with no |
2964 | + pending i/o's; if we start an i/o on |
2965 | + the file, we first remove it from this |
2966 | + list, and return it to the start of |
2967 | + the list when the i/o ends; |
2968 | + log files and the system tablespace are |
2969 | + not put to this list: they are opened |
2970 | + after the startup, and kept open until |
2971 | + shutdown */ |
2972 | + UT_LIST_BASE_NODE_T(fil_space_t) unflushed_spaces; |
2973 | + /*!< base node for the list of those |
2974 | + tablespaces whose files contain |
2975 | + unflushed writes; those spaces have |
2976 | + at least one file node where |
2977 | + modification_counter > flush_counter */ |
2978 | + ulint n_open; /*!< number of files currently open */ |
2979 | + ulint max_n_open; /*!< n_open is not allowed to exceed |
2980 | + this */ |
2981 | + ib_int64_t modification_counter;/*!< when we write to a file we |
2982 | + increment this by one */ |
2983 | + ulint max_assigned_id;/*!< maximum space id in the existing |
2984 | + tables, or assigned during the time |
2985 | + mysqld has been up; at an InnoDB |
2986 | + startup we scan the data dictionary |
2987 | + and set here the maximum of the |
2988 | + space id's of the tables there */ |
2989 | + ib_int64_t tablespace_version; |
2990 | + /*!< a counter which is incremented for |
2991 | + every space object memory creation; |
2992 | + every space mem object gets a |
2993 | + 'timestamp' from this; in DISCARD/ |
2994 | + IMPORT this is used to check if we |
2995 | + should ignore an insert buffer merge |
2996 | + request */ |
2997 | + UT_LIST_BASE_NODE_T(fil_space_t) space_list; |
2998 | + /*!< list of all file spaces */ |
2999 | + ibool space_id_reuse_warned; |
3000 | + /* !< TRUE if fil_space_create() |
3001 | + has issued a warning about |
3002 | + potential space_id reuse */ |
3003 | +}; |
3004 | + |
3005 | +#endif /* INNODB_VERSION_SHORT */ |
3006 | + |
3007 | +extern fil_system_t* fil_system; |
3008 | +extern char *opt_mysql_tmpdir; |
3009 | +extern MY_TMPDIR mysql_tmpdir_list; |
3010 | + |
3011 | +/* ==end=== definition at fil0fil.c === */ |
3012 | + |
3013 | +/* prototypes for static functions in original */ |
3014 | +#ifndef INNODB_VERSION_SHORT |
3015 | +page_t* |
3016 | +btr_node_ptr_get_child( |
3017 | +/*===================*/ |
3018 | + /* out: child page, x-latched */ |
3019 | + rec_t* node_ptr,/* in: node pointer */ |
3020 | + const ulint* offsets,/* in: array returned by rec_get_offsets() */ |
3021 | + mtr_t* mtr); /* in: mtr */ |
3022 | +#else |
3023 | +buf_block_t* |
3024 | +btr_node_ptr_get_child( |
3025 | +/*===================*/ |
3026 | + const rec_t* node_ptr,/*!< in: node pointer */ |
3027 | + dict_index_t* index, /*!< in: index */ |
3028 | + const ulint* offsets,/*!< in: array returned by rec_get_offsets() */ |
3029 | + mtr_t* mtr); /*!< in: mtr */ |
3030 | + |
3031 | +buf_block_t* |
3032 | +btr_root_block_get( |
3033 | +/*===============*/ |
3034 | + dict_index_t* index, /*!< in: index tree */ |
3035 | + mtr_t* mtr); /*!< in: mtr */ |
3036 | +#endif |
3037 | + |
3038 | +int |
3039 | +fil_file_readdir_next_file( |
3040 | +/*=======================*/ |
3041 | + /* out: 0 if ok, -1 if error even after the |
3042 | + retries, 1 if at the end of the directory */ |
3043 | + ulint* err, /* out: this is set to DB_ERROR if an error |
3044 | + was encountered, otherwise not changed */ |
3045 | + const char* dirname,/* in: directory name or path */ |
3046 | + os_file_dir_t dir, /* in: directory stream */ |
3047 | + os_file_stat_t* info); /* in/out: buffer where the info is returned */ |
3048 | + |
3049 | +ibool |
3050 | +recv_check_cp_is_consistent( |
3051 | +/*========================*/ |
3052 | + /* out: TRUE if ok */ |
3053 | + byte* buf); /* in: buffer containing checkpoint info */ |
3054 | + |
3055 | +ulint |
3056 | +recv_find_max_checkpoint( |
3057 | +/*=====================*/ |
3058 | + /* out: error code or DB_SUCCESS */ |
3059 | + log_group_t** max_group, /* out: max group */ |
3060 | + ulint* max_field); /* out: LOG_CHECKPOINT_1 or |
3061 | + LOG_CHECKPOINT_2 */ |
3062 | + |
3063 | +ibool |
3064 | +log_block_checksum_is_ok_or_old_format( |
3065 | +/*===================================*/ |
3066 | + /* out: TRUE if ok, or if the log block may be in the |
3067 | + format of InnoDB version < 3.23.52 */ |
3068 | + byte* block); /* in: pointer to a log block */ |
3069 | + |
3070 | +ulint |
3071 | +open_or_create_log_file( |
3072 | +/*====================*/ |
3073 | + /* out: DB_SUCCESS or error code */ |
3074 | + ibool create_new_db, /* in: TRUE if we should create a |
3075 | + new database */ |
3076 | + ibool* log_file_created, /* out: TRUE if new log file |
3077 | + created */ |
3078 | + ibool log_file_has_been_opened,/* in: TRUE if a log file has been |
3079 | + opened before: then it is an error |
3080 | + to try to create another log file */ |
3081 | + ulint k, /* in: log group number */ |
3082 | + ulint i); /* in: log file number in group */ |
3083 | + |
3084 | +ulint |
3085 | +open_or_create_data_files( |
3086 | +/*======================*/ |
3087 | + /* out: DB_SUCCESS or error code */ |
3088 | + ibool* create_new_db, /* out: TRUE if new database should be |
3089 | + created */ |
3090 | +#ifdef XTRADB_BASED |
3091 | + ibool* create_new_doublewrite_file, |
3092 | +#endif |
3093 | +#ifdef UNIV_LOG_ARCHIVE |
3094 | + ulint* min_arch_log_no,/* out: min of archived log numbers in data |
3095 | + files */ |
3096 | + ulint* max_arch_log_no,/* out: */ |
3097 | +#endif /* UNIV_LOG_ARCHIVE */ |
3098 | + LSN64* min_flushed_lsn,/* out: min of flushed lsn values in data |
3099 | + files */ |
3100 | + LSN64* max_flushed_lsn,/* out: */ |
3101 | + ulint* sum_of_new_sizes);/* out: sum of sizes of the new files added |
3102 | + */ |
3103 | + |
3104 | +/****************************************************************//** |
3105 | +A simple function to open or create a file. |
3106 | +@return own: handle to the file, not defined if error, error number |
3107 | +can be retrieved with os_file_get_last_error */ |
3108 | +os_file_t |
3109 | +xb_file_create_no_error_handling( |
3110 | +/*=============================*/ |
3111 | + const char* name, /*!< in: name of the file or path as a |
3112 | + null-terminated string */ |
3113 | + ulint create_mode,/*!< in: OS_FILE_OPEN if an existing file |
3114 | + is opened (if does not exist, error), or |
3115 | + OS_FILE_CREATE if a new file is created |
3116 | + (if exists, error) */ |
3117 | + ulint access_type,/*!< in: OS_FILE_READ_ONLY, |
3118 | + OS_FILE_READ_WRITE, or |
3119 | + OS_FILE_READ_ALLOW_DELETE; the last option is |
3120 | + used by a backup program reading the file */ |
3121 | + ibool* success);/*!< out: TRUE if succeed, FALSE if error */ |
3122 | + |
3123 | +/****************************************************************//** |
3124 | +Opens an existing file or creates a new. |
3125 | +@return own: handle to the file, not defined if error, error number |
3126 | +can be retrieved with os_file_get_last_error */ |
3127 | +os_file_t |
3128 | +xb_file_create( |
3129 | +/*===========*/ |
3130 | + const char* name, /*!< in: name of the file or path as a |
3131 | + null-terminated string */ |
3132 | + ulint create_mode,/*!< in: OS_FILE_OPEN if an existing file |
3133 | + is opened (if does not exist, error), or |
3134 | + OS_FILE_CREATE if a new file is created |
3135 | + (if exists, error), |
3136 | + OS_FILE_OVERWRITE if a new file is created |
3137 | + or an old overwritten; |
3138 | + OS_FILE_OPEN_RAW, if a raw device or disk |
3139 | + partition should be opened */ |
3140 | + ulint purpose,/*!< in: OS_FILE_AIO, if asynchronous, |
3141 | + non-buffered i/o is desired, |
3142 | + OS_FILE_NORMAL, if any normal file; |
3143 | + NOTE that it also depends on type, os_aio_.. |
3144 | + and srv_.. variables whether we really use |
3145 | + async i/o or unbuffered i/o: look in the |
3146 | + function source code for the exact rules */ |
3147 | + ulint type, /*!< in: OS_DATA_FILE or OS_LOG_FILE */ |
3148 | + ibool* success);/*!< out: TRUE if succeed, FALSE if error */ |
3149 | + |
3150 | + |
3151 | +/***********************************************************************//** |
3152 | +Renames a file (can also move it to another directory). It is safest that the |
3153 | +file is closed before calling this function. |
3154 | +@return TRUE if success */ |
3155 | +ibool |
3156 | +xb_file_rename( |
3157 | +/*===========*/ |
3158 | + const char* oldpath,/*!< in: old file path as a null-terminated |
3159 | + string */ |
3160 | + const char* newpath);/*!< in: new file path */ |
3161 | + |
3162 | +void |
3163 | +xb_file_set_nocache( |
3164 | +/*================*/ |
3165 | + os_file_t fd, /* in: file descriptor to alter */ |
3166 | + const char* file_name, /* in: used in the diagnostic message |
3167 | + */ |
3168 | + const char* operation_name);/* in: used in the diagnostic message, |
3169 | + we call os_file_set_nocache() |
3170 | + immediately after opening or creating |
3171 | + a file, so this is either "open" or |
3172 | + "create" */ |
3173 | + |
3174 | +/***********************************************************************//** |
3175 | +Compatibility wrapper around os_file_flush(). |
3176 | +@return TRUE if success */ |
3177 | +ibool |
3178 | +xb_file_flush( |
3179 | +/*==========*/ |
3180 | + os_file_t file); /*!< in, own: handle to a file */ |
3181 | + |
3182 | +void |
3183 | +innobase_mysql_prepare_print_arbitrary_thd(void); |
3184 | + |
3185 | +void |
3186 | +innobase_mysql_end_print_arbitrary_thd(void); |
3187 | + |
3188 | +int |
3189 | +mysql_get_identifier_quote_char( |
3190 | + trx_t* trx, |
3191 | + const char* name, |
3192 | + ulint namelen); |
3193 | + |
3194 | +void |
3195 | +innobase_print_identifier( |
3196 | + FILE* f, |
3197 | + trx_t* trx __attribute__((unused)), |
3198 | + ibool table_id __attribute__((unused)), |
3199 | + const char* name, |
3200 | + ulint namelen); |
3201 | + |
3202 | +/**********************************************************************//** |
3203 | +It should be safe to use lower_case_table_names=0 for xtrabackup. If it causes |
3204 | +any problems, we can add the lower_case_table_names option to xtrabackup |
3205 | +later. |
3206 | +@return 0 */ |
3207 | +ulint |
3208 | +innobase_get_lower_case_table_names(void); |
3209 | + |
3210 | +/******************************************************************//** |
3211 | +Strip dir name from a full path name and return only the file name |
3212 | +@return file name or "null" if no file name */ |
3213 | +const char* |
3214 | +innobase_basename( |
3215 | +/*==============*/ |
3216 | + const char* path_name); /*!< in: full path name */ |
3217 | + |
3218 | +int |
3219 | +innobase_mysql_cmp( |
3220 | + int mysql_type, |
3221 | + uint charset_number, |
3222 | + unsigned char* a, |
3223 | + unsigned int a_length, |
3224 | + unsigned char* b, |
3225 | + unsigned int b_length); |
3226 | + |
3227 | +ibool |
3228 | +innobase_query_is_update(void); |
3229 | + |
3230 | +#endif /* INNODB_INT_H */ |
3231 | |
3232 | === added file 'src/page_write_filt.c' |
3233 | --- src/page_write_filt.c 1970-01-01 00:00:00 +0000 |
3234 | +++ src/page_write_filt.c 2012-05-24 09:35:22 +0000 |
3235 | @@ -0,0 +1,309 @@ |
3236 | +/****************************************************** |
3237 | +XtraBackup: hot backup tool for InnoDB |
3238 | +(c) 2009-2012 Percona Inc. |
3239 | +Originally Created 3/3/2009 Yasufumi Kinoshita |
3240 | +Written by Alexey Kopytov, Aleksandr Kuzminsky, Stewart Smith, Vadim Tkachenko, |
3241 | +Yasufumi Kinoshita, Ignacio Nin and Baron Schwartz. |
3242 | + |
3243 | +This program is free software; you can redistribute it and/or modify |
3244 | +it under the terms of the GNU General Public License as published by |
3245 | +the Free Software Foundation; version 2 of the License. |
3246 | + |
3247 | +This program is distributed in the hope that it will be useful, |
3248 | +but WITHOUT ANY WARRANTY; without even the implied warranty of |
3249 | +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3250 | +GNU General Public License for more details. |
3251 | + |
3252 | +You should have received a copy of the GNU General Public License |
3253 | +along with this program; if not, write to the Free Software |
3254 | +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
3255 | + |
3256 | +*******************************************************/ |
3257 | + |
3258 | +/* Page filters implementation */ |
3259 | + |
3260 | +#include <my_base.h> |
3261 | +#include <ut0mem.h> |
3262 | +#include "common.h" |
3263 | +#include "innodb_int.h" |
3264 | +#include "page_write_filt.h" |
3265 | +#include "fil_cur.h" |
3266 | + |
3267 | +/************************************************************************ |
3268 | +Write-through page filter. */ |
3269 | +static my_bool pwf_wt_process(xb_page_write_filt_ctxt_t *ctxt, |
3270 | + ds_file_t *dstfile); |
3271 | + |
3272 | +static xb_page_write_filt_t pwf_write_through = { |
3273 | + &pwf_wt_process, |
3274 | + NULL, |
3275 | + NULL |
3276 | +}; |
3277 | + |
3278 | +/************************************************************************ |
3279 | +Incremental page filter. */ |
3280 | +static my_bool pwf_incremental_process(xb_page_write_filt_ctxt_t *ctxt, |
3281 | + ds_file_t *dstfile); |
3282 | +static my_bool pwf_incremental_finalize(xb_page_write_filt_ctxt_t *ctxt, |
3283 | + ds_file_t *dstfile); |
3284 | +static void pwf_incremental_deinit(xb_page_write_filt_ctxt_t *ctxt); |
3285 | + |
3286 | +static xb_page_write_filt_t pwf_incremental = { |
3287 | + &pwf_incremental_process, |
3288 | + &pwf_incremental_finalize, |
3289 | + &pwf_incremental_deinit |
3290 | +}; |
3291 | + |
3292 | +/************************************************************************ |
3293 | +Compact page filter. */ |
3294 | +static my_bool pwf_compact_process(xb_page_write_filt_ctxt_t *ctxt, |
3295 | + ds_file_t *dstfile); |
3296 | +static my_bool pwf_compact_finalize(xb_page_write_filt_ctxt_t *ctxt, |
3297 | + ds_file_t *dstfile); |
3298 | + |
3299 | +static xb_page_write_filt_t pwf_compact = { |
3300 | + &pwf_compact_process, |
3301 | + &pwf_compact_finalize, |
3302 | + NULL |
3303 | +}; |
3304 | + |
3305 | + |
3306 | +/************************************************************************ |
3307 | +Initialize incremental page filter. |
3308 | + |
3309 | +@return TRUE on success, FALSE on error. */ |
3310 | +xb_page_write_filt_t* |
3311 | +pwf_make_incremental_filt(xb_page_write_filt_ctxt_t *ctxt, |
3312 | + xb_fil_cur_t *cursor, char *dst_name, |
3313 | + LSN64 incremental_lsn) |
3314 | +{ |
3315 | + char meta_name[FN_REFLEN]; |
3316 | + xb_delta_info_t info; |
3317 | + ulint buf_size; |
3318 | + xb_pwf_incremental_ctxt_t *cp = |
3319 | + &(ctxt->u.pwf_incremental_ctxt); |
3320 | + |
3321 | + ctxt->cursor = cursor; |
3322 | + |
3323 | + /* allocate buffer for incremental backup (4096 pages) */ |
3324 | + buf_size = (UNIV_PAGE_SIZE_MAX / 4 + 1) * UNIV_PAGE_SIZE_MAX; |
3325 | + cp->incremental_lsn = incremental_lsn; |
3326 | + cp->delta_buf_base = ut_malloc(buf_size); |
3327 | + bzero(cp->delta_buf_base, buf_size); |
3328 | + cp->delta_buf = ut_align(cp->delta_buf_base, UNIV_PAGE_SIZE_MAX); |
3329 | + |
3330 | + /* write delta meta info */ |
3331 | + snprintf(meta_name, sizeof(meta_name), "%s%s", dst_name, |
3332 | + XB_DELTA_INFO_SUFFIX); |
3333 | + info.page_size = cursor->page_size; |
3334 | + if (!xb_write_delta_metadata(meta_name, &info)) { |
3335 | + msg("[%02lu] xtrabackup: Error: " |
3336 | + "failed to write meta info for %s\n", |
3337 | + cursor->thread_n, cursor->path); |
3338 | + return(NULL); |
3339 | + } |
3340 | + |
3341 | + /* change the target file name, since we are only going to write |
3342 | + delta pages */ |
3343 | + strcat(dst_name, ".delta"); |
3344 | + |
3345 | + mach_write_to_4(cp->delta_buf, 0x78747261UL); /*"xtra"*/ |
3346 | + cp->npages = 1; |
3347 | + |
3348 | + return(&pwf_incremental); |
3349 | +} |
3350 | + |
3351 | +/************************************************************************ |
3352 | +Run the next batch of pages through incremental page filter. |
3353 | + |
3354 | +@return TRUE on success, FALSE on error. */ |
3355 | +static my_bool |
3356 | +pwf_incremental_process(xb_page_write_filt_ctxt_t *ctxt, ds_file_t *dstfile) |
3357 | +{ |
3358 | + ulint i; |
3359 | + xb_fil_cur_t *cursor = ctxt->cursor; |
3360 | + ulint page_size = cursor->page_size; |
3361 | + byte *page; |
3362 | + xb_pwf_incremental_ctxt_t *cp = &(ctxt->u.pwf_incremental_ctxt); |
3363 | + |
3364 | + for (i = 0, page = cursor->buf; i < cursor->buf_npages; |
3365 | + i++, page += page_size) { |
3366 | + if (ut_dulint_cmp(cp->incremental_lsn, |
3367 | + MACH_READ_64(page + FIL_PAGE_LSN)) >= 0) { |
3368 | + continue; |
3369 | + } |
3370 | + |
3371 | + /* updated page */ |
3372 | + if (cp->npages == page_size / 4) { |
3373 | + /* flush buffer */ |
3374 | + if (ds_write(dstfile, cp->delta_buf, |
3375 | + cp->npages * page_size)) { |
3376 | + return(FALSE); |
3377 | + } |
3378 | + |
3379 | + /* clear buffer */ |
3380 | + bzero(cp->delta_buf, page_size / 4 * page_size); |
3381 | + mach_write_to_4(cp->delta_buf, 0x78747261UL); /*"xtra"*/ |
3382 | + cp->npages = 1; |
3383 | + } |
3384 | + |
3385 | + mach_write_to_4(cp->delta_buf + cp->npages * 4, |
3386 | + cursor->buf_page_no + i); |
3387 | + memcpy(cp->delta_buf + cp->npages * page_size, page, page_size); |
3388 | + |
3389 | + cp->npages++; |
3390 | + } |
3391 | + |
3392 | + return(TRUE); |
3393 | +} |
3394 | + |
3395 | +/************************************************************************ |
3396 | +Flush the incremental page filter's buffer. |
3397 | + |
3398 | +@return TRUE on success, FALSE on error. */ |
3399 | +static my_bool |
3400 | +pwf_incremental_finalize(xb_page_write_filt_ctxt_t *ctxt, ds_file_t *dstfile) |
3401 | +{ |
3402 | + xb_fil_cur_t *cursor = ctxt->cursor; |
3403 | + ulint page_size = cursor->page_size; |
3404 | + xb_pwf_incremental_ctxt_t *cp = &(ctxt->u.pwf_incremental_ctxt); |
3405 | + |
3406 | + if (cp->npages != page_size / 4) { |
3407 | + mach_write_to_4(cp->delta_buf + cp->npages * 4, 0xFFFFFFFFUL); |
3408 | + } |
3409 | + |
3410 | + /* Mark the final block */ |
3411 | + mach_write_to_4(cp->delta_buf, 0x58545241UL); /*"XTRA"*/ |
3412 | + |
3413 | + /* flush buffer */ |
3414 | + if (ds_write(dstfile, cp->delta_buf, cp->npages * page_size)) { |
3415 | + return(FALSE); |
3416 | + } |
3417 | + |
3418 | + return(TRUE); |
3419 | +} |
3420 | + |
3421 | +/************************************************************************ |
3422 | +Free the incremental page filter's buffer. */ |
3423 | +static void |
3424 | +pwf_incremental_deinit(xb_page_write_filt_ctxt_t *ctxt) |
3425 | +{ |
3426 | + xb_pwf_incremental_ctxt_t *cp = &(ctxt->u.pwf_incremental_ctxt); |
3427 | + |
3428 | + if (cp->delta_buf_base != NULL) { |
3429 | + ut_free(cp->delta_buf_base); |
3430 | + } |
3431 | +} |
3432 | + |
3433 | +/************************************************************************ |
3434 | +Initialize the write-through page filter. |
3435 | + |
3436 | +@return TRUE on success, FALSE on error. */ |
3437 | +xb_page_write_filt_t* |
3438 | +pwf_make_write_through_filt(xb_page_write_filt_ctxt_t *ctxt, |
3439 | + xb_fil_cur_t *cursor) |
3440 | +{ |
3441 | + ctxt->cursor = cursor; |
3442 | + |
3443 | + return(&pwf_write_through); |
3444 | +} |
3445 | + |
3446 | +/************************************************************************ |
3447 | +Write the next batch of pages to the destination datasinkr. |
3448 | + |
3449 | +@return TRUE on success, FALSE on error. */ |
3450 | +static my_bool |
3451 | +pwf_wt_process(xb_page_write_filt_ctxt_t *ctxt, ds_file_t *dstfile) |
3452 | +{ |
3453 | + xb_fil_cur_t *cursor = ctxt->cursor; |
3454 | + |
3455 | + if (ds_write(dstfile, cursor->buf, cursor->buf_read)) { |
3456 | + return(FALSE); |
3457 | + } |
3458 | + |
3459 | + return(TRUE); |
3460 | +} |
3461 | + |
3462 | +/************************************************************************ |
3463 | +Initialize the compact page filter. |
3464 | + |
3465 | +@return TRUE on success, FALSE on error. */ |
3466 | +xb_page_write_filt_t* |
3467 | +pwf_make_compact_filt(xb_page_write_filt_ctxt_t *ctxt, xb_fil_cur_t *cursor) |
3468 | +{ |
3469 | + xb_pwf_compact_ctxt_t *cp = &(ctxt->u.pwf_compact_ctxt); |
3470 | + |
3471 | + /* Don't compact the system table space */ |
3472 | + cp->skip = cursor->is_system; |
3473 | + |
3474 | + return(&pwf_compact); |
3475 | +} |
3476 | + |
3477 | +static my_bool |
3478 | +check_if_skip_page(byte *page __attribute__((unused))) |
3479 | +{ |
3480 | + return(FALSE); |
3481 | +} |
3482 | + |
3483 | +/************************************************************************ |
3484 | +Run the next batch of pages through the compact page filter. |
3485 | + |
3486 | +@return TRUE on success, FALSE on error. */ |
3487 | +static my_bool |
3488 | +pwf_compact_process(xb_page_write_filt_ctxt_t *ctxt, ds_file_t *dstfile) |
3489 | +{ |
3490 | + xb_fil_cur_t *cursor = ctxt->cursor; |
3491 | + ulint page_size = cursor->page_size; |
3492 | + byte *page; |
3493 | + byte *buf_end; |
3494 | + byte *write_from; |
3495 | + xb_pwf_compact_ctxt_t *cp = &(ctxt->u.pwf_compact_ctxt); |
3496 | + |
3497 | + if (cp->skip) { |
3498 | + return(!ds_write(dstfile, cursor->buf, cursor->buf_read)); |
3499 | + } |
3500 | + |
3501 | + write_from = NULL; |
3502 | + buf_end = cursor->buf + cursor->buf_read; |
3503 | + for (page = cursor->buf; page < buf_end; page += page_size) { |
3504 | + if (!check_if_skip_page(page)) { |
3505 | + if (write_from == NULL) { |
3506 | + write_from = page; |
3507 | + } |
3508 | + continue; |
3509 | + } |
3510 | + } |
3511 | + |
3512 | + /* Write the remaining pages in the buffer, if any */ |
3513 | + if (write_from != NULL && |
3514 | + ds_write(dstfile, write_from, buf_end - write_from)) { |
3515 | + return(FALSE); |
3516 | + } |
3517 | + |
3518 | + return(TRUE); |
3519 | +} |
3520 | + |
3521 | +/************************************************************************ |
3522 | +Close the compact filter's page map stream. |
3523 | + |
3524 | +@return TRUE on success, FALSE on error. */ |
3525 | +static my_bool |
3526 | +pwf_compact_finalize(xb_page_write_filt_ctxt_t *ctxt, ds_file_t *dstfile) |
3527 | +{ |
3528 | + xb_fil_cur_t *cursor = ctxt->cursor; |
3529 | + ulint page_size = cursor->page_size; |
3530 | + xb_pwf_incremental_ctxt_t *cp = &(ctxt->u.pwf_incremental_ctxt); |
3531 | + |
3532 | + if (cp->npages != page_size / 4) { |
3533 | + mach_write_to_4(cp->delta_buf + cp->npages * 4, 0xFFFFFFFFUL); |
3534 | + } |
3535 | + |
3536 | + mach_write_to_4(cp->delta_buf, 0x58545241UL); /*"XTRA"*/ |
3537 | + |
3538 | + /* flush buffer */ |
3539 | + if (ds_write(dstfile, cp->delta_buf, cp->npages * page_size)) { |
3540 | + return(FALSE); |
3541 | + } |
3542 | + |
3543 | + return(TRUE); |
3544 | +} |
3545 | |
3546 | === added file 'src/page_write_filt.h' |
3547 | --- src/page_write_filt.h 1970-01-01 00:00:00 +0000 |
3548 | +++ src/page_write_filt.h 2012-05-24 09:35:22 +0000 |
3549 | @@ -0,0 +1,74 @@ |
3550 | +/****************************************************** |
3551 | +XtraBackup: hot backup tool for InnoDB |
3552 | +(c) 2009-2012 Percona Inc. |
3553 | +Originally Created 3/3/2009 Yasufumi Kinoshita |
3554 | +Written by Alexey Kopytov, Aleksandr Kuzminsky, Stewart Smith, Vadim Tkachenko, |
3555 | +Yasufumi Kinoshita, Ignacio Nin and Baron Schwartz. |
3556 | + |
3557 | +This program is free software; you can redistribute it and/or modify |
3558 | +it under the terms of the GNU General Public License as published by |
3559 | +the Free Software Foundation; version 2 of the License. |
3560 | + |
3561 | +This program is distributed in the hope that it will be useful, |
3562 | +but WITHOUT ANY WARRANTY; without even the implied warranty of |
3563 | +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3564 | +GNU General Public License for more details. |
3565 | + |
3566 | +You should have received a copy of the GNU General Public License |
3567 | +along with this program; if not, write to the Free Software |
3568 | +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
3569 | + |
3570 | +*******************************************************/ |
3571 | + |
3572 | +/* Page filter interface */ |
3573 | + |
3574 | +#ifndef XB_PAGE_WRITE_FILT_H |
3575 | +#define XB_PAGE_WRITE_FILT_H |
3576 | + |
3577 | +#include "fil_cur.h" |
3578 | +#include "datasink.h" |
3579 | + |
3580 | +/* Incremental page filter context */ |
3581 | +typedef struct { |
3582 | + LSN64 incremental_lsn; |
3583 | + byte *delta_buf_base; |
3584 | + byte *delta_buf; |
3585 | + ulint npages; |
3586 | +} xb_pwf_incremental_ctxt_t; |
3587 | + |
3588 | +/* Compact page filter context */ |
3589 | +typedef struct { |
3590 | + my_bool skip; |
3591 | +} xb_pwf_compact_ctxt_t; |
3592 | + |
3593 | +/* Page filter context used as an opaque structure by callers */ |
3594 | +typedef struct { |
3595 | + xb_fil_cur_t *cursor; |
3596 | + union { |
3597 | + xb_pwf_incremental_ctxt_t pwf_incremental_ctxt; |
3598 | + xb_pwf_compact_ctxt_t pwf_compact_ctxt; |
3599 | + } u; |
3600 | +} xb_page_write_filt_ctxt_t; |
3601 | + |
3602 | + |
3603 | +typedef struct { |
3604 | + my_bool (*process)(xb_page_write_filt_ctxt_t *ctxt, |
3605 | + ds_file_t *dstfile); |
3606 | + my_bool (*finalize)(xb_page_write_filt_ctxt_t *, ds_file_t *dstfile); |
3607 | + void (*deinit)(xb_page_write_filt_ctxt_t *); |
3608 | +} xb_page_write_filt_t; |
3609 | + |
3610 | +/* Factory functions for the available page filters */ |
3611 | +xb_page_write_filt_t* |
3612 | +pwf_make_write_through_filt(xb_page_write_filt_ctxt_t *ctxt, |
3613 | + xb_fil_cur_t *cursor); |
3614 | + |
3615 | +xb_page_write_filt_t* |
3616 | +pwf_make_incremental_filt(xb_page_write_filt_ctxt_t *ctxt, |
3617 | + xb_fil_cur_t *cursor, char *dst_name, |
3618 | + LSN64 incremental_lsn); |
3619 | + |
3620 | +xb_page_write_filt_t* |
3621 | +pwf_make_compact_filt(xb_page_write_filt_ctxt_t *ctxt, xb_fil_cur_t *cursor); |
3622 | + |
3623 | +#endif /* XB_PAGE_FILT_H */ |
3624 | |
3625 | === modified file 'src/quicklz/quicklz.h' |
3626 | --- src/quicklz/quicklz.h 2012-02-10 20:05:56 +0000 |
3627 | +++ src/quicklz/quicklz.h 2012-05-24 09:35:22 +0000 |
3628 | @@ -134,6 +134,7 @@ |
3629 | size_t qlz_compress(const void *source, char *destination, size_t size, qlz_state_compress *state); |
3630 | size_t qlz_decompress(const char *source, void *destination, qlz_state_decompress *state); |
3631 | int qlz_get_setting(int setting); |
3632 | +size_t qlz_size_header(const char *source); |
3633 | |
3634 | #if defined (__cplusplus) |
3635 | } |
3636 | |
3637 | === modified file 'src/xbstream.c' |
3638 | --- src/xbstream.c 2012-02-10 20:05:56 +0000 |
3639 | +++ src/xbstream.c 2012-05-24 09:35:22 +0000 |
3640 | @@ -23,7 +23,7 @@ |
3641 | #include <hash.h> |
3642 | #include "common.h" |
3643 | #include "xbstream.h" |
3644 | -#include "local.h" |
3645 | +#include "ds_local.h" |
3646 | |
3647 | #define XBSTREAM_VERSION "1.0" |
3648 | #define XBSTREAM_BUFFER_SIZE (1024 * 1024UL) |
3649 | @@ -36,6 +36,12 @@ |
3650 | RUN_MODE_EXTRACT |
3651 | } run_mode_t; |
3652 | |
3653 | +/* Need the following definitions to avoid linking with ds_stream.o, |
3654 | +ds_compress.o, ds_tmpfile.o and their linking dependencies */ |
3655 | +datasink_t datasink_stream; |
3656 | +datasink_t datasink_compress; |
3657 | +datasink_t datasink_tmpfile; |
3658 | + |
3659 | static run_mode_t opt_mode; |
3660 | static char * opt_directory = NULL; |
3661 | static my_bool opt_verbose = 0; |
3662 | @@ -61,7 +67,7 @@ |
3663 | typedef struct { |
3664 | char *path; |
3665 | uint pathlen; |
3666 | - off_t offset; |
3667 | + my_off_t offset; |
3668 | ds_ctxt_t *ds_ctxt; |
3669 | ds_file_t *file; |
3670 | } file_entry_t; |
3671 | @@ -199,9 +205,7 @@ |
3672 | uchar buf[XBSTREAM_BUFFER_SIZE]; |
3673 | size_t bytes; |
3674 | |
3675 | -#ifdef USE_POSIX_FADVISE |
3676 | posix_fadvise(file, 0, 0, POSIX_FADV_SEQUENTIAL); |
3677 | -#endif |
3678 | |
3679 | while ((bytes = my_read(file, buf, XBSTREAM_BUFFER_SIZE, |
3680 | MYF(MY_WME))) > 0) { |
3681 | @@ -210,9 +214,7 @@ |
3682 | my_progname); |
3683 | return 1; |
3684 | } |
3685 | -#ifdef USE_POSIX_FADVISE |
3686 | posix_fadvise(file, 0, 0, POSIX_FADV_DONTNEED); |
3687 | -#endif |
3688 | |
3689 | } |
3690 | |
3691 | @@ -291,7 +293,6 @@ |
3692 | file_entry_new(ds_ctxt_t *ds_ctxt, const char *path, uint pathlen) |
3693 | { |
3694 | file_entry_t *entry; |
3695 | - datasink_t *ds = ds_ctxt->datasink; |
3696 | ds_file_t *file; |
3697 | |
3698 | entry = (file_entry_t *) my_malloc(sizeof(file_entry_t), |
3699 | @@ -306,7 +307,7 @@ |
3700 | } |
3701 | entry->pathlen = pathlen; |
3702 | |
3703 | - file = ds->open(ds_ctxt, path, NULL); |
3704 | + file = ds_open(ds_ctxt, path, NULL); |
3705 | if (file == NULL) { |
3706 | msg("%s: failed to create file.\n", my_progname); |
3707 | goto err; |
3708 | @@ -343,10 +344,7 @@ |
3709 | void |
3710 | file_entry_free(file_entry_t *entry) |
3711 | { |
3712 | - ds_ctxt_t *ds_ctxt = entry->ds_ctxt; |
3713 | - datasink_t *ds = ds_ctxt->datasink; |
3714 | - |
3715 | - ds->close(entry->file); |
3716 | + ds_close(entry->file); |
3717 | MY_FREE(entry->path); |
3718 | MY_FREE(entry); |
3719 | } |
3720 | @@ -354,14 +352,13 @@ |
3721 | static |
3722 | int |
3723 | mode_extract(int argc __attribute__((unused)), |
3724 | - char **argv __attribute((unused))) |
3725 | + char **argv __attribute__((unused))) |
3726 | { |
3727 | xb_rstream_t *stream; |
3728 | xb_rstream_result_t res; |
3729 | xb_rstream_chunk_t chunk; |
3730 | HASH filehash; |
3731 | file_entry_t *entry; |
3732 | - datasink_t *ds; |
3733 | ds_ctxt_t *ds_ctxt; |
3734 | |
3735 | stream = xb_stream_read_new(); |
3736 | @@ -371,8 +368,7 @@ |
3737 | } |
3738 | |
3739 | /* If --directory is specified, it is already set as CWD by now. */ |
3740 | - ds = &datasink_local; |
3741 | - ds_ctxt = ds->init("."); |
3742 | + ds_ctxt = ds_create(".", DS_TYPE_LOCAL); |
3743 | |
3744 | if (my_hash_init(&filehash, &my_charset_bin, START_FILE_HASH_SIZE, |
3745 | 0, 0, (my_hash_get_key) get_file_entry_key, |
3746 | @@ -420,7 +416,7 @@ |
3747 | goto err; |
3748 | } |
3749 | |
3750 | - if (ds->write(entry->file, chunk.data, chunk.length)) { |
3751 | + if (ds_write(entry->file, chunk.data, chunk.length)) { |
3752 | msg("%s: my_write() failed.\n", my_progname); |
3753 | goto err; |
3754 | } |
3755 | @@ -433,13 +429,13 @@ |
3756 | } |
3757 | |
3758 | my_hash_free(&filehash); |
3759 | - ds->deinit(ds_ctxt); |
3760 | + ds_destroy(ds_ctxt); |
3761 | xb_stream_read_done(stream); |
3762 | |
3763 | return 0; |
3764 | err: |
3765 | my_hash_free(&filehash); |
3766 | - ds->deinit(ds_ctxt); |
3767 | + ds_destroy(ds_ctxt); |
3768 | xb_stream_read_done(stream); |
3769 | |
3770 | return 1; |
3771 | |
3772 | === modified file 'src/xtrabackup.c' |
3773 | --- src/xtrabackup.c 2012-05-21 07:55:19 +0000 |
3774 | +++ src/xtrabackup.c 2012-05-24 09:35:22 +0000 |
3775 | @@ -48,9 +48,9 @@ |
3776 | |
3777 | //#define XTRABACKUP_TARGET_IS_PLUGIN |
3778 | |
3779 | +#include <mysql_version.h> |
3780 | #include <my_base.h> |
3781 | #include <my_getopt.h> |
3782 | -#include <mysql_version.h> |
3783 | #include <mysql_com.h> |
3784 | |
3785 | #if (MYSQL_VERSION_ID < 50100) |
3786 | @@ -59,8 +59,6 @@ |
3787 | #define G_PTR uchar* |
3788 | #endif |
3789 | |
3790 | -#include <univ.i> |
3791 | -#include <os0file.h> |
3792 | #include <os0thread.h> |
3793 | #include <srv0start.h> |
3794 | #include <srv0srv.h> |
3795 | @@ -72,8 +70,6 @@ |
3796 | #include <row0mysql.h> |
3797 | #include <row0sel.h> |
3798 | #include <row0upd.h> |
3799 | -#include <log0log.h> |
3800 | -#include <log0recv.h> |
3801 | #include <lock0lock.h> |
3802 | #include <dict0crea.h> |
3803 | #include <btr0cur.h> |
3804 | @@ -81,9 +77,7 @@ |
3805 | #include <btr0sea.h> |
3806 | #include <fsp0fsp.h> |
3807 | #include <sync0sync.h> |
3808 | -#include <fil0fil.h> |
3809 | #include <trx0xa.h> |
3810 | -#include <btr0sea.h> |
3811 | #include <log0recv.h> |
3812 | #include <fcntl.h> |
3813 | |
3814 | @@ -93,574 +87,11 @@ |
3815 | |
3816 | #include "common.h" |
3817 | #include "datasink.h" |
3818 | -#include "local.h" |
3819 | -#include "stream.h" |
3820 | -#include "compress.h" |
3821 | |
3822 | #include "xb_regex.h" |
3823 | - |
3824 | -#ifndef INNODB_VERSION_SHORT |
3825 | -#define IB_INT64 ib_longlong |
3826 | -#define LSN64 dulint |
3827 | -#define MACH_READ_64 mach_read_from_8 |
3828 | -#define MACH_WRITE_64 mach_write_to_8 |
3829 | -#define OS_MUTEX_CREATE() os_mutex_create(NULL) |
3830 | -#else |
3831 | -#define IB_INT64 ib_int64_t |
3832 | -#define LSN64 ib_uint64_t |
3833 | -#if (MYSQL_VERSION_ID < 50500) |
3834 | -#define MACH_READ_64 mach_read_ull |
3835 | -#define MACH_WRITE_64 mach_write_ull |
3836 | -#define OS_MUTEX_CREATE() os_mutex_create(NULL) |
3837 | -#else |
3838 | -#define MACH_READ_64 mach_read_from_8 |
3839 | -#define MACH_WRITE_64 mach_write_to_8 |
3840 | -#define OS_MUTEX_CREATE() os_mutex_create() |
3841 | -#endif |
3842 | -#define ut_dulint_zero 0 |
3843 | -#define ut_dulint_cmp(A, B) (A > B ? 1 : (A == B ? 0 : -1)) |
3844 | -#define ut_dulint_add(A, B) (A + B) |
3845 | -#define ut_dulint_minus(A, B) (A - B) |
3846 | -#define ut_dulint_align_down(A, B) (A & ~((ib_int64_t)B - 1)) |
3847 | -#define ut_dulint_align_up(A, B) ((A + B - 1) & ~((ib_int64_t)B - 1)) |
3848 | -#endif |
3849 | - |
3850 | -#ifdef __WIN__ |
3851 | -#define SRV_PATH_SEPARATOR '\\' |
3852 | -#define SRV_PATH_SEPARATOR_STR "\\" |
3853 | -#else |
3854 | -#define SRV_PATH_SEPARATOR '/' |
3855 | -#define SRV_PATH_SEPARATOR_STR "/" |
3856 | -#endif |
3857 | - |
3858 | -#ifndef UNIV_PAGE_SIZE_MAX |
3859 | -#define UNIV_PAGE_SIZE_MAX UNIV_PAGE_SIZE |
3860 | -#endif |
3861 | -#ifndef UNIV_PAGE_SIZE_SHIFT_MAX |
3862 | -#define UNIV_PAGE_SIZE_SHIFT_MAX UNIV_PAGE_SIZE_SHIFT |
3863 | -#endif |
3864 | - |
3865 | -#if MYSQL_VERSION_ID >= 50507 |
3866 | -/* |
3867 | - As of MySQL 5.5.7, InnoDB uses thd_wait plugin service. |
3868 | - We have to provide mock functions to avoid linker errors. |
3869 | -*/ |
3870 | -#include <mysql/plugin.h> |
3871 | -#include <mysql/service_thd_wait.h> |
3872 | - |
3873 | -void thd_wait_begin(MYSQL_THD thd, int wait_type) |
3874 | -{ |
3875 | - (void)thd; |
3876 | - (void)wait_type; |
3877 | - return; |
3878 | -} |
3879 | - |
3880 | -void thd_wait_end(MYSQL_THD thd) |
3881 | -{ |
3882 | - (void)thd; |
3883 | - return; |
3884 | -} |
3885 | - |
3886 | -#endif /* MYSQL_VERSION_ID >= 50507 */ |
3887 | - |
3888 | -/* prototypes for static functions in original */ |
3889 | -#ifndef INNODB_VERSION_SHORT |
3890 | -page_t* |
3891 | -btr_node_ptr_get_child( |
3892 | -/*===================*/ |
3893 | - /* out: child page, x-latched */ |
3894 | - rec_t* node_ptr,/* in: node pointer */ |
3895 | - const ulint* offsets,/* in: array returned by rec_get_offsets() */ |
3896 | - mtr_t* mtr); /* in: mtr */ |
3897 | -#else |
3898 | -buf_block_t* |
3899 | -btr_node_ptr_get_child( |
3900 | -/*===================*/ |
3901 | - const rec_t* node_ptr,/*!< in: node pointer */ |
3902 | - dict_index_t* index, /*!< in: index */ |
3903 | - const ulint* offsets,/*!< in: array returned by rec_get_offsets() */ |
3904 | - mtr_t* mtr); /*!< in: mtr */ |
3905 | - |
3906 | -buf_block_t* |
3907 | -btr_root_block_get( |
3908 | -/*===============*/ |
3909 | - dict_index_t* index, /*!< in: index tree */ |
3910 | - mtr_t* mtr); /*!< in: mtr */ |
3911 | -#endif |
3912 | - |
3913 | -int |
3914 | -fil_file_readdir_next_file( |
3915 | -/*=======================*/ |
3916 | - /* out: 0 if ok, -1 if error even after the |
3917 | - retries, 1 if at the end of the directory */ |
3918 | - ulint* err, /* out: this is set to DB_ERROR if an error |
3919 | - was encountered, otherwise not changed */ |
3920 | - const char* dirname,/* in: directory name or path */ |
3921 | - os_file_dir_t dir, /* in: directory stream */ |
3922 | - os_file_stat_t* info); /* in/out: buffer where the info is returned */ |
3923 | - |
3924 | -ibool |
3925 | -recv_check_cp_is_consistent( |
3926 | -/*========================*/ |
3927 | - /* out: TRUE if ok */ |
3928 | - byte* buf); /* in: buffer containing checkpoint info */ |
3929 | - |
3930 | -ulint |
3931 | -recv_find_max_checkpoint( |
3932 | -/*=====================*/ |
3933 | - /* out: error code or DB_SUCCESS */ |
3934 | - log_group_t** max_group, /* out: max group */ |
3935 | - ulint* max_field); /* out: LOG_CHECKPOINT_1 or |
3936 | - LOG_CHECKPOINT_2 */ |
3937 | - |
3938 | -ibool |
3939 | -log_block_checksum_is_ok_or_old_format( |
3940 | -/*===================================*/ |
3941 | - /* out: TRUE if ok, or if the log block may be in the |
3942 | - format of InnoDB version < 3.23.52 */ |
3943 | - byte* block); /* in: pointer to a log block */ |
3944 | - |
3945 | -ulint |
3946 | -open_or_create_log_file( |
3947 | -/*====================*/ |
3948 | - /* out: DB_SUCCESS or error code */ |
3949 | - ibool create_new_db, /* in: TRUE if we should create a |
3950 | - new database */ |
3951 | - ibool* log_file_created, /* out: TRUE if new log file |
3952 | - created */ |
3953 | - ibool log_file_has_been_opened,/* in: TRUE if a log file has been |
3954 | - opened before: then it is an error |
3955 | - to try to create another log file */ |
3956 | - ulint k, /* in: log group number */ |
3957 | - ulint i); /* in: log file number in group */ |
3958 | - |
3959 | -ulint |
3960 | -open_or_create_data_files( |
3961 | -/*======================*/ |
3962 | - /* out: DB_SUCCESS or error code */ |
3963 | - ibool* create_new_db, /* out: TRUE if new database should be |
3964 | - created */ |
3965 | -#ifdef XTRADB_BASED |
3966 | - ibool* create_new_doublewrite_file, |
3967 | -#endif |
3968 | -#ifdef UNIV_LOG_ARCHIVE |
3969 | - ulint* min_arch_log_no,/* out: min of archived log numbers in data |
3970 | - files */ |
3971 | - ulint* max_arch_log_no,/* out: */ |
3972 | -#endif /* UNIV_LOG_ARCHIVE */ |
3973 | - LSN64* min_flushed_lsn,/* out: min of flushed lsn values in data |
3974 | - files */ |
3975 | - LSN64* max_flushed_lsn,/* out: */ |
3976 | - ulint* sum_of_new_sizes);/* out: sum of sizes of the new files added */ |
3977 | - |
3978 | -void |
3979 | -os_file_set_nocache( |
3980 | -/*================*/ |
3981 | - int fd, /* in: file descriptor to alter */ |
3982 | - const char* file_name, /* in: used in the diagnostic message */ |
3983 | - const char* operation_name); /* in: used in the diagnostic message, |
3984 | - we call os_file_set_nocache() |
3985 | - immediately after opening or creating |
3986 | - a file, so this is either "open" or |
3987 | - "create" */ |
3988 | - |
3989 | -/****************************************************************//** |
3990 | -A simple function to open or create a file. |
3991 | -@return own: handle to the file, not defined if error, error number |
3992 | -can be retrieved with os_file_get_last_error */ |
3993 | -UNIV_INLINE |
3994 | -os_file_t |
3995 | -xb_file_create_no_error_handling( |
3996 | -/*=============================*/ |
3997 | - const char* name, /*!< in: name of the file or path as a |
3998 | - null-terminated string */ |
3999 | - ulint create_mode,/*!< in: OS_FILE_OPEN if an existing file |
4000 | - is opened (if does not exist, error), or |
4001 | - OS_FILE_CREATE if a new file is created |
4002 | - (if exists, error) */ |
4003 | - ulint access_type,/*!< in: OS_FILE_READ_ONLY, |
4004 | - OS_FILE_READ_WRITE, or |
4005 | - OS_FILE_READ_ALLOW_DELETE; the last option is |
4006 | - used by a backup program reading the file */ |
4007 | - ibool* success);/*!< out: TRUE if succeed, FALSE if error */ |
4008 | - |
4009 | -/****************************************************************//** |
4010 | -Opens an existing file or creates a new. |
4011 | -@return own: handle to the file, not defined if error, error number |
4012 | -can be retrieved with os_file_get_last_error */ |
4013 | -UNIV_INLINE |
4014 | -os_file_t |
4015 | -xb_file_create( |
4016 | -/*===========*/ |
4017 | - const char* name, /*!< in: name of the file or path as a |
4018 | - null-terminated string */ |
4019 | - ulint create_mode,/*!< in: OS_FILE_OPEN if an existing file |
4020 | - is opened (if does not exist, error), or |
4021 | - OS_FILE_CREATE if a new file is created |
4022 | - (if exists, error), |
4023 | - OS_FILE_OVERWRITE if a new file is created |
4024 | - or an old overwritten; |
4025 | - OS_FILE_OPEN_RAW, if a raw device or disk |
4026 | - partition should be opened */ |
4027 | - ulint purpose,/*!< in: OS_FILE_AIO, if asynchronous, |
4028 | - non-buffered i/o is desired, |
4029 | - OS_FILE_NORMAL, if any normal file; |
4030 | - NOTE that it also depends on type, os_aio_.. |
4031 | - and srv_.. variables whether we really use |
4032 | - async i/o or unbuffered i/o: look in the |
4033 | - function source code for the exact rules */ |
4034 | - ulint type, /*!< in: OS_DATA_FILE or OS_LOG_FILE */ |
4035 | - ibool* success);/*!< out: TRUE if succeed, FALSE if error */ |
4036 | - |
4037 | - |
4038 | -/***********************************************************************//** |
4039 | -Renames a file (can also move it to another directory). It is safest that the |
4040 | -file is closed before calling this function. |
4041 | -@return TRUE if success */ |
4042 | -UNIV_INLINE |
4043 | -ibool |
4044 | -xb_file_rename( |
4045 | -/*===========*/ |
4046 | - const char* oldpath,/*!< in: old file path as a null-terminated |
4047 | - string */ |
4048 | - const char* newpath);/*!< in: new file path */ |
4049 | - |
4050 | -UNIV_INLINE |
4051 | -void |
4052 | -xb_file_set_nocache( |
4053 | -/*================*/ |
4054 | - os_file_t fd, /* in: file descriptor to alter */ |
4055 | - const char* file_name, /* in: used in the diagnostic message */ |
4056 | - const char* operation_name);/* in: used in the diagnostic message, |
4057 | - we call os_file_set_nocache() |
4058 | - immediately after opening or creating |
4059 | - a file, so this is either "open" or |
4060 | - "create" */ |
4061 | - |
4062 | -/***********************************************************************//** |
4063 | -Compatibility wrapper around os_file_flush(). |
4064 | -@return TRUE if success */ |
4065 | -static |
4066 | -ibool |
4067 | -xb_file_flush( |
4068 | -/*==========*/ |
4069 | - os_file_t file); /*!< in, own: handle to a file */ |
4070 | - |
4071 | -/* ==start === definition at fil0fil.c === */ |
4072 | -// ################################################################## |
4073 | -// NOTE: We should check the following definitions fit to the source. |
4074 | -// ################################################################## |
4075 | - |
4076 | -#ifndef INNODB_VERSION_SHORT |
4077 | -//5.0 5.1 |
4078 | -/* File node of a tablespace or the log data space */ |
4079 | -struct fil_node_struct { |
4080 | - fil_space_t* space; /* backpointer to the space where this node |
4081 | - belongs */ |
4082 | - char* name; /* path to the file */ |
4083 | - ibool open; /* TRUE if file open */ |
4084 | - os_file_t handle; /* OS handle to the file, if file open */ |
4085 | - ibool is_raw_disk;/* TRUE if the 'file' is actually a raw |
4086 | - device or a raw disk partition */ |
4087 | - ulint size; /* size of the file in database pages, 0 if |
4088 | - not known yet; the possible last incomplete |
4089 | - megabyte may be ignored if space == 0 */ |
4090 | - ulint n_pending; |
4091 | - /* count of pending i/o's on this file; |
4092 | - closing of the file is not allowed if |
4093 | - this is > 0 */ |
4094 | - ulint n_pending_flushes; |
4095 | - /* count of pending flushes on this file; |
4096 | - closing of the file is not allowed if |
4097 | - this is > 0 */ |
4098 | - ib_longlong modification_counter;/* when we write to the file we |
4099 | - increment this by one */ |
4100 | - ib_longlong flush_counter;/* up to what modification_counter value |
4101 | - we have flushed the modifications to disk */ |
4102 | - UT_LIST_NODE_T(fil_node_t) chain; |
4103 | - /* link field for the file chain */ |
4104 | - UT_LIST_NODE_T(fil_node_t) LRU; |
4105 | - /* link field for the LRU list */ |
4106 | - ulint magic_n; |
4107 | -}; |
4108 | - |
4109 | -struct fil_space_struct { |
4110 | - char* name; /* space name = the path to the first file in |
4111 | - it */ |
4112 | - ulint id; /* space id */ |
4113 | - ib_longlong tablespace_version; |
4114 | - /* in DISCARD/IMPORT this timestamp is used to |
4115 | - check if we should ignore an insert buffer |
4116 | - merge request for a page because it actually |
4117 | - was for the previous incarnation of the |
4118 | - space */ |
4119 | - ibool mark; /* this is set to TRUE at database startup if |
4120 | - the space corresponds to a table in the InnoDB |
4121 | - data dictionary; so we can print a warning of |
4122 | - orphaned tablespaces */ |
4123 | - ibool stop_ios;/* TRUE if we want to rename the .ibd file of |
4124 | - tablespace and want to stop temporarily |
4125 | - posting of new i/o requests on the file */ |
4126 | - ibool stop_ibuf_merges; |
4127 | - /* we set this TRUE when we start deleting a |
4128 | - single-table tablespace */ |
4129 | - ibool is_being_deleted; |
4130 | - /* this is set to TRUE when we start |
4131 | - deleting a single-table tablespace and its |
4132 | - file; when this flag is set no further i/o |
4133 | - or flush requests can be placed on this space, |
4134 | - though there may be such requests still being |
4135 | - processed on this space */ |
4136 | - ulint purpose;/* FIL_TABLESPACE, FIL_LOG, or FIL_ARCH_LOG */ |
4137 | - UT_LIST_BASE_NODE_T(fil_node_t) chain; |
4138 | - /* base node for the file chain */ |
4139 | - ulint size; /* space size in pages; 0 if a single-table |
4140 | - tablespace whose size we do not know yet; |
4141 | - last incomplete megabytes in data files may be |
4142 | - ignored if space == 0 */ |
4143 | - ulint n_reserved_extents; |
4144 | - /* number of reserved free extents for |
4145 | - ongoing operations like B-tree page split */ |
4146 | - ulint n_pending_flushes; /* this is > 0 when flushing |
4147 | - the tablespace to disk; dropping of the |
4148 | - tablespace is forbidden if this is > 0 */ |
4149 | - ulint n_pending_ibuf_merges;/* this is > 0 when merging |
4150 | - insert buffer entries to a page so that we |
4151 | - may need to access the ibuf bitmap page in the |
4152 | - tablespade: dropping of the tablespace is |
4153 | - forbidden if this is > 0 */ |
4154 | - hash_node_t hash; /* hash chain node */ |
4155 | - hash_node_t name_hash;/* hash chain the name_hash table */ |
4156 | - rw_lock_t latch; /* latch protecting the file space storage |
4157 | - allocation */ |
4158 | - UT_LIST_NODE_T(fil_space_t) unflushed_spaces; |
4159 | - /* list of spaces with at least one unflushed |
4160 | - file we have written to */ |
4161 | - ibool is_in_unflushed_spaces; /* TRUE if this space is |
4162 | - currently in the list above */ |
4163 | - UT_LIST_NODE_T(fil_space_t) space_list; |
4164 | - /* list of all spaces */ |
4165 | - ibuf_data_t* ibuf_data; |
4166 | - /* insert buffer data */ |
4167 | - ulint magic_n; |
4168 | -}; |
4169 | -typedef struct fil_system_struct fil_system_t; |
4170 | -struct fil_system_struct { |
4171 | - mutex_t mutex; /* The mutex protecting the cache */ |
4172 | - hash_table_t* spaces; /* The hash table of spaces in the |
4173 | - system; they are hashed on the space |
4174 | - id */ |
4175 | - hash_table_t* name_hash; /* hash table based on the space |
4176 | - name */ |
4177 | - UT_LIST_BASE_NODE_T(fil_node_t) LRU; |
4178 | - /* base node for the LRU list of the |
4179 | - most recently used open files with no |
4180 | - pending i/o's; if we start an i/o on |
4181 | - the file, we first remove it from this |
4182 | - list, and return it to the start of |
4183 | - the list when the i/o ends; |
4184 | - log files and the system tablespace are |
4185 | - not put to this list: they are opened |
4186 | - after the startup, and kept open until |
4187 | - shutdown */ |
4188 | - UT_LIST_BASE_NODE_T(fil_space_t) unflushed_spaces; |
4189 | - /* base node for the list of those |
4190 | - tablespaces whose files contain |
4191 | - unflushed writes; those spaces have |
4192 | - at least one file node where |
4193 | - modification_counter > flush_counter */ |
4194 | - ulint n_open; /* number of files currently open */ |
4195 | - ulint max_n_open; /* n_open is not allowed to exceed |
4196 | - this */ |
4197 | - ib_longlong modification_counter;/* when we write to a file we |
4198 | - increment this by one */ |
4199 | - ulint max_assigned_id;/* maximum space id in the existing |
4200 | - tables, or assigned during the time |
4201 | - mysqld has been up; at an InnoDB |
4202 | - startup we scan the data dictionary |
4203 | - and set here the maximum of the |
4204 | - space id's of the tables there */ |
4205 | - ib_longlong tablespace_version; |
4206 | - /* a counter which is incremented for |
4207 | - every space object memory creation; |
4208 | - every space mem object gets a |
4209 | - 'timestamp' from this; in DISCARD/ |
4210 | - IMPORT this is used to check if we |
4211 | - should ignore an insert buffer merge |
4212 | - request */ |
4213 | - UT_LIST_BASE_NODE_T(fil_space_t) space_list; |
4214 | - /* list of all file spaces */ |
4215 | -}; |
4216 | -#else |
4217 | -//Plugin ? |
4218 | -/** File node of a tablespace or the log data space */ |
4219 | -struct fil_node_struct { |
4220 | - fil_space_t* space; /*!< backpointer to the space where this node |
4221 | - belongs */ |
4222 | - char* name; /*!< path to the file */ |
4223 | - ibool open; /*!< TRUE if file open */ |
4224 | - os_file_t handle; /*!< OS handle to the file, if file open */ |
4225 | - ibool is_raw_disk;/*!< TRUE if the 'file' is actually a raw |
4226 | - device or a raw disk partition */ |
4227 | - ulint size; /*!< size of the file in database pages, 0 if |
4228 | - not known yet; the possible last incomplete |
4229 | - megabyte may be ignored if space == 0 */ |
4230 | - ulint n_pending; |
4231 | - /*!< count of pending i/o's on this file; |
4232 | - closing of the file is not allowed if |
4233 | - this is > 0 */ |
4234 | - ulint n_pending_flushes; |
4235 | - /*!< count of pending flushes on this file; |
4236 | - closing of the file is not allowed if |
4237 | - this is > 0 */ |
4238 | - ib_int64_t modification_counter;/*!< when we write to the file we |
4239 | - increment this by one */ |
4240 | - ib_int64_t flush_counter;/*!< up to what |
4241 | - modification_counter value we have |
4242 | - flushed the modifications to disk */ |
4243 | - UT_LIST_NODE_T(fil_node_t) chain; |
4244 | - /*!< link field for the file chain */ |
4245 | - UT_LIST_NODE_T(fil_node_t) LRU; |
4246 | - /*!< link field for the LRU list */ |
4247 | - ulint magic_n;/*!< FIL_NODE_MAGIC_N */ |
4248 | -}; |
4249 | - |
4250 | -struct fil_space_struct { |
4251 | - char* name; /*!< space name = the path to the first file in |
4252 | - it */ |
4253 | - ulint id; /*!< space id */ |
4254 | - ib_int64_t tablespace_version; |
4255 | - /*!< in DISCARD/IMPORT this timestamp |
4256 | - is used to check if we should ignore |
4257 | - an insert buffer merge request for a |
4258 | - page because it actually was for the |
4259 | - previous incarnation of the space */ |
4260 | - ibool mark; /*!< this is set to TRUE at database startup if |
4261 | - the space corresponds to a table in the InnoDB |
4262 | - data dictionary; so we can print a warning of |
4263 | - orphaned tablespaces */ |
4264 | - ibool stop_ios;/*!< TRUE if we want to rename the |
4265 | - .ibd file of tablespace and want to |
4266 | - stop temporarily posting of new i/o |
4267 | - requests on the file */ |
4268 | - ibool stop_ibuf_merges; |
4269 | - /*!< we set this TRUE when we start |
4270 | - deleting a single-table tablespace */ |
4271 | - ibool is_being_deleted; |
4272 | - /*!< this is set to TRUE when we start |
4273 | - deleting a single-table tablespace and its |
4274 | - file; when this flag is set no further i/o |
4275 | - or flush requests can be placed on this space, |
4276 | - though there may be such requests still being |
4277 | - processed on this space */ |
4278 | - ulint purpose;/*!< FIL_TABLESPACE, FIL_LOG, or |
4279 | - FIL_ARCH_LOG */ |
4280 | - UT_LIST_BASE_NODE_T(fil_node_t) chain; |
4281 | - /*!< base node for the file chain */ |
4282 | - ulint size; /*!< space size in pages; 0 if a single-table |
4283 | - tablespace whose size we do not know yet; |
4284 | - last incomplete megabytes in data files may be |
4285 | - ignored if space == 0 */ |
4286 | - ulint flags; /*!< compressed page size and file format, or 0 */ |
4287 | - ulint n_reserved_extents; |
4288 | - /*!< number of reserved free extents for |
4289 | - ongoing operations like B-tree page split */ |
4290 | - ulint n_pending_flushes; /*!< this is positive when flushing |
4291 | - the tablespace to disk; dropping of the |
4292 | - tablespace is forbidden if this is positive */ |
4293 | - ulint n_pending_ibuf_merges;/*!< this is positive |
4294 | - when merging insert buffer entries to |
4295 | - a page so that we may need to access |
4296 | - the ibuf bitmap page in the |
4297 | - tablespade: dropping of the tablespace |
4298 | - is forbidden if this is positive */ |
4299 | - hash_node_t hash; /*!< hash chain node */ |
4300 | - hash_node_t name_hash;/*!< hash chain the name_hash table */ |
4301 | -#ifndef UNIV_HOTBACKUP |
4302 | - rw_lock_t latch; /*!< latch protecting the file space storage |
4303 | - allocation */ |
4304 | -#endif /* !UNIV_HOTBACKUP */ |
4305 | - UT_LIST_NODE_T(fil_space_t) unflushed_spaces; |
4306 | - /*!< list of spaces with at least one unflushed |
4307 | - file we have written to */ |
4308 | - ibool is_in_unflushed_spaces; /*!< TRUE if this space is |
4309 | - currently in unflushed_spaces */ |
4310 | -#ifdef XTRADB_BASED |
4311 | - ibool is_corrupt; |
4312 | -#endif |
4313 | - UT_LIST_NODE_T(fil_space_t) space_list; |
4314 | - /*!< list of all spaces */ |
4315 | - ulint magic_n;/*!< FIL_SPACE_MAGIC_N */ |
4316 | -}; |
4317 | - |
4318 | -typedef struct fil_system_struct fil_system_t; |
4319 | - |
4320 | -struct fil_system_struct { |
4321 | -#ifndef UNIV_HOTBACKUP |
4322 | - mutex_t mutex; /*!< The mutex protecting the cache */ |
4323 | -#ifdef XTRADB_BASED |
4324 | - mutex_t file_extend_mutex; |
4325 | -#endif |
4326 | -#endif /* !UNIV_HOTBACKUP */ |
4327 | - hash_table_t* spaces; /*!< The hash table of spaces in the |
4328 | - system; they are hashed on the space |
4329 | - id */ |
4330 | - hash_table_t* name_hash; /*!< hash table based on the space |
4331 | - name */ |
4332 | - UT_LIST_BASE_NODE_T(fil_node_t) LRU; |
4333 | - /*!< base node for the LRU list of the |
4334 | - most recently used open files with no |
4335 | - pending i/o's; if we start an i/o on |
4336 | - the file, we first remove it from this |
4337 | - list, and return it to the start of |
4338 | - the list when the i/o ends; |
4339 | - log files and the system tablespace are |
4340 | - not put to this list: they are opened |
4341 | - after the startup, and kept open until |
4342 | - shutdown */ |
4343 | - UT_LIST_BASE_NODE_T(fil_space_t) unflushed_spaces; |
4344 | - /*!< base node for the list of those |
4345 | - tablespaces whose files contain |
4346 | - unflushed writes; those spaces have |
4347 | - at least one file node where |
4348 | - modification_counter > flush_counter */ |
4349 | - ulint n_open; /*!< number of files currently open */ |
4350 | - ulint max_n_open; /*!< n_open is not allowed to exceed |
4351 | - this */ |
4352 | - ib_int64_t modification_counter;/*!< when we write to a file we |
4353 | - increment this by one */ |
4354 | - ulint max_assigned_id;/*!< maximum space id in the existing |
4355 | - tables, or assigned during the time |
4356 | - mysqld has been up; at an InnoDB |
4357 | - startup we scan the data dictionary |
4358 | - and set here the maximum of the |
4359 | - space id's of the tables there */ |
4360 | - ib_int64_t tablespace_version; |
4361 | - /*!< a counter which is incremented for |
4362 | - every space object memory creation; |
4363 | - every space mem object gets a |
4364 | - 'timestamp' from this; in DISCARD/ |
4365 | - IMPORT this is used to check if we |
4366 | - should ignore an insert buffer merge |
4367 | - request */ |
4368 | - UT_LIST_BASE_NODE_T(fil_space_t) space_list; |
4369 | - /*!< list of all file spaces */ |
4370 | - ibool space_id_reuse_warned; |
4371 | - /* !< TRUE if fil_space_create() |
4372 | - has issued a warning about |
4373 | - potential space_id reuse */ |
4374 | -}; |
4375 | - |
4376 | -#endif /* INNODB_VERSION_SHORT */ |
4377 | - |
4378 | -typedef struct { |
4379 | - ulint page_size; |
4380 | -} xb_delta_info_t; |
4381 | - |
4382 | -extern fil_system_t* fil_system; |
4383 | - |
4384 | -/* ==end=== definition at fil0fil.c === */ |
4385 | - |
4386 | +#include "innodb_int.h" |
4387 | +#include "fil_cur.h" |
4388 | +#include "page_write_filt.h" |
4389 | |
4390 | my_bool innodb_inited= 0; |
4391 | |
4392 | @@ -684,7 +115,6 @@ |
4393 | lint io_ticket; |
4394 | os_event_t wait_throttle = NULL; |
4395 | |
4396 | -my_bool xtrabackup_log_only = FALSE; |
4397 | char *xtrabackup_incremental = NULL; |
4398 | LSN64 incremental_lsn; |
4399 | LSN64 incremental_to_lsn; |
4400 | @@ -748,29 +178,23 @@ |
4401 | ib_uint64_t metadata_last_lsn = 0; |
4402 | #endif |
4403 | |
4404 | -#define XB_DELTA_INFO_SUFFIX ".meta" |
4405 | - |
4406 | #define XB_LOG_FILENAME "xtrabackup_logfile" |
4407 | |
4408 | -#ifdef __WIN__ |
4409 | -#define XB_FILE_UNDEFINED NULL |
4410 | -#else |
4411 | -#define XB_FILE_UNDEFINED (-1) |
4412 | -#endif |
4413 | - |
4414 | -int dst_log_fd = XB_FILE_UNDEFINED; |
4415 | -char dst_log_path[FN_REFLEN]; |
4416 | +ds_file_t *dst_log_file = NULL; |
4417 | |
4418 | /* === some variables from mysqld === */ |
4419 | char mysql_real_data_home[FN_REFLEN] = "./"; |
4420 | char *mysql_data_home= mysql_real_data_home; |
4421 | static char mysql_data_home_buff[2]; |
4422 | |
4423 | +<<<<<<< TREE |
4424 | char *opt_mysql_tmpdir = NULL; |
4425 | MY_TMPDIR mysql_tmpdir_list; |
4426 | |
4427 | const char *defaults_group = "mysqld"; |
4428 | |
4429 | +======= |
4430 | +>>>>>>> MERGE-SOURCE |
4431 | /* === static parameters in ha_innodb.cc */ |
4432 | |
4433 | #define HA_INNOBASE_ROWS_IN_TABLE 10000 /* to get optimization right */ |
4434 | @@ -795,7 +219,9 @@ |
4435 | long innobase_open_files = 300L; |
4436 | |
4437 | long innobase_page_size = (1 << 14); /* 16KB */ |
4438 | +#ifdef XTRADB_BASED |
4439 | static ulong innobase_log_block_size = 512; |
4440 | +#endif |
4441 | my_bool innobase_fast_checksum = FALSE; |
4442 | my_bool innobase_extra_undoslots = FALSE; |
4443 | char* innobase_doublewrite_file = NULL; |
4444 | @@ -842,6 +268,16 @@ |
4445 | |
4446 | static char *xtrabackup_debug_sync = NULL; |
4447 | |
4448 | +static my_bool xtrabackup_compact = FALSE; |
4449 | + |
4450 | +/* Datasinks */ |
4451 | +static ds_ctxt_t *ds_data = NULL; |
4452 | +static ds_ctxt_t *ds_meta = NULL; |
4453 | +static ds_ctxt_t *ds_local = NULL; |
4454 | +static ds_ctxt_t *ds_compress = NULL; |
4455 | +static ds_ctxt_t *ds_tmpfile = NULL; |
4456 | +static ds_ctxt_t *ds_stream = NULL; |
4457 | + |
4458 | /* ======== Datafiles iterator ======== */ |
4459 | typedef struct { |
4460 | fil_system_t *system; |
4461 | @@ -922,7 +358,6 @@ |
4462 | uint *count; |
4463 | os_mutex_t count_mutex; |
4464 | os_thread_id_t id; |
4465 | - ds_ctxt_t *ds_ctxt; |
4466 | } data_thread_ctxt_t; |
4467 | |
4468 | /* ======== for option and variables ======== */ |
4469 | @@ -939,7 +374,6 @@ |
4470 | OPT_XTRA_SUSPEND_AT_END, |
4471 | OPT_XTRA_USE_MEMORY, |
4472 | OPT_XTRA_THROTTLE, |
4473 | - OPT_XTRA_LOG_ONLY, |
4474 | OPT_XTRA_INCREMENTAL, |
4475 | OPT_XTRA_INCREMENTAL_BASEDIR, |
4476 | OPT_XTRA_EXTRA_LSNDIR, |
4477 | @@ -996,8 +430,13 @@ |
4478 | OPT_INNODB_SYNC_SPIN_LOOPS, |
4479 | OPT_INNODB_THREAD_CONCURRENCY, |
4480 | OPT_INNODB_THREAD_SLEEP_DELAY, |
4481 | +<<<<<<< TREE |
4482 | OPT_XTRA_DEBUG_SYNC, |
4483 | OPT_DEFAULTS_GROUP |
4484 | +======= |
4485 | + OPT_XTRA_DEBUG_SYNC, |
4486 | + OPT_XTRA_COMPACT |
4487 | +>>>>>>> MERGE-SOURCE |
4488 | }; |
4489 | |
4490 | static struct my_option my_long_options[] = |
4491 | @@ -1036,9 +475,6 @@ |
4492 | {"throttle", OPT_XTRA_THROTTLE, "limit count of IO operations (pairs of read&write) per second to IOS values (for '--backup')", |
4493 | (G_PTR*) &xtrabackup_throttle, (G_PTR*) &xtrabackup_throttle, |
4494 | 0, GET_LONG, REQUIRED_ARG, 0, 0, LONG_MAX, 0, 1, 0}, |
4495 | - {"log-stream", OPT_XTRA_LOG_ONLY, "outputs the contents of 'xtrabackup_logfile' to stdout only until the file 'xtrabackup_suspended' deleted (for '--backup').", |
4496 | - (G_PTR*) &xtrabackup_log_only, (G_PTR*) &xtrabackup_log_only, |
4497 | - 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, |
4498 | {"extra-lsndir", OPT_XTRA_EXTRA_LSNDIR, "(for --backup): save an extra copy of the xtrabackup_checkpoints file in this directory.", |
4499 | (G_PTR*) &xtrabackup_extra_lsndir, (G_PTR*) &xtrabackup_extra_lsndir, |
4500 | 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, |
4501 | @@ -1281,9 +717,17 @@ |
4502 | 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, |
4503 | #endif |
4504 | |
4505 | +<<<<<<< TREE |
4506 | {"defaults_group", OPT_DEFAULTS_GROUP, "defaults group in config file (default \"mysqld\").", |
4507 | (G_PTR*) &defaults_group, (G_PTR*) &defaults_group, |
4508 | 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, |
4509 | +======= |
4510 | + {"compact", OPT_XTRA_COMPACT, |
4511 | + "Create a compact backup by skipping secondary index pages.", |
4512 | + (G_PTR*) &xtrabackup_compact, (G_PTR*) &xtrabackup_compact, |
4513 | + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, |
4514 | + |
4515 | +>>>>>>> MERGE-SOURCE |
4516 | { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} |
4517 | }; |
4518 | |
4519 | @@ -1298,15 +742,13 @@ |
4520 | } |
4521 | #endif |
4522 | |
4523 | -UNIV_INLINE |
4524 | -void |
4525 | +static void |
4526 | debug_sync_point(const char *name) |
4527 | { |
4528 | #ifndef __WIN__ |
4529 | FILE *fp; |
4530 | pid_t pid; |
4531 | char pid_path[FN_REFLEN]; |
4532 | - int stat_loc; |
4533 | |
4534 | if (xtrabackup_debug_sync == NULL) { |
4535 | return; |
4536 | @@ -1432,686 +874,6 @@ |
4537 | return 0; |
4538 | } |
4539 | |
4540 | -/* ================ Dummys =================== */ |
4541 | - |
4542 | -ibool |
4543 | -thd_is_replication_slave_thread( |
4544 | - void* thd) |
4545 | -{ |
4546 | - (void)thd; |
4547 | - msg("xtrabackup: thd_is_replication_slave_thread() is called\n"); |
4548 | - return(FALSE); |
4549 | -} |
4550 | - |
4551 | -ibool |
4552 | -thd_has_edited_nontrans_tables( |
4553 | - void* thd) |
4554 | -{ |
4555 | - (void)thd; |
4556 | - msg("xtrabackup: thd_has_edited_nontrans_tables() is called\n"); |
4557 | - return(FALSE); |
4558 | -} |
4559 | - |
4560 | -ibool |
4561 | -thd_is_select( |
4562 | - const void* thd) |
4563 | -{ |
4564 | - (void)thd; |
4565 | - msg("xtrabackup: thd_is_select() is called\n"); |
4566 | - return(FALSE); |
4567 | -} |
4568 | - |
4569 | -void |
4570 | -innobase_mysql_prepare_print_arbitrary_thd(void) |
4571 | -{ |
4572 | - /* do nothing */ |
4573 | -} |
4574 | - |
4575 | -void |
4576 | -innobase_mysql_end_print_arbitrary_thd(void) |
4577 | -{ |
4578 | - /* do nothing */ |
4579 | -} |
4580 | - |
4581 | -void |
4582 | -innobase_mysql_print_thd( |
4583 | - FILE* f, |
4584 | - void* input_thd, |
4585 | - uint max_query_len) |
4586 | -{ |
4587 | - (void)f; |
4588 | - (void)input_thd; |
4589 | - (void)max_query_len; |
4590 | - msg("xtrabackup: innobase_mysql_print_thd() is called\n"); |
4591 | -} |
4592 | - |
4593 | -void |
4594 | -innobase_get_cset_width( |
4595 | - ulint cset, |
4596 | - ulint* mbminlen, |
4597 | - ulint* mbmaxlen) |
4598 | -{ |
4599 | - CHARSET_INFO* cs; |
4600 | - ut_ad(cset < 256); |
4601 | - ut_ad(mbminlen); |
4602 | - ut_ad(mbmaxlen); |
4603 | - |
4604 | - cs = all_charsets[cset]; |
4605 | - if (cs) { |
4606 | - *mbminlen = cs->mbminlen; |
4607 | - *mbmaxlen = cs->mbmaxlen; |
4608 | - } else { |
4609 | - ut_a(cset == 0); |
4610 | - *mbminlen = *mbmaxlen = 0; |
4611 | - } |
4612 | -} |
4613 | - |
4614 | -void |
4615 | -innobase_convert_from_table_id( |
4616 | -#ifdef INNODB_VERSION_SHORT |
4617 | - struct charset_info_st* cs, |
4618 | -#endif |
4619 | - char* to, |
4620 | - const char* from, |
4621 | - ulint len) |
4622 | -{ |
4623 | -#ifdef INNODB_VERSION_SHORT |
4624 | - (void)cs; |
4625 | -#endif |
4626 | - (void)to; |
4627 | - (void)from; |
4628 | - (void)len; |
4629 | - |
4630 | - msg("xtrabackup: innobase_convert_from_table_id() is called\n"); |
4631 | -} |
4632 | - |
4633 | -void |
4634 | -innobase_convert_from_id( |
4635 | -#ifdef INNODB_VERSION_SHORT |
4636 | - struct charset_info_st* cs, |
4637 | -#endif |
4638 | - char* to, |
4639 | - const char* from, |
4640 | - ulint len) |
4641 | -{ |
4642 | -#ifdef INNODB_VERSION_SHORT |
4643 | - (void)cs; |
4644 | -#endif |
4645 | - (void)to; |
4646 | - (void)from; |
4647 | - (void)len; |
4648 | - msg("xtrabackup: innobase_convert_from_id() is called\n"); |
4649 | -} |
4650 | - |
4651 | -int |
4652 | -innobase_strcasecmp( |
4653 | - const char* a, |
4654 | - const char* b) |
4655 | -{ |
4656 | - return(my_strcasecmp(&my_charset_utf8_general_ci, a, b)); |
4657 | -} |
4658 | - |
4659 | -void |
4660 | -innobase_casedn_str( |
4661 | - char* a) |
4662 | -{ |
4663 | - my_casedn_str(&my_charset_utf8_general_ci, a); |
4664 | -} |
4665 | - |
4666 | -struct charset_info_st* |
4667 | -innobase_get_charset( |
4668 | - void* mysql_thd) |
4669 | -{ |
4670 | - (void)mysql_thd; |
4671 | - msg("xtrabackup: innobase_get_charset() is called\n"); |
4672 | - return(NULL); |
4673 | -} |
4674 | - |
4675 | -const char* |
4676 | -innobase_get_stmt( |
4677 | - void* mysql_thd, |
4678 | - size_t* length) |
4679 | -{ |
4680 | - (void)mysql_thd; |
4681 | - (void)length; |
4682 | - msg("xtrabackup: innobase_get_stmt() is called\n"); |
4683 | - return("nothing"); |
4684 | -} |
4685 | - |
4686 | -int |
4687 | -innobase_mysql_tmpfile(void) |
4688 | -{ |
4689 | - char filename[FN_REFLEN]; |
4690 | - int fd2 = -1; |
4691 | - File fd = create_temp_file(filename, my_tmpdir(&mysql_tmpdir_list), "ib", |
4692 | -#ifdef __WIN__ |
4693 | - O_BINARY | O_TRUNC | O_SEQUENTIAL | |
4694 | - O_TEMPORARY | O_SHORT_LIVED | |
4695 | -#endif /* __WIN__ */ |
4696 | - O_CREAT | O_EXCL | O_RDWR, |
4697 | - MYF(MY_WME)); |
4698 | - if (fd >= 0) { |
4699 | -#ifndef __WIN__ |
4700 | - /* On Windows, open files cannot be removed, but files can be |
4701 | - created with the O_TEMPORARY flag to the same effect |
4702 | - ("delete on close"). */ |
4703 | - unlink(filename); |
4704 | -#endif /* !__WIN__ */ |
4705 | - /* Copy the file descriptor, so that the additional resources |
4706 | - allocated by create_temp_file() can be freed by invoking |
4707 | - my_close(). |
4708 | - |
4709 | - Because the file descriptor returned by this function |
4710 | - will be passed to fdopen(), it will be closed by invoking |
4711 | - fclose(), which in turn will invoke close() instead of |
4712 | - my_close(). */ |
4713 | -#ifdef _WIN32 |
4714 | - /* Note that on Windows, the integer returned by mysql_tmpfile |
4715 | - has no relation to C runtime file descriptor. Here, we need |
4716 | - to call my_get_osfhandle to get the HANDLE and then convert it |
4717 | - to C runtime filedescriptor. */ |
4718 | - { |
4719 | - HANDLE hFile = my_get_osfhandle(fd); |
4720 | - HANDLE hDup; |
4721 | - BOOL bOK = |
4722 | - DuplicateHandle(GetCurrentProcess(), hFile, |
4723 | - GetCurrentProcess(), &hDup, 0, |
4724 | - FALSE, DUPLICATE_SAME_ACCESS); |
4725 | - if(bOK) { |
4726 | - fd2 = _open_osfhandle((intptr_t)hDup,0); |
4727 | - } |
4728 | - else { |
4729 | - my_osmaperr(GetLastError()); |
4730 | - fd2 = -1; |
4731 | - } |
4732 | - } |
4733 | -#else |
4734 | - fd2 = dup(fd); |
4735 | -#endif |
4736 | - if (fd2 < 0) { |
4737 | - msg("xtrabackup: Got error %d on dup\n",fd2); |
4738 | - } |
4739 | - my_close(fd, MYF(MY_WME)); |
4740 | - } |
4741 | - return(fd2); |
4742 | -} |
4743 | - |
4744 | -/*********************************************************************** |
4745 | -Creates a temporary file in tmpdir with a specified prefix in the file |
4746 | -name. The file will be automatically removed on close. |
4747 | -Unlike innobase_mysql_tmpfile(), dup() is not used, so the returned |
4748 | -file must be closed with my_close(). |
4749 | -@return file descriptor or a negative number in case of error.*/ |
4750 | -File |
4751 | -xtrabackup_create_tmpfile(char *path, const char *prefix) |
4752 | -{ |
4753 | - File fd = create_temp_file(path, my_tmpdir(&mysql_tmpdir_list), |
4754 | - prefix, |
4755 | -#ifdef __WIN__ |
4756 | - O_BINARY | O_TRUNC | O_SEQUENTIAL | |
4757 | - O_TEMPORARY | O_SHORT_LIVED | |
4758 | -#endif /* __WIN__ */ |
4759 | - O_CREAT | O_EXCL | O_RDWR, |
4760 | - MYF(MY_WME)); |
4761 | -#ifndef __WIN__ |
4762 | - if (fd >= 0) { |
4763 | - /* On Windows, open files cannot be removed, but files can be |
4764 | - created with the O_TEMPORARY flag to the same effect |
4765 | - ("delete on close"). */ |
4766 | - unlink(path); |
4767 | - } |
4768 | -#endif /* !__WIN__ */ |
4769 | - |
4770 | - return(fd); |
4771 | -} |
4772 | - |
4773 | -void |
4774 | -innobase_invalidate_query_cache( |
4775 | - trx_t* trx, |
4776 | -#ifndef INNODB_VERSION_SHORT |
4777 | - char* full_name, |
4778 | -#else |
4779 | - const char* full_name, |
4780 | -#endif |
4781 | - ulint full_name_len) |
4782 | -{ |
4783 | - (void)trx; |
4784 | - (void)full_name; |
4785 | - (void)full_name_len; |
4786 | - /* do nothing */ |
4787 | -} |
4788 | - |
4789 | -int |
4790 | -mysql_get_identifier_quote_char( |
4791 | - trx_t* trx, |
4792 | - const char* name, |
4793 | - ulint namelen) |
4794 | -{ |
4795 | - (void)trx; |
4796 | - (void)name; |
4797 | - (void)namelen; |
4798 | - return '"'; |
4799 | -} |
4800 | - |
4801 | -void |
4802 | -innobase_print_identifier( |
4803 | - FILE* f, |
4804 | - trx_t* trx __attribute__((unused)), |
4805 | - ibool table_id __attribute__((unused)), |
4806 | - const char* name, |
4807 | - ulint namelen) |
4808 | -{ |
4809 | - const char* s = name; |
4810 | - const char* e = s + namelen; |
4811 | - int q; |
4812 | - |
4813 | - q = '"'; |
4814 | - |
4815 | - putc(q, f); |
4816 | - while (s < e) { |
4817 | - int c = *s++; |
4818 | - if (c == q) { |
4819 | - putc(c, f); |
4820 | - } |
4821 | - putc(c, f); |
4822 | - } |
4823 | - putc(q, f); |
4824 | -} |
4825 | - |
4826 | -/**********************************************************************//** |
4827 | -It should be safe to use lower_case_table_names=0 for xtrabackup. If it causes |
4828 | -any problems, we can add the lower_case_table_names option to xtrabackup |
4829 | -later. |
4830 | -@return 0 */ |
4831 | -ulint |
4832 | -innobase_get_lower_case_table_names(void) |
4833 | -/*=====================================*/ |
4834 | -{ |
4835 | - return(0); |
4836 | -} |
4837 | - |
4838 | -/******************************************************************//** |
4839 | -Strip dir name from a full path name and return only the file name |
4840 | -@return file name or "null" if no file name */ |
4841 | -const char* |
4842 | -innobase_basename( |
4843 | -/*==============*/ |
4844 | - const char* path_name) /*!< in: full path name */ |
4845 | -{ |
4846 | - const char* name = base_name(path_name); |
4847 | - |
4848 | - return((name) ? name : "null"); |
4849 | -} |
4850 | - |
4851 | -/*****************************************************************//** |
4852 | -Convert an SQL identifier to the MySQL system_charset_info (UTF-8) |
4853 | -and quote it if needed. |
4854 | -@return pointer to the end of buf */ |
4855 | -static |
4856 | -char* |
4857 | -innobase_convert_identifier( |
4858 | -/*========================*/ |
4859 | - char* buf, /*!< out: buffer for converted identifier */ |
4860 | - ulint buflen, /*!< in: length of buf, in bytes */ |
4861 | - const char* id, /*!< in: identifier to convert */ |
4862 | - ulint idlen, /*!< in: length of id, in bytes */ |
4863 | - void* thd __attribute__((unused)), |
4864 | - /*!< in: MySQL connection thread, or NULL */ |
4865 | - ibool file_id __attribute__((unused))) |
4866 | - /*!< in: TRUE=id is a table or database name; |
4867 | - FALSE=id is an UTF-8 string */ |
4868 | -{ |
4869 | - const char* s = id; |
4870 | - int q; |
4871 | - |
4872 | - /* See if the identifier needs to be quoted. */ |
4873 | - q = '"'; |
4874 | - |
4875 | - if (q == EOF) { |
4876 | - if (UNIV_UNLIKELY(idlen > buflen)) { |
4877 | - idlen = buflen; |
4878 | - } |
4879 | - memcpy(buf, s, idlen); |
4880 | - return(buf + idlen); |
4881 | - } |
4882 | - |
4883 | - /* Quote the identifier. */ |
4884 | - if (buflen < 2) { |
4885 | - return(buf); |
4886 | - } |
4887 | - |
4888 | - *buf++ = q; |
4889 | - buflen--; |
4890 | - |
4891 | - for (; idlen; idlen--) { |
4892 | - int c = *s++; |
4893 | - if (UNIV_UNLIKELY(c == q)) { |
4894 | - if (UNIV_UNLIKELY(buflen < 3)) { |
4895 | - break; |
4896 | - } |
4897 | - |
4898 | - *buf++ = c; |
4899 | - *buf++ = c; |
4900 | - buflen -= 2; |
4901 | - } else { |
4902 | - if (UNIV_UNLIKELY(buflen < 2)) { |
4903 | - break; |
4904 | - } |
4905 | - |
4906 | - *buf++ = c; |
4907 | - buflen--; |
4908 | - } |
4909 | - } |
4910 | - |
4911 | - *buf++ = q; |
4912 | - return(buf); |
4913 | -} |
4914 | - |
4915 | -/*****************************************************************//** |
4916 | -Convert a table or index name to the MySQL system_charset_info (UTF-8) |
4917 | -and quote it if needed. |
4918 | -@return pointer to the end of buf */ |
4919 | -char* |
4920 | -innobase_convert_name( |
4921 | -/*==================*/ |
4922 | - char* buf, /*!< out: buffer for converted identifier */ |
4923 | - ulint buflen, /*!< in: length of buf, in bytes */ |
4924 | - const char* id, /*!< in: identifier to convert */ |
4925 | - ulint idlen, /*!< in: length of id, in bytes */ |
4926 | - void* thd, /*!< in: MySQL connection thread, or NULL */ |
4927 | - ibool table_id)/*!< in: TRUE=id is a table or database name; |
4928 | - FALSE=id is an index name */ |
4929 | -{ |
4930 | - char* s = buf; |
4931 | - const char* bufend = buf + buflen; |
4932 | - |
4933 | - if (table_id) { |
4934 | - const char* slash = (const char*) memchr(id, '/', idlen); |
4935 | - if (!slash) { |
4936 | - |
4937 | - goto no_db_name; |
4938 | - } |
4939 | - |
4940 | - /* Print the database name and table name separately. */ |
4941 | - s = innobase_convert_identifier(s, bufend - s, id, slash - id, |
4942 | - thd, TRUE); |
4943 | - if (UNIV_LIKELY(s < bufend)) { |
4944 | - *s++ = '.'; |
4945 | - s = innobase_convert_identifier(s, bufend - s, |
4946 | - slash + 1, idlen |
4947 | - - (slash - id) - 1, |
4948 | - thd, TRUE); |
4949 | - } |
4950 | -#ifdef INNODB_VERSION_SHORT |
4951 | - } else if (UNIV_UNLIKELY(*id == TEMP_INDEX_PREFIX)) { |
4952 | - /* Temporary index name (smart ALTER TABLE) */ |
4953 | - const char temp_index_suffix[]= "--temporary--"; |
4954 | - |
4955 | - s = innobase_convert_identifier(buf, buflen, id + 1, idlen - 1, |
4956 | - thd, FALSE); |
4957 | - if (s - buf + (sizeof temp_index_suffix - 1) < buflen) { |
4958 | - memcpy(s, temp_index_suffix, |
4959 | - sizeof temp_index_suffix - 1); |
4960 | - s += sizeof temp_index_suffix - 1; |
4961 | - } |
4962 | -#endif |
4963 | - } else { |
4964 | -no_db_name: |
4965 | - s = innobase_convert_identifier(buf, buflen, id, idlen, |
4966 | - thd, table_id); |
4967 | - } |
4968 | - |
4969 | - return(s); |
4970 | - |
4971 | -} |
4972 | - |
4973 | -ibool |
4974 | -trx_is_interrupted( |
4975 | - trx_t* trx) |
4976 | -{ |
4977 | - (void)trx; |
4978 | - /* There are no mysql_thd */ |
4979 | - return(FALSE); |
4980 | -} |
4981 | - |
4982 | -int |
4983 | -innobase_mysql_cmp( |
4984 | - int mysql_type, |
4985 | - uint charset_number, |
4986 | - unsigned char* a, |
4987 | - unsigned int a_length, |
4988 | - unsigned char* b, |
4989 | - unsigned int b_length) |
4990 | -{ |
4991 | - CHARSET_INFO* charset; |
4992 | - enum enum_field_types mysql_tp; |
4993 | - int ret; |
4994 | - |
4995 | - DBUG_ASSERT(a_length != UNIV_SQL_NULL); |
4996 | - DBUG_ASSERT(b_length != UNIV_SQL_NULL); |
4997 | - |
4998 | - mysql_tp = (enum enum_field_types) mysql_type; |
4999 | - |
5000 | - switch (mysql_tp) { |
Jenkins in progress at http:// jenkins. percona. com/job/ percona- xtrabackup- param/182/ , I will add a note once it completes.