mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 12:02:42 +01:00
209a500df9
Implement ON DELETE CASCADE and facilitate switching off of UNIQUE constraints and foreign keys innobase/btr/btr0cur.c: Implement ON DELETE CASCADE and facilitate switching off of UNIQUE constraints and foreign keys innobase/dict/dict0crea.c: Implement ON DELETE CASCADE and facilitate switching off of UNIQUE constraints and foreign keys innobase/dict/dict0dict.c: Implement ON DELETE CASCADE and facilitate switching off of UNIQUE constraints and foreign keys innobase/dict/dict0load.c: Implement ON DELETE CASCADE and facilitate switching off of UNIQUE constraints and foreign keys innobase/dict/dict0mem.c: Implement ON DELETE CASCADE and facilitate switching off of UNIQUE constraints and foreign keys innobase/include/btr0btr.h: Implement ON DELETE CASCADE and facilitate switching off of UNIQUE constraints and foreign keys innobase/include/dict0mem.h: Implement ON DELETE CASCADE and facilitate switching off of UNIQUE constraints and foreign keys innobase/include/ibuf0ibuf.h: Implement ON DELETE CASCADE and facilitate switching off of UNIQUE constraints and foreign keys innobase/include/os0file.h: Implement ON DELETE CASCADE and facilitate switching off of UNIQUE constraints and foreign keys innobase/include/os0sync.h: Implement ON DELETE CASCADE and facilitate switching off of UNIQUE constraints and foreign keys innobase/include/row0mysql.h: Implement ON DELETE CASCADE and facilitate switching off of UNIQUE constraints and foreign keys innobase/include/row0upd.h: Implement ON DELETE CASCADE and facilitate switching off of UNIQUE constraints and foreign keys innobase/include/sync0sync.h: Implement ON DELETE CASCADE and facilitate switching off of UNIQUE constraints and foreign keys innobase/include/trx0sys.h: Implement ON DELETE CASCADE and facilitate switching off of UNIQUE constraints and foreign keys innobase/include/trx0trx.h: Implement ON DELETE CASCADE and facilitate switching off of UNIQUE constraints and foreign keys innobase/include/ibuf0ibuf.ic: Implement ON DELETE CASCADE and facilitate switching off of UNIQUE constraints and foreign keys innobase/include/os0sync.ic: Implement ON DELETE CASCADE and facilitate switching off of UNIQUE constraints and foreign keys innobase/include/sync0sync.ic: Implement ON DELETE CASCADE and facilitate switching off of UNIQUE constraints and foreign keys innobase/include/trx0sys.ic: Implement ON DELETE CASCADE and facilitate switching off of UNIQUE constraints and foreign keys innobase/lock/lock0lock.c: Implement ON DELETE CASCADE and facilitate switching off of UNIQUE constraints and foreign keys innobase/pars/pars0opt.c: Implement ON DELETE CASCADE and facilitate switching off of UNIQUE constraints and foreign keys innobase/que/que0que.c: Implement ON DELETE CASCADE and facilitate switching off of UNIQUE constraints and foreign keys innobase/row/row0ins.c: Implement ON DELETE CASCADE and facilitate switching off of UNIQUE constraints and foreign keys innobase/row/row0mysql.c: Implement ON DELETE CASCADE and facilitate switching off of UNIQUE constraints and foreign keys innobase/row/row0sel.c: Implement ON DELETE CASCADE and facilitate switching off of UNIQUE constraints and foreign keys innobase/row/row0upd.c: Implement ON DELETE CASCADE and facilitate switching off of UNIQUE constraints and foreign keys innobase/srv/srv0srv.c: Implement ON DELETE CASCADE and facilitate switching off of UNIQUE constraints and foreign keys innobase/sync/sync0sync.c: Implement ON DELETE CASCADE and facilitate switching off of UNIQUE constraints and foreign keys innobase/trx/trx0sys.c: Implement ON DELETE CASCADE and facilitate switching off of UNIQUE constraints and foreign keys innobase/trx/trx0trx.c: Implement ON DELETE CASCADE and facilitate switching off of UNIQUE constraints and foreign keys
351 lines
8.7 KiB
Text
351 lines
8.7 KiB
Text
/******************************************************
|
|
Transaction system
|
|
|
|
(c) 1996 Innobase Oy
|
|
|
|
Created 3/26/1996 Heikki Tuuri
|
|
*******************************************************/
|
|
|
|
#include "srv0srv.h"
|
|
#include "trx0trx.h"
|
|
#include "data0type.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 */
|
|
#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. */
|
|
|
|
void
|
|
trx_sys_flush_max_trx_id(void);
|
|
/*==========================*/
|
|
|
|
/*******************************************************************
|
|
Checks if a page address is the trx sys header page. */
|
|
UNIV_INLINE
|
|
ibool
|
|
trx_sys_hdr_page(
|
|
/*=============*/
|
|
/* out: TRUE if trx sys header 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. */
|
|
UNIV_INLINE
|
|
trx_rseg_t*
|
|
trx_sys_get_nth_rseg(
|
|
/*=================*/
|
|
/* out: pointer to rseg object, NULL if slot
|
|
not in use */
|
|
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. */
|
|
UNIV_INLINE
|
|
trx_sysf_t*
|
|
trx_sysf_get(
|
|
/*=========*/
|
|
/* out: pointer to system header, page x-latched. */
|
|
mtr_t* mtr) /* in: mtr */
|
|
{
|
|
trx_sysf_t* header;
|
|
|
|
ut_ad(mtr);
|
|
|
|
header = TRX_SYS + buf_page_get(TRX_SYS_SPACE, TRX_SYS_PAGE_NO,
|
|
RW_X_LATCH, mtr);
|
|
|
|
buf_page_dbg_add_level(header, SYNC_TRX_SYS_HEADER);
|
|
|
|
return(header);
|
|
}
|
|
|
|
/*********************************************************************
|
|
Gets the space of the nth rollback segment slot in the trx system
|
|
file copy. */
|
|
UNIV_INLINE
|
|
ulint
|
|
trx_sysf_rseg_get_space(
|
|
/*====================*/
|
|
/* out: space id */
|
|
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. */
|
|
UNIV_INLINE
|
|
ulint
|
|
trx_sysf_rseg_get_page_no(
|
|
/*======================*/
|
|
/* out: page number, FIL_NULL
|
|
if slot unused */
|
|
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);
|
|
}
|
|
|
|
/*********************************************************************
|
|
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 */
|
|
dulint id) /* in: id */
|
|
{
|
|
ut_ad(DATA_TRX_ID_LEN == 6);
|
|
|
|
mach_write_to_6(ptr, id);
|
|
}
|
|
|
|
/*********************************************************************
|
|
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_... */
|
|
UNIV_INLINE
|
|
dulint
|
|
trx_read_trx_id(
|
|
/*============*/
|
|
/* out: id */
|
|
byte* ptr) /* in: pointer to memory from where to read */
|
|
{
|
|
ut_ad(DATA_TRX_ID_LEN == 6);
|
|
|
|
return(mach_read_from_6(ptr));
|
|
}
|
|
|
|
/********************************************************************
|
|
Looks for the trx handle with the given id in trx_list. */
|
|
UNIV_INLINE
|
|
trx_t*
|
|
trx_get_on_id(
|
|
/*==========*/
|
|
/* out: the trx handle or NULL if not found */
|
|
dulint 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.) */
|
|
UNIV_INLINE
|
|
dulint
|
|
trx_list_get_min_trx_id(void)
|
|
/*=========================*/
|
|
/* out: the minimum trx id, or trx_sys->max_trx_id
|
|
if the trx list is empty */
|
|
{
|
|
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. */
|
|
UNIV_INLINE
|
|
ibool
|
|
trx_is_active(
|
|
/*==========*/
|
|
/* out: TRUE if active */
|
|
dulint 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);
|
|
}
|
|
|
|
trx = trx_get_on_id(trx_id);
|
|
if (trx && (trx->conc_state == TRX_ACTIVE)) {
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
/*********************************************************************
|
|
Allocates a new transaction id. */
|
|
UNIV_INLINE
|
|
dulint
|
|
trx_sys_get_new_trx_id(void)
|
|
/*========================*/
|
|
/* out: new, allocated trx id */
|
|
{
|
|
dulint 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. */
|
|
UNIV_INLINE
|
|
dulint
|
|
trx_sys_get_new_trx_no(void)
|
|
/*========================*/
|
|
/* out: new, allocated trx number */
|
|
{
|
|
ut_ad(mutex_own(&kernel_mutex));
|
|
|
|
return(trx_sys_get_new_trx_id());
|
|
}
|