~percona-core/percona-xtrabackup/2.0

« back to all changes in this revision

Viewing changes to src/xtrabackup.cc

  • Committer: Alexey Kopytov
  • Date: 2013-04-28 05:28:35 UTC
  • mfrom: (533.1.2 2.0)
  • Revision ID: akopytov@gmail.com-20130428052835-aadtc5yxcbadcmbj
Manual merge of lp:~akopytov/percona-xtrabackup/support-remote-tablespaces-2.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
286
286
 
287
287
#ifdef __WIN__
288
288
#define SRV_PATH_SEPARATOR      '\\'
289
 
#define SRV_PATH_SEPARATOR_STR  "\\"    
290
289
#else
291
290
#define SRV_PATH_SEPARATOR      '/'
292
 
#define SRV_PATH_SEPARATOR_STR  "/"
293
291
#endif
294
292
 
295
293
#ifndef UNIV_PAGE_SIZE_MAX
3118
3116
                        char *p;
3119
3117
 
3120
3118
                        p = srv_data_file_names[i];
3121
 
                        while ((p = strstr(p, SRV_PATH_SEPARATOR_STR)) != NULL)
 
3119
                        while ((p = strchr(p, SRV_PATH_SEPARATOR)) != NULL)
3122
3120
                        {
3123
3121
                                p++;
3124
3122
                                srv_data_file_names[i] = p;
3654
3652
}
3655
3653
 
3656
3654
/************************************************************************
3657
 
Checks if a table specified as a path should be skipped from backup
3658
 
based on the --tables or --tables-file options.
 
3655
Checks if a table specified as a name in the form "database/name" (InnoDB 5.6)
 
3656
or "./database/name.ibd" (InnoDB 5.5-) should be skipped from backup based on
 
3657
the --tables or --tables-file options.
3659
3658
 
3660
3659
@return TRUE if the table should be skipped. */
3661
3660
static my_bool
3662
 
check_if_skip_table(const char *path, const char *suffix)
 
3661
check_if_skip_table(const char *name)
3663
3662
{
3664
3663
        char buf[FN_REFLEN];
3665
3664
        const char *dbname, *tbname;
3666
3665
        const char *ptr;
3667
3666
        char *eptr;
3668
 
        int dbname_len;
3669
3667
 
3670
3668
        if (xtrabackup_tables == NULL && xtrabackup_tables_file == NULL) {
3671
3669
                return(FALSE);
3672
3670
        }
3673
3671
 
3674
3672
        dbname = NULL;
3675
 
        tbname = path;
3676
 
        while ((ptr = strstr(tbname, SRV_PATH_SEPARATOR_STR)) != NULL) {
 
3673
        tbname = name;
 
3674
        while ((ptr = strchr(tbname, SRV_PATH_SEPARATOR)) != NULL) {
3677
3675
                dbname = tbname;
3678
3676
                tbname = ptr + 1;
3679
3677
        }
3683
3681
        }
3684
3682
 
3685
3683
        strncpy(buf, dbname, FN_REFLEN);
3686
 
        buf[FN_REFLEN - 1] = 0;
 
3684
        buf[FN_REFLEN - 1] = '\0';
3687
3685
        buf[tbname - 1 - dbname] = '.';
3688
3686
 
3689
 
        dbname_len = strlen(dbname) - strlen(suffix);
3690
 
        if (dbname_len < 1) {
3691
 
                return(FALSE);
 
3687
        /* Check if there's a suffix in the table name. If so, truncate it. We
 
3688
        rely on the fact that a dot cannot be a part of a table name (it is
 
3689
        encoded by the server with the @NNNN syntax). */
 
3690
        if ((eptr = strchr(&buf[tbname - dbname], '.')) != NULL) {
 
3691
 
 
3692
                *eptr = '\0';
3692
3693
        }
3693
 
        buf[dbname_len - 1] = 0;
3694
3694
 
3695
3695
        /* For partitioned tables first try to match against the regexp
3696
3696
        without truncating the #P#... suffix so we can backup individual
3965
3965
}
3966
3966
#endif
3967
3967
 
 
3968
/***********************************************************************
 
3969
Extracts the relative path ("database/table.ibd") of a tablespace from a
 
3970
specified possibly absolute path.
 
3971
 
 
3972
For user tablespaces both "./database/table.ibd" and
 
3973
"/remote/dir/database/table.ibd" result in "database/table.ibd".
 
3974
 
 
3975
For system tablepsaces (i.e. When is_system is TRUE) both "/remote/dir/ibdata1"
 
3976
and "./ibdata1" yield "ibdata1" in the output. */
 
3977
static
 
3978
const char *
 
3979
xb_get_relative_path(
 
3980
/*=================*/
 
3981
        const char*     path,           /*!< in: tablespace path (either
 
3982
                                        relative or absolute) */
 
3983
        ibool           is_system)      /*!< in: TRUE for system tablespaces,
 
3984
                                        i.e. when only the filename must be
 
3985
                                        returned. */
 
3986
{
 
3987
        const char *next;
 
3988
        const char *cur;
 
3989
        const char *prev;
 
3990
 
 
3991
        prev = NULL;
 
3992
        cur = path;
 
3993
 
 
3994
        while ((next = strchr(cur, SRV_PATH_SEPARATOR)) != NULL) {
 
3995
 
 
3996
                prev = cur;
 
3997
                cur = next + 1;
 
3998
        }
 
3999
 
 
4000
        if (is_system) {
 
4001
 
 
4002
                return(cur);
 
4003
        } else {
 
4004
 
 
4005
                return((prev == NULL) ? cur : prev);
 
4006
        }
 
4007
 
 
4008
}
 
4009
 
3968
4010
/* TODO: We may tune the behavior (e.g. by fil_aio)*/
3969
4011
#define COPY_CHUNK 64
3970
4012
 
3990
4032
        xb_delta_info_t info;
3991
4033
        datasink_t      *ds = ds_ctxt->datasink;
3992
4034
        ds_file_t       *dstfile = NULL;
 
4035
        ibool           is_system;
 
4036
 
 
4037
        /* Get the name and the path for the tablespace. node->name always
 
4038
        contains the path (which may be absolute for remote tablespaces in
 
4039
        5.6+). space->name contains the tablespace name in the form
 
4040
        "./database/table.ibd" (in 5.5-) or "database/table" (in 5.6+). For a
 
4041
        multi-node shared tablespace, space->name contains the name of the first
 
4042
        node, but that's irrelevant, since we only need node_name to match them
 
4043
        against filters, and the shared tablespace is always copied regardless
 
4044
        of the filters value. */
 
4045
 
 
4046
        const char* const node_name = node->space->name;
 
4047
        const char* const node_path = node->name;
3993
4048
 
3994
4049
        info.page_size = 0;
3995
4050
        info.zip_size = 0;
3996
4051
        info.space_id = 0;
3997
4052
 
3998
 
        if ((!trx_sys_sys_space(node->space->id))
3999
 
                && check_if_skip_table(node->name, "ibd")) {
4000
 
                msg("[%02u] Skipping %s.\n", thread_n, node->name);
 
4053
        is_system = trx_sys_sys_space(node->space->id);
 
4054
 
 
4055
        if (!is_system && check_if_skip_table(node_name)) {
 
4056
                msg("[%02u] Skipping %s.\n", thread_n, node_name);
4001
4057
                return(FALSE);
4002
4058
        }
4003
4059
 
4004
 
        if (trx_sys_sys_space(node->space->id))
4005
 
        {
4006
 
                char *next, *p;
4007
 
                /* system datafile "/fullpath/datafilename.ibd" or "./datafilename.ibd" */
4008
 
                p = node->name;
4009
 
                while ((next = strstr(p, SRV_PATH_SEPARATOR_STR)) != NULL)
4010
 
                {
4011
 
                        p = next + 1;
4012
 
                }
4013
 
                strncpy(dst_name, p, sizeof(dst_name));
4014
 
        } else {
4015
 
                /* file per table style "./database/table.ibd" */
4016
 
                strncpy(dst_name, node->name, sizeof(dst_name));
4017
 
        }
 
4060
        /* Get the relative path for the destination tablespace name. Non-system
 
4061
        tablespaces may have absolute paths for remote tablespaces in MySQL
 
4062
        5.6+. We want to make "local" copies for the backup. We don't use
 
4063
        node_name here, because in MySQL 5.6+ it doesn't contain the .ibd
 
4064
        suffix */
 
4065
        strncpy(dst_name, xb_get_relative_path(node_path, is_system),
 
4066
                sizeof(dst_name));
4018
4067
 
4019
4068
        /* open src_file*/
4020
 
        src_file = xb_file_create_no_error_handling(node->name,
 
4069
        src_file = xb_file_create_no_error_handling(node_path,
4021
4070
                                                    OS_FILE_OPEN,
4022
4071
                                                    OS_FILE_READ_ONLY,
4023
4072
                                                    &success);
4029
4078
                    "[%02u] xtrabackup: Warning: We assume the "
4030
4079
                    "table was dropped or renamed during "
4031
4080
                    "xtrabackup execution and ignore the file.\n",
4032
 
                    thread_n, node->name, thread_n);
 
4081
                    thread_n, node_path, thread_n);
4033
4082
                goto skip;
4034
4083
        }
4035
4084
 
4036
 
        xb_file_set_nocache(src_file, node->name, "OPEN");
 
4085
        xb_file_set_nocache(src_file, node_path, "OPEN");
4037
4086
 
4038
4087
#ifdef USE_POSIX_FADVISE
4039
4088
        posix_fadvise(src_file, 0, 0, POSIX_FADV_SEQUENTIAL);
4050
4099
                page_size = info.zip_size;
4051
4100
                page_size_shift = get_bit_shift(page_size);
4052
4101
                msg("[%02u] %s is compressed with page size = "
4053
 
                    "%lu bytes\n", thread_n, node->name, page_size);
 
4102
                    "%lu bytes\n", thread_n, node_name, page_size);
4054
4103
                if (page_size_shift < 10 || page_size_shift > 14) {
4055
4104
                        msg("[%02u] xtrabackup: Error: Invalid "
4056
4105
                            "page size: %lu.\n", thread_n, page_size);
4087
4136
        } else
4088
4137
                info.page_size = 0;
4089
4138
 
4090
 
        if (my_stat(node->name, &src_stat, MYF(MY_WME)) == NULL) {
 
4139
        if (my_stat(node_path, &src_stat, MYF(MY_WME)) == NULL) {
4091
4140
                msg("[%02u] xtrabackup: Warning: cannot stat %s\n",
4092
 
                    thread_n, node->name);
 
4141
                    thread_n, node_path);
4093
4142
                goto skip;
4094
4143
        }
4095
4144
        dstfile = ds->open(ds_ctxt, dst_name, &src_stat);
4103
4152
        if (xtrabackup_stream) {
4104
4153
                const char *action = xtrabackup_compress ?
4105
4154
                        "Compressing and streaming" : "Streaming";
4106
 
                msg("[%02u] %s %s\n", thread_n, action, node->name);
 
4155
                msg("[%02u] %s %s\n", thread_n, action, node_path);
4107
4156
        } else {
4108
4157
                const char *action;
4109
4158
 
4113
4162
                        action = "Copying";
4114
4163
                }
4115
4164
                msg("[%02u] %s %s to %s\n", thread_n, action,
4116
 
                    node->name, dstfile->path);
 
4165
                    node_path, dstfile->path);
4117
4166
        }
4118
4167
 
4119
4168
        buf2 = static_cast<byte *>(ut_malloc(COPY_CHUNK
4180
4229
                                                    "resulted in fail. File "
4181
4230
                                                    "%s seems to be "
4182
4231
                                                    "corrupted.\n",
4183
 
                                                    thread_n, node->name);
 
4232
                                                    thread_n, node_path);
4184
4233
                                                goto error;
4185
4234
                                        }
4186
4235
                                        msg("[%02u] xtrabackup: "
4305
4354
        msg("[%02u] xtrabackup: Warning: We assume the "
4306
4355
            "table was dropped during xtrabackup execution "
4307
4356
            "and ignore the file.\n", thread_n);
4308
 
        msg("[%02u] xtrabackup: Warning: skipping file %s.\n",
4309
 
            thread_n, node->name);
 
4357
        msg("[%02u] xtrabackup: Warning: skipping tablespace %s.\n",
 
4358
            thread_n, node_name);
4310
4359
        return(FALSE);
4311
4360
}
4312
4361
 
6159
6208
                table = dict_table_get_low(table_name);
6160
6209
                mem_free(table_name);
6161
6210
 
6162
 
                if (table && check_if_skip_table(table->name, ""))
 
6211
                if (table && check_if_skip_table(table->name))
6163
6212
                        goto skip;
6164
6213
 
6165
6214
                if (table == NULL) {
7643
7692
 
7644
7693
                                        p = info_file_path;
7645
7694
                                        prev = NULL;
7646
 
                                        while ((next = strstr(p, SRV_PATH_SEPARATOR_STR)) != NULL)
 
7695
                                        while ((next =
 
7696
                                                strchr(p, SRV_PATH_SEPARATOR))
 
7697
                                               != NULL)
7647
7698
                                        {
7648
7699
                                                prev = p;
7649
7700
                                                p = next + 1;