Fixed several bugs in page CRC handling

- Ignore CRC errors in REDO for potential new pages
- Ignore CRC errors when repairing tables
- Don't do readcheck callback on read error
- Set my_errno to HA_ERR_WRONG_CRC if we find page with wrong CRC
- Check index page for length before calculating CRC to catch bad pages
Fixed bugs where we used wrong file descriptor to read/write bitmaps
Fixed wrong hash key in 'files_in_flush'
Fixed wrong lock method when writing bitmap
Fixed some wrong printf statements in check/repair that caused core dumps
Fixed argument to translog_page_validator that cause reading of log files to fail
Store number of bytes used for delete-linked key pages to be able to use standard index CRC for deleted key pages.
Use fast 'dummy' pagecheck callbacks for temporary tables
Don't die silently if flush finds pinned pages
Give error (for now) if one tries to create a transactional table with fulltext or spatial keys
Removed some not needed calls to pagecache_file_init()
Added checking of pagecache checksums to ma_test1 and ma_test2
More DBUG
Fixed some DBUG_PRINT to be in line with rest of the code


include/my_base.h:
  Added HA_ERR_INTERNAL_ERROR (used for flush with pinned pages) and HA_ERR_WRONG_CRC
mysql-test/r/binlog_unsafe.result:
  Added missing DROP VIEW statement
mysql-test/r/maria.result:
  Added TRANSACTIONAL=0 when testing with fulltext keys
  Added test that verifies we can't yet create transactional test with fulltext or spatial keys
mysql-test/r/ps_maria.result:
  Added TRANSACTIONAL=0 when testing with fulltext keys
mysql-test/t/binlog_unsafe.test:
  Added missing DROP VIEW statement
mysql-test/t/maria.test:
  Added TRANSACTIONAL=0 when testing with fulltext keys
  Added test that verifies we can't yet create transactional test with fulltext or spatial keys
mysql-test/t/ps_maria.test:
  Added TRANSACTIONAL=0 when testing with fulltext keys
mysys/my_fopen.c:
  Fd: -> fd:
mysys/my_handler.c:
  Added new error messages
mysys/my_lock.c:
  Fd: -> fd:
mysys/my_pread.c:
  Fd: -> fd:
mysys/my_read.c:
  Fd: -> fd:
mysys/my_seek.c:
  Fd: -> fd:
mysys/my_sync.c:
  Fd: -> fd:
mysys/my_write.c:
  Fd: -> fd:
sql/mysqld.cc:
  Fixed wrong argument to my_uuid_init()
sql/sql_plugin.cc:
  Unified DBUG_PRINT (for convert-dbug-for-diff)
storage/maria/ma_bitmap.c:
  Fixed wrong lock method when writing bitmap
  Fixed valgrind error
  Use fast  'dummy' pagecheck callbacks for temporary tables
  Faster bitmap handling for non transational tables
storage/maria/ma_blockrec.c:
  Fixed that bitmap reading is done with the correct filehandle
  Handle reading of pages with wrong CRC when page contect doesn't matter
  Use the page buffer also when we get WRONG CRC or FILE_TOO_SHORT. (Faster and fixed a couple of bugs)
storage/maria/ma_check.c:
  Split long strings for readablity
  Fixed some wrong printf statements that caused core dumps
  Use bitmap.file for bitmaps
  Ignore pages with wrong CRC
storage/maria/ma_close.c:
  More DBUG_PRINT
storage/maria/ma_create.c:
  Give error (for now) if one tries to create a crash safe table with fulltext or spatial keys
storage/maria/ma_key_recover.c:
  Ignore HA_ERR_WRONG_CRC for new pages
  info->s  ->  share
  Store number of bytes used for delete-linked key pages to be able to use standard index CRC for deleted key pages.
storage/maria/ma_loghandler.c:
  Fixed argument to translog_page_validator()
storage/maria/ma_open.c:
  Removed old VMS specific code
  Added function to setup pagecache callbacks
  Moved code around to set 'share->temporary' early
  Removed some not needed calls to pagecache_file_init()
storage/maria/ma_page.c:
  Store number of bytes used for delete-linked key pages to be able to use standard index CRC for deleted key pages.
storage/maria/ma_pagecache.c:
  Don't do readcheck callback on read error
  Reset PCBLOCK_ERROR in pagecache_unlock_by_link() if we write page
  Set my_errno to HA_ER_INTERNAL_ERROR if flush() finds pinned pages
  Don't die silently if flush finds pinned pages.
  Use correct file descriptor when flushing pages
  Fixed wrong hash key in 'files_in_flush';  This must be the file descriptor, not the PAGECACHE_FILE as there may be several PAGECACHE_FILE for same file descriptor
  More DBUG_PRINT
storage/maria/ma_pagecrc.c:
  Removed inline from not tiny static function
  Set my_errno to HA_ERR_WRONG_CRC if we find page with wrong CRC
  (Otherwise my_errno may be 0, and a lot of other code will be confused)
  CRCerror -> error (to keep code uniform)
  Print crc with %lu, as in my_checksum()
  uchar* -> uchar *
  Check index page for length before calculating CRC to catch bad pages
  Added 'dummy' crc_check and filler functions that are used for temporary tables
storage/maria/ma_recovery.c:
  More DBUG
  More message to users to give information what phase failed
  Better error message if recovery failed
storage/maria/ma_test1.c:
  Added checking of page checksums (combined with 'c' to not have to add more test runs)
storage/maria/ma_test2.c:
  Added checking of page checksums (combined with 'c' to not have to add more test runs)
storage/maria/maria_chk.c:
  Fixed wrong argument to _ma_check_print_error()
storage/maria/maria_def.h:
  Added format information to _ma_check_print_xxxx functions
  uchar* -> uchar *
This commit is contained in:
unknown 2007-12-18 03:21:32 +02:00
parent 7d6d02ca9d
commit 30d3d8d3fc
33 changed files with 381 additions and 196 deletions

View File

@ -364,6 +364,7 @@ enum ha_base_keytype {
#define HA_ERR_KEY_NOT_FOUND 120 /* Didn't find key on read or update */
#define HA_ERR_FOUND_DUPP_KEY 121 /* Dupplicate key on write */
#define HA_ERR_INTERNAL_ERROR 122 /* Internal error */
#define HA_ERR_RECORD_CHANGED 123 /* Uppdate with is recoverable */
#define HA_ERR_WRONG_INDEX 124 /* Wrong index given to function */
#define HA_ERR_CRASHED 126 /* Indexfile is crashed */
@ -423,7 +424,8 @@ enum ha_base_keytype {
#define HA_ERR_NEW_FILE 171 /* New file format */
#define HA_ERR_INITIALIZATION 172 /* Error during initialization */
#define HA_ERR_FILE_TOO_SHORT 173 /* File too short */
#define HA_ERR_LAST 173 /* Copy of last error nr */
#define HA_ERR_WRONG_CRC 174 /* Wrong CRC on page */
#define HA_ERR_LAST 174 /* Copy of last error nr */
/* Number of different errors */
#define HA_ERR_ERRORS (HA_ERR_LAST - HA_ERR_FIRST + 1)

View File

@ -11,3 +11,4 @@ Level Warning
Code 1591
Message Statement is not safe to log in statement format.
DROP TABLE t1,t2,t3;
DROP VIEW v1;

View File

@ -325,7 +325,7 @@ KEY `ip` (`ip`),
KEY `poster_login` (`poster_login`),
KEY `topic_id` (`topic_id`),
FULLTEXT KEY `post_text` (`post_text`)
);
) TRANSACTIONAL=0;
INSERT INTO t1 (post_text) VALUES ('ceci est un test'),('ceci est un test'),('ceci est un test'),('ceci est un test'),('ceci est un test');
REPAIR TABLE t1;
Table Op Msg_type Msg_text
@ -2068,3 +2068,10 @@ Maria_pagecache_read_requests #
Maria_pagecache_reads #
Maria_pagecache_write_requests #
Maria_pagecache_writes #
create table t1 (s varchar(25), fulltext(s)) TRANSACTIONAL= 1;
ERROR HY000: Maria can't yet handle SPATIAL or FULLTEXT keys in transactional mode. For now use TRANSACTIONAL=0
drop table if exists t1;
create table t1 ( fid int not null auto_increment primary key,
g geometry not null, spatial key(g));
ERROR HY000: Maria can't yet handle SPATIAL or FULLTEXT keys in transactional mode. For now use TRANSACTIONAL=0
drop table if exists t1;

View File

@ -1166,7 +1166,7 @@ def Extra 253 255 0 N 1 31 8
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t9 ALL NULL NULL NULL NULL 2
drop table if exists t2 ;
create table t2 (s varchar(25), fulltext(s))
create table t2 (s varchar(25), fulltext(s)) TRANSACTIONAL= 0
ENGINE = 'MARIA' ;
insert into t2 values ('Gravedigger'), ('Greed'),('Hollow Dogs') ;
commit ;

View File

@ -14,5 +14,4 @@ INSERT INTO t1 SELECT UUID();
query_vertical SHOW WARNINGS;
DROP TABLE t1,t2,t3;
DROP VIEW v1;

View File

@ -342,7 +342,7 @@ CREATE TABLE `t1` (
KEY `poster_login` (`poster_login`),
KEY `topic_id` (`topic_id`),
FULLTEXT KEY `post_text` (`post_text`)
);
) TRANSACTIONAL=0;
INSERT INTO t1 (post_text) VALUES ('ceci est un test'),('ceci est un test'),('ceci est un test'),('ceci est un test'),('ceci est un test');
@ -1306,6 +1306,18 @@ show variables like 'maria%';
--replace_column 2 #
show status like 'maria%';
#
# Show that we can't yet create fulltext or spatial index with Maria
#
--error 138
create table t1 (s varchar(25), fulltext(s)) TRANSACTIONAL= 1;
drop table if exists t1;
--error 138
create table t1 ( fid int not null auto_increment primary key,
g geometry not null, spatial key(g));
drop table if exists t1;
# End of 5.2 tests
--disable_result_log

View File

@ -24,7 +24,7 @@ let $type= 'MARIA' ;
--disable_warnings
drop table if exists t2 ;
--enable_warnings
eval create table t2 (s varchar(25), fulltext(s))
eval create table t2 (s varchar(25), fulltext(s)) TRANSACTIONAL= 0
ENGINE = $type ;
insert into t2 values ('Gravedigger'), ('Greed'),('Hollow Dogs') ;
commit ;

View File

@ -134,7 +134,7 @@ FILE *my_fdopen(File Filedes, const char *name, int Flags, myf MyFlags)
FILE *fd;
char type[5];
DBUG_ENTER("my_fdopen");
DBUG_PRINT("my",("Fd: %d Flags: %d MyFlags: %d",
DBUG_PRINT("my",("fd: %d Flags: %d MyFlags: %d",
Filedes, Flags, MyFlags));
make_ftype(type,Flags);

View File

@ -575,7 +575,7 @@ static const char *handler_error_messages[]=
{
"Didn't find key on read or update",
"Duplicate key on write or update",
"Undefined handler error 122",
"Internal (unspecified) error in handler",
"Someone has changed the row since it was read (while the table was locked to prevent it)",
"Wrong index given to function",
"Undefined handler error 125",
@ -627,7 +627,8 @@ static const char *handler_error_messages[]=
"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",
"File to short; Expected more data in file"
"File to short; Expected more data in file",
"Read page with wrong checksum"
};

View File

@ -49,7 +49,7 @@ int my_lock(File fd, int locktype, my_off_t start, my_off_t length,
int nxErrno;
#endif
DBUG_ENTER("my_lock");
DBUG_PRINT("my",("Fd: %d Op: %d start: %ld Length: %ld MyFlags: %d",
DBUG_PRINT("my",("fd: %d Op: %d start: %ld Length: %ld MyFlags: %d",
fd,locktype,(long) start,(long) length,MyFlags));
#ifdef VMS
DBUG_RETURN(0);

View File

@ -48,7 +48,7 @@ size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset,
size_t readbytes;
int error= 0;
DBUG_ENTER("my_pread");
DBUG_PRINT("my",("Fd: %d Seek: %lu Buffer: 0x%lx Count: %u MyFlags: %d",
DBUG_PRINT("my",("fd: %d Seek: %lu Buffer: 0x%lx Count: %u MyFlags: %d",
Filedes, (ulong) offset, (long) Buffer, (uint) Count,
MyFlags));
for (;;)
@ -128,7 +128,7 @@ size_t my_pwrite(int Filedes, const uchar *Buffer, size_t Count,
size_t writenbytes, written;
uint errors;
DBUG_ENTER("my_pwrite");
DBUG_PRINT("my",("Fd: %d Seek: %lu Buffer: 0x%lx Count: %u MyFlags: %d",
DBUG_PRINT("my",("fd: %d Seek: %lu Buffer: 0x%lx Count: %u MyFlags: %d",
Filedes, (ulong) offset, (long) Buffer, (uint) Count,
MyFlags));
errors= 0;

View File

@ -37,7 +37,7 @@ size_t my_read(File Filedes, uchar *Buffer, size_t Count, myf MyFlags)
{
size_t readbytes, save_count;
DBUG_ENTER("my_read");
DBUG_PRINT("my",("Fd: %d Buffer: 0x%lx Count: %lu MyFlags: %d",
DBUG_PRINT("my",("fd: %d Buffer: 0x%lx Count: %lu MyFlags: %d",
Filedes, (long) Buffer, (ulong) Count, MyFlags));
save_count= Count;

View File

@ -47,7 +47,7 @@ my_off_t my_seek(File fd, my_off_t pos, int whence,
{
reg1 os_off_t newpos= -1;
DBUG_ENTER("my_seek");
DBUG_PRINT("my",("Fd: %d Hpos: %lu Pos: %lu Whence: %d MyFlags: %d",
DBUG_PRINT("my",("fd: %d Hpos: %lu Pos: %lu Whence: %d MyFlags: %d",
fd, (ulong) (((ulonglong) pos) >> 32), (ulong) pos,
whence, MyFlags));
DBUG_ASSERT(pos != MY_FILEPOS_ERROR); /* safety check */
@ -87,7 +87,7 @@ my_off_t my_tell(File fd, myf MyFlags __attribute__((unused)))
{
os_off_t pos;
DBUG_ENTER("my_tell");
DBUG_PRINT("my",("Fd: %d MyFlags: %d",fd, MyFlags));
DBUG_PRINT("my",("fd: %d MyFlags: %d",fd, MyFlags));
DBUG_ASSERT(fd >= 0);
#ifdef HAVE_TELL
pos=tell(fd);

View File

@ -44,7 +44,7 @@ int my_sync(File fd, myf my_flags)
{
int res;
DBUG_ENTER("my_sync");
DBUG_PRINT("my",("Fd: %d my_flags: %d", fd, my_flags));
DBUG_PRINT("my",("fd: %d my_flags: %d", fd, my_flags));
do
{

View File

@ -25,7 +25,7 @@ size_t my_write(int Filedes, const uchar *Buffer, size_t Count, myf MyFlags)
size_t writenbytes, written;
uint errors;
DBUG_ENTER("my_write");
DBUG_PRINT("my",("Fd: %d Buffer: 0x%lx Count: %lu MyFlags: %d",
DBUG_PRINT("my",("fd: %d Buffer: 0x%lx Count: %lu MyFlags: %d",
Filedes, (long) Buffer, (ulong) Count, MyFlags));
errors=0; written=0;

View File

@ -3249,7 +3249,7 @@ static int init_server_components()
my_rnd_init(&sql_rand,(ulong) server_start_time,(ulong) server_start_time/2);
reset_floating_point_exceptions();
init_thr_lock();
my_uuid_init(my_rnd(&sql_rand),12345);
my_uuid_init((ulong) (my_rnd(&sql_rand))*12345,12345);
#ifdef HAVE_REPLICATION
init_slave_list();
#endif

View File

@ -633,7 +633,7 @@ static plugin_ref intern_plugin_lock(LEX *lex, plugin_ref rc CALLER_INFO_PROTO)
*plugin= pi;
#endif
pi->ref_count++;
DBUG_PRINT("info",("thd: 0x%lx, plugin: \"%s\", ref_count: %d",
DBUG_PRINT("info",("thd: 0x%lx plugin: \"%s\" ref_count: %d",
(long) current_thd, pi->name.str, pi->ref_count));
if (lex)

View File

@ -144,6 +144,7 @@ static inline my_bool write_changed_bitmap(MARIA_SHARE *share,
DBUG_ASSERT(share->pagecache->block_size == bitmap->block_size);
DBUG_ASSERT(bitmap->file.write_callback != 0);
DBUG_PRINT("info", ("bitmap->non_flushable: %u", bitmap->non_flushable));
if ((bitmap->non_flushable == 0)
#ifdef WRONG_BITMAP_FLUSH
|| 1
@ -176,10 +177,11 @@ static inline my_bool write_changed_bitmap(MARIA_SHARE *share,
int res= pagecache_write(share->pagecache,
&bitmap->file, bitmap->page, 0,
(uchar*) bitmap->map, PAGECACHE_PLAIN_PAGE,
PAGECACHE_LOCK_READ, PAGECACHE_PIN,
PAGECACHE_LOCK_WRITE, PAGECACHE_PIN,
PAGECACHE_WRITE_DELAY, &page_link.link,
LSN_IMPOSSIBLE);
page_link.unlock= PAGECACHE_LOCK_WRITE_UNLOCK;
page_link.changed= 1;
push_dynamic(&bitmap->pinned_pages, (void*) &page_link);
DBUG_RETURN(res);
}
@ -217,12 +219,23 @@ my_bool _ma_bitmap_init(MARIA_SHARE *share, File file)
sizeof(MARIA_PINNED_PAGE), 1, 1))
return 1;
bitmap->file.file= file;
bitmap->block_size= share->block_size;
pagecache_file_init(bitmap->file, &maria_page_crc_check_bitmap,
(share->options & HA_OPTION_PAGE_CHECKSUM ?
&maria_page_crc_set_normal :
&maria_page_filler_set_bitmap), share);
bitmap->file.file= file;
bitmap->file.callback_data= (uchar*) share;
if (share->temporary)
{
bitmap->file.read_callback= &maria_page_crc_check_none;
bitmap->file.write_callback= &maria_page_filler_set_none;
}
else
{
bitmap->file.read_callback= &maria_page_crc_check_bitmap;
if (share->options & HA_OPTION_PAGE_CHECKSUM)
bitmap->file.write_callback= &maria_page_crc_set_normal;
else
bitmap->file.write_callback= &maria_page_filler_set_bitmap;
}
/* Size needs to be aligned on 6 */
aligned_bit_blocks= (share->block_size - PAGE_SUFFIX_SIZE) / 6;
bitmap->total_size= aligned_bit_blocks * 6;
@ -2119,7 +2132,18 @@ my_bool _ma_bitmap_set_full_page_bits(MARIA_HA *info,
void _ma_bitmap_flushable(MARIA_SHARE *share, int non_flushable_inc)
{
MARIA_FILE_BITMAP *bitmap= &share->bitmap;
MARIA_FILE_BITMAP *bitmap;
/*
Not transactional tables are never automaticly flushed and needs no
protection
*/
#ifndef EXTRA_DEBUG
if (!share->now_transactional)
return;
#endif
bitmap= &share->bitmap;
if (non_flushable_inc == -1)
{
pthread_mutex_lock(&bitmap->bitmap_lock);

View File

@ -4389,7 +4389,7 @@ restart_bitmap_scan:
}
DBUG_PRINT("info", ("Reading bitmap at %lu",
(ulong) info->scan.bitmap_page));
if (!(pagecache_read(share->pagecache, &info->dfile,
if (!(pagecache_read(share->pagecache, &info->s->bitmap.file,
info->scan.bitmap_page,
0, info->scan.bitmap_buff, PAGECACHE_PLAIN_PAGE,
PAGECACHE_LOCK_LEFT_UNLOCKED, 0)))
@ -5175,9 +5175,11 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
share->pagecache->readwrite_flags= share->pagecache->org_readwrite_flags;
if (!buff)
{
if (my_errno != HA_ERR_FILE_TOO_SHORT)
/* Skip errors when reading outside of file and uninitialized pages */
if (my_errno != HA_ERR_FILE_TOO_SHORT &&
my_errno != HA_ERR_WRONG_CRC)
{
/* If not read outside of file */
/* Fatal disk error when reading page */
pagecache_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
@ -5185,8 +5187,7 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
DBUG_RETURN(my_errno);
}
/* Create new page */
buff= info->keyread_buff;
info->keyread_buff_used= 1;
buff= pagecache_block_link_to_buffer(page_link.link);
buff[PAGE_TYPE_OFFSET]= UNALLOCATED_PAGE;
}
else if (lsn_korr(buff) >= lsn) /* Test if already applied */
@ -5626,7 +5627,8 @@ uint _ma_apply_redo_insert_row_blobs(MARIA_HA *info,
org_readwrite_flags;
if (!buff)
{
if (my_errno != HA_ERR_FILE_TOO_SHORT)
if (my_errno != HA_ERR_FILE_TOO_SHORT &&
my_errno != HA_ERR_WRONG_CRC)
{
/* If not read outside of file */
pagecache_unlock_by_link(share->pagecache, page_link.link,
@ -5641,8 +5643,7 @@ uint _ma_apply_redo_insert_row_blobs(MARIA_HA *info,
pagecache (increased data_file_length but not physical file
length), now reads page N+1: the read fails.
*/
buff= info->keyread_buff;
info->keyread_buff_used= 1;
buff= pagecache_block_link_to_buffer(page_link.link);
make_empty_page(info, buff, BLOB_PAGE);
}
else

View File

@ -922,8 +922,11 @@ static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo,
}
if (keypos != endpos)
{
_ma_check_print_error(param,"Keyblock size at page %s is not correct. Block length: %d key length: %d",
llstr(page,llbuff), used_length, (keypos - buff));
_ma_check_print_error(param,
"Keyblock size at page %s is not correct. "
"Block length: %u key length: %u",
llstr(page, llbuff), used_length,
(uint) (keypos - buff));
goto err;
}
my_afree((uchar*) temp_buff);
@ -1376,7 +1379,7 @@ static int check_compressed_record(HA_CHECK *param, MARIA_HA *info, int extend,
block_info.rec_len > (uint) share->max_pack_length)
{
_ma_check_print_error(param,
"Found block with wrong recordlength: %d at %s",
"Found block with wrong recordlength: %lu at %s",
block_info.rec_len, llstr(start_recpos,llbuff));
got_error=1;
goto end;
@ -1709,7 +1712,7 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
{
/* Bitmap page */
if (pagecache_read(share->pagecache,
&info->dfile,
&info->s->bitmap.file,
(pos / block_size), 1,
bitmap_buff,
PAGECACHE_PLAIN_PAGE,
@ -1717,7 +1720,7 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
{
_ma_check_print_error(param,
"Page %9s: Got error: %d when reading datafile",
my_errno, llstr(pos, llbuff));
llstr(pos, llbuff), my_errno);
goto err;
}
param->used+= block_size;
@ -1746,7 +1749,7 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
{
_ma_check_print_error(param,
"Page %9s: Got error: %d when reading datafile",
my_errno, llstr(pos, llbuff));
llstr(pos, llbuff), my_errno);
goto err;
}
page_type= page_buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK;
@ -4154,8 +4157,9 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
{
if (!searching)
_ma_check_print_info(param,
"Deleted block with impossible length %u at %s",
block_info.block_len,llstr(pos,llbuff));
"Deleted block with impossible length %lu "
"at %s",
block_info.block_len,llstr(pos,llbuff));
error=1;
}
else
@ -4193,10 +4197,11 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
{
if (!searching)
_ma_check_print_info(param,
"Found block with impossible length %u at %s; Skipped",
block_info.block_len+
"Found block with impossible length %lu "
"at %s; Skipped",
block_info.block_len+
(uint) (block_info.filepos-pos),
llstr(pos,llbuff));
llstr(pos,llbuff));
if (found_record)
goto try_next;
searching=1;
@ -4393,9 +4398,11 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
block_info.rec_len > (uint) share->max_pack_length)
{
if (! searching)
_ma_check_print_info(param,"Found block with wrong recordlength: %d at %s\n",
block_info.rec_len,
llstr(sort_param->pos,llbuff));
_ma_check_print_info(param,
"Found block with wrong recordlength: %lu "
"at %s\n",
block_info.rec_len,
llstr(sort_param->pos,llbuff));
continue;
}
if (_ma_read_cache(&sort_param->read_cache,(uchar*) sort_param->rec_buff,
@ -4918,9 +4925,9 @@ static int sort_delete_record(MARIA_SORT_PARAM *sort_param)
if (key_info->s->options & HA_OPTION_COMPRESS_RECORD)
{
_ma_check_print_error(param,
"Recover aborted; Can't run standard recovery on compressed tables "
"with errors in data-file. Use 'maria_chk --safe-recover' "
"to fix it",stderr);;
"Recover aborted; Can't run standard recovery on "
"compressed tables with errors in data-file. "
"Use 'maria_chk --safe-recover' to fix it");
DBUG_RETURN(1);
}
@ -5801,8 +5808,16 @@ read_next_page:
page, 0, info->scan.page_buff,
PAGECACHE_READ_UNKNOWN_PAGE,
PAGECACHE_LOCK_LEFT_UNLOCKED, 0)))
{
if (my_errno == HA_ERR_WRONG_CRC)
{
_ma_check_print_info(sort_info->param,
"Wrong CRC on page at %s",
llstr(page * share->block_size, llbuff));
continue;
}
DBUG_RETURN(my_errno);
}
page_type= (info->scan.page_buff[PAGE_TYPE_OFFSET] &
PAGE_TYPE_MASK);
if (page_type == HEAD_PAGE)

View File

@ -145,13 +145,16 @@ int maria_close(register MARIA_HA *info)
Checkpoint. Fortunately in BLOCK_RECORD we close earlier under mutex.
*/
if (my_close(info->dfile.file, MYF(0)))
error = my_errno;
error= my_errno;
}
delete_dynamic(&info->pinned_pages);
my_free(info, MYF(0));
if (error)
{
DBUG_PRINT("error", ("Got error on close: %d", my_errno));
DBUG_RETURN(my_errno= error);
}
DBUG_RETURN(0);
} /* maria_close */

View File

@ -124,7 +124,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
(keys + uniques) * HA_MAX_KEY_SEG);
/* Start by checking fields and field-types used */
/* Start by checking fields and field-types used */
varchar_length=long_varchar_count=packed= not_block_record_extra_length=
pack_reclength= max_field_lengths= 0;
@ -412,6 +412,17 @@ int maria_create(const char *name, enum data_file_type datafile_type,
share.state.key_root[i]= HA_OFFSET_ERROR;
length= real_length_diff= 0;
min_key_length= key_length= pointer;
if ((keydef->flag & (HA_SPATIAL | HA_FULLTEXT) &&
ci->transactional))
{
my_errno= HA_ERR_UNSUPPORTED;
my_message(HA_ERR_UNSUPPORTED,
"Maria can't yet handle SPATIAL or FULLTEXT keys in "
"transactional mode. For now use TRANSACTIONAL=0", MYF(0));
goto err_no_lock;
}
if (keydef->flag & HA_SPATIAL)
{
#ifdef HAVE_SPATIAL
@ -1057,10 +1068,6 @@ int maria_create(const char *name, enum data_file_type datafile_type,
DROP+CREATE happened (applying REDOs to the wrong table).
*/
share.kfile.file= file;
pagecache_file_init(share.kfile, &maria_page_crc_check_index,
(share.options & HA_OPTION_PAGE_CHECKSUM ?
&maria_page_crc_set_index :
&maria_page_filler_set_normal), &share);
if (_ma_update_create_rename_lsn_sub(&share, lsn, FALSE))
goto err;
my_free(log_data, MYF(0));
@ -1245,7 +1252,13 @@ static int compare_columns(MARIA_COLUMNDEF **a_ptr, MARIA_COLUMNDEF **b_ptr)
}
/* Initialize data file */
/**
@brief Initialize data file
@note
In BLOCK_RECORD, a freshly created datafile is one page long; while in
other formats it is 0-byte long.
*/
int _ma_initialize_data_file(MARIA_SHARE *share, File dfile)
{
@ -1253,16 +1266,8 @@ int _ma_initialize_data_file(MARIA_SHARE *share, File dfile)
{
share->bitmap.block_size= share->base.block_size;
share->bitmap.file.file = dfile;
pagecache_file_init(share->bitmap.file, &maria_page_crc_check_bitmap,
(share->options & HA_OPTION_PAGE_CHECKSUM ?
&maria_page_crc_set_normal :
&maria_page_filler_set_bitmap), share);
return _ma_bitmap_create_first(share);
}
/*
So, in BLOCK_RECORD, a freshly created datafile is one page long; while in
other formats it is 0-byte long.
*/
return 0;
}

View File

@ -584,10 +584,15 @@ uint _ma_apply_redo_index_new_page(MARIA_HA *info, LSN lsn,
PAGECACHE_PLAIN_PAGE, PAGECACHE_LOCK_WRITE,
&page_link.link)))
{
result= (uint) my_errno;
goto err;
if (my_errno != HA_ERR_FILE_TOO_SHORT &&
my_errno != HA_ERR_WRONG_CRC)
{
result= 1;
goto err;
}
buff= pagecache_block_link_to_buffer(page_link.link);
}
if (lsn_korr(buff) >= lsn)
else if (lsn_korr(buff) >= lsn)
{
/* Already applied */
result= 0;
@ -662,7 +667,7 @@ uint _ma_apply_redo_index_free_page(MARIA_HA *info,
old_link= ((free_page != IMPOSSIBLE_PAGE_NO) ?
(my_off_t) free_page * share->block_size :
HA_OFFSET_ERROR);
if (!(buff= pagecache_read(share->pagecache, &info->s->kfile,
if (!(buff= pagecache_read(share->pagecache, &share->kfile,
page, 0, 0,
PAGECACHE_PLAIN_PAGE, PAGECACHE_LOCK_WRITE,
&page_link.link)))
@ -678,7 +683,8 @@ uint _ma_apply_redo_index_free_page(MARIA_HA *info,
}
/* Free page */
bzero(buff + LSN_STORE_SIZE, share->keypage_header - LSN_STORE_SIZE);
_ma_store_keynr(info->s, buff, (uchar) MARIA_DELETE_KEY_NR);
_ma_store_keynr(share, buff, (uchar) MARIA_DELETE_KEY_NR);
_ma_store_page_used(share, buff, share->keypage_header + 8);
mi_sizestore(buff + share->keypage_header, old_link);
share->state.changed|= STATE_NOT_SORTED_PAGES;
@ -755,7 +761,7 @@ uint _ma_apply_redo_index(MARIA_HA *info,
/* Set header to point at key data */
header+= PAGE_STORE_SIZE;
if (!(buff= pagecache_read(share->pagecache, &info->s->kfile,
if (!(buff= pagecache_read(share->pagecache, &share->kfile,
page, 0, 0,
PAGECACHE_PLAIN_PAGE, PAGECACHE_LOCK_WRITE,
&page_link.link)))
@ -934,7 +940,7 @@ my_bool _ma_apply_undo_key_insert(MARIA_HA *info, LSN undo_lsn,
new_root= share->state.key_root[keynr];
res= _ma_ck_real_delete(info, share->keyinfo+keynr, key,
length - info->s->rec_reflength, &new_root);
length - share->rec_reflength, &new_root);
msg.root= &share->state.key_root[keynr];
msg.value= new_root;
@ -1050,13 +1056,13 @@ my_bool _ma_lock_key_del(MARIA_HA *info, my_bool insert_at_end)
void _ma_unlock_key_del(MARIA_HA *info)
{
MARIA_SHARE *share= info->s;
DBUG_ASSERT(info->used_key_del);
if (info->used_key_del == 1) /* Ignore insert-with-append */
{
MARIA_SHARE *share= info->s;
pthread_mutex_lock(&share->intern_lock);
share->used_key_del= 0;
info->s->state.key_del= info->s->current_key_del;
share->state.key_del= info->s->current_key_del;
pthread_mutex_unlock(&share->intern_lock);
pthread_cond_signal(&share->intern_cond);
}

View File

@ -2729,7 +2729,7 @@ static uchar *translog_get_page(TRANSLOG_VALIDATOR_DATA *data, uchar *buffer,
supposed to be correct.
*/
if (translog_page_validator((uchar*) buffer,
LSN_OFFSET(addr),
LSN_OFFSET(addr) / TRANSLOG_PAGE_SIZE,
(uchar*) &file_copy))
{
DBUG_ASSERT(0);

View File

@ -28,9 +28,6 @@
#include <process.h> /* Prototype for getpid */
#endif
#endif
#ifdef VMS
#include "static.c"
#endif
static void setup_key_functions(MARIA_KEYDEF *keyinfo);
static my_bool maria_scan_init_dummy(MARIA_HA *info);
@ -39,6 +36,11 @@ static my_bool maria_once_init_dummy(MARIA_SHARE *, File);
static my_bool maria_once_end_dummy(MARIA_SHARE *);
static uchar *_ma_base_info_read(uchar *ptr, MARIA_BASE_INFO *base);
static uchar *_ma_state_info_read(uchar *ptr, MARIA_STATE_INFO *state);
static void set_data_pagecache_callbacks(PAGECACHE_FILE *file,
MARIA_SHARE *share);
static void set_index_pagecache_callbacks(PAGECACHE_FILE *file,
MARIA_SHARE *share);
#define get_next_element(to,pos,size) { memcpy((char*) to,pos,(size_t) size); \
pos+=size;}
@ -144,17 +146,18 @@ static MARIA_HA *maria_clone_internal(MARIA_SHARE *share, int mode,
info.this_loop=0; /* Update counter */
info.last_unique= share->state.unique;
info.last_loop= share->state.update_count;
info.lock_type=F_UNLCK;
info.quick_mode=0;
info.bulk_insert=0;
info.ft1_to_ft2=0;
info.errkey= -1;
info.page_changed=1;
info.keyread_buff= info.buff + share->base.max_key_block_length;
pagecache_file_init(info.dfile, &maria_page_crc_check_data,
(share->options & HA_OPTION_PAGE_CHECKSUM ?
&maria_page_crc_set_normal :
&maria_page_filler_set_normal), share);
info.lock_type= F_UNLCK;
if (share->options & HA_OPTION_TMP_TABLE)
info.lock_type= F_WRLCK;
set_data_pagecache_callbacks(&info.dfile, share);
bitmap_init(&info.changed_fields, changed_fields_bitmap,
share->base.fields, 0);
if ((*share->init)(&info))
@ -178,15 +181,6 @@ static MARIA_HA *maria_clone_internal(MARIA_SHARE *share, int mode,
share->r_locks++;
share->tot_locks++;
}
if (share->options & HA_OPTION_TMP_TABLE)
{
share->temporary= share->delay_key_write= 1;
share->write_flag=MYF(MY_NABP);
share->w_locks++; /* We don't have to update status */
share->tot_locks++;
info.lock_type=F_WRLCK;
}
if ((share->options & HA_OPTION_DELAY_KEY_WRITE) &&
maria_delay_key_write)
share->delay_key_write=1;
@ -717,11 +711,23 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
}
errpos= 5;
if (open_flags & HA_OPEN_DELAY_KEY_WRITE)
share->options|= HA_OPTION_DELAY_KEY_WRITE;
if (mode == O_RDONLY)
share->options|= HA_OPTION_READ_ONLY_DATA;
share->is_log_table= FALSE;
if (open_flags & HA_OPEN_TMP_TABLE)
{
share->options|= HA_OPTION_TMP_TABLE;
share->temporary= share->delay_key_write= 1;
share->write_flag=MYF(MY_NABP);
share->w_locks++; /* We don't have to update status */
share->tot_locks++;
}
share->kfile.file= kfile;
pagecache_file_init(share->kfile, &maria_page_crc_check_index,
(share->options & HA_OPTION_PAGE_CHECKSUM ?
&maria_page_crc_set_index :
&maria_page_filler_set_normal), share);
set_index_pagecache_callbacks(&share->kfile, share);
share->this_process=(ulong) getpid();
share->last_process= share->state.process;
share->base.key_parts=key_parts;
@ -737,13 +743,6 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
_ma_setup_functions(share);
if ((*share->once_init)(share, info.dfile.file))
goto err;
share->is_log_table= FALSE;
if (open_flags & HA_OPEN_TMP_TABLE)
share->options|= HA_OPTION_TMP_TABLE;
if (open_flags & HA_OPEN_DELAY_KEY_WRITE)
share->options|= HA_OPTION_DELAY_KEY_WRITE;
if (mode == O_RDONLY)
share->options|= HA_OPTION_READ_ONLY_DATA;
#ifdef THREAD
thr_lock_init(&share->lock);
@ -1535,6 +1534,46 @@ uchar *_ma_column_nr_read(uchar *ptr, uint16 *offsets, uint columns)
}
static void set_data_pagecache_callbacks(PAGECACHE_FILE *file,
MARIA_SHARE *share)
{
file->callback_data= (uchar*) share;
if (share->temporary)
{
file->read_callback= &maria_page_crc_check_none;
file->write_callback= &maria_page_filler_set_none;
}
else
{
file->read_callback= &maria_page_crc_check_data;
if (share->options & HA_OPTION_PAGE_CHECKSUM)
file->write_callback= &maria_page_crc_set_normal;
else
file->write_callback= &maria_page_filler_set_normal;
}
}
static void set_index_pagecache_callbacks(PAGECACHE_FILE *file,
MARIA_SHARE *share)
{
file->callback_data= (uchar*) share;
if (share->temporary)
{
file->read_callback= &maria_page_crc_check_none;
file->write_callback= &maria_page_filler_set_none;
}
else
{
file->read_callback= &maria_page_crc_check_index;
if (share->options & HA_OPTION_PAGE_CHECKSUM)
file->write_callback= &maria_page_crc_set_index;
else
file->write_callback= &maria_page_filler_set_normal;
}
}
/**************************************************************************
Open data file
We can't use dup() here as the data file descriptors need to have different
@ -1550,14 +1589,6 @@ int _ma_open_datafile(MARIA_HA *info, MARIA_SHARE *share,
info->dfile.file= share->bitmap.file.file=
my_open(share->data_file_name, share->mode | O_SHARE,
MYF(MY_WME));
pagecache_file_init(share->bitmap.file, &maria_page_crc_check_bitmap,
(share->options & HA_OPTION_PAGE_CHECKSUM ?
&maria_page_crc_set_normal :
&maria_page_filler_set_bitmap), share);
pagecache_file_init(info->dfile, &maria_page_crc_check_data,
(share->options & HA_OPTION_PAGE_CHECKSUM ?
&maria_page_crc_set_normal :
&maria_page_filler_set_normal), share);
return info->dfile.file >= 0 ? 0 : 1;
}
@ -1572,10 +1603,6 @@ int _ma_open_keyfile(MARIA_SHARE *share)
share->kfile.file= my_open(share->unique_file_name,
share->mode | O_SHARE,
MYF(MY_WME));
pagecache_file_init(share->kfile, &maria_page_crc_check_index,
(share->options & HA_OPTION_PAGE_CHECKSUM ?
&maria_page_crc_set_index :
&maria_page_filler_set_normal), share);
pthread_mutex_unlock(&share->intern_lock);
return (share->kfile.file < 0);
}

View File

@ -199,6 +199,7 @@ int _ma_dispose(register MARIA_HA *info, my_off_t pos, my_bool page_not_read)
page_no= pos / block_size;
bzero(buff, share->keypage_header);
_ma_store_keynr(share, buff, (uchar) MARIA_DELETE_KEY_NR);
_ma_store_page_used(share, buff, share->keypage_header + 8);
mi_sizestore(buff + share->keypage_header, old_link);
share->state.changed|= STATE_NOT_SORTED_PAGES;

View File

@ -318,7 +318,7 @@ struct st_pagecache_block_link
/** @brief information describing a run of flush_pagecache_blocks_int() */
struct st_file_in_flush
{
PAGECACHE_FILE file;
File file;
/**
@brief threads waiting for the thread currently flushing this file to be
done
@ -2421,6 +2421,8 @@ retry:
or waits until another thread reads it. What page to read is determined
by a block parameter - reference to a hash link for this page.
If an error occurs THE PCBLOCK_ERROR bit is set in the block status.
On entry cache_lock is locked
*/
static void read_block(PAGECACHE *pagecache,
@ -2428,8 +2430,6 @@ static void read_block(PAGECACHE *pagecache,
my_bool primary)
{
/* On entry cache_lock is locked */
DBUG_ENTER("read_block");
if (primary)
{
@ -2456,21 +2456,17 @@ static void read_block(PAGECACHE *pagecache,
if (error)
block->status|= PCBLOCK_ERROR;
else
block->status= PCBLOCK_READ;
DBUG_PRINT("info", ("read_callback: 0x%lx data: 0x%lx",
(ulong) block->hash_link->file.read_callback,
(ulong) block->hash_link->file.callback_data));
if ((*block->hash_link->file.read_callback)(block->buffer,
block->hash_link->pageno,
block->hash_link->
file.callback_data))
{
DBUG_PRINT("error", ("read callback problem"));
block->status|= PCBLOCK_ERROR;
block->status|= PCBLOCK_READ;
if ((*block->hash_link->file.read_callback)(block->buffer,
block->hash_link->pageno,
block->hash_link->
file.callback_data))
{
DBUG_PRINT("error", ("read callback problem"));
block->status|= PCBLOCK_ERROR;
}
}
DBUG_PRINT("read_block",
("primary request: new page in cache"));
/* Signal that all pending requests for this page now can be processed */
@ -2796,6 +2792,7 @@ void pagecache_unlock_by_link(PAGECACHE *pagecache,
}
if (lsn != LSN_IMPOSSIBLE)
check_and_set_lsn(pagecache, lsn, block);
block->status&= ~PCBLOCK_ERROR;
}
/* if we lock for write we must link the block to changed blocks */
@ -3066,7 +3063,11 @@ restart:
pagecache_pthread_mutex_unlock(&pagecache->cache_lock);
if (status & PCBLOCK_ERROR)
{
DBUG_ASSERT(my_errno != 0);
DBUG_PRINT("error", ("Got error %d when doing page read", my_errno));
DBUG_RETURN((uchar *) 0);
}
DBUG_RETURN(buff);
}
@ -3412,7 +3413,11 @@ restart:
if (write_mode == PAGECACHE_WRITE_DONE)
{
if (!(block->status & PCBLOCK_ERROR))
if (block->status & PCBLOCK_ERROR)
{
DBUG_PRINT("warning", ("Writing on page with error"));
}
else
{
/* Copy data from buff */
if (!(size & 511))
@ -3646,7 +3651,10 @@ static int flush_cached_blocks(PAGECACHE *pagecache,
/* undo the mark put by flush_pagecache_blocks_int(): */
block->status&= ~PCBLOCK_IN_FLUSH;
rc|= PCFLUSH_PINNED;
DBUG_PRINT("warning", ("Page pinned"));
unreg_request(pagecache, block, 1);
if (!*first_errno)
*first_errno= HA_ERR_INTERNAL_ERROR;
continue;
}
/* if the block is not pinned then it is not write locked */
@ -3671,7 +3679,7 @@ static int flush_cached_blocks(PAGECACHE *pagecache,
@todo If page is contiguous with next page to flush, group flushes in
one single my_pwrite().
*/
error= pagecache_fwrite(pagecache, file,
error= pagecache_fwrite(pagecache, &block->hash_link->file,
block->buffer,
block->hash_link->pageno,
block->type,
@ -3687,7 +3695,8 @@ static int flush_cached_blocks(PAGECACHE *pagecache,
{
block->status|= PCBLOCK_ERROR;
if (!*first_errno)
*first_errno= errno ? errno : -1;
*first_errno= my_errno ? my_errno : -1;
rc|= PCFLUSH_ERROR;
}
#ifdef THREAD
/*
@ -3789,12 +3798,12 @@ static int flush_pagecache_blocks_int(PAGECACHE *pagecache,
#ifdef THREAD
struct st_file_in_flush us_flusher, *other_flusher;
us_flusher.file= *file;
us_flusher.file= file->file;
us_flusher.flush_queue.last_thread= NULL;
us_flusher.first_in_switch= FALSE;
while ((other_flusher= (struct st_file_in_flush *)
hash_search(&pagecache->files_in_flush, (uchar *)file,
sizeof(*file))))
hash_search(&pagecache->files_in_flush, (uchar *)&file->file,
sizeof(file->file))))
{
/*
File is in flush already: wait, unless FLUSH_KEEP_LAZY. "Flusher"
@ -4031,8 +4040,12 @@ restart:
#endif
if (cache != cache_buff)
my_free((uchar*) cache, MYF(0));
if (last_errno)
errno= last_errno; /* Return first error */
if (rc != 0)
{
if (last_errno)
my_errno= last_errno; /* Return first error */
DBUG_PRINT("error", ("Got error: %d", my_errno));
}
DBUG_RETURN(rc);
}

View File

@ -41,11 +41,11 @@ static uint32 maria_page_crc(ulong start, uchar *data, uint length)
@retval 1 Error
*/
static inline my_bool maria_page_crc_check(uchar *page,
pgcache_page_no_t page_no,
MARIA_SHARE *share,
uint32 no_crc_val,
int data_length)
static my_bool maria_page_crc_check(uchar *page,
pgcache_page_no_t page_no,
MARIA_SHARE *share,
uint32 no_crc_val,
int data_length)
{
uint32 crc= uint4korr(page + share->block_size - CRC_SIZE), new_crc;
my_bool res;
@ -63,22 +63,24 @@ static inline my_bool maria_page_crc_check(uchar *page,
*/
if (crc >= MARIA_NO_CRC_BITMAP_PAGE)
{
DBUG_PRINT("info", ("No crc: (0x%lx) crc: (0x%lx) page: %lu ",
DBUG_PRINT("info", ("No crc: %lu crc: %lu page: %lu ",
(ulong) no_crc_val, (ulong) crc, (ulong) page_no));
#ifndef DBUG_OFF
if (crc != no_crc_val)
DBUG_PRINT("CRCerror", ("Wrong no CRC value"));
#endif
DBUG_RETURN(test(crc != no_crc_val));
{
my_errno= HA_ERR_WRONG_CRC;
DBUG_PRINT("error", ("Wrong no CRC value"));
DBUG_RETURN(1);
}
DBUG_RETURN(0);
}
new_crc= maria_page_crc(page_no, page, data_length);
DBUG_ASSERT(new_crc != no_crc_val);
res= test(new_crc != crc);
if (res)
{
DBUG_PRINT("CRCerror", ("Page: %lu crc: 0x%lx calculated crc: 0x%lx",
(ulong) page_no, (ulong) crc, (ulong) new_crc));
maria_mark_crashed_share(share);
DBUG_PRINT("error", ("Page: %lu crc: %lu calculated crc: %lu",
(ulong) page_no, (ulong) crc, (ulong) new_crc));
my_errno= HA_ERR_WRONG_CRC;
}
DBUG_RETURN(res);
}
@ -97,15 +99,13 @@ static inline my_bool maria_page_crc_check(uchar *page,
my_bool maria_page_crc_set_normal(uchar *page,
pgcache_page_no_t page_no,
uchar* data_ptr)
uchar *data_ptr)
{
MARIA_SHARE *share= (MARIA_SHARE *)data_ptr;
int data_length= share->block_size - CRC_SIZE;
uint32 crc= maria_page_crc(page_no, page, data_length);
DBUG_ENTER("maria_page_crc_set");
DBUG_PRINT("info", ("Page %u crc: 0x%lx",
(uint)page_no, (ulong)crc));
DBUG_PRINT("info", ("Page %lu crc: %lu", (ulong) page_no, (ulong)crc));
/* crc is on the stack so it is aligned, pagecache buffer is aligned, too */
int4store_aligned(page + data_length, crc);
@ -125,15 +125,15 @@ my_bool maria_page_crc_set_normal(uchar *page,
my_bool maria_page_crc_set_index(uchar *page,
pgcache_page_no_t page_no,
uchar* data_ptr)
uchar *data_ptr)
{
MARIA_SHARE *share= (MARIA_SHARE *)data_ptr;
int data_length= _ma_get_page_used(share, page);
uint32 crc= maria_page_crc(page_no, page, data_length);
DBUG_ENTER("maria_page_crc_set");
DBUG_PRINT("info", ("Page %u crc: 0x%lx",
(uint)page_no, (ulong)crc));
DBUG_PRINT("info", ("Page %lu crc: %lu",
(ulong) page_no, (ulong) crc));
DBUG_ASSERT((uint)data_length <= share->block_size - CRC_SIZE);
/* crc is on the stack so it is aligned, pagecache buffer is aligned, too */
int4store_aligned(page + share->block_size - CRC_SIZE, crc);
@ -157,7 +157,7 @@ my_bool maria_page_crc_set_index(uchar *page,
my_bool maria_page_crc_check_data(uchar *page,
pgcache_page_no_t page_no,
uchar* data_ptr)
uchar *data_ptr)
{
MARIA_SHARE *share= (MARIA_SHARE *)data_ptr;
return (maria_page_crc_check(page, page_no, share,
@ -179,7 +179,7 @@ my_bool maria_page_crc_check_data(uchar *page,
my_bool maria_page_crc_check_bitmap(uchar *page,
pgcache_page_no_t page_no,
uchar* data_ptr)
uchar *data_ptr)
{
MARIA_SHARE *share= (MARIA_SHARE *)data_ptr;
return (maria_page_crc_check(page, page_no, share,
@ -201,12 +201,34 @@ my_bool maria_page_crc_check_bitmap(uchar *page,
my_bool maria_page_crc_check_index(uchar *page,
pgcache_page_no_t page_no,
uchar* data_ptr)
uchar *data_ptr)
{
MARIA_SHARE *share= (MARIA_SHARE *)data_ptr;
return (maria_page_crc_check(page, page_no, share,
uint length= _ma_get_page_used(share, page);
if (length > share->block_size - CRC_SIZE)
{
DBUG_PRINT("error", ("Wrong page length: %u", length));
return (my_errno= HA_ERR_WRONG_CRC);
}
return maria_page_crc_check(page, page_no, share,
MARIA_NO_CRC_NORMAL_PAGE,
_ma_get_page_used(share, page)));
length);
}
/**
@brief Maria pages dumme read callback for temporary tables
@retval 0 OK
@retval 1 Error
*/
my_bool maria_page_crc_check_none(uchar *page __attribute__((unused)),
pgcache_page_no_t page_no
__attribute__((unused)),
uchar *data_ptr __attribute__((unused)))
{
return 0;
}
@ -221,16 +243,18 @@ my_bool maria_page_crc_check_index(uchar *page,
*/
my_bool maria_page_filler_set_normal(uchar *page,
__attribute__((unused))
pgcache_page_no_t page_no,
uchar* data_ptr)
pgcache_page_no_t page_no
__attribute__((unused)),
uchar *data_ptr)
{
DBUG_ENTER("maria_page_filler_set_normal");
DBUG_ASSERT(page_no != 0); /* Catches some simple bugs */
int4store_aligned(page + ((MARIA_SHARE *)data_ptr)->block_size - CRC_SIZE,
MARIA_NO_CRC_NORMAL_PAGE);
DBUG_RETURN(0);
}
/**
@brief Maria pages write callback (sets the page filler for bitmap)
@ -242,12 +266,27 @@ my_bool maria_page_filler_set_normal(uchar *page,
*/
my_bool maria_page_filler_set_bitmap(uchar *page,
__attribute__((unused))
pgcache_page_no_t page_no,
uchar* data_ptr)
pgcache_page_no_t page_no
__attribute__((unused)),
uchar *data_ptr)
{
DBUG_ENTER("maria_page_filler_set_bitmap");
int4store_aligned(page + ((MARIA_SHARE *)data_ptr)->block_size - CRC_SIZE,
MARIA_NO_CRC_BITMAP_PAGE);
DBUG_RETURN(0);
}
/**
@brief Maria pages dummy write callback for temporary tables
@retval 0 OK
*/
my_bool maria_page_filler_set_none(uchar *page __attribute__((unused)),
pgcache_page_no_t page_no
__attribute__((unused)),
uchar *data_ptr __attribute__((unused)))
{
return 0;
}

View File

@ -161,6 +161,7 @@ void tprint(FILE *trace_file __attribute__ ((unused)),
{
va_list args;
va_start(args, format);
DBUG_PRINT("info", ("%s", format));
if (trace_file != NULL)
{
if (procent_printed)
@ -181,6 +182,7 @@ void eprint(FILE *trace_file __attribute__ ((unused)),
{
va_list args;
va_start(args, format);
DBUG_PRINT("error", ("%s", format));
if (procent_printed)
{
/* In silent mode, print on another line than the 0% 10% 20% line */
@ -329,11 +331,17 @@ int maria_apply_log(LSN from_lsn, enum maria_apply_log_way apply,
now= my_getsystime();
if (run_redo_phase(from_lsn, apply))
{
ma_message_no_user(0, "Redo phase failed");
goto err;
}
if ((uncommitted_trans=
end_of_redo_phase(should_run_undo_phase)) == (uint)-1)
{
ma_message_no_user(0, "End of redo phase failed");
goto err;
}
old_now= now;
now= my_getsystime();
@ -375,7 +383,10 @@ int maria_apply_log(LSN from_lsn, enum maria_apply_log_way apply,
if (should_run_undo_phase)
{
if (run_undo_phase(uncommitted_trans))
{
ma_message_no_user(0, "Undo phase failed");
goto err;
}
}
else if (uncommitted_trans > 0)
{
@ -398,7 +409,10 @@ int maria_apply_log(LSN from_lsn, enum maria_apply_log_way apply,
not want that (we want to keep some modules initialized for runtime).
*/
if (close_all_tables())
{
ma_message_no_user(0, "closing of tables failed");
goto err;
}
old_now= now;
now= my_getsystime();
@ -437,11 +451,13 @@ end:
if (recovery_message_printed != REC_MSG_NONE)
{
fprintf(stderr, "\n");
if (error)
ma_message_no_user(0, "recovery failed");
else
if (!error)
ma_message_no_user(ME_JUST_INFO, "recovery done");
}
if (error)
my_message(HA_ERR_INITIALIZATION,
"Maria recovery failed. Please run maria_chk -r on all maria "
"tables and delete all maria_log.######## files", MYF(0));
procent_printed= 0;
/* we don't cleanly close tables if we hit some error (may corrupt them) */
DBUG_RETURN(error);
@ -2462,6 +2478,8 @@ static uint end_of_redo_phase(my_bool prepare_for_undo_phase)
static int run_undo_phase(uint uncommitted)
{
DBUG_ENTER("run_undo_phase");
if (uncommitted > 0)
{
checkpoint_useful= TRUE;
@ -2493,23 +2511,23 @@ static int run_undo_phase(uint uncommitted)
LOG_DESC *log_desc;
if (translog_read_record_header(trn->undo_lsn, &rec) ==
RECHEADER_READ_ERROR)
return 1;
DBUG_RETURN(1);
log_desc= &log_record_type_descriptor[rec.type];
display_record_position(log_desc, &rec, 0);
if (log_desc->record_execute_in_undo_phase(&rec, trn))
{
tprint(tracef, "Got error %d when executing undo\n", my_errno);
return 1;
DBUG_RETURN(1);
}
}
if (trnman_rollback_trn(trn))
return 1;
DBUG_RETURN(1);
/* We could want to span a few threads (4?) instead of 1 */
/* In the future, we want to have this phase *online* */
}
}
return 0;
DBUG_RETURN(0);
}
@ -2809,7 +2827,7 @@ static LSN parse_checkpoint_record(LSN lsn)
*/
if (ptr != (log_record_buffer.str + log_record_buffer.length))
{
tprint(tracef, "checkpoint record corrupted\n");
eprint(tracef, "checkpoint record corrupted\n");
return LSN_ERROR;
}
set_if_smaller(start_address, minimum_rec_lsn_of_dirty_pages);
@ -2847,6 +2865,8 @@ static int close_all_tables(void)
LIST *list_element, *next_open;
MARIA_HA *info;
TRANSLOG_ADDRESS addr;
DBUG_ENTER("close_all_tables");
pthread_mutex_lock(&THR_LOCK_maria);
if (maria_open_list == NULL)
goto end;
@ -2888,7 +2908,7 @@ static int close_all_tables(void)
}
end:
pthread_mutex_unlock(&THR_LOCK_maria);
return error;
DBUG_RETURN(error);
}

View File

@ -788,7 +788,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
key_type= HA_KEYTYPE_TEXT;
break;
case 'c':
create_flag|= HA_CREATE_CHECKSUM;
create_flag|= HA_CREATE_CHECKSUM | HA_CREATE_PAGE_CHECKSUM;
break;
case 'R': /* Length of record pointer */
if (rec_pointer_size > 3)

View File

@ -1105,7 +1105,7 @@ static void get_options(int argc, char **argv)
opt_quick_mode=1;
break;
case 'c':
create_flag|= HA_CREATE_CHECKSUM;
create_flag|= HA_CREATE_CHECKSUM | HA_CREATE_PAGE_CHECKSUM;
break;
case 'D':
create_flag|=HA_CREATE_DELAY_KEY_WRITE;

View File

@ -1636,8 +1636,8 @@ static int maria_sort_records(HA_CHECK *param,
share->state.key_root[sort_key],
MYF(MY_NABP+MY_WME)))
{
_ma_check_print_error(param,"Can't read indexpage from filepos: %s",
(ulong) share->state.key_root[sort_key]);
_ma_check_print_error(param, "Can't read indexpage from filepos: %s",
llstr(share->state.key_root[sort_key], llbuff));
goto err;
}

View File

@ -1029,9 +1029,12 @@ int _ma_flush_table_files(MARIA_HA *info, uint flush_data_or_index,
See ma_check_standalone.h .
*/
volatile int *_ma_killed_ptr(HA_CHECK *param);
void _ma_check_print_error _VARARGS((HA_CHECK *param, const char *fmt, ...));
void _ma_check_print_warning _VARARGS((HA_CHECK *param, const char *fmt, ...));
void _ma_check_print_info _VARARGS((HA_CHECK *param, const char *fmt, ...));
void _ma_check_print_error _VARARGS((HA_CHECK *param, const char *fmt, ...))
ATTRIBUTE_FORMAT(printf, 2, 3);
void _ma_check_print_warning _VARARGS((HA_CHECK *param, const char *fmt, ...))
ATTRIBUTE_FORMAT(printf, 2, 3);
void _ma_check_print_info _VARARGS((HA_CHECK *param, const char *fmt, ...))
ATTRIBUTE_FORMAT(printf, 2, 3);
C_MODE_END
int _ma_flush_pending_blocks(MARIA_SORT_PARAM *param);
@ -1062,23 +1065,29 @@ void _ma_tmp_disable_logging_for_table(MARIA_HA *info,
#define MARIA_NO_CRC_BITMAP_PAGE 0xfffffffe
extern my_bool maria_page_crc_set_index(uchar *page,
pgcache_page_no_t page_no,
uchar* data_ptr);
uchar *data_ptr);
extern my_bool maria_page_crc_set_normal(uchar *page,
pgcache_page_no_t page_no,
uchar* data_ptr);
uchar *data_ptr);
extern my_bool maria_page_crc_check_bitmap(uchar *page,
pgcache_page_no_t page_no,
uchar* data_ptr);
uchar *data_ptr);
extern my_bool maria_page_crc_check_data(uchar *page,
pgcache_page_no_t page_no,
uchar* data_ptr);
uchar *data_ptr);
extern my_bool maria_page_crc_check_index(uchar *page,
pgcache_page_no_t page_no,
uchar* data_ptr);
uchar *data_ptr);
extern my_bool maria_page_crc_check_none(uchar *page,
pgcache_page_no_t page_no,
uchar *data_ptr);
extern my_bool maria_page_filler_set_bitmap(uchar *page,
pgcache_page_no_t page_no,
uchar* data_ptr);
uchar *data_ptr);
extern my_bool maria_page_filler_set_normal(uchar *page,
pgcache_page_no_t page_no,
uchar* data_ptr);
uchar *data_ptr);
extern my_bool maria_page_filler_set_none(uchar *page,
pgcache_page_no_t page_no,
uchar *data_ptr);
extern PAGECACHE *maria_log_pagecache;