37 #ifndef UNIV_HOTBACKUP
71 fprintf(stderr,
"InnoDB: flag mismatch in space %u page %u"
72 " index %s of table %s\n",
84 #ifndef UNIV_HOTBACKUP
85 #ifdef UNIV_BLOB_DEBUG
90 static ibool btr_blob_dbg_msg;
96 #define btr_blob_dbg_msg_issue(op, b, ctx) \
97 fprintf(stderr, op " %u:%u:%u->%u %s(%u,%u,%u)\n", \
98 (b)->ref_page_no, (b)->ref_heap_no, \
99 (b)->ref_field_no, (b)->blob_page_no, ctx, \
100 (b)->owner, (b)->always_owner, (b)->del)
108 btr_blob_dbg_rbt_insert(
111 const btr_blob_dbg_t* b,
114 if (btr_blob_dbg_msg) {
115 btr_blob_dbg_msg_issue(
"insert", b, ctx);
117 mutex_enter(&index->blobs_mutex);
119 mutex_exit(&index->blobs_mutex);
128 btr_blob_dbg_rbt_delete(
131 const btr_blob_dbg_t* b,
134 if (btr_blob_dbg_msg) {
135 btr_blob_dbg_msg_issue(
"delete", b, ctx);
137 mutex_enter(&index->blobs_mutex);
139 mutex_exit(&index->blobs_mutex);
153 const btr_blob_dbg_t* aa =
static_cast<const btr_blob_dbg_t*
>(a);
154 const btr_blob_dbg_t* bb =
static_cast<const btr_blob_dbg_t*
>(b);
159 if (aa->ref_page_no != bb->ref_page_no) {
160 return(aa->ref_page_no < bb->ref_page_no ? -1 : 1);
162 if (aa->ref_heap_no != bb->ref_heap_no) {
163 return(aa->ref_heap_no < bb->ref_heap_no ? -1 : 1);
165 if (aa->ref_field_no != bb->ref_field_no) {
166 return(aa->ref_field_no < bb->ref_field_no ? -1 : 1);
175 btr_blob_dbg_add_blob(
188 b.blob_page_no = page_no;
191 b.ref_field_no = field_no;
193 b.always_owner = b.owner = TRUE;
196 btr_blob_dbg_rbt_insert(index, &b, ctx);
204 btr_blob_dbg_add_rec(
216 ut_ad(rec_offs_validate(rec, index, offsets));
229 const byte* field_ref = rec_get_nth_field(
230 rec, offsets, i, &len);
232 ut_a(len != UNIV_SQL_NULL);
237 BTR_EXTERN_FIELD_REF_SIZE)) {
246 b.always_owner = b.owner
251 btr_blob_dbg_rbt_insert(index, &b, ctx);
280 node != NULL; node =
rbt_next(index->blobs, node)) {
281 const btr_blob_dbg_t* b
282 = rbt_value(btr_blob_dbg_t, node);
283 fprintf(stderr,
"%u:%u:%u->%u%s%s%s\n",
284 b->ref_page_no, b->ref_heap_no, b->ref_field_no,
286 b->owner ?
"" :
"(disowned)",
287 b->always_owner ?
"" :
"(has disowned)",
288 b->del ?
"(deleted)" :
"");
297 btr_blob_dbg_remove_rec(
301 const ulint* offsets,
308 ut_ad(rec_offs_validate(rec, index, offsets));
320 const byte* field_ref = rec_get_nth_field(
321 rec, offsets, i, &len);
323 ut_a(len != UNIV_SQL_NULL);
324 ut_a(len >= BTR_EXTERN_FIELD_REF_SIZE);
331 switch (b.blob_page_no) {
339 BTR_EXTERN_FIELD_REF_SIZE));
346 btr_blob_dbg_rbt_delete(index, &b, ctx);
360 btr_blob_dbg_is_empty(
366 ibool success = TRUE;
372 mutex_enter(&index->blobs_mutex);
375 node != NULL; node =
rbt_next(index->blobs, node)) {
376 const btr_blob_dbg_t* b
377 = rbt_value(btr_blob_dbg_t, node);
379 if (b->ref_page_no != page_no && b->blob_page_no != page_no) {
384 "InnoDB: orphan BLOB ref%s%s%s %u:%u:%u->%u\n",
385 b->owner ?
"" :
"(disowned)",
386 b->always_owner ?
"" :
"(has disowned)",
387 b->del ?
"(deleted)" :
"",
388 b->ref_page_no, b->ref_heap_no, b->ref_field_no,
391 if (b->blob_page_no != page_no || b->owner || !b->del) {
396 mutex_exit(&index->blobs_mutex);
412 const btr_blob_dbg_op_f op)
416 ulint offsets_[REC_OFFS_NORMAL_SIZE];
417 ulint* offsets = offsets_;
418 rec_offs_init(offsets_);
429 rec = page_get_infimum_rec(page);
433 offsets = rec_get_offsets(rec, index, offsets,
434 ULINT_UNDEFINED, &heap);
435 count += op(rec, index, offsets, ctx);
460 return(btr_blob_dbg_op(page, NULL, index, ctx, btr_blob_dbg_add_rec));
478 count = btr_blob_dbg_op(page, NULL, index, ctx,
479 btr_blob_dbg_remove_rec);
492 btr_blob_dbg_restore(
505 removed = btr_blob_dbg_remove(npage, index, ctx);
506 added = btr_blob_dbg_add(page, index, ctx);
507 ut_a(added == removed);
514 btr_blob_dbg_set_deleted_flag(
518 const ulint* offsets,
526 ut_ad(rec_offs_validate(rec, index, offsets));
541 const byte* field_ref = rec_get_nth_field(
542 rec, offsets, i, &len);
544 ut_a(len != UNIV_SQL_NULL);
545 ut_a(len >= BTR_EXTERN_FIELD_REF_SIZE);
552 switch (b.blob_page_no) {
555 BTR_EXTERN_FIELD_REF_SIZE));
563 mutex_enter(&index->blobs_mutex);
567 c = rbt_value(btr_blob_dbg_t, node);
570 if (btr_blob_dbg_msg) {
572 mutex_exit(&index->blobs_mutex);
573 btr_blob_dbg_msg_issue(
"del_mk", &b,
"");
575 mutex_exit(&index->blobs_mutex);
589 const ulint* offsets,
595 const byte* field_ref;
598 ut_ad(rec_offs_validate(rec, index, offsets));
601 field_ref = rec_get_nth_field(rec, offsets, i, &len);
602 ut_a(len != UNIV_SQL_NULL);
603 ut_a(len >= BTR_EXTERN_FIELD_REF_SIZE);
612 ut_a(b.owner == own);
614 mutex_enter(&index->blobs_mutex);
624 btr_blob_dbg_t* c = rbt_value(btr_blob_dbg_t, node);
627 ut_a(own || c->owner);
631 c->always_owner = FALSE;
635 mutex_exit(&index->blobs_mutex);
694 #ifdef UNIV_BTR_DEBUG
700 btr_root_fseg_validate(
735 block =
btr_block_get(space, zip_size, root_page_no, mode, index, mtr);
737 #ifdef UNIV_BTR_DEBUG
739 const page_t* root = buf_block_get_frame(block);
761 return(buf_block_get_frame(btr_root_block_get(index, RW_X_LATCH,
786 root_block = btr_root_block_get(index, RW_S_LATCH, mtr);
788 height = btr_page_get_level(buf_block_get_frame(root_block), mtr);
792 #ifdef UNIV_SYNC_DEBUG
793 sync_thread_reset_level(&root_block->
lock);
805 btr_root_fseg_adjust_on_import(
807 fseg_header_t* seg_header,
820 }
else if (page_zip) {
855 DBUG_EXECUTE_IF(
"ib_import_trigger_corruption_3",
859 space_id, zip_size, root_page_no, RW_X_LATCH, index, &mtr);
861 page = buf_block_get_frame(block);
874 bool page_is_compact_format;
900 if (err == DB_SUCCESS
901 && (!btr_root_fseg_adjust_on_import(
903 + page, page_zip, space_id, &mtr)
904 || !btr_root_fseg_adjust_on_import(
906 + page, page_zip, space_id, &mtr))) {
956 prev_page = buf_block_get_frame(prev_block);
958 ut_ad(mtr_memo_contains(mtr, prev_block,
960 || mtr_memo_contains(mtr, prev_block,
961 MTR_MEMO_PAGE_X_FIX));
962 #ifdef UNIV_BTR_DEBUG
1013 next_page = buf_block_get_frame(next_block);
1015 ut_ad(mtr_memo_contains(mtr, next_block, MTR_MEMO_PAGE_S_FIX)
1016 || mtr_memo_contains(mtr, next_block,
1017 MTR_MEMO_PAGE_X_FIX));
1018 #ifdef UNIV_BTR_DEBUG
1043 page_t* page = buf_block_get_frame(block);
1045 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
1053 btr_page_set_level(page, NULL, level, mtr);
1058 btr_page_set_index_id(page, page_zip, index->
id, mtr);
1067 btr_page_alloc_for_ibuf(
1080 + PAGE_BTR_IBUF_FREE_LIST, mtr);
1085 node_addr.
page, RW_X_LATCH, mtr);
1086 new_page = buf_block_get_frame(new_block);
1087 buf_block_dbg_add_level(new_block, SYNC_IBUF_TREE_NODE_NEW);
1089 flst_remove(root + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST,
1090 new_page + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST_NODE,
1105 static __attribute__((nonnull, warn_unused_result))
1130 seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_LEAF;
1132 seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_TOP;
1140 seg_header, hint_page_no, file_direction,
1141 TRUE, mtr, init_mtr));
1171 return(btr_page_alloc_for_ibuf(index, mtr));
1174 new_block = btr_page_alloc_low(
1175 index, hint_page_no, file_direction, level, mtr, init_mtr);
1178 buf_block_dbg_add_level(new_block, SYNC_TREE_NODE_NEW);
1206 return(ULINT_UNDEFINED);
1211 if (flag == BTR_N_LEAF_PAGES) {
1212 seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_LEAF;
1216 }
else if (flag == BTR_TOTAL_SIZE) {
1217 seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_TOP;
1221 seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_LEAF;
1236 btr_page_free_for_ibuf(
1244 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
1248 buf_block_get_frame(block)
1249 + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST_NODE, mtr);
1271 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
1280 btr_page_free_for_ibuf(index, block, mtr);
1288 seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_LEAF;
1290 seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_TOP;
1300 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
1318 const page_t* page = buf_block_get_frame(block);
1319 ulint level = btr_page_get_level(page, mtr);
1334 const ulint* offsets,
1341 ut_ad(rec_offs_validate(rec, NULL, offsets));
1346 field = rec_get_nth_field(rec, offsets,
1349 ut_ad(len == REC_NODE_PTR_SIZE);
1365 btr_node_ptr_get_child(
1367 const rec_t* node_ptr,
1369 const ulint* offsets,
1375 ut_ad(rec_offs_validate(node_ptr, index, offsets));
1380 page_no, RW_X_LATCH, index, mtr));
1389 btr_page_get_father_node_ptr_func(
1417 user_rec = btr_cur_get_rec(cursor);
1425 node_ptr = btr_cur_get_rec(cursor);
1428 offsets = rec_get_offsets(node_ptr, index, offsets,
1429 ULINT_UNDEFINED, &heap);
1433 fputs(
"InnoDB: Dump of the child page:\n", stderr);
1436 fputs(
"InnoDB: Dump of the parent page:\n", stderr);
1440 fputs(
"InnoDB: Corruption of an index tree: table ", stderr);
1442 fputs(
", index ", stderr);
1444 fprintf(stderr,
",\n"
1445 "InnoDB: father ptr page no %lu, child page no %lu\n",
1451 offsets = rec_get_offsets(print_rec, index,
1452 offsets, ULINT_UNDEFINED, &heap);
1454 offsets = rec_get_offsets(node_ptr, index, offsets,
1455 ULINT_UNDEFINED, &heap);
1458 fputs(
"InnoDB: You should dump + drop + reimport the table"
1460 "InnoDB: corruption. If the crash happens at "
1461 "the database startup, see\n"
1462 "InnoDB: " REFMAN
"forcing-innodb-recovery.html about\n"
1463 "InnoDB: forcing recovery. "
1464 "Then dump + drop + reimport.\n", stderr);
1472 #define btr_page_get_father_node_ptr(of,heap,cur,mtr) \
1473 btr_page_get_father_node_ptr_func(of,heap,cur,__FILE__,__LINE__,mtr)
1481 btr_page_get_father_block(
1495 return(btr_page_get_father_node_ptr(offsets, heap, cursor, mtr));
1503 btr_page_get_father(
1518 btr_page_get_father_node_ptr(NULL, heap, cursor, mtr);
1533 index_id_t index_id,
1552 IBUF_HEADER + IBUF_TREE_SEG_HEADER, mtr);
1554 buf_block_dbg_add_level(
1555 ibuf_hdr_block, SYNC_IBUF_TREE_NODE_NEW);
1558 == IBUF_HEADER_PAGE_NO);
1563 buf_block_get_frame(ibuf_hdr_block)
1564 + IBUF_HEADER + IBUF_TREE_SEG_HEADER,
1565 IBUF_TREE_ROOT_PAGE_NO,
1569 #ifdef UNIV_BLOB_DEBUG
1571 mutex_create(PFS_NOT_INSTRUMENTED,
1572 &index->blobs_mutex, SYNC_ANY_LATCH);
1573 index->blobs =
rbt_create(
sizeof(btr_blob_dbg_t),
1578 PAGE_HEADER + PAGE_BTR_SEG_TOP, mtr);
1581 if (block == NULL) {
1587 frame = buf_block_get_frame(block);
1589 if (type & DICT_IBUF) {
1591 buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE_NEW);
1593 ut_ad(page_no == IBUF_TREE_ROOT_PAGE_NO);
1595 flst_init(frame + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST, mtr);
1599 buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW);
1602 PAGE_HEADER + PAGE_BTR_SEG_LEAF, mtr)) {
1612 buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW);
1624 btr_page_set_level(page, NULL, 0, mtr);
1630 btr_page_set_index_id(page, page_zip, index_id, mtr);
1633 btr_page_set_next(page, page_zip,
FIL_NULL, mtr);
1634 btr_page_set_prev(page, page_zip,
FIL_NULL, mtr);
1672 root =
btr_page_get(space, zip_size, root_page_no, RW_X_LATCH,
1674 #ifdef UNIV_BTR_DEBUG
1684 finished =
fseg_free_step(root + PAGE_HEADER + PAGE_BTR_SEG_LEAF,
1695 root =
btr_page_get(space, zip_size, root_page_no, RW_X_LATCH,
1697 #ifdef UNIV_BTR_DEBUG
1703 root + PAGE_HEADER + PAGE_BTR_SEG_TOP, &mtr);
1725 fseg_header_t* header;
1727 block =
btr_block_get(space, zip_size, root_page_no, RW_X_LATCH,
1732 header = buf_block_get_frame(block) + PAGE_HEADER + PAGE_BTR_SEG_TOP;
1733 #ifdef UNIV_BTR_DEBUG
1734 ut_a(btr_root_fseg_validate(header, space));
1770 #ifndef UNIV_HOTBACKUP
1773 page_t* page = buf_block_get_frame(block);
1780 ulint max_ins_size1;
1781 ulint max_ins_size2;
1782 bool success =
false;
1784 bool log_compressed;
1786 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
1788 #ifdef UNIV_ZIP_DEBUG
1789 ut_a(!page_zip || page_zip_validate(page_zip, page, index));
1797 #ifndef UNIV_HOTBACKUP
1800 ut_ad(block == back_block1);
1801 temp_block = back_block2;
1803 temp_page = temp_block->
frame;
1808 #ifndef UNIV_HOTBACKUP
1815 btr_blob_dbg_remove(page, index,
"btr_page_reorganize");
1829 page_get_infimum_rec(temp_page),
1839 ut_ad(max_trx_id != 0 || recovery);
1844 log_compressed = page_zip && page_zip_log_pages;
1846 if (log_compressed) {
1854 btr_blob_dbg_restore(page, temp_page, index,
1855 "btr_page_reorganize_compress_fail");
1857 #if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
1859 ut_a(!memcmp(page, temp_page, PAGE_HEADER));
1860 ut_a(!memcmp(PAGE_HEADER + PAGE_N_RECS + page,
1861 PAGE_HEADER + PAGE_N_RECS + temp_page,
1862 PAGE_DATA - (PAGE_HEADER + PAGE_N_RECS)));
1868 memcpy(PAGE_HEADER + page, PAGE_HEADER + temp_page,
1869 PAGE_N_RECS - PAGE_N_DIR_SLOTS);
1870 memcpy(PAGE_DATA + page, PAGE_DATA + temp_page,
1873 #if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
1874 ut_a(!memcmp(page, temp_page, UNIV_PAGE_SIZE));
1880 #ifndef UNIV_HOTBACKUP
1890 if (data_size1 != data_size2 || max_ins_size1 != max_ins_size2) {
1895 "InnoDB: Error: page old data size %lu"
1896 " new data size %lu\n"
1897 "InnoDB: Error: page old max ins size %lu"
1898 " new max ins size %lu\n"
1899 "InnoDB: Submit a detailed bug report"
1900 " to http://bugs.mysql.com\n",
1901 (
unsigned long) data_size1, (
unsigned long) data_size2,
1902 (
unsigned long) max_ins_size1,
1903 (
unsigned long) max_ins_size2);
1913 ut_ad(cursor->
rec == page_get_infimum_rec(page));
1917 #ifdef UNIV_ZIP_DEBUG
1918 ut_a(!page_zip || page_zip_validate(page_zip, page, index));
1920 #ifndef UNIV_HOTBACKUP
1927 #ifndef UNIV_HOTBACKUP
1942 log_ptr = log_compressed
1945 mtr, page, index, type,
1949 if (log_ptr && page_zip) {
1970 static __attribute__((nonnull))
1972 btr_page_reorganize_block(
1991 #ifndef UNIV_HOTBACKUP
2012 cursor, index, mtr));
2032 ut_ad(ptr && end_ptr);
2038 if (ptr == end_ptr) {
2047 level = page_zip_level;
2050 if (block != NULL) {
2051 btr_page_reorganize_block(
true, level, block, index, mtr);
2057 #ifndef UNIV_HOTBACKUP
2070 page_t* page = buf_block_get_frame(block);
2072 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
2074 #ifdef UNIV_ZIP_DEBUG
2075 ut_a(!page_zip || page_zip_validate(page_zip, page, index));
2079 btr_blob_dbg_remove(page, index,
"btr_page_empty");
2088 btr_page_set_level(page, NULL, level, mtr);
2123 rec_t* node_ptr_rec;
2131 root_block = btr_cur_get_block(cursor);
2135 #ifdef UNIV_ZIP_DEBUG
2136 ut_a(!root_page_zip || page_zip_validate(root_page_zip, root, index));
2138 #ifdef UNIV_BTR_DEBUG
2152 ut_ad(mtr_memo_contains(mtr, root_block, MTR_MEMO_PAGE_X_FIX));
2158 level = btr_page_get_level(root, mtr);
2160 new_block =
btr_page_alloc(index, 0, FSP_NO_DIR, level, mtr, mtr);
2161 new_page = buf_block_get_frame(new_block);
2163 ut_a(!new_page_zip == !root_page_zip);
2168 btr_page_create(new_block, new_page_zip, index, level, mtr);
2171 btr_page_set_next(new_page, new_page_zip,
FIL_NULL, mtr);
2172 btr_page_set_prev(new_page, new_page_zip,
FIL_NULL, mtr);
2177 #ifdef UNIV_ZIP_COPY
2181 page_get_infimum_rec(root),
2187 root_page_zip, root, index, mtr);
2192 page_get_infimum_rec(root));
2217 index, rec, new_page_no, *heap, level);
2223 | REC_INFO_MIN_REC_FLAG);
2226 btr_page_empty(root_block, root_page_zip, index, level + 1, mtr);
2233 btr_page_set_next(root, root_page_zip,
FIL_NULL, mtr);
2234 btr_page_set_prev(root, root_page_zip,
FIL_NULL, mtr);
2236 page_cursor = btr_cur_get_page_cur(cursor);
2243 index, offsets, heap, 0, mtr);
2252 fprintf(stderr,
"Root raise new page no %lu\n", new_page_no);
2261 PAGE_CUR_LE, page_cursor);
2265 tuple, n_ext, mtr));
2283 rec_t* insert_point;
2287 insert_point = btr_cur_get_rec(cursor);
2292 infimum = page_get_infimum_rec(page);
2299 if (infimum != insert_point
2302 *split_rec = insert_point;
2328 rec_t* insert_point;
2331 insert_point = btr_cur_get_rec(cursor);
2361 *split_rec = next_next_rec;
2378 btr_page_get_split_rec(
2411 if (free_space > (ulint) free_space_zip) {
2412 free_space = (ulint) free_space_zip;
2420 ut_ad(total_n_recs >= 2);
2425 ins_rec = btr_cur_get_rec(cursor);
2426 rec = page_get_infimum_rec(page);
2440 if (rec == ins_rec) {
2443 }
else if (rec == NULL) {
2451 incl_data += insert_size;
2453 offsets = rec_get_offsets(rec, cursor->
index,
2454 offsets, ULINT_UNDEFINED,
2468 if (rec == ins_rec) {
2472 }
else if (rec == NULL) {
2494 static __attribute__((nonnull(1,3,4,6), warn_unused_result))
2496 btr_page_insert_fits(
2500 const rec_t* split_rec,
2515 const rec_t* end_rec;
2522 || rec_offs_validate(split_rec, cursor->index, *offsets));
2536 if (split_rec == NULL) {
2543 end_rec = split_rec;
2546 end_rec = page_get_supremum_rec(page);
2558 while (rec != end_rec) {
2562 *offsets = rec_get_offsets(rec, cursor->index, *offsets,
2563 ULINT_UNDEFINED, heap);
2602 ulint* offsets = NULL;
2609 &cursor, 0, file, line, mtr);
2618 &cursor, &offsets, &heap,
2619 tuple, &rec, &dummy_big_rec, 0, NULL, mtr);
2621 if (err == DB_FAIL) {
2626 &cursor, &offsets, &heap,
2628 &dummy_big_rec, 0, NULL, mtr);
2629 ut_a(err == DB_SUCCESS);
2637 static __attribute__((nonnull))
2639 btr_attach_half_pages(
2645 const rec_t* split_rec,
2656 page_t* page = buf_block_get_frame(block);
2659 ulint lower_page_no;
2660 ulint upper_page_no;
2666 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
2667 ut_ad(mtr_memo_contains(mtr, new_block, MTR_MEMO_PAGE_X_FIX));
2673 if (direction == FSP_DOWN) {
2678 lower_page = buf_block_get_frame(new_block);
2681 upper_page = buf_block_get_frame(block);
2686 offsets = btr_page_get_father_block(NULL, heap, index,
2687 block, mtr, &cursor);
2693 btr_cur_get_rec(&cursor),
2695 offsets, lower_page_no, mtr);
2698 lower_page = buf_block_get_frame(block);
2701 upper_page = buf_block_get_frame(new_block);
2707 level = btr_page_get_level(buf_block_get_frame(block), mtr);
2709 == btr_page_get_level(buf_block_get_frame(new_block), mtr));
2715 upper_page_no, heap, level);
2720 btr_insert_on_non_leaf_level(flags, index, level + 1,
2721 node_ptr_upper, mtr);
2737 space, zip_size, prev_page_no, RW_X_LATCH, index, mtr);
2738 #ifdef UNIV_BTR_DEBUG
2744 btr_page_set_next(buf_block_get_frame(prev_block),
2746 lower_page_no, mtr);
2751 space, zip_size, next_page_no, RW_X_LATCH, index, mtr);
2752 #ifdef UNIV_BTR_DEBUG
2758 btr_page_set_prev(buf_block_get_frame(next_block),
2760 upper_page_no, mtr);
2763 btr_page_set_prev(lower_page, lower_page_zip, prev_page_no, mtr);
2764 btr_page_set_next(lower_page, lower_page_zip, upper_page_no, mtr);
2766 btr_page_set_prev(upper_page, upper_page_zip, lower_page_no, mtr);
2767 btr_page_set_next(upper_page, upper_page_zip, next_page_no, mtr);
2773 static __attribute__((nonnull, warn_unused_result))
2775 btr_page_tuple_smaller(
2785 const rec_t* first_rec;
2789 block = btr_cur_get_block(cursor);
2792 first_rec = page_cur_get_rec(&pcur);
2794 *offsets = rec_get_offsets(
2795 first_rec, cursor->index, *offsets,
2841 ibool insert_will_fit;
2843 ulint n_iterations = 0;
2860 #ifdef UNIV_SYNC_DEBUG
2864 block = btr_cur_get_block(cursor);
2865 page = buf_block_get_frame(block);
2868 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
2876 insert_left = FALSE;
2878 if (n_iterations > 0) {
2880 hint_page_no = page_no + 1;
2881 split_rec = btr_page_get_split_rec(cursor, tuple, n_ext);
2883 if (split_rec == NULL) {
2884 insert_left = btr_page_tuple_smaller(
2885 cursor, tuple, offsets, n_uniq, heap);
2889 hint_page_no = page_no + 1;
2892 direction = FSP_DOWN;
2893 hint_page_no = page_no - 1;
2897 hint_page_no = page_no + 1;
2906 }
else if (btr_page_tuple_smaller(cursor, tuple,
2907 offsets, n_uniq, heap)) {
2909 page_get_infimum_rec(page));
2917 btr_page_get_level(page, mtr), mtr, mtr);
2918 new_page = buf_block_get_frame(new_block);
2920 btr_page_create(new_block, new_page_zip, cursor->
index,
2921 btr_page_get_level(page, mtr), mtr);
2928 first_rec = move_limit = split_rec;
2930 *offsets = rec_get_offsets(split_rec, cursor->
index, *offsets,
2935 if (!insert_left && new_page_zip && n_iterations > 0) {
2942 }
else if (insert_left) {
2943 ut_a(n_iterations > 0);
2949 ut_ad(!insert_left);
2960 btr_attach_half_pages(flags, cursor->
index, block,
2961 first_rec, new_block, direction, mtr);
2969 insert_will_fit = !new_page_zip
2970 && btr_page_insert_fits(cursor, split_rec,
2971 offsets, tuple, n_ext, heap);
2978 insert_will_fit = !new_page_zip
2979 && btr_page_insert_fits(cursor, NULL,
2980 offsets, tuple, n_ext, heap);
2991 if (direction == FSP_DOWN) {
2995 #ifdef UNIV_ZIP_COPY
2999 cursor->
index, mtr)) {
3008 page_zip, page, cursor->
index, mtr);
3010 new_block, cursor->
index,
3012 ULINT_UNDEFINED, mtr);
3017 new_block, block, move_limit,
3018 new_page + PAGE_NEW_INFIMUM);
3021 new_block, block, cursor->
index);
3026 cursor->
index, mtr);
3029 left_block = new_block;
3030 right_block =
block;
3037 #ifdef UNIV_ZIP_COPY
3041 cursor->
index, mtr)) {
3050 page_zip, page, cursor->
index, mtr);
3052 + new_page, new_block,
3053 cursor->
index, mtr);
3060 new_block, block, cursor->
index);
3067 ULINT_UNDEFINED, mtr);
3071 right_block = new_block;
3076 #ifdef UNIV_ZIP_DEBUG
3078 ut_a(page_zip_validate(page_zip, page, cursor->
index));
3079 ut_a(page_zip_validate(new_page_zip, new_page, cursor->
index));
3090 insert_block = left_block;
3092 insert_block = right_block;
3096 page_cursor = btr_cur_get_page_cur(cursor);
3099 PAGE_CUR_LE, page_cursor);
3102 offsets, heap, n_ext, mtr);
3104 #ifdef UNIV_ZIP_DEBUG
3107 = buf_block_get_frame(insert_block);
3112 ut_a(!insert_page_zip
3113 || page_zip_validate(insert_page_zip, insert_page,
3127 if (page_cur_get_page_zip(page_cursor)
3134 offsets, heap, n_ext, mtr);
3149 ut_ad(n_iterations < 2
3151 ut_ad(!insert_will_fit);
3163 left_block, right_block, mtr);
3167 fprintf(stderr,
"Split and insert done %lu %lu\n",
3176 ut_ad(!rec || rec_offs_validate(rec, cursor->
index, *offsets));
3180 #ifdef UNIV_SYNC_DEBUG
3188 # define btr_level_list_remove(space,zip_size,page,index,mtr) \
3189 btr_level_list_remove_func(space,zip_size,page,index,mtr)
3198 # define btr_level_list_remove(space,zip_size,page,index,mtr) \
3199 btr_level_list_remove_func(space,zip_size,page,mtr)
3204 static __attribute__((nonnull))
3206 btr_level_list_remove_func(
3212 #ifdef UNIV_SYNC_DEBUG
3221 ut_ad(mtr_memo_contains_page(mtr, page, MTR_MEMO_PAGE_X_FIX));
3233 RW_X_LATCH, index, mtr);
3235 = buf_block_get_frame(prev_block);
3236 #ifdef UNIV_BTR_DEBUG
3242 btr_page_set_next(prev_page,
3250 RW_X_LATCH, index, mtr);
3252 = buf_block_get_frame(next_block);
3253 #ifdef UNIV_BTR_DEBUG
3259 btr_page_set_prev(next_page,
3270 btr_set_min_rec_mark_log(
3282 # define btr_set_min_rec_mark_log(rec,comp,mtr) ((void) 0)
3301 if (end_ptr < ptr + 2) {
3343 #ifndef UNIV_HOTBACKUP
3358 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
3361 btr_page_get_father(index, block, mtr, &cursor);
3364 BTR_CREATE_FLAG,
RB_NONE, mtr);
3365 ut_a(err == DB_SUCCESS);
3391 page_t* page = buf_block_get_frame(block);
3396 bool lift_father_up;
3401 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
3403 page_level = btr_page_get_level(page, mtr);
3408 ulint* offsets = NULL;
3411 * (REC_OFFS_HEADER_SIZE + 1 + 1 + index->
n_fields));
3414 offsets = btr_page_get_father_block(offsets, heap, index,
3415 block, mtr, &cursor);
3416 father_block = btr_cur_get_block(&cursor);
3418 father_page = buf_block_get_frame(father_block);
3427 for (b = father_block;
3431 offsets = btr_page_get_father_block(offsets, heap,
3435 blocks[n_blocks++] = b = btr_cur_get_block(&cursor);
3438 lift_father_up = (n_blocks && page_level == 0);
3439 if (lift_father_up) {
3448 block = father_block;
3449 page = buf_block_get_frame(block);
3450 page_level = btr_page_get_level(page, mtr);
3454 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
3456 father_block = blocks[0];
3458 father_page = buf_block_get_frame(father_block);
3467 btr_page_empty(father_block, father_page_zip, index, page_level, mtr);
3472 #ifdef UNIV_ZIP_COPY
3476 page_get_infimum_rec(page),
3480 ut_a(father_page_zip);
3485 page_zip, page, index, mtr);
3490 page_get_infimum_rec(page));
3496 btr_blob_dbg_remove(page, index,
"btr_lift_page_up");
3500 for (i = lift_father_up ? 1 : 0; i < n_blocks; i++, page_level++) {
3501 page_t* page = buf_block_get_frame(blocks[i]);
3504 ut_ad(btr_page_get_level(page, mtr) == page_level + 1);
3506 btr_page_set_level(page, page_zip, page_level, mtr);
3507 #ifdef UNIV_ZIP_DEBUG
3508 ut_a(!page_zip || page_zip_validate(page_zip, page, index));
3520 ut_ad(btr_check_node_ptr(index, father_block, mtr));
3522 return(lift_father_up ? block_orig : father_block);
3551 ulint right_page_no;
3553 page_t* merge_page = NULL;
3562 DBUG_ENTER(
"btr_compress");
3564 block = btr_cur_get_block(cursor);
3572 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
3588 offsets = btr_page_get_father_block(NULL, heap, index, block, mtr,
3600 merge_block = btr_lift_page_up(index, block, mtr);
3610 DBUG_EXECUTE_IF(
"ib_always_merge_right", is_left = FALSE;);
3618 merge_page = buf_block_get_frame(merge_block);
3620 #ifdef UNIV_BTR_DEBUG
3633 #ifdef UNIV_ZIP_DEBUG
3634 if (merge_page_zip) {
3638 ut_a(page_zip_validate(merge_page_zip, merge_page, index));
3639 ut_a(page_zip_validate(page_zip, page, index));
3646 merge_block, block, page_get_supremum_rec(page),
3656 btr_level_list_remove(space, zip_size, page, index, mtr);
3671 #ifdef UNIV_BTR_DEBUG
3672 byte fil_page_prev[4];
3675 btr_page_get_father(index, merge_block, mtr, &cursor2);
3677 if (merge_page_zip && left_page_no ==
FIL_NULL) {
3683 #ifdef UNIV_BTR_DEBUG
3686 #if FIL_NULL != 0xffffffff
3687 # error "FIL_NULL != 0xffffffff"
3693 page_get_infimum_rec(page),
3694 cursor->
index, mtr);
3697 ut_a(merge_page_zip);
3698 #ifdef UNIV_BTR_DEBUG
3702 ut_a(!memcmp(fil_page_prev,
3711 #ifdef UNIV_BTR_DEBUG
3712 if (merge_page_zip && left_page_no ==
FIL_NULL) {
3725 btr_level_list_remove(space, zip_size, page, index, mtr);
3730 btr_cur_get_rec(&father_cursor),
3732 offsets, right_page_no, mtr);
3737 ut_a(err == DB_SUCCESS);
3746 btr_blob_dbg_remove(page, index,
"btr_compress");
3790 #ifdef UNIV_ZIP_DEBUG
3791 ut_a(!merge_page_zip || page_zip_validate(merge_page_zip, merge_page,
3798 ut_ad(btr_check_node_ptr(index, merge_block, mtr));
3807 merge_block, cursor);
3831 btr_discard_only_page_on_level(
3837 ulint page_level = 0;
3846 const page_t* page = buf_block_get_frame(block);
3849 ut_a(page_level == btr_page_get_level(page, mtr));
3853 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
3856 btr_page_get_father(index, block, mtr, &cursor);
3857 father = btr_cur_get_block(&cursor);
3871 #ifdef UNIV_BTR_DEBUG
3873 const page_t* root = buf_block_get_frame(block);
3912 ulint right_page_no;
3919 block = btr_cur_get_block(cursor);
3925 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
3936 RW_X_LATCH, index, mtr);
3937 merge_page = buf_block_get_frame(merge_block);
3938 #ifdef UNIV_BTR_DEBUG
3942 }
else if (right_page_no !=
FIL_NULL) {
3944 RW_X_LATCH, index, mtr);
3945 merge_page = buf_block_get_frame(merge_block);
3946 #ifdef UNIV_BTR_DEBUG
3951 btr_discard_only_page_on_level(index, block, mtr);
3956 page = buf_block_get_frame(block);
3979 btr_level_list_remove(space, zip_size, page, index, mtr);
3980 #ifdef UNIV_ZIP_DEBUG
3984 ut_a(!merge_page_zip
3985 || page_zip_validate(merge_page_zip, merge_page, index));
3998 btr_blob_dbg_remove(page, index,
"btr_discard_page");
4003 ut_ad(btr_check_node_ptr(index, merge_block, mtr));
4006 #ifdef UNIV_BTR_PRINT
4020 fputs(
"Sorry, cannot print info of an ibuf tree:"
4021 " use ibuf functions\n", stderr);
4030 seg = root + PAGE_HEADER + PAGE_BTR_SEG_TOP;
4032 fputs(
"INFO OF THE NON-LEAF PAGE SEGMENT\n", stderr);
4033 fseg_print(seg, &mtr);
4035 if (!dict_index_is_univ(index)) {
4037 seg = root + PAGE_HEADER + PAGE_BTR_SEG_LEAF;
4039 fputs(
"INFO OF THE LEAF PAGE SEGMENT\n", stderr);
4040 fseg_print(seg, &mtr);
4050 btr_print_recursive(
4060 const page_t* page = buf_block_get_frame(block);
4066 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
4067 fprintf(stderr,
"NODE ON LEVEL %lu page number %lu\n",
4068 (ulong) btr_page_get_level(page, mtr),
4071 page_print(block, index, width, width);
4084 }
else if ((i <= width) || (i >= n_recs - width)) {
4086 const rec_t* node_ptr;
4090 node_ptr = page_cur_get_rec(&cursor);
4092 *offsets = rec_get_offsets(node_ptr, index, *offsets,
4093 ULINT_UNDEFINED, heap);
4094 btr_print_recursive(index,
4095 btr_node_ptr_get_child(node_ptr,
4099 width, heap, offsets, &mtr2);
4121 ulint offsets_[REC_OFFS_NORMAL_SIZE];
4122 ulint* offsets = offsets_;
4123 rec_offs_init(offsets_);
4125 fputs(
"--------------------------\n"
4126 "INDEX TREE PRINT\n", stderr);
4130 root = btr_root_block_get(index, RW_X_LATCH, &mtr);
4132 btr_print_recursive(index, root, width, &heap, &offsets, &mtr);
4159 page_t* page = buf_block_get_frame(block);
4161 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
4168 offsets = btr_page_get_father_block(NULL, heap, index, block, mtr,
4178 btr_page_get_level(page, mtr));
4192 btr_index_rec_validate_report(
4198 fputs(
"InnoDB: Record in ", stderr);
4200 fprintf(stderr,
", page %lu, at offset %lu\n",
4214 ibool dump_on_error)
4223 ulint offsets_[REC_OFFS_NORMAL_SIZE];
4224 ulint* offsets = offsets_;
4225 rec_offs_init(offsets_);
4229 if (dict_index_is_univ(index)) {
4238 btr_index_rec_validate_report(page, rec, index);
4239 fprintf(stderr,
"InnoDB: compact flag=%lu, should be %lu\n",
4249 btr_index_rec_validate_report(page, rec, index);
4250 fprintf(stderr,
"InnoDB: has %lu fields, should have %lu\n",
4253 if (dump_on_error) {
4256 fputs(
"InnoDB: corrupt record ", stderr);
4263 offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
4265 for (i = 0; i <
n; i++) {
4277 if ((dict_index_get_nth_field(index, i)->prefix_len == 0
4278 && len != UNIV_SQL_NULL && fixed_size
4279 && len != fixed_size)
4280 || (dict_index_get_nth_field(index, i)->prefix_len > 0
4281 && len != UNIV_SQL_NULL
4283 > dict_index_get_nth_field(index, i)->prefix_len)) {
4285 btr_index_rec_validate_report(page, rec, index);
4287 "InnoDB: field %lu len is %lu,"
4289 (ulong) i, (ulong) len, (ulong) fixed_size);
4291 if (dump_on_error) {
4295 fputs(
"InnoDB: corrupt record ", stderr);
4318 btr_index_page_validate(
4332 DBUG_EXECUTE_IF(
"check_table_rec_next",
4334 page_cur_get_page(&cur), 0)
4337 page_dir_get_nth_slot(
4338 page_cur_get_page(&cur), 0))
4356 DBUG_EXECUTE_IF(
"check_table_rec_next",
4358 page_cur_get_page(&cur),
4374 btr_validate_report1(
4380 fprintf(stderr,
"InnoDB: Error in page %lu of ",
4384 fprintf(stderr,
", index tree level %lu", level);
4393 btr_validate_report2(
4400 fprintf(stderr,
"InnoDB: Error in pages %lu and %lu of ",
4405 fprintf(stderr,
", index tree level %lu", level);
4432 ulint right_page_no;
4440 ulint* offsets = NULL;
4442 #ifdef UNIV_ZIP_DEBUG
4450 block = btr_root_block_get(index, RW_X_LATCH, &mtr);
4451 page = buf_block_get_frame(block);
4452 seg = page + PAGE_HEADER + PAGE_BTR_SEG_TOP;
4462 "Flags mismatch: table=%lu, tablespace=%lu",
4463 (ulint) index->
table->
flags, (ulint) space_flags);
4470 while (level != btr_page_get_level(page, &mtr)) {
4471 const rec_t* node_ptr;
4476 btr_validate_report1(index, level, block);
4478 ib_logf(IB_LOG_LEVEL_WARN,
"page is free");
4485 #ifdef UNIV_ZIP_DEBUG
4487 ut_a(!page_zip || page_zip_validate(page_zip, page, index));
4494 node_ptr = page_cur_get_rec(&cursor);
4495 offsets = rec_get_offsets(node_ptr, index, offsets,
4496 ULINT_UNDEFINED, &heap);
4497 block = btr_node_ptr_get_child(node_ptr, index, offsets, &mtr);
4498 page = buf_block_get_frame(block);
4506 seg -= PAGE_BTR_SEG_TOP - PAGE_BTR_SEG_LEAF;
4511 offsets = offsets2 = NULL;
4514 #ifdef UNIV_ZIP_DEBUG
4516 ut_a(!page_zip || page_zip_validate(page_zip, page, index));
4523 btr_validate_report1(index, level, block);
4525 ib_logf(IB_LOG_LEVEL_WARN,
"Page is marked as free");
4531 "Page index id " IB_ID_FMT
" != data dictionary "
4532 "index id " IB_ID_FMT,
4539 btr_validate_report1(index, level, block);
4542 }
else if (level == 0 && !btr_index_page_validate(block, index)) {
4550 ut_a(btr_page_get_level(page, &mtr) == level);
4560 const rec_t* right_rec;
4562 RW_X_LATCH, index, &mtr);
4563 right_page = buf_block_get_frame(right_block);
4567 btr_validate_report2(index, level, block, right_block);
4568 fputs(
"InnoDB: broken FIL_PAGE_NEXT"
4569 " or FIL_PAGE_PREV links\n", stderr);
4577 btr_validate_report2(index, level, block, right_block);
4578 fputs(
"InnoDB: 'compact' flag mismatch\n", stderr);
4584 goto node_ptr_fails;
4590 offsets = rec_get_offsets(rec, index,
4591 offsets, ULINT_UNDEFINED, &heap);
4592 offsets2 = rec_get_offsets(right_rec, index,
4593 offsets2, ULINT_UNDEFINED, &heap);
4594 if (
cmp_rec_rec(rec, right_rec, offsets, offsets2,
4597 btr_validate_report2(index, level, block, right_block);
4599 fputs(
"InnoDB: records in wrong order"
4600 " on adjacent pages\n", stderr);
4605 fputs(
"InnoDB: record ", stderr);
4609 fputs(
"InnoDB: record ", stderr);
4611 page_get_infimum_rec(right_page));
4619 if (level > 0 && left_page_no ==
FIL_NULL) {
4631 offsets = btr_page_get_father_block(offsets, heap, index,
4632 block, &mtr, &node_cur);
4634 node_ptr = btr_cur_get_rec(&node_cur);
4639 offsets = btr_page_get_father_node_ptr(offsets, heap,
4642 if (node_ptr != btr_cur_get_rec(&node_cur)
4646 btr_validate_report1(index, level, block);
4648 fputs(
"InnoDB: node pointer to the page is wrong\n",
4654 fputs(
"InnoDB: node ptr ", stderr);
4657 rec = btr_cur_get_rec(&node_cur);
4658 fprintf(stderr,
"\n"
4659 "InnoDB: node ptr child page n:o %lu\n",
4663 fputs(
"InnoDB: record on page ", stderr);
4668 goto node_ptr_fails;
4675 0, heap, btr_page_get_level(page, &mtr));
4680 page_get_infimum_rec(page));
4682 btr_validate_report1(index, level, block);
4689 fputs(
"InnoDB: Error: node ptrs differ"
4691 "InnoDB: node ptr ", stderr);
4693 fputs(
"InnoDB: first rec ", stderr);
4698 goto node_ptr_fails;
4704 page_get_infimum_rec(father_page)));
4710 page_get_supremum_rec(father_page)));
4713 const rec_t* right_node_ptr
4716 offsets = btr_page_get_father_block(
4717 offsets, heap, index, right_block,
4718 &mtr, &right_node_cur);
4720 != page_get_supremum_rec(father_page)) {
4722 if (btr_cur_get_rec(&right_node_cur)
4723 != right_node_ptr) {
4725 fputs(
"InnoDB: node pointer to"
4726 " the right page is wrong\n",
4729 btr_validate_report1(index, level,
4743 page_t* right_father_page
4746 if (btr_cur_get_rec(&right_node_cur)
4748 page_get_infimum_rec(
4749 right_father_page))) {
4751 fputs(
"InnoDB: node pointer 2 to"
4752 " the right page is wrong\n",
4755 btr_validate_report1(index, level,
4762 right_father_page, 0,
4776 fputs(
"InnoDB: node pointer 3 to"
4777 " the right page is wrong\n",
4780 btr_validate_report1(index, level,
4787 right_father_page, 0,
4808 }
else if (right_page_no !=
FIL_NULL) {
4813 space, zip_size, right_page_no,
4814 RW_X_LATCH, index, &mtr);
4816 page = buf_block_get_frame(block);
4850 ulint n = btr_page_get_level(root, &mtr);
4852 for (ulint i = 0; i <=
n; ++
i) {
4854 if (!btr_validate_level(index, trx, n - i)) {
4884 ulint max_ins_size_reorg;
4888 DBUG_ENTER(
"btr_can_merge_with_page");
4899 mblock =
btr_block_get(space, zip_size, page_no, RW_X_LATCH, index,
4901 mpage = buf_block_get_frame(mblock);
4909 if (data_size > max_ins_size_reorg) {
4926 if (data_size > max_ins_size) {
4930 if (!btr_page_reorganize_block(
4931 false, page_zip_level, mblock, index, mtr)) {
4939 ut_ad(max_ins_size == max_ins_size_reorg);
4941 if (data_size > max_ins_size) {
4950 *merge_block = mblock;
4954 *merge_block = NULL;