mirror of
https://github.com/zebrajr/server.git
synced 2025-12-06 12:20:40 +01:00
MDEV-21174: Replace mlog_write_ulint() with mtr_t::write()
mtr_t::write(): Replaces mlog_write_ulint(), mlog_write_ull(). Optimize away writes if the page contents does not change, except when a dummy write has been explicitly requested. Because the member function template takes a block descriptor as a parameter, it is possible to introduce better consistency checks. Due to this, the code for handling file-based lists, undo logs and user transactions was refactored to pass around buf_block_t.
This commit is contained in:
parent
504823bcce
commit
56f6dab1d0
File diff suppressed because it is too large
Load Diff
|
|
@ -92,6 +92,8 @@ PageBulk::init()
|
||||||
new_page_zip = buf_block_get_page_zip(new_block);
|
new_page_zip = buf_block_get_page_zip(new_block);
|
||||||
new_page_no = page_get_page_no(new_page);
|
new_page_no = page_get_page_no(new_page);
|
||||||
|
|
||||||
|
byte* index_id = PAGE_HEADER + PAGE_INDEX_ID + new_page;
|
||||||
|
|
||||||
if (new_page_zip) {
|
if (new_page_zip) {
|
||||||
page_create_zip(new_block, m_index, m_level, 0,
|
page_create_zip(new_block, m_index, m_level, 0,
|
||||||
&m_mtr);
|
&m_mtr);
|
||||||
|
|
@ -100,11 +102,9 @@ PageBulk::init()
|
||||||
page_zip_write_header(new_page_zip,
|
page_zip_write_header(new_page_zip,
|
||||||
FIL_PAGE_PREV + new_page,
|
FIL_PAGE_PREV + new_page,
|
||||||
8, &m_mtr);
|
8, &m_mtr);
|
||||||
mach_write_to_8(PAGE_HEADER + PAGE_INDEX_ID + new_page,
|
mach_write_to_8(index_id, m_index->id);
|
||||||
m_index->id);
|
page_zip_write_header(new_page_zip, index_id,
|
||||||
page_zip_write_header(new_page_zip,
|
8, &m_mtr);
|
||||||
PAGE_HEADER + PAGE_INDEX_ID
|
|
||||||
+ new_page, 8, &m_mtr);
|
|
||||||
} else {
|
} else {
|
||||||
ut_ad(!dict_index_is_spatial(m_index));
|
ut_ad(!dict_index_is_spatial(m_index));
|
||||||
page_create(new_block, &m_mtr,
|
page_create(new_block, &m_mtr,
|
||||||
|
|
@ -114,10 +114,10 @@ PageBulk::init()
|
||||||
== FIL_PAGE_PREV + 4);
|
== FIL_PAGE_PREV + 4);
|
||||||
compile_time_assert(FIL_NULL == 0xffffffff);
|
compile_time_assert(FIL_NULL == 0xffffffff);
|
||||||
mlog_memset(new_block, FIL_PAGE_PREV, 8, 0xff, &m_mtr);
|
mlog_memset(new_block, FIL_PAGE_PREV, 8, 0xff, &m_mtr);
|
||||||
mlog_write_ulint(PAGE_HEADER + PAGE_LEVEL + new_page,
|
m_mtr.write<2,mtr_t::OPT>(*new_block,
|
||||||
m_level, MLOG_2BYTES, &m_mtr);
|
PAGE_HEADER + PAGE_LEVEL
|
||||||
mlog_write_ull(PAGE_HEADER + PAGE_INDEX_ID + new_page,
|
+ new_page, m_level);
|
||||||
m_index->id, &m_mtr);
|
m_mtr.write<8>(*new_block, index_id, m_index->id);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
new_block = btr_block_get(*m_index, m_page_no, RW_X_LATCH,
|
new_block = btr_block_get(*m_index, m_page_no, RW_X_LATCH,
|
||||||
|
|
@ -130,7 +130,7 @@ PageBulk::init()
|
||||||
|
|
||||||
ut_ad(page_dir_get_n_heap(new_page) == PAGE_HEAP_NO_USER_LOW);
|
ut_ad(page_dir_get_n_heap(new_page) == PAGE_HEAP_NO_USER_LOW);
|
||||||
|
|
||||||
btr_page_set_level(new_page, new_page_zip, m_level, &m_mtr);
|
btr_page_set_level(new_block, m_level, &m_mtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_level && dict_index_is_sec_or_ibuf(m_index)) {
|
if (!m_level && dict_index_is_sec_or_ibuf(m_index)) {
|
||||||
|
|
@ -169,13 +169,14 @@ PageBulk::init()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Insert a record in the page.
|
/** Insert a record in the page.
|
||||||
|
@tparam fmt the page format
|
||||||
@param[in] rec record
|
@param[in] rec record
|
||||||
@param[in] offsets record offsets */
|
@param[in] offsets record offsets */
|
||||||
void
|
template<PageBulk::format fmt>
|
||||||
PageBulk::insert(
|
inline void PageBulk::insertPage(const rec_t *rec, ulint *offsets)
|
||||||
const rec_t* rec,
|
|
||||||
ulint* offsets)
|
|
||||||
{
|
{
|
||||||
|
ut_ad((m_page_zip != nullptr) == (fmt == COMPRESSED));
|
||||||
|
ut_ad((fmt != REDUNDANT) == m_is_comp);
|
||||||
ulint rec_size;
|
ulint rec_size;
|
||||||
|
|
||||||
ut_ad(m_heap != NULL);
|
ut_ad(m_heap != NULL);
|
||||||
|
|
@ -210,7 +211,7 @@ PageBulk::insert(
|
||||||
|
|
||||||
/* 3. Set the n_owned field in the inserted record to zero,
|
/* 3. Set the n_owned field in the inserted record to zero,
|
||||||
and set the heap_no field. */
|
and set the heap_no field. */
|
||||||
if (m_is_comp) {
|
if (fmt != REDUNDANT) {
|
||||||
rec_set_n_owned_new(insert_rec, NULL, 0);
|
rec_set_n_owned_new(insert_rec, NULL, 0);
|
||||||
rec_set_heap_no_new(insert_rec,
|
rec_set_heap_no_new(insert_rec,
|
||||||
PAGE_HEAP_NO_USER_LOW + m_rec_no);
|
PAGE_HEAP_NO_USER_LOW + m_rec_no);
|
||||||
|
|
@ -242,15 +243,30 @@ PageBulk::insert(
|
||||||
m_cur_rec = insert_rec;
|
m_cur_rec = insert_rec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Insert a record in the page.
|
||||||
|
@param[in] rec record
|
||||||
|
@param[in] offsets record offsets */
|
||||||
|
inline void PageBulk::insert(const rec_t *rec, ulint *offsets)
|
||||||
|
{
|
||||||
|
if (UNIV_LIKELY_NULL(m_page_zip))
|
||||||
|
insertPage<COMPRESSED>(rec, offsets);
|
||||||
|
else if (m_is_comp)
|
||||||
|
insertPage<DYNAMIC>(rec, offsets);
|
||||||
|
else
|
||||||
|
insertPage<REDUNDANT>(rec, offsets);
|
||||||
|
}
|
||||||
|
|
||||||
/** Mark end of insertion to the page. Scan all records to set page dirs,
|
/** Mark end of insertion to the page. Scan all records to set page dirs,
|
||||||
and set page header members.
|
and set page header members.
|
||||||
Note: we refer to page_copy_rec_list_end_to_created_page. */
|
@tparam fmt the page format */
|
||||||
void
|
template<PageBulk::format fmt>
|
||||||
PageBulk::finish()
|
inline void PageBulk::finishPage()
|
||||||
{
|
{
|
||||||
ut_ad(m_rec_no > 0);
|
ut_ad(m_rec_no > 0);
|
||||||
|
ut_ad((m_page_zip != nullptr) == (fmt == COMPRESSED));
|
||||||
|
ut_ad((fmt != REDUNDANT) == m_is_comp);
|
||||||
ut_ad(m_total_data + page_dir_calc_reserved_space(m_rec_no)
|
ut_ad(m_total_data + page_dir_calc_reserved_space(m_rec_no)
|
||||||
<= page_get_free_space_of_empty(m_is_comp));
|
<= page_get_free_space_of_empty(fmt != REDUNDANT));
|
||||||
/* See page_copy_rec_list_end_to_created_page() */
|
/* See page_copy_rec_list_end_to_created_page() */
|
||||||
ut_d(page_dir_set_n_slots(m_page, NULL, srv_page_size / 2));
|
ut_d(page_dir_set_n_slots(m_page, NULL, srv_page_size / 2));
|
||||||
|
|
||||||
|
|
@ -304,26 +320,26 @@ PageBulk::finish()
|
||||||
|
|
||||||
ut_ad(!dict_index_is_spatial(m_index));
|
ut_ad(!dict_index_is_spatial(m_index));
|
||||||
ut_ad(!page_get_instant(m_page));
|
ut_ad(!page_get_instant(m_page));
|
||||||
|
ut_ad(!mach_read_from_2(PAGE_HEADER + PAGE_N_DIRECTION + m_page));
|
||||||
|
|
||||||
if (!m_flush_observer && !m_page_zip) {
|
if (fmt != COMPRESSED && !m_flush_observer) {
|
||||||
mlog_write_ulint(PAGE_HEADER + PAGE_N_DIR_SLOTS + m_page,
|
m_mtr.write<2,mtr_t::OPT>(*m_block,
|
||||||
2 + slot_index, MLOG_2BYTES, &m_mtr);
|
PAGE_HEADER + PAGE_N_DIR_SLOTS
|
||||||
mlog_write_ulint(PAGE_HEADER + PAGE_HEAP_TOP + m_page,
|
+ m_page, 2 + slot_index);
|
||||||
ulint(m_heap_top - m_page),
|
m_mtr.write<2>(*m_block, PAGE_HEADER + PAGE_HEAP_TOP + m_page,
|
||||||
MLOG_2BYTES, &m_mtr);
|
ulint(m_heap_top - m_page));
|
||||||
mlog_write_ulint(PAGE_HEADER + PAGE_N_HEAP + m_page,
|
m_mtr.write<2>(*m_block,
|
||||||
(PAGE_HEAP_NO_USER_LOW + m_rec_no)
|
PAGE_HEADER + PAGE_N_HEAP + m_page,
|
||||||
| ulint(m_is_comp) << 15,
|
(PAGE_HEAP_NO_USER_LOW + m_rec_no)
|
||||||
MLOG_2BYTES, &m_mtr);
|
| uint16_t{fmt != REDUNDANT} << 15);
|
||||||
mlog_write_ulint(PAGE_HEADER + PAGE_N_RECS + m_page, m_rec_no,
|
m_mtr.write<2>(*m_block,
|
||||||
MLOG_2BYTES, &m_mtr);
|
PAGE_HEADER + PAGE_N_RECS + m_page, m_rec_no);
|
||||||
mlog_write_ulint(PAGE_HEADER + PAGE_LAST_INSERT + m_page,
|
m_mtr.write<2>(*m_block,
|
||||||
ulint(m_cur_rec - m_page),
|
PAGE_HEADER + PAGE_LAST_INSERT + m_page,
|
||||||
MLOG_2BYTES, &m_mtr);
|
ulint(m_cur_rec - m_page));
|
||||||
mlog_write_ulint(PAGE_HEADER + PAGE_DIRECTION_B - 1 + m_page,
|
m_mtr.write<2>(*m_block,
|
||||||
PAGE_RIGHT, MLOG_2BYTES, &m_mtr);
|
PAGE_HEADER + PAGE_DIRECTION_B - 1 + m_page,
|
||||||
mlog_write_ulint(PAGE_HEADER + PAGE_N_DIRECTION + m_page, 0,
|
PAGE_RIGHT);
|
||||||
MLOG_2BYTES, &m_mtr);
|
|
||||||
} else {
|
} else {
|
||||||
/* For ROW_FORMAT=COMPRESSED, redo log may be written
|
/* For ROW_FORMAT=COMPRESSED, redo log may be written
|
||||||
in PageBulk::compress(). */
|
in PageBulk::compress(). */
|
||||||
|
|
@ -333,18 +349,29 @@ PageBulk::finish()
|
||||||
ulint(m_heap_top - m_page));
|
ulint(m_heap_top - m_page));
|
||||||
mach_write_to_2(PAGE_HEADER + PAGE_N_HEAP + m_page,
|
mach_write_to_2(PAGE_HEADER + PAGE_N_HEAP + m_page,
|
||||||
(PAGE_HEAP_NO_USER_LOW + m_rec_no)
|
(PAGE_HEAP_NO_USER_LOW + m_rec_no)
|
||||||
| ulint(m_is_comp) << 15);
|
| uint16_t{fmt != REDUNDANT} << 15);
|
||||||
mach_write_to_2(PAGE_HEADER + PAGE_N_RECS + m_page, m_rec_no);
|
mach_write_to_2(PAGE_HEADER + PAGE_N_RECS + m_page, m_rec_no);
|
||||||
mach_write_to_2(PAGE_HEADER + PAGE_LAST_INSERT + m_page,
|
mach_write_to_2(PAGE_HEADER + PAGE_LAST_INSERT + m_page,
|
||||||
ulint(m_cur_rec - m_page));
|
ulint(m_cur_rec - m_page));
|
||||||
mach_write_to_2(PAGE_HEADER + PAGE_DIRECTION_B - 1 + m_page,
|
mach_write_to_2(PAGE_HEADER + PAGE_DIRECTION_B - 1 + m_page,
|
||||||
PAGE_RIGHT);
|
PAGE_RIGHT);
|
||||||
mach_write_to_2(PAGE_HEADER + PAGE_N_DIRECTION + m_page, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_block->skip_flush_check = false;
|
m_block->skip_flush_check = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Mark end of insertion to the page. Scan all records to set page dirs,
|
||||||
|
and set page header members. */
|
||||||
|
inline void PageBulk::finish()
|
||||||
|
{
|
||||||
|
if (UNIV_LIKELY_NULL(m_page_zip))
|
||||||
|
finishPage<COMPRESSED>();
|
||||||
|
else if (m_is_comp)
|
||||||
|
finishPage<DYNAMIC>();
|
||||||
|
else
|
||||||
|
finishPage<REDUNDANT>();
|
||||||
|
}
|
||||||
|
|
||||||
/** Commit inserts done to the page
|
/** Commit inserts done to the page
|
||||||
@param[in] success Flag whether all inserts succeed. */
|
@param[in] success Flag whether all inserts succeed. */
|
||||||
void
|
void
|
||||||
|
|
@ -521,28 +548,24 @@ PageBulk::copyOut(
|
||||||
@param[in] next_page_no next page no */
|
@param[in] next_page_no next page no */
|
||||||
inline void PageBulk::setNext(ulint next_page_no)
|
inline void PageBulk::setNext(ulint next_page_no)
|
||||||
{
|
{
|
||||||
if (UNIV_LIKELY_NULL(m_page_zip)) {
|
if (UNIV_LIKELY_NULL(m_page_zip))
|
||||||
/* For ROW_FORMAT=COMPRESSED, redo log may be written
|
/* For ROW_FORMAT=COMPRESSED, redo log may be written
|
||||||
in PageBulk::compress(). */
|
in PageBulk::compress(). */
|
||||||
mach_write_to_4(m_page + FIL_PAGE_NEXT, next_page_no);
|
mach_write_to_4(m_page + FIL_PAGE_NEXT, next_page_no);
|
||||||
} else {
|
else
|
||||||
mlog_write_ulint(m_page + FIL_PAGE_NEXT, next_page_no,
|
m_mtr.write<4>(*m_block, m_page + FIL_PAGE_NEXT, next_page_no);
|
||||||
MLOG_4BYTES, &m_mtr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Set previous page
|
/** Set previous page
|
||||||
@param[in] prev_page_no previous page no */
|
@param[in] prev_page_no previous page no */
|
||||||
inline void PageBulk::setPrev(ulint prev_page_no)
|
inline void PageBulk::setPrev(ulint prev_page_no)
|
||||||
{
|
{
|
||||||
if (UNIV_LIKELY_NULL(m_page_zip)) {
|
if (UNIV_LIKELY_NULL(m_page_zip))
|
||||||
/* For ROW_FORMAT=COMPRESSED, redo log may be written
|
/* For ROW_FORMAT=COMPRESSED, redo log may be written
|
||||||
in PageBulk::compress(). */
|
in PageBulk::compress(). */
|
||||||
mach_write_to_4(m_page + FIL_PAGE_PREV, prev_page_no);
|
mach_write_to_4(m_page + FIL_PAGE_PREV, prev_page_no);
|
||||||
} else {
|
else
|
||||||
mlog_write_ulint(m_page + FIL_PAGE_PREV, prev_page_no,
|
m_mtr.write<4>(*m_block, m_page + FIL_PAGE_PREV, prev_page_no);
|
||||||
MLOG_4BYTES, &m_mtr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Check if required space is available in the page for the rec to be inserted.
|
/** Check if required space is available in the page for the rec to be inserted.
|
||||||
|
|
@ -748,9 +771,10 @@ BtrBulk::pageCommit(
|
||||||
page_bulk->setNext(next_page_bulk->getPageNo());
|
page_bulk->setNext(next_page_bulk->getPageNo());
|
||||||
next_page_bulk->setPrev(page_bulk->getPageNo());
|
next_page_bulk->setPrev(page_bulk->getPageNo());
|
||||||
} else {
|
} else {
|
||||||
/** Suppose a page is released and latched again, we need to
|
ut_ad(!page_has_next(page_bulk->getPage()));
|
||||||
|
/* If a page is released and latched again, we need to
|
||||||
mark it modified in mini-transaction. */
|
mark it modified in mini-transaction. */
|
||||||
page_bulk->setNext(FIL_NULL);
|
page_bulk->set_modified();
|
||||||
}
|
}
|
||||||
|
|
||||||
ut_ad(!rw_lock_own_flagged(&m_index->lock,
|
ut_ad(!rw_lock_own_flagged(&m_index->lock,
|
||||||
|
|
|
||||||
|
|
@ -154,8 +154,7 @@ static
|
||||||
void
|
void
|
||||||
btr_cur_unmark_extern_fields(
|
btr_cur_unmark_extern_fields(
|
||||||
/*=========================*/
|
/*=========================*/
|
||||||
page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed
|
buf_block_t* block, /*!< in/out: index page */
|
||||||
part will be updated, or NULL */
|
|
||||||
rec_t* rec, /*!< in/out: record in a clustered index */
|
rec_t* rec, /*!< in/out: record in a clustered index */
|
||||||
dict_index_t* index, /*!< in: index of the page */
|
dict_index_t* index, /*!< in: index of the page */
|
||||||
const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
|
const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
|
||||||
|
|
@ -181,8 +180,7 @@ btr_rec_free_updated_extern_fields(
|
||||||
dict_index_t* index, /*!< in: index of rec; the index tree MUST be
|
dict_index_t* index, /*!< in: index of rec; the index tree MUST be
|
||||||
X-latched */
|
X-latched */
|
||||||
rec_t* rec, /*!< in: record */
|
rec_t* rec, /*!< in: record */
|
||||||
page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
|
buf_block_t* block, /*!< in: index page of rec */
|
||||||
part will be updated, or NULL */
|
|
||||||
const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
|
const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
|
||||||
const upd_t* update, /*!< in: update vector */
|
const upd_t* update, /*!< in: update vector */
|
||||||
bool rollback,/*!< in: performing rollback? */
|
bool rollback,/*!< in: performing rollback? */
|
||||||
|
|
@ -198,8 +196,7 @@ btr_rec_free_externally_stored_fields(
|
||||||
tree MUST be X-latched */
|
tree MUST be X-latched */
|
||||||
rec_t* rec, /*!< in: record */
|
rec_t* rec, /*!< in: record */
|
||||||
const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
|
const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
|
||||||
page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
|
buf_block_t* block, /*!< in: index page of rec */
|
||||||
part will be updated, or NULL */
|
|
||||||
bool rollback,/*!< in: performing rollback? */
|
bool rollback,/*!< in: performing rollback? */
|
||||||
mtr_t* mtr); /*!< in: mini-transaction handle which contains
|
mtr_t* mtr); /*!< in: mini-transaction handle which contains
|
||||||
an X-latch to record page and to the index
|
an X-latch to record page and to the index
|
||||||
|
|
@ -224,7 +221,6 @@ btr_cur_latch_leaves(
|
||||||
uint32_t left_page_no;
|
uint32_t left_page_no;
|
||||||
uint32_t right_page_no;
|
uint32_t right_page_no;
|
||||||
buf_block_t* get_block;
|
buf_block_t* get_block;
|
||||||
page_t* page = buf_block_get_frame(block);
|
|
||||||
bool spatial;
|
bool spatial;
|
||||||
btr_latch_leaves_t latch_leaves = {{NULL, NULL, NULL}, {0, 0, 0}};
|
btr_latch_leaves_t latch_leaves = {{NULL, NULL, NULL}, {0, 0, 0}};
|
||||||
|
|
||||||
|
|
@ -252,7 +248,8 @@ btr_cur_latch_leaves(
|
||||||
true, mtr);
|
true, mtr);
|
||||||
latch_leaves.blocks[1] = get_block;
|
latch_leaves.blocks[1] = get_block;
|
||||||
#ifdef UNIV_BTR_DEBUG
|
#ifdef UNIV_BTR_DEBUG
|
||||||
ut_a(page_is_comp(get_block->frame) == page_is_comp(page));
|
ut_a(page_is_comp(get_block->frame)
|
||||||
|
== page_is_comp(block->frame));
|
||||||
#endif /* UNIV_BTR_DEBUG */
|
#endif /* UNIV_BTR_DEBUG */
|
||||||
if (spatial) {
|
if (spatial) {
|
||||||
cursor->rtr_info->tree_blocks[RTR_MAX_LEVELS]
|
cursor->rtr_info->tree_blocks[RTR_MAX_LEVELS]
|
||||||
|
|
@ -268,7 +265,7 @@ btr_cur_latch_leaves(
|
||||||
dict_index_get_lock(cursor->index),
|
dict_index_get_lock(cursor->index),
|
||||||
MTR_MEMO_X_LOCK | MTR_MEMO_SX_LOCK));
|
MTR_MEMO_X_LOCK | MTR_MEMO_SX_LOCK));
|
||||||
/* x-latch also siblings from left to right */
|
/* x-latch also siblings from left to right */
|
||||||
left_page_no = btr_page_get_prev(page);
|
left_page_no = btr_page_get_prev(block->frame);
|
||||||
|
|
||||||
if (left_page_no != FIL_NULL) {
|
if (left_page_no != FIL_NULL) {
|
||||||
|
|
||||||
|
|
@ -304,11 +301,12 @@ btr_cur_latch_leaves(
|
||||||
/* Sanity check only after both the blocks are latched. */
|
/* Sanity check only after both the blocks are latched. */
|
||||||
if (latch_leaves.blocks[0] != NULL) {
|
if (latch_leaves.blocks[0] != NULL) {
|
||||||
ut_a(page_is_comp(latch_leaves.blocks[0]->frame)
|
ut_a(page_is_comp(latch_leaves.blocks[0]->frame)
|
||||||
== page_is_comp(page));
|
== page_is_comp(block->frame));
|
||||||
ut_a(btr_page_get_next(latch_leaves.blocks[0]->frame)
|
ut_a(btr_page_get_next(latch_leaves.blocks[0]->frame)
|
||||||
== page_get_page_no(page));
|
== block->page.id.page_no());
|
||||||
}
|
}
|
||||||
ut_a(page_is_comp(get_block->frame) == page_is_comp(page));
|
ut_a(page_is_comp(get_block->frame)
|
||||||
|
== page_is_comp(block->frame));
|
||||||
#endif /* UNIV_BTR_DEBUG */
|
#endif /* UNIV_BTR_DEBUG */
|
||||||
|
|
||||||
if (spatial) {
|
if (spatial) {
|
||||||
|
|
@ -316,7 +314,7 @@ btr_cur_latch_leaves(
|
||||||
= get_block;
|
= get_block;
|
||||||
}
|
}
|
||||||
|
|
||||||
right_page_no = btr_page_get_next(page);
|
right_page_no = btr_page_get_next(block->frame);
|
||||||
|
|
||||||
if (right_page_no != FIL_NULL) {
|
if (right_page_no != FIL_NULL) {
|
||||||
if (spatial) {
|
if (spatial) {
|
||||||
|
|
@ -331,9 +329,9 @@ btr_cur_latch_leaves(
|
||||||
latch_leaves.blocks[2] = get_block;
|
latch_leaves.blocks[2] = get_block;
|
||||||
#ifdef UNIV_BTR_DEBUG
|
#ifdef UNIV_BTR_DEBUG
|
||||||
ut_a(page_is_comp(get_block->frame)
|
ut_a(page_is_comp(get_block->frame)
|
||||||
== page_is_comp(page));
|
== page_is_comp(block->frame));
|
||||||
ut_a(btr_page_get_prev(get_block->frame)
|
ut_a(btr_page_get_prev(get_block->frame)
|
||||||
== page_get_page_no(page));
|
== block->page.id.page_no());
|
||||||
#endif /* UNIV_BTR_DEBUG */
|
#endif /* UNIV_BTR_DEBUG */
|
||||||
if (spatial) {
|
if (spatial) {
|
||||||
cursor->rtr_info->tree_blocks[
|
cursor->rtr_info->tree_blocks[
|
||||||
|
|
@ -348,7 +346,7 @@ btr_cur_latch_leaves(
|
||||||
mode = latch_mode == BTR_SEARCH_PREV ? RW_S_LATCH : RW_X_LATCH;
|
mode = latch_mode == BTR_SEARCH_PREV ? RW_S_LATCH : RW_X_LATCH;
|
||||||
/* latch also left sibling */
|
/* latch also left sibling */
|
||||||
rw_lock_s_lock(&block->lock);
|
rw_lock_s_lock(&block->lock);
|
||||||
left_page_no = btr_page_get_prev(page);
|
left_page_no = btr_page_get_prev(block->frame);
|
||||||
rw_lock_s_unlock(&block->lock);
|
rw_lock_s_unlock(&block->lock);
|
||||||
|
|
||||||
if (left_page_no != FIL_NULL) {
|
if (left_page_no != FIL_NULL) {
|
||||||
|
|
@ -360,9 +358,9 @@ btr_cur_latch_leaves(
|
||||||
cursor->left_block = get_block;
|
cursor->left_block = get_block;
|
||||||
#ifdef UNIV_BTR_DEBUG
|
#ifdef UNIV_BTR_DEBUG
|
||||||
ut_a(page_is_comp(get_block->frame)
|
ut_a(page_is_comp(get_block->frame)
|
||||||
== page_is_comp(page));
|
== page_is_comp(block->frame));
|
||||||
ut_a(btr_page_get_next(get_block->frame)
|
ut_a(btr_page_get_next(get_block->frame)
|
||||||
== page_get_page_no(page));
|
== block->page.id.page_no());
|
||||||
#endif /* UNIV_BTR_DEBUG */
|
#endif /* UNIV_BTR_DEBUG */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -372,7 +370,8 @@ btr_cur_latch_leaves(
|
||||||
true, mtr);
|
true, mtr);
|
||||||
latch_leaves.blocks[1] = get_block;
|
latch_leaves.blocks[1] = get_block;
|
||||||
#ifdef UNIV_BTR_DEBUG
|
#ifdef UNIV_BTR_DEBUG
|
||||||
ut_a(page_is_comp(get_block->frame) == page_is_comp(page));
|
ut_a(page_is_comp(get_block->frame)
|
||||||
|
== page_is_comp(block->frame));
|
||||||
#endif /* UNIV_BTR_DEBUG */
|
#endif /* UNIV_BTR_DEBUG */
|
||||||
return(latch_leaves);
|
return(latch_leaves);
|
||||||
case BTR_CONT_MODIFY_TREE:
|
case BTR_CONT_MODIFY_TREE:
|
||||||
|
|
@ -2424,8 +2423,7 @@ btr_cur_search_to_nth_level_func(
|
||||||
cursor->up_bytes = up_bytes;
|
cursor->up_bytes = up_bytes;
|
||||||
|
|
||||||
if (autoinc) {
|
if (autoinc) {
|
||||||
page_set_autoinc(tree_blocks[0],
|
page_set_autoinc(tree_blocks[0], autoinc, mtr, false);
|
||||||
index, autoinc, mtr, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BTR_CUR_HASH_ADAPT
|
#ifdef BTR_CUR_HASH_ADAPT
|
||||||
|
|
@ -4160,8 +4158,6 @@ btr_cur_update_in_place(
|
||||||
further pages */
|
further pages */
|
||||||
{
|
{
|
||||||
dict_index_t* index;
|
dict_index_t* index;
|
||||||
buf_block_t* block;
|
|
||||||
page_zip_des_t* page_zip;
|
|
||||||
dberr_t err;
|
dberr_t err;
|
||||||
rec_t* rec;
|
rec_t* rec;
|
||||||
roll_ptr_t roll_ptr = 0;
|
roll_ptr_t roll_ptr = 0;
|
||||||
|
|
@ -4190,11 +4186,11 @@ btr_cur_update_in_place(
|
||||||
<< ") by " << ib::hex(trx_id) << ": "
|
<< ") by " << ib::hex(trx_id) << ": "
|
||||||
<< rec_printer(rec, offsets).str());
|
<< rec_printer(rec, offsets).str());
|
||||||
|
|
||||||
block = btr_cur_get_block(cursor);
|
buf_block_t* block = btr_cur_get_block(cursor);
|
||||||
page_zip = buf_block_get_page_zip(block);
|
page_zip_des_t* page_zip = buf_block_get_page_zip(block);
|
||||||
|
|
||||||
/* Check that enough space is available on the compressed page. */
|
/* Check that enough space is available on the compressed page. */
|
||||||
if (page_zip) {
|
if (UNIV_LIKELY_NULL(page_zip)) {
|
||||||
ut_ad(!index->table->is_temporary());
|
ut_ad(!index->table->is_temporary());
|
||||||
|
|
||||||
if (!btr_cur_update_alloc_zip(
|
if (!btr_cur_update_alloc_zip(
|
||||||
|
|
@ -4277,8 +4273,7 @@ btr_cur_update_in_place(
|
||||||
/* The new updated record owns its possible externally
|
/* The new updated record owns its possible externally
|
||||||
stored fields */
|
stored fields */
|
||||||
|
|
||||||
btr_cur_unmark_extern_fields(page_zip,
|
btr_cur_unmark_extern_fields(block, rec, index, offsets, mtr);
|
||||||
rec, index, offsets, mtr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ut_ad(err == DB_SUCCESS);
|
ut_ad(err == DB_SUCCESS);
|
||||||
|
|
@ -4803,7 +4798,6 @@ btr_cur_pessimistic_update(
|
||||||
big_rec_t* dummy_big_rec;
|
big_rec_t* dummy_big_rec;
|
||||||
dict_index_t* index;
|
dict_index_t* index;
|
||||||
buf_block_t* block;
|
buf_block_t* block;
|
||||||
page_t* page;
|
|
||||||
page_zip_des_t* page_zip;
|
page_zip_des_t* page_zip;
|
||||||
rec_t* rec;
|
rec_t* rec;
|
||||||
page_cur_t* page_cursor;
|
page_cur_t* page_cursor;
|
||||||
|
|
@ -4813,13 +4807,11 @@ btr_cur_pessimistic_update(
|
||||||
ibool was_first;
|
ibool was_first;
|
||||||
ulint n_reserved = 0;
|
ulint n_reserved = 0;
|
||||||
ulint n_ext;
|
ulint n_ext;
|
||||||
ulint max_ins_size = 0;
|
|
||||||
|
|
||||||
*offsets = NULL;
|
*offsets = NULL;
|
||||||
*big_rec = NULL;
|
*big_rec = NULL;
|
||||||
|
|
||||||
block = btr_cur_get_block(cursor);
|
block = btr_cur_get_block(cursor);
|
||||||
page = buf_block_get_frame(block);
|
|
||||||
page_zip = buf_block_get_page_zip(block);
|
page_zip = buf_block_get_page_zip(block);
|
||||||
index = cursor->index;
|
index = cursor->index;
|
||||||
|
|
||||||
|
|
@ -4828,7 +4820,7 @@ btr_cur_pessimistic_update(
|
||||||
MTR_MEMO_SX_LOCK));
|
MTR_MEMO_SX_LOCK));
|
||||||
ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
|
ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
|
||||||
#ifdef UNIV_ZIP_DEBUG
|
#ifdef UNIV_ZIP_DEBUG
|
||||||
ut_a(!page_zip || page_zip_validate(page_zip, page, index));
|
ut_a(!page_zip || page_zip_validate(page_zip, block->frame, index));
|
||||||
#endif /* UNIV_ZIP_DEBUG */
|
#endif /* UNIV_ZIP_DEBUG */
|
||||||
ut_ad(!page_zip || !index->table->is_temporary());
|
ut_ad(!page_zip || !index->table->is_temporary());
|
||||||
/* The insert buffer tree should never be updated in place. */
|
/* The insert buffer tree should never be updated in place. */
|
||||||
|
|
@ -4861,7 +4853,7 @@ btr_cur_pessimistic_update(
|
||||||
if (page_zip
|
if (page_zip
|
||||||
&& optim_err != DB_ZIP_OVERFLOW
|
&& optim_err != DB_ZIP_OVERFLOW
|
||||||
&& !dict_index_is_clust(index)
|
&& !dict_index_is_clust(index)
|
||||||
&& page_is_leaf(page)) {
|
&& page_is_leaf(block->frame)) {
|
||||||
ut_ad(!index->table->is_temporary());
|
ut_ad(!index->table->is_temporary());
|
||||||
ibuf_update_free_bits_zip(block, mtr);
|
ibuf_update_free_bits_zip(block, mtr);
|
||||||
}
|
}
|
||||||
|
|
@ -4910,7 +4902,7 @@ btr_cur_pessimistic_update(
|
||||||
/* We have to set appropriate extern storage bits in the new
|
/* We have to set appropriate extern storage bits in the new
|
||||||
record to be inserted: we have to remember which fields were such */
|
record to be inserted: we have to remember which fields were such */
|
||||||
|
|
||||||
ut_ad(!page_is_comp(page) || !rec_get_node_ptr_flag(rec));
|
ut_ad(!page_is_comp(block->frame) || !rec_get_node_ptr_flag(rec));
|
||||||
ut_ad(rec_offs_validate(rec, index, *offsets));
|
ut_ad(rec_offs_validate(rec, index, *offsets));
|
||||||
if (index->is_primary()) {
|
if (index->is_primary()) {
|
||||||
n_ext += btr_push_update_extern_fields(
|
n_ext += btr_push_update_extern_fields(
|
||||||
|
|
@ -4933,12 +4925,12 @@ btr_cur_pessimistic_update(
|
||||||
DEBUG_SYNC_C("blob_rollback_middle");
|
DEBUG_SYNC_C("blob_rollback_middle");
|
||||||
|
|
||||||
btr_rec_free_updated_extern_fields(
|
btr_rec_free_updated_extern_fields(
|
||||||
index, rec, page_zip, *offsets, update, true, mtr);
|
index, rec, block, *offsets, update, true, mtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (page_zip_rec_needs_ext(
|
if (page_zip_rec_needs_ext(
|
||||||
rec_get_converted_size(index, new_entry, n_ext),
|
rec_get_converted_size(index, new_entry, n_ext),
|
||||||
page_is_comp(page),
|
page_is_comp(block->frame),
|
||||||
dict_index_get_n_fields(index),
|
dict_index_get_n_fields(index),
|
||||||
block->zip_size())
|
block->zip_size())
|
||||||
|| (UNIV_UNLIKELY(update->is_alter_metadata())
|
|| (UNIV_UNLIKELY(update->is_alter_metadata())
|
||||||
|
|
@ -4954,14 +4946,15 @@ btr_cur_pessimistic_update(
|
||||||
BTR_KEEP_IBUF_BITMAP. */
|
BTR_KEEP_IBUF_BITMAP. */
|
||||||
#ifdef UNIV_ZIP_DEBUG
|
#ifdef UNIV_ZIP_DEBUG
|
||||||
ut_a(!page_zip
|
ut_a(!page_zip
|
||||||
|| page_zip_validate(page_zip, page, index));
|
|| page_zip_validate(page_zip, block->frame,
|
||||||
|
index));
|
||||||
#endif /* UNIV_ZIP_DEBUG */
|
#endif /* UNIV_ZIP_DEBUG */
|
||||||
index->table->space->release_free_extents(n_reserved);
|
index->table->space->release_free_extents(n_reserved);
|
||||||
err = DB_TOO_BIG_RECORD;
|
err = DB_TOO_BIG_RECORD;
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
ut_ad(page_is_leaf(page));
|
ut_ad(page_is_leaf(block->frame));
|
||||||
ut_ad(dict_index_is_clust(index));
|
ut_ad(dict_index_is_clust(index));
|
||||||
ut_ad(flags & BTR_KEEP_POS_FLAG);
|
ut_ad(flags & BTR_KEEP_POS_FLAG);
|
||||||
}
|
}
|
||||||
|
|
@ -4996,10 +4989,9 @@ btr_cur_pessimistic_update(
|
||||||
btr_cur_write_sys(new_entry, index, trx_id, roll_ptr);
|
btr_cur_write_sys(new_entry, index, trx_id, roll_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!page_zip) {
|
const ulint max_ins_size = page_zip
|
||||||
max_ins_size = page_get_max_insert_size_after_reorganize(
|
? 0 : page_get_max_insert_size_after_reorganize(block->frame,
|
||||||
page, 1);
|
1);
|
||||||
}
|
|
||||||
|
|
||||||
if (UNIV_UNLIKELY(is_metadata)) {
|
if (UNIV_UNLIKELY(is_metadata)) {
|
||||||
ut_ad(new_entry->is_metadata());
|
ut_ad(new_entry->is_metadata());
|
||||||
|
|
@ -5027,7 +5019,7 @@ btr_cur_pessimistic_update(
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef UNIV_ZIP_DEBUG
|
#ifdef UNIV_ZIP_DEBUG
|
||||||
ut_a(!page_zip || page_zip_validate(page_zip, page, index));
|
ut_a(!page_zip || page_zip_validate(page_zip, block->frame, index));
|
||||||
#endif /* UNIV_ZIP_DEBUG */
|
#endif /* UNIV_ZIP_DEBUG */
|
||||||
page_cursor = btr_cur_get_page_cur(cursor);
|
page_cursor = btr_cur_get_page_cur(cursor);
|
||||||
|
|
||||||
|
|
@ -5058,8 +5050,8 @@ btr_cur_pessimistic_update(
|
||||||
|| rec_is_alter_metadata(rec, *index)) {
|
|| rec_is_alter_metadata(rec, *index)) {
|
||||||
/* The new inserted record owns its possible externally
|
/* The new inserted record owns its possible externally
|
||||||
stored fields */
|
stored fields */
|
||||||
btr_cur_unmark_extern_fields(
|
btr_cur_unmark_extern_fields(btr_cur_get_block(cursor),
|
||||||
page_zip, rec, index, *offsets, mtr);
|
rec, index, *offsets, mtr);
|
||||||
} else {
|
} else {
|
||||||
/* In delete-marked records, DB_TRX_ID must
|
/* In delete-marked records, DB_TRX_ID must
|
||||||
always refer to an existing undo log record. */
|
always refer to an existing undo log record. */
|
||||||
|
|
@ -5067,7 +5059,7 @@ btr_cur_pessimistic_update(
|
||||||
}
|
}
|
||||||
|
|
||||||
bool adjust = big_rec_vec && (flags & BTR_KEEP_POS_FLAG);
|
bool adjust = big_rec_vec && (flags & BTR_KEEP_POS_FLAG);
|
||||||
ut_ad(!adjust || page_is_leaf(page));
|
ut_ad(!adjust || page_is_leaf(block->frame));
|
||||||
|
|
||||||
if (btr_cur_compress_if_useful(cursor, adjust, mtr)) {
|
if (btr_cur_compress_if_useful(cursor, adjust, mtr)) {
|
||||||
if (adjust) {
|
if (adjust) {
|
||||||
|
|
@ -5075,7 +5067,7 @@ btr_cur_pessimistic_update(
|
||||||
true, *offsets);
|
true, *offsets);
|
||||||
}
|
}
|
||||||
} else if (!dict_index_is_clust(index)
|
} else if (!dict_index_is_clust(index)
|
||||||
&& page_is_leaf(page)) {
|
&& page_is_leaf(block->frame)) {
|
||||||
/* Update the free bits in the insert buffer.
|
/* Update the free bits in the insert buffer.
|
||||||
This is the same block which was skipped by
|
This is the same block which was skipped by
|
||||||
BTR_KEEP_IBUF_BITMAP. */
|
BTR_KEEP_IBUF_BITMAP. */
|
||||||
|
|
@ -5090,7 +5082,7 @@ btr_cur_pessimistic_update(
|
||||||
|
|
||||||
if (!srv_read_only_mode
|
if (!srv_read_only_mode
|
||||||
&& !big_rec_vec
|
&& !big_rec_vec
|
||||||
&& page_is_leaf(page)
|
&& page_is_leaf(block->frame)
|
||||||
&& !dict_index_is_online_ddl(index)) {
|
&& !dict_index_is_online_ddl(index)) {
|
||||||
|
|
||||||
mtr_memo_release(mtr, dict_index_get_lock(index),
|
mtr_memo_release(mtr, dict_index_get_lock(index),
|
||||||
|
|
@ -5115,13 +5107,13 @@ btr_cur_pessimistic_update(
|
||||||
BTR_KEEP_IBUF_BITMAP. */
|
BTR_KEEP_IBUF_BITMAP. */
|
||||||
if (!dict_index_is_clust(index)
|
if (!dict_index_is_clust(index)
|
||||||
&& !index->table->is_temporary()
|
&& !index->table->is_temporary()
|
||||||
&& page_is_leaf(page)) {
|
&& page_is_leaf(block->frame)) {
|
||||||
ibuf_reset_free_bits(block);
|
ibuf_reset_free_bits(block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (big_rec_vec != NULL) {
|
if (big_rec_vec != NULL) {
|
||||||
ut_ad(page_is_leaf(page));
|
ut_ad(page_is_leaf(block->frame));
|
||||||
ut_ad(dict_index_is_clust(index));
|
ut_ad(dict_index_is_clust(index));
|
||||||
ut_ad(flags & BTR_KEEP_POS_FLAG);
|
ut_ad(flags & BTR_KEEP_POS_FLAG);
|
||||||
|
|
||||||
|
|
@ -5170,28 +5162,20 @@ btr_cur_pessimistic_update(
|
||||||
/* Update PAGE_MAX_TRX_ID in the index page header.
|
/* Update PAGE_MAX_TRX_ID in the index page header.
|
||||||
It was not updated by btr_cur_pessimistic_insert()
|
It was not updated by btr_cur_pessimistic_insert()
|
||||||
because of BTR_NO_LOCKING_FLAG. */
|
because of BTR_NO_LOCKING_FLAG. */
|
||||||
buf_block_t* rec_block;
|
page_update_max_trx_id(btr_cur_get_block(cursor),
|
||||||
|
btr_cur_get_page_zip(cursor),
|
||||||
rec_block = btr_cur_get_block(cursor);
|
|
||||||
|
|
||||||
page_update_max_trx_id(rec_block,
|
|
||||||
buf_block_get_page_zip(rec_block),
|
|
||||||
trx_id, mtr);
|
trx_id, mtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rec_get_deleted_flag(rec, rec_offs_comp(*offsets))) {
|
if (!rec_get_deleted_flag(rec, rec_offs_comp(*offsets))) {
|
||||||
/* The new inserted record owns its possible externally
|
/* The new inserted record owns its possible externally
|
||||||
stored fields */
|
stored fields */
|
||||||
buf_block_t* rec_block = btr_cur_get_block(cursor);
|
|
||||||
|
|
||||||
#ifdef UNIV_ZIP_DEBUG
|
#ifdef UNIV_ZIP_DEBUG
|
||||||
ut_a(!page_zip || page_zip_validate(page_zip, page, index));
|
ut_a(!page_zip || page_zip_validate(page_zip, block->frame,
|
||||||
page = buf_block_get_frame(rec_block);
|
index));
|
||||||
#endif /* UNIV_ZIP_DEBUG */
|
#endif /* UNIV_ZIP_DEBUG */
|
||||||
page_zip = buf_block_get_page_zip(rec_block);
|
btr_cur_unmark_extern_fields(btr_cur_get_block(cursor), rec,
|
||||||
|
index, *offsets, mtr);
|
||||||
btr_cur_unmark_extern_fields(page_zip,
|
|
||||||
rec, index, *offsets, mtr);
|
|
||||||
} else {
|
} else {
|
||||||
/* In delete-marked records, DB_TRX_ID must
|
/* In delete-marked records, DB_TRX_ID must
|
||||||
always refer to an existing undo log record. */
|
always refer to an existing undo log record. */
|
||||||
|
|
@ -5222,7 +5206,8 @@ btr_cur_pessimistic_update(
|
||||||
|
|
||||||
return_after_reservations:
|
return_after_reservations:
|
||||||
#ifdef UNIV_ZIP_DEBUG
|
#ifdef UNIV_ZIP_DEBUG
|
||||||
ut_a(!page_zip || page_zip_validate(page_zip, page, index));
|
ut_a(!page_zip || page_zip_validate(btr_cur_get_page_zip(cursor),
|
||||||
|
btr_cur_get_page(cursor), index));
|
||||||
#endif /* UNIV_ZIP_DEBUG */
|
#endif /* UNIV_ZIP_DEBUG */
|
||||||
|
|
||||||
index->table->space->release_free_extents(n_reserved);
|
index->table->space->release_free_extents(n_reserved);
|
||||||
|
|
@ -5393,7 +5378,6 @@ btr_cur_del_mark_set_clust_rec(
|
||||||
{
|
{
|
||||||
roll_ptr_t roll_ptr;
|
roll_ptr_t roll_ptr;
|
||||||
dberr_t err;
|
dberr_t err;
|
||||||
page_zip_des_t* page_zip;
|
|
||||||
trx_t* trx;
|
trx_t* trx;
|
||||||
|
|
||||||
ut_ad(dict_index_is_clust(index));
|
ut_ad(dict_index_is_clust(index));
|
||||||
|
|
@ -5431,7 +5415,7 @@ btr_cur_del_mark_set_clust_rec(
|
||||||
the adaptive hash index does not depend on the delete-mark
|
the adaptive hash index does not depend on the delete-mark
|
||||||
and the delete-mark is being updated in place. */
|
and the delete-mark is being updated in place. */
|
||||||
|
|
||||||
page_zip = buf_block_get_page_zip(block);
|
page_zip_des_t* page_zip = buf_block_get_page_zip(block);
|
||||||
|
|
||||||
btr_rec_set_deleted_flag(rec, page_zip, TRUE);
|
btr_rec_set_deleted_flag(rec, page_zip, TRUE);
|
||||||
|
|
||||||
|
|
@ -5905,7 +5889,7 @@ btr_cur_pessimistic_delete(
|
||||||
|
|
||||||
if (rec_offs_any_extern(offsets)) {
|
if (rec_offs_any_extern(offsets)) {
|
||||||
btr_rec_free_externally_stored_fields(index,
|
btr_rec_free_externally_stored_fields(index,
|
||||||
rec, offsets, page_zip,
|
rec, offsets, block,
|
||||||
rollback, mtr);
|
rollback, mtr);
|
||||||
#ifdef UNIV_ZIP_DEBUG
|
#ifdef UNIV_ZIP_DEBUG
|
||||||
ut_a(!page_zip || page_zip_validate(page_zip, page, index));
|
ut_a(!page_zip || page_zip_validate(page_zip, page, index));
|
||||||
|
|
@ -7144,13 +7128,12 @@ static
|
||||||
void
|
void
|
||||||
btr_cur_set_ownership_of_extern_field(
|
btr_cur_set_ownership_of_extern_field(
|
||||||
/*==================================*/
|
/*==================================*/
|
||||||
page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed
|
buf_block_t* block, /*!< in/out: index page */
|
||||||
part will be updated, or NULL */
|
|
||||||
rec_t* rec, /*!< in/out: clustered index record */
|
rec_t* rec, /*!< in/out: clustered index record */
|
||||||
dict_index_t* index, /*!< in: index of the page */
|
dict_index_t* index, /*!< in: index of the page */
|
||||||
const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
|
const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
|
||||||
ulint i, /*!< in: field number */
|
ulint i, /*!< in: field number */
|
||||||
ibool val, /*!< in: value to set */
|
bool val, /*!< in: value to set */
|
||||||
mtr_t* mtr) /*!< in: mtr, or NULL if not logged */
|
mtr_t* mtr) /*!< in: mtr, or NULL if not logged */
|
||||||
{
|
{
|
||||||
byte* data;
|
byte* data;
|
||||||
|
|
@ -7174,15 +7157,14 @@ btr_cur_set_ownership_of_extern_field(
|
||||||
byte_val |= BTR_EXTERN_OWNER_FLAG;
|
byte_val |= BTR_EXTERN_OWNER_FLAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (page_zip) {
|
if (UNIV_LIKELY_NULL(block->page.zip.data)) {
|
||||||
mach_write_to_1(data + local_len + BTR_EXTERN_LEN, byte_val);
|
mach_write_to_1(data + local_len + BTR_EXTERN_LEN, byte_val);
|
||||||
page_zip_write_blob_ptr(page_zip, rec, index, offsets, i, mtr);
|
page_zip_write_blob_ptr(&block->page.zip, rec, index, offsets,
|
||||||
} else if (mtr != NULL) {
|
i, mtr);
|
||||||
|
|
||||||
mlog_write_ulint(data + local_len + BTR_EXTERN_LEN, byte_val,
|
|
||||||
MLOG_1BYTE, mtr);
|
|
||||||
} else {
|
} else {
|
||||||
mach_write_to_1(data + local_len + BTR_EXTERN_LEN, byte_val);
|
mtr->write<1,mtr_t::OPT>(*block,
|
||||||
|
data + local_len + BTR_EXTERN_LEN,
|
||||||
|
byte_val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -7194,8 +7176,7 @@ to free the field. */
|
||||||
void
|
void
|
||||||
btr_cur_disown_inherited_fields(
|
btr_cur_disown_inherited_fields(
|
||||||
/*============================*/
|
/*============================*/
|
||||||
page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed
|
buf_block_t* block, /*!< in/out: index page */
|
||||||
part will be updated, or NULL */
|
|
||||||
rec_t* rec, /*!< in/out: record in a clustered index */
|
rec_t* rec, /*!< in/out: record in a clustered index */
|
||||||
dict_index_t* index, /*!< in: index of the page */
|
dict_index_t* index, /*!< in: index of the page */
|
||||||
const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
|
const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
|
||||||
|
|
@ -7212,7 +7193,7 @@ btr_cur_disown_inherited_fields(
|
||||||
if (rec_offs_nth_extern(offsets, i)
|
if (rec_offs_nth_extern(offsets, i)
|
||||||
&& !upd_get_field_by_field_no(update, i, false)) {
|
&& !upd_get_field_by_field_no(update, i, false)) {
|
||||||
btr_cur_set_ownership_of_extern_field(
|
btr_cur_set_ownership_of_extern_field(
|
||||||
page_zip, rec, index, offsets, i, FALSE, mtr);
|
block, rec, index, offsets, i, false, mtr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -7225,29 +7206,23 @@ static
|
||||||
void
|
void
|
||||||
btr_cur_unmark_extern_fields(
|
btr_cur_unmark_extern_fields(
|
||||||
/*=========================*/
|
/*=========================*/
|
||||||
page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed
|
buf_block_t* block, /*!< in/out: index page */
|
||||||
part will be updated, or NULL */
|
|
||||||
rec_t* rec, /*!< in/out: record in a clustered index */
|
rec_t* rec, /*!< in/out: record in a clustered index */
|
||||||
dict_index_t* index, /*!< in: index of the page */
|
dict_index_t* index, /*!< in: index of the page */
|
||||||
const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
|
const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
|
||||||
mtr_t* mtr) /*!< in: mtr, or NULL if not logged */
|
mtr_t* mtr) /*!< in: mtr, or NULL if not logged */
|
||||||
{
|
{
|
||||||
ulint n;
|
|
||||||
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));
|
||||||
n = rec_offs_n_fields(offsets);
|
|
||||||
|
|
||||||
if (!rec_offs_any_extern(offsets)) {
|
if (!rec_offs_any_extern(offsets)) {
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
const ulint n = rec_offs_n_fields(offsets);
|
||||||
if (rec_offs_nth_extern(offsets, i)) {
|
|
||||||
|
|
||||||
|
for (ulint i = 0; i < n; i++) {
|
||||||
|
if (rec_offs_nth_extern(offsets, i)) {
|
||||||
btr_cur_set_ownership_of_extern_field(
|
btr_cur_set_ownership_of_extern_field(
|
||||||
page_zip, rec, index, offsets, i, TRUE, mtr);
|
block, rec, index, offsets, i, true, mtr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -7648,7 +7623,6 @@ btr_store_big_rec_extern_fields(
|
||||||
|
|
||||||
for (ulint blob_npages = 0;; ++blob_npages) {
|
for (ulint blob_npages = 0;; ++blob_npages) {
|
||||||
buf_block_t* block;
|
buf_block_t* block;
|
||||||
page_t* page;
|
|
||||||
const ulint commit_freq = 4;
|
const ulint commit_freq = 4;
|
||||||
ulint r_extents;
|
ulint r_extents;
|
||||||
|
|
||||||
|
|
@ -7711,11 +7685,9 @@ btr_store_big_rec_extern_fields(
|
||||||
ut_a(block != NULL);
|
ut_a(block != NULL);
|
||||||
|
|
||||||
page_no = block->page.id.page_no();
|
page_no = block->page.id.page_no();
|
||||||
page = buf_block_get_frame(block);
|
|
||||||
|
|
||||||
if (prev_page_no != FIL_NULL) {
|
if (prev_page_no != FIL_NULL) {
|
||||||
buf_block_t* prev_block;
|
buf_block_t* prev_block;
|
||||||
page_t* prev_page;
|
|
||||||
|
|
||||||
prev_block = buf_page_get(
|
prev_block = buf_page_get(
|
||||||
page_id_t(space_id, prev_page_no),
|
page_id_t(space_id, prev_page_no),
|
||||||
|
|
@ -7724,23 +7696,25 @@ btr_store_big_rec_extern_fields(
|
||||||
|
|
||||||
buf_block_dbg_add_level(prev_block,
|
buf_block_dbg_add_level(prev_block,
|
||||||
SYNC_EXTERN_STORAGE);
|
SYNC_EXTERN_STORAGE);
|
||||||
prev_page = buf_block_get_frame(prev_block);
|
|
||||||
|
|
||||||
if (page_zip) {
|
if (page_zip) {
|
||||||
mlog_write_ulint(
|
mtr.write<4>(*prev_block,
|
||||||
prev_page + FIL_PAGE_NEXT,
|
prev_block->frame
|
||||||
page_no, MLOG_4BYTES, &mtr);
|
+ FIL_PAGE_NEXT,
|
||||||
memcpy(buf_block_get_page_zip(
|
page_no);
|
||||||
prev_block)
|
memcpy_aligned<4>(
|
||||||
->data + FIL_PAGE_NEXT,
|
buf_block_get_page_zip(
|
||||||
prev_page + FIL_PAGE_NEXT, 4);
|
prev_block)
|
||||||
|
->data + FIL_PAGE_NEXT,
|
||||||
|
prev_block->frame
|
||||||
|
+ FIL_PAGE_NEXT, 4);
|
||||||
} else {
|
} else {
|
||||||
mlog_write_ulint(
|
mtr.write<4>(*prev_block,
|
||||||
prev_page + FIL_PAGE_DATA
|
BTR_BLOB_HDR_NEXT_PAGE_NO
|
||||||
+ BTR_BLOB_HDR_NEXT_PAGE_NO,
|
+ FIL_PAGE_DATA
|
||||||
page_no, MLOG_4BYTES, &mtr);
|
+ prev_block->frame,
|
||||||
|
page_no);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (dict_index_is_online_ddl(index)) {
|
} else if (dict_index_is_online_ddl(index)) {
|
||||||
row_log_table_blob_alloc(index, page_no);
|
row_log_table_blob_alloc(index, page_no);
|
||||||
}
|
}
|
||||||
|
|
@ -7751,7 +7725,7 @@ btr_store_big_rec_extern_fields(
|
||||||
|
|
||||||
/* Write FIL_PAGE_TYPE to the redo log
|
/* Write FIL_PAGE_TYPE to the redo log
|
||||||
separately, before logging any other
|
separately, before logging any other
|
||||||
changes to the page, so that the debug
|
changes to the block, so that the debug
|
||||||
assertions in
|
assertions in
|
||||||
recv_parse_or_apply_log_rec_body() can
|
recv_parse_or_apply_log_rec_body() can
|
||||||
be made simpler. Before InnoDB Plugin
|
be made simpler. Before InnoDB Plugin
|
||||||
|
|
@ -7759,13 +7733,13 @@ btr_store_big_rec_extern_fields(
|
||||||
FIL_PAGE_TYPE was logged as part of
|
FIL_PAGE_TYPE was logged as part of
|
||||||
the mlog_log_string() below. */
|
the mlog_log_string() below. */
|
||||||
|
|
||||||
mlog_write_ulint(page + FIL_PAGE_TYPE,
|
mtr.write<2>(*block,
|
||||||
prev_page_no == FIL_NULL
|
block->frame + FIL_PAGE_TYPE,
|
||||||
? FIL_PAGE_TYPE_ZBLOB
|
prev_page_no == FIL_NULL
|
||||||
: FIL_PAGE_TYPE_ZBLOB2,
|
? FIL_PAGE_TYPE_ZBLOB
|
||||||
MLOG_2BYTES, &mtr);
|
: FIL_PAGE_TYPE_ZBLOB2);
|
||||||
|
|
||||||
c_stream.next_out = page
|
c_stream.next_out = block->frame
|
||||||
+ FIL_PAGE_DATA;
|
+ FIL_PAGE_DATA;
|
||||||
c_stream.avail_out = static_cast<uInt>(
|
c_stream.avail_out = static_cast<uInt>(
|
||||||
payload_size_zip);
|
payload_size_zip);
|
||||||
|
|
@ -7799,15 +7773,13 @@ btr_store_big_rec_extern_fields(
|
||||||
Number */
|
Number */
|
||||||
ut_ad(!dict_index_is_spatial(index));
|
ut_ad(!dict_index_is_spatial(index));
|
||||||
|
|
||||||
mlog_write_ulint(page
|
mtr.write<4>(*block, block->frame
|
||||||
+ FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION,
|
+ FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION,
|
||||||
space_id,
|
space_id);
|
||||||
MLOG_4BYTES, &mtr);
|
mtr.write<4>(*block, block->frame
|
||||||
mlog_write_ulint(page
|
+ FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + 4,
|
||||||
+ FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + 4,
|
rec_page_no);
|
||||||
rec_page_no,
|
mlog_log_string(block->frame
|
||||||
MLOG_4BYTES, &mtr);
|
|
||||||
mlog_log_string(page
|
|
||||||
+ FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION,
|
+ FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION,
|
||||||
page_zip_get_size(page_zip)
|
page_zip_get_size(page_zip)
|
||||||
- FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION
|
- FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION
|
||||||
|
|
@ -7828,7 +7800,7 @@ btr_store_big_rec_extern_fields(
|
||||||
ut_ad(blob_page_zip);
|
ut_ad(blob_page_zip);
|
||||||
ut_ad(page_zip_get_size(blob_page_zip)
|
ut_ad(page_zip_get_size(blob_page_zip)
|
||||||
== page_zip_get_size(page_zip));
|
== page_zip_get_size(page_zip));
|
||||||
memcpy(blob_page_zip->data, page,
|
memcpy(blob_page_zip->data, block->frame,
|
||||||
page_zip_get_size(page_zip));
|
page_zip_get_size(page_zip));
|
||||||
|
|
||||||
if (err == Z_OK && prev_page_no != FIL_NULL) {
|
if (err == Z_OK && prev_page_no != FIL_NULL) {
|
||||||
|
|
@ -7880,9 +7852,9 @@ btr_store_big_rec_extern_fields(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mlog_write_ulint(page + FIL_PAGE_TYPE,
|
mtr.write<2>(*block, FIL_PAGE_TYPE
|
||||||
FIL_PAGE_TYPE_BLOB,
|
+ block->frame,
|
||||||
MLOG_2BYTES, &mtr);
|
FIL_PAGE_TYPE_BLOB);
|
||||||
|
|
||||||
if (extern_len > payload_size) {
|
if (extern_len > payload_size) {
|
||||||
store_len = payload_size;
|
store_len = payload_size;
|
||||||
|
|
@ -7890,47 +7862,44 @@ btr_store_big_rec_extern_fields(
|
||||||
store_len = extern_len;
|
store_len = extern_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
mlog_write_string(page + FIL_PAGE_DATA
|
mlog_write_string(FIL_PAGE_DATA
|
||||||
+ BTR_BLOB_HDR_SIZE,
|
+ BTR_BLOB_HDR_SIZE
|
||||||
|
+ block->frame,
|
||||||
(const byte*)
|
(const byte*)
|
||||||
big_rec_vec->fields[i].data
|
big_rec_vec->fields[i].data
|
||||||
+ big_rec_vec->fields[i].len
|
+ big_rec_vec->fields[i].len
|
||||||
- extern_len,
|
- extern_len,
|
||||||
store_len, &mtr);
|
store_len, &mtr);
|
||||||
mlog_write_ulint(page + FIL_PAGE_DATA
|
mtr.write<4>(*block, BTR_BLOB_HDR_PART_LEN
|
||||||
+ BTR_BLOB_HDR_PART_LEN,
|
+ FIL_PAGE_DATA + block->frame,
|
||||||
store_len, MLOG_4BYTES, &mtr);
|
store_len);
|
||||||
mlog_write_ulint(page + FIL_PAGE_DATA
|
compile_time_assert(FIL_NULL == 0xffffffff);
|
||||||
+ BTR_BLOB_HDR_NEXT_PAGE_NO,
|
mlog_memset(block, BTR_BLOB_HDR_NEXT_PAGE_NO
|
||||||
FIL_NULL, MLOG_4BYTES, &mtr);
|
+ FIL_PAGE_DATA, 4, 0xff, &mtr);
|
||||||
|
|
||||||
extern_len -= store_len;
|
extern_len -= store_len;
|
||||||
|
|
||||||
ut_ad(!mach_read_from_4(BTR_EXTERN_LEN
|
ut_ad(!mach_read_from_4(BTR_EXTERN_LEN
|
||||||
+ field_ref));
|
+ field_ref));
|
||||||
mlog_write_ulint(field_ref
|
mtr.write<4>(*rec_block,
|
||||||
+ BTR_EXTERN_LEN + 4,
|
BTR_EXTERN_LEN + 4 + field_ref,
|
||||||
big_rec_vec->fields[i].len
|
big_rec_vec->fields[i].len
|
||||||
- extern_len,
|
- extern_len);
|
||||||
MLOG_4BYTES, &mtr);
|
|
||||||
|
|
||||||
if (prev_page_no == FIL_NULL) {
|
if (prev_page_no == FIL_NULL) {
|
||||||
ut_ad(blob_npages == 0);
|
ut_ad(blob_npages == 0);
|
||||||
mlog_write_ulint(field_ref
|
mtr.write<4,mtr_t::OPT>(
|
||||||
+ BTR_EXTERN_SPACE_ID,
|
*rec_block,
|
||||||
space_id, MLOG_4BYTES,
|
field_ref + BTR_EXTERN_SPACE_ID,
|
||||||
&mtr);
|
space_id);
|
||||||
|
|
||||||
mlog_write_ulint(field_ref
|
mtr.write<4>(*rec_block, field_ref
|
||||||
+ BTR_EXTERN_PAGE_NO,
|
+ BTR_EXTERN_PAGE_NO,
|
||||||
page_no, MLOG_4BYTES,
|
page_no);
|
||||||
&mtr);
|
|
||||||
|
|
||||||
mlog_write_ulint(field_ref
|
mtr.write<4>(*rec_block, field_ref
|
||||||
+ BTR_EXTERN_OFFSET,
|
+ BTR_EXTERN_OFFSET,
|
||||||
FIL_PAGE_DATA,
|
FIL_PAGE_DATA);
|
||||||
MLOG_4BYTES,
|
|
||||||
&mtr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
prev_page_no = page_no;
|
prev_page_no = page_no;
|
||||||
|
|
@ -8038,8 +8007,7 @@ btr_free_externally_stored_field(
|
||||||
page_zip_write_blob_ptr(), or NULL */
|
page_zip_write_blob_ptr(), or NULL */
|
||||||
const ulint* offsets, /*!< in: rec_get_offsets(rec, index),
|
const ulint* offsets, /*!< in: rec_get_offsets(rec, index),
|
||||||
or NULL */
|
or NULL */
|
||||||
page_zip_des_t* page_zip, /*!< in: compressed page corresponding
|
buf_block_t* block, /*!< in/out: page of field_ref */
|
||||||
to rec, or NULL if rec == NULL */
|
|
||||||
ulint i, /*!< in: field number of field_ref;
|
ulint i, /*!< in: field number of field_ref;
|
||||||
ignored if rec == NULL */
|
ignored if rec == NULL */
|
||||||
bool rollback, /*!< in: performing rollback? */
|
bool rollback, /*!< in: performing rollback? */
|
||||||
|
|
@ -8084,10 +8052,8 @@ btr_free_externally_stored_field(
|
||||||
const ulint ext_zip_size = index->table->space->zip_size();
|
const ulint ext_zip_size = index->table->space->zip_size();
|
||||||
const ulint rec_zip_size = rec ? ext_zip_size : 0;
|
const ulint rec_zip_size = rec ? ext_zip_size : 0;
|
||||||
|
|
||||||
if (rec == NULL) {
|
/* !rec holds in a call from purge when field_ref is in an undo page */
|
||||||
/* This is a call from row_purge_upd_exist_or_extern(). */
|
ut_ad(rec || !block->page.zip.data);
|
||||||
ut_ad(!page_zip);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
#ifdef UNIV_DEBUG
|
#ifdef UNIV_DEBUG
|
||||||
|
|
@ -8156,24 +8122,23 @@ btr_free_externally_stored_field(
|
||||||
|
|
||||||
btr_page_free(index, ext_block, &mtr, true);
|
btr_page_free(index, ext_block, &mtr, true);
|
||||||
|
|
||||||
if (page_zip != NULL) {
|
if (UNIV_LIKELY_NULL(block->page.zip.data)) {
|
||||||
mach_write_to_4(field_ref + BTR_EXTERN_PAGE_NO,
|
mach_write_to_4(field_ref + BTR_EXTERN_PAGE_NO,
|
||||||
next_page_no);
|
next_page_no);
|
||||||
mach_write_to_4(field_ref + BTR_EXTERN_LEN + 4,
|
memset(field_ref + BTR_EXTERN_LEN, 0, 4);
|
||||||
0);
|
page_zip_write_blob_ptr(&block->page.zip,
|
||||||
page_zip_write_blob_ptr(page_zip, rec, index,
|
rec, index,
|
||||||
offsets, i, &mtr);
|
offsets, i, &mtr);
|
||||||
} else {
|
} else {
|
||||||
mlog_write_ulint(field_ref
|
mtr.write<4>(*block,
|
||||||
+ BTR_EXTERN_PAGE_NO,
|
BTR_EXTERN_PAGE_NO + field_ref,
|
||||||
next_page_no,
|
next_page_no);
|
||||||
MLOG_4BYTES, &mtr);
|
mtr.write<4>(*block,
|
||||||
mlog_write_ulint(field_ref
|
BTR_EXTERN_LEN + 4 + field_ref,
|
||||||
+ BTR_EXTERN_LEN + 4, 0,
|
0U);
|
||||||
MLOG_4BYTES, &mtr);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ut_a(!page_zip);
|
ut_ad(!block->page.zip.data);
|
||||||
btr_check_blob_fil_page_type(space_id, page_no, page,
|
btr_check_blob_fil_page_type(space_id, page_no, page,
|
||||||
FALSE);
|
FALSE);
|
||||||
|
|
||||||
|
|
@ -8182,17 +8147,16 @@ btr_free_externally_stored_field(
|
||||||
+ BTR_BLOB_HDR_NEXT_PAGE_NO);
|
+ BTR_BLOB_HDR_NEXT_PAGE_NO);
|
||||||
btr_page_free(index, ext_block, &mtr, true);
|
btr_page_free(index, ext_block, &mtr, true);
|
||||||
|
|
||||||
mlog_write_ulint(field_ref + BTR_EXTERN_PAGE_NO,
|
mtr.write<4>(*block, BTR_EXTERN_PAGE_NO + field_ref,
|
||||||
next_page_no,
|
next_page_no);
|
||||||
MLOG_4BYTES, &mtr);
|
|
||||||
/* Zero out the BLOB length. If the server
|
/* Zero out the BLOB length. If the server
|
||||||
crashes during the execution of this function,
|
crashes during the execution of this function,
|
||||||
trx_rollback_all_recovered() could
|
trx_rollback_all_recovered() could
|
||||||
dereference the half-deleted BLOB, fetching a
|
dereference the half-deleted BLOB, fetching a
|
||||||
wrong prefix for the BLOB. */
|
wrong prefix for the BLOB. */
|
||||||
mlog_write_ulint(field_ref + BTR_EXTERN_LEN + 4,
|
mtr.write<4,mtr_t::OPT>(*block,
|
||||||
0,
|
BTR_EXTERN_LEN + 4 + field_ref,
|
||||||
MLOG_4BYTES, &mtr);
|
0U);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Commit mtr and release the BLOB block to save memory. */
|
/* Commit mtr and release the BLOB block to save memory. */
|
||||||
|
|
@ -8210,8 +8174,7 @@ btr_rec_free_externally_stored_fields(
|
||||||
tree MUST be X-latched */
|
tree MUST be X-latched */
|
||||||
rec_t* rec, /*!< in/out: record */
|
rec_t* rec, /*!< in/out: record */
|
||||||
const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
|
const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
|
||||||
page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
|
buf_block_t* block, /*!< in: index page of rec */
|
||||||
part will be updated, or NULL */
|
|
||||||
bool rollback,/*!< in: performing rollback? */
|
bool rollback,/*!< in: performing rollback? */
|
||||||
mtr_t* mtr) /*!< in: mini-transaction handle which contains
|
mtr_t* mtr) /*!< in: mini-transaction handle which contains
|
||||||
an X-latch to record page and to the index
|
an X-latch to record page and to the index
|
||||||
|
|
@ -8233,7 +8196,7 @@ btr_rec_free_externally_stored_fields(
|
||||||
if (rec_offs_nth_extern(offsets, i)) {
|
if (rec_offs_nth_extern(offsets, i)) {
|
||||||
btr_free_externally_stored_field(
|
btr_free_externally_stored_field(
|
||||||
index, btr_rec_get_field_ref(rec, offsets, i),
|
index, btr_rec_get_field_ref(rec, offsets, i),
|
||||||
rec, offsets, page_zip, i, rollback, mtr);
|
rec, offsets, block, i, rollback, mtr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -8248,8 +8211,7 @@ btr_rec_free_updated_extern_fields(
|
||||||
dict_index_t* index, /*!< in: index of rec; the index tree MUST be
|
dict_index_t* index, /*!< in: index of rec; the index tree MUST be
|
||||||
X-latched */
|
X-latched */
|
||||||
rec_t* rec, /*!< in/out: record */
|
rec_t* rec, /*!< in/out: record */
|
||||||
page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
|
buf_block_t* block, /*!< in: index page of rec */
|
||||||
part will be updated, or NULL */
|
|
||||||
const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
|
const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
|
||||||
const upd_t* update, /*!< in: update vector */
|
const upd_t* update, /*!< in: update vector */
|
||||||
bool rollback,/*!< in: performing rollback? */
|
bool rollback,/*!< in: performing rollback? */
|
||||||
|
|
@ -8277,7 +8239,7 @@ btr_rec_free_updated_extern_fields(
|
||||||
|
|
||||||
btr_free_externally_stored_field(
|
btr_free_externally_stored_field(
|
||||||
index, data + len - BTR_EXTERN_FIELD_REF_SIZE,
|
index, data + len - BTR_EXTERN_FIELD_REF_SIZE,
|
||||||
rec, offsets, page_zip,
|
rec, offsets, block,
|
||||||
ufield->field_no, rollback, mtr);
|
ufield->field_no, rollback, mtr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -71,25 +71,13 @@ buf_dblwr_page_inside(
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************//**
|
/** @return the TRX_SYS page */
|
||||||
Calls buf_page_get() on the TRX_SYS_PAGE and returns a pointer to the
|
inline buf_block_t *buf_dblwr_trx_sys_get(mtr_t *mtr)
|
||||||
doublewrite buffer within it.
|
|
||||||
@return pointer to the doublewrite buffer within the filespace header
|
|
||||||
page. */
|
|
||||||
UNIV_INLINE
|
|
||||||
byte*
|
|
||||||
buf_dblwr_get(
|
|
||||||
/*==========*/
|
|
||||||
mtr_t* mtr) /*!< in/out: MTR to hold the page latch */
|
|
||||||
{
|
{
|
||||||
buf_block_t* block;
|
buf_block_t *block= buf_page_get(page_id_t(TRX_SYS_SPACE, TRX_SYS_PAGE_NO),
|
||||||
|
0, RW_X_LATCH, mtr);
|
||||||
block = buf_page_get(page_id_t(TRX_SYS_SPACE, TRX_SYS_PAGE_NO),
|
buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
|
||||||
0, RW_X_LATCH, mtr);
|
return block;
|
||||||
|
|
||||||
buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
|
|
||||||
|
|
||||||
return(buf_block_get_frame(block) + TRX_SYS_DOUBLEWRITE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************//**
|
/********************************************************************//**
|
||||||
|
|
@ -106,12 +94,7 @@ buf_dblwr_sync_datafiles()
|
||||||
|
|
||||||
/****************************************************************//**
|
/****************************************************************//**
|
||||||
Creates or initialializes the doublewrite buffer at a database start. */
|
Creates or initialializes the doublewrite buffer at a database start. */
|
||||||
static
|
static void buf_dblwr_init(const byte *doublewrite)
|
||||||
void
|
|
||||||
buf_dblwr_init(
|
|
||||||
/*===========*/
|
|
||||||
byte* doublewrite) /*!< in: pointer to the doublewrite buf
|
|
||||||
header on trx sys page */
|
|
||||||
{
|
{
|
||||||
ulint buf_size;
|
ulint buf_size;
|
||||||
|
|
||||||
|
|
@ -164,7 +147,6 @@ buf_dblwr_create()
|
||||||
{
|
{
|
||||||
buf_block_t* block2;
|
buf_block_t* block2;
|
||||||
buf_block_t* new_block;
|
buf_block_t* new_block;
|
||||||
byte* doublewrite;
|
|
||||||
byte* fseg_header;
|
byte* fseg_header;
|
||||||
ulint page_no;
|
ulint page_no;
|
||||||
ulint prev_page_no;
|
ulint prev_page_no;
|
||||||
|
|
@ -180,14 +162,15 @@ buf_dblwr_create()
|
||||||
mtr.start();
|
mtr.start();
|
||||||
buf_dblwr_being_created = TRUE;
|
buf_dblwr_being_created = TRUE;
|
||||||
|
|
||||||
doublewrite = buf_dblwr_get(&mtr);
|
buf_block_t *trx_sys_block = buf_dblwr_trx_sys_get(&mtr);
|
||||||
|
|
||||||
if (mach_read_from_4(doublewrite + TRX_SYS_DOUBLEWRITE_MAGIC)
|
if (mach_read_from_4(TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_MAGIC
|
||||||
|
+ trx_sys_block->frame)
|
||||||
== TRX_SYS_DOUBLEWRITE_MAGIC_N) {
|
== TRX_SYS_DOUBLEWRITE_MAGIC_N) {
|
||||||
/* The doublewrite buffer has already been created:
|
/* The doublewrite buffer has already been created:
|
||||||
just read in some numbers */
|
just read in some numbers */
|
||||||
|
|
||||||
buf_dblwr_init(doublewrite);
|
buf_dblwr_init(TRX_SYS_DOUBLEWRITE + trx_sys_block->frame);
|
||||||
|
|
||||||
mtr.commit();
|
mtr.commit();
|
||||||
buf_dblwr_being_created = FALSE;
|
buf_dblwr_being_created = FALSE;
|
||||||
|
|
@ -229,7 +212,8 @@ buf_dblwr_create()
|
||||||
|
|
||||||
buf_block_dbg_add_level(block2, SYNC_NO_ORDER_CHECK);
|
buf_block_dbg_add_level(block2, SYNC_NO_ORDER_CHECK);
|
||||||
|
|
||||||
fseg_header = doublewrite + TRX_SYS_DOUBLEWRITE_FSEG;
|
fseg_header = TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_FSEG
|
||||||
|
+ trx_sys_block->frame;
|
||||||
prev_page_no = 0;
|
prev_page_no = 0;
|
||||||
|
|
||||||
for (i = 0; i < TRX_SYS_DOUBLEWRITE_BLOCKS * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE
|
for (i = 0; i < TRX_SYS_DOUBLEWRITE_BLOCKS * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE
|
||||||
|
|
@ -265,30 +249,38 @@ buf_dblwr_create()
|
||||||
recv_parse_or_apply_log_rec_body() will see a valid
|
recv_parse_or_apply_log_rec_body() will see a valid
|
||||||
page type. The flushes of new_block are actually
|
page type. The flushes of new_block are actually
|
||||||
unnecessary here. */
|
unnecessary here. */
|
||||||
ut_d(mlog_write_ulint(FIL_PAGE_TYPE + new_block->frame,
|
ut_d(mtr.write<2>(*new_block,
|
||||||
FIL_PAGE_TYPE_SYS, MLOG_2BYTES, &mtr));
|
FIL_PAGE_TYPE + new_block->frame,
|
||||||
|
FIL_PAGE_TYPE_SYS));
|
||||||
|
|
||||||
if (i == FSP_EXTENT_SIZE / 2) {
|
if (i == FSP_EXTENT_SIZE / 2) {
|
||||||
ut_a(page_no == FSP_EXTENT_SIZE);
|
ut_a(page_no == FSP_EXTENT_SIZE);
|
||||||
mlog_write_ulint(doublewrite
|
mtr.write<4>(*trx_sys_block,
|
||||||
+ TRX_SYS_DOUBLEWRITE_BLOCK1,
|
TRX_SYS_DOUBLEWRITE
|
||||||
page_no, MLOG_4BYTES, &mtr);
|
+ TRX_SYS_DOUBLEWRITE_BLOCK1
|
||||||
mlog_write_ulint(doublewrite
|
+ trx_sys_block->frame,
|
||||||
+ TRX_SYS_DOUBLEWRITE_REPEAT
|
page_no);
|
||||||
+ TRX_SYS_DOUBLEWRITE_BLOCK1,
|
mtr.write<4>(*trx_sys_block,
|
||||||
page_no, MLOG_4BYTES, &mtr);
|
TRX_SYS_DOUBLEWRITE
|
||||||
|
+ TRX_SYS_DOUBLEWRITE_REPEAT
|
||||||
|
+ TRX_SYS_DOUBLEWRITE_BLOCK1
|
||||||
|
+ trx_sys_block->frame,
|
||||||
|
page_no);
|
||||||
|
|
||||||
} else if (i == FSP_EXTENT_SIZE / 2
|
} else if (i == FSP_EXTENT_SIZE / 2
|
||||||
+ TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) {
|
+ TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) {
|
||||||
ut_a(page_no == 2 * FSP_EXTENT_SIZE);
|
ut_a(page_no == 2 * FSP_EXTENT_SIZE);
|
||||||
mlog_write_ulint(doublewrite
|
mtr.write<4>(*trx_sys_block,
|
||||||
+ TRX_SYS_DOUBLEWRITE_BLOCK2,
|
TRX_SYS_DOUBLEWRITE
|
||||||
page_no, MLOG_4BYTES, &mtr);
|
+ TRX_SYS_DOUBLEWRITE_BLOCK2
|
||||||
mlog_write_ulint(doublewrite
|
+ trx_sys_block->frame,
|
||||||
+ TRX_SYS_DOUBLEWRITE_REPEAT
|
page_no);
|
||||||
+ TRX_SYS_DOUBLEWRITE_BLOCK2,
|
mtr.write<4>(*trx_sys_block,
|
||||||
page_no, MLOG_4BYTES, &mtr);
|
TRX_SYS_DOUBLEWRITE
|
||||||
|
+ TRX_SYS_DOUBLEWRITE_REPEAT
|
||||||
|
+ TRX_SYS_DOUBLEWRITE_BLOCK2
|
||||||
|
+ trx_sys_block->frame,
|
||||||
|
page_no);
|
||||||
} else if (i > FSP_EXTENT_SIZE / 2) {
|
} else if (i > FSP_EXTENT_SIZE / 2) {
|
||||||
ut_a(page_no == prev_page_no + 1);
|
ut_a(page_no == prev_page_no + 1);
|
||||||
}
|
}
|
||||||
|
|
@ -303,29 +295,32 @@ buf_dblwr_create()
|
||||||
lock the fseg header too many times. Since
|
lock the fseg header too many times. Since
|
||||||
this code is not done while any other threads
|
this code is not done while any other threads
|
||||||
are active, restart the MTR occasionally. */
|
are active, restart the MTR occasionally. */
|
||||||
mtr_commit(&mtr);
|
mtr.commit();
|
||||||
mtr_start(&mtr);
|
mtr.start();
|
||||||
doublewrite = buf_dblwr_get(&mtr);
|
trx_sys_block = buf_dblwr_trx_sys_get(&mtr);
|
||||||
fseg_header = doublewrite
|
fseg_header = TRX_SYS_DOUBLEWRITE
|
||||||
+ TRX_SYS_DOUBLEWRITE_FSEG;
|
+ TRX_SYS_DOUBLEWRITE_FSEG
|
||||||
|
+ trx_sys_block->frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
prev_page_no = page_no;
|
prev_page_no = page_no;
|
||||||
}
|
}
|
||||||
|
|
||||||
mlog_write_ulint(doublewrite + TRX_SYS_DOUBLEWRITE_MAGIC,
|
mtr.write<4>(*trx_sys_block,
|
||||||
TRX_SYS_DOUBLEWRITE_MAGIC_N,
|
TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_MAGIC
|
||||||
MLOG_4BYTES, &mtr);
|
+ trx_sys_block->frame,
|
||||||
mlog_write_ulint(doublewrite + TRX_SYS_DOUBLEWRITE_MAGIC
|
TRX_SYS_DOUBLEWRITE_MAGIC_N);
|
||||||
+ TRX_SYS_DOUBLEWRITE_REPEAT,
|
mtr.write<4>(*trx_sys_block,
|
||||||
TRX_SYS_DOUBLEWRITE_MAGIC_N,
|
TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_MAGIC
|
||||||
MLOG_4BYTES, &mtr);
|
+ TRX_SYS_DOUBLEWRITE_REPEAT
|
||||||
|
+ trx_sys_block->frame,
|
||||||
|
TRX_SYS_DOUBLEWRITE_MAGIC_N);
|
||||||
|
|
||||||
mlog_write_ulint(doublewrite
|
mtr.write<4>(*trx_sys_block,
|
||||||
+ TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED,
|
TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED
|
||||||
TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N,
|
+ trx_sys_block->frame,
|
||||||
MLOG_4BYTES, &mtr);
|
TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N);
|
||||||
mtr_commit(&mtr);
|
mtr.commit();
|
||||||
|
|
||||||
/* Flush the modified pages to disk and make a checkpoint */
|
/* Flush the modified pages to disk and make a checkpoint */
|
||||||
log_make_checkpoint();
|
log_make_checkpoint();
|
||||||
|
|
|
||||||
|
|
@ -35,24 +35,13 @@ Created 4/18/1996 Heikki Tuuri
|
||||||
#include "log0recv.h"
|
#include "log0recv.h"
|
||||||
#include "os0file.h"
|
#include "os0file.h"
|
||||||
|
|
||||||
/**********************************************************************//**
|
/** @return the DICT_HDR block, x-latched */
|
||||||
Gets a pointer to the dictionary header and x-latches its page.
|
buf_block_t *dict_hdr_get(mtr_t* mtr)
|
||||||
@return pointer to the dictionary header, page x-latched */
|
|
||||||
dict_hdr_t*
|
|
||||||
dict_hdr_get(
|
|
||||||
/*=========*/
|
|
||||||
mtr_t* mtr) /*!< in: mtr */
|
|
||||||
{
|
{
|
||||||
buf_block_t* block;
|
buf_block_t *block= buf_page_get(page_id_t(DICT_HDR_SPACE, DICT_HDR_PAGE_NO),
|
||||||
dict_hdr_t* header;
|
0, RW_X_LATCH, mtr);
|
||||||
|
buf_block_dbg_add_level(block, SYNC_DICT_HEADER);
|
||||||
block = buf_page_get(page_id_t(DICT_HDR_SPACE, DICT_HDR_PAGE_NO),
|
return block;
|
||||||
0, RW_X_LATCH, mtr);
|
|
||||||
header = DICT_HDR + buf_block_get_frame(block);
|
|
||||||
|
|
||||||
buf_block_dbg_add_level(block, SYNC_DICT_HEADER);
|
|
||||||
|
|
||||||
return(header);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************//**
|
/**********************************************************************//**
|
||||||
|
|
@ -67,36 +56,41 @@ dict_hdr_get_new_id(
|
||||||
ulint* space_id) /*!< out: space id
|
ulint* space_id) /*!< out: space id
|
||||||
(not assigned if NULL) */
|
(not assigned if NULL) */
|
||||||
{
|
{
|
||||||
dict_hdr_t* dict_hdr;
|
|
||||||
ib_id_t id;
|
ib_id_t id;
|
||||||
mtr_t mtr;
|
mtr_t mtr;
|
||||||
|
|
||||||
mtr_start(&mtr);
|
mtr.start();
|
||||||
dict_hdr = dict_hdr_get(&mtr);
|
buf_block_t* dict_hdr = dict_hdr_get(&mtr);
|
||||||
|
|
||||||
if (table_id) {
|
if (table_id) {
|
||||||
id = mach_read_from_8(dict_hdr + DICT_HDR_TABLE_ID);
|
id = mach_read_from_8(DICT_HDR + DICT_HDR_TABLE_ID
|
||||||
|
+ dict_hdr->frame);
|
||||||
id++;
|
id++;
|
||||||
mlog_write_ull(dict_hdr + DICT_HDR_TABLE_ID, id, &mtr);
|
mtr.write<8>(*dict_hdr, DICT_HDR + DICT_HDR_TABLE_ID
|
||||||
|
+ dict_hdr->frame, id);
|
||||||
*table_id = id;
|
*table_id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index_id) {
|
if (index_id) {
|
||||||
id = mach_read_from_8(dict_hdr + DICT_HDR_INDEX_ID);
|
id = mach_read_from_8(DICT_HDR + DICT_HDR_INDEX_ID
|
||||||
|
+ dict_hdr->frame);
|
||||||
id++;
|
id++;
|
||||||
mlog_write_ull(dict_hdr + DICT_HDR_INDEX_ID, id, &mtr);
|
mtr.write<8>(*dict_hdr, DICT_HDR + DICT_HDR_INDEX_ID
|
||||||
|
+ dict_hdr->frame, id);
|
||||||
*index_id = id;
|
*index_id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (space_id) {
|
if (space_id) {
|
||||||
*space_id = mach_read_from_4(dict_hdr + DICT_HDR_MAX_SPACE_ID);
|
*space_id = mach_read_from_4(DICT_HDR + DICT_HDR_MAX_SPACE_ID
|
||||||
|
+ dict_hdr->frame);
|
||||||
if (fil_assign_new_space_id(space_id)) {
|
if (fil_assign_new_space_id(space_id)) {
|
||||||
mlog_write_ulint(dict_hdr + DICT_HDR_MAX_SPACE_ID,
|
mtr.write<4>(*dict_hdr,
|
||||||
*space_id, MLOG_4BYTES, &mtr);
|
DICT_HDR + DICT_HDR_MAX_SPACE_ID
|
||||||
|
+ dict_hdr->frame, *space_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mtr_commit(&mtr);
|
mtr.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************//**
|
/**********************************************************************//**
|
||||||
|
|
@ -106,7 +100,6 @@ void
|
||||||
dict_hdr_flush_row_id(void)
|
dict_hdr_flush_row_id(void)
|
||||||
/*=======================*/
|
/*=======================*/
|
||||||
{
|
{
|
||||||
dict_hdr_t* dict_hdr;
|
|
||||||
row_id_t id;
|
row_id_t id;
|
||||||
mtr_t mtr;
|
mtr_t mtr;
|
||||||
|
|
||||||
|
|
@ -114,13 +107,13 @@ dict_hdr_flush_row_id(void)
|
||||||
|
|
||||||
id = dict_sys.row_id;
|
id = dict_sys.row_id;
|
||||||
|
|
||||||
mtr_start(&mtr);
|
mtr.start();
|
||||||
|
|
||||||
dict_hdr = dict_hdr_get(&mtr);
|
buf_block_t* d = dict_hdr_get(&mtr);
|
||||||
|
|
||||||
mlog_write_ull(dict_hdr + DICT_HDR_ROW_ID, id, &mtr);
|
mtr.write<8>(*d, DICT_HDR + DICT_HDR_ROW_ID + d->frame, id);
|
||||||
|
|
||||||
mtr_commit(&mtr);
|
mtr.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************//**
|
/*****************************************************************//**
|
||||||
|
|
@ -134,7 +127,6 @@ dict_hdr_create(
|
||||||
mtr_t* mtr) /*!< in: mtr */
|
mtr_t* mtr) /*!< in: mtr */
|
||||||
{
|
{
|
||||||
buf_block_t* block;
|
buf_block_t* block;
|
||||||
dict_hdr_t* dict_header;
|
|
||||||
ulint root_page_no;
|
ulint root_page_no;
|
||||||
|
|
||||||
ut_ad(mtr);
|
ut_ad(mtr);
|
||||||
|
|
@ -147,24 +139,22 @@ dict_hdr_create(
|
||||||
|
|
||||||
ut_a(DICT_HDR_PAGE_NO == block->page.id.page_no());
|
ut_a(DICT_HDR_PAGE_NO == block->page.id.page_no());
|
||||||
|
|
||||||
dict_header = dict_hdr_get(mtr);
|
buf_block_t* d = dict_hdr_get(mtr);
|
||||||
|
|
||||||
/* Start counting row, table, index, and tree ids from
|
/* Start counting row, table, index, and tree ids from
|
||||||
DICT_HDR_FIRST_ID */
|
DICT_HDR_FIRST_ID */
|
||||||
mlog_write_ull(dict_header + DICT_HDR_ROW_ID,
|
mtr->write<8>(*d, DICT_HDR + DICT_HDR_ROW_ID + d->frame,
|
||||||
DICT_HDR_FIRST_ID, mtr);
|
DICT_HDR_FIRST_ID);
|
||||||
|
mtr->write<8>(*d, DICT_HDR + DICT_HDR_TABLE_ID + d->frame,
|
||||||
|
DICT_HDR_FIRST_ID);
|
||||||
|
mtr->write<8>(*d, DICT_HDR + DICT_HDR_INDEX_ID + d->frame,
|
||||||
|
DICT_HDR_FIRST_ID);
|
||||||
|
|
||||||
mlog_write_ull(dict_header + DICT_HDR_TABLE_ID,
|
ut_ad(!mach_read_from_4(DICT_HDR + DICT_HDR_MAX_SPACE_ID + d->frame));
|
||||||
DICT_HDR_FIRST_ID, mtr);
|
|
||||||
|
|
||||||
mlog_write_ull(dict_header + DICT_HDR_INDEX_ID,
|
|
||||||
DICT_HDR_FIRST_ID, mtr);
|
|
||||||
|
|
||||||
ut_ad(mach_read_from_4(dict_header + DICT_HDR_MAX_SPACE_ID) == 0);
|
|
||||||
|
|
||||||
/* Obsolete, but we must initialize it anyway. */
|
/* Obsolete, but we must initialize it anyway. */
|
||||||
mlog_write_ulint(dict_header + DICT_HDR_MIX_ID_LOW,
|
mtr->write<4>(*d, DICT_HDR + DICT_HDR_MIX_ID_LOW + d->frame,
|
||||||
DICT_HDR_FIRST_ID, MLOG_4BYTES, mtr);
|
DICT_HDR_FIRST_ID);
|
||||||
|
|
||||||
/* Create the B-tree roots for the clustered indexes of the basic
|
/* Create the B-tree roots for the clustered indexes of the basic
|
||||||
system tables */
|
system tables */
|
||||||
|
|
@ -178,8 +168,7 @@ dict_hdr_create(
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
mlog_write_ulint(dict_header + DICT_HDR_TABLES, root_page_no,
|
mtr->write<4>(*d, DICT_HDR + DICT_HDR_TABLES + d->frame, root_page_no);
|
||||||
MLOG_4BYTES, mtr);
|
|
||||||
/*--------------------------*/
|
/*--------------------------*/
|
||||||
root_page_no = btr_create(DICT_UNIQUE,
|
root_page_no = btr_create(DICT_UNIQUE,
|
||||||
fil_system.sys_space, DICT_TABLE_IDS_ID,
|
fil_system.sys_space, DICT_TABLE_IDS_ID,
|
||||||
|
|
@ -189,8 +178,8 @@ dict_hdr_create(
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
mlog_write_ulint(dict_header + DICT_HDR_TABLE_IDS, root_page_no,
|
mtr->write<4>(*d, DICT_HDR + DICT_HDR_TABLE_IDS + d->frame,
|
||||||
MLOG_4BYTES, mtr);
|
root_page_no);
|
||||||
/*--------------------------*/
|
/*--------------------------*/
|
||||||
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
|
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
|
||||||
fil_system.sys_space, DICT_COLUMNS_ID,
|
fil_system.sys_space, DICT_COLUMNS_ID,
|
||||||
|
|
@ -200,8 +189,8 @@ dict_hdr_create(
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
mlog_write_ulint(dict_header + DICT_HDR_COLUMNS, root_page_no,
|
mtr->write<4>(*d, DICT_HDR + DICT_HDR_COLUMNS + d->frame,
|
||||||
MLOG_4BYTES, mtr);
|
root_page_no);
|
||||||
/*--------------------------*/
|
/*--------------------------*/
|
||||||
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
|
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
|
||||||
fil_system.sys_space, DICT_INDEXES_ID,
|
fil_system.sys_space, DICT_INDEXES_ID,
|
||||||
|
|
@ -211,8 +200,8 @@ dict_hdr_create(
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
mlog_write_ulint(dict_header + DICT_HDR_INDEXES, root_page_no,
|
mtr->write<4>(*d, DICT_HDR + DICT_HDR_INDEXES + d->frame,
|
||||||
MLOG_4BYTES, mtr);
|
root_page_no);
|
||||||
/*--------------------------*/
|
/*--------------------------*/
|
||||||
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
|
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
|
||||||
fil_system.sys_space, DICT_FIELDS_ID,
|
fil_system.sys_space, DICT_FIELDS_ID,
|
||||||
|
|
@ -222,8 +211,7 @@ dict_hdr_create(
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
mlog_write_ulint(dict_header + DICT_HDR_FIELDS, root_page_no,
|
mtr->write<4>(*d, DICT_HDR + DICT_HDR_FIELDS + d->frame, root_page_no);
|
||||||
MLOG_4BYTES, mtr);
|
|
||||||
/*--------------------------*/
|
/*--------------------------*/
|
||||||
|
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
|
|
@ -239,7 +227,6 @@ dict_boot(void)
|
||||||
{
|
{
|
||||||
dict_table_t* table;
|
dict_table_t* table;
|
||||||
dict_index_t* index;
|
dict_index_t* index;
|
||||||
dict_hdr_t* dict_hdr;
|
|
||||||
mem_heap_t* heap;
|
mem_heap_t* heap;
|
||||||
mtr_t mtr;
|
mtr_t mtr;
|
||||||
|
|
||||||
|
|
@ -271,7 +258,7 @@ dict_boot(void)
|
||||||
mutex_enter(&dict_sys.mutex);
|
mutex_enter(&dict_sys.mutex);
|
||||||
|
|
||||||
/* Get the dictionary header */
|
/* Get the dictionary header */
|
||||||
dict_hdr = dict_hdr_get(&mtr);
|
const byte* dict_hdr = &dict_hdr_get(&mtr)->frame[DICT_HDR];
|
||||||
|
|
||||||
/* Because we only write new row ids to disk-based data structure
|
/* Because we only write new row ids to disk-based data structure
|
||||||
(dictionary header) when it is divisible by
|
(dictionary header) when it is divisible by
|
||||||
|
|
|
||||||
|
|
@ -373,16 +373,18 @@ dict_build_table_def_step(
|
||||||
mtr.start();
|
mtr.start();
|
||||||
undo->table_id = trx->table_id;
|
undo->table_id = trx->table_id;
|
||||||
undo->dict_operation = TRUE;
|
undo->dict_operation = TRUE;
|
||||||
page_t* page = trx_undo_page_get(
|
buf_block_t* block = trx_undo_page_get(
|
||||||
page_id_t(trx->rsegs.m_redo.rseg->space->id,
|
page_id_t(trx->rsegs.m_redo.rseg->space->id,
|
||||||
undo->hdr_page_no),
|
undo->hdr_page_no),
|
||||||
&mtr);
|
&mtr);
|
||||||
mlog_write_ulint(page + undo->hdr_offset
|
mtr.write<1,mtr_t::OPT>(
|
||||||
+ TRX_UNDO_DICT_TRANS,
|
*block,
|
||||||
TRUE, MLOG_1BYTE, &mtr);
|
block->frame + undo->hdr_offset
|
||||||
mlog_write_ull(page + undo->hdr_offset
|
+ TRX_UNDO_DICT_TRANS, 1U);
|
||||||
+ TRX_UNDO_TABLE_ID,
|
mtr.write<8,mtr_t::OPT>(
|
||||||
trx->table_id, &mtr);
|
*block,
|
||||||
|
block->frame + undo->hdr_offset
|
||||||
|
+ TRX_UNDO_TABLE_ID, trx->table_id);
|
||||||
mtr.commit();
|
mtr.commit();
|
||||||
log_write_up_to(mtr.commit_lsn(), true);
|
log_write_up_to(mtr.commit_lsn(), true);
|
||||||
}
|
}
|
||||||
|
|
@ -851,14 +853,13 @@ dict_create_index_tree_step(
|
||||||
err = DB_OUT_OF_FILE_SPACE; );
|
err = DB_OUT_OF_FILE_SPACE; );
|
||||||
}
|
}
|
||||||
|
|
||||||
ulint len;
|
ulint len;
|
||||||
byte* data = rec_get_nth_field_old(btr_pcur_get_rec(&pcur),
|
byte* data = rec_get_nth_field_old(btr_pcur_get_rec(&pcur),
|
||||||
DICT_FLD__SYS_INDEXES__PAGE_NO,
|
DICT_FLD__SYS_INDEXES__PAGE_NO,
|
||||||
&len);
|
&len);
|
||||||
ut_ad(len == 4);
|
ut_ad(len == 4);
|
||||||
if (mach_read_from_4(data) != node->page_no) {
|
mtr.write<4,mtr_t::OPT>(*btr_pcur_get_block(&pcur), data,
|
||||||
mlog_write_ulint(data, node->page_no, MLOG_4BYTES, &mtr);
|
node->page_no);
|
||||||
}
|
|
||||||
|
|
||||||
mtr.commit();
|
mtr.commit();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4013,7 +4013,7 @@ dict_set_corrupted(
|
||||||
if (len != 4) {
|
if (len != 4) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
mlog_write_ulint(field, index->type, MLOG_4BYTES, &mtr);
|
mtr.write<4>(*btr_cur_get_block(&cursor), field, index->type);
|
||||||
status = "Flagged";
|
status = "Flagged";
|
||||||
} else {
|
} else {
|
||||||
fail:
|
fail:
|
||||||
|
|
@ -4113,11 +4113,8 @@ dict_index_set_merge_threshold(
|
||||||
DICT_FLD__SYS_INDEXES__MERGE_THRESHOLD, &len);
|
DICT_FLD__SYS_INDEXES__MERGE_THRESHOLD, &len);
|
||||||
|
|
||||||
ut_ad(len == 4);
|
ut_ad(len == 4);
|
||||||
|
mtr.write<4,mtr_t::OPT>(*btr_cur_get_block(&cursor), field,
|
||||||
if (len == 4) {
|
merge_threshold);
|
||||||
mlog_write_ulint(field, merge_threshold,
|
|
||||||
MLOG_4BYTES, &mtr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mtr_commit(&mtr);
|
mtr_commit(&mtr);
|
||||||
|
|
|
||||||
|
|
@ -1481,7 +1481,8 @@ void dict_check_tablespaces_and_store_max_id()
|
||||||
/* Initialize the max space_id from sys header */
|
/* Initialize the max space_id from sys header */
|
||||||
mtr.start();
|
mtr.start();
|
||||||
ulint max_space_id = mach_read_from_4(DICT_HDR_MAX_SPACE_ID
|
ulint max_space_id = mach_read_from_4(DICT_HDR_MAX_SPACE_ID
|
||||||
+ dict_hdr_get(&mtr));
|
+ DICT_HDR
|
||||||
|
+ dict_hdr_get(&mtr)->frame);
|
||||||
mtr.commit();
|
mtr.commit();
|
||||||
|
|
||||||
fil_set_max_space_id_if_bigger(max_space_id);
|
fil_set_max_space_id_if_bigger(max_space_id);
|
||||||
|
|
|
||||||
|
|
@ -2035,8 +2035,9 @@ fil_crypt_rotate_page(
|
||||||
modified = true;
|
modified = true;
|
||||||
|
|
||||||
/* force rotation by dummy updating page */
|
/* force rotation by dummy updating page */
|
||||||
mlog_write_ulint(frame + FIL_PAGE_SPACE_ID,
|
mtr.write<1,mtr_t::FORCED>(*block,
|
||||||
space_id, MLOG_4BYTES, &mtr);
|
&frame[FIL_PAGE_SPACE_ID],
|
||||||
|
frame[FIL_PAGE_SPACE_ID]);
|
||||||
|
|
||||||
/* statistics */
|
/* statistics */
|
||||||
state->crypt_stat.pages_modified++;
|
state->crypt_stat.pages_modified++;
|
||||||
|
|
|
||||||
|
|
@ -3899,8 +3899,8 @@ void fsp_flags_try_adjust(fil_space_t* space, ulint flags)
|
||||||
<< " to " << ib::hex(flags);
|
<< " to " << ib::hex(flags);
|
||||||
}
|
}
|
||||||
mtr.set_named_space(space);
|
mtr.set_named_space(space);
|
||||||
mlog_write_ulint(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS
|
mtr.write<4>(*b, FSP_HEADER_OFFSET + FSP_SPACE_FLAGS
|
||||||
+ b->frame, flags, MLOG_4BYTES, &mtr);
|
+ b->frame, flags);
|
||||||
}
|
}
|
||||||
func_exit:
|
func_exit:
|
||||||
mtr.commit();
|
mtr.commit();
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,6 +1,7 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||||
|
Copyright (c) 2019, MariaDB Corporation.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
the terms of the GNU General Public License as published by the Free Software
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
|
@ -27,434 +28,300 @@ Created 11/28/1995 Heikki Tuuri
|
||||||
#include "buf0buf.h"
|
#include "buf0buf.h"
|
||||||
#include "page0page.h"
|
#include "page0page.h"
|
||||||
|
|
||||||
/********************************************************************//**
|
/** Add a node to an empty list. */
|
||||||
Adds a node to an empty list. */
|
static void flst_add_to_empty(buf_block_t *base, uint16_t boffset,
|
||||||
static
|
buf_block_t *add, uint16_t aoffset, mtr_t *mtr)
|
||||||
void
|
|
||||||
flst_add_to_empty(
|
|
||||||
/*==============*/
|
|
||||||
flst_base_node_t* base, /*!< in: pointer to base node of
|
|
||||||
empty list */
|
|
||||||
flst_node_t* node, /*!< in: node to add */
|
|
||||||
mtr_t* mtr) /*!< in: mini-transaction handle */
|
|
||||||
{
|
{
|
||||||
ulint space;
|
ut_ad(base != add || boffset != aoffset);
|
||||||
fil_addr_t node_addr;
|
ut_ad(boffset < base->physical_size());
|
||||||
|
ut_ad(aoffset < add->physical_size());
|
||||||
|
ut_ad(mtr_memo_contains_page_flagged(mtr, base->frame,
|
||||||
|
MTR_MEMO_PAGE_X_FIX |
|
||||||
|
MTR_MEMO_PAGE_SX_FIX));
|
||||||
|
ut_ad(mtr_memo_contains_page_flagged(mtr, add->frame,
|
||||||
|
MTR_MEMO_PAGE_X_FIX |
|
||||||
|
MTR_MEMO_PAGE_SX_FIX));
|
||||||
|
fil_addr_t addr= { add->page.id.page_no(), aoffset };
|
||||||
|
|
||||||
ut_ad(mtr && base && node);
|
/* Update first and last fields of base node */
|
||||||
ut_ad(base != node);
|
flst_write_addr(*base, base->frame + boffset + FLST_FIRST, addr, mtr);
|
||||||
ut_ad(mtr_memo_contains_page_flagged(mtr, base,
|
/* MDEV-12353 TODO: use MEMMOVE record */
|
||||||
MTR_MEMO_PAGE_X_FIX
|
flst_write_addr(*base, base->frame + boffset + FLST_LAST, addr, mtr);
|
||||||
| MTR_MEMO_PAGE_SX_FIX));
|
|
||||||
ut_ad(mtr_memo_contains_page_flagged(mtr, node,
|
|
||||||
MTR_MEMO_PAGE_X_FIX
|
|
||||||
| MTR_MEMO_PAGE_SX_FIX));
|
|
||||||
ut_a(!flst_get_len(base));
|
|
||||||
|
|
||||||
buf_ptr_get_fsp_addr(node, &space, &node_addr);
|
/* Set prev and next fields of node to add */
|
||||||
|
flst_zero_addr(*add, add->frame + aoffset + FLST_PREV, mtr);
|
||||||
|
flst_zero_addr(*add, add->frame + aoffset + FLST_NEXT, mtr);
|
||||||
|
|
||||||
/* Update first and last fields of base node */
|
/* Update len of base node */
|
||||||
flst_write_addr(base + FLST_FIRST, node_addr, mtr);
|
ut_ad(!mach_read_from_4(base->frame + boffset + FLST_LEN));
|
||||||
flst_write_addr(base + FLST_LAST, node_addr, mtr);
|
mtr->write<1>(*base, base->frame + boffset + (FLST_LEN + 3), 1U);
|
||||||
|
|
||||||
/* Set prev and next fields of node to add */
|
|
||||||
flst_zero_addr(node + FLST_PREV, mtr);
|
|
||||||
flst_zero_addr(node + FLST_NEXT, mtr);
|
|
||||||
|
|
||||||
/* Update len of base node */
|
|
||||||
mlog_write_ulint(base + FLST_LEN, 1, MLOG_4BYTES, mtr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************//**
|
/** Insert a node after another one.
|
||||||
Inserts a node after another in a list. */
|
@param[in,out] base base node block
|
||||||
static
|
@param[in] boffset byte offset of the base node
|
||||||
void
|
@param[in,out] cur insert position block
|
||||||
flst_insert_after(
|
@param[in] coffset byte offset of the insert position
|
||||||
/*==============*/
|
@param[in,out] add block to be added
|
||||||
flst_base_node_t* base, /*!< in: pointer to base node of list */
|
@param[in] aoffset byte offset of the block to be added
|
||||||
flst_node_t* node1, /*!< in: node to insert after */
|
@param[in,outr] mtr mini-transaction */
|
||||||
flst_node_t* node2, /*!< in: node to add */
|
static void flst_insert_after(buf_block_t *base, uint16_t boffset,
|
||||||
mtr_t* mtr); /*!< in: mini-transaction handle */
|
buf_block_t *cur, uint16_t coffset,
|
||||||
/********************************************************************//**
|
buf_block_t *add, uint16_t aoffset, mtr_t *mtr)
|
||||||
Inserts a node before another in a list. */
|
|
||||||
static
|
|
||||||
void
|
|
||||||
flst_insert_before(
|
|
||||||
/*===============*/
|
|
||||||
flst_base_node_t* base, /*!< in: pointer to base node of list */
|
|
||||||
flst_node_t* node2, /*!< in: node to insert */
|
|
||||||
flst_node_t* node3, /*!< in: node to insert before */
|
|
||||||
mtr_t* mtr); /*!< in: mini-transaction handle */
|
|
||||||
|
|
||||||
/********************************************************************//**
|
|
||||||
Adds a node as the last node in a list. */
|
|
||||||
void
|
|
||||||
flst_add_last(
|
|
||||||
/*==========*/
|
|
||||||
flst_base_node_t* base, /*!< in: pointer to base node of list */
|
|
||||||
flst_node_t* node, /*!< in: node to add */
|
|
||||||
mtr_t* mtr) /*!< in: mini-transaction handle */
|
|
||||||
{
|
{
|
||||||
ulint space;
|
ut_ad(base != cur || boffset != coffset);
|
||||||
fil_addr_t node_addr;
|
ut_ad(base != add || boffset != aoffset);
|
||||||
ulint len;
|
ut_ad(cur != add || coffset != aoffset);
|
||||||
fil_addr_t last_addr;
|
ut_ad(boffset < base->physical_size());
|
||||||
|
ut_ad(coffset < cur->physical_size());
|
||||||
|
ut_ad(aoffset < add->physical_size());
|
||||||
|
ut_ad(mtr_memo_contains_page_flagged(mtr, base->frame,
|
||||||
|
MTR_MEMO_PAGE_X_FIX |
|
||||||
|
MTR_MEMO_PAGE_SX_FIX));
|
||||||
|
ut_ad(mtr_memo_contains_page_flagged(mtr, cur->frame,
|
||||||
|
MTR_MEMO_PAGE_X_FIX |
|
||||||
|
MTR_MEMO_PAGE_SX_FIX));
|
||||||
|
ut_ad(mtr_memo_contains_page_flagged(mtr, add->frame,
|
||||||
|
MTR_MEMO_PAGE_X_FIX |
|
||||||
|
MTR_MEMO_PAGE_SX_FIX));
|
||||||
|
|
||||||
ut_ad(mtr && base && node);
|
fil_addr_t cur_addr= { cur->page.id.page_no(), coffset };
|
||||||
ut_ad(base != node);
|
fil_addr_t add_addr= { add->page.id.page_no(), aoffset };
|
||||||
ut_ad(mtr_memo_contains_page_flagged(mtr, base,
|
fil_addr_t next_addr= flst_get_next_addr(cur->frame + coffset);
|
||||||
MTR_MEMO_PAGE_X_FIX
|
|
||||||
| MTR_MEMO_PAGE_SX_FIX));
|
|
||||||
ut_ad(mtr_memo_contains_page_flagged(mtr, node,
|
|
||||||
MTR_MEMO_PAGE_X_FIX
|
|
||||||
| MTR_MEMO_PAGE_SX_FIX));
|
|
||||||
len = flst_get_len(base);
|
|
||||||
last_addr = flst_get_last(base);
|
|
||||||
|
|
||||||
buf_ptr_get_fsp_addr(node, &space, &node_addr);
|
flst_write_addr(*add, add->frame + aoffset + FLST_PREV, cur_addr, mtr);
|
||||||
|
flst_write_addr(*add, add->frame + aoffset + FLST_NEXT, next_addr, mtr);
|
||||||
|
|
||||||
/* If the list is not empty, call flst_insert_after */
|
if (fil_addr_is_null(next_addr))
|
||||||
if (len != 0) {
|
flst_write_addr(*base, base->frame + boffset + FLST_LAST, add_addr, mtr);
|
||||||
flst_node_t* last_node;
|
else
|
||||||
|
{
|
||||||
|
buf_block_t *block;
|
||||||
|
flst_node_t *next= fut_get_ptr(add->page.id.space(), add->zip_size(),
|
||||||
|
next_addr, RW_SX_LATCH, mtr, &block);
|
||||||
|
flst_write_addr(*block, next + FLST_PREV, add_addr, mtr);
|
||||||
|
}
|
||||||
|
|
||||||
if (last_addr.page == node_addr.page) {
|
flst_write_addr(*cur, cur->frame + coffset + FLST_NEXT, add_addr, mtr);
|
||||||
last_node = page_align(node) + last_addr.boffset;
|
|
||||||
} else {
|
|
||||||
fil_space_t* s = fil_space_acquire_silent(space);
|
|
||||||
ulint zip_size = s ? s->zip_size() : 0;
|
|
||||||
if (s) s->release();
|
|
||||||
|
|
||||||
last_node = fut_get_ptr(space, zip_size, last_addr,
|
byte *len= &base->frame[boffset + FLST_LEN];
|
||||||
RW_SX_LATCH, mtr);
|
mtr->write<4>(*base, len, mach_read_from_4(len) + 1);
|
||||||
}
|
|
||||||
|
|
||||||
flst_insert_after(base, last_node, node, mtr);
|
|
||||||
} else {
|
|
||||||
/* else call flst_add_to_empty */
|
|
||||||
flst_add_to_empty(base, node, mtr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************//**
|
/** Insert a node before another one.
|
||||||
Adds a node as the first node in a list. */
|
@param[in,out] base base node block
|
||||||
void
|
@param[in] boffset byte offset of the base node
|
||||||
flst_add_first(
|
@param[in,out] cur insert position block
|
||||||
/*===========*/
|
@param[in] coffset byte offset of the insert position
|
||||||
flst_base_node_t* base, /*!< in: pointer to base node of list */
|
@param[in,out] add block to be added
|
||||||
flst_node_t* node, /*!< in: node to add */
|
@param[in] aoffset byte offset of the block to be added
|
||||||
mtr_t* mtr) /*!< in: mini-transaction handle */
|
@param[in,outr] mtr mini-transaction */
|
||||||
|
static void flst_insert_before(buf_block_t *base, uint16_t boffset,
|
||||||
|
buf_block_t *cur, uint16_t coffset,
|
||||||
|
buf_block_t *add, uint16_t aoffset, mtr_t *mtr)
|
||||||
{
|
{
|
||||||
ulint space;
|
ut_ad(base != cur || boffset != coffset);
|
||||||
fil_addr_t node_addr;
|
ut_ad(base != add || boffset != aoffset);
|
||||||
ulint len;
|
ut_ad(cur != add || coffset != aoffset);
|
||||||
fil_addr_t first_addr;
|
ut_ad(boffset < base->physical_size());
|
||||||
flst_node_t* first_node;
|
ut_ad(coffset < cur->physical_size());
|
||||||
|
ut_ad(aoffset < add->physical_size());
|
||||||
|
ut_ad(mtr_memo_contains_page_flagged(mtr, base->frame,
|
||||||
|
MTR_MEMO_PAGE_X_FIX |
|
||||||
|
MTR_MEMO_PAGE_SX_FIX));
|
||||||
|
ut_ad(mtr_memo_contains_page_flagged(mtr, cur->frame,
|
||||||
|
MTR_MEMO_PAGE_X_FIX |
|
||||||
|
MTR_MEMO_PAGE_SX_FIX));
|
||||||
|
ut_ad(mtr_memo_contains_page_flagged(mtr, add->frame,
|
||||||
|
MTR_MEMO_PAGE_X_FIX |
|
||||||
|
MTR_MEMO_PAGE_SX_FIX));
|
||||||
|
|
||||||
ut_ad(mtr && base && node);
|
fil_addr_t cur_addr= { cur->page.id.page_no(), coffset };
|
||||||
ut_ad(base != node);
|
fil_addr_t add_addr= { add->page.id.page_no(), aoffset };
|
||||||
ut_ad(mtr_memo_contains_page_flagged(mtr, base,
|
fil_addr_t prev_addr= flst_get_prev_addr(cur->frame + coffset);
|
||||||
MTR_MEMO_PAGE_X_FIX
|
|
||||||
| MTR_MEMO_PAGE_SX_FIX));
|
|
||||||
ut_ad(mtr_memo_contains_page_flagged(mtr, node,
|
|
||||||
MTR_MEMO_PAGE_X_FIX
|
|
||||||
| MTR_MEMO_PAGE_SX_FIX));
|
|
||||||
len = flst_get_len(base);
|
|
||||||
first_addr = flst_get_first(base);
|
|
||||||
|
|
||||||
buf_ptr_get_fsp_addr(node, &space, &node_addr);
|
flst_write_addr(*add, add->frame + aoffset + FLST_PREV, prev_addr, mtr);
|
||||||
|
flst_write_addr(*add, add->frame + aoffset + FLST_NEXT, cur_addr, mtr);
|
||||||
|
|
||||||
/* If the list is not empty, call flst_insert_before */
|
if (fil_addr_is_null(prev_addr))
|
||||||
if (len != 0) {
|
flst_write_addr(*base, base->frame + boffset + FLST_FIRST, add_addr, mtr);
|
||||||
if (first_addr.page == node_addr.page) {
|
else
|
||||||
first_node = page_align(node) + first_addr.boffset;
|
{
|
||||||
} else {
|
buf_block_t *block;
|
||||||
fil_space_t* s = fil_space_acquire_silent(space);
|
flst_node_t *prev= fut_get_ptr(add->page.id.space(), add->zip_size(),
|
||||||
ulint zip_size = s ? s->zip_size() : 0;
|
prev_addr, RW_SX_LATCH, mtr, &block);
|
||||||
if (s) s->release();
|
flst_write_addr(*block, prev + FLST_NEXT, add_addr, mtr);
|
||||||
|
}
|
||||||
|
|
||||||
first_node = fut_get_ptr(space, zip_size, first_addr,
|
flst_write_addr(*cur, cur->frame + coffset + FLST_PREV, add_addr, mtr);
|
||||||
RW_SX_LATCH, mtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
flst_insert_before(base, node, first_node, mtr);
|
byte *len= &base->frame[boffset + FLST_LEN];
|
||||||
} else {
|
mtr->write<4>(*base, len, mach_read_from_4(len) + 1);
|
||||||
/* else call flst_add_to_empty */
|
|
||||||
flst_add_to_empty(base, node, mtr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************//**
|
/** Append a file list node to a list.
|
||||||
Inserts a node after another in a list. */
|
@param[in,out] base base node block
|
||||||
static
|
@param[in] boffset byte offset of the base node
|
||||||
void
|
@param[in,out] add block to be added
|
||||||
flst_insert_after(
|
@param[in] aoffset byte offset of the node to be added
|
||||||
/*==============*/
|
@param[in,outr] mtr mini-transaction */
|
||||||
flst_base_node_t* base, /*!< in: pointer to base node of list */
|
void flst_add_last(buf_block_t *base, uint16_t boffset,
|
||||||
flst_node_t* node1, /*!< in: node to insert after */
|
buf_block_t *add, uint16_t aoffset, mtr_t *mtr)
|
||||||
flst_node_t* node2, /*!< in: node to add */
|
|
||||||
mtr_t* mtr) /*!< in: mini-transaction handle */
|
|
||||||
{
|
{
|
||||||
ulint space;
|
ut_ad(base != add || boffset != aoffset);
|
||||||
fil_addr_t node1_addr;
|
ut_ad(boffset < base->physical_size());
|
||||||
fil_addr_t node2_addr;
|
ut_ad(aoffset < add->physical_size());
|
||||||
flst_node_t* node3;
|
ut_ad(mtr_memo_contains_page_flagged(mtr, base->frame,
|
||||||
fil_addr_t node3_addr;
|
MTR_MEMO_PAGE_X_FIX |
|
||||||
ulint len;
|
MTR_MEMO_PAGE_SX_FIX));
|
||||||
|
ut_ad(mtr_memo_contains_page_flagged(mtr, add->frame,
|
||||||
|
MTR_MEMO_PAGE_X_FIX |
|
||||||
|
MTR_MEMO_PAGE_SX_FIX));
|
||||||
|
|
||||||
ut_ad(mtr && node1 && node2 && base);
|
if (!flst_get_len(base->frame + boffset))
|
||||||
ut_ad(base != node1);
|
flst_add_to_empty(base, boffset, add, aoffset, mtr);
|
||||||
ut_ad(base != node2);
|
else
|
||||||
ut_ad(node2 != node1);
|
{
|
||||||
ut_ad(mtr_memo_contains_page_flagged(mtr, base,
|
fil_addr_t addr= flst_get_last(base->frame + boffset);
|
||||||
MTR_MEMO_PAGE_X_FIX
|
buf_block_t *cur= add;
|
||||||
| MTR_MEMO_PAGE_SX_FIX));
|
const flst_node_t *c= addr.page == add->page.id.page_no()
|
||||||
ut_ad(mtr_memo_contains_page_flagged(mtr, node1,
|
? add->frame + addr.boffset
|
||||||
MTR_MEMO_PAGE_X_FIX
|
: fut_get_ptr(add->page.id.space(), add->zip_size(), addr,
|
||||||
| MTR_MEMO_PAGE_SX_FIX));
|
RW_SX_LATCH, mtr, &cur);
|
||||||
ut_ad(mtr_memo_contains_page_flagged(mtr, node2,
|
flst_insert_after(base, boffset, cur,
|
||||||
MTR_MEMO_PAGE_X_FIX
|
static_cast<uint16_t>(c - cur->frame),
|
||||||
| MTR_MEMO_PAGE_SX_FIX));
|
add, aoffset, mtr);
|
||||||
|
}
|
||||||
buf_ptr_get_fsp_addr(node1, &space, &node1_addr);
|
|
||||||
buf_ptr_get_fsp_addr(node2, &space, &node2_addr);
|
|
||||||
|
|
||||||
node3_addr = flst_get_next_addr(node1);
|
|
||||||
|
|
||||||
/* Set prev and next fields of node2 */
|
|
||||||
flst_write_addr(node2 + FLST_PREV, node1_addr, mtr);
|
|
||||||
flst_write_addr(node2 + FLST_NEXT, node3_addr, mtr);
|
|
||||||
|
|
||||||
if (!fil_addr_is_null(node3_addr)) {
|
|
||||||
/* Update prev field of node3 */
|
|
||||||
fil_space_t* s = fil_space_acquire_silent(space);
|
|
||||||
ulint zip_size = s ? s->zip_size() : 0;
|
|
||||||
if (s) s->release();
|
|
||||||
|
|
||||||
node3 = fut_get_ptr(space, zip_size,
|
|
||||||
node3_addr, RW_SX_LATCH, mtr);
|
|
||||||
flst_write_addr(node3 + FLST_PREV, node2_addr, mtr);
|
|
||||||
} else {
|
|
||||||
/* node1 was last in list: update last field in base */
|
|
||||||
flst_write_addr(base + FLST_LAST, node2_addr, mtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set next field of node1 */
|
|
||||||
flst_write_addr(node1 + FLST_NEXT, node2_addr, mtr);
|
|
||||||
|
|
||||||
/* Update len of base node */
|
|
||||||
len = flst_get_len(base);
|
|
||||||
mlog_write_ulint(base + FLST_LEN, len + 1, MLOG_4BYTES, mtr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************//**
|
/** Prepend a file list node to a list.
|
||||||
Inserts a node before another in a list. */
|
@param[in,out] base base node block
|
||||||
static
|
@param[in] boffset byte offset of the base node
|
||||||
void
|
@param[in,out] add block to be added
|
||||||
flst_insert_before(
|
@param[in] aoffset byte offset of the node to be added
|
||||||
/*===============*/
|
@param[in,outr] mtr mini-transaction */
|
||||||
flst_base_node_t* base, /*!< in: pointer to base node of list */
|
void flst_add_first(buf_block_t *base, uint16_t boffset,
|
||||||
flst_node_t* node2, /*!< in: node to insert */
|
buf_block_t *add, uint16_t aoffset, mtr_t *mtr)
|
||||||
flst_node_t* node3, /*!< in: node to insert before */
|
|
||||||
mtr_t* mtr) /*!< in: mini-transaction handle */
|
|
||||||
{
|
{
|
||||||
ulint space;
|
ut_ad(base != add || boffset != aoffset);
|
||||||
flst_node_t* node1;
|
ut_ad(boffset < base->physical_size());
|
||||||
fil_addr_t node1_addr;
|
ut_ad(aoffset < add->physical_size());
|
||||||
fil_addr_t node2_addr;
|
ut_ad(mtr_memo_contains_page_flagged(mtr, base->frame,
|
||||||
fil_addr_t node3_addr;
|
MTR_MEMO_PAGE_X_FIX |
|
||||||
ulint len;
|
MTR_MEMO_PAGE_SX_FIX));
|
||||||
|
ut_ad(mtr_memo_contains_page_flagged(mtr, add->frame,
|
||||||
|
MTR_MEMO_PAGE_X_FIX |
|
||||||
|
MTR_MEMO_PAGE_SX_FIX));
|
||||||
|
|
||||||
ut_ad(mtr && node2 && node3 && base);
|
if (!flst_get_len(base->frame + boffset))
|
||||||
ut_ad(base != node2);
|
flst_add_to_empty(base, boffset, add, aoffset, mtr);
|
||||||
ut_ad(base != node3);
|
else
|
||||||
ut_ad(node2 != node3);
|
{
|
||||||
ut_ad(mtr_memo_contains_page_flagged(mtr, base,
|
fil_addr_t addr= flst_get_first(base->frame + boffset);
|
||||||
MTR_MEMO_PAGE_X_FIX
|
buf_block_t *cur= add;
|
||||||
| MTR_MEMO_PAGE_SX_FIX));
|
const flst_node_t *c= addr.page == add->page.id.page_no()
|
||||||
ut_ad(mtr_memo_contains_page_flagged(mtr, node2,
|
? add->frame + addr.boffset
|
||||||
MTR_MEMO_PAGE_X_FIX
|
: fut_get_ptr(add->page.id.space(), add->zip_size(), addr,
|
||||||
| MTR_MEMO_PAGE_SX_FIX));
|
RW_SX_LATCH, mtr, &cur);
|
||||||
ut_ad(mtr_memo_contains_page_flagged(mtr, node3,
|
flst_insert_before(base, boffset, cur,
|
||||||
MTR_MEMO_PAGE_X_FIX
|
static_cast<uint16_t>(c - cur->frame),
|
||||||
| MTR_MEMO_PAGE_SX_FIX));
|
add, aoffset, mtr);
|
||||||
|
}
|
||||||
buf_ptr_get_fsp_addr(node2, &space, &node2_addr);
|
|
||||||
buf_ptr_get_fsp_addr(node3, &space, &node3_addr);
|
|
||||||
|
|
||||||
node1_addr = flst_get_prev_addr(node3);
|
|
||||||
|
|
||||||
/* Set prev and next fields of node2 */
|
|
||||||
flst_write_addr(node2 + FLST_PREV, node1_addr, mtr);
|
|
||||||
flst_write_addr(node2 + FLST_NEXT, node3_addr, mtr);
|
|
||||||
|
|
||||||
if (!fil_addr_is_null(node1_addr)) {
|
|
||||||
fil_space_t* s = fil_space_acquire_silent(space);
|
|
||||||
ulint zip_size = s ? s->zip_size() : 0;
|
|
||||||
if (s) s->release();
|
|
||||||
|
|
||||||
/* Update next field of node1 */
|
|
||||||
node1 = fut_get_ptr(space, zip_size, node1_addr,
|
|
||||||
RW_SX_LATCH, mtr);
|
|
||||||
flst_write_addr(node1 + FLST_NEXT, node2_addr, mtr);
|
|
||||||
} else {
|
|
||||||
/* node3 was first in list: update first field in base */
|
|
||||||
flst_write_addr(base + FLST_FIRST, node2_addr, mtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set prev field of node3 */
|
|
||||||
flst_write_addr(node3 + FLST_PREV, node2_addr, mtr);
|
|
||||||
|
|
||||||
/* Update len of base node */
|
|
||||||
len = flst_get_len(base);
|
|
||||||
mlog_write_ulint(base + FLST_LEN, len + 1, MLOG_4BYTES, mtr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************//**
|
/** Remove a file list node.
|
||||||
Removes a node. */
|
@param[in,out] base base node block
|
||||||
void
|
@param[in] boffset byte offset of the base node
|
||||||
flst_remove(
|
@param[in,out] cur block to be removed
|
||||||
/*========*/
|
@param[in] coffset byte offset of the current record to be removed
|
||||||
flst_base_node_t* base, /*!< in: pointer to base node of list */
|
@param[in,outr] mtr mini-transaction */
|
||||||
flst_node_t* node2, /*!< in: node to remove */
|
void flst_remove(buf_block_t *base, uint16_t boffset,
|
||||||
mtr_t* mtr) /*!< in: mini-transaction handle */
|
buf_block_t *cur, uint16_t coffset, mtr_t *mtr)
|
||||||
{
|
{
|
||||||
ulint space;
|
ut_ad(boffset < base->physical_size());
|
||||||
flst_node_t* node1;
|
ut_ad(coffset < cur->physical_size());
|
||||||
fil_addr_t node1_addr;
|
ut_ad(mtr_memo_contains_page_flagged(mtr, base->frame,
|
||||||
fil_addr_t node2_addr;
|
MTR_MEMO_PAGE_X_FIX |
|
||||||
flst_node_t* node3;
|
MTR_MEMO_PAGE_SX_FIX));
|
||||||
fil_addr_t node3_addr;
|
ut_ad(mtr_memo_contains_page_flagged(mtr, cur->frame,
|
||||||
ulint len;
|
MTR_MEMO_PAGE_X_FIX |
|
||||||
|
MTR_MEMO_PAGE_SX_FIX));
|
||||||
|
|
||||||
ut_ad(mtr && node2 && base);
|
const fil_addr_t prev_addr= flst_get_prev_addr(cur->frame + coffset);
|
||||||
ut_ad(mtr_memo_contains_page_flagged(mtr, base,
|
const fil_addr_t next_addr= flst_get_next_addr(cur->frame + coffset);
|
||||||
MTR_MEMO_PAGE_X_FIX
|
|
||||||
| MTR_MEMO_PAGE_SX_FIX));
|
|
||||||
ut_ad(mtr_memo_contains_page_flagged(mtr, node2,
|
|
||||||
MTR_MEMO_PAGE_X_FIX
|
|
||||||
| MTR_MEMO_PAGE_SX_FIX));
|
|
||||||
|
|
||||||
buf_ptr_get_fsp_addr(node2, &space, &node2_addr);
|
if (fil_addr_is_null(prev_addr))
|
||||||
|
flst_write_addr(*base, base->frame + boffset + FLST_FIRST, next_addr, mtr);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buf_block_t *block= cur;
|
||||||
|
flst_node_t *prev= prev_addr.page == cur->page.id.page_no()
|
||||||
|
? cur->frame + prev_addr.boffset
|
||||||
|
: fut_get_ptr(cur->page.id.space(), cur->zip_size(), prev_addr,
|
||||||
|
RW_SX_LATCH, mtr, &block);
|
||||||
|
flst_write_addr(*block, prev + FLST_NEXT, next_addr, mtr);
|
||||||
|
}
|
||||||
|
|
||||||
fil_space_t* s = fil_space_acquire_silent(space);
|
if (fil_addr_is_null(next_addr))
|
||||||
ulint zip_size = s ? s->zip_size() : 0;
|
flst_write_addr(*base, base->frame + boffset + FLST_LAST, prev_addr, mtr);
|
||||||
if (s) s->release();
|
else
|
||||||
|
{
|
||||||
|
buf_block_t *block= cur;
|
||||||
|
flst_node_t *next= next_addr.page == cur->page.id.page_no()
|
||||||
|
? cur->frame + next_addr.boffset
|
||||||
|
: fut_get_ptr(cur->page.id.space(), cur->zip_size(), next_addr,
|
||||||
|
RW_SX_LATCH, mtr, &block);
|
||||||
|
flst_write_addr(*block, next + FLST_PREV, prev_addr, mtr);
|
||||||
|
}
|
||||||
|
|
||||||
node1_addr = flst_get_prev_addr(node2);
|
byte *len= &base->frame[boffset + FLST_LEN];
|
||||||
node3_addr = flst_get_next_addr(node2);
|
ut_ad(mach_read_from_4(len) > 0);
|
||||||
|
mtr->write<4>(*base, len, mach_read_from_4(len) - 1);
|
||||||
if (!fil_addr_is_null(node1_addr)) {
|
|
||||||
|
|
||||||
/* Update next field of node1 */
|
|
||||||
|
|
||||||
if (node1_addr.page == node2_addr.page) {
|
|
||||||
|
|
||||||
node1 = page_align(node2) + node1_addr.boffset;
|
|
||||||
} else {
|
|
||||||
node1 = fut_get_ptr(space, zip_size,
|
|
||||||
node1_addr, RW_SX_LATCH, mtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
ut_ad(node1 != node2);
|
|
||||||
|
|
||||||
flst_write_addr(node1 + FLST_NEXT, node3_addr, mtr);
|
|
||||||
} else {
|
|
||||||
/* node2 was first in list: update first field in base */
|
|
||||||
flst_write_addr(base + FLST_FIRST, node3_addr, mtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!fil_addr_is_null(node3_addr)) {
|
|
||||||
/* Update prev field of node3 */
|
|
||||||
|
|
||||||
if (node3_addr.page == node2_addr.page) {
|
|
||||||
|
|
||||||
node3 = page_align(node2) + node3_addr.boffset;
|
|
||||||
} else {
|
|
||||||
node3 = fut_get_ptr(space, zip_size,
|
|
||||||
node3_addr, RW_SX_LATCH, mtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
ut_ad(node2 != node3);
|
|
||||||
|
|
||||||
flst_write_addr(node3 + FLST_PREV, node1_addr, mtr);
|
|
||||||
} else {
|
|
||||||
/* node2 was last in list: update last field in base */
|
|
||||||
flst_write_addr(base + FLST_LAST, node1_addr, mtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Update len of base node */
|
|
||||||
len = flst_get_len(base);
|
|
||||||
ut_ad(len > 0);
|
|
||||||
|
|
||||||
mlog_write_ulint(base + FLST_LEN, len - 1, MLOG_4BYTES, mtr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************//**
|
#ifdef UNIV_DEBUG
|
||||||
Validates a file-based list.
|
/** Validate a file-based list. */
|
||||||
@return TRUE if ok */
|
void flst_validate(const buf_block_t *base, uint16_t boffset, mtr_t *mtr)
|
||||||
ibool
|
|
||||||
flst_validate(
|
|
||||||
/*==========*/
|
|
||||||
const flst_base_node_t* base, /*!< in: pointer to base node of list */
|
|
||||||
mtr_t* mtr1) /*!< in: mtr */
|
|
||||||
{
|
{
|
||||||
ulint space;
|
ut_ad(boffset < base->physical_size());
|
||||||
const flst_node_t* node;
|
ut_ad(mtr_memo_contains_page_flagged(mtr, base->frame,
|
||||||
fil_addr_t node_addr;
|
MTR_MEMO_PAGE_X_FIX |
|
||||||
fil_addr_t base_addr;
|
MTR_MEMO_PAGE_SX_FIX));
|
||||||
ulint len;
|
|
||||||
ulint i;
|
|
||||||
mtr_t mtr2;
|
|
||||||
|
|
||||||
ut_ad(base);
|
/* We use two mini-transaction handles: the first is used to lock
|
||||||
ut_ad(mtr_memo_contains_page_flagged(mtr1, base,
|
the base node, and prevent other threads from modifying the list.
|
||||||
MTR_MEMO_PAGE_X_FIX
|
The second is used to traverse the list. We cannot run the second
|
||||||
| MTR_MEMO_PAGE_SX_FIX));
|
mtr without committing it at times, because if the list is long,
|
||||||
|
the x-locked pages could fill the buffer, resulting in a deadlock. */
|
||||||
|
mtr_t mtr2;
|
||||||
|
|
||||||
/* We use two mini-transaction handles: the first is used to
|
const uint32_t len= flst_get_len(base->frame + boffset);
|
||||||
lock the base node, and prevent other threads from modifying the
|
fil_addr_t addr= flst_get_first(base->frame + boffset);
|
||||||
list. The second is used to traverse the list. We cannot run the
|
|
||||||
second mtr without committing it at times, because if the list
|
|
||||||
is long, then the x-locked pages could fill the buffer resulting
|
|
||||||
in a deadlock. */
|
|
||||||
|
|
||||||
/* Find out the space id */
|
for (uint32_t i= len; i--; )
|
||||||
buf_ptr_get_fsp_addr(base, &space, &base_addr);
|
{
|
||||||
|
mtr2.start();
|
||||||
|
const flst_node_t *node= fut_get_ptr(base->page.id.space(),
|
||||||
|
base->zip_size(), addr,
|
||||||
|
RW_SX_LATCH, &mtr2);
|
||||||
|
addr= flst_get_next_addr(node);
|
||||||
|
mtr2.commit();
|
||||||
|
}
|
||||||
|
|
||||||
fil_space_t* s = fil_space_acquire_silent(space);
|
ut_ad(fil_addr_is_null(addr));
|
||||||
ulint zip_size = s ? s->zip_size() : 0;
|
|
||||||
if (s) s->release();
|
|
||||||
|
|
||||||
len = flst_get_len(base);
|
addr= flst_get_last(base->frame + boffset);
|
||||||
node_addr = flst_get_first(base);
|
|
||||||
|
|
||||||
for (i = 0; i < len; i++) {
|
for (uint32_t i= len; i--; )
|
||||||
mtr_start(&mtr2);
|
{
|
||||||
|
mtr2.start();
|
||||||
|
const flst_node_t *node= fut_get_ptr(base->page.id.space(),
|
||||||
|
base->zip_size(), addr,
|
||||||
|
RW_SX_LATCH, &mtr2);
|
||||||
|
addr= flst_get_prev_addr(node);
|
||||||
|
mtr2.commit();
|
||||||
|
}
|
||||||
|
|
||||||
node = fut_get_ptr(space, zip_size,
|
ut_ad(fil_addr_is_null(addr));
|
||||||
node_addr, RW_SX_LATCH, &mtr2);
|
|
||||||
node_addr = flst_get_next_addr(node);
|
|
||||||
|
|
||||||
mtr_commit(&mtr2); /* Commit mtr2 each round to prevent buffer
|
|
||||||
becoming full */
|
|
||||||
}
|
|
||||||
|
|
||||||
ut_a(fil_addr_is_null(node_addr));
|
|
||||||
|
|
||||||
node_addr = flst_get_last(base);
|
|
||||||
|
|
||||||
for (i = 0; i < len; i++) {
|
|
||||||
mtr_start(&mtr2);
|
|
||||||
|
|
||||||
node = fut_get_ptr(space, zip_size,
|
|
||||||
node_addr, RW_SX_LATCH, &mtr2);
|
|
||||||
node_addr = flst_get_prev_addr(node);
|
|
||||||
|
|
||||||
mtr_commit(&mtr2); /* Commit mtr2 each round to prevent buffer
|
|
||||||
becoming full */
|
|
||||||
}
|
|
||||||
|
|
||||||
ut_a(fil_addr_is_null(node_addr));
|
|
||||||
|
|
||||||
return(TRUE);
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -628,12 +628,8 @@ rtr_adjust_upper_level(
|
||||||
rtr_mbr_t* new_mbr, /*!< in: MBR on the new page */
|
rtr_mbr_t* new_mbr, /*!< in: MBR on the new page */
|
||||||
mtr_t* mtr) /*!< in: mtr */
|
mtr_t* mtr) /*!< in: mtr */
|
||||||
{
|
{
|
||||||
page_t* page;
|
|
||||||
page_t* new_page;
|
|
||||||
ulint page_no;
|
ulint page_no;
|
||||||
ulint new_page_no;
|
ulint new_page_no;
|
||||||
page_zip_des_t* page_zip;
|
|
||||||
page_zip_des_t* new_page_zip;
|
|
||||||
dict_index_t* index = sea_cur->index;
|
dict_index_t* index = sea_cur->index;
|
||||||
btr_cur_t cursor;
|
btr_cur_t cursor;
|
||||||
ulint* offsets;
|
ulint* offsets;
|
||||||
|
|
@ -657,13 +653,9 @@ rtr_adjust_upper_level(
|
||||||
level = btr_page_get_level(buf_block_get_frame(block));
|
level = btr_page_get_level(buf_block_get_frame(block));
|
||||||
ut_ad(level == btr_page_get_level(buf_block_get_frame(new_block)));
|
ut_ad(level == btr_page_get_level(buf_block_get_frame(new_block)));
|
||||||
|
|
||||||
page = buf_block_get_frame(block);
|
|
||||||
page_no = block->page.id.page_no();
|
page_no = block->page.id.page_no();
|
||||||
page_zip = buf_block_get_page_zip(block);
|
|
||||||
|
|
||||||
new_page = buf_block_get_frame(new_block);
|
|
||||||
new_page_no = new_block->page.id.page_no();
|
new_page_no = new_block->page.id.page_no();
|
||||||
new_page_zip = buf_block_get_page_zip(new_block);
|
|
||||||
|
|
||||||
/* Set new mbr for the old page on the upper level. */
|
/* Set new mbr for the old page on the upper level. */
|
||||||
/* Look up the index for the node pointer to page */
|
/* Look up the index for the node pointer to page */
|
||||||
|
|
@ -672,7 +664,8 @@ rtr_adjust_upper_level(
|
||||||
|
|
||||||
page_cursor = btr_cur_get_page_cur(&cursor);
|
page_cursor = btr_cur_get_page_cur(&cursor);
|
||||||
|
|
||||||
rtr_update_mbr_field(&cursor, offsets, NULL, page, mbr, NULL, mtr);
|
rtr_update_mbr_field(&cursor, offsets, NULL, block->frame, mbr, NULL,
|
||||||
|
mtr);
|
||||||
|
|
||||||
/* Already updated parent MBR, reset in our path */
|
/* Already updated parent MBR, reset in our path */
|
||||||
if (sea_cur->rtr_info) {
|
if (sea_cur->rtr_info) {
|
||||||
|
|
@ -686,7 +679,7 @@ rtr_adjust_upper_level(
|
||||||
/* Insert the node for the new page. */
|
/* Insert the node for the new page. */
|
||||||
node_ptr_upper = rtr_index_build_node_ptr(
|
node_ptr_upper = rtr_index_build_node_ptr(
|
||||||
index, new_mbr,
|
index, new_mbr,
|
||||||
page_rec_get_next(page_get_infimum_rec(new_page)),
|
page_rec_get_next(page_get_infimum_rec(new_block->frame)),
|
||||||
new_page_no, heap);
|
new_page_no, heap);
|
||||||
|
|
||||||
ulint up_match = 0;
|
ulint up_match = 0;
|
||||||
|
|
@ -742,26 +735,25 @@ rtr_adjust_upper_level(
|
||||||
|
|
||||||
ut_ad(block->zip_size() == index->table->space->zip_size());
|
ut_ad(block->zip_size() == index->table->space->zip_size());
|
||||||
|
|
||||||
const uint32_t next_page_no = btr_page_get_next(page);
|
const uint32_t next_page_no = btr_page_get_next(block->frame);
|
||||||
|
|
||||||
if (next_page_no != FIL_NULL) {
|
if (next_page_no != FIL_NULL) {
|
||||||
buf_block_t* next_block = btr_block_get(
|
buf_block_t* next_block = btr_block_get(
|
||||||
*index, next_page_no, RW_X_LATCH, false, mtr);
|
*index, next_page_no, RW_X_LATCH, false, mtr);
|
||||||
#ifdef UNIV_BTR_DEBUG
|
#ifdef UNIV_BTR_DEBUG
|
||||||
ut_a(page_is_comp(next_block->frame) == page_is_comp(page));
|
ut_a(page_is_comp(next_block->frame)
|
||||||
|
== page_is_comp(block->frame));
|
||||||
ut_a(btr_page_get_prev(next_block->frame)
|
ut_a(btr_page_get_prev(next_block->frame)
|
||||||
== block->page.id.page_no());
|
== block->page.id.page_no());
|
||||||
#endif /* UNIV_BTR_DEBUG */
|
#endif /* UNIV_BTR_DEBUG */
|
||||||
|
|
||||||
btr_page_set_prev(buf_block_get_frame(next_block),
|
btr_page_set_prev(next_block, new_page_no, mtr);
|
||||||
buf_block_get_page_zip(next_block),
|
|
||||||
new_page_no, mtr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
btr_page_set_next(page, page_zip, new_page_no, mtr);
|
btr_page_set_next(block, new_page_no, mtr);
|
||||||
|
|
||||||
btr_page_set_prev(new_page, new_page_zip, page_no, mtr);
|
btr_page_set_prev(new_block, page_no, mtr);
|
||||||
btr_page_set_next(new_page, new_page_zip, next_page_no, mtr);
|
btr_page_set_next(new_block, next_page_no, mtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************//**
|
/*************************************************************//**
|
||||||
|
|
@ -848,11 +840,8 @@ rtr_split_page_move_rec_list(
|
||||||
ut_ad(!is_leaf || cur_split_node->key != first_rec);
|
ut_ad(!is_leaf || cur_split_node->key != first_rec);
|
||||||
|
|
||||||
rec = page_cur_insert_rec_low(
|
rec = page_cur_insert_rec_low(
|
||||||
page_cur_get_rec(&new_page_cursor),
|
page_cur_get_rec(&new_page_cursor),
|
||||||
index,
|
index, cur_split_node->key, offsets, mtr);
|
||||||
cur_split_node->key,
|
|
||||||
offsets,
|
|
||||||
mtr);
|
|
||||||
|
|
||||||
ut_a(rec);
|
ut_a(rec);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17856,14 +17856,10 @@ innodb_make_page_dirty(THD*, st_mysql_sys_var*, void*, const void* save)
|
||||||
space->zip_size(), RW_X_LATCH, &mtr);
|
space->zip_size(), RW_X_LATCH, &mtr);
|
||||||
|
|
||||||
if (block != NULL) {
|
if (block != NULL) {
|
||||||
byte* page = block->frame;
|
ib::info() << "Dirtying page: " << block->page.id;
|
||||||
|
mtr.write<1,mtr_t::FORCED>(*block,
|
||||||
ib::info() << "Dirtying page: " << page_id_t(
|
block->frame + FIL_PAGE_SPACE_ID,
|
||||||
page_get_space_id(page), page_get_page_no(page));
|
block->frame[FIL_PAGE_SPACE_ID]);
|
||||||
|
|
||||||
mlog_write_ulint(page + FIL_PAGE_TYPE,
|
|
||||||
fil_page_get_type(page),
|
|
||||||
MLOG_2BYTES, &mtr);
|
|
||||||
}
|
}
|
||||||
mtr.commit();
|
mtr.commit();
|
||||||
goto func_exit;
|
goto func_exit;
|
||||||
|
|
|
||||||
|
|
@ -10198,12 +10198,12 @@ commit_cache_norebuild(
|
||||||
space->zip_size(),
|
space->zip_size(),
|
||||||
RW_X_LATCH, &mtr)) {
|
RW_X_LATCH, &mtr)) {
|
||||||
mtr.set_named_space(space);
|
mtr.set_named_space(space);
|
||||||
mlog_write_ulint(
|
mtr.write<4,mtr_t::OPT>(
|
||||||
|
*b,
|
||||||
FSP_HEADER_OFFSET
|
FSP_HEADER_OFFSET
|
||||||
+ FSP_SPACE_FLAGS + b->frame,
|
+ FSP_SPACE_FLAGS + b->frame,
|
||||||
space->flags
|
space->flags
|
||||||
& ~FSP_FLAGS_MEM_MASK,
|
& ~FSP_FLAGS_MEM_MASK);
|
||||||
MLOG_4BYTES, &mtr);
|
|
||||||
}
|
}
|
||||||
mtr.commit();
|
mtr.commit();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -332,17 +332,12 @@ ibuf_header_page_get(
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************//**
|
/** Acquire the change buffer root page.
|
||||||
Gets the root page and sx-latches it.
|
@param[in,out] mtr mini-transaction
|
||||||
@return insert buffer tree root page */
|
@return change buffer root page, SX-latched */
|
||||||
static
|
static buf_block_t *ibuf_tree_root_get(mtr_t *mtr)
|
||||||
page_t*
|
|
||||||
ibuf_tree_root_get(
|
|
||||||
/*===============*/
|
|
||||||
mtr_t* mtr) /*!< in: mtr */
|
|
||||||
{
|
{
|
||||||
buf_block_t* block;
|
buf_block_t* block;
|
||||||
page_t* root;
|
|
||||||
|
|
||||||
ut_ad(ibuf_inside(mtr));
|
ut_ad(ibuf_inside(mtr));
|
||||||
ut_ad(mutex_own(&ibuf_mutex));
|
ut_ad(mutex_own(&ibuf_mutex));
|
||||||
|
|
@ -356,13 +351,11 @@ ibuf_tree_root_get(
|
||||||
|
|
||||||
buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE_NEW);
|
buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE_NEW);
|
||||||
|
|
||||||
root = buf_block_get_frame(block);
|
ut_ad(page_get_space_id(block->frame) == IBUF_SPACE_ID);
|
||||||
|
ut_ad(page_get_page_no(block->frame) == FSP_IBUF_TREE_ROOT_PAGE_NO);
|
||||||
|
ut_ad(ibuf.empty == page_is_empty(block->frame));
|
||||||
|
|
||||||
ut_ad(page_get_space_id(root) == IBUF_SPACE_ID);
|
return block;
|
||||||
ut_ad(page_get_page_no(root) == FSP_IBUF_TREE_ROOT_PAGE_NO);
|
|
||||||
ut_ad(ibuf.empty == page_is_empty(root));
|
|
||||||
|
|
||||||
return(root);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************//**
|
/******************************************************************//**
|
||||||
|
|
@ -624,29 +617,27 @@ ibuf_bitmap_page_get_bits_low(
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the desired bit for a given page in a bitmap page.
|
/** Sets the desired bit for a given page in a bitmap page.
|
||||||
@param[in,out] page bitmap page
|
@tparam bit IBUF_BITMAP_FREE, IBUF_BITMAP_BUFFERED, ...
|
||||||
|
@param[in,out] block bitmap page
|
||||||
@param[in] page_id page id whose bits to set
|
@param[in] page_id page id whose bits to set
|
||||||
@param[in] physical_size page size
|
@param[in] physical_size page size
|
||||||
@param[in] bit IBUF_BITMAP_FREE, IBUF_BITMAP_BUFFERED, ...
|
|
||||||
@param[in] val value to set
|
@param[in] val value to set
|
||||||
@param[in,out] mtr mtr containing an x-latch to the bitmap page */
|
@param[in,out] mtr mtr containing an x-latch to the bitmap page */
|
||||||
static
|
template<ulint bit>
|
||||||
void
|
static void
|
||||||
ibuf_bitmap_page_set_bits(
|
ibuf_bitmap_page_set_bits(
|
||||||
page_t* page,
|
buf_block_t* block,
|
||||||
const page_id_t page_id,
|
const page_id_t page_id,
|
||||||
ulint physical_size,
|
ulint physical_size,
|
||||||
ulint bit,
|
|
||||||
ulint val,
|
ulint val,
|
||||||
mtr_t* mtr)
|
mtr_t* mtr)
|
||||||
{
|
{
|
||||||
ulint byte_offset;
|
ulint byte_offset;
|
||||||
ulint bit_offset;
|
ulint bit_offset;
|
||||||
ulint map_byte;
|
|
||||||
|
|
||||||
ut_ad(bit < IBUF_BITS_PER_PAGE);
|
static_assert(bit < IBUF_BITS_PER_PAGE, "wrong bit");
|
||||||
compile_time_assert(!(IBUF_BITS_PER_PAGE % 2));
|
compile_time_assert(!(IBUF_BITS_PER_PAGE % 2));
|
||||||
ut_ad(mtr_memo_contains_page(mtr, page, MTR_MEMO_PAGE_X_FIX));
|
ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
|
||||||
ut_ad(mtr->is_named_space(page_id.space()));
|
ut_ad(mtr->is_named_space(page_id.space()));
|
||||||
|
|
||||||
bit_offset = (page_id.page_no() % physical_size)
|
bit_offset = (page_id.page_no() % physical_size)
|
||||||
|
|
@ -657,21 +648,22 @@ ibuf_bitmap_page_set_bits(
|
||||||
|
|
||||||
ut_ad(byte_offset + IBUF_BITMAP < srv_page_size);
|
ut_ad(byte_offset + IBUF_BITMAP < srv_page_size);
|
||||||
|
|
||||||
map_byte = mach_read_from_1(page + IBUF_BITMAP + byte_offset);
|
byte* map_byte = &block->frame[IBUF_BITMAP + byte_offset];
|
||||||
|
byte b = *map_byte;
|
||||||
|
|
||||||
if (bit == IBUF_BITMAP_FREE) {
|
if (bit == IBUF_BITMAP_FREE) {
|
||||||
ut_ad(bit_offset + 1 < 8);
|
ut_ad(bit_offset + 1 < 8);
|
||||||
ut_ad(val <= 3);
|
ut_ad(val <= 3);
|
||||||
|
b &= ~(3U << bit_offset);
|
||||||
map_byte = ut_bit_set_nth(map_byte, bit_offset, val / 2);
|
b |= (val & 2) << (bit_offset - 1)
|
||||||
map_byte = ut_bit_set_nth(map_byte, bit_offset + 1, val % 2);
|
| (val & 1) << (bit_offset + 1);
|
||||||
} else {
|
} else {
|
||||||
ut_ad(val <= 1);
|
ut_ad(val <= 1);
|
||||||
map_byte = ut_bit_set_nth(map_byte, bit_offset, val);
|
b &= ~(1U << bit_offset);
|
||||||
|
b |= val << bit_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
mlog_write_ulint(page + IBUF_BITMAP + byte_offset, map_byte,
|
mtr->write<1,mtr_t::OPT>(*block, map_byte, b);
|
||||||
MLOG_1BYTE, mtr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Calculates the bitmap page number for a given page number.
|
/** Calculates the bitmap page number for a given page number.
|
||||||
|
|
@ -697,7 +689,7 @@ stored.
|
||||||
page containing the descriptor bits for the file page; the bitmap page
|
page containing the descriptor bits for the file page; the bitmap page
|
||||||
is x-latched */
|
is x-latched */
|
||||||
static
|
static
|
||||||
page_t*
|
buf_block_t*
|
||||||
ibuf_bitmap_get_map_page_func(
|
ibuf_bitmap_get_map_page_func(
|
||||||
const page_id_t page_id,
|
const page_id_t page_id,
|
||||||
ulint zip_size,
|
ulint zip_size,
|
||||||
|
|
@ -718,8 +710,7 @@ ibuf_bitmap_get_map_page_func(
|
||||||
|
|
||||||
|
|
||||||
buf_block_dbg_add_level(block, SYNC_IBUF_BITMAP);
|
buf_block_dbg_add_level(block, SYNC_IBUF_BITMAP);
|
||||||
|
return block;
|
||||||
return(buf_block_get_frame(block));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the ibuf bitmap page where the bits describing a given file page are
|
/** Gets the ibuf bitmap page where the bits describing a given file page are
|
||||||
|
|
@ -749,31 +740,19 @@ ibuf_set_free_bits_low(
|
||||||
ulint val, /*!< in: value to set: < 4 */
|
ulint val, /*!< in: value to set: < 4 */
|
||||||
mtr_t* mtr) /*!< in/out: mtr */
|
mtr_t* mtr) /*!< in/out: mtr */
|
||||||
{
|
{
|
||||||
page_t* bitmap_page;
|
|
||||||
buf_frame_t* frame;
|
|
||||||
|
|
||||||
ut_ad(mtr->is_named_space(block->page.id.space()));
|
ut_ad(mtr->is_named_space(block->page.id.space()));
|
||||||
|
if (!page_is_leaf(block->frame)) {
|
||||||
if (!block) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
frame = buf_block_get_frame(block);
|
|
||||||
|
|
||||||
if (!frame || !page_is_leaf(frame)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bitmap_page = ibuf_bitmap_get_map_page(block->page.id,
|
|
||||||
block->zip_size(), mtr);
|
|
||||||
|
|
||||||
#ifdef UNIV_IBUF_DEBUG
|
#ifdef UNIV_IBUF_DEBUG
|
||||||
ut_a(val <= ibuf_index_page_calc_free(block));
|
ut_a(val <= ibuf_index_page_calc_free(block));
|
||||||
#endif /* UNIV_IBUF_DEBUG */
|
#endif /* UNIV_IBUF_DEBUG */
|
||||||
|
|
||||||
ibuf_bitmap_page_set_bits(
|
ibuf_bitmap_page_set_bits<IBUF_BITMAP_FREE>(
|
||||||
bitmap_page, block->page.id, block->physical_size(),
|
ibuf_bitmap_get_map_page(block->page.id, block->zip_size(),
|
||||||
IBUF_BITMAP_FREE, val, mtr);
|
mtr),
|
||||||
|
block->page.id, block->physical_size(), val, mtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************//**
|
/************************************************************************//**
|
||||||
|
|
@ -793,34 +772,21 @@ ibuf_set_free_bits_func(
|
||||||
#endif /* UNIV_IBUF_DEBUG */
|
#endif /* UNIV_IBUF_DEBUG */
|
||||||
ulint val) /*!< in: value to set: < 4 */
|
ulint val) /*!< in: value to set: < 4 */
|
||||||
{
|
{
|
||||||
mtr_t mtr;
|
if (!page_is_leaf(block->frame)) {
|
||||||
page_t* page;
|
|
||||||
page_t* bitmap_page;
|
|
||||||
|
|
||||||
page = buf_block_get_frame(block);
|
|
||||||
|
|
||||||
if (!page_is_leaf(page)) {
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mtr_start(&mtr);
|
mtr_t mtr;
|
||||||
|
mtr.start();
|
||||||
const fil_space_t* space = mtr.set_named_space_id(
|
const fil_space_t* space = mtr.set_named_space_id(
|
||||||
block->page.id.space());
|
block->page.id.space());
|
||||||
|
|
||||||
bitmap_page = ibuf_bitmap_get_map_page(block->page.id,
|
buf_block_t* bitmap_page = ibuf_bitmap_get_map_page(block->page.id,
|
||||||
block->zip_size(), &mtr);
|
block->zip_size(),
|
||||||
|
&mtr);
|
||||||
|
|
||||||
switch (space->purpose) {
|
if (space->purpose != FIL_TYPE_TABLESPACE) {
|
||||||
case FIL_TYPE_LOG:
|
mtr.set_log_mode(MTR_LOG_NO_REDO);
|
||||||
ut_ad(0);
|
|
||||||
break;
|
|
||||||
case FIL_TYPE_TABLESPACE:
|
|
||||||
break;
|
|
||||||
/* fall through */
|
|
||||||
case FIL_TYPE_TEMPORARY:
|
|
||||||
case FIL_TYPE_IMPORT:
|
|
||||||
mtr_set_log_mode(&mtr, MTR_LOG_NO_REDO);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef UNIV_IBUF_DEBUG
|
#ifdef UNIV_IBUF_DEBUG
|
||||||
|
|
@ -830,31 +796,17 @@ ibuf_set_free_bits_func(
|
||||||
old_val = ibuf_bitmap_page_get_bits(
|
old_val = ibuf_bitmap_page_get_bits(
|
||||||
bitmap_page, block->page.id,
|
bitmap_page, block->page.id,
|
||||||
IBUF_BITMAP_FREE, &mtr);
|
IBUF_BITMAP_FREE, &mtr);
|
||||||
# if 0
|
|
||||||
if (old_val != max_val) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"Ibuf: page %lu old val %lu max val %lu\n",
|
|
||||||
page_get_page_no(page),
|
|
||||||
old_val, max_val);
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
|
|
||||||
ut_a(old_val <= max_val);
|
ut_a(old_val <= max_val);
|
||||||
}
|
}
|
||||||
# if 0
|
|
||||||
fprintf(stderr, "Setting page no %lu free bits to %lu should be %lu\n",
|
|
||||||
page_get_page_no(page), val,
|
|
||||||
ibuf_index_page_calc_free(block));
|
|
||||||
# endif
|
|
||||||
|
|
||||||
ut_a(val <= ibuf_index_page_calc_free(block));
|
ut_a(val <= ibuf_index_page_calc_free(block));
|
||||||
#endif /* UNIV_IBUF_DEBUG */
|
#endif /* UNIV_IBUF_DEBUG */
|
||||||
|
|
||||||
ibuf_bitmap_page_set_bits(
|
ibuf_bitmap_page_set_bits<IBUF_BITMAP_FREE>(
|
||||||
bitmap_page, block->page.id, block->physical_size(),
|
bitmap_page, block->page.id, block->physical_size(),
|
||||||
IBUF_BITMAP_FREE, val, &mtr);
|
val, &mtr);
|
||||||
|
|
||||||
mtr_commit(&mtr);
|
mtr.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************//**
|
/************************************************************************//**
|
||||||
|
|
@ -929,19 +881,10 @@ ibuf_update_free_bits_zip(
|
||||||
buf_block_t* block, /*!< in/out: index page */
|
buf_block_t* block, /*!< in/out: index page */
|
||||||
mtr_t* mtr) /*!< in/out: mtr */
|
mtr_t* mtr) /*!< in/out: mtr */
|
||||||
{
|
{
|
||||||
page_t* bitmap_page;
|
ut_ad(page_is_leaf(block->frame));
|
||||||
ulint after;
|
ut_ad(block->zip_size());
|
||||||
|
|
||||||
ut_a(block);
|
ulint after = ibuf_index_page_calc_free_zip(block);
|
||||||
buf_frame_t* frame = buf_block_get_frame(block);
|
|
||||||
ut_a(frame);
|
|
||||||
ut_a(page_is_leaf(frame));
|
|
||||||
ut_a(block->zip_size());
|
|
||||||
|
|
||||||
bitmap_page = ibuf_bitmap_get_map_page(block->page.id,
|
|
||||||
block->zip_size(), mtr);
|
|
||||||
|
|
||||||
after = ibuf_index_page_calc_free_zip(block);
|
|
||||||
|
|
||||||
if (after == 0) {
|
if (after == 0) {
|
||||||
/* We move the page to the front of the buffer pool LRU list:
|
/* We move the page to the front of the buffer pool LRU list:
|
||||||
|
|
@ -952,9 +895,10 @@ ibuf_update_free_bits_zip(
|
||||||
buf_page_make_young(&block->page);
|
buf_page_make_young(&block->page);
|
||||||
}
|
}
|
||||||
|
|
||||||
ibuf_bitmap_page_set_bits(
|
ibuf_bitmap_page_set_bits<IBUF_BITMAP_FREE>(
|
||||||
bitmap_page, block->page.id, block->physical_size(),
|
ibuf_bitmap_get_map_page(block->page.id, block->zip_size(),
|
||||||
IBUF_BITMAP_FREE, after, mtr);
|
mtr),
|
||||||
|
block->page.id, block->physical_size(), after, mtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************//**
|
/**********************************************************************//**
|
||||||
|
|
@ -1029,7 +973,6 @@ ibuf_page_low(
|
||||||
{
|
{
|
||||||
ibool ret;
|
ibool ret;
|
||||||
mtr_t local_mtr;
|
mtr_t local_mtr;
|
||||||
page_t* bitmap_page;
|
|
||||||
|
|
||||||
ut_ad(!recv_no_ibuf_operations);
|
ut_ad(!recv_no_ibuf_operations);
|
||||||
ut_ad(x_latch || mtr == NULL);
|
ut_ad(x_latch || mtr == NULL);
|
||||||
|
|
@ -1064,10 +1007,8 @@ ibuf_page_low(
|
||||||
zip_size, RW_NO_LATCH, NULL, BUF_GET_NO_LATCH,
|
zip_size, RW_NO_LATCH, NULL, BUF_GET_NO_LATCH,
|
||||||
file, line, &local_mtr, &err);
|
file, line, &local_mtr, &err);
|
||||||
|
|
||||||
bitmap_page = buf_block_get_frame(block);
|
|
||||||
|
|
||||||
ret = ibuf_bitmap_page_get_bits_low(
|
ret = ibuf_bitmap_page_get_bits_low(
|
||||||
bitmap_page, page_id, zip_size,
|
block->frame, page_id, zip_size,
|
||||||
MTR_MEMO_BUF_FIX, &local_mtr, IBUF_BITMAP_IBUF);
|
MTR_MEMO_BUF_FIX, &local_mtr, IBUF_BITMAP_IBUF);
|
||||||
|
|
||||||
mtr_commit(&local_mtr);
|
mtr_commit(&local_mtr);
|
||||||
|
|
@ -1080,10 +1021,10 @@ ibuf_page_low(
|
||||||
mtr_start(mtr);
|
mtr_start(mtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bitmap_page = ibuf_bitmap_get_map_page_func(page_id, zip_size,
|
ret = ibuf_bitmap_page_get_bits(ibuf_bitmap_get_map_page_func(
|
||||||
file, line, mtr);
|
page_id, zip_size, file, line,
|
||||||
|
mtr)->frame,
|
||||||
ret = ibuf_bitmap_page_get_bits(bitmap_page, page_id, zip_size,
|
page_id, zip_size,
|
||||||
IBUF_BITMAP_IBUF, mtr);
|
IBUF_BITMAP_IBUF, mtr);
|
||||||
|
|
||||||
if (mtr == &local_mtr) {
|
if (mtr == &local_mtr) {
|
||||||
|
|
@ -1891,23 +1832,16 @@ ibuf_data_too_much_free(void)
|
||||||
return(ibuf.free_list_len >= 3 + (ibuf.size / 2) + 3 * ibuf.height);
|
return(ibuf.free_list_len >= 3 + (ibuf.size / 2) + 3 * ibuf.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************//**
|
/** Allocate a change buffer page.
|
||||||
Allocates a new page from the ibuf file segment and adds it to the free
|
@retval true on success
|
||||||
list.
|
@retval false if no space left */
|
||||||
@return TRUE on success, FALSE if no space left */
|
static bool ibuf_add_free_page()
|
||||||
static
|
|
||||||
ibool
|
|
||||||
ibuf_add_free_page(void)
|
|
||||||
/*====================*/
|
|
||||||
{
|
{
|
||||||
mtr_t mtr;
|
mtr_t mtr;
|
||||||
page_t* header_page;
|
page_t* header_page;
|
||||||
buf_block_t* block;
|
buf_block_t* block;
|
||||||
page_t* page;
|
|
||||||
page_t* root;
|
|
||||||
page_t* bitmap_page;
|
|
||||||
|
|
||||||
mtr_start(&mtr);
|
mtr.start();
|
||||||
/* Acquire the fsp latch before the ibuf header, obeying the latching
|
/* Acquire the fsp latch before the ibuf header, obeying the latching
|
||||||
order */
|
order */
|
||||||
mtr_x_lock_space(fil_system.sys_space, &mtr);
|
mtr_x_lock_space(fil_system.sys_space, &mtr);
|
||||||
|
|
@ -1928,26 +1862,24 @@ ibuf_add_free_page(void)
|
||||||
&mtr);
|
&mtr);
|
||||||
|
|
||||||
if (block == NULL) {
|
if (block == NULL) {
|
||||||
mtr_commit(&mtr);
|
mtr.commit();
|
||||||
|
return false;
|
||||||
return(FALSE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ut_ad(rw_lock_get_x_lock_count(&block->lock) == 1);
|
ut_ad(rw_lock_get_x_lock_count(&block->lock) == 1);
|
||||||
ibuf_enter(&mtr);
|
ibuf_enter(&mtr);
|
||||||
mutex_enter(&ibuf_mutex);
|
mutex_enter(&ibuf_mutex);
|
||||||
root = ibuf_tree_root_get(&mtr);
|
|
||||||
|
|
||||||
buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE_NEW);
|
buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE_NEW);
|
||||||
page = buf_block_get_frame(block);
|
|
||||||
|
|
||||||
mlog_write_ulint(page + FIL_PAGE_TYPE, FIL_PAGE_IBUF_FREE_LIST,
|
mtr.write<2>(*block, block->frame + FIL_PAGE_TYPE,
|
||||||
MLOG_2BYTES, &mtr);
|
FIL_PAGE_IBUF_FREE_LIST);
|
||||||
|
|
||||||
/* Add the page to the free list and update the ibuf size data */
|
/* Add the page to the free list and update the ibuf size data */
|
||||||
|
|
||||||
flst_add_last(root + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST,
|
flst_add_last(ibuf_tree_root_get(&mtr),
|
||||||
page + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST_NODE, &mtr);
|
PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST,
|
||||||
|
block, PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST_NODE, &mtr);
|
||||||
|
|
||||||
ibuf.seg_size++;
|
ibuf.seg_size++;
|
||||||
ibuf.free_list_len++;
|
ibuf.free_list_len++;
|
||||||
|
|
@ -1955,17 +1887,18 @@ ibuf_add_free_page(void)
|
||||||
/* Set the bit indicating that this page is now an ibuf tree page
|
/* Set the bit indicating that this page is now an ibuf tree page
|
||||||
(level 2 page) */
|
(level 2 page) */
|
||||||
|
|
||||||
const page_id_t page_id(IBUF_SPACE_ID, block->page.id.page_no());
|
const page_id_t page_id(IBUF_SPACE_ID, block->page.id.page_no());
|
||||||
bitmap_page = ibuf_bitmap_get_map_page(page_id, 0, &mtr);
|
buf_block_t* bitmap_page = ibuf_bitmap_get_map_page(page_id, 0, &mtr);
|
||||||
|
|
||||||
mutex_exit(&ibuf_mutex);
|
mutex_exit(&ibuf_mutex);
|
||||||
|
|
||||||
ibuf_bitmap_page_set_bits(bitmap_page, page_id, srv_page_size,
|
ibuf_bitmap_page_set_bits<IBUF_BITMAP_IBUF>(bitmap_page, page_id,
|
||||||
IBUF_BITMAP_IBUF, TRUE, &mtr);
|
srv_page_size, true,
|
||||||
|
&mtr);
|
||||||
|
|
||||||
ibuf_mtr_commit(&mtr);
|
ibuf_mtr_commit(&mtr);
|
||||||
|
|
||||||
return(TRUE);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************//**
|
/*********************************************************************//**
|
||||||
|
|
@ -1979,9 +1912,6 @@ ibuf_remove_free_page(void)
|
||||||
mtr_t mtr2;
|
mtr_t mtr2;
|
||||||
page_t* header_page;
|
page_t* header_page;
|
||||||
ulint page_no;
|
ulint page_no;
|
||||||
page_t* page;
|
|
||||||
page_t* root;
|
|
||||||
page_t* bitmap_page;
|
|
||||||
|
|
||||||
log_free_check();
|
log_free_check();
|
||||||
|
|
||||||
|
|
@ -2009,12 +1939,12 @@ ibuf_remove_free_page(void)
|
||||||
|
|
||||||
ibuf_mtr_start(&mtr2);
|
ibuf_mtr_start(&mtr2);
|
||||||
|
|
||||||
root = ibuf_tree_root_get(&mtr2);
|
buf_block_t* root = ibuf_tree_root_get(&mtr2);
|
||||||
|
|
||||||
mutex_exit(&ibuf_mutex);
|
mutex_exit(&ibuf_mutex);
|
||||||
|
|
||||||
page_no = flst_get_last(PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST
|
page_no = flst_get_last(PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST
|
||||||
+ root).page;
|
+ root->frame).page;
|
||||||
|
|
||||||
/* NOTE that we must release the latch on the ibuf tree root
|
/* NOTE that we must release the latch on the ibuf tree root
|
||||||
because in fseg_free_page we access level 1 pages, and the root
|
because in fseg_free_page we access level 1 pages, and the root
|
||||||
|
|
@ -2044,22 +1974,15 @@ ibuf_remove_free_page(void)
|
||||||
root = ibuf_tree_root_get(&mtr);
|
root = ibuf_tree_root_get(&mtr);
|
||||||
|
|
||||||
ut_ad(page_no == flst_get_last(PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST
|
ut_ad(page_no == flst_get_last(PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST
|
||||||
+ root).page);
|
+ root->frame).page);
|
||||||
|
|
||||||
{
|
buf_block_t* block = buf_page_get(page_id, 0, RW_X_LATCH, &mtr);
|
||||||
buf_block_t* block;
|
buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE);
|
||||||
|
|
||||||
block = buf_page_get(page_id, 0, RW_X_LATCH, &mtr);
|
|
||||||
|
|
||||||
buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE);
|
|
||||||
|
|
||||||
page = buf_block_get_frame(block);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove the page from the free list and update the ibuf size data */
|
/* Remove the page from the free list and update the ibuf size data */
|
||||||
|
|
||||||
flst_remove(root + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST,
|
flst_remove(root, PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST,
|
||||||
page + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST_NODE, &mtr);
|
block, PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST_NODE, &mtr);
|
||||||
|
|
||||||
mutex_exit(&ibuf_pessimistic_insert_mutex);
|
mutex_exit(&ibuf_pessimistic_insert_mutex);
|
||||||
|
|
||||||
|
|
@ -2069,13 +1992,12 @@ ibuf_remove_free_page(void)
|
||||||
/* Set the bit indicating that this page is no more an ibuf tree page
|
/* Set the bit indicating that this page is no more an ibuf tree page
|
||||||
(level 2 page) */
|
(level 2 page) */
|
||||||
|
|
||||||
bitmap_page = ibuf_bitmap_get_map_page(page_id, 0, &mtr);
|
buf_block_t* bitmap_page = ibuf_bitmap_get_map_page(page_id, 0, &mtr);
|
||||||
|
|
||||||
mutex_exit(&ibuf_mutex);
|
mutex_exit(&ibuf_mutex);
|
||||||
|
|
||||||
ibuf_bitmap_page_set_bits(
|
ibuf_bitmap_page_set_bits<IBUF_BITMAP_IBUF>(
|
||||||
bitmap_page, page_id, srv_page_size,
|
bitmap_page, page_id, srv_page_size, false, &mtr);
|
||||||
IBUF_BITMAP_IBUF, FALSE, &mtr);
|
|
||||||
|
|
||||||
ut_d(buf_page_set_file_page_was_freed(page_id));
|
ut_d(buf_page_set_file_page_was_freed(page_id));
|
||||||
|
|
||||||
|
|
@ -3305,8 +3227,7 @@ ibuf_insert_low(
|
||||||
ulint buffered;
|
ulint buffered;
|
||||||
lint min_n_recs;
|
lint min_n_recs;
|
||||||
rec_t* ins_rec;
|
rec_t* ins_rec;
|
||||||
ibool old_bit_value;
|
buf_block_t* bitmap_page;
|
||||||
page_t* bitmap_page;
|
|
||||||
buf_block_t* block;
|
buf_block_t* block;
|
||||||
page_t* root;
|
page_t* root;
|
||||||
dberr_t err;
|
dberr_t err;
|
||||||
|
|
@ -3459,8 +3380,8 @@ ibuf_insert_low(
|
||||||
|
|
||||||
if (op == IBUF_OP_INSERT) {
|
if (op == IBUF_OP_INSERT) {
|
||||||
ulint bits = ibuf_bitmap_page_get_bits(
|
ulint bits = ibuf_bitmap_page_get_bits(
|
||||||
bitmap_page, page_id, physical_size, IBUF_BITMAP_FREE,
|
bitmap_page->frame, page_id, physical_size,
|
||||||
&bitmap_mtr);
|
IBUF_BITMAP_FREE, &bitmap_mtr);
|
||||||
|
|
||||||
if (buffered + entry_size + page_dir_calc_reserved_space(1)
|
if (buffered + entry_size + page_dir_calc_reserved_space(1)
|
||||||
> ibuf_index_page_calc_free_from_bits(physical_size,
|
> ibuf_index_page_calc_free_from_bits(physical_size,
|
||||||
|
|
@ -3505,17 +3426,8 @@ ibuf_insert_low(
|
||||||
|
|
||||||
/* Set the bitmap bit denoting that the insert buffer contains
|
/* Set the bitmap bit denoting that the insert buffer contains
|
||||||
buffered entries for this index page, if the bit is not set yet */
|
buffered entries for this index page, if the bit is not set yet */
|
||||||
|
ibuf_bitmap_page_set_bits<IBUF_BITMAP_BUFFERED>(
|
||||||
old_bit_value = ibuf_bitmap_page_get_bits(
|
bitmap_page, page_id, physical_size, true, &bitmap_mtr);
|
||||||
bitmap_page, page_id, physical_size,
|
|
||||||
IBUF_BITMAP_BUFFERED, &bitmap_mtr);
|
|
||||||
|
|
||||||
if (!old_bit_value) {
|
|
||||||
ibuf_bitmap_page_set_bits(bitmap_page, page_id, physical_size,
|
|
||||||
IBUF_BITMAP_BUFFERED, TRUE,
|
|
||||||
&bitmap_mtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
ibuf_mtr_commit(&bitmap_mtr);
|
ibuf_mtr_commit(&bitmap_mtr);
|
||||||
|
|
||||||
cursor = btr_pcur_get_btr_cur(&pcur);
|
cursor = btr_pcur_get_btr_cur(&pcur);
|
||||||
|
|
@ -3548,7 +3460,7 @@ ibuf_insert_low(
|
||||||
which would cause the sx-latching of the root after that to
|
which would cause the sx-latching of the root after that to
|
||||||
break the latching order. */
|
break the latching order. */
|
||||||
|
|
||||||
root = ibuf_tree_root_get(&mtr);
|
root = ibuf_tree_root_get(&mtr)->frame;
|
||||||
|
|
||||||
err = btr_cur_optimistic_insert(
|
err = btr_cur_optimistic_insert(
|
||||||
BTR_NO_LOCKING_FLAG | BTR_NO_UNDO_LOG_FLAG,
|
BTR_NO_LOCKING_FLAG | BTR_NO_UNDO_LOG_FLAG,
|
||||||
|
|
@ -3760,9 +3672,6 @@ ibuf_insert_to_index_page_low(
|
||||||
page_cur_t* page_cur)/*!< in/out: cursor positioned on the record
|
page_cur_t* page_cur)/*!< in/out: cursor positioned on the record
|
||||||
after which to insert the buffered entry */
|
after which to insert the buffered entry */
|
||||||
{
|
{
|
||||||
const page_t* page;
|
|
||||||
const page_t* bitmap_page;
|
|
||||||
ulint old_bits;
|
|
||||||
rec_t* rec;
|
rec_t* rec;
|
||||||
DBUG_ENTER("ibuf_insert_to_index_page_low");
|
DBUG_ENTER("ibuf_insert_to_index_page_low");
|
||||||
|
|
||||||
|
|
@ -3790,11 +3699,10 @@ ibuf_insert_to_index_page_low(
|
||||||
DBUG_RETURN(rec);
|
DBUG_RETURN(rec);
|
||||||
}
|
}
|
||||||
|
|
||||||
page = buf_block_get_frame(block);
|
|
||||||
|
|
||||||
ib::error() << "Insert buffer insert fails; page free "
|
ib::error() << "Insert buffer insert fails; page free "
|
||||||
<< page_get_max_insert_size(page, 1) << ", dtuple size "
|
<< page_get_max_insert_size(block->frame, 1)
|
||||||
<< rec_get_converted_size(index, entry, 0);
|
<< ", dtuple size "
|
||||||
|
<< rec_get_converted_size(index, entry, 0);
|
||||||
|
|
||||||
fputs("InnoDB: Cannot insert index record ", stderr);
|
fputs("InnoDB: Cannot insert index record ", stderr);
|
||||||
dtuple_print(stderr, entry);
|
dtuple_print(stderr, entry);
|
||||||
|
|
@ -3802,14 +3710,14 @@ ibuf_insert_to_index_page_low(
|
||||||
"InnoDB: is now probably corrupt. Please run CHECK TABLE on\n"
|
"InnoDB: is now probably corrupt. Please run CHECK TABLE on\n"
|
||||||
"InnoDB: that table.\n", stderr);
|
"InnoDB: that table.\n", stderr);
|
||||||
|
|
||||||
bitmap_page = ibuf_bitmap_get_map_page(block->page.id,
|
|
||||||
block->zip_size(), mtr);
|
|
||||||
old_bits = ibuf_bitmap_page_get_bits(
|
|
||||||
bitmap_page, block->page.id, block->zip_size(),
|
|
||||||
IBUF_BITMAP_FREE, mtr);
|
|
||||||
|
|
||||||
ib::error() << "page " << block->page.id << ", size "
|
ib::error() << "page " << block->page.id << ", size "
|
||||||
<< block->physical_size() << ", bitmap bits " << old_bits;
|
<< block->physical_size() << ", bitmap bits "
|
||||||
|
<< ibuf_bitmap_page_get_bits(
|
||||||
|
ibuf_bitmap_get_map_page(block->page.id,
|
||||||
|
block->zip_size(),
|
||||||
|
mtr)->frame,
|
||||||
|
block->page.id, block->zip_size(),
|
||||||
|
IBUF_BITMAP_FREE, mtr);
|
||||||
|
|
||||||
ib::error() << BUG_REPORT_MSG;
|
ib::error() << BUG_REPORT_MSG;
|
||||||
|
|
||||||
|
|
@ -3898,7 +3806,6 @@ ibuf_insert_to_index_page(
|
||||||
|
|
||||||
if (UNIV_UNLIKELY(low_match == dtuple_get_n_fields(entry))) {
|
if (UNIV_UNLIKELY(low_match == dtuple_get_n_fields(entry))) {
|
||||||
upd_t* update;
|
upd_t* update;
|
||||||
page_zip_des_t* page_zip;
|
|
||||||
|
|
||||||
rec = page_cur_get_rec(&page_cur);
|
rec = page_cur_get_rec(&page_cur);
|
||||||
|
|
||||||
|
|
@ -3910,8 +3817,7 @@ ibuf_insert_to_index_page(
|
||||||
ULINT_UNDEFINED, &heap);
|
ULINT_UNDEFINED, &heap);
|
||||||
update = row_upd_build_sec_rec_difference_binary(
|
update = row_upd_build_sec_rec_difference_binary(
|
||||||
rec, index, offsets, entry, heap);
|
rec, index, offsets, entry, heap);
|
||||||
|
page_zip_des_t* page_zip = buf_block_get_page_zip(block);
|
||||||
page_zip = buf_block_get_page_zip(block);
|
|
||||||
|
|
||||||
if (update->n_fields == 0) {
|
if (update->n_fields == 0) {
|
||||||
/* The records only differ in the delete-mark.
|
/* The records only differ in the delete-mark.
|
||||||
|
|
@ -4023,7 +3929,7 @@ ibuf_set_del_mark(
|
||||||
|
|
||||||
if (low_match == dtuple_get_n_fields(entry)) {
|
if (low_match == dtuple_get_n_fields(entry)) {
|
||||||
rec_t* rec;
|
rec_t* rec;
|
||||||
page_zip_des_t* page_zip;
|
page_zip_des_t* page_zip;
|
||||||
|
|
||||||
rec = page_cur_get_rec(&page_cur);
|
rec = page_cur_get_rec(&page_cur);
|
||||||
page_zip = page_cur_get_page_zip(&page_cur);
|
page_zip = page_cur_get_page_zip(&page_cur);
|
||||||
|
|
@ -4272,7 +4178,7 @@ bool ibuf_delete_rec(ulint space, ulint page_no, btr_pcur_t* pcur,
|
||||||
goto func_exit;
|
goto func_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
root = ibuf_tree_root_get(mtr);
|
root = ibuf_tree_root_get(mtr)->frame;
|
||||||
|
|
||||||
btr_cur_pessimistic_delete(&err, TRUE, btr_pcur_get_btr_cur(pcur), 0,
|
btr_cur_pessimistic_delete(&err, TRUE, btr_pcur_get_btr_cur(pcur), 0,
|
||||||
false, mtr);
|
false, mtr);
|
||||||
|
|
@ -4317,10 +4223,10 @@ bool ibuf_page_exists(const buf_page_t& bpage)
|
||||||
bool bitmap_bits = false;
|
bool bitmap_bits = false;
|
||||||
|
|
||||||
ibuf_mtr_start(&mtr);
|
ibuf_mtr_start(&mtr);
|
||||||
if (const page_t* bitmap_page = ibuf_bitmap_get_map_page(
|
if (const buf_block_t* bitmap_page = ibuf_bitmap_get_map_page(
|
||||||
bpage.id, bpage.zip_size(), &mtr)) {
|
bpage.id, bpage.zip_size(), &mtr)) {
|
||||||
bitmap_bits = ibuf_bitmap_page_get_bits(
|
bitmap_bits = ibuf_bitmap_page_get_bits(
|
||||||
bitmap_page, bpage.id, bpage.zip_size(),
|
bitmap_page->frame, bpage.id, bpage.zip_size(),
|
||||||
IBUF_BITMAP_BUFFERED, &mtr) != 0;
|
IBUF_BITMAP_BUFFERED, &mtr) != 0;
|
||||||
}
|
}
|
||||||
ibuf_mtr_commit(&mtr);
|
ibuf_mtr_commit(&mtr);
|
||||||
|
|
@ -4351,7 +4257,6 @@ ibuf_merge_or_delete_for_page(
|
||||||
#ifdef UNIV_IBUF_DEBUG
|
#ifdef UNIV_IBUF_DEBUG
|
||||||
ulint volume = 0;
|
ulint volume = 0;
|
||||||
#endif /* UNIV_IBUF_DEBUG */
|
#endif /* UNIV_IBUF_DEBUG */
|
||||||
page_zip_des_t* page_zip = NULL;
|
|
||||||
bool corruption_noticed = false;
|
bool corruption_noticed = false;
|
||||||
mtr_t mtr;
|
mtr_t mtr;
|
||||||
|
|
||||||
|
|
@ -4385,18 +4290,18 @@ ibuf_merge_or_delete_for_page(
|
||||||
block = NULL;
|
block = NULL;
|
||||||
update_ibuf_bitmap = false;
|
update_ibuf_bitmap = false;
|
||||||
} else {
|
} else {
|
||||||
page_t* bitmap_page = NULL;
|
|
||||||
ulint bitmap_bits = 0;
|
ulint bitmap_bits = 0;
|
||||||
|
|
||||||
ibuf_mtr_start(&mtr);
|
ibuf_mtr_start(&mtr);
|
||||||
|
|
||||||
bitmap_page = ibuf_bitmap_get_map_page(
|
buf_block_t* bitmap_page = ibuf_bitmap_get_map_page(
|
||||||
page_id, zip_size, &mtr);
|
page_id, zip_size, &mtr);
|
||||||
|
|
||||||
if (bitmap_page &&
|
if (bitmap_page
|
||||||
fil_page_get_type(bitmap_page) != FIL_PAGE_TYPE_ALLOCATED) {
|
&& fil_page_get_type(bitmap_page->frame)
|
||||||
|
!= FIL_PAGE_TYPE_ALLOCATED) {
|
||||||
bitmap_bits = ibuf_bitmap_page_get_bits(
|
bitmap_bits = ibuf_bitmap_page_get_bits(
|
||||||
bitmap_page, page_id, zip_size,
|
bitmap_page->frame, page_id, zip_size,
|
||||||
IBUF_BITMAP_BUFFERED, &mtr);
|
IBUF_BITMAP_BUFFERED, &mtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4429,7 +4334,6 @@ ibuf_merge_or_delete_for_page(
|
||||||
the debug checks. */
|
the debug checks. */
|
||||||
|
|
||||||
rw_lock_x_lock_move_ownership(&(block->lock));
|
rw_lock_x_lock_move_ownership(&(block->lock));
|
||||||
page_zip = buf_block_get_page_zip(block);
|
|
||||||
|
|
||||||
if (!fil_page_index_page_check(block->frame)
|
if (!fil_page_index_page_check(block->frame)
|
||||||
|| !page_is_leaf(block->frame)) {
|
|| !page_is_leaf(block->frame)) {
|
||||||
|
|
@ -4496,8 +4400,7 @@ ibuf_merge_or_delete_for_page(
|
||||||
|| ibuf_rec_get_space(&mtr, rec) != page_id.space()) {
|
|| ibuf_rec_get_space(&mtr, rec) != page_id.space()) {
|
||||||
|
|
||||||
if (block != NULL) {
|
if (block != NULL) {
|
||||||
page_header_reset_last_insert(
|
page_header_reset_last_insert(block, &mtr);
|
||||||
block->frame, page_zip, &mtr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
goto reset_bit;
|
goto reset_bit;
|
||||||
|
|
@ -4519,8 +4422,9 @@ ibuf_merge_or_delete_for_page(
|
||||||
ibuf_op_t op = ibuf_rec_get_op_type(&mtr, rec);
|
ibuf_op_t op = ibuf_rec_get_op_type(&mtr, rec);
|
||||||
|
|
||||||
max_trx_id = page_get_max_trx_id(page_align(rec));
|
max_trx_id = page_get_max_trx_id(page_align(rec));
|
||||||
page_update_max_trx_id(block, page_zip, max_trx_id,
|
page_update_max_trx_id(block,
|
||||||
&mtr);
|
buf_block_get_page_zip(block),
|
||||||
|
max_trx_id, &mtr);
|
||||||
|
|
||||||
ut_ad(page_validate(page_align(rec), ibuf.index));
|
ut_ad(page_validate(page_align(rec), ibuf.index));
|
||||||
|
|
||||||
|
|
@ -4635,28 +4539,17 @@ ibuf_merge_or_delete_for_page(
|
||||||
}
|
}
|
||||||
|
|
||||||
reset_bit:
|
reset_bit:
|
||||||
if (update_ibuf_bitmap) {
|
if (!update_ibuf_bitmap) {
|
||||||
page_t* bitmap_page;
|
} else if (buf_block_t* bitmap = ibuf_bitmap_get_map_page(
|
||||||
|
page_id, zip_size, &mtr)) {
|
||||||
bitmap_page = ibuf_bitmap_get_map_page(page_id, zip_size,
|
/* FIXME: update the bitmap byte only once! */
|
||||||
&mtr);
|
ibuf_bitmap_page_set_bits<IBUF_BITMAP_BUFFERED>(
|
||||||
|
bitmap, page_id, physical_size, false, &mtr);
|
||||||
ibuf_bitmap_page_set_bits(
|
|
||||||
bitmap_page, page_id, physical_size,
|
|
||||||
IBUF_BITMAP_BUFFERED, FALSE, &mtr);
|
|
||||||
|
|
||||||
if (block != NULL) {
|
if (block != NULL) {
|
||||||
ulint old_bits = ibuf_bitmap_page_get_bits(
|
ibuf_bitmap_page_set_bits<IBUF_BITMAP_FREE>(
|
||||||
bitmap_page, page_id, zip_size,
|
bitmap, page_id, physical_size,
|
||||||
IBUF_BITMAP_FREE, &mtr);
|
ibuf_index_page_calc_free(block), &mtr);
|
||||||
|
|
||||||
ulint new_bits = ibuf_index_page_calc_free(block);
|
|
||||||
|
|
||||||
if (old_bits != new_bits) {
|
|
||||||
ibuf_bitmap_page_set_bits(
|
|
||||||
bitmap_page, page_id, physical_size,
|
|
||||||
IBUF_BITMAP_FREE, new_bits, &mtr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4760,18 +4653,15 @@ bool
|
||||||
ibuf_is_empty(void)
|
ibuf_is_empty(void)
|
||||||
/*===============*/
|
/*===============*/
|
||||||
{
|
{
|
||||||
bool is_empty;
|
|
||||||
const page_t* root;
|
|
||||||
mtr_t mtr;
|
mtr_t mtr;
|
||||||
|
|
||||||
ibuf_mtr_start(&mtr);
|
ibuf_mtr_start(&mtr);
|
||||||
|
|
||||||
mutex_enter(&ibuf_mutex);
|
ut_d(mutex_enter(&ibuf_mutex));
|
||||||
root = ibuf_tree_root_get(&mtr);
|
const buf_block_t* root = ibuf_tree_root_get(&mtr);
|
||||||
mutex_exit(&ibuf_mutex);
|
bool is_empty = page_is_empty(root->frame);
|
||||||
|
|
||||||
is_empty = page_is_empty(root);
|
|
||||||
ut_a(is_empty == ibuf.empty);
|
ut_a(is_empty == ibuf.empty);
|
||||||
|
ut_d(mutex_exit(&ibuf_mutex));
|
||||||
ibuf_mtr_commit(&mtr);
|
ibuf_mtr_commit(&mtr);
|
||||||
|
|
||||||
return(is_empty);
|
return(is_empty);
|
||||||
|
|
@ -4849,9 +4739,6 @@ dberr_t ibuf_check_bitmap_on_import(const trx_t* trx, fil_space_t* space)
|
||||||
the space, as usual. */
|
the space, as usual. */
|
||||||
|
|
||||||
for (page_no = 0; page_no < size; page_no += physical_size) {
|
for (page_no = 0; page_no < size; page_no += physical_size) {
|
||||||
page_t* bitmap_page;
|
|
||||||
ulint i;
|
|
||||||
|
|
||||||
if (trx_is_interrupted(trx)) {
|
if (trx_is_interrupted(trx)) {
|
||||||
mutex_exit(&ibuf_mutex);
|
mutex_exit(&ibuf_mutex);
|
||||||
return(DB_INTERRUPTED);
|
return(DB_INTERRUPTED);
|
||||||
|
|
@ -4863,10 +4750,15 @@ dberr_t ibuf_check_bitmap_on_import(const trx_t* trx, fil_space_t* space)
|
||||||
|
|
||||||
ibuf_enter(&mtr);
|
ibuf_enter(&mtr);
|
||||||
|
|
||||||
bitmap_page = ibuf_bitmap_get_map_page(
|
buf_block_t* bitmap_page = ibuf_bitmap_get_map_page(
|
||||||
page_id_t(space->id, page_no), zip_size, &mtr);
|
page_id_t(space->id, page_no), zip_size, &mtr);
|
||||||
|
if (!bitmap_page) {
|
||||||
|
mutex_exit(&ibuf_mutex);
|
||||||
|
mtr.commit();
|
||||||
|
return DB_CORRUPTION;
|
||||||
|
}
|
||||||
|
|
||||||
if (buf_page_is_zeroes(bitmap_page, physical_size)) {
|
if (buf_page_is_zeroes(bitmap_page->frame, physical_size)) {
|
||||||
/* This means we got all-zero page instead of
|
/* This means we got all-zero page instead of
|
||||||
ibuf bitmap page. The subsequent page should be
|
ibuf bitmap page. The subsequent page should be
|
||||||
all-zero pages. */
|
all-zero pages. */
|
||||||
|
|
@ -4886,17 +4778,13 @@ dberr_t ibuf_check_bitmap_on_import(const trx_t* trx, fil_space_t* space)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bitmap_page) {
|
for (ulint i = FSP_IBUF_BITMAP_OFFSET + 1; i < physical_size;
|
||||||
mutex_exit(&ibuf_mutex);
|
i++) {
|
||||||
return DB_CORRUPTION;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = FSP_IBUF_BITMAP_OFFSET + 1; i < physical_size; i++) {
|
|
||||||
const ulint offset = page_no + i;
|
const ulint offset = page_no + i;
|
||||||
const page_id_t cur_page_id(space->id, offset);
|
const page_id_t cur_page_id(space->id, offset);
|
||||||
|
|
||||||
if (ibuf_bitmap_page_get_bits(
|
if (ibuf_bitmap_page_get_bits(
|
||||||
bitmap_page, cur_page_id, zip_size,
|
bitmap_page->frame, cur_page_id, zip_size,
|
||||||
IBUF_BITMAP_IBUF, &mtr)) {
|
IBUF_BITMAP_IBUF, &mtr)) {
|
||||||
|
|
||||||
mutex_exit(&ibuf_mutex);
|
mutex_exit(&ibuf_mutex);
|
||||||
|
|
@ -4914,7 +4802,7 @@ dberr_t ibuf_check_bitmap_on_import(const trx_t* trx, fil_space_t* space)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ibuf_bitmap_page_get_bits(
|
if (ibuf_bitmap_page_get_bits(
|
||||||
bitmap_page, cur_page_id, zip_size,
|
bitmap_page->frame, cur_page_id, zip_size,
|
||||||
IBUF_BITMAP_BUFFERED, &mtr)) {
|
IBUF_BITMAP_BUFFERED, &mtr)) {
|
||||||
|
|
||||||
ib_errf(trx->mysql_thd,
|
ib_errf(trx->mysql_thd,
|
||||||
|
|
@ -4928,10 +4816,9 @@ dberr_t ibuf_check_bitmap_on_import(const trx_t* trx, fil_space_t* space)
|
||||||
/* Tolerate this error, so that
|
/* Tolerate this error, so that
|
||||||
slightly corrupted tables can be
|
slightly corrupted tables can be
|
||||||
imported and dumped. Clear the bit. */
|
imported and dumped. Clear the bit. */
|
||||||
ibuf_bitmap_page_set_bits(
|
ibuf_bitmap_page_set_bits<IBUF_BITMAP_BUFFERED>(
|
||||||
bitmap_page, cur_page_id,
|
bitmap_page, cur_page_id,
|
||||||
physical_size,
|
physical_size, false, &mtr);
|
||||||
IBUF_BITMAP_BUFFERED, FALSE, &mtr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4951,7 +4838,6 @@ ibuf_set_bitmap_for_bulk_load(
|
||||||
buf_block_t* block,
|
buf_block_t* block,
|
||||||
bool reset)
|
bool reset)
|
||||||
{
|
{
|
||||||
page_t* bitmap_page;
|
|
||||||
mtr_t mtr;
|
mtr_t mtr;
|
||||||
ulint free_val;
|
ulint free_val;
|
||||||
|
|
||||||
|
|
@ -4959,20 +4845,22 @@ ibuf_set_bitmap_for_bulk_load(
|
||||||
|
|
||||||
free_val = ibuf_index_page_calc_free(block);
|
free_val = ibuf_index_page_calc_free(block);
|
||||||
|
|
||||||
mtr_start(&mtr);
|
mtr.start();
|
||||||
fil_space_t* space = mtr.set_named_space_id(block->page.id.space());
|
fil_space_t* space = mtr.set_named_space_id(block->page.id.space());
|
||||||
|
|
||||||
bitmap_page = ibuf_bitmap_get_map_page(block->page.id,
|
buf_block_t* bitmap_page = ibuf_bitmap_get_map_page(block->page.id,
|
||||||
space->zip_size(), &mtr);
|
space->zip_size(),
|
||||||
|
&mtr);
|
||||||
|
|
||||||
free_val = reset ? 0 : ibuf_index_page_calc_free(block);
|
free_val = reset ? 0 : ibuf_index_page_calc_free(block);
|
||||||
ibuf_bitmap_page_set_bits(
|
/* FIXME: update the bitmap byte only once! */
|
||||||
|
ibuf_bitmap_page_set_bits<IBUF_BITMAP_FREE>(
|
||||||
bitmap_page, block->page.id, block->physical_size(),
|
bitmap_page, block->page.id, block->physical_size(),
|
||||||
IBUF_BITMAP_FREE, free_val, &mtr);
|
free_val, &mtr);
|
||||||
|
|
||||||
ibuf_bitmap_page_set_bits(
|
ibuf_bitmap_page_set_bits<IBUF_BITMAP_BUFFERED>(
|
||||||
bitmap_page, block->page.id, block->physical_size(),
|
bitmap_page, block->page.id, block->physical_size(),
|
||||||
IBUF_BITMAP_BUFFERED, FALSE, &mtr);
|
false, &mtr);
|
||||||
|
|
||||||
mtr_commit(&mtr);
|
mtr.commit();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -541,7 +541,7 @@ inline void btr_set_min_rec_mark(rec_t *rec, const buf_block_t &block,
|
||||||
page. We are not modifying the compressed page frame at all. */
|
page. We are not modifying the compressed page frame at all. */
|
||||||
*rec|= REC_INFO_MIN_REC_FLAG;
|
*rec|= REC_INFO_MIN_REC_FLAG;
|
||||||
else
|
else
|
||||||
mlog_write_ulint(rec, *rec | REC_INFO_MIN_REC_FLAG, MLOG_1BYTE, mtr);
|
mtr->write<1>(block, rec, *rec | REC_INFO_MIN_REC_FLAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Seek to the parent page of a B-tree page.
|
/** Seek to the parent page of a B-tree page.
|
||||||
|
|
|
||||||
|
|
@ -29,28 +29,6 @@ Created 6/2/1994 Heikki Tuuri
|
||||||
#include "mtr0log.h"
|
#include "mtr0log.h"
|
||||||
#include "page0zip.h"
|
#include "page0zip.h"
|
||||||
|
|
||||||
/**************************************************************//**
|
|
||||||
Sets the index id field of a page. */
|
|
||||||
UNIV_INLINE
|
|
||||||
void
|
|
||||||
btr_page_set_index_id(
|
|
||||||
/*==================*/
|
|
||||||
page_t* page, /*!< in: page to be created */
|
|
||||||
page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
|
|
||||||
part will be updated, or NULL */
|
|
||||||
index_id_t id, /*!< in: index id */
|
|
||||||
mtr_t* mtr) /*!< in: mtr */
|
|
||||||
{
|
|
||||||
if (page_zip) {
|
|
||||||
mach_write_to_8(page + (PAGE_HEADER + PAGE_INDEX_ID), id);
|
|
||||||
page_zip_write_header(page_zip,
|
|
||||||
page + (PAGE_HEADER + PAGE_INDEX_ID),
|
|
||||||
8, mtr);
|
|
||||||
} else {
|
|
||||||
mlog_write_ull(page + (PAGE_HEADER + PAGE_INDEX_ID), id, mtr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**************************************************************//**
|
/**************************************************************//**
|
||||||
Gets the index id field of a page.
|
Gets the index id field of a page.
|
||||||
@return index id */
|
@return index id */
|
||||||
|
|
@ -63,77 +41,56 @@ btr_page_get_index_id(
|
||||||
return(mach_read_from_8(page + PAGE_HEADER + PAGE_INDEX_ID));
|
return(mach_read_from_8(page + PAGE_HEADER + PAGE_INDEX_ID));
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************//**
|
/** Set PAGE_LEVEL.
|
||||||
Sets the node level field in an index page. */
|
@param[in,out] block buffer block
|
||||||
UNIV_INLINE
|
@param[in] level page level
|
||||||
void
|
@param[in,out] mtr mini-transaction */
|
||||||
btr_page_set_level(
|
inline
|
||||||
/*===============*/
|
void btr_page_set_level(buf_block_t *block, ulint level, mtr_t *mtr)
|
||||||
page_t* page, /*!< in: index page */
|
|
||||||
page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
|
|
||||||
part will be updated, or NULL */
|
|
||||||
ulint level, /*!< in: level, leaf level == 0 */
|
|
||||||
mtr_t* mtr) /*!< in: mini-transaction handle */
|
|
||||||
{
|
{
|
||||||
ut_ad(page != NULL);
|
ut_ad(level <= BTR_MAX_NODE_LEVEL);
|
||||||
ut_ad(mtr != NULL);
|
|
||||||
ut_ad(level <= BTR_MAX_NODE_LEVEL);
|
|
||||||
|
|
||||||
if (page_zip) {
|
byte *page_level= PAGE_HEADER + PAGE_LEVEL + block->frame;
|
||||||
mach_write_to_2(page + (PAGE_HEADER + PAGE_LEVEL), level);
|
|
||||||
page_zip_write_header(page_zip,
|
if (UNIV_LIKELY_NULL(block->page.zip.data))
|
||||||
page + (PAGE_HEADER + PAGE_LEVEL),
|
{
|
||||||
2, mtr);
|
mach_write_to_2(page_level, level);
|
||||||
} else {
|
page_zip_write_header(&block->page.zip, page_level, 2, mtr);
|
||||||
mlog_write_ulint(page + (PAGE_HEADER + PAGE_LEVEL), level,
|
}
|
||||||
MLOG_2BYTES, mtr);
|
else
|
||||||
}
|
mtr->write<2,mtr_t::OPT>(*block, page_level, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************//**
|
/** Set FIL_PAGE_NEXT.
|
||||||
Sets the next index page field. */
|
@param[in,out] block buffer block
|
||||||
UNIV_INLINE
|
@param[in] next number of successor page
|
||||||
void
|
@param[in,out] mtr mini-transaction */
|
||||||
btr_page_set_next(
|
inline void btr_page_set_next(buf_block_t *block, ulint next, mtr_t *mtr)
|
||||||
/*==============*/
|
|
||||||
page_t* page, /*!< in: index page */
|
|
||||||
page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
|
|
||||||
part will be updated, or NULL */
|
|
||||||
ulint next, /*!< in: next page number */
|
|
||||||
mtr_t* mtr) /*!< in: mini-transaction handle */
|
|
||||||
{
|
{
|
||||||
ut_ad(page != NULL);
|
byte *fil_page_next= block->frame + FIL_PAGE_NEXT;
|
||||||
ut_ad(mtr != NULL);
|
if (UNIV_LIKELY_NULL(block->page.zip.data))
|
||||||
|
{
|
||||||
if (page_zip) {
|
mach_write_to_4(fil_page_next, next);
|
||||||
mach_write_to_4(page + FIL_PAGE_NEXT, next);
|
page_zip_write_header(&block->page.zip, fil_page_next, 4, mtr);
|
||||||
page_zip_write_header(page_zip, page + FIL_PAGE_NEXT, 4, mtr);
|
}
|
||||||
} else {
|
else
|
||||||
mlog_write_ulint(page + FIL_PAGE_NEXT, next, MLOG_4BYTES, mtr);
|
mtr->write<4>(*block, fil_page_next, next);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************//**
|
/** Set FIL_PAGE_PREV.
|
||||||
Sets the previous index page field. */
|
@param[in,out] block buffer block
|
||||||
UNIV_INLINE
|
@param[in] prev number of predecessor page
|
||||||
void
|
@param[in,out] mtr mini-transaction */
|
||||||
btr_page_set_prev(
|
inline void btr_page_set_prev(buf_block_t *block, ulint prev, mtr_t *mtr)
|
||||||
/*==============*/
|
|
||||||
page_t* page, /*!< in: index page */
|
|
||||||
page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
|
|
||||||
part will be updated, or NULL */
|
|
||||||
ulint prev, /*!< in: previous page number */
|
|
||||||
mtr_t* mtr) /*!< in: mini-transaction handle */
|
|
||||||
{
|
{
|
||||||
ut_ad(page != NULL);
|
byte *fil_page_prev= block->frame + FIL_PAGE_PREV;
|
||||||
ut_ad(mtr != NULL);
|
if (UNIV_LIKELY_NULL(block->page.zip.data))
|
||||||
|
{
|
||||||
if (page_zip) {
|
mach_write_to_4(fil_page_prev, prev);
|
||||||
mach_write_to_4(page + FIL_PAGE_PREV, prev);
|
page_zip_write_header(&block->page.zip, fil_page_prev, 4, mtr);
|
||||||
page_zip_write_header(page_zip, page + FIL_PAGE_PREV, 4, mtr);
|
}
|
||||||
} else {
|
else
|
||||||
mlog_write_ulint(page + FIL_PAGE_PREV, prev, MLOG_4BYTES, mtr);
|
mtr->write<4>(*block, fil_page_prev, prev);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************//**
|
/**************************************************************//**
|
||||||
|
|
|
||||||
|
|
@ -101,11 +101,25 @@ class PageBulk
|
||||||
/** Insert a record in the page.
|
/** Insert a record in the page.
|
||||||
@param[in] rec record
|
@param[in] rec record
|
||||||
@param[in] offsets record offsets */
|
@param[in] offsets record offsets */
|
||||||
void insert(const rec_t* rec, ulint* offsets);
|
inline void insert(const rec_t* rec, ulint* offsets);
|
||||||
|
private:
|
||||||
|
/** Page format */
|
||||||
|
enum format { REDUNDANT, DYNAMIC, COMPRESSED };
|
||||||
|
/** Mark end of insertion to the page. Scan all records to set page
|
||||||
|
dirs, and set page header members.
|
||||||
|
@tparam format the page format */
|
||||||
|
template<format> inline void finishPage();
|
||||||
|
/** Insert a record in the page.
|
||||||
|
@tparam format the page format
|
||||||
|
@param[in] rec record
|
||||||
|
@param[in] offsets record offsets */
|
||||||
|
template<format> inline void insertPage(const rec_t* rec,
|
||||||
|
ulint* offsets);
|
||||||
|
|
||||||
|
public:
|
||||||
/** Mark end of insertion to the page. Scan all records to set page
|
/** Mark end of insertion to the page. Scan all records to set page
|
||||||
dirs, and set page header members. */
|
dirs, and set page header members. */
|
||||||
void finish();
|
inline void finish();
|
||||||
|
|
||||||
/** Commit mtr for a page
|
/** Commit mtr for a page
|
||||||
@param[in] success Flag whether all inserts succeed. */
|
@param[in] success Flag whether all inserts succeed. */
|
||||||
|
|
@ -199,6 +213,8 @@ class PageBulk
|
||||||
return(m_err);
|
return(m_err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_modified() { m_mtr.set_modified(); }
|
||||||
|
|
||||||
/* Memory heap for internal allocation */
|
/* Memory heap for internal allocation */
|
||||||
mem_heap_t* m_heap;
|
mem_heap_t* m_heap;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -646,8 +646,7 @@ to free the field. */
|
||||||
void
|
void
|
||||||
btr_cur_disown_inherited_fields(
|
btr_cur_disown_inherited_fields(
|
||||||
/*============================*/
|
/*============================*/
|
||||||
page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed
|
buf_block_t* block, /*!< in/out: index page */
|
||||||
part will be updated, or NULL */
|
|
||||||
rec_t* rec, /*!< in/out: record in a clustered index */
|
rec_t* rec, /*!< in/out: record in a clustered index */
|
||||||
dict_index_t* index, /*!< in: index of the page */
|
dict_index_t* index, /*!< in: index of the page */
|
||||||
const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
|
const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
|
||||||
|
|
@ -722,12 +721,12 @@ btr_free_externally_stored_field(
|
||||||
page_zip_write_blob_ptr(), or NULL */
|
page_zip_write_blob_ptr(), or NULL */
|
||||||
const ulint* offsets, /*!< in: rec_get_offsets(rec, index),
|
const ulint* offsets, /*!< in: rec_get_offsets(rec, index),
|
||||||
or NULL */
|
or NULL */
|
||||||
page_zip_des_t* page_zip, /*!< in: compressed page corresponding
|
buf_block_t* block, /*!< in/out: page of field_ref */
|
||||||
to rec, or NULL if rec == NULL */
|
|
||||||
ulint i, /*!< in: field number of field_ref;
|
ulint i, /*!< in: field number of field_ref;
|
||||||
ignored if rec == NULL */
|
ignored if rec == NULL */
|
||||||
bool rollback, /*!< in: performing rollback? */
|
bool rollback, /*!< in: performing rollback? */
|
||||||
mtr_t* local_mtr); /*!< in: mtr containing the latch */
|
mtr_t* local_mtr) /*!< in: mtr containing the latch */
|
||||||
|
MY_ATTRIBUTE((nonnull(1,2,5,8)));
|
||||||
|
|
||||||
/** Copies the prefix of an externally stored field of a record.
|
/** Copies the prefix of an externally stored field of a record.
|
||||||
The clustered index record must be protected by a lock or a page latch.
|
The clustered index record must be protected by a lock or a page latch.
|
||||||
|
|
|
||||||
|
|
@ -716,16 +716,6 @@ inline void aligned_free(void *ptr)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************//**
|
|
||||||
Gets the space id, page offset, and byte offset within page of a
|
|
||||||
pointer pointing to a buffer frame containing a file page. */
|
|
||||||
UNIV_INLINE
|
|
||||||
void
|
|
||||||
buf_ptr_get_fsp_addr(
|
|
||||||
/*=================*/
|
|
||||||
const void* ptr, /*!< in: pointer to a buffer frame */
|
|
||||||
ulint* space, /*!< out: space id */
|
|
||||||
fil_addr_t* addr); /*!< out: page offset and byte offset */
|
|
||||||
/**********************************************************************//**
|
/**********************************************************************//**
|
||||||
Gets the hash value of a block. This can be used in searches in the
|
Gets the hash value of a block. This can be used in searches in the
|
||||||
lock hash table.
|
lock hash table.
|
||||||
|
|
@ -1094,9 +1084,9 @@ buf_block_get_frame(
|
||||||
Gets the compressed page descriptor corresponding to an uncompressed page
|
Gets the compressed page descriptor corresponding to an uncompressed page
|
||||||
if applicable. */
|
if applicable. */
|
||||||
#define buf_block_get_page_zip(block) \
|
#define buf_block_get_page_zip(block) \
|
||||||
((block)->page.zip.data ? &(block)->page.zip : NULL)
|
(UNIV_LIKELY_NULL((block)->page.zip.data) ? &(block)->page.zip : NULL)
|
||||||
#define is_buf_block_get_page_zip(block) \
|
#define is_buf_block_get_page_zip(block) \
|
||||||
((block)->page.zip.data != 0)
|
UNIV_LIKELY_NULL((block)->page.zip.data)
|
||||||
|
|
||||||
#ifdef BTR_CUR_HASH_ADAPT
|
#ifdef BTR_CUR_HASH_ADAPT
|
||||||
/** Get a buffer block from an adaptive hash index pointer.
|
/** Get a buffer block from an adaptive hash index pointer.
|
||||||
|
|
|
||||||
|
|
@ -758,25 +758,6 @@ buf_frame_align(
|
||||||
return(frame);
|
return(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************//**
|
|
||||||
Gets the space id, page offset, and byte offset within page of a
|
|
||||||
pointer pointing to a buffer frame containing a file page. */
|
|
||||||
UNIV_INLINE
|
|
||||||
void
|
|
||||||
buf_ptr_get_fsp_addr(
|
|
||||||
/*=================*/
|
|
||||||
const void* ptr, /*!< in: pointer to a buffer frame */
|
|
||||||
ulint* space, /*!< out: space id */
|
|
||||||
fil_addr_t* addr) /*!< out: page offset and byte offset */
|
|
||||||
{
|
|
||||||
const page_t* page = (const page_t*) ut_align_down(ptr,
|
|
||||||
srv_page_size);
|
|
||||||
|
|
||||||
*space = mach_read_from_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
|
|
||||||
addr->page = mach_read_from_4(page + FIL_PAGE_OFFSET);
|
|
||||||
addr->boffset = static_cast<uint16_t>(ut_align_offset(ptr, srv_page_size));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************************************************************//**
|
/**********************************************************************//**
|
||||||
Gets the hash value of the page the pointer is pointing to. This can be used
|
Gets the hash value of the page the pointer is pointing to. This can be used
|
||||||
in searches in the lock hash table.
|
in searches in the lock hash table.
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||||
Copyright (c) 2018, MariaDB Corporation.
|
Copyright (c) 2018, 2019, MariaDB Corporation.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
the terms of the GNU General Public License as published by the Free Software
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
|
@ -33,15 +33,8 @@ Created 4/18/1996 Heikki Tuuri
|
||||||
#include "buf0buf.h"
|
#include "buf0buf.h"
|
||||||
#include "dict0dict.h"
|
#include "dict0dict.h"
|
||||||
|
|
||||||
typedef byte dict_hdr_t;
|
/** @return the DICT_HDR block, x-latched */
|
||||||
|
buf_block_t *dict_hdr_get(mtr_t* mtr);
|
||||||
/**********************************************************************//**
|
|
||||||
Gets a pointer to the dictionary header and x-latches its page.
|
|
||||||
@return pointer to the dictionary header, page x-latched */
|
|
||||||
dict_hdr_t*
|
|
||||||
dict_hdr_get(
|
|
||||||
/*=========*/
|
|
||||||
mtr_t* mtr); /*!< in: mtr */
|
|
||||||
/**********************************************************************//**
|
/**********************************************************************//**
|
||||||
Returns a new table, index, or space id. */
|
Returns a new table, index, or space id. */
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,6 @@ see the table in fsp0types.h @{ */
|
||||||
#define FSP_HEADER_OFFSET FIL_PAGE_DATA
|
#define FSP_HEADER_OFFSET FIL_PAGE_DATA
|
||||||
|
|
||||||
/* The data structures in files are defined just as byte strings in C */
|
/* The data structures in files are defined just as byte strings in C */
|
||||||
typedef byte fsp_header_t;
|
|
||||||
typedef byte xdes_t;
|
typedef byte xdes_t;
|
||||||
|
|
||||||
/* SPACE HEADER
|
/* SPACE HEADER
|
||||||
|
|
@ -207,7 +206,7 @@ typedef byte fseg_inode_t;
|
||||||
(16 + 3 * FLST_BASE_NODE_SIZE \
|
(16 + 3 * FLST_BASE_NODE_SIZE \
|
||||||
+ FSEG_FRAG_ARR_N_SLOTS * FSEG_FRAG_SLOT_SIZE)
|
+ FSEG_FRAG_ARR_N_SLOTS * FSEG_FRAG_SLOT_SIZE)
|
||||||
|
|
||||||
#define FSEG_MAGIC_N_VALUE 97937874
|
static constexpr uint32_t FSEG_MAGIC_N_VALUE= 97937874;
|
||||||
|
|
||||||
#define FSEG_FILLFACTOR 8 /* If this value is x, then if
|
#define FSEG_FILLFACTOR 8 /* If this value is x, then if
|
||||||
the number of unused but reserved
|
the number of unused but reserved
|
||||||
|
|
@ -534,7 +533,7 @@ by repeatedly calling this function in different mini-transactions.
|
||||||
Doing the freeing in a single mini-transaction might result in
|
Doing the freeing in a single mini-transaction might result in
|
||||||
too big a mini-transaction.
|
too big a mini-transaction.
|
||||||
@return TRUE if freeing completed */
|
@return TRUE if freeing completed */
|
||||||
ibool
|
bool
|
||||||
fseg_free_step_func(
|
fseg_free_step_func(
|
||||||
fseg_header_t* header, /*!< in, own: segment header; NOTE: if the header
|
fseg_header_t* header, /*!< in, own: segment header; NOTE: if the header
|
||||||
resides on the first page of the frag list
|
resides on the first page of the frag list
|
||||||
|
|
@ -554,8 +553,8 @@ fseg_free_step_func(
|
||||||
/**********************************************************************//**
|
/**********************************************************************//**
|
||||||
Frees part of a segment. Differs from fseg_free_step because this function
|
Frees part of a segment. Differs from fseg_free_step because this function
|
||||||
leaves the header page unfreed.
|
leaves the header page unfreed.
|
||||||
@return TRUE if freeing completed, except the header page */
|
@return true if freeing completed, except the header page */
|
||||||
ibool
|
bool
|
||||||
fseg_free_step_not_header_func(
|
fseg_free_step_not_header_func(
|
||||||
fseg_header_t* header, /*!< in: segment header which must reside on
|
fseg_header_t* header, /*!< in: segment header which must reside on
|
||||||
the first fragment page of the segment */
|
the first fragment page of the segment */
|
||||||
|
|
|
||||||
|
|
@ -68,79 +68,91 @@ typedef byte flst_node_t;
|
||||||
@param[in,out] block file page
|
@param[in,out] block file page
|
||||||
@param[in] ofs byte offset of the list base node
|
@param[in] ofs byte offset of the list base node
|
||||||
@param[in,out] mtr mini-transaction */
|
@param[in,out] mtr mini-transaction */
|
||||||
inline void flst_init(buf_block_t* block, uint16_t ofs, mtr_t* mtr)
|
inline void flst_init(const buf_block_t* block, uint16_t ofs, mtr_t* mtr)
|
||||||
{
|
{
|
||||||
ut_ad(0 == mach_read_from_2(FLST_LEN + ofs + block->frame));
|
ut_ad(!mach_read_from_2(FLST_LEN + ofs + block->frame));
|
||||||
ut_ad(0 == mach_read_from_2(FLST_FIRST + FIL_ADDR_BYTE + ofs
|
ut_ad(!mach_read_from_2(FLST_FIRST + FIL_ADDR_BYTE + ofs + block->frame));
|
||||||
+ block->frame));
|
ut_ad(!mach_read_from_2(FLST_LAST + FIL_ADDR_BYTE + ofs + block->frame));
|
||||||
ut_ad(0 == mach_read_from_2(FLST_LAST + FIL_ADDR_BYTE + ofs
|
compile_time_assert(FIL_NULL == 0xffU * 0x1010101U);
|
||||||
+ block->frame));
|
mlog_memset(block, FLST_FIRST + FIL_ADDR_PAGE + ofs, 4, 0xff, mtr);
|
||||||
compile_time_assert(FIL_NULL == 0xffU * 0x1010101U);
|
mlog_memset(block, FLST_LAST + FIL_ADDR_PAGE + ofs, 4, 0xff, mtr);
|
||||||
mlog_memset(block, FLST_FIRST + FIL_ADDR_PAGE + ofs, 4, 0xff, mtr);
|
|
||||||
mlog_memset(block, FLST_LAST + FIL_ADDR_PAGE + ofs, 4, 0xff, mtr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Write a null file address.
|
/** Write a null file address.
|
||||||
@param[in,out] faddr file address to be zeroed otu
|
@param[in] b file page
|
||||||
@param[in,out] mtr mini-transaction */
|
@param[in,out] addr file address to be zeroed out
|
||||||
inline void flst_zero_addr(fil_faddr_t* faddr, mtr_t* mtr)
|
@param[in,out] mtr mini-transaction */
|
||||||
|
inline void flst_zero_addr(const buf_block_t& b, fil_faddr_t *addr, mtr_t *mtr)
|
||||||
{
|
{
|
||||||
if (mach_read_from_4(faddr + FIL_ADDR_PAGE) != FIL_NULL) {
|
if (mach_read_from_4(addr + FIL_ADDR_PAGE) != FIL_NULL)
|
||||||
mlog_memset(faddr + FIL_ADDR_PAGE, 4, 0xff, mtr);
|
mlog_memset(&b, ulint(addr - b.frame) + FIL_ADDR_PAGE, 4, 0xff, mtr);
|
||||||
}
|
mtr->write<2,mtr_t::OPT>(b, addr + FIL_ADDR_BYTE, 0U);
|
||||||
if (mach_read_from_2(faddr + FIL_ADDR_BYTE)) {
|
|
||||||
mlog_write_ulint(faddr + FIL_ADDR_BYTE, 0, MLOG_2BYTES, mtr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************//**
|
/** Write a file address.
|
||||||
Initializes a list base node. */
|
@param[in] block file page
|
||||||
UNIV_INLINE
|
@param[in,out] faddr file address location
|
||||||
void
|
@param[in] addr file address to be written out
|
||||||
flst_init(
|
@param[in,out] mtr mini-transaction */
|
||||||
/*======*/
|
inline void flst_write_addr(const buf_block_t& block, fil_faddr_t *faddr,
|
||||||
flst_base_node_t* base, /*!< in: pointer to base node */
|
fil_addr_t addr, mtr_t* mtr)
|
||||||
mtr_t* mtr); /*!< in: mini-transaction handle */
|
{
|
||||||
/********************************************************************//**
|
ut_ad(mtr->memo_contains_page_flagged(faddr,
|
||||||
Adds a node as the last node in a list. */
|
MTR_MEMO_PAGE_X_FIX
|
||||||
void
|
| MTR_MEMO_PAGE_SX_FIX));
|
||||||
flst_add_last(
|
ut_a(addr.page == FIL_NULL || addr.boffset >= FIL_PAGE_DATA);
|
||||||
/*==========*/
|
ut_a(ut_align_offset(faddr, srv_page_size) >= FIL_PAGE_DATA);
|
||||||
flst_base_node_t* base, /*!< in: pointer to base node of list */
|
|
||||||
flst_node_t* node, /*!< in: node to add */
|
mtr->write<4,mtr_t::OPT>(block, faddr + FIL_ADDR_PAGE, addr.page);
|
||||||
mtr_t* mtr); /*!< in: mini-transaction handle */
|
mtr->write<2,mtr_t::OPT>(block, faddr + FIL_ADDR_BYTE, addr.boffset);
|
||||||
/********************************************************************//**
|
}
|
||||||
Adds a node as the first node in a list. */
|
|
||||||
void
|
/** Initialize a list base node.
|
||||||
flst_add_first(
|
@param[in] block file page
|
||||||
/*===========*/
|
@param[in,out] base base node
|
||||||
flst_base_node_t* base, /*!< in: pointer to base node of list */
|
@param[in,out] mtr mini-transaction */
|
||||||
flst_node_t* node, /*!< in: node to add */
|
inline void flst_init(const buf_block_t& block, byte *base, mtr_t *mtr)
|
||||||
mtr_t* mtr); /*!< in: mini-transaction handle */
|
{
|
||||||
/********************************************************************//**
|
ut_ad(mtr->memo_contains_page_flagged(base, MTR_MEMO_PAGE_X_FIX |
|
||||||
Removes a node. */
|
MTR_MEMO_PAGE_SX_FIX));
|
||||||
void
|
mtr->write<4,mtr_t::OPT>(block, base + FLST_LEN, 0U);
|
||||||
flst_remove(
|
flst_zero_addr(block, base + FLST_FIRST, mtr);
|
||||||
/*========*/
|
flst_zero_addr(block, base + FLST_LAST, mtr);
|
||||||
flst_base_node_t* base, /*!< in: pointer to base node of list */
|
}
|
||||||
flst_node_t* node2, /*!< in: node to remove */
|
|
||||||
mtr_t* mtr); /*!< in: mini-transaction handle */
|
/** Append a file list node to a list.
|
||||||
/** Get the length of a list.
|
@param[in,out] base base node block
|
||||||
@param[in] base base node
|
@param[in] boffset byte offset of the base node
|
||||||
@return length */
|
@param[in,out] add block to be added
|
||||||
UNIV_INLINE
|
@param[in] aoffset byte offset of the node to be added
|
||||||
uint32_t
|
@param[in,outr] mtr mini-transaction */
|
||||||
flst_get_len(
|
void flst_add_last(buf_block_t *base, uint16_t boffset,
|
||||||
const flst_base_node_t* base);
|
buf_block_t *add, uint16_t aoffset, mtr_t *mtr)
|
||||||
/********************************************************************//**
|
MY_ATTRIBUTE((nonnull));
|
||||||
Writes a file address. */
|
/** Prepend a file list node to a list.
|
||||||
UNIV_INLINE
|
@param[in,out] base base node block
|
||||||
void
|
@param[in] boffset byte offset of the base node
|
||||||
flst_write_addr(
|
@param[in,out] add block to be added
|
||||||
/*============*/
|
@param[in] aoffset byte offset of the node to be added
|
||||||
fil_faddr_t* faddr, /*!< in: pointer to file faddress */
|
@param[in,outr] mtr mini-transaction */
|
||||||
fil_addr_t addr, /*!< in: file address */
|
void flst_add_first(buf_block_t *base, uint16_t boffset,
|
||||||
mtr_t* mtr); /*!< in: mini-transaction handle */
|
buf_block_t *add, uint16_t aoffset, mtr_t *mtr)
|
||||||
|
MY_ATTRIBUTE((nonnull));
|
||||||
|
/** Remove a file list node.
|
||||||
|
@param[in,out] base base node block
|
||||||
|
@param[in] boffset byte offset of the base node
|
||||||
|
@param[in,out] cur block to be removed
|
||||||
|
@param[in] coffset byte offset of the current record to be removed
|
||||||
|
@param[in,outr] mtr mini-transaction */
|
||||||
|
void flst_remove(buf_block_t *base, uint16_t boffset,
|
||||||
|
buf_block_t *cur, uint16_t coffset, mtr_t *mtr)
|
||||||
|
MY_ATTRIBUTE((nonnull));
|
||||||
|
|
||||||
|
/** @return the length of a list */
|
||||||
|
inline uint32_t flst_get_len(const flst_base_node_t *base)
|
||||||
|
{
|
||||||
|
return mach_read_from_4(base + FLST_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
/** @return a file address */
|
/** @return a file address */
|
||||||
inline fil_addr_t flst_read_addr(const fil_faddr_t *faddr)
|
inline fil_addr_t flst_read_addr(const fil_faddr_t *faddr)
|
||||||
|
|
@ -176,16 +188,10 @@ inline fil_addr_t flst_get_prev_addr(const flst_node_t *node)
|
||||||
return flst_read_addr(node + FLST_PREV);
|
return flst_read_addr(node + FLST_PREV);
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************//**
|
#ifdef UNIV_DEBUG
|
||||||
Validates a file-based list.
|
/** Validate a file-based list. */
|
||||||
@return TRUE if ok */
|
void flst_validate(const buf_block_t *base, uint16_t boffset, mtr_t *mtr);
|
||||||
ibool
|
#endif
|
||||||
flst_validate(
|
|
||||||
/*==========*/
|
|
||||||
const flst_base_node_t* base, /*!< in: pointer to base node of list */
|
|
||||||
mtr_t* mtr1); /*!< in: mtr */
|
|
||||||
|
|
||||||
#include "fut0lst.ic"
|
|
||||||
|
|
||||||
#endif /* !UNIV_INNOCHECKSUM */
|
#endif /* !UNIV_INNOCHECKSUM */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,80 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
|
|
||||||
Copyright (c) 1995, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
|
||||||
Copyright (c) 2019, MariaDB Corporation.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU General Public License as published by the Free Software
|
|
||||||
Foundation; version 2 of the License.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
||||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along with
|
|
||||||
this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
|
|
||||||
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
/******************************************************************//**
|
|
||||||
@file include/fut0lst.ic
|
|
||||||
File-based list utilities
|
|
||||||
|
|
||||||
Created 11/28/1995 Heikki Tuuri
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#include "buf0buf.h"
|
|
||||||
|
|
||||||
/********************************************************************//**
|
|
||||||
Writes a file address. */
|
|
||||||
UNIV_INLINE
|
|
||||||
void
|
|
||||||
flst_write_addr(
|
|
||||||
/*============*/
|
|
||||||
fil_faddr_t* faddr, /*!< in: pointer to file faddress */
|
|
||||||
fil_addr_t addr, /*!< in: file address */
|
|
||||||
mtr_t* mtr) /*!< in: mini-transaction handle */
|
|
||||||
{
|
|
||||||
ut_ad(faddr && mtr);
|
|
||||||
ut_ad(mtr_memo_contains_page_flagged(mtr, faddr,
|
|
||||||
MTR_MEMO_PAGE_X_FIX
|
|
||||||
| MTR_MEMO_PAGE_SX_FIX));
|
|
||||||
ut_a(addr.page == FIL_NULL || addr.boffset >= FIL_PAGE_DATA);
|
|
||||||
ut_a(ut_align_offset(faddr, srv_page_size) >= FIL_PAGE_DATA);
|
|
||||||
|
|
||||||
mlog_write_ulint(faddr + FIL_ADDR_PAGE, addr.page, MLOG_4BYTES, mtr);
|
|
||||||
mlog_write_ulint(faddr + FIL_ADDR_BYTE, addr.boffset,
|
|
||||||
MLOG_2BYTES, mtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************//**
|
|
||||||
Initializes a list base node. */
|
|
||||||
UNIV_INLINE
|
|
||||||
void
|
|
||||||
flst_init(
|
|
||||||
/*======*/
|
|
||||||
flst_base_node_t* base, /*!< in: pointer to base node */
|
|
||||||
mtr_t* mtr) /*!< in: mini-transaction handle */
|
|
||||||
{
|
|
||||||
ut_ad(mtr_memo_contains_page_flagged(mtr, base,
|
|
||||||
MTR_MEMO_PAGE_X_FIX
|
|
||||||
| MTR_MEMO_PAGE_SX_FIX));
|
|
||||||
|
|
||||||
if (mach_read_from_4(base + FLST_LEN)) {
|
|
||||||
mlog_write_ulint(base + FLST_LEN, 0, MLOG_4BYTES, mtr);
|
|
||||||
}
|
|
||||||
flst_zero_addr(base + FLST_FIRST, mtr);
|
|
||||||
flst_zero_addr(base + FLST_LAST, mtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Get the length of a list.
|
|
||||||
@param[in] base base node
|
|
||||||
@return length */
|
|
||||||
UNIV_INLINE
|
|
||||||
uint32_t
|
|
||||||
flst_get_len(
|
|
||||||
const flst_base_node_t* base)
|
|
||||||
{
|
|
||||||
return(mach_read_from_4(base + FLST_LEN));
|
|
||||||
}
|
|
||||||
|
|
@ -33,26 +33,6 @@ Created 12/7/1995 Heikki Tuuri
|
||||||
// Forward declaration
|
// Forward declaration
|
||||||
struct dict_index_t;
|
struct dict_index_t;
|
||||||
|
|
||||||
/********************************************************//**
|
|
||||||
Writes 1, 2 or 4 bytes to a file page. Writes the corresponding log
|
|
||||||
record to the mini-transaction log if mtr is not NULL. */
|
|
||||||
void
|
|
||||||
mlog_write_ulint(
|
|
||||||
/*=============*/
|
|
||||||
byte* ptr, /*!< in: pointer where to write */
|
|
||||||
ulint val, /*!< in: value to write */
|
|
||||||
mlog_id_t type, /*!< in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */
|
|
||||||
mtr_t* mtr); /*!< in: mini-transaction handle */
|
|
||||||
|
|
||||||
/********************************************************//**
|
|
||||||
Writes 8 bytes to a file page. Writes the corresponding log
|
|
||||||
record to the mini-transaction log, only if mtr is not NULL */
|
|
||||||
void
|
|
||||||
mlog_write_ull(
|
|
||||||
/*===========*/
|
|
||||||
byte* ptr, /*!< in: pointer where to write */
|
|
||||||
ib_uint64_t val, /*!< in: value to write */
|
|
||||||
mtr_t* mtr); /*!< in: mini-transaction handle */
|
|
||||||
/********************************************************//**
|
/********************************************************//**
|
||||||
Writes a string to a file page buffered in the buffer pool. Writes the
|
Writes a string to a file page buffered in the buffer pool. Writes the
|
||||||
corresponding log record to the mini-transaction log. */
|
corresponding log record to the mini-transaction log. */
|
||||||
|
|
@ -80,7 +60,7 @@ mlog_log_string(
|
||||||
@param[in] val the data byte to write
|
@param[in] val the data byte to write
|
||||||
@param[in,out] mtr mini-transaction */
|
@param[in,out] mtr mini-transaction */
|
||||||
void
|
void
|
||||||
mlog_memset(buf_block_t* b, ulint ofs, ulint len, byte val, mtr_t* mtr);
|
mlog_memset(const buf_block_t* b, ulint ofs, ulint len, byte val, mtr_t* mtr);
|
||||||
|
|
||||||
/** Initialize a string of bytes.
|
/** Initialize a string of bytes.
|
||||||
@param[in,out] byte byte address
|
@param[in,out] byte byte address
|
||||||
|
|
@ -124,14 +104,6 @@ mlog_catenate_ulint_compressed(
|
||||||
mtr_t* mtr, /*!< in: mtr */
|
mtr_t* mtr, /*!< in: mtr */
|
||||||
ulint val); /*!< in: value to write */
|
ulint val); /*!< in: value to write */
|
||||||
/********************************************************//**
|
/********************************************************//**
|
||||||
Catenates a compressed 64-bit integer to mlog. */
|
|
||||||
UNIV_INLINE
|
|
||||||
void
|
|
||||||
mlog_catenate_ull_compressed(
|
|
||||||
/*=========================*/
|
|
||||||
mtr_t* mtr, /*!< in: mtr */
|
|
||||||
ib_uint64_t val); /*!< in: value to write */
|
|
||||||
/********************************************************//**
|
|
||||||
Opens a buffer to mlog. It must be closed with mlog_close.
|
Opens a buffer to mlog. It must be closed with mlog_close.
|
||||||
@return buffer, NULL if log mode MTR_LOG_NONE */
|
@return buffer, NULL if log mode MTR_LOG_NONE */
|
||||||
UNIV_INLINE
|
UNIV_INLINE
|
||||||
|
|
@ -151,6 +123,56 @@ mlog_close(
|
||||||
byte* ptr); /*!< in: buffer space from ptr up was
|
byte* ptr); /*!< in: buffer space from ptr up was
|
||||||
not used */
|
not used */
|
||||||
|
|
||||||
|
/** Write 1, 2, 4, or 8 bytes to a file page.
|
||||||
|
@param[in] block file page
|
||||||
|
@param[in,out] ptr pointer in file page
|
||||||
|
@param[in] val value to write
|
||||||
|
@tparam l number of bytes to write
|
||||||
|
@tparam w write request type
|
||||||
|
@tparam V type of val */
|
||||||
|
template<unsigned l,mtr_t::write_type w,typename V>
|
||||||
|
inline void mtr_t::write(const buf_block_t &block, byte *ptr, V val)
|
||||||
|
{
|
||||||
|
ut_ad(ut_align_down(ptr, srv_page_size) == block.frame);
|
||||||
|
ut_ad(m_log_mode == MTR_LOG_NONE || m_log_mode == MTR_LOG_NO_REDO ||
|
||||||
|
!block.page.zip.data ||
|
||||||
|
/* written by fil_crypt_rotate_page() or innodb_make_page_dirty()? */
|
||||||
|
(w == FORCED && l == 1 && ptr == &block.frame[FIL_PAGE_SPACE_ID]) ||
|
||||||
|
mach_read_from_2(block.frame + FIL_PAGE_TYPE) <= FIL_PAGE_TYPE_ZBLOB2);
|
||||||
|
static_assert(l == 1 || l == 2 || l == 4 || l == 8, "wrong length");
|
||||||
|
|
||||||
|
switch (l) {
|
||||||
|
case 1:
|
||||||
|
if (w == OPT && mach_read_from_1(ptr) == val) return;
|
||||||
|
ut_ad(w != NORMAL || mach_read_from_1(ptr) != val);
|
||||||
|
mach_write_to_1(ptr, val);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (w == OPT && mach_read_from_2(ptr) == val) return;
|
||||||
|
ut_ad(w != NORMAL || mach_read_from_2(ptr) != val);
|
||||||
|
mach_write_to_2(ptr, val);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
if (w == OPT && mach_read_from_4(ptr) == val) return;
|
||||||
|
ut_ad(w != NORMAL || mach_read_from_4(ptr) != val);
|
||||||
|
mach_write_to_4(ptr, val);
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
if (w == OPT && mach_read_from_8(ptr) == val) return;
|
||||||
|
ut_ad(w != NORMAL || mach_read_from_8(ptr) != val);
|
||||||
|
mach_write_to_8(ptr, val);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
byte *log_ptr= mlog_open(this, 11 + 2 + (l == 8 ? 9 : 5));
|
||||||
|
if (!log_ptr)
|
||||||
|
return;
|
||||||
|
if (l == 8)
|
||||||
|
log_write(block, ptr, static_cast<mlog_id_t>(l), log_ptr, uint64_t{val});
|
||||||
|
else
|
||||||
|
log_write(block, ptr, static_cast<mlog_id_t>(l), log_ptr,
|
||||||
|
static_cast<uint32_t>(val));
|
||||||
|
}
|
||||||
|
|
||||||
/** Writes a log record about an operation.
|
/** Writes a log record about an operation.
|
||||||
@param[in] type redo log record type
|
@param[in] type redo log record type
|
||||||
@param[in] space_id tablespace identifier
|
@param[in] space_id tablespace identifier
|
||||||
|
|
@ -195,7 +217,7 @@ mlog_parse_initial_log_record(
|
||||||
ulint* space, /*!< out: space id */
|
ulint* space, /*!< out: space id */
|
||||||
ulint* page_no);/*!< out: page number */
|
ulint* page_no);/*!< out: page number */
|
||||||
/********************************************************//**
|
/********************************************************//**
|
||||||
Parses a log record written by mlog_write_ulint, mlog_write_ull, mlog_memset.
|
Parses a log record written by mtr_t::write(), mlog_memset().
|
||||||
@return parsed record end, NULL if not a complete record */
|
@return parsed record end, NULL if not a complete record */
|
||||||
const byte*
|
const byte*
|
||||||
mlog_parse_nbytes(
|
mlog_parse_nbytes(
|
||||||
|
|
|
||||||
|
|
@ -141,30 +141,6 @@ mlog_catenate_ulint_compressed(
|
||||||
mlog_close(mtr, log_ptr);
|
mlog_close(mtr, log_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************//**
|
|
||||||
Catenates a compressed 64-bit integer to mlog. */
|
|
||||||
UNIV_INLINE
|
|
||||||
void
|
|
||||||
mlog_catenate_ull_compressed(
|
|
||||||
/*=========================*/
|
|
||||||
mtr_t* mtr, /*!< in: mtr */
|
|
||||||
ib_uint64_t val) /*!< in: value to write */
|
|
||||||
{
|
|
||||||
byte* log_ptr;
|
|
||||||
|
|
||||||
log_ptr = mlog_open(mtr, 15);
|
|
||||||
|
|
||||||
/* If no logging is requested, we may return now */
|
|
||||||
if (log_ptr == NULL) {
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
log_ptr += mach_u64_write_compressed(log_ptr, val);
|
|
||||||
|
|
||||||
mlog_close(mtr, log_ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Writes a log record about an operation.
|
/** Writes a log record about an operation.
|
||||||
@param[in] type redo log record type
|
@param[in] type redo log record type
|
||||||
@param[in] space_id tablespace identifier
|
@param[in] space_id tablespace identifier
|
||||||
|
|
|
||||||
|
|
@ -425,7 +425,50 @@ struct mtr_t {
|
||||||
static inline bool is_block_dirtied(const buf_block_t* block)
|
static inline bool is_block_dirtied(const buf_block_t* block)
|
||||||
MY_ATTRIBUTE((warn_unused_result));
|
MY_ATTRIBUTE((warn_unused_result));
|
||||||
|
|
||||||
|
/** Write request types */
|
||||||
|
enum write_type
|
||||||
|
{
|
||||||
|
/** the page is guaranteed to always change */
|
||||||
|
NORMAL= 0,
|
||||||
|
/** optional: the page contents might not change */
|
||||||
|
OPT,
|
||||||
|
/** force a write, even if the page contents is not changing */
|
||||||
|
FORCED
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Write 1, 2, 4, or 8 bytes to a file page.
|
||||||
|
@param[in] block file page
|
||||||
|
@param[in,out] ptr pointer in file page
|
||||||
|
@param[in] val value to write
|
||||||
|
@tparam l number of bytes to write
|
||||||
|
@tparam w write request type
|
||||||
|
@tparam V type of val */
|
||||||
|
template<unsigned l,write_type w= NORMAL,typename V>
|
||||||
|
inline void write(const buf_block_t &block, byte *ptr, V val)
|
||||||
|
MY_ATTRIBUTE((nonnull));
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/**
|
||||||
|
Write a log record for writing 1, 2, or 4 bytes.
|
||||||
|
@param[in] block file page
|
||||||
|
@param[in,out] ptr pointer in file page
|
||||||
|
@param[in] l number of bytes to write
|
||||||
|
@param[in,out] log_ptr log record buffer
|
||||||
|
@param[in] val value to write */
|
||||||
|
void log_write(const buf_block_t &block, byte *ptr, mlog_id_t l,
|
||||||
|
byte *log_ptr, uint32_t val)
|
||||||
|
MY_ATTRIBUTE((nonnull));
|
||||||
|
/**
|
||||||
|
Write a log record for writing 8 bytes.
|
||||||
|
@param[in] block file page
|
||||||
|
@param[in,out] ptr pointer in file page
|
||||||
|
@param[in] l number of bytes to write (8)
|
||||||
|
@param[in,out] log_ptr log record buffer
|
||||||
|
@param[in] val value to write */
|
||||||
|
void log_write(const buf_block_t &block, byte *ptr, mlog_id_t l,
|
||||||
|
byte *log_ptr, uint64_t val)
|
||||||
|
MY_ATTRIBUTE((nonnull));
|
||||||
|
|
||||||
/** Prepare to write the mini-transaction log to the redo log buffer.
|
/** Prepare to write the mini-transaction log to the redo log buffer.
|
||||||
@return number of bytes to write in finish_write() */
|
@return number of bytes to write in finish_write() */
|
||||||
inline ulint prepare_write();
|
inline ulint prepare_write();
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ enum mtr_log_t {
|
||||||
|
|
||||||
/** @name Log item types
|
/** @name Log item types
|
||||||
The log items are declared 'byte' so that the compiler can warn if val
|
The log items are declared 'byte' so that the compiler can warn if val
|
||||||
and type parameters are switched in a call to mlog_write_ulint. NOTE!
|
and type parameters are switched in a call to mlog_write. NOTE!
|
||||||
For 1 - 8 bytes, the flag value must give the length also! @{ */
|
For 1 - 8 bytes, the flag value must give the length also! @{ */
|
||||||
enum mlog_id_t {
|
enum mlog_id_t {
|
||||||
/** if the mtr contains only one log record for one page,
|
/** if the mtr contains only one log record for one page,
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ Created 2/2/1994 Heikki Tuuri
|
||||||
#include "fil0fil.h"
|
#include "fil0fil.h"
|
||||||
#include "buf0buf.h"
|
#include "buf0buf.h"
|
||||||
#include "rem0rec.h"
|
#include "rem0rec.h"
|
||||||
|
#include "mach0data.h"
|
||||||
#ifndef UNIV_INNOCHECKSUM
|
#ifndef UNIV_INNOCHECKSUM
|
||||||
#include "dict0dict.h"
|
#include "dict0dict.h"
|
||||||
#include "data0data.h"
|
#include "data0data.h"
|
||||||
|
|
@ -42,8 +43,6 @@ Created 2/2/1994 Heikki Tuuri
|
||||||
Index page header starts at the first offset left free by the FIL-module */
|
Index page header starts at the first offset left free by the FIL-module */
|
||||||
|
|
||||||
typedef byte page_header_t;
|
typedef byte page_header_t;
|
||||||
#else
|
|
||||||
# include "mach0data.h"
|
|
||||||
#endif /* !UNIV_INNOCHECKSUM */
|
#endif /* !UNIV_INNOCHECKSUM */
|
||||||
|
|
||||||
#define PAGE_HEADER FSEG_PAGE_DATA /* index page header starts at this
|
#define PAGE_HEADER FSEG_PAGE_DATA /* index page header starts at this
|
||||||
|
|
@ -393,13 +392,17 @@ inline
|
||||||
bool
|
bool
|
||||||
page_rec_is_infimum(const rec_t* rec);
|
page_rec_is_infimum(const rec_t* rec);
|
||||||
|
|
||||||
/*************************************************************//**
|
/** Read PAGE_MAX_TRX_ID.
|
||||||
Returns the max trx id field value. */
|
@param[in] page index page
|
||||||
UNIV_INLINE
|
@return the value of PAGE_MAX_TRX_ID or PAGE_ROOT_AUTO_INC */
|
||||||
trx_id_t
|
inline trx_id_t page_get_max_trx_id(const page_t *page)
|
||||||
page_get_max_trx_id(
|
{
|
||||||
/*================*/
|
static_assert((PAGE_HEADER + PAGE_MAX_TRX_ID) % 8 == 0, "alignment");
|
||||||
const page_t* page); /*!< in: page */
|
const byte *p= static_cast<const byte*>
|
||||||
|
(MY_ASSUME_ALIGNED(page + PAGE_HEADER + PAGE_MAX_TRX_ID, 8));
|
||||||
|
return mach_read_from_8(p);
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************//**
|
/*************************************************************//**
|
||||||
Sets the max trx id field value. */
|
Sets the max trx id field value. */
|
||||||
void
|
void
|
||||||
|
|
@ -424,7 +427,6 @@ page_update_max_trx_id(
|
||||||
|
|
||||||
/** Persist the AUTO_INCREMENT value on a clustered index root page.
|
/** Persist the AUTO_INCREMENT value on a clustered index root page.
|
||||||
@param[in,out] block clustered index root page
|
@param[in,out] block clustered index root page
|
||||||
@param[in] index clustered index
|
|
||||||
@param[in] autoinc next available AUTO_INCREMENT value
|
@param[in] autoinc next available AUTO_INCREMENT value
|
||||||
@param[in,out] mtr mini-transaction
|
@param[in,out] mtr mini-transaction
|
||||||
@param[in] reset whether to reset the AUTO_INCREMENT
|
@param[in] reset whether to reset the AUTO_INCREMENT
|
||||||
|
|
@ -433,7 +435,6 @@ page_update_max_trx_id(
|
||||||
void
|
void
|
||||||
page_set_autoinc(
|
page_set_autoinc(
|
||||||
buf_block_t* block,
|
buf_block_t* block,
|
||||||
const dict_index_t* index MY_ATTRIBUTE((unused)),
|
|
||||||
ib_uint64_t autoinc,
|
ib_uint64_t autoinc,
|
||||||
mtr_t* mtr,
|
mtr_t* mtr,
|
||||||
bool reset)
|
bool reset)
|
||||||
|
|
@ -517,17 +518,12 @@ page_header_set_ptr(
|
||||||
ulint field, /*!< in/out: PAGE_FREE, ... */
|
ulint field, /*!< in/out: PAGE_FREE, ... */
|
||||||
const byte* ptr); /*!< in: pointer or NULL*/
|
const byte* ptr); /*!< in: pointer or NULL*/
|
||||||
|
|
||||||
/*************************************************************//**
|
/**
|
||||||
Resets the last insert info field in the page header. Writes to mlog
|
Reset PAGE_LAST_INSERT.
|
||||||
about this operation. */
|
@param[in,out] block file page
|
||||||
UNIV_INLINE
|
@param[in,out] mtr mini-transaction */
|
||||||
void
|
inline void page_header_reset_last_insert(buf_block_t *block, mtr_t *mtr)
|
||||||
page_header_reset_last_insert(
|
MY_ATTRIBUTE((nonnull));
|
||||||
/*==========================*/
|
|
||||||
page_t* page, /*!< in: page */
|
|
||||||
page_zip_des_t* page_zip,/*!< in/out: compressed page whose
|
|
||||||
uncompressed part will be updated, or NULL */
|
|
||||||
mtr_t* mtr); /*!< in: mtr */
|
|
||||||
#define page_get_infimum_rec(page) ((page) + page_get_infimum_offset(page))
|
#define page_get_infimum_rec(page) ((page) + page_get_infimum_offset(page))
|
||||||
#define page_get_supremum_rec(page) ((page) + page_get_supremum_offset(page))
|
#define page_get_supremum_rec(page) ((page) + page_get_supremum_offset(page))
|
||||||
|
|
||||||
|
|
@ -663,14 +659,17 @@ ibool
|
||||||
page_rec_check(
|
page_rec_check(
|
||||||
/*===========*/
|
/*===========*/
|
||||||
const rec_t* rec); /*!< in: record */
|
const rec_t* rec); /*!< in: record */
|
||||||
/***************************************************************//**
|
/** Get the record pointed to by a directory slot.
|
||||||
Gets the record pointed to by a directory slot.
|
@param[in] slot directory slot
|
||||||
@return pointer to record */
|
@return pointer to record */
|
||||||
UNIV_INLINE
|
inline rec_t *page_dir_slot_get_rec(page_dir_slot_t *slot)
|
||||||
const rec_t*
|
{
|
||||||
page_dir_slot_get_rec(
|
return page_align(slot) + mach_read_from_2(slot);
|
||||||
/*==================*/
|
}
|
||||||
const page_dir_slot_t* slot); /*!< in: directory slot */
|
inline const rec_t *page_dir_slot_get_rec(const page_dir_slot_t *slot)
|
||||||
|
{
|
||||||
|
return page_dir_slot_get_rec(const_cast<rec_t*>(slot));
|
||||||
|
}
|
||||||
/***************************************************************//**
|
/***************************************************************//**
|
||||||
This is used to set the record offset in a directory slot. */
|
This is used to set the record offset in a directory slot. */
|
||||||
UNIV_INLINE
|
UNIV_INLINE
|
||||||
|
|
|
||||||
|
|
@ -28,24 +28,10 @@ Created 2/2/1994 Heikki Tuuri
|
||||||
#define page0page_ic
|
#define page0page_ic
|
||||||
|
|
||||||
#ifndef UNIV_INNOCHECKSUM
|
#ifndef UNIV_INNOCHECKSUM
|
||||||
#include "mach0data.h"
|
|
||||||
#include "rem0cmp.h"
|
#include "rem0cmp.h"
|
||||||
#include "mtr0log.h"
|
#include "mtr0log.h"
|
||||||
#include "page0zip.h"
|
#include "page0zip.h"
|
||||||
|
|
||||||
/*************************************************************//**
|
|
||||||
Returns the max trx id field value. */
|
|
||||||
UNIV_INLINE
|
|
||||||
trx_id_t
|
|
||||||
page_get_max_trx_id(
|
|
||||||
/*================*/
|
|
||||||
const page_t* page) /*!< in: page */
|
|
||||||
{
|
|
||||||
ut_ad(page);
|
|
||||||
|
|
||||||
return(mach_read_from_8(page + PAGE_HEADER + PAGE_MAX_TRX_ID));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************//**
|
/*************************************************************//**
|
||||||
Sets the max trx id field value if trx_id is bigger than the previous
|
Sets the max trx id field value if trx_id is bigger than the previous
|
||||||
value. */
|
value. */
|
||||||
|
|
@ -115,21 +101,16 @@ page_set_ssn_id(
|
||||||
node_seq_t ssn_id, /*!< in: transaction id */
|
node_seq_t ssn_id, /*!< in: transaction id */
|
||||||
mtr_t* mtr) /*!< in/out: mini-transaction */
|
mtr_t* mtr) /*!< in/out: mini-transaction */
|
||||||
{
|
{
|
||||||
page_t* page = buf_block_get_frame(block);
|
|
||||||
|
|
||||||
ut_ad(!mtr || mtr_memo_contains_flagged(mtr, block,
|
ut_ad(!mtr || mtr_memo_contains_flagged(mtr, block,
|
||||||
MTR_MEMO_PAGE_SX_FIX
|
MTR_MEMO_PAGE_SX_FIX
|
||||||
| MTR_MEMO_PAGE_X_FIX));
|
| MTR_MEMO_PAGE_X_FIX));
|
||||||
|
|
||||||
if (page_zip) {
|
byte* ssn = block->frame + FIL_RTREE_SPLIT_SEQ_NUM;
|
||||||
mach_write_to_8(page + FIL_RTREE_SPLIT_SEQ_NUM, ssn_id);
|
if (UNIV_LIKELY_NULL(page_zip)) {
|
||||||
page_zip_write_header(page_zip,
|
mach_write_to_8(ssn, ssn_id);
|
||||||
page + FIL_RTREE_SPLIT_SEQ_NUM,
|
page_zip_write_header(page_zip, ssn, 8, mtr);
|
||||||
8, mtr);
|
|
||||||
} else if (mtr) {
|
|
||||||
mlog_write_ull(page + FIL_RTREE_SPLIT_SEQ_NUM, ssn_id, mtr);
|
|
||||||
} else {
|
} else {
|
||||||
mach_write_to_8(page + FIL_RTREE_SPLIT_SEQ_NUM, ssn_id);
|
mtr->write<8,mtr_t::OPT>(*block, ssn, ssn_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -229,30 +210,21 @@ page_header_set_ptr(
|
||||||
page_header_set_field(page, page_zip, field, offs);
|
page_header_set_field(page, page_zip, field, offs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************//**
|
/**
|
||||||
Resets the last insert info field in the page header. Writes to mlog
|
Reset PAGE_LAST_INSERT.
|
||||||
about this operation. */
|
@param[in,out] block file page
|
||||||
UNIV_INLINE
|
@param[in,out] mtr mini-transaction */
|
||||||
void
|
inline void page_header_reset_last_insert(buf_block_t *block, mtr_t *mtr)
|
||||||
page_header_reset_last_insert(
|
|
||||||
/*==========================*/
|
|
||||||
page_t* page, /*!< in/out: page */
|
|
||||||
page_zip_des_t* page_zip,/*!< in/out: compressed page whose
|
|
||||||
uncompressed part will be updated, or NULL */
|
|
||||||
mtr_t* mtr) /*!< in: mtr */
|
|
||||||
{
|
{
|
||||||
ut_ad(page != NULL);
|
byte *b= &block->frame[PAGE_HEADER + PAGE_LAST_INSERT];
|
||||||
ut_ad(mtr != NULL);
|
|
||||||
|
|
||||||
if (page_zip) {
|
if (UNIV_LIKELY_NULL(block->page.zip.data))
|
||||||
mach_write_to_2(page + (PAGE_HEADER + PAGE_LAST_INSERT), 0);
|
{
|
||||||
page_zip_write_header(page_zip,
|
mach_write_to_2(b, 0);
|
||||||
page + (PAGE_HEADER + PAGE_LAST_INSERT),
|
page_zip_write_header(&block->page.zip, b, 2, mtr);
|
||||||
2, mtr);
|
}
|
||||||
} else {
|
else
|
||||||
mlog_write_ulint(page + (PAGE_HEADER + PAGE_LAST_INSERT), 0,
|
mtr->write<2,mtr_t::OPT>(*block, b, 0U);
|
||||||
MLOG_2BYTES, mtr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************//**
|
/***************************************************************//**
|
||||||
|
|
@ -541,18 +513,6 @@ page_rec_check(
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************//**
|
|
||||||
Gets the record pointed to by a directory slot.
|
|
||||||
@return pointer to record */
|
|
||||||
UNIV_INLINE
|
|
||||||
const rec_t*
|
|
||||||
page_dir_slot_get_rec(
|
|
||||||
/*==================*/
|
|
||||||
const page_dir_slot_t* slot) /*!< in: directory slot */
|
|
||||||
{
|
|
||||||
return(page_align(slot) + mach_read_from_2(slot));
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************//**
|
/***************************************************************//**
|
||||||
This is used to set the record offset in a directory slot. */
|
This is used to set the record offset in a directory slot. */
|
||||||
UNIV_INLINE
|
UNIV_INLINE
|
||||||
|
|
|
||||||
|
|
@ -184,15 +184,15 @@ class purge_sys_t
|
||||||
to purge */
|
to purge */
|
||||||
trx_rseg_t* rseg; /*!< Rollback segment for the next undo
|
trx_rseg_t* rseg; /*!< Rollback segment for the next undo
|
||||||
record to purge */
|
record to purge */
|
||||||
ulint page_no; /*!< Page number for the next undo
|
uint32_t page_no; /*!< Page number for the next undo
|
||||||
record to purge, page number of the
|
record to purge, page number of the
|
||||||
log header, if dummy record */
|
log header, if dummy record */
|
||||||
ulint offset; /*!< Page offset for the next undo
|
uint32_t hdr_page_no; /*!< Header page of the undo log where
|
||||||
|
the next record to purge belongs */
|
||||||
|
uint16_t offset; /*!< Page offset for the next undo
|
||||||
record to purge, 0 if the dummy
|
record to purge, 0 if the dummy
|
||||||
record */
|
record */
|
||||||
ulint hdr_page_no; /*!< Header page of the undo log where
|
uint16_t hdr_offset; /*!< Header byte offset on the page */
|
||||||
the next record to purge belongs */
|
|
||||||
ulint hdr_offset; /*!< Header byte offset on the page */
|
|
||||||
|
|
||||||
|
|
||||||
TrxUndoRsegsIterator
|
TrxUndoRsegsIterator
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ Created 3/26/1996 Heikki Tuuri
|
||||||
@param[in,out] mtr mini-transaction
|
@param[in,out] mtr mini-transaction
|
||||||
@return rollback segment header, page x-latched */
|
@return rollback segment header, page x-latched */
|
||||||
UNIV_INLINE
|
UNIV_INLINE
|
||||||
trx_rsegf_t*
|
buf_block_t*
|
||||||
trx_rsegf_get(fil_space_t* space, ulint page_no, mtr_t* mtr);
|
trx_rsegf_get(fil_space_t* space, ulint page_no, mtr_t* mtr);
|
||||||
|
|
||||||
/** Gets a newly created rollback segment header.
|
/** Gets a newly created rollback segment header.
|
||||||
|
|
@ -45,29 +45,12 @@ trx_rsegf_get(fil_space_t* space, ulint page_no, mtr_t* mtr);
|
||||||
@param[in,out] mtr mini-transaction
|
@param[in,out] mtr mini-transaction
|
||||||
@return rollback segment header, page x-latched */
|
@return rollback segment header, page x-latched */
|
||||||
UNIV_INLINE
|
UNIV_INLINE
|
||||||
trx_rsegf_t*
|
buf_block_t*
|
||||||
trx_rsegf_get_new(
|
trx_rsegf_get_new(
|
||||||
ulint space,
|
ulint space,
|
||||||
ulint page_no,
|
ulint page_no,
|
||||||
mtr_t* mtr);
|
mtr_t* mtr);
|
||||||
|
|
||||||
/***************************************************************//**
|
|
||||||
Sets the file page number of the nth undo log slot. */
|
|
||||||
UNIV_INLINE
|
|
||||||
void
|
|
||||||
trx_rsegf_set_nth_undo(
|
|
||||||
/*===================*/
|
|
||||||
trx_rsegf_t* rsegf, /*!< in: rollback segment header */
|
|
||||||
ulint n, /*!< in: index of slot */
|
|
||||||
ulint page_no,/*!< in: page number of the undo log segment */
|
|
||||||
mtr_t* mtr); /*!< in: mtr */
|
|
||||||
/****************************************************************//**
|
|
||||||
Looks for a free slot for an undo log segment.
|
|
||||||
@return slot index or ULINT_UNDEFINED if not found */
|
|
||||||
UNIV_INLINE
|
|
||||||
ulint
|
|
||||||
trx_rsegf_undo_find_free(const trx_rsegf_t* rsegf);
|
|
||||||
|
|
||||||
/** Create a rollback segment header.
|
/** Create a rollback segment header.
|
||||||
@param[in,out] space system, undo, or temporary tablespace
|
@param[in,out] space system, undo, or temporary tablespace
|
||||||
@param[in] rseg_id rollback segment identifier
|
@param[in] rseg_id rollback segment identifier
|
||||||
|
|
@ -155,10 +138,10 @@ struct trx_rseg_t {
|
||||||
|
|
||||||
/** Page number of the last not yet purged log header in the history
|
/** Page number of the last not yet purged log header in the history
|
||||||
list; FIL_NULL if all list purged */
|
list; FIL_NULL if all list purged */
|
||||||
ulint last_page_no;
|
uint32_t last_page_no;
|
||||||
|
|
||||||
/** Byte offset of the last not yet purged log header */
|
/** Byte offset of the last not yet purged log header */
|
||||||
ulint last_offset;
|
uint16_t last_offset;
|
||||||
|
|
||||||
/** trx_t::no * 2 + old_insert of the last not yet purged log */
|
/** trx_t::no * 2 + old_insert of the last not yet purged log */
|
||||||
trx_id_t last_commit;
|
trx_id_t last_commit;
|
||||||
|
|
@ -255,15 +238,13 @@ If no binlog information is present, the first byte is NUL. */
|
||||||
/*-------------------------------------------------------------*/
|
/*-------------------------------------------------------------*/
|
||||||
|
|
||||||
/** Read the page number of an undo log slot.
|
/** Read the page number of an undo log slot.
|
||||||
@param[in] rsegf rollback segment header
|
@param[in] rseg_header rollback segment header
|
||||||
@param[in] n slot number */
|
@param[in] n slot number */
|
||||||
inline
|
inline uint32_t trx_rsegf_get_nth_undo(const buf_block_t *rseg_header, ulint n)
|
||||||
uint32_t
|
|
||||||
trx_rsegf_get_nth_undo(const trx_rsegf_t* rsegf, ulint n)
|
|
||||||
{
|
{
|
||||||
ut_ad(n < TRX_RSEG_N_SLOTS);
|
ut_ad(n < TRX_RSEG_N_SLOTS);
|
||||||
return mach_read_from_4(rsegf + TRX_RSEG_UNDO_SLOTS
|
return mach_read_from_4(TRX_RSEG + TRX_RSEG_UNDO_SLOTS +
|
||||||
+ n * TRX_RSEG_SLOT_SIZE);
|
n * TRX_RSEG_SLOT_SIZE + rseg_header->frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WITH_WSREP
|
#ifdef WITH_WSREP
|
||||||
|
|
@ -273,7 +254,7 @@ trx_rsegf_get_nth_undo(const trx_rsegf_t* rsegf, ulint n)
|
||||||
@param[in,out] mtr mini-transaction */
|
@param[in,out] mtr mini-transaction */
|
||||||
void
|
void
|
||||||
trx_rseg_update_wsrep_checkpoint(
|
trx_rseg_update_wsrep_checkpoint(
|
||||||
trx_rsegf_t* rseg_header,
|
buf_block_t* rseg_header,
|
||||||
const XID* xid,
|
const XID* xid,
|
||||||
mtr_t* mtr);
|
mtr_t* mtr);
|
||||||
|
|
||||||
|
|
@ -295,7 +276,7 @@ bool trx_rseg_read_wsrep_checkpoint(XID& xid);
|
||||||
/** Upgrade a rollback segment header page to MariaDB 10.3 format.
|
/** Upgrade a rollback segment header page to MariaDB 10.3 format.
|
||||||
@param[in,out] rseg_header rollback segment header page
|
@param[in,out] rseg_header rollback segment header page
|
||||||
@param[in,out] mtr mini-transaction */
|
@param[in,out] mtr mini-transaction */
|
||||||
void trx_rseg_format_upgrade(trx_rsegf_t* rseg_header, mtr_t* mtr);
|
void trx_rseg_format_upgrade(buf_block_t *rseg_header, mtr_t *mtr);
|
||||||
|
|
||||||
/** Update the offset information about the end of the binlog entry
|
/** Update the offset information about the end of the binlog entry
|
||||||
which corresponds to the transaction just being committed.
|
which corresponds to the transaction just being committed.
|
||||||
|
|
@ -304,8 +285,8 @@ up to which replication has proceeded.
|
||||||
@param[in,out] rseg_header rollback segment header
|
@param[in,out] rseg_header rollback segment header
|
||||||
@param[in] trx committing transaction
|
@param[in] trx committing transaction
|
||||||
@param[in,out] mtr mini-transaction */
|
@param[in,out] mtr mini-transaction */
|
||||||
void
|
void trx_rseg_update_binlog_offset(buf_block_t *rseg_header, const trx_t *trx,
|
||||||
trx_rseg_update_binlog_offset(byte* rseg_header, const trx_t* trx, mtr_t* mtr);
|
mtr_t *mtr);
|
||||||
|
|
||||||
#include "trx0rseg.ic"
|
#include "trx0rseg.ic"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved.
|
||||||
Copyright (c) 2017, 2018, MariaDB Corporation.
|
Copyright (c) 2017, 2019, MariaDB Corporation.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
the terms of the GNU General Public License as published by the Free Software
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
|
@ -33,7 +33,7 @@ Created 3/26/1996 Heikki Tuuri
|
||||||
@param[in,out] mtr mini-transaction
|
@param[in,out] mtr mini-transaction
|
||||||
@return rollback segment header, page x-latched */
|
@return rollback segment header, page x-latched */
|
||||||
UNIV_INLINE
|
UNIV_INLINE
|
||||||
trx_rsegf_t*
|
buf_block_t*
|
||||||
trx_rsegf_get(fil_space_t* space, ulint page_no, mtr_t* mtr)
|
trx_rsegf_get(fil_space_t* space, ulint page_no, mtr_t* mtr)
|
||||||
{
|
{
|
||||||
ut_ad(space == fil_system.sys_space || space == fil_system.temp_space
|
ut_ad(space == fil_system.sys_space || space == fil_system.temp_space
|
||||||
|
|
@ -44,8 +44,7 @@ trx_rsegf_get(fil_space_t* space, ulint page_no, mtr_t* mtr)
|
||||||
0, RW_X_LATCH, mtr);
|
0, RW_X_LATCH, mtr);
|
||||||
|
|
||||||
buf_block_dbg_add_level(block, SYNC_RSEG_HEADER);
|
buf_block_dbg_add_level(block, SYNC_RSEG_HEADER);
|
||||||
|
return block;
|
||||||
return TRX_RSEG + block->frame;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets a newly created rollback segment header.
|
/** Gets a newly created rollback segment header.
|
||||||
|
|
@ -54,14 +53,13 @@ trx_rsegf_get(fil_space_t* space, ulint page_no, mtr_t* mtr)
|
||||||
@param[in,out] mtr mini-transaction
|
@param[in,out] mtr mini-transaction
|
||||||
@return rollback segment header, page x-latched */
|
@return rollback segment header, page x-latched */
|
||||||
UNIV_INLINE
|
UNIV_INLINE
|
||||||
trx_rsegf_t*
|
buf_block_t*
|
||||||
trx_rsegf_get_new(
|
trx_rsegf_get_new(
|
||||||
ulint space,
|
ulint space,
|
||||||
ulint page_no,
|
ulint page_no,
|
||||||
mtr_t* mtr)
|
mtr_t* mtr)
|
||||||
{
|
{
|
||||||
buf_block_t* block;
|
buf_block_t* block;
|
||||||
trx_rsegf_t* header;
|
|
||||||
|
|
||||||
ut_ad(space <= srv_undo_tablespaces_active || space == SRV_TMP_SPACE_ID
|
ut_ad(space <= srv_undo_tablespaces_active || space == SRV_TMP_SPACE_ID
|
||||||
|| !srv_was_started);
|
|| !srv_was_started);
|
||||||
|
|
@ -70,54 +68,5 @@ trx_rsegf_get_new(
|
||||||
block = buf_page_get(page_id_t(space, page_no), 0, RW_X_LATCH, mtr);
|
block = buf_page_get(page_id_t(space, page_no), 0, RW_X_LATCH, mtr);
|
||||||
|
|
||||||
buf_block_dbg_add_level(block, SYNC_RSEG_HEADER_NEW);
|
buf_block_dbg_add_level(block, SYNC_RSEG_HEADER_NEW);
|
||||||
|
return block;
|
||||||
header = TRX_RSEG + buf_block_get_frame(block);
|
|
||||||
|
|
||||||
return(header);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************//**
|
|
||||||
Sets the file page number of the nth undo log slot. */
|
|
||||||
UNIV_INLINE
|
|
||||||
void
|
|
||||||
trx_rsegf_set_nth_undo(
|
|
||||||
/*===================*/
|
|
||||||
trx_rsegf_t* rsegf, /*!< in: rollback segment header */
|
|
||||||
ulint n, /*!< in: index of slot */
|
|
||||||
ulint page_no,/*!< in: page number of the undo log segment */
|
|
||||||
mtr_t* mtr) /*!< in: mtr */
|
|
||||||
{
|
|
||||||
ut_a(n < TRX_RSEG_N_SLOTS);
|
|
||||||
|
|
||||||
mlog_write_ulint(rsegf + TRX_RSEG_UNDO_SLOTS + n * TRX_RSEG_SLOT_SIZE,
|
|
||||||
page_no, MLOG_4BYTES, mtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************//**
|
|
||||||
Looks for a free slot for an undo log segment.
|
|
||||||
@return slot index or ULINT_UNDEFINED if not found */
|
|
||||||
UNIV_INLINE
|
|
||||||
ulint
|
|
||||||
trx_rsegf_undo_find_free(const trx_rsegf_t* rsegf)
|
|
||||||
{
|
|
||||||
ulint i;
|
|
||||||
ulint page_no;
|
|
||||||
ulint max_slots = TRX_RSEG_N_SLOTS;
|
|
||||||
|
|
||||||
#ifdef UNIV_DEBUG
|
|
||||||
if (trx_rseg_n_slots_debug) {
|
|
||||||
max_slots = ut_min(static_cast<ulint>(trx_rseg_n_slots_debug),
|
|
||||||
static_cast<ulint>(TRX_RSEG_N_SLOTS));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (i = 0; i < max_slots; i++) {
|
|
||||||
page_no = trx_rsegf_get_nth_undo(rsegf, i);
|
|
||||||
|
|
||||||
if (page_no == FIL_NULL) {
|
|
||||||
return(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return(ULINT_UNDEFINED);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -121,8 +121,6 @@ struct trx_savept_t{
|
||||||
|
|
||||||
/** File objects */
|
/** File objects */
|
||||||
/* @{ */
|
/* @{ */
|
||||||
/** Rollback segment header */
|
|
||||||
typedef byte trx_rsegf_t;
|
|
||||||
/** Undo segment header */
|
/** Undo segment header */
|
||||||
typedef byte trx_usegf_t;
|
typedef byte trx_usegf_t;
|
||||||
/** Undo log header */
|
/** Undo log header */
|
||||||
|
|
|
||||||
|
|
@ -46,10 +46,10 @@ UNIV_INLINE
|
||||||
roll_ptr_t
|
roll_ptr_t
|
||||||
trx_undo_build_roll_ptr(
|
trx_undo_build_roll_ptr(
|
||||||
/*====================*/
|
/*====================*/
|
||||||
ibool is_insert, /*!< in: TRUE if insert undo log */
|
bool is_insert, /*!< in: TRUE if insert undo log */
|
||||||
ulint rseg_id, /*!< in: rollback segment id */
|
ulint rseg_id, /*!< in: rollback segment id */
|
||||||
ulint page_no, /*!< in: page number */
|
uint32_t page_no, /*!< in: page number */
|
||||||
ulint offset); /*!< in: offset of the undo entry within page */
|
uint16_t offset); /*!< in: offset of the undo entry within page */
|
||||||
/***********************************************************************//**
|
/***********************************************************************//**
|
||||||
Decodes a roll pointer. */
|
Decodes a roll pointer. */
|
||||||
UNIV_INLINE
|
UNIV_INLINE
|
||||||
|
|
@ -57,16 +57,16 @@ void
|
||||||
trx_undo_decode_roll_ptr(
|
trx_undo_decode_roll_ptr(
|
||||||
/*=====================*/
|
/*=====================*/
|
||||||
roll_ptr_t roll_ptr, /*!< in: roll pointer */
|
roll_ptr_t roll_ptr, /*!< in: roll pointer */
|
||||||
ibool* is_insert, /*!< out: TRUE if insert undo log */
|
bool* is_insert, /*!< out: TRUE if insert undo log */
|
||||||
ulint* rseg_id, /*!< out: rollback segment id */
|
ulint* rseg_id, /*!< out: rollback segment id */
|
||||||
ulint* page_no, /*!< out: page number */
|
uint32_t* page_no, /*!< out: page number */
|
||||||
ulint* offset); /*!< out: offset of the undo
|
uint16_t* offset); /*!< out: offset of the undo
|
||||||
entry within page */
|
entry within page */
|
||||||
/***********************************************************************//**
|
/***********************************************************************//**
|
||||||
Returns TRUE if the roll pointer is of the insert type.
|
Determine if DB_ROLL_PTR is of the insert type.
|
||||||
@return TRUE if insert undo log */
|
@return true if insert */
|
||||||
UNIV_INLINE
|
UNIV_INLINE
|
||||||
ibool
|
bool
|
||||||
trx_undo_roll_ptr_is_insert(
|
trx_undo_roll_ptr_is_insert(
|
||||||
/*========================*/
|
/*========================*/
|
||||||
roll_ptr_t roll_ptr); /*!< in: roll pointer */
|
roll_ptr_t roll_ptr); /*!< in: roll pointer */
|
||||||
|
|
@ -101,7 +101,7 @@ inline roll_ptr_t trx_read_roll_ptr(const byte* ptr)
|
||||||
@param[in,out] mtr mini-transaction
|
@param[in,out] mtr mini-transaction
|
||||||
@return pointer to page x-latched */
|
@return pointer to page x-latched */
|
||||||
UNIV_INLINE
|
UNIV_INLINE
|
||||||
page_t*
|
buf_block_t*
|
||||||
trx_undo_page_get(const page_id_t page_id, mtr_t* mtr);
|
trx_undo_page_get(const page_id_t page_id, mtr_t* mtr);
|
||||||
|
|
||||||
/** Gets an undo log page and s-latches it.
|
/** Gets an undo log page and s-latches it.
|
||||||
|
|
@ -109,56 +109,52 @@ trx_undo_page_get(const page_id_t page_id, mtr_t* mtr);
|
||||||
@param[in,out] mtr mini-transaction
|
@param[in,out] mtr mini-transaction
|
||||||
@return pointer to page s-latched */
|
@return pointer to page s-latched */
|
||||||
UNIV_INLINE
|
UNIV_INLINE
|
||||||
page_t*
|
buf_block_t*
|
||||||
trx_undo_page_get_s_latched(const page_id_t page_id, mtr_t* mtr);
|
trx_undo_page_get_s_latched(const page_id_t page_id, mtr_t* mtr);
|
||||||
|
|
||||||
/******************************************************************//**
|
/** Get the next record in an undo log.
|
||||||
Returns the next undo log record on the page in the specified log, or
|
@param[in] undo_page undo log page
|
||||||
NULL if none exists.
|
@param[in] rec undo record offset in the page
|
||||||
@return pointer to record, NULL if none */
|
@param[in] page_no undo log header page number
|
||||||
UNIV_INLINE
|
@param[in] offset undo log header offset on page
|
||||||
trx_undo_rec_t*
|
@return undo log record, the page latched, NULL if none */
|
||||||
trx_undo_page_get_next_rec(
|
inline trx_undo_rec_t*
|
||||||
/*=======================*/
|
trx_undo_page_get_next_rec(const buf_block_t *undo_page, uint16_t rec,
|
||||||
trx_undo_rec_t* rec, /*!< in: undo log record */
|
uint32_t page_no, uint16_t offset);
|
||||||
ulint page_no,/*!< in: undo log header page number */
|
/** Get the previous record in an undo log.
|
||||||
ulint offset);/*!< in: undo log header offset on page */
|
@param[in,out] block undo log page
|
||||||
/***********************************************************************//**
|
@param[in] rec undo record offset in the page
|
||||||
Gets the previous record in an undo log.
|
@param[in] page_no undo log header page number
|
||||||
@return undo log record, the page s-latched, NULL if none */
|
@param[in] offset undo log header offset on page
|
||||||
trx_undo_rec_t*
|
@param[in] shared latching mode: true=RW_S_LATCH, false=RW_X_LATCH
|
||||||
trx_undo_get_prev_rec(
|
@param[in,out] mtr mini-transaction
|
||||||
/*==================*/
|
|
||||||
trx_undo_rec_t* rec, /*!< in: undo record */
|
|
||||||
ulint page_no,/*!< in: undo log header page number */
|
|
||||||
ulint offset, /*!< in: undo log header offset on page */
|
|
||||||
bool shared, /*!< in: true=S-latch, false=X-latch */
|
|
||||||
mtr_t* mtr); /*!< in: mtr */
|
|
||||||
/***********************************************************************//**
|
|
||||||
Gets the next record in an undo log.
|
|
||||||
@return undo log record, the page s-latched, NULL if none */
|
|
||||||
trx_undo_rec_t*
|
|
||||||
trx_undo_get_next_rec(
|
|
||||||
/*==================*/
|
|
||||||
trx_undo_rec_t* rec, /*!< in: undo record */
|
|
||||||
ulint page_no,/*!< in: undo log header page number */
|
|
||||||
ulint offset, /*!< in: undo log header offset on page */
|
|
||||||
mtr_t* mtr); /*!< in: mtr */
|
|
||||||
|
|
||||||
/** Gets the first record in an undo log.
|
|
||||||
@param[in] space undo log header space
|
|
||||||
@param[in] page_no undo log header page number
|
|
||||||
@param[in] offset undo log header offset on page
|
|
||||||
@param[in] mode latching mode: RW_S_LATCH or RW_X_LATCH
|
|
||||||
@param[in,out] mtr mini-transaction
|
|
||||||
@return undo log record, the page latched, NULL if none */
|
@return undo log record, the page latched, NULL if none */
|
||||||
trx_undo_rec_t*
|
trx_undo_rec_t*
|
||||||
trx_undo_get_first_rec(
|
trx_undo_get_prev_rec(buf_block_t *&block, uint16_t rec, uint32_t page_no,
|
||||||
fil_space_t* space,
|
uint16_t offset, bool shared, mtr_t *mtr);
|
||||||
ulint page_no,
|
/** Get the next record in an undo log.
|
||||||
ulint offset,
|
@param[in,out] block undo log page
|
||||||
ulint mode,
|
@param[in] rec undo record offset in the page
|
||||||
mtr_t* mtr);
|
@param[in] page_no undo log header page number
|
||||||
|
@param[in] offset undo log header offset on page
|
||||||
|
@param[in,out] mtr mini-transaction
|
||||||
|
@return undo log record, the page latched, NULL if none */
|
||||||
|
trx_undo_rec_t*
|
||||||
|
trx_undo_get_next_rec(buf_block_t *&block, uint16_t rec, uint32_t page_no,
|
||||||
|
uint16_t offset, mtr_t *mtr);
|
||||||
|
|
||||||
|
/** Get the first record in an undo log.
|
||||||
|
@param[in] space undo log header space
|
||||||
|
@param[in] page_no undo log header page number
|
||||||
|
@param[in] offset undo log header offset on page
|
||||||
|
@param[in] mode latching mode: RW_S_LATCH or RW_X_LATCH
|
||||||
|
@param[out] block undo log page
|
||||||
|
@param[in,out] mtr mini-transaction
|
||||||
|
@return undo log record, the page latched, NULL if none */
|
||||||
|
trx_undo_rec_t*
|
||||||
|
trx_undo_get_first_rec(const fil_space_t &space, uint32_t page_no,
|
||||||
|
uint16_t offset, ulint mode, buf_block_t*& block,
|
||||||
|
mtr_t *mtr);
|
||||||
|
|
||||||
/** Allocate an undo log page.
|
/** Allocate an undo log page.
|
||||||
@param[in,out] undo undo log
|
@param[in,out] undo undo log
|
||||||
|
|
@ -193,8 +189,8 @@ freed, but emptied, if all the records there are below the limit.
|
||||||
void
|
void
|
||||||
trx_undo_truncate_start(
|
trx_undo_truncate_start(
|
||||||
trx_rseg_t* rseg,
|
trx_rseg_t* rseg,
|
||||||
ulint hdr_page_no,
|
uint32_t hdr_page_no,
|
||||||
ulint hdr_offset,
|
uint16_t hdr_offset,
|
||||||
undo_no_t limit);
|
undo_no_t limit);
|
||||||
/** Mark that an undo log header belongs to a data dictionary transaction.
|
/** Mark that an undo log header belongs to a data dictionary transaction.
|
||||||
@param[in] trx dictionary transaction
|
@param[in] trx dictionary transaction
|
||||||
|
|
@ -227,7 +223,7 @@ trx_undo_assign_low(trx_t* trx, trx_rseg_t* rseg, trx_undo_t** undo,
|
||||||
/******************************************************************//**
|
/******************************************************************//**
|
||||||
Sets the state of the undo log segment at a transaction finish.
|
Sets the state of the undo log segment at a transaction finish.
|
||||||
@return undo log segment header page, x-latched */
|
@return undo log segment header page, x-latched */
|
||||||
page_t*
|
buf_block_t*
|
||||||
trx_undo_set_state_at_finish(
|
trx_undo_set_state_at_finish(
|
||||||
/*=========================*/
|
/*=========================*/
|
||||||
trx_undo_t* undo, /*!< in: undo log memory copy */
|
trx_undo_t* undo, /*!< in: undo log memory copy */
|
||||||
|
|
@ -237,14 +233,10 @@ trx_undo_set_state_at_finish(
|
||||||
@param[in,out] trx transaction
|
@param[in,out] trx transaction
|
||||||
@param[in,out] undo undo log
|
@param[in,out] undo undo log
|
||||||
@param[in] rollback false=XA PREPARE, true=XA ROLLBACK
|
@param[in] rollback false=XA PREPARE, true=XA ROLLBACK
|
||||||
@param[in,out] mtr mini-transaction
|
@param[in,out] mtr mini-transaction */
|
||||||
@return undo log segment header page, x-latched */
|
void trx_undo_set_state_at_prepare(trx_t *trx, trx_undo_t *undo, bool rollback,
|
||||||
page_t*
|
mtr_t *mtr)
|
||||||
trx_undo_set_state_at_prepare(
|
MY_ATTRIBUTE((nonnull));
|
||||||
trx_t* trx,
|
|
||||||
trx_undo_t* undo,
|
|
||||||
bool rollback,
|
|
||||||
mtr_t* mtr);
|
|
||||||
|
|
||||||
/** Free an old insert or temporary undo log after commit or rollback.
|
/** Free an old insert or temporary undo log after commit or rollback.
|
||||||
The information is not needed after a commit or rollback, therefore
|
The information is not needed after a commit or rollback, therefore
|
||||||
|
|
@ -281,14 +273,14 @@ trx_undo_parse_page_header_reuse(
|
||||||
/** Parse the redo log entry of an undo log page header create.
|
/** Parse the redo log entry of an undo log page header create.
|
||||||
@param[in] ptr redo log record
|
@param[in] ptr redo log record
|
||||||
@param[in] end_ptr end of log buffer
|
@param[in] end_ptr end of log buffer
|
||||||
@param[in,out] page page frame or NULL
|
@param[in,out] block page frame or NULL
|
||||||
@param[in,out] mtr mini-transaction or NULL
|
@param[in,out] mtr mini-transaction or NULL
|
||||||
@return end of log record or NULL */
|
@return end of log record or NULL */
|
||||||
byte*
|
byte*
|
||||||
trx_undo_parse_page_header(
|
trx_undo_parse_page_header(
|
||||||
const byte* ptr,
|
const byte* ptr,
|
||||||
const byte* end_ptr,
|
const byte* end_ptr,
|
||||||
page_t* page,
|
buf_block_t* block,
|
||||||
mtr_t* mtr);
|
mtr_t* mtr);
|
||||||
/** Read an undo log when starting up the database.
|
/** Read an undo log when starting up the database.
|
||||||
@param[in,out] rseg rollback segment
|
@param[in,out] rseg rollback segment
|
||||||
|
|
@ -296,9 +288,9 @@ trx_undo_parse_page_header(
|
||||||
@param[in] page_no undo log segment page number
|
@param[in] page_no undo log segment page number
|
||||||
@param[in,out] max_trx_id the largest observed transaction ID
|
@param[in,out] max_trx_id the largest observed transaction ID
|
||||||
@return size of the undo log in pages */
|
@return size of the undo log in pages */
|
||||||
ulint
|
uint32_t
|
||||||
trx_undo_mem_create_at_db_start(trx_rseg_t* rseg, ulint id, ulint page_no,
|
trx_undo_mem_create_at_db_start(trx_rseg_t *rseg, ulint id, uint32_t page_no,
|
||||||
trx_id_t& max_trx_id);
|
trx_id_t &max_trx_id);
|
||||||
|
|
||||||
#endif /* !UNIV_INNOCHECKSUM */
|
#endif /* !UNIV_INNOCHECKSUM */
|
||||||
|
|
||||||
|
|
@ -340,20 +332,20 @@ struct trx_undo_t {
|
||||||
id */
|
id */
|
||||||
trx_rseg_t* rseg; /*!< rseg where the undo log belongs */
|
trx_rseg_t* rseg; /*!< rseg where the undo log belongs */
|
||||||
/*-----------------------------*/
|
/*-----------------------------*/
|
||||||
ulint hdr_page_no; /*!< page number of the header page in
|
uint32_t hdr_page_no; /*!< page number of the header page in
|
||||||
the undo log */
|
the undo log */
|
||||||
ulint hdr_offset; /*!< header offset of the undo log on
|
uint32_t last_page_no; /*!< page number of the last page in the
|
||||||
the page */
|
|
||||||
ulint last_page_no; /*!< page number of the last page in the
|
|
||||||
undo log; this may differ from
|
undo log; this may differ from
|
||||||
top_page_no during a rollback */
|
top_page_no during a rollback */
|
||||||
ulint size; /*!< current size in pages */
|
uint16_t hdr_offset; /*!< header offset of the undo log on
|
||||||
|
the page */
|
||||||
|
uint32_t size; /*!< current size in pages */
|
||||||
/*-----------------------------*/
|
/*-----------------------------*/
|
||||||
ulint top_page_no; /*!< page number where the latest undo
|
uint32_t top_page_no; /*!< page number where the latest undo
|
||||||
log record was catenated; during
|
log record was catenated; during
|
||||||
rollback the page from which the latest
|
rollback the page from which the latest
|
||||||
undo record was chosen */
|
undo record was chosen */
|
||||||
ulint top_offset; /*!< offset of the latest undo record,
|
uint16_t top_offset; /*!< offset of the latest undo record,
|
||||||
i.e., the topmost element in the undo
|
i.e., the topmost element in the undo
|
||||||
log if we think of it as a stack */
|
log if we think of it as a stack */
|
||||||
undo_no_t top_undo_no; /*!< undo number of the latest record
|
undo_no_t top_undo_no; /*!< undo number of the latest record
|
||||||
|
|
|
||||||
|
|
@ -34,22 +34,17 @@ UNIV_INLINE
|
||||||
roll_ptr_t
|
roll_ptr_t
|
||||||
trx_undo_build_roll_ptr(
|
trx_undo_build_roll_ptr(
|
||||||
/*====================*/
|
/*====================*/
|
||||||
ibool is_insert, /*!< in: TRUE if insert undo log */
|
bool is_insert, /*!< in: TRUE if insert undo log */
|
||||||
ulint rseg_id, /*!< in: rollback segment id */
|
ulint rseg_id, /*!< in: rollback segment id */
|
||||||
ulint page_no, /*!< in: page number */
|
uint32_t page_no, /*!< in: page number */
|
||||||
ulint offset) /*!< in: offset of the undo entry within page */
|
uint16_t offset) /*!< in: offset of the undo entry within page */
|
||||||
{
|
{
|
||||||
roll_ptr_t roll_ptr;
|
compile_time_assert(DATA_ROLL_PTR_LEN == 7);
|
||||||
compile_time_assert(DATA_ROLL_PTR_LEN == 7);
|
ut_ad(rseg_id < TRX_SYS_N_RSEGS);
|
||||||
ut_ad(is_insert == 0 || is_insert == 1);
|
|
||||||
ut_ad(rseg_id < TRX_SYS_N_RSEGS);
|
|
||||||
ut_ad(offset < 65536);
|
|
||||||
|
|
||||||
roll_ptr = (roll_ptr_t) is_insert << ROLL_PTR_INSERT_FLAG_POS
|
return roll_ptr_t{is_insert} << ROLL_PTR_INSERT_FLAG_POS |
|
||||||
| (roll_ptr_t) rseg_id << ROLL_PTR_RSEG_ID_POS
|
roll_ptr_t{rseg_id} << ROLL_PTR_RSEG_ID_POS |
|
||||||
| (roll_ptr_t) page_no << ROLL_PTR_PAGE_POS
|
roll_ptr_t{page_no} << ROLL_PTR_PAGE_POS | offset;
|
||||||
| offset;
|
|
||||||
return(roll_ptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************//**
|
/***********************************************************************//**
|
||||||
|
|
@ -59,35 +54,32 @@ void
|
||||||
trx_undo_decode_roll_ptr(
|
trx_undo_decode_roll_ptr(
|
||||||
/*=====================*/
|
/*=====================*/
|
||||||
roll_ptr_t roll_ptr, /*!< in: roll pointer */
|
roll_ptr_t roll_ptr, /*!< in: roll pointer */
|
||||||
ibool* is_insert, /*!< out: TRUE if insert undo log */
|
bool* is_insert, /*!< out: TRUE if insert undo log */
|
||||||
ulint* rseg_id, /*!< out: rollback segment id */
|
ulint* rseg_id, /*!< out: rollback segment id */
|
||||||
ulint* page_no, /*!< out: page number */
|
uint32_t* page_no, /*!< out: page number */
|
||||||
ulint* offset) /*!< out: offset of the undo
|
uint16_t* offset) /*!< out: offset of the undo
|
||||||
entry within page */
|
entry within page */
|
||||||
{
|
{
|
||||||
compile_time_assert(DATA_ROLL_PTR_LEN == 7);
|
compile_time_assert(DATA_ROLL_PTR_LEN == 7);
|
||||||
ut_ad(roll_ptr < (1ULL << 56));
|
ut_ad(roll_ptr < (1ULL << 56));
|
||||||
*offset = (ulint) roll_ptr & 0xFFFF;
|
*offset= static_cast<uint16_t>(roll_ptr);
|
||||||
roll_ptr >>= 16;
|
*page_no= static_cast<uint32_t>(roll_ptr >> 16);
|
||||||
*page_no = (ulint) roll_ptr & 0xFFFFFFFF;
|
*rseg_id= static_cast<ulint>(roll_ptr >> 48 & 0x7F);
|
||||||
roll_ptr >>= 32;
|
*is_insert= static_cast<bool>(roll_ptr >> 55);
|
||||||
*rseg_id = (ulint) roll_ptr & 0x7F;
|
|
||||||
roll_ptr >>= 7;
|
|
||||||
*is_insert = (ibool) roll_ptr; /* TRUE==1 */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************//**
|
/***********************************************************************//**
|
||||||
Returns TRUE if the roll pointer is of the insert type.
|
Determine if DB_ROLL_PTR is of the insert type.
|
||||||
@return TRUE if insert undo log */
|
@return true if insert */
|
||||||
UNIV_INLINE
|
UNIV_INLINE
|
||||||
ibool
|
bool
|
||||||
trx_undo_roll_ptr_is_insert(
|
trx_undo_roll_ptr_is_insert(
|
||||||
/*========================*/
|
/*========================*/
|
||||||
roll_ptr_t roll_ptr) /*!< in: roll pointer */
|
roll_ptr_t roll_ptr) /*!< in: roll pointer */
|
||||||
{
|
{
|
||||||
compile_time_assert(DATA_ROLL_PTR_LEN == 7);
|
compile_time_assert(DATA_ROLL_PTR_LEN == 7);
|
||||||
ut_ad(roll_ptr < (1ULL << (ROLL_PTR_INSERT_FLAG_POS + 1)));
|
ut_ad(roll_ptr < (1ULL << (ROLL_PTR_INSERT_FLAG_POS + 1)));
|
||||||
return((ibool) (roll_ptr >> ROLL_PTR_INSERT_FLAG_POS));
|
return static_cast<bool>(roll_ptr >> ROLL_PTR_INSERT_FLAG_POS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************//**
|
/***********************************************************************//**
|
||||||
|
|
@ -108,14 +100,13 @@ trx_undo_trx_id_is_insert(
|
||||||
@param[in,out] mtr mini-transaction
|
@param[in,out] mtr mini-transaction
|
||||||
@return pointer to page x-latched */
|
@return pointer to page x-latched */
|
||||||
UNIV_INLINE
|
UNIV_INLINE
|
||||||
page_t*
|
buf_block_t*
|
||||||
trx_undo_page_get(const page_id_t page_id, mtr_t* mtr)
|
trx_undo_page_get(const page_id_t page_id, mtr_t* mtr)
|
||||||
{
|
{
|
||||||
buf_block_t* block = buf_page_get(page_id, 0, RW_X_LATCH, mtr);
|
buf_block_t* block = buf_page_get(page_id, 0, RW_X_LATCH, mtr);
|
||||||
|
|
||||||
buf_block_dbg_add_level(block, SYNC_TRX_UNDO_PAGE);
|
buf_block_dbg_add_level(block, SYNC_TRX_UNDO_PAGE);
|
||||||
|
return block;
|
||||||
return(buf_block_get_frame(block));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets an undo log page and s-latches it.
|
/** Gets an undo log page and s-latches it.
|
||||||
|
|
@ -123,14 +114,14 @@ trx_undo_page_get(const page_id_t page_id, mtr_t* mtr)
|
||||||
@param[in,out] mtr mini-transaction
|
@param[in,out] mtr mini-transaction
|
||||||
@return pointer to page s-latched */
|
@return pointer to page s-latched */
|
||||||
UNIV_INLINE
|
UNIV_INLINE
|
||||||
page_t*
|
buf_block_t*
|
||||||
trx_undo_page_get_s_latched(const page_id_t page_id, mtr_t* mtr)
|
trx_undo_page_get_s_latched(const page_id_t page_id, mtr_t* mtr)
|
||||||
{
|
{
|
||||||
buf_block_t* block = buf_page_get(page_id, 0, RW_S_LATCH, mtr);
|
buf_block_t* block = buf_page_get(page_id, 0, RW_S_LATCH, mtr);
|
||||||
|
|
||||||
buf_block_dbg_add_level(block, SYNC_TRX_UNDO_PAGE);
|
buf_block_dbg_add_level(block, SYNC_TRX_UNDO_PAGE);
|
||||||
|
|
||||||
return(buf_block_get_frame(block));
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Determine the end offset of undo log records of an undo log page.
|
/** Determine the end offset of undo log records of an undo log page.
|
||||||
|
|
@ -139,46 +130,29 @@ trx_undo_page_get_s_latched(const page_id_t page_id, mtr_t* mtr)
|
||||||
@param[in] offset undo log header offset
|
@param[in] offset undo log header offset
|
||||||
@return end offset */
|
@return end offset */
|
||||||
inline
|
inline
|
||||||
uint16_t
|
uint16_t trx_undo_page_get_end(const buf_block_t *undo_page, uint32_t page_no,
|
||||||
trx_undo_page_get_end(const page_t* undo_page, ulint page_no, ulint offset)
|
uint16_t offset)
|
||||||
{
|
{
|
||||||
if (page_no == page_get_page_no(undo_page)) {
|
if (page_no == undo_page->page.id.page_no())
|
||||||
if (uint16_t end = mach_read_from_2(TRX_UNDO_NEXT_LOG
|
if (uint16_t end = mach_read_from_2(TRX_UNDO_NEXT_LOG + offset +
|
||||||
+ offset + undo_page)) {
|
undo_page->frame))
|
||||||
return end;
|
return end;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return mach_read_from_2(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE
|
return mach_read_from_2(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE +
|
||||||
+ undo_page);
|
undo_page->frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************//**
|
/** Get the next record in an undo log.
|
||||||
Returns the next undo log record on the page in the specified log, or
|
@param[in] undo_page undo log page
|
||||||
NULL if none exists.
|
@param[in] rec undo record offset in the page
|
||||||
@return pointer to record, NULL if none */
|
@param[in] page_no undo log header page number
|
||||||
UNIV_INLINE
|
@param[in] offset undo log header offset on page
|
||||||
trx_undo_rec_t*
|
@return undo log record, the page latched, NULL if none */
|
||||||
trx_undo_page_get_next_rec(
|
inline trx_undo_rec_t*
|
||||||
/*=======================*/
|
trx_undo_page_get_next_rec(const buf_block_t *undo_page, uint16_t rec,
|
||||||
trx_undo_rec_t* rec, /*!< in: undo log record */
|
uint32_t page_no, uint16_t offset)
|
||||||
ulint page_no,/*!< in: undo log header page number */
|
|
||||||
ulint offset) /*!< in: undo log header offset on page */
|
|
||||||
{
|
{
|
||||||
page_t* undo_page;
|
uint16_t end= trx_undo_page_get_end(undo_page, page_no, offset);
|
||||||
ulint end;
|
uint16_t next= mach_read_from_2(undo_page->frame + rec);
|
||||||
ulint next;
|
return next == end ? nullptr : undo_page->frame + next;
|
||||||
|
|
||||||
undo_page = (page_t*) ut_align_down(rec, srv_page_size);
|
|
||||||
|
|
||||||
end = trx_undo_page_get_end(undo_page, page_no, offset);
|
|
||||||
|
|
||||||
next = mach_read_from_2(rec);
|
|
||||||
|
|
||||||
if (next == end) {
|
|
||||||
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return(undo_page + next);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ General philosophy of InnoDB redo-logs:
|
||||||
through mtr, which in mtr_commit() writes log records
|
through mtr, which in mtr_commit() writes log records
|
||||||
to the InnoDB redo log.
|
to the InnoDB redo log.
|
||||||
|
|
||||||
2) Normally these changes are performed using a mlog_write_ulint()
|
2) Normally these changes are performed using a mlog_write()
|
||||||
or similar function.
|
or similar function.
|
||||||
|
|
||||||
3) In some page level operations only a code number of a
|
3) In some page level operations only a code number of a
|
||||||
|
|
|
||||||
|
|
@ -1619,7 +1619,7 @@ recv_parse_or_apply_log_rec_body(
|
||||||
break;
|
break;
|
||||||
case MLOG_UNDO_HDR_CREATE:
|
case MLOG_UNDO_HDR_CREATE:
|
||||||
ut_ad(!page || page_type == FIL_PAGE_UNDO_LOG);
|
ut_ad(!page || page_type == FIL_PAGE_UNDO_LOG);
|
||||||
ptr = trx_undo_parse_page_header(ptr, end_ptr, page, mtr);
|
ptr = trx_undo_parse_page_header(ptr, end_ptr, block, mtr);
|
||||||
break;
|
break;
|
||||||
case MLOG_REC_MIN_MARK: case MLOG_COMP_REC_MIN_MARK:
|
case MLOG_REC_MIN_MARK: case MLOG_COMP_REC_MIN_MARK:
|
||||||
ut_ad(!page || fil_page_type_is_index(page_type));
|
ut_ad(!page || fil_page_type_is_index(page_type));
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ mlog_parse_initial_log_record(
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************//**
|
/********************************************************//**
|
||||||
Parses a log record written by mlog_write_ulint, mlog_write_ull, mlog_memset.
|
Parses a log record written by mtr_t::write(), mlog_memset().
|
||||||
@return parsed record end, NULL if not a complete record or a corrupt record */
|
@return parsed record end, NULL if not a complete record or a corrupt record */
|
||||||
const byte*
|
const byte*
|
||||||
mlog_parse_nbytes(
|
mlog_parse_nbytes(
|
||||||
|
|
@ -213,80 +213,58 @@ mlog_parse_nbytes(
|
||||||
return const_cast<byte*>(ptr);
|
return const_cast<byte*>(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************//**
|
/**
|
||||||
Writes 1, 2 or 4 bytes to a file page. Writes the corresponding log
|
Write a log record for writing 1, 2, 4, or 8 bytes.
|
||||||
record to the mini-transaction log if mtr is not NULL. */
|
@param[in] block file page
|
||||||
void
|
@param[in,out] ptr pointer in file page
|
||||||
mlog_write_ulint(
|
@param[in] l number of bytes to write
|
||||||
/*=============*/
|
@param[in,out] log_ptr log record buffer
|
||||||
byte* ptr, /*!< in: pointer where to write */
|
@param[in,out] mtr mini-transaction */
|
||||||
ulint val, /*!< in: value to write */
|
static byte *
|
||||||
mlog_id_t type, /*!< in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */
|
mlog_log_write_low(const buf_block_t &block, byte *ptr, mlog_id_t l,
|
||||||
mtr_t* mtr) /*!< in: mini-transaction handle */
|
byte *log_ptr, mtr_t &mtr)
|
||||||
{
|
{
|
||||||
switch (type) {
|
ut_ad(block.page.state == BUF_BLOCK_FILE_PAGE);
|
||||||
case MLOG_1BYTE:
|
ut_ad(ptr >= block.frame + FIL_PAGE_OFFSET);
|
||||||
mach_write_to_1(ptr, val);
|
ut_ad(ptr + unsigned(l) <= &block.frame[srv_page_size - FIL_PAGE_DATA_END]);
|
||||||
break;
|
log_ptr= mlog_write_initial_log_record_low(l,
|
||||||
case MLOG_2BYTES:
|
block.page.id.space(),
|
||||||
mach_write_to_2(ptr, val);
|
block.page.id.page_no(),
|
||||||
break;
|
log_ptr, &mtr);
|
||||||
case MLOG_4BYTES:
|
mach_write_to_2(log_ptr, page_offset(ptr));
|
||||||
mach_write_to_4(ptr, val);
|
return log_ptr + 2;
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ut_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mtr != 0) {
|
|
||||||
byte* log_ptr = mlog_open(mtr, 11 + 2 + 5);
|
|
||||||
|
|
||||||
/* If no logging is requested, we may return now */
|
|
||||||
|
|
||||||
if (log_ptr != 0) {
|
|
||||||
|
|
||||||
log_ptr = mlog_write_initial_log_record_fast(
|
|
||||||
ptr, type, log_ptr, mtr);
|
|
||||||
|
|
||||||
mach_write_to_2(log_ptr, page_offset(ptr));
|
|
||||||
log_ptr += 2;
|
|
||||||
|
|
||||||
log_ptr += mach_write_compressed(log_ptr, val);
|
|
||||||
|
|
||||||
mlog_close(mtr, log_ptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************//**
|
/**
|
||||||
Writes 8 bytes to a file page. Writes the corresponding log
|
Write a log record for writing 1, 2, or 4 bytes.
|
||||||
record to the mini-transaction log, only if mtr is not NULL */
|
@param[in] block file page
|
||||||
void
|
@param[in,out] ptr pointer in file page
|
||||||
mlog_write_ull(
|
@param[in] l number of bytes to write
|
||||||
/*===========*/
|
@param[in,out] log_ptr log record buffer
|
||||||
byte* ptr, /*!< in: pointer where to write */
|
@param[in] val value to write */
|
||||||
ib_uint64_t val, /*!< in: value to write */
|
void mtr_t::log_write(const buf_block_t &block, byte *ptr, mlog_id_t l,
|
||||||
mtr_t* mtr) /*!< in: mini-transaction handle */
|
byte *log_ptr, uint32_t val)
|
||||||
{
|
{
|
||||||
mach_write_to_8(ptr, val);
|
ut_ad(l == MLOG_1BYTE || l == MLOG_2BYTES || l == MLOG_4BYTES);
|
||||||
|
log_ptr= mlog_log_write_low(block, ptr, l, log_ptr, *this);
|
||||||
|
log_ptr+= mach_write_compressed(log_ptr, val);
|
||||||
|
mlog_close(this, log_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
if (mtr != 0) {
|
/**
|
||||||
byte* log_ptr = mlog_open(mtr, 11 + 2 + 9);
|
Write a log record for writing 8 bytes.
|
||||||
|
@param[in] block file page
|
||||||
/* If no logging is requested, we may return now */
|
@param[in,out] ptr pointer in file page
|
||||||
if (log_ptr != 0) {
|
@param[in] l number of bytes to write
|
||||||
|
@param[in,out] log_ptr log record buffer
|
||||||
log_ptr = mlog_write_initial_log_record_fast(
|
@param[in] val value to write */
|
||||||
ptr, MLOG_8BYTES, log_ptr, mtr);
|
void mtr_t::log_write(const buf_block_t &block, byte *ptr, mlog_id_t l,
|
||||||
|
byte *log_ptr, uint64_t val)
|
||||||
mach_write_to_2(log_ptr, page_offset(ptr));
|
{
|
||||||
log_ptr += 2;
|
ut_ad(l == MLOG_8BYTES);
|
||||||
|
log_ptr= mlog_log_write_low(block, ptr, l, log_ptr, *this);
|
||||||
log_ptr += mach_u64_write_compressed(log_ptr, val);
|
log_ptr+= mach_u64_write_compressed(log_ptr, val);
|
||||||
|
mlog_close(this, log_ptr);
|
||||||
mlog_close(mtr, log_ptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************//**
|
/********************************************************//**
|
||||||
|
|
@ -402,7 +380,7 @@ mlog_parse_string(
|
||||||
@param[in] val the data byte to write
|
@param[in] val the data byte to write
|
||||||
@param[in,out] mtr mini-transaction */
|
@param[in,out] mtr mini-transaction */
|
||||||
void
|
void
|
||||||
mlog_memset(buf_block_t* b, ulint ofs, ulint len, byte val, mtr_t* mtr)
|
mlog_memset(const buf_block_t* b, ulint ofs, ulint len, byte val, mtr_t* mtr)
|
||||||
{
|
{
|
||||||
ut_ad(len);
|
ut_ad(len);
|
||||||
ut_ad(ofs <= ulint(srv_page_size));
|
ut_ad(ofs <= ulint(srv_page_size));
|
||||||
|
|
|
||||||
|
|
@ -196,24 +196,19 @@ page_set_max_trx_id(
|
||||||
trx_id_t trx_id, /*!< in: transaction id */
|
trx_id_t trx_id, /*!< in: transaction id */
|
||||||
mtr_t* mtr) /*!< in/out: mini-transaction, or NULL */
|
mtr_t* mtr) /*!< in/out: mini-transaction, or NULL */
|
||||||
{
|
{
|
||||||
page_t* page = buf_block_get_frame(block);
|
ut_ad(!mtr || mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
|
||||||
ut_ad(!mtr || mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
|
static_assert((PAGE_HEADER + PAGE_MAX_TRX_ID) % 8 == 0, "alignment");
|
||||||
|
byte *max_trx_id= static_cast<byte*>(MY_ASSUME_ALIGNED(PAGE_MAX_TRX_ID
|
||||||
|
+ PAGE_HEADER
|
||||||
|
+ block->frame, 8));
|
||||||
|
|
||||||
/* It is not necessary to write this change to the redo log, as
|
if (UNIV_LIKELY_NULL(page_zip))
|
||||||
during a database recovery we assume that the max trx id of every
|
{
|
||||||
page is the maximum trx id assigned before the crash. */
|
mach_write_to_8(max_trx_id, trx_id);
|
||||||
|
page_zip_write_header(page_zip, max_trx_id, 8, mtr);
|
||||||
if (page_zip) {
|
}
|
||||||
mach_write_to_8(page + (PAGE_HEADER + PAGE_MAX_TRX_ID), trx_id);
|
else
|
||||||
page_zip_write_header(page_zip,
|
mtr->write<8>(*block, max_trx_id, trx_id);
|
||||||
page + (PAGE_HEADER + PAGE_MAX_TRX_ID),
|
|
||||||
8, mtr);
|
|
||||||
} else if (mtr) {
|
|
||||||
mlog_write_ull(page + (PAGE_HEADER + PAGE_MAX_TRX_ID),
|
|
||||||
trx_id, mtr);
|
|
||||||
} else {
|
|
||||||
mach_write_to_8(page + (PAGE_HEADER + PAGE_MAX_TRX_ID), trx_id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Persist the AUTO_INCREMENT value on a clustered index root page.
|
/** Persist the AUTO_INCREMENT value on a clustered index root page.
|
||||||
|
|
@ -227,27 +222,23 @@ page_set_max_trx_id(
|
||||||
void
|
void
|
||||||
page_set_autoinc(
|
page_set_autoinc(
|
||||||
buf_block_t* block,
|
buf_block_t* block,
|
||||||
const dict_index_t* index MY_ATTRIBUTE((unused)),
|
|
||||||
ib_uint64_t autoinc,
|
ib_uint64_t autoinc,
|
||||||
mtr_t* mtr,
|
mtr_t* mtr,
|
||||||
bool reset)
|
bool reset)
|
||||||
{
|
{
|
||||||
ut_ad(mtr_memo_contains_flagged(
|
ut_ad(mtr->memo_contains_flagged(block, MTR_MEMO_PAGE_X_FIX |
|
||||||
mtr, block, MTR_MEMO_PAGE_X_FIX | MTR_MEMO_PAGE_SX_FIX));
|
MTR_MEMO_PAGE_SX_FIX));
|
||||||
ut_ad(index->is_primary());
|
|
||||||
ut_ad(index->page == block->page.id.page_no());
|
|
||||||
ut_ad(index->table->space_id == block->page.id.space());
|
|
||||||
|
|
||||||
byte* field = PAGE_HEADER + PAGE_ROOT_AUTO_INC
|
byte *field= PAGE_HEADER + PAGE_ROOT_AUTO_INC + block->frame;
|
||||||
+ buf_block_get_frame(block);
|
if (!reset && mach_read_from_8(field) >= autoinc)
|
||||||
if (!reset && mach_read_from_8(field) >= autoinc) {
|
/* nothing to update */;
|
||||||
/* nothing to update */
|
else if (page_zip_des_t* page_zip = buf_block_get_page_zip(block))
|
||||||
} else if (page_zip_des_t* page_zip = buf_block_get_page_zip(block)) {
|
{
|
||||||
mach_write_to_8(field, autoinc);
|
mach_write_to_8(field, autoinc);
|
||||||
page_zip_write_header(page_zip, field, 8, mtr);
|
page_zip_write_header(page_zip, field, 8, mtr);
|
||||||
} else {
|
}
|
||||||
mlog_write_ull(field, autoinc, mtr);
|
else
|
||||||
}
|
mtr->write<8,mtr_t::OPT>(*block, field, autoinc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The page infimum and supremum of an empty page in ROW_FORMAT=REDUNDANT */
|
/** The page infimum and supremum of an empty page in ROW_FORMAT=REDUNDANT */
|
||||||
|
|
@ -483,12 +474,12 @@ page_create_empty(
|
||||||
page_header_get_field(page, PAGE_LEVEL),
|
page_header_get_field(page, PAGE_LEVEL),
|
||||||
max_trx_id, mtr);
|
max_trx_id, mtr);
|
||||||
} else {
|
} else {
|
||||||
page_create(block, mtr, page_is_comp(page),
|
page_create(block, mtr, index->table->not_redundant(),
|
||||||
dict_index_is_spatial(index));
|
index->is_spatial());
|
||||||
|
|
||||||
if (max_trx_id) {
|
if (max_trx_id) {
|
||||||
mlog_write_ull(PAGE_HEADER + PAGE_MAX_TRX_ID + page,
|
mtr->write<8>(*block, PAGE_HEADER + PAGE_MAX_TRX_ID
|
||||||
max_trx_id, mtr);
|
+ block->frame, max_trx_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -581,12 +572,13 @@ page_copy_rec_list_end(
|
||||||
{
|
{
|
||||||
page_t* new_page = buf_block_get_frame(new_block);
|
page_t* new_page = buf_block_get_frame(new_block);
|
||||||
page_zip_des_t* new_page_zip = buf_block_get_page_zip(new_block);
|
page_zip_des_t* new_page_zip = buf_block_get_page_zip(new_block);
|
||||||
page_t* page = page_align(rec);
|
page_t* page = block->frame;
|
||||||
rec_t* ret = page_rec_get_next(
|
rec_t* ret = page_rec_get_next(
|
||||||
page_get_infimum_rec(new_page));
|
page_get_infimum_rec(new_page));
|
||||||
ulint num_moved = 0;
|
ulint num_moved = 0;
|
||||||
rtr_rec_move_t* rec_move = NULL;
|
rtr_rec_move_t* rec_move = NULL;
|
||||||
mem_heap_t* heap = NULL;
|
mem_heap_t* heap = NULL;
|
||||||
|
ut_ad(page_align(rec) == page);
|
||||||
|
|
||||||
#ifdef UNIV_ZIP_DEBUG
|
#ifdef UNIV_ZIP_DEBUG
|
||||||
if (new_page_zip) {
|
if (new_page_zip) {
|
||||||
|
|
@ -810,8 +802,9 @@ page_copy_rec_list_start(
|
||||||
for MVCC. */
|
for MVCC. */
|
||||||
if (is_leaf && dict_index_is_sec_or_ibuf(index)
|
if (is_leaf && dict_index_is_sec_or_ibuf(index)
|
||||||
&& !index->table->is_temporary()) {
|
&& !index->table->is_temporary()) {
|
||||||
page_update_max_trx_id(new_block, NULL,
|
page_update_max_trx_id(new_block,
|
||||||
page_get_max_trx_id(page_align(rec)),
|
new_page_zip,
|
||||||
|
page_get_max_trx_id(block->frame),
|
||||||
mtr);
|
mtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -979,7 +972,6 @@ page_delete_rec_list_end(
|
||||||
rec_t* prev_rec;
|
rec_t* prev_rec;
|
||||||
ulint n_owned;
|
ulint n_owned;
|
||||||
page_zip_des_t* page_zip = buf_block_get_page_zip(block);
|
page_zip_des_t* page_zip = buf_block_get_page_zip(block);
|
||||||
page_t* page = page_align(rec);
|
|
||||||
mem_heap_t* heap = NULL;
|
mem_heap_t* heap = NULL;
|
||||||
ulint offsets_[REC_OFFS_NORMAL_SIZE];
|
ulint offsets_[REC_OFFS_NORMAL_SIZE];
|
||||||
ulint* offsets = offsets_;
|
ulint* offsets = offsets_;
|
||||||
|
|
@ -987,8 +979,9 @@ page_delete_rec_list_end(
|
||||||
|
|
||||||
ut_ad(size == ULINT_UNDEFINED || size < srv_page_size);
|
ut_ad(size == ULINT_UNDEFINED || size < srv_page_size);
|
||||||
ut_ad(!page_zip || page_rec_is_comp(rec));
|
ut_ad(!page_zip || page_rec_is_comp(rec));
|
||||||
|
ut_ad(page_align(rec) == block->frame);
|
||||||
#ifdef UNIV_ZIP_DEBUG
|
#ifdef UNIV_ZIP_DEBUG
|
||||||
ut_a(!page_zip || page_zip_validate(page_zip, page, index));
|
ut_a(!page_zip || page_zip_validate(page_zip, block->frame, index));
|
||||||
#endif /* UNIV_ZIP_DEBUG */
|
#endif /* UNIV_ZIP_DEBUG */
|
||||||
|
|
||||||
if (page_rec_is_supremum(rec)) {
|
if (page_rec_is_supremum(rec)) {
|
||||||
|
|
@ -1006,19 +999,21 @@ page_delete_rec_list_end(
|
||||||
only be executed when applying redo log that was
|
only be executed when applying redo log that was
|
||||||
generated by an older version of MySQL. */
|
generated by an older version of MySQL. */
|
||||||
} else if (page_rec_is_infimum(rec)
|
} else if (page_rec_is_infimum(rec)
|
||||||
|| n_recs == page_get_n_recs(page)) {
|
|| n_recs == page_get_n_recs(block->frame)) {
|
||||||
delete_all:
|
delete_all:
|
||||||
/* We are deleting all records. */
|
/* We are deleting all records. */
|
||||||
page_create_empty(block, index, mtr);
|
page_create_empty(block, index, mtr);
|
||||||
return;
|
return;
|
||||||
} else if (page_is_comp(page)) {
|
} else if (page_is_comp(block->frame)) {
|
||||||
if (page_rec_get_next_low(page + PAGE_NEW_INFIMUM, 1) == rec) {
|
if (page_rec_get_next_low(block->frame + PAGE_NEW_INFIMUM, 1)
|
||||||
|
== rec) {
|
||||||
/* We are deleting everything from the first
|
/* We are deleting everything from the first
|
||||||
user record onwards. */
|
user record onwards. */
|
||||||
goto delete_all;
|
goto delete_all;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (page_rec_get_next_low(page + PAGE_OLD_INFIMUM, 0) == rec) {
|
if (page_rec_get_next_low(block->frame + PAGE_OLD_INFIMUM, 0)
|
||||||
|
== rec) {
|
||||||
/* We are deleting everything from the first
|
/* We are deleting everything from the first
|
||||||
user record onwards. */
|
user record onwards. */
|
||||||
goto delete_all;
|
goto delete_all;
|
||||||
|
|
@ -1028,23 +1023,23 @@ page_delete_rec_list_end(
|
||||||
/* Reset the last insert info in the page header and increment
|
/* Reset the last insert info in the page header and increment
|
||||||
the modify clock for the frame */
|
the modify clock for the frame */
|
||||||
|
|
||||||
page_header_set_ptr(page, page_zip, PAGE_LAST_INSERT, NULL);
|
page_header_set_ptr(block->frame, page_zip, PAGE_LAST_INSERT, NULL);
|
||||||
|
|
||||||
/* The page gets invalid for optimistic searches: increment the
|
/* The page gets invalid for optimistic searches: increment the
|
||||||
frame modify clock */
|
frame modify clock */
|
||||||
|
|
||||||
buf_block_modify_clock_inc(block);
|
buf_block_modify_clock_inc(block);
|
||||||
|
|
||||||
page_delete_rec_list_write_log(rec, index, page_is_comp(page)
|
page_delete_rec_list_write_log(rec, index, page_is_comp(block->frame)
|
||||||
? MLOG_COMP_LIST_END_DELETE
|
? MLOG_COMP_LIST_END_DELETE
|
||||||
: MLOG_LIST_END_DELETE, mtr);
|
: MLOG_LIST_END_DELETE, mtr);
|
||||||
|
|
||||||
const bool is_leaf = page_is_leaf(page);
|
const bool is_leaf = page_is_leaf(block->frame);
|
||||||
|
|
||||||
if (page_zip) {
|
if (page_zip) {
|
||||||
mtr_log_t log_mode;
|
mtr_log_t log_mode;
|
||||||
|
|
||||||
ut_a(page_is_comp(page));
|
ut_ad(page_is_comp(block->frame));
|
||||||
/* Individual deletes are not logged */
|
/* Individual deletes are not logged */
|
||||||
|
|
||||||
log_mode = mtr_set_log_mode(mtr, MTR_LOG_NONE);
|
log_mode = mtr_set_log_mode(mtr, MTR_LOG_NONE);
|
||||||
|
|
@ -1057,7 +1052,7 @@ page_delete_rec_list_end(
|
||||||
ULINT_UNDEFINED, &heap);
|
ULINT_UNDEFINED, &heap);
|
||||||
rec = rec_get_next_ptr(rec, TRUE);
|
rec = rec_get_next_ptr(rec, TRUE);
|
||||||
#ifdef UNIV_ZIP_DEBUG
|
#ifdef UNIV_ZIP_DEBUG
|
||||||
ut_a(page_zip_validate(page_zip, page, index));
|
ut_a(page_zip_validate(page_zip, block->frame, index));
|
||||||
#endif /* UNIV_ZIP_DEBUG */
|
#endif /* UNIV_ZIP_DEBUG */
|
||||||
page_cur_delete_rec(&cur, index, offsets, mtr);
|
page_cur_delete_rec(&cur, index, offsets, mtr);
|
||||||
} while (page_offset(rec) != PAGE_NEW_SUPREMUM);
|
} while (page_offset(rec) != PAGE_NEW_SUPREMUM);
|
||||||
|
|
@ -1074,7 +1069,7 @@ page_delete_rec_list_end(
|
||||||
|
|
||||||
prev_rec = page_rec_get_prev(rec);
|
prev_rec = page_rec_get_prev(rec);
|
||||||
|
|
||||||
last_rec = page_rec_get_prev(page_get_supremum_rec(page));
|
last_rec = page_rec_get_prev(page_get_supremum_rec(block->frame));
|
||||||
|
|
||||||
bool scrub = srv_immediate_scrub_data_uncompressed;
|
bool scrub = srv_immediate_scrub_data_uncompressed;
|
||||||
if ((size == ULINT_UNDEFINED) || (n_recs == ULINT_UNDEFINED) ||
|
if ((size == ULINT_UNDEFINED) || (n_recs == ULINT_UNDEFINED) ||
|
||||||
|
|
@ -1090,7 +1085,7 @@ page_delete_rec_list_end(
|
||||||
is_leaf,
|
is_leaf,
|
||||||
ULINT_UNDEFINED, &heap);
|
ULINT_UNDEFINED, &heap);
|
||||||
s = rec_offs_size(offsets);
|
s = rec_offs_size(offsets);
|
||||||
ut_ad(ulint(rec2 - page) + s
|
ut_ad(ulint(rec2 - block->frame) + s
|
||||||
- rec_offs_extra_size(offsets)
|
- rec_offs_extra_size(offsets)
|
||||||
< srv_page_size);
|
< srv_page_size);
|
||||||
ut_ad(size + s < srv_page_size);
|
ut_ad(size + s < srv_page_size);
|
||||||
|
|
@ -1116,7 +1111,7 @@ page_delete_rec_list_end(
|
||||||
of the records owned by the supremum record, as it is allowed to be
|
of the records owned by the supremum record, as it is allowed to be
|
||||||
less than PAGE_DIR_SLOT_MIN_N_OWNED */
|
less than PAGE_DIR_SLOT_MIN_N_OWNED */
|
||||||
|
|
||||||
if (page_is_comp(page)) {
|
if (page_is_comp(block->frame)) {
|
||||||
rec_t* rec2 = rec;
|
rec_t* rec2 = rec;
|
||||||
ulint count = 0;
|
ulint count = 0;
|
||||||
|
|
||||||
|
|
@ -1131,7 +1126,7 @@ page_delete_rec_list_end(
|
||||||
n_owned = rec_get_n_owned_new(rec2) - count;
|
n_owned = rec_get_n_owned_new(rec2) - count;
|
||||||
slot_index = page_dir_find_owner_slot(rec2);
|
slot_index = page_dir_find_owner_slot(rec2);
|
||||||
ut_ad(slot_index > 0);
|
ut_ad(slot_index > 0);
|
||||||
slot = page_dir_get_nth_slot(page, slot_index);
|
slot = page_dir_get_nth_slot(block->frame, slot_index);
|
||||||
} else {
|
} else {
|
||||||
rec_t* rec2 = rec;
|
rec_t* rec2 = rec;
|
||||||
ulint count = 0;
|
ulint count = 0;
|
||||||
|
|
@ -1147,28 +1142,30 @@ page_delete_rec_list_end(
|
||||||
n_owned = rec_get_n_owned_old(rec2) - count;
|
n_owned = rec_get_n_owned_old(rec2) - count;
|
||||||
slot_index = page_dir_find_owner_slot(rec2);
|
slot_index = page_dir_find_owner_slot(rec2);
|
||||||
ut_ad(slot_index > 0);
|
ut_ad(slot_index > 0);
|
||||||
slot = page_dir_get_nth_slot(page, slot_index);
|
slot = page_dir_get_nth_slot(block->frame, slot_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
page_dir_slot_set_rec(slot, page_get_supremum_rec(page));
|
page_dir_slot_set_rec(slot, page_get_supremum_rec(block->frame));
|
||||||
page_dir_slot_set_n_owned(slot, NULL, n_owned);
|
page_dir_slot_set_n_owned(slot, NULL, n_owned);
|
||||||
|
|
||||||
page_dir_set_n_slots(page, NULL, slot_index + 1);
|
page_dir_set_n_slots(block->frame, NULL, slot_index + 1);
|
||||||
|
|
||||||
/* Remove the record chain segment from the record chain */
|
/* Remove the record chain segment from the record chain */
|
||||||
page_rec_set_next(prev_rec, page_get_supremum_rec(page));
|
page_rec_set_next(prev_rec, page_get_supremum_rec(block->frame));
|
||||||
|
|
||||||
/* Catenate the deleted chain segment to the page free list */
|
/* Catenate the deleted chain segment to the page free list */
|
||||||
|
|
||||||
page_rec_set_next(last_rec, page_header_get_ptr(page, PAGE_FREE));
|
page_rec_set_next(last_rec, page_header_get_ptr(block->frame,
|
||||||
page_header_set_ptr(page, NULL, PAGE_FREE, rec);
|
PAGE_FREE));
|
||||||
|
page_header_set_ptr(block->frame, NULL, PAGE_FREE, rec);
|
||||||
|
|
||||||
page_header_set_field(page, NULL, PAGE_GARBAGE, size
|
page_header_set_field(block->frame, NULL, PAGE_GARBAGE, size
|
||||||
+ page_header_get_field(page, PAGE_GARBAGE));
|
+ page_header_get_field(block->frame,
|
||||||
|
PAGE_GARBAGE));
|
||||||
|
|
||||||
ut_ad(page_get_n_recs(page) > n_recs);
|
ut_ad(page_get_n_recs(block->frame) > n_recs);
|
||||||
page_header_set_field(page, NULL, PAGE_N_RECS,
|
page_header_set_field(block->frame, NULL, PAGE_N_RECS,
|
||||||
(ulint)(page_get_n_recs(page) - n_recs));
|
ulint{page_get_n_recs(block->frame) - n_recs});
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************//**
|
/*************************************************************//**
|
||||||
|
|
|
||||||
|
|
@ -924,12 +924,11 @@ row_purge_upd_exist_or_extern_func(
|
||||||
if (dfield_is_ext(&ufield->new_val)) {
|
if (dfield_is_ext(&ufield->new_val)) {
|
||||||
trx_rseg_t* rseg;
|
trx_rseg_t* rseg;
|
||||||
buf_block_t* block;
|
buf_block_t* block;
|
||||||
ulint internal_offset;
|
|
||||||
byte* data_field;
|
byte* data_field;
|
||||||
ibool is_insert;
|
bool is_insert;
|
||||||
ulint rseg_id;
|
ulint rseg_id;
|
||||||
ulint page_no;
|
uint32_t page_no;
|
||||||
ulint offset;
|
uint16_t offset;
|
||||||
|
|
||||||
/* We use the fact that new_val points to
|
/* We use the fact that new_val points to
|
||||||
undo_rec and get thus the offset of
|
undo_rec and get thus the offset of
|
||||||
|
|
@ -937,7 +936,7 @@ row_purge_upd_exist_or_extern_func(
|
||||||
can calculate from node->roll_ptr the file
|
can calculate from node->roll_ptr the file
|
||||||
address of the new_val data */
|
address of the new_val data */
|
||||||
|
|
||||||
internal_offset = ulint(
|
const uint16_t internal_offset = uint16_t(
|
||||||
static_cast<const byte*>
|
static_cast<const byte*>
|
||||||
(dfield_get_data(&ufield->new_val))
|
(dfield_get_data(&ufield->new_val))
|
||||||
- undo_rec);
|
- undo_rec);
|
||||||
|
|
@ -989,7 +988,7 @@ row_purge_upd_exist_or_extern_func(
|
||||||
index,
|
index,
|
||||||
data_field + dfield_get_len(&ufield->new_val)
|
data_field + dfield_get_len(&ufield->new_val)
|
||||||
- BTR_EXTERN_FIELD_REF_SIZE,
|
- BTR_EXTERN_FIELD_REF_SIZE,
|
||||||
NULL, NULL, NULL, 0, false, &mtr);
|
NULL, NULL, block, 0, false, &mtr);
|
||||||
mtr.commit();
|
mtr.commit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -208,20 +208,22 @@ row_undo_ins_remove_clust_rec(
|
||||||
/* When rolling back the very first instant ADD COLUMN
|
/* When rolling back the very first instant ADD COLUMN
|
||||||
operation, reset the root page to the basic state. */
|
operation, reset the root page to the basic state. */
|
||||||
ut_ad(!index->table->is_temporary());
|
ut_ad(!index->table->is_temporary());
|
||||||
if (page_t* root = btr_root_get(index, &mtr)) {
|
if (buf_block_t* root = btr_root_block_get(index, RW_SX_LATCH,
|
||||||
byte* page_type = root + FIL_PAGE_TYPE;
|
&mtr)) {
|
||||||
|
byte* page_type = root->frame + FIL_PAGE_TYPE;
|
||||||
ut_ad(mach_read_from_2(page_type)
|
ut_ad(mach_read_from_2(page_type)
|
||||||
== FIL_PAGE_TYPE_INSTANT
|
== FIL_PAGE_TYPE_INSTANT
|
||||||
|| mach_read_from_2(page_type)
|
|| mach_read_from_2(page_type)
|
||||||
== FIL_PAGE_INDEX);
|
== FIL_PAGE_INDEX);
|
||||||
mlog_write_ulint(page_type, FIL_PAGE_INDEX,
|
mtr.write<2,mtr_t::OPT>(*root, page_type,
|
||||||
MLOG_2BYTES, &mtr);
|
FIL_PAGE_INDEX);
|
||||||
byte* instant = PAGE_INSTANT + PAGE_HEADER + root;
|
byte* instant = PAGE_INSTANT + PAGE_HEADER
|
||||||
mlog_write_ulint(instant,
|
+ root->frame;
|
||||||
page_ptr_get_direction(instant + 1),
|
mtr.write<2,mtr_t::OPT>(
|
||||||
MLOG_2BYTES, &mtr);
|
*root, instant,
|
||||||
rec_t* infimum = page_get_infimum_rec(root);
|
page_ptr_get_direction(instant + 1));
|
||||||
rec_t* supremum = page_get_supremum_rec(root);
|
rec_t* infimum = page_get_infimum_rec(root->frame);
|
||||||
|
rec_t* supremum = page_get_supremum_rec(root->frame);
|
||||||
static const byte str[8 + 8] = "supremuminfimum";
|
static const byte str[8 + 8] = "supremuminfimum";
|
||||||
if (memcmp(infimum, str + 8, 8)
|
if (memcmp(infimum, str + 8, 8)
|
||||||
|| memcmp(supremum, str, 8)) {
|
|| memcmp(supremum, str, 8)) {
|
||||||
|
|
|
||||||
|
|
@ -335,37 +335,30 @@ static bool row_undo_rec_get(undo_node_t* node)
|
||||||
mtr_t mtr;
|
mtr_t mtr;
|
||||||
mtr.start();
|
mtr.start();
|
||||||
|
|
||||||
page_t* undo_page = trx_undo_page_get_s_latched(
|
buf_block_t* undo_page = trx_undo_page_get_s_latched(
|
||||||
page_id_t(undo->rseg->space->id, undo->top_page_no), &mtr);
|
page_id_t(undo->rseg->space->id, undo->top_page_no), &mtr);
|
||||||
|
|
||||||
ulint offset = undo->top_offset;
|
uint16_t offset = undo->top_offset;
|
||||||
|
|
||||||
trx_undo_rec_t* prev_rec = trx_undo_get_prev_rec(
|
|
||||||
undo_page + offset, undo->hdr_page_no, undo->hdr_offset,
|
|
||||||
true, &mtr);
|
|
||||||
|
|
||||||
if (prev_rec == NULL) {
|
|
||||||
undo->top_undo_no = IB_ID_MAX;
|
|
||||||
ut_ad(undo->empty());
|
|
||||||
} else {
|
|
||||||
page_t* prev_rec_page = page_align(prev_rec);
|
|
||||||
|
|
||||||
if (prev_rec_page != undo_page) {
|
|
||||||
|
|
||||||
|
buf_block_t* prev_page = undo_page;
|
||||||
|
if (trx_undo_rec_t* prev_rec = trx_undo_get_prev_rec(
|
||||||
|
prev_page, offset, undo->hdr_page_no, undo->hdr_offset,
|
||||||
|
true, &mtr)) {
|
||||||
|
if (prev_page != undo_page) {
|
||||||
trx->pages_undone++;
|
trx->pages_undone++;
|
||||||
}
|
}
|
||||||
|
|
||||||
undo->top_page_no = page_get_page_no(prev_rec_page);
|
undo->top_page_no = prev_page->page.id.page_no();
|
||||||
undo->top_offset = ulint(prev_rec - prev_rec_page);
|
undo->top_offset = page_offset(prev_rec);
|
||||||
undo->top_undo_no = trx_undo_rec_get_undo_no(prev_rec);
|
undo->top_undo_no = trx_undo_rec_get_undo_no(prev_rec);
|
||||||
ut_ad(!undo->empty());
|
ut_ad(!undo->empty());
|
||||||
|
} else {
|
||||||
|
undo->top_undo_no = IB_ID_MAX;
|
||||||
|
ut_ad(undo->empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
node->undo_rec = trx_undo_rec_copy(undo_page->frame + offset,
|
||||||
const trx_undo_rec_t* undo_rec = undo_page + offset;
|
node->heap);
|
||||||
node->undo_rec = trx_undo_rec_copy(undo_rec, node->heap);
|
|
||||||
}
|
|
||||||
|
|
||||||
mtr.commit();
|
mtr.commit();
|
||||||
|
|
||||||
switch (trx_undo_rec_get_type(node->undo_rec)) {
|
switch (trx_undo_rec_get_type(node->undo_rec)) {
|
||||||
|
|
|
||||||
|
|
@ -2755,7 +2755,7 @@ row_upd_clust_rec_by_insert(
|
||||||
insert fails, then this disown will be undone
|
insert fails, then this disown will be undone
|
||||||
when the operation is rolled back. */
|
when the operation is rolled back. */
|
||||||
btr_cur_disown_inherited_fields(
|
btr_cur_disown_inherited_fields(
|
||||||
btr_cur_get_page_zip(btr_cur),
|
btr_cur_get_block(btr_cur),
|
||||||
rec, index, offsets, node->update,
|
rec, index, offsets, node->update,
|
||||||
mtr);
|
mtr);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1813,9 +1813,9 @@ dberr_t srv_start(bool create_new_db)
|
||||||
ut_ad(size == fil_system.sys_space
|
ut_ad(size == fil_system.sys_space
|
||||||
->size_in_header);
|
->size_in_header);
|
||||||
size += sum_of_new_sizes;
|
size += sum_of_new_sizes;
|
||||||
mlog_write_ulint(FSP_HEADER_OFFSET + FSP_SIZE
|
mtr.write<4>(*block,
|
||||||
+ block->frame, size,
|
FSP_HEADER_OFFSET + FSP_SIZE
|
||||||
MLOG_4BYTES, &mtr);
|
+ block->frame, size);
|
||||||
fil_system.sys_space->size_in_header = size;
|
fil_system.sys_space->size_in_header = size;
|
||||||
mtr.commit();
|
mtr.commit();
|
||||||
/* Immediately write the log record about
|
/* Immediately write the log record about
|
||||||
|
|
|
||||||
|
|
@ -211,15 +211,16 @@ trx_purge_add_undo_to_history(const trx_t* trx, trx_undo_t*& undo, mtr_t* mtr)
|
||||||
|| undo == trx->rsegs.m_redo.old_insert);
|
|| undo == trx->rsegs.m_redo.old_insert);
|
||||||
trx_rseg_t* rseg = trx->rsegs.m_redo.rseg;
|
trx_rseg_t* rseg = trx->rsegs.m_redo.rseg;
|
||||||
ut_ad(undo->rseg == rseg);
|
ut_ad(undo->rseg == rseg);
|
||||||
trx_rsegf_t* rseg_header = trx_rsegf_get(
|
buf_block_t* rseg_header = trx_rsegf_get(
|
||||||
rseg->space, rseg->page_no, mtr);
|
rseg->space, rseg->page_no, mtr);
|
||||||
page_t* undo_page = trx_undo_set_state_at_finish(
|
buf_block_t* undo_page = trx_undo_set_state_at_finish(
|
||||||
undo, mtr);
|
undo, mtr);
|
||||||
trx_ulogf_t* undo_header = undo_page + undo->hdr_offset;
|
trx_ulogf_t* undo_header = undo_page->frame + undo->hdr_offset;
|
||||||
|
|
||||||
ut_ad(mach_read_from_2(undo_header + TRX_UNDO_NEEDS_PURGE) <= 1);
|
ut_ad(mach_read_from_2(undo_header + TRX_UNDO_NEEDS_PURGE) <= 1);
|
||||||
|
|
||||||
if (UNIV_UNLIKELY(mach_read_from_4(TRX_RSEG_FORMAT + rseg_header))) {
|
if (UNIV_UNLIKELY(mach_read_from_4(TRX_RSEG + TRX_RSEG_FORMAT
|
||||||
|
+ rseg_header->frame))) {
|
||||||
/* This database must have been upgraded from
|
/* This database must have been upgraded from
|
||||||
before MariaDB 10.3.5. */
|
before MariaDB 10.3.5. */
|
||||||
trx_rseg_format_upgrade(rseg_header, mtr);
|
trx_rseg_format_upgrade(rseg_header, mtr);
|
||||||
|
|
@ -228,23 +229,27 @@ trx_purge_add_undo_to_history(const trx_t* trx, trx_undo_t*& undo, mtr_t* mtr)
|
||||||
if (undo->state != TRX_UNDO_CACHED) {
|
if (undo->state != TRX_UNDO_CACHED) {
|
||||||
/* The undo log segment will not be reused */
|
/* The undo log segment will not be reused */
|
||||||
ut_a(undo->id < TRX_RSEG_N_SLOTS);
|
ut_a(undo->id < TRX_RSEG_N_SLOTS);
|
||||||
trx_rsegf_set_nth_undo(rseg_header, undo->id, FIL_NULL, mtr);
|
compile_time_assert(FIL_NULL == 0xffffffff);
|
||||||
|
mlog_memset(TRX_RSEG + TRX_RSEG_UNDO_SLOTS
|
||||||
|
+ undo->id * TRX_RSEG_SLOT_SIZE
|
||||||
|
+ rseg_header->frame, 4, 0xff, mtr);
|
||||||
|
|
||||||
MONITOR_DEC(MONITOR_NUM_UNDO_SLOT_USED);
|
MONITOR_DEC(MONITOR_NUM_UNDO_SLOT_USED);
|
||||||
|
|
||||||
uint32_t hist_size = mach_read_from_4(TRX_RSEG_HISTORY_SIZE
|
uint32_t hist_size = mach_read_from_4(TRX_RSEG_HISTORY_SIZE
|
||||||
+ rseg_header);
|
+ TRX_RSEG
|
||||||
|
+ rseg_header->frame);
|
||||||
|
|
||||||
ut_ad(undo->size == flst_get_len(TRX_UNDO_SEG_HDR
|
ut_ad(undo->size == flst_get_len(TRX_UNDO_SEG_HDR
|
||||||
+ TRX_UNDO_PAGE_LIST
|
+ TRX_UNDO_PAGE_LIST
|
||||||
+ undo_page));
|
+ undo_page->frame));
|
||||||
|
|
||||||
mlog_write_ulint(
|
mtr->write<4>(*rseg_header, TRX_RSEG + TRX_RSEG_HISTORY_SIZE
|
||||||
rseg_header + TRX_RSEG_HISTORY_SIZE,
|
+ rseg_header->frame,
|
||||||
hist_size + undo->size, MLOG_4BYTES, mtr);
|
hist_size + undo->size);
|
||||||
|
mtr->write<8>(*rseg_header, TRX_RSEG + TRX_RSEG_MAX_TRX_ID
|
||||||
mlog_write_ull(rseg_header + TRX_RSEG_MAX_TRX_ID,
|
+ rseg_header->frame,
|
||||||
trx_sys.get_max_trx_id(), mtr);
|
trx_sys.get_max_trx_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* After the purge thread has been given permission to exit,
|
/* After the purge thread has been given permission to exit,
|
||||||
|
|
@ -287,16 +292,17 @@ trx_purge_add_undo_to_history(const trx_t* trx, trx_undo_t*& undo, mtr_t* mtr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add the log as the first in the history list */
|
/* Add the log as the first in the history list */
|
||||||
flst_add_first(rseg_header + TRX_RSEG_HISTORY,
|
flst_add_first(rseg_header, TRX_RSEG + TRX_RSEG_HISTORY,
|
||||||
undo_header + TRX_UNDO_HISTORY_NODE, mtr);
|
undo_page, undo->hdr_offset + TRX_UNDO_HISTORY_NODE,
|
||||||
|
mtr);
|
||||||
|
|
||||||
mlog_write_ull(undo_header + TRX_UNDO_TRX_NO, trx->no, mtr);
|
mtr->write<8>(*undo_page, undo_header + TRX_UNDO_TRX_NO, trx->no);
|
||||||
/* This is needed for upgrading old undo log pages from
|
/* This is needed for upgrading old undo log pages from
|
||||||
before MariaDB 10.3.1. */
|
before MariaDB 10.3.1. */
|
||||||
if (UNIV_UNLIKELY(!mach_read_from_2(undo_header
|
if (UNIV_UNLIKELY(!mach_read_from_2(undo_header
|
||||||
+ TRX_UNDO_NEEDS_PURGE))) {
|
+ TRX_UNDO_NEEDS_PURGE))) {
|
||||||
mlog_write_ulint(undo_header + TRX_UNDO_NEEDS_PURGE, 1,
|
mtr->write<2>(*undo_page, undo_header + TRX_UNDO_NEEDS_PURGE,
|
||||||
MLOG_2BYTES, mtr);
|
1U);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rseg->last_page_no == FIL_NULL) {
|
if (rseg->last_page_no == FIL_NULL) {
|
||||||
|
|
@ -320,19 +326,16 @@ trx_purge_add_undo_to_history(const trx_t* trx, trx_undo_t*& undo, mtr_t* mtr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Remove undo log header from the history list.
|
/** Remove undo log header from the history list.
|
||||||
@param[in,out] rseg_hdr rollback segment header
|
@param[in,out] rseg rollback segment header page
|
||||||
@param[in] log_hdr undo log segment header
|
@param[in] log undo log segment header page
|
||||||
@param[in,out] mtr mini transaction. */
|
@param[in] offset byte offset in the undo log segment header page
|
||||||
static
|
@param[in,out] mtr mini-transaction */
|
||||||
void
|
static void trx_purge_remove_log_hdr(buf_block_t *rseg, buf_block_t* log,
|
||||||
trx_purge_remove_log_hdr(
|
uint16_t offset, mtr_t *mtr)
|
||||||
trx_rsegf_t* rseg_hdr,
|
|
||||||
trx_ulogf_t* log_hdr,
|
|
||||||
mtr_t* mtr)
|
|
||||||
{
|
{
|
||||||
flst_remove(rseg_hdr + TRX_RSEG_HISTORY,
|
flst_remove(rseg, TRX_RSEG + TRX_RSEG_HISTORY,
|
||||||
log_hdr + TRX_UNDO_HISTORY_NODE, mtr);
|
log, offset + TRX_UNDO_HISTORY_NODE, mtr);
|
||||||
trx_sys.rseg_history_len--;
|
trx_sys.rseg_history_len--;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Free an undo log segment, and remove the header from the history list.
|
/** Free an undo log segment, and remove the header from the history list.
|
||||||
|
|
@ -343,14 +346,12 @@ void
|
||||||
trx_purge_free_segment(trx_rseg_t* rseg, fil_addr_t hdr_addr)
|
trx_purge_free_segment(trx_rseg_t* rseg, fil_addr_t hdr_addr)
|
||||||
{
|
{
|
||||||
mtr_t mtr;
|
mtr_t mtr;
|
||||||
trx_rsegf_t* rseg_hdr;
|
|
||||||
page_t* undo_page;
|
|
||||||
|
|
||||||
mtr.start();
|
mtr.start();
|
||||||
mutex_enter(&rseg->mutex);
|
mutex_enter(&rseg->mutex);
|
||||||
|
|
||||||
rseg_hdr = trx_rsegf_get(rseg->space, rseg->page_no, &mtr);
|
buf_block_t* rseg_hdr = trx_rsegf_get(rseg->space, rseg->page_no, &mtr);
|
||||||
undo_page = trx_undo_page_get(
|
buf_block_t* block = trx_undo_page_get(
|
||||||
page_id_t(rseg->space->id, hdr_addr.page), &mtr);
|
page_id_t(rseg->space->id, hdr_addr.page), &mtr);
|
||||||
|
|
||||||
/* Mark the last undo log totally purged, so that if the
|
/* Mark the last undo log totally purged, so that if the
|
||||||
|
|
@ -358,12 +359,12 @@ trx_purge_free_segment(trx_rseg_t* rseg, fil_addr_t hdr_addr)
|
||||||
again. The list of pages in the undo log tail gets
|
again. The list of pages in the undo log tail gets
|
||||||
inconsistent during the freeing of the segment, and therefore
|
inconsistent during the freeing of the segment, and therefore
|
||||||
purge should not try to access them again. */
|
purge should not try to access them again. */
|
||||||
mlog_write_ulint(undo_page + hdr_addr.boffset + TRX_UNDO_NEEDS_PURGE,
|
mtr.write<2>(*block, block->frame + hdr_addr.boffset
|
||||||
0, MLOG_2BYTES, &mtr);
|
+ TRX_UNDO_NEEDS_PURGE, 0U);
|
||||||
|
|
||||||
while (!fseg_free_step_not_header(
|
while (!fseg_free_step_not_header(
|
||||||
TRX_UNDO_SEG_HDR + TRX_UNDO_FSEG_HEADER
|
TRX_UNDO_SEG_HDR + TRX_UNDO_FSEG_HEADER
|
||||||
+ undo_page, false, &mtr)) {
|
+ block->frame, false, &mtr)) {
|
||||||
mutex_exit(&rseg->mutex);
|
mutex_exit(&rseg->mutex);
|
||||||
|
|
||||||
mtr.commit();
|
mtr.commit();
|
||||||
|
|
@ -373,7 +374,7 @@ trx_purge_free_segment(trx_rseg_t* rseg, fil_addr_t hdr_addr)
|
||||||
|
|
||||||
rseg_hdr = trx_rsegf_get(rseg->space, rseg->page_no, &mtr);
|
rseg_hdr = trx_rsegf_get(rseg->space, rseg->page_no, &mtr);
|
||||||
|
|
||||||
undo_page = trx_undo_page_get(
|
block = trx_undo_page_get(
|
||||||
page_id_t(rseg->space->id, hdr_addr.page), &mtr);
|
page_id_t(rseg->space->id, hdr_addr.page), &mtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -381,15 +382,15 @@ trx_purge_free_segment(trx_rseg_t* rseg, fil_addr_t hdr_addr)
|
||||||
stored in the list base node tells us how big it was before we
|
stored in the list base node tells us how big it was before we
|
||||||
started the freeing. */
|
started the freeing. */
|
||||||
|
|
||||||
const ulint seg_size = flst_get_len(
|
const uint32_t seg_size = flst_get_len(
|
||||||
TRX_UNDO_SEG_HDR + TRX_UNDO_PAGE_LIST + undo_page);
|
TRX_UNDO_SEG_HDR + TRX_UNDO_PAGE_LIST + block->frame);
|
||||||
|
|
||||||
/* We may free the undo log segment header page; it must be freed
|
/* We may free the undo log segment header page; it must be freed
|
||||||
within the same mtr as the undo log header is removed from the
|
within the same mtr as the undo log header is removed from the
|
||||||
history list: otherwise, in case of a database crash, the segment
|
history list: otherwise, in case of a database crash, the segment
|
||||||
could become inaccessible garbage in the file space. */
|
could become inaccessible garbage in the file space. */
|
||||||
|
|
||||||
trx_purge_remove_log_hdr(rseg_hdr, undo_page + hdr_addr.boffset, &mtr);
|
trx_purge_remove_log_hdr(rseg_hdr, block, hdr_addr.boffset, &mtr);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
|
|
@ -399,14 +400,12 @@ trx_purge_free_segment(trx_rseg_t* rseg, fil_addr_t hdr_addr)
|
||||||
fsp0fsp.cc. */
|
fsp0fsp.cc. */
|
||||||
|
|
||||||
} while (!fseg_free_step(TRX_UNDO_SEG_HDR + TRX_UNDO_FSEG_HEADER
|
} while (!fseg_free_step(TRX_UNDO_SEG_HDR + TRX_UNDO_FSEG_HEADER
|
||||||
+ undo_page, false, &mtr));
|
+ block->frame, false, &mtr));
|
||||||
|
|
||||||
const ulint hist_size = mach_read_from_4(rseg_hdr
|
byte* hist = TRX_RSEG + TRX_RSEG_HISTORY_SIZE + rseg_hdr->frame;
|
||||||
+ TRX_RSEG_HISTORY_SIZE);
|
ut_ad(mach_read_from_4(hist) >= seg_size);
|
||||||
ut_ad(hist_size >= seg_size);
|
|
||||||
|
|
||||||
mlog_write_ulint(rseg_hdr + TRX_RSEG_HISTORY_SIZE,
|
mtr.write<4>(*rseg_hdr, hist, mach_read_from_4(hist) - seg_size);
|
||||||
hist_size - seg_size, MLOG_4BYTES, &mtr);
|
|
||||||
|
|
||||||
ut_ad(rseg->curr_size >= seg_size);
|
ut_ad(rseg->curr_size >= seg_size);
|
||||||
|
|
||||||
|
|
@ -428,10 +427,6 @@ trx_purge_truncate_rseg_history(
|
||||||
{
|
{
|
||||||
fil_addr_t hdr_addr;
|
fil_addr_t hdr_addr;
|
||||||
fil_addr_t prev_hdr_addr;
|
fil_addr_t prev_hdr_addr;
|
||||||
trx_rsegf_t* rseg_hdr;
|
|
||||||
page_t* undo_page;
|
|
||||||
trx_ulogf_t* log_hdr;
|
|
||||||
trx_usegf_t* seg_hdr;
|
|
||||||
mtr_t mtr;
|
mtr_t mtr;
|
||||||
trx_id_t undo_trx_no;
|
trx_id_t undo_trx_no;
|
||||||
|
|
||||||
|
|
@ -439,10 +434,10 @@ trx_purge_truncate_rseg_history(
|
||||||
ut_ad(rseg.is_persistent());
|
ut_ad(rseg.is_persistent());
|
||||||
mutex_enter(&rseg.mutex);
|
mutex_enter(&rseg.mutex);
|
||||||
|
|
||||||
rseg_hdr = trx_rsegf_get(rseg.space, rseg.page_no, &mtr);
|
buf_block_t* rseg_hdr = trx_rsegf_get(rseg.space, rseg.page_no, &mtr);
|
||||||
|
|
||||||
hdr_addr = trx_purge_get_log_from_hist(flst_get_last(TRX_RSEG_HISTORY
|
hdr_addr = trx_purge_get_log_from_hist(
|
||||||
+ rseg_hdr));
|
flst_get_last(TRX_RSEG + TRX_RSEG_HISTORY + rseg_hdr->frame));
|
||||||
loop:
|
loop:
|
||||||
if (hdr_addr.page == FIL_NULL) {
|
if (hdr_addr.page == FIL_NULL) {
|
||||||
func_exit:
|
func_exit:
|
||||||
|
|
@ -451,12 +446,11 @@ trx_purge_truncate_rseg_history(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
undo_page = trx_undo_page_get(page_id_t(rseg.space->id, hdr_addr.page),
|
buf_block_t* block = trx_undo_page_get(page_id_t(rseg.space->id,
|
||||||
&mtr);
|
hdr_addr.page),
|
||||||
|
&mtr);
|
||||||
log_hdr = undo_page + hdr_addr.boffset;
|
undo_trx_no = mach_read_from_8(block->frame + hdr_addr.boffset
|
||||||
|
+ TRX_UNDO_TRX_NO);
|
||||||
undo_trx_no = mach_read_from_8(log_hdr + TRX_UNDO_TRX_NO);
|
|
||||||
|
|
||||||
if (undo_trx_no >= limit.trx_no()) {
|
if (undo_trx_no >= limit.trx_no()) {
|
||||||
if (undo_trx_no == limit.trx_no()) {
|
if (undo_trx_no == limit.trx_no()) {
|
||||||
|
|
@ -469,12 +463,13 @@ trx_purge_truncate_rseg_history(
|
||||||
}
|
}
|
||||||
|
|
||||||
prev_hdr_addr = trx_purge_get_log_from_hist(
|
prev_hdr_addr = trx_purge_get_log_from_hist(
|
||||||
flst_get_prev_addr(log_hdr + TRX_UNDO_HISTORY_NODE));
|
flst_get_prev_addr(block->frame + hdr_addr.boffset
|
||||||
|
+ TRX_UNDO_HISTORY_NODE));
|
||||||
|
|
||||||
seg_hdr = undo_page + TRX_UNDO_SEG_HDR;
|
if (mach_read_from_2(TRX_UNDO_SEG_HDR + TRX_UNDO_STATE + block->frame)
|
||||||
|
== TRX_UNDO_TO_PURGE
|
||||||
if ((mach_read_from_2(seg_hdr + TRX_UNDO_STATE) == TRX_UNDO_TO_PURGE)
|
&& !mach_read_from_2(block->frame + hdr_addr.boffset
|
||||||
&& (mach_read_from_2(log_hdr + TRX_UNDO_NEXT_LOG) == 0)) {
|
+ TRX_UNDO_NEXT_LOG)) {
|
||||||
|
|
||||||
/* We can free the whole log segment */
|
/* We can free the whole log segment */
|
||||||
|
|
||||||
|
|
@ -486,7 +481,8 @@ trx_purge_truncate_rseg_history(
|
||||||
trx_purge_free_segment(&rseg, hdr_addr);
|
trx_purge_free_segment(&rseg, hdr_addr);
|
||||||
} else {
|
} else {
|
||||||
/* Remove the log hdr from the rseg history. */
|
/* Remove the log hdr from the rseg history. */
|
||||||
trx_purge_remove_log_hdr(rseg_hdr, log_hdr, &mtr);
|
trx_purge_remove_log_hdr(rseg_hdr, block, hdr_addr.boffset,
|
||||||
|
&mtr);
|
||||||
|
|
||||||
mutex_exit(&rseg.mutex);
|
mutex_exit(&rseg.mutex);
|
||||||
mtr.commit();
|
mtr.commit();
|
||||||
|
|
@ -825,8 +821,6 @@ static void trx_purge_rseg_get_next_history_log(
|
||||||
ulint* n_pages_handled)/*!< in/out: number of UNDO pages
|
ulint* n_pages_handled)/*!< in/out: number of UNDO pages
|
||||||
handled */
|
handled */
|
||||||
{
|
{
|
||||||
page_t* undo_page;
|
|
||||||
trx_ulogf_t* log_hdr;
|
|
||||||
fil_addr_t prev_log_addr;
|
fil_addr_t prev_log_addr;
|
||||||
trx_id_t trx_no;
|
trx_id_t trx_no;
|
||||||
mtr_t mtr;
|
mtr_t mtr;
|
||||||
|
|
@ -841,11 +835,12 @@ static void trx_purge_rseg_get_next_history_log(
|
||||||
|
|
||||||
mtr.start();
|
mtr.start();
|
||||||
|
|
||||||
undo_page = trx_undo_page_get_s_latched(
|
const buf_block_t* undo_page = trx_undo_page_get_s_latched(
|
||||||
page_id_t(purge_sys.rseg->space->id,
|
page_id_t(purge_sys.rseg->space->id,
|
||||||
purge_sys.rseg->last_page_no), &mtr);
|
purge_sys.rseg->last_page_no), &mtr);
|
||||||
|
|
||||||
log_hdr = undo_page + purge_sys.rseg->last_offset;
|
const trx_ulogf_t* log_hdr = undo_page->frame
|
||||||
|
+ purge_sys.rseg->last_offset;
|
||||||
|
|
||||||
/* Increase the purge page count by one for every handled log */
|
/* Increase the purge page count by one for every handled log */
|
||||||
|
|
||||||
|
|
@ -873,7 +868,7 @@ static void trx_purge_rseg_get_next_history_log(
|
||||||
|
|
||||||
log_hdr = trx_undo_page_get_s_latched(
|
log_hdr = trx_undo_page_get_s_latched(
|
||||||
page_id_t(purge_sys.rseg->space->id, prev_log_addr.page),
|
page_id_t(purge_sys.rseg->space->id, prev_log_addr.page),
|
||||||
&mtr)
|
&mtr)->frame
|
||||||
+ prev_log_addr.boffset;
|
+ prev_log_addr.boffset;
|
||||||
|
|
||||||
trx_no = mach_read_from_8(log_hdr + TRX_UNDO_TRX_NO);
|
trx_no = mach_read_from_8(log_hdr + TRX_UNDO_TRX_NO);
|
||||||
|
|
@ -908,8 +903,8 @@ static
|
||||||
void
|
void
|
||||||
trx_purge_read_undo_rec()
|
trx_purge_read_undo_rec()
|
||||||
{
|
{
|
||||||
ulint offset;
|
uint16_t offset;
|
||||||
ulint page_no;
|
uint32_t page_no;
|
||||||
ib_uint64_t undo_no;
|
ib_uint64_t undo_no;
|
||||||
|
|
||||||
purge_sys.hdr_offset = purge_sys.rseg->last_offset;
|
purge_sys.hdr_offset = purge_sys.rseg->last_offset;
|
||||||
|
|
@ -918,13 +913,15 @@ trx_purge_read_undo_rec()
|
||||||
if (purge_sys.rseg->needs_purge) {
|
if (purge_sys.rseg->needs_purge) {
|
||||||
mtr_t mtr;
|
mtr_t mtr;
|
||||||
mtr.start();
|
mtr.start();
|
||||||
|
buf_block_t* undo_page;
|
||||||
if (trx_undo_rec_t* undo_rec = trx_undo_get_first_rec(
|
if (trx_undo_rec_t* undo_rec = trx_undo_get_first_rec(
|
||||||
purge_sys.rseg->space, purge_sys.hdr_page_no,
|
*purge_sys.rseg->space, purge_sys.hdr_page_no,
|
||||||
purge_sys.hdr_offset, RW_S_LATCH, &mtr)) {
|
purge_sys.hdr_offset, RW_S_LATCH,
|
||||||
|
undo_page, &mtr)) {
|
||||||
|
|
||||||
offset = page_offset(undo_rec);
|
offset = page_offset(undo_rec);
|
||||||
undo_no = trx_undo_rec_get_undo_no(undo_rec);
|
undo_no = trx_undo_rec_get_undo_no(undo_rec);
|
||||||
page_no = page_get_page_no(page_align(undo_rec));
|
page_no = undo_page->page.id.page_no();
|
||||||
} else {
|
} else {
|
||||||
offset = 0;
|
offset = 0;
|
||||||
undo_no = 0;
|
undo_no = 0;
|
||||||
|
|
@ -974,22 +971,14 @@ trx_purge_get_next_rec(
|
||||||
handled */
|
handled */
|
||||||
mem_heap_t* heap) /*!< in: memory heap where copied */
|
mem_heap_t* heap) /*!< in: memory heap where copied */
|
||||||
{
|
{
|
||||||
trx_undo_rec_t* rec;
|
|
||||||
trx_undo_rec_t* rec_copy;
|
|
||||||
trx_undo_rec_t* rec2;
|
|
||||||
page_t* undo_page;
|
|
||||||
page_t* page;
|
|
||||||
ulint offset;
|
|
||||||
ulint page_no;
|
|
||||||
ulint space;
|
|
||||||
mtr_t mtr;
|
mtr_t mtr;
|
||||||
|
|
||||||
ut_ad(purge_sys.next_stored);
|
ut_ad(purge_sys.next_stored);
|
||||||
ut_ad(purge_sys.tail.trx_no() < purge_sys.view.low_limit_no());
|
ut_ad(purge_sys.tail.trx_no() < purge_sys.view.low_limit_no());
|
||||||
|
|
||||||
space = purge_sys.rseg->space->id;
|
const ulint space = purge_sys.rseg->space->id;
|
||||||
page_no = purge_sys.page_no;
|
const uint32_t page_no = purge_sys.page_no;
|
||||||
offset = purge_sys.offset;
|
const uint16_t offset = purge_sys.offset;
|
||||||
|
|
||||||
if (offset == 0) {
|
if (offset == 0) {
|
||||||
/* It is the dummy undo log record, which means that there is
|
/* It is the dummy undo log record, which means that there is
|
||||||
|
|
@ -1006,16 +995,16 @@ trx_purge_get_next_rec(
|
||||||
|
|
||||||
mtr_start(&mtr);
|
mtr_start(&mtr);
|
||||||
|
|
||||||
undo_page = trx_undo_page_get_s_latched(page_id_t(space, page_no),
|
buf_block_t* undo_page = trx_undo_page_get_s_latched(
|
||||||
&mtr);
|
page_id_t(space, page_no), &mtr);
|
||||||
|
buf_block_t* rec2_page = undo_page;
|
||||||
|
|
||||||
rec = undo_page + offset;
|
const trx_undo_rec_t* rec2 = trx_undo_page_get_next_rec(
|
||||||
|
undo_page, offset, purge_sys.hdr_page_no, purge_sys.hdr_offset);
|
||||||
rec2 = trx_undo_page_get_next_rec(rec, purge_sys.hdr_page_no,
|
|
||||||
purge_sys.hdr_offset);
|
|
||||||
|
|
||||||
if (rec2 == NULL) {
|
if (rec2 == NULL) {
|
||||||
rec2 = trx_undo_get_next_rec(rec, purge_sys.hdr_page_no,
|
rec2 = trx_undo_get_next_rec(rec2_page, offset,
|
||||||
|
purge_sys.hdr_page_no,
|
||||||
purge_sys.hdr_offset, &mtr);
|
purge_sys.hdr_offset, &mtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1032,22 +1021,19 @@ trx_purge_get_next_rec(
|
||||||
|
|
||||||
undo_page = trx_undo_page_get_s_latched(
|
undo_page = trx_undo_page_get_s_latched(
|
||||||
page_id_t(space, page_no), &mtr);
|
page_id_t(space, page_no), &mtr);
|
||||||
|
|
||||||
rec = undo_page + offset;
|
|
||||||
} else {
|
} else {
|
||||||
page = page_align(rec2);
|
purge_sys.offset = page_offset(rec2);
|
||||||
|
purge_sys.page_no = rec2_page->page.id.page_no();
|
||||||
purge_sys.offset = ulint(rec2 - page);
|
|
||||||
purge_sys.page_no = page_get_page_no(page);
|
|
||||||
purge_sys.tail.undo_no = trx_undo_rec_get_undo_no(rec2);
|
purge_sys.tail.undo_no = trx_undo_rec_get_undo_no(rec2);
|
||||||
|
|
||||||
if (undo_page != page) {
|
if (undo_page != rec2_page) {
|
||||||
/* We advance to a new page of the undo log: */
|
/* We advance to a new page of the undo log: */
|
||||||
(*n_pages_handled)++;
|
(*n_pages_handled)++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rec_copy = trx_undo_rec_copy(rec, heap);
|
trx_undo_rec_t* rec_copy = trx_undo_rec_copy(undo_page->frame + offset,
|
||||||
|
heap);
|
||||||
|
|
||||||
mtr_commit(&mtr);
|
mtr_commit(&mtr);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -162,7 +162,7 @@ that was written to ptr. Update the first free value by the number of bytes
|
||||||
written for this undo record.
|
written for this undo record.
|
||||||
@return offset of the inserted entry on the page if succeeded, 0 if fail */
|
@return offset of the inserted entry on the page if succeeded, 0 if fail */
|
||||||
static
|
static
|
||||||
ulint
|
uint16_t
|
||||||
trx_undo_page_set_next_prev_and_add(
|
trx_undo_page_set_next_prev_and_add(
|
||||||
/*================================*/
|
/*================================*/
|
||||||
buf_block_t* undo_block, /*!< in/out: undo log page */
|
buf_block_t* undo_block, /*!< in/out: undo log page */
|
||||||
|
|
@ -170,30 +170,22 @@ trx_undo_page_set_next_prev_and_add(
|
||||||
written on this undo page. */
|
written on this undo page. */
|
||||||
mtr_t* mtr) /*!< in: mtr */
|
mtr_t* mtr) /*!< in: mtr */
|
||||||
{
|
{
|
||||||
ulint first_free; /*!< offset within undo_page */
|
ut_ad(page_align(ptr) == undo_block->frame);
|
||||||
ulint end_of_rec; /*!< offset within undo_page */
|
|
||||||
byte* ptr_to_first_free;
|
|
||||||
/* pointer within undo_page
|
|
||||||
that points to the next free
|
|
||||||
offset value within undo_page.*/
|
|
||||||
|
|
||||||
ut_ad(ptr > undo_block->frame);
|
|
||||||
ut_ad(ptr < undo_block->frame + srv_page_size);
|
|
||||||
|
|
||||||
if (UNIV_UNLIKELY(trx_undo_left(undo_block, ptr) < 2)) {
|
if (UNIV_UNLIKELY(trx_undo_left(undo_block, ptr) < 2)) {
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr_to_first_free = TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE
|
byte* ptr_to_first_free = TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE
|
||||||
+ undo_block->frame;
|
+ undo_block->frame;
|
||||||
|
|
||||||
first_free = mach_read_from_2(ptr_to_first_free);
|
uint16_t first_free = mach_read_from_2(ptr_to_first_free);
|
||||||
|
|
||||||
/* Write offset of the previous undo log record */
|
/* Write offset of the previous undo log record */
|
||||||
mach_write_to_2(ptr, first_free);
|
mach_write_to_2(ptr, first_free);
|
||||||
ptr += 2;
|
ptr += 2;
|
||||||
|
|
||||||
end_of_rec = ulint(ptr - undo_block->frame);
|
uint16_t end_of_rec = uint16_t(ptr - undo_block->frame);
|
||||||
|
|
||||||
/* Write offset of the next undo log record */
|
/* Write offset of the next undo log record */
|
||||||
mach_write_to_2(undo_block->frame + first_free, end_of_rec);
|
mach_write_to_2(undo_block->frame + first_free, end_of_rec);
|
||||||
|
|
@ -457,7 +449,7 @@ trx_undo_report_insert_virtual(
|
||||||
Reports in the undo log of an insert of a clustered index record.
|
Reports in the undo log of an insert of a clustered index record.
|
||||||
@return offset of the inserted entry on the page if succeed, 0 if fail */
|
@return offset of the inserted entry on the page if succeed, 0 if fail */
|
||||||
static
|
static
|
||||||
ulint
|
uint16_t
|
||||||
trx_undo_page_report_insert(
|
trx_undo_page_report_insert(
|
||||||
/*========================*/
|
/*========================*/
|
||||||
buf_block_t* undo_block, /*!< in: undo log page */
|
buf_block_t* undo_block, /*!< in: undo log page */
|
||||||
|
|
@ -467,10 +459,6 @@ trx_undo_page_report_insert(
|
||||||
inserted to the clustered index */
|
inserted to the clustered index */
|
||||||
mtr_t* mtr) /*!< in: mtr */
|
mtr_t* mtr) /*!< in: mtr */
|
||||||
{
|
{
|
||||||
ulint first_free;
|
|
||||||
byte* ptr;
|
|
||||||
ulint i;
|
|
||||||
|
|
||||||
ut_ad(dict_index_is_clust(index));
|
ut_ad(dict_index_is_clust(index));
|
||||||
/* MariaDB 10.3.1+ in trx_undo_page_init() always initializes
|
/* MariaDB 10.3.1+ in trx_undo_page_init() always initializes
|
||||||
TRX_UNDO_PAGE_TYPE as 0, but previous versions wrote
|
TRX_UNDO_PAGE_TYPE as 0, but previous versions wrote
|
||||||
|
|
@ -479,9 +467,10 @@ trx_undo_page_report_insert(
|
||||||
ut_ad(mach_read_from_2(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_TYPE
|
ut_ad(mach_read_from_2(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_TYPE
|
||||||
+ undo_block->frame) <= 2);
|
+ undo_block->frame) <= 2);
|
||||||
|
|
||||||
first_free = mach_read_from_2(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE
|
uint16_t first_free = mach_read_from_2(TRX_UNDO_PAGE_HDR
|
||||||
+ undo_block->frame);
|
+ TRX_UNDO_PAGE_FREE
|
||||||
ptr = undo_block->frame + first_free;
|
+ undo_block->frame);
|
||||||
|
byte* ptr = undo_block->frame + first_free;
|
||||||
|
|
||||||
ut_ad(first_free <= srv_page_size);
|
ut_ad(first_free <= srv_page_size);
|
||||||
|
|
||||||
|
|
@ -509,7 +498,7 @@ trx_undo_page_report_insert(
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < dict_index_get_n_unique(index); i++) {
|
for (unsigned i = 0; i < dict_index_get_n_unique(index); i++) {
|
||||||
|
|
||||||
const dfield_t* field = dtuple_get_nth_field(clust_entry, i);
|
const dfield_t* field = dtuple_get_nth_field(clust_entry, i);
|
||||||
ulint flen = dfield_get_len(field);
|
ulint flen = dfield_get_len(field);
|
||||||
|
|
@ -572,12 +561,14 @@ trx_undo_rec_get_pars(
|
||||||
|
|
||||||
*updated_extern = !!(type_cmpl & TRX_UNDO_UPD_EXTERN);
|
*updated_extern = !!(type_cmpl & TRX_UNDO_UPD_EXTERN);
|
||||||
type_cmpl &= ~TRX_UNDO_UPD_EXTERN;
|
type_cmpl &= ~TRX_UNDO_UPD_EXTERN;
|
||||||
|
|
||||||
*type = type_cmpl & (TRX_UNDO_CMPL_INFO_MULT - 1);
|
*type = type_cmpl & (TRX_UNDO_CMPL_INFO_MULT - 1);
|
||||||
|
ut_ad(*type >= TRX_UNDO_RENAME_TABLE);
|
||||||
|
ut_ad(*type <= TRX_UNDO_DEL_MARK_REC);
|
||||||
*cmpl_info = type_cmpl / TRX_UNDO_CMPL_INFO_MULT;
|
*cmpl_info = type_cmpl / TRX_UNDO_CMPL_INFO_MULT;
|
||||||
|
|
||||||
*undo_no = mach_read_next_much_compressed(&ptr);
|
*undo_no = mach_read_next_much_compressed(&ptr);
|
||||||
*table_id = mach_read_next_much_compressed(&ptr);
|
*table_id = mach_read_next_much_compressed(&ptr);
|
||||||
|
ut_ad(*table_id);
|
||||||
|
|
||||||
return(const_cast<byte*>(ptr));
|
return(const_cast<byte*>(ptr));
|
||||||
}
|
}
|
||||||
|
|
@ -856,7 +847,7 @@ record.
|
||||||
@return byte offset of the inserted undo log entry on the page if
|
@return byte offset of the inserted undo log entry on the page if
|
||||||
succeed, 0 if fail */
|
succeed, 0 if fail */
|
||||||
static
|
static
|
||||||
ulint
|
uint16_t
|
||||||
trx_undo_page_report_modify(
|
trx_undo_page_report_modify(
|
||||||
/*========================*/
|
/*========================*/
|
||||||
buf_block_t* undo_block, /*!< in: undo log page */
|
buf_block_t* undo_block, /*!< in: undo log page */
|
||||||
|
|
@ -875,7 +866,6 @@ trx_undo_page_report_modify(
|
||||||
virtual column info */
|
virtual column info */
|
||||||
mtr_t* mtr) /*!< in: mtr */
|
mtr_t* mtr) /*!< in: mtr */
|
||||||
{
|
{
|
||||||
ulint first_free;
|
|
||||||
byte* ptr;
|
byte* ptr;
|
||||||
|
|
||||||
ut_ad(index->is_primary());
|
ut_ad(index->is_primary());
|
||||||
|
|
@ -887,8 +877,9 @@ trx_undo_page_report_modify(
|
||||||
ut_ad(mach_read_from_2(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_TYPE
|
ut_ad(mach_read_from_2(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_TYPE
|
||||||
+ undo_block->frame) <= 2);
|
+ undo_block->frame) <= 2);
|
||||||
|
|
||||||
first_free = mach_read_from_2(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE
|
uint16_t first_free = mach_read_from_2(TRX_UNDO_PAGE_HDR
|
||||||
+ undo_block->frame);
|
+ TRX_UNDO_PAGE_FREE
|
||||||
|
+ undo_block->frame);
|
||||||
ptr = undo_block->frame + first_free;
|
ptr = undo_block->frame + first_free;
|
||||||
|
|
||||||
ut_ad(first_free <= srv_page_size);
|
ut_ad(first_free <= srv_page_size);
|
||||||
|
|
@ -1953,13 +1944,13 @@ trx_undo_erase_page_end(page_t* undo_page)
|
||||||
@return byte offset of the undo log record
|
@return byte offset of the undo log record
|
||||||
@retval 0 in case of failure */
|
@retval 0 in case of failure */
|
||||||
static
|
static
|
||||||
ulint
|
uint16_t
|
||||||
trx_undo_page_report_rename(trx_t* trx, const dict_table_t* table,
|
trx_undo_page_report_rename(trx_t* trx, const dict_table_t* table,
|
||||||
buf_block_t* block, mtr_t* mtr)
|
buf_block_t* block, mtr_t* mtr)
|
||||||
{
|
{
|
||||||
byte* ptr_first_free = TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE
|
byte* ptr_first_free = TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE
|
||||||
+ block->frame;
|
+ block->frame;
|
||||||
ulint first_free = mach_read_from_2(ptr_first_free);
|
uint16_t first_free = mach_read_from_2(ptr_first_free);
|
||||||
ut_ad(first_free >= TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_HDR_SIZE);
|
ut_ad(first_free >= TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_HDR_SIZE);
|
||||||
ut_ad(first_free <= srv_page_size);
|
ut_ad(first_free <= srv_page_size);
|
||||||
byte* start = block->frame + first_free;
|
byte* start = block->frame + first_free;
|
||||||
|
|
@ -1985,7 +1976,7 @@ trx_undo_page_report_rename(trx_t* trx, const dict_table_t* table,
|
||||||
ptr += len;
|
ptr += len;
|
||||||
mach_write_to_2(ptr, first_free);
|
mach_write_to_2(ptr, first_free);
|
||||||
ptr += 2;
|
ptr += 2;
|
||||||
ulint offset = page_offset(ptr);
|
uint16_t offset = page_offset(ptr);
|
||||||
mach_write_to_2(start, offset);
|
mach_write_to_2(start, offset);
|
||||||
mach_write_to_2(ptr_first_free, offset);
|
mach_write_to_2(ptr_first_free, offset);
|
||||||
|
|
||||||
|
|
@ -2014,7 +2005,7 @@ dberr_t trx_undo_report_rename(trx_t* trx, const dict_table_t* table)
|
||||||
ut_ad(loop_count++ < 2);
|
ut_ad(loop_count++ < 2);
|
||||||
ut_ad(undo->last_page_no == block->page.id.page_no());
|
ut_ad(undo->last_page_no == block->page.id.page_no());
|
||||||
|
|
||||||
if (ulint offset = trx_undo_page_report_rename(
|
if (uint16_t offset = trx_undo_page_report_rename(
|
||||||
trx, table, block, &mtr)) {
|
trx, table, block, &mtr)) {
|
||||||
undo->withdraw_clock = buf_withdraw_clock;
|
undo->withdraw_clock = buf_withdraw_clock;
|
||||||
undo->top_page_no = undo->last_page_no;
|
undo->top_page_no = undo->last_page_no;
|
||||||
|
|
@ -2118,7 +2109,7 @@ trx_undo_report_row_operation(
|
||||||
ut_ad(undo != NULL);
|
ut_ad(undo != NULL);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ulint offset = !rec
|
uint16_t offset = !rec
|
||||||
? trx_undo_page_report_insert(
|
? trx_undo_page_report_insert(
|
||||||
undo_block, trx, index, clust_entry, &mtr)
|
undo_block, trx, index, clust_entry, &mtr)
|
||||||
: trx_undo_page_report_modify(
|
: trx_undo_page_report_modify(
|
||||||
|
|
@ -2240,11 +2231,10 @@ trx_undo_get_undo_rec_low(
|
||||||
{
|
{
|
||||||
trx_undo_rec_t* undo_rec;
|
trx_undo_rec_t* undo_rec;
|
||||||
ulint rseg_id;
|
ulint rseg_id;
|
||||||
ulint page_no;
|
uint32_t page_no;
|
||||||
ulint offset;
|
uint16_t offset;
|
||||||
const page_t* undo_page;
|
|
||||||
trx_rseg_t* rseg;
|
trx_rseg_t* rseg;
|
||||||
ibool is_insert;
|
bool is_insert;
|
||||||
mtr_t mtr;
|
mtr_t mtr;
|
||||||
|
|
||||||
trx_undo_decode_roll_ptr(roll_ptr, &is_insert, &rseg_id, &page_no,
|
trx_undo_decode_roll_ptr(roll_ptr, &is_insert, &rseg_id, &page_no,
|
||||||
|
|
@ -2254,14 +2244,14 @@ trx_undo_get_undo_rec_low(
|
||||||
rseg = trx_sys.rseg_array[rseg_id];
|
rseg = trx_sys.rseg_array[rseg_id];
|
||||||
ut_ad(rseg->is_persistent());
|
ut_ad(rseg->is_persistent());
|
||||||
|
|
||||||
mtr_start(&mtr);
|
mtr.start();
|
||||||
|
|
||||||
undo_page = trx_undo_page_get_s_latched(
|
buf_block_t* undo_page = trx_undo_page_get_s_latched(
|
||||||
page_id_t(rseg->space->id, page_no), &mtr);
|
page_id_t(rseg->space->id, page_no), &mtr);
|
||||||
|
|
||||||
undo_rec = trx_undo_rec_copy(undo_page + offset, heap);
|
undo_rec = trx_undo_rec_copy(undo_page->frame + offset, heap);
|
||||||
|
|
||||||
mtr_commit(&mtr);
|
mtr.commit();
|
||||||
|
|
||||||
return(undo_rec);
|
return(undo_rec);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ static unsigned char wsrep_uuid[16];
|
||||||
@param[in,out] mtr mini transaction */
|
@param[in,out] mtr mini transaction */
|
||||||
static void
|
static void
|
||||||
trx_rseg_write_wsrep_checkpoint(
|
trx_rseg_write_wsrep_checkpoint(
|
||||||
trx_rsegf_t* rseg_header,
|
buf_block_t* rseg_header,
|
||||||
const XID* xid,
|
const XID* xid,
|
||||||
mtr_t* mtr)
|
mtr_t* mtr)
|
||||||
{
|
{
|
||||||
|
|
@ -57,25 +57,27 @@ trx_rseg_write_wsrep_checkpoint(
|
||||||
DBUG_ASSERT(xid->bqual_length >= 0);
|
DBUG_ASSERT(xid->bqual_length >= 0);
|
||||||
DBUG_ASSERT(xid->gtrid_length + xid->bqual_length < XIDDATASIZE);
|
DBUG_ASSERT(xid->gtrid_length + xid->bqual_length < XIDDATASIZE);
|
||||||
|
|
||||||
mlog_write_ulint(TRX_RSEG_WSREP_XID_FORMAT + rseg_header,
|
mtr->write<4>(*rseg_header, TRX_RSEG + TRX_RSEG_WSREP_XID_FORMAT
|
||||||
uint32_t(xid->formatID),
|
+ rseg_header->frame,
|
||||||
MLOG_4BYTES, mtr);
|
uint32_t(xid->formatID));
|
||||||
|
|
||||||
mlog_write_ulint(TRX_RSEG_WSREP_XID_GTRID_LEN + rseg_header,
|
mtr->write<4>(*rseg_header, TRX_RSEG + TRX_RSEG_WSREP_XID_GTRID_LEN
|
||||||
uint32_t(xid->gtrid_length),
|
+ rseg_header->frame,
|
||||||
MLOG_4BYTES, mtr);
|
uint32_t(xid->gtrid_length));
|
||||||
|
|
||||||
mlog_write_ulint(TRX_RSEG_WSREP_XID_BQUAL_LEN + rseg_header,
|
mtr->write<4>(*rseg_header, TRX_RSEG + TRX_RSEG_WSREP_XID_BQUAL_LEN
|
||||||
uint32_t(xid->bqual_length),
|
+ rseg_header->frame,
|
||||||
MLOG_4BYTES, mtr);
|
uint32_t(xid->bqual_length));
|
||||||
|
|
||||||
const ulint xid_length = static_cast<ulint>(xid->gtrid_length
|
const ulint xid_length = static_cast<ulint>(xid->gtrid_length
|
||||||
+ xid->bqual_length);
|
+ xid->bqual_length);
|
||||||
mlog_write_string(TRX_RSEG_WSREP_XID_DATA + rseg_header,
|
mlog_write_string(TRX_RSEG + TRX_RSEG_WSREP_XID_DATA
|
||||||
|
+ rseg_header->frame,
|
||||||
reinterpret_cast<const byte*>(xid->data),
|
reinterpret_cast<const byte*>(xid->data),
|
||||||
xid_length, mtr);
|
xid_length, mtr);
|
||||||
if (UNIV_LIKELY(xid_length < XIDDATASIZE)) {
|
if (UNIV_LIKELY(xid_length < XIDDATASIZE)) {
|
||||||
mlog_memset(TRX_RSEG_WSREP_XID_DATA + rseg_header + xid_length,
|
mlog_memset(TRX_RSEG + TRX_RSEG_WSREP_XID_DATA
|
||||||
|
+ rseg_header->frame + xid_length,
|
||||||
XIDDATASIZE - xid_length, 0, mtr);
|
XIDDATASIZE - xid_length, 0, mtr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -86,7 +88,7 @@ trx_rseg_write_wsrep_checkpoint(
|
||||||
@param[in,out] mtr mini-transaction */
|
@param[in,out] mtr mini-transaction */
|
||||||
void
|
void
|
||||||
trx_rseg_update_wsrep_checkpoint(
|
trx_rseg_update_wsrep_checkpoint(
|
||||||
trx_rsegf_t* rseg_header,
|
buf_block_t* rseg_header,
|
||||||
const XID* xid,
|
const XID* xid,
|
||||||
mtr_t* mtr)
|
mtr_t* mtr)
|
||||||
{
|
{
|
||||||
|
|
@ -109,16 +111,13 @@ trx_rseg_update_wsrep_checkpoint(
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Clear the WSREP XID information from rollback segment header.
|
/** Clear the WSREP XID information from rollback segment header.
|
||||||
@param[in,out] rseg_header Rollback segment header
|
@param[in,out] block rollback segment header
|
||||||
@param[in,out] mtr mini-transaction */
|
@param[in,out] mtr mini-transaction */
|
||||||
static void
|
static void trx_rseg_clear_wsrep_checkpoint(buf_block_t *block, mtr_t *mtr)
|
||||||
trx_rseg_clear_wsrep_checkpoint(
|
|
||||||
trx_rsegf_t* rseg_header,
|
|
||||||
mtr_t* mtr)
|
|
||||||
{
|
{
|
||||||
mlog_memset(rseg_header + TRX_RSEG_WSREP_XID_INFO,
|
mlog_memset(block, TRX_RSEG + TRX_RSEG_WSREP_XID_INFO,
|
||||||
TRX_RSEG_WSREP_XID_DATA + XIDDATASIZE
|
TRX_RSEG_WSREP_XID_DATA + XIDDATASIZE - TRX_RSEG_WSREP_XID_INFO,
|
||||||
- TRX_RSEG_WSREP_XID_INFO, 0, mtr);
|
0, mtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -133,9 +132,10 @@ trx_rseg_update_wsrep_checkpoint(const XID* xid, mtr_t* mtr)
|
||||||
sizeof wsrep_uuid);
|
sizeof wsrep_uuid);
|
||||||
const trx_rseg_t* rseg = trx_sys.rseg_array[0];
|
const trx_rseg_t* rseg = trx_sys.rseg_array[0];
|
||||||
|
|
||||||
trx_rsegf_t* rseg_header = trx_rsegf_get(rseg->space, rseg->page_no,
|
buf_block_t* rseg_header = trx_rsegf_get(rseg->space, rseg->page_no,
|
||||||
mtr);
|
mtr);
|
||||||
if (UNIV_UNLIKELY(mach_read_from_4(rseg_header + TRX_RSEG_FORMAT))) {
|
if (UNIV_UNLIKELY(mach_read_from_4(TRX_RSEG + TRX_RSEG_FORMAT
|
||||||
|
+ rseg_header->frame))) {
|
||||||
trx_rseg_format_upgrade(rseg_header, mtr);
|
trx_rseg_format_upgrade(rseg_header, mtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -178,25 +178,26 @@ void trx_rseg_update_wsrep_checkpoint(const XID* xid)
|
||||||
@param[out] xid Transaction XID
|
@param[out] xid Transaction XID
|
||||||
@return whether the WSREP XID was present */
|
@return whether the WSREP XID was present */
|
||||||
static
|
static
|
||||||
bool trx_rseg_read_wsrep_checkpoint(const trx_rsegf_t* rseg_header, XID& xid)
|
bool trx_rseg_read_wsrep_checkpoint(const buf_block_t *rseg_header, XID &xid)
|
||||||
{
|
{
|
||||||
int formatID = static_cast<int>(
|
int formatID = static_cast<int>(
|
||||||
mach_read_from_4(
|
mach_read_from_4(TRX_RSEG + TRX_RSEG_WSREP_XID_FORMAT
|
||||||
TRX_RSEG_WSREP_XID_FORMAT + rseg_header));
|
+ rseg_header->frame));
|
||||||
if (formatID == 0) {
|
if (formatID == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
xid.formatID = formatID;
|
xid.formatID = formatID;
|
||||||
xid.gtrid_length = static_cast<int>(
|
xid.gtrid_length = static_cast<int>(
|
||||||
mach_read_from_4(
|
mach_read_from_4(TRX_RSEG + TRX_RSEG_WSREP_XID_GTRID_LEN
|
||||||
TRX_RSEG_WSREP_XID_GTRID_LEN + rseg_header));
|
+ rseg_header->frame));
|
||||||
|
|
||||||
xid.bqual_length = static_cast<int>(
|
xid.bqual_length = static_cast<int>(
|
||||||
mach_read_from_4(
|
mach_read_from_4(TRX_RSEG + TRX_RSEG_WSREP_XID_BQUAL_LEN
|
||||||
TRX_RSEG_WSREP_XID_BQUAL_LEN + rseg_header));
|
+ rseg_header->frame));
|
||||||
|
|
||||||
memcpy(xid.data, TRX_RSEG_WSREP_XID_DATA + rseg_header, XIDDATASIZE);
|
memcpy(xid.data, TRX_RSEG + TRX_RSEG_WSREP_XID_DATA
|
||||||
|
+ rseg_header->frame, XIDDATASIZE);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -252,10 +253,11 @@ bool trx_rseg_read_wsrep_checkpoint(XID& xid)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const trx_rsegf_t* rseg_header = trx_rsegf_get_new(
|
const buf_block_t* rseg_header = trx_rsegf_get_new(
|
||||||
trx_sysf_rseg_get_space(sys, rseg_id), page_no, &mtr);
|
trx_sysf_rseg_get_space(sys, rseg_id), page_no, &mtr);
|
||||||
|
|
||||||
if (mach_read_from_4(rseg_header + TRX_RSEG_FORMAT)) {
|
if (mach_read_from_4(TRX_RSEG + TRX_RSEG_FORMAT
|
||||||
|
+ rseg_header->frame)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -279,17 +281,15 @@ bool trx_rseg_read_wsrep_checkpoint(XID& xid)
|
||||||
/** Upgrade a rollback segment header page to MariaDB 10.3 format.
|
/** Upgrade a rollback segment header page to MariaDB 10.3 format.
|
||||||
@param[in,out] rseg_header rollback segment header page
|
@param[in,out] rseg_header rollback segment header page
|
||||||
@param[in,out] mtr mini-transaction */
|
@param[in,out] mtr mini-transaction */
|
||||||
void trx_rseg_format_upgrade(trx_rsegf_t* rseg_header, mtr_t* mtr)
|
void trx_rseg_format_upgrade(buf_block_t *rseg_header, mtr_t *mtr)
|
||||||
{
|
{
|
||||||
ut_ad(page_offset(rseg_header) == TRX_RSEG);
|
mlog_memset(rseg_header, TRX_RSEG + TRX_RSEG_FORMAT, 4, 0, mtr);
|
||||||
byte* rseg_format = TRX_RSEG_FORMAT + rseg_header;
|
/* Clear also possible garbage at the end of the page. Old
|
||||||
mlog_write_ulint(rseg_format, 0, MLOG_4BYTES, mtr);
|
InnoDB versions did not initialize unused parts of pages. */
|
||||||
/* Clear also possible garbage at the end of the page. Old
|
mlog_memset(rseg_header, TRX_RSEG + TRX_RSEG_MAX_TRX_ID + 8,
|
||||||
InnoDB versions did not initialize unused parts of pages. */
|
srv_page_size
|
||||||
mlog_memset(TRX_RSEG_MAX_TRX_ID + 8 + rseg_header,
|
- (FIL_PAGE_DATA_END + TRX_RSEG + TRX_RSEG_MAX_TRX_ID + 8),
|
||||||
srv_page_size
|
0, mtr);
|
||||||
- (FIL_PAGE_DATA_END
|
|
||||||
+ TRX_RSEG + TRX_RSEG_MAX_TRX_ID + 8), 0, mtr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Create a rollback segment header.
|
/** Create a rollback segment header.
|
||||||
|
|
@ -337,16 +337,16 @@ trx_rseg_header_create(
|
||||||
/* Add the rollback segment info to the free slot in
|
/* Add the rollback segment info to the free slot in
|
||||||
the trx system header */
|
the trx system header */
|
||||||
|
|
||||||
mlog_write_ulint(TRX_SYS + TRX_SYS_RSEGS
|
mtr->write<4,mtr_t::OPT>(
|
||||||
+ TRX_SYS_RSEG_SPACE
|
*sys_header,
|
||||||
+ rseg_id * TRX_SYS_RSEG_SLOT_SIZE
|
TRX_SYS + TRX_SYS_RSEGS + TRX_SYS_RSEG_SPACE
|
||||||
+ sys_header->frame,
|
+ rseg_id * TRX_SYS_RSEG_SLOT_SIZE
|
||||||
space->id, MLOG_4BYTES, mtr);
|
+ sys_header->frame, space->id);
|
||||||
mlog_write_ulint(TRX_SYS + TRX_SYS_RSEGS
|
mtr->write<4,mtr_t::OPT>(
|
||||||
+ TRX_SYS_RSEG_PAGE_NO
|
*sys_header,
|
||||||
+ rseg_id * TRX_SYS_RSEG_SLOT_SIZE
|
TRX_SYS + TRX_SYS_RSEGS + TRX_SYS_RSEG_PAGE_NO
|
||||||
+ sys_header->frame,
|
+ rseg_id * TRX_SYS_RSEG_SLOT_SIZE
|
||||||
block->page.id.page_no(), MLOG_4BYTES, mtr);
|
+ sys_header->frame, block->page.id.page_no());
|
||||||
}
|
}
|
||||||
|
|
||||||
return block;
|
return block;
|
||||||
|
|
@ -410,29 +410,28 @@ trx_rseg_mem_create(ulint id, fil_space_t* space, ulint page_no)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Read the undo log lists.
|
/** Read the undo log lists.
|
||||||
@param[in,out] rseg rollback segment
|
@param[in,out] rseg rollback segment
|
||||||
@param[in,out] max_trx_id maximum observed transaction identifier
|
@param[in,out] max_trx_id maximum observed transaction identifier
|
||||||
@param[in] rseg_header rollback segment header
|
@param[in] rseg_header rollback segment header
|
||||||
@return the combined size of undo log segments in pages */
|
@return the combined size of undo log segments in pages */
|
||||||
static
|
static ulint trx_undo_lists_init(trx_rseg_t *rseg, trx_id_t &max_trx_id,
|
||||||
ulint
|
const buf_block_t *rseg_header)
|
||||||
trx_undo_lists_init(trx_rseg_t* rseg, trx_id_t& max_trx_id,
|
|
||||||
const trx_rsegf_t* rseg_header)
|
|
||||||
{
|
{
|
||||||
ut_ad(srv_force_recovery < SRV_FORCE_NO_UNDO_LOG_SCAN);
|
ut_ad(srv_force_recovery < SRV_FORCE_NO_UNDO_LOG_SCAN);
|
||||||
|
|
||||||
ulint size = 0;
|
ulint size= 0;
|
||||||
|
|
||||||
for (ulint i = 0; i < TRX_RSEG_N_SLOTS; i++) {
|
for (ulint i= 0; i < TRX_RSEG_N_SLOTS; i++)
|
||||||
ulint page_no = trx_rsegf_get_nth_undo(rseg_header, i);
|
{
|
||||||
if (page_no != FIL_NULL) {
|
uint32_t page_no= trx_rsegf_get_nth_undo(rseg_header, i);
|
||||||
size += trx_undo_mem_create_at_db_start(
|
if (page_no != FIL_NULL)
|
||||||
rseg, i, page_no, max_trx_id);
|
{
|
||||||
MONITOR_INC(MONITOR_NUM_UNDO_SLOT_USED);
|
size+= trx_undo_mem_create_at_db_start(rseg, i, page_no, max_trx_id);
|
||||||
}
|
MONITOR_INC(MONITOR_NUM_UNDO_SLOT_USED);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return(size);
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Restore the state of a persistent rollback segment.
|
/** Restore the state of a persistent rollback segment.
|
||||||
|
|
@ -443,20 +442,20 @@ static
|
||||||
void
|
void
|
||||||
trx_rseg_mem_restore(trx_rseg_t* rseg, trx_id_t& max_trx_id, mtr_t* mtr)
|
trx_rseg_mem_restore(trx_rseg_t* rseg, trx_id_t& max_trx_id, mtr_t* mtr)
|
||||||
{
|
{
|
||||||
trx_rsegf_t* rseg_header = trx_rsegf_get_new(
|
buf_block_t* rseg_hdr = trx_rsegf_get_new(
|
||||||
rseg->space->id, rseg->page_no, mtr);
|
rseg->space->id, rseg->page_no, mtr);
|
||||||
|
|
||||||
if (mach_read_from_4(rseg_header + TRX_RSEG_FORMAT) == 0) {
|
if (!mach_read_from_4(TRX_RSEG + TRX_RSEG_FORMAT + rseg_hdr->frame)) {
|
||||||
trx_id_t id = mach_read_from_8(rseg_header
|
trx_id_t id = mach_read_from_8(TRX_RSEG + TRX_RSEG_MAX_TRX_ID
|
||||||
+ TRX_RSEG_MAX_TRX_ID);
|
+ rseg_hdr->frame);
|
||||||
|
|
||||||
if (id > max_trx_id) {
|
if (id > max_trx_id) {
|
||||||
max_trx_id = id;
|
max_trx_id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rseg_header[TRX_RSEG_BINLOG_NAME]) {
|
const char* binlog_name = TRX_RSEG + TRX_RSEG_BINLOG_NAME
|
||||||
const char* binlog_name = reinterpret_cast<const char*>
|
+ reinterpret_cast<const char*>(rseg_hdr->frame);
|
||||||
(rseg_header) + TRX_RSEG_BINLOG_NAME;
|
if (*binlog_name) {
|
||||||
compile_time_assert(TRX_RSEG_BINLOG_NAME_LEN == sizeof
|
compile_time_assert(TRX_RSEG_BINLOG_NAME_LEN == sizeof
|
||||||
trx_sys.recovered_binlog_filename);
|
trx_sys.recovered_binlog_filename);
|
||||||
|
|
||||||
|
|
@ -468,7 +467,8 @@ trx_rseg_mem_restore(trx_rseg_t* rseg, trx_id_t& max_trx_id, mtr_t* mtr)
|
||||||
|
|
||||||
if (cmp >= 0) {
|
if (cmp >= 0) {
|
||||||
uint64_t binlog_offset = mach_read_from_8(
|
uint64_t binlog_offset = mach_read_from_8(
|
||||||
rseg_header + TRX_RSEG_BINLOG_OFFSET);
|
TRX_RSEG + TRX_RSEG_BINLOG_OFFSET
|
||||||
|
+ rseg_hdr->frame);
|
||||||
if (cmp) {
|
if (cmp) {
|
||||||
memcpy(trx_sys.
|
memcpy(trx_sys.
|
||||||
recovered_binlog_filename,
|
recovered_binlog_filename,
|
||||||
|
|
@ -485,7 +485,7 @@ trx_rseg_mem_restore(trx_rseg_t* rseg, trx_id_t& max_trx_id, mtr_t* mtr)
|
||||||
|
|
||||||
#ifdef WITH_WSREP
|
#ifdef WITH_WSREP
|
||||||
trx_rseg_read_wsrep_checkpoint(
|
trx_rseg_read_wsrep_checkpoint(
|
||||||
rseg_header, trx_sys.recovered_wsrep_xid);
|
rseg_hdr, trx_sys.recovered_wsrep_xid);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -499,32 +499,37 @@ trx_rseg_mem_restore(trx_rseg_t* rseg, trx_id_t& max_trx_id, mtr_t* mtr)
|
||||||
|
|
||||||
/* Initialize the undo log lists according to the rseg header */
|
/* Initialize the undo log lists according to the rseg header */
|
||||||
|
|
||||||
rseg->curr_size = mach_read_from_4(rseg_header + TRX_RSEG_HISTORY_SIZE)
|
rseg->curr_size = mach_read_from_4(TRX_RSEG + TRX_RSEG_HISTORY_SIZE
|
||||||
+ 1 + trx_undo_lists_init(rseg, max_trx_id, rseg_header);
|
+ rseg_hdr->frame)
|
||||||
|
+ 1 + trx_undo_lists_init(rseg, max_trx_id, rseg_hdr);
|
||||||
|
|
||||||
if (auto len = flst_get_len(rseg_header + TRX_RSEG_HISTORY)) {
|
if (auto len = flst_get_len(TRX_RSEG + TRX_RSEG_HISTORY
|
||||||
|
+ rseg_hdr->frame)) {
|
||||||
trx_sys.rseg_history_len += len;
|
trx_sys.rseg_history_len += len;
|
||||||
|
|
||||||
fil_addr_t node_addr = trx_purge_get_log_from_hist(
|
fil_addr_t node_addr = trx_purge_get_log_from_hist(
|
||||||
flst_get_last(rseg_header + TRX_RSEG_HISTORY));
|
flst_get_last(TRX_RSEG + TRX_RSEG_HISTORY
|
||||||
|
+ rseg_hdr->frame));
|
||||||
|
|
||||||
rseg->last_page_no = node_addr.page;
|
rseg->last_page_no = node_addr.page;
|
||||||
rseg->last_offset = node_addr.boffset;
|
rseg->last_offset = node_addr.boffset;
|
||||||
|
|
||||||
const trx_ulogf_t* undo_log_hdr = trx_undo_page_get(
|
const buf_block_t* block = trx_undo_page_get(
|
||||||
page_id_t(rseg->space->id, node_addr.page), mtr)
|
page_id_t(rseg->space->id, node_addr.page), mtr);
|
||||||
+ node_addr.boffset;
|
|
||||||
|
|
||||||
trx_id_t id = mach_read_from_8(undo_log_hdr + TRX_UNDO_TRX_ID);
|
trx_id_t id = mach_read_from_8(block->frame + node_addr.boffset
|
||||||
|
+ TRX_UNDO_TRX_ID);
|
||||||
if (id > max_trx_id) {
|
if (id > max_trx_id) {
|
||||||
max_trx_id = id;
|
max_trx_id = id;
|
||||||
}
|
}
|
||||||
id = mach_read_from_8(undo_log_hdr + TRX_UNDO_TRX_NO);
|
id = mach_read_from_8(block->frame + node_addr.boffset
|
||||||
|
+ TRX_UNDO_TRX_NO);
|
||||||
if (id > max_trx_id) {
|
if (id > max_trx_id) {
|
||||||
max_trx_id = id;
|
max_trx_id = id;
|
||||||
}
|
}
|
||||||
unsigned purge = mach_read_from_2(
|
unsigned purge = mach_read_from_2(block->frame
|
||||||
undo_log_hdr + TRX_UNDO_NEEDS_PURGE);
|
+ node_addr.boffset
|
||||||
|
+ TRX_UNDO_NEEDS_PURGE);
|
||||||
ut_ad(purge <= 1);
|
ut_ad(purge <= 1);
|
||||||
rseg->set_last_trx_no(id, purge != 0);
|
rseg->set_last_trx_no(id, purge != 0);
|
||||||
rseg->needs_purge = purge != 0;
|
rseg->needs_purge = purge != 0;
|
||||||
|
|
@ -638,8 +643,8 @@ trx_rseg_array_init()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Finally, clear WSREP XID in TRX_SYS page. */
|
/* Finally, clear WSREP XID in TRX_SYS page. */
|
||||||
const buf_block_t* sys = trx_sysf_get(&mtr);
|
mlog_memset(trx_sysf_get(&mtr),
|
||||||
mlog_memset(TRX_SYS + TRX_SYS_WSREP_XID_INFO + sys->frame,
|
TRX_SYS + TRX_SYS_WSREP_XID_INFO,
|
||||||
TRX_SYS_WSREP_XID_LEN, 0, &mtr);
|
TRX_SYS_WSREP_XID_LEN, 0, &mtr);
|
||||||
mtr.commit();
|
mtr.commit();
|
||||||
}
|
}
|
||||||
|
|
@ -765,8 +770,8 @@ up to which replication has proceeded.
|
||||||
@param[in,out] rseg_header rollback segment header
|
@param[in,out] rseg_header rollback segment header
|
||||||
@param[in] trx committing transaction
|
@param[in] trx committing transaction
|
||||||
@param[in,out] mtr mini-transaction */
|
@param[in,out] mtr mini-transaction */
|
||||||
void
|
void trx_rseg_update_binlog_offset(buf_block_t *rseg_header, const trx_t *trx,
|
||||||
trx_rseg_update_binlog_offset(byte* rseg_header, const trx_t* trx, mtr_t* mtr)
|
mtr_t *mtr)
|
||||||
{
|
{
|
||||||
DBUG_LOG("trx", "trx_mysql_binlog_offset: " << trx->mysql_log_offset);
|
DBUG_LOG("trx", "trx_mysql_binlog_offset: " << trx->mysql_log_offset);
|
||||||
|
|
||||||
|
|
@ -778,9 +783,11 @@ trx_rseg_update_binlog_offset(byte* rseg_header, const trx_t* trx, mtr_t* mtr)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mlog_write_ull(rseg_header + TRX_RSEG_BINLOG_OFFSET,
|
mtr->write<8,mtr_t::OPT>(*rseg_header,
|
||||||
trx->mysql_log_offset, mtr);
|
TRX_RSEG + TRX_RSEG_BINLOG_OFFSET
|
||||||
byte* p = rseg_header + TRX_RSEG_BINLOG_NAME;
|
+ rseg_header->frame,
|
||||||
|
trx->mysql_log_offset);
|
||||||
|
byte* p = TRX_RSEG + TRX_RSEG_BINLOG_NAME + rseg_header->frame;
|
||||||
const byte* binlog_name = reinterpret_cast<const byte*>
|
const byte* binlog_name = reinterpret_cast<const byte*>
|
||||||
(trx->mysql_log_file_name);
|
(trx->mysql_log_file_name);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -147,8 +147,6 @@ trx_sysf_create(
|
||||||
{
|
{
|
||||||
ulint slot_no;
|
ulint slot_no;
|
||||||
buf_block_t* block;
|
buf_block_t* block;
|
||||||
page_t* page;
|
|
||||||
byte* ptr;
|
|
||||||
|
|
||||||
ut_ad(mtr);
|
ut_ad(mtr);
|
||||||
|
|
||||||
|
|
@ -167,30 +165,28 @@ trx_sysf_create(
|
||||||
|
|
||||||
ut_a(block->page.id.page_no() == TRX_SYS_PAGE_NO);
|
ut_a(block->page.id.page_no() == TRX_SYS_PAGE_NO);
|
||||||
|
|
||||||
page = buf_block_get_frame(block);
|
mtr->write<2>(*block, FIL_PAGE_TYPE + block->frame,
|
||||||
|
FIL_PAGE_TYPE_TRX_SYS);
|
||||||
|
|
||||||
mlog_write_ulint(page + FIL_PAGE_TYPE, FIL_PAGE_TYPE_TRX_SYS,
|
ut_ad(!mach_read_from_4(block->frame
|
||||||
MLOG_2BYTES, mtr);
|
+ TRX_SYS_DOUBLEWRITE
|
||||||
|
+ TRX_SYS_DOUBLEWRITE_MAGIC));
|
||||||
/* Reset the doublewrite buffer magic number to zero so that we
|
|
||||||
know that the doublewrite buffer has not yet been created (this
|
|
||||||
suppresses a Valgrind warning) */
|
|
||||||
|
|
||||||
mlog_write_ulint(page + TRX_SYS_DOUBLEWRITE
|
|
||||||
+ TRX_SYS_DOUBLEWRITE_MAGIC, 0, MLOG_4BYTES, mtr);
|
|
||||||
|
|
||||||
/* Reset the rollback segment slots. Old versions of InnoDB
|
/* Reset the rollback segment slots. Old versions of InnoDB
|
||||||
(before MySQL 5.5) define TRX_SYS_N_RSEGS as 256 and expect
|
(before MySQL 5.5) define TRX_SYS_N_RSEGS as 256 and expect
|
||||||
that the whole array is initialized. */
|
that the whole array is initialized. */
|
||||||
ptr = TRX_SYS + TRX_SYS_RSEGS + page;
|
|
||||||
compile_time_assert(256 >= TRX_SYS_N_RSEGS);
|
compile_time_assert(256 >= TRX_SYS_N_RSEGS);
|
||||||
memset(ptr, 0xff, 256 * TRX_SYS_RSEG_SLOT_SIZE);
|
compile_time_assert(TRX_SYS + TRX_SYS_RSEGS
|
||||||
ptr += 256 * TRX_SYS_RSEG_SLOT_SIZE;
|
+ 256 * TRX_SYS_RSEG_SLOT_SIZE
|
||||||
ut_a(ptr <= page + (srv_page_size - FIL_PAGE_DATA_END));
|
<= UNIV_PAGE_SIZE_MIN - FIL_PAGE_DATA_END);
|
||||||
|
mlog_memset(block, TRX_SYS + TRX_SYS_RSEGS,
|
||||||
|
256 * TRX_SYS_RSEG_SLOT_SIZE, 0xff, mtr);
|
||||||
/* Initialize all of the page. This part used to be uninitialized. */
|
/* Initialize all of the page. This part used to be uninitialized. */
|
||||||
mlog_memset(block, ptr - page,
|
mlog_memset(block, TRX_SYS + TRX_SYS_RSEGS
|
||||||
srv_page_size - FIL_PAGE_DATA_END + size_t(page - ptr),
|
+ 256 * TRX_SYS_RSEG_SLOT_SIZE,
|
||||||
|
srv_page_size
|
||||||
|
- (FIL_PAGE_DATA_END + TRX_SYS + TRX_SYS_RSEGS
|
||||||
|
+ 256 * TRX_SYS_RSEG_SLOT_SIZE),
|
||||||
0, mtr);
|
0, mtr);
|
||||||
|
|
||||||
/* Create the first rollback segment in the SYSTEM tablespace */
|
/* Create the first rollback segment in the SYSTEM tablespace */
|
||||||
|
|
|
||||||
|
|
@ -565,8 +565,6 @@ trx_resurrect_table_locks(
|
||||||
const trx_undo_t* undo) /*!< in: undo log */
|
const trx_undo_t* undo) /*!< in: undo log */
|
||||||
{
|
{
|
||||||
mtr_t mtr;
|
mtr_t mtr;
|
||||||
page_t* undo_page;
|
|
||||||
trx_undo_rec_t* undo_rec;
|
|
||||||
table_id_set tables;
|
table_id_set tables;
|
||||||
|
|
||||||
ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE) ||
|
ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE) ||
|
||||||
|
|
@ -581,11 +579,11 @@ trx_resurrect_table_locks(
|
||||||
|
|
||||||
/* trx_rseg_mem_create() may have acquired an X-latch on this
|
/* trx_rseg_mem_create() may have acquired an X-latch on this
|
||||||
page, so we cannot acquire an S-latch. */
|
page, so we cannot acquire an S-latch. */
|
||||||
undo_page = trx_undo_page_get(
|
buf_block_t* block = trx_undo_page_get(
|
||||||
page_id_t(trx->rsegs.m_redo.rseg->space->id,
|
page_id_t(trx->rsegs.m_redo.rseg->space->id,
|
||||||
undo->top_page_no), &mtr);
|
undo->top_page_no), &mtr);
|
||||||
|
buf_block_t* undo_block = block;
|
||||||
undo_rec = undo_page + undo->top_offset;
|
trx_undo_rec_t* undo_rec = block->frame + undo->top_offset;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ulint type;
|
ulint type;
|
||||||
|
|
@ -594,11 +592,9 @@ trx_resurrect_table_locks(
|
||||||
ulint cmpl_info;
|
ulint cmpl_info;
|
||||||
bool updated_extern;
|
bool updated_extern;
|
||||||
|
|
||||||
page_t* undo_rec_page = page_align(undo_rec);
|
if (undo_block != block) {
|
||||||
|
mtr.memo_release(undo_block, MTR_MEMO_PAGE_X_FIX);
|
||||||
if (undo_rec_page != undo_page) {
|
undo_block = block;
|
||||||
mtr.release_page(undo_page, MTR_MEMO_PAGE_X_FIX);
|
|
||||||
undo_page = undo_rec_page;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trx_undo_rec_get_pars(
|
trx_undo_rec_get_pars(
|
||||||
|
|
@ -607,7 +603,7 @@ trx_resurrect_table_locks(
|
||||||
tables.insert(table_id);
|
tables.insert(table_id);
|
||||||
|
|
||||||
undo_rec = trx_undo_get_prev_rec(
|
undo_rec = trx_undo_get_prev_rec(
|
||||||
undo_rec, undo->hdr_page_no,
|
block, page_offset(undo_rec), undo->hdr_page_no,
|
||||||
undo->hdr_offset, false, &mtr);
|
undo->hdr_offset, false, &mtr);
|
||||||
} while (undo_rec);
|
} while (undo_rec);
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user