34 #include "xtrabackup_api.h"
36 #ifndef UNIV_HOTBACKUP
46 #ifdef UNIV_BLOB_DEBUG
51 static ibool btr_blob_dbg_msg;
57 #define btr_blob_dbg_msg_issue(op, b, ctx) \
58 fprintf(stderr, op " %u:%u:%u->%u %s(%u,%u,%u)\n", \
59 (b)->ref_page_no, (b)->ref_heap_no, \
60 (b)->ref_field_no, (b)->blob_page_no, ctx, \
61 (b)->owner, (b)->always_owner, (b)->del)
69 btr_blob_dbg_rbt_insert(
72 const btr_blob_dbg_t* b,
75 if (btr_blob_dbg_msg) {
76 btr_blob_dbg_msg_issue(
"insert", b, ctx);
78 mutex_enter(&index->blobs_mutex);
80 mutex_exit(&index->blobs_mutex);
89 btr_blob_dbg_rbt_delete(
92 const btr_blob_dbg_t* b,
95 if (btr_blob_dbg_msg) {
96 btr_blob_dbg_msg_issue(
"delete", b, ctx);
98 mutex_enter(&index->blobs_mutex);
100 mutex_exit(&index->blobs_mutex);
114 const btr_blob_dbg_t* aa = a;
115 const btr_blob_dbg_t* bb = b;
120 if (aa->ref_page_no != bb->ref_page_no) {
121 return(aa->ref_page_no < bb->ref_page_no ? -1 : 1);
123 if (aa->ref_heap_no != bb->ref_heap_no) {
124 return(aa->ref_heap_no < bb->ref_heap_no ? -1 : 1);
126 if (aa->ref_field_no != bb->ref_field_no) {
127 return(aa->ref_field_no < bb->ref_field_no ? -1 : 1);
136 btr_blob_dbg_add_blob(
149 b.blob_page_no = page_no;
152 b.ref_field_no = field_no;
154 b.always_owner = b.owner = TRUE;
157 btr_blob_dbg_rbt_insert(index, &b, ctx);
165 btr_blob_dbg_add_rec(
169 const ulint* offsets,
190 const byte* field_ref = rec_get_nth_field(
191 rec, offsets, i, &len);
193 ut_a(len != UNIV_SQL_NULL);
197 if (!memcmp(field_ref, field_ref_zero,
198 BTR_EXTERN_FIELD_REF_SIZE)) {
207 b.always_owner = b.owner
212 btr_blob_dbg_rbt_insert(index, &b, ctx);
241 node != NULL; node =
rbt_next(index->blobs, node)) {
242 const btr_blob_dbg_t* b
243 = rbt_value(btr_blob_dbg_t, node);
244 fprintf(stderr,
"%u:%u:%u->%u%s%s%s\n",
245 b->ref_page_no, b->ref_heap_no, b->ref_field_no,
247 b->owner ?
"" :
"(disowned)",
248 b->always_owner ?
"" :
"(has disowned)",
249 b->del ?
"(deleted)" :
"");
258 btr_blob_dbg_remove_rec(
262 const ulint* offsets,
281 const byte* field_ref = rec_get_nth_field(
282 rec, offsets, i, &len);
284 ut_a(len != UNIV_SQL_NULL);
285 ut_a(len >= BTR_EXTERN_FIELD_REF_SIZE);
292 switch (b.blob_page_no) {
299 ut_a(!memcmp(field_ref, field_ref_zero,
300 BTR_EXTERN_FIELD_REF_SIZE));
307 btr_blob_dbg_rbt_delete(index, &b, ctx);
321 btr_blob_dbg_is_empty(
327 ibool success = TRUE;
333 mutex_enter(&index->blobs_mutex);
336 node != NULL; node =
rbt_next(index->blobs, node)) {
337 const btr_blob_dbg_t* b
338 = rbt_value(btr_blob_dbg_t, node);
340 if (b->ref_page_no != page_no && b->blob_page_no != page_no) {
345 "InnoDB: orphan BLOB ref%s%s%s %u:%u:%u->%u\n",
346 b->owner ?
"" :
"(disowned)",
347 b->always_owner ?
"" :
"(has disowned)",
348 b->del ?
"(deleted)" :
"",
349 b->ref_page_no, b->ref_heap_no, b->ref_field_no,
352 if (b->blob_page_no != page_no || b->owner || !b->del) {
357 mutex_exit(&index->blobs_mutex);
373 const btr_blob_dbg_op_f op)
377 ulint offsets_[REC_OFFS_NORMAL_SIZE];
378 ulint* offsets = offsets_;
379 rec_offs_init(offsets_);
390 rec = page_get_infimum_rec(page);
394 offsets = rec_get_offsets(rec, index, offsets,
395 ULINT_UNDEFINED, &heap);
396 count += op(rec, index, offsets, ctx);
400 if (UNIV_LIKELY_NULL(heap)) {
421 return(btr_blob_dbg_op(page, NULL, index, ctx, btr_blob_dbg_add_rec));
439 count = btr_blob_dbg_op(page, NULL, index, ctx,
440 btr_blob_dbg_remove_rec);
453 btr_blob_dbg_restore(
466 removed = btr_blob_dbg_remove(npage, index, ctx);
467 added = btr_blob_dbg_add(page, index, ctx);
468 ut_a(added == removed);
475 btr_blob_dbg_set_deleted_flag(
479 const ulint* offsets,
502 const byte* field_ref = rec_get_nth_field(
503 rec, offsets, i, &len);
505 ut_a(len != UNIV_SQL_NULL);
506 ut_a(len >= BTR_EXTERN_FIELD_REF_SIZE);
513 switch (b.blob_page_no) {
515 ut_a(memcmp(field_ref, field_ref_zero,
516 BTR_EXTERN_FIELD_REF_SIZE));
524 mutex_enter(&index->blobs_mutex);
528 c = rbt_value(btr_blob_dbg_t, node);
531 if (btr_blob_dbg_msg) {
533 mutex_exit(&index->blobs_mutex);
534 btr_blob_dbg_msg_issue(
"del_mk", &b,
"");
536 mutex_exit(&index->blobs_mutex);
550 const ulint* offsets,
556 const byte* field_ref;
562 field_ref = rec_get_nth_field(rec, offsets, i, &len);
563 ut_a(len != UNIV_SQL_NULL);
564 ut_a(len >= BTR_EXTERN_FIELD_REF_SIZE);
573 ut_a(b.owner == own);
575 mutex_enter(&index->blobs_mutex);
581 ut_a(!memcmp(field_ref, field_ref_zero, BTR_EXTERN_FIELD_REF_SIZE)
585 btr_blob_dbg_t* c = rbt_value(btr_blob_dbg_t, node);
588 ut_a(own || c->owner);
592 c->always_owner = FALSE;
596 mutex_exit(&index->blobs_mutex);
655 #ifdef UNIV_BTR_DEBUG
661 btr_root_fseg_validate(
663 const fseg_header_t* seg_header,
693 block =
btr_block_get(space, zip_size, root_page_no, RW_X_LATCH, mtr);
696 #ifdef UNIV_BTR_DEBUG
698 const page_t* root = buf_block_get_frame(block);
720 return(buf_block_get_frame(btr_root_block_get(index, mtr)));
729 btr_get_prev_user_rec(
759 zip_size = fil_space_get_zip_size(space);
763 prev_page = buf_block_get_frame(prev_block);
765 ut_ad(mtr_memo_contains(mtr, prev_block,
767 || mtr_memo_contains(mtr, prev_block,
768 MTR_MEMO_PAGE_X_FIX));
769 #ifdef UNIV_BTR_DEBUG
787 btr_get_next_user_rec(
816 zip_size = fil_space_get_zip_size(space);
820 next_page = buf_block_get_frame(next_block);
822 ut_ad(mtr_memo_contains(mtr, next_block, MTR_MEMO_PAGE_S_FIX)
823 || mtr_memo_contains(mtr, next_block,
824 MTR_MEMO_PAGE_X_FIX));
825 #ifdef UNIV_BTR_DEBUG
850 page_t* page = buf_block_get_frame(block);
852 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
855 if (UNIV_LIKELY_NULL(page_zip)) {
860 btr_page_set_level(page, NULL, level, mtr);
865 btr_page_set_index_id(page, page_zip, index->
id, mtr);
874 btr_page_alloc_for_ibuf(
884 root = btr_root_get(index, mtr);
887 + PAGE_BTR_IBUF_FREE_LIST, mtr);
892 node_addr.
page, RW_X_LATCH, mtr);
893 new_page = buf_block_get_frame(new_block);
894 buf_block_dbg_add_level(new_block, SYNC_TREE_NODE_NEW);
896 flst_remove(root + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST,
897 new_page + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST_NODE,
899 ut_ad(flst_validate(root + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST,
921 fseg_header_t* seg_header;
928 return(btr_page_alloc_for_ibuf(index, mtr));
931 root = btr_root_get(index, mtr);
934 seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_LEAF;
936 seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_TOP;
943 new_page_no = fseg_alloc_free_page_general(seg_header, hint_page_no,
944 file_direction, TRUE, mtr);
952 new_page_no, RW_X_LATCH, mtr);
953 buf_block_dbg_add_level(new_block, SYNC_TREE_NODE_NEW);
968 fseg_header_t* seg_header;
978 root = btr_root_get(index, &mtr);
980 if (flag == BTR_N_LEAF_PAGES) {
981 seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_LEAF;
983 fseg_n_reserved_pages(seg_header, &n, &mtr);
985 }
else if (flag == BTR_TOTAL_SIZE) {
986 seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_TOP;
988 n = fseg_n_reserved_pages(seg_header, &dummy, &mtr);
990 seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_LEAF;
992 n += fseg_n_reserved_pages(seg_header, &dummy, &mtr);
1007 btr_page_free_for_ibuf(
1015 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
1016 root = btr_root_get(index, mtr);
1018 flst_add_first(root + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST,
1019 buf_block_get_frame(block)
1020 + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST_NODE, mtr);
1022 ut_ad(flst_validate(root + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST,
1039 fseg_header_t* seg_header;
1042 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
1051 btr_page_free_for_ibuf(index, block, mtr);
1056 root = btr_root_get(index, mtr);
1059 seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_LEAF;
1061 seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_TOP;
1064 fseg_free_page(seg_header,
1084 btr_page_free_low(index, block, level, mtr);
1091 btr_node_ptr_set_child_page_no(
1096 const ulint* offsets,
1108 field = rec_get_nth_field(rec, offsets,
1111 ut_ad(len == REC_NODE_PTR_SIZE);
1113 if (UNIV_LIKELY_NULL(page_zip)) {
1126 btr_node_ptr_get_child(
1128 const rec_t* node_ptr,
1130 const ulint* offsets,
1141 page_no, RW_X_LATCH, mtr));
1150 btr_page_get_father_node_ptr_func(
1180 tuple = dict_index_build_node_ptr(index, user_rec, 0, heap, level);
1182 btr_cur_search_to_nth_level(index, level + 1, tuple, PAGE_CUR_LE,
1189 offsets = rec_get_offsets(node_ptr, index, offsets,
1190 ULINT_UNDEFINED, &heap);
1195 fputs(
"InnoDB: Dump of the child page:\n", stderr);
1197 fputs(
"InnoDB: Dump of the parent page:\n", stderr);
1200 fputs(
"InnoDB: Corruption of an index tree: table ", stderr);
1202 fputs(
", index ", stderr);
1204 fprintf(stderr,
",\n"
1205 "InnoDB: father ptr page no %lu, child page no %lu\n",
1211 offsets = rec_get_offsets(print_rec, index,
1212 offsets, ULINT_UNDEFINED, &heap);
1214 offsets = rec_get_offsets(node_ptr, index, offsets,
1215 ULINT_UNDEFINED, &heap);
1218 fputs(
"InnoDB: You should dump + drop + reimport the table"
1220 "InnoDB: corruption. If the crash happens at "
1221 "the database startup, see\n"
1222 "InnoDB: " REFMAN
"forcing-innodb-recovery.html about\n"
1223 "InnoDB: forcing recovery. "
1224 "Then dump + drop + reimport.\n", stderr);
1232 #define btr_page_get_father_node_ptr(of,heap,cur,mtr) \
1233 btr_page_get_father_node_ptr_func(of,heap,cur,__FILE__,__LINE__,mtr)
1241 btr_page_get_father_block(
1255 return(btr_page_get_father_node_ptr(offsets, heap, cursor, mtr));
1263 btr_page_get_father(
1278 btr_page_get_father_node_ptr(NULL, heap, cursor, mtr);
1293 index_id_t index_id,
1312 IBUF_HEADER + IBUF_TREE_SEG_HEADER, mtr);
1314 buf_block_dbg_add_level(ibuf_hdr_block, SYNC_TREE_NODE_NEW);
1317 == IBUF_HEADER_PAGE_NO);
1321 page_no = fseg_alloc_free_page(buf_block_get_frame(
1324 + IBUF_TREE_SEG_HEADER,
1325 IBUF_TREE_ROOT_PAGE_NO,
1327 ut_ad(page_no == IBUF_TREE_ROOT_PAGE_NO);
1332 #ifdef UNIV_BLOB_DEBUG
1334 mutex_create(PFS_NOT_INSTRUMENTED,
1335 &index->blobs_mutex, SYNC_ANY_LATCH);
1336 index->blobs =
rbt_create(
sizeof(btr_blob_dbg_t),
1340 block = fseg_create(space, 0,
1341 PAGE_HEADER + PAGE_BTR_SEG_TOP, mtr);
1344 if (block == NULL) {
1350 frame = buf_block_get_frame(block);
1352 buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW);
1354 if (type & DICT_IBUF) {
1357 ut_ad(page_no == IBUF_TREE_ROOT_PAGE_NO);
1359 flst_init(frame + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST, mtr);
1363 if (!fseg_create(space, page_no,
1364 PAGE_HEADER + PAGE_BTR_SEG_LEAF, mtr)) {
1367 btr_free_root(space, zip_size, page_no, mtr);
1374 buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW);
1380 if (UNIV_LIKELY_NULL(page_zip)) {
1386 btr_page_set_level(page, NULL, 0, mtr);
1392 btr_page_set_index_id(page, page_zip, index_id, mtr);
1395 btr_page_set_next(page, page_zip,
FIL_NULL, mtr);
1396 btr_page_set_prev(page, page_zip,
FIL_NULL, mtr);
1403 ibuf_reset_free_bits(block);
1420 btr_free_but_not_root(
1434 root =
btr_page_get(space, zip_size, root_page_no, RW_X_LATCH, &mtr);
1435 #ifdef UNIV_BTR_DEBUG
1445 finished = fseg_free_step(root + PAGE_HEADER + PAGE_BTR_SEG_LEAF,
1456 root =
btr_page_get(space, zip_size, root_page_no, RW_X_LATCH, &mtr);
1457 #ifdef UNIV_BTR_DEBUG
1462 finished = fseg_free_step_not_header(
1463 root + PAGE_HEADER + PAGE_BTR_SEG_TOP, &mtr);
1486 fseg_header_t* header;
1488 block =
btr_block_get(space, zip_size, root_page_no, RW_X_LATCH, mtr);
1490 btr_search_drop_page_hash_index(block);
1492 header = buf_block_get_frame(block) + PAGE_HEADER + PAGE_BTR_SEG_TOP;
1493 #ifdef UNIV_BTR_DEBUG
1494 ut_a(btr_root_fseg_validate(header, space));
1497 while (!fseg_free_step(header, mtr)) {};
1505 btr_page_reorganize_low(
1517 page_t* page = buf_block_get_frame(block);
1524 ulint max_ins_size1;
1525 ulint max_ins_size2;
1526 ibool success = FALSE;
1528 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
1530 #ifdef UNIV_ZIP_DEBUG
1531 ut_a(!page_zip || page_zip_validate(page_zip, page));
1536 #ifndef UNIV_HOTBACKUP
1546 #ifndef UNIV_HOTBACKUP
1547 temp_block = buf_block_alloc(buf_pool);
1549 ut_ad(block == back_block1);
1550 temp_block = back_block2;
1552 temp_page = temp_block->
frame;
1557 #ifndef UNIV_HOTBACKUP
1558 if (UNIV_LIKELY(!recovery)) {
1559 btr_search_drop_page_hash_index(block);
1564 btr_blob_dbg_remove(page, index,
"btr_page_reorganize");
1575 page_get_infimum_rec(temp_page),
1585 ut_ad(max_trx_id != 0 || recovery);
1588 if (UNIV_LIKELY_NULL(page_zip)
1593 btr_blob_dbg_restore(page, temp_page, index,
1594 "btr_page_reorganize_compress_fail");
1596 #if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
1598 ut_a(!memcmp(page, temp_page, PAGE_HEADER));
1599 ut_a(!memcmp(PAGE_HEADER + PAGE_N_RECS + page,
1600 PAGE_HEADER + PAGE_N_RECS + temp_page,
1601 PAGE_DATA - (PAGE_HEADER + PAGE_N_RECS)));
1607 memcpy(PAGE_HEADER + page, PAGE_HEADER + temp_page,
1608 PAGE_N_RECS - PAGE_N_DIR_SLOTS);
1609 memcpy(PAGE_DATA + page, PAGE_DATA + temp_page,
1612 #if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
1613 ut_a(!memcmp(page, temp_page, UNIV_PAGE_SIZE));
1619 #ifndef UNIV_HOTBACKUP
1620 if (UNIV_LIKELY(!recovery)) {
1629 if (UNIV_UNLIKELY(data_size1 != data_size2)
1630 || UNIV_UNLIKELY(max_ins_size1 != max_ins_size2)) {
1631 buf_page_print(page, 0);
1632 buf_page_print(temp_page, 0);
1634 "InnoDB: Error: page old data size %lu"
1635 " new data size %lu\n"
1636 "InnoDB: Error: page old max ins size %lu"
1637 " new max ins size %lu\n"
1638 "InnoDB: Submit a detailed bug report"
1639 " to http://bugs.mysql.com\n",
1640 (
unsigned long) data_size1, (
unsigned long) data_size2,
1641 (
unsigned long) max_ins_size1,
1642 (
unsigned long) max_ins_size2);
1648 #ifdef UNIV_ZIP_DEBUG
1649 ut_a(!page_zip || page_zip_validate(page_zip, page));
1651 #ifndef UNIV_HOTBACKUP
1661 #ifndef UNIV_HOTBACKUP
1671 btr_page_reorganize(
1677 return(btr_page_reorganize_low(FALSE, block, index, mtr));
1686 btr_parse_page_reorganize(
1695 ut_ad(ptr && end_ptr);
1699 if (UNIV_LIKELY(block != NULL)) {
1700 btr_page_reorganize_low(TRUE, block, index, mtr);
1706 #ifndef UNIV_HOTBACKUP
1719 page_t* page = buf_block_get_frame(block);
1721 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
1723 #ifdef UNIV_ZIP_DEBUG
1724 ut_a(!page_zip || page_zip_validate(page_zip, page));
1727 btr_search_drop_page_hash_index(block);
1728 btr_blob_dbg_remove(page, index,
"btr_page_empty");
1733 if (UNIV_LIKELY_NULL(page_zip)) {
1737 btr_page_set_level(page, NULL, level, mtr);
1752 btr_root_raise_and_insert(
1770 rec_t* node_ptr_rec;
1780 #ifdef UNIV_ZIP_DEBUG
1781 ut_a(!root_page_zip || page_zip_validate(root_page_zip, root));
1784 #ifdef UNIV_BTR_DEBUG
1798 ut_ad(mtr_memo_contains(mtr, root_block, MTR_MEMO_PAGE_X_FIX));
1806 new_block = btr_page_alloc(index, 0, FSP_NO_DIR, level, mtr);
1807 new_page = buf_block_get_frame(new_block);
1809 ut_a(!new_page_zip == !root_page_zip);
1814 btr_page_create(new_block, new_page_zip, index, level, mtr);
1817 btr_page_set_next(new_page, new_page_zip,
FIL_NULL, mtr);
1818 btr_page_set_prev(new_page, new_page_zip,
FIL_NULL, mtr);
1823 #ifdef UNIV_ZIP_COPY
1828 page_get_infimum_rec(root),
1834 root_page_zip, root, index, mtr);
1839 page_get_infimum_rec(root));
1841 btr_search_move_or_delete_hash_entries(new_block, root_block,
1861 node_ptr = dict_index_build_node_ptr(index, rec, new_page_no, heap,
1868 | REC_INFO_MIN_REC_FLAG);
1871 btr_page_empty(root_block, root_page_zip, index, level + 1, mtr);
1878 btr_page_set_next(root, root_page_zip,
FIL_NULL, mtr);
1879 btr_page_set_prev(root, root_page_zip,
FIL_NULL, mtr);
1881 page_cursor = btr_cur_get_page_cur(cursor);
1900 fprintf(stderr,
"Root raise new page no %lu\n", new_page_no);
1904 ibuf_reset_free_bits(new_block);
1909 PAGE_CUR_LE, page_cursor);
1912 return(btr_page_split_and_insert(cursor, tuple, n_ext, mtr));
1921 btr_page_get_split_rec_to_left(
1930 rec_t* insert_point;
1939 infimum = page_get_infimum_rec(page);
1946 if (infimum != insert_point
1949 *split_rec = insert_point;
1966 btr_page_get_split_rec_to_right(
1975 rec_t* insert_point;
2009 *split_rec = next_next_rec;
2026 btr_page_get_split_rec(
2053 if (UNIV_LIKELY_NULL(page_zip)) {
2059 if (UNIV_LIKELY(free_space > (ulint) free_space_zip)) {
2060 free_space = (ulint) free_space_zip;
2068 ut_ad(total_n_recs >= 2);
2074 rec = page_get_infimum_rec(page);
2088 if (rec == ins_rec) {
2091 }
else if (rec == NULL) {
2099 incl_data += insert_size;
2101 offsets = rec_get_offsets(rec, cursor->
index,
2102 offsets, ULINT_UNDEFINED,
2116 if (rec == ins_rec) {
2120 }
else if (rec == NULL) {
2132 if (UNIV_LIKELY_NULL(heap)) {
2144 btr_page_insert_fits(
2148 const rec_t* split_rec,
2151 const ulint* offsets,
2163 const rec_t* end_rec;
2168 ut_ad(!split_rec == !offsets);
2186 if (split_rec == NULL) {
2193 end_rec = split_rec;
2196 end_rec = page_get_supremum_rec(page);
2210 while (rec != end_rec) {
2214 offs = rec_get_offsets(rec, cursor->
index, offs,
2215 ULINT_UNDEFINED, &heap);
2240 btr_insert_on_non_leaf_level_func(
2256 btr_cur_search_to_nth_level(index, level, tuple, PAGE_CUR_LE,
2258 &cursor, 0, file, line, mtr);
2260 err = btr_cur_pessimistic_insert(BTR_NO_LOCKING_FLAG
2262 | BTR_NO_UNDO_LOG_FLAG,
2263 &cursor, tuple, &rec,
2264 &dummy_big_rec, 0, NULL, mtr);
2265 ut_a(err == DB_SUCCESS);
2273 btr_attach_half_pages(
2288 page_t* page = buf_block_get_frame(block);
2291 ulint lower_page_no;
2292 ulint upper_page_no;
2298 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
2299 ut_ad(mtr_memo_contains(mtr, new_block, MTR_MEMO_PAGE_X_FIX));
2305 if (direction == FSP_DOWN) {
2310 lower_page = buf_block_get_frame(new_block);
2313 upper_page = buf_block_get_frame(block);
2318 offsets = btr_page_get_father_block(NULL, heap, index,
2319 block, mtr, &cursor);
2324 btr_node_ptr_set_child_page_no(
2327 offsets, lower_page_no, mtr);
2330 lower_page = buf_block_get_frame(block);
2333 upper_page = buf_block_get_frame(new_block);
2346 node_ptr_upper = dict_index_build_node_ptr(index, split_rec,
2347 upper_page_no, heap, level);
2352 btr_insert_on_non_leaf_level(index, level + 1, node_ptr_upper, mtr);
2370 #ifdef UNIV_BTR_DEBUG
2376 btr_page_set_next(buf_block_get_frame(prev_block),
2378 lower_page_no, mtr);
2385 #ifdef UNIV_BTR_DEBUG
2391 btr_page_set_prev(buf_block_get_frame(next_block),
2393 upper_page_no, mtr);
2396 btr_page_set_prev(lower_page, lower_page_zip, prev_page_no, mtr);
2397 btr_page_set_next(lower_page, lower_page_zip, upper_page_no, mtr);
2399 btr_page_set_prev(upper_page, upper_page_zip, lower_page_no, mtr);
2400 btr_page_set_next(upper_page, upper_page_zip, next_page_no, mtr);
2408 btr_page_tuple_smaller(
2418 const rec_t* first_rec;
2425 first_rec = page_cur_get_rec(&pcur);
2427 offsets = rec_get_offsets(
2428 first_rec, cursor->
index, offsets,
2445 btr_page_split_and_insert(
2471 ibool insert_will_fit;
2473 ulint n_iterations = 0;
2487 #ifdef UNIV_SYNC_DEBUG
2492 page = buf_block_get_frame(block);
2495 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
2503 insert_left = FALSE;
2505 if (n_iterations > 0) {
2507 hint_page_no = page_no + 1;
2508 split_rec = btr_page_get_split_rec(cursor, tuple, n_ext);
2510 if (UNIV_UNLIKELY(split_rec == NULL)) {
2511 insert_left = btr_page_tuple_smaller(
2512 cursor, tuple, offsets, n_uniq, &heap);
2514 }
else if (btr_page_get_split_rec_to_right(cursor, &split_rec)) {
2516 hint_page_no = page_no + 1;
2517 }
else if (btr_page_get_split_rec_to_left(cursor, &split_rec)) {
2518 direction = FSP_DOWN;
2519 hint_page_no = page_no - 1;
2523 hint_page_no = page_no + 1;
2531 }
else if (btr_page_tuple_smaller(cursor, tuple,
2532 offsets, n_uniq, &heap)) {
2534 page_get_infimum_rec(page));
2541 new_block = btr_page_alloc(cursor->
index, hint_page_no, direction,
2543 new_page = buf_block_get_frame(new_block);
2545 btr_page_create(new_block, new_page_zip, cursor->
index,
2553 first_rec = move_limit = split_rec;
2555 offsets = rec_get_offsets(split_rec, cursor->
index, offsets,
2560 if (UNIV_UNLIKELY(!insert_left && new_page_zip
2561 && n_iterations > 0)) {
2568 }
else if (UNIV_UNLIKELY(insert_left)) {
2569 ut_a(n_iterations > 0);
2575 ut_ad(!insert_left);
2586 btr_attach_half_pages(cursor->
index, block,
2587 first_rec, new_block, direction, mtr);
2595 insert_will_fit = !new_page_zip
2596 && btr_page_insert_fits(cursor, split_rec,
2597 offsets, tuple, n_ext, heap);
2604 insert_will_fit = !new_page_zip
2605 && btr_page_insert_fits(cursor, NULL,
2606 NULL, tuple, n_ext, heap);
2616 if (direction == FSP_DOWN) {
2620 #ifdef UNIV_ZIP_COPY
2625 cursor->
index, mtr))) {
2634 page_zip, page, cursor->
index, mtr);
2636 new_block, cursor->
index,
2638 ULINT_UNDEFINED, mtr);
2643 new_block, block, move_limit,
2644 new_page + PAGE_NEW_INFIMUM);
2646 btr_search_move_or_delete_hash_entries(
2647 new_block, block, cursor->
index);
2652 cursor->
index, mtr);
2655 left_block = new_block;
2656 right_block = block;
2663 #ifdef UNIV_ZIP_COPY
2668 cursor->
index, mtr))) {
2677 page_zip, page, cursor->
index, mtr);
2679 + new_page, new_block,
2680 cursor->
index, mtr);
2686 btr_search_move_or_delete_hash_entries(
2687 new_block, block, cursor->
index);
2694 ULINT_UNDEFINED, mtr);
2698 right_block = new_block;
2703 #ifdef UNIV_ZIP_DEBUG
2704 if (UNIV_LIKELY_NULL(page_zip)) {
2705 ut_a(page_zip_validate(page_zip, page));
2706 ut_a(page_zip_validate(new_page_zip, new_page));
2717 insert_block = left_block;
2719 insert_block = right_block;
2723 page_cursor = btr_cur_get_page_cur(cursor);
2726 PAGE_CUR_LE, page_cursor);
2729 cursor->
index, n_ext, mtr);
2731 #ifdef UNIV_ZIP_DEBUG
2734 = buf_block_get_frame(insert_block);
2739 ut_a(!insert_page_zip
2740 || page_zip_validate(insert_page_zip, insert_page));
2744 if (UNIV_LIKELY(rec != NULL)) {
2752 (!btr_page_reorganize(insert_block, cursor->
index, mtr))) {
2758 PAGE_CUR_LE, page_cursor);
2762 if (UNIV_UNLIKELY(rec == NULL)) {
2768 ibuf_reset_free_bits(new_block);
2774 ut_ad(n_iterations < 2
2776 ut_ad(!insert_will_fit);
2786 ibuf_update_free_bits_for_two_pages_low(
2788 left_block, right_block, mtr);
2792 fprintf(stderr,
"Split and insert done %lu %lu\n",
2808 btr_level_list_remove(
2820 ut_ad(mtr_memo_contains_page(mtr, page, MTR_MEMO_PAGE_X_FIX));
2834 = buf_block_get_frame(prev_block);
2835 #ifdef UNIV_BTR_DEBUG
2841 btr_page_set_next(prev_page,
2851 = buf_block_get_frame(next_block);
2852 #ifdef UNIV_BTR_DEBUG
2858 btr_page_set_prev(next_page,
2869 btr_set_min_rec_mark_log(
2881 # define btr_set_min_rec_mark_log(rec,comp,mtr) ((void) 0)
2890 btr_parse_set_min_rec_mark(
2900 if (end_ptr < ptr + 2) {
2910 btr_set_min_rec_mark(rec, mtr);
2920 btr_set_min_rec_mark(
2942 #ifndef UNIV_HOTBACKUP
2947 btr_node_ptr_delete(
2957 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
2960 btr_page_get_father(index, block, mtr, &cursor);
2962 compressed = btr_cur_pessimistic_delete(&err, TRUE, &cursor,
RB_NONE,
2964 ut_a(err == DB_SUCCESS);
2967 btr_cur_compress_if_useful(&cursor, mtr);
2989 page_t* page = buf_block_get_frame(block);
2997 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
3008 offsets = btr_page_get_father_block(NULL, heap, index,
3009 block, mtr, &cursor);
3012 father_page = buf_block_get_frame(father_block);
3021 for (b = father_block;
3025 offsets = btr_page_get_father_block(offsets, heap,
3035 btr_search_drop_page_hash_index(block);
3038 btr_page_empty(father_block, father_page_zip, index, page_level, mtr);
3042 #ifdef UNIV_ZIP_COPY
3047 page_get_infimum_rec(page),
3051 ut_a(father_page_zip);
3056 page_zip, page, index, mtr);
3061 page_get_infimum_rec(page));
3063 btr_search_move_or_delete_hash_entries(father_block, block,
3067 btr_blob_dbg_remove(page, index,
"btr_lift_page_up");
3071 for (i = 0; i < n_blocks; i++, page_level++) {
3072 page_t* inner_page = buf_block_get_frame(blocks[i]);
3077 btr_page_set_level(inner_page, page_zip, page_level, mtr);
3078 #ifdef UNIV_ZIP_DEBUG
3079 ut_a(!page_zip || page_zip_validate(page_zip, inner_page));
3084 btr_page_free(index, block, mtr);
3088 ibuf_reset_free_bits(father_block);
3091 ut_ad(btr_check_node_ptr(index, father_block, mtr));
3118 ulint right_page_no;
3131 ulint max_ins_size_reorg;
3140 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
3148 fprintf(stderr,
"Merge left page %lu right %lu \n",
3149 left_page_no, right_page_no);
3153 offsets = btr_page_get_father_block(NULL, heap, index, block, mtr,
3159 is_left = left_page_no !=
FIL_NULL;
3165 merge_page = buf_block_get_frame(merge_block);
3166 #ifdef UNIV_BTR_DEBUG
3170 }
else if (right_page_no !=
FIL_NULL) {
3174 merge_page = buf_block_get_frame(merge_block);
3175 #ifdef UNIV_BTR_DEBUG
3182 btr_lift_page_up(index, block, mtr);
3189 #ifdef UNIV_BTR_DEBUG
3194 merge_page, n_recs);
3195 if (data_size > max_ins_size_reorg) {
3203 ibuf_reset_free_bits(merge_block);
3214 if (UNIV_UNLIKELY(data_size > max_ins_size)) {
3218 if (UNIV_UNLIKELY(!btr_page_reorganize(merge_block,
3227 ut_ad(max_ins_size == max_ins_size_reorg);
3229 if (UNIV_UNLIKELY(data_size > max_ins_size)) {
3239 #ifdef UNIV_ZIP_DEBUG
3240 if (UNIV_LIKELY_NULL(merge_page_zip)) {
3244 ut_a(page_zip_validate(merge_page_zip, merge_page));
3245 ut_a(page_zip_validate(page_zip, page));
3252 merge_block, block, page_get_supremum_rec(page),
3255 if (UNIV_UNLIKELY(!orig_pred)) {
3259 btr_search_drop_page_hash_index(block);
3262 btr_level_list_remove(space, zip_size, page, mtr);
3264 btr_node_ptr_delete(index, block, mtr);
3268 #ifdef UNIV_BTR_DEBUG
3269 byte fil_page_prev[4];
3272 if (UNIV_LIKELY_NULL(merge_page_zip)) {
3277 #ifdef UNIV_BTR_DEBUG
3280 #if FIL_NULL != 0xffffffff
3281 # error "FIL_NULL != 0xffffffff"
3287 page_get_infimum_rec(page),
3288 cursor->
index, mtr);
3290 if (UNIV_UNLIKELY(!orig_succ)) {
3291 ut_a(merge_page_zip);
3292 #ifdef UNIV_BTR_DEBUG
3294 ut_a(!memcmp(fil_page_prev,
3300 btr_search_drop_page_hash_index(block);
3302 #ifdef UNIV_BTR_DEBUG
3303 if (UNIV_LIKELY_NULL(merge_page_zip)) {
3315 btr_level_list_remove(space, zip_size, page, mtr);
3320 btr_node_ptr_set_child_page_no(
3323 offsets, right_page_no, mtr);
3324 btr_node_ptr_delete(index, merge_block, mtr);
3329 btr_blob_dbg_remove(page, index,
"btr_compress");
3361 ibuf_reset_free_bits(merge_block);
3374 #ifdef UNIV_ZIP_DEBUG
3375 ut_a(!merge_page_zip || page_zip_validate(merge_page_zip, merge_page));
3379 btr_page_free(index, block, mtr);
3381 ut_ad(btr_check_node_ptr(index, merge_block, mtr));
3392 btr_discard_only_page_on_level(
3398 ulint page_level = 0;
3407 const page_t* page = buf_block_get_frame(block);
3414 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
3415 btr_search_drop_page_hash_index(block);
3417 btr_page_get_father(index, block, mtr, &cursor);
3423 btr_page_free(index, block, mtr);
3432 #ifdef UNIV_BTR_DEBUG
3434 const page_t* root = buf_block_get_frame(block);
3447 ibuf_reset_free_bits(block);
3474 ulint right_page_no;
3487 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
3499 merge_page = buf_block_get_frame(merge_block);
3500 #ifdef UNIV_BTR_DEBUG
3504 }
else if (right_page_no !=
FIL_NULL) {
3507 merge_page = buf_block_get_frame(merge_block);
3508 #ifdef UNIV_BTR_DEBUG
3513 btr_discard_only_page_on_level(index, block, mtr);
3518 page = buf_block_get_frame(block);
3520 btr_search_drop_page_hash_index(block);
3535 btr_set_min_rec_mark(node_ptr, mtr);
3538 btr_node_ptr_delete(index, block, mtr);
3541 btr_level_list_remove(space, zip_size, page, mtr);
3542 #ifdef UNIV_ZIP_DEBUG
3546 ut_a(!merge_page_zip
3547 || page_zip_validate(merge_page_zip, merge_page));
3560 btr_blob_dbg_remove(page, index,
"btr_discard_page");
3563 btr_page_free(index, block, mtr);
3565 ut_ad(btr_check_node_ptr(index, merge_block, mtr));
3568 #ifdef UNIV_BTR_PRINT
3582 fputs(
"Sorry, cannot print info of an ibuf tree:"
3583 " use ibuf functions\n", stderr);
3590 root = btr_root_get(index, &mtr);
3592 seg = root + PAGE_HEADER + PAGE_BTR_SEG_TOP;
3594 fputs(
"INFO OF THE NON-LEAF PAGE SEGMENT\n", stderr);
3595 fseg_print(seg, &mtr);
3599 seg = root + PAGE_HEADER + PAGE_BTR_SEG_LEAF;
3601 fputs(
"INFO OF THE LEAF PAGE SEGMENT\n", stderr);
3602 fseg_print(seg, &mtr);
3612 btr_print_recursive(
3622 const page_t* page = buf_block_get_frame(block);
3628 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
3629 fprintf(stderr,
"NODE ON LEVEL %lu page number %lu\n",
3646 }
else if ((i <= width) || (i >= n_recs - width)) {
3648 const rec_t* node_ptr;
3652 node_ptr = page_cur_get_rec(&cursor);
3654 *offsets = rec_get_offsets(node_ptr, index, *offsets,
3655 ULINT_UNDEFINED, heap);
3656 btr_print_recursive(index,
3657 btr_node_ptr_get_child(node_ptr,
3661 width, heap, offsets, &mtr2);
3683 ulint offsets_[REC_OFFS_NORMAL_SIZE];
3684 ulint* offsets = offsets_;
3685 rec_offs_init(offsets_);
3687 fputs(
"--------------------------\n"
3688 "INDEX TREE PRINT\n", stderr);
3692 root = btr_root_block_get(index, &mtr);
3694 btr_print_recursive(index, root, width, &heap, &offsets, &mtr);
3695 if (UNIV_LIKELY_NULL(heap)) {
3701 btr_validate_index(index, NULL);
3721 page_t* page = buf_block_get_frame(block);
3723 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
3730 offsets = btr_page_get_father_block(NULL, heap, index, block, mtr,
3738 tuple = dict_index_build_node_ptr(
3754 btr_index_rec_validate_report(
3760 fputs(
"InnoDB: Record in ", stderr);
3761 dict_index_name_print(stderr, NULL, index);
3762 fprintf(stderr,
", page %lu, at offset %lu\n",
3772 btr_index_rec_validate(
3776 ibool dump_on_error)
3785 ulint offsets_[REC_OFFS_NORMAL_SIZE];
3786 ulint* offsets = offsets_;
3787 rec_offs_init(offsets_);
3801 btr_index_rec_validate_report(page, rec, index);
3802 fprintf(stderr,
"InnoDB: compact flag=%lu, should be %lu\n",
3813 btr_index_rec_validate_report(page, rec, index);
3814 fprintf(stderr,
"InnoDB: has %lu fields, should have %lu\n",
3817 if (dump_on_error) {
3818 buf_page_print(page, 0);
3820 fputs(
"InnoDB: corrupt record ", stderr);
3821 rec_print_old(stderr, rec);
3827 offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
3829 for (i = 0; i < n; i++) {
3841 if ((dict_index_get_nth_field(index, i)->prefix_len == 0
3842 && len != UNIV_SQL_NULL && fixed_size
3843 && len != fixed_size)
3844 || (dict_index_get_nth_field(index, i)->prefix_len > 0
3845 && len != UNIV_SQL_NULL
3847 > dict_index_get_nth_field(index, i)->prefix_len)) {
3849 btr_index_rec_validate_report(page, rec, index);
3851 "InnoDB: field %lu len is %lu,"
3853 (ulong) i, (ulong) len, (ulong) fixed_size);
3855 if (dump_on_error) {
3856 buf_page_print(page, 0);
3858 fputs(
"InnoDB: corrupt record ", stderr);
3862 if (UNIV_LIKELY_NULL(heap)) {
3869 if (UNIV_LIKELY_NULL(heap)) {
3881 btr_index_page_validate(
3898 if (!btr_index_rec_validate(cur.
rec, index, TRUE)) {
3913 btr_validate_report1(
3919 fprintf(stderr,
"InnoDB: Error in page %lu of ",
3921 dict_index_name_print(stderr, NULL, index);
3923 fprintf(stderr,
", index tree level %lu", level);
3932 btr_validate_report2(
3939 fprintf(stderr,
"InnoDB: Error in pages %lu and %lu of ",
3942 dict_index_name_print(stderr, NULL, index);
3944 fprintf(stderr,
", index tree level %lu", level);
3970 ulint right_page_no;
3977 ulint* offsets = NULL;
3978 ulint* offsets2= NULL;
3979 #ifdef UNIV_ZIP_DEBUG
3987 block = btr_root_block_get(index, &mtr);
3988 page = buf_block_get_frame(block);
3994 const rec_t* node_ptr;
3998 #ifdef UNIV_ZIP_DEBUG
4000 ut_a(!page_zip || page_zip_validate(page_zip, page));
4007 node_ptr = page_cur_get_rec(&cursor);
4008 offsets = rec_get_offsets(node_ptr, index, offsets,
4009 ULINT_UNDEFINED, &heap);
4010 block = btr_node_ptr_get_child(node_ptr, index, offsets, &mtr);
4011 page = buf_block_get_frame(block);
4023 offsets = offsets2 = NULL;
4026 #ifdef UNIV_ZIP_DEBUG
4028 ut_a(!page_zip || page_zip_validate(page_zip, page));
4034 btr_validate_report1(index, level, block);
4037 }
else if (level == 0) {
4041 if (!btr_index_page_validate(block, index)) {
4057 const rec_t* right_rec;
4060 right_page = buf_block_get_frame(right_block);
4063 btr_validate_report2(index, level, block, right_block);
4064 fputs(
"InnoDB: broken FIL_PAGE_NEXT"
4065 " or FIL_PAGE_PREV links\n", stderr);
4066 buf_page_print(page, 0);
4067 buf_page_print(right_page, 0);
4074 btr_validate_report2(index, level, block, right_block);
4075 fputs(
"InnoDB: 'compact' flag mismatch\n", stderr);
4076 buf_page_print(page, 0);
4077 buf_page_print(right_page, 0);
4081 goto node_ptr_fails;
4087 offsets = rec_get_offsets(rec, index,
4088 offsets, ULINT_UNDEFINED, &heap);
4089 offsets2 = rec_get_offsets(right_rec, index,
4090 offsets2, ULINT_UNDEFINED, &heap);
4095 btr_validate_report2(index, level, block, right_block);
4097 fputs(
"InnoDB: records in wrong order"
4098 " on adjacent pages\n", stderr);
4100 buf_page_print(page, 0);
4101 buf_page_print(right_page, 0);
4103 fputs(
"InnoDB: record ", stderr);
4107 fputs(
"InnoDB: record ", stderr);
4109 page_get_infimum_rec(right_page));
4117 if (level > 0 && left_page_no ==
FIL_NULL) {
4129 offsets = btr_page_get_father_block(offsets, heap, index,
4130 block, &mtr, &node_cur);
4137 offsets = btr_page_get_father_node_ptr(offsets, heap,
4145 btr_validate_report1(index, level, block);
4147 fputs(
"InnoDB: node pointer to the page is wrong\n",
4150 buf_page_print(father_page, 0);
4151 buf_page_print(page, 0);
4153 fputs(
"InnoDB: node ptr ", stderr);
4157 fprintf(stderr,
"\n"
4158 "InnoDB: node ptr child page n:o %lu\n",
4162 fputs(
"InnoDB: record on page ", stderr);
4167 goto node_ptr_fails;
4171 node_ptr_tuple = dict_index_build_node_ptr(
4179 page_get_infimum_rec(page));
4181 btr_validate_report1(index, level, block);
4183 buf_page_print(father_page, 0);
4184 buf_page_print(page, 0);
4186 fputs(
"InnoDB: Error: node ptrs differ"
4188 "InnoDB: node ptr ", stderr);
4190 fputs(
"InnoDB: first rec ", stderr);
4195 goto node_ptr_fails;
4201 page_get_infimum_rec(father_page)));
4207 page_get_supremum_rec(father_page)));
4210 const rec_t* right_node_ptr
4213 offsets = btr_page_get_father_block(
4214 offsets, heap, index, right_block,
4215 &mtr, &right_node_cur);
4217 != page_get_supremum_rec(father_page)) {
4220 != right_node_ptr) {
4222 fputs(
"InnoDB: node pointer to"
4223 " the right page is wrong\n",
4226 btr_validate_report1(index, level,
4229 buf_page_print(father_page, 0);
4230 buf_page_print(page, 0);
4231 buf_page_print(right_page, 0);
4234 page_t* right_father_page
4239 page_get_infimum_rec(
4240 right_father_page))) {
4242 fputs(
"InnoDB: node pointer 2 to"
4243 " the right page is wrong\n",
4246 btr_validate_report1(index, level,
4249 buf_page_print(father_page, 0);
4250 buf_page_print(right_father_page, 0);
4251 buf_page_print(page, 0);
4252 buf_page_print(right_page, 0);
4259 fputs(
"InnoDB: node pointer 3 to"
4260 " the right page is wrong\n",
4263 btr_validate_report1(index, level,
4266 buf_page_print(father_page, 0);
4267 buf_page_print(right_father_page, 0);
4268 buf_page_print(page, 0);
4269 buf_page_print(right_page, 0);
4286 page = buf_block_get_frame(block);
4313 root = btr_root_get(index, &mtr);
4317 if (!btr_validate_level(index, trx, n - i)) {