mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
updated with changes from Percona-Server-5.1.47-11.2
This commit is contained in:
parent
3e4d2be619
commit
0c6afe17dc
152 changed files with 10152 additions and 2307 deletions
|
@ -29,9 +29,9 @@ IF (CMAKE_SIZEOF_VOID_P MATCHES 8)
|
|||
SET(WIN64 TRUE)
|
||||
ENDIF (CMAKE_SIZEOF_VOID_P MATCHES 8)
|
||||
|
||||
# Include directories under innobase
|
||||
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/storage/innobase/include
|
||||
${CMAKE_SOURCE_DIR}/storage/innobase/handler)
|
||||
# Include directories under innodb_plugin
|
||||
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/storage/innodb_plugin/include
|
||||
${CMAKE_SOURCE_DIR}/storage/innodb_plugin/handler)
|
||||
|
||||
# Include directories under mysql
|
||||
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
|
||||
|
@ -47,7 +47,7 @@ IF (MSVC AND $(WIN64))
|
|||
PROPERTIES COMPILE_FLAGS -Od)
|
||||
ENDIF (MSVC AND $(WIN64))
|
||||
|
||||
SET(INNOBASE_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c
|
||||
SET(INNODB_PLUGIN_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c
|
||||
buf/buf0buddy.c buf/buf0buf.c buf/buf0flu.c buf/buf0lru.c buf/buf0rea.c
|
||||
data/data0data.c data/data0type.c
|
||||
dict/dict0boot.c dict/dict0crea.c dict/dict0dict.c dict/dict0load.c dict/dict0mem.c
|
||||
|
@ -78,22 +78,11 @@ SET(INNOBASE_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c
|
|||
trx/trx0i_s.c trx/trx0purge.c trx/trx0rec.c trx/trx0roll.c trx/trx0rseg.c
|
||||
trx/trx0sys.c trx/trx0trx.c trx/trx0undo.c
|
||||
usr/usr0sess.c
|
||||
ut/ut0byte.c ut/ut0dbg.c ut/ut0mem.c ut/ut0rnd.c ut/ut0ut.c ut/ut0vec.c
|
||||
ut/ut0byte.c ut/ut0dbg.c ut/ut0mem.c ut/ut0rbt.c ut/ut0rnd.c ut/ut0ut.c ut/ut0vec.c
|
||||
ut/ut0list.c ut/ut0wqueue.c)
|
||||
ADD_DEFINITIONS(-DHAVE_WINDOWS_ATOMICS -DIB_HAVE_PAUSE_INSTRUCTION)
|
||||
# Windows atomics do not perform well. Disable Windows atomics by default.
|
||||
# See bug#52102 for details.
|
||||
#ADD_DEFINITIONS(-DHAVE_WINDOWS_ATOMICS -DINNODB_RW_LOCKS_USE_ATOMICS -DHAVE_IB_PAUSE_INSTRUCTION)
|
||||
ADD_DEFINITIONS(-DHAVE_IB_PAUSE_INSTRUCTION)
|
||||
|
||||
IF (MYSQL_VERSION_ID GREATER "50137")
|
||||
MYSQL_STORAGE_ENGINE(INNOBASE)
|
||||
# Use ha_innodb for plugin name, if plugin is built
|
||||
GET_TARGET_PROPERTY(LIB_LOCATION ha_innobase LOCATION)
|
||||
IF(LIB_LOCATION)
|
||||
SET_TARGET_PROPERTIES(ha_innobase PROPERTIES OUTPUT_NAME ha_innodb)
|
||||
ENDIF(LIB_LOCATION)
|
||||
ELSE (MYSQL_VERSION_ID GREATER "50137")
|
||||
IF (NOT SOURCE_SUBLIBS)
|
||||
ADD_DEFINITIONS(-D_WIN32 -DMYSQL_SERVER)
|
||||
ADD_LIBRARY(innobase STATIC ${INNOBASE_SOURCES})
|
||||
# Require mysqld_error.h, which is built as part of the GenError
|
||||
ADD_DEPENDENCIES(innobase GenError)
|
||||
ENDIF (NOT SOURCE_SUBLIBS)
|
||||
ENDIF (MYSQL_VERSION_ID GREATER "50137")
|
||||
MYSQL_STORAGE_ENGINE(INNODB_PLUGIN)
|
||||
|
|
271
ChangeLog
271
ChangeLog
|
@ -1,3 +1,262 @@
|
|||
2010-05-03 The InnoDB Team
|
||||
|
||||
* buf0buf.c:
|
||||
Fix Bug#53248 compressed tables page checksum mismatch after
|
||||
re-enabling innodb_checksums
|
||||
|
||||
2010-04-28 The InnoDB Team
|
||||
|
||||
* log/log0recv.h, log/log0recv.c:
|
||||
Fix Bug#53122 InnoDB recovery uses too big a hash table for redo
|
||||
log records
|
||||
|
||||
2010-04-27 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc, lock/lock0lock.c, row/row0mysql.c,
|
||||
row/row0sel.c:
|
||||
Fix Bug#48607 READ UNCOMMITTED uses more locks than READ COMMITTED
|
||||
in InnoDB 5.1+
|
||||
|
||||
2010-04-26 The InnoDB Team
|
||||
|
||||
* row/row0sel.c:
|
||||
Fix Bug#52663 Lost update incrementing column value under
|
||||
READ COMMITTED isolation level
|
||||
|
||||
2010-04-22 The InnoDB Team
|
||||
|
||||
* include/dict0boot.h, dict/dict0boot.c:
|
||||
Fix a bug that prevented the crash recovery of fast CREATE INDEX
|
||||
from dropping partially created indexes.
|
||||
|
||||
2010-04-21 The InnoDB Team
|
||||
|
||||
* btr/btr0btr.c:
|
||||
Fix Bug#52964 Infinite loop in btr_page_split_and_insert()
|
||||
in ROW_FORMAT=COMPRESSED
|
||||
|
||||
2010-04-21 The InnoDB Team
|
||||
|
||||
* data/data0data.c:
|
||||
Fix Bug#52745 Failing assertion: blob_no < page_zip->n_blobs
|
||||
|
||||
2010-04-20 The InnoDB Team
|
||||
|
||||
* dict/dict0crea.c, handler/ha_innodb.cc, include/trx0trx.h:
|
||||
Fix Bug#50495 'Row size too large' for plugin, but works for
|
||||
built-in InnoDB
|
||||
Only check the record size at index creation time when
|
||||
innodb_strict_mode is set or when ROW_FORMAT is DYNAMIC or COMPRESSED.
|
||||
|
||||
2010-04-20 The InnoDB Team
|
||||
|
||||
* btr/btr0btr.c, include/univ.i:
|
||||
Implement UNIV_BTR_AVOID_COPY, for avoiding writes when a B-tree
|
||||
node is split at the first or last record.
|
||||
|
||||
2010-04-15 The InnoDB Team
|
||||
|
||||
* trx/trx0rec.c:
|
||||
Fix Bug#52746 InnoDB purge thread crashed with table containing
|
||||
prefix indexed blobs
|
||||
|
||||
2010-03-31 The InnoDB Team
|
||||
|
||||
* mysql-test/innodb_bug51920.test, mysql-test/innodb_bug51920.result,
|
||||
srv/srv0srv.c:
|
||||
Fix Bug#51920 InnoDB connections in row lock wait ignore KILL
|
||||
until lock wait timeout
|
||||
|
||||
2010-03-31 The InnoDB Team
|
||||
|
||||
* mysql-test/innodb_bug38231.test:
|
||||
Remove non-determinism in the test case.
|
||||
|
||||
2010-03-18 The InnoDB Team
|
||||
|
||||
* CMakeLists.txt:
|
||||
Fix Bug#52102 InnoDB Plugin shows performance drop compared to
|
||||
InnoDB (Windows)
|
||||
|
||||
2010-03-18 The InnoDB Team
|
||||
|
||||
* buf0buf.ic:
|
||||
When comparing the time of the first access to a block against
|
||||
innodb_old_blocks_time, use 32-bit arithmetics. The comparison was
|
||||
incorrect on 64-bit systems.
|
||||
|
||||
2010-03-11 The InnoDB Team
|
||||
|
||||
* buf0buf.h, buf0buf.ic:
|
||||
Fix and clarify the latching of some buf_block_t members.
|
||||
Note that check_index_page_at_flush is not protected by any mutex.
|
||||
Note and assert that lock_hash_val is protected by the rw-latch.
|
||||
|
||||
2010-03-10 The InnoDB Team
|
||||
|
||||
* trx/trx0sys.c:
|
||||
Fix Bug#51653 outdated reference to set-variable
|
||||
|
||||
2010-03-10 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc, mysql-test/innodb_bug21704.result,
|
||||
mysql-test/innodb_bug47621.result, mysql-test/innodb_bug47621.test:
|
||||
Fix Bug#47621 MySQL and InnoDB data dictionaries will become out of
|
||||
sync when renaming columns
|
||||
|
||||
2010-03-10 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc:
|
||||
Fix Bug#51356 Many Valgrind errors in error messages
|
||||
with concurrent DDL
|
||||
|
||||
2010-03-10 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc, handler/handler0alter.cc,
|
||||
mysql-test/innodb_bug51378.result, mysql-test/innodb_bug51378.test:
|
||||
Fix Bug#51378 Init 'ref_length' to correct value, in case an out
|
||||
of bound MySQL primary_key
|
||||
|
||||
2010-03-10 The InnoDB Team
|
||||
|
||||
* log/log0recv.c:
|
||||
Remove a bogus assertion about page numbers exceeding 0x90000000
|
||||
in the redo log. Abort when encountering a corrupted redo log
|
||||
record, unless innodb_force_recovery is set.
|
||||
|
||||
2010-03-09 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc:
|
||||
Make SHOW ENGINE INNODB MUTEX STATUS display SUM(os_waits)
|
||||
for the buffer pool block mutexes and locks.
|
||||
|
||||
2010-03-08 The InnoDB Team
|
||||
|
||||
* fil/fil0fil.c:
|
||||
Fix ALTER TABLE ... IMPORT TABLESPACE of compressed tables.
|
||||
|
||||
2010-03-03 The InnoDB Team
|
||||
|
||||
* handler/handler0alter.cc, innodb-index.result, innodb-index.test,
|
||||
innodb.result, innodb.test:
|
||||
Disallow a duplicate index name when creating an index.
|
||||
|
||||
2010-02-11 The InnoDB Team
|
||||
|
||||
* include/mem0mem.h, include/mem0mem.ic, mem/mem0mem.c:
|
||||
Fix Bug#49535 Available memory check slows down crash
|
||||
recovery tens of times
|
||||
|
||||
2010-02-09 The InnoDB Team
|
||||
|
||||
* buf/buf0buf.c:
|
||||
Fix Bug#38901 InnoDB logs error repeatedly when trying to load
|
||||
page into buffer pool
|
||||
|
||||
2010-02-09 The InnoDB Team
|
||||
|
||||
* srv/srv0srv.c:
|
||||
Let the master thread sleep if the amount of work to be done is
|
||||
calibrated as taking less than a second.
|
||||
|
||||
2010-02-04 The InnoDB Team
|
||||
|
||||
* btr/btr0btr.c, btr/btr0cur.c, btr/btr0pcur.c, buf/buf0buf.c,
|
||||
include/btr0btr.h, include/btr0cur.h, include/btr0pcur.h,
|
||||
include/btr0pcur.ic, include/buf0buf.h, row/row0ins.c, row/row0sel.c:
|
||||
Pass the file name and line number of the caller of the
|
||||
b-tree cursor functions to the buffer pool requests, in order
|
||||
to make the latch diagnostics more accurate.
|
||||
|
||||
2010-02-03 The InnoDB Team
|
||||
|
||||
* lock/lock0lock.c:
|
||||
Fix Bug#49001 SHOW INNODB STATUS deadlock info incorrect
|
||||
when deadlock detection aborts
|
||||
|
||||
2010-02-03 The InnoDB Team
|
||||
|
||||
* buf/buf0lru.c:
|
||||
Fix Bug#35077 Very slow DROP TABLE (ALTER TABLE, OPTIMIZE TABLE)
|
||||
on compressed tables
|
||||
|
||||
2010-02-03 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc, include/row0mysql.h, row/row0mysql.c:
|
||||
Clean up CHECK TABLE error handling.
|
||||
|
||||
2010-02-01 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc, mysql-test/innodb-autoinc.test,
|
||||
mysql-test/innodb-autoinc.result,
|
||||
mysql-test/innodb-autoinc-44030.test,
|
||||
mysql-test/innodb-autoinc-44030.result:
|
||||
Fix Bug#49497 Error 1467 (ER_AUTOINC_READ_FAILED) on inserting
|
||||
a negative value
|
||||
|
||||
2010-01-27 The InnoDB Team
|
||||
|
||||
* include/row0mysql.h, log/log0recv.c, row/row0mysql.c:
|
||||
Drop temporary tables at startup.
|
||||
This addresses the third aspect of
|
||||
Bug#41609 Crash recovery does not work for InnoDB temporary tables.
|
||||
|
||||
2010-01-21 The InnoDB Team
|
||||
|
||||
* buf/buf0buf.c:
|
||||
Do not merge buffered inserts to compressed pages before
|
||||
the redo log has been applied in crash recovery.
|
||||
|
||||
2010-01-13 The InnoDB Team
|
||||
|
||||
* row/row0sel.c:
|
||||
On the READ UNCOMMITTED isolation level, do not attempt to access
|
||||
a clustered index record that has been marked for deletion. The
|
||||
built-in InnoDB in MySQL 5.1 and earlier would attempt to retrieve
|
||||
a previous version of the record in this case.
|
||||
|
||||
2010-01-13 The InnoDB Team
|
||||
|
||||
* buf/buf0buf.c:
|
||||
When disabling the adaptive hash index, check the block state
|
||||
before checking block->is_hashed, because the latter may be
|
||||
uninitialized right after server startup.
|
||||
|
||||
2010-01-12 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc, handler/ha_innodb.h:
|
||||
Fix Bug#46193 crash when accessing tables after enabling
|
||||
innodb_force_recovery option
|
||||
|
||||
2010-01-12 The InnoDB Team
|
||||
|
||||
* row/row0mysql.c:
|
||||
Fix Bug#49238 Creating/Dropping a temporary table while at 1023
|
||||
transactions will cause assert.
|
||||
|
||||
2009-12-02 The InnoDB Team
|
||||
|
||||
* srv/srv0start.c:
|
||||
Display the zlib version number at startup.
|
||||
InnoDB compressed tables use zlib, and the implementation depends
|
||||
on the zlib function compressBound(), whose definition was slightly
|
||||
changed in zlib version 1.2.3.1 in 2006. MySQL bundles zlib 1.2.3
|
||||
from 2005, but some installations use a more recent zlib.
|
||||
|
||||
2009-11-30 The InnoDB Team
|
||||
|
||||
* dict/dict0crea.c, dict/dict0mem.c, dict/dict0load.c,
|
||||
dict/dict0boot.c, fil/fil0fil.c, handler/ha_innodb.cc,
|
||||
include/dict0mem.h, row/row0mysql.c:
|
||||
Fix the bogus warning messages for non-existing temporary
|
||||
tables that were reported in
|
||||
Bug#41609 Crash recovery does not work for InnoDB temporary tables.
|
||||
The actual crash recovery bug was corrected on 2009-04-29.
|
||||
|
||||
2009-11-27 The InnoDB Team
|
||||
|
||||
InnoDB Plugin 1.0.6 released
|
||||
|
||||
2009-11-20 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc:
|
||||
|
@ -79,8 +338,8 @@
|
|||
sync/sync0arr.c, sync/sync0sync.c, thr/thr0loc.c, trx/trx0i_s.c,
|
||||
trx/trx0purge.c, trx/trx0rseg.c, trx/trx0sys.c, trx/trx0undo.c,
|
||||
usr/usr0sess.c, ut/ut0mem.c:
|
||||
Fix Bug #45992 innodb memory not freed after shutdown
|
||||
Fix Bug #46656 InnoDB plugin: memory leaks (Valgrind)
|
||||
Fix Bug#45992 innodb memory not freed after shutdown
|
||||
Fix Bug#46656 InnoDB plugin: memory leaks (Valgrind)
|
||||
|
||||
2009-10-29 The InnoDB Team
|
||||
|
||||
|
@ -422,7 +681,7 @@
|
|||
* dict/dict0dict.c:
|
||||
When an index column cannot be found in the table during index
|
||||
creation, display additional diagnostic before an assertion failure.
|
||||
This does NOT fix Bug #44571 InnoDB Plugin crashes on ADD INDEX,
|
||||
This does NOT fix Bug#44571 InnoDB Plugin crashes on ADD INDEX,
|
||||
but it helps understand the reason of the crash.
|
||||
|
||||
2009-06-17 The InnoDB Team
|
||||
|
@ -535,6 +794,12 @@
|
|||
Fix Bug#44320 InnoDB: missing DB_ROLL_PTR in Table Monitor COLUMNS
|
||||
output
|
||||
|
||||
2009-04-29 The InnoDB Team
|
||||
|
||||
* fil/fil0fil.c, include/fil0fil.h, include/mtr0mtr.h,
|
||||
log/log0recv.c:
|
||||
Fix Bug#41609 Crash recovery does not work for InnoDB temporary tables
|
||||
|
||||
2009-04-23 The InnoDB Team
|
||||
|
||||
* row/row0mysql.c:
|
||||
|
|
16
Makefile.am
16
Makefile.am
|
@ -217,6 +217,7 @@ noinst_HEADERS= \
|
|||
include/ut0lst.h \
|
||||
include/ut0mem.h \
|
||||
include/ut0mem.ic \
|
||||
include/ut0rbt.h \
|
||||
include/ut0rnd.h \
|
||||
include/ut0rnd.ic \
|
||||
include/ut0sort.h \
|
||||
|
@ -229,7 +230,7 @@ noinst_HEADERS= \
|
|||
mem/mem0dbg.c
|
||||
|
||||
EXTRA_LIBRARIES= libinnobase.a
|
||||
noinst_LIBRARIES= @plugin_innobase_static_target@
|
||||
noinst_LIBRARIES= @plugin_innodb_plugin_static_target@
|
||||
libinnobase_a_SOURCES= \
|
||||
btr/btr0btr.c \
|
||||
btr/btr0cur.c \
|
||||
|
@ -319,6 +320,7 @@ libinnobase_a_SOURCES= \
|
|||
ut/ut0dbg.c \
|
||||
ut/ut0list.c \
|
||||
ut/ut0mem.c \
|
||||
ut/ut0rbt.c \
|
||||
ut/ut0rnd.c \
|
||||
ut/ut0ut.c \
|
||||
ut/ut0vec.c \
|
||||
|
@ -327,13 +329,13 @@ libinnobase_a_SOURCES= \
|
|||
libinnobase_a_CXXFLAGS= $(AM_CFLAGS)
|
||||
libinnobase_a_CFLAGS= $(AM_CFLAGS)
|
||||
|
||||
EXTRA_LTLIBRARIES= ha_innodb.la
|
||||
pkgplugin_LTLIBRARIES= @plugin_innobase_shared_target@
|
||||
EXTRA_LTLIBRARIES= ha_innodb_plugin.la
|
||||
pkgplugin_LTLIBRARIES= @plugin_innodb_plugin_shared_target@
|
||||
|
||||
ha_innodb_la_LDFLAGS= -module -rpath $(pkgplugindir)
|
||||
ha_innodb_la_CXXFLAGS= $(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS)
|
||||
ha_innodb_la_CFLAGS= $(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS)
|
||||
ha_innodb_la_SOURCES= $(libinnobase_a_SOURCES)
|
||||
ha_innodb_plugin_la_LDFLAGS= -module -rpath $(pkgplugindir)
|
||||
ha_innodb_plugin_la_CXXFLAGS= $(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS)
|
||||
ha_innodb_plugin_la_CFLAGS= $(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS)
|
||||
ha_innodb_plugin_la_SOURCES= $(libinnobase_a_SOURCES)
|
||||
|
||||
EXTRA_DIST= CMakeLists.txt plug.in \
|
||||
pars/make_bison.sh pars/make_flex.sh \
|
||||
|
|
1315
Makefile.in
1315
Makefile.in
File diff suppressed because it is too large
Load diff
139
btr/btr0btr.c
139
btr/btr0btr.c
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1994, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -604,13 +604,15 @@ an x-latch on the tree.
|
|||
@return rec_get_offsets() of the node pointer record */
|
||||
static
|
||||
ulint*
|
||||
btr_page_get_father_node_ptr(
|
||||
/*=========================*/
|
||||
btr_page_get_father_node_ptr_func(
|
||||
/*==============================*/
|
||||
ulint* offsets,/*!< in: work area for the return value */
|
||||
mem_heap_t* heap, /*!< in: memory heap to use */
|
||||
btr_cur_t* cursor, /*!< in: cursor pointing to user record,
|
||||
out: cursor on node pointer record,
|
||||
its page x-latched */
|
||||
const char* file, /*!< in: file name */
|
||||
ulint line, /*!< in: line where called */
|
||||
mtr_t* mtr) /*!< in: mtr */
|
||||
{
|
||||
dtuple_t* tuple;
|
||||
|
@ -634,7 +636,8 @@ btr_page_get_father_node_ptr(
|
|||
tuple = dict_index_build_node_ptr(index, user_rec, 0, heap, level);
|
||||
|
||||
btr_cur_search_to_nth_level(index, level + 1, tuple, PAGE_CUR_LE,
|
||||
BTR_CONT_MODIFY_TREE, cursor, 0, mtr);
|
||||
BTR_CONT_MODIFY_TREE, cursor, 0,
|
||||
file, line, mtr);
|
||||
|
||||
node_ptr = btr_cur_get_rec(cursor);
|
||||
ut_ad(!page_rec_is_comp(node_ptr)
|
||||
|
@ -682,6 +685,9 @@ btr_page_get_father_node_ptr(
|
|||
return(offsets);
|
||||
}
|
||||
|
||||
#define btr_page_get_father_node_ptr(of,heap,cur,mtr) \
|
||||
btr_page_get_father_node_ptr_func(of,heap,cur,__FILE__,__LINE__,mtr)
|
||||
|
||||
/************************************************************//**
|
||||
Returns the upper level node pointer to a page. It is assumed that mtr holds
|
||||
an x-latch on the tree.
|
||||
|
@ -1475,11 +1481,11 @@ Calculates a split record such that the tuple will certainly fit on
|
|||
its half-page when the split is performed. We assume in this function
|
||||
only that the cursor page has at least one user record.
|
||||
@return split record, or NULL if tuple will be the first record on
|
||||
upper half-page */
|
||||
the lower or upper half-page (determined by btr_page_tuple_smaller()) */
|
||||
static
|
||||
rec_t*
|
||||
btr_page_get_sure_split_rec(
|
||||
/*========================*/
|
||||
btr_page_get_split_rec(
|
||||
/*===================*/
|
||||
btr_cur_t* cursor, /*!< in: cursor at which insert should be made */
|
||||
const dtuple_t* tuple, /*!< in: tuple to insert */
|
||||
ulint n_ext) /*!< in: number of externally stored columns */
|
||||
|
@ -1692,11 +1698,13 @@ Inserts a data tuple to a tree on a non-leaf level. It is assumed
|
|||
that mtr holds an x-latch on the tree. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
btr_insert_on_non_leaf_level(
|
||||
/*=========================*/
|
||||
btr_insert_on_non_leaf_level_func(
|
||||
/*==============================*/
|
||||
dict_index_t* index, /*!< in: index */
|
||||
ulint level, /*!< in: level, must be > 0 */
|
||||
dtuple_t* tuple, /*!< in: the record to be inserted */
|
||||
const char* file, /*!< in: file name */
|
||||
ulint line, /*!< in: line where called */
|
||||
mtr_t* mtr) /*!< in: mtr */
|
||||
{
|
||||
big_rec_t* dummy_big_rec;
|
||||
|
@ -1708,7 +1716,7 @@ btr_insert_on_non_leaf_level(
|
|||
|
||||
btr_cur_search_to_nth_level(index, level, tuple, PAGE_CUR_LE,
|
||||
BTR_CONT_MODIFY_TREE,
|
||||
&cursor, 0, mtr);
|
||||
&cursor, 0, file, line, mtr);
|
||||
|
||||
err = btr_cur_pessimistic_insert(BTR_NO_LOCKING_FLAG
|
||||
| BTR_KEEP_SYS_FLAG
|
||||
|
@ -1853,6 +1861,37 @@ btr_attach_half_pages(
|
|||
btr_page_set_next(upper_page, upper_page_zip, next_page_no, mtr);
|
||||
}
|
||||
|
||||
/*************************************************************//**
|
||||
Determine if a tuple is smaller than any record on the page.
|
||||
@return TRUE if smaller */
|
||||
static
|
||||
ibool
|
||||
btr_page_tuple_smaller(
|
||||
/*===================*/
|
||||
btr_cur_t* cursor, /*!< in: b-tree cursor */
|
||||
const dtuple_t* tuple, /*!< in: tuple to consider */
|
||||
ulint* offsets,/*!< in/out: temporary storage */
|
||||
ulint n_uniq, /*!< in: number of unique fields
|
||||
in the index page records */
|
||||
mem_heap_t** heap) /*!< in/out: heap for offsets */
|
||||
{
|
||||
buf_block_t* block;
|
||||
const rec_t* first_rec;
|
||||
page_cur_t pcur;
|
||||
|
||||
/* Read the first user record in the page. */
|
||||
block = btr_cur_get_block(cursor);
|
||||
page_cur_set_before_first(block, &pcur);
|
||||
page_cur_move_to_next(&pcur);
|
||||
first_rec = page_cur_get_rec(&pcur);
|
||||
|
||||
offsets = rec_get_offsets(
|
||||
first_rec, cursor->index, offsets,
|
||||
n_uniq, heap);
|
||||
|
||||
return(cmp_dtuple_rec(tuple, first_rec, offsets) < 0);
|
||||
}
|
||||
|
||||
/*************************************************************//**
|
||||
Splits an index page to halves and inserts the tuple. It is assumed
|
||||
that mtr holds an x-latch to the index tree. NOTE: the tree x-latch is
|
||||
|
@ -1923,12 +1962,17 @@ func_start:
|
|||
/* 1. Decide the split record; split_rec == NULL means that the
|
||||
tuple to be inserted should be the first record on the upper
|
||||
half-page */
|
||||
insert_left = FALSE;
|
||||
|
||||
if (n_iterations > 0) {
|
||||
direction = FSP_UP;
|
||||
hint_page_no = page_no + 1;
|
||||
split_rec = btr_page_get_sure_split_rec(cursor, tuple, n_ext);
|
||||
split_rec = btr_page_get_split_rec(cursor, tuple, n_ext);
|
||||
|
||||
if (UNIV_UNLIKELY(split_rec == NULL)) {
|
||||
insert_left = btr_page_tuple_smaller(
|
||||
cursor, tuple, offsets, n_uniq, &heap);
|
||||
}
|
||||
} else if (btr_page_get_split_rec_to_right(cursor, &split_rec)) {
|
||||
direction = FSP_UP;
|
||||
hint_page_no = page_no + 1;
|
||||
|
@ -1936,37 +1980,24 @@ func_start:
|
|||
} else if (btr_page_get_split_rec_to_left(cursor, &split_rec)) {
|
||||
direction = FSP_DOWN;
|
||||
hint_page_no = page_no - 1;
|
||||
ut_ad(split_rec);
|
||||
} else {
|
||||
direction = FSP_UP;
|
||||
hint_page_no = page_no + 1;
|
||||
|
||||
if (page_get_n_recs(page) == 1) {
|
||||
page_cur_t pcur;
|
||||
/* If there is only one record in the index page, we
|
||||
can't split the node in the middle by default. We need
|
||||
to determine whether the new record will be inserted
|
||||
to the left or right. */
|
||||
|
||||
/* There is only one record in the index page
|
||||
therefore we can't split the node in the middle
|
||||
by default. We need to determine whether the
|
||||
new record will be inserted to the left or right. */
|
||||
|
||||
/* Read the first (and only) record in the page. */
|
||||
page_cur_set_before_first(block, &pcur);
|
||||
page_cur_move_to_next(&pcur);
|
||||
first_rec = page_cur_get_rec(&pcur);
|
||||
|
||||
offsets = rec_get_offsets(
|
||||
first_rec, cursor->index, offsets,
|
||||
n_uniq, &heap);
|
||||
|
||||
/* If the new record is less than the existing record
|
||||
the split in the middle will copy the existing
|
||||
record to the new node. */
|
||||
if (cmp_dtuple_rec(tuple, first_rec, offsets) < 0) {
|
||||
split_rec = page_get_middle_rec(page);
|
||||
} else {
|
||||
split_rec = NULL;
|
||||
}
|
||||
} else {
|
||||
if (page_get_n_recs(page) > 1) {
|
||||
split_rec = page_get_middle_rec(page);
|
||||
} else if (btr_page_tuple_smaller(cursor, tuple,
|
||||
offsets, n_uniq, &heap)) {
|
||||
split_rec = page_rec_get_next(
|
||||
page_get_infimum_rec(page));
|
||||
} else {
|
||||
split_rec = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1996,11 +2027,15 @@ func_start:
|
|||
avoid further splits by inserting the record
|
||||
to an empty page. */
|
||||
split_rec = NULL;
|
||||
goto insert_right;
|
||||
goto insert_empty;
|
||||
}
|
||||
} else if (UNIV_UNLIKELY(insert_left)) {
|
||||
first_rec = page_rec_get_next(page_get_infimum_rec(page));
|
||||
move_limit = page_rec_get_next(btr_cur_get_rec(cursor));
|
||||
} else {
|
||||
insert_right:
|
||||
insert_left = FALSE;
|
||||
insert_empty:
|
||||
ut_ad(!split_rec);
|
||||
ut_ad(!insert_left);
|
||||
buf = mem_alloc(rec_get_converted_size(cursor->index,
|
||||
tuple, n_ext));
|
||||
|
||||
|
@ -2024,7 +2059,11 @@ insert_right:
|
|||
&& btr_page_insert_fits(cursor, split_rec,
|
||||
offsets, tuple, n_ext, heap);
|
||||
} else {
|
||||
mem_free(buf);
|
||||
if (!insert_left) {
|
||||
mem_free(buf);
|
||||
buf = NULL;
|
||||
}
|
||||
|
||||
insert_will_fit = !new_page_zip
|
||||
&& btr_page_insert_fits(cursor, NULL,
|
||||
NULL, tuple, n_ext, heap);
|
||||
|
@ -2037,7 +2076,17 @@ insert_right:
|
|||
}
|
||||
|
||||
/* 5. Move then the records to the new page */
|
||||
if (direction == FSP_DOWN) {
|
||||
if (direction == FSP_DOWN
|
||||
#ifdef UNIV_BTR_AVOID_COPY
|
||||
&& page_rec_is_supremum(move_limit)) {
|
||||
/* Instead of moving all records, make the new page
|
||||
the empty page. */
|
||||
|
||||
left_block = block;
|
||||
right_block = new_block;
|
||||
} else if (direction == FSP_DOWN
|
||||
#endif /* UNIV_BTR_AVOID_COPY */
|
||||
) {
|
||||
/* fputs("Split left\n", stderr); */
|
||||
|
||||
if (0
|
||||
|
@ -2080,6 +2129,14 @@ insert_right:
|
|||
right_block = block;
|
||||
|
||||
lock_update_split_left(right_block, left_block);
|
||||
#ifdef UNIV_BTR_AVOID_COPY
|
||||
} else if (!split_rec) {
|
||||
/* Instead of moving all records, make the new page
|
||||
the empty page. */
|
||||
|
||||
left_block = new_block;
|
||||
right_block = block;
|
||||
#endif /* UNIV_BTR_AVOID_COPY */
|
||||
} else {
|
||||
/* fputs("Split right\n", stderr); */
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1994, 2010, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 2008, Google Inc.
|
||||
|
||||
Portions of this file contain modifications contributed and copyrighted by
|
||||
|
@ -372,6 +372,8 @@ btr_cur_search_to_nth_level(
|
|||
ulint has_search_latch,/*!< in: info on the latch mode the
|
||||
caller currently has on btr_search_latch:
|
||||
RW_S_LATCH, or 0 */
|
||||
const char* file, /*!< in: file name */
|
||||
ulint line, /*!< in: line where called */
|
||||
mtr_t* mtr) /*!< in: mtr */
|
||||
{
|
||||
page_cur_t* page_cursor;
|
||||
|
@ -550,7 +552,7 @@ btr_cur_search_to_nth_level(
|
|||
retry_page_get:
|
||||
block = buf_page_get_gen(space, zip_size, page_no,
|
||||
rw_latch, guess, buf_mode,
|
||||
__FILE__, __LINE__, mtr);
|
||||
file, line, mtr);
|
||||
if (block == NULL) {
|
||||
if (srv_pass_corrupt_table && buf_mode != BUF_GET_IF_IN_POOL) {
|
||||
page_cursor->block = 0;
|
||||
|
@ -727,13 +729,15 @@ func_exit:
|
|||
Opens a cursor at either end of an index. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
btr_cur_open_at_index_side(
|
||||
/*=======================*/
|
||||
btr_cur_open_at_index_side_func(
|
||||
/*============================*/
|
||||
ibool from_left, /*!< in: TRUE if open to the low end,
|
||||
FALSE if to the high end */
|
||||
dict_index_t* index, /*!< in: index */
|
||||
ulint latch_mode, /*!< in: latch mode */
|
||||
btr_cur_t* cursor, /*!< in: cursor */
|
||||
const char* file, /*!< in: file name */
|
||||
ulint line, /*!< in: line where called */
|
||||
mtr_t* mtr) /*!< in: mtr */
|
||||
{
|
||||
page_cur_t* page_cursor;
|
||||
|
@ -778,7 +782,7 @@ btr_cur_open_at_index_side(
|
|||
page_t* page;
|
||||
block = buf_page_get_gen(space, zip_size, page_no,
|
||||
RW_NO_LATCH, NULL, BUF_GET,
|
||||
__FILE__, __LINE__, mtr);
|
||||
file, line, mtr);
|
||||
page = buf_block_get_frame(block);
|
||||
|
||||
if (srv_pass_corrupt_table && !page) {
|
||||
|
@ -869,11 +873,13 @@ btr_cur_open_at_index_side(
|
|||
Positions a cursor at a randomly chosen position within a B-tree. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
btr_cur_open_at_rnd_pos(
|
||||
/*====================*/
|
||||
btr_cur_open_at_rnd_pos_func(
|
||||
/*=========================*/
|
||||
dict_index_t* index, /*!< in: index */
|
||||
ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
|
||||
btr_cur_t* cursor, /*!< in/out: B-tree cursor */
|
||||
const char* file, /*!< in: file name */
|
||||
ulint line, /*!< in: line where called */
|
||||
mtr_t* mtr) /*!< in: mtr */
|
||||
{
|
||||
page_cur_t* page_cursor;
|
||||
|
@ -908,7 +914,7 @@ btr_cur_open_at_rnd_pos(
|
|||
|
||||
block = buf_page_get_gen(space, zip_size, page_no,
|
||||
RW_NO_LATCH, NULL, BUF_GET,
|
||||
__FILE__, __LINE__, mtr);
|
||||
file, line, mtr);
|
||||
page = buf_block_get_frame(block);
|
||||
|
||||
if (srv_pass_corrupt_table && !page) {
|
||||
|
@ -1229,7 +1235,6 @@ btr_cur_optimistic_insert(
|
|||
ibool inherit;
|
||||
ulint zip_size;
|
||||
ulint rec_size;
|
||||
mem_heap_t* heap = NULL;
|
||||
ulint err;
|
||||
|
||||
*big_rec = NULL;
|
||||
|
@ -1315,10 +1320,6 @@ btr_cur_optimistic_insert(
|
|||
index, entry, big_rec_vec);
|
||||
}
|
||||
|
||||
if (heap) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
|
||||
return(DB_TOO_BIG_RECORD);
|
||||
}
|
||||
}
|
||||
|
@ -1341,15 +1342,11 @@ fail_err:
|
|||
dtuple_convert_back_big_rec(index, entry, big_rec_vec);
|
||||
}
|
||||
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
|
||||
return(err);
|
||||
}
|
||||
|
||||
if (UNIV_UNLIKELY(max_size < BTR_CUR_PAGE_REORGANIZE_LIMIT
|
||||
|| max_size < rec_size)
|
||||
|| max_size < rec_size)
|
||||
&& UNIV_LIKELY(page_get_n_recs(page) > 1)
|
||||
&& page_get_max_insert_size(page, 1) < rec_size) {
|
||||
|
||||
|
@ -1415,10 +1412,6 @@ fail_err:
|
|||
}
|
||||
}
|
||||
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
if (!reorg && leaf && (cursor->flag == BTR_CUR_HASH)) {
|
||||
btr_search_update_hash_node_on_insert(cursor);
|
||||
|
@ -3282,7 +3275,8 @@ btr_estimate_n_rows_in_range(
|
|||
|
||||
btr_cur_search_to_nth_level(index, 0, tuple1, mode1,
|
||||
BTR_SEARCH_LEAF | BTR_ESTIMATE,
|
||||
&cursor, 0, &mtr);
|
||||
&cursor, 0,
|
||||
__FILE__, __LINE__, &mtr);
|
||||
} else {
|
||||
btr_cur_open_at_index_side(TRUE, index,
|
||||
BTR_SEARCH_LEAF | BTR_ESTIMATE,
|
||||
|
@ -3299,7 +3293,8 @@ btr_estimate_n_rows_in_range(
|
|||
|
||||
btr_cur_search_to_nth_level(index, 0, tuple2, mode2,
|
||||
BTR_SEARCH_LEAF | BTR_ESTIMATE,
|
||||
&cursor, 0, &mtr);
|
||||
&cursor, 0,
|
||||
__FILE__, __LINE__, &mtr);
|
||||
} else {
|
||||
btr_cur_open_at_index_side(FALSE, index,
|
||||
BTR_SEARCH_LEAF | BTR_ESTIMATE,
|
||||
|
@ -3438,7 +3433,7 @@ btr_estimate_n_pages_not_null(
|
|||
|
||||
btr_cur_search_to_nth_level(index, 0, tuple1, PAGE_CUR_G,
|
||||
BTR_SEARCH_LEAF | BTR_ESTIMATE,
|
||||
&cursor, 0, &mtr);
|
||||
&cursor, 0, __FILE__, __LINE__, &mtr);
|
||||
|
||||
mtr_commit(&mtr);
|
||||
|
||||
|
@ -3588,9 +3583,11 @@ btr_estimate_number_of_different_key_vals(
|
|||
effective_pages = btr_estimate_n_pages_not_null(index, 1 /*k*/, first_rec_path);
|
||||
|
||||
if (!effective_pages) {
|
||||
dict_index_stat_mutex_enter(index);
|
||||
for (j = 0; j <= n_cols; j++) {
|
||||
index->stat_n_diff_key_vals[j] = (ib_int64_t)index->stat_n_leaf_pages;
|
||||
}
|
||||
dict_index_stat_mutex_exit(index);
|
||||
return;
|
||||
} else if (effective_pages > index->stat_n_leaf_pages) {
|
||||
effective_pages = index->stat_n_leaf_pages;
|
||||
|
@ -3732,6 +3729,8 @@ btr_estimate_number_of_different_key_vals(
|
|||
also the pages used for external storage of fields (those pages are
|
||||
included in index->stat_n_leaf_pages) */
|
||||
|
||||
dict_index_stat_mutex_enter(index);
|
||||
|
||||
for (j = 0; j <= n_cols; j++) {
|
||||
index->stat_n_diff_key_vals[j]
|
||||
= ((n_diff[j]
|
||||
|
@ -3770,8 +3769,9 @@ btr_estimate_number_of_different_key_vals(
|
|||
}
|
||||
}
|
||||
|
||||
mem_free(n_diff);
|
||||
dict_index_stat_mutex_exit(index);
|
||||
|
||||
mem_free(n_diff);
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
|
@ -4639,7 +4639,7 @@ btr_free_externally_stored_field(
|
|||
/* In the rollback of uncommitted transactions, we may
|
||||
encounter a clustered index record whose BLOBs have
|
||||
not been written. There is nothing to free then. */
|
||||
ut_a(rb_ctx == RB_RECOVERY);
|
||||
ut_a(rb_ctx == RB_RECOVERY || rb_ctx == RB_RECOVERY_PURGE_REC);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4685,7 +4685,7 @@ btr_free_externally_stored_field(
|
|||
|| (mach_read_from_1(field_ref + BTR_EXTERN_LEN)
|
||||
& BTR_EXTERN_OWNER_FLAG)
|
||||
/* Rollback and inherited field */
|
||||
|| (rb_ctx != RB_NONE
|
||||
|| ((rb_ctx == RB_NORMAL || rb_ctx == RB_RECOVERY)
|
||||
&& (mach_read_from_1(field_ref + BTR_EXTERN_LEN)
|
||||
& BTR_EXTERN_INHERITED_FLAG))) {
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -211,10 +211,12 @@ record and it can be restored on a user record whose ordering fields
|
|||
are identical to the ones of the original user record */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
btr_pcur_restore_position(
|
||||
/*======================*/
|
||||
btr_pcur_restore_position_func(
|
||||
/*===========================*/
|
||||
ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
|
||||
btr_pcur_t* cursor, /*!< in: detached persistent cursor */
|
||||
const char* file, /*!< in: file name */
|
||||
ulint line, /*!< in: line where called */
|
||||
mtr_t* mtr) /*!< in: mtr */
|
||||
{
|
||||
dict_index_t* index;
|
||||
|
@ -223,6 +225,9 @@ btr_pcur_restore_position(
|
|||
ulint old_mode;
|
||||
mem_heap_t* heap;
|
||||
|
||||
ut_ad(mtr);
|
||||
ut_ad(mtr->state == MTR_ACTIVE);
|
||||
|
||||
index = btr_cur_get_index(btr_pcur_get_btr_cur(cursor));
|
||||
|
||||
if (UNIV_UNLIKELY(cursor->old_stored != BTR_PCUR_OLD_STORED)
|
||||
|
@ -263,7 +268,8 @@ btr_pcur_restore_position(
|
|||
if (UNIV_LIKELY(buf_page_optimistic_get(
|
||||
latch_mode,
|
||||
cursor->block_when_stored,
|
||||
cursor->modify_clock, mtr))) {
|
||||
cursor->modify_clock,
|
||||
file, line, mtr))) {
|
||||
cursor->pos_state = BTR_PCUR_IS_POSITIONED;
|
||||
|
||||
buf_block_dbg_add_level(btr_pcur_get_block(cursor),
|
||||
|
@ -318,8 +324,8 @@ btr_pcur_restore_position(
|
|||
mode = PAGE_CUR_L;
|
||||
}
|
||||
|
||||
btr_pcur_open_with_no_init(index, tuple, mode, latch_mode,
|
||||
cursor, 0, mtr);
|
||||
btr_pcur_open_with_no_init_func(index, tuple, mode, latch_mode,
|
||||
cursor, 0, file, line, mtr);
|
||||
|
||||
/* Restore the old search mode */
|
||||
cursor->search_mode = old_mode;
|
||||
|
@ -568,8 +574,8 @@ before first in tree. The latching mode must be BTR_SEARCH_LEAF or
|
|||
BTR_MODIFY_LEAF. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
btr_pcur_open_on_user_rec(
|
||||
/*======================*/
|
||||
btr_pcur_open_on_user_rec_func(
|
||||
/*===========================*/
|
||||
dict_index_t* index, /*!< in: index */
|
||||
const dtuple_t* tuple, /*!< in: tuple on which search done */
|
||||
ulint mode, /*!< in: PAGE_CUR_L, ... */
|
||||
|
@ -577,9 +583,12 @@ btr_pcur_open_on_user_rec(
|
|||
BTR_MODIFY_LEAF */
|
||||
btr_pcur_t* cursor, /*!< in: memory buffer for persistent
|
||||
cursor */
|
||||
const char* file, /*!< in: file name */
|
||||
ulint line, /*!< in: line where called */
|
||||
mtr_t* mtr) /*!< in: mtr */
|
||||
{
|
||||
btr_pcur_open(index, tuple, mode, latch_mode, cursor, mtr);
|
||||
btr_pcur_open_func(index, tuple, mode, latch_mode, cursor,
|
||||
file, line, mtr);
|
||||
|
||||
if ((mode == PAGE_CUR_GE) || (mode == PAGE_CUR_G)) {
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 2006, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 2006, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -430,6 +430,8 @@ buf_buddy_relocate_block(
|
|||
}
|
||||
mutex_exit(&flush_list_mutex);
|
||||
|
||||
UNIV_MEM_INVALID(bpage, sizeof *bpage);
|
||||
|
||||
mutex_exit(&buf_pool_zip_mutex);
|
||||
mutex_exit(&zip_free_mutex);
|
||||
return(TRUE);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 2008, Google Inc.
|
||||
|
||||
Portions of this file contain modifications contributed and copyrighted by
|
||||
|
@ -277,6 +277,8 @@ the read requests for the whole area.
|
|||
#ifndef UNIV_HOTBACKUP
|
||||
/** Value in microseconds */
|
||||
static const int WAIT_FOR_READ = 5000;
|
||||
/** Number of attemtps made to read in a page in the buffer pool */
|
||||
static const ulint BUF_PAGE_READ_MAX_RETRIES = 100;
|
||||
|
||||
/** The buffer buf_pool of the database */
|
||||
UNIV_INTERN buf_pool_t* buf_pool = NULL;
|
||||
|
@ -1150,7 +1152,9 @@ buf_pool_drop_hash_index(void)
|
|||
when we have an x-latch on btr_search_latch;
|
||||
see the comment in buf0buf.h */
|
||||
|
||||
if (!block->is_hashed) {
|
||||
if (buf_block_get_state(block)
|
||||
!= BUF_BLOCK_FILE_PAGE
|
||||
|| !block->is_hashed) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1283,8 +1287,6 @@ buf_relocate(
|
|||
|
||||
HASH_DELETE(buf_page_t, hash, buf_pool->page_hash, fold, bpage);
|
||||
HASH_INSERT(buf_page_t, hash, buf_pool->page_hash, fold, dpage);
|
||||
|
||||
UNIV_MEM_INVALID(bpage, sizeof *bpage);
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
|
@ -1980,14 +1982,14 @@ buf_zip_decompress(
|
|||
buf_block_t* block, /*!< in/out: block */
|
||||
ibool check) /*!< in: TRUE=verify the page checksum */
|
||||
{
|
||||
const byte* frame = block->page.zip.data;
|
||||
const byte* frame = block->page.zip.data;
|
||||
ulint stamp_checksum = mach_read_from_4(
|
||||
frame + FIL_PAGE_SPACE_OR_CHKSUM);
|
||||
|
||||
ut_ad(buf_block_get_zip_size(block));
|
||||
ut_a(buf_block_get_space(block) != 0);
|
||||
|
||||
if (UNIV_LIKELY(check)) {
|
||||
ulint stamp_checksum = mach_read_from_4(
|
||||
frame + FIL_PAGE_SPACE_OR_CHKSUM);
|
||||
if (UNIV_LIKELY(check && stamp_checksum != BUF_NO_CHECKSUM_MAGIC)) {
|
||||
ulint calc_checksum = page_zip_calc_checksum(
|
||||
frame, page_zip_get_size(&block->page.zip));
|
||||
|
||||
|
@ -2196,6 +2198,7 @@ buf_page_get_gen(
|
|||
unsigned access_time;
|
||||
ulint fix_type;
|
||||
ibool must_read;
|
||||
ulint retries = 0;
|
||||
mutex_t* block_mutex;
|
||||
trx_t* trx = NULL;
|
||||
ulint sec;
|
||||
|
@ -2204,6 +2207,7 @@ buf_page_get_gen(
|
|||
ib_uint64_t finish_time;
|
||||
|
||||
ut_ad(mtr);
|
||||
ut_ad(mtr->state == MTR_ACTIVE);
|
||||
ut_ad((rw_latch == RW_S_LATCH)
|
||||
|| (rw_latch == RW_X_LATCH)
|
||||
|| (rw_latch == RW_NO_LATCH));
|
||||
|
@ -2271,7 +2275,29 @@ loop2:
|
|||
return(NULL);
|
||||
}
|
||||
|
||||
buf_read_page(space, zip_size, offset, trx);
|
||||
if (buf_read_page(space, zip_size, offset, trx)) {
|
||||
retries = 0;
|
||||
} else if (retries < BUF_PAGE_READ_MAX_RETRIES) {
|
||||
++retries;
|
||||
} else {
|
||||
fprintf(stderr, "InnoDB: Error: Unable"
|
||||
" to read tablespace %lu page no"
|
||||
" %lu into the buffer pool after"
|
||||
" %lu attempts\n"
|
||||
"InnoDB: The most probable cause"
|
||||
" of this error may be that the"
|
||||
" table has been corrupted.\n"
|
||||
"InnoDB: You can try to fix this"
|
||||
" problem by using"
|
||||
" innodb_force_recovery.\n"
|
||||
"InnoDB: Please see reference manual"
|
||||
" for more details.\n"
|
||||
"InnoDB: Aborting...\n",
|
||||
space, offset,
|
||||
BUF_PAGE_READ_MAX_RETRIES);
|
||||
|
||||
ut_error;
|
||||
}
|
||||
|
||||
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
|
||||
ut_a(++buf_dbg_counter % 37 || buf_validate());
|
||||
|
@ -2414,22 +2440,8 @@ wait_until_unfixed:
|
|||
ut_ad(!block->page.in_flush_list);
|
||||
} else {
|
||||
/* Relocate buf_pool->flush_list. */
|
||||
buf_page_t* b;
|
||||
|
||||
b = UT_LIST_GET_PREV(flush_list, &block->page);
|
||||
ut_ad(block->page.in_flush_list);
|
||||
UT_LIST_REMOVE(flush_list, buf_pool->flush_list,
|
||||
&block->page);
|
||||
|
||||
if (b) {
|
||||
UT_LIST_INSERT_AFTER(
|
||||
flush_list, buf_pool->flush_list, b,
|
||||
&block->page);
|
||||
} else {
|
||||
UT_LIST_ADD_FIRST(
|
||||
flush_list, buf_pool->flush_list,
|
||||
&block->page);
|
||||
}
|
||||
buf_flush_relocate_on_flush_list(bpage,
|
||||
&block->page);
|
||||
}
|
||||
|
||||
mutex_exit(&flush_list_mutex);
|
||||
|
@ -2447,6 +2459,9 @@ wait_until_unfixed:
|
|||
block->page.buf_fix_count = 1;
|
||||
buf_block_set_io_fix(block, BUF_IO_READ);
|
||||
rw_lock_x_lock(&block->lock);
|
||||
|
||||
UNIV_MEM_INVALID(bpage, sizeof *bpage);
|
||||
|
||||
mutex_exit(block_mutex);
|
||||
mutex_exit(&buf_pool_zip_mutex);
|
||||
|
||||
|
@ -2461,8 +2476,9 @@ wait_until_unfixed:
|
|||
/* Decompress the page and apply buffered operations
|
||||
while not holding buf_pool_mutex or block->mutex. */
|
||||
success = buf_zip_decompress(block, srv_use_checksums);
|
||||
ut_a(success);
|
||||
|
||||
if (UNIV_LIKELY(success)) {
|
||||
if (UNIV_LIKELY(!recv_no_ibuf_operations)) {
|
||||
ibuf_merge_or_delete_for_page(block, space, offset,
|
||||
zip_size, TRUE);
|
||||
}
|
||||
|
@ -2478,14 +2494,6 @@ wait_until_unfixed:
|
|||
buf_pool->n_pend_unzip--;
|
||||
mutex_exit(&buf_pool_mutex);
|
||||
rw_lock_x_unlock(&block->lock);
|
||||
|
||||
if (UNIV_UNLIKELY(!success)) {
|
||||
|
||||
//buf_pool_mutex_exit();
|
||||
mutex_exit(block_mutex);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case BUF_BLOCK_ZIP_FREE:
|
||||
|
@ -2603,8 +2611,8 @@ page.
|
|||
@return TRUE if success */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
buf_page_optimistic_get_func(
|
||||
/*=========================*/
|
||||
buf_page_optimistic_get(
|
||||
/*====================*/
|
||||
ulint rw_latch,/*!< in: RW_S_LATCH, RW_X_LATCH */
|
||||
buf_block_t* block, /*!< in: guessed buffer block */
|
||||
ib_uint64_t modify_clock,/*!< in: modify clock value if mode is
|
||||
|
@ -2618,7 +2626,9 @@ buf_page_optimistic_get_func(
|
|||
ulint fix_type;
|
||||
trx_t* trx = NULL;
|
||||
|
||||
ut_ad(mtr && block);
|
||||
ut_ad(block);
|
||||
ut_ad(mtr);
|
||||
ut_ad(mtr->state == MTR_ACTIVE);
|
||||
ut_ad((rw_latch == RW_S_LATCH) || (rw_latch == RW_X_LATCH));
|
||||
|
||||
mutex_enter(&block->mutex);
|
||||
|
@ -2738,6 +2748,7 @@ buf_page_get_known_nowait(
|
|||
trx_t* trx = NULL;
|
||||
|
||||
ut_ad(mtr);
|
||||
ut_ad(mtr->state == MTR_ACTIVE);
|
||||
ut_ad((rw_latch == RW_S_LATCH) || (rw_latch == RW_X_LATCH));
|
||||
|
||||
mutex_enter(&block->mutex);
|
||||
|
@ -2846,6 +2857,9 @@ buf_page_try_get_func(
|
|||
ibool success;
|
||||
ulint fix_type;
|
||||
|
||||
ut_ad(mtr);
|
||||
ut_ad(mtr->state == MTR_ACTIVE);
|
||||
|
||||
//buf_pool_mutex_enter();
|
||||
rw_lock_s_lock(&page_hash_latch);
|
||||
block = buf_block_hash_get(space_id, page_no);
|
||||
|
@ -3249,6 +3263,7 @@ buf_page_create(
|
|||
ulint time_ms = ut_time_ms();
|
||||
|
||||
ut_ad(mtr);
|
||||
ut_ad(mtr->state == MTR_ACTIVE);
|
||||
ut_ad(space || !zip_size);
|
||||
|
||||
free_block = buf_LRU_get_free_block(0);
|
||||
|
@ -3431,7 +3446,8 @@ buf_page_io_complete(
|
|||
read_space_id = mach_read_from_4(
|
||||
frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
|
||||
|
||||
if (bpage->space == TRX_SYS_SPACE
|
||||
if ((bpage->space == TRX_SYS_SPACE
|
||||
|| (srv_doublewrite_file && bpage->space == TRX_DOUBLEWRITE_SPACE))
|
||||
&& trx_doublewrite_page_inside(bpage->offset)) {
|
||||
|
||||
ut_print_timestamp(stderr);
|
||||
|
@ -3503,7 +3519,7 @@ corrupt:
|
|||
REFMAN "forcing-recovery.html\n"
|
||||
"InnoDB: about forcing recovery.\n", stderr);
|
||||
|
||||
if (srv_pass_corrupt_table && bpage->space > 0
|
||||
if (srv_pass_corrupt_table && !trx_sys_sys_space(bpage->space)
|
||||
&& bpage->space < SRV_LOG_SPACE_FIRST_ID) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: space %lu will be treated as corrupt.\n",
|
||||
|
|
284
buf/buf0flu.c
284
buf/buf0flu.c
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -87,6 +87,146 @@ buf_flush_validate_low(void);
|
|||
/*========================*/
|
||||
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
|
||||
|
||||
/********************************************************************//**
|
||||
Insert a block in the flush_rbt and returns a pointer to its
|
||||
predecessor or NULL if no predecessor. The ordering is maintained
|
||||
on the basis of the <oldest_modification, space, offset> key.
|
||||
@return pointer to the predecessor or NULL if no predecessor. */
|
||||
static
|
||||
buf_page_t*
|
||||
buf_flush_insert_in_flush_rbt(
|
||||
/*==========================*/
|
||||
buf_page_t* bpage) /*!< in: bpage to be inserted. */
|
||||
{
|
||||
buf_page_t* prev = NULL;
|
||||
const ib_rbt_node_t* c_node;
|
||||
const ib_rbt_node_t* p_node;
|
||||
|
||||
//ut_ad(buf_pool_mutex_own());
|
||||
ut_ad(mutex_own(&flush_list_mutex));
|
||||
|
||||
/* Insert this buffer into the rbt. */
|
||||
c_node = rbt_insert(buf_pool->flush_rbt, &bpage, &bpage);
|
||||
ut_a(c_node != NULL);
|
||||
|
||||
/* Get the predecessor. */
|
||||
p_node = rbt_prev(buf_pool->flush_rbt, c_node);
|
||||
|
||||
if (p_node != NULL) {
|
||||
prev = *rbt_value(buf_page_t*, p_node);
|
||||
ut_a(prev != NULL);
|
||||
}
|
||||
|
||||
return(prev);
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Delete a bpage from the flush_rbt. */
|
||||
static
|
||||
void
|
||||
buf_flush_delete_from_flush_rbt(
|
||||
/*============================*/
|
||||
buf_page_t* bpage) /*!< in: bpage to be removed. */
|
||||
{
|
||||
|
||||
ibool ret = FALSE;
|
||||
|
||||
//ut_ad(buf_pool_mutex_own());
|
||||
ut_ad(mutex_own(&flush_list_mutex));
|
||||
ret = rbt_delete(buf_pool->flush_rbt, &bpage);
|
||||
ut_ad(ret);
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Compare two modified blocks in the buffer pool. The key for comparison
|
||||
is:
|
||||
key = <oldest_modification, space, offset>
|
||||
This comparison is used to maintian ordering of blocks in the
|
||||
buf_pool->flush_rbt.
|
||||
Note that for the purpose of flush_rbt, we only need to order blocks
|
||||
on the oldest_modification. The other two fields are used to uniquely
|
||||
identify the blocks.
|
||||
@return < 0 if b2 < b1, 0 if b2 == b1, > 0 if b2 > b1 */
|
||||
static
|
||||
int
|
||||
buf_flush_block_cmp(
|
||||
/*================*/
|
||||
const void* p1, /*!< in: block1 */
|
||||
const void* p2) /*!< in: block2 */
|
||||
{
|
||||
int ret;
|
||||
const buf_page_t* b1;
|
||||
const buf_page_t* b2;
|
||||
|
||||
ut_ad(p1 != NULL);
|
||||
ut_ad(p2 != NULL);
|
||||
|
||||
b1 = *(const buf_page_t**) p1;
|
||||
b2 = *(const buf_page_t**) p2;
|
||||
|
||||
ut_ad(b1 != NULL);
|
||||
ut_ad(b2 != NULL);
|
||||
|
||||
ut_ad(b1->in_flush_list);
|
||||
ut_ad(b2->in_flush_list);
|
||||
|
||||
if (b2->oldest_modification
|
||||
> b1->oldest_modification) {
|
||||
return(1);
|
||||
}
|
||||
|
||||
if (b2->oldest_modification
|
||||
< b1->oldest_modification) {
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* If oldest_modification is same then decide on the space. */
|
||||
ret = (int)(b2->space - b1->space);
|
||||
|
||||
/* Or else decide ordering on the offset field. */
|
||||
return(ret ? ret : (int)(b2->offset - b1->offset));
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Initialize the red-black tree to speed up insertions into the flush_list
|
||||
during recovery process. Should be called at the start of recovery
|
||||
process before any page has been read/written. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
buf_flush_init_flush_rbt(void)
|
||||
/*==========================*/
|
||||
{
|
||||
//buf_pool_mutex_enter();
|
||||
mutex_enter(&flush_list_mutex);
|
||||
|
||||
/* Create red black tree for speedy insertions in flush list. */
|
||||
buf_pool->flush_rbt = rbt_create(sizeof(buf_page_t*),
|
||||
buf_flush_block_cmp);
|
||||
//buf_pool_mutex_exit();
|
||||
mutex_exit(&flush_list_mutex);
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Frees up the red-black tree. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
buf_flush_free_flush_rbt(void)
|
||||
/*==========================*/
|
||||
{
|
||||
//buf_pool_mutex_enter();
|
||||
mutex_enter(&flush_list_mutex);
|
||||
|
||||
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
|
||||
ut_a(buf_flush_validate_low());
|
||||
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
|
||||
|
||||
rbt_free(buf_pool->flush_rbt);
|
||||
buf_pool->flush_rbt = NULL;
|
||||
|
||||
//buf_pool_mutex_exit();
|
||||
mutex_exit(&flush_list_mutex);
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Inserts a modified block into the flush list. */
|
||||
UNIV_INTERN
|
||||
|
@ -102,6 +242,13 @@ buf_flush_insert_into_flush_list(
|
|||
|| (UT_LIST_GET_FIRST(buf_pool->flush_list)->oldest_modification
|
||||
<= block->page.oldest_modification));
|
||||
|
||||
/* If we are in the recovery then we need to update the flush
|
||||
red-black tree as well. */
|
||||
if (UNIV_LIKELY_NULL(buf_pool->flush_rbt)) {
|
||||
buf_flush_insert_sorted_into_flush_list(block);
|
||||
return;
|
||||
}
|
||||
|
||||
ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
|
||||
ut_ad(block->page.in_LRU_list);
|
||||
ut_ad(block->page.in_page_hash);
|
||||
|
@ -140,26 +287,27 @@ buf_flush_insert_sorted_into_flush_list(
|
|||
ut_d(block->page.in_flush_list = TRUE);
|
||||
|
||||
prev_b = NULL;
|
||||
b = UT_LIST_GET_FIRST(buf_pool->flush_list);
|
||||
|
||||
if (srv_fast_recovery) {
|
||||
/* speed hack */
|
||||
if (b == NULL || b->oldest_modification < block->page.oldest_modification) {
|
||||
UT_LIST_ADD_FIRST(flush_list, buf_pool->flush_list, &block->page);
|
||||
/* For the most part when this function is called the flush_rbt
|
||||
should not be NULL. In a very rare boundary case it is possible
|
||||
that the flush_rbt has already been freed by the recovery thread
|
||||
before the last page was hooked up in the flush_list by the
|
||||
io-handler thread. In that case we'll just do a simple
|
||||
linear search in the else block. */
|
||||
if (buf_pool->flush_rbt) {
|
||||
|
||||
prev_b = buf_flush_insert_in_flush_rbt(&block->page);
|
||||
|
||||
} else {
|
||||
b = UT_LIST_GET_LAST(buf_pool->flush_list);
|
||||
if (b->oldest_modification < block->page.oldest_modification) {
|
||||
/* align oldest_modification not to sort */
|
||||
block->page.oldest_modification = b->oldest_modification;
|
||||
|
||||
b = UT_LIST_GET_FIRST(buf_pool->flush_list);
|
||||
|
||||
while (b && b->oldest_modification
|
||||
> block->page.oldest_modification) {
|
||||
ut_ad(b->in_flush_list);
|
||||
prev_b = b;
|
||||
b = UT_LIST_GET_NEXT(flush_list, b);
|
||||
}
|
||||
UT_LIST_ADD_LAST(flush_list, buf_pool->flush_list, &block->page);
|
||||
}
|
||||
} else {
|
||||
/* normal */
|
||||
while (b && b->oldest_modification > block->page.oldest_modification) {
|
||||
ut_ad(b->in_flush_list);
|
||||
prev_b = b;
|
||||
b = UT_LIST_GET_NEXT(flush_list, b);
|
||||
}
|
||||
|
||||
if (prev_b == NULL) {
|
||||
|
@ -168,7 +316,6 @@ buf_flush_insert_sorted_into_flush_list(
|
|||
UT_LIST_INSERT_AFTER(flush_list, buf_pool->flush_list,
|
||||
prev_b, &block->page);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
|
||||
ut_a(buf_flush_validate_low());
|
||||
|
@ -262,7 +409,6 @@ buf_flush_remove(
|
|||
mutex_enter(&flush_list_mutex);
|
||||
|
||||
ut_ad(bpage->in_flush_list);
|
||||
ut_d(bpage->in_flush_list = FALSE);
|
||||
|
||||
switch (buf_page_get_state(bpage)) {
|
||||
case BUF_BLOCK_ZIP_PAGE:
|
||||
|
@ -285,6 +431,15 @@ buf_flush_remove(
|
|||
break;
|
||||
}
|
||||
|
||||
/* If the flush_rbt is active then delete from it as well. */
|
||||
if (UNIV_LIKELY_NULL(buf_pool->flush_rbt)) {
|
||||
buf_flush_delete_from_flush_rbt(bpage);
|
||||
}
|
||||
|
||||
/* Must be done after we have removed it from the flush_rbt
|
||||
because we assert on in_flush_list in comparison function. */
|
||||
ut_d(bpage->in_flush_list = FALSE);
|
||||
|
||||
bpage->oldest_modification = 0;
|
||||
|
||||
ut_d(UT_LIST_VALIDATE(flush_list, buf_page_t, buf_pool->flush_list,
|
||||
|
@ -292,6 +447,64 @@ buf_flush_remove(
|
|||
mutex_exit(&flush_list_mutex);
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Relocates a buffer control block on the flush_list.
|
||||
Note that it is assumed that the contents of bpage has already been
|
||||
copied to dpage. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
buf_flush_relocate_on_flush_list(
|
||||
/*=============================*/
|
||||
buf_page_t* bpage, /*!< in/out: control block being moved */
|
||||
buf_page_t* dpage) /*!< in/out: destination block */
|
||||
{
|
||||
buf_page_t* prev;
|
||||
buf_page_t* prev_b = NULL;
|
||||
|
||||
//ut_ad(buf_pool_mutex_own());
|
||||
ut_ad(mutex_own(&flush_list_mutex));
|
||||
|
||||
ut_ad(mutex_own(buf_page_get_mutex(bpage)));
|
||||
|
||||
ut_ad(bpage->in_flush_list);
|
||||
ut_ad(dpage->in_flush_list);
|
||||
|
||||
/* If recovery is active we must swap the control blocks in
|
||||
the flush_rbt as well. */
|
||||
if (UNIV_LIKELY_NULL(buf_pool->flush_rbt)) {
|
||||
buf_flush_delete_from_flush_rbt(bpage);
|
||||
prev_b = buf_flush_insert_in_flush_rbt(dpage);
|
||||
}
|
||||
|
||||
/* Must be done after we have removed it from the flush_rbt
|
||||
because we assert on in_flush_list in comparison function. */
|
||||
ut_d(bpage->in_flush_list = FALSE);
|
||||
|
||||
prev = UT_LIST_GET_PREV(flush_list, bpage);
|
||||
UT_LIST_REMOVE(flush_list, buf_pool->flush_list, bpage);
|
||||
|
||||
if (prev) {
|
||||
ut_ad(prev->in_flush_list);
|
||||
UT_LIST_INSERT_AFTER(
|
||||
flush_list,
|
||||
buf_pool->flush_list,
|
||||
prev, dpage);
|
||||
} else {
|
||||
UT_LIST_ADD_FIRST(
|
||||
flush_list,
|
||||
buf_pool->flush_list,
|
||||
dpage);
|
||||
}
|
||||
|
||||
/* Just an extra check. Previous in flush_list
|
||||
should be the same control block as in flush_rbt. */
|
||||
ut_a(!buf_pool->flush_rbt || prev_b == prev);
|
||||
|
||||
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
|
||||
ut_a(buf_flush_validate_low());
|
||||
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Updates the flush system data structures when a write is completed. */
|
||||
UNIV_INTERN
|
||||
|
@ -452,7 +665,8 @@ corrupted_page:
|
|||
write_buf = trx_doublewrite->write_buf;
|
||||
i = 0;
|
||||
|
||||
fil_io(OS_FILE_WRITE, TRUE, TRX_SYS_SPACE, 0,
|
||||
fil_io(OS_FILE_WRITE, TRUE,
|
||||
(srv_doublewrite_file ? TRX_DOUBLEWRITE_SPACE : TRX_SYS_SPACE), 0,
|
||||
trx_doublewrite->block1, 0, len,
|
||||
(void*) write_buf, NULL);
|
||||
|
||||
|
@ -489,7 +703,8 @@ corrupted_page:
|
|||
+ TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE;
|
||||
ut_ad(i == TRX_SYS_DOUBLEWRITE_BLOCK_SIZE);
|
||||
|
||||
fil_io(OS_FILE_WRITE, TRUE, TRX_SYS_SPACE, 0,
|
||||
fil_io(OS_FILE_WRITE, TRUE,
|
||||
(srv_doublewrite_file ? TRX_DOUBLEWRITE_SPACE : TRX_SYS_SPACE), 0,
|
||||
trx_doublewrite->block2, 0, len,
|
||||
(void*) write_buf, NULL);
|
||||
|
||||
|
@ -519,7 +734,7 @@ corrupted_page:
|
|||
flush:
|
||||
/* Now flush the doublewrite buffer data to disk */
|
||||
|
||||
fil_flush(TRX_SYS_SPACE);
|
||||
fil_flush(srv_doublewrite_file ? TRX_DOUBLEWRITE_SPACE : TRX_SYS_SPACE);
|
||||
|
||||
/* We know that the writes have been flushed to disk now
|
||||
and in recovery we will find them in the doublewrite buffer
|
||||
|
@ -1473,24 +1688,45 @@ ibool
|
|||
buf_flush_validate_low(void)
|
||||
/*========================*/
|
||||
{
|
||||
buf_page_t* bpage;
|
||||
buf_page_t* bpage;
|
||||
const ib_rbt_node_t* rnode = NULL;
|
||||
|
||||
UT_LIST_VALIDATE(flush_list, buf_page_t, buf_pool->flush_list,
|
||||
ut_ad(ut_list_node_313->in_flush_list));
|
||||
|
||||
bpage = UT_LIST_GET_FIRST(buf_pool->flush_list);
|
||||
|
||||
/* If we are in recovery mode i.e.: flush_rbt != NULL
|
||||
then each block in the flush_list must also be present
|
||||
in the flush_rbt. */
|
||||
if (UNIV_LIKELY_NULL(buf_pool->flush_rbt)) {
|
||||
rnode = rbt_first(buf_pool->flush_rbt);
|
||||
}
|
||||
|
||||
while (bpage != NULL) {
|
||||
const ib_uint64_t om = bpage->oldest_modification;
|
||||
ut_ad(bpage->in_flush_list);
|
||||
//ut_a(buf_page_in_file(bpage)); /* optimistic */
|
||||
ut_a(om > 0);
|
||||
|
||||
if (UNIV_LIKELY_NULL(buf_pool->flush_rbt)) {
|
||||
ut_a(rnode);
|
||||
buf_page_t* rpage = *rbt_value(buf_page_t*,
|
||||
rnode);
|
||||
ut_a(rpage);
|
||||
ut_a(rpage == bpage);
|
||||
rnode = rbt_next(buf_pool->flush_rbt, rnode);
|
||||
}
|
||||
|
||||
bpage = UT_LIST_GET_NEXT(flush_list, bpage);
|
||||
|
||||
ut_a(!bpage || om >= bpage->oldest_modification);
|
||||
}
|
||||
|
||||
/* By this time we must have exhausted the traversal of
|
||||
flush_rbt (if active) as well. */
|
||||
ut_a(rnode == NULL);
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
|
|
124
buf/buf0lru.c
124
buf/buf0lru.c
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -371,21 +371,39 @@ scan_again:
|
|||
bpage = UT_LIST_GET_LAST(buf_pool->LRU);
|
||||
|
||||
while (bpage != NULL) {
|
||||
mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
|
||||
buf_page_t* prev_bpage;
|
||||
ibool prev_bpage_buf_fix = FALSE;
|
||||
|
||||
ut_a(buf_page_in_file(bpage));
|
||||
|
||||
prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
|
||||
|
||||
if (!block_mutex) {
|
||||
bpage = prev_bpage;
|
||||
continue;
|
||||
}
|
||||
/* bpage->space and bpage->io_fix are protected by
|
||||
buf_pool_mutex and block_mutex. It is safe to check
|
||||
them while holding buf_pool_mutex only. */
|
||||
|
||||
if (buf_page_get_space(bpage) == id) {
|
||||
if (bpage->buf_fix_count > 0
|
||||
|| buf_page_get_io_fix(bpage) != BUF_IO_NONE) {
|
||||
if (buf_page_get_space(bpage) != id) {
|
||||
/* Skip this block, as it does not belong to
|
||||
the space that is being invalidated. */
|
||||
} else if (buf_page_get_io_fix(bpage) != BUF_IO_NONE) {
|
||||
/* We cannot remove this page during this scan
|
||||
yet; maybe the system is currently reading it
|
||||
in, or flushing the modifications to the file */
|
||||
|
||||
all_freed = FALSE;
|
||||
} else {
|
||||
mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
|
||||
|
||||
if (!block_mutex) {
|
||||
/* It may be impossible case...
|
||||
Something wrong, so will be scan_again */
|
||||
|
||||
all_freed = FALSE;
|
||||
|
||||
goto next_page_no_mutex;
|
||||
}
|
||||
|
||||
if (bpage->buf_fix_count > 0) {
|
||||
|
||||
/* We cannot remove this page during
|
||||
this scan yet; maybe the system is
|
||||
|
@ -405,8 +423,40 @@ scan_again:
|
|||
(ulong) buf_page_get_page_no(bpage));
|
||||
}
|
||||
#endif
|
||||
if (buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE
|
||||
&& ((buf_block_t*) bpage)->is_hashed) {
|
||||
if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
|
||||
/* This is a compressed-only block
|
||||
descriptor. Ensure that prev_bpage
|
||||
cannot be relocated when bpage is freed. */
|
||||
if (UNIV_LIKELY(prev_bpage != NULL)) {
|
||||
switch (buf_page_get_state(
|
||||
prev_bpage)) {
|
||||
case BUF_BLOCK_FILE_PAGE:
|
||||
/* Descriptors of uncompressed
|
||||
blocks will not be relocated,
|
||||
because we are holding the
|
||||
buf_pool_mutex. */
|
||||
break;
|
||||
case BUF_BLOCK_ZIP_PAGE:
|
||||
case BUF_BLOCK_ZIP_DIRTY:
|
||||
/* Descriptors of compressed-
|
||||
only blocks can be relocated,
|
||||
unless they are buffer-fixed.
|
||||
Because both bpage and
|
||||
prev_bpage are protected by
|
||||
buf_pool_zip_mutex, it is
|
||||
not necessary to acquire
|
||||
further mutexes. */
|
||||
ut_ad(&buf_pool_zip_mutex
|
||||
== block_mutex);
|
||||
ut_ad(mutex_own(block_mutex));
|
||||
prev_bpage_buf_fix = TRUE;
|
||||
prev_bpage->buf_fix_count++;
|
||||
break;
|
||||
default:
|
||||
ut_error;
|
||||
}
|
||||
}
|
||||
} else if (((buf_block_t*) bpage)->is_hashed) {
|
||||
ulint page_no;
|
||||
ulint zip_size;
|
||||
|
||||
|
@ -432,7 +482,8 @@ scan_again:
|
|||
buf_flush_remove(bpage);
|
||||
}
|
||||
|
||||
/* Remove from the LRU list */
|
||||
/* Remove from the LRU list. */
|
||||
|
||||
if (buf_LRU_block_remove_hashed_page(bpage, TRUE)
|
||||
!= BUF_BLOCK_ZIP_FREE) {
|
||||
buf_LRU_block_free_hashed_page((buf_block_t*)
|
||||
|
@ -444,18 +495,27 @@ scan_again:
|
|||
ut_ad(block_mutex == &buf_pool_zip_mutex);
|
||||
ut_ad(!mutex_own(block_mutex));
|
||||
|
||||
/* The compressed block descriptor
|
||||
(bpage) has been deallocated and
|
||||
block_mutex released. Also,
|
||||
buf_buddy_free() may have relocated
|
||||
prev_bpage. Rescan the LRU list. */
|
||||
if (prev_bpage_buf_fix) {
|
||||
/* We temporarily buffer-fixed
|
||||
prev_bpage, so that
|
||||
buf_buddy_free() could not
|
||||
relocate it, in case it was a
|
||||
compressed-only block
|
||||
descriptor. */
|
||||
|
||||
bpage = UT_LIST_GET_LAST(buf_pool->LRU);
|
||||
continue;
|
||||
mutex_enter(block_mutex);
|
||||
ut_ad(prev_bpage->buf_fix_count > 0);
|
||||
prev_bpage->buf_fix_count--;
|
||||
mutex_exit(block_mutex);
|
||||
}
|
||||
|
||||
goto next_page_no_mutex;
|
||||
}
|
||||
}
|
||||
next_page:
|
||||
mutex_exit(block_mutex);
|
||||
mutex_exit(block_mutex);
|
||||
}
|
||||
|
||||
next_page_no_mutex:
|
||||
bpage = prev_bpage;
|
||||
}
|
||||
|
||||
|
@ -1600,26 +1660,8 @@ not_freed:
|
|||
if (b->state == BUF_BLOCK_ZIP_PAGE) {
|
||||
buf_LRU_insert_zip_clean(b);
|
||||
} else {
|
||||
buf_page_t* prev;
|
||||
|
||||
ut_ad(b->in_flush_list);
|
||||
ut_d(bpage->in_flush_list = FALSE);
|
||||
|
||||
prev = UT_LIST_GET_PREV(flush_list, b);
|
||||
UT_LIST_REMOVE(flush_list, buf_pool->flush_list, b);
|
||||
|
||||
if (prev) {
|
||||
ut_ad(prev->in_flush_list);
|
||||
UT_LIST_INSERT_AFTER(
|
||||
flush_list,
|
||||
buf_pool->flush_list,
|
||||
prev, b);
|
||||
} else {
|
||||
UT_LIST_ADD_FIRST(
|
||||
flush_list,
|
||||
buf_pool->flush_list,
|
||||
b);
|
||||
}
|
||||
/* Relocate on buf_pool->flush_list. */
|
||||
buf_flush_relocate_on_flush_list(bpage, b);
|
||||
}
|
||||
mutex_exit(&flush_list_mutex);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -86,7 +86,9 @@ buf_read_page_low(
|
|||
wake_later = mode & OS_AIO_SIMULATED_WAKE_LATER;
|
||||
mode = mode & ~OS_AIO_SIMULATED_WAKE_LATER;
|
||||
|
||||
if (trx_doublewrite && space == TRX_SYS_SPACE
|
||||
if (trx_doublewrite
|
||||
&& (space == TRX_SYS_SPACE
|
||||
|| (srv_doublewrite_file && space == TRX_DOUBLEWRITE_SPACE))
|
||||
&& ( (offset >= trx_doublewrite->block1
|
||||
&& offset < trx_doublewrite->block1
|
||||
+ TRX_SYS_DOUBLEWRITE_BLOCK_SIZE)
|
||||
|
@ -656,6 +658,50 @@ buf_read_recv_pages(
|
|||
/* It is a single table tablespace and the .ibd file is
|
||||
missing: do nothing */
|
||||
|
||||
/* the log records should be treated here same reason
|
||||
for http://bugs.mysql.com/bug.php?id=43948 */
|
||||
|
||||
if (recv_recovery_is_on()) {
|
||||
recv_addr_t* recv_addr;
|
||||
|
||||
mutex_enter(&(recv_sys->mutex));
|
||||
|
||||
if (recv_sys->apply_log_recs == FALSE) {
|
||||
mutex_exit(&(recv_sys->mutex));
|
||||
goto not_to_recover;
|
||||
}
|
||||
|
||||
for (i = 0; i < n_stored; i++) {
|
||||
/* recv_get_fil_addr_struct() */
|
||||
recv_addr = HASH_GET_FIRST(recv_sys->addr_hash,
|
||||
hash_calc_hash(ut_fold_ulint_pair(space, page_nos[i]),
|
||||
recv_sys->addr_hash));
|
||||
while (recv_addr) {
|
||||
if ((recv_addr->space == space)
|
||||
&& (recv_addr->page_no == page_nos[i])) {
|
||||
break;
|
||||
}
|
||||
recv_addr = HASH_GET_NEXT(addr_hash, recv_addr);
|
||||
}
|
||||
|
||||
if ((recv_addr == NULL)
|
||||
|| (recv_addr->state == RECV_BEING_PROCESSED)
|
||||
|| (recv_addr->state == RECV_PROCESSED)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
recv_addr->state = RECV_PROCESSED;
|
||||
|
||||
ut_a(recv_sys->n_addrs);
|
||||
recv_sys->n_addrs--;
|
||||
}
|
||||
|
||||
mutex_exit(&(recv_sys->mutex));
|
||||
|
||||
fprintf(stderr, " (cannot find space: %lu)", space);
|
||||
}
|
||||
not_to_recover:
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -674,10 +720,10 @@ buf_read_recv_pages(
|
|||
|
||||
count++;
|
||||
|
||||
if (count > 5000) {
|
||||
if (count > 1000) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error: InnoDB has waited for"
|
||||
" 50 seconds for pending\n"
|
||||
" 10 seconds for pending\n"
|
||||
"InnoDB: reads to the buffer pool to"
|
||||
" be finished.\n"
|
||||
"InnoDB: Number of pending reads %lu,"
|
||||
|
|
|
@ -666,6 +666,21 @@ dtuple_convert_big_rec(
|
|||
goto skip_field;
|
||||
}
|
||||
|
||||
/* In DYNAMIC and COMPRESSED format, store
|
||||
locally any non-BLOB columns whose maximum
|
||||
length does not exceed 256 bytes. This is
|
||||
because there is no room for the "external
|
||||
storage" flag when the maximum length is 255
|
||||
bytes or less. This restriction trivially
|
||||
holds in REDUNDANT and COMPACT format, because
|
||||
there we always store locally columns whose
|
||||
length is up to local_len == 788 bytes.
|
||||
@see rec_init_offsets_comp_ordinary */
|
||||
if (ifield->col->mtype != DATA_BLOB
|
||||
&& ifield->col->len < 256) {
|
||||
goto skip_field;
|
||||
}
|
||||
|
||||
longest_i = i;
|
||||
longest = savings;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -275,6 +275,9 @@ dict_boot(void)
|
|||
and (TYPE & DICT_TF_FORMAT_MASK) are nonzero and TYPE = table->flags */
|
||||
dict_mem_table_add_col(table, heap, "TYPE", DATA_INT, 0, 4);
|
||||
dict_mem_table_add_col(table, heap, "MIX_ID", DATA_BINARY, 0, 0);
|
||||
/* MIX_LEN may contain additional table flags when
|
||||
ROW_FORMAT!=REDUNDANT. Currently, these flags include
|
||||
DICT_TF2_TEMPORARY. */
|
||||
dict_mem_table_add_col(table, heap, "MIX_LEN", DATA_INT, 0, 4);
|
||||
dict_mem_table_add_col(table, heap, "CLUSTER_NAME", DATA_BINARY, 0, 0);
|
||||
dict_mem_table_add_col(table, heap, "SPACE", DATA_INT, 0, 4);
|
||||
|
@ -358,7 +361,7 @@ dict_boot(void)
|
|||
dict_mem_table_add_col(table, heap, "SPACE", DATA_INT, 0, 4);
|
||||
dict_mem_table_add_col(table, heap, "PAGE_NO", DATA_INT, 0, 4);
|
||||
|
||||
/* The '+ 2' below comes from the 2 system fields */
|
||||
/* The '+ 2' below comes from the fields DB_TRX_ID, DB_ROLL_PTR */
|
||||
#if DICT_SYS_INDEXES_PAGE_NO_FIELD != 6 + 2
|
||||
#error "DICT_SYS_INDEXES_PAGE_NO_FIELD != 6 + 2"
|
||||
#endif
|
||||
|
@ -367,6 +370,9 @@ dict_boot(void)
|
|||
#endif
|
||||
#if DICT_SYS_INDEXES_TYPE_FIELD != 4 + 2
|
||||
#error "DICT_SYS_INDEXES_TYPE_FIELD != 4 + 2"
|
||||
#endif
|
||||
#if DICT_SYS_INDEXES_NAME_FIELD != 2 + 2
|
||||
#error "DICT_SYS_INDEXES_NAME_FIELD != 2 + 2"
|
||||
#endif
|
||||
|
||||
table->id = DICT_INDEXES_ID;
|
||||
|
|
128
dict/dict0crea.c
128
dict/dict0crea.c
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -51,16 +51,18 @@ static
|
|||
dtuple_t*
|
||||
dict_create_sys_tables_tuple(
|
||||
/*=========================*/
|
||||
dict_table_t* table, /*!< in: table */
|
||||
mem_heap_t* heap) /*!< in: memory heap from which the memory for
|
||||
the built tuple is allocated */
|
||||
const dict_table_t* table, /*!< in: table */
|
||||
mem_heap_t* heap) /*!< in: memory heap from
|
||||
which the memory for the built
|
||||
tuple is allocated */
|
||||
{
|
||||
dict_table_t* sys_tables;
|
||||
dtuple_t* entry;
|
||||
dfield_t* dfield;
|
||||
byte* ptr;
|
||||
|
||||
ut_ad(table && heap);
|
||||
ut_ad(table);
|
||||
ut_ad(heap);
|
||||
|
||||
sys_tables = dict_sys->sys_tables;
|
||||
|
||||
|
@ -69,18 +71,18 @@ dict_create_sys_tables_tuple(
|
|||
dict_table_copy_types(entry, sys_tables);
|
||||
|
||||
/* 0: NAME -----------------------------*/
|
||||
dfield = dtuple_get_nth_field(entry, 0);
|
||||
dfield = dtuple_get_nth_field(entry, 0/*NAME*/);
|
||||
|
||||
dfield_set_data(dfield, table->name, ut_strlen(table->name));
|
||||
/* 3: ID -------------------------------*/
|
||||
dfield = dtuple_get_nth_field(entry, 1);
|
||||
dfield = dtuple_get_nth_field(entry, 1/*ID*/);
|
||||
|
||||
ptr = mem_heap_alloc(heap, 8);
|
||||
mach_write_to_8(ptr, table->id);
|
||||
|
||||
dfield_set_data(dfield, ptr, 8);
|
||||
/* 4: N_COLS ---------------------------*/
|
||||
dfield = dtuple_get_nth_field(entry, 2);
|
||||
dfield = dtuple_get_nth_field(entry, 2/*N_COLS*/);
|
||||
|
||||
#if DICT_TF_COMPACT != 1
|
||||
#error
|
||||
|
@ -91,40 +93,41 @@ dict_create_sys_tables_tuple(
|
|||
| ((table->flags & DICT_TF_COMPACT) << 31));
|
||||
dfield_set_data(dfield, ptr, 4);
|
||||
/* 5: TYPE -----------------------------*/
|
||||
dfield = dtuple_get_nth_field(entry, 3);
|
||||
dfield = dtuple_get_nth_field(entry, 3/*TYPE*/);
|
||||
|
||||
ptr = mem_heap_alloc(heap, 4);
|
||||
if (table->flags & ~DICT_TF_COMPACT) {
|
||||
if (table->flags & (~DICT_TF_COMPACT & ~(~0 << DICT_TF_BITS))) {
|
||||
ut_a(table->flags & DICT_TF_COMPACT);
|
||||
ut_a(dict_table_get_format(table) >= DICT_TF_FORMAT_ZIP);
|
||||
ut_a((table->flags & DICT_TF_ZSSIZE_MASK)
|
||||
<= (DICT_TF_ZSSIZE_MAX << DICT_TF_ZSSIZE_SHIFT));
|
||||
ut_a(!(table->flags & (~0 << DICT_TF_BITS)));
|
||||
mach_write_to_4(ptr, table->flags);
|
||||
ut_a(!(table->flags & (~0 << DICT_TF2_BITS)));
|
||||
mach_write_to_4(ptr, table->flags & ~(~0 << DICT_TF_BITS));
|
||||
} else {
|
||||
mach_write_to_4(ptr, DICT_TABLE_ORDINARY);
|
||||
}
|
||||
|
||||
dfield_set_data(dfield, ptr, 4);
|
||||
/* 6: MIX_ID (obsolete) ---------------------------*/
|
||||
dfield = dtuple_get_nth_field(entry, 4);
|
||||
dfield = dtuple_get_nth_field(entry, 4/*MIX_ID*/);
|
||||
|
||||
ptr = mem_heap_zalloc(heap, 8);
|
||||
|
||||
dfield_set_data(dfield, ptr, 8);
|
||||
/* 7: MIX_LEN (obsolete) --------------------------*/
|
||||
/* 7: MIX_LEN (additional flags) --------------------------*/
|
||||
|
||||
dfield = dtuple_get_nth_field(entry, 5);
|
||||
dfield = dtuple_get_nth_field(entry, 5/*MIX_LEN*/);
|
||||
|
||||
ptr = mem_heap_zalloc(heap, 4);
|
||||
ptr = mem_heap_alloc(heap, 4);
|
||||
mach_write_to_4(ptr, table->flags >> DICT_TF2_SHIFT);
|
||||
|
||||
dfield_set_data(dfield, ptr, 4);
|
||||
/* 8: CLUSTER_NAME ---------------------*/
|
||||
dfield = dtuple_get_nth_field(entry, 6);
|
||||
dfield = dtuple_get_nth_field(entry, 6/*CLUSTER_NAME*/);
|
||||
dfield_set_null(dfield); /* not supported */
|
||||
|
||||
/* 9: SPACE ----------------------------*/
|
||||
dfield = dtuple_get_nth_field(entry, 7);
|
||||
dfield = dtuple_get_nth_field(entry, 7/*SPACE*/);
|
||||
|
||||
ptr = mem_heap_alloc(heap, 4);
|
||||
mach_write_to_4(ptr, table->space);
|
||||
|
@ -143,19 +146,21 @@ static
|
|||
dtuple_t*
|
||||
dict_create_sys_columns_tuple(
|
||||
/*==========================*/
|
||||
dict_table_t* table, /*!< in: table */
|
||||
ulint i, /*!< in: column number */
|
||||
mem_heap_t* heap) /*!< in: memory heap from which the memory for
|
||||
the built tuple is allocated */
|
||||
const dict_table_t* table, /*!< in: table */
|
||||
ulint i, /*!< in: column number */
|
||||
mem_heap_t* heap) /*!< in: memory heap from
|
||||
which the memory for the built
|
||||
tuple is allocated */
|
||||
{
|
||||
dict_table_t* sys_columns;
|
||||
dtuple_t* entry;
|
||||
const dict_col_t* column;
|
||||
dfield_t* dfield;
|
||||
byte* ptr;
|
||||
const char* col_name;
|
||||
const char* col_name;
|
||||
|
||||
ut_ad(table && heap);
|
||||
ut_ad(table);
|
||||
ut_ad(heap);
|
||||
|
||||
column = dict_table_get_nth_col(table, i);
|
||||
|
||||
|
@ -166,47 +171,47 @@ dict_create_sys_columns_tuple(
|
|||
dict_table_copy_types(entry, sys_columns);
|
||||
|
||||
/* 0: TABLE_ID -----------------------*/
|
||||
dfield = dtuple_get_nth_field(entry, 0);
|
||||
dfield = dtuple_get_nth_field(entry, 0/*TABLE_ID*/);
|
||||
|
||||
ptr = mem_heap_alloc(heap, 8);
|
||||
mach_write_to_8(ptr, table->id);
|
||||
|
||||
dfield_set_data(dfield, ptr, 8);
|
||||
/* 1: POS ----------------------------*/
|
||||
dfield = dtuple_get_nth_field(entry, 1);
|
||||
dfield = dtuple_get_nth_field(entry, 1/*POS*/);
|
||||
|
||||
ptr = mem_heap_alloc(heap, 4);
|
||||
mach_write_to_4(ptr, i);
|
||||
|
||||
dfield_set_data(dfield, ptr, 4);
|
||||
/* 4: NAME ---------------------------*/
|
||||
dfield = dtuple_get_nth_field(entry, 2);
|
||||
dfield = dtuple_get_nth_field(entry, 2/*NAME*/);
|
||||
|
||||
col_name = dict_table_get_col_name(table, i);
|
||||
dfield_set_data(dfield, col_name, ut_strlen(col_name));
|
||||
/* 5: MTYPE --------------------------*/
|
||||
dfield = dtuple_get_nth_field(entry, 3);
|
||||
dfield = dtuple_get_nth_field(entry, 3/*MTYPE*/);
|
||||
|
||||
ptr = mem_heap_alloc(heap, 4);
|
||||
mach_write_to_4(ptr, column->mtype);
|
||||
|
||||
dfield_set_data(dfield, ptr, 4);
|
||||
/* 6: PRTYPE -------------------------*/
|
||||
dfield = dtuple_get_nth_field(entry, 4);
|
||||
dfield = dtuple_get_nth_field(entry, 4/*PRTYPE*/);
|
||||
|
||||
ptr = mem_heap_alloc(heap, 4);
|
||||
mach_write_to_4(ptr, column->prtype);
|
||||
|
||||
dfield_set_data(dfield, ptr, 4);
|
||||
/* 7: LEN ----------------------------*/
|
||||
dfield = dtuple_get_nth_field(entry, 5);
|
||||
dfield = dtuple_get_nth_field(entry, 5/*LEN*/);
|
||||
|
||||
ptr = mem_heap_alloc(heap, 4);
|
||||
mach_write_to_4(ptr, column->len);
|
||||
|
||||
dfield_set_data(dfield, ptr, 4);
|
||||
/* 8: PREC ---------------------------*/
|
||||
dfield = dtuple_get_nth_field(entry, 6);
|
||||
dfield = dtuple_get_nth_field(entry, 6/*PREC*/);
|
||||
|
||||
ptr = mem_heap_alloc(heap, 4);
|
||||
mach_write_to_4(ptr, 0/* unused */);
|
||||
|
@ -230,6 +235,7 @@ dict_build_table_def_step(
|
|||
dict_table_t* table;
|
||||
dtuple_t* row;
|
||||
ulint error;
|
||||
ulint flags;
|
||||
const char* path_or_name;
|
||||
ibool is_path;
|
||||
mtr_t mtr;
|
||||
|
@ -268,9 +274,10 @@ dict_build_table_def_step(
|
|||
ut_ad(!dict_table_zip_size(table)
|
||||
|| dict_table_get_format(table) >= DICT_TF_FORMAT_ZIP);
|
||||
|
||||
flags = table->flags & ~(~0 << DICT_TF_BITS);
|
||||
error = fil_create_new_single_table_tablespace(
|
||||
&space, path_or_name, is_path,
|
||||
table->flags == DICT_TF_COMPACT ? 0 : table->flags,
|
||||
flags == DICT_TF_COMPACT ? 0 : flags,
|
||||
FIL_IBD_FILE_INITIAL_SIZE);
|
||||
table->space = (unsigned int) space;
|
||||
|
||||
|
@ -286,7 +293,7 @@ dict_build_table_def_step(
|
|||
mtr_commit(&mtr);
|
||||
} else {
|
||||
/* Create in the system tablespace: disallow new features */
|
||||
table->flags &= DICT_TF_COMPACT;
|
||||
table->flags &= (~0 << DICT_TF_BITS) | DICT_TF_COMPACT;
|
||||
}
|
||||
|
||||
row = dict_create_sys_tables_tuple(table, node->heap);
|
||||
|
@ -322,9 +329,10 @@ static
|
|||
dtuple_t*
|
||||
dict_create_sys_indexes_tuple(
|
||||
/*==========================*/
|
||||
dict_index_t* index, /*!< in: index */
|
||||
mem_heap_t* heap) /*!< in: memory heap from which the memory for
|
||||
the built tuple is allocated */
|
||||
const dict_index_t* index, /*!< in: index */
|
||||
mem_heap_t* heap) /*!< in: memory heap from
|
||||
which the memory for the built
|
||||
tuple is allocated */
|
||||
{
|
||||
dict_table_t* sys_indexes;
|
||||
dict_table_t* table;
|
||||
|
@ -333,7 +341,8 @@ dict_create_sys_indexes_tuple(
|
|||
byte* ptr;
|
||||
|
||||
ut_ad(mutex_own(&(dict_sys->mutex)));
|
||||
ut_ad(index && heap);
|
||||
ut_ad(index);
|
||||
ut_ad(heap);
|
||||
|
||||
sys_indexes = dict_sys->sys_indexes;
|
||||
|
||||
|
@ -344,32 +353,32 @@ dict_create_sys_indexes_tuple(
|
|||
dict_table_copy_types(entry, sys_indexes);
|
||||
|
||||
/* 0: TABLE_ID -----------------------*/
|
||||
dfield = dtuple_get_nth_field(entry, 0);
|
||||
dfield = dtuple_get_nth_field(entry, 0/*TABLE_ID*/);
|
||||
|
||||
ptr = mem_heap_alloc(heap, 8);
|
||||
mach_write_to_8(ptr, table->id);
|
||||
|
||||
dfield_set_data(dfield, ptr, 8);
|
||||
/* 1: ID ----------------------------*/
|
||||
dfield = dtuple_get_nth_field(entry, 1);
|
||||
dfield = dtuple_get_nth_field(entry, 1/*ID*/);
|
||||
|
||||
ptr = mem_heap_alloc(heap, 8);
|
||||
mach_write_to_8(ptr, index->id);
|
||||
|
||||
dfield_set_data(dfield, ptr, 8);
|
||||
/* 4: NAME --------------------------*/
|
||||
dfield = dtuple_get_nth_field(entry, 2);
|
||||
dfield = dtuple_get_nth_field(entry, 2/*NAME*/);
|
||||
|
||||
dfield_set_data(dfield, index->name, ut_strlen(index->name));
|
||||
/* 5: N_FIELDS ----------------------*/
|
||||
dfield = dtuple_get_nth_field(entry, 3);
|
||||
dfield = dtuple_get_nth_field(entry, 3/*N_FIELDS*/);
|
||||
|
||||
ptr = mem_heap_alloc(heap, 4);
|
||||
mach_write_to_4(ptr, index->n_fields);
|
||||
|
||||
dfield_set_data(dfield, ptr, 4);
|
||||
/* 6: TYPE --------------------------*/
|
||||
dfield = dtuple_get_nth_field(entry, 4);
|
||||
dfield = dtuple_get_nth_field(entry, 4/*TYPE*/);
|
||||
|
||||
ptr = mem_heap_alloc(heap, 4);
|
||||
mach_write_to_4(ptr, index->type);
|
||||
|
@ -381,7 +390,7 @@ dict_create_sys_indexes_tuple(
|
|||
#error "DICT_SYS_INDEXES_SPACE_NO_FIELD != 7"
|
||||
#endif
|
||||
|
||||
dfield = dtuple_get_nth_field(entry, 5);
|
||||
dfield = dtuple_get_nth_field(entry, 5/*SPACE*/);
|
||||
|
||||
ptr = mem_heap_alloc(heap, 4);
|
||||
mach_write_to_4(ptr, index->space);
|
||||
|
@ -393,7 +402,7 @@ dict_create_sys_indexes_tuple(
|
|||
#error "DICT_SYS_INDEXES_PAGE_NO_FIELD != 8"
|
||||
#endif
|
||||
|
||||
dfield = dtuple_get_nth_field(entry, 6);
|
||||
dfield = dtuple_get_nth_field(entry, 6/*PAGE_NO*/);
|
||||
|
||||
ptr = mem_heap_alloc(heap, 4);
|
||||
mach_write_to_4(ptr, FIL_NULL);
|
||||
|
@ -412,10 +421,11 @@ static
|
|||
dtuple_t*
|
||||
dict_create_sys_fields_tuple(
|
||||
/*=========================*/
|
||||
dict_index_t* index, /*!< in: index */
|
||||
ulint i, /*!< in: field number */
|
||||
mem_heap_t* heap) /*!< in: memory heap from which the memory for
|
||||
the built tuple is allocated */
|
||||
const dict_index_t* index, /*!< in: index */
|
||||
ulint i, /*!< in: field number */
|
||||
mem_heap_t* heap) /*!< in: memory heap from
|
||||
which the memory for the built
|
||||
tuple is allocated */
|
||||
{
|
||||
dict_table_t* sys_fields;
|
||||
dtuple_t* entry;
|
||||
|
@ -425,7 +435,8 @@ dict_create_sys_fields_tuple(
|
|||
ibool index_contains_column_prefix_field = FALSE;
|
||||
ulint j;
|
||||
|
||||
ut_ad(index && heap);
|
||||
ut_ad(index);
|
||||
ut_ad(heap);
|
||||
|
||||
for (j = 0; j < index->n_fields; j++) {
|
||||
if (dict_index_get_nth_field(index, j)->prefix_len > 0) {
|
||||
|
@ -443,7 +454,7 @@ dict_create_sys_fields_tuple(
|
|||
dict_table_copy_types(entry, sys_fields);
|
||||
|
||||
/* 0: INDEX_ID -----------------------*/
|
||||
dfield = dtuple_get_nth_field(entry, 0);
|
||||
dfield = dtuple_get_nth_field(entry, 0/*INDEX_ID*/);
|
||||
|
||||
ptr = mem_heap_alloc(heap, 8);
|
||||
mach_write_to_8(ptr, index->id);
|
||||
|
@ -451,7 +462,7 @@ dict_create_sys_fields_tuple(
|
|||
dfield_set_data(dfield, ptr, 8);
|
||||
/* 1: POS + PREFIX LENGTH ----------------------------*/
|
||||
|
||||
dfield = dtuple_get_nth_field(entry, 1);
|
||||
dfield = dtuple_get_nth_field(entry, 1/*POS*/);
|
||||
|
||||
ptr = mem_heap_alloc(heap, 4);
|
||||
|
||||
|
@ -471,7 +482,7 @@ dict_create_sys_fields_tuple(
|
|||
|
||||
dfield_set_data(dfield, ptr, 4);
|
||||
/* 4: COL_NAME -------------------------*/
|
||||
dfield = dtuple_get_nth_field(entry, 2);
|
||||
dfield = dtuple_get_nth_field(entry, 2/*COL_NAME*/);
|
||||
|
||||
dfield_set_data(dfield, field->name,
|
||||
ut_strlen(field->name));
|
||||
|
@ -602,6 +613,7 @@ dict_create_index_tree_step(
|
|||
dict_table_t* sys_indexes;
|
||||
dict_table_t* table;
|
||||
dtuple_t* search_tuple;
|
||||
ulint zip_size;
|
||||
btr_pcur_t pcur;
|
||||
mtr_t mtr;
|
||||
|
||||
|
@ -626,8 +638,9 @@ dict_create_index_tree_step(
|
|||
|
||||
btr_pcur_move_to_next_user_rec(&pcur, &mtr);
|
||||
|
||||
node->page_no = btr_create(index->type, index->space,
|
||||
dict_table_zip_size(index->table),
|
||||
zip_size = dict_table_zip_size(index->table);
|
||||
|
||||
node->page_no = btr_create(index->type, index->space, zip_size,
|
||||
index->id, index, &mtr);
|
||||
/* printf("Created a new index tree in space %lu root page %lu\n",
|
||||
index->space, index->page_no); */
|
||||
|
@ -1092,8 +1105,11 @@ dict_create_index_step(
|
|||
|
||||
dulint index_id = node->index->id;
|
||||
|
||||
err = dict_index_add_to_cache(node->table, node->index,
|
||||
FIL_NULL, TRUE);
|
||||
err = dict_index_add_to_cache(
|
||||
node->table, node->index, FIL_NULL,
|
||||
trx_is_strict(trx)
|
||||
|| dict_table_get_format(node->table)
|
||||
>= DICT_TF_FORMAT_ZIP);
|
||||
|
||||
node->index = dict_index_get_if_in_cache_low(index_id);
|
||||
ut_a(!node->index == (err != DB_SUCCESS));
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -81,6 +81,10 @@ UNIV_INTERN rw_lock_t dict_operation_lock;
|
|||
/** Identifies generated InnoDB foreign key names */
|
||||
static char dict_ibfk[] = "_ibfk_";
|
||||
|
||||
/** array of mutexes protecting dict_index_t::stat_n_diff_key_vals[] */
|
||||
#define DICT_INDEX_STAT_MUTEX_SIZE 32
|
||||
mutex_t dict_index_stat_mutex[DICT_INDEX_STAT_MUTEX_SIZE];
|
||||
|
||||
/*******************************************************************//**
|
||||
Tries to find column names for the index and sets the col field of the
|
||||
index.
|
||||
|
@ -141,7 +145,7 @@ static
|
|||
void
|
||||
dict_field_print_low(
|
||||
/*=================*/
|
||||
dict_field_t* field); /*!< in: field */
|
||||
const dict_field_t* field); /*!< in: field */
|
||||
/*********************************************************************//**
|
||||
Frees a foreign key struct. */
|
||||
static
|
||||
|
@ -240,6 +244,45 @@ dict_mutex_exit_for_mysql(void)
|
|||
mutex_exit(&(dict_sys->mutex));
|
||||
}
|
||||
|
||||
/** Get the mutex that protects index->stat_n_diff_key_vals[] */
|
||||
#define GET_INDEX_STAT_MUTEX(index) \
|
||||
(&dict_index_stat_mutex[ut_fold_dulint(index->id) \
|
||||
% DICT_INDEX_STAT_MUTEX_SIZE])
|
||||
|
||||
/**********************************************************************//**
|
||||
Lock the appropriate mutex to protect index->stat_n_diff_key_vals[].
|
||||
index->id is used to pick the right mutex and it should not change
|
||||
before dict_index_stat_mutex_exit() is called on this index. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
dict_index_stat_mutex_enter(
|
||||
/*========================*/
|
||||
const dict_index_t* index) /*!< in: index */
|
||||
{
|
||||
ut_ad(index != NULL);
|
||||
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
|
||||
ut_ad(index->cached);
|
||||
ut_ad(!index->to_be_dropped);
|
||||
|
||||
mutex_enter(GET_INDEX_STAT_MUTEX(index));
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
Unlock the appropriate mutex that protects index->stat_n_diff_key_vals[]. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
dict_index_stat_mutex_exit(
|
||||
/*=======================*/
|
||||
const dict_index_t* index) /*!< in: index */
|
||||
{
|
||||
ut_ad(index != NULL);
|
||||
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
|
||||
ut_ad(index->cached);
|
||||
ut_ad(!index->to_be_dropped);
|
||||
|
||||
mutex_exit(GET_INDEX_STAT_MUTEX(index));
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Decrements the count of open MySQL handles to a table. */
|
||||
UNIV_INTERN
|
||||
|
@ -608,6 +651,8 @@ void
|
|||
dict_init(void)
|
||||
/*===========*/
|
||||
{
|
||||
int i;
|
||||
|
||||
dict_sys = mem_alloc(sizeof(dict_sys_t));
|
||||
|
||||
mutex_create(&dict_sys->mutex, SYNC_DICT);
|
||||
|
@ -628,6 +673,10 @@ dict_init(void)
|
|||
ut_a(dict_foreign_err_file);
|
||||
|
||||
mutex_create(&dict_foreign_err_mutex, SYNC_ANY_LATCH);
|
||||
|
||||
for (i = 0; i < DICT_INDEX_STAT_MUTEX_SIZE; i++) {
|
||||
mutex_create(&dict_index_stat_mutex[i], SYNC_INDEX_TREE);
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
|
@ -1442,11 +1491,7 @@ dict_index_too_big_for_tree(
|
|||
goto add_field_size;
|
||||
}
|
||||
|
||||
if (srv_relax_table_creation) {
|
||||
field_max_size = dict_col_get_min_size(col);
|
||||
} else {
|
||||
field_max_size = dict_col_get_max_size(col);
|
||||
}
|
||||
field_ext_max_size = field_max_size < 256 ? 1 : 2;
|
||||
|
||||
if (field->prefix_len) {
|
||||
|
@ -1527,6 +1572,7 @@ dict_index_add_to_cache(
|
|||
|
||||
if (!dict_index_find_cols(table, index)) {
|
||||
|
||||
dict_mem_index_free(index);
|
||||
return(DB_CORRUPTION);
|
||||
}
|
||||
|
||||
|
@ -4247,9 +4293,13 @@ dict_update_statistics_low(
|
|||
|
||||
index = dict_table_get_first_index(table);
|
||||
|
||||
dict_index_stat_mutex_enter(index);
|
||||
|
||||
table->stat_n_rows = index->stat_n_diff_key_vals[
|
||||
dict_index_get_n_unique(index)];
|
||||
|
||||
dict_index_stat_mutex_exit(index);
|
||||
|
||||
table->stat_clustered_index_size = index->stat_index_size;
|
||||
|
||||
table->stat_sum_of_other_index_sizes = sum_of_index_sizes
|
||||
|
@ -4428,6 +4478,8 @@ dict_index_print_low(
|
|||
|
||||
ut_ad(mutex_own(&(dict_sys->mutex)));
|
||||
|
||||
dict_index_stat_mutex_enter(index);
|
||||
|
||||
if (index->n_user_defined_cols > 0) {
|
||||
n_vals = index->stat_n_diff_key_vals[
|
||||
index->n_user_defined_cols];
|
||||
|
@ -4435,6 +4487,8 @@ dict_index_print_low(
|
|||
n_vals = index->stat_n_diff_key_vals[1];
|
||||
}
|
||||
|
||||
dict_index_stat_mutex_exit(index);
|
||||
|
||||
if (dict_index_is_clust(index)) {
|
||||
type_string = "clustered index";
|
||||
} else if (dict_index_is_unique(index)) {
|
||||
|
@ -4480,7 +4534,7 @@ static
|
|||
void
|
||||
dict_field_print_low(
|
||||
/*=================*/
|
||||
dict_field_t* field) /*!< in: field */
|
||||
const dict_field_t* field) /*!< in: field */
|
||||
{
|
||||
ut_ad(mutex_own(&(dict_sys->mutex)));
|
||||
|
||||
|
@ -4844,8 +4898,10 @@ UNIV_INTERN
|
|||
void
|
||||
dict_table_check_for_dup_indexes(
|
||||
/*=============================*/
|
||||
const dict_table_t* table) /*!< in: Check for dup indexes
|
||||
const dict_table_t* table, /*!< in: Check for dup indexes
|
||||
in this table */
|
||||
ibool tmp_ok) /*!< in: TRUE=allow temporary
|
||||
index names */
|
||||
{
|
||||
/* Check for duplicates, ignoring indexes that are marked
|
||||
as to be dropped */
|
||||
|
@ -4853,13 +4909,17 @@ dict_table_check_for_dup_indexes(
|
|||
const dict_index_t* index1;
|
||||
const dict_index_t* index2;
|
||||
|
||||
ut_ad(mutex_own(&dict_sys->mutex));
|
||||
|
||||
/* The primary index _must_ exist */
|
||||
ut_a(UT_LIST_GET_LEN(table->indexes) > 0);
|
||||
|
||||
index1 = UT_LIST_GET_FIRST(table->indexes);
|
||||
index2 = UT_LIST_GET_NEXT(indexes, index1);
|
||||
|
||||
while (index1 && index2) {
|
||||
do {
|
||||
ut_ad(tmp_ok || *index1->name != TEMP_INDEX_PREFIX);
|
||||
|
||||
index2 = UT_LIST_GET_NEXT(indexes, index1);
|
||||
|
||||
while (index2) {
|
||||
|
||||
|
@ -4871,8 +4931,7 @@ dict_table_check_for_dup_indexes(
|
|||
}
|
||||
|
||||
index1 = UT_LIST_GET_NEXT(indexes, index1);
|
||||
index2 = UT_LIST_GET_NEXT(indexes, index1);
|
||||
}
|
||||
} while (index1);
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
|
@ -4925,6 +4984,10 @@ dict_close(void)
|
|||
|
||||
mem_free(dict_sys);
|
||||
dict_sys = NULL;
|
||||
|
||||
for (i = 0; i < DICT_INDEX_STAT_MUTEX_SIZE; i++) {
|
||||
mutex_free(&dict_index_stat_mutex[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
|
@ -4939,7 +5002,7 @@ dict_table_set_corrupt_by_space(
|
|||
dict_table_t* table;
|
||||
ibool found = FALSE;
|
||||
|
||||
ut_a(space_id != 0 && space_id < SRV_LOG_SPACE_FIRST_ID);
|
||||
ut_a(!trx_sys_sys_space(space_id) && space_id < SRV_LOG_SPACE_FIRST_ID);
|
||||
|
||||
if (need_mutex)
|
||||
mutex_enter(&(dict_sys->mutex));
|
||||
|
|
119
dict/dict0load.c
119
dict/dict0load.c
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -260,7 +260,7 @@ dict_sys_tables_get_flags(
|
|||
return(0);
|
||||
}
|
||||
|
||||
field = rec_get_nth_field_old(rec, 4, &len);
|
||||
field = rec_get_nth_field_old(rec, 4/*N_COLS*/, &len);
|
||||
n_cols = mach_read_from_4(field);
|
||||
|
||||
if (UNIV_UNLIKELY(!(n_cols & 0x80000000UL))) {
|
||||
|
@ -390,15 +390,35 @@ loop:
|
|||
|
||||
mtr_commit(&mtr);
|
||||
|
||||
if (space_id != 0 && in_crash_recovery) {
|
||||
if (trx_sys_sys_space(space_id)) {
|
||||
/* The system tablespace always exists. */
|
||||
} else if (in_crash_recovery) {
|
||||
/* Check that the tablespace (the .ibd file) really
|
||||
exists; print a warning to the .err log if not */
|
||||
exists; print a warning to the .err log if not.
|
||||
Do not print warnings for temporary tables. */
|
||||
ibool is_temp;
|
||||
|
||||
fil_space_for_table_exists_in_mem(space_id, name,
|
||||
FALSE, TRUE, TRUE);
|
||||
}
|
||||
field = rec_get_nth_field_old(rec, 4, &len);
|
||||
if (0x80000000UL & mach_read_from_4(field)) {
|
||||
/* ROW_FORMAT=COMPACT: read the is_temp
|
||||
flag from SYS_TABLES.MIX_LEN. */
|
||||
field = rec_get_nth_field_old(rec, 7, &len);
|
||||
is_temp = mach_read_from_4(field)
|
||||
& DICT_TF2_TEMPORARY;
|
||||
} else {
|
||||
/* For tables created with old versions
|
||||
of InnoDB, SYS_TABLES.MIX_LEN may contain
|
||||
garbage. Such tables would always be
|
||||
in ROW_FORMAT=REDUNDANT. Pretend that
|
||||
all such tables are non-temporary. That is,
|
||||
do not suppress error printouts about
|
||||
temporary tables not being found. */
|
||||
is_temp = FALSE;
|
||||
}
|
||||
|
||||
if (space_id != 0 && !in_crash_recovery) {
|
||||
fil_space_for_table_exists_in_mem(
|
||||
space_id, name, is_temp, TRUE, !is_temp);
|
||||
} else {
|
||||
/* It is a normal database startup: create the space
|
||||
object and check that the .ibd file exists. */
|
||||
|
||||
|
@ -878,7 +898,7 @@ err_exit:
|
|||
space = mach_read_from_4(field);
|
||||
|
||||
/* Check if the tablespace exists and has the right name */
|
||||
if (space != 0) {
|
||||
if (!trx_sys_sys_space(space)) {
|
||||
flags = dict_sys_tables_get_flags(rec);
|
||||
|
||||
if (UNIV_UNLIKELY(flags == ULINT_UNDEFINED)) {
|
||||
|
@ -894,31 +914,6 @@ err_exit:
|
|||
(ulong) flags);
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
if (fil_space_for_table_exists_in_mem(space, name, FALSE,
|
||||
FALSE, FALSE)) {
|
||||
/* Ok; (if we did a crash recovery then the tablespace
|
||||
can already be in the memory cache) */
|
||||
} else {
|
||||
/* In >= 4.1.9, InnoDB scans the data dictionary also
|
||||
at a normal mysqld startup. It is an error if the
|
||||
space object does not exist in memory. */
|
||||
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr,
|
||||
" InnoDB: error: space object of table %s,\n"
|
||||
"InnoDB: space id %lu did not exist in memory."
|
||||
" Retrying an open.\n",
|
||||
name, (ulong)space);
|
||||
/* Try to open the tablespace */
|
||||
if (!fil_open_single_table_tablespace(
|
||||
TRUE, space, flags, name)) {
|
||||
/* We failed to find a sensible tablespace
|
||||
file */
|
||||
|
||||
ibd_file_missing = TRUE;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
flags = 0;
|
||||
}
|
||||
|
@ -928,9 +923,63 @@ err_exit:
|
|||
field = rec_get_nth_field_old(rec, 4, &len);
|
||||
n_cols = mach_read_from_4(field);
|
||||
|
||||
/* The high-order bit of N_COLS is the "compact format" flag. */
|
||||
/* The high-order bit of N_COLS is the "compact format" flag.
|
||||
For tables in that format, MIX_LEN may hold additional flags. */
|
||||
if (n_cols & 0x80000000UL) {
|
||||
ulint flags2;
|
||||
|
||||
flags |= DICT_TF_COMPACT;
|
||||
|
||||
ut_a(name_of_col_is(sys_tables, sys_index, 7, "MIX_LEN"));
|
||||
field = rec_get_nth_field_old(rec, 7, &len);
|
||||
|
||||
flags2 = mach_read_from_4(field);
|
||||
|
||||
if (flags2 & (~0 << (DICT_TF2_BITS - DICT_TF2_SHIFT))) {
|
||||
ut_print_timestamp(stderr);
|
||||
fputs(" InnoDB: Warning: table ", stderr);
|
||||
ut_print_filename(stderr, name);
|
||||
fprintf(stderr, "\n"
|
||||
"InnoDB: in InnoDB data dictionary"
|
||||
" has unknown flags %lx.\n",
|
||||
(ulong) flags2);
|
||||
|
||||
flags2 &= ~(~0 << (DICT_TF2_BITS - DICT_TF2_SHIFT));
|
||||
}
|
||||
|
||||
flags |= flags2 << DICT_TF2_SHIFT;
|
||||
}
|
||||
|
||||
/* See if the tablespace is available. */
|
||||
if (trx_sys_sys_space(space)) {
|
||||
/* The system tablespace is always available. */
|
||||
} else if (!fil_space_for_table_exists_in_mem(
|
||||
space, name,
|
||||
(flags >> DICT_TF2_SHIFT) & DICT_TF2_TEMPORARY,
|
||||
FALSE, FALSE)) {
|
||||
|
||||
if ((flags >> DICT_TF2_SHIFT) & DICT_TF2_TEMPORARY) {
|
||||
/* Do not bother to retry opening temporary tables. */
|
||||
ibd_file_missing = TRUE;
|
||||
} else {
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr,
|
||||
" InnoDB: error: space object of table");
|
||||
ut_print_filename(stderr, name);
|
||||
fprintf(stderr, ",\n"
|
||||
"InnoDB: space id %lu did not exist in memory."
|
||||
" Retrying an open.\n",
|
||||
(ulong) space);
|
||||
/* Try to open the tablespace */
|
||||
if (!fil_open_single_table_tablespace(
|
||||
TRUE, space,
|
||||
flags & ~(~0 << DICT_TF_BITS), name)) {
|
||||
/* We failed to find a sensible
|
||||
tablespace file */
|
||||
|
||||
ibd_file_missing = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
table = dict_mem_table_create(name, space, n_cols & ~0x80000000UL,
|
||||
|
|
|
@ -59,7 +59,7 @@ dict_mem_table_create(
|
|||
mem_heap_t* heap;
|
||||
|
||||
ut_ad(name);
|
||||
ut_a(!(flags & (~0 << DICT_TF_BITS)));
|
||||
ut_a(!(flags & (~0 << DICT_TF2_BITS)));
|
||||
|
||||
heap = mem_heap_create(DICT_HEAP_SIZE);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -38,6 +38,7 @@ Created 10/25/1995 Heikki Tuuri
|
|||
#include "mtr0mtr.h"
|
||||
#include "mtr0log.h"
|
||||
#include "dict0dict.h"
|
||||
#include "page0page.h"
|
||||
#include "page0zip.h"
|
||||
#include "trx0trx.h"
|
||||
#include "trx0sys.h"
|
||||
|
@ -673,14 +674,14 @@ fil_node_open_file(
|
|||
size_bytes = (((ib_int64_t)size_high) << 32)
|
||||
+ (ib_int64_t)size_low;
|
||||
#ifdef UNIV_HOTBACKUP
|
||||
if (space->id == 0) {
|
||||
if (trx_sys_sys_space(space->id)) {
|
||||
node->size = (ulint) (size_bytes / UNIV_PAGE_SIZE);
|
||||
os_file_close(node->handle);
|
||||
goto add_size;
|
||||
}
|
||||
#endif /* UNIV_HOTBACKUP */
|
||||
ut_a(space->purpose != FIL_LOG);
|
||||
ut_a(space->id != 0);
|
||||
ut_a(!trx_sys_sys_space(space->id));
|
||||
|
||||
if (size_bytes < FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE) {
|
||||
fprintf(stderr,
|
||||
|
@ -726,7 +727,7 @@ fil_node_open_file(
|
|||
}
|
||||
|
||||
if (UNIV_UNLIKELY(space_id == ULINT_UNDEFINED
|
||||
|| space_id == 0)) {
|
||||
|| trx_sys_sys_space(space_id))) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error: tablespace id %lu"
|
||||
" in file %s is not sensible\n",
|
||||
|
@ -788,7 +789,7 @@ add_size:
|
|||
|
||||
system->n_open++;
|
||||
|
||||
if (space->purpose == FIL_TABLESPACE && space->id != 0) {
|
||||
if (space->purpose == FIL_TABLESPACE && !trx_sys_sys_space(space->id)) {
|
||||
/* Put the node to the LRU list */
|
||||
UT_LIST_ADD_FIRST(LRU, system->LRU, node);
|
||||
}
|
||||
|
@ -821,7 +822,7 @@ fil_node_close_file(
|
|||
ut_a(system->n_open > 0);
|
||||
system->n_open--;
|
||||
|
||||
if (node->space->purpose == FIL_TABLESPACE && node->space->id != 0) {
|
||||
if (node->space->purpose == FIL_TABLESPACE && !trx_sys_sys_space(node->space->id)) {
|
||||
ut_a(UT_LIST_GET_LEN(system->LRU) > 0);
|
||||
|
||||
/* The node is in the LRU list, remove it */
|
||||
|
@ -907,7 +908,7 @@ fil_mutex_enter_and_prepare_for_io(
|
|||
retry:
|
||||
mutex_enter(&fil_system->mutex);
|
||||
|
||||
if (space_id == 0 || space_id >= SRV_LOG_SPACE_FIRST_ID) {
|
||||
if (trx_sys_sys_space(space_id) || space_id >= SRV_LOG_SPACE_FIRST_ID) {
|
||||
/* We keep log files and system tablespace files always open;
|
||||
this is important in preventing deadlocks in this module, as
|
||||
a page read completion often performs another read from the
|
||||
|
@ -1102,10 +1103,13 @@ fil_space_create(
|
|||
fil_space_t* space;
|
||||
|
||||
/* The tablespace flags (FSP_SPACE_FLAGS) should be 0 for
|
||||
ROW_FORMAT=COMPACT (table->flags == DICT_TF_COMPACT) and
|
||||
ROW_FORMAT=COMPACT
|
||||
((table->flags & ~(~0 << DICT_TF_BITS)) == DICT_TF_COMPACT) and
|
||||
ROW_FORMAT=REDUNDANT (table->flags == 0). For any other
|
||||
format, the tablespace flags should equal table->flags. */
|
||||
format, the tablespace flags should equal
|
||||
(table->flags & ~(~0 << DICT_TF_BITS)). */
|
||||
ut_a(flags != DICT_TF_COMPACT);
|
||||
ut_a(!(flags & (~0UL << DICT_TF_BITS)));
|
||||
|
||||
try_again:
|
||||
/*printf(
|
||||
|
@ -1134,7 +1138,7 @@ try_again:
|
|||
" tablespace memory cache!\n",
|
||||
(ulong) space->id);
|
||||
|
||||
if (id == 0 || purpose != FIL_TABLESPACE) {
|
||||
if (trx_sys_sys_space(id) || purpose != FIL_TABLESPACE) {
|
||||
|
||||
mutex_exit(&fil_system->mutex);
|
||||
|
||||
|
@ -1528,7 +1532,7 @@ fil_init(
|
|||
fil_system->max_n_open = max_n_open;
|
||||
|
||||
fil_system->modification_counter = 0;
|
||||
fil_system->max_assigned_id = 0;
|
||||
fil_system->max_assigned_id = TRX_SYS_SPACE_MAX;
|
||||
|
||||
fil_system->tablespace_version = 0;
|
||||
|
||||
|
@ -1555,7 +1559,7 @@ fil_open_log_and_system_tablespace_files(void)
|
|||
space = UT_LIST_GET_FIRST(fil_system->space_list);
|
||||
|
||||
while (space != NULL) {
|
||||
if (space->purpose != FIL_TABLESPACE || space->id == 0) {
|
||||
if (space->purpose != FIL_TABLESPACE || trx_sys_sys_space(space->id)) {
|
||||
node = UT_LIST_GET_FIRST(space->chain);
|
||||
|
||||
while (node != NULL) {
|
||||
|
@ -2589,10 +2593,13 @@ fil_create_new_single_table_tablespace(
|
|||
|
||||
ut_a(size >= FIL_IBD_FILE_INITIAL_SIZE);
|
||||
/* The tablespace flags (FSP_SPACE_FLAGS) should be 0 for
|
||||
ROW_FORMAT=COMPACT (table->flags == DICT_TF_COMPACT) and
|
||||
ROW_FORMAT=COMPACT
|
||||
((table->flags & ~(~0 << DICT_TF_BITS)) == DICT_TF_COMPACT) and
|
||||
ROW_FORMAT=REDUNDANT (table->flags == 0). For any other
|
||||
format, the tablespace flags should equal table->flags. */
|
||||
format, the tablespace flags should equal
|
||||
(table->flags & ~(~0 << DICT_TF_BITS)). */
|
||||
ut_a(flags != DICT_TF_COMPACT);
|
||||
ut_a(!(flags & (~0UL << DICT_TF_BITS)));
|
||||
|
||||
path = fil_make_ibd_name(tablename, is_temp);
|
||||
|
||||
|
@ -2793,6 +2800,7 @@ fil_reset_too_high_lsns(
|
|||
ib_int64_t offset;
|
||||
ulint zip_size;
|
||||
ibool success;
|
||||
page_zip_des_t page_zip;
|
||||
|
||||
filepath = fil_make_ibd_name(name, FALSE);
|
||||
|
||||
|
@ -2840,6 +2848,12 @@ fil_reset_too_high_lsns(
|
|||
space_id = fsp_header_get_space_id(page);
|
||||
zip_size = fsp_header_get_zip_size(page);
|
||||
|
||||
page_zip_des_init(&page_zip);
|
||||
page_zip_set_size(&page_zip, zip_size);
|
||||
if (zip_size) {
|
||||
page_zip.data = page + UNIV_PAGE_SIZE;
|
||||
}
|
||||
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr,
|
||||
" InnoDB: Flush lsn in the tablespace file %lu"
|
||||
|
@ -2874,20 +2888,23 @@ fil_reset_too_high_lsns(
|
|||
/* We have to reset the lsn */
|
||||
|
||||
if (zip_size) {
|
||||
memcpy(page + UNIV_PAGE_SIZE, page, zip_size);
|
||||
memcpy(page_zip.data, page, zip_size);
|
||||
buf_flush_init_for_writing(
|
||||
page, page + UNIV_PAGE_SIZE,
|
||||
current_lsn);
|
||||
page, &page_zip, current_lsn);
|
||||
success = os_file_write(
|
||||
filepath, file, page_zip.data,
|
||||
(ulint) offset & 0xFFFFFFFFUL,
|
||||
(ulint) (offset >> 32), zip_size);
|
||||
} else {
|
||||
buf_flush_init_for_writing(
|
||||
page, NULL, current_lsn);
|
||||
success = os_file_write(
|
||||
filepath, file, page,
|
||||
(ulint)(offset & 0xFFFFFFFFUL),
|
||||
(ulint)(offset >> 32),
|
||||
UNIV_PAGE_SIZE);
|
||||
}
|
||||
success = os_file_write(filepath, file, page,
|
||||
(ulint)(offset & 0xFFFFFFFFUL),
|
||||
(ulint)(offset >> 32),
|
||||
zip_size
|
||||
? zip_size
|
||||
: UNIV_PAGE_SIZE);
|
||||
|
||||
if (!success) {
|
||||
|
||||
goto func_exit;
|
||||
|
@ -2963,10 +2980,13 @@ fil_open_single_table_tablespace(
|
|||
filepath = fil_make_ibd_name(name, FALSE);
|
||||
|
||||
/* The tablespace flags (FSP_SPACE_FLAGS) should be 0 for
|
||||
ROW_FORMAT=COMPACT (table->flags == DICT_TF_COMPACT) and
|
||||
ROW_FORMAT=COMPACT
|
||||
((table->flags & ~(~0 << DICT_TF_BITS)) == DICT_TF_COMPACT) and
|
||||
ROW_FORMAT=REDUNDANT (table->flags == 0). For any other
|
||||
format, the tablespace flags should equal table->flags. */
|
||||
format, the tablespace flags should equal
|
||||
(table->flags & ~(~0 << DICT_TF_BITS)). */
|
||||
ut_a(flags != DICT_TF_COMPACT);
|
||||
ut_a(!(flags & (~0UL << DICT_TF_BITS)));
|
||||
|
||||
file = os_file_create_simple_no_error_handling(
|
||||
filepath, OS_FILE_OPEN, OS_FILE_READ_WRITE, &success);
|
||||
|
@ -3016,7 +3036,8 @@ fil_open_single_table_tablespace(
|
|||
space_id = fsp_header_get_space_id(page);
|
||||
space_flags = fsp_header_get_flags(page);
|
||||
|
||||
if (srv_expand_import && (space_id != id || space_flags != flags)) {
|
||||
if (srv_expand_import
|
||||
&& (space_id != id || space_flags != (flags & ~(~0 << DICT_TF_BITS)))) {
|
||||
dulint old_id[31];
|
||||
dulint new_id[31];
|
||||
ulint root_page[31];
|
||||
|
@ -3357,7 +3378,8 @@ skip_write:
|
|||
|
||||
ut_free(buf2);
|
||||
|
||||
if (UNIV_UNLIKELY(space_id != id || space_flags != flags)) {
|
||||
if (UNIV_UNLIKELY(space_id != id
|
||||
|| space_flags != (flags & ~(~0 << DICT_TF_BITS)))) {
|
||||
ut_print_timestamp(stderr);
|
||||
|
||||
fputs(" InnoDB: Error: tablespace id and flags in file ",
|
||||
|
@ -3596,7 +3618,7 @@ fil_load_single_table_tablespace(
|
|||
}
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
if (space_id == ULINT_UNDEFINED || space_id == 0) {
|
||||
if (space_id == ULINT_UNDEFINED || trx_sys_sys_space(space_id)) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error: tablespace id %lu in file %s"
|
||||
" is not sensible\n",
|
||||
|
@ -3605,7 +3627,7 @@ fil_load_single_table_tablespace(
|
|||
goto func_exit;
|
||||
}
|
||||
#else
|
||||
if (space_id == ULINT_UNDEFINED || space_id == 0) {
|
||||
if (space_id == ULINT_UNDEFINED || trx_sys_sys_space(space_id)) {
|
||||
char* new_path;
|
||||
|
||||
fprintf(stderr,
|
||||
|
@ -3884,7 +3906,7 @@ fil_print_orphaned_tablespaces(void)
|
|||
space = UT_LIST_GET_FIRST(fil_system->space_list);
|
||||
|
||||
while (space) {
|
||||
if (space->purpose == FIL_TABLESPACE && space->id != 0
|
||||
if (space->purpose == FIL_TABLESPACE && !trx_sys_sys_space(space->id)
|
||||
&& !space->mark) {
|
||||
fputs("InnoDB: Warning: tablespace ", stderr);
|
||||
ut_print_filename(stderr, space->name);
|
||||
|
@ -4459,7 +4481,7 @@ fil_node_prepare_for_io(
|
|||
}
|
||||
|
||||
if (node->n_pending == 0 && space->purpose == FIL_TABLESPACE
|
||||
&& space->id != 0) {
|
||||
&& !trx_sys_sys_space(space->id)) {
|
||||
/* The node is in the LRU list, remove it */
|
||||
|
||||
ut_a(UT_LIST_GET_LEN(system->LRU) > 0);
|
||||
|
@ -4505,7 +4527,7 @@ fil_node_complete_io(
|
|||
}
|
||||
|
||||
if (node->n_pending == 0 && node->space->purpose == FIL_TABLESPACE
|
||||
&& node->space->id != 0) {
|
||||
&& !trx_sys_sys_space(node->space->id)) {
|
||||
/* The node must be put back to the LRU list */
|
||||
UT_LIST_ADD_FIRST(LRU, system->LRU, node);
|
||||
}
|
||||
|
@ -5136,7 +5158,7 @@ fil_validate(void)
|
|||
ut_a(fil_node->n_pending == 0);
|
||||
ut_a(fil_node->open);
|
||||
ut_a(fil_node->space->purpose == FIL_TABLESPACE);
|
||||
ut_a(fil_node->space->id != 0);
|
||||
ut_a(!trx_sys_sys_space(fil_node->space->id));
|
||||
|
||||
fil_node = UT_LIST_GET_NEXT(LRU, fil_node);
|
||||
}
|
||||
|
@ -5218,8 +5240,10 @@ void
|
|||
fil_close(void)
|
||||
/*===========*/
|
||||
{
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
/* The mutex should already have been freed. */
|
||||
ut_ad(fil_system->mutex.magic_n == 0);
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
|
||||
hash_table_free(fil_system->spaces);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -48,7 +48,7 @@ Created 11/29/1995 Heikki Tuuri
|
|||
# include "log0log.h"
|
||||
#endif /* UNIV_HOTBACKUP */
|
||||
#include "dict0mem.h"
|
||||
|
||||
#include "trx0sys.h"
|
||||
|
||||
#define FSP_HEADER_OFFSET FIL_PAGE_DATA /* Offset of the space header
|
||||
within a file page */
|
||||
|
@ -392,11 +392,11 @@ UNIV_INLINE
|
|||
ibool
|
||||
xdes_get_bit(
|
||||
/*=========*/
|
||||
xdes_t* descr, /*!< in: descriptor */
|
||||
ulint bit, /*!< in: XDES_FREE_BIT or XDES_CLEAN_BIT */
|
||||
ulint offset, /*!< in: page offset within extent:
|
||||
0 ... FSP_EXTENT_SIZE - 1 */
|
||||
mtr_t* mtr) /*!< in: mtr */
|
||||
const xdes_t* descr, /*!< in: descriptor */
|
||||
ulint bit, /*!< in: XDES_FREE_BIT or XDES_CLEAN_BIT */
|
||||
ulint offset, /*!< in: page offset within extent:
|
||||
0 ... FSP_EXTENT_SIZE - 1 */
|
||||
mtr_t* mtr) /*!< in: mtr */
|
||||
{
|
||||
ulint index;
|
||||
ulint byte_index;
|
||||
|
@ -533,8 +533,8 @@ UNIV_INLINE
|
|||
ulint
|
||||
xdes_get_n_used(
|
||||
/*============*/
|
||||
xdes_t* descr, /*!< in: descriptor */
|
||||
mtr_t* mtr) /*!< in: mtr */
|
||||
const xdes_t* descr, /*!< in: descriptor */
|
||||
mtr_t* mtr) /*!< in: mtr */
|
||||
{
|
||||
ulint i;
|
||||
ulint count = 0;
|
||||
|
@ -557,8 +557,8 @@ UNIV_INLINE
|
|||
ibool
|
||||
xdes_is_free(
|
||||
/*=========*/
|
||||
xdes_t* descr, /*!< in: descriptor */
|
||||
mtr_t* mtr) /*!< in: mtr */
|
||||
const xdes_t* descr, /*!< in: descriptor */
|
||||
mtr_t* mtr) /*!< in: mtr */
|
||||
{
|
||||
if (0 == xdes_get_n_used(descr, mtr)) {
|
||||
|
||||
|
@ -575,8 +575,8 @@ UNIV_INLINE
|
|||
ibool
|
||||
xdes_is_full(
|
||||
/*=========*/
|
||||
xdes_t* descr, /*!< in: descriptor */
|
||||
mtr_t* mtr) /*!< in: mtr */
|
||||
const xdes_t* descr, /*!< in: descriptor */
|
||||
mtr_t* mtr) /*!< in: mtr */
|
||||
{
|
||||
if (FSP_EXTENT_SIZE == xdes_get_n_used(descr, mtr)) {
|
||||
|
||||
|
@ -592,7 +592,7 @@ UNIV_INLINE
|
|||
void
|
||||
xdes_set_state(
|
||||
/*===========*/
|
||||
xdes_t* descr, /*!< in: descriptor */
|
||||
xdes_t* descr, /*!< in/out: descriptor */
|
||||
ulint state, /*!< in: state to set */
|
||||
mtr_t* mtr) /*!< in: mtr handle */
|
||||
{
|
||||
|
@ -611,8 +611,8 @@ UNIV_INLINE
|
|||
ulint
|
||||
xdes_get_state(
|
||||
/*===========*/
|
||||
xdes_t* descr, /*!< in: descriptor */
|
||||
mtr_t* mtr) /*!< in: mtr handle */
|
||||
const xdes_t* descr, /*!< in: descriptor */
|
||||
mtr_t* mtr) /*!< in: mtr handle */
|
||||
{
|
||||
ulint state;
|
||||
|
||||
|
@ -712,7 +712,7 @@ UNIV_INLINE
|
|||
xdes_t*
|
||||
xdes_get_descriptor_with_space_hdr(
|
||||
/*===============================*/
|
||||
fsp_header_t* sp_header,/*!< in: space header, x-latched */
|
||||
fsp_header_t* sp_header,/*!< in/out: space header, x-latched */
|
||||
ulint space, /*!< in: space id */
|
||||
ulint offset, /*!< in: page offset;
|
||||
if equal to the free limit,
|
||||
|
@ -882,9 +882,7 @@ fsp_init_file_page_low(
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef UNIV_BASIC_LOG_DEBUG
|
||||
memset(page, 0xff, UNIV_PAGE_SIZE);
|
||||
#endif
|
||||
UNIV_MEM_INVALID(page, UNIV_PAGE_SIZE);
|
||||
mach_write_to_4(page + FIL_PAGE_OFFSET, buf_block_get_page_no(block));
|
||||
memset(page + FIL_PAGE_LSN, 0, 8);
|
||||
mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID,
|
||||
|
@ -1017,10 +1015,10 @@ fsp_header_init(
|
|||
flst_init(header + FSP_SEG_INODES_FREE, mtr);
|
||||
|
||||
mlog_write_dulint(header + FSP_SEG_ID, ut_dulint_create(0, 1), mtr);
|
||||
if (space == 0) {
|
||||
if (space == TRX_SYS_SPACE || space == TRX_DOUBLEWRITE_SPACE) {
|
||||
fsp_fill_free_list(FALSE, space, header, mtr);
|
||||
btr_create(DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF,
|
||||
0, 0, ut_dulint_add(DICT_IBUF_ID_MIN, space),
|
||||
space, 0, ut_dulint_add(DICT_IBUF_ID_MIN, space),
|
||||
dict_ind_redundant, mtr);
|
||||
} else {
|
||||
fsp_fill_free_list(TRUE, space, header, mtr);
|
||||
|
@ -1355,7 +1353,7 @@ fsp_fill_free_list(
|
|||
descriptor page and ibuf bitmap page;
|
||||
then we do not allocate more extents */
|
||||
ulint space, /*!< in: space */
|
||||
fsp_header_t* header, /*!< in: space header */
|
||||
fsp_header_t* header, /*!< in/out: space header */
|
||||
mtr_t* mtr) /*!< in: mtr */
|
||||
{
|
||||
ulint limit;
|
||||
|
|
16
ha/ha0ha.c
16
ha/ha0ha.c
|
@ -101,6 +101,8 @@ ha_clear(
|
|||
ulint i;
|
||||
ulint n;
|
||||
|
||||
ut_ad(table);
|
||||
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EXCLUSIVE));
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
@ -146,7 +148,9 @@ ha_insert_for_fold_func(
|
|||
ha_node_t* prev_node;
|
||||
ulint hash;
|
||||
|
||||
ut_ad(table && data);
|
||||
ut_ad(data);
|
||||
ut_ad(table);
|
||||
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
|
||||
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
|
||||
ut_a(block->frame == page_align(data));
|
||||
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
|
||||
|
@ -237,6 +241,8 @@ ha_delete_hash_node(
|
|||
hash_table_t* table, /*!< in: hash table */
|
||||
ha_node_t* del_node) /*!< in: node to be deleted */
|
||||
{
|
||||
ut_ad(table);
|
||||
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
|
||||
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
|
||||
# ifndef UNIV_HOTBACKUP
|
||||
if (table->adaptive) {
|
||||
|
@ -267,6 +273,8 @@ ha_search_and_update_if_found_func(
|
|||
{
|
||||
ha_node_t* node;
|
||||
|
||||
ut_ad(table);
|
||||
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
|
||||
ASSERT_HASH_MUTEX_OWN(table, fold);
|
||||
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
|
||||
ut_a(new_block->frame == page_align(new_data));
|
||||
|
@ -304,6 +312,8 @@ ha_remove_all_nodes_to_page(
|
|||
{
|
||||
ha_node_t* node;
|
||||
|
||||
ut_ad(table);
|
||||
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
|
||||
ASSERT_HASH_MUTEX_OWN(table, fold);
|
||||
|
||||
node = ha_chain_get_first(table, fold);
|
||||
|
@ -353,6 +363,8 @@ ha_validate(
|
|||
ibool ok = TRUE;
|
||||
ulint i;
|
||||
|
||||
ut_ad(table);
|
||||
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
|
||||
ut_a(start_index <= end_index);
|
||||
ut_a(start_index < hash_get_n_cells(table));
|
||||
ut_a(end_index < hash_get_n_cells(table));
|
||||
|
@ -404,6 +416,8 @@ builds, see http://bugs.mysql.com/36941 */
|
|||
#endif /* PRINT_USED_CELLS */
|
||||
ulint n_bufs;
|
||||
|
||||
ut_ad(table);
|
||||
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
|
||||
#ifdef PRINT_USED_CELLS
|
||||
for (i = 0; i < hash_get_n_cells(table); i++) {
|
||||
|
||||
|
|
|
@ -119,7 +119,7 @@ hash_create(
|
|||
table->heaps = NULL;
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
table->heap = NULL;
|
||||
table->magic_n = HASH_TABLE_MAGIC_N;
|
||||
ut_d(table->magic_n = HASH_TABLE_MAGIC_N);
|
||||
|
||||
/* Initialize the cell array */
|
||||
hash_table_clear(table);
|
||||
|
@ -135,6 +135,8 @@ hash_table_free(
|
|||
/*============*/
|
||||
hash_table_t* table) /*!< in, own: hash table */
|
||||
{
|
||||
ut_ad(table);
|
||||
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
ut_a(table->mutexes == NULL);
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
|
@ -160,6 +162,8 @@ hash_create_mutexes_func(
|
|||
{
|
||||
ulint i;
|
||||
|
||||
ut_ad(table);
|
||||
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
|
||||
ut_a(n_mutexes > 0);
|
||||
ut_a(ut_is_2pow(n_mutexes));
|
||||
|
||||
|
|
1142
handler/ha_innodb.cc
1142
handler/ha_innodb.cc
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 2000, 2009, MySQL AB & Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 2000, 2010, MySQL AB & Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -27,16 +27,32 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
#pragma interface /* gcc class implementation */
|
||||
#endif
|
||||
|
||||
/* Structure defines translation table between mysql index and innodb
|
||||
index structures */
|
||||
typedef struct innodb_idx_translate_struct {
|
||||
ulint index_count; /*!< number of valid index entries
|
||||
in the index_mapping array */
|
||||
ulint array_size; /*!< array size of index_mapping */
|
||||
dict_index_t** index_mapping; /*!< index pointer array directly
|
||||
maps to index in Innodb from MySQL
|
||||
array index */
|
||||
} innodb_idx_translate_t;
|
||||
|
||||
|
||||
/** InnoDB table share */
|
||||
typedef struct st_innobase_share {
|
||||
THR_LOCK lock; /*!< MySQL lock protecting
|
||||
this structure */
|
||||
const char* table_name; /*!< InnoDB table name */
|
||||
uint use_count; /*!< reference count,
|
||||
incremented in get_share()
|
||||
and decremented in free_share() */
|
||||
void* table_name_hash;/*!< hash table chain node */
|
||||
dict_table_t* ib_table;
|
||||
THR_LOCK lock; /*!< MySQL lock protecting
|
||||
this structure */
|
||||
const char* table_name; /*!< InnoDB table name */
|
||||
uint use_count; /*!< reference count,
|
||||
incremented in get_share()
|
||||
and decremented in
|
||||
free_share() */
|
||||
void* table_name_hash;/*!< hash table chain node */
|
||||
innodb_idx_translate_t idx_trans_tbl; /*!< index translation
|
||||
table between MySQL and
|
||||
Innodb */
|
||||
dict_table_t* ib_table;
|
||||
} INNOBASE_SHARE;
|
||||
|
||||
|
||||
|
@ -92,9 +108,8 @@ class ha_innobase: public handler
|
|||
ulint innobase_reset_autoinc(ulonglong auto_inc);
|
||||
ulint innobase_get_autoinc(ulonglong* value);
|
||||
ulint innobase_update_autoinc(ulonglong auto_inc);
|
||||
ulint innobase_initialize_autoinc();
|
||||
void innobase_initialize_autoinc();
|
||||
dict_index_t* innobase_get_index(uint keynr);
|
||||
ulonglong innobase_get_int_col_max_value(const Field* field);
|
||||
|
||||
/* Init values for the class: */
|
||||
public:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 2005, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 2005, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -229,9 +229,11 @@ static
|
|||
int
|
||||
innobase_check_index_keys(
|
||||
/*======================*/
|
||||
const KEY* key_info, /*!< in: Indexes to be created */
|
||||
ulint num_of_keys) /*!< in: Number of indexes to
|
||||
be created */
|
||||
const KEY* key_info, /*!< in: Indexes to be
|
||||
created */
|
||||
ulint num_of_keys, /*!< in: Number of
|
||||
indexes to be created */
|
||||
const dict_table_t* table) /*!< in: Existing indexes */
|
||||
{
|
||||
ulint key_num;
|
||||
|
||||
|
@ -248,9 +250,22 @@ innobase_check_index_keys(
|
|||
const KEY& key2 = key_info[i];
|
||||
|
||||
if (0 == strcmp(key.name, key2.name)) {
|
||||
sql_print_error("InnoDB: key name `%s` appears"
|
||||
" twice in CREATE INDEX\n",
|
||||
key.name);
|
||||
my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0),
|
||||
key.name);
|
||||
|
||||
return(ER_WRONG_NAME_FOR_INDEX);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check that the same index name does not already exist. */
|
||||
|
||||
for (const dict_index_t* index
|
||||
= dict_table_get_first_index(table);
|
||||
index; index = dict_table_get_next_index(index)) {
|
||||
|
||||
if (0 == strcmp(key.name, index->name)) {
|
||||
my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0),
|
||||
key.name);
|
||||
|
||||
return(ER_WRONG_NAME_FOR_INDEX);
|
||||
}
|
||||
|
@ -258,7 +273,7 @@ innobase_check_index_keys(
|
|||
|
||||
/* Check that MySQL does not try to create a column
|
||||
prefix index field on an inappropriate data type and
|
||||
that the same colum does not appear twice in the index. */
|
||||
that the same column does not appear twice in the index. */
|
||||
|
||||
for (ulint i = 0; i < key.key_parts; i++) {
|
||||
const KEY_PART_INFO& key_part1
|
||||
|
@ -289,14 +304,8 @@ innobase_check_index_keys(
|
|||
}
|
||||
}
|
||||
|
||||
sql_print_error("InnoDB: MySQL is trying to"
|
||||
" create a column prefix"
|
||||
" index field on an"
|
||||
" inappropriate data type."
|
||||
" column `%s`,"
|
||||
" index `%s`.\n",
|
||||
field->field_name,
|
||||
key.name);
|
||||
my_error(ER_WRONG_KEY_COLUMN, MYF(0),
|
||||
field->field_name);
|
||||
return(ER_WRONG_KEY_COLUMN);
|
||||
}
|
||||
|
||||
|
@ -309,11 +318,8 @@ innobase_check_index_keys(
|
|||
continue;
|
||||
}
|
||||
|
||||
sql_print_error("InnoDB: column `%s`"
|
||||
" is not allowed to occur"
|
||||
" twice in index `%s`.\n",
|
||||
key_part1.field->field_name,
|
||||
key.name);
|
||||
my_error(ER_WRONG_KEY_COLUMN, MYF(0),
|
||||
key_part1.field->field_name);
|
||||
return(ER_WRONG_KEY_COLUMN);
|
||||
}
|
||||
}
|
||||
|
@ -522,12 +528,14 @@ innobase_create_key_def(
|
|||
key_info->name, "PRIMARY");
|
||||
|
||||
/* If there is a UNIQUE INDEX consisting entirely of NOT NULL
|
||||
columns, MySQL will treat it as a PRIMARY KEY unless the
|
||||
table already has one. */
|
||||
columns and if the index does not contain column prefix(es)
|
||||
(only prefix/part of the column is indexed), MySQL will treat the
|
||||
index as a PRIMARY KEY unless the table already has one. */
|
||||
|
||||
if (!new_primary && (key_info->flags & HA_NOSAME)
|
||||
&& (!(key_info->flags & HA_KEY_HAS_PART_KEY_SEG))
|
||||
&& row_table_got_default_clust_index(table)) {
|
||||
uint key_part = key_info->key_parts;
|
||||
uint key_part = key_info->key_parts;
|
||||
|
||||
new_primary = TRUE;
|
||||
|
||||
|
@ -656,12 +664,18 @@ ha_innobase::add_index(
|
|||
innodb_table = indexed_table
|
||||
= dict_table_get(prebuilt->table->name, FALSE);
|
||||
|
||||
if (UNIV_UNLIKELY(!innodb_table)) {
|
||||
error = HA_ERR_NO_SUCH_TABLE;
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
/* Check if the index name is reserved. */
|
||||
if (innobase_index_name_is_reserved(trx, key_info, num_of_keys)) {
|
||||
error = -1;
|
||||
} else {
|
||||
/* Check that index keys are sensible */
|
||||
error = innobase_check_index_keys(key_info, num_of_keys);
|
||||
error = innobase_check_index_keys(key_info, num_of_keys,
|
||||
innodb_table);
|
||||
}
|
||||
|
||||
if (UNIV_UNLIKELY(error)) {
|
||||
|
@ -708,6 +722,8 @@ err_exit:
|
|||
row_mysql_lock_data_dictionary(trx);
|
||||
dict_locked = TRUE;
|
||||
|
||||
ut_d(dict_table_check_for_dup_indexes(innodb_table, FALSE));
|
||||
|
||||
/* If a new primary key is defined for the table we need
|
||||
to drop the original table and rebuild all indexes. */
|
||||
|
||||
|
@ -740,6 +756,8 @@ err_exit:
|
|||
user_thd);
|
||||
}
|
||||
|
||||
ut_d(dict_table_check_for_dup_indexes(innodb_table,
|
||||
FALSE));
|
||||
row_mysql_unlock_data_dictionary(trx);
|
||||
goto err_exit;
|
||||
}
|
||||
|
@ -764,6 +782,10 @@ err_exit:
|
|||
|
||||
ut_ad(error == DB_SUCCESS);
|
||||
|
||||
/* We will need to rebuild index translation table. Set
|
||||
valid index entry count in the translation table to zero */
|
||||
share->idx_trans_tbl.index_count = 0;
|
||||
|
||||
/* Commit the data dictionary transaction in order to release
|
||||
the table locks on the system tables. This means that if
|
||||
MySQL crashes while creating a new primary key inside
|
||||
|
@ -799,18 +821,6 @@ err_exit:
|
|||
index, num_of_idx, table);
|
||||
|
||||
error_handling:
|
||||
#ifdef UNIV_DEBUG
|
||||
/* TODO: At the moment we can't handle the following statement
|
||||
in our debugging code below:
|
||||
|
||||
alter table t drop index b, add index (b);
|
||||
|
||||
The fix will have to parse the SQL and note that the index
|
||||
being added has the same name as the one being dropped and
|
||||
ignore that in the dup index check.*/
|
||||
//dict_table_check_for_dup_indexes(prebuilt->table);
|
||||
#endif
|
||||
|
||||
/* After an error, remove all those index definitions from the
|
||||
dictionary which were defined. */
|
||||
|
||||
|
@ -822,6 +832,8 @@ error_handling:
|
|||
row_mysql_lock_data_dictionary(trx);
|
||||
dict_locked = TRUE;
|
||||
|
||||
ut_d(dict_table_check_for_dup_indexes(prebuilt->table, TRUE));
|
||||
|
||||
if (!new_primary) {
|
||||
error = row_merge_rename_indexes(trx, indexed_table);
|
||||
|
||||
|
@ -909,6 +921,7 @@ convert_error:
|
|||
}
|
||||
|
||||
if (dict_locked) {
|
||||
ut_d(dict_table_check_for_dup_indexes(innodb_table, FALSE));
|
||||
row_mysql_unlock_data_dictionary(trx);
|
||||
}
|
||||
|
||||
|
@ -951,6 +964,7 @@ ha_innobase::prepare_drop_index(
|
|||
/* Test and mark all the indexes to be dropped */
|
||||
|
||||
row_mysql_lock_data_dictionary(trx);
|
||||
ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
|
||||
|
||||
/* Check that none of the indexes have previously been flagged
|
||||
for deletion. */
|
||||
|
@ -1116,6 +1130,7 @@ func_exit:
|
|||
} while (index);
|
||||
}
|
||||
|
||||
ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
|
||||
row_mysql_unlock_data_dictionary(trx);
|
||||
|
||||
DBUG_RETURN(err);
|
||||
|
@ -1162,6 +1177,7 @@ ha_innobase::final_drop_index(
|
|||
prebuilt->table->flags, user_thd);
|
||||
|
||||
row_mysql_lock_data_dictionary(trx);
|
||||
ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
|
||||
|
||||
if (UNIV_UNLIKELY(err)) {
|
||||
|
||||
|
@ -1198,11 +1214,12 @@ ha_innobase::final_drop_index(
|
|||
ut_a(!index->to_be_dropped);
|
||||
}
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
dict_table_check_for_dup_indexes(prebuilt->table);
|
||||
#endif
|
||||
/* We will need to rebuild index translation table. Set
|
||||
valid index entry count in the translation table to zero */
|
||||
share->idx_trans_tbl.index_count = 0;
|
||||
|
||||
func_exit:
|
||||
ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
|
||||
trx_commit_for_mysql(trx);
|
||||
trx_commit_for_mysql(prebuilt->trx);
|
||||
row_mysql_unlock_data_dictionary(trx);
|
||||
|
|
|
@ -2900,6 +2900,9 @@ i_s_innodb_index_stats_fill(
|
|||
i_s_table->field[3]->store(index->n_uniq);
|
||||
|
||||
row_per_keys[0] = '\0';
|
||||
|
||||
/* It is remained optimistic operation still for now */
|
||||
//dict_index_stat_mutex_enter(index);
|
||||
if (index->stat_n_diff_key_vals) {
|
||||
for (i = 1; i <= index->n_uniq; i++) {
|
||||
ib_int64_t rec_per_key;
|
||||
|
@ -2913,6 +2916,8 @@ i_s_innodb_index_stats_fill(
|
|||
strncat(row_per_keys, buff, 256 - strlen(row_per_keys));
|
||||
}
|
||||
}
|
||||
//dict_index_stat_mutex_exit(index);
|
||||
|
||||
field_store_string(i_s_table->field[4], row_per_keys);
|
||||
|
||||
i_s_table->field[5]->store(index->stat_index_size);
|
||||
|
@ -3169,6 +3174,14 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_admin_command =
|
|||
|
||||
static ST_FIELD_INFO i_s_innodb_sys_tables_info[] =
|
||||
{
|
||||
{STRUCT_FLD(field_name, "SCHEMA"),
|
||||
STRUCT_FLD(field_length, NAME_LEN),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
|
||||
STRUCT_FLD(value, 0),
|
||||
STRUCT_FLD(field_flags, 0),
|
||||
STRUCT_FLD(old_name, ""),
|
||||
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
|
||||
|
||||
{STRUCT_FLD(field_name, "NAME"),
|
||||
STRUCT_FLD(field_length, NAME_LEN),
|
||||
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
|
||||
|
@ -3325,6 +3338,54 @@ copy_string_field(
|
|||
return status;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
copy_name_fields(
|
||||
/*=============*/
|
||||
TABLE* table,
|
||||
int table_field_1,
|
||||
const rec_t* rec,
|
||||
int rec_field)
|
||||
{
|
||||
int status;
|
||||
const byte* data;
|
||||
ulint len;
|
||||
|
||||
data = rec_get_nth_field_old(rec, rec_field, &len);
|
||||
if (len == UNIV_SQL_NULL) {
|
||||
table->field[table_field_1]->set_null();
|
||||
table->field[table_field_1 + 1]->set_null();
|
||||
status = 0; /* success */
|
||||
} else {
|
||||
char buf[NAME_LEN * 2 + 2];
|
||||
char* ptr;
|
||||
|
||||
if (len > NAME_LEN * 2 + 1) {
|
||||
table->field[table_field_1]->set_null();
|
||||
status = field_store_string(table->field[table_field_1 + 1],
|
||||
"###TOO LONG NAME###");
|
||||
goto end_func;
|
||||
}
|
||||
|
||||
strncpy(buf, (char*)data, len);
|
||||
buf[len] = '\0';
|
||||
ptr = strchr(buf, '/');
|
||||
if (ptr) {
|
||||
*ptr = '\0';
|
||||
++ptr;
|
||||
|
||||
status = field_store_string(table->field[table_field_1], buf);
|
||||
status |= field_store_string(table->field[table_field_1 + 1], ptr);
|
||||
} else {
|
||||
table->field[table_field_1]->set_null();
|
||||
status = field_store_string(table->field[table_field_1 + 1], buf);
|
||||
}
|
||||
}
|
||||
|
||||
end_func:
|
||||
return status;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
copy_int_field(
|
||||
|
@ -3395,49 +3456,49 @@ copy_sys_tables_rec(
|
|||
|
||||
/* NAME */
|
||||
field = dict_index_get_nth_col_pos(index, 0);
|
||||
status = copy_string_field(table, 0, rec, field);
|
||||
status = copy_name_fields(table, 0, rec, field);
|
||||
if (status) {
|
||||
return status;
|
||||
}
|
||||
/* ID */
|
||||
field = dict_index_get_nth_col_pos(index, 1);
|
||||
status = copy_id_field(table, 1, rec, field);
|
||||
status = copy_id_field(table, 2, rec, field);
|
||||
if (status) {
|
||||
return status;
|
||||
}
|
||||
/* N_COLS */
|
||||
field = dict_index_get_nth_col_pos(index, 2);
|
||||
status = copy_int_field(table, 2, rec, field);
|
||||
status = copy_int_field(table, 3, rec, field);
|
||||
if (status) {
|
||||
return status;
|
||||
}
|
||||
/* TYPE */
|
||||
field = dict_index_get_nth_col_pos(index, 3);
|
||||
status = copy_int_field(table, 3, rec, field);
|
||||
status = copy_int_field(table, 4, rec, field);
|
||||
if (status) {
|
||||
return status;
|
||||
}
|
||||
/* MIX_ID */
|
||||
field = dict_index_get_nth_col_pos(index, 4);
|
||||
status = copy_id_field(table, 4, rec, field);
|
||||
status = copy_id_field(table, 5, rec, field);
|
||||
if (status) {
|
||||
return status;
|
||||
}
|
||||
/* MIX_LEN */
|
||||
field = dict_index_get_nth_col_pos(index, 5);
|
||||
status = copy_int_field(table, 5, rec, field);
|
||||
status = copy_int_field(table, 6, rec, field);
|
||||
if (status) {
|
||||
return status;
|
||||
}
|
||||
/* CLUSTER_NAME */
|
||||
field = dict_index_get_nth_col_pos(index, 6);
|
||||
status = copy_string_field(table, 6, rec, field);
|
||||
status = copy_string_field(table, 7, rec, field);
|
||||
if (status) {
|
||||
return status;
|
||||
}
|
||||
/* SPACE */
|
||||
field = dict_index_get_nth_col_pos(index, 7);
|
||||
status = copy_int_field(table, 7, rec, field);
|
||||
status = copy_int_field(table, 8, rec, field);
|
||||
if (status) {
|
||||
return status;
|
||||
}
|
||||
|
|
|
@ -41,8 +41,8 @@ struct innodb_enhancement {
|
|||
{"innodb_admin_command_base","XtraDB specific command interface through i_s","","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
{"innodb_show_lock_name","Show mutex/lock name instead of crated file/line","","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
{"innodb_extend_slow","Extended statistics in slow.log","It is InnoDB-part only. It needs to patch also to mysqld.","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
{"innodb_relax_table_creation","Relax limitation of column size at table creation as builtin InnoDB.","","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
{"innodb_lru_dump_restore","Dump and restore command for content of buffer pool","","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
{"innodb_separate_doublewrite","Add option 'innodb_doublewrite_file' to separate doublewrite dedicated tablespace","","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
{"innodb_pass_corrupt_table","Treat tables as corrupt instead of crash, when meet corrupt blocks","","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
{"innodb_fast_checksum","Using the checksum on 32bit-unit calculation","incompatible for unpatched ver.","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
{"innodb_files_extend","allow >4GB transaction log files, and can vary universal page size of datafiles","incompatible for unpatched ver.","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
|
|
|
@ -733,24 +733,41 @@ page containing the descriptor bits for the file page; the bitmap page
|
|||
is x-latched */
|
||||
static
|
||||
page_t*
|
||||
ibuf_bitmap_get_map_page(
|
||||
/*=====================*/
|
||||
ulint space, /*!< in: space id of the file page */
|
||||
ulint page_no,/*!< in: page number of the file page */
|
||||
ulint zip_size,/*!< in: compressed page size in bytes;
|
||||
0 for uncompressed pages */
|
||||
mtr_t* mtr) /*!< in: mtr */
|
||||
ibuf_bitmap_get_map_page_func(
|
||||
/*==========================*/
|
||||
ulint space, /*!< in: space id of the file page */
|
||||
ulint page_no,/*!< in: page number of the file page */
|
||||
ulint zip_size,/*!< in: compressed page size in bytes;
|
||||
0 for uncompressed pages */
|
||||
const char* file, /*!< in: file name */
|
||||
ulint line, /*!< in: line where called */
|
||||
mtr_t* mtr) /*!< in: mtr */
|
||||
{
|
||||
buf_block_t* block;
|
||||
|
||||
block = buf_page_get(space, zip_size,
|
||||
ibuf_bitmap_page_no_calc(zip_size, page_no),
|
||||
RW_X_LATCH, mtr);
|
||||
block = buf_page_get_gen(space, zip_size,
|
||||
ibuf_bitmap_page_no_calc(zip_size, page_no),
|
||||
RW_X_LATCH, NULL, BUF_GET,
|
||||
file, line, mtr);
|
||||
buf_block_dbg_add_level(block, SYNC_IBUF_BITMAP);
|
||||
|
||||
return(buf_block_get_frame(block));
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Gets the ibuf bitmap page where the bits describing a given file page are
|
||||
stored.
|
||||
@return bitmap page where the file page is mapped, that is, the bitmap
|
||||
page containing the descriptor bits for the file page; the bitmap page
|
||||
is x-latched
|
||||
@param space in: space id of the file page
|
||||
@param page_no in: page number of the file page
|
||||
@param zip_size in: compressed page size in bytes; 0 for uncompressed pages
|
||||
@param mtr in: mini-transaction */
|
||||
#define ibuf_bitmap_get_map_page(space, page_no, zip_size, mtr) \
|
||||
ibuf_bitmap_get_map_page_func(space, page_no, zip_size, \
|
||||
__FILE__, __LINE__, mtr)
|
||||
|
||||
/************************************************************************//**
|
||||
Sets the free bits of the page in the ibuf bitmap. This is done in a separate
|
||||
mini-transaction, hence this operation does not restrict further work to only
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1994, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -193,6 +193,10 @@ btr_leaf_page_release(
|
|||
mtr_t* mtr); /*!< in: mtr */
|
||||
/**************************************************************//**
|
||||
Gets the child node file address in a node pointer.
|
||||
NOTE: the offsets array must contain all offsets for the record since
|
||||
we read the last field according to offsets and assume that it contains
|
||||
the child page number. In other words offsets must have been retrieved
|
||||
with rec_get_offsets(n_fields=ULINT_UNDEFINED).
|
||||
@return child node address */
|
||||
UNIV_INLINE
|
||||
ulint
|
||||
|
@ -317,12 +321,16 @@ Inserts a data tuple to a tree on a non-leaf level. It is assumed
|
|||
that mtr holds an x-latch on the tree. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
btr_insert_on_non_leaf_level(
|
||||
/*=========================*/
|
||||
btr_insert_on_non_leaf_level_func(
|
||||
/*==============================*/
|
||||
dict_index_t* index, /*!< in: index */
|
||||
ulint level, /*!< in: level, must be > 0 */
|
||||
dtuple_t* tuple, /*!< in: the record to be inserted */
|
||||
const char* file, /*!< in: file name */
|
||||
ulint line, /*!< in: line where called */
|
||||
mtr_t* mtr); /*!< in: mtr */
|
||||
# define btr_insert_on_non_leaf_level(i,l,t,m) \
|
||||
btr_insert_on_non_leaf_level_func(i,l,t,__FILE__,__LINE__,m)
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
/****************************************************************//**
|
||||
Sets a record as the predefined minimum record. */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1994, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -257,6 +257,10 @@ btr_page_set_prev(
|
|||
|
||||
/**************************************************************//**
|
||||
Gets the child node file address in a node pointer.
|
||||
NOTE: the offsets array must contain all offsets for the record since
|
||||
we read the last field according to offsets and assume that it contains
|
||||
the child page number. In other words offsets must have been retrieved
|
||||
with rec_get_offsets(n_fields=ULINT_UNDEFINED).
|
||||
@return child node address */
|
||||
UNIV_INLINE
|
||||
ulint
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1994, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -152,29 +152,39 @@ btr_cur_search_to_nth_level(
|
|||
ulint has_search_latch,/*!< in: latch mode the caller
|
||||
currently has on btr_search_latch:
|
||||
RW_S_LATCH, or 0 */
|
||||
const char* file, /*!< in: file name */
|
||||
ulint line, /*!< in: line where called */
|
||||
mtr_t* mtr); /*!< in: mtr */
|
||||
/*****************************************************************//**
|
||||
Opens a cursor at either end of an index. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
btr_cur_open_at_index_side(
|
||||
/*=======================*/
|
||||
btr_cur_open_at_index_side_func(
|
||||
/*============================*/
|
||||
ibool from_left, /*!< in: TRUE if open to the low end,
|
||||
FALSE if to the high end */
|
||||
dict_index_t* index, /*!< in: index */
|
||||
ulint latch_mode, /*!< in: latch mode */
|
||||
btr_cur_t* cursor, /*!< in: cursor */
|
||||
const char* file, /*!< in: file name */
|
||||
ulint line, /*!< in: line where called */
|
||||
mtr_t* mtr); /*!< in: mtr */
|
||||
#define btr_cur_open_at_index_side(f,i,l,c,m) \
|
||||
btr_cur_open_at_index_side_func(f,i,l,c,__FILE__,__LINE__,m)
|
||||
/**********************************************************************//**
|
||||
Positions a cursor at a randomly chosen position within a B-tree. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
btr_cur_open_at_rnd_pos(
|
||||
/*====================*/
|
||||
btr_cur_open_at_rnd_pos_func(
|
||||
/*=========================*/
|
||||
dict_index_t* index, /*!< in: index */
|
||||
ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
|
||||
btr_cur_t* cursor, /*!< in/out: B-tree cursor */
|
||||
const char* file, /*!< in: file name */
|
||||
ulint line, /*!< in: line where called */
|
||||
mtr_t* mtr); /*!< in: mtr */
|
||||
#define btr_cur_open_at_rnd_pos(i,l,c,m) \
|
||||
btr_cur_open_at_rnd_pos_func(i,l,c,__FILE__,__LINE__,m)
|
||||
/*************************************************************//**
|
||||
Tries to perform an insert to a page in an index tree, next to cursor.
|
||||
It is assumed that mtr holds an x-latch on the page. The operation does
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -82,8 +82,8 @@ Initializes and opens a persistent cursor to an index tree. It should be
|
|||
closed with btr_pcur_close. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
btr_pcur_open(
|
||||
/*==========*/
|
||||
btr_pcur_open_func(
|
||||
/*===============*/
|
||||
dict_index_t* index, /*!< in: index */
|
||||
const dtuple_t* tuple, /*!< in: tuple on which search done */
|
||||
ulint mode, /*!< in: PAGE_CUR_L, ...;
|
||||
|
@ -94,14 +94,18 @@ btr_pcur_open(
|
|||
record! */
|
||||
ulint latch_mode,/*!< in: BTR_SEARCH_LEAF, ... */
|
||||
btr_pcur_t* cursor, /*!< in: memory buffer for persistent cursor */
|
||||
const char* file, /*!< in: file name */
|
||||
ulint line, /*!< in: line where called */
|
||||
mtr_t* mtr); /*!< in: mtr */
|
||||
#define btr_pcur_open(i,t,md,l,c,m) \
|
||||
btr_pcur_open_func(i,t,md,l,c,__FILE__,__LINE__,m)
|
||||
/**************************************************************//**
|
||||
Opens an persistent cursor to an index tree without initializing the
|
||||
cursor. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
btr_pcur_open_with_no_init(
|
||||
/*=======================*/
|
||||
btr_pcur_open_with_no_init_func(
|
||||
/*============================*/
|
||||
dict_index_t* index, /*!< in: index */
|
||||
const dtuple_t* tuple, /*!< in: tuple on which search done */
|
||||
ulint mode, /*!< in: PAGE_CUR_L, ...;
|
||||
|
@ -119,7 +123,12 @@ btr_pcur_open_with_no_init(
|
|||
ulint has_search_latch,/*!< in: latch mode the caller
|
||||
currently has on btr_search_latch:
|
||||
RW_S_LATCH, or 0 */
|
||||
const char* file, /*!< in: file name */
|
||||
ulint line, /*!< in: line where called */
|
||||
mtr_t* mtr); /*!< in: mtr */
|
||||
#define btr_pcur_open_with_no_init(ix,t,md,l,cur,has,m) \
|
||||
btr_pcur_open_with_no_init_func(ix,t,md,l,cur,has,__FILE__,__LINE__,m)
|
||||
|
||||
/*****************************************************************//**
|
||||
Opens a persistent cursor at either end of an index. */
|
||||
UNIV_INLINE
|
||||
|
@ -160,8 +169,8 @@ before first in tree. The latching mode must be BTR_SEARCH_LEAF or
|
|||
BTR_MODIFY_LEAF. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
btr_pcur_open_on_user_rec(
|
||||
/*======================*/
|
||||
btr_pcur_open_on_user_rec_func(
|
||||
/*===========================*/
|
||||
dict_index_t* index, /*!< in: index */
|
||||
const dtuple_t* tuple, /*!< in: tuple on which search done */
|
||||
ulint mode, /*!< in: PAGE_CUR_L, ... */
|
||||
|
@ -169,17 +178,25 @@ btr_pcur_open_on_user_rec(
|
|||
BTR_MODIFY_LEAF */
|
||||
btr_pcur_t* cursor, /*!< in: memory buffer for persistent
|
||||
cursor */
|
||||
const char* file, /*!< in: file name */
|
||||
ulint line, /*!< in: line where called */
|
||||
mtr_t* mtr); /*!< in: mtr */
|
||||
#define btr_pcur_open_on_user_rec(i,t,md,l,c,m) \
|
||||
btr_pcur_open_on_user_rec_func(i,t,md,l,c,__FILE__,__LINE__,m)
|
||||
/**********************************************************************//**
|
||||
Positions a cursor at a randomly chosen position within a B-tree. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
btr_pcur_open_at_rnd_pos(
|
||||
/*=====================*/
|
||||
btr_pcur_open_at_rnd_pos_func(
|
||||
/*==========================*/
|
||||
dict_index_t* index, /*!< in: index */
|
||||
ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
|
||||
btr_pcur_t* cursor, /*!< in/out: B-tree pcur */
|
||||
const char* file, /*!< in: file name */
|
||||
ulint line, /*!< in: line where called */
|
||||
mtr_t* mtr); /*!< in: mtr */
|
||||
#define btr_pcur_open_at_rnd_pos(i,l,c,m) \
|
||||
btr_pcur_open_at_rnd_pos_func(i,l,c,__FILE__,__LINE__,m)
|
||||
/**************************************************************//**
|
||||
Frees the possible old_rec_buf buffer of a persistent cursor and sets the
|
||||
latch mode of the persistent cursor to BTR_NO_LATCHES. */
|
||||
|
@ -218,11 +235,15 @@ record and it can be restored on a user record whose ordering fields
|
|||
are identical to the ones of the original user record */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
btr_pcur_restore_position(
|
||||
/*======================*/
|
||||
btr_pcur_restore_position_func(
|
||||
/*===========================*/
|
||||
ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
|
||||
btr_pcur_t* cursor, /*!< in: detached persistent cursor */
|
||||
const char* file, /*!< in: file name */
|
||||
ulint line, /*!< in: line where called */
|
||||
mtr_t* mtr); /*!< in: mtr */
|
||||
#define btr_pcur_restore_position(l,cur,mtr) \
|
||||
btr_pcur_restore_position_func(l,cur,__FILE__,__LINE__,mtr)
|
||||
/**************************************************************//**
|
||||
If the latch mode of the cursor is BTR_LEAF_SEARCH or BTR_LEAF_MODIFY,
|
||||
releases the page latch and bufferfix reserved by the cursor.
|
||||
|
@ -260,20 +281,13 @@ btr_pcur_get_mtr(
|
|||
/*=============*/
|
||||
btr_pcur_t* cursor); /*!< in: persistent cursor */
|
||||
/**************************************************************//**
|
||||
Commits the pcur mtr and sets the pcur latch mode to BTR_NO_LATCHES,
|
||||
Commits the mtr and sets the pcur latch mode to BTR_NO_LATCHES,
|
||||
that is, the cursor becomes detached. If there have been modifications
|
||||
to the page where pcur is positioned, this can be used instead of
|
||||
btr_pcur_release_leaf. Function btr_pcur_store_position should be used
|
||||
before calling this, if restoration of cursor is wanted later. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
btr_pcur_commit(
|
||||
/*============*/
|
||||
btr_pcur_t* pcur); /*!< in: persistent cursor */
|
||||
/**************************************************************//**
|
||||
Differs from btr_pcur_commit in that we can specify the mtr to commit. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
btr_pcur_commit_specify_mtr(
|
||||
/*========================*/
|
||||
btr_pcur_t* pcur, /*!< in: persistent cursor */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -395,30 +395,13 @@ btr_pcur_move_to_next(
|
|||
}
|
||||
|
||||
/**************************************************************//**
|
||||
Commits the pcur mtr and sets the pcur latch mode to BTR_NO_LATCHES,
|
||||
Commits the mtr and sets the pcur latch mode to BTR_NO_LATCHES,
|
||||
that is, the cursor becomes detached. If there have been modifications
|
||||
to the page where pcur is positioned, this can be used instead of
|
||||
btr_pcur_release_leaf. Function btr_pcur_store_position should be used
|
||||
before calling this, if restoration of cursor is wanted later. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
btr_pcur_commit(
|
||||
/*============*/
|
||||
btr_pcur_t* pcur) /*!< in: persistent cursor */
|
||||
{
|
||||
ut_a(pcur->pos_state == BTR_PCUR_IS_POSITIONED);
|
||||
|
||||
pcur->latch_mode = BTR_NO_LATCHES;
|
||||
|
||||
mtr_commit(pcur->mtr);
|
||||
|
||||
pcur->pos_state = BTR_PCUR_WAS_POSITIONED;
|
||||
}
|
||||
|
||||
/**************************************************************//**
|
||||
Differs from btr_pcur_commit in that we can specify the mtr to commit. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
btr_pcur_commit_specify_mtr(
|
||||
/*========================*/
|
||||
btr_pcur_t* pcur, /*!< in: persistent cursor */
|
||||
|
@ -483,8 +466,8 @@ Initializes and opens a persistent cursor to an index tree. It should be
|
|||
closed with btr_pcur_close. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
btr_pcur_open(
|
||||
/*==========*/
|
||||
btr_pcur_open_func(
|
||||
/*===============*/
|
||||
dict_index_t* index, /*!< in: index */
|
||||
const dtuple_t* tuple, /*!< in: tuple on which search done */
|
||||
ulint mode, /*!< in: PAGE_CUR_L, ...;
|
||||
|
@ -495,6 +478,8 @@ btr_pcur_open(
|
|||
record! */
|
||||
ulint latch_mode,/*!< in: BTR_SEARCH_LEAF, ... */
|
||||
btr_pcur_t* cursor, /*!< in: memory buffer for persistent cursor */
|
||||
const char* file, /*!< in: file name */
|
||||
ulint line, /*!< in: line where called */
|
||||
mtr_t* mtr) /*!< in: mtr */
|
||||
{
|
||||
btr_cur_t* btr_cursor;
|
||||
|
@ -511,7 +496,7 @@ btr_pcur_open(
|
|||
btr_cursor = btr_pcur_get_btr_cur(cursor);
|
||||
|
||||
btr_cur_search_to_nth_level(index, 0, tuple, mode, latch_mode,
|
||||
btr_cursor, 0, mtr);
|
||||
btr_cursor, 0, file, line, mtr);
|
||||
cursor->pos_state = BTR_PCUR_IS_POSITIONED;
|
||||
|
||||
cursor->trx_if_known = NULL;
|
||||
|
@ -522,8 +507,8 @@ Opens an persistent cursor to an index tree without initializing the
|
|||
cursor. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
btr_pcur_open_with_no_init(
|
||||
/*=======================*/
|
||||
btr_pcur_open_with_no_init_func(
|
||||
/*============================*/
|
||||
dict_index_t* index, /*!< in: index */
|
||||
const dtuple_t* tuple, /*!< in: tuple on which search done */
|
||||
ulint mode, /*!< in: PAGE_CUR_L, ...;
|
||||
|
@ -541,6 +526,8 @@ btr_pcur_open_with_no_init(
|
|||
ulint has_search_latch,/*!< in: latch mode the caller
|
||||
currently has on btr_search_latch:
|
||||
RW_S_LATCH, or 0 */
|
||||
const char* file, /*!< in: file name */
|
||||
ulint line, /*!< in: line where called */
|
||||
mtr_t* mtr) /*!< in: mtr */
|
||||
{
|
||||
btr_cur_t* btr_cursor;
|
||||
|
@ -553,7 +540,8 @@ btr_pcur_open_with_no_init(
|
|||
btr_cursor = btr_pcur_get_btr_cur(cursor);
|
||||
|
||||
btr_cur_search_to_nth_level(index, 0, tuple, mode, latch_mode,
|
||||
btr_cursor, has_search_latch, mtr);
|
||||
btr_cursor, has_search_latch,
|
||||
file, line, mtr);
|
||||
cursor->pos_state = BTR_PCUR_IS_POSITIONED;
|
||||
|
||||
cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
|
||||
|
@ -600,11 +588,13 @@ btr_pcur_open_at_index_side(
|
|||
Positions a cursor at a randomly chosen position within a B-tree. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
btr_pcur_open_at_rnd_pos(
|
||||
/*=====================*/
|
||||
btr_pcur_open_at_rnd_pos_func(
|
||||
/*==========================*/
|
||||
dict_index_t* index, /*!< in: index */
|
||||
ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
|
||||
btr_pcur_t* cursor, /*!< in/out: B-tree pcur */
|
||||
const char* file, /*!< in: file name */
|
||||
ulint line, /*!< in: line where called */
|
||||
mtr_t* mtr) /*!< in: mtr */
|
||||
{
|
||||
/* Initialize the cursor */
|
||||
|
@ -614,8 +604,9 @@ btr_pcur_open_at_rnd_pos(
|
|||
|
||||
btr_pcur_init(cursor);
|
||||
|
||||
btr_cur_open_at_rnd_pos(index, latch_mode,
|
||||
btr_pcur_get_btr_cur(cursor), mtr);
|
||||
btr_cur_open_at_rnd_pos_func(index, latch_mode,
|
||||
btr_pcur_get_btr_cur(cursor),
|
||||
file, line, mtr);
|
||||
cursor->pos_state = BTR_PCUR_IS_POSITIONED;
|
||||
cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -33,6 +33,7 @@ Created 11/5/1995 Heikki Tuuri
|
|||
#include "hash0hash.h"
|
||||
#include "ut0byte.h"
|
||||
#include "page0types.h"
|
||||
#include "ut0rbt.h"
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
#include "os0proc.h"
|
||||
|
||||
|
@ -202,20 +203,14 @@ with care. */
|
|||
#define buf_page_get_with_no_latch(SP, ZS, OF, MTR) buf_page_get_gen(\
|
||||
SP, ZS, OF, RW_NO_LATCH, NULL,\
|
||||
BUF_GET_NO_LATCH, __FILE__, __LINE__, MTR)
|
||||
/**************************************************************//**
|
||||
NOTE! The following macros should be used instead of
|
||||
buf_page_optimistic_get_func, to improve debugging. Only values RW_S_LATCH and
|
||||
RW_X_LATCH are allowed as LA! */
|
||||
#define buf_page_optimistic_get(LA, BL, MC, MTR) \
|
||||
buf_page_optimistic_get_func(LA, BL, MC, __FILE__, __LINE__, MTR)
|
||||
/********************************************************************//**
|
||||
This is the general function used to get optimistic access to a database
|
||||
page.
|
||||
@return TRUE if success */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
buf_page_optimistic_get_func(
|
||||
/*=========================*/
|
||||
buf_page_optimistic_get(
|
||||
/*====================*/
|
||||
ulint rw_latch,/*!< in: RW_S_LATCH, RW_X_LATCH */
|
||||
buf_block_t* block, /*!< in: guessed block */
|
||||
ib_uint64_t modify_clock,/*!< in: modify clock value if mode is
|
||||
|
@ -1205,15 +1200,21 @@ struct buf_block_struct{
|
|||
rw_lock_t lock; /*!< read-write lock of the buffer
|
||||
frame */
|
||||
unsigned lock_hash_val:32;/*!< hashed value of the page address
|
||||
in the record lock hash table */
|
||||
unsigned check_index_page_at_flush:1;
|
||||
in the record lock hash table;
|
||||
protected by buf_block_t::lock
|
||||
(or buf_block_t::mutex, buf_pool_mutex
|
||||
in buf_page_get_gen(),
|
||||
buf_page_init_for_read()
|
||||
and buf_page_create()) */
|
||||
ibool check_index_page_at_flush;
|
||||
/*!< TRUE if we know that this is
|
||||
an index page, and want the database
|
||||
to check its consistency before flush;
|
||||
note that there may be pages in the
|
||||
buffer pool which are index pages,
|
||||
but this flag is not set because
|
||||
we do not keep track of all pages */
|
||||
we do not keep track of all pages;
|
||||
NOT protected by any mutex */
|
||||
/* @} */
|
||||
/** @name Optimistic search field */
|
||||
/* @{ */
|
||||
|
@ -1379,6 +1380,19 @@ struct buf_pool_struct{
|
|||
/*!< this is in the set state
|
||||
when there is no flush batch
|
||||
of the given type running */
|
||||
ib_rbt_t* flush_rbt; /* !< a red-black tree is used
|
||||
exclusively during recovery to
|
||||
speed up insertions in the
|
||||
flush_list. This tree contains
|
||||
blocks in order of
|
||||
oldest_modification LSN and is
|
||||
kept in sync with the
|
||||
flush_list.
|
||||
Each member of the tree MUST
|
||||
also be on the flush_list.
|
||||
This tree is relevant only in
|
||||
recovery and is set to NULL
|
||||
once the recovery is over. */
|
||||
ulint freed_page_clock;/*!< a sequence number used
|
||||
to count the number of buffer
|
||||
blocks removed from the end of
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 2008, Google Inc.
|
||||
|
||||
Portions of this file contain modifications contributed and copyrighted by
|
||||
|
@ -81,7 +81,7 @@ buf_page_peek_if_too_old(
|
|||
unsigned access_time = buf_page_is_accessed(bpage);
|
||||
|
||||
if (access_time > 0
|
||||
&& (ut_time_ms() - access_time)
|
||||
&& ((ib_uint32_t) (ut_time_ms() - access_time))
|
||||
>= buf_LRU_old_threshold_ms) {
|
||||
return(TRUE);
|
||||
}
|
||||
|
@ -743,6 +743,12 @@ buf_block_get_lock_hash_val(
|
|||
/*========================*/
|
||||
const buf_block_t* block) /*!< in: block */
|
||||
{
|
||||
ut_ad(block);
|
||||
ut_ad(buf_page_in_file(&block->page));
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
ut_ad(rw_lock_own(&(((buf_block_t*) block)->lock), RW_LOCK_EXCLUSIVE)
|
||||
|| rw_lock_own(&(((buf_block_t*) block)->lock), RW_LOCK_SHARED));
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
return(block->lock_hash_val);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -40,6 +40,16 @@ buf_flush_remove(
|
|||
/*=============*/
|
||||
buf_page_t* bpage); /*!< in: pointer to the block in question */
|
||||
/********************************************************************//**
|
||||
Relocates a buffer control block on the flush_list.
|
||||
Note that it is assumed that the contents of bpage has already been
|
||||
copied to dpage. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
buf_flush_relocate_on_flush_list(
|
||||
/*=============================*/
|
||||
buf_page_t* bpage, /*!< in/out: control block being moved */
|
||||
buf_page_t* dpage); /*!< in/out: destination block */
|
||||
/********************************************************************//**
|
||||
Updates the flush system data structures when a write is completed. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
|
@ -140,8 +150,8 @@ how much redo the workload is generating and at what rate. */
|
|||
|
||||
struct buf_flush_stat_struct
|
||||
{
|
||||
ib_uint64_t redo; /**< amount of redo generated. */
|
||||
ulint n_flushed; /**< number of pages flushed. */
|
||||
ib_uint64_t redo; /*!< amount of redo generated. */
|
||||
ulint n_flushed; /*!< number of pages flushed. */
|
||||
};
|
||||
|
||||
/** Statistics for selecting flush rate of dirty pages. */
|
||||
|
@ -176,6 +186,22 @@ buf_flush_validate(void);
|
|||
/*====================*/
|
||||
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
|
||||
|
||||
/******************************************************************//**
|
||||
Initialize the red-black tree to speed up insertions into the flush_list
|
||||
during recovery process. Should be called at the start of recovery
|
||||
process before any page has been read/written. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
buf_flush_init_flush_rbt(void);
|
||||
/*==========================*/
|
||||
|
||||
/******************************************************************//**
|
||||
Frees up the red-black tree. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
buf_flush_free_flush_rbt(void);
|
||||
/*==========================*/
|
||||
|
||||
/** When buf_flush_free_margin is called, it tries to make this many blocks
|
||||
available to replacement in the free list and at the end of the LRU list (to
|
||||
make sure that a read-ahead batch can be read efficiently in a single
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -285,6 +285,10 @@ dtype_new_store_for_order_and_null_size(
|
|||
#endif
|
||||
ulint len;
|
||||
|
||||
ut_ad(type);
|
||||
ut_ad(type->mtype >= DATA_VARCHAR);
|
||||
ut_ad(type->mtype <= DATA_MYSQL);
|
||||
|
||||
buf[0] = (byte)(type->mtype & 0xFFUL);
|
||||
|
||||
if (type->prtype & DATA_BINARY_TYPE) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -137,6 +137,7 @@ clustered index */
|
|||
#define DICT_SYS_INDEXES_PAGE_NO_FIELD 8
|
||||
#define DICT_SYS_INDEXES_SPACE_NO_FIELD 7
|
||||
#define DICT_SYS_INDEXES_TYPE_FIELD 6
|
||||
#define DICT_SYS_INDEXES_NAME_FIELD 4
|
||||
|
||||
/* When a row id which is zero modulo this number (which must be a power of
|
||||
two) is assigned, the field DICT_HDR_ROW_ID on the dictionary header page is
|
||||
|
|
|
@ -928,9 +928,10 @@ UNIV_INTERN
|
|||
void
|
||||
dict_table_check_for_dup_indexes(
|
||||
/*=============================*/
|
||||
const dict_table_t* table); /*!< in: Check for dup indexes
|
||||
const dict_table_t* table, /*!< in: Check for dup indexes
|
||||
in this table */
|
||||
|
||||
ibool tmp_ok);/*!< in: TRUE=allow temporary
|
||||
index names */
|
||||
#endif /* UNIV_DEBUG */
|
||||
/**********************************************************************//**
|
||||
Builds a node pointer out of a physical record and a page number.
|
||||
|
@ -1060,6 +1061,22 @@ UNIV_INTERN
|
|||
void
|
||||
dict_mutex_exit_for_mysql(void);
|
||||
/*===========================*/
|
||||
/**********************************************************************//**
|
||||
Lock the appropriate mutex to protect index->stat_n_diff_key_vals[].
|
||||
index->id is used to pick the right mutex and it should not change
|
||||
before dict_index_stat_mutex_exit() is called on this index. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
dict_index_stat_mutex_enter(
|
||||
/*========================*/
|
||||
const dict_index_t* index); /*!< in: index */
|
||||
/**********************************************************************//**
|
||||
Unlock the appropriate mutex that protects index->stat_n_diff_key_vals[]. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
dict_index_stat_mutex_exit(
|
||||
/*=======================*/
|
||||
const dict_index_t* index); /*!< in: index */
|
||||
/********************************************************************//**
|
||||
Checks if the database name in two table names is the same.
|
||||
@return TRUE if same db name */
|
||||
|
|
|
@ -80,21 +80,39 @@ combination of types */
|
|||
/** File format */
|
||||
/* @{ */
|
||||
#define DICT_TF_FORMAT_SHIFT 5 /* file format */
|
||||
#define DICT_TF_FORMAT_MASK (127 << DICT_TF_FORMAT_SHIFT)
|
||||
#define DICT_TF_FORMAT_MASK \
|
||||
((~(~0 << (DICT_TF_BITS - DICT_TF_FORMAT_SHIFT))) << DICT_TF_FORMAT_SHIFT)
|
||||
#define DICT_TF_FORMAT_51 0 /*!< InnoDB/MySQL up to 5.1 */
|
||||
#define DICT_TF_FORMAT_ZIP 1 /*!< InnoDB plugin for 5.1:
|
||||
compressed tables,
|
||||
new BLOB treatment */
|
||||
/** Maximum supported file format */
|
||||
#define DICT_TF_FORMAT_MAX DICT_TF_FORMAT_ZIP
|
||||
|
||||
/* @} */
|
||||
#define DICT_TF_BITS 6 /*!< number of flag bits */
|
||||
#if (1 << (DICT_TF_BITS - DICT_TF_FORMAT_SHIFT)) <= DICT_TF_FORMAT_MAX
|
||||
# error "DICT_TF_BITS is insufficient for DICT_TF_FORMAT_MAX"
|
||||
#endif
|
||||
/* @} */
|
||||
|
||||
/** @brief Additional table flags.
|
||||
|
||||
These flags will be stored in SYS_TABLES.MIX_LEN. All unused flags
|
||||
will be written as 0. The column may contain garbage for tables
|
||||
created with old versions of InnoDB that only implemented
|
||||
ROW_FORMAT=REDUNDANT. */
|
||||
/* @{ */
|
||||
#define DICT_TF2_SHIFT DICT_TF_BITS
|
||||
/*!< Shift value for
|
||||
table->flags. */
|
||||
#define DICT_TF2_TEMPORARY 1 /*!< TRUE for tables from
|
||||
CREATE TEMPORARY TABLE. */
|
||||
#define DICT_TF2_BITS (DICT_TF2_SHIFT + 1)
|
||||
/*!< Total number of bits
|
||||
in table->flags. */
|
||||
/* @} */
|
||||
|
||||
|
||||
/**********************************************************************//**
|
||||
Creates a table memory object.
|
||||
@return own: table object */
|
||||
|
@ -374,7 +392,7 @@ struct dict_table_struct{
|
|||
unsigned space:32;
|
||||
/*!< space where the clustered index of the
|
||||
table is placed */
|
||||
unsigned flags:DICT_TF_BITS;/*!< DICT_TF_COMPACT, ... */
|
||||
unsigned flags:DICT_TF2_BITS;/*!< DICT_TF_COMPACT, ... */
|
||||
unsigned ibd_file_missing:1;
|
||||
/*!< TRUE if this is in a single-table
|
||||
tablespace and the .ibd file is missing; then
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -110,9 +110,10 @@ extern fil_addr_t fil_addr_null;
|
|||
contents of this field is valid
|
||||
for all uncompressed pages. */
|
||||
#define FIL_PAGE_FILE_FLUSH_LSN 26 /*!< this is only defined for the
|
||||
first page in a data file: the file
|
||||
has been flushed to disk at least up
|
||||
to this lsn */
|
||||
first page in a system tablespace
|
||||
data file (ibdata*, not *.ibd):
|
||||
the file has been flushed to disk
|
||||
at least up to this lsn */
|
||||
#define FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID 34 /*!< starting from 4.1.x this
|
||||
contains the space id of the page */
|
||||
#define FIL_PAGE_DATA 38 /*!< start of the data on the page */
|
||||
|
|
|
@ -434,11 +434,12 @@ struct hash_table_struct {
|
|||
these heaps */
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
mem_heap_t* heap;
|
||||
#ifdef UNIV_DEBUG
|
||||
ulint magic_n;
|
||||
# define HASH_TABLE_MAGIC_N 76561114
|
||||
#endif /* UNIV_DEBUG */
|
||||
};
|
||||
|
||||
#define HASH_TABLE_MAGIC_N 76561114
|
||||
|
||||
#ifndef UNIV_NONINL
|
||||
#include "hash0hash.ic"
|
||||
#endif
|
||||
|
|
|
@ -35,6 +35,8 @@ hash_get_nth_cell(
|
|||
hash_table_t* table, /*!< in: hash table */
|
||||
ulint n) /*!< in: cell index */
|
||||
{
|
||||
ut_ad(table);
|
||||
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
|
||||
ut_ad(n < table->n_cells);
|
||||
|
||||
return(table->array + n);
|
||||
|
@ -48,6 +50,8 @@ hash_table_clear(
|
|||
/*=============*/
|
||||
hash_table_t* table) /*!< in/out: hash table */
|
||||
{
|
||||
ut_ad(table);
|
||||
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
|
||||
memset(table->array, 0x0,
|
||||
table->n_cells * sizeof(*table->array));
|
||||
}
|
||||
|
@ -61,6 +65,8 @@ hash_get_n_cells(
|
|||
/*=============*/
|
||||
hash_table_t* table) /*!< in: table */
|
||||
{
|
||||
ut_ad(table);
|
||||
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
|
||||
return(table->n_cells);
|
||||
}
|
||||
|
||||
|
@ -74,6 +80,8 @@ hash_calc_hash(
|
|||
ulint fold, /*!< in: folded value */
|
||||
hash_table_t* table) /*!< in: hash table */
|
||||
{
|
||||
ut_ad(table);
|
||||
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
|
||||
return(ut_hash_ulint(fold, table->n_cells));
|
||||
}
|
||||
|
||||
|
@ -88,6 +96,8 @@ hash_get_mutex_no(
|
|||
hash_table_t* table, /*!< in: hash table */
|
||||
ulint fold) /*!< in: fold */
|
||||
{
|
||||
ut_ad(table);
|
||||
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
|
||||
ut_ad(ut_is_2pow(table->n_mutexes));
|
||||
return(ut_2pow_remainder(hash_calc_hash(fold, table),
|
||||
table->n_mutexes));
|
||||
|
@ -103,6 +113,8 @@ hash_get_nth_heap(
|
|||
hash_table_t* table, /*!< in: hash table */
|
||||
ulint i) /*!< in: index of the heap */
|
||||
{
|
||||
ut_ad(table);
|
||||
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
|
||||
ut_ad(i < table->n_mutexes);
|
||||
|
||||
return(table->heaps[i]);
|
||||
|
@ -120,6 +132,9 @@ hash_get_heap(
|
|||
{
|
||||
ulint i;
|
||||
|
||||
ut_ad(table);
|
||||
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
|
||||
|
||||
if (table->heap) {
|
||||
return(table->heap);
|
||||
}
|
||||
|
@ -139,6 +154,8 @@ hash_get_nth_mutex(
|
|||
hash_table_t* table, /*!< in: hash table */
|
||||
ulint i) /*!< in: index of the mutex */
|
||||
{
|
||||
ut_ad(table);
|
||||
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
|
||||
ut_ad(i < table->n_mutexes);
|
||||
|
||||
return(table->mutexes + i);
|
||||
|
@ -156,6 +173,9 @@ hash_get_mutex(
|
|||
{
|
||||
ulint i;
|
||||
|
||||
ut_ad(table);
|
||||
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
|
||||
|
||||
i = hash_get_mutex_no(table, fold);
|
||||
|
||||
return(hash_get_nth_mutex(table, i));
|
||||
|
|
|
@ -43,6 +43,7 @@ extern ibool lock_print_waits;
|
|||
#endif /* UNIV_DEBUG */
|
||||
/* Buffer for storing information about the most recent deadlock error */
|
||||
extern FILE* lock_latest_err_file;
|
||||
extern ulint srv_n_lock_deadlock_count;
|
||||
|
||||
/*********************************************************************//**
|
||||
Gets the size of a lock struct.
|
||||
|
@ -613,13 +614,16 @@ lock_rec_print(
|
|||
FILE* file, /*!< in: file where to print */
|
||||
const lock_t* lock); /*!< in: record type lock */
|
||||
/*********************************************************************//**
|
||||
Prints info of locks for all transactions. */
|
||||
Prints info of locks for all transactions.
|
||||
@return FALSE if not able to obtain kernel mutex
|
||||
and exits without printing info */
|
||||
UNIV_INTERN
|
||||
void
|
||||
ibool
|
||||
lock_print_info_summary(
|
||||
/*====================*/
|
||||
FILE* file); /*!< in: file where to print */
|
||||
/*********************************************************************//**
|
||||
FILE* file, /*!< in: file where to print */
|
||||
ibool nowait);/*!< in: whether to wait for the kernel mutex */
|
||||
/*************************************************************************
|
||||
Prints info of locks for each transaction. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
|
|
|
@ -1,23 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||
Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*****************************************************************************/
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 2009, Google Inc.
|
||||
|
||||
Portions of this file contain modifications contributed and copyrighted by
|
||||
|
@ -825,7 +808,17 @@ struct log_struct{
|
|||
written to some log group; for this to
|
||||
be advanced, it is enough that the
|
||||
write i/o has been completed for all
|
||||
log groups */
|
||||
log groups.
|
||||
Note that since InnoDB currently
|
||||
has only one log group therefore
|
||||
this value is redundant. Also it
|
||||
is possible that this value
|
||||
falls behind the
|
||||
flushed_to_disk_lsn transiently.
|
||||
It is appropriate to use either
|
||||
flushed_to_disk_lsn or
|
||||
write_lsn which are always
|
||||
up-to-date and accurate. */
|
||||
ib_uint64_t write_lsn; /*!< end lsn for the current running
|
||||
write */
|
||||
ulint write_end_offset;/*!< the data in buffer has
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -314,12 +314,15 @@ log_reserve_and_write_fast(
|
|||
ulint data_len;
|
||||
#ifdef UNIV_LOG_LSN_DEBUG
|
||||
/* length of the LSN pseudo-record */
|
||||
ulint lsn_len = 1
|
||||
+ mach_get_compressed_size(log_sys->lsn >> 32)
|
||||
+ mach_get_compressed_size(log_sys->lsn & 0xFFFFFFFFUL);
|
||||
ulint lsn_len;
|
||||
#endif /* UNIV_LOG_LSN_DEBUG */
|
||||
|
||||
mutex_enter(&log_sys->mutex);
|
||||
#ifdef UNIV_LOG_LSN_DEBUG
|
||||
lsn_len = 1
|
||||
+ mach_get_compressed_size(log_sys->lsn >> 32)
|
||||
+ mach_get_compressed_size(log_sys->lsn & 0xFFFFFFFFUL);
|
||||
#endif /* UNIV_LOG_LSN_DEBUG */
|
||||
|
||||
data_len = len
|
||||
#ifdef UNIV_LOG_LSN_DEBUG
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1997, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1997, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -176,6 +176,12 @@ UNIV_INTERN
|
|||
void
|
||||
recv_recovery_from_checkpoint_finish(void);
|
||||
/*======================================*/
|
||||
/********************************************************//**
|
||||
Initiates the rollback of active transactions. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
recv_recovery_rollback_active(void);
|
||||
/*===============================*/
|
||||
/*******************************************************//**
|
||||
Scans log from a buffer and stores new log data to the parsing buffer.
|
||||
Parses and hashes the log records if new data found. Unless
|
||||
|
@ -258,12 +264,14 @@ void
|
|||
recv_sys_init(
|
||||
/*==========*/
|
||||
ulint available_memory); /*!< in: available memory in bytes */
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
/********************************************************//**
|
||||
Reset the state of the recovery system variables. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
recv_sys_var_init(void);
|
||||
/*===================*/
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
/*******************************************************************//**
|
||||
Empties the hash table of stored log records, applying them to appropriate
|
||||
pages. */
|
||||
|
@ -360,8 +368,8 @@ typedef struct recv_addr_struct recv_addr_t;
|
|||
struct recv_addr_struct{
|
||||
enum recv_addr_state state;
|
||||
/*!< recovery state of the page */
|
||||
ulint space; /*!< space id */
|
||||
ulint page_no;/*!< page number */
|
||||
unsigned space:32;/*!< space id */
|
||||
unsigned page_no:32;/*!< page number */
|
||||
UT_LIST_BASE_NODE_T(recv_t)
|
||||
rec_list;/*!< list of log records for this page */
|
||||
hash_node_t addr_hash;/*!< hash node in the hash bucket chain */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1994, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -28,6 +28,13 @@ Created 6/9/1994 Heikki Tuuri
|
|||
check fields whose sizes are given below */
|
||||
|
||||
#ifdef UNIV_MEM_DEBUG
|
||||
# ifndef UNIV_HOTBACKUP
|
||||
/* The mutex which protects in the debug version the hash table
|
||||
containing the list of live memory heaps, and also the global
|
||||
variables in mem0dbg.c. */
|
||||
extern mutex_t mem_hash_mutex;
|
||||
# endif /* !UNIV_HOTBACKUP */
|
||||
|
||||
#define MEM_FIELD_HEADER_SIZE ut_calc_align(2 * sizeof(ulint),\
|
||||
UNIV_MEM_ALIGNMENT)
|
||||
#define MEM_FIELD_TRAILER_SIZE sizeof(ulint)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1994, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -25,9 +25,6 @@ Created 6/8/1994 Heikki Tuuri
|
|||
*************************************************************************/
|
||||
|
||||
#ifdef UNIV_MEM_DEBUG
|
||||
# ifndef UNIV_HOTBACKUP
|
||||
extern mutex_t mem_hash_mutex;
|
||||
# endif /* !UNIV_HOTBACKUP */
|
||||
extern ulint mem_current_allocated_memory;
|
||||
|
||||
/******************************************************************//**
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1994, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -359,6 +359,9 @@ struct mem_block_info_struct {
|
|||
to the heap is also the first block in this list,
|
||||
though it also contains the base node of the list. */
|
||||
ulint len; /*!< physical length of this block in bytes */
|
||||
ulint total_size; /* physical length in bytes of all blocks
|
||||
in the heap. This is defined only in the base
|
||||
node and is set to ULINT_UNDEFINED in others. */
|
||||
ulint type; /*!< type of heap: MEM_HEAP_DYNAMIC, or
|
||||
MEM_HEAP_BUF possibly ORed to MEM_HEAP_BTR_SEARCH */
|
||||
ulint free; /*!< offset in bytes of the first free position for
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1994, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -579,18 +579,12 @@ mem_heap_get_size(
|
|||
/*==============*/
|
||||
mem_heap_t* heap) /*!< in: heap */
|
||||
{
|
||||
mem_block_t* block;
|
||||
ulint size = 0;
|
||||
|
||||
ut_ad(mem_heap_check(heap));
|
||||
|
||||
block = heap;
|
||||
size = heap->total_size;
|
||||
|
||||
while (block != NULL) {
|
||||
|
||||
size += mem_block_get_len(block);
|
||||
block = UT_LIST_GET_NEXT(list, block);
|
||||
}
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
if (heap->free_block) {
|
||||
size += UNIV_PAGE_SIZE;
|
||||
|
|
|
@ -27,8 +27,8 @@ Created 12/7/1995 Heikki Tuuri
|
|||
#include "ut0lst.h"
|
||||
#include "buf0buf.h"
|
||||
#include "fsp0types.h"
|
||||
#include "srv0srv.h"
|
||||
#include "trx0sys.h"
|
||||
|
||||
/********************************************************//**
|
||||
Opens a buffer to mlog. It must be closed with mlog_close.
|
||||
@return buffer, NULL if log mode MTR_LOG_NONE */
|
||||
|
@ -201,7 +201,8 @@ mlog_write_initial_log_record_fast(
|
|||
the doublewrite buffer is located in pages
|
||||
FSP_EXTENT_SIZE, ..., 3 * FSP_EXTENT_SIZE - 1 in the
|
||||
system tablespace */
|
||||
if (space == TRX_SYS_SPACE
|
||||
if ((space == TRX_SYS_SPACE
|
||||
|| (srv_doublewrite_file && space == TRX_DOUBLEWRITE_SPACE))
|
||||
&& offset >= FSP_EXTENT_SIZE && offset < 3 * FSP_EXTENT_SIZE) {
|
||||
if (trx_doublewrite_buf_is_being_created) {
|
||||
/* Do nothing: we only come to this branch in an
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -70,6 +70,7 @@ mtr_memo_push(
|
|||
ut_ad(type <= MTR_MEMO_X_LOCK);
|
||||
ut_ad(mtr);
|
||||
ut_ad(mtr->magic_n == MTR_MAGIC_N);
|
||||
ut_ad(mtr->state == MTR_ACTIVE);
|
||||
|
||||
memo = &(mtr->memo);
|
||||
|
||||
|
@ -92,6 +93,7 @@ mtr_set_savepoint(
|
|||
|
||||
ut_ad(mtr);
|
||||
ut_ad(mtr->magic_n == MTR_MAGIC_N);
|
||||
ut_ad(mtr->state == MTR_ACTIVE);
|
||||
|
||||
memo = &(mtr->memo);
|
||||
|
||||
|
@ -149,6 +151,7 @@ mtr_memo_contains(
|
|||
|
||||
ut_ad(mtr);
|
||||
ut_ad(mtr->magic_n == MTR_MAGIC_N);
|
||||
ut_ad(mtr->state == MTR_ACTIVE || mtr->state == MTR_COMMITTING);
|
||||
|
||||
memo = &(mtr->memo);
|
||||
|
||||
|
|
|
@ -1,23 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||
Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*****************************************************************************/
|
||||
/***********************************************************************
|
||||
|
||||
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 2009, Percona Inc.
|
||||
|
||||
Portions of this file contain modifications contributed and copyrighted
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -30,6 +30,7 @@ Created 5/27/1996 Heikki Tuuri
|
|||
#include "data0data.h"
|
||||
#include "dict0types.h"
|
||||
#include "trx0trx.h"
|
||||
#include "trx0roll.h"
|
||||
#include "srv0srv.h"
|
||||
#include "usr0types.h"
|
||||
#include "que0types.h"
|
||||
|
@ -215,6 +216,16 @@ trx_t*
|
|||
thr_get_trx(
|
||||
/*========*/
|
||||
que_thr_t* thr); /*!< in: query thread */
|
||||
/*******************************************************************//**
|
||||
Determines if this thread is rolling back an incomplete transaction
|
||||
in crash recovery.
|
||||
@return TRUE if thr is rolling back an incomplete transaction in crash
|
||||
recovery */
|
||||
UNIV_INLINE
|
||||
ibool
|
||||
thr_is_recv(
|
||||
/*========*/
|
||||
const que_thr_t* thr); /*!< in: query thread */
|
||||
/***********************************************************************//**
|
||||
Gets the type of a graph node. */
|
||||
UNIV_INLINE
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -38,6 +38,20 @@ thr_get_trx(
|
|||
return(thr->graph->trx);
|
||||
}
|
||||
|
||||
/*******************************************************************//**
|
||||
Determines if this thread is rolling back an incomplete transaction
|
||||
in crash recovery.
|
||||
@return TRUE if thr is rolling back an incomplete transaction in crash
|
||||
recovery */
|
||||
UNIV_INLINE
|
||||
ibool
|
||||
thr_is_recv(
|
||||
/*========*/
|
||||
const que_thr_t* thr) /*!< in: query thread */
|
||||
{
|
||||
return(trx_is_recv(thr->graph->trx));
|
||||
}
|
||||
|
||||
/***********************************************************************//**
|
||||
Gets the first thr in a fork. */
|
||||
UNIV_INLINE
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 2000, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 2000, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -451,6 +451,12 @@ row_drop_table_for_mysql(
|
|||
const char* name, /*!< in: table name */
|
||||
trx_t* trx, /*!< in: transaction handle */
|
||||
ibool drop_db);/*!< in: TRUE=dropping whole database */
|
||||
/*********************************************************************//**
|
||||
Drop all temporary tables during crash recovery. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
row_mysql_drop_temp_tables(void);
|
||||
/*============================*/
|
||||
|
||||
/*********************************************************************//**
|
||||
Discards the tablespace of a table which stored in an .ibd file. Discarding
|
||||
|
@ -494,14 +500,19 @@ row_rename_table_for_mysql(
|
|||
trx_t* trx, /*!< in: transaction handle */
|
||||
ibool commit); /*!< in: if TRUE then commit trx */
|
||||
/*********************************************************************//**
|
||||
Checks a table for corruption.
|
||||
@return DB_ERROR or DB_SUCCESS */
|
||||
Checks that the index contains entries in an ascending order, unique
|
||||
constraint is not broken, and calculates the number of index entries
|
||||
in the read view of the current transaction.
|
||||
@return DB_SUCCESS if ok */
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
row_check_table_for_mysql(
|
||||
row_check_index_for_mysql(
|
||||
/*======================*/
|
||||
row_prebuilt_t* prebuilt); /*!< in: prebuilt struct in MySQL
|
||||
handle */
|
||||
row_prebuilt_t* prebuilt, /*!< in: prebuilt struct
|
||||
in MySQL handle */
|
||||
const dict_index_t* index, /*!< in: index */
|
||||
ulint* n_rows); /*!< out: number of entries
|
||||
seen in the consistent read */
|
||||
|
||||
/*********************************************************************//**
|
||||
Determines if a table is a magic monitor table.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1997, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1997, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -105,17 +105,6 @@ row_fetch_print(
|
|||
/*============*/
|
||||
void* row, /*!< in: sel_node_t* */
|
||||
void* user_arg); /*!< in: not used */
|
||||
/****************************************************************//**
|
||||
Callback function for fetch that stores an unsigned 4 byte integer to the
|
||||
location pointed. The column's type must be DATA_INT, DATA_UNSIGNED, length
|
||||
= 4.
|
||||
@return always returns NULL */
|
||||
UNIV_INTERN
|
||||
void*
|
||||
row_fetch_store_uint4(
|
||||
/*==================*/
|
||||
void* row, /*!< in: sel_node_t* */
|
||||
void* user_arg); /*!< in: data pointer */
|
||||
/***********************************************************//**
|
||||
Prints a row in a select result.
|
||||
@return query thread to run next or NULL */
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 2008, 2009, Google Inc.
|
||||
Copyright (c) 2009, Percona Inc.
|
||||
|
||||
Portions of this file contain modifications contributed and copyrighted by
|
||||
Google, Inc. Those modifications are gratefully acknowledged and are described
|
||||
|
@ -9,6 +10,13 @@ briefly in the InnoDB documentation. The contributions by Google are
|
|||
incorporated with their permission, and subject to the conditions contained in
|
||||
the file COPYING.Google.
|
||||
|
||||
Portions of this file contain modifications contributed and copyrighted
|
||||
by Percona Inc.. Those modifications are
|
||||
gratefully acknowledged and are described briefly in the InnoDB
|
||||
documentation. The contributions by Percona Inc. are incorporated with
|
||||
their permission, and subject to the conditions contained in the file
|
||||
COPYING.Percona.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; version 2 of the License.
|
||||
|
@ -22,32 +30,6 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
|||
Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*****************************************************************************/
|
||||
/***********************************************************************
|
||||
|
||||
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 2009, Percona Inc.
|
||||
|
||||
Portions of this file contain modifications contributed and copyrighted
|
||||
by Percona Inc.. Those modifications are
|
||||
gratefully acknowledged and are described briefly in the InnoDB
|
||||
documentation. The contributions by Percona Inc. are incorporated with
|
||||
their permission, and subject to the conditions contained in the file
|
||||
COPYING.Percona.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
/**************************************************//**
|
||||
@file include/srv0srv.h
|
||||
|
@ -133,9 +115,10 @@ extern char** srv_data_file_names;
|
|||
extern ulint* srv_data_file_sizes;
|
||||
extern ulint* srv_data_file_is_raw_partition;
|
||||
|
||||
extern char* srv_doublewrite_file;
|
||||
|
||||
extern ibool srv_extra_undoslots;
|
||||
|
||||
extern ibool srv_fast_recovery;
|
||||
extern ibool srv_recovery_stats;
|
||||
|
||||
extern ulint srv_use_purge_thread;
|
||||
|
@ -247,7 +230,6 @@ extern ulint srv_read_ahead;
|
|||
extern ulint srv_adaptive_checkpoint;
|
||||
|
||||
extern ulint srv_expand_import;
|
||||
extern ulint srv_relax_table_creation;
|
||||
extern ulint srv_pass_corrupt_table;
|
||||
|
||||
extern ulint srv_extra_rsegments;
|
||||
|
@ -265,7 +247,8 @@ extern ibool srv_print_innodb_tablespace_monitor;
|
|||
extern ibool srv_print_verbose_log;
|
||||
extern ibool srv_print_innodb_table_monitor;
|
||||
|
||||
extern ibool srv_lock_timeout_and_monitor_active;
|
||||
extern ibool srv_lock_timeout_active;
|
||||
extern ibool srv_monitor_active;
|
||||
extern ibool srv_error_monitor_active;
|
||||
|
||||
extern ulong srv_n_spin_wait_rounds;
|
||||
|
@ -595,15 +578,23 @@ srv_release_mysql_thread_if_suspended(
|
|||
MySQL OS thread */
|
||||
/*********************************************************************//**
|
||||
A thread which wakes up threads whose lock wait may have lasted too long.
|
||||
This also prints the info output by various InnoDB monitors.
|
||||
@return a dummy parameter */
|
||||
UNIV_INTERN
|
||||
os_thread_ret_t
|
||||
srv_lock_timeout_and_monitor_thread(
|
||||
/*================================*/
|
||||
srv_lock_timeout_thread(
|
||||
/*====================*/
|
||||
void* arg); /*!< in: a dummy parameter required by
|
||||
os_thread_create */
|
||||
/*********************************************************************//**
|
||||
A thread which prints the info output by various InnoDB monitors.
|
||||
@return a dummy parameter */
|
||||
UNIV_INTERN
|
||||
os_thread_ret_t
|
||||
srv_monitor_thread(
|
||||
/*===============*/
|
||||
void* arg); /*!< in: a dummy parameter required by
|
||||
os_thread_create */
|
||||
/*************************************************************************
|
||||
A thread which prints warnings about semaphore waits which have lasted
|
||||
too long. These can be used to track bugs which cause hangs.
|
||||
@return a dummy parameter */
|
||||
|
@ -614,12 +605,15 @@ srv_error_monitor_thread(
|
|||
void* arg); /*!< in: a dummy parameter required by
|
||||
os_thread_create */
|
||||
/******************************************************************//**
|
||||
Outputs to a file the output of the InnoDB Monitor. */
|
||||
Outputs to a file the output of the InnoDB Monitor.
|
||||
@return FALSE if not all information printed
|
||||
due to failure to obtain necessary mutex */
|
||||
UNIV_INTERN
|
||||
void
|
||||
ibool
|
||||
srv_printf_innodb_monitor(
|
||||
/*======================*/
|
||||
FILE* file, /*!< in: output stream */
|
||||
ibool nowait, /*!< in: whether to wait for kernel mutex */
|
||||
ulint* trx_start, /*!< out: file position of the start of
|
||||
the list of active transactions */
|
||||
ulint* trx_end); /*!< out: file position of the end of
|
||||
|
@ -664,6 +658,7 @@ struct export_var_struct{
|
|||
ulint innodb_buffer_pool_write_requests;/*!< srv_buf_pool_write_requests */
|
||||
ulint innodb_buffer_pool_read_ahead; /*!< srv_read_ahead */
|
||||
ulint innodb_buffer_pool_read_ahead_evicted;/*!< srv_read_ahead evicted*/
|
||||
ulint innodb_deadlocks; /* ??? */
|
||||
ulint innodb_dblwr_pages_written; /*!< srv_dblwr_pages_written */
|
||||
ulint innodb_dblwr_writes; /*!< srv_dblwr_writes */
|
||||
ibool innodb_have_atomic_builtins; /*!< HAVE_ATOMIC_BUILTINS */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 2008, Google Inc.
|
||||
|
||||
Portions of this file contain modifications contributed and copyrighted by
|
||||
|
@ -429,8 +429,9 @@ ibool
|
|||
rw_lock_own(
|
||||
/*========*/
|
||||
rw_lock_t* lock, /*!< in: rw-lock */
|
||||
ulint lock_type); /*!< in: lock type: RW_LOCK_SHARED,
|
||||
ulint lock_type) /*!< in: lock type: RW_LOCK_SHARED,
|
||||
RW_LOCK_EX */
|
||||
__attribute__((warn_unused_result));
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
/******************************************************************//**
|
||||
Checks if somebody has locked the rw-lock in the specified mode. */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 2008, Google Inc.
|
||||
|
||||
Portions of this file contain modifications contributed and copyrighted by
|
||||
|
@ -206,7 +206,8 @@ UNIV_INTERN
|
|||
ibool
|
||||
mutex_own(
|
||||
/*======*/
|
||||
const mutex_t* mutex); /*!< in: mutex */
|
||||
const mutex_t* mutex) /*!< in: mutex */
|
||||
__attribute__((warn_unused_result));
|
||||
#endif /* UNIV_DEBUG */
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
/******************************************************************//**
|
||||
|
@ -238,16 +239,27 @@ ibool
|
|||
sync_thread_levels_empty(void);
|
||||
/*==========================*/
|
||||
/******************************************************************//**
|
||||
Checks that the level array for the current thread is empty.
|
||||
@return TRUE if empty except the exceptions specified below */
|
||||
Checks if the level array for the current thread contains a
|
||||
mutex or rw-latch at the specified level.
|
||||
@return a matching latch, or NULL if not found */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
sync_thread_levels_empty_gen(
|
||||
/*=========================*/
|
||||
void*
|
||||
sync_thread_levels_contains(
|
||||
/*========================*/
|
||||
ulint level); /*!< in: latching order level
|
||||
(SYNC_DICT, ...)*/
|
||||
/******************************************************************//**
|
||||
Checks if the level array for the current thread is empty.
|
||||
@return a latch, or NULL if empty except the exceptions specified below */
|
||||
UNIV_INTERN
|
||||
void*
|
||||
sync_thread_levels_nonempty_gen(
|
||||
/*============================*/
|
||||
ibool dict_mutex_allowed); /*!< in: TRUE if dictionary mutex is
|
||||
allowed to be owned by the thread,
|
||||
also purge_is_running mutex is
|
||||
allowed */
|
||||
#define sync_thread_levels_empty_gen(d) (!sync_thread_levels_nonempty_gen(d))
|
||||
/******************************************************************//**
|
||||
Gets the debug information for a reserved mutex. */
|
||||
UNIV_INTERN
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
|
|
@ -124,6 +124,22 @@ trx_sys_hdr_page(
|
|||
/*=============*/
|
||||
ulint space, /*!< in: space */
|
||||
ulint page_no);/*!< in: page number */
|
||||
/***************************************************************//**
|
||||
Checks if a space is the system tablespaces.
|
||||
@return TRUE if system tablespace */
|
||||
UNIV_INLINE
|
||||
ibool
|
||||
trx_sys_sys_space(
|
||||
/*==============*/
|
||||
ulint space); /*!< in: space */
|
||||
/***************************************************************//**
|
||||
Checks if a space is the doublewrite tablespace.
|
||||
@return TRUE if doublewrite tablespace */
|
||||
UNIV_INLINE
|
||||
ibool
|
||||
trx_sys_doublewrite_space(
|
||||
/*======================*/
|
||||
ulint space); /*!< in: space */
|
||||
/*****************************************************************//**
|
||||
Creates and initializes the central memory structures for the transaction
|
||||
system. This is called when the database is started. */
|
||||
|
@ -137,6 +153,13 @@ UNIV_INTERN
|
|||
void
|
||||
trx_sys_create(void);
|
||||
/*================*/
|
||||
/*****************************************************************//**
|
||||
Creates and initializes the dummy transaction system page for tablespace. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
trx_sys_dummy_create(
|
||||
/*=================*/
|
||||
ulint space);
|
||||
/*********************************************************************
|
||||
Create extra rollback segments when create_new_db */
|
||||
UNIV_INTERN
|
||||
|
@ -343,12 +366,14 @@ UNIV_INTERN
|
|||
void
|
||||
trx_sys_file_format_tag_init(void);
|
||||
/*==============================*/
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
/*****************************************************************//**
|
||||
Shutdown/Close the transaction system. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
trx_sys_close(void);
|
||||
/*===============*/
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
/*****************************************************************//**
|
||||
Get the name representation of the file format from its id.
|
||||
@return pointer to the name */
|
||||
|
@ -444,6 +469,8 @@ trx_sys_file_format_id_to_name(
|
|||
|
||||
/* Space id and page no where the trx system file copy resides */
|
||||
#define TRX_SYS_SPACE 0 /* the SYSTEM tablespace */
|
||||
#define TRX_DOUBLEWRITE_SPACE 1 /* the doublewrite buffer tablespace if used */
|
||||
#define TRX_SYS_SPACE_MAX 9 /* reserved max space id for system tablespaces */
|
||||
#include "fsp0fsp.h"
|
||||
#define TRX_SYS_PAGE_NO FSP_TRX_SYS_PAGE_NO
|
||||
|
||||
|
@ -507,7 +534,6 @@ this contains the same fields as TRX_SYS_MYSQL_LOG_INFO below */
|
|||
within that file */
|
||||
#define TRX_SYS_MYSQL_LOG_NAME 12 /*!< MySQL log file name */
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
/** Doublewrite buffer */
|
||||
/* @{ */
|
||||
/** The offset of the doublewrite buffer header on the trx system header page */
|
||||
|
@ -559,6 +585,7 @@ FIL_PAGE_ARCH_LOG_NO_OR_SPACE_NO. */
|
|||
#define TRX_SYS_DOUBLEWRITE_BLOCK_SIZE FSP_EXTENT_SIZE
|
||||
/* @} */
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
/** File format tag */
|
||||
/* @{ */
|
||||
/** The offset of the file format tag on the trx system header page
|
||||
|
|
|
@ -70,6 +70,40 @@ trx_sys_hdr_page(
|
|||
return(FALSE);
|
||||
}
|
||||
|
||||
/***************************************************************//**
|
||||
Checks if a space is the system tablespaces.
|
||||
@return TRUE if system tablespace */
|
||||
UNIV_INLINE
|
||||
ibool
|
||||
trx_sys_sys_space(
|
||||
/*==============*/
|
||||
ulint space) /*!< in: space */
|
||||
{
|
||||
if (srv_doublewrite_file) {
|
||||
/* several spaces are reserved */
|
||||
return((ibool)(space <= TRX_SYS_SPACE_MAX));
|
||||
} else {
|
||||
return((ibool)(space == TRX_SYS_SPACE));
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************//**
|
||||
Checks if a space is the doublewrite tablespace.
|
||||
@return TRUE if doublewrite tablespace */
|
||||
UNIV_INLINE
|
||||
ibool
|
||||
trx_sys_doublewrite_space(
|
||||
/*======================*/
|
||||
ulint space) /*!< in: space */
|
||||
{
|
||||
if (srv_doublewrite_file) {
|
||||
/* doublewrite buffer is separated */
|
||||
return((ibool)(space == TRX_DOUBLEWRITE_SPACE));
|
||||
} else {
|
||||
return((ibool)(space == TRX_SYS_SPACE));
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************//**
|
||||
Gets the pointer in the nth slot of the rseg array.
|
||||
@return pointer to rseg object, NULL if slot not in use */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -338,9 +338,7 @@ trx_commit_step(
|
|||
|
||||
/**********************************************************************//**
|
||||
Prints info about a transaction to the given file. The caller must own the
|
||||
kernel mutex and must have called
|
||||
innobase_mysql_prepare_print_arbitrary_thd(), unless he knows that MySQL
|
||||
or InnoDB cannot meanwhile change the info printed here. */
|
||||
kernel mutex. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
trx_print(
|
||||
|
@ -351,7 +349,7 @@ trx_print(
|
|||
use the default max length */
|
||||
|
||||
/** Type of data dictionary operation */
|
||||
enum trx_dict_op {
|
||||
typedef enum trx_dict_op {
|
||||
/** The transaction is not modifying the data dictionary. */
|
||||
TRX_DICT_OP_NONE = 0,
|
||||
/** The transaction is creating a table or an index, or
|
||||
|
@ -363,7 +361,7 @@ enum trx_dict_op {
|
|||
existing table. In crash recovery, the data dictionary
|
||||
must be locked, but the table must not be dropped. */
|
||||
TRX_DICT_OP_INDEX = 2
|
||||
};
|
||||
} trx_dict_op_t;
|
||||
|
||||
/**********************************************************************//**
|
||||
Determine if a transaction is a dictionary operation.
|
||||
|
@ -393,6 +391,14 @@ ibool
|
|||
trx_is_interrupted(
|
||||
/*===============*/
|
||||
trx_t* trx); /*!< in: transaction */
|
||||
/**********************************************************************//**
|
||||
Determines if the currently running transaction is in strict mode.
|
||||
@return TRUE if strict */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
trx_is_strict(
|
||||
/*==========*/
|
||||
trx_t* trx); /*!< in: transaction */
|
||||
#else /* !UNIV_HOTBACKUP */
|
||||
#define trx_is_interrupted(trx) FALSE
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
|
@ -465,69 +471,79 @@ rolling back after a database recovery */
|
|||
|
||||
struct trx_struct{
|
||||
ulint magic_n;
|
||||
/* All the next fields are protected by the kernel mutex, except the
|
||||
undo logs which are protected by undo_mutex */
|
||||
|
||||
/* These fields are not protected by any mutex. */
|
||||
const char* op_info; /*!< English text describing the
|
||||
current operation, or an empty
|
||||
string */
|
||||
unsigned is_purge:1; /*!< 0=user transaction, 1=purge */
|
||||
unsigned is_recovered:1; /*!< 0=normal transaction,
|
||||
1=recovered, must be rolled back */
|
||||
unsigned conc_state:2; /*!< state of the trx from the point
|
||||
ulint conc_state; /*!< state of the trx from the point
|
||||
of view of concurrency control:
|
||||
TRX_ACTIVE, TRX_COMMITTED_IN_MEMORY,
|
||||
... */
|
||||
unsigned que_state:2; /*!< valid when conc_state == TRX_ACTIVE:
|
||||
TRX_QUE_RUNNING, TRX_QUE_LOCK_WAIT,
|
||||
... */
|
||||
unsigned isolation_level:2;/* TRX_ISO_REPEATABLE_READ, ... */
|
||||
unsigned check_foreigns:1;/* normally TRUE, but if the user
|
||||
ulint isolation_level;/* TRX_ISO_REPEATABLE_READ, ... */
|
||||
ulint check_foreigns; /* normally TRUE, but if the user
|
||||
wants to suppress foreign key checks,
|
||||
(in table imports, for example) we
|
||||
set this FALSE */
|
||||
unsigned check_unique_secondary:1;
|
||||
ulint check_unique_secondary;
|
||||
/* normally TRUE, but if the user
|
||||
wants to speed up inserts by
|
||||
suppressing unique key checks
|
||||
for secondary indexes when we decide
|
||||
if we can use the insert buffer for
|
||||
them, we set this FALSE */
|
||||
unsigned support_xa:1; /*!< normally we do the XA two-phase
|
||||
ulint support_xa; /*!< normally we do the XA two-phase
|
||||
commit steps, but by setting this to
|
||||
FALSE, one can save CPU time and about
|
||||
150 bytes in the undo log size as then
|
||||
we skip XA steps */
|
||||
unsigned flush_log_later:1;/* In 2PC, we hold the
|
||||
ulint flush_log_later;/* In 2PC, we hold the
|
||||
prepare_commit mutex across
|
||||
both phases. In that case, we
|
||||
defer flush of the logs to disk
|
||||
until after we release the
|
||||
mutex. */
|
||||
unsigned must_flush_log_later:1;/* this flag is set to TRUE in
|
||||
ulint must_flush_log_later;/* this flag is set to TRUE in
|
||||
trx_commit_off_kernel() if
|
||||
flush_log_later was TRUE, and there
|
||||
were modifications by the transaction;
|
||||
in that case we must flush the log
|
||||
in trx_commit_complete_for_mysql() */
|
||||
unsigned dict_operation:2;/**< @see enum trx_dict_op */
|
||||
unsigned duplicates:2; /*!< TRX_DUP_IGNORE | TRX_DUP_REPLACE */
|
||||
unsigned active_trans:2; /*!< 1 - if a transaction in MySQL
|
||||
ulint duplicates; /*!< TRX_DUP_IGNORE | TRX_DUP_REPLACE */
|
||||
ulint active_trans; /*!< 1 - if a transaction in MySQL
|
||||
is active. 2 - if prepare_commit_mutex
|
||||
was taken */
|
||||
unsigned has_search_latch:1;
|
||||
ulint has_search_latch;
|
||||
/* TRUE if this trx has latched the
|
||||
search system latch in S-mode */
|
||||
unsigned declared_to_be_inside_innodb:1;
|
||||
ulint deadlock_mark; /*!< a mark field used in deadlock
|
||||
checking algorithm. */
|
||||
trx_dict_op_t dict_operation; /**< @see enum trx_dict_op */
|
||||
|
||||
/* Fields protected by the srv_conc_mutex. */
|
||||
ulint declared_to_be_inside_innodb;
|
||||
/* this is TRUE if we have declared
|
||||
this transaction in
|
||||
srv_conc_enter_innodb to be inside the
|
||||
InnoDB engine */
|
||||
unsigned handling_signals:1;/* this is TRUE as long as the trx
|
||||
is handling signals */
|
||||
unsigned dict_operation_lock_mode:2;
|
||||
/* 0, RW_S_LATCH, or RW_X_LATCH:
|
||||
|
||||
/* Fields protected by dict_operation_lock. The very latch
|
||||
it is used to track. */
|
||||
ulint dict_operation_lock_mode;
|
||||
/*!< 0, RW_S_LATCH, or RW_X_LATCH:
|
||||
the latch mode trx currently holds
|
||||
on dict_operation_lock */
|
||||
|
||||
/* All the next fields are protected by the kernel mutex, except the
|
||||
undo logs which are protected by undo_mutex */
|
||||
ulint is_purge; /*!< 0=user transaction, 1=purge */
|
||||
ulint is_recovered; /*!< 0=normal transaction,
|
||||
1=recovered, must be rolled back */
|
||||
ulint que_state; /*!< valid when conc_state
|
||||
== TRX_ACTIVE: TRX_QUE_RUNNING,
|
||||
TRX_QUE_LOCK_WAIT, ... */
|
||||
ulint handling_signals;/* this is TRUE as long as the trx
|
||||
is handling signals */
|
||||
time_t start_time; /*!< time the trx object was created
|
||||
or the state last time became
|
||||
TRX_ACTIVE */
|
||||
|
@ -657,11 +673,6 @@ struct trx_struct{
|
|||
wait_thrs; /*!< query threads belonging to this
|
||||
trx that are in the QUE_THR_LOCK_WAIT
|
||||
state */
|
||||
ulint deadlock_mark; /*!< a mark field used in deadlock
|
||||
checking algorithm. This must be
|
||||
in its own machine word, because
|
||||
it can be changed by other
|
||||
threads while holding kernel_mutex. */
|
||||
/*------------------------------*/
|
||||
mem_heap_t* lock_heap; /*!< memory heap for the locks of the
|
||||
transaction */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -70,6 +70,13 @@ typedef struct trx_named_savept_struct trx_named_savept_t;
|
|||
enum trx_rb_ctx {
|
||||
RB_NONE = 0, /*!< no rollback */
|
||||
RB_NORMAL, /*!< normal rollback */
|
||||
RB_RECOVERY_PURGE_REC,
|
||||
/*!< rolling back an incomplete transaction,
|
||||
in crash recovery, rolling back an
|
||||
INSERT that was performed by updating a
|
||||
delete-marked record; if the delete-marked record
|
||||
no longer exists in an active read view, it will
|
||||
be purged */
|
||||
RB_RECOVERY /*!< rolling back an incomplete transaction,
|
||||
in crash recovery */
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1994, 2010, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 2008, Google Inc.
|
||||
Copyright (c) 2009, Sun Microsystems, Inc.
|
||||
|
||||
|
@ -46,10 +46,10 @@ Created 1/20/1994 Heikki Tuuri
|
|||
|
||||
#define INNODB_VERSION_MAJOR 1
|
||||
#define INNODB_VERSION_MINOR 0
|
||||
#define INNODB_VERSION_BUGFIX 6
|
||||
#define INNODB_VERSION_BUGFIX 8
|
||||
|
||||
#ifndef PERCONA_INNODB_VERSION
|
||||
#define PERCONA_INNODB_VERSION unknown
|
||||
#define PERCONA_INNODB_VERSION 11.2
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -122,7 +122,7 @@ if we are compiling on Windows. */
|
|||
|
||||
/* Include <sys/stat.h> to get S_I... macros defined for os0file.c */
|
||||
# include <sys/stat.h>
|
||||
# if !defined(__NETWARE__) && !defined(__WIN__)
|
||||
# if !defined(__NETWARE__) && !defined(__WIN__)
|
||||
# include <sys/mman.h> /* mmap() for os0proc.c */
|
||||
# endif
|
||||
|
||||
|
@ -172,6 +172,9 @@ command. Not tested on Windows. */
|
|||
#define UNIV_COMPILE_TEST_FUNCS
|
||||
*/
|
||||
|
||||
#ifdef HAVE_purify
|
||||
# define UNIV_DEBUG_VALGRIND
|
||||
#endif /* HAVE_purify */
|
||||
#if 0
|
||||
#define UNIV_DEBUG_VALGRIND /* Enable extra
|
||||
Valgrind instrumentation */
|
||||
|
@ -209,6 +212,10 @@ operations (very slow); also UNIV_DEBUG must be defined */
|
|||
adaptive hash index */
|
||||
#define UNIV_SRV_PRINT_LATCH_WAITS /* enable diagnostic output
|
||||
in sync0sync.c */
|
||||
#define UNIV_BTR_AVOID_COPY /* when splitting B-tree nodes,
|
||||
do not move any records when
|
||||
all the records would
|
||||
be moved */
|
||||
#define UNIV_BTR_PRINT /* enable functions for
|
||||
printing B-trees */
|
||||
#define UNIV_ZIP_DEBUG /* extensive consistency checks
|
||||
|
@ -236,11 +243,6 @@ by one. */
|
|||
/* the above option prevents forcing of log to disk
|
||||
at a buffer page write: it should be tested with this
|
||||
option off; also some ibuf tests are suppressed */
|
||||
/*
|
||||
#define UNIV_BASIC_LOG_DEBUG
|
||||
*/
|
||||
/* the above option enables basic recovery debugging:
|
||||
new allocated file pages are reset */
|
||||
|
||||
/* Linkage specifier for non-static InnoDB symbols (variables and functions)
|
||||
that are only referenced from within InnoDB, not from MySQL */
|
||||
|
|
309
include/ut0rbt.h
Normal file
309
include/ut0rbt.h
Normal file
|
@ -0,0 +1,309 @@
|
|||
/*****************************************************************************
|
||||
Copyright (c) 2006, 2009, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||
Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*****************************************************************************/
|
||||
|
||||
/*******************************************************************//**
|
||||
@file include/ut0rbt.h
|
||||
Red-Black tree implementation.
|
||||
|
||||
Created 2007-03-20 Sunny Bains
|
||||
************************************************************************/
|
||||
|
||||
#ifndef INNOBASE_UT0RBT_H
|
||||
#define INNOBASE_UT0RBT_H
|
||||
|
||||
#if !defined(IB_RBT_TESTING)
|
||||
#include "univ.i"
|
||||
#include "ut0mem.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define ut_malloc malloc
|
||||
#define ut_free free
|
||||
#define ulint unsigned long
|
||||
#define ut_a(c) assert(c)
|
||||
#define ut_error assert(0)
|
||||
#define ibool unsigned int
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
/* Red black tree typedefs */
|
||||
typedef struct ib_rbt_struct ib_rbt_t;
|
||||
typedef struct ib_rbt_node_struct ib_rbt_node_t;
|
||||
/* FIXME: Iterator is a better name than _bound_ */
|
||||
typedef struct ib_rbt_bound_struct ib_rbt_bound_t;
|
||||
typedef void (*ib_rbt_print_node)(const ib_rbt_node_t* node);
|
||||
typedef int (*ib_rbt_compare)(const void* p1, const void* p2);
|
||||
|
||||
/* Red black tree color types */
|
||||
enum ib_rbt_color_enum {
|
||||
IB_RBT_RED,
|
||||
IB_RBT_BLACK
|
||||
};
|
||||
|
||||
typedef enum ib_rbt_color_enum ib_rbt_color_t;
|
||||
|
||||
/* Red black tree node */
|
||||
struct ib_rbt_node_struct {
|
||||
ib_rbt_color_t color; /* color of this node */
|
||||
|
||||
ib_rbt_node_t* left; /* points left child */
|
||||
ib_rbt_node_t* right; /* points right child */
|
||||
ib_rbt_node_t* parent; /* points parent node */
|
||||
|
||||
char value[1]; /* Data value */
|
||||
};
|
||||
|
||||
/* Red black tree instance.*/
|
||||
struct ib_rbt_struct {
|
||||
ib_rbt_node_t* nil; /* Black colored node that is
|
||||
used as a sentinel. This is
|
||||
pre-allocated too.*/
|
||||
|
||||
ib_rbt_node_t* root; /* Root of the tree, this is
|
||||
pre-allocated and the first
|
||||
data node is the left child.*/
|
||||
|
||||
ulint n_nodes; /* Total number of data nodes */
|
||||
|
||||
ib_rbt_compare compare; /* Fn. to use for comparison */
|
||||
ulint sizeof_value; /* Sizeof the item in bytes */
|
||||
};
|
||||
|
||||
/* The result of searching for a key in the tree, this is useful for
|
||||
a speedy lookup and insert if key doesn't exist.*/
|
||||
struct ib_rbt_bound_struct {
|
||||
const ib_rbt_node_t*
|
||||
last; /* Last node visited */
|
||||
|
||||
int result; /* Result of comparing with
|
||||
the last non-nil node that
|
||||
was visited */
|
||||
};
|
||||
|
||||
/* Size in elements (t is an rb tree instance) */
|
||||
#define rbt_size(t) (t->n_nodes)
|
||||
|
||||
/* Check whether the rb tree is empty (t is an rb tree instance) */
|
||||
#define rbt_empty(t) (rbt_size(t) == 0)
|
||||
|
||||
/* Get data value (t is the data type, n is an rb tree node instance) */
|
||||
#define rbt_value(t, n) ((t*) &n->value[0])
|
||||
|
||||
/* Compare a key with the node value (t is tree, k is key, n is node)*/
|
||||
#define rbt_compare(t, k, n) (t->compare(k, n->value))
|
||||
|
||||
/****************************************************************//**
|
||||
Free an instance of a red black tree */
|
||||
UNIV_INTERN
|
||||
void
|
||||
rbt_free(
|
||||
/*=====*/
|
||||
ib_rbt_t* tree); /*!< in: rb tree to free */
|
||||
/****************************************************************//**
|
||||
Create an instance of a red black tree
|
||||
@return rb tree instance */
|
||||
UNIV_INTERN
|
||||
ib_rbt_t*
|
||||
rbt_create(
|
||||
/*=======*/
|
||||
size_t sizeof_value, /*!< in: size in bytes */
|
||||
ib_rbt_compare compare); /*!< in: comparator */
|
||||
/****************************************************************//**
|
||||
Delete a node from the red black tree, identified by key.
|
||||
@return TRUE if success FALSE if not found */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
rbt_delete(
|
||||
/*=======*/
|
||||
ib_rbt_t* tree, /*!< in: rb tree */
|
||||
const void* key); /*!< in: key to delete */
|
||||
/****************************************************************//**
|
||||
Remove a node from the rb tree, the node is not free'd, that is the
|
||||
callers responsibility.
|
||||
@return the deleted node with the const. */
|
||||
UNIV_INTERN
|
||||
ib_rbt_node_t*
|
||||
rbt_remove_node(
|
||||
/*============*/
|
||||
ib_rbt_t* tree, /*!< in: rb tree */
|
||||
const ib_rbt_node_t*
|
||||
node); /*!< in: node to delete, this
|
||||
is a fudge and declared const
|
||||
because the caller has access
|
||||
only to const nodes.*/
|
||||
/****************************************************************//**
|
||||
Find a matching node in the rb tree.
|
||||
@return node if found else return NULL */
|
||||
UNIV_INTERN
|
||||
const ib_rbt_node_t*
|
||||
rbt_lookup(
|
||||
/*=======*/
|
||||
const ib_rbt_t* tree, /*!< in: rb tree to search */
|
||||
const void* key); /*!< in: key to lookup */
|
||||
/****************************************************************//**
|
||||
Generic insert of a value in the rb tree.
|
||||
@return inserted node */
|
||||
UNIV_INTERN
|
||||
const ib_rbt_node_t*
|
||||
rbt_insert(
|
||||
/*=======*/
|
||||
ib_rbt_t* tree, /*!< in: rb tree */
|
||||
const void* key, /*!< in: key for ordering */
|
||||
const void* value); /*!< in: data that will be
|
||||
copied to the node.*/
|
||||
/****************************************************************//**
|
||||
Add a new node to the tree, useful for data that is pre-sorted.
|
||||
@return appended node */
|
||||
UNIV_INTERN
|
||||
const ib_rbt_node_t*
|
||||
rbt_add_node(
|
||||
/*=========*/
|
||||
ib_rbt_t* tree, /*!< in: rb tree */
|
||||
ib_rbt_bound_t* parent, /*!< in: parent */
|
||||
const void* value); /*!< in: this value is copied
|
||||
to the node */
|
||||
/****************************************************************//**
|
||||
Return the left most data node in the tree
|
||||
@return left most node */
|
||||
UNIV_INTERN
|
||||
const ib_rbt_node_t*
|
||||
rbt_first(
|
||||
/*======*/
|
||||
const ib_rbt_t* tree); /*!< in: rb tree */
|
||||
/****************************************************************//**
|
||||
Return the right most data node in the tree
|
||||
@return right most node */
|
||||
UNIV_INTERN
|
||||
const ib_rbt_node_t*
|
||||
rbt_last(
|
||||
/*=====*/
|
||||
const ib_rbt_t* tree); /*!< in: rb tree */
|
||||
/****************************************************************//**
|
||||
Return the next node from current.
|
||||
@return successor node to current that is passed in. */
|
||||
UNIV_INTERN
|
||||
const ib_rbt_node_t*
|
||||
rbt_next(
|
||||
/*=====*/
|
||||
const ib_rbt_t* tree, /*!< in: rb tree */
|
||||
const ib_rbt_node_t* /*!< in: current node */
|
||||
current);
|
||||
/****************************************************************//**
|
||||
Return the prev node from current.
|
||||
@return precedessor node to current that is passed in */
|
||||
UNIV_INTERN
|
||||
const ib_rbt_node_t*
|
||||
rbt_prev(
|
||||
/*=====*/
|
||||
const ib_rbt_t* tree, /*!< in: rb tree */
|
||||
const ib_rbt_node_t* /*!< in: current node */
|
||||
current);
|
||||
/****************************************************************//**
|
||||
Find the node that has the lowest key that is >= key.
|
||||
@return node that satisfies the lower bound constraint or NULL */
|
||||
UNIV_INTERN
|
||||
const ib_rbt_node_t*
|
||||
rbt_lower_bound(
|
||||
/*============*/
|
||||
const ib_rbt_t* tree, /*!< in: rb tree */
|
||||
const void* key); /*!< in: key to search */
|
||||
/****************************************************************//**
|
||||
Find the node that has the greatest key that is <= key.
|
||||
@return node that satisifies the upper bound constraint or NULL */
|
||||
UNIV_INTERN
|
||||
const ib_rbt_node_t*
|
||||
rbt_upper_bound(
|
||||
/*============*/
|
||||
const ib_rbt_t* tree, /*!< in: rb tree */
|
||||
const void* key); /*!< in: key to search */
|
||||
/****************************************************************//**
|
||||
Search for the key, a node will be retuned in parent.last, whether it
|
||||
was found or not. If not found then parent.last will contain the
|
||||
parent node for the possibly new key otherwise the matching node.
|
||||
@return result of last comparison */
|
||||
UNIV_INTERN
|
||||
int
|
||||
rbt_search(
|
||||
/*=======*/
|
||||
const ib_rbt_t* tree, /*!< in: rb tree */
|
||||
ib_rbt_bound_t* parent, /*!< in: search bounds */
|
||||
const void* key); /*!< in: key to search */
|
||||
/****************************************************************//**
|
||||
Search for the key, a node will be retuned in parent.last, whether it
|
||||
was found or not. If not found then parent.last will contain the
|
||||
parent node for the possibly new key otherwise the matching node.
|
||||
@return result of last comparison */
|
||||
UNIV_INTERN
|
||||
int
|
||||
rbt_search_cmp(
|
||||
/*===========*/
|
||||
const ib_rbt_t* tree, /*!< in: rb tree */
|
||||
ib_rbt_bound_t* parent, /*!< in: search bounds */
|
||||
const void* key, /*!< in: key to search */
|
||||
ib_rbt_compare compare); /*!< in: comparator */
|
||||
/****************************************************************//**
|
||||
Clear the tree, deletes (and free's) all the nodes. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
rbt_clear(
|
||||
/*======*/
|
||||
ib_rbt_t* tree); /*!< in: rb tree */
|
||||
/****************************************************************//**
|
||||
Merge the node from dst into src. Return the number of nodes merged.
|
||||
@return no. of recs merged */
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
rbt_merge_uniq(
|
||||
/*===========*/
|
||||
ib_rbt_t* dst, /*!< in: dst rb tree */
|
||||
const ib_rbt_t* src); /*!< in: src rb tree */
|
||||
/****************************************************************//**
|
||||
Merge the node from dst into src. Return the number of nodes merged.
|
||||
Delete the nodes from src after copying node to dst. As a side effect
|
||||
the duplicates will be left untouched in the src, since we don't support
|
||||
duplicates (yet). NOTE: src and dst must be similar, the function doesn't
|
||||
check for this condition (yet).
|
||||
@return no. of recs merged */
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
rbt_merge_uniq_destructive(
|
||||
/*=======================*/
|
||||
ib_rbt_t* dst, /*!< in: dst rb tree */
|
||||
ib_rbt_t* src); /*!< in: src rb tree */
|
||||
/****************************************************************//**
|
||||
Verify the integrity of the RB tree. For debugging. 0 failure else height
|
||||
of tree (in count of black nodes).
|
||||
@return TRUE if OK FALSE if tree invalid. */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
rbt_validate(
|
||||
/*=========*/
|
||||
const ib_rbt_t* tree); /*!< in: tree to validate */
|
||||
/****************************************************************//**
|
||||
Iterate over the tree in depth first order. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
rbt_print(
|
||||
/*======*/
|
||||
const ib_rbt_t* tree, /*!< in: tree to traverse */
|
||||
ib_rbt_print_node print); /*!< in: print function */
|
||||
|
||||
#endif /* INNOBASE_UT0RBT_H */
|
|
@ -152,6 +152,7 @@ ut_hash_ulint(
|
|||
ulint key, /*!< in: value to be hashed */
|
||||
ulint table_size) /*!< in: hash table size */
|
||||
{
|
||||
ut_ad(table_size);
|
||||
key = key ^ UT_HASH_RANDOM_MASK2;
|
||||
|
||||
return(key % table_size);
|
||||
|
|
279
lock/lock0lock.c
279
lock/lock0lock.c
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -376,6 +376,7 @@ UNIV_INTERN FILE* lock_latest_err_file;
|
|||
/* Flags for recursive deadlock search */
|
||||
#define LOCK_VICTIM_IS_START 1
|
||||
#define LOCK_VICTIM_IS_OTHER 2
|
||||
#define LOCK_EXCEED_MAX_DEPTH 3
|
||||
|
||||
/********************************************************************//**
|
||||
Checks if a lock request results in a deadlock.
|
||||
|
@ -394,24 +395,25 @@ Looks recursively for a deadlock.
|
|||
deadlock and we chose 'start' as the victim, LOCK_VICTIM_IS_OTHER if a
|
||||
deadlock was found and we chose some other trx as a victim: we must do
|
||||
the search again in this last case because there may be another
|
||||
deadlock! */
|
||||
deadlock!
|
||||
LOCK_EXCEED_MAX_DEPTH if the lock search exceeds max steps or max depth. */
|
||||
static
|
||||
ulint
|
||||
lock_deadlock_recursive(
|
||||
/*====================*/
|
||||
trx_t* start, /*!< in: recursion starting point */
|
||||
trx_t* trx, /*!< in: a transaction waiting for a lock */
|
||||
lock_t* wait_lock, /*!< in: the lock trx is waiting to be granted */
|
||||
lock_t* wait_lock, /*!< in: lock that is waiting to be granted */
|
||||
ulint* cost, /*!< in/out: number of calculation steps thus
|
||||
far: if this exceeds LOCK_MAX_N_STEPS_...
|
||||
we return LOCK_VICTIM_IS_START */
|
||||
we return LOCK_EXCEED_MAX_DEPTH */
|
||||
ulint depth); /*!< in: recursion depth: if this exceeds
|
||||
LOCK_MAX_DEPTH_IN_DEADLOCK_CHECK, we
|
||||
return LOCK_VICTIM_IS_START */
|
||||
return LOCK_EXCEED_MAX_DEPTH */
|
||||
|
||||
/*********************************************************************//**
|
||||
Gets the nth bit of a record lock.
|
||||
@return TRUE if bit set */
|
||||
@return TRUE if bit set also if i == ULINT_UNDEFINED return FALSE*/
|
||||
UNIV_INLINE
|
||||
ibool
|
||||
lock_rec_get_nth_bit(
|
||||
|
@ -1222,7 +1224,7 @@ lock_rec_get_first_on_page(
|
|||
|
||||
/*********************************************************************//**
|
||||
Gets the next explicit lock request on a record.
|
||||
@return next lock, NULL if none exists */
|
||||
@return next lock, NULL if none exists or if heap_no == ULINT_UNDEFINED */
|
||||
UNIV_INLINE
|
||||
lock_t*
|
||||
lock_rec_get_next(
|
||||
|
@ -2404,7 +2406,7 @@ lock_rec_inherit_to_gap(
|
|||
if (!lock_rec_get_insert_intention(lock)
|
||||
&& !((srv_locks_unsafe_for_binlog
|
||||
|| lock->trx->isolation_level
|
||||
== TRX_ISO_READ_COMMITTED)
|
||||
<= TRX_ISO_READ_COMMITTED)
|
||||
&& lock_get_mode(lock) == LOCK_X)) {
|
||||
|
||||
lock_rec_add_to_queue(LOCK_REC | LOCK_GAP
|
||||
|
@ -3267,8 +3269,6 @@ lock_deadlock_occurs(
|
|||
lock_t* lock, /*!< in: lock the transaction is requesting */
|
||||
trx_t* trx) /*!< in: transaction */
|
||||
{
|
||||
dict_table_t* table;
|
||||
dict_index_t* index;
|
||||
trx_t* mark_trx;
|
||||
ulint ret;
|
||||
ulint cost = 0;
|
||||
|
@ -3290,31 +3290,51 @@ retry:
|
|||
|
||||
ret = lock_deadlock_recursive(trx, trx, lock, &cost, 0);
|
||||
|
||||
if (ret == LOCK_VICTIM_IS_OTHER) {
|
||||
switch (ret) {
|
||||
case LOCK_VICTIM_IS_OTHER:
|
||||
/* We chose some other trx as a victim: retry if there still
|
||||
is a deadlock */
|
||||
|
||||
goto retry;
|
||||
}
|
||||
|
||||
if (UNIV_UNLIKELY(ret == LOCK_VICTIM_IS_START)) {
|
||||
if (lock_get_type_low(lock) & LOCK_TABLE) {
|
||||
table = lock->un_member.tab_lock.table;
|
||||
index = NULL;
|
||||
} else {
|
||||
index = lock->index;
|
||||
table = index->table;
|
||||
}
|
||||
case LOCK_EXCEED_MAX_DEPTH:
|
||||
/* If the lock search exceeds the max step
|
||||
or the max depth, the current trx will be
|
||||
the victim. Print its information. */
|
||||
rewind(lock_latest_err_file);
|
||||
ut_print_timestamp(lock_latest_err_file);
|
||||
|
||||
lock_deadlock_found = TRUE;
|
||||
|
||||
fputs("*** WE ROLL BACK TRANSACTION (2)\n",
|
||||
fputs("TOO DEEP OR LONG SEARCH IN THE LOCK TABLE"
|
||||
" WAITS-FOR GRAPH, WE WILL ROLL BACK"
|
||||
" FOLLOWING TRANSACTION \n",
|
||||
lock_latest_err_file);
|
||||
|
||||
return(TRUE);
|
||||
fputs("\n*** TRANSACTION:\n", lock_latest_err_file);
|
||||
trx_print(lock_latest_err_file, trx, 3000);
|
||||
|
||||
fputs("*** WAITING FOR THIS LOCK TO BE GRANTED:\n",
|
||||
lock_latest_err_file);
|
||||
|
||||
if (lock_get_type(lock) == LOCK_REC) {
|
||||
lock_rec_print(lock_latest_err_file, lock);
|
||||
} else {
|
||||
lock_table_print(lock_latest_err_file, lock);
|
||||
}
|
||||
break;
|
||||
|
||||
case LOCK_VICTIM_IS_START:
|
||||
srv_n_lock_deadlock_count++;
|
||||
fputs("*** WE ROLL BACK TRANSACTION (2)\n",
|
||||
lock_latest_err_file);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* No deadlock detected*/
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
lock_deadlock_found = TRUE;
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
|
@ -3323,25 +3343,26 @@ Looks recursively for a deadlock.
|
|||
deadlock and we chose 'start' as the victim, LOCK_VICTIM_IS_OTHER if a
|
||||
deadlock was found and we chose some other trx as a victim: we must do
|
||||
the search again in this last case because there may be another
|
||||
deadlock! */
|
||||
deadlock!
|
||||
LOCK_EXCEED_MAX_DEPTH if the lock search exceeds max steps or max depth. */
|
||||
static
|
||||
ulint
|
||||
lock_deadlock_recursive(
|
||||
/*====================*/
|
||||
trx_t* start, /*!< in: recursion starting point */
|
||||
trx_t* trx, /*!< in: a transaction waiting for a lock */
|
||||
lock_t* wait_lock, /*!< in: the lock trx is waiting to be granted */
|
||||
lock_t* wait_lock, /*!< in: lock that is waiting to be granted */
|
||||
ulint* cost, /*!< in/out: number of calculation steps thus
|
||||
far: if this exceeds LOCK_MAX_N_STEPS_...
|
||||
we return LOCK_VICTIM_IS_START */
|
||||
we return LOCK_EXCEED_MAX_DEPTH */
|
||||
ulint depth) /*!< in: recursion depth: if this exceeds
|
||||
LOCK_MAX_DEPTH_IN_DEADLOCK_CHECK, we
|
||||
return LOCK_VICTIM_IS_START */
|
||||
return LOCK_EXCEED_MAX_DEPTH */
|
||||
{
|
||||
lock_t* lock;
|
||||
ulint bit_no = ULINT_UNDEFINED;
|
||||
trx_t* lock_trx;
|
||||
ulint ret;
|
||||
lock_t* lock;
|
||||
trx_t* lock_trx;
|
||||
ulint heap_no = ULINT_UNDEFINED;
|
||||
|
||||
ut_a(trx);
|
||||
ut_a(start);
|
||||
|
@ -3357,27 +3378,44 @@ lock_deadlock_recursive(
|
|||
|
||||
*cost = *cost + 1;
|
||||
|
||||
lock = wait_lock;
|
||||
|
||||
if (lock_get_type_low(wait_lock) == LOCK_REC) {
|
||||
ulint space;
|
||||
ulint page_no;
|
||||
|
||||
bit_no = lock_rec_find_set_bit(wait_lock);
|
||||
heap_no = lock_rec_find_set_bit(wait_lock);
|
||||
ut_a(heap_no != ULINT_UNDEFINED);
|
||||
|
||||
ut_a(bit_no != ULINT_UNDEFINED);
|
||||
space = wait_lock->un_member.rec_lock.space;
|
||||
page_no = wait_lock->un_member.rec_lock.page_no;
|
||||
|
||||
lock = lock_rec_get_first_on_page_addr(space, page_no);
|
||||
|
||||
/* Position the iterator on the first matching record lock. */
|
||||
while (lock != NULL
|
||||
&& lock != wait_lock
|
||||
&& !lock_rec_get_nth_bit(lock, heap_no)) {
|
||||
|
||||
lock = lock_rec_get_next_on_page(lock);
|
||||
}
|
||||
|
||||
if (lock == wait_lock) {
|
||||
lock = NULL;
|
||||
}
|
||||
|
||||
ut_ad(lock == NULL || lock_rec_get_nth_bit(lock, heap_no));
|
||||
|
||||
} else {
|
||||
lock = wait_lock;
|
||||
}
|
||||
|
||||
/* Look at the locks ahead of wait_lock in the lock queue */
|
||||
|
||||
for (;;) {
|
||||
if (lock_get_type_low(lock) & LOCK_TABLE) {
|
||||
/* Get previous table lock. */
|
||||
if (heap_no == ULINT_UNDEFINED) {
|
||||
|
||||
lock = UT_LIST_GET_PREV(un_member.tab_lock.locks,
|
||||
lock);
|
||||
} else {
|
||||
ut_ad(lock_get_type_low(lock) == LOCK_REC);
|
||||
ut_a(bit_no != ULINT_UNDEFINED);
|
||||
|
||||
lock = (lock_t*) lock_rec_get_prev(lock, bit_no);
|
||||
lock = UT_LIST_GET_PREV(
|
||||
un_member.tab_lock.locks, lock);
|
||||
}
|
||||
|
||||
if (lock == NULL) {
|
||||
|
@ -3395,7 +3433,7 @@ lock_deadlock_recursive(
|
|||
|
||||
lock_trx = lock->trx;
|
||||
|
||||
if (lock_trx == start || too_far) {
|
||||
if (lock_trx == start) {
|
||||
|
||||
/* We came back to the recursion starting
|
||||
point: a deadlock detected; or we have
|
||||
|
@ -3442,19 +3480,10 @@ lock_deadlock_recursive(
|
|||
}
|
||||
#ifdef UNIV_DEBUG
|
||||
if (lock_print_waits) {
|
||||
fputs("Deadlock detected"
|
||||
" or too long search\n",
|
||||
fputs("Deadlock detected\n",
|
||||
stderr);
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
if (too_far) {
|
||||
|
||||
fputs("TOO DEEP OR LONG SEARCH"
|
||||
" IN THE LOCK TABLE"
|
||||
" WAITS-FOR GRAPH\n", ef);
|
||||
|
||||
return(LOCK_VICTIM_IS_START);
|
||||
}
|
||||
|
||||
if (trx_weight_cmp(wait_lock->trx,
|
||||
start) >= 0) {
|
||||
|
@ -3490,6 +3519,21 @@ lock_deadlock_recursive(
|
|||
return(LOCK_VICTIM_IS_OTHER);
|
||||
}
|
||||
|
||||
if (too_far) {
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
if (lock_print_waits) {
|
||||
fputs("Deadlock search exceeds"
|
||||
" max steps or depth.\n",
|
||||
stderr);
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
/* The information about transaction/lock
|
||||
to be rolled back is available in the top
|
||||
level. Do not print anything here. */
|
||||
return(LOCK_EXCEED_MAX_DEPTH);
|
||||
}
|
||||
|
||||
if (lock_trx->que_state == TRX_QUE_LOCK_WAIT) {
|
||||
|
||||
/* Another trx ahead has requested lock in an
|
||||
|
@ -3499,12 +3543,28 @@ lock_deadlock_recursive(
|
|||
ret = lock_deadlock_recursive(
|
||||
start, lock_trx,
|
||||
lock_trx->wait_lock, cost, depth + 1);
|
||||
|
||||
if (ret != 0) {
|
||||
|
||||
return(ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Get the next record lock to check. */
|
||||
if (heap_no != ULINT_UNDEFINED) {
|
||||
|
||||
ut_a(lock != NULL);
|
||||
|
||||
do {
|
||||
lock = lock_rec_get_next_on_page(lock);
|
||||
} while (lock != NULL
|
||||
&& lock != wait_lock
|
||||
&& !lock_rec_get_nth_bit(lock, heap_no));
|
||||
|
||||
if (lock == wait_lock) {
|
||||
lock = NULL;
|
||||
}
|
||||
}
|
||||
}/* end of the 'for (;;)'-loop */
|
||||
}
|
||||
|
||||
|
@ -3706,9 +3766,10 @@ lock_table_enqueue_waiting(
|
|||
|
||||
/*********************************************************************//**
|
||||
Checks if other transactions have an incompatible mode lock request in
|
||||
the lock queue. */
|
||||
the lock queue.
|
||||
@return lock or NULL */
|
||||
UNIV_INLINE
|
||||
ibool
|
||||
lock_t*
|
||||
lock_table_other_has_incompatible(
|
||||
/*==============================*/
|
||||
trx_t* trx, /*!< in: transaction, or NULL if all
|
||||
|
@ -3730,13 +3791,13 @@ lock_table_other_has_incompatible(
|
|||
&& (!lock_mode_compatible(lock_get_mode(lock), mode))
|
||||
&& (wait || !(lock_get_wait(lock)))) {
|
||||
|
||||
return(TRUE);
|
||||
return(lock);
|
||||
}
|
||||
|
||||
lock = UT_LIST_GET_PREV(un_member.tab_lock.locks, lock);
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
|
@ -4260,31 +4321,34 @@ lock_rec_print(
|
|||
putc('\n', file);
|
||||
|
||||
if ( srv_show_verbose_locks ) {
|
||||
block = buf_page_try_get(space, page_no, &mtr);
|
||||
if (block) {
|
||||
for (i = 0; i < lock_rec_get_n_bits(lock); i++) {
|
||||
block = buf_page_try_get(space, page_no, &mtr);
|
||||
|
||||
if (lock_rec_get_nth_bit(lock, i)) {
|
||||
for (i = 0; i < lock_rec_get_n_bits(lock); ++i) {
|
||||
|
||||
const rec_t* rec
|
||||
= page_find_rec_with_heap_no(
|
||||
buf_block_get_frame(block), i);
|
||||
offsets = rec_get_offsets(
|
||||
rec, lock->index, offsets,
|
||||
ULINT_UNDEFINED, &heap);
|
||||
|
||||
fprintf(file, "Record lock, heap no %lu ",
|
||||
(ulong) i);
|
||||
rec_print_new(file, rec, offsets);
|
||||
putc('\n', file);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < lock_rec_get_n_bits(lock); i++) {
|
||||
fprintf(file, "Record lock, heap no %lu\n", (ulong) i);
|
||||
}
|
||||
if (!lock_rec_get_nth_bit(lock, i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
fprintf(file, "Record lock, heap no %lu", (ulong) i);
|
||||
|
||||
if (block) {
|
||||
const rec_t* rec;
|
||||
|
||||
rec = page_find_rec_with_heap_no(
|
||||
buf_block_get_frame(block), i);
|
||||
|
||||
offsets = rec_get_offsets(
|
||||
rec, lock->index, offsets,
|
||||
ULINT_UNDEFINED, &heap);
|
||||
|
||||
putc(' ', file);
|
||||
rec_print_new(file, rec, offsets);
|
||||
}
|
||||
|
||||
putc('\n', file);
|
||||
}
|
||||
}
|
||||
|
||||
mtr_commit(&mtr);
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
|
@ -4329,14 +4393,26 @@ lock_get_n_rec_locks(void)
|
|||
#endif /* PRINT_NUM_OF_LOCK_STRUCTS */
|
||||
|
||||
/*********************************************************************//**
|
||||
Prints info of locks for all transactions. */
|
||||
Prints info of locks for all transactions.
|
||||
@return FALSE if not able to obtain kernel mutex
|
||||
and exits without printing info */
|
||||
UNIV_INTERN
|
||||
void
|
||||
ibool
|
||||
lock_print_info_summary(
|
||||
/*====================*/
|
||||
FILE* file) /*!< in: file where to print */
|
||||
FILE* file, /*!< in: file where to print */
|
||||
ibool nowait) /*!< in: whether to wait for the kernel mutex */
|
||||
{
|
||||
lock_mutex_enter_kernel();
|
||||
/* if nowait is FALSE, wait on the kernel mutex,
|
||||
otherwise return immediately if fail to obtain the
|
||||
mutex. */
|
||||
if (!nowait) {
|
||||
lock_mutex_enter_kernel();
|
||||
} else if (mutex_enter_nowait(&kernel_mutex)) {
|
||||
fputs("FAIL TO OBTAIN KERNEL MUTEX, "
|
||||
"SKIP LOCK INFO PRINTING\n", file);
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
if (lock_deadlock_found) {
|
||||
fputs("------------------------\n"
|
||||
|
@ -4368,6 +4444,7 @@ lock_print_info_summary(
|
|||
"Total number of lock structs in row lock hash table %lu\n",
|
||||
(ulong) lock_get_n_rec_locks());
|
||||
#endif /* PRINT_NUM_OF_LOCK_STRUCTS */
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
|
@ -4648,6 +4725,7 @@ lock_rec_queue_validate(
|
|||
ut_a(lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP,
|
||||
block, heap_no, impl_trx));
|
||||
}
|
||||
#if 0
|
||||
} else {
|
||||
|
||||
/* The kernel mutex may get released temporarily in the
|
||||
|
@ -4658,6 +4736,27 @@ lock_rec_queue_validate(
|
|||
(fil_space_t::latch), the following check WILL break
|
||||
latching order and may cause a deadlock of threads. */
|
||||
|
||||
/* NOTE: This is a bogus check that would fail in the
|
||||
following case: Our transaction is updating a
|
||||
row. After it has updated the clustered index record,
|
||||
it goes to a secondary index record and finds someone
|
||||
else holding an explicit S- or X-lock on that
|
||||
secondary index record, presumably from a locking
|
||||
read. Our transaction cannot update the secondary
|
||||
index immediately, but places a waiting X-lock request
|
||||
on the secondary index record. There is nothing
|
||||
illegal in this. The assertion is simply too strong. */
|
||||
|
||||
/* From the locking point of view, each secondary
|
||||
index is a separate table. A lock that is held on
|
||||
secondary index rec does not give any rights to modify
|
||||
or read the clustered index rec. Therefore, we can
|
||||
think of the sec index as a separate 'table' from the
|
||||
clust index 'table'. Conversely, a transaction that
|
||||
has acquired a lock on and modified a clustered index
|
||||
record may need to wait for a lock on the
|
||||
corresponding record in a secondary index. */
|
||||
|
||||
impl_trx = lock_sec_rec_some_has_impl_off_kernel(
|
||||
rec, index, offsets);
|
||||
|
||||
|
@ -4668,6 +4767,7 @@ lock_rec_queue_validate(
|
|||
ut_a(lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP,
|
||||
block, heap_no, impl_trx));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
lock = lock_rec_get_first(block, heap_no);
|
||||
|
@ -4765,6 +4865,13 @@ loop:
|
|||
|| lock->trx->conc_state == TRX_PREPARED
|
||||
|| lock->trx->conc_state == TRX_COMMITTED_IN_MEMORY);
|
||||
|
||||
# ifdef UNIV_SYNC_DEBUG
|
||||
/* Only validate the record queues when this thread is not
|
||||
holding a space->latch. Deadlocks are possible due to
|
||||
latching order violation when UNIV_DEBUG is defined while
|
||||
UNIV_SYNC_DEBUG is not. */
|
||||
if (!sync_thread_levels_contains(SYNC_FSP))
|
||||
# endif /* UNIV_SYNC_DEBUG */
|
||||
for (i = nth_bit; i < lock_rec_get_n_bits(lock); i++) {
|
||||
|
||||
if (i == 1 || lock_rec_get_nth_bit(lock, i)) {
|
||||
|
@ -4930,7 +5037,7 @@ lock_rec_insert_check_and_lock(
|
|||
}
|
||||
|
||||
trx = thr_get_trx(thr);
|
||||
next_rec = page_rec_get_next((rec_t*) rec);
|
||||
next_rec = page_rec_get_next_const(rec);
|
||||
next_rec_heap_no = page_rec_get_heap_no(next_rec);
|
||||
|
||||
lock_mutex_enter_kernel();
|
||||
|
|
|
@ -1,23 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||
Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*****************************************************************************/
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 2009, Google Inc.
|
||||
|
||||
Portions of this file contain modifications contributed and copyrighted by
|
||||
|
@ -2045,7 +2028,7 @@ log_checkpoint(
|
|||
return(TRUE);
|
||||
}
|
||||
|
||||
ut_ad(log_sys->written_to_all_lsn >= oldest_lsn);
|
||||
ut_ad(log_sys->flushed_to_disk_lsn >= oldest_lsn);
|
||||
|
||||
if (log_sys->n_pending_checkpoint_writes > 0) {
|
||||
/* A checkpoint write is running */
|
||||
|
@ -3127,7 +3110,7 @@ loop:
|
|||
|
||||
if (srv_fast_shutdown < 2
|
||||
&& (srv_error_monitor_active
|
||||
|| srv_lock_timeout_and_monitor_active)) {
|
||||
|| srv_lock_timeout_active || srv_monitor_active)) {
|
||||
|
||||
mutex_exit(&kernel_mutex);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1997, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1997, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -138,7 +138,9 @@ UNIV_INTERN ulint recv_max_parsed_page_no;
|
|||
/** This many frames must be left free in the buffer pool when we scan
|
||||
the log and store the scanned log records in the buffer pool: we will
|
||||
use these free frames to read in pages when we start applying the
|
||||
log records to the database. */
|
||||
log records to the database.
|
||||
This is the default value. If the actual size of the buffer pool is
|
||||
larger than 10 MB we'll set this value to 512. */
|
||||
UNIV_INTERN ulint recv_n_pool_free_frames;
|
||||
|
||||
/** The maximum lsn we see for a page during the recovery process. If this
|
||||
|
@ -242,6 +244,7 @@ recv_sys_mem_free(void)
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
/************************************************************
|
||||
Reset the state of the recovery system variables. */
|
||||
UNIV_INTERN
|
||||
|
@ -251,7 +254,7 @@ recv_sys_var_init(void)
|
|||
{
|
||||
recv_lsn_checks_on = FALSE;
|
||||
|
||||
recv_n_pool_free_frames = 1024;
|
||||
recv_n_pool_free_frames = 256;
|
||||
|
||||
recv_recovery_on = FALSE;
|
||||
|
||||
|
@ -277,10 +280,11 @@ recv_sys_var_init(void)
|
|||
|
||||
recv_max_parsed_page_no = 0;
|
||||
|
||||
recv_n_pool_free_frames = 1024;
|
||||
recv_n_pool_free_frames = 256;
|
||||
|
||||
recv_max_page_lsn = 0;
|
||||
}
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
|
||||
/************************************************************
|
||||
Inits the recovery system for a recovery operation. */
|
||||
|
@ -295,20 +299,37 @@ recv_sys_init(
|
|||
return;
|
||||
}
|
||||
|
||||
/* Initialize red-black tree for fast insertions into the
|
||||
flush_list during recovery process.
|
||||
As this initialization is done while holding the buffer pool
|
||||
mutex we perform it before acquiring recv_sys->mutex. */
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
buf_flush_init_flush_rbt();
|
||||
|
||||
mutex_enter(&(recv_sys->mutex));
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
recv_sys->heap = mem_heap_create_in_buffer(256);
|
||||
#else /* !UNIV_HOTBACKUP */
|
||||
recv_sys->heap = mem_heap_create(256);
|
||||
recv_is_from_backup = TRUE;
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
|
||||
/* Set appropriate value of recv_n_pool_free_frames. */
|
||||
if (buf_pool_get_curr_size() >= (10 * 1024 * 1024)) {
|
||||
/* Buffer pool of size greater than 10 MB. */
|
||||
recv_n_pool_free_frames = 512;
|
||||
}
|
||||
|
||||
if (buf_pool_get_curr_size() >= (32 * 1024 * 1024)) {
|
||||
/* Buffer pool of size greater than 32 MB. */
|
||||
recv_n_pool_free_frames = 1024;
|
||||
}
|
||||
|
||||
recv_sys->buf = ut_malloc(RECV_PARSING_BUF_SIZE);
|
||||
recv_sys->len = 0;
|
||||
recv_sys->recovered_offset = 0;
|
||||
|
||||
recv_sys->addr_hash = hash_create(available_memory / 64);
|
||||
recv_sys->addr_hash = hash_create(available_memory / 512);
|
||||
recv_sys->n_addrs = 0;
|
||||
|
||||
recv_sys->apply_log_recs = FALSE;
|
||||
|
@ -348,7 +369,7 @@ recv_sys_empty_hash(void)
|
|||
hash_table_free(recv_sys->addr_hash);
|
||||
mem_heap_empty(recv_sys->heap);
|
||||
|
||||
recv_sys->addr_hash = hash_create(buf_pool_get_curr_size() / 256);
|
||||
recv_sys->addr_hash = hash_create(buf_pool_get_curr_size() / 512);
|
||||
}
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
|
@ -373,6 +394,9 @@ recv_sys_debug_free(void)
|
|||
recv_sys->last_block_buf_start = NULL;
|
||||
|
||||
mutex_exit(&(recv_sys->mutex));
|
||||
|
||||
/* Free up the flush_rbt. */
|
||||
buf_flush_free_flush_rbt();
|
||||
}
|
||||
# endif /* UNIV_LOG_DEBUG */
|
||||
|
||||
|
@ -2117,15 +2141,6 @@ recv_parse_log_rec(
|
|||
}
|
||||
#endif /* UNIV_LOG_LSN_DEBUG */
|
||||
|
||||
/* Check that page_no is sensible */
|
||||
|
||||
if (UNIV_UNLIKELY(*page_no > 0x8FFFFFFFUL)) {
|
||||
|
||||
recv_sys->found_corrupt_log = TRUE;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
new_ptr = recv_parse_or_apply_log_rec_body(*type, new_ptr, end_ptr,
|
||||
NULL, NULL);
|
||||
if (UNIV_UNLIKELY(new_ptr == NULL)) {
|
||||
|
@ -2234,6 +2249,14 @@ recv_report_corrupt_log(
|
|||
putc('\n', stderr);
|
||||
}
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
if (!srv_force_recovery) {
|
||||
fputs("InnoDB: Set innodb_force_recovery"
|
||||
" to ignore this error.\n", stderr);
|
||||
ut_error;
|
||||
}
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
|
||||
fputs("InnoDB: WARNING: the log file may have been corrupt and it\n"
|
||||
"InnoDB: is possible that the log scan did not proceed\n"
|
||||
"InnoDB: far enough in recovery! Please run CHECK TABLE\n"
|
||||
|
@ -2623,7 +2646,7 @@ recv_scan_log_recs(
|
|||
|
||||
ut_ad(start_lsn % OS_FILE_LOG_BLOCK_SIZE == 0);
|
||||
ut_ad(len % OS_FILE_LOG_BLOCK_SIZE == 0);
|
||||
ut_ad(len > 0);
|
||||
ut_ad(len >= OS_FILE_LOG_BLOCK_SIZE);
|
||||
ut_a(store_to_hash <= TRUE);
|
||||
|
||||
finished = FALSE;
|
||||
|
@ -2748,6 +2771,16 @@ recv_scan_log_recs(
|
|||
|
||||
recv_sys->found_corrupt_log = TRUE;
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
if (!srv_force_recovery) {
|
||||
fputs("InnoDB: Set"
|
||||
" innodb_force_recovery"
|
||||
" to ignore this error.\n",
|
||||
stderr);
|
||||
ut_error;
|
||||
}
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
|
||||
} else if (!recv_sys->found_corrupt_log) {
|
||||
more_data = recv_sys_add_to_parsing_buf(
|
||||
log_block, scanned_lsn);
|
||||
|
@ -3277,8 +3310,6 @@ void
|
|||
recv_recovery_from_checkpoint_finish(void)
|
||||
/*======================================*/
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Apply the hashed log records to the respective file pages */
|
||||
|
||||
if (srv_force_recovery < SRV_FORCE_NO_LOG_REDO) {
|
||||
|
@ -3404,9 +3435,16 @@ recv_recovery_from_checkpoint_finish(void)
|
|||
The data dictionary latch should guarantee that there is at
|
||||
most one data dictionary transaction active at a time. */
|
||||
trx_rollback_or_clean_recovered(FALSE);
|
||||
}
|
||||
|
||||
/* Drop partially created indexes. */
|
||||
row_merge_drop_temp_indexes();
|
||||
/********************************************************//**
|
||||
Initiates the rollback of active transactions. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
recv_recovery_rollback_active(void)
|
||||
/*===============================*/
|
||||
{
|
||||
int i;
|
||||
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
/* Wait for a while so that created threads have time to suspend
|
||||
|
@ -3416,6 +3454,11 @@ recv_recovery_from_checkpoint_finish(void)
|
|||
/* Switch latching order checks on in sync0sync.c */
|
||||
sync_order_checks_on = TRUE;
|
||||
#endif
|
||||
/* Drop partially created indexes. */
|
||||
row_merge_drop_temp_indexes();
|
||||
/* Drop temporary tables. */
|
||||
row_mysql_drop_temp_tables();
|
||||
|
||||
if (srv_force_recovery < SRV_FORCE_NO_TRX_UNDO) {
|
||||
/* Rollback the uncommitted transactions which have no user
|
||||
session */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1994, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -180,6 +180,10 @@ mem_close(void)
|
|||
{
|
||||
mem_pool_free(mem_comm_pool);
|
||||
mem_comm_pool = NULL;
|
||||
#ifdef UNIV_MEM_DEBUG
|
||||
mutex_free(&mem_hash_mutex);
|
||||
mem_hash_initialized = FALSE;
|
||||
#endif /* UNIV_MEM_DEBUG */
|
||||
}
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1994, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -383,6 +383,20 @@ mem_heap_create_block(
|
|||
mem_block_set_free(block, MEM_BLOCK_HEADER_SIZE);
|
||||
mem_block_set_start(block, MEM_BLOCK_HEADER_SIZE);
|
||||
|
||||
if (UNIV_UNLIKELY(heap == NULL)) {
|
||||
/* This is the first block of the heap. The field
|
||||
total_size should be initialized here */
|
||||
block->total_size = len;
|
||||
} else {
|
||||
/* Not the first allocation for the heap. This block's
|
||||
total_length field should be set to undefined. */
|
||||
ut_d(block->total_size = ULINT_UNDEFINED);
|
||||
UNIV_MEM_INVALID(&block->total_size,
|
||||
sizeof block->total_size);
|
||||
|
||||
heap->total_size += len;
|
||||
}
|
||||
|
||||
ut_ad((ulint)MEM_BLOCK_HEADER_SIZE < len);
|
||||
|
||||
return(block);
|
||||
|
@ -471,6 +485,10 @@ mem_heap_block_free(
|
|||
|
||||
mem_pool_mutex_exit();
|
||||
#endif
|
||||
|
||||
ut_ad(heap->total_size >= block->len);
|
||||
heap->total_size -= block->len;
|
||||
|
||||
type = heap->type;
|
||||
len = block->len;
|
||||
block->magic_n = MEM_FREED_BLOCK_MAGIC_N;
|
||||
|
|
32
os/os0file.c
32
os/os0file.c
|
@ -1,23 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||
Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*****************************************************************************/
|
||||
/***********************************************************************
|
||||
|
||||
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 2009, Percona Inc.
|
||||
|
||||
Portions of this file contain modifications contributed and copyrighted
|
||||
|
@ -846,7 +829,15 @@ next_file:
|
|||
#ifdef HAVE_READDIR_R
|
||||
ret = readdir_r(dir, (struct dirent*)dirent_buf, &ent);
|
||||
|
||||
if (ret != 0) {
|
||||
if (ret != 0
|
||||
#ifdef UNIV_AIX
|
||||
/* On AIX, only if we got non-NULL 'ent' (result) value and
|
||||
a non-zero 'ret' (return) value, it indicates a failed
|
||||
readdir_r() call. An NULL 'ent' with an non-zero 'ret'
|
||||
would indicate the "end of the directory" is reached. */
|
||||
&& ent != NULL
|
||||
#endif
|
||||
) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: cannot read directory %s, error %lu\n",
|
||||
dirname, (ulong)ret);
|
||||
|
@ -4030,6 +4021,9 @@ os_aio_simulated_handle(
|
|||
ulint i;
|
||||
time_t now;
|
||||
|
||||
/* Fix compiler warning */
|
||||
*consecutive_ios = NULL;
|
||||
|
||||
segment = os_aio_get_array_and_local_segment(&array, global_segment);
|
||||
|
||||
restart:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
|
||||
Copyright (c) 1994, 2010, Innobase Oy. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -658,6 +658,14 @@ page_copy_rec_list_end(
|
|||
index, mtr);
|
||||
}
|
||||
|
||||
/* Update PAGE_MAX_TRX_ID on the uncompressed page.
|
||||
Modifications will be redo logged and copied to the compressed
|
||||
page in page_zip_compress() or page_zip_reorganize() below. */
|
||||
if (dict_index_is_sec_or_ibuf(index) && page_is_leaf(page)) {
|
||||
page_update_max_trx_id(new_block, NULL,
|
||||
page_get_max_trx_id(page), mtr);
|
||||
}
|
||||
|
||||
if (UNIV_LIKELY_NULL(new_page_zip)) {
|
||||
mtr_set_log_mode(mtr, log_mode);
|
||||
|
||||
|
@ -696,15 +704,10 @@ page_copy_rec_list_end(
|
|||
}
|
||||
}
|
||||
|
||||
/* Update the lock table, MAX_TRX_ID, and possible hash index */
|
||||
/* Update the lock table and possible hash index */
|
||||
|
||||
lock_move_rec_list_end(new_block, block, rec);
|
||||
|
||||
if (dict_index_is_sec_or_ibuf(index) && page_is_leaf(page)) {
|
||||
page_update_max_trx_id(new_block, new_page_zip,
|
||||
page_get_max_trx_id(page), mtr);
|
||||
}
|
||||
|
||||
btr_search_move_or_delete_hash_entries(new_block, block, index);
|
||||
|
||||
return(ret);
|
||||
|
@ -772,6 +775,16 @@ page_copy_rec_list_start(
|
|||
mem_heap_free(heap);
|
||||
}
|
||||
|
||||
/* Update PAGE_MAX_TRX_ID on the uncompressed page.
|
||||
Modifications will be redo logged and copied to the compressed
|
||||
page in page_zip_compress() or page_zip_reorganize() below. */
|
||||
if (dict_index_is_sec_or_ibuf(index)
|
||||
&& page_is_leaf(page_align(rec))) {
|
||||
page_update_max_trx_id(new_block, NULL,
|
||||
page_get_max_trx_id(page_align(rec)),
|
||||
mtr);
|
||||
}
|
||||
|
||||
if (UNIV_LIKELY_NULL(new_page_zip)) {
|
||||
mtr_set_log_mode(mtr, log_mode);
|
||||
|
||||
|
@ -809,14 +822,7 @@ page_copy_rec_list_start(
|
|||
}
|
||||
}
|
||||
|
||||
/* Update MAX_TRX_ID, the lock table, and possible hash index */
|
||||
|
||||
if (dict_index_is_sec_or_ibuf(index)
|
||||
&& page_is_leaf(page_align(rec))) {
|
||||
page_update_max_trx_id(new_block, new_page_zip,
|
||||
page_get_max_trx_id(page_align(rec)),
|
||||
mtr);
|
||||
}
|
||||
/* Update the lock table and possible hash index */
|
||||
|
||||
lock_move_rec_list_start(new_block, block, rec, ret);
|
||||
|
||||
|
@ -2408,8 +2414,13 @@ page_validate(
|
|||
}
|
||||
|
||||
offs = page_offset(rec_get_start(rec, offsets));
|
||||
i = rec_offs_size(offsets);
|
||||
if (UNIV_UNLIKELY(offs + i >= UNIV_PAGE_SIZE)) {
|
||||
fputs("InnoDB: record offset out of bounds\n", stderr);
|
||||
goto func_exit;
|
||||
}
|
||||
|
||||
for (i = rec_offs_size(offsets); i--; ) {
|
||||
while (i--) {
|
||||
if (UNIV_UNLIKELY(buf[offs + i])) {
|
||||
/* No other record may overlap this */
|
||||
|
||||
|
@ -2517,8 +2528,13 @@ n_owned_zero:
|
|||
|
||||
count++;
|
||||
offs = page_offset(rec_get_start(rec, offsets));
|
||||
i = rec_offs_size(offsets);
|
||||
if (UNIV_UNLIKELY(offs + i >= UNIV_PAGE_SIZE)) {
|
||||
fputs("InnoDB: record offset out of bounds\n", stderr);
|
||||
goto func_exit;
|
||||
}
|
||||
|
||||
for (i = rec_offs_size(offsets); i--; ) {
|
||||
while (i--) {
|
||||
|
||||
if (UNIV_UNLIKELY(buf[offs + i])) {
|
||||
fputs("InnoDB: Record overlaps another"
|
||||
|
|
28
percona-suite/percona_innodb_deadlock_count.result
Normal file
28
percona-suite/percona_innodb_deadlock_count.result
Normal file
|
@ -0,0 +1,28 @@
|
|||
# Establish connection con1 (user=root)
|
||||
# Establish connection con2 (user=root)
|
||||
# Establish connection con3 (user=root)
|
||||
# Drop test table
|
||||
drop table if exists t;
|
||||
# Create test table
|
||||
create table t(a INT PRIMARY KEY, b INT) engine=InnoDB;
|
||||
# Insert two rows to test table
|
||||
insert into t values(2,1);
|
||||
insert into t values(1,2);
|
||||
# Switch to connection con1
|
||||
BEGIN;
|
||||
SELECT b FROM t WHERE a=1 FOR UPDATE;
|
||||
b
|
||||
2
|
||||
# Switch to connection con2
|
||||
BEGIN;
|
||||
SELECT b FROM t WHERE a=2 FOR UPDATE;
|
||||
b
|
||||
1
|
||||
# Switch to connection con1
|
||||
SELECT b FROM t WHERE a=2 FOR UPDATE;
|
||||
# Switch to connection con2
|
||||
SELECT b FROM t WHERE a=1 FOR UPDATE;
|
||||
# Switch to connection con3
|
||||
1
|
||||
# Drop test table
|
||||
drop table t;
|
49
percona-suite/percona_innodb_deadlock_count.test
Normal file
49
percona-suite/percona_innodb_deadlock_count.test
Normal file
|
@ -0,0 +1,49 @@
|
|||
--source include/have_innodb.inc
|
||||
--echo # Establish connection con1 (user=root)
|
||||
connect (con1,localhost,root,,);
|
||||
--echo # Establish connection con2 (user=root)
|
||||
connect (con2,localhost,root,,);
|
||||
--echo # Establish connection con3 (user=root)
|
||||
connect (con3,localhost,root,,);
|
||||
--echo # Drop test table
|
||||
--disable_warnings
|
||||
drop table if exists t;
|
||||
--enable_warnings
|
||||
disable_abort_on_error;
|
||||
|
||||
--echo # Create test table
|
||||
create table t(a INT PRIMARY KEY, b INT) engine=InnoDB;
|
||||
--echo # Insert two rows to test table
|
||||
insert into t values(2,1);
|
||||
insert into t values(1,2);
|
||||
|
||||
#--echo # Save current deadlock count
|
||||
let $current = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'Innodb_deadlocks'`;
|
||||
|
||||
--echo # Switch to connection con1
|
||||
connection con1;
|
||||
BEGIN; SELECT b FROM t WHERE a=1 FOR UPDATE;
|
||||
|
||||
#show engine innodb status;
|
||||
|
||||
--echo # Switch to connection con2
|
||||
connection con2;
|
||||
BEGIN; SELECT b FROM t WHERE a=2 FOR UPDATE;
|
||||
|
||||
--echo # Switch to connection con1
|
||||
connection con1;
|
||||
SEND SELECT b FROM t WHERE a=2 FOR UPDATE;
|
||||
|
||||
--echo # Switch to connection con2
|
||||
connection con2;
|
||||
SEND SELECT b FROM t WHERE a=1 FOR UPDATE;
|
||||
|
||||
SLEEP 0.2;
|
||||
--echo # Switch to connection con3
|
||||
connection con3;
|
||||
let $result = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'Innodb_deadlocks'`;
|
||||
|
||||
let $diff = `SELECT $result - $current`;
|
||||
echo $diff;
|
||||
--echo # Drop test table
|
||||
drop table t;
|
1
percona-suite/percona_innodb_doublewrite_file-master.opt
Normal file
1
percona-suite/percona_innodb_doublewrite_file-master.opt
Normal file
|
@ -0,0 +1 @@
|
|||
--innodb_doublewrite_file=ib_doublewrite
|
4
percona-suite/percona_innodb_doublewrite_file.result
Normal file
4
percona-suite/percona_innodb_doublewrite_file.result
Normal file
|
@ -0,0 +1,4 @@
|
|||
show variables like 'innodb_doublewrite%';
|
||||
Variable_name Value
|
||||
innodb_doublewrite ON
|
||||
innodb_doublewrite_file ib_doublewrite
|
2
percona-suite/percona_innodb_doublewrite_file.test
Normal file
2
percona-suite/percona_innodb_doublewrite_file.test
Normal file
|
@ -0,0 +1,2 @@
|
|||
--source include/have_innodb.inc
|
||||
show variables like 'innodb_doublewrite%';
|
|
@ -0,0 +1 @@
|
|||
--slow-query-log-file=percona_log_slow_slave_statements-master.log --long-query-time=1
|
|
@ -0,0 +1 @@
|
|||
--slow-query-log-file=percona_log_slow_slave_statements-slave.log --long-query-time=1
|
|
@ -0,0 +1,103 @@
|
|||
# Activate master-slave replication
|
||||
stop slave;
|
||||
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||
reset master;
|
||||
reset slave;
|
||||
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||
start slave;
|
||||
# Make table t for test
|
||||
DROP TABLE IF EXISTS t;
|
||||
CREATE TABLE t(id INT);
|
||||
# Start slave replication
|
||||
START SLAVE;
|
||||
INSERT INTO t VALUES (1);
|
||||
# Read information about master binlog
|
||||
# Sync(1) slave thread
|
||||
# Read and change log_slow_slave_statements to ON on slave
|
||||
show variables like 'log_slow_slave_statements';
|
||||
Variable_name Value
|
||||
log_slow_slave_statements OFF
|
||||
set global log_slow_slave_statements=ON;
|
||||
show variables like 'log_slow_slave_statements';
|
||||
Variable_name Value
|
||||
log_slow_slave_statements ON
|
||||
INSERT INTO t VALUES (2);
|
||||
# Read information about master binlog
|
||||
# Sync slave(2) thread
|
||||
# Restart slave
|
||||
STOP SLAVE;
|
||||
START SLAVE;
|
||||
INSERT INTO t VALUES (3);
|
||||
# Read information about master binlog
|
||||
# Sync(3) slave thread
|
||||
show variables like 'long_query_time';
|
||||
Variable_name Value
|
||||
long_query_time 1.000000
|
||||
show global variables like 'long_query_time';
|
||||
Variable_name Value
|
||||
long_query_time 1.000000
|
||||
show global variables like 'use_global_long_query_time';
|
||||
Variable_name Value
|
||||
use_global_long_query_time OFF
|
||||
set global long_query_time=0;
|
||||
show variables like 'long_query_time';
|
||||
Variable_name Value
|
||||
long_query_time 1.000000
|
||||
show global variables like 'long_query_time';
|
||||
Variable_name Value
|
||||
long_query_time 0.000000
|
||||
show global variables like 'use_global_long_query_time';
|
||||
Variable_name Value
|
||||
use_global_long_query_time OFF
|
||||
INSERT INTO t VALUES (4);
|
||||
# Read information about master binlog
|
||||
# Sync slave(4) thread
|
||||
show variables like 'long_query_time';
|
||||
Variable_name Value
|
||||
long_query_time 1.000000
|
||||
show global variables like 'long_query_time';
|
||||
Variable_name Value
|
||||
long_query_time 0.000000
|
||||
show global variables like 'use_global_long_query_time';
|
||||
Variable_name Value
|
||||
use_global_long_query_time OFF
|
||||
set global use_global_long_query_time=1;
|
||||
show variables like 'long_query_time';
|
||||
Variable_name Value
|
||||
long_query_time 0.000000
|
||||
show global variables like 'long_query_time';
|
||||
Variable_name Value
|
||||
long_query_time 0.000000
|
||||
show global variables like 'use_global_long_query_time';
|
||||
Variable_name Value
|
||||
use_global_long_query_time ON
|
||||
INSERT INTO t VALUES (5);
|
||||
# Read information about master binlog
|
||||
# Sync slave(5) thread
|
||||
show variables like 'long_query_time';
|
||||
Variable_name Value
|
||||
long_query_time 0.000000
|
||||
show global variables like 'long_query_time';
|
||||
Variable_name Value
|
||||
long_query_time 0.000000
|
||||
show global variables like 'use_global_long_query_time';
|
||||
Variable_name Value
|
||||
use_global_long_query_time ON
|
||||
set global long_query_time=1;
|
||||
set global use_global_long_query_time=0;
|
||||
# Analyse master slow_query_log
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
# Analyse slave slow_query_log
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
1
|
||||
set global log_slow_slave_statements=OFF;
|
||||
DROP TABLE t;
|
||||
# Read information about master binlog
|
||||
# Sync slave(6) thread
|
|
@ -0,0 +1,137 @@
|
|||
-- echo # Activate master-slave replication
|
||||
-- source include/master-slave.inc
|
||||
|
||||
connection master;
|
||||
-- echo # Make table t for test
|
||||
-- disable_warnings
|
||||
DROP TABLE IF EXISTS t;
|
||||
-- enable_warnings
|
||||
CREATE TABLE t(id INT);
|
||||
|
||||
|
||||
-- echo # Start slave replication
|
||||
-- disable_warnings
|
||||
connection slave;
|
||||
START SLAVE;
|
||||
-- source include/wait_for_slave_to_start.inc
|
||||
-- enable_warnings
|
||||
|
||||
#-- echo # Make insert(1) on master
|
||||
connection master;
|
||||
INSERT INTO t VALUES (1);
|
||||
-- echo # Read information about master binlog
|
||||
let $binlog_file = query_get_value(SHOW MASTER STATUS,File,1);
|
||||
let $binlog_position = query_get_value(SHOW MASTER STATUS,Position,1);
|
||||
|
||||
-- echo # Sync(1) slave thread
|
||||
connection slave;
|
||||
let $sync_result = `SELECT MASTER_POS_WAIT('$binlog_file',$binlog_position)`;
|
||||
|
||||
-- echo # Read and change log_slow_slave_statements to ON on slave
|
||||
show variables like 'log_slow_slave_statements';
|
||||
set global log_slow_slave_statements=ON;
|
||||
show variables like 'log_slow_slave_statements';
|
||||
|
||||
#-- echo # Make insert(2) on master
|
||||
connection master;
|
||||
INSERT INTO t VALUES (2);
|
||||
-- echo # Read information about master binlog
|
||||
let $binlog_file = query_get_value(SHOW MASTER STATUS,File,1);
|
||||
let $binlog_position = query_get_value(SHOW MASTER STATUS,Position,1);
|
||||
|
||||
-- echo # Sync slave(2) thread
|
||||
connection slave;
|
||||
let $sync_result = `SELECT MASTER_POS_WAIT('$binlog_file',$binlog_position)`;
|
||||
-- echo # Restart slave
|
||||
STOP SLAVE;
|
||||
-- source include/wait_for_slave_to_stop.inc
|
||||
START SLAVE;
|
||||
-- source include/wait_for_slave_to_start.inc
|
||||
|
||||
#-- echo # Make insert(3) on master
|
||||
connection master;
|
||||
INSERT INTO t VALUES (3);
|
||||
-- echo # Read information about master binlog
|
||||
let $binlog_file = query_get_value(SHOW MASTER STATUS,File,1);
|
||||
let $binlog_position = query_get_value(SHOW MASTER STATUS,Position,1);
|
||||
|
||||
-- echo # Sync(3) slave thread
|
||||
connection slave;
|
||||
let $sync_result = `SELECT MASTER_POS_WAIT('$binlog_file',$binlog_position)`;
|
||||
show variables like 'long_query_time';
|
||||
show global variables like 'long_query_time';
|
||||
show global variables like 'use_global_long_query_time';
|
||||
set global long_query_time=0;
|
||||
show variables like 'long_query_time';
|
||||
show global variables like 'long_query_time';
|
||||
show global variables like 'use_global_long_query_time';
|
||||
|
||||
#-- echo # Make insert(4) on master
|
||||
connection master;
|
||||
INSERT INTO t VALUES (4);
|
||||
-- echo # Read information about master binlog
|
||||
let $binlog_file = query_get_value(SHOW MASTER STATUS,File,1);
|
||||
let $binlog_position = query_get_value(SHOW MASTER STATUS,Position,1);
|
||||
|
||||
-- echo # Sync slave(4) thread
|
||||
connection slave;
|
||||
let $sync_result = `SELECT MASTER_POS_WAIT('$binlog_file',$binlog_position)`;
|
||||
show variables like 'long_query_time';
|
||||
show global variables like 'long_query_time';
|
||||
show global variables like 'use_global_long_query_time';
|
||||
set global use_global_long_query_time=1;
|
||||
show variables like 'long_query_time';
|
||||
show global variables like 'long_query_time';
|
||||
show global variables like 'use_global_long_query_time';
|
||||
|
||||
#-- echo # Make insert(5) on master
|
||||
connection master;
|
||||
INSERT INTO t VALUES (5);
|
||||
-- echo # Read information about master binlog
|
||||
let $binlog_file = query_get_value(SHOW MASTER STATUS,File,1);
|
||||
let $binlog_position = query_get_value(SHOW MASTER STATUS,Position,1);
|
||||
|
||||
-- echo # Sync slave(5) thread
|
||||
connection slave;
|
||||
let $sync_result = `SELECT MASTER_POS_WAIT('$binlog_file',$binlog_position)`;
|
||||
show variables like 'long_query_time';
|
||||
show global variables like 'long_query_time';
|
||||
show global variables like 'use_global_long_query_time';
|
||||
set global long_query_time=1;
|
||||
set global use_global_long_query_time=0;
|
||||
|
||||
-- echo # Analyse master slow_query_log
|
||||
let $i=5;
|
||||
let $k=1;
|
||||
let $cmd=cat ./var/mysqld.1/data/percona_log_slow_slave_statements-master.log | grep;
|
||||
while($i)
|
||||
{
|
||||
let $current_cmd = $cmd "INSERT INTO t VALUES ($k)" | wc -l;
|
||||
exec $current_cmd;
|
||||
dec $i;
|
||||
inc $k;
|
||||
}
|
||||
|
||||
-- echo # Analyse slave slow_query_log
|
||||
let $i=5;
|
||||
let $k=1;
|
||||
let $cmd=cat ./var/mysqld.2/data/percona_log_slow_slave_statements-slave.log | grep;
|
||||
while($i)
|
||||
{
|
||||
let $current_cmd = $cmd "INSERT INTO t VALUES ($k)" | wc -l;
|
||||
exec $current_cmd;
|
||||
dec $i;
|
||||
inc $k;
|
||||
}
|
||||
set global log_slow_slave_statements=OFF;
|
||||
|
||||
connection master;
|
||||
DROP TABLE t;
|
||||
|
||||
-- echo # Read information about master binlog
|
||||
let $binlog_file = query_get_value(SHOW MASTER STATUS,File,1);
|
||||
let $binlog_position = query_get_value(SHOW MASTER STATUS,Position,1);
|
||||
|
||||
-- echo # Sync slave(6) thread
|
||||
connection slave;
|
||||
let $sync_result = `SELECT MASTER_POS_WAIT('$binlog_file',$binlog_position)`;
|
|
@ -0,0 +1 @@
|
|||
--slow-query-log-file=percona_log_slow_slave_statements-master.log --long-query-time=0
|
|
@ -0,0 +1 @@
|
|||
--slow-query-log-file=percona_log_slow_slave_statements-slave.log --long-query-time=0
|
86
percona-suite/percona_log_slow_slave_statements.result
Normal file
86
percona-suite/percona_log_slow_slave_statements.result
Normal file
|
@ -0,0 +1,86 @@
|
|||
# Activate master-slave replication
|
||||
stop slave;
|
||||
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||
reset master;
|
||||
reset slave;
|
||||
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||
start slave;
|
||||
# Make table t for test
|
||||
DROP TABLE IF EXISTS t;
|
||||
CREATE TABLE t(id INT);
|
||||
# Start slave replication
|
||||
START SLAVE;
|
||||
INSERT INTO t VALUES (1);
|
||||
# Read information about master binlog
|
||||
# Sync(1) slave thread
|
||||
# Read and change log_slow_slave_statements to ON on slave
|
||||
show variables like 'log_slow_slave_statements';
|
||||
Variable_name Value
|
||||
log_slow_slave_statements OFF
|
||||
set global log_slow_slave_statements=ON;
|
||||
show variables like 'log_slow_slave_statements';
|
||||
Variable_name Value
|
||||
log_slow_slave_statements ON
|
||||
INSERT INTO t VALUES (2);
|
||||
# Read information about master binlog
|
||||
# Sync slave(2) thread
|
||||
# Restart slave
|
||||
STOP SLAVE;
|
||||
START SLAVE;
|
||||
INSERT INTO t VALUES (3);
|
||||
# Read information about master binlog
|
||||
# Sync(3) slave thread
|
||||
# Read and change log_slow_slave_statements to OFF on slave
|
||||
show variables like 'log_slow_slave_statements';
|
||||
Variable_name Value
|
||||
log_slow_slave_statements ON
|
||||
set global log_slow_slave_statements=OFF;
|
||||
show variables like 'log_slow_slave_statements';
|
||||
Variable_name Value
|
||||
log_slow_slave_statements OFF
|
||||
INSERT INTO t VALUES (4);
|
||||
# Read information about master binlog
|
||||
# Sync slave(4) thread
|
||||
# Restart slave
|
||||
STOP SLAVE;
|
||||
START SLAVE;
|
||||
INSERT INTO t VALUES (5);
|
||||
# Read information about master binlog
|
||||
# Sync slave(5) thread
|
||||
# Read and change log_slow_slave_statements to ON on slave
|
||||
show variables like 'log_slow_slave_statements';
|
||||
Variable_name Value
|
||||
log_slow_slave_statements OFF
|
||||
set global log_slow_slave_statements=ON;
|
||||
show variables like 'log_slow_slave_statements';
|
||||
Variable_name Value
|
||||
log_slow_slave_statements ON
|
||||
INSERT INTO t VALUES (6);
|
||||
# Read information about master binlog
|
||||
# Sync slave(6) thread
|
||||
# Restart slave
|
||||
STOP SLAVE;
|
||||
START SLAVE;
|
||||
INSERT INTO t VALUES (7);
|
||||
# Read information about master binlog
|
||||
# Sync slave(7) thread
|
||||
# Analyse master slow_query_log
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
# Analyse slave slow_query_log
|
||||
0
|
||||
0
|
||||
1
|
||||
0
|
||||
0
|
||||
0
|
||||
1
|
||||
set global log_slow_slave_statements=OFF;
|
||||
DROP TABLE t;
|
||||
# Read information about master binlog
|
||||
# Sync slave(8) thread
|
158
percona-suite/percona_log_slow_slave_statements.test
Normal file
158
percona-suite/percona_log_slow_slave_statements.test
Normal file
|
@ -0,0 +1,158 @@
|
|||
-- echo # Activate master-slave replication
|
||||
-- source include/master-slave.inc
|
||||
|
||||
connection master;
|
||||
-- echo # Make table t for test
|
||||
-- disable_warnings
|
||||
DROP TABLE IF EXISTS t;
|
||||
-- enable_warnings
|
||||
CREATE TABLE t(id INT);
|
||||
|
||||
|
||||
-- echo # Start slave replication
|
||||
-- disable_warnings
|
||||
connection slave;
|
||||
START SLAVE;
|
||||
-- source include/wait_for_slave_to_start.inc
|
||||
-- enable_warnings
|
||||
|
||||
#-- echo # Make insert(1) on master
|
||||
connection master;
|
||||
INSERT INTO t VALUES (1);
|
||||
-- echo # Read information about master binlog
|
||||
let $binlog_file = query_get_value(SHOW MASTER STATUS,File,1);
|
||||
let $binlog_position = query_get_value(SHOW MASTER STATUS,Position,1);
|
||||
|
||||
-- echo # Sync(1) slave thread
|
||||
connection slave;
|
||||
let $sync_result = `SELECT MASTER_POS_WAIT('$binlog_file',$binlog_position)`;
|
||||
|
||||
-- echo # Read and change log_slow_slave_statements to ON on slave
|
||||
show variables like 'log_slow_slave_statements';
|
||||
set global log_slow_slave_statements=ON;
|
||||
show variables like 'log_slow_slave_statements';
|
||||
|
||||
#-- echo # Make insert(2) on master
|
||||
connection master;
|
||||
INSERT INTO t VALUES (2);
|
||||
-- echo # Read information about master binlog
|
||||
let $binlog_file = query_get_value(SHOW MASTER STATUS,File,1);
|
||||
let $binlog_position = query_get_value(SHOW MASTER STATUS,Position,1);
|
||||
|
||||
-- echo # Sync slave(2) thread
|
||||
connection slave;
|
||||
let $sync_result = `SELECT MASTER_POS_WAIT('$binlog_file',$binlog_position)`;
|
||||
-- echo # Restart slave
|
||||
STOP SLAVE;
|
||||
-- source include/wait_for_slave_to_stop.inc
|
||||
START SLAVE;
|
||||
-- source include/wait_for_slave_to_start.inc
|
||||
|
||||
#-- echo # Make insert(3) on master
|
||||
connection master;
|
||||
INSERT INTO t VALUES (3);
|
||||
-- echo # Read information about master binlog
|
||||
let $binlog_file = query_get_value(SHOW MASTER STATUS,File,1);
|
||||
let $binlog_position = query_get_value(SHOW MASTER STATUS,Position,1);
|
||||
|
||||
-- echo # Sync(3) slave thread
|
||||
connection slave;
|
||||
let $sync_result = `SELECT MASTER_POS_WAIT('$binlog_file',$binlog_position)`;
|
||||
-- echo # Read and change log_slow_slave_statements to OFF on slave
|
||||
show variables like 'log_slow_slave_statements';
|
||||
set global log_slow_slave_statements=OFF;
|
||||
show variables like 'log_slow_slave_statements';
|
||||
|
||||
#-- echo # Make insert(4) on master
|
||||
connection master;
|
||||
INSERT INTO t VALUES (4);
|
||||
-- echo # Read information about master binlog
|
||||
let $binlog_file = query_get_value(SHOW MASTER STATUS,File,1);
|
||||
let $binlog_position = query_get_value(SHOW MASTER STATUS,Position,1);
|
||||
|
||||
-- echo # Sync slave(4) thread
|
||||
connection slave;
|
||||
let $sync_result = `SELECT MASTER_POS_WAIT('$binlog_file',$binlog_position)`;
|
||||
-- echo # Restart slave
|
||||
STOP SLAVE;
|
||||
-- source include/wait_for_slave_to_stop.inc
|
||||
START SLAVE;
|
||||
-- source include/wait_for_slave_to_start.inc
|
||||
|
||||
#-- echo # Make insert(5) on master
|
||||
connection master;
|
||||
INSERT INTO t VALUES (5);
|
||||
-- echo # Read information about master binlog
|
||||
let $binlog_file = query_get_value(SHOW MASTER STATUS,File,1);
|
||||
let $binlog_position = query_get_value(SHOW MASTER STATUS,Position,1);
|
||||
|
||||
-- echo # Sync slave(5) thread
|
||||
connection slave;
|
||||
let $sync_result = `SELECT MASTER_POS_WAIT('$binlog_file',$binlog_position)`;
|
||||
-- echo # Read and change log_slow_slave_statements to ON on slave
|
||||
show variables like 'log_slow_slave_statements';
|
||||
set global log_slow_slave_statements=ON;
|
||||
show variables like 'log_slow_slave_statements';
|
||||
|
||||
#-- echo # Make insert(6) on master
|
||||
connection master;
|
||||
INSERT INTO t VALUES (6);
|
||||
-- echo # Read information about master binlog
|
||||
let $binlog_file = query_get_value(SHOW MASTER STATUS,File,1);
|
||||
let $binlog_position = query_get_value(SHOW MASTER STATUS,Position,1);
|
||||
|
||||
-- echo # Sync slave(6) thread
|
||||
connection slave;
|
||||
let $sync_result = `SELECT MASTER_POS_WAIT('$binlog_file',$binlog_position)`;
|
||||
-- echo # Restart slave
|
||||
STOP SLAVE;
|
||||
-- source include/wait_for_slave_to_stop.inc
|
||||
START SLAVE;
|
||||
-- source include/wait_for_slave_to_start.inc
|
||||
|
||||
#-- echo # Make insert(7) on master
|
||||
connection master;
|
||||
INSERT INTO t VALUES (7);
|
||||
-- echo # Read information about master binlog
|
||||
let $binlog_file = query_get_value(SHOW MASTER STATUS,File,1);
|
||||
let $binlog_position = query_get_value(SHOW MASTER STATUS,Position,1);
|
||||
|
||||
-- echo # Sync slave(7) thread
|
||||
connection slave;
|
||||
let $sync_result = `SELECT MASTER_POS_WAIT('$binlog_file',$binlog_position)`;
|
||||
|
||||
-- echo # Analyse master slow_query_log
|
||||
let $i=7;
|
||||
let $k=1;
|
||||
let $cmd=cat ./var/mysqld.1/data/percona_log_slow_slave_statements-master.log | grep;
|
||||
while($i)
|
||||
{
|
||||
let $current_cmd = $cmd "INSERT INTO t VALUES ($k)" | wc -l;
|
||||
exec $current_cmd;
|
||||
dec $i;
|
||||
inc $k;
|
||||
}
|
||||
|
||||
-- echo # Analyse slave slow_query_log
|
||||
let $i=7;
|
||||
let $k=1;
|
||||
let $cmd=cat ./var/mysqld.2/data/percona_log_slow_slave_statements-slave.log | grep;
|
||||
while($i)
|
||||
{
|
||||
let $current_cmd = $cmd "INSERT INTO t VALUES ($k)" | wc -l;
|
||||
exec $current_cmd;
|
||||
dec $i;
|
||||
inc $k;
|
||||
}
|
||||
set global log_slow_slave_statements=OFF;
|
||||
|
||||
connection master;
|
||||
DROP TABLE t;
|
||||
|
||||
-- echo # Read information about master binlog
|
||||
let $binlog_file = query_get_value(SHOW MASTER STATUS,File,1);
|
||||
let $binlog_position = query_get_value(SHOW MASTER STATUS,Position,1);
|
||||
|
||||
-- echo # Sync slave(8) thread
|
||||
connection slave;
|
||||
let $sync_result = `SELECT MASTER_POS_WAIT('$binlog_file',$binlog_position)`;
|
95
percona-suite/percona_query_cache_with_comments.inc
Normal file
95
percona-suite/percona_query_cache_with_comments.inc
Normal file
|
@ -0,0 +1,95 @@
|
|||
--source include/percona_query_cache_with_comments_clear.inc
|
||||
let $query=/* with comment first */select * from t1;
|
||||
eval $query;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $query=# with comment first
|
||||
select * from t1;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $query=-- with comment first
|
||||
select * from t1;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $query=/* with comment first and "quote" */select * from t1;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $query=# with comment first and "quote"
|
||||
select * from t1;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $query=-- with comment first and "quote"
|
||||
select * from t1;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $query=
|
||||
/* with comment and whitespaces first */select * from t1;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $query=
|
||||
# with comment and whitespaces first
|
||||
select * from t1;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $query=
|
||||
-- with comment and whitespaces first
|
||||
select * from t1;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $internal=* internal comment *;
|
||||
|
||||
let $query=select * /$internal/ from t1;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
let $query=select */$internal/ from t1;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
let $query=select */$internal/from t1;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $internal=* internal comment with "quote" *;
|
||||
|
||||
let $query=select * /$internal/ from t1;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
let $query=select */$internal/ from t1;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
let $query=select */$internal/from t1;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $query=select * from t1
|
||||
;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $query=select * from t1 ;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $query=select * from t1 ;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $query=select * from t1
|
||||
/* comment in the end */;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $query=select * from t1
|
||||
/* *\/ */;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $query=select * from t1
|
||||
/* comment in the end */
|
||||
;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $query=select * from t1 #comment in the end;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $query=select * from t1 #comment in the end
|
||||
;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $query=select * from t1 -- comment in the end;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $query=select * from t1 -- comment in the end
|
||||
;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $query=select ' \' ' from t1;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
88
percona-suite/percona_query_cache_with_comments.inc.backup
Normal file
88
percona-suite/percona_query_cache_with_comments.inc.backup
Normal file
|
@ -0,0 +1,88 @@
|
|||
--source include/percona_query_cache_with_comments_clear.inc
|
||||
let $query=/* with comment first */select * from t1;
|
||||
eval $query;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $query=# with comment first
|
||||
select * from t1;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $query=-- with comment first
|
||||
select * from t1;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $query=/* with comment first and "quote" */select * from t1;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $query=# with comment first and "quote"
|
||||
select * from t1;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $query=-- with comment first and "quote"
|
||||
select * from t1;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $query=
|
||||
/* with comment and whitespaces first */select * from t1;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $query=
|
||||
# with comment and whitespaces first
|
||||
select * from t1;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $query=
|
||||
-- with comment and whitespaces first
|
||||
select * from t1;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $internal=* internal comment *;
|
||||
|
||||
let $query=select * /$internal/ from t1;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
let $query=select */$internal/ from t1;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
let $query=select */$internal/from t1;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $internal=* internal comment with "quote" *;
|
||||
|
||||
let $query=select * /$internal/ from t1;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
let $query=select */$internal/ from t1;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
let $query=select */$internal/from t1;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $query=select * from t1
|
||||
;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $query=select * from t1 ;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $query=select * from t1 ;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $query=select * from t1
|
||||
/* comment in the end */;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $query=select * from t1
|
||||
/* comment in the end */
|
||||
;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $query=select * from t1 #comment in the end;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $query=select * from t1 #comment in the end
|
||||
;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $query=select * from t1 -- comment in the end;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
||||
|
||||
let $query=select * from t1 -- comment in the end
|
||||
;
|
||||
--source include/percona_query_cache_with_comments_eval.inc
|
866
percona-suite/percona_query_cache_with_comments.result
Normal file
866
percona-suite/percona_query_cache_with_comments.result
Normal file
|
@ -0,0 +1,866 @@
|
|||
set global query_cache_strip_comments=ON;
|
||||
set GLOBAL query_cache_size=1355776;
|
||||
drop table if exists t1;
|
||||
create table t1 (a int not null);
|
||||
insert into t1 values (1),(2),(3);
|
||||
flush query cache;
|
||||
flush query cache;
|
||||
reset query cache;
|
||||
flush status;
|
||||
flush query cache;
|
||||
flush query cache;
|
||||
reset query cache;
|
||||
flush status;
|
||||
/* with comment first */select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
-----------------------------------------------------
|
||||
/* with comment first */select * from t1
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 0
|
||||
/* with comment first */select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
/* with comment first */select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 2
|
||||
-----------------------------------------------------
|
||||
# with comment first
|
||||
select * from t1
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 2
|
||||
# with comment first
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
# with comment first
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 4
|
||||
-----------------------------------------------------
|
||||
-- with comment first
|
||||
select * from t1
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 4
|
||||
-- with comment first
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
-- with comment first
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 6
|
||||
-----------------------------------------------------
|
||||
/* with comment first and "quote" */select * from t1
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 6
|
||||
/* with comment first and "quote" */select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
/* with comment first and "quote" */select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 8
|
||||
-----------------------------------------------------
|
||||
# with comment first and "quote"
|
||||
select * from t1
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 8
|
||||
# with comment first and "quote"
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
# with comment first and "quote"
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 10
|
||||
-----------------------------------------------------
|
||||
-- with comment first and "quote"
|
||||
select * from t1
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 10
|
||||
-- with comment first and "quote"
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
-- with comment first and "quote"
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 12
|
||||
-----------------------------------------------------
|
||||
/* with comment and whitespaces first */select * from t1
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 12
|
||||
/* with comment and whitespaces first */select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
/* with comment and whitespaces first */select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 14
|
||||
-----------------------------------------------------
|
||||
# with comment and whitespaces first
|
||||
select * from t1
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 14
|
||||
# with comment and whitespaces first
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
# with comment and whitespaces first
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 16
|
||||
-----------------------------------------------------
|
||||
-- with comment and whitespaces first
|
||||
select * from t1
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 16
|
||||
-- with comment and whitespaces first
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
-- with comment and whitespaces first
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 18
|
||||
-----------------------------------------------------
|
||||
select * /* internal comment */ from t1
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 18
|
||||
select * /* internal comment */ from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
select * /* internal comment */ from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 20
|
||||
-----------------------------------------------------
|
||||
select */* internal comment */ from t1
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 20
|
||||
select */* internal comment */ from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
select */* internal comment */ from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 22
|
||||
-----------------------------------------------------
|
||||
select */* internal comment */from t1
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 22
|
||||
select */* internal comment */from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
select */* internal comment */from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 24
|
||||
-----------------------------------------------------
|
||||
select * /* internal comment with "quote" */ from t1
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 24
|
||||
select * /* internal comment with "quote" */ from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
select * /* internal comment with "quote" */ from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 26
|
||||
-----------------------------------------------------
|
||||
select */* internal comment with "quote" */ from t1
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 26
|
||||
select */* internal comment with "quote" */ from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
select */* internal comment with "quote" */ from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 28
|
||||
-----------------------------------------------------
|
||||
select */* internal comment with "quote" */from t1
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 28
|
||||
select */* internal comment with "quote" */from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
select */* internal comment with "quote" */from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 30
|
||||
-----------------------------------------------------
|
||||
select * from t1
|
||||
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 30
|
||||
select * from t1
|
||||
;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
select * from t1
|
||||
;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 32
|
||||
-----------------------------------------------------
|
||||
select * from t1
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 32
|
||||
select * from t1 ;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
select * from t1 ;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 34
|
||||
-----------------------------------------------------
|
||||
select * from t1
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 34
|
||||
select * from t1 ;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
select * from t1 ;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 36
|
||||
-----------------------------------------------------
|
||||
select * from t1
|
||||
/* comment in the end */
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 36
|
||||
select * from t1
|
||||
/* comment in the end */;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
select * from t1
|
||||
/* comment in the end */;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 38
|
||||
-----------------------------------------------------
|
||||
select * from t1
|
||||
/* *\/ */
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 38
|
||||
select * from t1
|
||||
/* *\/ */;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
select * from t1
|
||||
/* *\/ */;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 40
|
||||
-----------------------------------------------------
|
||||
select * from t1
|
||||
/* comment in the end */
|
||||
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 40
|
||||
select * from t1
|
||||
/* comment in the end */
|
||||
;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
select * from t1
|
||||
/* comment in the end */
|
||||
;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 42
|
||||
-----------------------------------------------------
|
||||
select * from t1 #comment in the end
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 42
|
||||
select * from t1 #comment in the end;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
select * from t1 #comment in the end;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 44
|
||||
-----------------------------------------------------
|
||||
select * from t1 #comment in the end
|
||||
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 44
|
||||
select * from t1 #comment in the end
|
||||
;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
select * from t1 #comment in the end
|
||||
;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 46
|
||||
-----------------------------------------------------
|
||||
select * from t1 -- comment in the end
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 46
|
||||
select * from t1 -- comment in the end;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
select * from t1 -- comment in the end;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 48
|
||||
-----------------------------------------------------
|
||||
select * from t1 -- comment in the end
|
||||
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 48
|
||||
select * from t1 -- comment in the end
|
||||
;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
select * from t1 -- comment in the end
|
||||
;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 50
|
||||
-----------------------------------------------------
|
||||
select ' \' ' from t1
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 50
|
||||
select ' \' ' from t1;
|
||||
'
|
||||
'
|
||||
'
|
||||
'
|
||||
select ' \' ' from t1;
|
||||
'
|
||||
'
|
||||
'
|
||||
'
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 2
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 2
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 51
|
||||
DROP TABLE t1;
|
||||
SET GLOBAL query_cache_size=default;
|
||||
set global query_cache_strip_comments=OFF;
|
4
percona-suite/percona_query_cache_with_comments.test
Normal file
4
percona-suite/percona_query_cache_with_comments.test
Normal file
|
@ -0,0 +1,4 @@
|
|||
set global query_cache_strip_comments=ON;
|
||||
-- source include/percona_query_cache_with_comments_begin.inc
|
||||
-- source include/percona_query_cache_with_comments.inc
|
||||
-- source include/percona_query_cache_with_comments_end.inc
|
12
percona-suite/percona_query_cache_with_comments_begin.inc
Normal file
12
percona-suite/percona_query_cache_with_comments_begin.inc
Normal file
|
@ -0,0 +1,12 @@
|
|||
-- source include/have_query_cache.inc
|
||||
|
||||
set GLOBAL query_cache_size=1355776;
|
||||
|
||||
--disable_warnings
|
||||
drop table if exists t1;
|
||||
--enable_warnings
|
||||
|
||||
create table t1 (a int not null);
|
||||
insert into t1 values (1),(2),(3);
|
||||
|
||||
--source include/percona_query_cache_with_comments_clear.inc
|
|
@ -0,0 +1,5 @@
|
|||
# Reset query cache variables.
|
||||
flush query cache; # This crashed in some versions
|
||||
flush query cache; # This crashed in some versions
|
||||
reset query cache;
|
||||
flush status;
|
21
percona-suite/percona_query_cache_with_comments_crash.result
Normal file
21
percona-suite/percona_query_cache_with_comments_crash.result
Normal file
|
@ -0,0 +1,21 @@
|
|||
set GLOBAL query_cache_size=1355776;
|
||||
drop table if exists t1;
|
||||
create table t1 (a int not null);
|
||||
insert into t1 values (1),(2),(3);
|
||||
flush query cache;
|
||||
flush query cache;
|
||||
reset query cache;
|
||||
flush status;
|
||||
( select * from t1 );
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
/*!40101 SET @OLD_SQL_MODE := @@SQL_MODE, @@SQL_MODE := REPLACE(REPLACE(@@SQL_MODE, 'ANSI_QUOTES', ''), ',,', ','), @OLD_QUOTE := @@SQL_QUOTE_SHOW_CREATE, @@SQL_QUOTE_SHOW_CREATE := 1 */;
|
||||
/* only comment */;
|
||||
# only comment
|
||||
;
|
||||
-- only comment
|
||||
;
|
||||
DROP TABLE t1;
|
||||
SET GLOBAL query_cache_size= default;
|
22
percona-suite/percona_query_cache_with_comments_crash.test
Normal file
22
percona-suite/percona_query_cache_with_comments_crash.test
Normal file
|
@ -0,0 +1,22 @@
|
|||
-- source include/have_query_cache.inc
|
||||
set GLOBAL query_cache_size=1355776;
|
||||
--disable_warnings
|
||||
drop table if exists t1;
|
||||
--enable_warnings
|
||||
create table t1 (a int not null);
|
||||
insert into t1 values (1),(2),(3);
|
||||
flush query cache; # This crashed in some versions
|
||||
flush query cache; # This crashed in some versions
|
||||
reset query cache;
|
||||
flush status;
|
||||
( select * from t1 );
|
||||
/*!40101 SET @OLD_SQL_MODE := @@SQL_MODE, @@SQL_MODE := REPLACE(REPLACE(@@SQL_MODE, 'ANSI_QUOTES', ''), ',,', ','), @OLD_QUOTE := @@SQL_QUOTE_SHOW_CREATE, @@SQL_QUOTE_SHOW_CREATE := 1 */;
|
||||
/* only comment */;
|
||||
let query=# only comment
|
||||
;
|
||||
eval $query;
|
||||
let query=-- only comment
|
||||
;
|
||||
eval $query;
|
||||
DROP TABLE t1;
|
||||
SET GLOBAL query_cache_size= default;
|
865
percona-suite/percona_query_cache_with_comments_disable.result
Normal file
865
percona-suite/percona_query_cache_with_comments_disable.result
Normal file
|
@ -0,0 +1,865 @@
|
|||
set GLOBAL query_cache_size=1355776;
|
||||
drop table if exists t1;
|
||||
create table t1 (a int not null);
|
||||
insert into t1 values (1),(2),(3);
|
||||
flush query cache;
|
||||
flush query cache;
|
||||
reset query cache;
|
||||
flush status;
|
||||
flush query cache;
|
||||
flush query cache;
|
||||
reset query cache;
|
||||
flush status;
|
||||
/* with comment first */select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
-----------------------------------------------------
|
||||
/* with comment first */select * from t1
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 0
|
||||
/* with comment first */select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
/* with comment first */select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 2
|
||||
-----------------------------------------------------
|
||||
# with comment first
|
||||
select * from t1
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 1
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 2
|
||||
# with comment first
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
# with comment first
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 2
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 2
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 2
|
||||
-----------------------------------------------------
|
||||
-- with comment first
|
||||
select * from t1
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 2
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 2
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 2
|
||||
-- with comment first
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
-- with comment first
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 3
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 3
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 2
|
||||
-----------------------------------------------------
|
||||
/* with comment first and "quote" */select * from t1
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 3
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 3
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 2
|
||||
/* with comment first and "quote" */select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
/* with comment first and "quote" */select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 4
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 4
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 3
|
||||
-----------------------------------------------------
|
||||
# with comment first and "quote"
|
||||
select * from t1
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 4
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 4
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 3
|
||||
# with comment first and "quote"
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
# with comment first and "quote"
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 5
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 5
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 3
|
||||
-----------------------------------------------------
|
||||
-- with comment first and "quote"
|
||||
select * from t1
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 5
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 5
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 3
|
||||
-- with comment first and "quote"
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
-- with comment first and "quote"
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 6
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 6
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 3
|
||||
-----------------------------------------------------
|
||||
/* with comment and whitespaces first */select * from t1
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 6
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 6
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 3
|
||||
/* with comment and whitespaces first */select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
/* with comment and whitespaces first */select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 7
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 7
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 4
|
||||
-----------------------------------------------------
|
||||
# with comment and whitespaces first
|
||||
select * from t1
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 7
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 7
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 4
|
||||
# with comment and whitespaces first
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
# with comment and whitespaces first
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 8
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 8
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 4
|
||||
-----------------------------------------------------
|
||||
-- with comment and whitespaces first
|
||||
select * from t1
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 8
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 8
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 4
|
||||
-- with comment and whitespaces first
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
-- with comment and whitespaces first
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 9
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 9
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 4
|
||||
-----------------------------------------------------
|
||||
select * /* internal comment */ from t1
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 9
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 9
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 4
|
||||
select * /* internal comment */ from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
select * /* internal comment */ from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 10
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 10
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 5
|
||||
-----------------------------------------------------
|
||||
select */* internal comment */ from t1
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 10
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 10
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 5
|
||||
select */* internal comment */ from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
select */* internal comment */ from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 11
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 11
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 6
|
||||
-----------------------------------------------------
|
||||
select */* internal comment */from t1
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 11
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 11
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 6
|
||||
select */* internal comment */from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
select */* internal comment */from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 12
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 12
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 7
|
||||
-----------------------------------------------------
|
||||
select * /* internal comment with "quote" */ from t1
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 12
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 12
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 7
|
||||
select * /* internal comment with "quote" */ from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
select * /* internal comment with "quote" */ from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 13
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 13
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 8
|
||||
-----------------------------------------------------
|
||||
select */* internal comment with "quote" */ from t1
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 13
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 13
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 8
|
||||
select */* internal comment with "quote" */ from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
select */* internal comment with "quote" */ from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 14
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 14
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 9
|
||||
-----------------------------------------------------
|
||||
select */* internal comment with "quote" */from t1
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 14
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 14
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 9
|
||||
select */* internal comment with "quote" */from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
select */* internal comment with "quote" */from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 15
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 15
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 10
|
||||
-----------------------------------------------------
|
||||
select * from t1
|
||||
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 15
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 15
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 10
|
||||
select * from t1
|
||||
;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
select * from t1
|
||||
;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 16
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 16
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 11
|
||||
-----------------------------------------------------
|
||||
select * from t1
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 16
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 16
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 11
|
||||
select * from t1 ;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
select * from t1 ;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 16
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 16
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 13
|
||||
-----------------------------------------------------
|
||||
select * from t1
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 16
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 16
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 13
|
||||
select * from t1 ;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
select * from t1 ;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 16
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 16
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 15
|
||||
-----------------------------------------------------
|
||||
select * from t1
|
||||
/* comment in the end */
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 16
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 16
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 15
|
||||
select * from t1
|
||||
/* comment in the end */;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
select * from t1
|
||||
/* comment in the end */;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 17
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 17
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 16
|
||||
-----------------------------------------------------
|
||||
select * from t1
|
||||
/* *\/ */
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 17
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 17
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 16
|
||||
select * from t1
|
||||
/* *\/ */;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
select * from t1
|
||||
/* *\/ */;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 18
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 18
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 17
|
||||
-----------------------------------------------------
|
||||
select * from t1
|
||||
/* comment in the end */
|
||||
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 18
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 18
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 17
|
||||
select * from t1
|
||||
/* comment in the end */
|
||||
;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
select * from t1
|
||||
/* comment in the end */
|
||||
;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 18
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 18
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 19
|
||||
-----------------------------------------------------
|
||||
select * from t1 #comment in the end
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 18
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 18
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 19
|
||||
select * from t1 #comment in the end;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
select * from t1 #comment in the end;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 19
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 19
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 20
|
||||
-----------------------------------------------------
|
||||
select * from t1 #comment in the end
|
||||
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 19
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 19
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 20
|
||||
select * from t1 #comment in the end
|
||||
;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
select * from t1 #comment in the end
|
||||
;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 19
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 19
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 22
|
||||
-----------------------------------------------------
|
||||
select * from t1 -- comment in the end
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 19
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 19
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 22
|
||||
select * from t1 -- comment in the end;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
select * from t1 -- comment in the end;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 20
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 20
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 23
|
||||
-----------------------------------------------------
|
||||
select * from t1 -- comment in the end
|
||||
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 20
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 20
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 23
|
||||
select * from t1 -- comment in the end
|
||||
;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
select * from t1 -- comment in the end
|
||||
;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 20
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 20
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 25
|
||||
-----------------------------------------------------
|
||||
select ' \' ' from t1
|
||||
-----------------------------------------------------
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 20
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 20
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 25
|
||||
select ' \' ' from t1;
|
||||
'
|
||||
'
|
||||
'
|
||||
'
|
||||
select ' \' ' from t1;
|
||||
'
|
||||
'
|
||||
'
|
||||
'
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 21
|
||||
show status like "Qcache_inserts";
|
||||
Variable_name Value
|
||||
Qcache_inserts 21
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 26
|
||||
DROP TABLE t1;
|
||||
SET GLOBAL query_cache_size=default;
|
||||
set global query_cache_strip_comments=OFF;
|
|
@ -0,0 +1,3 @@
|
|||
-- source include/percona_query_cache_with_comments_begin.inc
|
||||
-- source include/percona_query_cache_with_comments.inc
|
||||
-- source include/percona_query_cache_with_comments_end.inc
|
3
percona-suite/percona_query_cache_with_comments_end.inc
Normal file
3
percona-suite/percona_query_cache_with_comments_end.inc
Normal file
|
@ -0,0 +1,3 @@
|
|||
DROP TABLE t1;
|
||||
SET GLOBAL query_cache_size=default;
|
||||
set global query_cache_strip_comments=OFF;
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue