📄 btr0cur.c
字号:
/* The first parameter means that no lock checking and undo logging is made in the insert */ err = btr_cur_pessimistic_insert(BTR_NO_UNDO_LOG_FLAG | BTR_NO_LOCKING_FLAG | BTR_KEEP_SYS_FLAG, cursor, new_entry, &rec, &dummy_big_rec, NULL, mtr); ut_a(rec); ut_a(err == DB_SUCCESS); ut_a(dummy_big_rec == NULL); rec_set_field_extern_bits(rec, index, ext_vect, n_ext_vect, mtr); offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap); if (!rec_get_deleted_flag(rec, rec_offs_comp(offsets))) { /* The new inserted record owns its possible externally stored fields */ btr_cur_unmark_extern_fields(rec, mtr, offsets); } lock_rec_restore_from_page_infimum(rec, page); /* If necessary, restore also the correct lock state for a new, preceding supremum record created in a page split. While the old record was nonexistent, the supremum might have inherited its locks from a wrong record. */ if (!was_first) { btr_cur_pess_upd_restore_supremum(rec, mtr); }return_after_reservations: mem_heap_free(heap); if (n_extents > 0) { fil_space_release_free_extents(index->space, n_reserved); } *big_rec = big_rec_vec; return(err);}/*==================== B-TREE DELETE MARK AND UNMARK ===============*//********************************************************************Writes the redo log record for delete marking or unmarking of an indexrecord. */UNIV_INLINEvoidbtr_cur_del_mark_set_clust_rec_log(/*===============================*/ ulint flags, /* in: flags */ rec_t* rec, /* in: record */ dict_index_t* index, /* in: index of the record */ ibool val, /* in: value to set */ trx_t* trx, /* in: deleting transaction */ dulint roll_ptr,/* in: roll ptr to the undo log record */ mtr_t* mtr) /* in: mtr */{ byte* log_ptr; ut_ad(flags < 256); ut_ad(val <= 1); ut_ad(!!page_rec_is_comp(rec) == index->table->comp); log_ptr = mlog_open_and_write_index(mtr, rec, index, page_rec_is_comp(rec) ? MLOG_COMP_REC_CLUST_DELETE_MARK : MLOG_REC_CLUST_DELETE_MARK, 1 + 1 + DATA_ROLL_PTR_LEN + 14 + 2); if (!log_ptr) { /* Logging in mtr is switched off during crash recovery */ return; } mach_write_to_1(log_ptr, flags); log_ptr++; mach_write_to_1(log_ptr, val); log_ptr++; log_ptr = row_upd_write_sys_vals_to_log(index, trx, roll_ptr, log_ptr, mtr); mach_write_to_2(log_ptr, ut_align_offset(rec, UNIV_PAGE_SIZE)); log_ptr += 2; mlog_close(mtr, log_ptr);}/********************************************************************Parses the redo log record for delete marking or unmarking of a clusteredindex record. */byte*btr_cur_parse_del_mark_set_clust_rec(/*=================================*/ /* out: end of log record or NULL */ byte* ptr, /* in: buffer */ byte* end_ptr,/* in: buffer end */ dict_index_t* index, /* in: index corresponding to page */ page_t* page) /* in: page or NULL */{ ulint flags; ulint val; ulint pos; dulint trx_id; dulint roll_ptr; ulint offset; rec_t* rec; ut_ad(!page || !!page_is_comp(page) == index->table->comp); if (end_ptr < ptr + 2) { return(NULL); } flags = mach_read_from_1(ptr); ptr++; val = mach_read_from_1(ptr); ptr++; ptr = row_upd_parse_sys_vals(ptr, end_ptr, &pos, &trx_id, &roll_ptr); if (ptr == NULL) { return(NULL); } if (end_ptr < ptr + 2) { return(NULL); } offset = mach_read_from_2(ptr); ptr += 2; ut_a(offset <= UNIV_PAGE_SIZE); if (page) { rec = page + offset; if (!(flags & BTR_KEEP_SYS_FLAG)) { mem_heap_t* heap = NULL; ulint offsets_[REC_OFFS_NORMAL_SIZE]; *offsets_ = (sizeof offsets_) / sizeof *offsets_; row_upd_rec_sys_fields_in_recovery(rec, rec_get_offsets(rec, index, offsets_, ULINT_UNDEFINED, &heap), pos, trx_id, roll_ptr); if (UNIV_LIKELY_NULL(heap)) { mem_heap_free(heap); } } /* We do not need to reserve btr_search_latch, as the page is only being recovered, and there cannot be a hash index to it. */ rec_set_deleted_flag(rec, page_is_comp(page), val); } return(ptr);}/***************************************************************Marks a clustered index record deleted. Writes an undo log record toundo log on this delete marking. Writes in the trx id field the idof the deleting transaction, and in the roll ptr field pointer to theundo log record created. */ulintbtr_cur_del_mark_set_clust_rec(/*===========================*/ /* out: DB_SUCCESS, DB_LOCK_WAIT, or error number */ ulint flags, /* in: undo logging and locking flags */ btr_cur_t* cursor, /* in: cursor */ ibool val, /* in: value to set */ que_thr_t* thr, /* in: query thread */ mtr_t* mtr) /* in: mtr */{ dict_index_t* index; buf_block_t* block; dulint roll_ptr; ulint err; rec_t* rec; trx_t* trx; mem_heap_t* heap = NULL; ulint offsets_[REC_OFFS_NORMAL_SIZE]; ulint* offsets = offsets_; *offsets_ = (sizeof offsets_) / sizeof *offsets_; rec = btr_cur_get_rec(cursor); index = cursor->index; ut_ad(!!page_rec_is_comp(rec) == index->table->comp); offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);#ifdef UNIV_DEBUG if (btr_cur_print_record_ops && thr) { btr_cur_trx_report(thr_get_trx(thr), index, "del mark "); rec_print_new(stderr, rec, offsets); }#endif /* UNIV_DEBUG */ ut_ad(index->type & DICT_CLUSTERED); ut_ad(!rec_get_deleted_flag(rec, rec_offs_comp(offsets))); err = lock_clust_rec_modify_check_and_lock(flags, rec, index, offsets, thr); if (err != DB_SUCCESS) { if (UNIV_LIKELY_NULL(heap)) { mem_heap_free(heap); } return(err); } err = trx_undo_report_row_operation(flags, TRX_UNDO_MODIFY_OP, thr, index, NULL, NULL, 0, rec, &roll_ptr); if (err != DB_SUCCESS) { if (UNIV_LIKELY_NULL(heap)) { mem_heap_free(heap); } return(err); } block = buf_block_align(rec); if (block->is_hashed) { rw_lock_x_lock(&btr_search_latch); } rec_set_deleted_flag(rec, rec_offs_comp(offsets), val); trx = thr_get_trx(thr); if (!(flags & BTR_KEEP_SYS_FLAG)) { row_upd_rec_sys_fields(rec, index, offsets, trx, roll_ptr); } if (block->is_hashed) { rw_lock_x_unlock(&btr_search_latch); } btr_cur_del_mark_set_clust_rec_log(flags, rec, index, val, trx, roll_ptr, mtr); if (UNIV_LIKELY_NULL(heap)) { mem_heap_free(heap); } return(DB_SUCCESS);}/********************************************************************Writes the redo log record for a delete mark setting of a secondaryindex record. */UNIV_INLINEvoidbtr_cur_del_mark_set_sec_rec_log(/*=============================*/ rec_t* rec, /* in: record */ ibool val, /* in: value to set */ mtr_t* mtr) /* in: mtr */{ byte* log_ptr; ut_ad(val <= 1); log_ptr = mlog_open(mtr, 11 + 1 + 2); if (!log_ptr) { /* Logging in mtr is switched off during crash recovery: in that case mlog_open returns NULL */ return; } log_ptr = mlog_write_initial_log_record_fast( rec, MLOG_REC_SEC_DELETE_MARK, log_ptr, mtr); mach_write_to_1(log_ptr, val); log_ptr++; mach_write_to_2(log_ptr, ut_align_offset(rec, UNIV_PAGE_SIZE)); log_ptr += 2; mlog_close(mtr, log_ptr);}/********************************************************************Parses the redo log record for delete marking or unmarking of a secondaryindex record. */byte*btr_cur_parse_del_mark_set_sec_rec(/*===============================*/ /* out: end of log record or NULL */ byte* ptr, /* in: buffer */ byte* end_ptr,/* in: buffer end */ page_t* page) /* in: page or NULL */{ ulint val; ulint offset; rec_t* rec; if (end_ptr < ptr + 3) { return(NULL); } val = mach_read_from_1(ptr); ptr++; offset = mach_read_from_2(ptr); ptr += 2; ut_a(offset <= UNIV_PAGE_SIZE); if (page) { rec = page + offset; /* We do not need to reserve btr_search_latch, as the page is only being recovered, and there cannot be a hash index to it. */ rec_set_deleted_flag(rec, page_is_comp(page), val); } return(ptr);} /***************************************************************Sets a secondary index record delete mark to TRUE or FALSE. */ulintbtr_cur_del_mark_set_sec_rec(/*=========================*/ /* out: DB_SUCCESS, DB_LOCK_WAIT, or error number */ ulint flags, /* in: locking flag */ btr_cur_t* cursor, /* in: cursor */ ibool val, /* in: value to set */ que_thr_t* thr, /* in: query thread */ mtr_t* mtr) /* in: mtr */{ buf_block_t* block; rec_t* rec; ulint err; rec = btr_cur_get_rec(cursor);#ifdef UNIV_DEBUG if (btr_cur_print_record_ops && thr) { btr_cur_trx_report(thr_get_trx(thr), cursor->index, "del mark "); rec_print(stderr, rec, cursor->index); }#endif /* UNIV_DEBUG */ err = lock_sec_rec_modify_check_and_lock(flags, rec, cursor->index, thr); if (err != DB_SUCCESS) { return(err); } block = buf_block_align(rec); ut_ad(!!page_is_comp(buf_block_get_frame(block)) == cursor->index->table->comp); if (block->is_hashed) { rw_lock_x_lock(&btr_search_latch); } rec_set_deleted_flag(rec, page_is_comp(buf_block_get_frame(block)), val); if (block->is_hashed) { rw_lock_x_unlock(&btr_search_latch); } btr_cur_del_mark_set_sec_rec_log(rec, val, mtr); return(DB_SUCCESS);}/***************************************************************Sets a secondary index record delete mark to FALSE. This function is onlyused by the insert buffer insert merge mechanism. */voidbtr_cur_del_unmark_for_ibuf(/*========================*/ rec_t* rec, /* in: record to delete unmark */ mtr_t* mtr) /* in: mtr */{ /* We do not need to reserve btr_search_latch, as the page has just been read to the buffer pool and there cannot be a hash index to it. */ rec_set_deleted_flag(rec, page_is_comp(buf_frame_align(rec)), FALSE); btr_cur_del_mark_set_sec_rec_log(rec, FALSE, mtr);}/*==================== B-TREE RECORD REMOVE =========================*//*****************************************************************Tries to compress a page of the tree on the leaf level. It is assumedthat mtr holds an x-latch on the tree and on the cursor page. To avoiddeadlocks, mtr must also own x-latches to brothers of page, if thosebrothers exist. NOTE: it is assumed that the caller has reserved enoughfree extents so that the compression will always succeed if done! */voidbtr_cur_compress(/*=============*/ btr_cur_t* cursor, /* in: cursor on the page to compress; cursor does not stay valid */ mtr_t* mtr) /* in: mtr */{ ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(btr_cur_get_tree(cursor)), MTR_MEMO_X_LOCK)); ut_ad(mtr_memo_contains(mtr, buf_block_align( btr_cur_get_page(cursor)), MTR_MEMO_PAGE_X_FIX)); ut_ad(btr_page_get_level(btr_cur_get_page(cursor), mtr) == 0); btr_compress(cursor, mtr); }/*****************************************************************Tries to compress a page of the tree if it seems useful. It is assumedthat mtr holds an x-latch on the tree and on the cursor page. To avoiddeadlocks, mtr must also own x-latches to brothers of page, if thosebrothers exist. NOTE: it is assumed that the caller has reserved enoughfree extents so that the compression will always succeed if done! */iboolbtr_cur_compress_if_useful(/*=======================*/ /* out: TRUE if compression occurred */ btr_cur_t* cursor, /* in: cursor on the page to compress; cursor does not stay valid if compression occurs */ mtr_t* mtr) /* in: mtr */{ ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(btr_cur_get_tree(cursor)), MTR_MEMO_X_LOCK)); ut_ad(mtr_memo_contains(mtr, buf_block_align( btr_cur_get_page(cursor)), MTR_MEMO_PAGE_X_FIX)); if (btr_cur_compress_recommendation(cursor, mtr)) { btr_compress(cursor, mtr); return(TRUE); } return(FALSE);}/***********************************************************Removes the record on which the tree cursor is positioned on a leaf page.It is assumed that the mtr has an x-latch on the page where the cursor ispositioned, but no latch on the whole tree. */iboolbtr_cur_optimistic_delete(/*======================*/ /* out: TRUE if success, i.e., the page did not become too empty */ btr_cur_t* cursor, /* in: cursor on leaf page, on the record to delete; cursor stays valid: if deletion succeeds, on fun
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -