summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.bzrignore2
-rw-r--r--include/maria.h2
-rw-r--r--include/my_base.h3
-rw-r--r--include/my_sys.h2
-rw-r--r--include/myisamchk.h1
-rw-r--r--mysql-test/r/innodb.result14
-rw-r--r--mysql-test/r/mix2_myisam.result28
-rw-r--r--mysql-test/r/myisam.result12
-rw-r--r--mysql-test/r/old-mode.result14
-rw-r--r--mysql-test/t/myisam.test2
-rw-r--r--mysql-test/t/old-mode-master.opt1
-rw-r--r--mysql-test/t/old-mode.test16
-rw-r--r--mysys/checksum.c12
-rw-r--r--mysys/lf_alloc-pin.c1
-rw-r--r--mysys/my_handler.c3
-rw-r--r--mysys/my_init.c12
-rw-r--r--mysys/my_pread.c7
-rw-r--r--mysys/my_read.c6
-rw-r--r--sql/mysqld.cc8
-rw-r--r--sql/sql_parse.cc3
-rw-r--r--storage/maria/ha_maria.cc17
-rw-r--r--storage/maria/ma_blockrec.c4
-rw-r--r--storage/maria/ma_cache.c4
-rw-r--r--storage/maria/ma_check.c39
-rw-r--r--storage/maria/ma_delete.c78
-rw-r--r--storage/maria/ma_dynrec.c2
-rw-r--r--storage/maria/ma_ft_update.c2
-rw-r--r--storage/maria/ma_key_recover.c122
-rw-r--r--storage/maria/ma_locking.c4
-rw-r--r--storage/maria/ma_loghandler.c2
-rw-r--r--storage/maria/ma_loghandler.h1
-rw-r--r--storage/maria/ma_open.c4
-rwxr-xr-xstorage/maria/ma_pagecache.c214
-rw-r--r--storage/maria/ma_pagecache.h5
-rw-r--r--storage/maria/ma_recovery.c191
-rw-r--r--storage/maria/ma_rt_index.c7
-rw-r--r--storage/maria/ma_rt_key.c4
-rw-r--r--storage/maria/ma_rt_split.c7
-rw-r--r--storage/maria/ma_static.c1
-rw-r--r--storage/maria/ma_test1.c6
-rw-r--r--storage/maria/ma_test2.c4
-rw-r--r--storage/maria/ma_test3.c3
-rw-r--r--storage/maria/ma_write.c40
-rw-r--r--storage/maria/maria_chk.c4
-rw-r--r--storage/maria/maria_def.h33
-rw-r--r--storage/maria/maria_ftdump.c2
-rw-r--r--storage/maria/maria_pack.c5
-rw-r--r--storage/maria/maria_read_log.c56
-rw-r--r--storage/maria/unittest/lockman2-t.c3
-rw-r--r--storage/maria/unittest/ma_pagecache_consist.c2
-rw-r--r--storage/maria/unittest/ma_pagecache_single.c90
-rw-r--r--storage/maria/unittest/ma_test_loghandler-t.c2
-rw-r--r--storage/maria/unittest/ma_test_loghandler_first_lsn-t.c2
-rw-r--r--storage/maria/unittest/ma_test_loghandler_max_lsn-t.c2
-rw-r--r--storage/maria/unittest/ma_test_loghandler_multigroup-t.c4
-rw-r--r--storage/maria/unittest/ma_test_loghandler_multithread-t.c2
-rw-r--r--storage/maria/unittest/ma_test_loghandler_noflush-t.c2
-rw-r--r--storage/maria/unittest/ma_test_loghandler_pagecache-t.c2
-rw-r--r--storage/maria/unittest/ma_test_loghandler_purge-t.c2
-rw-r--r--storage/maria/unittest/test_file.c27
-rw-r--r--storage/maria/unittest/trnman-t.c3
-rw-r--r--storage/myisam/mi_cache.c4
-rw-r--r--storage/myisam/mi_create.c2
-rw-r--r--storage/myisam/mi_dynrec.c2
-rw-r--r--storage/myisam/mi_locking.c4
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 &param, bool do_optimize)
ulonglong key_map= ((local_testflag & T_CREATE_MISSING_KEYS) ?
maria_get_mask_all_keys_active(share->base.keys) :
share->state.key_map);
- uint testflag= param.testflag;
+ uint save_testflag= param.testflag;
if (maria_test_if_sort_rep(file, file->state->records, key_map, 0) &&
(local_testflag & T_REP_BY_SORT))
{
@@ -1226,6 +1226,7 @@ int ha_maria::repair(THD *thd, HA_CHECK &param, bool do_optimize)
/* TODO: respect maria_repair_threads variable */
my_snprintf(buf, 40, "Repair with %d threads", my_count_bits(key_map));
thd->proc_info= buf;
+ param.testflag|= T_REP_PARALLEL;
error= maria_repair_parallel(&param, file, fixed_name,
param.testflag & T_QUICK);
thd->proc_info= "Repair done"; // to reset proc_info, as
@@ -1234,6 +1235,7 @@ int ha_maria::repair(THD *thd, HA_CHECK &param, bool do_optimize)
else
{
thd->proc_info= "Repair by sorting";
+ param.testflag|= T_REP_BY_SORT;
error= maria_repair_by_sort(&param, file, fixed_name,
param.testflag & T_QUICK);
}
@@ -1241,7 +1243,7 @@ int ha_maria::repair(THD *thd, HA_CHECK &param, bool do_optimize)
else
{
thd->proc_info= "Repair with keycache";
- param.testflag &= ~T_REP_BY_SORT;
+ param.testflag &= ~(T_REP_BY_SORT | T_REP_PARALLEL);
error= maria_repair(&param, file, fixed_name, param.testflag & T_QUICK);
/**
@todo RECOVERY BUG we do things with the index file
@@ -1249,7 +1251,7 @@ int ha_maria::repair(THD *thd, HA_CHECK &param, bool do_optimize)
record and bumped create_rename_lsn. Is it ok?
*/
}
- param.testflag= testflag;
+ param.testflag= save_testflag;
optimize_done= 1;
}
if (!error)
@@ -2410,13 +2412,14 @@ static int ha_maria_init(void *p)
maria_hton->flags= HTON_CAN_RECREATE | HTON_SUPPORT_LOG_TABLES;
bzero(maria_log_pagecache, sizeof(*maria_log_pagecache));
maria_data_root= mysql_real_data_home;
+ maria_tmpdir= &mysql_tmpdir_list; /* For REDO */
res= maria_init() || ma_control_file_create_or_open() ||
- (init_pagecache(maria_pagecache,
+ !init_pagecache(maria_pagecache,
pagecache_buffer_size, pagecache_division_limit,
- pagecache_age_threshold, MARIA_KEY_BLOCK_LENGTH) == 0) ||
- (init_pagecache(maria_log_pagecache,
+ pagecache_age_threshold, MARIA_KEY_BLOCK_LENGTH, 0) ||
+ !init_pagecache(maria_log_pagecache,
TRANSLOG_PAGECACHE_SIZE, 0, 0,
- TRANSLOG_PAGE_SIZE) == 0) ||
+ TRANSLOG_PAGE_SIZE, 0) ||
translog_init(maria_data_root, TRANSLOG_FILE_SIZE,
MYSQL_VERSION_ID, server_id, maria_log_pagecache,
TRANSLOG_DEFAULT_FLAGS) ||
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(&param);
- param.isam_file_name= info->s->open_file_name;
- param.testflag= uint4korr(rec->header);
- if (maria_repair(&param, info, info->s->open_file_name, param.testflag))
+ param.isam_file_name= name= info->s->open_file_name;
+ param.testflag= uint4korr(rec->header + FILEID_STORE_SIZE);
+ param.tmpdir= maria_tmpdir;
+ DBUG_ASSERT(maria_tmpdir);
+
+ info->s->state.key_map= uint8korr(rec->header + FILEID_STORE_SIZE + 4);
+ quick_repair= param.testflag & T_QUICK;
+
+
+ if (param.testflag & T_REP_PARALLEL)
+ {
+ if (maria_repair_parallel(&param, info, name, quick_repair))
+ goto end;
+ }
+ else if (param.testflag & T_REP_BY_SORT)
+ {
+ if (maria_repair_by_sort(&param, info, name, quick_repair))
+ goto end;
+ }
+ else if (maria_repair(&param, info, name, quick_repair))
goto end;
+
if (_ma_update_create_rename_lsn(info->s, rec->lsn, TRUE))
goto end;
error= 0;
+
end:
- return error;
+ DBUG_RETURN(error);
}
@@ -953,7 +1013,7 @@ prototype_redo_exec_hook(REDO_DROP_TABLE)
log_record_buffer.str, NULL) !=
rec->record_length)
{
- tprint(tracef, "Failed to read record\n");
+ eprint(tracef, "Failed to read record\n");
return 1;
}
name= log_record_buffer.str;
@@ -991,7 +1051,7 @@ prototype_redo_exec_hook(REDO_DROP_TABLE)
tprint(tracef, ", dropping '%s'", name);
if (maria_delete_table(name))
{
- tprint(tracef, "Failed to drop table\n");
+ eprint(tracef, "Failed to drop table\n");
goto end;
}
}
@@ -1012,6 +1072,7 @@ prototype_redo_exec_hook(FILE_ID)
int error= 1;
const char *name;
MARIA_HA *info;
+ DBUG_ENTER("exec_REDO_LOGREC_FILE_ID");
if (cmp_translog_addr(rec->lsn, checkpoint_start) < 0)
{
@@ -1022,7 +1083,7 @@ prototype_redo_exec_hook(FILE_ID)
happened and so mapping is not needed.
*/
tprint(tracef, "ignoring because before checkpoint\n");
- return 0;
+ DBUG_RETURN(0);
}
enlarge_buffer(rec);
@@ -1031,7 +1092,7 @@ prototype_redo_exec_hook(FILE_ID)
log_record_buffer.str, NULL) !=
rec->record_length)
{
- tprint(tracef, "Failed to read record\n");
+ eprint(tracef, "Failed to read record\n");
goto end;
}
sid= fileid_korr(log_record_buffer.str);
@@ -1042,7 +1103,7 @@ prototype_redo_exec_hook(FILE_ID)
prepare_table_for_close(info, rec->lsn);
if (maria_close(info))
{
- tprint(tracef, "Failed to close table\n");
+ eprint(tracef, "Failed to close table\n");
goto end;
}
all_tables[sid].info= NULL;
@@ -1052,7 +1113,7 @@ prototype_redo_exec_hook(FILE_ID)
goto end;
error= 0;
end:
- return error;
+ DBUG_RETURN(error);
}
@@ -1213,14 +1274,14 @@ prototype_redo_exec_hook(REDO_INSERT_ROW_HEAD)
enlarge_buffer(rec);
if (log_record_buffer.str == NULL)
{
- tprint(tracef, "Failed to read allocate buffer for record\n");
+ eprint(tracef, "Failed to read allocate buffer for record\n");
goto end;
}
if (translog_read_record(rec->lsn, 0, rec->record_length,
log_record_buffer.str, NULL) !=
rec->record_length)
{
- tprint(tracef, "Failed to read record\n");
+ eprint(tracef, "Failed to read record\n");
goto end;
}
buff= log_record_buffer.str;
@@ -1255,7 +1316,7 @@ prototype_redo_exec_hook(REDO_INSERT_ROW_TAIL)
log_record_buffer.str, NULL) !=
rec->record_length)
{
- tprint(tracef, "Failed to read record\n");
+ eprint(tracef, "Failed to read record\n");
goto end;
}
buff= log_record_buffer.str;
@@ -1291,7 +1352,7 @@ prototype_redo_exec_hook(REDO_INSERT_ROW_BLOBS)
log_record_buffer.str, NULL) !=
rec->record_length)
{
- tprint(tracef, "Failed to read record\n");
+ eprint(tracef, "Failed to read record\n");
goto end;
}
buff= log_record_buffer.str;
@@ -1351,7 +1412,7 @@ prototype_redo_exec_hook(REDO_FREE_BLOCKS)
log_record_buffer.str, NULL) !=
rec->record_length)
{
- tprint(tracef, "Failed to read record\n");
+ eprint(tracef, "Failed to read record\n");
goto end;
}
@@ -1410,7 +1471,7 @@ prototype_redo_exec_hook(REDO_INDEX)
log_record_buffer.str, NULL) !=
rec->record_length)
{
- tprint(tracef, "Failed to read record\n");
+ eprint(tracef, "Failed to read record\n");
goto end;
}
@@ -1436,7 +1497,7 @@ prototype_redo_exec_hook(REDO_INDEX_NEW_PAGE)
log_record_buffer.str, NULL) !=
rec->record_length)
{
- tprint(tracef, "Failed to read record\n");
+ eprint(tracef, "Failed to read record\n");
goto end;
}
@@ -1493,7 +1554,7 @@ prototype_redo_exec_hook(UNDO_ROW_INSERT)
HA_CHECKSUM_STORE_SIZE, buff, NULL) !=
HA_CHECKSUM_STORE_SIZE)
{
- tprint(tracef, "Failed to read record\n");
+ eprint(tracef, "Failed to read record\n");
return 1;
}
share->state.state.checksum+= ha_checksum_korr(buff);
@@ -1532,7 +1593,7 @@ prototype_redo_exec_hook(UNDO_ROW_DELETE)
HA_CHECKSUM_STORE_SIZE, buff, NULL) !=
HA_CHECKSUM_STORE_SIZE)
{
- tprint(tracef, "Failed to read record\n");
+ eprint(tracef, "Failed to read record\n");
return 1;
}
share->state.state.checksum+= ha_checksum_korr(buff);
@@ -1564,7 +1625,7 @@ prototype_redo_exec_hook(UNDO_ROW_UPDATE)
HA_CHECKSUM_STORE_SIZE, buff, NULL) !=
HA_CHECKSUM_STORE_SIZE)
{
- tprint(tracef, "Failed to read record\n");
+ eprint(tracef, "Failed to read record\n");
return 1;
}
share->state.state.checksum+= ha_checksum_korr(buff);
@@ -1712,7 +1773,7 @@ prototype_redo_exec_hook(CLR_END)
buff, NULL) !=
KEY_NR_STORE_SIZE + PAGE_STORE_SIZE)
{
- tprint(tracef, "Failed to read record\n");
+ eprint(tracef, "Failed to read record\n");
DBUG_RETURN(1);
}
key_nr= key_nr_korr(buff);
@@ -1732,7 +1793,7 @@ prototype_redo_exec_hook(CLR_END)
CLR_TYPE_STORE_SIZE, HA_CHECKSUM_STORE_SIZE,
buff, NULL) != HA_CHECKSUM_STORE_SIZE)
{
- tprint(tracef, "Failed to read record\n");
+ eprint(tracef, "Failed to read record\n");
DBUG_RETURN(1);
}
share->state.state.checksum+= ha_checksum_korr(buff);
@@ -1781,7 +1842,7 @@ prototype_undo_exec_hook(UNDO_ROW_INSERT)
log_record_buffer.str, NULL) !=
rec->record_length)
{
- tprint(tracef, "Failed to read record\n");
+ eprint(tracef, "Failed to read record\n");
return 1;
}
record_ptr= log_record_buffer.str;
@@ -1818,7 +1879,7 @@ prototype_undo_exec_hook(UNDO_ROW_DELETE)
log_record_buffer.str, NULL) !=
rec->record_length)
{
- tprint(tracef, "Failed to read record\n");
+ eprint(tracef, "Failed to read record\n");
return 1;
}
@@ -1860,7 +1921,7 @@ prototype_undo_exec_hook(UNDO_ROW_UPDATE)
log_record_buffer.str, NULL) !=
rec->record_length)
{
- tprint(tracef, "Failed to read record\n");
+ eprint(tracef, "Failed to read record\n");
return 1;
}
@@ -1904,7 +1965,7 @@ prototype_undo_exec_hook(UNDO_KEY_INSERT)
log_record_buffer.str, NULL) !=
rec->record_length)
{
- tprint(tracef, "Failed to read record\n");
+ eprint(tracef, "Failed to read record\n");
return 1;
}
@@ -1949,7 +2010,7 @@ prototype_undo_exec_hook(UNDO_KEY_DELETE)
log_record_buffer.str, NULL) !=
rec->record_length)
{
- tprint(tracef, "Failed to read record\n");
+ eprint(tracef, "Failed to read record\n");
return 1;
}
@@ -1994,7 +2055,7 @@ prototype_undo_exec_hook(UNDO_KEY_DELETE_WITH_ROOT)
log_record_buffer.str, NULL) !=
rec->record_length)
{
- tprint(tracef, "Failed to read record\n");
+ eprint(tracef, "Failed to read record\n");
return 1;
}
@@ -2077,7 +2138,7 @@ static int run_redo_phase(LSN lsn, enum maria_apply_log_way apply)
if (len == RECHEADER_READ_ERROR)
{
- tprint(tracef, "Failed to read header of the first record.\n");
+ eprint(tracef, "Failed to read header of the first record.\n");
return 1;
}
if (translog_init_scanner(lsn, 1, &scanner, 1))
@@ -2211,7 +2272,10 @@ static int run_redo_phase(LSN lsn, enum maria_apply_log_way apply)
translog_destroy_scanner(&scanner);
translog_free_record_header(&rec);
if (recovery_message_printed == REC_MSG_REDO)
+ {
fprintf(stderr, " 100%%");
+ procent_printed= 1;
+ }
return 0;
err:
@@ -2343,7 +2407,7 @@ static int run_undo_phase(uint unfinished)
display_record_position(log_desc, &rec, 0);
if (log_desc->record_execute_in_undo_phase(&rec, trn))
{
- tprint(tracef, "Got error when executing undo\n");
+ tprint(tracef, "Got error %d when executing undo\n", my_errno);
return 1;
}
}
@@ -2542,7 +2606,7 @@ static LSN parse_checkpoint_record(LSN lsn)
log_record_buffer.str, NULL) !=
rec.record_length)
{
- tprint(tracef, "Failed to read record\n");
+ eprint(tracef, "Failed to read record\n");
return LSN_ERROR;
}
@@ -2793,6 +2857,7 @@ static void print_redo_phase_progress(TRANSLOG_ADDRESS addr)
static ulonglong initial_remainder= -1;
int cur_logno, cur_offset;
ulonglong local_remainder;
+ int percentage_done;
if (tracef == stdout)
return;
@@ -2800,6 +2865,7 @@ static void print_redo_phase_progress(TRANSLOG_ADDRESS addr)
{
print_preamble();
fprintf(stderr, "recovered pages: 0%%");
+ procent_printed= 1;
recovery_message_printed= REC_MSG_REDO;
}
if (end_logno == FILENO_IMPOSSIBLE)
@@ -2815,12 +2881,13 @@ static void print_redo_phase_progress(TRANSLOG_ADDRESS addr)
max(end_logno - cur_logno - 1, 0) * TRANSLOG_FILE_SIZE + end_offset);
if (initial_remainder == (ulonglong)(-1))
initial_remainder= local_remainder;
- int percentage_done=
- (initial_remainder - local_remainder) * ULL(100) / initial_remainder;
+ percentage_done= ((initial_remainder - local_remainder) * ULL(100) /
+ initial_remainder);
if ((percentage_done - percentage_printed) >= 10)
{
percentage_printed= percentage_done;
fprintf(stderr, " %d%%", percentage_done);
+ procent_printed= 1;
}
}
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);
}
}