mirror of
https://github.com/MariaDB/server.git
synced 2025-01-19 13:32:33 +01:00
d33b523271
Fixed BUGS: #3300: "UPDATE statement with no index column in where condition locks all rows" Implement semi-consistent read to reduce lock conflicts at the cost of breaking serializability. ha_innobase::unlock_row(): reset the "did semi consistent read" flag ha_innobase::was_semi_consistent_read(), ha_innobase::try_semi_consistent_read(): new methods row_prebuilt_t, row_create_prebuilt(): add field row_read_type for keeping track of semi-consistent reads row_vers_build_for_semi_consistent_read(), row_sel_build_committed_vers_for_mysql(): new functions row_search_for_mysql(): implement semi-consistent reads #9802: "Foreign key checks disallow alter table". Added test cases. #12456: "Cursor shows incorrect data - DML does not affect, probably caching" This patch implements a high-granularity read view to be used with cursors. In this high-granularity consistent read view modifications done by the creating transaction after the cursor is created or future transactions are not visible. But those modifications that transaction did before the cursor was created are visible. #12701: "Support >4GB buffer pool and log files on 64-bit Windows" Do not call os_file_create_tmpfile() at runtime. Instead, create all tempfiles at startup and guard access to them with mutexes. #13778: "If FOREIGN_KEY_CHECKS=0, one can create inconsistent FOREIGN KEYs". When FOREIGN_KEY_CHECKS=0 we still need to check that datatypes between foreign key references are compatible. #14189: "VARBINARY and BINARY variables: trailing space ignored with InnoDB" innobase_init(): Assert that DATA_MYSQL_BINARY_CHARSET_COLL == my_charset_bin.number. dtype_get_pad_char(): Do not pad VARBINARY or BINARY columns. row_ins_cascade_calc_update_vec(): Refuse ON UPDATE CASCADE when trying to change the length of a VARBINARY column that refers to or is referenced by a BINARY column. BINARY columns are no longer padded on comparison, and thus they cannot be padded on storage either. #14747: "Race condition can cause btr_search_drop_page_hash_index() to crash" Note that buf_block_t::index should be protected by btr_search_latch or an s-latch or x-latch on the index page. btr_search_drop_page_hash_index(): Read block->index while holding btr_search_latch and use the cached value in the loop. Remove some redundant assertions. #15108: "mysqld crashes when innodb_log_file_size is set > 4G" #15308: "Problem of Order with Enum Column in Primary Key" #15550: "mysqld crashes in printing a FOREIGN KEY error in InnoDB" row_ins_foreign_report_add_err(): When printing the parent record, use the index in the parent table rather than the index in the child table. #15653: "Slow inserts to InnoDB if many thousands of .ibd files" Keep track on unflushed modifications to file spaces. When there are tens of thousands of file spaces, flushing all files in fil_flush_file_spaces() would be very slow. fil_flush_file_spaces(): Only flush unflushed file spaces. fil_space_t, fil_system_t: Add a list of unflushed spaces. #15991: "innodb-file-per-table + symlink database + rename = cr" os_file_handle_error(): Map the error codes EXDEV, ENOTDIR, and EISDIR to the new code OS_FILE_PATH_ERROR. Treat this code as OS_FILE_PATH_ERROR. This fixes the crash on RENAME TABLE when the .ibd file is a symbolic link to a different file system. #16157: "InnoDB crashes when main location settings are empty" This patch is from Heikki. #16298: "InnoDB segfaults in INSERTs in upgrade of 4.0 -> 5.0 tables with VARCHAR BINARY" dict_load_columns(): Set the charset-collation code DATA_MYSQL_BINARY_CHARSET_COLL for those binary string columns that lack a charset-collation code, i.e., the tables were created with an older version of MySQL/InnoDB than 4.1.2. #16229: "MySQL/InnoDB uses full explicit table locks in trigger processing" Take a InnoDB table lock only if user has explicitly requested a table lock. Added some additional comments to store_lock() and external_lock(). #16387: "InnoDB crash when dropping a foreign key <table>_ibfk_0" Do not mistake TABLENAME_ibfk_0 for auto-generated id. dict_table_get_highest_foreign_id(): Ignore foreign constraint identifiers starting with the pattern TABLENAME_ibfk_0. #16582: "InnoDB: Error in an adaptive hash index pointer to page" Account for a race condition when dropping the adaptive hash index for a B-tree page. btr_search_drop_page_hash_index(): Retry the operation if a hash index with different parameters was built meanwhile. Add diagnostics for the case that hash node pointers to the page remain. btr_search_info_update_hash(), btr_search_info_update_slow(): Document the parameter "info" as in/out. #16814: "SHOW INNODB STATUS format error in LATEST FOREIGN KEY ERROR section" Add a missing newline to the LAST FOREIGN KEY ERROR section in SHOW INNODB STATUS output. dict_foreign_error_report(): Always print a newline after invoking dict_print_info_on_foreign_key_in_create_format(). #16827: "Better InnoDB error message if ibdata files omitted from my.cnf" #17126: "CHECK TABLE on InnoDB causes a short hang during check of adaptive hash" CHECK TABLE blocking other queries, by releasing the btr_search_latch periodically during the adaptive hash table validation. #17405: "Valgrind: conditional jump or move depends on unititialised values" buf_block_init(): Reset magic_n, buf_fix_count and io_fix to avoid testing uninitialized variables.
344 lines
12 KiB
C
344 lines
12 KiB
C
/******************************************************
|
|
Mini-transaction buffer
|
|
|
|
(c) 1995 Innobase Oy
|
|
|
|
Created 11/26/1995 Heikki Tuuri
|
|
*******************************************************/
|
|
|
|
#ifndef mtr0mtr_h
|
|
#define mtr0mtr_h
|
|
|
|
#include "univ.i"
|
|
#include "mem0mem.h"
|
|
#include "dyn0dyn.h"
|
|
#include "buf0types.h"
|
|
#include "sync0rw.h"
|
|
#include "ut0byte.h"
|
|
#include "mtr0types.h"
|
|
#include "page0types.h"
|
|
|
|
/* Logging modes for a mini-transaction */
|
|
#define MTR_LOG_ALL 21 /* default mode: log all operations
|
|
modifying disk-based data */
|
|
#define MTR_LOG_NONE 22 /* log no operations */
|
|
/*#define MTR_LOG_SPACE 23 */ /* log only operations modifying
|
|
file space page allocation data
|
|
(operations in fsp0fsp.* ) */
|
|
#define MTR_LOG_SHORT_INSERTS 24 /* inserts are logged in a shorter
|
|
form */
|
|
|
|
/* Types for the mlock objects to store in the mtr memo; NOTE that the
|
|
first 3 values must be RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */
|
|
#define MTR_MEMO_PAGE_S_FIX RW_S_LATCH
|
|
#define MTR_MEMO_PAGE_X_FIX RW_X_LATCH
|
|
#define MTR_MEMO_BUF_FIX RW_NO_LATCH
|
|
#define MTR_MEMO_MODIFY 54
|
|
#define MTR_MEMO_S_LOCK 55
|
|
#define MTR_MEMO_X_LOCK 56
|
|
|
|
/* Log item types: we have made them to be of the type 'byte'
|
|
for the compiler to warn if val and type parameters are switched
|
|
in a call to mlog_write_ulint. NOTE! For 1 - 8 bytes, the
|
|
flag value must give the length also! */
|
|
#define MLOG_SINGLE_REC_FLAG 128 /* if the mtr contains only
|
|
one log record for one page,
|
|
i.e., write_initial_log_record
|
|
has been called only once,
|
|
this flag is ORed to the type
|
|
of that first log record */
|
|
#define MLOG_1BYTE (1) /* one byte is written */
|
|
#define MLOG_2BYTES (2) /* 2 bytes ... */
|
|
#define MLOG_4BYTES (4) /* 4 bytes ... */
|
|
#define MLOG_8BYTES (8) /* 8 bytes ... */
|
|
#define MLOG_REC_INSERT ((byte)9) /* record insert */
|
|
#define MLOG_REC_CLUST_DELETE_MARK ((byte)10) /* mark clustered index record
|
|
deleted */
|
|
#define MLOG_REC_SEC_DELETE_MARK ((byte)11) /* mark secondary index record
|
|
deleted */
|
|
#define MLOG_REC_UPDATE_IN_PLACE ((byte)13) /* update of a record,
|
|
preserves record field sizes */
|
|
#define MLOG_REC_DELETE ((byte)14) /* delete a record from a
|
|
page */
|
|
#define MLOG_LIST_END_DELETE ((byte)15) /* delete record list end on
|
|
index page */
|
|
#define MLOG_LIST_START_DELETE ((byte)16) /* delete record list start on
|
|
index page */
|
|
#define MLOG_LIST_END_COPY_CREATED ((byte)17) /* copy record list end to a
|
|
new created index page */
|
|
#define MLOG_PAGE_REORGANIZE ((byte)18) /* reorganize an index page */
|
|
#define MLOG_PAGE_CREATE ((byte)19) /* create an index page */
|
|
#define MLOG_UNDO_INSERT ((byte)20) /* insert entry in an undo
|
|
log */
|
|
#define MLOG_UNDO_ERASE_END ((byte)21) /* erase an undo log page end */
|
|
#define MLOG_UNDO_INIT ((byte)22) /* initialize a page in an
|
|
undo log */
|
|
#define MLOG_UNDO_HDR_DISCARD ((byte)23) /* discard an update undo log
|
|
header */
|
|
#define MLOG_UNDO_HDR_REUSE ((byte)24) /* reuse an insert undo log
|
|
header */
|
|
#define MLOG_UNDO_HDR_CREATE ((byte)25) /* create an undo log header */
|
|
#define MLOG_REC_MIN_MARK ((byte)26) /* mark an index record as the
|
|
predefined minimum record */
|
|
#define MLOG_IBUF_BITMAP_INIT ((byte)27) /* initialize an ibuf bitmap
|
|
page */
|
|
/*#define MLOG_FULL_PAGE ((byte)28) full contents of a page */
|
|
#define MLOG_INIT_FILE_PAGE ((byte)29) /* this means that a file page
|
|
is taken into use and the prior
|
|
contents of the page should be
|
|
ignored: in recovery we must
|
|
not trust the lsn values stored
|
|
to the file page */
|
|
#define MLOG_WRITE_STRING ((byte)30) /* write a string to a page */
|
|
#define MLOG_MULTI_REC_END ((byte)31) /* if a single mtr writes
|
|
log records for several pages,
|
|
this log record ends the
|
|
sequence of these records */
|
|
#define MLOG_DUMMY_RECORD ((byte)32) /* dummy log record used to
|
|
pad a log block full */
|
|
#define MLOG_FILE_CREATE ((byte)33) /* log record about an .ibd
|
|
file creation */
|
|
#define MLOG_FILE_RENAME ((byte)34) /* log record about an .ibd
|
|
file rename */
|
|
#define MLOG_FILE_DELETE ((byte)35) /* log record about an .ibd
|
|
file deletion */
|
|
#define MLOG_COMP_REC_MIN_MARK ((byte)36) /* mark a compact index record
|
|
as the predefined minimum
|
|
record */
|
|
#define MLOG_COMP_PAGE_CREATE ((byte)37) /* create a compact
|
|
index page */
|
|
#define MLOG_COMP_REC_INSERT ((byte)38) /* compact record insert */
|
|
#define MLOG_COMP_REC_CLUST_DELETE_MARK ((byte)39)
|
|
/* mark compact clustered index
|
|
record deleted */
|
|
#define MLOG_COMP_REC_SEC_DELETE_MARK ((byte)40)/* mark compact secondary index
|
|
record deleted; this log
|
|
record type is redundant, as
|
|
MLOG_REC_SEC_DELETE_MARK is
|
|
independent of the record
|
|
format. */
|
|
#define MLOG_COMP_REC_UPDATE_IN_PLACE ((byte)41)/* update of a compact record,
|
|
preserves record field sizes */
|
|
#define MLOG_COMP_REC_DELETE ((byte)42) /* delete a compact record
|
|
from a page */
|
|
#define MLOG_COMP_LIST_END_DELETE ((byte)43) /* delete compact record list
|
|
end on index page */
|
|
#define MLOG_COMP_LIST_START_DELETE ((byte)44) /* delete compact record list
|
|
start on index page */
|
|
#define MLOG_COMP_LIST_END_COPY_CREATED ((byte)45)
|
|
/* copy compact record list end
|
|
to a new created index page */
|
|
#define MLOG_COMP_PAGE_REORGANIZE ((byte)46) /* reorganize an index page */
|
|
|
|
#define MLOG_BIGGEST_TYPE ((byte)46) /* biggest value (used in
|
|
asserts) */
|
|
|
|
/*******************************************************************
|
|
Starts a mini-transaction and creates a mini-transaction handle
|
|
and buffer in the memory buffer given by the caller. */
|
|
UNIV_INLINE
|
|
mtr_t*
|
|
mtr_start(
|
|
/*======*/
|
|
/* out: mtr buffer which also acts as
|
|
the mtr handle */
|
|
mtr_t* mtr); /* in: memory buffer for the mtr buffer */
|
|
/*******************************************************************
|
|
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 */
|
|
/*******************************************************************
|
|
Commits a mini-transaction. */
|
|
|
|
void
|
|
mtr_commit(
|
|
/*=======*/
|
|
mtr_t* mtr); /* in: mini-transaction */
|
|
/**************************************************************
|
|
Sets and returns a savepoint in mtr. */
|
|
UNIV_INLINE
|
|
ulint
|
|
mtr_set_savepoint(
|
|
/*==============*/
|
|
/* out: savepoint */
|
|
mtr_t* mtr); /* in: mtr */
|
|
/**************************************************************
|
|
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 */
|
|
/**************************************************************
|
|
Releases the (index tree) s-latch stored in an mtr memo after a
|
|
savepoint. */
|
|
UNIV_INLINE
|
|
void
|
|
mtr_release_s_latch_at_savepoint(
|
|
/*=============================*/
|
|
mtr_t* mtr, /* in: mtr */
|
|
ulint savepoint, /* in: savepoint */
|
|
rw_lock_t* lock); /* in: latch to release */
|
|
/*******************************************************************
|
|
Gets the logging mode of a mini-transaction. */
|
|
UNIV_INLINE
|
|
ulint
|
|
mtr_get_log_mode(
|
|
/*=============*/
|
|
/* out: logging mode: MTR_LOG_NONE, ... */
|
|
mtr_t* mtr); /* in: mtr */
|
|
/*******************************************************************
|
|
Changes the logging mode of a mini-transaction. */
|
|
UNIV_INLINE
|
|
ulint
|
|
mtr_set_log_mode(
|
|
/*=============*/
|
|
/* out: old mode */
|
|
mtr_t* mtr, /* in: mtr */
|
|
ulint mode); /* in: logging mode: MTR_LOG_NONE, ... */
|
|
/************************************************************
|
|
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); /* in: mini-transaction handle */
|
|
/************************************************************
|
|
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); /* in: mini-transaction handle */
|
|
/*************************************************************************
|
|
This macro locks an rw-lock in s-mode. */
|
|
#define mtr_s_lock(B, MTR) mtr_s_lock_func((B), __FILE__, __LINE__,\
|
|
(MTR))
|
|
/*************************************************************************
|
|
This macro locks an rw-lock in x-mode. */
|
|
#define mtr_x_lock(B, MTR) mtr_x_lock_func((B), __FILE__, __LINE__,\
|
|
(MTR))
|
|
/*************************************************************************
|
|
NOTE! Use the macro above!
|
|
Locks a lock in s-mode. */
|
|
UNIV_INLINE
|
|
void
|
|
mtr_s_lock_func(
|
|
/*============*/
|
|
rw_lock_t* lock, /* in: rw-lock */
|
|
const char* file, /* in: file name */
|
|
ulint line, /* in: line number */
|
|
mtr_t* mtr); /* in: mtr */
|
|
/*************************************************************************
|
|
NOTE! Use the macro above!
|
|
Locks a lock in x-mode. */
|
|
UNIV_INLINE
|
|
void
|
|
mtr_x_lock_func(
|
|
/*============*/
|
|
rw_lock_t* lock, /* in: rw-lock */
|
|
const char* file, /* in: file name */
|
|
ulint line, /* in: line number */
|
|
mtr_t* mtr); /* in: mtr */
|
|
|
|
/*******************************************************
|
|
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, ... */
|
|
/**************************************************************
|
|
Checks if memo contains the given item. */
|
|
UNIV_INLINE
|
|
ibool
|
|
mtr_memo_contains(
|
|
/*==============*/
|
|
/* out: TRUE if contains */
|
|
mtr_t* mtr, /* in: mtr */
|
|
void* object, /* in: object to search */
|
|
ulint type); /* in: type of object */
|
|
/*************************************************************
|
|
Prints info of an mtr handle. */
|
|
|
|
void
|
|
mtr_print(
|
|
/*======*/
|
|
mtr_t* mtr); /* in: mtr */
|
|
/*######################################################################*/
|
|
|
|
#define MTR_BUF_MEMO_SIZE 200 /* number of slots in memo */
|
|
|
|
/*******************************************************************
|
|
Returns the log object of a mini-transaction buffer. */
|
|
UNIV_INLINE
|
|
dyn_array_t*
|
|
mtr_get_log(
|
|
/*========*/
|
|
/* out: log */
|
|
mtr_t* mtr); /* in: mini-transaction */
|
|
/*******************************************************
|
|
Pushes an object to an mtr memo stack. */
|
|
UNIV_INLINE
|
|
void
|
|
mtr_memo_push(
|
|
/*==========*/
|
|
mtr_t* mtr, /* in: mtr */
|
|
void* object, /* in: object */
|
|
ulint type); /* in: object type: MTR_MEMO_S_LOCK, ... */
|
|
|
|
|
|
/* Type definition of a mini-transaction memo stack slot. */
|
|
typedef struct mtr_memo_slot_struct mtr_memo_slot_t;
|
|
struct mtr_memo_slot_struct{
|
|
ulint type; /* type of the stored object (MTR_MEMO_S_LOCK, ...) */
|
|
void* object; /* pointer to the object */
|
|
};
|
|
|
|
/* Mini-transaction handle and buffer */
|
|
struct mtr_struct{
|
|
ulint state; /* MTR_ACTIVE, MTR_COMMITTING, MTR_COMMITTED */
|
|
dyn_array_t memo; /* memo stack for locks etc. */
|
|
dyn_array_t log; /* mini-transaction log */
|
|
ibool modifications;
|
|
/* TRUE if the mtr made modifications to
|
|
buffer pool pages */
|
|
ulint n_log_recs;
|
|
/* count of how many page initial log records
|
|
have been written to the mtr log */
|
|
ulint log_mode; /* specifies which operations should be
|
|
logged; default value MTR_LOG_ALL */
|
|
dulint start_lsn;/* start lsn of the possible log entry for
|
|
this mtr */
|
|
dulint end_lsn;/* end lsn of the possible log entry for
|
|
this mtr */
|
|
ulint magic_n;
|
|
};
|
|
|
|
#define MTR_MAGIC_N 54551
|
|
|
|
#define MTR_ACTIVE 12231
|
|
#define MTR_COMMITTING 56456
|
|
#define MTR_COMMITTED 34676
|
|
|
|
#ifndef UNIV_NONINL
|
|
#include "mtr0mtr.ic"
|
|
#endif
|
|
|
|
#endif
|