mirror of
https://github.com/MariaDB/server.git
synced 2025-07-08 17:02:21 +03:00
Merge jamppa@bk-internal.mysql.com:/home/bk/mysql-maria
into a88-113-38-195.elisa-laajakaista.fi:/home/my/bk/mysql-maria.prod BUILD/SETUP.sh: Auto merged sql/opt_range.cc: Auto merged sql/sql_insert.cc: Auto merged storage/maria/ha_maria.cc: Auto merged storage/maria/ma_check.c: Auto merged storage/maria/ma_create.c: Auto merged storage/maria/ma_delete.c: Auto merged storage/maria/ma_open.c: Auto merged storage/maria/ma_update.c: Auto merged storage/maria/ma_write.c: Auto merged storage/maria/maria_chk.c: Auto merged storage/maria/maria_def.h: Auto merged storage/maria/ma_pagecache.c: Manual merge with maria tree. storage/myisam/sort.c: Manual merge with maria tree.
This commit is contained in:
@ -145,6 +145,7 @@ base_configs="--prefix=$prefix --enable-assembler "
|
||||
base_configs="$base_configs --with-extra-charsets=complex "
|
||||
base_configs="$base_configs --enable-thread-safe-client "
|
||||
base_configs="$base_configs --with-big-tables"
|
||||
base_configs="$base_configs --with-plugin-maria"
|
||||
|
||||
if test -d "$path/../cmd-line-utils/readline"
|
||||
then
|
||||
|
7
BUILD/compile-amd64-gprof-no-ndb
Executable file
7
BUILD/compile-amd64-gprof-no-ndb
Executable file
@ -0,0 +1,7 @@
|
||||
#! /bin/sh
|
||||
path=`dirname $0`
|
||||
. "$path/SETUP.sh"
|
||||
extra_flags="$amd64_cflags -pg -g"
|
||||
extra_configs="$amd64_configs $max_no_ndb_configs --disable-shared $static_link"
|
||||
|
||||
. "$path/FINISH.sh"
|
@ -2139,9 +2139,6 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
|
||||
quick=0;
|
||||
needed_reg.clear_all();
|
||||
quick_keys.clear_all();
|
||||
if ((specialflag & SPECIAL_SAFE_MODE) && ! force_quick_range ||
|
||||
!limit)
|
||||
DBUG_RETURN(0); /* purecov: inspected */
|
||||
if (keys_to_use.is_clear_all())
|
||||
DBUG_RETURN(0);
|
||||
records= head->file->stats.records;
|
||||
|
@ -3488,10 +3488,12 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
|
||||
|
||||
/*
|
||||
If error during the CREATE SELECT we drop the table, so no need for
|
||||
engines to do logging of insertions (optimization).
|
||||
engines to do logging of insertions (optimization). We don't do it for
|
||||
temporary tables (yet) as re-enabling causes an undesirable commit.
|
||||
*/
|
||||
if (ha_enable_transaction(thd, FALSE))
|
||||
DBUG_RETURN(-1);
|
||||
if (((thd->lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) == 0) &&
|
||||
ha_enable_transaction(thd, FALSE))
|
||||
DBUG_RETURN(-1);
|
||||
|
||||
if (!(table= create_table_from_items(thd, create_info, create_table,
|
||||
alter_info, &values,
|
||||
@ -3632,11 +3634,12 @@ bool select_create::send_eof()
|
||||
nevertheless.
|
||||
*/
|
||||
if (!table->s->tmp_table)
|
||||
{
|
||||
ha_enable_transaction(thd, TRUE);
|
||||
ha_commit(thd); // Can fail, but we proceed anyway
|
||||
|
||||
}
|
||||
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
|
||||
table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
|
||||
ha_enable_transaction(thd, TRUE);
|
||||
if (thd->extra_lock)
|
||||
{
|
||||
mysql_unlock_tables(thd, thd->extra_lock);
|
||||
@ -3659,6 +3662,9 @@ void select_create::abort()
|
||||
select_insert::abort();
|
||||
reenable_binlog(thd);
|
||||
|
||||
if (table && !table->s->tmp_table)
|
||||
ha_enable_transaction(thd, TRUE);
|
||||
|
||||
/*
|
||||
We roll back the statement, including truncating the transaction
|
||||
cache of the binary log, if the statement failed.
|
||||
@ -3675,8 +3681,6 @@ void select_create::abort()
|
||||
if (thd->current_stmt_binlog_row_based)
|
||||
ha_rollback_stmt(thd);
|
||||
|
||||
ha_enable_transaction(thd, TRUE);
|
||||
|
||||
if (thd->extra_lock)
|
||||
{
|
||||
mysql_unlock_tables(thd, thd->extra_lock);
|
||||
|
@ -62,7 +62,7 @@ noinst_HEADERS = maria_def.h ma_rt_index.h ma_rt_key.h ma_rt_mbr.h \
|
||||
ma_control_file.h ha_maria.h ma_blockrec.h \
|
||||
ma_loghandler.h ma_loghandler_lsn.h ma_pagecache.h \
|
||||
ma_checkpoint.h ma_recovery.h ma_commit.h \
|
||||
trnman_public.h
|
||||
trnman_public.h ma_check_standalone.h
|
||||
ma_test1_DEPENDENCIES= $(LIBRARIES)
|
||||
ma_test1_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmaria.a \
|
||||
$(top_builddir)/storage/myisam/libmyisam.a \
|
||||
|
@ -2151,6 +2151,9 @@ int ha_maria::create(const char *name, register TABLE *table_arg,
|
||||
error;
|
||||
?
|
||||
Why fool the user?
|
||||
Shouldn't this test be pushed down to maria_create()? Because currently,
|
||||
ma_test1 -T crashes: it creates a table with DYNAMIC_RECORD but has
|
||||
born_transactional==1, which confuses some recovery-related code.
|
||||
*/
|
||||
#endif
|
||||
create_info.transactional= (row_type == BLOCK_RECORD &&
|
||||
|
@ -300,6 +300,32 @@ typedef struct st_maria_extent_cursor
|
||||
} MARIA_EXTENT_CURSOR;
|
||||
|
||||
|
||||
/**
|
||||
@brief Structure for passing down info to write_hook_for_clr_end().
|
||||
This hooks needs to know the variation of the live checksum caused by the
|
||||
current operation to update state.checksum under log's mutex,
|
||||
needs to know the transaction's previous undo_lsn to set
|
||||
trn->undo_lsn under log mutex, and needs to know the type of UNDO being
|
||||
undone now to modify state.records under log mutex.
|
||||
*/
|
||||
struct st_msg_to_write_hook_for_clr_end
|
||||
{
|
||||
LSN previous_undo_lsn;
|
||||
enum translog_record_type undone_record_type;
|
||||
ha_checksum checksum_delta;
|
||||
};
|
||||
/** S:share,D:checksum_delta,E:expression,P:pointer_into_record,L:length */
|
||||
#define store_checksum_in_rec(S,D,E,P,L) do \
|
||||
{ \
|
||||
D= 0; \
|
||||
if ((S)->calc_checksum != NULL) \
|
||||
{ \
|
||||
D= (E); \
|
||||
ha_checksum_store(P, D); \
|
||||
L+= HA_CHECKSUM_STORE_SIZE; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static my_bool delete_tails(MARIA_HA *info, MARIA_RECORD_POS *tails);
|
||||
static my_bool delete_head_or_tail(MARIA_HA *info,
|
||||
ulonglong page, uint record_number,
|
||||
@ -1387,7 +1413,7 @@ static my_bool write_tail(MARIA_HA *info,
|
||||
if (translog_write_record(&lsn, LOGREC_REDO_INSERT_ROW_TAIL,
|
||||
info->trn, info, sizeof(log_data) + length,
|
||||
TRANSLOG_INTERNAL_PARTS + 2, log_array,
|
||||
log_data))
|
||||
log_data, NULL))
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
@ -1642,7 +1668,7 @@ static my_bool free_full_pages(MARIA_HA *info, MARIA_ROW *row)
|
||||
if (translog_write_record(&lsn, LOGREC_REDO_PURGE_BLOCKS, info->trn,
|
||||
info, sizeof(log_data) + extents_length,
|
||||
TRANSLOG_INTERNAL_PARTS + 2, log_array,
|
||||
log_data))
|
||||
log_data, NULL))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
DBUG_RETURN(_ma_bitmap_free_full_pages(info, row->extents,
|
||||
@ -1689,7 +1715,7 @@ static my_bool free_full_page_range(MARIA_HA *info, ulonglong page, uint count)
|
||||
if (translog_write_record(&lsn, LOGREC_REDO_PURGE_BLOCKS,
|
||||
info->trn, info, sizeof(log_data),
|
||||
TRANSLOG_INTERNAL_PARTS + 1, log_array,
|
||||
log_data))
|
||||
log_data, NULL))
|
||||
res= 1;
|
||||
|
||||
}
|
||||
@ -1716,6 +1742,9 @@ static my_bool free_full_page_range(MARIA_HA *info, ulonglong page, uint count)
|
||||
@param row_pos Position on head page where to put head part of
|
||||
record
|
||||
@param undo_lsn <> LSN_ERROR if we are executing an UNDO
|
||||
@param old_record_checksum Checksum of old_record: ignored if table does
|
||||
not have live checksum; otherwise if
|
||||
old_record==NULL it must be 0.
|
||||
|
||||
@note
|
||||
On return all pinned pages are released.
|
||||
@ -1731,7 +1760,8 @@ static my_bool write_block_record(MARIA_HA *info,
|
||||
MARIA_BITMAP_BLOCKS *bitmap_blocks,
|
||||
my_bool head_block_is_read,
|
||||
struct st_row_pos_info *row_pos,
|
||||
LSN undo_lsn)
|
||||
LSN undo_lsn,
|
||||
ha_checksum old_record_checksum)
|
||||
{
|
||||
uchar *data, *end_of_data, *tmp_data_used, *tmp_data;
|
||||
uchar *row_extents_first_part, *row_extents_second_part;
|
||||
@ -1785,7 +1815,10 @@ static my_bool write_block_record(MARIA_HA *info,
|
||||
if (share->base.pack_fields)
|
||||
store_key_length_inc(data, row->field_lengths_length);
|
||||
if (share->calc_checksum)
|
||||
{
|
||||
*(data++)= (uchar) (row->checksum); /* store least significant byte */
|
||||
DBUG_ASSERT(!((old_record_checksum != 0) && (old_record == NULL)));
|
||||
}
|
||||
memcpy(data, record, share->base.null_bytes);
|
||||
data+= share->base.null_bytes;
|
||||
memcpy(data, row->empty_bits, share->base.pack_bytes);
|
||||
@ -2211,7 +2244,7 @@ static my_bool write_block_record(MARIA_HA *info,
|
||||
if (translog_write_record(&lsn, LOGREC_REDO_INSERT_ROW_HEAD, info->trn,
|
||||
info, sizeof(log_data) + data_length,
|
||||
TRANSLOG_INTERNAL_PARTS + 2, log_array,
|
||||
log_data))
|
||||
log_data, NULL))
|
||||
goto disk_err;
|
||||
}
|
||||
|
||||
@ -2328,7 +2361,7 @@ static my_bool write_block_record(MARIA_HA *info,
|
||||
error= translog_write_record(&lsn, LOGREC_REDO_INSERT_ROW_BLOBS,
|
||||
info->trn, info, log_entry_length,
|
||||
(uint) (log_array_pos - log_array),
|
||||
log_array, log_data);
|
||||
log_array, log_data, NULL);
|
||||
if (log_array != tmp_log_array)
|
||||
my_free((uchar*) log_array, MYF(0));
|
||||
if (error)
|
||||
@ -2343,31 +2376,44 @@ static my_bool write_block_record(MARIA_HA *info,
|
||||
|
||||
if (undo_lsn != LSN_ERROR)
|
||||
{
|
||||
uchar log_data[LSN_STORE_SIZE + FILEID_STORE_SIZE + 1];
|
||||
uchar log_data[LSN_STORE_SIZE + FILEID_STORE_SIZE +
|
||||
CLR_TYPE_STORE_SIZE + HA_CHECKSUM_STORE_SIZE];
|
||||
struct st_msg_to_write_hook_for_clr_end msg;
|
||||
/* undo_lsn must be first for compression to work */
|
||||
lsn_store(log_data, undo_lsn);
|
||||
/*
|
||||
Store if this CLR is about an UNDO_INSERT, UNDO_DELETE or UNDO_UPDATE;
|
||||
in the first/second case, Recovery, when it sees the CLR_END in the
|
||||
REDO phase, may decrement/increment the records' count.
|
||||
Store if this CLR is about UNDO_DELETE or UNDO_UPDATE;
|
||||
in the first case, Recovery, when it sees the CLR_END in the
|
||||
REDO phase, may decrement the records' count.
|
||||
*/
|
||||
log_data[LSN_STORE_SIZE + FILEID_STORE_SIZE]= old_record ?
|
||||
LOGREC_UNDO_ROW_UPDATE : LOGREC_UNDO_ROW_DELETE;
|
||||
log_array[TRANSLOG_INTERNAL_PARTS + 0].str= (char*) log_data;
|
||||
log_array[TRANSLOG_INTERNAL_PARTS + 0].length= sizeof(log_data);
|
||||
|
||||
log_array[TRANSLOG_INTERNAL_PARTS + 0].length=
|
||||
sizeof(log_data) - HA_CHECKSUM_STORE_SIZE;
|
||||
msg.undone_record_type=
|
||||
old_record ? LOGREC_UNDO_ROW_UPDATE : LOGREC_UNDO_ROW_DELETE;
|
||||
clr_type_store(log_data + LSN_STORE_SIZE + FILEID_STORE_SIZE,
|
||||
msg.undone_record_type);
|
||||
msg.previous_undo_lsn= undo_lsn;
|
||||
store_checksum_in_rec(share, msg.checksum_delta,
|
||||
row->checksum - old_record_checksum,
|
||||
log_data + LSN_STORE_SIZE + FILEID_STORE_SIZE +
|
||||
CLR_TYPE_STORE_SIZE,
|
||||
log_array[TRANSLOG_INTERNAL_PARTS + 0].length);
|
||||
if (translog_write_record(&lsn, LOGREC_CLR_END,
|
||||
info->trn, info, sizeof(log_data),
|
||||
info->trn, info,
|
||||
log_array[TRANSLOG_INTERNAL_PARTS + 0].length,
|
||||
TRANSLOG_INTERNAL_PARTS + 1, log_array,
|
||||
log_data + LSN_STORE_SIZE))
|
||||
log_data + LSN_STORE_SIZE, &msg))
|
||||
goto disk_err;
|
||||
}
|
||||
else
|
||||
{
|
||||
uchar log_data[LSN_STORE_SIZE + FILEID_STORE_SIZE +
|
||||
PAGE_STORE_SIZE + DIRPOS_STORE_SIZE];
|
||||
PAGE_STORE_SIZE + DIRPOS_STORE_SIZE +
|
||||
HA_CHECKSUM_STORE_SIZE];
|
||||
ha_checksum checksum_delta;
|
||||
|
||||
/* LOGREC_UNDO_ROW_INSERT & LOGREC_UNDO_ROW_INSERT share same header */
|
||||
/* LOGREC_UNDO_ROW_INSERT & LOGREC_UNDO_ROW_UPDATE share same header */
|
||||
lsn_store(log_data, info->trn->undo_lsn);
|
||||
page_store(log_data + LSN_STORE_SIZE + FILEID_STORE_SIZE,
|
||||
head_block->page);
|
||||
@ -2376,15 +2422,24 @@ static my_bool write_block_record(MARIA_HA *info,
|
||||
row_pos->rownr);
|
||||
|
||||
log_array[TRANSLOG_INTERNAL_PARTS + 0].str= (char*) log_data;
|
||||
log_array[TRANSLOG_INTERNAL_PARTS + 0].length= sizeof(log_data);
|
||||
log_array[TRANSLOG_INTERNAL_PARTS + 0].length=
|
||||
sizeof(log_data) - HA_CHECKSUM_STORE_SIZE;
|
||||
store_checksum_in_rec(share, checksum_delta,
|
||||
row->checksum - old_record_checksum,
|
||||
log_data + LSN_STORE_SIZE + FILEID_STORE_SIZE +
|
||||
PAGE_STORE_SIZE + DIRPOS_STORE_SIZE,
|
||||
log_array[TRANSLOG_INTERNAL_PARTS + 0].length);
|
||||
compile_time_assert(sizeof(ha_checksum) == HA_CHECKSUM_STORE_SIZE);
|
||||
|
||||
if (!old_record)
|
||||
{
|
||||
/* Write UNDO log record for the INSERT */
|
||||
if (translog_write_record(&lsn, LOGREC_UNDO_ROW_INSERT,
|
||||
info->trn, info, sizeof(log_data),
|
||||
info->trn, info,
|
||||
log_array[TRANSLOG_INTERNAL_PARTS +
|
||||
0].length,
|
||||
TRANSLOG_INTERNAL_PARTS + 1, log_array,
|
||||
log_data + LSN_STORE_SIZE))
|
||||
log_data + LSN_STORE_SIZE, &checksum_delta))
|
||||
goto disk_err;
|
||||
}
|
||||
else
|
||||
@ -2397,10 +2452,11 @@ static my_bool write_block_record(MARIA_HA *info,
|
||||
TRANSLOG_INTERNAL_PARTS + 1,
|
||||
&row_parts_count);
|
||||
if (translog_write_record(&lsn, LOGREC_UNDO_ROW_UPDATE, info->trn,
|
||||
info, sizeof(log_data) + row_length,
|
||||
info, log_array[TRANSLOG_INTERNAL_PARTS +
|
||||
0].length + row_length,
|
||||
TRANSLOG_INTERNAL_PARTS + 1 +
|
||||
row_parts_count,
|
||||
log_array, log_data + LSN_STORE_SIZE))
|
||||
row_parts_count, log_array,
|
||||
log_data + LSN_STORE_SIZE, &checksum_delta))
|
||||
goto disk_err;
|
||||
}
|
||||
}
|
||||
@ -2517,10 +2573,18 @@ static my_bool allocate_and_write_block_record(MARIA_HA *info,
|
||||
DBUG_RETURN(1);
|
||||
row->lastpos= ma_recordpos(blocks->block->page, row_pos.rownr);
|
||||
if (info->s->calc_checksum)
|
||||
row->checksum= (info->s->calc_checksum)(info, record);
|
||||
{
|
||||
if (undo_lsn == LSN_ERROR)
|
||||
row->checksum= (info->s->calc_checksum)(info, record);
|
||||
else
|
||||
{
|
||||
/* _ma_apply_undo_row_delete() already set row's checksum. Verify it. */
|
||||
DBUG_ASSERT(row->checksum == (info->s->calc_checksum)(info, record));
|
||||
}
|
||||
}
|
||||
if (write_block_record(info, (uchar*) 0, record, row,
|
||||
blocks, blocks->block->org_bitmap_value != 0,
|
||||
&row_pos, undo_lsn))
|
||||
&row_pos, undo_lsn, 0))
|
||||
DBUG_RETURN(1); /* Error reading bitmap */
|
||||
DBUG_PRINT("exit", ("Rowid: %lu (%lu:%u)", (ulong) row->lastpos,
|
||||
(ulong) ma_recordpos_to_page(row->lastpos),
|
||||
@ -2592,6 +2656,7 @@ my_bool _ma_write_abort_block_record(MARIA_HA *info)
|
||||
MARIA_BITMAP_BLOCKS *blocks= &info->cur_row.insert_blocks;
|
||||
MARIA_BITMAP_BLOCK *block, *end;
|
||||
LSN lsn= LSN_IMPOSSIBLE;
|
||||
MARIA_SHARE *share= info->s;
|
||||
DBUG_ENTER("_ma_write_abort_block_record");
|
||||
|
||||
if (delete_head_or_tail(info,
|
||||
@ -2619,13 +2684,14 @@ my_bool _ma_write_abort_block_record(MARIA_HA *info)
|
||||
}
|
||||
}
|
||||
|
||||
if (info->s->now_transactional)
|
||||
if (share->now_transactional)
|
||||
{
|
||||
LSN previous_undo_lsn;
|
||||
TRANSLOG_HEADER_BUFFER rec;
|
||||
LEX_STRING log_array[TRANSLOG_INTERNAL_PARTS + 1];
|
||||
uchar log_data[LSN_STORE_SIZE + FILEID_STORE_SIZE + 1];
|
||||
uchar log_data[LSN_STORE_SIZE + FILEID_STORE_SIZE +
|
||||
CLR_TYPE_STORE_SIZE + HA_CHECKSUM_STORE_SIZE];
|
||||
int len;
|
||||
struct st_msg_to_write_hook_for_clr_end msg;
|
||||
/*
|
||||
We do need the code above (delete_head_or_tail() etc) for
|
||||
non-transactional tables.
|
||||
@ -2644,15 +2710,24 @@ my_bool _ma_write_abort_block_record(MARIA_HA *info)
|
||||
goto end;
|
||||
}
|
||||
DBUG_ASSERT(rec.type == LOGREC_UNDO_ROW_INSERT);
|
||||
previous_undo_lsn= lsn_korr(rec.header);
|
||||
lsn_store(log_data, previous_undo_lsn);
|
||||
log_data[LSN_STORE_SIZE + FILEID_STORE_SIZE]= LOGREC_UNDO_ROW_INSERT;
|
||||
memcpy(log_data, rec.header, LSN_STORE_SIZE); /* previous UNDO LSN */
|
||||
msg.previous_undo_lsn= lsn_korr(rec.header);
|
||||
msg.undone_record_type= LOGREC_UNDO_ROW_INSERT;
|
||||
clr_type_store(log_data + LSN_STORE_SIZE + FILEID_STORE_SIZE,
|
||||
LOGREC_UNDO_ROW_INSERT);
|
||||
log_array[TRANSLOG_INTERNAL_PARTS + 0].str= (char*) log_data;
|
||||
log_array[TRANSLOG_INTERNAL_PARTS + 0].length= sizeof(log_data);
|
||||
log_array[TRANSLOG_INTERNAL_PARTS + 0].length=
|
||||
sizeof(log_data) - HA_CHECKSUM_STORE_SIZE;
|
||||
store_checksum_in_rec(share, msg.checksum_delta,
|
||||
- info->cur_row.checksum,
|
||||
log_data + LSN_STORE_SIZE + FILEID_STORE_SIZE +
|
||||
CLR_TYPE_STORE_SIZE,
|
||||
log_array[TRANSLOG_INTERNAL_PARTS + 0].length);
|
||||
if (translog_write_record(&lsn, LOGREC_CLR_END,
|
||||
info->trn, info, sizeof(log_data),
|
||||
info->trn, info,
|
||||
log_array[TRANSLOG_INTERNAL_PARTS + 0].length,
|
||||
TRANSLOG_INTERNAL_PARTS + 1, log_array,
|
||||
log_data + LSN_STORE_SIZE))
|
||||
log_data + LSN_STORE_SIZE, &msg))
|
||||
res= 1;
|
||||
}
|
||||
end:
|
||||
@ -2685,6 +2760,8 @@ static my_bool _ma_update_block_record2(MARIA_HA *info,
|
||||
uchar *dir;
|
||||
ulonglong page;
|
||||
struct st_row_pos_info row_pos;
|
||||
my_bool res;
|
||||
ha_checksum old_checksum;
|
||||
MARIA_SHARE *share= info->s;
|
||||
DBUG_ENTER("_ma_update_block_record2");
|
||||
DBUG_PRINT("enter", ("rowid: %lu", (long) record_pos));
|
||||
@ -2694,7 +2771,11 @@ static my_bool _ma_update_block_record2(MARIA_HA *info,
|
||||
DBUG_DUMP("newrec", record, share->base.reclength);
|
||||
#endif
|
||||
|
||||
/* checksum was computed by maria_update() already and put into cur_row */
|
||||
/*
|
||||
Checksums of new and old rows were computed by callers already; new
|
||||
row's was put into cur_row, old row's was put into new_row.
|
||||
*/
|
||||
old_checksum= new_row->checksum;
|
||||
new_row->checksum= cur_row->checksum;
|
||||
calc_record_size(info, record, new_row);
|
||||
page= ma_recordpos_to_page(record_pos);
|
||||
@ -2747,8 +2828,9 @@ static my_bool _ma_update_block_record2(MARIA_HA *info,
|
||||
|
||||
if (cur_row->extents_count && free_full_pages(info, cur_row))
|
||||
goto err;
|
||||
DBUG_RETURN(write_block_record(info, oldrec, record, new_row, blocks,
|
||||
1, &row_pos, undo_lsn));
|
||||
res= write_block_record(info, oldrec, record, new_row, blocks,
|
||||
1, &row_pos, undo_lsn, old_checksum);
|
||||
DBUG_RETURN(res);
|
||||
}
|
||||
/*
|
||||
Allocate all size in block for record
|
||||
@ -2781,8 +2863,9 @@ static my_bool _ma_update_block_record2(MARIA_HA *info,
|
||||
row_pos.dir= dir;
|
||||
row_pos.data= buff + uint2korr(dir);
|
||||
row_pos.length= head_length;
|
||||
DBUG_RETURN(write_block_record(info, oldrec, record, new_row, blocks, 1,
|
||||
&row_pos, undo_lsn));
|
||||
res= write_block_record(info, oldrec, record, new_row, blocks, 1,
|
||||
&row_pos, undo_lsn, old_checksum);
|
||||
DBUG_RETURN(res);
|
||||
|
||||
err:
|
||||
_ma_unpin_all_pages_and_finalize_row(info, 0);
|
||||
@ -2949,7 +3032,7 @@ static my_bool delete_head_or_tail(MARIA_HA *info,
|
||||
LOGREC_REDO_PURGE_ROW_TAIL),
|
||||
info->trn, info, sizeof(log_data),
|
||||
TRANSLOG_INTERNAL_PARTS + 1, log_array,
|
||||
log_data))
|
||||
log_data, NULL))
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
if (pagecache_write(share->pagecache,
|
||||
@ -2976,7 +3059,7 @@ static my_bool delete_head_or_tail(MARIA_HA *info,
|
||||
if (translog_write_record(&lsn, LOGREC_REDO_PURGE_BLOCKS,
|
||||
info->trn, info, sizeof(log_data),
|
||||
TRANSLOG_INTERNAL_PARTS + 1, log_array,
|
||||
log_data))
|
||||
log_data, NULL))
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
/* Write the empty page (needed only for REPAIR to work) */
|
||||
@ -3044,6 +3127,7 @@ my_bool _ma_delete_block_record(MARIA_HA *info, const uchar *record)
|
||||
{
|
||||
ulonglong page;
|
||||
uint record_number;
|
||||
MARIA_SHARE *share= info->s;
|
||||
DBUG_ENTER("_ma_delete_block_record");
|
||||
|
||||
page= ma_recordpos_to_page(info->cur_row.lastpos);
|
||||
@ -3058,13 +3142,14 @@ my_bool _ma_delete_block_record(MARIA_HA *info, const uchar *record)
|
||||
if (info->cur_row.extents && free_full_pages(info, &info->cur_row))
|
||||
goto err;
|
||||
|
||||
if (info->s->now_transactional)
|
||||
if (share->now_transactional)
|
||||
{
|
||||
LSN lsn;
|
||||
uchar log_data[LSN_STORE_SIZE + FILEID_STORE_SIZE + PAGE_STORE_SIZE +
|
||||
DIR_COUNT_SIZE];
|
||||
DIRPOS_STORE_SIZE + HA_CHECKSUM_STORE_SIZE];
|
||||
size_t row_length;
|
||||
uint row_parts_count;
|
||||
ha_checksum checksum_delta;
|
||||
|
||||
/* Write UNDO record */
|
||||
lsn_store(log_data, info->trn->undo_lsn);
|
||||
@ -3073,15 +3158,26 @@ my_bool _ma_delete_block_record(MARIA_HA *info, const uchar *record)
|
||||
PAGE_STORE_SIZE, record_number);
|
||||
|
||||
info->log_row_parts[TRANSLOG_INTERNAL_PARTS].str= (char*) log_data;
|
||||
info->log_row_parts[TRANSLOG_INTERNAL_PARTS].length= sizeof(log_data);
|
||||
info->log_row_parts[TRANSLOG_INTERNAL_PARTS].length=
|
||||
sizeof(log_data) - HA_CHECKSUM_STORE_SIZE;
|
||||
store_checksum_in_rec(share, checksum_delta,
|
||||
- info->cur_row.checksum,
|
||||
log_data + LSN_STORE_SIZE + FILEID_STORE_SIZE +
|
||||
PAGE_STORE_SIZE + DIRPOS_STORE_SIZE,
|
||||
info->log_row_parts[TRANSLOG_INTERNAL_PARTS +
|
||||
0].length);
|
||||
|
||||
row_length= fill_insert_undo_parts(info, record, info->log_row_parts +
|
||||
TRANSLOG_INTERNAL_PARTS + 1,
|
||||
&row_parts_count);
|
||||
|
||||
if (translog_write_record(&lsn, LOGREC_UNDO_ROW_DELETE, info->trn,
|
||||
info, sizeof(log_data) + row_length,
|
||||
info,
|
||||
info->log_row_parts[TRANSLOG_INTERNAL_PARTS +
|
||||
0].length + row_length,
|
||||
TRANSLOG_INTERNAL_PARTS + 1 + row_parts_count,
|
||||
info->log_row_parts, log_data + LSN_STORE_SIZE))
|
||||
info->log_row_parts, log_data + LSN_STORE_SIZE,
|
||||
&checksum_delta))
|
||||
goto err;
|
||||
|
||||
}
|
||||
@ -3377,7 +3473,8 @@ static my_bool read_long_data(MARIA_HA *info, uchar *to, ulong length,
|
||||
cur_row.extents_counts contains number of extents
|
||||
cur_row.empty_bits is set to empty bits
|
||||
cur_row.field_lengths contains packed length of all fields
|
||||
cur_row.blob_length contains total length of all blobs.
|
||||
cur_row.blob_length contains total length of all blobs
|
||||
cur_row.checksum contains checksum of read record.
|
||||
|
||||
RETURN
|
||||
0 ok
|
||||
@ -4576,6 +4673,211 @@ static size_t fill_update_undo_parts(MARIA_HA *info, const uchar *oldrec,
|
||||
DBUG_RETURN(row_length);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
In-write hooks called under log's lock when log record is written
|
||||
***************************************************************************/
|
||||
|
||||
/**
|
||||
@brief Sets transaction's rec_lsn if needed
|
||||
|
||||
A transaction sometimes writes a REDO even before the page is in the
|
||||
pagecache (example: brand new head or tail pages; full pages). So, if
|
||||
Checkpoint happens just after the REDO write, it needs to know that the
|
||||
REDO phase must start before this REDO. Scanning the pagecache cannot
|
||||
tell that as the page is not in the cache. So, transaction sets its rec_lsn
|
||||
to the REDO's LSN or somewhere before, and Checkpoint reads the
|
||||
transaction's rec_lsn.
|
||||
|
||||
@return Operation status, always 0 (success)
|
||||
*/
|
||||
|
||||
my_bool write_hook_for_redo(enum translog_record_type type
|
||||
__attribute__ ((unused)),
|
||||
TRN *trn, MARIA_HA *tbl_info
|
||||
__attribute__ ((unused)),
|
||||
LSN *lsn, void *hook_arg
|
||||
__attribute__ ((unused)))
|
||||
{
|
||||
/*
|
||||
Users of dummy_transaction_object must keep this TRN clean as it
|
||||
is used by many threads (like those manipulating non-transactional
|
||||
tables). It might be dangerous if one user sets rec_lsn or some other
|
||||
member and it is picked up by another user (like putting this rec_lsn into
|
||||
a page of a non-transactional table); it's safer if all members stay 0. So
|
||||
non-transactional log records (REPAIR, CREATE, RENAME, DROP) should not
|
||||
call this hook; we trust them but verify ;)
|
||||
*/
|
||||
DBUG_ASSERT(trn->trid != 0);
|
||||
/*
|
||||
If the hook stays so simple, it would be faster to pass
|
||||
!trn->rec_lsn ? trn->rec_lsn : some_dummy_lsn
|
||||
to translog_write_record(), like Monty did in his original code, and not
|
||||
have a hook. For now we keep it like this.
|
||||
*/
|
||||
if (trn->rec_lsn == 0)
|
||||
trn->rec_lsn= *lsn;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief Sets transaction's undo_lsn, first_undo_lsn if needed
|
||||
|
||||
@return Operation status, always 0 (success)
|
||||
*/
|
||||
|
||||
my_bool write_hook_for_undo(enum translog_record_type type
|
||||
__attribute__ ((unused)),
|
||||
TRN *trn, MARIA_HA *tbl_info
|
||||
__attribute__ ((unused)),
|
||||
LSN *lsn, void *hook_arg
|
||||
__attribute__ ((unused)))
|
||||
{
|
||||
DBUG_ASSERT(trn->trid != 0);
|
||||
trn->undo_lsn= *lsn;
|
||||
if (unlikely(LSN_WITH_FLAGS_TO_LSN(trn->first_undo_lsn) == 0))
|
||||
trn->first_undo_lsn=
|
||||
trn->undo_lsn | LSN_WITH_FLAGS_TO_FLAGS(trn->first_undo_lsn);
|
||||
DBUG_ASSERT(tbl_info->state == &tbl_info->s->state.state);
|
||||
return 0;
|
||||
/*
|
||||
when we implement purging, we will specialize this hook: UNDO_PURGE
|
||||
records will additionally set trn->undo_purge_lsn
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief Sets the table's records count and checksum to 0, then calls the
|
||||
generic REDO hook.
|
||||
|
||||
@return Operation status, always 0 (success)
|
||||
*/
|
||||
|
||||
my_bool write_hook_for_redo_delete_all(enum translog_record_type type
|
||||
__attribute__ ((unused)),
|
||||
TRN *trn, MARIA_HA *tbl_info
|
||||
__attribute__ ((unused)),
|
||||
LSN *lsn, void *hook_arg)
|
||||
{
|
||||
MARIA_SHARE *share= tbl_info->s;
|
||||
DBUG_ASSERT(tbl_info->state == &tbl_info->s->state.state);
|
||||
share->state.state.records= share->state.state.checksum= 0;
|
||||
return write_hook_for_redo(type, trn, tbl_info, lsn, hook_arg);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief Upates "records" and "checksum" and calls the generic UNDO hook
|
||||
|
||||
@return Operation status, always 0 (success)
|
||||
*/
|
||||
|
||||
my_bool write_hook_for_undo_row_insert(enum translog_record_type type
|
||||
__attribute__ ((unused)),
|
||||
TRN *trn, MARIA_HA *tbl_info,
|
||||
LSN *lsn, void *hook_arg)
|
||||
{
|
||||
MARIA_SHARE *share= tbl_info->s;
|
||||
share->state.state.records++;
|
||||
share->state.state.checksum+= *(ha_checksum *)hook_arg;
|
||||
return write_hook_for_undo(type, trn, tbl_info, lsn, hook_arg);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief Upates "records" and calls the generic UNDO hook
|
||||
|
||||
@return Operation status, always 0 (success)
|
||||
*/
|
||||
|
||||
my_bool write_hook_for_undo_row_delete(enum translog_record_type type
|
||||
__attribute__ ((unused)),
|
||||
TRN *trn, MARIA_HA *tbl_info,
|
||||
LSN *lsn, void *hook_arg)
|
||||
{
|
||||
MARIA_SHARE *share= tbl_info->s;
|
||||
share->state.state.records--;
|
||||
share->state.state.checksum+= *(ha_checksum *)hook_arg;
|
||||
return write_hook_for_undo(type, trn, tbl_info, lsn, hook_arg);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief Upates "records" and "checksum" and calls the generic UNDO hook
|
||||
|
||||
@return Operation status, always 0 (success)
|
||||
*/
|
||||
|
||||
my_bool write_hook_for_undo_row_update(enum translog_record_type type
|
||||
__attribute__ ((unused)),
|
||||
TRN *trn, MARIA_HA *tbl_info,
|
||||
LSN *lsn, void *hook_arg)
|
||||
{
|
||||
MARIA_SHARE *share= tbl_info->s;
|
||||
share->state.state.checksum+= *(ha_checksum *)hook_arg;
|
||||
return write_hook_for_undo(type, trn, tbl_info, lsn, hook_arg);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief Sets transaction's undo_lsn, first_undo_lsn if needed
|
||||
|
||||
@return Operation status, always 0 (success)
|
||||
*/
|
||||
|
||||
my_bool write_hook_for_clr_end(enum translog_record_type type
|
||||
__attribute__ ((unused)),
|
||||
TRN *trn, MARIA_HA *tbl_info
|
||||
__attribute__ ((unused)),
|
||||
LSN *lsn __attribute__ ((unused)),
|
||||
void *hook_arg)
|
||||
{
|
||||
MARIA_SHARE *share= tbl_info->s;
|
||||
struct st_msg_to_write_hook_for_clr_end *msg=
|
||||
(struct st_msg_to_write_hook_for_clr_end *)hook_arg;
|
||||
DBUG_ASSERT(trn->trid != 0);
|
||||
trn->undo_lsn= msg->previous_undo_lsn;
|
||||
share->state.state.checksum+= msg->checksum_delta;
|
||||
|
||||
switch (msg->undone_record_type) {
|
||||
case LOGREC_UNDO_ROW_DELETE:
|
||||
share->state.state.records++;
|
||||
break;
|
||||
case LOGREC_UNDO_ROW_INSERT:
|
||||
share->state.state.records--;
|
||||
break;
|
||||
case LOGREC_UNDO_ROW_UPDATE:
|
||||
break;
|
||||
default:
|
||||
DBUG_ASSERT(0);
|
||||
}
|
||||
if (trn->undo_lsn == LSN_IMPOSSIBLE) /* has fully rolled back */
|
||||
trn->first_undo_lsn= LSN_WITH_FLAGS_TO_FLAGS(trn->first_undo_lsn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief Updates table's lsn_of_file_id.
|
||||
|
||||
@return Operation status, always 0 (success)
|
||||
*/
|
||||
|
||||
my_bool write_hook_for_file_id(enum translog_record_type type
|
||||
__attribute__ ((unused)),
|
||||
TRN *trn
|
||||
__attribute__ ((unused)),
|
||||
MARIA_HA *tbl_info,
|
||||
LSN *lsn __attribute__ ((unused)),
|
||||
void *hook_arg
|
||||
__attribute__ ((unused)))
|
||||
{
|
||||
DBUG_ASSERT(cmp_translog_addr(tbl_info->s->lsn_of_file_id, *lsn) < 0);
|
||||
tbl_info->s->lsn_of_file_id= *lsn;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
Applying of REDO log records
|
||||
***************************************************************************/
|
||||
@ -4609,6 +4911,9 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
|
||||
uint block_size= share->block_size;
|
||||
uint rec_offset;
|
||||
uchar *buff= info->keyread_buff, *dir;
|
||||
MARIA_PINNED_PAGE page_link;
|
||||
enum pagecache_page_lock unlock_method;
|
||||
enum pagecache_page_pin unpin_method;
|
||||
DBUG_ENTER("_ma_apply_redo_insert_row_head_or_tail");
|
||||
|
||||
info->keyread_buff_used= 1;
|
||||
@ -4635,26 +4940,31 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
|
||||
empty_space= (block_size - PAGE_OVERHEAD_SIZE);
|
||||
rec_offset= PAGE_HEADER_SIZE;
|
||||
dir= buff+ block_size - PAGE_SUFFIX_SIZE - DIR_ENTRY_SIZE;
|
||||
unlock_method= PAGECACHE_LOCK_LEFT_UNLOCKED;
|
||||
unpin_method= PAGECACHE_PIN_LEFT_UNPINNED;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint max_entry;
|
||||
if (!(buff= pagecache_read(share->pagecache,
|
||||
&info->dfile,
|
||||
page, 0,
|
||||
buff, PAGECACHE_PLAIN_PAGE,
|
||||
PAGECACHE_LOCK_LEFT_UNLOCKED, 0)))
|
||||
if (!(buff= pagecache_read(share->pagecache, &info->dfile,
|
||||
page, 0, 0,
|
||||
PAGECACHE_PLAIN_PAGE, PAGECACHE_LOCK_WRITE,
|
||||
&page_link.link)))
|
||||
DBUG_RETURN(my_errno);
|
||||
if (lsn_korr(buff) >= lsn)
|
||||
if (lsn_korr(buff) >= lsn) /* Test if already applied */
|
||||
{
|
||||
/* Already applied */
|
||||
|
||||
pagecache_unlock_by_link(share->pagecache, page_link.link,
|
||||
PAGECACHE_LOCK_WRITE_UNLOCK,
|
||||
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
|
||||
LSN_IMPOSSIBLE);
|
||||
/* Fix bitmap, just in case */
|
||||
empty_space= uint2korr(buff + EMPTY_SPACE_OFFSET);
|
||||
if (_ma_bitmap_set(info, page, page_type == HEAD_PAGE, empty_space))
|
||||
DBUG_RETURN(my_errno);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
unlock_method= PAGECACHE_LOCK_WRITE_UNLOCK;
|
||||
unpin_method= PAGECACHE_UNPIN;
|
||||
|
||||
max_entry= (uint) ((uchar*) buff)[DIR_COUNT_OFFSET];
|
||||
if (((buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) != page_type))
|
||||
@ -4725,8 +5035,7 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
|
||||
if (pagecache_write(share->pagecache,
|
||||
&info->dfile, page, 0,
|
||||
buff, PAGECACHE_PLAIN_PAGE,
|
||||
PAGECACHE_LOCK_LEFT_UNLOCKED,
|
||||
PAGECACHE_PIN_LEFT_UNPINNED,
|
||||
unlock_method, unpin_method,
|
||||
PAGECACHE_WRITE_DELAY, 0))
|
||||
DBUG_RETURN(my_errno);
|
||||
|
||||
@ -4747,6 +5056,11 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
|
||||
DBUG_RETURN(0);
|
||||
|
||||
err:
|
||||
if (unlock_method == PAGECACHE_LOCK_WRITE_UNLOCK)
|
||||
pagecache_unlock_by_link(share->pagecache, page_link.link,
|
||||
PAGECACHE_LOCK_WRITE_UNLOCK,
|
||||
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
|
||||
LSN_IMPOSSIBLE);
|
||||
DBUG_RETURN(HA_ERR_WRONG_IN_RECORD);
|
||||
}
|
||||
|
||||
@ -4778,6 +5092,8 @@ uint _ma_apply_redo_purge_row_head_or_tail(MARIA_HA *info, LSN lsn,
|
||||
uint rownr, empty_space;
|
||||
uint block_size= share->block_size;
|
||||
uchar *buff= info->keyread_buff;
|
||||
int result;
|
||||
MARIA_PINNED_PAGE page_link;
|
||||
DBUG_ENTER("_ma_apply_redo_purge_row_head_or_tail");
|
||||
|
||||
page= page_korr(header);
|
||||
@ -4788,11 +5104,10 @@ uint _ma_apply_redo_purge_row_head_or_tail(MARIA_HA *info, LSN lsn,
|
||||
|
||||
info->keyread_buff_used= 1;
|
||||
|
||||
if (!(buff= pagecache_read(share->pagecache,
|
||||
&info->dfile,
|
||||
page, 0,
|
||||
buff, PAGECACHE_PLAIN_PAGE,
|
||||
PAGECACHE_LOCK_LEFT_UNLOCKED, 0)))
|
||||
if (!(buff= pagecache_read(share->pagecache, &info->dfile,
|
||||
page, 0, 0,
|
||||
PAGECACHE_PLAIN_PAGE, PAGECACHE_LOCK_WRITE,
|
||||
&page_link.link)))
|
||||
DBUG_RETURN(my_errno);
|
||||
|
||||
if (lsn_korr(buff) >= lsn)
|
||||
@ -4802,6 +5117,11 @@ uint _ma_apply_redo_purge_row_head_or_tail(MARIA_HA *info, LSN lsn,
|
||||
Note that in case the page is not anymore a head or tail page
|
||||
a future redo will fix the bitmap.
|
||||
*/
|
||||
pagecache_unlock_by_link(share->pagecache, page_link.link,
|
||||
PAGECACHE_LOCK_WRITE_UNLOCK,
|
||||
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
|
||||
LSN_IMPOSSIBLE);
|
||||
|
||||
if ((buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) == page_type)
|
||||
{
|
||||
empty_space= uint2korr(buff+EMPTY_SPACE_OFFSET);
|
||||
@ -4815,22 +5135,30 @@ uint _ma_apply_redo_purge_row_head_or_tail(MARIA_HA *info, LSN lsn,
|
||||
DBUG_ASSERT((buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) == (uchar) page_type);
|
||||
|
||||
if (delete_dir_entry(buff, block_size, rownr, &empty_space) < 0)
|
||||
DBUG_RETURN(HA_ERR_WRONG_IN_RECORD);
|
||||
goto err;
|
||||
|
||||
lsn_store(buff, lsn);
|
||||
result= 0;
|
||||
if (pagecache_write(share->pagecache,
|
||||
&info->dfile, page, 0,
|
||||
buff, PAGECACHE_PLAIN_PAGE,
|
||||
PAGECACHE_LOCK_LEFT_UNLOCKED,
|
||||
PAGECACHE_PIN_LEFT_UNPINNED,
|
||||
PAGECACHE_LOCK_WRITE_UNLOCK, PAGECACHE_UNPIN,
|
||||
PAGECACHE_WRITE_DELAY, 0))
|
||||
DBUG_RETURN(my_errno);
|
||||
result= my_errno;
|
||||
|
||||
/* This will work even if the page was marked as UNALLOCATED_PAGE */
|
||||
if (_ma_bitmap_set(info, page, page_type == HEAD_PAGE, empty_space))
|
||||
DBUG_RETURN(my_errno);
|
||||
result= my_errno;
|
||||
|
||||
DBUG_RETURN(result);
|
||||
|
||||
err:
|
||||
pagecache_unlock_by_link(share->pagecache, page_link.link,
|
||||
PAGECACHE_LOCK_WRITE_UNLOCK,
|
||||
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
|
||||
LSN_IMPOSSIBLE);
|
||||
DBUG_RETURN(HA_ERR_WRONG_IN_RECORD);
|
||||
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
@ -4872,16 +5200,21 @@ uint _ma_apply_redo_purge_blocks(MARIA_HA *info,
|
||||
|
||||
for (i= 0; i < page_range ; i++)
|
||||
{
|
||||
MARIA_PINNED_PAGE page_link;
|
||||
if (!(buff= pagecache_read(share->pagecache,
|
||||
&info->dfile,
|
||||
page+i, 0,
|
||||
buff, PAGECACHE_PLAIN_PAGE,
|
||||
PAGECACHE_LOCK_LEFT_UNLOCKED, 0)))
|
||||
PAGECACHE_LOCK_WRITE, &page_link.link)))
|
||||
DBUG_RETURN(my_errno);
|
||||
|
||||
if (lsn_korr(buff) >= lsn)
|
||||
{
|
||||
/* Already applied */
|
||||
pagecache_unlock_by_link(share->pagecache, page_link.link,
|
||||
PAGECACHE_LOCK_WRITE_UNLOCK,
|
||||
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
|
||||
LSN_IMPOSSIBLE);
|
||||
continue;
|
||||
}
|
||||
buff[PAGE_TYPE_OFFSET]= UNALLOCATED_PAGE;
|
||||
@ -4889,8 +5222,7 @@ uint _ma_apply_redo_purge_blocks(MARIA_HA *info,
|
||||
if (pagecache_write(share->pagecache,
|
||||
&info->dfile, page+i, 0,
|
||||
buff, PAGECACHE_PLAIN_PAGE,
|
||||
PAGECACHE_LOCK_LEFT_UNLOCKED,
|
||||
PAGECACHE_PIN_LEFT_UNPINNED,
|
||||
PAGECACHE_LOCK_WRITE_UNLOCK, PAGECACHE_UNPIN,
|
||||
PAGECACHE_WRITE_DELAY, 0))
|
||||
DBUG_RETURN(my_errno);
|
||||
}
|
||||
@ -4914,19 +5246,25 @@ my_bool _ma_apply_undo_row_insert(MARIA_HA *info, LSN undo_lsn,
|
||||
ulonglong page;
|
||||
uint rownr;
|
||||
LEX_STRING log_array[TRANSLOG_INTERNAL_PARTS + 1];
|
||||
uchar log_data[LSN_STORE_SIZE + FILEID_STORE_SIZE + 1], *buff;
|
||||
uchar log_data[LSN_STORE_SIZE + FILEID_STORE_SIZE +
|
||||
CLR_TYPE_STORE_SIZE + HA_CHECKSUM_STORE_SIZE],
|
||||
*buff;
|
||||
my_bool res= 1;
|
||||
MARIA_PINNED_PAGE page_link;
|
||||
LSN lsn;
|
||||
MARIA_SHARE *share= info->s;
|
||||
struct st_msg_to_write_hook_for_clr_end msg;
|
||||
DBUG_ENTER("_ma_apply_undo_row_insert");
|
||||
|
||||
page= page_korr(header);
|
||||
rownr= dirpos_korr(header + PAGE_STORE_SIZE);
|
||||
header+= PAGE_STORE_SIZE;
|
||||
rownr= dirpos_korr(header);
|
||||
header+= DIRPOS_STORE_SIZE;
|
||||
DBUG_PRINT("enter", ("Page: %lu rownr: %u", (ulong) page, rownr));
|
||||
|
||||
if (!(buff= pagecache_read(info->s->pagecache,
|
||||
if (!(buff= pagecache_read(share->pagecache,
|
||||
&info->dfile, page, 0,
|
||||
info->buff, info->s->page_type,
|
||||
info->buff, share->page_type,
|
||||
PAGECACHE_LOCK_WRITE,
|
||||
&page_link.link)))
|
||||
DBUG_RETURN(1);
|
||||
@ -4947,14 +5285,24 @@ my_bool _ma_apply_undo_row_insert(MARIA_HA *info, LSN undo_lsn,
|
||||
|
||||
/* undo_lsn must be first for compression to work */
|
||||
lsn_store(log_data, undo_lsn);
|
||||
log_data[LSN_STORE_SIZE + FILEID_STORE_SIZE]= LOGREC_UNDO_ROW_INSERT;
|
||||
clr_type_store(log_data + LSN_STORE_SIZE + FILEID_STORE_SIZE,
|
||||
LOGREC_UNDO_ROW_INSERT);
|
||||
log_array[TRANSLOG_INTERNAL_PARTS + 0].length=
|
||||
sizeof(log_data) - HA_CHECKSUM_STORE_SIZE;
|
||||
msg.undone_record_type= LOGREC_UNDO_ROW_INSERT;
|
||||
msg.previous_undo_lsn= undo_lsn;
|
||||
store_checksum_in_rec(share, msg.checksum_delta,
|
||||
- ha_checksum_korr(header),
|
||||
log_data + LSN_STORE_SIZE + FILEID_STORE_SIZE +
|
||||
CLR_TYPE_STORE_SIZE,
|
||||
log_array[TRANSLOG_INTERNAL_PARTS + 0].length);
|
||||
log_array[TRANSLOG_INTERNAL_PARTS + 0].str= (char*) log_data;
|
||||
log_array[TRANSLOG_INTERNAL_PARTS + 0].length= sizeof(log_data);
|
||||
|
||||
if (translog_write_record(&lsn, LOGREC_CLR_END,
|
||||
info->trn, info, sizeof(log_data),
|
||||
info->trn, info, log_array[TRANSLOG_INTERNAL_PARTS
|
||||
+ 0].length,
|
||||
TRANSLOG_INTERNAL_PARTS + 1, log_array,
|
||||
log_data + LSN_STORE_SIZE))
|
||||
log_data + LSN_STORE_SIZE, &msg))
|
||||
goto err;
|
||||
|
||||
res= 0;
|
||||
@ -4984,6 +5332,16 @@ my_bool _ma_apply_undo_row_delete(MARIA_HA *info, LSN undo_lsn,
|
||||
some buffers to point directly to 'header'
|
||||
*/
|
||||
memcpy(&row, &info->cur_row, sizeof(row));
|
||||
if (share->calc_checksum)
|
||||
{
|
||||
/*
|
||||
We extract the checksum delta here, saving a recomputation in
|
||||
allocate_and_write_block_record(). It's only an optimization.
|
||||
*/
|
||||
row.checksum= - ha_checksum_korr(header);
|
||||
header+= HA_CHECKSUM_STORE_SIZE;
|
||||
}
|
||||
|
||||
null_field_lengths= row.null_field_lengths;
|
||||
blob_lengths= row.blob_lengths;
|
||||
|
||||
@ -5154,18 +5512,25 @@ my_bool _ma_apply_undo_row_update(MARIA_HA *info, LSN undo_lsn,
|
||||
uchar *current_record, *orig_record;
|
||||
int error= 1;
|
||||
MARIA_RECORD_POS record_pos;
|
||||
ha_checksum checksum_delta;
|
||||
DBUG_ENTER("_ma_apply_undo_row_update");
|
||||
|
||||
page= page_korr(header);
|
||||
rownr= dirpos_korr(header + PAGE_STORE_SIZE);
|
||||
header+= PAGE_STORE_SIZE;
|
||||
rownr= dirpos_korr(header);
|
||||
header+= DIRPOS_STORE_SIZE;
|
||||
record_pos= ma_recordpos(page, rownr);
|
||||
DBUG_PRINT("enter", ("Page: %lu rownr: %u", (ulong) page, rownr));
|
||||
|
||||
if (share->calc_checksum)
|
||||
{
|
||||
checksum_delta= ha_checksum_korr(header);
|
||||
header+= HA_CHECKSUM_STORE_SIZE;
|
||||
}
|
||||
/*
|
||||
Set header to point to old field values, generated by
|
||||
fill_update_undo_parts()
|
||||
*/
|
||||
header+= PAGE_STORE_SIZE + DIRPOS_STORE_SIZE;
|
||||
field_length_header= ma_get_length((uchar**) &header);
|
||||
field_length_data= header;
|
||||
header+= field_length_header;
|
||||
@ -5260,14 +5625,14 @@ my_bool _ma_apply_undo_row_update(MARIA_HA *info, LSN undo_lsn,
|
||||
|
||||
if (share->calc_checksum)
|
||||
{
|
||||
info->cur_row.checksum= (*share->calc_checksum)(info, orig_record);
|
||||
info->state->checksum+= (info->cur_row.checksum -
|
||||
(*share->calc_checksum)(info, current_record));
|
||||
info->new_row.checksum= checksum_delta +
|
||||
(info->cur_row.checksum= (*share->calc_checksum)(info, orig_record));
|
||||
/* verify that record's content is sane */
|
||||
DBUG_ASSERT(info->new_row.checksum ==
|
||||
(*share->calc_checksum)(info, current_record));
|
||||
}
|
||||
|
||||
/*
|
||||
Now records are up to date, execute the update to original values
|
||||
*/
|
||||
/* Now records are up to date, execute the update to original values */
|
||||
if (_ma_update_block_record2(info, record_pos, current_record, orig_record,
|
||||
undo_lsn))
|
||||
goto err;
|
||||
|
@ -193,3 +193,28 @@ my_bool _ma_apply_undo_row_delete(MARIA_HA *info, LSN undo_lsn,
|
||||
const uchar *header, size_t length);
|
||||
my_bool _ma_apply_undo_row_update(MARIA_HA *info, LSN undo_lsn,
|
||||
const uchar *header, size_t length);
|
||||
|
||||
my_bool write_hook_for_redo(enum translog_record_type type,
|
||||
TRN *trn, MARIA_HA *tbl_info, LSN *lsn,
|
||||
void *hook_arg);
|
||||
my_bool write_hook_for_undo(enum translog_record_type type,
|
||||
TRN *trn, MARIA_HA *tbl_info, LSN *lsn,
|
||||
void *hook_arg);
|
||||
my_bool write_hook_for_redo_delete_all(enum translog_record_type type,
|
||||
TRN *trn, MARIA_HA *tbl_info,
|
||||
LSN *lsn, void *hook_arg);
|
||||
my_bool write_hook_for_undo_row_insert(enum translog_record_type type,
|
||||
TRN *trn, MARIA_HA *tbl_info,
|
||||
LSN *lsn, void *hook_arg);
|
||||
my_bool write_hook_for_undo_row_delete(enum translog_record_type type,
|
||||
TRN *trn, MARIA_HA *tbl_info,
|
||||
LSN *lsn, void *hook_arg);
|
||||
my_bool write_hook_for_undo_row_update(enum translog_record_type type,
|
||||
TRN *trn, MARIA_HA *tbl_info,
|
||||
LSN *lsn, void *hook_arg);
|
||||
my_bool write_hook_for_clr_end(enum translog_record_type type,
|
||||
TRN *trn, MARIA_HA *tbl_info, LSN *lsn,
|
||||
void *hook_arg);
|
||||
my_bool write_hook_for_file_id(enum translog_record_type type,
|
||||
TRN *trn, MARIA_HA *tbl_info, LSN *lsn,
|
||||
void *hook_arg);
|
||||
|
@ -5603,11 +5603,10 @@ static int write_log_record_for_repair(const HA_CHECK *param, MARIA_HA *info)
|
||||
record).
|
||||
*/
|
||||
LEX_STRING log_array[TRANSLOG_INTERNAL_PARTS + 1];
|
||||
uchar log_data[LSN_STORE_SIZE];
|
||||
uchar log_data[FILEID_STORE_SIZE + 4];
|
||||
LSN lsn;
|
||||
compile_time_assert(LSN_STORE_SIZE >= (FILEID_STORE_SIZE + 4));
|
||||
log_array[TRANSLOG_INTERNAL_PARTS + 0].str= (char*) log_data;
|
||||
log_array[TRANSLOG_INTERNAL_PARTS + 0].length= FILEID_STORE_SIZE + 4;
|
||||
log_array[TRANSLOG_INTERNAL_PARTS + 0].length= sizeof(log_data);
|
||||
/*
|
||||
testflag gives an idea of what REPAIR did (in particular T_QUICK
|
||||
or not: did it touch the data file or not?).
|
||||
@ -5615,10 +5614,9 @@ static int write_log_record_for_repair(const HA_CHECK *param, MARIA_HA *info)
|
||||
int4store(log_data + FILEID_STORE_SIZE, param->testflag);
|
||||
if (unlikely(translog_write_record(&lsn, LOGREC_REDO_REPAIR_TABLE,
|
||||
&dummy_transaction_object, info,
|
||||
log_array[TRANSLOG_INTERNAL_PARTS +
|
||||
0].length,
|
||||
sizeof(log_data),
|
||||
sizeof(log_array)/sizeof(log_array[0]),
|
||||
log_array, log_data) ||
|
||||
log_array, log_data, NULL) ||
|
||||
translog_flush(lsn)))
|
||||
return 1;
|
||||
/*
|
||||
|
106
storage/maria/ma_check_standalone.h
Normal file
106
storage/maria/ma_check_standalone.h
Normal file
@ -0,0 +1,106 @@
|
||||
/* Copyright (C) 2007 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
/*
|
||||
All standalone programs which need to use functions from ma_check.c
|
||||
(like maria_repair()) must define their version of _ma_killed_ptr()
|
||||
and _ma_check_print_info|warning|error(). Indeed, linking with ma_check.o
|
||||
brings in the dependencies of ma_check.o which are definitions of the above
|
||||
functions; if the program does not define them then the ones of
|
||||
ha_maria.o are used i.e. ha_maria.o is linked into the program, and this
|
||||
brings dependencies of ha_maria.o on mysqld.o into the program's linking
|
||||
which thus fails, as the program is not linked with mysqld.o.
|
||||
This file contains the versions of these functions used by maria_chk and
|
||||
maria_read_log.
|
||||
*/
|
||||
|
||||
/*
|
||||
Check if check/repair operation was killed by a signal
|
||||
*/
|
||||
|
||||
static int not_killed= 0;
|
||||
|
||||
volatile int *_ma_killed_ptr(HA_CHECK *param __attribute__((unused)))
|
||||
{
|
||||
return ¬_killed; /* always NULL */
|
||||
}
|
||||
|
||||
/* print warnings and errors */
|
||||
/* VARARGS */
|
||||
|
||||
void _ma_check_print_info(HA_CHECK *param __attribute__((unused)),
|
||||
const char *fmt,...)
|
||||
{
|
||||
va_list args;
|
||||
DBUG_ENTER("_ma_check_print_info");
|
||||
DBUG_PRINT("enter", ("format: %s", fmt));
|
||||
|
||||
va_start(args,fmt);
|
||||
VOID(vfprintf(stdout, fmt, args));
|
||||
VOID(fputc('\n',stdout));
|
||||
va_end(args);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/* VARARGS */
|
||||
|
||||
void _ma_check_print_warning(HA_CHECK *param, const char *fmt,...)
|
||||
{
|
||||
va_list args;
|
||||
DBUG_ENTER("_ma_check_print_warning");
|
||||
DBUG_PRINT("enter", ("format: %s", fmt));
|
||||
|
||||
fflush(stdout);
|
||||
if (!param->warning_printed && !param->error_printed)
|
||||
{
|
||||
if (param->testflag & T_SILENT)
|
||||
fprintf(stderr,"%s: MARIA file %s\n",my_progname_short,
|
||||
param->isam_file_name);
|
||||
param->out_flag|= O_DATA_LOST;
|
||||
}
|
||||
param->warning_printed=1;
|
||||
va_start(args,fmt);
|
||||
fprintf(stderr,"%s: warning: ",my_progname_short);
|
||||
VOID(vfprintf(stderr, fmt, args));
|
||||
VOID(fputc('\n',stderr));
|
||||
fflush(stderr);
|
||||
va_end(args);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/* VARARGS */
|
||||
|
||||
void _ma_check_print_error(HA_CHECK *param, const char *fmt,...)
|
||||
{
|
||||
va_list args;
|
||||
DBUG_ENTER("_ma_check_print_error");
|
||||
DBUG_PRINT("enter", ("format: %s", fmt));
|
||||
|
||||
fflush(stdout);
|
||||
if (!param->warning_printed && !param->error_printed)
|
||||
{
|
||||
if (param->testflag & T_SILENT)
|
||||
fprintf(stderr,"%s: MARIA file %s\n",my_progname_short,param->isam_file_name);
|
||||
param->out_flag|= O_DATA_LOST;
|
||||
}
|
||||
param->error_printed|=1;
|
||||
va_start(args,fmt);
|
||||
fprintf(stderr,"%s: error: ",my_progname_short);
|
||||
VOID(vfprintf(stderr, fmt, args));
|
||||
VOID(fputc('\n',stderr));
|
||||
fflush(stderr);
|
||||
va_end(args);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
@ -266,7 +266,7 @@ static int really_execute_checkpoint(void)
|
||||
&dummy_transaction_object, NULL,
|
||||
total_rec_length,
|
||||
sizeof(log_array)/sizeof(log_array[0]),
|
||||
log_array, NULL) ||
|
||||
log_array, NULL, NULL) ||
|
||||
translog_flush(lsn)))
|
||||
goto err;
|
||||
|
||||
@ -652,7 +652,7 @@ pthread_handler_t ma_checkpoint_background(void *arg __attribute__((unused)))
|
||||
break;
|
||||
#if 0 /* good for testing, to do a lot of checkpoints, finds a lot of bugs */
|
||||
pthread_mutex_unlock(&LOCK_checkpoint);
|
||||
my_sleep(100000); // a tenth of a second
|
||||
my_sleep(100000); /* a tenth of a second */
|
||||
pthread_mutex_lock(&LOCK_checkpoint);
|
||||
#else
|
||||
/* To have a killable sleep, we use timedwait like our SQL GET_LOCK() */
|
||||
@ -893,7 +893,7 @@ static int collect_tables(LEX_STRING *str, LSN checkpoint_start_log_horizon)
|
||||
|
||||
filter_param.pages_covered_by_bitmap= share->bitmap.pages_covered;
|
||||
/* OS file descriptors are ints which we stored in 4 bytes */
|
||||
compile_time_assert(sizeof(int) == 4);
|
||||
compile_time_assert(sizeof(int) <= 4);
|
||||
pthread_mutex_lock(&share->intern_lock);
|
||||
/*
|
||||
Tables in a normal state have their two file descriptors open.
|
||||
|
@ -64,7 +64,7 @@ int ma_commit(TRN *trn)
|
||||
res= (translog_write_record(&commit_lsn, LOGREC_COMMIT,
|
||||
trn, NULL, 0,
|
||||
sizeof(log_array)/sizeof(log_array[0]),
|
||||
log_array, NULL) ||
|
||||
log_array, NULL, NULL) ||
|
||||
translog_flush(commit_lsn) ||
|
||||
trnman_commit_trn(trn));
|
||||
/*
|
||||
|
@ -998,7 +998,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
|
||||
&dummy_transaction_object, NULL,
|
||||
total_rec_length,
|
||||
sizeof(log_array)/sizeof(log_array[0]),
|
||||
log_array, NULL) ||
|
||||
log_array, NULL, NULL) ||
|
||||
translog_flush(lsn)))
|
||||
goto err;
|
||||
/*
|
||||
|
@ -44,10 +44,10 @@ int maria_delete(MARIA_HA *info,const uchar *record)
|
||||
/* Test if record is in datafile */
|
||||
|
||||
DBUG_EXECUTE_IF("maria_pretend_crashed_table_on_usage",
|
||||
maria_print_error(info->s, HA_ERR_CRASHED);
|
||||
maria_print_error(share, HA_ERR_CRASHED);
|
||||
DBUG_RETURN(my_errno= HA_ERR_CRASHED););
|
||||
DBUG_EXECUTE_IF("my_error_test_undefined_error",
|
||||
maria_print_error(info->s, INT_MAX);
|
||||
maria_print_error(share, INT_MAX);
|
||||
DBUG_RETURN(my_errno= INT_MAX););
|
||||
if (!(info->update & HA_STATE_AKTIV))
|
||||
{
|
||||
@ -70,17 +70,17 @@ int maria_delete(MARIA_HA *info,const uchar *record)
|
||||
old_key= info->lastkey2;
|
||||
for (i=0 ; i < share->base.keys ; i++ )
|
||||
{
|
||||
if (maria_is_key_active(info->s->state.key_map, i))
|
||||
if (maria_is_key_active(share->state.key_map, i))
|
||||
{
|
||||
info->s->keyinfo[i].version++;
|
||||
if (info->s->keyinfo[i].flag & HA_FULLTEXT )
|
||||
share->keyinfo[i].version++;
|
||||
if (share->keyinfo[i].flag & HA_FULLTEXT )
|
||||
{
|
||||
if (_ma_ft_del(info, i, old_key, record, info->cur_row.lastpos))
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (info->s->keyinfo[i].ck_delete(info,i,old_key,
|
||||
if (share->keyinfo[i].ck_delete(info,i,old_key,
|
||||
_ma_make_key(info, i, old_key,
|
||||
record,
|
||||
info->cur_row.lastpos)))
|
||||
@ -91,19 +91,20 @@ int maria_delete(MARIA_HA *info,const uchar *record)
|
||||
}
|
||||
}
|
||||
|
||||
if (share->calc_checksum)
|
||||
{
|
||||
/*
|
||||
We can't use the row based checksum as this doesn't have enough
|
||||
precision.
|
||||
*/
|
||||
info->cur_row.checksum= (*share->calc_checksum)(info, record);
|
||||
}
|
||||
|
||||
if ((*share->delete_record)(info, record))
|
||||
goto err; /* Remove record from database */
|
||||
|
||||
/*
|
||||
We can't use the row based checksum as this doesn't have enough
|
||||
precision.
|
||||
*/
|
||||
if (info->s->calc_checksum)
|
||||
{
|
||||
info->cur_row.checksum= (*info->s->calc_checksum)(info,record);
|
||||
info->state->checksum-= info->cur_row.checksum;
|
||||
}
|
||||
|
||||
info->state->checksum+= - !share->now_transactional *
|
||||
info->cur_row.checksum;
|
||||
info->update= HA_STATE_CHANGED+HA_STATE_DELETED+HA_STATE_ROW_CHANGED;
|
||||
info->state->records-= !share->now_transactional;
|
||||
share->state.changed|= STATE_NOT_OPTIMIZED_ROWS;
|
||||
@ -113,8 +114,8 @@ int maria_delete(MARIA_HA *info,const uchar *record)
|
||||
allow_break(); /* Allow SIGHUP & SIGINT */
|
||||
if (info->invalidator != 0)
|
||||
{
|
||||
DBUG_PRINT("info", ("invalidator... '%s' (delete)", info->s->open_file_name));
|
||||
(*info->invalidator)(info->s->open_file_name);
|
||||
DBUG_PRINT("info", ("invalidator... '%s' (delete)", share->open_file_name));
|
||||
(*info->invalidator)(share->open_file_name);
|
||||
info->invalidator=0;
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
@ -124,7 +125,7 @@ err:
|
||||
mi_sizestore(lastpos, info->cur_row.lastpos);
|
||||
if (save_errno != HA_ERR_RECORD_CHANGED)
|
||||
{
|
||||
maria_print_error(info->s, HA_ERR_CRASHED);
|
||||
maria_print_error(share, HA_ERR_CRASHED);
|
||||
maria_mark_crashed(info); /* mark table crashed */
|
||||
}
|
||||
VOID(_ma_writeinfo(info,WRITEINFO_UPDATE_KEYFILE));
|
||||
@ -133,7 +134,7 @@ err:
|
||||
my_errno=save_errno;
|
||||
if (save_errno == HA_ERR_KEY_NOT_FOUND)
|
||||
{
|
||||
maria_print_error(info->s, HA_ERR_CRASHED);
|
||||
maria_print_error(share, HA_ERR_CRASHED);
|
||||
my_errno=HA_ERR_CRASHED;
|
||||
}
|
||||
|
||||
|
@ -64,14 +64,15 @@ int maria_delete_all_rows(MARIA_HA *info)
|
||||
if (unlikely(translog_write_record(&lsn, LOGREC_REDO_DELETE_ALL,
|
||||
info->trn, info, 0,
|
||||
sizeof(log_array)/sizeof(log_array[0]),
|
||||
log_array, log_data) ||
|
||||
log_array, log_data, NULL) ||
|
||||
translog_flush(lsn)))
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
For recovery it matters that this is called after writing the log record,
|
||||
so that resetting state.records actually happens under log's mutex.
|
||||
so that resetting state.records and state.checksum actually happens under
|
||||
log's mutex.
|
||||
*/
|
||||
_ma_reset_status(info);
|
||||
|
||||
@ -147,10 +148,6 @@ void _ma_reset_status(MARIA_HA *info)
|
||||
info->state->key_file_length= share->base.keystart;
|
||||
info->state->data_file_length= 0;
|
||||
info->state->empty= info->state->key_empty= 0;
|
||||
/**
|
||||
@todo RECOVERY BUG
|
||||
the line below must happen under log's mutex when writing the REDO
|
||||
*/
|
||||
info->state->checksum= 0;
|
||||
|
||||
/* Drop the delete key chain. */
|
||||
|
@ -92,7 +92,7 @@ int maria_delete_table(const char *name)
|
||||
log_array[TRANSLOG_INTERNAL_PARTS +
|
||||
0].length,
|
||||
sizeof(log_array)/sizeof(log_array[0]),
|
||||
log_array, NULL) ||
|
||||
log_array, NULL, NULL) ||
|
||||
translog_flush(lsn)))
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -48,6 +48,7 @@ typedef uint16 SHORT_TRANSACTION_ID;
|
||||
|
||||
struct st_maria_info;
|
||||
|
||||
/* Changing one of the "SIZE" below will break backward-compatibility! */
|
||||
/* Length of CRC at end of pages */
|
||||
#define CRC_LENGTH 4
|
||||
/* Size of file id in logs */
|
||||
@ -57,16 +58,23 @@ struct st_maria_info;
|
||||
/* Size of page ranges in log */
|
||||
#define PAGERANGE_STORE_SIZE ROW_EXTENT_COUNT_SIZE
|
||||
#define DIRPOS_STORE_SIZE 1
|
||||
#define CLR_TYPE_STORE_SIZE 1
|
||||
/* If table has live checksum we store its changes in UNDOs */
|
||||
#define HA_CHECKSUM_STORE_SIZE 4
|
||||
|
||||
/* Store methods to match the above sizes */
|
||||
#define fileid_store(T,A) int2store(T,A)
|
||||
#define page_store(T,A) int5store(T,A)
|
||||
#define dirpos_store(T,A) ((*(uchar*) (T)) = A)
|
||||
#define pagerange_store(T,A) int2store(T,A)
|
||||
#define clr_type_store(T,A) ((*(uchar*) (T)) = A)
|
||||
#define ha_checksum_store(T,A) int4store(T,A)
|
||||
#define fileid_korr(P) uint2korr(P)
|
||||
#define page_korr(P) uint5korr(P)
|
||||
#define dirpos_korr(P) ((P)[0])
|
||||
#define pagerange_korr(P) uint2korr(P)
|
||||
#define clr_type_korr(P) ((P)[0])
|
||||
#define ha_checksum_korr(P) uint4korr(P)
|
||||
|
||||
/*
|
||||
Length of disk drive sector size (we assume that writing it
|
||||
@ -182,10 +190,14 @@ typedef struct st_translog_scanner_data
|
||||
TRANSLOG_ADDRESS horizon;
|
||||
TRANSLOG_ADDRESS last_file_page; /* Last page on in this file */
|
||||
uchar *page; /* page content pointer */
|
||||
/* direct link on the current page or NULL if not supported/requested */
|
||||
PAGECACHE_BLOCK_LINK *direct_link;
|
||||
/* offset of the chunk in the page */
|
||||
translog_size_t page_offset;
|
||||
/* set horizon only once at init */
|
||||
my_bool fixed_horizon;
|
||||
/* try to get direct link on the page if it is possible */
|
||||
my_bool use_direct_link;
|
||||
} TRANSLOG_SCANNER_DATA;
|
||||
|
||||
|
||||
@ -226,7 +238,8 @@ translog_write_record(LSN *lsn, enum translog_record_type type,
|
||||
struct st_transaction *trn,
|
||||
struct st_maria_info *tbl_info,
|
||||
translog_size_t rec_len, uint part_no,
|
||||
LEX_STRING *parts_data, uchar *store_share_id);
|
||||
LEX_STRING *parts_data, uchar *store_share_id,
|
||||
void *hook_arg);
|
||||
|
||||
extern void translog_destroy();
|
||||
|
||||
@ -245,7 +258,9 @@ extern my_bool translog_flush(LSN lsn);
|
||||
|
||||
extern my_bool translog_init_scanner(LSN lsn,
|
||||
my_bool fixed_horizon,
|
||||
struct st_translog_scanner_data *scanner);
|
||||
struct st_translog_scanner_data *scanner,
|
||||
my_bool use_direct_link);
|
||||
extern void translog_destroy_scanner(TRANSLOG_SCANNER_DATA *scanner);
|
||||
|
||||
extern int translog_read_next_record_header(TRANSLOG_SCANNER_DATA *scanner,
|
||||
TRANSLOG_HEADER_BUFFER *buff);
|
||||
@ -293,12 +308,11 @@ struct st_translog_parts
|
||||
|
||||
typedef my_bool(*prewrite_rec_hook) (enum translog_record_type type,
|
||||
TRN *trn, struct st_maria_info *tbl_info,
|
||||
struct st_translog_parts *parts);
|
||||
void *hook_arg);
|
||||
|
||||
typedef my_bool(*inwrite_rec_hook) (enum translog_record_type type,
|
||||
TRN *trn, struct st_maria_info *tbl_info,
|
||||
LSN *lsn,
|
||||
struct st_translog_parts *parts);
|
||||
LSN *lsn, void *hook_arg);
|
||||
|
||||
typedef uint16(*read_rec_hook) (enum translog_record_type type,
|
||||
uint16 read_length, uchar *read_buff,
|
||||
|
@ -58,7 +58,7 @@ if (pos > end_pos) \
|
||||
** In MySQL the server will handle version issues.
|
||||
******************************************************************************/
|
||||
|
||||
MARIA_HA *_ma_test_if_reopen(char *filename)
|
||||
MARIA_HA *_ma_test_if_reopen(const char *filename)
|
||||
{
|
||||
LIST *pos;
|
||||
|
||||
@ -177,7 +177,7 @@ static MARIA_HA *maria_clone_internal(MARIA_SHARE *share, int mode,
|
||||
share->delay_key_write=1;
|
||||
|
||||
info.state= &share->state.state; /* Change global values by default */
|
||||
if (!share->base.born_transactional) /* but for transactional ones ... */
|
||||
if (!share->base.born_transactional) /* For transactional ones ... */
|
||||
info.trn= &dummy_transaction_object; /* ... force crash if no trn given */
|
||||
pthread_mutex_unlock(&share->intern_lock);
|
||||
|
||||
@ -1002,7 +1002,9 @@ uint _ma_state_info_write(MARIA_SHARE *share, uint pWrite)
|
||||
if (pWrite & 4)
|
||||
pthread_mutex_lock(&share->intern_lock);
|
||||
else if (maria_multi_threaded)
|
||||
{
|
||||
safe_mutex_assert_owner(&share->intern_lock);
|
||||
}
|
||||
if (share->base.born_transactional && translog_inited &&
|
||||
!maria_in_recovery)
|
||||
{
|
||||
|
@ -96,7 +96,7 @@
|
||||
#define PCBLOCK_INFO(B) \
|
||||
DBUG_PRINT("info", \
|
||||
("block: 0x%lx file: %lu page: %lu s: %0x hshL: 0x%lx req: %u/%u " \
|
||||
"wrlocks: %u", \
|
||||
"wrlocks: %u pins: %u", \
|
||||
(ulong)(B), \
|
||||
(ulong)((B)->hash_link ? \
|
||||
(B)->hash_link->file.file : \
|
||||
@ -110,7 +110,8 @@
|
||||
(uint)((B)->hash_link ? \
|
||||
(B)->hash_link->requests : \
|
||||
0), \
|
||||
block->wlocks))
|
||||
block->wlocks, \
|
||||
(uint)(B)->pins))
|
||||
|
||||
/* TODO: put it to my_static.c */
|
||||
my_bool my_disable_flush_pagecache_blocks= 0;
|
||||
@ -457,8 +458,10 @@ error:
|
||||
#define FLUSH_CACHE 2000 /* sort this many blocks at once */
|
||||
|
||||
static void free_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block);
|
||||
#ifndef DBUG_OFF
|
||||
static void test_key_cache(PAGECACHE *pagecache,
|
||||
const char *where, my_bool lock);
|
||||
#endif
|
||||
|
||||
#define PAGECACHE_HASH(p, f, pos) (((ulong) (pos) + \
|
||||
(ulong) (f).file) & (p->hash_entries-1))
|
||||
@ -655,11 +658,11 @@ static inline uint next_power(uint value)
|
||||
|
||||
*/
|
||||
|
||||
int init_pagecache(PAGECACHE *pagecache, size_t use_mem,
|
||||
uint division_limit, uint age_threshold,
|
||||
uint block_size)
|
||||
ulong init_pagecache(PAGECACHE *pagecache, size_t use_mem,
|
||||
uint division_limit, uint age_threshold,
|
||||
uint block_size)
|
||||
{
|
||||
uint blocks, hash_links, length;
|
||||
ulong blocks, hash_links, length;
|
||||
int error;
|
||||
DBUG_ENTER("init_pagecache");
|
||||
DBUG_ASSERT(block_size >= 512);
|
||||
@ -689,10 +692,10 @@ int init_pagecache(PAGECACHE *pagecache, size_t use_mem,
|
||||
block_size));
|
||||
DBUG_ASSERT(((uint)(1 << pagecache->shift)) == block_size);
|
||||
|
||||
blocks= (int) (use_mem / (sizeof(PAGECACHE_BLOCK_LINK) +
|
||||
2 * sizeof(PAGECACHE_HASH_LINK) +
|
||||
sizeof(PAGECACHE_HASH_LINK*) *
|
||||
5/4 + block_size));
|
||||
blocks= (ulong) (use_mem / (sizeof(PAGECACHE_BLOCK_LINK) +
|
||||
2 * sizeof(PAGECACHE_HASH_LINK) +
|
||||
sizeof(PAGECACHE_HASH_LINK*) *
|
||||
5/4 + block_size));
|
||||
/*
|
||||
We need to support page cache with just one block to be able to do
|
||||
scanning of rows-in-block files
|
||||
@ -714,7 +717,7 @@ int init_pagecache(PAGECACHE *pagecache, size_t use_mem,
|
||||
ALIGN_SIZE(hash_links * sizeof(PAGECACHE_HASH_LINK)) +
|
||||
ALIGN_SIZE(sizeof(PAGECACHE_HASH_LINK*) *
|
||||
pagecache->hash_entries))) +
|
||||
(((ulong) blocks) << pagecache->shift) > use_mem)
|
||||
(blocks << pagecache->shift) > use_mem)
|
||||
blocks--;
|
||||
/* Allocate memory for cache page buffers */
|
||||
if ((pagecache->block_mem=
|
||||
@ -726,7 +729,7 @@ int init_pagecache(PAGECACHE *pagecache, size_t use_mem,
|
||||
For each block 2 hash links are allocated
|
||||
*/
|
||||
if ((pagecache->block_root=
|
||||
(PAGECACHE_BLOCK_LINK*) my_malloc((uint) length, MYF(0))))
|
||||
(PAGECACHE_BLOCK_LINK*) my_malloc((size_t) length, MYF(0))))
|
||||
break;
|
||||
my_large_free(pagecache->block_mem, MYF(0));
|
||||
pagecache->block_mem= 0;
|
||||
@ -738,8 +741,8 @@ int init_pagecache(PAGECACHE *pagecache, size_t use_mem,
|
||||
}
|
||||
blocks= blocks / 4*3;
|
||||
}
|
||||
pagecache->blocks_unused= (ulong) blocks;
|
||||
pagecache->disk_blocks= (int) blocks;
|
||||
pagecache->blocks_unused= blocks;
|
||||
pagecache->disk_blocks= (long) blocks;
|
||||
pagecache->hash_links= hash_links;
|
||||
pagecache->hash_root=
|
||||
(PAGECACHE_HASH_LINK**) ((char*) pagecache->block_root +
|
||||
@ -781,8 +784,8 @@ int init_pagecache(PAGECACHE *pagecache, size_t use_mem,
|
||||
pagecache->waiting_for_hash_link.last_thread= NULL;
|
||||
pagecache->waiting_for_block.last_thread= NULL;
|
||||
DBUG_PRINT("exit",
|
||||
("disk_blocks: %d block_root: 0x%lx hash_entries: %d\
|
||||
hash_root: 0x%lx hash_links: %d hash_link_root: 0x%lx",
|
||||
("disk_blocks: %ld block_root: 0x%lx hash_entries: %ld\
|
||||
hash_root: 0x%lx hash_links: %ld hash_link_root: 0x%lx",
|
||||
pagecache->disk_blocks, (long) pagecache->block_root,
|
||||
pagecache->hash_entries, (long) pagecache->hash_root,
|
||||
pagecache->hash_links, (long) pagecache->hash_link_root));
|
||||
@ -795,7 +798,7 @@ int init_pagecache(PAGECACHE *pagecache, size_t use_mem,
|
||||
}
|
||||
|
||||
pagecache->blocks= pagecache->disk_blocks > 0 ? pagecache->disk_blocks : 0;
|
||||
DBUG_RETURN((int) pagecache->disk_blocks);
|
||||
DBUG_RETURN((ulong) pagecache->disk_blocks);
|
||||
|
||||
err:
|
||||
error= my_errno;
|
||||
@ -886,11 +889,11 @@ static int flush_all_key_blocks(PAGECACHE *pagecache)
|
||||
So we disable it for now.
|
||||
*/
|
||||
#if NOT_USED /* keep disabled until code is fixed see above !! */
|
||||
int resize_pagecache(PAGECACHE *pagecache,
|
||||
size_t use_mem, uint division_limit,
|
||||
uint age_threshold)
|
||||
ulong resize_pagecache(PAGECACHE *pagecache,
|
||||
size_t use_mem, uint division_limit,
|
||||
uint age_threshold)
|
||||
{
|
||||
int blocks;
|
||||
ulong blocks;
|
||||
#ifdef THREAD
|
||||
struct st_my_thread_var *thread;
|
||||
WQUEUE *wqueue;
|
||||
@ -1281,8 +1284,10 @@ static void unlink_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block)
|
||||
DBUG_ENTER("unlink_block");
|
||||
DBUG_PRINT("unlink_block", ("unlink 0x%lx", (ulong)block));
|
||||
if (block->next_used == block)
|
||||
{
|
||||
/* The list contains only one member */
|
||||
pagecache->used_last= pagecache->used_ins= NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
block->next_used->prev_used= block->prev_used;
|
||||
@ -2660,13 +2665,12 @@ void pagecache_unpin(PAGECACHE *pagecache,
|
||||
*/
|
||||
|
||||
void pagecache_unlock_by_link(PAGECACHE *pagecache,
|
||||
PAGECACHE_PAGE_LINK *link,
|
||||
PAGECACHE_BLOCK_LINK *block,
|
||||
enum pagecache_page_lock lock,
|
||||
enum pagecache_page_pin pin,
|
||||
LSN first_REDO_LSN_for_page,
|
||||
LSN lsn)
|
||||
{
|
||||
PAGECACHE_BLOCK_LINK *block= (PAGECACHE_BLOCK_LINK *)link;
|
||||
DBUG_ENTER("pagecache_unlock_by_link");
|
||||
DBUG_PRINT("enter", ("block: 0x%lx fd: %u page: %lu %s %s",
|
||||
(ulong) block,
|
||||
@ -2751,10 +2755,9 @@ void pagecache_unlock_by_link(PAGECACHE *pagecache,
|
||||
*/
|
||||
|
||||
void pagecache_unpin_by_link(PAGECACHE *pagecache,
|
||||
PAGECACHE_PAGE_LINK *link,
|
||||
PAGECACHE_BLOCK_LINK *block,
|
||||
LSN lsn)
|
||||
{
|
||||
PAGECACHE_BLOCK_LINK *block= (PAGECACHE_BLOCK_LINK *)link;
|
||||
DBUG_ENTER("pagecache_unpin_by_link");
|
||||
DBUG_PRINT("enter", ("block: 0x%lx fd: %u page: %lu",
|
||||
(ulong) block,
|
||||
@ -2819,16 +2822,28 @@ void pagecache_unpin_by_link(PAGECACHE *pagecache,
|
||||
|
||||
Pin will be chosen according to lock parameter (see lock_to_pin)
|
||||
*/
|
||||
static enum pagecache_page_pin lock_to_pin[]=
|
||||
static enum pagecache_page_pin lock_to_pin[2][8]=
|
||||
{
|
||||
PAGECACHE_PIN_LEFT_UNPINNED /*PAGECACHE_LOCK_LEFT_UNLOCKED*/,
|
||||
PAGECACHE_PIN_LEFT_UNPINNED /*PAGECACHE_LOCK_LEFT_READLOCKED*/,
|
||||
PAGECACHE_PIN_LEFT_PINNED /*PAGECACHE_LOCK_LEFT_WRITELOCKED*/,
|
||||
PAGECACHE_PIN_LEFT_UNPINNED /*PAGECACHE_LOCK_READ*/,
|
||||
PAGECACHE_PIN /*PAGECACHE_LOCK_WRITE*/,
|
||||
PAGECACHE_PIN_LEFT_UNPINNED /*PAGECACHE_LOCK_READ_UNLOCK*/,
|
||||
PAGECACHE_UNPIN /*PAGECACHE_LOCK_WRITE_UNLOCK*/,
|
||||
PAGECACHE_UNPIN /*PAGECACHE_LOCK_WRITE_TO_READ*/
|
||||
{
|
||||
PAGECACHE_PIN_LEFT_UNPINNED /*PAGECACHE_LOCK_LEFT_UNLOCKED*/,
|
||||
PAGECACHE_PIN_LEFT_UNPINNED /*PAGECACHE_LOCK_LEFT_READLOCKED*/,
|
||||
PAGECACHE_PIN_LEFT_PINNED /*PAGECACHE_LOCK_LEFT_WRITELOCKED*/,
|
||||
PAGECACHE_PIN_LEFT_UNPINNED /*PAGECACHE_LOCK_READ*/,
|
||||
PAGECACHE_PIN /*PAGECACHE_LOCK_WRITE*/,
|
||||
PAGECACHE_PIN_LEFT_UNPINNED /*PAGECACHE_LOCK_READ_UNLOCK*/,
|
||||
PAGECACHE_UNPIN /*PAGECACHE_LOCK_WRITE_UNLOCK*/,
|
||||
PAGECACHE_UNPIN /*PAGECACHE_LOCK_WRITE_TO_READ*/
|
||||
},
|
||||
{
|
||||
PAGECACHE_PIN_LEFT_UNPINNED /*PAGECACHE_LOCK_LEFT_UNLOCKED*/,
|
||||
PAGECACHE_PIN_LEFT_PINNED /*PAGECACHE_LOCK_LEFT_READLOCKED*/,
|
||||
PAGECACHE_PIN_LEFT_PINNED /*PAGECACHE_LOCK_LEFT_WRITELOCKED*/,
|
||||
PAGECACHE_PIN /*PAGECACHE_LOCK_READ*/,
|
||||
PAGECACHE_PIN /*PAGECACHE_LOCK_WRITE*/,
|
||||
PAGECACHE_PIN_LEFT_UNPINNED /*PAGECACHE_LOCK_READ_UNLOCK*/,
|
||||
PAGECACHE_UNPIN /*PAGECACHE_LOCK_WRITE_UNLOCK*/,
|
||||
PAGECACHE_PIN_LEFT_PINNED /*PAGECACHE_LOCK_WRITE_TO_READ*/
|
||||
}
|
||||
};
|
||||
|
||||
uchar *pagecache_valid_read(PAGECACHE *pagecache,
|
||||
@ -2838,24 +2853,27 @@ uchar *pagecache_valid_read(PAGECACHE *pagecache,
|
||||
uchar *buff,
|
||||
enum pagecache_page_type type,
|
||||
enum pagecache_page_lock lock,
|
||||
PAGECACHE_PAGE_LINK *link,
|
||||
PAGECACHE_BLOCK_LINK **link,
|
||||
pagecache_disk_read_validator validator,
|
||||
uchar* validator_data)
|
||||
{
|
||||
int error= 0;
|
||||
enum pagecache_page_pin pin= lock_to_pin[lock];
|
||||
PAGECACHE_PAGE_LINK fake_link;
|
||||
enum pagecache_page_pin pin= lock_to_pin[test(buff==0)][lock];
|
||||
PAGECACHE_BLOCK_LINK *fake_link;
|
||||
DBUG_ENTER("pagecache_valid_read");
|
||||
DBUG_PRINT("enter", ("fd: %u page: %lu level: %u t:%s %s %s",
|
||||
(uint) file->file, (ulong) pageno, level,
|
||||
DBUG_PRINT("enter", ("fd: %u page: %lu buffer: 0x%lx level: %u "
|
||||
"t:%s %s %s",
|
||||
(uint) file->file, (ulong) pageno,
|
||||
(ulong) buff, level,
|
||||
page_cache_page_type_str[type],
|
||||
page_cache_page_lock_str[lock],
|
||||
page_cache_page_pin_str[pin]));
|
||||
DBUG_ASSERT(buff != 0 || (buff == 0 && (pin == PAGECACHE_PIN ||
|
||||
pin == PAGECACHE_PIN_LEFT_PINNED)));
|
||||
|
||||
if (!link)
|
||||
link= &fake_link;
|
||||
else
|
||||
*link= 0;
|
||||
*link= 0; /* Catch errors */
|
||||
|
||||
restart:
|
||||
|
||||
@ -2909,19 +2927,25 @@ restart:
|
||||
goto restart;
|
||||
}
|
||||
|
||||
if (! ((status= block->status) & PCBLOCK_ERROR))
|
||||
status= block->status;
|
||||
if (!buff)
|
||||
buff= block->buffer;
|
||||
else
|
||||
{
|
||||
if (!(status & PCBLOCK_ERROR))
|
||||
{
|
||||
#if !defined(SERIALIZED_READ_FROM_CACHE)
|
||||
pagecache_pthread_mutex_unlock(&pagecache->cache_lock);
|
||||
pagecache_pthread_mutex_unlock(&pagecache->cache_lock);
|
||||
#endif
|
||||
|
||||
DBUG_ASSERT((pagecache->block_size & 511) == 0);
|
||||
/* Copy data from the cache buffer */
|
||||
bmove512(buff, block->buffer, pagecache->block_size);
|
||||
DBUG_ASSERT((pagecache->block_size & 511) == 0);
|
||||
/* Copy data from the cache buffer */
|
||||
bmove512(buff, block->buffer, pagecache->block_size);
|
||||
|
||||
#if !defined(SERIALIZED_READ_FROM_CACHE)
|
||||
pagecache_pthread_mutex_lock(&pagecache->cache_lock);
|
||||
pagecache_pthread_mutex_lock(&pagecache->cache_lock);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
remove_reader(block);
|
||||
@ -2933,7 +2957,7 @@ restart:
|
||||
if (pin == PAGECACHE_PIN_LEFT_UNPINNED || pin == PAGECACHE_UNPIN)
|
||||
unreg_request(pagecache, block, 1);
|
||||
else
|
||||
*link= (PAGECACHE_PAGE_LINK)block;
|
||||
*link= block;
|
||||
|
||||
dec_counter_for_resize_op(pagecache);
|
||||
|
||||
@ -2982,7 +3006,7 @@ my_bool pagecache_delete(PAGECACHE *pagecache,
|
||||
my_bool flush)
|
||||
{
|
||||
int error= 0;
|
||||
enum pagecache_page_pin pin= lock_to_pin[lock];
|
||||
enum pagecache_page_pin pin= lock_to_pin[0][lock];
|
||||
DBUG_ENTER("pagecache_delete");
|
||||
DBUG_PRINT("enter", ("fd: %u page: %lu %s %s",
|
||||
(uint) file->file, (ulong) pageno,
|
||||
@ -3187,13 +3211,13 @@ my_bool pagecache_write_part(PAGECACHE *pagecache,
|
||||
enum pagecache_page_lock lock,
|
||||
enum pagecache_page_pin pin,
|
||||
enum pagecache_write_mode write_mode,
|
||||
PAGECACHE_PAGE_LINK *link,
|
||||
PAGECACHE_BLOCK_LINK **link,
|
||||
uint offset, uint size,
|
||||
pagecache_disk_read_validator validator,
|
||||
uchar* validator_data)
|
||||
{
|
||||
PAGECACHE_BLOCK_LINK *block= NULL;
|
||||
PAGECACHE_PAGE_LINK fake_link;
|
||||
PAGECACHE_BLOCK_LINK *fake_link;
|
||||
int error= 0;
|
||||
int need_lock_change= write_lock_change_table[lock].need_lock_change;
|
||||
DBUG_ENTER("pagecache_write_part");
|
||||
@ -3209,10 +3233,10 @@ my_bool pagecache_write_part(PAGECACHE *pagecache,
|
||||
DBUG_ASSERT(lock != PAGECACHE_LOCK_LEFT_READLOCKED);
|
||||
DBUG_ASSERT(lock != PAGECACHE_LOCK_READ_UNLOCK);
|
||||
DBUG_ASSERT(offset + size <= pagecache->block_size);
|
||||
|
||||
if (!link)
|
||||
link= &fake_link;
|
||||
else
|
||||
*link= 0;
|
||||
*link= 0;
|
||||
|
||||
restart:
|
||||
|
||||
@ -3337,7 +3361,7 @@ restart:
|
||||
if (pin == PAGECACHE_PIN_LEFT_UNPINNED || pin == PAGECACHE_UNPIN)
|
||||
unreg_request(pagecache, block, 1);
|
||||
else
|
||||
*link= (PAGECACHE_PAGE_LINK)block;
|
||||
*link= block;
|
||||
|
||||
if (block->status & PCBLOCK_ERROR)
|
||||
error= 1;
|
||||
@ -3829,7 +3853,8 @@ int flush_pagecache_blocks(PAGECACHE *pagecache,
|
||||
0 on success (always because it can't fail)
|
||||
*/
|
||||
|
||||
int reset_pagecache_counters(const char *name, PAGECACHE *pagecache)
|
||||
int reset_pagecache_counters(const char *name __attribute__((unused)),
|
||||
PAGECACHE *pagecache)
|
||||
{
|
||||
DBUG_ENTER("reset_pagecache_counters");
|
||||
if (!pagecache->inited)
|
||||
@ -3873,7 +3898,7 @@ my_bool pagecache_collect_changed_blocks_with_lsn(PAGECACHE *pagecache,
|
||||
LSN *min_rec_lsn)
|
||||
{
|
||||
my_bool error= 0;
|
||||
uint stored_list_size= 0;
|
||||
ulong stored_list_size= 0;
|
||||
uint file_hash;
|
||||
char *ptr;
|
||||
LSN minimum_rec_lsn= LSN_MAX;
|
||||
@ -3916,8 +3941,8 @@ my_bool pagecache_collect_changed_blocks_with_lsn(PAGECACHE *pagecache,
|
||||
}
|
||||
}
|
||||
|
||||
compile_time_assert(sizeof(pagecache->blocks == 4));
|
||||
str->length= 4 + /* number of dirty pages */
|
||||
compile_time_assert(sizeof(pagecache->blocks) <= 8);
|
||||
str->length= 8 + /* number of dirty pages */
|
||||
(4 + /* file */
|
||||
4 + /* pageno */
|
||||
LSN_STORE_SIZE /* rec_lsn */
|
||||
@ -3925,8 +3950,8 @@ my_bool pagecache_collect_changed_blocks_with_lsn(PAGECACHE *pagecache,
|
||||
if (NULL == (str->str= my_malloc(str->length, MYF(MY_WME))))
|
||||
goto err;
|
||||
ptr= str->str;
|
||||
int4store(ptr, stored_list_size);
|
||||
ptr+= 4;
|
||||
int8store(ptr, (ulonglong)stored_list_size);
|
||||
ptr+= 8;
|
||||
if (!stored_list_size)
|
||||
goto end;
|
||||
for (file_hash= 0; file_hash < PAGECACHE_CHANGED_BLOCKS_HASH; file_hash++)
|
||||
@ -3938,8 +3963,8 @@ my_bool pagecache_collect_changed_blocks_with_lsn(PAGECACHE *pagecache,
|
||||
{
|
||||
if (block->type != PAGECACHE_LSN_PAGE)
|
||||
continue; /* no need to store it in the checkpoint record */
|
||||
compile_time_assert((4 == sizeof(block->hash_link->file.file)));
|
||||
compile_time_assert((4 == sizeof(block->hash_link->pageno)));
|
||||
compile_time_assert(sizeof(block->hash_link->file.file) <= 4);
|
||||
compile_time_assert(sizeof(block->hash_link->pageno) <= 4);
|
||||
int4store(ptr, block->hash_link->file.file);
|
||||
ptr+= 4;
|
||||
int4store(ptr, block->hash_link->pageno);
|
||||
|
@ -73,8 +73,6 @@ enum pagecache_write_mode
|
||||
PAGECACHE_WRITE_DONE
|
||||
};
|
||||
|
||||
typedef void *PAGECACHE_PAGE_LINK;
|
||||
|
||||
/* file descriptor for Maria */
|
||||
typedef struct st_pagecache_file
|
||||
{
|
||||
@ -106,25 +104,22 @@ typedef my_bool (*pagecache_disk_read_validator)(uchar *page, uchar *data);
|
||||
|
||||
typedef struct st_pagecache
|
||||
{
|
||||
my_bool inited;
|
||||
my_bool resize_in_flush; /* true during flush of resize operation */
|
||||
my_bool can_be_used; /* usage of cache for read/write is allowed */
|
||||
uint shift; /* block size = 2 ^ shift */
|
||||
size_t mem_size; /* specified size of the cache memory */
|
||||
uint32 block_size; /* size of the page buffer of a cache block */
|
||||
size_t mem_size; /* specified size of the cache memory */
|
||||
ulong min_warm_blocks; /* min number of warm blocks; */
|
||||
ulong age_threshold; /* age threshold for hot blocks */
|
||||
ulonglong time; /* total number of block link operations */
|
||||
uint hash_entries; /* max number of entries in the hash table */
|
||||
int hash_links; /* max number of hash links */
|
||||
int hash_links_used; /* number of hash links taken from free links pool */
|
||||
int disk_blocks; /* max number of blocks in the cache */
|
||||
ulong hash_entries; /* max number of entries in the hash table */
|
||||
long hash_links; /* max number of hash links */
|
||||
long hash_links_used; /* number of hash links taken from free links pool */
|
||||
long disk_blocks; /* max number of blocks in the cache */
|
||||
ulong blocks_used; /* maximum number of concurrently used blocks */
|
||||
ulong blocks_unused; /* number of currently unused blocks */
|
||||
ulong blocks_changed; /* number of currently dirty blocks */
|
||||
ulong warm_blocks; /* number of blocks in warm sub-chain */
|
||||
ulong cnt_for_resize_op; /* counter to block resize operation */
|
||||
ulong blocks_available; /* number of blocks available in the LRU chain */
|
||||
long blocks; /* max number of blocks in the cache */
|
||||
uint32 block_size; /* size of the page buffer of a cache block */
|
||||
PAGECACHE_HASH_LINK **hash_root;/* arr. of entries into hash table buckets */
|
||||
PAGECACHE_HASH_LINK *hash_link_root;/* memory for hash table links */
|
||||
PAGECACHE_HASH_LINK *free_hash_list;/* list of free hash links */
|
||||
@ -159,19 +154,22 @@ typedef struct st_pagecache
|
||||
ulonglong global_cache_r_requests;/* number of read requests (read hits) */
|
||||
ulonglong global_cache_read; /* number of reads from files to cache */
|
||||
|
||||
int blocks; /* max number of blocks in the cache */
|
||||
uint shift; /* block size = 2 ^ shift */
|
||||
my_bool inited;
|
||||
my_bool resize_in_flush; /* true during flush of resize operation */
|
||||
my_bool can_be_used; /* usage of cache for read/write is allowed */
|
||||
my_bool in_init; /* Set to 1 in MySQL during init/resize */
|
||||
} PAGECACHE;
|
||||
|
||||
/* The default key cache */
|
||||
extern PAGECACHE dflt_pagecache_var, *dflt_pagecache;
|
||||
|
||||
extern int init_pagecache(PAGECACHE *pagecache, size_t use_mem,
|
||||
uint division_limit, uint age_threshold,
|
||||
uint block_size);
|
||||
extern int resize_pagecache(PAGECACHE *pagecache,
|
||||
size_t use_mem, uint division_limit,
|
||||
uint age_threshold);
|
||||
extern ulong init_pagecache(PAGECACHE *pagecache, size_t use_mem,
|
||||
uint division_limit, uint age_threshold,
|
||||
uint block_size);
|
||||
extern ulong resize_pagecache(PAGECACHE *pagecache,
|
||||
size_t use_mem, uint division_limit,
|
||||
uint age_threshold);
|
||||
extern void change_pagecache_param(PAGECACHE *pagecache, uint division_limit,
|
||||
uint age_threshold);
|
||||
|
||||
@ -185,7 +183,7 @@ extern uchar *pagecache_valid_read(PAGECACHE *pagecache,
|
||||
uchar *buff,
|
||||
enum pagecache_page_type type,
|
||||
enum pagecache_page_lock lock,
|
||||
PAGECACHE_PAGE_LINK *link,
|
||||
PAGECACHE_BLOCK_LINK **link,
|
||||
pagecache_disk_read_validator validator,
|
||||
uchar* validator_data);
|
||||
|
||||
@ -205,7 +203,7 @@ extern my_bool pagecache_write_part(PAGECACHE *pagecache,
|
||||
enum pagecache_page_lock lock,
|
||||
enum pagecache_page_pin pin,
|
||||
enum pagecache_write_mode write_mode,
|
||||
PAGECACHE_PAGE_LINK *link,
|
||||
PAGECACHE_BLOCK_LINK **link,
|
||||
uint offset,
|
||||
uint size,
|
||||
pagecache_disk_read_validator validator,
|
||||
@ -218,7 +216,7 @@ extern void pagecache_unlock(PAGECACHE *pagecache,
|
||||
LSN first_REDO_LSN_for_page,
|
||||
LSN lsn);
|
||||
extern void pagecache_unlock_by_link(PAGECACHE *pagecache,
|
||||
PAGECACHE_PAGE_LINK *link,
|
||||
PAGECACHE_BLOCK_LINK *block,
|
||||
enum pagecache_page_lock lock,
|
||||
enum pagecache_page_pin pin,
|
||||
LSN first_REDO_LSN_for_page,
|
||||
@ -228,7 +226,7 @@ extern void pagecache_unpin(PAGECACHE *pagecache,
|
||||
pgcache_page_no_t pageno,
|
||||
LSN lsn);
|
||||
extern void pagecache_unpin_by_link(PAGECACHE *pagecache,
|
||||
PAGECACHE_PAGE_LINK *link,
|
||||
PAGECACHE_BLOCK_LINK *link,
|
||||
LSN lsn);
|
||||
extern int flush_pagecache_blocks(PAGECACHE *keycache,
|
||||
PAGECACHE_FILE *file,
|
||||
|
@ -50,6 +50,7 @@ static LSN current_group_end_lsn,
|
||||
static TrID max_long_trid= 0; /**< max long trid seen by REDO phase */
|
||||
static FILE *tracef; /**< trace file for debugging */
|
||||
static my_bool skip_DDLs; /**< if REDO phase should skip DDL records */
|
||||
static ulonglong now; /**< for tracking execution time of phases */
|
||||
|
||||
#define prototype_redo_exec_hook(R) \
|
||||
static int exec_REDO_LOGREC_ ## R(const TRANSLOG_HEADER_BUFFER *rec)
|
||||
@ -105,6 +106,7 @@ static int new_table(uint16 sid, const char *name,
|
||||
static int new_page(File fileid, pgcache_page_no_t pageid, LSN rec_lsn,
|
||||
struct st_dirty_page *dirty_page);
|
||||
static int close_all_tables(void);
|
||||
static my_bool close_one_table(const char *name, LSN addr);
|
||||
static void print_redo_phase_progress(TRANSLOG_ADDRESS addr);
|
||||
|
||||
/** @brief global [out] buffer for translog_read_record(); never shrinks */
|
||||
@ -123,13 +125,16 @@ static my_bool redo_phase_message_printed;
|
||||
/** @brief Prints to a trace file if it is not NULL */
|
||||
void tprint(FILE *trace_file, const char *format, ...)
|
||||
ATTRIBUTE_FORMAT(printf, 2, 3);
|
||||
void tprint(FILE *trace_file, const char *format, ...)
|
||||
void tprint(FILE *trace_file __attribute__ ((unused)),
|
||||
const char *format __attribute__ ((unused)), ...)
|
||||
{
|
||||
#ifdef EXTRA_DEBUG
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
if (trace_file != NULL)
|
||||
vfprintf(trace_file, format, args);
|
||||
va_end(args);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define ALERT_USER() DBUG_ASSERT(0)
|
||||
@ -157,7 +162,7 @@ int maria_recover(void)
|
||||
DBUG_ASSERT(!maria_in_recovery);
|
||||
maria_in_recovery= TRUE;
|
||||
|
||||
#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
|
||||
#ifdef EXTRA_DEBUG
|
||||
trace_file= fopen("maria_recovery.trace", "w");
|
||||
#else
|
||||
trace_file= NULL; /* no trace file for being fast */
|
||||
@ -308,8 +313,12 @@ end:
|
||||
log_record_buffer.length= 0;
|
||||
if (tracef != stdout && redo_phase_message_printed)
|
||||
{
|
||||
ulonglong old_now= now;
|
||||
now= my_getsystime();
|
||||
float previous_phase_took= (now - old_now)/10000000.0;
|
||||
/** @todo RECOVERY BUG all prints to stderr should go to error log */
|
||||
fprintf(stderr, "\n");
|
||||
/** @todo RECOVERY BUG all prints to stderr should go to error log */
|
||||
fprintf(stderr, " (%.1f seconds)\n", previous_phase_took);
|
||||
}
|
||||
/* we don't cleanly close tables if we hit some error (may corrupt them) */
|
||||
DBUG_RETURN(error);
|
||||
@ -415,6 +424,8 @@ prototype_redo_exec_hook(REDO_CREATE_TABLE)
|
||||
uint flags;
|
||||
int error= 1, create_mode= O_RDWR | O_TRUNC;
|
||||
MARIA_HA *info= NULL;
|
||||
uint kfile_size_before_extension, keystart;
|
||||
|
||||
if (skip_DDLs)
|
||||
{
|
||||
tprint(tracef, "we skip DDLs\n");
|
||||
@ -431,6 +442,12 @@ prototype_redo_exec_hook(REDO_CREATE_TABLE)
|
||||
}
|
||||
name= log_record_buffer.str;
|
||||
tprint(tracef, "Table '%s'", name);
|
||||
if (close_one_table(name, rec->lsn))
|
||||
{
|
||||
tprint(tracef, " got error %d on close\n", my_errno);
|
||||
ALERT_USER();
|
||||
goto end;
|
||||
}
|
||||
/* we try hard to get create_rename_lsn, to avoid mistakes if possible */
|
||||
info= maria_open(name, O_RDONLY, HA_OPEN_FOR_REPAIR);
|
||||
if (info)
|
||||
@ -474,7 +491,7 @@ prototype_redo_exec_hook(REDO_CREATE_TABLE)
|
||||
info= NULL;
|
||||
}
|
||||
else /* one or two files absent, or header corrupted... */
|
||||
tprint(tracef, "can't be opened, probably does not exist");
|
||||
tprint(tracef, " can't be opened, probably does not exist");
|
||||
/* if does not exist, or is older, overwrite it */
|
||||
/** @todo symlinks */
|
||||
ptr= name + strlen(name) + 1;
|
||||
@ -490,13 +507,13 @@ prototype_redo_exec_hook(REDO_CREATE_TABLE)
|
||||
if ((kfile= my_create_with_symlink(linkname_ptr, filename, 0, create_mode,
|
||||
MYF(MY_WME|create_flag))) < 0)
|
||||
{
|
||||
tprint(tracef, "Failed to create index file\n");
|
||||
tprint(tracef, " Failed to create index file\n");
|
||||
goto end;
|
||||
}
|
||||
ptr++;
|
||||
uint kfile_size_before_extension= uint2korr(ptr);
|
||||
kfile_size_before_extension= uint2korr(ptr);
|
||||
ptr+= 2;
|
||||
uint keystart= uint2korr(ptr);
|
||||
keystart= uint2korr(ptr);
|
||||
ptr+= 2;
|
||||
/* set create_rename_lsn (for maria_read_log to be idempotent) */
|
||||
lsn_store(ptr + sizeof(info->s->state.header) + 2, rec->lsn);
|
||||
@ -507,7 +524,7 @@ prototype_redo_exec_hook(REDO_CREATE_TABLE)
|
||||
kfile_size_before_extension, 0, MYF(MY_NABP|MY_WME)) ||
|
||||
my_chsize(kfile, keystart, 0, MYF(MY_WME)))
|
||||
{
|
||||
tprint(tracef, "Failed to write to index file\n");
|
||||
tprint(tracef, " Failed to write to index file\n");
|
||||
goto end;
|
||||
}
|
||||
if (!(flags & HA_DONT_TOUCH_DATA))
|
||||
@ -521,7 +538,7 @@ prototype_redo_exec_hook(REDO_CREATE_TABLE)
|
||||
MYF(MY_WME | create_flag))) < 0) ||
|
||||
my_close(dfile, MYF(MY_WME)))
|
||||
{
|
||||
tprint(tracef, "Failed to create data file\n");
|
||||
tprint(tracef, " Failed to create data file\n");
|
||||
goto end;
|
||||
}
|
||||
/*
|
||||
@ -533,7 +550,7 @@ prototype_redo_exec_hook(REDO_CREATE_TABLE)
|
||||
if (((info= maria_open(name, O_RDONLY, 0)) == NULL) ||
|
||||
_ma_initialize_data_file(info->s, info->dfile.file))
|
||||
{
|
||||
tprint(tracef, "Failed to open new table or write to data file\n");
|
||||
tprint(tracef, " Failed to open new table or write to data file\n");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
@ -766,27 +783,17 @@ prototype_redo_exec_hook(REDO_REPAIR_TABLE)
|
||||
than the mapping, so we can repair.
|
||||
*/
|
||||
tprint(tracef, " repairing...\n");
|
||||
/**
|
||||
@todo RECOVERY BUG fix this:
|
||||
the maria_chk_init() call causes a heap of linker errors in ha_maria.cc!
|
||||
*/
|
||||
#if 0
|
||||
HA_CHECK param;
|
||||
maria_chk_init(¶m);
|
||||
param.isam_file_name= info->s->open_file_name;
|
||||
param.testflag= uint4korr(rec->header);
|
||||
if (maria_repair(¶m, info, info->s->open_file_name,
|
||||
param.testflag & T_QUICK))
|
||||
if (maria_repair(¶m, info, info->s->open_file_name, param.testflag))
|
||||
goto end;
|
||||
if (_ma_update_create_rename_lsn(info->s, rec->lsn, TRUE))
|
||||
goto end;
|
||||
error= 0;
|
||||
end:
|
||||
return error;
|
||||
#else
|
||||
DBUG_ASSERT("fix this table repairing" == NULL);
|
||||
return error;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -1199,12 +1206,25 @@ prototype_redo_exec_hook(UNDO_ROW_INSERT)
|
||||
MARIA_HA *info= get_MARIA_HA_from_UNDO_record(rec);
|
||||
if (info == NULL)
|
||||
return 0;
|
||||
MARIA_SHARE *share= info->s;
|
||||
set_undo_lsn_for_active_trans(rec->short_trid, rec->lsn);
|
||||
if (cmp_translog_addr(rec->lsn, info->s->state.is_of_horizon) >= 0)
|
||||
if (cmp_translog_addr(rec->lsn, share->state.is_of_horizon) >= 0)
|
||||
{
|
||||
tprint(tracef, " state older than record, updating rows' count\n");
|
||||
info->s->state.state.records++;
|
||||
/** @todo RECOVERY BUG Also update the table's checksum */
|
||||
share->state.state.records++;
|
||||
if (share->calc_checksum)
|
||||
{
|
||||
uchar buff[HA_CHECKSUM_STORE_SIZE];
|
||||
if (translog_read_record(rec->lsn, LSN_STORE_SIZE + FILEID_STORE_SIZE +
|
||||
PAGE_STORE_SIZE + DIRPOS_STORE_SIZE,
|
||||
HA_CHECKSUM_STORE_SIZE, buff, NULL) !=
|
||||
HA_CHECKSUM_STORE_SIZE)
|
||||
{
|
||||
tprint(tracef, "Failed to read record\n");
|
||||
return 1;
|
||||
}
|
||||
share->state.state.checksum+= ha_checksum_korr(buff);
|
||||
}
|
||||
/**
|
||||
@todo some bits below will rather be set when executing UNDOs related
|
||||
to keys
|
||||
@ -1222,15 +1242,29 @@ prototype_redo_exec_hook(UNDO_ROW_DELETE)
|
||||
MARIA_HA *info= get_MARIA_HA_from_UNDO_record(rec);
|
||||
if (info == NULL)
|
||||
return 0;
|
||||
MARIA_SHARE *share= info->s;
|
||||
set_undo_lsn_for_active_trans(rec->short_trid, rec->lsn);
|
||||
if (cmp_translog_addr(rec->lsn, info->s->state.is_of_horizon) >= 0)
|
||||
if (cmp_translog_addr(rec->lsn, share->state.is_of_horizon) >= 0)
|
||||
{
|
||||
tprint(tracef, " state older than record, updating rows' count\n");
|
||||
info->s->state.state.records--;
|
||||
info->s->state.changed|= STATE_CHANGED | STATE_NOT_ANALYZED |
|
||||
share->state.state.records--;
|
||||
if (share->calc_checksum)
|
||||
{
|
||||
uchar buff[HA_CHECKSUM_STORE_SIZE];
|
||||
if (translog_read_record(rec->lsn, LSN_STORE_SIZE + FILEID_STORE_SIZE +
|
||||
PAGE_STORE_SIZE + DIRPOS_STORE_SIZE,
|
||||
HA_CHECKSUM_STORE_SIZE, buff, NULL) !=
|
||||
HA_CHECKSUM_STORE_SIZE)
|
||||
{
|
||||
tprint(tracef, "Failed to read record\n");
|
||||
return 1;
|
||||
}
|
||||
share->state.state.checksum+= ha_checksum_korr(buff);
|
||||
}
|
||||
share->state.changed|= STATE_CHANGED | STATE_NOT_ANALYZED |
|
||||
STATE_NOT_OPTIMIZED_KEYS | STATE_NOT_SORTED_PAGES;
|
||||
}
|
||||
tprint(tracef, " rows' count %lu\n", (ulong)info->s->state.state.records);
|
||||
tprint(tracef, " rows' count %lu\n", (ulong)share->state.state.records);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1240,10 +1274,24 @@ prototype_redo_exec_hook(UNDO_ROW_UPDATE)
|
||||
MARIA_HA *info= get_MARIA_HA_from_UNDO_record(rec);
|
||||
if (info == NULL)
|
||||
return 0;
|
||||
MARIA_SHARE *share= info->s;
|
||||
set_undo_lsn_for_active_trans(rec->short_trid, rec->lsn);
|
||||
if (cmp_translog_addr(rec->lsn, info->s->state.is_of_horizon) >= 0)
|
||||
if (cmp_translog_addr(rec->lsn, share->state.is_of_horizon) >= 0)
|
||||
{
|
||||
info->s->state.changed|= STATE_CHANGED | STATE_NOT_ANALYZED |
|
||||
if (share->calc_checksum)
|
||||
{
|
||||
uchar buff[HA_CHECKSUM_STORE_SIZE];
|
||||
if (translog_read_record(rec->lsn, LSN_STORE_SIZE + FILEID_STORE_SIZE +
|
||||
PAGE_STORE_SIZE + DIRPOS_STORE_SIZE,
|
||||
HA_CHECKSUM_STORE_SIZE, buff, NULL) !=
|
||||
HA_CHECKSUM_STORE_SIZE)
|
||||
{
|
||||
tprint(tracef, "Failed to read record\n");
|
||||
return 1;
|
||||
}
|
||||
share->state.state.checksum+= ha_checksum_korr(buff);
|
||||
}
|
||||
share->state.changed|= STATE_CHANGED | STATE_NOT_ANALYZED |
|
||||
STATE_NOT_OPTIMIZED_KEYS | STATE_NOT_SORTED_PAGES;
|
||||
}
|
||||
return 0;
|
||||
@ -1294,33 +1342,46 @@ prototype_redo_exec_hook(CLR_END)
|
||||
MARIA_HA *info= get_MARIA_HA_from_UNDO_record(rec);
|
||||
if (info == NULL)
|
||||
return 0;
|
||||
MARIA_SHARE *share= info->s;
|
||||
LSN previous_undo_lsn= lsn_korr(rec->header);
|
||||
enum translog_record_type undone_record_type=
|
||||
(rec->header)[LSN_STORE_SIZE + FILEID_STORE_SIZE];
|
||||
clr_type_korr(rec->header + LSN_STORE_SIZE + FILEID_STORE_SIZE);
|
||||
const LOG_DESC *log_desc= &log_record_type_descriptor[undone_record_type];
|
||||
|
||||
set_undo_lsn_for_active_trans(rec->short_trid, previous_undo_lsn);
|
||||
tprint(tracef, " CLR_END was about %s, undo_lsn now LSN (%lu,0x%lx)\n",
|
||||
log_desc->name, LSN_IN_PARTS(previous_undo_lsn));
|
||||
if (cmp_translog_addr(rec->lsn, info->s->state.is_of_horizon) >= 0)
|
||||
if (cmp_translog_addr(rec->lsn, share->state.is_of_horizon) >= 0)
|
||||
{
|
||||
tprint(tracef, " state older than record, updating rows' count\n");
|
||||
if (share->calc_checksum)
|
||||
{
|
||||
uchar buff[HA_CHECKSUM_STORE_SIZE];
|
||||
if (translog_read_record(rec->lsn, LSN_STORE_SIZE + FILEID_STORE_SIZE +
|
||||
CLR_TYPE_STORE_SIZE, HA_CHECKSUM_STORE_SIZE,
|
||||
buff, NULL) != HA_CHECKSUM_STORE_SIZE)
|
||||
{
|
||||
tprint(tracef, "Failed to read record\n");
|
||||
return 1;
|
||||
}
|
||||
share->state.state.checksum+= ha_checksum_korr(buff);
|
||||
}
|
||||
switch (undone_record_type) {
|
||||
case LOGREC_UNDO_ROW_DELETE:
|
||||
info->s->state.state.records++;
|
||||
share->state.state.records++;
|
||||
break;
|
||||
case LOGREC_UNDO_ROW_INSERT:
|
||||
info->s->state.state.records--;
|
||||
share->state.state.records--;
|
||||
break;
|
||||
case LOGREC_UNDO_ROW_UPDATE:
|
||||
break;
|
||||
default:
|
||||
DBUG_ASSERT(0);
|
||||
}
|
||||
info->s->state.changed|= STATE_CHANGED | STATE_NOT_ANALYZED |
|
||||
share->state.changed|= STATE_CHANGED | STATE_NOT_ANALYZED |
|
||||
STATE_NOT_OPTIMIZED_KEYS | STATE_NOT_SORTED_PAGES;
|
||||
}
|
||||
tprint(tracef, " rows' count %lu\n", (ulong)info->s->state.state.records);
|
||||
tprint(tracef, " rows' count %lu\n", (ulong)share->state.state.records);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1341,12 +1402,33 @@ prototype_undo_exec_hook(UNDO_ROW_INSERT)
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
info->s->state.changed|= STATE_CHANGED | STATE_NOT_ANALYZED |
|
||||
MARIA_SHARE *share= info->s;
|
||||
share->state.changed|= STATE_CHANGED | STATE_NOT_ANALYZED |
|
||||
STATE_NOT_OPTIMIZED_KEYS | STATE_NOT_SORTED_PAGES;
|
||||
|
||||
const uchar *record_ptr= rec->header;
|
||||
if (share->calc_checksum)
|
||||
{
|
||||
/*
|
||||
We need to read more of the record to put the checksum into the record
|
||||
buffer used by _ma_apply_undo_row_insert().
|
||||
If the table has no live checksum, rec->header will be enough.
|
||||
*/
|
||||
enlarge_buffer(rec);
|
||||
if (log_record_buffer.str == NULL ||
|
||||
translog_read_record(rec->lsn, 0, rec->record_length,
|
||||
log_record_buffer.str, NULL) !=
|
||||
rec->record_length)
|
||||
{
|
||||
tprint(tracef, "Failed to read record\n");
|
||||
return 1;
|
||||
}
|
||||
record_ptr= log_record_buffer.str;
|
||||
}
|
||||
|
||||
info->trn= trn;
|
||||
error= _ma_apply_undo_row_insert(info, previous_undo_lsn,
|
||||
rec->header + LSN_STORE_SIZE +
|
||||
record_ptr + LSN_STORE_SIZE +
|
||||
FILEID_STORE_SIZE);
|
||||
info->trn= 0;
|
||||
/* trn->undo_lsn is updated in an inwrite_hook when writing the CLR_END */
|
||||
@ -1366,7 +1448,8 @@ prototype_undo_exec_hook(UNDO_ROW_DELETE)
|
||||
if (info == NULL)
|
||||
return 1;
|
||||
|
||||
info->s->state.changed|= STATE_CHANGED | STATE_NOT_ANALYZED |
|
||||
MARIA_SHARE *share= info->s;
|
||||
share->state.changed|= STATE_CHANGED | STATE_NOT_ANALYZED |
|
||||
STATE_NOT_OPTIMIZED_KEYS | STATE_NOT_SORTED_PAGES;
|
||||
|
||||
enlarge_buffer(rec);
|
||||
@ -1393,8 +1476,7 @@ prototype_undo_exec_hook(UNDO_ROW_DELETE)
|
||||
PAGE_STORE_SIZE + DIRPOS_STORE_SIZE));
|
||||
info->trn= 0;
|
||||
tprint(tracef, " rows' count %lu\n undo_lsn now LSN (%lu,0x%lx)\n",
|
||||
(ulong)info->s->state.state.records,
|
||||
LSN_IN_PARTS(previous_undo_lsn));
|
||||
(ulong)share->state.state.records, LSN_IN_PARTS(previous_undo_lsn));
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -1407,8 +1489,8 @@ prototype_undo_exec_hook(UNDO_ROW_UPDATE)
|
||||
|
||||
if (info == NULL)
|
||||
return 1;
|
||||
|
||||
info->s->state.changed|= STATE_CHANGED | STATE_NOT_ANALYZED |
|
||||
MARIA_SHARE *share= info->s;
|
||||
share->state.changed|= STATE_CHANGED | STATE_NOT_ANALYZED |
|
||||
STATE_NOT_OPTIMIZED_KEYS | STATE_NOT_SORTED_PAGES;
|
||||
|
||||
enlarge_buffer(rec);
|
||||
@ -1436,6 +1518,11 @@ prototype_undo_exec_hook(UNDO_ROW_UPDATE)
|
||||
|
||||
static int run_redo_phase(LSN lsn, my_bool apply)
|
||||
{
|
||||
TRANSLOG_HEADER_BUFFER rec;
|
||||
struct st_translog_scanner_data scanner;
|
||||
int len;
|
||||
uint i;
|
||||
|
||||
/* install hooks for execution */
|
||||
#define install_redo_exec_hook(R) \
|
||||
log_record_type_descriptor[LOGREC_ ## R].record_execute_in_redo_phase= \
|
||||
@ -1467,8 +1554,6 @@ static int run_redo_phase(LSN lsn, my_bool apply)
|
||||
|
||||
current_group_end_lsn= LSN_IMPOSSIBLE;
|
||||
|
||||
TRANSLOG_HEADER_BUFFER rec;
|
||||
|
||||
if (unlikely(lsn == LSN_IMPOSSIBLE || lsn == translog_get_horizon()))
|
||||
{
|
||||
tprint(tracef, "checkpoint address refers to the log end log or "
|
||||
@ -1476,7 +1561,7 @@ static int run_redo_phase(LSN lsn, my_bool apply)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int len= translog_read_record_header(lsn, &rec);
|
||||
len= translog_read_record_header(lsn, &rec);
|
||||
|
||||
/** @todo EOF should be detected */
|
||||
if (len == RECHEADER_READ_ERROR)
|
||||
@ -1484,13 +1569,11 @@ static int run_redo_phase(LSN lsn, my_bool apply)
|
||||
tprint(tracef, "Failed to read header of the first record.\n");
|
||||
return 1;
|
||||
}
|
||||
struct st_translog_scanner_data scanner;
|
||||
if (translog_init_scanner(lsn, 1, &scanner))
|
||||
if (translog_init_scanner(lsn, 1, &scanner, 1))
|
||||
{
|
||||
tprint(tracef, "Scanner init failed\n");
|
||||
return 1;
|
||||
}
|
||||
uint i;
|
||||
for (i= 1;;i++)
|
||||
{
|
||||
uint16 sid= rec.short_trid;
|
||||
@ -1519,24 +1602,25 @@ static int run_redo_phase(LSN lsn, my_bool apply)
|
||||
}
|
||||
else
|
||||
{
|
||||
struct st_translog_scanner_data scanner2;
|
||||
TRANSLOG_HEADER_BUFFER rec2;
|
||||
/*
|
||||
There is a complete group for this transaction, containing more
|
||||
than this event.
|
||||
*/
|
||||
tprint(tracef, " ends a group:\n");
|
||||
struct st_translog_scanner_data scanner2;
|
||||
TRANSLOG_HEADER_BUFFER rec2;
|
||||
len=
|
||||
translog_read_record_header(all_active_trans[sid].group_start_lsn, &rec2);
|
||||
translog_read_record_header(all_active_trans[sid].group_start_lsn,
|
||||
&rec2);
|
||||
if (len < 0) /* EOF or error */
|
||||
{
|
||||
tprint(tracef, "Cannot find record where it should be\n");
|
||||
return 1;
|
||||
goto err;
|
||||
}
|
||||
if (translog_init_scanner(rec2.lsn, 1, &scanner2))
|
||||
if (translog_init_scanner(rec2.lsn, 1, &scanner2, 1))
|
||||
{
|
||||
tprint(tracef, "Scanner2 init failed\n");
|
||||
return 1;
|
||||
goto err;
|
||||
}
|
||||
current_group_end_lsn= rec.lsn;
|
||||
do
|
||||
@ -1546,13 +1630,16 @@ static int run_redo_phase(LSN lsn, my_bool apply)
|
||||
const LOG_DESC *log_desc2= &log_record_type_descriptor[rec2.type];
|
||||
display_record_position(log_desc2, &rec2, 0);
|
||||
if (apply && display_and_apply_record(log_desc2, &rec2))
|
||||
return 1;
|
||||
{
|
||||
translog_destroy_scanner(&scanner2);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
len= translog_read_next_record_header(&scanner2, &rec2);
|
||||
if (len < 0) /* EOF or error */
|
||||
{
|
||||
tprint(tracef, "Cannot find record where it should be\n");
|
||||
return 1;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
while (rec2.lsn < rec.lsn);
|
||||
@ -1561,10 +1648,11 @@ static int run_redo_phase(LSN lsn, my_bool apply)
|
||||
all_active_trans[sid].group_start_lsn= LSN_IMPOSSIBLE;
|
||||
current_group_end_lsn= LSN_IMPOSSIBLE; /* for debugging */
|
||||
display_record_position(log_desc, &rec, 0);
|
||||
translog_destroy_scanner(&scanner2);
|
||||
}
|
||||
}
|
||||
if (apply && display_and_apply_record(log_desc, &rec))
|
||||
return 1;
|
||||
goto err;
|
||||
}
|
||||
else /* record does not end group */
|
||||
{
|
||||
@ -1585,13 +1673,18 @@ static int run_redo_phase(LSN lsn, my_bool apply)
|
||||
break;
|
||||
case RECHEADER_READ_ERROR:
|
||||
tprint(tracef, "Error reading log\n");
|
||||
return 1;
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
translog_destroy_scanner(&scanner);
|
||||
translog_free_record_header(&rec);
|
||||
return 0;
|
||||
|
||||
err:
|
||||
translog_destroy_scanner(&scanner);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@ -1607,10 +1700,11 @@ static uint end_of_redo_phase(my_bool prepare_for_undo_phase)
|
||||
{
|
||||
uint sid, unfinished= 0;
|
||||
char llbuf[22];
|
||||
LSN addr;
|
||||
|
||||
hash_free(&all_dirty_pages);
|
||||
/*
|
||||
hash_free() can be called multiple times probably, but be safe it that
|
||||
hash_free() can be called multiple times probably, but be safe if that
|
||||
changes
|
||||
*/
|
||||
bzero(&all_dirty_pages, sizeof(all_dirty_pages));
|
||||
@ -1628,11 +1722,8 @@ static uint end_of_redo_phase(my_bool prepare_for_undo_phase)
|
||||
LSN gslsn= all_active_trans[sid].group_start_lsn;
|
||||
TRN *trn;
|
||||
if (gslsn != LSN_IMPOSSIBLE)
|
||||
{
|
||||
tprint(tracef, "Group at LSN (%lu,0x%lx) short_trid %u aborted\n",
|
||||
LSN_IN_PARTS(gslsn), sid);
|
||||
ALERT_USER();
|
||||
}
|
||||
if (all_active_trans[sid].undo_lsn != LSN_IMPOSSIBLE)
|
||||
{
|
||||
char llbuf[22];
|
||||
@ -1667,7 +1758,7 @@ static uint end_of_redo_phase(my_bool prepare_for_undo_phase)
|
||||
The UNDO phase uses some normal run-time code of ROLLBACK: generates log
|
||||
records, etc; prepare tables for that
|
||||
*/
|
||||
LSN addr= translog_get_horizon();
|
||||
addr= translog_get_horizon();
|
||||
for (sid= 0; sid <= SHARE_ID_MAX; sid++)
|
||||
{
|
||||
MARIA_HA *info= all_tables[sid].info;
|
||||
@ -1710,8 +1801,12 @@ static int run_undo_phase(uint unfinished)
|
||||
{
|
||||
if (tracef != stdout)
|
||||
{
|
||||
ulonglong old_now= now;
|
||||
now= my_getsystime();
|
||||
float previous_phase_took= (now - old_now)/10000000.0;
|
||||
/** @todo RECOVERY BUG all prints to stderr should go to error log */
|
||||
fprintf(stderr, " 100%%; transactions to roll back:");
|
||||
fprintf(stderr, " 100%% (%.1f seconds); transactions to roll back:",
|
||||
previous_phase_took);
|
||||
}
|
||||
tprint(tracef, "%u transactions will be rolled back\n", unfinished);
|
||||
for( ; ; )
|
||||
@ -1898,7 +1993,7 @@ static MARIA_HA *get_MARIA_HA_from_UNDO_record(const
|
||||
|
||||
static LSN parse_checkpoint_record(LSN lsn)
|
||||
{
|
||||
uint i;
|
||||
ulong i;
|
||||
TRANSLOG_HEADER_BUFFER rec;
|
||||
|
||||
tprint(tracef, "Loading data from checkpoint record at LSN (%lu,0x%lx)\n",
|
||||
@ -1982,9 +2077,9 @@ static LSN parse_checkpoint_record(LSN lsn)
|
||||
}
|
||||
|
||||
/* dirty pages */
|
||||
uint nb_dirty_pages= uint4korr(ptr);
|
||||
ptr+= 4;
|
||||
tprint(tracef, "%u dirty pages\n", nb_dirty_pages);
|
||||
ulong nb_dirty_pages= uint8korr(ptr);
|
||||
ptr+= 8;
|
||||
tprint(tracef, "%lu dirty pages\n", nb_dirty_pages);
|
||||
if (hash_init(&all_dirty_pages, &my_charset_bin, nb_dirty_pages,
|
||||
offsetof(struct st_dirty_page, file_and_page_id),
|
||||
sizeof(((struct st_dirty_page *)NULL)->file_and_page_id),
|
||||
@ -2046,8 +2141,11 @@ static int close_all_tables(void)
|
||||
tprint(tracef, "Closing all tables\n");
|
||||
if (tracef != stdout && redo_phase_message_printed)
|
||||
{
|
||||
ulonglong old_now= now;
|
||||
now= my_getsystime();
|
||||
float previous_phase_took= (now - old_now)/10000000.0;
|
||||
/** @todo RECOVERY BUG all prints to stderr should go to error log */
|
||||
fprintf(stderr, "; flushing tables");
|
||||
fprintf(stderr, " (%.1f seconds); flushing tables", previous_phase_took);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2070,6 +2168,42 @@ end:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* Close one table during redo phase */
|
||||
|
||||
static my_bool close_one_table(const char *open_name, LSN addr)
|
||||
{
|
||||
my_bool res= 0;
|
||||
LIST *pos;
|
||||
/* There are no other threads using the tables, so we don't need any locks */
|
||||
for (pos=maria_open_list ; pos ;)
|
||||
{
|
||||
MARIA_HA *info= (MARIA_HA*) pos->data;
|
||||
MARIA_SHARE *share= info->s;
|
||||
pos= pos->next;
|
||||
if (!strcmp(share->open_file_name, open_name))
|
||||
{
|
||||
struct st_table_for_recovery *internal_table, *end;
|
||||
|
||||
for (internal_table= all_tables, end= internal_table + SHARE_ID_MAX + 1;
|
||||
internal_table < end ;
|
||||
internal_table++)
|
||||
{
|
||||
if (internal_table->info == info)
|
||||
{
|
||||
internal_table->info= 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
prepare_table_for_close(info, addr);
|
||||
if (maria_close(info))
|
||||
res= 1;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static void print_redo_phase_progress(TRANSLOG_ADDRESS addr)
|
||||
{
|
||||
static int end_logno= FILENO_IMPOSSIBLE, end_offset, percentage_printed= 0;
|
||||
@ -2081,6 +2215,7 @@ static void print_redo_phase_progress(TRANSLOG_ADDRESS addr)
|
||||
/** @todo RECOVERY BUG all prints to stderr should go to error log */
|
||||
fprintf(stderr, "Maria engine: starting recovery; recovered pages: 0%%");
|
||||
redo_phase_message_printed= TRUE;
|
||||
now= my_getsystime();
|
||||
}
|
||||
if (end_logno == FILENO_IMPOSSIBLE)
|
||||
{
|
||||
@ -2106,7 +2241,7 @@ static void print_redo_phase_progress(TRANSLOG_ADDRESS addr)
|
||||
}
|
||||
|
||||
#ifdef MARIA_EXTERNAL_LOCKING
|
||||
#error Maria's Checkpoint and Recovery are really not ready for it
|
||||
#error Marias Checkpoint and Recovery are really not ready for it
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -85,7 +85,7 @@ int maria_rename(const char *old_name, const char *new_name)
|
||||
&dummy_transaction_object, NULL,
|
||||
old_name_len + new_name_len,
|
||||
sizeof(log_array)/sizeof(log_array[0]),
|
||||
log_array, NULL) ||
|
||||
log_array, NULL, NULL) ||
|
||||
translog_flush(lsn)))
|
||||
{
|
||||
maria_close(info);
|
||||
|
@ -4,10 +4,6 @@ TEST WITH ma_test1 -s -M -T -c
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 3757530372
|
||||
---
|
||||
> Checksum: 0
|
||||
11c11
|
||||
< Datafile length: 16384 Keyfile length: 16384
|
||||
---
|
||||
@ -21,10 +17,6 @@ testing idempotency
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 3757530372
|
||||
---
|
||||
> Checksum: 0
|
||||
11c11
|
||||
< Datafile length: 16384 Keyfile length: 16384
|
||||
---
|
||||
@ -78,10 +70,6 @@ Dying on request without maria_commit()/maria_close()
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 221293111
|
||||
---
|
||||
> Checksum: 0
|
||||
11c11
|
||||
< Datafile length: 16384 Keyfile length: 16384
|
||||
---
|
||||
@ -95,10 +83,6 @@ testing idempotency
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 221293111
|
||||
---
|
||||
> Checksum: 0
|
||||
11c11
|
||||
< Datafile length: 16384 Keyfile length: 16384
|
||||
---
|
||||
@ -112,10 +96,6 @@ testing applying of CLRs to recreate table
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 221293111
|
||||
---
|
||||
> Checksum: 0
|
||||
11c11
|
||||
< Datafile length: 16384 Keyfile length: 16384
|
||||
---
|
||||
@ -137,10 +117,6 @@ testing applying of CLRs to recreate table
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 3697324514
|
||||
---
|
||||
> Checksum: 0
|
||||
11c11
|
||||
< Datafile length: 16384 Keyfile length: 16384
|
||||
---
|
||||
@ -158,10 +134,6 @@ Dying on request without maria_commit()/maria_close()
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 2428948025
|
||||
---
|
||||
> Checksum: 3026590807
|
||||
11c11
|
||||
< Datafile length: 16384 Keyfile length: 16384
|
||||
---
|
||||
@ -175,10 +147,6 @@ testing idempotency
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 2428948025
|
||||
---
|
||||
> Checksum: 3026590807
|
||||
11c11
|
||||
< Datafile length: 16384 Keyfile length: 16384
|
||||
---
|
||||
@ -192,10 +160,6 @@ testing applying of CLRs to recreate table
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 2428948025
|
||||
---
|
||||
> Checksum: 0
|
||||
11c11
|
||||
< Datafile length: 16384 Keyfile length: 16384
|
||||
---
|
||||
@ -253,10 +217,6 @@ Dying on request without maria_commit()/maria_close()
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 221293111
|
||||
---
|
||||
> Checksum: 0
|
||||
11c11
|
||||
< Datafile length: 16384 Keyfile length: 16384
|
||||
---
|
||||
@ -270,10 +230,6 @@ testing idempotency
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 221293111
|
||||
---
|
||||
> Checksum: 0
|
||||
11c11
|
||||
< Datafile length: 16384 Keyfile length: 16384
|
||||
---
|
||||
@ -287,10 +243,6 @@ testing applying of CLRs to recreate table
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 221293111
|
||||
---
|
||||
> Checksum: 0
|
||||
11c11
|
||||
< Datafile length: 16384 Keyfile length: 16384
|
||||
---
|
||||
@ -312,10 +264,6 @@ testing applying of CLRs to recreate table
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 3697324514
|
||||
---
|
||||
> Checksum: 0
|
||||
11c11
|
||||
< Datafile length: 16384 Keyfile length: 16384
|
||||
---
|
||||
@ -333,10 +281,6 @@ Dying on request without maria_commit()/maria_close()
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 2428948025
|
||||
---
|
||||
> Checksum: 3026590807
|
||||
11c11
|
||||
< Datafile length: 16384 Keyfile length: 16384
|
||||
---
|
||||
@ -350,10 +294,6 @@ testing idempotency
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 2428948025
|
||||
---
|
||||
> Checksum: 3026590807
|
||||
11c11
|
||||
< Datafile length: 16384 Keyfile length: 16384
|
||||
---
|
||||
@ -367,10 +307,6 @@ testing applying of CLRs to recreate table
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 2428948025
|
||||
---
|
||||
> Checksum: 0
|
||||
11c11
|
||||
< Datafile length: 16384 Keyfile length: 16384
|
||||
---
|
||||
@ -428,10 +364,6 @@ Dying on request without maria_commit()/maria_close()
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 221293111
|
||||
---
|
||||
> Checksum: 0
|
||||
11c11
|
||||
< Datafile length: 16384 Keyfile length: 16384
|
||||
---
|
||||
@ -445,10 +377,6 @@ testing idempotency
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 221293111
|
||||
---
|
||||
> Checksum: 0
|
||||
11c11
|
||||
< Datafile length: 16384 Keyfile length: 16384
|
||||
---
|
||||
@ -462,10 +390,6 @@ testing applying of CLRs to recreate table
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 221293111
|
||||
---
|
||||
> Checksum: 0
|
||||
11c11
|
||||
< Datafile length: 16384 Keyfile length: 16384
|
||||
---
|
||||
@ -487,10 +411,6 @@ testing applying of CLRs to recreate table
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 3697324514
|
||||
---
|
||||
> Checksum: 0
|
||||
11c11
|
||||
< Datafile length: 16384 Keyfile length: 16384
|
||||
---
|
||||
@ -508,10 +428,6 @@ Dying on request without maria_commit()/maria_close()
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 2428948025
|
||||
---
|
||||
> Checksum: 0
|
||||
11c11
|
||||
< Datafile length: 16384 Keyfile length: 16384
|
||||
---
|
||||
@ -525,10 +441,6 @@ testing idempotency
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 2428948025
|
||||
---
|
||||
> Checksum: 0
|
||||
11c11
|
||||
< Datafile length: 16384 Keyfile length: 16384
|
||||
---
|
||||
@ -542,10 +454,6 @@ testing applying of CLRs to recreate table
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 2428948025
|
||||
---
|
||||
> Checksum: 0
|
||||
11c11
|
||||
< Datafile length: 16384 Keyfile length: 16384
|
||||
---
|
||||
@ -603,10 +511,6 @@ Dying on request without maria_commit()/maria_close()
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 411409161
|
||||
---
|
||||
> Checksum: 0
|
||||
11c11
|
||||
< Datafile length: 49152 Keyfile length: 16384
|
||||
---
|
||||
@ -620,10 +524,6 @@ testing idempotency
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 411409161
|
||||
---
|
||||
> Checksum: 0
|
||||
11c11
|
||||
< Datafile length: 49152 Keyfile length: 16384
|
||||
---
|
||||
@ -637,10 +537,6 @@ testing applying of CLRs to recreate table
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 411409161
|
||||
---
|
||||
> Checksum: 0
|
||||
11c11
|
||||
< Datafile length: 49152 Keyfile length: 16384
|
||||
---
|
||||
@ -662,10 +558,6 @@ testing applying of CLRs to recreate table
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 4024695312
|
||||
---
|
||||
> Checksum: 0
|
||||
11c11
|
||||
< Datafile length: 49152 Keyfile length: 16384
|
||||
---
|
||||
@ -683,10 +575,6 @@ Dying on request without maria_commit()/maria_close()
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 529753687
|
||||
---
|
||||
> Checksum: 800025671
|
||||
11c11
|
||||
< Datafile length: 49152 Keyfile length: 16384
|
||||
---
|
||||
@ -700,10 +588,6 @@ testing idempotency
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 529753687
|
||||
---
|
||||
> Checksum: 800025671
|
||||
11c11
|
||||
< Datafile length: 49152 Keyfile length: 16384
|
||||
---
|
||||
@ -717,10 +601,6 @@ testing applying of CLRs to recreate table
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 529753687
|
||||
---
|
||||
> Checksum: 0
|
||||
11c11
|
||||
< Datafile length: 49152 Keyfile length: 16384
|
||||
---
|
||||
@ -778,10 +658,6 @@ Dying on request without maria_commit()/maria_close()
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 411409161
|
||||
---
|
||||
> Checksum: 0
|
||||
11c11
|
||||
< Datafile length: 49152 Keyfile length: 16384
|
||||
---
|
||||
@ -795,10 +671,6 @@ testing idempotency
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 411409161
|
||||
---
|
||||
> Checksum: 0
|
||||
11c11
|
||||
< Datafile length: 49152 Keyfile length: 16384
|
||||
---
|
||||
@ -812,10 +684,6 @@ testing applying of CLRs to recreate table
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 411409161
|
||||
---
|
||||
> Checksum: 0
|
||||
11c11
|
||||
< Datafile length: 49152 Keyfile length: 16384
|
||||
---
|
||||
@ -837,10 +705,6 @@ testing applying of CLRs to recreate table
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 4024695312
|
||||
---
|
||||
> Checksum: 0
|
||||
11c11
|
||||
< Datafile length: 49152 Keyfile length: 16384
|
||||
---
|
||||
@ -858,10 +722,6 @@ Dying on request without maria_commit()/maria_close()
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 529753687
|
||||
---
|
||||
> Checksum: 800025671
|
||||
11c11
|
||||
< Datafile length: 49152 Keyfile length: 16384
|
||||
---
|
||||
@ -875,10 +735,6 @@ testing idempotency
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 529753687
|
||||
---
|
||||
> Checksum: 800025671
|
||||
11c11
|
||||
< Datafile length: 49152 Keyfile length: 16384
|
||||
---
|
||||
@ -892,10 +748,6 @@ testing applying of CLRs to recreate table
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 529753687
|
||||
---
|
||||
> Checksum: 0
|
||||
11c11
|
||||
< Datafile length: 49152 Keyfile length: 16384
|
||||
---
|
||||
@ -953,10 +805,6 @@ Dying on request without maria_commit()/maria_close()
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 411409161
|
||||
---
|
||||
> Checksum: 0
|
||||
11c11
|
||||
< Datafile length: 49152 Keyfile length: 16384
|
||||
---
|
||||
@ -970,10 +818,6 @@ testing idempotency
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 411409161
|
||||
---
|
||||
> Checksum: 0
|
||||
11c11
|
||||
< Datafile length: 49152 Keyfile length: 16384
|
||||
---
|
||||
@ -987,10 +831,6 @@ testing applying of CLRs to recreate table
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 411409161
|
||||
---
|
||||
> Checksum: 0
|
||||
11c11
|
||||
< Datafile length: 49152 Keyfile length: 16384
|
||||
---
|
||||
@ -1012,10 +852,6 @@ testing applying of CLRs to recreate table
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 4024695312
|
||||
---
|
||||
> Checksum: 0
|
||||
11c11
|
||||
< Datafile length: 49152 Keyfile length: 16384
|
||||
---
|
||||
@ -1033,10 +869,6 @@ Dying on request without maria_commit()/maria_close()
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 529753687
|
||||
---
|
||||
> Checksum: 0
|
||||
11c11
|
||||
< Datafile length: 49152 Keyfile length: 16384
|
||||
---
|
||||
@ -1050,10 +882,6 @@ testing idempotency
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 529753687
|
||||
---
|
||||
> Checksum: 0
|
||||
11c11
|
||||
< Datafile length: 49152 Keyfile length: 16384
|
||||
---
|
||||
@ -1067,10 +895,6 @@ testing applying of CLRs to recreate table
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
7c7
|
||||
< Checksum: 529753687
|
||||
---
|
||||
> Checksum: 0
|
||||
11c11
|
||||
< Datafile length: 49152 Keyfile length: 16384
|
||||
---
|
||||
|
@ -27,11 +27,9 @@ int maria_update(register MARIA_HA *info, const uchar *oldrec, uchar *newrec)
|
||||
bool auto_key_changed=0;
|
||||
ulonglong changed;
|
||||
MARIA_SHARE *share=info->s;
|
||||
ha_checksum old_checksum;
|
||||
DBUG_ENTER("maria_update");
|
||||
LINT_INIT(new_key);
|
||||
LINT_INIT(changed);
|
||||
LINT_INIT(old_checksum);
|
||||
|
||||
DBUG_EXECUTE_IF("maria_pretend_crashed_table_on_usage",
|
||||
maria_print_error(info->s, HA_ERR_CRASHED);
|
||||
@ -59,16 +57,6 @@ int maria_update(register MARIA_HA *info, const uchar *oldrec, uchar *newrec)
|
||||
goto err_end; /* Record has changed */
|
||||
}
|
||||
|
||||
if (share->calc_checksum)
|
||||
{
|
||||
/*
|
||||
We can't use the row based checksum as this doesn't have enough
|
||||
precision.
|
||||
*/
|
||||
if (info->s->calc_checksum)
|
||||
old_checksum= (*info->s->calc_checksum)(info, oldrec);
|
||||
}
|
||||
|
||||
/* Calculate and check all unique constraints */
|
||||
key_changed=0;
|
||||
for (i=0 ; i < share->state.header.uniques ; i++)
|
||||
@ -137,19 +125,23 @@ int maria_update(register MARIA_HA *info, const uchar *oldrec, uchar *newrec)
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
If we are running with external locking, we must update the index file
|
||||
that something has changed.
|
||||
*/
|
||||
if (changed || !my_disable_locking)
|
||||
key_changed|= HA_STATE_CHANGED;
|
||||
|
||||
if (share->calc_checksum)
|
||||
{
|
||||
info->cur_row.checksum= (*share->calc_checksum)(info,newrec);
|
||||
info->state->checksum+= (info->cur_row.checksum - old_checksum);
|
||||
/* Store new checksum in index file header */
|
||||
key_changed|= HA_STATE_CHANGED;
|
||||
/*
|
||||
We can't use the row based checksum as this doesn't have enough
|
||||
precision (one byte, while the table's is more bytes).
|
||||
At least _ma_check_unique() modifies the 'newrec' record, so checksum
|
||||
has to be computed _after_ it. Nobody apparently modifies 'oldrec'.
|
||||
We need to pass the old row's checksum down to (*update_record)(), we do
|
||||
this via info->new_row.checksum (not intuitive but existing code
|
||||
mandated that cur_row is the new row).
|
||||
If (*update_record)() fails, table will be marked corrupted so no need
|
||||
to revert the live checksum change.
|
||||
*/
|
||||
info->state->checksum+= !share->now_transactional *
|
||||
((info->cur_row.checksum= (*share->calc_checksum)(info, newrec)) -
|
||||
(info->new_row.checksum= (*share->calc_checksum)(info, oldrec)));
|
||||
}
|
||||
{
|
||||
/*
|
||||
@ -165,14 +157,9 @@ int maria_update(register MARIA_HA *info, const uchar *oldrec, uchar *newrec)
|
||||
org_delete_link= share->state.dellink;
|
||||
if ((*share->update_record)(info, pos, oldrec, newrec))
|
||||
goto err;
|
||||
if (!key_changed &&
|
||||
(memcmp((char*) &state, (char*) info->state, sizeof(state)) ||
|
||||
org_split != share->state.split ||
|
||||
org_delete_link != share->state.dellink))
|
||||
key_changed|= HA_STATE_CHANGED; /* Must update index file */
|
||||
}
|
||||
if (auto_key_changed)
|
||||
set_if_bigger(info->s->state.auto_increment,
|
||||
set_if_bigger(share->state.auto_increment,
|
||||
ma_retrieve_auto_increment(info, newrec));
|
||||
|
||||
/*
|
||||
@ -195,8 +182,8 @@ int maria_update(register MARIA_HA *info, const uchar *oldrec, uchar *newrec)
|
||||
allow_break(); /* Allow SIGHUP & SIGINT */
|
||||
if (info->invalidator != 0)
|
||||
{
|
||||
DBUG_PRINT("info", ("invalidator... '%s' (update)", info->s->open_file_name));
|
||||
(*info->invalidator)(info->s->open_file_name);
|
||||
DBUG_PRINT("info", ("invalidator... '%s' (update)", share->open_file_name));
|
||||
(*info->invalidator)(share->open_file_name);
|
||||
info->invalidator=0;
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
@ -232,7 +219,7 @@ err:
|
||||
}
|
||||
else
|
||||
{
|
||||
maria_print_error(info->s, HA_ERR_CRASHED);
|
||||
maria_print_error(share, HA_ERR_CRASHED);
|
||||
maria_mark_crashed(info);
|
||||
}
|
||||
info->update= (HA_STATE_CHANGED | HA_STATE_AKTIV | HA_STATE_ROW_CHANGED |
|
||||
@ -243,7 +230,7 @@ err:
|
||||
allow_break(); /* Allow SIGHUP & SIGINT */
|
||||
if (save_errno == HA_ERR_KEY_NOT_FOUND)
|
||||
{
|
||||
maria_print_error(info->s, HA_ERR_CRASHED);
|
||||
maria_print_error(share, HA_ERR_CRASHED);
|
||||
save_errno=HA_ERR_CRASHED;
|
||||
}
|
||||
DBUG_RETURN(my_errno=save_errno);
|
||||
|
@ -162,10 +162,6 @@ int maria_write(MARIA_HA *info, uchar *record)
|
||||
rw_unlock(&share->key_root_lock[i]);
|
||||
}
|
||||
}
|
||||
/**
|
||||
@todo RECOVERY BUG
|
||||
this += must happen under log's mutex when writing the UNDO
|
||||
*/
|
||||
if (share->calc_write_checksum)
|
||||
info->cur_row.checksum= (*share->calc_write_checksum)(info,record);
|
||||
if (filepos != HA_OFFSET_ERROR)
|
||||
@ -176,7 +172,8 @@ int maria_write(MARIA_HA *info, uchar *record)
|
||||
@todo when we enable multiple writers, we will have to protect
|
||||
'records' and 'checksum' somehow.
|
||||
*/
|
||||
info->state->checksum+= info->cur_row.checksum;
|
||||
info->state->checksum+= !share->now_transactional *
|
||||
info->cur_row.checksum;
|
||||
}
|
||||
if (share->base.auto_key)
|
||||
set_if_bigger(info->s->state.auto_increment,
|
||||
|
@ -154,7 +154,7 @@ int main(int argc, char **argv)
|
||||
|
||||
enum options_mc {
|
||||
OPT_CHARSETS_DIR=256, OPT_SET_COLLATION,OPT_START_CHECK_POS,
|
||||
OPT_CORRECT_CHECKSUM, OPT_KEY_BUFFER_SIZE,
|
||||
OPT_CORRECT_CHECKSUM, OPT_PAGE_BUFFER_SIZE,
|
||||
OPT_KEY_CACHE_BLOCK_SIZE, OPT_MARIA_BLOCK_SIZE,
|
||||
OPT_READ_BUFFER_SIZE, OPT_WRITE_BUFFER_SIZE, OPT_SORT_BUFFER_SIZE,
|
||||
OPT_SORT_KEY_BLOCKS, OPT_DECODE_BITS, OPT_FT_MIN_WORD_LEN,
|
||||
@ -296,7 +296,7 @@ static struct my_option my_long_options[] =
|
||||
{"wait", 'w',
|
||||
"Wait if table is locked.",
|
||||
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{ "key_buffer_size", OPT_KEY_BUFFER_SIZE, "",
|
||||
{ "page_buffer_size", OPT_PAGE_BUFFER_SIZE, "",
|
||||
(uchar**) &check_param.use_buffers, (uchar**) &check_param.use_buffers, 0,
|
||||
GET_ULONG, REQUIRED_ARG, (long) USE_BUFFER_INIT, (long) MALLOC_OVERHEAD,
|
||||
(long) ~0L, (long) MALLOC_OVERHEAD, (long) IO_SIZE, 0},
|
||||
@ -1758,84 +1758,4 @@ err:
|
||||
} /* sort_record_index */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Check if maria_chk was killed by a signal
|
||||
This is overloaded by other programs that want to be able to abort
|
||||
sorting
|
||||
*/
|
||||
|
||||
static int not_killed= 0;
|
||||
|
||||
volatile int *_ma_killed_ptr(HA_CHECK *param __attribute__((unused)))
|
||||
{
|
||||
return ¬_killed; /* always NULL */
|
||||
}
|
||||
|
||||
/* print warnings and errors */
|
||||
/* VARARGS */
|
||||
|
||||
void _ma_check_print_info(HA_CHECK *param __attribute__((unused)),
|
||||
const char *fmt,...)
|
||||
{
|
||||
va_list args;
|
||||
DBUG_ENTER("_ma_check_print_info");
|
||||
DBUG_PRINT("enter", ("format: %s", fmt));
|
||||
|
||||
va_start(args,fmt);
|
||||
VOID(vfprintf(stdout, fmt, args));
|
||||
VOID(fputc('\n',stdout));
|
||||
va_end(args);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/* VARARGS */
|
||||
|
||||
void _ma_check_print_warning(HA_CHECK *param, const char *fmt,...)
|
||||
{
|
||||
va_list args;
|
||||
DBUG_ENTER("_ma_check_print_warning");
|
||||
DBUG_PRINT("enter", ("format: %s", fmt));
|
||||
|
||||
fflush(stdout);
|
||||
if (!param->warning_printed && !param->error_printed)
|
||||
{
|
||||
if (param->testflag & T_SILENT)
|
||||
fprintf(stderr,"%s: MARIA file %s\n",my_progname_short,
|
||||
param->isam_file_name);
|
||||
param->out_flag|= O_DATA_LOST;
|
||||
}
|
||||
param->warning_printed=1;
|
||||
va_start(args,fmt);
|
||||
fprintf(stderr,"%s: warning: ",my_progname_short);
|
||||
VOID(vfprintf(stderr, fmt, args));
|
||||
VOID(fputc('\n',stderr));
|
||||
fflush(stderr);
|
||||
va_end(args);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/* VARARGS */
|
||||
|
||||
void _ma_check_print_error(HA_CHECK *param, const char *fmt,...)
|
||||
{
|
||||
va_list args;
|
||||
DBUG_ENTER("_ma_check_print_error");
|
||||
DBUG_PRINT("enter", ("format: %s", fmt));
|
||||
|
||||
fflush(stdout);
|
||||
if (!param->warning_printed && !param->error_printed)
|
||||
{
|
||||
if (param->testflag & T_SILENT)
|
||||
fprintf(stderr,"%s: MARIA file %s\n",my_progname_short,param->isam_file_name);
|
||||
param->out_flag|= O_DATA_LOST;
|
||||
}
|
||||
param->error_printed|=1;
|
||||
va_start(args,fmt);
|
||||
fprintf(stderr,"%s: error: ",my_progname_short);
|
||||
VOID(vfprintf(stderr, fmt, args));
|
||||
VOID(fputc('\n',stderr));
|
||||
fflush(stderr);
|
||||
va_end(args);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
#include "ma_check_standalone.h"
|
||||
|
@ -632,7 +632,7 @@ typedef struct st_maria_s_param
|
||||
/* Used to store reference to pinned page */
|
||||
typedef struct st_pinned_page
|
||||
{
|
||||
PAGECACHE_PAGE_LINK link;
|
||||
PAGECACHE_BLOCK_LINK *link;
|
||||
enum pagecache_page_lock unlock;
|
||||
} MARIA_PINNED_PAGE;
|
||||
|
||||
@ -842,7 +842,7 @@ typedef struct st_maria_block_info
|
||||
#define UPDATE_AUTO_INC 8
|
||||
#define UPDATE_OPEN_COUNT 16
|
||||
|
||||
#define USE_BUFFER_INIT (((1024L*512L-MALLOC_OVERHEAD)/IO_SIZE)*IO_SIZE)
|
||||
#define USE_BUFFER_INIT (((1024L*1024L*10-MALLOC_OVERHEAD)/8192)*8192)
|
||||
#define READ_BUFFER_INIT (1024L*256L-MALLOC_OVERHEAD)
|
||||
#define SORT_BUFFER_INIT (2048L*1024L-MALLOC_OVERHEAD)
|
||||
#define MIN_SORT_BUFFER (4096-MALLOC_OVERHEAD)
|
||||
@ -906,7 +906,7 @@ my_bool _ma_check_status(void *param);
|
||||
void _ma_reset_status(MARIA_HA *maria);
|
||||
#include "ma_commit.h"
|
||||
|
||||
extern MARIA_HA *_ma_test_if_reopen(char *filename);
|
||||
extern MARIA_HA *_ma_test_if_reopen(const char *filename);
|
||||
my_bool _ma_check_table_is_closed(const char *name, const char *where);
|
||||
int _ma_open_datafile(MARIA_HA *info, MARIA_SHARE *share, File file_to_dup);
|
||||
int _ma_open_keyfile(MARIA_SHARE *share);
|
||||
@ -923,7 +923,10 @@ C_MODE_START
|
||||
int _ma_flush_table_files(MARIA_HA *info, uint flush_data_or_index,
|
||||
enum flush_type flush_type_for_data,
|
||||
enum flush_type flush_type_for_index);
|
||||
/* Functions needed by _ma_check (are overrided in MySQL) */
|
||||
/*
|
||||
Functions needed by _ma_check (are overridden in MySQL/ha_maria.cc).
|
||||
See ma_check_standalone.h .
|
||||
*/
|
||||
volatile int *_ma_killed_ptr(HA_CHECK *param);
|
||||
void _ma_check_print_error _VARARGS((HA_CHECK *param, const char *fmt, ...));
|
||||
void _ma_check_print_warning _VARARGS((HA_CHECK *param, const char *fmt, ...));
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include "ma_recovery.h"
|
||||
#include <my_getopt.h>
|
||||
|
||||
#define PCACHE_SIZE (1024*1024*10)
|
||||
#define LOG_FLAGS 0
|
||||
#define LOG_FILE_SIZE (1024L*1024L)
|
||||
|
||||
@ -30,13 +29,16 @@ 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_display_and_apply;
|
||||
static my_bool opt_only_display, opt_apply, opt_apply_undo, opt_silent;
|
||||
static ulong opt_page_buffer_size;
|
||||
static const char *my_progname_short;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
LSN lsn;
|
||||
char **default_argv;
|
||||
MY_INIT(argv[0]);
|
||||
my_progname_short= my_progname+dirname_length(my_progname);
|
||||
|
||||
load_defaults("my", load_default_groups, &argc, &argv);
|
||||
default_argv= argv;
|
||||
@ -63,7 +65,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
/* same page cache for log and data; assumes same page size... */
|
||||
DBUG_ASSERT(maria_block_size == TRANSLOG_PAGE_SIZE);
|
||||
if (init_pagecache(maria_pagecache, PCACHE_SIZE, 0, 0,
|
||||
if (init_pagecache(maria_pagecache, opt_page_buffer_size, 0, 0,
|
||||
TRANSLOG_PAGE_SIZE) == 0)
|
||||
{
|
||||
fprintf(stderr, "Got error in init_pagecache() (errno: %d)\n", errno);
|
||||
@ -100,15 +102,15 @@ int main(int argc, char **argv)
|
||||
LSN_IN_PARTS(lsn));
|
||||
|
||||
fprintf(stdout, "TRACE of the last maria_read_log\n");
|
||||
if (maria_apply_log(lsn, opt_display_and_apply, stdout,
|
||||
opt_display_and_apply, FALSE))
|
||||
if (maria_apply_log(lsn, opt_apply, opt_silent ? NULL : stdout,
|
||||
opt_apply_undo, FALSE))
|
||||
goto err;
|
||||
fprintf(stdout, "%s: SUCCESS\n", my_progname);
|
||||
fprintf(stdout, "%s: SUCCESS\n", my_progname_short);
|
||||
|
||||
goto end;
|
||||
err:
|
||||
/* don't touch anything more, in case we hit a bug */
|
||||
fprintf(stderr, "%s: FAILED\n", my_progname);
|
||||
fprintf(stderr, "%s: FAILED\n", my_progname_short);
|
||||
exit(1);
|
||||
end:
|
||||
maria_end();
|
||||
@ -119,21 +121,37 @@ end:
|
||||
}
|
||||
|
||||
|
||||
#include "ma_check_standalone.h"
|
||||
|
||||
|
||||
static struct my_option my_long_options[] =
|
||||
{
|
||||
{"apply", 'a',
|
||||
"Apply log to tables. Will display a lot of information if not run with --silent",
|
||||
(uchar **) &opt_apply, (uchar **) &opt_apply, 0,
|
||||
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
#ifndef DBUG_OFF
|
||||
{"debug", '#', "Output debug log. Often the argument is 'd:t:o,filename'.",
|
||||
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
|
||||
#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 about records's header",
|
||||
(uchar **) &opt_only_display, (uchar **) &opt_only_display, 0, GET_BOOL,
|
||||
NO_ARG,0, 0, 0, 0, 0, 0},
|
||||
{"display-and-apply", 'a',
|
||||
"like --only-display but displays more info and modifies tables",
|
||||
(uchar **) &opt_display_and_apply, (uchar **) &opt_display_and_apply, 0,
|
||||
{ "page_buffer_size", 'P', "",
|
||||
(uchar**) &opt_page_buffer_size, (uchar**) &opt_page_buffer_size, 0,
|
||||
GET_ULONG, REQUIRED_ARG, (long) USE_BUFFER_INIT,
|
||||
(long) MALLOC_OVERHEAD, (long) ~(ulong) 0, (long) MALLOC_OVERHEAD,
|
||||
(long) IO_SIZE, 0},
|
||||
{"silent", 's', "Print less information during apply/undo phase",
|
||||
(uchar **) &opt_silent, (uchar **) &opt_silent, 0,
|
||||
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
#ifndef DBUG_OFF
|
||||
{"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.",
|
||||
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
|
||||
#endif
|
||||
{"undo", 'u', "Apply undos to tables. (disable with --disable-undo)",
|
||||
(uchar **) &opt_apply_undo, (uchar **) &opt_apply_undo, 0,
|
||||
GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
|
||||
{"version", 'V', "Print version and exit.",
|
||||
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
@ -141,8 +159,8 @@ static struct my_option my_long_options[] =
|
||||
|
||||
static void print_version(void)
|
||||
{
|
||||
VOID(printf("%s Ver 1.0 for %s on %s\n",
|
||||
my_progname, SYSTEM_TYPE, MACHINE_TYPE));
|
||||
VOID(printf("%s Ver 1.1 for %s on %s\n",
|
||||
my_progname_short, SYSTEM_TYPE, MACHINE_TYPE));
|
||||
NETWARE_SET_SCREEN_MODE(1);
|
||||
}
|
||||
|
||||
@ -156,7 +174,7 @@ static void usage(void)
|
||||
|
||||
puts("Display and apply log records from a MARIA transaction log");
|
||||
puts("found in the current directory (for now)");
|
||||
VOID(printf("\nUsage: %s OPTIONS\n", my_progname));
|
||||
VOID(printf("\nUsage: %s OPTIONS\n", my_progname_short));
|
||||
puts("You need to use one of -o or -a");
|
||||
my_print_help(my_long_options);
|
||||
print_defaults("my", load_default_groups);
|
||||
@ -174,6 +192,9 @@ get_one_option(int optid __attribute__((unused)),
|
||||
case '?':
|
||||
usage();
|
||||
exit(0);
|
||||
case 'V':
|
||||
print_version();
|
||||
exit(0);
|
||||
#ifndef DBUG_OFF
|
||||
case '#':
|
||||
DBUG_SET_INITIAL(argument ? argument : default_dbug_option);
|
||||
@ -187,12 +208,13 @@ static void get_options(int *argc,char ***argv)
|
||||
{
|
||||
int ho_error;
|
||||
|
||||
my_progname= argv[0][0];
|
||||
|
||||
if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
|
||||
exit(ho_error);
|
||||
|
||||
if ((opt_only_display + opt_display_and_apply) != 1)
|
||||
if (!opt_apply)
|
||||
opt_apply_undo= FALSE;
|
||||
|
||||
if ((opt_only_display + opt_apply) != 1)
|
||||
{
|
||||
usage();
|
||||
exit(1);
|
||||
|
@ -407,7 +407,7 @@ static void version()
|
||||
|
||||
static my_bool
|
||||
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
||||
char *argument)
|
||||
char *argument __attribute__((unused)))
|
||||
{
|
||||
switch(optid) {
|
||||
case 'V':
|
||||
|
@ -198,8 +198,8 @@ int main(int argc __attribute__((unused)), char *argv[])
|
||||
trn->first_undo_lsn= TRANSACTION_LOGGED_LONG_ID;
|
||||
if (translog_write_record(&lsn,
|
||||
LOGREC_FIXED_RECORD_0LSN_EXAMPLE,
|
||||
trn, NULL,
|
||||
6, TRANSLOG_INTERNAL_PARTS + 1, parts, NULL))
|
||||
trn, NULL, 6, TRANSLOG_INTERNAL_PARTS + 1,
|
||||
parts, NULL, NULL))
|
||||
{
|
||||
fprintf(stderr, "Can't write record #%lu\n", (ulong) 0);
|
||||
translog_destroy();
|
||||
@ -220,8 +220,8 @@ int main(int argc __attribute__((unused)), char *argv[])
|
||||
/* check auto-count feature */
|
||||
parts[TRANSLOG_INTERNAL_PARTS + 1].str= NULL;
|
||||
parts[TRANSLOG_INTERNAL_PARTS + 1].length= 0;
|
||||
if (translog_write_record(&lsn, LOGREC_FIXED_RECORD_1LSN_EXAMPLE,
|
||||
trn, NULL, LSN_STORE_SIZE, 0, parts, NULL))
|
||||
if (translog_write_record(&lsn, LOGREC_FIXED_RECORD_1LSN_EXAMPLE, trn,
|
||||
NULL, LSN_STORE_SIZE, 0, parts, NULL, NULL))
|
||||
{
|
||||
fprintf(stderr, "1 Can't write reference defore record #%lu\n",
|
||||
(ulong) i);
|
||||
@ -241,7 +241,7 @@ int main(int argc __attribute__((unused)), char *argv[])
|
||||
if (translog_write_record(&lsn,
|
||||
LOGREC_VARIABLE_RECORD_1LSN_EXAMPLE,
|
||||
trn, NULL, 0, TRANSLOG_INTERNAL_PARTS + 2,
|
||||
parts, NULL))
|
||||
parts, NULL, NULL))
|
||||
{
|
||||
fprintf(stderr, "1 Can't write var reference defore record #%lu\n",
|
||||
(ulong) i);
|
||||
@ -259,8 +259,8 @@ int main(int argc __attribute__((unused)), char *argv[])
|
||||
parts[TRANSLOG_INTERNAL_PARTS + 0].length= 23;
|
||||
if (translog_write_record(&lsn,
|
||||
LOGREC_FIXED_RECORD_2LSN_EXAMPLE,
|
||||
trn, NULL,
|
||||
23, TRANSLOG_INTERNAL_PARTS + 1, parts, NULL))
|
||||
trn, NULL, 23, TRANSLOG_INTERNAL_PARTS + 1,
|
||||
parts, NULL, NULL))
|
||||
{
|
||||
fprintf(stderr, "0 Can't write reference defore record #%lu\n",
|
||||
(ulong) i);
|
||||
@ -280,7 +280,8 @@ int main(int argc __attribute__((unused)), char *argv[])
|
||||
if (translog_write_record(&lsn,
|
||||
LOGREC_VARIABLE_RECORD_2LSN_EXAMPLE,
|
||||
trn, NULL, 14 + rec_len,
|
||||
TRANSLOG_INTERNAL_PARTS + 2, parts, NULL))
|
||||
TRANSLOG_INTERNAL_PARTS + 2, parts, NULL,
|
||||
NULL))
|
||||
{
|
||||
fprintf(stderr, "0 Can't write var reference defore record #%lu\n",
|
||||
(ulong) i);
|
||||
@ -297,7 +298,7 @@ int main(int argc __attribute__((unused)), char *argv[])
|
||||
LOGREC_FIXED_RECORD_0LSN_EXAMPLE,
|
||||
trn, NULL, 6,
|
||||
TRANSLOG_INTERNAL_PARTS + 1,
|
||||
parts, NULL))
|
||||
parts, NULL, NULL))
|
||||
{
|
||||
fprintf(stderr, "Can't write record #%lu\n", (ulong) i);
|
||||
translog_destroy();
|
||||
@ -316,7 +317,7 @@ int main(int argc __attribute__((unused)), char *argv[])
|
||||
LOGREC_VARIABLE_RECORD_0LSN_EXAMPLE,
|
||||
trn, NULL, rec_len,
|
||||
TRANSLOG_INTERNAL_PARTS + 1,
|
||||
parts, NULL))
|
||||
parts, NULL, NULL))
|
||||
{
|
||||
fprintf(stderr, "Can't write variable record #%lu\n", (ulong) i);
|
||||
translog_destroy();
|
||||
@ -363,7 +364,7 @@ int main(int argc __attribute__((unused)), char *argv[])
|
||||
read_ok(&rec);
|
||||
translog_free_record_header(&rec);
|
||||
lsn= first_lsn;
|
||||
if (translog_init_scanner(first_lsn, 1, &scanner))
|
||||
if (translog_init_scanner(first_lsn, 1, &scanner, 0))
|
||||
{
|
||||
fprintf(stderr, "scanner init failed\n");
|
||||
goto err;
|
||||
|
@ -106,7 +106,7 @@ int main(int argc __attribute__((unused)), char *argv[])
|
||||
LOGREC_FIXED_RECORD_0LSN_EXAMPLE,
|
||||
&dummy_transaction_object, NULL, 6,
|
||||
TRANSLOG_INTERNAL_PARTS + 1,
|
||||
parts, NULL))
|
||||
parts, NULL, NULL))
|
||||
{
|
||||
fprintf(stderr, "Can't write record #%lu\n", (ulong) 0);
|
||||
translog_destroy();
|
||||
|
@ -96,7 +96,7 @@ int main(int argc __attribute__((unused)), char *argv[])
|
||||
LOGREC_FIXED_RECORD_0LSN_EXAMPLE,
|
||||
&dummy_transaction_object, NULL, 6,
|
||||
TRANSLOG_INTERNAL_PARTS + 1,
|
||||
parts, NULL))
|
||||
parts, NULL, NULL))
|
||||
{
|
||||
fprintf(stderr, "Can't write record #%lu\n", (ulong) 0);
|
||||
translog_destroy();
|
||||
|
@ -194,8 +194,8 @@ int main(int argc __attribute__((unused)), char *argv[])
|
||||
trn->short_id= 0;
|
||||
trn->first_undo_lsn= TRANSACTION_LOGGED_LONG_ID;
|
||||
if (translog_write_record(&lsn, LOGREC_FIXED_RECORD_0LSN_EXAMPLE,
|
||||
trn, NULL,
|
||||
6, TRANSLOG_INTERNAL_PARTS + 1, parts, NULL))
|
||||
trn, NULL, 6, TRANSLOG_INTERNAL_PARTS + 1, parts,
|
||||
NULL, NULL))
|
||||
{
|
||||
fprintf(stderr, "Can't write record #%lu\n", (ulong) 0);
|
||||
translog_destroy();
|
||||
@ -214,10 +214,9 @@ int main(int argc __attribute__((unused)), char *argv[])
|
||||
parts[TRANSLOG_INTERNAL_PARTS + 0].length= LSN_STORE_SIZE;
|
||||
trn->short_id= i % 0xFFFF;
|
||||
if (translog_write_record(&lsn,
|
||||
LOGREC_FIXED_RECORD_1LSN_EXAMPLE,
|
||||
trn, NULL,
|
||||
LSN_STORE_SIZE,
|
||||
TRANSLOG_INTERNAL_PARTS + 1, parts, NULL))
|
||||
LOGREC_FIXED_RECORD_1LSN_EXAMPLE, trn, NULL,
|
||||
LSN_STORE_SIZE, TRANSLOG_INTERNAL_PARTS + 1,
|
||||
parts, NULL, NULL))
|
||||
{
|
||||
fprintf(stderr, "1 Can't write reference before record #%lu\n",
|
||||
(ulong) i);
|
||||
@ -237,7 +236,7 @@ int main(int argc __attribute__((unused)), char *argv[])
|
||||
LOGREC_VARIABLE_RECORD_1LSN_EXAMPLE,
|
||||
trn, NULL, LSN_STORE_SIZE + rec_len,
|
||||
TRANSLOG_INTERNAL_PARTS + 2,
|
||||
parts, NULL))
|
||||
parts, NULL, NULL))
|
||||
{
|
||||
fprintf(stderr, "1 Can't write var reference before record #%lu\n",
|
||||
(ulong) i);
|
||||
@ -256,9 +255,8 @@ int main(int argc __attribute__((unused)), char *argv[])
|
||||
trn->short_id= i % 0xFFFF;
|
||||
if (translog_write_record(&lsn,
|
||||
LOGREC_FIXED_RECORD_2LSN_EXAMPLE,
|
||||
trn, NULL, 23,
|
||||
TRANSLOG_INTERNAL_PARTS + 1,
|
||||
parts, NULL))
|
||||
trn, NULL, 23, TRANSLOG_INTERNAL_PARTS + 1,
|
||||
parts, NULL, NULL))
|
||||
{
|
||||
fprintf(stderr, "0 Can't write reference before record #%lu\n",
|
||||
(ulong) i);
|
||||
@ -279,7 +277,7 @@ int main(int argc __attribute__((unused)), char *argv[])
|
||||
LOGREC_VARIABLE_RECORD_2LSN_EXAMPLE,
|
||||
trn, NULL, LSN_STORE_SIZE * 2 + rec_len,
|
||||
TRANSLOG_INTERNAL_PARTS + 2,
|
||||
parts, NULL))
|
||||
parts, NULL, NULL))
|
||||
{
|
||||
fprintf(stderr, "0 Can't write var reference before record #%lu\n",
|
||||
(ulong) i);
|
||||
@ -296,7 +294,7 @@ int main(int argc __attribute__((unused)), char *argv[])
|
||||
if (translog_write_record(&lsn,
|
||||
LOGREC_FIXED_RECORD_0LSN_EXAMPLE,
|
||||
trn, NULL, 6,
|
||||
TRANSLOG_INTERNAL_PARTS + 1, parts, NULL))
|
||||
TRANSLOG_INTERNAL_PARTS + 1, parts, NULL, NULL))
|
||||
{
|
||||
fprintf(stderr, "Can't write record #%lu\n", (ulong) i);
|
||||
translog_destroy();
|
||||
@ -314,7 +312,7 @@ int main(int argc __attribute__((unused)), char *argv[])
|
||||
if (translog_write_record(&lsn,
|
||||
LOGREC_VARIABLE_RECORD_0LSN_EXAMPLE,
|
||||
trn, NULL, rec_len,
|
||||
TRANSLOG_INTERNAL_PARTS + 1, parts, NULL))
|
||||
TRANSLOG_INTERNAL_PARTS + 1, parts, NULL, NULL))
|
||||
{
|
||||
fprintf(stderr, "Can't write variable record #%lu\n", (ulong) i);
|
||||
translog_destroy();
|
||||
@ -378,7 +376,7 @@ int main(int argc __attribute__((unused)), char *argv[])
|
||||
ok(1, "read record");
|
||||
translog_free_record_header(&rec);
|
||||
lsn= first_lsn;
|
||||
if (translog_init_scanner(first_lsn, 1, &scanner))
|
||||
if (translog_init_scanner(first_lsn, 1, &scanner, 0))
|
||||
{
|
||||
fprintf(stderr, "scanner init failed\n");
|
||||
goto err;
|
||||
|
@ -138,7 +138,7 @@ void writer(int num)
|
||||
if (translog_write_record(&lsn,
|
||||
LOGREC_FIXED_RECORD_0LSN_EXAMPLE,
|
||||
&trn, NULL, 6, TRANSLOG_INTERNAL_PARTS + 1,
|
||||
parts, NULL))
|
||||
parts, NULL, NULL))
|
||||
{
|
||||
fprintf(stderr, "Can't write LOGREC_FIXED_RECORD_0LSN_EXAMPLE record #%lu "
|
||||
"thread %i\n", (ulong) i, num);
|
||||
@ -155,7 +155,7 @@ void writer(int num)
|
||||
LOGREC_VARIABLE_RECORD_0LSN_EXAMPLE,
|
||||
&trn, NULL,
|
||||
len, TRANSLOG_INTERNAL_PARTS + 1,
|
||||
parts, NULL))
|
||||
parts, NULL, NULL))
|
||||
{
|
||||
fprintf(stderr, "Can't write variable record #%lu\n", (ulong) i);
|
||||
translog_destroy();
|
||||
@ -307,7 +307,7 @@ int main(int argc __attribute__((unused)),
|
||||
LOGREC_FIXED_RECORD_0LSN_EXAMPLE,
|
||||
&dummy_transaction_object, NULL, 6,
|
||||
TRANSLOG_INTERNAL_PARTS + 1,
|
||||
parts, NULL))
|
||||
parts, NULL, NULL))
|
||||
{
|
||||
fprintf(stderr, "Can't write the first record\n");
|
||||
translog_destroy();
|
||||
@ -373,7 +373,7 @@ int main(int argc __attribute__((unused)),
|
||||
|
||||
bzero(indeces, sizeof(indeces));
|
||||
|
||||
if (translog_init_scanner(first_lsn, 1, &scanner))
|
||||
if (translog_init_scanner(first_lsn, 1, &scanner, 0))
|
||||
{
|
||||
fprintf(stderr, "scanner init failed\n");
|
||||
goto err;
|
||||
|
@ -85,7 +85,7 @@ int main(int argc __attribute__((unused)), char *argv[])
|
||||
LOGREC_FIXED_RECORD_0LSN_EXAMPLE,
|
||||
&dummy_transaction_object, NULL, 6,
|
||||
TRANSLOG_INTERNAL_PARTS + 1,
|
||||
parts, NULL))
|
||||
parts, NULL, NULL))
|
||||
{
|
||||
fprintf(stderr, "Can't write record #%lu\n", (ulong) 0);
|
||||
translog_destroy();
|
||||
|
@ -97,7 +97,7 @@ int main(int argc __attribute__((unused)), char *argv[])
|
||||
LOGREC_FIXED_RECORD_0LSN_EXAMPLE,
|
||||
&dummy_transaction_object, NULL, 6,
|
||||
TRANSLOG_INTERNAL_PARTS + 1,
|
||||
parts, NULL))
|
||||
parts, NULL, NULL))
|
||||
{
|
||||
fprintf(stderr, "Can't write record #%lu\n", (ulong) 0);
|
||||
translog_destroy();
|
||||
|
@ -80,7 +80,7 @@ int main(int argc __attribute__((unused)), char *argv[])
|
||||
LOGREC_FIXED_RECORD_0LSN_EXAMPLE,
|
||||
&dummy_transaction_object, NULL, 6,
|
||||
TRANSLOG_INTERNAL_PARTS + 1,
|
||||
parts, NULL))
|
||||
parts, NULL, NULL))
|
||||
{
|
||||
fprintf(stderr, "Can't write record #%lu\n", (ulong) 0);
|
||||
translog_destroy();
|
||||
@ -102,7 +102,7 @@ int main(int argc __attribute__((unused)), char *argv[])
|
||||
LOGREC_FIXED_RECORD_0LSN_EXAMPLE,
|
||||
&dummy_transaction_object, NULL, 6,
|
||||
TRANSLOG_INTERNAL_PARTS + 1,
|
||||
parts, NULL))
|
||||
parts, NULL, NULL))
|
||||
{
|
||||
fprintf(stderr, "Can't write record #%lu\n", (ulong) 0);
|
||||
translog_destroy();
|
||||
@ -125,7 +125,7 @@ int main(int argc __attribute__((unused)), char *argv[])
|
||||
if (translog_write_record(&lsn,
|
||||
LOGREC_VARIABLE_RECORD_0LSN_EXAMPLE,
|
||||
&dummy_transaction_object, NULL, LONG_BUFFER_SIZE,
|
||||
TRANSLOG_INTERNAL_PARTS + 1, parts, NULL))
|
||||
TRANSLOG_INTERNAL_PARTS + 1, parts, NULL, NULL))
|
||||
{
|
||||
fprintf(stderr, "Can't write variable record\n");
|
||||
translog_destroy();
|
||||
@ -150,7 +150,7 @@ int main(int argc __attribute__((unused)), char *argv[])
|
||||
LOGREC_FIXED_RECORD_0LSN_EXAMPLE,
|
||||
&dummy_transaction_object, NULL, 6,
|
||||
TRANSLOG_INTERNAL_PARTS + 1,
|
||||
parts, NULL))
|
||||
parts, NULL, NULL))
|
||||
{
|
||||
fprintf(stderr, "Can't write last record\n");
|
||||
translog_destroy();
|
||||
|
Reference in New Issue
Block a user