~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Brian Aker
  • Date: 2008-11-04 15:39:09 UTC
  • mfrom: (575.1.2 devel)
  • Revision ID: brian@tangent.org-20081104153909-c72hn65udxs1ccal
Merge of Monty's work

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