Added error HA_ERR_FILE_TOO_SHORT to be used when files are shorter than expected (by my_read/my_pread)

Added debugger hook _my_dbug_put_break_here() that is called if we get a CRC that matches --debug-crc-break (my_crc_dbug_break)
Fixed REDO_REPAIR to use all repair modes (repair, repair_by_sort, repair_paralell
REDO_REPAIR now also logs used key map
Fixed some bugs in REDO logging of key pages
Better error messages from maria_read_log
Added my_readwrite_flags to init_pagecache() to be able to get better error messages and simplify code.
Don't allow pagecaches with less than 8 blocks (Causes strange crashes)
Added EXTRA_DEBUG_KEY_CHANGES. When this is defined some REDO_INDEX entries contains page checksums (these are calculated and checked in DBUG mode, ignored otherwise)
Fixed bug in ma_pagecache unit tests that caused program to sometimes fail
Added some missing calls to MY_INIT() that caused some unit tests to fail
Fixed that TRUNCATE works properly on temporary MyISAM files
Updates some result files to new table checksums results (checksum when NULL fields are ignored)
perl test-insert can be replayed with maria_read_log!


sql/share/Makefile.am:
  Change mode to -rw-rw-r--
BitKeeper/etc/ignore:
  added storage/maria/unittest/page_cache_test_file_1 storage/maria/unittest/pagecache_debug.log
include/maria.h:
  Added maria_tmpdir
include/my_base.h:
  Added error HA_ERR_FILE_TOO_SHORT
include/my_sys.h:
  Added variable my_crc_dbug_check
  Added function my_dbug_put_break_here()
include/myisamchk.h:
  Added org_key_map (Needed for writing REDO record for REPAIR)
mysql-test/r/innodb.result:
  Updated to new checksum algorithm (NULL ignored)
mysql-test/r/mix2_myisam.result:
  Updated to new checksum algorithm (NULL ignored)
mysql-test/r/myisam.result:
  Updated to new checksum algorithm (NULL ignored)
mysql-test/t/myisam.test:
  Added used table
mysys/checksum.c:
  Added DBUG for checksum results
  Added debugger hook so that _my_dbug_put_break_here() is called if we get matching CRC
mysys/lf_alloc-pin.c:
  Fixed compiler warning
mysys/my_handler.c:
  Added new error message
mysys/my_init.c:
  If my_progname is not given, use 'unknown' form my_progname_short
  Added debugger function my_debug_put_break_here()
mysys/my_pread.c:
  In case of too short file when MY_NABP or MY_FNABP is specified, give error HA_ERR_FILE_TO_SHORT
mysys/my_read.c:
  In case of too short file when MY_NABP or MY_FNABP is specified, give error HA_ERR_FILE_TO_SHORT
sql/mysqld.cc:
  Added debug option --debug-crc-break
sql/sql_parse.cc:
  Trivial optimization
storage/maria/ha_maria.cc:
  Renamed variable to be more logical
  Ensure that param.testflag is correct when calling repair
  Added extra argument to init_pagecache
  Set default value for maria_tempdir
storage/maria/ma_blockrec.c:
  Test for HA_ERR_FILE_TOO_SHORT instead for -1
storage/maria/ma_cache.c:
  Test for HA_ERR_FILE_TOO_SHORT instead for -1
storage/maria/ma_check.c:
  Set param->testflag to match how repair is run (needed for REDO logging)
  Simple optimization
  Moved flag if page is node from pagelength to keypage-flag byte
  Log used key map in REDO log.
storage/maria/ma_delete.c:
  Remember previous UNDO entry when writing undo (for future CLR records)
  Moved flag if page is node from pagelength to keypage-flag byte
  Fixed some bugs in redo logging
  Added CRC for some translog REDO_INDEX entries
storage/maria/ma_dynrec.c:
  Test for HA_ERR_FILE_TOO_SHORT instead for -1
storage/maria/ma_ft_update.c:
  Fixed call to _ma_store_page_used()
storage/maria/ma_key_recover.c:
  Added CRC for some translog REDO_INDEX entries
  Removed not needed pagecache_write() in _ma_apply_redo_index()
storage/maria/ma_locking.c:
  Test for HA_ERR_FILE_TOO_SHORT instead for -1
storage/maria/ma_loghandler.c:
  Added used key map to REDO_REPAIR_TABLE
storage/maria/ma_loghandler.h:
  Added operation for checksum of key pages
storage/maria/ma_open.c:
  Allocate storage for undo lsn pointers
storage/maria/ma_pagecache.c:
  Remove not needed include file
  Change logging to use fd: for file descritors as other code
  Added my_readwrite_flags to init_pagecache() to be able to get better error messages for maria_chk/maria_read_log
  Don't allow pagecaches with less than 8 blocks
  Remove wrong DBUG_ASSERT()
storage/maria/ma_pagecache.h:
  Added readwrite_flags
storage/maria/ma_recovery.c:
  Better error messages for maria_read_log:
  - Added eprint() for printing error messages
  - Print extra \n before error message if we are printing %0 %10 ...
  
  Added used key_map to REDO_REPAIR log entry
  More DBUG
  Call same repair method that was used by mysqld
storage/maria/ma_rt_index.c:
  Moved flag if page is node from pagelength to keypage-flag byte
storage/maria/ma_rt_key.c:
  Fixed call to _ma_store_page_used()
storage/maria/ma_rt_split.c:
  Moved flag if page is node from pagelength to keypage-flag byte
storage/maria/ma_static.c:
  Added maria_tmpdir
storage/maria/ma_test1.c:
  Updated call to init_pagecache()
storage/maria/ma_test2.c:
  Updated call to init_pagecache()
storage/maria/ma_test3.c:
  Updated call to init_pagecache()
storage/maria/ma_write.c:
  Removed #ifdef NOT_YET
  Moved flag if page is node from pagelength to keypage-flag byte
  Fixed bug in  _ma_log_del_prefix()
storage/maria/maria_chk.c:
  Fixed wrong min limit for page_buffer_size
  Updated call to init_pagecache()
storage/maria/maria_def.h:
  Added EXTRA_DEBUG_KEY_CHANGES. When this is defined some REDO_INDEX entries contains page checksums
  Moved flag if page is node from pagelength to keypage-flag byte
storage/maria/maria_ftdump.c:
  Updated call to init_pagecache()
storage/maria/maria_pack.c:
  Updated call to init_pagecache()
  Reset share->state.create_rename_lsn & share->state.is_of_horizon
storage/maria/maria_read_log.c:
  Better error messages
  Added --tmpdir option (needed to set temporary directory for REDO_REPAIR)
  Added --start-from-lsn
  Changed option for --display-only to 'd' (wanted to use -o for 'offset')
storage/maria/unittest/lockman2-t.c:
  Added missing call to MY_INIT()
storage/maria/unittest/ma_pagecache_consist.c:
  Updated call to init_pagecache()
storage/maria/unittest/ma_pagecache_single.c:
  Fixed bug that caused program to sometimes fail
  Added some DBUG_ASSERTS()
  Changed some calls to malloc()/free() to my_malloc()/my_free()
  Create extra file to expose original hard-to-find bug
storage/maria/unittest/ma_test_loghandler-t.c:
  Updated call to init_pagecache()
storage/maria/unittest/ma_test_loghandler_first_lsn-t.c:
  Updated call to init_pagecache()
storage/maria/unittest/ma_test_loghandler_max_lsn-t.c:
  Updated call to init_pagecache()
storage/maria/unittest/ma_test_loghandler_multigroup-t.c:
  Updated call to init_pagecache()
storage/maria/unittest/ma_test_loghandler_multithread-t.c:
  Updated call to init_pagecache()
storage/maria/unittest/ma_test_loghandler_noflush-t.c:
  Updated call to init_pagecache()
storage/maria/unittest/ma_test_loghandler_pagecache-t.c:
  Updated call to init_pagecache()
storage/maria/unittest/ma_test_loghandler_purge-t.c:
  Updated call to init_pagecache()
storage/maria/unittest/test_file.c:
  Changed malloc()/free() to my_malloc()/my_free()
  Fixed memory leak
  Changd logic a bit while trying to find bug in reset_file()
storage/maria/unittest/trnman-t.c:
  Added missing call to MY_INIT()
storage/myisam/mi_cache.c:
  Test for HA_ERR_FILE_TOO_SHORT instead for -1
storage/myisam/mi_create.c:
  Removed O_EXCL to get TRUNCATE to work for temporary files
storage/myisam/mi_dynrec.c:
  Test for HA_ERR_FILE_TOO_SHORT instead for -1
storage/myisam/mi_locking.c:
  Test for HA_ERR_FILE_TOO_SHORT instead for -1
mysql-test/r/old-mode.result:
  New BitKeeper file ``mysql-test/r/old-mode.result''
mysql-test/t/old-mode-master.opt:
  New BitKeeper file ``mysql-test/t/old-mode-master.opt''
mysql-test/t/old-mode.test:
  New BitKeeper file ``mysql-test/t/old-mode.test''
This commit is contained in:
unknown 2007-12-04 23:23:42 +02:00
parent 143f35e611
commit ebf7ab7bce
65 changed files with 741 additions and 434 deletions

View File

@ -3063,3 +3063,5 @@ libmysqld/sql_tablespace.cc
sql/link_sources
ylwrap
libmysql_r/link_sources
storage/maria/unittest/page_cache_test_file_1
storage/maria/unittest/pagecache_debug.log

View File

@ -255,7 +255,7 @@ extern my_bool maria_delay_key_write;
extern my_off_t maria_max_temp_length;
extern ulong maria_bulk_insert_tree_size, maria_data_pointer_size;
extern PAGECACHE maria_pagecache_var, *maria_pagecache;
extern MY_TMPDIR *maria_tmpdir;
/* Prototypes for maria-functions */

View File

@ -422,7 +422,8 @@ enum ha_base_keytype {
#define HA_ERR_LOGGING_IMPOSSIBLE 170
#define HA_ERR_NEW_FILE 171 /* New file format */
#define HA_ERR_INITIALIZATION 172 /* Error during initialization */
#define HA_ERR_LAST 172 /* Copy of last error nr */
#define HA_ERR_FILE_TOO_SHORT 173 /* File too short */
#define HA_ERR_LAST 173 /* Copy of last error nr */
/* Number of different errors */
#define HA_ERR_ERRORS (HA_ERR_LAST - HA_ERR_FIRST + 1)

View File

@ -546,6 +546,7 @@ my_off_t my_b_safe_tell(IO_CACHE* info); /* picks the correct tell() */
*(info)->current_pos)
typedef uint32 ha_checksum;
extern ha_checksum my_crc_dbug_check;
/* Define the type of function to be passed to process_default_option_files */
typedef int (*Process_option_func)(void *ctx, const char *group_name,
@ -858,6 +859,7 @@ extern int unpackfrm(uchar **, size_t *, const uchar *);
extern ha_checksum my_checksum(ha_checksum crc, const uchar *mem,
size_t count);
extern void my_debug_put_break_here(void);
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

@ -128,6 +128,7 @@ typedef struct st_handler_check_param
ha_checksum key_crc[HA_MAX_POSSIBLE_KEY];
ha_checksum tmp_key_crc[HA_MAX_POSSIBLE_KEY];
ha_checksum tmp_record_checksum;
ulonglong org_key_map;
size_t use_buffers, read_buffer_length, write_buffer_length;
size_t sort_buffer_length, sort_key_blocks;
ulong rec_per_key_part[HA_MAX_KEY_SEG * HA_MAX_POSSIBLE_KEY];

View File

@ -1440,7 +1440,7 @@ insert t2 select * from t1;
insert t3 select * from t1;
checksum table t1, t2, t3, t4 quick;
Table Checksum
test.t1 2948697075
test.t1 3442722830
test.t2 NULL
test.t3 NULL
test.t4 NULL
@ -1448,17 +1448,17 @@ Warnings:
Error 1146 Table 'test.t4' doesn't exist
checksum table t1, t2, t3, t4;
Table Checksum
test.t1 2948697075
test.t2 2948697075
test.t3 2948697075
test.t1 3442722830
test.t2 3442722830
test.t3 3442722830
test.t4 NULL
Warnings:
Error 1146 Table 'test.t4' doesn't exist
checksum table t1, t2, t3, t4 extended;
Table Checksum
test.t1 2948697075
test.t2 2948697075
test.t3 2948697075
test.t1 3442722830
test.t2 3442722830
test.t3 3442722830
test.t4 NULL
Warnings:
Error 1146 Table 'test.t4' doesn't exist

View File

@ -1232,34 +1232,34 @@ insert t5 select * from t1;
insert t6 select * from t1;
checksum table t1, t2, t3, t4, t5, t6, t7 quick;
Table Checksum
test.t1 2948697075
test.t1 3442722830
test.t2 NULL
test.t3 NULL
test.t4 NULL
test.t5 2948697075
test.t5 3442722830
test.t6 NULL
test.t7 NULL
Warnings:
Error 1146 Table 'test.t7' doesn't exist
checksum table t1, t2, t3, t4, t5, t6, t7;
Table Checksum
test.t1 2948697075
test.t2 2948697075
test.t3 2948697075
test.t4 2948697075
test.t5 2948697075
test.t6 2948697075
test.t1 3442722830
test.t2 3442722830
test.t3 3442722830
test.t4 3442722830
test.t5 3442722830
test.t6 3442722830
test.t7 NULL
Warnings:
Error 1146 Table 'test.t7' doesn't exist
checksum table t1, t2, t3, t4, t5, t6, t7 extended;
Table Checksum
test.t1 2948697075
test.t2 2948697075
test.t3 2948697075
test.t4 2948697075
test.t5 2948697075
test.t6 2948697075
test.t1 3442722830
test.t2 3442722830
test.t3 3442722830
test.t4 3442722830
test.t5 3442722830
test.t6 3442722830
test.t7 NULL
Warnings:
Error 1146 Table 'test.t7' doesn't exist

View File

@ -1,4 +1,4 @@
drop table if exists t1,t2;
drop table if exists t1,t2,t3;
SET SQL_WARNINGS=1;
CREATE TABLE t1 (
STRING_DATA char(255) default NULL,
@ -551,22 +551,22 @@ insert t1 values (1, "aaa", "bbb"), (NULL, "", "ccccc"), (0, NULL, "");
insert t2 select * from t1;
checksum table t1, t2, t3 quick;
Table Checksum
test.t1 2948697075
test.t1 3442722830
test.t2 NULL
test.t3 NULL
Warnings:
Error 1146 Table 'test.t3' doesn't exist
checksum table t1, t2, t3;
Table Checksum
test.t1 2948697075
test.t2 2948697075
test.t1 3442722830
test.t2 3442722830
test.t3 NULL
Warnings:
Error 1146 Table 'test.t3' doesn't exist
checksum table t1, t2, t3 extended;
Table Checksum
test.t1 2948697075
test.t2 2948697075
test.t1 3442722830
test.t2 3442722830
test.t3 NULL
Warnings:
Error 1146 Table 'test.t3' doesn't exist

View File

@ -0,0 +1,14 @@
drop table if exists t1,t2;
create table t1 (a int, b varchar(200), c text not null) checksum=1;
create table t2 (a int, b varchar(200), c text not null) checksum=0;
insert t1 values (1, "aaa", "bbb"), (NULL, "", "ccccc"), (0, NULL, "");
insert t2 select * from t1;
checksum table t1, t2;
Table Checksum
test.t1 3442722830
test.t2 2948697075
checksum table t1, t2 extended;
Table Checksum
test.t1 2948697075
test.t2 2948697075
drop table t1,t2;

View File

@ -4,7 +4,7 @@
# Initialise
--disable_warnings
drop table if exists t1,t2;
drop table if exists t1,t2,t3;
--enable_warnings
SET SQL_WARNINGS=1;

View File

@ -0,0 +1 @@
--old=1

View File

@ -0,0 +1,16 @@
#
# Test 'old' mode
#
# Initialise
--disable_warnings
drop table if exists t1,t2;
--enable_warnings
create table t1 (a int, b varchar(200), c text not null) checksum=1;
create table t2 (a int, b varchar(200), c text not null) checksum=0;
insert t1 values (1, "aaa", "bbb"), (NULL, "", "ccccc"), (0, NULL, "");
insert t2 select * from t1;
checksum table t1, t2;
checksum table t1, t2 extended;
drop table t1,t2;

View File

@ -18,6 +18,8 @@
#include <my_sys.h>
#include <zlib.h>
ha_checksum my_crc_dbug_check= 1; /* Unlikely number */
/*
Calculate a long checksum for a memoryblock.
@ -34,9 +36,13 @@ ha_checksum my_checksum(ha_checksum crc, const uchar *pos, size_t length)
const uchar *end=pos+length;
for ( ; pos != end ; pos++)
crc=((crc << 8) + *((uchar*) pos)) + (crc >> (8*sizeof(ha_checksum)-8));
return crc;
#else
return (ha_checksum)crc32((uint)crc, pos, length);
crc= (ha_checksum) crc32((uint)crc, pos, length);
#endif /* NOT_USED */
DBUG_PRINT("info", ("crc: %lu", (ulong) crc));
#ifndef DBUG_OFF
if (crc == my_crc_dbug_check)
my_debug_put_break_here();
#endif
return crc;
}

View File

@ -333,6 +333,7 @@ static void _lf_pinbox_real_free(LF_PINS *pins)
struct st_lf_alloc_node *first, *last= NULL;
LF_PINBOX *pinbox= pins->pinbox;
LINT_INIT(first);
npins= pinbox->pins_in_array+1;
#ifdef HAVE_ALLOCA

View File

@ -626,7 +626,8 @@ static const char *handler_error_messages[]=
"Record is the same",
"It is not possible to log this statement",
"The table is of a new format not supported by this version",
"Got a fatal error during initialzaction of handler"
"Got a fatal error during initialzaction of handler",
"File to short; Expected more data in file"
};

View File

@ -78,7 +78,10 @@ my_bool my_init(void)
my_umask= 0660; /* Default umask for new files */
my_umask_dir= 0700; /* Default umask for new directories */
init_glob_errs();
my_progname_short= my_progname + dirname_length(my_progname);
my_progname_short= "unknown";
if (my_progname)
my_progname_short= my_progname + dirname_length(my_progname);
#if defined(THREAD) && defined(SAFE_MUTEX)
safe_mutex_global_init(); /* Must be called early */
#endif
@ -233,6 +236,13 @@ Voluntary context switches %ld, Involuntary context switches %ld\n",
my_init_done=0;
} /* my_end */
#ifndef DBUG_OFF
/* Dummy tag function for debugging */
void my_debug_put_break_here(void)
{
}
#endif
#ifdef __WIN__

View File

@ -15,6 +15,7 @@
#include "mysys_priv.h"
#include "mysys_err.h"
#include "my_base.h"
#include <errno.h>
#ifdef HAVE_PREAD
#include <unistd.h>
@ -63,7 +64,11 @@ size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset,
pthread_mutex_unlock(&my_file_info[Filedes].mutex);
#else
if ((error= ((readbytes= pread(Filedes, Buffer, Count, offset)) != Count)))
my_errno= errno ? errno : -1;
{
my_errno= errno;
if (errno == 0 || (errno == -1 && (MyFlags & (MY_NABP | MY_FNABP))))
my_errno= HA_ERR_FILE_TOO_SHORT;
}
#endif
if (error || readbytes != Count)
{

View File

@ -15,9 +15,9 @@
#include "mysys_priv.h"
#include "mysys_err.h"
#include <my_base.h>
#include <errno.h>
/*
Read a chunk of bytes from a file with retry's if needed
@ -46,7 +46,9 @@ size_t my_read(File Filedes, uchar *Buffer, size_t Count, myf MyFlags)
errno= 0; /* Linux doesn't reset this */
if ((readbytes= read(Filedes, Buffer, Count)) != Count)
{
my_errno= errno ? errno : -1;
my_errno= errno;
if (errno == 0 || (errno == -1 && (MyFlags & (MY_NABP | MY_FNABP))))
my_errno= HA_ERR_FILE_TOO_SHORT;
DBUG_PRINT("warning",("Read only %d bytes off %lu from %d, errno: %d",
(int) readbytes, (ulong) Count, Filedes,
my_errno));

View File

@ -340,6 +340,7 @@ static char *default_storage_engine_str;
static char compiled_default_collation_name[]= MYSQL_DEFAULT_COLLATION_NAME;
static I_List<THD> thread_cache;
static double long_query_time;
static ulong opt_my_crc_dbug_check;
static pthread_cond_t COND_thread_cache, COND_flush_thread_cache;
@ -5119,7 +5120,7 @@ enum options_mysqld
OPT_SECURE_FILE_PRIV,
OPT_MIN_EXAMINED_ROW_LIMIT,
OPT_LOG_SLOW_SLAVE_STATEMENTS,
OPT_OLD_MODE
OPT_DEBUG_CRC, OPT_OLD_MODE
};
@ -5244,6 +5245,10 @@ struct my_option my_long_options[] =
#ifndef DBUG_OFF
{"debug", '#', "Debug log.", (uchar**) &default_dbug_option,
(uchar**) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
{"debug-crc-break", OPT_DEBUG_CRC,
"Call my_debug_put_break_here() if crc matches this number (for debug).",
(uchar**) &opt_my_crc_dbug_check, (uchar**) &opt_my_crc_dbug_check,
0, GET_ULONG, REQUIRED_ARG, 0, 0, ~(ulong) 0L, 0, 0, 0},
#endif
{"default-character-set", 'C', "Set the default character set (deprecated option, use --character-set-server instead).",
(uchar**) &default_character_set_name, (uchar**) &default_character_set_name,
@ -7893,6 +7898,7 @@ static void get_options(int *argc,char **argv)
/* Set global variables based on startup options */
myisam_block_size=(uint) 1 << my_bit_log2(opt_myisam_block_size);
my_crc_dbug_check= opt_my_crc_dbug_check;
/* long_query_time is in microseconds */
global_system_variables.long_query_time= max_system_variables.long_query_time=

View File

@ -4683,8 +4683,7 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
(see SQLCOM_GRANT case, mysql_execute_command() function) and
set db_is_pattern according to 'dont_check_global_grants' value.
*/
bool db_is_pattern= (test(want_access & GRANT_ACL) &&
dont_check_global_grants);
bool db_is_pattern= ((want_access & GRANT_ACL) && dont_check_global_grants);
#endif
ulong dummy;
DBUG_ENTER("check_access");

View File

@ -1211,7 +1211,7 @@ int ha_maria::repair(THD *thd, HA_CHECK &param, bool do_optimize)
ulonglong key_map= ((local_testflag & T_CREATE_MISSING_KEYS) ?
maria_get_mask_all_keys_active(share->base.keys) :
share->state.key_map);
uint testflag= param.testflag;
uint save_testflag= param.testflag;
if (maria_test_if_sort_rep(file, file->state->records, key_map, 0) &&
(local_testflag & T_REP_BY_SORT))
{
@ -1226,6 +1226,7 @@ int ha_maria::repair(THD *thd, HA_CHECK &param, bool do_optimize)
/* TODO: respect maria_repair_threads variable */
my_snprintf(buf, 40, "Repair with %d threads", my_count_bits(key_map));
thd->proc_info= buf;
param.testflag|= T_REP_PARALLEL;
error= maria_repair_parallel(&param, file, fixed_name,
param.testflag & T_QUICK);
thd->proc_info= "Repair done"; // to reset proc_info, as
@ -1234,6 +1235,7 @@ int ha_maria::repair(THD *thd, HA_CHECK &param, bool do_optimize)
else
{
thd->proc_info= "Repair by sorting";
param.testflag|= T_REP_BY_SORT;
error= maria_repair_by_sort(&param, file, fixed_name,
param.testflag & T_QUICK);
}
@ -1241,7 +1243,7 @@ int ha_maria::repair(THD *thd, HA_CHECK &param, bool do_optimize)
else
{
thd->proc_info= "Repair with keycache";
param.testflag &= ~T_REP_BY_SORT;
param.testflag &= ~(T_REP_BY_SORT | T_REP_PARALLEL);
error= maria_repair(&param, file, fixed_name, param.testflag & T_QUICK);
/**
@todo RECOVERY BUG we do things with the index file
@ -1249,7 +1251,7 @@ int ha_maria::repair(THD *thd, HA_CHECK &param, bool do_optimize)
record and bumped create_rename_lsn. Is it ok?
*/
}
param.testflag= testflag;
param.testflag= save_testflag;
optimize_done= 1;
}
if (!error)
@ -2410,13 +2412,14 @@ static int ha_maria_init(void *p)
maria_hton->flags= HTON_CAN_RECREATE | HTON_SUPPORT_LOG_TABLES;
bzero(maria_log_pagecache, sizeof(*maria_log_pagecache));
maria_data_root= mysql_real_data_home;
maria_tmpdir= &mysql_tmpdir_list; /* For REDO */
res= maria_init() || ma_control_file_create_or_open() ||
(init_pagecache(maria_pagecache,
!init_pagecache(maria_pagecache,
pagecache_buffer_size, pagecache_division_limit,
pagecache_age_threshold, MARIA_KEY_BLOCK_LENGTH) == 0) ||
(init_pagecache(maria_log_pagecache,
pagecache_age_threshold, MARIA_KEY_BLOCK_LENGTH, 0) ||
!init_pagecache(maria_log_pagecache,
TRANSLOG_PAGECACHE_SIZE, 0, 0,
TRANSLOG_PAGE_SIZE) == 0) ||
TRANSLOG_PAGE_SIZE, 0) ||
translog_init(maria_data_root, TRANSLOG_FILE_SIZE,
MYSQL_VERSION_ID, server_id, maria_log_pagecache,
TRANSLOG_DEFAULT_FLAGS) ||

View File

@ -5045,7 +5045,7 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
PAGECACHE_PLAIN_PAGE, PAGECACHE_LOCK_WRITE,
&page_link.link)))
{
if (my_errno != -1) /* If not read outside of file */
if (my_errno != HA_ERR_FILE_TOO_SHORT) /* If not read outside of file */
{
pagecache_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK,
@ -5487,7 +5487,7 @@ uint _ma_apply_redo_insert_row_blobs(MARIA_HA *info,
PAGECACHE_PLAIN_PAGE,
PAGECACHE_LOCK_WRITE, &page_link.link)))
{
if (my_errno != -1) /* If not read outside of file */
if (my_errno != HA_ERR_FILE_TOO_SHORT) /* If not read outside of file */
{
pagecache_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK,

View File

@ -97,8 +97,8 @@ int _ma_read_cache(IO_CACHE *info, uchar *buff, my_off_t pos, uint length,
DBUG_PRINT("error",
("Error %d reading next-multi-part block (Got %d bytes)",
my_errno, (int) read_length));
if (!my_errno || my_errno == -1)
my_errno=HA_ERR_WRONG_IN_RECORD;
if (!my_errno || my_errno == HA_ERR_FILE_TOO_SHORT)
my_errno= HA_ERR_WRONG_IN_RECORD;
DBUG_RETURN(1);
}
bzero(buff+read_length,MARIA_BLOCK_INFO_HEADER_LENGTH - in_buff_length -

View File

@ -2051,6 +2051,11 @@ static void initialize_variables_for_repair(HA_CHECK *param,
if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
param->testflag|= T_CALC_CHECKSUM;
param->glob_crc= 0;
if (rep_quick)
param->testflag|= T_QUICK;
else
param->testflag&= ~T_QUICK;
param->org_key_map= info->s->state.key_map;
sort_param->sort_info= sort_info;
sort_param->fix_datafile= (my_bool) (! rep_quick);
@ -2872,7 +2877,7 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
double *rec_per_key_part;
char llbuff[22];
MARIA_SORT_INFO sort_info;
ulonglong key_map=share->state.key_map;
ulonglong key_map= share->state.key_map;
myf sync_dir= ((share->now_transactional && !share->temporary) ?
MY_SYNC_DIR : 0);
my_bool scan_inited= 0;
@ -3005,9 +3010,7 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
for (sort_param.key=0 ; sort_param.key < share->base.keys ;
rec_per_key_part+=sort_param.keyinfo->keysegs, sort_param.key++)
{
sort_param.read_cache=param->read_cache;
sort_param.keyinfo=share->keyinfo+sort_param.key;
sort_param.seg=sort_param.keyinfo->seg;
if (! maria_is_key_active(key_map, sort_param.key))
{
/* Remember old statistics for key */
@ -3020,6 +3023,9 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
if ((!(param->testflag & T_SILENT)))
printf ("- Fixing index %d\n",sort_param.key+1);
sort_param.read_cache=param->read_cache;
sort_param.seg=sort_param.keyinfo->seg;
sort_param.max_pos= sort_param.pos= org_header_length;
keyseg=sort_param.seg;
bzero((char*) sort_param.unique,sizeof(sort_param.unique));
@ -3364,9 +3370,6 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
printf("Data records: %s\n", llstr(start_records,llbuff));
}
if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
param->testflag|=T_CALC_CHECKSUM;
if (_ma_flush_table_files(info, MARIA_FLUSH_DATA | MARIA_FLUSH_INDEX,
FLUSH_FORCE_WRITE, FLUSH_IGNORE_CHANGED))
goto err;
@ -4815,14 +4818,17 @@ static int sort_insert_key(MARIA_SORT_PARAM *sort_param,
/* Save pointer to previous block */
if (nod_flag)
{
_ma_store_keypage_flag(info, anc_buff, KEYPAGE_FLAG_ISNOD);
_ma_kpointer(info,key_block->end_pos,prev_block);
}
t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,
(uchar*) 0,lastkey,lastkey,key,
&s_temp);
(*keyinfo->store_key)(keyinfo, key_block->end_pos+nod_flag,&s_temp);
a_length+=t_length;
_ma_store_page_used(info, anc_buff, a_length, nod_flag);
_ma_store_page_used(info, anc_buff, a_length);
key_block->end_pos+=t_length;
if (a_length <= keyinfo->block_length)
{
@ -4832,7 +4838,7 @@ static int sort_insert_key(MARIA_SORT_PARAM *sort_param,
}
/* Fill block with end-zero and write filled block */
_ma_store_page_used(info, anc_buff, key_block->last_length, nod_flag);
_ma_store_page_used(info, anc_buff, key_block->last_length);
bzero(anc_buff+key_block->last_length,
keyinfo->block_length- key_block->last_length);
key_file_length=info->state->key_file_length;
@ -5812,8 +5818,7 @@ static int write_log_record_for_repair(const HA_CHECK *param, MARIA_HA *info)
if (translog_inited && !maria_in_recovery &&
info->s->base.born_transactional)
{
my_bool now_transactional= info->s->now_transactional;
info->s->now_transactional= 1;
my_bool save_now_transactional= info->s->now_transactional;
/*
For now this record is only informative. It could serve when applying
@ -5833,15 +5838,21 @@ static int write_log_record_for_repair(const HA_CHECK *param, MARIA_HA *info)
record).
*/
LEX_STRING log_array[TRANSLOG_INTERNAL_PARTS + 1];
uchar log_data[FILEID_STORE_SIZE + 4];
uchar log_data[FILEID_STORE_SIZE + 4 + 8];
LSN lsn;
log_array[TRANSLOG_INTERNAL_PARTS + 0].str= (char*) log_data;
log_array[TRANSLOG_INTERNAL_PARTS + 0].length= sizeof(log_data);
/*
testflag gives an idea of what REPAIR did (in particular T_QUICK
or not: did it touch the data file or not?).
*/
int4store(log_data + FILEID_STORE_SIZE, param->testflag);
/* org_key_map is used when recreating index after a load data infile */
int8store(log_data + FILEID_STORE_SIZE + 4, param->org_key_map);
log_array[TRANSLOG_INTERNAL_PARTS + 0].str= (char*) log_data;
log_array[TRANSLOG_INTERNAL_PARTS + 0].length= sizeof(log_data);
info->s->now_transactional= 1;
if (unlikely(translog_write_record(&lsn, LOGREC_REDO_REPAIR_TABLE,
&dummy_transaction_object, info,
sizeof(log_data),
@ -5857,7 +5868,7 @@ static int write_log_record_for_repair(const HA_CHECK *param, MARIA_HA *info)
*/
if (_ma_update_create_rename_lsn(share, lsn, TRUE))
return 1;
info->s->now_transactional= now_transactional;
info->s->now_transactional= save_now_transactional;
}
return 0;
}

View File

@ -176,6 +176,7 @@ int _ma_ck_delete(register MARIA_HA *info, uint keynr, uchar *key,
struct st_msg_to_write_hook_for_undo_key msg;
enum translog_record_type log_type= LOGREC_UNDO_KEY_DELETE;
info->key_delete_undo_lsn[keynr]= info->trn->undo_lsn;
lsn_store(log_data, info->trn->undo_lsn);
key_nr_store(log_data + LSN_STORE_SIZE + FILEID_STORE_SIZE, keynr);
log_pos= log_data + LSN_STORE_SIZE + FILEID_STORE_SIZE + KEY_NR_STORE_SIZE;
@ -436,7 +437,7 @@ static int d_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
anc_page_link->changed= 1;
anc_buff_length-= tmp;
_ma_store_page_used(info, anc_buff, anc_buff_length, nod_flag);
_ma_store_page_used(info, anc_buff, anc_buff_length);
/*
Log initial changes on pages
@ -622,7 +623,7 @@ static int del(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
}
/* Remove last key from leaf page */
_ma_store_page_used(info, leaf_buff, key_start-leaf_buff, nod_flag);
_ma_store_page_used(info, leaf_buff, key_start-leaf_buff);
if (info->s->now_transactional &&
_ma_log_suffix(info, leaf_page, leaf_buff, leaf_length,
@ -659,11 +660,10 @@ static int del(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
if (!(*keyinfo->get_key)(keyinfo,share->base.key_reflength,&keypos,ret_key))
goto err;
_ma_kpointer(info,keypos - share->base.key_reflength,next_block);
_ma_store_page_used(info, anc_buff, a_length + length,
share->base.key_reflength);
_ma_store_page_used(info, anc_buff, a_length + length);
if (info->s->now_transactional &&
_ma_log_add(info, anc_page, anc_buff, a_length + length,
_ma_log_add(info, anc_page, anc_buff, a_length,
key_start, s_temp.changed_length, s_temp.move_length, 1))
goto err;
@ -704,7 +704,7 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
int t_length;
uint length,anc_length,buff_length,leaf_length,p_length,s_length,nod_flag;
uint next_buff_length, new_buff_length, key_reflength, key_length;
uint unchanged_leaf_length, new_leaf_length;
uint unchanged_leaf_length, new_leaf_length, new_anc_length;
my_off_t next_page;
uchar anc_key[HA_MAX_KEY_BUFF],leaf_key[HA_MAX_KEY_BUFF];
uchar *buff,*endpos,*next_keypos,*anc_pos,*half_pos,*prev_key;
@ -778,7 +778,7 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
memcpy(buff, leaf_buff,(size_t) leaf_length);
(*keyinfo->store_key)(keyinfo, buff+leaf_length, &key_inserted);
buff_length= (uint) (endpos-buff);
_ma_store_page_used(info, buff, buff_length, nod_flag);
_ma_store_page_used(info, buff, buff_length);
/* remove key from anc_buff */
if (!(s_length=remove_key(keyinfo,key_reflength,keypos,anc_key,
@ -786,8 +786,8 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
&key_deleted)))
goto err;
anc_length-=s_length;
_ma_store_page_used(info, anc_buff, anc_length, key_reflength);
new_anc_length= anc_length - s_length;
_ma_store_page_used(info, anc_buff, new_anc_length);
if (buff_length <= (uint) (keyinfo->block_length - KEYPAGE_CHECKSUM_SIZE))
{
@ -827,7 +827,7 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
*/
MARIA_KEY_PARAM anc_key_inserted;
anc_end_pos= anc_buff + anc_length;
anc_end_pos= anc_buff + new_anc_length;
DBUG_PRINT("test",("anc_buff: 0x%lx anc_end_pos: 0x%lx",
(long) anc_buff, (long) anc_end_pos));
if (!first_key &&
@ -838,7 +838,7 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
goto err;
new_leaf_length= (uint) (half_pos-buff);
memcpy(leaf_buff, buff, (size_t) new_leaf_length);
_ma_store_page_used(info, leaf_buff, new_leaf_length, nod_flag);
_ma_store_page_used(info, leaf_buff, new_leaf_length);
/* Correct new keypointer to leaf_page */
half_pos=after_key;
@ -857,8 +857,8 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
else
bmove(keypos,keypos-t_length,(uint) (anc_end_pos-keypos)+t_length);
(*keyinfo->store_key)(keyinfo,keypos, &anc_key_inserted);
anc_length+= t_length;
_ma_store_page_used(info, anc_buff, anc_length, key_reflength);
new_anc_length+= t_length;
_ma_store_page_used(info, anc_buff, new_anc_length);
/* Store key first in new page */
if (nod_flag)
@ -874,7 +874,7 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
bmove(buff+p_length+t_length, half_pos, (size_t) length);
(*keyinfo->store_key)(keyinfo,buff+p_length, &key_inserted);
new_buff_length= length + t_length + p_length;
_ma_store_page_used(info, buff, new_buff_length, nod_flag);
_ma_store_page_used(info, buff, new_buff_length);
if (info->s->now_transactional)
{
@ -889,7 +889,7 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
if (_ma_log_add(info, anc_page, anc_buff, anc_length,
keypos,
anc_key_inserted.move_length +
min(anc_key_inserted.changed_length -
max(anc_key_inserted.changed_length -
anc_key_inserted.move_length,
key_deleted.changed_length),
anc_key_inserted.move_length -
@ -940,8 +940,8 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
PAGECACHE_LOCK_LEFT_WRITELOCKED, DFLT_INIT_HITS,
leaf_buff))
goto err;
DBUG_RETURN(anc_length <= ((info->quick_mode ? MARIA_MIN_BLOCK_LENGTH :
(uint) keyinfo->underflow_block_length)));
DBUG_RETURN(new_anc_length <= ((info->quick_mode ? MARIA_MIN_BLOCK_LENGTH :
(uint) keyinfo->underflow_block_length)));
}
DBUG_PRINT("test",("use left page"));
@ -988,7 +988,7 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
key_inserted.move_length);
new_buff_length= buff_length + leaf_length - p_length + t_length;
_ma_store_page_used(info, buff, new_buff_length, nod_flag);
_ma_store_page_used(info, buff, new_buff_length);
/* remove key from anc_buff */
if (!(s_length= remove_key(keyinfo,key_reflength,keypos,anc_key,
@ -996,8 +996,8 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
&key_deleted)))
goto err;
anc_length-=s_length;
_ma_store_page_used(info, anc_buff, anc_length, key_reflength);
new_anc_length= anc_length - s_length;
_ma_store_page_used(info, anc_buff, new_anc_length);
if (new_buff_length <= (uint) (keyinfo->block_length -
KEYPAGE_CHECKSUM_SIZE))
@ -1049,9 +1049,9 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
_ma_kpointer(info,leaf_key+key_length,leaf_page);
/* Save key in anc_buff */
DBUG_DUMP("anc_buff",anc_buff,anc_length);
DBUG_DUMP("anc_buff", anc_buff, new_anc_length);
DBUG_DUMP("key_to_anc",leaf_key,key_length);
anc_end_pos= anc_buff + anc_length;
anc_end_pos= anc_buff + new_anc_length;
t_length=(*keyinfo->pack_key)(keyinfo,key_reflength,
keypos == anc_end_pos ? (uchar*) 0
: keypos,
@ -1063,8 +1063,8 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
else
bmove(keypos,keypos-t_length,(uint) (anc_end_pos-keypos)+t_length);
(*keyinfo->store_key)(keyinfo,keypos, &anc_key_inserted);
anc_length+= t_length;
_ma_store_page_used(info, anc_buff, anc_length, key_reflength);
new_anc_length+= t_length;
_ma_store_page_used(info, anc_buff, new_anc_length);
/* Store first key on new page */
if (nod_flag)
@ -1082,9 +1082,9 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
bmove(leaf_buff+p_length+t_length, half_pos, (size_t) length);
(*keyinfo->store_key)(keyinfo,leaf_buff+p_length, &key_inserted);
new_leaf_length= length + t_length + p_length;
_ma_store_page_used(info, leaf_buff, new_leaf_length, nod_flag);
_ma_store_page_used(info, leaf_buff, new_leaf_length);
new_buff_length= (uint) (endpos - buff);
_ma_store_page_used(info, buff, new_buff_length, nod_flag);
_ma_store_page_used(info, buff, new_buff_length);
if (info->s->now_transactional)
{
@ -1099,7 +1099,7 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
if (_ma_log_add(info, anc_page, anc_buff, anc_length,
keypos,
anc_key_inserted.move_length +
min(anc_key_inserted.changed_length -
max(anc_key_inserted.changed_length -
anc_key_inserted.move_length,
key_deleted.changed_length),
anc_key_inserted.move_length -
@ -1136,7 +1136,7 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
if (_ma_write_keypage(info, keyinfo, next_page,
PAGECACHE_LOCK_LEFT_WRITELOCKED, DFLT_INIT_HITS, buff))
goto err;
DBUG_RETURN(anc_length <= (uint)
DBUG_RETURN(new_anc_length <= (uint)
(keyinfo->block_length - KEYPAGE_CHECKSUM_SIZE)/2);
err:
@ -1262,6 +1262,7 @@ static uint remove_key(MARIA_KEYDEF *keyinfo, uint nod_flag,
uint pack_length;
uint diff= (next_length-prev_length);
/* keypos points to data of next key (after key length) */
bmove(keypos - diff, lastkey + prev_length, diff);
rest_length+= diff;
pack_length= prev_length ? get_pack_length(rest_length): 0;
@ -1323,14 +1324,15 @@ static my_bool _ma_log_delete(MARIA_HA *info, my_off_t page, uchar *buff,
uint move_length)
{
LSN lsn;
uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 9], *log_pos;
LEX_STRING log_array[TRANSLOG_INTERNAL_PARTS + 2];
uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 9 + 7], *log_pos;
LEX_STRING log_array[TRANSLOG_INTERNAL_PARTS + 3];
uint translog_parts;
uint offset= (uint) (key_pos - buff);
DBUG_ENTER("_ma_log_delete");
DBUG_PRINT("enter", ("page: %lu changed_length: %u move_length: %d",
(ulong) page, changed_length, move_length));
DBUG_ASSERT(info->s->now_transactional && move_length);
DBUG_ASSERT(offset + changed_length <= _ma_get_page_used(info, buff));
/* Store address of new root page */
page/= info->s->block_size;
@ -1352,6 +1354,22 @@ static my_bool _ma_log_delete(MARIA_HA *info, my_off_t page, uchar *buff,
log_array[TRANSLOG_INTERNAL_PARTS + 1].length= changed_length;
}
#ifdef EXTRA_DEBUG_KEY_CHANGES
{
int page_length= _ma_get_page_used(info, buff);
ha_checksum crc;
crc= my_checksum(0, buff + LSN_STORE_SIZE, page_length - LSN_STORE_SIZE);
log_pos[0]= KEY_OP_CHECK;
int2store(log_pos+1, page_length);
int4store(log_pos+3, crc);
log_array[TRANSLOG_INTERNAL_PARTS + translog_parts].str= log_pos;
log_array[TRANSLOG_INTERNAL_PARTS + translog_parts].length= 7;
changed_length+= 7;
translog_parts++;
}
#endif
log_array[TRANSLOG_INTERNAL_PARTS + 0].str= (char*) log_data;
log_array[TRANSLOG_INTERNAL_PARTS + 0].length= (uint) (log_pos - log_data);

View File

@ -1801,7 +1801,7 @@ int _ma_read_rnd_dynamic_record(MARIA_HA *info,
if (my_read(info->dfile.file, (uchar*)to, block_info.data_len,
MYF(MY_NABP)))
{
if (my_errno == -1)
if (my_errno == HA_ERR_FILE_TOO_SHORT)
my_errno= HA_ERR_WRONG_IN_RECORD; /* Unexpected end of file */
goto err;
}

View File

@ -330,7 +330,7 @@ uint _ma_ft_convert_to_ft2(MARIA_HA *info, uint keynr, uchar *key)
/* creating pageful of keys */
bzero(info->buff, info->s->keypage_header);
_ma_store_keynr(info, info->buff, keynr);
_ma_store_page_used(info, info->buff, length + info->s->keypage_header, 0);
_ma_store_page_used(info, info->buff, length + info->s->keypage_header);
memcpy(info->buff + info->s->keypage_header, key_ptr, length);
info->keyread_buff_used= info->page_changed=1; /* info->buff is used */
if ((root= _ma_new(info, DFLT_INIT_HITS, &page_link)) == HA_OFFSET_ERROR ||

View File

@ -206,8 +206,8 @@ my_bool _ma_log_prefix(MARIA_HA *info, my_off_t page,
{
uint translog_parts;
LSN lsn;
uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 7], *log_pos;
LEX_STRING log_array[TRANSLOG_INTERNAL_PARTS + 2];
uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 7 + 7], *log_pos;
LEX_STRING log_array[TRANSLOG_INTERNAL_PARTS + 3];
DBUG_ENTER("_ma_log_prefix");
DBUG_PRINT("enter", ("page: %lu changed_length: %u move_length: %d",
(ulong) page, changed_length, move_length));
@ -223,7 +223,6 @@ my_bool _ma_log_prefix(MARIA_HA *info, my_off_t page,
log_pos[0]= KEY_OP_DEL_PREFIX;
int2store(log_pos+1, -move_length);
log_pos+= 3;
translog_parts= 1;
if (changed_length)
{
/*
@ -244,6 +243,8 @@ my_bool _ma_log_prefix(MARIA_HA *info, my_off_t page,
int2store(log_pos+3, changed_length);
log_pos+= 5;
}
translog_parts= 1;
log_array[TRANSLOG_INTERNAL_PARTS + 0].str= log_data;
log_array[TRANSLOG_INTERNAL_PARTS + 0].length= (uint) (log_pos -
log_data);
@ -255,6 +256,22 @@ my_bool _ma_log_prefix(MARIA_HA *info, my_off_t page,
translog_parts= 2;
}
#ifdef EXTRA_DEBUG_KEY_CHANGES
{
int page_length= _ma_get_page_used(info, buff);
ha_checksum crc;
crc= my_checksum(0, buff + LSN_STORE_SIZE, page_length - LSN_STORE_SIZE);
log_pos[0]= KEY_OP_CHECK;
int2store(log_pos+1, page_length);
int4store(log_pos+3, crc);
log_array[TRANSLOG_INTERNAL_PARTS + translog_parts].str= log_pos;
log_array[TRANSLOG_INTERNAL_PARTS + translog_parts].length= 7;
changed_length+= 7;
translog_parts++;
}
#endif
DBUG_RETURN(translog_write_record(&lsn, LOGREC_REDO_INDEX,
info->trn, info,
log_array[TRANSLOG_INTERNAL_PARTS +
@ -273,8 +290,8 @@ my_bool _ma_log_suffix(MARIA_HA *info, my_off_t page,
uchar *buff, uint org_length, uint new_length)
{
LSN lsn;
LEX_STRING log_array[TRANSLOG_INTERNAL_PARTS + 2];
uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 10], *log_pos;
LEX_STRING log_array[TRANSLOG_INTERNAL_PARTS + 3];
uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 10 + 7], *log_pos;
int diff;
uint translog_parts, extra_length;
DBUG_ENTER("_ma_log_suffix");
@ -305,10 +322,26 @@ my_bool _ma_log_suffix(MARIA_HA *info, my_off_t page,
translog_parts= 2;
extra_length= (uint) diff;
}
log_array[TRANSLOG_INTERNAL_PARTS + 0].str= log_data;
log_array[TRANSLOG_INTERNAL_PARTS + 0].length= (uint) (log_pos -
log_data);
#ifdef EXTRA_DEBUG_KEY_CHANGES
{
ha_checksum crc;
crc= my_checksum(0, buff + LSN_STORE_SIZE, new_length - LSN_STORE_SIZE);
log_pos[0]= KEY_OP_CHECK;
int2store(log_pos+1, new_length);
int4store(log_pos+3, crc);
log_array[TRANSLOG_INTERNAL_PARTS + translog_parts].str= log_pos;
log_array[TRANSLOG_INTERNAL_PARTS + translog_parts].length= 7;
extra_length+= 7;
translog_parts++;
}
#endif
DBUG_RETURN(translog_write_record(&lsn, LOGREC_REDO_INDEX,
info->trn, info,
log_array[TRANSLOG_INTERNAL_PARTS +
@ -321,6 +354,9 @@ my_bool _ma_log_suffix(MARIA_HA *info, my_off_t page,
/**
@brief Log that a key was added to the page
@param buff Page buffer
@param buff_length Original length of buff (before key was added)
@note
If handle_overflow is set, then we have to protect against
logging changes that is outside of the page.
@ -334,12 +370,14 @@ my_bool _ma_log_add(MARIA_HA *info, my_off_t page, uchar *buff,
my_bool handle_overflow __attribute__ ((unused)))
{
LSN lsn;
uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 3+ 3 + 3 + 3], *log_pos;
LEX_STRING log_array[TRANSLOG_INTERNAL_PARTS + 2];
uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 3 + 3 + 3 + 3 + 7];
uchar *log_pos;
LEX_STRING log_array[TRANSLOG_INTERNAL_PARTS + 3];
uint offset= (uint) (key_pos - buff);
uint page_length= info->s->block_size - KEYPAGE_CHECKSUM_SIZE;
uint translog_parts;
DBUG_ENTER("_ma_log_add");
DBUG_PRINT("enter", ("page: %lu page_length: %u changed_length: %u "
DBUG_PRINT("enter", ("page: %lu org_page_length: %u changed_length: %u "
"move_length: %d",
(ulong) page, buff_length, changed_length,
move_length));
@ -394,6 +432,7 @@ my_bool _ma_log_add(MARIA_HA *info, my_off_t page, uchar *buff,
}
int2store(log_pos+1, changed_length);
log_pos+= 3;
translog_parts= 2;
log_array[TRANSLOG_INTERNAL_PARTS + 0].str= log_data;
log_array[TRANSLOG_INTERNAL_PARTS + 0].length= (uint) (log_pos -
@ -401,12 +440,31 @@ my_bool _ma_log_add(MARIA_HA *info, my_off_t page, uchar *buff,
log_array[TRANSLOG_INTERNAL_PARTS + 1].str= key_pos;
log_array[TRANSLOG_INTERNAL_PARTS + 1].length= changed_length;
#ifdef EXTRA_DEBUG_KEY_CHANGES
{
ha_checksum crc;
uint save_page_length= _ma_get_page_used(info, buff);
uint new_length= buff_length + move_length;
_ma_store_page_used(info, buff, new_length);
crc= my_checksum(0, buff + LSN_STORE_SIZE, new_length - LSN_STORE_SIZE);
log_pos[0]= KEY_OP_CHECK;
int2store(log_pos+1, new_length);
int4store(log_pos+3, crc);
log_array[TRANSLOG_INTERNAL_PARTS + translog_parts].str= log_pos;
log_array[TRANSLOG_INTERNAL_PARTS + translog_parts].length= 7;
changed_length+= 7;
translog_parts++;
_ma_store_page_used(info, buff, save_page_length);
}
#endif
if (translog_write_record(&lsn, LOGREC_REDO_INDEX,
info->trn, info,
log_array[TRANSLOG_INTERNAL_PARTS +
0].length + changed_length,
TRANSLOG_INTERNAL_PARTS + 2, log_array,
log_data, NULL))
TRANSLOG_INTERNAL_PARTS + translog_parts,
log_array, log_data, NULL))
DBUG_RETURN(-1);
DBUG_RETURN(0);
}
@ -627,11 +685,15 @@ err:
KEY_OP_ADD_SUFFIX 2 length, data Add data to end of page
KEY_OP_DEL_SUFFIX 2 length Reduce page length with this
Sets position to start of page
KEY_OP_CHECK 6 page_length[2},CRC Used only when debugging
@return Operation status
@retval 0 OK
@retval 1 Error
*/
long my_counter= 0;
uint _ma_apply_redo_index(MARIA_HA *info,
LSN lsn, const uchar *header, uint head_length)
{
@ -674,12 +736,12 @@ uint _ma_apply_redo_index(MARIA_HA *info,
do
{
switch ((enum en_key_op) (*header++)) {
case KEY_OP_OFFSET:
case KEY_OP_OFFSET: /* 1 */
page_offset= uint2korr(header);
header+= 2;
DBUG_ASSERT(page_offset >= keypage_header && page_offset <= page_length);
break;
case KEY_OP_SHIFT:
case KEY_OP_SHIFT: /* 2 */
{
int length= sint2korr(header);
header+= 2;
@ -695,7 +757,7 @@ uint _ma_apply_redo_index(MARIA_HA *info,
page_length+= length;
break;
}
case KEY_OP_CHANGE:
case KEY_OP_CHANGE: /* 3 */
{
uint length= uint2korr(header);
DBUG_ASSERT(page_offset != 0 && page_offset + length <= page_length);
@ -704,7 +766,7 @@ uint _ma_apply_redo_index(MARIA_HA *info,
header+= 2 + length;
break;
}
case KEY_OP_ADD_PREFIX:
case KEY_OP_ADD_PREFIX: /* 4 */
{
uint insert_length= uint2korr(header);
uint changed_length= uint2korr(header+2);
@ -718,7 +780,7 @@ uint _ma_apply_redo_index(MARIA_HA *info,
page_length+= insert_length;
break;
}
case KEY_OP_DEL_PREFIX:
case KEY_OP_DEL_PREFIX: /* 5 */
{
uint length= uint2korr(header);
header+= 2;
@ -731,7 +793,7 @@ uint _ma_apply_redo_index(MARIA_HA *info,
page_offset= keypage_header; /* Prepare for change */
break;
}
case KEY_OP_ADD_SUFFIX:
case KEY_OP_ADD_SUFFIX: /* 6 */
{
uint insert_length= uint2korr(header);
DBUG_ASSERT(page_length + insert_length <= share->block_size);
@ -741,7 +803,7 @@ uint _ma_apply_redo_index(MARIA_HA *info,
header+= 2 + insert_length;
break;
}
case KEY_OP_DEL_SUFFIX:
case KEY_OP_DEL_SUFFIX: /* 7 */
{
uint del_length= uint2korr(header);
header+= 2;
@ -749,6 +811,21 @@ uint _ma_apply_redo_index(MARIA_HA *info,
page_length-= del_length;
break;
}
case KEY_OP_CHECK: /* 8 */
#ifdef EXTRA_DEBUG_KEY_CHANGES
{
uint check_page_length;
ha_checksum crc;
check_page_length= uint2korr(header);
crc= uint4korr(header+2);
_ma_store_page_used(info, buff, page_length);
DBUG_ASSERT(check_page_length == page_length);
DBUG_ASSERT(crc == (uint32) my_checksum(0, buff + LSN_STORE_SIZE,
page_length- LSN_STORE_SIZE));
#endif
header+= 6;
break;
}
case KEY_OP_NONE:
default:
DBUG_ASSERT(0);
@ -759,7 +836,7 @@ uint _ma_apply_redo_index(MARIA_HA *info,
DBUG_ASSERT(header == header_end);
/* Write modified page */
_ma_store_page_used(info, buff, page_length, nod_flag);
_ma_store_page_used(info, buff, page_length);
/*
Clean old stuff up. Gives us better compression of we archive things
@ -768,15 +845,6 @@ uint _ma_apply_redo_index(MARIA_HA *info,
if (page_length < org_page_length)
bzero(buff + page_length, org_page_length-page_length);
result= 0;
if (pagecache_write(share->pagecache,
&info->s->kfile, page, 0,
buff, PAGECACHE_PLAIN_PAGE,
PAGECACHE_LOCK_LEFT_WRITELOCKED,
PAGECACHE_PIN_LEFT_PINNED,
PAGECACHE_WRITE_DELAY, 0, LSN_IMPOSSIBLE))
result= 1;
/* Mark page to be unlocked and written at _ma_unpin_all_pages() */
page_link.unlock= PAGECACHE_LOCK_WRITE_UNLOCK;
page_link.changed= 1;

View File

@ -389,8 +389,8 @@ int _ma_readinfo(register MARIA_HA *info __attribute__ ((unused)),
/* should not be done for transactional tables */
if (_ma_state_info_read_dsk(share->kfile.file, &share->state))
{
int error=my_errno ? my_errno : -1;
my_errno=error;
if (!my_errno)
my_errno= HA_ERR_FILE_TOO_SHORT;
DBUG_RETURN(1);
}
}

View File

@ -548,7 +548,7 @@ static LOG_DESC INIT_LOGREC_REDO_DELETE_ALL=
"redo_delete_all", LOGREC_IS_GROUP_ITSELF, NULL, NULL};
static LOG_DESC INIT_LOGREC_REDO_REPAIR_TABLE=
{LOGRECTYPE_FIXEDLENGTH, FILEID_STORE_SIZE + 4, FILEID_STORE_SIZE + 4,
{LOGRECTYPE_FIXEDLENGTH, FILEID_STORE_SIZE + 4 + 8, FILEID_STORE_SIZE + 4 + 8,
NULL, NULL, NULL, 0,
"redo_repair_table", LOGREC_IS_GROUP_ITSELF, NULL, NULL};

View File

@ -155,6 +155,7 @@ enum en_key_op
KEY_OP_DEL_PREFIX, /* Delete data at start of page */
KEY_OP_ADD_SUFFIX, /* Insert data at end of page */
KEY_OP_DEL_SUFFIX, /* Delete data at end of page */
KEY_OP_CHECK /* For debugging; CRC of used part of page */
};
/* Size of log file; One log file is restricted to 4G */

View File

@ -121,6 +121,10 @@ static MARIA_HA *maria_clone_internal(MARIA_SHARE *share, int mode,
&info.first_mbr_key, share->base.max_key_length,
&info.maria_rtree_recursion_state,
share->have_rtree ? 1024 : 0,
&info.key_write_undo_lsn,
(uint) (sizeof(LSN) * share->base.keys),
&info.key_delete_undo_lsn,
(uint) (sizeof(LSN) * share->base.keys),
&changed_fields_bitmap,
bitmap_buffer_size(share->base.fields),
NullS))

View File

@ -44,7 +44,6 @@
#include "ma_pagecache.h"
#include <my_bit.h>
#include <errno.h>
#include <stdarg.h>
/*
Some compilation flags have been added specifically for this module
@ -95,7 +94,7 @@
#define PCBLOCK_INFO(B) \
DBUG_PRINT("info", \
("block: 0x%lx file: %lu page: %lu s: %0x hshL: 0x%lx req: %u/%u " \
("block: 0x%lx fd: %lu page: %lu s: %0x hshL: 0x%lx req: %u/%u " \
"wrlocks: %u pins: %u", \
(ulong)(B), \
(ulong)((B)->hash_link ? \
@ -671,6 +670,8 @@ static inline uint next_power(uint value)
division_limit division limit (may be zero)
age_threshold age threshold (may be zero)
block_size size of block (should be power of 2)
my_read_flags Flags used for all pread/pwrite calls
Usually MY_WME in case of recovery
RETURN VALUE
number of blocks in the key cache, if successful,
@ -688,7 +689,7 @@ static inline uint next_power(uint value)
ulong init_pagecache(PAGECACHE *pagecache, size_t use_mem,
uint division_limit, uint age_threshold,
uint block_size)
uint block_size, myf my_readwrite_flags)
{
ulong blocks, hash_links, length;
int error;
@ -721,8 +722,8 @@ ulong init_pagecache(PAGECACHE *pagecache, size_t use_mem,
pagecache->mem_size= use_mem;
pagecache->block_size= block_size;
pagecache->shift= my_bit_log2(block_size);
DBUG_PRINT("info", ("block_size: %u",
block_size));
pagecache->readwrite_flags= my_readwrite_flags | MY_NABP | MY_WAIT_IF_FULL;
DBUG_PRINT("info", ("block_size: %u", block_size));
DBUG_ASSERT(((uint)(1 << pagecache->shift)) == block_size);
blocks= (ulong) (use_mem / (sizeof(PAGECACHE_BLOCK_LINK) +
@ -733,102 +734,99 @@ ulong init_pagecache(PAGECACHE *pagecache, size_t use_mem,
We need to support page cache with just one block to be able to do
scanning of rows-in-block files
*/
if (blocks >= 1)
for ( ; ; )
{
for ( ; ; )
if (blocks < 8)
{
if (blocks < 8)
{
my_errno= ENOMEM;
goto err;
}
/* Set my_hash_entries to the next bigger 2 power */
if ((pagecache->hash_entries= next_power(blocks)) <
(blocks) * 5/4)
pagecache->hash_entries<<= 1;
hash_links= 2 * blocks;
#if defined(MAX_THREADS)
if (hash_links < MAX_THREADS + blocks - 1)
hash_links= MAX_THREADS + blocks - 1;
#endif
while ((length= (ALIGN_SIZE(blocks * sizeof(PAGECACHE_BLOCK_LINK)) +
ALIGN_SIZE(hash_links * sizeof(PAGECACHE_HASH_LINK)) +
ALIGN_SIZE(sizeof(PAGECACHE_HASH_LINK*) *
pagecache->hash_entries))) +
(blocks << pagecache->shift) > use_mem)
blocks--;
/* Allocate memory for cache page buffers */
if ((pagecache->block_mem=
my_large_malloc((ulong) blocks * pagecache->block_size,
MYF(MY_WME))))
{
/*
Allocate memory for blocks, hash_links and hash entries;
For each block 2 hash links are allocated
*/
if ((pagecache->block_root=
(PAGECACHE_BLOCK_LINK*) my_malloc((size_t) length, MYF(0))))
break;
my_large_free(pagecache->block_mem, MYF(0));
pagecache->block_mem= 0;
}
blocks= blocks / 4*3;
my_errno= ENOMEM;
goto err;
}
pagecache->blocks_unused= blocks;
pagecache->disk_blocks= (long) blocks;
pagecache->hash_links= hash_links;
pagecache->hash_root=
(PAGECACHE_HASH_LINK**) ((char*) pagecache->block_root +
ALIGN_SIZE(blocks*sizeof(PAGECACHE_BLOCK_LINK)));
pagecache->hash_link_root=
(PAGECACHE_HASH_LINK*) ((char*) pagecache->hash_root +
ALIGN_SIZE((sizeof(PAGECACHE_HASH_LINK*) *
pagecache->hash_entries)));
bzero((uchar*) pagecache->block_root,
pagecache->disk_blocks * sizeof(PAGECACHE_BLOCK_LINK));
bzero((uchar*) pagecache->hash_root,
pagecache->hash_entries * sizeof(PAGECACHE_HASH_LINK*));
bzero((uchar*) pagecache->hash_link_root,
pagecache->hash_links * sizeof(PAGECACHE_HASH_LINK));
pagecache->hash_links_used= 0;
pagecache->free_hash_list= NULL;
pagecache->blocks_used= pagecache->blocks_changed= 0;
pagecache->global_blocks_changed= 0;
pagecache->blocks_available=0; /* For debugging */
/* The LRU chain is empty after initialization */
pagecache->used_last= NULL;
pagecache->used_ins= NULL;
pagecache->free_block_list= NULL;
pagecache->time= 0;
pagecache->warm_blocks= 0;
pagecache->min_warm_blocks= (division_limit ?
blocks * division_limit / 100 + 1 :
blocks);
pagecache->age_threshold= (age_threshold ?
blocks * age_threshold / 100 :
blocks);
pagecache->cnt_for_resize_op= 0;
pagecache->resize_in_flush= 0;
pagecache->can_be_used= 1;
pagecache->waiting_for_hash_link.last_thread= NULL;
pagecache->waiting_for_block.last_thread= NULL;
DBUG_PRINT("exit",
("disk_blocks: %ld block_root: 0x%lx hash_entries: %ld\
hash_root: 0x%lx hash_links: %ld hash_link_root: 0x%lx",
pagecache->disk_blocks, (long) pagecache->block_root,
pagecache->hash_entries, (long) pagecache->hash_root,
pagecache->hash_links, (long) pagecache->hash_link_root));
bzero((uchar*) pagecache->changed_blocks,
sizeof(pagecache->changed_blocks[0]) *
PAGECACHE_CHANGED_BLOCKS_HASH);
bzero((uchar*) pagecache->file_blocks,
sizeof(pagecache->file_blocks[0]) *
PAGECACHE_CHANGED_BLOCKS_HASH);
/* Set my_hash_entries to the next bigger 2 power */
if ((pagecache->hash_entries= next_power(blocks)) <
(blocks) * 5/4)
pagecache->hash_entries<<= 1;
hash_links= 2 * blocks;
#if defined(MAX_THREADS)
if (hash_links < MAX_THREADS + blocks - 1)
hash_links= MAX_THREADS + blocks - 1;
#endif
while ((length= (ALIGN_SIZE(blocks * sizeof(PAGECACHE_BLOCK_LINK)) +
ALIGN_SIZE(hash_links * sizeof(PAGECACHE_HASH_LINK)) +
ALIGN_SIZE(sizeof(PAGECACHE_HASH_LINK*) *
pagecache->hash_entries))) +
(blocks << pagecache->shift) > use_mem)
blocks--;
/* Allocate memory for cache page buffers */
if ((pagecache->block_mem=
my_large_malloc((ulong) blocks * pagecache->block_size,
MYF(MY_WME))))
{
/*
Allocate memory for blocks, hash_links and hash entries;
For each block 2 hash links are allocated
*/
if ((pagecache->block_root=
(PAGECACHE_BLOCK_LINK*) my_malloc((size_t) length, MYF(0))))
break;
my_large_free(pagecache->block_mem, MYF(0));
pagecache->block_mem= 0;
}
blocks= blocks / 4*3;
}
pagecache->blocks_unused= blocks;
pagecache->disk_blocks= (long) blocks;
pagecache->hash_links= hash_links;
pagecache->hash_root=
(PAGECACHE_HASH_LINK**) ((char*) pagecache->block_root +
ALIGN_SIZE(blocks*sizeof(PAGECACHE_BLOCK_LINK)));
pagecache->hash_link_root=
(PAGECACHE_HASH_LINK*) ((char*) pagecache->hash_root +
ALIGN_SIZE((sizeof(PAGECACHE_HASH_LINK*) *
pagecache->hash_entries)));
bzero((uchar*) pagecache->block_root,
pagecache->disk_blocks * sizeof(PAGECACHE_BLOCK_LINK));
bzero((uchar*) pagecache->hash_root,
pagecache->hash_entries * sizeof(PAGECACHE_HASH_LINK*));
bzero((uchar*) pagecache->hash_link_root,
pagecache->hash_links * sizeof(PAGECACHE_HASH_LINK));
pagecache->hash_links_used= 0;
pagecache->free_hash_list= NULL;
pagecache->blocks_used= pagecache->blocks_changed= 0;
pagecache->global_blocks_changed= 0;
pagecache->blocks_available=0; /* For debugging */
/* The LRU chain is empty after initialization */
pagecache->used_last= NULL;
pagecache->used_ins= NULL;
pagecache->free_block_list= NULL;
pagecache->time= 0;
pagecache->warm_blocks= 0;
pagecache->min_warm_blocks= (division_limit ?
blocks * division_limit / 100 + 1 :
blocks);
pagecache->age_threshold= (age_threshold ?
blocks * age_threshold / 100 :
blocks);
pagecache->cnt_for_resize_op= 0;
pagecache->resize_in_flush= 0;
pagecache->can_be_used= 1;
pagecache->waiting_for_hash_link.last_thread= NULL;
pagecache->waiting_for_block.last_thread= NULL;
DBUG_PRINT("exit",
("disk_blocks: %ld block_root: 0x%lx hash_entries: %ld\
hash_root: 0x%lx hash_links: %ld hash_link_root: 0x%lx",
pagecache->disk_blocks, (long) pagecache->block_root,
pagecache->hash_entries, (long) pagecache->hash_root,
pagecache->hash_links, (long) pagecache->hash_link_root));
bzero((uchar*) pagecache->changed_blocks,
sizeof(pagecache->changed_blocks[0]) *
PAGECACHE_CHANGED_BLOCKS_HASH);
bzero((uchar*) pagecache->file_blocks,
sizeof(pagecache->file_blocks[0]) *
PAGECACHE_CHANGED_BLOCKS_HASH);
pagecache->blocks= pagecache->disk_blocks > 0 ? pagecache->disk_blocks : 0;
DBUG_RETURN((ulong) pagecache->disk_blocks);
@ -981,7 +979,8 @@ ulong resize_pagecache(PAGECACHE *pagecache,
end_pagecache(pagecache, 0); /* Don't free mutex */
/* The following will work even if use_mem is 0 */
blocks= init_pagecache(pagecache, pagecache->block_size, use_mem,
division_limit, age_threshold);
division_limit, age_threshold,
pagecache->readwrite_flags);
finish:
#ifdef THREAD
@ -2020,7 +2019,7 @@ restart:
block->buffer,
block->hash_link->pageno,
block->type,
MYF(MY_NABP | MY_WAIT_IF_FULL));
pagecache->readwrite_flags);
pagecache_pthread_mutex_lock(&pagecache->cache_lock);
pagecache->global_cache_write++;
}
@ -2417,13 +2416,13 @@ static void read_block(PAGECACHE *pagecache,
pagecache_disk_read_validator validator,
uchar* validator_data)
{
uint got_length;
/* On entry cache_lock is locked */
DBUG_ENTER("read_block");
if (primary)
{
size_t error;
/*
This code is executed only by threads
that submitted primary requests
@ -2438,11 +2437,12 @@ static void read_block(PAGECACHE *pagecache,
Here other threads may step in and register as secondary readers.
They will register in block->wqueue[COND_FOR_REQUESTED].
*/
got_length= pagecache_fread(pagecache, &block->hash_link->file,
block->buffer,
block->hash_link->pageno, MYF(0));
error= pagecache_fread(pagecache, &block->hash_link->file,
block->buffer,
block->hash_link->pageno,
pagecache->readwrite_flags);
pagecache_pthread_mutex_lock(&pagecache->cache_lock);
if (got_length < pagecache->block_size)
if (error)
block->status|= PCBLOCK_ERROR;
else
block->status= PCBLOCK_READ;
@ -2796,7 +2796,6 @@ void pagecache_unlock_by_link(PAGECACHE *pagecache,
block->status&= ~PCBLOCK_DIRECT_W;
DBUG_PRINT("info", ("Drop PCBLOCK_DIRECT_W for block: 0x%lx",
(ulong) block));
}
if (make_lock_and_pin(pagecache, block, lock, pin, 0))
@ -2996,10 +2995,6 @@ restart:
DBUG_PRINT("info", ("read is done"));
}
/* PCBLOCK_DIRECT_W should be unlocked in unlock */
DBUG_ASSERT((block->status & PCBLOCK_DIRECT_W) == 0 ||
lock == PAGECACHE_LOCK_LEFT_WRITELOCKED);
if (make_lock_and_pin(pagecache, block, lock, pin, file))
{
/*
@ -3069,7 +3064,8 @@ no_key_cache: /* Key cache is not used */
/* We can't use mutex here as the key cache may not be initialized */
pagecache->global_cache_r_requests++;
pagecache->global_cache_read++;
if (pagecache_fread(pagecache, file, (uchar*) buff, pageno, MYF(MY_NABP)))
if (pagecache_fread(pagecache, file, (uchar*) buff, pageno,
pagecache->readwrite_flags))
error= 1;
DBUG_RETURN(error ? (uchar*) 0 : buff);
}
@ -3169,7 +3165,7 @@ restart:
block->buffer,
block->hash_link->pageno,
block->type,
MYF(MY_NABP | MY_WAIT_IF_FULL));
pagecache->readwrite_flags);
pagecache_pthread_mutex_lock(&pagecache->cache_lock);
pagecache->global_cache_write++;
@ -3494,7 +3490,7 @@ no_key_cache:
pagecache->global_cache_w_requests++;
pagecache->global_cache_write++;
if (pagecache_fwrite(pagecache, file, (uchar*) buff, pageno, type,
MYF(MY_NABP | MY_WAIT_IF_FULL)))
pagecache->readwrite_flags))
error=1;
}
@ -3662,7 +3658,7 @@ static int flush_cached_blocks(PAGECACHE *pagecache,
block->buffer,
block->hash_link->pageno,
block->type,
MYF(MY_NABP | MY_WAIT_IF_FULL));
pagecache->readwrite_flags);
pagecache_pthread_mutex_lock(&pagecache->cache_lock);
make_lock_and_pin(pagecache, block,
@ -3744,7 +3740,7 @@ static int flush_pagecache_blocks_int(PAGECACHE *pagecache,
int rc= PCFLUSH_OK;
DBUG_ENTER("flush_pagecache_blocks_int");
DBUG_PRINT("enter",
("file: %d blocks_used: %lu blocks_changed: %lu type: %d",
("fd: %d blocks_used: %lu blocks_changed: %lu type: %d",
file->file, pagecache->blocks_used, pagecache->blocks_changed,
type));

View File

@ -158,7 +158,8 @@ typedef struct st_pagecache
ulonglong global_cache_r_requests;/* number of read requests (read hits) */
ulonglong global_cache_read; /* number of reads from files to cache */
uint shift; /* block size = 2 ^ shift */
uint shift; /* block size = 2 ^ shift */
myf readwrite_flags; /* Flags to pread/pwrite() */
my_bool inited;
my_bool resize_in_flush; /* true during flush of resize operation */
my_bool can_be_used; /* usage of cache for read/write is allowed */
@ -183,7 +184,7 @@ extern PAGECACHE dflt_pagecache_var, *dflt_pagecache;
extern ulong init_pagecache(PAGECACHE *pagecache, size_t use_mem,
uint division_limit, uint age_threshold,
uint block_size);
uint block_size, myf my_read_flags);
extern ulong resize_pagecache(PAGECACHE *pagecache,
size_t use_mem, uint division_limit,
uint age_threshold);

View File

@ -58,6 +58,7 @@ static FILE *tracef; /**< trace file for debugging */
static my_bool skip_DDLs; /**< if REDO phase should skip DDL records */
/** @brief to avoid writing a checkpoint if recovery did nothing. */
static my_bool checkpoint_useful;
static my_bool procent_printed;
static ulonglong now; /**< for tracking execution time of phases */
uint warnings; /**< count of warnings */
@ -156,10 +157,36 @@ void tprint(FILE *trace_file __attribute__ ((unused)),
va_list args;
va_start(args, format);
if (trace_file != NULL)
{
if (procent_printed)
{
procent_printed= 0;
fputc('\n', trace_file ? trace_file : stderr);
}
vfprintf(trace_file, format, args);
}
va_end(args);
}
void eprint(FILE *trace_file, const char *format, ...)
ATTRIBUTE_FORMAT(printf, 2, 3);
void eprint(FILE *trace_file __attribute__ ((unused)),
const char *format __attribute__ ((unused)), ...)
{
va_list args;
va_start(args, format);
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);
}
vfprintf(trace_file ? trace_file : stderr, format, args);
va_end(args);
}
#define ALERT_USER() DBUG_ASSERT(0)
static void print_preamble()
@ -312,6 +339,7 @@ int maria_apply_log(LSN from_lsn, enum maria_apply_log_way apply,
Detailed progress info goes to stderr, because ma_message_no_user()
cannot put several messages on one line.
*/
procent_printed= 1;
fprintf(stderr, " (%.1f seconds); ", phase_took);
}
@ -353,6 +381,7 @@ int maria_apply_log(LSN from_lsn, enum maria_apply_log_way apply,
if (recovery_message_printed == REC_MSG_UNDO)
{
float phase_took= (now - old_now)/10000000.0;
procent_printed= 1;
fprintf(stderr, " (%.1f seconds); ", phase_took);
}
@ -368,6 +397,7 @@ int maria_apply_log(LSN from_lsn, enum maria_apply_log_way apply,
if (recovery_message_printed == REC_MSG_FLUSH)
{
float phase_took= (now - old_now)/10000000.0;
procent_printed= 1;
fprintf(stderr, " (%.1f seconds); ", phase_took);
}
@ -381,7 +411,7 @@ int maria_apply_log(LSN from_lsn, enum maria_apply_log_way apply,
goto end;
err:
error= 1;
tprint(tracef, "Recovery of tables with transaction logs FAILED\n");
tprint(tracef, "\nRecovery of tables with transaction logs FAILED\n");
end:
hash_free(&all_dirty_pages);
bzero(&all_dirty_pages, sizeof(all_dirty_pages));
@ -404,6 +434,7 @@ end:
else
ma_message_no_user(ME_JUST_INFO, "recovery done");
}
procent_printed= 0;
/* we don't cleanly close tables if we hit some error (may corrupt them) */
DBUG_RETURN(error);
}
@ -418,7 +449,8 @@ static void display_record_position(const LOG_DESC *log_desc,
if number==0, we're going over records which we had already seen and which
form a group, so we indent below the group's end record
*/
tprint(tracef, "%sRec#%u LSN (%lu,0x%lx) short_trid %u %s(num_type:%u) len %lu\n",
tprint(tracef,
"%sRec#%u LSN (%lu,0x%lx) short_trid %u %s(num_type:%u) len %lu\n",
number ? "" : " ", number, LSN_IN_PARTS(rec->lsn),
rec->short_trid, log_desc->name, rec->type,
(ulong)rec->record_length);
@ -436,7 +468,7 @@ static int display_and_apply_record(const LOG_DESC *log_desc,
return 1;
}
if ((error= (*log_desc->record_execute_in_redo_phase)(rec)))
tprint(tracef, "Got error when executing record\n");
eprint(tracef, "Got error %d when executing record\n", my_errno);
return error;
}
@ -467,10 +499,10 @@ prototype_redo_exec_hook(LONG_TRANSACTION_ID)
{
char llbuf[22];
llstr(long_trid, llbuf);
tprint(tracef, "Found an old transaction long_trid %s short_trid %u"
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", llbuf,
sid, LSN_IN_PARTS(ulsn));
" committed nor rollback (undo_lsn: (%lu,0x%lx))\n",
llbuf, sid, LSN_IN_PARTS(ulsn));
goto err;
}
}
@ -570,11 +602,10 @@ prototype_redo_exec_hook(REDO_CREATE_TABLE)
log_record_buffer.str, NULL) !=
rec->record_length)
{
tprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record\n");
goto end;
}
name= log_record_buffer.str;
tprint(tracef, "Table '%s'", name);
/*
TRUNCATE TABLE and REPAIR USE_FRM call maria_create(), so below we can
find a REDO_CREATE_TABLE for a table which we have open, that's why we
@ -582,7 +613,7 @@ prototype_redo_exec_hook(REDO_CREATE_TABLE)
*/
if (close_one_table(name, rec->lsn))
{
tprint(tracef, " got error %d on close\n", my_errno);
eprint(tracef, "Table '%s' got error %d on close\n", name, my_errno);
ALERT_USER();
goto end;
}
@ -594,7 +625,8 @@ prototype_redo_exec_hook(REDO_CREATE_TABLE)
/* check that we're not already using it */
if (share->reopen != 1)
{
tprint(tracef, ", is already open (reopen=%u)\n", share->reopen);
eprint(tracef, "Table '%s is already open (reopen=%u)\n",
name, share->reopen);
ALERT_USER();
goto end;
}
@ -606,22 +638,23 @@ prototype_redo_exec_hook(REDO_CREATE_TABLE)
one was renamed to its name, thus create_rename_lsn is 0 and should
not be trusted.
*/
tprint(tracef, ", is not transactional, ignoring creation\n");
tprint(tracef, "Table '%s' is not transactional, ignoring creation\n",
name);
ALERT_USER();
error= 0;
goto end;
}
if (cmp_translog_addr(share->state.create_rename_lsn, rec->lsn) >= 0)
{
tprint(tracef, ", has create_rename_lsn (%lu,0x%lx) more recent than"
" record, ignoring creation",
LSN_IN_PARTS(share->state.create_rename_lsn));
tprint(tracef, "Table '%s' has create_rename_lsn (%lu,0x%lx) more "
"recent than record, ignoring creation",
name, LSN_IN_PARTS(share->state.create_rename_lsn));
error= 0;
goto end;
}
if (maria_is_crashed(info))
{
tprint(tracef, ", is crashed, can't recreate it");
eprint(tracef, "Table '%s' is crashed, can't recreate it\n", name);
ALERT_USER();
goto end;
}
@ -629,7 +662,8 @@ prototype_redo_exec_hook(REDO_CREATE_TABLE)
info= NULL;
}
else /* one or two files absent, or header corrupted... */
tprint(tracef, " can't be opened, probably does not exist");
tprint(tracef, "Table '%s' can't be opened, probably does not exist\n",
name);
/* if does not exist, or is older, overwrite it */
ptr= name + strlen(name) + 1;
if ((flags= ptr[0] ? HA_DONT_TOUCH_DATA : 0))
@ -653,7 +687,8 @@ prototype_redo_exec_hook(REDO_CREATE_TABLE)
/** @todo handle symlinks */
if (data_file_name[0] || index_file_name[0])
{
tprint(tracef, ", DATA|INDEX DIRECTORY clauses are not handled\n");
eprint(tracef, "Table '%s' DATA|INDEX DIRECTORY clauses are not handled\n",
name);
goto end;
}
fn_format(filename, name, "", MARIA_NAME_IEXT,
@ -662,18 +697,18 @@ prototype_redo_exec_hook(REDO_CREATE_TABLE)
MY_APPEND_EXT);
linkname_ptr= NULL;
create_flag= MY_DELETE_OLD;
tprint(tracef, ", creating as '%s'", filename);
tprint(tracef, "Table '%s' creating as '%s'", name, filename);
if ((kfile= my_create_with_symlink(linkname_ptr, filename, 0, create_mode,
MYF(MY_WME|create_flag))) < 0)
{
tprint(tracef, " Failed to create index file\n");
eprint(tracef, "Failed to create index file\n");
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)))
{
tprint(tracef, " Failed to write to index file\n");
eprint(tracef, "Failed to write to index file\n");
goto end;
}
if (!(flags & HA_DONT_TOUCH_DATA))
@ -687,7 +722,7 @@ prototype_redo_exec_hook(REDO_CREATE_TABLE)
MYF(MY_WME | create_flag))) < 0) ||
my_close(dfile, MYF(MY_WME)))
{
tprint(tracef, " Failed to create data file\n");
eprint(tracef, "Failed to create data file\n");
goto end;
}
/*
@ -699,7 +734,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))
{
tprint(tracef, " Failed to open new table or write to data file\n");
eprint(tracef, "Failed to open new table or write to data file\n");
goto end;
}
}
@ -730,7 +765,7 @@ prototype_redo_exec_hook(REDO_RENAME_TABLE)
log_record_buffer.str, NULL) !=
rec->record_length)
{
tprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record\n");
goto end;
}
old_name= log_record_buffer.str;
@ -867,13 +902,13 @@ prototype_redo_exec_hook(REDO_RENAME_TABLE)
tprint(tracef, ", renaming '%s'", old_name);
if (maria_rename(old_name, new_name))
{
tprint(tracef, "Failed to rename table\n");
eprint(tracef, "Failed to rename table\n");
goto end;
}
info= maria_open(new_name, O_RDONLY, 0);
if (info == NULL)
{
tprint(tracef, "Failed to open renamed table\n");
eprint(tracef, "Failed to open renamed table\n");
goto end;
}
if (_ma_update_create_rename_lsn(info->s, rec->lsn, TRUE))
@ -887,7 +922,7 @@ drop:
tprint(tracef, ", only dropping '%s'", old_name);
if (maria_delete_table(old_name))
{
tprint(tracef, "Failed to drop table\n");
eprint(tracef, "Failed to drop table\n");
goto end;
}
error= 0;
@ -907,6 +942,11 @@ prototype_redo_exec_hook(REDO_REPAIR_TABLE)
{
int error= 1;
MARIA_HA *info;
HA_CHECK param;
char *name;
uint quick_repair;
DBUG_ENTER("exec_REDO_LOGREC_REDO_REPAIR_TABLE");
if (skip_DDLs)
{
/*
@ -914,26 +954,46 @@ prototype_redo_exec_hook(REDO_REPAIR_TABLE)
insertions into them.
*/
tprint(tracef, "we skip DDLs\n");
return 0;
DBUG_RETURN(0);
}
if ((info= get_MARIA_HA_from_REDO_record(rec)) == NULL)
return 0;
DBUG_RETURN(0);
/*
Otherwise, the mapping is newer than the table, and our record is newer
than the mapping, so we can repair.
*/
tprint(tracef, " repairing...\n");
HA_CHECK param;
maria_chk_init(&param);
param.isam_file_name= info->s->open_file_name;
param.testflag= uint4korr(rec->header);
if (maria_repair(&param, info, info->s->open_file_name, param.testflag))
param.isam_file_name= name= info->s->open_file_name;
param.testflag= uint4korr(rec->header + FILEID_STORE_SIZE);
param.tmpdir= maria_tmpdir;
DBUG_ASSERT(maria_tmpdir);
info->s->state.key_map= uint8korr(rec->header + FILEID_STORE_SIZE + 4);
quick_repair= param.testflag & T_QUICK;
if (param.testflag & T_REP_PARALLEL)
{
if (maria_repair_parallel(&param, info, name, quick_repair))
goto end;
}
else if (param.testflag & T_REP_BY_SORT)
{
if (maria_repair_by_sort(&param, info, name, quick_repair))
goto end;
}
else if (maria_repair(&param, info, name, quick_repair))
goto end;
if (_ma_update_create_rename_lsn(info->s, rec->lsn, TRUE))
goto end;
error= 0;
end:
return error;
DBUG_RETURN(error);
}
@ -953,7 +1013,7 @@ prototype_redo_exec_hook(REDO_DROP_TABLE)
log_record_buffer.str, NULL) !=
rec->record_length)
{
tprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record\n");
return 1;
}
name= log_record_buffer.str;
@ -991,7 +1051,7 @@ prototype_redo_exec_hook(REDO_DROP_TABLE)
tprint(tracef, ", dropping '%s'", name);
if (maria_delete_table(name))
{
tprint(tracef, "Failed to drop table\n");
eprint(tracef, "Failed to drop table\n");
goto end;
}
}
@ -1012,6 +1072,7 @@ prototype_redo_exec_hook(FILE_ID)
int error= 1;
const char *name;
MARIA_HA *info;
DBUG_ENTER("exec_REDO_LOGREC_FILE_ID");
if (cmp_translog_addr(rec->lsn, checkpoint_start) < 0)
{
@ -1022,7 +1083,7 @@ prototype_redo_exec_hook(FILE_ID)
happened and so mapping is not needed.
*/
tprint(tracef, "ignoring because before checkpoint\n");
return 0;
DBUG_RETURN(0);
}
enlarge_buffer(rec);
@ -1031,7 +1092,7 @@ prototype_redo_exec_hook(FILE_ID)
log_record_buffer.str, NULL) !=
rec->record_length)
{
tprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record\n");
goto end;
}
sid= fileid_korr(log_record_buffer.str);
@ -1042,7 +1103,7 @@ prototype_redo_exec_hook(FILE_ID)
prepare_table_for_close(info, rec->lsn);
if (maria_close(info))
{
tprint(tracef, "Failed to close table\n");
eprint(tracef, "Failed to close table\n");
goto end;
}
all_tables[sid].info= NULL;
@ -1052,7 +1113,7 @@ prototype_redo_exec_hook(FILE_ID)
goto end;
error= 0;
end:
return error;
DBUG_RETURN(error);
}
@ -1213,14 +1274,14 @@ prototype_redo_exec_hook(REDO_INSERT_ROW_HEAD)
enlarge_buffer(rec);
if (log_record_buffer.str == NULL)
{
tprint(tracef, "Failed to read allocate buffer for record\n");
eprint(tracef, "Failed to read allocate buffer for record\n");
goto end;
}
if (translog_read_record(rec->lsn, 0, rec->record_length,
log_record_buffer.str, NULL) !=
rec->record_length)
{
tprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record\n");
goto end;
}
buff= log_record_buffer.str;
@ -1255,7 +1316,7 @@ prototype_redo_exec_hook(REDO_INSERT_ROW_TAIL)
log_record_buffer.str, NULL) !=
rec->record_length)
{
tprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record\n");
goto end;
}
buff= log_record_buffer.str;
@ -1291,7 +1352,7 @@ prototype_redo_exec_hook(REDO_INSERT_ROW_BLOBS)
log_record_buffer.str, NULL) !=
rec->record_length)
{
tprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record\n");
goto end;
}
buff= log_record_buffer.str;
@ -1351,7 +1412,7 @@ prototype_redo_exec_hook(REDO_FREE_BLOCKS)
log_record_buffer.str, NULL) !=
rec->record_length)
{
tprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record\n");
goto end;
}
@ -1410,7 +1471,7 @@ prototype_redo_exec_hook(REDO_INDEX)
log_record_buffer.str, NULL) !=
rec->record_length)
{
tprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record\n");
goto end;
}
@ -1436,7 +1497,7 @@ prototype_redo_exec_hook(REDO_INDEX_NEW_PAGE)
log_record_buffer.str, NULL) !=
rec->record_length)
{
tprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record\n");
goto end;
}
@ -1493,7 +1554,7 @@ prototype_redo_exec_hook(UNDO_ROW_INSERT)
HA_CHECKSUM_STORE_SIZE, buff, NULL) !=
HA_CHECKSUM_STORE_SIZE)
{
tprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record\n");
return 1;
}
share->state.state.checksum+= ha_checksum_korr(buff);
@ -1532,7 +1593,7 @@ prototype_redo_exec_hook(UNDO_ROW_DELETE)
HA_CHECKSUM_STORE_SIZE, buff, NULL) !=
HA_CHECKSUM_STORE_SIZE)
{
tprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record\n");
return 1;
}
share->state.state.checksum+= ha_checksum_korr(buff);
@ -1564,7 +1625,7 @@ prototype_redo_exec_hook(UNDO_ROW_UPDATE)
HA_CHECKSUM_STORE_SIZE, buff, NULL) !=
HA_CHECKSUM_STORE_SIZE)
{
tprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record\n");
return 1;
}
share->state.state.checksum+= ha_checksum_korr(buff);
@ -1712,7 +1773,7 @@ prototype_redo_exec_hook(CLR_END)
buff, NULL) !=
KEY_NR_STORE_SIZE + PAGE_STORE_SIZE)
{
tprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record\n");
DBUG_RETURN(1);
}
key_nr= key_nr_korr(buff);
@ -1732,7 +1793,7 @@ prototype_redo_exec_hook(CLR_END)
CLR_TYPE_STORE_SIZE, HA_CHECKSUM_STORE_SIZE,
buff, NULL) != HA_CHECKSUM_STORE_SIZE)
{
tprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record\n");
DBUG_RETURN(1);
}
share->state.state.checksum+= ha_checksum_korr(buff);
@ -1781,7 +1842,7 @@ prototype_undo_exec_hook(UNDO_ROW_INSERT)
log_record_buffer.str, NULL) !=
rec->record_length)
{
tprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record\n");
return 1;
}
record_ptr= log_record_buffer.str;
@ -1818,7 +1879,7 @@ prototype_undo_exec_hook(UNDO_ROW_DELETE)
log_record_buffer.str, NULL) !=
rec->record_length)
{
tprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record\n");
return 1;
}
@ -1860,7 +1921,7 @@ prototype_undo_exec_hook(UNDO_ROW_UPDATE)
log_record_buffer.str, NULL) !=
rec->record_length)
{
tprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record\n");
return 1;
}
@ -1904,7 +1965,7 @@ prototype_undo_exec_hook(UNDO_KEY_INSERT)
log_record_buffer.str, NULL) !=
rec->record_length)
{
tprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record\n");
return 1;
}
@ -1949,7 +2010,7 @@ prototype_undo_exec_hook(UNDO_KEY_DELETE)
log_record_buffer.str, NULL) !=
rec->record_length)
{
tprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record\n");
return 1;
}
@ -1994,7 +2055,7 @@ prototype_undo_exec_hook(UNDO_KEY_DELETE_WITH_ROOT)
log_record_buffer.str, NULL) !=
rec->record_length)
{
tprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record\n");
return 1;
}
@ -2077,7 +2138,7 @@ static int run_redo_phase(LSN lsn, enum maria_apply_log_way apply)
if (len == RECHEADER_READ_ERROR)
{
tprint(tracef, "Failed to read header of the first record.\n");
eprint(tracef, "Failed to read header of the first record.\n");
return 1;
}
if (translog_init_scanner(lsn, 1, &scanner, 1))
@ -2211,7 +2272,10 @@ static int run_redo_phase(LSN lsn, enum maria_apply_log_way apply)
translog_destroy_scanner(&scanner);
translog_free_record_header(&rec);
if (recovery_message_printed == REC_MSG_REDO)
{
fprintf(stderr, " 100%%");
procent_printed= 1;
}
return 0;
err:
@ -2343,7 +2407,7 @@ static int run_undo_phase(uint unfinished)
display_record_position(log_desc, &rec, 0);
if (log_desc->record_execute_in_undo_phase(&rec, trn))
{
tprint(tracef, "Got error when executing undo\n");
tprint(tracef, "Got error %d when executing undo\n", my_errno);
return 1;
}
}
@ -2542,7 +2606,7 @@ static LSN parse_checkpoint_record(LSN lsn)
log_record_buffer.str, NULL) !=
rec.record_length)
{
tprint(tracef, "Failed to read record\n");
eprint(tracef, "Failed to read record\n");
return LSN_ERROR;
}
@ -2793,6 +2857,7 @@ static void print_redo_phase_progress(TRANSLOG_ADDRESS addr)
static ulonglong initial_remainder= -1;
int cur_logno, cur_offset;
ulonglong local_remainder;
int percentage_done;
if (tracef == stdout)
return;
@ -2800,6 +2865,7 @@ static void print_redo_phase_progress(TRANSLOG_ADDRESS addr)
{
print_preamble();
fprintf(stderr, "recovered pages: 0%%");
procent_printed= 1;
recovery_message_printed= REC_MSG_REDO;
}
if (end_logno == FILENO_IMPOSSIBLE)
@ -2815,12 +2881,13 @@ static void print_redo_phase_progress(TRANSLOG_ADDRESS addr)
max(end_logno - cur_logno - 1, 0) * TRANSLOG_FILE_SIZE + end_offset);
if (initial_remainder == (ulonglong)(-1))
initial_remainder= local_remainder;
int percentage_done=
(initial_remainder - local_remainder) * ULL(100) / initial_remainder;
percentage_done= ((initial_remainder - local_remainder) * ULL(100) /
initial_remainder);
if ((percentage_done - percentage_printed) >= 10)
{
percentage_printed= percentage_done;
fprintf(stderr, " %d%%", percentage_done);
procent_printed= 1;
}
}

View File

@ -662,7 +662,7 @@ static int maria_rtree_insert_level(MARIA_HA *info, uint keynr, uchar *key,
info->keyread_buff_used= 1;
bzero(info->buff, info->s->keypage_header);
_ma_store_keynr(info, info->buff, keynr);
_ma_store_page_used(info, info->buff, info->s->keypage_header, 0);
_ma_store_page_used(info, info->buff, info->s->keypage_header);
res= maria_rtree_add_key(info, keyinfo, key, key_length, info->buff,
NULL);
@ -698,9 +698,10 @@ static int maria_rtree_insert_level(MARIA_HA *info, uint keynr, uchar *key,
}
bzero(new_root_buf, info->s->keypage_header);
if (nod_flag)
_ma_store_keypage_flag(info, new_root_buf, KEYPAGE_FLAG_ISNOD);
_ma_store_keynr(info, new_root_buf, keynr);
_ma_store_page_used(info, new_root_buf, info->s->keypage_header,
nod_flag);
_ma_store_page_used(info, new_root_buf, info->s->keypage_header);
if ((new_root= _ma_new(info, DFLT_INIT_HITS, &page_link)) ==
HA_OFFSET_ERROR)
goto err1;

View File

@ -59,7 +59,7 @@ int maria_rtree_add_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
info->s->base.rec_reflength);
page_size+= key_length + info->s->base.rec_reflength;
}
_ma_store_page_used(info, page_buf, page_size, nod_flag);
_ma_store_page_used(info, page_buf, page_size);
DBUG_RETURN(0);
}
@ -86,7 +86,7 @@ int maria_rtree_delete_key(MARIA_HA *info, uchar *page_buf, uchar *key,
(key - page_buf));
page_size-= key_length + nod_flag;
_ma_store_page_used(info, page_buf, page_size, nod_flag);
_ma_store_page_used(info, page_buf, page_size);
return 0;
}

View File

@ -340,11 +340,12 @@ int maria_rtree_split_page(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
}
bzero(new_page, info->s->keypage_header);
if (nod_flag)
_ma_store_keypage_flag(info, new_page, KEYPAGE_FLAG_ISNOD);
_ma_store_keynr(info, new_page, keyinfo->key_nr);
_ma_store_page_used(info, page, info->s->keypage_header + n1 * full_length,
nod_flag);
_ma_store_page_used(info, page, info->s->keypage_header + n1 * full_length)
_ma_store_page_used(info, new_page, info->s->keypage_header +
n2 * full_length, nod_flag);
n2 * full_length);
if ((*new_page_offs= _ma_new(info, DFLT_INIT_HITS, &page_link)) ==
HA_OFFSET_ERROR)

View File

@ -48,6 +48,7 @@ PAGECACHE *maria_pagecache= &maria_pagecache_var;
PAGECACHE maria_log_pagecache_var;
PAGECACHE *maria_log_pagecache= &maria_log_pagecache_var;
MY_TMPDIR *maria_tmpdir; /* Tempdir for redo */
/**
@brief when transactionality does not matter we can use this transaction

View File

@ -76,11 +76,11 @@ int main(int argc,char *argv[])
/* Maria requires that we always have a page cache */
if (maria_init() ||
(init_pagecache(maria_pagecache, maria_block_size * 16, 0, 0,
maria_block_size) == 0) ||
maria_block_size, MY_WME) == 0) ||
ma_control_file_create_or_open() ||
(init_pagecache(maria_log_pagecache,
TRANSLOG_PAGECACHE_SIZE, 0, 0,
TRANSLOG_PAGE_SIZE) == 0) ||
TRANSLOG_PAGE_SIZE, MY_WME) == 0) ||
translog_init(maria_data_root, TRANSLOG_FILE_SIZE,
0, 0, maria_log_pagecache,
TRANSLOG_DEFAULT_FLAGS) ||
@ -840,7 +840,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
printf("test1 Ver 1.2 \n");
exit(0);
case '#':
DBUG_PUSH (argument);
DBUG_PUSH(argument);
break;
case '?':
usage();

View File

@ -89,11 +89,11 @@ int main(int argc, char *argv[])
/* Maria requires that we always have a page cache */
if (maria_init() ||
(init_pagecache(maria_pagecache, pagecache_size, 0, 0,
maria_block_size) == 0) ||
maria_block_size, MY_WME) == 0) ||
ma_control_file_create_or_open() ||
(init_pagecache(maria_log_pagecache,
TRANSLOG_PAGECACHE_SIZE, 0, 0,
TRANSLOG_PAGE_SIZE) == 0) ||
TRANSLOG_PAGE_SIZE, MY_WME) == 0) ||
translog_init(maria_data_root, TRANSLOG_FILE_SIZE,
0, 0, maria_log_pagecache,
TRANSLOG_DEFAULT_FLAGS) ||

View File

@ -178,7 +178,8 @@ void start_test(int id)
exit(1);
}
if (pagecacheing && rnd(2) == 0)
init_pagecache(maria_pagecache, 65536L, 0, 0, MARIA_KEY_BLOCK_LENGTH);
init_pagecache(maria_pagecache, 65536L, 0, 0, MARIA_KEY_BLOCK_LENGTH,
MY_WME);
printf("Process %d, pid: %d\n",id,getpid()); fflush(stdout);
for (error=i=0 ; i < tests && !error; i++)

View File

@ -380,9 +380,7 @@ static int _ma_ck_write_btree_with_log(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
int error;
my_off_t new_root= *root;
uchar key_buff[HA_MAX_KEY_BUFF];
#ifdef NOT_YET
DBUG_ENTER("_ma_ck_write_btree_with_log");
#endif
if (info->s->now_transactional)
{
@ -399,6 +397,8 @@ static int _ma_ck_write_btree_with_log(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
LEX_STRING log_array[TRANSLOG_INTERNAL_PARTS + 2];
struct st_msg_to_write_hook_for_undo_key msg;
/* Save if we need to write a clr record */
info->key_write_undo_lsn[keyinfo->key_nr]= info->trn->undo_lsn;
lsn_store(log_data, info->trn->undo_lsn);
key_nr_store(log_data + LSN_STORE_SIZE + FILEID_STORE_SIZE,
keyinfo->key_nr);
@ -426,15 +426,10 @@ static int _ma_ck_write_btree_with_log(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
}
_ma_unpin_all_pages_and_finalize_row(info, lsn);
#ifdef NOT_YET
DBUG_RETURN(error);
#else
return(error);
#endif
} /* _ma_ck_write_btree_with_log */
/**
@brief Write a key to the b-tree
@ -485,7 +480,9 @@ int _ma_enlarge_root(MARIA_HA *info, MARIA_KEYDEF *keyinfo, const uchar *key,
bzero(info->buff, info->s->keypage_header);
_ma_store_keynr(info, info->buff, keyinfo->key_nr);
_ma_store_page_used(info, info->buff, page_length, nod_flag);
_ma_store_page_used(info, info->buff, page_length);
if (nod_flag)
_ma_store_keypage_flag(info, info->buff, KEYPAGE_FLAG_ISNOD);
(*keyinfo->store_key)(keyinfo, info->buff + info->s->keypage_header +
nod_flag, &s_temp);
@ -727,7 +724,7 @@ int _ma_insert(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
}
(*keyinfo->store_key)(keyinfo,key_pos,&s_temp);
a_length+=t_length;
_ma_store_page_used(info, anc_buff, a_length, nod_flag);
_ma_store_page_used(info, anc_buff, a_length);
/*
Check if the new key fits totally into the the page
@ -781,7 +778,7 @@ int _ma_insert(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
/* fixing the page's length - it contains only one key now */
_ma_store_page_used(info, anc_buff, info->s->keypage_header + blen +
ft2len + 2, 0);
ft2len + 2);
}
/* the rest will be done when we're back from recursion */
}
@ -874,7 +871,7 @@ int _ma_split_page(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
split_length= (uint) (key_pos - split_buff);
a_length= _ma_get_page_used(info, split_buff);
_ma_store_page_used(info, split_buff, split_length, nod_flag);
_ma_store_page_used(info, split_buff, split_length);
key_pos=after_key;
if (nod_flag)
@ -905,7 +902,9 @@ int _ma_split_page(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
page_length= length + t_length + key_ref_length;
bzero(new_buff, info->s->keypage_header);
_ma_store_page_used(info, new_buff, page_length, nod_flag);
if (nod_flag)
_ma_store_keypage_flag(info, new_buff, KEYPAGE_FLAG_ISNOD);
_ma_store_page_used(info, new_buff, page_length);
/* Copy key number */
new_buff[info->s->keypage_header - KEYPAGE_USED_SIZE - KEYPAGE_KEYID_SIZE -
KEYPAGE_FLAG_SIZE]=
@ -1121,8 +1120,8 @@ static int _ma_balance_page(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
new_left_length= info->s->keypage_header+nod_flag+(keys/2)*curr_keylength;
new_right_length=info->s->keypage_header+nod_flag+(((keys+1)/2)*
curr_keylength);
_ma_store_page_used(info, curr_buff, new_left_length, nod_flag);
_ma_store_page_used(info, buff, new_right_length, nod_flag);
_ma_store_page_used(info, curr_buff, new_left_length);
_ma_store_page_used(info, buff, new_right_length);
DBUG_PRINT("info", ("left_length: %u -> %u right_length: %u -> %u",
left_length, new_left_length,
@ -1300,15 +1299,18 @@ static int _ma_balance_page(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
left_length, right_length,
new_left_length, new_right_length,
extra_length));
_ma_store_page_used(info, curr_buff,new_left_length,nod_flag);
_ma_store_page_used(info, buff,new_right_length,nod_flag);
_ma_store_page_used(info, curr_buff, new_left_length);
_ma_store_page_used(info, buff, new_right_length);
bzero(extra_buff, info->s->keypage_header);
if (nod_flag)
_ma_store_keypage_flag(info, extra_buff, KEYPAGE_FLAG_ISNOD);
/* Copy key number */
extra_buff[info->s->keypage_header - KEYPAGE_USED_SIZE - KEYPAGE_KEYID_SIZE -
KEYPAGE_FLAG_SIZE]=
buff[info->s->keypage_header - KEYPAGE_USED_SIZE - KEYPAGE_KEYID_SIZE -
KEYPAGE_FLAG_SIZE];
_ma_store_page_used(info, extra_buff, extra_buff_length, nod_flag);
_ma_store_page_used(info, extra_buff, extra_buff_length);
/* move first largest keys to new page */
pos=buff+right_length-extra_length;
@ -1871,12 +1873,14 @@ static my_bool _ma_log_del_prefix(MARIA_HA *info, my_off_t page, uchar *buff,
translog_parts= 1;
extra_length= 0;
if (offset <= diff_length)
if (offset < diff_length + info->s->keypage_header)
{
/*
Key is not anymore on page. Move data down, but take into account that
the original page had grown with 'move_length bytes'
*/
DBUG_ASSERT(offset + key_length <= diff_length + info->s->keypage_header);
log_pos[0]= KEY_OP_DEL_PREFIX;
int2store(log_pos+1, diff_length - move_length);
log_pos+= 3;

View File

@ -296,7 +296,7 @@ static struct my_option my_long_options[] =
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{ "page_buffer_size", OPT_PAGE_BUFFER_SIZE, "",
(uchar**) &check_param.use_buffers, (uchar**) &check_param.use_buffers, 0,
GET_ULONG, REQUIRED_ARG, (long) USE_BUFFER_INIT, (long) MALLOC_OVERHEAD,
GET_ULONG, REQUIRED_ARG, (long) USE_BUFFER_INIT, (long) USE_BUFFER_INIT,
(long) ~0L, (long) MALLOC_OVERHEAD, (long) IO_SIZE, 0},
{ "read_buffer_size", OPT_READ_BUFFER_SIZE, "",
(uchar**) &check_param.read_buffer_length,
@ -998,7 +998,7 @@ static int maria_chk(HA_CHECK *param, char *filename)
maria_lock_database(info, F_EXTRA_LCK);
datafile= info->dfile.file;
if (init_pagecache(maria_pagecache, param->use_buffers, 0, 0,
maria_block_size) == 0)
maria_block_size, MY_WME) == 0)
{
_ma_check_print_error(param, "Can't initialize page cache with %lu memory",
(ulong) param->use_buffers);

View File

@ -34,6 +34,9 @@
#endif
/* Do extra sanity checking */
#define SANITY_CHECKS 1
#ifdef EXTRA_DEBUG
#define EXTRA_DEBUG_KEY_CHANGES
#endif
#define MAX_NONMAPPED_INSERTS 1000
#define MARIA_MAX_TREE_LEVELS 32
@ -433,6 +436,8 @@ struct st_maria_handler
DYNAMIC_ARRAY *ft1_to_ft2; /* used only in ft1->ft2 conversion */
MEM_ROOT ft_memroot; /* used by the parser */
MYSQL_FTPARSER_PARAM *ftparser_param; /* share info between init/deinit */
LSN *key_write_undo_lsn; /* Pointer to undo for each key */
LSN *key_delete_undo_lsn; /* Pointer to undo for each key */
uchar *buff; /* page buffer */
uchar *keyread_buff; /* Buffer for last key read */
uchar *lastkey, *lastkey2; /* Last used search key */
@ -543,29 +548,29 @@ struct st_maria_handler
#define MAX_KEYPAGE_HEADER_SIZE (LSN_STORE_SIZE + KEYPAGE_USED_SIZE + \
KEYPAGE_KEYID_SIZE + KEYPAGE_FLAG_SIZE + \
TRANSID_SIZE)
#define KEYPAGE_FLAG_ISNOD 1
#define _ma_get_page_used(info,x) \
(((uint) mi_uint2korr(x + (info)->s->keypage_header - KEYPAGE_USED_SIZE)) & \
32767)
#define _ma_store_page_used(info,x,y,nod) \
{ uint16 boh=(nod ? (uint16) 32768 : 0) + (uint16) (y); \
mi_int2store(x + (info)->s->keypage_header - KEYPAGE_USED_SIZE, boh); }
((uint) mi_uint2korr((x) + (info)->s->keypage_header - KEYPAGE_USED_SIZE))
#define _ma_store_page_used(info,x,y) \
mi_int2store((x) + (info)->s->keypage_header - KEYPAGE_USED_SIZE, (y))
#define _ma_test_if_nod(info,x) \
(x[(info)->s->keypage_header-KEYPAGE_USED_SIZE] & 128 ? \
(info)->s->base.key_reflength : 0)
#define _ma_get_used_and_nod(info,buff,length,nod) \
{ \
nod= 0; \
length= mi_uint2korr((buff) + (info)->s->keypage_header - \
KEYPAGE_USED_SIZE); \
if (length & 32768) {length&= 32767; nod= (info)->s->base.key_reflength; } \
((_ma_get_keypage_flag(info,x) & KEYPAGE_FLAG_ISNOD) ? (info)->s->base.key_reflength : 0)
#define _ma_get_used_and_nod(info,buff,length,nod) \
{ \
nod= _ma_test_if_nod((info),(buff)); \
length= _ma_get_page_used((info),(buff)); \
}
#define _ma_store_keynr(info, x, nr) x[(info)->s->keypage_header - KEYPAGE_KEYID_SIZE - KEYPAGE_FLAG_SIZE - KEYPAGE_USED_SIZE]= nr
#define _ma_store_keynr(info, x, nr) x[(info)->s->keypage_header - KEYPAGE_KEYID_SIZE - KEYPAGE_FLAG_SIZE - KEYPAGE_USED_SIZE]= (nr)
#define _ma_get_keynr(info, x) ((uchar) x[(info)->s->keypage_header - KEYPAGE_KEYID_SIZE - KEYPAGE_FLAG_SIZE - KEYPAGE_USED_SIZE])
#define _ma_store_transid(buff, transid) \
int6store((buff) + LSN_STORE_SIZE, (transid))
#define _ma_korr_transid(buff) \
uint6korr((buff) + LSN_STORE_SIZE)
#define _ma_get_keypage_flag(info,x) x[(info)->s->keypage_header - KEYPAGE_USED_SIZE - KEYPAGE_FLAG_SIZE]
#define _ma_store_keypage_flag(info,x,flag) x[(info)->s->keypage_header - KEYPAGE_USED_SIZE - KEYPAGE_FLAG_SIZE]= (flag)
#define maria_mark_crashed(x) do{(x)->s->state.changed|= STATE_CRASHED; \
DBUG_PRINT("error", ("Marked table crashed")); \

View File

@ -85,7 +85,7 @@ int main(int argc,char *argv[])
}
init_pagecache(maria_pagecache, USE_BUFFER_INIT, 0, 0,
MARIA_KEY_BLOCK_LENGTH);
MARIA_KEY_BLOCK_LENGTH, MY_WME);
if (!(info=maria_open(argv[0], O_RDONLY,
HA_OPEN_ABORT_IF_LOCKED|HA_OPEN_FROM_SQL_LAYER)))

View File

@ -516,7 +516,7 @@ static int compress(PACK_MRG_INFO *mrg,char *result_table)
2+4+16));
if (init_pagecache(maria_pagecache, MARIA_MIN_PAGE_CACHE_SIZE, 0, 0,
maria_block_size) == 0)
maria_block_size, MY_WME) == 0)
{
fprintf(stderr, "Can't initialize page cache\n");
goto err;
@ -2975,6 +2975,9 @@ static int save_state(MARIA_HA *isam_file,PACK_MRG_INFO *mrg,
share->state.dellink= HA_OFFSET_ERROR;
share->state.split=(ha_rows) mrg->records;
share->state.version=(ulong) time((time_t*) 0);
if (share->base.born_transactional)
share->state.create_rename_lsn= share->state.is_of_horizon=
LSN_REPAIRED_BY_MARIA_CHK;
if (! maria_is_all_keys_active(share->state.key_map, share->base.keys))
{
/*

View File

@ -29,9 +29,13 @@ const char *default_dbug_option= "d:t:i:O,\\maria_read_log.trace";
const char *default_dbug_option= "d:t:i:o,/tmp/maria_read_log.trace";
#endif
#endif /* DBUG_OFF */
static my_bool opt_display_only, opt_apply, opt_apply_undo, opt_silent,
opt_check;
static my_bool opt_display_only, opt_apply, opt_apply_undo, opt_silent;
static my_bool opt_check;
static const char *opt_tmpdir;
static ulong opt_page_buffer_size;
static ulonglong opt_start_from_lsn;
static MY_TMPDIR maria_chk_tmpdir;
int main(int argc, char **argv)
{
@ -66,7 +70,7 @@ int main(int argc, char **argv)
/* same page cache for log and data; assumes same page size... */
DBUG_ASSERT(maria_block_size == TRANSLOG_PAGE_SIZE);
if (init_pagecache(maria_pagecache, opt_page_buffer_size, 0, 0,
TRANSLOG_PAGE_SIZE) == 0)
TRANSLOG_PAGE_SIZE, MY_WME) == 0)
{
fprintf(stderr, "Got error in init_pagecache() (errno: %d)\n", errno);
goto err;
@ -101,6 +105,19 @@ int main(int argc, char **argv)
fprintf(stdout, "The transaction log starts from lsn (%lu,0x%lx)\n",
LSN_IN_PARTS(lsn));
if (opt_start_from_lsn)
{
if (opt_start_from_lsn < (ulonglong) lsn)
{
fprintf(stderr, "start_from_lsn is too small. Aborting\n");
maria_end();
goto err;
}
lsn= (LSN) opt_start_from_lsn;
fprintf(stdout, "Starting reading log from lsn (%lu,0x%lx)\n",
LSN_IN_PARTS(lsn));
}
fprintf(stdout, "TRACE of the last maria_read_log\n");
if (maria_apply_log(lsn, opt_apply ? MARIA_LOG_APPLY :
(opt_check ? MARIA_LOG_CHECK :
@ -113,17 +130,20 @@ int main(int argc, char **argv)
fprintf(stdout, "%s: DOUBTFUL (%u warnings, check previous output)\n",
my_progname_short, warnings_count);
goto end;
err:
/* don't touch anything more, in case we hit a bug */
fprintf(stderr, "%s: FAILED\n", my_progname_short);
exit(1);
end:
maria_end();
free_tmpdir(&maria_chk_tmpdir);
free_defaults(default_argv);
my_end(0);
exit(0);
return 0; /* No compiler warning */
err:
/* don't touch anything more, in case we hit a bug */
fprintf(stderr, "%s: FAILED\n", my_progname_short);
free_tmpdir(&maria_chk_tmpdir);
free_defaults(default_argv);
exit(1);
}
@ -147,17 +167,28 @@ static struct my_option my_long_options[] =
#endif
{"help", '?', "Display this help and exit.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"display-only", 'o', "display brief info read from records' header",
{"display-only", 'd', "display brief info read from records' header",
(uchar **) &opt_display_only, (uchar **) &opt_display_only, 0, GET_BOOL,
NO_ARG,0, 0, 0, 0, 0, 0},
{ "page_buffer_size", 'P', "",
(uchar**) &opt_page_buffer_size, (uchar**) &opt_page_buffer_size, 0,
GET_ULONG, REQUIRED_ARG, (long) USE_BUFFER_INIT,
(long) MALLOC_OVERHEAD, (long) ~(ulong) 0, (long) MALLOC_OVERHEAD,
(long) USE_BUFFER_INIT, (long) ~(ulong) 0, (long) MALLOC_OVERHEAD,
(long) IO_SIZE, 0},
{ "start_from_lsn", 'o', "Start reading log from this lsn",
(uchar**) &opt_start_from_lsn, (uchar**) &opt_start_from_lsn,
0, GET_ULL, REQUIRED_ARG, 0, 0, ~(longlong) 0, 0, 0, 0 },
{"silent", 's', "Print less information during apply/undo phase",
(uchar **) &opt_silent, (uchar **) &opt_silent, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"tmpdir", 't', "Path for temporary files. Multiple paths can be specified, "
"separated by "
#if defined( __WIN__) || defined(__NETWARE__)
"semicolon (;)"
#else
"colon (:)"
#endif
, (uchar**) &opt_tmpdir, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"undo", 'u', "Apply UNDO records to tables. (disable with --disable-undo)",
(uchar **) &opt_apply_undo, (uchar **) &opt_apply_undo, 0,
GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
@ -170,7 +201,7 @@ static struct my_option my_long_options[] =
static void print_version(void)
{
VOID(printf("%s Ver 1.1 for %s on %s\n",
VOID(printf("%s Ver 1.2 for %s on %s\n",
my_progname_short, SYSTEM_TYPE, MACHINE_TYPE));
NETWARE_SET_SCREEN_MODE(1);
}
@ -230,4 +261,7 @@ static void get_options(int *argc,char ***argv)
usage();
exit(1);
}
if (init_tmpdir(&maria_chk_tmpdir, opt_tmpdir))
exit(1);
maria_tmpdir= &maria_chk_tmpdir;
}

View File

@ -286,9 +286,10 @@ pthread_handler_t test_lockman(void *arg)
return 0;
}
int main()
int main(int argc __attribute__((unused)), char **argv)
{
int i;
MY_INIT(argv[0]);
my_init();
pthread_mutex_init(&rt_mutex, 0);

View File

@ -362,7 +362,7 @@ int main(int argc __attribute__((unused)),
#endif
if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
PAGE_SIZE)) == 0)
PAGE_SIZE, 0)) == 0)
{
fprintf(stderr,"Got error: init_pagecache() (errno: %d)\n",
errno);

View File

@ -16,6 +16,7 @@ static const char* default_dbug_option;
#endif
static char *file1_name= (char*)"page_cache_test_file_1";
static char *file2_name= (char*)"page_cache_test_file_2";
static PAGECACHE_FILE file1;
static pthread_cond_t COND_thread_count;
static pthread_mutex_t LOCK_thread_count;
@ -69,21 +70,17 @@ static struct file_desc simple_delete_flush_test_file[]=
file_name Path (and name) of file which should be reset
*/
void reset_file(PAGECACHE_FILE file, char *file_name)
void reset_file(PAGECACHE_FILE *file, const char *file_name)
{
flush_pagecache_blocks(&pagecache, &file1, FLUSH_RELEASE);
if (my_close(file1.file, MYF(0)) != 0)
{
diag("Got error during %s closing from close() (errno: %d)\n",
file_name, errno);
flush_pagecache_blocks(&pagecache, file, FLUSH_RELEASE);
if (my_close(file->file, MYF(MY_WME)))
exit(1);
}
my_delete(file_name, MYF(0));
if ((file.file= my_open(file_name,
O_CREAT | O_TRUNC | O_RDWR, MYF(0))) == -1)
my_delete(file_name, MYF(MY_WME));
if ((file->file= my_open(file_name,
O_CREAT | O_TRUNC | O_RDWR, MYF(0))) == -1)
{
diag("Got error during %s creation from open() (errno: %d)\n",
file_name, errno);
file_name, my_errno);
exit(1);
}
}
@ -116,7 +113,7 @@ int simple_read_write_test()
simple_read_write_test_file))),
"Simple write-read page file");
if (res)
reset_file(file1, file1_name);
reset_file(&file1, file1_name);
free(buffw);
free(buffr);
DBUG_RETURN(res);
@ -131,8 +128,9 @@ int simple_read_change_write_read_test()
{
unsigned char *buffw= malloc(PAGE_SIZE);
unsigned char *buffr= malloc(PAGE_SIZE);
int res;
int res, res2;
DBUG_ENTER("simple_read_change_write_read_test");
/* prepare the file */
bfill(buffw, PAGE_SIZE, '\1');
pagecache_write(&pagecache, &file1, 0, 3, (char*)buffw,
@ -161,15 +159,17 @@ int simple_read_change_write_read_test()
0);
ok((res= test(memcmp(buffr, buffw, PAGE_SIZE) == 0)),
"Simple read-change-write-read page ");
DBUG_ASSERT(pagecache.blocks_changed == 1);
flush_pagecache_blocks(&pagecache, &file1, FLUSH_FORCE_WRITE);
ok((res&= test(test_file(file1, file1_name, PAGE_SIZE, PAGE_SIZE,
DBUG_ASSERT(pagecache.blocks_changed == 0);
ok((res2= test(test_file(file1, file1_name, PAGE_SIZE, PAGE_SIZE,
simple_read_change_write_read_test_file))),
"Simple read-change-write-read page file");
if (res)
reset_file(file1, file1_name);
if (res && res2)
reset_file(&file1, file1_name);
free(buffw);
free(buffr);
DBUG_RETURN(res);
DBUG_RETURN(res && res2);
}
@ -247,7 +247,7 @@ int simple_pin_test()
simple_pin_test_file2))),
"Simple pin page result file");
if (res)
reset_file(file1, file1_name);
reset_file(&file1, file1_name);
err:
free(buffw);
free(buffr);
@ -289,7 +289,7 @@ int simple_delete_forget_test()
simple_delete_forget_test_file))),
"Simple delete-forget page file");
if (res)
reset_file(file1, file1_name);
reset_file(&file1, file1_name);
free(buffw);
free(buffr);
DBUG_RETURN(res);
@ -331,7 +331,7 @@ int simple_delete_flush_test()
simple_delete_flush_test_file))),
"Simple delete-forget page file");
if (res)
reset_file(file1, file1_name);
reset_file(&file1, file1_name);
free(buffw);
free(buffr);
DBUG_RETURN(res);
@ -344,13 +344,14 @@ int simple_delete_flush_test()
int simple_big_test()
{
unsigned char *buffw= (unsigned char *)malloc(PAGE_SIZE);
unsigned char *buffr= (unsigned char *)malloc(PAGE_SIZE);
struct file_desc *desc=
(struct file_desc *)malloc((PCACHE_SIZE/(PAGE_SIZE/2) + 1) *
sizeof(struct file_desc));
unsigned char *buffw= (unsigned char *) my_malloc(PAGE_SIZE, MYF(MY_WME));
unsigned char *buffr= (unsigned char *) my_malloc(PAGE_SIZE, MYF(MY_WME));
struct file_desc *desc= ((struct file_desc *)
my_malloc((PCACHE_SIZE/(PAGE_SIZE/2) + 1) *
sizeof(struct file_desc), MYF(MY_WME)));
int res, i;
DBUG_ENTER("simple_big_test");
/* prepare the file twice larger then cache */
for (i= 0; i < PCACHE_SIZE/(PAGE_SIZE/2); i++)
{
@ -380,7 +381,8 @@ int simple_big_test()
if (buffr[j] != (i & 0xff))
{
diag("simple_big_test seq: page %u byte %u mismatch\n", i, j);
return 0;
res= 0;
goto err;
}
}
}
@ -399,7 +401,8 @@ int simple_big_test()
if (buffr[j] != (page & 0xff))
{
diag("simple_big_test rnd: page %u byte %u mismatch\n", page, j);
return 0;
res= 0;
goto err;
}
}
}
@ -410,11 +413,16 @@ int simple_big_test()
desc))),
"Simple big file");
if (res)
reset_file(file1, file1_name);
free(buffw);
free(buffr);
reset_file(&file1, file1_name);
err:
my_free(buffw, 0);
my_free(buffr, 0);
my_free(desc, 0);
DBUG_RETURN(res);
}
/*
Thread function
*/
@ -427,7 +435,6 @@ static void *test_thread(void *arg)
my_thread_init();
DBUG_ENTER("test_thread");
DBUG_PRINT("enter", ("param: %d", param));
if (!simple_read_write_test() ||
@ -460,7 +467,7 @@ int main(int argc __attribute__((unused)),
pthread_t tid;
pthread_attr_t thr_attr;
int *param, error, pagen;
File tmp_file;
MY_INIT(argv[0]);
#ifndef DBUG_OFF
@ -475,10 +482,13 @@ int main(int argc __attribute__((unused)),
DBUG_SET_INITIAL(default_dbug_option);
}
#endif
DBUG_ENTER("main");
DBUG_PRINT("info", ("Main thread: %s\n", my_thread_name()));
if ((tmp_file= my_open(file2_name, O_CREAT | O_TRUNC | O_RDWR,
MYF(MY_WME))) < 0)
exit(1);
if ((file1.file= my_open(file1_name,
O_CREAT | O_TRUNC | O_RDWR, MYF(0))) == -1)
{
@ -486,6 +496,9 @@ int main(int argc __attribute__((unused)),
errno);
exit(1);
}
my_close(tmp_file, MYF(0));
my_delete(file2_name, MYF(0));
DBUG_PRINT("info", ("file1: %d", file1.file));
if (chmod(file1_name, S_IRWXU | S_IRWXG | S_IRWXO) != 0)
{
@ -529,7 +542,7 @@ int main(int argc __attribute__((unused)),
plan(12);
if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
PAGE_SIZE)) == 0)
PAGE_SIZE, MYF(MY_WME))) == 0)
{
fprintf(stderr,"Got error: init_pagecache() (errno: %d)\n",
errno);
@ -571,12 +584,9 @@ int main(int argc __attribute__((unused)),
end_pagecache(&pagecache, 1);
DBUG_PRINT("info", ("Page cache ended"));
if (my_close(file1.file, MYF(0)) != 0)
{
fprintf(stderr, "Got error during file1 closing from close() (errno: %d)\n",
errno);
if (my_close(file1.file, MYF(MY_WME)))
exit(1);
}
/*my_delete(file1_name, MYF(0));*/
my_end(0);

View File

@ -170,7 +170,7 @@ int main(int argc __attribute__((unused)), char *argv[])
exit(1);
}
if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
TRANSLOG_PAGE_SIZE)) == 0)
TRANSLOG_PAGE_SIZE, 0)) == 0)
{
fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno);
exit(1);

View File

@ -60,7 +60,7 @@ int main(int argc __attribute__((unused)), char *argv[])
exit(1);
}
if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
PCACHE_PAGE)) == 0)
PCACHE_PAGE, 0)) == 0)
{
fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno);
exit(1);

View File

@ -54,7 +54,7 @@ int main(int argc __attribute__((unused)), char *argv[])
exit(1);
}
if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
PCACHE_PAGE)) == 0)
PCACHE_PAGE, 0)) == 0)
{
fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno);
exit(1);

View File

@ -167,7 +167,7 @@ int main(int argc __attribute__((unused)), char *argv[])
exit(1);
}
if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
TRANSLOG_PAGE_SIZE)) == 0)
TRANSLOG_PAGE_SIZE, 0)) == 0)
{
fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno);
exit(1);
@ -332,7 +332,7 @@ int main(int argc __attribute__((unused)), char *argv[])
exit(1);
}
if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
TRANSLOG_PAGE_SIZE)) == 0)
TRANSLOG_PAGE_SIZE, 0)) == 0)
{
fprintf(stderr, "pass2: Got error: init_pagecache() (errno: %d)\n", errno);
exit(1);

View File

@ -277,7 +277,7 @@ int main(int argc __attribute__((unused)),
exit(1);
}
if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
TRANSLOG_PAGE_SIZE)) == 0)
TRANSLOG_PAGE_SIZE, 0)) == 0)
{
fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno);
exit(1);

View File

@ -62,7 +62,7 @@ int main(int argc __attribute__((unused)), char *argv[])
exit(1);
}
if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
PCACHE_PAGE)) == 0)
PCACHE_PAGE, 0)) == 0)
{
fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno);
exit(1);

View File

@ -62,7 +62,7 @@ int main(int argc __attribute__((unused)), char *argv[])
exit(1);
}
if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
PCACHE_PAGE)) == 0)
PCACHE_PAGE, 0)) == 0)
{
fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno);
exit(1);

View File

@ -57,7 +57,7 @@ int main(int argc __attribute__((unused)), char *argv[])
exit(1);
}
if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
PCACHE_PAGE)) == 0)
PCACHE_PAGE, 0)) == 0)
{
fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno);
exit(1);

View File

@ -24,32 +24,37 @@ int test_file(PAGECACHE_FILE file, char *file_name,
off_t size, size_t buff_size, struct file_desc *desc)
{
MY_STAT stat_buff, *stat;
unsigned char *buffr= malloc(buff_size);
unsigned char *buffr= my_malloc(buff_size, MYF(0));
off_t pos= 0;
size_t byte;
int step= 0;
int res= 1; /* ok */
if ((stat= my_stat(file_name, &stat_buff, MYF(0))) == NULL)
{
diag("Can't stat() %s (errno: %d)\n", file_name, errno);
return 0;
res= 0;
goto err;
}
if (stat->st_size != size)
{
diag("file %s size is %lu (should be %lu)\n",
file_name, (ulong) stat->st_size, (ulong) size);
return 0;
res= 0; /* failed */
/* continue to get more information */
}
/* check content */
my_seek(file.file, 0, SEEK_SET, MYF(0));
my_seek(file.file, 0, SEEK_SET, MYF(MY_WME));
while (desc[step].length != 0)
{
if (my_read(file.file, (char*)buffr, desc[step].length, MYF(0)) !=
desc[step].length)
{
diag("Can't read %u bytes from %s (errno: %d)\n",
(uint)desc[step].length, file_name, errno);
return 0;
diag("Can't read %u bytes from %s (file: %d errno: %d)\n",
(uint)desc[step].length, file_name, file.file, errno);
res= 0;
goto err;
}
for (byte= 0; byte < desc[step].length; byte++)
{
@ -58,11 +63,15 @@ int test_file(PAGECACHE_FILE file, char *file_name,
diag("content of %s mismatch 0x%x in position %lu instead of 0x%x\n",
file_name, (uint) buffr[byte], (ulong) (pos + byte),
desc[step].content);
return 0;
res= 0;
goto err;
}
}
pos+= desc[step].length;
step++;
}
return 1;
err:
my_free(buffr, 0);
return res;
}

View File

@ -154,8 +154,9 @@ void test_trnman_read_from()
}
}
int main()
int main(int argc __attribute__((unused)), char **argv)
{
MY_INIT(argv[0]);
my_init();
plan(6);

View File

@ -97,8 +97,8 @@ int _mi_read_cache(IO_CACHE *info, uchar *buff, my_off_t pos, uint length,
DBUG_PRINT("error",
("Error %d reading next-multi-part block (Got %d bytes)",
my_errno, (int) read_length));
if (!my_errno || my_errno == -1)
my_errno=HA_ERR_WRONG_IN_RECORD;
if (!my_errno || my_errno == -1 || my_errno == HA_ERR_FILE_TOO_SHORT)
my_errno= HA_ERR_WRONG_IN_RECORD;
DBUG_RETURN(1);
}
bzero(buff+read_length,MI_BLOCK_INFO_HEADER_LENGTH - in_buff_length -

View File

@ -185,7 +185,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
if (flags & HA_CREATE_TMP_TABLE)
{
options|= HA_OPTION_TMP_TABLE;
create_mode|= O_EXCL | O_NOFOLLOW;
create_mode|= O_NOFOLLOW;
}
if (flags & HA_CREATE_CHECKSUM || (options & HA_OPTION_CHECKSUM))
{

View File

@ -1764,7 +1764,7 @@ int _mi_read_rnd_dynamic_record(MI_INFO *info, uchar *buf,
/* VOID(my_seek(info->dfile,filepos,MY_SEEK_SET,MYF(0))); */
if (my_read(info->dfile,(uchar*) to,block_info.data_len,MYF(MY_NABP)))
{
if (my_errno == -1)
if (my_errno == HA_ERR_FILE_TOO_SHORT)
my_errno= HA_ERR_WRONG_IN_RECORD; /* Unexpected end of file */
goto err;
}

View File

@ -429,10 +429,10 @@ int _mi_readinfo(register MI_INFO *info, int lock_type, int check_keybuffer)
DBUG_RETURN(1);
if (mi_state_info_read_dsk(share->kfile, &share->state, 1))
{
int error=my_errno ? my_errno : -1;
int error= my_errno ? my_errno : HA_ERR_FILE_TOO_SHORT;
VOID(my_lock(share->kfile,F_UNLCK,0L,F_TO_EOF,
MYF(MY_SEEK_NOT_DONE)));
my_errno=error;
my_errno= error;
DBUG_RETURN(1);
}
}