Merge lp:~sergei.glushchenko/percona-xtrabackup/xb20-databases into lp:percona-xtrabackup/2.0
- xb20-databases
- Merge into 2.0
Status: | Superseded |
---|---|
Proposed branch: | lp:~sergei.glushchenko/percona-xtrabackup/xb20-databases |
Merge into: | lp:percona-xtrabackup/2.0 |
Diff against target: |
1012 lines (+706/-130) 8 files modified
doc/source/innobackupex/partial_backups_innobackupex.rst (+1/-4) doc/source/xtrabackup_bin/partial_backups.rst (+6/-1) doc/source/xtrabackup_bin/xbk_option_reference.rst (+8/-0) innobackupex (+7/-0) src/xtrabackup.c (+356/-125) test/t/ib_databases.sh (+50/-0) test/t/ib_databases_file.sh (+57/-0) test/t/xb_databases_options.sh (+221/-0) |
To merge this branch: | bzr merge lp:~sergei.glushchenko/percona-xtrabackup/xb20-databases |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Laurynas Biveinis (community) | Needs Fixing | ||
Review via email: mp+143063@code.launchpad.net |
Commit message
Description of the change
Bug 569387
xtrabackup ignores --databases, i.e. when --databases
is specified it affects only innobackupex script,
InnoDB data will be copied fully.
--databases and --databases-file options been introduced
for xtrabackup binary, which cover two modes of --databases
option of innobackupex.
Sergei Glushchenko (sergei.glushchenko) wrote : | # |
Sergei Glushchenko (sergei.glushchenko) wrote : | # |
have conflicts. looking
Sergei Glushchenko (sergei.glushchenko) wrote : | # |
conflict resolved
Laurynas Biveinis (laurynas-biveinis) wrote : | # |
Code:
- the commit message does not describe the changes done to
xtrabackup.c.
- please make static the variables and functions that are local to
xtrabackup.c.
- I don't think table_hash_
be handled by tables_hash != NULL check.
- Likewise for database_
- use my_malloc(.., MYF(MY_FAE)); instead of plain malloc and its
result check in xb_new_
value of xb_new_
- please assert in xb_new_
violate MySQL name limits: 64 chars for db name, 64 chars for
table name, and a dot.
- Line 243: missing || xtrabackup_
have caused a crash for the new ib_databases_
replace this by lazy initialization of hash tables that actually
get any insertions.
- Lines 243--248: why both hashes are created unconditionally? I
think the logic should be: init table hash, if any of table or db
options given; init db hash, if any of db options given.
- Lines 244 and 246: redundant comments.
- Line 255: why strtok_r instead of strtok? I don't think the
reentrancy is needed here?
- The hash insert code is duplicated for the xtrabackup_
and x_d_file hash insertion in xb_filters_init(), please make a
function.
- Please validate the provided names in xb_filter_init against
length.
- How are duplicate names handled in the hash tables?
Testcases:
- The existing testcases test the IB options and how IB works with
XB fine. But I think that an XB-specific testcase is necessary
as well. It should:
- test the XB options;
- test invalid input (too long table and database names, non
existing tables and databases, illegal characters, duplicate
filters, etc).
Documentation:
- diff lines 8 and 9: use "either ... or" instead of "whether", s/-
or a/, or a.
- diff line 43: cannot parse "names" in "Only names databases and tables will
be backed up."
Sergei Glushchenko (sergei.glushchenko) wrote : | # |
Code:
> - the commit message does not describe the changes done to
> xtrabackup.c.
Commit message has been changed.
> - please make static the variables and functions that are local to
> xtrabackup.c.
done.
> - I don't think table_hash_
> be handled by tables_hash != NULL check.
>
> - Likewise for database_
filters init code has been refactored
> - use my_malloc(.., MYF(MY_FAE)); instead of plain malloc and its
> result check in xb_new_
> value of xb_new_
ut_malloc has been used.
> - please assert in xb_new_
> violate MySQL name limits: 64 chars for db name, 64 chars for
> table name, and a dot.
>
> - Line 243: missing || xtrabackup_
> have caused a crash for the new ib_databases_
> replace this by lazy initialization of hash tables that actually
> get any insertions.
>
> - Lines 243--248: why both hashes are created unconditionally? I
> think the logic should be: init table hash, if any of table or db
> options given; init db hash, if any of db options given.
>
> - Lines 244 and 246: redundant comments.
filters init code has been refactored
> - Line 255: why strtok_r instead of strtok? I don't think the
> reentrancy is needed here?
I really like strtok_r more because of it design. Don't like functions, which
state is saved globally between invocations.
> - The hash insert code is duplicated for the xtrabackup_
> and x_d_file hash insertion in xb_filters_init(), please make a
> function.
>
> - Please validate the provided names in xb_filter_init against
> length.
filters init code has been refactored
> - How are duplicate names handled in the hash tables?
hash tables resolve collisions with linked list, so it will impact on
performance if we have *a lot* of duplicate entries in tables file, or
databases file. I don't think it is a case.
Testcases:
- The existing testcases test the IB options and how IB works with
XB fine. But I think that an XB-specific testcase is necessary
as well. It should:
- test the XB options;
- test invalid input (too long table and database names, non
existing tables and databases, illegal characters, duplicate
filters, etc).
> Documentation:
> - diff lines 8 and 9: use "either ... or" instead of "whether", s/-
> or a/, or a.
>
> - diff line 43: cannot parse "names" in "Only names databases and tables will
> be backed up."
fixed
Sergei Glushchenko (sergei.glushchenko) wrote : | # |
Laurynas Biveinis (laurynas-biveinis) wrote : | # |
- Please rebase on the current trunk GCAs. The C++ conversion might
require a tweak or two. Also that will require some testcase
changes, described below.
- Please make variable definitions that are local to xtrabackup.c
static as well, not only functions.
- Diff line 189: "There aren't tables specified ... " -> "There are
no tables specified ... "
- Diff line 240: s/sucessfull/
- In xb_register_
to the block start.
- Diff line 412: s/etnries/entries
- Diff line 434: likewise.
- After the rebase, ib_databases.sh, ib_databases_
current stop_server that kill -9s the server and thus encourages
not a partial but full data dir overwrite to restore. Thus please
backup mysql and performance_schema as well, and rm -rf the
whole datadir.
- In xb_database_
... can be replaced by xtrabackup ...
- Does "diff -u <(ls_dir $backup_dir)" fail the test on a diff
difference found?
Sergei Glushchenko (sergei.glushchenko) wrote : | # |
Laurynas,
Thanks for the review, I'd like to rebase this branch on the latest trunk when https:/
Thanks,
Sergei
Unmerged revisions
- 496. By Sergei Glushchenko
-
Bug 569387
xtrabackup ignores --databases, i.e. when --databases
is specified it affects only innobackupex script,
InnoDB data will be copied fully.
two options have been added for xtrabackup
* --databases is a space separated list of entries database_name[.table_ name]
* --databases-file is a name of file which contains
entries database_name[.table_ name] one entry per line
* check_if_skip_table has been modified to check whether database is
enabled first and after check the table
* databases and tables filters initialization has been refactored
in order to avoid code duplication
innnobackupex's --databases option is mapped to one of these options,
depending on value.
Bug 1131084
Unneccessary/debug print in xtrabackup output.
There was msg("xtrabackup: tables regcomp(%s): %s\n", p, errbuf);
which has been removed in this branch.
Preview Diff
1 | === modified file 'doc/source/innobackupex/partial_backups_innobackupex.rst' | |||
2 | --- doc/source/innobackupex/partial_backups_innobackupex.rst 2012-09-19 11:35:43 +0000 | |||
3 | +++ doc/source/innobackupex/partial_backups_innobackupex.rst 2013-02-25 08:01:21 +0000 | |||
4 | @@ -42,7 +42,7 @@ | |||
5 | 42 | Using the :option:`--databases` option | 42 | Using the :option:`--databases` option |
6 | 43 | -------------------------------------- | 43 | -------------------------------------- |
7 | 44 | 44 | ||
9 | 45 | This option is specific to |innobackupex| and accepts whether a space-separated list of the databases and tables to backup - in the ``databasename[.tablename]`` form - or a file containing the list at one element per line. | 45 | This option accepts eigther a space-separated list of the databases and tables to backup - in the ``databasename[.tablename]`` form - or a file containing the list at one element per line. |
10 | 46 | 46 | ||
11 | 47 | For example, :: | 47 | For example, :: |
12 | 48 | 48 | ||
13 | @@ -50,9 +50,6 @@ | |||
14 | 50 | 50 | ||
15 | 51 | will create a timestamped directory with the usual files that |innobackupex| creates, but only containing the data-files related to ``mytable`` in the ``mydatabase`` directory and the ``mysql`` directory with the entire ``mysql`` database. | 51 | will create a timestamped directory with the usual files that |innobackupex| creates, but only containing the data-files related to ``mytable`` in the ``mydatabase`` directory and the ``mysql`` directory with the entire ``mysql`` database. |
16 | 52 | 52 | ||
17 | 53 | .. note:: | ||
18 | 54 | |||
19 | 55 | Currently in XtraBackup the --databases option has no effect for InnoDB files for both local and streaming backups, i.e. all InnoDB files are always backed up. Currently, only .frm and non-InnoDB tables are limited by that option. | ||
20 | 56 | 53 | ||
21 | 57 | Preparing Partial Backups | 54 | Preparing Partial Backups |
22 | 58 | ========================= | 55 | ========================= |
23 | 59 | 56 | ||
24 | === modified file 'doc/source/xtrabackup_bin/partial_backups.rst' | |||
25 | --- doc/source/xtrabackup_bin/partial_backups.rst 2011-07-07 05:32:50 +0000 | |||
26 | +++ doc/source/xtrabackup_bin/partial_backups.rst 2013-02-25 08:01:21 +0000 | |||
27 | @@ -2,7 +2,7 @@ | |||
28 | 2 | Partial Backups | 2 | Partial Backups |
29 | 3 | ================= | 3 | ================= |
30 | 4 | 4 | ||
32 | 5 | |xtrabackup| supports taking partial backups when the :term:`innodb_file_per_table` option is enabled. There are two ways to create partial backups: matching the tables' names with a regular expression or providing a list of them in a file. | 5 | |xtrabackup| supports taking partial backups when the :term:`innodb_file_per_table` option is enabled. There are three ways to create partial backups: matching the tables' names with a regular expression, providing a list of them in a file or providing a list of databases. |
33 | 6 | 6 | ||
34 | 7 | .. warning:: If any of the matched or listed tables is deleted during the backup, |xtrabackup| will fail. | 7 | .. warning:: If any of the matched or listed tables is deleted during the backup, |xtrabackup| will fail. |
35 | 8 | 8 | ||
36 | @@ -30,6 +30,11 @@ | |||
37 | 30 | 30 | ||
38 | 31 | |check| errors? outputs? | 31 | |check| errors? outputs? |
39 | 32 | 32 | ||
40 | 33 | Using the :option:`--databases` and :option:`--databases-file` options | ||
41 | 34 | ====================================================================== | ||
42 | 35 | |||
43 | 36 | The ``--databases`` option accepts a space-separated list of the databases and tables to backup - in the ``databasename[.tablename]`` form. The ``--databases-file`` option specifies a file that can contain multiple databases and tables in the ``databasename[.tablename]`` form, one element name per line in the file. Only named databases and tables will be backed up. Names are matched exactly, case-sensitive, with no pattern or regular expression matching. | ||
44 | 37 | |||
45 | 33 | Preparing the Backup | 38 | Preparing the Backup |
46 | 34 | ==================== | 39 | ==================== |
47 | 35 | 40 | ||
48 | 36 | 41 | ||
49 | === modified file 'doc/source/xtrabackup_bin/xbk_option_reference.rst' | |||
50 | --- doc/source/xtrabackup_bin/xbk_option_reference.rst 2012-05-18 11:19:17 +0000 | |||
51 | +++ doc/source/xtrabackup_bin/xbk_option_reference.rst 2013-02-25 08:01:21 +0000 | |||
52 | @@ -17,6 +17,14 @@ | |||
53 | 17 | 17 | ||
54 | 18 | Don't read default options from any option file. Must be given as the first option on the command-line. | 18 | Don't read default options from any option file. Must be given as the first option on the command-line. |
55 | 19 | 19 | ||
56 | 20 | .. option:: --databases=# | ||
57 | 21 | |||
58 | 22 | This option specifies the list of databases and tables that should be backed up. The option accepts the list of the form ``"databasename1[.table_name1] databasename2[.table_name2] . . ."``. | ||
59 | 23 | |||
60 | 24 | .. option:: --databases-file=# | ||
61 | 25 | |||
62 | 26 | This option specifies the path to the file containing the list of databases and tables that should be backed up. The file can contain the list elements of the form ``databasename1[.table_name1]``, one element per line. | ||
63 | 27 | |||
64 | 20 | .. option:: --defaults-file=# | 28 | .. option:: --defaults-file=# |
65 | 21 | 29 | ||
66 | 22 | Only read default options from the given file. Must be given as the first option on the command-line. Must be a real file; it cannot be a symbolic link. | 30 | Only read default options from the given file. Must be given as the first option on the command-line. Must be a real file; it cannot be a symbolic link. |
67 | 23 | 31 | ||
68 | === modified file 'innobackupex' | |||
69 | --- innobackupex 2013-01-17 15:08:37 +0000 | |||
70 | +++ innobackupex 2013-02-25 08:01:21 +0000 | |||
71 | @@ -1067,6 +1067,13 @@ | |||
72 | 1067 | if ($option_stream) { | 1067 | if ($option_stream) { |
73 | 1068 | $options = $options . " --stream=$option_stream"; | 1068 | $options = $options . " --stream=$option_stream"; |
74 | 1069 | } | 1069 | } |
75 | 1070 | if ($option_databases) { | ||
76 | 1071 | if ($option_databases =~ /^\//) { | ||
77 | 1072 | $options = $options . " --databases_file='$option_databases'"; | ||
78 | 1073 | } else { | ||
79 | 1074 | $options = $options . " --databases='$option_databases'"; | ||
80 | 1075 | } | ||
81 | 1076 | } | ||
82 | 1070 | $cmdline = "$option_ibbackup_binary $options"; | 1077 | $cmdline = "$option_ibbackup_binary $options"; |
83 | 1071 | 1078 | ||
84 | 1072 | # run ibbackup as a child process | 1079 | # run ibbackup as a child process |
85 | 1073 | 1080 | ||
86 | === modified file 'src/xtrabackup.c' | |||
87 | --- src/xtrabackup.c 2013-01-13 22:34:01 +0000 | |||
88 | +++ src/xtrabackup.c 2013-02-25 08:01:21 +0000 | |||
89 | @@ -87,6 +87,7 @@ | |||
90 | 87 | #include <log0recv.h> | 87 | #include <log0recv.h> |
91 | 88 | #include <fcntl.h> | 88 | #include <fcntl.h> |
92 | 89 | #include <buf0lru.h> | 89 | #include <buf0lru.h> |
93 | 90 | #include <string.h> | ||
94 | 90 | 91 | ||
95 | 91 | #ifdef INNODB_VERSION_SHORT | 92 | #ifdef INNODB_VERSION_SHORT |
96 | 92 | #include <ibuf0ibuf.h> | 93 | #include <ibuf0ibuf.h> |
97 | @@ -660,7 +661,7 @@ | |||
98 | 660 | 661 | ||
99 | 661 | #ifdef INNODB_VERSION_SHORT | 662 | #ifdef INNODB_VERSION_SHORT |
100 | 662 | #define XB_HASH_SEARCH(NAME, TABLE, FOLD, DATA, ASSERTION, TEST) \ | 663 | #define XB_HASH_SEARCH(NAME, TABLE, FOLD, DATA, ASSERTION, TEST) \ |
102 | 663 | HASH_SEARCH(NAME, TABLE, FOLD, xtrabackup_tables_t*, DATA, ASSERTION, \ | 664 | HASH_SEARCH(NAME, TABLE, FOLD, xtrabackup_filter_entry_t*, DATA, ASSERTION, \ |
103 | 664 | TEST) | 665 | TEST) |
104 | 665 | #else | 666 | #else |
105 | 666 | #define XB_HASH_SEARCH(NAME, TABLE, FOLD, DATA, ASSERTION, TEST) \ | 667 | #define XB_HASH_SEARCH(NAME, TABLE, FOLD, DATA, ASSERTION, TEST) \ |
106 | @@ -807,18 +808,30 @@ | |||
107 | 807 | char *xtrabackup_incremental_dir = NULL; /* for --prepare */ | 808 | char *xtrabackup_incremental_dir = NULL; /* for --prepare */ |
108 | 808 | 809 | ||
109 | 809 | char *xtrabackup_tables = NULL; | 810 | char *xtrabackup_tables = NULL; |
112 | 810 | int tables_regex_num; | 811 | |
113 | 811 | xb_regex_t *tables_regex; | 812 | /* List of regular expressions for filtering */ |
114 | 813 | typedef struct xb_regex_list_node_struct xb_regex_list_node_t; | ||
115 | 814 | struct xb_regex_list_node_struct { | ||
116 | 815 | UT_LIST_NODE_T(xb_regex_list_node_t) regex_list; | ||
117 | 816 | xb_regex_t regex; | ||
118 | 817 | }; | ||
119 | 818 | UT_LIST_BASE_NODE_T(xb_regex_list_node_t) regex_list; | ||
120 | 819 | |||
121 | 812 | xb_regmatch_t tables_regmatch[1]; | 820 | xb_regmatch_t tables_regmatch[1]; |
122 | 813 | 821 | ||
123 | 814 | char *xtrabackup_tables_file = NULL; | 822 | char *xtrabackup_tables_file = NULL; |
127 | 815 | hash_table_t* tables_hash; | 823 | hash_table_t* tables_hash = NULL; |
128 | 816 | 824 | ||
129 | 817 | struct xtrabackup_tables_struct{ | 825 | char *xtrabackup_databases = NULL; |
130 | 826 | char *xtrabackup_databases_file = NULL; | ||
131 | 827 | hash_table_t* databases_hash = NULL; | ||
132 | 828 | |||
133 | 829 | struct xtrabackup_filter_entry_struct{ | ||
134 | 818 | char* name; | 830 | char* name; |
135 | 831 | ibool has_tables_specified; | ||
136 | 819 | hash_node_t name_hash; | 832 | hash_node_t name_hash; |
137 | 820 | }; | 833 | }; |
139 | 821 | typedef struct xtrabackup_tables_struct xtrabackup_tables_t; | 834 | typedef struct xtrabackup_filter_entry_struct xtrabackup_filter_entry_t; |
140 | 822 | 835 | ||
141 | 823 | #ifdef XTRADB_BASED | 836 | #ifdef XTRADB_BASED |
142 | 824 | static ulint thread_nr[SRV_MAX_N_IO_THREADS + 6 + 64]; | 837 | static ulint thread_nr[SRV_MAX_N_IO_THREADS + 6 + 64]; |
143 | @@ -1059,6 +1072,8 @@ | |||
144 | 1059 | OPT_XTRA_INCREMENTAL_DIR, | 1072 | OPT_XTRA_INCREMENTAL_DIR, |
145 | 1060 | OPT_XTRA_TABLES, | 1073 | OPT_XTRA_TABLES, |
146 | 1061 | OPT_XTRA_TABLES_FILE, | 1074 | OPT_XTRA_TABLES_FILE, |
147 | 1075 | OPT_XTRA_DATABASES, | ||
148 | 1076 | OPT_XTRA_DATABASES_FILE, | ||
149 | 1062 | OPT_XTRA_CREATE_IB_LOGFILE, | 1077 | OPT_XTRA_CREATE_IB_LOGFILE, |
150 | 1063 | OPT_XTRA_PARALLEL, | 1078 | OPT_XTRA_PARALLEL, |
151 | 1064 | OPT_XTRA_STREAM, | 1079 | OPT_XTRA_STREAM, |
152 | @@ -1174,6 +1189,12 @@ | |||
153 | 1174 | {"tables_file", OPT_XTRA_TABLES_FILE, "filtering by list of the exact database.table name in the file.", | 1189 | {"tables_file", OPT_XTRA_TABLES_FILE, "filtering by list of the exact database.table name in the file.", |
154 | 1175 | (G_PTR*) &xtrabackup_tables_file, (G_PTR*) &xtrabackup_tables_file, | 1190 | (G_PTR*) &xtrabackup_tables_file, (G_PTR*) &xtrabackup_tables_file, |
155 | 1176 | 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, | 1191 | 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, |
156 | 1192 | {"databases", OPT_XTRA_DATABASES, "filtering by list of databases.", | ||
157 | 1193 | (G_PTR*) &xtrabackup_databases, (G_PTR*) &xtrabackup_databases, | ||
158 | 1194 | 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, | ||
159 | 1195 | {"databases_file", OPT_XTRA_TABLES_FILE, "filtering by list of databases in the file.", | ||
160 | 1196 | (G_PTR*) &xtrabackup_databases_file, (G_PTR*) &xtrabackup_databases_file, | ||
161 | 1197 | 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, | ||
162 | 1177 | {"create-ib-logfile", OPT_XTRA_CREATE_IB_LOGFILE, "** not work for now** creates ib_logfile* also after '--prepare'. ### If you want create ib_logfile*, only re-execute this command in same options. ###", | 1198 | {"create-ib-logfile", OPT_XTRA_CREATE_IB_LOGFILE, "** not work for now** creates ib_logfile* also after '--prepare'. ### If you want create ib_logfile*, only re-execute this command in same options. ###", |
163 | 1178 | (G_PTR*) &xtrabackup_create_ib_logfile, (G_PTR*) &xtrabackup_create_ib_logfile, | 1199 | (G_PTR*) &xtrabackup_create_ib_logfile, (G_PTR*) &xtrabackup_create_ib_logfile, |
164 | 1179 | 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, | 1200 | 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, |
165 | @@ -2900,7 +2921,9 @@ | |||
166 | 2900 | char *eptr; | 2921 | char *eptr; |
167 | 2901 | int dbname_len; | 2922 | int dbname_len; |
168 | 2902 | 2923 | ||
170 | 2903 | if (xtrabackup_tables == NULL && xtrabackup_tables_file == NULL) { | 2924 | if (UT_LIST_GET_LEN(regex_list) == 0 && |
171 | 2925 | tables_hash == NULL && | ||
172 | 2926 | databases_hash == NULL) { | ||
173 | 2904 | return(FALSE); | 2927 | return(FALSE); |
174 | 2905 | } | 2928 | } |
175 | 2906 | 2929 | ||
176 | @@ -2916,6 +2939,26 @@ | |||
177 | 2916 | } | 2939 | } |
178 | 2917 | 2940 | ||
179 | 2918 | strncpy(buf, dbname, FN_REFLEN); | 2941 | strncpy(buf, dbname, FN_REFLEN); |
180 | 2942 | buf[tbname - 1 - dbname] = 0; | ||
181 | 2943 | |||
182 | 2944 | if (databases_hash) { | ||
183 | 2945 | /* There are some filters for databases, check them */ | ||
184 | 2946 | xtrabackup_filter_entry_t* database; | ||
185 | 2947 | |||
186 | 2948 | XB_HASH_SEARCH(name_hash, databases_hash, ut_fold_string(buf), | ||
187 | 2949 | database, ut_ad(database->name), | ||
188 | 2950 | !strcmp(database->name, buf)); | ||
189 | 2951 | /* Table's database isn't found, skip the table */ | ||
190 | 2952 | if (!database) { | ||
191 | 2953 | return(TRUE); | ||
192 | 2954 | } | ||
193 | 2955 | /* There aren't tables specified for the database, | ||
194 | 2956 | it should be backed up entirely */ | ||
195 | 2957 | if (!database->has_tables_specified) { | ||
196 | 2958 | return(FALSE); | ||
197 | 2959 | } | ||
198 | 2960 | } | ||
199 | 2961 | |||
200 | 2919 | buf[FN_REFLEN - 1] = 0; | 2962 | buf[FN_REFLEN - 1] = 0; |
201 | 2920 | buf[tbname - 1 - dbname] = '.'; | 2963 | buf[tbname - 1 - dbname] = '.'; |
202 | 2921 | 2964 | ||
203 | @@ -2929,11 +2972,13 @@ | |||
204 | 2929 | *eptr = 0; | 2972 | *eptr = 0; |
205 | 2930 | } | 2973 | } |
206 | 2931 | 2974 | ||
212 | 2932 | if (xtrabackup_tables) { | 2975 | if (UT_LIST_GET_LEN(regex_list)) { |
213 | 2933 | int regres = REG_NOMATCH; | 2976 | /* Check against regular expressions list */ |
214 | 2934 | int i; | 2977 | int regres = REG_NOMATCH; |
215 | 2935 | for (i = 0; i < tables_regex_num; i++) { | 2978 | xb_regex_list_node_t* node; |
216 | 2936 | regres = xb_regexec(&tables_regex[i], buf, 1, | 2979 | for (node = UT_LIST_GET_FIRST(regex_list); node; |
217 | 2980 | node = UT_LIST_GET_NEXT(regex_list, node)) { | ||
218 | 2981 | regres = xb_regexec(&node->regex, buf, 1, | ||
219 | 2937 | tables_regmatch, 0); | 2982 | tables_regmatch, 0); |
220 | 2938 | if (regres != REG_NOMATCH) { | 2983 | if (regres != REG_NOMATCH) { |
221 | 2939 | break; | 2984 | break; |
222 | @@ -2944,8 +2989,9 @@ | |||
223 | 2944 | } | 2989 | } |
224 | 2945 | } | 2990 | } |
225 | 2946 | 2991 | ||
228 | 2947 | if (xtrabackup_tables_file) { | 2992 | if (tables_hash) { |
229 | 2948 | xtrabackup_tables_t* table; | 2993 | /* Finally, check against full qualified tables list */ |
230 | 2994 | xtrabackup_filter_entry_t* table; | ||
231 | 2949 | 2995 | ||
232 | 2950 | XB_HASH_SEARCH(name_hash, tables_hash, ut_fold_string(buf), | 2996 | XB_HASH_SEARCH(name_hash, tables_hash, ut_fold_string(buf), |
233 | 2951 | table, ut_ad(table->name), | 2997 | table, ut_ad(table->name), |
234 | @@ -4258,6 +4304,242 @@ | |||
235 | 4258 | return(FALSE); | 4304 | return(FALSE); |
236 | 4259 | } | 4305 | } |
237 | 4260 | 4306 | ||
238 | 4307 | /*********************************************************************** | ||
239 | 4308 | Allocate and initialize the entry for databases and tables filtering | ||
240 | 4309 | hash tables. If memory allocation is not successfull, terminate program. | ||
241 | 4310 | @return pointer to the created entry. */ | ||
242 | 4311 | static | ||
243 | 4312 | xtrabackup_filter_entry_t * | ||
244 | 4313 | xb_new_filter_entry( | ||
245 | 4314 | /*================*/ | ||
246 | 4315 | const char* name) /*!< in: name of table/database */ | ||
247 | 4316 | { | ||
248 | 4317 | xtrabackup_filter_entry_t *entry; | ||
249 | 4318 | ulint namelen = strlen(name); | ||
250 | 4319 | |||
251 | 4320 | /* Length of name shouldn't be greater than 129 character, | ||
252 | 4321 | which isn't actually 129 bytes as some of UTF-8 characters | ||
253 | 4322 | for example can be encoded by 4 bytes. */ | ||
254 | 4323 | ut_a(namelen <= NAME_LEN * 2 + 1); | ||
255 | 4324 | |||
256 | 4325 | entry = ut_malloc(sizeof(xtrabackup_filter_entry_t) + namelen + 1); | ||
257 | 4326 | memset(entry, '\0', sizeof(xtrabackup_filter_entry_t) + namelen + 1); | ||
258 | 4327 | entry->name = ((char*)entry) + sizeof(xtrabackup_filter_entry_t); | ||
259 | 4328 | strcpy(entry->name, name); | ||
260 | 4329 | entry->has_tables_specified = FALSE; | ||
261 | 4330 | |||
262 | 4331 | return entry; | ||
263 | 4332 | } | ||
264 | 4333 | |||
265 | 4334 | /*********************************************************************** | ||
266 | 4335 | Free entry filtering hash table entry. */ | ||
267 | 4336 | static | ||
268 | 4337 | void | ||
269 | 4338 | xb_free_filter_entry( | ||
270 | 4339 | /*=================*/ | ||
271 | 4340 | xtrabackup_filter_entry_t* entry) /*!< in: entry */ | ||
272 | 4341 | { | ||
273 | 4342 | ut_free(entry); | ||
274 | 4343 | } | ||
275 | 4344 | |||
276 | 4345 | /*********************************************************************** | ||
277 | 4346 | Add entry to hash table. If hash table is NULL, allocate and initialize | ||
278 | 4347 | new hash table */ | ||
279 | 4348 | static | ||
280 | 4349 | xtrabackup_filter_entry_t* | ||
281 | 4350 | xb_add_filter_entry_to_hash( | ||
282 | 4351 | /*========================*/ | ||
283 | 4352 | const char* name, /*!< in: name of table/database */ | ||
284 | 4353 | hash_table_t** hash) /*!< in/out: hash to insert into */ | ||
285 | 4354 | { | ||
286 | 4355 | xtrabackup_filter_entry_t* entry; | ||
287 | 4356 | |||
288 | 4357 | entry = xb_new_filter_entry(name); | ||
289 | 4358 | |||
290 | 4359 | if (UNIV_UNLIKELY(*hash == NULL)) { | ||
291 | 4360 | *hash = hash_create(1000); | ||
292 | 4361 | } | ||
293 | 4362 | HASH_INSERT(xtrabackup_filter_entry_t, | ||
294 | 4363 | name_hash, *hash, | ||
295 | 4364 | ut_fold_string(entry->name), | ||
296 | 4365 | entry); | ||
297 | 4366 | |||
298 | 4367 | return entry; | ||
299 | 4368 | } | ||
300 | 4369 | |||
301 | 4370 | /*********************************************************************** | ||
302 | 4371 | Validate name of table or database. If name is invalid, program will | ||
303 | 4372 | be finished with error code */ | ||
304 | 4373 | static | ||
305 | 4374 | void | ||
306 | 4375 | xb_validate_name( | ||
307 | 4376 | /*=============*/ | ||
308 | 4377 | const char* name, /*!< in: name */ | ||
309 | 4378 | size_t len) /*!< in: length of name */ | ||
310 | 4379 | { | ||
311 | 4380 | const char* p; | ||
312 | 4381 | |||
313 | 4382 | /* perform only basic validation. validate length and | ||
314 | 4383 | path symbols */ | ||
315 | 4384 | if (len > NAME_LEN) { | ||
316 | 4385 | msg("xtrabackup: name `%s` is too long.\n", name); | ||
317 | 4386 | exit(EXIT_FAILURE); | ||
318 | 4387 | } | ||
319 | 4388 | p = strpbrk(name, "/\\~"); | ||
320 | 4389 | if (p && p - name < NAME_LEN) { | ||
321 | 4390 | msg("xtrabackup: name `%s` is not valid.\n", name); | ||
322 | 4391 | exit(EXIT_FAILURE); | ||
323 | 4392 | } | ||
324 | 4393 | } | ||
325 | 4394 | |||
326 | 4395 | /*********************************************************************** | ||
327 | 4396 | Register new filter entry which can be either database | ||
328 | 4397 | or table name. */ | ||
329 | 4398 | static | ||
330 | 4399 | void | ||
331 | 4400 | xb_register_filter_entry( | ||
332 | 4401 | /*=====================*/ | ||
333 | 4402 | const char* name) /*!< in: name */ | ||
334 | 4403 | { | ||
335 | 4404 | const char* p; | ||
336 | 4405 | size_t namelen; | ||
337 | 4406 | |||
338 | 4407 | namelen = strlen(name); | ||
339 | 4408 | if ((p = strchr(name, '.')) != NULL) { | ||
340 | 4409 | char dbname[NAME_LEN + 1]; | ||
341 | 4410 | |||
342 | 4411 | xb_validate_name(name, p - name); | ||
343 | 4412 | xb_validate_name(p + 1, namelen - (p - name)); | ||
344 | 4413 | |||
345 | 4414 | strncpy(dbname, name, p - name); | ||
346 | 4415 | dbname[p - name] = 0; | ||
347 | 4416 | |||
348 | 4417 | xtrabackup_filter_entry_t* db_entry = NULL; | ||
349 | 4418 | |||
350 | 4419 | if (databases_hash) { | ||
351 | 4420 | XB_HASH_SEARCH(name_hash, databases_hash, | ||
352 | 4421 | ut_fold_string(dbname), | ||
353 | 4422 | db_entry, ut_ad(db_entry->name), | ||
354 | 4423 | !strcmp(db_entry->name, dbname)); | ||
355 | 4424 | } | ||
356 | 4425 | if (!db_entry) { | ||
357 | 4426 | db_entry = xb_add_filter_entry_to_hash(dbname, | ||
358 | 4427 | &databases_hash); | ||
359 | 4428 | } | ||
360 | 4429 | db_entry->has_tables_specified = TRUE; | ||
361 | 4430 | xb_add_filter_entry_to_hash(name, &tables_hash); | ||
362 | 4431 | } else { | ||
363 | 4432 | xb_validate_name(name, namelen); | ||
364 | 4433 | |||
365 | 4434 | xb_add_filter_entry_to_hash(name, &databases_hash); | ||
366 | 4435 | } | ||
367 | 4436 | } | ||
368 | 4437 | |||
369 | 4438 | /*********************************************************************** | ||
370 | 4439 | Register new table for the filter. */ | ||
371 | 4440 | static | ||
372 | 4441 | void | ||
373 | 4442 | xb_register_table( | ||
374 | 4443 | /*==============*/ | ||
375 | 4444 | const char* name) /*!< in: name of table */ | ||
376 | 4445 | { | ||
377 | 4446 | if (strchr(name, '.') == NULL) { | ||
378 | 4447 | msg("xtrabackup: `%s` is not fully qualified name.\n", name); | ||
379 | 4448 | exit(EXIT_FAILURE); | ||
380 | 4449 | } | ||
381 | 4450 | |||
382 | 4451 | xb_register_filter_entry(name); | ||
383 | 4452 | } | ||
384 | 4453 | |||
385 | 4454 | /*********************************************************************** | ||
386 | 4455 | Register new regex for the filter. */ | ||
387 | 4456 | static | ||
388 | 4457 | void | ||
389 | 4458 | xb_register_regex( | ||
390 | 4459 | /*==============*/ | ||
391 | 4460 | const char* regex) /*!< in: regex */ | ||
392 | 4461 | { | ||
393 | 4462 | xb_regex_list_node_t* node; | ||
394 | 4463 | char errbuf[100]; | ||
395 | 4464 | int ret; | ||
396 | 4465 | |||
397 | 4466 | node = ut_malloc(sizeof(xb_regex_list_node_t)); | ||
398 | 4467 | |||
399 | 4468 | ret = xb_regcomp(&node->regex, regex, REG_EXTENDED); | ||
400 | 4469 | if (ret != 0) { | ||
401 | 4470 | xb_regerror(ret, &node->regex, errbuf, sizeof(errbuf)); | ||
402 | 4471 | msg("xtrabackup: error: tables regcomp(%s): %s\n", regex, errbuf); | ||
403 | 4472 | exit(EXIT_FAILURE); | ||
404 | 4473 | } | ||
405 | 4474 | |||
406 | 4475 | UT_LIST_ADD_LAST(regex_list, regex_list, node); | ||
407 | 4476 | } | ||
408 | 4477 | |||
409 | 4478 | typedef void (*insert_entry_func_t)(const char*); | ||
410 | 4479 | |||
411 | 4480 | /*********************************************************************** | ||
412 | 4481 | Scan string and load filter etnries from it. */ | ||
413 | 4482 | static | ||
414 | 4483 | void | ||
415 | 4484 | xb_load_list_string( | ||
416 | 4485 | /*================*/ | ||
417 | 4486 | const char* list, /*!< in: string representing a list */ | ||
418 | 4487 | const char* delimiters, /*!< in: delimiters of entries */ | ||
419 | 4488 | insert_entry_func_t ins) /*!< in: callback to add entry */ | ||
420 | 4489 | { | ||
421 | 4490 | char* p; | ||
422 | 4491 | char* saveptr; | ||
423 | 4492 | |||
424 | 4493 | p = strtok_r(list, delimiters, &saveptr); | ||
425 | 4494 | while (p) { | ||
426 | 4495 | |||
427 | 4496 | ins(p); | ||
428 | 4497 | |||
429 | 4498 | p = strtok_r(NULL, delimiters, &saveptr); | ||
430 | 4499 | } | ||
431 | 4500 | } | ||
432 | 4501 | |||
433 | 4502 | /*********************************************************************** | ||
434 | 4503 | Scan file and load filter etnries from it. */ | ||
435 | 4504 | static | ||
436 | 4505 | void | ||
437 | 4506 | xb_load_list_file( | ||
438 | 4507 | /*==============*/ | ||
439 | 4508 | const char* filename, /*!< in: name of file */ | ||
440 | 4509 | insert_entry_func_t ins) /*!< in: callback to add entry */ | ||
441 | 4510 | { | ||
442 | 4511 | char name_buf[NAME_LEN*2+2]; | ||
443 | 4512 | FILE *fp; | ||
444 | 4513 | |||
445 | 4514 | /* read and store the filenames */ | ||
446 | 4515 | fp = fopen(filename, "r"); | ||
447 | 4516 | if (!fp) { | ||
448 | 4517 | msg("xtrabackup: cannot open %s\n", | ||
449 | 4518 | filename); | ||
450 | 4519 | exit(EXIT_FAILURE); | ||
451 | 4520 | } | ||
452 | 4521 | for (;;) { | ||
453 | 4522 | char* p = name_buf; | ||
454 | 4523 | |||
455 | 4524 | if (fgets(name_buf, sizeof(name_buf), fp) == 0) { | ||
456 | 4525 | break; | ||
457 | 4526 | } | ||
458 | 4527 | |||
459 | 4528 | p = strchr(name_buf, '\n'); | ||
460 | 4529 | if (p) { | ||
461 | 4530 | *p = '\0'; | ||
462 | 4531 | } else { | ||
463 | 4532 | msg("xtrabackup: `%s...` name is too long", name_buf); | ||
464 | 4533 | exit(EXIT_FAILURE); | ||
465 | 4534 | } | ||
466 | 4535 | |||
467 | 4536 | ins(name_buf); | ||
468 | 4537 | } | ||
469 | 4538 | |||
470 | 4539 | fclose(fp); | ||
471 | 4540 | } | ||
472 | 4541 | |||
473 | 4542 | |||
474 | 4261 | /************************************************************************ | 4543 | /************************************************************************ |
475 | 4262 | Inittialize table filters for partial backup. */ | 4544 | Inittialize table filters for partial backup. */ |
476 | 4263 | static | 4545 | static |
477 | @@ -4265,86 +4547,55 @@ | |||
478 | 4265 | xb_filters_init() | 4547 | xb_filters_init() |
479 | 4266 | /*=============*/ | 4548 | /*=============*/ |
480 | 4267 | { | 4549 | { |
481 | 4550 | UT_LIST_INIT(regex_list); | ||
482 | 4551 | |||
483 | 4552 | if (xtrabackup_databases) { | ||
484 | 4553 | xb_load_list_string(xtrabackup_databases, " \t", | ||
485 | 4554 | xb_register_filter_entry); | ||
486 | 4555 | } | ||
487 | 4556 | if (xtrabackup_databases_file) { | ||
488 | 4557 | xb_load_list_file(xtrabackup_databases_file, | ||
489 | 4558 | xb_register_filter_entry); | ||
490 | 4559 | } | ||
491 | 4268 | if (xtrabackup_tables) { | 4560 | if (xtrabackup_tables) { |
525 | 4269 | /* init regexp */ | 4561 | xb_load_list_string(xtrabackup_tables, ",", |
526 | 4270 | char *p, *next; | 4562 | xb_register_regex); |
494 | 4271 | int i; | ||
495 | 4272 | char errbuf[100]; | ||
496 | 4273 | |||
497 | 4274 | tables_regex_num = 1; | ||
498 | 4275 | |||
499 | 4276 | p = xtrabackup_tables; | ||
500 | 4277 | while ((p = strchr(p, ',')) != NULL) { | ||
501 | 4278 | p++; | ||
502 | 4279 | tables_regex_num++; | ||
503 | 4280 | } | ||
504 | 4281 | |||
505 | 4282 | tables_regex = ut_malloc(sizeof(xb_regex_t) * tables_regex_num); | ||
506 | 4283 | |||
507 | 4284 | p = xtrabackup_tables; | ||
508 | 4285 | for (i=0; i < tables_regex_num; i++) { | ||
509 | 4286 | next = strchr(p, ','); | ||
510 | 4287 | ut_a(next || i == tables_regex_num - 1); | ||
511 | 4288 | |||
512 | 4289 | next++; | ||
513 | 4290 | if (i != tables_regex_num - 1) | ||
514 | 4291 | *(next - 1) = '\0'; | ||
515 | 4292 | |||
516 | 4293 | xb_regerror(xb_regcomp(&tables_regex[i], p, | ||
517 | 4294 | REG_EXTENDED), | ||
518 | 4295 | &tables_regex[i], errbuf, sizeof(errbuf)); | ||
519 | 4296 | msg("xtrabackup: tables regcomp(%s): %s\n", p, errbuf); | ||
520 | 4297 | |||
521 | 4298 | if (i != tables_regex_num - 1) | ||
522 | 4299 | *(next - 1) = ','; | ||
523 | 4300 | p = next; | ||
524 | 4301 | } | ||
527 | 4302 | } | 4563 | } |
528 | 4303 | |||
529 | 4304 | if (xtrabackup_tables_file) { | 4564 | if (xtrabackup_tables_file) { |
573 | 4305 | char name_buf[NAME_LEN*2+2]; | 4565 | xb_load_list_file(xtrabackup_tables_file, xb_register_table); |
574 | 4306 | FILE *fp; | 4566 | } |
575 | 4307 | 4567 | } | |
576 | 4308 | name_buf[NAME_LEN*2+1] = '\0'; | 4568 | |
577 | 4309 | 4569 | ||
578 | 4310 | /* init tables_hash */ | 4570 | /************************************************************************ |
579 | 4311 | tables_hash = hash_create(1000); | 4571 | Release all the hash entries and hash itself. */ |
580 | 4312 | 4572 | static | |
581 | 4313 | /* read and store the filenames */ | 4573 | void |
582 | 4314 | fp = fopen(xtrabackup_tables_file,"r"); | 4574 | xb_filter_hash_clear( |
583 | 4315 | if (!fp) { | 4575 | hash_table_t* hash) |
584 | 4316 | msg("xtrabackup: cannot open %s\n", | 4576 | { |
585 | 4317 | xtrabackup_tables_file); | 4577 | ulint i; |
586 | 4318 | exit(EXIT_FAILURE); | 4578 | |
587 | 4319 | } | 4579 | /* free the hash elements */ |
588 | 4320 | for (;;) { | 4580 | for (i = 0; i < hash_get_n_cells(hash); i++) { |
589 | 4321 | xtrabackup_tables_t* table; | 4581 | xtrabackup_filter_entry_t* table; |
590 | 4322 | char* p = name_buf; | 4582 | |
591 | 4323 | 4583 | table = HASH_GET_FIRST(hash, i); | |
592 | 4324 | if ( fgets(name_buf, NAME_LEN*2+1, fp) == 0 ) { | 4584 | |
593 | 4325 | break; | 4585 | while (table) { |
594 | 4326 | } | 4586 | xtrabackup_filter_entry_t* prev_table = table; |
595 | 4327 | 4587 | ||
596 | 4328 | p = strchr(name_buf, '\n'); | 4588 | table = HASH_GET_NEXT(name_hash, prev_table); |
597 | 4329 | if (p) | 4589 | |
598 | 4330 | { | 4590 | HASH_DELETE(xtrabackup_filter_entry_t, name_hash, hash, |
599 | 4331 | *p = '\0'; | 4591 | ut_fold_string(prev_table->name), prev_table); |
600 | 4332 | } | 4592 | free(prev_table); |
601 | 4333 | 4593 | } | |
602 | 4334 | table = malloc(sizeof(xtrabackup_tables_t) + strlen(name_buf) + 1); | 4594 | } |
603 | 4335 | memset(table, '\0', sizeof(xtrabackup_tables_t) + strlen(name_buf) + 1); | 4595 | |
604 | 4336 | table->name = ((char*)table) + sizeof(xtrabackup_tables_t); | 4596 | /* free hash */ |
605 | 4337 | strcpy(table->name, name_buf); | 4597 | hash_table_free(hash); |
606 | 4338 | 4598 | } | |
564 | 4339 | HASH_INSERT(xtrabackup_tables_t, name_hash, tables_hash, | ||
565 | 4340 | ut_fold_string(table->name), table); | ||
566 | 4341 | |||
567 | 4342 | msg("xtrabackup: table '%s' is registered to the " | ||
568 | 4343 | "list.\n", table->name); | ||
569 | 4344 | } | ||
570 | 4345 | } | ||
571 | 4346 | } | ||
572 | 4347 | |||
607 | 4348 | 4599 | ||
608 | 4349 | /************************************************************************ | 4600 | /************************************************************************ |
609 | 4350 | Destroy table filters for partial backup. */ | 4601 | Destroy table filters for partial backup. */ |
610 | @@ -4353,29 +4604,19 @@ | |||
611 | 4353 | xb_filters_free() | 4604 | xb_filters_free() |
612 | 4354 | /*=============*/ | 4605 | /*=============*/ |
613 | 4355 | { | 4606 | { |
637 | 4356 | 4607 | while (UT_LIST_GET_LEN(regex_list) > 0) { | |
638 | 4357 | if (xtrabackup_tables_file) { | 4608 | xb_regex_list_node_t* node = UT_LIST_GET_FIRST(regex_list); |
639 | 4358 | ulint i; | 4609 | UT_LIST_REMOVE(regex_list, regex_list, node); |
640 | 4359 | 4610 | xb_regfree(&node->regex); | |
641 | 4360 | /* free the hash elements */ | 4611 | ut_free(node); |
642 | 4361 | for (i = 0; i < hash_get_n_cells(tables_hash); i++) { | 4612 | } |
643 | 4362 | xtrabackup_tables_t* table; | 4613 | |
644 | 4363 | 4614 | if (tables_hash) { | |
645 | 4364 | table = HASH_GET_FIRST(tables_hash, i); | 4615 | xb_filter_hash_clear(tables_hash); |
646 | 4365 | 4616 | } | |
647 | 4366 | while (table) { | 4617 | |
648 | 4367 | xtrabackup_tables_t* prev_table = table; | 4618 | if (databases_hash) { |
649 | 4368 | 4619 | xb_filter_hash_clear(databases_hash); | |
627 | 4369 | table = HASH_GET_NEXT(name_hash, prev_table); | ||
628 | 4370 | |||
629 | 4371 | HASH_DELETE(xtrabackup_tables_t, name_hash, tables_hash, | ||
630 | 4372 | ut_fold_string(prev_table->name), prev_table); | ||
631 | 4373 | free(prev_table); | ||
632 | 4374 | } | ||
633 | 4375 | } | ||
634 | 4376 | |||
635 | 4377 | /* free tables_hash */ | ||
636 | 4378 | hash_table_free(tables_hash); | ||
650 | 4379 | } | 4620 | } |
651 | 4380 | 4621 | ||
652 | 4381 | } | 4622 | } |
653 | @@ -7206,16 +7447,6 @@ | |||
654 | 7206 | if (xtrabackup_prepare) | 7447 | if (xtrabackup_prepare) |
655 | 7207 | xtrabackup_prepare_func(); | 7448 | xtrabackup_prepare_func(); |
656 | 7208 | 7449 | ||
657 | 7209 | if (xtrabackup_tables) { | ||
658 | 7210 | /* free regexp */ | ||
659 | 7211 | int i; | ||
660 | 7212 | |||
661 | 7213 | for (i = 0; i < tables_regex_num; i++) { | ||
662 | 7214 | xb_regfree(&tables_regex[i]); | ||
663 | 7215 | } | ||
664 | 7216 | ut_free(tables_regex); | ||
665 | 7217 | } | ||
666 | 7218 | |||
667 | 7219 | xb_regex_end(); | 7450 | xb_regex_end(); |
668 | 7220 | 7451 | ||
669 | 7221 | exit(EXIT_SUCCESS); | 7452 | exit(EXIT_SUCCESS); |
670 | 7222 | 7453 | ||
671 | === added file 'test/t/ib_databases.sh' | |||
672 | --- test/t/ib_databases.sh 1970-01-01 00:00:00 +0000 | |||
673 | +++ test/t/ib_databases.sh 2013-02-25 08:01:21 +0000 | |||
674 | @@ -0,0 +1,50 @@ | |||
675 | 1 | ######################################################################## | ||
676 | 2 | # Bug #569387: innobackupex ignores --databases | ||
677 | 3 | # Testcase covers using --databases option with InnoDB | ||
678 | 4 | # database (list is specified in option itself) | ||
679 | 5 | ######################################################################## | ||
680 | 6 | |||
681 | 7 | . inc/common.sh | ||
682 | 8 | |||
683 | 9 | start_server --innodb-file-per-table | ||
684 | 10 | |||
685 | 11 | cat <<EOF | run_cmd $MYSQL $MYSQL_ARGS | ||
686 | 12 | |||
687 | 13 | CREATE DATABASE test1; | ||
688 | 14 | |||
689 | 15 | CREATE TABLE test1.a (a INT PRIMARY KEY); | ||
690 | 16 | CREATE TABLE test1.b (b INT PRIMARY KEY); | ||
691 | 17 | CREATE TABLE test1.c (c INT PRIMARY KEY); | ||
692 | 18 | |||
693 | 19 | CREATE TABLE test.a (a INT PRIMARY KEY); | ||
694 | 20 | CREATE TABLE test.b (b INT PRIMARY KEY); | ||
695 | 21 | CREATE TABLE test.c (c INT PRIMARY KEY); | ||
696 | 22 | |||
697 | 23 | EOF | ||
698 | 24 | |||
699 | 25 | # This is a workaround to pass --databases='test test1.b test1.c' | ||
700 | 26 | $IB_BIN $IB_ARGS --no-timestamp --databases='test test1.b test1.c' $topdir/backup | ||
701 | 27 | innobackupex --apply-log $topdir/backup | ||
702 | 28 | vlog "Backup taken" | ||
703 | 29 | |||
704 | 30 | stop_server | ||
705 | 31 | |||
706 | 32 | # Restore partial backup | ||
707 | 33 | # Remove database | ||
708 | 34 | rm -rf $mysql_datadir/test/* | ||
709 | 35 | rm -rf $mysql_datadir/test1/* | ||
710 | 36 | vlog "Original database removed" | ||
711 | 37 | |||
712 | 38 | # Restore database from backup | ||
713 | 39 | cp -rv $topdir/backup/test/* $mysql_datadir/test | ||
714 | 40 | cp -rv $topdir/backup/test1/* $mysql_datadir/test1 | ||
715 | 41 | vlog "database restored from backup" | ||
716 | 42 | |||
717 | 43 | start_server | ||
718 | 44 | |||
719 | 45 | OUT=`run_cmd $MYSQL $MYSQL_ARGS -e "USE test; SHOW TABLES; USE test1; SHOW TABLES;" | tr -d '\n'` | ||
720 | 46 | |||
721 | 47 | if [ $OUT != "Tables_in_testabcTables_in_test1bc" ] ; then | ||
722 | 48 | vlog "Backed up tables set doesn't match filter" ; | ||
723 | 49 | exit 1; | ||
724 | 50 | fi | ||
725 | 0 | 51 | ||
726 | === added file 'test/t/ib_databases_file.sh' | |||
727 | --- test/t/ib_databases_file.sh 1970-01-01 00:00:00 +0000 | |||
728 | +++ test/t/ib_databases_file.sh 2013-02-25 08:01:21 +0000 | |||
729 | @@ -0,0 +1,57 @@ | |||
730 | 1 | ######################################################################## | ||
731 | 2 | # Bug #569387: innobackupex ignores --databases | ||
732 | 3 | # Testcase covers using --databases option with InnoDB | ||
733 | 4 | # database (list is specified in file which option | ||
734 | 5 | # points to) | ||
735 | 6 | ######################################################################## | ||
736 | 7 | |||
737 | 8 | . inc/common.sh | ||
738 | 9 | |||
739 | 10 | start_server --innodb-file-per-table | ||
740 | 11 | |||
741 | 12 | cat <<EOF | run_cmd $MYSQL $MYSQL_ARGS | ||
742 | 13 | |||
743 | 14 | CREATE DATABASE test1; | ||
744 | 15 | |||
745 | 16 | CREATE TABLE test1.a (a INT PRIMARY KEY) engine=InnoDB; | ||
746 | 17 | CREATE TABLE test1.b (b INT PRIMARY KEY) engine=InnoDB; | ||
747 | 18 | CREATE TABLE test1.c (c INT PRIMARY KEY) engine=InnoDB; | ||
748 | 19 | |||
749 | 20 | CREATE TABLE test.a (a INT PRIMARY KEY) engine=InnoDB; | ||
750 | 21 | CREATE TABLE test.b (b INT PRIMARY KEY) engine=InnoDB; | ||
751 | 22 | CREATE TABLE test.c (c INT PRIMARY KEY) engine=InnoDB; | ||
752 | 23 | |||
753 | 24 | EOF | ||
754 | 25 | |||
755 | 26 | # Take a backup | ||
756 | 27 | # Backup the whole test and b,c from test1 | ||
757 | 28 | cat >$topdir/databases_file <<EOF | ||
758 | 29 | test | ||
759 | 30 | test1.b | ||
760 | 31 | test1.c | ||
761 | 32 | EOF | ||
762 | 33 | innobackupex --no-timestamp --databases=$topdir/databases_file $topdir/backup | ||
763 | 34 | innobackupex --apply-log $topdir/backup | ||
764 | 35 | vlog "Backup taken" | ||
765 | 36 | |||
766 | 37 | stop_server | ||
767 | 38 | |||
768 | 39 | # Restore partial backup | ||
769 | 40 | # Remove database | ||
770 | 41 | rm -rf $mysql_datadir/test/* | ||
771 | 42 | rm -rf $mysql_datadir/test1/* | ||
772 | 43 | vlog "Original database removed" | ||
773 | 44 | |||
774 | 45 | # Restore database from backup | ||
775 | 46 | cp -rv $topdir/backup/test/* $mysql_datadir/test | ||
776 | 47 | cp -rv $topdir/backup/test1/* $mysql_datadir/test1 | ||
777 | 48 | vlog "database restored from backup" | ||
778 | 49 | |||
779 | 50 | start_server | ||
780 | 51 | |||
781 | 52 | OUT=`run_cmd $MYSQL $MYSQL_ARGS -e "USE test; SHOW TABLES; USE test1; SHOW TABLES;" | tr -d '\n'` | ||
782 | 53 | |||
783 | 54 | if [ $OUT != "Tables_in_testabcTables_in_test1bc" ] ; then | ||
784 | 55 | vlog "Backed up tables set don't match filter" ; | ||
785 | 56 | exit 1; | ||
786 | 57 | fi | ||
787 | 0 | 58 | ||
788 | === added file 'test/t/xb_databases_options.sh' | |||
789 | --- test/t/xb_databases_options.sh 1970-01-01 00:00:00 +0000 | |||
790 | +++ test/t/xb_databases_options.sh 2013-02-25 08:01:21 +0000 | |||
791 | @@ -0,0 +1,221 @@ | |||
792 | 1 | ######################################################################## | ||
793 | 2 | # Bug #569387: xtrabackup ignores --databases, i.e. when --databases | ||
794 | 3 | # | ||
795 | 4 | # Test following xtrabackup options | ||
796 | 5 | # --databases | ||
797 | 6 | # --databases-file | ||
798 | 7 | # --tables | ||
799 | 8 | # --tables-file | ||
800 | 9 | ######################################################################## | ||
801 | 10 | |||
802 | 11 | . inc/common.sh | ||
803 | 12 | |||
804 | 13 | start_server --innodb-file-per-table | ||
805 | 14 | |||
806 | 15 | function setup_test { | ||
807 | 16 | |||
808 | 17 | cat <<EOF | run_cmd $MYSQL $MYSQL_ARGS | ||
809 | 18 | |||
810 | 19 | create database database1; | ||
811 | 20 | create database database2; | ||
812 | 21 | create database test1; | ||
813 | 22 | create database test2; | ||
814 | 23 | create database thisisadatabase; | ||
815 | 24 | create database testdatabase; | ||
816 | 25 | |||
817 | 26 | create table database1.thisisatable (a int primary key) engine=InnoDB; | ||
818 | 27 | create table database1.t (a int primary key) engine=InnoDB; | ||
819 | 28 | create table database1.t1 (a int primary key) engine=InnoDB; | ||
820 | 29 | create table database1.t2 (a int primary key) engine=InnoDB; | ||
821 | 30 | create table database1.ancor (a int primary key) engine=InnoDB; | ||
822 | 31 | create table database1.glow (a int primary key) engine=InnoDB; | ||
823 | 32 | |||
824 | 33 | create table database2.thisisatable (a int primary key) engine=InnoDB; | ||
825 | 34 | create table database2.t (a int primary key) engine=InnoDB; | ||
826 | 35 | create table database2.t1 (a int primary key) engine=InnoDB; | ||
827 | 36 | create table database2.t2 (a int primary key) engine=InnoDB; | ||
828 | 37 | create table database2.ancor (a int primary key) engine=InnoDB; | ||
829 | 38 | create table database2.glow (a int primary key) engine=InnoDB; | ||
830 | 39 | |||
831 | 40 | create table test1.thisisatable (a int primary key) engine=InnoDB; | ||
832 | 41 | create table test1.t (a int primary key) engine=InnoDB; | ||
833 | 42 | create table test1.t1 (a int primary key) engine=InnoDB; | ||
834 | 43 | create table test1.t2 (a int primary key) engine=InnoDB; | ||
835 | 44 | create table test1.ancor (a int primary key) engine=InnoDB; | ||
836 | 45 | create table test1.glow (a int primary key) engine=InnoDB; | ||
837 | 46 | |||
838 | 47 | create table test2.thisisatable (a int primary key) engine=InnoDB; | ||
839 | 48 | create table test2.t (a int primary key) engine=InnoDB; | ||
840 | 49 | create table test2.t1 (a int primary key) engine=InnoDB; | ||
841 | 50 | create table test2.t2 (a int primary key) engine=InnoDB; | ||
842 | 51 | create table test2.ancor (a int primary key) engine=InnoDB; | ||
843 | 52 | create table test2.glow (a int primary key) engine=InnoDB; | ||
844 | 53 | |||
845 | 54 | create table thisisadatabase.thisisatable (a int primary key) engine=InnoDB; | ||
846 | 55 | create table thisisadatabase.t (a int primary key) engine=InnoDB; | ||
847 | 56 | create table thisisadatabase.t1 (a int primary key) engine=InnoDB; | ||
848 | 57 | create table thisisadatabase.t2 (a int primary key) engine=InnoDB; | ||
849 | 58 | create table thisisadatabase.ancor (a int primary key) engine=InnoDB; | ||
850 | 59 | create table thisisadatabase.glow (a int primary key) engine=InnoDB; | ||
851 | 60 | |||
852 | 61 | create table testdatabase.thisisatable (a int primary key) engine=InnoDB; | ||
853 | 62 | create table testdatabase.t (a int primary key) engine=InnoDB; | ||
854 | 63 | create table testdatabase.t1 (a int primary key) engine=InnoDB; | ||
855 | 64 | create table testdatabase.t2 (a int primary key) engine=InnoDB; | ||
856 | 65 | create table testdatabase.ancor (a int primary key) engine=InnoDB; | ||
857 | 66 | create table testdatabase.glow (a int primary key) engine=InnoDB; | ||
858 | 67 | |||
859 | 68 | EOF | ||
860 | 69 | |||
861 | 70 | } | ||
862 | 71 | |||
863 | 72 | function ls_dir { | ||
864 | 73 | d=`pwd` | ||
865 | 74 | cd $1 | ||
866 | 75 | find . -name '*.ibd' | sort | ||
867 | 76 | cd $d | ||
868 | 77 | } | ||
869 | 78 | |||
870 | 79 | setup_test | ||
871 | 80 | |||
872 | 81 | backup_dir=$topdir/backup_dir | ||
873 | 82 | mkdir -p $backup_dir | ||
874 | 83 | |||
875 | 84 | # invalid characters | ||
876 | 85 | $XB_BIN $XB_ARGS --backup --databases=a/b/c --target-dir=$backup_dir --datadir=$mysql_datadir 2>&1 | grep 'is not valid' | ||
877 | 86 | |||
878 | 87 | # too long name | ||
879 | 88 | $XB_BIN $XB_ARGS --backup --databases=verylonglonglongname111111skjhkdjhfkjdhgkjdfh1555555555555511stillnotlongenoughsowilladdmore1111111111111111111114848484848484fkjhdjfhkdjfhd8484848aaaaaaaaaancnvjvifmifjhfkmfkfnbfifnfkfik4848484841111111prettyenoughnow --target-dir=$backup_dir --datadir=$mysql_datadir 2>&1 | grep 'is too long' | ||
880 | 89 | |||
881 | 90 | # too long name | ||
882 | 91 | $XB_BIN $XB_ARGS --backup --databases=test1.verylonglonglongname111111skjhkdjhfkjdhgkjdfh1555555555555511stillnotlongenoughsowilladdmore1111111111111111111114848484848484fkjhdjfhkdjfhd8484848aaaaaaaaaancnvjvifmifjhfkmfkfnbfifnfkfik4848484841111111prettyenoughnow --target-dir=$backup_dir --datadir=$mysql_datadir 2>&1 | grep 'is too long' | ||
883 | 92 | |||
884 | 93 | # not fully qualified name | ||
885 | 94 | $XB_BIN $XB_ARGS --backup --tables-file=<(echo verylonglonglongname111111skjhkdjhfkjdhgkjdfh1555555555555511stillnotlongenoughsowilladdmore1111111111111111111114848484848484fkjhdjfhkdjfhd8484848aaaaaaaaaancnvjvifmifjhfkmfkfnbfifnfkfik4848484841111111prettyenoughnow) --target-dir=$backup_dir --datadir=$mysql_datadir 2>&1 | grep 'is not fully qualified' | ||
886 | 95 | |||
887 | 96 | # again too long name | ||
888 | 97 | $XB_BIN $XB_ARGS --backup --tables-file=<(echo test1.verylonglonglongname111111skjhkdjhfkjdhgkjdfh1555555555555511stillnotlongenoughsowilladdmore1111111111111111111114848484848484fkjhdjfhkdjfhd8484848aaaaaaaaaancnvjvifmifjhfkmfkfnbfifnfkfik4848484841111111prettyenoughnow) --target-dir=$backup_dir --datadir=$mysql_datadir 2>&1 | grep 'is too long' | ||
889 | 98 | |||
890 | 99 | # should go fine, we cannot validate regex against length | ||
891 | 100 | $XB_BIN $XB_ARGS --backup --tables=verylonglonglongname111111skjhkdjhfkjdhgkjdfh1555555555555511stillnotlongenoughsowilladdmore1111111111111111111114848484848484fkjhdjfhkdjfhd8484848aaaaaaaaaancnvjvifmifjhfkmfkfnbfifnfkfik4848484841111111prettyenoughnow --target-dir=$backup_dir --datadir=$mysql_datadir | ||
892 | 101 | rm -rf $backup_dir/* | ||
893 | 102 | |||
894 | 103 | # should go fine, we cannot validate regex against length | ||
895 | 104 | $XB_BIN $XB_ARGS --backup --tables=test1.verylonglonglongname111111skjhkdjhfkjdhgkjdfh1555555555555511stillnotlongenoughsowilladdmore1111111111111111111114848484848484fkjhdjfhkdjfhd8484848aaaaaaaaaancnvjvifmifjhfkmfkfnbfifnfkfik4848484841111111prettyenoughnow --target-dir=$backup_dir --datadir=$mysql_datadir | ||
896 | 105 | rm -rf $backup_dir/* | ||
897 | 106 | |||
898 | 107 | vlog "Testing with --databases=..." | ||
899 | 108 | $XB_BIN $XB_ARGS --backup --databases='database database2 test1.t test1.ancor thisisadatabase testdatabase.t testdatabase.t7' --target-dir=$backup_dir --datadir=$mysql_datadir | ||
900 | 109 | diff -u <(ls_dir $backup_dir) - <<EOF | ||
901 | 110 | ./database2/ancor.ibd | ||
902 | 111 | ./database2/glow.ibd | ||
903 | 112 | ./database2/t.ibd | ||
904 | 113 | ./database2/t1.ibd | ||
905 | 114 | ./database2/t2.ibd | ||
906 | 115 | ./database2/thisisatable.ibd | ||
907 | 116 | ./test1/ancor.ibd | ||
908 | 117 | ./test1/t.ibd | ||
909 | 118 | ./testdatabase/t.ibd | ||
910 | 119 | ./thisisadatabase/ancor.ibd | ||
911 | 120 | ./thisisadatabase/glow.ibd | ||
912 | 121 | ./thisisadatabase/t.ibd | ||
913 | 122 | ./thisisadatabase/t1.ibd | ||
914 | 123 | ./thisisadatabase/t2.ibd | ||
915 | 124 | ./thisisadatabase/thisisatable.ibd | ||
916 | 125 | EOF | ||
917 | 126 | rm -rf $backup_dir/* | ||
918 | 127 | |||
919 | 128 | vlog "Testing with --databases-file=..." | ||
920 | 129 | cat >$topdir/list <<EOF | ||
921 | 130 | database | ||
922 | 131 | database2 | ||
923 | 132 | test1.t | ||
924 | 133 | test1.ancor | ||
925 | 134 | thisisadatabase | ||
926 | 135 | testdatabase.t | ||
927 | 136 | testdatabase.t7 | ||
928 | 137 | EOF | ||
929 | 138 | $XB_BIN $XB_ARGS --backup --databases-file=$topdir/list --target-dir=$backup_dir --datadir=$mysql_datadir | ||
930 | 139 | diff -u <(ls_dir $backup_dir) - <<EOF | ||
931 | 140 | ./database2/ancor.ibd | ||
932 | 141 | ./database2/glow.ibd | ||
933 | 142 | ./database2/t.ibd | ||
934 | 143 | ./database2/t1.ibd | ||
935 | 144 | ./database2/t2.ibd | ||
936 | 145 | ./database2/thisisatable.ibd | ||
937 | 146 | ./test1/ancor.ibd | ||
938 | 147 | ./test1/t.ibd | ||
939 | 148 | ./testdatabase/t.ibd | ||
940 | 149 | ./thisisadatabase/ancor.ibd | ||
941 | 150 | ./thisisadatabase/glow.ibd | ||
942 | 151 | ./thisisadatabase/t.ibd | ||
943 | 152 | ./thisisadatabase/t1.ibd | ||
944 | 153 | ./thisisadatabase/t2.ibd | ||
945 | 154 | ./thisisadatabase/thisisatable.ibd | ||
946 | 155 | EOF | ||
947 | 156 | rm -rf $backup_dir/* | ||
948 | 157 | |||
949 | 158 | vlog "Testing failure with --tables-file=..." | ||
950 | 159 | cat >$topdir/list <<EOF | ||
951 | 160 | database | ||
952 | 161 | database2 | ||
953 | 162 | test1.t | ||
954 | 163 | test1.ancor | ||
955 | 164 | thisisadatabase | ||
956 | 165 | testdatabase.t | ||
957 | 166 | testdatabase.t7 | ||
958 | 167 | EOF | ||
959 | 168 | run_cmd_expect_failure $XB_BIN $XB_ARGS --backup --tables-file=$topdir/list --target-dir=$backup_dir --datadir=$mysql_datadir | ||
960 | 169 | diff -u <(ls_dir $backup_dir) - <<EOF | ||
961 | 170 | EOF | ||
962 | 171 | rm -rf $backup_dir/* | ||
963 | 172 | |||
964 | 173 | vlog "Testing with --tables-file=..." | ||
965 | 174 | cat >$topdir/list <<EOF | ||
966 | 175 | test1.t | ||
967 | 176 | test1.ancor | ||
968 | 177 | testdatabase.t | ||
969 | 178 | testdatabase.t7 | ||
970 | 179 | EOF | ||
971 | 180 | run_cmd $XB_BIN $XB_ARGS --backup --tables-file=$topdir/list --target-dir=$backup_dir --datadir=$mysql_datadir | ||
972 | 181 | diff -u <(ls_dir $backup_dir) - <<EOF | ||
973 | 182 | ./test1/ancor.ibd | ||
974 | 183 | ./test1/t.ibd | ||
975 | 184 | ./testdatabase/t.ibd | ||
976 | 185 | EOF | ||
977 | 186 | rm -rf $backup_dir/* | ||
978 | 187 | |||
979 | 188 | vlog "Testing with --tables=..." | ||
980 | 189 | $XB_BIN $XB_ARGS --backup --tables='dat.base,test1.t,test1.a' --target-dir=$backup_dir --datadir=$mysql_datadir | ||
981 | 190 | diff -u <(ls_dir $backup_dir) - <<EOF | ||
982 | 191 | ./database1/ancor.ibd | ||
983 | 192 | ./database1/glow.ibd | ||
984 | 193 | ./database1/t.ibd | ||
985 | 194 | ./database1/t1.ibd | ||
986 | 195 | ./database1/t2.ibd | ||
987 | 196 | ./database1/thisisatable.ibd | ||
988 | 197 | ./database2/ancor.ibd | ||
989 | 198 | ./database2/glow.ibd | ||
990 | 199 | ./database2/t.ibd | ||
991 | 200 | ./database2/t1.ibd | ||
992 | 201 | ./database2/t2.ibd | ||
993 | 202 | ./database2/thisisatable.ibd | ||
994 | 203 | ./test1/ancor.ibd | ||
995 | 204 | ./test1/t.ibd | ||
996 | 205 | ./test1/t1.ibd | ||
997 | 206 | ./test1/t2.ibd | ||
998 | 207 | ./test1/thisisatable.ibd | ||
999 | 208 | ./testdatabase/ancor.ibd | ||
1000 | 209 | ./testdatabase/glow.ibd | ||
1001 | 210 | ./testdatabase/t.ibd | ||
1002 | 211 | ./testdatabase/t1.ibd | ||
1003 | 212 | ./testdatabase/t2.ibd | ||
1004 | 213 | ./testdatabase/thisisatable.ibd | ||
1005 | 214 | ./thisisadatabase/ancor.ibd | ||
1006 | 215 | ./thisisadatabase/glow.ibd | ||
1007 | 216 | ./thisisadatabase/t.ibd | ||
1008 | 217 | ./thisisadatabase/t1.ibd | ||
1009 | 218 | ./thisisadatabase/t2.ibd | ||
1010 | 219 | ./thisisadatabase/thisisatable.ibd | ||
1011 | 220 | EOF | ||
1012 | 221 | rm -rf $backup_dir/* |
http:// jenkins. percona. com/view/ XtraBackup/ job/percona- xtrabackup- 2.0-param/ 325/