2009-05-27 11:45:59 +02:00
|
|
|
/*****************************************************************************
|
|
|
|
|
2016-08-12 10:17:45 +02:00
|
|
|
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
|
2009-05-27 11:45:59 +02: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-08-01 16:27:34 +02:00
|
|
|
this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
|
2009-05-27 11:45:59 +02:00
|
|
|
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
/**************************************************//**
|
|
|
|
@file include/trx0sys.ic
|
|
|
|
Transaction system
|
|
|
|
|
|
|
|
Created 3/26/1996 Heikki Tuuri
|
|
|
|
*******************************************************/
|
|
|
|
|
|
|
|
#include "trx0trx.h"
|
|
|
|
#include "data0type.h"
|
2016-12-30 14:04:10 +01:00
|
|
|
#include "srv0srv.h"
|
|
|
|
#include "mtr0log.h"
|
2009-05-27 11:45:59 +02:00
|
|
|
|
|
|
|
/* The typedef for rseg slot in the file copy */
|
|
|
|
typedef byte trx_sysf_rseg_t;
|
|
|
|
|
|
|
|
/* Rollback segment specification slot offsets */
|
|
|
|
/*-------------------------------------------------------------*/
|
2009-10-16 13:58:02 +02:00
|
|
|
#define TRX_SYS_RSEG_SPACE 0 /* space where the segment
|
2009-05-27 11:45:59 +02:00
|
|
|
header is placed; starting with
|
|
|
|
MySQL/InnoDB 5.1.7, this is
|
|
|
|
UNIV_UNDEFINED if the slot is unused */
|
2009-10-16 13:58:02 +02:00
|
|
|
#define TRX_SYS_RSEG_PAGE_NO 4 /* page number where the segment
|
2009-05-27 11:45:59 +02:00
|
|
|
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. */
|
|
|
|
void
|
|
|
|
trx_sys_flush_max_trx_id(void);
|
|
|
|
/*==========================*/
|
|
|
|
|
2016-08-12 10:17:45 +02:00
|
|
|
/** Checks if a page address is the trx sys header page.
|
|
|
|
@param[in] page_id page id
|
|
|
|
@return true if trx sys header page */
|
2009-05-27 11:45:59 +02:00
|
|
|
UNIV_INLINE
|
2016-08-12 10:17:45 +02:00
|
|
|
bool
|
2009-05-27 11:45:59 +02:00
|
|
|
trx_sys_hdr_page(
|
2016-08-12 10:17:45 +02:00
|
|
|
const page_id_t& page_id)
|
2009-05-27 11:45:59 +02:00
|
|
|
{
|
2016-08-12 10:17:45 +02:00
|
|
|
return(page_id.space() == TRX_SYS_SPACE
|
|
|
|
&& page_id.page_no() == TRX_SYS_PAGE_NO);
|
2009-05-27 11:45:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**********************************************************************//**
|
|
|
|
Gets a pointer to the transaction system header and x-latches its page.
|
2016-08-12 10:17:45 +02:00
|
|
|
@return pointer to system header, page x-latched. */
|
2009-05-27 11:45:59 +02:00
|
|
|
UNIV_INLINE
|
|
|
|
trx_sysf_t*
|
|
|
|
trx_sysf_get(
|
|
|
|
/*=========*/
|
|
|
|
mtr_t* mtr) /*!< in: mtr */
|
|
|
|
{
|
2016-08-12 10:17:45 +02:00
|
|
|
buf_block_t* block = NULL;
|
|
|
|
trx_sysf_t* header = NULL;
|
2009-05-27 11:45:59 +02:00
|
|
|
|
|
|
|
ut_ad(mtr);
|
|
|
|
|
2016-08-12 10:17:45 +02:00
|
|
|
block = buf_page_get(page_id_t(TRX_SYS_SPACE, TRX_SYS_PAGE_NO),
|
|
|
|
univ_page_size, RW_X_LATCH, mtr);
|
|
|
|
|
2016-09-06 08:43:16 +02:00
|
|
|
if (block) {
|
|
|
|
buf_block_dbg_add_level(block, SYNC_TRX_SYS_HEADER);
|
2009-05-27 11:45:59 +02:00
|
|
|
|
2016-09-06 08:43:16 +02:00
|
|
|
header = TRX_SYS + buf_block_get_frame(block);
|
|
|
|
}
|
2009-05-27 11:45:59 +02:00
|
|
|
|
|
|
|
return(header);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************//**
|
|
|
|
Gets the space of the nth rollback segment slot in the trx system
|
|
|
|
file copy.
|
2016-08-12 10:17:45 +02:00
|
|
|
@return space id */
|
2009-05-27 11:45:59 +02:00
|
|
|
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(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.
|
2016-08-12 10:17:45 +02:00
|
|
|
@return page number, FIL_NULL if slot unused */
|
2009-05-27 11:45:59 +02:00
|
|
|
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(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(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(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);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************//**
|
|
|
|
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
|
2016-08-12 10:17:45 +02:00
|
|
|
ut_ad(id > 0);
|
2009-05-27 11:45:59 +02:00
|
|
|
mach_write_to_6(ptr, id);
|
|
|
|
}
|
|
|
|
|
2016-08-12 10:17:45 +02:00
|
|
|
/*****************************************************************//**
|
|
|
|
Check if slot-id is reserved slot-id for noredo rsegs. */
|
|
|
|
UNIV_INLINE
|
|
|
|
bool
|
|
|
|
trx_sys_is_noredo_rseg_slot(
|
|
|
|
/*========================*/
|
|
|
|
ulint slot_id) /*!< in: slot_id to check */
|
|
|
|
{
|
|
|
|
/* Slots allocated from temp-tablespace are no-redo slots. */
|
|
|
|
return(slot_id > 0 && slot_id < (srv_tmp_undo_logs + 1));
|
|
|
|
}
|
|
|
|
|
2009-05-27 11:45:59 +02:00
|
|
|
/*****************************************************************//**
|
|
|
|
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_...
|
2016-08-12 10:17:45 +02:00
|
|
|
@return id */
|
2009-05-27 11:45:59 +02:00
|
|
|
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));
|
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************//**
|
2012-08-01 16:27:34 +02:00
|
|
|
Looks for the trx handle with the given id in rw_trx_list.
|
|
|
|
The caller must be holding trx_sys->mutex.
|
2016-08-12 10:17:45 +02:00
|
|
|
@return the trx handle or NULL if not found;
|
2012-08-01 16:27:34 +02:00
|
|
|
the pointer must not be dereferenced unless lock_sys->mutex was
|
|
|
|
acquired before calling this function and is still being held */
|
2009-05-27 11:45:59 +02:00
|
|
|
UNIV_INLINE
|
|
|
|
trx_t*
|
2012-08-01 16:27:34 +02:00
|
|
|
trx_get_rw_trx_by_id(
|
|
|
|
/*=================*/
|
2009-05-27 11:45:59 +02:00
|
|
|
trx_id_t trx_id) /*!< in: trx id to search for */
|
|
|
|
{
|
2016-08-12 10:17:45 +02:00
|
|
|
ut_ad(trx_id > 0);
|
|
|
|
ut_ad(trx_sys_mutex_own());
|
2009-05-27 11:45:59 +02:00
|
|
|
|
2016-08-12 10:17:45 +02:00
|
|
|
if (trx_sys->rw_trx_set.empty()) {
|
2012-08-01 16:27:34 +02:00
|
|
|
return(NULL);
|
|
|
|
}
|
|
|
|
|
2016-08-12 10:17:45 +02:00
|
|
|
TrxIdSet::iterator it;
|
2009-05-27 11:45:59 +02:00
|
|
|
|
2016-08-12 10:17:45 +02:00
|
|
|
it = trx_sys->rw_trx_set.find(TrxTrack(trx_id));
|
2012-08-01 16:27:34 +02:00
|
|
|
|
2016-08-12 10:17:45 +02:00
|
|
|
return(it == trx_sys->rw_trx_set.end() ? NULL : it->m_trx);
|
2012-08-01 16:27:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************//**
|
|
|
|
Returns the minimum 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->state
|
|
|
|
to find out if the minimum trx id transaction itself is active, or already
|
|
|
|
committed.). The caller must be holding the trx_sys_t::mutex in shared mode.
|
2016-08-12 10:17:45 +02:00
|
|
|
@return the minimum trx id, or trx_sys->max_trx_id if the trx list is empty */
|
2012-08-01 16:27:34 +02:00
|
|
|
UNIV_INLINE
|
|
|
|
trx_id_t
|
|
|
|
trx_rw_min_trx_id_low(void)
|
|
|
|
/*=======================*/
|
|
|
|
{
|
|
|
|
trx_id_t id;
|
|
|
|
|
2016-08-12 10:17:45 +02:00
|
|
|
ut_ad(trx_sys_mutex_own());
|
2012-08-01 16:27:34 +02:00
|
|
|
|
2016-08-12 10:17:45 +02:00
|
|
|
const trx_t* trx = UT_LIST_GET_LAST(trx_sys->rw_trx_list);
|
2012-08-01 16:27:34 +02:00
|
|
|
|
|
|
|
if (trx == NULL) {
|
|
|
|
id = trx_sys->max_trx_id;
|
|
|
|
} else {
|
|
|
|
assert_trx_in_rw_list(trx);
|
|
|
|
id = trx->id;
|
2009-05-27 11:45:59 +02:00
|
|
|
}
|
|
|
|
|
2012-08-01 16:27:34 +02:00
|
|
|
return(id);
|
2009-05-27 11:45:59 +02:00
|
|
|
}
|
|
|
|
|
2011-06-29 08:57:15 +02:00
|
|
|
#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
|
2011-06-29 09:04:00 +02:00
|
|
|
/***********************************************************//**
|
|
|
|
Assert that a transaction has been recovered.
|
|
|
|
@return TRUE */
|
2011-06-29 08:57:15 +02:00
|
|
|
UNIV_INLINE
|
|
|
|
ibool
|
2011-06-29 09:04:00 +02:00
|
|
|
trx_assert_recovered(
|
|
|
|
/*=================*/
|
|
|
|
trx_id_t trx_id) /*!< in: transaction identifier */
|
2011-06-29 08:57:15 +02:00
|
|
|
{
|
2012-08-01 16:27:34 +02:00
|
|
|
const trx_t* trx;
|
2011-06-29 08:57:15 +02:00
|
|
|
|
2016-08-12 10:17:45 +02:00
|
|
|
trx_sys_mutex_enter();
|
2012-08-01 16:27:34 +02:00
|
|
|
|
|
|
|
trx = trx_get_rw_trx_by_id(trx_id);
|
2011-06-29 09:04:00 +02:00
|
|
|
ut_a(trx->is_recovered);
|
2012-08-01 16:27:34 +02:00
|
|
|
|
2016-08-12 10:17:45 +02:00
|
|
|
trx_sys_mutex_exit();
|
2011-06-29 08:57:15 +02:00
|
|
|
|
|
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
|
|
|
|
|
2009-05-27 11:45:59 +02:00
|
|
|
/****************************************************************//**
|
2012-08-01 16:27:34 +02:00
|
|
|
Returns the minimum trx id in rw trx list. This is the smallest id for which
|
|
|
|
the rw trx can possibly be active. (But, you must look at the trx->state
|
|
|
|
to find out if the minimum trx id transaction itself is active, or already
|
2009-05-27 11:45:59 +02:00
|
|
|
committed.)
|
2016-08-12 10:17:45 +02:00
|
|
|
@return the minimum trx id, or trx_sys->max_trx_id if rw trx list is empty */
|
2009-05-27 11:45:59 +02:00
|
|
|
UNIV_INLINE
|
|
|
|
trx_id_t
|
2012-08-01 16:27:34 +02:00
|
|
|
trx_rw_min_trx_id(void)
|
|
|
|
/*===================*/
|
2009-05-27 11:45:59 +02:00
|
|
|
{
|
2016-08-12 10:17:45 +02:00
|
|
|
trx_sys_mutex_enter();
|
2009-05-27 11:45:59 +02:00
|
|
|
|
2016-08-12 10:17:45 +02:00
|
|
|
trx_id_t id = trx_rw_min_trx_id_low();
|
2009-05-27 11:45:59 +02:00
|
|
|
|
2016-08-12 10:17:45 +02:00
|
|
|
trx_sys_mutex_exit();
|
2009-05-27 11:45:59 +02:00
|
|
|
|
2012-08-01 16:27:34 +02:00
|
|
|
return(id);
|
2009-05-27 11:45:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************//**
|
2016-08-12 10:17:45 +02:00
|
|
|
Checks if a rw transaction with the given id is active. If the caller is
|
|
|
|
not holding lock_sys->mutex, the transaction may already have been committed.
|
|
|
|
@return transaction instance if active, or NULL */
|
2009-05-27 11:45:59 +02:00
|
|
|
UNIV_INLINE
|
2012-08-01 16:27:34 +02:00
|
|
|
trx_t*
|
|
|
|
trx_rw_is_active_low(
|
|
|
|
/*=================*/
|
|
|
|
trx_id_t trx_id, /*!< in: trx id of the transaction */
|
|
|
|
ibool* corrupt) /*!< in: NULL or pointer to a flag
|
|
|
|
that will be set if corrupt */
|
2009-05-27 11:45:59 +02:00
|
|
|
{
|
2012-08-01 16:27:34 +02:00
|
|
|
trx_t* trx;
|
2009-05-27 11:45:59 +02:00
|
|
|
|
2016-08-12 10:17:45 +02:00
|
|
|
ut_ad(trx_sys_mutex_own());
|
2009-05-27 11:45:59 +02:00
|
|
|
|
2012-08-01 16:27:34 +02:00
|
|
|
if (trx_id < trx_rw_min_trx_id_low()) {
|
2009-05-27 11:45:59 +02:00
|
|
|
|
2012-08-01 16:27:34 +02:00
|
|
|
trx = NULL;
|
|
|
|
} else if (trx_id >= trx_sys->max_trx_id) {
|
2009-05-27 11:45:59 +02:00
|
|
|
|
2012-08-01 16:27:34 +02:00
|
|
|
/* There must be corruption: we let the caller handle the
|
|
|
|
diagnostic prints in this case. */
|
2009-05-27 11:45:59 +02:00
|
|
|
|
2012-08-01 16:27:34 +02:00
|
|
|
trx = NULL;
|
|
|
|
if (corrupt != NULL) {
|
|
|
|
*corrupt = TRUE;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
trx = trx_get_rw_trx_by_id(trx_id);
|
2009-05-27 11:45:59 +02:00
|
|
|
|
2012-08-01 16:27:34 +02:00
|
|
|
if (trx != NULL
|
|
|
|
&& trx_state_eq(trx, TRX_STATE_COMMITTED_IN_MEMORY)) {
|
|
|
|
|
|
|
|
trx = NULL;
|
|
|
|
}
|
2009-05-27 11:45:59 +02:00
|
|
|
}
|
|
|
|
|
2012-08-01 16:27:34 +02:00
|
|
|
return(trx);
|
|
|
|
}
|
2009-05-27 11:45:59 +02:00
|
|
|
|
2012-08-01 16:27:34 +02:00
|
|
|
/****************************************************************//**
|
|
|
|
Checks if a rw transaction with the given id is active. If the caller is
|
|
|
|
not holding lock_sys->mutex, the transaction may already have been
|
|
|
|
committed.
|
2016-08-12 10:17:45 +02:00
|
|
|
@return transaction instance if active, or NULL; */
|
2012-08-01 16:27:34 +02:00
|
|
|
UNIV_INLINE
|
|
|
|
trx_t*
|
|
|
|
trx_rw_is_active(
|
|
|
|
/*=============*/
|
|
|
|
trx_id_t trx_id, /*!< in: trx id of the transaction */
|
2016-08-12 10:17:45 +02:00
|
|
|
ibool* corrupt, /*!< in: NULL or pointer to a flag
|
2012-08-01 16:27:34 +02:00
|
|
|
that will be set if corrupt */
|
2016-08-12 10:17:45 +02:00
|
|
|
bool do_ref_count) /*!< in: if true then increment the
|
|
|
|
trx_t::n_ref_count */
|
2012-08-01 16:27:34 +02:00
|
|
|
{
|
|
|
|
trx_t* trx;
|
2009-05-27 11:45:59 +02:00
|
|
|
|
2016-08-12 10:17:45 +02:00
|
|
|
trx_sys_mutex_enter();
|
2012-08-01 16:27:34 +02:00
|
|
|
|
|
|
|
trx = trx_rw_is_active_low(trx_id, corrupt);
|
|
|
|
|
2016-08-12 10:17:45 +02:00
|
|
|
if (trx != 0) {
|
|
|
|
trx = trx_reference(trx, do_ref_count);
|
|
|
|
}
|
|
|
|
|
|
|
|
trx_sys_mutex_exit();
|
2012-08-01 16:27:34 +02:00
|
|
|
|
|
|
|
return(trx);
|
2009-05-27 11:45:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************//**
|
|
|
|
Allocates a new transaction id.
|
2016-08-12 10:17:45 +02:00
|
|
|
@return new, allocated trx id */
|
2009-05-27 11:45:59 +02:00
|
|
|
UNIV_INLINE
|
|
|
|
trx_id_t
|
2016-08-12 10:17:45 +02:00
|
|
|
trx_sys_get_new_trx_id()
|
|
|
|
/*====================*/
|
2009-05-27 11:45:59 +02:00
|
|
|
{
|
2014-08-06 14:39:15 +02:00
|
|
|
#ifndef WITH_WSREP
|
|
|
|
/* wsrep_fake_trx_id violates this assert */
|
2016-09-06 08:43:16 +02:00
|
|
|
ut_ad(trx_sys_mutex_own());
|
2014-08-06 14:39:15 +02:00
|
|
|
#endif /* WITH_WSREP */
|
2009-05-27 11:45:59 +02:00
|
|
|
|
|
|
|
/* 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! */
|
|
|
|
|
2016-08-12 10:17:45 +02:00
|
|
|
if (!(trx_sys->max_trx_id % TRX_SYS_TRX_ID_WRITE_MARGIN)) {
|
2009-05-27 11:45:59 +02:00
|
|
|
|
|
|
|
trx_sys_flush_max_trx_id();
|
|
|
|
}
|
|
|
|
|
2012-08-01 16:27:34 +02:00
|
|
|
return(trx_sys->max_trx_id++);
|
|
|
|
}
|
2009-05-27 11:45:59 +02:00
|
|
|
|
2012-08-01 16:27:34 +02:00
|
|
|
/*****************************************************************//**
|
|
|
|
Determines the maximum transaction id.
|
|
|
|
@return maximum currently allocated trx id; will be stale after the
|
|
|
|
next call to trx_sys_get_new_trx_id() */
|
|
|
|
UNIV_INLINE
|
|
|
|
trx_id_t
|
|
|
|
trx_sys_get_max_trx_id(void)
|
|
|
|
/*========================*/
|
|
|
|
{
|
2016-08-12 10:17:45 +02:00
|
|
|
ut_ad(!trx_sys_mutex_own());
|
2012-08-01 16:27:34 +02:00
|
|
|
|
|
|
|
#if UNIV_WORD_SIZE < DATA_TRX_ID_LEN
|
|
|
|
/* Avoid torn reads. */
|
2016-08-12 10:17:45 +02:00
|
|
|
|
|
|
|
trx_sys_mutex_enter();
|
|
|
|
|
|
|
|
trx_id_t max_trx_id = trx_sys->max_trx_id;
|
|
|
|
|
|
|
|
trx_sys_mutex_exit();
|
|
|
|
|
2012-08-01 16:27:34 +02:00
|
|
|
return(max_trx_id);
|
|
|
|
#else
|
|
|
|
/* Perform a dirty read. Callers should be prepared for stale
|
|
|
|
values, and we know that the value fits in a machine word, so
|
|
|
|
that it will be read and written atomically. */
|
|
|
|
return(trx_sys->max_trx_id);
|
2016-08-12 10:17:45 +02:00
|
|
|
#endif /* UNIV_WORD_SIZE < DATA_TRX_ID_LEN */
|
2009-05-27 11:45:59 +02:00
|
|
|
}
|
|
|
|
|
2012-08-01 16:27:34 +02:00
|
|
|
/*****************************************************************//**
|
|
|
|
Get the number of transaction in the system, independent of their state.
|
|
|
|
@return count of transactions in trx_sys_t::rw_trx_list */
|
|
|
|
UNIV_INLINE
|
|
|
|
ulint
|
|
|
|
trx_sys_get_n_rw_trx(void)
|
|
|
|
/*======================*/
|
|
|
|
{
|
|
|
|
ulint n_trx;
|
|
|
|
|
2016-08-12 10:17:45 +02:00
|
|
|
trx_sys_mutex_enter();
|
2012-08-01 16:27:34 +02:00
|
|
|
|
|
|
|
n_trx = UT_LIST_GET_LEN(trx_sys->rw_trx_list);
|
|
|
|
|
2016-08-12 10:17:45 +02:00
|
|
|
trx_sys_mutex_exit();
|
2012-08-01 16:27:34 +02:00
|
|
|
|
|
|
|
return(n_trx);
|
|
|
|
}
|
2016-08-12 10:17:45 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
Add the transaction to the RW transaction set
|
|
|
|
@param trx transaction instance to add */
|
|
|
|
UNIV_INLINE
|
|
|
|
void
|
|
|
|
trx_sys_rw_trx_add(trx_t* trx)
|
|
|
|
{
|
|
|
|
ut_ad(trx->id != 0);
|
|
|
|
|
|
|
|
trx_sys->rw_trx_set.insert(TrxTrack(trx->id, trx));
|
|
|
|
ut_d(trx->in_rw_trx_list = true);
|
|
|
|
}
|