diff options
author | unknown <monty@mysql.com/narttu.mysql.fi> | 2007-12-04 23:23:42 +0200 |
---|---|---|
committer | unknown <monty@mysql.com/narttu.mysql.fi> | 2007-12-04 23:23:42 +0200 |
commit | ebf7ab7bce003093745337be43cd6107726aa0fb (patch) | |
tree | 327fd39b1039bcb9b18fae4b8ea7e73e121beb2c | |
parent | 143f35e611ab9fdf51300d0bf458bdbf1f8b7625 (diff) | |
download | mariadb-git-ebf7ab7bce003093745337be43cd6107726aa0fb.tar.gz |
Added error HA_ERR_FILE_TOO_SHORT to be used when files are shorter than expected (by my_read/my_pread)
Added debugger hook _my_dbug_put_break_here() that is called if we get a CRC that matches --debug-crc-break (my_crc_dbug_break)
Fixed REDO_REPAIR to use all repair modes (repair, repair_by_sort, repair_paralell
REDO_REPAIR now also logs used key map
Fixed some bugs in REDO logging of key pages
Better error messages from maria_read_log
Added my_readwrite_flags to init_pagecache() to be able to get better error messages and simplify code.
Don't allow pagecaches with less than 8 blocks (Causes strange crashes)
Added EXTRA_DEBUG_KEY_CHANGES. When this is defined some REDO_INDEX entries contains page checksums (these are calculated and checked in DBUG mode, ignored otherwise)
Fixed bug in ma_pagecache unit tests that caused program to sometimes fail
Added some missing calls to MY_INIT() that caused some unit tests to fail
Fixed that TRUNCATE works properly on temporary MyISAM files
Updates some result files to new table checksums results (checksum when NULL fields are ignored)
perl test-insert can be replayed with maria_read_log!
sql/share/Makefile.am:
Change mode to -rw-rw-r--
BitKeeper/etc/ignore:
added storage/maria/unittest/page_cache_test_file_1 storage/maria/unittest/pagecache_debug.log
include/maria.h:
Added maria_tmpdir
include/my_base.h:
Added error HA_ERR_FILE_TOO_SHORT
include/my_sys.h:
Added variable my_crc_dbug_check
Added function my_dbug_put_break_here()
include/myisamchk.h:
Added org_key_map (Needed for writing REDO record for REPAIR)
mysql-test/r/innodb.result:
Updated to new checksum algorithm (NULL ignored)
mysql-test/r/mix2_myisam.result:
Updated to new checksum algorithm (NULL ignored)
mysql-test/r/myisam.result:
Updated to new checksum algorithm (NULL ignored)
mysql-test/t/myisam.test:
Added used table
mysys/checksum.c:
Added DBUG for checksum results
Added debugger hook so that _my_dbug_put_break_here() is called if we get matching CRC
mysys/lf_alloc-pin.c:
Fixed compiler warning
mysys/my_handler.c:
Added new error message
mysys/my_init.c:
If my_progname is not given, use 'unknown' form my_progname_short
Added debugger function my_debug_put_break_here()
mysys/my_pread.c:
In case of too short file when MY_NABP or MY_FNABP is specified, give error HA_ERR_FILE_TO_SHORT
mysys/my_read.c:
In case of too short file when MY_NABP or MY_FNABP is specified, give error HA_ERR_FILE_TO_SHORT
sql/mysqld.cc:
Added debug option --debug-crc-break
sql/sql_parse.cc:
Trivial optimization
storage/maria/ha_maria.cc:
Renamed variable to be more logical
Ensure that param.testflag is correct when calling repair
Added extra argument to init_pagecache
Set default value for maria_tempdir
storage/maria/ma_blockrec.c:
Test for HA_ERR_FILE_TOO_SHORT instead for -1
storage/maria/ma_cache.c:
Test for HA_ERR_FILE_TOO_SHORT instead for -1
storage/maria/ma_check.c:
Set param->testflag to match how repair is run (needed for REDO logging)
Simple optimization
Moved flag if page is node from pagelength to keypage-flag byte
Log used key map in REDO log.
storage/maria/ma_delete.c:
Remember previous UNDO entry when writing undo (for future CLR records)
Moved flag if page is node from pagelength to keypage-flag byte
Fixed some bugs in redo logging
Added CRC for some translog REDO_INDEX entries
storage/maria/ma_dynrec.c:
Test for HA_ERR_FILE_TOO_SHORT instead for -1
storage/maria/ma_ft_update.c:
Fixed call to _ma_store_page_used()
storage/maria/ma_key_recover.c:
Added CRC for some translog REDO_INDEX entries
Removed not needed pagecache_write() in _ma_apply_redo_index()
storage/maria/ma_locking.c:
Test for HA_ERR_FILE_TOO_SHORT instead for -1
storage/maria/ma_loghandler.c:
Added used key map to REDO_REPAIR_TABLE
storage/maria/ma_loghandler.h:
Added operation for checksum of key pages
storage/maria/ma_open.c:
Allocate storage for undo lsn pointers
storage/maria/ma_pagecache.c:
Remove not needed include file
Change logging to use fd: for file descritors as other code
Added my_readwrite_flags to init_pagecache() to be able to get better error messages for maria_chk/maria_read_log
Don't allow pagecaches with less than 8 blocks
Remove wrong DBUG_ASSERT()
storage/maria/ma_pagecache.h:
Added readwrite_flags
storage/maria/ma_recovery.c:
Better error messages for maria_read_log:
- Added eprint() for printing error messages
- Print extra \n before error message if we are printing %0 %10 ...
Added used key_map to REDO_REPAIR log entry
More DBUG
Call same repair method that was used by mysqld
storage/maria/ma_rt_index.c:
Moved flag if page is node from pagelength to keypage-flag byte
storage/maria/ma_rt_key.c:
Fixed call to _ma_store_page_used()
storage/maria/ma_rt_split.c:
Moved flag if page is node from pagelength to keypage-flag byte
storage/maria/ma_static.c:
Added maria_tmpdir
storage/maria/ma_test1.c:
Updated call to init_pagecache()
storage/maria/ma_test2.c:
Updated call to init_pagecache()
storage/maria/ma_test3.c:
Updated call to init_pagecache()
storage/maria/ma_write.c:
Removed #ifdef NOT_YET
Moved flag if page is node from pagelength to keypage-flag byte
Fixed bug in _ma_log_del_prefix()
storage/maria/maria_chk.c:
Fixed wrong min limit for page_buffer_size
Updated call to init_pagecache()
storage/maria/maria_def.h:
Added EXTRA_DEBUG_KEY_CHANGES. When this is defined some REDO_INDEX entries contains page checksums
Moved flag if page is node from pagelength to keypage-flag byte
storage/maria/maria_ftdump.c:
Updated call to init_pagecache()
storage/maria/maria_pack.c:
Updated call to init_pagecache()
Reset share->state.create_rename_lsn & share->state.is_of_horizon
storage/maria/maria_read_log.c:
Better error messages
Added --tmpdir option (needed to set temporary directory for REDO_REPAIR)
Added --start-from-lsn
Changed option for --display-only to 'd' (wanted to use -o for 'offset')
storage/maria/unittest/lockman2-t.c:
Added missing call to MY_INIT()
storage/maria/unittest/ma_pagecache_consist.c:
Updated call to init_pagecache()
storage/maria/unittest/ma_pagecache_single.c:
Fixed bug that caused program to sometimes fail
Added some DBUG_ASSERTS()
Changed some calls to malloc()/free() to my_malloc()/my_free()
Create extra file to expose original hard-to-find bug
storage/maria/unittest/ma_test_loghandler-t.c:
Updated call to init_pagecache()
storage/maria/unittest/ma_test_loghandler_first_lsn-t.c:
Updated call to init_pagecache()
storage/maria/unittest/ma_test_loghandler_max_lsn-t.c:
Updated call to init_pagecache()
storage/maria/unittest/ma_test_loghandler_multigroup-t.c:
Updated call to init_pagecache()
storage/maria/unittest/ma_test_loghandler_multithread-t.c:
Updated call to init_pagecache()
storage/maria/unittest/ma_test_loghandler_noflush-t.c:
Updated call to init_pagecache()
storage/maria/unittest/ma_test_loghandler_pagecache-t.c:
Updated call to init_pagecache()
storage/maria/unittest/ma_test_loghandler_purge-t.c:
Updated call to init_pagecache()
storage/maria/unittest/test_file.c:
Changed malloc()/free() to my_malloc()/my_free()
Fixed memory leak
Changd logic a bit while trying to find bug in reset_file()
storage/maria/unittest/trnman-t.c:
Added missing call to MY_INIT()
storage/myisam/mi_cache.c:
Test for HA_ERR_FILE_TOO_SHORT instead for -1
storage/myisam/mi_create.c:
Removed O_EXCL to get TRUNCATE to work for temporary files
storage/myisam/mi_dynrec.c:
Test for HA_ERR_FILE_TOO_SHORT instead for -1
storage/myisam/mi_locking.c:
Test for HA_ERR_FILE_TOO_SHORT instead for -1
mysql-test/r/old-mode.result:
New BitKeeper file ``mysql-test/r/old-mode.result''
mysql-test/t/old-mode-master.opt:
New BitKeeper file ``mysql-test/t/old-mode-master.opt''
mysql-test/t/old-mode.test:
New BitKeeper file ``mysql-test/t/old-mode.test''
65 files changed, 736 insertions, 429 deletions
diff --git a/.bzrignore b/.bzrignore index 5bdb136c0c6..acbf0040063 100644 --- a/.bzrignore +++ b/.bzrignore @@ -3063,3 +3063,5 @@ libmysqld/sql_tablespace.cc sql/link_sources ylwrap libmysql_r/link_sources +storage/maria/unittest/page_cache_test_file_1 +storage/maria/unittest/pagecache_debug.log diff --git a/include/maria.h b/include/maria.h index 9f6672d482c..8baacfc9c13 100644 --- a/include/maria.h +++ b/include/maria.h @@ -255,7 +255,7 @@ extern my_bool maria_delay_key_write; extern my_off_t maria_max_temp_length; extern ulong maria_bulk_insert_tree_size, maria_data_pointer_size; extern PAGECACHE maria_pagecache_var, *maria_pagecache; - +extern MY_TMPDIR *maria_tmpdir; /* Prototypes for maria-functions */ diff --git a/include/my_base.h b/include/my_base.h index 684e3633fe3..2b60ff552a4 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -422,7 +422,8 @@ enum ha_base_keytype { #define HA_ERR_LOGGING_IMPOSSIBLE 170 #define HA_ERR_NEW_FILE 171 /* New file format */ #define HA_ERR_INITIALIZATION 172 /* Error during initialization */ -#define HA_ERR_LAST 172 /* Copy of last error nr */ +#define HA_ERR_FILE_TOO_SHORT 173 /* File too short */ +#define HA_ERR_LAST 173 /* Copy of last error nr */ /* Number of different errors */ #define HA_ERR_ERRORS (HA_ERR_LAST - HA_ERR_FIRST + 1) diff --git a/include/my_sys.h b/include/my_sys.h index c884dd741f6..f8f3411f337 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -546,6 +546,7 @@ my_off_t my_b_safe_tell(IO_CACHE* info); /* picks the correct tell() */ *(info)->current_pos) typedef uint32 ha_checksum; +extern ha_checksum my_crc_dbug_check; /* Define the type of function to be passed to process_default_option_files */ typedef int (*Process_option_func)(void *ctx, const char *group_name, @@ -858,6 +859,7 @@ extern int unpackfrm(uchar **, size_t *, const uchar *); extern ha_checksum my_checksum(ha_checksum crc, const uchar *mem, size_t count); +extern void my_debug_put_break_here(void); extern void my_sleep(ulong m_seconds); extern ulong crc32(ulong crc, const uchar *buf, uint len); extern uint my_set_max_open_files(uint files); diff --git a/include/myisamchk.h b/include/myisamchk.h index 30b986a835a..3c5d59884be 100644 --- a/include/myisamchk.h +++ b/include/myisamchk.h @@ -128,6 +128,7 @@ typedef struct st_handler_check_param ha_checksum key_crc[HA_MAX_POSSIBLE_KEY]; ha_checksum tmp_key_crc[HA_MAX_POSSIBLE_KEY]; ha_checksum tmp_record_checksum; + ulonglong org_key_map; size_t use_buffers, read_buffer_length, write_buffer_length; size_t sort_buffer_length, sort_key_blocks; ulong rec_per_key_part[HA_MAX_KEY_SEG * HA_MAX_POSSIBLE_KEY]; diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index d0b67e90afb..e7910ee9e32 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -1440,7 +1440,7 @@ insert t2 select * from t1; insert t3 select * from t1; checksum table t1, t2, t3, t4 quick; Table Checksum -test.t1 2948697075 +test.t1 3442722830 test.t2 NULL test.t3 NULL test.t4 NULL @@ -1448,17 +1448,17 @@ Warnings: Error 1146 Table 'test.t4' doesn't exist checksum table t1, t2, t3, t4; Table Checksum -test.t1 2948697075 -test.t2 2948697075 -test.t3 2948697075 +test.t1 3442722830 +test.t2 3442722830 +test.t3 3442722830 test.t4 NULL Warnings: Error 1146 Table 'test.t4' doesn't exist checksum table t1, t2, t3, t4 extended; Table Checksum -test.t1 2948697075 -test.t2 2948697075 -test.t3 2948697075 +test.t1 3442722830 +test.t2 3442722830 +test.t3 3442722830 test.t4 NULL Warnings: Error 1146 Table 'test.t4' doesn't exist diff --git a/mysql-test/r/mix2_myisam.result b/mysql-test/r/mix2_myisam.result index cabc4de8d21..e0a3d1af089 100644 --- a/mysql-test/r/mix2_myisam.result +++ b/mysql-test/r/mix2_myisam.result @@ -1232,34 +1232,34 @@ insert t5 select * from t1; insert t6 select * from t1; checksum table t1, t2, t3, t4, t5, t6, t7 quick; Table Checksum -test.t1 2948697075 +test.t1 3442722830 test.t2 NULL test.t3 NULL test.t4 NULL -test.t5 2948697075 +test.t5 3442722830 test.t6 NULL test.t7 NULL Warnings: Error 1146 Table 'test.t7' doesn't exist checksum table t1, t2, t3, t4, t5, t6, t7; Table Checksum -test.t1 2948697075 -test.t2 2948697075 -test.t3 2948697075 -test.t4 2948697075 -test.t5 2948697075 -test.t6 2948697075 +test.t1 3442722830 +test.t2 3442722830 +test.t3 3442722830 +test.t4 3442722830 +test.t5 3442722830 +test.t6 3442722830 test.t7 NULL Warnings: Error 1146 Table 'test.t7' doesn't exist checksum table t1, t2, t3, t4, t5, t6, t7 extended; Table Checksum -test.t1 2948697075 -test.t2 2948697075 -test.t3 2948697075 -test.t4 2948697075 -test.t5 2948697075 -test.t6 2948697075 +test.t1 3442722830 +test.t2 3442722830 +test.t3 3442722830 +test.t4 3442722830 +test.t5 3442722830 +test.t6 3442722830 test.t7 NULL Warnings: Error 1146 Table 'test.t7' doesn't exist diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index 73661897ee1..cb9c3355f7a 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -1,4 +1,4 @@ -drop table if exists t1,t2; +drop table if exists t1,t2,t3; SET SQL_WARNINGS=1; CREATE TABLE t1 ( STRING_DATA char(255) default NULL, @@ -551,22 +551,22 @@ insert t1 values (1, "aaa", "bbb"), (NULL, "", "ccccc"), (0, NULL, ""); insert t2 select * from t1; checksum table t1, t2, t3 quick; Table Checksum -test.t1 2948697075 +test.t1 3442722830 test.t2 NULL test.t3 NULL Warnings: Error 1146 Table 'test.t3' doesn't exist checksum table t1, t2, t3; Table Checksum -test.t1 2948697075 -test.t2 2948697075 +test.t1 3442722830 +test.t2 3442722830 test.t3 NULL Warnings: Error 1146 Table 'test.t3' doesn't exist checksum table t1, t2, t3 extended; Table Checksum -test.t1 2948697075 -test.t2 2948697075 +test.t1 3442722830 +test.t2 3442722830 test.t3 NULL Warnings: Error 1146 Table 'test.t3' doesn't exist diff --git a/mysql-test/r/old-mode.result b/mysql-test/r/old-mode.result new file mode 100644 index 00000000000..df2c0b6fee0 --- /dev/null +++ b/mysql-test/r/old-mode.result @@ -0,0 +1,14 @@ +drop table if exists t1,t2; +create table t1 (a int, b varchar(200), c text not null) checksum=1; +create table t2 (a int, b varchar(200), c text not null) checksum=0; +insert t1 values (1, "aaa", "bbb"), (NULL, "", "ccccc"), (0, NULL, ""); +insert t2 select * from t1; +checksum table t1, t2; +Table Checksum +test.t1 3442722830 +test.t2 2948697075 +checksum table t1, t2 extended; +Table Checksum +test.t1 2948697075 +test.t2 2948697075 +drop table t1,t2; diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test index b06fd536f45..5c6fe0fc887 100644 --- a/mysql-test/t/myisam.test +++ b/mysql-test/t/myisam.test @@ -4,7 +4,7 @@ # Initialise --disable_warnings -drop table if exists t1,t2; +drop table if exists t1,t2,t3; --enable_warnings SET SQL_WARNINGS=1; diff --git a/mysql-test/t/old-mode-master.opt b/mysql-test/t/old-mode-master.opt new file mode 100644 index 00000000000..840ee0dedcf --- /dev/null +++ b/mysql-test/t/old-mode-master.opt @@ -0,0 +1 @@ +--old=1 diff --git a/mysql-test/t/old-mode.test b/mysql-test/t/old-mode.test new file mode 100644 index 00000000000..4fa21f761ca --- /dev/null +++ b/mysql-test/t/old-mode.test @@ -0,0 +1,16 @@ +# +# Test 'old' mode +# + +# Initialise +--disable_warnings +drop table if exists t1,t2; +--enable_warnings + +create table t1 (a int, b varchar(200), c text not null) checksum=1; +create table t2 (a int, b varchar(200), c text not null) checksum=0; +insert t1 values (1, "aaa", "bbb"), (NULL, "", "ccccc"), (0, NULL, ""); +insert t2 select * from t1; +checksum table t1, t2; +checksum table t1, t2 extended; +drop table t1,t2; diff --git a/mysys/checksum.c b/mysys/checksum.c index 4f86f6845f0..0cc9801c2b1 100644 --- a/mysys/checksum.c +++ b/mysys/checksum.c @@ -18,6 +18,8 @@ #include <my_sys.h> #include <zlib.h> +ha_checksum my_crc_dbug_check= 1; /* Unlikely number */ + /* Calculate a long checksum for a memoryblock. @@ -34,9 +36,13 @@ ha_checksum my_checksum(ha_checksum crc, const uchar *pos, size_t length) const uchar *end=pos+length; for ( ; pos != end ; pos++) crc=((crc << 8) + *((uchar*) pos)) + (crc >> (8*sizeof(ha_checksum)-8)); - return crc; #else - return (ha_checksum)crc32((uint)crc, pos, length); + crc= (ha_checksum) crc32((uint)crc, pos, length); +#endif /* NOT_USED */ + DBUG_PRINT("info", ("crc: %lu", (ulong) crc)); +#ifndef DBUG_OFF + if (crc == my_crc_dbug_check) + my_debug_put_break_here(); #endif + return crc; } - diff --git a/mysys/lf_alloc-pin.c b/mysys/lf_alloc-pin.c index a847d722023..ff9c5a42f81 100644 --- a/mysys/lf_alloc-pin.c +++ b/mysys/lf_alloc-pin.c @@ -333,6 +333,7 @@ static void _lf_pinbox_real_free(LF_PINS *pins) struct st_lf_alloc_node *first, *last= NULL; LF_PINBOX *pinbox= pins->pinbox; + LINT_INIT(first); npins= pinbox->pins_in_array+1; #ifdef HAVE_ALLOCA diff --git a/mysys/my_handler.c b/mysys/my_handler.c index f7cf4f310d7..2b1c91a43e2 100644 --- a/mysys/my_handler.c +++ b/mysys/my_handler.c @@ -626,7 +626,8 @@ static const char *handler_error_messages[]= "Record is the same", "It is not possible to log this statement", "The table is of a new format not supported by this version", - "Got a fatal error during initialzaction of handler" + "Got a fatal error during initialzaction of handler", + "File to short; Expected more data in file" }; diff --git a/mysys/my_init.c b/mysys/my_init.c index 8ddc6092f79..850333e0100 100644 --- a/mysys/my_init.c +++ b/mysys/my_init.c @@ -78,7 +78,10 @@ my_bool my_init(void) my_umask= 0660; /* Default umask for new files */ my_umask_dir= 0700; /* Default umask for new directories */ init_glob_errs(); - my_progname_short= my_progname + dirname_length(my_progname); + my_progname_short= "unknown"; + if (my_progname) + my_progname_short= my_progname + dirname_length(my_progname); + #if defined(THREAD) && defined(SAFE_MUTEX) safe_mutex_global_init(); /* Must be called early */ #endif @@ -233,6 +236,13 @@ Voluntary context switches %ld, Involuntary context switches %ld\n", my_init_done=0; } /* my_end */ +#ifndef DBUG_OFF +/* Dummy tag function for debugging */ + +void my_debug_put_break_here(void) +{ +} +#endif #ifdef __WIN__ diff --git a/mysys/my_pread.c b/mysys/my_pread.c index de7a2b611ed..821d8636d8e 100644 --- a/mysys/my_pread.c +++ b/mysys/my_pread.c @@ -15,6 +15,7 @@ #include "mysys_priv.h" #include "mysys_err.h" +#include "my_base.h" #include <errno.h> #ifdef HAVE_PREAD #include <unistd.h> @@ -63,7 +64,11 @@ size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset, pthread_mutex_unlock(&my_file_info[Filedes].mutex); #else if ((error= ((readbytes= pread(Filedes, Buffer, Count, offset)) != Count))) - my_errno= errno ? errno : -1; + { + my_errno= errno; + if (errno == 0 || (errno == -1 && (MyFlags & (MY_NABP | MY_FNABP)))) + my_errno= HA_ERR_FILE_TOO_SHORT; + } #endif if (error || readbytes != Count) { diff --git a/mysys/my_read.c b/mysys/my_read.c index f3e8a4b300e..ee91620e163 100644 --- a/mysys/my_read.c +++ b/mysys/my_read.c @@ -15,9 +15,9 @@ #include "mysys_priv.h" #include "mysys_err.h" +#include <my_base.h> #include <errno.h> - /* Read a chunk of bytes from a file with retry's if needed @@ -46,7 +46,9 @@ size_t my_read(File Filedes, uchar *Buffer, size_t Count, myf MyFlags) errno= 0; /* Linux doesn't reset this */ if ((readbytes= read(Filedes, Buffer, Count)) != Count) { - my_errno= errno ? errno : -1; + my_errno= errno; + if (errno == 0 || (errno == -1 && (MyFlags & (MY_NABP | MY_FNABP)))) + my_errno= HA_ERR_FILE_TOO_SHORT; DBUG_PRINT("warning",("Read only %d bytes off %lu from %d, errno: %d", (int) readbytes, (ulong) Count, Filedes, my_errno)); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 731d49474f7..c95522b114d 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -340,6 +340,7 @@ static char *default_storage_engine_str; static char compiled_default_collation_name[]= MYSQL_DEFAULT_COLLATION_NAME; static I_List<THD> thread_cache; static double long_query_time; +static ulong opt_my_crc_dbug_check; static pthread_cond_t COND_thread_cache, COND_flush_thread_cache; @@ -5119,7 +5120,7 @@ enum options_mysqld OPT_SECURE_FILE_PRIV, OPT_MIN_EXAMINED_ROW_LIMIT, OPT_LOG_SLOW_SLAVE_STATEMENTS, - OPT_OLD_MODE + OPT_DEBUG_CRC, OPT_OLD_MODE }; @@ -5244,6 +5245,10 @@ struct my_option my_long_options[] = #ifndef DBUG_OFF {"debug", '#', "Debug log.", (uchar**) &default_dbug_option, (uchar**) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-crc-break", OPT_DEBUG_CRC, + "Call my_debug_put_break_here() if crc matches this number (for debug).", + (uchar**) &opt_my_crc_dbug_check, (uchar**) &opt_my_crc_dbug_check, + 0, GET_ULONG, REQUIRED_ARG, 0, 0, ~(ulong) 0L, 0, 0, 0}, #endif {"default-character-set", 'C', "Set the default character set (deprecated option, use --character-set-server instead).", (uchar**) &default_character_set_name, (uchar**) &default_character_set_name, @@ -7893,6 +7898,7 @@ static void get_options(int *argc,char **argv) /* Set global variables based on startup options */ myisam_block_size=(uint) 1 << my_bit_log2(opt_myisam_block_size); + my_crc_dbug_check= opt_my_crc_dbug_check; /* long_query_time is in microseconds */ global_system_variables.long_query_time= max_system_variables.long_query_time= diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e440aeaa588..ad0ba27651f 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4683,8 +4683,7 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, (see SQLCOM_GRANT case, mysql_execute_command() function) and set db_is_pattern according to 'dont_check_global_grants' value. */ - bool db_is_pattern= (test(want_access & GRANT_ACL) && - dont_check_global_grants); + bool db_is_pattern= ((want_access & GRANT_ACL) && dont_check_global_grants); #endif ulong dummy; DBUG_ENTER("check_access"); diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index 287c183c830..46e443d33f7 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -1211,7 +1211,7 @@ int ha_maria::repair(THD *thd, HA_CHECK ¶m, bool do_optimize) ulonglong key_map= ((local_testflag & T_CREATE_MISSING_KEYS) ? maria_get_mask_all_keys_active(share->base.keys) : share->state.key_map); - uint testflag= param.testflag; + uint save_testflag= param.testflag; if (maria_test_if_sort_rep(file, file->state->records, key_map, 0) && (local_testflag & T_REP_BY_SORT)) { @@ -1226,6 +1226,7 @@ int ha_maria::repair(THD *thd, HA_CHECK ¶m, bool do_optimize) /* TODO: respect maria_repair_threads variable */ my_snprintf(buf, 40, "Repair with %d threads", my_count_bits(key_map)); thd->proc_info= buf; + param.testflag|= T_REP_PARALLEL; error= maria_repair_parallel(¶m, file, fixed_name, param.testflag & T_QUICK); thd->proc_info= "Repair done"; // to reset proc_info, as @@ -1234,6 +1235,7 @@ int ha_maria::repair(THD *thd, HA_CHECK ¶m, bool do_optimize) else { thd->proc_info= "Repair by sorting"; + param.testflag|= T_REP_BY_SORT; error= maria_repair_by_sort(¶m, file, fixed_name, param.testflag & T_QUICK); } @@ -1241,7 +1243,7 @@ int ha_maria::repair(THD *thd, HA_CHECK ¶m, bool do_optimize) else { thd->proc_info= "Repair with keycache"; - param.testflag &= ~T_REP_BY_SORT; + param.testflag &= ~(T_REP_BY_SORT | T_REP_PARALLEL); error= maria_repair(¶m, file, fixed_name, param.testflag & T_QUICK); /** @todo RECOVERY BUG we do things with the index file @@ -1249,7 +1251,7 @@ int ha_maria::repair(THD *thd, HA_CHECK ¶m, bool do_optimize) record and bumped create_rename_lsn. Is it ok? */ } - param.testflag= testflag; + param.testflag= save_testflag; optimize_done= 1; } if (!error) @@ -2410,13 +2412,14 @@ static int ha_maria_init(void *p) maria_hton->flags= HTON_CAN_RECREATE | HTON_SUPPORT_LOG_TABLES; bzero(maria_log_pagecache, sizeof(*maria_log_pagecache)); maria_data_root= mysql_real_data_home; + maria_tmpdir= &mysql_tmpdir_list; /* For REDO */ res= maria_init() || ma_control_file_create_or_open() || - (init_pagecache(maria_pagecache, + !init_pagecache(maria_pagecache, pagecache_buffer_size, pagecache_division_limit, - pagecache_age_threshold, MARIA_KEY_BLOCK_LENGTH) == 0) || - (init_pagecache(maria_log_pagecache, + pagecache_age_threshold, MARIA_KEY_BLOCK_LENGTH, 0) || + !init_pagecache(maria_log_pagecache, TRANSLOG_PAGECACHE_SIZE, 0, 0, - TRANSLOG_PAGE_SIZE) == 0) || + TRANSLOG_PAGE_SIZE, 0) || translog_init(maria_data_root, TRANSLOG_FILE_SIZE, MYSQL_VERSION_ID, server_id, maria_log_pagecache, TRANSLOG_DEFAULT_FLAGS) || diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c index f4abbc2c1c5..36218351b7b 100644 --- a/storage/maria/ma_blockrec.c +++ b/storage/maria/ma_blockrec.c @@ -5045,7 +5045,7 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn, PAGECACHE_PLAIN_PAGE, PAGECACHE_LOCK_WRITE, &page_link.link))) { - if (my_errno != -1) /* If not read outside of file */ + if (my_errno != HA_ERR_FILE_TOO_SHORT) /* If not read outside of file */ { pagecache_unlock_by_link(share->pagecache, page_link.link, PAGECACHE_LOCK_WRITE_UNLOCK, @@ -5487,7 +5487,7 @@ uint _ma_apply_redo_insert_row_blobs(MARIA_HA *info, PAGECACHE_PLAIN_PAGE, PAGECACHE_LOCK_WRITE, &page_link.link))) { - if (my_errno != -1) /* If not read outside of file */ + if (my_errno != HA_ERR_FILE_TOO_SHORT) /* If not read outside of file */ { pagecache_unlock_by_link(share->pagecache, page_link.link, PAGECACHE_LOCK_WRITE_UNLOCK, diff --git a/storage/maria/ma_cache.c b/storage/maria/ma_cache.c index 6b1f9ec3fae..0cd4a356f70 100644 --- a/storage/maria/ma_cache.c +++ b/storage/maria/ma_cache.c @@ -97,8 +97,8 @@ int _ma_read_cache(IO_CACHE *info, uchar *buff, my_off_t pos, uint length, DBUG_PRINT("error", ("Error %d reading next-multi-part block (Got %d bytes)", my_errno, (int) read_length)); - if (!my_errno || my_errno == -1) - my_errno=HA_ERR_WRONG_IN_RECORD; + if (!my_errno || my_errno == HA_ERR_FILE_TOO_SHORT) + my_errno= HA_ERR_WRONG_IN_RECORD; DBUG_RETURN(1); } bzero(buff+read_length,MARIA_BLOCK_INFO_HEADER_LENGTH - in_buff_length - diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c index f30ebebd6e7..d3e472c3ebb 100644 --- a/storage/maria/ma_check.c +++ b/storage/maria/ma_check.c @@ -2051,6 +2051,11 @@ static void initialize_variables_for_repair(HA_CHECK *param, if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD)) param->testflag|= T_CALC_CHECKSUM; param->glob_crc= 0; + if (rep_quick) + param->testflag|= T_QUICK; + else + param->testflag&= ~T_QUICK; + param->org_key_map= info->s->state.key_map; sort_param->sort_info= sort_info; sort_param->fix_datafile= (my_bool) (! rep_quick); @@ -2872,7 +2877,7 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info, double *rec_per_key_part; char llbuff[22]; MARIA_SORT_INFO sort_info; - ulonglong key_map=share->state.key_map; + ulonglong key_map= share->state.key_map; myf sync_dir= ((share->now_transactional && !share->temporary) ? MY_SYNC_DIR : 0); my_bool scan_inited= 0; @@ -3005,9 +3010,7 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info, for (sort_param.key=0 ; sort_param.key < share->base.keys ; rec_per_key_part+=sort_param.keyinfo->keysegs, sort_param.key++) { - sort_param.read_cache=param->read_cache; sort_param.keyinfo=share->keyinfo+sort_param.key; - sort_param.seg=sort_param.keyinfo->seg; if (! maria_is_key_active(key_map, sort_param.key)) { /* Remember old statistics for key */ @@ -3020,6 +3023,9 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info, if ((!(param->testflag & T_SILENT))) printf ("- Fixing index %d\n",sort_param.key+1); + + sort_param.read_cache=param->read_cache; + sort_param.seg=sort_param.keyinfo->seg; sort_param.max_pos= sort_param.pos= org_header_length; keyseg=sort_param.seg; bzero((char*) sort_param.unique,sizeof(sort_param.unique)); @@ -3364,9 +3370,6 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info, printf("Data records: %s\n", llstr(start_records,llbuff)); } - if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD)) - param->testflag|=T_CALC_CHECKSUM; - if (_ma_flush_table_files(info, MARIA_FLUSH_DATA | MARIA_FLUSH_INDEX, FLUSH_FORCE_WRITE, FLUSH_IGNORE_CHANGED)) goto err; @@ -4815,14 +4818,17 @@ static int sort_insert_key(MARIA_SORT_PARAM *sort_param, /* Save pointer to previous block */ if (nod_flag) + { + _ma_store_keypage_flag(info, anc_buff, KEYPAGE_FLAG_ISNOD); _ma_kpointer(info,key_block->end_pos,prev_block); + } t_length=(*keyinfo->pack_key)(keyinfo,nod_flag, (uchar*) 0,lastkey,lastkey,key, &s_temp); (*keyinfo->store_key)(keyinfo, key_block->end_pos+nod_flag,&s_temp); a_length+=t_length; - _ma_store_page_used(info, anc_buff, a_length, nod_flag); + _ma_store_page_used(info, anc_buff, a_length); key_block->end_pos+=t_length; if (a_length <= keyinfo->block_length) { @@ -4832,7 +4838,7 @@ static int sort_insert_key(MARIA_SORT_PARAM *sort_param, } /* Fill block with end-zero and write filled block */ - _ma_store_page_used(info, anc_buff, key_block->last_length, nod_flag); + _ma_store_page_used(info, anc_buff, key_block->last_length); bzero(anc_buff+key_block->last_length, keyinfo->block_length- key_block->last_length); key_file_length=info->state->key_file_length; @@ -5812,8 +5818,7 @@ static int write_log_record_for_repair(const HA_CHECK *param, MARIA_HA *info) if (translog_inited && !maria_in_recovery && info->s->base.born_transactional) { - my_bool now_transactional= info->s->now_transactional; - info->s->now_transactional= 1; + my_bool save_now_transactional= info->s->now_transactional; /* For now this record is only informative. It could serve when applying @@ -5833,15 +5838,21 @@ static int write_log_record_for_repair(const HA_CHECK *param, MARIA_HA *info) record). */ LEX_STRING log_array[TRANSLOG_INTERNAL_PARTS + 1]; - uchar log_data[FILEID_STORE_SIZE + 4]; + uchar log_data[FILEID_STORE_SIZE + 4 + 8]; LSN lsn; - log_array[TRANSLOG_INTERNAL_PARTS + 0].str= (char*) log_data; - log_array[TRANSLOG_INTERNAL_PARTS + 0].length= sizeof(log_data); + /* testflag gives an idea of what REPAIR did (in particular T_QUICK or not: did it touch the data file or not?). */ int4store(log_data + FILEID_STORE_SIZE, param->testflag); + /* org_key_map is used when recreating index after a load data infile */ + int8store(log_data + FILEID_STORE_SIZE + 4, param->org_key_map); + + log_array[TRANSLOG_INTERNAL_PARTS + 0].str= (char*) log_data; + log_array[TRANSLOG_INTERNAL_PARTS + 0].length= sizeof(log_data); + + info->s->now_transactional= 1; if (unlikely(translog_write_record(&lsn, LOGREC_REDO_REPAIR_TABLE, &dummy_transaction_object, info, sizeof(log_data), @@ -5857,7 +5868,7 @@ static int write_log_record_for_repair(const HA_CHECK *param, MARIA_HA *info) */ if (_ma_update_create_rename_lsn(share, lsn, TRUE)) return 1; - info->s->now_transactional= now_transactional; + info->s->now_transactional= save_now_transactional; } return 0; } diff --git a/storage/maria/ma_delete.c b/storage/maria/ma_delete.c index 12e2f2e426d..58203de0568 100644 --- a/storage/maria/ma_delete.c +++ b/storage/maria/ma_delete.c @@ -176,6 +176,7 @@ int _ma_ck_delete(register MARIA_HA *info, uint keynr, uchar *key, struct st_msg_to_write_hook_for_undo_key msg; enum translog_record_type log_type= LOGREC_UNDO_KEY_DELETE; + info->key_delete_undo_lsn[keynr]= info->trn->undo_lsn; lsn_store(log_data, info->trn->undo_lsn); key_nr_store(log_data + LSN_STORE_SIZE + FILEID_STORE_SIZE, keynr); log_pos= log_data + LSN_STORE_SIZE + FILEID_STORE_SIZE + KEY_NR_STORE_SIZE; @@ -436,7 +437,7 @@ static int d_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo, anc_page_link->changed= 1; anc_buff_length-= tmp; - _ma_store_page_used(info, anc_buff, anc_buff_length, nod_flag); + _ma_store_page_used(info, anc_buff, anc_buff_length); /* Log initial changes on pages @@ -622,7 +623,7 @@ static int del(register MARIA_HA *info, MARIA_KEYDEF *keyinfo, } /* Remove last key from leaf page */ - _ma_store_page_used(info, leaf_buff, key_start-leaf_buff, nod_flag); + _ma_store_page_used(info, leaf_buff, key_start-leaf_buff); if (info->s->now_transactional && _ma_log_suffix(info, leaf_page, leaf_buff, leaf_length, @@ -659,11 +660,10 @@ static int del(register MARIA_HA *info, MARIA_KEYDEF *keyinfo, if (!(*keyinfo->get_key)(keyinfo,share->base.key_reflength,&keypos,ret_key)) goto err; _ma_kpointer(info,keypos - share->base.key_reflength,next_block); - _ma_store_page_used(info, anc_buff, a_length + length, - share->base.key_reflength); + _ma_store_page_used(info, anc_buff, a_length + length); if (info->s->now_transactional && - _ma_log_add(info, anc_page, anc_buff, a_length + length, + _ma_log_add(info, anc_page, anc_buff, a_length, key_start, s_temp.changed_length, s_temp.move_length, 1)) goto err; @@ -704,7 +704,7 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo, int t_length; uint length,anc_length,buff_length,leaf_length,p_length,s_length,nod_flag; uint next_buff_length, new_buff_length, key_reflength, key_length; - uint unchanged_leaf_length, new_leaf_length; + uint unchanged_leaf_length, new_leaf_length, new_anc_length; my_off_t next_page; uchar anc_key[HA_MAX_KEY_BUFF],leaf_key[HA_MAX_KEY_BUFF]; uchar *buff,*endpos,*next_keypos,*anc_pos,*half_pos,*prev_key; @@ -778,7 +778,7 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo, memcpy(buff, leaf_buff,(size_t) leaf_length); (*keyinfo->store_key)(keyinfo, buff+leaf_length, &key_inserted); buff_length= (uint) (endpos-buff); - _ma_store_page_used(info, buff, buff_length, nod_flag); + _ma_store_page_used(info, buff, buff_length); /* remove key from anc_buff */ if (!(s_length=remove_key(keyinfo,key_reflength,keypos,anc_key, @@ -786,8 +786,8 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo, &key_deleted))) goto err; - anc_length-=s_length; - _ma_store_page_used(info, anc_buff, anc_length, key_reflength); + new_anc_length= anc_length - s_length; + _ma_store_page_used(info, anc_buff, new_anc_length); if (buff_length <= (uint) (keyinfo->block_length - KEYPAGE_CHECKSUM_SIZE)) { @@ -827,7 +827,7 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo, */ MARIA_KEY_PARAM anc_key_inserted; - anc_end_pos= anc_buff + anc_length; + anc_end_pos= anc_buff + new_anc_length; DBUG_PRINT("test",("anc_buff: 0x%lx anc_end_pos: 0x%lx", (long) anc_buff, (long) anc_end_pos)); if (!first_key && @@ -838,7 +838,7 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo, goto err; new_leaf_length= (uint) (half_pos-buff); memcpy(leaf_buff, buff, (size_t) new_leaf_length); - _ma_store_page_used(info, leaf_buff, new_leaf_length, nod_flag); + _ma_store_page_used(info, leaf_buff, new_leaf_length); /* Correct new keypointer to leaf_page */ half_pos=after_key; @@ -857,8 +857,8 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo, else bmove(keypos,keypos-t_length,(uint) (anc_end_pos-keypos)+t_length); (*keyinfo->store_key)(keyinfo,keypos, &anc_key_inserted); - anc_length+= t_length; - _ma_store_page_used(info, anc_buff, anc_length, key_reflength); + new_anc_length+= t_length; + _ma_store_page_used(info, anc_buff, new_anc_length); /* Store key first in new page */ if (nod_flag) @@ -874,7 +874,7 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo, bmove(buff+p_length+t_length, half_pos, (size_t) length); (*keyinfo->store_key)(keyinfo,buff+p_length, &key_inserted); new_buff_length= length + t_length + p_length; - _ma_store_page_used(info, buff, new_buff_length, nod_flag); + _ma_store_page_used(info, buff, new_buff_length); if (info->s->now_transactional) { @@ -889,7 +889,7 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo, if (_ma_log_add(info, anc_page, anc_buff, anc_length, keypos, anc_key_inserted.move_length + - min(anc_key_inserted.changed_length - + max(anc_key_inserted.changed_length - anc_key_inserted.move_length, key_deleted.changed_length), anc_key_inserted.move_length - @@ -940,8 +940,8 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo, PAGECACHE_LOCK_LEFT_WRITELOCKED, DFLT_INIT_HITS, leaf_buff)) goto err; - DBUG_RETURN(anc_length <= ((info->quick_mode ? MARIA_MIN_BLOCK_LENGTH : - (uint) keyinfo->underflow_block_length))); + DBUG_RETURN(new_anc_length <= ((info->quick_mode ? MARIA_MIN_BLOCK_LENGTH : + (uint) keyinfo->underflow_block_length))); } DBUG_PRINT("test",("use left page")); @@ -988,7 +988,7 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo, key_inserted.move_length); new_buff_length= buff_length + leaf_length - p_length + t_length; - _ma_store_page_used(info, buff, new_buff_length, nod_flag); + _ma_store_page_used(info, buff, new_buff_length); /* remove key from anc_buff */ if (!(s_length= remove_key(keyinfo,key_reflength,keypos,anc_key, @@ -996,8 +996,8 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo, &key_deleted))) goto err; - anc_length-=s_length; - _ma_store_page_used(info, anc_buff, anc_length, key_reflength); + new_anc_length= anc_length - s_length; + _ma_store_page_used(info, anc_buff, new_anc_length); if (new_buff_length <= (uint) (keyinfo->block_length - KEYPAGE_CHECKSUM_SIZE)) @@ -1049,9 +1049,9 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo, _ma_kpointer(info,leaf_key+key_length,leaf_page); /* Save key in anc_buff */ - DBUG_DUMP("anc_buff",anc_buff,anc_length); + DBUG_DUMP("anc_buff", anc_buff, new_anc_length); DBUG_DUMP("key_to_anc",leaf_key,key_length); - anc_end_pos= anc_buff + anc_length; + anc_end_pos= anc_buff + new_anc_length; t_length=(*keyinfo->pack_key)(keyinfo,key_reflength, keypos == anc_end_pos ? (uchar*) 0 : keypos, @@ -1063,8 +1063,8 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo, else bmove(keypos,keypos-t_length,(uint) (anc_end_pos-keypos)+t_length); (*keyinfo->store_key)(keyinfo,keypos, &anc_key_inserted); - anc_length+= t_length; - _ma_store_page_used(info, anc_buff, anc_length, key_reflength); + new_anc_length+= t_length; + _ma_store_page_used(info, anc_buff, new_anc_length); /* Store first key on new page */ if (nod_flag) @@ -1082,9 +1082,9 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo, bmove(leaf_buff+p_length+t_length, half_pos, (size_t) length); (*keyinfo->store_key)(keyinfo,leaf_buff+p_length, &key_inserted); new_leaf_length= length + t_length + p_length; - _ma_store_page_used(info, leaf_buff, new_leaf_length, nod_flag); + _ma_store_page_used(info, leaf_buff, new_leaf_length); new_buff_length= (uint) (endpos - buff); - _ma_store_page_used(info, buff, new_buff_length, nod_flag); + _ma_store_page_used(info, buff, new_buff_length); if (info->s->now_transactional) { @@ -1099,7 +1099,7 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo, if (_ma_log_add(info, anc_page, anc_buff, anc_length, keypos, anc_key_inserted.move_length + - min(anc_key_inserted.changed_length - + max(anc_key_inserted.changed_length - anc_key_inserted.move_length, key_deleted.changed_length), anc_key_inserted.move_length - @@ -1136,7 +1136,7 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo, if (_ma_write_keypage(info, keyinfo, next_page, PAGECACHE_LOCK_LEFT_WRITELOCKED, DFLT_INIT_HITS, buff)) goto err; - DBUG_RETURN(anc_length <= (uint) + DBUG_RETURN(new_anc_length <= (uint) (keyinfo->block_length - KEYPAGE_CHECKSUM_SIZE)/2); err: @@ -1262,6 +1262,7 @@ static uint remove_key(MARIA_KEYDEF *keyinfo, uint nod_flag, uint pack_length; uint diff= (next_length-prev_length); + /* keypos points to data of next key (after key length) */ bmove(keypos - diff, lastkey + prev_length, diff); rest_length+= diff; pack_length= prev_length ? get_pack_length(rest_length): 0; @@ -1323,14 +1324,15 @@ static my_bool _ma_log_delete(MARIA_HA *info, my_off_t page, uchar *buff, uint move_length) { LSN lsn; - uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 9], *log_pos; - LEX_STRING log_array[TRANSLOG_INTERNAL_PARTS + 2]; + uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 9 + 7], *log_pos; + LEX_STRING log_array[TRANSLOG_INTERNAL_PARTS + 3]; uint translog_parts; uint offset= (uint) (key_pos - buff); DBUG_ENTER("_ma_log_delete"); DBUG_PRINT("enter", ("page: %lu changed_length: %u move_length: %d", (ulong) page, changed_length, move_length)); DBUG_ASSERT(info->s->now_transactional && move_length); + DBUG_ASSERT(offset + changed_length <= _ma_get_page_used(info, buff)); /* Store address of new root page */ page/= info->s->block_size; @@ -1352,6 +1354,22 @@ static my_bool _ma_log_delete(MARIA_HA *info, my_off_t page, uchar *buff, log_array[TRANSLOG_INTERNAL_PARTS + 1].length= changed_length; } +#ifdef EXTRA_DEBUG_KEY_CHANGES + { + int page_length= _ma_get_page_used(info, buff); + ha_checksum crc; + crc= my_checksum(0, buff + LSN_STORE_SIZE, page_length - LSN_STORE_SIZE); + log_pos[0]= KEY_OP_CHECK; + int2store(log_pos+1, page_length); + int4store(log_pos+3, crc); + + log_array[TRANSLOG_INTERNAL_PARTS + translog_parts].str= log_pos; + log_array[TRANSLOG_INTERNAL_PARTS + translog_parts].length= 7; + changed_length+= 7; + translog_parts++; + } +#endif + log_array[TRANSLOG_INTERNAL_PARTS + 0].str= (char*) log_data; log_array[TRANSLOG_INTERNAL_PARTS + 0].length= (uint) (log_pos - log_data); diff --git a/storage/maria/ma_dynrec.c b/storage/maria/ma_dynrec.c index c631594671f..0b3e84b76d6 100644 --- a/storage/maria/ma_dynrec.c +++ b/storage/maria/ma_dynrec.c @@ -1801,7 +1801,7 @@ int _ma_read_rnd_dynamic_record(MARIA_HA *info, if (my_read(info->dfile.file, (uchar*)to, block_info.data_len, MYF(MY_NABP))) { - if (my_errno == -1) + if (my_errno == HA_ERR_FILE_TOO_SHORT) my_errno= HA_ERR_WRONG_IN_RECORD; /* Unexpected end of file */ goto err; } diff --git a/storage/maria/ma_ft_update.c b/storage/maria/ma_ft_update.c index b793ccd1295..841b83e01f3 100644 --- a/storage/maria/ma_ft_update.c +++ b/storage/maria/ma_ft_update.c @@ -330,7 +330,7 @@ uint _ma_ft_convert_to_ft2(MARIA_HA *info, uint keynr, uchar *key) /* creating pageful of keys */ bzero(info->buff, info->s->keypage_header); _ma_store_keynr(info, info->buff, keynr); - _ma_store_page_used(info, info->buff, length + info->s->keypage_header, 0); + _ma_store_page_used(info, info->buff, length + info->s->keypage_header); memcpy(info->buff + info->s->keypage_header, key_ptr, length); info->keyread_buff_used= info->page_changed=1; /* info->buff is used */ if ((root= _ma_new(info, DFLT_INIT_HITS, &page_link)) == HA_OFFSET_ERROR || diff --git a/storage/maria/ma_key_recover.c b/storage/maria/ma_key_recover.c index ed9c785439b..beca5077ee5 100644 --- a/storage/maria/ma_key_recover.c +++ b/storage/maria/ma_key_recover.c @@ -206,8 +206,8 @@ my_bool _ma_log_prefix(MARIA_HA *info, my_off_t page, { uint translog_parts; LSN lsn; - uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 7], *log_pos; - LEX_STRING log_array[TRANSLOG_INTERNAL_PARTS + 2]; + uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 7 + 7], *log_pos; + LEX_STRING log_array[TRANSLOG_INTERNAL_PARTS + 3]; DBUG_ENTER("_ma_log_prefix"); DBUG_PRINT("enter", ("page: %lu changed_length: %u move_length: %d", (ulong) page, changed_length, move_length)); @@ -223,7 +223,6 @@ my_bool _ma_log_prefix(MARIA_HA *info, my_off_t page, log_pos[0]= KEY_OP_DEL_PREFIX; int2store(log_pos+1, -move_length); log_pos+= 3; - translog_parts= 1; if (changed_length) { /* @@ -244,6 +243,8 @@ my_bool _ma_log_prefix(MARIA_HA *info, my_off_t page, int2store(log_pos+3, changed_length); log_pos+= 5; } + + translog_parts= 1; log_array[TRANSLOG_INTERNAL_PARTS + 0].str= log_data; log_array[TRANSLOG_INTERNAL_PARTS + 0].length= (uint) (log_pos - log_data); @@ -255,6 +256,22 @@ my_bool _ma_log_prefix(MARIA_HA *info, my_off_t page, translog_parts= 2; } +#ifdef EXTRA_DEBUG_KEY_CHANGES + { + int page_length= _ma_get_page_used(info, buff); + ha_checksum crc; + crc= my_checksum(0, buff + LSN_STORE_SIZE, page_length - LSN_STORE_SIZE); + log_pos[0]= KEY_OP_CHECK; + int2store(log_pos+1, page_length); + int4store(log_pos+3, crc); + + log_array[TRANSLOG_INTERNAL_PARTS + translog_parts].str= log_pos; + log_array[TRANSLOG_INTERNAL_PARTS + translog_parts].length= 7; + changed_length+= 7; + translog_parts++; + } +#endif + DBUG_RETURN(translog_write_record(&lsn, LOGREC_REDO_INDEX, info->trn, info, log_array[TRANSLOG_INTERNAL_PARTS + @@ -273,8 +290,8 @@ my_bool _ma_log_suffix(MARIA_HA *info, my_off_t page, uchar *buff, uint org_length, uint new_length) { LSN lsn; - LEX_STRING log_array[TRANSLOG_INTERNAL_PARTS + 2]; - uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 10], *log_pos; + LEX_STRING log_array[TRANSLOG_INTERNAL_PARTS + 3]; + uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 10 + 7], *log_pos; int diff; uint translog_parts, extra_length; DBUG_ENTER("_ma_log_suffix"); @@ -305,10 +322,26 @@ my_bool _ma_log_suffix(MARIA_HA *info, my_off_t page, translog_parts= 2; extra_length= (uint) diff; } + log_array[TRANSLOG_INTERNAL_PARTS + 0].str= log_data; log_array[TRANSLOG_INTERNAL_PARTS + 0].length= (uint) (log_pos - log_data); +#ifdef EXTRA_DEBUG_KEY_CHANGES + { + ha_checksum crc; + crc= my_checksum(0, buff + LSN_STORE_SIZE, new_length - LSN_STORE_SIZE); + log_pos[0]= KEY_OP_CHECK; + int2store(log_pos+1, new_length); + int4store(log_pos+3, crc); + + log_array[TRANSLOG_INTERNAL_PARTS + translog_parts].str= log_pos; + log_array[TRANSLOG_INTERNAL_PARTS + translog_parts].length= 7; + extra_length+= 7; + translog_parts++; + } +#endif + DBUG_RETURN(translog_write_record(&lsn, LOGREC_REDO_INDEX, info->trn, info, log_array[TRANSLOG_INTERNAL_PARTS + @@ -321,6 +354,9 @@ my_bool _ma_log_suffix(MARIA_HA *info, my_off_t page, /** @brief Log that a key was added to the page + @param buff Page buffer + @param buff_length Original length of buff (before key was added) + @note If handle_overflow is set, then we have to protect against logging changes that is outside of the page. @@ -334,12 +370,14 @@ my_bool _ma_log_add(MARIA_HA *info, my_off_t page, uchar *buff, my_bool handle_overflow __attribute__ ((unused))) { LSN lsn; - uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 3+ 3 + 3 + 3], *log_pos; - LEX_STRING log_array[TRANSLOG_INTERNAL_PARTS + 2]; + uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 3 + 3 + 3 + 3 + 7]; + uchar *log_pos; + LEX_STRING log_array[TRANSLOG_INTERNAL_PARTS + 3]; uint offset= (uint) (key_pos - buff); uint page_length= info->s->block_size - KEYPAGE_CHECKSUM_SIZE; + uint translog_parts; DBUG_ENTER("_ma_log_add"); - DBUG_PRINT("enter", ("page: %lu page_length: %u changed_length: %u " + DBUG_PRINT("enter", ("page: %lu org_page_length: %u changed_length: %u " "move_length: %d", (ulong) page, buff_length, changed_length, move_length)); @@ -394,6 +432,7 @@ my_bool _ma_log_add(MARIA_HA *info, my_off_t page, uchar *buff, } int2store(log_pos+1, changed_length); log_pos+= 3; + translog_parts= 2; log_array[TRANSLOG_INTERNAL_PARTS + 0].str= log_data; log_array[TRANSLOG_INTERNAL_PARTS + 0].length= (uint) (log_pos - @@ -401,12 +440,31 @@ my_bool _ma_log_add(MARIA_HA *info, my_off_t page, uchar *buff, log_array[TRANSLOG_INTERNAL_PARTS + 1].str= key_pos; log_array[TRANSLOG_INTERNAL_PARTS + 1].length= changed_length; +#ifdef EXTRA_DEBUG_KEY_CHANGES + { + ha_checksum crc; + uint save_page_length= _ma_get_page_used(info, buff); + uint new_length= buff_length + move_length; + _ma_store_page_used(info, buff, new_length); + crc= my_checksum(0, buff + LSN_STORE_SIZE, new_length - LSN_STORE_SIZE); + log_pos[0]= KEY_OP_CHECK; + int2store(log_pos+1, new_length); + int4store(log_pos+3, crc); + + log_array[TRANSLOG_INTERNAL_PARTS + translog_parts].str= log_pos; + log_array[TRANSLOG_INTERNAL_PARTS + translog_parts].length= 7; + changed_length+= 7; + translog_parts++; + _ma_store_page_used(info, buff, save_page_length); + } +#endif + if (translog_write_record(&lsn, LOGREC_REDO_INDEX, info->trn, info, log_array[TRANSLOG_INTERNAL_PARTS + 0].length + changed_length, - TRANSLOG_INTERNAL_PARTS + 2, log_array, - log_data, NULL)) + TRANSLOG_INTERNAL_PARTS + translog_parts, + log_array, log_data, NULL)) DBUG_RETURN(-1); DBUG_RETURN(0); } @@ -627,11 +685,15 @@ err: KEY_OP_ADD_SUFFIX 2 length, data Add data to end of page KEY_OP_DEL_SUFFIX 2 length Reduce page length with this Sets position to start of page + KEY_OP_CHECK 6 page_length[2},CRC Used only when debugging + @return Operation status @retval 0 OK @retval 1 Error */ +long my_counter= 0; + uint _ma_apply_redo_index(MARIA_HA *info, LSN lsn, const uchar *header, uint head_length) { @@ -674,12 +736,12 @@ uint _ma_apply_redo_index(MARIA_HA *info, do { switch ((enum en_key_op) (*header++)) { - case KEY_OP_OFFSET: + case KEY_OP_OFFSET: /* 1 */ page_offset= uint2korr(header); header+= 2; DBUG_ASSERT(page_offset >= keypage_header && page_offset <= page_length); break; - case KEY_OP_SHIFT: + case KEY_OP_SHIFT: /* 2 */ { int length= sint2korr(header); header+= 2; @@ -695,7 +757,7 @@ uint _ma_apply_redo_index(MARIA_HA *info, page_length+= length; break; } - case KEY_OP_CHANGE: + case KEY_OP_CHANGE: /* 3 */ { uint length= uint2korr(header); DBUG_ASSERT(page_offset != 0 && page_offset + length <= page_length); @@ -704,7 +766,7 @@ uint _ma_apply_redo_index(MARIA_HA *info, header+= 2 + length; break; } - case KEY_OP_ADD_PREFIX: + case KEY_OP_ADD_PREFIX: /* 4 */ { uint insert_length= uint2korr(header); uint changed_length= uint2korr(header+2); @@ -718,7 +780,7 @@ uint _ma_apply_redo_index(MARIA_HA *info, page_length+= insert_length; break; } - case KEY_OP_DEL_PREFIX: + case KEY_OP_DEL_PREFIX: /* 5 */ { uint length= uint2korr(header); header+= 2; @@ -731,7 +793,7 @@ uint _ma_apply_redo_index(MARIA_HA *info, page_offset= keypage_header; /* Prepare for change */ break; } - case KEY_OP_ADD_SUFFIX: + case KEY_OP_ADD_SUFFIX: /* 6 */ { uint insert_length= uint2korr(header); DBUG_ASSERT(page_length + insert_length <= share->block_size); @@ -741,7 +803,7 @@ uint _ma_apply_redo_index(MARIA_HA *info, header+= 2 + insert_length; break; } - case KEY_OP_DEL_SUFFIX: + case KEY_OP_DEL_SUFFIX: /* 7 */ { uint del_length= uint2korr(header); header+= 2; @@ -749,6 +811,21 @@ uint _ma_apply_redo_index(MARIA_HA *info, page_length-= del_length; break; } + case KEY_OP_CHECK: /* 8 */ +#ifdef EXTRA_DEBUG_KEY_CHANGES + { + uint check_page_length; + ha_checksum crc; + check_page_length= uint2korr(header); + crc= uint4korr(header+2); + _ma_store_page_used(info, buff, page_length); + DBUG_ASSERT(check_page_length == page_length); + DBUG_ASSERT(crc == (uint32) my_checksum(0, buff + LSN_STORE_SIZE, + page_length- LSN_STORE_SIZE)); +#endif + header+= 6; + break; + } case KEY_OP_NONE: default: DBUG_ASSERT(0); @@ -759,7 +836,7 @@ uint _ma_apply_redo_index(MARIA_HA *info, DBUG_ASSERT(header == header_end); /* Write modified page */ - _ma_store_page_used(info, buff, page_length, nod_flag); + _ma_store_page_used(info, buff, page_length); /* Clean old stuff up. Gives us better compression of we archive things @@ -768,15 +845,6 @@ uint _ma_apply_redo_index(MARIA_HA *info, if (page_length < org_page_length) bzero(buff + page_length, org_page_length-page_length); - result= 0; - if (pagecache_write(share->pagecache, - &info->s->kfile, page, 0, - buff, PAGECACHE_PLAIN_PAGE, - PAGECACHE_LOCK_LEFT_WRITELOCKED, - PAGECACHE_PIN_LEFT_PINNED, - PAGECACHE_WRITE_DELAY, 0, LSN_IMPOSSIBLE)) - result= 1; - /* Mark page to be unlocked and written at _ma_unpin_all_pages() */ page_link.unlock= PAGECACHE_LOCK_WRITE_UNLOCK; page_link.changed= 1; diff --git a/storage/maria/ma_locking.c b/storage/maria/ma_locking.c index 0b24fe9594c..aee9d729d53 100644 --- a/storage/maria/ma_locking.c +++ b/storage/maria/ma_locking.c @@ -389,8 +389,8 @@ int _ma_readinfo(register MARIA_HA *info __attribute__ ((unused)), /* should not be done for transactional tables */ if (_ma_state_info_read_dsk(share->kfile.file, &share->state)) { - int error=my_errno ? my_errno : -1; - my_errno=error; + if (!my_errno) + my_errno= HA_ERR_FILE_TOO_SHORT; DBUG_RETURN(1); } } diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c index 2b1d6e4a48d..2866e922e6e 100644 --- a/storage/maria/ma_loghandler.c +++ b/storage/maria/ma_loghandler.c @@ -548,7 +548,7 @@ static LOG_DESC INIT_LOGREC_REDO_DELETE_ALL= "redo_delete_all", LOGREC_IS_GROUP_ITSELF, NULL, NULL}; static LOG_DESC INIT_LOGREC_REDO_REPAIR_TABLE= -{LOGRECTYPE_FIXEDLENGTH, FILEID_STORE_SIZE + 4, FILEID_STORE_SIZE + 4, +{LOGRECTYPE_FIXEDLENGTH, FILEID_STORE_SIZE + 4 + 8, FILEID_STORE_SIZE + 4 + 8, NULL, NULL, NULL, 0, "redo_repair_table", LOGREC_IS_GROUP_ITSELF, NULL, NULL}; diff --git a/storage/maria/ma_loghandler.h b/storage/maria/ma_loghandler.h index 4aa98cb2f0a..f6652ea4494 100644 --- a/storage/maria/ma_loghandler.h +++ b/storage/maria/ma_loghandler.h @@ -155,6 +155,7 @@ enum en_key_op KEY_OP_DEL_PREFIX, /* Delete data at start of page */ KEY_OP_ADD_SUFFIX, /* Insert data at end of page */ KEY_OP_DEL_SUFFIX, /* Delete data at end of page */ + KEY_OP_CHECK /* For debugging; CRC of used part of page */ }; /* Size of log file; One log file is restricted to 4G */ diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c index 9fe2b5ec704..24293b79a1a 100644 --- a/storage/maria/ma_open.c +++ b/storage/maria/ma_open.c @@ -121,6 +121,10 @@ static MARIA_HA *maria_clone_internal(MARIA_SHARE *share, int mode, &info.first_mbr_key, share->base.max_key_length, &info.maria_rtree_recursion_state, share->have_rtree ? 1024 : 0, + &info.key_write_undo_lsn, + (uint) (sizeof(LSN) * share->base.keys), + &info.key_delete_undo_lsn, + (uint) (sizeof(LSN) * share->base.keys), &changed_fields_bitmap, bitmap_buffer_size(share->base.fields), NullS)) diff --git a/storage/maria/ma_pagecache.c b/storage/maria/ma_pagecache.c index dff9d504f3c..68827e9fbbc 100755 --- a/storage/maria/ma_pagecache.c +++ b/storage/maria/ma_pagecache.c @@ -44,7 +44,6 @@ #include "ma_pagecache.h" #include <my_bit.h> #include <errno.h> -#include <stdarg.h> /* Some compilation flags have been added specifically for this module @@ -95,7 +94,7 @@ #define PCBLOCK_INFO(B) \ DBUG_PRINT("info", \ - ("block: 0x%lx file: %lu page: %lu s: %0x hshL: 0x%lx req: %u/%u " \ + ("block: 0x%lx fd: %lu page: %lu s: %0x hshL: 0x%lx req: %u/%u " \ "wrlocks: %u pins: %u", \ (ulong)(B), \ (ulong)((B)->hash_link ? \ @@ -671,6 +670,8 @@ static inline uint next_power(uint value) division_limit division limit (may be zero) age_threshold age threshold (may be zero) block_size size of block (should be power of 2) + my_read_flags Flags used for all pread/pwrite calls + Usually MY_WME in case of recovery RETURN VALUE number of blocks in the key cache, if successful, @@ -688,7 +689,7 @@ static inline uint next_power(uint value) ulong init_pagecache(PAGECACHE *pagecache, size_t use_mem, uint division_limit, uint age_threshold, - uint block_size) + uint block_size, myf my_readwrite_flags) { ulong blocks, hash_links, length; int error; @@ -721,8 +722,8 @@ ulong init_pagecache(PAGECACHE *pagecache, size_t use_mem, pagecache->mem_size= use_mem; pagecache->block_size= block_size; pagecache->shift= my_bit_log2(block_size); - DBUG_PRINT("info", ("block_size: %u", - block_size)); + pagecache->readwrite_flags= my_readwrite_flags | MY_NABP | MY_WAIT_IF_FULL; + DBUG_PRINT("info", ("block_size: %u", block_size)); DBUG_ASSERT(((uint)(1 << pagecache->shift)) == block_size); blocks= (ulong) (use_mem / (sizeof(PAGECACHE_BLOCK_LINK) + @@ -733,102 +734,99 @@ ulong init_pagecache(PAGECACHE *pagecache, size_t use_mem, We need to support page cache with just one block to be able to do scanning of rows-in-block files */ - if (blocks >= 1) + for ( ; ; ) { - for ( ; ; ) + if (blocks < 8) { - if (blocks < 8) - { - my_errno= ENOMEM; - goto err; - } - /* Set my_hash_entries to the next bigger 2 power */ - if ((pagecache->hash_entries= next_power(blocks)) < - (blocks) * 5/4) - pagecache->hash_entries<<= 1; - hash_links= 2 * blocks; + my_errno= ENOMEM; + goto err; + } + /* Set my_hash_entries to the next bigger 2 power */ + if ((pagecache->hash_entries= next_power(blocks)) < + (blocks) * 5/4) + pagecache->hash_entries<<= 1; + hash_links= 2 * blocks; #if defined(MAX_THREADS) - if (hash_links < MAX_THREADS + blocks - 1) - hash_links= MAX_THREADS + blocks - 1; + if (hash_links < MAX_THREADS + blocks - 1) + hash_links= MAX_THREADS + blocks - 1; #endif - while ((length= (ALIGN_SIZE(blocks * sizeof(PAGECACHE_BLOCK_LINK)) + - ALIGN_SIZE(hash_links * sizeof(PAGECACHE_HASH_LINK)) + - ALIGN_SIZE(sizeof(PAGECACHE_HASH_LINK*) * - pagecache->hash_entries))) + - (blocks << pagecache->shift) > use_mem) - blocks--; - /* Allocate memory for cache page buffers */ - if ((pagecache->block_mem= - my_large_malloc((ulong) blocks * pagecache->block_size, - MYF(MY_WME)))) - { - /* - Allocate memory for blocks, hash_links and hash entries; - For each block 2 hash links are allocated - */ - if ((pagecache->block_root= - (PAGECACHE_BLOCK_LINK*) my_malloc((size_t) length, MYF(0)))) - break; - my_large_free(pagecache->block_mem, MYF(0)); - pagecache->block_mem= 0; - } - blocks= blocks / 4*3; + while ((length= (ALIGN_SIZE(blocks * sizeof(PAGECACHE_BLOCK_LINK)) + + ALIGN_SIZE(hash_links * sizeof(PAGECACHE_HASH_LINK)) + + ALIGN_SIZE(sizeof(PAGECACHE_HASH_LINK*) * + pagecache->hash_entries))) + + (blocks << pagecache->shift) > use_mem) + blocks--; + /* Allocate memory for cache page buffers */ + if ((pagecache->block_mem= + my_large_malloc((ulong) blocks * pagecache->block_size, + MYF(MY_WME)))) + { + /* + Allocate memory for blocks, hash_links and hash entries; + For each block 2 hash links are allocated + */ + if ((pagecache->block_root= + (PAGECACHE_BLOCK_LINK*) my_malloc((size_t) length, MYF(0)))) + break; + my_large_free(pagecache->block_mem, MYF(0)); + pagecache->block_mem= 0; } - pagecache->blocks_unused= blocks; - pagecache->disk_blocks= (long) blocks; - pagecache->hash_links= hash_links; - pagecache->hash_root= - (PAGECACHE_HASH_LINK**) ((char*) pagecache->block_root + - ALIGN_SIZE(blocks*sizeof(PAGECACHE_BLOCK_LINK))); - pagecache->hash_link_root= - (PAGECACHE_HASH_LINK*) ((char*) pagecache->hash_root + - ALIGN_SIZE((sizeof(PAGECACHE_HASH_LINK*) * - pagecache->hash_entries))); - bzero((uchar*) pagecache->block_root, - pagecache->disk_blocks * sizeof(PAGECACHE_BLOCK_LINK)); - bzero((uchar*) pagecache->hash_root, - pagecache->hash_entries * sizeof(PAGECACHE_HASH_LINK*)); - bzero((uchar*) pagecache->hash_link_root, - pagecache->hash_links * sizeof(PAGECACHE_HASH_LINK)); - pagecache->hash_links_used= 0; - pagecache->free_hash_list= NULL; - pagecache->blocks_used= pagecache->blocks_changed= 0; - - pagecache->global_blocks_changed= 0; - pagecache->blocks_available=0; /* For debugging */ - - /* The LRU chain is empty after initialization */ - pagecache->used_last= NULL; - pagecache->used_ins= NULL; - pagecache->free_block_list= NULL; - pagecache->time= 0; - pagecache->warm_blocks= 0; - pagecache->min_warm_blocks= (division_limit ? - blocks * division_limit / 100 + 1 : - blocks); - pagecache->age_threshold= (age_threshold ? - blocks * age_threshold / 100 : + blocks= blocks / 4*3; + } + pagecache->blocks_unused= blocks; + pagecache->disk_blocks= (long) blocks; + pagecache->hash_links= hash_links; + pagecache->hash_root= + (PAGECACHE_HASH_LINK**) ((char*) pagecache->block_root + + ALIGN_SIZE(blocks*sizeof(PAGECACHE_BLOCK_LINK))); + pagecache->hash_link_root= + (PAGECACHE_HASH_LINK*) ((char*) pagecache->hash_root + + ALIGN_SIZE((sizeof(PAGECACHE_HASH_LINK*) * + pagecache->hash_entries))); + bzero((uchar*) pagecache->block_root, + pagecache->disk_blocks * sizeof(PAGECACHE_BLOCK_LINK)); + bzero((uchar*) pagecache->hash_root, + pagecache->hash_entries * sizeof(PAGECACHE_HASH_LINK*)); + bzero((uchar*) pagecache->hash_link_root, + pagecache->hash_links * sizeof(PAGECACHE_HASH_LINK)); + pagecache->hash_links_used= 0; + pagecache->free_hash_list= NULL; + pagecache->blocks_used= pagecache->blocks_changed= 0; + + pagecache->global_blocks_changed= 0; + pagecache->blocks_available=0; /* For debugging */ + + /* The LRU chain is empty after initialization */ + pagecache->used_last= NULL; + pagecache->used_ins= NULL; + pagecache->free_block_list= NULL; + pagecache->time= 0; + pagecache->warm_blocks= 0; + pagecache->min_warm_blocks= (division_limit ? + blocks * division_limit / 100 + 1 : blocks); + pagecache->age_threshold= (age_threshold ? + blocks * age_threshold / 100 : + blocks); - pagecache->cnt_for_resize_op= 0; - pagecache->resize_in_flush= 0; - pagecache->can_be_used= 1; + pagecache->cnt_for_resize_op= 0; + pagecache->resize_in_flush= 0; + pagecache->can_be_used= 1; - pagecache->waiting_for_hash_link.last_thread= NULL; - pagecache->waiting_for_block.last_thread= NULL; - DBUG_PRINT("exit", - ("disk_blocks: %ld block_root: 0x%lx hash_entries: %ld\ + pagecache->waiting_for_hash_link.last_thread= NULL; + pagecache->waiting_for_block.last_thread= NULL; + DBUG_PRINT("exit", + ("disk_blocks: %ld block_root: 0x%lx hash_entries: %ld\ hash_root: 0x%lx hash_links: %ld hash_link_root: 0x%lx", - pagecache->disk_blocks, (long) pagecache->block_root, - pagecache->hash_entries, (long) pagecache->hash_root, - pagecache->hash_links, (long) pagecache->hash_link_root)); - bzero((uchar*) pagecache->changed_blocks, - sizeof(pagecache->changed_blocks[0]) * - PAGECACHE_CHANGED_BLOCKS_HASH); - bzero((uchar*) pagecache->file_blocks, - sizeof(pagecache->file_blocks[0]) * - PAGECACHE_CHANGED_BLOCKS_HASH); - } + pagecache->disk_blocks, (long) pagecache->block_root, + pagecache->hash_entries, (long) pagecache->hash_root, + pagecache->hash_links, (long) pagecache->hash_link_root)); + bzero((uchar*) pagecache->changed_blocks, + sizeof(pagecache->changed_blocks[0]) * + PAGECACHE_CHANGED_BLOCKS_HASH); + bzero((uchar*) pagecache->file_blocks, + sizeof(pagecache->file_blocks[0]) * + PAGECACHE_CHANGED_BLOCKS_HASH); pagecache->blocks= pagecache->disk_blocks > 0 ? pagecache->disk_blocks : 0; DBUG_RETURN((ulong) pagecache->disk_blocks); @@ -981,7 +979,8 @@ ulong resize_pagecache(PAGECACHE *pagecache, end_pagecache(pagecache, 0); /* Don't free mutex */ /* The following will work even if use_mem is 0 */ blocks= init_pagecache(pagecache, pagecache->block_size, use_mem, - division_limit, age_threshold); + division_limit, age_threshold, + pagecache->readwrite_flags); finish: #ifdef THREAD @@ -2020,7 +2019,7 @@ restart: block->buffer, block->hash_link->pageno, block->type, - MYF(MY_NABP | MY_WAIT_IF_FULL)); + pagecache->readwrite_flags); pagecache_pthread_mutex_lock(&pagecache->cache_lock); pagecache->global_cache_write++; } @@ -2417,13 +2416,13 @@ static void read_block(PAGECACHE *pagecache, pagecache_disk_read_validator validator, uchar* validator_data) { - uint got_length; /* On entry cache_lock is locked */ DBUG_ENTER("read_block"); if (primary) { + size_t error; /* This code is executed only by threads that submitted primary requests @@ -2438,11 +2437,12 @@ static void read_block(PAGECACHE *pagecache, Here other threads may step in and register as secondary readers. They will register in block->wqueue[COND_FOR_REQUESTED]. */ - got_length= pagecache_fread(pagecache, &block->hash_link->file, - block->buffer, - block->hash_link->pageno, MYF(0)); + error= pagecache_fread(pagecache, &block->hash_link->file, + block->buffer, + block->hash_link->pageno, + pagecache->readwrite_flags); pagecache_pthread_mutex_lock(&pagecache->cache_lock); - if (got_length < pagecache->block_size) + if (error) block->status|= PCBLOCK_ERROR; else block->status= PCBLOCK_READ; @@ -2796,7 +2796,6 @@ void pagecache_unlock_by_link(PAGECACHE *pagecache, block->status&= ~PCBLOCK_DIRECT_W; DBUG_PRINT("info", ("Drop PCBLOCK_DIRECT_W for block: 0x%lx", (ulong) block)); - } if (make_lock_and_pin(pagecache, block, lock, pin, 0)) @@ -2996,10 +2995,6 @@ restart: DBUG_PRINT("info", ("read is done")); } - /* PCBLOCK_DIRECT_W should be unlocked in unlock */ - DBUG_ASSERT((block->status & PCBLOCK_DIRECT_W) == 0 || - lock == PAGECACHE_LOCK_LEFT_WRITELOCKED); - if (make_lock_and_pin(pagecache, block, lock, pin, file)) { /* @@ -3069,7 +3064,8 @@ no_key_cache: /* Key cache is not used */ /* We can't use mutex here as the key cache may not be initialized */ pagecache->global_cache_r_requests++; pagecache->global_cache_read++; - if (pagecache_fread(pagecache, file, (uchar*) buff, pageno, MYF(MY_NABP))) + if (pagecache_fread(pagecache, file, (uchar*) buff, pageno, + pagecache->readwrite_flags)) error= 1; DBUG_RETURN(error ? (uchar*) 0 : buff); } @@ -3169,7 +3165,7 @@ restart: block->buffer, block->hash_link->pageno, block->type, - MYF(MY_NABP | MY_WAIT_IF_FULL)); + pagecache->readwrite_flags); pagecache_pthread_mutex_lock(&pagecache->cache_lock); pagecache->global_cache_write++; @@ -3494,7 +3490,7 @@ no_key_cache: pagecache->global_cache_w_requests++; pagecache->global_cache_write++; if (pagecache_fwrite(pagecache, file, (uchar*) buff, pageno, type, - MYF(MY_NABP | MY_WAIT_IF_FULL))) + pagecache->readwrite_flags)) error=1; } @@ -3662,7 +3658,7 @@ static int flush_cached_blocks(PAGECACHE *pagecache, block->buffer, block->hash_link->pageno, block->type, - MYF(MY_NABP | MY_WAIT_IF_FULL)); + pagecache->readwrite_flags); pagecache_pthread_mutex_lock(&pagecache->cache_lock); make_lock_and_pin(pagecache, block, @@ -3744,7 +3740,7 @@ static int flush_pagecache_blocks_int(PAGECACHE *pagecache, int rc= PCFLUSH_OK; DBUG_ENTER("flush_pagecache_blocks_int"); DBUG_PRINT("enter", - ("file: %d blocks_used: %lu blocks_changed: %lu type: %d", + ("fd: %d blocks_used: %lu blocks_changed: %lu type: %d", file->file, pagecache->blocks_used, pagecache->blocks_changed, type)); diff --git a/storage/maria/ma_pagecache.h b/storage/maria/ma_pagecache.h index 99b6fe9f6ae..9ed743f9cdd 100644 --- a/storage/maria/ma_pagecache.h +++ b/storage/maria/ma_pagecache.h @@ -158,7 +158,8 @@ typedef struct st_pagecache ulonglong global_cache_r_requests;/* number of read requests (read hits) */ ulonglong global_cache_read; /* number of reads from files to cache */ - uint shift; /* block size = 2 ^ shift */ + uint shift; /* block size = 2 ^ shift */ + myf readwrite_flags; /* Flags to pread/pwrite() */ my_bool inited; my_bool resize_in_flush; /* true during flush of resize operation */ my_bool can_be_used; /* usage of cache for read/write is allowed */ @@ -183,7 +184,7 @@ extern PAGECACHE dflt_pagecache_var, *dflt_pagecache; extern ulong init_pagecache(PAGECACHE *pagecache, size_t use_mem, uint division_limit, uint age_threshold, - uint block_size); + uint block_size, myf my_read_flags); extern ulong resize_pagecache(PAGECACHE *pagecache, size_t use_mem, uint division_limit, uint age_threshold); diff --git a/storage/maria/ma_recovery.c b/storage/maria/ma_recovery.c index c6481412232..e47d686a09c 100644 --- a/storage/maria/ma_recovery.c +++ b/storage/maria/ma_recovery.c @@ -58,6 +58,7 @@ static FILE *tracef; /**< trace file for debugging */ static my_bool skip_DDLs; /**< if REDO phase should skip DDL records */ /** @brief to avoid writing a checkpoint if recovery did nothing. */ static my_bool checkpoint_useful; +static my_bool procent_printed; static ulonglong now; /**< for tracking execution time of phases */ uint warnings; /**< count of warnings */ @@ -156,10 +157,36 @@ void tprint(FILE *trace_file __attribute__ ((unused)), va_list args; va_start(args, format); if (trace_file != NULL) + { + if (procent_printed) + { + procent_printed= 0; + fputc('\n', trace_file ? trace_file : stderr); + } vfprintf(trace_file, format, args); + } va_end(args); } +void eprint(FILE *trace_file, const char *format, ...) + ATTRIBUTE_FORMAT(printf, 2, 3); + +void eprint(FILE *trace_file __attribute__ ((unused)), + const char *format __attribute__ ((unused)), ...) +{ + va_list args; + va_start(args, format); + if (procent_printed) + { + /* In silent mode, print on another line than the 0% 10% 20% line */ + procent_printed= 0; + fputc('\n', trace_file ? trace_file : stderr); + } + vfprintf(trace_file ? trace_file : stderr, format, args); + va_end(args); +} + + #define ALERT_USER() DBUG_ASSERT(0) static void print_preamble() @@ -312,6 +339,7 @@ int maria_apply_log(LSN from_lsn, enum maria_apply_log_way apply, Detailed progress info goes to stderr, because ma_message_no_user() cannot put several messages on one line. */ + procent_printed= 1; fprintf(stderr, " (%.1f seconds); ", phase_took); } @@ -353,6 +381,7 @@ int maria_apply_log(LSN from_lsn, enum maria_apply_log_way apply, if (recovery_message_printed == REC_MSG_UNDO) { float phase_took= (now - old_now)/10000000.0; + procent_printed= 1; fprintf(stderr, " (%.1f seconds); ", phase_took); } @@ -368,6 +397,7 @@ int maria_apply_log(LSN from_lsn, enum maria_apply_log_way apply, if (recovery_message_printed == REC_MSG_FLUSH) { float phase_took= (now - old_now)/10000000.0; + procent_printed= 1; fprintf(stderr, " (%.1f seconds); ", phase_took); } @@ -381,7 +411,7 @@ int maria_apply_log(LSN from_lsn, enum maria_apply_log_way apply, goto end; err: error= 1; - tprint(tracef, "Recovery of tables with transaction logs FAILED\n"); + tprint(tracef, "\nRecovery of tables with transaction logs FAILED\n"); end: hash_free(&all_dirty_pages); bzero(&all_dirty_pages, sizeof(all_dirty_pages)); @@ -404,6 +434,7 @@ end: else ma_message_no_user(ME_JUST_INFO, "recovery done"); } + procent_printed= 0; /* we don't cleanly close tables if we hit some error (may corrupt them) */ DBUG_RETURN(error); } @@ -418,7 +449,8 @@ static void display_record_position(const LOG_DESC *log_desc, if number==0, we're going over records which we had already seen and which form a group, so we indent below the group's end record */ - tprint(tracef, "%sRec#%u LSN (%lu,0x%lx) short_trid %u %s(num_type:%u) len %lu\n", + tprint(tracef, + "%sRec#%u LSN (%lu,0x%lx) short_trid %u %s(num_type:%u) len %lu\n", number ? "" : " ", number, LSN_IN_PARTS(rec->lsn), rec->short_trid, log_desc->name, rec->type, (ulong)rec->record_length); @@ -436,7 +468,7 @@ static int display_and_apply_record(const LOG_DESC *log_desc, return 1; } if ((error= (*log_desc->record_execute_in_redo_phase)(rec))) - tprint(tracef, "Got error when executing record\n"); + eprint(tracef, "Got error %d when executing record\n", my_errno); return error; } @@ -467,10 +499,10 @@ prototype_redo_exec_hook(LONG_TRANSACTION_ID) { char llbuf[22]; llstr(long_trid, llbuf); - tprint(tracef, "Found an old transaction long_trid %s short_trid %u" + eprint(tracef, "Found an old transaction long_trid %s short_trid %u" " with same short id as this new transaction, and has neither" - " committed nor rollback (undo_lsn: (%lu,0x%lx))\n", llbuf, - sid, LSN_IN_PARTS(ulsn)); + " committed nor rollback (undo_lsn: (%lu,0x%lx))\n", + llbuf, sid, LSN_IN_PARTS(ulsn)); goto err; } } @@ -570,11 +602,10 @@ prototype_redo_exec_hook(REDO_CREATE_TABLE) log_record_buffer.str, NULL) != rec->record_length) { - tprint(tracef, "Failed to read record\n"); + eprint(tracef, "Failed to read record\n"); goto end; } name= log_record_buffer.str; - tprint(tracef, "Table '%s'", name); /* TRUNCATE TABLE and REPAIR USE_FRM call maria_create(), so below we can find a REDO_CREATE_TABLE for a table which we have open, that's why we @@ -582,7 +613,7 @@ prototype_redo_exec_hook(REDO_CREATE_TABLE) */ if (close_one_table(name, rec->lsn)) { - tprint(tracef, " got error %d on close\n", my_errno); + eprint(tracef, "Table '%s' got error %d on close\n", name, my_errno); ALERT_USER(); goto end; } @@ -594,7 +625,8 @@ prototype_redo_exec_hook(REDO_CREATE_TABLE) /* check that we're not already using it */ if (share->reopen != 1) { - tprint(tracef, ", is already open (reopen=%u)\n", share->reopen); + eprint(tracef, "Table '%s is already open (reopen=%u)\n", + name, share->reopen); ALERT_USER(); goto end; } @@ -606,22 +638,23 @@ prototype_redo_exec_hook(REDO_CREATE_TABLE) one was renamed to its name, thus create_rename_lsn is 0 and should not be trusted. */ - tprint(tracef, ", is not transactional, ignoring creation\n"); + tprint(tracef, "Table '%s' is not transactional, ignoring creation\n", + name); ALERT_USER(); error= 0; goto end; } if (cmp_translog_addr(share->state.create_rename_lsn, rec->lsn) >= 0) { - tprint(tracef, ", has create_rename_lsn (%lu,0x%lx) more recent than" - " record, ignoring creation", - LSN_IN_PARTS(share->state.create_rename_lsn)); + tprint(tracef, "Table '%s' has create_rename_lsn (%lu,0x%lx) more " + "recent than record, ignoring creation", + name, LSN_IN_PARTS(share->state.create_rename_lsn)); error= 0; goto end; } if (maria_is_crashed(info)) { - tprint(tracef, ", is crashed, can't recreate it"); + eprint(tracef, "Table '%s' is crashed, can't recreate it\n", name); ALERT_USER(); goto end; } @@ -629,7 +662,8 @@ prototype_redo_exec_hook(REDO_CREATE_TABLE) info= NULL; } else /* one or two files absent, or header corrupted... */ - tprint(tracef, " can't be opened, probably does not exist"); + tprint(tracef, "Table '%s' can't be opened, probably does not exist\n", + name); /* if does not exist, or is older, overwrite it */ ptr= name + strlen(name) + 1; if ((flags= ptr[0] ? HA_DONT_TOUCH_DATA : 0)) @@ -653,7 +687,8 @@ prototype_redo_exec_hook(REDO_CREATE_TABLE) /** @todo handle symlinks */ if (data_file_name[0] || index_file_name[0]) { - tprint(tracef, ", DATA|INDEX DIRECTORY clauses are not handled\n"); + eprint(tracef, "Table '%s' DATA|INDEX DIRECTORY clauses are not handled\n", + name); goto end; } fn_format(filename, name, "", MARIA_NAME_IEXT, @@ -662,18 +697,18 @@ prototype_redo_exec_hook(REDO_CREATE_TABLE) MY_APPEND_EXT); linkname_ptr= NULL; create_flag= MY_DELETE_OLD; - tprint(tracef, ", creating as '%s'", filename); + tprint(tracef, "Table '%s' creating as '%s'", name, filename); if ((kfile= my_create_with_symlink(linkname_ptr, filename, 0, create_mode, MYF(MY_WME|create_flag))) < 0) { - tprint(tracef, " Failed to create index file\n"); + eprint(tracef, "Failed to create index file\n"); goto end; } if (my_pwrite(kfile, kfile_header, kfile_size_before_extension, 0, MYF(MY_NABP|MY_WME)) || my_chsize(kfile, keystart, 0, MYF(MY_WME))) { - tprint(tracef, " Failed to write to index file\n"); + eprint(tracef, "Failed to write to index file\n"); goto end; } if (!(flags & HA_DONT_TOUCH_DATA)) @@ -687,7 +722,7 @@ prototype_redo_exec_hook(REDO_CREATE_TABLE) MYF(MY_WME | create_flag))) < 0) || my_close(dfile, MYF(MY_WME))) { - tprint(tracef, " Failed to create data file\n"); + eprint(tracef, "Failed to create data file\n"); goto end; } /* @@ -699,7 +734,7 @@ prototype_redo_exec_hook(REDO_CREATE_TABLE) if (((info= maria_open(name, O_RDONLY, 0)) == NULL) || _ma_initialize_data_file(info->s, info->dfile.file)) { - tprint(tracef, " Failed to open new table or write to data file\n"); + eprint(tracef, "Failed to open new table or write to data file\n"); goto end; } } @@ -730,7 +765,7 @@ prototype_redo_exec_hook(REDO_RENAME_TABLE) log_record_buffer.str, NULL) != rec->record_length) { - tprint(tracef, "Failed to read record\n"); + eprint(tracef, "Failed to read record\n"); goto end; } old_name= log_record_buffer.str; @@ -867,13 +902,13 @@ prototype_redo_exec_hook(REDO_RENAME_TABLE) tprint(tracef, ", renaming '%s'", old_name); if (maria_rename(old_name, new_name)) { - tprint(tracef, "Failed to rename table\n"); + eprint(tracef, "Failed to rename table\n"); goto end; } info= maria_open(new_name, O_RDONLY, 0); if (info == NULL) { - tprint(tracef, "Failed to open renamed table\n"); + eprint(tracef, "Failed to open renamed table\n"); goto end; } if (_ma_update_create_rename_lsn(info->s, rec->lsn, TRUE)) @@ -887,7 +922,7 @@ drop: tprint(tracef, ", only dropping '%s'", old_name); if (maria_delete_table(old_name)) { - tprint(tracef, "Failed to drop table\n"); + eprint(tracef, "Failed to drop table\n"); goto end; } error= 0; @@ -907,6 +942,11 @@ prototype_redo_exec_hook(REDO_REPAIR_TABLE) { int error= 1; MARIA_HA *info; + HA_CHECK param; + char *name; + uint quick_repair; + DBUG_ENTER("exec_REDO_LOGREC_REDO_REPAIR_TABLE"); + if (skip_DDLs) { /* @@ -914,26 +954,46 @@ prototype_redo_exec_hook(REDO_REPAIR_TABLE) insertions into them. */ tprint(tracef, "we skip DDLs\n"); - return 0; + DBUG_RETURN(0); } if ((info= get_MARIA_HA_from_REDO_record(rec)) == NULL) - return 0; + DBUG_RETURN(0); + /* Otherwise, the mapping is newer than the table, and our record is newer than the mapping, so we can repair. */ tprint(tracef, " repairing...\n"); - HA_CHECK param; + maria_chk_init(¶m); - param.isam_file_name= info->s->open_file_name; - param.testflag= uint4korr(rec->header); - if (maria_repair(¶m, info, info->s->open_file_name, param.testflag)) + param.isam_file_name= name= info->s->open_file_name; + param.testflag= uint4korr(rec->header + FILEID_STORE_SIZE); + param.tmpdir= maria_tmpdir; + DBUG_ASSERT(maria_tmpdir); + + info->s->state.key_map= uint8korr(rec->header + FILEID_STORE_SIZE + 4); + quick_repair= param.testflag & T_QUICK; + + + if (param.testflag & T_REP_PARALLEL) + { + if (maria_repair_parallel(¶m, info, name, quick_repair)) + goto end; + } + else if (param.testflag & T_REP_BY_SORT) + { + if (maria_repair_by_sort(¶m, info, name, quick_repair)) + goto end; + } + else if (maria_repair(¶m, info, name, quick_repair)) goto end; + if (_ma_update_create_rename_lsn(info->s, rec->lsn, TRUE)) goto end; error= 0; + end: - return error; + DBUG_RETURN(error); } @@ -953,7 +1013,7 @@ prototype_redo_exec_hook(REDO_DROP_TABLE) log_record_buffer.str, NULL) != rec->record_length) { - tprint(tracef, "Failed to read record\n"); + eprint(tracef, "Failed to read record\n"); return 1; } name= log_record_buffer.str; @@ -991,7 +1051,7 @@ prototype_redo_exec_hook(REDO_DROP_TABLE) tprint(tracef, ", dropping '%s'", name); if (maria_delete_table(name)) { - tprint(tracef, "Failed to drop table\n"); + eprint(tracef, "Failed to drop table\n"); goto end; } } @@ -1012,6 +1072,7 @@ prototype_redo_exec_hook(FILE_ID) int error= 1; const char *name; MARIA_HA *info; + DBUG_ENTER("exec_REDO_LOGREC_FILE_ID"); if (cmp_translog_addr(rec->lsn, checkpoint_start) < 0) { @@ -1022,7 +1083,7 @@ prototype_redo_exec_hook(FILE_ID) happened and so mapping is not needed. */ tprint(tracef, "ignoring because before checkpoint\n"); - return 0; + DBUG_RETURN(0); } enlarge_buffer(rec); @@ -1031,7 +1092,7 @@ prototype_redo_exec_hook(FILE_ID) log_record_buffer.str, NULL) != rec->record_length) { - tprint(tracef, "Failed to read record\n"); + eprint(tracef, "Failed to read record\n"); goto end; } sid= fileid_korr(log_record_buffer.str); @@ -1042,7 +1103,7 @@ prototype_redo_exec_hook(FILE_ID) prepare_table_for_close(info, rec->lsn); if (maria_close(info)) { - tprint(tracef, "Failed to close table\n"); + eprint(tracef, "Failed to close table\n"); goto end; } all_tables[sid].info= NULL; @@ -1052,7 +1113,7 @@ prototype_redo_exec_hook(FILE_ID) goto end; error= 0; end: - return error; + DBUG_RETURN(error); } @@ -1213,14 +1274,14 @@ prototype_redo_exec_hook(REDO_INSERT_ROW_HEAD) enlarge_buffer(rec); if (log_record_buffer.str == NULL) { - tprint(tracef, "Failed to read allocate buffer for record\n"); + eprint(tracef, "Failed to read allocate buffer for record\n"); goto end; } if (translog_read_record(rec->lsn, 0, rec->record_length, log_record_buffer.str, NULL) != rec->record_length) { - tprint(tracef, "Failed to read record\n"); + eprint(tracef, "Failed to read record\n"); goto end; } buff= log_record_buffer.str; @@ -1255,7 +1316,7 @@ prototype_redo_exec_hook(REDO_INSERT_ROW_TAIL) log_record_buffer.str, NULL) != rec->record_length) { - tprint(tracef, "Failed to read record\n"); + eprint(tracef, "Failed to read record\n"); goto end; } buff= log_record_buffer.str; @@ -1291,7 +1352,7 @@ prototype_redo_exec_hook(REDO_INSERT_ROW_BLOBS) log_record_buffer.str, NULL) != rec->record_length) { - tprint(tracef, "Failed to read record\n"); + eprint(tracef, "Failed to read record\n"); goto end; } buff= log_record_buffer.str; @@ -1351,7 +1412,7 @@ prototype_redo_exec_hook(REDO_FREE_BLOCKS) log_record_buffer.str, NULL) != rec->record_length) { - tprint(tracef, "Failed to read record\n"); + eprint(tracef, "Failed to read record\n"); goto end; } @@ -1410,7 +1471,7 @@ prototype_redo_exec_hook(REDO_INDEX) log_record_buffer.str, NULL) != rec->record_length) { - tprint(tracef, "Failed to read record\n"); + eprint(tracef, "Failed to read record\n"); goto end; } @@ -1436,7 +1497,7 @@ prototype_redo_exec_hook(REDO_INDEX_NEW_PAGE) log_record_buffer.str, NULL) != rec->record_length) { - tprint(tracef, "Failed to read record\n"); + eprint(tracef, "Failed to read record\n"); goto end; } @@ -1493,7 +1554,7 @@ prototype_redo_exec_hook(UNDO_ROW_INSERT) HA_CHECKSUM_STORE_SIZE, buff, NULL) != HA_CHECKSUM_STORE_SIZE) { - tprint(tracef, "Failed to read record\n"); + eprint(tracef, "Failed to read record\n"); return 1; } share->state.state.checksum+= ha_checksum_korr(buff); @@ -1532,7 +1593,7 @@ prototype_redo_exec_hook(UNDO_ROW_DELETE) HA_CHECKSUM_STORE_SIZE, buff, NULL) != HA_CHECKSUM_STORE_SIZE) { - tprint(tracef, "Failed to read record\n"); + eprint(tracef, "Failed to read record\n"); return 1; } share->state.state.checksum+= ha_checksum_korr(buff); @@ -1564,7 +1625,7 @@ prototype_redo_exec_hook(UNDO_ROW_UPDATE) HA_CHECKSUM_STORE_SIZE, buff, NULL) != HA_CHECKSUM_STORE_SIZE) { - tprint(tracef, "Failed to read record\n"); + eprint(tracef, "Failed to read record\n"); return 1; } share->state.state.checksum+= ha_checksum_korr(buff); @@ -1712,7 +1773,7 @@ prototype_redo_exec_hook(CLR_END) buff, NULL) != KEY_NR_STORE_SIZE + PAGE_STORE_SIZE) { - tprint(tracef, "Failed to read record\n"); + eprint(tracef, "Failed to read record\n"); DBUG_RETURN(1); } key_nr= key_nr_korr(buff); @@ -1732,7 +1793,7 @@ prototype_redo_exec_hook(CLR_END) CLR_TYPE_STORE_SIZE, HA_CHECKSUM_STORE_SIZE, buff, NULL) != HA_CHECKSUM_STORE_SIZE) { - tprint(tracef, "Failed to read record\n"); + eprint(tracef, "Failed to read record\n"); DBUG_RETURN(1); } share->state.state.checksum+= ha_checksum_korr(buff); @@ -1781,7 +1842,7 @@ prototype_undo_exec_hook(UNDO_ROW_INSERT) log_record_buffer.str, NULL) != rec->record_length) { - tprint(tracef, "Failed to read record\n"); + eprint(tracef, "Failed to read record\n"); return 1; } record_ptr= log_record_buffer.str; @@ -1818,7 +1879,7 @@ prototype_undo_exec_hook(UNDO_ROW_DELETE) log_record_buffer.str, NULL) != rec->record_length) { - tprint(tracef, "Failed to read record\n"); + eprint(tracef, "Failed to read record\n"); return 1; } @@ -1860,7 +1921,7 @@ prototype_undo_exec_hook(UNDO_ROW_UPDATE) log_record_buffer.str, NULL) != rec->record_length) { - tprint(tracef, "Failed to read record\n"); + eprint(tracef, "Failed to read record\n"); return 1; } @@ -1904,7 +1965,7 @@ prototype_undo_exec_hook(UNDO_KEY_INSERT) log_record_buffer.str, NULL) != rec->record_length) { - tprint(tracef, "Failed to read record\n"); + eprint(tracef, "Failed to read record\n"); return 1; } @@ -1949,7 +2010,7 @@ prototype_undo_exec_hook(UNDO_KEY_DELETE) log_record_buffer.str, NULL) != rec->record_length) { - tprint(tracef, "Failed to read record\n"); + eprint(tracef, "Failed to read record\n"); return 1; } @@ -1994,7 +2055,7 @@ prototype_undo_exec_hook(UNDO_KEY_DELETE_WITH_ROOT) log_record_buffer.str, NULL) != rec->record_length) { - tprint(tracef, "Failed to read record\n"); + eprint(tracef, "Failed to read record\n"); return 1; } @@ -2077,7 +2138,7 @@ static int run_redo_phase(LSN lsn, enum maria_apply_log_way apply) if (len == RECHEADER_READ_ERROR) { - tprint(tracef, "Failed to read header of the first record.\n"); + eprint(tracef, "Failed to read header of the first record.\n"); return 1; } if (translog_init_scanner(lsn, 1, &scanner, 1)) @@ -2211,7 +2272,10 @@ static int run_redo_phase(LSN lsn, enum maria_apply_log_way apply) translog_destroy_scanner(&scanner); translog_free_record_header(&rec); if (recovery_message_printed == REC_MSG_REDO) + { fprintf(stderr, " 100%%"); + procent_printed= 1; + } return 0; err: @@ -2343,7 +2407,7 @@ static int run_undo_phase(uint unfinished) display_record_position(log_desc, &rec, 0); if (log_desc->record_execute_in_undo_phase(&rec, trn)) { - tprint(tracef, "Got error when executing undo\n"); + tprint(tracef, "Got error %d when executing undo\n", my_errno); return 1; } } @@ -2542,7 +2606,7 @@ static LSN parse_checkpoint_record(LSN lsn) log_record_buffer.str, NULL) != rec.record_length) { - tprint(tracef, "Failed to read record\n"); + eprint(tracef, "Failed to read record\n"); return LSN_ERROR; } @@ -2793,6 +2857,7 @@ static void print_redo_phase_progress(TRANSLOG_ADDRESS addr) static ulonglong initial_remainder= -1; int cur_logno, cur_offset; ulonglong local_remainder; + int percentage_done; if (tracef == stdout) return; @@ -2800,6 +2865,7 @@ static void print_redo_phase_progress(TRANSLOG_ADDRESS addr) { print_preamble(); fprintf(stderr, "recovered pages: 0%%"); + procent_printed= 1; recovery_message_printed= REC_MSG_REDO; } if (end_logno == FILENO_IMPOSSIBLE) @@ -2815,12 +2881,13 @@ static void print_redo_phase_progress(TRANSLOG_ADDRESS addr) max(end_logno - cur_logno - 1, 0) * TRANSLOG_FILE_SIZE + end_offset); if (initial_remainder == (ulonglong)(-1)) initial_remainder= local_remainder; - int percentage_done= - (initial_remainder - local_remainder) * ULL(100) / initial_remainder; + percentage_done= ((initial_remainder - local_remainder) * ULL(100) / + initial_remainder); if ((percentage_done - percentage_printed) >= 10) { percentage_printed= percentage_done; fprintf(stderr, " %d%%", percentage_done); + procent_printed= 1; } } diff --git a/storage/maria/ma_rt_index.c b/storage/maria/ma_rt_index.c index eba2a519a3f..50d4e9e0fd2 100644 --- a/storage/maria/ma_rt_index.c +++ b/storage/maria/ma_rt_index.c @@ -662,7 +662,7 @@ static int maria_rtree_insert_level(MARIA_HA *info, uint keynr, uchar *key, info->keyread_buff_used= 1; bzero(info->buff, info->s->keypage_header); _ma_store_keynr(info, info->buff, keynr); - _ma_store_page_used(info, info->buff, info->s->keypage_header, 0); + _ma_store_page_used(info, info->buff, info->s->keypage_header); res= maria_rtree_add_key(info, keyinfo, key, key_length, info->buff, NULL); @@ -698,9 +698,10 @@ static int maria_rtree_insert_level(MARIA_HA *info, uint keynr, uchar *key, } bzero(new_root_buf, info->s->keypage_header); + if (nod_flag) + _ma_store_keypage_flag(info, new_root_buf, KEYPAGE_FLAG_ISNOD); _ma_store_keynr(info, new_root_buf, keynr); - _ma_store_page_used(info, new_root_buf, info->s->keypage_header, - nod_flag); + _ma_store_page_used(info, new_root_buf, info->s->keypage_header); if ((new_root= _ma_new(info, DFLT_INIT_HITS, &page_link)) == HA_OFFSET_ERROR) goto err1; diff --git a/storage/maria/ma_rt_key.c b/storage/maria/ma_rt_key.c index 311137850f6..a976c252a93 100644 --- a/storage/maria/ma_rt_key.c +++ b/storage/maria/ma_rt_key.c @@ -59,7 +59,7 @@ int maria_rtree_add_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key, info->s->base.rec_reflength); page_size+= key_length + info->s->base.rec_reflength; } - _ma_store_page_used(info, page_buf, page_size, nod_flag); + _ma_store_page_used(info, page_buf, page_size); DBUG_RETURN(0); } @@ -86,7 +86,7 @@ int maria_rtree_delete_key(MARIA_HA *info, uchar *page_buf, uchar *key, (key - page_buf)); page_size-= key_length + nod_flag; - _ma_store_page_used(info, page_buf, page_size, nod_flag); + _ma_store_page_used(info, page_buf, page_size); return 0; } diff --git a/storage/maria/ma_rt_split.c b/storage/maria/ma_rt_split.c index 25cfb0be91a..b9583241366 100644 --- a/storage/maria/ma_rt_split.c +++ b/storage/maria/ma_rt_split.c @@ -340,11 +340,12 @@ int maria_rtree_split_page(MARIA_HA *info, MARIA_KEYDEF *keyinfo, } bzero(new_page, info->s->keypage_header); + if (nod_flag) + _ma_store_keypage_flag(info, new_page, KEYPAGE_FLAG_ISNOD); _ma_store_keynr(info, new_page, keyinfo->key_nr); - _ma_store_page_used(info, page, info->s->keypage_header + n1 * full_length, - nod_flag); + _ma_store_page_used(info, page, info->s->keypage_header + n1 * full_length) _ma_store_page_used(info, new_page, info->s->keypage_header + - n2 * full_length, nod_flag); + n2 * full_length); if ((*new_page_offs= _ma_new(info, DFLT_INIT_HITS, &page_link)) == HA_OFFSET_ERROR) diff --git a/storage/maria/ma_static.c b/storage/maria/ma_static.c index fe1335c39fe..20c5c999a8f 100644 --- a/storage/maria/ma_static.c +++ b/storage/maria/ma_static.c @@ -48,6 +48,7 @@ PAGECACHE *maria_pagecache= &maria_pagecache_var; PAGECACHE maria_log_pagecache_var; PAGECACHE *maria_log_pagecache= &maria_log_pagecache_var; +MY_TMPDIR *maria_tmpdir; /* Tempdir for redo */ /** @brief when transactionality does not matter we can use this transaction diff --git a/storage/maria/ma_test1.c b/storage/maria/ma_test1.c index d46072e626a..5c362723fa8 100644 --- a/storage/maria/ma_test1.c +++ b/storage/maria/ma_test1.c @@ -76,11 +76,11 @@ int main(int argc,char *argv[]) /* Maria requires that we always have a page cache */ if (maria_init() || (init_pagecache(maria_pagecache, maria_block_size * 16, 0, 0, - maria_block_size) == 0) || + maria_block_size, MY_WME) == 0) || ma_control_file_create_or_open() || (init_pagecache(maria_log_pagecache, TRANSLOG_PAGECACHE_SIZE, 0, 0, - TRANSLOG_PAGE_SIZE) == 0) || + TRANSLOG_PAGE_SIZE, MY_WME) == 0) || translog_init(maria_data_root, TRANSLOG_FILE_SIZE, 0, 0, maria_log_pagecache, TRANSLOG_DEFAULT_FLAGS) || @@ -840,7 +840,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), printf("test1 Ver 1.2 \n"); exit(0); case '#': - DBUG_PUSH (argument); + DBUG_PUSH(argument); break; case '?': usage(); diff --git a/storage/maria/ma_test2.c b/storage/maria/ma_test2.c index 762d2d7ebb0..60c6a3be8b4 100644 --- a/storage/maria/ma_test2.c +++ b/storage/maria/ma_test2.c @@ -89,11 +89,11 @@ int main(int argc, char *argv[]) /* Maria requires that we always have a page cache */ if (maria_init() || (init_pagecache(maria_pagecache, pagecache_size, 0, 0, - maria_block_size) == 0) || + maria_block_size, MY_WME) == 0) || ma_control_file_create_or_open() || (init_pagecache(maria_log_pagecache, TRANSLOG_PAGECACHE_SIZE, 0, 0, - TRANSLOG_PAGE_SIZE) == 0) || + TRANSLOG_PAGE_SIZE, MY_WME) == 0) || translog_init(maria_data_root, TRANSLOG_FILE_SIZE, 0, 0, maria_log_pagecache, TRANSLOG_DEFAULT_FLAGS) || diff --git a/storage/maria/ma_test3.c b/storage/maria/ma_test3.c index 6d45e391e65..de8b4c83a51 100644 --- a/storage/maria/ma_test3.c +++ b/storage/maria/ma_test3.c @@ -178,7 +178,8 @@ void start_test(int id) exit(1); } if (pagecacheing && rnd(2) == 0) - init_pagecache(maria_pagecache, 65536L, 0, 0, MARIA_KEY_BLOCK_LENGTH); + init_pagecache(maria_pagecache, 65536L, 0, 0, MARIA_KEY_BLOCK_LENGTH, + MY_WME); printf("Process %d, pid: %d\n",id,getpid()); fflush(stdout); for (error=i=0 ; i < tests && !error; i++) diff --git a/storage/maria/ma_write.c b/storage/maria/ma_write.c index 5348e4c6ac2..9116ca7cce4 100644 --- a/storage/maria/ma_write.c +++ b/storage/maria/ma_write.c @@ -380,9 +380,7 @@ static int _ma_ck_write_btree_with_log(MARIA_HA *info, MARIA_KEYDEF *keyinfo, int error; my_off_t new_root= *root; uchar key_buff[HA_MAX_KEY_BUFF]; -#ifdef NOT_YET DBUG_ENTER("_ma_ck_write_btree_with_log"); -#endif if (info->s->now_transactional) { @@ -399,6 +397,8 @@ static int _ma_ck_write_btree_with_log(MARIA_HA *info, MARIA_KEYDEF *keyinfo, LEX_STRING log_array[TRANSLOG_INTERNAL_PARTS + 2]; struct st_msg_to_write_hook_for_undo_key msg; + /* Save if we need to write a clr record */ + info->key_write_undo_lsn[keyinfo->key_nr]= info->trn->undo_lsn; lsn_store(log_data, info->trn->undo_lsn); key_nr_store(log_data + LSN_STORE_SIZE + FILEID_STORE_SIZE, keyinfo->key_nr); @@ -426,15 +426,10 @@ static int _ma_ck_write_btree_with_log(MARIA_HA *info, MARIA_KEYDEF *keyinfo, } _ma_unpin_all_pages_and_finalize_row(info, lsn); -#ifdef NOT_YET DBUG_RETURN(error); -#else - return(error); -#endif } /* _ma_ck_write_btree_with_log */ - /** @brief Write a key to the b-tree @@ -485,7 +480,9 @@ int _ma_enlarge_root(MARIA_HA *info, MARIA_KEYDEF *keyinfo, const uchar *key, bzero(info->buff, info->s->keypage_header); _ma_store_keynr(info, info->buff, keyinfo->key_nr); - _ma_store_page_used(info, info->buff, page_length, nod_flag); + _ma_store_page_used(info, info->buff, page_length); + if (nod_flag) + _ma_store_keypage_flag(info, info->buff, KEYPAGE_FLAG_ISNOD); (*keyinfo->store_key)(keyinfo, info->buff + info->s->keypage_header + nod_flag, &s_temp); @@ -727,7 +724,7 @@ int _ma_insert(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo, } (*keyinfo->store_key)(keyinfo,key_pos,&s_temp); a_length+=t_length; - _ma_store_page_used(info, anc_buff, a_length, nod_flag); + _ma_store_page_used(info, anc_buff, a_length); /* Check if the new key fits totally into the the page @@ -781,7 +778,7 @@ int _ma_insert(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo, /* fixing the page's length - it contains only one key now */ _ma_store_page_used(info, anc_buff, info->s->keypage_header + blen + - ft2len + 2, 0); + ft2len + 2); } /* the rest will be done when we're back from recursion */ } @@ -874,7 +871,7 @@ int _ma_split_page(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo, split_length= (uint) (key_pos - split_buff); a_length= _ma_get_page_used(info, split_buff); - _ma_store_page_used(info, split_buff, split_length, nod_flag); + _ma_store_page_used(info, split_buff, split_length); key_pos=after_key; if (nod_flag) @@ -905,7 +902,9 @@ int _ma_split_page(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo, page_length= length + t_length + key_ref_length; bzero(new_buff, info->s->keypage_header); - _ma_store_page_used(info, new_buff, page_length, nod_flag); + if (nod_flag) + _ma_store_keypage_flag(info, new_buff, KEYPAGE_FLAG_ISNOD); + _ma_store_page_used(info, new_buff, page_length); /* Copy key number */ new_buff[info->s->keypage_header - KEYPAGE_USED_SIZE - KEYPAGE_KEYID_SIZE - KEYPAGE_FLAG_SIZE]= @@ -1121,8 +1120,8 @@ static int _ma_balance_page(register MARIA_HA *info, MARIA_KEYDEF *keyinfo, new_left_length= info->s->keypage_header+nod_flag+(keys/2)*curr_keylength; new_right_length=info->s->keypage_header+nod_flag+(((keys+1)/2)* curr_keylength); - _ma_store_page_used(info, curr_buff, new_left_length, nod_flag); - _ma_store_page_used(info, buff, new_right_length, nod_flag); + _ma_store_page_used(info, curr_buff, new_left_length); + _ma_store_page_used(info, buff, new_right_length); DBUG_PRINT("info", ("left_length: %u -> %u right_length: %u -> %u", left_length, new_left_length, @@ -1300,15 +1299,18 @@ static int _ma_balance_page(register MARIA_HA *info, MARIA_KEYDEF *keyinfo, left_length, right_length, new_left_length, new_right_length, extra_length)); - _ma_store_page_used(info, curr_buff,new_left_length,nod_flag); - _ma_store_page_used(info, buff,new_right_length,nod_flag); + _ma_store_page_used(info, curr_buff, new_left_length); + _ma_store_page_used(info, buff, new_right_length); bzero(extra_buff, info->s->keypage_header); + if (nod_flag) + _ma_store_keypage_flag(info, extra_buff, KEYPAGE_FLAG_ISNOD); + /* Copy key number */ extra_buff[info->s->keypage_header - KEYPAGE_USED_SIZE - KEYPAGE_KEYID_SIZE - KEYPAGE_FLAG_SIZE]= buff[info->s->keypage_header - KEYPAGE_USED_SIZE - KEYPAGE_KEYID_SIZE - KEYPAGE_FLAG_SIZE]; - _ma_store_page_used(info, extra_buff, extra_buff_length, nod_flag); + _ma_store_page_used(info, extra_buff, extra_buff_length); /* move first largest keys to new page */ pos=buff+right_length-extra_length; @@ -1871,12 +1873,14 @@ static my_bool _ma_log_del_prefix(MARIA_HA *info, my_off_t page, uchar *buff, translog_parts= 1; extra_length= 0; - if (offset <= diff_length) + if (offset < diff_length + info->s->keypage_header) { /* Key is not anymore on page. Move data down, but take into account that the original page had grown with 'move_length bytes' */ + DBUG_ASSERT(offset + key_length <= diff_length + info->s->keypage_header); + log_pos[0]= KEY_OP_DEL_PREFIX; int2store(log_pos+1, diff_length - move_length); log_pos+= 3; diff --git a/storage/maria/maria_chk.c b/storage/maria/maria_chk.c index 0203dd2fb26..7bae30655be 100644 --- a/storage/maria/maria_chk.c +++ b/storage/maria/maria_chk.c @@ -296,7 +296,7 @@ static struct my_option my_long_options[] = 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, { "page_buffer_size", OPT_PAGE_BUFFER_SIZE, "", (uchar**) &check_param.use_buffers, (uchar**) &check_param.use_buffers, 0, - GET_ULONG, REQUIRED_ARG, (long) USE_BUFFER_INIT, (long) MALLOC_OVERHEAD, + GET_ULONG, REQUIRED_ARG, (long) USE_BUFFER_INIT, (long) USE_BUFFER_INIT, (long) ~0L, (long) MALLOC_OVERHEAD, (long) IO_SIZE, 0}, { "read_buffer_size", OPT_READ_BUFFER_SIZE, "", (uchar**) &check_param.read_buffer_length, @@ -998,7 +998,7 @@ static int maria_chk(HA_CHECK *param, char *filename) maria_lock_database(info, F_EXTRA_LCK); datafile= info->dfile.file; if (init_pagecache(maria_pagecache, param->use_buffers, 0, 0, - maria_block_size) == 0) + maria_block_size, MY_WME) == 0) { _ma_check_print_error(param, "Can't initialize page cache with %lu memory", (ulong) param->use_buffers); diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h index 4e771a2c85a..bf02793b0ee 100644 --- a/storage/maria/maria_def.h +++ b/storage/maria/maria_def.h @@ -34,6 +34,9 @@ #endif /* Do extra sanity checking */ #define SANITY_CHECKS 1 +#ifdef EXTRA_DEBUG +#define EXTRA_DEBUG_KEY_CHANGES +#endif #define MAX_NONMAPPED_INSERTS 1000 #define MARIA_MAX_TREE_LEVELS 32 @@ -433,6 +436,8 @@ struct st_maria_handler DYNAMIC_ARRAY *ft1_to_ft2; /* used only in ft1->ft2 conversion */ MEM_ROOT ft_memroot; /* used by the parser */ MYSQL_FTPARSER_PARAM *ftparser_param; /* share info between init/deinit */ + LSN *key_write_undo_lsn; /* Pointer to undo for each key */ + LSN *key_delete_undo_lsn; /* Pointer to undo for each key */ uchar *buff; /* page buffer */ uchar *keyread_buff; /* Buffer for last key read */ uchar *lastkey, *lastkey2; /* Last used search key */ @@ -543,29 +548,29 @@ struct st_maria_handler #define MAX_KEYPAGE_HEADER_SIZE (LSN_STORE_SIZE + KEYPAGE_USED_SIZE + \ KEYPAGE_KEYID_SIZE + KEYPAGE_FLAG_SIZE + \ TRANSID_SIZE) +#define KEYPAGE_FLAG_ISNOD 1 #define _ma_get_page_used(info,x) \ - (((uint) mi_uint2korr(x + (info)->s->keypage_header - KEYPAGE_USED_SIZE)) & \ - 32767) -#define _ma_store_page_used(info,x,y,nod) \ -{ uint16 boh=(nod ? (uint16) 32768 : 0) + (uint16) (y); \ - mi_int2store(x + (info)->s->keypage_header - KEYPAGE_USED_SIZE, boh); } + ((uint) mi_uint2korr((x) + (info)->s->keypage_header - KEYPAGE_USED_SIZE)) +#define _ma_store_page_used(info,x,y) \ + mi_int2store((x) + (info)->s->keypage_header - KEYPAGE_USED_SIZE, (y)) #define _ma_test_if_nod(info,x) \ - (x[(info)->s->keypage_header-KEYPAGE_USED_SIZE] & 128 ? \ - (info)->s->base.key_reflength : 0) -#define _ma_get_used_and_nod(info,buff,length,nod) \ -{ \ - nod= 0; \ - length= mi_uint2korr((buff) + (info)->s->keypage_header - \ - KEYPAGE_USED_SIZE); \ - if (length & 32768) {length&= 32767; nod= (info)->s->base.key_reflength; } \ + ((_ma_get_keypage_flag(info,x) & KEYPAGE_FLAG_ISNOD) ? (info)->s->base.key_reflength : 0) + +#define _ma_get_used_and_nod(info,buff,length,nod) \ +{ \ + nod= _ma_test_if_nod((info),(buff)); \ + length= _ma_get_page_used((info),(buff)); \ } -#define _ma_store_keynr(info, x, nr) x[(info)->s->keypage_header - KEYPAGE_KEYID_SIZE - KEYPAGE_FLAG_SIZE - KEYPAGE_USED_SIZE]= nr +#define _ma_store_keynr(info, x, nr) x[(info)->s->keypage_header - KEYPAGE_KEYID_SIZE - KEYPAGE_FLAG_SIZE - KEYPAGE_USED_SIZE]= (nr) #define _ma_get_keynr(info, x) ((uchar) x[(info)->s->keypage_header - KEYPAGE_KEYID_SIZE - KEYPAGE_FLAG_SIZE - KEYPAGE_USED_SIZE]) #define _ma_store_transid(buff, transid) \ int6store((buff) + LSN_STORE_SIZE, (transid)) #define _ma_korr_transid(buff) \ uint6korr((buff) + LSN_STORE_SIZE) +#define _ma_get_keypage_flag(info,x) x[(info)->s->keypage_header - KEYPAGE_USED_SIZE - KEYPAGE_FLAG_SIZE] +#define _ma_store_keypage_flag(info,x,flag) x[(info)->s->keypage_header - KEYPAGE_USED_SIZE - KEYPAGE_FLAG_SIZE]= (flag) + #define maria_mark_crashed(x) do{(x)->s->state.changed|= STATE_CRASHED; \ DBUG_PRINT("error", ("Marked table crashed")); \ diff --git a/storage/maria/maria_ftdump.c b/storage/maria/maria_ftdump.c index 9df86b50474..d691cbe0c3b 100644 --- a/storage/maria/maria_ftdump.c +++ b/storage/maria/maria_ftdump.c @@ -85,7 +85,7 @@ int main(int argc,char *argv[]) } init_pagecache(maria_pagecache, USE_BUFFER_INIT, 0, 0, - MARIA_KEY_BLOCK_LENGTH); + MARIA_KEY_BLOCK_LENGTH, MY_WME); if (!(info=maria_open(argv[0], O_RDONLY, HA_OPEN_ABORT_IF_LOCKED|HA_OPEN_FROM_SQL_LAYER))) diff --git a/storage/maria/maria_pack.c b/storage/maria/maria_pack.c index b7b8a042435..dc0afdd4b64 100644 --- a/storage/maria/maria_pack.c +++ b/storage/maria/maria_pack.c @@ -516,7 +516,7 @@ static int compress(PACK_MRG_INFO *mrg,char *result_table) 2+4+16)); if (init_pagecache(maria_pagecache, MARIA_MIN_PAGE_CACHE_SIZE, 0, 0, - maria_block_size) == 0) + maria_block_size, MY_WME) == 0) { fprintf(stderr, "Can't initialize page cache\n"); goto err; @@ -2975,6 +2975,9 @@ static int save_state(MARIA_HA *isam_file,PACK_MRG_INFO *mrg, share->state.dellink= HA_OFFSET_ERROR; share->state.split=(ha_rows) mrg->records; share->state.version=(ulong) time((time_t*) 0); + if (share->base.born_transactional) + share->state.create_rename_lsn= share->state.is_of_horizon= + LSN_REPAIRED_BY_MARIA_CHK; if (! maria_is_all_keys_active(share->state.key_map, share->base.keys)) { /* diff --git a/storage/maria/maria_read_log.c b/storage/maria/maria_read_log.c index 22250a630ba..f27ae624674 100644 --- a/storage/maria/maria_read_log.c +++ b/storage/maria/maria_read_log.c @@ -29,9 +29,13 @@ const char *default_dbug_option= "d:t:i:O,\\maria_read_log.trace"; const char *default_dbug_option= "d:t:i:o,/tmp/maria_read_log.trace"; #endif #endif /* DBUG_OFF */ -static my_bool opt_display_only, opt_apply, opt_apply_undo, opt_silent, - opt_check; +static my_bool opt_display_only, opt_apply, opt_apply_undo, opt_silent; +static my_bool opt_check; +static const char *opt_tmpdir; static ulong opt_page_buffer_size; +static ulonglong opt_start_from_lsn; +static MY_TMPDIR maria_chk_tmpdir; + int main(int argc, char **argv) { @@ -66,7 +70,7 @@ int main(int argc, char **argv) /* same page cache for log and data; assumes same page size... */ DBUG_ASSERT(maria_block_size == TRANSLOG_PAGE_SIZE); if (init_pagecache(maria_pagecache, opt_page_buffer_size, 0, 0, - TRANSLOG_PAGE_SIZE) == 0) + TRANSLOG_PAGE_SIZE, MY_WME) == 0) { fprintf(stderr, "Got error in init_pagecache() (errno: %d)\n", errno); goto err; @@ -101,6 +105,19 @@ int main(int argc, char **argv) fprintf(stdout, "The transaction log starts from lsn (%lu,0x%lx)\n", LSN_IN_PARTS(lsn)); + if (opt_start_from_lsn) + { + if (opt_start_from_lsn < (ulonglong) lsn) + { + fprintf(stderr, "start_from_lsn is too small. Aborting\n"); + maria_end(); + goto err; + } + lsn= (LSN) opt_start_from_lsn; + fprintf(stdout, "Starting reading log from lsn (%lu,0x%lx)\n", + LSN_IN_PARTS(lsn)); + } + fprintf(stdout, "TRACE of the last maria_read_log\n"); if (maria_apply_log(lsn, opt_apply ? MARIA_LOG_APPLY : (opt_check ? MARIA_LOG_CHECK : @@ -113,17 +130,20 @@ int main(int argc, char **argv) fprintf(stdout, "%s: DOUBTFUL (%u warnings, check previous output)\n", my_progname_short, warnings_count); - goto end; -err: - /* don't touch anything more, in case we hit a bug */ - fprintf(stderr, "%s: FAILED\n", my_progname_short); - exit(1); end: maria_end(); + free_tmpdir(&maria_chk_tmpdir); free_defaults(default_argv); my_end(0); exit(0); return 0; /* No compiler warning */ + +err: + /* don't touch anything more, in case we hit a bug */ + fprintf(stderr, "%s: FAILED\n", my_progname_short); + free_tmpdir(&maria_chk_tmpdir); + free_defaults(default_argv); + exit(1); } @@ -147,17 +167,28 @@ static struct my_option my_long_options[] = #endif {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"display-only", 'o', "display brief info read from records' header", + {"display-only", 'd', "display brief info read from records' header", (uchar **) &opt_display_only, (uchar **) &opt_display_only, 0, GET_BOOL, NO_ARG,0, 0, 0, 0, 0, 0}, { "page_buffer_size", 'P', "", (uchar**) &opt_page_buffer_size, (uchar**) &opt_page_buffer_size, 0, GET_ULONG, REQUIRED_ARG, (long) USE_BUFFER_INIT, - (long) MALLOC_OVERHEAD, (long) ~(ulong) 0, (long) MALLOC_OVERHEAD, + (long) USE_BUFFER_INIT, (long) ~(ulong) 0, (long) MALLOC_OVERHEAD, (long) IO_SIZE, 0}, + { "start_from_lsn", 'o', "Start reading log from this lsn", + (uchar**) &opt_start_from_lsn, (uchar**) &opt_start_from_lsn, + 0, GET_ULL, REQUIRED_ARG, 0, 0, ~(longlong) 0, 0, 0, 0 }, {"silent", 's', "Print less information during apply/undo phase", (uchar **) &opt_silent, (uchar **) &opt_silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"tmpdir", 't', "Path for temporary files. Multiple paths can be specified, " + "separated by " +#if defined( __WIN__) || defined(__NETWARE__) + "semicolon (;)" +#else + "colon (:)" +#endif + , (uchar**) &opt_tmpdir, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"undo", 'u', "Apply UNDO records to tables. (disable with --disable-undo)", (uchar **) &opt_apply_undo, (uchar **) &opt_apply_undo, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, @@ -170,7 +201,7 @@ static struct my_option my_long_options[] = static void print_version(void) { - VOID(printf("%s Ver 1.1 for %s on %s\n", + VOID(printf("%s Ver 1.2 for %s on %s\n", my_progname_short, SYSTEM_TYPE, MACHINE_TYPE)); NETWARE_SET_SCREEN_MODE(1); } @@ -230,4 +261,7 @@ static void get_options(int *argc,char ***argv) usage(); exit(1); } + if (init_tmpdir(&maria_chk_tmpdir, opt_tmpdir)) + exit(1); + maria_tmpdir= &maria_chk_tmpdir; } diff --git a/storage/maria/unittest/lockman2-t.c b/storage/maria/unittest/lockman2-t.c index 01af1a03d22..c00e2695a77 100644 --- a/storage/maria/unittest/lockman2-t.c +++ b/storage/maria/unittest/lockman2-t.c @@ -286,9 +286,10 @@ pthread_handler_t test_lockman(void *arg) return 0; } -int main() +int main(int argc __attribute__((unused)), char **argv) { int i; + MY_INIT(argv[0]); my_init(); pthread_mutex_init(&rt_mutex, 0); diff --git a/storage/maria/unittest/ma_pagecache_consist.c b/storage/maria/unittest/ma_pagecache_consist.c index fb0c4fac541..a2cf8c8f9d1 100644 --- a/storage/maria/unittest/ma_pagecache_consist.c +++ b/storage/maria/unittest/ma_pagecache_consist.c @@ -362,7 +362,7 @@ int main(int argc __attribute__((unused)), #endif if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0, - PAGE_SIZE)) == 0) + PAGE_SIZE, 0)) == 0) { fprintf(stderr,"Got error: init_pagecache() (errno: %d)\n", errno); diff --git a/storage/maria/unittest/ma_pagecache_single.c b/storage/maria/unittest/ma_pagecache_single.c index 90938ae3921..8bf356afb97 100644 --- a/storage/maria/unittest/ma_pagecache_single.c +++ b/storage/maria/unittest/ma_pagecache_single.c @@ -16,6 +16,7 @@ static const char* default_dbug_option; #endif static char *file1_name= (char*)"page_cache_test_file_1"; +static char *file2_name= (char*)"page_cache_test_file_2"; static PAGECACHE_FILE file1; static pthread_cond_t COND_thread_count; static pthread_mutex_t LOCK_thread_count; @@ -69,21 +70,17 @@ static struct file_desc simple_delete_flush_test_file[]= file_name Path (and name) of file which should be reset */ -void reset_file(PAGECACHE_FILE file, char *file_name) +void reset_file(PAGECACHE_FILE *file, const char *file_name) { - flush_pagecache_blocks(&pagecache, &file1, FLUSH_RELEASE); - if (my_close(file1.file, MYF(0)) != 0) - { - diag("Got error during %s closing from close() (errno: %d)\n", - file_name, errno); + flush_pagecache_blocks(&pagecache, file, FLUSH_RELEASE); + if (my_close(file->file, MYF(MY_WME))) exit(1); - } - my_delete(file_name, MYF(0)); - if ((file.file= my_open(file_name, - O_CREAT | O_TRUNC | O_RDWR, MYF(0))) == -1) + my_delete(file_name, MYF(MY_WME)); + if ((file->file= my_open(file_name, + O_CREAT | O_TRUNC | O_RDWR, MYF(0))) == -1) { diag("Got error during %s creation from open() (errno: %d)\n", - file_name, errno); + file_name, my_errno); exit(1); } } @@ -116,7 +113,7 @@ int simple_read_write_test() simple_read_write_test_file))), "Simple write-read page file"); if (res) - reset_file(file1, file1_name); + reset_file(&file1, file1_name); free(buffw); free(buffr); DBUG_RETURN(res); @@ -131,8 +128,9 @@ int simple_read_change_write_read_test() { unsigned char *buffw= malloc(PAGE_SIZE); unsigned char *buffr= malloc(PAGE_SIZE); - int res; + int res, res2; DBUG_ENTER("simple_read_change_write_read_test"); + /* prepare the file */ bfill(buffw, PAGE_SIZE, '\1'); pagecache_write(&pagecache, &file1, 0, 3, (char*)buffw, @@ -161,15 +159,17 @@ int simple_read_change_write_read_test() 0); ok((res= test(memcmp(buffr, buffw, PAGE_SIZE) == 0)), "Simple read-change-write-read page "); + DBUG_ASSERT(pagecache.blocks_changed == 1); flush_pagecache_blocks(&pagecache, &file1, FLUSH_FORCE_WRITE); - ok((res&= test(test_file(file1, file1_name, PAGE_SIZE, PAGE_SIZE, + DBUG_ASSERT(pagecache.blocks_changed == 0); + ok((res2= test(test_file(file1, file1_name, PAGE_SIZE, PAGE_SIZE, simple_read_change_write_read_test_file))), "Simple read-change-write-read page file"); - if (res) - reset_file(file1, file1_name); + if (res && res2) + reset_file(&file1, file1_name); free(buffw); free(buffr); - DBUG_RETURN(res); + DBUG_RETURN(res && res2); } @@ -247,7 +247,7 @@ int simple_pin_test() simple_pin_test_file2))), "Simple pin page result file"); if (res) - reset_file(file1, file1_name); + reset_file(&file1, file1_name); err: free(buffw); free(buffr); @@ -289,7 +289,7 @@ int simple_delete_forget_test() simple_delete_forget_test_file))), "Simple delete-forget page file"); if (res) - reset_file(file1, file1_name); + reset_file(&file1, file1_name); free(buffw); free(buffr); DBUG_RETURN(res); @@ -331,7 +331,7 @@ int simple_delete_flush_test() simple_delete_flush_test_file))), "Simple delete-forget page file"); if (res) - reset_file(file1, file1_name); + reset_file(&file1, file1_name); free(buffw); free(buffr); DBUG_RETURN(res); @@ -344,13 +344,14 @@ int simple_delete_flush_test() int simple_big_test() { - unsigned char *buffw= (unsigned char *)malloc(PAGE_SIZE); - unsigned char *buffr= (unsigned char *)malloc(PAGE_SIZE); - struct file_desc *desc= - (struct file_desc *)malloc((PCACHE_SIZE/(PAGE_SIZE/2) + 1) * - sizeof(struct file_desc)); + unsigned char *buffw= (unsigned char *) my_malloc(PAGE_SIZE, MYF(MY_WME)); + unsigned char *buffr= (unsigned char *) my_malloc(PAGE_SIZE, MYF(MY_WME)); + struct file_desc *desc= ((struct file_desc *) + my_malloc((PCACHE_SIZE/(PAGE_SIZE/2) + 1) * + sizeof(struct file_desc), MYF(MY_WME))); int res, i; DBUG_ENTER("simple_big_test"); + /* prepare the file twice larger then cache */ for (i= 0; i < PCACHE_SIZE/(PAGE_SIZE/2); i++) { @@ -380,7 +381,8 @@ int simple_big_test() if (buffr[j] != (i & 0xff)) { diag("simple_big_test seq: page %u byte %u mismatch\n", i, j); - return 0; + res= 0; + goto err; } } } @@ -399,7 +401,8 @@ int simple_big_test() if (buffr[j] != (page & 0xff)) { diag("simple_big_test rnd: page %u byte %u mismatch\n", page, j); - return 0; + res= 0; + goto err; } } } @@ -410,11 +413,16 @@ int simple_big_test() desc))), "Simple big file"); if (res) - reset_file(file1, file1_name); - free(buffw); - free(buffr); + reset_file(&file1, file1_name); + +err: + my_free(buffw, 0); + my_free(buffr, 0); + my_free(desc, 0); DBUG_RETURN(res); } + + /* Thread function */ @@ -427,7 +435,6 @@ static void *test_thread(void *arg) my_thread_init(); DBUG_ENTER("test_thread"); - DBUG_PRINT("enter", ("param: %d", param)); if (!simple_read_write_test() || @@ -460,7 +467,7 @@ int main(int argc __attribute__((unused)), pthread_t tid; pthread_attr_t thr_attr; int *param, error, pagen; - + File tmp_file; MY_INIT(argv[0]); #ifndef DBUG_OFF @@ -475,10 +482,13 @@ int main(int argc __attribute__((unused)), DBUG_SET_INITIAL(default_dbug_option); } #endif - - DBUG_ENTER("main"); DBUG_PRINT("info", ("Main thread: %s\n", my_thread_name())); + + if ((tmp_file= my_open(file2_name, O_CREAT | O_TRUNC | O_RDWR, + MYF(MY_WME))) < 0) + exit(1); + if ((file1.file= my_open(file1_name, O_CREAT | O_TRUNC | O_RDWR, MYF(0))) == -1) { @@ -486,6 +496,9 @@ int main(int argc __attribute__((unused)), errno); exit(1); } + my_close(tmp_file, MYF(0)); + my_delete(file2_name, MYF(0)); + DBUG_PRINT("info", ("file1: %d", file1.file)); if (chmod(file1_name, S_IRWXU | S_IRWXG | S_IRWXO) != 0) { @@ -529,7 +542,7 @@ int main(int argc __attribute__((unused)), plan(12); if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0, - PAGE_SIZE)) == 0) + PAGE_SIZE, MYF(MY_WME))) == 0) { fprintf(stderr,"Got error: init_pagecache() (errno: %d)\n", errno); @@ -571,12 +584,9 @@ int main(int argc __attribute__((unused)), end_pagecache(&pagecache, 1); DBUG_PRINT("info", ("Page cache ended")); - if (my_close(file1.file, MYF(0)) != 0) - { - fprintf(stderr, "Got error during file1 closing from close() (errno: %d)\n", - errno); + if (my_close(file1.file, MYF(MY_WME))) exit(1); - } + /*my_delete(file1_name, MYF(0));*/ my_end(0); diff --git a/storage/maria/unittest/ma_test_loghandler-t.c b/storage/maria/unittest/ma_test_loghandler-t.c index 48aae3e1b3e..452477f6975 100644 --- a/storage/maria/unittest/ma_test_loghandler-t.c +++ b/storage/maria/unittest/ma_test_loghandler-t.c @@ -170,7 +170,7 @@ int main(int argc __attribute__((unused)), char *argv[]) exit(1); } if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0, - TRANSLOG_PAGE_SIZE)) == 0) + TRANSLOG_PAGE_SIZE, 0)) == 0) { fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno); exit(1); diff --git a/storage/maria/unittest/ma_test_loghandler_first_lsn-t.c b/storage/maria/unittest/ma_test_loghandler_first_lsn-t.c index 845e33b63a5..30c51c96ffb 100644 --- a/storage/maria/unittest/ma_test_loghandler_first_lsn-t.c +++ b/storage/maria/unittest/ma_test_loghandler_first_lsn-t.c @@ -60,7 +60,7 @@ int main(int argc __attribute__((unused)), char *argv[]) exit(1); } if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0, - PCACHE_PAGE)) == 0) + PCACHE_PAGE, 0)) == 0) { fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno); exit(1); diff --git a/storage/maria/unittest/ma_test_loghandler_max_lsn-t.c b/storage/maria/unittest/ma_test_loghandler_max_lsn-t.c index 68561443a02..5f9ed01cb4a 100644 --- a/storage/maria/unittest/ma_test_loghandler_max_lsn-t.c +++ b/storage/maria/unittest/ma_test_loghandler_max_lsn-t.c @@ -54,7 +54,7 @@ int main(int argc __attribute__((unused)), char *argv[]) exit(1); } if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0, - PCACHE_PAGE)) == 0) + PCACHE_PAGE, 0)) == 0) { fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno); exit(1); diff --git a/storage/maria/unittest/ma_test_loghandler_multigroup-t.c b/storage/maria/unittest/ma_test_loghandler_multigroup-t.c index e5afa0b40db..c66ad6fdc8d 100644 --- a/storage/maria/unittest/ma_test_loghandler_multigroup-t.c +++ b/storage/maria/unittest/ma_test_loghandler_multigroup-t.c @@ -167,7 +167,7 @@ int main(int argc __attribute__((unused)), char *argv[]) exit(1); } if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0, - TRANSLOG_PAGE_SIZE)) == 0) + TRANSLOG_PAGE_SIZE, 0)) == 0) { fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno); exit(1); @@ -332,7 +332,7 @@ int main(int argc __attribute__((unused)), char *argv[]) exit(1); } if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0, - TRANSLOG_PAGE_SIZE)) == 0) + TRANSLOG_PAGE_SIZE, 0)) == 0) { fprintf(stderr, "pass2: Got error: init_pagecache() (errno: %d)\n", errno); exit(1); diff --git a/storage/maria/unittest/ma_test_loghandler_multithread-t.c b/storage/maria/unittest/ma_test_loghandler_multithread-t.c index 0a81aeac55f..43e124f208c 100644 --- a/storage/maria/unittest/ma_test_loghandler_multithread-t.c +++ b/storage/maria/unittest/ma_test_loghandler_multithread-t.c @@ -277,7 +277,7 @@ int main(int argc __attribute__((unused)), exit(1); } if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0, - TRANSLOG_PAGE_SIZE)) == 0) + TRANSLOG_PAGE_SIZE, 0)) == 0) { fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno); exit(1); diff --git a/storage/maria/unittest/ma_test_loghandler_noflush-t.c b/storage/maria/unittest/ma_test_loghandler_noflush-t.c index a53e6257314..01e1bc71fbe 100644 --- a/storage/maria/unittest/ma_test_loghandler_noflush-t.c +++ b/storage/maria/unittest/ma_test_loghandler_noflush-t.c @@ -62,7 +62,7 @@ int main(int argc __attribute__((unused)), char *argv[]) exit(1); } if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0, - PCACHE_PAGE)) == 0) + PCACHE_PAGE, 0)) == 0) { fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno); exit(1); diff --git a/storage/maria/unittest/ma_test_loghandler_pagecache-t.c b/storage/maria/unittest/ma_test_loghandler_pagecache-t.c index c93f57fad01..e384acad5e5 100644 --- a/storage/maria/unittest/ma_test_loghandler_pagecache-t.c +++ b/storage/maria/unittest/ma_test_loghandler_pagecache-t.c @@ -62,7 +62,7 @@ int main(int argc __attribute__((unused)), char *argv[]) exit(1); } if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0, - PCACHE_PAGE)) == 0) + PCACHE_PAGE, 0)) == 0) { fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno); exit(1); diff --git a/storage/maria/unittest/ma_test_loghandler_purge-t.c b/storage/maria/unittest/ma_test_loghandler_purge-t.c index d9001b9d3ad..d59ac1a12dd 100644 --- a/storage/maria/unittest/ma_test_loghandler_purge-t.c +++ b/storage/maria/unittest/ma_test_loghandler_purge-t.c @@ -57,7 +57,7 @@ int main(int argc __attribute__((unused)), char *argv[]) exit(1); } if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0, - PCACHE_PAGE)) == 0) + PCACHE_PAGE, 0)) == 0) { fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno); exit(1); diff --git a/storage/maria/unittest/test_file.c b/storage/maria/unittest/test_file.c index 758d0bfa81b..215fd54a819 100644 --- a/storage/maria/unittest/test_file.c +++ b/storage/maria/unittest/test_file.c @@ -24,32 +24,37 @@ int test_file(PAGECACHE_FILE file, char *file_name, off_t size, size_t buff_size, struct file_desc *desc) { MY_STAT stat_buff, *stat; - unsigned char *buffr= malloc(buff_size); + unsigned char *buffr= my_malloc(buff_size, MYF(0)); off_t pos= 0; size_t byte; int step= 0; + int res= 1; /* ok */ if ((stat= my_stat(file_name, &stat_buff, MYF(0))) == NULL) { diag("Can't stat() %s (errno: %d)\n", file_name, errno); - return 0; + res= 0; + goto err; } if (stat->st_size != size) { diag("file %s size is %lu (should be %lu)\n", file_name, (ulong) stat->st_size, (ulong) size); - return 0; + res= 0; /* failed */ + /* continue to get more information */ } + /* check content */ - my_seek(file.file, 0, SEEK_SET, MYF(0)); + my_seek(file.file, 0, SEEK_SET, MYF(MY_WME)); while (desc[step].length != 0) { if (my_read(file.file, (char*)buffr, desc[step].length, MYF(0)) != desc[step].length) { - diag("Can't read %u bytes from %s (errno: %d)\n", - (uint)desc[step].length, file_name, errno); - return 0; + diag("Can't read %u bytes from %s (file: %d errno: %d)\n", + (uint)desc[step].length, file_name, file.file, errno); + res= 0; + goto err; } for (byte= 0; byte < desc[step].length; byte++) { @@ -58,11 +63,15 @@ int test_file(PAGECACHE_FILE file, char *file_name, diag("content of %s mismatch 0x%x in position %lu instead of 0x%x\n", file_name, (uint) buffr[byte], (ulong) (pos + byte), desc[step].content); - return 0; + res= 0; + goto err; } } pos+= desc[step].length; step++; } - return 1; + +err: + my_free(buffr, 0); + return res; } diff --git a/storage/maria/unittest/trnman-t.c b/storage/maria/unittest/trnman-t.c index db137cf088c..103f76cf776 100644 --- a/storage/maria/unittest/trnman-t.c +++ b/storage/maria/unittest/trnman-t.c @@ -154,8 +154,9 @@ void test_trnman_read_from() } } -int main() +int main(int argc __attribute__((unused)), char **argv) { + MY_INIT(argv[0]); my_init(); plan(6); diff --git a/storage/myisam/mi_cache.c b/storage/myisam/mi_cache.c index d6dcc431a8d..1ccf038a570 100644 --- a/storage/myisam/mi_cache.c +++ b/storage/myisam/mi_cache.c @@ -97,8 +97,8 @@ int _mi_read_cache(IO_CACHE *info, uchar *buff, my_off_t pos, uint length, DBUG_PRINT("error", ("Error %d reading next-multi-part block (Got %d bytes)", my_errno, (int) read_length)); - if (!my_errno || my_errno == -1) - my_errno=HA_ERR_WRONG_IN_RECORD; + if (!my_errno || my_errno == -1 || my_errno == HA_ERR_FILE_TOO_SHORT) + my_errno= HA_ERR_WRONG_IN_RECORD; DBUG_RETURN(1); } bzero(buff+read_length,MI_BLOCK_INFO_HEADER_LENGTH - in_buff_length - diff --git a/storage/myisam/mi_create.c b/storage/myisam/mi_create.c index 38e518fd823..23f84819949 100644 --- a/storage/myisam/mi_create.c +++ b/storage/myisam/mi_create.c @@ -185,7 +185,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, if (flags & HA_CREATE_TMP_TABLE) { options|= HA_OPTION_TMP_TABLE; - create_mode|= O_EXCL | O_NOFOLLOW; + create_mode|= O_NOFOLLOW; } if (flags & HA_CREATE_CHECKSUM || (options & HA_OPTION_CHECKSUM)) { diff --git a/storage/myisam/mi_dynrec.c b/storage/myisam/mi_dynrec.c index 2a12fd04641..0811de2b968 100644 --- a/storage/myisam/mi_dynrec.c +++ b/storage/myisam/mi_dynrec.c @@ -1764,7 +1764,7 @@ int _mi_read_rnd_dynamic_record(MI_INFO *info, uchar *buf, /* VOID(my_seek(info->dfile,filepos,MY_SEEK_SET,MYF(0))); */ if (my_read(info->dfile,(uchar*) to,block_info.data_len,MYF(MY_NABP))) { - if (my_errno == -1) + if (my_errno == HA_ERR_FILE_TOO_SHORT) my_errno= HA_ERR_WRONG_IN_RECORD; /* Unexpected end of file */ goto err; } diff --git a/storage/myisam/mi_locking.c b/storage/myisam/mi_locking.c index 2d89fce2a81..ad23a42ab83 100644 --- a/storage/myisam/mi_locking.c +++ b/storage/myisam/mi_locking.c @@ -429,10 +429,10 @@ int _mi_readinfo(register MI_INFO *info, int lock_type, int check_keybuffer) DBUG_RETURN(1); if (mi_state_info_read_dsk(share->kfile, &share->state, 1)) { - int error=my_errno ? my_errno : -1; + int error= my_errno ? my_errno : HA_ERR_FILE_TOO_SHORT; VOID(my_lock(share->kfile,F_UNLCK,0L,F_TO_EOF, MYF(MY_SEEK_NOT_DONE))); - my_errno=error; + my_errno= error; DBUG_RETURN(1); } } |