Merge lp:~sergei.glushchenko/percona-xtrabackup/2.1-xb-bug569387 into lp:percona-xtrabackup/2.1
- 2.1-xb-bug569387
- Merge into 2.1
Proposed by
Sergei Glushchenko
Status: | Rejected |
---|---|
Rejected by: | Alexey Kopytov |
Proposed branch: | lp:~sergei.glushchenko/percona-xtrabackup/2.1-xb-bug569387 |
Merge into: | lp:percona-xtrabackup/2.1 |
Diff against target: |
1052 lines (+686/-143) 9 files modified
doc/source/innobackupex/partial_backups_innobackupex.rst (+1/-5) doc/source/xtrabackup_bin/partial_backups.rst (+6/-1) doc/source/xtrabackup_bin/xbk_option_reference.rst (+8/-0) innobackupex.pl (+8/-0) src/innodb_int.h (+2/-2) src/xtrabackup.cc (+338/-135) test/t/ib_databases.sh (+48/-0) test/t/ib_databases_file.sh (+57/-0) test/t/xb_databases_options.sh (+218/-0) |
To merge this branch: | bzr merge lp:~sergei.glushchenko/percona-xtrabackup/2.1-xb-bug569387 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Alexey Kopytov (community) | Disapprove | ||
Review via email: mp+231931@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Unmerged revisions
- 757. By Sergei Glushchenko
-
Bug 569387: innobackupex ignores --databases without --stream
Changes:
- 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_table_matches_ filters has been modified to check whether
database is enabled first and then 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.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'doc/source/innobackupex/partial_backups_innobackupex.rst' | |||
2 | --- doc/source/innobackupex/partial_backups_innobackupex.rst 2013-11-14 12:17:21 +0000 | |||
3 | +++ doc/source/innobackupex/partial_backups_innobackupex.rst 2014-08-22 16:46:12 +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 either 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 either 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,10 +50,6 @@ | |||
14 | 50 | 50 | ||
15 | 51 | The command above 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 | The command above 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 |Percona 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 | |||
21 | 57 | Preparing Partial Backups | 53 | Preparing Partial Backups |
22 | 58 | ========================= | 54 | ========================= |
23 | 59 | 55 | ||
24 | 60 | 56 | ||
25 | === modified file 'doc/source/xtrabackup_bin/partial_backups.rst' | |||
26 | --- doc/source/xtrabackup_bin/partial_backups.rst 2013-04-29 11:08:57 +0000 | |||
27 | +++ doc/source/xtrabackup_bin/partial_backups.rst 2014-08-22 16:46:12 +0000 | |||
28 | @@ -2,7 +2,7 @@ | |||
29 | 2 | Partial Backups | 2 | Partial Backups |
30 | 3 | ================= | 3 | ================= |
31 | 4 | 4 | ||
33 | 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 two ways to create partial backups: matching the tables' names with a regular expression or providing a list of them in a file or providing a list of databases. |
34 | 6 | 6 | ||
35 | 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. |
36 | 8 | 8 | ||
37 | @@ -31,6 +31,11 @@ | |||
38 | 31 | $ echo "mydatabase.mytable" > /tmp/tables.txt | 31 | $ echo "mydatabase.mytable" > /tmp/tables.txt |
39 | 32 | $ xtrabackup --backup --tables-file=/tmp/tables.txt | 32 | $ xtrabackup --backup --tables-file=/tmp/tables.txt |
40 | 33 | 33 | ||
41 | 34 | Using the :option:`--databases` and :option:`--databases-file` options | ||
42 | 35 | ====================================================================== | ||
43 | 36 | |||
44 | 37 | 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. | ||
45 | 38 | |||
46 | 34 | Preparing the Backup | 39 | Preparing the Backup |
47 | 35 | ==================== | 40 | ==================== |
48 | 36 | 41 | ||
49 | 37 | 42 | ||
50 | === modified file 'doc/source/xtrabackup_bin/xbk_option_reference.rst' | |||
51 | --- doc/source/xtrabackup_bin/xbk_option_reference.rst 2014-05-18 08:23:31 +0000 | |||
52 | +++ doc/source/xtrabackup_bin/xbk_option_reference.rst 2014-08-22 16:46:12 +0000 | |||
53 | @@ -125,6 +125,14 @@ | |||
54 | 125 | 125 | ||
55 | 126 | Don't read default options from any option file. Must be given as the first option on the command-line. | 126 | Don't read default options from any option file. Must be given as the first option on the command-line. |
56 | 127 | 127 | ||
57 | 128 | .. option:: --databases=# | ||
58 | 129 | |||
59 | 130 | 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] . . ."``. | ||
60 | 131 | |||
61 | 132 | .. option:: --databases-file=# | ||
62 | 133 | |||
63 | 134 | 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. | ||
64 | 135 | |||
65 | 128 | .. option:: --parallel=# | 136 | .. option:: --parallel=# |
66 | 129 | 137 | ||
67 | 130 | This option specifies the number of threads to use to copy multiple data files concurrently when creating a backup. The default value is 1 (i.e., no concurrent transfer). | 138 | This option specifies the number of threads to use to copy multiple data files concurrently when creating a backup. The default value is 1 (i.e., no concurrent transfer). |
68 | 131 | 139 | ||
69 | === modified file 'innobackupex.pl' | |||
70 | --- innobackupex.pl 2014-07-21 15:16:00 +0000 | |||
71 | +++ innobackupex.pl 2014-08-22 16:46:12 +0000 | |||
72 | @@ -2811,6 +2811,14 @@ | |||
73 | 2811 | $options = $options . " --compact"; | 2811 | $options = $options . " --compact"; |
74 | 2812 | } | 2812 | } |
75 | 2813 | 2813 | ||
76 | 2814 | if ($option_databases) { | ||
77 | 2815 | if ($option_databases =~ /^\//) { | ||
78 | 2816 | $options = $options . " --databases_file='$option_databases'"; | ||
79 | 2817 | } else { | ||
80 | 2818 | $options = $options . " --databases='$option_databases'"; | ||
81 | 2819 | } | ||
82 | 2820 | } | ||
83 | 2821 | |||
84 | 2814 | $cmdline = "$option_ibbackup_binary $options"; | 2822 | $cmdline = "$option_ibbackup_binary $options"; |
85 | 2815 | 2823 | ||
86 | 2816 | # run ibbackup as a child process | 2824 | # run ibbackup as a child process |
87 | 2817 | 2825 | ||
88 | === modified file 'src/innodb_int.h' | |||
89 | --- src/innodb_int.h 2014-01-10 11:13:00 +0000 | |||
90 | +++ src/innodb_int.h 2014-08-22 16:46:12 +0000 | |||
91 | @@ -305,8 +305,8 @@ | |||
92 | 305 | #endif | 305 | #endif |
93 | 306 | 306 | ||
94 | 307 | #define XB_HASH_SEARCH(NAME, TABLE, FOLD, DATA, ASSERTION, TEST) \ | 307 | #define XB_HASH_SEARCH(NAME, TABLE, FOLD, DATA, ASSERTION, TEST) \ |
97 | 308 | HASH_SEARCH(NAME, TABLE, FOLD, xtrabackup_tables_t*, DATA, ASSERTION, \ | 308 | HASH_SEARCH(NAME, TABLE, FOLD, xtrabackup_filter_entry_t*, DATA, \ |
98 | 309 | TEST) | 309 | ASSERTION, TEST) |
99 | 310 | 310 | ||
100 | 311 | /* The following constants have been copied from fsp0fsp.c */ | 311 | /* The following constants have been copied from fsp0fsp.c */ |
101 | 312 | #define FSP_HEADER_OFFSET FIL_PAGE_DATA /* Offset of the space header | 312 | #define FSP_HEADER_OFFSET FIL_PAGE_DATA /* Offset of the space header |
102 | 313 | 313 | ||
103 | === modified file 'src/xtrabackup.cc' | |||
104 | --- src/xtrabackup.cc 2014-06-24 09:58:44 +0000 | |||
105 | +++ src/xtrabackup.cc 2014-08-22 16:46:12 +0000 | |||
106 | @@ -58,6 +58,7 @@ | |||
107 | 58 | #endif | 58 | #endif |
108 | 59 | 59 | ||
109 | 60 | #include <fcntl.h> | 60 | #include <fcntl.h> |
110 | 61 | #include <string.h> | ||
111 | 61 | 62 | ||
112 | 62 | #ifdef __linux__ | 63 | #ifdef __linux__ |
113 | 63 | # include <sys/prctl.h> | 64 | # include <sys/prctl.h> |
114 | @@ -122,21 +123,33 @@ | |||
115 | 122 | 123 | ||
116 | 123 | lsn_t xtrabackup_archived_to_lsn = 0; /* for --archived-to-lsn */ | 124 | lsn_t xtrabackup_archived_to_lsn = 0; /* for --archived-to-lsn */ |
117 | 124 | 125 | ||
129 | 125 | char *xtrabackup_tables = NULL; | 126 | static char *xtrabackup_tables = NULL; |
130 | 126 | int tables_regex_num; | 127 | |
131 | 127 | xb_regex_t *tables_regex; | 128 | /* List of regular expressions for filtering */ |
132 | 128 | xb_regmatch_t tables_regmatch[1]; | 129 | typedef struct xb_regex_list_node_struct xb_regex_list_node_t; |
133 | 129 | 130 | struct xb_regex_list_node_struct { | |
134 | 130 | char *xtrabackup_tables_file = NULL; | 131 | UT_LIST_NODE_T(xb_regex_list_node_t) regex_list; |
135 | 131 | hash_table_t* tables_hash; | 132 | xb_regex_t regex; |
136 | 132 | 133 | }; | |
137 | 133 | hash_table_t* inc_dir_tables_hash; | 134 | static UT_LIST_BASE_NODE_T(xb_regex_list_node_t) regex_list; |
138 | 134 | 135 | ||
139 | 135 | struct xtrabackup_tables_struct{ | 136 | static xb_regmatch_t tables_regmatch[1]; |
140 | 137 | |||
141 | 138 | static char *xtrabackup_tables_file = NULL; | ||
142 | 139 | static hash_table_t* tables_hash = NULL; | ||
143 | 140 | |||
144 | 141 | static char *xtrabackup_databases = NULL; | ||
145 | 142 | static char *xtrabackup_databases_file = NULL; | ||
146 | 143 | static hash_table_t* databases_hash = NULL; | ||
147 | 144 | |||
148 | 145 | static hash_table_t* inc_dir_tables_hash; | ||
149 | 146 | |||
150 | 147 | struct xtrabackup_filter_entry_struct{ | ||
151 | 136 | char* name; | 148 | char* name; |
152 | 149 | ibool has_tables; | ||
153 | 137 | hash_node_t name_hash; | 150 | hash_node_t name_hash; |
154 | 138 | }; | 151 | }; |
156 | 139 | typedef struct xtrabackup_tables_struct xtrabackup_tables_t; | 152 | typedef struct xtrabackup_filter_entry_struct xtrabackup_filter_entry_t; |
157 | 140 | 153 | ||
158 | 141 | #ifdef XTRADB_BASED | 154 | #ifdef XTRADB_BASED |
159 | 142 | static ulint thread_nr[SRV_MAX_N_IO_THREADS + 6 + 64]; | 155 | static ulint thread_nr[SRV_MAX_N_IO_THREADS + 6 + 64]; |
160 | @@ -408,6 +421,8 @@ | |||
161 | 408 | OPT_XTRA_ARCHIVED_TO_LSN, | 421 | OPT_XTRA_ARCHIVED_TO_LSN, |
162 | 409 | OPT_XTRA_TABLES, | 422 | OPT_XTRA_TABLES, |
163 | 410 | OPT_XTRA_TABLES_FILE, | 423 | OPT_XTRA_TABLES_FILE, |
164 | 424 | OPT_XTRA_DATABASES, | ||
165 | 425 | OPT_XTRA_DATABASES_FILE, | ||
166 | 411 | OPT_XTRA_CREATE_IB_LOGFILE, | 426 | OPT_XTRA_CREATE_IB_LOGFILE, |
167 | 412 | OPT_XTRA_PARALLEL, | 427 | OPT_XTRA_PARALLEL, |
168 | 413 | OPT_XTRA_STREAM, | 428 | OPT_XTRA_STREAM, |
169 | @@ -583,6 +598,13 @@ | |||
170 | 583 | {"tables_file", OPT_XTRA_TABLES_FILE, "filtering by list of the exact database.table name in the file.", | 598 | {"tables_file", OPT_XTRA_TABLES_FILE, "filtering by list of the exact database.table name in the file.", |
171 | 584 | (G_PTR*) &xtrabackup_tables_file, (G_PTR*) &xtrabackup_tables_file, | 599 | (G_PTR*) &xtrabackup_tables_file, (G_PTR*) &xtrabackup_tables_file, |
172 | 585 | 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, | 600 | 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, |
173 | 601 | {"databases", OPT_XTRA_DATABASES, "filtering by list of databases.", | ||
174 | 602 | (G_PTR*) &xtrabackup_databases, (G_PTR*) &xtrabackup_databases, | ||
175 | 603 | 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, | ||
176 | 604 | {"databases_file", OPT_XTRA_TABLES_FILE, | ||
177 | 605 | "filtering by list of databases in the file.", | ||
178 | 606 | (G_PTR*) &xtrabackup_databases_file, (G_PTR*) &xtrabackup_databases_file, | ||
179 | 607 | 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, | ||
180 | 586 | {"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. ###", | 608 | {"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. ###", |
181 | 587 | (G_PTR*) &xtrabackup_create_ib_logfile, (G_PTR*) &xtrabackup_create_ib_logfile, | 609 | (G_PTR*) &xtrabackup_create_ib_logfile, (G_PTR*) &xtrabackup_create_ib_logfile, |
182 | 588 | 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, | 610 | 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, |
183 | @@ -1742,16 +1764,15 @@ | |||
184 | 1742 | static my_bool | 1764 | static my_bool |
185 | 1743 | check_if_table_matches_filters(const char *name) | 1765 | check_if_table_matches_filters(const char *name) |
186 | 1744 | { | 1766 | { |
197 | 1745 | int regres; | 1767 | int regres; |
198 | 1746 | int i; | 1768 | xtrabackup_filter_entry_t* table; |
199 | 1747 | xtrabackup_tables_t* table; | 1769 | xb_regex_list_node_t* node; |
200 | 1748 | 1770 | ||
201 | 1749 | if (xtrabackup_tables) { | 1771 | if (UT_LIST_GET_LEN(regex_list)) { |
202 | 1750 | 1772 | /* Check against regular expressions list */ | |
203 | 1751 | regres = REG_NOMATCH; | 1773 | for (node = UT_LIST_GET_FIRST(regex_list); node; |
204 | 1752 | 1774 | node = UT_LIST_GET_NEXT(regex_list, node)) { | |
205 | 1753 | for (i = 0; i < tables_regex_num; i++) { | 1775 | regres = xb_regexec(&node->regex, name, 1, |
196 | 1754 | regres = xb_regexec(&tables_regex[i], name, 1, | ||
206 | 1755 | tables_regmatch, 0); | 1776 | tables_regmatch, 0); |
207 | 1756 | if (regres != REG_NOMATCH) { | 1777 | if (regres != REG_NOMATCH) { |
208 | 1757 | 1778 | ||
209 | @@ -1760,8 +1781,8 @@ | |||
210 | 1760 | } | 1781 | } |
211 | 1761 | } | 1782 | } |
212 | 1762 | 1783 | ||
215 | 1763 | if (xtrabackup_tables_file) { | 1784 | if (tables_hash) { |
216 | 1764 | 1785 | /* Finally, check against full qualified tables list */ | |
217 | 1765 | XB_HASH_SEARCH(name_hash, tables_hash, ut_fold_string(name), | 1786 | XB_HASH_SEARCH(name_hash, tables_hash, ut_fold_string(name), |
218 | 1766 | table, (void) 0, | 1787 | table, (void) 0, |
219 | 1767 | !strcmp(table->name, name)); | 1788 | !strcmp(table->name, name)); |
220 | @@ -1791,7 +1812,9 @@ | |||
221 | 1791 | const char *ptr; | 1812 | const char *ptr; |
222 | 1792 | char *eptr; | 1813 | char *eptr; |
223 | 1793 | 1814 | ||
225 | 1794 | if (xtrabackup_tables == NULL && xtrabackup_tables_file == NULL) { | 1815 | if (UT_LIST_GET_LEN(regex_list) == 0 && |
226 | 1816 | tables_hash == NULL && | ||
227 | 1817 | databases_hash == NULL) { | ||
228 | 1795 | return(FALSE); | 1818 | return(FALSE); |
229 | 1796 | } | 1819 | } |
230 | 1797 | 1820 | ||
231 | @@ -1807,6 +1830,26 @@ | |||
232 | 1807 | } | 1830 | } |
233 | 1808 | 1831 | ||
234 | 1809 | strncpy(buf, dbname, FN_REFLEN); | 1832 | strncpy(buf, dbname, FN_REFLEN); |
235 | 1833 | buf[tbname - 1 - dbname] = 0; | ||
236 | 1834 | |||
237 | 1835 | if (databases_hash) { | ||
238 | 1836 | /* There are some filters for databases, check them */ | ||
239 | 1837 | xtrabackup_filter_entry_t* database; | ||
240 | 1838 | |||
241 | 1839 | XB_HASH_SEARCH(name_hash, databases_hash, ut_fold_string(buf), | ||
242 | 1840 | database, (void) 0, | ||
243 | 1841 | !strcmp(database->name, buf)); | ||
244 | 1842 | /* Table's database isn't found, skip the table */ | ||
245 | 1843 | if (!database) { | ||
246 | 1844 | return(TRUE); | ||
247 | 1845 | } | ||
248 | 1846 | /* There aren't tables specified for the database, | ||
249 | 1847 | it should be backed up entirely */ | ||
250 | 1848 | if (!database->has_tables) { | ||
251 | 1849 | return(FALSE); | ||
252 | 1850 | } | ||
253 | 1851 | } | ||
254 | 1852 | |||
255 | 1810 | buf[FN_REFLEN - 1] = '\0'; | 1853 | buf[FN_REFLEN - 1] = '\0'; |
256 | 1811 | buf[tbname - 1 - dbname] = '.'; | 1854 | buf[tbname - 1 - dbname] = '.'; |
257 | 1812 | 1855 | ||
258 | @@ -2789,120 +2832,279 @@ | |||
259 | 2789 | return(FALSE); | 2832 | return(FALSE); |
260 | 2790 | } | 2833 | } |
261 | 2791 | 2834 | ||
262 | 2835 | /*********************************************************************** | ||
263 | 2836 | Allocate and initialize the entry for databases and tables filtering | ||
264 | 2837 | hash tables. If memory allocation is not successful, terminate program. | ||
265 | 2838 | @return pointer to the created entry. */ | ||
266 | 2839 | static | ||
267 | 2840 | xtrabackup_filter_entry_t * | ||
268 | 2841 | xb_new_filter_entry( | ||
269 | 2842 | /*================*/ | ||
270 | 2843 | const char* name) /*!< in: name of table/database */ | ||
271 | 2844 | { | ||
272 | 2845 | xtrabackup_filter_entry_t *entry; | ||
273 | 2846 | ulint namelen = strlen(name); | ||
274 | 2847 | |||
275 | 2848 | /* Length of name shouldn't be greater than 129 character, | ||
276 | 2849 | which isn't actually 129 bytes as some of UTF-8 characters | ||
277 | 2850 | for example can be encoded by 4 bytes. */ | ||
278 | 2851 | ut_a(namelen <= NAME_LEN * 2 + 1); | ||
279 | 2852 | |||
280 | 2853 | entry = static_cast<xtrabackup_filter_entry_t *> | ||
281 | 2854 | (ut_malloc(sizeof(xtrabackup_filter_entry_t) + namelen + 1)); | ||
282 | 2855 | memset(entry, '\0', sizeof(xtrabackup_filter_entry_t) + namelen + 1); | ||
283 | 2856 | entry->name = ((char*)entry) + sizeof(xtrabackup_filter_entry_t); | ||
284 | 2857 | strcpy(entry->name, name); | ||
285 | 2858 | entry->has_tables = FALSE; | ||
286 | 2859 | |||
287 | 2860 | return entry; | ||
288 | 2861 | } | ||
289 | 2862 | |||
290 | 2863 | /*********************************************************************** | ||
291 | 2864 | Add entry to hash table. If hash table is NULL, allocate and initialize | ||
292 | 2865 | new hash table */ | ||
293 | 2866 | static | ||
294 | 2867 | xtrabackup_filter_entry_t* | ||
295 | 2868 | xb_add_filter_entry_to_hash( | ||
296 | 2869 | /*========================*/ | ||
297 | 2870 | const char* name, /*!< in: name of table/database */ | ||
298 | 2871 | hash_table_t** hash) /*!< in/out: hash to insert into */ | ||
299 | 2872 | { | ||
300 | 2873 | xtrabackup_filter_entry_t* entry; | ||
301 | 2874 | |||
302 | 2875 | entry = xb_new_filter_entry(name); | ||
303 | 2876 | |||
304 | 2877 | if (UNIV_UNLIKELY(*hash == NULL)) { | ||
305 | 2878 | *hash = hash_create(1000); | ||
306 | 2879 | } | ||
307 | 2880 | HASH_INSERT(xtrabackup_filter_entry_t, | ||
308 | 2881 | name_hash, *hash, | ||
309 | 2882 | ut_fold_string(entry->name), | ||
310 | 2883 | entry); | ||
311 | 2884 | |||
312 | 2885 | return entry; | ||
313 | 2886 | } | ||
314 | 2887 | |||
315 | 2888 | /*********************************************************************** | ||
316 | 2889 | Validate name of table or database. If name is invalid, program will | ||
317 | 2890 | be finished with error code */ | ||
318 | 2891 | static | ||
319 | 2892 | void | ||
320 | 2893 | xb_validate_name( | ||
321 | 2894 | /*=============*/ | ||
322 | 2895 | const char* name, /*!< in: name */ | ||
323 | 2896 | size_t len) /*!< in: length of name */ | ||
324 | 2897 | { | ||
325 | 2898 | const char* p; | ||
326 | 2899 | |||
327 | 2900 | /* perform only basic validation. validate length and | ||
328 | 2901 | path symbols */ | ||
329 | 2902 | if (len > NAME_LEN) { | ||
330 | 2903 | msg("xtrabackup: name `%s` is too long.\n", name); | ||
331 | 2904 | exit(EXIT_FAILURE); | ||
332 | 2905 | } | ||
333 | 2906 | p = strpbrk(name, "/\\~"); | ||
334 | 2907 | if (p && p - name < NAME_LEN) { | ||
335 | 2908 | msg("xtrabackup: name `%s` is not valid.\n", name); | ||
336 | 2909 | exit(EXIT_FAILURE); | ||
337 | 2910 | } | ||
338 | 2911 | } | ||
339 | 2912 | |||
340 | 2913 | /*********************************************************************** | ||
341 | 2914 | Register new filter entry which can be either database | ||
342 | 2915 | or table name. */ | ||
343 | 2916 | static | ||
344 | 2917 | void | ||
345 | 2918 | xb_register_filter_entry( | ||
346 | 2919 | /*=====================*/ | ||
347 | 2920 | const char* name) /*!< in: name */ | ||
348 | 2921 | { | ||
349 | 2922 | const char* p; | ||
350 | 2923 | size_t namelen; | ||
351 | 2924 | xtrabackup_filter_entry_t* db_entry = NULL; | ||
352 | 2925 | |||
353 | 2926 | namelen = strlen(name); | ||
354 | 2927 | if ((p = strchr(name, '.')) != NULL) { | ||
355 | 2928 | char dbname[NAME_LEN + 1]; | ||
356 | 2929 | |||
357 | 2930 | xb_validate_name(name, p - name); | ||
358 | 2931 | xb_validate_name(p + 1, namelen - (p - name)); | ||
359 | 2932 | |||
360 | 2933 | strncpy(dbname, name, p - name); | ||
361 | 2934 | dbname[p - name] = 0; | ||
362 | 2935 | |||
363 | 2936 | if (databases_hash) { | ||
364 | 2937 | XB_HASH_SEARCH(name_hash, databases_hash, | ||
365 | 2938 | ut_fold_string(dbname), | ||
366 | 2939 | db_entry, (void) 0, | ||
367 | 2940 | !strcmp(db_entry->name, dbname)); | ||
368 | 2941 | } | ||
369 | 2942 | if (!db_entry) { | ||
370 | 2943 | db_entry = xb_add_filter_entry_to_hash(dbname, | ||
371 | 2944 | &databases_hash); | ||
372 | 2945 | } | ||
373 | 2946 | db_entry->has_tables = TRUE; | ||
374 | 2947 | xb_add_filter_entry_to_hash(name, &tables_hash); | ||
375 | 2948 | } else { | ||
376 | 2949 | xb_validate_name(name, namelen); | ||
377 | 2950 | |||
378 | 2951 | xb_add_filter_entry_to_hash(name, &databases_hash); | ||
379 | 2952 | } | ||
380 | 2953 | } | ||
381 | 2954 | |||
382 | 2955 | /*********************************************************************** | ||
383 | 2956 | Register new table for the filter. */ | ||
384 | 2957 | static | ||
385 | 2958 | void | ||
386 | 2959 | xb_register_table( | ||
387 | 2960 | /*==============*/ | ||
388 | 2961 | const char* name) /*!< in: name of table */ | ||
389 | 2962 | { | ||
390 | 2963 | if (strchr(name, '.') == NULL) { | ||
391 | 2964 | msg("xtrabackup: `%s` is not fully qualified name.\n", name); | ||
392 | 2965 | exit(EXIT_FAILURE); | ||
393 | 2966 | } | ||
394 | 2967 | |||
395 | 2968 | xb_register_filter_entry(name); | ||
396 | 2969 | } | ||
397 | 2970 | |||
398 | 2971 | /*********************************************************************** | ||
399 | 2972 | Register new regex for the filter. */ | ||
400 | 2973 | static | ||
401 | 2974 | void | ||
402 | 2975 | xb_register_regex( | ||
403 | 2976 | /*==============*/ | ||
404 | 2977 | const char* regex) /*!< in: regex */ | ||
405 | 2978 | { | ||
406 | 2979 | xb_regex_list_node_t* node; | ||
407 | 2980 | char errbuf[100]; | ||
408 | 2981 | int ret; | ||
409 | 2982 | |||
410 | 2983 | node = static_cast<xb_regex_list_node_t *> | ||
411 | 2984 | (ut_malloc(sizeof(xb_regex_list_node_t))); | ||
412 | 2985 | |||
413 | 2986 | ret = xb_regcomp(&node->regex, regex, REG_EXTENDED); | ||
414 | 2987 | if (ret != 0) { | ||
415 | 2988 | xb_regerror(ret, &node->regex, errbuf, sizeof(errbuf)); | ||
416 | 2989 | msg("xtrabackup: error: tables regcomp(%s): %s\n", | ||
417 | 2990 | regex, errbuf); | ||
418 | 2991 | exit(EXIT_FAILURE); | ||
419 | 2992 | } | ||
420 | 2993 | |||
421 | 2994 | UT_LIST_ADD_LAST(regex_list, regex_list, node); | ||
422 | 2995 | } | ||
423 | 2996 | |||
424 | 2997 | typedef void (*insert_entry_func_t)(const char*); | ||
425 | 2998 | |||
426 | 2999 | /*********************************************************************** | ||
427 | 3000 | Scan string and load filter entries from it. */ | ||
428 | 3001 | static | ||
429 | 3002 | void | ||
430 | 3003 | xb_load_list_string( | ||
431 | 3004 | /*================*/ | ||
432 | 3005 | char* list, /*!< in: string representing a list */ | ||
433 | 3006 | const char* delimiters, /*!< in: delimiters of entries */ | ||
434 | 3007 | insert_entry_func_t ins) /*!< in: callback to add entry */ | ||
435 | 3008 | { | ||
436 | 3009 | char* p; | ||
437 | 3010 | char* saveptr; | ||
438 | 3011 | |||
439 | 3012 | p = strtok_r(list, delimiters, &saveptr); | ||
440 | 3013 | while (p) { | ||
441 | 3014 | |||
442 | 3015 | ins(p); | ||
443 | 3016 | |||
444 | 3017 | p = strtok_r(NULL, delimiters, &saveptr); | ||
445 | 3018 | } | ||
446 | 3019 | } | ||
447 | 3020 | |||
448 | 3021 | /*********************************************************************** | ||
449 | 3022 | Scan file and load filter entries from it. */ | ||
450 | 3023 | static | ||
451 | 3024 | void | ||
452 | 3025 | xb_load_list_file( | ||
453 | 3026 | /*==============*/ | ||
454 | 3027 | const char* filename, /*!< in: name of file */ | ||
455 | 3028 | insert_entry_func_t ins) /*!< in: callback to add entry */ | ||
456 | 3029 | { | ||
457 | 3030 | char name_buf[NAME_LEN*2+2]; | ||
458 | 3031 | FILE *fp; | ||
459 | 3032 | |||
460 | 3033 | /* read and store the filenames */ | ||
461 | 3034 | fp = fopen(filename, "r"); | ||
462 | 3035 | if (!fp) { | ||
463 | 3036 | msg("xtrabackup: cannot open %s\n", | ||
464 | 3037 | filename); | ||
465 | 3038 | exit(EXIT_FAILURE); | ||
466 | 3039 | } | ||
467 | 3040 | for (;;) { | ||
468 | 3041 | char* p = name_buf; | ||
469 | 3042 | |||
470 | 3043 | if (fgets(name_buf, sizeof(name_buf), fp) == 0) { | ||
471 | 3044 | break; | ||
472 | 3045 | } | ||
473 | 3046 | |||
474 | 3047 | p = strchr(name_buf, '\n'); | ||
475 | 3048 | if (p) { | ||
476 | 3049 | *p = '\0'; | ||
477 | 3050 | } else { | ||
478 | 3051 | msg("xtrabackup: `%s...` name is too long", name_buf); | ||
479 | 3052 | exit(EXIT_FAILURE); | ||
480 | 3053 | } | ||
481 | 3054 | |||
482 | 3055 | ins(name_buf); | ||
483 | 3056 | } | ||
484 | 3057 | |||
485 | 3058 | fclose(fp); | ||
486 | 3059 | } | ||
487 | 3060 | |||
488 | 3061 | |||
489 | 2792 | static | 3062 | static |
490 | 2793 | void | 3063 | void |
491 | 2794 | xb_filters_init() | 3064 | xb_filters_init() |
492 | 2795 | { | 3065 | { |
493 | 3066 | UT_LIST_INIT(regex_list); | ||
494 | 3067 | |||
495 | 3068 | if (xtrabackup_databases) { | ||
496 | 3069 | xb_load_list_string(xtrabackup_databases, " \t", | ||
497 | 3070 | xb_register_filter_entry); | ||
498 | 3071 | } | ||
499 | 3072 | |||
500 | 3073 | if (xtrabackup_databases_file) { | ||
501 | 3074 | xb_load_list_file(xtrabackup_databases_file, | ||
502 | 3075 | xb_register_filter_entry); | ||
503 | 3076 | } | ||
504 | 3077 | |||
505 | 2796 | if (xtrabackup_tables) { | 3078 | if (xtrabackup_tables) { |
550 | 2797 | /* init regexp */ | 3079 | xb_load_list_string(xtrabackup_tables, ",", |
551 | 2798 | char *p, *next; | 3080 | xb_register_regex); |
508 | 2799 | int i; | ||
509 | 2800 | char errbuf[100]; | ||
510 | 2801 | |||
511 | 2802 | tables_regex_num = 1; | ||
512 | 2803 | |||
513 | 2804 | p = xtrabackup_tables; | ||
514 | 2805 | while ((p = strchr(p, ',')) != NULL) { | ||
515 | 2806 | p++; | ||
516 | 2807 | tables_regex_num++; | ||
517 | 2808 | } | ||
518 | 2809 | |||
519 | 2810 | tables_regex = static_cast<xb_regex_t *> | ||
520 | 2811 | (ut_malloc(sizeof(xb_regex_t) * tables_regex_num)); | ||
521 | 2812 | |||
522 | 2813 | p = xtrabackup_tables; | ||
523 | 2814 | for (i=0; i < tables_regex_num; i++) { | ||
524 | 2815 | int rc; | ||
525 | 2816 | |||
526 | 2817 | next = strchr(p, ','); | ||
527 | 2818 | ut_a(next || i == tables_regex_num - 1); | ||
528 | 2819 | |||
529 | 2820 | next++; | ||
530 | 2821 | if (i != tables_regex_num - 1) | ||
531 | 2822 | *(next - 1) = '\0'; | ||
532 | 2823 | |||
533 | 2824 | rc = xb_regcomp(&tables_regex[i], p, | ||
534 | 2825 | REG_EXTENDED); | ||
535 | 2826 | |||
536 | 2827 | if (rc) { | ||
537 | 2828 | |||
538 | 2829 | xb_regerror(rc, &tables_regex[i], errbuf, | ||
539 | 2830 | sizeof(errbuf)); | ||
540 | 2831 | msg("xtrabackup: regcomp(%s) failed: %s\n", | ||
541 | 2832 | p, errbuf); | ||
542 | 2833 | |||
543 | 2834 | exit(EXIT_FAILURE); | ||
544 | 2835 | } | ||
545 | 2836 | |||
546 | 2837 | if (i != tables_regex_num - 1) | ||
547 | 2838 | *(next - 1) = ','; | ||
548 | 2839 | p = next; | ||
549 | 2840 | } | ||
552 | 2841 | } | 3081 | } |
553 | 2842 | 3082 | ||
554 | 2843 | if (xtrabackup_tables_file) { | 3083 | if (xtrabackup_tables_file) { |
594 | 2844 | char name_buf[NAME_LEN*2+2]; | 3084 | xb_load_list_file(xtrabackup_tables_file, xb_register_table); |
556 | 2845 | FILE *fp; | ||
557 | 2846 | |||
558 | 2847 | name_buf[NAME_LEN*2+1] = '\0'; | ||
559 | 2848 | |||
560 | 2849 | /* init tables_hash */ | ||
561 | 2850 | tables_hash = hash_create(1000); | ||
562 | 2851 | |||
563 | 2852 | /* read and store the filenames */ | ||
564 | 2853 | fp = fopen(xtrabackup_tables_file,"r"); | ||
565 | 2854 | if (!fp) { | ||
566 | 2855 | msg("xtrabackup: cannot open %s\n", | ||
567 | 2856 | xtrabackup_tables_file); | ||
568 | 2857 | exit(EXIT_FAILURE); | ||
569 | 2858 | } | ||
570 | 2859 | for (;;) { | ||
571 | 2860 | xtrabackup_tables_t* table; | ||
572 | 2861 | char* p = name_buf; | ||
573 | 2862 | |||
574 | 2863 | if ( fgets(name_buf, NAME_LEN*2+1, fp) == 0 ) { | ||
575 | 2864 | break; | ||
576 | 2865 | } | ||
577 | 2866 | |||
578 | 2867 | p = strchr(name_buf, '\n'); | ||
579 | 2868 | if (p) | ||
580 | 2869 | { | ||
581 | 2870 | *p = '\0'; | ||
582 | 2871 | } | ||
583 | 2872 | |||
584 | 2873 | table = static_cast<xtrabackup_tables_t *> | ||
585 | 2874 | (ut_malloc(sizeof(xtrabackup_tables_t) | ||
586 | 2875 | + strlen(name_buf) + 1)); | ||
587 | 2876 | memset(table, '\0', sizeof(xtrabackup_tables_t) + strlen(name_buf) + 1); | ||
588 | 2877 | table->name = ((char*)table) + sizeof(xtrabackup_tables_t); | ||
589 | 2878 | strcpy(table->name, name_buf); | ||
590 | 2879 | |||
591 | 2880 | HASH_INSERT(xtrabackup_tables_t, name_hash, tables_hash, | ||
592 | 2881 | ut_fold_string(table->name), table); | ||
593 | 2882 | } | ||
595 | 2883 | } | 3085 | } |
596 | 2884 | } | 3086 | } |
597 | 2885 | 3087 | ||
598 | 2886 | static | 3088 | static |
599 | 2887 | void | 3089 | void |
601 | 2888 | xb_tables_hash_free(hash_table_t* hash) | 3090 | xb_filter_hash_free(hash_table_t* hash) |
602 | 2889 | { | 3091 | { |
603 | 2890 | ulint i; | 3092 | ulint i; |
604 | 2891 | 3093 | ||
605 | 2892 | /* free the hash elements */ | 3094 | /* free the hash elements */ |
606 | 2893 | for (i = 0; i < hash_get_n_cells(hash); i++) { | 3095 | for (i = 0; i < hash_get_n_cells(hash); i++) { |
608 | 2894 | xtrabackup_tables_t* table; | 3096 | xtrabackup_filter_entry_t* table; |
609 | 2895 | 3097 | ||
611 | 2896 | table = static_cast<xtrabackup_tables_t *> | 3098 | table = static_cast<xtrabackup_filter_entry_t *> |
612 | 2897 | (HASH_GET_FIRST(hash, i)); | 3099 | (HASH_GET_FIRST(hash, i)); |
613 | 2898 | 3100 | ||
614 | 2899 | while (table) { | 3101 | while (table) { |
616 | 2900 | xtrabackup_tables_t* prev_table = table; | 3102 | xtrabackup_filter_entry_t* prev_table = table; |
617 | 2901 | 3103 | ||
619 | 2902 | table = static_cast<xtrabackup_tables_t *> | 3104 | table = static_cast<xtrabackup_filter_entry_t *> |
620 | 2903 | (HASH_GET_NEXT(name_hash, prev_table)); | 3105 | (HASH_GET_NEXT(name_hash, prev_table)); |
621 | 2904 | 3106 | ||
623 | 2905 | HASH_DELETE(xtrabackup_tables_t, name_hash, hash, | 3107 | HASH_DELETE(xtrabackup_filter_entry_t, name_hash, hash, |
624 | 2906 | ut_fold_string(prev_table->name), prev_table); | 3108 | ut_fold_string(prev_table->name), prev_table); |
625 | 2907 | ut_free(prev_table); | 3109 | ut_free(prev_table); |
626 | 2908 | } | 3110 | } |
627 | @@ -2918,18 +3120,19 @@ | |||
628 | 2918 | void | 3120 | void |
629 | 2919 | xb_filters_free() | 3121 | xb_filters_free() |
630 | 2920 | { | 3122 | { |
643 | 2921 | if (xtrabackup_tables) { | 3123 | while (UT_LIST_GET_LEN(regex_list) > 0) { |
644 | 2922 | /* free regexp */ | 3124 | xb_regex_list_node_t* node = UT_LIST_GET_FIRST(regex_list); |
645 | 2923 | int i; | 3125 | UT_LIST_REMOVE(regex_list, regex_list, node); |
646 | 2924 | 3126 | xb_regfree(&node->regex); | |
647 | 2925 | for (i = 0; i < tables_regex_num; i++) { | 3127 | ut_free(node); |
648 | 2926 | xb_regfree(&tables_regex[i]); | 3128 | } |
649 | 2927 | } | 3129 | |
650 | 2928 | ut_free(tables_regex); | 3130 | if (tables_hash) { |
651 | 2929 | } | 3131 | xb_filter_hash_free(tables_hash); |
652 | 2930 | 3132 | } | |
653 | 2931 | if (xtrabackup_tables_file) { | 3133 | |
654 | 2932 | xb_tables_hash_free(tables_hash); | 3134 | if (databases_hash) { |
655 | 3135 | xb_filter_hash_free(databases_hash); | ||
656 | 2933 | } | 3136 | } |
657 | 2934 | } | 3137 | } |
658 | 2935 | 3138 | ||
659 | @@ -4271,7 +4474,7 @@ | |||
660 | 4271 | fil_space_t* fil_space; | 4474 | fil_space_t* fil_space; |
661 | 4272 | os_file_t file = 0; | 4475 | os_file_t file = 0; |
662 | 4273 | ulint tablespace_flags; | 4476 | ulint tablespace_flags; |
664 | 4274 | xtrabackup_tables_t* table; | 4477 | xtrabackup_filter_entry_t* table; |
665 | 4275 | 4478 | ||
666 | 4276 | ut_a(dbname != NULL || | 4479 | ut_a(dbname != NULL || |
667 | 4277 | trx_sys_sys_space(space_id) || | 4480 | trx_sys_sys_space(space_id) || |
668 | @@ -4311,13 +4514,13 @@ | |||
669 | 4311 | } | 4514 | } |
670 | 4312 | 4515 | ||
671 | 4313 | /* remember space name for further reference */ | 4516 | /* remember space name for further reference */ |
674 | 4314 | table = static_cast<xtrabackup_tables_t *> | 4517 | table = static_cast<xtrabackup_filter_entry_t *> |
675 | 4315 | (ut_malloc(sizeof(xtrabackup_tables_t) + | 4518 | (ut_malloc(sizeof(xtrabackup_filter_entry_t) + |
676 | 4316 | strlen(dest_space_name) + 1)); | 4519 | strlen(dest_space_name) + 1)); |
677 | 4317 | 4520 | ||
679 | 4318 | table->name = ((char*)table) + sizeof(xtrabackup_tables_t); | 4521 | table->name = ((char*)table) + sizeof(xtrabackup_filter_entry_t); |
680 | 4319 | strcpy(table->name, dest_space_name); | 4522 | strcpy(table->name, dest_space_name); |
682 | 4320 | HASH_INSERT(xtrabackup_tables_t, name_hash, inc_dir_tables_hash, | 4523 | HASH_INSERT(xtrabackup_filter_entry_t, name_hash, inc_dir_tables_hash, |
683 | 4321 | ut_fold_string(table->name), table); | 4524 | ut_fold_string(table->name), table); |
684 | 4322 | 4525 | ||
685 | 4323 | mutex_enter(&fil_system->mutex); | 4526 | mutex_enter(&fil_system->mutex); |
686 | @@ -4651,8 +4854,8 @@ | |||
687 | 4651 | const char* file_name, /*!<in: file name with suffix */ | 4854 | const char* file_name, /*!<in: file name with suffix */ |
688 | 4652 | void* arg __attribute__((unused))) | 4855 | void* arg __attribute__((unused))) |
689 | 4653 | { | 4856 | { |
692 | 4654 | char name[FN_REFLEN]; | 4857 | char name[FN_REFLEN]; |
693 | 4655 | xtrabackup_tables_t* table; | 4858 | xtrabackup_filter_entry_t* table; |
694 | 4656 | 4859 | ||
695 | 4657 | snprintf(name, FN_REFLEN, "%s%s/%s", | 4860 | snprintf(name, FN_REFLEN, "%s%s/%s", |
696 | 4658 | xb_dict_prefix, db_name, file_name); | 4861 | xb_dict_prefix, db_name, file_name); |
697 | @@ -5434,7 +5637,7 @@ | |||
698 | 5434 | 5637 | ||
699 | 5435 | if(!xtrabackup_apply_deltas()) { | 5638 | if(!xtrabackup_apply_deltas()) { |
700 | 5436 | xb_data_files_close(); | 5639 | xb_data_files_close(); |
702 | 5437 | xb_tables_hash_free(inc_dir_tables_hash); | 5640 | xb_filter_hash_free(inc_dir_tables_hash); |
703 | 5438 | goto error; | 5641 | goto error; |
704 | 5439 | } | 5642 | } |
705 | 5440 | } | 5643 | } |
706 | @@ -5447,7 +5650,7 @@ | |||
707 | 5447 | 5650 | ||
708 | 5448 | xb_process_datadir("./", ".ibd", rm_if_not_found, NULL); | 5651 | xb_process_datadir("./", ".ibd", rm_if_not_found, NULL); |
709 | 5449 | 5652 | ||
711 | 5450 | xb_tables_hash_free(inc_dir_tables_hash); | 5653 | xb_filter_hash_free(inc_dir_tables_hash); |
712 | 5451 | } | 5654 | } |
713 | 5452 | sync_close(); | 5655 | sync_close(); |
714 | 5453 | sync_initialized = FALSE; | 5656 | sync_initialized = FALSE; |
715 | 5454 | 5657 | ||
716 | === added file 'test/t/ib_databases.sh' | |||
717 | --- test/t/ib_databases.sh 1970-01-01 00:00:00 +0000 | |||
718 | +++ test/t/ib_databases.sh 2014-08-22 16:46:12 +0000 | |||
719 | @@ -0,0 +1,48 @@ | |||
720 | 1 | ######################################################################## | ||
721 | 2 | # Bug #569387: innobackupex ignores --databases | ||
722 | 3 | # Testcase covers using --databases option with InnoDB | ||
723 | 4 | # database (list is specified in option itself) | ||
724 | 5 | ######################################################################## | ||
725 | 6 | |||
726 | 7 | . inc/common.sh | ||
727 | 8 | |||
728 | 9 | start_server --innodb-file-per-table | ||
729 | 10 | |||
730 | 11 | cat <<EOF | run_cmd $MYSQL $MYSQL_ARGS | ||
731 | 12 | |||
732 | 13 | CREATE DATABASE test1; | ||
733 | 14 | |||
734 | 15 | CREATE TABLE test1.a (a INT PRIMARY KEY); | ||
735 | 16 | CREATE TABLE test1.b (b INT PRIMARY KEY); | ||
736 | 17 | CREATE TABLE test1.c (c INT PRIMARY KEY); | ||
737 | 18 | |||
738 | 19 | CREATE TABLE test.a (a INT PRIMARY KEY); | ||
739 | 20 | CREATE TABLE test.b (b INT PRIMARY KEY); | ||
740 | 21 | CREATE TABLE test.c (c INT PRIMARY KEY); | ||
741 | 22 | |||
742 | 23 | EOF | ||
743 | 24 | |||
744 | 25 | # This is a workaround to pass --databases='test test1.b test1.c ... ' (containing spaces) | ||
745 | 26 | $IB_BIN $IB_ARGS --no-timestamp --databases='test test1.b test1.c mysql performance_schema' $topdir/backup | ||
746 | 27 | innobackupex --apply-log $topdir/backup | ||
747 | 28 | vlog "Backup taken" | ||
748 | 29 | |||
749 | 30 | stop_server | ||
750 | 31 | |||
751 | 32 | # Restore partial backup | ||
752 | 33 | # Remove database | ||
753 | 34 | rm -rf $mysql_datadir/* | ||
754 | 35 | vlog "Original database removed" | ||
755 | 36 | |||
756 | 37 | # Restore database from backup | ||
757 | 38 | innobackupex --copy-back $topdir/backup | ||
758 | 39 | vlog "database restored from backup" | ||
759 | 40 | |||
760 | 41 | start_server | ||
761 | 42 | |||
762 | 43 | OUT=`run_cmd $MYSQL $MYSQL_ARGS -e "USE test; SHOW TABLES; USE test1; SHOW TABLES;" | tr -d '\n'` | ||
763 | 44 | |||
764 | 45 | if [ $OUT != "Tables_in_testabcTables_in_test1bc" ] ; then | ||
765 | 46 | vlog "Backed up tables set doesn't match filter" ; | ||
766 | 47 | exit 1; | ||
767 | 48 | fi | ||
768 | 0 | 49 | ||
769 | === added file 'test/t/ib_databases_file.sh' | |||
770 | --- test/t/ib_databases_file.sh 1970-01-01 00:00:00 +0000 | |||
771 | +++ test/t/ib_databases_file.sh 2014-08-22 16:46:12 +0000 | |||
772 | @@ -0,0 +1,57 @@ | |||
773 | 1 | ######################################################################## | ||
774 | 2 | # Bug #569387: innobackupex ignores --databases | ||
775 | 3 | # Testcase covers using --databases option with InnoDB | ||
776 | 4 | # database (list is specified in file which option | ||
777 | 5 | # points to) | ||
778 | 6 | ######################################################################## | ||
779 | 7 | |||
780 | 8 | . inc/common.sh | ||
781 | 9 | |||
782 | 10 | start_server --innodb-file-per-table | ||
783 | 11 | |||
784 | 12 | cat <<EOF | run_cmd $MYSQL $MYSQL_ARGS | ||
785 | 13 | |||
786 | 14 | CREATE DATABASE test1; | ||
787 | 15 | |||
788 | 16 | CREATE TABLE test1.a (a INT PRIMARY KEY) engine=InnoDB; | ||
789 | 17 | CREATE TABLE test1.b (b INT PRIMARY KEY) engine=InnoDB; | ||
790 | 18 | CREATE TABLE test1.c (c INT PRIMARY KEY) engine=InnoDB; | ||
791 | 19 | |||
792 | 20 | CREATE TABLE test.a (a INT PRIMARY KEY) engine=InnoDB; | ||
793 | 21 | CREATE TABLE test.b (b INT PRIMARY KEY) engine=InnoDB; | ||
794 | 22 | CREATE TABLE test.c (c INT PRIMARY KEY) engine=InnoDB; | ||
795 | 23 | |||
796 | 24 | EOF | ||
797 | 25 | |||
798 | 26 | # Take a backup | ||
799 | 27 | # Backup the whole test and b,c from test1 | ||
800 | 28 | cat >$topdir/databases_file <<EOF | ||
801 | 29 | mysql | ||
802 | 30 | performance_schema | ||
803 | 31 | test | ||
804 | 32 | test1.b | ||
805 | 33 | test1.c | ||
806 | 34 | EOF | ||
807 | 35 | innobackupex --no-timestamp --databases=$topdir/databases_file $topdir/backup | ||
808 | 36 | innobackupex --apply-log $topdir/backup | ||
809 | 37 | vlog "Backup taken" | ||
810 | 38 | |||
811 | 39 | stop_server | ||
812 | 40 | |||
813 | 41 | # Restore partial backup | ||
814 | 42 | # Remove database | ||
815 | 43 | rm -rf $mysql_datadir/* | ||
816 | 44 | vlog "Original database removed" | ||
817 | 45 | |||
818 | 46 | # Restore database from backup | ||
819 | 47 | innobackupex --copy-back $topdir/backup | ||
820 | 48 | vlog "database restored from backup" | ||
821 | 49 | |||
822 | 50 | start_server | ||
823 | 51 | |||
824 | 52 | OUT=`run_cmd $MYSQL $MYSQL_ARGS -e "USE test; SHOW TABLES; USE test1; SHOW TABLES;" | tr -d '\n'` | ||
825 | 53 | |||
826 | 54 | if [ $OUT != "Tables_in_testabcTables_in_test1bc" ] ; then | ||
827 | 55 | vlog "Backed up tables set don't match filter" ; | ||
828 | 56 | exit 1; | ||
829 | 57 | fi | ||
830 | 0 | 58 | ||
831 | === added file 'test/t/xb_databases_options.sh' | |||
832 | --- test/t/xb_databases_options.sh 1970-01-01 00:00:00 +0000 | |||
833 | +++ test/t/xb_databases_options.sh 2014-08-22 16:46:12 +0000 | |||
834 | @@ -0,0 +1,218 @@ | |||
835 | 1 | ######################################################################## | ||
836 | 2 | # Bug #569387: xtrabackup ignores --databases, i.e. when --databases | ||
837 | 3 | # | ||
838 | 4 | # Test following xtrabackup options | ||
839 | 5 | # --databases | ||
840 | 6 | # --databases-file | ||
841 | 7 | # --tables | ||
842 | 8 | # --tables-file | ||
843 | 9 | ######################################################################## | ||
844 | 10 | |||
845 | 11 | . inc/common.sh | ||
846 | 12 | |||
847 | 13 | start_server --innodb-file-per-table | ||
848 | 14 | |||
849 | 15 | function setup_test { | ||
850 | 16 | |||
851 | 17 | cat <<EOF | run_cmd $MYSQL $MYSQL_ARGS | ||
852 | 18 | |||
853 | 19 | create database database1; | ||
854 | 20 | create database database2; | ||
855 | 21 | create database test1; | ||
856 | 22 | create database test2; | ||
857 | 23 | create database thisisadatabase; | ||
858 | 24 | create database testdatabase; | ||
859 | 25 | |||
860 | 26 | create table database1.thisisatable (a int primary key) engine=InnoDB; | ||
861 | 27 | create table database1.t (a int primary key) engine=InnoDB; | ||
862 | 28 | create table database1.t1 (a int primary key) engine=InnoDB; | ||
863 | 29 | create table database1.t2 (a int primary key) engine=InnoDB; | ||
864 | 30 | create table database1.ancor (a int primary key) engine=InnoDB; | ||
865 | 31 | create table database1.glow (a int primary key) engine=InnoDB; | ||
866 | 32 | |||
867 | 33 | create table database2.thisisatable (a int primary key) engine=InnoDB; | ||
868 | 34 | create table database2.t (a int primary key) engine=InnoDB; | ||
869 | 35 | create table database2.t1 (a int primary key) engine=InnoDB; | ||
870 | 36 | create table database2.t2 (a int primary key) engine=InnoDB; | ||
871 | 37 | create table database2.ancor (a int primary key) engine=InnoDB; | ||
872 | 38 | create table database2.glow (a int primary key) engine=InnoDB; | ||
873 | 39 | |||
874 | 40 | create table test1.thisisatable (a int primary key) engine=InnoDB; | ||
875 | 41 | create table test1.t (a int primary key) engine=InnoDB; | ||
876 | 42 | create table test1.t1 (a int primary key) engine=InnoDB; | ||
877 | 43 | create table test1.t2 (a int primary key) engine=InnoDB; | ||
878 | 44 | create table test1.ancor (a int primary key) engine=InnoDB; | ||
879 | 45 | create table test1.glow (a int primary key) engine=InnoDB; | ||
880 | 46 | |||
881 | 47 | create table test2.thisisatable (a int primary key) engine=InnoDB; | ||
882 | 48 | create table test2.t (a int primary key) engine=InnoDB; | ||
883 | 49 | create table test2.t1 (a int primary key) engine=InnoDB; | ||
884 | 50 | create table test2.t2 (a int primary key) engine=InnoDB; | ||
885 | 51 | create table test2.ancor (a int primary key) engine=InnoDB; | ||
886 | 52 | create table test2.glow (a int primary key) engine=InnoDB; | ||
887 | 53 | |||
888 | 54 | create table thisisadatabase.thisisatable (a int primary key) engine=InnoDB; | ||
889 | 55 | create table thisisadatabase.t (a int primary key) engine=InnoDB; | ||
890 | 56 | create table thisisadatabase.t1 (a int primary key) engine=InnoDB; | ||
891 | 57 | create table thisisadatabase.t2 (a int primary key) engine=InnoDB; | ||
892 | 58 | create table thisisadatabase.ancor (a int primary key) engine=InnoDB; | ||
893 | 59 | create table thisisadatabase.glow (a int primary key) engine=InnoDB; | ||
894 | 60 | |||
895 | 61 | create table testdatabase.thisisatable (a int primary key) engine=InnoDB; | ||
896 | 62 | create table testdatabase.t (a int primary key) engine=InnoDB; | ||
897 | 63 | create table testdatabase.t1 (a int primary key) engine=InnoDB; | ||
898 | 64 | create table testdatabase.t2 (a int primary key) engine=InnoDB; | ||
899 | 65 | create table testdatabase.ancor (a int primary key) engine=InnoDB; | ||
900 | 66 | create table testdatabase.glow (a int primary key) engine=InnoDB; | ||
901 | 67 | |||
902 | 68 | EOF | ||
903 | 69 | |||
904 | 70 | } | ||
905 | 71 | |||
906 | 72 | function ls_dir { | ||
907 | 73 | ( cd $1 ; find . -name '*.ibd' -type f | sort -d ) | ||
908 | 74 | } | ||
909 | 75 | |||
910 | 76 | setup_test | ||
911 | 77 | |||
912 | 78 | backup_dir=$topdir/backup_dir | ||
913 | 79 | mkdir -p $backup_dir | ||
914 | 80 | |||
915 | 81 | # invalid characters | ||
916 | 82 | xtrabackup --backup --databases=a/b/c --target-dir=$backup_dir --datadir=$mysql_datadir 2>&1 | grep 'is not valid' | ||
917 | 83 | |||
918 | 84 | # too long name | ||
919 | 85 | xtrabackup --backup --databases=verylonglonglongname111111skjhkdjhfkjdhgkjdfh1555555555555511stillnotlongenoughsowilladdmore1111111111111111111114848484848484fkjhdjfhkdjfhd8484848aaaaaaaaaancnvjvifmifjhfkmfkfnbfifnfkfik4848484841111111prettyenoughnow --target-dir=$backup_dir --datadir=$mysql_datadir 2>&1 | grep 'is too long' | ||
920 | 86 | |||
921 | 87 | # too long name | ||
922 | 88 | xtrabackup --backup --databases=test1.verylonglonglongname111111skjhkdjhfkjdhgkjdfh1555555555555511stillnotlongenoughsowilladdmore1111111111111111111114848484848484fkjhdjfhkdjfhd8484848aaaaaaaaaancnvjvifmifjhfkmfkfnbfifnfkfik4848484841111111prettyenoughnow --target-dir=$backup_dir --datadir=$mysql_datadir 2>&1 | grep 'is too long' | ||
923 | 89 | |||
924 | 90 | # not fully qualified name | ||
925 | 91 | xtrabackup --backup --tables-file=<(echo verylonglonglongname111111skjhkdjhfkjdhgkjdfh1555555555555511stillnotlongenoughsowilladdmore1111111111111111111114848484848484fkjhdjfhkdjfhd8484848aaaaaaaaaancnvjvifmifjhfkmfkfnbfifnfkfik4848484841111111prettyenoughnow) --target-dir=$backup_dir --datadir=$mysql_datadir 2>&1 | grep 'is not fully qualified' | ||
926 | 92 | |||
927 | 93 | # again too long name | ||
928 | 94 | xtrabackup --backup --tables-file=<(echo test1.verylonglonglongname111111skjhkdjhfkjdhgkjdfh1555555555555511stillnotlongenoughsowilladdmore1111111111111111111114848484848484fkjhdjfhkdjfhd8484848aaaaaaaaaancnvjvifmifjhfkmfkfnbfifnfkfik4848484841111111prettyenoughnow) --target-dir=$backup_dir --datadir=$mysql_datadir 2>&1 | grep 'is too long' | ||
929 | 95 | |||
930 | 96 | # should go fine, we cannot validate regex against length | ||
931 | 97 | xtrabackup --backup --tables=verylonglonglongname111111skjhkdjhfkjdhgkjdfh1555555555555511stillnotlongenoughsowilladdmore1111111111111111111114848484848484fkjhdjfhkdjfhd8484848aaaaaaaaaancnvjvifmifjhfkmfkfnbfifnfkfik4848484841111111prettyenoughnow --target-dir=$backup_dir --datadir=$mysql_datadir | ||
932 | 98 | rm -rf $backup_dir/* | ||
933 | 99 | |||
934 | 100 | # should go fine, we cannot validate regex against length | ||
935 | 101 | xtrabackup --backup --tables=test1.verylonglonglongname111111skjhkdjhfkjdhgkjdfh1555555555555511stillnotlongenoughsowilladdmore1111111111111111111114848484848484fkjhdjfhkdjfhd8484848aaaaaaaaaancnvjvifmifjhfkmfkfnbfifnfkfik4848484841111111prettyenoughnow --target-dir=$backup_dir --datadir=$mysql_datadir | ||
936 | 102 | rm -rf $backup_dir/* | ||
937 | 103 | |||
938 | 104 | vlog "Testing with --databases=..." | ||
939 | 105 | $XB_BIN $XB_ARGS --backup --databases='database database2 test1.t test1.ancor thisisadatabase testdatabase.t testdatabase.t7' --target-dir=$backup_dir --datadir=$mysql_datadir | ||
940 | 106 | diff -u <(ls_dir $backup_dir) - <<EOF | ||
941 | 107 | ./database2/ancor.ibd | ||
942 | 108 | ./database2/glow.ibd | ||
943 | 109 | ./database2/t1.ibd | ||
944 | 110 | ./database2/t2.ibd | ||
945 | 111 | ./database2/thisisatable.ibd | ||
946 | 112 | ./database2/t.ibd | ||
947 | 113 | ./test1/ancor.ibd | ||
948 | 114 | ./test1/t.ibd | ||
949 | 115 | ./testdatabase/t.ibd | ||
950 | 116 | ./thisisadatabase/ancor.ibd | ||
951 | 117 | ./thisisadatabase/glow.ibd | ||
952 | 118 | ./thisisadatabase/t1.ibd | ||
953 | 119 | ./thisisadatabase/t2.ibd | ||
954 | 120 | ./thisisadatabase/thisisatable.ibd | ||
955 | 121 | ./thisisadatabase/t.ibd | ||
956 | 122 | EOF | ||
957 | 123 | rm -rf $backup_dir/* | ||
958 | 124 | |||
959 | 125 | vlog "Testing with --databases-file=..." | ||
960 | 126 | cat >$topdir/list <<EOF | ||
961 | 127 | database | ||
962 | 128 | database2 | ||
963 | 129 | test1.t | ||
964 | 130 | test1.ancor | ||
965 | 131 | thisisadatabase | ||
966 | 132 | testdatabase.t | ||
967 | 133 | testdatabase.t7 | ||
968 | 134 | EOF | ||
969 | 135 | xtrabackup --backup --databases-file=$topdir/list --target-dir=$backup_dir --datadir=$mysql_datadir | ||
970 | 136 | diff -u <(ls_dir $backup_dir) - <<EOF | ||
971 | 137 | ./database2/ancor.ibd | ||
972 | 138 | ./database2/glow.ibd | ||
973 | 139 | ./database2/t1.ibd | ||
974 | 140 | ./database2/t2.ibd | ||
975 | 141 | ./database2/thisisatable.ibd | ||
976 | 142 | ./database2/t.ibd | ||
977 | 143 | ./test1/ancor.ibd | ||
978 | 144 | ./test1/t.ibd | ||
979 | 145 | ./testdatabase/t.ibd | ||
980 | 146 | ./thisisadatabase/ancor.ibd | ||
981 | 147 | ./thisisadatabase/glow.ibd | ||
982 | 148 | ./thisisadatabase/t1.ibd | ||
983 | 149 | ./thisisadatabase/t2.ibd | ||
984 | 150 | ./thisisadatabase/thisisatable.ibd | ||
985 | 151 | ./thisisadatabase/t.ibd | ||
986 | 152 | EOF | ||
987 | 153 | rm -rf $backup_dir/* | ||
988 | 154 | |||
989 | 155 | vlog "Testing failure with --tables-file=..." | ||
990 | 156 | cat >$topdir/list <<EOF | ||
991 | 157 | database | ||
992 | 158 | database2 | ||
993 | 159 | test1.t | ||
994 | 160 | test1.ancor | ||
995 | 161 | thisisadatabase | ||
996 | 162 | testdatabase.t | ||
997 | 163 | testdatabase.t7 | ||
998 | 164 | EOF | ||
999 | 165 | run_cmd_expect_failure $XB_BIN $XB_ARGS --backup --tables-file=$topdir/list --target-dir=$backup_dir --datadir=$mysql_datadir | ||
1000 | 166 | diff -u <(ls_dir $backup_dir) - <<EOF | ||
1001 | 167 | EOF | ||
1002 | 168 | rm -rf $backup_dir/* | ||
1003 | 169 | |||
1004 | 170 | vlog "Testing with --tables-file=..." | ||
1005 | 171 | cat >$topdir/list <<EOF | ||
1006 | 172 | test1.t | ||
1007 | 173 | test1.ancor | ||
1008 | 174 | testdatabase.t | ||
1009 | 175 | testdatabase.t7 | ||
1010 | 176 | EOF | ||
1011 | 177 | xtrabackup --backup --tables-file=$topdir/list --target-dir=$backup_dir --datadir=$mysql_datadir | ||
1012 | 178 | diff -u <(ls_dir $backup_dir) - <<EOF | ||
1013 | 179 | ./test1/ancor.ibd | ||
1014 | 180 | ./test1/t.ibd | ||
1015 | 181 | ./testdatabase/t.ibd | ||
1016 | 182 | EOF | ||
1017 | 183 | rm -rf $backup_dir/* | ||
1018 | 184 | |||
1019 | 185 | vlog "Testing with --tables=..." | ||
1020 | 186 | xtrabackup --backup --tables='dat.base,test1.t,test1.a' --target-dir=$backup_dir --datadir=$mysql_datadir | ||
1021 | 187 | diff -u <(ls_dir $backup_dir) - <<EOF | ||
1022 | 188 | ./database1/ancor.ibd | ||
1023 | 189 | ./database1/glow.ibd | ||
1024 | 190 | ./database1/t1.ibd | ||
1025 | 191 | ./database1/t2.ibd | ||
1026 | 192 | ./database1/thisisatable.ibd | ||
1027 | 193 | ./database1/t.ibd | ||
1028 | 194 | ./database2/ancor.ibd | ||
1029 | 195 | ./database2/glow.ibd | ||
1030 | 196 | ./database2/t1.ibd | ||
1031 | 197 | ./database2/t2.ibd | ||
1032 | 198 | ./database2/thisisatable.ibd | ||
1033 | 199 | ./database2/t.ibd | ||
1034 | 200 | ./test1/ancor.ibd | ||
1035 | 201 | ./test1/t1.ibd | ||
1036 | 202 | ./test1/t2.ibd | ||
1037 | 203 | ./test1/thisisatable.ibd | ||
1038 | 204 | ./test1/t.ibd | ||
1039 | 205 | ./testdatabase/ancor.ibd | ||
1040 | 206 | ./testdatabase/glow.ibd | ||
1041 | 207 | ./testdatabase/t1.ibd | ||
1042 | 208 | ./testdatabase/t2.ibd | ||
1043 | 209 | ./testdatabase/thisisatable.ibd | ||
1044 | 210 | ./testdatabase/t.ibd | ||
1045 | 211 | ./thisisadatabase/ancor.ibd | ||
1046 | 212 | ./thisisadatabase/glow.ibd | ||
1047 | 213 | ./thisisadatabase/t1.ibd | ||
1048 | 214 | ./thisisadatabase/t2.ibd | ||
1049 | 215 | ./thisisadatabase/thisisatable.ibd | ||
1050 | 216 | ./thisisadatabase/t.ibd | ||
1051 | 217 | EOF | ||
1052 | 218 | rm -rf $backup_dir/* |
Looking at the diff, changes like these are too invasive for a CS release. Will review & merge only the 2.2 MP.