53 #define FSP_HEADER_OFFSET FIL_PAGE_DATA
57 typedef byte fsp_header_t;
68 #define FSP_SPACE_ID 0
69 #define FSP_NOT_USED 4
75 #define FSP_FREE_LIMIT 12
85 #define FSP_SPACE_FLAGS 16
86 #define FSP_FRAG_N_USED 20
89 #define FSP_FREE_FRAG (24 + FLST_BASE_NODE_SIZE)
92 #define FSP_FULL_FRAG (24 + 2 * FLST_BASE_NODE_SIZE)
95 #define FSP_SEG_ID (24 + 3 * FLST_BASE_NODE_SIZE)
98 #define FSP_SEG_INODES_FULL (32 + 3 * FLST_BASE_NODE_SIZE)
102 #define FSP_SEG_INODES_FREE (32 + 4 * FLST_BASE_NODE_SIZE)
108 #define FSP_HEADER_SIZE (32 + 5 * FLST_BASE_NODE_SIZE)
110 #define FSP_FREE_ADD 4
122 typedef byte fseg_inode_t;
124 #define FSEG_INODE_PAGE_NODE FSEG_PAGE_DATA
128 #define FSEG_ARR_OFFSET (FSEG_PAGE_DATA + FLST_NODE_SIZE)
132 #define FSEG_NOT_FULL_N_USED 8
138 #define FSEG_NOT_FULL (12 + FLST_BASE_NODE_SIZE)
140 #define FSEG_FULL (12 + 2 * FLST_BASE_NODE_SIZE)
142 #define FSEG_MAGIC_N (12 + 3 * FLST_BASE_NODE_SIZE)
144 #define FSEG_FRAG_ARR (16 + 3 * FLST_BASE_NODE_SIZE)
148 #define FSEG_FRAG_ARR_N_SLOTS (FSP_EXTENT_SIZE / 2)
151 #define FSEG_FRAG_SLOT_SIZE 4
155 #define FSEG_INODE_SIZE \
156 (16 + 3 * FLST_BASE_NODE_SIZE \
157 + FSEG_FRAG_ARR_N_SLOTS * FSEG_FRAG_SLOT_SIZE)
159 #define FSP_SEG_INODES_PER_PAGE(zip_size) \
160 (((zip_size ? zip_size : UNIV_PAGE_SIZE) \
161 - FSEG_ARR_OFFSET - 10) / FSEG_INODE_SIZE)
165 #define FSEG_MAGIC_N_VALUE 97937874
167 #define FSEG_FILLFACTOR 8
177 #define FSEG_FRAG_LIMIT FSEG_FRAG_ARR_N_SLOTS
184 #define FSEG_FREE_LIST_LIMIT 40
189 #define FSEG_FREE_LIST_MAX_LEN 4
201 #define XDES_FLST_NODE 8
203 #define XDES_STATE (FLST_NODE_SIZE + 8)
206 #define XDES_BITMAP (FLST_NODE_SIZE + 12)
211 #define XDES_BITS_PER_PAGE 2
212 #define XDES_FREE_BIT 0
214 #define XDES_CLEAN_BIT 1
220 #define XDES_FREE_FRAG 2
222 #define XDES_FULL_FRAG 3
228 (XDES_BITMAP + UT_BITS_IN_BYTES(FSP_EXTENT_SIZE * XDES_BITS_PER_PAGE))
231 #define XDES_ARR_OFFSET (FSP_HEADER_OFFSET + FSP_HEADER_SIZE)
233 #ifndef UNIV_HOTBACKUP
235 static ibool fsp_tbs_full_error_printed = FALSE;
254 fseg_inode_t* seg_inode,
266 fseg_n_reserved_pages_low(
268 fseg_inode_t* header,
279 fseg_inode_t* seg_inode,
292 fseg_get_first_extent(
314 fsp_header_t* header,
323 fseg_alloc_free_page_low(
328 fseg_inode_t* seg_inode,
350 #ifndef UNIV_HOTBACKUP
356 fsp_get_space_header(
364 fsp_header_t* header;
367 ut_ad(zip_size <= UNIV_PAGE_SIZE);
369 ut_ad(
id || !zip_size);
372 header = FSP_HEADER_OFFSET + buf_block_get_frame(block);
373 buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
398 ut_ad(mtr_memo_contains_page(mtr, descr, MTR_MEMO_PAGE_X_FIX));
399 ut_ad((bit == XDES_FREE_BIT) || (bit == XDES_CLEAN_BIT));
400 ut_ad(offset < FSP_EXTENT_SIZE);
402 index = bit + XDES_BITS_PER_PAGE * offset;
404 byte_index = index / 8;
405 bit_index = index % 8;
430 ut_ad(mtr_memo_contains_page(mtr, descr, MTR_MEMO_PAGE_X_FIX));
431 ut_ad((bit == XDES_FREE_BIT) || (bit == XDES_CLEAN_BIT));
432 ut_ad(offset < FSP_EXTENT_SIZE);
434 index = bit + XDES_BITS_PER_PAGE * offset;
436 byte_index = index / 8;
437 bit_index = index % 8;
466 ut_ad(hint < FSP_EXTENT_SIZE);
467 ut_ad(mtr_memo_contains_page(mtr, descr, MTR_MEMO_PAGE_X_FIX));
468 for (i = hint; i < FSP_EXTENT_SIZE; i++) {
469 if (val == xdes_get_bit(descr, bit, i, mtr)) {
475 for (i = 0; i < hint; i++) {
476 if (val == xdes_get_bit(descr, bit, i, mtr)) {
482 return(ULINT_UNDEFINED);
491 xdes_find_bit_downward(
503 ut_ad(hint < FSP_EXTENT_SIZE);
504 ut_ad(mtr_memo_contains_page(mtr, descr, MTR_MEMO_PAGE_X_FIX));
505 for (i = hint + 1; i > 0; i--) {
506 if (val == xdes_get_bit(descr, bit, i - 1, mtr)) {
512 for (i = FSP_EXTENT_SIZE - 1; i > hint; i--) {
513 if (val == xdes_get_bit(descr, bit, i, mtr)) {
519 return(ULINT_UNDEFINED);
536 ut_ad(mtr_memo_contains_page(mtr, descr, MTR_MEMO_PAGE_X_FIX));
537 for (i = 0; i < FSP_EXTENT_SIZE; i++) {
538 if (FALSE == xdes_get_bit(descr, XDES_FREE_BIT, i, mtr)) {
556 if (0 == xdes_get_n_used(descr, mtr)) {
574 if (FSP_EXTENT_SIZE == xdes_get_n_used(descr, mtr)) {
593 ut_ad(state >= XDES_FREE);
594 ut_ad(state <= XDES_FSEG);
595 ut_ad(mtr_memo_contains_page(mtr, descr, MTR_MEMO_PAGE_X_FIX));
613 ut_ad(mtr_memo_contains_page(mtr, descr, MTR_MEMO_PAGE_X_FIX));
616 ut_ad(state - 1 < XDES_FSEG);
632 ut_ad(mtr_memo_contains_page(mtr, descr, MTR_MEMO_PAGE_X_FIX));
633 ut_ad((XDES_SIZE - XDES_BITMAP) % 4 == 0);
635 for (i = XDES_BITMAP; i < XDES_SIZE; i += 4) {
639 xdes_set_state(descr, XDES_FREE, mtr);
647 xdes_calc_descriptor_page(
653 ut_a(UNIV_PAGE_SIZE >
654 XDES_ARR_OFFSET + (UNIV_PAGE_SIZE / FSP_EXTENT_SIZE) * XDES_SIZE);
664 ut_ad(zip_size > XDES_ARR_OFFSET
665 + (zip_size / FSP_EXTENT_SIZE) * XDES_SIZE);
675 xdes_calc_descriptor_index(
701 xdes_get_descriptor_with_space_hdr(
703 fsp_header_t* sp_header,
718 ut_ad(mtr_memo_contains(mtr, fil_space_get_latch(space, NULL),
720 ut_ad(mtr_memo_contains_page(mtr, sp_header, MTR_MEMO_PAGE_S_FIX)
721 || mtr_memo_contains_page(mtr, sp_header, MTR_MEMO_PAGE_X_FIX));
731 if ((offset >= size) || (offset > limit)) {
738 if (offset == limit) {
739 fsp_fill_free_list(FALSE, space, sp_header, mtr);
742 descr_page_no = xdes_calc_descriptor_page(zip_size, offset);
744 if (descr_page_no == 0) {
753 buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
755 descr_page = buf_block_get_frame(block);
758 return(descr_page + XDES_ARR_OFFSET
759 + XDES_SIZE * xdes_calc_descriptor_index(zip_size, offset));
783 fsp_header_t* sp_header;
785 block =
buf_page_get(space, zip_size, 0, RW_X_LATCH, mtr);
786 buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
788 sp_header = FSP_HEADER_OFFSET + buf_block_get_frame(block);
789 return(xdes_get_descriptor_with_space_hdr(sp_header, space, offset,
800 xdes_lst_get_descriptor(
812 ut_ad(mtr_memo_contains(mtr, fil_space_get_latch(space, NULL),
814 descr =
fut_get_ptr(space, zip_size, lst_node, RW_X_LATCH, mtr)
832 + ((
page_offset(descr) - XDES_ARR_OFFSET) / XDES_SIZE)
841 fsp_init_file_page_low(
845 page_t* page = buf_block_get_frame(block);
848 #ifndef UNIV_HOTBACKUP
852 if (UNIV_LIKELY_NULL(page_zip)) {
853 memset(page, 0, UNIV_PAGE_SIZE);
867 memset(page, 0, UNIV_PAGE_SIZE);
873 #ifndef UNIV_HOTBACKUP
883 fsp_init_file_page_low(block);
895 fsp_parse_init_file_page(
901 ut_ad(ptr && end_ptr);
904 fsp_init_file_page_low(block);
926 fsp_header_init_fields(
945 #ifndef UNIV_HOTBACKUP
957 fsp_header_t* header;
965 mtr_x_lock(fil_space_get_latch(space, &flags), mtr);
968 block = buf_page_create(space, 0, zip_size, mtr);
970 buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
974 fsp_init_file_page(block, mtr);
975 page = buf_block_get_frame(block);
980 header = FSP_HEADER_OFFSET + page;
994 flst_init(header + FSP_SEG_INODES_FULL, mtr);
995 flst_init(header + FSP_SEG_INODES_FREE, mtr);
999 fsp_fill_free_list(FALSE, space, header, mtr);
1001 0, 0, DICT_IBUF_ID_MIN + space,
1002 dict_ind_redundant, mtr);
1004 fsp_fill_free_list(TRUE, space, header, mtr);
1014 fsp_header_get_space_id(
1027 "InnoDB: Error: space id in fsp header %lu,"
1028 " but in the page header %lu\n",
1029 (ulong) fsp_id, (ulong)
id);
1031 return(ULINT_UNDEFINED);
1042 fsp_header_get_flags(
1056 fsp_header_get_zip_size(
1060 ulint flags = fsp_header_get_flags(page);
1065 #ifndef UNIV_HOTBACKUP
1070 fsp_header_inc_size(
1076 fsp_header_t* header;
1082 mtr_x_lock(fil_space_get_latch(space, &flags), mtr);
1084 header = fsp_get_space_header(space,
1102 fsp_header_get_free_limit(
void)
1105 fsp_header_t* header;
1111 mtr_x_lock(fil_space_get_latch(0, NULL), &mtr);
1113 header = fsp_get_space_header(0, 0, &mtr);
1117 limit /= ((1024 * 1024) / UNIV_PAGE_SIZE);
1134 fsp_header_get_tablespace_size(
void)
1137 fsp_header_t* header;
1143 mtr_x_lock(fil_space_get_latch(0, NULL), &mtr);
1145 header = fsp_get_space_header(0, 0, &mtr);
1160 fsp_try_extend_data_file_with_pages(
1164 fsp_header_t* header,
1175 ut_a(page_no >= size);
1177 success = fil_extend_space_to_desired_size(&actual_size, space,
1192 fsp_try_extend_data_file(
1194 ulint* actual_increase,
1200 fsp_header_t* header,
1207 ulint size_increase;
1211 *actual_increase = 0;
1213 if (space == 0 && !srv_auto_extend_last_data_file) {
1219 if (fsp_tbs_full_error_printed == FALSE) {
1221 "InnoDB: Error: Data file(s) ran"
1223 "Please add another data file or"
1224 " use \'autoextend\' for the last"
1226 fsp_tbs_full_error_printed = TRUE;
1238 if (!srv_last_file_size_max) {
1239 size_increase = SRV_AUTO_EXTEND_INCREMENT;
1241 if (srv_last_file_size_max
1242 < srv_data_file_sizes[srv_n_data_files - 1]) {
1245 "InnoDB: Error: Last data file size"
1246 " is %lu, max size allowed %lu\n",
1247 (ulong) srv_data_file_sizes[
1248 srv_n_data_files - 1],
1249 (ulong) srv_last_file_size_max);
1252 size_increase = srv_last_file_size_max
1253 - srv_data_file_sizes[srv_n_data_files - 1];
1254 if (size_increase > SRV_AUTO_EXTEND_INCREMENT) {
1255 size_increase = SRV_AUTO_EXTEND_INCREMENT;
1266 extent_size = FSP_EXTENT_SIZE;
1268 extent_size = FSP_EXTENT_SIZE
1269 * UNIV_PAGE_SIZE / zip_size;
1272 if (size < extent_size) {
1274 success = fsp_try_extend_data_file_with_pages(
1275 space, extent_size - 1, header, mtr);
1280 *actual_increase = new_size - old_size;
1288 if (size < 32 * extent_size) {
1289 size_increase = extent_size;
1294 size_increase = FSP_FREE_ADD * extent_size;
1298 if (size_increase == 0) {
1303 success = fil_extend_space_to_desired_size(&actual_size, space,
1304 size + size_increase);
1310 (1024 * 1024) / UNIV_PAGE_SIZE);
1313 (1024 * 1024) / zip_size);
1317 *actual_increase = new_size - old_size;
1336 fsp_header_t* header,
1345 ulint actual_increase;
1349 ut_ad(header && mtr);
1359 ut_a(zip_size <= UNIV_PAGE_SIZE);
1362 if (space == 0 && srv_auto_extend_last_data_file
1363 && size < limit + FSP_EXTENT_SIZE * FSP_FREE_ADD) {
1366 fsp_try_extend_data_file(&actual_increase, space, header, mtr);
1370 if (space != 0 && !init_space
1371 && size < limit + FSP_EXTENT_SIZE * FSP_FREE_ADD) {
1374 fsp_try_extend_data_file(&actual_increase, space, header, mtr);
1380 while ((init_space && i < 1)
1381 || ((i + FSP_EXTENT_SIZE <= size) && (count < FSP_FREE_ADD))) {
1398 (i + FSP_EXTENT_SIZE)
1399 / ((1024 * 1024) / UNIV_PAGE_SIZE));
1402 if (UNIV_UNLIKELY(init_xdes)) {
1411 block = buf_page_create(
1412 space, i, zip_size, mtr);
1415 buf_block_dbg_add_level(block,
1418 fsp_init_file_page(block, mtr);
1432 block = buf_page_create(space,
1433 i + FSP_IBUF_BITMAP_OFFSET,
1434 zip_size, &ibuf_mtr);
1436 i + FSP_IBUF_BITMAP_OFFSET,
1437 RW_X_LATCH, &ibuf_mtr);
1438 buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
1440 fsp_init_file_page(block, &ibuf_mtr);
1442 ibuf_bitmap_page_init(block, &ibuf_mtr);
1447 descr = xdes_get_descriptor_with_space_hdr(header, space, i,
1449 xdes_init(descr, mtr);
1451 if (UNIV_UNLIKELY(init_xdes)) {
1457 xdes_set_bit(descr, XDES_FREE_BIT, 0, FALSE, mtr);
1458 xdes_set_bit(descr, XDES_FREE_BIT,
1459 FSP_IBUF_BITMAP_OFFSET, FALSE, mtr);
1460 xdes_set_state(descr, XDES_FREE_FRAG, mtr);
1462 flst_add_last(header + FSP_FREE_FRAG,
1463 descr + XDES_FLST_NODE, mtr);
1469 flst_add_last(header + FSP_FREE,
1470 descr + XDES_FLST_NODE, mtr);
1474 i += FSP_EXTENT_SIZE;
1483 fsp_alloc_free_extent(
1493 fsp_header_t* header;
1499 header = fsp_get_space_header(space, zip_size, mtr);
1501 descr = xdes_get_descriptor_with_space_hdr(header, space, hint, mtr);
1503 if (descr && (xdes_get_state(descr, mtr) == XDES_FREE)) {
1509 if (fil_addr_is_null(first)) {
1510 fsp_fill_free_list(FALSE, space, header, mtr);
1515 if (fil_addr_is_null(first)) {
1520 descr = xdes_lst_get_descriptor(space, zip_size, first, mtr);
1523 flst_remove(header + FSP_FREE, descr + XDES_FLST_NODE, mtr);
1533 fsp_alloc_free_page(
1541 fsp_header_t* header;
1553 header = fsp_get_space_header(space, zip_size, mtr);
1556 descr = xdes_get_descriptor_with_space_hdr(header, space, hint, mtr);
1558 if (descr && (xdes_get_state(descr, mtr) == XDES_FREE_FRAG)) {
1564 if (fil_addr_is_null(first)) {
1572 descr = fsp_alloc_free_extent(space, zip_size,
1575 if (descr == NULL) {
1581 xdes_set_state(descr, XDES_FREE_FRAG, mtr);
1582 flst_add_last(header + FSP_FREE_FRAG,
1583 descr + XDES_FLST_NODE, mtr);
1585 descr = xdes_lst_get_descriptor(space, zip_size,
1596 free = xdes_find_bit(descr, XDES_FREE_BIT, TRUE,
1597 hint % FSP_EXTENT_SIZE, mtr);
1598 if (free == ULINT_UNDEFINED) {
1606 page_no = xdes_get_offset(descr) + free;
1610 if (space_size <= page_no) {
1615 if (page_no >= FSP_EXTENT_SIZE) {
1617 "InnoDB: Error: trying to extend a"
1618 " single-table tablespace %lu\n"
1619 "InnoDB: by single page(s) though the"
1620 " space size %lu. Page no %lu.\n",
1621 (ulong) space, (ulong) space_size,
1625 success = fsp_try_extend_data_file_with_pages(space, page_no,
1633 xdes_set_bit(descr, XDES_FREE_BIT, free, FALSE, mtr);
1641 if (xdes_is_full(descr, mtr)) {
1643 flst_remove(header + FSP_FREE_FRAG, descr + XDES_FLST_NODE,
1645 xdes_set_state(descr, XDES_FULL_FRAG, mtr);
1647 flst_add_last(header + FSP_FULL_FRAG, descr + XDES_FLST_NODE,
1658 buf_page_create(space, page_no, zip_size, mtr);
1660 block =
buf_page_get(space, zip_size, page_no, RW_X_LATCH, mtr);
1661 buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
1664 fsp_init_file_page(block, mtr);
1681 fsp_header_t* header;
1690 header = fsp_get_space_header(space, zip_size, mtr);
1692 descr = xdes_get_descriptor_with_space_hdr(header, space, page, mtr);
1694 state = xdes_get_state(descr, mtr);
1696 if (state != XDES_FREE_FRAG && state != XDES_FULL_FRAG) {
1698 "InnoDB: Error: File space extent descriptor"
1699 " of page %lu has state %lu\n",
1702 fputs(
"InnoDB: Dump of descriptor: ", stderr);
1706 if (state == XDES_FREE) {
1716 if (xdes_get_bit(descr, XDES_FREE_BIT, page % FSP_EXTENT_SIZE, mtr)) {
1718 "InnoDB: Error: File space extent descriptor"
1719 " of page %lu says it is free\n"
1720 "InnoDB: Dump of descriptor: ", (ulong) page);
1730 xdes_set_bit(descr, XDES_FREE_BIT, page % FSP_EXTENT_SIZE, TRUE, mtr);
1731 xdes_set_bit(descr, XDES_CLEAN_BIT, page % FSP_EXTENT_SIZE, TRUE, mtr);
1735 if (state == XDES_FULL_FRAG) {
1737 flst_remove(header + FSP_FULL_FRAG, descr + XDES_FLST_NODE,
1739 xdes_set_state(descr, XDES_FREE_FRAG, mtr);
1740 flst_add_last(header + FSP_FREE_FRAG, descr + XDES_FLST_NODE,
1743 frag_n_used + FSP_EXTENT_SIZE - 1,
1746 ut_a(frag_n_used > 0);
1751 if (xdes_is_free(descr, mtr)) {
1753 flst_remove(header + FSP_FREE_FRAG, descr + XDES_FLST_NODE,
1755 fsp_free_extent(space, zip_size, page, mtr);
1771 fsp_header_t* header;
1776 header = fsp_get_space_header(space, zip_size, mtr);
1778 descr = xdes_get_descriptor_with_space_hdr(header, space, page, mtr);
1780 if (xdes_get_state(descr, mtr) == XDES_FREE) {
1788 xdes_init(descr, mtr);
1790 flst_add_last(header + FSP_FREE, descr + XDES_FLST_NODE, mtr);
1798 fsp_seg_inode_page_get_nth_inode(
1807 ut_ad(i < FSP_SEG_INODES_PER_PAGE(zip_size));
1808 ut_ad(mtr_memo_contains_page(mtr, page, MTR_MEMO_PAGE_X_FIX));
1810 return(page + FSEG_ARR_OFFSET + FSEG_INODE_SIZE * i);
1818 fsp_seg_inode_page_find_used(
1825 fseg_inode_t* inode;
1827 for (i = 0; i < FSP_SEG_INODES_PER_PAGE(zip_size); i++) {
1829 inode = fsp_seg_inode_page_get_nth_inode(
1830 page, i, zip_size, mtr);
1836 == FSEG_MAGIC_N_VALUE);
1841 return(ULINT_UNDEFINED);
1849 fsp_seg_inode_page_find_free(
1856 fseg_inode_t* inode;
1858 for (; i < FSP_SEG_INODES_PER_PAGE(zip_size); i++) {
1860 inode = fsp_seg_inode_page_get_nth_inode(
1861 page, i, zip_size, mtr);
1870 == FSEG_MAGIC_N_VALUE);
1873 return(ULINT_UNDEFINED);
1881 fsp_alloc_seg_inode_page(
1883 fsp_header_t* space_header,
1886 fseg_inode_t* inode;
1900 page_no = fsp_alloc_free_page(space, zip_size, 0, mtr);
1907 block =
buf_page_get(space, zip_size, page_no, RW_X_LATCH, mtr);
1908 buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
1912 page = buf_block_get_frame(block);
1917 for (i = 0; i < FSP_SEG_INODES_PER_PAGE(zip_size); i++) {
1919 inode = fsp_seg_inode_page_get_nth_inode(page, i,
1925 flst_add_last(space_header + FSP_SEG_INODES_FREE,
1926 page + FSEG_INODE_PAGE_NODE, mtr);
1935 fsp_alloc_seg_inode(
1937 fsp_header_t* space_header,
1943 fseg_inode_t* inode;
1950 if (
flst_get_len(space_header + FSP_SEG_INODES_FREE, mtr) == 0) {
1953 success = fsp_alloc_seg_inode_page(space_header, mtr);
1966 zip_size, page_no, RW_X_LATCH, mtr);
1967 buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
1969 page = buf_block_get_frame(block);
1971 n = fsp_seg_inode_page_find_free(page, 0, zip_size, mtr);
1973 ut_a(n != ULINT_UNDEFINED);
1975 inode = fsp_seg_inode_page_get_nth_inode(page, n, zip_size, mtr);
1977 if (ULINT_UNDEFINED == fsp_seg_inode_page_find_free(page, n + 1,
1982 flst_remove(space_header + FSP_SEG_INODES_FREE,
1983 page + FSEG_INODE_PAGE_NODE, mtr);
1985 flst_add_last(space_header + FSP_SEG_INODES_FULL,
1986 page + FSEG_INODE_PAGE_NODE, mtr);
2003 fseg_inode_t* inode,
2007 fsp_header_t* space_header;
2011 space_header = fsp_get_space_header(space, zip_size, mtr);
2016 == fsp_seg_inode_page_find_free(page, 0, zip_size, mtr)) {
2020 flst_remove(space_header + FSP_SEG_INODES_FULL,
2021 page + FSEG_INODE_PAGE_NODE, mtr);
2023 flst_add_last(space_header + FSP_SEG_INODES_FREE,
2024 page + FSEG_INODE_PAGE_NODE, mtr);
2031 == fsp_seg_inode_page_find_used(page, zip_size, mtr)) {
2035 flst_remove(space_header + FSP_SEG_INODES_FREE,
2036 page + FSEG_INODE_PAGE_NODE, mtr);
2049 fseg_header_t* header,
2056 fseg_inode_t* inode;
2062 inode =
fut_get_ptr(space, zip_size, inode_addr, RW_X_LATCH, mtr);
2069 == FSEG_MAGIC_N_VALUE);
2082 fseg_header_t* header,
2089 = fseg_inode_try_get(header, space, zip_size, mtr);
2099 fseg_get_nth_frag_page_no(
2101 fseg_inode_t* inode,
2105 ut_ad(inode && mtr);
2106 ut_ad(n < FSEG_FRAG_ARR_N_SLOTS);
2107 ut_ad(mtr_memo_contains_page(mtr, inode, MTR_MEMO_PAGE_X_FIX));
2110 + n * FSEG_FRAG_SLOT_SIZE));
2117 fseg_set_nth_frag_page_no(
2119 fseg_inode_t* inode,
2124 ut_ad(inode && mtr);
2125 ut_ad(n < FSEG_FRAG_ARR_N_SLOTS);
2126 ut_ad(mtr_memo_contains_page(mtr, inode, MTR_MEMO_PAGE_X_FIX));
2138 fseg_find_free_frag_page_slot(
2140 fseg_inode_t* inode,
2146 ut_ad(inode && mtr);
2148 for (i = 0; i < FSEG_FRAG_ARR_N_SLOTS; i++) {
2149 page_no = fseg_get_nth_frag_page_no(inode, i, mtr);
2157 return(ULINT_UNDEFINED);
2165 fseg_find_last_used_frag_page_slot(
2167 fseg_inode_t* inode,
2173 ut_ad(inode && mtr);
2175 for (i = 0; i < FSEG_FRAG_ARR_N_SLOTS; i++) {
2176 page_no = fseg_get_nth_frag_page_no(
2177 inode, FSEG_FRAG_ARR_N_SLOTS - i - 1, mtr);
2181 return(FSEG_FRAG_ARR_N_SLOTS - i - 1);
2185 return(ULINT_UNDEFINED);
2193 fseg_get_n_frag_pages(
2195 fseg_inode_t* inode,
2201 ut_ad(inode && mtr);
2203 for (i = 0; i < FSEG_FRAG_ARR_N_SLOTS; i++) {
2204 if (
FIL_NULL != fseg_get_nth_frag_page_no(inode, i, mtr)) {
2218 fseg_create_general(
2227 ibool has_done_reservation,
2237 fsp_header_t* space_header;
2238 fseg_inode_t* inode;
2241 fseg_header_t* header = 0;
2248 ut_ad(byte_offset + FSEG_HEADER_SIZE
2251 latch = fil_space_get_latch(space, &flags);
2255 block =
buf_page_get(space, zip_size, page, RW_X_LATCH, mtr);
2256 header = byte_offset + buf_block_get_frame(block);
2259 ut_ad(!mutex_own(&kernel_mutex)
2260 || mtr_memo_contains(mtr, latch, MTR_MEMO_X_LOCK));
2268 if (space == IBUF_SPACE_ID) {
2269 ibuf_free_excess_pages();
2273 if (!has_done_reservation) {
2274 success = fsp_reserve_free_extents(&n_reserved, space, 2,
2281 space_header = fsp_get_space_header(space, zip_size, mtr);
2283 inode = fsp_alloc_seg_inode(space_header, mtr);
2285 if (inode == NULL) {
2306 for (i = 0; i < FSEG_FRAG_ARR_N_SLOTS; i++) {
2307 fseg_set_nth_frag_page_no(inode, i,
FIL_NULL, mtr);
2311 page = fseg_alloc_free_page_low(space, zip_size,
2312 inode, 0, FSP_UP, mtr);
2316 fsp_free_seg_inode(space, zip_size, inode, mtr);
2321 block =
buf_page_get(space, zip_size, page, RW_X_LATCH, mtr);
2322 header = byte_offset + buf_block_get_frame(block);
2337 if (!has_done_reservation) {
2339 fil_space_release_free_extents(space, n_reserved);
2362 return(fseg_create_general(space, page, byte_offset, FALSE, mtr));
2371 fseg_n_reserved_pages_low(
2373 fseg_inode_t* inode,
2380 ut_ad(inode && used && mtr);
2381 ut_ad(mtr_memo_contains_page(mtr, inode, MTR_MEMO_PAGE_X_FIX));
2384 + FSP_EXTENT_SIZE *
flst_get_len(inode + FSEG_FULL, mtr)
2385 + fseg_get_n_frag_pages(inode, mtr);
2387 ret = fseg_get_n_frag_pages(inode, mtr)
2388 + FSP_EXTENT_SIZE *
flst_get_len(inode + FSEG_FREE, mtr)
2389 + FSP_EXTENT_SIZE *
flst_get_len(inode + FSEG_NOT_FULL, mtr)
2390 + FSP_EXTENT_SIZE *
flst_get_len(inode + FSEG_FULL, mtr);
2401 fseg_n_reserved_pages(
2403 fseg_header_t* header,
2408 fseg_inode_t* inode;
2415 latch = fil_space_get_latch(space, &flags);
2418 ut_ad(!mutex_own(&kernel_mutex)
2419 || mtr_memo_contains(mtr, latch, MTR_MEMO_X_LOCK));
2423 inode = fseg_inode_get(header, space, zip_size, mtr);
2425 ret = fseg_n_reserved_pages_low(inode, used, mtr);
2437 fseg_fill_free_list(
2439 fseg_inode_t* inode,
2453 ut_ad(inode && mtr);
2456 reserved = fseg_n_reserved_pages_low(inode, &used, mtr);
2458 if (reserved < FSEG_FREE_LIST_LIMIT * FSP_EXTENT_SIZE) {
2471 for (i = 0; i < FSEG_FREE_LIST_MAX_LEN; i++) {
2472 descr = xdes_get_descriptor(space, zip_size, hint, mtr);
2475 || (XDES_FREE != xdes_get_state(descr, mtr))) {
2482 descr = fsp_alloc_free_extent(space, zip_size, hint, mtr);
2484 xdes_set_state(descr, XDES_FSEG, mtr);
2488 == FSEG_MAGIC_N_VALUE);
2491 flst_add_last(inode + FSEG_FREE, descr + XDES_FLST_NODE, mtr);
2492 hint += FSP_EXTENT_SIZE;
2504 fseg_alloc_free_extent(
2506 fseg_inode_t* inode,
2524 descr = xdes_lst_get_descriptor(space, zip_size, first, mtr);
2527 descr = fsp_alloc_free_extent(space, zip_size, 0, mtr);
2529 if (descr == NULL) {
2536 xdes_set_state(descr, XDES_FSEG, mtr);
2538 flst_add_last(inode + FSEG_FREE, descr + XDES_FLST_NODE, mtr);
2541 fseg_fill_free_list(inode, space, zip_size,
2542 xdes_get_offset(descr) + FSP_EXTENT_SIZE,
2556 fseg_alloc_free_page_low(
2561 fseg_inode_t* seg_inode,
2570 fsp_header_t* space_header;
2579 ibool frag_page_allocated = FALSE;
2584 ut_ad((direction >= FSP_UP) && (direction <= FSP_NO_DIR));
2586 == FSEG_MAGIC_N_VALUE);
2592 reserved = fseg_n_reserved_pages_low(seg_inode, &used, mtr);
2594 space_header = fsp_get_space_header(space, zip_size, mtr);
2596 descr = xdes_get_descriptor_with_space_hdr(space_header, space,
2598 if (descr == NULL) {
2602 descr = xdes_get_descriptor(space, zip_size, hint, mtr);
2607 if ((xdes_get_state(descr, mtr) == XDES_FSEG)
2609 && (xdes_get_bit(descr, XDES_FREE_BIT,
2610 hint % FSP_EXTENT_SIZE, mtr) == TRUE)) {
2617 }
else if ((xdes_get_state(descr, mtr) == XDES_FREE)
2618 && ((reserved - used) < reserved / FSEG_FILLFACTOR)
2619 && (used >= FSEG_FRAG_LIMIT)) {
2625 ret_descr = fsp_alloc_free_extent(space, zip_size, hint, mtr);
2627 ut_a(ret_descr == descr);
2629 xdes_set_state(ret_descr, XDES_FSEG, mtr);
2631 flst_add_last(seg_inode + FSEG_FREE,
2632 ret_descr + XDES_FLST_NODE, mtr);
2635 fseg_fill_free_list(seg_inode, space, zip_size,
2636 hint + FSP_EXTENT_SIZE, mtr);
2639 }
else if ((direction != FSP_NO_DIR)
2640 && ((reserved - used) < reserved / FSEG_FILLFACTOR)
2641 && (used >= FSEG_FRAG_LIMIT)
2643 = fseg_alloc_free_extent(seg_inode,
2644 space, zip_size, mtr)))) {
2652 ret_page = xdes_get_offset(ret_descr);
2654 if (direction == FSP_DOWN) {
2655 ret_page += FSP_EXTENT_SIZE - 1;
2658 }
else if ((xdes_get_state(descr, mtr) == XDES_FSEG)
2660 && (!xdes_is_full(descr, mtr))) {
2669 ret_page = xdes_get_offset(ret_descr)
2670 + xdes_find_bit(ret_descr, XDES_FREE_BIT, TRUE,
2671 hint % FSP_EXTENT_SIZE, mtr);
2673 }
else if (reserved - used > 0) {
2678 if (
flst_get_len(seg_inode + FSEG_NOT_FULL, mtr) > 0) {
2681 }
else if (
flst_get_len(seg_inode + FSEG_FREE, mtr) > 0) {
2688 ret_descr = xdes_lst_get_descriptor(space, zip_size,
2690 ret_page = xdes_get_offset(ret_descr)
2691 + xdes_find_bit(ret_descr, XDES_FREE_BIT, TRUE,
2694 }
else if (used < FSEG_FRAG_LIMIT) {
2697 ret_page = fsp_alloc_free_page(space, zip_size, hint, mtr);
2700 frag_page_allocated = TRUE;
2705 n = fseg_find_free_frag_page_slot(seg_inode, mtr);
2708 fseg_set_nth_frag_page_no(seg_inode, n, ret_page,
2715 ret_descr = fseg_alloc_free_extent(seg_inode,
2716 space, zip_size, mtr);
2718 if (ret_descr == NULL) {
2721 ret_page = xdes_get_offset(ret_descr);
2732 space_size = fil_space_get_size(space);
2734 if (space_size <= ret_page) {
2738 if (ret_page >= FSP_EXTENT_SIZE) {
2740 "InnoDB: Error (2): trying to extend"
2741 " a single-table tablespace %lu\n"
2742 "InnoDB: by single page(s) though"
2743 " the space size %lu. Page no %lu.\n",
2744 (ulong) space, (ulong) space_size,
2749 success = fsp_try_extend_data_file_with_pages(
2750 space, ret_page, space_header, mtr);
2758 if (!frag_page_allocated) {
2766 block = buf_page_create(space, ret_page, page_zip_size, mtr);
2767 buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
2769 if (UNIV_UNLIKELY(block !=
buf_page_get(space, page_zip_size,
2770 ret_page, RW_X_LATCH,
2776 fsp_init_file_page(block, mtr);
2782 ut_ad(xdes_get_descriptor(space, page_zip_size, ret_page, mtr)
2784 ut_ad(xdes_get_bit(ret_descr, XDES_FREE_BIT,
2785 ret_page % FSP_EXTENT_SIZE, mtr) == TRUE);
2787 fseg_mark_page_used(seg_inode, space, page_zip_size, ret_page, mtr);
2790 buf_reset_check_index_page_at_flush(space, ret_page);
2802 fseg_alloc_free_page_general(
2804 fseg_header_t* seg_header,
2811 ibool has_done_reservation,
2818 fseg_inode_t* inode;
2829 latch = fil_space_get_latch(space, &flags);
2833 ut_ad(!mutex_own(&kernel_mutex)
2834 || mtr_memo_contains(mtr, latch, MTR_MEMO_X_LOCK));
2842 if (space == IBUF_SPACE_ID) {
2843 ibuf_free_excess_pages();
2847 inode = fseg_inode_get(seg_header, space, zip_size, mtr);
2849 if (!has_done_reservation) {
2850 success = fsp_reserve_free_extents(&n_reserved, space, 2,
2857 page_no = fseg_alloc_free_page_low(space, zip_size,
2858 inode, hint, direction, mtr);
2859 if (!has_done_reservation) {
2860 fil_space_release_free_extents(space, n_reserved);
2873 fseg_alloc_free_page(
2875 fseg_header_t* seg_header,
2884 return(fseg_alloc_free_page_general(seg_header, hint, direction,
2897 fsp_reserve_free_pages(
2900 fsp_header_t* space_header,
2910 ut_a(size < FSP_EXTENT_SIZE / 2);
2912 descr = xdes_get_descriptor_with_space_hdr(space_header, space, 0,
2914 n_used = xdes_get_n_used(descr, mtr);
2916 ut_a(n_used <= size);
2918 if (size >= n_used + 2) {
2923 return(fsp_try_extend_data_file_with_pages(space, n_used + 1,
2924 space_header, mtr));
2955 fsp_reserve_free_extents(
2965 fsp_header_t* space_header;
2967 ulint n_free_list_ext;
2976 ulint n_pages_added;
2979 *n_reserved = n_ext;
2981 latch = fil_space_get_latch(space, &flags);
2984 ut_ad(!mutex_own(&kernel_mutex)
2985 || mtr_memo_contains(mtr, latch, MTR_MEMO_X_LOCK));
2989 space_header = fsp_get_space_header(space, zip_size, mtr);
2993 if (size < FSP_EXTENT_SIZE / 2) {
2996 return(fsp_reserve_free_pages(space, space_header, size, mtr));
2999 n_free_list_ext =
flst_get_len(space_header + FSP_FREE, mtr);
3008 n_free_up = (size - free_limit) / FSP_EXTENT_SIZE;
3010 if (n_free_up > 0) {
3013 n_free_up -= n_free_up
3014 / (UNIV_PAGE_SIZE / FSP_EXTENT_SIZE);
3016 n_free_up -= n_free_up
3017 / (zip_size / FSP_EXTENT_SIZE);
3021 n_free = n_free_list_ext + n_free_up;
3023 if (alloc_type == FSP_NORMAL) {
3028 reserve = 2 + ((size / FSP_EXTENT_SIZE) * 2) / 200;
3030 if (n_free <= reserve + n_ext) {
3034 }
else if (alloc_type == FSP_UNDO) {
3037 reserve = 1 + ((size / FSP_EXTENT_SIZE) * 1) / 200;
3039 if (n_free <= reserve + n_ext) {
3044 ut_a(alloc_type == FSP_CLEANING);
3047 success = fil_space_reserve_free_extents(space, n_free, n_ext);
3053 success = fsp_try_extend_data_file(&n_pages_added, space,
3055 if (success && n_pages_added > 0) {
3071 fsp_get_available_space_in_free_extents(
3075 fsp_header_t* space_header;
3076 ulint n_free_list_ext;
3087 ut_ad(!mutex_own(&kernel_mutex));
3104 mutex_enter(&dict_sys->
mutex);
3109 if (fil_tablespace_deleted_or_being_deleted_in_mem(space, -1)) {
3111 mutex_exit(&dict_sys->
mutex);
3113 return(ULLINT_UNDEFINED);
3118 latch = fil_space_get_latch(space, &flags);
3128 mutex_exit(&dict_sys->
mutex);
3135 if (fil_tablespace_is_being_deleted(space)) {
3139 return(ULLINT_UNDEFINED);
3146 space_header = fsp_get_space_header(space, zip_size, &mtr);
3150 n_free_list_ext =
flst_get_len(space_header + FSP_FREE, &mtr);
3156 if (size < FSP_EXTENT_SIZE) {
3168 n_free_up = (size - free_limit) / FSP_EXTENT_SIZE;
3170 if (n_free_up > 0) {
3173 n_free_up -= n_free_up
3174 / (UNIV_PAGE_SIZE / FSP_EXTENT_SIZE);
3176 n_free_up -= n_free_up
3177 / (zip_size / FSP_EXTENT_SIZE);
3181 n_free = n_free_list_ext + n_free_up;
3187 reserve = 2 + ((size / FSP_EXTENT_SIZE) * 2) / 200;
3189 if (reserve > n_free) {
3194 return((ullint) (n_free - reserve)
3196 * (UNIV_PAGE_SIZE / 1024));
3198 return((ullint) (n_free - reserve)
3200 * (zip_size / 1024));
3209 fseg_mark_page_used(
3211 fseg_inode_t* seg_inode,
3219 ulint not_full_n_used;
3221 ut_ad(seg_inode && mtr);
3224 == FSEG_MAGIC_N_VALUE);
3226 descr = xdes_get_descriptor(space, zip_size, page, mtr);
3231 if (xdes_is_free(descr, mtr)) {
3234 flst_remove(seg_inode + FSEG_FREE, descr + XDES_FLST_NODE,
3236 flst_add_last(seg_inode + FSEG_NOT_FULL,
3237 descr + XDES_FLST_NODE, mtr);
3240 ut_ad(xdes_get_bit(descr, XDES_FREE_BIT, page % FSP_EXTENT_SIZE, mtr)
3243 xdes_set_bit(descr, XDES_FREE_BIT, page % FSP_EXTENT_SIZE, FALSE, mtr);
3245 not_full_n_used =
mtr_read_ulint(seg_inode + FSEG_NOT_FULL_N_USED,
3250 if (xdes_is_full(descr, mtr)) {
3253 flst_remove(seg_inode + FSEG_NOT_FULL,
3254 descr + XDES_FLST_NODE, mtr);
3255 flst_add_last(seg_inode + FSEG_FULL,
3256 descr + XDES_FLST_NODE, mtr);
3259 not_full_n_used - FSP_EXTENT_SIZE,
3270 fseg_inode_t* seg_inode,
3278 ulint not_full_n_used;
3284 ut_ad(seg_inode && mtr);
3286 == FSEG_MAGIC_N_VALUE);
3292 btr_search_drop_page_hash_when_freed(space, zip_size, page);
3294 descr = xdes_get_descriptor(space, zip_size, page, mtr);
3297 if (xdes_get_bit(descr, XDES_FREE_BIT, page % FSP_EXTENT_SIZE, mtr)) {
3298 fputs(
"InnoDB: Dump of the tablespace extent descriptor: ",
3302 fprintf(stderr,
"\n"
3303 "InnoDB: Serious error! InnoDB is trying to"
3305 "InnoDB: though it is already marked as free"
3306 " in the tablespace!\n"
3307 "InnoDB: The tablespace free space info is corrupt.\n"
3308 "InnoDB: You may need to dump your"
3309 " InnoDB tables and recreate the whole\n"
3310 "InnoDB: database!\n", (ulong) page);
3312 fputs(
"InnoDB: Please refer to\n"
3313 "InnoDB: " REFMAN
"forcing-innodb-recovery.html\n"
3314 "InnoDB: about forcing recovery.\n", stderr);
3318 state = xdes_get_state(descr, mtr);
3320 if (state != XDES_FSEG) {
3324 if (fseg_get_nth_frag_page_no(seg_inode, i, mtr)
3327 fseg_set_nth_frag_page_no(seg_inode, i,
3333 fsp_free_page(space, zip_size, page, mtr);
3344 "InnoDB: InnoDB is freeing space %lu page %lu,\n"
3345 "InnoDB: which belongs to descr seg %llu\n"
3346 "InnoDB: segment %llu.\n",
3347 (ulong) space, (ulong) page,
3351 if (UNIV_UNLIKELY(descr_id != seg_id)) {
3352 fputs(
"InnoDB: Dump of the tablespace extent descriptor: ",
3355 fputs(
"\nInnoDB: Dump of the segment inode: ", stderr);
3360 "InnoDB: Serious error: InnoDB is trying to"
3361 " free space %lu page %lu,\n"
3362 "InnoDB: which does not belong to"
3363 " segment %llu but belongs\n"
3364 "InnoDB: to segment %llu.\n",
3365 (ulong) space, (ulong) page,
3371 not_full_n_used =
mtr_read_ulint(seg_inode + FSEG_NOT_FULL_N_USED,
3373 if (xdes_is_full(descr, mtr)) {
3375 flst_remove(seg_inode + FSEG_FULL,
3376 descr + XDES_FLST_NODE, mtr);
3377 flst_add_last(seg_inode + FSEG_NOT_FULL,
3378 descr + XDES_FLST_NODE, mtr);
3380 not_full_n_used + FSP_EXTENT_SIZE - 1,
3383 ut_a(not_full_n_used > 0);
3388 xdes_set_bit(descr, XDES_FREE_BIT, page % FSP_EXTENT_SIZE, TRUE, mtr);
3389 xdes_set_bit(descr, XDES_CLEAN_BIT, page % FSP_EXTENT_SIZE, TRUE, mtr);
3391 if (xdes_is_free(descr, mtr)) {
3393 flst_remove(seg_inode + FSEG_NOT_FULL,
3394 descr + XDES_FLST_NODE, mtr);
3395 fsp_free_extent(space, zip_size, page, mtr);
3405 fseg_header_t* seg_header,
3412 fseg_inode_t* seg_inode;
3415 latch = fil_space_get_latch(space, &flags);
3418 ut_ad(!mutex_own(&kernel_mutex)
3419 || mtr_memo_contains(mtr, latch, MTR_MEMO_X_LOCK));
3423 seg_inode = fseg_inode_get(seg_header, space, zip_size, mtr);
3425 fseg_free_page_low(seg_inode, space, zip_size, page, mtr);
3427 #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
3428 buf_page_set_file_page_was_freed(space, page);
3438 fseg_inode_t* seg_inode,
3445 ulint first_page_in_extent;
3447 ulint not_full_n_used;
3451 ut_ad(seg_inode && mtr);
3453 descr = xdes_get_descriptor(space, zip_size, page, mtr);
3455 ut_a(xdes_get_state(descr, mtr) == XDES_FSEG);
3456 ut_a(!memcmp(descr + XDES_ID, seg_inode + FSEG_ID, 8));
3458 == FSEG_MAGIC_N_VALUE);
3460 first_page_in_extent = page - (page % FSP_EXTENT_SIZE);
3462 for (i = 0; i < FSP_EXTENT_SIZE; i++) {
3463 if (FALSE == xdes_get_bit(descr, XDES_FREE_BIT, i, mtr)) {
3468 btr_search_drop_page_hash_when_freed(
3469 space, zip_size, first_page_in_extent + i);
3473 if (xdes_is_full(descr, mtr)) {
3474 flst_remove(seg_inode + FSEG_FULL,
3475 descr + XDES_FLST_NODE, mtr);
3476 }
else if (xdes_is_free(descr, mtr)) {
3477 flst_remove(seg_inode + FSEG_FREE,
3478 descr + XDES_FLST_NODE, mtr);
3480 flst_remove(seg_inode + FSEG_NOT_FULL,
3481 descr + XDES_FLST_NODE, mtr);
3484 seg_inode + FSEG_NOT_FULL_N_USED,
MLOG_4BYTES, mtr);
3486 descr_n_used = xdes_get_n_used(descr, mtr);
3487 ut_a(not_full_n_used >= descr_n_used);
3489 not_full_n_used - descr_n_used,
3493 fsp_free_extent(space, zip_size, page, mtr);
3495 #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
3496 for (i = 0; i < FSP_EXTENT_SIZE; i++) {
3498 buf_page_set_file_page_was_freed(space,
3499 first_page_in_extent + i);
3514 fseg_header_t* header,
3523 fseg_inode_t* inode;
3533 latch = fil_space_get_latch(space, &flags);
3536 ut_ad(!mutex_own(&kernel_mutex)
3537 || mtr_memo_contains(mtr, latch, MTR_MEMO_X_LOCK));
3541 descr = xdes_get_descriptor(space, zip_size, header_page, mtr);
3547 ut_a(xdes_get_bit(descr, XDES_FREE_BIT,
3548 header_page % FSP_EXTENT_SIZE, mtr) == FALSE);
3549 inode = fseg_inode_try_get(header, space, zip_size, mtr);
3551 if (UNIV_UNLIKELY(inode == NULL)) {
3552 fprintf(stderr,
"double free of inode from %u:%u\n",
3553 (
unsigned) space, (
unsigned) header_page);
3557 descr = fseg_get_first_extent(inode, space, zip_size, mtr);
3559 if (descr != NULL) {
3561 page = xdes_get_offset(descr);
3563 fseg_free_extent(inode, space, zip_size, page, mtr);
3569 n = fseg_find_last_used_frag_page_slot(inode, mtr);
3571 if (n == ULINT_UNDEFINED) {
3573 fsp_free_seg_inode(space, zip_size, inode, mtr);
3578 fseg_free_page_low(inode, space, zip_size,
3579 fseg_get_nth_frag_page_no(inode, n, mtr), mtr);
3581 n = fseg_find_last_used_frag_page_slot(inode, mtr);
3583 if (n == ULINT_UNDEFINED) {
3585 fsp_free_seg_inode(space, zip_size, inode, mtr);
3599 fseg_free_step_not_header(
3601 fseg_header_t* header,
3608 fseg_inode_t* inode;
3617 latch = fil_space_get_latch(space, &flags);
3620 ut_ad(!mutex_own(&kernel_mutex)
3621 || mtr_memo_contains(mtr, latch, MTR_MEMO_X_LOCK));
3625 inode = fseg_inode_get(header, space, zip_size, mtr);
3627 descr = fseg_get_first_extent(inode, space, zip_size, mtr);
3629 if (descr != NULL) {
3631 page = xdes_get_offset(descr);
3633 fseg_free_extent(inode, space, zip_size, page, mtr);
3640 n = fseg_find_last_used_frag_page_slot(inode, mtr);
3642 if (n == ULINT_UNDEFINED) {
3646 page_no = fseg_get_nth_frag_page_no(inode, n, mtr);
3653 fseg_free_page_low(inode, space, zip_size, page_no, mtr);
3665 fseg_get_first_extent(
3667 fseg_inode_t* inode,
3676 ut_ad(inode && mtr);
3681 first = fil_addr_null;
3687 }
else if (
flst_get_len(inode + FSEG_NOT_FULL, mtr) > 0) {
3700 descr = xdes_lst_get_descriptor(space, zip_size, first, mtr);
3712 fseg_inode_t* inode,
3723 ut_ad(mtr_memo_contains_page(mtr2, inode, MTR_MEMO_PAGE_X_FIX));
3731 flst_validate(inode + FSEG_FREE, mtr2);
3732 flst_validate(inode + FSEG_NOT_FULL, mtr2);
3733 flst_validate(inode + FSEG_FULL, mtr2);
3738 while (!fil_addr_is_null(node_addr)) {
3743 mtr_x_lock(fil_space_get_latch(space, &flags), &mtr);
3746 descr = xdes_lst_get_descriptor(space, zip_size,
3749 ut_a(xdes_get_n_used(descr, &mtr) == 0);
3750 ut_a(xdes_get_state(descr, &mtr) == XDES_FSEG);
3761 while (!fil_addr_is_null(node_addr)) {
3766 mtr_x_lock(fil_space_get_latch(space, &flags), &mtr);
3769 descr = xdes_lst_get_descriptor(space, zip_size,
3772 ut_a(xdes_get_n_used(descr, &mtr) > 0);
3773 ut_a(xdes_get_n_used(descr, &mtr) < FSP_EXTENT_SIZE);
3774 ut_a(xdes_get_state(descr, &mtr) == XDES_FSEG);
3777 n_used2 += xdes_get_n_used(descr, &mtr);
3787 while (!fil_addr_is_null(node_addr)) {
3792 mtr_x_lock(fil_space_get_latch(space, &flags), &mtr);
3795 descr = xdes_lst_get_descriptor(space, zip_size,
3798 ut_a(xdes_get_n_used(descr, &mtr) == FSP_EXTENT_SIZE);
3799 ut_a(xdes_get_state(descr, &mtr) == XDES_FSEG);
3806 ut_a(n_used == n_used2);
3819 fseg_header_t* header,
3822 fseg_inode_t* inode;
3830 mtr_x_lock(fil_space_get_latch(space, &flags), mtr);
3833 inode = fseg_inode_get(header, space, zip_size, mtr);
3835 ret = fseg_validate_low(inode, mtr);
3847 fseg_inode_t* inode,
3861 ut_ad(mtr_memo_contains_page(mtr, inode, MTR_MEMO_PAGE_X_FIX));
3865 reserved = fseg_n_reserved_pages_low(inode, &used, mtr);
3871 n_frag = fseg_get_n_frag_pages(inode, mtr);
3877 "SEGMENT id %llu space %lu; page %lu;"
3878 " res %lu used %lu; full ext %lu\n"
3879 "fragm pages %lu; free extents %lu;"
3880 " not full extents %lu: pages %lu\n",
3882 (ulong) space, (ulong) page_no,
3883 (ulong) reserved, (ulong) used, (ulong) n_full,
3884 (ulong) n_frag, (ulong) n_free, (ulong) n_not_full,
3889 #ifdef UNIV_BTR_PRINT
3896 fseg_header_t* header,
3899 fseg_inode_t* inode;
3906 mtr_x_lock(fil_space_get_latch(space, &flags), mtr);
3909 inode = fseg_inode_get(header, space, zip_size, mtr);
3911 fseg_print_low(inode, mtr);
3924 fsp_header_t* header;
3925 fseg_inode_t* seg_inode;
3938 ulint descr_count = 0;
3941 ulint n_full_frag_pages;
3943 ulint seg_inode_len_free;
3944 ulint seg_inode_len_full;
3946 latch = fil_space_get_latch(space, &flags);
3949 ut_a(zip_size <= UNIV_PAGE_SIZE);
3960 header = fsp_get_space_header(space, zip_size, &mtr);
3968 n_full_frag_pages = FSP_EXTENT_SIZE
3971 if (UNIV_UNLIKELY(free_limit > size)) {
3974 ut_a(size < FSP_EXTENT_SIZE);
3977 flst_validate(header + FSP_FREE, &mtr);
3978 flst_validate(header + FSP_FREE_FRAG, &mtr);
3979 flst_validate(header + FSP_FULL_FRAG, &mtr);
3987 header = fsp_get_space_header(space, zip_size, &mtr);
3992 while (!fil_addr_is_null(node_addr)) {
3997 descr = xdes_lst_get_descriptor(space, zip_size,
4000 ut_a(xdes_get_n_used(descr, &mtr) == 0);
4001 ut_a(xdes_get_state(descr, &mtr) == XDES_FREE);
4011 header = fsp_get_space_header(space, zip_size, &mtr);
4016 while (!fil_addr_is_null(node_addr)) {
4021 descr = xdes_lst_get_descriptor(space, zip_size,
4024 ut_a(xdes_get_n_used(descr, &mtr) > 0);
4025 ut_a(xdes_get_n_used(descr, &mtr) < FSP_EXTENT_SIZE);
4026 ut_a(xdes_get_state(descr, &mtr) == XDES_FREE_FRAG);
4028 n_used += xdes_get_n_used(descr, &mtr);
4038 header = fsp_get_space_header(space, zip_size, &mtr);
4043 while (!fil_addr_is_null(node_addr)) {
4048 descr = xdes_lst_get_descriptor(space, zip_size,
4051 ut_a(xdes_get_n_used(descr, &mtr) == FSP_EXTENT_SIZE);
4052 ut_a(xdes_get_state(descr, &mtr) == XDES_FULL_FRAG);
4062 header = fsp_get_space_header(space, zip_size, &mtr);
4066 seg_inode_len_full =
flst_get_len(header + FSP_SEG_INODES_FULL, &mtr);
4070 while (!fil_addr_is_null(node_addr)) {
4078 space, zip_size, node_addr, RW_X_LATCH, &mtr)
4079 - FSEG_INODE_PAGE_NODE;
4081 seg_inode = fsp_seg_inode_page_get_nth_inode(
4082 seg_inode_page, n, zip_size, &mtr);
4084 fseg_validate_low(seg_inode, &mtr);
4093 n_used2 += fseg_get_n_frag_pages(seg_inode, &mtr);
4096 seg_inode_page + FSEG_INODE_PAGE_NODE, &mtr);
4098 }
while (++n < FSP_SEG_INODES_PER_PAGE(zip_size));
4100 node_addr = next_node_addr;
4106 header = fsp_get_space_header(space, zip_size, &mtr);
4110 seg_inode_len_free =
flst_get_len(header + FSP_SEG_INODES_FREE, &mtr);
4114 while (!fil_addr_is_null(node_addr)) {
4123 space, zip_size, node_addr, RW_X_LATCH, &mtr)
4124 - FSEG_INODE_PAGE_NODE;
4126 seg_inode = fsp_seg_inode_page_get_nth_inode(
4127 seg_inode_page, n, zip_size, &mtr);
4129 fseg_validate_low(seg_inode, &mtr);
4132 seg_inode + FSEG_FREE, &mtr);
4134 seg_inode + FSEG_FULL, &mtr);
4136 seg_inode + FSEG_NOT_FULL, &mtr);
4137 n_used2 += fseg_get_n_frag_pages(
4142 seg_inode_page + FSEG_INODE_PAGE_NODE, &mtr);
4144 }
while (++n < FSP_SEG_INODES_PER_PAGE(zip_size));
4146 node_addr = next_node_addr;
4149 ut_a(descr_count * FSP_EXTENT_SIZE == free_limit);
4151 ut_a(n_used + n_full_frag_pages
4152 == n_used2 + 2 * ((free_limit + (UNIV_PAGE_SIZE - 1))
4154 + seg_inode_len_full + seg_inode_len_free);
4156 ut_a(n_used + n_full_frag_pages
4157 == n_used2 + 2 * ((free_limit + (zip_size - 1))
4159 + seg_inode_len_full + seg_inode_len_free);
4161 ut_a(frag_n_used == n_used);
4176 fsp_header_t* header;
4177 fseg_inode_t* seg_inode;
4196 latch = fil_space_get_latch(space, &flags);
4210 header = fsp_get_space_header(space, zip_size, &mtr);
4219 n_free_frag =
flst_get_len(header + FSP_FREE_FRAG, &mtr);
4220 n_full_frag =
flst_get_len(header + FSP_FULL_FRAG, &mtr);
4225 "FILE SPACE INFO: id %lu\n"
4226 "size %lu, free limit %lu, free extents %lu\n"
4227 "not full frag extents %lu: used pages %lu,"
4228 " full frag extents %lu\n"
4229 "first seg id not used %llu\n",
4231 (ulong) size, (ulong) free_limit, (ulong) n_free,
4232 (ulong) n_free_frag, (ulong) frag_n_used, (ulong) n_full_frag,
4242 header = fsp_get_space_header(space, zip_size, &mtr);
4248 while (!fil_addr_is_null(node_addr)) {
4258 space, zip_size, node_addr, RW_X_LATCH, &mtr)
4259 - FSEG_INODE_PAGE_NODE;
4261 seg_inode = fsp_seg_inode_page_get_nth_inode(
4262 seg_inode_page, n, zip_size, &mtr);
4264 fseg_print_low(seg_inode, &mtr);
4269 seg_inode_page + FSEG_INODE_PAGE_NODE, &mtr);
4271 }
while (++n < FSP_SEG_INODES_PER_PAGE(zip_size));
4273 node_addr = next_node_addr;
4279 header = fsp_get_space_header(space, zip_size, &mtr);
4285 while (!fil_addr_is_null(node_addr)) {
4295 space, zip_size, node_addr, RW_X_LATCH, &mtr)
4296 - FSEG_INODE_PAGE_NODE;
4298 seg_inode = fsp_seg_inode_page_get_nth_inode(
4299 seg_inode_page, n, zip_size, &mtr);
4302 fseg_print_low(seg_inode, &mtr);
4307 seg_inode_page + FSEG_INODE_PAGE_NODE, &mtr);
4309 }
while (++n < FSP_SEG_INODES_PER_PAGE(zip_size));
4311 node_addr = next_node_addr;
4316 fprintf(stderr,
"NUMBER of file segments: %lu\n", (ulong) n_segs);