~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

Moved sql_common.h and my_time.h to libdrizzle.

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
#include "mtr0mtr.h"
27
27
#include "mtr0log.h"
28
28
#include "dict0dict.h"
29
 
#include "page0zip.h"
30
29
 
31
30
 
32
31
/*
88
87
/* When mysqld is run, the default directory "." is the mysqld datadir,
89
88
but in the MySQL Embedded Server Library and ibbackup it is not the default
90
89
directory, and we must set the base file path explicitly */
91
 
UNIV_INTERN const char* fil_path_to_mysql_datadir       = ".";
 
90
const char*     fil_path_to_mysql_datadir       = ".";
92
91
 
93
92
/* The number of fsyncs done to the log */
94
 
UNIV_INTERN ulint       fil_n_log_flushes                       = 0;
 
93
ulint   fil_n_log_flushes                       = 0;
95
94
 
96
 
UNIV_INTERN ulint       fil_n_pending_log_flushes               = 0;
97
 
UNIV_INTERN ulint       fil_n_pending_tablespace_flushes        = 0;
 
95
ulint   fil_n_pending_log_flushes               = 0;
 
96
ulint   fil_n_pending_tablespace_flushes        = 0;
98
97
 
99
98
/* Null file address */
100
 
UNIV_INTERN fil_addr_t  fil_addr_null = {FIL_NULL, 0};
 
99
fil_addr_t      fil_addr_null = {FIL_NULL, 0};
101
100
 
102
101
/* File node of a tablespace or the log data space */
103
102
struct fil_node_struct {
119
118
                                /* count of pending flushes on this file;
120
119
                                closing of the file is not allowed if
121
120
                                this is > 0 */
122
 
        ib_int64_t      modification_counter;/* when we write to the file we
 
121
        ib_longlong     modification_counter;/* when we write to the file we
123
122
                                increment this by one */
124
 
        ib_int64_t      flush_counter;/* up to what modification_counter value
 
123
        ib_longlong     flush_counter;/* up to what modification_counter value
125
124
                                we have flushed the modifications to disk */
126
125
        UT_LIST_NODE_T(fil_node_t) chain;
127
126
                                /* link field for the file chain */
137
136
        char*           name;   /* space name = the path to the first file in
138
137
                                it */
139
138
        ulint           id;     /* space id */
140
 
        ib_int64_t      tablespace_version;
 
139
        ib_longlong     tablespace_version;
141
140
                                /* in DISCARD/IMPORT this timestamp is used to
142
141
                                check if we should ignore an insert buffer
143
142
                                merge request for a page because it actually
167
166
                                tablespace whose size we do not know yet;
168
167
                                last incomplete megabytes in data files may be
169
168
                                ignored if space == 0 */
170
 
        ulint           flags;  /* in: compressed page size
171
 
                                and file format, or 0 */
172
169
        ulint           n_reserved_extents;
173
170
                                /* number of reserved free extents for
174
171
                                ongoing operations like B-tree page split */
230
227
        ulint           n_open;         /* number of files currently open */
231
228
        ulint           max_n_open;     /* n_open is not allowed to exceed
232
229
                                        this */
233
 
        ib_int64_t      modification_counter;/* when we write to a file we
 
230
        ib_longlong     modification_counter;/* when we write to a file we
234
231
                                        increment this by one */
235
232
        ulint           max_assigned_id;/* maximum space id in the existing
236
233
                                        tables, or assigned during the time
238
235
                                        startup we scan the data dictionary
239
236
                                        and set here the maximum of the
240
237
                                        space id's of the tables there */
241
 
        ib_int64_t      tablespace_version;
 
238
        ib_longlong     tablespace_version;
242
239
                                        /* a counter which is incremented for
243
240
                                        every space object memory creation;
244
241
                                        every space mem object gets a
252
249
 
253
250
/* The tablespace memory cache. This variable is NULL before the module is
254
251
initialized. */
255
 
UNIV_INTERN fil_system_t*       fil_system      = NULL;
 
252
fil_system_t*   fil_system      = NULL;
256
253
 
257
254
 
258
255
/************************************************************************
292
289
                                found */
293
290
        const char*     name);  /* in: table name in the standard
294
291
                                'databasename/tablename' format */
295
 
/************************************************************************
296
 
Reads data from a space to a buffer. Remember that the possible incomplete
297
 
blocks at the end of file are ignored: they are not taken into account when
298
 
calculating the byte offset within a space. */
299
 
UNIV_INLINE
300
 
ulint
301
 
fil_read(
302
 
/*=====*/
303
 
                                /* out: DB_SUCCESS, or DB_TABLESPACE_DELETED
304
 
                                if we are trying to do i/o on a tablespace
305
 
                                which does not exist */
306
 
        ibool   sync,           /* in: TRUE if synchronous aio is desired */
307
 
        ulint   space_id,       /* in: space id */
308
 
        ulint   zip_size,       /* in: compressed page size in bytes;
309
 
                                0 for uncompressed pages */
310
 
        ulint   block_offset,   /* in: offset in number of blocks */
311
 
        ulint   byte_offset,    /* in: remainder of offset in bytes; in aio
312
 
                                this must be divisible by the OS block size */
313
 
        ulint   len,            /* in: how many bytes to read; this must not
314
 
                                cross a file boundary; in aio this must be a
315
 
                                block size multiple */
316
 
        void*   buf,            /* in/out: buffer where to store data read;
317
 
                                in aio this must be appropriately aligned */
318
 
        void*   message)        /* in: message for aio handler if non-sync
319
 
                                aio used, else ignored */
320
 
{
321
 
        return(fil_io(OS_FILE_READ, sync, space_id, zip_size, block_offset,
322
 
                                          byte_offset, len, buf, message));
323
 
}
324
 
 
325
 
/************************************************************************
326
 
Writes data to a space from a buffer. Remember that the possible incomplete
327
 
blocks at the end of file are ignored: they are not taken into account when
328
 
calculating the byte offset within a space. */
329
 
UNIV_INLINE
330
 
ulint
331
 
fil_write(
332
 
/*======*/
333
 
                                /* out: DB_SUCCESS, or DB_TABLESPACE_DELETED
334
 
                                if we are trying to do i/o on a tablespace
335
 
                                which does not exist */
336
 
        ibool   sync,           /* in: TRUE if synchronous aio is desired */
337
 
        ulint   space_id,       /* in: space id */
338
 
        ulint   zip_size,       /* in: compressed page size in bytes;
339
 
                                0 for uncompressed pages */
340
 
        ulint   block_offset,   /* in: offset in number of blocks */
341
 
        ulint   byte_offset,    /* in: remainder of offset in bytes; in aio
342
 
                                this must be divisible by the OS block size */
343
 
        ulint   len,            /* in: how many bytes to write; this must
344
 
                                not cross a file boundary; in aio this must
345
 
                                be a block size multiple */
346
 
        void*   buf,            /* in: buffer from which to write; in aio
347
 
                                this must be appropriately aligned */
348
 
        void*   message)        /* in: message for aio handler if non-sync
349
 
                                aio used, else ignored */
350
 
{
351
 
        return(fil_io(OS_FILE_WRITE, sync, space_id, zip_size, block_offset,
352
 
                                           byte_offset, len, buf, message));
353
 
}
354
 
 
355
 
/***********************************************************************
356
 
Returns the table space by a given id, NULL if not found. */
357
 
UNIV_INLINE
358
 
fil_space_t*
359
 
fil_space_get_by_id(
360
 
/*================*/
361
 
        ulint   id)     /* in: space id */
362
 
{
363
 
        fil_space_t*    space;
364
 
 
365
 
        ut_ad(mutex_own(&fil_system->mutex));
366
 
 
367
 
        HASH_SEARCH(hash, fil_system->spaces, id,
368
 
                    fil_space_t*, space, space->id == id);
369
 
 
370
 
        return(space);
371
 
}
372
 
 
373
 
/***********************************************************************
374
 
Returns the table space by a given name, NULL if not found. */
375
 
UNIV_INLINE
376
 
fil_space_t*
377
 
fil_space_get_by_name(
378
 
/*==================*/
379
 
        const char*     name)   /* in: space name */
380
 
{
381
 
        fil_space_t*    space;
382
 
        ulint           fold;
383
 
 
384
 
        ut_ad(mutex_own(&fil_system->mutex));
385
 
 
386
 
        fold = ut_fold_string(name);
387
 
 
388
 
        HASH_SEARCH(name_hash, fil_system->name_hash, fold,
389
 
                    fil_space_t*, space, !strcmp(name, space->name));
390
 
 
391
 
        return(space);
392
 
}
 
292
 
393
293
 
394
294
/***********************************************************************
395
295
Returns the version number of a tablespace, -1 if not found. */
396
 
UNIV_INTERN
397
 
ib_int64_t
 
296
 
 
297
ib_longlong
398
298
fil_space_get_version(
399
299
/*==================*/
400
300
                        /* out: version number, -1 if the tablespace does not
403
303
{
404
304
        fil_system_t*   system          = fil_system;
405
305
        fil_space_t*    space;
406
 
        ib_int64_t      version         = -1;
 
306
        ib_longlong     version         = -1;
407
307
 
408
308
        ut_ad(system);
409
309
 
410
310
        mutex_enter(&(system->mutex));
411
311
 
412
 
        space = fil_space_get_by_id(id);
 
312
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
413
313
 
414
314
        if (space) {
415
315
                version = space->tablespace_version;
422
322
 
423
323
/***********************************************************************
424
324
Returns the latch of a file space. */
425
 
UNIV_INTERN
 
325
 
426
326
rw_lock_t*
427
327
fil_space_get_latch(
428
328
/*================*/
429
329
                        /* out: latch protecting storage allocation */
430
 
        ulint   id,     /* in: space id */
431
 
        ulint*  flags)  /* out: tablespace flags */
 
330
        ulint   id)     /* in: space id */
432
331
{
433
332
        fil_system_t*   system          = fil_system;
434
333
        fil_space_t*    space;
437
336
 
438
337
        mutex_enter(&(system->mutex));
439
338
 
440
 
        space = fil_space_get_by_id(id);
 
339
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
441
340
 
442
341
        ut_a(space);
443
342
 
444
 
        if (flags) {
445
 
                *flags = space->flags;
446
 
        }
447
 
 
448
343
        mutex_exit(&(system->mutex));
449
344
 
450
345
        return(&(space->latch));
452
347
 
453
348
/***********************************************************************
454
349
Returns the type of a file space. */
455
 
UNIV_INTERN
 
350
 
456
351
ulint
457
352
fil_space_get_type(
458
353
/*===============*/
466
361
 
467
362
        mutex_enter(&(system->mutex));
468
363
 
469
 
        space = fil_space_get_by_id(id);
 
364
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
470
365
 
471
366
        ut_a(space);
472
367
 
477
372
 
478
373
/***********************************************************************
479
374
Returns the ibuf data of a file space. */
480
 
UNIV_INTERN
 
375
 
481
376
ibuf_data_t*
482
377
fil_space_get_ibuf_data(
483
378
/*====================*/
493
388
 
494
389
        mutex_enter(&(system->mutex));
495
390
 
496
 
        space = fil_space_get_by_id(id);
 
391
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
497
392
 
498
393
        mutex_exit(&(system->mutex));
499
394
 
532
427
 
533
428
/***********************************************************************
534
429
Appends a new file to the chain of files of a space. File must be closed. */
535
 
UNIV_INTERN
 
430
 
536
431
void
537
432
fil_node_create(
538
433
/*============*/
568
463
        node->modification_counter = 0;
569
464
        node->flush_counter = 0;
570
465
 
571
 
        space = fil_space_get_by_id(id);
 
466
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
572
467
 
573
468
        if (!space) {
574
469
                ut_print_timestamp(stderr);
606
501
        fil_system_t*   system, /* in: tablespace memory cache */
607
502
        fil_space_t*    space)  /* in: space */
608
503
{
609
 
        ib_int64_t      size_bytes;
 
504
        ib_longlong     size_bytes;
610
505
        ulint           size_low;
611
506
        ulint           size_high;
612
507
        ibool           ret;
615
510
        byte*           buf2;
616
511
        byte*           page;
617
512
        ulint           space_id;
618
 
        ulint           flags;
619
513
#endif /* !UNIV_HOTBACKUP */
620
514
 
621
515
        ut_ad(mutex_own(&(system->mutex)));
649
543
 
650
544
                os_file_get_size(node->handle, &size_low, &size_high);
651
545
 
652
 
                size_bytes = (((ib_int64_t)size_high) << 32)
653
 
                        + (ib_int64_t)size_low;
 
546
                size_bytes = (((ib_longlong)size_high) << 32)
 
547
                        + (ib_longlong)size_low;
654
548
#ifdef UNIV_HOTBACKUP
655
549
                node->size = (ulint) (size_bytes / UNIV_PAGE_SIZE);
656
 
                /* TODO: adjust to zip_size, like below? */
 
550
 
657
551
#else
658
552
                ut_a(space->purpose != FIL_LOG);
659
553
                ut_a(space->id != 0);
683
577
                success = os_file_read(node->handle, page, 0, 0,
684
578
                                       UNIV_PAGE_SIZE);
685
579
                space_id = fsp_header_get_space_id(page);
686
 
                flags = fsp_header_get_flags(page);
687
580
 
688
581
                ut_free(buf2);
689
582
 
691
584
 
692
585
                os_file_close(node->handle);
693
586
 
694
 
                if (UNIV_UNLIKELY(space_id != space->id)) {
 
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) {
695
597
                        fprintf(stderr,
696
598
                                "InnoDB: Error: tablespace id is %lu"
697
599
                                " in the data dictionary\n"
698
600
                                "InnoDB: but in file %s it is %lu!\n",
699
601
                                space->id, node->name, space_id);
700
602
 
701
 
                        ut_error;
702
 
                }
703
 
 
704
 
                if (UNIV_UNLIKELY(space_id == ULINT_UNDEFINED
705
 
                                  || space_id == 0)) {
706
 
                        fprintf(stderr,
707
 
                                "InnoDB: Error: tablespace id %lu"
708
 
                                " in file %s is not sensible\n",
709
 
                                (ulong) space_id, node->name);
710
 
 
711
 
                        ut_error;
712
 
                }
713
 
 
714
 
                if (UNIV_UNLIKELY(space->flags != flags)) {
715
 
                        fprintf(stderr,
716
 
                                "InnoDB: Error: table flags are %lx"
717
 
                                " in the data dictionary\n"
718
 
                                "InnoDB: but the flags in file %s are %lx!\n",
719
 
                                space->flags, node->name, flags);
720
 
 
721
 
                        ut_error;
722
 
                }
723
 
 
724
 
                if (size_bytes >= 1024 * 1024) {
725
 
                        /* Truncate the size to whole megabytes. */
726
 
                        size_bytes = ut_2pow_round(size_bytes, 1024 * 1024);
727
 
                }
728
 
 
729
 
                if (!(flags & DICT_TF_ZSSIZE_MASK)) {
 
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 {
730
611
                        node->size = (ulint) (size_bytes / UNIV_PAGE_SIZE);
731
 
                } else {
732
 
                        node->size = (ulint)
733
 
                                (size_bytes
734
 
                                 / dict_table_flags_to_zip_size(flags));
735
612
                }
736
613
#endif
737
614
                space->size += node->size;
900
777
                return;
901
778
        }
902
779
 
903
 
        space = fil_space_get_by_id(space_id);
904
 
 
 
780
        HASH_SEARCH(hash, system->spaces, space_id, space,
 
781
                    space->id == space_id);
905
782
        if (space != NULL && space->stop_ios) {
906
783
                /* We are going to do a rename file and want to stop new i/o's
907
784
                for a while */
1026
903
        mem_free(node);
1027
904
}
1028
905
 
1029
 
#ifdef UNIV_LOG_ARCHIVE
1030
906
/********************************************************************
1031
907
Drops files from the start of a file space, so that its size is cut by
1032
908
the amount given. */
1033
 
UNIV_INTERN
 
909
 
1034
910
void
1035
911
fil_space_truncate_start(
1036
912
/*=====================*/
1045
921
 
1046
922
        mutex_enter(&(system->mutex));
1047
923
 
1048
 
        space = fil_space_get_by_id(id);
 
924
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
1049
925
 
1050
926
        ut_a(space);
1051
927
 
1052
928
        while (trunc_len > 0) {
1053
929
                node = UT_LIST_GET_FIRST(space->chain);
1054
930
 
1055
 
                ut_a(node->size * UNIV_PAGE_SIZE <= trunc_len);
 
931
                ut_a(node->size * UNIV_PAGE_SIZE >= trunc_len);
1056
932
 
1057
933
                trunc_len -= node->size * UNIV_PAGE_SIZE;
1058
934
 
1061
937
 
1062
938
        mutex_exit(&(system->mutex));
1063
939
}
1064
 
#endif /* UNIV_LOG_ARCHIVE */
1065
940
 
1066
941
/***********************************************************************
1067
942
Creates a space memory object and puts it to the tablespace memory cache. If
1068
943
there is an error, prints an error message to the .err log. */
1069
 
UNIV_INTERN
 
944
 
1070
945
ibool
1071
946
fil_space_create(
1072
947
/*=============*/
1073
948
                                /* out: TRUE if success */
1074
949
        const char*     name,   /* in: space name */
1075
950
        ulint           id,     /* in: space id */
1076
 
        ulint           flags,  /* in: compressed page size
1077
 
                                and file format, or 0 */
1078
951
        ulint           purpose)/* in: FIL_TABLESPACE, or FIL_LOG if log */
1079
952
{
1080
953
        fil_system_t*   system          = fil_system;
1081
954
        fil_space_t*    space;
1082
 
 
1083
 
        /* The tablespace flags (FSP_SPACE_FLAGS) should be 0 for
1084
 
        ROW_FORMAT=COMPACT (table->flags == DICT_TF_COMPACT) and
1085
 
        ROW_FORMAT=REDUNDANT (table->flags == 0).  For any other
1086
 
        format, the tablespace flags should equal table->flags. */
1087
 
        ut_a(flags != DICT_TF_COMPACT);
1088
 
 
 
955
        ulint           namesake_id;
1089
956
try_again:
1090
957
        /*printf(
1091
958
        "InnoDB: Adding tablespace %lu of name %s, purpose %lu\n", id, name,
1096
963
 
1097
964
        mutex_enter(&(system->mutex));
1098
965
 
1099
 
        space = fil_space_get_by_name(name);
1100
 
 
1101
 
        if (UNIV_LIKELY_NULL(space)) {
1102
 
                ulint   namesake_id;
1103
 
 
 
966
        HASH_SEARCH(name_hash, system->name_hash, ut_fold_string(name), space,
 
967
                    0 == strcmp(name, space->name));
 
968
        if (space != NULL) {
1104
969
                ut_print_timestamp(stderr);
1105
970
                fprintf(stderr,
1106
971
                        "  InnoDB: Warning: trying to init to the"
1144
1009
                goto try_again;
1145
1010
        }
1146
1011
 
1147
 
        space = fil_space_get_by_id(id);
 
1012
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
1148
1013
 
1149
 
        if (UNIV_LIKELY_NULL(space)) {
 
1014
        if (space != NULL) {
1150
1015
                fprintf(stderr,
1151
1016
                        "InnoDB: Error: trying to add tablespace %lu"
1152
1017
                        " of name ", (ulong) id);
1182
1047
        space->is_being_deleted = FALSE;
1183
1048
        space->purpose = purpose;
1184
1049
        space->size = 0;
1185
 
        space->flags = flags;
1186
1050
 
1187
1051
        space->n_reserved_extents = 0;
1188
1052
 
1267
1131
Frees a space object from the tablespace memory cache. Closes the files in
1268
1132
the chain but does not delete them. There must not be any pending i/o's or
1269
1133
flushes on the files. */
1270
 
UNIV_INTERN
 
1134
 
1271
1135
ibool
1272
1136
fil_space_free(
1273
1137
/*===========*/
1281
1145
 
1282
1146
        mutex_enter(&(system->mutex));
1283
1147
 
1284
 
        space = fil_space_get_by_id(id);
 
1148
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
1285
1149
 
1286
1150
        if (!space) {
1287
1151
                ut_print_timestamp(stderr);
1297
1161
 
1298
1162
        HASH_DELETE(fil_space_t, hash, system->spaces, id, space);
1299
1163
 
1300
 
        namespace = fil_space_get_by_name(space->name);
 
1164
        HASH_SEARCH(name_hash, system->name_hash, ut_fold_string(space->name),
 
1165
                    namespace, 0 == strcmp(space->name, namespace->name));
1301
1166
        ut_a(namespace);
1302
1167
        ut_a(space == namespace);
1303
1168
 
1353
1218
 
1354
1219
        ut_ad(system);
1355
1220
 
1356
 
        space = fil_space_get_by_id(id);
 
1221
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
1357
1222
 
1358
1223
        return(space);
1359
1224
}
1362
1227
/***********************************************************************
1363
1228
Returns the size of the space in pages. The tablespace must be cached in the
1364
1229
memory cache. */
1365
 
UNIV_INTERN
 
1230
 
1366
1231
ulint
1367
1232
fil_space_get_size(
1368
1233
/*===============*/
1378
1243
 
1379
1244
        fil_mutex_enter_and_prepare_for_io(id);
1380
1245
 
1381
 
        space = fil_space_get_by_id(id);
 
1246
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
1382
1247
 
1383
1248
        if (space == NULL) {
1384
1249
                mutex_exit(&(system->mutex));
1409
1274
}
1410
1275
 
1411
1276
/***********************************************************************
1412
 
Returns the flags of the space. The tablespace must be cached
1413
 
in the memory cache. */
1414
 
UNIV_INTERN
1415
 
ulint
1416
 
fil_space_get_flags(
1417
 
/*================*/
1418
 
                        /* out: flags, ULINT_UNDEFINED if space not found */
1419
 
        ulint   id)     /* in: space id */
1420
 
{
1421
 
        fil_system_t*   system          = fil_system;
1422
 
        fil_node_t*     node;
1423
 
        fil_space_t*    space;
1424
 
        ulint           flags;
1425
 
 
1426
 
        ut_ad(system);
1427
 
 
1428
 
        if (UNIV_UNLIKELY(!id)) {
1429
 
                return(0);
1430
 
        }
1431
 
 
1432
 
        fil_mutex_enter_and_prepare_for_io(id);
1433
 
 
1434
 
        space = fil_space_get_by_id(id);
1435
 
 
1436
 
        if (space == NULL) {
1437
 
                mutex_exit(&(system->mutex));
1438
 
 
1439
 
                return(ULINT_UNDEFINED);
1440
 
        }
1441
 
 
1442
 
        if (space->size == 0 && space->purpose == FIL_TABLESPACE) {
1443
 
                ut_a(id != 0);
1444
 
 
1445
 
                ut_a(1 == UT_LIST_GET_LEN(space->chain));
1446
 
 
1447
 
                node = UT_LIST_GET_FIRST(space->chain);
1448
 
 
1449
 
                /* It must be a single-table tablespace and we have not opened
1450
 
                the file yet; the following calls will open it and update the
1451
 
                size fields */
1452
 
 
1453
 
                fil_node_prepare_for_io(node, system, space);
1454
 
                fil_node_complete_io(node, system, OS_FILE_READ);
1455
 
        }
1456
 
 
1457
 
        flags = space->flags;
1458
 
 
1459
 
        mutex_exit(&(system->mutex));
1460
 
 
1461
 
        return(flags);
1462
 
}
1463
 
 
1464
 
/***********************************************************************
1465
 
Returns the compressed page size of the space, or 0 if the space
1466
 
is not compressed. The tablespace must be cached in the memory cache. */
1467
 
UNIV_INTERN
1468
 
ulint
1469
 
fil_space_get_zip_size(
1470
 
/*===================*/
1471
 
                        /* out: compressed page size, ULINT_UNDEFINED
1472
 
                        if space not found */
1473
 
        ulint   id)     /* in: space id */
1474
 
{
1475
 
        ulint   flags;
1476
 
 
1477
 
        flags = fil_space_get_flags(id);
1478
 
 
1479
 
        if (flags && flags != ULINT_UNDEFINED) {
1480
 
 
1481
 
                return(dict_table_flags_to_zip_size(flags));
1482
 
        }
1483
 
 
1484
 
        return(flags);
1485
 
}
1486
 
 
1487
 
/***********************************************************************
1488
1277
Checks if the pair space, page_no refers to an existing page in a tablespace
1489
1278
file space. The tablespace must be cached in the memory cache. */
1490
 
UNIV_INTERN
 
1279
 
1491
1280
ibool
1492
1281
fil_check_adress_in_tablespace(
1493
1282
/*===========================*/
1544
1333
 
1545
1334
/********************************************************************
1546
1335
Initializes the tablespace memory cache. */
1547
 
UNIV_INTERN
 
1336
 
1548
1337
void
1549
1338
fil_init(
1550
1339
/*=====*/
1569
1358
space objects for the log and the system tablespace have been created. The
1570
1359
purpose of this operation is to make sure we never run out of file descriptors
1571
1360
if we need to read from the insert buffer or to write to the log. */
1572
 
UNIV_INTERN
 
1361
 
1573
1362
void
1574
1363
fil_open_log_and_system_tablespace_files(void)
1575
1364
/*==========================================*/
1624
1413
/***********************************************************************
1625
1414
Closes all open files. There must not be any pending i/o's or not flushed
1626
1415
modifications in the files. */
1627
 
UNIV_INTERN
 
1416
 
1628
1417
void
1629
1418
fil_close_all_files(void)
1630
1419
/*=====================*/
1655
1444
/***********************************************************************
1656
1445
Sets the max tablespace id counter if the given number is bigger than the
1657
1446
previous value. */
1658
 
UNIV_INTERN
 
1447
 
1659
1448
void
1660
1449
fil_set_max_space_id_if_bigger(
1661
1450
/*===========================*/
1684
1473
Initializes the ibuf data structure for space 0 == the system tablespace.
1685
1474
This can be called after the file space headers have been created and the
1686
1475
dictionary system has been initialized. */
1687
 
UNIV_INTERN
 
1476
 
1688
1477
void
1689
1478
fil_ibuf_init_at_db_start(void)
1690
1479
/*===========================*/
1701
1490
 
1702
1491
/********************************************************************
1703
1492
Writes the flushed lsn and the latest archived log number to the page header
1704
 
of the first page of a data file of the system tablespace (space 0),
1705
 
which is uncompressed. */
 
1493
of the first page of a data file. */
1706
1494
static
1707
1495
ulint
1708
1496
fil_write_lsn_and_arch_no_to_file(
1709
1497
/*==============================*/
1710
 
        ulint           sum_of_sizes,   /* in: combined size of previous files
1711
 
                                        in space, in database pages */
1712
 
        ib_uint64_t     lsn,            /* in: lsn to write */
1713
 
        ulint           arch_log_no     /* in: archived log number to write */
 
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 */
1714
1503
        __attribute__((unused)))
1715
1504
{
1716
1505
        byte*   buf1;
1719
1508
        buf1 = mem_alloc(2 * UNIV_PAGE_SIZE);
1720
1509
        buf = ut_align(buf1, UNIV_PAGE_SIZE);
1721
1510
 
1722
 
        fil_read(TRUE, 0, 0, sum_of_sizes, 0, UNIV_PAGE_SIZE, buf, NULL);
1723
 
 
1724
 
        mach_write_ull(buf + FIL_PAGE_FILE_FLUSH_LSN, lsn);
1725
 
 
1726
 
        fil_write(TRUE, 0, 0, sum_of_sizes, 0, UNIV_PAGE_SIZE, buf, NULL);
 
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);
1727
1516
 
1728
1517
        return(DB_SUCCESS);
1729
1518
}
1731
1520
/********************************************************************
1732
1521
Writes the flushed lsn and the latest archived log number to the page
1733
1522
header of the first page of each data file in the system tablespace. */
1734
 
UNIV_INTERN
 
1523
 
1735
1524
ulint
1736
1525
fil_write_flushed_lsn_to_data_files(
1737
1526
/*================================*/
1738
 
                                        /* out: DB_SUCCESS or error number */
1739
 
        ib_uint64_t     lsn,            /* in: lsn to write */
1740
 
        ulint           arch_log_no)    /* in: latest archived log
1741
 
                                        file number */
 
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 */
1742
1530
{
1743
1531
        fil_space_t*    space;
1744
1532
        fil_node_t*     node;
1765
1553
                                mutex_exit(&(fil_system->mutex));
1766
1554
 
1767
1555
                                err = fil_write_lsn_and_arch_no_to_file(
1768
 
                                        sum_of_sizes, lsn, arch_log_no);
 
1556
                                        space->id, sum_of_sizes, lsn,
 
1557
                                        arch_log_no);
1769
1558
                                if (err != DB_SUCCESS) {
1770
1559
 
1771
1560
                                        return(err);
1788
1577
/***********************************************************************
1789
1578
Reads the flushed lsn and arch no fields from a data file at database
1790
1579
startup. */
1791
 
UNIV_INTERN
 
1580
 
1792
1581
void
1793
1582
fil_read_flushed_lsn_and_arch_log_no(
1794
1583
/*=================================*/
1795
 
        os_file_t       data_file,              /* in: open data file */
1796
 
        ibool           one_read_already,       /* in: TRUE if min and max
1797
 
                                                parameters below already
1798
 
                                                contain sensible data */
 
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 */
1799
1587
#ifdef UNIV_LOG_ARCHIVE
1800
 
        ulint*          min_arch_log_no,        /* in/out: */
1801
 
        ulint*          max_arch_log_no,        /* in/out: */
 
1588
        ulint*  min_arch_log_no,        /* in/out: */
 
1589
        ulint*  max_arch_log_no,        /* in/out: */
1802
1590
#endif /* UNIV_LOG_ARCHIVE */
1803
 
        ib_uint64_t*    min_flushed_lsn,        /* in/out: */
1804
 
        ib_uint64_t*    max_flushed_lsn)        /* in/out: */
 
1591
        dulint* min_flushed_lsn,        /* in/out: */
 
1592
        dulint* max_flushed_lsn)        /* in/out: */
1805
1593
{
1806
 
        byte*           buf;
1807
 
        byte*           buf2;
1808
 
        ib_uint64_t     flushed_lsn;
 
1594
        byte*   buf;
 
1595
        byte*   buf2;
 
1596
        dulint  flushed_lsn;
1809
1597
 
1810
1598
        buf2 = ut_malloc(2 * UNIV_PAGE_SIZE);
1811
1599
        /* Align the memory for a possible read from a raw device */
1813
1601
 
1814
1602
        os_file_read(data_file, buf, 0, 0, UNIV_PAGE_SIZE);
1815
1603
 
1816
 
        flushed_lsn = mach_read_ull(buf + FIL_PAGE_FILE_FLUSH_LSN);
 
1604
        flushed_lsn = mach_read_from_8(buf + FIL_PAGE_FILE_FLUSH_LSN);
1817
1605
 
1818
1606
        ut_free(buf2);
1819
1607
 
1827
1615
                return;
1828
1616
        }
1829
1617
 
1830
 
        if (*min_flushed_lsn > flushed_lsn) {
 
1618
        if (ut_dulint_cmp(*min_flushed_lsn, flushed_lsn) > 0) {
1831
1619
                *min_flushed_lsn = flushed_lsn;
1832
1620
        }
1833
 
        if (*max_flushed_lsn < flushed_lsn) {
 
1621
        if (ut_dulint_cmp(*max_flushed_lsn, flushed_lsn) < 0) {
1834
1622
                *max_flushed_lsn = flushed_lsn;
1835
1623
        }
1836
1624
#ifdef UNIV_LOG_ARCHIVE
1848
1636
/***********************************************************************
1849
1637
Increments the count of pending insert buffer page merges, if space is not
1850
1638
being deleted. */
1851
 
UNIV_INTERN
 
1639
 
1852
1640
ibool
1853
1641
fil_inc_pending_ibuf_merges(
1854
1642
/*========================*/
1861
1649
 
1862
1650
        mutex_enter(&(system->mutex));
1863
1651
 
1864
 
        space = fil_space_get_by_id(id);
 
1652
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
1865
1653
 
1866
1654
        if (space == NULL) {
1867
1655
                fprintf(stderr,
1885
1673
 
1886
1674
/***********************************************************************
1887
1675
Decrements the count of pending insert buffer page merges. */
1888
 
UNIV_INTERN
 
1676
 
1889
1677
void
1890
1678
fil_decr_pending_ibuf_merges(
1891
1679
/*=========================*/
1896
1684
 
1897
1685
        mutex_enter(&(system->mutex));
1898
1686
 
1899
 
        space = fil_space_get_by_id(id);
 
1687
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
1900
1688
 
1901
1689
        if (space == NULL) {
1902
1690
                fprintf(stderr,
1949
1737
fil_op_write_log(
1950
1738
/*=============*/
1951
1739
        ulint           type,           /* in: MLOG_FILE_CREATE,
1952
 
                                        MLOG_FILE_CREATE2,
1953
1740
                                        MLOG_FILE_DELETE, or
1954
1741
                                        MLOG_FILE_RENAME */
1955
1742
        ulint           space_id,       /* in: space id */
1956
 
        ulint           flags,          /* in: compressed page size
1957
 
                                        and file format
1958
 
                                        if type==MLOG_FILE_CREATE2, or 0 */
1959
1743
        const char*     name,           /* in: table name in the familiar
1960
1744
                                        'databasename/tablename' format, or
1961
1745
                                        the file path in the case of
1968
1752
        byte*   log_ptr;
1969
1753
        ulint   len;
1970
1754
 
1971
 
        log_ptr = mlog_open(mtr, 11 + 2 + 1);
 
1755
        log_ptr = mlog_open(mtr, 11 + 2);
1972
1756
 
1973
1757
        if (!log_ptr) {
1974
1758
                /* Logging in mtr is switched off during crash recovery:
1978
1762
 
1979
1763
        log_ptr = mlog_write_initial_log_record_for_file_op(type, space_id, 0,
1980
1764
                                                            log_ptr, mtr);
1981
 
        if (type == MLOG_FILE_CREATE2) {
1982
 
                mach_write_to_4(log_ptr, flags);
1983
 
                log_ptr += 4;
1984
 
        }
1985
1765
        /* Let us store the strings as null-terminated for easier readability
1986
1766
        and handling */
1987
1767
 
1994
1774
        mlog_catenate_string(mtr, (byte*) name, len);
1995
1775
 
1996
1776
        if (type == MLOG_FILE_RENAME) {
1997
 
                len = strlen(new_name) + 1;
 
1777
                ulint   len = strlen(new_name) + 1;
1998
1778
                log_ptr = mlog_open(mtr, 2 + len);
1999
1779
                ut_a(log_ptr);
2000
1780
                mach_write_to_2(log_ptr, len);
2018
1798
 
2019
1799
Note that ibbackup --apply-log sets fil_path_to_mysql_datadir to point to the
2020
1800
datadir that we should use in replaying the file operations. */
2021
 
UNIV_INTERN
 
1801
 
2022
1802
byte*
2023
1803
fil_op_log_parse_or_replay(
2024
1804
/*=======================*/
2030
1810
                                not fir completely between ptr and end_ptr */
2031
1811
        byte*   end_ptr,        /* in: buffer end */
2032
1812
        ulint   type,           /* in: the type of this log record */
2033
 
        ulint   space_id)       /* in: the space id of the tablespace in
2034
 
                                question, or 0 if the log record should
2035
 
                                only be parsed but not replayed */
 
1813
        ibool   do_replay,      /* in: TRUE if we want to replay the
 
1814
                                operation, and not just parse the log record */
 
1815
        ulint   space_id)       /* in: if do_replay is TRUE, the space id of
 
1816
                                the tablespace in question; otherwise
 
1817
                                ignored */
2036
1818
{
2037
1819
        ulint           name_len;
2038
1820
        ulint           new_name_len;
2039
1821
        const char*     name;
2040
1822
        const char*     new_name        = NULL;
2041
 
        ulint           flags           = 0;
2042
 
 
2043
 
        if (type == MLOG_FILE_CREATE2) {
2044
 
                if (end_ptr < ptr + 4) {
2045
 
 
2046
 
                        return(NULL);
2047
 
                }
2048
 
 
2049
 
                flags = mach_read_from_4(ptr);
2050
 
                ptr += 4;
2051
 
        }
2052
1823
 
2053
1824
        if (end_ptr < ptr + 2) {
2054
1825
 
2097
1868
        printf("new name %s\n", new_name);
2098
1869
        }
2099
1870
        */
2100
 
        if (!space_id) {
 
1871
        if (do_replay == FALSE) {
2101
1872
 
2102
1873
                return(ptr);
2103
1874
        }
2110
1881
        were renames of tables during the backup. See ibbackup code for more
2111
1882
        on the problem. */
2112
1883
 
2113
 
        switch (type) {
2114
 
        case MLOG_FILE_DELETE:
 
1884
        if (type == MLOG_FILE_DELETE) {
2115
1885
                if (fil_tablespace_exists_in_mem(space_id)) {
2116
1886
                        ut_a(fil_delete_tablespace(space_id));
2117
1887
                }
2118
 
 
2119
 
                break;
2120
 
 
2121
 
        case MLOG_FILE_RENAME:
 
1888
        } else if (type == MLOG_FILE_RENAME) {
2122
1889
                /* We do the rename based on space id, not old file name;
2123
1890
                this should guarantee that after the log replay each .ibd file
2124
1891
                has the correct name for the latest log sequence number; the
2142
1909
                                }
2143
1910
                        }
2144
1911
                }
2145
 
 
2146
 
                break;
2147
 
 
2148
 
        case MLOG_FILE_CREATE:
2149
 
        case MLOG_FILE_CREATE2:
 
1912
        } else {
 
1913
                ut_a(type == MLOG_FILE_CREATE);
 
1914
 
2150
1915
                if (fil_tablespace_exists_in_mem(space_id)) {
2151
1916
                        /* Do nothing */
2152
1917
                } else if (fil_get_space_id_for_table(name)
2157
1922
                        not exist yet */
2158
1923
                        fil_create_directory_for_tablename(name);
2159
1924
 
 
1925
                        ut_a(space_id != 0);
 
1926
 
2160
1927
                        if (fil_create_new_single_table_tablespace(
2161
 
                                    &space_id, name, FALSE, flags,
 
1928
                                    &space_id, name, FALSE,
2162
1929
                                    FIL_IBD_FILE_INITIAL_SIZE) != DB_SUCCESS) {
2163
1930
                                ut_error;
2164
1931
                        }
2165
1932
                }
2166
 
 
2167
 
                break;
2168
 
 
2169
 
        default:
2170
 
                ut_error;
2171
1933
        }
2172
1934
 
2173
1935
        return(ptr);
2176
1938
/***********************************************************************
2177
1939
Deletes a single-table tablespace. The tablespace must be cached in the
2178
1940
memory cache. */
2179
 
UNIV_INTERN
 
1941
 
2180
1942
ibool
2181
1943
fil_delete_tablespace(
2182
1944
/*==================*/
2194
1956
stop_ibuf_merges:
2195
1957
        mutex_enter(&(system->mutex));
2196
1958
 
2197
 
        space = fil_space_get_by_id(id);
 
1959
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
2198
1960
 
2199
1961
        if (space != NULL) {
2200
1962
                space->stop_ibuf_merges = TRUE;
2234
1996
try_again:
2235
1997
        mutex_enter(&(system->mutex));
2236
1998
 
2237
 
        space = fil_space_get_by_id(id);
 
1999
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
2238
2000
 
2239
2001
        if (space == NULL) {
2240
2002
                ut_print_timestamp(stderr);
2316
2078
                to write any log record */
2317
2079
                mtr_start(&mtr);
2318
2080
 
2319
 
                fil_op_write_log(MLOG_FILE_DELETE, id, 0, path, NULL, &mtr);
 
2081
                fil_op_write_log(MLOG_FILE_DELETE, id, path, NULL, &mtr);
2320
2082
                mtr_commit(&mtr);
2321
2083
#endif
2322
2084
                mem_free(path);
2337
2099
TABLE they are only removed gradually in the background;
2338
2100
3) when the user does IMPORT TABLESPACE, the tablespace will have the same id
2339
2101
as it originally had. */
2340
 
UNIV_INTERN
 
2102
 
2341
2103
ibool
2342
2104
fil_discard_tablespace(
2343
2105
/*===================*/
2361
2123
 
2362
2124
        ibuf_delete_for_discarded_space(id);
2363
2125
 
2364
 
        return(success);
 
2126
        return(TRUE);
2365
2127
}
2366
2128
 
2367
2129
/***********************************************************************
2379
2141
        fil_space_t*    space2;
2380
2142
        const char*     old_name        = space->name;
2381
2143
 
2382
 
        space2 = fil_space_get_by_name(old_name);
 
2144
        HASH_SEARCH(name_hash, system->name_hash, ut_fold_string(old_name),
 
2145
                    space2, 0 == strcmp(old_name, space2->name));
2383
2146
        if (space != space2) {
2384
2147
                fputs("InnoDB: Error: cannot find ", stderr);
2385
2148
                ut_print_filename(stderr, old_name);
2388
2151
                return(FALSE);
2389
2152
        }
2390
2153
 
2391
 
        space2 = fil_space_get_by_name(path);
 
2154
        HASH_SEARCH(name_hash, system->name_hash, ut_fold_string(path),
 
2155
                    space2, 0 == strcmp(path, space2->name));
2392
2156
        if (space2 != NULL) {
2393
2157
                fputs("InnoDB: Error: ", stderr);
2394
2158
                ut_print_filename(stderr, path);
2445
2209
/***********************************************************************
2446
2210
Renames a single-table tablespace. The tablespace must be cached in the
2447
2211
tablespace memory cache. */
2448
 
UNIV_INTERN
 
2212
 
2449
2213
ibool
2450
2214
fil_rename_tablespace(
2451
2215
/*==================*/
2488
2252
 
2489
2253
        mutex_enter(&(system->mutex));
2490
2254
 
2491
 
        space = fil_space_get_by_id(id);
 
2255
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
2492
2256
 
2493
2257
        if (space == NULL) {
2494
2258
                fprintf(stderr,
2585
2349
 
2586
2350
                mtr_start(&mtr);
2587
2351
 
2588
 
                fil_op_write_log(MLOG_FILE_RENAME, id, 0, old_name, new_name,
 
2352
                fil_op_write_log(MLOG_FILE_RENAME, id, old_name, new_name,
2589
2353
                                 &mtr);
2590
2354
                mtr_commit(&mtr);
2591
2355
        }
2599
2363
directory of a running mysqld program. We can refer to it by simply the
2600
2364
path '.'. Tables created with CREATE TEMPORARY TABLE we place in the temp
2601
2365
dir of the mysqld server. */
2602
 
UNIV_INTERN
 
2366
 
2603
2367
ulint
2604
2368
fil_create_new_single_table_tablespace(
2605
2369
/*===================================*/
2613
2377
                                        table */
2614
2378
        ibool           is_temp,        /* in: TRUE if a table created with
2615
2379
                                        CREATE TEMPORARY TABLE */
2616
 
        ulint           flags,          /* in: tablespace flags */
2617
2380
        ulint           size)           /* in: the initial size of the
2618
2381
                                        tablespace file in pages,
2619
2382
                                        must be >= FIL_IBD_FILE_INITIAL_SIZE */
2627
2390
        char*           path;
2628
2391
 
2629
2392
        ut_a(size >= FIL_IBD_FILE_INITIAL_SIZE);
2630
 
        /* The tablespace flags (FSP_SPACE_FLAGS) should be 0 for
2631
 
        ROW_FORMAT=COMPACT (table->flags == DICT_TF_COMPACT) and
2632
 
        ROW_FORMAT=REDUNDANT (table->flags == 0).  For any other
2633
 
        format, the tablespace flags should equal table->flags. */
2634
 
        ut_a(flags != DICT_TF_COMPACT);
2635
2393
 
2636
2394
        path = fil_make_ibd_name(tablename, is_temp);
2637
2395
 
2679
2437
                return(DB_ERROR);
2680
2438
        }
2681
2439
 
2682
 
        buf2 = ut_malloc(3 * UNIV_PAGE_SIZE);
 
2440
        buf2 = ut_malloc(2 * UNIV_PAGE_SIZE);
2683
2441
        /* Align the memory for file i/o if we might have O_DIRECT set */
2684
2442
        page = ut_align(buf2, UNIV_PAGE_SIZE);
2685
2443
 
2722
2480
 
2723
2481
        memset(page, '\0', UNIV_PAGE_SIZE);
2724
2482
 
2725
 
        fsp_header_init_fields(page, *space_id, flags);
2726
 
        mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, *space_id);
2727
 
 
2728
 
        if (!(flags & DICT_TF_ZSSIZE_MASK)) {
2729
 
                buf_flush_init_for_writing(page, NULL, 0);
2730
 
                ret = os_file_write(path, file, page, 0, 0, UNIV_PAGE_SIZE);
2731
 
        } else {
2732
 
                page_zip_des_t  page_zip;
2733
 
                ulint           zip_size;
2734
 
 
2735
 
                zip_size = ((PAGE_ZIP_MIN_SIZE >> 1)
2736
 
                            << ((flags & DICT_TF_ZSSIZE_MASK)
2737
 
                                >> DICT_TF_ZSSIZE_SHIFT));
2738
 
 
2739
 
                page_zip_set_size(&page_zip, zip_size);
2740
 
                page_zip.data = page + UNIV_PAGE_SIZE;
2741
 
#ifdef UNIV_DEBUG
2742
 
                page_zip.m_start =
2743
 
#endif /* UNIV_DEBUG */
2744
 
                        page_zip.m_end = page_zip.m_nonempty =
2745
 
                        page_zip.n_blobs = 0;
2746
 
                buf_flush_init_for_writing(page, &page_zip, 0);
2747
 
                ret = os_file_write(path, file, page_zip.data, 0, 0, zip_size);
2748
 
        }
 
2483
        fsp_header_write_space_id(page, *space_id);
 
2484
 
 
2485
        buf_flush_init_for_writing(page, ut_dulint_zero, *space_id, 0);
 
2486
 
 
2487
        ret = os_file_write(path, file, page, 0, 0, UNIV_PAGE_SIZE);
2749
2488
 
2750
2489
        ut_free(buf2);
2751
2490
 
2772
2511
                goto error_exit2;
2773
2512
        }
2774
2513
 
2775
 
        success = fil_space_create(path, *space_id, flags, FIL_TABLESPACE);
 
2514
        success = fil_space_create(path, *space_id, FIL_TABLESPACE);
2776
2515
 
2777
2516
        if (!success) {
2778
2517
                goto error_exit2;
2786
2525
 
2787
2526
                mtr_start(&mtr);
2788
2527
 
2789
 
                fil_op_write_log(flags
2790
 
                                 ? MLOG_FILE_CREATE2
2791
 
                                 : MLOG_FILE_CREATE,
2792
 
                                 *space_id, flags,
2793
 
                                 tablename, NULL, &mtr);
 
2528
                fil_op_write_log(MLOG_FILE_CREATE, *space_id, tablename,
 
2529
                                 NULL, &mtr);
2794
2530
 
2795
2531
                mtr_commit(&mtr);
2796
2532
        }
2808
2544
the shutdown stamped the latest lsn to the FIL_PAGE_FILE_FLUSH_LSN in the
2809
2545
first page of the .ibd file, and we can determine whether we need to reset the
2810
2546
lsn's just by looking at that flush lsn. */
2811
 
UNIV_INTERN
 
2547
 
2812
2548
ibool
2813
2549
fil_reset_too_high_lsns(
2814
2550
/*====================*/
2815
2551
                                        /* out: TRUE if success */
2816
2552
        const char*     name,           /* in: table name in the
2817
2553
                                        databasename/tablename format */
2818
 
        ib_uint64_t     current_lsn)    /* in: reset lsn's if the lsn stamped
 
2554
        dulint          current_lsn)    /* in: reset lsn's if the lsn stamped
2819
2555
                                        to FIL_PAGE_FILE_FLUSH_LSN in the
2820
2556
                                        first page is too high */
2821
2557
{
2823
2559
        char*           filepath;
2824
2560
        byte*           page;
2825
2561
        byte*           buf2;
2826
 
        ib_uint64_t     flush_lsn;
 
2562
        dulint          flush_lsn;
2827
2563
        ulint           space_id;
2828
 
        ib_int64_t      file_size;
2829
 
        ib_int64_t      offset;
2830
 
        ulint           zip_size;
 
2564
        ib_longlong     file_size;
 
2565
        ib_longlong     offset;
 
2566
        ulint           page_no;
2831
2567
        ibool           success;
2832
2568
 
2833
2569
        filepath = fil_make_ibd_name(name, FALSE);
2852
2588
 
2853
2589
        /* Read the first page of the tablespace */
2854
2590
 
2855
 
        buf2 = ut_malloc(3 * UNIV_PAGE_SIZE);
 
2591
        buf2 = ut_malloc(2 * UNIV_PAGE_SIZE);
2856
2592
        /* Align the memory for file i/o if we might have O_DIRECT set */
2857
2593
        page = ut_align(buf2, UNIV_PAGE_SIZE);
2858
2594
 
2864
2600
 
2865
2601
        /* We have to read the file flush lsn from the header of the file */
2866
2602
 
2867
 
        flush_lsn = mach_read_ull(page + FIL_PAGE_FILE_FLUSH_LSN);
 
2603
        flush_lsn = mach_read_from_8(page + FIL_PAGE_FILE_FLUSH_LSN);
2868
2604
 
2869
 
        if (current_lsn >= flush_lsn) {
 
2605
        if (ut_dulint_cmp(current_lsn, flush_lsn) >= 0) {
2870
2606
                /* Ok */
2871
2607
                success = TRUE;
2872
2608
 
2874
2610
        }
2875
2611
 
2876
2612
        space_id = fsp_header_get_space_id(page);
2877
 
        zip_size = fsp_header_get_zip_size(page);
2878
2613
 
2879
2614
        ut_print_timestamp(stderr);
2880
2615
        fprintf(stderr,
2881
2616
                "  InnoDB: Flush lsn in the tablespace file %lu"
2882
2617
                " to be imported\n"
2883
 
                "InnoDB: is %"PRIu64", which exceeds current"
2884
 
                " system lsn %"PRIu64".\n"
 
2618
                "InnoDB: is %lu %lu, which exceeds current"
 
2619
                " system lsn %lu %lu.\n"
2885
2620
                "InnoDB: We reset the lsn's in the file ",
2886
2621
                (ulong) space_id,
2887
 
                flush_lsn, current_lsn);
 
2622
                (ulong) ut_dulint_get_high(flush_lsn),
 
2623
                (ulong) ut_dulint_get_low(flush_lsn),
 
2624
                (ulong) ut_dulint_get_high(current_lsn),
 
2625
                (ulong) ut_dulint_get_low(current_lsn));
2888
2626
        ut_print_filename(stderr, filepath);
2889
2627
        fputs(".\n", stderr);
2890
2628
 
2891
 
        ut_a(ut_is_2pow(zip_size));
2892
 
        ut_a(zip_size <= UNIV_PAGE_SIZE);
2893
 
 
2894
2629
        /* Loop through all the pages in the tablespace and reset the lsn and
2895
2630
        the page checksum if necessary */
2896
2631
 
2897
2632
        file_size = os_file_get_size_as_iblonglong(file);
2898
2633
 
2899
 
        for (offset = 0; offset < file_size;
2900
 
             offset += zip_size ? zip_size : UNIV_PAGE_SIZE) {
 
2634
        for (offset = 0; offset < file_size; offset += UNIV_PAGE_SIZE) {
2901
2635
                success = os_file_read(file, page,
2902
2636
                                       (ulint)(offset & 0xFFFFFFFFUL),
2903
 
                                       (ulint)(offset >> 32),
2904
 
                                       zip_size ? zip_size : UNIV_PAGE_SIZE);
 
2637
                                       (ulint)(offset >> 32), UNIV_PAGE_SIZE);
2905
2638
                if (!success) {
2906
2639
 
2907
2640
                        goto func_exit;
2908
2641
                }
2909
 
                if (mach_read_ull(page + FIL_PAGE_LSN) > current_lsn) {
 
2642
                if (ut_dulint_cmp(mach_read_from_8(page + FIL_PAGE_LSN),
 
2643
                                  current_lsn) > 0) {
2910
2644
                        /* We have to reset the lsn */
 
2645
                        space_id = mach_read_from_4(
 
2646
                                page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
 
2647
                        page_no = mach_read_from_4(page + FIL_PAGE_OFFSET);
2911
2648
 
2912
 
                        if (zip_size) {
2913
 
                                memcpy(page + UNIV_PAGE_SIZE, page, zip_size);
2914
 
                                buf_flush_init_for_writing(
2915
 
                                        page, page + UNIV_PAGE_SIZE,
2916
 
                                        current_lsn);
2917
 
                        } else {
2918
 
                                buf_flush_init_for_writing(
2919
 
                                        page, NULL, current_lsn);
2920
 
                        }
 
2649
                        buf_flush_init_for_writing(page, current_lsn, space_id,
 
2650
                                                   page_no);
2921
2651
                        success = os_file_write(filepath, file, page,
2922
2652
                                                (ulint)(offset & 0xFFFFFFFFUL),
2923
2653
                                                (ulint)(offset >> 32),
2924
 
                                                zip_size
2925
 
                                                ? zip_size
2926
 
                                                : UNIV_PAGE_SIZE);
 
2654
                                                UNIV_PAGE_SIZE);
2927
2655
                        if (!success) {
2928
2656
 
2929
2657
                                goto func_exit;
2938
2666
        }
2939
2667
 
2940
2668
        /* We now update the flush_lsn stamp at the start of the file */
2941
 
        success = os_file_read(file, page, 0, 0,
2942
 
                               zip_size ? zip_size : UNIV_PAGE_SIZE);
 
2669
        success = os_file_read(file, page, 0, 0, UNIV_PAGE_SIZE);
2943
2670
        if (!success) {
2944
2671
 
2945
2672
                goto func_exit;
2946
2673
        }
2947
2674
 
2948
 
        mach_write_ull(page + FIL_PAGE_FILE_FLUSH_LSN, current_lsn);
 
2675
        mach_write_to_8(page + FIL_PAGE_FILE_FLUSH_LSN, current_lsn);
2949
2676
 
2950
 
        success = os_file_write(filepath, file, page, 0, 0,
2951
 
                                zip_size ? zip_size : UNIV_PAGE_SIZE);
 
2677
        success = os_file_write(filepath, file, page, 0, 0, UNIV_PAGE_SIZE);
2952
2678
        if (!success) {
2953
2679
 
2954
2680
                goto func_exit;
2971
2697
or under the protection of the dictionary mutex, so that two users cannot
2972
2698
race here. This operation does not leave the file associated with the
2973
2699
tablespace open, but closes it after we have looked at the space id in it. */
2974
 
UNIV_INTERN
 
2700
 
2975
2701
ibool
2976
2702
fil_open_single_table_tablespace(
2977
2703
/*=============================*/
2984
2710
                                        faster (the OS caches them) than
2985
2711
                                        accessing the first page of the file */
2986
2712
        ulint           id,             /* in: space id */
2987
 
        ulint           flags,          /* in: tablespace flags */
2988
2713
        const char*     name)           /* in: table name in the
2989
2714
                                        databasename/tablename format */
2990
2715
{
2994
2719
        byte*           buf2;
2995
2720
        byte*           page;
2996
2721
        ulint           space_id;
2997
 
        ulint           space_flags;
2998
2722
        ibool           ret             = TRUE;
2999
2723
 
3000
2724
        filepath = fil_make_ibd_name(name, FALSE);
3001
2725
 
3002
 
        /* The tablespace flags (FSP_SPACE_FLAGS) should be 0 for
3003
 
        ROW_FORMAT=COMPACT (table->flags == DICT_TF_COMPACT) and
3004
 
        ROW_FORMAT=REDUNDANT (table->flags == 0).  For any other
3005
 
        format, the tablespace flags should equal table->flags. */
3006
 
        ut_a(flags != DICT_TF_COMPACT);
3007
 
 
3008
2726
        file = os_file_create_simple_no_error_handling(
3009
2727
                filepath, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success);
3010
2728
        if (!success) {
3049
2767
 
3050
2768
        success = os_file_read(file, page, 0, 0, UNIV_PAGE_SIZE);
3051
2769
 
3052
 
        /* We have to read the tablespace id and flags from the file. */
 
2770
        /* We have to read the tablespace id from the file */
3053
2771
 
3054
2772
        space_id = fsp_header_get_space_id(page);
3055
 
        space_flags = fsp_header_get_flags(page);
3056
2773
 
3057
2774
        ut_free(buf2);
3058
2775
 
3059
 
        if (UNIV_UNLIKELY(space_id != id || space_flags != flags)) {
 
2776
        if (space_id != id) {
3060
2777
                ut_print_timestamp(stderr);
3061
2778
 
3062
 
                fputs("  InnoDB: Error: tablespace id and flags in file ",
3063
 
                      stderr);
 
2779
                fputs("  InnoDB: Error: tablespace id in file ", stderr);
3064
2780
                ut_print_filename(stderr, filepath);
3065
 
                fprintf(stderr, " are %lu and %lu, but in the InnoDB\n"
3066
 
                        "InnoDB: data dictionary they are %lu and %lu.\n"
 
2781
                fprintf(stderr, " is %lu, but in the InnoDB\n"
 
2782
                        "InnoDB: data dictionary it is %lu.\n"
3067
2783
                        "InnoDB: Have you moved InnoDB .ibd files"
3068
2784
                        " around without using the\n"
3069
2785
                        "InnoDB: commands DISCARD TABLESPACE and"
3072
2788
                        "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
3073
2789
                        "innodb-troubleshooting.html\n"
3074
2790
                        "InnoDB: for how to resolve the issue.\n",
3075
 
                        (ulong) space_id, (ulong) space_flags,
3076
 
                        (ulong) id, (ulong) flags);
 
2791
                        (ulong) space_id, (ulong) id);
3077
2792
 
3078
2793
                ret = FALSE;
3079
2794
 
3081
2796
        }
3082
2797
 
3083
2798
skip_check:
3084
 
        success = fil_space_create(filepath, space_id, flags, FIL_TABLESPACE);
 
2799
        success = fil_space_create(filepath, space_id, FIL_TABLESPACE);
3085
2800
 
3086
2801
        if (!success) {
3087
2802
                goto func_exit;
3137
2852
        byte*           buf2;
3138
2853
        byte*           page;
3139
2854
        ulint           space_id;
3140
 
        ulint           flags;
3141
2855
        ulint           size_low;
3142
2856
        ulint           size_high;
3143
 
        ib_int64_t      size;
 
2857
        ib_longlong     size;
3144
2858
#ifdef UNIV_HOTBACKUP
3145
2859
        fil_space_t*    space;
3146
2860
#endif
3260
2974
        /* Every .ibd file is created >= 4 pages in size. Smaller files
3261
2975
        cannot be ok. */
3262
2976
 
3263
 
        size = (((ib_int64_t)size_high) << 32) + (ib_int64_t)size_low;
 
2977
        size = (((ib_longlong)size_high) << 32) + (ib_longlong)size_low;
3264
2978
#ifndef UNIV_HOTBACKUP
3265
2979
        if (size < FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE) {
3266
2980
                fprintf(stderr,
3288
3002
                /* We have to read the tablespace id from the file */
3289
3003
 
3290
3004
                space_id = fsp_header_get_space_id(page);
3291
 
                flags = fsp_header_get_flags(page);
3292
3005
        } else {
3293
3006
                space_id = ULINT_UNDEFINED;
3294
 
                flags = 0;
3295
3007
        }
3296
3008
 
3297
3009
#ifndef UNIV_HOTBACKUP
3368
3080
        }
3369
3081
        mutex_exit(&(fil_system->mutex));
3370
3082
#endif
3371
 
        success = fil_space_create(filepath, space_id, flags, FIL_TABLESPACE);
 
3083
        success = fil_space_create(filepath, space_id, FIL_TABLESPACE);
3372
3084
 
3373
3085
        if (!success) {
3374
3086
 
3433
3145
we know into which file we should look to check the contents of a page stored
3434
3146
in the doublewrite buffer, also to know where to apply log records where the
3435
3147
space id is != 0. */
3436
 
UNIV_INTERN
 
3148
 
3437
3149
ulint
3438
3150
fil_load_single_table_tablespaces(void)
3439
3151
/*===================================*/
3561
3273
we can call this function to print an error message of orphaned .ibd files
3562
3274
for which there is not a data dictionary entry with a matching table name
3563
3275
and space id. */
3564
 
UNIV_INTERN
 
3276
 
3565
3277
void
3566
3278
fil_print_orphaned_tablespaces(void)
3567
3279
/*================================*/
3592
3304
/***********************************************************************
3593
3305
Returns TRUE if a single-table tablespace does not exist in the memory cache,
3594
3306
or is being deleted there. */
3595
 
UNIV_INTERN
 
3307
 
3596
3308
ibool
3597
3309
fil_tablespace_deleted_or_being_deleted_in_mem(
3598
3310
/*===========================================*/
3599
3311
                                /* out: TRUE if does not exist or is being\
3600
3312
                                deleted */
3601
3313
        ulint           id,     /* in: space id */
3602
 
        ib_int64_t      version)/* in: tablespace_version should be this; if
 
3314
        ib_longlong     version)/* in: tablespace_version should be this; if
3603
3315
                                you pass -1 as the value of this, then this
3604
3316
                                parameter is ignored */
3605
3317
{
3610
3322
 
3611
3323
        mutex_enter(&(system->mutex));
3612
3324
 
3613
 
        space = fil_space_get_by_id(id);
 
3325
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
3614
3326
 
3615
3327
        if (space == NULL || space->is_being_deleted) {
3616
3328
                mutex_exit(&(system->mutex));
3618
3330
                return(TRUE);
3619
3331
        }
3620
3332
 
3621
 
        if (version != ((ib_int64_t)-1)
 
3333
        if (version != ((ib_longlong)-1)
3622
3334
            && space->tablespace_version != version) {
3623
3335
                mutex_exit(&(system->mutex));
3624
3336
 
3632
3344
 
3633
3345
/***********************************************************************
3634
3346
Returns TRUE if a single-table tablespace exists in the memory cache. */
3635
 
UNIV_INTERN
 
3347
 
3636
3348
ibool
3637
3349
fil_tablespace_exists_in_mem(
3638
3350
/*=========================*/
3646
3358
 
3647
3359
        mutex_enter(&(system->mutex));
3648
3360
 
3649
 
        space = fil_space_get_by_id(id);
 
3361
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
3650
3362
 
3651
3363
        if (space == NULL) {
3652
3364
                mutex_exit(&(system->mutex));
3663
3375
Returns TRUE if a matching tablespace exists in the InnoDB tablespace memory
3664
3376
cache. Note that if we have not done a crash recovery at the database startup,
3665
3377
there may be many tablespaces which are not yet in the memory cache. */
3666
 
UNIV_INTERN
 
3378
 
3667
3379
ibool
3668
3380
fil_space_for_table_exists_in_mem(
3669
3381
/*==============================*/
3700
3412
 
3701
3413
        /* Look if there is a space with the same id */
3702
3414
 
3703
 
        space = fil_space_get_by_id(id);
 
3415
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
3704
3416
 
3705
3417
        /* Look if there is a space with the same name; the name is the
3706
3418
        directory path from the datadir to the file */
3707
3419
 
3708
 
        namespace = fil_space_get_by_name(path);
 
3420
        HASH_SEARCH(name_hash, system->name_hash,
 
3421
                    ut_fold_string(path), namespace,
 
3422
                    0 == strcmp(namespace->name, path));
3709
3423
        if (space && space == namespace) {
3710
3424
                /* Found */
3711
3425
 
3828
3542
        /* Look if there is a space with the same name; the name is the
3829
3543
        directory path to the file */
3830
3544
 
3831
 
        namespace = fil_space_get_by_name(path);
3832
 
 
 
3545
        HASH_SEARCH(name_hash, system->name_hash,
 
3546
                    ut_fold_string(path), namespace,
 
3547
                    0 == strcmp(namespace->name, path));
3833
3548
        if (namespace) {
3834
3549
                id = namespace->id;
3835
3550
        }
3845
3560
Tries to extend a data file so that it would accommodate the number of pages
3846
3561
given. The tablespace must be cached in the memory cache. If the space is big
3847
3562
enough already, does nothing. */
3848
 
UNIV_INTERN
 
3563
 
3849
3564
ibool
3850
3565
fil_extend_space_to_desired_size(
3851
3566
/*=============================*/
3868
3583
        ulint           file_start_page_no;
3869
3584
        ulint           offset_high;
3870
3585
        ulint           offset_low;
3871
 
        ulint           page_size;
3872
3586
        ibool           success         = TRUE;
3873
3587
 
3874
3588
        fil_mutex_enter_and_prepare_for_io(space_id);
3875
3589
 
3876
 
        space = fil_space_get_by_id(space_id);
 
3590
        HASH_SEARCH(hash, system->spaces, space_id, space,
 
3591
                    space->id == space_id);
3877
3592
        ut_a(space);
3878
3593
 
3879
3594
        if (space->size >= size_after_extend) {
3886
3601
                return(TRUE);
3887
3602
        }
3888
3603
 
3889
 
        page_size = dict_table_flags_to_zip_size(space->flags);
3890
 
        if (!page_size) {
3891
 
                page_size = UNIV_PAGE_SIZE;
3892
 
        }
3893
 
 
3894
3604
        node = UT_LIST_GET_LAST(space->chain);
3895
3605
 
3896
3606
        fil_node_prepare_for_io(node, system, space);
3899
3609
        file_start_page_no = space->size - node->size;
3900
3610
 
3901
3611
        /* Extend at most 64 pages at a time */
3902
 
        buf_size = ut_min(64, size_after_extend - start_page_no) * page_size;
3903
 
        buf2 = mem_alloc(buf_size + page_size);
3904
 
        buf = ut_align(buf2, page_size);
 
3612
        buf_size = ut_min(64, size_after_extend - start_page_no)
 
3613
                * UNIV_PAGE_SIZE;
 
3614
        buf2 = mem_alloc(buf_size + UNIV_PAGE_SIZE);
 
3615
        buf = ut_align(buf2, UNIV_PAGE_SIZE);
3905
3616
 
3906
3617
        memset(buf, 0, buf_size);
3907
3618
 
3908
3619
        while (start_page_no < size_after_extend) {
3909
 
                ulint   n_pages = ut_min(buf_size / page_size,
 
3620
                ulint   n_pages = ut_min(buf_size / UNIV_PAGE_SIZE,
3910
3621
                                         size_after_extend - start_page_no);
3911
3622
 
3912
3623
                offset_high = (start_page_no - file_start_page_no)
3913
 
                        / (4096 * ((1024 * 1024) / page_size));
 
3624
                        / (4096 * ((1024 * 1024) / UNIV_PAGE_SIZE));
3914
3625
                offset_low  = ((start_page_no - file_start_page_no)
3915
 
                               % (4096 * ((1024 * 1024) / page_size)))
3916
 
                        * page_size;
 
3626
                               % (4096 * ((1024 * 1024) / UNIV_PAGE_SIZE)))
 
3627
                        * UNIV_PAGE_SIZE;
3917
3628
#ifdef UNIV_HOTBACKUP
3918
3629
                success = os_file_write(node->name, node->handle, buf,
3919
3630
                                        offset_low, offset_high,
3920
 
                                        page_size * n_pages);
 
3631
                                        UNIV_PAGE_SIZE * n_pages);
3921
3632
#else
3922
3633
                success = os_aio(OS_FILE_WRITE, OS_AIO_SYNC,
3923
3634
                                 node->name, node->handle, buf,
3924
3635
                                 offset_low, offset_high,
3925
 
                                 page_size * n_pages,
 
3636
                                 UNIV_PAGE_SIZE * n_pages,
3926
3637
                                 NULL, NULL);
3927
3638
#endif
3928
3639
                if (success) {
3935
3646
                        how much we were able to extend it */
3936
3647
 
3937
3648
                        n_pages = ((ulint)
3938
 
                                   (os_file_get_size_as_iblonglong(
3939
 
                                           node->handle)
3940
 
                                    / page_size)) - node->size;
 
3649
                                   (os_file_get_size_as_iblonglong
 
3650
                                    (node->handle)
 
3651
                                    / UNIV_PAGE_SIZE)) - node->size;
3941
3652
 
3942
3653
                        node->size += n_pages;
3943
3654
                        space->size += n_pages;
3956
3667
 
3957
3668
#ifndef UNIV_HOTBACKUP
3958
3669
        if (space_id == 0) {
3959
 
                ulint pages_per_mb = (1024 * 1024) / page_size;
 
3670
                ulint pages_per_mb = (1024 * 1024) / UNIV_PAGE_SIZE;
3960
3671
 
3961
3672
                /* Keep the last data file size info up to date, rounded to
3962
3673
                full megabytes */
3982
3693
ibbackup --apply-log phase we extended the spaces on-demand so that log records
3983
3694
could be applied, but that may have left spaces still too small compared to
3984
3695
the size stored in the space header. */
3985
 
UNIV_INTERN
 
3696
 
3986
3697
void
3987
3698
fil_extend_tablespaces_to_stored_len(void)
3988
3699
/*======================================*/
4007
3718
                mutex_exit(&(system->mutex)); /* no need to protect with a
4008
3719
                                              mutex, because this is a
4009
3720
                                              single-threaded operation */
4010
 
                error = fil_read(TRUE, space->id, space->zip_size,
4011
 
                                 0, 0, UNIV_PAGE_SIZE, buf, NULL);
 
3721
                error = fil_read(TRUE, space->id, 0, 0, UNIV_PAGE_SIZE, buf,
 
3722
                                 NULL);
4012
3723
                ut_a(error == DB_SUCCESS);
4013
3724
 
4014
3725
                size_in_header = fsp_get_size_low(buf);
4043
3754
 
4044
3755
/***********************************************************************
4045
3756
Tries to reserve free extents in a file space. */
4046
 
UNIV_INTERN
 
3757
 
4047
3758
ibool
4048
3759
fil_space_reserve_free_extents(
4049
3760
/*===========================*/
4060
3771
 
4061
3772
        mutex_enter(&(system->mutex));
4062
3773
 
4063
 
        space = fil_space_get_by_id(id);
 
3774
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
4064
3775
 
4065
3776
        ut_a(space);
4066
3777
 
4078
3789
 
4079
3790
/***********************************************************************
4080
3791
Releases free extents in a file space. */
4081
 
UNIV_INTERN
 
3792
 
4082
3793
void
4083
3794
fil_space_release_free_extents(
4084
3795
/*===========================*/
4092
3803
 
4093
3804
        mutex_enter(&(system->mutex));
4094
3805
 
4095
 
        space = fil_space_get_by_id(id);
 
3806
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
4096
3807
 
4097
3808
        ut_a(space);
4098
3809
        ut_a(space->n_reserved_extents >= n_reserved);
4105
3816
/***********************************************************************
4106
3817
Gets the number of reserved extents. If the database is silent, this number
4107
3818
should be zero. */
4108
 
UNIV_INTERN
 
3819
 
4109
3820
ulint
4110
3821
fil_space_get_n_reserved_extents(
4111
3822
/*=============================*/
4119
3830
 
4120
3831
        mutex_enter(&(system->mutex));
4121
3832
 
4122
 
        space = fil_space_get_by_id(id);
 
3833
        HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
4123
3834
 
4124
3835
        ut_a(space);
4125
3836
 
4249
3960
 
4250
3961
/************************************************************************
4251
3962
Reads or writes data. This operation is asynchronous (aio). */
4252
 
UNIV_INTERN
 
3963
 
4253
3964
ulint
4254
3965
fil_io(
4255
3966
/*===*/
4267
3978
                                caution! */
4268
3979
        ibool   sync,           /* in: TRUE if synchronous aio is desired */
4269
3980
        ulint   space_id,       /* in: space id */
4270
 
        ulint   zip_size,       /* in: compressed page size in bytes;
4271
 
                                0 for uncompressed pages */
4272
3981
        ulint   block_offset,   /* in: offset in number of blocks */
4273
3982
        ulint   byte_offset,    /* in: remainder of offset in bytes; in
4274
3983
                                aio this must be divisible by the OS block
4299
4008
        type = type & ~OS_AIO_SIMULATED_WAKE_LATER;
4300
4009
 
4301
4010
        ut_ad(byte_offset < UNIV_PAGE_SIZE);
4302
 
        ut_ad(!zip_size || !byte_offset);
4303
 
        ut_ad(ut_is_2pow(zip_size));
4304
4011
        ut_ad(buf);
4305
4012
        ut_ad(len > 0);
4306
 
#if (1 << UNIV_PAGE_SIZE_SHIFT) != UNIV_PAGE_SIZE
4307
 
# error "(1 << UNIV_PAGE_SIZE_SHIFT) != UNIV_PAGE_SIZE"
4308
 
#endif
 
4013
        ut_a((1 << UNIV_PAGE_SIZE_SHIFT) == UNIV_PAGE_SIZE);
4309
4014
        ut_ad(fil_validate());
4310
4015
#ifndef UNIV_LOG_DEBUG
4311
4016
        /* ibuf bitmap pages must be read in the sync aio mode: */
4312
4017
        ut_ad(recv_no_ibuf_operations || (type == OS_FILE_WRITE)
4313
 
              || !ibuf_bitmap_page(zip_size, block_offset)
4314
 
              || sync || is_log);
 
4018
              || !ibuf_bitmap_page(block_offset) || sync || is_log);
4315
4019
#ifdef UNIV_SYNC_DEBUG
4316
4020
        ut_ad(!ibuf_inside() || is_log || (type == OS_FILE_WRITE)
4317
 
              || ibuf_page(space_id, zip_size, block_offset));
 
4021
              || ibuf_page(space_id, block_offset));
4318
4022
#endif
4319
4023
#endif
4320
4024
        if (sync) {
4321
4025
                mode = OS_AIO_SYNC;
4322
4026
        } else if (type == OS_FILE_READ && !is_log
4323
 
                   && ibuf_page(space_id, zip_size, block_offset)) {
 
4027
                   && ibuf_page(space_id, block_offset)) {
4324
4028
                mode = OS_AIO_IBUF;
4325
4029
        } else if (is_log) {
4326
4030
                mode = OS_AIO_LOG;
4339
4043
 
4340
4044
        fil_mutex_enter_and_prepare_for_io(space_id);
4341
4045
 
4342
 
        space = fil_space_get_by_id(space_id);
4343
 
 
 
4046
        HASH_SEARCH(hash, system->spaces, space_id, space,
 
4047
                    space->id == space_id);
4344
4048
        if (!space) {
4345
4049
                mutex_exit(&(system->mutex));
4346
4050
 
4361
4065
        node = UT_LIST_GET_FIRST(space->chain);
4362
4066
 
4363
4067
        for (;;) {
4364
 
                if (UNIV_UNLIKELY(node == NULL)) {
 
4068
                if (node == NULL) {
4365
4069
                        fil_report_invalid_page_access(
4366
4070
                                block_offset, space_id, space->name,
4367
4071
                                byte_offset, len, type);
4390
4094
 
4391
4095
        /* Check that at least the start offset is within the bounds of a
4392
4096
        single-table tablespace */
4393
 
        if (UNIV_UNLIKELY(node->size <= block_offset)
4394
 
            && space->id != 0 && space->purpose == FIL_TABLESPACE) {
 
4097
        if (space->purpose == FIL_TABLESPACE && space->id != 0
 
4098
            && node->size <= block_offset) {
4395
4099
 
4396
4100
                fil_report_invalid_page_access(
4397
4101
                        block_offset, space_id, space->name, byte_offset,
4405
4109
 
4406
4110
        /* Calculate the low 32 bits and the high 32 bits of the file offset */
4407
4111
 
4408
 
        if (!zip_size) {
4409
 
                offset_high = (block_offset >> (32 - UNIV_PAGE_SIZE_SHIFT));
4410
 
                offset_low  = ((block_offset << UNIV_PAGE_SIZE_SHIFT)
4411
 
                               & 0xFFFFFFFFUL) + byte_offset;
 
4112
        offset_high = (block_offset >> (32 - UNIV_PAGE_SIZE_SHIFT));
 
4113
        offset_low  = ((block_offset << UNIV_PAGE_SIZE_SHIFT) & 0xFFFFFFFFUL)
 
4114
                + byte_offset;
4412
4115
 
4413
 
                ut_a(node->size - block_offset
4414
 
                     >= ((byte_offset + len + (UNIV_PAGE_SIZE - 1))
4415
 
                         / UNIV_PAGE_SIZE));
4416
 
        } else {
4417
 
                ulint   zip_size_shift;
4418
 
                switch (zip_size) {
4419
 
                case 1024: zip_size_shift = 10; break;
4420
 
                case 2048: zip_size_shift = 11; break;
4421
 
                case 4096: zip_size_shift = 12; break;
4422
 
                case 8192: zip_size_shift = 13; break;
4423
 
                case 16384: zip_size_shift = 14; break;
4424
 
                default: ut_error;
4425
 
                }
4426
 
                offset_high = block_offset >> (32 - zip_size_shift);
4427
 
                offset_low = (block_offset << zip_size_shift & 0xFFFFFFFFUL)
4428
 
                        + byte_offset;
4429
 
                ut_a(node->size - block_offset
4430
 
                     >= (len + (zip_size - 1)) / zip_size);
4431
 
        }
 
4116
        ut_a(node->size - block_offset
 
4117
             >= (byte_offset + len + (UNIV_PAGE_SIZE - 1)) / UNIV_PAGE_SIZE);
4432
4118
 
4433
4119
        /* Do aio */
4434
4120
 
4467
4153
        return(DB_SUCCESS);
4468
4154
}
4469
4155
 
 
4156
/************************************************************************
 
4157
Reads data from a space to a buffer. Remember that the possible incomplete
 
4158
blocks at the end of file are ignored: they are not taken into account when
 
4159
calculating the byte offset within a space. */
 
4160
 
 
4161
ulint
 
4162
fil_read(
 
4163
/*=====*/
 
4164
                                /* out: DB_SUCCESS, or DB_TABLESPACE_DELETED
 
4165
                                if we are trying to do i/o on a tablespace
 
4166
                                which does not exist */
 
4167
        ibool   sync,           /* in: TRUE if synchronous aio is desired */
 
4168
        ulint   space_id,       /* in: space id */
 
4169
        ulint   block_offset,   /* in: offset in number of blocks */
 
4170
        ulint   byte_offset,    /* in: remainder of offset in bytes; in aio
 
4171
                                this must be divisible by the OS block size */
 
4172
        ulint   len,            /* in: how many bytes to read; this must not
 
4173
                                cross a file boundary; in aio this must be a
 
4174
                                block size multiple */
 
4175
        void*   buf,            /* in/out: buffer where to store data read;
 
4176
                                in aio this must be appropriately aligned */
 
4177
        void*   message)        /* in: message for aio handler if non-sync
 
4178
                                aio used, else ignored */
 
4179
{
 
4180
        return(fil_io(OS_FILE_READ, sync, space_id, block_offset,
 
4181
                      byte_offset, len, buf, message));
 
4182
}
 
4183
 
 
4184
/************************************************************************
 
4185
Writes data to a space from a buffer. Remember that the possible incomplete
 
4186
blocks at the end of file are ignored: they are not taken into account when
 
4187
calculating the byte offset within a space. */
 
4188
 
 
4189
ulint
 
4190
fil_write(
 
4191
/*======*/
 
4192
                                /* out: DB_SUCCESS, or DB_TABLESPACE_DELETED
 
4193
                                if we are trying to do i/o on a tablespace
 
4194
                                which does not exist */
 
4195
        ibool   sync,           /* in: TRUE if synchronous aio is desired */
 
4196
        ulint   space_id,       /* in: space id */
 
4197
        ulint   block_offset,   /* in: offset in number of blocks */
 
4198
        ulint   byte_offset,    /* in: remainder of offset in bytes; in aio
 
4199
                                this must be divisible by the OS block size */
 
4200
        ulint   len,            /* in: how many bytes to write; this must
 
4201
                                not cross a file boundary; in aio this must
 
4202
                                be a block size multiple */
 
4203
        void*   buf,            /* in: buffer from which to write; in aio
 
4204
                                this must be appropriately aligned */
 
4205
        void*   message)        /* in: message for aio handler if non-sync
 
4206
                                aio used, else ignored */
 
4207
{
 
4208
        return(fil_io(OS_FILE_WRITE, sync, space_id, block_offset,
 
4209
                      byte_offset, len, buf, message));
 
4210
}
 
4211
 
4470
4212
/**************************************************************************
4471
4213
Waits for an aio operation to complete. This function is used to write the
4472
4214
handler for completed requests. The aio array of pending requests is divided
4473
4215
into segments (see os0file.c for more info). The thread specifies which
4474
4216
segment it wants to wait for. */
4475
 
UNIV_INTERN
 
4217
 
4476
4218
void
4477
4219
fil_aio_wait(
4478
4220
/*=========*/
4523
4265
        deadlocks in the i/o system. We keep tablespace 0 data files always
4524
4266
        open, and use a special i/o thread to serve insert buffer requests. */
4525
4267
 
4526
 
        if (fil_node->space->purpose == FIL_TABLESPACE) {
 
4268
        if (buf_pool_is_block(message)) {
4527
4269
                srv_set_io_thread_op_info(segment, "complete io for buf page");
4528
4270
                buf_page_io_complete(message);
4529
4271
        } else {
4535
4277
/**************************************************************************
4536
4278
Flushes to disk possible writes cached by the OS. If the space does not exist
4537
4279
or is being dropped, does not do anything. */
4538
 
UNIV_INTERN
 
4280
 
4539
4281
void
4540
4282
fil_flush(
4541
4283
/*======*/
4546
4288
        fil_space_t*    space;
4547
4289
        fil_node_t*     node;
4548
4290
        os_file_t       file;
4549
 
        ib_int64_t      old_mod_counter;
 
4291
        ib_longlong     old_mod_counter;
4550
4292
 
4551
4293
        mutex_enter(&(system->mutex));
4552
4294
 
4553
 
        space = fil_space_get_by_id(space_id);
4554
 
 
 
4295
        HASH_SEARCH(hash, system->spaces, space_id, space,
 
4296
                    space->id == space_id);
4555
4297
        if (!space || space->is_being_deleted) {
4556
4298
                mutex_exit(&(system->mutex));
4557
4299
 
4651
4393
/**************************************************************************
4652
4394
Flushes to disk the writes in file spaces of the given type possibly cached by
4653
4395
the OS. */
4654
 
UNIV_INTERN
 
4396
 
4655
4397
void
4656
4398
fil_flush_file_spaces(
4657
4399
/*==================*/
4704
4446
 
4705
4447
/**********************************************************************
4706
4448
Checks the consistency of the tablespace cache. */
4707
 
UNIV_INTERN
 
4449
 
4708
4450
ibool
4709
4451
fil_validate(void)
4710
4452
/*==============*/
4765
4507
 
4766
4508
/************************************************************************
4767
4509
Returns TRUE if file address is undefined. */
4768
 
UNIV_INTERN
4769
4510
ibool
4770
4511
fil_addr_is_null(
4771
4512
/*=============*/
4772
4513
                                /* out: TRUE if undefined */
4773
4514
        fil_addr_t      addr)   /* in: address */
4774
4515
{
4775
 
        return(addr.page == FIL_NULL);
 
4516
        if (addr.page == FIL_NULL) {
 
4517
 
 
4518
                return(TRUE);
 
4519
        }
 
4520
 
 
4521
        return(FALSE);
4776
4522
}
4777
4523
 
4778
4524
/************************************************************************
4779
4525
Accessor functions for a file page */
4780
 
UNIV_INTERN
 
4526
 
4781
4527
ulint
4782
 
fil_page_get_prev(const byte*   page)
 
4528
fil_page_get_prev(byte* page)
4783
4529
{
4784
4530
        return(mach_read_from_4(page + FIL_PAGE_PREV));
4785
4531
}
4786
4532
 
4787
 
UNIV_INTERN
4788
4533
ulint
4789
 
fil_page_get_next(const byte*   page)
 
4534
fil_page_get_next(byte* page)
4790
4535
{
4791
4536
        return(mach_read_from_4(page + FIL_PAGE_NEXT));
4792
4537
}
4793
4538
 
4794
4539
/*************************************************************************
4795
4540
Sets the file page type. */
4796
 
UNIV_INTERN
 
4541
 
4797
4542
void
4798
4543
fil_page_set_type(
4799
4544
/*==============*/
4807
4552
 
4808
4553
/*************************************************************************
4809
4554
Gets the file page type. */
4810
 
UNIV_INTERN
 
4555
 
4811
4556
ulint
4812
4557
fil_page_get_type(
4813
4558
/*==============*/
4814
 
                                /* out: type; NOTE that if the type
4815
 
                                has not been written to page, the return value
4816
 
                                not defined */
4817
 
        const byte*     page)   /* in: file page */
 
4559
                        /* out: type; NOTE that if the type has not been
 
4560
                        written to page, the return value not defined */
 
4561
        byte*   page)   /* in: file page */
4818
4562
{
4819
4563
        ut_ad(page);
4820
4564