1
/*****************************************************************************
3
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
5
This program is free software; you can redistribute it and/or modify it under
6
the terms of the GNU General Public License as published by the Free Software
7
Foundation; version 2 of the License.
9
This program is distributed in the hope that it will be useful, but WITHOUT
10
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
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., 59 Temple
15
Place, Suite 330, Boston, MA 02111-1307 USA
17
*****************************************************************************/
19
/**************************************************//**
21
The tablespace memory cache
23
Created 10/25/1995 Heikki Tuuri
24
*******************************************************/
29
#include "hash0hash.h"
31
#include "mach0data.h"
37
#include "srv0start.h"
40
#include "dict0dict.h"
42
#ifndef UNIV_HOTBACKUP
44
# include "ibuf0ibuf.h"
45
# include "sync0sync.h"
47
#else /* !UNIV_HOTBACKUP */
48
static ulint srv_data_read, srv_data_written;
49
#endif /* !UNIV_HOTBACKUP */
52
IMPLEMENTATION OF THE TABLESPACE MEMORY CACHE
53
=============================================
55
The tablespace cache is responsible for providing fast read/write access to
56
tablespaces and logs of the database. File creation and deletion is done
57
in other modules which know more of the logic of the operation, however.
59
A tablespace consists of a chain of files. The size of the files does not
60
have to be divisible by the database block size, because we may just leave
61
the last incomplete block unused. When a new file is appended to the
62
tablespace, the maximum size of the file is also specified. At the moment,
63
we think that it is best to extend the file to its maximum size already at
64
the creation of the file, because then we can avoid dynamically extending
65
the file when more space is needed for the tablespace.
67
A block's position in the tablespace is specified with a 32-bit unsigned
68
integer. The files in the chain are thought to be catenated, and the block
69
corresponding to an address n is the nth block in the catenated file (where
70
the first block is named the 0th block, and the incomplete block fragments
71
at the end of files are not taken into account). A tablespace can be extended
72
by appending a new file at the end of the chain.
74
Our tablespace concept is similar to the one of Oracle.
76
To acquire more speed in disk transfers, a technique called disk striping is
77
sometimes used. This means that logical block addresses are divided in a
78
round-robin fashion across several disks. Windows NT supports disk striping,
79
so there we do not need to support it in the database. Disk striping is
80
implemented in hardware in RAID disks. We conclude that it is not necessary
81
to implement it in the database. Oracle 7 does not support disk striping,
84
Another trick used at some database sites is replacing tablespace files by
85
raw disks, that is, the whole physical disk drive, or a partition of it, is
86
opened as a single file, and it is accessed through byte offsets calculated
87
from the start of the disk or the partition. This is recommended in some
88
books on database tuning to achieve more speed in i/o. Using raw disk
89
certainly prevents the OS from fragmenting disk space, but it is not clear
90
if it really adds speed. We measured on the Pentium 100 MHz + NT + NTFS file
91
system + EIDE Conner disk only a negligible difference in speed when reading
92
from a file, versus reading from a raw disk.
94
To have fast access to a tablespace or a log file, we put the data structures
95
to a hash table. Each tablespace and log file is given an unique 32-bit
98
Some operating systems do not support many open files at the same time,
99
though NT seems to tolerate at least 900 open files. Therefore, we put the
100
open files in an LRU-list. If we need to open another file, we may close the
101
file at the end of the LRU-list. When an i/o-operation is pending on a file,
102
the file cannot be closed. We take the file nodes with pending i/o-operations
103
out of the LRU-list and keep a count of pending operations. When an operation
104
completes, we decrement the count and return the file node to the LRU-list if
105
the count drops to zero. */
107
/** When mysqld is run, the default directory "." is the mysqld datadir,
108
but in the MySQL Embedded Server Library and ibbackup it is not the default
109
directory, and we must set the base file path explicitly */
110
UNIV_INTERN const char* fil_path_to_mysql_datadir = ".";
112
/** The number of fsyncs done to the log */
113
UNIV_INTERN ulint fil_n_log_flushes = 0;
115
/** Number of pending redo log flushes */
116
UNIV_INTERN ulint fil_n_pending_log_flushes = 0;
117
/** Number of pending tablespace flushes */
118
UNIV_INTERN ulint fil_n_pending_tablespace_flushes = 0;
120
/** The null file address */
121
UNIV_INTERN fil_addr_t fil_addr_null = {FIL_NULL, 0};
123
/** File node of a tablespace or the log data space */
124
struct fil_node_struct {
125
fil_space_t* space; /*!< backpointer to the space where this node
127
char* name; /*!< path to the file */
128
ibool open; /*!< TRUE if file open */
129
os_file_t handle; /*!< OS handle to the file, if file open */
130
ibool is_raw_disk;/*!< TRUE if the 'file' is actually a raw
131
device or a raw disk partition */
132
ulint size; /*!< size of the file in database pages, 0 if
133
not known yet; the possible last incomplete
134
megabyte may be ignored if space == 0 */
136
/*!< count of pending i/o's on this file;
137
closing of the file is not allowed if
139
ulint n_pending_flushes;
140
/*!< count of pending flushes on this file;
141
closing of the file is not allowed if
143
ib_int64_t modification_counter;/*!< when we write to the file we
144
increment this by one */
145
ib_int64_t flush_counter;/*!< up to what
146
modification_counter value we have
147
flushed the modifications to disk */
148
UT_LIST_NODE_T(fil_node_t) chain;
149
/*!< link field for the file chain */
150
UT_LIST_NODE_T(fil_node_t) LRU;
151
/*!< link field for the LRU list */
152
ulint magic_n;/*!< FIL_NODE_MAGIC_N */
155
/** Value of fil_node_struct::magic_n */
156
#define FIL_NODE_MAGIC_N 89389
158
/** Tablespace or log data space: let us call them by a common name space */
159
struct fil_space_struct {
160
char* name; /*!< space name = the path to the first file in
162
ulint id; /*!< space id */
163
ib_int64_t tablespace_version;
164
/*!< in DISCARD/IMPORT this timestamp
165
is used to check if we should ignore
166
an insert buffer merge request for a
167
page because it actually was for the
168
previous incarnation of the space */
169
ibool mark; /*!< this is set to TRUE at database startup if
170
the space corresponds to a table in the InnoDB
171
data dictionary; so we can print a warning of
172
orphaned tablespaces */
173
ibool stop_ios;/*!< TRUE if we want to rename the
174
.ibd file of tablespace and want to
175
stop temporarily posting of new i/o
176
requests on the file */
177
ibool stop_ibuf_merges;
178
/*!< we set this TRUE when we start
179
deleting a single-table tablespace */
180
ibool is_being_deleted;
181
/*!< this is set to TRUE when we start
182
deleting a single-table tablespace and its
183
file; when this flag is set no further i/o
184
or flush requests can be placed on this space,
185
though there may be such requests still being
186
processed on this space */
187
ulint purpose;/*!< FIL_TABLESPACE, FIL_LOG, or
189
UT_LIST_BASE_NODE_T(fil_node_t) chain;
190
/*!< base node for the file chain */
191
ulint size; /*!< space size in pages; 0 if a single-table
192
tablespace whose size we do not know yet;
193
last incomplete megabytes in data files may be
194
ignored if space == 0 */
195
ulint flags; /*!< compressed page size and file format, or 0 */
196
ulint n_reserved_extents;
197
/*!< number of reserved free extents for
198
ongoing operations like B-tree page split */
199
ulint n_pending_flushes; /*!< this is positive when flushing
200
the tablespace to disk; dropping of the
201
tablespace is forbidden if this is positive */
202
ulint n_pending_ibuf_merges;/*!< this is positive
203
when merging insert buffer entries to
204
a page so that we may need to access
205
the ibuf bitmap page in the
206
tablespade: dropping of the tablespace
207
is forbidden if this is positive */
208
hash_node_t hash; /*!< hash chain node */
209
hash_node_t name_hash;/*!< hash chain the name_hash table */
210
#ifndef UNIV_HOTBACKUP
211
rw_lock_t latch; /*!< latch protecting the file space storage
213
#endif /* !UNIV_HOTBACKUP */
214
UT_LIST_NODE_T(fil_space_t) unflushed_spaces;
215
/*!< list of spaces with at least one unflushed
216
file we have written to */
217
ibool is_in_unflushed_spaces; /*!< TRUE if this space is
218
currently in unflushed_spaces */
219
UT_LIST_NODE_T(fil_space_t) space_list;
220
/*!< list of all spaces */
221
ulint magic_n;/*!< FIL_SPACE_MAGIC_N */
224
/** Value of fil_space_struct::magic_n */
225
#define FIL_SPACE_MAGIC_N 89472
227
/** The tablespace memory cache */
228
typedef struct fil_system_struct fil_system_t;
230
/** The tablespace memory cache; also the totality of logs (the log
231
data space) is stored here; below we talk about tablespaces, but also
232
the ib_logfiles form a 'space' and it is handled here */
234
struct fil_system_struct {
235
#ifndef UNIV_HOTBACKUP
236
mutex_t mutex; /*!< The mutex protecting the cache */
237
#endif /* !UNIV_HOTBACKUP */
238
hash_table_t* spaces; /*!< The hash table of spaces in the
239
system; they are hashed on the space
241
hash_table_t* name_hash; /*!< hash table based on the space
243
UT_LIST_BASE_NODE_T(fil_node_t) LRU;
244
/*!< base node for the LRU list of the
245
most recently used open files with no
246
pending i/o's; if we start an i/o on
247
the file, we first remove it from this
248
list, and return it to the start of
249
the list when the i/o ends;
250
log files and the system tablespace are
251
not put to this list: they are opened
252
after the startup, and kept open until
254
UT_LIST_BASE_NODE_T(fil_space_t) unflushed_spaces;
255
/*!< base node for the list of those
256
tablespaces whose files contain
257
unflushed writes; those spaces have
258
at least one file node where
259
modification_counter > flush_counter */
260
ulint n_open; /*!< number of files currently open */
261
ulint max_n_open; /*!< n_open is not allowed to exceed
263
ib_int64_t modification_counter;/*!< when we write to a file we
264
increment this by one */
265
ulint max_assigned_id;/*!< maximum space id in the existing
266
tables, or assigned during the time
267
mysqld has been up; at an InnoDB
268
startup we scan the data dictionary
269
and set here the maximum of the
270
space id's of the tables there */
271
ib_int64_t tablespace_version;
272
/*!< a counter which is incremented for
273
every space object memory creation;
274
every space mem object gets a
275
'timestamp' from this; in DISCARD/
276
IMPORT this is used to check if we
277
should ignore an insert buffer merge
279
UT_LIST_BASE_NODE_T(fil_space_t) space_list;
280
/*!< list of all file spaces */
283
/** The tablespace memory cache. This variable is NULL before the module is
285
static fil_system_t* fil_system = NULL;
288
/********************************************************************//**
289
NOTE: you must call fil_mutex_enter_and_prepare_for_io() first!
291
Prepares a file node for i/o. Opens the file if it is closed. Updates the
292
pending i/o's field in the node and the system appropriately. Takes the node
293
off the LRU list if it is in the LRU list. The caller must hold the fil_sys
297
fil_node_prepare_for_io(
298
/*====================*/
299
fil_node_t* node, /*!< in: file node */
300
fil_system_t* system, /*!< in: tablespace memory cache */
301
fil_space_t* space); /*!< in: space */
302
/********************************************************************//**
303
Updates the data structures when an i/o operation finishes. Updates the
304
pending i/o's field in the node appropriately. */
307
fil_node_complete_io(
308
/*=================*/
309
fil_node_t* node, /*!< in: file node */
310
fil_system_t* system, /*!< in: tablespace memory cache */
311
ulint type); /*!< in: OS_FILE_WRITE or OS_FILE_READ; marks
312
the node as modified if
313
type == OS_FILE_WRITE */
314
/*******************************************************************//**
315
Checks if a single-table tablespace for a given table name exists in the
316
tablespace memory cache.
317
@return space id, ULINT_UNDEFINED if not found */
320
fil_get_space_id_for_table(
321
/*=======================*/
322
const char* name); /*!< in: table name in the standard
323
'databasename/tablename' format */
324
/********************************************************************//**
325
Reads data from a space to a buffer. Remember that the possible incomplete
326
blocks at the end of file are ignored: they are not taken into account when
327
calculating the byte offset within a space.
328
@return DB_SUCCESS, or DB_TABLESPACE_DELETED if we are trying to do
329
i/o on a tablespace which does not exist */
334
ibool sync, /*!< in: TRUE if synchronous aio is desired */
335
ulint space_id, /*!< in: space id */
336
ulint zip_size, /*!< in: compressed page size in bytes;
337
0 for uncompressed pages */
338
ulint block_offset, /*!< in: offset in number of blocks */
339
ulint byte_offset, /*!< in: remainder of offset in bytes; in aio
340
this must be divisible by the OS block size */
341
ulint len, /*!< in: how many bytes to read; this must not
342
cross a file boundary; in aio this must be a
343
block size multiple */
344
void* buf, /*!< in/out: buffer where to store data read;
345
in aio this must be appropriately aligned */
346
void* message) /*!< in: message for aio handler if non-sync
347
aio used, else ignored */
349
return(fil_io(OS_FILE_READ, sync, space_id, zip_size, block_offset,
350
byte_offset, len, buf, message));
353
/********************************************************************//**
354
Writes data to a space from a buffer. Remember that the possible incomplete
355
blocks at the end of file are ignored: they are not taken into account when
356
calculating the byte offset within a space.
357
@return DB_SUCCESS, or DB_TABLESPACE_DELETED if we are trying to do
358
i/o on a tablespace which does not exist */
363
ibool sync, /*!< in: TRUE if synchronous aio is desired */
364
ulint space_id, /*!< in: space id */
365
ulint zip_size, /*!< in: compressed page size in bytes;
366
0 for uncompressed pages */
367
ulint block_offset, /*!< in: offset in number of blocks */
368
ulint byte_offset, /*!< in: remainder of offset in bytes; in aio
369
this must be divisible by the OS block size */
370
ulint len, /*!< in: how many bytes to write; this must
371
not cross a file boundary; in aio this must
372
be a block size multiple */
373
void* buf, /*!< in: buffer from which to write; in aio
374
this must be appropriately aligned */
375
void* message) /*!< in: message for aio handler if non-sync
376
aio used, else ignored */
378
return(fil_io(OS_FILE_WRITE, sync, space_id, zip_size, block_offset,
379
byte_offset, len, buf, message));
382
/*******************************************************************//**
383
Returns the table space by a given id, NULL if not found. */
388
ulint id) /*!< in: space id */
392
ut_ad(mutex_own(&fil_system->mutex));
394
HASH_SEARCH(hash, fil_system->spaces, id,
396
ut_ad(space->magic_n == FIL_SPACE_MAGIC_N),
402
/*******************************************************************//**
403
Returns the table space by a given name, NULL if not found. */
406
fil_space_get_by_name(
407
/*==================*/
408
const char* name) /*!< in: space name */
413
ut_ad(mutex_own(&fil_system->mutex));
415
fold = ut_fold_string(name);
417
HASH_SEARCH(name_hash, fil_system->name_hash, fold,
419
ut_ad(space->magic_n == FIL_SPACE_MAGIC_N),
420
!strcmp(name, space->name));
425
#ifndef UNIV_HOTBACKUP
426
/*******************************************************************//**
427
Returns the version number of a tablespace, -1 if not found.
428
@return version number, -1 if the tablespace does not exist in the
432
fil_space_get_version(
433
/*==================*/
434
ulint id) /*!< in: space id */
437
ib_int64_t version = -1;
441
mutex_enter(&fil_system->mutex);
443
space = fil_space_get_by_id(id);
446
version = space->tablespace_version;
449
mutex_exit(&fil_system->mutex);
454
/*******************************************************************//**
455
Returns the latch of a file space.
456
@return latch protecting storage allocation */
461
ulint id, /*!< in: space id */
462
ulint* flags) /*!< out: tablespace flags */
468
mutex_enter(&fil_system->mutex);
470
space = fil_space_get_by_id(id);
475
*flags = space->flags;
478
mutex_exit(&fil_system->mutex);
480
return(&(space->latch));
483
/*******************************************************************//**
484
Returns the type of a file space.
485
@return FIL_TABLESPACE or FIL_LOG */
490
ulint id) /*!< in: space id */
496
mutex_enter(&fil_system->mutex);
498
space = fil_space_get_by_id(id);
502
mutex_exit(&fil_system->mutex);
504
return(space->purpose);
506
#endif /* !UNIV_HOTBACKUP */
508
/**********************************************************************//**
509
Checks if all the file nodes in a space are flushed. The caller must hold
510
the fil_system mutex.
511
@return TRUE if all are flushed */
514
fil_space_is_flushed(
515
/*=================*/
516
fil_space_t* space) /*!< in: space */
520
ut_ad(mutex_own(&fil_system->mutex));
522
node = UT_LIST_GET_FIRST(space->chain);
525
if (node->modification_counter > node->flush_counter) {
530
node = UT_LIST_GET_NEXT(chain, node);
536
/*******************************************************************//**
537
Appends a new file to the chain of files of a space. File must be closed. */
542
const char* name, /*!< in: file name (file must be closed) */
543
ulint size, /*!< in: file size in database blocks, rounded
544
downwards to an integer */
545
ulint id, /*!< in: space id where to append */
546
ibool is_raw) /*!< in: TRUE if a raw device or
547
a raw disk partition */
555
mutex_enter(&fil_system->mutex);
557
node = mem_alloc(sizeof(fil_node_t));
559
node->name = mem_strdup(name);
562
ut_a(!is_raw || srv_start_raw_disk_in_use);
564
node->is_raw_disk = is_raw;
566
node->magic_n = FIL_NODE_MAGIC_N;
568
node->n_pending_flushes = 0;
570
node->modification_counter = 0;
571
node->flush_counter = 0;
573
space = fil_space_get_by_id(id);
576
ut_print_timestamp(stderr);
578
" InnoDB: Error: Could not find tablespace %lu for\n"
579
"InnoDB: file ", (ulong) id);
580
ut_print_filename(stderr, name);
581
fputs(" in the tablespace memory cache.\n", stderr);
582
mem_free(node->name);
586
mutex_exit(&fil_system->mutex);
595
UT_LIST_ADD_LAST(chain, space->chain, node);
597
mutex_exit(&fil_system->mutex);
600
/********************************************************************//**
601
Opens a the file of a node of a tablespace. The caller must own the fil_system
607
fil_node_t* node, /*!< in: file node */
608
fil_system_t* system, /*!< in: tablespace memory cache */
609
fil_space_t* space) /*!< in: space */
611
ib_int64_t size_bytes;
616
#ifndef UNIV_HOTBACKUP
621
#endif /* !UNIV_HOTBACKUP */
623
ut_ad(mutex_own(&(system->mutex)));
624
ut_a(node->n_pending == 0);
625
ut_a(node->open == FALSE);
627
if (node->size == 0) {
628
/* It must be a single-table tablespace and we do not know the
629
size of the file yet. First we open the file in the normal
630
mode, no async I/O here, for simplicity. Then do some checks,
631
and close the file again.
632
NOTE that we could not use the simple file read function
633
os_file_read() in Windows to read from a file opened for
636
node->handle = os_file_create_simple_no_error_handling(
637
node->name, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success);
639
/* The following call prints an error message */
640
os_file_get_last_error(TRUE);
642
ut_print_timestamp(stderr);
645
" InnoDB: Fatal error: cannot open %s\n."
646
"InnoDB: Have you deleted .ibd files"
647
" under a running mysqld server?\n",
652
os_file_get_size(node->handle, &size_low, &size_high);
654
size_bytes = (((ib_int64_t)size_high) << 32)
655
+ (ib_int64_t)size_low;
656
#ifdef UNIV_HOTBACKUP
657
node->size = (ulint) (size_bytes / UNIV_PAGE_SIZE);
658
/* TODO: adjust to zip_size, like below? */
660
ut_a(space->purpose != FIL_LOG);
661
ut_a(space->id != 0);
663
if (size_bytes < FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE) {
665
"InnoDB: Error: the size of single-table"
666
" tablespace file %s\n"
667
"InnoDB: is only %lu %lu,"
668
" should be at least %lu!\n",
672
(ulong) (FIL_IBD_FILE_INITIAL_SIZE
678
/* Read the first page of the tablespace */
680
buf2 = ut_malloc(2 * UNIV_PAGE_SIZE);
681
/* Align the memory for file i/o if we might have O_DIRECT
683
page = ut_align(buf2, UNIV_PAGE_SIZE);
685
success = os_file_read(node->handle, page, 0, 0,
687
space_id = fsp_header_get_space_id(page);
688
flags = fsp_header_get_flags(page);
692
/* Close the file now that we have read the space id from it */
694
os_file_close(node->handle);
696
if (UNIV_UNLIKELY(space_id != space->id)) {
698
"InnoDB: Error: tablespace id is %lu"
699
" in the data dictionary\n"
700
"InnoDB: but in file %s it is %lu!\n",
701
space->id, node->name, space_id);
706
if (UNIV_UNLIKELY(space_id == ULINT_UNDEFINED
709
"InnoDB: Error: tablespace id %lu"
710
" in file %s is not sensible\n",
711
(ulong) space_id, node->name);
716
if (UNIV_UNLIKELY(space->flags != flags)) {
718
"InnoDB: Error: table flags are %lx"
719
" in the data dictionary\n"
720
"InnoDB: but the flags in file %s are %lx!\n",
721
space->flags, node->name, flags);
726
if (size_bytes >= 1024 * 1024) {
727
/* Truncate the size to whole megabytes. */
728
size_bytes = ut_2pow_round(size_bytes, 1024 * 1024);
731
if (!(flags & DICT_TF_ZSSIZE_MASK)) {
732
node->size = (ulint) (size_bytes / UNIV_PAGE_SIZE);
736
/ dict_table_flags_to_zip_size(flags));
739
space->size += node->size;
742
/* printf("Opening file %s\n", node->name); */
744
/* Open the file for reading and writing, in Windows normally in the
745
unbuffered async I/O mode, though global variables may make
746
os_file_create() to fall back to the normal file I/O mode. */
748
if (space->purpose == FIL_LOG) {
749
node->handle = os_file_create(node->name, OS_FILE_OPEN,
750
OS_FILE_AIO, OS_LOG_FILE, &ret);
751
} else if (node->is_raw_disk) {
752
node->handle = os_file_create(node->name,
754
OS_FILE_AIO, OS_DATA_FILE, &ret);
756
node->handle = os_file_create(node->name, OS_FILE_OPEN,
757
OS_FILE_AIO, OS_DATA_FILE, &ret);
766
if (space->purpose == FIL_TABLESPACE && space->id != 0) {
767
/* Put the node to the LRU list */
768
UT_LIST_ADD_FIRST(LRU, system->LRU, node);
772
/**********************************************************************//**
778
fil_node_t* node, /*!< in: file node */
779
fil_system_t* system) /*!< in: tablespace memory cache */
783
ut_ad(node && system);
784
ut_ad(mutex_own(&(system->mutex)));
786
ut_a(node->n_pending == 0);
787
ut_a(node->n_pending_flushes == 0);
788
ut_a(node->modification_counter == node->flush_counter);
790
ret = os_file_close(node->handle);
793
/* printf("Closing file %s\n", node->name); */
796
ut_a(system->n_open > 0);
799
if (node->space->purpose == FIL_TABLESPACE && node->space->id != 0) {
800
ut_a(UT_LIST_GET_LEN(system->LRU) > 0);
802
/* The node is in the LRU list, remove it */
803
UT_LIST_REMOVE(LRU, system->LRU, node);
807
/********************************************************************//**
808
Tries to close a file in the LRU list. The caller must hold the fil_sys
810
@return TRUE if success, FALSE if should retry later; since i/o's
811
generally complete in < 100 ms, and as InnoDB writes at most 128 pages
812
from the buffer pool in a batch, and then immediately flushes the
813
files, there is a good chance that the next time we find a suitable
814
node from the LRU list */
817
fil_try_to_close_file_in_LRU(
818
/*=========================*/
819
ibool print_info) /*!< in: if TRUE, prints information why it
820
cannot close a file */
824
ut_ad(mutex_own(&fil_system->mutex));
826
node = UT_LIST_GET_LAST(fil_system->LRU);
830
"InnoDB: fil_sys open file LRU len %lu\n",
831
(ulong) UT_LIST_GET_LEN(fil_system->LRU));
834
while (node != NULL) {
835
if (node->modification_counter == node->flush_counter
836
&& node->n_pending_flushes == 0) {
838
fil_node_close_file(node, fil_system);
843
if (print_info && node->n_pending_flushes > 0) {
844
fputs("InnoDB: cannot close file ", stderr);
845
ut_print_filename(stderr, node->name);
846
fprintf(stderr, ", because n_pending_flushes %lu\n",
847
(ulong) node->n_pending_flushes);
851
&& node->modification_counter != node->flush_counter) {
852
fputs("InnoDB: cannot close file ", stderr);
853
ut_print_filename(stderr, node->name);
855
", because mod_count %ld != fl_count %ld\n",
856
(long) node->modification_counter,
857
(long) node->flush_counter);
860
node = UT_LIST_GET_PREV(LRU, node);
866
/*******************************************************************//**
867
Reserves the fil_system mutex and tries to make sure we can open at least one
868
file while holding it. This should be called before calling
869
fil_node_prepare_for_io(), because that function may need to open a file. */
872
fil_mutex_enter_and_prepare_for_io(
873
/*===============================*/
874
ulint space_id) /*!< in: space id */
878
ibool print_info = FALSE;
883
mutex_enter(&fil_system->mutex);
885
if (space_id == 0 || space_id >= SRV_LOG_SPACE_FIRST_ID) {
886
/* We keep log files and system tablespace files always open;
887
this is important in preventing deadlocks in this module, as
888
a page read completion often performs another read from the
889
insert buffer. The insert buffer is in tablespace 0, and we
890
cannot end up waiting in this function. */
895
if (fil_system->n_open < fil_system->max_n_open) {
900
space = fil_space_get_by_id(space_id);
902
if (space != NULL && space->stop_ios) {
903
/* We are going to do a rename file and want to stop new i/o's
906
if (count2 > 20000) {
907
fputs("InnoDB: Warning: tablespace ", stderr);
908
ut_print_filename(stderr, space->name);
910
" has i/o ops stopped for a long time %lu\n",
914
mutex_exit(&fil_system->mutex);
916
os_thread_sleep(20000);
923
/* If the file is already open, no need to do anything; if the space
924
does not exist, we handle the situation in the function which called
927
if (!space || UT_LIST_GET_FIRST(space->chain)->open) {
936
/* Too many files are open, try to close some */
938
success = fil_try_to_close_file_in_LRU(print_info);
940
if (success && fil_system->n_open >= fil_system->max_n_open) {
945
if (fil_system->n_open < fil_system->max_n_open) {
952
ut_print_timestamp(stderr);
954
" InnoDB: Warning: too many (%lu) files stay open"
955
" while the maximum\n"
956
"InnoDB: allowed value would be %lu.\n"
957
"InnoDB: You may need to raise the value of"
958
" innodb_max_files_open in\n"
960
(ulong) fil_system->n_open,
961
(ulong) fil_system->max_n_open);
966
mutex_exit(&fil_system->mutex);
968
#ifndef UNIV_HOTBACKUP
969
/* Wake the i/o-handler threads to make sure pending i/o's are
971
os_aio_simulated_wake_handler_threads();
973
os_thread_sleep(20000);
975
/* Flush tablespaces so that we can close modified files in the LRU
978
fil_flush_file_spaces(FIL_TABLESPACE);
985
/*******************************************************************//**
986
Frees a file node object from a tablespace memory cache. */
991
fil_node_t* node, /*!< in, own: file node */
992
fil_system_t* system, /*!< in: tablespace memory cache */
993
fil_space_t* space) /*!< in: space where the file node is chained */
995
ut_ad(node && system && space);
996
ut_ad(mutex_own(&(system->mutex)));
997
ut_a(node->magic_n == FIL_NODE_MAGIC_N);
998
ut_a(node->n_pending == 0);
1001
/* We fool the assertion in fil_node_close_file() to think
1002
there are no unflushed modifications in the file */
1004
node->modification_counter = node->flush_counter;
1006
if (space->is_in_unflushed_spaces
1007
&& fil_space_is_flushed(space)) {
1009
space->is_in_unflushed_spaces = FALSE;
1011
UT_LIST_REMOVE(unflushed_spaces,
1012
system->unflushed_spaces,
1016
fil_node_close_file(node, system);
1019
space->size -= node->size;
1021
UT_LIST_REMOVE(chain, space->chain, node);
1023
mem_free(node->name);
1027
#ifdef UNIV_LOG_ARCHIVE
1028
/****************************************************************//**
1029
Drops files from the start of a file space, so that its size is cut by
1030
the amount given. */
1033
fil_space_truncate_start(
1034
/*=====================*/
1035
ulint id, /*!< in: space id */
1036
ulint trunc_len) /*!< in: truncate by this much; it is an error
1037
if this does not equal to the combined size of
1038
some initial files in the space */
1043
mutex_enter(&fil_system->mutex);
1045
space = fil_space_get_by_id(id);
1049
while (trunc_len > 0) {
1050
node = UT_LIST_GET_FIRST(space->chain);
1052
ut_a(node->size * UNIV_PAGE_SIZE <= trunc_len);
1054
trunc_len -= node->size * UNIV_PAGE_SIZE;
1056
fil_node_free(node, fil_system, space);
1059
mutex_exit(&fil_system->mutex);
1061
#endif /* UNIV_LOG_ARCHIVE */
1063
/*******************************************************************//**
1064
Creates a space memory object and puts it to the tablespace memory cache. If
1065
there is an error, prints an error message to the .err log.
1066
@return TRUE if success */
1071
const char* name, /*!< in: space name */
1072
ulint id, /*!< in: space id */
1073
ulint flags, /*!< in: compressed page size
1074
and file format, or 0 */
1075
ulint purpose)/*!< in: FIL_TABLESPACE, or FIL_LOG if log */
1079
/* The tablespace flags (FSP_SPACE_FLAGS) should be 0 for
1080
ROW_FORMAT=COMPACT (table->flags == DICT_TF_COMPACT) and
1081
ROW_FORMAT=REDUNDANT (table->flags == 0). For any other
1082
format, the tablespace flags should equal table->flags. */
1083
ut_a(flags != DICT_TF_COMPACT);
1087
"InnoDB: Adding tablespace %lu of name %s, purpose %lu\n", id, name,
1093
mutex_enter(&fil_system->mutex);
1095
space = fil_space_get_by_name(name);
1097
if (UNIV_LIKELY_NULL(space)) {
1100
ut_print_timestamp(stderr);
1102
" InnoDB: Warning: trying to init to the"
1103
" tablespace memory cache\n"
1104
"InnoDB: a tablespace %lu of name ", (ulong) id);
1105
ut_print_filename(stderr, name);
1106
fprintf(stderr, ",\n"
1107
"InnoDB: but a tablespace %lu of the same name\n"
1108
"InnoDB: already exists in the"
1109
" tablespace memory cache!\n",
1112
if (id == 0 || purpose != FIL_TABLESPACE) {
1114
mutex_exit(&fil_system->mutex);
1120
"InnoDB: We assume that InnoDB did a crash recovery,"
1122
"InnoDB: an .ibd file for which the table"
1123
" did not exist in the\n"
1124
"InnoDB: InnoDB internal data dictionary in the"
1126
"InnoDB: We assume that you later removed the"
1127
" .ibd and .frm files,\n"
1128
"InnoDB: and are now trying to recreate the table."
1129
" We now remove the\n"
1130
"InnoDB: conflicting tablespace object"
1131
" from the memory cache and try\n"
1132
"InnoDB: the init again.\n");
1134
namesake_id = space->id;
1136
mutex_exit(&fil_system->mutex);
1138
fil_space_free(namesake_id);
1143
space = fil_space_get_by_id(id);
1145
if (UNIV_LIKELY_NULL(space)) {
1147
"InnoDB: Error: trying to add tablespace %lu"
1148
" of name ", (ulong) id);
1149
ut_print_filename(stderr, name);
1150
fprintf(stderr, "\n"
1151
"InnoDB: to the tablespace memory cache,"
1153
"InnoDB: %lu of name ", (ulong) space->id);
1154
ut_print_filename(stderr, space->name);
1155
fputs(" already exists in the tablespace\n"
1156
"InnoDB: memory cache!\n", stderr);
1158
mutex_exit(&fil_system->mutex);
1163
space = mem_alloc(sizeof(fil_space_t));
1165
space->name = mem_strdup(name);
1168
fil_system->tablespace_version++;
1169
space->tablespace_version = fil_system->tablespace_version;
1170
space->mark = FALSE;
1172
if (purpose == FIL_TABLESPACE && id > fil_system->max_assigned_id) {
1173
fil_system->max_assigned_id = id;
1176
space->stop_ios = FALSE;
1177
space->stop_ibuf_merges = FALSE;
1178
space->is_being_deleted = FALSE;
1179
space->purpose = purpose;
1181
space->flags = flags;
1183
space->n_reserved_extents = 0;
1185
space->n_pending_flushes = 0;
1186
space->n_pending_ibuf_merges = 0;
1188
UT_LIST_INIT(space->chain);
1189
space->magic_n = FIL_SPACE_MAGIC_N;
1191
rw_lock_create(&space->latch, SYNC_FSP);
1193
HASH_INSERT(fil_space_t, hash, fil_system->spaces, id, space);
1195
HASH_INSERT(fil_space_t, name_hash, fil_system->name_hash,
1196
ut_fold_string(name), space);
1197
space->is_in_unflushed_spaces = FALSE;
1199
UT_LIST_ADD_LAST(space_list, fil_system->space_list, space);
1201
mutex_exit(&fil_system->mutex);
1206
/*******************************************************************//**
1207
Assigns a new space id for a new single-table tablespace. This works simply by
1208
incrementing the global counter. If 4 billion id's is not enough, we may need
1210
@return new tablespace id; ULINT_UNDEFINED if could not assign an id */
1213
fil_assign_new_space_id(void)
1214
/*=========================*/
1218
mutex_enter(&fil_system->mutex);
1220
fil_system->max_assigned_id++;
1222
id = fil_system->max_assigned_id;
1224
if (id > (SRV_LOG_SPACE_FIRST_ID / 2) && (id % 1000000UL == 0)) {
1225
ut_print_timestamp(stderr);
1227
"InnoDB: Warning: you are running out of new"
1228
" single-table tablespace id's.\n"
1229
"InnoDB: Current counter is %lu and it"
1230
" must not exceed %lu!\n"
1231
"InnoDB: To reset the counter to zero"
1232
" you have to dump all your tables and\n"
1233
"InnoDB: recreate the whole InnoDB installation.\n",
1235
(ulong) SRV_LOG_SPACE_FIRST_ID);
1238
if (id >= SRV_LOG_SPACE_FIRST_ID) {
1239
ut_print_timestamp(stderr);
1241
"InnoDB: You have run out of single-table"
1242
" tablespace id's!\n"
1243
"InnoDB: Current counter is %lu.\n"
1244
"InnoDB: To reset the counter to zero you"
1245
" have to dump all your tables and\n"
1246
"InnoDB: recreate the whole InnoDB installation.\n",
1248
fil_system->max_assigned_id--;
1250
id = ULINT_UNDEFINED;
1253
mutex_exit(&fil_system->mutex);
1258
/*******************************************************************//**
1259
Frees a space object from the tablespace memory cache. Closes the files in
1260
the chain but does not delete them. There must not be any pending i/o's or
1261
flushes on the files.
1262
@return TRUE if success */
1267
ulint id) /*!< in: space id */
1270
fil_space_t* namespace;
1271
fil_node_t* fil_node;
1273
mutex_enter(&fil_system->mutex);
1275
space = fil_space_get_by_id(id);
1278
ut_print_timestamp(stderr);
1280
" InnoDB: Error: trying to remove tablespace %lu"
1281
" from the cache but\n"
1282
"InnoDB: it is not there.\n", (ulong) id);
1284
mutex_exit(&fil_system->mutex);
1289
HASH_DELETE(fil_space_t, hash, fil_system->spaces, id, space);
1291
namespace = fil_space_get_by_name(space->name);
1293
ut_a(space == namespace);
1295
HASH_DELETE(fil_space_t, name_hash, fil_system->name_hash,
1296
ut_fold_string(space->name), space);
1298
if (space->is_in_unflushed_spaces) {
1299
space->is_in_unflushed_spaces = FALSE;
1301
UT_LIST_REMOVE(unflushed_spaces, fil_system->unflushed_spaces,
1305
UT_LIST_REMOVE(space_list, fil_system->space_list, space);
1307
ut_a(space->magic_n == FIL_SPACE_MAGIC_N);
1308
ut_a(0 == space->n_pending_flushes);
1310
fil_node = UT_LIST_GET_FIRST(space->chain);
1312
while (fil_node != NULL) {
1313
fil_node_free(fil_node, fil_system, space);
1315
fil_node = UT_LIST_GET_FIRST(space->chain);
1318
ut_a(0 == UT_LIST_GET_LEN(space->chain));
1320
mutex_exit(&fil_system->mutex);
1322
rw_lock_free(&(space->latch));
1324
mem_free(space->name);
1330
/*******************************************************************//**
1331
Returns the size of the space in pages. The tablespace must be cached in the
1333
@return space size, 0 if space not found */
1338
ulint id) /*!< in: space id */
1346
fil_mutex_enter_and_prepare_for_io(id);
1348
space = fil_space_get_by_id(id);
1350
if (space == NULL) {
1351
mutex_exit(&fil_system->mutex);
1356
if (space->size == 0 && space->purpose == FIL_TABLESPACE) {
1359
ut_a(1 == UT_LIST_GET_LEN(space->chain));
1361
node = UT_LIST_GET_FIRST(space->chain);
1363
/* It must be a single-table tablespace and we have not opened
1364
the file yet; the following calls will open it and update the
1367
fil_node_prepare_for_io(node, fil_system, space);
1368
fil_node_complete_io(node, fil_system, OS_FILE_READ);
1373
mutex_exit(&fil_system->mutex);
1378
/*******************************************************************//**
1379
Returns the flags of the space. The tablespace must be cached
1380
in the memory cache.
1381
@return flags, ULINT_UNDEFINED if space not found */
1384
fil_space_get_flags(
1385
/*================*/
1386
ulint id) /*!< in: space id */
1394
if (UNIV_UNLIKELY(!id)) {
1398
fil_mutex_enter_and_prepare_for_io(id);
1400
space = fil_space_get_by_id(id);
1402
if (space == NULL) {
1403
mutex_exit(&fil_system->mutex);
1405
return(ULINT_UNDEFINED);
1408
if (space->size == 0 && space->purpose == FIL_TABLESPACE) {
1411
ut_a(1 == UT_LIST_GET_LEN(space->chain));
1413
node = UT_LIST_GET_FIRST(space->chain);
1415
/* It must be a single-table tablespace and we have not opened
1416
the file yet; the following calls will open it and update the
1419
fil_node_prepare_for_io(node, fil_system, space);
1420
fil_node_complete_io(node, fil_system, OS_FILE_READ);
1423
flags = space->flags;
1425
mutex_exit(&fil_system->mutex);
1430
/*******************************************************************//**
1431
Returns the compressed page size of the space, or 0 if the space
1432
is not compressed. The tablespace must be cached in the memory cache.
1433
@return compressed page size, ULINT_UNDEFINED if space not found */
1436
fil_space_get_zip_size(
1437
/*===================*/
1438
ulint id) /*!< in: space id */
1442
flags = fil_space_get_flags(id);
1444
if (flags && flags != ULINT_UNDEFINED) {
1446
return(dict_table_flags_to_zip_size(flags));
1452
/*******************************************************************//**
1453
Checks if the pair space, page_no refers to an existing page in a tablespace
1454
file space. The tablespace must be cached in the memory cache.
1455
@return TRUE if the address is meaningful */
1458
fil_check_adress_in_tablespace(
1459
/*===========================*/
1460
ulint id, /*!< in: space id */
1461
ulint page_no)/*!< in: page number */
1463
if (fil_space_get_size(id) > page_no) {
1471
/****************************************************************//**
1472
Initializes the tablespace memory cache. */
1477
ulint hash_size, /*!< in: hash table size */
1478
ulint max_n_open) /*!< in: max number of open files */
1480
ut_a(fil_system == NULL);
1482
ut_a(hash_size > 0);
1483
ut_a(max_n_open > 0);
1485
fil_system = mem_alloc(sizeof(fil_system_t));
1487
mutex_create(&fil_system->mutex, SYNC_ANY_LATCH);
1489
fil_system->spaces = hash_create(hash_size);
1490
fil_system->name_hash = hash_create(hash_size);
1492
UT_LIST_INIT(fil_system->LRU);
1494
fil_system->n_open = 0;
1495
fil_system->max_n_open = max_n_open;
1497
fil_system->modification_counter = 0;
1498
fil_system->max_assigned_id = 0;
1500
fil_system->tablespace_version = 0;
1502
UT_LIST_INIT(fil_system->unflushed_spaces);
1503
UT_LIST_INIT(fil_system->space_list);
1506
/*******************************************************************//**
1507
Opens all log files and system tablespace data files. They stay open until the
1508
database server shutdown. This should be called at a server startup after the
1509
space objects for the log and the system tablespace have been created. The
1510
purpose of this operation is to make sure we never run out of file descriptors
1511
if we need to read from the insert buffer or to write to the log. */
1514
fil_open_log_and_system_tablespace_files(void)
1515
/*==========================================*/
1520
mutex_enter(&fil_system->mutex);
1522
space = UT_LIST_GET_FIRST(fil_system->space_list);
1524
while (space != NULL) {
1525
if (space->purpose != FIL_TABLESPACE || space->id == 0) {
1526
node = UT_LIST_GET_FIRST(space->chain);
1528
while (node != NULL) {
1530
fil_node_open_file(node, fil_system,
1533
if (fil_system->max_n_open
1534
< 10 + fil_system->n_open) {
1536
"InnoDB: Warning: you must"
1537
" raise the value of"
1538
" innodb_max_open_files in\n"
1539
"InnoDB: my.cnf! Remember that"
1540
" InnoDB keeps all log files"
1542
"InnoDB: tablespace files open"
1543
" for the whole time mysqld is"
1545
"InnoDB: needs to open also"
1546
" some .ibd files if the"
1547
" file-per-table storage\n"
1548
"InnoDB: model is used."
1549
" Current open files %lu,"
1551
" open files %lu.\n",
1552
(ulong) fil_system->n_open,
1553
(ulong) fil_system->max_n_open);
1555
node = UT_LIST_GET_NEXT(chain, node);
1558
space = UT_LIST_GET_NEXT(space_list, space);
1561
mutex_exit(&fil_system->mutex);
1564
/*******************************************************************//**
1565
Closes all open files. There must not be any pending i/o's or not flushed
1566
modifications in the files. */
1569
fil_close_all_files(void)
1570
/*=====================*/
1575
mutex_enter(&fil_system->mutex);
1577
space = UT_LIST_GET_FIRST(fil_system->space_list);
1579
while (space != NULL) {
1580
node = UT_LIST_GET_FIRST(space->chain);
1582
while (node != NULL) {
1584
fil_node_close_file(node, fil_system);
1586
node = UT_LIST_GET_NEXT(chain, node);
1588
space = UT_LIST_GET_NEXT(space_list, space);
1591
mutex_exit(&fil_system->mutex);
1594
/*******************************************************************//**
1595
Sets the max tablespace id counter if the given number is bigger than the
1599
fil_set_max_space_id_if_bigger(
1600
/*===========================*/
1601
ulint max_id) /*!< in: maximum known id */
1603
if (max_id >= SRV_LOG_SPACE_FIRST_ID) {
1605
"InnoDB: Fatal error: max tablespace id"
1606
" is too high, %lu\n", (ulong) max_id);
1610
mutex_enter(&fil_system->mutex);
1612
if (fil_system->max_assigned_id < max_id) {
1614
fil_system->max_assigned_id = max_id;
1617
mutex_exit(&fil_system->mutex);
1620
/****************************************************************//**
1621
Writes the flushed lsn and the latest archived log number to the page header
1622
of the first page of a data file of the system tablespace (space 0),
1623
which is uncompressed. */
1626
fil_write_lsn_and_arch_no_to_file(
1627
/*==============================*/
1628
ulint sum_of_sizes, /*!< in: combined size of previous files
1629
in space, in database pages */
1630
ib_uint64_t lsn, /*!< in: lsn to write */
1631
ulint arch_log_no __attribute__((unused)))
1632
/*!< in: archived log number to write */
1637
buf1 = mem_alloc(2 * UNIV_PAGE_SIZE);
1638
buf = ut_align(buf1, UNIV_PAGE_SIZE);
1640
fil_read(TRUE, 0, 0, sum_of_sizes, 0, UNIV_PAGE_SIZE, buf, NULL);
1642
mach_write_ull(buf + FIL_PAGE_FILE_FLUSH_LSN, lsn);
1644
fil_write(TRUE, 0, 0, sum_of_sizes, 0, UNIV_PAGE_SIZE, buf, NULL);
1651
/****************************************************************//**
1652
Writes the flushed lsn and the latest archived log number to the page
1653
header of the first page of each data file in the system tablespace.
1654
@return DB_SUCCESS or error number */
1657
fil_write_flushed_lsn_to_data_files(
1658
/*================================*/
1659
ib_uint64_t lsn, /*!< in: lsn to write */
1660
ulint arch_log_no) /*!< in: latest archived log
1668
mutex_enter(&fil_system->mutex);
1670
space = UT_LIST_GET_FIRST(fil_system->space_list);
1673
/* We only write the lsn to all existing data files which have
1674
been open during the lifetime of the mysqld process; they are
1675
represented by the space objects in the tablespace memory
1676
cache. Note that all data files in the system tablespace 0 are
1679
if (space->purpose == FIL_TABLESPACE
1680
&& space->id == 0) {
1683
node = UT_LIST_GET_FIRST(space->chain);
1685
mutex_exit(&fil_system->mutex);
1687
err = fil_write_lsn_and_arch_no_to_file(
1688
sum_of_sizes, lsn, arch_log_no);
1689
if (err != DB_SUCCESS) {
1694
mutex_enter(&fil_system->mutex);
1696
sum_of_sizes += node->size;
1697
node = UT_LIST_GET_NEXT(chain, node);
1700
space = UT_LIST_GET_NEXT(space_list, space);
1703
mutex_exit(&fil_system->mutex);
1708
/*******************************************************************//**
1709
Reads the flushed lsn and arch no fields from a data file at database
1713
fil_read_flushed_lsn_and_arch_log_no(
1714
/*=================================*/
1715
os_file_t data_file, /*!< in: open data file */
1716
ibool one_read_already, /*!< in: TRUE if min and max
1717
parameters below already
1718
contain sensible data */
1719
#ifdef UNIV_LOG_ARCHIVE
1720
ulint* min_arch_log_no, /*!< in/out: */
1721
ulint* max_arch_log_no, /*!< in/out: */
1722
#endif /* UNIV_LOG_ARCHIVE */
1723
ib_uint64_t* min_flushed_lsn, /*!< in/out: */
1724
ib_uint64_t* max_flushed_lsn) /*!< in/out: */
1728
ib_uint64_t flushed_lsn;
1730
buf2 = ut_malloc(2 * UNIV_PAGE_SIZE);
1731
/* Align the memory for a possible read from a raw device */
1732
buf = ut_align(buf2, UNIV_PAGE_SIZE);
1734
os_file_read(data_file, buf, 0, 0, UNIV_PAGE_SIZE);
1736
flushed_lsn = mach_read_ull(buf + FIL_PAGE_FILE_FLUSH_LSN);
1740
if (!one_read_already) {
1741
*min_flushed_lsn = flushed_lsn;
1742
*max_flushed_lsn = flushed_lsn;
1743
#ifdef UNIV_LOG_ARCHIVE
1744
*min_arch_log_no = arch_log_no;
1745
*max_arch_log_no = arch_log_no;
1746
#endif /* UNIV_LOG_ARCHIVE */
1750
if (*min_flushed_lsn > flushed_lsn) {
1751
*min_flushed_lsn = flushed_lsn;
1753
if (*max_flushed_lsn < flushed_lsn) {
1754
*max_flushed_lsn = flushed_lsn;
1756
#ifdef UNIV_LOG_ARCHIVE
1757
if (*min_arch_log_no > arch_log_no) {
1758
*min_arch_log_no = arch_log_no;
1760
if (*max_arch_log_no < arch_log_no) {
1761
*max_arch_log_no = arch_log_no;
1763
#endif /* UNIV_LOG_ARCHIVE */
1766
/*================ SINGLE-TABLE TABLESPACES ==========================*/
1768
#ifndef UNIV_HOTBACKUP
1769
/*******************************************************************//**
1770
Increments the count of pending insert buffer page merges, if space is not
1772
@return TRUE if being deleted, and ibuf merges should be skipped */
1775
fil_inc_pending_ibuf_merges(
1776
/*========================*/
1777
ulint id) /*!< in: space id */
1781
mutex_enter(&fil_system->mutex);
1783
space = fil_space_get_by_id(id);
1785
if (space == NULL) {
1787
"InnoDB: Error: trying to do ibuf merge to a"
1788
" dropped tablespace %lu\n",
1792
if (space == NULL || space->stop_ibuf_merges) {
1793
mutex_exit(&fil_system->mutex);
1798
space->n_pending_ibuf_merges++;
1800
mutex_exit(&fil_system->mutex);
1805
/*******************************************************************//**
1806
Decrements the count of pending insert buffer page merges. */
1809
fil_decr_pending_ibuf_merges(
1810
/*=========================*/
1811
ulint id) /*!< in: space id */
1815
mutex_enter(&fil_system->mutex);
1817
space = fil_space_get_by_id(id);
1819
if (space == NULL) {
1821
"InnoDB: Error: decrementing ibuf merge of a"
1822
" dropped tablespace %lu\n",
1826
if (space != NULL) {
1827
space->n_pending_ibuf_merges--;
1830
mutex_exit(&fil_system->mutex);
1832
#endif /* !UNIV_HOTBACKUP */
1834
/********************************************************//**
1835
Creates the database directory for a table if it does not exist yet. */
1838
fil_create_directory_for_tablename(
1839
/*===============================*/
1840
const char* name) /*!< in: name in the standard
1841
'databasename/tablename' format */
1847
len = strlen(fil_path_to_mysql_datadir);
1848
namend = strchr(name, '/');
1850
path = mem_alloc(len + (namend - name) + 2);
1852
memcpy(path, fil_path_to_mysql_datadir, len);
1854
memcpy(path + len + 1, name, namend - name);
1855
path[len + (namend - name) + 1] = 0;
1857
srv_normalize_path_for_win(path);
1859
ut_a(os_file_create_directory(path, FALSE));
1863
#ifndef UNIV_HOTBACKUP
1864
/********************************************************//**
1865
Writes a log record about an .ibd file create/rename/delete. */
1870
ulint type, /*!< in: MLOG_FILE_CREATE,
1872
MLOG_FILE_DELETE, or
1874
ulint space_id, /*!< in: space id */
1875
ulint log_flags, /*!< in: redo log flags (stored
1876
in the page number field) */
1877
ulint flags, /*!< in: compressed page size
1879
if type==MLOG_FILE_CREATE2, or 0 */
1880
const char* name, /*!< in: table name in the familiar
1881
'databasename/tablename' format, or
1882
the file path in the case of
1884
const char* new_name, /*!< in: if type is MLOG_FILE_RENAME,
1885
the new table name in the
1886
'databasename/tablename' format */
1887
mtr_t* mtr) /*!< in: mini-transaction handle */
1892
log_ptr = mlog_open(mtr, 11 + 2 + 1);
1895
/* Logging in mtr is switched off during crash recovery:
1896
in that case mlog_open returns NULL */
1900
log_ptr = mlog_write_initial_log_record_for_file_op(
1901
type, space_id, log_flags, log_ptr, mtr);
1902
if (type == MLOG_FILE_CREATE2) {
1903
mach_write_to_4(log_ptr, flags);
1906
/* Let us store the strings as null-terminated for easier readability
1909
len = strlen(name) + 1;
1911
mach_write_to_2(log_ptr, len);
1913
mlog_close(mtr, log_ptr);
1915
mlog_catenate_string(mtr, (byte*) name, len);
1917
if (type == MLOG_FILE_RENAME) {
1918
len = strlen(new_name) + 1;
1919
log_ptr = mlog_open(mtr, 2 + len);
1921
mach_write_to_2(log_ptr, len);
1923
mlog_close(mtr, log_ptr);
1925
mlog_catenate_string(mtr, (byte*) new_name, len);
1930
/*******************************************************************//**
1931
Parses the body of a log record written about an .ibd file operation. That is,
1932
the log record part after the standard (type, space id, page no) header of the
1935
If desired, also replays the delete or rename operation if the .ibd file
1936
exists and the space id in it matches. Replays the create operation if a file
1937
at that path does not exist yet. If the database directory for the file to be
1938
created does not exist, then we create the directory, too.
1940
Note that ibbackup --apply-log sets fil_path_to_mysql_datadir to point to the
1941
datadir that we should use in replaying the file operations.
1942
@return end of log record, or NULL if the record was not completely
1943
contained between ptr and end_ptr */
1946
fil_op_log_parse_or_replay(
1947
/*=======================*/
1948
byte* ptr, /*!< in: buffer containing the log record body,
1949
or an initial segment of it, if the record does
1950
not fir completely between ptr and end_ptr */
1951
byte* end_ptr, /*!< in: buffer end */
1952
ulint type, /*!< in: the type of this log record */
1953
ulint space_id, /*!< in: the space id of the tablespace in
1954
question, or 0 if the log record should
1955
only be parsed but not replayed */
1956
ulint log_flags) /*!< in: redo log flags
1957
(stored in the page number parameter) */
1962
const char* new_name = NULL;
1965
if (type == MLOG_FILE_CREATE2) {
1966
if (end_ptr < ptr + 4) {
1971
flags = mach_read_from_4(ptr);
1975
if (end_ptr < ptr + 2) {
1980
name_len = mach_read_from_2(ptr);
1984
if (end_ptr < ptr + name_len) {
1989
name = (const char*) ptr;
1993
if (type == MLOG_FILE_RENAME) {
1994
if (end_ptr < ptr + 2) {
1999
new_name_len = mach_read_from_2(ptr);
2003
if (end_ptr < ptr + new_name_len) {
2008
new_name = (const char*) ptr;
2010
ptr += new_name_len;
2013
/* We managed to parse a full log record body */
2015
printf("Parsed log rec of type %lu space %lu\n"
2016
"name %s\n", type, space_id, name);
2018
if (type == MLOG_FILE_RENAME) {
2019
printf("new name %s\n", new_name);
2027
/* Let us try to perform the file operation, if sensible. Note that
2028
ibbackup has at this stage already read in all space id info to the
2029
fil0fil.c data structures.
2031
NOTE that our algorithm is not guaranteed to work correctly if there
2032
were renames of tables during the backup. See ibbackup code for more
2036
case MLOG_FILE_DELETE:
2037
if (fil_tablespace_exists_in_mem(space_id)) {
2038
ut_a(fil_delete_tablespace(space_id));
2043
case MLOG_FILE_RENAME:
2044
/* We do the rename based on space id, not old file name;
2045
this should guarantee that after the log replay each .ibd file
2046
has the correct name for the latest log sequence number; the
2047
proof is left as an exercise :) */
2049
if (fil_tablespace_exists_in_mem(space_id)) {
2050
/* Create the database directory for the new name, if
2051
it does not exist yet */
2052
fil_create_directory_for_tablename(new_name);
2054
/* Rename the table if there is not yet a tablespace
2055
with the same name */
2057
if (fil_get_space_id_for_table(new_name)
2058
== ULINT_UNDEFINED) {
2059
/* We do not care of the old name, that is
2060
why we pass NULL as the first argument */
2061
if (!fil_rename_tablespace(NULL, space_id,
2070
case MLOG_FILE_CREATE:
2071
case MLOG_FILE_CREATE2:
2072
if (fil_tablespace_exists_in_mem(space_id)) {
2074
} else if (fil_get_space_id_for_table(name)
2075
!= ULINT_UNDEFINED) {
2077
} else if (log_flags & MLOG_FILE_FLAG_TEMP) {
2078
/* Temporary table, do nothing */
2080
/* Create the database directory for name, if it does
2082
fil_create_directory_for_tablename(name);
2084
if (fil_create_new_single_table_tablespace(
2085
&space_id, name, FALSE, flags,
2086
FIL_IBD_FILE_INITIAL_SIZE) != DB_SUCCESS) {
2100
/*******************************************************************//**
2101
Deletes a single-table tablespace. The tablespace must be cached in the
2103
@return TRUE if success */
2106
fil_delete_tablespace(
2107
/*==================*/
2108
ulint id) /*!< in: space id */
2118
mutex_enter(&fil_system->mutex);
2120
space = fil_space_get_by_id(id);
2122
if (space != NULL) {
2123
space->stop_ibuf_merges = TRUE;
2125
if (space->n_pending_ibuf_merges == 0) {
2126
mutex_exit(&fil_system->mutex);
2133
ut_print_timestamp(stderr);
2134
fputs(" InnoDB: Warning: trying to"
2135
" delete tablespace ", stderr);
2136
ut_print_filename(stderr, space->name);
2137
fprintf(stderr, ",\n"
2138
"InnoDB: but there are %lu pending"
2139
" ibuf merges on it.\n"
2140
"InnoDB: Loop %lu.\n",
2141
(ulong) space->n_pending_ibuf_merges,
2145
mutex_exit(&fil_system->mutex);
2147
os_thread_sleep(20000);
2150
goto stop_ibuf_merges;
2154
mutex_exit(&fil_system->mutex);
2158
mutex_enter(&fil_system->mutex);
2160
space = fil_space_get_by_id(id);
2162
if (space == NULL) {
2163
ut_print_timestamp(stderr);
2165
" InnoDB: Error: cannot delete tablespace %lu\n"
2166
"InnoDB: because it is not found in the"
2167
" tablespace memory cache.\n",
2170
mutex_exit(&fil_system->mutex);
2176
ut_a(space->n_pending_ibuf_merges == 0);
2178
space->is_being_deleted = TRUE;
2180
ut_a(UT_LIST_GET_LEN(space->chain) == 1);
2181
node = UT_LIST_GET_FIRST(space->chain);
2183
if (space->n_pending_flushes > 0 || node->n_pending > 0) {
2185
ut_print_timestamp(stderr);
2186
fputs(" InnoDB: Warning: trying to"
2187
" delete tablespace ", stderr);
2188
ut_print_filename(stderr, space->name);
2189
fprintf(stderr, ",\n"
2190
"InnoDB: but there are %lu flushes"
2191
" and %lu pending i/o's on it\n"
2192
"InnoDB: Loop %lu.\n",
2193
(ulong) space->n_pending_flushes,
2194
(ulong) node->n_pending,
2197
mutex_exit(&fil_system->mutex);
2198
os_thread_sleep(20000);
2205
path = mem_strdup(space->name);
2207
mutex_exit(&fil_system->mutex);
2208
#ifndef UNIV_HOTBACKUP
2209
/* Invalidate in the buffer pool all pages belonging to the
2210
tablespace. Since we have set space->is_being_deleted = TRUE, readahead
2211
or ibuf merge can no longer read more pages of this tablespace to the
2212
buffer pool. Thus we can clean the tablespace out of the buffer pool
2213
completely and permanently. The flag is_being_deleted also prevents
2214
fil_flush() from being applied to this tablespace. */
2216
buf_LRU_invalidate_tablespace(id);
2218
/* printf("Deleting tablespace %s id %lu\n", space->name, id); */
2220
success = fil_space_free(id);
2223
success = os_file_delete(path);
2226
success = os_file_delete_if_exists(path);
2231
#ifndef UNIV_HOTBACKUP
2232
/* Write a log record about the deletion of the .ibd
2233
file, so that ibbackup can replay it in the
2234
--apply-log phase. We use a dummy mtr and the familiar
2235
log write mechanism. */
2238
/* When replaying the operation in ibbackup, do not try
2239
to write any log record */
2242
fil_op_write_log(MLOG_FILE_DELETE, id, 0, 0, path, NULL, &mtr);
2255
#ifndef UNIV_HOTBACKUP
2256
/*******************************************************************//**
2257
Discards a single-table tablespace. The tablespace must be cached in the
2258
memory cache. Discarding is like deleting a tablespace, but
2259
1) we do not drop the table from the data dictionary;
2260
2) we remove all insert buffer entries for the tablespace immediately; in DROP
2261
TABLE they are only removed gradually in the background;
2262
3) when the user does IMPORT TABLESPACE, the tablespace will have the same id
2263
as it originally had.
2264
@return TRUE if success */
2267
fil_discard_tablespace(
2268
/*===================*/
2269
ulint id) /*!< in: space id */
2273
success = fil_delete_tablespace(id);
2277
"InnoDB: Warning: cannot delete tablespace %lu"
2278
" in DISCARD TABLESPACE.\n"
2279
"InnoDB: But let us remove the"
2280
" insert buffer entries for this tablespace.\n",
2284
/* Remove all insert buffer entries for the tablespace */
2286
ibuf_delete_for_discarded_space(id);
2290
#endif /* !UNIV_HOTBACKUP */
2292
/*******************************************************************//**
2293
Renames the memory cache structures of a single-table tablespace.
2294
@return TRUE if success */
2297
fil_rename_tablespace_in_mem(
2298
/*=========================*/
2299
fil_space_t* space, /*!< in: tablespace memory object */
2300
fil_node_t* node, /*!< in: file node of that tablespace */
2301
const char* path) /*!< in: new name */
2303
fil_space_t* space2;
2304
const char* old_name = space->name;
2306
ut_ad(mutex_own(&fil_system->mutex));
2308
space2 = fil_space_get_by_name(old_name);
2309
if (space != space2) {
2310
fputs("InnoDB: Error: cannot find ", stderr);
2311
ut_print_filename(stderr, old_name);
2312
fputs(" in tablespace memory cache\n", stderr);
2317
space2 = fil_space_get_by_name(path);
2318
if (space2 != NULL) {
2319
fputs("InnoDB: Error: ", stderr);
2320
ut_print_filename(stderr, path);
2321
fputs(" is already in tablespace memory cache\n", stderr);
2326
HASH_DELETE(fil_space_t, name_hash, fil_system->name_hash,
2327
ut_fold_string(space->name), space);
2328
mem_free(space->name);
2329
mem_free(node->name);
2331
space->name = mem_strdup(path);
2332
node->name = mem_strdup(path);
2334
HASH_INSERT(fil_space_t, name_hash, fil_system->name_hash,
2335
ut_fold_string(path), space);
2339
/*******************************************************************//**
2340
Allocates a file name for a single-table tablespace. The string must be freed
2341
by caller with mem_free().
2342
@return own: file name */
2347
const char* name, /*!< in: table name or a dir path of a
2349
ibool is_temp) /*!< in: TRUE if it is a dir path */
2351
ulint namelen = strlen(name);
2352
ulint dirlen = strlen(fil_path_to_mysql_datadir);
2353
char* filename = mem_alloc(namelen + dirlen + sizeof "/.ibd");
2356
memcpy(filename, name, namelen);
2357
memcpy(filename + namelen, ".ibd", sizeof ".ibd");
2359
memcpy(filename, fil_path_to_mysql_datadir, dirlen);
2360
filename[dirlen] = '/';
2362
memcpy(filename + dirlen + 1, name, namelen);
2363
memcpy(filename + dirlen + namelen + 1, ".ibd", sizeof ".ibd");
2366
srv_normalize_path_for_win(filename);
2371
/*******************************************************************//**
2372
Renames a single-table tablespace. The tablespace must be cached in the
2373
tablespace memory cache.
2374
@return TRUE if success */
2377
fil_rename_tablespace(
2378
/*==================*/
2379
const char* old_name, /*!< in: old table name in the standard
2380
databasename/tablename format of
2381
InnoDB, or NULL if we do the rename
2382
based on the space id only */
2383
ulint id, /*!< in: space id */
2384
const char* new_name) /*!< in: new table name in the standard
2385
databasename/tablename format
2393
ibool old_name_was_specified = TRUE;
2398
if (old_name == NULL) {
2399
old_name = "(name not specified)";
2400
old_name_was_specified = FALSE;
2406
ut_print_timestamp(stderr);
2407
fputs(" InnoDB: Warning: problems renaming ", stderr);
2408
ut_print_filename(stderr, old_name);
2409
fputs(" to ", stderr);
2410
ut_print_filename(stderr, new_name);
2411
fprintf(stderr, ", %lu iterations\n", (ulong) count);
2414
mutex_enter(&fil_system->mutex);
2416
space = fil_space_get_by_id(id);
2418
if (space == NULL) {
2420
"InnoDB: Error: cannot find space id %lu"
2421
" in the tablespace memory cache\n"
2422
"InnoDB: though the table ", (ulong) id);
2423
ut_print_filename(stderr, old_name);
2424
fputs(" in a rename operation should have that id\n", stderr);
2425
mutex_exit(&fil_system->mutex);
2430
if (count > 25000) {
2431
space->stop_ios = FALSE;
2432
mutex_exit(&fil_system->mutex);
2437
/* We temporarily close the .ibd file because we do not trust that
2438
operating systems can rename an open file. For the closing we have to
2439
wait until there are no pending i/o's or flushes on the file. */
2441
space->stop_ios = TRUE;
2443
ut_a(UT_LIST_GET_LEN(space->chain) == 1);
2444
node = UT_LIST_GET_FIRST(space->chain);
2446
if (node->n_pending > 0 || node->n_pending_flushes > 0) {
2447
/* There are pending i/o's or flushes, sleep for a while and
2450
mutex_exit(&fil_system->mutex);
2452
os_thread_sleep(20000);
2456
} else if (node->modification_counter > node->flush_counter) {
2457
/* Flush the space */
2459
mutex_exit(&fil_system->mutex);
2461
os_thread_sleep(20000);
2467
} else if (node->open) {
2468
/* Close the file */
2470
fil_node_close_file(node, fil_system);
2473
/* Check that the old name in the space is right */
2475
if (old_name_was_specified) {
2476
old_path = fil_make_ibd_name(old_name, FALSE);
2478
ut_a(strcmp(space->name, old_path) == 0);
2479
ut_a(strcmp(node->name, old_path) == 0);
2481
old_path = mem_strdup(space->name);
2484
/* Rename the tablespace and the node in the memory cache */
2485
path = fil_make_ibd_name(new_name, FALSE);
2486
success = fil_rename_tablespace_in_mem(space, node, path);
2489
success = os_file_rename(old_path, path);
2492
/* We have to revert the changes we made
2493
to the tablespace memory cache */
2495
ut_a(fil_rename_tablespace_in_mem(space, node,
2503
space->stop_ios = FALSE;
2505
mutex_exit(&fil_system->mutex);
2507
#ifndef UNIV_HOTBACKUP
2513
fil_op_write_log(MLOG_FILE_RENAME, id, 0, 0, old_name, new_name,
2521
/*******************************************************************//**
2522
Creates a new single-table tablespace to a database directory of MySQL.
2523
Database directories are under the 'datadir' of MySQL. The datadir is the
2524
directory of a running mysqld program. We can refer to it by simply the
2525
path '.'. Tables created with CREATE TEMPORARY TABLE we place in the temp
2526
dir of the mysqld server.
2527
@return DB_SUCCESS or error code */
2530
fil_create_new_single_table_tablespace(
2531
/*===================================*/
2532
ulint* space_id, /*!< in/out: space id; if this is != 0,
2533
then this is an input parameter,
2535
const char* tablename, /*!< in: the table name in the usual
2536
databasename/tablename format
2537
of InnoDB, or a dir path to a temp
2539
ibool is_temp, /*!< in: TRUE if a table created with
2540
CREATE TEMPORARY TABLE */
2541
ulint flags, /*!< in: tablespace flags */
2542
ulint size) /*!< in: the initial size of the
2543
tablespace file in pages,
2544
must be >= FIL_IBD_FILE_INITIAL_SIZE */
2554
ut_a(size >= FIL_IBD_FILE_INITIAL_SIZE);
2555
/* The tablespace flags (FSP_SPACE_FLAGS) should be 0 for
2556
ROW_FORMAT=COMPACT (table->flags == DICT_TF_COMPACT) and
2557
ROW_FORMAT=REDUNDANT (table->flags == 0). For any other
2558
format, the tablespace flags should equal table->flags. */
2559
ut_a(flags != DICT_TF_COMPACT);
2561
path = fil_make_ibd_name(tablename, is_temp);
2563
file = os_file_create(path, OS_FILE_CREATE, OS_FILE_NORMAL,
2564
OS_DATA_FILE, &ret);
2566
ut_print_timestamp(stderr);
2567
fputs(" InnoDB: Error creating file ", stderr);
2568
ut_print_filename(stderr, path);
2569
fputs(".\n", stderr);
2571
/* The following call will print an error message */
2573
err = os_file_get_last_error(TRUE);
2575
if (err == OS_FILE_ALREADY_EXISTS) {
2576
fputs("InnoDB: The file already exists though"
2577
" the corresponding table did not\n"
2578
"InnoDB: exist in the InnoDB data dictionary."
2579
" Have you moved InnoDB\n"
2580
"InnoDB: .ibd files around without using the"
2582
"InnoDB: DISCARD TABLESPACE and"
2583
" IMPORT TABLESPACE, or did\n"
2584
"InnoDB: mysqld crash in the middle of"
2585
" CREATE TABLE? You can\n"
2586
"InnoDB: resolve the problem by"
2587
" removing the file ", stderr);
2588
ut_print_filename(stderr, path);
2590
"InnoDB: under the 'datadir' of MySQL.\n",
2594
return(DB_TABLESPACE_ALREADY_EXISTS);
2597
if (err == OS_FILE_DISK_FULL) {
2600
return(DB_OUT_OF_FILE_SPACE);
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);
2611
ret = os_file_set_size(path, file, size * UNIV_PAGE_SIZE, 0);
2615
os_file_close(file);
2616
os_file_delete(path);
2619
return(DB_OUT_OF_FILE_SPACE);
2622
if (*space_id == 0) {
2623
*space_id = fil_assign_new_space_id();
2626
/* printf("Creating tablespace %s id %lu\n", path, *space_id); */
2628
if (*space_id == ULINT_UNDEFINED) {
2631
os_file_close(file);
2633
os_file_delete(path);
2639
/* We have to write the space id to the file immediately and flush the
2640
file to disk. This is because in crash recovery we must be aware what
2641
tablespaces exist and what are their space id's, so that we can apply
2642
the log records to the right file. It may take quite a while until
2643
buffer pool flush algorithms write anything to the file and flush it to
2644
disk. If we would not write here anything, the file would be filled
2645
with zeros from the call of os_file_set_size(), until a buffer pool
2646
flush would write to it. */
2648
memset(page, '\0', UNIV_PAGE_SIZE);
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);
2653
if (!(flags & DICT_TF_ZSSIZE_MASK)) {
2654
buf_flush_init_for_writing(page, NULL, 0);
2655
ret = os_file_write(path, file, page, 0, 0, UNIV_PAGE_SIZE);
2657
page_zip_des_t page_zip;
2660
zip_size = ((PAGE_ZIP_MIN_SIZE >> 1)
2661
<< ((flags & DICT_TF_ZSSIZE_MASK)
2662
>> DICT_TF_ZSSIZE_SHIFT));
2664
page_zip_set_size(&page_zip, zip_size);
2665
page_zip.data = page + UNIV_PAGE_SIZE;
2668
#endif /* UNIV_DEBUG */
2669
page_zip.m_end = page_zip.m_nonempty =
2670
page_zip.n_blobs = 0;
2671
buf_flush_init_for_writing(page, &page_zip, 0);
2672
ret = os_file_write(path, file, page_zip.data, 0, 0, zip_size);
2678
fputs("InnoDB: Error: could not write the first page"
2679
" to tablespace ", stderr);
2680
ut_print_filename(stderr, path);
2685
ret = os_file_flush(file);
2688
fputs("InnoDB: Error: file flush of tablespace ", stderr);
2689
ut_print_filename(stderr, path);
2690
fputs(" failed\n", stderr);
2694
os_file_close(file);
2696
if (*space_id == ULINT_UNDEFINED) {
2700
success = fil_space_create(path, *space_id, flags, FIL_TABLESPACE);
2706
fil_node_create(path, size, *space_id, FALSE);
2708
#ifndef UNIV_HOTBACKUP
2714
fil_op_write_log(flags
2718
is_temp ? MLOG_FILE_FLAG_TEMP : 0,
2720
tablename, NULL, &mtr);
2729
#ifndef UNIV_HOTBACKUP
2730
/********************************************************************//**
2731
It is possible, though very improbable, that the lsn's in the tablespace to be
2732
imported have risen above the current system lsn, if a lengthy purge, ibuf
2733
merge, or rollback was performed on a backup taken with ibbackup. If that is
2734
the case, reset page lsn's in the file. We assume that mysqld was shut down
2735
after it performed these cleanup operations on the .ibd file, so that it at
2736
the shutdown stamped the latest lsn to the FIL_PAGE_FILE_FLUSH_LSN in the
2737
first page of the .ibd file, and we can determine whether we need to reset the
2738
lsn's just by looking at that flush lsn.
2739
@return TRUE if success */
2742
fil_reset_too_high_lsns(
2743
/*====================*/
2744
const char* name, /*!< in: table name in the
2745
databasename/tablename format */
2746
ib_uint64_t current_lsn) /*!< in: reset lsn's if the lsn stamped
2747
to FIL_PAGE_FILE_FLUSH_LSN in the
2748
first page is too high */
2754
ib_uint64_t flush_lsn;
2756
ib_int64_t file_size;
2761
filepath = fil_make_ibd_name(name, FALSE);
2763
file = os_file_create_simple_no_error_handling(
2764
filepath, OS_FILE_OPEN, OS_FILE_READ_WRITE, &success);
2766
/* The following call prints an error message */
2767
os_file_get_last_error(TRUE);
2769
ut_print_timestamp(stderr);
2771
fputs(" InnoDB: Error: trying to open a table,"
2773
"InnoDB: open the tablespace file ", stderr);
2774
ut_print_filename(stderr, filepath);
2775
fputs("!\n", stderr);
2781
/* Read the first page of the tablespace */
2783
buf2 = ut_malloc(3 * UNIV_PAGE_SIZE);
2784
/* Align the memory for file i/o if we might have O_DIRECT set */
2785
page = ut_align(buf2, UNIV_PAGE_SIZE);
2787
success = os_file_read(file, page, 0, 0, UNIV_PAGE_SIZE);
2793
/* We have to read the file flush lsn from the header of the file */
2795
flush_lsn = mach_read_ull(page + FIL_PAGE_FILE_FLUSH_LSN);
2797
if (current_lsn >= flush_lsn) {
2804
space_id = fsp_header_get_space_id(page);
2805
zip_size = fsp_header_get_zip_size(page);
2807
ut_print_timestamp(stderr);
2809
" InnoDB: Flush lsn in the tablespace file %lu"
2811
"InnoDB: is %"PRIu64", which exceeds current"
2812
" system lsn %"PRIu64".\n"
2813
"InnoDB: We reset the lsn's in the file ",
2815
flush_lsn, current_lsn);
2816
ut_print_filename(stderr, filepath);
2817
fputs(".\n", stderr);
2819
ut_a(ut_is_2pow(zip_size));
2820
ut_a(zip_size <= UNIV_PAGE_SIZE);
2822
/* Loop through all the pages in the tablespace and reset the lsn and
2823
the page checksum if necessary */
2825
file_size = os_file_get_size_as_iblonglong(file);
2827
for (offset = 0; offset < file_size;
2828
offset += zip_size ? zip_size : UNIV_PAGE_SIZE) {
2829
success = os_file_read(file, page,
2830
(ulint)(offset & 0xFFFFFFFFUL),
2831
(ulint)(offset >> 32),
2832
zip_size ? zip_size : UNIV_PAGE_SIZE);
2837
if (mach_read_ull(page + FIL_PAGE_LSN) > current_lsn) {
2838
/* We have to reset the lsn */
2841
memcpy(page + UNIV_PAGE_SIZE, page, zip_size);
2842
buf_flush_init_for_writing(
2843
page, page + UNIV_PAGE_SIZE,
2846
buf_flush_init_for_writing(
2847
page, NULL, current_lsn);
2849
success = os_file_write(filepath, file, page,
2850
(ulint)(offset & 0xFFFFFFFFUL),
2851
(ulint)(offset >> 32),
2862
success = os_file_flush(file);
2868
/* We now update the flush_lsn stamp at the start of the file */
2869
success = os_file_read(file, page, 0, 0,
2870
zip_size ? zip_size : UNIV_PAGE_SIZE);
2876
mach_write_ull(page + FIL_PAGE_FILE_FLUSH_LSN, current_lsn);
2878
success = os_file_write(filepath, file, page, 0, 0,
2879
zip_size ? zip_size : UNIV_PAGE_SIZE);
2884
success = os_file_flush(file);
2886
os_file_close(file);
2893
/********************************************************************//**
2894
Tries to open a single-table tablespace and optionally checks the space id is
2895
right in it. If does not succeed, prints an error message to the .err log. This
2896
function is used to open a tablespace when we start up mysqld, and also in
2898
NOTE that we assume this operation is used either at the database startup
2899
or under the protection of the dictionary mutex, so that two users cannot
2900
race here. This operation does not leave the file associated with the
2901
tablespace open, but closes it after we have looked at the space id in it.
2902
@return TRUE if success */
2905
fil_open_single_table_tablespace(
2906
/*=============================*/
2907
ibool check_space_id, /*!< in: should we check that the space
2908
id in the file is right; we assume
2909
that this function runs much faster
2910
if no check is made, since accessing
2911
the file inode probably is much
2912
faster (the OS caches them) than
2913
accessing the first page of the file */
2914
ulint id, /*!< in: space id */
2915
ulint flags, /*!< in: tablespace flags */
2916
const char* name) /*!< in: table name in the
2917
databasename/tablename format */
2928
filepath = fil_make_ibd_name(name, FALSE);
2930
/* The tablespace flags (FSP_SPACE_FLAGS) should be 0 for
2931
ROW_FORMAT=COMPACT (table->flags == DICT_TF_COMPACT) and
2932
ROW_FORMAT=REDUNDANT (table->flags == 0). For any other
2933
format, the tablespace flags should equal table->flags. */
2934
ut_a(flags != DICT_TF_COMPACT);
2936
file = os_file_create_simple_no_error_handling(
2937
filepath, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success);
2939
/* The following call prints an error message */
2940
os_file_get_last_error(TRUE);
2942
ut_print_timestamp(stderr);
2944
fputs(" InnoDB: Error: trying to open a table,"
2946
"InnoDB: open the tablespace file ", stderr);
2947
ut_print_filename(stderr, filepath);
2949
"InnoDB: Have you moved InnoDB .ibd files around"
2950
" without using the\n"
2951
"InnoDB: commands DISCARD TABLESPACE and"
2952
" IMPORT TABLESPACE?\n"
2953
"InnoDB: It is also possible that this is"
2954
" a temporary table #sql...,\n"
2955
"InnoDB: and MySQL removed the .ibd file for this.\n"
2956
"InnoDB: Please refer to\n"
2957
"InnoDB: " REFMAN "innodb-troubleshooting-datadict.html\n"
2958
"InnoDB: for how to resolve the issue.\n", stderr);
2965
if (!check_space_id) {
2971
/* Read the first page of the tablespace */
2973
buf2 = ut_malloc(2 * UNIV_PAGE_SIZE);
2974
/* Align the memory for file i/o if we might have O_DIRECT set */
2975
page = ut_align(buf2, UNIV_PAGE_SIZE);
2977
success = os_file_read(file, page, 0, 0, UNIV_PAGE_SIZE);
2979
/* We have to read the tablespace id and flags from the file. */
2981
space_id = fsp_header_get_space_id(page);
2982
space_flags = fsp_header_get_flags(page);
2986
if (UNIV_UNLIKELY(space_id != id || space_flags != flags)) {
2987
ut_print_timestamp(stderr);
2989
fputs(" InnoDB: Error: tablespace id and flags in file ",
2991
ut_print_filename(stderr, filepath);
2992
fprintf(stderr, " are %lu and %lu, but in the InnoDB\n"
2993
"InnoDB: data dictionary they are %lu and %lu.\n"
2994
"InnoDB: Have you moved InnoDB .ibd files"
2995
" around without using the\n"
2996
"InnoDB: commands DISCARD TABLESPACE and"
2997
" IMPORT TABLESPACE?\n"
2998
"InnoDB: Please refer to\n"
2999
"InnoDB: " REFMAN "innodb-troubleshooting-datadict.html\n"
3000
"InnoDB: for how to resolve the issue.\n",
3001
(ulong) space_id, (ulong) space_flags,
3002
(ulong) id, (ulong) flags);
3010
success = fil_space_create(filepath, space_id, flags, FIL_TABLESPACE);
3016
/* We do not measure the size of the file, that is why we pass the 0
3019
fil_node_create(filepath, 0, space_id, FALSE);
3021
os_file_close(file);
3026
#endif /* !UNIV_HOTBACKUP */
3028
#ifdef UNIV_HOTBACKUP
3029
/*******************************************************************//**
3030
Allocates a file name for an old version of a single-table tablespace.
3031
The string must be freed by caller with mem_free()!
3032
@return own: file name */
3035
fil_make_ibbackup_old_name(
3036
/*=======================*/
3037
const char* name) /*!< in: original file name */
3039
static const char suffix[] = "_ibbackup_old_vers_";
3040
ulint len = strlen(name);
3041
char* path = mem_alloc(len + (15 + sizeof suffix));
3043
memcpy(path, name, len);
3044
memcpy(path + len, suffix, (sizeof suffix) - 1);
3045
ut_sprintf_timestamp_without_extra_chars(path + len + sizeof suffix);
3048
#endif /* UNIV_HOTBACKUP */
3050
/********************************************************************//**
3051
Opens an .ibd file and adds the associated single-table tablespace to the
3052
InnoDB fil0fil.c data structures. */
3055
fil_load_single_table_tablespace(
3056
/*=============================*/
3057
const char* dbname, /*!< in: database name */
3058
const char* filename) /*!< in: file name (not a path),
3059
including the .ibd extension */
3071
#ifdef UNIV_HOTBACKUP
3074
filepath = mem_alloc(strlen(dbname) + strlen(filename)
3075
+ strlen(fil_path_to_mysql_datadir) + 3);
3077
sprintf(filepath, "%s/%s/%s", fil_path_to_mysql_datadir, dbname,
3079
srv_normalize_path_for_win(filepath);
3081
# ifndef UNIV_HOTBACKUP
3082
/* If lower_case_table_names is 0 or 2, then MySQL allows database
3083
directory names with upper case letters. On Windows, all table and
3084
database names in InnoDB are internally always in lower case. Put the
3085
file path to lower case, so that we are consistent with InnoDB's
3086
internal data dictionary. */
3088
dict_casedn_str(filepath);
3089
# endif /* !UNIV_HOTBACKUP */
3091
file = os_file_create_simple_no_error_handling(
3092
filepath, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success);
3094
/* The following call prints an error message */
3095
os_file_get_last_error(TRUE);
3098
"InnoDB: Error: could not open single-table tablespace"
3101
"InnoDB: We do not continue the crash recovery,"
3102
" because the table may become\n"
3103
"InnoDB: corrupt if we cannot apply the log records"
3104
" in the InnoDB log to it.\n"
3105
"InnoDB: To fix the problem and start mysqld:\n"
3106
"InnoDB: 1) If there is a permission problem"
3107
" in the file and mysqld cannot\n"
3108
"InnoDB: open the file, you should"
3109
" modify the permissions.\n"
3110
"InnoDB: 2) If the table is not needed, or you can"
3111
" restore it from a backup,\n"
3112
"InnoDB: then you can remove the .ibd file,"
3113
" and InnoDB will do a normal\n"
3114
"InnoDB: crash recovery and ignore that table.\n"
3115
"InnoDB: 3) If the file system or the"
3116
" disk is broken, and you cannot remove\n"
3117
"InnoDB: the .ibd file, you can set"
3118
" innodb_force_recovery > 0 in my.cnf\n"
3119
"InnoDB: and force InnoDB to continue crash"
3120
" recovery here.\n", filepath);
3124
if (srv_force_recovery > 0) {
3126
"InnoDB: innodb_force_recovery"
3127
" was set to %lu. Continuing crash recovery\n"
3128
"InnoDB: even though we cannot access"
3129
" the .ibd file of this table.\n",
3130
srv_force_recovery);
3137
success = os_file_get_size(file, &size_low, &size_high);
3140
/* The following call prints an error message */
3141
os_file_get_last_error(TRUE);
3144
"InnoDB: Error: could not measure the size"
3145
" of single-table tablespace file\n"
3147
"InnoDB: We do not continue crash recovery,"
3148
" because the table will become\n"
3149
"InnoDB: corrupt if we cannot apply the log records"
3150
" in the InnoDB log to it.\n"
3151
"InnoDB: To fix the problem and start mysqld:\n"
3152
"InnoDB: 1) If there is a permission problem"
3153
" in the file and mysqld cannot\n"
3154
"InnoDB: access the file, you should"
3155
" modify the permissions.\n"
3156
"InnoDB: 2) If the table is not needed,"
3157
" or you can restore it from a backup,\n"
3158
"InnoDB: then you can remove the .ibd file,"
3159
" and InnoDB will do a normal\n"
3160
"InnoDB: crash recovery and ignore that table.\n"
3161
"InnoDB: 3) If the file system or the disk is broken,"
3162
" and you cannot remove\n"
3163
"InnoDB: the .ibd file, you can set"
3164
" innodb_force_recovery > 0 in my.cnf\n"
3165
"InnoDB: and force InnoDB to continue"
3166
" crash recovery here.\n", filepath);
3168
os_file_close(file);
3171
if (srv_force_recovery > 0) {
3173
"InnoDB: innodb_force_recovery"
3174
" was set to %lu. Continuing crash recovery\n"
3175
"InnoDB: even though we cannot access"
3176
" the .ibd file of this table.\n",
3177
srv_force_recovery);
3184
/* TODO: What to do in other cases where we cannot access an .ibd
3185
file during a crash recovery? */
3187
/* Every .ibd file is created >= 4 pages in size. Smaller files
3190
size = (((ib_int64_t)size_high) << 32) + (ib_int64_t)size_low;
3191
#ifndef UNIV_HOTBACKUP
3192
if (size < FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE) {
3194
"InnoDB: Error: the size of single-table tablespace"
3196
"InnoDB: is only %lu %lu, should be at least %lu!",
3199
(ulong) size_low, (ulong) (4 * UNIV_PAGE_SIZE));
3200
os_file_close(file);
3206
/* Read the first page of the tablespace if the size big enough */
3208
buf2 = ut_malloc(2 * UNIV_PAGE_SIZE);
3209
/* Align the memory for file i/o if we might have O_DIRECT set */
3210
page = ut_align(buf2, UNIV_PAGE_SIZE);
3212
if (size >= FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE) {
3213
success = os_file_read(file, page, 0, 0, UNIV_PAGE_SIZE);
3215
/* We have to read the tablespace id from the file */
3217
space_id = fsp_header_get_space_id(page);
3218
flags = fsp_header_get_flags(page);
3220
space_id = ULINT_UNDEFINED;
3224
#ifndef UNIV_HOTBACKUP
3225
if (space_id == ULINT_UNDEFINED || space_id == 0) {
3227
"InnoDB: Error: tablespace id %lu in file %s"
3228
" is not sensible\n",
3234
if (space_id == ULINT_UNDEFINED || space_id == 0) {
3238
"InnoDB: Renaming tablespace %s of id %lu,\n"
3239
"InnoDB: to %s_ibbackup_old_vers_<timestamp>\n"
3240
"InnoDB: because its size %lld is too small"
3241
" (< 4 pages 16 kB each),\n"
3242
"InnoDB: or the space id in the file header"
3243
" is not sensible.\n"
3244
"InnoDB: This can happen in an ibbackup run,"
3245
" and is not dangerous.\n",
3246
filepath, space_id, filepath, size);
3247
os_file_close(file);
3249
new_path = fil_make_ibbackup_old_name(filepath);
3250
ut_a(os_file_rename(filepath, new_path));
3259
/* A backup may contain the same space several times, if the space got
3260
renamed at a sensitive time. Since it is enough to have one version of
3261
the space, we rename the file if a space with the same space id
3262
already exists in the tablespace memory cache. We rather rename the
3263
file than delete it, because if there is a bug, we do not want to
3264
destroy valuable data. */
3266
mutex_enter(&fil_system->mutex);
3268
space = fil_space_get_by_id(space_id);
3274
"InnoDB: Renaming tablespace %s of id %lu,\n"
3275
"InnoDB: to %s_ibbackup_old_vers_<timestamp>\n"
3276
"InnoDB: because space %s with the same id\n"
3277
"InnoDB: was scanned earlier. This can happen"
3278
" if you have renamed tables\n"
3279
"InnoDB: during an ibbackup run.\n",
3280
filepath, space_id, filepath,
3282
os_file_close(file);
3284
new_path = fil_make_ibbackup_old_name(filepath);
3286
mutex_exit(&fil_system->mutex);
3288
ut_a(os_file_rename(filepath, new_path));
3296
mutex_exit(&fil_system->mutex);
3298
success = fil_space_create(filepath, space_id, flags, FIL_TABLESPACE);
3305
/* We do not use the size information we have about the file, because
3306
the rounding formula for extents and pages is somewhat complex; we
3307
let fil_node_open() do that task. */
3309
fil_node_create(filepath, 0, space_id, FALSE);
3311
os_file_close(file);
3316
/***********************************************************************//**
3317
A fault-tolerant function that tries to read the next file name in the
3318
directory. We retry 100 times if os_file_readdir_next_file() returns -1. The
3319
idea is to read as much good data as we can and jump over bad data.
3320
@return 0 if ok, -1 if error even after the retries, 1 if at the end
3324
fil_file_readdir_next_file(
3325
/*=======================*/
3326
ulint* err, /*!< out: this is set to DB_ERROR if an error
3327
was encountered, otherwise not changed */
3328
const char* dirname,/*!< in: directory name or path */
3329
os_file_dir_t dir, /*!< in: directory stream */
3330
os_file_stat_t* info) /*!< in/out: buffer where the info is returned */
3335
for (i = 0; i < 100; i++) {
3336
ret = os_file_readdir_next_file(dirname, dir, info);
3344
"InnoDB: Error: os_file_readdir_next_file()"
3346
"InnoDB: directory %s\n"
3347
"InnoDB: Crash recovery may have failed"
3348
" for some .ibd files!\n", dirname);
3356
/********************************************************************//**
3357
At the server startup, if we need crash recovery, scans the database
3358
directories under the MySQL datadir, looking for .ibd files. Those files are
3359
single-table tablespaces. We need to know the space id in each of them so that
3360
we know into which file we should look to check the contents of a page stored
3361
in the doublewrite buffer, also to know where to apply log records where the
3363
@return DB_SUCCESS or error number */
3366
fil_load_single_table_tablespaces(void)
3367
/*===================================*/
3370
char* dbpath = NULL;
3371
ulint dbpath_len = 100;
3373
os_file_dir_t dbdir;
3374
os_file_stat_t dbinfo;
3375
os_file_stat_t fileinfo;
3376
ulint err = DB_SUCCESS;
3378
/* The datadir of MySQL is always the default directory of mysqld */
3380
dir = os_file_opendir(fil_path_to_mysql_datadir, TRUE);
3387
dbpath = mem_alloc(dbpath_len);
3389
/* Scan all directories under the datadir. They are the database
3390
directories of MySQL. */
3392
ret = fil_file_readdir_next_file(&err, fil_path_to_mysql_datadir, dir,
3396
/* printf("Looking at %s in datadir\n", dbinfo.name); */
3398
if (dbinfo.type == OS_FILE_TYPE_FILE
3399
|| dbinfo.type == OS_FILE_TYPE_UNKNOWN) {
3401
goto next_datadir_item;
3404
/* We found a symlink or a directory; try opening it to see
3405
if a symlink is a directory */
3407
len = strlen(fil_path_to_mysql_datadir)
3408
+ strlen (dbinfo.name) + 2;
3409
if (len > dbpath_len) {
3416
dbpath = mem_alloc(dbpath_len);
3418
sprintf(dbpath, "%s/%s", fil_path_to_mysql_datadir,
3420
srv_normalize_path_for_win(dbpath);
3422
dbdir = os_file_opendir(dbpath, FALSE);
3424
if (dbdir != NULL) {
3425
/* printf("Opened dir %s\n", dbinfo.name); */
3427
/* We found a database directory; loop through it,
3428
looking for possible .ibd files in it */
3430
ret = fil_file_readdir_next_file(&err, dbpath, dbdir,
3434
" Looking at file %s\n", fileinfo.name); */
3436
if (fileinfo.type == OS_FILE_TYPE_DIR) {
3438
goto next_file_item;
3441
/* We found a symlink or a file */
3442
if (strlen(fileinfo.name) > 4
3443
&& 0 == strcmp(fileinfo.name
3444
+ strlen(fileinfo.name) - 4,
3446
/* The name ends in .ibd; try opening
3448
fil_load_single_table_tablespace(
3449
dbinfo.name, fileinfo.name);
3452
ret = fil_file_readdir_next_file(&err,
3457
if (0 != os_file_closedir(dbdir)) {
3458
fputs("InnoDB: Warning: could not"
3459
" close database directory ", stderr);
3460
ut_print_filename(stderr, dbpath);
3468
ret = fil_file_readdir_next_file(&err,
3469
fil_path_to_mysql_datadir,
3475
if (0 != os_file_closedir(dir)) {
3477
"InnoDB: Error: could not close MySQL datadir\n");
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
3493
fil_print_orphaned_tablespaces(void)
3494
/*================================*/
3498
mutex_enter(&fil_system->mutex);
3500
space = UT_LIST_GET_FIRST(fil_system->space_list);
3503
if (space->purpose == FIL_TABLESPACE && space->id != 0
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",
3512
space = UT_LIST_GET_NEXT(space_list, space);
3515
mutex_exit(&fil_system->mutex);
3518
/*******************************************************************//**
3519
Returns TRUE if a single-table tablespace does not exist in the memory cache,
3520
or is being deleted there.
3521
@return TRUE if does not exist or is being\ deleted */
3524
fil_tablespace_deleted_or_being_deleted_in_mem(
3525
/*===========================================*/
3526
ulint id, /*!< in: space id */
3527
ib_int64_t version)/*!< in: tablespace_version should be this; if
3528
you pass -1 as the value of this, then this
3529
parameter is ignored */
3535
mutex_enter(&fil_system->mutex);
3537
space = fil_space_get_by_id(id);
3539
if (space == NULL || space->is_being_deleted) {
3540
mutex_exit(&fil_system->mutex);
3545
if (version != ((ib_int64_t)-1)
3546
&& space->tablespace_version != version) {
3547
mutex_exit(&fil_system->mutex);
3552
mutex_exit(&fil_system->mutex);
3557
/*******************************************************************//**
3558
Returns TRUE if a single-table tablespace exists in the memory cache.
3559
@return TRUE if exists */
3562
fil_tablespace_exists_in_mem(
3563
/*=========================*/
3564
ulint id) /*!< in: space id */
3570
mutex_enter(&fil_system->mutex);
3572
space = fil_space_get_by_id(id);
3574
mutex_exit(&fil_system->mutex);
3576
return(space != NULL);
3579
/*******************************************************************//**
3580
Returns TRUE if a matching tablespace exists in the InnoDB tablespace memory
3581
cache. Note that if we have not done a crash recovery at the database startup,
3582
there may be many tablespaces which are not yet in the memory cache.
3583
@return TRUE if a matching tablespace exists in the memory cache */
3586
fil_space_for_table_exists_in_mem(
3587
/*==============================*/
3588
ulint id, /*!< in: space id */
3589
const char* name, /*!< in: table name in the standard
3590
'databasename/tablename' format or
3591
the dir path to a temp table */
3592
ibool is_temp, /*!< in: TRUE if created with CREATE
3594
ibool mark_space, /*!< in: in crash recovery, at database
3595
startup we mark all spaces which have
3596
an associated table in the InnoDB
3597
data dictionary, so that
3598
we can print a warning about orphaned
3600
ibool print_error_if_does_not_exist)
3601
/*!< in: print detailed error
3602
information to the .err log if a
3603
matching tablespace is not found from
3606
fil_space_t* namespace;
3612
mutex_enter(&fil_system->mutex);
3614
path = fil_make_ibd_name(name, is_temp);
3616
/* Look if there is a space with the same id */
3618
space = fil_space_get_by_id(id);
3620
/* Look if there is a space with the same name; the name is the
3621
directory path from the datadir to the file */
3623
namespace = fil_space_get_by_name(path);
3624
if (space && space == namespace) {
3632
mutex_exit(&fil_system->mutex);
3637
if (!print_error_if_does_not_exist) {
3640
mutex_exit(&fil_system->mutex);
3645
if (space == NULL) {
3646
if (namespace == NULL) {
3647
ut_print_timestamp(stderr);
3648
fputs(" InnoDB: Error: table ", stderr);
3649
ut_print_filename(stderr, name);
3650
fprintf(stderr, "\n"
3651
"InnoDB: in InnoDB data dictionary"
3652
" has tablespace id %lu,\n"
3653
"InnoDB: but tablespace with that id"
3654
" or name does not exist. Have\n"
3655
"InnoDB: you deleted or moved .ibd files?\n"
3656
"InnoDB: This may also be a table created with"
3657
" CREATE TEMPORARY TABLE\n"
3658
"InnoDB: whose .ibd and .frm files"
3659
" MySQL automatically removed, but the\n"
3660
"InnoDB: table still exists in the"
3661
" InnoDB internal data dictionary.\n",
3664
ut_print_timestamp(stderr);
3665
fputs(" InnoDB: Error: table ", stderr);
3666
ut_print_filename(stderr, name);
3667
fprintf(stderr, "\n"
3668
"InnoDB: in InnoDB data dictionary has"
3669
" tablespace id %lu,\n"
3670
"InnoDB: but a tablespace with that id"
3671
" does not exist. There is\n"
3672
"InnoDB: a tablespace of name %s and id %lu,"
3674
"InnoDB: you deleted or moved .ibd files?\n",
3675
(ulong) id, namespace->name,
3676
(ulong) namespace->id);
3679
fputs("InnoDB: Please refer to\n"
3680
"InnoDB: " REFMAN "innodb-troubleshooting-datadict.html\n"
3681
"InnoDB: for how to resolve the issue.\n", stderr);
3684
mutex_exit(&fil_system->mutex);
3689
if (0 != strcmp(space->name, path)) {
3690
ut_print_timestamp(stderr);
3691
fputs(" InnoDB: Error: table ", stderr);
3692
ut_print_filename(stderr, name);
3693
fprintf(stderr, "\n"
3694
"InnoDB: in InnoDB data dictionary has"
3695
" tablespace id %lu,\n"
3696
"InnoDB: but the tablespace with that id"
3698
"InnoDB: Have you deleted or moved .ibd files?\n",
3699
(ulong) id, space->name);
3701
if (namespace != NULL) {
3702
fputs("InnoDB: There is a tablespace"
3703
" with the right name\n"
3704
"InnoDB: ", stderr);
3705
ut_print_filename(stderr, namespace->name);
3706
fprintf(stderr, ", but its id is %lu.\n",
3707
(ulong) namespace->id);
3714
mutex_exit(&fil_system->mutex);
3719
/*******************************************************************//**
3720
Checks if a single-table tablespace for a given table name exists in the
3721
tablespace memory cache.
3722
@return space id, ULINT_UNDEFINED if not found */
3725
fil_get_space_id_for_table(
3726
/*=======================*/
3727
const char* name) /*!< in: table name in the standard
3728
'databasename/tablename' format */
3730
fil_space_t* namespace;
3731
ulint id = ULINT_UNDEFINED;
3736
mutex_enter(&fil_system->mutex);
3738
path = fil_make_ibd_name(name, FALSE);
3740
/* Look if there is a space with the same name; the name is the
3741
directory path to the file */
3743
namespace = fil_space_get_by_name(path);
3751
mutex_exit(&fil_system->mutex);
3756
/**********************************************************************//**
3757
Tries to extend a data file so that it would accommodate the number of pages
3758
given. The tablespace must be cached in the memory cache. If the space is big
3759
enough already, does nothing.
3760
@return TRUE if success */
3763
fil_extend_space_to_desired_size(
3764
/*=============================*/
3765
ulint* actual_size, /*!< out: size of the space after extension;
3766
if we ran out of disk space this may be lower
3767
than the desired size */
3768
ulint space_id, /*!< in: space id */
3769
ulint size_after_extend)/*!< in: desired size in pages after the
3770
extension; if the current space size is bigger
3771
than this already, the function does nothing */
3778
ulint start_page_no;
3779
ulint file_start_page_no;
3783
ibool success = TRUE;
3785
fil_mutex_enter_and_prepare_for_io(space_id);
3787
space = fil_space_get_by_id(space_id);
3790
if (space->size >= size_after_extend) {
3791
/* Space already big enough */
3793
*actual_size = space->size;
3795
mutex_exit(&fil_system->mutex);
3800
page_size = dict_table_flags_to_zip_size(space->flags);
3802
page_size = UNIV_PAGE_SIZE;
3805
node = UT_LIST_GET_LAST(space->chain);
3807
fil_node_prepare_for_io(node, fil_system, space);
3809
start_page_no = space->size;
3810
file_start_page_no = space->size - node->size;
3812
/* Extend at most 64 pages at a time */
3813
buf_size = ut_min(64, size_after_extend - start_page_no) * page_size;
3814
buf2 = mem_alloc(buf_size + page_size);
3815
buf = ut_align(buf2, page_size);
3817
memset(buf, 0, buf_size);
3819
while (start_page_no < size_after_extend) {
3820
ulint n_pages = ut_min(buf_size / page_size,
3821
size_after_extend - start_page_no);
3823
offset_high = (start_page_no - file_start_page_no)
3824
/ (4096 * ((1024 * 1024) / page_size));
3825
offset_low = ((start_page_no - file_start_page_no)
3826
% (4096 * ((1024 * 1024) / page_size)))
3828
#ifdef UNIV_HOTBACKUP
3829
success = os_file_write(node->name, node->handle, buf,
3830
offset_low, offset_high,
3831
page_size * n_pages);
3833
success = os_aio(OS_FILE_WRITE, OS_AIO_SYNC,
3834
node->name, node->handle, buf,
3835
offset_low, offset_high,
3836
page_size * n_pages,
3840
node->size += n_pages;
3841
space->size += n_pages;
3843
os_has_said_disk_full = FALSE;
3845
/* Let us measure the size of the file to determine
3846
how much we were able to extend it */
3849
(os_file_get_size_as_iblonglong(
3851
/ page_size)) - node->size;
3853
node->size += n_pages;
3854
space->size += n_pages;
3859
start_page_no += n_pages;
3864
fil_node_complete_io(node, fil_system, OS_FILE_WRITE);
3866
*actual_size = space->size;
3868
#ifndef UNIV_HOTBACKUP
3869
if (space_id == 0) {
3870
ulint pages_per_mb = (1024 * 1024) / page_size;
3872
/* Keep the last data file size info up to date, rounded to
3875
srv_data_file_sizes[srv_n_data_files - 1]
3876
= (node->size / pages_per_mb) * pages_per_mb;
3878
#endif /* !UNIV_HOTBACKUP */
3881
printf("Extended %s to %lu, actual size %lu pages\n", space->name,
3882
size_after_extend, *actual_size); */
3883
mutex_exit(&fil_system->mutex);
3885
fil_flush(space_id);
3890
#ifdef UNIV_HOTBACKUP
3891
/********************************************************************//**
3892
Extends all tablespaces to the size stored in the space header. During the
3893
ibbackup --apply-log phase we extended the spaces on-demand so that log records
3894
could be applied, but that may have left spaces still too small compared to
3895
the size stored in the space header. */
3898
fil_extend_tablespaces_to_stored_len(void)
3899
/*======================================*/
3904
ulint size_in_header;
3908
buf = mem_alloc(UNIV_PAGE_SIZE);
3910
mutex_enter(&fil_system->mutex);
3912
space = UT_LIST_GET_FIRST(fil_system->space_list);
3915
ut_a(space->purpose == FIL_TABLESPACE);
3917
mutex_exit(&fil_system->mutex); /* no need to protect with a
3918
mutex, because this is a
3919
single-threaded operation */
3920
error = fil_read(TRUE, space->id,
3921
dict_table_flags_to_zip_size(space->flags),
3922
0, 0, UNIV_PAGE_SIZE, buf, NULL);
3923
ut_a(error == DB_SUCCESS);
3925
size_in_header = fsp_get_size_low(buf);
3927
success = fil_extend_space_to_desired_size(
3928
&actual_size, space->id, size_in_header);
3931
"InnoDB: Error: could not extend the"
3932
" tablespace of %s\n"
3933
"InnoDB: to the size stored in header,"
3935
"InnoDB: size after extension %lu pages\n"
3936
"InnoDB: Check that you have free disk space"
3938
space->name, size_in_header, actual_size);
3942
mutex_enter(&fil_system->mutex);
3944
space = UT_LIST_GET_NEXT(space_list, space);
3947
mutex_exit(&fil_system->mutex);
3953
/*========== RESERVE FREE EXTENTS (for a B-tree split, for example) ===*/
3955
/*******************************************************************//**
3956
Tries to reserve free extents in a file space.
3957
@return TRUE if succeed */
3960
fil_space_reserve_free_extents(
3961
/*===========================*/
3962
ulint id, /*!< in: space id */
3963
ulint n_free_now, /*!< in: number of free extents now */
3964
ulint n_to_reserve) /*!< in: how many one wants to reserve */
3971
mutex_enter(&fil_system->mutex);
3973
space = fil_space_get_by_id(id);
3977
if (space->n_reserved_extents + n_to_reserve > n_free_now) {
3980
space->n_reserved_extents += n_to_reserve;
3984
mutex_exit(&fil_system->mutex);
3989
/*******************************************************************//**
3990
Releases free extents in a file space. */
3993
fil_space_release_free_extents(
3994
/*===========================*/
3995
ulint id, /*!< in: space id */
3996
ulint n_reserved) /*!< in: how many one reserved */
4002
mutex_enter(&fil_system->mutex);
4004
space = fil_space_get_by_id(id);
4007
ut_a(space->n_reserved_extents >= n_reserved);
4009
space->n_reserved_extents -= n_reserved;
4011
mutex_exit(&fil_system->mutex);
4014
/*******************************************************************//**
4015
Gets the number of reserved extents. If the database is silent, this number
4019
fil_space_get_n_reserved_extents(
4020
/*=============================*/
4021
ulint id) /*!< in: space id */
4028
mutex_enter(&fil_system->mutex);
4030
space = fil_space_get_by_id(id);
4034
n = space->n_reserved_extents;
4036
mutex_exit(&fil_system->mutex);
4041
/*============================ FILE I/O ================================*/
4043
/********************************************************************//**
4044
NOTE: you must call fil_mutex_enter_and_prepare_for_io() first!
4046
Prepares a file node for i/o. Opens the file if it is closed. Updates the
4047
pending i/o's field in the node and the system appropriately. Takes the node
4048
off the LRU list if it is in the LRU list. The caller must hold the fil_sys
4052
fil_node_prepare_for_io(
4053
/*====================*/
4054
fil_node_t* node, /*!< in: file node */
4055
fil_system_t* system, /*!< in: tablespace memory cache */
4056
fil_space_t* space) /*!< in: space */
4058
ut_ad(node && system && space);
4059
ut_ad(mutex_own(&(system->mutex)));
4061
if (system->n_open > system->max_n_open + 5) {
4062
ut_print_timestamp(stderr);
4064
" InnoDB: Warning: open files %lu"
4065
" exceeds the limit %lu\n",
4066
(ulong) system->n_open,
4067
(ulong) system->max_n_open);
4070
if (node->open == FALSE) {
4071
/* File is closed: open it */
4072
ut_a(node->n_pending == 0);
4074
fil_node_open_file(node, system, space);
4077
if (node->n_pending == 0 && space->purpose == FIL_TABLESPACE
4078
&& space->id != 0) {
4079
/* The node is in the LRU list, remove it */
4081
ut_a(UT_LIST_GET_LEN(system->LRU) > 0);
4083
UT_LIST_REMOVE(LRU, system->LRU, node);
4089
/********************************************************************//**
4090
Updates the data structures when an i/o operation finishes. Updates the
4091
pending i/o's field in the node appropriately. */
4094
fil_node_complete_io(
4095
/*=================*/
4096
fil_node_t* node, /*!< in: file node */
4097
fil_system_t* system, /*!< in: tablespace memory cache */
4098
ulint type) /*!< in: OS_FILE_WRITE or OS_FILE_READ; marks
4099
the node as modified if
4100
type == OS_FILE_WRITE */
4104
ut_ad(mutex_own(&(system->mutex)));
4106
ut_a(node->n_pending > 0);
4110
if (type == OS_FILE_WRITE) {
4111
system->modification_counter++;
4112
node->modification_counter = system->modification_counter;
4114
if (!node->space->is_in_unflushed_spaces) {
4116
node->space->is_in_unflushed_spaces = TRUE;
4117
UT_LIST_ADD_FIRST(unflushed_spaces,
4118
system->unflushed_spaces,
4123
if (node->n_pending == 0 && node->space->purpose == FIL_TABLESPACE
4124
&& node->space->id != 0) {
4125
/* The node must be put back to the LRU list */
4126
UT_LIST_ADD_FIRST(LRU, system->LRU, node);
4130
/********************************************************************//**
4131
Report information about an invalid page access. */
4134
fil_report_invalid_page_access(
4135
/*===========================*/
4136
ulint block_offset, /*!< in: block offset */
4137
ulint space_id, /*!< in: space id */
4138
const char* space_name, /*!< in: space name */
4139
ulint byte_offset, /*!< in: byte offset */
4140
ulint len, /*!< in: I/O length */
4141
ulint type) /*!< in: I/O type */
4144
"InnoDB: Error: trying to access page number %lu"
4146
"InnoDB: space name %s,\n"
4147
"InnoDB: which is outside the tablespace bounds.\n"
4148
"InnoDB: Byte offset %lu, len %lu, i/o type %lu.\n"
4149
"InnoDB: If you get this error at mysqld startup,"
4150
" please check that\n"
4151
"InnoDB: your my.cnf matches the ibdata files"
4152
" that you have in the\n"
4153
"InnoDB: MySQL server.\n",
4154
(ulong) block_offset, (ulong) space_id, space_name,
4155
(ulong) byte_offset, (ulong) len, (ulong) type);
4158
/********************************************************************//**
4159
Reads or writes data. This operation is asynchronous (aio).
4160
@return DB_SUCCESS, or DB_TABLESPACE_DELETED if we are trying to do
4161
i/o on a tablespace which does not exist */
4166
ulint type, /*!< in: OS_FILE_READ or OS_FILE_WRITE,
4167
ORed to OS_FILE_LOG, if a log i/o
4168
and ORed to OS_AIO_SIMULATED_WAKE_LATER
4169
if simulated aio and we want to post a
4170
batch of i/os; NOTE that a simulated batch
4171
may introduce hidden chances of deadlocks,
4172
because i/os are not actually handled until
4173
all have been posted: use with great
4175
ibool sync, /*!< in: TRUE if synchronous aio is desired */
4176
ulint space_id, /*!< in: space id */
4177
ulint zip_size, /*!< in: compressed page size in bytes;
4178
0 for uncompressed pages */
4179
ulint block_offset, /*!< in: offset in number of blocks */
4180
ulint byte_offset, /*!< in: remainder of offset in bytes; in
4181
aio this must be divisible by the OS block
4183
ulint len, /*!< in: how many bytes to read or write; this
4184
must not cross a file boundary; in aio this
4185
must be a block size multiple */
4186
void* buf, /*!< in/out: buffer where to store read data
4187
or from where to write; in aio this must be
4188
appropriately aligned */
4189
void* message) /*!< in: message for aio handler if non-sync
4190
aio used, else ignored */
4201
is_log = type & OS_FILE_LOG;
4202
type = type & ~OS_FILE_LOG;
4204
wake_later = type & OS_AIO_SIMULATED_WAKE_LATER;
4205
type = type & ~OS_AIO_SIMULATED_WAKE_LATER;
4207
ut_ad(byte_offset < UNIV_PAGE_SIZE);
4208
ut_ad(!zip_size || !byte_offset);
4209
ut_ad(ut_is_2pow(zip_size));
4212
#if (1 << UNIV_PAGE_SIZE_SHIFT) != UNIV_PAGE_SIZE
4213
# error "(1 << UNIV_PAGE_SIZE_SHIFT) != UNIV_PAGE_SIZE"
4215
ut_ad(fil_validate());
4216
#ifndef UNIV_HOTBACKUP
4217
# ifndef UNIV_LOG_DEBUG
4218
/* ibuf bitmap pages must be read in the sync aio mode: */
4219
ut_ad(recv_no_ibuf_operations || (type == OS_FILE_WRITE)
4220
|| !ibuf_bitmap_page(zip_size, block_offset)
4222
ut_ad(!ibuf_inside() || is_log || (type == OS_FILE_WRITE)
4223
|| ibuf_page(space_id, zip_size, block_offset, NULL));
4224
# endif /* UNIV_LOG_DEBUG */
4227
} else if (is_log) {
4229
} else if (type == OS_FILE_READ
4230
&& !recv_no_ibuf_operations
4231
&& ibuf_page(space_id, zip_size, block_offset, NULL)) {
4234
mode = OS_AIO_NORMAL;
4236
#else /* !UNIV_HOTBACKUP */
4239
#endif /* !UNIV_HOTBACKUP */
4241
if (type == OS_FILE_READ) {
4242
srv_data_read+= len;
4243
} else if (type == OS_FILE_WRITE) {
4244
srv_data_written+= len;
4247
/* Reserve the fil_system mutex and make sure that we can open at
4248
least one file while holding it, if the file is not already open */
4250
fil_mutex_enter_and_prepare_for_io(space_id);
4252
space = fil_space_get_by_id(space_id);
4255
mutex_exit(&fil_system->mutex);
4257
ut_print_timestamp(stderr);
4259
" InnoDB: Error: trying to do i/o"
4260
" to a tablespace which does not exist.\n"
4261
"InnoDB: i/o type %lu, space id %lu,"
4262
" page no. %lu, i/o length %lu bytes\n",
4263
(ulong) type, (ulong) space_id, (ulong) block_offset,
4266
return(DB_TABLESPACE_DELETED);
4269
ut_ad((mode != OS_AIO_IBUF) || (space->purpose == FIL_TABLESPACE));
4271
node = UT_LIST_GET_FIRST(space->chain);
4274
if (UNIV_UNLIKELY(node == NULL)) {
4275
fil_report_invalid_page_access(
4276
block_offset, space_id, space->name,
4277
byte_offset, len, type);
4282
if (space->id != 0 && node->size == 0) {
4283
/* We do not know the size of a single-table tablespace
4284
before we open the file */
4289
if (node->size > block_offset) {
4293
block_offset -= node->size;
4294
node = UT_LIST_GET_NEXT(chain, node);
4298
/* Open file if closed */
4299
fil_node_prepare_for_io(node, fil_system, space);
4301
/* Check that at least the start offset is within the bounds of a
4302
single-table tablespace */
4303
if (UNIV_UNLIKELY(node->size <= block_offset)
4304
&& space->id != 0 && space->purpose == FIL_TABLESPACE) {
4306
fil_report_invalid_page_access(
4307
block_offset, space_id, space->name, byte_offset,
4313
/* Now we have made the changes in the data structures of fil_system */
4314
mutex_exit(&fil_system->mutex);
4316
/* Calculate the low 32 bits and the high 32 bits of the file offset */
4319
offset_high = (block_offset >> (32 - UNIV_PAGE_SIZE_SHIFT));
4320
offset_low = ((block_offset << UNIV_PAGE_SIZE_SHIFT)
4321
& 0xFFFFFFFFUL) + byte_offset;
4323
ut_a(node->size - block_offset
4324
>= ((byte_offset + len + (UNIV_PAGE_SIZE - 1))
4327
ulint zip_size_shift;
4329
case 1024: zip_size_shift = 10; break;
4330
case 2048: zip_size_shift = 11; break;
4331
case 4096: zip_size_shift = 12; break;
4332
case 8192: zip_size_shift = 13; break;
4333
case 16384: zip_size_shift = 14; break;
4336
offset_high = block_offset >> (32 - zip_size_shift);
4337
offset_low = (block_offset << zip_size_shift & 0xFFFFFFFFUL)
4339
ut_a(node->size - block_offset
4340
>= (len + (zip_size - 1)) / zip_size);
4345
ut_a(byte_offset % OS_FILE_LOG_BLOCK_SIZE == 0);
4346
ut_a((len % OS_FILE_LOG_BLOCK_SIZE) == 0);
4348
#ifdef UNIV_HOTBACKUP
4349
/* In ibbackup do normal i/o, not aio */
4350
if (type == OS_FILE_READ) {
4351
ret = os_file_read(node->handle, buf, offset_low, offset_high,
4354
ret = os_file_write(node->name, node->handle, buf,
4355
offset_low, offset_high, len);
4358
/* Queue the aio request */
4359
ret = os_aio(type, mode | wake_later, node->name, node->handle, buf,
4360
offset_low, offset_high, len, node, message);
4364
if (mode == OS_AIO_SYNC) {
4365
/* The i/o operation is already completed when we return from
4368
mutex_enter(&fil_system->mutex);
4370
fil_node_complete_io(node, fil_system, type);
4372
mutex_exit(&fil_system->mutex);
4374
ut_ad(fil_validate());
4380
#ifndef UNIV_HOTBACKUP
4381
/**********************************************************************//**
4382
Waits for an aio operation to complete. This function is used to write the
4383
handler for completed requests. The aio array of pending requests is divided
4384
into segments (see os0file.c for more info). The thread specifies which
4385
segment it wants to wait for. */
4390
ulint segment) /*!< in: the number of the segment in the aio
4391
array to wait for */
4394
fil_node_t* fil_node;
4398
ut_ad(fil_validate());
4400
if (os_aio_use_native_aio) {
4401
srv_set_io_thread_op_info(segment, "native aio handle");
4403
ret = os_aio_windows_handle(segment, 0, &fil_node,
4406
ret = 0; /* Eliminate compiler warning */
4410
srv_set_io_thread_op_info(segment, "simulated aio handle");
4412
ret = os_aio_simulated_handle(segment, &fil_node,
4418
srv_set_io_thread_op_info(segment, "complete io for fil node");
4420
mutex_enter(&fil_system->mutex);
4422
fil_node_complete_io(fil_node, fil_system, type);
4424
mutex_exit(&fil_system->mutex);
4426
ut_ad(fil_validate());
4428
/* Do the i/o handling */
4429
/* IMPORTANT: since i/o handling for reads will read also the insert
4430
buffer in tablespace 0, you have to be very careful not to introduce
4431
deadlocks in the i/o system. We keep tablespace 0 data files always
4432
open, and use a special i/o thread to serve insert buffer requests. */
4434
if (fil_node->space->purpose == FIL_TABLESPACE) {
4435
srv_set_io_thread_op_info(segment, "complete io for buf page");
4436
buf_page_io_complete(message);
4438
srv_set_io_thread_op_info(segment, "complete io for log");
4439
log_io_complete(message);
4442
#endif /* UNIV_HOTBACKUP */
4444
/**********************************************************************//**
4445
Flushes to disk possible writes cached by the OS. If the space does not exist
4446
or is being dropped, does not do anything. */
4451
ulint space_id) /*!< in: file space id (this can be a group of
4452
log files or a tablespace of the database) */
4457
ib_int64_t old_mod_counter;
4459
mutex_enter(&fil_system->mutex);
4461
space = fil_space_get_by_id(space_id);
4463
if (!space || space->is_being_deleted) {
4464
mutex_exit(&fil_system->mutex);
4469
space->n_pending_flushes++; /*!< prevent dropping of the space while
4471
node = UT_LIST_GET_FIRST(space->chain);
4474
if (node->modification_counter > node->flush_counter) {
4477
/* We want to flush the changes at least up to
4479
old_mod_counter = node->modification_counter;
4481
if (space->purpose == FIL_TABLESPACE) {
4482
fil_n_pending_tablespace_flushes++;
4484
fil_n_pending_log_flushes++;
4485
fil_n_log_flushes++;
4488
if (node->is_raw_disk) {
4494
if (node->n_pending_flushes > 0) {
4495
/* We want to avoid calling os_file_flush() on
4496
the file twice at the same time, because we do
4497
not know what bugs OS's may contain in file
4498
i/o; sleep for a while */
4500
mutex_exit(&fil_system->mutex);
4502
os_thread_sleep(20000);
4504
mutex_enter(&fil_system->mutex);
4506
if (node->flush_counter >= old_mod_counter) {
4515
file = node->handle;
4516
node->n_pending_flushes++;
4518
mutex_exit(&fil_system->mutex);
4520
/* fprintf(stderr, "Flushing to file %s\n",
4523
os_file_flush(file);
4525
mutex_enter(&fil_system->mutex);
4527
node->n_pending_flushes--;
4529
if (node->flush_counter < old_mod_counter) {
4530
node->flush_counter = old_mod_counter;
4532
if (space->is_in_unflushed_spaces
4533
&& fil_space_is_flushed(space)) {
4535
space->is_in_unflushed_spaces = FALSE;
4539
fil_system->unflushed_spaces,
4544
if (space->purpose == FIL_TABLESPACE) {
4545
fil_n_pending_tablespace_flushes--;
4547
fil_n_pending_log_flushes--;
4551
node = UT_LIST_GET_NEXT(chain, node);
4554
space->n_pending_flushes--;
4556
mutex_exit(&fil_system->mutex);
4559
/**********************************************************************//**
4560
Flushes to disk the writes in file spaces of the given type possibly cached by
4564
fil_flush_file_spaces(
4565
/*==================*/
4566
ulint purpose) /*!< in: FIL_TABLESPACE, FIL_LOG */
4573
mutex_enter(&fil_system->mutex);
4575
n_space_ids = UT_LIST_GET_LEN(fil_system->unflushed_spaces);
4576
if (n_space_ids == 0) {
4578
mutex_exit(&fil_system->mutex);
4582
/* Assemble a list of space ids to flush. Previously, we
4583
traversed fil_system->unflushed_spaces and called UT_LIST_GET_NEXT()
4584
on a space that was just removed from the list by fil_flush().
4585
Thus, the space could be dropped and the memory overwritten. */
4586
space_ids = mem_alloc(n_space_ids * sizeof *space_ids);
4590
for (space = UT_LIST_GET_FIRST(fil_system->unflushed_spaces);
4592
space = UT_LIST_GET_NEXT(unflushed_spaces, space)) {
4594
if (space->purpose == purpose && !space->is_being_deleted) {
4596
space_ids[n_space_ids++] = space->id;
4600
mutex_exit(&fil_system->mutex);
4602
/* Flush the spaces. It will not hurt to call fil_flush() on
4603
a non-existing space id. */
4604
for (i = 0; i < n_space_ids; i++) {
4606
fil_flush(space_ids[i]);
4609
mem_free(space_ids);
4612
/******************************************************************//**
4613
Checks the consistency of the tablespace cache.
4614
@return TRUE if ok */
4621
fil_node_t* fil_node;
4625
mutex_enter(&fil_system->mutex);
4627
/* Look for spaces in the hash table */
4629
for (i = 0; i < hash_get_n_cells(fil_system->spaces); i++) {
4631
space = HASH_GET_FIRST(fil_system->spaces, i);
4633
while (space != NULL) {
4634
UT_LIST_VALIDATE(chain, fil_node_t, space->chain,
4635
ut_a(ut_list_node_313->open
4636
|| !ut_list_node_313->n_pending));
4638
fil_node = UT_LIST_GET_FIRST(space->chain);
4640
while (fil_node != NULL) {
4641
if (fil_node->n_pending > 0) {
4642
ut_a(fil_node->open);
4645
if (fil_node->open) {
4648
fil_node = UT_LIST_GET_NEXT(chain, fil_node);
4650
space = HASH_GET_NEXT(hash, space);
4654
ut_a(fil_system->n_open == n_open);
4656
UT_LIST_VALIDATE(LRU, fil_node_t, fil_system->LRU, (void) 0);
4658
fil_node = UT_LIST_GET_FIRST(fil_system->LRU);
4660
while (fil_node != NULL) {
4661
ut_a(fil_node->n_pending == 0);
4662
ut_a(fil_node->open);
4663
ut_a(fil_node->space->purpose == FIL_TABLESPACE);
4664
ut_a(fil_node->space->id != 0);
4666
fil_node = UT_LIST_GET_NEXT(LRU, fil_node);
4669
mutex_exit(&fil_system->mutex);
4674
/********************************************************************//**
4675
Returns TRUE if file address is undefined.
4676
@return TRUE if undefined */
4681
fil_addr_t addr) /*!< in: address */
4683
return(addr.page == FIL_NULL);
4686
/********************************************************************//**
4687
Get the predecessor of a file page.
4688
@return FIL_PAGE_PREV */
4693
const byte* page) /*!< in: file page */
4695
return(mach_read_from_4(page + FIL_PAGE_PREV));
4698
/********************************************************************//**
4699
Get the successor of a file page.
4700
@return FIL_PAGE_NEXT */
4705
const byte* page) /*!< in: file page */
4707
return(mach_read_from_4(page + FIL_PAGE_NEXT));
4710
/*********************************************************************//**
4711
Sets the file page type. */
4716
byte* page, /*!< in/out: file page */
4717
ulint type) /*!< in: type */
4721
mach_write_to_2(page + FIL_PAGE_TYPE, type);
4724
/*********************************************************************//**
4725
Gets the file page type.
4726
@return type; NOTE that if the type has not been written to page, the
4727
return value not defined */
4732
const byte* page) /*!< in: file page */
4736
return(mach_read_from_2(page + FIL_PAGE_TYPE));