121
121
/** The null file address */
122
122
UNIV_INTERN fil_addr_t fil_addr_null = {FIL_NULL, 0};
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 */
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 */
124
134
/** File node of a tablespace or the log data space */
125
135
struct fil_node_struct {
126
136
fil_space_t* space; /*!< backpointer to the space where this node
280
290
UT_LIST_BASE_NODE_T(fil_space_t) space_list;
281
291
/*!< list of all file spaces */
282
ibool space_id_reuse_warned;
283
/* !< TRUE if fil_space_create()
284
has issued a warning about
285
potential space_id reuse */
288
294
/** The tablespace memory cache. This variable is NULL before the module is
655
661
node->handle = os_file_create_simple_no_error_handling(
656
node->name, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success);
662
innodb_file_data_key, node->name, OS_FILE_OPEN,
663
OS_FILE_READ_ONLY, &success);
658
665
/* The following call prints an error message */
659
666
os_file_get_last_error(TRUE);
771
778
os_file_create() to fall back to the normal file I/O mode. */
773
780
if (space->purpose == FIL_LOG) {
774
node->handle = os_file_create(node->name, OS_FILE_OPEN,
775
OS_FILE_AIO, OS_LOG_FILE, &ret);
781
node->handle = os_file_create(innodb_file_log_key,
782
node->name, OS_FILE_OPEN,
783
OS_FILE_AIO, OS_LOG_FILE,
776
785
} else if (node->is_raw_disk) {
777
node->handle = os_file_create(node->name,
786
node->handle = os_file_create(innodb_file_data_key,
778
788
OS_FILE_OPEN_RAW,
779
OS_FILE_AIO, OS_DATA_FILE, &ret);
789
OS_FILE_AIO, OS_DATA_FILE,
781
node->handle = os_file_create(node->name, OS_FILE_OPEN,
782
OS_FILE_AIO, OS_DATA_FILE, &ret);
792
node->handle = os_file_create(innodb_file_data_key,
793
node->name, OS_FILE_OPEN,
794
OS_FILE_AIO, OS_DATA_FILE,
1197
1210
space->tablespace_version = fil_system->tablespace_version;
1198
1211
space->mark = FALSE;
1200
if (UNIV_LIKELY(purpose == FIL_TABLESPACE && !recv_recovery_on)
1201
&& UNIV_UNLIKELY(id > fil_system->max_assigned_id)) {
1202
if (!fil_system->space_id_reuse_warned) {
1203
fil_system->space_id_reuse_warned = TRUE;
1205
ut_print_timestamp(stderr);
1207
" InnoDB: Warning: allocated tablespace %lu,"
1208
" old maximum was %lu\n",
1210
(ulong) fil_system->max_assigned_id);
1213
if (purpose == FIL_TABLESPACE && id > fil_system->max_assigned_id) {
1213
1214
fil_system->max_assigned_id = id;
1228
1229
UT_LIST_INIT(space->chain);
1229
1230
space->magic_n = FIL_SPACE_MAGIC_N;
1231
rw_lock_create(&space->latch, SYNC_FSP);
1232
rw_lock_create(fil_space_latch_key, &space->latch, SYNC_FSP);
1233
1234
HASH_INSERT(fil_space_t, hash, fil_system->spaces, id, space);
1247
1248
Assigns a new space id for a new single-table tablespace. This works simply by
1248
1249
incrementing the global counter. If 4 billion id's is not enough, we may need
1249
1250
to recycle id's.
1250
@return TRUE if assigned, FALSE if not */
1253
fil_assign_new_space_id(
1254
/*====================*/
1255
ulint* space_id) /*!< in/out: space id */
1251
@return new tablespace id; ULINT_UNDEFINED if could not assign an id */
1254
fil_assign_new_space_id(void)
1255
/*=========================*/
1260
1259
mutex_enter(&fil_system->mutex);
1264
if (id < fil_system->max_assigned_id) {
1265
id = fil_system->max_assigned_id;
1261
fil_system->max_assigned_id++;
1263
id = fil_system->max_assigned_id;
1270
1265
if (id > (SRV_LOG_SPACE_FIRST_ID / 2) && (id % 1000000UL == 0)) {
1271
1266
ut_print_timestamp(stderr);
1281
1276
(ulong) SRV_LOG_SPACE_FIRST_ID);
1284
success = (id < SRV_LOG_SPACE_FIRST_ID);
1287
*space_id = fil_system->max_assigned_id = id;
1279
if (id >= SRV_LOG_SPACE_FIRST_ID) {
1289
1280
ut_print_timestamp(stderr);
1290
1281
fprintf(stderr,
1291
1282
"InnoDB: You have run out of single-table"
1295
1286
" have to dump all your tables and\n"
1296
1287
"InnoDB: recreate the whole InnoDB installation.\n",
1298
*space_id = ULINT_UNDEFINED;
1289
fil_system->max_assigned_id--;
1291
id = ULINT_UNDEFINED;
1301
1294
mutex_exit(&fil_system->mutex);
1306
1299
/*******************************************************************//**
1536
1529
ut_a(hash_size > 0);
1537
1530
ut_a(max_n_open > 0);
1539
fil_system = mem_zalloc(sizeof(fil_system_t));
1532
fil_system = mem_alloc(sizeof(fil_system_t));
1541
mutex_create(&fil_system->mutex, SYNC_ANY_LATCH);
1534
mutex_create(fil_system_mutex_key,
1535
&fil_system->mutex, SYNC_ANY_LATCH);
1543
1537
fil_system->spaces = hash_create(hash_size);
1544
1538
fil_system->name_hash = hash_create(hash_size);
1546
1540
UT_LIST_INIT(fil_system->LRU);
1542
fil_system->n_open = 0;
1548
1543
fil_system->max_n_open = max_n_open;
1545
fil_system->modification_counter = 0;
1546
fil_system->max_assigned_id = 0;
1548
fil_system->tablespace_version = 0;
1550
UT_LIST_INIT(fil_system->unflushed_spaces);
1551
UT_LIST_INIT(fil_system->space_list);
1551
1554
/*******************************************************************//**
2130
2133
fil_create_directory_for_tablename(name);
2132
2135
if (fil_create_new_single_table_tablespace(
2133
space_id, name, FALSE, flags,
2136
&space_id, name, FALSE, flags,
2134
2137
FIL_IBD_FILE_INITIAL_SIZE) != DB_SUCCESS) {
2534
2537
success = fil_rename_tablespace_in_mem(space, node, path);
2537
success = os_file_rename(old_path, path);
2540
success = os_file_rename(innodb_file_data_key, old_path, path);
2539
2542
if (!success) {
2540
2543
/* We have to revert the changes we made
2578
2581
fil_create_new_single_table_tablespace(
2579
2582
/*===================================*/
2580
ulint space_id, /*!< in: space id */
2583
ulint* space_id, /*!< in/out: space id; if this is != 0,
2584
then this is an input parameter,
2581
2586
const char* tablename, /*!< in: the table name in the usual
2582
2587
databasename/tablename format
2583
2588
of InnoDB, or a dir path to a temp
2612
2615
path = fil_make_ibd_name(tablename, is_temp);
2614
file = os_file_create(path, OS_FILE_CREATE, OS_FILE_NORMAL,
2617
file = os_file_create(innodb_file_data_key, path,
2618
OS_FILE_CREATE, OS_FILE_NORMAL,
2615
2619
OS_DATA_FILE, &ret);
2616
2620
if (ret == FALSE) {
2617
2621
ut_print_timestamp(stderr);
2655
2659
return(DB_ERROR);
2662
buf2 = ut_malloc(3 * UNIV_PAGE_SIZE);
2663
/* Align the memory for file i/o if we might have O_DIRECT set */
2664
page = ut_align(buf2, UNIV_PAGE_SIZE);
2658
2666
ret = os_file_set_size(path, file, size * UNIV_PAGE_SIZE, 0);
2661
err = DB_OUT_OF_FILE_SPACE;
2670
os_file_close(file);
2671
os_file_delete(path);
2674
return(DB_OUT_OF_FILE_SPACE);
2677
if (*space_id == 0) {
2678
*space_id = fil_assign_new_space_id();
2681
/* printf("Creating tablespace %s id %lu\n", path, *space_id); */
2683
if (*space_id == ULINT_UNDEFINED) {
2663
2686
os_file_close(file);
2665
2688
os_file_delete(path);
2667
2690
mem_free(path);
2671
/* printf("Creating tablespace %s id %lu\n", path, space_id); */
2673
2694
/* We have to write the space id to the file immediately and flush the
2674
2695
file to disk. This is because in crash recovery we must be aware what
2675
2696
tablespaces exist and what are their space id's, so that we can apply
2679
2700
with zeros from the call of os_file_set_size(), until a buffer pool
2680
2701
flush would write to it. */
2682
buf2 = ut_malloc(3 * UNIV_PAGE_SIZE);
2683
/* Align the memory for file i/o if we might have O_DIRECT set */
2684
page = ut_align(buf2, UNIV_PAGE_SIZE);
2686
2703
memset(page, '\0', UNIV_PAGE_SIZE);
2688
fsp_header_init_fields(page, space_id, flags);
2689
mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, space_id);
2705
fsp_header_init_fields(page, *space_id, flags);
2706
mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, *space_id);
2691
2708
if (!(flags & DICT_TF_ZSSIZE_MASK)) {
2692
2709
buf_flush_init_for_writing(page, NULL, 0);
2727
2743
fputs("InnoDB: Error: file flush of tablespace ", stderr);
2728
2744
ut_print_filename(stderr, path);
2729
2745
fputs(" failed\n", stderr);
2731
2746
goto error_exit;
2734
2749
os_file_close(file);
2736
success = fil_space_create(path, space_id, flags, FIL_TABLESPACE);
2751
if (*space_id == ULINT_UNDEFINED) {
2755
success = fil_space_create(path, *space_id, flags, FIL_TABLESPACE);
2738
2757
if (!success) {
2740
2758
goto error_exit2;
2743
fil_node_create(path, size, space_id, FALSE);
2761
fil_node_create(path, size, *space_id, FALSE);
2745
2763
#ifndef UNIV_HOTBACKUP
2799
2817
filepath = fil_make_ibd_name(name, FALSE);
2801
2819
file = os_file_create_simple_no_error_handling(
2802
filepath, OS_FILE_OPEN, OS_FILE_READ_WRITE, &success);
2820
innodb_file_data_key, filepath, OS_FILE_OPEN,
2821
OS_FILE_READ_WRITE, &success);
2803
2822
if (!success) {
2804
2823
/* The following call prints an error message */
2805
2824
os_file_get_last_error(TRUE);
2983
3002
ut_a(!(flags & (~0UL << DICT_TF_BITS)));
2985
3004
file = os_file_create_simple_no_error_handling(
2986
filepath, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success);
3005
innodb_file_data_key, filepath, OS_FILE_OPEN,
3006
OS_FILE_READ_ONLY, &success);
2987
3007
if (!success) {
2988
3008
/* The following call prints an error message */
2989
3009
os_file_get_last_error(TRUE);
3139
3159
# endif /* !UNIV_HOTBACKUP */
3141
3161
file = os_file_create_simple_no_error_handling(
3142
filepath, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success);
3162
innodb_file_data_key, filepath, OS_FILE_OPEN,
3163
OS_FILE_READ_ONLY, &success);
3143
3164
if (!success) {
3144
3165
/* The following call prints an error message */
3145
3166
os_file_get_last_error(TRUE);
3297
3318
os_file_close(file);
3299
3320
new_path = fil_make_ibbackup_old_name(filepath);
3300
ut_a(os_file_rename(filepath, new_path));
3321
ut_a(os_file_rename(innodb_file_data_key, filepath, new_path));
3303
3324
mem_free(filepath);
3336
3357
mutex_exit(&fil_system->mutex);
3338
ut_a(os_file_rename(filepath, new_path));
3359
ut_a(os_file_rename(innodb_file_data_key, filepath, new_path));
3341
3362
mem_free(filepath);
3566
/********************************************************************//**
3567
If we need crash recovery, and we have called
3568
fil_load_single_table_tablespaces() and dict_load_single_table_tablespaces(),
3569
we can call this function to print an error message of orphaned .ibd files
3570
for which there is not a data dictionary entry with a matching table name
3574
fil_print_orphaned_tablespaces(void)
3575
/*================================*/
3579
mutex_enter(&fil_system->mutex);
3581
space = UT_LIST_GET_FIRST(fil_system->space_list);
3584
if (space->purpose == FIL_TABLESPACE && space->id != 0
3586
fputs("InnoDB: Warning: tablespace ", stderr);
3587
ut_print_filename(stderr, space->name);
3588
fprintf(stderr, " of id %lu has no matching table in\n"
3589
"InnoDB: the InnoDB data dictionary.\n",
3593
space = UT_LIST_GET_NEXT(space_list, space);
3596
mutex_exit(&fil_system->mutex);
3545
3599
/*******************************************************************//**
3546
3600
Returns TRUE if a single-table tablespace does not exist in the memory cache,
3547
3601
or is being deleted there.
4425
4479
ut_ad(fil_validate());
4427
if (os_aio_use_native_aio) {
4481
if (srv_use_native_aio) {
4428
4482
srv_set_io_thread_op_info(segment, "native aio handle");
4429
4483
#ifdef WIN_ASYNC_IO
4430
4484
ret = os_aio_windows_handle(segment, 0, &fil_node,
4431
4485
&message, &type);
4486
#elif defined(LINUX_NATIVE_AIO)
4487
ret = os_aio_linux_handle(segment, &fil_node,
4433
4490
ret = 0; /* Eliminate compiler warning */