mirror of
https://github.com/MariaDB/server.git
synced 2025-01-22 23:04:20 +01:00
b707b2e3b1
within UNIV_DEBUG. The two remaining callers in non-debug builds, btr_search_guess_on_hash() and btr_search_validate(), were rewritten to call buf_page_hash_get(). To implement support for a resizeable buffer pool, the function buf_block_align() had been rewritten to perform a page hash lookup in the buffer pool. The caller was also made responsible for holding the buffer pool mutex. Because the page hash lookup is expensive and it has to be done while holding the buffer pool mutex, implement buf_block_align() by pointer arithmetics again, and make btr_search_guess_on_hash() call it. Note that this will have to be adjusted if the interface to the resizeable buffer pool is actually implemented. rb://83 approved by Heikki Tuuri, to address Issue #161. As a deviation from the approved patch, this patch also makes btr_search_validate() (invoked by CHECK TABLE) check that buf_pool->page_hash is consistent with buf_block_align().
231 lines
5.3 KiB
Text
231 lines
5.3 KiB
Text
/******************************************************
|
|
Mini-transaction logging routines
|
|
|
|
(c) 1995 Innobase Oy
|
|
|
|
Created 12/7/1995 Heikki Tuuri
|
|
*******************************************************/
|
|
|
|
#include "mach0data.h"
|
|
#include "ut0lst.h"
|
|
#include "buf0buf.h"
|
|
|
|
/************************************************************
|
|
Opens a buffer to mlog. It must be closed with mlog_close. */
|
|
UNIV_INLINE
|
|
byte*
|
|
mlog_open(
|
|
/*======*/
|
|
/* out: buffer, NULL if log mode MTR_LOG_NONE */
|
|
mtr_t* mtr, /* in: mtr */
|
|
ulint size) /* in: buffer size in bytes; MUST be
|
|
smaller than DYN_ARRAY_DATA_SIZE! */
|
|
{
|
|
dyn_array_t* mlog;
|
|
|
|
mtr->modifications = TRUE;
|
|
|
|
if (mtr_get_log_mode(mtr) == MTR_LOG_NONE) {
|
|
|
|
return(NULL);
|
|
}
|
|
|
|
mlog = &(mtr->log);
|
|
|
|
return(dyn_array_open(mlog, size));
|
|
}
|
|
|
|
/************************************************************
|
|
Closes a buffer opened to mlog. */
|
|
UNIV_INLINE
|
|
void
|
|
mlog_close(
|
|
/*=======*/
|
|
mtr_t* mtr, /* in: mtr */
|
|
byte* ptr) /* in: buffer space from ptr up was not used */
|
|
{
|
|
dyn_array_t* mlog;
|
|
|
|
ut_ad(mtr_get_log_mode(mtr) != MTR_LOG_NONE);
|
|
|
|
mlog = &(mtr->log);
|
|
|
|
dyn_array_close(mlog, ptr);
|
|
}
|
|
|
|
/************************************************************
|
|
Catenates 1 - 4 bytes to the mtr log. The value is not compressed. */
|
|
UNIV_INLINE
|
|
void
|
|
mlog_catenate_ulint(
|
|
/*================*/
|
|
mtr_t* mtr, /* in: mtr */
|
|
ulint val, /* in: value to write */
|
|
ulint type) /* in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */
|
|
{
|
|
dyn_array_t* mlog;
|
|
byte* ptr;
|
|
|
|
if (mtr_get_log_mode(mtr) == MTR_LOG_NONE) {
|
|
|
|
return;
|
|
}
|
|
|
|
mlog = &(mtr->log);
|
|
|
|
#if MLOG_1BYTE != 1
|
|
# error "MLOG_1BYTE != 1"
|
|
#endif
|
|
#if MLOG_2BYTES != 2
|
|
# error "MLOG_2BYTES != 2"
|
|
#endif
|
|
#if MLOG_4BYTES != 4
|
|
# error "MLOG_4BYTES != 4"
|
|
#endif
|
|
#if MLOG_8BYTES != 8
|
|
# error "MLOG_8BYTES != 8"
|
|
#endif
|
|
ptr = (byte*) dyn_array_push(mlog, type);
|
|
|
|
if (type == MLOG_4BYTES) {
|
|
mach_write_to_4(ptr, val);
|
|
} else if (type == MLOG_2BYTES) {
|
|
mach_write_to_2(ptr, val);
|
|
} else {
|
|
ut_ad(type == MLOG_1BYTE);
|
|
mach_write_to_1(ptr, val);
|
|
}
|
|
}
|
|
|
|
/************************************************************
|
|
Catenates a compressed ulint to mlog. */
|
|
UNIV_INLINE
|
|
void
|
|
mlog_catenate_ulint_compressed(
|
|
/*===========================*/
|
|
mtr_t* mtr, /* in: mtr */
|
|
ulint val) /* in: value to write */
|
|
{
|
|
byte* log_ptr;
|
|
|
|
log_ptr = mlog_open(mtr, 10);
|
|
|
|
/* If no logging is requested, we may return now */
|
|
if (log_ptr == NULL) {
|
|
|
|
return;
|
|
}
|
|
|
|
log_ptr += mach_write_compressed(log_ptr, val);
|
|
|
|
mlog_close(mtr, log_ptr);
|
|
}
|
|
|
|
/************************************************************
|
|
Catenates a compressed dulint to mlog. */
|
|
UNIV_INLINE
|
|
void
|
|
mlog_catenate_dulint_compressed(
|
|
/*============================*/
|
|
mtr_t* mtr, /* in: mtr */
|
|
dulint val) /* in: value to write */
|
|
{
|
|
byte* log_ptr;
|
|
|
|
log_ptr = mlog_open(mtr, 15);
|
|
|
|
/* If no logging is requested, we may return now */
|
|
if (log_ptr == NULL) {
|
|
|
|
return;
|
|
}
|
|
|
|
log_ptr += mach_dulint_write_compressed(log_ptr, val);
|
|
|
|
mlog_close(mtr, log_ptr);
|
|
}
|
|
|
|
/************************************************************
|
|
Writes the initial part of a log record (3..11 bytes).
|
|
If the implementation of this function is changed, all
|
|
size parameters to mlog_open() should be adjusted accordingly! */
|
|
UNIV_INLINE
|
|
byte*
|
|
mlog_write_initial_log_record_fast(
|
|
/*===============================*/
|
|
/* out: new value of log_ptr */
|
|
const byte* ptr, /* in: pointer to (inside) a buffer
|
|
frame holding the file page where
|
|
modification is made */
|
|
byte type, /* in: log item type: MLOG_1BYTE, ... */
|
|
byte* log_ptr,/* in: pointer to mtr log which has
|
|
been opened */
|
|
mtr_t* mtr) /* in: mtr */
|
|
{
|
|
#ifdef UNIV_DEBUG
|
|
buf_block_t* block;
|
|
#endif
|
|
const byte* page;
|
|
ulint space;
|
|
ulint offset;
|
|
|
|
ut_ad(mtr_memo_contains_page(mtr, ptr, MTR_MEMO_PAGE_X_FIX));
|
|
ut_ad(type <= MLOG_BIGGEST_TYPE);
|
|
ut_ad(ptr && log_ptr);
|
|
|
|
page = (const byte*) ut_align_down(ptr, UNIV_PAGE_SIZE);
|
|
space = mach_read_from_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
|
|
offset = mach_read_from_4(page + FIL_PAGE_OFFSET);
|
|
|
|
mach_write_to_1(log_ptr, type);
|
|
log_ptr++;
|
|
log_ptr += mach_write_compressed(log_ptr, space);
|
|
log_ptr += mach_write_compressed(log_ptr, offset);
|
|
|
|
mtr->n_log_recs++;
|
|
|
|
#ifdef UNIV_LOG_DEBUG
|
|
fprintf(stderr,
|
|
"Adding to mtr log record type %lu space %lu page no %lu\n",
|
|
(ulong) type, space, offset);
|
|
#endif
|
|
|
|
#ifdef UNIV_DEBUG
|
|
/* We now assume that all x-latched pages have been modified! */
|
|
block = (buf_block_t*) buf_block_align(ptr);
|
|
|
|
if (!mtr_memo_contains(mtr, block, MTR_MEMO_MODIFY)) {
|
|
|
|
mtr_memo_push(mtr, block, MTR_MEMO_MODIFY);
|
|
}
|
|
#endif
|
|
return(log_ptr);
|
|
}
|
|
|
|
/************************************************************
|
|
Writes a log record about an .ibd file create/delete/rename. */
|
|
UNIV_INLINE
|
|
byte*
|
|
mlog_write_initial_log_record_for_file_op(
|
|
/*======================================*/
|
|
/* out: new value of log_ptr */
|
|
ulint type, /* in: MLOG_FILE_CREATE, MLOG_FILE_DELETE, or
|
|
MLOG_FILE_RENAME */
|
|
ulint space_id,/* in: space id, if applicable */
|
|
ulint page_no,/* in: page number (not relevant currently) */
|
|
byte* log_ptr,/* in: pointer to mtr log which has been opened */
|
|
mtr_t* mtr) /* in: mtr */
|
|
{
|
|
ut_ad(log_ptr);
|
|
|
|
mach_write_to_1(log_ptr, type);
|
|
log_ptr++;
|
|
|
|
/* We write dummy space id and page number */
|
|
log_ptr += mach_write_compressed(log_ptr, space_id);
|
|
log_ptr += mach_write_compressed(log_ptr, page_no);
|
|
|
|
mtr->n_log_recs++;
|
|
|
|
return(log_ptr);
|
|
}
|