mariadb/include/trx0sys.ic
marko d118d29eb3 branches/innodb+: Merge revisions 4006:4060 from branches/zip:
------------------------------------------------------------------------
  r4008 | vasil | 2009-01-20 17:01:08 +0200 (Tue, 20 Jan 2009) | 4 lines

  branches/zip:

  Add ChangeLog entries for the bugfixes in r4004 and r4005.

  ------------------------------------------------------------------------
  r4027 | marko | 2009-01-23 11:04:49 +0200 (Fri, 23 Jan 2009) | 1 line

  branches/zip: Remove some redundant #include statements.
  ------------------------------------------------------------------------
  r4028 | marko | 2009-01-23 11:26:10 +0200 (Fri, 23 Jan 2009) | 13 lines

  branches/zip: Enclose some more unused code in #ifdef UNIV_LOG_ARCHIVE.
  This will help trim the dependencies of InnoDB Hot Backup.

  recv_recovery_from_checkpoint_start(): Rename to
  recv_recovery_from_checkpoint_start_func(), and remove the two first
  parameters unless UNIV_LOG_ARCHIVE is defined.  Define and use
  the auxiliary macros TYPE_CHECKPOINT and LIMIT_LSN in the function.

  struct recv_sys_struct: Remove archive_group unless UNIV_LOG_ARCHIVE
  is defined.

  Do not define LOG_ARCHIVE unless UNIV_LOG_ARCHIVE is defined.
  ------------------------------------------------------------------------
  r4029 | marko | 2009-01-23 14:07:38 +0200 (Fri, 23 Jan 2009) | 1 line

  branches/zip: Remove some redundant #include directives.
  ------------------------------------------------------------------------
  r4030 | marko | 2009-01-23 15:31:36 +0200 (Fri, 23 Jan 2009) | 2 lines

  branches/zip: buf_page_get_gen(): Remove the unused mode BUF_GET_NOWAIT.
  This was noticed while investigating Issue #160.
  ------------------------------------------------------------------------
  r4033 | marko | 2009-01-23 15:49:04 +0200 (Fri, 23 Jan 2009) | 16 lines

  branches/zip: Merge revisions 4005:4032 from branches/5.1:

    ------------------------------------------------------------------------
    r4032 | marko | 2009-01-23 15:43:51 +0200 (Fri, 23 Jan 2009) | 10 lines

    branches/5.1: Merge r4031 from branches/5.0:

    btr_search_drop_page_hash_when_freed(): Check if buf_page_get_gen()
    returns NULL.  The page may have been evicted from the buffer pool
    between buf_page_peek_if_search_hashed() and buf_page_get_gen(),
    because the buffer pool mutex will be released between these two calls.
    (Bug #42279, Issue #160)

    rb://82 approved by Heikki Tuuri
    ------------------------------------------------------------------------
  ------------------------------------------------------------------------
  r4034 | marko | 2009-01-26 16:16:39 +0200 (Mon, 26 Jan 2009) | 2 lines

  branches/zip: buf_page_get_gen(): Fix a "possibly uninitialized" warning
  that was introduced in r4030.
  ------------------------------------------------------------------------
  r4036 | marko | 2009-01-26 22:33:20 +0200 (Mon, 26 Jan 2009) | 22 lines

  branches/zip: In r988, the function buf_block_align() was enclosed
  within UNIV_DEBUG. The two remaining callers in non-debug builds,
  btr_search_guess_on_hash() and btr_search_validate(), were rewritten
  to call buf_page_hash_get().

  To implement support for a resizeable buffer pool, the function
  buf_block_align() had been rewritten to perform a page hash lookup in
  the buffer pool. The caller was also made responsible for holding the
  buffer pool mutex.

  Because the page hash lookup is expensive and it has to be done while
  holding the buffer pool mutex, implement buf_block_align() by pointer
  arithmetics again, and make btr_search_guess_on_hash() call it. Note
  that this will have to be adjusted if the interface to the resizeable
  buffer pool is actually implemented.

  rb://83 approved by Heikki Tuuri, to address Issue #161.

  As a deviation from the approved patch, this patch also makes
  btr_search_validate() (invoked by CHECK TABLE) check that
  buf_pool->page_hash is consistent with buf_block_align().
  ------------------------------------------------------------------------
  r4039 | vasil | 2009-01-27 08:04:17 +0200 (Tue, 27 Jan 2009) | 5 lines

  branches/zip:

  Adjust the paths in innodb_file_per_table.diff with a recent rename of
  the test/result files in the MySQL tree.
  ------------------------------------------------------------------------
  r4042 | marko | 2009-01-27 10:05:24 +0200 (Tue, 27 Jan 2009) | 2 lines

  branches/zip: buf_LRU_invalidate_tablespace(): Fix a race condition:
  read zip_size while still holding block_mutex.
  ------------------------------------------------------------------------
  r4045 | marko | 2009-01-28 00:31:17 +0200 (Wed, 28 Jan 2009) | 8 lines

  branches/zip: btr_search_validate(): Fix a bogus UNIV_DEBUG
  assertion failure that was accidentally introduced in r4036.
  Instead of calling buf_block_get_frame(), which asserts that the
  block must be buffer-fixed, access block->frame directly.  That
  is safe, because changes of block->page.state are protected by
  the buffer pool mutex, which we are holding.

  This bug was reported by Michael.
  ------------------------------------------------------------------------
  r4046 | marko | 2009-01-28 00:33:20 +0200 (Wed, 28 Jan 2009) | 2 lines

  branches/zip: Revert the change to univ.i that was accidentally
  committed in r4045.
  ------------------------------------------------------------------------
  r4047 | marko | 2009-01-28 00:46:13 +0200 (Wed, 28 Jan 2009) | 6 lines

  branches/zip: btr_search_validate(): Fix an assertion failure that was
  introduced in r4036.
  Do not call buf_block_get_space(), buf_block_get_page_no()
  unless the block state is BUF_BLOCK_FILE_PAGE.

  This bug was reported by Michael.
  ------------------------------------------------------------------------
  r4050 | vasil | 2009-01-28 08:21:44 +0200 (Wed, 28 Jan 2009) | 5 lines

  branches/zip:

  Adjust the paths in innodb_lock_wait_timeout.diff with a recent rename of
  the test/result files in the MySQL tree.
  ------------------------------------------------------------------------
  r4051 | marko | 2009-01-28 14:35:49 +0200 (Wed, 28 Jan 2009) | 1 line

  branches/zip: trx0sys.ic: Remove unnecessary #include <data0type.h>.
  ------------------------------------------------------------------------
  r4052 | marko | 2009-01-28 15:21:45 +0200 (Wed, 28 Jan 2009) | 5 lines

  branches/zip: Enclose some functions inside #ifdef UNIV_HOTBACKUP:

  ut_sprintf_timestamp_without_extra_chars(), ut_get_year_month_day(),
  log_reset_first_header_and_checkpoint(): These functions are only used
  in InnoDB Hot Backup.
  ------------------------------------------------------------------------
  r4056 | calvin | 2009-01-29 03:06:41 +0200 (Thu, 29 Jan 2009) | 33 lines

  branches/zip: Merge revisions 4032:4035 from branches/5.1

  All InnoDB related tests passed on Windows, except
  known failure in partition_innodb_semi_consistent.

  The inadvertent change to btr0sea.c in this commit is reverted in r4060.

    ------------------------------------------------------------------------
    r4035 | vasil | 2009-01-26 09:26:25 -0600 (Mon, 26 Jan 2009) | 23 lines

    branches/5.1:

    Merge a change from MySQL:

      ------------------------------------------------------------
      revno: 2646.161.4
      committer: Tatiana A. Nurnberg <azundris@mysql.com>
      branch nick: 51-31177v2
      timestamp: Mon 2009-01-12 06:32:49 +0100
      message:
        Bug#31177: Server variables can't be set to their current values

        Bounds-checks and blocksize corrections were applied to user-input,
        but constants in the server were trusted implicitly. If these values
        did not actually meet the requirements, the user could not set change
        a variable, then set it back to the (wonky) factory default or maximum
        by explicitly specifying it (SET <var>=<value> vs SET <var>=DEFAULT).

        Now checks also apply to the server's presets. Wonky values and maxima
        get corrected at startup. Consequently all non-offsetted values the user
        sees are valid, and users can set the variable to that exact value if
        they so desire.
  ------------------------------------------------------------------------
  r4060 | marko | 2009-01-29 09:39:04 +0200 (Thu, 29 Jan 2009) | 1 line

  branches/zip: btr0sea.c: Revert the inadvertent change made in r4056.
  ------------------------------------------------------------------------
2009-01-29 09:47:07 +00:00

367 lines
9.2 KiB
Text

/******************************************************
Transaction system
(c) 1996 Innobase Oy
Created 3/26/1996 Heikki Tuuri
*******************************************************/
#include "srv0srv.h"
#include "trx0trx.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. */
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 */
{
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. */
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 */
{
#if DATA_TRX_ID_LEN != 6
# error "DATA_TRX_ID_LEN != 6"
#endif
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 */
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. */
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);
}
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. */
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());
}