mariadb/storage/innobase/mtr/mtr0mtr.c
unknown f6f91b9d3b Apply InnoDB snapshot ss923
Fixes:
- Bug #18077: InnoDB uses full explicit table locks in stored FUNCTION


storage/innobase/btr/btr0btr.c:
  Apply InnoDB snapshot ss923
  
  Revision r919:
  btr_page_get_father_for_rec(): Remove bogus comment about removed dict_tree_t.
storage/innobase/dict/dict0dict.c:
  Apply InnoDB snapshot ss923
  
  Revision r892:
  Merge changes from MySQL AB.
  
  dict_col_copy_type_noninline(): Remove the return statement.
  Some compilers do not allow return expressions of void type.
  
  innobase_start_or_create_for_mysql(): Do not cap srv_max_threads to 1000
  on Windows.
  
  Makefile.am (EXTRA_DIST): Add plug.in
  
  
  Revision r897:
  dict_index_get_if_in_cache(): Enclose in #ifdef UNIV_DEBUG.
  Replace the search loop with a call to dict_index_find_on_id_low().
storage/innobase/handler/ha_innodb.cc:
  Apply InnoDB snapshot ss923
  
  Revision r887:
  storage/innobase/handler: Merge changes from MySQL AB:
  
  ChangeSet
    2006/09/30 18:44:42-07:00 brian@zim.(none) 
    Merge zim.(none):/home/brian/mysql/merge-5.1
    into  zim.(none):/home/brian/mysql/arch-5.1
  
  ChangeSet
    2006/09/30 12:49:46-07:00 brian@zim.(none) 
    This patch adds handlerton passing to functions. NDB and Innodb still require a global hanlderton in the main code due to the nature of the sql_cache call back function (should be solveable... another patch).
    Partitioning now has a flag to allow disabling of engines from being compatible with partitioning. Cleaned up heap naming convention on panic call. 
  
  ChangeSet
    2006/09/29 17:19:02-07:00 brian@zim.(none) 
    This removes the passing of global hton to engine instance. 
  
  ChangeSet
    2006/09/28 13:22:56+02:00 gbichot@dl145h.mysql.com 
    Merge gbichot@bk-internal:/home/bk/mysql-5.1-arch
    into  dl145h.mysql.com:/users/gbichot/mysql-5.1-arch
  
  ChangeSet
    2006/09/28 13:19:43+02:00 gbichot@dl145h.mysql.com 
    In the handlerton, cursor creation function don't have an argument
    and so the engine calls current_thd to derive transaction information;
    instead we now pass THD to those functions, it looks more logical
    (it makes the implicit current_thd parameter more visible).
    Approved by Brian and Monty.
  
  ChangeSet
    2006/09/26 22:51:53-07:00 brian@zim.(none) 
    Merge zim.(none):/home/brian/mysql/merge-5.1
    into  zim.(none):/home/brian/mysql/arch-5.1
  
  
  Revision r895:
  Merge changes from MySQL AB, and remove two compilation warnings.
  
  ha_innodb.cc: innodb_mutex_show_status(): Add (ulong) casts to
  ulonglong expressions being passed to fprintf %lu.  The warnings
  were apparently introduced by MySQL AB developers.
  
  mysql_declare_plugin(innobase): Add PLUGIN_LICENSE_GPL.
  
  have_innodb.inc: Merge changes from MySQL AB.
  
  
  Revision r923:
  ha_innobase::store_lock(): When downgrading table locks, do not
  check thd->in_lock_tables but test if
  thd->lex->sql_command == SQLCOM_LOCK_TABLES
  instead.  Otherwise, stored functions will use table locks.  (Bug #18077)
  
  This patch is from Heikki.
storage/innobase/include/dict0dict.h:
  Apply InnoDB snapshot ss923
  
  Revision r897:
  dict_index_get_if_in_cache(): Enclose in #ifdef UNIV_DEBUG.
  Replace the search loop with a call to dict_index_find_on_id_low().
storage/innobase/include/mem0dbg.h:
  Apply InnoDB snapshot ss923
  
  Revision r901:
  Enclose some mem debug functions in #ifdef UNIV_DEBUG or #ifdef UNIV_MEM_DEBUG.
storage/innobase/include/mtr0mtr.h:
  Apply InnoDB snapshot ss923
  
  Revision r866:
  mtr_print(), mtr_memo_contains(): Disable unless #ifdef UNIV_DEBUG.
storage/innobase/include/mtr0mtr.ic:
  Apply InnoDB snapshot ss923
  
  Revision r866:
  mtr_print(), mtr_memo_contains(): Disable unless #ifdef UNIV_DEBUG.
storage/innobase/include/sync0rw.h:
  Apply InnoDB snapshot ss923
  
  Revision r907:
  Send all SHOW ENGINE INNODB STATUS information to the client also when
  UNIV_SYNC_DEBUG is defined.
  
  rw_lock_list_print_info(): Add parameter "file".
  
  mutex_list_print_info(): Add parameter "file".  Make the function static.
storage/innobase/include/sync0sync.h:
  Apply InnoDB snapshot ss923
  
  Revision r907:
  Send all SHOW ENGINE INNODB STATUS information to the client also when
  UNIV_SYNC_DEBUG is defined.
  
  rw_lock_list_print_info(): Add parameter "file".
  
  mutex_list_print_info(): Add parameter "file".  Make the function static.
storage/innobase/include/univ.i:
  Apply InnoDB snapshot ss923
  
  Revision r894:
  univ.i: Indent some of the directives, and remove conditions about Windows
  in the "#else" branch of "#if building on Windows".
storage/innobase/mem/mem0dbg.c:
  Apply InnoDB snapshot ss923
  
  Revision r901:
  Enclose some mem debug functions in #ifdef UNIV_DEBUG or #ifdef UNIV_MEM_DEBUG.
  
  
  Revision r902:
  mem0dbg.c: Enclose some more function definitions in #ifdef UNIV_MEM_DEBUG.
  The declarations were already enclosed in #ifdef UNIV_MEM_DEBUG.
storage/innobase/mem/mem0pool.c:
  Apply InnoDB snapshot ss923
  
  Revision r896:
  mem0pool.c: Remove obsolete comments about the dictionary cache being
  managed with an LRU algorithm.
storage/innobase/mtr/mtr0mtr.c:
  Apply InnoDB snapshot ss923
  
  Revision r866:
  mtr_print(), mtr_memo_contains(): Disable unless #ifdef UNIV_DEBUG.
storage/innobase/row/row0purge.c:
  Apply InnoDB snapshot ss923
  
  Revision r869:
  row_purge_parse_undo_rec(): Correct a faulty condition.  Luckily, this
  bug would only surface if the InnoDB SQL interpreter were used for
  updating fixed-length columns.  Currently (as the UPD_NODE_NO_SIZE_CHANGE
  flag is never set), cmpl_info can only be 0 or UPD_NODE_NO_ORD_CHANGE.
  Luckily, UPD_NODE_NO_ORD_CHANGE is 1, and the condition was simplified
  to !cmpl_info.
storage/innobase/sync/sync0rw.c:
  Apply InnoDB snapshot ss923
  
  Revision r907:
  Send all SHOW ENGINE INNODB STATUS information to the client also when
  UNIV_SYNC_DEBUG is defined.
  
  rw_lock_list_print_info(): Add parameter "file".
  
  mutex_list_print_info(): Add parameter "file".  Make the function static.
storage/innobase/sync/sync0sync.c:
  Apply InnoDB snapshot ss923
  
  Revision r907:
  Send all SHOW ENGINE INNODB STATUS information to the client also when
  UNIV_SYNC_DEBUG is defined.
  
  rw_lock_list_print_info(): Add parameter "file".
  
  mutex_list_print_info(): Add parameter "file".  Make the function static.
2006-10-20 12:36:15 -06:00

336 lines
7.9 KiB
C

/******************************************************
Mini-transaction buffer
(c) 1995 Innobase Oy
Created 11/26/1995 Heikki Tuuri
*******************************************************/
#include "mtr0mtr.h"
#ifdef UNIV_NONINL
#include "mtr0mtr.ic"
#endif
#include "buf0buf.h"
#include "page0types.h"
#include "mtr0log.h"
#include "log0log.h"
/*******************************************************************
Starts a mini-transaction and creates a mini-transaction handle
and buffer in the memory buffer given by the caller. */
mtr_t*
mtr_start_noninline(
/*================*/
/* out: mtr buffer which also acts as
the mtr handle */
mtr_t* mtr) /* in: memory buffer for the mtr buffer */
{
return(mtr_start(mtr));
}
/*********************************************************************
Releases the item in the slot given. */
UNIV_INLINE
void
mtr_memo_slot_release(
/*==================*/
mtr_t* mtr, /* in: mtr */
mtr_memo_slot_t* slot) /* in: memo slot */
{
void* object;
ulint type;
ut_ad(mtr && slot);
object = slot->object;
type = slot->type;
if (UNIV_LIKELY(object != NULL)) {
if (type <= MTR_MEMO_BUF_FIX) {
buf_page_release((buf_block_t*)object, type, mtr);
} else if (type == MTR_MEMO_S_LOCK) {
rw_lock_s_unlock((rw_lock_t*)object);
#ifdef UNIV_DEBUG
} else if (type == MTR_MEMO_X_LOCK) {
rw_lock_x_unlock((rw_lock_t*)object);
} else {
ut_ad(type == MTR_MEMO_MODIFY);
ut_ad(mtr_memo_contains(mtr, object,
MTR_MEMO_PAGE_X_FIX));
#else
} else {
rw_lock_x_unlock((rw_lock_t*)object);
#endif
}
}
slot->object = NULL;
}
/**************************************************************
Releases the mlocks and other objects stored in an mtr memo. They are released
in the order opposite to which they were pushed to the memo. NOTE! It is
essential that the x-rw-lock on a modified buffer page is not released before
buf_page_note_modification is called for that page! Otherwise, some thread
might race to modify it, and the flush list sort order on lsn would be
destroyed. */
UNIV_INLINE
void
mtr_memo_pop_all(
/*=============*/
mtr_t* mtr) /* in: mtr */
{
mtr_memo_slot_t* slot;
dyn_array_t* memo;
ulint offset;
ut_ad(mtr);
ut_ad(mtr->magic_n == MTR_MAGIC_N);
ut_ad(mtr->state == MTR_COMMITTING); /* Currently only used in
commit */
memo = &(mtr->memo);
offset = dyn_array_get_data_size(memo);
while (offset > 0) {
offset -= sizeof(mtr_memo_slot_t);
slot = dyn_array_get_element(memo, offset);
mtr_memo_slot_release(mtr, slot);
}
}
/****************************************************************
Writes the contents of a mini-transaction log, if any, to the database log. */
static
void
mtr_log_reserve_and_write(
/*======================*/
mtr_t* mtr) /* in: mtr */
{
dyn_array_t* mlog;
dyn_block_t* block;
ulint data_size;
ibool success;
byte* first_data;
ut_ad(mtr);
mlog = &(mtr->log);
first_data = dyn_block_get_data(mlog);
if (mtr->n_log_recs > 1) {
mlog_catenate_ulint(mtr, MLOG_MULTI_REC_END, MLOG_1BYTE);
} else {
*first_data = (byte)((ulint)*first_data
| MLOG_SINGLE_REC_FLAG);
}
if (mlog->heap == NULL) {
mtr->end_lsn = log_reserve_and_write_fast(
first_data, dyn_block_get_used(mlog),
&(mtr->start_lsn), &success);
if (success) {
return;
}
}
data_size = dyn_array_get_data_size(mlog);
/* Open the database log for log_write_low */
mtr->start_lsn = log_reserve_and_open(data_size);
if (mtr->log_mode == MTR_LOG_ALL) {
block = mlog;
while (block != NULL) {
log_write_low(dyn_block_get_data(block),
dyn_block_get_used(block));
block = dyn_array_get_next_block(mlog, block);
}
} else {
ut_ad(mtr->log_mode == MTR_LOG_NONE);
/* Do nothing */
}
mtr->end_lsn = log_close();
}
/*******************************************************************
Commits a mini-transaction. */
void
mtr_commit(
/*=======*/
mtr_t* mtr) /* in: mini-transaction */
{
ut_ad(mtr);
ut_ad(mtr->magic_n == MTR_MAGIC_N);
ut_ad(mtr->state == MTR_ACTIVE);
#ifdef UNIV_DEBUG
mtr->state = MTR_COMMITTING;
#endif
if (mtr->modifications) {
mtr_log_reserve_and_write(mtr);
}
/* We first update the modification info to buffer pages, and only
after that release the log mutex: this guarantees that when the log
mutex is free, all buffer pages contain an up-to-date info of their
modifications. This fact is used in making a checkpoint when we look
at the oldest modification of any page in the buffer pool. It is also
required when we insert modified buffer pages in to the flush list
which must be sorted on oldest_modification. */
mtr_memo_pop_all(mtr);
if (mtr->modifications) {
log_release();
}
#ifdef UNIV_DEBUG
mtr->state = MTR_COMMITTED;
#endif
dyn_array_free(&(mtr->memo));
dyn_array_free(&(mtr->log));
}
/**************************************************************
Releases the latches stored in an mtr memo down to a savepoint.
NOTE! The mtr must not have made changes to buffer pages after the
savepoint, as these can be handled only by mtr_commit. */
void
mtr_rollback_to_savepoint(
/*======================*/
mtr_t* mtr, /* in: mtr */
ulint savepoint) /* in: savepoint */
{
mtr_memo_slot_t* slot;
dyn_array_t* memo;
ulint offset;
ut_ad(mtr);
ut_ad(mtr->magic_n == MTR_MAGIC_N);
ut_ad(mtr->state == MTR_ACTIVE);
memo = &(mtr->memo);
offset = dyn_array_get_data_size(memo);
ut_ad(offset >= savepoint);
while (offset > savepoint) {
offset -= sizeof(mtr_memo_slot_t);
slot = dyn_array_get_element(memo, offset);
ut_ad(slot->type != MTR_MEMO_MODIFY);
mtr_memo_slot_release(mtr, slot);
}
}
/*******************************************************
Releases an object in the memo stack. */
void
mtr_memo_release(
/*=============*/
mtr_t* mtr, /* in: mtr */
void* object, /* in: object */
ulint type) /* in: object type: MTR_MEMO_S_LOCK, ... */
{
mtr_memo_slot_t* slot;
dyn_array_t* memo;
ulint offset;
ut_ad(mtr);
ut_ad(mtr->magic_n == MTR_MAGIC_N);
ut_ad(mtr->state == MTR_ACTIVE);
memo = &(mtr->memo);
offset = dyn_array_get_data_size(memo);
while (offset > 0) {
offset -= sizeof(mtr_memo_slot_t);
slot = dyn_array_get_element(memo, offset);
if ((object == slot->object) && (type == slot->type)) {
mtr_memo_slot_release(mtr, slot);
break;
}
}
}
/************************************************************
Reads 1 - 4 bytes from a file page buffered in the buffer pool. */
ulint
mtr_read_ulint(
/*===========*/
/* out: value read */
byte* ptr, /* in: pointer from where to read */
ulint type, /* in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */
mtr_t* mtr __attribute__((unused)))
/* in: mini-transaction handle */
{
ut_ad(mtr->state == MTR_ACTIVE);
ut_ad(mtr_memo_contains(mtr, buf_block_align(ptr),
MTR_MEMO_PAGE_S_FIX)
|| mtr_memo_contains(mtr, buf_block_align(ptr),
MTR_MEMO_PAGE_X_FIX));
if (type == MLOG_1BYTE) {
return(mach_read_from_1(ptr));
} else if (type == MLOG_2BYTES) {
return(mach_read_from_2(ptr));
} else {
ut_ad(type == MLOG_4BYTES);
return(mach_read_from_4(ptr));
}
}
/************************************************************
Reads 8 bytes from a file page buffered in the buffer pool. */
dulint
mtr_read_dulint(
/*============*/
/* out: value read */
byte* ptr, /* in: pointer from where to read */
mtr_t* mtr __attribute__((unused)))
/* in: mini-transaction handle */
{
ut_ad(mtr->state == MTR_ACTIVE);
ut_ad(ptr && mtr);
ut_ad(mtr_memo_contains(mtr, buf_block_align(ptr),
MTR_MEMO_PAGE_S_FIX)
|| mtr_memo_contains(mtr, buf_block_align(ptr),
MTR_MEMO_PAGE_X_FIX));
return(mach_read_from_8(ptr));
}
#ifdef UNIV_DEBUG
/*************************************************************
Prints info of an mtr handle. */
void
mtr_print(
/*======*/
mtr_t* mtr) /* in: mtr */
{
fprintf(stderr,
"Mini-transaction handle: memo size %lu bytes"
" log size %lu bytes\n",
(ulong) dyn_array_get_data_size(&(mtr->memo)),
(ulong) dyn_array_get_data_size(&(mtr->log)));
}
#endif /* UNIV_DEBUG */