~akopytov/percona-xtrabackup/bug1169509-2.0

« back to all changes in this revision

Viewing changes to xtrabackup.c

  • Committer: Alexey Kopytov
  • Date: 2011-04-21 06:36:29 UTC
  • mto: This revision was merged to the branch mainline in revision 249.
  • Revision ID: akopytov@gmail.com-20110421063629-s951sxdgt2gi93xw
Added initial support for Windows builds:

- removed the compatibility symlink from the source tree, it will be
created when packaging once the necessary changes are merged from the
release branch

- abstracted away regex API into xb_regex.h so we can use native regex
on POSIX systems and my_regex on Windows

- fixed a number of code issues which Visual Studio builds

- added CMakeLists.txt

- added building instructions in BUILD-WIN.txt

Show diffs side-by-side

added added

removed removed

Lines of Context:
62
62
#include <sync0sync.h>
63
63
#include <fil0fil.h>
64
64
#include <trx0xa.h>
 
65
#include <fcntl.h>
65
66
 
66
67
#ifdef INNODB_VERSION_SHORT
67
68
#include <ibuf0ibuf.h>
68
69
#endif
69
70
 
 
71
#include "xb_regex.h"
 
72
 
70
73
#ifndef INNODB_VERSION_SHORT
71
74
#define IB_INT64 ib_longlong
72
75
#define LSN64 dulint
232
235
                                        a file, so this is either "open" or
233
236
                                        "create" */
234
237
 
235
 
#include <fcntl.h>
236
 
#include <regex.h>
 
238
/****************************************************************//**
 
239
A simple function to open or create a file.
 
240
@return own: handle to the file, not defined if error, error number
 
241
can be retrieved with os_file_get_last_error */
 
242
UNIV_INLINE
 
243
os_file_t
 
244
xb_file_create_no_error_handling(
 
245
/*=============================*/
 
246
        const char*     name,   /*!< in: name of the file or path as a
 
247
                                null-terminated string */
 
248
        ulint           create_mode,/*!< in: OS_FILE_OPEN if an existing file
 
249
                                is opened (if does not exist, error), or
 
250
                                OS_FILE_CREATE if a new file is created
 
251
                                (if exists, error) */
 
252
        ulint           access_type,/*!< in: OS_FILE_READ_ONLY,
 
253
                                OS_FILE_READ_WRITE, or
 
254
                                OS_FILE_READ_ALLOW_DELETE; the last option is
 
255
                                used by a backup program reading the file */
 
256
        ibool*          success);/*!< out: TRUE if succeed, FALSE if error */
 
257
 
 
258
/****************************************************************//**
 
259
Opens an existing file or creates a new.
 
260
@return own: handle to the file, not defined if error, error number
 
261
can be retrieved with os_file_get_last_error */
 
262
UNIV_INLINE
 
263
os_file_t
 
264
xb_file_create(
 
265
/*===========*/
 
266
        const char*     name,   /*!< in: name of the file or path as a
 
267
                                null-terminated string */
 
268
        ulint           create_mode,/*!< in: OS_FILE_OPEN if an existing file
 
269
                                is opened (if does not exist, error), or
 
270
                                OS_FILE_CREATE if a new file is created
 
271
                                (if exists, error),
 
272
                                OS_FILE_OVERWRITE if a new file is created
 
273
                                or an old overwritten;
 
274
                                OS_FILE_OPEN_RAW, if a raw device or disk
 
275
                                partition should be opened */
 
276
        ulint           purpose,/*!< in: OS_FILE_AIO, if asynchronous,
 
277
                                non-buffered i/o is desired,
 
278
                                OS_FILE_NORMAL, if any normal file;
 
279
                                NOTE that it also depends on type, os_aio_..
 
280
                                and srv_.. variables whether we really use
 
281
                                async i/o or unbuffered i/o: look in the
 
282
                                function source code for the exact rules */
 
283
        ulint           type,   /*!< in: OS_DATA_FILE or OS_LOG_FILE */
 
284
        ibool*          success);/*!< out: TRUE if succeed, FALSE if error */
 
285
 
 
286
/***********************************************************************//**
 
287
Renames a file (can also move it to another directory). It is safest that the
 
288
file is closed before calling this function.
 
289
@return TRUE if success */
 
290
UNIV_INLINE
 
291
ibool
 
292
xb_file_rename(
 
293
/*===========*/
 
294
        const char*     oldpath,/*!< in: old file path as a null-terminated
 
295
                                string */
 
296
        const char*     newpath);/*!< in: new file path */
 
297
 
 
298
UNIV_INLINE
 
299
void
 
300
xb_file_set_nocache(
 
301
/*================*/
 
302
        os_file_t       fd,             /* in: file descriptor to alter */
 
303
        const char*     file_name,      /* in: used in the diagnostic message */
 
304
        const char*     operation_name);/* in: used in the diagnostic message,
 
305
                                        we call os_file_set_nocache()
 
306
                                        immediately after opening or creating
 
307
                                        a file, so this is either "open" or
 
308
                                        "create" */
237
309
 
238
310
#ifdef POSIX_FADV_NORMAL
239
311
#define USE_POSIX_FADVISE
586
658
 
587
659
char *xtrabackup_tables = NULL;
588
660
int tables_regex_num;
589
 
regex_t *tables_regex;
590
 
regmatch_t tables_regmatch[1];
 
661
xb_regex_t *tables_regex;
 
662
xb_regmatch_t tables_regmatch[1];
591
663
 
592
664
char *xtrabackup_tables_file = NULL;
593
665
hash_table_t* tables_hash;
633
705
 
634
706
#define XB_DELTA_INFO_SUFFIX ".meta"
635
707
 
 
708
#ifdef __WIN__
 
709
#define XB_FILE_UNDEFINED NULL
 
710
#else
 
711
#define XB_FILE_UNDEFINED (-1)
 
712
#endif
 
713
 
636
714
/* === sharing with thread === */
637
 
os_file_t       dst_log = -1;
 
715
os_file_t       dst_log = XB_FILE_UNDEFINED;
638
716
char            dst_log_path[FN_REFLEN];
639
717
 
640
718
/* === some variables from mysqld === */
1390
1468
                will be passed to fdopen(), it will be closed by invoking
1391
1469
                fclose(), which in turn will invoke close() instead of
1392
1470
                my_close(). */
 
1471
#ifdef _WIN32
 
1472
                /* Note that on Windows, the integer returned by mysql_tmpfile
 
1473
                has no relation to C runtime file descriptor. Here, we need
 
1474
                to call my_get_osfhandle to get the HANDLE and then convert it
 
1475
                to C runtime filedescriptor. */
 
1476
                {
 
1477
                        HANDLE hFile = my_get_osfhandle(fd);
 
1478
                        HANDLE hDup;
 
1479
                        BOOL bOK =
 
1480
                                DuplicateHandle(GetCurrentProcess(), hFile,
 
1481
                                                GetCurrentProcess(), &hDup, 0,
 
1482
                                                FALSE, DUPLICATE_SAME_ACCESS);
 
1483
                        if(bOK) {
 
1484
                                fd2 = _open_osfhandle((intptr_t)hDup,0);
 
1485
                        }
 
1486
                        else {
 
1487
                                my_osmaperr(GetLastError());
 
1488
                                fd2 = -1;
 
1489
                        }
 
1490
                }
 
1491
#else
1393
1492
                fd2 = dup(fd);
 
1493
#endif
1394
1494
                if (fd2 < 0) {
1395
1495
                        fprintf(stderr, "xtrabackup: Got error %d on dup\n",fd2);
1396
1496
                }
1430
1530
void
1431
1531
innobase_print_identifier(
1432
1532
        FILE*   f,
1433
 
        trx_t*  trx,
1434
 
        ibool   table_id,
 
1533
        trx_t*  trx __attribute__((unused)),
 
1534
        ibool   table_id __attribute__((unused)),
1435
1535
        const char*     name,
1436
1536
        ulint   namelen)
1437
1537
{
1438
 
        (void)trx;
1439
 
        (void)table_id;
1440
 
 
1441
1538
        const char*     s       = name;
1442
1539
        const char*     e = s + namelen;
1443
1540
        int             q;
1444
1541
 
1445
 
        q = '"';
 
1542
        q = '"';
1446
1543
 
1447
1544
        putc(q, f);
1448
1545
        while (s < e) {
1467
1564
        ulint           buflen, /*!< in: length of buf, in bytes */
1468
1565
        const char*     id,     /*!< in: identifier to convert */
1469
1566
        ulint           idlen,  /*!< in: length of id, in bytes */
1470
 
        void*           thd,    /*!< in: MySQL connection thread, or NULL */
1471
 
        ibool           file_id)/*!< in: TRUE=id is a table or database name;
1472
 
                                FALSE=id is an UTF-8 string */
 
1567
        void*           thd __attribute__((unused)), 
 
1568
                                                /*!< in: MySQL connection thread, or NULL */
 
1569
        ibool           file_id __attribute__((unused)))
 
1570
                                                /*!< in: TRUE=id is a table or database name;
 
1571
                                                FALSE=id is an UTF-8 string */
1473
1572
{
1474
 
        (void)thd;
1475
 
        (void)file_id;
1476
 
 
1477
1573
        const char*     s       = id;
1478
1574
        int             q;
1479
1575
 
2116
2212
#ifndef INNODB_VERSION_SHORT
2117
2213
        srv_use_adaptive_hash_indexes = (ibool) innobase_adaptive_hash_index;
2118
2214
#else
2119
 
        btr_search_enabled = (ibool) innobase_adaptive_hash_index;
 
2215
        btr_search_enabled = (char) innobase_adaptive_hash_index;
2120
2216
#endif
2121
2217
 
2122
2218
        os_use_large_pages = (ibool) innobase_use_large_pages;
2124
2220
 
2125
2221
        row_rollback_on_timeout = (ibool) innobase_rollback_on_timeout;
2126
2222
 
2127
 
        srv_file_per_table = (ibool) innobase_file_per_table;
 
2223
        srv_file_per_table = (my_bool) innobase_file_per_table;
2128
2224
 
2129
2225
        srv_locks_unsafe_for_binlog = (ibool) innobase_locks_unsafe_for_binlog;
2130
2226
 
2424
2520
        }
2425
2521
}
2426
2522
 
 
2523
#ifdef INNODB_VERSION_SHORT
 
2524
#define XB_HASH_SEARCH(NAME, TABLE, FOLD, DATA, ASSERTION, TEST) \
 
2525
        HASH_SEARCH(NAME, TABLE, FOLD, xtrabackup_tables_t*, DATA, ASSERTION, \
 
2526
                    TEST)
 
2527
#else
 
2528
#define XB_HASH_SEARCH(NAME, TABLE, FOLD, DATA, ASSERTION, TEST) \
 
2529
        HASH_SEARCH(NAME, TABLE, FOLD, DATA, TEST)
 
2530
#endif
 
2531
 
 
2532
/****************************************************************//**
 
2533
A simple function to open or create a file.
 
2534
@return own: handle to the file, not defined if error, error number
 
2535
can be retrieved with os_file_get_last_error */
 
2536
UNIV_INLINE
 
2537
os_file_t
 
2538
xb_file_create_no_error_handling(
 
2539
/*=============================*/
 
2540
        const char*     name,   /*!< in: name of the file or path as a
 
2541
                                null-terminated string */
 
2542
        ulint           create_mode,/*!< in: OS_FILE_OPEN if an existing file
 
2543
                                is opened (if does not exist, error), or
 
2544
                                OS_FILE_CREATE if a new file is created
 
2545
                                (if exists, error) */
 
2546
        ulint           access_type,/*!< in: OS_FILE_READ_ONLY,
 
2547
                                OS_FILE_READ_WRITE, or
 
2548
                                OS_FILE_READ_ALLOW_DELETE; the last option is
 
2549
                                used by a backup program reading the file */
 
2550
        ibool*          success)/*!< out: TRUE if succeed, FALSE if error */
 
2551
{
 
2552
#if MYSQL_VERSION_ID > 50500
 
2553
        return os_file_create_simple_no_error_handling(
 
2554
                0, /* innodb_file_data_key */
 
2555
                name, create_mode, access_type, success);
 
2556
#else
 
2557
        return os_file_create_simple_no_error_handling(
 
2558
                name, create_mode, access_type, success);
 
2559
#endif
 
2560
}
 
2561
 
 
2562
/****************************************************************//**
 
2563
Opens an existing file or creates a new.
 
2564
@return own: handle to the file, not defined if error, error number
 
2565
can be retrieved with os_file_get_last_error */
 
2566
UNIV_INLINE
 
2567
os_file_t
 
2568
xb_file_create(
 
2569
/*===========*/
 
2570
        const char*     name,   /*!< in: name of the file or path as a
 
2571
                                null-terminated string */
 
2572
        ulint           create_mode,/*!< in: OS_FILE_OPEN if an existing file
 
2573
                                is opened (if does not exist, error), or
 
2574
                                OS_FILE_CREATE if a new file is created
 
2575
                                (if exists, error),
 
2576
                                OS_FILE_OVERWRITE if a new file is created
 
2577
                                or an old overwritten;
 
2578
                                OS_FILE_OPEN_RAW, if a raw device or disk
 
2579
                                partition should be opened */
 
2580
        ulint           purpose,/*!< in: OS_FILE_AIO, if asynchronous,
 
2581
                                non-buffered i/o is desired,
 
2582
                                OS_FILE_NORMAL, if any normal file;
 
2583
                                NOTE that it also depends on type, os_aio_..
 
2584
                                and srv_.. variables whether we really use
 
2585
                                async i/o or unbuffered i/o: look in the
 
2586
                                function source code for the exact rules */
 
2587
        ulint           type,   /*!< in: OS_DATA_FILE or OS_LOG_FILE */
 
2588
        ibool*          success)/*!< out: TRUE if succeed, FALSE if error */
 
2589
{
 
2590
#if MYSQL_VERSION_ID > 50500
 
2591
        return os_file_create(0 /* innodb_file_data_key */,
 
2592
                              name, create_mode, purpose, type, success);
 
2593
#else
 
2594
        return os_file_create(name, create_mode, purpose, type, success);
 
2595
#endif
 
2596
}
 
2597
 
 
2598
/***********************************************************************//**
 
2599
Renames a file (can also move it to another directory). It is safest that the
 
2600
file is closed before calling this function.
 
2601
@return TRUE if success */
 
2602
UNIV_INLINE
 
2603
ibool
 
2604
xb_file_rename(
 
2605
/*===========*/
 
2606
        const char*     oldpath,/*!< in: old file path as a null-terminated
 
2607
                                string */
 
2608
        const char*     newpath)/*!< in: new file path */
 
2609
{
 
2610
#if MYSQL_VERSION_ID > 50500
 
2611
        return os_file_rename(
 
2612
                0 /* innodb_file_data_key */, oldpath, newpath);
 
2613
#else
 
2614
        return os_file_rename(oldpath, newpath);
 
2615
#endif
 
2616
}
 
2617
 
 
2618
UNIV_INLINE
 
2619
void
 
2620
xb_file_set_nocache(
 
2621
/*================*/
 
2622
        os_file_t       fd,             /* in: file descriptor to alter */
 
2623
        const char*     file_name,      /* in: used in the diagnostic message */
 
2624
        const char*     operation_name) /* in: used in the diagnostic message,
 
2625
                                        we call os_file_set_nocache()
 
2626
                                        immediately after opening or creating
 
2627
                                        a file, so this is either "open" or
 
2628
                                        "create" */
 
2629
{
 
2630
#ifndef __WIN__
 
2631
        if (srv_unix_file_flush_method == SRV_UNIX_O_DIRECT) {
 
2632
                os_file_set_nocache(fd, file_name, operation_name);
 
2633
        }
 
2634
#endif
 
2635
}
2427
2636
 
2428
2637
/* TODO: We may tune the behavior (e.g. by fil_aio)*/
2429
2638
#define COPY_CHUNK 64
2431
2640
static my_bool
2432
2641
xtrabackup_copy_datafile(fil_node_t* node, uint thread_n)
2433
2642
{
2434
 
        os_file_t       src_file = -1;
2435
 
        os_file_t       dst_file = -1;
 
2643
        os_file_t       src_file = XB_FILE_UNDEFINED;
 
2644
        os_file_t       dst_file = XB_FILE_UNDEFINED;
2436
2645
        char            dst_path[FN_REFLEN];
2437
2646
        char            meta_path[FN_REFLEN];
2438
2647
        ibool           success;
2483
2692
                *(p - 1) = '.';
2484
2693
 
2485
2694
                for (i = 0; i < tables_regex_num; i++) {
2486
 
                        regres = regexec(&tables_regex[i], prev, 1, tables_regmatch, 0);
 
2695
                        regres = xb_regexec(&tables_regex[i], prev, 1,
 
2696
                                            tables_regmatch, 0);
2487
2697
                        if (regres != REG_NOMATCH)
2488
2698
                                break;
2489
2699
                }
2528
2738
                tmp = p[p_len];
2529
2739
                p[p_len] = 0;
2530
2740
 
2531
 
                HASH_SEARCH(name_hash, tables_hash, ut_fold_string(prev),
2532
 
#ifdef INNODB_VERSION_SHORT
2533
 
                            xtrabackup_tables_t*,
2534
 
#endif
2535
 
                            table,
2536
 
#ifdef INNODB_VERSION_SHORT
2537
 
                            ut_ad(table->name),
2538
 
#endif
2539
 
                            !strcmp(table->name, prev));
 
2741
                XB_HASH_SEARCH(name_hash, tables_hash, ut_fold_string(prev),
 
2742
                               table,
 
2743
                               ut_ad(table->name),
 
2744
                               !strcmp(table->name, prev));
2540
2745
 
2541
2746
                p[p_len] = tmp;
2542
2747
 
2611
2816
 
2612
2817
        /* open src_file*/
2613
2818
        if (!node->open) {
2614
 
                src_file = os_file_create_simple_no_error_handling(
2615
 
#if (MYSQL_VERSION_ID > 50500)
2616
 
                                                0 /* dummy of innodb_file_data_key */,
2617
 
#endif
2618
 
                                                node->name, OS_FILE_OPEN,
2619
 
                                                OS_FILE_READ_ONLY, &success);
 
2819
                src_file = xb_file_create_no_error_handling(node->name,
 
2820
                                                            OS_FILE_OPEN,
 
2821
                                                            OS_FILE_READ_ONLY,
 
2822
                                                            &success);
2620
2823
                if (!success) {
2621
2824
                        /* The following call prints an error message */
2622
2825
                        os_file_get_last_error(TRUE);
2630
2833
                        goto skip;
2631
2834
                }
2632
2835
 
2633
 
                if (srv_unix_file_flush_method == SRV_UNIX_O_DIRECT) {
2634
 
                        os_file_set_nocache(src_file, node->name, "OPEN");
2635
 
                }
 
2836
                xb_file_set_nocache(src_file, node->name, "OPEN");
2636
2837
        } else {
2637
2838
                src_file = node->handle;
2638
2839
        }
2643
2844
#endif
2644
2845
 
2645
2846
        /* open dst_file */
2646
 
        /* os_file_create reads srv_unix_file_flush_method */
2647
 
        dst_file = os_file_create(
2648
 
#if (MYSQL_VERSION_ID > 50500)
2649
 
                        0 /* dummy of innodb_file_data_key */,
2650
 
#endif
2651
 
                        dst_path, OS_FILE_CREATE,
2652
 
                        OS_FILE_NORMAL, OS_DATA_FILE, &success);
2653
 
                if (!success) {
2654
 
                        /* The following call prints an error message */
2655
 
                        os_file_get_last_error(TRUE);
 
2847
        /* xb_file_create reads srv_unix_file_flush_method */
 
2848
        dst_file = xb_file_create(dst_path, OS_FILE_CREATE,
 
2849
                                  OS_FILE_NORMAL, OS_DATA_FILE, &success);
 
2850
        if (!success) {
 
2851
                /* The following call prints an error message */
 
2852
                os_file_get_last_error(TRUE);
2656
2853
 
2657
 
                        fprintf(stderr,"[%02u] xtrabackup: error: "
2658
 
                                "cannot open %s\n", thread_n, dst_path);
2659
 
                        goto error;
2660
 
                }
 
2854
                fprintf(stderr,"[%02u] xtrabackup: error: "
 
2855
                        "cannot open %s\n", thread_n, dst_path);
 
2856
                goto error;
 
2857
        }
2661
2858
 
2662
2859
#ifdef USE_POSIX_FADVISE
2663
2860
        posix_fadvise(dst_file, 0, 0, POSIX_FADV_DONTNEED);
2857
3054
        ut_free(buf2);
2858
3055
        return(FALSE);
2859
3056
error:
2860
 
        if (src_file != -1 && !node->open)
 
3057
        if (src_file != XB_FILE_UNDEFINED && !node->open)
2861
3058
                os_file_close(src_file);
2862
 
        if (dst_file != -1)
 
3059
        if (dst_file != XB_FILE_UNDEFINED)
2863
3060
                os_file_close(dst_file);
2864
3061
        if (buf2)
2865
3062
                ut_free(buf2);
2868
3065
        return(TRUE); /*ERROR*/
2869
3066
 
2870
3067
skip:
2871
 
        if (src_file != -1 && !node->open)
 
3068
        if (src_file != XB_FILE_UNDEFINED && !node->open)
2872
3069
                os_file_close(src_file);
2873
 
        if (dst_file != -1)
 
3070
        if (dst_file != XB_FILE_UNDEFINED)
2874
3071
                os_file_close(dst_file);
2875
3072
        if (buf2)
2876
3073
                ut_free(buf2);
2890
3087
        ibool           success;
2891
3088
 
2892
3089
        if (!xtrabackup_stream)
2893
 
                ut_a(dst_log != -1);
 
3090
                ut_a(dst_log != XB_FILE_UNDEFINED);
2894
3091
 
2895
3092
        /* read from checkpoint_lsn_start to current */
2896
3093
        contiguous_lsn = ut_dulint_align_down(from_lsn,
3042
3239
                if (!finished) {
3043
3240
                        write_size = RECV_SCAN_SIZE;
3044
3241
                } else {
3045
 
                        write_size = ut_dulint_minus(
 
3242
                        write_size = (ulint) ut_dulint_minus(
3046
3243
                                        ut_dulint_align_up(group_scanned_lsn, OS_FILE_LOG_BLOCK_SIZE),
3047
3244
                                        start_lsn);
3048
3245
                }
3158
3355
ulint
3159
3356
#endif
3160
3357
log_copying_thread(
3161
 
        void*   arg)
 
3358
        void*   arg __attribute__((unused)))
3162
3359
{
3163
 
        (void)arg;
3164
3360
        ulint   counter = 0;
3165
3361
 
3166
3362
        if (!xtrabackup_stream)
3167
 
                ut_a(dst_log != -1);
 
3363
                ut_a(dst_log != XB_FILE_UNDEFINED);
3168
3364
 
3169
3365
        log_copying_running = TRUE;
3170
3366
 
3378
3574
        if(innodb_init_param())
3379
3575
                exit(EXIT_FAILURE);
3380
3576
 
 
3577
#ifndef __WIN__        
3381
3578
        if (srv_file_flush_method_str == NULL) {
3382
3579
                /* These are the default options */
3383
3580
#if (MYSQL_VERSION_ID < 50100)
3385
3582
#else /* MYSQL_VERSION_ID < 51000 */
3386
3583
                srv_unix_file_flush_method = SRV_UNIX_FSYNC;
3387
3584
#endif
3388
 
                srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
3389
 
#ifndef __WIN__        
3390
3585
#if (MYSQL_VERSION_ID < 50100)
3391
3586
        } else if (0 == ut_strcmp(srv_file_flush_method_str, "fdatasync")) {
3392
3587
                srv_unix_file_flush_method = SRV_UNIX_FDATASYNC;
3406
3601
 
3407
3602
        } else if (0 == ut_strcmp(srv_file_flush_method_str, "nosync")) {
3408
3603
                srv_unix_file_flush_method = SRV_UNIX_NOSYNC;
3409
 
#else
3410
 
        } else if (0 == ut_strcmp(srv_file_flush_method_str, "normal")) {
3411
 
                srv_win_file_flush_method = SRV_WIN_IO_NORMAL;
3412
 
                os_aio_use_native_aio = FALSE;
3413
 
 
3414
 
        } else if (0 == ut_strcmp(srv_file_flush_method_str, "unbuffered")) {
3415
 
                srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
3416
 
                os_aio_use_native_aio = FALSE;
3417
 
 
3418
 
        } else if (0 == ut_strcmp(srv_file_flush_method_str,
3419
 
                                                        "async_unbuffered")) {
3420
 
                srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;      
3421
 
#endif
3422
3604
        } else {
3423
3605
                fprintf(stderr, 
3424
3606
                "xtrabackup: Unrecognized value %s for innodb_flush_method\n",
3425
3607
                                        srv_file_flush_method_str);
3426
3608
                exit(EXIT_FAILURE);
3427
3609
        }
 
3610
#else /* __WIN__ */
 
3611
        /* We can only use synchronous unbuffered IO on Windows for now */
 
3612
        if (srv_file_flush_method_str != NULL) {
 
3613
                fprintf(stderr,
 
3614
                        "xtrabackupp: Warning: "
 
3615
                        "ignoring innodb_flush_method = %s on Windows.\n");
 
3616
        }
 
3617
 
 
3618
        srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
 
3619
        srv_use_native_aio = FALSE;
 
3620
#endif
3428
3621
 
3429
3622
#ifndef INNODB_VERSION_SHORT
3430
3623
        if (srv_pool_size >= 1000 * 1024) {
3703
3896
                /* open 'xtrabackup_logfile' */
3704
3897
                sprintf(dst_log_path, "%s%s", xtrabackup_target_dir, "/xtrabackup_logfile");
3705
3898
                srv_normalize_path_for_win(dst_log_path);
3706
 
                /* os_file_create reads srv_unix_file_flush_method for OS_DATA_FILE*/
3707
 
                dst_log = os_file_create(
3708
 
#if (MYSQL_VERSION_ID > 50500)
3709
 
                                0 /* dummy of innodb_file_data_key */,
3710
 
#endif
3711
 
                                dst_log_path, OS_FILE_CREATE,
3712
 
                                OS_FILE_NORMAL, OS_DATA_FILE, &success);
 
3899
                /* xb_file_create reads srv_unix_file_flush_method for
 
3900
                OS_DATA_FILE*/
 
3901
                dst_log = xb_file_create(dst_log_path, OS_FILE_CREATE,
 
3902
                                         OS_FILE_NORMAL, OS_DATA_FILE,
 
3903
                                         &success);
3713
3904
 
3714
3905
                if (!success) {
3715
3906
                        /* The following call prints an error message */
3749
3940
 
3750
3941
        log_copy_offset += LOG_FILE_HDR_SIZE;
3751
3942
        if (!success) {
3752
 
                if (dst_log != -1)
 
3943
                if (dst_log != XB_FILE_UNDEFINED)
3753
3944
                        os_file_close(dst_log);
3754
3945
                exit(EXIT_FAILURE);
3755
3946
        }
3839
4030
 
3840
4031
        /* suspend-at-end */
3841
4032
        if (xtrabackup_suspend_at_end) {
3842
 
                os_file_t       suspend_file = -1;
 
4033
                os_file_t       suspend_file = XB_FILE_UNDEFINED;
3843
4034
                char    suspend_path[FN_REFLEN];
3844
4035
                ibool   success, exists;
3845
4036
                os_file_type_t  type;
3848
4039
                        "/xtrabackup_suspended");
3849
4040
 
3850
4041
                srv_normalize_path_for_win(suspend_path);
3851
 
                /* os_file_create reads srv_unix_file_flush_method */
3852
 
                suspend_file = os_file_create(
3853
 
#if (MYSQL_VERSION_ID > 50500)
3854
 
                                        0 /* dummy of innodb_file_data_key */,
3855
 
#endif
3856
 
                                        suspend_path, OS_FILE_OVERWRITE,
3857
 
                                        OS_FILE_NORMAL, OS_DATA_FILE, &success);
 
4042
                /* xb_file_create reads srv_unix_file_flush_method */
 
4043
                suspend_file = xb_file_create(suspend_path, OS_FILE_OVERWRITE,
 
4044
                                              OS_FILE_NORMAL, OS_DATA_FILE,
 
4045
                                              &success);
3858
4046
 
3859
4047
                if (!success) {
3860
4048
                        fprintf(stderr, "xtrabackup: Error: failed to create file 'xtrabackup_suspended'\n");
3861
4049
                }
3862
4050
 
3863
 
                if (suspend_file != -1)
 
4051
                if (suspend_file != XB_FILE_UNDEFINED)
3864
4052
                        os_file_close(suspend_file);
3865
4053
 
3866
4054
                exists = TRUE;
4011
4199
        ulonglong sum_data, sum_data_extern;
4012
4200
        ulonglong n_recs;
4013
4201
        ulint   page_size;
 
4202
        buf_block_t*    block;
 
4203
        ulint   zip_size;
4014
4204
 
4015
4205
        n_pages = sum_data = n_recs = 0;
4016
4206
        n_pages_extern = sum_data_extern = 0;
4017
4207
 
4018
 
#ifdef INNODB_VERSION_SHORT
4019
 
        buf_block_t*    block;
4020
 
        ulint   zip_size;
4021
 
#endif
4022
4208
 
4023
4209
        if (level == 0)
4024
4210
                fprintf(stdout, "        leaf pages: ");
4388
4574
                                *p = '.';
4389
4575
 
4390
4576
                        for (i = 0; i < tables_regex_num; i++) {
4391
 
                                regres = regexec(&tables_regex[i], table->name, 1, tables_regmatch, 0);
 
4577
                                regres = xb_regexec(&tables_regex[i],
 
4578
                                                    table->name, 1,
 
4579
                                                    tables_regmatch, 0);
4392
4580
                                if (regres != REG_NOMATCH)
4393
4581
                                        break;
4394
4582
                        }
4403
4591
                if (xtrabackup_tables_file) {
4404
4592
                        xtrabackup_tables_t*    xtable;
4405
4593
 
4406
 
                        HASH_SEARCH(name_hash, tables_hash, ut_fold_string(table->name),
4407
 
#ifdef INNODB_VERSION_SHORT
4408
 
                                    xtrabackup_tables_t*,
4409
 
#endif
4410
 
                                    xtable,
4411
 
#ifdef INNODB_VERSION_SHORT
4412
 
                                    ut_ad(xtable->name),
4413
 
#endif
4414
 
                                    !strcmp(xtable->name, table->name));
 
4594
                        XB_HASH_SEARCH(name_hash, tables_hash,
 
4595
                                       ut_fold_string(table->name),
 
4596
                                       xtable,
 
4597
                                       ut_ad(xtable->name),
 
4598
                                       !strcmp(xtable->name, table->name));
4415
4599
 
4416
4600
                        if (!xtable)
4417
4601
                                goto skip;
4527
4711
static my_bool
4528
4712
xtrabackup_init_temp_log(void)
4529
4713
{
4530
 
        os_file_t       src_file = -1;
 
4714
        os_file_t       src_file = XB_FILE_UNDEFINED;
4531
4715
        char    src_path[FN_REFLEN];
4532
4716
        char    dst_path[FN_REFLEN];
4533
4717
        ibool   success;
4557
4741
        srv_normalize_path_for_win(dst_path);
4558
4742
        srv_normalize_path_for_win(src_path);
4559
4743
retry:
4560
 
        src_file = os_file_create_simple_no_error_handling(
4561
 
#if (MYSQL_VERSION_ID > 50500)
4562
 
                                        0 /* dummy of innodb_file_data_key */,
4563
 
#endif
4564
 
                                        src_path, OS_FILE_OPEN,
4565
 
                                        OS_FILE_READ_WRITE /* OS_FILE_READ_ONLY */, &success);
 
4744
        src_file = xb_file_create_no_error_handling(src_path, OS_FILE_OPEN,
 
4745
                                                    OS_FILE_READ_WRITE,
 
4746
                                                    &success);
4566
4747
        if (!success) {
4567
4748
                /* The following call prints an error message */
4568
4749
                os_file_get_last_error(TRUE);
4572
4753
                        src_path);
4573
4754
 
4574
4755
                /* check if ib_logfile0 may be xtrabackup_logfile */
4575
 
                src_file = os_file_create_simple_no_error_handling(
4576
 
#if (MYSQL_VERSION_ID > 50500)
4577
 
                                0 /* dummy of innodb_file_data_key */,
4578
 
#endif
4579
 
                                dst_path, OS_FILE_OPEN,
4580
 
                                OS_FILE_READ_WRITE /* OS_FILE_READ_ONLY */, &success);
 
4756
                src_file = xb_file_create_no_error_handling(dst_path,
 
4757
                                                            OS_FILE_OPEN,
 
4758
                                                            OS_FILE_READ_WRITE,
 
4759
                                                            &success);
4581
4760
                if (!success) {
4582
4761
                        os_file_get_last_error(TRUE);
4583
4762
                        fprintf(stderr,
4604
4783
                        log_buf_ = NULL;
4605
4784
 
4606
4785
                        os_file_close(src_file);
4607
 
                        src_file = -1;
 
4786
                        src_file = XB_FILE_UNDEFINED;
4608
4787
 
4609
4788
                        /* rename and try again */
4610
 
                        success = os_file_rename(
4611
 
#if (MYSQL_VERSION_ID > 50500)
4612
 
                                        0 /* dummy of innodb_file_data_key */,
4613
 
#endif
4614
 
                                        dst_path, src_path);
 
4789
                        success = xb_file_rename(dst_path, src_path);
4615
4790
                        if (!success) {
4616
4791
                                goto error;
4617
4792
                        }
4627
4802
                log_buf_ = NULL;
4628
4803
 
4629
4804
                os_file_close(src_file);
4630
 
                src_file = -1;
 
4805
                src_file = XB_FILE_UNDEFINED;
4631
4806
 
4632
4807
                goto error;
4633
4808
        }
4637
4812
        posix_fadvise(src_file, 0, 0, POSIX_FADV_DONTNEED);
4638
4813
#endif
4639
4814
 
4640
 
        if (srv_unix_file_flush_method == SRV_UNIX_O_DIRECT) {
4641
 
                os_file_set_nocache(src_file, src_path, "OPEN");
4642
 
        }
 
4815
        xb_file_set_nocache(src_file, src_path, "OPEN");
4643
4816
 
4644
4817
        file_size = os_file_get_size_as_iblonglong(src_file);
4645
4818
 
4702
4875
        /* It seems to be needed to overwrite the both checkpoint area. */
4703
4876
        MACH_WRITE_64(log_buf + LOG_CHECKPOINT_1 + LOG_CHECKPOINT_LSN, max_lsn);
4704
4877
        mach_write_to_4(log_buf + LOG_CHECKPOINT_1 + LOG_CHECKPOINT_OFFSET,
4705
 
                        LOG_FILE_HDR_SIZE + ut_dulint_minus(max_lsn,
 
4878
                        LOG_FILE_HDR_SIZE + (ulint) ut_dulint_minus(max_lsn,
4706
4879
                        ut_dulint_align_down(max_lsn,OS_FILE_LOG_BLOCK_SIZE)));
4707
4880
#ifdef XTRADB_BASED
4708
4881
        MACH_WRITE_64(log_buf + LOG_CHECKPOINT_1 + LOG_CHECKPOINT_ARCHIVED_LSN,
4718
4891
 
4719
4892
        MACH_WRITE_64(log_buf + LOG_CHECKPOINT_2 + LOG_CHECKPOINT_LSN, max_lsn);
4720
4893
        mach_write_to_4(log_buf + LOG_CHECKPOINT_2 + LOG_CHECKPOINT_OFFSET,
4721
 
                        LOG_FILE_HDR_SIZE + ut_dulint_minus(max_lsn,
 
4894
                        LOG_FILE_HDR_SIZE + (ulint) ut_dulint_minus(max_lsn,
4722
4895
                        ut_dulint_align_down(max_lsn,OS_FILE_LOG_BLOCK_SIZE)));
4723
4896
#ifdef XTRADB_BASED
4724
4897
        MACH_WRITE_64(log_buf + LOG_CHECKPOINT_2 + LOG_CHECKPOINT_ARCHIVED_LSN,
4745
4918
                success = os_file_write(src_path, src_file, log_buf,
4746
4919
                                (ulint)(file_size & 0xFFFFFFFFUL),
4747
4920
                                (ulint)(file_size >> 32),
4748
 
                                UNIV_PAGE_SIZE - (file_size % UNIV_PAGE_SIZE));
 
4921
                                UNIV_PAGE_SIZE - (ulint) (file_size % UNIV_PAGE_SIZE));
4749
4922
                if (!success) {
4750
4923
                        goto error;
4751
4924
                }
4758
4931
                ulint   expand;
4759
4932
 
4760
4933
                memset(log_buf, 0, UNIV_PAGE_SIZE * 128);
4761
 
                expand = file_size / UNIV_PAGE_SIZE / 8;
 
4934
                expand = (ulint) (file_size / UNIV_PAGE_SIZE / 8);
4762
4935
 
4763
4936
                for (; expand > 128; expand -= 128) {
4764
4937
                        success = os_file_write(src_path, src_file, log_buf,
4808
4981
#endif
4809
4982
 
4810
4983
        os_file_close(src_file);
4811
 
        src_file = -1;
 
4984
        src_file = XB_FILE_UNDEFINED;
4812
4985
 
4813
4986
        /* Backup log parameters */
4814
4987
        innobase_log_group_home_dir_backup = innobase_log_group_home_dir;
4823
4996
        srv_thread_concurrency = 0;
4824
4997
 
4825
4998
        /* rename 'xtrabackup_logfile' to 'ib_logfile0' */
4826
 
        success = os_file_rename(
4827
 
#if (MYSQL_VERSION_ID > 50500)
4828
 
                        0 /* dummy of innodb_file_data_key */,
4829
 
#endif
4830
 
                        src_path, dst_path);
 
4999
        success = xb_file_rename(src_path, dst_path);
4831
5000
        if (!success) {
4832
5001
                goto error;
4833
5002
        }
4839
5008
 
4840
5009
skip_modify:
4841
5010
        os_file_close(src_file);
4842
 
        src_file = -1;
 
5011
        src_file = XB_FILE_UNDEFINED;
4843
5012
        ut_free(log_buf_);
4844
5013
        return(FALSE);
4845
5014
 
4846
5015
error:
4847
 
        if (src_file != -1)
 
5016
        if (src_file != XB_FILE_UNDEFINED)
4848
5017
                os_file_close(src_file);
4849
5018
        if (log_buf_)
4850
5019
                ut_free(log_buf_);
4881
5050
        const char*     dbname,         /* in: database name (ibdata: NULL) */
4882
5051
        const char*     filename,       /* in: file name (not a path),
4883
5052
                                        including the .delta extension */
4884
 
        my_bool check_newer)
 
5053
        my_bool check_newer __attribute__((unused)))
4885
5054
{
4886
 
        (void)check_newer;
4887
 
        os_file_t       src_file = -1;
4888
 
        os_file_t       dst_file = -1;
 
5055
        os_file_t       src_file = XB_FILE_UNDEFINED;
 
5056
        os_file_t       dst_file = XB_FILE_UNDEFINED;
4889
5057
        char    src_path[FN_REFLEN];
4890
5058
        char    dst_path[FN_REFLEN];
4891
5059
        char    meta_path[FN_REFLEN];
4938
5106
                goto error;
4939
5107
        }
4940
5108
        
4941
 
        src_file = os_file_create_simple_no_error_handling(
4942
 
#if (MYSQL_VERSION_ID > 50500)
4943
 
                        0 /* dummy of innodb_file_data_key */,
4944
 
#endif
4945
 
                        src_path, OS_FILE_OPEN, OS_FILE_READ_WRITE, &success);
 
5109
        src_file = xb_file_create_no_error_handling(src_path, OS_FILE_OPEN,
 
5110
                                                    OS_FILE_READ_WRITE,
 
5111
                                                    &success);
4946
5112
        if (!success) {
4947
5113
                os_file_get_last_error(TRUE);
4948
5114
                fprintf(stderr,
4956
5122
        posix_fadvise(src_file, 0, 0, POSIX_FADV_DONTNEED);
4957
5123
#endif
4958
5124
 
4959
 
        if (srv_unix_file_flush_method == SRV_UNIX_O_DIRECT) {
4960
 
                os_file_set_nocache(src_file, src_path, "OPEN");
4961
 
        }
 
5125
        xb_file_set_nocache(src_file, src_path, "OPEN");
4962
5126
 
4963
 
        dst_file = os_file_create_simple_no_error_handling(
4964
 
#if (MYSQL_VERSION_ID > 50500)
4965
 
                        0 /* dummy of innodb_file_data_key */,
4966
 
#endif
4967
 
                        dst_path, OS_FILE_OPEN, OS_FILE_READ_WRITE, &success);
 
5127
        dst_file = xb_file_create_no_error_handling(dst_path, OS_FILE_OPEN,
 
5128
                                                    OS_FILE_READ_WRITE,
 
5129
                                                    &success);
4968
5130
        if (!success) {
4969
5131
                os_file_get_last_error(TRUE);
4970
5132
                fprintf(stderr,
4977
5139
        posix_fadvise(dst_file, 0, 0, POSIX_FADV_DONTNEED);
4978
5140
#endif
4979
5141
 
4980
 
        if (srv_unix_file_flush_method == SRV_UNIX_O_DIRECT) {
4981
 
                os_file_set_nocache(dst_file, dst_path, "OPEN");
4982
 
        }
 
5142
        xb_file_set_nocache(dst_file, dst_path, "OPEN");
4983
5143
 
4984
5144
        printf("Applying %s ...\n", src_path);
4985
5145
 
5063
5223
                incremental_buffers++;
5064
5224
        }
5065
5225
 
5066
 
        if (src_file != -1)
 
5226
        if (src_file != XB_FILE_UNDEFINED)
5067
5227
                os_file_close(src_file);
5068
 
        if (dst_file != -1)
 
5228
        if (dst_file != XB_FILE_UNDEFINED)
5069
5229
                os_file_close(dst_file);
5070
5230
        return;
5071
5231
 
5072
5232
error:
5073
 
        if (src_file != -1)
 
5233
        if (src_file != XB_FILE_UNDEFINED)
5074
5234
                os_file_close(src_file);
5075
 
        if (dst_file != -1)
 
5235
        if (dst_file != XB_FILE_UNDEFINED)
5076
5236
                os_file_close(dst_file);
5077
5237
        fprintf(stderr, "xtrabackup: Error: xtrabackup_apply_delta() failed.\n");
5078
5238
        return;
5188
5348
static my_bool
5189
5349
xtrabackup_close_temp_log(my_bool clear_flag)
5190
5350
{
5191
 
        os_file_t       src_file = -1;
 
5351
        os_file_t       src_file = XB_FILE_UNDEFINED;
5192
5352
        char    src_path[FN_REFLEN];
5193
5353
        char    dst_path[FN_REFLEN];
5194
5354
        ibool   success;
5217
5377
        srv_normalize_path_for_win(dst_path);
5218
5378
        srv_normalize_path_for_win(src_path);
5219
5379
 
5220
 
        success = os_file_rename(
5221
 
#if (MYSQL_VERSION_ID > 50500)
5222
 
                        0 /* dummy of innodb_file_data_key */,
5223
 
#endif
5224
 
                        dst_path, src_path);
 
5380
        success = xb_file_rename(dst_path, src_path);
5225
5381
        if (!success) {
5226
5382
                goto error;
5227
5383
        }
5231
5387
                return(FALSE);
5232
5388
 
5233
5389
        /* clear LOG_FILE_WAS_CREATED_BY_HOT_BACKUP field */
5234
 
        src_file = os_file_create_simple_no_error_handling(
5235
 
#if (MYSQL_VERSION_ID > 50500)
5236
 
                                0 /* dummy of innodb_file_data_key */,
5237
 
#endif
5238
 
                                src_path, OS_FILE_OPEN,
5239
 
                                OS_FILE_READ_WRITE, &success);
 
5390
        src_file = xb_file_create_no_error_handling(src_path, OS_FILE_OPEN,
 
5391
                                                    OS_FILE_READ_WRITE,
 
5392
                                                    &success);
5240
5393
        if (!success) {
5241
5394
                goto error;
5242
5395
        }
5245
5398
        posix_fadvise(src_file, 0, 0, POSIX_FADV_DONTNEED);
5246
5399
#endif
5247
5400
 
5248
 
        if (srv_unix_file_flush_method == SRV_UNIX_O_DIRECT) {
5249
 
                os_file_set_nocache(src_file, src_path, "OPEN");
5250
 
        }
 
5401
        xb_file_set_nocache(src_file, src_path, "OPEN");
5251
5402
 
5252
5403
        log_buf_ = ut_malloc(LOG_FILE_HDR_SIZE * 2);
5253
5404
        log_buf = ut_align(log_buf_, LOG_FILE_HDR_SIZE);
5265
5416
        }
5266
5417
 
5267
5418
        os_file_close(src_file);
5268
 
        src_file = -1;
 
5419
        src_file = XB_FILE_UNDEFINED;
5269
5420
 
5270
5421
        return(FALSE);
5271
5422
error:
5272
 
        if (src_file != -1)
 
5423
        if (src_file != XB_FILE_UNDEFINED)
5273
5424
                os_file_close(src_file);
5274
5425
        if (log_buf_)
5275
5426
                ut_free(log_buf_);
5471
5622
                        fil_system_t*   f_system = fil_system;
5472
5623
                        fil_space_t*    space;
5473
5624
                        fil_node_t*     node;
5474
 
                        os_file_t       info_file = -1;
 
5625
                        os_file_t       info_file = XB_FILE_UNDEFINED;
5475
5626
                        char            info_file_path[FN_REFLEN];
5476
5627
                        ibool           success;
5477
5628
                        char            table_name[FN_REFLEN];
5587
5738
                                        }
5588
5739
 
5589
5740
                                        srv_normalize_path_for_win(info_file_path);
5590
 
                                        info_file = os_file_create(
5591
 
#if (MYSQL_VERSION_ID > 50500)
5592
 
                                                                0 /* dummy of innodb_file_data_key */,
5593
 
#endif
5594
 
                                                                info_file_path, OS_FILE_OVERWRITE,
5595
 
                                                                OS_FILE_NORMAL, OS_DATA_FILE, &success);
 
5741
                                        info_file = xb_file_create(
 
5742
                                                info_file_path,
 
5743
                                                OS_FILE_OVERWRITE,
 
5744
                                                OS_FILE_NORMAL, OS_DATA_FILE,
 
5745
                                                &success);
5596
5746
                                        if (!success) {
5597
5747
                                                os_file_get_last_error(TRUE);
5598
5748
                                                goto next_node;
5609
5759
                                                goto next_node;
5610
5760
                                        }
5611
5761
next_node:
5612
 
                                        if (info_file != -1) {
 
5762
                                        if (info_file != XB_FILE_UNDEFINED) {
5613
5763
                                                os_file_close(info_file);
5614
 
                                                info_file = -1;
 
5764
                                                info_file = XB_FILE_UNDEFINED;
5615
5765
                                        }
5616
5766
                                        mutex_exit(&(dict_sys->mutex));
5617
5767
                                        mutex_enter(&(f_system->mutex));
5756
5906
        int ho_error;
5757
5907
 
5758
5908
        MY_INIT(argv[0]);
 
5909
        xb_regex_init();
5759
5910
 
5760
5911
        load_defaults("my",load_default_groups,&argc,&argv);
5761
5912
 
5824
5975
                        tables_regex_num++;
5825
5976
                }
5826
5977
 
5827
 
                tables_regex = ut_malloc(sizeof(regex_t) * tables_regex_num);
 
5978
                tables_regex = ut_malloc(sizeof(xb_regex_t) * tables_regex_num);
5828
5979
 
5829
5980
                p = xtrabackup_tables;
5830
5981
                for (i=0; i < tables_regex_num; i++) {
5835
5986
                        if (i != tables_regex_num - 1)
5836
5987
                                *(next - 1) = '\0';
5837
5988
 
5838
 
                        regerror(regcomp(&tables_regex[i],p,REG_EXTENDED),
5839
 
                                        &tables_regex[i],errbuf,sizeof(errbuf));
5840
 
                        fprintf(stderr, "xtrabackup: tables regcomp(%s): %s\n",p,errbuf);
 
5989
                        xb_regerror(xb_regcomp(&tables_regex[i], p,
 
5990
                                               REG_EXTENDED),
 
5991
                                    &tables_regex[i], errbuf, sizeof(errbuf));
 
5992
                        fprintf(stderr, "xtrabackup: tables regcomp(%s): %s\n",
 
5993
                                p, errbuf);
5841
5994
 
5842
5995
                        if (i != tables_regex_num - 1)
5843
5996
                                *(next - 1) = ',';
6080
6233
                int i;
6081
6234
 
6082
6235
                for (i = 0; i < tables_regex_num; i++) {
6083
 
                        regfree(&tables_regex[i]);
 
6236
                        xb_regfree(&tables_regex[i]);
6084
6237
                }
6085
6238
                ut_free(tables_regex);
6086
6239
        }
6109
6262
                hash_table_free(tables_hash);
6110
6263
        }
6111
6264
 
 
6265
        xb_regex_end();
 
6266
 
6112
6267
        exit(EXIT_SUCCESS);
6113
6268
}