mirror of
https://github.com/MariaDB/server.git
synced 2026-05-16 20:07:13 +02:00
InnoDB: Zero fill newly created pages and deleted records to
remove old junk and to improve compression ratio. InnoDB: Make implicit type conversions explicit. (Bug #8826)
This commit is contained in:
parent
71c69f42cd
commit
5faaf74818
11 changed files with 85 additions and 77 deletions
|
|
@ -1642,7 +1642,7 @@ btr_cur_optimistic_update(
|
|||
|
||||
btr_search_update_hash_on_delete(cursor);
|
||||
|
||||
page_cur_delete_rec(page_cursor, index, mtr);
|
||||
page_cur_delete_rec(page_cursor, index, offsets, mtr);
|
||||
|
||||
page_cur_move_to_prev(page_cursor);
|
||||
|
||||
|
|
@ -1885,7 +1885,7 @@ btr_cur_pessimistic_update(
|
|||
|
||||
btr_search_update_hash_on_delete(cursor);
|
||||
|
||||
page_cur_delete_rec(page_cursor, index, mtr);
|
||||
page_cur_delete_rec(page_cursor, index, offsets, mtr);
|
||||
|
||||
page_cur_move_to_prev(page_cursor);
|
||||
|
||||
|
|
@ -2401,6 +2401,7 @@ btr_cur_optimistic_delete(
|
|||
mem_heap_t* heap = NULL;
|
||||
ulint offsets_[100] = { 100, };
|
||||
ulint* offsets = offsets_;
|
||||
ibool no_compress_needed;
|
||||
|
||||
ut_ad(mtr_memo_contains(mtr, buf_block_align(btr_cur_get_page(cursor)),
|
||||
MTR_MEMO_PAGE_X_FIX));
|
||||
|
|
@ -2414,9 +2415,11 @@ btr_cur_optimistic_delete(
|
|||
offsets = rec_get_offsets(rec, cursor->index, offsets,
|
||||
ULINT_UNDEFINED, &heap);
|
||||
|
||||
if (!rec_offs_any_extern(offsets)
|
||||
no_compress_needed = !rec_offs_any_extern(offsets)
|
||||
&& btr_cur_can_delete_without_compress(
|
||||
cursor, rec_offs_size(offsets), mtr)) {
|
||||
cursor, rec_offs_size(offsets), mtr);
|
||||
|
||||
if (no_compress_needed) {
|
||||
|
||||
lock_update_delete(rec);
|
||||
|
||||
|
|
@ -2425,20 +2428,17 @@ btr_cur_optimistic_delete(
|
|||
max_ins_size = page_get_max_insert_size_after_reorganize(page,
|
||||
1);
|
||||
page_cur_delete_rec(btr_cur_get_page_cur(cursor),
|
||||
cursor->index, mtr);
|
||||
cursor->index, offsets, mtr);
|
||||
|
||||
ibuf_update_free_bits_low(cursor->index, page, max_ins_size,
|
||||
mtr);
|
||||
if (heap) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
if (heap) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
return(FALSE);
|
||||
|
||||
return(no_compress_needed);
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
|
|
@ -2478,6 +2478,7 @@ btr_cur_pessimistic_delete(
|
|||
ibool success;
|
||||
ibool ret = FALSE;
|
||||
mem_heap_t* heap;
|
||||
ulint* offsets;
|
||||
|
||||
page = btr_cur_get_page(cursor);
|
||||
tree = btr_cur_get_tree(cursor);
|
||||
|
|
@ -2503,20 +2504,20 @@ btr_cur_pessimistic_delete(
|
|||
}
|
||||
}
|
||||
|
||||
heap = mem_heap_create(256);
|
||||
heap = mem_heap_create(1024);
|
||||
rec = btr_cur_get_rec(cursor);
|
||||
|
||||
offsets = rec_get_offsets(rec, cursor->index,
|
||||
NULL, ULINT_UNDEFINED, &heap);
|
||||
|
||||
/* Free externally stored fields if the record is neither
|
||||
a node pointer nor in two-byte format.
|
||||
This avoids unnecessary calls to rec_get_offsets(). */
|
||||
This avoids an unnecessary loop. */
|
||||
if (cursor->index->table->comp
|
||||
? !rec_get_node_ptr_flag(rec)
|
||||
: !rec_get_1byte_offs_flag(rec)) {
|
||||
btr_rec_free_externally_stored_fields(cursor->index,
|
||||
rec, rec_get_offsets(rec, cursor->index,
|
||||
NULL, ULINT_UNDEFINED, &heap),
|
||||
in_rollback, mtr);
|
||||
mem_heap_empty(heap);
|
||||
rec, offsets, in_rollback, mtr);
|
||||
}
|
||||
|
||||
if ((page_get_n_recs(page) < 2)
|
||||
|
|
@ -2568,7 +2569,8 @@ btr_cur_pessimistic_delete(
|
|||
|
||||
btr_search_update_hash_on_delete(cursor);
|
||||
|
||||
page_cur_delete_rec(btr_cur_get_page_cur(cursor), cursor->index, mtr);
|
||||
page_cur_delete_rec(btr_cur_get_page_cur(cursor), cursor->index,
|
||||
offsets, mtr);
|
||||
|
||||
ut_ad(btr_check_node_ptr(tree, page, mtr));
|
||||
|
||||
|
|
|
|||
|
|
@ -184,6 +184,7 @@ page_cur_delete_rec(
|
|||
/*================*/
|
||||
page_cur_t* cursor, /* in: a page cursor */
|
||||
dict_index_t* index, /* in: record descriptor */
|
||||
const ulint* offsets,/* in: rec_get_offsets(cursor->rec, index) */
|
||||
mtr_t* mtr); /* in: mini-transaction handle */
|
||||
/********************************************************************
|
||||
Searches the right position for a page cursor. */
|
||||
|
|
|
|||
|
|
@ -528,7 +528,7 @@ page_mem_free(
|
|||
/*==========*/
|
||||
page_t* page, /* in: index page */
|
||||
rec_t* rec, /* in: pointer to the (origin of) record */
|
||||
dict_index_t* index); /* in: record descriptor */
|
||||
const ulint* offsets);/* in: array returned by rec_get_offsets() */
|
||||
/**************************************************************
|
||||
The index page creation function. */
|
||||
|
||||
|
|
|
|||
|
|
@ -777,20 +777,28 @@ page_mem_free(
|
|||
/*==========*/
|
||||
page_t* page, /* in: index page */
|
||||
rec_t* rec, /* in: pointer to the (origin of) record */
|
||||
dict_index_t* index) /* in: record descriptor */
|
||||
const ulint* offsets)/* in: array returned by rec_get_offsets() */
|
||||
{
|
||||
rec_t* free;
|
||||
ulint garbage;
|
||||
|
||||
ut_ad(rec_offs_validate(rec, NULL, offsets));
|
||||
free = page_header_get_ptr(page, PAGE_FREE);
|
||||
|
||||
page_rec_set_next(rec, free);
|
||||
page_header_set_ptr(page, PAGE_FREE, rec);
|
||||
|
||||
/* Clear the data bytes of the deleted record in order to improve
|
||||
the compression ratio of the page and to make it easier to read
|
||||
page dumps in corruption reports. The extra bytes of the record
|
||||
cannot be cleared, because page_mem_alloc() needs them in order
|
||||
to determine the size of the deleted record. */
|
||||
memset(rec, 0, rec_offs_data_size(offsets));
|
||||
|
||||
garbage = page_header_get_field(page, PAGE_GARBAGE);
|
||||
|
||||
page_header_set_field(page, PAGE_GARBAGE,
|
||||
garbage + rec_get_size(rec, index));
|
||||
garbage + rec_offs_size(offsets));
|
||||
}
|
||||
|
||||
#ifdef UNIV_MATERIALIZE
|
||||
|
|
|
|||
|
|
@ -435,15 +435,6 @@ rec_offs_size(
|
|||
/* out: size */
|
||||
const ulint* offsets);/* in: array returned by rec_get_offsets() */
|
||||
/**************************************************************
|
||||
Returns the total size of a physical record. */
|
||||
|
||||
ulint
|
||||
rec_get_size(
|
||||
/*=========*/
|
||||
/* out: size */
|
||||
rec_t* rec, /* in: physical record */
|
||||
dict_index_t* index); /* in: record descriptor */
|
||||
/**************************************************************
|
||||
Returns a pointer to the start of the record. */
|
||||
UNIV_INLINE
|
||||
byte*
|
||||
|
|
|
|||
|
|
@ -1435,9 +1435,10 @@ loop:
|
|||
mutex_exit(&(recv_sys->mutex));
|
||||
}
|
||||
|
||||
#ifdef UNIV_HOTBACKUP
|
||||
/* This page is allocated from the buffer pool and used in the function
|
||||
below */
|
||||
page_t* recv_backup_application_page = NULL;
|
||||
static page_t* recv_backup_application_page = NULL;
|
||||
|
||||
/***********************************************************************
|
||||
Applies log records in the hash table to a backup. */
|
||||
|
|
@ -1559,6 +1560,7 @@ skip_this_recv_addr:
|
|||
|
||||
recv_sys_empty_hash();
|
||||
}
|
||||
#endif /* UNIV_HOTBACKUP */
|
||||
|
||||
#ifdef notdefined
|
||||
/***********************************************************************
|
||||
|
|
|
|||
|
|
@ -1267,9 +1267,18 @@ page_cur_parse_delete_rec(
|
|||
ut_a(offset <= UNIV_PAGE_SIZE);
|
||||
|
||||
if (page) {
|
||||
page_cur_position(page + offset, &cursor);
|
||||
mem_heap_t* heap = NULL;
|
||||
ulint offsets_[100] = { 100, };
|
||||
rec_t* rec = page + offset;
|
||||
|
||||
page_cur_delete_rec(&cursor, index, mtr);
|
||||
page_cur_position(rec, &cursor);
|
||||
|
||||
page_cur_delete_rec(&cursor, index,
|
||||
rec_get_offsets(rec, index, offsets_,
|
||||
ULINT_UNDEFINED, &heap), mtr);
|
||||
if (heap) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
}
|
||||
|
||||
return(ptr);
|
||||
|
|
@ -1284,6 +1293,7 @@ page_cur_delete_rec(
|
|||
/*================*/
|
||||
page_cur_t* cursor, /* in: a page cursor */
|
||||
dict_index_t* index, /* in: record descriptor */
|
||||
const ulint* offsets,/* in: rec_get_offsets(cursor->rec, index) */
|
||||
mtr_t* mtr) /* in: mini-transaction handle */
|
||||
{
|
||||
page_dir_slot_t* cur_dir_slot;
|
||||
|
|
@ -1300,6 +1310,7 @@ page_cur_delete_rec(
|
|||
|
||||
page = page_cur_get_page(cursor);
|
||||
current_rec = cursor->rec;
|
||||
ut_ad(rec_offs_validate(current_rec, index, offsets));
|
||||
|
||||
/* The record must not be the supremum or infimum record. */
|
||||
ut_ad(current_rec != page_get_supremum_rec(page));
|
||||
|
|
@ -1365,7 +1376,7 @@ page_cur_delete_rec(
|
|||
page_dir_slot_set_n_owned(cur_dir_slot, cur_n_owned - 1);
|
||||
|
||||
/* 6. Free the memory occupied by the record */
|
||||
page_mem_free(page, current_rec, index);
|
||||
page_mem_free(page, current_rec, offsets);
|
||||
|
||||
/* 7. Now we have decremented the number of owned records of the slot.
|
||||
If the number drops below PAGE_DIR_SLOT_MIN_N_OWNED, we balance the
|
||||
|
|
|
|||
|
|
@ -416,7 +416,7 @@ page_create(
|
|||
|
||||
mem_heap_free(heap);
|
||||
|
||||
/* 4. INITIALIZE THE PAGE HEADER */
|
||||
/* 4. INITIALIZE THE PAGE */
|
||||
|
||||
page_header_set_field(page, PAGE_N_DIR_SLOTS, 2);
|
||||
page_header_set_ptr(page, PAGE_HEAP_TOP, heap_top);
|
||||
|
|
@ -428,6 +428,8 @@ page_create(
|
|||
page_header_set_field(page, PAGE_N_DIRECTION, 0);
|
||||
page_header_set_field(page, PAGE_N_RECS, 0);
|
||||
page_set_max_trx_id(page, ut_dulint_zero);
|
||||
memset(heap_top, 0, UNIV_PAGE_SIZE - PAGE_EMPTY_DIR_START
|
||||
- (heap_top - page));
|
||||
|
||||
/* 5. SET POINTERS IN RECORDS AND DIR SLOTS */
|
||||
|
||||
|
|
@ -829,12 +831,18 @@ page_delete_rec_list_start(
|
|||
{
|
||||
page_cur_t cur1;
|
||||
ulint log_mode;
|
||||
ulint offsets_[100] = { 100, };
|
||||
ulint* offsets = offsets_;
|
||||
mem_heap_t* heap = NULL;
|
||||
byte type;
|
||||
|
||||
page_delete_rec_list_write_log(page, rec, index,
|
||||
index->table->comp
|
||||
? MLOG_COMP_LIST_START_DELETE
|
||||
: MLOG_LIST_START_DELETE,
|
||||
mtr);
|
||||
if (index->table->comp) {
|
||||
type = MLOG_COMP_LIST_START_DELETE;
|
||||
} else {
|
||||
type = MLOG_LIST_START_DELETE;
|
||||
}
|
||||
|
||||
page_delete_rec_list_write_log(page, rec, index, type, mtr);
|
||||
|
||||
page_cur_set_before_first(page, &cur1);
|
||||
|
||||
|
|
@ -850,8 +858,13 @@ page_delete_rec_list_start(
|
|||
log_mode = mtr_set_log_mode(mtr, MTR_LOG_NONE);
|
||||
|
||||
while (page_cur_get_rec(&cur1) != rec) {
|
||||
offsets = rec_get_offsets(page_cur_get_rec(&cur1), index,
|
||||
offsets, ULINT_UNDEFINED, &heap);
|
||||
page_cur_delete_rec(&cur1, index, offsets, mtr);
|
||||
}
|
||||
|
||||
page_cur_delete_rec(&cur1, index, mtr);
|
||||
if (heap) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
|
||||
/* Restore log mode */
|
||||
|
|
|
|||
|
|
@ -620,7 +620,7 @@ rec_set_nth_field_extern_bit_new(
|
|||
mlog_write_ulint(lens + 1, len,
|
||||
MLOG_1BYTE, mtr);
|
||||
} else {
|
||||
lens[1] = len;
|
||||
lens[1] = (byte) len;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -658,29 +658,6 @@ rec_set_field_extern_bits(
|
|||
}
|
||||
}
|
||||
|
||||
/**************************************************************
|
||||
Returns the total size of a physical record. */
|
||||
|
||||
ulint
|
||||
rec_get_size(
|
||||
/*=========*/
|
||||
/* out: size */
|
||||
rec_t* rec, /* in: physical record */
|
||||
dict_index_t* index) /* in: record descriptor */
|
||||
{
|
||||
mem_heap_t* heap = NULL;
|
||||
ulint offsets_[100 + REC_OFFS_HEADER_SIZE]
|
||||
= { 100, };
|
||||
ulint* offsets = rec_get_offsets(rec, index, offsets_,
|
||||
ULINT_UNDEFINED, &heap);
|
||||
ulint size = rec_offs_size(offsets);
|
||||
|
||||
if (heap) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
return(size);
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
Sets an old-style record field to SQL null.
|
||||
The physical size of the field is not changed. */
|
||||
|
|
@ -935,13 +912,13 @@ init:
|
|||
|| dtype_get_mtype(type) == DATA_BLOB);
|
||||
if (len < 128 || (dtype_get_len(type) < 256
|
||||
&& dtype_get_mtype(type) != DATA_BLOB)) {
|
||||
*lens-- = len;
|
||||
*lens-- = (byte) len;
|
||||
}
|
||||
else {
|
||||
/* the extern bits will be set later */
|
||||
ut_ad(len < 16384);
|
||||
*lens-- = len >> 8 | 0x80;
|
||||
*lens-- = len;
|
||||
*lens-- = (byte) (len >> 8) | 0x80;
|
||||
*lens-- = (byte) len;
|
||||
}
|
||||
}
|
||||
copy:
|
||||
|
|
|
|||
|
|
@ -1501,7 +1501,7 @@ srv_suspend_mysql_thread(
|
|||
ut_usectime(&sec, &ms);
|
||||
finish_time = (ib_longlong)sec * 1000000 + ms;
|
||||
|
||||
diff_time = finish_time - start_time;
|
||||
diff_time = (ulint) (finish_time - start_time);
|
||||
|
||||
srv_n_lock_wait_current_count--;
|
||||
srv_n_lock_wait_time = srv_n_lock_wait_time + diff_time;
|
||||
|
|
@ -1799,9 +1799,12 @@ srv_export_innodb_status(void)
|
|||
export_vars.innodb_row_lock_waits= srv_n_lock_wait_count;
|
||||
export_vars.innodb_row_lock_current_waits= srv_n_lock_wait_current_count;
|
||||
export_vars.innodb_row_lock_time= srv_n_lock_wait_time / 10000;
|
||||
export_vars.innodb_row_lock_time_avg=
|
||||
(srv_n_lock_wait_count > 0) ?
|
||||
(srv_n_lock_wait_time / 10000 / srv_n_lock_wait_count) : 0;
|
||||
if (srv_n_lock_wait_count > 0) {
|
||||
export_vars.innodb_row_lock_time_avg = (ulint)
|
||||
(srv_n_lock_wait_time / 10000 / srv_n_lock_wait_count);
|
||||
} else {
|
||||
export_vars.innodb_row_lock_time_avg = 0;
|
||||
}
|
||||
export_vars.innodb_row_lock_time_max= srv_n_lock_max_wait_time / 10000;
|
||||
export_vars.innodb_rows_read= srv_n_rows_read;
|
||||
export_vars.innodb_rows_inserted= srv_n_rows_inserted;
|
||||
|
|
|
|||
|
|
@ -369,11 +369,11 @@ mutex_spin_wait(
|
|||
{
|
||||
ulint index; /* index of the reserved wait cell */
|
||||
ulint i; /* spin round count */
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
ib_longlong lstart_time = 0, lfinish_time; /* for timing os_wait */
|
||||
ulint ltime_diff;
|
||||
ulint sec;
|
||||
ulint ms;
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
uint timer_started = 0;
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
ut_ad(mutex);
|
||||
|
|
@ -535,7 +535,7 @@ finish_timing:
|
|||
ut_usectime(&sec, &ms);
|
||||
lfinish_time= (ib_longlong)sec * 1000000 + ms;
|
||||
|
||||
ltime_diff= lfinish_time - lstart_time;
|
||||
ltime_diff= (ulint) (lfinish_time - lstart_time);
|
||||
mutex->lspent_time += ltime_diff;
|
||||
if (mutex->lmax_spent_time < ltime_diff)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue