summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <monty@mysql.com/narttu.mysql.fi>2007-12-18 03:21:32 +0200
committerunknown <monty@mysql.com/narttu.mysql.fi>2007-12-18 03:21:32 +0200
commit30d3d8d3fc41d04f2f90389a42f27520ed63b41b (patch)
tree7a6a9aa09551c88bf567bc3cf7b21c61ce74c0d7
parent7d6d02ca9d2f3868bcfb11ba529ef52a006d83e5 (diff)
downloadmariadb-git-30d3d8d3fc41d04f2f90389a42f27520ed63b41b.tar.gz
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 *
-rw-r--r--include/my_base.h4
-rw-r--r--mysql-test/r/binlog_unsafe.result1
-rw-r--r--mysql-test/r/maria.result9
-rw-r--r--mysql-test/r/ps_maria.result2
-rw-r--r--mysql-test/t/binlog_unsafe.test3
-rw-r--r--mysql-test/t/maria.test14
-rw-r--r--mysql-test/t/ps_maria.test2
-rw-r--r--mysys/my_fopen.c2
-rw-r--r--mysys/my_handler.c5
-rw-r--r--mysys/my_lock.c2
-rw-r--r--mysys/my_pread.c4
-rw-r--r--mysys/my_read.c2
-rw-r--r--mysys/my_seek.c4
-rw-r--r--mysys/my_sync.c2
-rw-r--r--mysys/my_write.c2
-rw-r--r--sql/mysqld.cc2
-rw-r--r--sql/sql_plugin.cc2
-rw-r--r--storage/maria/ma_bitmap.c38
-rw-r--r--storage/maria/ma_blockrec.c17
-rw-r--r--storage/maria/ma_check.c51
-rw-r--r--storage/maria/ma_close.c5
-rw-r--r--storage/maria/ma_create.c33
-rw-r--r--storage/maria/ma_key_recover.c24
-rw-r--r--storage/maria/ma_loghandler.c2
-rw-r--r--storage/maria/ma_open.c107
-rw-r--r--storage/maria/ma_page.c1
-rwxr-xr-xstorage/maria/ma_pagecache.c61
-rw-r--r--storage/maria/ma_pagecrc.c101
-rw-r--r--storage/maria/ma_recovery.c38
-rw-r--r--storage/maria/ma_test1.c2
-rw-r--r--storage/maria/ma_test2.c2
-rw-r--r--storage/maria/maria_chk.c4
-rw-r--r--storage/maria/maria_def.h29
33 files changed, 381 insertions, 196 deletions
diff --git a/include/my_base.h b/include/my_base.h
index 2b60ff552a4..7dfdbe97ba3 100644
--- a/include/my_base.h
+++ b/include/my_base.h
@@ -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)
diff --git a/mysql-test/r/binlog_unsafe.result b/mysql-test/r/binlog_unsafe.result
index 281bb475944..2ee965688ff 100644
--- a/mysql-test/r/binlog_unsafe.result
+++ b/mysql-test/r/binlog_unsafe.result
@@ -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;
diff --git a/mysql-test/r/maria.result b/mysql-test/r/maria.result
index 62619feb323..16cde49c1c6 100644
--- a/mysql-test/r/maria.result
+++ b/mysql-test/r/maria.result
@@ -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;
diff --git a/mysql-test/r/ps_maria.result b/mysql-test/r/ps_maria.result
index f06aac10747..40ed382ec6d 100644
--- a/mysql-test/r/ps_maria.result
+++ b/mysql-test/r/ps_maria.result
@@ -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 ;
diff --git a/mysql-test/t/binlog_unsafe.test b/mysql-test/t/binlog_unsafe.test
index f34c22dc5f7..209e16e0cc0 100644
--- a/mysql-test/t/binlog_unsafe.test
+++ b/mysql-test/t/binlog_unsafe.test
@@ -14,5 +14,4 @@ INSERT INTO t1 SELECT UUID();
query_vertical SHOW WARNINGS;
DROP TABLE t1,t2,t3;
-
-
+DROP VIEW v1;
diff --git a/mysql-test/t/maria.test b/mysql-test/t/maria.test
index 219bae02d5d..dad107ad474 100644
--- a/mysql-test/t/maria.test
+++ b/mysql-test/t/maria.test
@@ -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
diff --git a/mysql-test/t/ps_maria.test b/mysql-test/t/ps_maria.test
index dba1cd01844..5c042b955e7 100644
--- a/mysql-test/t/ps_maria.test
+++ b/mysql-test/t/ps_maria.test
@@ -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 ;
diff --git a/mysys/my_fopen.c b/mysys/my_fopen.c
index 44156da6ae3..351851cca76 100644
--- a/mysys/my_fopen.c
+++ b/mysys/my_fopen.c
@@ -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);
diff --git a/mysys/my_handler.c b/mysys/my_handler.c
index 2b1c91a43e2..312227891c5 100644
--- a/mysys/my_handler.c
+++ b/mysys/my_handler.c
@@ -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"
};
diff --git a/mysys/my_lock.c b/mysys/my_lock.c
index 4b8c067ba0d..200ee7188c9 100644
--- a/mysys/my_lock.c
+++ b/mysys/my_lock.c
@@ -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);
diff --git a/mysys/my_pread.c b/mysys/my_pread.c
index 821d8636d8e..e0218cd1f1f 100644
--- a/mysys/my_pread.c
+++ b/mysys/my_pread.c
@@ -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;
diff --git a/mysys/my_read.c b/mysys/my_read.c
index ee91620e163..63f1d4fdebd 100644
--- a/mysys/my_read.c
+++ b/mysys/my_read.c
@@ -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;
diff --git a/mysys/my_seek.c b/mysys/my_seek.c
index 2c661baeff7..4e18b510a1e 100644
--- a/mysys/my_seek.c
+++ b/mysys/my_seek.c
@@ -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);
diff --git a/mysys/my_sync.c b/mysys/my_sync.c
index ba6964b00d6..1b8420c034e 100644
--- a/mysys/my_sync.c
+++ b/mysys/my_sync.c
@@ -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
{
diff --git a/mysys/my_write.c b/mysys/my_write.c
index 056a84f1794..6586c9598f6 100644
--- a/mysys/my_write.c
+++ b/mysys/my_write.c
@@ -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;
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 080969d5765..e0cc3253989 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -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
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index 1ec56e0caea..411ef6c6b72 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -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)
diff --git a/storage/maria/ma_bitmap.c b/storage/maria/ma_bitmap.c
index a09348bd98a..447e0de9ad7 100644
--- a/storage/maria/ma_bitmap.c
+++ b/storage/maria/ma_bitmap.c
@@ -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);
diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c
index 7ea61b82a68..c31238368de 100644
--- a/storage/maria/ma_blockrec.c
+++ b/storage/maria/ma_blockrec.c
@@ -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
diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c
index ce08e076c77..c122ea6e7ba 100644
--- a/storage/maria/ma_check.c
+++ b/storage/maria/ma_check.c
@@ -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)
diff --git a/storage/maria/ma_close.c b/storage/maria/ma_close.c
index b354b0fb79c..f058754c0ad 100644
--- a/storage/maria/ma_close.c
+++ b/storage/maria/ma_close.c
@@ -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 */
diff --git a/storage/maria/ma_create.c b/storage/maria/ma_create.c
index 9c189a062ae..767242ec027 100644
--- a/storage/maria/ma_create.c
+++ b/storage/maria/ma_create.c
@@ -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;
}
diff --git a/storage/maria/ma_key_recover.c b/storage/maria/ma_key_recover.c
index 730b8b0a1e7..071c49661ef 100644
--- a/storage/maria/ma_key_recover.c
+++ b/storage/maria/ma_key_recover.c
@@ -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);
}
diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c
index 5cb630e8a14..2a176d14454 100644
--- a/storage/maria/ma_loghandler.c
+++ b/storage/maria/ma_loghandler.c
@@ -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);
diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c
index 8b72fdd8325..54f23da4ec9 100644
--- a/storage/maria/ma_open.c
+++ b/storage/maria/ma_open.c
@@ -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);
}
diff --git a/storage/maria/ma_page.c b/storage/maria/ma_page.c
index ba4f14af54f..863f3eede3f 100644
--- a/storage/maria/ma_page.c
+++ b/storage/maria/ma_page.c
@@ -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;
diff --git a/storage/maria/ma_pagecache.c b/storage/maria/ma_pagecache.c
index 69b7865574e..1a0f466c532 100755
--- a/storage/maria/ma_pagecache.c
+++ b/storage/maria/ma_pagecache.c
@@ -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);
}
diff --git a/storage/maria/ma_pagecrc.c b/storage/maria/ma_pagecrc.c
index 131eb778d96..051448259e3 100644
--- a/storage/maria/ma_pagecrc.c
+++ b/storage/maria/ma_pagecrc.c
@@ -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;
+}
diff --git a/storage/maria/ma_recovery.c b/storage/maria/ma_recovery.c
index 5f5bd2712bc..03a0cca5bf3 100644
--- a/storage/maria/ma_recovery.c
+++ b/storage/maria/ma_recovery.c
@@ -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);
}
diff --git a/storage/maria/ma_test1.c b/storage/maria/ma_test1.c
index 8bd241b56cf..363bceb7067 100644
--- a/storage/maria/ma_test1.c
+++ b/storage/maria/ma_test1.c
@@ -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)
diff --git a/storage/maria/ma_test2.c b/storage/maria/ma_test2.c
index bf16311e26e..b196455e950 100644
--- a/storage/maria/ma_test2.c
+++ b/storage/maria/ma_test2.c
@@ -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;
diff --git a/storage/maria/maria_chk.c b/storage/maria/maria_chk.c
index a9d87a3026d..8eb9f135a36 100644
--- a/storage/maria/maria_chk.c
+++ b/storage/maria/maria_chk.c
@@ -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;
}
diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h
index 97edd805af3..46564420deb 100644
--- a/storage/maria/maria_def.h
+++ b/storage/maria/maria_def.h
@@ -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;