Commit c877ff39 authored by Vasil Dimov's avatar Vasil Dimov

Import branches/innodb+ from SVN on top of storage/innobase.

parents fe0828b3 410e23a6
...@@ -22,13 +22,21 @@ INCLUDE(CheckCSourceRuns) ...@@ -22,13 +22,21 @@ INCLUDE(CheckCSourceRuns)
# OS tests # OS tests
IF(UNIX) IF(UNIX)
IF(CMAKE_SYSTEM_NAME STREQUAL "Linux") IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
CHECK_INCLUDE_FILES (libaio.h HAVE_LIBAIO_H)
CHECK_LIBRARY_EXISTS(aio io_queue_init "" HAVE_LIBAIO)
ADD_DEFINITIONS("-DUNIV_LINUX -D_GNU_SOURCE=1") ADD_DEFINITIONS("-DUNIV_LINUX -D_GNU_SOURCE=1")
IF(HAVE_LIBAIO_H AND HAVE_LIBAIO)
ADD_DEFINITIONS(-DLINUX_NATIVE_AIO=1)
LINK_LIBRARIES(aio)
ENDIF()
ELSEIF(CMAKE_SYSTEM_NAME MATCHES "HP*") ELSEIF(CMAKE_SYSTEM_NAME MATCHES "HP*")
ADD_DEFINITIONS("-DUNIV_HPUX -DUNIV_MUST_NOT_INLINE") ADD_DEFINITIONS("-DUNIV_HPUX -DUNIV_MUST_NOT_INLINE")
ELSEIF(CMAKE_SYSTEM_NAME STREQUAL "AIX") ELSEIF(CMAKE_SYSTEM_NAME STREQUAL "AIX")
ADD_DEFINITIONS("-DUNIV_AIX -DUNIX_MUST_NOT_INLINE") ADD_DEFINITIONS("-DUNIV_AIX -DUNIX_MUST_NOT_INLINE")
ELSEIF(CMAKE_SYSTEM_NAME STREQUAL "SunOS") ELSEIF(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
ADD_DEFINITIONS("-DUNIV_SOLARIS") ADD_DEFINITIONS("-DUNIV_SOLARIS")
ELSE()
ADD_DEFINITIONS("-DUNIV_MUST_NOT_INLINE")
ENDIF() ENDIF()
ENDIF() ENDIF()
...@@ -230,8 +238,12 @@ SET(INNOBASE_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c ...@@ -230,8 +238,12 @@ 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/trx0i_s.c trx/trx0purge.c trx/trx0rec.c trx/trx0roll.c trx/trx0rseg.c
trx/trx0sys.c trx/trx0trx.c trx/trx0undo.c trx/trx0sys.c trx/trx0trx.c trx/trx0undo.c
usr/usr0sess.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/ut0list.c ut/ut0mem.c ut/ut0rbt.c ut/ut0rnd.c
ut/ut0list.c ut/ut0wqueue.c) ut/ut0ut.c ut/ut0vec.c ut/ut0wqueue.c)
# 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(WITH_INNODB) IF(WITH_INNODB)
# Legacy option # Legacy option
......
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 2009-11-20 The InnoDB Team
* handler/ha_innodb.cc: * handler/ha_innodb.cc:
...@@ -79,8 +276,8 @@ ...@@ -79,8 +276,8 @@
sync/sync0arr.c, sync/sync0sync.c, thr/thr0loc.c, trx/trx0i_s.c, 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, trx/trx0purge.c, trx/trx0rseg.c, trx/trx0sys.c, trx/trx0undo.c,
usr/usr0sess.c, ut/ut0mem.c: usr/usr0sess.c, ut/ut0mem.c:
Fix Bug #45992 innodb memory not freed after shutdown Fix Bug#45992 innodb memory not freed after shutdown
Fix Bug #46656 InnoDB plugin: memory leaks (Valgrind) Fix Bug#46656 InnoDB plugin: memory leaks (Valgrind)
2009-10-29 The InnoDB Team 2009-10-29 The InnoDB Team
...@@ -422,7 +619,7 @@ ...@@ -422,7 +619,7 @@
* dict/dict0dict.c: * dict/dict0dict.c:
When an index column cannot be found in the table during index When an index column cannot be found in the table during index
creation, display additional diagnostic before an assertion failure. 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. but it helps understand the reason of the crash.
2009-06-17 The InnoDB Team 2009-06-17 The InnoDB Team
...@@ -535,6 +732,12 @@ ...@@ -535,6 +732,12 @@
Fix Bug#44320 InnoDB: missing DB_ROLL_PTR in Table Monitor COLUMNS Fix Bug#44320 InnoDB: missing DB_ROLL_PTR in Table Monitor COLUMNS
output 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 2009-04-23 The InnoDB Team
* row/row0mysql.c: * row/row0mysql.c:
......
...@@ -28,7 +28,6 @@ INCLUDES= -I$(top_srcdir)/include -I$(top_builddir)/include \ ...@@ -28,7 +28,6 @@ INCLUDES= -I$(top_srcdir)/include -I$(top_builddir)/include \
DEFS= @DEFS@ DEFS= @DEFS@
noinst_HEADERS= \ noinst_HEADERS= \
handler/ha_innodb.h \ handler/ha_innodb.h \
handler/i_s.h \ handler/i_s.h \
...@@ -118,6 +117,7 @@ noinst_HEADERS= \ ...@@ -118,6 +117,7 @@ noinst_HEADERS= \
include/mtr0types.h \ include/mtr0types.h \
include/mysql_addons.h \ include/mysql_addons.h \
include/os0file.h \ include/os0file.h \
include/os0file.ic \
include/os0proc.h \ include/os0proc.h \
include/os0proc.ic \ include/os0proc.ic \
include/os0sync.h \ include/os0sync.h \
...@@ -217,6 +217,7 @@ noinst_HEADERS= \ ...@@ -217,6 +217,7 @@ noinst_HEADERS= \
include/ut0lst.h \ include/ut0lst.h \
include/ut0mem.h \ include/ut0mem.h \
include/ut0mem.ic \ include/ut0mem.ic \
include/ut0rbt.h \
include/ut0rnd.h \ include/ut0rnd.h \
include/ut0rnd.ic \ include/ut0rnd.ic \
include/ut0sort.h \ include/ut0sort.h \
...@@ -318,6 +319,7 @@ libinnobase_a_SOURCES= \ ...@@ -318,6 +319,7 @@ libinnobase_a_SOURCES= \
ut/ut0dbg.c \ ut/ut0dbg.c \
ut/ut0list.c \ ut/ut0list.c \
ut/ut0mem.c \ ut/ut0mem.c \
ut/ut0rbt.c \
ut/ut0rnd.c \ ut/ut0rnd.c \
ut/ut0ut.c \ ut/ut0ut.c \
ut/ut0vec.c \ ut/ut0vec.c \
......
/***************************************************************************** /*****************************************************************************
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 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 the terms of the GNU General Public License as published by the Free Software
...@@ -592,15 +592,18 @@ an x-latch on the tree. ...@@ -592,15 +592,18 @@ an x-latch on the tree.
@return rec_get_offsets() of the node pointer record */ @return rec_get_offsets() of the node pointer record */
static static
ulint* ulint*
btr_page_get_father_node_ptr( btr_page_get_father_node_ptr_func(
/*=========================*/ /*==============================*/
ulint* offsets,/*!< in: work area for the return value */ ulint* offsets,/*!< in: work area for the return value */
mem_heap_t* heap, /*!< in: memory heap to use */ mem_heap_t* heap, /*!< in: memory heap to use */
btr_cur_t* cursor, /*!< in: cursor pointing to user record, btr_cur_t* cursor, /*!< in: cursor pointing to user record,
out: cursor on node pointer record, out: cursor on node pointer record,
its page x-latched */ its page x-latched */
const char* file, /*!< in: file name */
ulint line, /*!< in: line where called */
mtr_t* mtr) /*!< in: mtr */ mtr_t* mtr) /*!< in: mtr */
{ {
page_t* page;
dtuple_t* tuple; dtuple_t* tuple;
rec_t* user_rec; rec_t* user_rec;
rec_t* node_ptr; rec_t* node_ptr;
...@@ -617,12 +620,15 @@ btr_page_get_father_node_ptr( ...@@ -617,12 +620,15 @@ btr_page_get_father_node_ptr(
ut_ad(dict_index_get_page(index) != page_no); ut_ad(dict_index_get_page(index) != page_no);
level = btr_page_get_level(btr_cur_get_page(cursor), mtr); level = btr_page_get_level(btr_cur_get_page(cursor), mtr);
page = btr_cur_get_page(cursor);
user_rec = btr_cur_get_rec(cursor); user_rec = btr_cur_get_rec(cursor);
ut_a(page_rec_is_user_rec(user_rec)); ut_a(page_rec_is_user_rec(user_rec));
tuple = dict_index_build_node_ptr(index, user_rec, 0, heap, level); 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_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); node_ptr = btr_cur_get_rec(cursor);
ut_ad(!page_rec_is_comp(node_ptr) ut_ad(!page_rec_is_comp(node_ptr)
...@@ -670,6 +676,9 @@ btr_page_get_father_node_ptr( ...@@ -670,6 +676,9 @@ btr_page_get_father_node_ptr(
return(offsets); 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 Returns the upper level node pointer to a page. It is assumed that mtr holds
an x-latch on the tree. an x-latch on the tree.
...@@ -1662,11 +1671,13 @@ Inserts a data tuple to a tree on a non-leaf level. It is assumed ...@@ -1662,11 +1671,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. */ that mtr holds an x-latch on the tree. */
UNIV_INTERN UNIV_INTERN
void void
btr_insert_on_non_leaf_level( btr_insert_on_non_leaf_level_func(
/*=========================*/ /*==============================*/
dict_index_t* index, /*!< in: index */ dict_index_t* index, /*!< in: index */
ulint level, /*!< in: level, must be > 0 */ ulint level, /*!< in: level, must be > 0 */
dtuple_t* tuple, /*!< in: the record to be inserted */ 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 */ mtr_t* mtr) /*!< in: mtr */
{ {
big_rec_t* dummy_big_rec; big_rec_t* dummy_big_rec;
...@@ -1678,7 +1689,7 @@ btr_insert_on_non_leaf_level( ...@@ -1678,7 +1689,7 @@ btr_insert_on_non_leaf_level(
btr_cur_search_to_nth_level(index, level, tuple, PAGE_CUR_LE, btr_cur_search_to_nth_level(index, level, tuple, PAGE_CUR_LE,
BTR_CONT_MODIFY_TREE, BTR_CONT_MODIFY_TREE,
&cursor, 0, mtr); &cursor, 0, file, line, mtr);
err = btr_cur_pessimistic_insert(BTR_NO_LOCKING_FLAG err = btr_cur_pessimistic_insert(BTR_NO_LOCKING_FLAG
| BTR_KEEP_SYS_FLAG | BTR_KEEP_SYS_FLAG
......
This diff is collapsed.
/***************************************************************************** /*****************************************************************************
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 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 the terms of the GNU General Public License as published by the Free Software
...@@ -205,10 +205,12 @@ record and it can be restored on a user record whose ordering fields ...@@ -205,10 +205,12 @@ record and it can be restored on a user record whose ordering fields
are identical to the ones of the original user record */ are identical to the ones of the original user record */
UNIV_INTERN UNIV_INTERN
ibool ibool
btr_pcur_restore_position( btr_pcur_restore_position_func(
/*======================*/ /*===========================*/
ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */ ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
btr_pcur_t* cursor, /*!< in: detached persistent cursor */ 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 */ mtr_t* mtr) /*!< in: mtr */
{ {
dict_index_t* index; dict_index_t* index;
...@@ -217,6 +219,9 @@ btr_pcur_restore_position( ...@@ -217,6 +219,9 @@ btr_pcur_restore_position(
ulint old_mode; ulint old_mode;
mem_heap_t* heap; mem_heap_t* heap;
ut_ad(mtr);
ut_ad(mtr->state == MTR_ACTIVE);
index = btr_cur_get_index(btr_pcur_get_btr_cur(cursor)); index = btr_cur_get_index(btr_pcur_get_btr_cur(cursor));
if (UNIV_UNLIKELY(cursor->old_stored != BTR_PCUR_OLD_STORED) if (UNIV_UNLIKELY(cursor->old_stored != BTR_PCUR_OLD_STORED)
...@@ -257,7 +262,8 @@ btr_pcur_restore_position( ...@@ -257,7 +262,8 @@ btr_pcur_restore_position(
if (UNIV_LIKELY(buf_page_optimistic_get( if (UNIV_LIKELY(buf_page_optimistic_get(
latch_mode, latch_mode,
cursor->block_when_stored, cursor->block_when_stored,
cursor->modify_clock, mtr))) { cursor->modify_clock,
file, line, mtr))) {
cursor->pos_state = BTR_PCUR_IS_POSITIONED; cursor->pos_state = BTR_PCUR_IS_POSITIONED;
buf_block_dbg_add_level(btr_pcur_get_block(cursor), buf_block_dbg_add_level(btr_pcur_get_block(cursor),
...@@ -312,8 +318,8 @@ btr_pcur_restore_position( ...@@ -312,8 +318,8 @@ btr_pcur_restore_position(
mode = PAGE_CUR_L; mode = PAGE_CUR_L;
} }
btr_pcur_open_with_no_init(index, tuple, mode, latch_mode, btr_pcur_open_with_no_init_func(index, tuple, mode, latch_mode,
cursor, 0, mtr); cursor, 0, file, line, mtr);
/* Restore the old search mode */ /* Restore the old search mode */
cursor->search_mode = old_mode; cursor->search_mode = old_mode;
...@@ -553,8 +559,8 @@ before first in tree. The latching mode must be BTR_SEARCH_LEAF or ...@@ -553,8 +559,8 @@ before first in tree. The latching mode must be BTR_SEARCH_LEAF or
BTR_MODIFY_LEAF. */ BTR_MODIFY_LEAF. */
UNIV_INTERN UNIV_INTERN
void void
btr_pcur_open_on_user_rec( btr_pcur_open_on_user_rec_func(
/*======================*/ /*===========================*/
dict_index_t* index, /*!< in: index */ dict_index_t* index, /*!< in: index */
const dtuple_t* tuple, /*!< in: tuple on which search done */ const dtuple_t* tuple, /*!< in: tuple on which search done */
ulint mode, /*!< in: PAGE_CUR_L, ... */ ulint mode, /*!< in: PAGE_CUR_L, ... */
...@@ -562,9 +568,12 @@ btr_pcur_open_on_user_rec( ...@@ -562,9 +568,12 @@ btr_pcur_open_on_user_rec(
BTR_MODIFY_LEAF */ BTR_MODIFY_LEAF */
btr_pcur_t* cursor, /*!< in: memory buffer for persistent btr_pcur_t* cursor, /*!< in: memory buffer for persistent
cursor */ cursor */
const char* file, /*!< in: file name */
ulint line, /*!< in: line where called */
mtr_t* mtr) /*!< in: mtr */ 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)) { if ((mode == PAGE_CUR_GE) || (mode == PAGE_CUR_G)) {
......
...@@ -50,6 +50,11 @@ UNIV_INTERN char btr_search_enabled = TRUE; ...@@ -50,6 +50,11 @@ UNIV_INTERN char btr_search_enabled = TRUE;
/** Mutex protecting btr_search_enabled */ /** Mutex protecting btr_search_enabled */
static mutex_t btr_search_enabled_mutex; static mutex_t btr_search_enabled_mutex;
#ifdef UNIV_PFS_MUTEX
/* Key to register btr_search_enabled_mutex with performance schema */
UNIV_INTERN mysql_pfs_key_t btr_search_enabled_mutex_key;
#endif /* UNIV_PFS_MUTEX */
/** A dummy variable to fool the compiler */ /** A dummy variable to fool the compiler */
UNIV_INTERN ulint btr_search_this_is_zero = 0; UNIV_INTERN ulint btr_search_this_is_zero = 0;
...@@ -82,6 +87,11 @@ UNIV_INTERN byte btr_sea_pad2[64]; ...@@ -82,6 +87,11 @@ UNIV_INTERN byte btr_sea_pad2[64];
/** The adaptive hash index */ /** The adaptive hash index */
UNIV_INTERN btr_search_sys_t* btr_search_sys; UNIV_INTERN btr_search_sys_t* btr_search_sys;
#ifdef UNIV_PFS_RWLOCK
/* Key to register btr_search_sys with performance schema */
UNIV_INTERN mysql_pfs_key_t btr_search_latch_key;
#endif /* UNIV_PFS_RWLOCK */
/** If the number of records on the page divided by this parameter /** If the number of records on the page divided by this parameter
would have been successfully accessed using a hash index, the index would have been successfully accessed using a hash index, the index
is then built on the page, assuming the global limit has been reached */ is then built on the page, assuming the global limit has been reached */
...@@ -167,8 +177,10 @@ btr_search_sys_create( ...@@ -167,8 +177,10 @@ btr_search_sys_create(
btr_search_latch_temp = mem_alloc(sizeof(rw_lock_t)); btr_search_latch_temp = mem_alloc(sizeof(rw_lock_t));
rw_lock_create(&btr_search_latch, SYNC_SEARCH_SYS); rw_lock_create(btr_search_latch_key, &btr_search_latch,
mutex_create(&btr_search_enabled_mutex, SYNC_SEARCH_SYS_CONF); SYNC_SEARCH_SYS);
mutex_create(btr_search_enabled_mutex_key,
&btr_search_enabled_mutex, SYNC_SEARCH_SYS_CONF);
btr_search_sys = mem_alloc(sizeof(btr_search_sys_t)); btr_search_sys = mem_alloc(sizeof(btr_search_sys_t));
......
/***************************************************************************** /*****************************************************************************
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 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 the terms of the GNU General Public License as published by the Free Software
...@@ -391,6 +391,8 @@ buf_buddy_relocate_block( ...@@ -391,6 +391,8 @@ buf_buddy_relocate_block(
UT_LIST_ADD_FIRST(list, buf_pool->zip_clean, dpage); UT_LIST_ADD_FIRST(list, buf_pool->zip_clean, dpage);
} }
UNIV_MEM_INVALID(bpage, sizeof *bpage);
mutex_exit(&buf_pool_zip_mutex); mutex_exit(&buf_pool_zip_mutex);
return(TRUE); return(TRUE);
} }
...@@ -455,6 +457,8 @@ buf_buddy_relocate( ...@@ -455,6 +457,8 @@ buf_buddy_relocate(
return(FALSE); return(FALSE);
} }
ut_ad(!buf_pool_watch_is(bpage));
if (page_zip_get_size(&bpage->zip) != size) { if (page_zip_get_size(&bpage->zip) != size) {
/* The block is of different size. We would /* The block is of different size. We would
have to relocate all blocks covered by src. have to relocate all blocks covered by src.
......
This diff is collapsed.
This diff is collapsed.
/***************************************************************************** /*****************************************************************************
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 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 the terms of the GNU General Public License as published by the Free Software
...@@ -350,17 +350,31 @@ scan_again: ...@@ -350,17 +350,31 @@ scan_again:
bpage = UT_LIST_GET_LAST(buf_pool->LRU); bpage = UT_LIST_GET_LAST(buf_pool->LRU);
while (bpage != NULL) { while (bpage != NULL) {
mutex_t* block_mutex = buf_page_get_mutex(bpage);
buf_page_t* prev_bpage; buf_page_t* prev_bpage;
ibool prev_bpage_buf_fix = FALSE;
ut_a(buf_page_in_file(bpage)); ut_a(buf_page_in_file(bpage));
mutex_enter(block_mutex);
prev_bpage = UT_LIST_GET_PREV(LRU, bpage); prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
if (buf_page_get_space(bpage) == id) { /* bpage->space and bpage->io_fix are protected by
if (bpage->buf_fix_count > 0 buf_pool_mutex and block_mutex. It is safe to check
|| buf_page_get_io_fix(bpage) != BUF_IO_NONE) { them while holding buf_pool_mutex only. */
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(bpage);
mutex_enter(block_mutex);
if (bpage->buf_fix_count > 0) {
/* We cannot remove this page during /* We cannot remove this page during
this scan yet; maybe the system is this scan yet; maybe the system is
...@@ -380,8 +394,40 @@ scan_again: ...@@ -380,8 +394,40 @@ scan_again:
(ulong) buf_page_get_page_no(bpage)); (ulong) buf_page_get_page_no(bpage));
} }
#endif #endif
if (buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
&& ((buf_block_t*) bpage)->is_hashed) { /* 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 page_no;
ulint zip_size; ulint zip_size;
...@@ -405,7 +451,8 @@ scan_again: ...@@ -405,7 +451,8 @@ scan_again:
buf_flush_remove(bpage); buf_flush_remove(bpage);
} }
/* Remove from the LRU list */ /* Remove from the LRU list. */
if (buf_LRU_block_remove_hashed_page(bpage, TRUE) if (buf_LRU_block_remove_hashed_page(bpage, TRUE)
!= BUF_BLOCK_ZIP_FREE) { != BUF_BLOCK_ZIP_FREE) {
buf_LRU_block_free_hashed_page((buf_block_t*) buf_LRU_block_free_hashed_page((buf_block_t*)
...@@ -417,18 +464,27 @@ scan_again: ...@@ -417,18 +464,27 @@ scan_again:
ut_ad(block_mutex == &buf_pool_zip_mutex); ut_ad(block_mutex == &buf_pool_zip_mutex);
ut_ad(!mutex_own(block_mutex)); ut_ad(!mutex_own(block_mutex));
/* The compressed block descriptor if (prev_bpage_buf_fix) {
(bpage) has been deallocated and /* We temporarily buffer-fixed
block_mutex released. Also, prev_bpage, so that
buf_buddy_free() may have relocated buf_buddy_free() could not
prev_bpage. Rescan the LRU list. */ relocate it, in case it was a
compressed-only block
descriptor. */
bpage = UT_LIST_GET_LAST(buf_pool->LRU); mutex_enter(block_mutex);
continue; ut_ad(prev_bpage->buf_fix_count > 0);
prev_bpage->buf_fix_count--;
mutex_exit(block_mutex);
} }
goto next_page_no_mutex;
} }
next_page: next_page:
mutex_exit(block_mutex); mutex_exit(block_mutex);
}
next_page_no_mutex:
bpage = prev_bpage; bpage = prev_bpage;
} }
...@@ -1398,8 +1454,10 @@ alloc: ...@@ -1398,8 +1454,10 @@ alloc:
buf_page_t* prev_b = UT_LIST_GET_PREV(LRU, b); buf_page_t* prev_b = UT_LIST_GET_PREV(LRU, b);
const ulint fold = buf_page_address_fold( const ulint fold = buf_page_address_fold(
bpage->space, bpage->offset); bpage->space, bpage->offset);
buf_page_t* hash_b = buf_page_hash_get_low(
bpage->space, bpage->offset, fold);
ut_a(!buf_page_hash_get(bpage->space, bpage->offset)); ut_a(!hash_b);
b->state = b->oldest_modification b->state = b->oldest_modification
? BUF_BLOCK_ZIP_DIRTY ? BUF_BLOCK_ZIP_DIRTY
...@@ -1474,26 +1532,8 @@ alloc: ...@@ -1474,26 +1532,8 @@ alloc:
if (b->state == BUF_BLOCK_ZIP_PAGE) { if (b->state == BUF_BLOCK_ZIP_PAGE) {
buf_LRU_insert_zip_clean(b); buf_LRU_insert_zip_clean(b);
} else { } else {
buf_page_t* prev; /* Relocate on buf_pool->flush_list. */
buf_flush_relocate_on_flush_list(bpage, b);
ut_ad(b->in_flush_list);
ut_d(bpage->in_flush_list = FALSE);
prev = UT_LIST_GET_PREV(list, b);
UT_LIST_REMOVE(list, buf_pool->flush_list, b);
if (prev) {
ut_ad(prev->in_flush_list);
UT_LIST_INSERT_AFTER(
list,
buf_pool->flush_list,
prev, b);
} else {
UT_LIST_ADD_FIRST(
list,
buf_pool->flush_list,
b);
}
} }
bpage->zip.data = NULL; bpage->zip.data = NULL;
...@@ -1642,6 +1682,7 @@ buf_LRU_block_remove_hashed_page( ...@@ -1642,6 +1682,7 @@ buf_LRU_block_remove_hashed_page(
ibool zip) /*!< in: TRUE if should remove also the ibool zip) /*!< in: TRUE if should remove also the
compressed page of an uncompressed page */ compressed page of an uncompressed page */
{ {
ulint fold;
const buf_page_t* hashed_bpage; const buf_page_t* hashed_bpage;
ut_ad(bpage); ut_ad(bpage);
ut_ad(buf_pool_mutex_own()); ut_ad(buf_pool_mutex_own());
...@@ -1725,7 +1766,9 @@ buf_LRU_block_remove_hashed_page( ...@@ -1725,7 +1766,9 @@ buf_LRU_block_remove_hashed_page(
break; break;
} }
hashed_bpage = buf_page_hash_get(bpage->space, bpage->offset); fold = buf_page_address_fold(bpage->space, bpage->offset);
hashed_bpage = buf_page_hash_get_low(bpage->space, bpage->offset,
fold);
if (UNIV_UNLIKELY(bpage != hashed_bpage)) { if (UNIV_UNLIKELY(bpage != hashed_bpage)) {
fprintf(stderr, fprintf(stderr,
...@@ -1757,9 +1800,7 @@ buf_LRU_block_remove_hashed_page( ...@@ -1757,9 +1800,7 @@ buf_LRU_block_remove_hashed_page(
ut_ad(!bpage->in_zip_hash); ut_ad(!bpage->in_zip_hash);
ut_ad(bpage->in_page_hash); ut_ad(bpage->in_page_hash);
ut_d(bpage->in_page_hash = FALSE); ut_d(bpage->in_page_hash = FALSE);
HASH_DELETE(buf_page_t, hash, buf_pool->page_hash, HASH_DELETE(buf_page_t, hash, buf_pool->page_hash, fold, bpage);
buf_page_address_fold(bpage->space, bpage->offset),
bpage);
switch (buf_page_get_state(bpage)) { switch (buf_page_get_state(bpage)) {
case BUF_BLOCK_ZIP_PAGE: case BUF_BLOCK_ZIP_PAGE:
ut_ad(!bpage->in_free_list); ut_ad(!bpage->in_free_list);
...@@ -2036,6 +2077,7 @@ buf_LRU_print(void) ...@@ -2036,6 +2077,7 @@ buf_LRU_print(void)
while (bpage != NULL) { while (bpage != NULL) {
mutex_enter(buf_page_get_mutex(bpage));
fprintf(stderr, "BLOCK space %lu page %lu ", fprintf(stderr, "BLOCK space %lu page %lu ",
(ulong) buf_page_get_space(bpage), (ulong) buf_page_get_space(bpage),
(ulong) buf_page_get_page_no(bpage)); (ulong) buf_page_get_page_no(bpage));
...@@ -2084,6 +2126,7 @@ buf_LRU_print(void) ...@@ -2084,6 +2126,7 @@ buf_LRU_print(void)
break; break;
} }
mutex_exit(buf_page_get_mutex(bpage));
bpage = UT_LIST_GET_NEXT(LRU, bpage); bpage = UT_LIST_GET_NEXT(LRU, bpage);
} }
......
/***************************************************************************** /*****************************************************************************
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 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 the terms of the GNU General Public License as published by the Free Software
...@@ -608,14 +608,14 @@ buf_read_recv_pages( ...@@ -608,14 +608,14 @@ buf_read_recv_pages(
while (buf_pool->n_pend_reads >= recv_n_pool_free_frames / 2) { while (buf_pool->n_pend_reads >= recv_n_pool_free_frames / 2) {
os_aio_simulated_wake_handler_threads(); os_aio_simulated_wake_handler_threads();
os_thread_sleep(500000); os_thread_sleep(10000);
count++; count++;
if (count > 100) { if (count > 1000) {
fprintf(stderr, fprintf(stderr,
"InnoDB: Error: InnoDB has waited for" "InnoDB: Error: InnoDB has waited for"
" 50 seconds for pending\n" " 10 seconds for pending\n"
"InnoDB: reads to the buffer pool to" "InnoDB: reads to the buffer pool to"
" be finished.\n" " be finished.\n"
"InnoDB: Number of pending reads %lu," "InnoDB: Number of pending reads %lu,"
......
/***************************************************************************** /*****************************************************************************
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 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 the terms of the GNU General Public License as published by the Free Software
...@@ -274,6 +274,9 @@ dict_boot(void) ...@@ -274,6 +274,9 @@ dict_boot(void)
and (TYPE & DICT_TF_FORMAT_MASK) are nonzero and TYPE = table->flags */ 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, "TYPE", DATA_INT, 0, 4);
dict_mem_table_add_col(table, heap, "MIX_ID", DATA_BINARY, 0, 0); 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, "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, "CLUSTER_NAME", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, heap, "SPACE", DATA_INT, 0, 4); dict_mem_table_add_col(table, heap, "SPACE", DATA_INT, 0, 4);
...@@ -355,7 +358,7 @@ dict_boot(void) ...@@ -355,7 +358,7 @@ dict_boot(void)
dict_mem_table_add_col(table, heap, "SPACE", DATA_INT, 0, 4); 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); 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 #if DICT_SYS_INDEXES_PAGE_NO_FIELD != 6 + 2
#error "DICT_SYS_INDEXES_PAGE_NO_FIELD != 6 + 2" #error "DICT_SYS_INDEXES_PAGE_NO_FIELD != 6 + 2"
#endif #endif
...@@ -364,6 +367,9 @@ dict_boot(void) ...@@ -364,6 +367,9 @@ dict_boot(void)
#endif #endif
#if DICT_SYS_INDEXES_TYPE_FIELD != 4 + 2 #if DICT_SYS_INDEXES_TYPE_FIELD != 4 + 2
#error "DICT_SYS_INDEXES_TYPE_FIELD != 4 + 2" #error "DICT_SYS_INDEXES_TYPE_FIELD != 4 + 2"
#endif
#if DICT_SYS_INDEXES_NAME_FIELD != 1 + 2
#error "DICT_SYS_INDEXES_NAME_FIELD != 1 + 2"
#endif #endif
table->id = DICT_INDEXES_ID; table->id = DICT_INDEXES_ID;
......
This diff is collapsed.
/***************************************************************************** /*****************************************************************************
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 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 the terms of the GNU General Public License as published by the Free Software
...@@ -70,6 +70,17 @@ we need this; NOTE: a transaction which reserves this must keep book ...@@ -70,6 +70,17 @@ we need this; NOTE: a transaction which reserves this must keep book
on the mode in trx_struct::dict_operation_lock_mode */ on the mode in trx_struct::dict_operation_lock_mode */
UNIV_INTERN rw_lock_t dict_operation_lock; UNIV_INTERN rw_lock_t dict_operation_lock;
/* Keys to register rwlocks and mutexes with performance schema */
#ifdef UNIV_PFS_RWLOCK
UNIV_INTERN mysql_pfs_key_t dict_operation_lock_key;
UNIV_INTERN mysql_pfs_key_t index_tree_rw_lock_key;
#endif /* UNIV_PFS_RWLOCK */
#ifdef UNIV_PFS_MUTEX
UNIV_INTERN mysql_pfs_key_t dict_sys_mutex_key;
UNIV_INTERN mysql_pfs_key_t dict_foreign_err_mutex_key;
#endif /* UNIV_PFS_MUTEX */
#define DICT_HEAP_SIZE 100 /*!< initial memory heap size when #define DICT_HEAP_SIZE 100 /*!< initial memory heap size when
creating a table or index object */ creating a table or index object */
#define DICT_POOL_PER_TABLE_HASH 512 /*!< buffer pool max size per table #define DICT_POOL_PER_TABLE_HASH 512 /*!< buffer pool max size per table
...@@ -140,7 +151,7 @@ static ...@@ -140,7 +151,7 @@ static
void void
dict_field_print_low( dict_field_print_low(
/*=================*/ /*=================*/
dict_field_t* field); /*!< in: field */ const dict_field_t* field); /*!< in: field */
/*********************************************************************//** /*********************************************************************//**
Frees a foreign key struct. */ Frees a foreign key struct. */
static static
...@@ -607,7 +618,7 @@ dict_init(void) ...@@ -607,7 +618,7 @@ dict_init(void)
{ {
dict_sys = mem_alloc(sizeof(dict_sys_t)); dict_sys = mem_alloc(sizeof(dict_sys_t));
mutex_create(&dict_sys->mutex, SYNC_DICT); mutex_create(dict_sys_mutex_key, &dict_sys->mutex, SYNC_DICT);
dict_sys->table_hash = hash_create(buf_pool_get_curr_size() dict_sys->table_hash = hash_create(buf_pool_get_curr_size()
/ (DICT_POOL_PER_TABLE_HASH / (DICT_POOL_PER_TABLE_HASH
...@@ -619,12 +630,14 @@ dict_init(void) ...@@ -619,12 +630,14 @@ dict_init(void)
UT_LIST_INIT(dict_sys->table_LRU); UT_LIST_INIT(dict_sys->table_LRU);
rw_lock_create(&dict_operation_lock, SYNC_DICT_OPERATION); rw_lock_create(dict_operation_lock_key,
&dict_operation_lock, SYNC_DICT_OPERATION);
dict_foreign_err_file = os_file_create_tmpfile(); dict_foreign_err_file = os_file_create_tmpfile();
ut_a(dict_foreign_err_file); ut_a(dict_foreign_err_file);
mutex_create(&dict_foreign_err_mutex, SYNC_ANY_LATCH); mutex_create(dict_foreign_err_mutex_key,
&dict_foreign_err_mutex, SYNC_ANY_LATCH);
} }
/**********************************************************************//** /**********************************************************************//**
...@@ -1460,6 +1473,7 @@ dict_index_add_to_cache( ...@@ -1460,6 +1473,7 @@ dict_index_add_to_cache(
if (!dict_index_find_cols(table, index)) { if (!dict_index_find_cols(table, index)) {
dict_mem_index_free(index);
return(DB_CORRUPTION); return(DB_CORRUPTION);
} }
...@@ -1566,7 +1580,8 @@ undo_size_ok: ...@@ -1566,7 +1580,8 @@ undo_size_ok:
new_index->stat_n_leaf_pages = 1; new_index->stat_n_leaf_pages = 1;
new_index->page = page_no; new_index->page = page_no;
rw_lock_create(&new_index->lock, SYNC_INDEX_TREE); rw_lock_create(index_tree_rw_lock_key, &new_index->lock,
SYNC_INDEX_TREE);
if (!UNIV_UNLIKELY(new_index->type & DICT_UNIVERSAL)) { if (!UNIV_UNLIKELY(new_index->type & DICT_UNIVERSAL)) {
...@@ -4402,7 +4417,7 @@ static ...@@ -4402,7 +4417,7 @@ static
void void
dict_field_print_low( dict_field_print_low(
/*=================*/ /*=================*/
dict_field_t* field) /*!< in: field */ const dict_field_t* field) /*!< in: field */
{ {
ut_ad(mutex_own(&(dict_sys->mutex))); ut_ad(mutex_own(&(dict_sys->mutex)));
...@@ -4766,8 +4781,10 @@ UNIV_INTERN ...@@ -4766,8 +4781,10 @@ UNIV_INTERN
void void
dict_table_check_for_dup_indexes( 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 */ in this table */
ibool tmp_ok) /*!< in: TRUE=allow temporary
index names */
{ {
/* Check for duplicates, ignoring indexes that are marked /* Check for duplicates, ignoring indexes that are marked
as to be dropped */ as to be dropped */
...@@ -4775,13 +4792,17 @@ dict_table_check_for_dup_indexes( ...@@ -4775,13 +4792,17 @@ dict_table_check_for_dup_indexes(
const dict_index_t* index1; const dict_index_t* index1;
const dict_index_t* index2; const dict_index_t* index2;
ut_ad(mutex_own(&dict_sys->mutex));
/* The primary index _must_ exist */ /* The primary index _must_ exist */
ut_a(UT_LIST_GET_LEN(table->indexes) > 0); ut_a(UT_LIST_GET_LEN(table->indexes) > 0);
index1 = UT_LIST_GET_FIRST(table->indexes); 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) { while (index2) {
...@@ -4793,8 +4814,7 @@ dict_table_check_for_dup_indexes( ...@@ -4793,8 +4814,7 @@ dict_table_check_for_dup_indexes(
} }
index1 = UT_LIST_GET_NEXT(indexes, index1); index1 = UT_LIST_GET_NEXT(indexes, index1);
index2 = UT_LIST_GET_NEXT(indexes, index1); } while (index1);
}
} }
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
......
/***************************************************************************** /*****************************************************************************
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 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 the terms of the GNU General Public License as published by the Free Software
...@@ -260,7 +260,7 @@ dict_sys_tables_get_flags( ...@@ -260,7 +260,7 @@ dict_sys_tables_get_flags(
return(0); 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); n_cols = mach_read_from_4(field);
if (UNIV_UNLIKELY(!(n_cols & 0x80000000UL))) { if (UNIV_UNLIKELY(!(n_cols & 0x80000000UL))) {
...@@ -390,15 +390,35 @@ loop: ...@@ -390,15 +390,35 @@ loop:
mtr_commit(&mtr); mtr_commit(&mtr);
if (space_id != 0 && in_crash_recovery) { if (space_id == 0) {
/* The system tablespace always exists. */
} else if (in_crash_recovery) {
/* Check that the tablespace (the .ibd file) really /* 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, field = rec_get_nth_field_old(rec, 4, &len);
FALSE, TRUE, TRUE); 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 /* It is a normal database startup: create the space
object and check that the .ibd file exists. */ object and check that the .ibd file exists. */
...@@ -894,43 +914,72 @@ err_exit: ...@@ -894,43 +914,72 @@ err_exit:
(ulong) flags); (ulong) flags);
goto err_exit; goto err_exit;
} }
} else {
flags = 0;
}
ut_a(name_of_col_is(sys_tables, sys_index, 4, "N_COLS"));
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.
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));
}
if (fil_space_for_table_exists_in_mem(space, name, FALSE, flags |= flags2 << DICT_TF2_SHIFT;
}
/* See if the tablespace is available. */
if (space == 0) {
/* 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)) { 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. */
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); ut_print_timestamp(stderr);
fprintf(stderr, fprintf(stderr,
" InnoDB: error: space object of table %s,\n" " InnoDB: error: space object of table");
ut_print_filename(stderr, name);
fprintf(stderr, ",\n"
"InnoDB: space id %lu did not exist in memory." "InnoDB: space id %lu did not exist in memory."
" Retrying an open.\n", " Retrying an open.\n",
name, (ulong)space); (ulong) space);
/* Try to open the tablespace */ /* Try to open the tablespace */
if (!fil_open_single_table_tablespace( if (!fil_open_single_table_tablespace(
TRUE, space, flags, name)) { TRUE, space,
/* We failed to find a sensible tablespace flags & ~(~0 << DICT_TF_BITS), name)) {
file */ /* We failed to find a sensible
tablespace file */
ibd_file_missing = TRUE; ibd_file_missing = TRUE;
} }
} }
} else {
flags = 0;
}
ut_a(name_of_col_is(sys_tables, sys_index, 4, "N_COLS"));
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. */
if (n_cols & 0x80000000UL) {
flags |= DICT_TF_COMPACT;
} }
table = dict_mem_table_create(name, space, n_cols & ~0x80000000UL, table = dict_mem_table_create(name, space, n_cols & ~0x80000000UL,
......
/***************************************************************************** /*****************************************************************************
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 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 the terms of the GNU General Public License as published by the Free Software
...@@ -40,6 +40,11 @@ Created 1/8/1996 Heikki Tuuri ...@@ -40,6 +40,11 @@ Created 1/8/1996 Heikki Tuuri
#define DICT_HEAP_SIZE 100 /*!< initial memory heap size when #define DICT_HEAP_SIZE 100 /*!< initial memory heap size when
creating a table or index object */ creating a table or index object */
#ifdef UNIV_PFS_MUTEX
/* Key to register autoinc_mutex with performance schema */
UNIV_INTERN mysql_pfs_key_t autoinc_mutex_key;
#endif /* UNIV_PFS_MUTEX */
/**********************************************************************//** /**********************************************************************//**
Creates a table memory object. Creates a table memory object.
@return own: table object */ @return own: table object */
...@@ -59,7 +64,7 @@ dict_mem_table_create( ...@@ -59,7 +64,7 @@ dict_mem_table_create(
mem_heap_t* heap; mem_heap_t* heap;
ut_ad(name); ut_ad(name);
ut_a(!(flags & (~0 << DICT_TF_BITS))); ut_a(!(flags & (~0 << DICT_TF2_BITS)));
heap = mem_heap_create(DICT_HEAP_SIZE); heap = mem_heap_create(DICT_HEAP_SIZE);
...@@ -78,7 +83,8 @@ dict_mem_table_create( ...@@ -78,7 +83,8 @@ dict_mem_table_create(
#ifndef UNIV_HOTBACKUP #ifndef UNIV_HOTBACKUP
table->autoinc_lock = mem_heap_alloc(heap, lock_get_size()); table->autoinc_lock = mem_heap_alloc(heap, lock_get_size());
mutex_create(&table->autoinc_mutex, SYNC_DICT_AUTOINC_MUTEX); mutex_create(autoinc_mutex_key,
&table->autoinc_mutex, SYNC_DICT_AUTOINC_MUTEX);
table->autoinc = 0; table->autoinc = 0;
......
/***************************************************************************** /*****************************************************************************
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 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 the terms of the GNU General Public License as published by the Free Software
...@@ -38,6 +38,7 @@ Created 10/25/1995 Heikki Tuuri ...@@ -38,6 +38,7 @@ Created 10/25/1995 Heikki Tuuri
#include "mtr0mtr.h" #include "mtr0mtr.h"
#include "mtr0log.h" #include "mtr0log.h"
#include "dict0dict.h" #include "dict0dict.h"
#include "page0page.h"
#include "page0zip.h" #include "page0zip.h"
#ifndef UNIV_HOTBACKUP #ifndef UNIV_HOTBACKUP
# include "buf0lru.h" # include "buf0lru.h"
...@@ -120,6 +121,16 @@ UNIV_INTERN ulint fil_n_pending_tablespace_flushes = 0; ...@@ -120,6 +121,16 @@ UNIV_INTERN ulint fil_n_pending_tablespace_flushes = 0;
/** The null file address */ /** The null file address */
UNIV_INTERN fil_addr_t fil_addr_null = {FIL_NULL, 0}; UNIV_INTERN fil_addr_t fil_addr_null = {FIL_NULL, 0};
#ifdef UNIV_PFS_MUTEX
/* Key to register fil_system_mutex with performance schema */
UNIV_INTERN mysql_pfs_key_t fil_system_mutex_key;
#endif /* UNIV_PFS_MUTEX */
#ifdef UNIV_PFS_RWLOCK
/* Key to register file space latch with performance schema */
UNIV_INTERN mysql_pfs_key_t fil_space_latch_key;
#endif /* UNIV_PFS_RWLOCK */
/** File node of a tablespace or the log data space */ /** File node of a tablespace or the log data space */
struct fil_node_struct { struct fil_node_struct {
fil_space_t* space; /*!< backpointer to the space where this node fil_space_t* space; /*!< backpointer to the space where this node
...@@ -648,7 +659,8 @@ fil_node_open_file( ...@@ -648,7 +659,8 @@ fil_node_open_file(
async I/O! */ async I/O! */
node->handle = os_file_create_simple_no_error_handling( node->handle = os_file_create_simple_no_error_handling(
node->name, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success); innodb_file_data_key, node->name, OS_FILE_OPEN,
OS_FILE_READ_ONLY, &success);
if (!success) { if (!success) {
/* The following call prints an error message */ /* The following call prints an error message */
os_file_get_last_error(TRUE); os_file_get_last_error(TRUE);
...@@ -766,15 +778,21 @@ add_size: ...@@ -766,15 +778,21 @@ add_size:
os_file_create() to fall back to the normal file I/O mode. */ os_file_create() to fall back to the normal file I/O mode. */
if (space->purpose == FIL_LOG) { if (space->purpose == FIL_LOG) {
node->handle = os_file_create(node->name, OS_FILE_OPEN, node->handle = os_file_create(innodb_file_log_key,
OS_FILE_AIO, OS_LOG_FILE, &ret); node->name, OS_FILE_OPEN,
OS_FILE_AIO, OS_LOG_FILE,
&ret);
} else if (node->is_raw_disk) { } else if (node->is_raw_disk) {
node->handle = os_file_create(node->name, node->handle = os_file_create(innodb_file_data_key,
node->name,
OS_FILE_OPEN_RAW, OS_FILE_OPEN_RAW,
OS_FILE_AIO, OS_DATA_FILE, &ret); OS_FILE_AIO, OS_DATA_FILE,
&ret);
} else { } else {
node->handle = os_file_create(node->name, OS_FILE_OPEN, node->handle = os_file_create(innodb_file_data_key,
OS_FILE_AIO, OS_DATA_FILE, &ret); node->name, OS_FILE_OPEN,
OS_FILE_AIO, OS_DATA_FILE,
&ret);
} }
ut_a(ret); ut_a(ret);
...@@ -1097,10 +1115,13 @@ fil_space_create( ...@@ -1097,10 +1115,13 @@ fil_space_create(
fil_space_t* space; fil_space_t* space;
/* The tablespace flags (FSP_SPACE_FLAGS) should be 0 for /* 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 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 != DICT_TF_COMPACT);
ut_a(!(flags & (~0UL << DICT_TF_BITS)));
try_again: try_again:
/*printf( /*printf(
...@@ -1208,7 +1229,7 @@ try_again: ...@@ -1208,7 +1229,7 @@ try_again:
UT_LIST_INIT(space->chain); UT_LIST_INIT(space->chain);
space->magic_n = FIL_SPACE_MAGIC_N; space->magic_n = FIL_SPACE_MAGIC_N;
rw_lock_create(&space->latch, SYNC_FSP); rw_lock_create(fil_space_latch_key, &space->latch, SYNC_FSP);
HASH_INSERT(fil_space_t, hash, fil_system->spaces, id, space); HASH_INSERT(fil_space_t, hash, fil_system->spaces, id, space);
...@@ -1510,7 +1531,8 @@ fil_init( ...@@ -1510,7 +1531,8 @@ fil_init(
fil_system = mem_alloc(sizeof(fil_system_t)); fil_system = mem_alloc(sizeof(fil_system_t));
mutex_create(&fil_system->mutex, SYNC_ANY_LATCH); mutex_create(fil_system_mutex_key,
&fil_system->mutex, SYNC_ANY_LATCH);
fil_system->spaces = hash_create(hash_size); fil_system->spaces = hash_create(hash_size);
fil_system->name_hash = hash_create(hash_size); fil_system->name_hash = hash_create(hash_size);
...@@ -2515,7 +2537,7 @@ retry: ...@@ -2515,7 +2537,7 @@ retry:
success = fil_rename_tablespace_in_mem(space, node, path); success = fil_rename_tablespace_in_mem(space, node, path);
if (success) { if (success) {
success = os_file_rename(old_path, path); success = os_file_rename(innodb_file_data_key, old_path, path);
if (!success) { if (!success) {
/* We have to revert the changes we made /* We have to revert the changes we made
...@@ -2582,14 +2604,18 @@ fil_create_new_single_table_tablespace( ...@@ -2582,14 +2604,18 @@ fil_create_new_single_table_tablespace(
ut_a(size >= FIL_IBD_FILE_INITIAL_SIZE); ut_a(size >= FIL_IBD_FILE_INITIAL_SIZE);
/* The tablespace flags (FSP_SPACE_FLAGS) should be 0 for /* 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 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 != DICT_TF_COMPACT);
ut_a(!(flags & (~0UL << DICT_TF_BITS)));
path = fil_make_ibd_name(tablename, is_temp); path = fil_make_ibd_name(tablename, is_temp);
file = os_file_create(path, OS_FILE_CREATE, OS_FILE_NORMAL, file = os_file_create(innodb_file_data_key, path,
OS_FILE_CREATE, OS_FILE_NORMAL,
OS_DATA_FILE, &ret); OS_DATA_FILE, &ret);
if (ret == FALSE) { if (ret == FALSE) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
...@@ -2786,11 +2812,13 @@ fil_reset_too_high_lsns( ...@@ -2786,11 +2812,13 @@ fil_reset_too_high_lsns(
ib_int64_t offset; ib_int64_t offset;
ulint zip_size; ulint zip_size;
ibool success; ibool success;
page_zip_des_t page_zip;
filepath = fil_make_ibd_name(name, FALSE); filepath = fil_make_ibd_name(name, FALSE);
file = os_file_create_simple_no_error_handling( file = os_file_create_simple_no_error_handling(
filepath, OS_FILE_OPEN, OS_FILE_READ_WRITE, &success); innodb_file_data_key, filepath, OS_FILE_OPEN,
OS_FILE_READ_WRITE, &success);
if (!success) { if (!success) {
/* The following call prints an error message */ /* The following call prints an error message */
os_file_get_last_error(TRUE); os_file_get_last_error(TRUE);
...@@ -2833,6 +2861,12 @@ fil_reset_too_high_lsns( ...@@ -2833,6 +2861,12 @@ fil_reset_too_high_lsns(
space_id = fsp_header_get_space_id(page); space_id = fsp_header_get_space_id(page);
zip_size = fsp_header_get_zip_size(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); ut_print_timestamp(stderr);
fprintf(stderr, fprintf(stderr,
" InnoDB: Flush lsn in the tablespace file %lu" " InnoDB: Flush lsn in the tablespace file %lu"
...@@ -2867,20 +2901,23 @@ fil_reset_too_high_lsns( ...@@ -2867,20 +2901,23 @@ fil_reset_too_high_lsns(
/* We have to reset the lsn */ /* We have to reset the lsn */
if (zip_size) { if (zip_size) {
memcpy(page + UNIV_PAGE_SIZE, page, zip_size); memcpy(page_zip.data, page, zip_size);
buf_flush_init_for_writing( buf_flush_init_for_writing(
page, page + UNIV_PAGE_SIZE, page, &page_zip, current_lsn);
current_lsn); success = os_file_write(
filepath, file, page_zip.data,
(ulint) offset & 0xFFFFFFFFUL,
(ulint) (offset >> 32), zip_size);
} else { } else {
buf_flush_init_for_writing( buf_flush_init_for_writing(
page, NULL, current_lsn); page, NULL, current_lsn);
} success = os_file_write(
success = os_file_write(filepath, file, page, filepath, file, page,
(ulint)(offset & 0xFFFFFFFFUL), (ulint)(offset & 0xFFFFFFFFUL),
(ulint)(offset >> 32), (ulint)(offset >> 32),
zip_size UNIV_PAGE_SIZE);
? zip_size }
: UNIV_PAGE_SIZE);
if (!success) { if (!success) {
goto func_exit; goto func_exit;
...@@ -2956,13 +2993,17 @@ fil_open_single_table_tablespace( ...@@ -2956,13 +2993,17 @@ fil_open_single_table_tablespace(
filepath = fil_make_ibd_name(name, FALSE); filepath = fil_make_ibd_name(name, FALSE);
/* The tablespace flags (FSP_SPACE_FLAGS) should be 0 for /* 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 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 != DICT_TF_COMPACT);
ut_a(!(flags & (~0UL << DICT_TF_BITS)));
file = os_file_create_simple_no_error_handling( file = os_file_create_simple_no_error_handling(
filepath, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success); innodb_file_data_key, filepath, OS_FILE_OPEN,
OS_FILE_READ_ONLY, &success);
if (!success) { if (!success) {
/* The following call prints an error message */ /* The following call prints an error message */
os_file_get_last_error(TRUE); os_file_get_last_error(TRUE);
...@@ -3011,7 +3052,8 @@ fil_open_single_table_tablespace( ...@@ -3011,7 +3052,8 @@ fil_open_single_table_tablespace(
ut_free(buf2); 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); ut_print_timestamp(stderr);
fputs(" InnoDB: Error: tablespace id and flags in file ", fputs(" InnoDB: Error: tablespace id and flags in file ",
...@@ -3117,7 +3159,8 @@ fil_load_single_table_tablespace( ...@@ -3117,7 +3159,8 @@ fil_load_single_table_tablespace(
# endif /* !UNIV_HOTBACKUP */ # endif /* !UNIV_HOTBACKUP */
#endif #endif
file = os_file_create_simple_no_error_handling( file = os_file_create_simple_no_error_handling(
filepath, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success); innodb_file_data_key, filepath, OS_FILE_OPEN,
OS_FILE_READ_ONLY, &success);
if (!success) { if (!success) {
/* The following call prints an error message */ /* The following call prints an error message */
os_file_get_last_error(TRUE); os_file_get_last_error(TRUE);
...@@ -3275,7 +3318,7 @@ fil_load_single_table_tablespace( ...@@ -3275,7 +3318,7 @@ fil_load_single_table_tablespace(
os_file_close(file); os_file_close(file);
new_path = fil_make_ibbackup_old_name(filepath); new_path = fil_make_ibbackup_old_name(filepath);
ut_a(os_file_rename(filepath, new_path)); ut_a(os_file_rename(innodb_file_data_key, filepath, new_path));
ut_free(buf2); ut_free(buf2);
mem_free(filepath); mem_free(filepath);
...@@ -3313,7 +3356,7 @@ fil_load_single_table_tablespace( ...@@ -3313,7 +3356,7 @@ fil_load_single_table_tablespace(
mutex_exit(&fil_system->mutex); mutex_exit(&fil_system->mutex);
ut_a(os_file_rename(filepath, new_path)); ut_a(os_file_rename(innodb_file_data_key, filepath, new_path));
ut_free(buf2); ut_free(buf2);
mem_free(filepath); mem_free(filepath);
...@@ -4435,11 +4478,14 @@ fil_aio_wait( ...@@ -4435,11 +4478,14 @@ fil_aio_wait(
ut_ad(fil_validate()); ut_ad(fil_validate());
if (os_aio_use_native_aio) { if (srv_use_native_aio) {
srv_set_io_thread_op_info(segment, "native aio handle"); srv_set_io_thread_op_info(segment, "native aio handle");
#ifdef WIN_ASYNC_IO #ifdef WIN_ASYNC_IO
ret = os_aio_windows_handle(segment, 0, &fil_node, ret = os_aio_windows_handle(segment, 0, &fil_node,
&message, &type); &message, &type);
#elif defined(LINUX_NATIVE_AIO)
ret = os_aio_linux_handle(segment, &fil_node,
&message, &type);
#else #else
ret = 0; /* Eliminate compiler warning */ ret = 0; /* Eliminate compiler warning */
ut_error; ut_error;
...@@ -4781,8 +4827,10 @@ void ...@@ -4781,8 +4827,10 @@ void
fil_close(void) fil_close(void)
/*===========*/ /*===========*/
{ {
#ifndef UNIV_HOTBACKUP
/* The mutex should already have been freed. */ /* The mutex should already have been freed. */
ut_ad(fil_system->mutex.magic_n == 0); ut_ad(fil_system->mutex.magic_n == 0);
#endif /* !UNIV_HOTBACKUP */
hash_table_free(fil_system->spaces); hash_table_free(fil_system->spaces);
......
/***************************************************************************** /*****************************************************************************
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 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 the terms of the GNU General Public License as published by the Free Software
...@@ -386,7 +386,7 @@ UNIV_INLINE ...@@ -386,7 +386,7 @@ UNIV_INLINE
ibool ibool
xdes_get_bit( xdes_get_bit(
/*=========*/ /*=========*/
xdes_t* descr, /*!< in: descriptor */ const xdes_t* descr, /*!< in: descriptor */
ulint bit, /*!< in: XDES_FREE_BIT or XDES_CLEAN_BIT */ ulint bit, /*!< in: XDES_FREE_BIT or XDES_CLEAN_BIT */
ulint offset, /*!< in: page offset within extent: ulint offset, /*!< in: page offset within extent:
0 ... FSP_EXTENT_SIZE - 1 */ 0 ... FSP_EXTENT_SIZE - 1 */
...@@ -527,7 +527,7 @@ UNIV_INLINE ...@@ -527,7 +527,7 @@ UNIV_INLINE
ulint ulint
xdes_get_n_used( xdes_get_n_used(
/*============*/ /*============*/
xdes_t* descr, /*!< in: descriptor */ const xdes_t* descr, /*!< in: descriptor */
mtr_t* mtr) /*!< in: mtr */ mtr_t* mtr) /*!< in: mtr */
{ {
ulint i; ulint i;
...@@ -551,7 +551,7 @@ UNIV_INLINE ...@@ -551,7 +551,7 @@ UNIV_INLINE
ibool ibool
xdes_is_free( xdes_is_free(
/*=========*/ /*=========*/
xdes_t* descr, /*!< in: descriptor */ const xdes_t* descr, /*!< in: descriptor */
mtr_t* mtr) /*!< in: mtr */ mtr_t* mtr) /*!< in: mtr */
{ {
if (0 == xdes_get_n_used(descr, mtr)) { if (0 == xdes_get_n_used(descr, mtr)) {
...@@ -569,7 +569,7 @@ UNIV_INLINE ...@@ -569,7 +569,7 @@ UNIV_INLINE
ibool ibool
xdes_is_full( xdes_is_full(
/*=========*/ /*=========*/
xdes_t* descr, /*!< in: descriptor */ const xdes_t* descr, /*!< in: descriptor */
mtr_t* mtr) /*!< in: mtr */ mtr_t* mtr) /*!< in: mtr */
{ {
if (FSP_EXTENT_SIZE == xdes_get_n_used(descr, mtr)) { if (FSP_EXTENT_SIZE == xdes_get_n_used(descr, mtr)) {
...@@ -586,7 +586,7 @@ UNIV_INLINE ...@@ -586,7 +586,7 @@ UNIV_INLINE
void void
xdes_set_state( xdes_set_state(
/*===========*/ /*===========*/
xdes_t* descr, /*!< in: descriptor */ xdes_t* descr, /*!< in/out: descriptor */
ulint state, /*!< in: state to set */ ulint state, /*!< in: state to set */
mtr_t* mtr) /*!< in: mtr handle */ mtr_t* mtr) /*!< in: mtr handle */
{ {
...@@ -605,7 +605,7 @@ UNIV_INLINE ...@@ -605,7 +605,7 @@ UNIV_INLINE
ulint ulint
xdes_get_state( xdes_get_state(
/*===========*/ /*===========*/
xdes_t* descr, /*!< in: descriptor */ const xdes_t* descr, /*!< in: descriptor */
mtr_t* mtr) /*!< in: mtr handle */ mtr_t* mtr) /*!< in: mtr handle */
{ {
ulint state; ulint state;
...@@ -705,7 +705,7 @@ UNIV_INLINE ...@@ -705,7 +705,7 @@ UNIV_INLINE
xdes_t* xdes_t*
xdes_get_descriptor_with_space_hdr( 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 space, /*!< in: space id */
ulint offset, /*!< in: page offset; ulint offset, /*!< in: page offset;
if equal to the free limit, if equal to the free limit,
...@@ -869,9 +869,7 @@ fsp_init_file_page_low( ...@@ -869,9 +869,7 @@ fsp_init_file_page_low(
return; return;
} }
#ifdef UNIV_BASIC_LOG_DEBUG UNIV_MEM_INVALID(page, UNIV_PAGE_SIZE);
memset(page, 0xff, UNIV_PAGE_SIZE);
#endif
mach_write_to_4(page + FIL_PAGE_OFFSET, buf_block_get_page_no(block)); mach_write_to_4(page + FIL_PAGE_OFFSET, buf_block_get_page_no(block));
memset(page + FIL_PAGE_LSN, 0, 8); memset(page + FIL_PAGE_LSN, 0, 8);
mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID,
...@@ -1342,7 +1340,7 @@ fsp_fill_free_list( ...@@ -1342,7 +1340,7 @@ fsp_fill_free_list(
descriptor page and ibuf bitmap page; descriptor page and ibuf bitmap page;
then we do not allocate more extents */ then we do not allocate more extents */
ulint space, /*!< in: space */ ulint space, /*!< in: space */
fsp_header_t* header, /*!< in: space header */ fsp_header_t* header, /*!< in/out: space header */
mtr_t* mtr) /*!< in: mtr */ mtr_t* mtr) /*!< in: mtr */
{ {
ulint limit; ulint limit;
......
...@@ -101,6 +101,8 @@ ha_clear( ...@@ -101,6 +101,8 @@ ha_clear(
ulint i; ulint i;
ulint n; ulint n;
ut_ad(table);
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EXCLUSIVE)); ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EXCLUSIVE));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
...@@ -146,7 +148,9 @@ ha_insert_for_fold_func( ...@@ -146,7 +148,9 @@ ha_insert_for_fold_func(
ha_node_t* prev_node; ha_node_t* prev_node;
ulint hash; 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 #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
ut_a(block->frame == page_align(data)); ut_a(block->frame == page_align(data));
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
...@@ -237,6 +241,8 @@ ha_delete_hash_node( ...@@ -237,6 +241,8 @@ ha_delete_hash_node(
hash_table_t* table, /*!< in: hash table */ hash_table_t* table, /*!< in: hash table */
ha_node_t* del_node) /*!< in: node to be deleted */ 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 #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
# ifndef UNIV_HOTBACKUP # ifndef UNIV_HOTBACKUP
if (table->adaptive) { if (table->adaptive) {
...@@ -267,6 +273,8 @@ ha_search_and_update_if_found_func( ...@@ -267,6 +273,8 @@ ha_search_and_update_if_found_func(
{ {
ha_node_t* node; ha_node_t* node;
ut_ad(table);
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
ASSERT_HASH_MUTEX_OWN(table, fold); ASSERT_HASH_MUTEX_OWN(table, fold);
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
ut_a(new_block->frame == page_align(new_data)); ut_a(new_block->frame == page_align(new_data));
...@@ -304,6 +312,8 @@ ha_remove_all_nodes_to_page( ...@@ -304,6 +312,8 @@ ha_remove_all_nodes_to_page(
{ {
ha_node_t* node; ha_node_t* node;
ut_ad(table);
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
ASSERT_HASH_MUTEX_OWN(table, fold); ASSERT_HASH_MUTEX_OWN(table, fold);
node = ha_chain_get_first(table, fold); node = ha_chain_get_first(table, fold);
...@@ -353,6 +363,8 @@ ha_validate( ...@@ -353,6 +363,8 @@ ha_validate(
ibool ok = TRUE; ibool ok = TRUE;
ulint i; ulint i;
ut_ad(table);
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
ut_a(start_index <= end_index); ut_a(start_index <= end_index);
ut_a(start_index < hash_get_n_cells(table)); ut_a(start_index < hash_get_n_cells(table));
ut_a(end_index < hash_get_n_cells(table)); ut_a(end_index < hash_get_n_cells(table));
...@@ -391,6 +403,8 @@ ha_print_info( ...@@ -391,6 +403,8 @@ ha_print_info(
FILE* file, /*!< in: file where to print */ FILE* file, /*!< in: file where to print */
hash_table_t* table) /*!< in: hash table */ hash_table_t* table) /*!< in: hash table */
{ {
ut_ad(table);
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
/* Some of the code here is disabled for performance reasons in production /* Some of the code here is disabled for performance reasons in production
builds, see http://bugs.mysql.com/36941 */ builds, see http://bugs.mysql.com/36941 */
......
...@@ -31,6 +31,11 @@ Created 5/20/1997 Heikki Tuuri ...@@ -31,6 +31,11 @@ Created 5/20/1997 Heikki Tuuri
#include "mem0mem.h" #include "mem0mem.h"
#ifndef UNIV_HOTBACKUP #ifndef UNIV_HOTBACKUP
# ifdef UNIV_PFS_MUTEX
UNIV_INTERN mysql_pfs_key_t hash_table_mutex_key;
# endif /* UNIV_PFS_MUTEX */
/************************************************************//** /************************************************************//**
Reserves the mutex for a fold value in a hash table. */ Reserves the mutex for a fold value in a hash table. */
UNIV_INTERN UNIV_INTERN
...@@ -119,7 +124,7 @@ hash_create( ...@@ -119,7 +124,7 @@ hash_create(
table->heaps = NULL; table->heaps = NULL;
#endif /* !UNIV_HOTBACKUP */ #endif /* !UNIV_HOTBACKUP */
table->heap = NULL; table->heap = NULL;
table->magic_n = HASH_TABLE_MAGIC_N; ut_d(table->magic_n = HASH_TABLE_MAGIC_N);
/* Initialize the cell array */ /* Initialize the cell array */
hash_table_clear(table); hash_table_clear(table);
...@@ -135,6 +140,8 @@ hash_table_free( ...@@ -135,6 +140,8 @@ hash_table_free(
/*============*/ /*============*/
hash_table_t* table) /*!< in, own: hash table */ hash_table_t* table) /*!< in, own: hash table */
{ {
ut_ad(table);
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
#ifndef UNIV_HOTBACKUP #ifndef UNIV_HOTBACKUP
ut_a(table->mutexes == NULL); ut_a(table->mutexes == NULL);
#endif /* !UNIV_HOTBACKUP */ #endif /* !UNIV_HOTBACKUP */
...@@ -160,13 +167,16 @@ hash_create_mutexes_func( ...@@ -160,13 +167,16 @@ hash_create_mutexes_func(
{ {
ulint i; ulint i;
ut_ad(table);
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
ut_a(n_mutexes > 0); ut_a(n_mutexes > 0);
ut_a(ut_is_2pow(n_mutexes)); ut_a(ut_is_2pow(n_mutexes));
table->mutexes = mem_alloc(n_mutexes * sizeof(mutex_t)); table->mutexes = mem_alloc(n_mutexes * sizeof(mutex_t));
for (i = 0; i < n_mutexes; i++) { for (i = 0; i < n_mutexes; i++) {
mutex_create(table->mutexes + i, sync_level); mutex_create(hash_table_mutex_key,
table->mutexes + i, sync_level);
} }
table->n_mutexes = n_mutexes; table->n_mutexes = n_mutexes;
......
This diff is collapsed.
/***************************************************************************** /*****************************************************************************
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 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 the terms of the GNU General Public License as published by the Free Software
...@@ -27,6 +27,18 @@ Place, Suite 330, Boston, MA 02111-1307 USA ...@@ -27,6 +27,18 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#pragma interface /* gcc class implementation */ #pragma interface /* gcc class implementation */
#endif #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 */ /** InnoDB table share */
typedef struct st_innobase_share { typedef struct st_innobase_share {
THR_LOCK lock; /*!< MySQL lock protecting THR_LOCK lock; /*!< MySQL lock protecting
...@@ -34,8 +46,12 @@ typedef struct st_innobase_share { ...@@ -34,8 +46,12 @@ typedef struct st_innobase_share {
const char* table_name; /*!< InnoDB table name */ const char* table_name; /*!< InnoDB table name */
uint use_count; /*!< reference count, uint use_count; /*!< reference count,
incremented in get_share() incremented in get_share()
and decremented in free_share() */ and decremented in
free_share() */
void* table_name_hash;/*!< hash table chain node */ void* table_name_hash;/*!< hash table chain node */
innodb_idx_translate_t idx_trans_tbl; /*!< index translation
table between MySQL and
Innodb */
} INNOBASE_SHARE; } INNOBASE_SHARE;
...@@ -91,9 +107,8 @@ class ha_innobase: public handler ...@@ -91,9 +107,8 @@ class ha_innobase: public handler
ulint innobase_reset_autoinc(ulonglong auto_inc); ulint innobase_reset_autoinc(ulonglong auto_inc);
ulint innobase_get_autoinc(ulonglong* value); ulint innobase_get_autoinc(ulonglong* value);
ulint innobase_update_autoinc(ulonglong auto_inc); ulint innobase_update_autoinc(ulonglong auto_inc);
ulint innobase_initialize_autoinc(); void innobase_initialize_autoinc();
dict_index_t* innobase_get_index(uint keynr); dict_index_t* innobase_get_index(uint keynr);
ulonglong innobase_get_int_col_max_value(const Field* field);
/* Init values for the class: */ /* Init values for the class: */
public: public:
......
/***************************************************************************** /*****************************************************************************
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 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 the terms of the GNU General Public License as published by the Free Software
...@@ -21,10 +21,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA ...@@ -21,10 +21,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
Smart ALTER TABLE Smart ALTER TABLE
*******************************************************/ *******************************************************/
#include <unireg.h> #include <mysql_priv.h>
#include <mysqld_error.h> #include <mysqld_error.h>
#include <sql_lex.h> // SQLCOM_CREATE_INDEX
#include <mysql/innodb_priv.h>
extern "C" { extern "C" {
#include "log0log.h" #include "log0log.h"
...@@ -231,9 +229,11 @@ static ...@@ -231,9 +229,11 @@ static
int int
innobase_check_index_keys( innobase_check_index_keys(
/*======================*/ /*======================*/
const KEY* key_info, /*!< in: Indexes to be created */ const KEY* key_info, /*!< in: Indexes to be
ulint num_of_keys) /*!< in: Number of indexes to created */
be created */ ulint num_of_keys, /*!< in: Number of
indexes to be created */
const dict_table_t* table) /*!< in: Existing indexes */
{ {
ulint key_num; ulint key_num;
...@@ -250,8 +250,21 @@ innobase_check_index_keys( ...@@ -250,8 +250,21 @@ innobase_check_index_keys(
const KEY& key2 = key_info[i]; const KEY& key2 = key_info[i];
if (0 == strcmp(key.name, key2.name)) { if (0 == strcmp(key.name, key2.name)) {
sql_print_error("InnoDB: key name `%s` appears" my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0),
" twice in CREATE INDEX\n", 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); key.name);
return(ER_WRONG_NAME_FOR_INDEX); return(ER_WRONG_NAME_FOR_INDEX);
...@@ -260,7 +273,7 @@ innobase_check_index_keys( ...@@ -260,7 +273,7 @@ innobase_check_index_keys(
/* Check that MySQL does not try to create a column /* Check that MySQL does not try to create a column
prefix index field on an inappropriate data type and 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++) { for (ulint i = 0; i < key.key_parts; i++) {
const KEY_PART_INFO& key_part1 const KEY_PART_INFO& key_part1
...@@ -291,14 +304,8 @@ innobase_check_index_keys( ...@@ -291,14 +304,8 @@ innobase_check_index_keys(
} }
} }
sql_print_error("InnoDB: MySQL is trying to" my_error(ER_WRONG_KEY_COLUMN, MYF(0),
" create a column prefix" field->field_name);
" index field on an"
" inappropriate data type."
" column `%s`,"
" index `%s`.\n",
field->field_name,
key.name);
return(ER_WRONG_KEY_COLUMN); return(ER_WRONG_KEY_COLUMN);
} }
...@@ -311,11 +318,8 @@ innobase_check_index_keys( ...@@ -311,11 +318,8 @@ innobase_check_index_keys(
continue; continue;
} }
sql_print_error("InnoDB: column `%s`" my_error(ER_WRONG_KEY_COLUMN, MYF(0),
" is not allowed to occur" key_part1.field->field_name);
" twice in index `%s`.\n",
key_part1.field->field_name,
key.name);
return(ER_WRONG_KEY_COLUMN); return(ER_WRONG_KEY_COLUMN);
} }
} }
...@@ -524,10 +528,12 @@ innobase_create_key_def( ...@@ -524,10 +528,12 @@ innobase_create_key_def(
key_info->name, "PRIMARY"); key_info->name, "PRIMARY");
/* If there is a UNIQUE INDEX consisting entirely of NOT NULL /* If there is a UNIQUE INDEX consisting entirely of NOT NULL
columns, MySQL will treat it as a PRIMARY KEY unless the columns and if the index does not contain column prefix(es)
table already has one. */ (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) if (!new_primary && (key_info->flags & HA_NOSAME)
&& (!(key_info->flags & HA_KEY_HAS_PART_KEY_SEG))
&& row_table_got_default_clust_index(table)) { && row_table_got_default_clust_index(table)) {
uint key_part = key_info->key_parts; uint key_part = key_info->key_parts;
...@@ -658,12 +664,18 @@ ha_innobase::add_index( ...@@ -658,12 +664,18 @@ ha_innobase::add_index(
innodb_table = indexed_table innodb_table = indexed_table
= dict_table_get(prebuilt->table->name, FALSE); = 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. */ /* Check if the index name is reserved. */
if (innobase_index_name_is_reserved(trx, key_info, num_of_keys)) { if (innobase_index_name_is_reserved(trx, key_info, num_of_keys)) {
error = -1; error = -1;
} else { } else {
/* Check that index keys are sensible */ /* 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)) { if (UNIV_UNLIKELY(error)) {
...@@ -710,6 +722,8 @@ err_exit: ...@@ -710,6 +722,8 @@ err_exit:
row_mysql_lock_data_dictionary(trx); row_mysql_lock_data_dictionary(trx);
dict_locked = TRUE; 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 /* If a new primary key is defined for the table we need
to drop the original table and rebuild all indexes. */ to drop the original table and rebuild all indexes. */
...@@ -742,6 +756,8 @@ err_exit: ...@@ -742,6 +756,8 @@ err_exit:
user_thd); user_thd);
} }
ut_d(dict_table_check_for_dup_indexes(innodb_table,
FALSE));
row_mysql_unlock_data_dictionary(trx); row_mysql_unlock_data_dictionary(trx);
goto err_exit; goto err_exit;
} }
...@@ -766,6 +782,10 @@ err_exit: ...@@ -766,6 +782,10 @@ err_exit:
ut_ad(error == DB_SUCCESS); 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 /* Commit the data dictionary transaction in order to release
the table locks on the system tables. This means that if the table locks on the system tables. This means that if
MySQL crashes while creating a new primary key inside MySQL crashes while creating a new primary key inside
...@@ -801,18 +821,6 @@ err_exit: ...@@ -801,18 +821,6 @@ err_exit:
index, num_of_idx, table); index, num_of_idx, table);
error_handling: 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 /* After an error, remove all those index definitions from the
dictionary which were defined. */ dictionary which were defined. */
...@@ -824,6 +832,8 @@ error_handling: ...@@ -824,6 +832,8 @@ error_handling:
row_mysql_lock_data_dictionary(trx); row_mysql_lock_data_dictionary(trx);
dict_locked = TRUE; dict_locked = TRUE;
ut_d(dict_table_check_for_dup_indexes(prebuilt->table, TRUE));
if (!new_primary) { if (!new_primary) {
error = row_merge_rename_indexes(trx, indexed_table); error = row_merge_rename_indexes(trx, indexed_table);
...@@ -910,6 +920,8 @@ convert_error: ...@@ -910,6 +920,8 @@ convert_error:
trx_commit_for_mysql(prebuilt->trx); trx_commit_for_mysql(prebuilt->trx);
} }
ut_d(dict_table_check_for_dup_indexes(innodb_table, FALSE));
if (dict_locked) { if (dict_locked) {
row_mysql_unlock_data_dictionary(trx); row_mysql_unlock_data_dictionary(trx);
} }
...@@ -953,6 +965,7 @@ ha_innobase::prepare_drop_index( ...@@ -953,6 +965,7 @@ ha_innobase::prepare_drop_index(
/* Test and mark all the indexes to be dropped */ /* Test and mark all the indexes to be dropped */
row_mysql_lock_data_dictionary(trx); 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 /* Check that none of the indexes have previously been flagged
for deletion. */ for deletion. */
...@@ -1118,6 +1131,7 @@ func_exit: ...@@ -1118,6 +1131,7 @@ func_exit:
} while (index); } while (index);
} }
ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
row_mysql_unlock_data_dictionary(trx); row_mysql_unlock_data_dictionary(trx);
DBUG_RETURN(err); DBUG_RETURN(err);
...@@ -1164,6 +1178,7 @@ ha_innobase::final_drop_index( ...@@ -1164,6 +1178,7 @@ ha_innobase::final_drop_index(
prebuilt->table->flags, user_thd); prebuilt->table->flags, user_thd);
row_mysql_lock_data_dictionary(trx); row_mysql_lock_data_dictionary(trx);
ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
if (UNIV_UNLIKELY(err)) { if (UNIV_UNLIKELY(err)) {
...@@ -1200,11 +1215,12 @@ ha_innobase::final_drop_index( ...@@ -1200,11 +1215,12 @@ ha_innobase::final_drop_index(
ut_a(!index->to_be_dropped); ut_a(!index->to_be_dropped);
} }
#ifdef UNIV_DEBUG /* We will need to rebuild index translation table. Set
dict_table_check_for_dup_indexes(prebuilt->table); valid index entry count in the translation table to zero */
#endif share->idx_trans_tbl.index_count = 0;
func_exit: func_exit:
ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
trx_commit_for_mysql(trx); trx_commit_for_mysql(trx);
trx_commit_for_mysql(prebuilt->trx); trx_commit_for_mysql(prebuilt->trx);
row_mysql_unlock_data_dictionary(trx); row_mysql_unlock_data_dictionary(trx);
......
...@@ -23,8 +23,8 @@ InnoDB INFORMATION SCHEMA tables interface to MySQL. ...@@ -23,8 +23,8 @@ InnoDB INFORMATION SCHEMA tables interface to MySQL.
Created July 18, 2007 Vasil Dimov Created July 18, 2007 Vasil Dimov
*******************************************************/ *******************************************************/
#include <mysql_priv.h>
#include <mysqld_error.h> #include <mysqld_error.h>
#include <sql_acl.h> // PROCESS_ACL
#include <m_ctype.h> #include <m_ctype.h>
#include <hash.h> #include <hash.h>
...@@ -32,8 +32,7 @@ Created July 18, 2007 Vasil Dimov ...@@ -32,8 +32,7 @@ Created July 18, 2007 Vasil Dimov
#include <mysys_err.h> #include <mysys_err.h>
#include <my_sys.h> #include <my_sys.h>
#include "i_s.h" #include "i_s.h"
#include <sql_plugin.h> #include <mysql/plugin.h>
#include <mysql/innodb_priv.h>
extern "C" { extern "C" {
#include "trx0i_s.h" #include "trx0i_s.h"
......
...@@ -36,7 +36,7 @@ Created November 07, 2007 Vasil Dimov ...@@ -36,7 +36,7 @@ Created November 07, 2007 Vasil Dimov
#define MYSQL_SERVER #define MYSQL_SERVER
#endif /* MYSQL_SERVER */ #endif /* MYSQL_SERVER */
#include <sql_priv.h> #include <mysql_priv.h>
#include "mysql_addons.h" #include "mysql_addons.h"
#include "univ.i" #include "univ.i"
This diff is collapsed.
/***************************************************************************** /*****************************************************************************
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 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 the terms of the GNU General Public License as published by the Free Software
...@@ -68,19 +68,30 @@ enum btr_latch_mode { ...@@ -68,19 +68,30 @@ enum btr_latch_mode {
BTR_MODIFY_PREV = 36 BTR_MODIFY_PREV = 36
}; };
/* BTR_INSERT, BTR_DELETE and BTR_DELETE_MARK are mutually exclusive. */
/** If this is ORed to btr_latch_mode, it means that the search tuple /** If this is ORed to btr_latch_mode, it means that the search tuple
will be inserted to the index, at the searched position */ will be inserted to the index, at the searched position.
When the record is not in the buffer pool, try to use the insert buffer. */
#define BTR_INSERT 512 #define BTR_INSERT 512
/** This flag ORed to btr_latch_mode says that we do the search in query /** This flag ORed to btr_latch_mode says that we do the search in query
optimization */ optimization */
#define BTR_ESTIMATE 1024 #define BTR_ESTIMATE 1024
/** This flag ORed to btr_latch_mode says that we can ignore possible /** This flag ORed to BTR_INSERT says that we can ignore possible
UNIQUE definition on secondary indexes when we decide if we can use UNIQUE definition on secondary indexes when we decide if we can use
the insert buffer to speed up inserts */ the insert buffer to speed up inserts */
#define BTR_IGNORE_SEC_UNIQUE 2048 #define BTR_IGNORE_SEC_UNIQUE 2048
/** Try to delete mark the record at the searched position using the
insert/delete buffer when the record is not in the buffer pool. */
#define BTR_DELETE_MARK 4096
/** Try to purge the record at the searched position using the insert/delete
buffer when the record is not in the buffer pool. */
#define BTR_DELETE 8192
/**************************************************************//** /**************************************************************//**
Gets the root node of a tree and x-latches it. Gets the root node of a tree and x-latches it.
@return root page, x-latched */ @return root page, x-latched */
...@@ -193,6 +204,10 @@ btr_leaf_page_release( ...@@ -193,6 +204,10 @@ btr_leaf_page_release(
mtr_t* mtr); /*!< in: mtr */ mtr_t* mtr); /*!< in: mtr */
/**************************************************************//** /**************************************************************//**
Gets the child node file address in a node pointer. 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 */ @return child node address */
UNIV_INLINE UNIV_INLINE
ulint ulint
...@@ -317,12 +332,16 @@ Inserts a data tuple to a tree on a non-leaf level. It is assumed ...@@ -317,12 +332,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. */ that mtr holds an x-latch on the tree. */
UNIV_INTERN UNIV_INTERN
void void
btr_insert_on_non_leaf_level( btr_insert_on_non_leaf_level_func(
/*=========================*/ /*==============================*/
dict_index_t* index, /*!< in: index */ dict_index_t* index, /*!< in: index */
ulint level, /*!< in: level, must be > 0 */ ulint level, /*!< in: level, must be > 0 */
dtuple_t* tuple, /*!< in: the record to be inserted */ 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 */ 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 */ #endif /* !UNIV_HOTBACKUP */
/****************************************************************//** /****************************************************************//**
Sets a record as the predefined minimum record. */ Sets a record as the predefined minimum record. */
......
/***************************************************************************** /*****************************************************************************
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 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 the terms of the GNU General Public License as published by the Free Software
...@@ -255,6 +255,10 @@ btr_page_set_prev( ...@@ -255,6 +255,10 @@ btr_page_set_prev(
/**************************************************************//** /**************************************************************//**
Gets the child node file address in a node pointer. 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 */ @return child node address */
UNIV_INLINE UNIV_INLINE
ulint ulint
......
/***************************************************************************** /*****************************************************************************
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 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 the terms of the GNU General Public License as published by the Free Software
...@@ -138,7 +138,8 @@ btr_cur_search_to_nth_level( ...@@ -138,7 +138,8 @@ btr_cur_search_to_nth_level(
should always be made using PAGE_CUR_LE to should always be made using PAGE_CUR_LE to
search the position! */ search the position! */
ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ..., ORed with ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ..., ORed with
BTR_INSERT and BTR_ESTIMATE; at most one of BTR_INSERT, BTR_DELETE_MARK,
BTR_DELETE, or BTR_ESTIMATE;
cursor->left_block is used to store a pointer cursor->left_block is used to store a pointer
to the left neighbor page, in the cases to the left neighbor page, in the cases
BTR_SEARCH_PREV and BTR_MODIFY_PREV; BTR_SEARCH_PREV and BTR_MODIFY_PREV;
...@@ -152,29 +153,39 @@ btr_cur_search_to_nth_level( ...@@ -152,29 +153,39 @@ btr_cur_search_to_nth_level(
ulint has_search_latch,/*!< in: latch mode the caller ulint has_search_latch,/*!< in: latch mode the caller
currently has on btr_search_latch: currently has on btr_search_latch:
RW_S_LATCH, or 0 */ RW_S_LATCH, or 0 */
const char* file, /*!< in: file name */
ulint line, /*!< in: line where called */
mtr_t* mtr); /*!< in: mtr */ mtr_t* mtr); /*!< in: mtr */
/*****************************************************************//** /*****************************************************************//**
Opens a cursor at either end of an index. */ Opens a cursor at either end of an index. */
UNIV_INTERN UNIV_INTERN
void 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, ibool from_left, /*!< in: TRUE if open to the low end,
FALSE if to the high end */ FALSE if to the high end */
dict_index_t* index, /*!< in: index */ dict_index_t* index, /*!< in: index */
ulint latch_mode, /*!< in: latch mode */ ulint latch_mode, /*!< in: latch mode */
btr_cur_t* cursor, /*!< in: cursor */ btr_cur_t* cursor, /*!< in: cursor */
const char* file, /*!< in: file name */
ulint line, /*!< in: line where called */
mtr_t* mtr); /*!< in: mtr */ 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. */ Positions a cursor at a randomly chosen position within a B-tree. */
UNIV_INTERN UNIV_INTERN
void void
btr_cur_open_at_rnd_pos( btr_cur_open_at_rnd_pos_func(
/*====================*/ /*=========================*/
dict_index_t* index, /*!< in: index */ dict_index_t* index, /*!< in: index */
ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */ ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
btr_cur_t* cursor, /*!< in/out: B-tree cursor */ 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 */ 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. 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 It is assumed that mtr holds an x-latch on the page. The operation does
...@@ -322,19 +333,6 @@ btr_cur_del_mark_set_sec_rec( ...@@ -322,19 +333,6 @@ btr_cur_del_mark_set_sec_rec(
ibool val, /*!< in: value to set */ ibool val, /*!< in: value to set */
que_thr_t* thr, /*!< in: query thread */ que_thr_t* thr, /*!< in: query thread */
mtr_t* mtr); /*!< in: mtr */ mtr_t* mtr); /*!< in: mtr */
/***********************************************************//**
Clear a secondary index record's delete mark. This function is only
used by the insert buffer insert merge mechanism. */
UNIV_INTERN
void
btr_cur_del_unmark_for_ibuf(
/*========================*/
rec_t* rec, /*!< in/out: record to delete unmark */
page_zip_des_t* page_zip, /*!< in/out: compressed page
corresponding to rec, or NULL
when the tablespace is
uncompressed */
mtr_t* mtr); /*!< in: mtr */
/*************************************************************//** /*************************************************************//**
Tries to compress a page of the tree if it seems useful. It is assumed Tries to compress a page of the tree if it seems useful. It is assumed
that mtr holds an x-latch on the tree and on the cursor page. To avoid that mtr holds an x-latch on the tree and on the cursor page. To avoid
...@@ -586,7 +584,20 @@ btr_push_update_extern_fields( ...@@ -586,7 +584,20 @@ btr_push_update_extern_fields(
const upd_t* update, /*!< in: update vector */ const upd_t* update, /*!< in: update vector */
mem_heap_t* heap) /*!< in: memory heap */ mem_heap_t* heap) /*!< in: memory heap */
__attribute__((nonnull)); __attribute__((nonnull));
/***********************************************************//**
Sets a secondary index record's delete mark to the given value. This
function is only used by the insert buffer merge mechanism. */
UNIV_INTERN
void
btr_cur_set_deleted_flag_for_ibuf(
/*==============================*/
rec_t* rec, /*!< in/out: record */
page_zip_des_t* page_zip, /*!< in/out: compressed page
corresponding to rec, or NULL
when the tablespace is
uncompressed */
ibool val, /*!< in: value to set */
mtr_t* mtr); /*!< in: mtr */
/*######################################################################*/ /*######################################################################*/
/** In the pessimistic delete, if the page data size drops below this /** In the pessimistic delete, if the page data size drops below this
...@@ -618,8 +629,13 @@ enum btr_cur_method { ...@@ -618,8 +629,13 @@ enum btr_cur_method {
hash_node, and might be necessary to hash_node, and might be necessary to
update */ update */
BTR_CUR_BINARY, /*!< success using the binary search */ BTR_CUR_BINARY, /*!< success using the binary search */
BTR_CUR_INSERT_TO_IBUF /*!< performed the intended insert to BTR_CUR_INSERT_TO_IBUF, /*!< performed the intended insert to
the insert buffer */ the insert buffer */
BTR_CUR_DEL_MARK_IBUF, /*!< performed the intended delete
mark in the insert/delete buffer */
BTR_CUR_DELETE_IBUF, /*!< performed the intended delete in
the insert/delete buffer */
BTR_CUR_DELETE_REF /*!< row_purge_poss_sec() failed */
}; };
/** The tree cursor: the definition appears here only for the compiler /** The tree cursor: the definition appears here only for the compiler
...@@ -627,6 +643,7 @@ to know struct size! */ ...@@ -627,6 +643,7 @@ to know struct size! */
struct btr_cur_struct { struct btr_cur_struct {
dict_index_t* index; /*!< index where positioned */ dict_index_t* index; /*!< index where positioned */
page_cur_t page_cur; /*!< page cursor */ page_cur_t page_cur; /*!< page cursor */
purge_node_t* purge_node; /*!< purge node, for BTR_DELETE */
buf_block_t* left_block; /*!< this field is used to store buf_block_t* left_block; /*!< this field is used to store
a pointer to the left neighbor a pointer to the left neighbor
page, in the cases page, in the cases
...@@ -683,6 +700,23 @@ struct btr_cur_struct { ...@@ -683,6 +700,23 @@ struct btr_cur_struct {
NULL */ NULL */
ulint fold; /*!< fold value used in the search if ulint fold; /*!< fold value used in the search if
flag is BTR_CUR_HASH */ flag is BTR_CUR_HASH */
/*----- Delete buffering -------*/
ulint ibuf_cnt; /* in searches done on insert buffer
trees, this contains the "counter"
value (the first two bytes of the
fourth field) extracted from the
page above the leaf page, from the
father node pointer that pointed to
the leaf page. in other words, it
contains the minimum counter value
for records to be inserted on the
chosen leaf page. If for some reason
this can't be read, or if the search
ended on the leftmost leaf page in
the tree (in which case the father
node pointer had the 'minimum
record' flag set), this is
ULINT_UNDEFINED. */
/*------------------------------*/ /*------------------------------*/
/* @} */ /* @} */
btr_path_t* path_arr; /*!< in estimating the number of btr_path_t* path_arr; /*!< in estimating the number of
......
/***************************************************************************** /*****************************************************************************
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 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 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 ...@@ -82,8 +82,8 @@ Initializes and opens a persistent cursor to an index tree. It should be
closed with btr_pcur_close. */ closed with btr_pcur_close. */
UNIV_INLINE UNIV_INLINE
void void
btr_pcur_open( btr_pcur_open_func(
/*==========*/ /*===============*/
dict_index_t* index, /*!< in: index */ dict_index_t* index, /*!< in: index */
const dtuple_t* tuple, /*!< in: tuple on which search done */ const dtuple_t* tuple, /*!< in: tuple on which search done */
ulint mode, /*!< in: PAGE_CUR_L, ...; ulint mode, /*!< in: PAGE_CUR_L, ...;
...@@ -94,14 +94,18 @@ btr_pcur_open( ...@@ -94,14 +94,18 @@ btr_pcur_open(
record! */ record! */
ulint latch_mode,/*!< in: BTR_SEARCH_LEAF, ... */ ulint latch_mode,/*!< in: BTR_SEARCH_LEAF, ... */
btr_pcur_t* cursor, /*!< in: memory buffer for persistent cursor */ 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 */ 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 Opens an persistent cursor to an index tree without initializing the
cursor. */ cursor. */
UNIV_INLINE UNIV_INLINE
void void
btr_pcur_open_with_no_init( btr_pcur_open_with_no_init_func(
/*=======================*/ /*============================*/
dict_index_t* index, /*!< in: index */ dict_index_t* index, /*!< in: index */
const dtuple_t* tuple, /*!< in: tuple on which search done */ const dtuple_t* tuple, /*!< in: tuple on which search done */
ulint mode, /*!< in: PAGE_CUR_L, ...; ulint mode, /*!< in: PAGE_CUR_L, ...;
...@@ -119,7 +123,12 @@ btr_pcur_open_with_no_init( ...@@ -119,7 +123,12 @@ btr_pcur_open_with_no_init(
ulint has_search_latch,/*!< in: latch mode the caller ulint has_search_latch,/*!< in: latch mode the caller
currently has on btr_search_latch: currently has on btr_search_latch:
RW_S_LATCH, or 0 */ RW_S_LATCH, or 0 */
const char* file, /*!< in: file name */
ulint line, /*!< in: line where called */
mtr_t* mtr); /*!< in: mtr */ 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. */ Opens a persistent cursor at either end of an index. */
UNIV_INLINE UNIV_INLINE
...@@ -160,8 +169,8 @@ before first in tree. The latching mode must be BTR_SEARCH_LEAF or ...@@ -160,8 +169,8 @@ before first in tree. The latching mode must be BTR_SEARCH_LEAF or
BTR_MODIFY_LEAF. */ BTR_MODIFY_LEAF. */
UNIV_INTERN UNIV_INTERN
void void
btr_pcur_open_on_user_rec( btr_pcur_open_on_user_rec_func(
/*======================*/ /*===========================*/
dict_index_t* index, /*!< in: index */ dict_index_t* index, /*!< in: index */
const dtuple_t* tuple, /*!< in: tuple on which search done */ const dtuple_t* tuple, /*!< in: tuple on which search done */
ulint mode, /*!< in: PAGE_CUR_L, ... */ ulint mode, /*!< in: PAGE_CUR_L, ... */
...@@ -169,17 +178,25 @@ btr_pcur_open_on_user_rec( ...@@ -169,17 +178,25 @@ btr_pcur_open_on_user_rec(
BTR_MODIFY_LEAF */ BTR_MODIFY_LEAF */
btr_pcur_t* cursor, /*!< in: memory buffer for persistent btr_pcur_t* cursor, /*!< in: memory buffer for persistent
cursor */ cursor */
const char* file, /*!< in: file name */
ulint line, /*!< in: line where called */
mtr_t* mtr); /*!< in: mtr */ 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. */ Positions a cursor at a randomly chosen position within a B-tree. */
UNIV_INLINE UNIV_INLINE
void void
btr_pcur_open_at_rnd_pos( btr_pcur_open_at_rnd_pos_func(
/*=====================*/ /*==========================*/
dict_index_t* index, /*!< in: index */ dict_index_t* index, /*!< in: index */
ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */ ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
btr_pcur_t* cursor, /*!< in/out: B-tree pcur */ 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 */ 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 Frees the possible old_rec_buf buffer of a persistent cursor and sets the
latch mode of the persistent cursor to BTR_NO_LATCHES. */ 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 ...@@ -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 */ are identical to the ones of the original user record */
UNIV_INTERN UNIV_INTERN
ibool ibool
btr_pcur_restore_position( btr_pcur_restore_position_func(
/*======================*/ /*===========================*/
ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */ ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
btr_pcur_t* cursor, /*!< in: detached persistent cursor */ 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 */ 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, 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. releases the page latch and bufferfix reserved by the cursor.
...@@ -260,20 +281,13 @@ btr_pcur_get_mtr( ...@@ -260,20 +281,13 @@ btr_pcur_get_mtr(
/*=============*/ /*=============*/
btr_pcur_t* cursor); /*!< in: persistent cursor */ 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 that is, the cursor becomes detached. If there have been modifications
to the page where pcur is positioned, this can be used instead of 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 btr_pcur_release_leaf. Function btr_pcur_store_position should be used
before calling this, if restoration of cursor is wanted later. */ before calling this, if restoration of cursor is wanted later. */
UNIV_INLINE UNIV_INLINE
void 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_commit_specify_mtr(
/*========================*/ /*========================*/
btr_pcur_t* pcur, /*!< in: persistent cursor */ btr_pcur_t* pcur, /*!< in: persistent cursor */
......
/***************************************************************************** /*****************************************************************************
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 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 the terms of the GNU General Public License as published by the Free Software
...@@ -395,30 +395,13 @@ btr_pcur_move_to_next( ...@@ -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 that is, the cursor becomes detached. If there have been modifications
to the page where pcur is positioned, this can be used instead of 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 btr_pcur_release_leaf. Function btr_pcur_store_position should be used
before calling this, if restoration of cursor is wanted later. */ before calling this, if restoration of cursor is wanted later. */
UNIV_INLINE UNIV_INLINE
void 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_commit_specify_mtr(
/*========================*/ /*========================*/
btr_pcur_t* pcur, /*!< in: persistent cursor */ btr_pcur_t* pcur, /*!< in: persistent cursor */
...@@ -483,8 +466,8 @@ Initializes and opens a persistent cursor to an index tree. It should be ...@@ -483,8 +466,8 @@ Initializes and opens a persistent cursor to an index tree. It should be
closed with btr_pcur_close. */ closed with btr_pcur_close. */
UNIV_INLINE UNIV_INLINE
void void
btr_pcur_open( btr_pcur_open_func(
/*==========*/ /*===============*/
dict_index_t* index, /*!< in: index */ dict_index_t* index, /*!< in: index */
const dtuple_t* tuple, /*!< in: tuple on which search done */ const dtuple_t* tuple, /*!< in: tuple on which search done */
ulint mode, /*!< in: PAGE_CUR_L, ...; ulint mode, /*!< in: PAGE_CUR_L, ...;
...@@ -495,6 +478,8 @@ btr_pcur_open( ...@@ -495,6 +478,8 @@ btr_pcur_open(
record! */ record! */
ulint latch_mode,/*!< in: BTR_SEARCH_LEAF, ... */ ulint latch_mode,/*!< in: BTR_SEARCH_LEAF, ... */
btr_pcur_t* cursor, /*!< in: memory buffer for persistent cursor */ 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 */ mtr_t* mtr) /*!< in: mtr */
{ {
btr_cur_t* btr_cursor; btr_cur_t* btr_cursor;
...@@ -511,7 +496,7 @@ btr_pcur_open( ...@@ -511,7 +496,7 @@ btr_pcur_open(
btr_cursor = btr_pcur_get_btr_cur(cursor); btr_cursor = btr_pcur_get_btr_cur(cursor);
btr_cur_search_to_nth_level(index, 0, tuple, mode, latch_mode, 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->pos_state = BTR_PCUR_IS_POSITIONED;
cursor->trx_if_known = NULL; cursor->trx_if_known = NULL;
...@@ -522,8 +507,8 @@ Opens an persistent cursor to an index tree without initializing the ...@@ -522,8 +507,8 @@ Opens an persistent cursor to an index tree without initializing the
cursor. */ cursor. */
UNIV_INLINE UNIV_INLINE
void void
btr_pcur_open_with_no_init( btr_pcur_open_with_no_init_func(
/*=======================*/ /*============================*/
dict_index_t* index, /*!< in: index */ dict_index_t* index, /*!< in: index */
const dtuple_t* tuple, /*!< in: tuple on which search done */ const dtuple_t* tuple, /*!< in: tuple on which search done */
ulint mode, /*!< in: PAGE_CUR_L, ...; ulint mode, /*!< in: PAGE_CUR_L, ...;
...@@ -541,6 +526,8 @@ btr_pcur_open_with_no_init( ...@@ -541,6 +526,8 @@ btr_pcur_open_with_no_init(
ulint has_search_latch,/*!< in: latch mode the caller ulint has_search_latch,/*!< in: latch mode the caller
currently has on btr_search_latch: currently has on btr_search_latch:
RW_S_LATCH, or 0 */ RW_S_LATCH, or 0 */
const char* file, /*!< in: file name */
ulint line, /*!< in: line where called */
mtr_t* mtr) /*!< in: mtr */ mtr_t* mtr) /*!< in: mtr */
{ {
btr_cur_t* btr_cursor; btr_cur_t* btr_cursor;
...@@ -553,7 +540,8 @@ btr_pcur_open_with_no_init( ...@@ -553,7 +540,8 @@ btr_pcur_open_with_no_init(
btr_cursor = btr_pcur_get_btr_cur(cursor); btr_cursor = btr_pcur_get_btr_cur(cursor);
btr_cur_search_to_nth_level(index, 0, tuple, mode, latch_mode, 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->pos_state = BTR_PCUR_IS_POSITIONED;
cursor->old_stored = BTR_PCUR_OLD_NOT_STORED; cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
...@@ -600,11 +588,13 @@ btr_pcur_open_at_index_side( ...@@ -600,11 +588,13 @@ btr_pcur_open_at_index_side(
Positions a cursor at a randomly chosen position within a B-tree. */ Positions a cursor at a randomly chosen position within a B-tree. */
UNIV_INLINE UNIV_INLINE
void void
btr_pcur_open_at_rnd_pos( btr_pcur_open_at_rnd_pos_func(
/*=====================*/ /*==========================*/
dict_index_t* index, /*!< in: index */ dict_index_t* index, /*!< in: index */
ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */ ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
btr_pcur_t* cursor, /*!< in/out: B-tree pcur */ 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 */ mtr_t* mtr) /*!< in: mtr */
{ {
/* Initialize the cursor */ /* Initialize the cursor */
...@@ -614,8 +604,9 @@ btr_pcur_open_at_rnd_pos( ...@@ -614,8 +604,9 @@ btr_pcur_open_at_rnd_pos(
btr_pcur_init(cursor); btr_pcur_init(cursor);
btr_cur_open_at_rnd_pos(index, latch_mode, btr_cur_open_at_rnd_pos_func(index, latch_mode,
btr_pcur_get_btr_cur(cursor), mtr); btr_pcur_get_btr_cur(cursor),
file, line, mtr);
cursor->pos_state = BTR_PCUR_IS_POSITIONED; cursor->pos_state = BTR_PCUR_IS_POSITIONED;
cursor->old_stored = BTR_PCUR_OLD_NOT_STORED; cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/***************************************************************************** /*****************************************************************************
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 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 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( ...@@ -285,6 +285,10 @@ dtype_new_store_for_order_and_null_size(
#endif #endif
ulint len; ulint len;
ut_ad(type);
ut_ad(type->mtype >= DATA_VARCHAR);
ut_ad(type->mtype <= DATA_MYSQL);
buf[0] = (byte)(type->mtype & 0xFFUL); buf[0] = (byte)(type->mtype & 0xFFUL);
if (type->prtype & DATA_BINARY_TYPE) { if (type->prtype & DATA_BINARY_TYPE) {
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
--innodb_lock_wait_timeout=2 --loose-innodb_lock_wait_timeout=2
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment