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