1
0
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:
unknown
2007-10-04 23:33:55 +03:00
38 changed files with 1374 additions and 1041 deletions

View File

@ -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

View 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"

View File

@ -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;

View File

@ -3488,9 +3488,11 @@ 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))
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,
@ -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);

View File

@ -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 \

View File

@ -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 &&

View File

@ -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)
{
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 -
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;

View File

@ -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);

View File

@ -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;
/*

View 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 &not_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;
}

View File

@ -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.

View File

@ -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));
/*

View File

@ -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;
/*

View File

@ -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->delete_record)(info, record))
goto err; /* Remove record from database */
if (share->calc_checksum)
{
/*
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->cur_row.checksum= (*share->calc_checksum)(info, record);
}
if ((*share->delete_record)(info, record))
goto err; /* Remove record from database */
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;
}

View File

@ -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. */

View File

@ -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

View File

@ -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,

View File

@ -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)
{

View File

@ -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,
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,7 +692,7 @@ 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) +
blocks= (ulong) (use_mem / (sizeof(PAGECACHE_BLOCK_LINK) +
2 * sizeof(PAGECACHE_HASH_LINK) +
sizeof(PAGECACHE_HASH_LINK*) *
5/4 + block_size));
@ -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,
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,8 +2822,9 @@ 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*/,
@ -2829,6 +2833,17 @@ static enum pagecache_page_pin lock_to_pin[]=
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,7 +2927,12 @@ 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);
@ -2923,6 +2946,7 @@ restart:
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,9 +3233,9 @@ 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;
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);

View File

@ -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 */
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,17 +154,20 @@ 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,
extern ulong init_pagecache(PAGECACHE *pagecache, size_t use_mem,
uint division_limit, uint age_threshold,
uint block_size);
extern int resize_pagecache(PAGECACHE *pagecache,
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,
@ -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,

View 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(&param);
param.isam_file_name= info->s->open_file_name;
param.testflag= uint4korr(rec->header);
if (maria_repair(&param, info, info->s->open_file_name,
param.testflag & T_QUICK))
if (maria_repair(&param, 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
/*

View File

@ -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);

View File

@ -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
---

View File

@ -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);

View File

@ -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,

View File

@ -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 &not_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"

View File

@ -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, ...));

View File

@ -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);

View File

@ -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':

View File

@ -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;

View File

@ -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();

View File

@ -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();

View File

@ -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;

View File

@ -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;

View File

@ -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();

View File

@ -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();

View File

@ -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();