~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/fil/fil0fil.c

  • Committer: Brian Aker
  • Date: 2010-09-15 20:24:31 UTC
  • mto: (1766.1.1 build)
  • mto: This revision was merged to the branch mainline in revision 1767.
  • Revision ID: brian@tangent.org-20100915202431-wbrrl4vg6rzjvdiu
Adding opt for optional schedulers and making them --plugin-add only.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*****************************************************************************
2
2
 
3
 
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
 
3
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
4
4
 
5
5
This program is free software; you can redistribute it and/or modify it under
6
6
the terms of the GNU General Public License as published by the Free Software
11
11
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12
12
 
13
13
You should have received a copy of the GNU General Public License along with
14
 
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
15
 
St, Fifth Floor, Boston, MA 02110-1301 USA
 
14
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 
15
Place, Suite 330, Boston, MA 02111-1307 USA
16
16
 
17
17
*****************************************************************************/
18
18
 
38
38
#include "mtr0mtr.h"
39
39
#include "mtr0log.h"
40
40
#include "dict0dict.h"
41
 
#include "page0page.h"
42
41
#include "page0zip.h"
43
42
#ifndef UNIV_HOTBACKUP
44
43
# include "buf0lru.h"
121
120
/** The null file address */
122
121
UNIV_INTERN fil_addr_t  fil_addr_null = {FIL_NULL, 0};
123
122
 
124
 
#ifdef UNIV_PFS_MUTEX
125
 
/* Key to register fil_system_mutex with performance schema */
126
 
UNIV_INTERN mysql_pfs_key_t     fil_system_mutex_key;
127
 
#endif /* UNIV_PFS_MUTEX */
128
 
 
129
 
#ifdef UNIV_PFS_RWLOCK
130
 
/* Key to register file space latch with performance schema */
131
 
UNIV_INTERN mysql_pfs_key_t     fil_space_latch_key;
132
 
#endif /* UNIV_PFS_RWLOCK */
133
 
 
134
123
/** File node of a tablespace or the log data space */
135
124
struct fil_node_struct {
136
125
        fil_space_t*    space;  /*!< backpointer to the space where this node
289
278
                                        request */
290
279
        UT_LIST_BASE_NODE_T(fil_space_t) space_list;
291
280
                                        /*!< list of all file spaces */
292
 
        ibool           space_id_reuse_warned;
293
 
                                        /* !< TRUE if fil_space_create()
294
 
                                        has issued a warning about
295
 
                                        potential space_id reuse */
296
281
};
297
282
 
298
283
/** The tablespace memory cache. This variable is NULL before the module is
336
321
/*=======================*/
337
322
        const char*     name);  /*!< in: table name in the standard
338
323
                                'databasename/tablename' format */
339
 
/*******************************************************************//**
340
 
Frees a space object from the tablespace memory cache. Closes the files in
341
 
the chain but does not delete them. There must not be any pending i/o's or
342
 
flushes on the files. */
343
 
static
344
 
ibool
345
 
fil_space_free(
346
 
/*===========*/
347
 
                                /* out: TRUE if success */
348
 
        ulint           id,     /* in: space id */
349
 
        ibool           own_mutex);/* in: TRUE if own system->mutex */
350
324
/********************************************************************//**
351
325
Reads data from a space to a buffer. Remember that the possible incomplete
352
326
blocks at the end of file are ignored: they are not taken into account when
620
594
 
621
595
        UT_LIST_ADD_LAST(chain, space->chain, node);
622
596
 
623
 
        if (id < SRV_LOG_SPACE_FIRST_ID && fil_system->max_assigned_id < id) {
624
 
 
625
 
                fil_system->max_assigned_id = id;
626
 
        }
627
 
 
628
597
        mutex_exit(&fil_system->mutex);
629
598
}
630
599
 
644
613
        ulint           size_high;
645
614
        ibool           ret;
646
615
        ibool           success;
 
616
#ifndef UNIV_HOTBACKUP
647
617
        byte*           buf2;
648
618
        byte*           page;
649
619
        ulint           space_id;
650
620
        ulint           flags;
 
621
#endif /* !UNIV_HOTBACKUP */
651
622
 
652
623
        ut_ad(mutex_own(&(system->mutex)));
653
624
        ut_a(node->n_pending == 0);
663
634
                async I/O! */
664
635
 
665
636
                node->handle = os_file_create_simple_no_error_handling(
666
 
                        innodb_file_data_key, node->name, OS_FILE_OPEN,
667
 
                        OS_FILE_READ_ONLY, &success);
 
637
                        node->name, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success);
668
638
                if (!success) {
669
639
                        /* The following call prints an error message */
670
640
                        os_file_get_last_error(TRUE);
684
654
                size_bytes = (((ib_int64_t)size_high) << 32)
685
655
                        + (ib_int64_t)size_low;
686
656
#ifdef UNIV_HOTBACKUP
687
 
                if (space->id == 0) {
688
 
                        node->size = (ulint) (size_bytes / UNIV_PAGE_SIZE);
689
 
                        os_file_close(node->handle);
690
 
                        goto add_size;
691
 
                }
692
 
#endif /* UNIV_HOTBACKUP */
 
657
                node->size = (ulint) (size_bytes / UNIV_PAGE_SIZE);
 
658
                /* TODO: adjust to zip_size, like below? */
 
659
#else
693
660
                ut_a(space->purpose != FIL_LOG);
694
661
                ut_a(space->id != 0);
695
662
 
768
735
                                (size_bytes
769
736
                                 / dict_table_flags_to_zip_size(flags));
770
737
                }
771
 
 
772
 
#ifdef UNIV_HOTBACKUP
773
 
add_size:
774
 
#endif /* UNIV_HOTBACKUP */
 
738
#endif
775
739
                space->size += node->size;
776
740
        }
777
741
 
782
746
        os_file_create() to fall back to the normal file I/O mode. */
783
747
 
784
748
        if (space->purpose == FIL_LOG) {
785
 
                node->handle = os_file_create(innodb_file_log_key,
786
 
                                              node->name, OS_FILE_OPEN,
787
 
                                              OS_FILE_AIO, OS_LOG_FILE,
788
 
                                              &ret);
 
749
                node->handle = os_file_create(node->name, OS_FILE_OPEN,
 
750
                                              OS_FILE_AIO, OS_LOG_FILE, &ret);
789
751
        } else if (node->is_raw_disk) {
790
 
                node->handle = os_file_create(innodb_file_data_key,
791
 
                                              node->name,
 
752
                node->handle = os_file_create(node->name,
792
753
                                              OS_FILE_OPEN_RAW,
793
 
                                              OS_FILE_AIO, OS_DATA_FILE,
794
 
                                                     &ret);
 
754
                                              OS_FILE_AIO, OS_DATA_FILE, &ret);
795
755
        } else {
796
 
                node->handle = os_file_create(innodb_file_data_key,
797
 
                                              node->name, OS_FILE_OPEN,
798
 
                                              OS_FILE_AIO, OS_DATA_FILE,
799
 
                                              &ret);
 
756
                node->handle = os_file_create(node->name, OS_FILE_OPEN,
 
757
                                              OS_FILE_AIO, OS_DATA_FILE, &ret);
800
758
        }
801
759
 
802
760
        ut_a(ret);
997
955
                        " while the maximum\n"
998
956
                        "InnoDB: allowed value would be %lu.\n"
999
957
                        "InnoDB: You may need to raise the value of"
1000
 
                        " innodb_open_files in\n"
 
958
                        " innodb_max_files_open in\n"
1001
959
                        "InnoDB: my.cnf.\n",
1002
960
                        (ulong) fil_system->n_open,
1003
961
                        (ulong) fil_system->max_n_open);
1119
1077
        fil_space_t*    space;
1120
1078
 
1121
1079
        /* The tablespace flags (FSP_SPACE_FLAGS) should be 0 for
1122
 
        ROW_FORMAT=COMPACT
1123
 
        ((table->flags & ~(~0 << DICT_TF_BITS)) == DICT_TF_COMPACT) and
 
1080
        ROW_FORMAT=COMPACT (table->flags == DICT_TF_COMPACT) and
1124
1081
        ROW_FORMAT=REDUNDANT (table->flags == 0).  For any other
1125
 
        format, the tablespace flags should equal
1126
 
        (table->flags & ~(~0 << DICT_TF_BITS)). */
 
1082
        format, the tablespace flags should equal table->flags. */
1127
1083
        ut_a(flags != DICT_TF_COMPACT);
1128
 
        ut_a(!(flags & (~0UL << DICT_TF_BITS)));
1129
1084
 
1130
1085
try_again:
1131
1086
        /*printf(
1180
1135
 
1181
1136
                mutex_exit(&fil_system->mutex);
1182
1137
 
1183
 
                fil_space_free(namesake_id, FALSE);
 
1138
                fil_space_free(namesake_id);
1184
1139
 
1185
1140
                goto try_again;
1186
1141
        }
1214
1169
        space->tablespace_version = fil_system->tablespace_version;
1215
1170
        space->mark = FALSE;
1216
1171
 
1217
 
        if (UNIV_LIKELY(purpose == FIL_TABLESPACE && !recv_recovery_on)
1218
 
            && UNIV_UNLIKELY(id > fil_system->max_assigned_id)) {
1219
 
                if (!fil_system->space_id_reuse_warned) {
1220
 
                        fil_system->space_id_reuse_warned = TRUE;
1221
 
 
1222
 
                        ut_print_timestamp(stderr);
1223
 
                        fprintf(stderr,
1224
 
                                "  InnoDB: Warning: allocated tablespace %lu,"
1225
 
                                " old maximum was %lu\n",
1226
 
                                (ulong) id,
1227
 
                                (ulong) fil_system->max_assigned_id);
1228
 
                }
1229
 
 
 
1172
        if (purpose == FIL_TABLESPACE && id > fil_system->max_assigned_id) {
1230
1173
                fil_system->max_assigned_id = id;
1231
1174
        }
1232
1175
 
1245
1188
        UT_LIST_INIT(space->chain);
1246
1189
        space->magic_n = FIL_SPACE_MAGIC_N;
1247
1190
 
1248
 
        rw_lock_create(fil_space_latch_key, &space->latch, SYNC_FSP);
 
1191
        rw_lock_create(&space->latch, SYNC_FSP);
1249
1192
 
1250
1193
        HASH_INSERT(fil_space_t, hash, fil_system->spaces, id, space);
1251
1194
 
1264
1207
Assigns a new space id for a new single-table tablespace. This works simply by
1265
1208
incrementing the global counter. If 4 billion id's is not enough, we may need
1266
1209
to recycle id's.
1267
 
@return TRUE if assigned, FALSE if not */
1268
 
UNIV_INTERN
1269
 
ibool
1270
 
fil_assign_new_space_id(
1271
 
/*====================*/
1272
 
        ulint*  space_id)       /*!< in/out: space id */
 
1210
@return new tablespace id; ULINT_UNDEFINED if could not assign an id */
 
1211
static
 
1212
ulint
 
1213
fil_assign_new_space_id(void)
 
1214
/*=========================*/
1273
1215
{
1274
 
        ulint   id;
1275
 
        ibool   success;
 
1216
        ulint           id;
1276
1217
 
1277
1218
        mutex_enter(&fil_system->mutex);
1278
1219
 
1279
 
        id = *space_id;
1280
 
 
1281
 
        if (id < fil_system->max_assigned_id) {
1282
 
                id = fil_system->max_assigned_id;
1283
 
        }
1284
 
 
1285
 
        id++;
 
1220
        fil_system->max_assigned_id++;
 
1221
 
 
1222
        id = fil_system->max_assigned_id;
1286
1223
 
1287
1224
        if (id > (SRV_LOG_SPACE_FIRST_ID / 2) && (id % 1000000UL == 0)) {
1288
1225
                ut_print_timestamp(stderr);
1298
1235
                        (ulong) SRV_LOG_SPACE_FIRST_ID);
1299
1236
        }
1300
1237
 
1301
 
        success = (id < SRV_LOG_SPACE_FIRST_ID);
1302
 
 
1303
 
        if (success) {
1304
 
                *space_id = fil_system->max_assigned_id = id;
1305
 
        } else {
 
1238
        if (id >= SRV_LOG_SPACE_FIRST_ID) {
1306
1239
                ut_print_timestamp(stderr);
1307
1240
                fprintf(stderr,
1308
1241
                        "InnoDB: You have run out of single-table"
1312
1245
                        " have to dump all your tables and\n"
1313
1246
                        "InnoDB: recreate the whole InnoDB installation.\n",
1314
1247
                        (ulong) id);
1315
 
                *space_id = ULINT_UNDEFINED;
 
1248
                fil_system->max_assigned_id--;
 
1249
 
 
1250
                id = ULINT_UNDEFINED;
1316
1251
        }
1317
1252
 
1318
1253
        mutex_exit(&fil_system->mutex);
1319
1254
 
1320
 
        return(success);
 
1255
        return(id);
1321
1256
}
1322
1257
 
1323
1258
/*******************************************************************//**
1325
1260
the chain but does not delete them. There must not be any pending i/o's or
1326
1261
flushes on the files.
1327
1262
@return TRUE if success */
1328
 
static
 
1263
UNIV_INTERN
1329
1264
ibool
1330
1265
fil_space_free(
1331
1266
/*===========*/
1332
 
                                        /* out: TRUE if success */
1333
 
        ulint           id,             /* in: space id */
1334
 
        ibool           own_mutex)      /* in: TRUE if own system->mutex */
 
1267
        ulint   id)     /*!< in: space id */
1335
1268
{
1336
1269
        fil_space_t*    space;
1337
1270
        fil_space_t*    namespace;
1338
1271
        fil_node_t*     fil_node;
1339
1272
 
1340
 
        if (!own_mutex) {
1341
 
                mutex_enter(&fil_system->mutex);
1342
 
        }
 
1273
        mutex_enter(&fil_system->mutex);
1343
1274
 
1344
1275
        space = fil_space_get_by_id(id);
1345
1276
 
1386
1317
 
1387
1318
        ut_a(0 == UT_LIST_GET_LEN(space->chain));
1388
1319
 
1389
 
        if (!own_mutex) {
1390
 
                mutex_exit(&fil_system->mutex);
1391
 
        }
 
1320
        mutex_exit(&fil_system->mutex);
1392
1321
 
1393
1322
        rw_lock_free(&(space->latch));
1394
1323
 
1553
1482
        ut_a(hash_size > 0);
1554
1483
        ut_a(max_n_open > 0);
1555
1484
 
1556
 
        fil_system = mem_zalloc(sizeof(fil_system_t));
 
1485
        fil_system = mem_alloc(sizeof(fil_system_t));
1557
1486
 
1558
 
        mutex_create(fil_system_mutex_key,
1559
 
                     &fil_system->mutex, SYNC_ANY_LATCH);
 
1487
        mutex_create(&fil_system->mutex, SYNC_ANY_LATCH);
1560
1488
 
1561
1489
        fil_system->spaces = hash_create(hash_size);
1562
1490
        fil_system->name_hash = hash_create(hash_size);
1563
1491
 
1564
1492
        UT_LIST_INIT(fil_system->LRU);
1565
1493
 
 
1494
        fil_system->n_open = 0;
1566
1495
        fil_system->max_n_open = max_n_open;
 
1496
 
 
1497
        fil_system->modification_counter = 0;
 
1498
        fil_system->max_assigned_id = 0;
 
1499
 
 
1500
        fil_system->tablespace_version = 0;
 
1501
 
 
1502
        UT_LIST_INIT(fil_system->unflushed_spaces);
 
1503
        UT_LIST_INIT(fil_system->space_list);
1567
1504
}
1568
1505
 
1569
1506
/*******************************************************************//**
1598
1535
                                        fprintf(stderr,
1599
1536
                                                "InnoDB: Warning: you must"
1600
1537
                                                " raise the value of"
1601
 
                                                " innodb_open_files in\n"
 
1538
                                                " innodb_max_open_files in\n"
1602
1539
                                                "InnoDB: my.cnf! Remember that"
1603
1540
                                                " InnoDB keeps all log files"
1604
1541
                                                " and all system\n"
1640
1577
        space = UT_LIST_GET_FIRST(fil_system->space_list);
1641
1578
 
1642
1579
        while (space != NULL) {
1643
 
                fil_space_t*    prev_space = space;
1644
 
 
1645
1580
                node = UT_LIST_GET_FIRST(space->chain);
1646
1581
 
1647
1582
                while (node != NULL) {
1651
1586
                        node = UT_LIST_GET_NEXT(chain, node);
1652
1587
                }
1653
1588
                space = UT_LIST_GET_NEXT(space_list, space);
1654
 
                fil_space_free(prev_space->id, TRUE);
1655
1589
        }
1656
1590
 
1657
1591
        mutex_exit(&fil_system->mutex);
1705
1639
 
1706
1640
        fil_read(TRUE, 0, 0, sum_of_sizes, 0, UNIV_PAGE_SIZE, buf, NULL);
1707
1641
 
1708
 
        mach_write_to_8(buf + FIL_PAGE_FILE_FLUSH_LSN, lsn);
 
1642
        mach_write_ull(buf + FIL_PAGE_FILE_FLUSH_LSN, lsn);
1709
1643
 
1710
1644
        fil_write(TRUE, 0, 0, sum_of_sizes, 0, UNIV_PAGE_SIZE, buf, NULL);
1711
1645
 
1799
1733
 
1800
1734
        os_file_read(data_file, buf, 0, 0, UNIV_PAGE_SIZE);
1801
1735
 
1802
 
        flushed_lsn = mach_read_from_8(buf + FIL_PAGE_FILE_FLUSH_LSN);
 
1736
        flushed_lsn = mach_read_ull(buf + FIL_PAGE_FILE_FLUSH_LSN);
1803
1737
 
1804
1738
        ut_free(buf2);
1805
1739
 
2148
2082
                        fil_create_directory_for_tablename(name);
2149
2083
 
2150
2084
                        if (fil_create_new_single_table_tablespace(
2151
 
                                    space_id, name, FALSE, flags,
 
2085
                                    &space_id, name, FALSE, flags,
2152
2086
                                    FIL_IBD_FILE_INITIAL_SIZE) != DB_SUCCESS) {
2153
2087
                                ut_error;
2154
2088
                        }
2283
2217
#endif
2284
2218
        /* printf("Deleting tablespace %s id %lu\n", space->name, id); */
2285
2219
 
2286
 
        success = fil_space_free(id, FALSE);
 
2220
        success = fil_space_free(id);
2287
2221
 
2288
2222
        if (success) {
2289
2223
                success = os_file_delete(path);
2552
2486
        success = fil_rename_tablespace_in_mem(space, node, path);
2553
2487
 
2554
2488
        if (success) {
2555
 
                success = os_file_rename(innodb_file_data_key, old_path, path);
 
2489
                success = os_file_rename(old_path, path);
2556
2490
 
2557
2491
                if (!success) {
2558
2492
                        /* We have to revert the changes we made
2595
2529
ulint
2596
2530
fil_create_new_single_table_tablespace(
2597
2531
/*===================================*/
2598
 
        ulint           space_id,       /*!< in: space id */
 
2532
        ulint*          space_id,       /*!< in/out: space id; if this is != 0,
 
2533
                                        then this is an input parameter,
 
2534
                                        otherwise output */
2599
2535
        const char*     tablename,      /*!< in: the table name in the usual
2600
2536
                                        databasename/tablename format
2601
2537
                                        of InnoDB, or a dir path to a temp
2615
2551
        ibool           success;
2616
2552
        char*           path;
2617
2553
 
2618
 
        ut_a(space_id > 0);
2619
 
        ut_a(space_id < SRV_LOG_SPACE_FIRST_ID);
2620
2554
        ut_a(size >= FIL_IBD_FILE_INITIAL_SIZE);
2621
2555
        /* The tablespace flags (FSP_SPACE_FLAGS) should be 0 for
2622
 
        ROW_FORMAT=COMPACT
2623
 
        ((table->flags & ~(~0 << DICT_TF_BITS)) == DICT_TF_COMPACT) and
 
2556
        ROW_FORMAT=COMPACT (table->flags == DICT_TF_COMPACT) and
2624
2557
        ROW_FORMAT=REDUNDANT (table->flags == 0).  For any other
2625
 
        format, the tablespace flags should equal
2626
 
        (table->flags & ~(~0 << DICT_TF_BITS)). */
 
2558
        format, the tablespace flags should equal table->flags. */
2627
2559
        ut_a(flags != DICT_TF_COMPACT);
2628
 
        ut_a(!(flags & (~0UL << DICT_TF_BITS)));
2629
2560
 
2630
2561
        path = fil_make_ibd_name(tablename, is_temp);
2631
2562
 
2632
 
        file = os_file_create(innodb_file_data_key, path,
2633
 
                              OS_FILE_CREATE, OS_FILE_NORMAL,
 
2563
        file = os_file_create(path, OS_FILE_CREATE, OS_FILE_NORMAL,
2634
2564
                              OS_DATA_FILE, &ret);
2635
2565
        if (ret == FALSE) {
2636
2566
                ut_print_timestamp(stderr);
2674
2604
                return(DB_ERROR);
2675
2605
        }
2676
2606
 
 
2607
        buf2 = ut_malloc(3 * UNIV_PAGE_SIZE);
 
2608
        /* Align the memory for file i/o if we might have O_DIRECT set */
 
2609
        page = ut_align(buf2, UNIV_PAGE_SIZE);
 
2610
 
2677
2611
        ret = os_file_set_size(path, file, size * UNIV_PAGE_SIZE, 0);
2678
2612
 
2679
2613
        if (!ret) {
2680
 
                err = DB_OUT_OF_FILE_SPACE;
 
2614
                ut_free(buf2);
 
2615
                os_file_close(file);
 
2616
                os_file_delete(path);
 
2617
 
 
2618
                mem_free(path);
 
2619
                return(DB_OUT_OF_FILE_SPACE);
 
2620
        }
 
2621
 
 
2622
        if (*space_id == 0) {
 
2623
                *space_id = fil_assign_new_space_id();
 
2624
        }
 
2625
 
 
2626
        /* printf("Creating tablespace %s id %lu\n", path, *space_id); */
 
2627
 
 
2628
        if (*space_id == ULINT_UNDEFINED) {
 
2629
                ut_free(buf2);
2681
2630
error_exit:
2682
2631
                os_file_close(file);
2683
2632
error_exit2:
2684
2633
                os_file_delete(path);
2685
2634
 
2686
2635
                mem_free(path);
2687
 
                return(err);
 
2636
                return(DB_ERROR);
2688
2637
        }
2689
2638
 
2690
 
        /* printf("Creating tablespace %s id %lu\n", path, space_id); */
2691
 
 
2692
2639
        /* We have to write the space id to the file immediately and flush the
2693
2640
        file to disk. This is because in crash recovery we must be aware what
2694
2641
        tablespaces exist and what are their space id's, so that we can apply
2698
2645
        with zeros from the call of os_file_set_size(), until a buffer pool
2699
2646
        flush would write to it. */
2700
2647
 
2701
 
        buf2 = ut_malloc(3 * UNIV_PAGE_SIZE);
2702
 
        /* Align the memory for file i/o if we might have O_DIRECT set */
2703
 
        page = ut_align(buf2, UNIV_PAGE_SIZE);
2704
 
 
2705
2648
        memset(page, '\0', UNIV_PAGE_SIZE);
2706
2649
 
2707
 
        fsp_header_init_fields(page, space_id, flags);
2708
 
        mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, space_id);
 
2650
        fsp_header_init_fields(page, *space_id, flags);
 
2651
        mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, *space_id);
2709
2652
 
2710
2653
        if (!(flags & DICT_TF_ZSSIZE_MASK)) {
2711
2654
                buf_flush_init_for_writing(page, NULL, 0);
2736
2679
                      " to tablespace ", stderr);
2737
2680
                ut_print_filename(stderr, path);
2738
2681
                putc('\n', stderr);
2739
 
                err = DB_ERROR;
2740
2682
                goto error_exit;
2741
2683
        }
2742
2684
 
2746
2688
                fputs("InnoDB: Error: file flush of tablespace ", stderr);
2747
2689
                ut_print_filename(stderr, path);
2748
2690
                fputs(" failed\n", stderr);
2749
 
                err = DB_ERROR;
2750
2691
                goto error_exit;
2751
2692
        }
2752
2693
 
2753
2694
        os_file_close(file);
2754
2695
 
2755
 
        success = fil_space_create(path, space_id, flags, FIL_TABLESPACE);
 
2696
        if (*space_id == ULINT_UNDEFINED) {
 
2697
                goto error_exit2;
 
2698
        }
 
2699
 
 
2700
        success = fil_space_create(path, *space_id, flags, FIL_TABLESPACE);
2756
2701
 
2757
2702
        if (!success) {
2758
 
                err = DB_ERROR;
2759
2703
                goto error_exit2;
2760
2704
        }
2761
2705
 
2762
 
        fil_node_create(path, size, space_id, FALSE);
 
2706
        fil_node_create(path, size, *space_id, FALSE);
2763
2707
 
2764
2708
#ifndef UNIV_HOTBACKUP
2765
2709
        {
2770
2714
                fil_op_write_log(flags
2771
2715
                                 ? MLOG_FILE_CREATE2
2772
2716
                                 : MLOG_FILE_CREATE,
2773
 
                                 space_id,
 
2717
                                 *space_id,
2774
2718
                                 is_temp ? MLOG_FILE_FLAG_TEMP : 0,
2775
2719
                                 flags,
2776
2720
                                 tablename, NULL, &mtr);
2813
2757
        ib_int64_t      offset;
2814
2758
        ulint           zip_size;
2815
2759
        ibool           success;
2816
 
        page_zip_des_t  page_zip;
2817
2760
 
2818
2761
        filepath = fil_make_ibd_name(name, FALSE);
2819
2762
 
2820
2763
        file = os_file_create_simple_no_error_handling(
2821
 
                innodb_file_data_key, filepath, OS_FILE_OPEN,
2822
 
                OS_FILE_READ_WRITE, &success);
 
2764
                filepath, OS_FILE_OPEN, OS_FILE_READ_WRITE, &success);
2823
2765
        if (!success) {
2824
2766
                /* The following call prints an error message */
2825
2767
                os_file_get_last_error(TRUE);
2850
2792
 
2851
2793
        /* We have to read the file flush lsn from the header of the file */
2852
2794
 
2853
 
        flush_lsn = mach_read_from_8(page + FIL_PAGE_FILE_FLUSH_LSN);
 
2795
        flush_lsn = mach_read_ull(page + FIL_PAGE_FILE_FLUSH_LSN);
2854
2796
 
2855
2797
        if (current_lsn >= flush_lsn) {
2856
2798
                /* Ok */
2862
2804
        space_id = fsp_header_get_space_id(page);
2863
2805
        zip_size = fsp_header_get_zip_size(page);
2864
2806
 
2865
 
        page_zip_des_init(&page_zip);
2866
 
        page_zip_set_size(&page_zip, zip_size);
2867
 
        if (zip_size) {
2868
 
                page_zip.data = page + UNIV_PAGE_SIZE;
2869
 
        }
2870
 
 
2871
2807
        ut_print_timestamp(stderr);
2872
2808
        fprintf(stderr,
2873
2809
                "  InnoDB: Flush lsn in the tablespace file %lu"
2898
2834
 
2899
2835
                        goto func_exit;
2900
2836
                }
2901
 
                if (mach_read_from_8(page + FIL_PAGE_LSN) > current_lsn) {
 
2837
                if (mach_read_ull(page + FIL_PAGE_LSN) > current_lsn) {
2902
2838
                        /* We have to reset the lsn */
2903
2839
 
2904
2840
                        if (zip_size) {
2905
 
                                memcpy(page_zip.data, page, zip_size);
 
2841
                                memcpy(page + UNIV_PAGE_SIZE, page, zip_size);
2906
2842
                                buf_flush_init_for_writing(
2907
 
                                        page, &page_zip, current_lsn);
2908
 
                                success = os_file_write(
2909
 
                                        filepath, file, page_zip.data,
2910
 
                                        (ulint) offset & 0xFFFFFFFFUL,
2911
 
                                        (ulint) (offset >> 32), zip_size);
 
2843
                                        page, page + UNIV_PAGE_SIZE,
 
2844
                                        current_lsn);
2912
2845
                        } else {
2913
2846
                                buf_flush_init_for_writing(
2914
2847
                                        page, NULL, current_lsn);
2915
 
                                success = os_file_write(
2916
 
                                        filepath, file, page,
2917
 
                                        (ulint)(offset & 0xFFFFFFFFUL),
2918
 
                                        (ulint)(offset >> 32),
2919
 
                                        UNIV_PAGE_SIZE);
2920
2848
                        }
2921
 
 
 
2849
                        success = os_file_write(filepath, file, page,
 
2850
                                                (ulint)(offset & 0xFFFFFFFFUL),
 
2851
                                                (ulint)(offset >> 32),
 
2852
                                                zip_size
 
2853
                                                ? zip_size
 
2854
                                                : UNIV_PAGE_SIZE);
2922
2855
                        if (!success) {
2923
2856
 
2924
2857
                                goto func_exit;
2940
2873
                goto func_exit;
2941
2874
        }
2942
2875
 
2943
 
        mach_write_to_8(page + FIL_PAGE_FILE_FLUSH_LSN, current_lsn);
 
2876
        mach_write_ull(page + FIL_PAGE_FILE_FLUSH_LSN, current_lsn);
2944
2877
 
2945
2878
        success = os_file_write(filepath, file, page, 0, 0,
2946
2879
                                zip_size ? zip_size : UNIV_PAGE_SIZE);
2990
2923
        byte*           page;
2991
2924
        ulint           space_id;
2992
2925
        ulint           space_flags;
 
2926
        ibool           ret             = TRUE;
2993
2927
 
2994
2928
        filepath = fil_make_ibd_name(name, FALSE);
2995
2929
 
2996
2930
        /* The tablespace flags (FSP_SPACE_FLAGS) should be 0 for
2997
 
        ROW_FORMAT=COMPACT
2998
 
        ((table->flags & ~(~0 << DICT_TF_BITS)) == DICT_TF_COMPACT) and
 
2931
        ROW_FORMAT=COMPACT (table->flags == DICT_TF_COMPACT) and
2999
2932
        ROW_FORMAT=REDUNDANT (table->flags == 0).  For any other
3000
 
        format, the tablespace flags should equal
3001
 
        (table->flags & ~(~0 << DICT_TF_BITS)). */
 
2933
        format, the tablespace flags should equal table->flags. */
3002
2934
        ut_a(flags != DICT_TF_COMPACT);
3003
 
        ut_a(!(flags & (~0UL << DICT_TF_BITS)));
3004
2935
 
3005
2936
        file = os_file_create_simple_no_error_handling(
3006
 
                innodb_file_data_key, filepath, OS_FILE_OPEN,
3007
 
                OS_FILE_READ_ONLY, &success);
 
2937
                filepath, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success);
3008
2938
        if (!success) {
3009
2939
                /* The following call prints an error message */
3010
2940
                os_file_get_last_error(TRUE);
3053
2983
 
3054
2984
        ut_free(buf2);
3055
2985
 
3056
 
        if (UNIV_UNLIKELY(space_id != id
3057
 
                          || space_flags != (flags & ~(~0 << DICT_TF_BITS)))) {
 
2986
        if (UNIV_UNLIKELY(space_id != id || space_flags != flags)) {
3058
2987
                ut_print_timestamp(stderr);
3059
2988
 
3060
2989
                fputs("  InnoDB: Error: tablespace id and flags in file ",
3072
3001
                        (ulong) space_id, (ulong) space_flags,
3073
3002
                        (ulong) id, (ulong) flags);
3074
3003
 
3075
 
                success = FALSE;
 
3004
                ret = FALSE;
3076
3005
 
3077
3006
                goto func_exit;
3078
3007
        }
3092
3021
        os_file_close(file);
3093
3022
        mem_free(filepath);
3094
3023
 
3095
 
        return(success);
 
3024
        return(ret);
3096
3025
}
3097
3026
#endif /* !UNIV_HOTBACKUP */
3098
3027
 
3160
3089
# endif /* !UNIV_HOTBACKUP */
3161
3090
#endif
3162
3091
        file = os_file_create_simple_no_error_handling(
3163
 
                innodb_file_data_key, filepath, OS_FILE_OPEN,
3164
 
                OS_FILE_READ_ONLY, &success);
 
3092
                filepath, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success);
3165
3093
        if (!success) {
3166
3094
                /* The following call prints an error message */
3167
3095
                os_file_get_last_error(TRUE);
3309
3237
                fprintf(stderr,
3310
3238
                        "InnoDB: Renaming tablespace %s of id %lu,\n"
3311
3239
                        "InnoDB: to %s_ibbackup_old_vers_<timestamp>\n"
3312
 
                        "InnoDB: because its size %" PRId64 " is too small"
 
3240
                        "InnoDB: because its size %lld is too small"
3313
3241
                        " (< 4 pages 16 kB each),\n"
3314
3242
                        "InnoDB: or the space id in the file header"
3315
3243
                        " is not sensible.\n"
3319
3247
                os_file_close(file);
3320
3248
 
3321
3249
                new_path = fil_make_ibbackup_old_name(filepath);
3322
 
                ut_a(os_file_rename(innodb_file_data_key, filepath, new_path));
 
3250
                ut_a(os_file_rename(filepath, new_path));
3323
3251
 
3324
3252
                ut_free(buf2);
3325
3253
                mem_free(filepath);
3357
3285
 
3358
3286
                mutex_exit(&fil_system->mutex);
3359
3287
 
3360
 
                ut_a(os_file_rename(innodb_file_data_key, filepath, new_path));
 
3288
                ut_a(os_file_rename(filepath, new_path));
3361
3289
 
3362
3290
                ut_free(buf2);
3363
3291
                mem_free(filepath);
3371
3299
 
3372
3300
        if (!success) {
3373
3301
 
3374
 
                if (srv_force_recovery > 0) {
3375
 
                        fprintf(stderr,
3376
 
                                "InnoDB: innodb_force_recovery"
3377
 
                                " was set to %lu. Continuing crash recovery\n"
3378
 
                                "InnoDB: even though the tablespace creation"
3379
 
                                " of this table failed.\n",
3380
 
                                srv_force_recovery);
3381
 
                        goto func_exit;
3382
 
                }
3383
 
 
3384
 
                exit(1);
 
3302
                goto func_exit;
3385
3303
        }
3386
3304
 
3387
3305
        /* We do not use the size information we have about the file, because
3564
3482
        return(err);
3565
3483
}
3566
3484
 
 
3485
/********************************************************************//**
 
3486
If we need crash recovery, and we have called
 
3487
fil_load_single_table_tablespaces() and dict_load_single_table_tablespaces(),
 
3488
we can call this function to print an error message of orphaned .ibd files
 
3489
for which there is not a data dictionary entry with a matching table name
 
3490
and space id. */
 
3491
UNIV_INTERN
 
3492
void
 
3493
fil_print_orphaned_tablespaces(void)
 
3494
/*================================*/
 
3495
{
 
3496
        fil_space_t*    space;
 
3497
 
 
3498
        mutex_enter(&fil_system->mutex);
 
3499
 
 
3500
        space = UT_LIST_GET_FIRST(fil_system->space_list);
 
3501
 
 
3502
        while (space) {
 
3503
                if (space->purpose == FIL_TABLESPACE && space->id != 0
 
3504
                    && !space->mark) {
 
3505
                        fputs("InnoDB: Warning: tablespace ", stderr);
 
3506
                        ut_print_filename(stderr, space->name);
 
3507
                        fprintf(stderr, " of id %lu has no matching table in\n"
 
3508
                                "InnoDB: the InnoDB data dictionary.\n",
 
3509
                                (ulong) space->id);
 
3510
                }
 
3511
 
 
3512
                space = UT_LIST_GET_NEXT(space_list, space);
 
3513
        }
 
3514
 
 
3515
        mutex_exit(&fil_system->mutex);
 
3516
}
 
3517
 
3567
3518
/*******************************************************************//**
3568
3519
Returns TRUE if a single-table tablespace does not exist in the memory cache,
3569
3520
or is being deleted there.
4446
4397
 
4447
4398
        ut_ad(fil_validate());
4448
4399
 
4449
 
        if (srv_use_native_aio) {
 
4400
        if (os_aio_use_native_aio) {
4450
4401
                srv_set_io_thread_op_info(segment, "native aio handle");
4451
4402
#ifdef WIN_ASYNC_IO
4452
4403
                ret = os_aio_windows_handle(segment, 0, &fil_node,
4453
4404
                                            &message, &type);
4454
 
#elif defined(LINUX_NATIVE_AIO)
4455
 
                ret = os_aio_linux_handle(segment, &fil_node,
4456
 
                                          &message, &type);
4457
4405
#else
4458
4406
                ret = 0; /* Eliminate compiler warning */
4459
4407
                ut_error;
4787
4735
 
4788
4736
        return(mach_read_from_2(page + FIL_PAGE_TYPE));
4789
4737
}
4790
 
 
4791
 
/********************************************************************
4792
 
Initializes the tablespace memory cache. */
4793
 
UNIV_INTERN
4794
 
void
4795
 
fil_close(void)
4796
 
/*===========*/
4797
 
{
4798
 
#ifndef UNIV_HOTBACKUP
4799
 
        /* The mutex should already have been freed. */
4800
 
        ut_ad(fil_system->mutex.magic_n == 0);
4801
 
#endif /* !UNIV_HOTBACKUP */
4802
 
 
4803
 
        hash_table_free(fil_system->spaces);
4804
 
 
4805
 
        hash_table_free(fil_system->name_hash);
4806
 
 
4807
 
        ut_a(UT_LIST_GET_LEN(fil_system->LRU) == 0);
4808
 
        ut_a(UT_LIST_GET_LEN(fil_system->unflushed_spaces) == 0);
4809
 
        ut_a(UT_LIST_GET_LEN(fil_system->space_list) == 0);
4810
 
 
4811
 
        mem_free(fil_system);
4812
 
 
4813
 
        fil_system = NULL;
4814
 
}