summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <monty@mysql.com/narttu.mysql.fi>2007-11-28 21:38:30 +0200
committerunknown <monty@mysql.com/narttu.mysql.fi>2007-11-28 21:38:30 +0200
commit4e0964cb040d833351ddd66c00b146b2e93e9fa7 (patch)
treee16074ce3069413dcf25dc2c9487938ac5c62806
parent63cd7bdcd5f95ed08b521099157ff4c61fa62bc3 (diff)
downloadmariadb-git-4e0964cb040d833351ddd66c00b146b2e93e9fa7.tar.gz
Fixed repair_by_sort to work with BLOCK_RECORD
Fixed bugs in undo logging Fixed bug where head block was split before min_row_length (caused Maria to believe row was crashed on read) Reserved place for reference-transid on key pages (for packing of transids) ALTER TABLE and INSERT ... SELECT now uses fast creation of index Known bugs: ma_test_recovery fails because of a bug in redo handling when log is cut directly after a redo (Guilhem knows how to fix) ma_test_recovery.excepted is not totally correct, because of the above bug mysqld sometimes fails to restart; Fails with error "end_of_redo_phase: Assertion `long_trid != 0' failed"; Guilhem to investigate include/maria.h: Prototype changes Added current_filepos to st_maria_sort_info mysql-test/r/maria.result: Updated results that changes as alter table and insert ... select now uses fast creation of index mysys/mf_iocache.c: Reset variable to gurard against double invocation storage/maria/ma_bitmap.c: Added _ma_bitmap_reset_cache() (needed for repair) storage/maria/ma_blockrec.c: Simplify code More initial allocations Fixed bug where head block was split before min_row_length (caused Maria to believe row was crashed on read) storage/maria/ma_blockrec.h: Moved TRANSID_SIZE to maria_def.h Added prototype for new functions storage/maria/ma_check.c: Simplicy code Fixed repair_by_sort to work with BLOCK_RECORD - When using BLOCK_RECORD or UNPACK create new Maria handle - Use common initializer function - Align code with maria_repair() Made some changes to maria_repair_parallel() to use common initializer function Removed ASK_MONTY section by fixing noted problem storage/maria/ma_close.c: Moved check for readonly to _ma_state_info_write() storage/maria/ma_key_recover.c: Use different log entries if key root changes or not. This fixed some bugs when tree grows storage/maria/ma_key_recover.h: Added keynr to st_msg_to_write_hook_for_undo_key storage/maria/ma_loghandler.c: Added INIT_LOGREC_UNDO_KEY_INSERT_WITH_ROOT storage/maria/ma_loghandler.h: Added INIT_LOGREC_UNDO_KEY_INSERT_WITH_ROOT storage/maria/ma_open.c: Added TRANSID to all key pages (for future compressing of trans id's) For compressed records, alloc a bit bigger buffer to avoid valgrind warnings If table is opened readonly, don't update state storage/maria/ma_packrec.c: Allocate bigger array for bit unpacking to avoid valgrind errors storage/maria/ma_recovery.c: Added UNDO_KEY_INSERT_WITH_ROOT & UNDO_KEY_DELETE_WITH_ROOT storage/maria/ma_sort.c: More logging storage/maria/ma_test_all.sh: More tests storage/maria/ma_test_recovery.expected: Update results Note that this is not complete becasue of a bug in recovery storage/maria/ma_test_recovery: Removed recreation of index (not needed when we have redo for index pages) storage/maria/maria_chk.c: When using flag --read-only, don't update status for files When using --unpack, don't use REPAIR_BY_SORT if other repair option is given Enable repair_by_sort for BLOCK records Removed not needed newline at start of --describe storage/maria/maria_def.h: Support for TRANSID_SIZE to key pages storage/maria/maria_read_log.c: renamed --only-display to --display-only
-rw-r--r--include/maria.h16
-rw-r--r--mysql-test/r/maria.result6
-rw-r--r--mysys/mf_iocache.c1
-rw-r--r--storage/maria/ma_bitmap.c56
-rw-r--r--storage/maria/ma_blockrec.c34
-rw-r--r--storage/maria/ma_blockrec.h11
-rw-r--r--storage/maria/ma_check.c649
-rw-r--r--storage/maria/ma_close.c3
-rw-r--r--storage/maria/ma_key_recover.c47
-rw-r--r--storage/maria/ma_key_recover.h1
-rw-r--r--storage/maria/ma_loghandler.c9
-rw-r--r--storage/maria/ma_loghandler.h1
-rw-r--r--storage/maria/ma_open.c13
-rw-r--r--storage/maria/ma_packrec.c12
-rw-r--r--storage/maria/ma_recovery.c31
-rw-r--r--storage/maria/ma_sort.c4
-rwxr-xr-xstorage/maria/ma_test_all.sh33
-rwxr-xr-xstorage/maria/ma_test_recovery10
-rw-r--r--storage/maria/ma_test_recovery.expected198
-rw-r--r--storage/maria/maria_chk.c33
-rw-r--r--storage/maria/maria_def.h11
-rw-r--r--storage/maria/maria_read_log.c14
22 files changed, 723 insertions, 470 deletions
diff --git a/include/maria.h b/include/maria.h
index 6e87c93c7d1..9f6672d482c 100644
--- a/include/maria.h
+++ b/include/maria.h
@@ -370,7 +370,7 @@ typedef struct st_maria_sort_param
ulonglong unique[HA_MAX_KEY_SEG+1];
ulonglong notnull[HA_MAX_KEY_SEG+1];
- MARIA_RECORD_POS pos,max_pos,filepos,start_recpos;
+ MARIA_RECORD_POS pos,max_pos,filepos,start_recpos, current_filepos;
uint key, key_length,real_key_length,sortbuff_size;
uint maxbuffers, keys, find_length, sort_keys_length;
my_bool fix_datafile, master;
@@ -392,18 +392,16 @@ typedef struct st_maria_sort_param
/* functions in maria_check */
void maria_chk_init(HA_CHECK *param);
int maria_chk_status(HA_CHECK *param, MARIA_HA *info);
-int maria_chk_del(HA_CHECK *param, register MARIA_HA *info, uint test_flag);
+int maria_chk_del(HA_CHECK *param, MARIA_HA *info, uint test_flag);
int maria_chk_size(HA_CHECK *param, MARIA_HA *info);
int maria_chk_key(HA_CHECK *param, MARIA_HA *info);
int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info, int extend);
-int maria_repair(HA_CHECK *param, register MARIA_HA *info,
- char * name, int rep_quick);
-int maria_sort_index(HA_CHECK *param, register MARIA_HA *info,
- char * name);
-int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
- const char *name, int rep_quick);
+int maria_repair(HA_CHECK *param, MARIA_HA *info, char * name, uint rep_quick);
+int maria_sort_index(HA_CHECK *param, MARIA_HA *info, char * name);
+int maria_repair_by_sort(HA_CHECK *param, MARIA_HA *info,
+ const char *name, uint rep_quick);
int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
- const char *name, int rep_quick);
+ const char *name, uint rep_quick);
int maria_change_to_newfile(const char *filename, const char *old_ext,
const char *new_ext, myf myflags);
void maria_lock_memory(HA_CHECK *param);
diff --git a/mysql-test/r/maria.result b/mysql-test/r/maria.result
index 7fc6ae39224..97f2850dabd 100644
--- a/mysql-test/r/maria.result
+++ b/mysql-test/r/maria.result
@@ -625,7 +625,7 @@ t1 1 a 1 a A NULL NULL NULL YES BTREE disabled
alter table t1 enable keys;
show keys from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
-t1 1 a 1 a A NULL NULL NULL YES BTREE
+t1 1 a 1 a A 1000 NULL NULL YES BTREE
alter table t1 engine=heap;
alter table t1 disable keys;
Warnings:
@@ -1957,12 +1957,12 @@ create table t2 like t1;
insert into t2 select * from t1;
analyze table t2;
Table Op Msg_type Msg_text
-test.t2 analyze status OK
+test.t2 analyze status Table is already up to date
delete from t2;
insert into t2 select * from t1;
analyze table t2;
Table Op Msg_type Msg_text
-test.t2 analyze status OK
+test.t2 analyze status Table is already up to date
drop table t1,t2;
create table t1 (a bigint auto_increment, primary key(a), b char(255), c varchar(20000));
update t1 set b=repeat('a',100) where a between 1 and 100;
diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c
index 0f49dd22bb9..8d74894305a 100644
--- a/mysys/mf_iocache.c
+++ b/mysys/mf_iocache.c
@@ -1834,6 +1834,7 @@ int end_io_cache(IO_CACHE *info)
pthread_mutex_destroy(&info->append_buffer_lock);
#endif
}
+ info->share= 0;
DBUG_RETURN(error);
} /* end_io_cache */
diff --git a/storage/maria/ma_bitmap.c b/storage/maria/ma_bitmap.c
index a896a9670f9..afe63eea33a 100644
--- a/storage/maria/ma_bitmap.c
+++ b/storage/maria/ma_bitmap.c
@@ -124,9 +124,6 @@
#include "maria_def.h"
#include "ma_blockrec.h"
-/* Number of pages to store blob parts */
-#define BLOB_SEGMENT_MIN_SIZE 128
-
#define FULL_HEAD_PAGE 4
#define FULL_TAIL_PAGE 7
@@ -187,7 +184,6 @@ my_bool _ma_bitmap_init(MARIA_SHARE *share, File file)
return 1;
bitmap->file.file= file;
- bitmap->changed= 0;
bitmap->block_size= share->block_size;
/* Size needs to be alligned on 6 */
aligned_bit_blocks= (share->block_size - PAGE_SUFFIX_SIZE) / 6;
@@ -212,18 +208,8 @@ my_bool _ma_bitmap_init(MARIA_SHARE *share, File file)
pthread_mutex_init(&share->bitmap.bitmap_lock, MY_MUTEX_INIT_SLOW);
- /*
- We can't read a page yet, as in some case we don't have an active
- page cache yet.
- Pretend we have a dummy, full and not changed bitmap page in memory.
- */
+ _ma_bitmap_reset_cache(share);
- bitmap->page= ~(ulonglong) 0;
- bitmap->used_size= bitmap->total_size;
- bfill(bitmap->map, share->block_size, 255);
-#ifndef DBUG_OFF
- memcpy(bitmap->map + bitmap->block_size, bitmap->map, bitmap->block_size);
-#endif
if (share->state.first_bitmap_with_space == ~(ulonglong) 0)
{
/* Start scanning for free space from start of file */
@@ -313,6 +299,41 @@ void _ma_bitmap_delete_all(MARIA_SHARE *share)
}
+/**
+ @brief Reset bitmap caches
+
+ @fn _ma_bitmap_reset_cache()
+ @param share Maria share
+
+ @notes
+ This is called after we have swapped file descriptors and we want
+ bitmap to forget all cached information
+*/
+
+void _ma_bitmap_reset_cache(MARIA_SHARE *share)
+{
+ MARIA_FILE_BITMAP *bitmap= &share->bitmap;
+
+ if (bitmap->map) /* If using bitmap */
+ {
+ /* Forget changes in current bitmap page */
+ bitmap->changed= 0;
+
+ /*
+ We can't read a page yet, as in some case we don't have an active
+ page cache yet.
+ Pretend we have a dummy, full and not changed bitmap page in memory.
+ */
+ bitmap->page= ~(ulonglong) 0;
+ bitmap->used_size= bitmap->total_size;
+ bfill(bitmap->map, share->block_size, 255);
+#ifndef DBUG_OFF
+ memcpy(bitmap->map + bitmap->block_size, bitmap->map, bitmap->block_size);
+#endif
+ }
+}
+
+
/*
Return bitmap pattern for the smallest head block that can hold 'size'
@@ -1630,7 +1651,7 @@ my_bool _ma_bitmap_find_new_place(MARIA_HA *info, MARIA_ROW *row,
{
MARIA_SHARE *share= info->s;
my_bool res= 1;
- uint full_page_size, position;
+ uint position;
uint head_length, row_length, rest_length, extents_length;
ulonglong bitmap_page;
DBUG_ENTER("_ma_bitmap_find_new_place");
@@ -1670,9 +1691,8 @@ my_bool _ma_bitmap_find_new_place(MARIA_HA *info, MARIA_ROW *row,
/* The first segment size is stored in 'row_length' */
row_length= find_where_to_split_row(share, row, extents_length, free_size);
- full_page_size= FULL_PAGE_SIZE(share->block_size);
position= 0;
- if (head_length - row_length <= full_page_size)
+ if (head_length - row_length < MAX_TAIL_SIZE(share->block_size))
position= ELEMENTS_RESERVED_FOR_MAIN_PART -2; /* Only head and tail */
use_head(info, page, row_length, position);
rest_length= head_length - row_length;
diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c
index 069d9e95655..f4abbc2c1c5 100644
--- a/storage/maria/ma_blockrec.c
+++ b/storage/maria/ma_blockrec.c
@@ -456,6 +456,7 @@ my_bool _ma_once_end_block_record(MARIA_SHARE *share)
my_bool _ma_init_block_record(MARIA_HA *info)
{
MARIA_ROW *row= &info->cur_row, *new_row= &info->new_row;
+ uint default_extents;
DBUG_ENTER("_ma_init_block_record");
if (!my_multi_malloc(MY_WME,
@@ -490,17 +491,27 @@ my_bool _ma_init_block_record(MARIA_HA *info)
/* Skip over bytes used to store length of field length for logging */
row->field_lengths+= 2;
new_row->field_lengths+= 2;
+
+ /* Reserve some initial space to avoid mallocs during execution */
+ default_extents= (ELEMENTS_RESERVED_FOR_MAIN_PART + 1 +
+ (AVERAGE_BLOB_SIZE /
+ FULL_PAGE_SIZE(info->s->block_size) /
+ BLOB_SEGMENT_MIN_SIZE));
+
if (my_init_dynamic_array(&info->bitmap_blocks,
- sizeof(MARIA_BITMAP_BLOCK),
- ELEMENTS_RESERVED_FOR_MAIN_PART, 16))
+ sizeof(MARIA_BITMAP_BLOCK), default_extents,
+ 64))
goto err;
+ if (!(info->cur_row.extents= my_malloc(default_extents * ROW_EXTENT_SIZE,
+ MYF(MY_WME))))
+ goto err;
+
row->base_length= new_row->base_length= info->s->base_length;
/*
We need to reserve 'EXTRA_LENGTH_FIELDS' number of parts in
null_field_lengths to allow splitting of rows in 'find_where_to_split_row'
*/
-
row->null_field_lengths+= EXTRA_LENGTH_FIELDS;
new_row->null_field_lengths+= EXTRA_LENGTH_FIELDS;
@@ -3697,7 +3708,7 @@ int _ma_read_block_record2(MARIA_HA *info, uchar *record,
column < end_column; column++)
{
uint column_length= column->length;
- if (data >= end_of_data &&
+ if (data + column_length > end_of_data &&
!(data= read_next_extent(info, &extent, &end_of_data)))
goto err;
memcpy(record + column->offset, data, column_length);
@@ -3731,7 +3742,7 @@ int _ma_read_block_record2(MARIA_HA *info, uchar *record,
case FIELD_NORMAL: /* Fixed length field */
case FIELD_SKIP_PRESPACE:
case FIELD_SKIP_ZERO: /* Fixed length field */
- if (data >= end_of_data &&
+ if (data + column->length > end_of_data &&
!(data= read_next_extent(info, &extent, &end_of_data)))
goto err;
memcpy(field_pos, data, column->length);
@@ -4991,6 +5002,7 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
MARIA_PINNED_PAGE page_link;
enum pagecache_page_lock unlock_method;
enum pagecache_page_pin unpin_method;
+ my_off_t end_of_page;
DBUG_ENTER("_ma_apply_redo_insert_row_head_or_tail");
page= page_korr(header);
@@ -5000,8 +5012,12 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
(ulong) ma_recordpos(page, rownr),
(ulong) page, rownr, (uint) data_length));
- if (((page + 1) * info->s->block_size) > info->state->data_file_length)
+ end_of_page= (page + 1) * info->s->block_size;
+ if (end_of_page > info->state->data_file_length)
{
+ DBUG_PRINT("info", ("Enlarging data file from %lu to %lu",
+ (ulong) info->state->data_file_length,
+ (ulong) end_of_page));
/*
New page at end of file. Note that the test above is also positive if
data_file_length is not a multiple of block_size (system crashed while
@@ -5153,11 +5169,7 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
case we extended the file. We could not do it earlier: bitmap code tests
data_file_length to know if it has to create a new page or not.
*/
- {
- my_off_t end_of_page= (page + 1) * info->s->block_size;
- set_if_bigger(info->state->data_file_length, end_of_page);
- }
-
+ set_if_bigger(info->state->data_file_length, end_of_page);
DBUG_RETURN(result);
err:
diff --git a/storage/maria/ma_blockrec.h b/storage/maria/ma_blockrec.h
index a792f8c5db5..01d01fc6c1f 100644
--- a/storage/maria/ma_blockrec.h
+++ b/storage/maria/ma_blockrec.h
@@ -29,8 +29,8 @@
PAGE_SUFFIX_SIZE)
#define BLOCK_RECORD_POINTER_SIZE 6
-#define FULL_PAGE_SIZE(block_size) ((block_size) - LSN_SIZE - PAGE_TYPE_SIZE - \
- PAGE_SUFFIX_SIZE)
+#define FULL_PAGE_SIZE(block_size) ((block_size) - LSN_SIZE - \
+ PAGE_TYPE_SIZE - PAGE_SUFFIX_SIZE)
#define ROW_EXTENT_PAGE_SIZE 5
#define ROW_EXTENT_COUNT_SIZE 2
@@ -40,12 +40,16 @@
#define TAIL_BIT 0x8000 /* Bit in page_count to signify tail */
/* Number of extents reserved MARIA_BITMAP_BLOCKS to store head part */
#define ELEMENTS_RESERVED_FOR_MAIN_PART 4
+/* This is just used to prealloc a dynamic array */
+#define AVERAGE_BLOB_SIZE 1024L*1024L
+/* Number of pages to store continuous blob parts */
+#define BLOB_SEGMENT_MIN_SIZE 128
+
/* Fields before 'row->null_field_lengths' used by find_where_to_split_row */
#define EXTRA_LENGTH_FIELDS 3
/* Size for the different parts in the row header (and head page) */
#define FLAG_SIZE 1
-#define TRANSID_SIZE 6
#define VERPTR_SIZE 7
#define DIR_ENTRY_SIZE 4
#define FIELD_OFFSET_SIZE 2 /* size of pointers to field starts */
@@ -167,6 +171,7 @@ my_bool _ma_compare_block_record(register MARIA_HA *info,
my_bool _ma_bitmap_init(MARIA_SHARE *share, File file);
my_bool _ma_bitmap_end(MARIA_SHARE *share);
my_bool _ma_flush_bitmap(MARIA_SHARE *share);
+void _ma_bitmap_reset_cache(MARIA_SHARE *share);
my_bool _ma_bitmap_find_place(MARIA_HA *info, MARIA_ROW *row,
MARIA_BITMAP_BLOCKS *result_blocks);
my_bool _ma_bitmap_release_unused(MARIA_HA *info, MARIA_BITMAP_BLOCKS *blocks);
diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c
index 37c01954d9b..f30ebebd6e7 100644
--- a/storage/maria/ma_check.c
+++ b/storage/maria/ma_check.c
@@ -87,12 +87,15 @@ static ha_checksum maria_byte_checksum(const uchar *buf, uint length);
static void set_data_file_type(MARIA_SORT_INFO *sort_info, MARIA_SHARE *share);
static void restore_data_file_type(MARIA_SHARE *share);
static void change_data_file_descriptor(MARIA_HA *info, File new_file);
+static void unuse_data_file_descriptor(MARIA_HA *info);
static int _ma_safe_scan_block_record(MARIA_SORT_INFO *sort_info,
MARIA_HA *info, uchar *record);
static void copy_data_file_state(MARIA_STATE_INFO *to,
MARIA_STATE_INFO *from);
static int write_log_record_for_repair(const HA_CHECK *param, MARIA_HA *info);
static void report_keypage_fault(HA_CHECK *param, my_off_t position);
+my_bool create_new_data_handle(MARIA_SORT_PARAM *param, File new_file);
+
void maria_chk_init(HA_CHECK *param)
{
@@ -2031,6 +2034,38 @@ int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info,int extend)
} /* maria_chk_data_link */
+/**
+ @brief Initialize variables for repair
+*/
+
+static void initialize_variables_for_repair(HA_CHECK *param,
+ MARIA_SORT_INFO *sort_info,
+ MARIA_SORT_PARAM *sort_param,
+ MARIA_HA *info,
+ uint rep_quick)
+{
+ bzero((char *) sort_info, sizeof(*sort_info));
+ bzero((char *) sort_param, sizeof(*sort_param));
+
+ param->testflag|= T_REP; /* for easy checking */
+ if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
+ param->testflag|= T_CALC_CHECKSUM;
+ param->glob_crc= 0;
+
+ sort_param->sort_info= sort_info;
+ sort_param->fix_datafile= (my_bool) (! rep_quick);
+ sort_param->calc_checksum= test(param->testflag & T_CALC_CHECKSUM);
+ sort_info->info= sort_info->new_info= info;
+ sort_info->param= param;
+ set_data_file_type(sort_info, info->s);
+ sort_info->org_data_file_type= info->s->data_file_type;
+
+ bzero(&info->rec_cache, sizeof(info->rec_cache));
+ info->rec_cache.file= info->dfile.file;
+ info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
+}
+
+
/*
Recover old table by reading each record and writing all keys
@@ -2054,7 +2089,7 @@ int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info,int extend)
*/
int maria_repair(HA_CHECK *param, register MARIA_HA *info,
- char *name, int rep_quick)
+ char *name, uint rep_quick)
{
int error, got_error= 1;
uint i;
@@ -2071,26 +2106,18 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
MY_SYNC_DIR : 0);
DBUG_ENTER("maria_repair");
- bzero((char *)&sort_info, sizeof(sort_info));
- bzero((char *)&sort_param, sizeof(sort_param));
+ initialize_variables_for_repair(param, &sort_info, &sort_param, info,
+ rep_quick);
start_records=info->state->records;
- new_header_length=(param->testflag & T_UNPACK) ? 0L :
- share->pack.header_length;
+ new_header_length= ((param->testflag & T_UNPACK) ? 0L :
+ share->pack.header_length);
new_file= -1;
- sort_param.sort_info=&sort_info;
- block_record= org_data_file_type == BLOCK_RECORD;
- sort_info.info= sort_info.new_info= info;
- bzero(&info->rec_cache,sizeof(info->rec_cache));
if (!(param->testflag & T_SILENT))
{
printf("- recovering (with keycache) MARIA-table '%s'\n",name);
printf("Data records: %s\n", llstr(info->state->records,llbuff));
}
- param->testflag|=T_REP; /* for easy checking */
-
- if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
- param->testflag|=T_CALC_CHECKSUM;
/*
The physical size of the data file is sometimes used during repair (see
@@ -2121,43 +2148,18 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
new_header_length, "datafile-header"))
goto err;
info->s->state.dellink= HA_OFFSET_ERROR;
- info->rec_cache.file= new_file;
+ info->rec_cache.file= new_file; /* For sort_delete_record */
if (share->data_file_type == BLOCK_RECORD ||
(param->testflag & T_UNPACK))
{
- MARIA_HA *new_info;
- /*
- It's ok for Recovery to have two MARIA_SHARE on the same index file
- because the one below is not transactional
- */
- if (!(sort_info.new_info= maria_open(info->s->open_file_name, O_RDWR,
- HA_OPEN_COPY | HA_OPEN_FOR_REPAIR)))
- goto err;
- new_info= sort_info.new_info;
- change_data_file_descriptor(new_info, new_file);
- maria_lock_database(new_info, F_EXTRA_LCK);
- if ((param->testflag & T_UNPACK) &&
- share->data_file_type == COMPRESSED_RECORD)
- {
- (*new_info->s->once_end)(new_info->s);
- (*new_info->s->end)(new_info);
- restore_data_file_type(new_info->s);
- _ma_setup_functions(new_info->s);
- if ((*new_info->s->once_init)(new_info->s, new_file) ||
- (*new_info->s->init)(new_info))
- goto err;
- }
- _ma_reset_status(sort_info.new_info);
- if (_ma_initialize_data_file(sort_info.new_info->s, new_file))
+ if (create_new_data_handle(&sort_param, new_file))
goto err;
- block_record= 1;
-
- /* Use new virtual functions for key generation */
- info->s->keypos_to_recpos= new_info->s->keypos_to_recpos;
- info->s->recpos_to_keypos= new_info->s->recpos_to_keypos;
+ sort_info.new_info->rec_cache.file= new_file;
}
}
+ block_record= sort_info.new_info->s->data_file_type == BLOCK_RECORD;
+
if (org_data_file_type != BLOCK_RECORD)
{
/* We need a read buffer to read rows in big blocks */
@@ -2170,14 +2172,16 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
{
/* When writing to not block records, we need a write buffer */
if (!rep_quick)
- if (init_io_cache(&info->rec_cache, new_file,
+ {
+ if (init_io_cache(&sort_info.new_info->rec_cache, new_file,
(uint) param->write_buffer_length,
WRITE_CACHE, new_header_length, 1,
- MYF(MY_WME | MY_WAIT_IF_FULL)))
+ MYF(MY_WME | MY_WAIT_IF_FULL) & param->myf_rw))
goto err;
- info->opt_flag|=WRITE_CACHE_USED;
+ sort_info.new_info->opt_flag|=WRITE_CACHE_USED;
+ }
}
- else
+ else if (block_record)
{
scan_inited= 1;
if (maria_scan_init(sort_info.info))
@@ -2193,26 +2197,17 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
goto err;
}
- sort_info.param = param;
sort_param.read_cache=param->read_cache;
sort_param.pos=sort_param.max_pos=share->pack.header_length;
sort_param.filepos=new_header_length;
- param->read_cache.end_of_file=sort_info.filelength=
+ param->read_cache.end_of_file= sort_info.filelength=
my_seek(info->dfile.file, 0L, MY_SEEK_END, MYF(0));
- sort_info.dupp=0;
- sort_param.fix_datafile= (my_bool) (! rep_quick);
sort_param.master=1;
sort_info.max_records= ~(ha_rows) 0;
- set_data_file_type(&sort_info, share);
del=info->state->del;
info->state->records=info->state->del=share->state.split=0;
info->state->empty=0;
- param->glob_crc=0;
- if (param->testflag & T_CALC_CHECKSUM)
- sort_param.calc_checksum= 1;
-
- info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
/*
Clear all keys. Note that all key blocks allocated until now remain
@@ -2235,8 +2230,6 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
maria_lock_memory(param); /* Everything is alloced */
- sort_info.org_data_file_type= info->s->data_file_type;
-
/* Re-create all keys, which are set in key_map. */
while (!(error=sort_get_next_record(&sort_param)))
{
@@ -2248,7 +2241,8 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
if (my_errno != HA_ERR_FOUND_DUPP_KEY)
goto err;
DBUG_DUMP("record",(uchar*) sort_param.record,share->base.pack_reclength);
- _ma_check_print_info(param,"Duplicate key %2d for record at %10s against new record at %10s",
+ _ma_check_print_info(param,
+ "Duplicate key %2d for record at %10s against new record at %10s",
info->errkey+1,
llstr(sort_param.start_recpos,llbuff),
llstr(info->dup_key_pos,llbuff2));
@@ -2279,11 +2273,17 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
}
/* purecov: end */
}
- if (!block_record && _ma_sort_write_record(&sort_param))
- goto err;
+ if (!block_record)
+ {
+ if (_ma_sort_write_record(&sort_param))
+ goto err;
+ /* Filepos is pointer to where next row will be stored */
+ sort_param.current_filepos= sort_param.filepos;
+ }
}
if (error > 0 || maria_write_data_suffix(&sort_info, (my_bool)!rep_quick) ||
- flush_io_cache(&info->rec_cache) || param->read_cache.error < 0)
+ flush_io_cache(&sort_info.new_info->rec_cache) ||
+ param->read_cache.error < 0)
goto err;
if (param->testflag & T_WRITE_LOOP)
@@ -2317,8 +2317,14 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
}
}
+ VOID(end_io_cache(&sort_info.new_info->rec_cache));
+ info->opt_flag&= ~WRITE_CACHE_USED;
+ if (_ma_flush_table_files_after_repair(param, info))
+ goto err;
+
if (!rep_quick)
{
+ sort_info.new_info->state->data_file_length= sort_param.filepos;
if (sort_info.new_info != sort_info.info)
{
MARIA_STATE_INFO save_state= sort_info.new_info->s->state;
@@ -2329,9 +2335,8 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
}
copy_data_file_state(&info->s->state, &save_state);
new_file= -1;
+ sort_info.new_info= info;
}
- else
- info->state->data_file_length= sort_param.filepos;
share->state.version=(ulong) time((time_t*) 0); /* Force reopen */
/* Replace the actual file with the temporary file */
@@ -2376,38 +2381,25 @@ err:
maria_scan_end(sort_info.info);
VOID(end_io_cache(&param->read_cache));
+ VOID(end_io_cache(&sort_info.new_info->rec_cache));
info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
+ sort_info.new_info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
/* this below could fail, shouldn't we detect error? */
- VOID(end_io_cache(&info->rec_cache));
- got_error|= _ma_flush_table_files_after_repair(param, info);
if (got_error)
{
if (! param->error_printed)
_ma_check_print_error(param,"%d for record at pos %s",my_errno,
llstr(sort_param.start_recpos,llbuff));
+ (void) _ma_flush_table_files_after_repair(param, info);
if (sort_info.new_info && sort_info.new_info != sort_info.info)
{
- /**
- @todo ASK_MONTY
- grepping for "dfile.file="
- shows several places (ma_check.c, ma_panic.c, ma_extra.c) where we
- modify dfile.file without modifying share->bitmap.file.file; those
- sound like bugs because the two variables are normally copies of each
- other in BLOCK_RECORD (and in other record formats it does not hurt
- to change the unused share->bitmap.file.file).
- It does matter, because if we close dfile.file, set dfile.file to -1,
- but leave bitmap.file.file to its positive value, maria_close() will
- close a file which it is not allowed to (maybe even a file in another
- engine or mysqld!).
- */
- sort_info.new_info->dfile.file= -1;
+ unuse_data_file_descriptor(sort_info.new_info);
maria_close(sort_info.new_info);
}
if (new_file >= 0)
{
VOID(my_close(new_file,MYF(0)));
VOID(my_delete(param->temp_filename, MYF(MY_WME)));
- info->rec_cache.file=-1; /* don't flush data to new_file, it's closed */
}
maria_mark_crashed_on_repair(info);
}
@@ -2439,7 +2431,7 @@ static int writekeys(MARIA_SORT_PARAM *sort_param)
uchar *key;
MARIA_HA *info= sort_param->sort_info->info;
uchar *buff= sort_param->record;
- my_off_t filepos= sort_param->filepos;
+ my_off_t filepos= sort_param->current_filepos;
DBUG_ENTER("writekeys");
key= info->lastkey+info->s->base.max_key_length;
@@ -2866,7 +2858,7 @@ err:
*/
int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
- const char * name, int rep_quick)
+ const char * name, uint rep_quick)
{
int got_error;
uint i;
@@ -2883,57 +2875,32 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
ulonglong key_map=share->state.key_map;
myf sync_dir= ((share->now_transactional && !share->temporary) ?
MY_SYNC_DIR : 0);
+ my_bool scan_inited= 0;
DBUG_ENTER("maria_repair_by_sort");
- bzero((char*)&sort_info,sizeof(sort_info));
- bzero((char *)&sort_param, sizeof(sort_param));
-
- start_records=info->state->records;
+ start_records= info->state->records;
+ initialize_variables_for_repair(param, &sort_info, &sort_param, info,
+ rep_quick);
got_error=1;
new_file= -1;
org_header_length= share->pack.header_length;
new_header_length= (param->testflag & T_UNPACK) ? 0 : org_header_length;
+ sort_param.filepos= new_header_length;
if (!(param->testflag & T_SILENT))
{
printf("- recovering (with sort) MARIA-table '%s'\n",name);
printf("Data records: %s\n", llstr(start_records,llbuff));
}
- param->testflag|=T_REP; /* for easy checking */
-
- if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
- param->testflag|=T_CALC_CHECKSUM;
+ /* Flushing of keys is done later */
if (_ma_flush_table_files(info, MARIA_FLUSH_DATA | MARIA_FLUSH_INDEX,
- FLUSH_FORCE_WRITE, FLUSH_IGNORE_CHANGED))
- goto err;
-
- if (!(sort_info.key_block=
- alloc_key_blocks(param,
- (uint) param->sort_key_blocks,
- share->base.max_key_block_length)) ||
- init_io_cache(&param->read_cache, info->dfile.file,
- (uint) param->read_buffer_length,
- READ_CACHE, org_header_length, 1, MYF(MY_WME)) ||
- (! rep_quick &&
- init_io_cache(&info->rec_cache, info->dfile.file,
- (uint) param->write_buffer_length,
- WRITE_CACHE,new_header_length,1,
- MYF(MY_WME | MY_WAIT_IF_FULL) & param->myf_rw)))
+ FLUSH_FORCE_WRITE,
+ (param->testflag & T_CREATE_MISSING_KEYS) ?
+ FLUSH_FORCE_WRITE : FLUSH_IGNORE_CHANGED) ||
+ _ma_state_info_write(share, 1|2|4))
goto err;
- sort_info.key_block_end=sort_info.key_block+param->sort_key_blocks;
- info->opt_flag|=WRITE_CACHE_USED;
- info->rec_cache.file= info->dfile.file; /* for sort_delete_record */
- sort_info.org_data_file_type= info->s->data_file_type;
- if (!(sort_param.record=(uchar*) my_malloc((uint) share->base.pack_reclength,
- MYF(0))) ||
- _ma_alloc_buffer(&sort_param.rec_buff, &sort_param.rec_buff_size,
- info->s->base.default_rec_buff_size))
- {
- _ma_check_print_error(param, "Not enough memory for extra record");
- goto err;
- }
if (!rep_quick)
{
/* Get real path for data file */
@@ -2951,21 +2918,58 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
maria_filecopy(param, new_file, info->dfile.file, 0L,
new_header_length, "datafile-header"))
goto err;
- if (param->testflag & T_UNPACK)
- restore_data_file_type(share);
+
share->state.dellink= HA_OFFSET_ERROR;
- info->rec_cache.file=new_file;
+ info->rec_cache.file= new_file; /* For sort_delete_record */
+ if (share->data_file_type == BLOCK_RECORD ||
+ (param->testflag & T_UNPACK))
+ {
+ if (create_new_data_handle(&sort_param, new_file))
+ goto err;
+ sort_info.new_info->rec_cache.file= new_file;
+ }
+ }
+
+ if (!(sort_info.key_block=
+ alloc_key_blocks(param,
+ (uint) param->sort_key_blocks,
+ share->base.max_key_block_length)))
+ goto err;
+ sort_info.key_block_end=sort_info.key_block+param->sort_key_blocks;
+
+ if (info->s->data_file_type != BLOCK_RECORD)
+ {
+ /* We need a read buffer to read rows in big blocks */
+ if (init_io_cache(&param->read_cache, info->dfile.file,
+ (uint) param->read_buffer_length,
+ READ_CACHE, org_header_length, 1, MYF(MY_WME)))
+ goto err;
+ }
+ if (sort_info.new_info->s->data_file_type != BLOCK_RECORD)
+ {
+ /* When writing to not block records, we need a write buffer */
+ if (!rep_quick)
+ {
+ if (init_io_cache(&sort_info.new_info->rec_cache, new_file,
+ (uint) param->write_buffer_length,
+ WRITE_CACHE, new_header_length, 1,
+ MYF(MY_WME | MY_WAIT_IF_FULL) & param->myf_rw))
+ goto err;
+ sort_info.new_info->opt_flag|= WRITE_CACHE_USED;
+ }
+ }
+
+ if (!(sort_param.record=(uchar*) my_malloc((uint) share->base.pack_reclength,
+ MYF(0))) ||
+ _ma_alloc_buffer(&sort_param.rec_buff, &sort_param.rec_buff_size,
+ info->s->base.default_rec_buff_size))
+ {
+ _ma_check_print_error(param, "Not enough memory for extra record");
+ goto err;
}
- info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
if (!(param->testflag & T_CREATE_MISSING_KEYS))
{
- /*
- Flush key cache for this file if we are calling this outside
- maria_chk
- */
- flush_pagecache_blocks(share->pagecache, &share->kfile,
- FLUSH_IGNORE_CHANGED);
/* Clear the pointers to the given rows */
for (i=0 ; i < share->base.keys ; i++)
share->state.key_root[i]= HA_OFFSET_ERROR;
@@ -2973,22 +2977,10 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
info->state->key_file_length=share->base.keystart;
}
else
- {
- if (flush_pagecache_blocks(share->pagecache, &share->kfile,
- FLUSH_FORCE_WRITE))
- goto err;
key_map= ~key_map; /* Create the missing keys */
- }
-
- sort_info.info= sort_info.new_info= info;
- sort_info.param= param;
- set_data_file_type(&sort_info, share);
- sort_param.filepos=new_header_length;
- sort_info.dupp=0;
- sort_info.buff=0;
- param->read_cache.end_of_file=sort_info.filelength=
- my_seek(param->read_cache.file,0L,MY_SEEK_END,MYF(0));
+ param->read_cache.end_of_file= sort_info.filelength=
+ my_seek(info->dfile.file, 0L, MY_SEEK_END, MYF(0));
sort_param.wordlist=NULL;
init_alloc_root(&sort_param.wordroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0);
@@ -3005,14 +2997,9 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
sort_param.key_cmp=sort_key_cmp;
sort_param.lock_in_memory=maria_lock_memory;
sort_param.tmpdir=param->tmpdir;
- sort_param.sort_info=&sort_info;
- sort_param.fix_datafile= (my_bool) (! rep_quick);
sort_param.master =1;
del=info->state->del;
- param->glob_crc=0;
- if (param->testflag & T_CALC_CHECKSUM)
- sort_param.calc_checksum= 1;
rec_per_key_part= param->new_rec_per_key_part;
for (sort_param.key=0 ; sort_param.key < share->base.keys ;
@@ -3091,6 +3078,12 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
sort_param.key_write= sort_key_write;
}
+ if (sort_info.new_info->s->data_file_type == BLOCK_RECORD)
+ {
+ scan_inited= 1;
+ if (maria_scan_init(sort_info.info))
+ goto err;
+ }
if (_ma_create_index_by_sort(&sort_param,
(my_bool) (!(param->testflag & T_VERBOSE)),
(size_t) param->sort_buffer_length))
@@ -3098,26 +3091,36 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
param->retry_repair=1;
goto err;
}
+ if (scan_inited)
+ {
+ scan_inited= 0;
+ maria_scan_end(sort_info.info);
+ }
+
/* No need to calculate checksum again. */
sort_param.calc_checksum= 0;
free_root(&sort_param.wordroot, MYF(0));
/* Set for next loop */
- sort_info.max_records= (ha_rows) info->state->records;
+ sort_info.max_records= (ha_rows) sort_info.new_info->state->records;
if (param->testflag & T_STATISTICS)
maria_update_key_parts(sort_param.keyinfo, rec_per_key_part,
sort_param.unique,
- param->stats_method == MI_STATS_METHOD_IGNORE_NULLS?
- sort_param.notnull : NULL,
+ (param->stats_method ==
+ MI_STATS_METHOD_IGNORE_NULLS ?
+ sort_param.notnull : NULL),
(ulonglong) info->state->records);
maria_set_key_active(share->state.key_map, sort_param.key);
if (sort_param.fix_datafile)
{
param->read_cache.end_of_file=sort_param.filepos;
- if (maria_write_data_suffix(&sort_info,1) || end_io_cache(&info->rec_cache))
+ if (maria_write_data_suffix(&sort_info,1) ||
+ end_io_cache(&sort_info.new_info->rec_cache))
goto err;
+ sort_info.new_info->opt_flag&= ~WRITE_CACHE_USED;
+
if (param->testflag & T_SAFE_REPAIR)
{
/* Don't repair if we loosed more than one row */
@@ -3127,15 +3130,48 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
goto err;
}
}
- share->state.state.data_file_length = info->state->data_file_length=
- sort_param.filepos;
- /* Only whole records */
- share->state.version=(ulong) time((time_t*) 0);
- my_close(info->dfile.file, MYF(0));
- info->dfile.file= new_file;
- share->data_file_type= sort_info.new_data_file_type;
- org_header_length= (ulong) new_header_length;
+
+ if (_ma_flush_table_files_after_repair(param, info))
+ goto err;
+
+ sort_info.new_info->state->data_file_length= sort_param.filepos;
+ if (sort_info.new_info != sort_info.info)
+ {
+ MARIA_STATE_INFO save_state= sort_info.new_info->s->state;
+ if (maria_close(sort_info.new_info))
+ {
+ _ma_check_print_error(param, "Got error %d on close", my_errno);
+ goto err;
+ }
+ copy_data_file_state(&info->s->state, &save_state);
+ new_file= -1;
+ sort_info.new_info= info;
+ }
+
+ share->state.version=(ulong) time((time_t*) 0); /* Force reopen */
+
+ /* Replace the actual file with the temporary file */
+ if (new_file >= 0)
+ {
+ my_close(new_file, MYF(MY_WME));
+ new_file= -1;
+ }
+ change_data_file_descriptor(info, -1);
+ if (maria_change_to_newfile(share->data_file_name,MARIA_NAME_DEXT,
+ DATA_TMP_EXT,
+ (param->testflag & T_BACKUP_DATA ?
+ MYF(MY_REDEL_MAKE_BACKUP): MYF(0)) |
+ sync_dir) ||
+ _ma_open_datafile(info, share, -1))
+ {
+ goto err;
+ }
+ if (param->testflag & T_UNPACK)
+ restore_data_file_type(share);
+
+ org_header_length= share->pack.header_length;
sort_info.org_data_file_type= info->s->data_file_type;
+ sort_info.filelength= info->state->data_file_length;
sort_param.fix_datafile=0;
}
else
@@ -3177,6 +3213,7 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
"Can't change size of datafile, error: %d",
my_errno);
}
+
if (param->testflag & T_CALC_CHECKSUM)
info->state->checksum=param->glob_crc;
@@ -3200,41 +3237,40 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
memcpy( &share->state.state, info->state, sizeof(*info->state));
err:
- VOID(end_io_cache(&info->rec_cache));
+ if (scan_inited)
+ maria_scan_end(sort_info.info);
+
+ VOID(end_io_cache(&sort_info.new_info->rec_cache));
VOID(end_io_cache(&param->read_cache));
info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
- got_error|= _ma_flush_table_files_after_repair(param, info);
- if (!got_error)
- {
- /* Replace the actual file with the temporary file */
- if (new_file >= 0)
- {
- my_close(new_file,MYF(0));
- info->dfile.file= new_file= -1;
- if (maria_change_to_newfile(share->data_file_name,MARIA_NAME_DEXT,
- DATA_TMP_EXT,
- MYF((param->testflag & T_BACKUP_DATA ?
- MY_REDEL_MAKE_BACKUP : 0) |
- sync_dir)) ||
- _ma_open_datafile(info,share,-1))
- got_error=1;
- }
- }
+ sort_info.new_info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
if (got_error)
{
if (! param->error_printed)
_ma_check_print_error(param,"%d when fixing table",my_errno);
+ (void) _ma_flush_table_files_after_repair(param, info);
+ if (sort_info.new_info && sort_info.new_info != sort_info.info)
+ {
+ unuse_data_file_descriptor(sort_info.new_info);
+ maria_close(sort_info.new_info);
+ }
if (new_file >= 0)
{
VOID(my_close(new_file,MYF(0)));
VOID(my_delete(param->temp_filename, MYF(MY_WME)));
- if (info->dfile.file == new_file)
- info->dfile.file= -1;
}
maria_mark_crashed_on_repair(info);
}
- else if (key_map == share->state.key_map)
- share->state.changed&= ~STATE_NOT_OPTIMIZED_KEYS;
+ else
+ {
+ if (key_map == share->state.key_map)
+ share->state.changed&= ~STATE_NOT_OPTIMIZED_KEYS;
+ /*
+ Now that we have flushed and forced everything, we can bump
+ create_rename_lsn:
+ */
+ write_log_record_for_repair(param, info);
+ }
share->state.changed|= STATE_NOT_SORTED_PAGES;
share->state.changed&= ~STATE_NOT_OPTIMIZED_ROWS;
@@ -3243,8 +3279,6 @@ err:
my_free((uchar*) sort_info.key_block,MYF(MY_ALLOW_ZERO_PTR));
my_free((uchar*) sort_info.ft_buf, MYF(MY_ALLOW_ZERO_PTR));
my_free(sort_info.buff,MYF(MY_ALLOW_ZERO_PTR));
- if (!got_error && (param->testflag & T_UNPACK))
- restore_data_file_type(share);
DBUG_RETURN(got_error);
}
@@ -3291,7 +3325,7 @@ err:
*/
int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
- const char * name, int rep_quick)
+ const char * name, uint rep_quick)
{
#ifndef THREAD
return maria_repair_by_sort(param, info, name, rep_quick);
@@ -3302,7 +3336,7 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
ha_rows start_records;
my_off_t new_header_length,del;
File new_file;
- MARIA_SORT_PARAM *sort_param=0;
+ MARIA_SORT_PARAM *sort_param=0, tmp_sort_param;
MARIA_SHARE *share=info->s;
double *rec_per_key_part;
HA_KEYSEG *keyseg;
@@ -3316,6 +3350,9 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
MY_SYNC_DIR : 0;
DBUG_ENTER("maria_repair_parallel");
+ initialize_variables_for_repair(param, &sort_info, &tmp_sort_param, info,
+ rep_quick);
+
start_records=info->state->records;
got_error=1;
new_file= -1;
@@ -3326,7 +3363,6 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
printf("- parallel recovering (with sort) MARIA-table '%s'\n",name);
printf("Data records: %s\n", llstr(start_records,llbuff));
}
- param->testflag|=T_REP; /* for easy checking */
if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
param->testflag|=T_CALC_CHECKSUM;
@@ -3364,13 +3400,11 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
}
*/
DBUG_PRINT("info", ("is quick repair: %d", rep_quick));
- bzero((char*)&sort_info,sizeof(sort_info));
+
/* Initialize pthread structures before goto err. */
pthread_mutex_init(&sort_info.mutex, MY_MUTEX_INIT_FAST);
pthread_cond_init(&sort_info.cond, 0);
- sort_info.org_data_file_type= info->s->data_file_type;
-
if (!(sort_info.key_block=
alloc_key_blocks(param, (uint) param->sort_key_blocks,
share->base.max_key_block_length)) ||
@@ -3438,14 +3472,8 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
key_map= ~key_map; /* Create the missing keys */
}
- sort_info.info= sort_info.new_info= info;
- sort_info.param= param;
-
- set_data_file_type(&sort_info, share);
- sort_info.dupp=0;
- sort_info.buff=0;
- param->read_cache.end_of_file=sort_info.filelength=
- my_seek(param->read_cache.file,0L,MY_SEEK_END,MYF(0));
+ param->read_cache.end_of_file= sort_info.filelength=
+ my_seek(info->dfile.file, 0L, MY_SEEK_END, MYF(0));
if (sort_info.org_data_file_type == DYNAMIC_RECORD)
rec_length=max(share->base.min_pack_length+1,share->base.min_block_length);
@@ -3470,7 +3498,6 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
(ha_rows) (sort_info.filelength/rec_length+1));
del=info->state->del;
- param->glob_crc=0;
if (!(sort_param=(MARIA_SORT_PARAM *)
my_malloc((uint) share->base.keys *
@@ -3722,9 +3749,10 @@ err:
the share by remove_io_thread() or it was not yet started (if the
error happend before creating the thread).
*/
- VOID(end_io_cache(&info->rec_cache));
+ VOID(end_io_cache(&sort_info.new_info->rec_cache));
VOID(end_io_cache(&param->read_cache));
info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
+ sort_info.new_info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
/*
Destroy the new data cache in case of non-quick repair. All slave
threads did either detach from the share by remove_io_thread()
@@ -3799,15 +3827,18 @@ static int sort_key_read(MARIA_SORT_PARAM *sort_param, uchar *key)
sort_param->key+1);
DBUG_RETURN(1);
}
+ if (_ma_sort_write_record(sort_param))
+ DBUG_RETURN(1);
+
sort_param->real_key_length=
(info->s->rec_reflength+
_ma_make_key(info, sort_param->key, key,
- sort_param->record, sort_param->filepos));
+ sort_param->record, sort_param->current_filepos));
#ifdef HAVE_purify
bzero(key+sort_param->real_key_length,
(sort_param->key_length-sort_param->real_key_length));
#endif
- DBUG_RETURN(_ma_sort_write_record(sort_param));
+ DBUG_RETURN(0);
} /* sort_key_read */
@@ -3826,13 +3857,14 @@ static int sort_maria_ft_key_read(MARIA_SORT_PARAM *sort_param, uchar *key)
free_root(&sort_param->wordroot, MYF(MY_MARK_BLOCKS_FREE));
if ((error=sort_get_next_record(sort_param)))
DBUG_RETURN(error);
+ if ((error= _ma_sort_write_record(sort_param)))
+ DBUG_RETURN(error);
if (!(wptr= _ma_ft_parserecord(info,sort_param->key,sort_param->record,
&sort_param->wordroot)))
DBUG_RETURN(1);
if (wptr->pos)
break;
- error=_ma_sort_write_record(sort_param);
}
sort_param->wordptr=sort_param->wordlist=wptr;
}
@@ -3845,7 +3877,7 @@ static int sort_maria_ft_key_read(MARIA_SORT_PARAM *sort_param, uchar *key)
sort_param->real_key_length=(info->s->rec_reflength+
_ma_ft_make_key(info, sort_param->key,
key, wptr++,
- sort_param->filepos));
+ sort_param->current_filepos));
#ifdef HAVE_purify
if (sort_param->key_length > sort_param->real_key_length)
bzero(key+sort_param->real_key_length,
@@ -3855,7 +3887,6 @@ static int sort_maria_ft_key_read(MARIA_SORT_PARAM *sort_param, uchar *key)
{
free_root(&sort_param->wordroot, MYF(MY_MARK_BLOCKS_FREE));
sort_param->wordlist=0;
- error=_ma_sort_write_record(sort_param);
}
else
sort_param->wordptr=(void*)wptr;
@@ -3891,8 +3922,9 @@ static int sort_maria_ft_key_read(MARIA_SORT_PARAM *sort_param, uchar *key)
RETURN
-1 end of file
0 ok
- sort_param->filepos points to record position.
+ sort_param->current_filepos points to record position.
sort_param->record contains record
+ sort_param->max_pos contains position to last byte read
> 0 error
*/
@@ -3957,12 +3989,13 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
info->cur_row.checksum= checksum;
param->glob_crc+= checksum;
}
- sort_param->start_recpos= sort_param->filepos= info->cur_row.lastpos;
+ sort_param->start_recpos= sort_param->current_filepos=
+ info->cur_row.lastpos;
DBUG_RETURN(0);
}
if (flag == HA_ERR_END_OF_FILE)
{
- sort_param->max_pos= sort_info->filelength;
+ sort_param->max_pos= info->state->data_file_length;
DBUG_RETURN(-1);
}
/* Retry only if wrong record, not if disk error */
@@ -3986,7 +4019,7 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
sort_param->start_recpos=sort_param->pos;
if (!sort_param->fix_datafile)
{
- sort_param->filepos=sort_param->pos;
+ sort_param->current_filepos= sort_param->pos;
if (sort_param->master)
share->state.split++;
}
@@ -4136,7 +4169,8 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
if (!searching)
_ma_check_print_info(param,
"Found block with impossible length %u at %s; Skipped",
- block_info.block_len+ (uint) (block_info.filepos-pos),
+ block_info.block_len+
+ (uint) (block_info.filepos-pos),
llstr(pos,llbuff));
if (found_record)
goto try_next;
@@ -4176,7 +4210,7 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
sort_param->find_length=left_length=block_info.rec_len;
sort_param->start_recpos=pos;
if (!sort_param->fix_datafile)
- sort_param->filepos=sort_param->start_recpos;
+ sort_param->current_filepos= sort_param->start_recpos;
if (sort_param->fix_datafile && (param->testflag & T_EXTEND))
sort_param->pos=block_info.filepos+1;
else
@@ -4348,6 +4382,10 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
llstr(sort_param->pos,llbuff));
continue;
}
+#ifdef HAVE_purify
+ bzero(sort_param->rec_buff + block_info.rec_len,
+ info->s->base.extra_rec_buff_size);
+#endif
if (_ma_pack_rec_unpack(info, &sort_param->bit_buff, sort_param->record,
sort_param->rec_buff, block_info.rec_len))
{
@@ -4358,12 +4396,12 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
}
if (!sort_param->fix_datafile)
{
- sort_param->filepos=sort_param->pos;
+ sort_param->current_filepos= sort_param->pos;
if (sort_param->master)
share->state.split++;
}
- sort_param->max_pos=(sort_param->pos=block_info.filepos+
- block_info.rec_len);
+ sort_param->max_pos= (sort_param->pos=block_info.filepos+
+ block_info.rec_len);
info->packed_length=block_info.rec_len;
if (sort_param->calc_checksum)
@@ -4380,19 +4418,22 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
}
-/*
- Write record to new file.
+/**
+ @brief Write record to new file.
- SYNOPSIS
- _ma_sort_write_record()
- sort_param Sort parameters.
+ @fn _ma_sort_write_record()
+ @param sort_param Sort parameters.
- NOTE
- This is only called by a master thread if parallel repair is used.
+ @note
+ This is only called by a master thread if parallel repair is used.
- RETURN
- 0 OK
- 1 Error
+ @return
+ @retval 0 OK
+ sort_param->current_filepos points to inserted record for
+ block_records and to the place for the next record for
+ other row types.
+ sort_param->filepos points to end of file
+ @retval 1 Error
*/
int _ma_sort_write_record(MARIA_SORT_PARAM *sort_param)
@@ -4410,13 +4451,15 @@ int _ma_sort_write_record(MARIA_SORT_PARAM *sort_param)
if (sort_param->fix_datafile)
{
+ sort_param->current_filepos= sort_param->filepos;
switch (sort_info->new_data_file_type) {
case BLOCK_RECORD:
- if ((sort_param->filepos= (*share->write_record_init)(info,
- sort_param->
- record)) ==
+ if ((sort_param->current_filepos=
+ (*share->write_record_init)(info, sort_param->record)) ==
HA_OFFSET_ERROR)
DBUG_RETURN(1);
+ /* Pointer to end of file */
+ sort_param->filepos= info->state->data_file_length;
break;
case STATIC_RECORD:
if (my_b_write(&info->rec_cache,sort_param->record,
@@ -4820,7 +4863,7 @@ static int sort_insert_key(MARIA_SORT_PARAM *sort_param,
} /* sort_insert_key */
- /* Delete record when we found a duplicated key */
+/* Delete record when we found a duplicated key */
static int sort_delete_record(MARIA_SORT_PARAM *sort_param)
{
@@ -4829,57 +4872,61 @@ static int sort_delete_record(MARIA_SORT_PARAM *sort_param)
uchar *key;
MARIA_SORT_INFO *sort_info=sort_param->sort_info;
HA_CHECK *param=sort_info->param;
- MARIA_HA *info=sort_info->info;
+ MARIA_HA *row_info= sort_info->new_info, *key_info= sort_info->info;
DBUG_ENTER("sort_delete_record");
if ((param->testflag & (T_FORCE_UNIQUENESS|T_QUICK)) == T_QUICK)
{
_ma_check_print_error(param,
- "Quick-recover aborted; Run recovery without switch -q or with switch -qq");
+ "Quick-recover aborted; Run recovery without switch -q or with "
+ "switch -qq");
DBUG_RETURN(1);
}
- if (info->s->options & HA_OPTION_COMPRESS_RECORD)
+ if (key_info->s->options & HA_OPTION_COMPRESS_RECORD)
{
_ma_check_print_error(param,
- "Recover aborted; Can't run standard recovery on compressed tables with errors in data-file. Use switch 'maria_chk --safe-recover' to fix it\n",stderr);;
+ "Recover aborted; Can't run standard recovery on compressed tables "
+ "with errors in data-file. Use 'maria_chk --safe-recover' "
+ "to fix it",stderr);;
DBUG_RETURN(1);
}
- old_file= info->dfile.file;
- info->dfile.file= info->rec_cache.file;
+ old_file= row_info->dfile.file;
+ /* This only affects static and dynamic row formats */
+ row_info->dfile.file= row_info->rec_cache.file;
if (sort_info->current_key)
{
- key= info->lastkey+info->s->base.max_key_length;
- if ((error=(*info->s->read_record)(info,sort_param->record,
- info->cur_row.lastpos)) &&
+ key= key_info->lastkey + key_info->s->base.max_key_length;
+ if ((error=(*row_info->s->read_record)(row_info, sort_param->record,
+ key_info->cur_row.lastpos)) &&
error != HA_ERR_RECORD_DELETED)
{
_ma_check_print_error(param,"Can't read record to be removed");
- info->dfile.file= old_file;
+ row_info->dfile.file= old_file;
DBUG_RETURN(1);
}
for (i=0 ; i < sort_info->current_key ; i++)
{
- uint key_length= _ma_make_key(info, i, key, sort_param->record,
- info->cur_row.lastpos);
- if (_ma_ck_delete(info, i, key, key_length))
+ uint key_length= _ma_make_key(key_info, i, key, sort_param->record,
+ key_info->cur_row.lastpos);
+ if (_ma_ck_delete(key_info, i, key, key_length))
{
_ma_check_print_error(param,
"Can't delete key %d from record to be removed",
i+1);
- info->dfile.file= old_file;
+ row_info->dfile.file= old_file;
DBUG_RETURN(1);
}
}
if (sort_param->calc_checksum)
- param->glob_crc-=(*info->s->calc_check_checksum)(info,
- sort_param->record);
+ param->glob_crc-=(*key_info->s->calc_check_checksum)(key_info,
+ sort_param->record);
}
- error= (flush_io_cache(&info->rec_cache) ||
- (*info->s->delete_record)(info, sort_param->record));
- info->dfile.file= old_file; /* restore actual value */
- info->state->records--;
+ error= (flush_io_cache(&row_info->rec_cache) ||
+ (*row_info->s->delete_record)(row_info, sort_param->record));
+ row_info->dfile.file= old_file; /* restore actual value */
+ row_info->state->records--;
DBUG_RETURN(error);
} /* sort_delete_record */
@@ -5145,7 +5192,7 @@ int maria_recreate_table(HA_CHECK *param, MARIA_HA **org_info, char *filename)
(*org_info)->state->empty=info.state->empty;
(*org_info)->state->data_file_length=info.state->data_file_length;
if (maria_update_state_info(param,*org_info,UPDATE_TIME | UPDATE_STAT |
- UPDATE_OPEN_COUNT))
+ UPDATE_OPEN_COUNT))
goto end;
error=0;
end:
@@ -5184,6 +5231,7 @@ int maria_write_data_suffix(MARIA_SORT_INFO *sort_info, my_bool fix_datafile)
int maria_update_state_info(HA_CHECK *param, MARIA_HA *info,uint update)
{
MARIA_SHARE *share=info->s;
+ DBUG_ENTER("maria_update_state_info");
if (update & UPDATE_OPEN_COUNT)
{
@@ -5233,25 +5281,25 @@ int maria_update_state_info(HA_CHECK *param, MARIA_HA *info,uint update)
share->w_locks=w_locks;
share->tot_locks=r_locks+w_locks;
if (!error)
- return 0;
+ DBUG_RETURN(0);
}
err:
_ma_check_print_error(param,"%d when updating keyfile",my_errno);
- return 1;
+ DBUG_RETURN(1);
}
- /*
- Update auto increment value for a table
- When setting the 'repair_only' flag we only want to change the
- old auto_increment value if its wrong (smaller than some given key).
- The reason is that we shouldn't change the auto_increment value
- for a table without good reason when only doing a repair; If the
- user have inserted and deleted rows, the auto_increment value
- may be bigger than the biggest current row and this is ok.
-
- If repair_only is not set, we will update the flag to the value in
- param->auto_increment is bigger than the biggest key.
- */
+/*
+ Update auto increment value for a table
+ When setting the 'repair_only' flag we only want to change the
+ old auto_increment value if its wrong (smaller than some given key).
+ The reason is that we shouldn't change the auto_increment value
+ for a table without good reason when only doing a repair; If the
+ user have inserted and deleted rows, the auto_increment value
+ may be bigger than the biggest current row and this is ok.
+
+ If repair_only is not set, we will update the flag to the value in
+ param->auto_increment is bigger than the biggest key.
+*/
void _ma_update_auto_increment_key(HA_CHECK *param, MARIA_HA *info,
my_bool repair_only)
@@ -5462,7 +5510,7 @@ void maria_disable_non_unique_index(MARIA_HA *info, ha_rows rows)
*/
my_bool maria_test_if_sort_rep(MARIA_HA *info, ha_rows rows,
- ulonglong key_map, my_bool force)
+ ulonglong key_map, my_bool force)
{
MARIA_SHARE *share=info->s;
MARIA_KEYDEF *key=share->keyinfo;
@@ -5474,9 +5522,6 @@ my_bool maria_test_if_sort_rep(MARIA_HA *info, ha_rows rows,
*/
if (! maria_is_any_key_active(key_map))
return FALSE; /* Can't use sort */
- /* QQ: Remove this when maria_repair_by_sort() works with block format */
- if (info->s->data_file_type == BLOCK_RECORD)
- return FALSE;
for (i=0 ; i < share->base.keys ; i++,key++)
{
if (!force && maria_too_big_key_for_sort(key,rows))
@@ -5486,6 +5531,53 @@ my_bool maria_test_if_sort_rep(MARIA_HA *info, ha_rows rows,
}
+/**
+ @brief Create a new handle for manipulation the new record file
+
+ @note
+ It's ok for Recovery to have two MARIA_SHARE on the same index file
+ because the one we create here is not transactional
+*/
+
+my_bool create_new_data_handle(MARIA_SORT_PARAM *param, File new_file)
+{
+
+ MARIA_SORT_INFO *sort_info= param->sort_info;
+ MARIA_HA *info= sort_info->info;
+ MARIA_HA *new_info;
+ DBUG_ENTER("create_new_data_handle");
+
+ if (!(sort_info->new_info= maria_open(info->s->open_file_name, O_RDWR,
+ HA_OPEN_COPY | HA_OPEN_FOR_REPAIR)))
+ DBUG_RETURN(1);
+
+ new_info= sort_info->new_info;
+ change_data_file_descriptor(new_info, new_file);
+ maria_lock_database(new_info, F_EXTRA_LCK);
+ if ((sort_info->param->testflag & T_UNPACK) &&
+ info->s->data_file_type == COMPRESSED_RECORD)
+ {
+ (*new_info->s->once_end)(new_info->s);
+ (*new_info->s->end)(new_info);
+ restore_data_file_type(new_info->s);
+ _ma_setup_functions(new_info->s);
+ if ((*new_info->s->once_init)(new_info->s, new_file) ||
+ (*new_info->s->init)(new_info))
+ DBUG_RETURN(1);
+ }
+ _ma_reset_status(new_info);
+ if (_ma_initialize_data_file(new_info->s, new_file))
+ DBUG_RETURN(1);
+
+ param->filepos= new_info->state->data_file_length;
+
+ /* Use new virtual functions for key generation */
+ info->s->keypos_to_recpos= new_info->s->keypos_to_recpos;
+ info->s->recpos_to_keypos= new_info->s->recpos_to_keypos;
+ DBUG_RETURN(0);
+}
+
+
static void
set_data_file_type(MARIA_SORT_INFO *sort_info, MARIA_SHARE *share)
{
@@ -5525,6 +5617,22 @@ static void change_data_file_descriptor(MARIA_HA *info, File new_file)
{
my_close(info->dfile.file, MYF(MY_WME));
info->dfile.file= info->s->bitmap.file.file= new_file;
+ _ma_bitmap_reset_cache(info->s);
+}
+
+
+/**
+ @brief Mark the data file to not be used
+
+ @note
+ This is used in repair when we want to ensure the handler will not
+ write anything to the data file anymore
+*/
+
+static void unuse_data_file_descriptor(MARIA_HA *info)
+{
+ info->dfile.file= info->s->bitmap.file.file= -1;
+ _ma_bitmap_reset_cache(info->s);
}
@@ -5701,8 +5809,12 @@ static int write_log_record_for_repair(const HA_CHECK *param, MARIA_HA *info)
{
MARIA_SHARE *share= info->s;
/* in case this is maria_chk or recovery... */
- if (translog_inited && !maria_in_recovery)
+ if (translog_inited && !maria_in_recovery &&
+ info->s->base.born_transactional)
{
+ my_bool now_transactional= info->s->now_transactional;
+ info->s->now_transactional= 1;
+
/*
For now this record is only informative. It could serve when applying
logs to a backup, but that needs more thought. Assume table became
@@ -5745,6 +5857,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;
}
return 0;
}
diff --git a/storage/maria/ma_close.c b/storage/maria/ma_close.c
index 720a3b53dba..70a6ef9bf35 100644
--- a/storage/maria/ma_close.c
+++ b/storage/maria/ma_close.c
@@ -86,8 +86,7 @@ int maria_close(register MARIA_HA *info)
may be using the file at this point
IF using --external-locking, which does not apply to Maria.
*/
- if (share->mode != O_RDONLY &&
- ((share->changed && share->base.born_transactional) ||
+ if (((share->changed && share->base.born_transactional) ||
maria_is_crashed(info)))
{
/*
diff --git a/storage/maria/ma_key_recover.c b/storage/maria/ma_key_recover.c
index af6830564b0..ed9c785439b 100644
--- a/storage/maria/ma_key_recover.c
+++ b/storage/maria/ma_key_recover.c
@@ -73,7 +73,8 @@ my_bool _ma_write_clr(MARIA_HA *info, LSN undo_lsn,
LSN *res_lsn, void *extra_msg)
{
uchar log_data[LSN_STORE_SIZE + FILEID_STORE_SIZE + CLR_TYPE_STORE_SIZE +
- HA_CHECKSUM_STORE_SIZE];
+ HA_CHECKSUM_STORE_SIZE+ KEY_NR_STORE_SIZE + PAGE_STORE_SIZE];
+ uchar *log_pos;
LEX_STRING log_array[TRANSLOG_INTERNAL_PARTS + 1];
struct st_msg_to_write_hook_for_clr_end msg;
my_bool res;
@@ -81,10 +82,8 @@ my_bool _ma_write_clr(MARIA_HA *info, LSN undo_lsn,
/* undo_lsn must be first for compression to work */
lsn_store(log_data, undo_lsn);
- clr_type_store(log_data + LSN_STORE_SIZE + FILEID_STORE_SIZE,
- undo_type);
- log_array[TRANSLOG_INTERNAL_PARTS + 0].length=
- sizeof(log_data) - HA_CHECKSUM_STORE_SIZE;
+ clr_type_store(log_data + LSN_STORE_SIZE + FILEID_STORE_SIZE, undo_type);
+ log_pos= log_data + LSN_STORE_SIZE + FILEID_STORE_SIZE + CLR_TYPE_STORE_SIZE;
/* Extra_msg is handled in write_hook_for_clr_end() */
msg.undone_record_type= undo_type;
@@ -95,11 +94,24 @@ my_bool _ma_write_clr(MARIA_HA *info, LSN undo_lsn,
if (store_checksum)
{
msg.checksum_delta= checksum;
- ha_checksum_store(log_data + LSN_STORE_SIZE + FILEID_STORE_SIZE +
- CLR_TYPE_STORE_SIZE, checksum);
- log_array[TRANSLOG_INTERNAL_PARTS + 0].length= sizeof(log_data);
+ ha_checksum_store(log_pos, checksum);
+ log_pos+= HA_CHECKSUM_STORE_SIZE;
}
+ else if (undo_type == LOGREC_UNDO_KEY_INSERT_WITH_ROOT ||
+ undo_type == LOGREC_UNDO_KEY_DELETE_WITH_ROOT)
+ {
+ /* Key root changed. Store new key root */
+ struct st_msg_to_write_hook_for_undo_key *undo_msg= extra_msg;
+ ulonglong page;
+ key_nr_store(log_pos, undo_msg->keynr);
+ page= (undo_msg->value == HA_OFFSET_ERROR ? IMPOSSIBLE_PAGE_NO :
+ undo_msg->value / info->s->block_size);
+ page_store(log_pos + KEY_NR_STORE_SIZE, page);
+ log_pos+= KEY_NR_STORE_SIZE + PAGE_STORE_SIZE;
+ }
+
log_array[TRANSLOG_INTERNAL_PARTS + 0].str= (char*) log_data;
+ log_array[TRANSLOG_INTERNAL_PARTS + 0].length= (uint) (log_pos - log_data);
res= translog_write_record(res_lsn, LOGREC_CLR_END,
info->trn, info, log_array[TRANSLOG_INTERNAL_PARTS
@@ -141,8 +153,8 @@ my_bool write_hook_for_clr_end(enum translog_record_type type
case LOGREC_UNDO_ROW_UPDATE:
share->state.state.checksum+= msg->checksum_delta;
break;
- case LOGREC_UNDO_KEY_INSERT:
- case LOGREC_UNDO_KEY_DELETE:
+ case LOGREC_UNDO_KEY_INSERT_WITH_ROOT:
+ case LOGREC_UNDO_KEY_DELETE_WITH_ROOT:
{
/* Update key root */
struct st_msg_to_write_hook_for_undo_key *extra_msg=
@@ -150,6 +162,9 @@ my_bool write_hook_for_clr_end(enum translog_record_type type
*extra_msg->root= extra_msg->value;
break;
}
+ case LOGREC_UNDO_KEY_INSERT:
+ case LOGREC_UNDO_KEY_DELETE:
+ break;
default:
DBUG_ASSERT(0);
}
@@ -812,9 +827,11 @@ my_bool _ma_apply_undo_key_insert(MARIA_HA *info, LSN undo_lsn,
msg.root= &share->state.key_root[keynr];
msg.value= new_root;
+ msg.keynr= keynr;
- if (_ma_write_clr(info, undo_lsn, LOGREC_UNDO_KEY_INSERT, 1, 0, &lsn,
- (void*) &msg))
+ if (_ma_write_clr(info, undo_lsn, *msg.root == msg.value ?
+ LOGREC_UNDO_KEY_INSERT : LOGREC_UNDO_KEY_INSERT_WITH_ROOT,
+ 0, 0, &lsn, (void*) &msg))
res= 1;
_ma_unpin_all_pages_and_finalize_row(info, lsn);
@@ -855,7 +872,11 @@ my_bool _ma_apply_undo_key_delete(MARIA_HA *info, LSN undo_lsn,
msg.root= &share->state.key_root[keynr];
msg.value= new_root;
- if (_ma_write_clr(info, undo_lsn, LOGREC_UNDO_KEY_DELETE, 1, 0, &lsn,
+ msg.keynr= keynr;
+ if (_ma_write_clr(info, undo_lsn,
+ *msg.root == msg.value ?
+ LOGREC_UNDO_KEY_DELETE : LOGREC_UNDO_KEY_DELETE_WITH_ROOT,
+ 0, 0, &lsn,
(void*) &msg))
res= 1;
diff --git a/storage/maria/ma_key_recover.h b/storage/maria/ma_key_recover.h
index 210d58f3eb8..f2fd81f2120 100644
--- a/storage/maria/ma_key_recover.h
+++ b/storage/maria/ma_key_recover.h
@@ -35,6 +35,7 @@ struct st_msg_to_write_hook_for_undo_key
{
my_off_t *root;
my_off_t value;
+ uint keynr;
};
diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c
index e5e0d4e71bc..2b1d6e4a48d 100644
--- a/storage/maria/ma_loghandler.c
+++ b/storage/maria/ma_loghandler.c
@@ -490,6 +490,13 @@ static LOG_DESC INIT_LOGREC_UNDO_KEY_INSERT=
NULL, write_hook_for_undo_key, NULL, 1,
"undo_key_insert", LOGREC_LAST_IN_GROUP, NULL, NULL};
+/* This will never be in the log, only in the clr */
+static LOG_DESC INIT_LOGREC_UNDO_KEY_INSERT_WITH_ROOT=
+{LOGRECTYPE_VARIABLE_LENGTH, 0,
+ LSN_STORE_SIZE + FILEID_STORE_SIZE + KEY_NR_STORE_SIZE + PAGE_STORE_SIZE,
+ NULL, write_hook_for_undo_key, NULL, 1,
+ "undo_key_insert_with_root", LOGREC_LAST_IN_GROUP, NULL, NULL};
+
static LOG_DESC INIT_LOGREC_UNDO_KEY_DELETE=
{LOGRECTYPE_VARIABLE_LENGTH, 0,
LSN_STORE_SIZE + FILEID_STORE_SIZE + KEY_NR_STORE_SIZE,
@@ -605,6 +612,8 @@ static void loghandler_init()
INIT_LOGREC_UNDO_ROW_UPDATE;
log_record_type_descriptor[LOGREC_UNDO_KEY_INSERT]=
INIT_LOGREC_UNDO_KEY_INSERT;
+ log_record_type_descriptor[LOGREC_UNDO_KEY_INSERT_WITH_ROOT]=
+ INIT_LOGREC_UNDO_KEY_INSERT_WITH_ROOT;
log_record_type_descriptor[LOGREC_UNDO_KEY_DELETE]=
INIT_LOGREC_UNDO_KEY_DELETE;
log_record_type_descriptor[LOGREC_UNDO_KEY_DELETE_WITH_ROOT]=
diff --git a/storage/maria/ma_loghandler.h b/storage/maria/ma_loghandler.h
index 098ddffce66..4aa98cb2f0a 100644
--- a/storage/maria/ma_loghandler.h
+++ b/storage/maria/ma_loghandler.h
@@ -123,6 +123,7 @@ enum translog_record_type
LOGREC_UNDO_ROW_DELETE,
LOGREC_UNDO_ROW_UPDATE,
LOGREC_UNDO_KEY_INSERT,
+ LOGREC_UNDO_KEY_INSERT_WITH_ROOT,
LOGREC_UNDO_KEY_DELETE,
LOGREC_UNDO_KEY_DELETE_WITH_ROOT,
LOGREC_PREPARE,
diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c
index 18063dd3845..9fe2b5ec704 100644
--- a/storage/maria/ma_open.c
+++ b/storage/maria/ma_open.c
@@ -613,7 +613,8 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
share->base.null_bytes +
share->base.pack_bytes +
test(share->options & HA_OPTION_CHECKSUM));
- share->keypage_header= ((share->base.born_transactional ? LSN_STORE_SIZE :
+ share->keypage_header= ((share->base.born_transactional ?
+ LSN_STORE_SIZE + TRANSID_SIZE :
0) + KEYPAGE_KEYID_SIZE + KEYPAGE_FLAG_SIZE +
KEYPAGE_USED_SIZE);
@@ -672,6 +673,11 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
MARIA_REC_BUFF_OFFSET);
share->base.default_rec_buff_size+= share->base.extra_rec_buff_size;
}
+ if (share->data_file_type == COMPRESSED_RECORD)
+ {
+ /* Need some extra bytes for decode_bytes */
+ share->base.extra_rec_buff_size= 7;
+ }
disk_pos_assert(disk_pos + share->base.fields *MARIA_COLUMNDEF_SIZE,
end_pos);
for (i= j= 0 ; i < share->base.fields ; i++)
@@ -1042,6 +1048,9 @@ static void setup_key_functions(register MARIA_KEYDEF *keyinfo)
uint _ma_state_info_write(MARIA_SHARE *share, uint pWrite)
{
uint res;
+ if (share->options & HA_OPTION_READ_ONLY_DATA)
+ return 0;
+
if (pWrite & 4)
pthread_mutex_lock(&share->intern_lock);
else if (maria_multi_threaded)
@@ -1091,7 +1100,7 @@ uint _ma_state_info_write_sub(File file, MARIA_STATE_INFO *state, uint pWrite)
uchar *ptr=buff;
uint i, keys= (uint) state->header.keys;
size_t res;
- DBUG_ENTER("_ma_state_info_write");
+ DBUG_ENTER("_ma_state_info_write_sub");
memcpy_fixed(ptr,&state->header,sizeof(state->header));
ptr+=sizeof(state->header);
diff --git a/storage/maria/ma_packrec.c b/storage/maria/ma_packrec.c
index 08959aca079..5d04b9d705a 100644
--- a/storage/maria/ma_packrec.c
+++ b/storage/maria/ma_packrec.c
@@ -44,7 +44,9 @@
{ bits-=(bit+1); break; } \
pos+= *pos
-/* Size in uint16 of a Huffman tree for uchar compression of 256 uchar values. */
+/*
+ Size in uint16 of a Huffman tree for uchar compression of 256 uchar values
+*/
#define OFFSET_TABLE_SIZE 512
static my_bool _ma_read_pack_info(MARIA_SHARE *share, File file,
@@ -245,7 +247,8 @@ static my_bool _ma_read_pack_info(MARIA_SHARE *share, File file,
length=(uint) (elements*2+trees*(1 << maria_quick_table_bits));
if (!(share->decode_tables=(uint16*)
my_malloc((length+OFFSET_TABLE_SIZE)*sizeof(uint16)+
- (uint) (share->pack.header_length - sizeof(header)),
+ (uint) (share->pack.header_length - sizeof(header)) +
+ share->base.extra_rec_buff_size,
MYF(MY_WME | MY_ZEROFILL))))
goto err1;
tmp_buff=share->decode_tables+length;
@@ -255,6 +258,11 @@ static my_bool _ma_read_pack_info(MARIA_SHARE *share, File file,
(uint) (share->pack.header_length-sizeof(header)),
MYF(MY_NABP)))
goto err2;
+#ifdef HAVE_purify
+ /* Zero bytes accessed by fill_buffer */
+ bzero(disk_cache + (share->pack.header_length-sizeof(header)),
+ share->base.extra_rec_buff_size);
+#endif
huff_tree_bits=max_bit(trees ? trees-1 : 0);
init_bit_buffer(&bit_buff, disk_cache,
diff --git a/storage/maria/ma_recovery.c b/storage/maria/ma_recovery.c
index df1d1c509d8..c6481412232 100644
--- a/storage/maria/ma_recovery.c
+++ b/storage/maria/ma_recovery.c
@@ -1147,7 +1147,7 @@ static int new_table(uint16 sid, const char *name,
tprint(tracef, ", has wrong state.key_file_length (fixing it)");
share->state.state.key_file_length= kfile_len;
}
- if ((dfile_len % share->block_size) > 0)
+ if ((dfile_len % share->block_size) || (kfile_len % share->block_size))
{
tprint(tracef, ", has too short last page\n");
/* Recovery will fix this, no error */
@@ -1669,9 +1669,10 @@ prototype_redo_exec_hook(CLR_END)
enum translog_record_type undone_record_type;
const LOG_DESC *log_desc;
my_bool row_entry= 0;
+ DBUG_ENTER("exec_REDO_LOGREC_CLR_END");
if (info == NULL)
- return 0;
+ DBUG_RETURN(0);
share= info->s;
previous_undo_lsn= lsn_korr(rec->header);
undone_record_type=
@@ -1699,6 +1700,28 @@ prototype_redo_exec_hook(CLR_END)
case LOGREC_UNDO_KEY_INSERT:
case LOGREC_UNDO_KEY_DELETE:
break;
+ case LOGREC_UNDO_KEY_INSERT_WITH_ROOT:
+ case LOGREC_UNDO_KEY_DELETE_WITH_ROOT:
+ {
+ uint key_nr;
+ my_off_t page;
+ uchar buff[KEY_NR_STORE_SIZE + PAGE_STORE_SIZE];
+ if (translog_read_record(rec->lsn, LSN_STORE_SIZE + FILEID_STORE_SIZE +
+ CLR_TYPE_STORE_SIZE,
+ KEY_NR_STORE_SIZE + PAGE_STORE_SIZE,
+ buff, NULL) !=
+ KEY_NR_STORE_SIZE + PAGE_STORE_SIZE)
+ {
+ tprint(tracef, "Failed to read record\n");
+ DBUG_RETURN(1);
+ }
+ key_nr= key_nr_korr(buff);
+ page= page_korr(buff + KEY_NR_STORE_SIZE);
+ share->state.key_root[key_nr]= (page == IMPOSSIBLE_PAGE_NO ?
+ HA_OFFSET_ERROR :
+ page * share->block_size);
+ break;
+ }
default:
DBUG_ASSERT(0);
}
@@ -1710,7 +1733,7 @@ prototype_redo_exec_hook(CLR_END)
buff, NULL) != HA_CHECKSUM_STORE_SIZE)
{
tprint(tracef, "Failed to read record\n");
- return 1;
+ DBUG_RETURN(1);
}
share->state.state.checksum+= ha_checksum_korr(buff);
}
@@ -1719,7 +1742,7 @@ prototype_redo_exec_hook(CLR_END)
if (row_entry)
tprint(tracef, " rows' count %lu\n", (ulong)share->state.state.records);
_ma_unpin_all_pages(info, rec->lsn);
- return 0;
+ DBUG_RETURN(0);
}
diff --git a/storage/maria/ma_sort.c b/storage/maria/ma_sort.c
index e61019aeb83..69a95db2e09 100644
--- a/storage/maria/ma_sort.c
+++ b/storage/maria/ma_sort.c
@@ -110,7 +110,9 @@ int _ma_create_index_by_sort(MARIA_SORT_PARAM *info, my_bool no_messages,
uchar **sort_keys;
IO_CACHE tempfile, tempfile_for_exceptions;
DBUG_ENTER("_ma_create_index_by_sort");
- DBUG_PRINT("enter",("sort_length: %d", info->key_length));
+ DBUG_PRINT("enter",("sort_buff_size: %lu sort_length: %d max_records: %lu",
+ (ulong) sortbuff_size, info->key_length,
+ (ulong) info->sort_info->max_records));
if (info->keyinfo->flag & HA_VAR_LENGTH_KEY)
{
diff --git a/storage/maria/ma_test_all.sh b/storage/maria/ma_test_all.sh
index ef12d1340aa..bfadd3d516c 100755
--- a/storage/maria/ma_test_all.sh
+++ b/storage/maria/ma_test_all.sh
@@ -169,6 +169,11 @@ run_pack_tests()
$maria_path/maria_chk$suffix -rus test1
$maria_path/maria_chk$suffix -es test1
+ $maria_path/ma_test1$suffix $silent --checksum $row_type
+ $maria_path/maria_pack$suffix --force -s test1
+ $maria_path/maria_chk$suffix -rus --safe-recover test1
+ $maria_path/maria_chk$suffix -es test1
+
$maria_path/ma_test1$suffix $silent --checksum -S $row_type
$maria_path/maria_chk$suffix -se test1
$maria_path/maria_chk$suffix -ros test1
@@ -184,10 +189,10 @@ run_pack_tests()
$maria_path/ma_test2$suffix $silent -c -d1 $row_type
$maria_path/maria_chk$suffix -s --parallel-recover test2
$maria_path/maria_chk$suffix -se test2
- $maria_path/maria_chk$suffix -s --parallel-recover --unpack test2
+ $maria_path/maria_chk$suffix -s --unpack --parallel-recover test2
$maria_path/maria_chk$suffix -se test2
$maria_path/maria_pack$suffix --force -s test1
- $maria_path/maria_chk$suffix -s --parallel-recover --unpack test2
+ $maria_path/maria_chk$suffix -s --unpack --parallel-recover test2
$maria_path/maria_chk$suffix -se test2
}
@@ -234,6 +239,30 @@ $maria_path/maria_chk$suffix -ssm test2
/bin/sh $maria_path/ma_test_recovery
#
+# Extra tests that has caused failures in the past
+#
+
+# Problem with re-executing CLR's
+rm -f maria_log.* maria_log_control
+ma_test2 -s -L -K -W -P -M -T -c -b -t2 -u1
+cp maria_log_control tmp
+maria_read_log -a -s
+maria_chk -s -e test2
+cp tmp/maria_log_control .
+rm test2.MA?
+maria_read_log -a -s
+maria_chk -s -e test2
+
+# Problem with re-executing CLR's
+rm -f maria_log.* maria_log_control
+ma_test2 -s -L -K -W -P -M -T -c -b -t2 -u1
+maria_read_log -a -s
+maria_chk -s -e test2
+rm test2.MA?
+maria_read_log -a -s
+maria_chk -e -s test2
+
+#
# Some timing tests
#
#time $maria_path/ma_test2$suffix $silent
diff --git a/storage/maria/ma_test_recovery b/storage/maria/ma_test_recovery
index b2329694e62..87b343e9301 100755
--- a/storage/maria/ma_test_recovery
+++ b/storage/maria/ma_test_recovery
@@ -24,14 +24,7 @@ check_table_is_same()
$maria_path/maria_chk -dvv $table | grep -v "Creation time:" > $tmp/maria_chk_message.txt 2>&1
- # save the index file (because we want to test idempotency afterwards)
- cp $table.MAI tmp/
- # In the repair below it's good to use -q because it will die on any
- # incorrectness of the data file if UNDO was badly applied.
- # QQ: Remove the following line when we also can recover the index file
- $maria_path/maria_chk -s -rq $table
-
- $maria_path/maria_chk -s -e $table
+ $maria_path/maria_chk -s -e --read-only $table
checksum2=`$maria_path/maria_chk -dss $table`
if test "$checksum" != "$checksum2"
then
@@ -47,7 +40,6 @@ check_table_is_same()
cat $tmp/maria_chk_diff.txt
echo "========DIFF END======="
fi
- mv tmp/$table.MAI .
}
apply_log()
diff --git a/storage/maria/ma_test_recovery.expected b/storage/maria/ma_test_recovery.expected
index 249cefea15d..4c853476a28 100644
--- a/storage/maria/ma_test_recovery.expected
+++ b/storage/maria/ma_test_recovery.expected
@@ -47,40 +47,40 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-7c7
+6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
-12c12
+11c11
< Datafile length: 8192 Keyfile length: 8192
---
-> Datafile length: 90112 Keyfile length: 204800
+> Datafile length: 114688 Keyfile length: 204800
========DIFF END=======
testing idempotency
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-7c7
+6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
-12c12
+11c11
< Datafile length: 8192 Keyfile length: 8192
---
-> Datafile length: 90112 Keyfile length: 204800
+> Datafile length: 114688 Keyfile length: 204800
========DIFF END=======
testing applying of CLRs to recreate table
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-7c7
+6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
-12c12
+11c11
< Datafile length: 8192 Keyfile length: 8192
---
-> Datafile length: 90112 Keyfile length: 204800
+> Datafile length: 114688 Keyfile length: 204800
========DIFF END=======
TEST WITH ma_test1 -s -M -T -c -N --testflag=1 (commit at end)
TEST WITH ma_test1 -s -M -T -c -N --testflag=2 --test-undo=2 (additional aborted work)
@@ -117,40 +117,40 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-7c7
+6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
-12c12
+11c11
< Datafile length: 8192 Keyfile length: 8192
---
-> Datafile length: 90112 Keyfile length: 204800
+> Datafile length: 114688 Keyfile length: 204800
========DIFF END=======
testing idempotency
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-7c7
+6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
-12c12
+11c11
< Datafile length: 8192 Keyfile length: 8192
---
-> Datafile length: 90112 Keyfile length: 204800
+> Datafile length: 114688 Keyfile length: 204800
========DIFF END=======
testing applying of CLRs to recreate table
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-7c7
+6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
-12c12
+11c11
< Datafile length: 8192 Keyfile length: 8192
---
-> Datafile length: 90112 Keyfile length: 204800
+> Datafile length: 114688 Keyfile length: 204800
========DIFF END=======
TEST WITH ma_test1 -s -M -T -c -N --testflag=1 (commit at end)
TEST WITH ma_test1 -s -M -T -c -N --testflag=2 --test-undo=3 (additional aborted work)
@@ -187,40 +187,40 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-7c7
+6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
-12c12
+11c11
< Datafile length: 8192 Keyfile length: 8192
---
-> Datafile length: 81920 Keyfile length: 204800
+> Datafile length: 114688 Keyfile length: 204800
========DIFF END=======
testing idempotency
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-7c7
+6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
-12c12
+11c11
< Datafile length: 8192 Keyfile length: 8192
---
-> Datafile length: 81920 Keyfile length: 204800
+> Datafile length: 114688 Keyfile length: 204800
========DIFF END=======
testing applying of CLRs to recreate table
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-7c7
+6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
-12c12
+11c11
< Datafile length: 8192 Keyfile length: 8192
---
-> Datafile length: 81920 Keyfile length: 204800
+> Datafile length: 114688 Keyfile length: 204800
========DIFF END=======
TEST WITH ma_test1 -s -M -T -c -N -b --testflag=1 (commit at end)
TEST WITH ma_test1 -s -M -T -c -N -b --testflag=2 --test-undo=1 (additional aborted work)
@@ -257,40 +257,40 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-7c7
+6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
-12c12
+11c11
< Datafile length: 8192 Keyfile length: 8192
---
-> Datafile length: 122880 Keyfile length: 212992
+> Datafile length: 155648 Keyfile length: 212992
========DIFF END=======
testing idempotency
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-7c7
+6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
-12c12
+11c11
< Datafile length: 8192 Keyfile length: 8192
---
-> Datafile length: 122880 Keyfile length: 212992
+> Datafile length: 155648 Keyfile length: 212992
========DIFF END=======
testing applying of CLRs to recreate table
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-7c7
+6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
-12c12
+11c11
< Datafile length: 8192 Keyfile length: 8192
---
-> Datafile length: 122880 Keyfile length: 212992
+> Datafile length: 155648 Keyfile length: 212992
========DIFF END=======
TEST WITH ma_test1 -s -M -T -c -N -b --testflag=1 (commit at end)
TEST WITH ma_test1 -s -M -T -c -N -b --testflag=2 --test-undo=2 (additional aborted work)
@@ -327,40 +327,40 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-7c7
+6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
-12c12
+11c11
< Datafile length: 8192 Keyfile length: 8192
---
-> Datafile length: 122880 Keyfile length: 212992
+> Datafile length: 155648 Keyfile length: 212992
========DIFF END=======
testing idempotency
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-7c7
+6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
-12c12
+11c11
< Datafile length: 8192 Keyfile length: 8192
---
-> Datafile length: 122880 Keyfile length: 212992
+> Datafile length: 155648 Keyfile length: 212992
========DIFF END=======
testing applying of CLRs to recreate table
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-7c7
+6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
-12c12
+11c11
< Datafile length: 8192 Keyfile length: 8192
---
-> Datafile length: 122880 Keyfile length: 212992
+> Datafile length: 155648 Keyfile length: 212992
========DIFF END=======
TEST WITH ma_test1 -s -M -T -c -N -b --testflag=1 (commit at end)
TEST WITH ma_test1 -s -M -T -c -N -b --testflag=2 --test-undo=3 (additional aborted work)
@@ -397,11 +397,11 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-7c7
+6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
-12c12
+11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 122880 Keyfile length: 212992
@@ -410,27 +410,27 @@ testing idempotency
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-7c7
+6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
-12c12
+11c11
< Datafile length: 8192 Keyfile length: 8192
---
-> Datafile length: 122880 Keyfile length: 212992
+> Datafile length: 155648 Keyfile length: 212992
========DIFF END=======
testing applying of CLRs to recreate table
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-7c7
+6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
-12c12
+11c11
< Datafile length: 8192 Keyfile length: 8192
---
-> Datafile length: 122880 Keyfile length: 212992
+> Datafile length: 155648 Keyfile length: 212992
========DIFF END=======
TEST WITH ma_test1 -s -M -T -c -N -H1 --testflag=1 (commit at end)
TEST WITH ma_test1 -s -M -T -c -N -H1 --testflag=2 --test-undo=1 (additional aborted work)
@@ -467,40 +467,40 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-7c7
+6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
-12c12
+11c11
< Datafile length: 8192 Keyfile length: 8192
---
-> Datafile length: 90112 Keyfile length: 204800
+> Datafile length: 114688 Keyfile length: 204800
========DIFF END=======
testing idempotency
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-7c7
+6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
-12c12
+11c11
< Datafile length: 8192 Keyfile length: 8192
---
-> Datafile length: 90112 Keyfile length: 204800
+> Datafile length: 114688 Keyfile length: 204800
========DIFF END=======
testing applying of CLRs to recreate table
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-7c7
+6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
-12c12
+11c11
< Datafile length: 8192 Keyfile length: 8192
---
-> Datafile length: 90112 Keyfile length: 204800
+> Datafile length: 114688 Keyfile length: 204800
========DIFF END=======
TEST WITH ma_test1 -s -M -T -c -N -H1 --testflag=1 (commit at end)
TEST WITH ma_test1 -s -M -T -c -N -H1 --testflag=2 --test-undo=2 (additional aborted work)
@@ -537,37 +537,37 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-7c7
+6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
-12c12
+11c11
< Datafile length: 8192 Keyfile length: 8192
---
-> Datafile length: 90112 Keyfile length: 204800
+> Datafile length: 114688 Keyfile length: 204800
========DIFF END=======
testing idempotency
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-7c7
+6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
-12c12
+11c11
< Datafile length: 8192 Keyfile length: 8192
---
-> Datafile length: 90112 Keyfile length: 204800
+> Datafile length: 114688 Keyfile length: 204800
========DIFF END=======
testing applying of CLRs to recreate table
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-7c7
+6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
-12c12
+11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 90112 Keyfile length: 204800
@@ -607,11 +607,11 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-7c7
+6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
-12c12
+11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 81920 Keyfile length: 204800
@@ -620,11 +620,11 @@ testing idempotency
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-7c7
+6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
-12c12
+11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 81920 Keyfile length: 204800
@@ -633,11 +633,11 @@ testing applying of CLRs to recreate table
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-7c7
+6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
-12c12
+11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 81920 Keyfile length: 204800
@@ -677,40 +677,40 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-7c7
+6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
-12c12
+11c11
< Datafile length: 8192 Keyfile length: 8192
---
-> Datafile length: 122880 Keyfile length: 212992
+> Datafile length: 155648 Keyfile length: 212992
========DIFF END=======
testing idempotency
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-7c7
+6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
-12c12
+11c11
< Datafile length: 8192 Keyfile length: 8192
---
-> Datafile length: 122880 Keyfile length: 212992
+> Datafile length: 155648 Keyfile length: 212992
========DIFF END=======
testing applying of CLRs to recreate table
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-7c7
+6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
-12c12
+11c11
< Datafile length: 8192 Keyfile length: 8192
---
-> Datafile length: 122880 Keyfile length: 212992
+> Datafile length: 155648 Keyfile length: 212992
========DIFF END=======
TEST WITH ma_test1 -s -M -T -c -N -b -H1 --testflag=1 (commit at end)
TEST WITH ma_test1 -s -M -T -c -N -b -H1 --testflag=2 --test-undo=2 (additional aborted work)
@@ -747,11 +747,11 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-7c7
+6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
-12c12
+11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 122880 Keyfile length: 212992
@@ -760,11 +760,11 @@ testing idempotency
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-7c7
+6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
-12c12
+11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 122880 Keyfile length: 212992
@@ -773,11 +773,11 @@ testing applying of CLRs to recreate table
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-7c7
+6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
-12c12
+11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 122880 Keyfile length: 212992
@@ -817,11 +817,11 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-7c7
+6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
-12c12
+11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 122880 Keyfile length: 212992
@@ -830,25 +830,25 @@ testing idempotency
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-7c7
+6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
-12c12
+11c11
< Datafile length: 8192 Keyfile length: 8192
---
-> Datafile length: 122880 Keyfile length: 212992
+> Datafile length: 155648 Keyfile length: 212992
========DIFF END=======
testing applying of CLRs to recreate table
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
-7c7
+6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
-12c12
+11c11
< Datafile length: 8192 Keyfile length: 8192
---
-> Datafile length: 122880 Keyfile length: 212992
+> Datafile length: 155648 Keyfile length: 212992
========DIFF END=======
diff --git a/storage/maria/maria_chk.c b/storage/maria/maria_chk.c
index 4b78c5421a7..0203dd2fb26 100644
--- a/storage/maria/maria_chk.c
+++ b/storage/maria/maria_chk.c
@@ -135,7 +135,7 @@ int main(int argc, char **argv)
{ /* Only if descript */
char buff[22],buff2[22];
if (!(check_param.testflag & T_SILENT) || check_param.testflag & T_INFO)
- puts("\n---------\n");
+ puts("\n---------");
printf("\nTotal of all %d MARIA-files:\nData records: %9s Deleted blocks: %9s\n",check_param.total_files,llstr(check_param.total_records,buff),
llstr(check_param.total_deleted,buff2));
}
@@ -624,9 +624,13 @@ get_one_option(int optid,
break;
case 'u':
if (argument == disabled_my_option)
- check_param.testflag&= ~(T_UNPACK | T_REP_BY_SORT);
+ check_param.testflag&= ~T_UNPACK;
else
- check_param.testflag|= T_UNPACK | T_REP_BY_SORT;
+ {
+ check_param.testflag|= T_UNPACK;
+ if (!(check_param.testflag & T_REP_ANY))
+ check_param.testflag|= T_REP_BY_SORT;
+ }
break;
case 'v': /* Verbose */
if (argument == disabled_my_option)
@@ -802,13 +806,13 @@ static int maria_chk(HA_CHECK *param, char *filename)
datafile=0;
param->isam_file_name=filename; /* For error messages */
if (!(info=maria_open(filename,
- (param->testflag & (T_DESCRIPT | T_READONLY)) ?
- O_RDONLY : O_RDWR,
- HA_OPEN_FOR_REPAIR |
- ((param->testflag & T_WAIT_FOREVER) ?
- HA_OPEN_WAIT_IF_LOCKED :
- (param->testflag & T_DESCRIPT) ?
- HA_OPEN_IGNORE_IF_LOCKED : HA_OPEN_ABORT_IF_LOCKED))))
+ (param->testflag & (T_DESCRIPT | T_READONLY)) ?
+ O_RDONLY : O_RDWR,
+ HA_OPEN_FOR_REPAIR |
+ ((param->testflag & T_WAIT_FOREVER) ?
+ HA_OPEN_WAIT_IF_LOCKED :
+ (param->testflag & T_DESCRIPT) ?
+ HA_OPEN_IGNORE_IF_LOCKED : HA_OPEN_ABORT_IF_LOCKED))))
{
/* Avoid twice printing of isam file name */
param->error_printed=1;
@@ -852,7 +856,6 @@ static int maria_chk(HA_CHECK *param, char *filename)
DBUG_RETURN(1);
}
share=info->s;
- share->options&= ~HA_OPTION_READ_ONLY_DATA; /* We are modifing it */
share->tot_locks-= share->r_locks;
share->r_locks=0;
maria_block_size= share->base.block_size;
@@ -871,10 +874,10 @@ static int maria_chk(HA_CHECK *param, char *filename)
goto end2;
}
/* We can't do parallell repair with BLOCK_RECORD yet */
- if (param->testflag & (T_REP_BY_SORT | T_REP_PARALLEL))
+ if (param->testflag & T_REP_PARALLEL)
{
- param->testflag&= ~(T_REP_BY_SORT | T_REP_PARALLEL);
- param->testflag|= T_REP;
+ param->testflag&= ~T_REP_PARALLEL;
+ param->testflag|= T_REP_BY_SORT;
}
}
@@ -1255,7 +1258,7 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, char *name)
DBUG_VOID_RETURN;
}
- printf("\nMARIA file: %s\n",name);
+ printf("MARIA file: %s\n",name);
printf("Record format: %s\n", record_formats[share->data_file_type]);
printf("Crashsafe: %s\n",
share->base.born_transactional ? "yes" : "no");
diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h
index 95ddf358679..4e771a2c85a 100644
--- a/storage/maria/maria_def.h
+++ b/storage/maria/maria_def.h
@@ -118,7 +118,7 @@ typedef struct st_maria_state_info
#define MARIA_STATE_KEYBLOCK_SIZE 8
#define MARIA_STATE_KEYSEG_SIZE 12
#define MARIA_STATE_EXTRA_SIZE (MARIA_MAX_KEY*MARIA_STATE_KEY_SIZE + MARIA_MAX_KEY*HA_MAX_KEY_SEG*MARIA_STATE_KEYSEG_SIZE)
-#define MARIA_KEYDEF_SIZE (2+ 5*2)
+#define MARIA_KEYDEF_SIZE (2+ 5*2)
#define MARIA_UNIQUEDEF_SIZE (2+1+1)
#define HA_KEYSEG_SIZE (6+ 2*2 + 4*2)
#define MARIA_COLUMNDEF_SIZE (6+2+2+2+2+2+1+1)
@@ -507,6 +507,7 @@ struct st_maria_handler
#define USE_WHOLE_KEY 65535 /* Use whole key in _search() */
#define F_EXTRA_LCK -1
+#define TRANSID_SIZE 6
/* bits in opt_flag */
#define MEMMAP_USED 32
@@ -540,7 +541,8 @@ struct st_maria_handler
#define KEYPAGE_FLAG_SIZE 1
#define KEYPAGE_CHECKSUM_SIZE 4
#define MAX_KEYPAGE_HEADER_SIZE (LSN_STORE_SIZE + KEYPAGE_USED_SIZE + \
- KEYPAGE_KEYID_SIZE + KEYPAGE_FLAG_SIZE)
+ KEYPAGE_KEYID_SIZE + KEYPAGE_FLAG_SIZE + \
+ TRANSID_SIZE)
#define _ma_get_page_used(info,x) \
(((uint) mi_uint2korr(x + (info)->s->keypage_header - KEYPAGE_USED_SIZE)) & \
@@ -560,6 +562,11 @@ struct st_maria_handler
}
#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 maria_mark_crashed(x) do{(x)->s->state.changed|= STATE_CRASHED; \
DBUG_PRINT("error", ("Marked table crashed")); \
}while(0)
diff --git a/storage/maria/maria_read_log.c b/storage/maria/maria_read_log.c
index 237fad2bf94..22250a630ba 100644
--- a/storage/maria/maria_read_log.c
+++ b/storage/maria/maria_read_log.c
@@ -29,7 +29,7 @@ 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_only_display, opt_apply, opt_apply_undo, opt_silent,
+static my_bool opt_display_only, opt_apply, opt_apply_undo, opt_silent,
opt_check;
static ulong opt_page_buffer_size;
@@ -84,8 +84,8 @@ int main(int argc, char **argv)
goto err;
}
- if (opt_only_display)
- printf("You are using --only-display, NOTHING will be written to disk\n");
+ if (opt_display_only)
+ printf("You are using --display-only, NOTHING will be written to disk\n");
/* LSN could be also --start-from-lsn=# */
lsn= translog_first_lsn_in_log();
@@ -138,7 +138,7 @@ static struct my_option my_long_options[] =
(uchar **) &opt_apply, (uchar **) &opt_apply, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"check", 'c',
- "if --only-display, check if record is fully readable (for debugging)",
+ "if --display-only, check if record is fully readable (for debugging)",
(uchar **) &opt_check, (uchar **) &opt_check, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifndef DBUG_OFF
@@ -147,8 +147,8 @@ 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},
- {"only-display", 'o', "display brief info read from records' header",
- (uchar **) &opt_only_display, (uchar **) &opt_only_display, 0, GET_BOOL,
+ {"display-only", 'o', "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,
@@ -225,7 +225,7 @@ static void get_options(int *argc,char ***argv)
if (!opt_apply)
opt_apply_undo= FALSE;
- if ((opt_only_display + opt_apply) != 1)
+ if ((opt_display_only + opt_apply) != 1)
{
usage();
exit(1);