mirror of
https://github.com/MariaDB/server.git
synced 2025-08-31 22:22:30 +03:00
Adding innodb_plugin-1.0.4 as storage/innodb_plugin.
This commit is contained in:
386
storage/innodb_plugin/include/trx0sys.ic
Normal file
386
storage/innodb_plugin/include/trx0sys.ic
Normal file
@@ -0,0 +1,386 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
|
||||
|
||||
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
|
||||
|
||||
*****************************************************************************/
|
||||
|
||||
/**************************************************//**
|
||||
@file include/trx0sys.ic
|
||||
Transaction system
|
||||
|
||||
Created 3/26/1996 Heikki Tuuri
|
||||
*******************************************************/
|
||||
|
||||
#include "trx0trx.h"
|
||||
#include "data0type.h"
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
# include "srv0srv.h"
|
||||
|
||||
/* The typedef for rseg slot in the file copy */
|
||||
typedef byte trx_sysf_rseg_t;
|
||||
|
||||
/* Rollback segment specification slot offsets */
|
||||
/*-------------------------------------------------------------*/
|
||||
#define TRX_SYS_RSEG_SPACE 0 /* space where the the segment
|
||||
header is placed; starting with
|
||||
MySQL/InnoDB 5.1.7, this is
|
||||
UNIV_UNDEFINED if the slot is unused */
|
||||
#define TRX_SYS_RSEG_PAGE_NO 4 /* page number where the the segment
|
||||
header is placed; this is FIL_NULL
|
||||
if the slot is unused */
|
||||
/*-------------------------------------------------------------*/
|
||||
/* Size of a rollback segment specification slot */
|
||||
#define TRX_SYS_RSEG_SLOT_SIZE 8
|
||||
|
||||
/*****************************************************************//**
|
||||
Writes the value of max_trx_id to the file based trx system header. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
trx_sys_flush_max_trx_id(void);
|
||||
/*==========================*/
|
||||
|
||||
/***************************************************************//**
|
||||
Checks if a page address is the trx sys header page.
|
||||
@return TRUE if trx sys header page */
|
||||
UNIV_INLINE
|
||||
ibool
|
||||
trx_sys_hdr_page(
|
||||
/*=============*/
|
||||
ulint space, /*!< in: space */
|
||||
ulint page_no)/*!< in: page number */
|
||||
{
|
||||
if ((space == TRX_SYS_SPACE) && (page_no == TRX_SYS_PAGE_NO)) {
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
/***************************************************************//**
|
||||
Gets the pointer in the nth slot of the rseg array.
|
||||
@return pointer to rseg object, NULL if slot not in use */
|
||||
UNIV_INLINE
|
||||
trx_rseg_t*
|
||||
trx_sys_get_nth_rseg(
|
||||
/*=================*/
|
||||
trx_sys_t* sys, /*!< in: trx system */
|
||||
ulint n) /*!< in: index of slot */
|
||||
{
|
||||
ut_ad(mutex_own(&(kernel_mutex)));
|
||||
ut_ad(n < TRX_SYS_N_RSEGS);
|
||||
|
||||
return(sys->rseg_array[n]);
|
||||
}
|
||||
|
||||
/***************************************************************//**
|
||||
Sets the pointer in the nth slot of the rseg array. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
trx_sys_set_nth_rseg(
|
||||
/*=================*/
|
||||
trx_sys_t* sys, /*!< in: trx system */
|
||||
ulint n, /*!< in: index of slot */
|
||||
trx_rseg_t* rseg) /*!< in: pointer to rseg object, NULL if slot
|
||||
not in use */
|
||||
{
|
||||
ut_ad(n < TRX_SYS_N_RSEGS);
|
||||
|
||||
sys->rseg_array[n] = rseg;
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
Gets a pointer to the transaction system header and x-latches its page.
|
||||
@return pointer to system header, page x-latched. */
|
||||
UNIV_INLINE
|
||||
trx_sysf_t*
|
||||
trx_sysf_get(
|
||||
/*=========*/
|
||||
mtr_t* mtr) /*!< in: mtr */
|
||||
{
|
||||
buf_block_t* block;
|
||||
trx_sysf_t* header;
|
||||
|
||||
ut_ad(mtr);
|
||||
|
||||
block = buf_page_get(TRX_SYS_SPACE, 0, TRX_SYS_PAGE_NO,
|
||||
RW_X_LATCH, mtr);
|
||||
buf_block_dbg_add_level(block, SYNC_TRX_SYS_HEADER);
|
||||
|
||||
header = TRX_SYS + buf_block_get_frame(block);
|
||||
|
||||
return(header);
|
||||
}
|
||||
|
||||
/*****************************************************************//**
|
||||
Gets the space of the nth rollback segment slot in the trx system
|
||||
file copy.
|
||||
@return space id */
|
||||
UNIV_INLINE
|
||||
ulint
|
||||
trx_sysf_rseg_get_space(
|
||||
/*====================*/
|
||||
trx_sysf_t* sys_header, /*!< in: trx sys header */
|
||||
ulint i, /*!< in: slot index == rseg id */
|
||||
mtr_t* mtr) /*!< in: mtr */
|
||||
{
|
||||
ut_ad(mutex_own(&(kernel_mutex)));
|
||||
ut_ad(sys_header);
|
||||
ut_ad(i < TRX_SYS_N_RSEGS);
|
||||
|
||||
return(mtr_read_ulint(sys_header + TRX_SYS_RSEGS
|
||||
+ i * TRX_SYS_RSEG_SLOT_SIZE
|
||||
+ TRX_SYS_RSEG_SPACE, MLOG_4BYTES, mtr));
|
||||
}
|
||||
|
||||
/*****************************************************************//**
|
||||
Gets the page number of the nth rollback segment slot in the trx system
|
||||
header.
|
||||
@return page number, FIL_NULL if slot unused */
|
||||
UNIV_INLINE
|
||||
ulint
|
||||
trx_sysf_rseg_get_page_no(
|
||||
/*======================*/
|
||||
trx_sysf_t* sys_header, /*!< in: trx system header */
|
||||
ulint i, /*!< in: slot index == rseg id */
|
||||
mtr_t* mtr) /*!< in: mtr */
|
||||
{
|
||||
ut_ad(sys_header);
|
||||
ut_ad(mutex_own(&(kernel_mutex)));
|
||||
ut_ad(i < TRX_SYS_N_RSEGS);
|
||||
|
||||
return(mtr_read_ulint(sys_header + TRX_SYS_RSEGS
|
||||
+ i * TRX_SYS_RSEG_SLOT_SIZE
|
||||
+ TRX_SYS_RSEG_PAGE_NO, MLOG_4BYTES, mtr));
|
||||
}
|
||||
|
||||
/*****************************************************************//**
|
||||
Sets the space id of the nth rollback segment slot in the trx system
|
||||
file copy. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
trx_sysf_rseg_set_space(
|
||||
/*====================*/
|
||||
trx_sysf_t* sys_header, /*!< in: trx sys file copy */
|
||||
ulint i, /*!< in: slot index == rseg id */
|
||||
ulint space, /*!< in: space id */
|
||||
mtr_t* mtr) /*!< in: mtr */
|
||||
{
|
||||
ut_ad(mutex_own(&(kernel_mutex)));
|
||||
ut_ad(sys_header);
|
||||
ut_ad(i < TRX_SYS_N_RSEGS);
|
||||
|
||||
mlog_write_ulint(sys_header + TRX_SYS_RSEGS
|
||||
+ i * TRX_SYS_RSEG_SLOT_SIZE
|
||||
+ TRX_SYS_RSEG_SPACE,
|
||||
space,
|
||||
MLOG_4BYTES, mtr);
|
||||
}
|
||||
|
||||
/*****************************************************************//**
|
||||
Sets the page number of the nth rollback segment slot in the trx system
|
||||
header. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
trx_sysf_rseg_set_page_no(
|
||||
/*======================*/
|
||||
trx_sysf_t* sys_header, /*!< in: trx sys header */
|
||||
ulint i, /*!< in: slot index == rseg id */
|
||||
ulint page_no, /*!< in: page number, FIL_NULL if the
|
||||
slot is reset to unused */
|
||||
mtr_t* mtr) /*!< in: mtr */
|
||||
{
|
||||
ut_ad(mutex_own(&(kernel_mutex)));
|
||||
ut_ad(sys_header);
|
||||
ut_ad(i < TRX_SYS_N_RSEGS);
|
||||
|
||||
mlog_write_ulint(sys_header + TRX_SYS_RSEGS
|
||||
+ i * TRX_SYS_RSEG_SLOT_SIZE
|
||||
+ TRX_SYS_RSEG_PAGE_NO,
|
||||
page_no,
|
||||
MLOG_4BYTES, mtr);
|
||||
}
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
|
||||
/*****************************************************************//**
|
||||
Writes a trx id to an index page. In case that the id size changes in
|
||||
some future version, this function should be used instead of
|
||||
mach_write_... */
|
||||
UNIV_INLINE
|
||||
void
|
||||
trx_write_trx_id(
|
||||
/*=============*/
|
||||
byte* ptr, /*!< in: pointer to memory where written */
|
||||
trx_id_t id) /*!< in: id */
|
||||
{
|
||||
#if DATA_TRX_ID_LEN != 6
|
||||
# error "DATA_TRX_ID_LEN != 6"
|
||||
#endif
|
||||
mach_write_to_6(ptr, id);
|
||||
}
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
/*****************************************************************//**
|
||||
Reads a trx id from an index page. In case that the id size changes in
|
||||
some future version, this function should be used instead of
|
||||
mach_read_...
|
||||
@return id */
|
||||
UNIV_INLINE
|
||||
trx_id_t
|
||||
trx_read_trx_id(
|
||||
/*============*/
|
||||
const byte* ptr) /*!< in: pointer to memory from where to read */
|
||||
{
|
||||
#if DATA_TRX_ID_LEN != 6
|
||||
# error "DATA_TRX_ID_LEN != 6"
|
||||
#endif
|
||||
return(mach_read_from_6(ptr));
|
||||
}
|
||||
|
||||
/****************************************************************//**
|
||||
Looks for the trx handle with the given id in trx_list.
|
||||
@return the trx handle or NULL if not found */
|
||||
UNIV_INLINE
|
||||
trx_t*
|
||||
trx_get_on_id(
|
||||
/*==========*/
|
||||
trx_id_t trx_id) /*!< in: trx id to search for */
|
||||
{
|
||||
trx_t* trx;
|
||||
|
||||
ut_ad(mutex_own(&(kernel_mutex)));
|
||||
|
||||
trx = UT_LIST_GET_FIRST(trx_sys->trx_list);
|
||||
|
||||
while (trx != NULL) {
|
||||
if (0 == ut_dulint_cmp(trx_id, trx->id)) {
|
||||
|
||||
return(trx);
|
||||
}
|
||||
|
||||
trx = UT_LIST_GET_NEXT(trx_list, trx);
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/****************************************************************//**
|
||||
Returns the minumum trx id in trx list. This is the smallest id for which
|
||||
the trx can possibly be active. (But, you must look at the trx->conc_state to
|
||||
find out if the minimum trx id transaction itself is active, or already
|
||||
committed.)
|
||||
@return the minimum trx id, or trx_sys->max_trx_id if the trx list is empty */
|
||||
UNIV_INLINE
|
||||
trx_id_t
|
||||
trx_list_get_min_trx_id(void)
|
||||
/*=========================*/
|
||||
{
|
||||
trx_t* trx;
|
||||
|
||||
ut_ad(mutex_own(&(kernel_mutex)));
|
||||
|
||||
trx = UT_LIST_GET_LAST(trx_sys->trx_list);
|
||||
|
||||
if (trx == NULL) {
|
||||
|
||||
return(trx_sys->max_trx_id);
|
||||
}
|
||||
|
||||
return(trx->id);
|
||||
}
|
||||
|
||||
/****************************************************************//**
|
||||
Checks if a transaction with the given id is active.
|
||||
@return TRUE if active */
|
||||
UNIV_INLINE
|
||||
ibool
|
||||
trx_is_active(
|
||||
/*==========*/
|
||||
trx_id_t trx_id) /*!< in: trx id of the transaction */
|
||||
{
|
||||
trx_t* trx;
|
||||
|
||||
ut_ad(mutex_own(&(kernel_mutex)));
|
||||
|
||||
if (ut_dulint_cmp(trx_id, trx_list_get_min_trx_id()) < 0) {
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
if (ut_dulint_cmp(trx_id, trx_sys->max_trx_id) >= 0) {
|
||||
|
||||
/* There must be corruption: we return TRUE because this
|
||||
function is only called by lock_clust_rec_some_has_impl()
|
||||
and row_vers_impl_x_locked_off_kernel() and they have
|
||||
diagnostic prints in this case */
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
trx = trx_get_on_id(trx_id);
|
||||
if (trx && (trx->conc_state == TRX_ACTIVE
|
||||
|| trx->conc_state == TRX_PREPARED)) {
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
/*****************************************************************//**
|
||||
Allocates a new transaction id.
|
||||
@return new, allocated trx id */
|
||||
UNIV_INLINE
|
||||
trx_id_t
|
||||
trx_sys_get_new_trx_id(void)
|
||||
/*========================*/
|
||||
{
|
||||
trx_id_t id;
|
||||
|
||||
ut_ad(mutex_own(&kernel_mutex));
|
||||
|
||||
/* VERY important: after the database is started, max_trx_id value is
|
||||
divisible by TRX_SYS_TRX_ID_WRITE_MARGIN, and the following if
|
||||
will evaluate to TRUE when this function is first time called,
|
||||
and the value for trx id will be written to disk-based header!
|
||||
Thus trx id values will not overlap when the database is
|
||||
repeatedly started! */
|
||||
|
||||
if (ut_dulint_get_low(trx_sys->max_trx_id)
|
||||
% TRX_SYS_TRX_ID_WRITE_MARGIN == 0) {
|
||||
|
||||
trx_sys_flush_max_trx_id();
|
||||
}
|
||||
|
||||
id = trx_sys->max_trx_id;
|
||||
|
||||
UT_DULINT_INC(trx_sys->max_trx_id);
|
||||
|
||||
return(id);
|
||||
}
|
||||
|
||||
/*****************************************************************//**
|
||||
Allocates a new transaction number.
|
||||
@return new, allocated trx number */
|
||||
UNIV_INLINE
|
||||
trx_id_t
|
||||
trx_sys_get_new_trx_no(void)
|
||||
/*========================*/
|
||||
{
|
||||
ut_ad(mutex_own(&kernel_mutex));
|
||||
|
||||
return(trx_sys_get_new_trx_id());
|
||||
}
|
||||
#endif /* !UNIV_HOTBACKUP */
|
Reference in New Issue
Block a user