Commit ee486208 authored by Marko Mäkelä's avatar Marko Mäkelä

Merge mysql-5.1-innodb to mysql-5.5-innodb.

parents 79887971 5adf2313
...@@ -197,7 +197,7 @@ static ...@@ -197,7 +197,7 @@ static
ulint ulint
btr_rec_get_externally_stored_len( btr_rec_get_externally_stored_len(
/*==============================*/ /*==============================*/
rec_t* rec, /*!< in: record */ const rec_t* rec, /*!< in: record */
const ulint* offsets);/*!< in: array returned by rec_get_offsets() */ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
#endif /* !UNIV_HOTBACKUP */ #endif /* !UNIV_HOTBACKUP */
...@@ -3761,6 +3761,35 @@ btr_estimate_number_of_different_key_vals( ...@@ -3761,6 +3761,35 @@ btr_estimate_number_of_different_key_vals(
/*================== EXTERNAL STORAGE OF BIG FIELDS ===================*/ /*================== EXTERNAL STORAGE OF BIG FIELDS ===================*/
/***********************************************************//**
Gets the offset of the pointer to the externally stored part of a field.
@return offset of the pointer to the externally stored part */
static
ulint
btr_rec_get_field_ref_offs(
/*=======================*/
const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
ulint n) /*!< in: index of the external field */
{
ulint field_ref_offs;
ulint local_len;
ut_a(rec_offs_nth_extern(offsets, n));
field_ref_offs = rec_get_nth_field_offs(offsets, n, &local_len);
ut_a(local_len != UNIV_SQL_NULL);
ut_a(local_len >= BTR_EXTERN_FIELD_REF_SIZE);
return(field_ref_offs + local_len - BTR_EXTERN_FIELD_REF_SIZE);
}
/** Gets a pointer to the externally stored part of a field.
@param rec record
@param offsets rec_get_offsets(rec)
@param n index of the externally stored field
@return pointer to the externally stored part */
#define btr_rec_get_field_ref(rec, offsets, n) \
((rec) + btr_rec_get_field_ref_offs(offsets, n))
/***********************************************************//** /***********************************************************//**
Gets the externally stored size of a record, in units of a database page. Gets the externally stored size of a record, in units of a database page.
@return externally stored part, in units of a database page */ @return externally stored part, in units of a database page */
...@@ -3768,27 +3797,26 @@ static ...@@ -3768,27 +3797,26 @@ static
ulint ulint
btr_rec_get_externally_stored_len( btr_rec_get_externally_stored_len(
/*==============================*/ /*==============================*/
rec_t* rec, /*!< in: record */ const rec_t* rec, /*!< in: record */
const ulint* offsets)/*!< in: array returned by rec_get_offsets() */ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{ {
ulint n_fields; ulint n_fields;
byte* data;
ulint local_len;
ulint extern_len;
ulint total_extern_len = 0; ulint total_extern_len = 0;
ulint i; ulint i;
ut_ad(!rec_offs_comp(offsets) || !rec_get_node_ptr_flag(rec)); ut_ad(!rec_offs_comp(offsets) || !rec_get_node_ptr_flag(rec));
if (!rec_offs_any_extern(offsets)) {
return(0);
}
n_fields = rec_offs_n_fields(offsets); n_fields = rec_offs_n_fields(offsets);
for (i = 0; i < n_fields; i++) { for (i = 0; i < n_fields; i++) {
if (rec_offs_nth_extern(offsets, i)) { if (rec_offs_nth_extern(offsets, i)) {
data = rec_get_nth_field(rec, offsets, i, &local_len); ulint extern_len = mach_read_from_4(
btr_rec_get_field_ref(rec, offsets, i)
local_len -= BTR_EXTERN_FIELD_REF_SIZE;
extern_len = mach_read_from_4(data + local_len
+ BTR_EXTERN_LEN + 4); + BTR_EXTERN_LEN + 4);
total_extern_len += ut_calc_align(extern_len, total_extern_len += ut_calc_align(extern_len,
...@@ -3819,7 +3847,7 @@ btr_cur_set_ownership_of_extern_field( ...@@ -3819,7 +3847,7 @@ btr_cur_set_ownership_of_extern_field(
ulint byte_val; ulint byte_val;
data = rec_get_nth_field(rec, offsets, i, &local_len); data = rec_get_nth_field(rec, offsets, i, &local_len);
ut_ad(rec_offs_nth_extern(offsets, i));
ut_a(local_len >= BTR_EXTERN_FIELD_REF_SIZE); ut_a(local_len >= BTR_EXTERN_FIELD_REF_SIZE);
local_len -= BTR_EXTERN_FIELD_REF_SIZE; local_len -= BTR_EXTERN_FIELD_REF_SIZE;
...@@ -3829,6 +3857,9 @@ btr_cur_set_ownership_of_extern_field( ...@@ -3829,6 +3857,9 @@ btr_cur_set_ownership_of_extern_field(
if (val) { if (val) {
byte_val = byte_val & (~BTR_EXTERN_OWNER_FLAG); byte_val = byte_val & (~BTR_EXTERN_OWNER_FLAG);
} else { } else {
#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
ut_a(!(byte_val & BTR_EXTERN_OWNER_FLAG));
#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
byte_val = byte_val | BTR_EXTERN_OWNER_FLAG; byte_val = byte_val | BTR_EXTERN_OWNER_FLAG;
} }
...@@ -4067,8 +4098,8 @@ file segment of the index tree. ...@@ -4067,8 +4098,8 @@ file segment of the index tree.
@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */ @return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
UNIV_INTERN UNIV_INTERN
ulint ulint
btr_store_big_rec_extern_fields( btr_store_big_rec_extern_fields_func(
/*============================*/ /*=================================*/
dict_index_t* index, /*!< in: index of rec; the index tree dict_index_t* index, /*!< in: index of rec; the index tree
MUST be X-latched */ MUST be X-latched */
buf_block_t* rec_block, /*!< in/out: block containing rec */ buf_block_t* rec_block, /*!< in/out: block containing rec */
...@@ -4077,11 +4108,17 @@ btr_store_big_rec_extern_fields( ...@@ -4077,11 +4108,17 @@ btr_store_big_rec_extern_fields(
the "external storage" flags in offsets the "external storage" flags in offsets
will not correspond to rec when will not correspond to rec when
this function returns */ this function returns */
big_rec_t* big_rec_vec, /*!< in: vector containing fields #ifdef UNIV_DEBUG
mtr_t* local_mtr, /*!< in: mtr containing the
latch to rec and to the tree */
#endif /* UNIV_DEBUG */
#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
ibool update_in_place,/*! in: TRUE if the record is updated
in place (not delete+insert) */
#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
const big_rec_t*big_rec_vec) /*!< in: vector containing fields
to be stored externally */ to be stored externally */
mtr_t* local_mtr __attribute__((unused))) /*!< in: mtr
containing the latch to rec and to the
tree */
{ {
ulint rec_page_no; ulint rec_page_no;
byte* field_ref; byte* field_ref;
...@@ -4099,6 +4136,7 @@ btr_store_big_rec_extern_fields( ...@@ -4099,6 +4136,7 @@ btr_store_big_rec_extern_fields(
z_stream c_stream; z_stream c_stream;
ut_ad(rec_offs_validate(rec, index, offsets)); ut_ad(rec_offs_validate(rec, index, offsets));
ut_ad(rec_offs_any_extern(offsets));
ut_ad(mtr_memo_contains(local_mtr, dict_index_get_lock(index), ut_ad(mtr_memo_contains(local_mtr, dict_index_get_lock(index),
MTR_MEMO_X_LOCK)); MTR_MEMO_X_LOCK));
ut_ad(mtr_memo_contains(local_mtr, rec_block, MTR_MEMO_PAGE_X_FIX)); ut_ad(mtr_memo_contains(local_mtr, rec_block, MTR_MEMO_PAGE_X_FIX));
...@@ -4130,21 +4168,37 @@ btr_store_big_rec_extern_fields( ...@@ -4130,21 +4168,37 @@ btr_store_big_rec_extern_fields(
ut_a(err == Z_OK); ut_a(err == Z_OK);
} }
#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
/* All pointers to externally stored columns in the record
must either be zero or they must be pointers to inherited
columns, owned by this record or an earlier record version. */
for (i = 0; i < rec_offs_n_fields(offsets); i++) {
if (!rec_offs_nth_extern(offsets, i)) {
continue;
}
field_ref = btr_rec_get_field_ref(rec, offsets, i);
ut_a(!(field_ref[BTR_EXTERN_LEN] & BTR_EXTERN_OWNER_FLAG));
/* Either this must be an update in place,
or the BLOB must be inherited, or the BLOB pointer
must be zero (will be written in this function). */
ut_a(update_in_place
|| (field_ref[BTR_EXTERN_LEN] & BTR_EXTERN_INHERITED_FLAG)
|| !memcmp(field_ref, field_ref_zero,
BTR_EXTERN_FIELD_REF_SIZE));
}
#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
/* We have to create a file segment to the tablespace /* We have to create a file segment to the tablespace
for each field and put the pointer to the field in rec */ for each field and put the pointer to the field in rec */
for (i = 0; i < big_rec_vec->n_fields; i++) { for (i = 0; i < big_rec_vec->n_fields; i++) {
ut_ad(rec_offs_nth_extern(offsets, field_ref = btr_rec_get_field_ref(
big_rec_vec->fields[i].field_no)); rec, offsets, big_rec_vec->fields[i].field_no);
{ #if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
ulint local_len; /* A zero BLOB pointer should have been initially inserted. */
field_ref = rec_get_nth_field( ut_a(!memcmp(field_ref, field_ref_zero,
rec, offsets, big_rec_vec->fields[i].field_no, BTR_EXTERN_FIELD_REF_SIZE));
&local_len); #endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
ut_a(local_len >= BTR_EXTERN_FIELD_REF_SIZE);
local_len -= BTR_EXTERN_FIELD_REF_SIZE;
field_ref += local_len;
}
extern_len = big_rec_vec->fields[i].len; extern_len = big_rec_vec->fields[i].len;
UNIV_MEM_ASSERT_RW(big_rec_vec->fields[i].data, UNIV_MEM_ASSERT_RW(big_rec_vec->fields[i].data,
extern_len); extern_len);
...@@ -4426,6 +4480,23 @@ next_zip_page: ...@@ -4426,6 +4480,23 @@ next_zip_page:
mem_heap_free(heap); mem_heap_free(heap);
} }
#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
/* All pointers to externally stored columns in the record
must be valid. */
for (i = 0; i < rec_offs_n_fields(offsets); i++) {
if (!rec_offs_nth_extern(offsets, i)) {
continue;
}
field_ref = btr_rec_get_field_ref(rec, offsets, i);
/* The pointer must not be zero. */
ut_a(0 != memcmp(field_ref, field_ref_zero,
BTR_EXTERN_FIELD_REF_SIZE));
/* The column must not be disowned by this record. */
ut_a(!(field_ref[BTR_EXTERN_LEN] & BTR_EXTERN_OWNER_FLAG));
}
#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
return(DB_SUCCESS); return(DB_SUCCESS);
} }
...@@ -4448,6 +4519,7 @@ btr_check_blob_fil_page_type( ...@@ -4448,6 +4519,7 @@ btr_check_blob_fil_page_type(
if (UNIV_UNLIKELY(type != FIL_PAGE_TYPE_BLOB)) { if (UNIV_UNLIKELY(type != FIL_PAGE_TYPE_BLOB)) {
ulint flags = fil_space_get_flags(space_id); ulint flags = fil_space_get_flags(space_id);
#ifndef UNIV_DEBUG /* Improve debug test coverage */
if (UNIV_LIKELY if (UNIV_LIKELY
((flags & DICT_TF_FORMAT_MASK) == DICT_TF_FORMAT_51)) { ((flags & DICT_TF_FORMAT_MASK) == DICT_TF_FORMAT_51)) {
/* Old versions of InnoDB did not initialize /* Old versions of InnoDB did not initialize
...@@ -4456,6 +4528,7 @@ btr_check_blob_fil_page_type( ...@@ -4456,6 +4528,7 @@ btr_check_blob_fil_page_type(
a BLOB page that is in Antelope format.*/ a BLOB page that is in Antelope format.*/
return; return;
} }
#endif /* !UNIV_DEBUG */
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fprintf(stderr, fprintf(stderr,
...@@ -4505,23 +4578,13 @@ btr_free_externally_stored_field( ...@@ -4505,23 +4578,13 @@ btr_free_externally_stored_field(
ulint page_no; ulint page_no;
ulint next_page_no; ulint next_page_no;
mtr_t mtr; mtr_t mtr;
#ifdef UNIV_DEBUG
ut_ad(mtr_memo_contains(local_mtr, dict_index_get_lock(index), ut_ad(mtr_memo_contains(local_mtr, dict_index_get_lock(index),
MTR_MEMO_X_LOCK)); MTR_MEMO_X_LOCK));
ut_ad(mtr_memo_contains_page(local_mtr, field_ref, ut_ad(mtr_memo_contains_page(local_mtr, field_ref,
MTR_MEMO_PAGE_X_FIX)); MTR_MEMO_PAGE_X_FIX));
ut_ad(!rec || rec_offs_validate(rec, index, offsets)); ut_ad(!rec || rec_offs_validate(rec, index, offsets));
ut_ad(!rec || field_ref == btr_rec_get_field_ref(rec, offsets, i));
if (rec) {
ulint local_len;
const byte* f = rec_get_nth_field(rec, offsets,
i, &local_len);
ut_a(local_len >= BTR_EXTERN_FIELD_REF_SIZE);
local_len -= BTR_EXTERN_FIELD_REF_SIZE;
f += local_len;
ut_ad(f == field_ref);
}
#endif /* UNIV_DEBUG */
if (UNIV_UNLIKELY(!memcmp(field_ref, field_ref_zero, if (UNIV_UNLIKELY(!memcmp(field_ref, field_ref_zero,
BTR_EXTERN_FIELD_REF_SIZE))) { BTR_EXTERN_FIELD_REF_SIZE))) {
...@@ -4684,13 +4747,8 @@ btr_rec_free_externally_stored_fields( ...@@ -4684,13 +4747,8 @@ btr_rec_free_externally_stored_fields(
for (i = 0; i < n_fields; i++) { for (i = 0; i < n_fields; i++) {
if (rec_offs_nth_extern(offsets, i)) { if (rec_offs_nth_extern(offsets, i)) {
ulint len;
byte* data
= rec_get_nth_field(rec, offsets, i, &len);
ut_a(len >= BTR_EXTERN_FIELD_REF_SIZE);
btr_free_externally_stored_field( btr_free_externally_stored_field(
index, data + len - BTR_EXTERN_FIELD_REF_SIZE, index, btr_rec_get_field_ref(rec, offsets, i),
rec, offsets, page_zip, i, rb_ctx, mtr); rec, offsets, page_zip, i, rb_ctx, mtr);
} }
} }
......
...@@ -865,9 +865,9 @@ buf_block_init( ...@@ -865,9 +865,9 @@ buf_block_init(
block->modify_clock = 0; block->modify_clock = 0;
#ifdef UNIV_DEBUG_FILE_ACCESSES #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
block->page.file_page_was_freed = FALSE; block->page.file_page_was_freed = FALSE;
#endif /* UNIV_DEBUG_FILE_ACCESSES */ #endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
block->check_index_page_at_flush = FALSE; block->check_index_page_at_flush = FALSE;
block->index = NULL; block->index = NULL;
...@@ -2229,7 +2229,7 @@ buf_page_peek_if_search_hashed( ...@@ -2229,7 +2229,7 @@ buf_page_peek_if_search_hashed(
return(is_hashed); return(is_hashed);
} }
#ifdef UNIV_DEBUG_FILE_ACCESSES #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
/********************************************************************//** /********************************************************************//**
Sets file_page_was_freed TRUE if the page is found in the buffer pool. Sets file_page_was_freed TRUE if the page is found in the buffer pool.
This function should be called when we free a file page and want the This function should be called when we free a file page and want the
...@@ -2252,6 +2252,8 @@ buf_page_set_file_page_was_freed( ...@@ -2252,6 +2252,8 @@ buf_page_set_file_page_was_freed(
if (bpage) { if (bpage) {
ut_ad(!buf_pool_watch_is_sentinel(buf_pool, bpage)); ut_ad(!buf_pool_watch_is_sentinel(buf_pool, bpage));
/* bpage->file_page_was_freed can already hold
when this code is invoked from dict_drop_index_tree() */
bpage->file_page_was_freed = TRUE; bpage->file_page_was_freed = TRUE;
} }
...@@ -2289,7 +2291,7 @@ buf_page_reset_file_page_was_freed( ...@@ -2289,7 +2291,7 @@ buf_page_reset_file_page_was_freed(
return(bpage); return(bpage);
} }
#endif /* UNIV_DEBUG_FILE_ACCESSES */ #endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
/********************************************************************//** /********************************************************************//**
Get read access to a compressed page (usually of type Get read access to a compressed page (usually of type
...@@ -2390,7 +2392,7 @@ got_block: ...@@ -2390,7 +2392,7 @@ got_block:
buf_page_set_accessed_make_young(bpage, access_time); buf_page_set_accessed_make_young(bpage, access_time);
#ifdef UNIV_DEBUG_FILE_ACCESSES #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
ut_a(!bpage->file_page_was_freed); ut_a(!bpage->file_page_was_freed);
#endif #endif
...@@ -3058,7 +3060,7 @@ wait_until_unfixed: ...@@ -3058,7 +3060,7 @@ wait_until_unfixed:
buf_page_set_accessed_make_young(&block->page, access_time); buf_page_set_accessed_make_young(&block->page, access_time);
#ifdef UNIV_DEBUG_FILE_ACCESSES #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
ut_a(!block->page.file_page_was_freed); ut_a(!block->page.file_page_was_freed);
#endif #endif
...@@ -3217,7 +3219,7 @@ buf_page_optimistic_get( ...@@ -3217,7 +3219,7 @@ buf_page_optimistic_get(
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE); ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */ #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
#ifdef UNIV_DEBUG_FILE_ACCESSES #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
ut_a(block->page.file_page_was_freed == FALSE); ut_a(block->page.file_page_was_freed == FALSE);
#endif #endif
if (UNIV_UNLIKELY(!access_time)) { if (UNIV_UNLIKELY(!access_time)) {
...@@ -3329,7 +3331,7 @@ buf_page_get_known_nowait( ...@@ -3329,7 +3331,7 @@ buf_page_get_known_nowait(
ut_a(block->page.buf_fix_count > 0); ut_a(block->page.buf_fix_count > 0);
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE); ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */ #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
#ifdef UNIV_DEBUG_FILE_ACCESSES #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
ut_a(block->page.file_page_was_freed == FALSE); ut_a(block->page.file_page_was_freed == FALSE);
#endif #endif
...@@ -3415,9 +3417,9 @@ buf_page_try_get_func( ...@@ -3415,9 +3417,9 @@ buf_page_try_get_func(
ut_a(block->page.buf_fix_count > 0); ut_a(block->page.buf_fix_count > 0);
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE); ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */ #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
#ifdef UNIV_DEBUG_FILE_ACCESSES #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
ut_a(block->page.file_page_was_freed == FALSE); ut_a(block->page.file_page_was_freed == FALSE);
#endif /* UNIV_DEBUG_FILE_ACCESSES */ #endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK); buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
buf_pool->stat.n_page_gets++; buf_pool->stat.n_page_gets++;
...@@ -3446,9 +3448,9 @@ buf_page_init_low( ...@@ -3446,9 +3448,9 @@ buf_page_init_low(
bpage->newest_modification = 0; bpage->newest_modification = 0;
bpage->oldest_modification = 0; bpage->oldest_modification = 0;
HASH_INVALIDATE(bpage, hash); HASH_INVALIDATE(bpage, hash);
#ifdef UNIV_DEBUG_FILE_ACCESSES #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
bpage->file_page_was_freed = FALSE; bpage->file_page_was_freed = FALSE;
#endif /* UNIV_DEBUG_FILE_ACCESSES */ #endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
} }
/********************************************************************//** /********************************************************************//**
...@@ -3807,9 +3809,9 @@ buf_page_create( ...@@ -3807,9 +3809,9 @@ buf_page_create(
#ifdef UNIV_IBUF_COUNT_DEBUG #ifdef UNIV_IBUF_COUNT_DEBUG
ut_a(ibuf_count_get(space, offset) == 0); ut_a(ibuf_count_get(space, offset) == 0);
#endif #endif
#ifdef UNIV_DEBUG_FILE_ACCESSES #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
block->page.file_page_was_freed = FALSE; block->page.file_page_was_freed = FALSE;
#endif /* UNIV_DEBUG_FILE_ACCESSES */ #endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
/* Page can be found in buf_pool */ /* Page can be found in buf_pool */
buf_pool_mutex_exit(buf_pool); buf_pool_mutex_exit(buf_pool);
......
...@@ -3435,9 +3435,9 @@ fseg_free_page( ...@@ -3435,9 +3435,9 @@ fseg_free_page(
fseg_free_page_low(seg_inode, space, zip_size, page, mtr); fseg_free_page_low(seg_inode, space, zip_size, page, mtr);
#ifdef UNIV_DEBUG_FILE_ACCESSES #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
buf_page_set_file_page_was_freed(space, page); buf_page_set_file_page_was_freed(space, page);
#endif #endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
} }
/**********************************************************************//** /**********************************************************************//**
...@@ -3503,13 +3503,13 @@ fseg_free_extent( ...@@ -3503,13 +3503,13 @@ fseg_free_extent(
fsp_free_extent(space, zip_size, page, mtr); fsp_free_extent(space, zip_size, page, mtr);
#ifdef UNIV_DEBUG_FILE_ACCESSES #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
for (i = 0; i < FSP_EXTENT_SIZE; i++) { for (i = 0; i < FSP_EXTENT_SIZE; i++) {
buf_page_set_file_page_was_freed(space, buf_page_set_file_page_was_freed(space,
first_page_in_extent + i); first_page_in_extent + i);
} }
#endif #endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
} }
/**********************************************************************//** /**********************************************************************//**
......
...@@ -2276,9 +2276,9 @@ ibuf_remove_free_page(void) ...@@ -2276,9 +2276,9 @@ ibuf_remove_free_page(void)
fseg_free_page(header_page + IBUF_HEADER + IBUF_TREE_SEG_HEADER, fseg_free_page(header_page + IBUF_HEADER + IBUF_TREE_SEG_HEADER,
IBUF_SPACE_ID, page_no, &mtr); IBUF_SPACE_ID, page_no, &mtr);
#ifdef UNIV_DEBUG_FILE_ACCESSES #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
buf_page_reset_file_page_was_freed(IBUF_SPACE_ID, page_no); buf_page_reset_file_page_was_freed(IBUF_SPACE_ID, page_no);
#endif #endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
ibuf_enter(); ibuf_enter();
...@@ -2322,9 +2322,9 @@ ibuf_remove_free_page(void) ...@@ -2322,9 +2322,9 @@ ibuf_remove_free_page(void)
ibuf_bitmap_page_set_bits( ibuf_bitmap_page_set_bits(
bitmap_page, page_no, zip_size, IBUF_BITMAP_IBUF, FALSE, &mtr); bitmap_page, page_no, zip_size, IBUF_BITMAP_IBUF, FALSE, &mtr);
#ifdef UNIV_DEBUG_FILE_ACCESSES #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
buf_page_set_file_page_was_freed(IBUF_SPACE_ID, page_no); buf_page_set_file_page_was_freed(IBUF_SPACE_ID, page_no);
#endif #endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
mtr_commit(&mtr); mtr_commit(&mtr);
ibuf_exit(); ibuf_exit();
......
...@@ -500,8 +500,8 @@ file segment of the index tree. ...@@ -500,8 +500,8 @@ file segment of the index tree.
@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */ @return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
UNIV_INTERN UNIV_INTERN
ulint ulint
btr_store_big_rec_extern_fields( btr_store_big_rec_extern_fields_func(
/*============================*/ /*=================================*/
dict_index_t* index, /*!< in: index of rec; the index tree dict_index_t* index, /*!< in: index of rec; the index tree
MUST be X-latched */ MUST be X-latched */
buf_block_t* rec_block, /*!< in/out: block containing rec */ buf_block_t* rec_block, /*!< in/out: block containing rec */
...@@ -510,10 +510,42 @@ btr_store_big_rec_extern_fields( ...@@ -510,10 +510,42 @@ btr_store_big_rec_extern_fields(
the "external storage" flags in offsets the "external storage" flags in offsets
will not correspond to rec when will not correspond to rec when
this function returns */ this function returns */
big_rec_t* big_rec_vec, /*!< in: vector containing fields #ifdef UNIV_DEBUG
mtr_t* local_mtr, /*!< in: mtr containing the
latch to rec and to the tree */
#endif /* UNIV_DEBUG */
#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
ibool update_in_place,/*! in: TRUE if the record is updated
in place (not delete+insert) */
#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
const big_rec_t*big_rec_vec) /*!< in: vector containing fields
to be stored externally */ to be stored externally */
mtr_t* local_mtr); /*!< in: mtr containing the latch to __attribute__((nonnull));
rec and to the tree */
/** Stores the fields in big_rec_vec to the tablespace and puts pointers to
them in rec. The extern flags in rec will have to be set beforehand.
The fields are stored on pages allocated from leaf node
file segment of the index tree.
@param index in: clustered index; MUST be X-latched by mtr
@param b in/out: block containing rec; MUST be X-latched by mtr
@param rec in/out: clustered index record
@param offsets in: rec_get_offsets(rec, index);
the "external storage" flags in offsets will not be adjusted
@param mtr in: mini-transaction that holds x-latch on index and b
@param upd in: TRUE if the record is updated in place (not delete+insert)
@param big in: vector containing fields to be stored externally
@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
#ifdef UNIV_DEBUG
# define btr_store_big_rec_extern_fields(index,b,rec,offsets,mtr,upd,big) \
btr_store_big_rec_extern_fields_func(index,b,rec,offsets,mtr,upd,big)
#elif defined UNIV_BLOB_LIGHT_DEBUG
# define btr_store_big_rec_extern_fields(index,b,rec,offsets,mtr,upd,big) \
btr_store_big_rec_extern_fields_func(index,b,rec,offsets,upd,big)
#else
# define btr_store_big_rec_extern_fields(index,b,rec,offsets,mtr,upd,big) \
btr_store_big_rec_extern_fields_func(index,b,rec,offsets,big)
#endif
/*******************************************************************//** /*******************************************************************//**
Frees the space in an externally stored field to the file space Frees the space in an externally stored field to the file space
management if the field in data is owned the externally stored field, management if the field in data is owned the externally stored field,
......
...@@ -480,7 +480,7 @@ buf_reset_check_index_page_at_flush( ...@@ -480,7 +480,7 @@ buf_reset_check_index_page_at_flush(
/*================================*/ /*================================*/
ulint space, /*!< in: space id */ ulint space, /*!< in: space id */
ulint offset);/*!< in: page number */ ulint offset);/*!< in: page number */
#ifdef UNIV_DEBUG_FILE_ACCESSES #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
/********************************************************************//** /********************************************************************//**
Sets file_page_was_freed TRUE if the page is found in the buffer pool. Sets file_page_was_freed TRUE if the page is found in the buffer pool.
This function should be called when we free a file page and want the This function should be called when we free a file page and want the
...@@ -505,7 +505,7 @@ buf_page_reset_file_page_was_freed( ...@@ -505,7 +505,7 @@ buf_page_reset_file_page_was_freed(
/*===============================*/ /*===============================*/
ulint space, /*!< in: space id */ ulint space, /*!< in: space id */
ulint offset); /*!< in: page number */ ulint offset); /*!< in: page number */
#endif /* UNIV_DEBUG_FILE_ACCESSES */ #endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
/********************************************************************//** /********************************************************************//**
Reads the freed_page_clock of a buffer block. Reads the freed_page_clock of a buffer block.
@return freed_page_clock */ @return freed_page_clock */
...@@ -1403,11 +1403,11 @@ struct buf_page_struct{ ...@@ -1403,11 +1403,11 @@ struct buf_page_struct{
0 if the block was never accessed 0 if the block was never accessed
in the buffer pool */ in the buffer pool */
/* @} */ /* @} */
# ifdef UNIV_DEBUG_FILE_ACCESSES # if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
ibool file_page_was_freed; ibool file_page_was_freed;
/*!< this is set to TRUE when fsp /*!< this is set to TRUE when fsp
frees a page in buffer pool */ frees a page in buffer pool */
# endif /* UNIV_DEBUG_FILE_ACCESSES */ # endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
#endif /* !UNIV_HOTBACKUP */ #endif /* !UNIV_HOTBACKUP */
}; };
......
...@@ -184,14 +184,15 @@ command. Not tested on Windows. */ ...@@ -184,14 +184,15 @@ command. Not tested on Windows. */
debugging without UNIV_DEBUG */ debugging without UNIV_DEBUG */
#define UNIV_BUF_DEBUG /* Enable buffer pool #define UNIV_BUF_DEBUG /* Enable buffer pool
debugging without UNIV_DEBUG */ debugging without UNIV_DEBUG */
#define UNIV_BLOB_LIGHT_DEBUG /* Enable off-page column
debugging without UNIV_DEBUG */
#define UNIV_DEBUG /* Enable ut_ad() assertions #define UNIV_DEBUG /* Enable ut_ad() assertions
and disable UNIV_INLINE */ and disable UNIV_INLINE */
#define UNIV_DEBUG_LOCK_VALIDATE /* Enable #define UNIV_DEBUG_LOCK_VALIDATE /* Enable
ut_ad(lock_rec_validate_page()) ut_ad(lock_rec_validate_page())
assertions. */ assertions. */
#define UNIV_DEBUG_FILE_ACCESSES /* Debug .ibd file access #define UNIV_DEBUG_FILE_ACCESSES /* Enable freed block access
(field file_page_was_freed debugging without UNIV_DEBUG */
in buf_page_t) */
#define UNIV_LRU_DEBUG /* debug the buffer pool LRU */ #define UNIV_LRU_DEBUG /* debug the buffer pool LRU */
#define UNIV_HASH_DEBUG /* debug HASH_ macros */ #define UNIV_HASH_DEBUG /* debug HASH_ macros */
#define UNIV_LIST_DEBUG /* debug UT_LIST_ macros */ #define UNIV_LIST_DEBUG /* debug UT_LIST_ macros */
......
...@@ -2122,7 +2122,7 @@ function_exit: ...@@ -2122,7 +2122,7 @@ function_exit:
err = btr_store_big_rec_extern_fields( err = btr_store_big_rec_extern_fields(
index, btr_cur_get_block(&cursor), index, btr_cur_get_block(&cursor),
rec, offsets, big_rec, &mtr); rec, offsets, &mtr, FALSE, big_rec);
if (modify) { if (modify) {
dtuple_big_rec_free(big_rec); dtuple_big_rec_free(big_rec);
......
...@@ -715,47 +715,32 @@ err_exit: ...@@ -715,47 +715,32 @@ err_exit:
/***********************************************************//** /***********************************************************//**
Fetches an undo log record and does the purge for the recorded operation. Fetches an undo log record and does the purge for the recorded operation.
If none left, or the current purge completed, returns the control to the If none left, or the current purge completed, returns the control to the
parent node, which is always a query thread node. parent node, which is always a query thread node. */
@return DB_SUCCESS if operation successfully completed, else error code */ static __attribute__((nonnull))
static void
ulint
row_purge( row_purge(
/*======*/ /*======*/
purge_node_t* node, /*!< in: row purge node */ purge_node_t* node, /*!< in: row purge node */
que_thr_t* thr) /*!< in: query thread */ que_thr_t* thr) /*!< in: query thread */
{ {
roll_ptr_t roll_ptr;
ibool purge_needed;
ibool updated_extern; ibool updated_extern;
trx_t* trx;
ut_ad(node && thr);
trx = thr_get_trx(thr); ut_ad(node);
ut_ad(thr);
node->undo_rec = trx_purge_fetch_next_rec(&roll_ptr, node->undo_rec = trx_purge_fetch_next_rec(&node->roll_ptr,
&(node->reservation), &node->reservation,
node->heap); node->heap);
if (!node->undo_rec) { if (!node->undo_rec) {
/* Purge completed for this query thread */ /* Purge completed for this query thread */
thr->run_node = que_node_get_parent(node); thr->run_node = que_node_get_parent(node);
return(DB_SUCCESS); return;
}
node->roll_ptr = roll_ptr;
if (node->undo_rec == &trx_purge_dummy_rec) {
purge_needed = FALSE;
} else {
purge_needed = row_purge_parse_undo_rec(node, &updated_extern,
thr);
/* If purge_needed == TRUE, we must also remember to unfreeze
data dictionary! */
} }
if (purge_needed) { if (node->undo_rec != &trx_purge_dummy_rec
&& row_purge_parse_undo_rec(node, &updated_extern, thr)) {
node->found_clust = FALSE; node->found_clust = FALSE;
node->index = dict_table_get_next_index( node->index = dict_table_get_next_index(
...@@ -774,7 +759,7 @@ row_purge( ...@@ -774,7 +759,7 @@ row_purge(
btr_pcur_close(&(node->pcur)); btr_pcur_close(&(node->pcur));
} }
row_mysql_unfreeze_data_dictionary(trx); row_mysql_unfreeze_data_dictionary(thr_get_trx(thr));
} }
/* Do some cleanup */ /* Do some cleanup */
...@@ -782,8 +767,6 @@ row_purge( ...@@ -782,8 +767,6 @@ row_purge(
mem_heap_empty(node->heap); mem_heap_empty(node->heap);
thr->run_node = node; thr->run_node = node;
return(DB_SUCCESS);
} }
/***********************************************************//** /***********************************************************//**
...@@ -797,9 +780,6 @@ row_purge_step( ...@@ -797,9 +780,6 @@ row_purge_step(
que_thr_t* thr) /*!< in: query thread */ que_thr_t* thr) /*!< in: query thread */
{ {
purge_node_t* node; purge_node_t* node;
#ifdef UNIV_DEBUG
ulint err;
#endif /* UNIV_DEBUG */
ut_ad(thr); ut_ad(thr);
...@@ -807,12 +787,7 @@ row_purge_step( ...@@ -807,12 +787,7 @@ row_purge_step(
ut_ad(que_node_get_type(node) == QUE_NODE_PURGE); ut_ad(que_node_get_type(node) == QUE_NODE_PURGE);
#ifdef UNIV_DEBUG
err =
#endif /* UNIV_DEBUG */
row_purge(node, thr); row_purge(node, thr);
ut_ad(err == DB_SUCCESS);
return(thr); return(thr);
} }
...@@ -173,40 +173,26 @@ row_undo_mod_remove_clust_low( ...@@ -173,40 +173,26 @@ row_undo_mod_remove_clust_low(
mtr_t* mtr, /*!< in: mtr */ mtr_t* mtr, /*!< in: mtr */
ulint mode) /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */ ulint mode) /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */
{ {
btr_pcur_t* pcur;
btr_cur_t* btr_cur; btr_cur_t* btr_cur;
ulint err; ulint err;
ibool success;
ut_ad(node->rec_type == TRX_UNDO_UPD_DEL_REC); ut_ad(node->rec_type == TRX_UNDO_UPD_DEL_REC);
pcur = &(node->pcur);
btr_cur = btr_pcur_get_btr_cur(pcur);
success = btr_pcur_restore_position(mode, pcur, mtr); /* Find out if the record has been purged already
or if we can remove it. */
if (!success) { if (!btr_pcur_restore_position(mode, &node->pcur, mtr)
|| row_vers_must_preserve_del_marked(node->new_trx_id, mtr)) {
return(DB_SUCCESS); return(DB_SUCCESS);
} }
/* Find out if we can remove the whole clustered index record */ btr_cur = btr_pcur_get_btr_cur(&node->pcur);
if (node->rec_type == TRX_UNDO_UPD_DEL_REC
&& !row_vers_must_preserve_del_marked(node->new_trx_id, mtr)) {
/* Ok, we can remove */
} else {
return(DB_SUCCESS);
}
if (mode == BTR_MODIFY_LEAF) { if (mode == BTR_MODIFY_LEAF) {
success = btr_cur_optimistic_delete(btr_cur, mtr); err = btr_cur_optimistic_delete(btr_cur, mtr)
? DB_SUCCESS
if (success) { : DB_FAIL;
err = DB_SUCCESS;
} else {
err = DB_FAIL;
}
} else { } else {
ut_ad(mode == BTR_MODIFY_TREE); ut_ad(mode == BTR_MODIFY_TREE);
......
...@@ -1982,7 +1982,7 @@ row_upd_clust_rec( ...@@ -1982,7 +1982,7 @@ row_upd_clust_rec(
index, btr_cur_get_block(btr_cur), rec, index, btr_cur_get_block(btr_cur), rec,
rec_get_offsets(rec, index, offsets_, rec_get_offsets(rec, index, offsets_,
ULINT_UNDEFINED, &heap), ULINT_UNDEFINED, &heap),
big_rec, mtr); mtr, TRUE, big_rec);
mtr_commit(mtr); mtr_commit(mtr);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment