Commit 5faaf748 authored by marko@hundin.mysql.fi's avatar marko@hundin.mysql.fi

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)
parent 71c69f42
...@@ -1642,7 +1642,7 @@ btr_cur_optimistic_update( ...@@ -1642,7 +1642,7 @@ btr_cur_optimistic_update(
btr_search_update_hash_on_delete(cursor); 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); page_cur_move_to_prev(page_cursor);
...@@ -1885,7 +1885,7 @@ btr_cur_pessimistic_update( ...@@ -1885,7 +1885,7 @@ btr_cur_pessimistic_update(
btr_search_update_hash_on_delete(cursor); 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); page_cur_move_to_prev(page_cursor);
...@@ -2401,6 +2401,7 @@ btr_cur_optimistic_delete( ...@@ -2401,6 +2401,7 @@ btr_cur_optimistic_delete(
mem_heap_t* heap = NULL; mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, }; ulint offsets_[100] = { 100, };
ulint* offsets = offsets_; ulint* offsets = offsets_;
ibool no_compress_needed;
ut_ad(mtr_memo_contains(mtr, buf_block_align(btr_cur_get_page(cursor)), ut_ad(mtr_memo_contains(mtr, buf_block_align(btr_cur_get_page(cursor)),
MTR_MEMO_PAGE_X_FIX)); MTR_MEMO_PAGE_X_FIX));
...@@ -2414,9 +2415,11 @@ btr_cur_optimistic_delete( ...@@ -2414,9 +2415,11 @@ btr_cur_optimistic_delete(
offsets = rec_get_offsets(rec, cursor->index, offsets, offsets = rec_get_offsets(rec, cursor->index, offsets,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
if (!rec_offs_any_extern(offsets) no_compress_needed = !rec_offs_any_extern(offsets)
&& btr_cur_can_delete_without_compress( && 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); lock_update_delete(rec);
...@@ -2425,20 +2428,17 @@ btr_cur_optimistic_delete( ...@@ -2425,20 +2428,17 @@ btr_cur_optimistic_delete(
max_ins_size = page_get_max_insert_size_after_reorganize(page, max_ins_size = page_get_max_insert_size_after_reorganize(page,
1); 1);
page_cur_delete_rec(btr_cur_get_page_cur(cursor), 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, ibuf_update_free_bits_low(cursor->index, page, max_ins_size,
mtr); mtr);
if (heap) {
mem_heap_free(heap);
}
return(TRUE);
} }
if (heap) { if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
} }
return(FALSE);
return(no_compress_needed);
} }
/***************************************************************** /*****************************************************************
...@@ -2478,6 +2478,7 @@ btr_cur_pessimistic_delete( ...@@ -2478,6 +2478,7 @@ btr_cur_pessimistic_delete(
ibool success; ibool success;
ibool ret = FALSE; ibool ret = FALSE;
mem_heap_t* heap; mem_heap_t* heap;
ulint* offsets;
page = btr_cur_get_page(cursor); page = btr_cur_get_page(cursor);
tree = btr_cur_get_tree(cursor); tree = btr_cur_get_tree(cursor);
...@@ -2503,20 +2504,20 @@ btr_cur_pessimistic_delete( ...@@ -2503,20 +2504,20 @@ btr_cur_pessimistic_delete(
} }
} }
heap = mem_heap_create(256); heap = mem_heap_create(1024);
rec = btr_cur_get_rec(cursor); 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 /* Free externally stored fields if the record is neither
a node pointer nor in two-byte format. 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 if (cursor->index->table->comp
? !rec_get_node_ptr_flag(rec) ? !rec_get_node_ptr_flag(rec)
: !rec_get_1byte_offs_flag(rec)) { : !rec_get_1byte_offs_flag(rec)) {
btr_rec_free_externally_stored_fields(cursor->index, btr_rec_free_externally_stored_fields(cursor->index,
rec, rec_get_offsets(rec, cursor->index, rec, offsets, in_rollback, mtr);
NULL, ULINT_UNDEFINED, &heap),
in_rollback, mtr);
mem_heap_empty(heap);
} }
if ((page_get_n_recs(page) < 2) if ((page_get_n_recs(page) < 2)
...@@ -2568,7 +2569,8 @@ btr_cur_pessimistic_delete( ...@@ -2568,7 +2569,8 @@ btr_cur_pessimistic_delete(
btr_search_update_hash_on_delete(cursor); 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)); ut_ad(btr_check_node_ptr(tree, page, mtr));
......
...@@ -182,9 +182,10 @@ next record after the deleted one. */ ...@@ -182,9 +182,10 @@ next record after the deleted one. */
void void
page_cur_delete_rec( page_cur_delete_rec(
/*================*/ /*================*/
page_cur_t* cursor, /* in: a page cursor */ page_cur_t* cursor, /* in: a page cursor */
dict_index_t* index, /* in: record descriptor */ dict_index_t* index, /* in: record descriptor */
mtr_t* mtr); /* in: mini-transaction handle */ 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. */ Searches the right position for a page cursor. */
UNIV_INLINE UNIV_INLINE
......
...@@ -528,7 +528,7 @@ page_mem_free( ...@@ -528,7 +528,7 @@ page_mem_free(
/*==========*/ /*==========*/
page_t* page, /* in: index page */ page_t* page, /* in: index page */
rec_t* rec, /* in: pointer to the (origin of) record */ 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. */ The index page creation function. */
......
...@@ -777,20 +777,28 @@ page_mem_free( ...@@ -777,20 +777,28 @@ page_mem_free(
/*==========*/ /*==========*/
page_t* page, /* in: index page */ page_t* page, /* in: index page */
rec_t* rec, /* in: pointer to the (origin of) record */ 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; rec_t* free;
ulint garbage; ulint garbage;
ut_ad(rec_offs_validate(rec, NULL, offsets));
free = page_header_get_ptr(page, PAGE_FREE); free = page_header_get_ptr(page, PAGE_FREE);
page_rec_set_next(rec, free); page_rec_set_next(rec, free);
page_header_set_ptr(page, PAGE_FREE, rec); 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); garbage = page_header_get_field(page, PAGE_GARBAGE);
page_header_set_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 #ifdef UNIV_MATERIALIZE
......
...@@ -435,15 +435,6 @@ rec_offs_size( ...@@ -435,15 +435,6 @@ rec_offs_size(
/* out: size */ /* out: size */
const ulint* offsets);/* in: array returned by rec_get_offsets() */ 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. */ Returns a pointer to the start of the record. */
UNIV_INLINE UNIV_INLINE
byte* byte*
......
...@@ -1435,9 +1435,10 @@ recv_apply_hashed_log_recs( ...@@ -1435,9 +1435,10 @@ recv_apply_hashed_log_recs(
mutex_exit(&(recv_sys->mutex)); mutex_exit(&(recv_sys->mutex));
} }
#ifdef UNIV_HOTBACKUP
/* This page is allocated from the buffer pool and used in the function /* This page is allocated from the buffer pool and used in the function
below */ 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. */ Applies log records in the hash table to a backup. */
...@@ -1559,6 +1560,7 @@ recv_apply_log_recs_for_backup(void) ...@@ -1559,6 +1560,7 @@ recv_apply_log_recs_for_backup(void)
recv_sys_empty_hash(); recv_sys_empty_hash();
} }
#endif /* UNIV_HOTBACKUP */
#ifdef notdefined #ifdef notdefined
/*********************************************************************** /***********************************************************************
......
...@@ -1267,9 +1267,18 @@ page_cur_parse_delete_rec( ...@@ -1267,9 +1267,18 @@ page_cur_parse_delete_rec(
ut_a(offset <= UNIV_PAGE_SIZE); ut_a(offset <= UNIV_PAGE_SIZE);
if (page) { if (page) {
page_cur_position(page + offset, &cursor); mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
rec_t* rec = page + offset;
page_cur_position(rec, &cursor);
page_cur_delete_rec(&cursor, index, mtr); page_cur_delete_rec(&cursor, index,
rec_get_offsets(rec, index, offsets_,
ULINT_UNDEFINED, &heap), mtr);
if (heap) {
mem_heap_free(heap);
}
} }
return(ptr); return(ptr);
...@@ -1284,6 +1293,7 @@ page_cur_delete_rec( ...@@ -1284,6 +1293,7 @@ page_cur_delete_rec(
/*================*/ /*================*/
page_cur_t* cursor, /* in: a page cursor */ page_cur_t* cursor, /* in: a page cursor */
dict_index_t* index, /* in: record descriptor */ dict_index_t* index, /* in: record descriptor */
const ulint* offsets,/* in: rec_get_offsets(cursor->rec, index) */
mtr_t* mtr) /* in: mini-transaction handle */ mtr_t* mtr) /* in: mini-transaction handle */
{ {
page_dir_slot_t* cur_dir_slot; page_dir_slot_t* cur_dir_slot;
...@@ -1300,6 +1310,7 @@ page_cur_delete_rec( ...@@ -1300,6 +1310,7 @@ page_cur_delete_rec(
page = page_cur_get_page(cursor); page = page_cur_get_page(cursor);
current_rec = cursor->rec; current_rec = cursor->rec;
ut_ad(rec_offs_validate(current_rec, index, offsets));
/* The record must not be the supremum or infimum record. */ /* The record must not be the supremum or infimum record. */
ut_ad(current_rec != page_get_supremum_rec(page)); ut_ad(current_rec != page_get_supremum_rec(page));
...@@ -1365,7 +1376,7 @@ page_cur_delete_rec( ...@@ -1365,7 +1376,7 @@ page_cur_delete_rec(
page_dir_slot_set_n_owned(cur_dir_slot, cur_n_owned - 1); page_dir_slot_set_n_owned(cur_dir_slot, cur_n_owned - 1);
/* 6. Free the memory occupied by the record */ /* 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. /* 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 If the number drops below PAGE_DIR_SLOT_MIN_N_OWNED, we balance the
......
...@@ -416,7 +416,7 @@ page_create( ...@@ -416,7 +416,7 @@ page_create(
mem_heap_free(heap); 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_field(page, PAGE_N_DIR_SLOTS, 2);
page_header_set_ptr(page, PAGE_HEAP_TOP, heap_top); page_header_set_ptr(page, PAGE_HEAP_TOP, heap_top);
...@@ -428,7 +428,9 @@ page_create( ...@@ -428,7 +428,9 @@ page_create(
page_header_set_field(page, PAGE_N_DIRECTION, 0); page_header_set_field(page, PAGE_N_DIRECTION, 0);
page_header_set_field(page, PAGE_N_RECS, 0); page_header_set_field(page, PAGE_N_RECS, 0);
page_set_max_trx_id(page, ut_dulint_zero); 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 */ /* 5. SET POINTERS IN RECORDS AND DIR SLOTS */
/* Set the slots to point to infimum and supremum. */ /* Set the slots to point to infimum and supremum. */
...@@ -829,12 +831,18 @@ page_delete_rec_list_start( ...@@ -829,12 +831,18 @@ page_delete_rec_list_start(
{ {
page_cur_t cur1; page_cur_t cur1;
ulint log_mode; 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, if (index->table->comp) {
index->table->comp type = MLOG_COMP_LIST_START_DELETE;
? MLOG_COMP_LIST_START_DELETE } else {
: MLOG_LIST_START_DELETE, type = MLOG_LIST_START_DELETE;
mtr); }
page_delete_rec_list_write_log(page, rec, index, type, mtr);
page_cur_set_before_first(page, &cur1); page_cur_set_before_first(page, &cur1);
...@@ -850,8 +858,13 @@ page_delete_rec_list_start( ...@@ -850,8 +858,13 @@ page_delete_rec_list_start(
log_mode = mtr_set_log_mode(mtr, MTR_LOG_NONE); log_mode = mtr_set_log_mode(mtr, MTR_LOG_NONE);
while (page_cur_get_rec(&cur1) != rec) { 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 */ /* Restore log mode */
......
...@@ -620,7 +620,7 @@ rec_set_nth_field_extern_bit_new( ...@@ -620,7 +620,7 @@ rec_set_nth_field_extern_bit_new(
mlog_write_ulint(lens + 1, len, mlog_write_ulint(lens + 1, len,
MLOG_1BYTE, mtr); MLOG_1BYTE, mtr);
} else { } else {
lens[1] = len; lens[1] = (byte) len;
} }
return; return;
} }
...@@ -658,29 +658,6 @@ rec_set_field_extern_bits( ...@@ -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. Sets an old-style record field to SQL null.
The physical size of the field is not changed. */ The physical size of the field is not changed. */
...@@ -935,13 +912,13 @@ rec_convert_dtuple_to_rec_new( ...@@ -935,13 +912,13 @@ rec_convert_dtuple_to_rec_new(
|| dtype_get_mtype(type) == DATA_BLOB); || dtype_get_mtype(type) == DATA_BLOB);
if (len < 128 || (dtype_get_len(type) < 256 if (len < 128 || (dtype_get_len(type) < 256
&& dtype_get_mtype(type) != DATA_BLOB)) { && dtype_get_mtype(type) != DATA_BLOB)) {
*lens-- = len; *lens-- = (byte) len;
} }
else { else {
/* the extern bits will be set later */ /* the extern bits will be set later */
ut_ad(len < 16384); ut_ad(len < 16384);
*lens-- = len >> 8 | 0x80; *lens-- = (byte) (len >> 8) | 0x80;
*lens-- = len; *lens-- = (byte) len;
} }
} }
copy: copy:
......
...@@ -1501,7 +1501,7 @@ srv_suspend_mysql_thread( ...@@ -1501,7 +1501,7 @@ srv_suspend_mysql_thread(
ut_usectime(&sec, &ms); ut_usectime(&sec, &ms);
finish_time = (ib_longlong)sec * 1000000 + 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_current_count--;
srv_n_lock_wait_time = srv_n_lock_wait_time + diff_time; srv_n_lock_wait_time = srv_n_lock_wait_time + diff_time;
...@@ -1799,9 +1799,12 @@ srv_export_innodb_status(void) ...@@ -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_waits= srv_n_lock_wait_count;
export_vars.innodb_row_lock_current_waits= srv_n_lock_wait_current_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= srv_n_lock_wait_time / 10000;
export_vars.innodb_row_lock_time_avg= if (srv_n_lock_wait_count > 0) {
(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) : 0; (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_row_lock_time_max= srv_n_lock_max_wait_time / 10000;
export_vars.innodb_rows_read= srv_n_rows_read; export_vars.innodb_rows_read= srv_n_rows_read;
export_vars.innodb_rows_inserted= srv_n_rows_inserted; export_vars.innodb_rows_inserted= srv_n_rows_inserted;
......
...@@ -369,11 +369,11 @@ mutex_spin_wait( ...@@ -369,11 +369,11 @@ mutex_spin_wait(
{ {
ulint index; /* index of the reserved wait cell */ ulint index; /* index of the reserved wait cell */
ulint i; /* spin round count */ ulint i; /* spin round count */
#ifndef UNIV_HOTBACKUP
ib_longlong lstart_time = 0, lfinish_time; /* for timing os_wait */ ib_longlong lstart_time = 0, lfinish_time; /* for timing os_wait */
ulint ltime_diff; ulint ltime_diff;
ulint sec; ulint sec;
ulint ms; ulint ms;
#ifndef UNIV_HOTBACKUP
uint timer_started = 0; uint timer_started = 0;
#endif /* !UNIV_HOTBACKUP */ #endif /* !UNIV_HOTBACKUP */
ut_ad(mutex); ut_ad(mutex);
...@@ -535,7 +535,7 @@ Now there is no risk of infinite wait on the event. */ ...@@ -535,7 +535,7 @@ Now there is no risk of infinite wait on the event. */
ut_usectime(&sec, &ms); ut_usectime(&sec, &ms);
lfinish_time= (ib_longlong)sec * 1000000 + 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; mutex->lspent_time += ltime_diff;
if (mutex->lmax_spent_time < ltime_diff) if (mutex->lmax_spent_time < ltime_diff)
{ {
......
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