Commit 3594075a authored by Marko Mäkelä's avatar Marko Mäkelä

Assert that the 'default row' record cannot be locked

parent 18fc6274
...@@ -284,6 +284,20 @@ page_rec_is_comp(const byte* rec) ...@@ -284,6 +284,20 @@ page_rec_is_comp(const byte* rec)
return(page_is_comp(page_align(rec))); return(page_is_comp(page_align(rec)));
} }
# ifdef UNIV_DEBUG
/** Determine if the record is the 'default row' pseudo-record
in the clustered index.
@param[in] rec leaf page record on an index page
@return whether the record is the 'default row' pseudo-record */
inline
bool
page_rec_is_default_row(const rec_t* rec)
{
return rec_get_info_bits(rec, page_rec_is_comp(rec))
& REC_INFO_MIN_REC_FLAG;
}
# endif /* UNIV_DEBUG */
/** Determine the offset of the infimum record on the page. /** Determine the offset of the infimum record on the page.
@param[in] page index page @param[in] page index page
@return offset of the infimum record in record list, relative from page */ @return offset of the infimum record in record list, relative from page */
......
...@@ -356,6 +356,9 @@ lock_report_trx_id_insanity( ...@@ -356,6 +356,9 @@ lock_report_trx_id_insanity(
const ulint* offsets, /*!< in: rec_get_offsets(rec, index) */ const ulint* offsets, /*!< in: rec_get_offsets(rec, index) */
trx_id_t max_trx_id) /*!< in: trx_sys_get_max_trx_id() */ trx_id_t max_trx_id) /*!< in: trx_sys_get_max_trx_id() */
{ {
ut_ad(rec_offs_validate(rec, index, offsets));
ut_ad(!rec_is_default_row(rec, index));
ib::error() ib::error()
<< "Transaction id " << trx_id << "Transaction id " << trx_id
<< " associated with record" << rec_offsets_print(rec, offsets) << " associated with record" << rec_offsets_print(rec, offsets)
...@@ -382,6 +385,7 @@ lock_check_trx_id_sanity( ...@@ -382,6 +385,7 @@ lock_check_trx_id_sanity(
const ulint* offsets) /*!< in: rec_get_offsets(rec, index) */ const ulint* offsets) /*!< in: rec_get_offsets(rec, index) */
{ {
ut_ad(rec_offs_validate(rec, index, offsets)); ut_ad(rec_offs_validate(rec, index, offsets));
ut_ad(!rec_is_default_row(rec, index));
trx_id_t max_trx_id = trx_sys_get_max_trx_id(); trx_id_t max_trx_id = trx_sys_get_max_trx_id();
bool is_ok = trx_id < max_trx_id; bool is_ok = trx_id < max_trx_id;
...@@ -410,6 +414,7 @@ lock_clust_rec_cons_read_sees( ...@@ -410,6 +414,7 @@ lock_clust_rec_cons_read_sees(
ut_ad(dict_index_is_clust(index)); ut_ad(dict_index_is_clust(index));
ut_ad(page_rec_is_user_rec(rec)); ut_ad(page_rec_is_user_rec(rec));
ut_ad(rec_offs_validate(rec, index, offsets)); ut_ad(rec_offs_validate(rec, index, offsets));
ut_ad(!rec_is_default_row(rec, index));
/* Temp-tables are not shared across connections and multiple /* Temp-tables are not shared across connections and multiple
transactions from different connections cannot simultaneously transactions from different connections cannot simultaneously
...@@ -448,6 +453,8 @@ lock_sec_rec_cons_read_sees( ...@@ -448,6 +453,8 @@ lock_sec_rec_cons_read_sees(
const ReadView* view) /*!< in: consistent read view */ const ReadView* view) /*!< in: consistent read view */
{ {
ut_ad(page_rec_is_user_rec(rec)); ut_ad(page_rec_is_user_rec(rec));
ut_ad(!index->is_clust());
ut_ad(!rec_is_default_row(rec, index));
/* NOTE that we might call this function while holding the search /* NOTE that we might call this function while holding the search
system latch. */ system latch. */
...@@ -1492,6 +1499,7 @@ lock_sec_rec_some_has_impl( ...@@ -1492,6 +1499,7 @@ lock_sec_rec_some_has_impl(
ut_ad(!dict_index_is_clust(index)); ut_ad(!dict_index_is_clust(index));
ut_ad(page_rec_is_user_rec(rec)); ut_ad(page_rec_is_user_rec(rec));
ut_ad(rec_offs_validate(rec, index, offsets)); ut_ad(rec_offs_validate(rec, index, offsets));
ut_ad(!rec_is_default_row(rec, index));
max_trx_id = page_get_max_trx_id(page); max_trx_id = page_get_max_trx_id(page);
...@@ -1539,6 +1547,8 @@ lock_rec_other_trx_holds_expl( ...@@ -1539,6 +1547,8 @@ lock_rec_other_trx_holds_expl(
const buf_block_t* block) /*!< in: buffer block const buf_block_t* block) /*!< in: buffer block
containing the record */ containing the record */
{ {
ut_ad(!page_rec_is_default_row(rec));
trx_t* holds = NULL; trx_t* holds = NULL;
lock_mutex_enter(); lock_mutex_enter();
...@@ -3575,6 +3585,9 @@ lock_move_reorganize_page( ...@@ -3575,6 +3585,9 @@ lock_move_reorganize_page(
for (;;) { for (;;) {
ulint old_heap_no; ulint old_heap_no;
ulint new_heap_no; ulint new_heap_no;
ut_d(const rec_t* const orec = rec1);
ut_ad(page_rec_is_default_row(rec1)
== page_rec_is_default_row(rec2));
if (comp) { if (comp) {
old_heap_no = rec_get_heap_no_new(rec2); old_heap_no = rec_get_heap_no_new(rec2);
...@@ -3595,6 +3608,8 @@ lock_move_reorganize_page( ...@@ -3595,6 +3608,8 @@ lock_move_reorganize_page(
/* Clear the bit in old_lock. */ /* Clear the bit in old_lock. */
if (old_heap_no < lock->un_member.rec_lock.n_bits if (old_heap_no < lock->un_member.rec_lock.n_bits
&& lock_rec_reset_nth_bit(lock, old_heap_no)) { && lock_rec_reset_nth_bit(lock, old_heap_no)) {
ut_ad(!page_rec_is_default_row(orec));
/* NOTE that the old lock bitmap could be too /* NOTE that the old lock bitmap could be too
small for the new heap number! */ small for the new heap number! */
...@@ -3674,6 +3689,10 @@ lock_move_rec_list_end( ...@@ -3674,6 +3689,10 @@ lock_move_rec_list_end(
reset the lock bits on the old */ reset the lock bits on the old */
for (;;) { for (;;) {
ut_ad(page_rec_is_default_row(rec1)
== page_rec_is_default_row(rec2));
ut_d(const rec_t* const orec = rec1);
ulint rec1_heap_no; ulint rec1_heap_no;
ulint rec2_heap_no; ulint rec2_heap_no;
...@@ -3696,8 +3715,11 @@ lock_move_rec_list_end( ...@@ -3696,8 +3715,11 @@ lock_move_rec_list_end(
rec2_heap_no = rec_get_heap_no_old(rec2); rec2_heap_no = rec_get_heap_no_old(rec2);
ut_ad(rec_get_data_size_old(rec1)
== rec_get_data_size_old(rec2));
ut_ad(!memcmp(rec1, rec2, ut_ad(!memcmp(rec1, rec2,
rec_get_data_size_old(rec2))); rec_get_data_size_old(rec1)));
rec1 = page_rec_get_next_low(rec1, FALSE); rec1 = page_rec_get_next_low(rec1, FALSE);
rec2 = page_rec_get_next_low(rec2, FALSE); rec2 = page_rec_get_next_low(rec2, FALSE);
...@@ -3705,6 +3727,8 @@ lock_move_rec_list_end( ...@@ -3705,6 +3727,8 @@ lock_move_rec_list_end(
if (rec1_heap_no < lock->un_member.rec_lock.n_bits if (rec1_heap_no < lock->un_member.rec_lock.n_bits
&& lock_rec_reset_nth_bit(lock, rec1_heap_no)) { && lock_rec_reset_nth_bit(lock, rec1_heap_no)) {
ut_ad(!page_rec_is_default_row(orec));
if (type_mode & LOCK_WAIT) { if (type_mode & LOCK_WAIT) {
lock_reset_lock_and_trx_wait(lock); lock_reset_lock_and_trx_wait(lock);
} }
...@@ -3748,6 +3772,7 @@ lock_move_rec_list_start( ...@@ -3748,6 +3772,7 @@ lock_move_rec_list_start(
ut_ad(block->frame == page_align(rec)); ut_ad(block->frame == page_align(rec));
ut_ad(new_block->frame == page_align(old_end)); ut_ad(new_block->frame == page_align(old_end));
ut_ad(comp == page_rec_is_comp(old_end)); ut_ad(comp == page_rec_is_comp(old_end));
ut_ad(!page_rec_is_default_row(rec));
lock_mutex_enter(); lock_mutex_enter();
...@@ -3773,6 +3798,9 @@ lock_move_rec_list_start( ...@@ -3773,6 +3798,9 @@ lock_move_rec_list_start(
reset the lock bits on the old */ reset the lock bits on the old */
while (rec1 != rec) { while (rec1 != rec) {
ut_ad(!page_rec_is_default_row(rec1));
ut_ad(!page_rec_is_default_row(rec2));
ulint rec1_heap_no; ulint rec1_heap_no;
ulint rec2_heap_no; ulint rec2_heap_no;
...@@ -3873,6 +3901,8 @@ lock_rtr_move_rec_list( ...@@ -3873,6 +3901,8 @@ lock_rtr_move_rec_list(
rec1 = rec_move[moved].old_rec; rec1 = rec_move[moved].old_rec;
rec2 = rec_move[moved].new_rec; rec2 = rec_move[moved].new_rec;
ut_ad(!page_rec_is_default_row(rec1));
ut_ad(!page_rec_is_default_row(rec2));
if (comp) { if (comp) {
rec1_heap_no = rec_get_heap_no_new(rec1); rec1_heap_no = rec_get_heap_no_new(rec1);
...@@ -3951,6 +3981,8 @@ lock_update_merge_right( ...@@ -3951,6 +3981,8 @@ lock_update_merge_right(
page which will be page which will be
discarded */ discarded */
{ {
ut_ad(!page_rec_is_default_row(orig_succ));
lock_mutex_enter(); lock_mutex_enter();
/* Inherit the locks from the supremum of the left page to the /* Inherit the locks from the supremum of the left page to the
...@@ -4208,6 +4240,7 @@ lock_update_insert( ...@@ -4208,6 +4240,7 @@ lock_update_insert(
ulint donator_heap_no; ulint donator_heap_no;
ut_ad(block->frame == page_align(rec)); ut_ad(block->frame == page_align(rec));
ut_ad(!page_rec_is_default_row(rec));
/* Inherit the gap-locking locks for rec, in gap mode, from the next /* Inherit the gap-locking locks for rec, in gap mode, from the next
record */ record */
...@@ -4239,6 +4272,7 @@ lock_update_delete( ...@@ -4239,6 +4272,7 @@ lock_update_delete(
ulint next_heap_no; ulint next_heap_no;
ut_ad(page == page_align(rec)); ut_ad(page == page_align(rec));
ut_ad(!page_rec_is_default_row(rec));
if (page_is_comp(page)) { if (page_is_comp(page)) {
heap_no = rec_get_heap_no_new(rec); heap_no = rec_get_heap_no_new(rec);
...@@ -5074,6 +5108,7 @@ lock_rec_unlock( ...@@ -5074,6 +5108,7 @@ lock_rec_unlock(
ut_ad(block->frame == page_align(rec)); ut_ad(block->frame == page_align(rec));
ut_ad(!trx->lock.wait_lock); ut_ad(!trx->lock.wait_lock);
ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE)); ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE));
ut_ad(!page_rec_is_default_row(rec));
heap_no = page_rec_get_heap_no(rec); heap_no = page_rec_get_heap_no(rec);
...@@ -5600,6 +5635,7 @@ lock_rec_print(FILE* file, const lock_t* lock) ...@@ -5600,6 +5635,7 @@ lock_rec_print(FILE* file, const lock_t* lock)
rec = page_find_rec_with_heap_no( rec = page_find_rec_with_heap_no(
buf_block_get_frame(block), i); buf_block_get_frame(block), i);
ut_ad(!page_rec_is_default_row(rec));
offsets = rec_get_offsets( offsets = rec_get_offsets(
rec, lock->index, offsets, true, rec, lock->index, offsets, true,
...@@ -6229,6 +6265,7 @@ lock_rec_queue_validate( ...@@ -6229,6 +6265,7 @@ lock_rec_queue_validate(
ut_a(block->frame == page_align(rec)); ut_a(block->frame == page_align(rec));
ut_ad(rec_offs_validate(rec, index, offsets)); ut_ad(rec_offs_validate(rec, index, offsets));
ut_ad(!page_rec_is_comp(rec) == !rec_offs_comp(offsets)); ut_ad(!page_rec_is_comp(rec) == !rec_offs_comp(offsets));
ut_ad(page_rec_is_leaf(rec));
ut_ad(lock_mutex_own() == locked_lock_trx_sys); ut_ad(lock_mutex_own() == locked_lock_trx_sys);
ut_ad(!index || dict_index_is_clust(index) ut_ad(!index || dict_index_is_clust(index)
|| !dict_index_is_online_ddl(index)); || !dict_index_is_online_ddl(index));
...@@ -6331,6 +6368,7 @@ lock_rec_queue_validate( ...@@ -6331,6 +6368,7 @@ lock_rec_queue_validate(
lock = lock_rec_get_next_const(heap_no, lock)) { lock = lock_rec_get_next_const(heap_no, lock)) {
ut_ad(!trx_is_ac_nl_ro(lock->trx)); ut_ad(!trx_is_ac_nl_ro(lock->trx));
ut_ad(!page_rec_is_default_row(rec));
if (index) { if (index) {
ut_a(lock->index == index); ut_a(lock->index == index);
...@@ -6673,6 +6711,7 @@ lock_rec_insert_check_and_lock( ...@@ -6673,6 +6711,7 @@ lock_rec_insert_check_and_lock(
|| dict_index_is_clust(index) || dict_index_is_clust(index)
|| (flags & BTR_CREATE_FLAG)); || (flags & BTR_CREATE_FLAG));
ut_ad(mtr->is_named_space(index->space)); ut_ad(mtr->is_named_space(index->space));
ut_ad(page_rec_is_leaf(rec));
if (flags & BTR_NO_LOCKING_FLAG) { if (flags & BTR_NO_LOCKING_FLAG) {
...@@ -6687,6 +6726,7 @@ lock_rec_insert_check_and_lock( ...@@ -6687,6 +6726,7 @@ lock_rec_insert_check_and_lock(
trx_t* trx = thr_get_trx(thr); trx_t* trx = thr_get_trx(thr);
const rec_t* next_rec = page_rec_get_next_const(rec); const rec_t* next_rec = page_rec_get_next_const(rec);
ulint heap_no = page_rec_get_heap_no(next_rec); ulint heap_no = page_rec_get_heap_no(next_rec);
ut_ad(!rec_is_default_row(next_rec, index));
lock_mutex_enter(); lock_mutex_enter();
/* Because this code is invoked for a running transaction by /* Because this code is invoked for a running transaction by
...@@ -6812,6 +6852,8 @@ lock_rec_convert_impl_to_expl_for_trx( ...@@ -6812,6 +6852,8 @@ lock_rec_convert_impl_to_expl_for_trx(
ulint heap_no)/*!< in: rec heap number to lock */ ulint heap_no)/*!< in: rec heap number to lock */
{ {
ut_ad(trx_is_referenced(trx)); ut_ad(trx_is_referenced(trx));
ut_ad(page_rec_is_leaf(rec));
ut_ad(!rec_is_default_row(rec, index));
DEBUG_SYNC_C("before_lock_rec_convert_impl_to_expl_for_trx"); DEBUG_SYNC_C("before_lock_rec_convert_impl_to_expl_for_trx");
...@@ -6856,6 +6898,8 @@ lock_rec_convert_impl_to_expl( ...@@ -6856,6 +6898,8 @@ lock_rec_convert_impl_to_expl(
ut_ad(page_rec_is_user_rec(rec)); ut_ad(page_rec_is_user_rec(rec));
ut_ad(rec_offs_validate(rec, index, offsets)); ut_ad(rec_offs_validate(rec, index, offsets));
ut_ad(!page_rec_is_comp(rec) == !rec_offs_comp(offsets)); ut_ad(!page_rec_is_comp(rec) == !rec_offs_comp(offsets));
ut_ad(page_rec_is_leaf(rec));
ut_ad(!rec_is_default_row(rec, index));
if (dict_index_is_clust(index)) { if (dict_index_is_clust(index)) {
trx_id_t trx_id; trx_id_t trx_id;
...@@ -6910,6 +6954,7 @@ lock_clust_rec_modify_check_and_lock( ...@@ -6910,6 +6954,7 @@ lock_clust_rec_modify_check_and_lock(
ulint heap_no; ulint heap_no;
ut_ad(rec_offs_validate(rec, index, offsets)); ut_ad(rec_offs_validate(rec, index, offsets));
ut_ad(page_rec_is_leaf(rec));
ut_ad(dict_index_is_clust(index)); ut_ad(dict_index_is_clust(index));
ut_ad(block->frame == page_align(rec)); ut_ad(block->frame == page_align(rec));
...@@ -6917,6 +6962,7 @@ lock_clust_rec_modify_check_and_lock( ...@@ -6917,6 +6962,7 @@ lock_clust_rec_modify_check_and_lock(
return(DB_SUCCESS); return(DB_SUCCESS);
} }
ut_ad(!rec_is_default_row(rec, index));
ut_ad(!dict_table_is_temporary(index->table)); ut_ad(!dict_table_is_temporary(index->table));
heap_no = rec_offs_comp(offsets) heap_no = rec_offs_comp(offsets)
...@@ -6975,6 +7021,8 @@ lock_sec_rec_modify_check_and_lock( ...@@ -6975,6 +7021,8 @@ lock_sec_rec_modify_check_and_lock(
ut_ad(!dict_index_is_online_ddl(index) || (flags & BTR_CREATE_FLAG)); ut_ad(!dict_index_is_online_ddl(index) || (flags & BTR_CREATE_FLAG));
ut_ad(block->frame == page_align(rec)); ut_ad(block->frame == page_align(rec));
ut_ad(mtr->is_named_space(index->space)); ut_ad(mtr->is_named_space(index->space));
ut_ad(page_rec_is_leaf(rec));
ut_ad(!rec_is_default_row(rec, index));
if (flags & BTR_NO_LOCKING_FLAG) { if (flags & BTR_NO_LOCKING_FLAG) {
...@@ -7067,6 +7115,7 @@ lock_sec_rec_read_check_and_lock( ...@@ -7067,6 +7115,7 @@ lock_sec_rec_read_check_and_lock(
ut_ad(block->frame == page_align(rec)); ut_ad(block->frame == page_align(rec));
ut_ad(page_rec_is_user_rec(rec) || page_rec_is_supremum(rec)); ut_ad(page_rec_is_user_rec(rec) || page_rec_is_supremum(rec));
ut_ad(rec_offs_validate(rec, index, offsets)); ut_ad(rec_offs_validate(rec, index, offsets));
ut_ad(page_rec_is_leaf(rec));
ut_ad(mode == LOCK_X || mode == LOCK_S); ut_ad(mode == LOCK_X || mode == LOCK_S);
if ((flags & BTR_NO_LOCKING_FLAG) if ((flags & BTR_NO_LOCKING_FLAG)
...@@ -7076,6 +7125,7 @@ lock_sec_rec_read_check_and_lock( ...@@ -7076,6 +7125,7 @@ lock_sec_rec_read_check_and_lock(
return(DB_SUCCESS); return(DB_SUCCESS);
} }
ut_ad(!rec_is_default_row(rec, index));
heap_no = page_rec_get_heap_no(rec); heap_no = page_rec_get_heap_no(rec);
/* Some transaction may have an implicit x-lock on the record only /* Some transaction may have an implicit x-lock on the record only
...@@ -7147,6 +7197,8 @@ lock_clust_rec_read_check_and_lock( ...@@ -7147,6 +7197,8 @@ lock_clust_rec_read_check_and_lock(
ut_ad(gap_mode == LOCK_ORDINARY || gap_mode == LOCK_GAP ut_ad(gap_mode == LOCK_ORDINARY || gap_mode == LOCK_GAP
|| gap_mode == LOCK_REC_NOT_GAP); || gap_mode == LOCK_REC_NOT_GAP);
ut_ad(rec_offs_validate(rec, index, offsets)); ut_ad(rec_offs_validate(rec, index, offsets));
ut_ad(page_rec_is_leaf(rec));
ut_ad(!rec_is_default_row(rec, index));
if ((flags & BTR_NO_LOCKING_FLAG) if ((flags & BTR_NO_LOCKING_FLAG)
|| srv_read_only_mode || srv_read_only_mode
...@@ -8560,12 +8612,14 @@ lock_update_split_and_merge( ...@@ -8560,12 +8612,14 @@ lock_update_split_and_merge(
{ {
const rec_t* left_next_rec; const rec_t* left_next_rec;
ut_a(left_block && right_block); ut_ad(page_is_leaf(left_block->frame));
ut_a(orig_pred); ut_ad(page_is_leaf(right_block->frame));
ut_ad(page_align(orig_pred) == left_block->frame);
lock_mutex_enter(); lock_mutex_enter();
left_next_rec = page_rec_get_next_const(orig_pred); left_next_rec = page_rec_get_next_const(orig_pred);
ut_ad(!page_rec_is_default_row(left_next_rec));
/* Inherit the locks on the supremum of the left page to the /* Inherit the locks on the supremum of the left page to the
first record which was moved from the right page */ first record which was moved from the right page */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment