mariadb/storage/xtradb/include/mtr0mtr.ic

297 lines
7 KiB
Text
Raw Normal View History

2009-03-26 07:11:11 +01:00
/*****************************************************************************
Copyright (c) 1995, 2012, Oracle and/or its affiliates. All Rights Reserved.
2009-03-26 07:11:11 +01:00
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.,
51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
2009-03-26 07:11:11 +01:00
*****************************************************************************/
2009-09-07 12:22:53 +02:00
/**************************************************//**
@file include/mtr0mtr.ic
Mini-transaction buffer
Created 11/26/1995 Heikki Tuuri
*******************************************************/
2009-09-07 12:22:53 +02:00
#ifndef UNIV_HOTBACKUP
# include "sync0sync.h"
# include "sync0rw.h"
#endif /* !UNIV_HOTBACKUP */
#include "mach0data.h"
2013-05-08 09:52:54 +02:00
/***************************************************//**
Checks if a mini-transaction is dirtying a clean page.
@return TRUE if the mtr is dirtying a clean page. */
UNIV_INTERN
ibool
mtr_block_dirtied(
/*==============*/
const buf_block_t* block) /*!< in: block being x-fixed */
__attribute__((nonnull,warn_unused_result));
2009-09-07 12:22:53 +02:00
/***************************************************************//**
2011-07-14 21:22:41 +02:00
Starts a mini-transaction. */
UNIV_INLINE
2011-07-14 21:22:41 +02:00
void
mtr_start(
/*======*/
2011-07-14 21:22:41 +02:00
mtr_t* mtr) /*!< out: mini-transaction */
{
UNIV_MEM_INVALID(mtr, sizeof *mtr);
dyn_array_create(&(mtr->memo));
dyn_array_create(&(mtr->log));
mtr->log_mode = MTR_LOG_ALL;
mtr->modifications = FALSE;
2011-07-14 21:22:41 +02:00
mtr->inside_ibuf = FALSE;
mtr->n_log_recs = 0;
mtr->n_freed_pages = 0;
2013-05-08 09:52:54 +02:00
mtr->made_dirty = FALSE;
2009-03-26 07:11:11 +01:00
ut_d(mtr->state = MTR_ACTIVE);
ut_d(mtr->magic_n = MTR_MAGIC_N);
}
2009-09-07 12:22:53 +02:00
/***************************************************//**
Pushes an object to an mtr memo stack. */
UNIV_INLINE
void
mtr_memo_push(
/*==========*/
2009-09-07 12:22:53 +02:00
mtr_t* mtr, /*!< in: mtr */
void* object, /*!< in: object */
ulint type) /*!< in: object type: MTR_MEMO_S_LOCK, ... */
{
dyn_array_t* memo;
mtr_memo_slot_t* slot;
2013-05-08 09:52:54 +02:00
/* If this mtr has x-fixed a clean page then we set
the made_dirty flag. This tells us if we need to
grab log_flush_order_mutex at mtr_commit so that we
can insert the dirtied page to the flush list. */
if (type == MTR_MEMO_PAGE_X_FIX && !mtr->made_dirty) {
mtr->made_dirty =
mtr_block_dirtied((const buf_block_t *)object);
}
ut_ad(object);
ut_ad(type >= MTR_MEMO_PAGE_S_FIX);
ut_ad(type <= MTR_MEMO_X_LOCK);
ut_ad(mtr);
ut_ad(mtr->magic_n == MTR_MAGIC_N);
ut_ad(mtr->state == MTR_ACTIVE);
memo = &(mtr->memo);
slot = (mtr_memo_slot_t*) dyn_array_push(memo, sizeof *slot);
slot->object = object;
slot->type = type;
}
2009-09-07 12:22:53 +02:00
/**********************************************************//**
Sets and returns a savepoint in mtr.
@return savepoint */
UNIV_INLINE
ulint
mtr_set_savepoint(
/*==============*/
2009-09-07 12:22:53 +02:00
mtr_t* mtr) /*!< in: mtr */
{
dyn_array_t* memo;
ut_ad(mtr);
ut_ad(mtr->magic_n == MTR_MAGIC_N);
ut_ad(mtr->state == MTR_ACTIVE);
memo = &(mtr->memo);
return(dyn_array_get_data_size(memo));
}
2009-09-07 12:22:53 +02:00
#ifndef UNIV_HOTBACKUP
/**********************************************************//**
Releases the (index tree) s-latch stored in an mtr memo after a
savepoint. */
UNIV_INLINE
void
mtr_release_s_latch_at_savepoint(
/*=============================*/
2009-09-07 12:22:53 +02:00
mtr_t* mtr, /*!< in: mtr */
ulint savepoint, /*!< in: savepoint */
rw_lock_t* lock) /*!< in: latch to release */
{
mtr_memo_slot_t* slot;
dyn_array_t* memo;
ut_ad(mtr);
ut_ad(mtr->magic_n == MTR_MAGIC_N);
ut_ad(mtr->state == MTR_ACTIVE);
memo = &(mtr->memo);
ut_ad(dyn_array_get_data_size(memo) > savepoint);
slot = (mtr_memo_slot_t*) dyn_array_get_element(memo, savepoint);
ut_ad(slot->object == lock);
ut_ad(slot->type == MTR_MEMO_S_LOCK);
rw_lock_s_unlock(lock);
slot->object = NULL;
}
2009-09-07 12:22:53 +02:00
# ifdef UNIV_DEBUG
/**********************************************************//**
Checks if memo contains the given item.
@return TRUE if contains */
UNIV_INLINE
ibool
mtr_memo_contains(
/*==============*/
2009-09-07 12:22:53 +02:00
mtr_t* mtr, /*!< in: mtr */
const void* object, /*!< in: object to search */
ulint type) /*!< in: type of object */
{
mtr_memo_slot_t* slot;
dyn_array_t* memo;
ulint offset;
ut_ad(mtr);
ut_ad(mtr->magic_n == MTR_MAGIC_N);
ut_ad(mtr->state == MTR_ACTIVE || mtr->state == MTR_COMMITTING);
memo = &(mtr->memo);
offset = dyn_array_get_data_size(memo);
while (offset > 0) {
offset -= sizeof(mtr_memo_slot_t);
2011-07-14 21:22:41 +02:00
slot = (mtr_memo_slot_t*) dyn_array_get_element(memo, offset);
if ((object == slot->object) && (type == slot->type)) {
return(TRUE);
}
}
return(FALSE);
}
2009-09-07 12:22:53 +02:00
# endif /* UNIV_DEBUG */
#endif /* !UNIV_HOTBACKUP */
2009-09-07 12:22:53 +02:00
/***************************************************************//**
Returns the log object of a mini-transaction buffer.
@return log */
UNIV_INLINE
dyn_array_t*
mtr_get_log(
/*========*/
2009-09-07 12:22:53 +02:00
mtr_t* mtr) /*!< in: mini-transaction */
{
ut_ad(mtr);
ut_ad(mtr->magic_n == MTR_MAGIC_N);
return(&(mtr->log));
}
2009-09-07 12:22:53 +02:00
/***************************************************************//**
Gets the logging mode of a mini-transaction.
@return logging mode: MTR_LOG_NONE, ... */
UNIV_INLINE
ulint
mtr_get_log_mode(
/*=============*/
2009-09-07 12:22:53 +02:00
mtr_t* mtr) /*!< in: mtr */
{
ut_ad(mtr);
ut_ad(mtr->log_mode >= MTR_LOG_ALL);
ut_ad(mtr->log_mode <= MTR_LOG_SHORT_INSERTS);
return(mtr->log_mode);
}
2009-09-07 12:22:53 +02:00
/***************************************************************//**
Changes the logging mode of a mini-transaction.
@return old mode */
UNIV_INLINE
ulint
mtr_set_log_mode(
/*=============*/
2009-09-07 12:22:53 +02:00
mtr_t* mtr, /*!< in: mtr */
ulint mode) /*!< in: logging mode: MTR_LOG_NONE, ... */
{
ulint old_mode;
ut_ad(mtr);
ut_ad(mode >= MTR_LOG_ALL);
ut_ad(mode <= MTR_LOG_SHORT_INSERTS);
old_mode = mtr->log_mode;
if ((mode == MTR_LOG_SHORT_INSERTS) && (old_mode == MTR_LOG_NONE)) {
/* Do nothing */
} else {
mtr->log_mode = mode;
}
ut_ad(old_mode >= MTR_LOG_ALL);
ut_ad(old_mode <= MTR_LOG_SHORT_INSERTS);
return(old_mode);
}
2009-09-07 12:22:53 +02:00
#ifndef UNIV_HOTBACKUP
/*********************************************************************//**
Locks a lock in s-mode. */
UNIV_INLINE
void
mtr_s_lock_func(
/*============*/
2009-09-07 12:22:53 +02:00
rw_lock_t* lock, /*!< in: rw-lock */
const char* file, /*!< in: file name */
ulint line, /*!< in: line number */
mtr_t* mtr) /*!< in: mtr */
{
ut_ad(mtr);
ut_ad(lock);
rw_lock_s_lock_inline(lock, 0, file, line);
mtr_memo_push(mtr, lock, MTR_MEMO_S_LOCK);
}
2009-09-07 12:22:53 +02:00
/*********************************************************************//**
Locks a lock in x-mode. */
UNIV_INLINE
void
mtr_x_lock_func(
/*============*/
2009-09-07 12:22:53 +02:00
rw_lock_t* lock, /*!< in: rw-lock */
const char* file, /*!< in: file name */
ulint line, /*!< in: line number */
mtr_t* mtr) /*!< in: mtr */
{
ut_ad(mtr);
ut_ad(lock);
rw_lock_x_lock_inline(lock, 0, file, line);
mtr_memo_push(mtr, lock, MTR_MEMO_X_LOCK);
}
2009-09-07 12:22:53 +02:00
#endif /* !UNIV_HOTBACKUP */