Commit 5e876bd3 authored by Michael Widenius's avatar Michael Widenius

Aria bug fixes and improvements:

- Fixed performance bug in alter table with Aria; Aria didn't use disable keys + enable keys
- Fixed wrong warning about 'Wrong CRC on datapage' from REPAIR TABLE with aria block tables.
- Fixed bug in aria_chk that disabled performance counters.
- Added --translog_buffer_size to maria_read_log.

storage/maria/ha_maria.cc:
  Fixed performance bug in alter table with Aria; Aria didn't use disable keys + enable keys
storage/maria/ma_bitmap.c:
  Added some DBUG_ASSERT()'s and made code more uniform
storage/maria/ma_check.c:
  Fixed wrong warning about 'Wrong CRC on datapage' from REPAIR TABLE with aria block tables.
storage/maria/ma_pagecache.c:
  Copy read pages to buffer even if there was an error (to be able to detect zero filled pages)
storage/maria/maria_chk.c:
  Fixed bug in aria_chk that disabled performance counters.
storage/maria/maria_read_log.c:
  Added option to set translog_buffer_size
parent 9f4739a3
...@@ -1966,19 +1966,21 @@ void ha_maria::start_bulk_insert(ha_rows rows) ...@@ -1966,19 +1966,21 @@ void ha_maria::start_bulk_insert(ha_rows rows)
we don't want to update the key statistics based of only a few rows. we don't want to update the key statistics based of only a few rows.
Index file rebuild requires an exclusive lock, so if versioning is on Index file rebuild requires an exclusive lock, so if versioning is on
don't do it (see how ha_maria::store_lock() tries to predict repair). don't do it (see how ha_maria::store_lock() tries to predict repair).
We can repair index only if we have an exclusive (TL_WRITE) lock. To We can repair index only if we have an exclusive (TL_WRITE) lock or
see if table is empty, we shouldn't rely on the old records' count from if this is inside an ALTER TABLE, in which case lock_type == TL_UNLOCK.
our transaction's start (if that old count is 0 but now there are
records in the table, we would wrongly destroy them). To see if table is empty, we shouldn't rely on the old record
So we need to look at share->state.state.records. count from our transaction's start (if that old count is 0 but
As a safety net for now, we don't remove the test of now there are records in the table, we would wrongly destroy
file->state->records, because there is uncertainty on what will happen them). So we need to look at share->state.state.records. As a
during repair if the two states disagree. safety net for now, we don't remove the test of
file->state->records, because there is uncertainty on what will
happen during repair if the two states disagree.
*/ */
if ((file->state->records == 0) && if ((file->state->records == 0) &&
(share->state.state.records == 0) && can_enable_indexes && (share->state.state.records == 0) && can_enable_indexes &&
(!rows || rows >= MARIA_MIN_ROWS_TO_DISABLE_INDEXES) && (!rows || rows >= MARIA_MIN_ROWS_TO_DISABLE_INDEXES) &&
(file->lock.type == TL_WRITE)) (file->lock.type == TL_WRITE || file->lock.type == TL_UNLOCK))
{ {
/** /**
@todo for a single-row INSERT SELECT, we will go into repair, which @todo for a single-row INSERT SELECT, we will go into repair, which
......
...@@ -1061,14 +1061,18 @@ static my_bool move_to_next_bitmap(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap) ...@@ -1061,14 +1061,18 @@ static my_bool move_to_next_bitmap(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap)
MARIA_STATE_INFO *state= &info->s->state; MARIA_STATE_INFO *state= &info->s->state;
DBUG_ENTER("move_to_next_bitmap"); DBUG_ENTER("move_to_next_bitmap");
if (state->first_bitmap_with_space != ~(ulonglong) 0 && if (state->first_bitmap_with_space != ~(pgcache_page_no_t) 0 &&
state->first_bitmap_with_space != page) state->first_bitmap_with_space != page)
{ {
page= state->first_bitmap_with_space; page= state->first_bitmap_with_space;
state->first_bitmap_with_space= ~(ulonglong) 0; state->first_bitmap_with_space= ~(pgcache_page_no_t) 0;
DBUG_ASSERT(page % bitmap->pages_covered == 0);
} }
else else
{
page+= bitmap->pages_covered; page+= bitmap->pages_covered;
DBUG_ASSERT(page % bitmap->pages_covered == 0);
}
DBUG_RETURN(_ma_change_bitmap_page(info, bitmap, page)); DBUG_RETURN(_ma_change_bitmap_page(info, bitmap, page));
} }
...@@ -2039,8 +2043,7 @@ my_bool _ma_bitmap_find_new_place(MARIA_HA *info, MARIA_ROW *row, ...@@ -2039,8 +2043,7 @@ my_bool _ma_bitmap_find_new_place(MARIA_HA *info, MARIA_ROW *row,
goto abort; goto abort;
/* Switch bitmap to current head page */ /* Switch bitmap to current head page */
bitmap_page= page / share->bitmap.pages_covered; bitmap_page= page - page % share->bitmap.pages_covered;
bitmap_page*= share->bitmap.pages_covered;
if (share->bitmap.page != bitmap_page && if (share->bitmap.page != bitmap_page &&
_ma_change_bitmap_page(info, &share->bitmap, bitmap_page)) _ma_change_bitmap_page(info, &share->bitmap, bitmap_page))
......
...@@ -6511,6 +6511,17 @@ static void copy_data_file_state(MARIA_STATE_INFO *to, ...@@ -6511,6 +6511,17 @@ static void copy_data_file_state(MARIA_STATE_INFO *to,
} }
/* Return 1 if block is full of zero's */
static my_bool zero_filled_block(uchar *tmp, uint length)
{
while (length--)
if (*(tmp++) != 0)
return 0;
return 1;
}
/* /*
Read 'safely' next record while scanning table. Read 'safely' next record while scanning table.
...@@ -6611,10 +6622,22 @@ static int _ma_safe_scan_block_record(MARIA_SORT_INFO *sort_info, ...@@ -6611,10 +6622,22 @@ static int _ma_safe_scan_block_record(MARIA_SORT_INFO *sort_info,
PAGECACHE_LOCK_LEFT_UNLOCKED, 0))) PAGECACHE_LOCK_LEFT_UNLOCKED, 0)))
{ {
if (my_errno == HA_ERR_WRONG_CRC) if (my_errno == HA_ERR_WRONG_CRC)
{
/*
Don't give errors for zero filled blocks. These can
sometimes be found at end of a bitmap when we wrote a big
record last that was moved to the next bitmap.
*/
if (!zero_filled_block(info->scan.page_buff, share->block_size) ||
_ma_check_bitmap_data(info, UNALLOCATED_PAGE, 0,
_ma_bitmap_get_page_bits(info,
&share->bitmap,
page)))
{ {
_ma_check_print_info(sort_info->param, _ma_check_print_info(sort_info->param,
"Wrong CRC on datapage at %s", "Wrong CRC on datapage at %s",
llstr(page, llbuff)); llstr(page, llbuff));
}
continue; continue;
} }
DBUG_RETURN(my_errno); DBUG_RETURN(my_errno);
......
...@@ -3519,7 +3519,7 @@ uchar *pagecache_read(PAGECACHE *pagecache, ...@@ -3519,7 +3519,7 @@ uchar *pagecache_read(PAGECACHE *pagecache,
} }
else else
{ {
if (!(status & PCBLOCK_ERROR)) if (status & PCBLOCK_READ)
{ {
#if !defined(SERIALIZED_READ_FROM_CACHE) #if !defined(SERIALIZED_READ_FROM_CACHE)
pagecache_pthread_mutex_unlock(&pagecache->cache_lock); pagecache_pthread_mutex_unlock(&pagecache->cache_lock);
...@@ -3533,7 +3533,7 @@ uchar *pagecache_read(PAGECACHE *pagecache, ...@@ -3533,7 +3533,7 @@ uchar *pagecache_read(PAGECACHE *pagecache,
pagecache_pthread_mutex_lock(&pagecache->cache_lock); pagecache_pthread_mutex_lock(&pagecache->cache_lock);
#endif #endif
} }
else if (status & PCBLOCK_ERROR)
my_errno= block->error; my_errno= block->error;
} }
......
...@@ -878,9 +878,9 @@ static void get_options(register int *argc,register char ***argv) ...@@ -878,9 +878,9 @@ static void get_options(register int *argc,register char ***argv)
load_defaults("my", load_default_groups, argc, argv); load_defaults("my", load_default_groups, argc, argv);
default_argv= *argv; default_argv= *argv;
check_param.testflag= T_UPDATE_STATE;
if (isatty(fileno(stdout))) if (isatty(fileno(stdout)))
check_param.testflag|=T_WRITE_LOOP; check_param.testflag|=T_WRITE_LOOP;
check_param.testflag= T_UPDATE_STATE;
if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option))) if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
exit(ho_error); exit(ho_error);
......
...@@ -32,7 +32,7 @@ const char *default_dbug_option= "d:t:o,/tmp/aria_read_log.trace"; ...@@ -32,7 +32,7 @@ const char *default_dbug_option= "d:t:o,/tmp/aria_read_log.trace";
static my_bool opt_display_only, opt_apply, opt_apply_undo, opt_silent; static my_bool opt_display_only, opt_apply, opt_apply_undo, opt_silent;
static my_bool opt_check; static my_bool opt_check;
static const char *opt_tmpdir; static const char *opt_tmpdir;
static ulong opt_page_buffer_size; static ulong opt_page_buffer_size, opt_translog_buffer_size;
static ulonglong opt_start_from_lsn, opt_end_lsn, opt_start_from_checkpoint; static ulonglong opt_start_from_lsn, opt_end_lsn, opt_start_from_checkpoint;
static MY_TMPDIR maria_chk_tmpdir; static MY_TMPDIR maria_chk_tmpdir;
...@@ -80,9 +80,8 @@ int main(int argc, char **argv) ...@@ -80,9 +80,8 @@ int main(int argc, char **argv)
But if it finds a log and this log was crashed, it will create a new log, But if it finds a log and this log was crashed, it will create a new log,
which is useless. TODO: start log handler in read-only mode. which is useless. TODO: start log handler in read-only mode.
*/ */
if (init_pagecache(maria_log_pagecache, if (init_pagecache(maria_log_pagecache, opt_translog_buffer_size,
TRANSLOG_PAGECACHE_SIZE, 0, 0, 0, 0, TRANSLOG_PAGE_SIZE, MY_WME) == 0 ||
TRANSLOG_PAGE_SIZE, MY_WME) == 0 ||
translog_init(maria_data_root, TRANSLOG_FILE_SIZE, translog_init(maria_data_root, TRANSLOG_FILE_SIZE,
0, 0, maria_log_pagecache, TRANSLOG_DEFAULT_FLAGS, 0, 0, maria_log_pagecache, TRANSLOG_DEFAULT_FLAGS,
opt_display_only)) opt_display_only))
...@@ -166,7 +165,7 @@ int main(int argc, char **argv) ...@@ -166,7 +165,7 @@ int main(int argc, char **argv)
#include "ma_check_standalone.h" #include "ma_check_standalone.h"
enum options_mc { enum options_mc {
OPT_CHARSETS_DIR=256, OPT_FORCE_CRASH OPT_CHARSETS_DIR=256, OPT_FORCE_CRASH, OPT_TRANSLOG_BUFFER_SIZE
}; };
static struct my_option my_long_options[] = static struct my_option my_long_options[] =
...@@ -228,6 +227,12 @@ static struct my_option my_long_options[] = ...@@ -228,6 +227,12 @@ static struct my_option my_long_options[] =
"colon (:)" "colon (:)"
#endif #endif
, (char**) &opt_tmpdir, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, , (char**) &opt_tmpdir, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{ "translog-buffer-size", OPT_TRANSLOG_BUFFER_SIZE,
"The size of the buffer used for transaction log for Aria tables",
&opt_translog_buffer_size, &opt_translog_buffer_size, 0,
GET_ULONG, REQUIRED_ARG, (long) TRANSLOG_PAGECACHE_SIZE,
1024L*1024L, (long) ~(ulong) 0, (long) MALLOC_OVERHEAD,
(long) IO_SIZE, 0},
{"undo", 'u', "Apply UNDO records to tables. (disable with --disable-undo)", {"undo", 'u', "Apply UNDO records to tables. (disable with --disable-undo)",
(uchar **) &opt_apply_undo, (uchar **) &opt_apply_undo, 0, (uchar **) &opt_apply_undo, (uchar **) &opt_apply_undo, 0,
GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
......
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