mariadb/innobase/include/read0read.h
unknown 6861b1bf9b A fix and a test case for Bug#12243 "MySQL Server crashes with 2
cursors (+ commit)" and Bug#11832 "Server crash with InnoDB + Cursors"
See comments to the changed files.


innobase/include/read0read.h:
  - add cursor_view_t::n_mysql_tables_in_use
innobase/read/read0read.c:
  - maintain cursor_view_t::n_mysql_tables_in_use. InnoDB
  maintains trx->n_mysql_tables_in_use to know when it can auto-commit
  a read-only statement. When this count drops to zero,
  MySQL has ended processing of such statement and InnoDB can commit.
  Cursors should not break this invariant, and should exclude the tables
  used in a cursor from the count of active tables.
  When a cursor is closed, the number of its tables is added back, 
  to ensure that close_thread_tables->unlock_external->
  ha_innobase::external_lock(F_UNLCK) won't drop the count in trx 
  below zero.
innobase/row/row0sel.c:
  - remove the restoration of the global read view from 
  row_search_for_mysql: MySQL may call row_search_for_mysql
  more than once when fetching a row for a cursor (e.g. if there
  is a WHERE clause that filters out some rows).
sql/ha_innodb.cc:
  - add more verbose printout for the case when we close an InnoDB
  connection without priorlly issuing a commit or rollback. The problem
  should be investigated.
tests/mysql_client_test.c:
  - add a test case for Bug#12243 "MySQL Server crashes with 2 cursors 
  (+ commit)"
2005-08-10 18:36:13 +04:00

148 lines
5.1 KiB
C

/******************************************************
Cursor read
(c) 1997 Innobase Oy
Created 2/16/1997 Heikki Tuuri
*******************************************************/
#ifndef read0read_h
#define read0read_h
#include "univ.i"
#include "ut0byte.h"
#include "ut0lst.h"
#include "trx0trx.h"
#include "read0types.h"
/*************************************************************************
Opens a read view where exactly the transactions serialized before this
point in time are seen in the view. */
read_view_t*
read_view_open_now(
/*===============*/
/* out, own: read view struct */
trx_t* cr_trx, /* in: creating transaction, or NULL */
mem_heap_t* heap); /* in: memory heap from which allocated */
/*************************************************************************
Makes a copy of the oldest existing read view, or opens a new. The view
must be closed with ..._close. */
read_view_t*
read_view_oldest_copy_or_open_new(
/*==============================*/
/* out, own: read view struct */
trx_t* cr_trx, /* in: creating transaction, or NULL */
mem_heap_t* heap); /* in: memory heap from which allocated */
/*************************************************************************
Closes a read view. */
void
read_view_close(
/*============*/
read_view_t* view); /* in: read view */
/*************************************************************************
Closes a consistent read view for MySQL. This function is called at an SQL
statement end if the trx isolation level is <= TRX_ISO_READ_COMMITTED. */
void
read_view_close_for_mysql(
/*======================*/
trx_t* trx); /* in: trx which has a read view */
/*************************************************************************
Checks if a read view sees the specified transaction. */
UNIV_INLINE
ibool
read_view_sees_trx_id(
/*==================*/
/* out: TRUE if sees */
read_view_t* view, /* in: read view */
dulint trx_id); /* in: trx id */
/*************************************************************************
Prints a read view to stderr. */
void
read_view_print(
/*============*/
read_view_t* view); /* in: read view */
/*************************************************************************
Create a consistent cursor view for mysql to be used in cursors. In this
consistent read view modifications done by the creating transaction or future
transactions are not visible. */
cursor_view_t*
read_cursor_view_create_for_mysql(
/*==============================*/
trx_t* cr_trx);/* in: trx where cursor view is created */
/*************************************************************************
Close a given consistent cursor view for mysql and restore global read view
back to a transaction read view. */
void
read_cursor_view_close_for_mysql(
/*=============================*/
trx_t* trx, /* in: trx */
cursor_view_t* curview); /* in: cursor view to be closed */
/*************************************************************************
This function sets a given consistent cursor view to a transaction
read view if given consistent cursor view is not NULL. Otherwise, function
restores a global read view to a transaction read view. */
void
read_cursor_set_for_mysql(
/*======================*/
trx_t* trx, /* in: transaction where cursor is set */
cursor_view_t* curview);/* in: consistent cursor view to be set */
/* Read view lists the trx ids of those transactions for which a consistent
read should not see the modifications to the database. */
struct read_view_struct{
ibool can_be_too_old; /* TRUE if the system has had to purge old
versions which this read view should be able
to access: the read view can bump into the
DB_MISSING_HISTORY error */
dulint low_limit_no; /* The view does not need to see the undo
logs for transactions whose transaction number
is strictly smaller (<) than this value: they
can be removed in purge if not needed by other
views */
dulint low_limit_id; /* The read should not see any transaction
with trx id >= this value */
dulint up_limit_id; /* The read should see all trx ids which
are strictly smaller (<) than this value */
ulint n_trx_ids; /* Number of cells in the trx_ids array */
dulint* trx_ids; /* Additional trx ids which the read should
not see: typically, these are the active
transactions at the time when the read is
serialized, except the reading transaction
itself; the trx ids in this array are in a
descending order */
trx_t* creator; /* Pointer to the creating transaction, or
NULL if used in purge */
UT_LIST_NODE_T(read_view_t) view_list;
/* List of read views in trx_sys */
};
/* Implement InnoDB framework to support consistent read views in
cursors. This struct holds both heap where consistent read view
is allocated and pointer to a read view. */
struct cursor_view_struct{
mem_heap_t* heap;
/* Memory heap for the cursor view */
read_view_t* read_view;
/* Consistent read view of the cursor*/
ulint n_mysql_tables_in_use;
/* number of Innobase tables used in the
processing of this cursor */
};
#ifndef UNIV_NONINL
#include "read0read.ic"
#endif
#endif