Bugs fixed:

- If not in autocommit mode, delete rows one by one so that we can roll back if necessary
- bitmap->used_size was not correctly set, which caused bitmap pages to be overwritten
- Fixed bug in bitmap handling when allocation tail pages
- Ensure we reserve place for directory entry when calculation place for head and tail pages
- Fixed wrong value in bitmap->size[0]
- Fixed wrong assert in flush_log_for_bitmap
- Fixed bug in _ma_bitmap_release_unused() where tail blocks could be wrongly reset
- Mark new pages as changed (Required to get repair() to work)
- Fixed problem with advancing log horizon pointer within one page bounds
- Fixed DBUG_ASSERT() when enable_indexes failes for end_bulk_insert()
- Fixed bug in logging of rows with more than one big blob
- Fixed DBUG_ASSERTS() in pagecache to allow change of WRITE_LOCK to READ_LOCK in unlock() calls
- Flush pagecache when we change from logging to not logging (if not, pagecache code breaks)
- Ensure my_errno is set on return from write/delete/update
- Fixed bug when using FIELD_SKIP_PRESPACE

New features:
- mysql_fix_privilege_tables now first uses binaries and scripts from source distribution, then in installed distribution
- Fix that optimize works for Maria tables
- maria_check --zerofill now also clear freed blob pages
- maria_check -di now prints more information about record page utilization

Optimizations:
- Use pagecache_unlock_by_link() instead of pagecache_write() if possible. (Avoids a memory copy and a find_block)
- Simplify code to abort when we found optimal bit pattern
- Skip also full head page bit patterns when searching for tail
- Increase default repair buffer to 128M for maria_chk and maria_read_log
- Increase default sort buffer for maria_chk to 64M
- Increase size of sortbuffer and pagecache for mysqld to 64M
- VARCHAR/CHAR fields are stored in increasing length order for BLOCK_RECORD tables

Better reporting:
- Fixed test of error condition for flush (for better error code)
- More error messages to mysqld if Maria recovery fails
- Always print warning if rows are deleted in repair
- Added global function _db_force_flush() that is usable when doing debugging in gdb
- Added call to my_debug_put_break_here() in case of some errors (for debugging)
- Remove used testfiles in unittest as these was written in different directories depending on from where the test was started

This should fix the bugs found when importing a big table with many varchars and one/many blobs to Maria


dbug/dbug.c:
  Added global function _db_force_flush() that is usable when doing debugging in gdbine
extra/replace.c:
  Fixed memory leak
include/my_dbug.h:
  Prototype for _db_force_flush()
include/my_global.h:
  Added stdarg.h as my_sys.h now depends on it.
include/my_sys.h:
  Make my_dbug_put_break_here() a NOP if not DBUG build
  Added my_printv_error()
include/myisamchk.h:
  Added entry 'lost' to be able to count space that is lost forever
mysql-test/r/maria.result:
  Updated results
mysql-test/t/maria.test:
  Reset autocommit after test
  New test to check if delete_all_rows is used (verified with --debug)
mysys/my_error.c:
  Added my_printv_error()
scripts/mysql_fix_privilege_tables.sh:
  First use binaries and scripts from source distribution, then in installed distribution
  This ensures that a development branch doesn't pick up wrong scripts)
sql/mysqld.cc:
  Fix that one can break maria recovery with ^C when debugging
sql/sql_class.cc:
  Removed #ifdef that has no effect
  (The preceeding DBUG_ASSERT() ensures that the following code will not be exectued)
storage/maria/ha_maria.cc:
  Increase size of sortbuffer and pagecache to 64M
  Fix that optimize works for Maria tables
  Fixed DBUG_ASSERT() when enable_indexes failes for end_bulk_insert()
  If not in autocommit mode, delete rows one by one so that we can roll back if necessary
  Fixed variable comments
storage/maria/ma_bitmap.c:
  More ASSERTS to detect overwrite of bitmap pages
  bitmap->used_size was not correctly set, which caused bitmap pages to be overwritten
  Ensure we reserve place for directory entry when calculation place for head and tail pages
  bitmap->size[0] should not include space for directory entry
  Simplify code to abort when we found optimal bit pattern
  Skip also full head page bit patterns when searching for tail (should speed up some common cases)
  Fixed bug in allocate_tail() when block->used was not aligned on 6 bytes
  Fixed wrong assert in flush_log_for_bitmap
  Fixed bug in _ma_bitmap_release_unused() where tail blocks could be wrongly reset
storage/maria/ma_blockrec.c:
  Ensure my_errno is set on return
  Fixed not optimal setting of row->min_length if we don't have variable length fields
  Use pagecache_unlock_by_link() instead of pagecache_write() if possible. (Avoids a memory copy and a find_block)
  Added DBUG_ASSERT() if we read or write wrong VARCHAR data
  Added DBUG_ASSERT() to find out if row sizes are calculated wrong
  Fixed bug in logging of rows with more than one big blob
storage/maria/ma_check.c:
  Disable logging while normal repair is done to avoid logging of index changes
  Fixed bug that caused CHECKSUM part of key page to be used
  Fixed that deleted of wrong records also works for BLOCK_RECORD
  Clear unallocated pages:
  - BLOB pages are not automaticly cleared on delete, so we need to use the bitmap to know if page is used or not
  Better error reporting
  More information about record page utilization
  Change printing of file position to printing of pages to make output more readable
  Always print warning if rows are deleted
storage/maria/ma_create.c:
  Calculate share.base_max_pack_length more accurately for BLOCK_RECORD pages (for future)
  Fixed that FIELD_SKIP_PRESPACE is recorded as FIELD_NORMAL; Fixed bug where fields could be used in wrong order
  Store FIELD_SKIP_ZERO fields before CHAR and VARCHAR fields (optimization)
  Store other fields in length order (to get better utilization of head block)
storage/maria/ma_delete.c:
  Ensure my_errno is set on return
storage/maria/ma_dynrec.c:
  Indentation fix
storage/maria/ma_locking.c:
  Set changed if open_count is counted down.
  (To avoid getting error "client is using or hasn't closed the table properly" with transactional tables
storage/maria/ma_loghandler.c:
  Fixed problem with advancing log horizon pointer within one page bounds (Patch from Sanja)
  Added more DBUG
  Indentation fixes
storage/maria/ma_open.c:
  Removed wrong casts
storage/maria/ma_page.c:
  Fixed usage of PAGECACHE_LOCK_WRITE_UNLOCK with _ma_new()
  Mark new pages as changed (Required to get repair() to work)
storage/maria/ma_pagecache.c:
  Fixed test of error condition for flush
  Fixed problem when using PAGECACHE_LOCK_WRITE_TO_READ with unlock()
  Added call to my_debug_put_break_here() in case of errors (for debugging)
storage/maria/ma_pagecrc.c:
  Ensure we get same crc for 32 and 64 bit systems by forcing argument to maria_page_crc to uint32
storage/maria/ma_recovery.c:
  Call my_printv_error() from eprint() to get critical errors to mysqld log
  Removed \n from error strings to eprint() to get nicer output in mysqld
  Added simple test in _ma_reenable_logging_for_table() to not do any work if not needed
storage/maria/ma_update.c:
  Ensure my_errno is set on return
storage/maria/ma_write.c:
  Ensure my_errno is set on return
storage/maria/maria_chk.c:
  Use DEBUGGER_OFF if --debug is not use (to get slightly faster execution for debug binaries)
  Added option --skip-safemalloc
  Don't write exponents for rec/key
storage/maria/maria_def.h:
  Increase default repair buffer to 128M for maria_chk and maria_read_log
  Increase default sort buffer for maria_chk to 64M
storage/maria/unittest/Makefile.am:
  Don't update files automaticly from bitkeeper
storage/maria/unittest/ma_pagecache_consist.c:
  Remove testfile at end
storage/maria/unittest/ma_pagecache_single.c:
  Remove testfile at end
storage/maria/unittest/ma_test_all-t:
  More tests
  Safer checking if test caused error
This commit is contained in:
unknown 2008-01-07 18:54:41 +02:00
parent c719e1fd33
commit b5df1d3446
34 changed files with 656 additions and 414 deletions

View file

@ -2263,6 +2263,16 @@ static void dbug_flush(CODE_STATE *cs)
} /* dbug_flush */
/* For debugging */
void _db_force_flush()
{
CODE_STATE *cs;
get_code_state_or_return;
(void) fflush(cs->stack->out_file);
}
void _db_lock_file_()
{
CODE_STATE *cs;

View file

@ -136,6 +136,7 @@ int main(int argc, char *argv[])
}
}
free_buffer();
my_free(replace, MYF(0));
my_end(verbose ? MY_CHECK_ERROR | MY_GIVE_INFO : MY_CHECK_ERROR);
exit(error ? 2 : 0);
return 0; /* No compiler warning */

View file

@ -47,6 +47,7 @@ extern void _db_end_(void);
extern void _db_lock_file_(void);
extern void _db_unlock_file_(void);
extern FILE *_db_fp_(void);
extern void _db_force_flush();
#define DBUG_ENTER(a) const char *_db_func_, *_db_file_; uint _db_level_; \
char **_db_framep_; \

View file

@ -410,6 +410,7 @@ C_MODE_END
#ifndef stdin
#include <stdio.h>
#endif
#include <stdarg.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif

View file

@ -653,6 +653,8 @@ extern int my_error _VARARGS((int nr,myf MyFlags, ...));
extern int my_printf_error _VARARGS((uint my_err, const char *format,
myf MyFlags, ...))
ATTRIBUTE_FORMAT(printf, 2, 4);
extern int my_printv_error(uint error, const char *format, myf MyFlags,
va_list ap);
extern int my_error_register(const char **errmsgs, int first, int last);
extern const char **my_error_unregister(int first, int last);
extern int my_message(uint my_err, const char *str,myf MyFlags);
@ -866,7 +868,12 @@ extern int unpackfrm(uchar **, size_t *, const uchar *);
extern ha_checksum my_checksum(ha_checksum crc, const uchar *mem,
size_t count);
#ifndef DBUG_OFF
extern void my_debug_put_break_here(void);
#else
#define my_debug_put_break_here() {}
#endif
extern void my_sleep(ulong m_seconds);
extern ulong crc32(ulong crc, const uchar *buf, uint len);
extern uint my_set_max_open_files(uint files);

View file

@ -122,7 +122,7 @@ typedef struct st_handler_check_param
my_off_t search_after_block;
my_off_t new_file_pos, key_file_blocks;
my_off_t keydata, totaldata, key_blocks, start_check_pos;
my_off_t used, empty, splits, del_length, link_used;
my_off_t used, empty, splits, del_length, link_used, lost;
ha_rows total_records, total_deleted, records,del_blocks;
ha_rows full_page_count, tail_count;
ha_checksum record_checksum, glob_crc;

View file

@ -569,6 +569,7 @@ a a b
1 1 1
2 2 1
drop table t1,t2;
set autocommit=1;
CREATE TABLE t1 (c1 varchar(250) NOT NULL) ROW_FORMAT=DYNAMIC;
CREATE TABLE t2 (c1 varchar(250) NOT NULL, PRIMARY KEY (c1)) ROW_FORMAT=DYNAMIC;
INSERT INTO t1 VALUES ('test000001'), ('test000002'), ('test000003');
@ -2088,3 +2089,15 @@ drop table if exists t1;
set global maria_log_file_size=4294967296;
Warnings:
Warning 1292 Truncated incorrect log_file_size value: '4294967296'
create table t1 (a int not null);
lock tables t1 write;
insert into t1 values (1),(2);
delete from t1;
unlock tables;
select * from t1;
a
insert into t1 values (1),(2);
delete from t1;
select * from t1;
a
drop table t1;

View file

@ -546,6 +546,7 @@ disconnect root;
connection default;
select straight_join * from t1,t2 force index (primary) where t1.a=t2.a;
drop table t1,t2;
set autocommit=1;
#
# Full key.
CREATE TABLE t1 (c1 varchar(250) NOT NULL) ROW_FORMAT=DYNAMIC;
@ -1336,6 +1337,21 @@ drop table if exists t1;
--enable_warnings
set global maria_log_file_size=4294967296;
#
# Test delete of all rows in autocommit and not autocommit
#
create table t1 (a int not null);
lock tables t1 write;
insert into t1 values (1),(2);
delete from t1;
unlock tables;
select * from t1;
insert into t1 values (1),(2);
delete from t1;
select * from t1;
drop table t1;
# End of 5.2 tests
--disable_result_log

View file

@ -114,15 +114,39 @@ int my_printf_error(uint error, const char *format, myf MyFlags, ...)
va_list args;
char ebuff[ERRMSGSIZE+20];
DBUG_ENTER("my_printf_error");
DBUG_PRINT("my", ("nr: %d MyFlags: %d errno: %d Format: %s",
DBUG_PRINT("my", ("nr: %d MyFlags: %d errno: %d format: %s",
error, MyFlags, errno, format));
va_start(args,MyFlags);
(void) my_vsnprintf (ebuff, sizeof(ebuff), format, args);
(void) my_vsnprintf(ebuff, sizeof(ebuff), format, args);
va_end(args);
DBUG_RETURN((*error_handler_hook)(error, ebuff, MyFlags));
}
/*
Error with va_list
SYNOPSIS
my_printv_error()
error Errno
format Format string
MyFlags Flags
... variable list
*/
int my_printv_error(uint error, const char *format, myf MyFlags, va_list ap)
{
char ebuff[ERRMSGSIZE+20];
DBUG_ENTER("my_printv_error");
DBUG_PRINT("my", ("nr: %d MyFlags: %d errno: %d format: %s",
error, MyFlags, errno, format));
(void) my_vsnprintf(ebuff, sizeof(ebuff), format, ap);
DBUG_RETURN((*error_handler_hook)(error, ebuff, MyFlags));
}
/*
Give message using error_handler_hook

View file

@ -94,7 +94,7 @@ parse_arguments() {
# [mysql_install_db], and then merge with the command line arguments
print_defaults=my_print_defaults
for dir in ./bin @bindir@ @bindir@ extra $print_defaults_bindir/../bin $print_defaults_bindir/../extra
for dir in ./extra ./bin @bindir@ @bindir@ $print_defaults_bindir/../bin $print_defaults_bindir/../extra
do
if test -x $dir/my_print_defaults
then
@ -117,7 +117,7 @@ dirname=`dirname "$0"`
if test -z "$bindir"
then
for i in @bindir@ $basedir/bin "$dirname/../client"
for i in "$dirname/../client" $basedir/bin @bindir@
do
if test -f $i/mysql
then
@ -149,8 +149,8 @@ then
fi
# Find where first mysql_fix_privilege_tables.sql is located
for i in $basedir/support-files $basedir/share $basedir/share/mysql \
$basedir/scripts $pkgdatadir . "$dirname"
for i in "$dirname" $basedir/support-files $basedir/share \
$basedir/share/mysql $basedir/scripts $pkgdatadir .
do
if test -f $i/$file
then

View file

@ -2314,10 +2314,6 @@ static void init_signals(void)
struct sigaction sa;
DBUG_ENTER("init_signals");
if (test_flags & TEST_SIGINT)
{
my_sigset(thr_kill_signal, end_thread_signal);
}
my_sigset(THR_SERVER_ALARM,print_signal_warning); // Should never be called!
if (!(test_flags & TEST_NO_STACKTRACE) || (test_flags & TEST_CORE_ON_SIGNAL))
@ -2378,6 +2374,9 @@ static void init_signals(void)
{
// May be SIGINT
sigdelset(&set, thr_kill_signal);
sigdelset(&set, SIGINT);
my_sigset(thr_kill_signal, end_thread_signal);
my_sigset(SIGINT, end_thread_signal);
}
sigprocmask(SIG_SETMASK,&set,NULL);
pthread_sigmask(SIG_SETMASK,&set,NULL);

View file

@ -394,12 +394,9 @@ Diagnostics_area::set_ok_status(THD *thd, ha_rows affected_rows_arg,
const char *message_arg)
{
DBUG_ASSERT(! is_set());
#ifdef DBUG_OFF
/* In production, refuse to overwrite an error with an OK packet. */
/* Refuse to overwrite an error with an OK packet. */
if (is_error())
return;
#endif
/** Only allowed to report success if has not yet reported an error */
m_server_status= thd->server_status;
m_total_warn_count= thd->total_warn_count;
@ -423,11 +420,9 @@ Diagnostics_area::set_eof_status(THD *thd)
/** Only allowed to report eof if has not yet reported an error */
DBUG_ASSERT(! is_set());
#ifdef DBUG_OFF
/* In production, refuse to overwrite an error with an EOF packet. */
/* Refuse to overwrite an error with an EOF packet. */
if (is_error())
return;
#endif
m_server_status= thd->server_status;
/*

View file

@ -159,8 +159,8 @@ static MYSQL_SYSVAR_ULONG(pagecache_age_threshold,
static MYSQL_SYSVAR_ULONGLONG(pagecache_buffer_size, pagecache_buffer_size,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"The size of the buffer used for index blocks for Maria tables. "
"Increase this to get better index handling (for all reads and multiple "
"writes) to as much as you can afford.", 0, 0,
"Increase this to get better index handling (for all reads and "
"multiple writes) to as much as you can afford.", 0, 0,
KEY_CACHE_SIZE, MALLOC_OVERHEAD, ~(ulong) 0, IO_SIZE);
static MYSQL_SYSVAR_ULONG(pagecache_division_limit, pagecache_division_limit,
@ -180,13 +180,13 @@ static MYSQL_THDVAR_ULONG(sort_buffer_size, PLUGIN_VAR_RQCMDARG,
static MYSQL_THDVAR_ENUM(stats_method, PLUGIN_VAR_RQCMDARG,
"Specifies how maria index statistics collection code should threat "
"NULLs. Possible values of name are \"nulls_unequal\", \"nulls_equal\", "
"NULLs. Possible values are \"nulls_unequal\", \"nulls_equal\", "
"and \"nulls_ignored\".", 0, 0, 0, &maria_stats_method_typelib);
static MYSQL_SYSVAR_ENUM(sync_log_dir, sync_log_dir, PLUGIN_VAR_RQCMDARG,
"Controls syncing directory after log file growth and new file "
"creation. Possible values of are \"never\", \"newfile\" and "
"\"always\")", NULL, NULL, TRANSLOG_SYNC_DIR_NEWFILE,
"creation. Possible values are \"never\", \"newfile\" and "
"\"always\").", NULL, NULL, TRANSLOG_SYNC_DIR_NEWFILE,
&maria_sync_log_dir_typelib);
/*****************************************************************************
@ -1249,14 +1249,13 @@ int ha_maria::repair(THD *thd, HA_CHECK &param, bool do_optimize)
DBUG_RETURN(HA_ADMIN_FAILED);
}
/** @todo BUG the if() below is always false for BLOCK_RECORD */
if (!do_optimize ||
((file->state->del ||
((file->s->data_file_type != BLOCK_RECORD) &&
share->state.split != file->state->records)) &&
(!(param.testflag & T_QUICK) ||
(share->state.changed & (STATE_NOT_OPTIMIZED_KEYS |
STATE_NOT_OPTIMIZED_ROWS)))))
((file->s->data_file_type == BLOCK_RECORD) ?
(share->state.changed & STATE_NOT_OPTIMIZED_ROWS) :
(file->state->del || share->state.split != file->state->records)) &&
(!(param.testflag & T_QUICK) ||
(share->state.changed & (STATE_NOT_OPTIMIZED_KEYS |
STATE_NOT_OPTIMIZED_ROWS))))
{
ulonglong key_map= ((local_testflag & T_CREATE_MISSING_KEYS) ?
maria_get_mask_all_keys_active(share->base.keys) :
@ -1294,13 +1293,7 @@ int ha_maria::repair(THD *thd, HA_CHECK &param, bool do_optimize)
{
thd_proc_info(thd, "Repair with keycache");
param.testflag &= ~(T_REP_BY_SORT | T_REP_PARALLEL);
/*
Disable logging of index changes as the repair redo call will
make it for us
*/
_ma_tmp_disable_logging_for_table(file, 0);
error= maria_repair(&param, file, fixed_name, param.testflag & T_QUICK);
_ma_reenable_logging_for_table(file);
/**
@todo RECOVERY BUG we do things with the index file
(maria_sort_index() after the above which already has logged the
@ -1362,6 +1355,9 @@ int ha_maria::repair(THD *thd, HA_CHECK &param, bool do_optimize)
_ma_check_print_warning(&param, "Number of rows changed from %s to %s",
llstr(rows, llbuff),
llstr(file->state->records, llbuff2));
/* Abort if warning was converted to error */
if (current_thd->is_error())
error= 1;
}
}
else
@ -1594,7 +1590,7 @@ int ha_maria::enable_indexes(uint mode)
maria_chk_init(&param);
param.op_name= "recreating_index";
param.testflag= (T_SILENT | T_REP_BY_SORT | T_QUICK |
T_CREATE_MISSING_KEYS);
T_CREATE_MISSING_KEYS | T_SAFE_REPAIR);
param.myf_rw &= ~MY_WAIT_IF_FULL;
param.sort_buffer_length= THDVAR(thd,sort_buffer_size);
param.stats_method= (enum_handler_stats_method)THDVAR(thd,stats_method);
@ -2039,6 +2035,16 @@ int ha_maria::extra_opt(enum ha_extra_function operation, ulong cache_size)
int ha_maria::delete_all_rows()
{
if (file->s->now_transactional &&
((table->in_use->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) ||
table->in_use->locked_tables))
{
/*
We are not in autocommit mode or user have done LOCK TABLES.
We must do the delete row by row to be able to rollback the command
*/
return HA_ERR_WRONG_COMMAND;
}
return maria_delete_all_rows(file);
}

View file

@ -46,16 +46,16 @@
Dynamic size records:
3 bits are used to indicate
3 bits are used to indicate Bytes free in 8K page
0 Empty page
1 0-30 % full (at least room for 3 records)
2 30-60 % full (at least room for 2 records)
3 60-90 % full (at least room for one record)
4 100 % full (no more room for records)
5 Tail page, 0-40 % full
6 Tail page, 40-80 % full
7 Full tail page or full blob page
0 Empty page 8176 (head or tail)
1 0-30 % full (at least room for 3 records) 5724
2 30-60 % full (at least room for 2 records) 3271
3 60-90 % full (at least room for one record) 818
4 100 % full (no more room for records) 0
5 Tail page, 0-40 % full 4906
6 Tail page, 40-80 % full 1636
7 Full tail page or full blob page 0
Assuming 8K pages, this will allow us to map:
8192 (bytes per page) * 8 bits/byte / 3 bits/page * 8192 (page size)= 170.7M
@ -222,7 +222,7 @@ my_bool _ma_bitmap_init(MARIA_SHARE *share, File file)
/* Update size for bits */
/* TODO; Make this dependent of the row size */
max_page_size= share->block_size - PAGE_OVERHEAD_SIZE;
max_page_size= share->block_size - PAGE_OVERHEAD_SIZE + DIR_ENTRY_SIZE;
bitmap->sizes[0]= max_page_size; /* Empty page */
bitmap->sizes[1]= max_page_size - max_page_size * 30 / 100;
bitmap->sizes[2]= max_page_size - max_page_size * 60 / 100;
@ -915,6 +915,7 @@ static void fill_block(MARIA_FILE_BITMAP *bitmap,
/* For each 6 bytes we have 6*8/3= 16 patterns */
page= (best_data - bitmap->map) / 6 * 16 + best_pos;
DBUG_ASSERT(page + 1 < bitmap->pages_covered);
block->page= bitmap->page + 1 + page;
block->page_count= TAIL_PAGE_COUNT_MARKER;
block->empty_space= pattern_to_size(bitmap, best_bits);
@ -971,7 +972,7 @@ static my_bool allocate_head(MARIA_FILE_BITMAP *bitmap, uint size,
LINT_INIT(best_pos);
DBUG_ASSERT(size <= FULL_PAGE_SIZE(bitmap->block_size));
for (; data < end; data += 6)
for (; data < end; data+= 6)
{
ulonglong bits= uint6korr(data); /* 6 bytes = 6*8/3= 16 patterns */
uint i;
@ -991,14 +992,6 @@ static my_bool allocate_head(MARIA_FILE_BITMAP *bitmap, uint size,
if (pattern <= min_bits)
{
/* There is enough space here */
if (pattern == min_bits)
{
/* There is exactly enough space here, return this page */
best_bits= min_bits;
best_data= data;
best_pos= i;
goto found;
}
if ((int) pattern > (int) best_bits)
{
/*
@ -1009,16 +1002,19 @@ static my_bool allocate_head(MARIA_FILE_BITMAP *bitmap, uint size,
best_bits= pattern;
best_data= data;
best_pos= i;
if (pattern == min_bits)
goto found; /* Best possible match */
}
}
}
}
if (!best_data) /* Found no place */
{
if (bitmap->used_size == bitmap->total_size)
if (data >= bitmap->map + bitmap->total_size)
DBUG_RETURN(1); /* No space in bitmap */
/* Allocate data at end of bitmap */
bitmap->used_size+= 6;
set_if_smaller(bitmap->used_size, bitmap->total_size);
best_data= data;
best_pos= best_bits= 0;
}
@ -1068,41 +1064,38 @@ static my_bool allocate_tail(MARIA_FILE_BITMAP *bitmap, uint size,
the following patterns: 1-4 (head pages, not suitable for tail) or
7 (full tail page). See 'Dynamic size records' comment at start of file.
At the moment we only skip full tail pages (ie, all bits are
At the moment we only skip full head and tail pages (ie, all bits are
set) as this is easy to detect with one simple test and is a
quite common case if we have blobs.
*/
if ((!bits && best_data) || bits == LL(0xffffffffffff))
if ((!bits && best_data) || bits == LL(0xffffffffffff) ||
bits == LL(04444444444444444))
continue;
for (i= 0; i < 16; i++, bits >>= 3)
{
uint pattern= bits & 7;
if (pattern <= min_bits && (!pattern || pattern >= 5))
{
if (pattern == min_bits)
{
best_bits= min_bits;
best_data= data;
best_pos= i;
goto found;
}
if ((int) pattern > (int) best_bits)
{
best_bits= pattern;
best_data= data;
best_pos= i;
if (pattern == min_bits)
goto found; /* Can't be better */
}
}
}
}
if (!best_data)
{
if (bitmap->used_size == bitmap->total_size)
if (data >= bitmap->map + bitmap->total_size)
DBUG_RETURN(1);
/* Allocate data at end of bitmap */
best_data= end;
best_data= data;
bitmap->used_size+= 6;
set_if_smaller(bitmap->used_size, bitmap->total_size);
best_pos= best_bits= 0;
}
@ -1253,6 +1246,7 @@ static ulong allocate_full_pages(MARIA_FILE_BITMAP *bitmap,
block->sub_blocks= 0;
block->org_bitmap_value= 0;
block->used= 0;
DBUG_ASSERT(page + best_area_size < bitmap->pages_covered);
DBUG_PRINT("info", ("page: %lu page_count: %u",
(ulong) block->page, block->page_count));
@ -1290,7 +1284,10 @@ static ulong allocate_full_pages(MARIA_FILE_BITMAP *bitmap,
best_data++;
}
if (data_end < best_data)
{
bitmap->used_size= (uint) (best_data - bitmap->map);
DBUG_ASSERT(bitmap->used_size <= bitmap->total_size);
}
bitmap->changed= 1;
DBUG_EXECUTE("bitmap", _ma_print_bitmap_changes(bitmap););
DBUG_RETURN(block->page_count);
@ -1326,7 +1323,11 @@ static my_bool find_head(MARIA_HA *info, uint length, uint position)
*/
block= dynamic_element(&info->bitmap_blocks, position, MARIA_BITMAP_BLOCK *);
while (allocate_head(bitmap, length, block))
/*
We need to have DIRENTRY_SIZE here to take into account that we may
need an extra directory entry for the row
*/
while (allocate_head(bitmap, length + DIR_ENTRY_SIZE, block))
if (move_to_next_bitmap(info, bitmap))
return 1;
return 0;
@ -1353,13 +1354,18 @@ static my_bool find_tail(MARIA_HA *info, uint length, uint position)
MARIA_FILE_BITMAP *bitmap= &info->s->bitmap;
MARIA_BITMAP_BLOCK *block;
DBUG_ENTER("find_tail");
DBUG_ASSERT(length <= info->s->block_size - PAGE_OVERHEAD_SIZE);
/* Needed, as there is no error checking in dynamic_element */
if (allocate_dynamic(&info->bitmap_blocks, position))
DBUG_RETURN(1);
block= dynamic_element(&info->bitmap_blocks, position, MARIA_BITMAP_BLOCK *);
while (allocate_tail(bitmap, length, block))
/*
We have to add DIR_ENTRY_SIZE to ensure we have space for the tail and
it's directroy entry on the page
*/
while (allocate_tail(bitmap, length + DIR_ENTRY_SIZE, block))
if (move_to_next_bitmap(info, bitmap))
DBUG_RETURN(1);
DBUG_RETURN(0);
@ -1539,6 +1545,7 @@ static void use_head(MARIA_HA *info, ulonglong page, uint size,
MARIA_BITMAP_BLOCK *block;
uchar *data;
uint offset, tmp, offset_page;
DBUG_ASSERT(page % bitmap->pages_covered);
block= dynamic_element(&info->bitmap_blocks, block_position,
MARIA_BITMAP_BLOCK*);
@ -1740,8 +1747,7 @@ my_bool _ma_bitmap_find_place(MARIA_HA *info, MARIA_ROW *row,
extents_length= row->extents_count * ROW_EXTENT_SIZE;
/*
The + 3 here is space to be able to store the number of segments
in the row header.
The + 3 is reserved for storing the number of segments in the row header.
*/
if ((head_length= (row->head_length + extents_length + 3)) <=
max_page_size)
@ -2329,9 +2335,9 @@ my_bool _ma_bitmap_release_unused(MARIA_HA *info, MARIA_BITMAP_BLOCKS *blocks)
set_page_bits(info, bitmap, block->page, bits))
goto err;
}
if (!(block->used & BLOCKUSED_USED) &&
_ma_bitmap_reset_full_page_bits(info, bitmap,
block->page, page_count))
else if (!(block->used & BLOCKUSED_USED) &&
_ma_bitmap_reset_full_page_bits(info, bitmap,
block->page, page_count))
goto err;
}
@ -2586,8 +2592,7 @@ flush_log_for_bitmap(uchar *page __attribute__((unused)),
const MARIA_SHARE *share= (MARIA_SHARE*)data_ptr;
#endif
DBUG_ENTER("flush_log_for_bitmap");
DBUG_ASSERT(share->page_type == PAGECACHE_LSN_PAGE &&
share->now_transactional);
DBUG_ASSERT(share->now_transactional);
/*
WAL imposes that UNDOs reach disk before bitmap is flushed. We don't know
the LSN of the last UNDO about this bitmap page, so we flush whole log.

View file

@ -1269,8 +1269,23 @@ static void calc_record_size(MARIA_HA *info, const uchar *record,
}
}
row->field_lengths_length= (uint) (field_length_data - row->field_lengths);
/*
- row->base_length is base information we must have on a page in first
extent:
- flag byte (1) + is_nulls_extended (0 | 1) + null_bytes + pack_bytes +
table_checksum (0 | 1)
- row->min_length is minimum amount of data we must store on
a page. bitmap code will ensure we get at list this much +
total number of extents and one extent information
- fixed_not_null_fields_length is length of fixed length fields that can't
be compacted
- head_length is the amount of data for the head page
(ie, all fields except blobs)
*/
row->min_length= (row->base_length +
size_to_store_key_length(row->field_lengths_length));
(share->base.max_field_lengths ?
size_to_store_key_length(row->field_lengths_length) :
0));
row->head_length= (row->min_length +
share->base.fixed_not_null_fields_length +
row->field_lengths_length +
@ -1534,11 +1549,11 @@ static my_bool get_head_or_tail_page(MARIA_HA *info,
/* Read old page */
page_link.unlock= PAGECACHE_LOCK_WRITE_UNLOCK;
res->buff= pagecache_read(share->pagecache, &info->dfile,
block->page, 0, buff, share->page_type,
block->page, 0, 0, share->page_type,
lock, &page_link.link);
page_link.changed= res->buff == 0;
page_link.changed= res->buff != 0;
push_dynamic(&info->pinned_pages, (void*) &page_link);
if (page_link.changed)
if (!page_link.changed)
goto crashed;
DBUG_ASSERT((res->buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) == page_type);
@ -1620,10 +1635,10 @@ static my_bool get_rowpos_in_head_or_tail_page(MARIA_HA *info,
else
{
page_link.unlock= PAGECACHE_LOCK_WRITE_UNLOCK;
res->buff= pagecache_read(share->pagecache, &info->dfile,
block->page, 0, buff, share->page_type,
lock, &page_link.link);
page_link.changed= res->buff != 0;
buff= pagecache_read(share->pagecache, &info->dfile,
block->page, 0, 0, share->page_type,
lock, &page_link.link);
page_link.changed= buff != 0;
push_dynamic(&info->pinned_pages, (void*) &page_link);
if (!page_link.changed) /* Read error */
goto err;
@ -1797,27 +1812,32 @@ static my_bool write_tail(MARIA_HA *info,
info->state->data_file_length= position + block_size;
}
DBUG_ASSERT(share->pagecache->block_size == block_size);
if (!(res= pagecache_write(share->pagecache,
&info->dfile, block->page, 0,
row_pos.buff,share->page_type,
block_is_read ? PAGECACHE_LOCK_WRITE_TO_READ :
PAGECACHE_LOCK_READ,
block_is_read ? PAGECACHE_PIN_LEFT_PINNED :
PAGECACHE_PIN,
PAGECACHE_WRITE_DELAY, &page_link.link,
LSN_IMPOSSIBLE)))
if (block_is_read)
{
/* Current page link is last element in pinned_pages */
MARIA_PINNED_PAGE *page_link;
page_link= dynamic_element(&info->pinned_pages,
info->pinned_pages.elements-1,
MARIA_PINNED_PAGE*);
pagecache_unlock_by_link(share->pagecache, page_link->link,
PAGECACHE_LOCK_WRITE_TO_READ,
PAGECACHE_PIN_LEFT_PINNED, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 1);
DBUG_ASSERT(page_link->changed);
page_link->unlock= PAGECACHE_LOCK_READ_UNLOCK;
res= 0;
}
else if (!(res= pagecache_write(share->pagecache,
&info->dfile, block->page, 0,
row_pos.buff,share->page_type,
PAGECACHE_LOCK_READ,
PAGECACHE_PIN,
PAGECACHE_WRITE_DELAY, &page_link.link,
LSN_IMPOSSIBLE)))
{
page_link.unlock= PAGECACHE_LOCK_READ_UNLOCK;
page_link.changed= 1;
if (block_is_read)
{
/* Change the lock used when we read the page */
set_dynamic(&info->pinned_pages, (void*) &page_link,
info->pinned_pages.elements-1);
}
else
push_dynamic(&info->pinned_pages, (void*) &page_link);
push_dynamic(&info->pinned_pages, (void*) &page_link);
}
DBUG_RETURN(res);
}
@ -1909,7 +1929,6 @@ static my_bool write_full_pages(MARIA_HA *info,
bzero(buff + block_size - PAGE_SUFFIX_SIZE - (data_size - copy_length),
(data_size - copy_length) + PAGE_SUFFIX_SIZE);
DBUG_ASSERT(share->pagecache->block_size == block_size);
if (pagecache_write(share->pagecache,
&info->dfile, page, 0,
buff, share->page_type,
@ -2333,6 +2352,7 @@ static my_bool write_block_record(MARIA_HA *info,
my_bool row_extents_in_use, blob_full_pages_exists;
LSN lsn;
my_off_t position;
uint save_my_errno;
DBUG_ENTER("write_block_record");
LINT_INIT(row_extents_first_part);
@ -2382,6 +2402,9 @@ static my_bool write_block_record(MARIA_HA *info,
memcpy(data, row->empty_bits, share->base.pack_bytes);
data+= share->base.pack_bytes;
DBUG_ASSERT(row_extents_in_use || undo_lsn != LSN_ERROR ||
(uint) (data - row_pos->data) == row->min_length);
/*
Allocate a buffer of rest of data (except blobs)
@ -2439,6 +2462,11 @@ static my_bool write_block_record(MARIA_HA *info,
memcpy(tmp_data, field_length_data, row->field_lengths_length);
tmp_data+= row->field_lengths_length;
DBUG_ASSERT(row_extents_in_use || undo_lsn != LSN_ERROR ||
(uint) (tmp_data - row_pos->data) == row->min_length +
share->base.fixed_not_null_fields_length +
row->field_lengths_length);
/* Copy variable length fields and fields with null/zero */
for (end_column= share->columndef + share->base.fields - share->base.blobs;
column < end_column ;
@ -2479,6 +2507,7 @@ static my_bool write_block_record(MARIA_HA *info,
field_length_data+= 2;
field_pos+= 2;
}
DBUG_ASSERT(length <= column->length);
break;
default: /* Wrong data */
DBUG_ASSERT(0);
@ -2831,26 +2860,35 @@ static my_bool write_block_record(MARIA_HA *info,
if (info->state->data_file_length <= position)
info->state->data_file_length= position + block_size;
DBUG_ASSERT(share->pagecache->block_size == block_size);
if (pagecache_write(share->pagecache,
&info->dfile, head_block->page, 0,
page_buff, share->page_type,
head_block_is_read ? PAGECACHE_LOCK_WRITE_TO_READ :
PAGECACHE_LOCK_READ,
head_block_is_read ? PAGECACHE_PIN_LEFT_PINNED :
PAGECACHE_PIN,
PAGECACHE_WRITE_DELAY, &page_link.link,
LSN_IMPOSSIBLE))
goto disk_err;
page_link.unlock= PAGECACHE_LOCK_READ_UNLOCK;
page_link.changed= 1;
if (head_block_is_read)
{
MARIA_PINNED_PAGE *page_link;
/* Head page is always the first pinned page */
set_dynamic(&info->pinned_pages, (void*) &page_link, 0);
page_link= dynamic_element(&info->pinned_pages, 0,
MARIA_PINNED_PAGE*);
pagecache_unlock_by_link(share->pagecache, page_link->link,
PAGECACHE_LOCK_WRITE_TO_READ,
PAGECACHE_PIN_LEFT_PINNED, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 1);
page_link->unlock= PAGECACHE_LOCK_READ_UNLOCK;
page_link->changed= 1;
}
else
{
if (pagecache_write(share->pagecache,
&info->dfile, head_block->page, 0,
page_buff, share->page_type,
head_block_is_read ? PAGECACHE_LOCK_WRITE_TO_READ :
PAGECACHE_LOCK_READ,
head_block_is_read ? PAGECACHE_PIN_LEFT_PINNED :
PAGECACHE_PIN,
PAGECACHE_WRITE_DELAY, &page_link.link,
LSN_IMPOSSIBLE))
goto disk_err;
page_link.unlock= PAGECACHE_LOCK_READ_UNLOCK;
page_link.changed= 1;
push_dynamic(&info->pinned_pages, (void*) &page_link);
}
if (share->now_transactional && (tmp_data_used || blob_full_pages_exists))
{
@ -2918,8 +2956,8 @@ static my_bool write_block_record(MARIA_HA *info,
if (!*tmp_blob_lengths) /* Null or "" */
continue;
length= tmp_column->length - portable_sizeof_char_ptr;
blob_length= *tmp_blob_lengths;
length= tmp_column->length - portable_sizeof_char_ptr;
/*
If last part of blog was on tail page, change blob_length to
reflect this
@ -2929,7 +2967,7 @@ static my_bool write_block_record(MARIA_HA *info,
if (blob_length)
{
memcpy_fixed((uchar*) &log_array_pos->str,
record + column->offset + length,
record + tmp_column->offset + length,
sizeof(uchar*));
log_array_pos->length= blob_length;
log_entry_length+= blob_length;
@ -3136,8 +3174,9 @@ disk_err:
Unpin all pinned pages to not cause problems for disk cache. This is
safe to call even if we already called _ma_unpin_all_pages() above.
*/
save_my_errno= my_errno;
_ma_unpin_all_pages_and_finalize_row(info, LSN_IMPOSSIBLE);
my_errno= save_my_errno;
DBUG_RETURN(1);
}
@ -3163,6 +3202,7 @@ static my_bool allocate_and_write_block_record(MARIA_HA *info,
{
struct st_row_pos_info row_pos;
MARIA_BITMAP_BLOCKS *blocks= &row->insert_blocks;
int save_my_errno;
DBUG_ENTER("allocate_and_write_block_record");
_ma_bitmap_flushable(info, 1);
@ -3201,10 +3241,13 @@ static my_bool allocate_and_write_block_record(MARIA_HA *info,
/* Now let checkpoint happen but don't commit */
DBUG_EXECUTE_IF("maria_over_alloc_bitmap", sleep(1000););
DBUG_RETURN(0);
err:
save_my_errno= my_errno;
if (info->non_flushable_state)
_ma_bitmap_flushable(info, -1);
_ma_unpin_all_pages_and_finalize_row(info, LSN_IMPOSSIBLE);
my_errno= save_my_errno;
DBUG_RETURN(1);
}
@ -3362,8 +3405,8 @@ static my_bool _ma_update_block_record2(MARIA_HA *info,
_ma_bitmap_flushable(info, 1);
buff= pagecache_read(share->pagecache,
&info->dfile, (pgcache_page_no_t) page, 0,
info->buff, share->page_type,
&info->dfile, (pgcache_page_no_t) page, 0, 0,
share->page_type,
PAGECACHE_LOCK_WRITE, &page_link.link);
page_link.unlock= PAGECACHE_LOCK_WRITE_UNLOCK;
page_link.changed= buff != 0;
@ -3512,8 +3555,8 @@ static my_bool _ma_update_at_original_place(MARIA_HA *info,
_ma_bitmap_flushable(info, 1);
buff= pagecache_read(share->pagecache,
&info->dfile, (pgcache_page_no_t) page, 0,
info->buff, share->page_type,
&info->dfile, (pgcache_page_no_t) page, 0, 0,
share->page_type,
PAGECACHE_LOCK_WRITE, &page_link.link);
page_link.unlock= PAGECACHE_LOCK_WRITE_UNLOCK;
page_link.changed= buff != 0;
@ -3746,10 +3789,8 @@ static my_bool delete_head_or_tail(MARIA_HA *info,
(ulong) ma_recordpos(page, record_number),
(ulong) page, record_number));
DBUG_ASSERT(share->pagecache->block_size == block_size);
buff= pagecache_read(share->pagecache,
&info->dfile, page, 0,
0,
&info->dfile, page, 0, 0,
share->page_type,
PAGECACHE_LOCK_WRITE, &page_link.link);
page_link.unlock= PAGECACHE_LOCK_WRITE_UNLOCK;
@ -3794,14 +3835,6 @@ static my_bool delete_head_or_tail(MARIA_HA *info,
log_data, NULL))
DBUG_RETURN(1);
}
if (pagecache_write(share->pagecache,
&info->dfile, page, 0,
buff, share->page_type,
lock_at_write,
PAGECACHE_PIN_LEFT_PINNED,
PAGECACHE_WRITE_DELAY, &page_link.link,
LSN_IMPOSSIBLE))
DBUG_RETURN(1);
}
else /* page is now empty */
{
@ -3818,19 +3851,13 @@ static my_bool delete_head_or_tail(MARIA_HA *info,
log_data, NULL))
DBUG_RETURN(1);
}
/* Write the empty page (needed only for REPAIR to work) */
if (pagecache_write(share->pagecache,
&info->dfile, page, 0,
buff, share->page_type,
lock_at_write,
PAGECACHE_PIN_LEFT_PINNED,
PAGECACHE_WRITE_DELAY, &page_link.link,
LSN_IMPOSSIBLE))
DBUG_RETURN(1);
DBUG_ASSERT(empty_space >= share->bitmap.sizes[0]);
}
/* The page is pinned with a read lock */
pagecache_unlock_by_link(share->pagecache, page_link.link,
lock_at_write,
PAGECACHE_PIN_LEFT_PINNED, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 1);
page_link.unlock= lock_at_unpin;
set_dynamic(&info->pinned_pages, (void*) &page_link,
info->pinned_pages.elements-1);
@ -4105,7 +4132,6 @@ static uchar *read_next_extent(MARIA_HA *info, MARIA_EXTENT_CURSOR *extent,
if (extent->tail)
lock= extent->lock_for_tail_pages;
DBUG_ASSERT(share->pagecache->block_size == share->block_size);
buff= pagecache_read(share->pagecache,
&info->dfile, extent->page, 0,
info->buff, share->page_type,
@ -4439,6 +4465,10 @@ int _ma_read_block_record2(MARIA_HA *info, uchar *record,
field_pos+= 2;
field_length_data+= 2;
}
#ifdef SANITY_CHECKS
if (length > column->length)
goto err;
#endif
if (read_long_data(info, field_pos, length, &extent, &data,
&end_of_data))
DBUG_RETURN(my_errno);
@ -4673,7 +4703,6 @@ int _ma_read_block_record(MARIA_HA *info, uchar *record,
offset= ma_recordpos_to_dir_entry(record_pos);
DBUG_ASSERT(share->pagecache->block_size == block_size);
if (!(buff= pagecache_read(share->pagecache,
&info->dfile, ma_recordpos_to_page(record_pos), 0,
info->buff, share->page_type,
@ -6762,13 +6791,15 @@ err:
/**
@brief Pagecache callback to get the TRANSLOG_ADDRESS to flush up to, when a
data (non-bitmap) or index page needs to be flushed. Returns a real LSN.
@brief Get the TRANSLOG_ADDRESS to flush up to
@param page Page's content
@param page_no Page's number (<offset>/<page length>)
@param data_ptr Callback data pointer (pointer to MARIA_SHARE)
@note
Usable for data (non-bitmap) and index pages
@retval LSN to flush up to
*/

View file

@ -94,7 +94,8 @@ static int _ma_safe_scan_block_record(MARIA_SORT_INFO *sort_info,
static void copy_data_file_state(MARIA_STATE_INFO *to,
MARIA_STATE_INFO *from);
static int write_log_record_for_repair(const HA_CHECK *param, MARIA_HA *info);
static void report_keypage_fault(HA_CHECK *param, my_off_t position);
static void report_keypage_fault(HA_CHECK *param, MARIA_HA *info,
my_off_t position);
static my_bool create_new_data_handle(MARIA_SORT_PARAM *param, File new_file);
@ -496,7 +497,7 @@ int maria_chk_key(HA_CHECK *param, register MARIA_HA *info)
PAGECACHE_LOCK_LEFT_UNLOCKED, DFLT_INIT_HITS,
info->buff, 0, 0))
{
report_keypage_fault(param, share->state.key_root[key]);
report_keypage_fault(param, info, share->state.key_root[key]);
if (!(param->testflag & T_INFO))
DBUG_RETURN(-1);
result= -1;
@ -662,7 +663,7 @@ static int chk_index_down(HA_CHECK *param, MARIA_HA *info,
if (!_ma_fetch_keypage(info, keyinfo, page, PAGECACHE_LOCK_LEFT_UNLOCKED,
DFLT_INIT_HITS, buff, 0, 0))
{
report_keypage_fault(param, page);
report_keypage_fault(param, info, page);
goto err;
}
param->key_file_blocks+=keyinfo->block_length;
@ -1578,6 +1579,7 @@ static my_bool check_head_page(HA_CHECK *param, MARIA_HA *info, uchar *record,
uchar *dir_entry;
uint row;
char llbuff[22], llbuff2[22];
ulonglong page= page_pos / share->block_size;
DBUG_ENTER("check_head_page");
dir_entry= page_buff+ share->block_size - PAGE_SUFFIX_SIZE;
@ -1593,25 +1595,24 @@ static my_bool check_head_page(HA_CHECK *param, MARIA_HA *info, uchar *record,
{
_ma_check_print_error(param,
"Page %9s: Row %3u is too short (%d bytes)",
llstr(page_pos, llbuff), row, length);
llstr(page, llbuff), row, length);
DBUG_RETURN(1);
}
flag= (uint) (uchar) page_buff[pos];
if (flag & ~(ROW_FLAG_ALL))
_ma_check_print_error(param,
"Page %9s: Row %3u has wrong flag: %d",
llstr(page_pos, llbuff), row, flag);
llstr(page, llbuff), row, flag);
DBUG_PRINT("info", ("rowid: %s page: %lu row: %u",
llstr(ma_recordpos(page_pos/share->block_size, row),
llbuff),
(ulong) (page_pos / share->block_size), row));
llstr(ma_recordpos(page, row), llbuff),
(ulong) page, row));
if (_ma_read_block_record2(info, record, page_buff+pos,
page_buff+pos+length))
{
_ma_check_print_error(param,
"Page %9s: Row %3d is crashed",
llstr(page_pos, llbuff), row);
llstr(page, llbuff), row);
if (param->err_count++ > MAXERR || !(param->testflag & T_VERBOSE))
DBUG_RETURN(1);
continue;
@ -1621,7 +1622,7 @@ static my_bool check_head_page(HA_CHECK *param, MARIA_HA *info, uchar *record,
ha_checksum checksum= (*share->calc_checksum)(info, record);
if (info->cur_row.checksum != (checksum & 255))
_ma_check_print_error(param, "Page %9s: Row %3d has wrong checksum",
llstr(page_pos, llbuff), row);
llstr(page, llbuff), row);
param->glob_crc+= checksum;
}
if (info->cur_row.extents_count)
@ -1631,8 +1632,8 @@ static my_bool check_head_page(HA_CHECK *param, MARIA_HA *info, uchar *record,
/* Check that bitmap has the right marker for the found extents */
for (i= 0 ; i < info->cur_row.extents_count ; i++)
{
uint page, page_count, page_type;
page= uint5korr(extents);
uint extent_page, page_count, page_type;
extent_page= uint5korr(extents);
page_count= uint2korr(extents+5) & ~START_EXTENT_BIT;
extents+= ROW_EXTENT_SIZE;
page_type= BLOB_PAGE;
@ -1646,19 +1647,17 @@ static my_bool check_head_page(HA_CHECK *param, MARIA_HA *info, uchar *record,
Check the whole extent with one test and only do the loop if
something is wrong (for exact error reporting)
*/
for ( ; page_count--; page++)
for ( ; page_count--; extent_page++)
{
uint bitmap_pattern;
if (_ma_check_if_right_bitmap_type(info, page_type, page,
if (_ma_check_if_right_bitmap_type(info, page_type, extent_page,
&bitmap_pattern))
{
_ma_check_print_error(param,
"Page %9s: Row: %3d has an extent with wrong information in bitmap: Page %9s Page_type: %d Bitmap: %d",
llstr(page_pos, llbuff), row,
llstr(page * share->bitmap.block_size,
llbuff2),
page_type,
bitmap_pattern);
llstr(page, llbuff), row,
llstr(extent_page, llbuff2),
page_type, bitmap_pattern);
if (param->err_count++ > MAXERR || !(param->testflag & T_VERBOSE))
DBUG_RETURN(1);
}
@ -1668,8 +1667,7 @@ static my_bool check_head_page(HA_CHECK *param, MARIA_HA *info, uchar *record,
param->full_page_count+= info->cur_row.full_page_count;
param->tail_count+= info->cur_row.tail_count;
if (check_keys_in_record(param, info, extend,
ma_recordpos(page_pos/share->block_size, row),
record))
ma_recordpos(page, row), record))
DBUG_RETURN(1);
}
DBUG_RETURN(0);
@ -1685,6 +1683,7 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
{
MARIA_SHARE *share= info->s;
my_off_t pos;
ulonglong page;
uchar *page_buff, *bitmap_buff, *data;
char llbuff[22], llbuff2[22];
uint block_size= share->block_size;
@ -1705,10 +1704,11 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
full_page_count= tail_count= 0;
param->full_page_count= param->tail_count= 0;
param->used= param->link_used= 0;
param->splits= info->state->data_file_length / block_size;
for (pos= 0;
for (pos= 0, page= 0;
pos < info->state->data_file_length;
pos+= block_size)
pos+= block_size, page++)
{
uint row_count, real_row_count, empty_space, page_type, bitmap_pattern;
LINT_INIT(row_count);
@ -1719,19 +1719,19 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
_ma_scan_end_block_record(info);
return -1;
}
if (((pos / block_size) % share->bitmap.pages_covered) == 0)
if ((page % share->bitmap.pages_covered) == 0)
{
/* Bitmap page */
if (pagecache_read(share->pagecache,
&info->s->bitmap.file,
(pos / block_size), 1,
page, 1,
bitmap_buff,
PAGECACHE_PLAIN_PAGE,
PAGECACHE_LOCK_LEFT_UNLOCKED, 0) == 0)
{
_ma_check_print_error(param,
"Page %9s: Got error: %d when reading datafile",
llstr(pos, llbuff), my_errno);
llstr(page, llbuff), my_errno);
goto err;
}
param->used+= block_size;
@ -1739,11 +1739,10 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
continue;
}
/* Skip pages marked as empty in bitmap */
offset_page= (((pos / block_size) % share->bitmap.pages_covered) -1) * 3;
offset_page= ((page % share->bitmap.pages_covered) -1) * 3;
offset= offset_page & 7;
data= bitmap_buff + offset_page / 8;
bitmap_pattern= uint2korr(data);
param->splits++;
if (!((bitmap_pattern >> offset) & 7))
{
param->empty+= block_size;
@ -1753,22 +1752,22 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
if (pagecache_read(share->pagecache,
&info->dfile,
(pos / block_size), 1,
page, 1,
page_buff,
share->page_type,
PAGECACHE_LOCK_LEFT_UNLOCKED, 0) == 0)
{
_ma_check_print_error(param,
"Page %9s: Got error: %d when reading datafile",
llstr(pos, llbuff), my_errno);
llstr(page, llbuff), my_errno);
goto err;
}
page_type= page_buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK;
if (page_type == UNALLOCATED_PAGE || page_type >= MAX_PAGE_TYPE)
{
_ma_check_print_error(param,
"Page %9s: Found wrong page type %d",
llstr(pos, llbuff), page_type);
"Page: %9s Found wrong page type %d",
llstr(page, llbuff), page_type);
if (param->err_count++ > MAXERR || !(param->testflag & T_VERBOSE))
goto err;
continue;
@ -1782,20 +1781,22 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
case HEAD_PAGE:
row_count= ((uchar*) page_buff)[DIR_COUNT_OFFSET];
empty_space= uint2korr(page_buff + EMPTY_SPACE_OFFSET);
param->used+= (PAGE_HEADER_SIZE + PAGE_SUFFIX_SIZE +
row_count * DIR_ENTRY_SIZE);
param->used+= block_size - empty_space;
param->link_used+= (PAGE_HEADER_SIZE + PAGE_SUFFIX_SIZE +
row_count * DIR_ENTRY_SIZE);
if (empty_space < share->bitmap.sizes[3])
param->lost+= empty_space;
full_dir= row_count == MAX_ROWS_PER_PAGE;
break;
case TAIL_PAGE:
row_count= ((uchar*) page_buff)[DIR_COUNT_OFFSET];
empty_space= uint2korr(page_buff + EMPTY_SPACE_OFFSET);
param->used+= (PAGE_HEADER_SIZE + PAGE_SUFFIX_SIZE +
row_count * DIR_ENTRY_SIZE);
param->used+= block_size - empty_space;
param->link_used+= (PAGE_HEADER_SIZE + PAGE_SUFFIX_SIZE +
row_count * DIR_ENTRY_SIZE);
full_dir= row_count == MAX_ROWS_PER_PAGE;
if (empty_space < share->bitmap.sizes[6])
param->lost+= empty_space;
break;
case BLOB_PAGE:
full_page_count++;
@ -1805,19 +1806,19 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
param->used+= block_size;
break;
}
if (_ma_check_bitmap_data(info, page_type, pos / block_size,
if (_ma_check_bitmap_data(info, page_type, page,
full_dir ? 0 : empty_space,
&bitmap_pattern))
{
if (bitmap_pattern == ~(uint) 0)
_ma_check_print_error(param,
"Page: %9s: Wrong bitmap for data on page",
llstr(pos, llbuff));
"Page %9s: Wrong bitmap for data on page",
llstr(page, llbuff));
else
_ma_check_print_error(param,
"Page %9s: Wrong data in bitmap. Page_type: %d empty_space: %u Bitmap-bits: %d",
llstr(pos, llbuff), page_type, empty_space,
bitmap_pattern);
llstr(page, llbuff), page_type,
empty_space, bitmap_pattern);
if (param->err_count++ > MAXERR || !(param->testflag & T_VERBOSE))
goto err;
}
@ -1839,11 +1840,11 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
/* Verify that rest of bitmap is zero */
if ((pos / block_size) % share->bitmap.pages_covered)
if (page % share->bitmap.pages_covered)
{
/* Not at end of bitmap */
uint bitmap_pattern;
offset_page= (((pos / block_size) % share->bitmap.pages_covered) -1) * 3;
offset_page= ((page % share->bitmap.pages_covered) -1) * 3;
offset= offset_page & 7;
data= bitmap_buff + offset_page / 8;
bitmap_pattern= uint2korr(data);
@ -1853,10 +1854,12 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
data - 2)))
{
ulonglong bitmap_page;
bitmap_page= pos / block_size / share->bitmap.pages_covered;
bitmap_page= page / share->bitmap.pages_covered;
bitmap_page*= share->bitmap.pages_covered;
_ma_check_print_error(param, "Bitmap at %s has pages reserved outside of data file length",
_ma_check_print_error(param,
"Bitmap at page %s has pages reserved outside of "
"data file length",
llstr(bitmap_page, llbuff));
DBUG_EXECUTE("bitmap", _ma_print_bitmap(&share->bitmap, bitmap_buff,
bitmap_page););
@ -1874,9 +1877,6 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
llstr(param->tail_count, llbuff),
llstr(tail_count, llbuff2));
/* Update splits to avoid warning */
share->state.split= param->splits;
info->state->del= param->del_blocks;
return param->error_printed != 0;
err:
@ -1910,6 +1910,7 @@ int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info,int extend)
}
param->records= param->del_blocks= 0;
param->used= param->link_used= param->splits= param->del_length= 0;
param->lost= 0;
param->tmp_record_checksum= param->glob_crc= 0;
param->err_count= 0;
@ -1953,7 +1954,7 @@ int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info,int extend)
param->record_checksum != param->tmp_record_checksum)
{
_ma_check_print_error(param,
"Key pointers and record positions doesn't match");
"Key pointers and record positions doesn't match");
error=1;
}
else if (param->glob_crc != info->state->checksum &&
@ -1961,7 +1962,7 @@ int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info,int extend)
(HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD)))
{
_ma_check_print_warning(param,
"Record checksum is not the same as checksum stored in the index file");
"Record checksum is not the same as checksum stored in the index file");
error=1;
}
else if (!extend)
@ -1973,7 +1974,7 @@ int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info,int extend)
!(share->keyinfo[key].flag & (HA_FULLTEXT | HA_SPATIAL)))
{
_ma_check_print_error(param,"Checksum for key: %2d doesn't match checksum for records",
key+1);
key+1);
error=1;
}
}
@ -1982,37 +1983,41 @@ int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info,int extend)
if (param->del_length != info->state->empty)
{
_ma_check_print_warning(param,
"Found %s deleted space. Should be %s",
llstr(param->del_length,llbuff2),
llstr(info->state->empty,llbuff));
"Found %s deleted space. Should be %s",
llstr(param->del_length,llbuff2),
llstr(info->state->empty,llbuff));
}
if (param->used + param->empty + param->del_length !=
info->state->data_file_length)
/* Skip following checks for BLOCK RECORD as they don't make any sence */
if (share->data_file_type != BLOCK_RECORD)
{
_ma_check_print_warning(param,
"Found %s record data and %s unused data and %s deleted data",
llstr(param->used, llbuff),
llstr(param->empty,llbuff2),
llstr(param->del_length,llbuff3));
_ma_check_print_warning(param,
"Total %s Should be: %s",
llstr((param->used+param->empty+param->del_length),
llbuff),
llstr(info->state->data_file_length,llbuff2));
}
if (param->del_blocks != info->state->del)
{
_ma_check_print_warning(param,
"Found %10s deleted blocks Should be: %s",
llstr(param->del_blocks,llbuff),
llstr(info->state->del,llbuff2));
}
if (param->splits != share->state.split)
{
_ma_check_print_warning(param,
"Found %10s parts Should be: %s parts",
llstr(param->splits, llbuff),
llstr(share->state.split,llbuff2));
if (param->used + param->empty + param->del_length !=
info->state->data_file_length)
{
_ma_check_print_warning(param,
"Found %s record data and %s unused data and %s deleted data",
llstr(param->used, llbuff),
llstr(param->empty,llbuff2),
llstr(param->del_length,llbuff3));
_ma_check_print_warning(param,
"Total %s Should be: %s",
llstr((param->used+param->empty +
param->del_length), llbuff),
llstr(info->state->data_file_length,llbuff2));
}
if (param->del_blocks != info->state->del)
{
_ma_check_print_warning(param,
"Found %10s deleted blocks Should be: %s",
llstr(param->del_blocks,llbuff),
llstr(info->state->del,llbuff2));
}
if (param->splits != share->state.split)
{
_ma_check_print_warning(param,
"Found %10s parts Should be: %s parts",
llstr(param->splits, llbuff),
llstr(share->state.split,llbuff2));
}
}
if (param->testflag & T_INFO)
{
@ -2044,18 +2049,20 @@ int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info,int extend)
printf("Records:%18s\n", "0");
}
printf("Record blocks:%12s Delete blocks:%10s\n",
llstr(param->splits - param->del_blocks, llbuff),
llstr(param->splits - param->del_blocks, llbuff),
llstr(param->del_blocks, llbuff2));
printf("Record data: %12s Deleted data: %10s\n",
llstr(param->used - param->link_used,llbuff),
llstr(param->used - param->link_used,llbuff),
llstr(param->del_length, llbuff2));
printf("Lost space: %12s Linkdata: %10s\n",
llstr(param->empty, llbuff),llstr(param->link_used, llbuff2));
printf("Empty space: %12s Linkdata: %10s\n",
llstr(param->empty, llbuff),llstr(param->link_used, llbuff2));
if (param->lost)
printf("Lost space: %12s", llstr(param->lost, llbuff));
}
my_free((uchar*) record,MYF(0));
DBUG_RETURN (error);
err:
err:
my_free((uchar*) record,MYF(0));
param->testflag|=T_RETRY_WITHOUT_QUICK;
DBUG_RETURN(1);
@ -2180,6 +2187,8 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
if (initialize_variables_for_repair(param, &sort_info, &sort_param, info,
rep_quick))
goto err;
if (share->now_transactional)
_ma_tmp_disable_logging_for_table(info, 0);
new_header_length= ((param->testflag & T_UNPACK) ? 0L :
share->pack.header_length);
@ -2423,11 +2432,11 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
{
if (start_records != info->state->records)
printf("Data records: %s\n", llstr(info->state->records,llbuff));
if (sort_info.dupp)
_ma_check_print_warning(param,
"%s records have been removed",
llstr(sort_info.dupp,llbuff));
}
if (sort_info.dupp)
_ma_check_print_warning(param,
"%s records have been removed",
llstr(sort_info.dupp,llbuff));
got_error= 0;
/* If invoked by external program that uses thr_lock */
@ -2469,6 +2478,8 @@ err:
*/
write_log_record_for_repair(param, info);
}
_ma_reenable_logging_for_table(info);
my_free(sort_param.rec_buff, MYF(MY_ALLOW_ZERO_PTR));
my_free(sort_param.record,MYF(MY_ALLOW_ZERO_PTR));
my_free(sort_info.buff,MYF(MY_ALLOW_ZERO_PTR));
@ -2799,7 +2810,7 @@ static int sort_one_index(HA_CHECK *param, MARIA_HA *info,
if (!_ma_fetch_keypage(info, keyinfo, pagepos,PAGECACHE_LOCK_LEFT_UNLOCKED,
DFLT_INIT_HITS, buff, 0, 0))
{
report_keypage_fault(param, pagepos);
report_keypage_fault(param, info, pagepos);
goto err;
}
if ((nod_flag=_ma_test_if_nod(share, buff)) || keyinfo->flag & HA_FULLTEXT)
@ -2952,6 +2963,7 @@ static my_bool maria_zerofill_data(HA_CHECK *param, MARIA_HA *info,
my_off_t pos;
ulonglong page;
uint block_size= share->block_size;
MARIA_FILE_BITMAP *bitmap= &share->bitmap;
DBUG_ENTER("maria_zerofill_data");
/* This works only with BLOCK_RECORD files */
@ -2989,7 +3001,13 @@ static my_bool maria_zerofill_data(HA_CHECK *param, MARIA_HA *info,
bzero(buff, block_size);
break;
case BLOB_PAGE:
bzero(buff, LSN_SIZE);
if (_ma_bitmap_get_page_bits(info, bitmap, page) == 0)
{
/* Unallocated page */
bzero(buff, block_size);
}
else
bzero(buff, LSN_SIZE);
break;
case HEAD_PAGE:
case TAIL_PAGE:
@ -3364,6 +3382,7 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
(size_t) param->sort_buffer_length))
{
param->retry_repair=1;
_ma_check_print_error(param, "Create index by sort failed");
goto err;
}
DBUG_EXECUTE_IF("maria_flush_whole_log",
@ -3404,7 +3423,10 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
param->read_cache.end_of_file=sort_param.filepos;
if (maria_write_data_suffix(&sort_info,1) ||
end_io_cache(&sort_info.new_info->rec_cache))
{
_ma_check_print_error(param, "Got error when flushing row cache");
goto err;
}
sort_info.new_info->opt_flag&= ~WRITE_CACHE_USED;
if (param->testflag & T_SAFE_REPAIR)
@ -3412,14 +3434,20 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
/* Don't repair if we loosed more than one row */
if (info->state->records+1 < start_records)
{
info->state->records=start_records;
_ma_check_print_error(param,
"Rows lost; Aborting because safe repair was "
"requested");
info->state->records=start_records;
goto err;
}
}
/** @todo RECOVERY BUG seems misplaced in some cases */
if (_ma_flush_table_files_after_repair(param, info))
{
_ma_check_print_error(param, "Got error when flushing caches");
goto err;
}
sort_info.new_info->state->data_file_length= sort_param.filepos;
if (sort_info.new_info != sort_info.info)
@ -3433,6 +3461,7 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
copy_data_file_state(&share->state, &save_state);
new_file= -1;
sort_info.new_info= info;
info->rec_cache.file= info->dfile.file;
}
share->state.version=(ulong) time((time_t*) 0); /* Force reopen */
@ -3451,6 +3480,7 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
sync_dir) ||
_ma_open_datafile(info, share, -1))
{
_ma_check_print_error(param, "Couldn't change to new data file");
goto err;
}
if (param->testflag & T_UNPACK)
@ -3513,11 +3543,11 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
{
if (start_records != info->state->records)
printf("Data records: %s\n", llstr(info->state->records,llbuff));
if (sort_info.dupp)
_ma_check_print_warning(param,
"%s records have been removed",
llstr(sort_info.dupp,llbuff));
}
if (sort_info.dupp)
_ma_check_print_warning(param,
"%s records have been removed",
llstr(sort_info.dupp,llbuff));
got_error=0;
if (&share->state.state != info->state)
@ -3953,11 +3983,12 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
if (sort_param[0].fix_datafile)
{
/*
Append some nuls to the end of a memory mapped file. Destroy the
Append some nulls to the end of a memory mapped file. Destroy the
write cache. The master thread did already detach from the share
by remove_io_thread() in sort.c:thr_find_all_keys().
*/
if (maria_write_data_suffix(&sort_info,1) || end_io_cache(&info->rec_cache))
if (maria_write_data_suffix(&sort_info,1) ||
end_io_cache(&info->rec_cache))
goto err;
if (param->testflag & T_SAFE_REPAIR)
{
@ -4013,17 +4044,18 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
if (my_chsize(share->kfile.file, info->state->key_file_length, 0, MYF(0)))
_ma_check_print_warning(param,
"Can't change size of indexfile, error: %d", my_errno);
"Can't change size of indexfile, error: %d",
my_errno);
if (!(param->testflag & T_SILENT))
{
if (start_records != info->state->records)
printf("Data records: %s\n", llstr(info->state->records,llbuff));
if (sort_info.dupp)
_ma_check_print_warning(param,
"%s records have been removed",
llstr(sort_info.dupp,llbuff));
}
if (sort_info.dupp)
_ma_check_print_warning(param,
"%s records have been removed",
llstr(sort_info.dupp,llbuff));
got_error=0;
if (&share->state.state != info->state)
@ -5121,7 +5153,7 @@ static int sort_insert_key(MARIA_SORT_PARAM *sort_param,
a_length+=t_length;
_ma_store_page_used(share, anc_buff, a_length);
key_block->end_pos+=t_length;
if (a_length <= keyinfo->block_length)
if (a_length <= (uint) (keyinfo->block_length - KEYPAGE_CHECKSUM_SIZE))
{
VOID(_ma_move_key(keyinfo, key_block->lastkey, key));
key_block->last_length=a_length-t_length;
@ -5196,37 +5228,40 @@ static int sort_delete_record(MARIA_SORT_PARAM *sort_param)
old_file= row_info->dfile.file;
/* This only affects static and dynamic row formats */
row_info->dfile.file= row_info->rec_cache.file;
if (sort_info->current_key)
{
key= key_info->lastkey + key_info->s->base.max_key_length;
if ((error=(*row_info->s->read_record)(row_info, sort_param->record,
key_info->cur_row.lastpos)) &&
if (flush_io_cache(&row_info->rec_cache))
DBUG_RETURN(1);
key= key_info->lastkey + key_info->s->base.max_key_length;
if ((error=(*row_info->s->read_record)(row_info, sort_param->record,
key_info->cur_row.lastpos)) &&
error != HA_ERR_RECORD_DELETED)
{
_ma_check_print_error(param,"Can't read record to be removed");
row_info->dfile.file= old_file;
DBUG_RETURN(1);
}
row_info->cur_row.lastpos= key_info->cur_row.lastpos;
for (i=0 ; i < sort_info->current_key ; i++)
{
uint key_length= _ma_make_key(key_info, i, key, sort_param->record,
key_info->cur_row.lastpos);
if (_ma_ck_delete(key_info, i, key, key_length))
{
_ma_check_print_error(param,"Can't read record to be removed");
_ma_check_print_error(param,
"Can't delete key %d from record to be removed",
i+1);
row_info->dfile.file= old_file;
DBUG_RETURN(1);
}
for (i=0 ; i < sort_info->current_key ; i++)
{
uint key_length= _ma_make_key(key_info, i, key, sort_param->record,
key_info->cur_row.lastpos);
if (_ma_ck_delete(key_info, i, key, key_length))
{
_ma_check_print_error(param,
"Can't delete key %d from record to be removed",
i+1);
row_info->dfile.file= old_file;
DBUG_RETURN(1);
}
}
if (sort_param->calc_checksum)
param->glob_crc-=(*key_info->s->calc_check_checksum)(key_info,
sort_param->record);
}
error= (flush_io_cache(&row_info->rec_cache) ||
(*row_info->s->delete_record)(row_info, sort_param->record));
if (sort_param->calc_checksum)
param->glob_crc-=(*key_info->s->calc_check_checksum)(key_info,
sort_param->record);
error= (*row_info->s->delete_record)(row_info, sort_param->record);
if (error)
_ma_check_print_error(param,"Got error %d when deleting record",
my_errno);
row_info->dfile.file= old_file; /* restore actual value */
row_info->state->records--;
DBUG_RETURN(error);
@ -6024,7 +6059,7 @@ static int _ma_safe_scan_block_record(MARIA_SORT_INFO *sort_info,
if (info->scan.dir < info->scan.dir_end)
{
_ma_check_print_info(sort_info->param,
"Wrong directory on page: %s",
"Wrong directory on page %s",
llstr(page, llbuff));
goto read_next_page;
}
@ -6075,8 +6110,8 @@ read_next_page:
if (my_errno == HA_ERR_WRONG_CRC)
{
_ma_check_print_info(sort_info->param,
"Wrong CRC on page at %s",
llstr(page * share->block_size, llbuff));
"Wrong CRC on datapage at %s",
llstr(page, llbuff));
continue;
}
DBUG_RETURN(my_errno);
@ -6089,15 +6124,14 @@ read_next_page:
(uint) (uchar) info->scan.page_buff[DIR_COUNT_OFFSET]) != 0)
break;
_ma_check_print_info(sort_info->param,
"Wrong head page at %s",
llstr(page * share->block_size, llbuff));
"Wrong head page at page %s",
llstr(page, llbuff));
}
else if (page_type >= MAX_PAGE_TYPE)
{
_ma_check_print_info(sort_info->param,
"Found wrong page type: %d at %s",
page_type, llstr(page * share->block_size,
llbuff));
"Found wrong page type: %d at page %s",
page_type, llstr(page, llbuff));
}
}
@ -6199,17 +6233,19 @@ static int write_log_record_for_repair(const HA_CHECK *param, MARIA_HA *info)
/* Give error message why reading of key page failed */
static void report_keypage_fault(HA_CHECK *param, my_off_t position)
static void report_keypage_fault(HA_CHECK *param, MARIA_HA *info,
my_off_t position)
{
char buff[11];
uint32 block_size= info->s->block_size;
if (my_errno == HA_ERR_CRASHED)
_ma_check_print_error(param,
"Wrong base information on indexpage at filepos: %s",
llstr(position, buff));
"Wrong base information on indexpage at page: %s",
llstr(position / block_size, buff));
else
_ma_check_print_error(param,
"Can't read indexpage from filepos: %s, "
"Can't read indexpage from page: %s, "
"error: %d",
llstr(position,buff), my_errno);
llstr(position / block_size, buff), my_errno);
}

View file

@ -150,7 +150,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
if (datafile_type == BLOCK_RECORD)
{
if (type == FIELD_SKIP_PRESPACE)
type= FIELD_NORMAL; /* SKIP_PRESPACE not supported */
type= column->type= FIELD_NORMAL; /* SKIP_PRESPACE not supported */
if (type == FIELD_NORMAL &&
column->length > FULL_PAGE_SIZE(maria_block_size))
{
@ -297,15 +297,17 @@ int maria_create(const char *name, enum data_file_type datafile_type,
share.base.max_field_lengths= max_field_lengths;
share.base.field_offsets= 0; /* for future */
if (pack_reclength != INT_MAX32)
pack_reclength+= max_field_lengths + long_varchar_count;
if (flags & HA_CREATE_CHECKSUM || (options & HA_OPTION_CHECKSUM))
{
options|= HA_OPTION_CHECKSUM;
min_pack_length++;
pack_reclength++;
}
if (pack_reclength < INT_MAX32)
pack_reclength+= max_field_lengths + long_varchar_count;
else
pack_reclength= INT_MAX32;
if (flags & HA_CREATE_DELAY_KEY_WRITE)
options|= HA_OPTION_DELAY_KEY_WRITE;
if (flags & HA_CREATE_RELIES_ON_SQL_LAYER)
@ -741,6 +743,13 @@ int maria_create(const char *name, enum data_file_type datafile_type,
/* Add length of packed fields + length */
share.base.pack_reclength+= share.base.max_field_lengths+3;
/* Adjust max_pack_length, to be used if we have short rows */
if (share.base.max_pack_length < maria_block_size)
{
share.base.max_pack_length+= FLAG_SIZE;
if (ci->transactional)
share.base.max_pack_length+= TRANSID_SIZE * 2;
}
}
/* max_data_file_length and max_key_file_length are recalculated on open */
@ -1208,7 +1217,8 @@ uint maria_get_pointer_length(ulonglong file_length, uint def)
Fixed size, not null columns
Fixed length, null fields
Variable length fields (CHAR, VARCHAR)
Numbers (zero fill fields)
Variable length fields (CHAR, VARCHAR) according to length
Blobs
For same kind of fields, keep fields in original order
@ -1225,10 +1235,8 @@ static int compare_columns(MARIA_COLUMNDEF **a_ptr, MARIA_COLUMNDEF **b_ptr)
MARIA_COLUMNDEF *a= *a_ptr, *b= *b_ptr;
enum en_fieldtype a_type, b_type;
a_type= ((a->type == FIELD_NORMAL || a->type == FIELD_CHECK) ?
FIELD_NORMAL : a->type);
b_type= ((b->type == FIELD_NORMAL || b->type == FIELD_CHECK) ?
FIELD_NORMAL : b->type);
a_type= (a->type == FIELD_CHECK) ? FIELD_NORMAL : a->type;
b_type= (b->type == FIELD_CHECK) ? FIELD_NORMAL : b->type;
if (a_type == FIELD_NORMAL && !a->null_bit)
{
@ -1244,6 +1252,13 @@ static int compare_columns(MARIA_COLUMNDEF **a_ptr, MARIA_COLUMNDEF **b_ptr)
return -1;
if (b_type == FIELD_NORMAL)
return 1;
if (a_type == FIELD_SKIP_ZERO)
return -1;
if (b_type == FIELD_SKIP_ZERO)
return 1;
if (a->type != FIELD_BLOB && b->type != FIELD_BLOB)
if (a->length != b->length)
return sign((long) a->length - (long) b->length);
if (a_type == FIELD_BLOB)
return 1;
if (b_type == FIELD_BLOB)

View file

@ -130,7 +130,11 @@ int maria_delete(MARIA_HA *info,const uchar *record)
DBUG_RETURN(0);
err:
save_errno=my_errno;
save_errno= my_errno;
DBUG_ASSERT(save_errno);
if (!save_errno)
save_errno= HA_ERR_INTERNAL_ERROR; /* Should never happen */
mi_sizestore(lastpos, info->cur_row.lastpos);
if (save_errno != HA_ERR_RECORD_CHANGED)
{
@ -140,14 +144,12 @@ err:
VOID(_ma_writeinfo(info,WRITEINFO_UPDATE_KEYFILE));
info->update|=HA_STATE_WRITTEN; /* Buffer changed */
allow_break(); /* Allow SIGHUP & SIGINT */
my_errno=save_errno;
if (save_errno == HA_ERR_KEY_NOT_FOUND)
{
maria_print_error(share, HA_ERR_CRASHED);
my_errno=HA_ERR_CRASHED;
}
DBUG_RETURN(my_errno);
DBUG_RETURN(my_errno= save_errno);
} /* maria_delete */

View file

@ -1301,7 +1301,8 @@ ulong _ma_calc_total_blob_length(MARIA_HA *info, const uchar *record)
blob != end;
blob++)
{
blob->length= _ma_calc_blob_length(blob->pack_length,record + blob->offset);
blob->length= _ma_calc_blob_length(blob->pack_length,
record + blob->offset);
length+=blob->length;
}
return length;

View file

@ -589,6 +589,7 @@ int _ma_decrement_open_count(MARIA_HA *info)
if (share->state.open_count > 0)
{
share->state.open_count--;
share->changed= 1; /* We have to update state */
if (!(share->temporary | share->base.born_transactional))
{
mi_int2store(buff,share->state.open_count);

View file

@ -287,7 +287,6 @@ enum enum_translog_status translog_status= TRANSLOG_UNINITED;
#define TRANSLOG_CLSN_LEN_BITS 0xC0 /* Mask to get compressed LSN length */
#include <my_atomic.h>
/* an array that maps id of a MARIA_SHARE to this MARIA_SHARE */
static MARIA_SHARE **id_to_share= NULL;
@ -715,10 +714,14 @@ static void translog_check_cursor(struct st_buffer_cursor *cursor
void translog_stop_writing()
{
DBUG_ENTER("translog_stop_writing");
DBUG_PRINT("error", ("errno: %d my_errno: %d", errno, my_errno));
translog_status= (translog_status == TRANSLOG_SHUTDOWN ?
TRANSLOG_UNINITED :
TRANSLOG_READONLY);
log_descriptor.open_flags= O_BINARY | O_RDONLY;
DBUG_ASSERT(0);
DBUG_VOID_RETURN;
}
@ -1165,7 +1168,6 @@ end:
}
/*
@brief remove file mark "in progress" (for multi-group records)
@ -2238,7 +2240,6 @@ static my_bool translog_buffer_flush(struct st_translog_buffer *buffer)
(ulong) buffer->size));
translog_buffer_lock_assert_owner(buffer);
translog_wait_for_writers(buffer);
if (buffer->overlay && buffer->overlay->file == buffer->file &&
@ -2299,9 +2300,11 @@ static my_bool translog_buffer_flush(struct st_translog_buffer *buffer)
PAGECACHE_PIN_LEFT_UNPINNED, 0,
LSN_IMPOSSIBLE))
{
DBUG_PRINT("error", ("Can't write page (%lu,0x%lx) to pagecache",
(ulong) buffer->file,
(ulong) (LSN_OFFSET(buffer->offset)+ i)));
DBUG_PRINT("error",
("Can't write page (%lu,0x%lx) to pagecache, error: %d",
(ulong) buffer->file,
(ulong) (LSN_OFFSET(buffer->offset)+ i),
my_errno));
translog_stop_writing();
DBUG_RETURN(1);
}
@ -2489,7 +2492,6 @@ translog_check_sector_protection(uchar *page, TRANSLOG_FILE *file)
@param page_no The page number (<offset>/<page length>)
@param data_ptr Read callback data pointer (pointer to TRANSLOG_FILE)
@todo: add turning loghandler to read-only mode after merging with
that patch.
@ -4021,7 +4023,6 @@ translog_buffer_increase_writers(struct st_translog_buffer *buffer)
buffer target buffer
*/
static void translog_buffer_decrease_writers(struct st_translog_buffer *buffer)
{
DBUG_ENTER("translog_buffer_decrease_writers");
@ -4157,7 +4158,7 @@ translog_write_variable_record_chunk3_page(struct st_translog_parts *parts,
1 Error
*/
static my_bool translog_advance_pointer(uint pages, uint16 last_page_data)
static my_bool translog_advance_pointer(int pages, uint16 last_page_data)
{
translog_size_t last_page_offset= (log_descriptor.page_overhead +
last_page_data);
@ -4174,6 +4175,21 @@ static my_bool translog_advance_pointer(uint pages, uint16 last_page_data)
(uint) last_page_data));
translog_lock_assert_owner();
if (pages == -1)
{
/*
It is special case when we advance the pointer on the same page.
It can happened when we write last part of multi-group record.
*/
DBUG_ASSERT(last_page_data + log_descriptor.bc.current_page_fill <=
TRANSLOG_PAGE_SIZE);
offset= last_page_data;
last_page_offset= log_descriptor.bc.current_page_fill + last_page_data;
goto end;
}
DBUG_PRINT("info", ("last_page_offset %lu", (ulong) last_page_offset));
DBUG_ASSERT(last_page_offset <= TRANSLOG_PAGE_SIZE);
/*
The loop will be executed 1-3 times. Usually we advance the
pointer to fill only the current buffer (if we have more then 1/2 of
@ -4258,14 +4274,15 @@ static my_bool translog_advance_pointer(uint pages, uint16 last_page_data)
DBUG_RETURN(1);
offset-= min_offset;
}
DBUG_PRINT("info", ("drop write_counter"));
log_descriptor.bc.write_counter= 0;
log_descriptor.bc.previous_offset= 0;
end:
log_descriptor.bc.ptr+= offset;
log_descriptor.bc.buffer->size+= offset;
translog_buffer_increase_writers(log_descriptor.bc.buffer);
log_descriptor.horizon+= offset; /* offset increasing */
log_descriptor.bc.current_page_fill= last_page_offset;
DBUG_PRINT("info", ("drop write_counter"));
log_descriptor.bc.write_counter= 0;
log_descriptor.bc.previous_offset= 0;
DBUG_PRINT("info", ("NewP buffer #%u: 0x%lx chaser: %d Size: %lu (%lu) "
"offset: %u last page: %u",
(uint) log_descriptor.bc.buffer->buffer_no,
@ -4285,7 +4302,6 @@ static my_bool translog_advance_pointer(uint pages, uint16 last_page_data)
}
/*
Get page rest
@ -4435,7 +4451,7 @@ translog_write_variable_record_1group(LSN *lsn,
(log_descriptor.page_capacity_chunk_2 - 1),
record_rest, parts->record_length));
/* record_rest + 3 is chunk type 3 overhead + record_rest */
rc|= translog_advance_pointer(full_pages + additional_chunk3_page,
rc|= translog_advance_pointer((int)(full_pages + additional_chunk3_page),
(record_rest ? record_rest + 3 : 0));
log_descriptor.bc.buffer->last_lsn= *lsn;
@ -4460,7 +4476,6 @@ translog_write_variable_record_1group(LSN *lsn,
/* fill the pages */
translog_write_parts_on_page(&horizon, &cursor, first_page, parts);
DBUG_PRINT("info", ("absolute horizon: (%lu,0x%lx) local: (%lu,0x%lx)",
LSN_IN_PARTS(log_descriptor.horizon),
LSN_IN_PARTS(horizon)));
@ -4959,7 +4974,7 @@ translog_write_variable_record_mgroup(LSN *lsn,
(ulong)(parts->record_length - (first_page - 1 +
buffer_rest) -
done)));
rc|= translog_advance_pointer(full_pages, 0);
rc|= translog_advance_pointer((int)full_pages, 0);
rc|= translog_unlock();
@ -5104,8 +5119,10 @@ translog_write_variable_record_mgroup(LSN *lsn,
(ulong) full_pages *
log_descriptor.page_capacity_chunk_2,
chunk3_pages, (uint) chunk3_size, (uint) record_rest));
rc= translog_advance_pointer(full_pages + chunk3_pages +
(chunk0_pages - 1),
rc= translog_advance_pointer((int)(full_pages + chunk3_pages +
(chunk0_pages - 1)) +
(full_pages + chunk3_pages + chunk0_pages +
chunk2_page == 1? -1 : 0),
record_rest + header_fixed_part +
(groups.elements -
((page_capacity -
@ -5573,7 +5590,6 @@ my_bool translog_write_record(LSN *lsn,
DBUG_RETURN(1);
}
if (tbl_info)
{
MARIA_SHARE *share= tbl_info->s;
@ -7526,7 +7542,7 @@ my_bool translog_purge_at_flush()
if (unlikely(translog_status == TRANSLOG_READONLY))
{
DBUG_PRINT("info", ("The log is read onlyu => exit"));
DBUG_PRINT("info", ("The log is read only => exit"));
DBUG_RETURN(0);
}
@ -7639,4 +7655,3 @@ void translog_set_file_size(uint32 size)
}
DBUG_VOID_RETURN;
}

View file

@ -685,7 +685,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
disk_pos=_ma_columndef_read(disk_pos,&share->columndef[i]);
share->columndef[i].pack_type=0;
share->columndef[i].huff_tree=0;
if (share->columndef[i].type == (int) FIELD_BLOB)
if (share->columndef[i].type == FIELD_BLOB)
{
share->blobs[j].pack_length=
share->columndef[i].length-portable_sizeof_char_ptr;;
@ -693,7 +693,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
j++;
}
}
share->columndef[i].type=(int) FIELD_LAST; /* End marker */
share->columndef[i].type= FIELD_LAST; /* End marker */
disk_pos= _ma_column_nr_read(disk_pos, share->column_nr,
share->base.fields);

View file

@ -145,7 +145,8 @@ int _ma_write_keypage(register MARIA_HA *info,
lock,
lock == PAGECACHE_LOCK_LEFT_WRITELOCKED ?
PAGECACHE_PIN_LEFT_PINNED :
PAGECACHE_PIN,
(lock == PAGECACHE_LOCK_WRITE_UNLOCK ?
PAGECACHE_UNPIN : PAGECACHE_PIN),
PAGECACHE_WRITE_DELAY, &page_link.link,
LSN_IMPOSSIBLE);
@ -157,8 +158,7 @@ int _ma_write_keypage(register MARIA_HA *info,
push_dynamic(&info->pinned_pages, (void*) &page_link);
}
DBUG_RETURN(res);
} /* maria_write_keypage */
}
/*
@ -326,7 +326,11 @@ my_off_t _ma_new(register MARIA_HA *info, int level,
(*page_link)->unlock= PAGECACHE_LOCK_WRITE_UNLOCK;
(*page_link)->write_lock= PAGECACHE_LOCK_WRITE;
(*page_link)->changed= 0;
/*
We have to mark it changed as _ma_flush_pending_blocks() uses
'changed' to know if we used the page cache or not
*/
(*page_link)->changed= 1;
push_dynamic(&info->pinned_pages, (void*) *page_link);
*page_link= dynamic_element(&info->pinned_pages,
info->pinned_pages.elements-1,

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2000-2006 MySQL AB
/* Copyright (C) 2000-2008 MySQL AB
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
@ -2053,9 +2053,11 @@ restart:
link_to_file_list(pagecache, block, file,
(my_bool)(block->hash_link ? 1 : 0));
PCBLOCK_INFO(block);
block->status= error? PCBLOCK_ERROR : 0;
block->status= error ? PCBLOCK_ERROR : 0;
#ifndef DBUG_OFF
block->type= PAGECACHE_EMPTY_PAGE;
if (error)
my_debug_put_break_here();
#endif
block->hash_link= hash_link;
page_status= PAGE_TO_BE_READ;
@ -2239,8 +2241,8 @@ static my_bool get_wrlock(PAGECACHE *pagecache,
file.file != block->hash_link->file.file ||
pageno != block->hash_link->pageno)
{
DBUG_PRINT("info", ("the block 0x%lx changed => need retry"
"status %x files %d != %d or pages %d !=%d",
DBUG_PRINT("info", ("the block 0x%lx changed => need retry "
"status: %x files %d != %d or pages %d != %d",
(ulong)block, block->status,
file.file, block->hash_link->file.file,
pageno, block->hash_link->pageno));
@ -2446,7 +2448,10 @@ static void read_block(PAGECACHE *pagecache,
pagecache->readwrite_flags);
pagecache_pthread_mutex_lock(&pagecache->cache_lock);
if (error)
{
block->status|= PCBLOCK_ERROR;
my_debug_put_break_here();
}
else
{
block->status|= PCBLOCK_READ;
@ -2457,6 +2462,7 @@ static void read_block(PAGECACHE *pagecache,
{
DBUG_PRINT("error", ("read callback problem"));
block->status|= PCBLOCK_ERROR;
my_debug_put_break_here();
}
}
DBUG_PRINT("read_block",
@ -2608,6 +2614,7 @@ void pagecache_unlock(PAGECACHE *pagecache,
/* if we lock for write we must link the block to changed blocks */
DBUG_ASSERT((block->status & PCBLOCK_DIRECT_W) == 0 ||
(lock == PAGECACHE_LOCK_WRITE_UNLOCK ||
lock == PAGECACHE_LOCK_WRITE_TO_READ ||
lock == PAGECACHE_LOCK_LEFT_WRITELOCKED));
/*
if was_changed then status should be PCBLOCK_DIRECT_W or marked
@ -2616,7 +2623,8 @@ void pagecache_unlock(PAGECACHE *pagecache,
DBUG_ASSERT(!was_changed || (block->status & PCBLOCK_DIRECT_W) ||
(block->status & PCBLOCK_CHANGED));
if ((block->status & PCBLOCK_DIRECT_W) &&
(lock == PAGECACHE_LOCK_WRITE_UNLOCK))
(lock == PAGECACHE_LOCK_WRITE_UNLOCK ||
lock == PAGECACHE_LOCK_WRITE_TO_READ))
{
if (!(block->status & PCBLOCK_CHANGED) && was_changed)
link_to_changed_list(pagecache, block);
@ -2737,7 +2745,7 @@ void pagecache_unlock_by_link(PAGECACHE *pagecache,
LSN lsn, my_bool was_changed)
{
DBUG_ENTER("pagecache_unlock_by_link");
DBUG_PRINT("enter", ("block: 0x%lx fd: %u page: %lu changed: %d %s %s",
DBUG_PRINT("enter", ("block: 0x%lx fd: %u page: %lu changed: %d %s %s",
(ulong) block,
(uint) block->hash_link->file.file,
(ulong) block->hash_link->pageno, was_changed,
@ -2790,6 +2798,7 @@ void pagecache_unlock_by_link(PAGECACHE *pagecache,
/* if we lock for write we must link the block to changed blocks */
DBUG_ASSERT((block->status & PCBLOCK_DIRECT_W) == 0 ||
(lock == PAGECACHE_LOCK_WRITE_UNLOCK ||
lock == PAGECACHE_LOCK_WRITE_TO_READ ||
lock == PAGECACHE_LOCK_LEFT_WRITELOCKED));
/*
If was_changed then status should be PCBLOCK_DIRECT_W or marked
@ -2798,7 +2807,8 @@ void pagecache_unlock_by_link(PAGECACHE *pagecache,
DBUG_ASSERT(!was_changed || (block->status & PCBLOCK_DIRECT_W) ||
(block->status & PCBLOCK_CHANGED));
if ((block->status & PCBLOCK_DIRECT_W) &&
(lock == PAGECACHE_LOCK_WRITE_UNLOCK))
(lock == PAGECACHE_LOCK_WRITE_UNLOCK ||
lock == PAGECACHE_LOCK_WRITE_TO_READ))
{
if (!(block->status & PCBLOCK_CHANGED) && was_changed)
link_to_changed_list(pagecache, block);
@ -2844,7 +2854,7 @@ void pagecache_unpin_by_link(PAGECACHE *pagecache,
LSN lsn)
{
DBUG_ENTER("pagecache_unpin_by_link");
DBUG_PRINT("enter", ("block: 0x%lx fd: %u page: %lu",
DBUG_PRINT("enter", ("block: 0x%lx fd: %u page: %lu",
(ulong) block,
(uint) block->hash_link->file.file,
(ulong) block->hash_link->pageno));
@ -3177,6 +3187,7 @@ restart:
if (error)
{
block->status|= PCBLOCK_ERROR;
my_debug_put_break_here();
goto err;
}
}
@ -3407,6 +3418,7 @@ restart:
{
if (block->status & PCBLOCK_ERROR)
{
my_debug_put_break_here();
DBUG_PRINT("warning", ("Writing on page with error"));
}
else
@ -3431,6 +3443,7 @@ restart:
{
DBUG_PRINT("error", ("read callback problem"));
block->status|= PCBLOCK_ERROR;
my_debug_put_break_here();
}
KEYCACHE_DBUG_PRINT("key_cache_insert",
("Page injection"));
@ -3488,7 +3501,10 @@ restart:
*page_link= block;
if (block->status & PCBLOCK_ERROR)
{
error= 1;
my_debug_put_break_here();
}
dec_counter_for_resize_op(pagecache);
@ -3692,6 +3708,7 @@ static int flush_cached_blocks(PAGECACHE *pagecache,
if (error)
{
block->status|= PCBLOCK_ERROR;
my_debug_put_break_here();
if (!*first_errno)
*first_errno= my_errno ? my_errno : -1;
rc|= PCFLUSH_ERROR;
@ -3930,7 +3947,7 @@ restart:
*/
if ((rc|= flush_cached_blocks(pagecache, file, cache,
end, type, &error)) &
PCFLUSH_ERROR)
(PCFLUSH_ERROR | PCFLUSH_PINNED))
last_errno=error;
DBUG_PRINT("info", ("restarting..."));
/*
@ -3965,7 +3982,8 @@ restart:
if (pos != cache)
{
if ((rc|= flush_cached_blocks(pagecache, file, cache, pos, type,
&error)) & PCFLUSH_ERROR)
&error)) &
(PCFLUSH_ERROR | PCFLUSH_PINNED))
last_errno= error;
}
/* Wait until list of blocks in switch is empty */

View file

@ -13,7 +13,7 @@
@return crc of the page without special values
*/
static uint32 maria_page_crc(ulong start, uchar *data, uint length)
static uint32 maria_page_crc(uint32 start, uchar *data, uint length)
{
uint32 crc= crc32(start, data, length);
@ -73,7 +73,7 @@ static my_bool maria_page_crc_check(uchar *page,
}
DBUG_RETURN(0);
}
new_crc= maria_page_crc(page_no, page, data_length);
new_crc= maria_page_crc(page_no & UINT_MAX32, page, data_length);
DBUG_ASSERT(new_crc != no_crc_val);
res= test(new_crc != crc);
if (res)
@ -103,7 +103,7 @@ my_bool maria_page_crc_set_normal(uchar *page,
{
MARIA_SHARE *share= (MARIA_SHARE *)data_ptr;
int data_length= share->block_size - CRC_SIZE;
uint32 crc= maria_page_crc(page_no, page, data_length);
uint32 crc= maria_page_crc(page_no & UINT_MAX32, page, data_length);
DBUG_ENTER("maria_page_crc_set");
DBUG_PRINT("info", ("Page %lu crc: %lu", (ulong) page_no, (ulong)crc));
@ -129,9 +129,8 @@ my_bool maria_page_crc_set_index(uchar *page,
{
MARIA_SHARE *share= (MARIA_SHARE *)data_ptr;
int data_length= _ma_get_page_used(share, page);
uint32 crc= maria_page_crc(page_no, page, data_length);
uint32 crc= maria_page_crc(page_no & UINT_MAX32, page, data_length);
DBUG_ENTER("maria_page_crc_set");
DBUG_PRINT("info", ("Page %lu crc: %lu",
(ulong) page_no, (ulong) crc));
DBUG_ASSERT((uint)data_length <= share->block_size - CRC_SIZE);
@ -160,7 +159,7 @@ my_bool maria_page_crc_check_data(uchar *page,
uchar *data_ptr)
{
MARIA_SHARE *share= (MARIA_SHARE *)data_ptr;
return (maria_page_crc_check(page, page_no, share,
return (maria_page_crc_check(page, page_no & UINT_MAX32, share,
MARIA_NO_CRC_NORMAL_PAGE,
share->block_size - CRC_SIZE));
}
@ -182,7 +181,7 @@ my_bool maria_page_crc_check_bitmap(uchar *page,
uchar *data_ptr)
{
MARIA_SHARE *share= (MARIA_SHARE *)data_ptr;
return (maria_page_crc_check(page, page_no, share,
return (maria_page_crc_check(page, page_no & UINT_MAX32, share,
MARIA_NO_CRC_BITMAP_PAGE,
share->block_size - CRC_SIZE));
}
@ -210,7 +209,7 @@ my_bool maria_page_crc_check_index(uchar *page,
DBUG_PRINT("error", ("Wrong page length: %u", length));
return (my_errno= HA_ERR_WRONG_CRC);
}
return maria_page_crc_check(page, page_no, share,
return maria_page_crc_check(page, page_no & UINT_MAX32, share,
MARIA_NO_CRC_NORMAL_PAGE,
length);
}

View file

@ -174,7 +174,7 @@ void tprint(FILE *trace_file __attribute__ ((unused)),
if (procent_printed)
{
procent_printed= 0;
fputc('\n', trace_file ? trace_file : stderr);
fputc('\n', trace_file);
}
vfprintf(trace_file, format, args);
}
@ -190,13 +190,22 @@ void eprint(FILE *trace_file __attribute__ ((unused)),
va_list args;
va_start(args, format);
DBUG_PRINT("error", ("%s", format));
if (!trace_file)
trace_file= stderr;
if (procent_printed)
{
/* In silent mode, print on another line than the 0% 10% 20% line */
procent_printed= 0;
fputc('\n', trace_file ? trace_file : stderr);
fputc('\n', trace_file);
}
vfprintf(trace_file , format, args);
fputc('\n', trace_file);
if (trace_file != stderr)
{
va_start(args, format);
my_printv_error(HA_ERR_INITIALIZATION, format, MYF(0), args);
}
vfprintf(trace_file ? trace_file : stderr, format, args);
va_end(args);
}
@ -411,7 +420,7 @@ int maria_apply_log(LSN from_lsn, enum maria_apply_log_way apply,
else if (uncommitted_trans > 0)
{
eprint(tracef, "***WARNING: %u uncommitted transactions; some tables may"
" be left inconsistent!***\n", uncommitted_trans);
" be left inconsistent!***", uncommitted_trans);
recovery_warnings++;
}
@ -517,7 +526,7 @@ static int display_and_apply_record(const LOG_DESC *log_desc,
return 1;
}
if ((error= (*log_desc->record_execute_in_redo_phase)(rec)))
eprint(tracef, "Got error %d when executing record %s\n",
eprint(tracef, "Got error %d when executing record %s",
my_errno, log_desc->name);
return error;
}
@ -548,7 +557,7 @@ prototype_redo_exec_hook(LONG_TRANSACTION_ID)
llstr(long_trid, llbuf);
eprint(tracef, "Found an old transaction long_trid %s short_trid %u"
" with same short id as this new transaction, and has neither"
" committed nor rollback (undo_lsn: (%lu,0x%lx))\n",
" committed nor rollback (undo_lsn: (%lu,0x%lx))",
llbuf, sid, LSN_IN_PARTS(ulsn));
goto err;
}
@ -656,7 +665,7 @@ prototype_redo_exec_hook(REDO_CREATE_TABLE)
log_record_buffer.str, NULL) !=
rec->record_length)
{
eprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record");
goto end;
}
name= (char *)log_record_buffer.str;
@ -667,7 +676,7 @@ prototype_redo_exec_hook(REDO_CREATE_TABLE)
*/
if (close_one_table(name, rec->lsn))
{
eprint(tracef, "Table '%s' got error %d on close\n", name, my_errno);
eprint(tracef, "Table '%s' got error %d on close", name, my_errno);
ALERT_USER();
goto end;
}
@ -679,7 +688,7 @@ prototype_redo_exec_hook(REDO_CREATE_TABLE)
/* check that we're not already using it */
if (share->reopen != 1)
{
eprint(tracef, "Table '%s is already open (reopen=%u)\n",
eprint(tracef, "Table '%s is already open (reopen=%u)",
name, share->reopen);
ALERT_USER();
goto end;
@ -708,7 +717,7 @@ prototype_redo_exec_hook(REDO_CREATE_TABLE)
}
if (maria_is_crashed(info))
{
eprint(tracef, "Table '%s' is crashed, can't recreate it\n", name);
eprint(tracef, "Table '%s' is crashed, can't recreate it", name);
ALERT_USER();
goto end;
}
@ -743,7 +752,7 @@ prototype_redo_exec_hook(REDO_CREATE_TABLE)
/** @todo handle symlinks */
if (data_file_name[0] || index_file_name[0])
{
eprint(tracef, "Table '%s' DATA|INDEX DIRECTORY clauses are not handled\n",
eprint(tracef, "Table '%s' DATA|INDEX DIRECTORY clauses are not handled",
name);
goto end;
}
@ -757,14 +766,14 @@ prototype_redo_exec_hook(REDO_CREATE_TABLE)
if ((kfile= my_create_with_symlink(linkname_ptr, filename, 0, create_mode,
MYF(MY_WME|create_flag))) < 0)
{
eprint(tracef, "Failed to create index file\n");
eprint(tracef, "Failed to create index file");
goto end;
}
if (my_pwrite(kfile, kfile_header,
kfile_size_before_extension, 0, MYF(MY_NABP|MY_WME)) ||
my_chsize(kfile, keystart, 0, MYF(MY_WME)))
{
eprint(tracef, "Failed to write to index file\n");
eprint(tracef, "Failed to write to index file");
goto end;
}
if (!(flags & HA_DONT_TOUCH_DATA))
@ -778,7 +787,7 @@ prototype_redo_exec_hook(REDO_CREATE_TABLE)
MYF(MY_WME | create_flag))) < 0) ||
my_close(dfile, MYF(MY_WME)))
{
eprint(tracef, "Failed to create data file\n");
eprint(tracef, "Failed to create data file");
goto end;
}
/*
@ -790,7 +799,7 @@ prototype_redo_exec_hook(REDO_CREATE_TABLE)
if (((info= maria_open(name, O_RDONLY, 0)) == NULL) ||
_ma_initialize_data_file(info->s, info->dfile.file))
{
eprint(tracef, "Failed to open new table or write to data file\n");
eprint(tracef, "Failed to open new table or write to data file");
goto end;
}
}
@ -820,7 +829,7 @@ prototype_redo_exec_hook(REDO_RENAME_TABLE)
log_record_buffer.str, NULL) !=
rec->record_length)
{
eprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record");
goto end;
}
old_name= (char *)log_record_buffer.str;
@ -957,13 +966,13 @@ prototype_redo_exec_hook(REDO_RENAME_TABLE)
tprint(tracef, ", renaming '%s'", old_name);
if (maria_rename(old_name, new_name))
{
eprint(tracef, "Failed to rename table\n");
eprint(tracef, "Failed to rename table");
goto end;
}
info= maria_open(new_name, O_RDONLY, 0);
if (info == NULL)
{
eprint(tracef, "Failed to open renamed table\n");
eprint(tracef, "Failed to open renamed table");
goto end;
}
if (_ma_update_create_rename_lsn(info->s, rec->lsn, TRUE))
@ -977,7 +986,7 @@ drop:
tprint(tracef, ", only dropping '%s'", old_name);
if (maria_delete_table(old_name))
{
eprint(tracef, "Failed to drop table\n");
eprint(tracef, "Failed to drop table");
goto end;
}
error= 0;
@ -1068,7 +1077,7 @@ prototype_redo_exec_hook(REDO_DROP_TABLE)
log_record_buffer.str, NULL) !=
rec->record_length)
{
eprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record");
return 1;
}
name= (char *)log_record_buffer.str;
@ -1106,7 +1115,7 @@ prototype_redo_exec_hook(REDO_DROP_TABLE)
tprint(tracef, ", dropping '%s'", name);
if (maria_delete_table(name))
{
eprint(tracef, "Failed to drop table\n");
eprint(tracef, "Failed to drop table");
goto end;
}
}
@ -1147,7 +1156,7 @@ prototype_redo_exec_hook(FILE_ID)
log_record_buffer.str, NULL) !=
rec->record_length)
{
eprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record");
goto end;
}
sid= fileid_korr(log_record_buffer.str);
@ -1158,7 +1167,7 @@ prototype_redo_exec_hook(FILE_ID)
prepare_table_for_close(info, rec->lsn);
if (maria_close(info))
{
eprint(tracef, "Failed to close table\n");
eprint(tracef, "Failed to close table");
goto end;
}
all_tables[sid].info= NULL;
@ -1331,14 +1340,14 @@ prototype_redo_exec_hook(REDO_INSERT_ROW_HEAD)
enlarge_buffer(rec);
if (log_record_buffer.str == NULL)
{
eprint(tracef, "Failed to read allocate buffer for record\n");
eprint(tracef, "Failed to read allocate buffer for record");
goto end;
}
if (translog_read_record(rec->lsn, 0, rec->record_length,
log_record_buffer.str, NULL) !=
rec->record_length)
{
eprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record");
goto end;
}
buff= log_record_buffer.str;
@ -1373,7 +1382,7 @@ prototype_redo_exec_hook(REDO_INSERT_ROW_TAIL)
log_record_buffer.str, NULL) !=
rec->record_length)
{
eprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record");
goto end;
}
buff= log_record_buffer.str;
@ -1409,7 +1418,7 @@ prototype_redo_exec_hook(REDO_INSERT_ROW_BLOBS)
log_record_buffer.str, NULL) !=
rec->record_length)
{
eprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record");
goto end;
}
buff= log_record_buffer.str;
@ -1469,7 +1478,7 @@ prototype_redo_exec_hook(REDO_FREE_BLOCKS)
log_record_buffer.str, NULL) !=
rec->record_length)
{
eprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record");
goto end;
}
@ -1528,7 +1537,7 @@ prototype_redo_exec_hook(REDO_INDEX)
log_record_buffer.str, NULL) !=
rec->record_length)
{
eprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record");
goto end;
}
@ -1554,7 +1563,7 @@ prototype_redo_exec_hook(REDO_INDEX_NEW_PAGE)
log_record_buffer.str, NULL) !=
rec->record_length)
{
eprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record");
goto end;
}
@ -1618,7 +1627,7 @@ prototype_redo_exec_hook(UNDO_ROW_INSERT)
HA_CHECKSUM_STORE_SIZE, buff, NULL) !=
HA_CHECKSUM_STORE_SIZE)
{
eprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record");
return 1;
}
share->state.state.checksum+= ha_checksum_korr(buff);
@ -1655,7 +1664,7 @@ prototype_redo_exec_hook(UNDO_ROW_DELETE)
HA_CHECKSUM_STORE_SIZE, buff, NULL) !=
HA_CHECKSUM_STORE_SIZE)
{
eprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record");
return 1;
}
share->state.state.checksum+= ha_checksum_korr(buff);
@ -1689,7 +1698,7 @@ prototype_redo_exec_hook(UNDO_ROW_UPDATE)
HA_CHECKSUM_STORE_SIZE, buff, NULL) !=
HA_CHECKSUM_STORE_SIZE)
{
eprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record");
return 1;
}
share->state.state.checksum+= ha_checksum_korr(buff);
@ -1729,7 +1738,7 @@ prototype_redo_exec_hook(UNDO_KEY_INSERT)
log_record_buffer.str, NULL) !=
rec->record_length)
{
eprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record");
return 1;
}
to= log_record_buffer.str + LSN_STORE_SIZE + FILEID_STORE_SIZE +
@ -1851,7 +1860,7 @@ prototype_redo_exec_hook(CLR_END)
log_record_buffer.str, NULL) !=
rec->record_length)
{
eprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record");
return 1;
}
logpos= (log_record_buffer.str + LSN_STORE_SIZE + FILEID_STORE_SIZE +
@ -1939,7 +1948,7 @@ prototype_undo_exec_hook(UNDO_ROW_INSERT)
log_record_buffer.str, NULL) !=
rec->record_length)
{
eprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record");
return 1;
}
record_ptr= log_record_buffer.str;
@ -1977,7 +1986,7 @@ prototype_undo_exec_hook(UNDO_ROW_DELETE)
log_record_buffer.str, NULL) !=
rec->record_length)
{
eprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record");
return 1;
}
@ -2013,7 +2022,7 @@ prototype_undo_exec_hook(UNDO_ROW_UPDATE)
log_record_buffer.str, NULL) !=
rec->record_length)
{
eprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record");
return 1;
}
@ -2058,7 +2067,7 @@ prototype_undo_exec_hook(UNDO_KEY_INSERT)
log_record_buffer.str, NULL) !=
rec->record_length)
{
eprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record");
return 1;
}
@ -2104,7 +2113,7 @@ prototype_undo_exec_hook(UNDO_KEY_DELETE)
log_record_buffer.str, NULL) !=
rec->record_length)
{
eprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record");
return 1;
}
@ -2150,7 +2159,7 @@ prototype_undo_exec_hook(UNDO_KEY_DELETE_WITH_ROOT)
log_record_buffer.str, NULL) !=
rec->record_length)
{
eprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record");
return 1;
}
@ -2234,7 +2243,7 @@ static int run_redo_phase(LSN lsn, enum maria_apply_log_way apply)
if (len == RECHEADER_READ_ERROR)
{
eprint(tracef, "Failed to read header of the first record.\n");
eprint(tracef, "Failed to read header of the first record.");
return 1;
}
if (translog_scanner_init(lsn, 1, &scanner, 1))
@ -2530,7 +2539,7 @@ static int run_undo_phase(uint uncommitted)
display_record_position(log_desc, &rec, 0);
if (log_desc->record_execute_in_undo_phase(&rec, trn))
{
eprint(tracef, "Got error %d when executing undo %s\n", my_errno,
eprint(tracef, "Got error %d when executing undo %s", my_errno,
log_desc->name);
DBUG_RETURN(1);
}
@ -2741,7 +2750,7 @@ static LSN parse_checkpoint_record(LSN lsn)
log_record_buffer.str, NULL) !=
rec.record_length)
{
eprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record");
return LSN_ERROR;
}
@ -2999,6 +3008,7 @@ void _ma_tmp_disable_logging_for_table(MARIA_HA *info,
TRANSLOG_INTERNAL_PARTS + 1, log_array,
log_data, NULL);
}
/* if we disabled before writing the record, record wouldn't reach log */
share->now_transactional= FALSE;
/*
@ -3025,6 +3035,10 @@ void _ma_tmp_disable_logging_for_table(MARIA_HA *info,
void _ma_reenable_logging_for_table(MARIA_HA *info)
{
MARIA_SHARE *share= info->s;
if (share->now_transactional == share->base.born_transactional)
return;
if ((share->now_transactional= share->base.born_transactional))
{
/*

View file

@ -196,7 +196,11 @@ int maria_update(register MARIA_HA *info, const uchar *oldrec, uchar *newrec)
err:
DBUG_PRINT("error",("key: %d errno: %d",i,my_errno));
save_errno=my_errno;
save_errno= my_errno;
DBUG_ASSERT(save_errno);
if (!save_errno)
save_errno= HA_ERR_INTERNAL_ERROR; /* Should never happen */
if (my_errno == HA_ERR_FOUND_DUPP_KEY || my_errno == HA_ERR_OUT_OF_MEM ||
my_errno == HA_ERR_RECORD_FILE_FULL)
{

View file

@ -317,6 +317,8 @@ err:
err2:
save_errno=my_errno;
DBUG_ASSERT(save_errno);
if (!save_errno)
save_errno= HA_ERR_INTERNAL_ERROR; /* Should never happen */
DBUG_PRINT("error", ("got error: %d", save_errno));
VOID(_ma_writeinfo(info,WRITEINFO_UPDATE_KEYFILE));
allow_break(); /* Allow SIGHUP & SIGINT */

View file

@ -41,7 +41,7 @@ static const char *set_collation_name, *opt_tmpdir;
static CHARSET_INFO *set_collation;
static int stopwords_inited= 0;
static MY_TMPDIR maria_chk_tmpdir;
static my_bool opt_transaction_logging;
static my_bool opt_transaction_logging, opt_debug;
static const char *type_names[]=
{
@ -179,7 +179,8 @@ enum options_mc {
OPT_READ_BUFFER_SIZE, OPT_WRITE_BUFFER_SIZE, OPT_SORT_BUFFER_SIZE,
OPT_SORT_KEY_BLOCKS, OPT_DECODE_BITS, OPT_FT_MIN_WORD_LEN,
OPT_FT_MAX_WORD_LEN, OPT_FT_STOPWORD_FILE,
OPT_MAX_RECORD_LENGTH, OPT_AUTO_CLOSE, OPT_STATS_METHOD, OPT_TRANSACTION_LOG
OPT_MAX_RECORD_LENGTH, OPT_AUTO_CLOSE, OPT_STATS_METHOD, OPT_TRANSACTION_LOG,
OPT_SKIP_SAFEMALLOC
};
static struct my_option my_long_options[] =
@ -289,6 +290,13 @@ static struct my_option my_long_options[] =
{"silent", 's',
"Only print errors. One can use two -s to make maria_chk very silent.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifndef DBUG_OFF
#ifdef SAFEMALLOC
{"skip-safemalloc", OPT_SKIP_SAFEMALLOC,
"Don't use the memory allocation checking.", 0, 0, 0, GET_NO_ARG, NO_ARG,
0, 0, 0, 0, 0, 0},
#endif
#endif
{"sort-index", 'S',
"Sort index blocks. This speeds up 'read-next' in applications.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
@ -713,6 +721,12 @@ get_one_option(int optid,
break;
case '#':
DBUG_SET_INITIAL(argument ? argument : "d:t:o,/tmp/maria_chk.trace");
opt_debug= 1;
break;
case OPT_SKIP_SAFEMALLOC:
#ifdef SAFEMALLOC
sf_malloc_quick=1;
#endif
break;
case 'V':
print_version();
@ -813,6 +827,10 @@ static void get_options(register int *argc,register char ***argv)
exit(1);
}
if (!opt_debug)
{
DEBUGGER_OFF; /* Speed up things a bit */
}
if (init_tmpdir(&maria_chk_tmpdir, opt_tmpdir))
exit(1);
@ -906,7 +924,7 @@ static int maria_chk(HA_CHECK *param, char *filename)
if (param->testflag & T_SORT_RECORDS)
{
_ma_check_print_error(param,
"Record format used by '%s' is is not yet supported with repair/check",
"Record format used by '%s' is is not yet supported with sort-records",
filename);
param->error_printed= 0;
error= 1;
@ -1443,7 +1461,7 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, char *name)
else
buff[0]=0;
if (param->testflag & T_VERBOSE)
printf("%11.0g %12s %10d",
printf("%11.0f %12s %10d",
share->state.rec_per_key_part[keyseg_nr++],
buff,keyinfo->block_length);
VOID(putchar('\n'));
@ -1464,7 +1482,7 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, char *name)
printf(" %-6ld%-3d %-21s",
(long) keyseg->start+1,keyseg->length,buff);
if (param->testflag & T_VERBOSE)
printf("%11.0g", share->state.rec_per_key_part[keyseg_nr++]);
printf("%11.0f", share->state.rec_per_key_part[keyseg_nr++]);
VOID(putchar('\n'));
}
keyseg++;

View file

@ -952,9 +952,9 @@ typedef struct st_maria_block_info
#define UPDATE_AUTO_INC 8
#define UPDATE_OPEN_COUNT 16
#define USE_BUFFER_INIT (((1024L*1024L*10-MALLOC_OVERHEAD)/8192)*8192)
#define USE_BUFFER_INIT (((1024L*1024L*128-MALLOC_OVERHEAD)/8192)*8192)
#define READ_BUFFER_INIT (1024L*256L-MALLOC_OVERHEAD)
#define SORT_BUFFER_INIT (2048L*1024L-MALLOC_OVERHEAD)
#define SORT_BUFFER_INIT (1024L*1024L*64-MALLOC_OVERHEAD)
#define MIN_SORT_BUFFER (4096-MALLOC_OVERHEAD)
#define fast_ma_writeinfo(INFO) if (!(INFO)->s->tot_locks) (void) _ma_writeinfo((INFO),0)

View file

@ -100,3 +100,5 @@ ma_pagecache_consist_64kWR_t_big_CPPFLAGS = $(ma_pagecache_common_cppflags) -DPA
CLEANFILES = maria_log_control page_cache_test_file_1 \
maria_log.????????
# Don't update the files from bitkeeper
%::SCCS/s.%

View file

@ -462,7 +462,7 @@ int main(int argc __attribute__((unused)),
errno);
exit(1);
}
/*my_delete(file1_name, MYF(0));*/
my_delete(file1_name, MYF(0));
my_end(0);
DBUG_PRINT("info", ("file1 (%d) closed", file1.file));

View file

@ -613,7 +613,7 @@ int main(int argc __attribute__((unused)),
if (my_close(file1.file, MYF(MY_WME)))
exit(1);
/*my_delete(file1_name, MYF(0));*/
my_delete(file1_name, MYF(0));
my_end(0);
DBUG_PRINT("info", ("file1 (%d) closed", file1.file));

View file

@ -121,7 +121,9 @@ sub run_check_tests
["--key_multiple -P -S","-sm"] );
my @ma_test2_opt= ( ["-L -K -W -P","-sm"],
["-L -K -W -P -A","-sm"],
["-L -K -P -R3 -m50 -b1000000","-sm"],
["-L -K -W -P -b32768", "-sm"],
["-L -K -W -P -M -T -c -b32768 -t4 -m300", "-sm"],
["-L -K -P -R3 -m50 -b1000000", "-sm"],
["-L -B","-sm"],
["-D -B -c","-sm"],
["-m10000 -e4096 -K","-sm"],
@ -200,8 +202,8 @@ sub run_repair_tests()
"$maria_path/maria_chk$suffix -se test2",
"$maria_path/maria_chk$suffix -sr test2",
"$maria_path/maria_chk$suffix -se test2",
"$maria_path/ma_test2$suffix $silent -c -t4 $row_type",
"$maria_path/maria_chk$suffix -sz test1",
"$maria_path/ma_test2$suffix $silent -c -t4 -b32768 $row_type",
"$maria_path/maria_chk$suffix -s --zerofill test1",
"$maria_path/maria_chk$suffix -se test1"
);
@ -294,7 +296,7 @@ sub run_tests_on_warnings_and_errors
# ma_test2$suffix $silent -L -K -R1 -m2000 ; Should give error 135\n
# In the following a failure is a success and success is a failure
$com= "$maria_path/ma_test2$suffix $silent -L -K -R1 -m2000 ";
$com.= ">ma_test2_message.txt 2>&1 && false";
$com.= ">ma_test2_message.txt 2>&1";
ok($com, $verbose, 0, 1);
ok("cat ma_test2_message.txt", $verbose, 0);
ok("grep \"Error: 135\" ma_test2_message.txt > /dev/null", $verbose, 0);
@ -421,18 +423,19 @@ sub ok
print "Running: '$com'\n";
}
$output= `$com 2>&1`;
$err= $? >> 8;
$err= $?;
if ($verbose)
{
print "$output\n";
}
if ($err == $expected_error)
if ((!$err && !$expected_error) ||
(($err >> 8) == $expected_error && $expected_error))
{
print "ok\n";
return 1;
}
print "not ok\n";
$msg= "\nFailed test '$com' ";
$msg= "\nFailed test '$com' with error $err ";
if ($iteration)
{
$msg.= "(loop iteration $iteration.) ";
@ -445,6 +448,5 @@ sub ok
$msg.= "Was expecting errcode: $expected_error\n";
}
warn $msg;
return 0;
}