2009-03-26 07:11:11 +01:00
|
|
|
/*****************************************************************************
|
|
|
|
|
2012-06-15 10:23:33 +02: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
|
2012-06-15 10:23:33 +02:00
|
|
|
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
|
2008-12-01 07:10:29 +01:00
|
|
|
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 */
|
2008-12-01 07:10:29 +01:00
|
|
|
#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. */
|
2008-12-01 07:10:29 +01:00
|
|
|
UNIV_INLINE
|
2011-07-14 21:22:41 +02:00
|
|
|
void
|
2008-12-01 07:10:29 +01:00
|
|
|
mtr_start(
|
|
|
|
/*======*/
|
2011-07-14 21:22:41 +02:00
|
|
|
mtr_t* mtr) /*!< out: mini-transaction */
|
2008-12-01 07:10:29 +01:00
|
|
|
{
|
2011-07-17 11:28:48 +02:00
|
|
|
UNIV_MEM_INVALID(mtr, sizeof *mtr);
|
|
|
|
|
2008-12-01 07:10:29 +01:00
|
|
|
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;
|
2008-12-01 07:10:29 +01:00
|
|
|
mtr->n_log_recs = 0;
|
2012-06-15 10:23:33 +02:00
|
|
|
mtr->n_freed_pages = 0;
|
2013-05-08 09:52:54 +02:00
|
|
|
mtr->made_dirty = FALSE;
|
2008-12-01 07:10:29 +01:00
|
|
|
|
2009-03-26 07:11:11 +01:00
|
|
|
ut_d(mtr->state = MTR_ACTIVE);
|
|
|
|
ut_d(mtr->magic_n = MTR_MAGIC_N);
|
2008-12-01 07:10:29 +01:00
|
|
|
}
|
|
|
|
|
2009-09-07 12:22:53 +02:00
|
|
|
/***************************************************//**
|
2008-12-01 07:10:29 +01: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, ... */
|
2008-12-01 07:10:29 +01:00
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2008-12-01 07:10:29 +01:00
|
|
|
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);
|
2010-08-03 12:54:05 +02:00
|
|
|
ut_ad(mtr->state == MTR_ACTIVE);
|
2008-12-01 07:10:29 +01:00
|
|
|
|
|
|
|
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 */
|
2008-12-01 07:10:29 +01:00
|
|
|
UNIV_INLINE
|
|
|
|
ulint
|
|
|
|
mtr_set_savepoint(
|
|
|
|
/*==============*/
|
2009-09-07 12:22:53 +02:00
|
|
|
mtr_t* mtr) /*!< in: mtr */
|
2008-12-01 07:10:29 +01:00
|
|
|
{
|
|
|
|
dyn_array_t* memo;
|
|
|
|
|
|
|
|
ut_ad(mtr);
|
|
|
|
ut_ad(mtr->magic_n == MTR_MAGIC_N);
|
2010-08-03 12:54:05 +02:00
|
|
|
ut_ad(mtr->state == MTR_ACTIVE);
|
2008-12-01 07:10:29 +01:00
|
|
|
|
|
|
|
memo = &(mtr->memo);
|
|
|
|
|
|
|
|
return(dyn_array_get_data_size(memo));
|
|
|
|
}
|
|
|
|
|
2009-09-07 12:22:53 +02:00
|
|
|
#ifndef UNIV_HOTBACKUP
|
|
|
|
/**********************************************************//**
|
2008-12-01 07:10:29 +01:00
|
|
|
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 */
|
2008-12-01 07:10:29 +01:00
|
|
|
{
|
|
|
|
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 */
|
2008-12-01 07:10:29 +01:00
|
|
|
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 */
|
2008-12-01 07:10:29 +01:00
|
|
|
{
|
|
|
|
mtr_memo_slot_t* slot;
|
|
|
|
dyn_array_t* memo;
|
|
|
|
ulint offset;
|
|
|
|
|
|
|
|
ut_ad(mtr);
|
|
|
|
ut_ad(mtr->magic_n == MTR_MAGIC_N);
|
2010-08-03 12:54:05 +02:00
|
|
|
ut_ad(mtr->state == MTR_ACTIVE || mtr->state == MTR_COMMITTING);
|
2008-12-01 07:10:29 +01:00
|
|
|
|
|
|
|
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);
|
2008-12-01 07:10:29 +01:00
|
|
|
|
|
|
|
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 */
|
2008-12-01 07:10:29 +01:00
|
|
|
|
2009-09-07 12:22:53 +02:00
|
|
|
/***************************************************************//**
|
|
|
|
Returns the log object of a mini-transaction buffer.
|
|
|
|
@return log */
|
2008-12-01 07:10:29 +01:00
|
|
|
UNIV_INLINE
|
|
|
|
dyn_array_t*
|
|
|
|
mtr_get_log(
|
|
|
|
/*========*/
|
2009-09-07 12:22:53 +02:00
|
|
|
mtr_t* mtr) /*!< in: mini-transaction */
|
2008-12-01 07:10:29 +01:00
|
|
|
{
|
|
|
|
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, ... */
|
2008-12-01 07:10:29 +01:00
|
|
|
UNIV_INLINE
|
|
|
|
ulint
|
|
|
|
mtr_get_log_mode(
|
|
|
|
/*=============*/
|
2009-09-07 12:22:53 +02:00
|
|
|
mtr_t* mtr) /*!< in: mtr */
|
2008-12-01 07:10:29 +01:00
|
|
|
{
|
|
|
|
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 */
|
2008-12-01 07:10:29 +01:00
|
|
|
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, ... */
|
2008-12-01 07:10:29 +01:00
|
|
|
{
|
|
|
|
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
|
|
|
|
/*********************************************************************//**
|
2008-12-01 07:10:29 +01:00
|
|
|
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 */
|
2008-12-01 07:10:29 +01:00
|
|
|
{
|
|
|
|
ut_ad(mtr);
|
|
|
|
ut_ad(lock);
|
|
|
|
|
2012-06-15 10:23:33 +02:00
|
|
|
rw_lock_s_lock_inline(lock, 0, file, line);
|
2008-12-01 07:10:29 +01:00
|
|
|
|
|
|
|
mtr_memo_push(mtr, lock, MTR_MEMO_S_LOCK);
|
|
|
|
}
|
|
|
|
|
2009-09-07 12:22:53 +02:00
|
|
|
/*********************************************************************//**
|
2008-12-01 07:10:29 +01: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 */
|
2008-12-01 07:10:29 +01:00
|
|
|
{
|
|
|
|
ut_ad(mtr);
|
|
|
|
ut_ad(lock);
|
|
|
|
|
2012-06-15 10:23:33 +02:00
|
|
|
rw_lock_x_lock_inline(lock, 0, file, line);
|
2008-12-01 07:10:29 +01:00
|
|
|
|
|
|
|
mtr_memo_push(mtr, lock, MTR_MEMO_X_LOCK);
|
|
|
|
}
|
2009-09-07 12:22:53 +02:00
|
|
|
#endif /* !UNIV_HOTBACKUP */
|