mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Implement UNIV_BLOB_DEBUG. An early version of this caught Bug #55284.
This option is known to be broken when tablespaces contain off-page columns after crash recovery. It has only been tested when creating the data files from the scratch. btr_blob_dbg_t: A map from page_no:heap_no:field_no to first_blob_page_no. This map is instantiated for every clustered index in index->blobs. It is protected by index->blobs_mutex. btr_blob_dbg_msg_issue(): Issue a diagnostic message. Invoked when btr_blob_dbg_msg is set. btr_blob_dbg_rbt_insert(): Insert a btr_blob_dbg_t into index->blobs. btr_blob_dbg_rbt_delete(): Remove a btr_blob_dbg_t from index->blobs. btr_blob_dbg_cmp(): Comparator for btr_blob_dbg_t. btr_blob_dbg_add_blob(): Add a BLOB reference to the map. btr_blob_dbg_add_rec(): Add all BLOB references from a record to the map. btr_blob_dbg_print(): Display the map of BLOB references in an index. btr_blob_dbg_remove_rec(): Remove all BLOB references of a record from the map. btr_blob_dbg_is_empty(): Check that no BLOB references exist to or from a page. Disowned references from delete-marked records are tolerated. btr_blob_dbg_op(): Perform an operation on all BLOB references on a B-tree page. btr_blob_dbg_add(): Add all BLOB references from a B-tree page to the map. btr_blob_dbg_remove(): Remove all BLOB references from a B-tree page from the map. btr_blob_dbg_restore(): Restore the BLOB references after a failed page reorganize. btr_blob_dbg_set_deleted_flag(): Modify the 'deleted' flag in the BLOB references of a record. btr_blob_dbg_owner(): Own or disown a BLOB reference. btr_page_create(), btr_page_free_low(): Assert that no BLOB references exist. btr_create(): Create index->blobs for clustered indexes. btr_page_reorganize_low(): Invoke btr_blob_dbg_remove() before copying the records. Invoke btr_blob_dbg_restore() if the operation fails. btr_page_empty(), btr_lift_page_up(), btr_compress(), btr_discard_page(): Invoke btr_blob_dbg_remove(). btr_cur_del_mark_set_clust_rec(): Invoke btr_blob_dbg_set_deleted_flag(). Other cases of modifying the delete mark are either in the secondary index or during crash recovery, which we do not promise to support. btr_cur_set_ownership_of_extern_field(): Invoke btr_blob_dbg_owner(). btr_store_big_rec_extern_fields(): Invoke btr_blob_dbg_add_blob(). btr_free_externally_stored_field(): Invoke btr_blob_dbg_assert_empty() on the first BLOB page. page_cur_insert_rec_low(), page_cur_insert_rec_zip(), page_copy_rec_list_end_to_created_page(): Invoke btr_blob_dbg_add_rec(). page_cur_insert_rec_zip_reorg(), page_copy_rec_list_end(), page_copy_rec_list_start(): After failure, invoke btr_blob_dbg_remove() and btr_blob_dbg_add(). page_cur_delete_rec(): Invoke btr_blob_dbg_remove_rec(). page_delete_rec_list_end(): Invoke btr_blob_dbg_op(btr_blob_dbg_remove_rec). page_zip_reorganize(): Invoke btr_blob_dbg_remove() before copying the records. page_zip_copy_recs(): Invoke btr_blob_dbg_add(). row_upd_rec_in_place(): Invoke btr_blob_dbg_rbt_delete() and btr_blob_dbg_rbt_insert(). innobase_start_or_create_for_mysql(): Warn when UNIV_BLOB_DEBUG is enabled. rb://550 approved by Jimmy Yang
This commit is contained in:
@ -498,14 +498,49 @@ row_upd_rec_in_place(
|
||||
n_fields = upd_get_n_fields(update);
|
||||
|
||||
for (i = 0; i < n_fields; i++) {
|
||||
#ifdef UNIV_BLOB_DEBUG
|
||||
btr_blob_dbg_t b;
|
||||
const byte* field_ref = NULL;
|
||||
#endif /* UNIV_BLOB_DEBUG */
|
||||
|
||||
upd_field = upd_get_nth_field(update, i);
|
||||
new_val = &(upd_field->new_val);
|
||||
ut_ad(!dfield_is_ext(new_val) ==
|
||||
!rec_offs_nth_extern(offsets, upd_field->field_no));
|
||||
#ifdef UNIV_BLOB_DEBUG
|
||||
if (dfield_is_ext(new_val)) {
|
||||
ulint len;
|
||||
field_ref = rec_get_nth_field(rec, offsets, i, &len);
|
||||
ut_a(len != UNIV_SQL_NULL);
|
||||
ut_a(len >= BTR_EXTERN_FIELD_REF_SIZE);
|
||||
field_ref += len - BTR_EXTERN_FIELD_REF_SIZE;
|
||||
|
||||
b.ref_page_no = page_get_page_no(page_align(rec));
|
||||
b.ref_heap_no = page_rec_get_heap_no(rec);
|
||||
b.ref_field_no = i;
|
||||
b.blob_page_no = mach_read_from_4(
|
||||
field_ref + BTR_EXTERN_PAGE_NO);
|
||||
ut_a(b.ref_field_no >= index->n_uniq);
|
||||
btr_blob_dbg_rbt_delete(index, &b, "upd_in_place");
|
||||
}
|
||||
#endif /* UNIV_BLOB_DEBUG */
|
||||
|
||||
rec_set_nth_field(rec, offsets, upd_field->field_no,
|
||||
dfield_get_data(new_val),
|
||||
dfield_get_len(new_val));
|
||||
|
||||
#ifdef UNIV_BLOB_DEBUG
|
||||
if (dfield_is_ext(new_val)) {
|
||||
b.blob_page_no = mach_read_from_4(
|
||||
field_ref + BTR_EXTERN_PAGE_NO);
|
||||
b.always_owner = b.owner = !(field_ref[BTR_EXTERN_LEN]
|
||||
& BTR_EXTERN_OWNER_FLAG);
|
||||
b.del = rec_get_deleted_flag(
|
||||
rec, rec_offs_comp(offsets));
|
||||
|
||||
btr_blob_dbg_rbt_insert(index, &b, "upd_in_place");
|
||||
}
|
||||
#endif /* UNIV_BLOB_DEBUG */
|
||||
}
|
||||
|
||||
if (UNIV_LIKELY_NULL(page_zip)) {
|
||||
|
Reference in New Issue
Block a user