Merge lp:~sergei.glushchenko/percona-xtrabackup/xb20-databases into lp:percona-xtrabackup/2.0

Proposed by Sergei Glushchenko
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
Reviewer Review Type Date Requested Status
Laurynas Biveinis (community) Needs Fixing
Review via email: mp+143063@code.launchpad.net

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.

To post a comment you must log in.
Revision history for this message
Sergei Glushchenko (sergei.glushchenko) wrote :
Revision history for this message
Sergei Glushchenko (sergei.glushchenko) wrote :

have conflicts. looking

Revision history for this message
Sergei Glushchenko (sergei.glushchenko) wrote :

conflict resolved

Revision history for this message
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_entries_num is required. Its role can
     be handled by tables_hash != NULL check.

   - Likewise for database_hash_entries_num.

   - use my_malloc(.., MYF(MY_FAE)); instead of plain malloc and its
     result check in xb_new_filter_entry(). Then also the return
     value of xb_new_filter_entry() itself needs not to be checked.

   - please assert in xb_new_filter_entry() that the name does not
     violate MySQL name limits: 64 chars for db name, 64 chars for
     table name, and a dot.

   - Line 243: missing || xtrabackup_database_file? Shouldn't this
     have caused a crash for the new ib_databases_file.sh test? I'd
     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_databases
     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."

review: Needs Fixing
Revision history for this message
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_entries_num is required. Its role can
> be handled by tables_hash != NULL check.
>
> - Likewise for database_hash_entries_num.

filters init code has been refactored

> - use my_malloc(.., MYF(MY_FAE)); instead of plain malloc and its
> result check in xb_new_filter_entry(). Then also the return
> value of xb_new_filter_entry() itself needs not to be checked.

ut_malloc has been used.

> - please assert in xb_new_filter_entry() that the name does not
> violate MySQL name limits: 64 chars for db name, 64 chars for
> table name, and a dot.
>
> - Line 243: missing || xtrabackup_database_file? Shouldn't this
> have caused a crash for the new ib_databases_file.sh test? I'd
> 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_databases
> 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

Revision history for this message
Sergei Glushchenko (sergei.glushchenko) wrote :
Revision history for this message
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/sucessful
   - In xb_register_filter_entry(), please move db_entry declaration
     to the block start.
   - Diff line 412: s/etnries/entries
   - Diff line 434: likewise.
   - After the rebase, ib_databases.sh, ib_databases_file.sh will need to adjust to the
     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_options.sh at least some of $XB_BIN $XB_ARGS
     ... can be replaced by xtrabackup ...
   - Does "diff -u <(ls_dir $backup_dir)" fail the test on a diff
     difference found?

review: Needs Fixing
Revision history for this message
Sergei Glushchenko (sergei.glushchenko) wrote :

Laurynas,
Thanks for the review, I'd like to rebase this branch on the latest trunk when https://code.launchpad.net/~sergei.glushchenko/percona-xtrabackup/20-bug856400/+merge/152361 will be approved and merged to avoid conflicts and one more rebasing.

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

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'doc/source/innobackupex/partial_backups_innobackupex.rst'
--- doc/source/innobackupex/partial_backups_innobackupex.rst 2012-09-19 11:35:43 +0000
+++ doc/source/innobackupex/partial_backups_innobackupex.rst 2013-02-25 08:01:21 +0000
@@ -42,7 +42,7 @@
42Using the :option:`--databases` option42Using the :option:`--databases` option
43--------------------------------------43--------------------------------------
4444
45This 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.45This 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.
4646
47For example, ::47For example, ::
4848
@@ -50,9 +50,6 @@
5050
51will 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.51will 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.
5252
53.. note::
54
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.
5653
57Preparing Partial Backups54Preparing Partial Backups
58=========================55=========================
5956
=== modified file 'doc/source/xtrabackup_bin/partial_backups.rst'
--- doc/source/xtrabackup_bin/partial_backups.rst 2011-07-07 05:32:50 +0000
+++ doc/source/xtrabackup_bin/partial_backups.rst 2013-02-25 08:01:21 +0000
@@ -2,7 +2,7 @@
2 Partial Backups2 Partial Backups
3=================3=================
44
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.
66
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.
88
@@ -30,6 +30,11 @@
3030
31|check| errors? outputs?31|check| errors? outputs?
3232
33Using the :option:`--databases` and :option:`--databases-file` options
34======================================================================
35
36The ``--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.
37
33Preparing the Backup38Preparing the Backup
34====================39====================
3540
3641
=== modified file 'doc/source/xtrabackup_bin/xbk_option_reference.rst'
--- doc/source/xtrabackup_bin/xbk_option_reference.rst 2012-05-18 11:19:17 +0000
+++ doc/source/xtrabackup_bin/xbk_option_reference.rst 2013-02-25 08:01:21 +0000
@@ -17,6 +17,14 @@
1717
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.
1919
20.. option:: --databases=#
21
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] . . ."``.
23
24.. option:: --databases-file=#
25
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.
27
20.. option:: --defaults-file=#28.. option:: --defaults-file=#
2129
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.
2331
=== modified file 'innobackupex'
--- innobackupex 2013-01-17 15:08:37 +0000
+++ innobackupex 2013-02-25 08:01:21 +0000
@@ -1067,6 +1067,13 @@
1067 if ($option_stream) {1067 if ($option_stream) {
1068 $options = $options . " --stream=$option_stream";1068 $options = $options . " --stream=$option_stream";
1069 }1069 }
1070 if ($option_databases) {
1071 if ($option_databases =~ /^\//) {
1072 $options = $options . " --databases_file='$option_databases'";
1073 } else {
1074 $options = $options . " --databases='$option_databases'";
1075 }
1076 }
1070 $cmdline = "$option_ibbackup_binary $options";1077 $cmdline = "$option_ibbackup_binary $options";
10711078
1072 # run ibbackup as a child process1079 # run ibbackup as a child process
10731080
=== modified file 'src/xtrabackup.c'
--- src/xtrabackup.c 2013-01-13 22:34:01 +0000
+++ src/xtrabackup.c 2013-02-25 08:01:21 +0000
@@ -87,6 +87,7 @@
87#include <log0recv.h>87#include <log0recv.h>
88#include <fcntl.h>88#include <fcntl.h>
89#include <buf0lru.h>89#include <buf0lru.h>
90#include <string.h>
9091
91#ifdef INNODB_VERSION_SHORT92#ifdef INNODB_VERSION_SHORT
92#include <ibuf0ibuf.h>93#include <ibuf0ibuf.h>
@@ -660,7 +661,7 @@
660661
661#ifdef INNODB_VERSION_SHORT662#ifdef INNODB_VERSION_SHORT
662#define XB_HASH_SEARCH(NAME, TABLE, FOLD, DATA, ASSERTION, TEST) \663#define XB_HASH_SEARCH(NAME, TABLE, FOLD, DATA, ASSERTION, TEST) \
663 HASH_SEARCH(NAME, TABLE, FOLD, xtrabackup_tables_t*, DATA, ASSERTION, \664 HASH_SEARCH(NAME, TABLE, FOLD, xtrabackup_filter_entry_t*, DATA, ASSERTION, \
664 TEST)665 TEST)
665#else666#else
666#define XB_HASH_SEARCH(NAME, TABLE, FOLD, DATA, ASSERTION, TEST) \667#define XB_HASH_SEARCH(NAME, TABLE, FOLD, DATA, ASSERTION, TEST) \
@@ -807,18 +808,30 @@
807char *xtrabackup_incremental_dir = NULL; /* for --prepare */808char *xtrabackup_incremental_dir = NULL; /* for --prepare */
808809
809char *xtrabackup_tables = NULL;810char *xtrabackup_tables = NULL;
810int tables_regex_num;811
811xb_regex_t *tables_regex;812/* List of regular expressions for filtering */
813typedef struct xb_regex_list_node_struct xb_regex_list_node_t;
814struct xb_regex_list_node_struct {
815 UT_LIST_NODE_T(xb_regex_list_node_t) regex_list;
816 xb_regex_t regex;
817};
818UT_LIST_BASE_NODE_T(xb_regex_list_node_t) regex_list;
819
812xb_regmatch_t tables_regmatch[1];820xb_regmatch_t tables_regmatch[1];
813821
814char *xtrabackup_tables_file = NULL;822char *xtrabackup_tables_file = NULL;
815hash_table_t* tables_hash;823hash_table_t* tables_hash = NULL;
816824
817struct xtrabackup_tables_struct{825char *xtrabackup_databases = NULL;
826char *xtrabackup_databases_file = NULL;
827hash_table_t* databases_hash = NULL;
828
829struct xtrabackup_filter_entry_struct{
818 char* name;830 char* name;
831 ibool has_tables_specified;
819 hash_node_t name_hash;832 hash_node_t name_hash;
820};833};
821typedef struct xtrabackup_tables_struct xtrabackup_tables_t;834typedef struct xtrabackup_filter_entry_struct xtrabackup_filter_entry_t;
822835
823#ifdef XTRADB_BASED836#ifdef XTRADB_BASED
824static ulint thread_nr[SRV_MAX_N_IO_THREADS + 6 + 64];837static ulint thread_nr[SRV_MAX_N_IO_THREADS + 6 + 64];
@@ -1059,6 +1072,8 @@
1059 OPT_XTRA_INCREMENTAL_DIR,1072 OPT_XTRA_INCREMENTAL_DIR,
1060 OPT_XTRA_TABLES,1073 OPT_XTRA_TABLES,
1061 OPT_XTRA_TABLES_FILE,1074 OPT_XTRA_TABLES_FILE,
1075 OPT_XTRA_DATABASES,
1076 OPT_XTRA_DATABASES_FILE,
1062 OPT_XTRA_CREATE_IB_LOGFILE,1077 OPT_XTRA_CREATE_IB_LOGFILE,
1063 OPT_XTRA_PARALLEL,1078 OPT_XTRA_PARALLEL,
1064 OPT_XTRA_STREAM,1079 OPT_XTRA_STREAM,
@@ -1174,6 +1189,12 @@
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.",
1175 (G_PTR*) &xtrabackup_tables_file, (G_PTR*) &xtrabackup_tables_file,1190 (G_PTR*) &xtrabackup_tables_file, (G_PTR*) &xtrabackup_tables_file,
1176 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},1191 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1192 {"databases", OPT_XTRA_DATABASES, "filtering by list of databases.",
1193 (G_PTR*) &xtrabackup_databases, (G_PTR*) &xtrabackup_databases,
1194 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1195 {"databases_file", OPT_XTRA_TABLES_FILE, "filtering by list of databases in the file.",
1196 (G_PTR*) &xtrabackup_databases_file, (G_PTR*) &xtrabackup_databases_file,
1197 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
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. ###",
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,
1179 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},1200 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
@@ -2900,7 +2921,9 @@
2900 char *eptr;2921 char *eptr;
2901 int dbname_len;2922 int dbname_len;
29022923
2903 if (xtrabackup_tables == NULL && xtrabackup_tables_file == NULL) {2924 if (UT_LIST_GET_LEN(regex_list) == 0 &&
2925 tables_hash == NULL &&
2926 databases_hash == NULL) {
2904 return(FALSE);2927 return(FALSE);
2905 }2928 }
29062929
@@ -2916,6 +2939,26 @@
2916 }2939 }
29172940
2918 strncpy(buf, dbname, FN_REFLEN);2941 strncpy(buf, dbname, FN_REFLEN);
2942 buf[tbname - 1 - dbname] = 0;
2943
2944 if (databases_hash) {
2945 /* There are some filters for databases, check them */
2946 xtrabackup_filter_entry_t* database;
2947
2948 XB_HASH_SEARCH(name_hash, databases_hash, ut_fold_string(buf),
2949 database, ut_ad(database->name),
2950 !strcmp(database->name, buf));
2951 /* Table's database isn't found, skip the table */
2952 if (!database) {
2953 return(TRUE);
2954 }
2955 /* There aren't tables specified for the database,
2956 it should be backed up entirely */
2957 if (!database->has_tables_specified) {
2958 return(FALSE);
2959 }
2960 }
2961
2919 buf[FN_REFLEN - 1] = 0;2962 buf[FN_REFLEN - 1] = 0;
2920 buf[tbname - 1 - dbname] = '.';2963 buf[tbname - 1 - dbname] = '.';
29212964
@@ -2929,11 +2972,13 @@
2929 *eptr = 0;2972 *eptr = 0;
2930 }2973 }
29312974
2932 if (xtrabackup_tables) {2975 if (UT_LIST_GET_LEN(regex_list)) {
2933 int regres = REG_NOMATCH;2976 /* Check against regular expressions list */
2934 int i;2977 int regres = REG_NOMATCH;
2935 for (i = 0; i < tables_regex_num; i++) {2978 xb_regex_list_node_t* node;
2936 regres = xb_regexec(&tables_regex[i], buf, 1,2979 for (node = UT_LIST_GET_FIRST(regex_list); node;
2980 node = UT_LIST_GET_NEXT(regex_list, node)) {
2981 regres = xb_regexec(&node->regex, buf, 1,
2937 tables_regmatch, 0);2982 tables_regmatch, 0);
2938 if (regres != REG_NOMATCH) {2983 if (regres != REG_NOMATCH) {
2939 break;2984 break;
@@ -2944,8 +2989,9 @@
2944 }2989 }
2945 }2990 }
29462991
2947 if (xtrabackup_tables_file) {2992 if (tables_hash) {
2948 xtrabackup_tables_t* table;2993 /* Finally, check against full qualified tables list */
2994 xtrabackup_filter_entry_t* table;
29492995
2950 XB_HASH_SEARCH(name_hash, tables_hash, ut_fold_string(buf),2996 XB_HASH_SEARCH(name_hash, tables_hash, ut_fold_string(buf),
2951 table, ut_ad(table->name),2997 table, ut_ad(table->name),
@@ -4258,6 +4304,242 @@
4258 return(FALSE);4304 return(FALSE);
4259}4305}
42604306
4307/***********************************************************************
4308Allocate and initialize the entry for databases and tables filtering
4309hash tables. If memory allocation is not successfull, terminate program.
4310@return pointer to the created entry. */
4311static
4312xtrabackup_filter_entry_t *
4313xb_new_filter_entry(
4314/*================*/
4315 const char* name) /*!< in: name of table/database */
4316{
4317 xtrabackup_filter_entry_t *entry;
4318 ulint namelen = strlen(name);
4319
4320 /* Length of name shouldn't be greater than 129 character,
4321 which isn't actually 129 bytes as some of UTF-8 characters
4322 for example can be encoded by 4 bytes. */
4323 ut_a(namelen <= NAME_LEN * 2 + 1);
4324
4325 entry = ut_malloc(sizeof(xtrabackup_filter_entry_t) + namelen + 1);
4326 memset(entry, '\0', sizeof(xtrabackup_filter_entry_t) + namelen + 1);
4327 entry->name = ((char*)entry) + sizeof(xtrabackup_filter_entry_t);
4328 strcpy(entry->name, name);
4329 entry->has_tables_specified = FALSE;
4330
4331 return entry;
4332}
4333
4334/***********************************************************************
4335Free entry filtering hash table entry. */
4336static
4337void
4338xb_free_filter_entry(
4339/*=================*/
4340 xtrabackup_filter_entry_t* entry) /*!< in: entry */
4341{
4342 ut_free(entry);
4343}
4344
4345/***********************************************************************
4346Add entry to hash table. If hash table is NULL, allocate and initialize
4347new hash table */
4348static
4349xtrabackup_filter_entry_t*
4350xb_add_filter_entry_to_hash(
4351/*========================*/
4352 const char* name, /*!< in: name of table/database */
4353 hash_table_t** hash) /*!< in/out: hash to insert into */
4354{
4355 xtrabackup_filter_entry_t* entry;
4356
4357 entry = xb_new_filter_entry(name);
4358
4359 if (UNIV_UNLIKELY(*hash == NULL)) {
4360 *hash = hash_create(1000);
4361 }
4362 HASH_INSERT(xtrabackup_filter_entry_t,
4363 name_hash, *hash,
4364 ut_fold_string(entry->name),
4365 entry);
4366
4367 return entry;
4368}
4369
4370/***********************************************************************
4371Validate name of table or database. If name is invalid, program will
4372be finished with error code */
4373static
4374void
4375xb_validate_name(
4376/*=============*/
4377 const char* name, /*!< in: name */
4378 size_t len) /*!< in: length of name */
4379{
4380 const char* p;
4381
4382 /* perform only basic validation. validate length and
4383 path symbols */
4384 if (len > NAME_LEN) {
4385 msg("xtrabackup: name `%s` is too long.\n", name);
4386 exit(EXIT_FAILURE);
4387 }
4388 p = strpbrk(name, "/\\~");
4389 if (p && p - name < NAME_LEN) {
4390 msg("xtrabackup: name `%s` is not valid.\n", name);
4391 exit(EXIT_FAILURE);
4392 }
4393}
4394
4395/***********************************************************************
4396Register new filter entry which can be either database
4397or table name. */
4398static
4399void
4400xb_register_filter_entry(
4401/*=====================*/
4402 const char* name) /*!< in: name */
4403{
4404 const char* p;
4405 size_t namelen;
4406
4407 namelen = strlen(name);
4408 if ((p = strchr(name, '.')) != NULL) {
4409 char dbname[NAME_LEN + 1];
4410
4411 xb_validate_name(name, p - name);
4412 xb_validate_name(p + 1, namelen - (p - name));
4413
4414 strncpy(dbname, name, p - name);
4415 dbname[p - name] = 0;
4416
4417 xtrabackup_filter_entry_t* db_entry = NULL;
4418
4419 if (databases_hash) {
4420 XB_HASH_SEARCH(name_hash, databases_hash,
4421 ut_fold_string(dbname),
4422 db_entry, ut_ad(db_entry->name),
4423 !strcmp(db_entry->name, dbname));
4424 }
4425 if (!db_entry) {
4426 db_entry = xb_add_filter_entry_to_hash(dbname,
4427 &databases_hash);
4428 }
4429 db_entry->has_tables_specified = TRUE;
4430 xb_add_filter_entry_to_hash(name, &tables_hash);
4431 } else {
4432 xb_validate_name(name, namelen);
4433
4434 xb_add_filter_entry_to_hash(name, &databases_hash);
4435 }
4436}
4437
4438/***********************************************************************
4439Register new table for the filter. */
4440static
4441void
4442xb_register_table(
4443/*==============*/
4444 const char* name) /*!< in: name of table */
4445{
4446 if (strchr(name, '.') == NULL) {
4447 msg("xtrabackup: `%s` is not fully qualified name.\n", name);
4448 exit(EXIT_FAILURE);
4449 }
4450
4451 xb_register_filter_entry(name);
4452}
4453
4454/***********************************************************************
4455Register new regex for the filter. */
4456static
4457void
4458xb_register_regex(
4459/*==============*/
4460 const char* regex) /*!< in: regex */
4461{
4462 xb_regex_list_node_t* node;
4463 char errbuf[100];
4464 int ret;
4465
4466 node = ut_malloc(sizeof(xb_regex_list_node_t));
4467
4468 ret = xb_regcomp(&node->regex, regex, REG_EXTENDED);
4469 if (ret != 0) {
4470 xb_regerror(ret, &node->regex, errbuf, sizeof(errbuf));
4471 msg("xtrabackup: error: tables regcomp(%s): %s\n", regex, errbuf);
4472 exit(EXIT_FAILURE);
4473 }
4474
4475 UT_LIST_ADD_LAST(regex_list, regex_list, node);
4476}
4477
4478typedef void (*insert_entry_func_t)(const char*);
4479
4480/***********************************************************************
4481Scan string and load filter etnries from it. */
4482static
4483void
4484xb_load_list_string(
4485/*================*/
4486 const char* list, /*!< in: string representing a list */
4487 const char* delimiters, /*!< in: delimiters of entries */
4488 insert_entry_func_t ins) /*!< in: callback to add entry */
4489{
4490 char* p;
4491 char* saveptr;
4492
4493 p = strtok_r(list, delimiters, &saveptr);
4494 while (p) {
4495
4496 ins(p);
4497
4498 p = strtok_r(NULL, delimiters, &saveptr);
4499 }
4500}
4501
4502/***********************************************************************
4503Scan file and load filter etnries from it. */
4504static
4505void
4506xb_load_list_file(
4507/*==============*/
4508 const char* filename, /*!< in: name of file */
4509 insert_entry_func_t ins) /*!< in: callback to add entry */
4510{
4511 char name_buf[NAME_LEN*2+2];
4512 FILE *fp;
4513
4514 /* read and store the filenames */
4515 fp = fopen(filename, "r");
4516 if (!fp) {
4517 msg("xtrabackup: cannot open %s\n",
4518 filename);
4519 exit(EXIT_FAILURE);
4520 }
4521 for (;;) {
4522 char* p = name_buf;
4523
4524 if (fgets(name_buf, sizeof(name_buf), fp) == 0) {
4525 break;
4526 }
4527
4528 p = strchr(name_buf, '\n');
4529 if (p) {
4530 *p = '\0';
4531 } else {
4532 msg("xtrabackup: `%s...` name is too long", name_buf);
4533 exit(EXIT_FAILURE);
4534 }
4535
4536 ins(name_buf);
4537 }
4538
4539 fclose(fp);
4540}
4541
4542
4261/************************************************************************4543/************************************************************************
4262Inittialize table filters for partial backup. */4544Inittialize table filters for partial backup. */
4263static4545static
@@ -4265,86 +4547,55 @@
4265xb_filters_init()4547xb_filters_init()
4266/*=============*/4548/*=============*/
4267{4549{
4550 UT_LIST_INIT(regex_list);
4551
4552 if (xtrabackup_databases) {
4553 xb_load_list_string(xtrabackup_databases, " \t",
4554 xb_register_filter_entry);
4555 }
4556 if (xtrabackup_databases_file) {
4557 xb_load_list_file(xtrabackup_databases_file,
4558 xb_register_filter_entry);
4559 }
4268 if (xtrabackup_tables) {4560 if (xtrabackup_tables) {
4269 /* init regexp */4561 xb_load_list_string(xtrabackup_tables, ",",
4270 char *p, *next;4562 xb_register_regex);
4271 int i;
4272 char errbuf[100];
4273
4274 tables_regex_num = 1;
4275
4276 p = xtrabackup_tables;
4277 while ((p = strchr(p, ',')) != NULL) {
4278 p++;
4279 tables_regex_num++;
4280 }
4281
4282 tables_regex = ut_malloc(sizeof(xb_regex_t) * tables_regex_num);
4283
4284 p = xtrabackup_tables;
4285 for (i=0; i < tables_regex_num; i++) {
4286 next = strchr(p, ',');
4287 ut_a(next || i == tables_regex_num - 1);
4288
4289 next++;
4290 if (i != tables_regex_num - 1)
4291 *(next - 1) = '\0';
4292
4293 xb_regerror(xb_regcomp(&tables_regex[i], p,
4294 REG_EXTENDED),
4295 &tables_regex[i], errbuf, sizeof(errbuf));
4296 msg("xtrabackup: tables regcomp(%s): %s\n", p, errbuf);
4297
4298 if (i != tables_regex_num - 1)
4299 *(next - 1) = ',';
4300 p = next;
4301 }
4302 }4563 }
4303
4304 if (xtrabackup_tables_file) {4564 if (xtrabackup_tables_file) {
4305 char name_buf[NAME_LEN*2+2];4565 xb_load_list_file(xtrabackup_tables_file, xb_register_table);
4306 FILE *fp;4566 }
43074567}
4308 name_buf[NAME_LEN*2+1] = '\0';4568
43094569
4310 /* init tables_hash */4570/************************************************************************
4311 tables_hash = hash_create(1000);4571Release all the hash entries and hash itself. */
43124572static
4313 /* read and store the filenames */4573void
4314 fp = fopen(xtrabackup_tables_file,"r");4574xb_filter_hash_clear(
4315 if (!fp) {4575 hash_table_t* hash)
4316 msg("xtrabackup: cannot open %s\n",4576{
4317 xtrabackup_tables_file);4577 ulint i;
4318 exit(EXIT_FAILURE);4578
4319 }4579 /* free the hash elements */
4320 for (;;) {4580 for (i = 0; i < hash_get_n_cells(hash); i++) {
4321 xtrabackup_tables_t* table;4581 xtrabackup_filter_entry_t* table;
4322 char* p = name_buf;4582
43234583 table = HASH_GET_FIRST(hash, i);
4324 if ( fgets(name_buf, NAME_LEN*2+1, fp) == 0 ) {4584
4325 break;4585 while (table) {
4326 }4586 xtrabackup_filter_entry_t* prev_table = table;
43274587
4328 p = strchr(name_buf, '\n');4588 table = HASH_GET_NEXT(name_hash, prev_table);
4329 if (p)4589
4330 {4590 HASH_DELETE(xtrabackup_filter_entry_t, name_hash, hash,
4331 *p = '\0';4591 ut_fold_string(prev_table->name), prev_table);
4332 }4592 free(prev_table);
43334593 }
4334 table = malloc(sizeof(xtrabackup_tables_t) + strlen(name_buf) + 1);4594 }
4335 memset(table, '\0', sizeof(xtrabackup_tables_t) + strlen(name_buf) + 1);4595
4336 table->name = ((char*)table) + sizeof(xtrabackup_tables_t);4596 /* free hash */
4337 strcpy(table->name, name_buf);4597 hash_table_free(hash);
43384598}
4339 HASH_INSERT(xtrabackup_tables_t, name_hash, tables_hash,
4340 ut_fold_string(table->name), table);
4341
4342 msg("xtrabackup: table '%s' is registered to the "
4343 "list.\n", table->name);
4344 }
4345 }
4346}
4347
43484599
4349/************************************************************************4600/************************************************************************
4350Destroy table filters for partial backup. */4601Destroy table filters for partial backup. */
@@ -4353,29 +4604,19 @@
4353xb_filters_free()4604xb_filters_free()
4354/*=============*/4605/*=============*/
4355{4606{
43564607 while (UT_LIST_GET_LEN(regex_list) > 0) {
4357 if (xtrabackup_tables_file) {4608 xb_regex_list_node_t* node = UT_LIST_GET_FIRST(regex_list);
4358 ulint i;4609 UT_LIST_REMOVE(regex_list, regex_list, node);
43594610 xb_regfree(&node->regex);
4360 /* free the hash elements */4611 ut_free(node);
4361 for (i = 0; i < hash_get_n_cells(tables_hash); i++) {4612 }
4362 xtrabackup_tables_t* table;4613
43634614 if (tables_hash) {
4364 table = HASH_GET_FIRST(tables_hash, i);4615 xb_filter_hash_clear(tables_hash);
43654616 }
4366 while (table) {4617
4367 xtrabackup_tables_t* prev_table = table;4618 if (databases_hash) {
43684619 xb_filter_hash_clear(databases_hash);
4369 table = HASH_GET_NEXT(name_hash, prev_table);
4370
4371 HASH_DELETE(xtrabackup_tables_t, name_hash, tables_hash,
4372 ut_fold_string(prev_table->name), prev_table);
4373 free(prev_table);
4374 }
4375 }
4376
4377 /* free tables_hash */
4378 hash_table_free(tables_hash);
4379 }4620 }
43804621
4381}4622}
@@ -7206,16 +7447,6 @@
7206 if (xtrabackup_prepare)7447 if (xtrabackup_prepare)
7207 xtrabackup_prepare_func();7448 xtrabackup_prepare_func();
72087449
7209 if (xtrabackup_tables) {
7210 /* free regexp */
7211 int i;
7212
7213 for (i = 0; i < tables_regex_num; i++) {
7214 xb_regfree(&tables_regex[i]);
7215 }
7216 ut_free(tables_regex);
7217 }
7218
7219 xb_regex_end();7450 xb_regex_end();
72207451
7221 exit(EXIT_SUCCESS);7452 exit(EXIT_SUCCESS);
72227453
=== added file 'test/t/ib_databases.sh'
--- test/t/ib_databases.sh 1970-01-01 00:00:00 +0000
+++ test/t/ib_databases.sh 2013-02-25 08:01:21 +0000
@@ -0,0 +1,50 @@
1########################################################################
2# Bug #569387: innobackupex ignores --databases
3# Testcase covers using --databases option with InnoDB
4# database (list is specified in option itself)
5########################################################################
6
7. inc/common.sh
8
9start_server --innodb-file-per-table
10
11cat <<EOF | run_cmd $MYSQL $MYSQL_ARGS
12
13 CREATE DATABASE test1;
14
15 CREATE TABLE test1.a (a INT PRIMARY KEY);
16 CREATE TABLE test1.b (b INT PRIMARY KEY);
17 CREATE TABLE test1.c (c INT PRIMARY KEY);
18
19 CREATE TABLE test.a (a INT PRIMARY KEY);
20 CREATE TABLE test.b (b INT PRIMARY KEY);
21 CREATE TABLE test.c (c INT PRIMARY KEY);
22
23EOF
24
25# This is a workaround to pass --databases='test test1.b test1.c'
26$IB_BIN $IB_ARGS --no-timestamp --databases='test test1.b test1.c' $topdir/backup
27innobackupex --apply-log $topdir/backup
28vlog "Backup taken"
29
30stop_server
31
32# Restore partial backup
33# Remove database
34rm -rf $mysql_datadir/test/*
35rm -rf $mysql_datadir/test1/*
36vlog "Original database removed"
37
38# Restore database from backup
39cp -rv $topdir/backup/test/* $mysql_datadir/test
40cp -rv $topdir/backup/test1/* $mysql_datadir/test1
41vlog "database restored from backup"
42
43start_server
44
45OUT=`run_cmd $MYSQL $MYSQL_ARGS -e "USE test; SHOW TABLES; USE test1; SHOW TABLES;" | tr -d '\n'`
46
47if [ $OUT != "Tables_in_testabcTables_in_test1bc" ] ; then
48 vlog "Backed up tables set doesn't match filter" ;
49 exit 1;
50fi
051
=== added file 'test/t/ib_databases_file.sh'
--- test/t/ib_databases_file.sh 1970-01-01 00:00:00 +0000
+++ test/t/ib_databases_file.sh 2013-02-25 08:01:21 +0000
@@ -0,0 +1,57 @@
1########################################################################
2# Bug #569387: innobackupex ignores --databases
3# Testcase covers using --databases option with InnoDB
4# database (list is specified in file which option
5# points to)
6########################################################################
7
8. inc/common.sh
9
10start_server --innodb-file-per-table
11
12cat <<EOF | run_cmd $MYSQL $MYSQL_ARGS
13
14 CREATE DATABASE test1;
15
16 CREATE TABLE test1.a (a INT PRIMARY KEY) engine=InnoDB;
17 CREATE TABLE test1.b (b INT PRIMARY KEY) engine=InnoDB;
18 CREATE TABLE test1.c (c INT PRIMARY KEY) engine=InnoDB;
19
20 CREATE TABLE test.a (a INT PRIMARY KEY) engine=InnoDB;
21 CREATE TABLE test.b (b INT PRIMARY KEY) engine=InnoDB;
22 CREATE TABLE test.c (c INT PRIMARY KEY) engine=InnoDB;
23
24EOF
25
26# Take a backup
27# Backup the whole test and b,c from test1
28cat >$topdir/databases_file <<EOF
29test
30test1.b
31test1.c
32EOF
33innobackupex --no-timestamp --databases=$topdir/databases_file $topdir/backup
34innobackupex --apply-log $topdir/backup
35vlog "Backup taken"
36
37stop_server
38
39# Restore partial backup
40# Remove database
41rm -rf $mysql_datadir/test/*
42rm -rf $mysql_datadir/test1/*
43vlog "Original database removed"
44
45# Restore database from backup
46cp -rv $topdir/backup/test/* $mysql_datadir/test
47cp -rv $topdir/backup/test1/* $mysql_datadir/test1
48vlog "database restored from backup"
49
50start_server
51
52OUT=`run_cmd $MYSQL $MYSQL_ARGS -e "USE test; SHOW TABLES; USE test1; SHOW TABLES;" | tr -d '\n'`
53
54if [ $OUT != "Tables_in_testabcTables_in_test1bc" ] ; then
55 vlog "Backed up tables set don't match filter" ;
56 exit 1;
57fi
058
=== added file 'test/t/xb_databases_options.sh'
--- test/t/xb_databases_options.sh 1970-01-01 00:00:00 +0000
+++ test/t/xb_databases_options.sh 2013-02-25 08:01:21 +0000
@@ -0,0 +1,221 @@
1########################################################################
2# Bug #569387: xtrabackup ignores --databases, i.e. when --databases
3#
4# Test following xtrabackup options
5# --databases
6# --databases-file
7# --tables
8# --tables-file
9########################################################################
10
11. inc/common.sh
12
13start_server --innodb-file-per-table
14
15function setup_test {
16
17 cat <<EOF | run_cmd $MYSQL $MYSQL_ARGS
18
19 create database database1;
20 create database database2;
21 create database test1;
22 create database test2;
23 create database thisisadatabase;
24 create database testdatabase;
25
26 create table database1.thisisatable (a int primary key) engine=InnoDB;
27 create table database1.t (a int primary key) engine=InnoDB;
28 create table database1.t1 (a int primary key) engine=InnoDB;
29 create table database1.t2 (a int primary key) engine=InnoDB;
30 create table database1.ancor (a int primary key) engine=InnoDB;
31 create table database1.glow (a int primary key) engine=InnoDB;
32
33 create table database2.thisisatable (a int primary key) engine=InnoDB;
34 create table database2.t (a int primary key) engine=InnoDB;
35 create table database2.t1 (a int primary key) engine=InnoDB;
36 create table database2.t2 (a int primary key) engine=InnoDB;
37 create table database2.ancor (a int primary key) engine=InnoDB;
38 create table database2.glow (a int primary key) engine=InnoDB;
39
40 create table test1.thisisatable (a int primary key) engine=InnoDB;
41 create table test1.t (a int primary key) engine=InnoDB;
42 create table test1.t1 (a int primary key) engine=InnoDB;
43 create table test1.t2 (a int primary key) engine=InnoDB;
44 create table test1.ancor (a int primary key) engine=InnoDB;
45 create table test1.glow (a int primary key) engine=InnoDB;
46
47 create table test2.thisisatable (a int primary key) engine=InnoDB;
48 create table test2.t (a int primary key) engine=InnoDB;
49 create table test2.t1 (a int primary key) engine=InnoDB;
50 create table test2.t2 (a int primary key) engine=InnoDB;
51 create table test2.ancor (a int primary key) engine=InnoDB;
52 create table test2.glow (a int primary key) engine=InnoDB;
53
54 create table thisisadatabase.thisisatable (a int primary key) engine=InnoDB;
55 create table thisisadatabase.t (a int primary key) engine=InnoDB;
56 create table thisisadatabase.t1 (a int primary key) engine=InnoDB;
57 create table thisisadatabase.t2 (a int primary key) engine=InnoDB;
58 create table thisisadatabase.ancor (a int primary key) engine=InnoDB;
59 create table thisisadatabase.glow (a int primary key) engine=InnoDB;
60
61 create table testdatabase.thisisatable (a int primary key) engine=InnoDB;
62 create table testdatabase.t (a int primary key) engine=InnoDB;
63 create table testdatabase.t1 (a int primary key) engine=InnoDB;
64 create table testdatabase.t2 (a int primary key) engine=InnoDB;
65 create table testdatabase.ancor (a int primary key) engine=InnoDB;
66 create table testdatabase.glow (a int primary key) engine=InnoDB;
67
68EOF
69
70}
71
72function ls_dir {
73 d=`pwd`
74 cd $1
75 find . -name '*.ibd' | sort
76 cd $d
77}
78
79setup_test
80
81backup_dir=$topdir/backup_dir
82mkdir -p $backup_dir
83
84# invalid characters
85$XB_BIN $XB_ARGS --backup --databases=a/b/c --target-dir=$backup_dir --datadir=$mysql_datadir 2>&1 | grep 'is not valid'
86
87# too long name
88$XB_BIN $XB_ARGS --backup --databases=verylonglonglongname111111skjhkdjhfkjdhgkjdfh1555555555555511stillnotlongenoughsowilladdmore1111111111111111111114848484848484fkjhdjfhkdjfhd8484848aaaaaaaaaancnvjvifmifjhfkmfkfnbfifnfkfik4848484841111111prettyenoughnow --target-dir=$backup_dir --datadir=$mysql_datadir 2>&1 | grep 'is too long'
89
90# too long name
91$XB_BIN $XB_ARGS --backup --databases=test1.verylonglonglongname111111skjhkdjhfkjdhgkjdfh1555555555555511stillnotlongenoughsowilladdmore1111111111111111111114848484848484fkjhdjfhkdjfhd8484848aaaaaaaaaancnvjvifmifjhfkmfkfnbfifnfkfik4848484841111111prettyenoughnow --target-dir=$backup_dir --datadir=$mysql_datadir 2>&1 | grep 'is too long'
92
93# not fully qualified name
94$XB_BIN $XB_ARGS --backup --tables-file=<(echo verylonglonglongname111111skjhkdjhfkjdhgkjdfh1555555555555511stillnotlongenoughsowilladdmore1111111111111111111114848484848484fkjhdjfhkdjfhd8484848aaaaaaaaaancnvjvifmifjhfkmfkfnbfifnfkfik4848484841111111prettyenoughnow) --target-dir=$backup_dir --datadir=$mysql_datadir 2>&1 | grep 'is not fully qualified'
95
96# again too long name
97$XB_BIN $XB_ARGS --backup --tables-file=<(echo test1.verylonglonglongname111111skjhkdjhfkjdhgkjdfh1555555555555511stillnotlongenoughsowilladdmore1111111111111111111114848484848484fkjhdjfhkdjfhd8484848aaaaaaaaaancnvjvifmifjhfkmfkfnbfifnfkfik4848484841111111prettyenoughnow) --target-dir=$backup_dir --datadir=$mysql_datadir 2>&1 | grep 'is too long'
98
99# should go fine, we cannot validate regex against length
100$XB_BIN $XB_ARGS --backup --tables=verylonglonglongname111111skjhkdjhfkjdhgkjdfh1555555555555511stillnotlongenoughsowilladdmore1111111111111111111114848484848484fkjhdjfhkdjfhd8484848aaaaaaaaaancnvjvifmifjhfkmfkfnbfifnfkfik4848484841111111prettyenoughnow --target-dir=$backup_dir --datadir=$mysql_datadir
101rm -rf $backup_dir/*
102
103# should go fine, we cannot validate regex against length
104$XB_BIN $XB_ARGS --backup --tables=test1.verylonglonglongname111111skjhkdjhfkjdhgkjdfh1555555555555511stillnotlongenoughsowilladdmore1111111111111111111114848484848484fkjhdjfhkdjfhd8484848aaaaaaaaaancnvjvifmifjhfkmfkfnbfifnfkfik4848484841111111prettyenoughnow --target-dir=$backup_dir --datadir=$mysql_datadir
105rm -rf $backup_dir/*
106
107vlog "Testing with --databases=..."
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
109diff -u <(ls_dir $backup_dir) - <<EOF
110./database2/ancor.ibd
111./database2/glow.ibd
112./database2/t.ibd
113./database2/t1.ibd
114./database2/t2.ibd
115./database2/thisisatable.ibd
116./test1/ancor.ibd
117./test1/t.ibd
118./testdatabase/t.ibd
119./thisisadatabase/ancor.ibd
120./thisisadatabase/glow.ibd
121./thisisadatabase/t.ibd
122./thisisadatabase/t1.ibd
123./thisisadatabase/t2.ibd
124./thisisadatabase/thisisatable.ibd
125EOF
126rm -rf $backup_dir/*
127
128vlog "Testing with --databases-file=..."
129cat >$topdir/list <<EOF
130database
131database2
132test1.t
133test1.ancor
134thisisadatabase
135testdatabase.t
136testdatabase.t7
137EOF
138$XB_BIN $XB_ARGS --backup --databases-file=$topdir/list --target-dir=$backup_dir --datadir=$mysql_datadir
139diff -u <(ls_dir $backup_dir) - <<EOF
140./database2/ancor.ibd
141./database2/glow.ibd
142./database2/t.ibd
143./database2/t1.ibd
144./database2/t2.ibd
145./database2/thisisatable.ibd
146./test1/ancor.ibd
147./test1/t.ibd
148./testdatabase/t.ibd
149./thisisadatabase/ancor.ibd
150./thisisadatabase/glow.ibd
151./thisisadatabase/t.ibd
152./thisisadatabase/t1.ibd
153./thisisadatabase/t2.ibd
154./thisisadatabase/thisisatable.ibd
155EOF
156rm -rf $backup_dir/*
157
158vlog "Testing failure with --tables-file=..."
159cat >$topdir/list <<EOF
160database
161database2
162test1.t
163test1.ancor
164thisisadatabase
165testdatabase.t
166testdatabase.t7
167EOF
168run_cmd_expect_failure $XB_BIN $XB_ARGS --backup --tables-file=$topdir/list --target-dir=$backup_dir --datadir=$mysql_datadir
169diff -u <(ls_dir $backup_dir) - <<EOF
170EOF
171rm -rf $backup_dir/*
172
173vlog "Testing with --tables-file=..."
174cat >$topdir/list <<EOF
175test1.t
176test1.ancor
177testdatabase.t
178testdatabase.t7
179EOF
180run_cmd $XB_BIN $XB_ARGS --backup --tables-file=$topdir/list --target-dir=$backup_dir --datadir=$mysql_datadir
181diff -u <(ls_dir $backup_dir) - <<EOF
182./test1/ancor.ibd
183./test1/t.ibd
184./testdatabase/t.ibd
185EOF
186rm -rf $backup_dir/*
187
188vlog "Testing with --tables=..."
189$XB_BIN $XB_ARGS --backup --tables='dat.base,test1.t,test1.a' --target-dir=$backup_dir --datadir=$mysql_datadir
190diff -u <(ls_dir $backup_dir) - <<EOF
191./database1/ancor.ibd
192./database1/glow.ibd
193./database1/t.ibd
194./database1/t1.ibd
195./database1/t2.ibd
196./database1/thisisatable.ibd
197./database2/ancor.ibd
198./database2/glow.ibd
199./database2/t.ibd
200./database2/t1.ibd
201./database2/t2.ibd
202./database2/thisisatable.ibd
203./test1/ancor.ibd
204./test1/t.ibd
205./test1/t1.ibd
206./test1/t2.ibd
207./test1/thisisatable.ibd
208./testdatabase/ancor.ibd
209./testdatabase/glow.ibd
210./testdatabase/t.ibd
211./testdatabase/t1.ibd
212./testdatabase/t2.ibd
213./testdatabase/thisisatable.ibd
214./thisisadatabase/ancor.ibd
215./thisisadatabase/glow.ibd
216./thisisadatabase/t.ibd
217./thisisadatabase/t1.ibd
218./thisisadatabase/t2.ibd
219./thisisadatabase/thisisatable.ibd
220EOF
221rm -rf $backup_dir/*

Subscribers

People subscribed via source and target branches