~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/******************************************************
 
2
The tablespace memory cache
 
3
 
 
4
(c) 1995 Innobase Oy
 
5
 
 
6
Created 10/25/1995 Heikki Tuuri
 
7
*******************************************************/
 
8
 
 
9
#include "fil0fil.h"
 
10
 
 
11
#include "mem0mem.h"
 
12
#include "sync0sync.h"
 
13
#include "hash0hash.h"
 
14
#include "os0file.h"
 
15
#include "os0sync.h"
 
16
#include "mach0data.h"
 
17
#include "ibuf0ibuf.h"
 
18
#include "buf0buf.h"
 
19
#include "buf0flu.h"
 
20
#include "buf0lru.h"
 
21
#include "log0log.h"
 
22
#include "log0recv.h"
 
23
#include "fsp0fsp.h"
 
24
#include "srv0srv.h"
 
25
#include "srv0start.h"
 
26
#include "mtr0mtr.h"
 
27
#include "mtr0log.h"
 
28
#include "dict0dict.h"
 
29
 
 
30
 
 
31
/*
 
32
                IMPLEMENTATION OF THE TABLESPACE MEMORY CACHE
 
33
                =============================================
 
34
 
 
35
The tablespace cache is responsible for providing fast read/write access to
 
36
tablespaces and logs of the database. File creation and deletion is done
 
37
in other modules which know more of the logic of the operation, however.
 
38
 
 
39
A tablespace consists of a chain of files. The size of the files does not
 
40
have to be divisible by the database block size, because we may just leave
 
41
the last incomplete block unused. When a new file is appended to the
 
42
tablespace, the maximum size of the file is also specified. At the moment,
 
43
we think that it is best to extend the file to its maximum size already at
 
44
the creation of the file, because then we can avoid dynamically extending
 
45
the file when more space is needed for the tablespace.
 
46
 
 
47
A block's position in the tablespace is specified with a 32-bit unsigned
 
48
integer. The files in the chain are thought to be catenated, and the block
 
49
corresponding to an address n is the nth block in the catenated file (where
 
50
the first block is named the 0th block, and the incomplete block fragments
 
51
at the end of files are not taken into account). A tablespace can be extended
 
52
by appending a new file at the end of the chain.
 
53
 
 
54
Our tablespace concept is similar to the one of Oracle.
 
55
 
 
56
To acquire more speed in disk transfers, a technique called disk striping is
 
57
sometimes used. This means that logical block addresses are divided in a
 
58
round-robin fashion across several disks. Windows NT supports disk striping,
 
59
so there we do not need to support it in the database. Disk striping is
 
60
implemented in hardware in RAID disks. We conclude that it is not necessary
 
61
to implement it in the database. Oracle 7 does not support disk striping,
 
62
either.
 
63
 
 
64
Another trick used at some database sites is replacing tablespace files by
 
65
raw disks, that is, the whole physical disk drive, or a partition of it, is
 
66
opened as a single file, and it is accessed through byte offsets calculated
 
67
from the start of the disk or the partition. This is recommended in some
 
68
books on database tuning to achieve more speed in i/o. Using raw disk
 
69
certainly prevents the OS from fragmenting disk space, but it is not clear
 
70
if it really adds speed. We measured on the Pentium 100 MHz + NT + NTFS file
 
71
system + EIDE Conner disk only a negligible difference in speed when reading
 
72
from a file, versus reading from a raw disk.
 
73
 
 
74
To have fast access to a tablespace or a log file, we put the data structures
 
75
to a hash table. Each tablespace and log file is given an unique 32-bit
 
76
identifier.
 
77
 
 
78
Some operating systems do not support many open files at the same time,
 
79
though NT seems to tolerate at least 900 open files. Therefore, we put the
 
80
open files in an LRU-list. If we need to open another file, we may close the
 
81
file at the end of the LRU-list. When an i/o-operation is pending on a file,
 
82
the file cannot be closed. We take the file nodes with pending i/o-operations
 
83
out of the LRU-list and keep a count of pending operations. When an operation
 
84
completes, we decrement the count and return the file node to the LRU-list if
 
85
the count drops to zero. */
 
86
 
 
87
/* When mysqld is run, the default directory "." is the mysqld datadir,
 
88
but in the MySQL Embedded Server Library and ibbackup it is not the default
 
89
directory, and we must set the base file path explicitly */
 
90
const char*     fil_path_to_mysql_datadir       = ".";
 
91
 
 
92
/* The number of fsyncs done to the log */
 
93
ulint   fil_n_log_flushes                       = 0;
 
94
 
 
95
ulint   fil_n_pending_log_flushes               = 0;
 
96
ulint   fil_n_pending_tablespace_flushes        = 0;
 
97
 
 
98
/* Null file address */
 
99
fil_addr_t      fil_addr_null = {FIL_NULL, 0};
 
100
 
 
101
/* File node of a tablespace or the log data space */
 
102
struct fil_node_struct {
 
103
        fil_space_t*    space;  /* backpointer to the space where this node
 
104
                                belongs */
 
105
        char*           name;   /* path to the file */
 
106
        ibool           open;   /* TRUE if file open */
 
107
        os_file_t       handle; /* OS handle to the file, if file open */
 
108
        ibool           is_raw_disk;/* TRUE if the 'file' is actually a raw
 
109
                                device or a raw disk partition */
 
110
        ulint           size;   /* size of the file in database pages, 0 if
 
111
                                not known yet; the possible last incomplete
 
112
                                megabyte may be ignored if space == 0 */
 
113
        ulint           n_pending;
 
114
                                /* count of pending i/o's on this file;
 
115
                                closing of the file is not allowed if
 
116
                                this is > 0 */
 
117
        ulint           n_pending_flushes;
 
118
                                /* count of pending flushes on this file;
 
119
                                closing of the file is not allowed if
 
120
                                this is > 0 */
 
121
        ib_longlong     modification_counter;/* when we write to the file we
 
122
                                increment this by one */
 
123
        ib_longlong     flush_counter;/* up to what modification_counter value
 
124
                                we have flushed the modifications to disk */
 
125
        UT_LIST_NODE_T(fil_node_t) chain;
 
126
                                /* link field for the file chain */
 
127
        UT_LIST_NODE_T(fil_node_t) LRU;
 
128
                                /* link field for the LRU list */
 
129
        ulint           magic_n;
 
130
};
 
131
 
 
132
#define FIL_NODE_MAGIC_N        89389
 
133
 
 
134
/* Tablespace or log data space: let us call them by a common name space */
 
135
struct fil_space_struct {
 
136
        char*           name;   /* space name = the path to the first file in
 
137
                                it */
 
138
        ulint           id;     /* space id */
 
139
        ib_longlong     tablespace_version;
 
140
                                /* in DISCARD/IMPORT this timestamp is used to
 
141
                                check if we should ignore an insert buffer
 
142
                                merge request for a page because it actually
 
143
                                was for the previous incarnation of the
 
144
                                space */
 
145
        ibool           mark;   /* this is set to TRUE at database startup if
 
146
                                the space corresponds to a table in the InnoDB
 
147
                                data dictionary; so we can print a warning of
 
148
                                orphaned tablespaces */
 
149
        ibool           stop_ios;/* TRUE if we want to rename the .ibd file of
 
150
                                tablespace and want to stop temporarily
 
151
                                posting of new i/o requests on the file */
 
152
        ibool           stop_ibuf_merges;
 
153
                                /* we set this TRUE when we start deleting a
 
154
                                single-table tablespace */
 
155
        ibool           is_being_deleted;
 
156
                                /* this is set to TRUE when we start
 
157
                                deleting a single-table tablespace and its
 
158
                                file; when this flag is set no further i/o
 
159
                                or flush requests can be placed on this space,
 
160
                                though there may be such requests still being
 
161
                                processed on this space */
 
162
        ulint           purpose;/* FIL_TABLESPACE, FIL_LOG, or FIL_ARCH_LOG */
 
163
        UT_LIST_BASE_NODE_T(fil_node_t) chain;
 
164
                                /* base node for the file chain */
 
165
        ulint           size;   /* space size in pages; 0 if a single-table
 
166
                                tablespace whose size we do not know yet;
 
167
                                last incomplete megabytes in data files may be
 
168
                                ignored if space == 0 */
 
169
        ulint           n_reserved_extents;
 
170
                                /* number of reserved free extents for
 
171
                                ongoing operations like B-tree page split */
 
172
        ulint           n_pending_flushes; /* this is > 0 when flushing
 
173
                                the tablespace to disk; dropping of the
 
174
                                tablespace is forbidden if this is > 0 */
 
175
        ulint           n_pending_ibuf_merges;/* this is > 0 when merging
 
176
                                insert buffer entries to a page so that we
 
177
                                may need to access the ibuf bitmap page in the
 
178
                                tablespade: dropping of the tablespace is
 
179
                                forbidden if this is > 0 */
 
180
        hash_node_t     hash;   /* hash chain node */
 
181
        hash_node_t     name_hash;/* hash chain the name_hash table */
 
182
        rw_lock_t       latch;  /* latch protecting the file space storage
 
183
                                allocation */
 
184
        UT_LIST_NODE_T(fil_space_t) unflushed_spaces;
 
185
                                /* list of spaces with at least one unflushed
 
186
                                file we have written to */
 
187
        ibool           is_in_unflushed_spaces; /* TRUE if this space is
 
188
                                currently in the list above */
 
189
        UT_LIST_NODE_T(fil_space_t) space_list;
 
190
                                /* list of all spaces */
 
191
        ibuf_data_t*    ibuf_data;
 
192
                                /* insert buffer data */
 
193
        ulint           magic_n;
 
194
};
 
195
 
 
196
#define FIL_SPACE_MAGIC_N       89472
 
197
 
 
198
/* The tablespace memory cache; also the totality of logs = the log data space,
 
199
is stored here; below we talk about tablespaces, but also the ib_logfiles
 
200
form a 'space' and it is handled here */
 
201
 
 
202
typedef struct fil_system_struct        fil_system_t;
 
203
struct fil_system_struct {
 
204
        mutex_t         mutex;          /* The mutex protecting the cache */
 
205
        hash_table_t*   spaces;         /* The hash table of spaces in the
 
206
                                        system; they are hashed on the space
 
207
                                        id */
 
208
        hash_table_t*   name_hash;      /* hash table based on the space
 
209
                                        name */
 
210
        UT_LIST_BASE_NODE_T(fil_node_t) LRU;
 
211
                                        /* base node for the LRU list of the
 
212
                                        most recently used open files with no
 
213
                                        pending i/o's; if we start an i/o on
 
214
                                        the file, we first remove it from this
 
215
                                        list, and return it to the start of
 
216
                                        the list when the i/o ends;
 
217
                                        log files and the system tablespace are
 
218
                                        not put to this list: they are opened
 
219
                                        after the startup, and kept open until
 
220
                                        shutdown */
 
221
        UT_LIST_BASE_NODE_T(fil_space_t) unflushed_spaces;
 
222
                                        /* base node for the list of those
 
223
                                        tablespaces whose files contain
 
224
                                        unflushed writes; those spaces have
 
225
                                        at least one file node where
 
226
                                        modification_counter > flush_counter */
 
227
        ulint           n_open;         /* number of files currently open */
 
228
        ulint           max_n_open;     /* n_open is not allowed to exceed
 
229
                                        this */
 
230
        ib_longlong     modification_counter;/* when we write to a file we
 
231
                                        increment this by one */
 
232
        ulint           max_assigned_id;/* maximum space id in the existing
 
233
                                        tables, or assigned during the time
 
234
                                        mysqld has been up; at an InnoDB
 
235
                                        startup we scan the data dictionary
 
236
                                        and set here the maximum of the
 
237
                                        space id's of the tables there */
 
238
        ib_longlong     tablespace_version;
 
239
                                        /* a counter which is incremented for
 
240
                                        every space object memory creation;
 
241
                                        every space mem object gets a
 
242
                                        'timestamp' from this; in DISCARD/
 
243
                                        IMPORT this is used to check if we
 
244
                                        should ignore an insert buffer merge
 
245
                                        request */
 
246
        UT_LIST_BASE_NODE_T(fil_space_t) space_list;
 
247
                                        /* list of all file spaces */
 
248
};
 
249
 
 
250
/* The tablespace memory cache. This variable is NULL before the module is
 
251
initialized. */
 
252
fil_system_t*   fil_system      = NULL;
 
253
 
 
254
 
 
255
/************************************************************************
 
256
NOTE: you must call fil_mutex_enter_and_prepare_for_io() first!
 
257
 
 
258
Prepares a file node for i/o. Opens the file if it is closed. Updates the
 
259
pending i/o's field in the node and the system appropriately. Takes the node
 
260
off the LRU list if it is in the LRU list. The caller must hold the fil_sys
 
261
mutex. */
 
262
static
 
263
void
 
264
fil_node_prepare_for_io(
 
265
/*====================*/
 
266
        fil_node_t*     node,   /* in: file node */
 
267
        fil_system_t*   system, /* in: tablespace memory cache */
 
268
        fil_space_t*    space); /* in: space */
 
269
/************************************************************************
 
270
Updates the data structures when an i/o operation finishes. Updates the
 
271
pending i/o's field in the node appropriately. */
 
272
static
 
273
void
 
274
fil_node_complete_io(
 
275
/*=================*/
 
276
        fil_node_t*     node,   /* in: file node */
 
277
        fil_system_t*   system, /* in: tablespace memory cache */
 
278
        ulint           type);  /* in: OS_FILE_WRITE or OS_FILE_READ; marks
 
279
                                the node as modified if
 
280
                                type == OS_FILE_WRITE */
 
281
/***********************************************************************
 
282
Checks if a single-table tablespace for a given table name exists in the
 
283
tablespace memory cache. */
 
284
static
 
285
ulint
 
286
fil_get_space_id_for_table(
 
287
/*=======================*/
 
288
                                /* out: space id, ULINT_UNDEFINED if not
 
289
                                found */
 
290
        const char*     name);  /* in: table name in the standard
 
291
                                'databasename/tablename' format */
 
292
 
 
293
 
 
294
/***********************************************************************
 
295
Returns the version number of a tablespace, -1 if not found. */
 
296
 
 
297
ib_longlong
 
298
fil_space_get_version(
 
299
/*==================*/
 
300
                        /* out: version number, -1 if the tablespace does not
 
301
                        exist in the memory cache */
 
302
        ulint   id)     /* in: space id */
 
303
{
 
304
        fil_system_t*   system          = fil_system;
 
305
        fil_space_t*    space;
 
306
        ib_longlong     version         = -1;
 
307
 
 
308
        ut_ad(system);
 
309
 
 
310
        mutex_enter(&(system->mutex));
 
311
 
 
312
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
 
313
 
 
314
        if (space) {
 
315
                version = space->tablespace_version;
 
316
        }
 
317
 
 
318
        mutex_exit(&(system->mutex));
 
319
 
 
320
        return(version);
 
321
}
 
322
 
 
323
/***********************************************************************
 
324
Returns the latch of a file space. */
 
325
 
 
326
rw_lock_t*
 
327
fil_space_get_latch(
 
328
/*================*/
 
329
                        /* out: latch protecting storage allocation */
 
330
        ulint   id)     /* in: space id */
 
331
{
 
332
        fil_system_t*   system          = fil_system;
 
333
        fil_space_t*    space;
 
334
 
 
335
        ut_ad(system);
 
336
 
 
337
        mutex_enter(&(system->mutex));
 
338
 
 
339
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
 
340
 
 
341
        ut_a(space);
 
342
 
 
343
        mutex_exit(&(system->mutex));
 
344
 
 
345
        return(&(space->latch));
 
346
}
 
347
 
 
348
/***********************************************************************
 
349
Returns the type of a file space. */
 
350
 
 
351
ulint
 
352
fil_space_get_type(
 
353
/*===============*/
 
354
                        /* out: FIL_TABLESPACE or FIL_LOG */
 
355
        ulint   id)     /* in: space id */
 
356
{
 
357
        fil_system_t*   system          = fil_system;
 
358
        fil_space_t*    space;
 
359
 
 
360
        ut_ad(system);
 
361
 
 
362
        mutex_enter(&(system->mutex));
 
363
 
 
364
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
 
365
 
 
366
        ut_a(space);
 
367
 
 
368
        mutex_exit(&(system->mutex));
 
369
 
 
370
        return(space->purpose);
 
371
}
 
372
 
 
373
/***********************************************************************
 
374
Returns the ibuf data of a file space. */
 
375
 
 
376
ibuf_data_t*
 
377
fil_space_get_ibuf_data(
 
378
/*====================*/
 
379
                        /* out: ibuf data for this space */
 
380
        ulint   id)     /* in: space id */
 
381
{
 
382
        fil_system_t*   system          = fil_system;
 
383
        fil_space_t*    space;
 
384
 
 
385
        ut_ad(system);
 
386
 
 
387
        ut_a(id == 0);
 
388
 
 
389
        mutex_enter(&(system->mutex));
 
390
 
 
391
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
 
392
 
 
393
        mutex_exit(&(system->mutex));
 
394
 
 
395
        ut_a(space);
 
396
 
 
397
        return(space->ibuf_data);
 
398
}
 
399
 
 
400
/**************************************************************************
 
401
Checks if all the file nodes in a space are flushed. The caller must hold
 
402
the fil_system mutex. */
 
403
static
 
404
ibool
 
405
fil_space_is_flushed(
 
406
/*=================*/
 
407
                                /* out: TRUE if all are flushed */
 
408
        fil_space_t*    space)  /* in: space */
 
409
{
 
410
        fil_node_t*     node;
 
411
 
 
412
        ut_ad(mutex_own(&(fil_system->mutex)));
 
413
 
 
414
        node = UT_LIST_GET_FIRST(space->chain);
 
415
 
 
416
        while (node) {
 
417
                if (node->modification_counter > node->flush_counter) {
 
418
 
 
419
                        return(FALSE);
 
420
                }
 
421
 
 
422
                node = UT_LIST_GET_NEXT(chain, node);
 
423
        }
 
424
 
 
425
        return(TRUE);
 
426
}
 
427
 
 
428
/***********************************************************************
 
429
Appends a new file to the chain of files of a space. File must be closed. */
 
430
 
 
431
void
 
432
fil_node_create(
 
433
/*============*/
 
434
        const char*     name,   /* in: file name (file must be closed) */
 
435
        ulint           size,   /* in: file size in database blocks, rounded
 
436
                                downwards to an integer */
 
437
        ulint           id,     /* in: space id where to append */
 
438
        ibool           is_raw) /* in: TRUE if a raw device or
 
439
                                a raw disk partition */
 
440
{
 
441
        fil_system_t*   system  = fil_system;
 
442
        fil_node_t*     node;
 
443
        fil_space_t*    space;
 
444
 
 
445
        ut_a(system);
 
446
        ut_a(name);
 
447
 
 
448
        mutex_enter(&(system->mutex));
 
449
 
 
450
        node = mem_alloc(sizeof(fil_node_t));
 
451
 
 
452
        node->name = mem_strdup(name);
 
453
        node->open = FALSE;
 
454
 
 
455
        ut_a(!is_raw || srv_start_raw_disk_in_use);
 
456
 
 
457
        node->is_raw_disk = is_raw;
 
458
        node->size = size;
 
459
        node->magic_n = FIL_NODE_MAGIC_N;
 
460
        node->n_pending = 0;
 
461
        node->n_pending_flushes = 0;
 
462
 
 
463
        node->modification_counter = 0;
 
464
        node->flush_counter = 0;
 
465
 
 
466
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
 
467
 
 
468
        if (!space) {
 
469
                ut_print_timestamp(stderr);
 
470
                fprintf(stderr,
 
471
                        "  InnoDB: Error: Could not find tablespace %lu for\n"
 
472
                        "InnoDB: file ", (ulong) id);
 
473
                ut_print_filename(stderr, name);
 
474
                fputs(" in the tablespace memory cache.\n", stderr);
 
475
                mem_free(node->name);
 
476
 
 
477
                mem_free(node);
 
478
 
 
479
                mutex_exit(&(system->mutex));
 
480
 
 
481
                return;
 
482
        }
 
483
 
 
484
        space->size += size;
 
485
 
 
486
        node->space = space;
 
487
 
 
488
        UT_LIST_ADD_LAST(chain, space->chain, node);
 
489
 
 
490
        mutex_exit(&(system->mutex));
 
491
}
 
492
 
 
493
/************************************************************************
 
494
Opens a the file of a node of a tablespace. The caller must own the fil_system
 
495
mutex. */
 
496
static
 
497
void
 
498
fil_node_open_file(
 
499
/*===============*/
 
500
        fil_node_t*     node,   /* in: file node */
 
501
        fil_system_t*   system, /* in: tablespace memory cache */
 
502
        fil_space_t*    space)  /* in: space */
 
503
{
 
504
        ib_longlong     size_bytes;
 
505
        ulint           size_low;
 
506
        ulint           size_high;
 
507
        ibool           ret;
 
508
        ibool           success;
 
509
#ifndef UNIV_HOTBACKUP
 
510
        byte*           buf2;
 
511
        byte*           page;
 
512
        ulint           space_id;
 
513
#endif /* !UNIV_HOTBACKUP */
 
514
 
 
515
        ut_ad(mutex_own(&(system->mutex)));
 
516
        ut_a(node->n_pending == 0);
 
517
        ut_a(node->open == FALSE);
 
518
 
 
519
        if (node->size == 0) {
 
520
                /* It must be a single-table tablespace and we do not know the
 
521
                size of the file yet. First we open the file in the normal
 
522
                mode, no async I/O here, for simplicity. Then do some checks,
 
523
                and close the file again.
 
524
                NOTE that we could not use the simple file read function
 
525
                os_file_read() in Windows to read from a file opened for
 
526
                async I/O! */
 
527
 
 
528
                node->handle = os_file_create_simple_no_error_handling(
 
529
                        node->name, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success);
 
530
                if (!success) {
 
531
                        /* The following call prints an error message */
 
532
                        os_file_get_last_error(TRUE);
 
533
 
 
534
                        ut_print_timestamp(stderr);
 
535
 
 
536
                        fprintf(stderr,
 
537
                                "  InnoDB: Fatal error: cannot open %s\n."
 
538
                                "InnoDB: Have you deleted .ibd files"
 
539
                                " under a running mysqld server?\n",
 
540
                                node->name);
 
541
                        ut_a(0);
 
542
                }
 
543
 
 
544
                os_file_get_size(node->handle, &size_low, &size_high);
 
545
 
 
546
                size_bytes = (((ib_longlong)size_high) << 32)
 
547
                        + (ib_longlong)size_low;
 
548
#ifdef UNIV_HOTBACKUP
 
549
                node->size = (ulint) (size_bytes / UNIV_PAGE_SIZE);
 
550
 
 
551
#else
 
552
                ut_a(space->purpose != FIL_LOG);
 
553
                ut_a(space->id != 0);
 
554
 
 
555
                if (size_bytes < FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE) {
 
556
                        fprintf(stderr,
 
557
                                "InnoDB: Error: the size of single-table"
 
558
                                " tablespace file %s\n"
 
559
                                "InnoDB: is only %lu %lu,"
 
560
                                " should be at least %lu!\n",
 
561
                                node->name,
 
562
                                (ulong) size_high,
 
563
                                (ulong) size_low,
 
564
                                (ulong) (FIL_IBD_FILE_INITIAL_SIZE
 
565
                                         * UNIV_PAGE_SIZE));
 
566
 
 
567
                        ut_a(0);
 
568
                }
 
569
 
 
570
                /* Read the first page of the tablespace */
 
571
 
 
572
                buf2 = ut_malloc(2 * UNIV_PAGE_SIZE);
 
573
                /* Align the memory for file i/o if we might have O_DIRECT
 
574
                set */
 
575
                page = ut_align(buf2, UNIV_PAGE_SIZE);
 
576
 
 
577
                success = os_file_read(node->handle, page, 0, 0,
 
578
                                       UNIV_PAGE_SIZE);
 
579
                space_id = fsp_header_get_space_id(page);
 
580
 
 
581
                ut_free(buf2);
 
582
 
 
583
                /* Close the file now that we have read the space id from it */
 
584
 
 
585
                os_file_close(node->handle);
 
586
 
 
587
                if (space_id == ULINT_UNDEFINED || space_id == 0) {
 
588
                        fprintf(stderr,
 
589
                                "InnoDB: Error: tablespace id %lu"
 
590
                                " in file %s is not sensible\n",
 
591
                                (ulong) space_id, node->name);
 
592
 
 
593
                        ut_a(0);
 
594
                }
 
595
 
 
596
                if (space_id != space->id) {
 
597
                        fprintf(stderr,
 
598
                                "InnoDB: Error: tablespace id is %lu"
 
599
                                " in the data dictionary\n"
 
600
                                "InnoDB: but in file %s it is %lu!\n",
 
601
                                space->id, node->name, space_id);
 
602
 
 
603
                        ut_a(0);
 
604
                }
 
605
 
 
606
                if (size_bytes >= FSP_EXTENT_SIZE * UNIV_PAGE_SIZE) {
 
607
                        node->size = (ulint)
 
608
                                ((size_bytes / (1024 * 1024))
 
609
                                 * ((1024 * 1024) / UNIV_PAGE_SIZE));
 
610
                } else {
 
611
                        node->size = (ulint) (size_bytes / UNIV_PAGE_SIZE);
 
612
                }
 
613
#endif
 
614
                space->size += node->size;
 
615
        }
 
616
 
 
617
        /* printf("Opening file %s\n", node->name); */
 
618
 
 
619
        /* Open the file for reading and writing, in Windows normally in the
 
620
        unbuffered async I/O mode, though global variables may make
 
621
        os_file_create() to fall back to the normal file I/O mode. */
 
622
 
 
623
        if (space->purpose == FIL_LOG) {
 
624
                node->handle = os_file_create(node->name, OS_FILE_OPEN,
 
625
                                              OS_FILE_AIO, OS_LOG_FILE, &ret);
 
626
        } else if (node->is_raw_disk) {
 
627
                node->handle = os_file_create(node->name,
 
628
                                              OS_FILE_OPEN_RAW,
 
629
                                              OS_FILE_AIO, OS_DATA_FILE, &ret);
 
630
        } else {
 
631
                node->handle = os_file_create(node->name, OS_FILE_OPEN,
 
632
                                              OS_FILE_AIO, OS_DATA_FILE, &ret);
 
633
        }
 
634
 
 
635
        ut_a(ret);
 
636
 
 
637
        node->open = TRUE;
 
638
 
 
639
        system->n_open++;
 
640
 
 
641
        if (space->purpose == FIL_TABLESPACE && space->id != 0) {
 
642
                /* Put the node to the LRU list */
 
643
                UT_LIST_ADD_FIRST(LRU, system->LRU, node);
 
644
        }
 
645
}
 
646
 
 
647
/**************************************************************************
 
648
Closes a file. */
 
649
static
 
650
void
 
651
fil_node_close_file(
 
652
/*================*/
 
653
        fil_node_t*     node,   /* in: file node */
 
654
        fil_system_t*   system) /* in: tablespace memory cache */
 
655
{
 
656
        ibool   ret;
 
657
 
 
658
        ut_ad(node && system);
 
659
        ut_ad(mutex_own(&(system->mutex)));
 
660
        ut_a(node->open);
 
661
        ut_a(node->n_pending == 0);
 
662
        ut_a(node->n_pending_flushes == 0);
 
663
        ut_a(node->modification_counter == node->flush_counter);
 
664
 
 
665
        ret = os_file_close(node->handle);
 
666
        ut_a(ret);
 
667
 
 
668
        /* printf("Closing file %s\n", node->name); */
 
669
 
 
670
        node->open = FALSE;
 
671
        ut_a(system->n_open > 0);
 
672
        system->n_open--;
 
673
 
 
674
        if (node->space->purpose == FIL_TABLESPACE && node->space->id != 0) {
 
675
                ut_a(UT_LIST_GET_LEN(system->LRU) > 0);
 
676
 
 
677
                /* The node is in the LRU list, remove it */
 
678
                UT_LIST_REMOVE(LRU, system->LRU, node);
 
679
        }
 
680
}
 
681
 
 
682
/************************************************************************
 
683
Tries to close a file in the LRU list. The caller must hold the fil_sys
 
684
mutex. */
 
685
static
 
686
ibool
 
687
fil_try_to_close_file_in_LRU(
 
688
/*=========================*/
 
689
                                /* out: TRUE if success, FALSE if should retry
 
690
                                later; since i/o's generally complete in <
 
691
                                100 ms, and as InnoDB writes at most 128 pages
 
692
                                from the buffer pool in a batch, and then
 
693
                                immediately flushes the files, there is a good
 
694
                                chance that the next time we find a suitable
 
695
                                node from the LRU list */
 
696
        ibool   print_info)     /* in: if TRUE, prints information why it
 
697
                                cannot close a file */
 
698
{
 
699
        fil_system_t*   system          = fil_system;
 
700
        fil_node_t*     node;
 
701
 
 
702
        ut_ad(mutex_own(&(system->mutex)));
 
703
 
 
704
        node = UT_LIST_GET_LAST(system->LRU);
 
705
 
 
706
        if (print_info) {
 
707
                fprintf(stderr,
 
708
                        "InnoDB: fil_sys open file LRU len %lu\n",
 
709
                        (ulong) UT_LIST_GET_LEN(system->LRU));
 
710
        }
 
711
 
 
712
        while (node != NULL) {
 
713
                if (node->modification_counter == node->flush_counter
 
714
                    && node->n_pending_flushes == 0) {
 
715
 
 
716
                        fil_node_close_file(node, system);
 
717
 
 
718
                        return(TRUE);
 
719
                }
 
720
 
 
721
                if (print_info && node->n_pending_flushes > 0) {
 
722
                        fputs("InnoDB: cannot close file ", stderr);
 
723
                        ut_print_filename(stderr, node->name);
 
724
                        fprintf(stderr, ", because n_pending_flushes %lu\n",
 
725
                                (ulong) node->n_pending_flushes);
 
726
                }
 
727
 
 
728
                if (print_info
 
729
                    && node->modification_counter != node->flush_counter) {
 
730
                        fputs("InnoDB: cannot close file ", stderr);
 
731
                        ut_print_filename(stderr, node->name);
 
732
                        fprintf(stderr,
 
733
                                ", because mod_count %ld != fl_count %ld\n",
 
734
                                (long) node->modification_counter,
 
735
                                (long) node->flush_counter);
 
736
                }
 
737
 
 
738
                node = UT_LIST_GET_PREV(LRU, node);
 
739
        }
 
740
 
 
741
        return(FALSE);
 
742
}
 
743
 
 
744
/***********************************************************************
 
745
Reserves the fil_system mutex and tries to make sure we can open at least one
 
746
file while holding it. This should be called before calling
 
747
fil_node_prepare_for_io(), because that function may need to open a file. */
 
748
static
 
749
void
 
750
fil_mutex_enter_and_prepare_for_io(
 
751
/*===============================*/
 
752
        ulint   space_id)       /* in: space id */
 
753
{
 
754
        fil_system_t*   system          = fil_system;
 
755
        fil_space_t*    space;
 
756
        ibool           success;
 
757
        ibool           print_info      = FALSE;
 
758
        ulint           count           = 0;
 
759
        ulint           count2          = 0;
 
760
 
 
761
        ut_ad(!mutex_own(&(system->mutex)));
 
762
retry:
 
763
        mutex_enter(&(system->mutex));
 
764
 
 
765
        if (space_id == 0 || space_id >= SRV_LOG_SPACE_FIRST_ID) {
 
766
                /* We keep log files and system tablespace files always open;
 
767
                this is important in preventing deadlocks in this module, as
 
768
                a page read completion often performs another read from the
 
769
                insert buffer. The insert buffer is in tablespace 0, and we
 
770
                cannot end up waiting in this function. */
 
771
 
 
772
                return;
 
773
        }
 
774
 
 
775
        if (system->n_open < system->max_n_open) {
 
776
 
 
777
                return;
 
778
        }
 
779
 
 
780
        HASH_SEARCH(hash, system->spaces, space_id, space,
 
781
                    space->id == space_id);
 
782
        if (space != NULL && space->stop_ios) {
 
783
                /* We are going to do a rename file and want to stop new i/o's
 
784
                for a while */
 
785
 
 
786
                if (count2 > 20000) {
 
787
                        fputs("InnoDB: Warning: tablespace ", stderr);
 
788
                        ut_print_filename(stderr, space->name);
 
789
                        fprintf(stderr,
 
790
                                " has i/o ops stopped for a long time %lu\n",
 
791
                                (ulong) count2);
 
792
                }
 
793
 
 
794
                mutex_exit(&(system->mutex));
 
795
 
 
796
                os_thread_sleep(20000);
 
797
 
 
798
                count2++;
 
799
 
 
800
                goto retry;
 
801
        }
 
802
 
 
803
        /* If the file is already open, no need to do anything; if the space
 
804
        does not exist, we handle the situation in the function which called
 
805
        this function */
 
806
 
 
807
        if (!space || UT_LIST_GET_FIRST(space->chain)->open) {
 
808
 
 
809
                return;
 
810
        }
 
811
 
 
812
        if (count > 1) {
 
813
                print_info = TRUE;
 
814
        }
 
815
 
 
816
        /* Too many files are open, try to close some */
 
817
close_more:
 
818
        success = fil_try_to_close_file_in_LRU(print_info);
 
819
 
 
820
        if (success && system->n_open >= system->max_n_open) {
 
821
 
 
822
                goto close_more;
 
823
        }
 
824
 
 
825
        if (system->n_open < system->max_n_open) {
 
826
                /* Ok */
 
827
 
 
828
                return;
 
829
        }
 
830
 
 
831
        if (count >= 2) {
 
832
                ut_print_timestamp(stderr);
 
833
                fprintf(stderr,
 
834
                        "  InnoDB: Warning: too many (%lu) files stay open"
 
835
                        " while the maximum\n"
 
836
                        "InnoDB: allowed value would be %lu.\n"
 
837
                        "InnoDB: You may need to raise the value of"
 
838
                        " innodb_max_files_open in\n"
 
839
                        "InnoDB: my.cnf.\n",
 
840
                        (ulong) system->n_open, (ulong) system->max_n_open);
 
841
 
 
842
                return;
 
843
        }
 
844
 
 
845
        mutex_exit(&(system->mutex));
 
846
 
 
847
#ifndef UNIV_HOTBACKUP
 
848
        /* Wake the i/o-handler threads to make sure pending i/o's are
 
849
        performed */
 
850
        os_aio_simulated_wake_handler_threads();
 
851
 
 
852
        os_thread_sleep(20000);
 
853
#endif
 
854
        /* Flush tablespaces so that we can close modified files in the LRU
 
855
        list */
 
856
 
 
857
        fil_flush_file_spaces(FIL_TABLESPACE);
 
858
 
 
859
        count++;
 
860
 
 
861
        goto retry;
 
862
}
 
863
 
 
864
/***********************************************************************
 
865
Frees a file node object from a tablespace memory cache. */
 
866
static
 
867
void
 
868
fil_node_free(
 
869
/*==========*/
 
870
        fil_node_t*     node,   /* in, own: file node */
 
871
        fil_system_t*   system, /* in: tablespace memory cache */
 
872
        fil_space_t*    space)  /* in: space where the file node is chained */
 
873
{
 
874
        ut_ad(node && system && space);
 
875
        ut_ad(mutex_own(&(system->mutex)));
 
876
        ut_a(node->magic_n == FIL_NODE_MAGIC_N);
 
877
        ut_a(node->n_pending == 0);
 
878
 
 
879
        if (node->open) {
 
880
                /* We fool the assertion in fil_node_close_file() to think
 
881
                there are no unflushed modifications in the file */
 
882
 
 
883
                node->modification_counter = node->flush_counter;
 
884
 
 
885
                if (space->is_in_unflushed_spaces
 
886
                    && fil_space_is_flushed(space)) {
 
887
 
 
888
                        space->is_in_unflushed_spaces = FALSE;
 
889
 
 
890
                        UT_LIST_REMOVE(unflushed_spaces,
 
891
                                       system->unflushed_spaces,
 
892
                                       space);
 
893
                }
 
894
 
 
895
                fil_node_close_file(node, system);
 
896
        }
 
897
 
 
898
        space->size -= node->size;
 
899
 
 
900
        UT_LIST_REMOVE(chain, space->chain, node);
 
901
 
 
902
        mem_free(node->name);
 
903
        mem_free(node);
 
904
}
 
905
 
 
906
/********************************************************************
 
907
Drops files from the start of a file space, so that its size is cut by
 
908
the amount given. */
 
909
 
 
910
void
 
911
fil_space_truncate_start(
 
912
/*=====================*/
 
913
        ulint   id,             /* in: space id */
 
914
        ulint   trunc_len)      /* in: truncate by this much; it is an error
 
915
                                if this does not equal to the combined size of
 
916
                                some initial files in the space */
 
917
{
 
918
        fil_system_t*   system          = fil_system;
 
919
        fil_node_t*     node;
 
920
        fil_space_t*    space;
 
921
 
 
922
        mutex_enter(&(system->mutex));
 
923
 
 
924
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
 
925
 
 
926
        ut_a(space);
 
927
 
 
928
        while (trunc_len > 0) {
 
929
                node = UT_LIST_GET_FIRST(space->chain);
 
930
 
 
931
                ut_a(node->size * UNIV_PAGE_SIZE >= trunc_len);
 
932
 
 
933
                trunc_len -= node->size * UNIV_PAGE_SIZE;
 
934
 
 
935
                fil_node_free(node, system, space);
 
936
        }
 
937
 
 
938
        mutex_exit(&(system->mutex));
 
939
}
 
940
 
 
941
/***********************************************************************
 
942
Creates a space memory object and puts it to the tablespace memory cache. If
 
943
there is an error, prints an error message to the .err log. */
 
944
 
 
945
ibool
 
946
fil_space_create(
 
947
/*=============*/
 
948
                                /* out: TRUE if success */
 
949
        const char*     name,   /* in: space name */
 
950
        ulint           id,     /* in: space id */
 
951
        ulint           purpose)/* in: FIL_TABLESPACE, or FIL_LOG if log */
 
952
{
 
953
        fil_system_t*   system          = fil_system;
 
954
        fil_space_t*    space;
 
955
        ulint           namesake_id;
 
956
try_again:
 
957
        /*printf(
 
958
        "InnoDB: Adding tablespace %lu of name %s, purpose %lu\n", id, name,
 
959
        purpose);*/
 
960
 
 
961
        ut_a(system);
 
962
        ut_a(name);
 
963
 
 
964
        mutex_enter(&(system->mutex));
 
965
 
 
966
        HASH_SEARCH(name_hash, system->name_hash, ut_fold_string(name), space,
 
967
                    0 == strcmp(name, space->name));
 
968
        if (space != NULL) {
 
969
                ut_print_timestamp(stderr);
 
970
                fprintf(stderr,
 
971
                        "  InnoDB: Warning: trying to init to the"
 
972
                        " tablespace memory cache\n"
 
973
                        "InnoDB: a tablespace %lu of name ", (ulong) id);
 
974
                ut_print_filename(stderr, name);
 
975
                fprintf(stderr, ",\n"
 
976
                        "InnoDB: but a tablespace %lu of the same name\n"
 
977
                        "InnoDB: already exists in the"
 
978
                        " tablespace memory cache!\n",
 
979
                        (ulong) space->id);
 
980
 
 
981
                if (id == 0 || purpose != FIL_TABLESPACE) {
 
982
 
 
983
                        mutex_exit(&(system->mutex));
 
984
 
 
985
                        return(FALSE);
 
986
                }
 
987
 
 
988
                fprintf(stderr,
 
989
                        "InnoDB: We assume that InnoDB did a crash recovery,"
 
990
                        " and you had\n"
 
991
                        "InnoDB: an .ibd file for which the table"
 
992
                        " did not exist in the\n"
 
993
                        "InnoDB: InnoDB internal data dictionary in the"
 
994
                        " ibdata files.\n"
 
995
                        "InnoDB: We assume that you later removed the"
 
996
                        " .ibd and .frm files,\n"
 
997
                        "InnoDB: and are now trying to recreate the table."
 
998
                        " We now remove the\n"
 
999
                        "InnoDB: conflicting tablespace object"
 
1000
                        " from the memory cache and try\n"
 
1001
                        "InnoDB: the init again.\n");
 
1002
 
 
1003
                namesake_id = space->id;
 
1004
 
 
1005
                mutex_exit(&(system->mutex));
 
1006
 
 
1007
                fil_space_free(namesake_id);
 
1008
 
 
1009
                goto try_again;
 
1010
        }
 
1011
 
 
1012
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
 
1013
 
 
1014
        if (space != NULL) {
 
1015
                fprintf(stderr,
 
1016
                        "InnoDB: Error: trying to add tablespace %lu"
 
1017
                        " of name ", (ulong) id);
 
1018
                ut_print_filename(stderr, name);
 
1019
                fprintf(stderr, "\n"
 
1020
                        "InnoDB: to the tablespace memory cache,"
 
1021
                        " but tablespace\n"
 
1022
                        "InnoDB: %lu of name ", (ulong) space->id);
 
1023
                ut_print_filename(stderr, space->name);
 
1024
                fputs(" already exists in the tablespace\n"
 
1025
                      "InnoDB: memory cache!\n", stderr);
 
1026
 
 
1027
                mutex_exit(&(system->mutex));
 
1028
 
 
1029
                return(FALSE);
 
1030
        }
 
1031
 
 
1032
        space = mem_alloc(sizeof(fil_space_t));
 
1033
 
 
1034
        space->name = mem_strdup(name);
 
1035
        space->id = id;
 
1036
 
 
1037
        system->tablespace_version++;
 
1038
        space->tablespace_version = system->tablespace_version;
 
1039
        space->mark = FALSE;
 
1040
 
 
1041
        if (purpose == FIL_TABLESPACE && id > system->max_assigned_id) {
 
1042
                system->max_assigned_id = id;
 
1043
        }
 
1044
 
 
1045
        space->stop_ios = FALSE;
 
1046
        space->stop_ibuf_merges = FALSE;
 
1047
        space->is_being_deleted = FALSE;
 
1048
        space->purpose = purpose;
 
1049
        space->size = 0;
 
1050
 
 
1051
        space->n_reserved_extents = 0;
 
1052
 
 
1053
        space->n_pending_flushes = 0;
 
1054
        space->n_pending_ibuf_merges = 0;
 
1055
 
 
1056
        UT_LIST_INIT(space->chain);
 
1057
        space->magic_n = FIL_SPACE_MAGIC_N;
 
1058
 
 
1059
        space->ibuf_data = NULL;
 
1060
 
 
1061
        rw_lock_create(&space->latch, SYNC_FSP);
 
1062
 
 
1063
        HASH_INSERT(fil_space_t, hash, system->spaces, id, space);
 
1064
 
 
1065
        HASH_INSERT(fil_space_t, name_hash, system->name_hash,
 
1066
                    ut_fold_string(name), space);
 
1067
        space->is_in_unflushed_spaces = FALSE;
 
1068
 
 
1069
        UT_LIST_ADD_LAST(space_list, system->space_list, space);
 
1070
 
 
1071
        mutex_exit(&(system->mutex));
 
1072
 
 
1073
        return(TRUE);
 
1074
}
 
1075
 
 
1076
/***********************************************************************
 
1077
Assigns a new space id for a new single-table tablespace. This works simply by
 
1078
incrementing the global counter. If 4 billion id's is not enough, we may need
 
1079
to recycle id's. */
 
1080
static
 
1081
ulint
 
1082
fil_assign_new_space_id(void)
 
1083
/*=========================*/
 
1084
                        /* out: new tablespace id; ULINT_UNDEFINED if could
 
1085
                        not assign an id */
 
1086
{
 
1087
        fil_system_t*   system = fil_system;
 
1088
        ulint           id;
 
1089
 
 
1090
        mutex_enter(&(system->mutex));
 
1091
 
 
1092
        system->max_assigned_id++;
 
1093
 
 
1094
        id = system->max_assigned_id;
 
1095
 
 
1096
        if (id > (SRV_LOG_SPACE_FIRST_ID / 2) && (id % 1000000UL == 0)) {
 
1097
                ut_print_timestamp(stderr);
 
1098
                fprintf(stderr,
 
1099
                        "InnoDB: Warning: you are running out of new"
 
1100
                        " single-table tablespace id's.\n"
 
1101
                        "InnoDB: Current counter is %lu and it"
 
1102
                        " must not exceed %lu!\n"
 
1103
                        "InnoDB: To reset the counter to zero"
 
1104
                        " you have to dump all your tables and\n"
 
1105
                        "InnoDB: recreate the whole InnoDB installation.\n",
 
1106
                        (ulong) id,
 
1107
                        (ulong) SRV_LOG_SPACE_FIRST_ID);
 
1108
        }
 
1109
 
 
1110
        if (id >= SRV_LOG_SPACE_FIRST_ID) {
 
1111
                ut_print_timestamp(stderr);
 
1112
                fprintf(stderr,
 
1113
                        "InnoDB: You have run out of single-table"
 
1114
                        " tablespace id's!\n"
 
1115
                        "InnoDB: Current counter is %lu.\n"
 
1116
                        "InnoDB: To reset the counter to zero you"
 
1117
                        " have to dump all your tables and\n"
 
1118
                        "InnoDB: recreate the whole InnoDB installation.\n",
 
1119
                        (ulong) id);
 
1120
                system->max_assigned_id--;
 
1121
 
 
1122
                id = ULINT_UNDEFINED;
 
1123
        }
 
1124
 
 
1125
        mutex_exit(&(system->mutex));
 
1126
 
 
1127
        return(id);
 
1128
}
 
1129
 
 
1130
/***********************************************************************
 
1131
Frees a space object from the tablespace memory cache. Closes the files in
 
1132
the chain but does not delete them. There must not be any pending i/o's or
 
1133
flushes on the files. */
 
1134
 
 
1135
ibool
 
1136
fil_space_free(
 
1137
/*===========*/
 
1138
                        /* out: TRUE if success */
 
1139
        ulint   id)     /* in: space id */
 
1140
{
 
1141
        fil_system_t*   system = fil_system;
 
1142
        fil_space_t*    space;
 
1143
        fil_space_t*    namespace;
 
1144
        fil_node_t*     fil_node;
 
1145
 
 
1146
        mutex_enter(&(system->mutex));
 
1147
 
 
1148
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
 
1149
 
 
1150
        if (!space) {
 
1151
                ut_print_timestamp(stderr);
 
1152
                fprintf(stderr,
 
1153
                        "  InnoDB: Error: trying to remove tablespace %lu"
 
1154
                        " from the cache but\n"
 
1155
                        "InnoDB: it is not there.\n", (ulong) id);
 
1156
 
 
1157
                mutex_exit(&(system->mutex));
 
1158
 
 
1159
                return(FALSE);
 
1160
        }
 
1161
 
 
1162
        HASH_DELETE(fil_space_t, hash, system->spaces, id, space);
 
1163
 
 
1164
        HASH_SEARCH(name_hash, system->name_hash, ut_fold_string(space->name),
 
1165
                    namespace, 0 == strcmp(space->name, namespace->name));
 
1166
        ut_a(namespace);
 
1167
        ut_a(space == namespace);
 
1168
 
 
1169
        HASH_DELETE(fil_space_t, name_hash, system->name_hash,
 
1170
                    ut_fold_string(space->name), space);
 
1171
 
 
1172
        if (space->is_in_unflushed_spaces) {
 
1173
                space->is_in_unflushed_spaces = FALSE;
 
1174
 
 
1175
                UT_LIST_REMOVE(unflushed_spaces, system->unflushed_spaces,
 
1176
                               space);
 
1177
        }
 
1178
 
 
1179
        UT_LIST_REMOVE(space_list, system->space_list, space);
 
1180
 
 
1181
        ut_a(space->magic_n == FIL_SPACE_MAGIC_N);
 
1182
        ut_a(0 == space->n_pending_flushes);
 
1183
 
 
1184
        fil_node = UT_LIST_GET_FIRST(space->chain);
 
1185
 
 
1186
        while (fil_node != NULL) {
 
1187
                fil_node_free(fil_node, system, space);
 
1188
 
 
1189
                fil_node = UT_LIST_GET_FIRST(space->chain);
 
1190
        }
 
1191
 
 
1192
        ut_a(0 == UT_LIST_GET_LEN(space->chain));
 
1193
 
 
1194
        mutex_exit(&(system->mutex));
 
1195
 
 
1196
        rw_lock_free(&(space->latch));
 
1197
 
 
1198
        mem_free(space->name);
 
1199
        mem_free(space);
 
1200
 
 
1201
        return(TRUE);
 
1202
}
 
1203
 
 
1204
#ifdef UNIV_HOTBACKUP
 
1205
/***********************************************************************
 
1206
Returns the tablespace object for a given id, or NULL if not found from the
 
1207
tablespace memory cache. */
 
1208
static
 
1209
fil_space_t*
 
1210
fil_get_space_for_id_low(
 
1211
/*=====================*/
 
1212
                        /* out: tablespace object or NULL; NOTE that you must
 
1213
                        own &(fil_system->mutex) to call this function! */
 
1214
        ulint   id)     /* in: space id */
 
1215
{
 
1216
        fil_system_t*   system          = fil_system;
 
1217
        fil_space_t*    space;
 
1218
 
 
1219
        ut_ad(system);
 
1220
 
 
1221
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
 
1222
 
 
1223
        return(space);
 
1224
}
 
1225
#endif
 
1226
 
 
1227
/***********************************************************************
 
1228
Returns the size of the space in pages. The tablespace must be cached in the
 
1229
memory cache. */
 
1230
 
 
1231
ulint
 
1232
fil_space_get_size(
 
1233
/*===============*/
 
1234
                        /* out: space size, 0 if space not found */
 
1235
        ulint   id)     /* in: space id */
 
1236
{
 
1237
        fil_system_t*   system          = fil_system;
 
1238
        fil_node_t*     node;
 
1239
        fil_space_t*    space;
 
1240
        ulint           size;
 
1241
 
 
1242
        ut_ad(system);
 
1243
 
 
1244
        fil_mutex_enter_and_prepare_for_io(id);
 
1245
 
 
1246
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
 
1247
 
 
1248
        if (space == NULL) {
 
1249
                mutex_exit(&(system->mutex));
 
1250
 
 
1251
                return(0);
 
1252
        }
 
1253
 
 
1254
        if (space->size == 0 && space->purpose == FIL_TABLESPACE) {
 
1255
                ut_a(id != 0);
 
1256
 
 
1257
                ut_a(1 == UT_LIST_GET_LEN(space->chain));
 
1258
 
 
1259
                node = UT_LIST_GET_FIRST(space->chain);
 
1260
 
 
1261
                /* It must be a single-table tablespace and we have not opened
 
1262
                the file yet; the following calls will open it and update the
 
1263
                size fields */
 
1264
 
 
1265
                fil_node_prepare_for_io(node, system, space);
 
1266
                fil_node_complete_io(node, system, OS_FILE_READ);
 
1267
        }
 
1268
 
 
1269
        size = space->size;
 
1270
 
 
1271
        mutex_exit(&(system->mutex));
 
1272
 
 
1273
        return(size);
 
1274
}
 
1275
 
 
1276
/***********************************************************************
 
1277
Checks if the pair space, page_no refers to an existing page in a tablespace
 
1278
file space. The tablespace must be cached in the memory cache. */
 
1279
 
 
1280
ibool
 
1281
fil_check_adress_in_tablespace(
 
1282
/*===========================*/
 
1283
                        /* out: TRUE if the address is meaningful */
 
1284
        ulint   id,     /* in: space id */
 
1285
        ulint   page_no)/* in: page number */
 
1286
{
 
1287
        if (fil_space_get_size(id) > page_no) {
 
1288
 
 
1289
                return(TRUE);
 
1290
        }
 
1291
 
 
1292
        return(FALSE);
 
1293
}
 
1294
 
 
1295
/********************************************************************
 
1296
Creates a the tablespace memory cache. */
 
1297
static
 
1298
fil_system_t*
 
1299
fil_system_create(
 
1300
/*==============*/
 
1301
                                /* out, own: tablespace memory cache */
 
1302
        ulint   hash_size,      /* in: hash table size */
 
1303
        ulint   max_n_open)     /* in: maximum number of open files; must be
 
1304
                                > 10 */
 
1305
{
 
1306
        fil_system_t*   system;
 
1307
 
 
1308
        ut_a(hash_size > 0);
 
1309
        ut_a(max_n_open > 0);
 
1310
 
 
1311
        system = mem_alloc(sizeof(fil_system_t));
 
1312
 
 
1313
        mutex_create(&system->mutex, SYNC_ANY_LATCH);
 
1314
 
 
1315
        system->spaces = hash_create(hash_size);
 
1316
        system->name_hash = hash_create(hash_size);
 
1317
 
 
1318
        UT_LIST_INIT(system->LRU);
 
1319
 
 
1320
        system->n_open = 0;
 
1321
        system->max_n_open = max_n_open;
 
1322
 
 
1323
        system->modification_counter = 0;
 
1324
        system->max_assigned_id = 0;
 
1325
 
 
1326
        system->tablespace_version = 0;
 
1327
 
 
1328
        UT_LIST_INIT(system->unflushed_spaces);
 
1329
        UT_LIST_INIT(system->space_list);
 
1330
 
 
1331
        return(system);
 
1332
}
 
1333
 
 
1334
/********************************************************************
 
1335
Initializes the tablespace memory cache. */
 
1336
 
 
1337
void
 
1338
fil_init(
 
1339
/*=====*/
 
1340
        ulint   max_n_open)     /* in: max number of open files */
 
1341
{
 
1342
        ulint   hash_size;
 
1343
 
 
1344
        ut_a(fil_system == NULL);
 
1345
 
 
1346
        if (srv_file_per_table) {
 
1347
                hash_size = 50000;
 
1348
        } else {
 
1349
                hash_size = 5000;
 
1350
        }
 
1351
 
 
1352
        fil_system = fil_system_create(hash_size, max_n_open);
 
1353
}
 
1354
 
 
1355
/***********************************************************************
 
1356
Opens all log files and system tablespace data files. They stay open until the
 
1357
database server shutdown. This should be called at a server startup after the
 
1358
space objects for the log and the system tablespace have been created. The
 
1359
purpose of this operation is to make sure we never run out of file descriptors
 
1360
if we need to read from the insert buffer or to write to the log. */
 
1361
 
 
1362
void
 
1363
fil_open_log_and_system_tablespace_files(void)
 
1364
/*==========================================*/
 
1365
{
 
1366
        fil_system_t*   system = fil_system;
 
1367
        fil_space_t*    space;
 
1368
        fil_node_t*     node;
 
1369
 
 
1370
        mutex_enter(&(system->mutex));
 
1371
 
 
1372
        space = UT_LIST_GET_FIRST(system->space_list);
 
1373
 
 
1374
        while (space != NULL) {
 
1375
                if (space->purpose != FIL_TABLESPACE || space->id == 0) {
 
1376
                        node = UT_LIST_GET_FIRST(space->chain);
 
1377
 
 
1378
                        while (node != NULL) {
 
1379
                                if (!node->open) {
 
1380
                                        fil_node_open_file(node, system,
 
1381
                                                           space);
 
1382
                                }
 
1383
                                if (system->max_n_open < 10 + system->n_open) {
 
1384
                                        fprintf(stderr,
 
1385
                                                "InnoDB: Warning: you must"
 
1386
                                                " raise the value of"
 
1387
                                                " innodb_max_open_files in\n"
 
1388
                                                "InnoDB: my.cnf! Remember that"
 
1389
                                                " InnoDB keeps all log files"
 
1390
                                                " and all system\n"
 
1391
                                                "InnoDB: tablespace files open"
 
1392
                                                " for the whole time mysqld is"
 
1393
                                                " running, and\n"
 
1394
                                                "InnoDB: needs to open also"
 
1395
                                                " some .ibd files if the"
 
1396
                                                " file-per-table storage\n"
 
1397
                                                "InnoDB: model is used."
 
1398
                                                " Current open files %lu,"
 
1399
                                                " max allowed"
 
1400
                                                " open files %lu.\n",
 
1401
                                                (ulong) system->n_open,
 
1402
                                                (ulong) system->max_n_open);
 
1403
                                }
 
1404
                                node = UT_LIST_GET_NEXT(chain, node);
 
1405
                        }
 
1406
                }
 
1407
                space = UT_LIST_GET_NEXT(space_list, space);
 
1408
        }
 
1409
 
 
1410
        mutex_exit(&(system->mutex));
 
1411
}
 
1412
 
 
1413
/***********************************************************************
 
1414
Closes all open files. There must not be any pending i/o's or not flushed
 
1415
modifications in the files. */
 
1416
 
 
1417
void
 
1418
fil_close_all_files(void)
 
1419
/*=====================*/
 
1420
{
 
1421
        fil_system_t*   system = fil_system;
 
1422
        fil_space_t*    space;
 
1423
        fil_node_t*     node;
 
1424
 
 
1425
        mutex_enter(&(system->mutex));
 
1426
 
 
1427
        space = UT_LIST_GET_FIRST(system->space_list);
 
1428
 
 
1429
        while (space != NULL) {
 
1430
                node = UT_LIST_GET_FIRST(space->chain);
 
1431
 
 
1432
                while (node != NULL) {
 
1433
                        if (node->open) {
 
1434
                                fil_node_close_file(node, system);
 
1435
                        }
 
1436
                        node = UT_LIST_GET_NEXT(chain, node);
 
1437
                }
 
1438
                space = UT_LIST_GET_NEXT(space_list, space);
 
1439
        }
 
1440
 
 
1441
        mutex_exit(&(system->mutex));
 
1442
}
 
1443
 
 
1444
/***********************************************************************
 
1445
Sets the max tablespace id counter if the given number is bigger than the
 
1446
previous value. */
 
1447
 
 
1448
void
 
1449
fil_set_max_space_id_if_bigger(
 
1450
/*===========================*/
 
1451
        ulint   max_id) /* in: maximum known id */
 
1452
{
 
1453
        fil_system_t*   system = fil_system;
 
1454
 
 
1455
        if (max_id >= SRV_LOG_SPACE_FIRST_ID) {
 
1456
                fprintf(stderr,
 
1457
                        "InnoDB: Fatal error: max tablespace id"
 
1458
                        " is too high, %lu\n", (ulong) max_id);
 
1459
                ut_a(0);
 
1460
        }
 
1461
 
 
1462
        mutex_enter(&(system->mutex));
 
1463
 
 
1464
        if (system->max_assigned_id < max_id) {
 
1465
 
 
1466
                system->max_assigned_id = max_id;
 
1467
        }
 
1468
 
 
1469
        mutex_exit(&(system->mutex));
 
1470
}
 
1471
 
 
1472
/********************************************************************
 
1473
Initializes the ibuf data structure for space 0 == the system tablespace.
 
1474
This can be called after the file space headers have been created and the
 
1475
dictionary system has been initialized. */
 
1476
 
 
1477
void
 
1478
fil_ibuf_init_at_db_start(void)
 
1479
/*===========================*/
 
1480
{
 
1481
        fil_space_t*    space;
 
1482
 
 
1483
        space = UT_LIST_GET_FIRST(fil_system->space_list);
 
1484
 
 
1485
        ut_a(space);
 
1486
        ut_a(space->purpose == FIL_TABLESPACE);
 
1487
 
 
1488
        space->ibuf_data = ibuf_data_init_for_space(space->id);
 
1489
}
 
1490
 
 
1491
/********************************************************************
 
1492
Writes the flushed lsn and the latest archived log number to the page header
 
1493
of the first page of a data file. */
 
1494
static
 
1495
ulint
 
1496
fil_write_lsn_and_arch_no_to_file(
 
1497
/*==============================*/
 
1498
        ulint   space_id,       /* in: space number */
 
1499
        ulint   sum_of_sizes,   /* in: combined size of previous files in
 
1500
                                space, in database pages */
 
1501
        dulint  lsn,            /* in: lsn to write */
 
1502
        ulint   arch_log_no     /* in: archived log number to write */
 
1503
        __attribute__((unused)))
 
1504
{
 
1505
        byte*   buf1;
 
1506
        byte*   buf;
 
1507
 
 
1508
        buf1 = mem_alloc(2 * UNIV_PAGE_SIZE);
 
1509
        buf = ut_align(buf1, UNIV_PAGE_SIZE);
 
1510
 
 
1511
        fil_read(TRUE, space_id, sum_of_sizes, 0, UNIV_PAGE_SIZE, buf, NULL);
 
1512
 
 
1513
        mach_write_to_8(buf + FIL_PAGE_FILE_FLUSH_LSN, lsn);
 
1514
 
 
1515
        fil_write(TRUE, space_id, sum_of_sizes, 0, UNIV_PAGE_SIZE, buf, NULL);
 
1516
 
 
1517
        return(DB_SUCCESS);
 
1518
}
 
1519
 
 
1520
/********************************************************************
 
1521
Writes the flushed lsn and the latest archived log number to the page
 
1522
header of the first page of each data file in the system tablespace. */
 
1523
 
 
1524
ulint
 
1525
fil_write_flushed_lsn_to_data_files(
 
1526
/*================================*/
 
1527
                                /* out: DB_SUCCESS or error number */
 
1528
        dulint  lsn,            /* in: lsn to write */
 
1529
        ulint   arch_log_no)    /* in: latest archived log file number */
 
1530
{
 
1531
        fil_space_t*    space;
 
1532
        fil_node_t*     node;
 
1533
        ulint           sum_of_sizes;
 
1534
        ulint           err;
 
1535
 
 
1536
        mutex_enter(&(fil_system->mutex));
 
1537
 
 
1538
        space = UT_LIST_GET_FIRST(fil_system->space_list);
 
1539
 
 
1540
        while (space) {
 
1541
                /* We only write the lsn to all existing data files which have
 
1542
                been open during the lifetime of the mysqld process; they are
 
1543
                represented by the space objects in the tablespace memory
 
1544
                cache. Note that all data files in the system tablespace 0 are
 
1545
                always open. */
 
1546
 
 
1547
                if (space->purpose == FIL_TABLESPACE
 
1548
                    && space->id == 0) {
 
1549
                        sum_of_sizes = 0;
 
1550
 
 
1551
                        node = UT_LIST_GET_FIRST(space->chain);
 
1552
                        while (node) {
 
1553
                                mutex_exit(&(fil_system->mutex));
 
1554
 
 
1555
                                err = fil_write_lsn_and_arch_no_to_file(
 
1556
                                        space->id, sum_of_sizes, lsn,
 
1557
                                        arch_log_no);
 
1558
                                if (err != DB_SUCCESS) {
 
1559
 
 
1560
                                        return(err);
 
1561
                                }
 
1562
 
 
1563
                                mutex_enter(&(fil_system->mutex));
 
1564
 
 
1565
                                sum_of_sizes += node->size;
 
1566
                                node = UT_LIST_GET_NEXT(chain, node);
 
1567
                        }
 
1568
                }
 
1569
                space = UT_LIST_GET_NEXT(space_list, space);
 
1570
        }
 
1571
 
 
1572
        mutex_exit(&(fil_system->mutex));
 
1573
 
 
1574
        return(DB_SUCCESS);
 
1575
}
 
1576
 
 
1577
/***********************************************************************
 
1578
Reads the flushed lsn and arch no fields from a data file at database
 
1579
startup. */
 
1580
 
 
1581
void
 
1582
fil_read_flushed_lsn_and_arch_log_no(
 
1583
/*=================================*/
 
1584
        os_file_t data_file,            /* in: open data file */
 
1585
        ibool   one_read_already,       /* in: TRUE if min and max parameters
 
1586
                                        below already contain sensible data */
 
1587
#ifdef UNIV_LOG_ARCHIVE
 
1588
        ulint*  min_arch_log_no,        /* in/out: */
 
1589
        ulint*  max_arch_log_no,        /* in/out: */
 
1590
#endif /* UNIV_LOG_ARCHIVE */
 
1591
        dulint* min_flushed_lsn,        /* in/out: */
 
1592
        dulint* max_flushed_lsn)        /* in/out: */
 
1593
{
 
1594
        byte*   buf;
 
1595
        byte*   buf2;
 
1596
        dulint  flushed_lsn;
 
1597
 
 
1598
        buf2 = ut_malloc(2 * UNIV_PAGE_SIZE);
 
1599
        /* Align the memory for a possible read from a raw device */
 
1600
        buf = ut_align(buf2, UNIV_PAGE_SIZE);
 
1601
 
 
1602
        os_file_read(data_file, buf, 0, 0, UNIV_PAGE_SIZE);
 
1603
 
 
1604
        flushed_lsn = mach_read_from_8(buf + FIL_PAGE_FILE_FLUSH_LSN);
 
1605
 
 
1606
        ut_free(buf2);
 
1607
 
 
1608
        if (!one_read_already) {
 
1609
                *min_flushed_lsn = flushed_lsn;
 
1610
                *max_flushed_lsn = flushed_lsn;
 
1611
#ifdef UNIV_LOG_ARCHIVE
 
1612
                *min_arch_log_no = arch_log_no;
 
1613
                *max_arch_log_no = arch_log_no;
 
1614
#endif /* UNIV_LOG_ARCHIVE */
 
1615
                return;
 
1616
        }
 
1617
 
 
1618
        if (ut_dulint_cmp(*min_flushed_lsn, flushed_lsn) > 0) {
 
1619
                *min_flushed_lsn = flushed_lsn;
 
1620
        }
 
1621
        if (ut_dulint_cmp(*max_flushed_lsn, flushed_lsn) < 0) {
 
1622
                *max_flushed_lsn = flushed_lsn;
 
1623
        }
 
1624
#ifdef UNIV_LOG_ARCHIVE
 
1625
        if (*min_arch_log_no > arch_log_no) {
 
1626
                *min_arch_log_no = arch_log_no;
 
1627
        }
 
1628
        if (*max_arch_log_no < arch_log_no) {
 
1629
                *max_arch_log_no = arch_log_no;
 
1630
        }
 
1631
#endif /* UNIV_LOG_ARCHIVE */
 
1632
}
 
1633
 
 
1634
/*================ SINGLE-TABLE TABLESPACES ==========================*/
 
1635
 
 
1636
/***********************************************************************
 
1637
Increments the count of pending insert buffer page merges, if space is not
 
1638
being deleted. */
 
1639
 
 
1640
ibool
 
1641
fil_inc_pending_ibuf_merges(
 
1642
/*========================*/
 
1643
                        /* out: TRUE if being deleted, and ibuf merges should
 
1644
                        be skipped */
 
1645
        ulint   id)     /* in: space id */
 
1646
{
 
1647
        fil_system_t*   system          = fil_system;
 
1648
        fil_space_t*    space;
 
1649
 
 
1650
        mutex_enter(&(system->mutex));
 
1651
 
 
1652
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
 
1653
 
 
1654
        if (space == NULL) {
 
1655
                fprintf(stderr,
 
1656
                        "InnoDB: Error: trying to do ibuf merge to a"
 
1657
                        " dropped tablespace %lu\n",
 
1658
                        (ulong) id);
 
1659
        }
 
1660
 
 
1661
        if (space == NULL || space->stop_ibuf_merges) {
 
1662
                mutex_exit(&(system->mutex));
 
1663
 
 
1664
                return(TRUE);
 
1665
        }
 
1666
 
 
1667
        space->n_pending_ibuf_merges++;
 
1668
 
 
1669
        mutex_exit(&(system->mutex));
 
1670
 
 
1671
        return(FALSE);
 
1672
}
 
1673
 
 
1674
/***********************************************************************
 
1675
Decrements the count of pending insert buffer page merges. */
 
1676
 
 
1677
void
 
1678
fil_decr_pending_ibuf_merges(
 
1679
/*=========================*/
 
1680
        ulint   id)     /* in: space id */
 
1681
{
 
1682
        fil_system_t*   system          = fil_system;
 
1683
        fil_space_t*    space;
 
1684
 
 
1685
        mutex_enter(&(system->mutex));
 
1686
 
 
1687
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
 
1688
 
 
1689
        if (space == NULL) {
 
1690
                fprintf(stderr,
 
1691
                        "InnoDB: Error: decrementing ibuf merge of a"
 
1692
                        " dropped tablespace %lu\n",
 
1693
                        (ulong) id);
 
1694
        }
 
1695
 
 
1696
        if (space != NULL) {
 
1697
                space->n_pending_ibuf_merges--;
 
1698
        }
 
1699
 
 
1700
        mutex_exit(&(system->mutex));
 
1701
}
 
1702
 
 
1703
/************************************************************
 
1704
Creates the database directory for a table if it does not exist yet. */
 
1705
static
 
1706
void
 
1707
fil_create_directory_for_tablename(
 
1708
/*===============================*/
 
1709
        const char*     name)   /* in: name in the standard
 
1710
                                'databasename/tablename' format */
 
1711
{
 
1712
        const char*     namend;
 
1713
        char*           path;
 
1714
        ulint           len;
 
1715
 
 
1716
        len = strlen(fil_path_to_mysql_datadir);
 
1717
        namend = strchr(name, '/');
 
1718
        ut_a(namend);
 
1719
        path = mem_alloc(len + (namend - name) + 2);
 
1720
 
 
1721
        memcpy(path, fil_path_to_mysql_datadir, len);
 
1722
        path[len] = '/';
 
1723
        memcpy(path + len + 1, name, namend - name);
 
1724
        path[len + (namend - name) + 1] = 0;
 
1725
 
 
1726
        srv_normalize_path_for_win(path);
 
1727
 
 
1728
        ut_a(os_file_create_directory(path, FALSE));
 
1729
        mem_free(path);
 
1730
}
 
1731
 
 
1732
#ifndef UNIV_HOTBACKUP
 
1733
/************************************************************
 
1734
Writes a log record about an .ibd file create/rename/delete. */
 
1735
static
 
1736
void
 
1737
fil_op_write_log(
 
1738
/*=============*/
 
1739
        ulint           type,           /* in: MLOG_FILE_CREATE,
 
1740
                                        MLOG_FILE_DELETE, or
 
1741
                                        MLOG_FILE_RENAME */
 
1742
        ulint           space_id,       /* in: space id */
 
1743
        ulint           log_flags,      /* in: redo log flags (stored
 
1744
                                        in the page number field) */
 
1745
        const char*     name,           /* in: table name in the familiar
 
1746
                                        'databasename/tablename' format, or
 
1747
                                        the file path in the case of
 
1748
                                        MLOG_FILE_DELETE */
 
1749
        const char*     new_name,       /* in: if type is MLOG_FILE_RENAME,
 
1750
                                        the new table name in the
 
1751
                                        'databasename/tablename' format */
 
1752
        mtr_t*          mtr)            /* in: mini-transaction handle */
 
1753
{
 
1754
        byte*   log_ptr;
 
1755
        ulint   len;
 
1756
 
 
1757
        log_ptr = mlog_open(mtr, 11 + 2);
 
1758
 
 
1759
        if (!log_ptr) {
 
1760
                /* Logging in mtr is switched off during crash recovery:
 
1761
                in that case mlog_open returns NULL */
 
1762
                return;
 
1763
        }
 
1764
 
 
1765
        log_ptr = mlog_write_initial_log_record_for_file_op(
 
1766
                type, space_id, log_flags, log_ptr, mtr);
 
1767
        /* Let us store the strings as null-terminated for easier readability
 
1768
        and handling */
 
1769
 
 
1770
        len = strlen(name) + 1;
 
1771
 
 
1772
        mach_write_to_2(log_ptr, len);
 
1773
        log_ptr += 2;
 
1774
        mlog_close(mtr, log_ptr);
 
1775
 
 
1776
        mlog_catenate_string(mtr, (byte*) name, len);
 
1777
 
 
1778
        if (type == MLOG_FILE_RENAME) {
 
1779
                ulint   len = strlen(new_name) + 1;
 
1780
                log_ptr = mlog_open(mtr, 2 + len);
 
1781
                ut_a(log_ptr);
 
1782
                mach_write_to_2(log_ptr, len);
 
1783
                log_ptr += 2;
 
1784
                mlog_close(mtr, log_ptr);
 
1785
 
 
1786
                mlog_catenate_string(mtr, (byte*) new_name, len);
 
1787
        }
 
1788
}
 
1789
#endif
 
1790
 
 
1791
/***********************************************************************
 
1792
Parses the body of a log record written about an .ibd file operation. That is,
 
1793
the log record part after the standard (type, space id, page no) header of the
 
1794
log record.
 
1795
 
 
1796
If desired, also replays the delete or rename operation if the .ibd file
 
1797
exists and the space id in it matches. Replays the create operation if a file
 
1798
at that path does not exist yet. If the database directory for the file to be
 
1799
created does not exist, then we create the directory, too.
 
1800
 
 
1801
Note that ibbackup --apply-log sets fil_path_to_mysql_datadir to point to the
 
1802
datadir that we should use in replaying the file operations. */
 
1803
 
 
1804
byte*
 
1805
fil_op_log_parse_or_replay(
 
1806
/*=======================*/
 
1807
                                /* out: end of log record, or NULL if the
 
1808
                                record was not completely contained between
 
1809
                                ptr and end_ptr */
 
1810
        byte*   ptr,            /* in: buffer containing the log record body,
 
1811
                                or an initial segment of it, if the record does
 
1812
                                not fir completely between ptr and end_ptr */
 
1813
        byte*   end_ptr,        /* in: buffer end */
 
1814
        ulint   type,           /* in: the type of this log record */
 
1815
        ulint   space_id,       /* in: the space id of the tablespace in
 
1816
                                question, or 0 if the log record should
 
1817
                                only be parsed but not replayed */
 
1818
        ulint   log_flags)      /* in: redo log flags
 
1819
                                (stored in the page number parameter) */
 
1820
{
 
1821
        ulint           name_len;
 
1822
        ulint           new_name_len;
 
1823
        const char*     name;
 
1824
        const char*     new_name        = NULL;
 
1825
 
 
1826
        if (end_ptr < ptr + 2) {
 
1827
 
 
1828
                return(NULL);
 
1829
        }
 
1830
 
 
1831
        name_len = mach_read_from_2(ptr);
 
1832
 
 
1833
        ptr += 2;
 
1834
 
 
1835
        if (end_ptr < ptr + name_len) {
 
1836
 
 
1837
                return(NULL);
 
1838
        }
 
1839
 
 
1840
        name = (const char*) ptr;
 
1841
 
 
1842
        ptr += name_len;
 
1843
 
 
1844
        if (type == MLOG_FILE_RENAME) {
 
1845
                if (end_ptr < ptr + 2) {
 
1846
 
 
1847
                        return(NULL);
 
1848
                }
 
1849
 
 
1850
                new_name_len = mach_read_from_2(ptr);
 
1851
 
 
1852
                ptr += 2;
 
1853
 
 
1854
                if (end_ptr < ptr + new_name_len) {
 
1855
 
 
1856
                        return(NULL);
 
1857
                }
 
1858
 
 
1859
                new_name = (const char*) ptr;
 
1860
 
 
1861
                ptr += new_name_len;
 
1862
        }
 
1863
 
 
1864
        /* We managed to parse a full log record body */
 
1865
        /*
 
1866
        printf("Parsed log rec of type %lu space %lu\n"
 
1867
        "name %s\n", type, space_id, name);
 
1868
 
 
1869
        if (type == MLOG_FILE_RENAME) {
 
1870
        printf("new name %s\n", new_name);
 
1871
        }
 
1872
        */
 
1873
        if (!space_id) {
 
1874
 
 
1875
                return(ptr);
 
1876
        }
 
1877
 
 
1878
        /* Let us try to perform the file operation, if sensible. Note that
 
1879
        ibbackup has at this stage already read in all space id info to the
 
1880
        fil0fil.c data structures.
 
1881
 
 
1882
        NOTE that our algorithm is not guaranteed to work correctly if there
 
1883
        were renames of tables during the backup. See ibbackup code for more
 
1884
        on the problem. */
 
1885
 
 
1886
        if (type == MLOG_FILE_DELETE) {
 
1887
                if (fil_tablespace_exists_in_mem(space_id)) {
 
1888
                        ut_a(fil_delete_tablespace(space_id));
 
1889
                }
 
1890
        } else if (type == MLOG_FILE_RENAME) {
 
1891
                /* We do the rename based on space id, not old file name;
 
1892
                this should guarantee that after the log replay each .ibd file
 
1893
                has the correct name for the latest log sequence number; the
 
1894
                proof is left as an exercise :) */
 
1895
 
 
1896
                if (fil_tablespace_exists_in_mem(space_id)) {
 
1897
                        /* Create the database directory for the new name, if
 
1898
                        it does not exist yet */
 
1899
                        fil_create_directory_for_tablename(new_name);
 
1900
 
 
1901
                        /* Rename the table if there is not yet a tablespace
 
1902
                        with the same name */
 
1903
 
 
1904
                        if (fil_get_space_id_for_table(new_name)
 
1905
                            == ULINT_UNDEFINED) {
 
1906
                                /* We do not care of the old name, that is
 
1907
                                why we pass NULL as the first argument */
 
1908
                                if (!fil_rename_tablespace(NULL, space_id,
 
1909
                                                           new_name)) {
 
1910
                                        ut_error;
 
1911
                                }
 
1912
                        }
 
1913
                }
 
1914
        } else {
 
1915
                ut_a(type == MLOG_FILE_CREATE);
 
1916
 
 
1917
                if (fil_tablespace_exists_in_mem(space_id)) {
 
1918
                        /* Do nothing */
 
1919
                } else if (fil_get_space_id_for_table(name)
 
1920
                           != ULINT_UNDEFINED) {
 
1921
                        /* Do nothing */
 
1922
                } else if (log_flags & MLOG_FILE_FLAG_TEMP) {
 
1923
                        /* Temporary table, do nothing */
 
1924
                } else {
 
1925
                        /* Create the database directory for name, if it does
 
1926
                        not exist yet */
 
1927
                        fil_create_directory_for_tablename(name);
 
1928
 
 
1929
                        ut_a(space_id != 0);
 
1930
 
 
1931
                        if (fil_create_new_single_table_tablespace(
 
1932
                                    &space_id, name, FALSE,
 
1933
                                    FIL_IBD_FILE_INITIAL_SIZE) != DB_SUCCESS) {
 
1934
                                ut_error;
 
1935
                        }
 
1936
                }
 
1937
        }
 
1938
 
 
1939
        return(ptr);
 
1940
}
 
1941
 
 
1942
/***********************************************************************
 
1943
Deletes a single-table tablespace. The tablespace must be cached in the
 
1944
memory cache. */
 
1945
 
 
1946
ibool
 
1947
fil_delete_tablespace(
 
1948
/*==================*/
 
1949
                        /* out: TRUE if success */
 
1950
        ulint   id)     /* in: space id */
 
1951
{
 
1952
        fil_system_t*   system          = fil_system;
 
1953
        ibool           success;
 
1954
        fil_space_t*    space;
 
1955
        fil_node_t*     node;
 
1956
        ulint           count           = 0;
 
1957
        char*           path;
 
1958
 
 
1959
        ut_a(id != 0);
 
1960
stop_ibuf_merges:
 
1961
        mutex_enter(&(system->mutex));
 
1962
 
 
1963
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
 
1964
 
 
1965
        if (space != NULL) {
 
1966
                space->stop_ibuf_merges = TRUE;
 
1967
 
 
1968
                if (space->n_pending_ibuf_merges == 0) {
 
1969
                        mutex_exit(&(system->mutex));
 
1970
 
 
1971
                        count = 0;
 
1972
 
 
1973
                        goto try_again;
 
1974
                } else {
 
1975
                        if (count > 5000) {
 
1976
                                ut_print_timestamp(stderr);
 
1977
                                fputs("  InnoDB: Warning: trying to"
 
1978
                                      " delete tablespace ", stderr);
 
1979
                                ut_print_filename(stderr, space->name);
 
1980
                                fprintf(stderr, ",\n"
 
1981
                                        "InnoDB: but there are %lu pending"
 
1982
                                        " ibuf merges on it.\n"
 
1983
                                        "InnoDB: Loop %lu.\n",
 
1984
                                        (ulong) space->n_pending_ibuf_merges,
 
1985
                                        (ulong) count);
 
1986
                        }
 
1987
 
 
1988
                        mutex_exit(&(system->mutex));
 
1989
 
 
1990
                        os_thread_sleep(20000);
 
1991
                        count++;
 
1992
 
 
1993
                        goto stop_ibuf_merges;
 
1994
                }
 
1995
        }
 
1996
 
 
1997
        mutex_exit(&(system->mutex));
 
1998
        count = 0;
 
1999
 
 
2000
try_again:
 
2001
        mutex_enter(&(system->mutex));
 
2002
 
 
2003
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
 
2004
 
 
2005
        if (space == NULL) {
 
2006
                ut_print_timestamp(stderr);
 
2007
                fprintf(stderr,
 
2008
                        "  InnoDB: Error: cannot delete tablespace %lu\n"
 
2009
                        "InnoDB: because it is not found in the"
 
2010
                        " tablespace memory cache.\n",
 
2011
                        (ulong) id);
 
2012
 
 
2013
                mutex_exit(&(system->mutex));
 
2014
 
 
2015
                return(FALSE);
 
2016
        }
 
2017
 
 
2018
        ut_a(space);
 
2019
        ut_a(space->n_pending_ibuf_merges == 0);
 
2020
 
 
2021
        space->is_being_deleted = TRUE;
 
2022
 
 
2023
        ut_a(UT_LIST_GET_LEN(space->chain) == 1);
 
2024
        node = UT_LIST_GET_FIRST(space->chain);
 
2025
 
 
2026
        if (space->n_pending_flushes > 0 || node->n_pending > 0) {
 
2027
                if (count > 1000) {
 
2028
                        ut_print_timestamp(stderr);
 
2029
                        fputs("  InnoDB: Warning: trying to"
 
2030
                              " delete tablespace ", stderr);
 
2031
                        ut_print_filename(stderr, space->name);
 
2032
                        fprintf(stderr, ",\n"
 
2033
                                "InnoDB: but there are %lu flushes"
 
2034
                                " and %lu pending i/o's on it\n"
 
2035
                                "InnoDB: Loop %lu.\n",
 
2036
                                (ulong) space->n_pending_flushes,
 
2037
                                (ulong) node->n_pending,
 
2038
                                (ulong) count);
 
2039
                }
 
2040
                mutex_exit(&(system->mutex));
 
2041
                os_thread_sleep(20000);
 
2042
 
 
2043
                count++;
 
2044
 
 
2045
                goto try_again;
 
2046
        }
 
2047
 
 
2048
        path = mem_strdup(space->name);
 
2049
 
 
2050
        mutex_exit(&(system->mutex));
 
2051
#ifndef UNIV_HOTBACKUP
 
2052
        /* Invalidate in the buffer pool all pages belonging to the
 
2053
        tablespace. Since we have set space->is_being_deleted = TRUE, readahead
 
2054
        or ibuf merge can no longer read more pages of this tablespace to the
 
2055
        buffer pool. Thus we can clean the tablespace out of the buffer pool
 
2056
        completely and permanently. The flag is_being_deleted also prevents
 
2057
        fil_flush() from being applied to this tablespace. */
 
2058
 
 
2059
        buf_LRU_invalidate_tablespace(id);
 
2060
#endif
 
2061
        /* printf("Deleting tablespace %s id %lu\n", space->name, id); */
 
2062
 
 
2063
        success = fil_space_free(id);
 
2064
 
 
2065
        if (success) {
 
2066
                success = os_file_delete(path);
 
2067
 
 
2068
                if (!success) {
 
2069
                        success = os_file_delete_if_exists(path);
 
2070
                }
 
2071
        }
 
2072
 
 
2073
        if (success) {
 
2074
#ifndef UNIV_HOTBACKUP
 
2075
                /* Write a log record about the deletion of the .ibd
 
2076
                file, so that ibbackup can replay it in the
 
2077
                --apply-log phase. We use a dummy mtr and the familiar
 
2078
                log write mechanism. */
 
2079
                mtr_t           mtr;
 
2080
 
 
2081
                /* When replaying the operation in ibbackup, do not try
 
2082
                to write any log record */
 
2083
                mtr_start(&mtr);
 
2084
 
 
2085
                fil_op_write_log(MLOG_FILE_DELETE, id, 0, path, NULL, &mtr);
 
2086
                mtr_commit(&mtr);
 
2087
#endif
 
2088
                mem_free(path);
 
2089
 
 
2090
                return(TRUE);
 
2091
        }
 
2092
 
 
2093
        mem_free(path);
 
2094
 
 
2095
        return(FALSE);
 
2096
}
 
2097
 
 
2098
/***********************************************************************
 
2099
Discards a single-table tablespace. The tablespace must be cached in the
 
2100
memory cache. Discarding is like deleting a tablespace, but
 
2101
1) we do not drop the table from the data dictionary;
 
2102
2) we remove all insert buffer entries for the tablespace immediately; in DROP
 
2103
TABLE they are only removed gradually in the background;
 
2104
3) when the user does IMPORT TABLESPACE, the tablespace will have the same id
 
2105
as it originally had. */
 
2106
 
 
2107
ibool
 
2108
fil_discard_tablespace(
 
2109
/*===================*/
 
2110
                        /* out: TRUE if success */
 
2111
        ulint   id)     /* in: space id */
 
2112
{
 
2113
        ibool   success;
 
2114
 
 
2115
        success = fil_delete_tablespace(id);
 
2116
 
 
2117
        if (!success) {
 
2118
                fprintf(stderr,
 
2119
                        "InnoDB: Warning: cannot delete tablespace %lu"
 
2120
                        " in DISCARD TABLESPACE.\n"
 
2121
                        "InnoDB: But let us remove the"
 
2122
                        " insert buffer entries for this tablespace.\n",
 
2123
                        (ulong) id);
 
2124
        }
 
2125
 
 
2126
        /* Remove all insert buffer entries for the tablespace */
 
2127
 
 
2128
        ibuf_delete_for_discarded_space(id);
 
2129
 
 
2130
        return(TRUE);
 
2131
}
 
2132
 
 
2133
/***********************************************************************
 
2134
Renames the memory cache structures of a single-table tablespace. */
 
2135
static
 
2136
ibool
 
2137
fil_rename_tablespace_in_mem(
 
2138
/*=========================*/
 
2139
                                /* out: TRUE if success */
 
2140
        fil_space_t*    space,  /* in: tablespace memory object */
 
2141
        fil_node_t*     node,   /* in: file node of that tablespace */
 
2142
        const char*     path)   /* in: new name */
 
2143
{
 
2144
        fil_system_t*   system          = fil_system;
 
2145
        fil_space_t*    space2;
 
2146
        const char*     old_name        = space->name;
 
2147
 
 
2148
        HASH_SEARCH(name_hash, system->name_hash, ut_fold_string(old_name),
 
2149
                    space2, 0 == strcmp(old_name, space2->name));
 
2150
        if (space != space2) {
 
2151
                fputs("InnoDB: Error: cannot find ", stderr);
 
2152
                ut_print_filename(stderr, old_name);
 
2153
                fputs(" in tablespace memory cache\n", stderr);
 
2154
 
 
2155
                return(FALSE);
 
2156
        }
 
2157
 
 
2158
        HASH_SEARCH(name_hash, system->name_hash, ut_fold_string(path),
 
2159
                    space2, 0 == strcmp(path, space2->name));
 
2160
        if (space2 != NULL) {
 
2161
                fputs("InnoDB: Error: ", stderr);
 
2162
                ut_print_filename(stderr, path);
 
2163
                fputs(" is already in tablespace memory cache\n", stderr);
 
2164
 
 
2165
                return(FALSE);
 
2166
        }
 
2167
 
 
2168
        HASH_DELETE(fil_space_t, name_hash, system->name_hash,
 
2169
                    ut_fold_string(space->name), space);
 
2170
        mem_free(space->name);
 
2171
        mem_free(node->name);
 
2172
 
 
2173
        space->name = mem_strdup(path);
 
2174
        node->name = mem_strdup(path);
 
2175
 
 
2176
        HASH_INSERT(fil_space_t, name_hash, system->name_hash,
 
2177
                    ut_fold_string(path), space);
 
2178
        return(TRUE);
 
2179
}
 
2180
 
 
2181
/***********************************************************************
 
2182
Allocates a file name for a single-table tablespace. The string must be freed
 
2183
by caller with mem_free(). */
 
2184
static
 
2185
char*
 
2186
fil_make_ibd_name(
 
2187
/*==============*/
 
2188
                                        /* out, own: file name */
 
2189
        const char*     name,           /* in: table name or a dir path of a
 
2190
                                        TEMPORARY table */
 
2191
        ibool           is_temp)        /* in: TRUE if it is a dir path */
 
2192
{
 
2193
        ulint   namelen         = strlen(name);
 
2194
        ulint   dirlen          = strlen(fil_path_to_mysql_datadir);
 
2195
        char*   filename        = mem_alloc(namelen + dirlen + sizeof "/.ibd");
 
2196
 
 
2197
        if (is_temp) {
 
2198
                memcpy(filename, name, namelen);
 
2199
                memcpy(filename + namelen, ".ibd", sizeof ".ibd");
 
2200
        } else {
 
2201
                memcpy(filename, fil_path_to_mysql_datadir, dirlen);
 
2202
                filename[dirlen] = '/';
 
2203
 
 
2204
                memcpy(filename + dirlen + 1, name, namelen);
 
2205
                memcpy(filename + dirlen + namelen + 1, ".ibd", sizeof ".ibd");
 
2206
        }
 
2207
 
 
2208
        srv_normalize_path_for_win(filename);
 
2209
 
 
2210
        return(filename);
 
2211
}
 
2212
 
 
2213
/***********************************************************************
 
2214
Renames a single-table tablespace. The tablespace must be cached in the
 
2215
tablespace memory cache. */
 
2216
 
 
2217
ibool
 
2218
fil_rename_tablespace(
 
2219
/*==================*/
 
2220
                                        /* out: TRUE if success */
 
2221
        const char*     old_name,       /* in: old table name in the standard
 
2222
                                        databasename/tablename format of
 
2223
                                        InnoDB, or NULL if we do the rename
 
2224
                                        based on the space id only */
 
2225
        ulint           id,             /* in: space id */
 
2226
        const char*     new_name)       /* in: new table name in the standard
 
2227
                                        databasename/tablename format
 
2228
                                        of InnoDB */
 
2229
{
 
2230
        fil_system_t*   system          = fil_system;
 
2231
        ibool           success;
 
2232
        fil_space_t*    space;
 
2233
        fil_node_t*     node;
 
2234
        ulint           count           = 0;
 
2235
        char*           path;
 
2236
        ibool           old_name_was_specified          = TRUE;
 
2237
        char*           old_path;
 
2238
 
 
2239
        ut_a(id != 0);
 
2240
 
 
2241
        if (old_name == NULL) {
 
2242
                old_name = "(name not specified)";
 
2243
                old_name_was_specified = FALSE;
 
2244
        }
 
2245
retry:
 
2246
        count++;
 
2247
 
 
2248
        if (count > 1000) {
 
2249
                ut_print_timestamp(stderr);
 
2250
                fputs("  InnoDB: Warning: problems renaming ", stderr);
 
2251
                ut_print_filename(stderr, old_name);
 
2252
                fputs(" to ", stderr);
 
2253
                ut_print_filename(stderr, new_name);
 
2254
                fprintf(stderr, ", %lu iterations\n", (ulong) count);
 
2255
        }
 
2256
 
 
2257
        mutex_enter(&(system->mutex));
 
2258
 
 
2259
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
 
2260
 
 
2261
        if (space == NULL) {
 
2262
                fprintf(stderr,
 
2263
                        "InnoDB: Error: cannot find space id %lu"
 
2264
                        " in the tablespace memory cache\n"
 
2265
                        "InnoDB: though the table ", (ulong) id);
 
2266
                ut_print_filename(stderr, old_name);
 
2267
                fputs(" in a rename operation should have that id\n", stderr);
 
2268
                mutex_exit(&(system->mutex));
 
2269
 
 
2270
                return(FALSE);
 
2271
        }
 
2272
 
 
2273
        if (count > 25000) {
 
2274
                space->stop_ios = FALSE;
 
2275
                mutex_exit(&(system->mutex));
 
2276
 
 
2277
                return(FALSE);
 
2278
        }
 
2279
 
 
2280
        /* We temporarily close the .ibd file because we do not trust that
 
2281
        operating systems can rename an open file. For the closing we have to
 
2282
        wait until there are no pending i/o's or flushes on the file. */
 
2283
 
 
2284
        space->stop_ios = TRUE;
 
2285
 
 
2286
        ut_a(UT_LIST_GET_LEN(space->chain) == 1);
 
2287
        node = UT_LIST_GET_FIRST(space->chain);
 
2288
 
 
2289
        if (node->n_pending > 0 || node->n_pending_flushes > 0) {
 
2290
                /* There are pending i/o's or flushes, sleep for a while and
 
2291
                retry */
 
2292
 
 
2293
                mutex_exit(&(system->mutex));
 
2294
 
 
2295
                os_thread_sleep(20000);
 
2296
 
 
2297
                goto retry;
 
2298
 
 
2299
        } else if (node->modification_counter > node->flush_counter) {
 
2300
                /* Flush the space */
 
2301
 
 
2302
                mutex_exit(&(system->mutex));
 
2303
 
 
2304
                os_thread_sleep(20000);
 
2305
 
 
2306
                fil_flush(id);
 
2307
 
 
2308
                goto retry;
 
2309
 
 
2310
        } else if (node->open) {
 
2311
                /* Close the file */
 
2312
 
 
2313
                fil_node_close_file(node, system);
 
2314
        }
 
2315
 
 
2316
        /* Check that the old name in the space is right */
 
2317
 
 
2318
        if (old_name_was_specified) {
 
2319
                old_path = fil_make_ibd_name(old_name, FALSE);
 
2320
 
 
2321
                ut_a(strcmp(space->name, old_path) == 0);
 
2322
                ut_a(strcmp(node->name, old_path) == 0);
 
2323
        } else {
 
2324
                old_path = mem_strdup(space->name);
 
2325
        }
 
2326
 
 
2327
        /* Rename the tablespace and the node in the memory cache */
 
2328
        path = fil_make_ibd_name(new_name, FALSE);
 
2329
        success = fil_rename_tablespace_in_mem(space, node, path);
 
2330
 
 
2331
        if (success) {
 
2332
                success = os_file_rename(old_path, path);
 
2333
 
 
2334
                if (!success) {
 
2335
                        /* We have to revert the changes we made
 
2336
                        to the tablespace memory cache */
 
2337
 
 
2338
                        ut_a(fil_rename_tablespace_in_mem(space, node,
 
2339
                                                          old_path));
 
2340
                }
 
2341
        }
 
2342
 
 
2343
        mem_free(path);
 
2344
        mem_free(old_path);
 
2345
 
 
2346
        space->stop_ios = FALSE;
 
2347
 
 
2348
        mutex_exit(&(system->mutex));
 
2349
 
 
2350
#ifndef UNIV_HOTBACKUP
 
2351
        if (success) {
 
2352
                mtr_t           mtr;
 
2353
 
 
2354
                mtr_start(&mtr);
 
2355
 
 
2356
                fil_op_write_log(MLOG_FILE_RENAME, id, 0, old_name, new_name,
 
2357
                                 &mtr);
 
2358
                mtr_commit(&mtr);
 
2359
        }
 
2360
#endif
 
2361
        return(success);
 
2362
}
 
2363
 
 
2364
/***********************************************************************
 
2365
Creates a new single-table tablespace to a database directory of MySQL.
 
2366
Database directories are under the 'datadir' of MySQL. The datadir is the
 
2367
directory of a running mysqld program. We can refer to it by simply the
 
2368
path '.'. Tables created with CREATE TEMPORARY TABLE we place in the temp
 
2369
dir of the mysqld server. */
 
2370
 
 
2371
ulint
 
2372
fil_create_new_single_table_tablespace(
 
2373
/*===================================*/
 
2374
                                        /* out: DB_SUCCESS or error code */
 
2375
        ulint*          space_id,       /* in/out: space id; if this is != 0,
 
2376
                                        then this is an input parameter,
 
2377
                                        otherwise output */
 
2378
        const char*     tablename,      /* in: the table name in the usual
 
2379
                                        databasename/tablename format
 
2380
                                        of InnoDB, or a dir path to a temp
 
2381
                                        table */
 
2382
        ibool           is_temp,        /* in: TRUE if a table created with
 
2383
                                        CREATE TEMPORARY TABLE */
 
2384
        ulint           size)           /* in: the initial size of the
 
2385
                                        tablespace file in pages,
 
2386
                                        must be >= FIL_IBD_FILE_INITIAL_SIZE */
 
2387
{
 
2388
        os_file_t       file;
 
2389
        ibool           ret;
 
2390
        ulint           err;
 
2391
        byte*           buf2;
 
2392
        byte*           page;
 
2393
        ibool           success;
 
2394
        char*           path;
 
2395
 
 
2396
        ut_a(size >= FIL_IBD_FILE_INITIAL_SIZE);
 
2397
 
 
2398
        path = fil_make_ibd_name(tablename, is_temp);
 
2399
 
 
2400
        file = os_file_create(path, OS_FILE_CREATE, OS_FILE_NORMAL,
 
2401
                              OS_DATA_FILE, &ret);
 
2402
        if (ret == FALSE) {
 
2403
                ut_print_timestamp(stderr);
 
2404
                fputs("  InnoDB: Error creating file ", stderr);
 
2405
                ut_print_filename(stderr, path);
 
2406
                fputs(".\n", stderr);
 
2407
 
 
2408
                /* The following call will print an error message */
 
2409
 
 
2410
                err = os_file_get_last_error(TRUE);
 
2411
 
 
2412
                if (err == OS_FILE_ALREADY_EXISTS) {
 
2413
                        fputs("InnoDB: The file already exists though"
 
2414
                              " the corresponding table did not\n"
 
2415
                              "InnoDB: exist in the InnoDB data dictionary."
 
2416
                              " Have you moved InnoDB\n"
 
2417
                              "InnoDB: .ibd files around without using the"
 
2418
                              " SQL commands\n"
 
2419
                              "InnoDB: DISCARD TABLESPACE and"
 
2420
                              " IMPORT TABLESPACE, or did\n"
 
2421
                              "InnoDB: mysqld crash in the middle of"
 
2422
                              " CREATE TABLE? You can\n"
 
2423
                              "InnoDB: resolve the problem by"
 
2424
                              " removing the file ", stderr);
 
2425
                        ut_print_filename(stderr, path);
 
2426
                        fputs("\n"
 
2427
                              "InnoDB: under the 'datadir' of MySQL.\n",
 
2428
                              stderr);
 
2429
 
 
2430
                        mem_free(path);
 
2431
                        return(DB_TABLESPACE_ALREADY_EXISTS);
 
2432
                }
 
2433
 
 
2434
                if (err == OS_FILE_DISK_FULL) {
 
2435
 
 
2436
                        mem_free(path);
 
2437
                        return(DB_OUT_OF_FILE_SPACE);
 
2438
                }
 
2439
 
 
2440
                mem_free(path);
 
2441
                return(DB_ERROR);
 
2442
        }
 
2443
 
 
2444
        buf2 = ut_malloc(2 * UNIV_PAGE_SIZE);
 
2445
        /* Align the memory for file i/o if we might have O_DIRECT set */
 
2446
        page = ut_align(buf2, UNIV_PAGE_SIZE);
 
2447
 
 
2448
        ret = os_file_set_size(path, file, size * UNIV_PAGE_SIZE, 0);
 
2449
 
 
2450
        if (!ret) {
 
2451
                ut_free(buf2);
 
2452
                os_file_close(file);
 
2453
                os_file_delete(path);
 
2454
 
 
2455
                mem_free(path);
 
2456
                return(DB_OUT_OF_FILE_SPACE);
 
2457
        }
 
2458
 
 
2459
        if (*space_id == 0) {
 
2460
                *space_id = fil_assign_new_space_id();
 
2461
        }
 
2462
 
 
2463
        /* printf("Creating tablespace %s id %lu\n", path, *space_id); */
 
2464
 
 
2465
        if (*space_id == ULINT_UNDEFINED) {
 
2466
                ut_free(buf2);
 
2467
error_exit:
 
2468
                os_file_close(file);
 
2469
error_exit2:
 
2470
                os_file_delete(path);
 
2471
 
 
2472
                mem_free(path);
 
2473
                return(DB_ERROR);
 
2474
        }
 
2475
 
 
2476
        /* We have to write the space id to the file immediately and flush the
 
2477
        file to disk. This is because in crash recovery we must be aware what
 
2478
        tablespaces exist and what are their space id's, so that we can apply
 
2479
        the log records to the right file. It may take quite a while until
 
2480
        buffer pool flush algorithms write anything to the file and flush it to
 
2481
        disk. If we would not write here anything, the file would be filled
 
2482
        with zeros from the call of os_file_set_size(), until a buffer pool
 
2483
        flush would write to it. */
 
2484
 
 
2485
        memset(page, '\0', UNIV_PAGE_SIZE);
 
2486
 
 
2487
        fsp_header_write_space_id(page, *space_id);
 
2488
 
 
2489
        buf_flush_init_for_writing(page, ut_dulint_zero, *space_id, 0);
 
2490
 
 
2491
        ret = os_file_write(path, file, page, 0, 0, UNIV_PAGE_SIZE);
 
2492
 
 
2493
        ut_free(buf2);
 
2494
 
 
2495
        if (!ret) {
 
2496
                fputs("InnoDB: Error: could not write the first page"
 
2497
                      " to tablespace ", stderr);
 
2498
                ut_print_filename(stderr, path);
 
2499
                putc('\n', stderr);
 
2500
                goto error_exit;
 
2501
        }
 
2502
 
 
2503
        ret = os_file_flush(file);
 
2504
 
 
2505
        if (!ret) {
 
2506
                fputs("InnoDB: Error: file flush of tablespace ", stderr);
 
2507
                ut_print_filename(stderr, path);
 
2508
                fputs(" failed\n", stderr);
 
2509
                goto error_exit;
 
2510
        }
 
2511
 
 
2512
        os_file_close(file);
 
2513
 
 
2514
        if (*space_id == ULINT_UNDEFINED) {
 
2515
                goto error_exit2;
 
2516
        }
 
2517
 
 
2518
        success = fil_space_create(path, *space_id, FIL_TABLESPACE);
 
2519
 
 
2520
        if (!success) {
 
2521
                goto error_exit2;
 
2522
        }
 
2523
 
 
2524
        fil_node_create(path, size, *space_id, FALSE);
 
2525
 
 
2526
#ifndef UNIV_HOTBACKUP
 
2527
        {
 
2528
                mtr_t           mtr;
 
2529
 
 
2530
                mtr_start(&mtr);
 
2531
 
 
2532
                fil_op_write_log(MLOG_FILE_CREATE, *space_id,
 
2533
                                 is_temp ? MLOG_FILE_FLAG_TEMP : 0,
 
2534
                                 tablename, NULL, &mtr);
 
2535
 
 
2536
                mtr_commit(&mtr);
 
2537
        }
 
2538
#endif
 
2539
        mem_free(path);
 
2540
        return(DB_SUCCESS);
 
2541
}
 
2542
 
 
2543
/************************************************************************
 
2544
It is possible, though very improbable, that the lsn's in the tablespace to be
 
2545
imported have risen above the current system lsn, if a lengthy purge, ibuf
 
2546
merge, or rollback was performed on a backup taken with ibbackup. If that is
 
2547
the case, reset page lsn's in the file. We assume that mysqld was shut down
 
2548
after it performed these cleanup operations on the .ibd file, so that it at
 
2549
the shutdown stamped the latest lsn to the FIL_PAGE_FILE_FLUSH_LSN in the
 
2550
first page of the .ibd file, and we can determine whether we need to reset the
 
2551
lsn's just by looking at that flush lsn. */
 
2552
 
 
2553
ibool
 
2554
fil_reset_too_high_lsns(
 
2555
/*====================*/
 
2556
                                        /* out: TRUE if success */
 
2557
        const char*     name,           /* in: table name in the
 
2558
                                        databasename/tablename format */
 
2559
        dulint          current_lsn)    /* in: reset lsn's if the lsn stamped
 
2560
                                        to FIL_PAGE_FILE_FLUSH_LSN in the
 
2561
                                        first page is too high */
 
2562
{
 
2563
        os_file_t       file;
 
2564
        char*           filepath;
 
2565
        byte*           page;
 
2566
        byte*           buf2;
 
2567
        dulint          flush_lsn;
 
2568
        ulint           space_id;
 
2569
        ib_longlong     file_size;
 
2570
        ib_longlong     offset;
 
2571
        ulint           page_no;
 
2572
        ibool           success;
 
2573
 
 
2574
        filepath = fil_make_ibd_name(name, FALSE);
 
2575
 
 
2576
        file = os_file_create_simple_no_error_handling(
 
2577
                filepath, OS_FILE_OPEN, OS_FILE_READ_WRITE, &success);
 
2578
        if (!success) {
 
2579
                /* The following call prints an error message */
 
2580
                os_file_get_last_error(TRUE);
 
2581
 
 
2582
                ut_print_timestamp(stderr);
 
2583
 
 
2584
                fputs("  InnoDB: Error: trying to open a table,"
 
2585
                      " but could not\n"
 
2586
                      "InnoDB: open the tablespace file ", stderr);
 
2587
                ut_print_filename(stderr, filepath);
 
2588
                fputs("!\n", stderr);
 
2589
                mem_free(filepath);
 
2590
 
 
2591
                return(FALSE);
 
2592
        }
 
2593
 
 
2594
        /* Read the first page of the tablespace */
 
2595
 
 
2596
        buf2 = ut_malloc(2 * UNIV_PAGE_SIZE);
 
2597
        /* Align the memory for file i/o if we might have O_DIRECT set */
 
2598
        page = ut_align(buf2, UNIV_PAGE_SIZE);
 
2599
 
 
2600
        success = os_file_read(file, page, 0, 0, UNIV_PAGE_SIZE);
 
2601
        if (!success) {
 
2602
 
 
2603
                goto func_exit;
 
2604
        }
 
2605
 
 
2606
        /* We have to read the file flush lsn from the header of the file */
 
2607
 
 
2608
        flush_lsn = mach_read_from_8(page + FIL_PAGE_FILE_FLUSH_LSN);
 
2609
 
 
2610
        if (ut_dulint_cmp(current_lsn, flush_lsn) >= 0) {
 
2611
                /* Ok */
 
2612
                success = TRUE;
 
2613
 
 
2614
                goto func_exit;
 
2615
        }
 
2616
 
 
2617
        space_id = fsp_header_get_space_id(page);
 
2618
 
 
2619
        ut_print_timestamp(stderr);
 
2620
        fprintf(stderr,
 
2621
                "  InnoDB: Flush lsn in the tablespace file %lu"
 
2622
                " to be imported\n"
 
2623
                "InnoDB: is %lu %lu, which exceeds current"
 
2624
                " system lsn %lu %lu.\n"
 
2625
                "InnoDB: We reset the lsn's in the file ",
 
2626
                (ulong) space_id,
 
2627
                (ulong) ut_dulint_get_high(flush_lsn),
 
2628
                (ulong) ut_dulint_get_low(flush_lsn),
 
2629
                (ulong) ut_dulint_get_high(current_lsn),
 
2630
                (ulong) ut_dulint_get_low(current_lsn));
 
2631
        ut_print_filename(stderr, filepath);
 
2632
        fputs(".\n", stderr);
 
2633
 
 
2634
        /* Loop through all the pages in the tablespace and reset the lsn and
 
2635
        the page checksum if necessary */
 
2636
 
 
2637
        file_size = os_file_get_size_as_iblonglong(file);
 
2638
 
 
2639
        for (offset = 0; offset < file_size; offset += UNIV_PAGE_SIZE) {
 
2640
                success = os_file_read(file, page,
 
2641
                                       (ulint)(offset & 0xFFFFFFFFUL),
 
2642
                                       (ulint)(offset >> 32), UNIV_PAGE_SIZE);
 
2643
                if (!success) {
 
2644
 
 
2645
                        goto func_exit;
 
2646
                }
 
2647
                if (ut_dulint_cmp(mach_read_from_8(page + FIL_PAGE_LSN),
 
2648
                                  current_lsn) > 0) {
 
2649
                        /* We have to reset the lsn */
 
2650
                        space_id = mach_read_from_4(
 
2651
                                page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
 
2652
                        page_no = mach_read_from_4(page + FIL_PAGE_OFFSET);
 
2653
 
 
2654
                        buf_flush_init_for_writing(page, current_lsn, space_id,
 
2655
                                                   page_no);
 
2656
                        success = os_file_write(filepath, file, page,
 
2657
                                                (ulint)(offset & 0xFFFFFFFFUL),
 
2658
                                                (ulint)(offset >> 32),
 
2659
                                                UNIV_PAGE_SIZE);
 
2660
                        if (!success) {
 
2661
 
 
2662
                                goto func_exit;
 
2663
                        }
 
2664
                }
 
2665
        }
 
2666
 
 
2667
        success = os_file_flush(file);
 
2668
        if (!success) {
 
2669
 
 
2670
                goto func_exit;
 
2671
        }
 
2672
 
 
2673
        /* We now update the flush_lsn stamp at the start of the file */
 
2674
        success = os_file_read(file, page, 0, 0, UNIV_PAGE_SIZE);
 
2675
        if (!success) {
 
2676
 
 
2677
                goto func_exit;
 
2678
        }
 
2679
 
 
2680
        mach_write_to_8(page + FIL_PAGE_FILE_FLUSH_LSN, current_lsn);
 
2681
 
 
2682
        success = os_file_write(filepath, file, page, 0, 0, UNIV_PAGE_SIZE);
 
2683
        if (!success) {
 
2684
 
 
2685
                goto func_exit;
 
2686
        }
 
2687
        success = os_file_flush(file);
 
2688
func_exit:
 
2689
        os_file_close(file);
 
2690
        ut_free(buf2);
 
2691
        mem_free(filepath);
 
2692
 
 
2693
        return(success);
 
2694
}
 
2695
 
 
2696
/************************************************************************
 
2697
Tries to open a single-table tablespace and optionally checks the space id is
 
2698
right in it. If does not succeed, prints an error message to the .err log. This
 
2699
function is used to open a tablespace when we start up mysqld, and also in
 
2700
IMPORT TABLESPACE.
 
2701
NOTE that we assume this operation is used either at the database startup
 
2702
or under the protection of the dictionary mutex, so that two users cannot
 
2703
race here. This operation does not leave the file associated with the
 
2704
tablespace open, but closes it after we have looked at the space id in it. */
 
2705
 
 
2706
ibool
 
2707
fil_open_single_table_tablespace(
 
2708
/*=============================*/
 
2709
                                        /* out: TRUE if success */
 
2710
        ibool           check_space_id, /* in: should we check that the space
 
2711
                                        id in the file is right; we assume
 
2712
                                        that this function runs much faster
 
2713
                                        if no check is made, since accessing
 
2714
                                        the file inode probably is much
 
2715
                                        faster (the OS caches them) than
 
2716
                                        accessing the first page of the file */
 
2717
        ulint           id,             /* in: space id */
 
2718
        const char*     name)           /* in: table name in the
 
2719
                                        databasename/tablename format */
 
2720
{
 
2721
        os_file_t       file;
 
2722
        char*           filepath;
 
2723
        ibool           success;
 
2724
        byte*           buf2;
 
2725
        byte*           page;
 
2726
        ulint           space_id;
 
2727
        ibool           ret             = TRUE;
 
2728
 
 
2729
        filepath = fil_make_ibd_name(name, FALSE);
 
2730
 
 
2731
        file = os_file_create_simple_no_error_handling(
 
2732
                filepath, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success);
 
2733
        if (!success) {
 
2734
                /* The following call prints an error message */
 
2735
                os_file_get_last_error(TRUE);
 
2736
 
 
2737
                ut_print_timestamp(stderr);
 
2738
 
 
2739
                fputs("  InnoDB: Error: trying to open a table,"
 
2740
                      " but could not\n"
 
2741
                      "InnoDB: open the tablespace file ", stderr);
 
2742
                ut_print_filename(stderr, filepath);
 
2743
                fputs("!\n"
 
2744
                      "InnoDB: Have you moved InnoDB .ibd files around"
 
2745
                      " without using the\n"
 
2746
                      "InnoDB: commands DISCARD TABLESPACE and"
 
2747
                      " IMPORT TABLESPACE?\n"
 
2748
                      "InnoDB: It is also possible that this is"
 
2749
                      " a temporary table #sql...,\n"
 
2750
                      "InnoDB: and MySQL removed the .ibd file for this.\n"
 
2751
                      "InnoDB: Please refer to\n"
 
2752
                      "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
 
2753
                      "innodb-troubleshooting-datadict.html\n"
 
2754
                      "InnoDB: for how to resolve the issue.\n", stderr);
 
2755
 
 
2756
                mem_free(filepath);
 
2757
 
 
2758
                return(FALSE);
 
2759
        }
 
2760
 
 
2761
        if (!check_space_id) {
 
2762
                space_id = id;
 
2763
 
 
2764
                goto skip_check;
 
2765
        }
 
2766
 
 
2767
        /* Read the first page of the tablespace */
 
2768
 
 
2769
        buf2 = ut_malloc(2 * UNIV_PAGE_SIZE);
 
2770
        /* Align the memory for file i/o if we might have O_DIRECT set */
 
2771
        page = ut_align(buf2, UNIV_PAGE_SIZE);
 
2772
 
 
2773
        success = os_file_read(file, page, 0, 0, UNIV_PAGE_SIZE);
 
2774
 
 
2775
        /* We have to read the tablespace id from the file */
 
2776
 
 
2777
        space_id = fsp_header_get_space_id(page);
 
2778
 
 
2779
        ut_free(buf2);
 
2780
 
 
2781
        if (space_id != id) {
 
2782
                ut_print_timestamp(stderr);
 
2783
 
 
2784
                fputs("  InnoDB: Error: tablespace id in file ", stderr);
 
2785
                ut_print_filename(stderr, filepath);
 
2786
                fprintf(stderr, " is %lu, but in the InnoDB\n"
 
2787
                        "InnoDB: data dictionary it is %lu.\n"
 
2788
                        "InnoDB: Have you moved InnoDB .ibd files"
 
2789
                        " around without using the\n"
 
2790
                        "InnoDB: commands DISCARD TABLESPACE and"
 
2791
                        " IMPORT TABLESPACE?\n"
 
2792
                        "InnoDB: Please refer to\n"
 
2793
                        "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
 
2794
                        "innodb-troubleshooting-datadict.html\n"
 
2795
                        "InnoDB: for how to resolve the issue.\n",
 
2796
                        (ulong) space_id, (ulong) id);
 
2797
 
 
2798
                ret = FALSE;
 
2799
 
 
2800
                goto func_exit;
 
2801
        }
 
2802
 
 
2803
skip_check:
 
2804
        success = fil_space_create(filepath, space_id, FIL_TABLESPACE);
 
2805
 
 
2806
        if (!success) {
 
2807
                goto func_exit;
 
2808
        }
 
2809
 
 
2810
        /* We do not measure the size of the file, that is why we pass the 0
 
2811
        below */
 
2812
 
 
2813
        fil_node_create(filepath, 0, space_id, FALSE);
 
2814
func_exit:
 
2815
        os_file_close(file);
 
2816
        mem_free(filepath);
 
2817
 
 
2818
        return(ret);
 
2819
}
 
2820
 
 
2821
#ifdef UNIV_HOTBACKUP
 
2822
/***********************************************************************
 
2823
Allocates a file name for an old version of a single-table tablespace.
 
2824
The string must be freed by caller with mem_free()! */
 
2825
static
 
2826
char*
 
2827
fil_make_ibbackup_old_name(
 
2828
/*=======================*/
 
2829
                                        /* out, own: file name */
 
2830
        const char*     name)           /* in: original file name */
 
2831
{
 
2832
        static const char suffix[] = "_ibbackup_old_vers_";
 
2833
        ulint   len     = strlen(name);
 
2834
        char*   path    = mem_alloc(len + (15 + sizeof suffix));
 
2835
 
 
2836
        memcpy(path, name, len);
 
2837
        memcpy(path + len, suffix, (sizeof suffix) - 1);
 
2838
        ut_sprintf_timestamp_without_extra_chars(path + len + sizeof suffix);
 
2839
        return(path);
 
2840
}
 
2841
#endif /* UNIV_HOTBACKUP */
 
2842
 
 
2843
/************************************************************************
 
2844
Opens an .ibd file and adds the associated single-table tablespace to the
 
2845
InnoDB fil0fil.c data structures. */
 
2846
static
 
2847
void
 
2848
fil_load_single_table_tablespace(
 
2849
/*=============================*/
 
2850
        const char*     dbname,         /* in: database name */
 
2851
        const char*     filename)       /* in: file name (not a path),
 
2852
                                        including the .ibd extension */
 
2853
{
 
2854
        os_file_t       file;
 
2855
        char*           filepath;
 
2856
        ibool           success;
 
2857
        byte*           buf2;
 
2858
        byte*           page;
 
2859
        ulint           space_id;
 
2860
        ulint           size_low;
 
2861
        ulint           size_high;
 
2862
        ib_longlong     size;
 
2863
#ifdef UNIV_HOTBACKUP
 
2864
        fil_space_t*    space;
 
2865
#endif
 
2866
        filepath = mem_alloc(strlen(dbname) + strlen(filename)
 
2867
                             + strlen(fil_path_to_mysql_datadir) + 3);
 
2868
 
 
2869
        sprintf(filepath, "%s/%s/%s", fil_path_to_mysql_datadir, dbname,
 
2870
                filename);
 
2871
        srv_normalize_path_for_win(filepath);
 
2872
#ifdef __WIN__
 
2873
# ifndef UNIV_HOTBACKUP
 
2874
        /* If lower_case_table_names is 0 or 2, then MySQL allows database
 
2875
        directory names with upper case letters. On Windows, all table and
 
2876
        database names in InnoDB are internally always in lower case. Put the
 
2877
        file path to lower case, so that we are consistent with InnoDB's
 
2878
        internal data dictionary. */
 
2879
 
 
2880
        dict_casedn_str(filepath);
 
2881
# endif /* !UNIV_HOTBACKUP */
 
2882
#endif
 
2883
        file = os_file_create_simple_no_error_handling(
 
2884
                filepath, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success);
 
2885
        if (!success) {
 
2886
                /* The following call prints an error message */
 
2887
                os_file_get_last_error(TRUE);
 
2888
 
 
2889
                fprintf(stderr,
 
2890
                        "InnoDB: Error: could not open single-table tablespace"
 
2891
                        " file\n"
 
2892
                        "InnoDB: %s!\n"
 
2893
                        "InnoDB: We do not continue the crash recovery,"
 
2894
                        " because the table may become\n"
 
2895
                        "InnoDB: corrupt if we cannot apply the log records"
 
2896
                        " in the InnoDB log to it.\n"
 
2897
                        "InnoDB: To fix the problem and start mysqld:\n"
 
2898
                        "InnoDB: 1) If there is a permission problem"
 
2899
                        " in the file and mysqld cannot\n"
 
2900
                        "InnoDB: open the file, you should"
 
2901
                        " modify the permissions.\n"
 
2902
                        "InnoDB: 2) If the table is not needed, or you can"
 
2903
                        " restore it from a backup,\n"
 
2904
                        "InnoDB: then you can remove the .ibd file,"
 
2905
                        " and InnoDB will do a normal\n"
 
2906
                        "InnoDB: crash recovery and ignore that table.\n"
 
2907
                        "InnoDB: 3) If the file system or the"
 
2908
                        " disk is broken, and you cannot remove\n"
 
2909
                        "InnoDB: the .ibd file, you can set"
 
2910
                        " innodb_force_recovery > 0 in my.cnf\n"
 
2911
                        "InnoDB: and force InnoDB to continue crash"
 
2912
                        " recovery here.\n", filepath);
 
2913
 
 
2914
                mem_free(filepath);
 
2915
 
 
2916
                if (srv_force_recovery > 0) {
 
2917
                        fprintf(stderr,
 
2918
                                "InnoDB: innodb_force_recovery"
 
2919
                                " was set to %lu. Continuing crash recovery\n"
 
2920
                                "InnoDB: even though we cannot access"
 
2921
                                " the .ibd file of this table.\n",
 
2922
                                srv_force_recovery);
 
2923
                        return;
 
2924
                }
 
2925
 
 
2926
                exit(1);
 
2927
        }
 
2928
 
 
2929
        success = os_file_get_size(file, &size_low, &size_high);
 
2930
 
 
2931
        if (!success) {
 
2932
                /* The following call prints an error message */
 
2933
                os_file_get_last_error(TRUE);
 
2934
 
 
2935
                fprintf(stderr,
 
2936
                        "InnoDB: Error: could not measure the size"
 
2937
                        " of single-table tablespace file\n"
 
2938
                        "InnoDB: %s!\n"
 
2939
                        "InnoDB: We do not continue crash recovery,"
 
2940
                        " because the table will become\n"
 
2941
                        "InnoDB: corrupt if we cannot apply the log records"
 
2942
                        " in the InnoDB log to it.\n"
 
2943
                        "InnoDB: To fix the problem and start mysqld:\n"
 
2944
                        "InnoDB: 1) If there is a permission problem"
 
2945
                        " in the file and mysqld cannot\n"
 
2946
                        "InnoDB: access the file, you should"
 
2947
                        " modify the permissions.\n"
 
2948
                        "InnoDB: 2) If the table is not needed,"
 
2949
                        " or you can restore it from a backup,\n"
 
2950
                        "InnoDB: then you can remove the .ibd file,"
 
2951
                        " and InnoDB will do a normal\n"
 
2952
                        "InnoDB: crash recovery and ignore that table.\n"
 
2953
                        "InnoDB: 3) If the file system or the disk is broken,"
 
2954
                        " and you cannot remove\n"
 
2955
                        "InnoDB: the .ibd file, you can set"
 
2956
                        " innodb_force_recovery > 0 in my.cnf\n"
 
2957
                        "InnoDB: and force InnoDB to continue"
 
2958
                        " crash recovery here.\n", filepath);
 
2959
 
 
2960
                os_file_close(file);
 
2961
                mem_free(filepath);
 
2962
 
 
2963
                if (srv_force_recovery > 0) {
 
2964
                        fprintf(stderr,
 
2965
                                "InnoDB: innodb_force_recovery"
 
2966
                                " was set to %lu. Continuing crash recovery\n"
 
2967
                                "InnoDB: even though we cannot access"
 
2968
                                " the .ibd file of this table.\n",
 
2969
                                srv_force_recovery);
 
2970
                        return;
 
2971
                }
 
2972
 
 
2973
                exit(1);
 
2974
        }
 
2975
 
 
2976
        /* TODO: What to do in other cases where we cannot access an .ibd
 
2977
        file during a crash recovery? */
 
2978
 
 
2979
        /* Every .ibd file is created >= 4 pages in size. Smaller files
 
2980
        cannot be ok. */
 
2981
 
 
2982
        size = (((ib_longlong)size_high) << 32) + (ib_longlong)size_low;
 
2983
#ifndef UNIV_HOTBACKUP
 
2984
        if (size < FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE) {
 
2985
                fprintf(stderr,
 
2986
                        "InnoDB: Error: the size of single-table tablespace"
 
2987
                        " file %s\n"
 
2988
                        "InnoDB: is only %lu %lu, should be at least %lu!",
 
2989
                        filepath,
 
2990
                        (ulong) size_high,
 
2991
                        (ulong) size_low, (ulong) (4 * UNIV_PAGE_SIZE));
 
2992
                os_file_close(file);
 
2993
                mem_free(filepath);
 
2994
 
 
2995
                return;
 
2996
        }
 
2997
#endif
 
2998
        /* Read the first page of the tablespace if the size big enough */
 
2999
 
 
3000
        buf2 = ut_malloc(2 * UNIV_PAGE_SIZE);
 
3001
        /* Align the memory for file i/o if we might have O_DIRECT set */
 
3002
        page = ut_align(buf2, UNIV_PAGE_SIZE);
 
3003
 
 
3004
        if (size >= FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE) {
 
3005
                success = os_file_read(file, page, 0, 0, UNIV_PAGE_SIZE);
 
3006
 
 
3007
                /* We have to read the tablespace id from the file */
 
3008
 
 
3009
                space_id = fsp_header_get_space_id(page);
 
3010
        } else {
 
3011
                space_id = ULINT_UNDEFINED;
 
3012
        }
 
3013
 
 
3014
#ifndef UNIV_HOTBACKUP
 
3015
        if (space_id == ULINT_UNDEFINED || space_id == 0) {
 
3016
                fprintf(stderr,
 
3017
                        "InnoDB: Error: tablespace id %lu in file %s"
 
3018
                        " is not sensible\n",
 
3019
                        (ulong) space_id,
 
3020
                        filepath);
 
3021
                goto func_exit;
 
3022
        }
 
3023
#else
 
3024
        if (space_id == ULINT_UNDEFINED || space_id == 0) {
 
3025
                char*   new_path;
 
3026
 
 
3027
                fprintf(stderr,
 
3028
                        "InnoDB: Renaming tablespace %s of id %lu,\n"
 
3029
                        "InnoDB: to %s_ibbackup_old_vers_<timestamp>\n"
 
3030
                        "InnoDB: because its size %lld is too small"
 
3031
                        " (< 4 pages 16 kB each),\n"
 
3032
                        "InnoDB: or the space id in the file header"
 
3033
                        " is not sensible.\n"
 
3034
                        "InnoDB: This can happen in an ibbackup run,"
 
3035
                        " and is not dangerous.\n",
 
3036
                        filepath, space_id, filepath, size);
 
3037
                os_file_close(file);
 
3038
 
 
3039
                new_path = fil_make_ibbackup_old_name(filepath);
 
3040
                ut_a(os_file_rename(filepath, new_path));
 
3041
 
 
3042
                ut_free(buf2);
 
3043
                mem_free(filepath);
 
3044
                mem_free(new_path);
 
3045
 
 
3046
                return;
 
3047
        }
 
3048
 
 
3049
        /* A backup may contain the same space several times, if the space got
 
3050
        renamed at a sensitive time. Since it is enough to have one version of
 
3051
        the space, we rename the file if a space with the same space id
 
3052
        already exists in the tablespace memory cache. We rather rename the
 
3053
        file than delete it, because if there is a bug, we do not want to
 
3054
        destroy valuable data. */
 
3055
 
 
3056
        mutex_enter(&(fil_system->mutex));
 
3057
 
 
3058
        space = fil_get_space_for_id_low(space_id);
 
3059
 
 
3060
        if (space) {
 
3061
                char*   new_path;
 
3062
 
 
3063
                fprintf(stderr,
 
3064
                        "InnoDB: Renaming tablespace %s of id %lu,\n"
 
3065
                        "InnoDB: to %s_ibbackup_old_vers_<timestamp>\n"
 
3066
                        "InnoDB: because space %s with the same id\n"
 
3067
                        "InnoDB: was scanned earlier. This can happen"
 
3068
                        " if you have renamed tables\n"
 
3069
                        "InnoDB: during an ibbackup run.\n",
 
3070
                        filepath, space_id, filepath,
 
3071
                        space->name);
 
3072
                os_file_close(file);
 
3073
 
 
3074
                new_path = fil_make_ibbackup_old_name(filepath);
 
3075
 
 
3076
                mutex_exit(&(fil_system->mutex));
 
3077
 
 
3078
                ut_a(os_file_rename(filepath, new_path));
 
3079
 
 
3080
                ut_free(buf2);
 
3081
                mem_free(filepath);
 
3082
                mem_free(new_path);
 
3083
 
 
3084
                return;
 
3085
        }
 
3086
        mutex_exit(&(fil_system->mutex));
 
3087
#endif
 
3088
        success = fil_space_create(filepath, space_id, FIL_TABLESPACE);
 
3089
 
 
3090
        if (!success) {
 
3091
 
 
3092
                goto func_exit;
 
3093
        }
 
3094
 
 
3095
        /* We do not use the size information we have about the file, because
 
3096
        the rounding formula for extents and pages is somewhat complex; we
 
3097
        let fil_node_open() do that task. */
 
3098
 
 
3099
        fil_node_create(filepath, 0, space_id, FALSE);
 
3100
func_exit:
 
3101
        os_file_close(file);
 
3102
        ut_free(buf2);
 
3103
        mem_free(filepath);
 
3104
}
 
3105
 
 
3106
/***************************************************************************
 
3107
A fault-tolerant function that tries to read the next file name in the
 
3108
directory. We retry 100 times if os_file_readdir_next_file() returns -1. The
 
3109
idea is to read as much good data as we can and jump over bad data. */
 
3110
static
 
3111
int
 
3112
fil_file_readdir_next_file(
 
3113
/*=======================*/
 
3114
                                /* out: 0 if ok, -1 if error even after the
 
3115
                                retries, 1 if at the end of the directory */
 
3116
        ulint*          err,    /* out: this is set to DB_ERROR if an error
 
3117
                                was encountered, otherwise not changed */
 
3118
        const char*     dirname,/* in: directory name or path */
 
3119
        os_file_dir_t   dir,    /* in: directory stream */
 
3120
        os_file_stat_t* info)   /* in/out: buffer where the info is returned */
 
3121
{
 
3122
        ulint   i;
 
3123
        int     ret;
 
3124
 
 
3125
        for (i = 0; i < 100; i++) {
 
3126
                ret = os_file_readdir_next_file(dirname, dir, info);
 
3127
 
 
3128
                if (ret != -1) {
 
3129
 
 
3130
                        return(ret);
 
3131
                }
 
3132
 
 
3133
                fprintf(stderr,
 
3134
                        "InnoDB: Error: os_file_readdir_next_file()"
 
3135
                        " returned -1 in\n"
 
3136
                        "InnoDB: directory %s\n"
 
3137
                        "InnoDB: Crash recovery may have failed"
 
3138
                        " for some .ibd files!\n", dirname);
 
3139
 
 
3140
                *err = DB_ERROR;
 
3141
        }
 
3142
 
 
3143
        return(-1);
 
3144
}
 
3145
 
 
3146
/************************************************************************
 
3147
At the server startup, if we need crash recovery, scans the database
 
3148
directories under the MySQL datadir, looking for .ibd files. Those files are
 
3149
single-table tablespaces. We need to know the space id in each of them so that
 
3150
we know into which file we should look to check the contents of a page stored
 
3151
in the doublewrite buffer, also to know where to apply log records where the
 
3152
space id is != 0. */
 
3153
 
 
3154
ulint
 
3155
fil_load_single_table_tablespaces(void)
 
3156
/*===================================*/
 
3157
                        /* out: DB_SUCCESS or error number */
 
3158
{
 
3159
        int             ret;
 
3160
        char*           dbpath          = NULL;
 
3161
        ulint           dbpath_len      = 100;
 
3162
        os_file_dir_t   dir;
 
3163
        os_file_dir_t   dbdir;
 
3164
        os_file_stat_t  dbinfo;
 
3165
        os_file_stat_t  fileinfo;
 
3166
        ulint           err             = DB_SUCCESS;
 
3167
 
 
3168
        /* The datadir of MySQL is always the default directory of mysqld */
 
3169
 
 
3170
        dir = os_file_opendir(fil_path_to_mysql_datadir, TRUE);
 
3171
 
 
3172
        if (dir == NULL) {
 
3173
 
 
3174
                return(DB_ERROR);
 
3175
        }
 
3176
 
 
3177
        dbpath = mem_alloc(dbpath_len);
 
3178
 
 
3179
        /* Scan all directories under the datadir. They are the database
 
3180
        directories of MySQL. */
 
3181
 
 
3182
        ret = fil_file_readdir_next_file(&err, fil_path_to_mysql_datadir, dir,
 
3183
                                         &dbinfo);
 
3184
        while (ret == 0) {
 
3185
                ulint len;
 
3186
                /* printf("Looking at %s in datadir\n", dbinfo.name); */
 
3187
 
 
3188
                if (dbinfo.type == OS_FILE_TYPE_FILE
 
3189
                    || dbinfo.type == OS_FILE_TYPE_UNKNOWN) {
 
3190
 
 
3191
                        goto next_datadir_item;
 
3192
                }
 
3193
 
 
3194
                /* We found a symlink or a directory; try opening it to see
 
3195
                if a symlink is a directory */
 
3196
 
 
3197
                len = strlen(fil_path_to_mysql_datadir)
 
3198
                        + strlen (dbinfo.name) + 2;
 
3199
                if (len > dbpath_len) {
 
3200
                        dbpath_len = len;
 
3201
 
 
3202
                        if (dbpath) {
 
3203
                                mem_free(dbpath);
 
3204
                        }
 
3205
 
 
3206
                        dbpath = mem_alloc(dbpath_len);
 
3207
                }
 
3208
                sprintf(dbpath, "%s/%s", fil_path_to_mysql_datadir,
 
3209
                        dbinfo.name);
 
3210
                srv_normalize_path_for_win(dbpath);
 
3211
 
 
3212
                dbdir = os_file_opendir(dbpath, FALSE);
 
3213
 
 
3214
                if (dbdir != NULL) {
 
3215
                        /* printf("Opened dir %s\n", dbinfo.name); */
 
3216
 
 
3217
                        /* We found a database directory; loop through it,
 
3218
                        looking for possible .ibd files in it */
 
3219
 
 
3220
                        ret = fil_file_readdir_next_file(&err, dbpath, dbdir,
 
3221
                                                         &fileinfo);
 
3222
                        while (ret == 0) {
 
3223
                                /* printf(
 
3224
                                "     Looking at file %s\n", fileinfo.name); */
 
3225
 
 
3226
                                if (fileinfo.type == OS_FILE_TYPE_DIR) {
 
3227
 
 
3228
                                        goto next_file_item;
 
3229
                                }
 
3230
 
 
3231
                                /* We found a symlink or a file */
 
3232
                                if (strlen(fileinfo.name) > 4
 
3233
                                    && 0 == strcmp(fileinfo.name
 
3234
                                                   + strlen(fileinfo.name) - 4,
 
3235
                                                   ".ibd")) {
 
3236
                                        /* The name ends in .ibd; try opening
 
3237
                                        the file */
 
3238
                                        fil_load_single_table_tablespace(
 
3239
                                                dbinfo.name, fileinfo.name);
 
3240
                                }
 
3241
next_file_item:
 
3242
                                ret = fil_file_readdir_next_file(&err,
 
3243
                                                                 dbpath, dbdir,
 
3244
                                                                 &fileinfo);
 
3245
                        }
 
3246
 
 
3247
                        if (0 != os_file_closedir(dbdir)) {
 
3248
                                fputs("InnoDB: Warning: could not"
 
3249
                                      " close database directory ", stderr);
 
3250
                                ut_print_filename(stderr, dbpath);
 
3251
                                putc('\n', stderr);
 
3252
 
 
3253
                                err = DB_ERROR;
 
3254
                        }
 
3255
                }
 
3256
 
 
3257
next_datadir_item:
 
3258
                ret = fil_file_readdir_next_file(&err,
 
3259
                                                 fil_path_to_mysql_datadir,
 
3260
                                                 dir, &dbinfo);
 
3261
        }
 
3262
 
 
3263
        mem_free(dbpath);
 
3264
 
 
3265
        if (0 != os_file_closedir(dir)) {
 
3266
                fprintf(stderr,
 
3267
                        "InnoDB: Error: could not close MySQL datadir\n");
 
3268
 
 
3269
                return(DB_ERROR);
 
3270
        }
 
3271
 
 
3272
        return(err);
 
3273
}
 
3274
 
 
3275
/************************************************************************
 
3276
If we need crash recovery, and we have called
 
3277
fil_load_single_table_tablespaces() and dict_load_single_table_tablespaces(),
 
3278
we can call this function to print an error message of orphaned .ibd files
 
3279
for which there is not a data dictionary entry with a matching table name
 
3280
and space id. */
 
3281
 
 
3282
void
 
3283
fil_print_orphaned_tablespaces(void)
 
3284
/*================================*/
 
3285
{
 
3286
        fil_system_t*   system          = fil_system;
 
3287
        fil_space_t*    space;
 
3288
 
 
3289
        mutex_enter(&(system->mutex));
 
3290
 
 
3291
        space = UT_LIST_GET_FIRST(system->space_list);
 
3292
 
 
3293
        while (space) {
 
3294
                if (space->purpose == FIL_TABLESPACE && space->id != 0
 
3295
                    && !space->mark) {
 
3296
                        fputs("InnoDB: Warning: tablespace ", stderr);
 
3297
                        ut_print_filename(stderr, space->name);
 
3298
                        fprintf(stderr, " of id %lu has no matching table in\n"
 
3299
                                "InnoDB: the InnoDB data dictionary.\n",
 
3300
                                (ulong) space->id);
 
3301
                }
 
3302
 
 
3303
                space = UT_LIST_GET_NEXT(space_list, space);
 
3304
        }
 
3305
 
 
3306
        mutex_exit(&(system->mutex));
 
3307
}
 
3308
 
 
3309
/***********************************************************************
 
3310
Returns TRUE if a single-table tablespace does not exist in the memory cache,
 
3311
or is being deleted there. */
 
3312
 
 
3313
ibool
 
3314
fil_tablespace_deleted_or_being_deleted_in_mem(
 
3315
/*===========================================*/
 
3316
                                /* out: TRUE if does not exist or is being\
 
3317
                                deleted */
 
3318
        ulint           id,     /* in: space id */
 
3319
        ib_longlong     version)/* in: tablespace_version should be this; if
 
3320
                                you pass -1 as the value of this, then this
 
3321
                                parameter is ignored */
 
3322
{
 
3323
        fil_system_t*   system  = fil_system;
 
3324
        fil_space_t*    space;
 
3325
 
 
3326
        ut_ad(system);
 
3327
 
 
3328
        mutex_enter(&(system->mutex));
 
3329
 
 
3330
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
 
3331
 
 
3332
        if (space == NULL || space->is_being_deleted) {
 
3333
                mutex_exit(&(system->mutex));
 
3334
 
 
3335
                return(TRUE);
 
3336
        }
 
3337
 
 
3338
        if (version != ((ib_longlong)-1)
 
3339
            && space->tablespace_version != version) {
 
3340
                mutex_exit(&(system->mutex));
 
3341
 
 
3342
                return(TRUE);
 
3343
        }
 
3344
 
 
3345
        mutex_exit(&(system->mutex));
 
3346
 
 
3347
        return(FALSE);
 
3348
}
 
3349
 
 
3350
/***********************************************************************
 
3351
Returns TRUE if a single-table tablespace exists in the memory cache. */
 
3352
 
 
3353
ibool
 
3354
fil_tablespace_exists_in_mem(
 
3355
/*=========================*/
 
3356
                        /* out: TRUE if exists */
 
3357
        ulint   id)     /* in: space id */
 
3358
{
 
3359
        fil_system_t*   system          = fil_system;
 
3360
        fil_space_t*    space;
 
3361
 
 
3362
        ut_ad(system);
 
3363
 
 
3364
        mutex_enter(&(system->mutex));
 
3365
 
 
3366
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
 
3367
 
 
3368
        if (space == NULL) {
 
3369
                mutex_exit(&(system->mutex));
 
3370
 
 
3371
                return(FALSE);
 
3372
        }
 
3373
 
 
3374
        mutex_exit(&(system->mutex));
 
3375
 
 
3376
        return(TRUE);
 
3377
}
 
3378
 
 
3379
/***********************************************************************
 
3380
Returns TRUE if a matching tablespace exists in the InnoDB tablespace memory
 
3381
cache. Note that if we have not done a crash recovery at the database startup,
 
3382
there may be many tablespaces which are not yet in the memory cache. */
 
3383
 
 
3384
ibool
 
3385
fil_space_for_table_exists_in_mem(
 
3386
/*==============================*/
 
3387
                                        /* out: TRUE if a matching tablespace
 
3388
                                        exists in the memory cache */
 
3389
        ulint           id,             /* in: space id */
 
3390
        const char*     name,           /* in: table name in the standard
 
3391
                                        'databasename/tablename' format or
 
3392
                                        the dir path to a temp table */
 
3393
        ibool           is_temp,        /* in: TRUE if created with CREATE
 
3394
                                        TEMPORARY TABLE */
 
3395
        ibool           mark_space,     /* in: in crash recovery, at database
 
3396
                                        startup we mark all spaces which have
 
3397
                                        an associated table in the InnoDB
 
3398
                                        data dictionary, so that
 
3399
                                        we can print a warning about orphaned
 
3400
                                        tablespaces */
 
3401
        ibool           print_error_if_does_not_exist)
 
3402
                                        /* in: print detailed error
 
3403
                                        information to the .err log if a
 
3404
                                        matching tablespace is not found from
 
3405
                                        memory */
 
3406
{
 
3407
        fil_system_t*   system          = fil_system;
 
3408
        fil_space_t*    namespace;
 
3409
        fil_space_t*    space;
 
3410
        char*           path;
 
3411
 
 
3412
        ut_ad(system);
 
3413
 
 
3414
        mutex_enter(&(system->mutex));
 
3415
 
 
3416
        path = fil_make_ibd_name(name, is_temp);
 
3417
 
 
3418
        /* Look if there is a space with the same id */
 
3419
 
 
3420
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
 
3421
 
 
3422
        /* Look if there is a space with the same name; the name is the
 
3423
        directory path from the datadir to the file */
 
3424
 
 
3425
        HASH_SEARCH(name_hash, system->name_hash,
 
3426
                    ut_fold_string(path), namespace,
 
3427
                    0 == strcmp(namespace->name, path));
 
3428
        if (space && space == namespace) {
 
3429
                /* Found */
 
3430
 
 
3431
                if (mark_space) {
 
3432
                        space->mark = TRUE;
 
3433
                }
 
3434
 
 
3435
                mem_free(path);
 
3436
                mutex_exit(&(system->mutex));
 
3437
 
 
3438
                return(TRUE);
 
3439
        }
 
3440
 
 
3441
        if (!print_error_if_does_not_exist) {
 
3442
 
 
3443
                mem_free(path);
 
3444
                mutex_exit(&(system->mutex));
 
3445
 
 
3446
                return(FALSE);
 
3447
        }
 
3448
 
 
3449
        if (space == NULL) {
 
3450
                if (namespace == NULL) {
 
3451
                        ut_print_timestamp(stderr);
 
3452
                        fputs("  InnoDB: Error: table ", stderr);
 
3453
                        ut_print_filename(stderr, name);
 
3454
                        fprintf(stderr, "\n"
 
3455
                                "InnoDB: in InnoDB data dictionary"
 
3456
                                " has tablespace id %lu,\n"
 
3457
                                "InnoDB: but tablespace with that id"
 
3458
                                " or name does not exist. Have\n"
 
3459
                                "InnoDB: you deleted or moved .ibd files?\n"
 
3460
                                "InnoDB: This may also be a table created with"
 
3461
                                " CREATE TEMPORARY TABLE\n"
 
3462
                                "InnoDB: whose .ibd and .frm files"
 
3463
                                " MySQL automatically removed, but the\n"
 
3464
                                "InnoDB: table still exists in the"
 
3465
                                " InnoDB internal data dictionary.\n",
 
3466
                                (ulong) id);
 
3467
                } else {
 
3468
                        ut_print_timestamp(stderr);
 
3469
                        fputs("  InnoDB: Error: table ", stderr);
 
3470
                        ut_print_filename(stderr, name);
 
3471
                        fprintf(stderr, "\n"
 
3472
                                "InnoDB: in InnoDB data dictionary has"
 
3473
                                " tablespace id %lu,\n"
 
3474
                                "InnoDB: but a tablespace with that id"
 
3475
                                " does not exist. There is\n"
 
3476
                                "InnoDB: a tablespace of name %s and id %lu,"
 
3477
                                " though. Have\n"
 
3478
                                "InnoDB: you deleted or moved .ibd files?\n",
 
3479
                                (ulong) id, namespace->name,
 
3480
                                (ulong) namespace->id);
 
3481
                }
 
3482
error_exit:
 
3483
                fputs("InnoDB: Please refer to\n"
 
3484
                      "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
 
3485
                      "innodb-troubleshooting-datadict.html\n"
 
3486
                      "InnoDB: for how to resolve the issue.\n", stderr);
 
3487
 
 
3488
                mem_free(path);
 
3489
                mutex_exit(&(system->mutex));
 
3490
 
 
3491
                return(FALSE);
 
3492
        }
 
3493
 
 
3494
        if (0 != strcmp(space->name, path)) {
 
3495
                ut_print_timestamp(stderr);
 
3496
                fputs("  InnoDB: Error: table ", stderr);
 
3497
                ut_print_filename(stderr, name);
 
3498
                fprintf(stderr, "\n"
 
3499
                        "InnoDB: in InnoDB data dictionary has"
 
3500
                        " tablespace id %lu,\n"
 
3501
                        "InnoDB: but the tablespace with that id"
 
3502
                        " has name %s.\n"
 
3503
                        "InnoDB: Have you deleted or moved .ibd files?\n",
 
3504
                        (ulong) id, space->name);
 
3505
 
 
3506
                if (namespace != NULL) {
 
3507
                        fputs("InnoDB: There is a tablespace"
 
3508
                              " with the right name\n"
 
3509
                              "InnoDB: ", stderr);
 
3510
                        ut_print_filename(stderr, namespace->name);
 
3511
                        fprintf(stderr, ", but its id is %lu.\n",
 
3512
                                (ulong) namespace->id);
 
3513
                }
 
3514
 
 
3515
                goto error_exit;
 
3516
        }
 
3517
 
 
3518
        mem_free(path);
 
3519
        mutex_exit(&(system->mutex));
 
3520
 
 
3521
        return(FALSE);
 
3522
}
 
3523
 
 
3524
/***********************************************************************
 
3525
Checks if a single-table tablespace for a given table name exists in the
 
3526
tablespace memory cache. */
 
3527
static
 
3528
ulint
 
3529
fil_get_space_id_for_table(
 
3530
/*=======================*/
 
3531
                                /* out: space id, ULINT_UNDEFINED if not
 
3532
                                found */
 
3533
        const char*     name)   /* in: table name in the standard
 
3534
                                'databasename/tablename' format */
 
3535
{
 
3536
        fil_system_t*   system          = fil_system;
 
3537
        fil_space_t*    namespace;
 
3538
        ulint           id              = ULINT_UNDEFINED;
 
3539
        char*           path;
 
3540
 
 
3541
        ut_ad(system);
 
3542
 
 
3543
        mutex_enter(&(system->mutex));
 
3544
 
 
3545
        path = fil_make_ibd_name(name, FALSE);
 
3546
 
 
3547
        /* Look if there is a space with the same name; the name is the
 
3548
        directory path to the file */
 
3549
 
 
3550
        HASH_SEARCH(name_hash, system->name_hash,
 
3551
                    ut_fold_string(path), namespace,
 
3552
                    0 == strcmp(namespace->name, path));
 
3553
        if (namespace) {
 
3554
                id = namespace->id;
 
3555
        }
 
3556
 
 
3557
        mem_free(path);
 
3558
 
 
3559
        mutex_exit(&(system->mutex));
 
3560
 
 
3561
        return(id);
 
3562
}
 
3563
 
 
3564
/**************************************************************************
 
3565
Tries to extend a data file so that it would accommodate the number of pages
 
3566
given. The tablespace must be cached in the memory cache. If the space is big
 
3567
enough already, does nothing. */
 
3568
 
 
3569
ibool
 
3570
fil_extend_space_to_desired_size(
 
3571
/*=============================*/
 
3572
                                /* out: TRUE if success */
 
3573
        ulint*  actual_size,    /* out: size of the space after extension;
 
3574
                                if we ran out of disk space this may be lower
 
3575
                                than the desired size */
 
3576
        ulint   space_id,       /* in: space id */
 
3577
        ulint   size_after_extend)/* in: desired size in pages after the
 
3578
                                extension; if the current space size is bigger
 
3579
                                than this already, the function does nothing */
 
3580
{
 
3581
        fil_system_t*   system          = fil_system;
 
3582
        fil_node_t*     node;
 
3583
        fil_space_t*    space;
 
3584
        byte*           buf2;
 
3585
        byte*           buf;
 
3586
        ulint           buf_size;
 
3587
        ulint           start_page_no;
 
3588
        ulint           file_start_page_no;
 
3589
        ulint           offset_high;
 
3590
        ulint           offset_low;
 
3591
        ibool           success         = TRUE;
 
3592
 
 
3593
        fil_mutex_enter_and_prepare_for_io(space_id);
 
3594
 
 
3595
        HASH_SEARCH(hash, system->spaces, space_id, space,
 
3596
                    space->id == space_id);
 
3597
        ut_a(space);
 
3598
 
 
3599
        if (space->size >= size_after_extend) {
 
3600
                /* Space already big enough */
 
3601
 
 
3602
                *actual_size = space->size;
 
3603
 
 
3604
                mutex_exit(&(system->mutex));
 
3605
 
 
3606
                return(TRUE);
 
3607
        }
 
3608
 
 
3609
        node = UT_LIST_GET_LAST(space->chain);
 
3610
 
 
3611
        fil_node_prepare_for_io(node, system, space);
 
3612
 
 
3613
        start_page_no = space->size;
 
3614
        file_start_page_no = space->size - node->size;
 
3615
 
 
3616
        /* Extend at most 64 pages at a time */
 
3617
        buf_size = ut_min(64, size_after_extend - start_page_no)
 
3618
                * UNIV_PAGE_SIZE;
 
3619
        buf2 = mem_alloc(buf_size + UNIV_PAGE_SIZE);
 
3620
        buf = ut_align(buf2, UNIV_PAGE_SIZE);
 
3621
 
 
3622
        memset(buf, 0, buf_size);
 
3623
 
 
3624
        while (start_page_no < size_after_extend) {
 
3625
                ulint   n_pages = ut_min(buf_size / UNIV_PAGE_SIZE,
 
3626
                                         size_after_extend - start_page_no);
 
3627
 
 
3628
                offset_high = (start_page_no - file_start_page_no)
 
3629
                        / (4096 * ((1024 * 1024) / UNIV_PAGE_SIZE));
 
3630
                offset_low  = ((start_page_no - file_start_page_no)
 
3631
                               % (4096 * ((1024 * 1024) / UNIV_PAGE_SIZE)))
 
3632
                        * UNIV_PAGE_SIZE;
 
3633
#ifdef UNIV_HOTBACKUP
 
3634
                success = os_file_write(node->name, node->handle, buf,
 
3635
                                        offset_low, offset_high,
 
3636
                                        UNIV_PAGE_SIZE * n_pages);
 
3637
#else
 
3638
                success = os_aio(OS_FILE_WRITE, OS_AIO_SYNC,
 
3639
                                 node->name, node->handle, buf,
 
3640
                                 offset_low, offset_high,
 
3641
                                 UNIV_PAGE_SIZE * n_pages,
 
3642
                                 NULL, NULL);
 
3643
#endif
 
3644
                if (success) {
 
3645
                        node->size += n_pages;
 
3646
                        space->size += n_pages;
 
3647
 
 
3648
                        os_has_said_disk_full = FALSE;
 
3649
                } else {
 
3650
                        /* Let us measure the size of the file to determine
 
3651
                        how much we were able to extend it */
 
3652
 
 
3653
                        n_pages = ((ulint)
 
3654
                                   (os_file_get_size_as_iblonglong
 
3655
                                    (node->handle)
 
3656
                                    / UNIV_PAGE_SIZE)) - node->size;
 
3657
 
 
3658
                        node->size += n_pages;
 
3659
                        space->size += n_pages;
 
3660
 
 
3661
                        break;
 
3662
                }
 
3663
 
 
3664
                start_page_no += n_pages;
 
3665
        }
 
3666
 
 
3667
        mem_free(buf2);
 
3668
 
 
3669
        fil_node_complete_io(node, system, OS_FILE_WRITE);
 
3670
 
 
3671
        *actual_size = space->size;
 
3672
 
 
3673
#ifndef UNIV_HOTBACKUP
 
3674
        if (space_id == 0) {
 
3675
                ulint pages_per_mb = (1024 * 1024) / UNIV_PAGE_SIZE;
 
3676
 
 
3677
                /* Keep the last data file size info up to date, rounded to
 
3678
                full megabytes */
 
3679
 
 
3680
                srv_data_file_sizes[srv_n_data_files - 1]
 
3681
                        = (node->size / pages_per_mb) * pages_per_mb;
 
3682
        }
 
3683
#endif /* !UNIV_HOTBACKUP */
 
3684
 
 
3685
        /*
 
3686
        printf("Extended %s to %lu, actual size %lu pages\n", space->name,
 
3687
        size_after_extend, *actual_size); */
 
3688
        mutex_exit(&(system->mutex));
 
3689
 
 
3690
        fil_flush(space_id);
 
3691
 
 
3692
        return(success);
 
3693
}
 
3694
 
 
3695
#ifdef UNIV_HOTBACKUP
 
3696
/************************************************************************
 
3697
Extends all tablespaces to the size stored in the space header. During the
 
3698
ibbackup --apply-log phase we extended the spaces on-demand so that log records
 
3699
could be applied, but that may have left spaces still too small compared to
 
3700
the size stored in the space header. */
 
3701
 
 
3702
void
 
3703
fil_extend_tablespaces_to_stored_len(void)
 
3704
/*======================================*/
 
3705
{
 
3706
        fil_system_t*   system          = fil_system;
 
3707
        fil_space_t*    space;
 
3708
        byte*           buf;
 
3709
        ulint           actual_size;
 
3710
        ulint           size_in_header;
 
3711
        ulint           error;
 
3712
        ibool           success;
 
3713
 
 
3714
        buf = mem_alloc(UNIV_PAGE_SIZE);
 
3715
 
 
3716
        mutex_enter(&(system->mutex));
 
3717
 
 
3718
        space = UT_LIST_GET_FIRST(system->space_list);
 
3719
 
 
3720
        while (space) {
 
3721
                ut_a(space->purpose == FIL_TABLESPACE);
 
3722
 
 
3723
                mutex_exit(&(system->mutex)); /* no need to protect with a
 
3724
                                              mutex, because this is a
 
3725
                                              single-threaded operation */
 
3726
                error = fil_read(TRUE, space->id, 0, 0, UNIV_PAGE_SIZE, buf,
 
3727
                                 NULL);
 
3728
                ut_a(error == DB_SUCCESS);
 
3729
 
 
3730
                size_in_header = fsp_get_size_low(buf);
 
3731
 
 
3732
                success = fil_extend_space_to_desired_size(
 
3733
                        &actual_size, space->id, size_in_header);
 
3734
                if (!success) {
 
3735
                        fprintf(stderr,
 
3736
                                "InnoDB: Error: could not extend the"
 
3737
                                " tablespace of %s\n"
 
3738
                                "InnoDB: to the size stored in header,"
 
3739
                                " %lu pages;\n"
 
3740
                                "InnoDB: size after extension %lu pages\n"
 
3741
                                "InnoDB: Check that you have free disk space"
 
3742
                                " and retry!\n",
 
3743
                                space->name, size_in_header, actual_size);
 
3744
                        exit(1);
 
3745
                }
 
3746
 
 
3747
                mutex_enter(&(system->mutex));
 
3748
 
 
3749
                space = UT_LIST_GET_NEXT(space_list, space);
 
3750
        }
 
3751
 
 
3752
        mutex_exit(&(system->mutex));
 
3753
 
 
3754
        mem_free(buf);
 
3755
}
 
3756
#endif
 
3757
 
 
3758
/*========== RESERVE FREE EXTENTS (for a B-tree split, for example) ===*/
 
3759
 
 
3760
/***********************************************************************
 
3761
Tries to reserve free extents in a file space. */
 
3762
 
 
3763
ibool
 
3764
fil_space_reserve_free_extents(
 
3765
/*===========================*/
 
3766
                                /* out: TRUE if succeed */
 
3767
        ulint   id,             /* in: space id */
 
3768
        ulint   n_free_now,     /* in: number of free extents now */
 
3769
        ulint   n_to_reserve)   /* in: how many one wants to reserve */
 
3770
{
 
3771
        fil_system_t*   system          = fil_system;
 
3772
        fil_space_t*    space;
 
3773
        ibool           success;
 
3774
 
 
3775
        ut_ad(system);
 
3776
 
 
3777
        mutex_enter(&(system->mutex));
 
3778
 
 
3779
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
 
3780
 
 
3781
        ut_a(space);
 
3782
 
 
3783
        if (space->n_reserved_extents + n_to_reserve > n_free_now) {
 
3784
                success = FALSE;
 
3785
        } else {
 
3786
                space->n_reserved_extents += n_to_reserve;
 
3787
                success = TRUE;
 
3788
        }
 
3789
 
 
3790
        mutex_exit(&(system->mutex));
 
3791
 
 
3792
        return(success);
 
3793
}
 
3794
 
 
3795
/***********************************************************************
 
3796
Releases free extents in a file space. */
 
3797
 
 
3798
void
 
3799
fil_space_release_free_extents(
 
3800
/*===========================*/
 
3801
        ulint   id,             /* in: space id */
 
3802
        ulint   n_reserved)     /* in: how many one reserved */
 
3803
{
 
3804
        fil_system_t*   system          = fil_system;
 
3805
        fil_space_t*    space;
 
3806
 
 
3807
        ut_ad(system);
 
3808
 
 
3809
        mutex_enter(&(system->mutex));
 
3810
 
 
3811
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
 
3812
 
 
3813
        ut_a(space);
 
3814
        ut_a(space->n_reserved_extents >= n_reserved);
 
3815
 
 
3816
        space->n_reserved_extents -= n_reserved;
 
3817
 
 
3818
        mutex_exit(&(system->mutex));
 
3819
}
 
3820
 
 
3821
/***********************************************************************
 
3822
Gets the number of reserved extents. If the database is silent, this number
 
3823
should be zero. */
 
3824
 
 
3825
ulint
 
3826
fil_space_get_n_reserved_extents(
 
3827
/*=============================*/
 
3828
        ulint   id)             /* in: space id */
 
3829
{
 
3830
        fil_system_t*   system          = fil_system;
 
3831
        fil_space_t*    space;
 
3832
        ulint           n;
 
3833
 
 
3834
        ut_ad(system);
 
3835
 
 
3836
        mutex_enter(&(system->mutex));
 
3837
 
 
3838
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
 
3839
 
 
3840
        ut_a(space);
 
3841
 
 
3842
        n = space->n_reserved_extents;
 
3843
 
 
3844
        mutex_exit(&(system->mutex));
 
3845
 
 
3846
        return(n);
 
3847
}
 
3848
 
 
3849
/*============================ FILE I/O ================================*/
 
3850
 
 
3851
/************************************************************************
 
3852
NOTE: you must call fil_mutex_enter_and_prepare_for_io() first!
 
3853
 
 
3854
Prepares a file node for i/o. Opens the file if it is closed. Updates the
 
3855
pending i/o's field in the node and the system appropriately. Takes the node
 
3856
off the LRU list if it is in the LRU list. The caller must hold the fil_sys
 
3857
mutex. */
 
3858
static
 
3859
void
 
3860
fil_node_prepare_for_io(
 
3861
/*====================*/
 
3862
        fil_node_t*     node,   /* in: file node */
 
3863
        fil_system_t*   system, /* in: tablespace memory cache */
 
3864
        fil_space_t*    space)  /* in: space */
 
3865
{
 
3866
        ut_ad(node && system && space);
 
3867
        ut_ad(mutex_own(&(system->mutex)));
 
3868
 
 
3869
        if (system->n_open > system->max_n_open + 5) {
 
3870
                ut_print_timestamp(stderr);
 
3871
                fprintf(stderr,
 
3872
                        "  InnoDB: Warning: open files %lu"
 
3873
                        " exceeds the limit %lu\n",
 
3874
                        (ulong) system->n_open,
 
3875
                        (ulong) system->max_n_open);
 
3876
        }
 
3877
 
 
3878
        if (node->open == FALSE) {
 
3879
                /* File is closed: open it */
 
3880
                ut_a(node->n_pending == 0);
 
3881
 
 
3882
                fil_node_open_file(node, system, space);
 
3883
        }
 
3884
 
 
3885
        if (node->n_pending == 0 && space->purpose == FIL_TABLESPACE
 
3886
            && space->id != 0) {
 
3887
                /* The node is in the LRU list, remove it */
 
3888
 
 
3889
                ut_a(UT_LIST_GET_LEN(system->LRU) > 0);
 
3890
 
 
3891
                UT_LIST_REMOVE(LRU, system->LRU, node);
 
3892
        }
 
3893
 
 
3894
        node->n_pending++;
 
3895
}
 
3896
 
 
3897
/************************************************************************
 
3898
Updates the data structures when an i/o operation finishes. Updates the
 
3899
pending i/o's field in the node appropriately. */
 
3900
static
 
3901
void
 
3902
fil_node_complete_io(
 
3903
/*=================*/
 
3904
        fil_node_t*     node,   /* in: file node */
 
3905
        fil_system_t*   system, /* in: tablespace memory cache */
 
3906
        ulint           type)   /* in: OS_FILE_WRITE or OS_FILE_READ; marks
 
3907
                                the node as modified if
 
3908
                                type == OS_FILE_WRITE */
 
3909
{
 
3910
        ut_ad(node);
 
3911
        ut_ad(system);
 
3912
        ut_ad(mutex_own(&(system->mutex)));
 
3913
 
 
3914
        ut_a(node->n_pending > 0);
 
3915
 
 
3916
        node->n_pending--;
 
3917
 
 
3918
        if (type == OS_FILE_WRITE) {
 
3919
                system->modification_counter++;
 
3920
                node->modification_counter = system->modification_counter;
 
3921
 
 
3922
                if (!node->space->is_in_unflushed_spaces) {
 
3923
 
 
3924
                        node->space->is_in_unflushed_spaces = TRUE;
 
3925
                        UT_LIST_ADD_FIRST(unflushed_spaces,
 
3926
                                          system->unflushed_spaces,
 
3927
                                          node->space);
 
3928
                }
 
3929
        }
 
3930
 
 
3931
        if (node->n_pending == 0 && node->space->purpose == FIL_TABLESPACE
 
3932
            && node->space->id != 0) {
 
3933
                /* The node must be put back to the LRU list */
 
3934
                UT_LIST_ADD_FIRST(LRU, system->LRU, node);
 
3935
        }
 
3936
}
 
3937
 
 
3938
/************************************************************************
 
3939
Report information about an invalid page access. */
 
3940
static
 
3941
void
 
3942
fil_report_invalid_page_access(
 
3943
/*===========================*/
 
3944
        ulint           block_offset,   /* in: block offset */
 
3945
        ulint           space_id,       /* in: space id */
 
3946
        const char*     space_name,     /* in: space name */
 
3947
        ulint           byte_offset,    /* in: byte offset */
 
3948
        ulint           len,            /* in: I/O length */
 
3949
        ulint           type)           /* in: I/O type */
 
3950
{
 
3951
        fprintf(stderr,
 
3952
                "InnoDB: Error: trying to access page number %lu"
 
3953
                " in space %lu,\n"
 
3954
                "InnoDB: space name %s,\n"
 
3955
                "InnoDB: which is outside the tablespace bounds.\n"
 
3956
                "InnoDB: Byte offset %lu, len %lu, i/o type %lu.\n"
 
3957
                "InnoDB: If you get this error at mysqld startup,"
 
3958
                " please check that\n"
 
3959
                "InnoDB: your my.cnf matches the ibdata files"
 
3960
                " that you have in the\n"
 
3961
                "InnoDB: MySQL server.\n",
 
3962
                (ulong) block_offset, (ulong) space_id, space_name,
 
3963
                (ulong) byte_offset, (ulong) len, (ulong) type);
 
3964
}
 
3965
 
 
3966
/************************************************************************
 
3967
Reads or writes data. This operation is asynchronous (aio). */
 
3968
 
 
3969
ulint
 
3970
fil_io(
 
3971
/*===*/
 
3972
                                /* out: DB_SUCCESS, or DB_TABLESPACE_DELETED
 
3973
                                if we are trying to do i/o on a tablespace
 
3974
                                which does not exist */
 
3975
        ulint   type,           /* in: OS_FILE_READ or OS_FILE_WRITE,
 
3976
                                ORed to OS_FILE_LOG, if a log i/o
 
3977
                                and ORed to OS_AIO_SIMULATED_WAKE_LATER
 
3978
                                if simulated aio and we want to post a
 
3979
                                batch of i/os; NOTE that a simulated batch
 
3980
                                may introduce hidden chances of deadlocks,
 
3981
                                because i/os are not actually handled until
 
3982
                                all have been posted: use with great
 
3983
                                caution! */
 
3984
        ibool   sync,           /* in: TRUE if synchronous aio is desired */
 
3985
        ulint   space_id,       /* in: space id */
 
3986
        ulint   block_offset,   /* in: offset in number of blocks */
 
3987
        ulint   byte_offset,    /* in: remainder of offset in bytes; in
 
3988
                                aio this must be divisible by the OS block
 
3989
                                size */
 
3990
        ulint   len,            /* in: how many bytes to read or write; this
 
3991
                                must not cross a file boundary; in aio this
 
3992
                                must be a block size multiple */
 
3993
        void*   buf,            /* in/out: buffer where to store read data
 
3994
                                or from where to write; in aio this must be
 
3995
                                appropriately aligned */
 
3996
        void*   message)        /* in: message for aio handler if non-sync
 
3997
                                aio used, else ignored */
 
3998
{
 
3999
        fil_system_t*   system          = fil_system;
 
4000
        ulint           mode;
 
4001
        fil_space_t*    space;
 
4002
        fil_node_t*     node;
 
4003
        ulint           offset_high;
 
4004
        ulint           offset_low;
 
4005
        ibool           ret;
 
4006
        ulint           is_log;
 
4007
        ulint           wake_later;
 
4008
 
 
4009
        is_log = type & OS_FILE_LOG;
 
4010
        type = type & ~OS_FILE_LOG;
 
4011
 
 
4012
        wake_later = type & OS_AIO_SIMULATED_WAKE_LATER;
 
4013
        type = type & ~OS_AIO_SIMULATED_WAKE_LATER;
 
4014
 
 
4015
        ut_ad(byte_offset < UNIV_PAGE_SIZE);
 
4016
        ut_ad(buf);
 
4017
        ut_ad(len > 0);
 
4018
        ut_a((1 << UNIV_PAGE_SIZE_SHIFT) == UNIV_PAGE_SIZE);
 
4019
        ut_ad(fil_validate());
 
4020
#ifndef UNIV_LOG_DEBUG
 
4021
        /* ibuf bitmap pages must be read in the sync aio mode: */
 
4022
        ut_ad(recv_no_ibuf_operations || (type == OS_FILE_WRITE)
 
4023
              || !ibuf_bitmap_page(block_offset) || sync || is_log);
 
4024
#ifdef UNIV_SYNC_DEBUG
 
4025
        ut_ad(!ibuf_inside() || is_log || (type == OS_FILE_WRITE)
 
4026
              || ibuf_page(space_id, block_offset));
 
4027
#endif
 
4028
#endif
 
4029
        if (sync) {
 
4030
                mode = OS_AIO_SYNC;
 
4031
        } else if (type == OS_FILE_READ && !is_log
 
4032
                   && ibuf_page(space_id, block_offset)) {
 
4033
                mode = OS_AIO_IBUF;
 
4034
        } else if (is_log) {
 
4035
                mode = OS_AIO_LOG;
 
4036
        } else {
 
4037
                mode = OS_AIO_NORMAL;
 
4038
        }
 
4039
 
 
4040
        if (type == OS_FILE_READ) {
 
4041
                srv_data_read+= len;
 
4042
        } else if (type == OS_FILE_WRITE) {
 
4043
                srv_data_written+= len;
 
4044
        }
 
4045
 
 
4046
        /* Reserve the fil_system mutex and make sure that we can open at
 
4047
        least one file while holding it, if the file is not already open */
 
4048
 
 
4049
        fil_mutex_enter_and_prepare_for_io(space_id);
 
4050
 
 
4051
        HASH_SEARCH(hash, system->spaces, space_id, space,
 
4052
                    space->id == space_id);
 
4053
        if (!space) {
 
4054
                mutex_exit(&(system->mutex));
 
4055
 
 
4056
                ut_print_timestamp(stderr);
 
4057
                fprintf(stderr,
 
4058
                        "  InnoDB: Error: trying to do i/o"
 
4059
                        " to a tablespace which does not exist.\n"
 
4060
                        "InnoDB: i/o type %lu, space id %lu,"
 
4061
                        " page no. %lu, i/o length %lu bytes\n",
 
4062
                        (ulong) type, (ulong) space_id, (ulong) block_offset,
 
4063
                        (ulong) len);
 
4064
 
 
4065
                return(DB_TABLESPACE_DELETED);
 
4066
        }
 
4067
 
 
4068
        ut_ad((mode != OS_AIO_IBUF) || (space->purpose == FIL_TABLESPACE));
 
4069
 
 
4070
        node = UT_LIST_GET_FIRST(space->chain);
 
4071
 
 
4072
        for (;;) {
 
4073
                if (node == NULL) {
 
4074
                        fil_report_invalid_page_access(
 
4075
                                block_offset, space_id, space->name,
 
4076
                                byte_offset, len, type);
 
4077
 
 
4078
                        ut_error;
 
4079
                }
 
4080
 
 
4081
                if (space->id != 0 && node->size == 0) {
 
4082
                        /* We do not know the size of a single-table tablespace
 
4083
                        before we open the file */
 
4084
 
 
4085
                        break;
 
4086
                }
 
4087
 
 
4088
                if (node->size > block_offset) {
 
4089
                        /* Found! */
 
4090
                        break;
 
4091
                } else {
 
4092
                        block_offset -= node->size;
 
4093
                        node = UT_LIST_GET_NEXT(chain, node);
 
4094
                }
 
4095
        }
 
4096
 
 
4097
        /* Open file if closed */
 
4098
        fil_node_prepare_for_io(node, system, space);
 
4099
 
 
4100
        /* Check that at least the start offset is within the bounds of a
 
4101
        single-table tablespace */
 
4102
        if (space->purpose == FIL_TABLESPACE && space->id != 0
 
4103
            && node->size <= block_offset) {
 
4104
 
 
4105
                fil_report_invalid_page_access(
 
4106
                        block_offset, space_id, space->name, byte_offset,
 
4107
                        len, type);
 
4108
 
 
4109
                ut_error;
 
4110
        }
 
4111
 
 
4112
        /* Now we have made the changes in the data structures of system */
 
4113
        mutex_exit(&(system->mutex));
 
4114
 
 
4115
        /* Calculate the low 32 bits and the high 32 bits of the file offset */
 
4116
 
 
4117
        offset_high = (block_offset >> (32 - UNIV_PAGE_SIZE_SHIFT));
 
4118
        offset_low  = ((block_offset << UNIV_PAGE_SIZE_SHIFT) & 0xFFFFFFFFUL)
 
4119
                + byte_offset;
 
4120
 
 
4121
        ut_a(node->size - block_offset
 
4122
             >= (byte_offset + len + (UNIV_PAGE_SIZE - 1)) / UNIV_PAGE_SIZE);
 
4123
 
 
4124
        /* Do aio */
 
4125
 
 
4126
        ut_a(byte_offset % OS_FILE_LOG_BLOCK_SIZE == 0);
 
4127
        ut_a((len % OS_FILE_LOG_BLOCK_SIZE) == 0);
 
4128
 
 
4129
#ifdef UNIV_HOTBACKUP
 
4130
        /* In ibbackup do normal i/o, not aio */
 
4131
        if (type == OS_FILE_READ) {
 
4132
                ret = os_file_read(node->handle, buf, offset_low, offset_high,
 
4133
                                   len);
 
4134
        } else {
 
4135
                ret = os_file_write(node->name, node->handle, buf,
 
4136
                                    offset_low, offset_high, len);
 
4137
        }
 
4138
#else
 
4139
        /* Queue the aio request */
 
4140
        ret = os_aio(type, mode | wake_later, node->name, node->handle, buf,
 
4141
                     offset_low, offset_high, len, node, message);
 
4142
#endif
 
4143
        ut_a(ret);
 
4144
 
 
4145
        if (mode == OS_AIO_SYNC) {
 
4146
                /* The i/o operation is already completed when we return from
 
4147
                os_aio: */
 
4148
 
 
4149
                mutex_enter(&(system->mutex));
 
4150
 
 
4151
                fil_node_complete_io(node, system, type);
 
4152
 
 
4153
                mutex_exit(&(system->mutex));
 
4154
 
 
4155
                ut_ad(fil_validate());
 
4156
        }
 
4157
 
 
4158
        return(DB_SUCCESS);
 
4159
}
 
4160
 
 
4161
/************************************************************************
 
4162
Reads data from a space to a buffer. Remember that the possible incomplete
 
4163
blocks at the end of file are ignored: they are not taken into account when
 
4164
calculating the byte offset within a space. */
 
4165
 
 
4166
ulint
 
4167
fil_read(
 
4168
/*=====*/
 
4169
                                /* out: DB_SUCCESS, or DB_TABLESPACE_DELETED
 
4170
                                if we are trying to do i/o on a tablespace
 
4171
                                which does not exist */
 
4172
        ibool   sync,           /* in: TRUE if synchronous aio is desired */
 
4173
        ulint   space_id,       /* in: space id */
 
4174
        ulint   block_offset,   /* in: offset in number of blocks */
 
4175
        ulint   byte_offset,    /* in: remainder of offset in bytes; in aio
 
4176
                                this must be divisible by the OS block size */
 
4177
        ulint   len,            /* in: how many bytes to read; this must not
 
4178
                                cross a file boundary; in aio this must be a
 
4179
                                block size multiple */
 
4180
        void*   buf,            /* in/out: buffer where to store data read;
 
4181
                                in aio this must be appropriately aligned */
 
4182
        void*   message)        /* in: message for aio handler if non-sync
 
4183
                                aio used, else ignored */
 
4184
{
 
4185
        return(fil_io(OS_FILE_READ, sync, space_id, block_offset,
 
4186
                      byte_offset, len, buf, message));
 
4187
}
 
4188
 
 
4189
/************************************************************************
 
4190
Writes data to a space from a buffer. Remember that the possible incomplete
 
4191
blocks at the end of file are ignored: they are not taken into account when
 
4192
calculating the byte offset within a space. */
 
4193
 
 
4194
ulint
 
4195
fil_write(
 
4196
/*======*/
 
4197
                                /* out: DB_SUCCESS, or DB_TABLESPACE_DELETED
 
4198
                                if we are trying to do i/o on a tablespace
 
4199
                                which does not exist */
 
4200
        ibool   sync,           /* in: TRUE if synchronous aio is desired */
 
4201
        ulint   space_id,       /* in: space id */
 
4202
        ulint   block_offset,   /* in: offset in number of blocks */
 
4203
        ulint   byte_offset,    /* in: remainder of offset in bytes; in aio
 
4204
                                this must be divisible by the OS block size */
 
4205
        ulint   len,            /* in: how many bytes to write; this must
 
4206
                                not cross a file boundary; in aio this must
 
4207
                                be a block size multiple */
 
4208
        void*   buf,            /* in: buffer from which to write; in aio
 
4209
                                this must be appropriately aligned */
 
4210
        void*   message)        /* in: message for aio handler if non-sync
 
4211
                                aio used, else ignored */
 
4212
{
 
4213
        return(fil_io(OS_FILE_WRITE, sync, space_id, block_offset,
 
4214
                      byte_offset, len, buf, message));
 
4215
}
 
4216
 
 
4217
/**************************************************************************
 
4218
Waits for an aio operation to complete. This function is used to write the
 
4219
handler for completed requests. The aio array of pending requests is divided
 
4220
into segments (see os0file.c for more info). The thread specifies which
 
4221
segment it wants to wait for. */
 
4222
 
 
4223
void
 
4224
fil_aio_wait(
 
4225
/*=========*/
 
4226
        ulint   segment)        /* in: the number of the segment in the aio
 
4227
                                array to wait for */
 
4228
{
 
4229
        fil_system_t*   system          = fil_system;
 
4230
        ibool           ret;
 
4231
        fil_node_t*     fil_node;
 
4232
        void*           message;
 
4233
        ulint           type;
 
4234
 
 
4235
        ut_ad(fil_validate());
 
4236
 
 
4237
        if (os_aio_use_native_aio) {
 
4238
                srv_set_io_thread_op_info(segment, "native aio handle");
 
4239
#ifdef WIN_ASYNC_IO
 
4240
                ret = os_aio_windows_handle(segment, 0, &fil_node,
 
4241
                                            &message, &type);
 
4242
#elif defined(POSIX_ASYNC_IO)
 
4243
                ret = os_aio_posix_handle(segment, &fil_node, &message);
 
4244
#else
 
4245
                ret = 0; /* Eliminate compiler warning */
 
4246
                ut_error;
 
4247
#endif
 
4248
        } else {
 
4249
                srv_set_io_thread_op_info(segment, "simulated aio handle");
 
4250
 
 
4251
                ret = os_aio_simulated_handle(segment, &fil_node,
 
4252
                                              &message, &type);
 
4253
        }
 
4254
 
 
4255
        ut_a(ret);
 
4256
 
 
4257
        srv_set_io_thread_op_info(segment, "complete io for fil node");
 
4258
 
 
4259
        mutex_enter(&(system->mutex));
 
4260
 
 
4261
        fil_node_complete_io(fil_node, fil_system, type);
 
4262
 
 
4263
        mutex_exit(&(system->mutex));
 
4264
 
 
4265
        ut_ad(fil_validate());
 
4266
 
 
4267
        /* Do the i/o handling */
 
4268
        /* IMPORTANT: since i/o handling for reads will read also the insert
 
4269
        buffer in tablespace 0, you have to be very careful not to introduce
 
4270
        deadlocks in the i/o system. We keep tablespace 0 data files always
 
4271
        open, and use a special i/o thread to serve insert buffer requests. */
 
4272
 
 
4273
        if (buf_pool_is_block(message)) {
 
4274
                srv_set_io_thread_op_info(segment, "complete io for buf page");
 
4275
                buf_page_io_complete(message);
 
4276
        } else {
 
4277
                srv_set_io_thread_op_info(segment, "complete io for log");
 
4278
                log_io_complete(message);
 
4279
        }
 
4280
}
 
4281
 
 
4282
/**************************************************************************
 
4283
Flushes to disk possible writes cached by the OS. If the space does not exist
 
4284
or is being dropped, does not do anything. */
 
4285
 
 
4286
void
 
4287
fil_flush(
 
4288
/*======*/
 
4289
        ulint   space_id)       /* in: file space id (this can be a group of
 
4290
                                log files or a tablespace of the database) */
 
4291
{
 
4292
        fil_system_t*   system  = fil_system;
 
4293
        fil_space_t*    space;
 
4294
        fil_node_t*     node;
 
4295
        os_file_t       file;
 
4296
        ib_longlong     old_mod_counter;
 
4297
 
 
4298
        mutex_enter(&(system->mutex));
 
4299
 
 
4300
        HASH_SEARCH(hash, system->spaces, space_id, space,
 
4301
                    space->id == space_id);
 
4302
        if (!space || space->is_being_deleted) {
 
4303
                mutex_exit(&(system->mutex));
 
4304
 
 
4305
                return;
 
4306
        }
 
4307
 
 
4308
        space->n_pending_flushes++;     /* prevent dropping of the space while
 
4309
                                        we are flushing */
 
4310
        node = UT_LIST_GET_FIRST(space->chain);
 
4311
 
 
4312
        while (node) {
 
4313
                if (node->modification_counter > node->flush_counter) {
 
4314
                        ut_a(node->open);
 
4315
 
 
4316
                        /* We want to flush the changes at least up to
 
4317
                        old_mod_counter */
 
4318
                        old_mod_counter = node->modification_counter;
 
4319
 
 
4320
                        if (space->purpose == FIL_TABLESPACE) {
 
4321
                                fil_n_pending_tablespace_flushes++;
 
4322
                        } else {
 
4323
                                fil_n_pending_log_flushes++;
 
4324
                                fil_n_log_flushes++;
 
4325
                        }
 
4326
#ifdef __WIN__
 
4327
                        if (node->is_raw_disk) {
 
4328
 
 
4329
                                goto skip_flush;
 
4330
                        }
 
4331
#endif
 
4332
retry:
 
4333
                        if (node->n_pending_flushes > 0) {
 
4334
                                /* We want to avoid calling os_file_flush() on
 
4335
                                the file twice at the same time, because we do
 
4336
                                not know what bugs OS's may contain in file
 
4337
                                i/o; sleep for a while */
 
4338
 
 
4339
                                mutex_exit(&(system->mutex));
 
4340
 
 
4341
                                os_thread_sleep(20000);
 
4342
 
 
4343
                                mutex_enter(&(system->mutex));
 
4344
 
 
4345
                                if (node->flush_counter >= old_mod_counter) {
 
4346
 
 
4347
                                        goto skip_flush;
 
4348
                                }
 
4349
 
 
4350
                                goto retry;
 
4351
                        }
 
4352
 
 
4353
                        ut_a(node->open);
 
4354
                        file = node->handle;
 
4355
                        node->n_pending_flushes++;
 
4356
 
 
4357
                        mutex_exit(&(system->mutex));
 
4358
 
 
4359
                        /* fprintf(stderr, "Flushing to file %s\n",
 
4360
                        node->name); */
 
4361
 
 
4362
                        os_file_flush(file);
 
4363
 
 
4364
                        mutex_enter(&(system->mutex));
 
4365
 
 
4366
                        node->n_pending_flushes--;
 
4367
skip_flush:
 
4368
                        if (node->flush_counter < old_mod_counter) {
 
4369
                                node->flush_counter = old_mod_counter;
 
4370
 
 
4371
                                if (space->is_in_unflushed_spaces
 
4372
                                    && fil_space_is_flushed(space)) {
 
4373
 
 
4374
                                        space->is_in_unflushed_spaces = FALSE;
 
4375
 
 
4376
                                        UT_LIST_REMOVE(
 
4377
                                                unflushed_spaces,
 
4378
                                                system->unflushed_spaces,
 
4379
                                                space);
 
4380
                                }
 
4381
                        }
 
4382
 
 
4383
                        if (space->purpose == FIL_TABLESPACE) {
 
4384
                                fil_n_pending_tablespace_flushes--;
 
4385
                        } else {
 
4386
                                fil_n_pending_log_flushes--;
 
4387
                        }
 
4388
                }
 
4389
 
 
4390
                node = UT_LIST_GET_NEXT(chain, node);
 
4391
        }
 
4392
 
 
4393
        space->n_pending_flushes--;
 
4394
 
 
4395
        mutex_exit(&(system->mutex));
 
4396
}
 
4397
 
 
4398
/**************************************************************************
 
4399
Flushes to disk the writes in file spaces of the given type possibly cached by
 
4400
the OS. */
 
4401
 
 
4402
void
 
4403
fil_flush_file_spaces(
 
4404
/*==================*/
 
4405
        ulint   purpose)        /* in: FIL_TABLESPACE, FIL_LOG */
 
4406
{
 
4407
        fil_system_t*   system  = fil_system;
 
4408
        fil_space_t*    space;
 
4409
        ulint*          space_ids;
 
4410
        ulint           n_space_ids;
 
4411
        ulint           i;
 
4412
 
 
4413
        mutex_enter(&(system->mutex));
 
4414
 
 
4415
        n_space_ids = UT_LIST_GET_LEN(system->unflushed_spaces);
 
4416
        if (n_space_ids == 0) {
 
4417
 
 
4418
                mutex_exit(&system->mutex);
 
4419
                return;
 
4420
        }
 
4421
 
 
4422
        /* Assemble a list of space ids to flush.  Previously, we
 
4423
        traversed system->unflushed_spaces and called UT_LIST_GET_NEXT()
 
4424
        on a space that was just removed from the list by fil_flush().
 
4425
        Thus, the space could be dropped and the memory overwritten. */
 
4426
        space_ids = mem_alloc(n_space_ids * sizeof *space_ids);
 
4427
 
 
4428
        n_space_ids = 0;
 
4429
 
 
4430
        for (space = UT_LIST_GET_FIRST(system->unflushed_spaces);
 
4431
             space;
 
4432
             space = UT_LIST_GET_NEXT(unflushed_spaces, space)) {
 
4433
 
 
4434
                if (space->purpose == purpose && !space->is_being_deleted) {
 
4435
 
 
4436
                        space_ids[n_space_ids++] = space->id;
 
4437
                }
 
4438
        }
 
4439
 
 
4440
        mutex_exit(&system->mutex);
 
4441
 
 
4442
        /* Flush the spaces.  It will not hurt to call fil_flush() on
 
4443
        a non-existing space id. */
 
4444
        for (i = 0; i < n_space_ids; i++) {
 
4445
 
 
4446
                fil_flush(space_ids[i]);
 
4447
        }
 
4448
 
 
4449
        mem_free(space_ids);
 
4450
}
 
4451
 
 
4452
/**********************************************************************
 
4453
Checks the consistency of the tablespace cache. */
 
4454
 
 
4455
ibool
 
4456
fil_validate(void)
 
4457
/*==============*/
 
4458
                        /* out: TRUE if ok */
 
4459
{
 
4460
        fil_system_t*   system          = fil_system;
 
4461
        fil_space_t*    space;
 
4462
        fil_node_t*     fil_node;
 
4463
        ulint           n_open          = 0;
 
4464
        ulint           i;
 
4465
 
 
4466
        mutex_enter(&(system->mutex));
 
4467
 
 
4468
        /* Look for spaces in the hash table */
 
4469
 
 
4470
        for (i = 0; i < hash_get_n_cells(system->spaces); i++) {
 
4471
 
 
4472
                space = HASH_GET_FIRST(system->spaces, i);
 
4473
 
 
4474
                while (space != NULL) {
 
4475
                        UT_LIST_VALIDATE(chain, fil_node_t, space->chain);
 
4476
 
 
4477
                        fil_node = UT_LIST_GET_FIRST(space->chain);
 
4478
 
 
4479
                        while (fil_node != NULL) {
 
4480
                                if (fil_node->n_pending > 0) {
 
4481
                                        ut_a(fil_node->open);
 
4482
                                }
 
4483
 
 
4484
                                if (fil_node->open) {
 
4485
                                        n_open++;
 
4486
                                }
 
4487
                                fil_node = UT_LIST_GET_NEXT(chain, fil_node);
 
4488
                        }
 
4489
                        space = HASH_GET_NEXT(hash, space);
 
4490
                }
 
4491
        }
 
4492
 
 
4493
        ut_a(system->n_open == n_open);
 
4494
 
 
4495
        UT_LIST_VALIDATE(LRU, fil_node_t, system->LRU);
 
4496
 
 
4497
        fil_node = UT_LIST_GET_FIRST(system->LRU);
 
4498
 
 
4499
        while (fil_node != NULL) {
 
4500
                ut_a(fil_node->n_pending == 0);
 
4501
                ut_a(fil_node->open);
 
4502
                ut_a(fil_node->space->purpose == FIL_TABLESPACE);
 
4503
                ut_a(fil_node->space->id != 0);
 
4504
 
 
4505
                fil_node = UT_LIST_GET_NEXT(LRU, fil_node);
 
4506
        }
 
4507
 
 
4508
        mutex_exit(&(system->mutex));
 
4509
 
 
4510
        return(TRUE);
 
4511
}
 
4512
 
 
4513
/************************************************************************
 
4514
Returns TRUE if file address is undefined. */
 
4515
ibool
 
4516
fil_addr_is_null(
 
4517
/*=============*/
 
4518
                                /* out: TRUE if undefined */
 
4519
        fil_addr_t      addr)   /* in: address */
 
4520
{
 
4521
        if (addr.page == FIL_NULL) {
 
4522
 
 
4523
                return(TRUE);
 
4524
        }
 
4525
 
 
4526
        return(FALSE);
 
4527
}
 
4528
 
 
4529
/************************************************************************
 
4530
Accessor functions for a file page */
 
4531
 
 
4532
ulint
 
4533
fil_page_get_prev(byte* page)
 
4534
{
 
4535
        return(mach_read_from_4(page + FIL_PAGE_PREV));
 
4536
}
 
4537
 
 
4538
ulint
 
4539
fil_page_get_next(byte* page)
 
4540
{
 
4541
        return(mach_read_from_4(page + FIL_PAGE_NEXT));
 
4542
}
 
4543
 
 
4544
/*************************************************************************
 
4545
Sets the file page type. */
 
4546
 
 
4547
void
 
4548
fil_page_set_type(
 
4549
/*==============*/
 
4550
        byte*   page,   /* in: file page */
 
4551
        ulint   type)   /* in: type */
 
4552
{
 
4553
        ut_ad(page);
 
4554
 
 
4555
        mach_write_to_2(page + FIL_PAGE_TYPE, type);
 
4556
}
 
4557
 
 
4558
/*************************************************************************
 
4559
Gets the file page type. */
 
4560
 
 
4561
ulint
 
4562
fil_page_get_type(
 
4563
/*==============*/
 
4564
                        /* out: type; NOTE that if the type has not been
 
4565
                        written to page, the return value not defined */
 
4566
        byte*   page)   /* in: file page */
 
4567
{
 
4568
        ut_ad(page);
 
4569
 
 
4570
        return(mach_read_from_2(page + FIL_PAGE_TYPE));
 
4571
}