60
60
about the first extent, but have not
61
61
physically allocted those pages to the
63
#define FSP_LOWEST_NO_WRITE 16 /* The lowest page offset for which
64
the page has not been written to disk
65
(if it has been written, we know that
66
the OS has really reserved the
67
physical space for the page) */
63
#define FSP_SPACE_FLAGS 16 /* table->flags & ~DICT_TF_COMPACT */
68
64
#define FSP_FRAG_N_USED 20 /* number of used pages in the
69
65
FSP_FREE_FRAG list */
70
66
#define FSP_FREE 24 /* list of free extents */
293
299
/* out: the allocated page number, FIL_NULL
294
300
if no page could be allocated */
295
301
ulint space, /* in: space */
302
ulint zip_size,/* in: compressed page size in bytes
303
or 0 for uncompressed pages */
296
304
fseg_inode_t* seg_inode, /* in: segment inode */
297
305
ulint hint, /* in: hint of which page would be desirable */
298
306
byte direction, /* in: if the new page is needed because
323
331
/*=================*/
324
332
/* out: pointer to the space header, page x-locked */
325
333
ulint id, /* in: space id */
334
ulint zip_size,/* in: compressed page size in bytes
335
or 0 for uncompressed pages */
326
336
mtr_t* mtr) /* in: mtr */
328
339
fsp_header_t* header;
341
ut_ad(ut_is_2pow(zip_size));
342
ut_ad(zip_size <= UNIV_PAGE_SIZE);
343
ut_ad(!zip_size || zip_size >= PAGE_ZIP_MIN_SIZE);
344
ut_ad(id || !zip_size);
332
header = FSP_HEADER_OFFSET + buf_page_get(id, 0, RW_X_LATCH, mtr);
346
block = buf_page_get(id, zip_size, 0, RW_X_LATCH, mtr);
347
header = FSP_HEADER_OFFSET + buf_block_get_frame(block);
333
348
#ifdef UNIV_SYNC_DEBUG
334
buf_page_dbg_add_level(header, SYNC_FSP_PAGE);
349
buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
335
350
#endif /* UNIV_SYNC_DEBUG */
351
ut_ad(id == mach_read_from_4(FSP_SPACE_ID + header));
352
ut_ad(zip_size == dict_table_flags_to_zip_size(
353
mach_read_from_4(FSP_SPACE_FLAGS + header)));
573
585
xdes_t* descr, /* in: descriptor */
574
586
mtr_t* mtr) /* in: mtr handle */
576
590
ut_ad(descr && mtr);
577
ut_ad(mtr_memo_contains(mtr, buf_block_align(descr),
578
MTR_MEMO_PAGE_X_FIX));
591
ut_ad(mtr_memo_contains_page(mtr, descr, MTR_MEMO_PAGE_X_FIX));
580
return(mtr_read_ulint(descr + XDES_STATE, MLOG_4BYTES, mtr));
593
state = mtr_read_ulint(descr + XDES_STATE, MLOG_4BYTES, mtr);
594
ut_ad(state - 1 < XDES_FSEG);
583
598
/**************************************************************************
610
624
xdes_calc_descriptor_page(
611
625
/*======================*/
612
626
/* out: descriptor page offset */
627
ulint zip_size, /* in: compressed page size in bytes;
628
0 for uncompressed pages */
613
629
ulint offset) /* in: page offset */
615
631
#if UNIV_PAGE_SIZE <= XDES_ARR_OFFSET \
616
+ (XDES_DESCRIBED_PER_PAGE / FSP_EXTENT_SIZE) * XDES_SIZE
632
+ (UNIV_PAGE_SIZE / FSP_EXTENT_SIZE) * XDES_SIZE
635
#if PAGE_ZIP_MIN_SIZE <= XDES_ARR_OFFSET \
636
+ (PAGE_ZIP_MIN_SIZE / FSP_EXTENT_SIZE) * XDES_SIZE
639
ut_ad(ut_is_2pow(zip_size));
620
return(ut_2pow_round(offset, XDES_DESCRIBED_PER_PAGE));
642
return(ut_2pow_round(offset, UNIV_PAGE_SIZE));
644
ut_ad(zip_size > XDES_ARR_OFFSET
645
+ (zip_size / FSP_EXTENT_SIZE) * XDES_SIZE);
646
return(ut_2pow_round(offset, zip_size));
623
650
/************************************************************************
627
654
xdes_calc_descriptor_index(
628
655
/*=======================*/
629
656
/* out: descriptor index */
657
ulint zip_size, /* in: compressed page size in bytes;
658
0 for uncompressed pages */
630
659
ulint offset) /* in: page offset */
632
return(ut_2pow_remainder(offset, XDES_DESCRIBED_PER_PAGE)
661
ut_ad(ut_is_2pow(zip_size));
664
return(ut_2pow_remainder(offset, UNIV_PAGE_SIZE)
667
return(ut_2pow_remainder(offset, zip_size) / FSP_EXTENT_SIZE);
636
671
/************************************************************************
659
695
ulint descr_page_no;
660
696
page_t* descr_page;
663
ut_ad(mtr_memo_contains(mtr, fil_space_get_latch(space),
699
ut_ad(mtr_memo_contains(mtr, fil_space_get_latch(space, NULL),
664
700
MTR_MEMO_X_LOCK));
701
ut_ad(mtr_memo_contains_page(mtr, sp_header, MTR_MEMO_PAGE_S_FIX)
702
|| mtr_memo_contains_page(mtr, sp_header, MTR_MEMO_PAGE_X_FIX));
665
703
/* Read free limit and space size */
666
limit = mtr_read_ulint(sp_header + FSP_FREE_LIMIT, MLOG_4BYTES, mtr);
667
size = mtr_read_ulint(sp_header + FSP_SIZE, MLOG_4BYTES, mtr);
704
limit = mach_read_from_4(sp_header + FSP_FREE_LIMIT);
705
size = mach_read_from_4(sp_header + FSP_SIZE);
706
zip_size = dict_table_flags_to_zip_size(
707
mach_read_from_4(sp_header + FSP_SPACE_FLAGS));
669
709
/* If offset is >= size or > limit, return NULL */
679
719
fsp_fill_free_list(FALSE, space, sp_header, mtr);
682
descr_page_no = xdes_calc_descriptor_page(offset);
722
descr_page_no = xdes_calc_descriptor_page(zip_size, offset);
684
724
if (descr_page_no == 0) {
685
725
/* It is on the space header page */
687
descr_page = buf_frame_align(sp_header);
727
descr_page = page_align(sp_header);
689
descr_page = buf_page_get(space, descr_page_no, RW_X_LATCH,
731
block = buf_page_get(space, zip_size, descr_page_no,
691
733
#ifdef UNIV_SYNC_DEBUG
692
buf_page_dbg_add_level(descr_page, SYNC_FSP_PAGE);
734
buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
693
735
#endif /* UNIV_SYNC_DEBUG */
736
descr_page = buf_block_get_frame(block);
696
739
return(descr_page + XDES_ARR_OFFSET
697
+ XDES_SIZE * xdes_calc_descriptor_index(offset));
740
+ XDES_SIZE * xdes_calc_descriptor_index(zip_size, offset));
700
743
/************************************************************************
712
755
page does not exist in the space or if offset > free
714
757
ulint space, /* in: space id */
758
ulint zip_size,/* in: compressed page size in bytes
759
or 0 for uncompressed pages */
715
760
ulint offset, /* in: page offset; if equal to the free limit,
716
761
we try to add new extents to the space free list */
717
762
mtr_t* mtr) /* in: mtr handle */
719
765
fsp_header_t* sp_header;
721
sp_header = FSP_HEADER_OFFSET
722
+ buf_page_get(space, 0, RW_X_LATCH, mtr);
767
block = buf_page_get(space, zip_size, 0, RW_X_LATCH, mtr);
723
768
#ifdef UNIV_SYNC_DEBUG
724
buf_page_dbg_add_level(sp_header, SYNC_FSP_PAGE);
769
buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
725
770
#endif /* UNIV_SYNC_DEBUG */
771
sp_header = FSP_HEADER_OFFSET + buf_block_get_frame(block);
726
772
return(xdes_get_descriptor_with_space_hdr(sp_header, space, offset,
747
ut_ad(mtr_memo_contains(mtr, fil_space_get_latch(space),
795
ut_ad(mtr_memo_contains(mtr, fil_space_get_latch(space, NULL),
748
796
MTR_MEMO_X_LOCK));
749
descr = fut_get_ptr(space, lst_node, RW_X_LATCH, mtr) - XDES_FLST_NODE;
797
descr = fut_get_ptr(space, zip_size, lst_node, RW_X_LATCH, mtr)
754
803
/************************************************************************
755
Gets pointer to the next descriptor in a descriptor list and x-locks its
761
xdes_t* descr, /* in: pointer to a descriptor */
762
mtr_t* mtr) /* in: mtr handle */
768
space = buf_frame_get_space_id(descr);
770
return(xdes_lst_get_descriptor(
772
flst_get_next_addr(descr + XDES_FLST_NODE, mtr), mtr));
775
/************************************************************************
776
804
Returns page offset of the first page in extent described by a descriptor. */
796
823
fsp_init_file_page_low(
797
824
/*===================*/
798
byte* ptr) /* in: pointer to a page */
825
buf_block_t* block) /* in: pointer to a page */
801
page = buf_frame_align(ptr);
803
buf_block_align(page)->check_index_page_at_flush = FALSE;
827
page_t* page = buf_block_get_frame(block);
828
page_zip_des_t* page_zip= buf_block_get_page_zip(block);
830
block->check_index_page_at_flush = FALSE;
832
if (UNIV_LIKELY_NULL(page_zip)) {
833
memset(page, 0, UNIV_PAGE_SIZE);
834
memset(page_zip->data, 0, page_zip_get_size(page_zip));
835
mach_write_to_4(page + FIL_PAGE_OFFSET,
836
buf_block_get_page_no(block));
838
+ FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID,
839
buf_block_get_space(block));
840
memcpy(page_zip->data + FIL_PAGE_OFFSET,
841
page + FIL_PAGE_OFFSET, 4);
842
memcpy(page_zip->data + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID,
843
page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, 4);
805
847
#ifdef UNIV_BASIC_LOG_DEBUG
806
848
memset(page, 0xff, UNIV_PAGE_SIZE);
808
mach_write_to_8(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM,
810
mach_write_to_8(page + FIL_PAGE_LSN, ut_dulint_zero);
850
mach_write_to_4(page + FIL_PAGE_OFFSET, buf_block_get_page_no(block));
851
memset(page + FIL_PAGE_LSN, 0, 8);
852
mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID,
853
buf_block_get_space(block));
854
memset(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM, 0, 8);
813
857
/***************************************************************
817
861
fsp_init_file_page(
818
862
/*===============*/
819
page_t* page, /* in: page */
820
mtr_t* mtr) /* in: mtr */
863
buf_block_t* block, /* in: pointer to a page */
864
mtr_t* mtr) /* in: mtr */
822
fsp_init_file_page_low(page);
866
fsp_init_file_page_low(block);
824
mlog_write_initial_log_record(page, MLOG_INIT_FILE_PAGE, mtr);
868
mlog_write_initial_log_record(buf_block_get_frame(block),
869
MLOG_INIT_FILE_PAGE, mtr);
827
872
/***************************************************************
828
873
Parses a redo log record of a file page init. */
831
876
fsp_parse_init_file_page(
832
877
/*=====================*/
833
/* out: end of log record or NULL */
834
byte* ptr, /* in: buffer */
835
byte* end_ptr __attribute__((unused)), /* in: buffer end */
836
page_t* page) /* in: page or NULL */
878
/* out: end of log record or NULL */
879
byte* ptr, /* in: buffer */
880
byte* end_ptr __attribute__((unused)), /* in: buffer end */
881
buf_block_t* block) /* in: block or NULL */
838
883
ut_ad(ptr && end_ptr);
841
fsp_init_file_page_low(page);
886
fsp_init_file_page_low(block);
857
902
/**************************************************************************
858
Writes the space id to a tablespace header. This function is used past the
859
buffer pool when we in fil0fil.c create a new single-table tablespace. */
903
Writes the space id and compressed page size to a tablespace header.
904
This function is used past the buffer pool when we in fil0fil.c create
905
a new single-table tablespace. */
862
fsp_header_write_space_id(
863
/*======================*/
864
page_t* page, /* in: first page in the space */
865
ulint space_id) /* in: space id */
908
fsp_header_init_fields(
909
/*===================*/
910
page_t* page, /* in/out: first page in the space */
911
ulint space_id, /* in: space id */
912
ulint flags) /* in: tablespace flags (FSP_SPACE_FLAGS):
913
0, or table->flags if newer than COMPACT */
867
mach_write_to_4(page + FSP_HEADER_OFFSET + FSP_SPACE_ID, space_id);
915
/* The tablespace flags (FSP_SPACE_FLAGS) should be 0 for
916
ROW_FORMAT=COMPACT (table->flags == DICT_TF_COMPACT) and
917
ROW_FORMAT=REDUNDANT (table->flags == 0). For any other
918
format, the tablespace flags should equal table->flags. */
919
ut_a(flags != DICT_TF_COMPACT);
921
mach_write_to_4(FSP_HEADER_OFFSET + FSP_SPACE_ID + page,
923
mach_write_to_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page,
870
927
/**************************************************************************
871
928
Initializes the space header of a new created space and creates also the
872
929
insert buffer tree root if space == 0. */
877
ulint space, /* in: space id */
878
ulint size, /* in: current size in blocks */
879
mtr_t* mtr) /* in: mini-transaction handle */
934
ulint space, /* in: space id */
935
ulint size, /* in: current size in blocks */
936
mtr_t* mtr) /* in: mini-transaction handle */
881
938
fsp_header_t* header;
886
mtr_x_lock(fil_space_get_latch(space), mtr);
946
mtr_x_lock(fil_space_get_latch(space, &flags), mtr);
888
page = buf_page_create(space, 0, mtr);
889
buf_page_get(space, 0, RW_X_LATCH, mtr);
948
zip_size = dict_table_flags_to_zip_size(flags);
949
block = buf_page_create(space, 0, zip_size, mtr);
950
buf_page_get(space, zip_size, 0, RW_X_LATCH, mtr);
890
951
#ifdef UNIV_SYNC_DEBUG
891
buf_page_dbg_add_level(page, SYNC_FSP_PAGE);
952
buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
892
953
#endif /* UNIV_SYNC_DEBUG */
894
955
/* The prior contents of the file page should be ignored */
896
fsp_init_file_page(page, mtr);
957
fsp_init_file_page(block, mtr);
958
page = buf_block_get_frame(block);
898
960
mlog_write_ulint(page + FIL_PAGE_TYPE, FIL_PAGE_TYPE_FSP_HDR,
899
961
MLOG_2BYTES, mtr);
906
968
mlog_write_ulint(header + FSP_SIZE, size, MLOG_4BYTES, mtr);
907
969
mlog_write_ulint(header + FSP_FREE_LIMIT, 0, MLOG_4BYTES, mtr);
908
mlog_write_ulint(header + FSP_LOWEST_NO_WRITE, 0, MLOG_4BYTES, mtr);
970
mlog_write_ulint(header + FSP_SPACE_FLAGS, flags,
909
972
mlog_write_ulint(header + FSP_FRAG_N_USED, 0, MLOG_4BYTES, mtr);
911
974
flst_init(header + FSP_FREE, mtr);
917
980
mlog_write_dulint(header + FSP_SEG_ID, ut_dulint_create(0, 1), mtr);
918
981
if (space == 0) {
919
982
fsp_fill_free_list(FALSE, space, header, mtr);
920
btr_create(DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF, space,
921
ut_dulint_add(DICT_IBUF_ID_MIN, space), FALSE, mtr);
983
btr_create(DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF,
984
0, 0, ut_dulint_add(DICT_IBUF_ID_MIN, space),
985
srv_sys->dummy_ind1, mtr);
923
987
fsp_fill_free_list(TRUE, space, header, mtr);
955
1019
/**************************************************************************
1020
Reads the space flags from the first page of a tablespace. */
1023
fsp_header_get_flags(
1024
/*=================*/
1026
const page_t* page) /* in: first page of a tablespace */
1028
ut_ad(!page_offset(page));
1030
return(mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page));
1033
/**************************************************************************
1034
Reads the compressed page size from the first page of a tablespace. */
1037
fsp_header_get_zip_size(
1038
/*====================*/
1039
/* out: compressed page size in bytes,
1040
or 0 if uncompressed */
1041
const page_t* page) /* in: first page of a tablespace */
1043
ulint flags = fsp_header_get_flags(page);
1045
return(dict_table_flags_to_zip_size(flags));
1048
/**************************************************************************
956
1049
Increases the space size field of a space. */
959
1052
fsp_header_inc_size(
960
1053
/*================*/
980
1076
/**************************************************************************
981
Gets the current free limit of a tablespace. The free limit means the
982
place of the first page which has never been put to the the free list
983
for allocation. The space above that address is initialized to zero.
984
Sets also the global variable log_fsp_current_free_limit. */
1077
Gets the current free limit of the system tablespace. The free limit
1078
means the place of the first page which has never been put to the the
1079
free list for allocation. The space above that address is initialized
1080
to zero. Sets also the global variable log_fsp_current_free_limit. */
987
fsp_header_get_free_limit(
988
/*======================*/
1083
fsp_header_get_free_limit(void)
1084
/*===========================*/
989
1085
/* out: free limit in megabytes */
990
ulint space) /* in: space id, must be 0 */
992
1087
fsp_header_t* header;
996
ut_a(space == 0); /* We have only one log_fsp_current_... variable */
998
1091
mtr_start(&mtr);
1000
mtr_x_lock(fil_space_get_latch(space), &mtr);
1093
mtr_x_lock(fil_space_get_latch(0, NULL), &mtr);
1002
header = fsp_get_space_header(space, &mtr);
1095
header = fsp_get_space_header(0, 0, &mtr);
1004
1097
limit = mtr_read_ulint(header + FSP_FREE_LIMIT, MLOG_4BYTES, &mtr);
1006
limit = limit / ((1024 * 1024) / UNIV_PAGE_SIZE);
1099
limit /= ((1024 * 1024) / UNIV_PAGE_SIZE);
1008
1101
log_fsp_current_free_limit_set_and_checkpoint(limit);
1015
1108
/**************************************************************************
1016
Gets the size of the tablespace from the tablespace header. If we do not
1017
have an auto-extending data file, this should be equal to the size of the
1018
data files. If there is an auto-extending data file, this can be smaller. */
1109
Gets the size of the system tablespace from the tablespace header. If
1110
we do not have an auto-extending data file, this should be equal to
1111
the size of the data files. If there is an auto-extending data file,
1112
this can be smaller. */
1021
fsp_header_get_tablespace_size(
1022
/*===========================*/
1115
fsp_header_get_tablespace_size(void)
1116
/*================================*/
1023
1117
/* out: size in pages */
1024
ulint space) /* in: space id, must be 0 */
1026
1119
fsp_header_t* header;
1030
ut_a(space == 0); /* We have only one log_fsp_current_... variable */
1032
1123
mtr_start(&mtr);
1034
mtr_x_lock(fil_space_get_latch(space), &mtr);
1125
mtr_x_lock(fil_space_get_latch(0, NULL), &mtr);
1036
header = fsp_get_space_header(space, &mtr);
1127
header = fsp_get_space_header(0, 0, &mtr);
1038
1129
size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, &mtr);
1108
1200
size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, mtr);
1201
zip_size = dict_table_flags_to_zip_size(
1202
mach_read_from_4(header + FSP_SPACE_FLAGS));
1110
1204
old_size = size;
1112
if (space == 0 && srv_last_file_size_max != 0) {
1113
if (srv_last_file_size_max
1114
< srv_data_file_sizes[srv_n_data_files - 1]) {
1117
"InnoDB: Error: Last data file size is %lu,"
1118
" max size allowed %lu\n",
1119
(ulong) srv_data_file_sizes[
1120
srv_n_data_files - 1],
1121
(ulong) srv_last_file_size_max);
1124
size_increase = srv_last_file_size_max
1125
- srv_data_file_sizes[srv_n_data_files - 1];
1126
if (size_increase > SRV_AUTO_EXTEND_INCREMENT) {
1207
if (!srv_last_file_size_max) {
1127
1208
size_increase = SRV_AUTO_EXTEND_INCREMENT;
1210
if (srv_last_file_size_max
1211
< srv_data_file_sizes[srv_n_data_files - 1]) {
1214
"InnoDB: Error: Last data file size"
1215
" is %lu, max size allowed %lu\n",
1216
(ulong) srv_data_file_sizes[
1217
srv_n_data_files - 1],
1218
(ulong) srv_last_file_size_max);
1221
size_increase = srv_last_file_size_max
1222
- srv_data_file_sizes[srv_n_data_files - 1];
1223
if (size_increase > SRV_AUTO_EXTEND_INCREMENT) {
1224
size_increase = SRV_AUTO_EXTEND_INCREMENT;
1131
size_increase = SRV_AUTO_EXTEND_INCREMENT;
1133
/* We extend single-table tablespaces first one extent
1134
at a time, but for bigger tablespaces more. It is not
1135
enough to extend always by one extent, because some
1136
extents are frag page extents. */
1138
if (size < FSP_EXTENT_SIZE) {
1139
/* Let us first extend the file to 64 pages */
1140
success = fsp_try_extend_data_file_with_pages(
1141
space, FSP_EXTENT_SIZE - 1,
1144
new_size = mtr_read_ulint(
1148
*actual_increase = new_size - old_size;
1153
size = FSP_EXTENT_SIZE;
1156
if (size < 32 * FSP_EXTENT_SIZE) {
1157
size_increase = FSP_EXTENT_SIZE;
1159
/* Below in fsp_fill_free_list() we assume
1160
that we add at most FSP_FREE_ADD extents at
1162
size_increase = FSP_FREE_ADD * FSP_EXTENT_SIZE;
1228
/* We extend single-table tablespaces first one extent
1229
at a time, but for bigger tablespaces more. It is not
1230
enough to extend always by one extent, because some
1231
extents are frag page extents. */
1232
ulint extent_size; /* one megabyte, in pages */
1235
extent_size = FSP_EXTENT_SIZE;
1237
extent_size = FSP_EXTENT_SIZE
1238
* UNIV_PAGE_SIZE / zip_size;
1241
if (size < extent_size) {
1242
/* Let us first extend the file to extent_size */
1243
success = fsp_try_extend_data_file_with_pages(
1244
space, extent_size - 1, header, mtr);
1246
new_size = mtr_read_ulint(header + FSP_SIZE,
1249
*actual_increase = new_size - old_size;
1257
if (size < 32 * extent_size) {
1258
size_increase = extent_size;
1260
/* Below in fsp_fill_free_list() we assume
1261
that we add at most FSP_FREE_ADD extents at
1263
size_increase = FSP_FREE_ADD * extent_size;
1174
1274
/* We ignore any fragments of a full megabyte when storing the size
1175
1275
to the space header */
1177
mlog_write_ulint(header + FSP_SIZE,
1178
ut_calc_align_down(actual_size,
1179
(1024 * 1024) / UNIV_PAGE_SIZE),
1181
new_size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, mtr);
1278
new_size = ut_calc_align_down(actual_size,
1279
(1024 * 1024) / UNIV_PAGE_SIZE);
1281
new_size = ut_calc_align_down(actual_size,
1282
(1024 * 1024) / zip_size);
1284
mlog_write_ulint(header + FSP_SIZE, new_size, MLOG_4BYTES, mtr);
1183
1286
*actual_increase = new_size - old_size;
1219
1321
size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, mtr);
1220
1322
limit = mtr_read_ulint(header + FSP_FREE_LIMIT, MLOG_4BYTES, mtr);
1324
zip_size = dict_table_flags_to_zip_size(
1325
mach_read_from_4(FSP_SPACE_FLAGS + header));
1326
ut_a(ut_is_2pow(zip_size));
1327
ut_a(zip_size <= UNIV_PAGE_SIZE);
1328
ut_a(!zip_size || zip_size >= PAGE_ZIP_MIN_SIZE);
1222
1330
if (space == 0 && srv_auto_extend_last_data_file
1223
1331
&& size < limit + FSP_EXTENT_SIZE * FSP_FREE_ADD) {
1240
1348
while ((init_space && i < 1)
1241
1349
|| ((i + FSP_EXTENT_SIZE <= size) && (count < FSP_FREE_ADD))) {
1353
init_xdes = ut_2pow_remainder(i, zip_size) == 0;
1355
init_xdes = ut_2pow_remainder(i, UNIV_PAGE_SIZE) == 0;
1243
1358
mlog_write_ulint(header + FSP_FREE_LIMIT, i + FSP_EXTENT_SIZE,
1244
1359
MLOG_4BYTES, mtr);
1246
1361
/* Update the free limit info in the log system and make
1247
1362
a checkpoint */
1248
1363
if (space == 0) {
1249
1365
log_fsp_current_free_limit_set_and_checkpoint(
1250
1366
(i + FSP_EXTENT_SIZE)
1251
1367
/ ((1024 * 1024) / UNIV_PAGE_SIZE));
1254
if (0 == i % XDES_DESCRIBED_PER_PAGE) {
1370
if (UNIV_UNLIKELY(init_xdes)) {
1256
1374
/* We are going to initialize a new descriptor page
1257
1375
and a new ibuf bitmap page: the prior contents of the
1258
1376
pages should be ignored. */
1261
descr_page = buf_page_create(space, i, mtr);
1262
buf_page_get(space, i, RW_X_LATCH, mtr);
1379
block = buf_page_create(
1380
space, i, zip_size, mtr);
1381
buf_page_get(space, zip_size, i,
1263
1383
#ifdef UNIV_SYNC_DEBUG
1264
buf_page_dbg_add_level(descr_page,
1384
buf_block_dbg_add_level(block,
1266
1386
#endif /* UNIV_SYNC_DEBUG */
1267
fsp_init_file_page(descr_page, mtr);
1268
mlog_write_ulint(descr_page + FIL_PAGE_TYPE,
1387
fsp_init_file_page(block, mtr);
1388
mlog_write_ulint(buf_block_get_frame(block)
1269
1390
FIL_PAGE_TYPE_XDES,
1270
1391
MLOG_2BYTES, mtr);
1278
1399
mtr_start(&ibuf_mtr);
1280
ibuf_page = buf_page_create(space,
1401
block = buf_page_create(space,
1281
1402
i + FSP_IBUF_BITMAP_OFFSET,
1283
buf_page_get(space, i + FSP_IBUF_BITMAP_OFFSET,
1403
zip_size, &ibuf_mtr);
1404
buf_page_get(space, zip_size,
1405
i + FSP_IBUF_BITMAP_OFFSET,
1284
1406
RW_X_LATCH, &ibuf_mtr);
1285
1407
#ifdef UNIV_SYNC_DEBUG
1286
buf_page_dbg_add_level(ibuf_page, SYNC_FSP_PAGE);
1408
buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
1287
1409
#endif /* UNIV_SYNC_DEBUG */
1288
fsp_init_file_page(ibuf_page, &ibuf_mtr);
1410
fsp_init_file_page(block, &ibuf_mtr);
1290
ibuf_bitmap_page_init(ibuf_page, &ibuf_mtr);
1412
ibuf_bitmap_page_init(block, &ibuf_mtr);
1292
1414
mtr_commit(&ibuf_mtr);
1297
1419
xdes_init(descr, mtr);
1299
#if XDES_DESCRIBED_PER_PAGE % FSP_EXTENT_SIZE
1300
# error "XDES_DESCRIBED_PER_PAGE % FSP_EXTENT_SIZE != 0"
1421
#if UNIV_PAGE_SIZE % FSP_EXTENT_SIZE
1422
# error "UNIV_PAGE_SIZE % FSP_EXTENT_SIZE != 0"
1424
#if PAGE_ZIP_MIN_SIZE % FSP_EXTENT_SIZE
1425
# error "PAGE_ZIP_MIN_SIZE % FSP_EXTENT_SIZE != 0"
1303
if (0 == i % XDES_DESCRIBED_PER_PAGE) {
1428
if (UNIV_UNLIKELY(init_xdes)) {
1305
1430
/* The first page in the extent is a descriptor page
1306
1431
and the second is an ibuf bitmap page: mark them
1502
1633
be obtained immediately with buf_page_get without need for a disk
1505
buf_page_create(space, page_no, mtr);
1636
buf_page_create(space, page_no, zip_size, mtr);
1507
page = buf_page_get(space, page_no, RW_X_LATCH, mtr);
1638
block = buf_page_get(space, zip_size, page_no, RW_X_LATCH, mtr);
1508
1639
#ifdef UNIV_SYNC_DEBUG
1509
buf_page_dbg_add_level(page, SYNC_FSP_PAGE);
1640
buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
1510
1641
#endif /* UNIV_SYNC_DEBUG */
1512
1643
/* Prior contents of the page should be ignored */
1513
fsp_init_file_page(page, mtr);
1644
fsp_init_file_page(block, mtr);
1515
1646
return(page_no);
1643
1778
/* out: segment inode */
1644
1779
page_t* page, /* in: segment inode page */
1645
1780
ulint i, /* in: inode index on page */
1646
mtr_t* mtr __attribute__((unused))) /* in: mini-transaction handle */
1781
ulint zip_size __attribute__((unused)),
1782
/* in: compressed page size, or 0 */
1783
mtr_t* mtr __attribute__((unused)))
1784
/* in: mini-transaction handle */
1648
ut_ad(i < FSP_SEG_INODES_PER_PAGE);
1649
ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
1650
MTR_MEMO_PAGE_X_FIX));
1786
ut_ad(i < FSP_SEG_INODES_PER_PAGE(zip_size));
1787
ut_ad(mtr_memo_contains_page(mtr, page, MTR_MEMO_PAGE_X_FIX));
1652
1789
return(page + FSEG_ARR_OFFSET + FSEG_INODE_SIZE * i);
1661
1798
/* out: segment inode index, or ULINT_UNDEFINED
1662
1799
if not found */
1663
1800
page_t* page, /* in: segment inode page */
1801
ulint zip_size,/* in: compressed page size, or 0 */
1664
1802
mtr_t* mtr) /* in: mini-transaction handle */
1667
1805
fseg_inode_t* inode;
1669
for (i = 0; i < FSP_SEG_INODES_PER_PAGE; i++) {
1671
inode = fsp_seg_inode_page_get_nth_inode(page, i, mtr);
1673
if (ut_dulint_cmp(mach_read_from_8(inode + FSEG_ID),
1674
ut_dulint_zero) != 0) {
1807
for (i = 0; i < FSP_SEG_INODES_PER_PAGE(zip_size); i++) {
1809
inode = fsp_seg_inode_page_get_nth_inode(
1810
page, i, zip_size, mtr);
1812
if (!ut_dulint_is_zero(mach_read_from_8(inode + FSEG_ID))) {
1675
1813
/* This is used */
1690
1828
/* out: segment inode index, or ULINT_UNDEFINED
1691
1829
if not found */
1692
1830
page_t* page, /* in: segment inode page */
1693
ulint j, /* in: search forward starting from this index */
1831
ulint i, /* in: search forward starting from this index */
1832
ulint zip_size,/* in: compressed page size, or 0 */
1694
1833
mtr_t* mtr) /* in: mini-transaction handle */
1697
1835
fseg_inode_t* inode;
1699
for (i = j; i < FSP_SEG_INODES_PER_PAGE; i++) {
1701
inode = fsp_seg_inode_page_get_nth_inode(page, i, mtr);
1703
if (ut_dulint_cmp(mach_read_from_8(inode + FSEG_ID),
1704
ut_dulint_zero) == 0) {
1837
for (; i < FSP_SEG_INODES_PER_PAGE(zip_size); i++) {
1839
inode = fsp_seg_inode_page_get_nth_inode(
1840
page, i, zip_size, mtr);
1842
if (ut_dulint_is_zero(mach_read_from_8(inode + FSEG_ID))) {
1705
1843
/* This is unused */
1722
1860
mtr_t* mtr) /* in: mini-transaction handle */
1724
1862
fseg_inode_t* inode;
1730
space = buf_frame_get_space_id(space_header);
1870
space = page_get_space_id(page_align(space_header));
1871
zip_size = dict_table_flags_to_zip_size(
1872
mach_read_from_4(FSP_SPACE_FLAGS + space_header));
1732
page_no = fsp_alloc_free_page(space, 0, mtr);
1874
page_no = fsp_alloc_free_page(space, zip_size, 0, mtr);
1734
1876
if (page_no == FIL_NULL) {
1739
page = buf_page_get(space, page_no, RW_X_LATCH, mtr);
1741
buf_block_align(page)->check_index_page_at_flush = FALSE;
1881
block = buf_page_get(space, zip_size, page_no, RW_X_LATCH, mtr);
1882
#ifdef UNIV_SYNC_DEBUG
1883
buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
1884
#endif /* UNIV_SYNC_DEBUG */
1886
block->check_index_page_at_flush = FALSE;
1888
page = buf_block_get_frame(block);
1743
1890
mlog_write_ulint(page + FIL_PAGE_TYPE, FIL_PAGE_INODE,
1744
1891
MLOG_2BYTES, mtr);
1745
#ifdef UNIV_SYNC_DEBUG
1746
buf_page_dbg_add_level(page, SYNC_FSP_PAGE);
1747
#endif /* UNIV_SYNC_DEBUG */
1749
for (i = 0; i < FSP_SEG_INODES_PER_PAGE; i++) {
1751
inode = fsp_seg_inode_page_get_nth_inode(page, i, mtr);
1893
for (i = 0; i < FSP_SEG_INODES_PER_PAGE(zip_size); i++) {
1895
inode = fsp_seg_inode_page_get_nth_inode(page, i,
1753
1898
mlog_write_dulint(inode + FSEG_ID, ut_dulint_zero, mtr);
1789
1936
page_no = flst_get_first(space_header + FSP_SEG_INODES_FREE, mtr).page;
1791
page = buf_page_get(buf_frame_get_space_id(space_header), page_no,
1938
zip_size = dict_table_flags_to_zip_size(
1939
mach_read_from_4(FSP_SPACE_FLAGS + space_header));
1940
block = buf_page_get(page_get_space_id(page_align(space_header)),
1941
zip_size, page_no, RW_X_LATCH, mtr);
1793
1942
#ifdef UNIV_SYNC_DEBUG
1794
buf_page_dbg_add_level(page, SYNC_FSP_PAGE);
1943
buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
1795
1944
#endif /* UNIV_SYNC_DEBUG */
1945
page = buf_block_get_frame(block);
1797
n = fsp_seg_inode_page_find_free(page, 0, mtr);
1947
n = fsp_seg_inode_page_find_free(page, 0, zip_size, mtr);
1799
1949
ut_a(n != ULINT_UNDEFINED);
1801
inode = fsp_seg_inode_page_get_nth_inode(page, n, mtr);
1951
inode = fsp_seg_inode_page_get_nth_inode(page, n, zip_size, mtr);
1803
1953
if (ULINT_UNDEFINED == fsp_seg_inode_page_find_free(page, n + 1,
1805
1955
/* There are no other unused headers left on the page: move it
1806
1956
to another list */
1822
1972
fsp_free_seg_inode(
1823
1973
/*===============*/
1824
1974
ulint space, /* in: space id */
1975
ulint zip_size,/* in: compressed page size in bytes
1976
or 0 for uncompressed pages */
1825
1977
fseg_inode_t* inode, /* in: segment inode */
1826
1978
mtr_t* mtr) /* in: mini-transaction handle */
1829
1981
fsp_header_t* space_header;
1831
page = buf_frame_align(inode);
1983
page = page_align(inode);
1833
space_header = fsp_get_space_header(space, mtr);
1985
space_header = fsp_get_space_header(space, zip_size, mtr);
1835
1987
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
1837
if (ULINT_UNDEFINED == fsp_seg_inode_page_find_free(page, 0, mtr)) {
1990
== fsp_seg_inode_page_find_free(page, 0, zip_size, mtr)) {
1839
1992
/* Move the page to another list */
1848
2001
mlog_write_dulint(inode + FSEG_ID, ut_dulint_zero, mtr);
1849
2002
mlog_write_ulint(inode + FSEG_MAGIC_N, 0, MLOG_4BYTES, mtr);
1851
if (ULINT_UNDEFINED == fsp_seg_inode_page_find_used(page, mtr)) {
2005
== fsp_seg_inode_page_find_used(page, zip_size, mtr)) {
1853
2007
/* There are no other used headers left on the page: free it */
1855
2009
flst_remove(space_header + FSP_SEG_INODES_FREE,
1856
2010
page + FSEG_INODE_PAGE_NODE, mtr);
1858
fsp_free_page(space, buf_frame_get_page_no(page), mtr);
2012
fsp_free_page(space, zip_size, page_get_page_no(page), mtr);
1875
2032
inode_addr.page = mach_read_from_4(header + FSEG_HDR_PAGE_NO);
1876
2033
inode_addr.boffset = mach_read_from_2(header + FSEG_HDR_OFFSET);
2034
ut_ad(space == mach_read_from_4(header + FSEG_HDR_SPACE));
1878
inode = fut_get_ptr(mach_read_from_4(header + FSEG_HDR_SPACE),
1879
inode_addr, RW_X_LATCH, mtr);
2036
inode = fut_get_ptr(space, zip_size, inode_addr, RW_X_LATCH, mtr);
1881
2038
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
2028
2183
mtr_t* mtr) /* in: mtr */
2030
2187
fsp_header_t* space_header;
2031
2188
fseg_inode_t* inode;
2033
fseg_header_t* header = 0; /* remove warning */
2190
buf_block_t* block = 0; /* remove warning */
2191
fseg_header_t* header = 0; /* remove warning */
2034
2192
rw_lock_t* latch;
2036
2194
ulint n_reserved;
2198
ut_ad(byte_offset + FSEG_HEADER_SIZE
2199
<= UNIV_PAGE_SIZE - FIL_PAGE_DATA_END);
2201
latch = fil_space_get_latch(space, &flags);
2202
zip_size = dict_table_flags_to_zip_size(flags);
2042
2204
if (page != 0) {
2043
header = byte_offset + buf_page_get(space, page, RW_X_LATCH,
2205
block = buf_page_get(space, zip_size, page, RW_X_LATCH, mtr);
2206
header = byte_offset + buf_block_get_frame(block);
2047
2209
ut_ad(!mutex_own(&kernel_mutex)
2048
|| mtr_memo_contains(mtr, fil_space_get_latch(space),
2050
latch = fil_space_get_latch(space);
2210
|| mtr_memo_contains(mtr, latch, MTR_MEMO_X_LOCK));
2052
2212
mtr_x_lock(latch, mtr);
2101
2261
if (page == 0) {
2102
page = fseg_alloc_free_page_low(space, inode, 0, FSP_UP, mtr);
2262
page = fseg_alloc_free_page_low(space, zip_size,
2263
inode, 0, FSP_UP, mtr);
2104
2265
if (page == FIL_NULL) {
2106
fsp_free_seg_inode(space, inode, mtr);
2267
fsp_free_seg_inode(space, zip_size, inode, mtr);
2108
2269
goto funct_exit;
2111
header = byte_offset
2112
+ buf_page_get(space, page, RW_X_LATCH, mtr);
2272
block = buf_page_get(space, zip_size, page, RW_X_LATCH, mtr);
2273
header = byte_offset + buf_block_get_frame(block);
2113
2274
mlog_write_ulint(header - byte_offset + FIL_PAGE_TYPE,
2114
2275
FIL_PAGE_TYPE_SYS, MLOG_2BYTES, mtr);
2117
2278
mlog_write_ulint(header + FSEG_HDR_OFFSET,
2118
inode - buf_frame_align(inode), MLOG_2BYTES, mtr);
2279
page_offset(inode), MLOG_2BYTES, mtr);
2120
2281
mlog_write_ulint(header + FSEG_HDR_PAGE_NO,
2121
buf_frame_get_page_no(inode), MLOG_4BYTES, mtr);
2282
page_get_page_no(page_align(inode)),
2123
2285
mlog_write_ulint(header + FSEG_HDR_SPACE, space, MLOG_4BYTES, mtr);
2125
ret = buf_frame_align(header);
2128
2288
if (!has_done_reservation) {
2130
2290
fil_space_release_free_extents(space, n_reserved);
2136
2296
/**************************************************************************
2137
2297
Creates a new segment. */
2142
/* out: the page where the segment header is placed,
2302
/* out: the block where the segment header is placed,
2143
2303
x-latched, NULL if could not create segment
2144
2304
because of lack of space */
2145
2305
ulint space, /* in: space id */
2200
2359
fseg_inode_t* inode;
2203
space = buf_frame_get_space_id(header);
2365
space = page_get_space_id(page_align(header));
2366
latch = fil_space_get_latch(space, &flags);
2367
zip_size = dict_table_flags_to_zip_size(flags);
2205
2369
ut_ad(!mutex_own(&kernel_mutex)
2206
|| mtr_memo_contains(mtr, fil_space_get_latch(space),
2209
mtr_x_lock(fil_space_get_latch(space), mtr);
2211
inode = fseg_inode_get(header, mtr);
2370
|| mtr_memo_contains(mtr, latch, MTR_MEMO_X_LOCK));
2372
mtr_x_lock(latch, mtr);
2374
inode = fseg_inode_get(header, space, zip_size, mtr);
2213
2376
ret = fseg_n_reserved_pages_low(inode, used, mtr);
2301
2468
first = flst_get_first(inode + FSEG_FREE, mtr);
2303
descr = xdes_lst_get_descriptor(space, first, mtr);
2470
descr = xdes_lst_get_descriptor(space, zip_size, first, mtr);
2305
2472
/* Segment free list was empty, allocate from space */
2306
descr = fsp_alloc_free_extent(space, 0, mtr);
2473
descr = fsp_alloc_free_extent(space, zip_size, 0, mtr);
2308
2475
if (descr == NULL) {
2336
2503
/* out: the allocated page number, FIL_NULL
2337
2504
if no page could be allocated */
2338
2505
ulint space, /* in: space */
2506
ulint zip_size,/* in: compressed page size in bytes
2507
or 0 for uncompressed pages */
2339
2508
fseg_inode_t* seg_inode, /* in: segment inode */
2340
2509
ulint hint, /* in: hint of which page would be desirable */
2341
2510
byte direction, /* in: if the new page is needed because
2365
2533
== FSEG_MAGIC_N_VALUE);
2366
2534
seg_id = mtr_read_dulint(seg_inode + FSEG_ID, mtr);
2368
ut_ad(ut_dulint_cmp(seg_id, ut_dulint_zero) > 0);
2536
ut_ad(!ut_dulint_is_zero(seg_id));
2370
2538
reserved = fseg_n_reserved_pages_low(seg_inode, &used, mtr);
2372
space_header = fsp_get_space_header(space, mtr);
2540
space_header = fsp_get_space_header(space, zip_size, mtr);
2374
2542
descr = xdes_get_descriptor_with_space_hdr(space_header, space,
2536
2707
/* Initialize the allocated page to buffer pool, so that it
2537
2708
can be obtained immediately with buf_page_get without need
2538
2709
for a disk read */
2540
page = buf_page_create(space, ret_page, mtr);
2542
ut_a(page == buf_page_get(space, ret_page, RW_X_LATCH, mtr));
2711
ulint zip_size = dict_table_flags_to_zip_size(
2712
mach_read_from_4(FSP_SPACE_FLAGS + space_header));
2714
block = buf_page_create(space, ret_page, zip_size, mtr);
2544
2715
#ifdef UNIV_SYNC_DEBUG
2545
buf_page_dbg_add_level(page, SYNC_FSP_PAGE);
2716
buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
2546
2717
#endif /* UNIV_SYNC_DEBUG */
2718
if (UNIV_UNLIKELY(block != buf_page_get(space, zip_size,
2719
ret_page, RW_X_LATCH,
2548
2724
/* The prior contents of the page should be ignored */
2549
fsp_init_file_page(page, mtr);
2725
fsp_init_file_page(block, mtr);
2551
2727
/* At this point we know the extent and the page offset.
2552
2728
The extent is still in the appropriate list (FSEG_NOT_FULL
2553
2729
or FSEG_FREE), and the page is not yet marked as used. */
2555
ut_ad(xdes_get_descriptor(space, ret_page, mtr) == ret_descr);
2731
ut_ad(xdes_get_descriptor(space, zip_size, ret_page, mtr)
2556
2733
ut_ad(xdes_get_bit(ret_descr, XDES_FREE_BIT,
2557
2734
ret_page % FSP_EXTENT_SIZE, mtr) == TRUE);
2559
fseg_mark_page_used(seg_inode, space, ret_page, mtr);
2736
fseg_mark_page_used(seg_inode, space, zip_size, ret_page, mtr);
2562
2739
buf_reset_check_index_page_at_flush(space, ret_page);
2591
2768
fseg_inode_t* inode;
2593
2772
rw_lock_t* latch;
2596
2775
ulint n_reserved;
2598
space = buf_frame_get_space_id(seg_header);
2777
space = page_get_space_id(page_align(seg_header));
2779
latch = fil_space_get_latch(space, &flags);
2781
zip_size = dict_table_flags_to_zip_size(flags);
2600
2783
ut_ad(!mutex_own(&kernel_mutex)
2601
|| mtr_memo_contains(mtr, fil_space_get_latch(space),
2603
latch = fil_space_get_latch(space);
2784
|| mtr_memo_contains(mtr, latch, MTR_MEMO_X_LOCK));
2605
2786
mtr_x_lock(latch, mtr);
2745
2928
ulint n_pages_added;
2748
ut_ad(!mutex_own(&kernel_mutex)
2749
|| mtr_memo_contains(mtr, fil_space_get_latch(space),
2751
2931
*n_reserved = n_ext;
2753
latch = fil_space_get_latch(space);
2933
latch = fil_space_get_latch(space, &flags);
2934
zip_size = dict_table_flags_to_zip_size(flags);
2936
ut_ad(!mutex_own(&kernel_mutex)
2937
|| mtr_memo_contains(mtr, latch, MTR_MEMO_X_LOCK));
2755
2939
mtr_x_lock(latch, mtr);
2757
space_header = fsp_get_space_header(space, mtr);
2941
space_header = fsp_get_space_header(space, zip_size, mtr);
2759
2943
size = mtr_read_ulint(space_header + FSP_SIZE, MLOG_4BYTES, mtr);
2980
3187
/* Drop search system page hash index if the page is found in
2981
3188
the pool and is hashed */
2983
btr_search_drop_page_hash_when_freed(space, page);
3190
btr_search_drop_page_hash_when_freed(space, zip_size, page);
2985
descr = xdes_get_descriptor(space, page, mtr);
3192
descr = xdes_get_descriptor(space, zip_size, page, mtr);
2988
3195
if (xdes_get_bit(descr, XDES_FREE_BIT, page % FSP_EXTENT_SIZE, mtr)) {
3103
3310
ulint page, /* in: page offset */
3104
3311
mtr_t* mtr) /* in: mtr handle */
3106
3315
fseg_inode_t* seg_inode;
3318
latch = fil_space_get_latch(space, &flags);
3319
zip_size = dict_table_flags_to_zip_size(flags);
3108
3321
ut_ad(!mutex_own(&kernel_mutex)
3109
|| mtr_memo_contains(mtr, fil_space_get_latch(space),
3112
mtr_x_lock(fil_space_get_latch(space), mtr);
3114
seg_inode = fseg_inode_get(seg_header, mtr);
3116
fseg_free_page_low(seg_inode, space, page, mtr);
3322
|| mtr_memo_contains(mtr, latch, MTR_MEMO_X_LOCK));
3324
mtr_x_lock(latch, mtr);
3326
seg_inode = fseg_inode_get(seg_header, space, zip_size, mtr);
3328
fseg_free_page_low(seg_inode, space, zip_size, page, mtr);
3118
3330
#ifdef UNIV_DEBUG_FILE_ACCESSES
3119
3331
buf_page_set_file_page_was_freed(space, page);
3211
3425
fseg_inode_t* inode;
3214
space = buf_frame_get_space_id(header);
3432
space = page_get_space_id(page_align(header));
3433
header_page = page_get_page_no(page_align(header));
3435
latch = fil_space_get_latch(space, &flags);
3436
zip_size = dict_table_flags_to_zip_size(flags);
3216
3438
ut_ad(!mutex_own(&kernel_mutex)
3217
|| mtr_memo_contains(mtr, fil_space_get_latch(space),
3220
mtr_x_lock(fil_space_get_latch(space), mtr);
3222
descr = xdes_get_descriptor(space, buf_frame_get_page_no(header), mtr);
3439
|| mtr_memo_contains(mtr, latch, MTR_MEMO_X_LOCK));
3441
mtr_x_lock(latch, mtr);
3443
descr = xdes_get_descriptor(space, zip_size, header_page, mtr);
3224
3445
/* Check that the header resides on a page which has not been
3228
ut_a(xdes_get_bit(descr, XDES_FREE_BIT, buf_frame_get_page_no(header)
3229
% FSP_EXTENT_SIZE, mtr) == FALSE);
3230
inode = fseg_inode_get(header, mtr);
3449
ut_a(xdes_get_bit(descr, XDES_FREE_BIT,
3450
header_page % FSP_EXTENT_SIZE, mtr) == FALSE);
3451
inode = fseg_inode_get(header, space, zip_size, mtr);
3232
descr = fseg_get_first_extent(inode, mtr);
3453
descr = fseg_get_first_extent(inode, space, zip_size, mtr);
3234
3455
if (descr != NULL) {
3235
3456
/* Free the extent held by the segment */
3236
3457
page = xdes_get_offset(descr);
3238
fseg_free_extent(inode, space, page, mtr);
3459
fseg_free_extent(inode, space, zip_size, page, mtr);
3246
3467
if (n == ULINT_UNDEFINED) {
3247
3468
/* Freeing completed: free the segment inode */
3248
fsp_free_seg_inode(space, inode, mtr);
3469
fsp_free_seg_inode(space, zip_size, inode, mtr);
3253
fseg_free_page_low(inode, space,
3474
fseg_free_page_low(inode, space, zip_size,
3254
3475
fseg_get_nth_frag_page_no(inode, n, mtr), mtr);
3256
3477
n = fseg_find_last_used_frag_page_slot(inode, mtr);
3258
3479
if (n == ULINT_UNDEFINED) {
3259
3480
/* Freeing completed: free the segment inode */
3260
fsp_free_seg_inode(space, inode, mtr);
3481
fsp_free_seg_inode(space, zip_size, inode, mtr);
3284
3505
fseg_inode_t* inode;
3288
space = buf_frame_get_space_id(header);
3512
space = page_get_space_id(page_align(header));
3514
latch = fil_space_get_latch(space, &flags);
3515
zip_size = dict_table_flags_to_zip_size(flags);
3290
3517
ut_ad(!mutex_own(&kernel_mutex)
3291
|| mtr_memo_contains(mtr, fil_space_get_latch(space),
3294
mtr_x_lock(fil_space_get_latch(space), mtr);
3296
inode = fseg_inode_get(header, mtr);
3298
descr = fseg_get_first_extent(inode, mtr);
3518
|| mtr_memo_contains(mtr, latch, MTR_MEMO_X_LOCK));
3520
mtr_x_lock(latch, mtr);
3522
inode = fseg_inode_get(header, space, zip_size, mtr);
3524
descr = fseg_get_first_extent(inode, space, zip_size, mtr);
3300
3526
if (descr != NULL) {
3301
3527
/* Free the extent held by the segment */
3302
3528
page = xdes_get_offset(descr);
3304
fseg_free_extent(inode, space, page, mtr);
3530
fseg_free_extent(inode, space, zip_size, page, mtr);
3329
3555
/***********************************************************************
3330
3556
Frees a segment. The freeing is performed in several mini-transactions,
3331
3557
so that there is no danger of bufferfixing too many buffer pages. */
3336
3562
ulint space, /* in: space id */
3563
ulint zip_size,/* in: compressed page size in bytes
3564
or 0 for uncompressed pages */
3337
3565
ulint page_no,/* in: page number where the segment header is
3339
3567
ulint offset) /* in: byte offset of the segment header on that
3443
3672
node_addr = flst_get_first(inode + FSEG_FREE, mtr2);
3445
3674
while (!fil_addr_is_null(node_addr)) {
3446
3678
mtr_start(&mtr);
3447
mtr_x_lock(fil_space_get_latch(space), &mtr);
3679
mtr_x_lock(fil_space_get_latch(space, &flags), &mtr);
3680
zip_size = dict_table_flags_to_zip_size(flags);
3449
descr = xdes_lst_get_descriptor(space, node_addr, &mtr);
3682
descr = xdes_lst_get_descriptor(space, zip_size,
3451
3685
ut_a(xdes_get_n_used(descr, &mtr) == 0);
3452
3686
ut_a(xdes_get_state(descr, &mtr) == XDES_FSEG);
3462
3696
node_addr = flst_get_first(inode + FSEG_NOT_FULL, mtr2);
3464
3698
while (!fil_addr_is_null(node_addr)) {
3465
3702
mtr_start(&mtr);
3466
mtr_x_lock(fil_space_get_latch(space), &mtr);
3703
mtr_x_lock(fil_space_get_latch(space, &flags), &mtr);
3704
zip_size = dict_table_flags_to_zip_size(flags);
3468
descr = xdes_lst_get_descriptor(space, node_addr, &mtr);
3706
descr = xdes_lst_get_descriptor(space, zip_size,
3470
3709
ut_a(xdes_get_n_used(descr, &mtr) > 0);
3471
3710
ut_a(xdes_get_n_used(descr, &mtr) < FSP_EXTENT_SIZE);
3484
3723
node_addr = flst_get_first(inode + FSEG_FULL, mtr2);
3486
3725
while (!fil_addr_is_null(node_addr)) {
3487
3729
mtr_start(&mtr);
3488
mtr_x_lock(fil_space_get_latch(space), &mtr);
3730
mtr_x_lock(fil_space_get_latch(space, &flags), &mtr);
3731
zip_size = dict_table_flags_to_zip_size(flags);
3490
descr = xdes_lst_get_descriptor(space, node_addr, &mtr);
3733
descr = xdes_lst_get_descriptor(space, zip_size,
3492
3736
ut_a(xdes_get_n_used(descr, &mtr) == FSP_EXTENT_SIZE);
3493
3737
ut_a(xdes_get_state(descr, &mtr) == XDES_FSEG);
3506
3750
/***********************************************************************
3507
3751
Validates a segment. */
3512
3756
/* out: TRUE if ok */
3513
3757
fseg_header_t* header, /* in: segment header */
3514
mtr_t* mtr2) /* in: mtr */
3758
mtr_t* mtr) /* in: mtr */
3516
3760
fseg_inode_t* inode;
3520
space = buf_frame_get_space_id(header);
3522
mtr_x_lock(fil_space_get_latch(space), mtr2);
3524
inode = fseg_inode_get(header, mtr2);
3526
ret = fseg_validate_low(inode, mtr2);
3766
space = page_get_space_id(page_align(header));
3768
mtr_x_lock(fil_space_get_latch(space, &flags), mtr);
3769
zip_size = dict_table_flags_to_zip_size(flags);
3771
inode = fseg_inode_get(header, space, zip_size, mtr);
3773
ret = fseg_validate_low(inode, mtr);
3593
3840
fseg_inode_t* inode;
3596
space = buf_frame_get_space_id(header);
3598
mtr_x_lock(fil_space_get_latch(space), mtr);
3600
inode = fseg_inode_get(header, mtr);
3845
space = page_get_space_id(page_align(header));
3847
mtr_x_lock(fil_space_get_latch(space, &flags), mtr);
3848
zip_size = dict_table_flags_to_zip_size(flags);
3850
inode = fseg_inode_get(header, space, zip_size, mtr);
3602
3852
fseg_print_low(inode, mtr);
3854
#endif /* UNIV_BTR_PRINT */
3605
3856
/***********************************************************************
3606
3857
Validates the file space system and its segments. */
3630
3884
ulint seg_inode_len_free;
3631
3885
ulint seg_inode_len_full;
3887
latch = fil_space_get_latch(space, &flags);
3888
zip_size = dict_table_flags_to_zip_size(flags);
3889
ut_a(ut_is_2pow(zip_size));
3890
ut_a(zip_size <= UNIV_PAGE_SIZE);
3891
ut_a(!zip_size || zip_size >= PAGE_ZIP_MIN_SIZE);
3633
3893
/* Start first a mini-transaction mtr2 to lock out all other threads
3634
3894
from the fsp system */
3635
3895
mtr_start(&mtr2);
3636
mtr_x_lock(fil_space_get_latch(space), &mtr2);
3896
mtr_x_lock(latch, &mtr2);
3638
3898
mtr_start(&mtr);
3639
mtr_x_lock(fil_space_get_latch(space), &mtr);
3899
mtr_x_lock(latch, &mtr);
3641
header = fsp_get_space_header(space, &mtr);
3901
header = fsp_get_space_header(space, zip_size, &mtr);
3643
3903
size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, &mtr);
3644
3904
free_limit = mtr_read_ulint(header + FSP_FREE_LIMIT,
3664
3924
/* Validate FSP_FREE list */
3665
3925
mtr_start(&mtr);
3666
mtr_x_lock(fil_space_get_latch(space), &mtr);
3926
mtr_x_lock(latch, &mtr);
3668
header = fsp_get_space_header(space, &mtr);
3928
header = fsp_get_space_header(space, zip_size, &mtr);
3669
3929
node_addr = flst_get_first(header + FSP_FREE, &mtr);
3671
3931
mtr_commit(&mtr);
3673
3933
while (!fil_addr_is_null(node_addr)) {
3674
3934
mtr_start(&mtr);
3675
mtr_x_lock(fil_space_get_latch(space), &mtr);
3935
mtr_x_lock(latch, &mtr);
3678
descr = xdes_lst_get_descriptor(space, node_addr, &mtr);
3938
descr = xdes_lst_get_descriptor(space, zip_size,
3680
3941
ut_a(xdes_get_n_used(descr, &mtr) == 0);
3681
3942
ut_a(xdes_get_state(descr, &mtr) == XDES_FREE);
3687
3948
/* Validate FSP_FREE_FRAG list */
3688
3949
mtr_start(&mtr);
3689
mtr_x_lock(fil_space_get_latch(space), &mtr);
3950
mtr_x_lock(latch, &mtr);
3691
header = fsp_get_space_header(space, &mtr);
3952
header = fsp_get_space_header(space, zip_size, &mtr);
3692
3953
node_addr = flst_get_first(header + FSP_FREE_FRAG, &mtr);
3694
3955
mtr_commit(&mtr);
3696
3957
while (!fil_addr_is_null(node_addr)) {
3697
3958
mtr_start(&mtr);
3698
mtr_x_lock(fil_space_get_latch(space), &mtr);
3959
mtr_x_lock(latch, &mtr);
3701
descr = xdes_lst_get_descriptor(space, node_addr, &mtr);
3962
descr = xdes_lst_get_descriptor(space, zip_size,
3703
3965
ut_a(xdes_get_n_used(descr, &mtr) > 0);
3704
3966
ut_a(xdes_get_n_used(descr, &mtr) < FSP_EXTENT_SIZE);
3713
3975
/* Validate FSP_FULL_FRAG list */
3714
3976
mtr_start(&mtr);
3715
mtr_x_lock(fil_space_get_latch(space), &mtr);
3977
mtr_x_lock(latch, &mtr);
3717
header = fsp_get_space_header(space, &mtr);
3979
header = fsp_get_space_header(space, zip_size, &mtr);
3718
3980
node_addr = flst_get_first(header + FSP_FULL_FRAG, &mtr);
3720
3982
mtr_commit(&mtr);
3722
3984
while (!fil_addr_is_null(node_addr)) {
3723
3985
mtr_start(&mtr);
3724
mtr_x_lock(fil_space_get_latch(space), &mtr);
3986
mtr_x_lock(latch, &mtr);
3727
descr = xdes_lst_get_descriptor(space, node_addr, &mtr);
3989
descr = xdes_lst_get_descriptor(space, zip_size,
3729
3992
ut_a(xdes_get_n_used(descr, &mtr) == FSP_EXTENT_SIZE);
3730
3993
ut_a(xdes_get_state(descr, &mtr) == XDES_FULL_FRAG);
3748
4011
while (!fil_addr_is_null(node_addr)) {
3750
for (n = 0; n < FSP_SEG_INODES_PER_PAGE; n++) {
3752
4015
mtr_start(&mtr);
3753
mtr_x_lock(fil_space_get_latch(space), &mtr);
4016
mtr_x_lock(latch, &mtr);
3755
4018
seg_inode_page = fut_get_ptr(
3756
space, node_addr, RW_X_LATCH, &mtr)
4019
space, zip_size, node_addr, RW_X_LATCH, &mtr)
3757
4020
- FSEG_INODE_PAGE_NODE;
3759
4022
seg_inode = fsp_seg_inode_page_get_nth_inode(
3760
seg_inode_page, n, &mtr);
3762
mach_read_from_8(seg_inode + FSEG_ID),
3763
ut_dulint_zero) != 0);
4023
seg_inode_page, n, zip_size, &mtr);
4024
ut_a(!ut_dulint_is_zero(
4025
mach_read_from_8(seg_inode + FSEG_ID)));
3764
4026
fseg_validate_low(seg_inode, &mtr);
3766
4028
descr_count += flst_get_len(seg_inode + FSEG_FREE,
3775
4037
next_node_addr = flst_get_next_addr(
3776
4038
seg_inode_page + FSEG_INODE_PAGE_NODE, &mtr);
3777
4039
mtr_commit(&mtr);
4040
} while (++n < FSP_SEG_INODES_PER_PAGE(zip_size));
3780
4042
node_addr = next_node_addr;
3783
4045
mtr_start(&mtr);
3784
mtr_x_lock(fil_space_get_latch(space), &mtr);
4046
mtr_x_lock(latch, &mtr);
3786
header = fsp_get_space_header(space, &mtr);
4048
header = fsp_get_space_header(space, zip_size, &mtr);
3788
4050
node_addr = flst_get_first(header + FSP_SEG_INODES_FREE, &mtr);
3794
4056
while (!fil_addr_is_null(node_addr)) {
3796
for (n = 0; n < FSP_SEG_INODES_PER_PAGE; n++) {
3798
4061
mtr_start(&mtr);
3799
mtr_x_lock(fil_space_get_latch(space), &mtr);
4062
mtr_x_lock(latch, &mtr);
3801
4064
seg_inode_page = fut_get_ptr(
3802
space, node_addr, RW_X_LATCH, &mtr)
4065
space, zip_size, node_addr, RW_X_LATCH, &mtr)
3803
4066
- FSEG_INODE_PAGE_NODE;
3805
4068
seg_inode = fsp_seg_inode_page_get_nth_inode(
3806
seg_inode_page, n, &mtr);
3808
mach_read_from_8(seg_inode + FSEG_ID),
3809
ut_dulint_zero) != 0) {
4069
seg_inode_page, n, zip_size, &mtr);
4070
if (!ut_dulint_is_zero(
4071
mach_read_from_8(seg_inode + FSEG_ID))) {
3810
4072
fseg_validate_low(seg_inode, &mtr);
3812
4074
descr_count += flst_get_len(
3822
4084
next_node_addr = flst_get_next_addr(
3823
4085
seg_inode_page + FSEG_INODE_PAGE_NODE, &mtr);
3824
4086
mtr_commit(&mtr);
4087
} while (++n < FSP_SEG_INODES_PER_PAGE(zip_size));
3827
4089
node_addr = next_node_addr;
3830
4092
ut_a(descr_count * FSP_EXTENT_SIZE == free_limit);
3831
ut_a(n_used + n_full_frag_pages
3832
== n_used2 + 2* ((free_limit + XDES_DESCRIBED_PER_PAGE - 1)
3833
/ XDES_DESCRIBED_PER_PAGE)
3834
+ seg_inode_len_full + seg_inode_len_free);
4094
ut_a(n_used + n_full_frag_pages
4095
== n_used2 + 2 * ((free_limit + (UNIV_PAGE_SIZE - 1))
4097
+ seg_inode_len_full + seg_inode_len_free);
4099
ut_a(n_used + n_full_frag_pages
4100
== n_used2 + 2 * ((free_limit + (zip_size - 1))
4102
+ seg_inode_len_full + seg_inode_len_free);
3835
4104
ut_a(frag_n_used == n_used);
3837
4106
mtr_commit(&mtr2);
4141
latch = fil_space_get_latch(space, &flags);
4142
zip_size = dict_table_flags_to_zip_size(flags);
3869
4144
/* Start first a mini-transaction mtr2 to lock out all other threads
3870
4145
from the fsp system */
3872
4147
mtr_start(&mtr2);
3874
mtr_x_lock(fil_space_get_latch(space), &mtr2);
4149
mtr_x_lock(latch, &mtr2);
3876
4151
mtr_start(&mtr);
3878
mtr_x_lock(fil_space_get_latch(space), &mtr);
4153
mtr_x_lock(latch, &mtr);
3880
header = fsp_get_space_header(space, &mtr);
4155
header = fsp_get_space_header(space, zip_size, &mtr);
3882
4157
size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, &mtr);
3921
4196
while (!fil_addr_is_null(node_addr)) {
3923
for (n = 0; n < FSP_SEG_INODES_PER_PAGE; n++) {
3925
4202
mtr_start(&mtr);
3926
mtr_x_lock(fil_space_get_latch(space), &mtr);
4203
mtr_x_lock(latch, &mtr);
3928
4205
seg_inode_page = fut_get_ptr(
3929
space, node_addr, RW_X_LATCH, &mtr)
4206
space, zip_size, node_addr, RW_X_LATCH, &mtr)
3930
4207
- FSEG_INODE_PAGE_NODE;
3932
4209
seg_inode = fsp_seg_inode_page_get_nth_inode(
3933
seg_inode_page, n, &mtr);
3935
mach_read_from_8(seg_inode + FSEG_ID),
3936
ut_dulint_zero) != 0);
4210
seg_inode_page, n, zip_size, &mtr);
4211
ut_a(!ut_dulint_is_zero(
4212
mach_read_from_8(seg_inode + FSEG_ID)));
3937
4213
fseg_print_low(seg_inode, &mtr);
3941
4217
next_node_addr = flst_get_next_addr(
3942
4218
seg_inode_page + FSEG_INODE_PAGE_NODE, &mtr);
3943
4219
mtr_commit(&mtr);
4220
} while (++n < FSP_SEG_INODES_PER_PAGE(zip_size));
3946
4222
node_addr = next_node_addr;
3949
4225
mtr_start(&mtr);
3950
mtr_x_lock(fil_space_get_latch(space), &mtr);
4226
mtr_x_lock(latch, &mtr);
3952
header = fsp_get_space_header(space, &mtr);
4228
header = fsp_get_space_header(space, zip_size, &mtr);
3954
4230
node_addr = flst_get_first(header + FSP_SEG_INODES_FREE, &mtr);
3958
4234
while (!fil_addr_is_null(node_addr)) {
3960
for (n = 0; n < FSP_SEG_INODES_PER_PAGE; n++) {
3962
4240
mtr_start(&mtr);
3963
mtr_x_lock(fil_space_get_latch(space), &mtr);
4241
mtr_x_lock(latch, &mtr);
3965
4243
seg_inode_page = fut_get_ptr(
3966
space, node_addr, RW_X_LATCH, &mtr)
4244
space, zip_size, node_addr, RW_X_LATCH, &mtr)
3967
4245
- FSEG_INODE_PAGE_NODE;
3969
4247
seg_inode = fsp_seg_inode_page_get_nth_inode(
3970
seg_inode_page, n, &mtr);
3972
mach_read_from_8(seg_inode + FSEG_ID),
3973
ut_dulint_zero) != 0) {
4248
seg_inode_page, n, zip_size, &mtr);
4249
if (!ut_dulint_is_zero(
4250
mach_read_from_8(seg_inode + FSEG_ID))) {
3975
4252
fseg_print_low(seg_inode, &mtr);