Commit 704b39a1 authored by unknown's avatar unknown

- moving pagecache.h from include/ to storage/maria as it is Maria-

specific
- adding TRN::first_undo_lsn, needed to know when a log can be deleted;
this variable must be set under log's mutex and that leads to setting
TRN::rec_lsn, TRN::undo_lsn and TRN::first_undo_lsn in a
inwrite_rec_hook; adding implementation of one hook for REDOs and one
for UNDOs. Thus translog_write_record() always uses TRN and so does
not need a short_id argument, can find it from TRN.
- Monty's patch for the last Valgrind error in the tree.
- Log handler's unit tests fail but Sanja says it's known


include/Makefile.am:
  pagecache.h moved and renamed
include/maria.h:
  pagecache.h moved and renamed
sql/handler.h:
  pagecache.h moved and renamed
storage/maria/Makefile.am:
  pagecache.h moved and renamed
storage/maria/ha_maria.cc:
  adding an assertion which sounds logical
storage/maria/ma_blockrec.c:
  trn->rec_lsn and trn->undo_lsn are now set via hooks inside the log
  record's writing; this allows to also set trn->first_undo_lsn
  needed to compute the log's low-water mark.
  The PAGERANGE_STORE_SIZE -> PAGE_STORE_SIZE is Monty's fix to a
  Valgrind error.
storage/maria/ma_loghandler.c:
  "tcb" renamed to "trn". Log handler now knows what is a transaction,
  and finds short_id from trn. trn's rec_lsn, undo_lsn, first_undo_lsn
  are now set by some inwrite_rec_hookS (one for REDOs, one for UNDOs).
  The HAVE_purify blocks are Monty's fix to a Valgrind error.
storage/maria/ma_loghandler.h:
  Log handler functions use TRN, that needs a forward declaration
storage/maria/ma_pagecache.c:
  pagecache.h was moved and renamed
storage/maria/ma_pagecache.h:
  pagecache.h was moved and renamed
storage/maria/ma_pagecaches.c:
  pagecache.h was moved and renamed
storage/maria/trnman.c:
  initializing some members of TRN.
storage/maria/trnman.h:
  TRN::first_undo_lsn needed for log's low-water mark calculation
  (which will serve to know which logs can be deleted)
storage/maria/unittest/ma_test_loghandler-t.c:
  translog_write_record() now needs a valid TRN
storage/maria/unittest/ma_test_loghandler_multigroup-t.c:
  translog_write_record() now needs a valid TRN
storage/maria/unittest/ma_test_loghandler_multithread-t.c:
  translog_write_record() now needs a valid TRN
storage/maria/unittest/ma_test_loghandler_pagecache-t.c:
  translog_write_record() now needs a valid TRN
storage/maria/unittest/test_file.h:
  pagecache.h was moved and renamed
parent fdfb5148
......@@ -37,7 +37,7 @@ noinst_HEADERS = config-win.h config-netware.h lf.h my_bit.h \
mysql_version.h.in my_handler.h my_time.h decimal.h \
my_vle.h my_user.h my_atomic.h atomic/nolock.h \
atomic/rwlock.h atomic/x86-gcc.h atomic/x86-msvc.h \
my_libwrap.h pagecache.h wqueue.h
my_libwrap.h wqueue.h
# Remove built files and the symlinked directories
CLEANFILES = $(BUILT_SOURCES) readline openssl
......
......@@ -27,9 +27,7 @@ extern "C" {
#ifndef _m_ctype_h
#include <m_ctype.h>
#endif
#ifndef _pagecache_h
#include "pagecache.h"
#endif
#include "../storage/maria/ma_pagecache.h"
#include "my_handler.h"
#include "ft_global.h"
#include <myisamchk.h>
......
......@@ -23,7 +23,7 @@
#include <my_handler.h>
#include <ft_global.h>
#include <keycache.h>
#include <pagecache.h>
#include "../storage/maria/ma_pagecache.h"
#ifndef NO_HASH
#define NO_HASH /* Not yet implemented */
......
......@@ -54,7 +54,7 @@ noinst_HEADERS = maria_def.h ma_rt_index.h ma_rt_key.h ma_rt_mbr.h \
ma_sp_defs.h ma_fulltext.h ma_ftdefs.h ma_ft_test1.h \
ma_ft_eval.h trnman.h lockman.h tablockman.h \
ma_control_file.h ha_maria.h ma_blockrec.h \
ma_loghandler.h ma_loghandler_lsn.h
ma_loghandler.h ma_loghandler_lsn.h ma_pagecache.h
ma_test1_DEPENDENCIES= $(LIBRARIES)
ma_test1_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmaria.a \
$(top_builddir)/storage/myisam/libmyisam.a \
......
......@@ -1919,8 +1919,15 @@ int ha_maria::start_stmt(THD *thd, thr_lock_type lock_type)
if (file->s->base.transactional)
{
DBUG_ASSERT(trn); // this may be called only after external_lock()
DBUG_ASSERT(trnman_has_locked_tables(trn));
DBUG_ASSERT(lock_type != F_UNLCK);
/* As external_lock() was already called, don't increment locked_tables */
/*
As external_lock() was already called, don't increment locked_tables.
Note that we call the function below possibly several times when
statement starts (once per table). This is ok as long as that function
does cheap operations. Otherwise, we will need to do it only on first
call to start_stmt().
*/
trnman_new_statement(trn);
}
return 0;
......
......@@ -1141,12 +1141,9 @@ static my_bool write_tail(MARIA_HA *info,
log_array[TRANSLOG_INTERNAL_PARTS + 0].length= sizeof(log_data);
log_array[TRANSLOG_INTERNAL_PARTS + 1].str= (char*) row_pos.data;
log_array[TRANSLOG_INTERNAL_PARTS + 1].length= length;
if (translog_write_record(!info->trn->rec_lsn ? &info->trn->rec_lsn : &lsn,
LOGREC_REDO_INSERT_ROW_TAIL,
info->trn->short_id, NULL, share,
sizeof(log_data) + length,
TRANSLOG_INTERNAL_PARTS + 2,
log_array))
if (translog_write_record(&lsn, LOGREC_REDO_INSERT_ROW_TAIL,
info->trn, share, sizeof(log_data) + length,
TRANSLOG_INTERNAL_PARTS + 2, log_array))
DBUG_RETURN(1);
}
......@@ -1398,10 +1395,8 @@ static my_bool free_full_pages(MARIA_HA *info, MARIA_ROW *row)
log_array[TRANSLOG_INTERNAL_PARTS + 0].length= sizeof(log_data);
log_array[TRANSLOG_INTERNAL_PARTS + 1].str= row->extents;
log_array[TRANSLOG_INTERNAL_PARTS + 1].length= extents_length;
if (translog_write_record(!info->trn->rec_lsn ? &info->trn->rec_lsn : &lsn,
LOGREC_REDO_PURGE_BLOCKS,
info->trn->short_id, NULL, info->s,
sizeof(log_data) + extents_length,
if (translog_write_record(&lsn, LOGREC_REDO_PURGE_BLOCKS, info->trn,
info->s, sizeof(log_data) + extents_length,
TRANSLOG_INTERNAL_PARTS + 2, log_array))
DBUG_RETURN(1);
......@@ -1416,9 +1411,6 @@ static my_bool free_full_pages(MARIA_HA *info, MARIA_ROW *row)
NOTES
This is very similar to free_full_pages()
We don't have to update trn->rec_lsn here as before calling this function
we have already generated REDO's for deleting the HEAD block.
RETURN
0 ok
1 error
......@@ -1449,8 +1441,7 @@ static my_bool free_full_page_range(MARIA_HA *info, ulonglong page, uint count)
log_array[TRANSLOG_INTERNAL_PARTS + 0].length= sizeof(log_data);
if (translog_write_record(&lsn, LOGREC_REDO_PURGE_BLOCKS,
info->trn->short_id, NULL, info->s,
sizeof(log_data),
info->trn, info->s, sizeof(log_data),
TRANSLOG_INTERNAL_PARTS + 1, log_array))
res= 1;
......@@ -1957,10 +1948,8 @@ static my_bool write_block_record(MARIA_HA *info,
log_array[TRANSLOG_INTERNAL_PARTS + 0].length= sizeof(log_data);
log_array[TRANSLOG_INTERNAL_PARTS + 1].str= (char*) row_pos->data;
log_array[TRANSLOG_INTERNAL_PARTS + 1].length= data_length;
if (translog_write_record(!info->trn->rec_lsn ? &info->trn->rec_lsn : &lsn,
LOGREC_REDO_INSERT_ROW_HEAD,
info->trn->short_id, NULL, share,
sizeof(log_data) + data_length,
if (translog_write_record(&lsn, LOGREC_REDO_INSERT_ROW_HEAD, info->trn,
share, sizeof(log_data) + data_length,
TRANSLOG_INTERNAL_PARTS + 2, log_array))
goto disk_err;
}
......@@ -2077,9 +2066,8 @@ static my_bool write_block_record(MARIA_HA *info,
/* trn->rec_lsn is already set earlier in this function */
error= translog_write_record(&lsn, LOGREC_REDO_INSERT_ROW_BLOBS,
info->trn->short_id, NULL, share,
log_entry_length, (uint) (log_array_pos -
log_array),
info->trn, share, log_entry_length,
(uint) (log_array_pos - log_array),
log_array);
if (log_array != tmp_log_array)
my_free((gptr) log_array, MYF(0));
......@@ -2109,11 +2097,9 @@ static my_bool write_block_record(MARIA_HA *info,
if (!old_record)
{
/* Write UNDO log record for the INSERT */
if (translog_write_record(&info->trn->undo_lsn, LOGREC_UNDO_ROW_INSERT,
info->trn->short_id, NULL, share,
sizeof(log_data),
TRANSLOG_INTERNAL_PARTS + 1,
log_array))
if (translog_write_record(&lsn, LOGREC_UNDO_ROW_INSERT,
info->trn, share, sizeof(log_data),
TRANSLOG_INTERNAL_PARTS + 1, log_array))
goto disk_err;
}
else
......@@ -2125,9 +2111,8 @@ static my_bool write_block_record(MARIA_HA *info,
info->log_row_parts +
TRANSLOG_INTERNAL_PARTS + 1,
&row_parts_count);
if (translog_write_record(&info->trn->undo_lsn, LOGREC_UNDO_ROW_UPDATE,
info->trn->short_id, NULL, share,
sizeof(log_data) + row_length,
if (translog_write_record(&lsn, LOGREC_UNDO_ROW_UPDATE, info->trn,
share, sizeof(log_data) + row_length,
TRANSLOG_INTERNAL_PARTS + 1 + row_parts_count,
log_array))
goto disk_err;
......@@ -2293,6 +2278,7 @@ my_bool _ma_write_abort_block_record(MARIA_HA *info)
if (info->s->base.transactional)
{
LSN lsn;
LEX_STRING log_array[TRANSLOG_INTERNAL_PARTS + 1];
uchar log_data[LSN_STORE_SIZE];
......@@ -2302,15 +2288,16 @@ my_bool _ma_write_abort_block_record(MARIA_HA *info)
really undo a failed insert. Note that this UNDO will cause recover
to ignore the LOGREC_UNDO_ROW_INSERT that is the previous entry
in the UNDO chain.
We will soon change that: we will here execute the UNDO records
generated while we were trying to write the row; this will log some CLRs
which will replace this LOGREC_UNDO_PURGE. RECOVERY TODO BUG.
*/
lsn_store(log_data, info->trn->undo_lsn);
log_array[TRANSLOG_INTERNAL_PARTS + 0].str= (char*) log_data;
log_array[TRANSLOG_INTERNAL_PARTS + 0].length= sizeof(log_data);
if (translog_write_record(&info->trn->undo_lsn, LOGREC_UNDO_ROW_PURGE,
info->trn->short_id, NULL, info->s,
sizeof(log_data),
TRANSLOG_INTERNAL_PARTS + 1,
log_array))
if (translog_write_record(&lsn, LOGREC_UNDO_ROW_PURGE,
info->trn, info->s, sizeof(log_data),
TRANSLOG_INTERNAL_PARTS + 1, log_array))
res= 1;
}
_ma_unpin_all_pages(info, info->trn->undo_lsn);
......@@ -2534,12 +2521,10 @@ static my_bool delete_head_or_tail(MARIA_HA *info,
log_array[TRANSLOG_INTERNAL_PARTS + 0].str= (char*) log_data;
log_array[TRANSLOG_INTERNAL_PARTS + 0].length= sizeof(log_data);
if (translog_write_record(!info->trn->rec_lsn ? &info->trn->rec_lsn : &lsn,
(head ? LOGREC_REDO_PURGE_ROW_HEAD :
if (translog_write_record(&lsn, (head ? LOGREC_REDO_PURGE_ROW_HEAD :
LOGREC_REDO_PURGE_ROW_TAIL),
info->trn->short_id, NULL, share,
sizeof(log_data), TRANSLOG_INTERNAL_PARTS + 1,
log_array))
info->trn, share, sizeof(log_data),
TRANSLOG_INTERNAL_PARTS + 1, log_array))
DBUG_RETURN(1);
if (pagecache_write(share->pagecache,
&info->dfile, page, 0,
......@@ -2564,14 +2549,12 @@ static my_bool delete_head_or_tail(MARIA_HA *info,
pagerange_store(log_data + FILEID_STORE_SIZE, 1);
page_store(log_data+ FILEID_STORE_SIZE + PAGERANGE_STORE_SIZE, page);
pagerange_store(log_data + FILEID_STORE_SIZE + PAGERANGE_STORE_SIZE +
PAGERANGE_STORE_SIZE, 1);
PAGE_STORE_SIZE, 1);
log_array[TRANSLOG_INTERNAL_PARTS + 0].str= (char*) log_data;
log_array[TRANSLOG_INTERNAL_PARTS + 0].length= sizeof(log_data);
if (translog_write_record(!info->trn->rec_lsn ? &info->trn->rec_lsn : &lsn,
LOGREC_REDO_PURGE_BLOCKS,
info->trn->short_id, NULL, share,
sizeof(log_data), TRANSLOG_INTERNAL_PARTS + 1,
log_array))
if (translog_write_record(&lsn, LOGREC_REDO_PURGE_BLOCKS,
info->trn, share, sizeof(log_data),
TRANSLOG_INTERNAL_PARTS + 1, log_array))
DBUG_RETURN(1);
DBUG_ASSERT(empty_space >= info->s->bitmap.sizes[0]);
}
......@@ -2640,6 +2623,7 @@ my_bool _ma_delete_block_record(MARIA_HA *info, const byte *record)
if (info->s->base.transactional)
{
LSN lsn;
uchar log_data[LSN_STORE_SIZE + FILEID_STORE_SIZE + PAGE_STORE_SIZE +
DIR_COUNT_SIZE];
size_t row_length;
......@@ -2658,9 +2642,8 @@ my_bool _ma_delete_block_record(MARIA_HA *info, const byte *record)
TRANSLOG_INTERNAL_PARTS + 1,
&row_parts_count);
if (translog_write_record(&info->trn->undo_lsn, LOGREC_UNDO_ROW_DELETE,
info->trn->short_id, NULL, info->s,
sizeof(log_data) + row_length,
if (translog_write_record(&lsn, LOGREC_UNDO_ROW_DELETE, info->trn,
info->s, sizeof(log_data) + row_length,
TRANSLOG_INTERNAL_PARTS + 1 + row_parts_count,
info->log_row_parts))
goto err;
......
......@@ -15,6 +15,7 @@
#include "maria_def.h"
#include "ma_blockrec.h"
#include "trnman.h"
/* number of opened log files in the pagecache (should be at least 2) */
#define OPENED_FILES_NUM 3
......@@ -187,11 +188,11 @@ enum record_class
#define TRANSLOG_CLSN_MAX_LEN 5 /* Maximum length of compressed LSN */
typedef my_bool(*prewrite_rec_hook) (enum translog_record_type type,
void *tcb, struct st_maria_share *share,
TRN *trn, struct st_maria_share *share,
struct st_translog_parts *parts);
typedef my_bool(*inwrite_rec_hook) (enum translog_record_type type,
void *tcb,
TRN *trn,
LSN *lsn,
struct st_translog_parts *parts);
......@@ -225,6 +226,13 @@ struct st_log_record_type_descriptor
};
static my_bool write_hook_for_redo(enum translog_record_type type,
TRN *trn, LSN *lsn,
struct st_translog_parts *parts);
static my_bool write_hook_for_undo(enum translog_record_type type,
TRN *trn, LSN *lsn,
struct st_translog_parts *parts);
/*
Initialize log_record_type_descriptors
......@@ -240,29 +248,31 @@ static LOG_DESC INIT_LOGREC_RESERVED_FOR_CHUNKS23=
static LOG_DESC INIT_LOGREC_REDO_INSERT_ROW_HEAD=
{LOGRECTYPE_VARIABLE_LENGTH, 0,
FILEID_STORE_SIZE + PAGE_STORE_SIZE + DIRPOS_STORE_SIZE, NULL, NULL, NULL, 0};
FILEID_STORE_SIZE + PAGE_STORE_SIZE + DIRPOS_STORE_SIZE, NULL,
write_hook_for_redo, NULL, 0};
static LOG_DESC INIT_LOGREC_REDO_INSERT_ROW_TAIL=
{LOGRECTYPE_VARIABLE_LENGTH, 0, 9, NULL, NULL, NULL, 0};
/* QQ shouldn't this 9 be 8? */
{LOGRECTYPE_VARIABLE_LENGTH, 0, 9, NULL, write_hook_for_redo, NULL, 0};
static LOG_DESC INIT_LOGREC_REDO_INSERT_ROW_BLOB=
{LOGRECTYPE_VARIABLE_LENGTH, 0, 8, NULL, NULL, NULL, 0};
{LOGRECTYPE_VARIABLE_LENGTH, 0, 8, NULL, write_hook_for_redo, NULL, 0};
/*QQQ:TODO:header???*/
static LOG_DESC INIT_LOGREC_REDO_INSERT_ROW_BLOBS=
{LOGRECTYPE_VARIABLE_LENGTH, 0, 0, NULL, NULL, NULL, 0};
{LOGRECTYPE_VARIABLE_LENGTH, 0, 0, NULL, write_hook_for_redo, NULL, 0};
static LOG_DESC INIT_LOGREC_REDO_PURGE_ROW_HEAD=
{LOGRECTYPE_FIXEDLENGTH,
FILEID_STORE_SIZE + PAGE_STORE_SIZE + DIRPOS_STORE_SIZE,
FILEID_STORE_SIZE + PAGE_STORE_SIZE + DIRPOS_STORE_SIZE,
NULL, NULL, NULL, 0};
NULL, write_hook_for_redo, NULL, 0};
static LOG_DESC INIT_LOGREC_REDO_PURGE_ROW_TAIL=
{LOGRECTYPE_FIXEDLENGTH,
FILEID_STORE_SIZE + PAGE_STORE_SIZE + DIRPOS_STORE_SIZE,
FILEID_STORE_SIZE + PAGE_STORE_SIZE + DIRPOS_STORE_SIZE,
NULL, NULL, NULL, 0};
NULL, write_hook_for_redo, NULL, 0};
/* QQQ: TODO: variable and fixed size??? */
static LOG_DESC INIT_LOGREC_REDO_PURGE_BLOCKS=
......@@ -271,22 +281,22 @@ static LOG_DESC INIT_LOGREC_REDO_PURGE_BLOCKS=
PAGERANGE_STORE_SIZE,
FILEID_STORE_SIZE + PAGERANGE_STORE_SIZE + PAGE_STORE_SIZE +
PAGERANGE_STORE_SIZE,
NULL, NULL, NULL, 0};
NULL, write_hook_for_redo, NULL, 0};
static LOG_DESC INIT_LOGREC_REDO_DELETE_ROW=
{LOGRECTYPE_FIXEDLENGTH, 16, 16, NULL, NULL, NULL, 0};
{LOGRECTYPE_FIXEDLENGTH, 16, 16, NULL, write_hook_for_redo, NULL, 0};
static LOG_DESC INIT_LOGREC_REDO_UPDATE_ROW_HEAD=
{LOGRECTYPE_VARIABLE_LENGTH, 0, 9, NULL, NULL, NULL, 0};
{LOGRECTYPE_VARIABLE_LENGTH, 0, 9, NULL, write_hook_for_redo, NULL, 0};
static LOG_DESC INIT_LOGREC_REDO_INDEX=
{LOGRECTYPE_VARIABLE_LENGTH, 0, 9, NULL, NULL, NULL, 0};
{LOGRECTYPE_VARIABLE_LENGTH, 0, 9, NULL, write_hook_for_redo, NULL, 0};
static LOG_DESC INIT_LOGREC_REDO_UNDELETE_ROW=
{LOGRECTYPE_FIXEDLENGTH, 16, 16, NULL, NULL, NULL, 0};
{LOGRECTYPE_FIXEDLENGTH, 16, 16, NULL, write_hook_for_redo, NULL, 0};
static LOG_DESC INIT_LOGREC_CLR_END=
{LOGRECTYPE_PSEUDOFIXEDLENGTH, 5, 5, NULL, NULL, NULL, 1};
{LOGRECTYPE_PSEUDOFIXEDLENGTH, 5, 5, NULL, write_hook_for_redo, NULL, 1};
static LOG_DESC INIT_LOGREC_PURGE_END=
{LOGRECTYPE_PSEUDOFIXEDLENGTH, 5, 5, NULL, NULL, NULL, 1};
......@@ -295,27 +305,27 @@ static LOG_DESC INIT_LOGREC_UNDO_ROW_INSERT=
{LOGRECTYPE_FIXEDLENGTH,
LSN_STORE_SIZE + FILEID_STORE_SIZE + PAGE_STORE_SIZE + DIRPOS_STORE_SIZE,
LSN_STORE_SIZE + FILEID_STORE_SIZE + PAGE_STORE_SIZE + DIRPOS_STORE_SIZE,
NULL, NULL, NULL, 0};
NULL, write_hook_for_undo, NULL, 0};
static LOG_DESC INIT_LOGREC_UNDO_ROW_DELETE=
{LOGRECTYPE_VARIABLE_LENGTH, 0,
LSN_STORE_SIZE + FILEID_STORE_SIZE + PAGE_STORE_SIZE + DIRPOS_STORE_SIZE,
NULL, NULL, NULL, 0};
NULL, write_hook_for_undo, NULL, 0};
static LOG_DESC INIT_LOGREC_UNDO_ROW_UPDATE=
{LOGRECTYPE_VARIABLE_LENGTH, 0,
LSN_STORE_SIZE + FILEID_STORE_SIZE + PAGE_STORE_SIZE + DIRPOS_STORE_SIZE,
NULL, NULL, NULL, 1};
NULL, write_hook_for_undo, NULL, 1};
static LOG_DESC INIT_LOGREC_UNDO_ROW_PURGE=
{LOGRECTYPE_PSEUDOFIXEDLENGTH, LSN_STORE_SIZE, LSN_STORE_SIZE,
NULL, NULL, NULL, 1};
static LOG_DESC INIT_LOGREC_UNDO_KEY_INSERT=
{LOGRECTYPE_VARIABLE_LENGTH, 0, 10, NULL, NULL, NULL, 1};
{LOGRECTYPE_VARIABLE_LENGTH, 0, 10, NULL, write_hook_for_undo, NULL, 1};
static LOG_DESC INIT_LOGREC_UNDO_KEY_DELETE=
{LOGRECTYPE_VARIABLE_LENGTH, 0, 15, NULL, NULL, NULL, 0};
{LOGRECTYPE_VARIABLE_LENGTH, 0, 15, NULL, write_hook_for_undo, NULL, 0};
static LOG_DESC INIT_LOGREC_PREPARE=
{LOGRECTYPE_VARIABLE_LENGTH, 0, 0, NULL, NULL, NULL, 0};
......@@ -2528,7 +2538,7 @@ static my_bool translog_write_parts_on_page(TRANSLOG_ADDRESS *horizon,
translog_write_variable_record_1group_header()
parts Descriptor of record source parts
type The log record type
short_trid Sort transaction ID or 0 if it has no sense
short_trid Short transaction ID or 0 if it has no sense
header_length Calculated header length of chunk type 0
chunk0_header Buffer for the chunk header writing
*/
......@@ -2915,12 +2925,12 @@ static translog_size_t translog_get_current_group_size()
translog_write_variable_record_1group()
lsn LSN of the record will be written here
type the log record type
short_trid Sort transaction ID or 0 if it has no sense
short_trid Short transaction ID or 0 if it has no sense
parts Descriptor of record source parts
buffer_to_flush Buffer which have to be flushed if it is not 0
header_length Calculated header length of chunk type 0
tcb Transaction control block pointer for hooks by
record log type
trn Transaction structure pointer for hooks by
record log type, for short_id
RETURN
0 OK
......@@ -2934,7 +2944,7 @@ translog_write_variable_record_1group(LSN *lsn,
struct st_translog_parts *parts,
struct st_translog_buffer
*buffer_to_flush, uint16 header_length,
void *tcb)
TRN *trn)
{
TRANSLOG_ADDRESS horizon;
struct st_buffer_cursor cursor;
......@@ -2947,7 +2957,7 @@ translog_write_variable_record_1group(LSN *lsn,
*lsn= horizon= log_descriptor.horizon;
if (log_record_type_descriptor[type].inwrite_hook &&
(*log_record_type_descriptor[type].inwrite_hook)(type, tcb, lsn, parts))
(*log_record_type_descriptor[type].inwrite_hook)(type, trn, lsn, parts))
{
translog_unlock();
DBUG_RETURN(1);
......@@ -3069,12 +3079,12 @@ translog_write_variable_record_1group(LSN *lsn,
translog_write_variable_record_1chunk()
lsn LSN of the record will be written here
type the log record type
short_trid Sort transaction ID or 0 if it has no sense
short_trid Short transaction ID or 0 if it has no sense
parts Descriptor of record source parts
buffer_to_flush Buffer which have to be flushed if it is not 0
header_length Calculated header length of chunk type 0
tcb Transaction control block pointer for hooks by
record log type
trn Transaction structure pointer for hooks by
record log type, for short_id
RETURN
0 OK
......@@ -3088,7 +3098,7 @@ translog_write_variable_record_1chunk(LSN *lsn,
struct st_translog_parts *parts,
struct st_translog_buffer
*buffer_to_flush, uint16 header_length,
void *tcb)
TRN *trn)
{
int rc;
byte chunk0_header[1 + 2 + 5 + 2];
......@@ -3099,7 +3109,7 @@ translog_write_variable_record_1chunk(LSN *lsn,
*lsn= log_descriptor.horizon;
if (log_record_type_descriptor[type].inwrite_hook &&
(*log_record_type_descriptor[type].inwrite_hook)(type, tcb,
(*log_record_type_descriptor[type].inwrite_hook)(type, trn,
lsn, parts))
{
translog_unlock();
......@@ -3399,13 +3409,13 @@ static my_bool translog_relative_LSN_encode(struct st_translog_parts *parts,
translog_write_variable_record_mgroup()
lsn LSN of the record will be written here
type the log record type
short_trid Sort transaction ID or 0 if it has no sense
short_trid Short transaction ID or 0 if it has no sense
parts Descriptor of record source parts
buffer_to_flush Buffer which have to be flushed if it is not 0
header_length Header length calculated for 1 group
buffer_rest Beginning from which we plan to write in full pages
tcb Transaction control block pointer for hooks by
record log type
trn Transaction structure pointer for hooks by
record log type, for short_id
RETURN
0 OK
......@@ -3421,7 +3431,7 @@ translog_write_variable_record_mgroup(LSN *lsn,
*buffer_to_flush,
uint16 header_length,
translog_size_t buffer_rest,
void *tcb)
TRN *trn)
{
TRANSLOG_ADDRESS horizon;
struct st_buffer_cursor cursor;
......@@ -3757,7 +3767,7 @@ translog_write_variable_record_mgroup(LSN *lsn,
first_chunk0= 0;
*lsn= horizon;
if (log_record_type_descriptor[type].inwrite_hook &&
(*log_record_type_descriptor[type].inwrite_hook) (type, tcb,
(*log_record_type_descriptor[type].inwrite_hook) (type, trn,
lsn, parts))
goto err;
}
......@@ -3831,10 +3841,10 @@ translog_write_variable_record_mgroup(LSN *lsn,
translog_write_variable_record()
lsn LSN of the record will be written here
type the log record type
short_trid Sort transaction ID or 0 if it has no sense
short_trid Short transaction ID or 0 if it has no sense
parts Descriptor of record source parts
tcb Transaction control block pointer for hooks by
record log type
trn Transaction structure pointer for hooks by
record log type, for short_id
RETURN
0 OK
......@@ -3845,7 +3855,7 @@ static my_bool translog_write_variable_record(LSN *lsn,
enum translog_record_type type,
SHORT_TRANSACTION_ID short_trid,
struct st_translog_parts *parts,
void *tcb)
TRN *trn)
{
struct st_translog_buffer *buffer_to_flush= NULL;
uint header_length1= 1 + 2 + 2 +
......@@ -3920,7 +3930,7 @@ static my_bool translog_write_variable_record(LSN *lsn,
/* following function makes translog_unlock(); */
DBUG_RETURN(translog_write_variable_record_1chunk(lsn, type, short_trid,
parts, buffer_to_flush,
header_length1, tcb));
header_length1, trn));
}
buffer_rest= translog_get_current_group_size();
......@@ -3930,13 +3940,13 @@ static my_bool translog_write_variable_record(LSN *lsn,
/* following function makes translog_unlock(); */
DBUG_RETURN(translog_write_variable_record_1group(lsn, type, short_trid,
parts, buffer_to_flush,
header_length1, tcb));
header_length1, trn));
}
/* following function makes translog_unlock(); */
DBUG_RETURN(translog_write_variable_record_mgroup(lsn, type, short_trid,
parts, buffer_to_flush,
header_length1,
buffer_rest, tcb));
buffer_rest, trn));
}
......@@ -3947,10 +3957,10 @@ static my_bool translog_write_variable_record(LSN *lsn,
translog_write_fixed_record()
lsn LSN of the record will be written here
type the log record type
short_trid Sort transaction ID or 0 if it has no sense
short_trid Short transaction ID or 0 if it has no sense
parts Descriptor of record source parts
tcb Transaction control block pointer for hooks by
record log type
trn Transaction structure pointer for hooks by
record log type, for short_id
RETURN
0 OK
......@@ -3961,7 +3971,7 @@ static my_bool translog_write_fixed_record(LSN *lsn,
enum translog_record_type type,
SHORT_TRANSACTION_ID short_trid,
struct st_translog_parts *parts,
void *tcb)
TRN *trn)
{
struct st_translog_buffer *buffer_to_flush= NULL;
byte chunk1_header[1 + 2];
......@@ -4012,7 +4022,7 @@ static my_bool translog_write_fixed_record(LSN *lsn,
*lsn= log_descriptor.horizon;
if (log_record_type_descriptor[type].inwrite_hook &&
(*log_record_type_descriptor[type].inwrite_hook) (type, tcb,
(*log_record_type_descriptor[type].inwrite_hook) (type, trn,
lsn, parts))
{
rc= 1;
......@@ -4074,9 +4084,9 @@ static my_bool translog_write_fixed_record(LSN *lsn,
translog_write_record()
lsn LSN of the record will be written here
type the log record type
short_trid Sort transaction ID or 0 if it has no sense
tcb Transaction control block pointer for hooks by
record log type
trn Transaction structure pointer for hooks by
record log type, for short_id
share MARIA_SHARE of table or NULL
rec_len record length or 0 (count it)
part_no number of parts or 0 (count it)
parts_data zero ended (in case of number of parts is 0)
......@@ -4091,8 +4101,7 @@ static my_bool translog_write_fixed_record(LSN *lsn,
my_bool translog_write_record(LSN *lsn,
enum translog_record_type type,
SHORT_TRANSACTION_ID short_trid,
void *tcb, struct st_maria_share *share,
TRN *trn, struct st_maria_share *share,
translog_size_t rec_len,
uint part_no,
LEX_STRING *parts_data)
......@@ -4100,6 +4109,7 @@ my_bool translog_write_record(LSN *lsn,
struct st_translog_parts parts;
LEX_STRING *part;
int rc;
uint short_trid= trn->short_id;
DBUG_ENTER("translog_write_record");
DBUG_PRINT("enter", ("type: %u ShortTrID: %u",
(uint) type, (uint)short_trid));
......@@ -4169,17 +4179,17 @@ my_bool translog_write_record(LSN *lsn,
/* process this parts */
if (!(rc= (log_record_type_descriptor[type].prewrite_hook &&
(*log_record_type_descriptor[type].prewrite_hook) (type, tcb,
(*log_record_type_descriptor[type].prewrite_hook) (type, trn,
share,
&parts))))
{
switch (log_record_type_descriptor[type].class) {
case LOGRECTYPE_VARIABLE_LENGTH:
rc= translog_write_variable_record(lsn, type, short_trid, &parts, tcb);
rc= translog_write_variable_record(lsn, type, short_trid, &parts, trn);
break;
case LOGRECTYPE_PSEUDOFIXEDLENGTH:
case LOGRECTYPE_FIXEDLENGTH:
rc= translog_write_fixed_record(lsn, type, short_trid, &parts, tcb);
rc= translog_write_fixed_record(lsn, type, short_trid, &parts, trn);
break;
case LOGRECTYPE_NOT_ALLOWED:
default:
......@@ -4745,7 +4755,7 @@ translog_read_record_header_from_buffer(byte *page,
TRANSLOG_CHUNK_FIXED);
buff->type= (page[page_offset] & TRANSLOG_REC_TYPE);
buff->short_trid= uint2korr(page + page_offset + 1);
DBUG_PRINT("info", ("Type %u, Sort TrID %u, LSN (%lu,0x%lx)",
DBUG_PRINT("info", ("Type %u, Short TrID %u, LSN (%lu,0x%lx)",
(uint) buff->type, (uint)buff->short_trid,
(ulong) LSN_FILE_NO(buff->lsn),
(ulong) LSN_OFFSET(buff->lsn)));
......@@ -5386,3 +5396,32 @@ my_bool translog_flush(LSN lsn)
translog_unlock();
DBUG_RETURN(rc);
}
static my_bool write_hook_for_redo(enum translog_record_type type
__attribute__ ((unused)),
TRN *trn, LSN *lsn,
struct st_translog_parts *parts
__attribute__ ((unused)))
{
if (trn->rec_lsn == 0)
trn->rec_lsn= *lsn;
return 0;
}
static my_bool write_hook_for_undo(enum translog_record_type type
__attribute__ ((unused)),
TRN *trn, LSN *lsn,
struct st_translog_parts *parts
__attribute__ ((unused)))
{
trn->undo_lsn= *lsn;
if (trn->first_undo_lsn == 0)
trn->first_undo_lsn= *lsn;
return 0;
/*
when we implement purging, we will specialize this hook: UNDO_PURGE
records will additionally set trn->undo_purge_lsn
*/
}
......@@ -180,6 +180,7 @@ struct st_translog_reader_data
my_bool eor; /* end of the record */
};
struct st_transaction;
#ifdef __cplusplus
extern "C" {
#endif
......@@ -191,8 +192,8 @@ extern my_bool translog_init(const char *directory, uint32 log_file_max_size,
extern my_bool translog_write_record(LSN *lsn,
enum translog_record_type type,
SHORT_TRANSACTION_ID short_trid,
void *tcb, struct st_maria_share *share,
struct st_transaction *trn,
struct st_maria_share *share,
translog_size_t rec_len,
uint part_no,
LEX_STRING *parts_data);
......
......@@ -41,7 +41,7 @@
#include "maria_def.h"
#include <m_string.h>
#include <pagecache.h>
#include "ma_pagecache.h"
#include <my_bit.h>
#include <errno.h>
#include <stdarg.h>
......
......@@ -16,11 +16,11 @@
/* Page cache variable structures */
#ifndef _pagecache_h
#define _pagecache_h
#ifndef _ma_pagecache_h
#define _ma_pagecache_h
C_MODE_START
#include "../storage/maria/ma_loghandler_lsn.h"
#include "ma_loghandler_lsn.h"
#include <m_string.h>
/* Type of the page */
......
......@@ -23,7 +23,7 @@
*/
#include "maria_def.h"
#include <pagecache.h>
#include "ma_pagecache.h"
#include <hash.h>
#include <m_string.h>
#include "../../mysys/my_safehash.h"
......
......@@ -298,7 +298,7 @@ TRN *trnman_new_trn(pthread_mutex_t *mutex, pthread_cond_t *cond,
trn->min_read_from= trn->trid;
trn->commit_trid= 0;
trn->undo_lsn= 0;
trn->rec_lsn= trn->undo_lsn= trn->first_undo_lsn= 0;
trn->locks.mutex= mutex;
trn->locks.cond= cond;
......
......@@ -45,7 +45,7 @@ struct st_transaction
LF_PINS *pins;
TrID trid, min_read_from, commit_trid;
TRN *next, *prev;
LSN rec_lsn, undo_lsn;
LSN rec_lsn, undo_lsn, first_undo_lsn;
uint locked_tables;
/* Note! if locks.loid is 0, trn is NOT initialized */
};
......
......@@ -2,12 +2,14 @@
#include <stdio.h>
#include <errno.h>
#include <tap.h>
#include "../trnman.h"
extern my_bool maria_log_remove();
#ifndef DBUG_OFF
static const char *default_dbug_option;
#endif
static TRN *trn= &dummy_transaction_object;
#define PCACHE_SIZE (1024*1024*10)
......@@ -166,9 +168,10 @@ int main(int argc __attribute__((unused)), char *argv[])
int4store(long_tr_id, 0);
parts[TRANSLOG_INTERNAL_PARTS + 0].str= (char*)long_tr_id;
parts[TRANSLOG_INTERNAL_PARTS + 0].length= 6;
trn->short_id= 0;
if (translog_write_record(&lsn,
LOGREC_LONG_TRANSACTION_ID,
0, NULL, NULL,
trn, NULL,
6, TRANSLOG_INTERNAL_PARTS + 1, parts))
{
fprintf(stderr, "Can't write record #%lu\n", (ulong) 0);
......@@ -181,6 +184,7 @@ int main(int argc __attribute__((unused)), char *argv[])
for (i= 1; i < ITERATIONS; i++)
{
trn->short_id= i % 0xFFFF;
if (i % 2)
{
lsn_store(lsn_buff, lsn_base);
......@@ -189,7 +193,7 @@ 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_CLR_END, (i % 0xFFFF), NULL,
if (translog_write_record(&lsn, LOGREC_CLR_END, trn,
NULL, LSN_STORE_SIZE, 0, parts))
{
fprintf(stderr, "1 Can't write reference defore record #%lu\n",
......@@ -209,8 +213,7 @@ int main(int argc __attribute__((unused)), char *argv[])
/* check record length auto-counting */
if (translog_write_record(&lsn,
LOGREC_UNDO_KEY_INSERT,
(i % 0xFFFF),
NULL, NULL, 0, TRANSLOG_INTERNAL_PARTS + 2,
trn, NULL, 0, TRANSLOG_INTERNAL_PARTS + 2,
parts))
{
fprintf(stderr, "1 Can't write var reference defore record #%lu\n",
......@@ -229,7 +232,7 @@ int main(int argc __attribute__((unused)), char *argv[])
parts[TRANSLOG_INTERNAL_PARTS + 0].length= 23;
if (translog_write_record(&lsn,
LOGREC_UNDO_ROW_DELETE,
(i % 0xFFFF), NULL, NULL,
trn, NULL,
23, TRANSLOG_INTERNAL_PARTS + 1, parts))
{
fprintf(stderr, "0 Can't write reference defore record #%lu\n",
......@@ -249,8 +252,7 @@ int main(int argc __attribute__((unused)), char *argv[])
parts[TRANSLOG_INTERNAL_PARTS + 1].length= rec_len;
if (translog_write_record(&lsn,
LOGREC_UNDO_KEY_DELETE,
(i % 0xFFFF),
NULL, NULL, 14 + rec_len,
trn, NULL, 14 + rec_len,
TRANSLOG_INTERNAL_PARTS + 2, parts))
{
fprintf(stderr, "0 Can't write var reference defore record #%lu\n",
......@@ -266,7 +268,7 @@ int main(int argc __attribute__((unused)), char *argv[])
parts[TRANSLOG_INTERNAL_PARTS + 0].length= 6;
if (translog_write_record(&lsn,
LOGREC_LONG_TRANSACTION_ID,
(i % 0xFFFF), NULL, NULL, 6,
trn, NULL, 6,
TRANSLOG_INTERNAL_PARTS + 1,
parts))
{
......@@ -285,7 +287,7 @@ int main(int argc __attribute__((unused)), char *argv[])
parts[TRANSLOG_INTERNAL_PARTS + 0].length= rec_len;
if (translog_write_record(&lsn,
LOGREC_REDO_INSERT_ROW_HEAD,
(i % 0xFFFF), NULL, NULL, rec_len,
trn, NULL, rec_len,
TRANSLOG_INTERNAL_PARTS + 1,
parts))
{
......
......@@ -2,12 +2,14 @@
#include <stdio.h>
#include <errno.h>
#include <tap.h>
#include "../trnman.h"
extern my_bool maria_log_remove();
#ifndef DBUG_OFF
static const char *default_dbug_option;
#endif
static TRN *trn= &dummy_transaction_object;
#define PCACHE_SIZE (1024*1024*10)
......@@ -186,7 +188,8 @@ int main(int argc __attribute__((unused)), char *argv[])
int4store(long_tr_id, 0);
parts[TRANSLOG_INTERNAL_PARTS + 0].str= (char*)long_tr_id;
parts[TRANSLOG_INTERNAL_PARTS + 0].length= 6;
if (translog_write_record(&lsn, LOGREC_LONG_TRANSACTION_ID, 0, NULL, NULL,
trn->short_id= 0;
if (translog_write_record(&lsn, LOGREC_LONG_TRANSACTION_ID, trn, NULL,
6, TRANSLOG_INTERNAL_PARTS + 1, parts))
{
fprintf(stderr, "Can't write record #%lu\n", (ulong) 0);
......@@ -204,9 +207,10 @@ int main(int argc __attribute__((unused)), char *argv[])
lsn_store(lsn_buff, lsn_base);
parts[TRANSLOG_INTERNAL_PARTS + 0].str= (char*)lsn_buff;
parts[TRANSLOG_INTERNAL_PARTS + 0].length= LSN_STORE_SIZE;
trn->short_id= i % 0xFFFF;
if (translog_write_record(&lsn,
LOGREC_CLR_END,
(i % 0xFFFF), NULL, NULL,
trn, NULL,
LSN_STORE_SIZE,
TRANSLOG_INTERNAL_PARTS + 1, parts))
{
......@@ -223,10 +227,10 @@ int main(int argc __attribute__((unused)), char *argv[])
parts[TRANSLOG_INTERNAL_PARTS + 0].length= LSN_STORE_SIZE;
parts[TRANSLOG_INTERNAL_PARTS + 1].str= (char*)long_buffer;
parts[TRANSLOG_INTERNAL_PARTS + 1].length= rec_len;
trn->short_id= i % 0xFFFF;
if (translog_write_record(&lsn,
LOGREC_UNDO_KEY_INSERT,
(i % 0xFFFF),
NULL, NULL, LSN_STORE_SIZE + rec_len,
trn, NULL, LSN_STORE_SIZE + rec_len,
TRANSLOG_INTERNAL_PARTS + 2,
parts))
{
......@@ -244,9 +248,10 @@ int main(int argc __attribute__((unused)), char *argv[])
lsn_store(lsn_buff + LSN_STORE_SIZE, first_lsn);
parts[TRANSLOG_INTERNAL_PARTS + 1].str= (char*)lsn_buff;
parts[TRANSLOG_INTERNAL_PARTS + 1].length= 23;
trn->short_id= i % 0xFFFF;
if (translog_write_record(&lsn,
LOGREC_UNDO_ROW_DELETE,
(i % 0xFFFF), NULL, NULL, 23,
trn, NULL, 23,
TRANSLOG_INTERNAL_PARTS + 1,
parts))
{
......@@ -264,10 +269,10 @@ int main(int argc __attribute__((unused)), char *argv[])
parts[TRANSLOG_INTERNAL_PARTS + 0].length= LSN_STORE_SIZE * 2;
parts[TRANSLOG_INTERNAL_PARTS + 1].str= (char*)long_buffer;
parts[TRANSLOG_INTERNAL_PARTS + 1].length= rec_len;
trn->short_id= i % 0xFFFF;
if (translog_write_record(&lsn,
LOGREC_UNDO_KEY_DELETE,
(i % 0xFFFF),
NULL, NULL, LSN_STORE_SIZE * 2 + rec_len,
trn, NULL, LSN_STORE_SIZE * 2 + rec_len,
TRANSLOG_INTERNAL_PARTS + 2,
parts))
{
......@@ -282,9 +287,10 @@ int main(int argc __attribute__((unused)), char *argv[])
int4store(long_tr_id, i);
parts[TRANSLOG_INTERNAL_PARTS + 0].str= (char*)long_tr_id;
parts[TRANSLOG_INTERNAL_PARTS + 0].length= 6;
trn->short_id= i % 0xFFFF;
if (translog_write_record(&lsn,
LOGREC_LONG_TRANSACTION_ID,
(i % 0xFFFF), NULL, NULL, 6,
trn, NULL, 6,
TRANSLOG_INTERNAL_PARTS + 1, parts))
{
fprintf(stderr, "Can't write record #%lu\n", (ulong) i);
......@@ -299,9 +305,10 @@ int main(int argc __attribute__((unused)), char *argv[])
rec_len= get_len();
parts[TRANSLOG_INTERNAL_PARTS + 0].str= (char*)long_buffer;
parts[TRANSLOG_INTERNAL_PARTS + 0].length= rec_len;
trn->short_id= i % 0xFFFF;
if (translog_write_record(&lsn,
LOGREC_REDO_INSERT_ROW_HEAD,
(i % 0xFFFF), NULL, NULL, rec_len,
trn, NULL, rec_len,
TRANSLOG_INTERNAL_PARTS + 1, parts))
{
fprintf(stderr, "Can't write variable record #%lu\n", (ulong) i);
......
......@@ -2,6 +2,8 @@
#include <stdio.h>
#include <errno.h>
#include <tap.h>
#include "../trnman.h"
extern my_bool maria_log_remove();
#ifndef DBUG_OFF
......@@ -117,9 +119,11 @@ static my_bool read_and_check_content(TRANSLOG_HEADER_BUFFER *rec,
void writer(int num)
{
LSN lsn;
TRN trn;
byte long_tr_id[6];
uint i;
trn.short_id= num;
for (i= 0; i < ITERATIONS; i++)
{
uint len= get_len();
......@@ -132,7 +136,7 @@ void writer(int num)
parts[TRANSLOG_INTERNAL_PARTS + 0].length= 6;
if (translog_write_record(&lsn,
LOGREC_LONG_TRANSACTION_ID,
num, NULL, NULL, 6, TRANSLOG_INTERNAL_PARTS + 1,
&trn, NULL, 6, TRANSLOG_INTERNAL_PARTS + 1,
parts))
{
fprintf(stderr, "Can't write LOGREC_LONG_TRANSACTION_ID record #%lu "
......@@ -148,7 +152,7 @@ void writer(int num)
parts[TRANSLOG_INTERNAL_PARTS + 0].length= len;
if (translog_write_record(&lsn,
LOGREC_REDO_INSERT_ROW_HEAD,
num, NULL, NULL,
&trn, NULL,
len, TRANSLOG_INTERNAL_PARTS + 1,
parts))
{
......@@ -296,7 +300,8 @@ int main(int argc __attribute__((unused)),
parts[TRANSLOG_INTERNAL_PARTS + 0].length= 6;
if (translog_write_record(&first_lsn,
LOGREC_LONG_TRANSACTION_ID,
0, NULL, NULL, 6, TRANSLOG_INTERNAL_PARTS + 1,
&dummy_transaction_object, NULL, 6,
TRANSLOG_INTERNAL_PARTS + 1,
parts))
{
fprintf(stderr, "Can't write the first record\n");
......
......@@ -2,6 +2,7 @@
#include <stdio.h>
#include <errno.h>
#include <tap.h>
#include "../trnman.h"
extern my_bool maria_log_remove();
......@@ -90,7 +91,8 @@ int main(int argc __attribute__((unused)), char *argv[])
parts[TRANSLOG_INTERNAL_PARTS + 0].length= 6;
if (translog_write_record(&lsn,
LOGREC_LONG_TRANSACTION_ID,
0, NULL, NULL, 6, TRANSLOG_INTERNAL_PARTS + 1,
&dummy_transaction_object, NULL, 6,
TRANSLOG_INTERNAL_PARTS + 1,
parts))
{
fprintf(stderr, "Can't write record #%lu\n", (ulong) 0);
......
#include <m_string.h>
#include <pagecache.h>
#include "../ma_pagecache.h"
/*
File content descriptor
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment