diff options
author | unknown <guilhem@gbichot4.local> | 2008-01-29 22:20:59 +0100 |
---|---|---|
committer | unknown <guilhem@gbichot4.local> | 2008-01-29 22:20:59 +0100 |
commit | 2fcff8988aee4f444ed30b3248a60b7ed357bd6c (patch) | |
tree | 2549015abe70820f71758170954350a90193266b | |
parent | e4e8418ced94fff9c8b4bd7b8fcf5e2123717f2b (diff) | |
download | mariadb-git-2fcff8988aee4f444ed30b3248a60b7ed357bd6c.tar.gz |
Fix for BUG#34114 "maria_chk reports false error when several tables on
command-line" and BUG#34062 "Maria table corruption on master".
Use 5 bytes (instead of 4) to store page's number in the checkpoint
record, to allow bigger table (1PB with maria-block-size=1kB).
Help pushbuild not run out of memory by moving the portion of
maria-recovery.test which generates lots of data into a -big.test.
mysql-test/r/maria-recovery.result:
result moved
mysql-test/t/maria-recovery.test:
piece which generates much data moved to maria-recovery-big.test
mysys/my_pread.c:
To fix BUG#34062, where a 1.1TB file was generated due to a wrong
pwrite offset, it was useful to not lose precision on 'offset' in
DBUG_PRINT, so that the crazy value is visible.
mysys/my_read.c:
To fix BUG#34062, where a 1.1TB file was generated due to a wrong
pwrite offset, it was useful to not lose precision on 'offset' in
DBUG_PRINT, so that the crazy value is visible.
mysys/my_write.c:
To fix BUG#34062, where a 1.1TB file was generated due to a wrong
pwrite offset, it was useful to not lose precision on 'offset' in
DBUG_PRINT, so that the crazy value is visible.
storage/maria/ha_maria.cc:
When starting a bulk insert, we throw away dirty index pages from the
cache. Unique (non disabled) key insertions thus read out-of-date
pages from the disk leading to BUG#34062 "Maria table corruption on
master": a DELETE in procedure viewer_sp() had deleted all rows of
viewer_tbl2 one by one, putting index page 1 into key_del; that page
was thrown away at start of INSERT SELECT, then the INSERT SELECT
needed a page to insert keys, looked at key_del, found 1, read page 1
from disk, and its out-of-date content was used to set the new value of
key_del (crazy value of 1TB), then a later insertion needed another
index page, tried to read page at this crazy offset and failed, leading
to corruption mark.
The fix is to destroy out-of-date pages and make the state consistent
with that, i.e. call maria_delete_all_rows().
storage/maria/ma_blockrec.c:
Special hook for UNDO_BULK_INSERT
storage/maria/ma_blockrec.h:
special hook for UNDO_BULK_INSERT
storage/maria/ma_check.c:
Fix for BUG#34114 "maria_chk reports false error when several tables on
command-line": if the Nth (on the command line) table was BLOCK_RECORD
it would start checks by using the param->record_checksum computed by
checks of table N-1.
storage/maria/ma_delete_all.c:
comment
storage/maria/ma_loghandler.c:
special hook for UNDO_BULK_INSERT
storage/maria/ma_page.c:
comment
storage/maria/ma_pagecache.c:
page number is 5 bytes in checkpoint record now (allows bigger tables)
storage/maria/ma_recovery.c:
page number is 5 bytes in checkpoint record now
storage/maria/ma_recovery_util.c:
page number is 5 bytes now
storage/maria/ma_write.c:
typo
mysql-test/r/maria-recovery-big.result:
result is correct
mysql-test/t/maria-recovery-big-master.opt:
usual options for recovery tests
mysql-test/t/maria-recovery-big.test:
Moving out the big blob test to a -big test (it exhausts memory when
using /dev/shm on certain machines)
-rw-r--r-- | mysql-test/r/maria-recovery-big.result | 81 | ||||
-rw-r--r-- | mysql-test/r/maria-recovery.result | 74 | ||||
-rw-r--r-- | mysql-test/t/maria-recovery-big-master.opt | 2 | ||||
-rw-r--r-- | mysql-test/t/maria-recovery-big.test | 68 | ||||
-rw-r--r-- | mysql-test/t/maria-recovery.test | 35 | ||||
-rw-r--r-- | mysys/my_pread.c | 19 | ||||
-rw-r--r-- | mysys/my_read.c | 8 | ||||
-rw-r--r-- | mysys/my_write.c | 8 | ||||
-rw-r--r-- | storage/maria/ha_maria.cc | 16 | ||||
-rw-r--r-- | storage/maria/ma_blockrec.c | 17 | ||||
-rw-r--r-- | storage/maria/ma_blockrec.h | 3 | ||||
-rw-r--r-- | storage/maria/ma_check.c | 3 | ||||
-rw-r--r-- | storage/maria/ma_delete_all.c | 4 | ||||
-rw-r--r-- | storage/maria/ma_loghandler.c | 2 | ||||
-rw-r--r-- | storage/maria/ma_page.c | 4 | ||||
-rw-r--r-- | storage/maria/ma_pagecache.c | 9 | ||||
-rw-r--r-- | storage/maria/ma_recovery.c | 6 | ||||
-rw-r--r-- | storage/maria/ma_recovery_util.c | 7 | ||||
-rw-r--r-- | storage/maria/ma_write.c | 2 |
19 files changed, 224 insertions, 144 deletions
diff --git a/mysql-test/r/maria-recovery-big.result b/mysql-test/r/maria-recovery-big.result new file mode 100644 index 00000000000..6fe2860382f --- /dev/null +++ b/mysql-test/r/maria-recovery-big.result @@ -0,0 +1,81 @@ +set global maria_log_file_size=4294967295; +drop database if exists mysqltest; +create database mysqltest; +use mysqltest; +* TEST of recovery with blobs +* shut down mysqld, removed logs, restarted it +use mysqltest; +set @@max_allowed_packet=32000000; +create table t1 (a int, b longtext) engine=maria table_checksum=1; +* copied t1 for feeding_recovery +insert into t1 values (1,"123456789012345678901234567890"),(2,"09876543210987654321"); +flush table t1; +* copied t1 for comparison +lock table t1 write; +update t1 set b=CONCAT(b,b); +update t1 set b=CONCAT(b,b); +update t1 set b=CONCAT(b,b); +update t1 set b=CONCAT(b,b); +update t1 set b=CONCAT(b,b); +update t1 set b=CONCAT(b,b); +update t1 set b=CONCAT(b,b); +update t1 set b=CONCAT(b,b); +update t1 set b=CONCAT(b,b); +update t1 set b=CONCAT(b,b); +update t1 set b=CONCAT(b,b); +update t1 set b=CONCAT(b,b); +update t1 set b=CONCAT(b,b); +update t1 set b=CONCAT(b,b); +update t1 set b=CONCAT(b,b); +update t1 set b=CONCAT(b,b); +update t1 set b=CONCAT(b,b); +update t1 set b=CONCAT(b,b); +update t1 set b=CONCAT(b,b); +update t1 set b=CONCAT(b,b); +select a,length(b) from t1; +a length(b) +1 31457280 +2 20971520 +update t1 set b=mid(b,1,length(b)/2); +update t1 set b=mid(b,1,length(b)/2); +update t1 set b=mid(b,1,length(b)/2); +update t1 set b=mid(b,1,length(b)/2); +update t1 set b=mid(b,1,length(b)/2); +update t1 set b=mid(b,1,length(b)/2); +update t1 set b=mid(b,1,length(b)/2); +update t1 set b=mid(b,1,length(b)/2); +update t1 set b=mid(b,1,length(b)/2); +update t1 set b=mid(b,1,length(b)/2); +update t1 set b=mid(b,1,length(b)/2); +update t1 set b=mid(b,1,length(b)/2); +update t1 set b=mid(b,1,length(b)/2); +update t1 set b=mid(b,1,length(b)/2); +update t1 set b=mid(b,1,length(b)/2); +update t1 set b=mid(b,1,length(b)/2); +update t1 set b=mid(b,1,length(b)/2); +update t1 set b=mid(b,1,length(b)/2); +update t1 set b=mid(b,1,length(b)/2); +update t1 set b=mid(b,1,length(b)/2); +update t1 set b=mid(b,1,length(b)/2); +update t1 set b=mid(b,1,length(b)/2); +select a,length(b) from t1; +a length(b) +1 8 +2 5 +SET SESSION debug="+d,maria_flush_whole_log,maria_crash"; +* crashing mysqld intentionally +set global maria_checkpoint_interval=1; +ERROR HY000: Lost connection to MySQL server during query +* copied t1 back for feeding_recovery +* recovery happens +check table t1 extended; +Table Op Msg_type Msg_text +mysqltest.t1 check status OK +* testing that checksum after recovery is as expected +Checksum-check +ok +use mysqltest; +drop table t1; +drop database mysqltest_for_feeding_recovery; +drop database mysqltest_for_comparison; +drop database mysqltest; diff --git a/mysql-test/r/maria-recovery.result b/mysql-test/r/maria-recovery.result index c21791d4d3d..6c05095f913 100644 --- a/mysql-test/r/maria-recovery.result +++ b/mysql-test/r/maria-recovery.result @@ -302,80 +302,6 @@ a 1 3 drop table t1; -* TEST of recovery with blobs -* shut down mysqld, removed logs, restarted it -use mysqltest; -set @@max_allowed_packet=32000000; -create table t1 (a int, b longtext) engine=maria table_checksum=1; -* copied t1 for feeding_recovery -insert into t1 values (1,"123456789012345678901234567890"),(2,"09876543210987654321"); -flush table t1; -* copied t1 for comparison -lock table t1 write; -update t1 set b=CONCAT(b,b); -update t1 set b=CONCAT(b,b); -update t1 set b=CONCAT(b,b); -update t1 set b=CONCAT(b,b); -update t1 set b=CONCAT(b,b); -update t1 set b=CONCAT(b,b); -update t1 set b=CONCAT(b,b); -update t1 set b=CONCAT(b,b); -update t1 set b=CONCAT(b,b); -update t1 set b=CONCAT(b,b); -update t1 set b=CONCAT(b,b); -update t1 set b=CONCAT(b,b); -update t1 set b=CONCAT(b,b); -update t1 set b=CONCAT(b,b); -update t1 set b=CONCAT(b,b); -update t1 set b=CONCAT(b,b); -update t1 set b=CONCAT(b,b); -update t1 set b=CONCAT(b,b); -update t1 set b=CONCAT(b,b); -update t1 set b=CONCAT(b,b); -select a,length(b) from t1; -a length(b) -1 31457280 -2 20971520 -update t1 set b=mid(b,1,length(b)/2); -update t1 set b=mid(b,1,length(b)/2); -update t1 set b=mid(b,1,length(b)/2); -update t1 set b=mid(b,1,length(b)/2); -update t1 set b=mid(b,1,length(b)/2); -update t1 set b=mid(b,1,length(b)/2); -update t1 set b=mid(b,1,length(b)/2); -update t1 set b=mid(b,1,length(b)/2); -update t1 set b=mid(b,1,length(b)/2); -update t1 set b=mid(b,1,length(b)/2); -update t1 set b=mid(b,1,length(b)/2); -update t1 set b=mid(b,1,length(b)/2); -update t1 set b=mid(b,1,length(b)/2); -update t1 set b=mid(b,1,length(b)/2); -update t1 set b=mid(b,1,length(b)/2); -update t1 set b=mid(b,1,length(b)/2); -update t1 set b=mid(b,1,length(b)/2); -update t1 set b=mid(b,1,length(b)/2); -update t1 set b=mid(b,1,length(b)/2); -update t1 set b=mid(b,1,length(b)/2); -update t1 set b=mid(b,1,length(b)/2); -update t1 set b=mid(b,1,length(b)/2); -select a,length(b) from t1; -a length(b) -1 8 -2 5 -SET SESSION debug="+d,maria_flush_whole_log,maria_crash"; -* crashing mysqld intentionally -set global maria_checkpoint_interval=1; -ERROR HY000: Lost connection to MySQL server during query -* copied t1 back for feeding_recovery -* recovery happens -check table t1 extended; -Table Op Msg_type Msg_text -mysqltest.t1 check status OK -* testing that checksum after recovery is as expected -Checksum-check -ok -use mysqltest; -drop table t1; * TEST of recovery when crash before bulk-insert-with-repair is committed create table t1 (a varchar(100), key(a)) engine=maria; create table t2 (a varchar(100)) engine=myisam; diff --git a/mysql-test/t/maria-recovery-big-master.opt b/mysql-test/t/maria-recovery-big-master.opt new file mode 100644 index 00000000000..d09f57dc35d --- /dev/null +++ b/mysql-test/t/maria-recovery-big-master.opt @@ -0,0 +1,2 @@ +--skip-stack-trace --skip-core-file --loose-debug-on=1 + diff --git a/mysql-test/t/maria-recovery-big.test b/mysql-test/t/maria-recovery-big.test new file mode 100644 index 00000000000..d71865b73c1 --- /dev/null +++ b/mysql-test/t/maria-recovery-big.test @@ -0,0 +1,68 @@ +# Maria recovery test which cannot run in shared memory +# because it generates too much data, or which takes a lot of time. + +--source include/not_embedded.inc +# Don't test this under valgrind, memory leaks will occur as we crash +--source include/not_valgrind.inc +# Binary must be compiled with debug for crash to occur +--source include/have_debug.inc +--source include/have_maria.inc + +set global maria_log_file_size=4294967295; + +--disable_warnings +drop database if exists mysqltest; +--enable_warnings +create database mysqltest; + +# Include scripts can perform SQL. For it to not influence the main test +# they use a separate connection. This way if they use a DDL it would +# not autocommit in the main test. +connect (admin, 127.0.0.1, root,,mysqltest,,); +--enable_reconnect + +connection default; +use mysqltest; +--enable_reconnect + +# +# Test with big blobs +# + +--echo * TEST of recovery with blobs +-- source include/maria_empty_logs.inc +set @@max_allowed_packet=32000000; +create table t1 (a int, b longtext) engine=maria table_checksum=1; +let $mms_tables=1; +-- source include/maria_make_snapshot_for_feeding_recovery.inc +insert into t1 values (1,"123456789012345678901234567890"),(2,"09876543210987654321"); +-- source include/maria_make_snapshot_for_comparison.inc +lock table t1 write; +let $loop=20; +while ($loop) +{ + update t1 set b=CONCAT(b,b); + dec $loop; +} +select a,length(b) from t1; +let $loop=22; +while ($loop) +{ + update t1 set b=mid(b,1,length(b)/2); + dec $loop; +} +select a,length(b) from t1; +# we want recovery to run on the first snapshot made above +let $mvr_restore_old_snapshot=1; +let $mms_compare_physically=0; +let $mvr_debug_option="+d,maria_flush_whole_log,maria_crash"; +let $mvr_crash_statement= set global maria_checkpoint_interval=1; +-- source include/maria_verify_recovery.inc +drop table t1; + +# clean up everything +let $mms_purpose=feeding_recovery; +eval drop database mysqltest_for_$mms_purpose; +let $mms_purpose=comparison; +eval drop database mysqltest_for_$mms_purpose; +drop database mysqltest; diff --git a/mysql-test/t/maria-recovery.test b/mysql-test/t/maria-recovery.test index 116a5476d46..febd4cf15dc 100644 --- a/mysql-test/t/maria-recovery.test +++ b/mysql-test/t/maria-recovery.test @@ -256,41 +256,6 @@ select * from t1; select * from t1; drop table t1; -# -# Test with big blobs -# - ---echo * TEST of recovery with blobs --- source include/maria_empty_logs.inc -set @@max_allowed_packet=32000000; -create table t1 (a int, b longtext) engine=maria table_checksum=1; -let $mms_tables=1; --- source include/maria_make_snapshot_for_feeding_recovery.inc -insert into t1 values (1,"123456789012345678901234567890"),(2,"09876543210987654321"); --- source include/maria_make_snapshot_for_comparison.inc -lock table t1 write; -let $loop=20; -while ($loop) -{ - update t1 set b=CONCAT(b,b); - dec $loop; -} -select a,length(b) from t1; -let $loop=22; -while ($loop) -{ - update t1 set b=mid(b,1,length(b)/2); - dec $loop; -} -select a,length(b) from t1; -# we want recovery to run on the first snapshot made above -let $mvr_restore_old_snapshot=1; -let $mms_compare_physically=0; -let $mvr_debug_option="+d,maria_flush_whole_log,maria_crash"; -let $mvr_crash_statement= set global maria_checkpoint_interval=1; --- source include/maria_verify_recovery.inc -drop table t1; - --echo * TEST of recovery when crash before bulk-insert-with-repair is committed create table t1 (a varchar(100), key(a)) engine=maria; create table t2 (a varchar(100)) engine=myisam; diff --git a/mysys/my_pread.c b/mysys/my_pread.c index e0218cd1f1f..cfccc40a782 100644 --- a/mysys/my_pread.c +++ b/mysys/my_pread.c @@ -16,6 +16,7 @@ #include "mysys_priv.h" #include "mysys_err.h" #include "my_base.h" +#include <m_string.h> #include <errno.h> #ifdef HAVE_PREAD #include <unistd.h> @@ -47,10 +48,13 @@ size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset, { size_t readbytes; int error= 0; +#ifndef DBUG_OFF + char llbuf1[22], llbuf2[22]; DBUG_ENTER("my_pread"); - DBUG_PRINT("my",("fd: %d Seek: %lu Buffer: 0x%lx Count: %u MyFlags: %d", - Filedes, (ulong) offset, (long) Buffer, (uint) Count, - MyFlags)); + DBUG_PRINT("my",("fd: %d Seek: %s Buffer: 0x%lx Count: %s MyFlags: %d", + Filedes, ullstr(offset, llbuf1), + (long) Buffer, ullstr(Count, llbuf2), MyFlags)); +#endif for (;;) { #ifndef __WIN__ @@ -127,10 +131,13 @@ size_t my_pwrite(int Filedes, const uchar *Buffer, size_t Count, { size_t writenbytes, written; uint errors; +#ifndef DBUG_OFF + char llbuf1[22], llbuf2[22]; DBUG_ENTER("my_pwrite"); - DBUG_PRINT("my",("fd: %d Seek: %lu Buffer: 0x%lx Count: %u MyFlags: %d", - Filedes, (ulong) offset, (long) Buffer, (uint) Count, - MyFlags)); + DBUG_PRINT("my",("fd: %d Seek: %s Buffer: 0x%lx Count: %s MyFlags: %d", + Filedes, ullstr(offset, llbuf1), + (long) Buffer, ullstr(Count, llbuf2), MyFlags)); +#endif errors= 0; written= 0; diff --git a/mysys/my_read.c b/mysys/my_read.c index 63f1d4fdebd..0d6c8d14416 100644 --- a/mysys/my_read.c +++ b/mysys/my_read.c @@ -16,6 +16,7 @@ #include "mysys_priv.h" #include "mysys_err.h" #include <my_base.h> +#include <m_string.h> #include <errno.h> /* @@ -36,9 +37,12 @@ size_t my_read(File Filedes, uchar *Buffer, size_t Count, myf MyFlags) { size_t readbytes, save_count; +#ifndef DBUG_OFF + char llbuf[22]; DBUG_ENTER("my_read"); - DBUG_PRINT("my",("fd: %d Buffer: 0x%lx Count: %lu MyFlags: %d", - Filedes, (long) Buffer, (ulong) Count, MyFlags)); + DBUG_PRINT("my",("fd: %d Buffer: 0x%lx Count: %s MyFlags: %d", + Filedes, (long) Buffer, ullstr(Count, llbuf), MyFlags)); +#endif save_count= Count; for (;;) diff --git a/mysys/my_write.c b/mysys/my_write.c index 7f8b85c241e..515ccb5fd37 100644 --- a/mysys/my_write.c +++ b/mysys/my_write.c @@ -15,6 +15,7 @@ #include "mysys_priv.h" #include "mysys_err.h" +#include <m_string.h> #include <errno.h> @@ -24,9 +25,12 @@ size_t my_write(int Filedes, const uchar *Buffer, size_t Count, myf MyFlags) { size_t writenbytes, written; uint errors; +#ifndef DBUG_OFF + char llbuf[22]; DBUG_ENTER("my_write"); - DBUG_PRINT("my",("fd: %d Buffer: 0x%lx Count: %lu MyFlags: %d", - Filedes, (long) Buffer, (ulong) Count, MyFlags)); + DBUG_PRINT("my",("fd: %d Buffer: 0x%lx Count: %s MyFlags: %d", + Filedes, (long) Buffer, ullstr(Count, llbuf), MyFlags)); +#endif errors=0; written=0; /* The behavior of write(fd, buf, 0) is not portable */ diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index 9d799031eb2..cbff204ef9f 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -648,7 +648,7 @@ void _ma_check_print_warning(HA_CHECK *param, const char *fmt, ...) #define BULK_INSERT_SINGLE_UNDO_AND_REPAIR 1 /** Transactional table doing bulk insert with one single UNDO - (UNDO_BULK_INSERT) and with repair. + (UNDO_BULK_INSERT) and without repair. */ #define BULK_INSERT_SINGLE_UNDO_AND_NO_REPAIR 2 /** @@ -1749,15 +1749,16 @@ void ha_maria::start_bulk_insert(ha_rows rows) { bulk_insert_single_undo= BULK_INSERT_SINGLE_UNDO_AND_NO_REPAIR; write_log_record_for_bulk_insert(file); + _ma_tmp_disable_logging_for_table(file, TRUE); /* Pages currently in the page cache have type PAGECACHE_LSN_PAGE, we are not allowed to overwrite them with PAGECACHE_PLAIN_PAGE, so throw them away. It is not losing data, because we just wrote and - forced an UNDO which will for sure empty the table if we crash. + forced an UNDO which will for sure empty the table if we crash. The + upcoming unique-key insertions however need a proper index, so we + cannot leave the corrupted on-disk index file, thus we truncate it. */ - _ma_flush_table_files(file, MARIA_FLUSH_DATA|MARIA_FLUSH_INDEX, - FLUSH_IGNORE_CHANGED, FLUSH_IGNORE_CHANGED); - _ma_tmp_disable_logging_for_table(file, TRUE); + maria_delete_all_rows(file); } } else if (!file->bulk_insert && @@ -1765,11 +1766,6 @@ void ha_maria::start_bulk_insert(ha_rows rows) { maria_init_bulk_insert(file, thd->variables.bulk_insert_buff_size, rows); } - /** - @todo If we have 0 records here, there is no need to log REDO/UNDO for - each data row, we can just log some special UNDO which will empty the - data file if need to rollback. - */ } DBUG_VOID_RETURN; } diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c index 2263e79fe52..f4e59fe34e0 100644 --- a/storage/maria/ma_blockrec.c +++ b/storage/maria/ma_blockrec.c @@ -5718,6 +5718,23 @@ my_bool write_hook_for_undo_row_update(enum translog_record_type type } +my_bool write_hook_for_undo_bulk_insert(enum translog_record_type type + __attribute__ ((unused)), + TRN *trn, MARIA_HA *tbl_info, + LSN *lsn, void *hook_arg) +{ + /* + We are going to call maria_delete_all_rows(), but without logging and + syncing, as an optimization (if we crash before commit, the UNDO will + empty; if we crash after commit, we have flushed and forced the files). + Status still needs to be reset under log mutex, in case of a concurrent + checkpoint. + */ + _ma_reset_status(tbl_info); + return write_hook_for_undo(type, trn, tbl_info, lsn, hook_arg); +} + + /** @brief Updates table's lsn_of_file_id. diff --git a/storage/maria/ma_blockrec.h b/storage/maria/ma_blockrec.h index e8dc554bb98..6d7e4475868 100644 --- a/storage/maria/ma_blockrec.h +++ b/storage/maria/ma_blockrec.h @@ -266,6 +266,9 @@ my_bool write_hook_for_undo_row_delete(enum translog_record_type type, my_bool write_hook_for_undo_row_update(enum translog_record_type type, TRN *trn, MARIA_HA *tbl_info, LSN *lsn, void *hook_arg); +my_bool write_hook_for_undo_bulk_insert(enum translog_record_type type, + TRN *trn, MARIA_HA *tbl_info, + LSN *lsn, void *hook_arg); my_bool write_hook_for_file_id(enum translog_record_type type, TRN *trn, MARIA_HA *tbl_info, LSN *lsn, void *hook_arg); diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c index d8c553a3173..cee1e7a9b65 100644 --- a/storage/maria/ma_check.c +++ b/storage/maria/ma_check.c @@ -164,10 +164,11 @@ int maria_chk_del(HA_CHECK *param, register MARIA_HA *info, LINT_INIT(old_link); + param->record_checksum=0; + if (share->data_file_type == BLOCK_RECORD) DBUG_RETURN(0); /* No delete links here */ - param->record_checksum=0; delete_link_length=((share->options & HA_OPTION_PACK_RECORD) ? 20 : share->rec_reflength+1); diff --git a/storage/maria/ma_delete_all.c b/storage/maria/ma_delete_all.c index e9fed6ca05f..c209196ff9a 100644 --- a/storage/maria/ma_delete_all.c +++ b/storage/maria/ma_delete_all.c @@ -24,6 +24,10 @@ @param info Maria handler + @note It is important that this function does not rely on the state + information, as it may be called by ma_apply_undo_bulk_insert() on an + inconsistent table left by a crash. + @return Operation status @retval 0 ok @retval 1 error diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c index 21e2262c4a9..4e41b513a25 100644 --- a/storage/maria/ma_loghandler.c +++ b/storage/maria/ma_loghandler.c @@ -616,7 +616,7 @@ static LOG_DESC INIT_LOGREC_INCOMPLETE_GROUP= static LOG_DESC INIT_LOGREC_UNDO_BULK_INSERT= {LOGRECTYPE_VARIABLE_LENGTH, 0, LSN_STORE_SIZE + FILEID_STORE_SIZE, - NULL, write_hook_for_undo, NULL, 1, + NULL, write_hook_for_undo_bulk_insert, NULL, 1, "undo_bulk_insert", LOGREC_LAST_IN_GROUP, NULL, NULL}; static LOG_DESC INIT_LOGREC_REDO_BITMAP_NEW_PAGE= diff --git a/storage/maria/ma_page.c b/storage/maria/ma_page.c index d971010a267..99325dc63b2 100644 --- a/storage/maria/ma_page.c +++ b/storage/maria/ma_page.c @@ -322,6 +322,10 @@ my_off_t _ma_new(register MARIA_HA *info, int level, pos= HA_OFFSET_ERROR; else { + /* + Next deleted page's number is in the header of the present page + (single linked list): + */ share->current_key_del= mi_sizekorr(buff+share->keypage_header); DBUG_ASSERT(share->current_key_del != share->state.key_del && share->current_key_del); diff --git a/storage/maria/ma_pagecache.c b/storage/maria/ma_pagecache.c index d69f37985b7..5b51b2578f8 100644 --- a/storage/maria/ma_pagecache.c +++ b/storage/maria/ma_pagecache.c @@ -4255,7 +4255,7 @@ my_bool pagecache_collect_changed_blocks_with_lsn(PAGECACHE *pagecache, str->length= 8 + /* number of dirty pages */ (2 + /* table id */ 1 + /* data or index file */ - 4 + /* pageno */ + 5 + /* pageno */ LSN_STORE_SIZE /* rec_lsn */ ) * stored_list_size; if (NULL == (str->str= my_malloc(str->length, MYF(MY_WME)))) @@ -4283,10 +4283,9 @@ my_bool pagecache_collect_changed_blocks_with_lsn(PAGECACHE *pagecache, ptr+= 2; ptr[0]= (share->kfile.file == block->hash_link->file.file); ptr++; - /* TODO: We should fix the code here to handle 5 byte page numbers */ - DBUG_ASSERT(block->hash_link->pageno <= UINT_MAX32); - int4store(ptr, block->hash_link->pageno); - ptr+= 4; + DBUG_ASSERT(block->hash_link->pageno < ((ULL(1)) << 40)); + int5store(ptr, block->hash_link->pageno); + ptr+= 5; lsn_store(ptr, block->rec_lsn); ptr+= LSN_STORE_SIZE; if (block->rec_lsn != LSN_MAX) diff --git a/storage/maria/ma_recovery.c b/storage/maria/ma_recovery.c index 46f8d9fc62a..b31e969d345 100644 --- a/storage/maria/ma_recovery.c +++ b/storage/maria/ma_recovery.c @@ -3009,8 +3009,8 @@ static LSN parse_checkpoint_record(LSN lsn) ptr+= 2; is_index= ptr[0]; ptr++; - page_id= uint4korr(ptr); - ptr+= 4; + page_id= uint5korr(ptr); + ptr+= 5; rec_lsn= lsn_korr(ptr); ptr+= LSN_STORE_SIZE; if (new_page((is_index << 16) | table_id, @@ -3056,7 +3056,7 @@ static int new_page(uint32 fileid, pgcache_page_no_t pageid, LSN rec_lsn, struct st_dirty_page *dirty_page) { /* serves as hash key */ - dirty_page->file_and_page_id= (((uint64)fileid) << 32) | pageid; + dirty_page->file_and_page_id= (((uint64)fileid) << 40) | pageid; dirty_page->rec_lsn= rec_lsn; return my_hash_insert(&all_dirty_pages, (uchar *)dirty_page); } diff --git a/storage/maria/ma_recovery_util.c b/storage/maria/ma_recovery_util.c index b2b5c376635..a45a990472e 100644 --- a/storage/maria/ma_recovery_util.c +++ b/storage/maria/ma_recovery_util.c @@ -117,13 +117,12 @@ my_bool _ma_redo_not_needed_for_page(uint16 shortid, LSN lsn, { /* 64-bit key is formed like this: - Most significant byte: 0 - Next byte: 0 if data page, 1 if index page + Most significant byte: 0 if data page, 1 if index page Next 2 bytes: table's short id - Next 4 bytes: page number + Next 5 bytes: page number */ uint64 file_and_page_id= - (((uint64)((index << 16) | shortid)) << 32) | page; + (((uint64)((index << 16) | shortid)) << 40) | page; struct st_dirty_page *dirty_page= (struct st_dirty_page *) hash_search(&all_dirty_pages, (uchar *)&file_and_page_id, sizeof(file_and_page_id)); diff --git a/storage/maria/ma_write.c b/storage/maria/ma_write.c index 163d21c9c28..0310e72a71e 100644 --- a/storage/maria/ma_write.c +++ b/storage/maria/ma_write.c @@ -877,7 +877,7 @@ int _ma_split_page(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo, MARIA_PINNED_PAGE tmp_page_link, *page_link= &tmp_page_link; MARIA_SHARE *share= info->s; int res; - DBUG_ENTER("maria_split_page"); + DBUG_ENTER("_ma_split_page"); LINT_INIT(after_key); DBUG_DUMP("buff", split_buff, _ma_get_page_used(share, split_buff)); |