Commit 0c6afe17 authored by unknown's avatar unknown

updated with changes from Percona-Server-5.1.47-11.2

parent 3e4d2be6
......@@ -29,9 +29,9 @@ IF (CMAKE_SIZEOF_VOID_P MATCHES 8)
SET(WIN64 TRUE)
ENDIF (CMAKE_SIZEOF_VOID_P MATCHES 8)
# Include directories under innobase
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/storage/innobase/include
${CMAKE_SOURCE_DIR}/storage/innobase/handler)
# Include directories under innodb_plugin
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/storage/innodb_plugin/include
${CMAKE_SOURCE_DIR}/storage/innodb_plugin/handler)
# Include directories under mysql
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
......@@ -47,7 +47,7 @@ IF (MSVC AND $(WIN64))
PROPERTIES COMPILE_FLAGS -Od)
ENDIF (MSVC AND $(WIN64))
SET(INNOBASE_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c
SET(INNODB_PLUGIN_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c
buf/buf0buddy.c buf/buf0buf.c buf/buf0flu.c buf/buf0lru.c buf/buf0rea.c
data/data0data.c data/data0type.c
dict/dict0boot.c dict/dict0crea.c dict/dict0dict.c dict/dict0load.c dict/dict0mem.c
......@@ -78,22 +78,11 @@ SET(INNOBASE_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c
trx/trx0i_s.c trx/trx0purge.c trx/trx0rec.c trx/trx0roll.c trx/trx0rseg.c
trx/trx0sys.c trx/trx0trx.c trx/trx0undo.c
usr/usr0sess.c
ut/ut0byte.c ut/ut0dbg.c ut/ut0mem.c ut/ut0rnd.c ut/ut0ut.c ut/ut0vec.c
ut/ut0byte.c ut/ut0dbg.c ut/ut0mem.c ut/ut0rbt.c ut/ut0rnd.c ut/ut0ut.c ut/ut0vec.c
ut/ut0list.c ut/ut0wqueue.c)
ADD_DEFINITIONS(-DHAVE_WINDOWS_ATOMICS -DIB_HAVE_PAUSE_INSTRUCTION)
# Windows atomics do not perform well. Disable Windows atomics by default.
# See bug#52102 for details.
#ADD_DEFINITIONS(-DHAVE_WINDOWS_ATOMICS -DINNODB_RW_LOCKS_USE_ATOMICS -DHAVE_IB_PAUSE_INSTRUCTION)
ADD_DEFINITIONS(-DHAVE_IB_PAUSE_INSTRUCTION)
IF (MYSQL_VERSION_ID GREATER "50137")
MYSQL_STORAGE_ENGINE(INNOBASE)
# Use ha_innodb for plugin name, if plugin is built
GET_TARGET_PROPERTY(LIB_LOCATION ha_innobase LOCATION)
IF(LIB_LOCATION)
SET_TARGET_PROPERTIES(ha_innobase PROPERTIES OUTPUT_NAME ha_innodb)
ENDIF(LIB_LOCATION)
ELSE (MYSQL_VERSION_ID GREATER "50137")
IF (NOT SOURCE_SUBLIBS)
ADD_DEFINITIONS(-D_WIN32 -DMYSQL_SERVER)
ADD_LIBRARY(innobase STATIC ${INNOBASE_SOURCES})
# Require mysqld_error.h, which is built as part of the GenError
ADD_DEPENDENCIES(innobase GenError)
ENDIF (NOT SOURCE_SUBLIBS)
ENDIF (MYSQL_VERSION_ID GREATER "50137")
MYSQL_STORAGE_ENGINE(INNODB_PLUGIN)
2010-05-03 The InnoDB Team
* buf0buf.c:
Fix Bug#53248 compressed tables page checksum mismatch after
re-enabling innodb_checksums
2010-04-28 The InnoDB Team
* log/log0recv.h, log/log0recv.c:
Fix Bug#53122 InnoDB recovery uses too big a hash table for redo
log records
2010-04-27 The InnoDB Team
* handler/ha_innodb.cc, lock/lock0lock.c, row/row0mysql.c,
row/row0sel.c:
Fix Bug#48607 READ UNCOMMITTED uses more locks than READ COMMITTED
in InnoDB 5.1+
2010-04-26 The InnoDB Team
* row/row0sel.c:
Fix Bug#52663 Lost update incrementing column value under
READ COMMITTED isolation level
2010-04-22 The InnoDB Team
* include/dict0boot.h, dict/dict0boot.c:
Fix a bug that prevented the crash recovery of fast CREATE INDEX
from dropping partially created indexes.
2010-04-21 The InnoDB Team
* btr/btr0btr.c:
Fix Bug#52964 Infinite loop in btr_page_split_and_insert()
in ROW_FORMAT=COMPRESSED
2010-04-21 The InnoDB Team
* data/data0data.c:
Fix Bug#52745 Failing assertion: blob_no < page_zip->n_blobs
2010-04-20 The InnoDB Team
* dict/dict0crea.c, handler/ha_innodb.cc, include/trx0trx.h:
Fix Bug#50495 'Row size too large' for plugin, but works for
built-in InnoDB
Only check the record size at index creation time when
innodb_strict_mode is set or when ROW_FORMAT is DYNAMIC or COMPRESSED.
2010-04-20 The InnoDB Team
* btr/btr0btr.c, include/univ.i:
Implement UNIV_BTR_AVOID_COPY, for avoiding writes when a B-tree
node is split at the first or last record.
2010-04-15 The InnoDB Team
* trx/trx0rec.c:
Fix Bug#52746 InnoDB purge thread crashed with table containing
prefix indexed blobs
2010-03-31 The InnoDB Team
* mysql-test/innodb_bug51920.test, mysql-test/innodb_bug51920.result,
srv/srv0srv.c:
Fix Bug#51920 InnoDB connections in row lock wait ignore KILL
until lock wait timeout
2010-03-31 The InnoDB Team
* mysql-test/innodb_bug38231.test:
Remove non-determinism in the test case.
2010-03-18 The InnoDB Team
* CMakeLists.txt:
Fix Bug#52102 InnoDB Plugin shows performance drop compared to
InnoDB (Windows)
2010-03-18 The InnoDB Team
* buf0buf.ic:
When comparing the time of the first access to a block against
innodb_old_blocks_time, use 32-bit arithmetics. The comparison was
incorrect on 64-bit systems.
2010-03-11 The InnoDB Team
* buf0buf.h, buf0buf.ic:
Fix and clarify the latching of some buf_block_t members.
Note that check_index_page_at_flush is not protected by any mutex.
Note and assert that lock_hash_val is protected by the rw-latch.
2010-03-10 The InnoDB Team
* trx/trx0sys.c:
Fix Bug#51653 outdated reference to set-variable
2010-03-10 The InnoDB Team
* handler/ha_innodb.cc, mysql-test/innodb_bug21704.result,
mysql-test/innodb_bug47621.result, mysql-test/innodb_bug47621.test:
Fix Bug#47621 MySQL and InnoDB data dictionaries will become out of
sync when renaming columns
2010-03-10 The InnoDB Team
* handler/ha_innodb.cc:
Fix Bug#51356 Many Valgrind errors in error messages
with concurrent DDL
2010-03-10 The InnoDB Team
* handler/ha_innodb.cc, handler/handler0alter.cc,
mysql-test/innodb_bug51378.result, mysql-test/innodb_bug51378.test:
Fix Bug#51378 Init 'ref_length' to correct value, in case an out
of bound MySQL primary_key
2010-03-10 The InnoDB Team
* log/log0recv.c:
Remove a bogus assertion about page numbers exceeding 0x90000000
in the redo log. Abort when encountering a corrupted redo log
record, unless innodb_force_recovery is set.
2010-03-09 The InnoDB Team
* handler/ha_innodb.cc:
Make SHOW ENGINE INNODB MUTEX STATUS display SUM(os_waits)
for the buffer pool block mutexes and locks.
2010-03-08 The InnoDB Team
* fil/fil0fil.c:
Fix ALTER TABLE ... IMPORT TABLESPACE of compressed tables.
2010-03-03 The InnoDB Team
* handler/handler0alter.cc, innodb-index.result, innodb-index.test,
innodb.result, innodb.test:
Disallow a duplicate index name when creating an index.
2010-02-11 The InnoDB Team
* include/mem0mem.h, include/mem0mem.ic, mem/mem0mem.c:
Fix Bug#49535 Available memory check slows down crash
recovery tens of times
2010-02-09 The InnoDB Team
* buf/buf0buf.c:
Fix Bug#38901 InnoDB logs error repeatedly when trying to load
page into buffer pool
2010-02-09 The InnoDB Team
* srv/srv0srv.c:
Let the master thread sleep if the amount of work to be done is
calibrated as taking less than a second.
2010-02-04 The InnoDB Team
* btr/btr0btr.c, btr/btr0cur.c, btr/btr0pcur.c, buf/buf0buf.c,
include/btr0btr.h, include/btr0cur.h, include/btr0pcur.h,
include/btr0pcur.ic, include/buf0buf.h, row/row0ins.c, row/row0sel.c:
Pass the file name and line number of the caller of the
b-tree cursor functions to the buffer pool requests, in order
to make the latch diagnostics more accurate.
2010-02-03 The InnoDB Team
* lock/lock0lock.c:
Fix Bug#49001 SHOW INNODB STATUS deadlock info incorrect
when deadlock detection aborts
2010-02-03 The InnoDB Team
* buf/buf0lru.c:
Fix Bug#35077 Very slow DROP TABLE (ALTER TABLE, OPTIMIZE TABLE)
on compressed tables
2010-02-03 The InnoDB Team
* handler/ha_innodb.cc, include/row0mysql.h, row/row0mysql.c:
Clean up CHECK TABLE error handling.
2010-02-01 The InnoDB Team
* handler/ha_innodb.cc, mysql-test/innodb-autoinc.test,
mysql-test/innodb-autoinc.result,
mysql-test/innodb-autoinc-44030.test,
mysql-test/innodb-autoinc-44030.result:
Fix Bug#49497 Error 1467 (ER_AUTOINC_READ_FAILED) on inserting
a negative value
2010-01-27 The InnoDB Team
* include/row0mysql.h, log/log0recv.c, row/row0mysql.c:
Drop temporary tables at startup.
This addresses the third aspect of
Bug#41609 Crash recovery does not work for InnoDB temporary tables.
2010-01-21 The InnoDB Team
* buf/buf0buf.c:
Do not merge buffered inserts to compressed pages before
the redo log has been applied in crash recovery.
2010-01-13 The InnoDB Team
* row/row0sel.c:
On the READ UNCOMMITTED isolation level, do not attempt to access
a clustered index record that has been marked for deletion. The
built-in InnoDB in MySQL 5.1 and earlier would attempt to retrieve
a previous version of the record in this case.
2010-01-13 The InnoDB Team
* buf/buf0buf.c:
When disabling the adaptive hash index, check the block state
before checking block->is_hashed, because the latter may be
uninitialized right after server startup.
2010-01-12 The InnoDB Team
* handler/ha_innodb.cc, handler/ha_innodb.h:
Fix Bug#46193 crash when accessing tables after enabling
innodb_force_recovery option
2010-01-12 The InnoDB Team
* row/row0mysql.c:
Fix Bug#49238 Creating/Dropping a temporary table while at 1023
transactions will cause assert.
2009-12-02 The InnoDB Team
* srv/srv0start.c:
Display the zlib version number at startup.
InnoDB compressed tables use zlib, and the implementation depends
on the zlib function compressBound(), whose definition was slightly
changed in zlib version 1.2.3.1 in 2006. MySQL bundles zlib 1.2.3
from 2005, but some installations use a more recent zlib.
2009-11-30 The InnoDB Team
* dict/dict0crea.c, dict/dict0mem.c, dict/dict0load.c,
dict/dict0boot.c, fil/fil0fil.c, handler/ha_innodb.cc,
include/dict0mem.h, row/row0mysql.c:
Fix the bogus warning messages for non-existing temporary
tables that were reported in
Bug#41609 Crash recovery does not work for InnoDB temporary tables.
The actual crash recovery bug was corrected on 2009-04-29.
2009-11-27 The InnoDB Team
InnoDB Plugin 1.0.6 released
2009-11-20 The InnoDB Team
* handler/ha_innodb.cc:
......@@ -79,8 +338,8 @@
sync/sync0arr.c, sync/sync0sync.c, thr/thr0loc.c, trx/trx0i_s.c,
trx/trx0purge.c, trx/trx0rseg.c, trx/trx0sys.c, trx/trx0undo.c,
usr/usr0sess.c, ut/ut0mem.c:
Fix Bug #45992 innodb memory not freed after shutdown
Fix Bug #46656 InnoDB plugin: memory leaks (Valgrind)
Fix Bug#45992 innodb memory not freed after shutdown
Fix Bug#46656 InnoDB plugin: memory leaks (Valgrind)
2009-10-29 The InnoDB Team
......@@ -422,7 +681,7 @@
* dict/dict0dict.c:
When an index column cannot be found in the table during index
creation, display additional diagnostic before an assertion failure.
This does NOT fix Bug #44571 InnoDB Plugin crashes on ADD INDEX,
This does NOT fix Bug#44571 InnoDB Plugin crashes on ADD INDEX,
but it helps understand the reason of the crash.
2009-06-17 The InnoDB Team
......@@ -535,6 +794,12 @@
Fix Bug#44320 InnoDB: missing DB_ROLL_PTR in Table Monitor COLUMNS
output
2009-04-29 The InnoDB Team
* fil/fil0fil.c, include/fil0fil.h, include/mtr0mtr.h,
log/log0recv.c:
Fix Bug#41609 Crash recovery does not work for InnoDB temporary tables
2009-04-23 The InnoDB Team
* row/row0mysql.c:
......
......@@ -217,6 +217,7 @@ noinst_HEADERS= \
include/ut0lst.h \
include/ut0mem.h \
include/ut0mem.ic \
include/ut0rbt.h \
include/ut0rnd.h \
include/ut0rnd.ic \
include/ut0sort.h \
......@@ -229,7 +230,7 @@ noinst_HEADERS= \
mem/mem0dbg.c
EXTRA_LIBRARIES= libinnobase.a
noinst_LIBRARIES= @plugin_innobase_static_target@
noinst_LIBRARIES= @plugin_innodb_plugin_static_target@
libinnobase_a_SOURCES= \
btr/btr0btr.c \
btr/btr0cur.c \
......@@ -319,6 +320,7 @@ libinnobase_a_SOURCES= \
ut/ut0dbg.c \
ut/ut0list.c \
ut/ut0mem.c \
ut/ut0rbt.c \
ut/ut0rnd.c \
ut/ut0ut.c \
ut/ut0vec.c \
......@@ -327,13 +329,13 @@ libinnobase_a_SOURCES= \
libinnobase_a_CXXFLAGS= $(AM_CFLAGS)
libinnobase_a_CFLAGS= $(AM_CFLAGS)
EXTRA_LTLIBRARIES= ha_innodb.la
pkgplugin_LTLIBRARIES= @plugin_innobase_shared_target@
EXTRA_LTLIBRARIES= ha_innodb_plugin.la
pkgplugin_LTLIBRARIES= @plugin_innodb_plugin_shared_target@
ha_innodb_la_LDFLAGS= -module -rpath $(pkgplugindir)
ha_innodb_la_CXXFLAGS= $(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS)
ha_innodb_la_CFLAGS= $(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS)
ha_innodb_la_SOURCES= $(libinnobase_a_SOURCES)
ha_innodb_plugin_la_LDFLAGS= -module -rpath $(pkgplugindir)
ha_innodb_plugin_la_CXXFLAGS= $(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS)
ha_innodb_plugin_la_CFLAGS= $(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS)
ha_innodb_plugin_la_SOURCES= $(libinnobase_a_SOURCES)
EXTRA_DIST= CMakeLists.txt plug.in \
pars/make_bison.sh pars/make_flex.sh \
......
This source diff could not be displayed because it is too large. You can view the blob instead.
/*****************************************************************************
Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
Copyright (c) 1994, 2010, Innobase Oy. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
......@@ -604,13 +604,15 @@ an x-latch on the tree.
@return rec_get_offsets() of the node pointer record */
static
ulint*
btr_page_get_father_node_ptr(
/*=========================*/
btr_page_get_father_node_ptr_func(
/*==============================*/
ulint* offsets,/*!< in: work area for the return value */
mem_heap_t* heap, /*!< in: memory heap to use */
btr_cur_t* cursor, /*!< in: cursor pointing to user record,
out: cursor on node pointer record,
its page x-latched */
const char* file, /*!< in: file name */
ulint line, /*!< in: line where called */
mtr_t* mtr) /*!< in: mtr */
{
dtuple_t* tuple;
......@@ -634,7 +636,8 @@ btr_page_get_father_node_ptr(
tuple = dict_index_build_node_ptr(index, user_rec, 0, heap, level);
btr_cur_search_to_nth_level(index, level + 1, tuple, PAGE_CUR_LE,
BTR_CONT_MODIFY_TREE, cursor, 0, mtr);
BTR_CONT_MODIFY_TREE, cursor, 0,
file, line, mtr);
node_ptr = btr_cur_get_rec(cursor);
ut_ad(!page_rec_is_comp(node_ptr)
......@@ -682,6 +685,9 @@ btr_page_get_father_node_ptr(
return(offsets);
}
#define btr_page_get_father_node_ptr(of,heap,cur,mtr) \
btr_page_get_father_node_ptr_func(of,heap,cur,__FILE__,__LINE__,mtr)
/************************************************************//**
Returns the upper level node pointer to a page. It is assumed that mtr holds
an x-latch on the tree.
......@@ -1475,11 +1481,11 @@ Calculates a split record such that the tuple will certainly fit on
its half-page when the split is performed. We assume in this function
only that the cursor page has at least one user record.
@return split record, or NULL if tuple will be the first record on
upper half-page */
the lower or upper half-page (determined by btr_page_tuple_smaller()) */
static
rec_t*
btr_page_get_sure_split_rec(
/*========================*/
btr_page_get_split_rec(
/*===================*/
btr_cur_t* cursor, /*!< in: cursor at which insert should be made */
const dtuple_t* tuple, /*!< in: tuple to insert */
ulint n_ext) /*!< in: number of externally stored columns */
......@@ -1692,11 +1698,13 @@ Inserts a data tuple to a tree on a non-leaf level. It is assumed
that mtr holds an x-latch on the tree. */
UNIV_INTERN
void
btr_insert_on_non_leaf_level(
/*=========================*/
btr_insert_on_non_leaf_level_func(
/*==============================*/
dict_index_t* index, /*!< in: index */
ulint level, /*!< in: level, must be > 0 */
dtuple_t* tuple, /*!< in: the record to be inserted */
const char* file, /*!< in: file name */
ulint line, /*!< in: line where called */
mtr_t* mtr) /*!< in: mtr */
{
big_rec_t* dummy_big_rec;
......@@ -1708,7 +1716,7 @@ btr_insert_on_non_leaf_level(
btr_cur_search_to_nth_level(index, level, tuple, PAGE_CUR_LE,
BTR_CONT_MODIFY_TREE,
&cursor, 0, mtr);
&cursor, 0, file, line, mtr);
err = btr_cur_pessimistic_insert(BTR_NO_LOCKING_FLAG
| BTR_KEEP_SYS_FLAG
......@@ -1853,6 +1861,37 @@ btr_attach_half_pages(
btr_page_set_next(upper_page, upper_page_zip, next_page_no, mtr);
}
/*************************************************************//**
Determine if a tuple is smaller than any record on the page.
@return TRUE if smaller */
static
ibool
btr_page_tuple_smaller(
/*===================*/
btr_cur_t* cursor, /*!< in: b-tree cursor */
const dtuple_t* tuple, /*!< in: tuple to consider */
ulint* offsets,/*!< in/out: temporary storage */
ulint n_uniq, /*!< in: number of unique fields
in the index page records */
mem_heap_t** heap) /*!< in/out: heap for offsets */
{
buf_block_t* block;
const rec_t* first_rec;
page_cur_t pcur;
/* Read the first user record in the page. */
block = btr_cur_get_block(cursor);
page_cur_set_before_first(block, &pcur);
page_cur_move_to_next(&pcur);
first_rec = page_cur_get_rec(&pcur);
offsets = rec_get_offsets(
first_rec, cursor->index, offsets,
n_uniq, heap);
return(cmp_dtuple_rec(tuple, first_rec, offsets) < 0);
}
/*************************************************************//**
Splits an index page to halves and inserts the tuple. It is assumed
that mtr holds an x-latch to the index tree. NOTE: the tree x-latch is
......@@ -1923,12 +1962,17 @@ func_start:
/* 1. Decide the split record; split_rec == NULL means that the
tuple to be inserted should be the first record on the upper
half-page */
insert_left = FALSE;
if (n_iterations > 0) {
direction = FSP_UP;
hint_page_no = page_no + 1;
split_rec = btr_page_get_sure_split_rec(cursor, tuple, n_ext);
split_rec = btr_page_get_split_rec(cursor, tuple, n_ext);
if (UNIV_UNLIKELY(split_rec == NULL)) {
insert_left = btr_page_tuple_smaller(
cursor, tuple, offsets, n_uniq, &heap);
}
} else if (btr_page_get_split_rec_to_right(cursor, &split_rec)) {
direction = FSP_UP;
hint_page_no = page_no + 1;
......@@ -1936,37 +1980,24 @@ func_start:
} else if (btr_page_get_split_rec_to_left(cursor, &split_rec)) {
direction = FSP_DOWN;
hint_page_no = page_no - 1;
ut_ad(split_rec);
} else {
direction = FSP_UP;
hint_page_no = page_no + 1;
if (page_get_n_recs(page) == 1) {
page_cur_t pcur;
/* There is only one record in the index page
therefore we can't split the node in the middle
by default. We need to determine whether the
new record will be inserted to the left or right. */
/* Read the first (and only) record in the page. */
page_cur_set_before_first(block, &pcur);
page_cur_move_to_next(&pcur);
first_rec = page_cur_get_rec(&pcur);
/* If there is only one record in the index page, we
can't split the node in the middle by default. We need
to determine whether the new record will be inserted
to the left or right. */
offsets = rec_get_offsets(
first_rec, cursor->index, offsets,
n_uniq, &heap);
/* If the new record is less than the existing record
the split in the middle will copy the existing
record to the new node. */
if (cmp_dtuple_rec(tuple, first_rec, offsets) < 0) {
split_rec = page_get_middle_rec(page);
} else {
split_rec = NULL;
}
} else {
if (page_get_n_recs(page) > 1) {
split_rec = page_get_middle_rec(page);
} else if (btr_page_tuple_smaller(cursor, tuple,
offsets, n_uniq, &heap)) {
split_rec = page_rec_get_next(
page_get_infimum_rec(page));
} else {
split_rec = NULL;
}
}
......@@ -1996,11 +2027,15 @@ func_start:
avoid further splits by inserting the record
to an empty page. */
split_rec = NULL;
goto insert_right;
goto insert_empty;
}
} else if (UNIV_UNLIKELY(insert_left)) {
first_rec = page_rec_get_next(page_get_infimum_rec(page));
move_limit = page_rec_get_next(btr_cur_get_rec(cursor));
} else {
insert_right:
insert_left = FALSE;
insert_empty:
ut_ad(!split_rec);
ut_ad(!insert_left);
buf = mem_alloc(rec_get_converted_size(cursor->index,
tuple, n_ext));
......@@ -2024,7 +2059,11 @@ insert_right:
&& btr_page_insert_fits(cursor, split_rec,
offsets, tuple, n_ext, heap);
} else {
mem_free(buf);
if (!insert_left) {
mem_free(buf);
buf = NULL;
}
insert_will_fit = !new_page_zip
&& btr_page_insert_fits(cursor, NULL,
NULL, tuple, n_ext, heap);
......@@ -2037,7 +2076,17 @@ insert_right:
}
/* 5. Move then the records to the new page */
if (direction == FSP_DOWN) {
if (direction == FSP_DOWN
#ifdef UNIV_BTR_AVOID_COPY
&& page_rec_is_supremum(move_limit)) {
/* Instead of moving all records, make the new page
the empty page. */
left_block = block;
right_block = new_block;
} else if (direction == FSP_DOWN
#endif /* UNIV_BTR_AVOID_COPY */
) {
/* fputs("Split left\n", stderr); */
if (0
......@@ -2080,6 +2129,14 @@ insert_right:
right_block = block;
lock_update_split_left(right_block, left_block);
#ifdef UNIV_BTR_AVOID_COPY
} else if (!split_rec) {
/* Instead of moving all records, make the new page
the empty page. */
left_block = new_block;
right_block = block;
#endif /* UNIV_BTR_AVOID_COPY */
} else {
/* fputs("Split right\n", stderr); */
......
/*****************************************************************************
Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
Copyright (c) 1994, 2010, Innobase Oy. All Rights Reserved.
Copyright (c) 2008, Google Inc.
Portions of this file contain modifications contributed and copyrighted by
......@@ -372,6 +372,8 @@ btr_cur_search_to_nth_level(
ulint has_search_latch,/*!< in: info on the latch mode the
caller currently has on btr_search_latch:
RW_S_LATCH, or 0 */
const char* file, /*!< in: file name */
ulint line, /*!< in: line where called */
mtr_t* mtr) /*!< in: mtr */
{
page_cur_t* page_cursor;
......@@ -550,7 +552,7 @@ btr_cur_search_to_nth_level(
retry_page_get:
block = buf_page_get_gen(space, zip_size, page_no,
rw_latch, guess, buf_mode,
__FILE__, __LINE__, mtr);
file, line, mtr);
if (block == NULL) {
if (srv_pass_corrupt_table && buf_mode != BUF_GET_IF_IN_POOL) {
page_cursor->block = 0;
......@@ -727,13 +729,15 @@ func_exit:
Opens a cursor at either end of an index. */
UNIV_INTERN
void
btr_cur_open_at_index_side(
/*=======================*/
btr_cur_open_at_index_side_func(
/*============================*/
ibool from_left, /*!< in: TRUE if open to the low end,
FALSE if to the high end */
dict_index_t* index, /*!< in: index */
ulint latch_mode, /*!< in: latch mode */
btr_cur_t* cursor, /*!< in: cursor */
const char* file, /*!< in: file name */
ulint line, /*!< in: line where called */
mtr_t* mtr) /*!< in: mtr */
{
page_cur_t* page_cursor;
......@@ -778,7 +782,7 @@ btr_cur_open_at_index_side(
page_t* page;
block = buf_page_get_gen(space, zip_size, page_no,
RW_NO_LATCH, NULL, BUF_GET,
__FILE__, __LINE__, mtr);
file, line, mtr);
page = buf_block_get_frame(block);
if (srv_pass_corrupt_table && !page) {
......@@ -869,11 +873,13 @@ btr_cur_open_at_index_side(
Positions a cursor at a randomly chosen position within a B-tree. */
UNIV_INTERN
void
btr_cur_open_at_rnd_pos(
/*====================*/
btr_cur_open_at_rnd_pos_func(
/*=========================*/
dict_index_t* index, /*!< in: index */
ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
btr_cur_t* cursor, /*!< in/out: B-tree cursor */
const char* file, /*!< in: file name */
ulint line, /*!< in: line where called */
mtr_t* mtr) /*!< in: mtr */
{
page_cur_t* page_cursor;
......@@ -908,7 +914,7 @@ btr_cur_open_at_rnd_pos(
block = buf_page_get_gen(space, zip_size, page_no,
RW_NO_LATCH, NULL, BUF_GET,
__FILE__, __LINE__, mtr);
file, line, mtr);
page = buf_block_get_frame(block);
if (srv_pass_corrupt_table && !page) {
......@@ -1229,7 +1235,6 @@ btr_cur_optimistic_insert(
ibool inherit;
ulint zip_size;
ulint rec_size;
mem_heap_t* heap = NULL;
ulint err;
*big_rec = NULL;
......@@ -1315,10 +1320,6 @@ btr_cur_optimistic_insert(
index, entry, big_rec_vec);
}
if (heap) {
mem_heap_free(heap);
}
return(DB_TOO_BIG_RECORD);
}
}
......@@ -1341,15 +1342,11 @@ fail_err:
dtuple_convert_back_big_rec(index, entry, big_rec_vec);
}
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return(err);
}
if (UNIV_UNLIKELY(max_size < BTR_CUR_PAGE_REORGANIZE_LIMIT
|| max_size < rec_size)
|| max_size < rec_size)
&& UNIV_LIKELY(page_get_n_recs(page) > 1)
&& page_get_max_insert_size(page, 1) < rec_size) {
......@@ -1415,10 +1412,6 @@ fail_err:
}
}
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
#ifdef BTR_CUR_HASH_ADAPT
if (!reorg && leaf && (cursor->flag == BTR_CUR_HASH)) {
btr_search_update_hash_node_on_insert(cursor);
......@@ -3282,7 +3275,8 @@ btr_estimate_n_rows_in_range(
btr_cur_search_to_nth_level(index, 0, tuple1, mode1,
BTR_SEARCH_LEAF | BTR_ESTIMATE,
&cursor, 0, &mtr);
&cursor, 0,
__FILE__, __LINE__, &mtr);
} else {
btr_cur_open_at_index_side(TRUE, index,
BTR_SEARCH_LEAF | BTR_ESTIMATE,
......@@ -3299,7 +3293,8 @@ btr_estimate_n_rows_in_range(
btr_cur_search_to_nth_level(index, 0, tuple2, mode2,
BTR_SEARCH_LEAF | BTR_ESTIMATE,
&cursor, 0, &mtr);
&cursor, 0,
__FILE__, __LINE__, &mtr);
} else {
btr_cur_open_at_index_side(FALSE, index,
BTR_SEARCH_LEAF | BTR_ESTIMATE,
......@@ -3438,7 +3433,7 @@ btr_estimate_n_pages_not_null(
btr_cur_search_to_nth_level(index, 0, tuple1, PAGE_CUR_G,
BTR_SEARCH_LEAF | BTR_ESTIMATE,
&cursor, 0, &mtr);
&cursor, 0, __FILE__, __LINE__, &mtr);
mtr_commit(&mtr);
......@@ -3588,9 +3583,11 @@ btr_estimate_number_of_different_key_vals(
effective_pages = btr_estimate_n_pages_not_null(index, 1 /*k*/, first_rec_path);
if (!effective_pages) {
dict_index_stat_mutex_enter(index);
for (j = 0; j <= n_cols; j++) {
index->stat_n_diff_key_vals[j] = (ib_int64_t)index->stat_n_leaf_pages;
}
dict_index_stat_mutex_exit(index);
return;
} else if (effective_pages > index->stat_n_leaf_pages) {
effective_pages = index->stat_n_leaf_pages;
......@@ -3732,6 +3729,8 @@ btr_estimate_number_of_different_key_vals(
also the pages used for external storage of fields (those pages are
included in index->stat_n_leaf_pages) */
dict_index_stat_mutex_enter(index);
for (j = 0; j <= n_cols; j++) {
index->stat_n_diff_key_vals[j]
= ((n_diff[j]
......@@ -3770,8 +3769,9 @@ btr_estimate_number_of_different_key_vals(
}
}
mem_free(n_diff);
dict_index_stat_mutex_exit(index);
mem_free(n_diff);
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
......@@ -4639,7 +4639,7 @@ btr_free_externally_stored_field(
/* In the rollback of uncommitted transactions, we may
encounter a clustered index record whose BLOBs have
not been written. There is nothing to free then. */
ut_a(rb_ctx == RB_RECOVERY);
ut_a(rb_ctx == RB_RECOVERY || rb_ctx == RB_RECOVERY_PURGE_REC);
return;
}
......@@ -4685,7 +4685,7 @@ btr_free_externally_stored_field(
|| (mach_read_from_1(field_ref + BTR_EXTERN_LEN)
& BTR_EXTERN_OWNER_FLAG)
/* Rollback and inherited field */
|| (rb_ctx != RB_NONE
|| ((rb_ctx == RB_NORMAL || rb_ctx == RB_RECOVERY)
&& (mach_read_from_1(field_ref + BTR_EXTERN_LEN)
& BTR_EXTERN_INHERITED_FLAG))) {
......
/*****************************************************************************
Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
......@@ -211,10 +211,12 @@ record and it can be restored on a user record whose ordering fields
are identical to the ones of the original user record */
UNIV_INTERN
ibool
btr_pcur_restore_position(
/*======================*/
btr_pcur_restore_position_func(
/*===========================*/
ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
btr_pcur_t* cursor, /*!< in: detached persistent cursor */
const char* file, /*!< in: file name */
ulint line, /*!< in: line where called */
mtr_t* mtr) /*!< in: mtr */
{
dict_index_t* index;
......@@ -223,6 +225,9 @@ btr_pcur_restore_position(
ulint old_mode;
mem_heap_t* heap;
ut_ad(mtr);
ut_ad(mtr->state == MTR_ACTIVE);
index = btr_cur_get_index(btr_pcur_get_btr_cur(cursor));
if (UNIV_UNLIKELY(cursor->old_stored != BTR_PCUR_OLD_STORED)
......@@ -263,7 +268,8 @@ btr_pcur_restore_position(
if (UNIV_LIKELY(buf_page_optimistic_get(
latch_mode,
cursor->block_when_stored,
cursor->modify_clock, mtr))) {
cursor->modify_clock,
file, line, mtr))) {
cursor->pos_state = BTR_PCUR_IS_POSITIONED;
buf_block_dbg_add_level(btr_pcur_get_block(cursor),
......@@ -318,8 +324,8 @@ btr_pcur_restore_position(
mode = PAGE_CUR_L;
}
btr_pcur_open_with_no_init(index, tuple, mode, latch_mode,
cursor, 0, mtr);
btr_pcur_open_with_no_init_func(index, tuple, mode, latch_mode,
cursor, 0, file, line, mtr);
/* Restore the old search mode */
cursor->search_mode = old_mode;
......@@ -568,8 +574,8 @@ before first in tree. The latching mode must be BTR_SEARCH_LEAF or
BTR_MODIFY_LEAF. */
UNIV_INTERN
void
btr_pcur_open_on_user_rec(
/*======================*/
btr_pcur_open_on_user_rec_func(
/*===========================*/
dict_index_t* index, /*!< in: index */
const dtuple_t* tuple, /*!< in: tuple on which search done */
ulint mode, /*!< in: PAGE_CUR_L, ... */
......@@ -577,9 +583,12 @@ btr_pcur_open_on_user_rec(
BTR_MODIFY_LEAF */
btr_pcur_t* cursor, /*!< in: memory buffer for persistent
cursor */
const char* file, /*!< in: file name */
ulint line, /*!< in: line where called */
mtr_t* mtr) /*!< in: mtr */
{
btr_pcur_open(index, tuple, mode, latch_mode, cursor, mtr);
btr_pcur_open_func(index, tuple, mode, latch_mode, cursor,
file, line, mtr);
if ((mode == PAGE_CUR_GE) || (mode == PAGE_CUR_G)) {
......
/*****************************************************************************
Copyright (c) 2006, 2009, Innobase Oy. All Rights Reserved.
Copyright (c) 2006, 2010, Innobase Oy. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
......@@ -430,6 +430,8 @@ buf_buddy_relocate_block(
}
mutex_exit(&flush_list_mutex);
UNIV_MEM_INVALID(bpage, sizeof *bpage);
mutex_exit(&buf_pool_zip_mutex);
mutex_exit(&zip_free_mutex);
return(TRUE);
......
/*****************************************************************************
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
Copyright (c) 2008, Google Inc.
Portions of this file contain modifications contributed and copyrighted by
......@@ -277,6 +277,8 @@ the read requests for the whole area.
#ifndef UNIV_HOTBACKUP
/** Value in microseconds */
static const int WAIT_FOR_READ = 5000;
/** Number of attemtps made to read in a page in the buffer pool */
static const ulint BUF_PAGE_READ_MAX_RETRIES = 100;
/** The buffer buf_pool of the database */
UNIV_INTERN buf_pool_t* buf_pool = NULL;
......@@ -1150,7 +1152,9 @@ buf_pool_drop_hash_index(void)
when we have an x-latch on btr_search_latch;
see the comment in buf0buf.h */
if (!block->is_hashed) {
if (buf_block_get_state(block)
!= BUF_BLOCK_FILE_PAGE
|| !block->is_hashed) {
continue;
}
......@@ -1283,8 +1287,6 @@ buf_relocate(
HASH_DELETE(buf_page_t, hash, buf_pool->page_hash, fold, bpage);
HASH_INSERT(buf_page_t, hash, buf_pool->page_hash, fold, dpage);
UNIV_MEM_INVALID(bpage, sizeof *bpage);
}
/********************************************************************//**
......@@ -1980,14 +1982,14 @@ buf_zip_decompress(
buf_block_t* block, /*!< in/out: block */
ibool check) /*!< in: TRUE=verify the page checksum */
{
const byte* frame = block->page.zip.data;
const byte* frame = block->page.zip.data;
ulint stamp_checksum = mach_read_from_4(
frame + FIL_PAGE_SPACE_OR_CHKSUM);
ut_ad(buf_block_get_zip_size(block));
ut_a(buf_block_get_space(block) != 0);
if (UNIV_LIKELY(check)) {
ulint stamp_checksum = mach_read_from_4(
frame + FIL_PAGE_SPACE_OR_CHKSUM);
if (UNIV_LIKELY(check && stamp_checksum != BUF_NO_CHECKSUM_MAGIC)) {
ulint calc_checksum = page_zip_calc_checksum(
frame, page_zip_get_size(&block->page.zip));
......@@ -2196,6 +2198,7 @@ buf_page_get_gen(
unsigned access_time;
ulint fix_type;
ibool must_read;
ulint retries = 0;
mutex_t* block_mutex;
trx_t* trx = NULL;
ulint sec;
......@@ -2204,6 +2207,7 @@ buf_page_get_gen(
ib_uint64_t finish_time;
ut_ad(mtr);
ut_ad(mtr->state == MTR_ACTIVE);
ut_ad((rw_latch == RW_S_LATCH)
|| (rw_latch == RW_X_LATCH)
|| (rw_latch == RW_NO_LATCH));
......@@ -2271,7 +2275,29 @@ loop2:
return(NULL);
}
buf_read_page(space, zip_size, offset, trx);
if (buf_read_page(space, zip_size, offset, trx)) {
retries = 0;
} else if (retries < BUF_PAGE_READ_MAX_RETRIES) {
++retries;
} else {
fprintf(stderr, "InnoDB: Error: Unable"
" to read tablespace %lu page no"
" %lu into the buffer pool after"
" %lu attempts\n"
"InnoDB: The most probable cause"
" of this error may be that the"
" table has been corrupted.\n"
"InnoDB: You can try to fix this"
" problem by using"
" innodb_force_recovery.\n"
"InnoDB: Please see reference manual"
" for more details.\n"
"InnoDB: Aborting...\n",
space, offset,
BUF_PAGE_READ_MAX_RETRIES);
ut_error;
}
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
ut_a(++buf_dbg_counter % 37 || buf_validate());
......@@ -2414,22 +2440,8 @@ wait_until_unfixed:
ut_ad(!block->page.in_flush_list);
} else {
/* Relocate buf_pool->flush_list. */
buf_page_t* b;
b = UT_LIST_GET_PREV(flush_list, &block->page);
ut_ad(block->page.in_flush_list);
UT_LIST_REMOVE(flush_list, buf_pool->flush_list,
&block->page);
if (b) {
UT_LIST_INSERT_AFTER(
flush_list, buf_pool->flush_list, b,
&block->page);
} else {
UT_LIST_ADD_FIRST(
flush_list, buf_pool->flush_list,
&block->page);
}
buf_flush_relocate_on_flush_list(bpage,
&block->page);
}
mutex_exit(&flush_list_mutex);
......@@ -2447,6 +2459,9 @@ wait_until_unfixed:
block->page.buf_fix_count = 1;
buf_block_set_io_fix(block, BUF_IO_READ);
rw_lock_x_lock(&block->lock);
UNIV_MEM_INVALID(bpage, sizeof *bpage);
mutex_exit(block_mutex);
mutex_exit(&buf_pool_zip_mutex);
......@@ -2461,8 +2476,9 @@ wait_until_unfixed:
/* Decompress the page and apply buffered operations
while not holding buf_pool_mutex or block->mutex. */
success = buf_zip_decompress(block, srv_use_checksums);
ut_a(success);
if (UNIV_LIKELY(success)) {
if (UNIV_LIKELY(!recv_no_ibuf_operations)) {
ibuf_merge_or_delete_for_page(block, space, offset,
zip_size, TRUE);
}
......@@ -2478,14 +2494,6 @@ wait_until_unfixed:
buf_pool->n_pend_unzip--;
mutex_exit(&buf_pool_mutex);
rw_lock_x_unlock(&block->lock);
if (UNIV_UNLIKELY(!success)) {
//buf_pool_mutex_exit();
mutex_exit(block_mutex);
return(NULL);
}
break;
case BUF_BLOCK_ZIP_FREE:
......@@ -2603,8 +2611,8 @@ page.
@return TRUE if success */
UNIV_INTERN
ibool
buf_page_optimistic_get_func(
/*=========================*/
buf_page_optimistic_get(
/*====================*/
ulint rw_latch,/*!< in: RW_S_LATCH, RW_X_LATCH */
buf_block_t* block, /*!< in: guessed buffer block */
ib_uint64_t modify_clock,/*!< in: modify clock value if mode is
......@@ -2618,7 +2626,9 @@ buf_page_optimistic_get_func(
ulint fix_type;
trx_t* trx = NULL;
ut_ad(mtr && block);
ut_ad(block);
ut_ad(mtr);
ut_ad(mtr->state == MTR_ACTIVE);
ut_ad((rw_latch == RW_S_LATCH) || (rw_latch == RW_X_LATCH));
mutex_enter(&block->mutex);
......@@ -2738,6 +2748,7 @@ buf_page_get_known_nowait(
trx_t* trx = NULL;
ut_ad(mtr);
ut_ad(mtr->state == MTR_ACTIVE);
ut_ad((rw_latch == RW_S_LATCH) || (rw_latch == RW_X_LATCH));
mutex_enter(&block->mutex);
......@@ -2846,6 +2857,9 @@ buf_page_try_get_func(
ibool success;
ulint fix_type;
ut_ad(mtr);
ut_ad(mtr->state == MTR_ACTIVE);
//buf_pool_mutex_enter();
rw_lock_s_lock(&page_hash_latch);
block = buf_block_hash_get(space_id, page_no);
......@@ -3249,6 +3263,7 @@ buf_page_create(
ulint time_ms = ut_time_ms();
ut_ad(mtr);
ut_ad(mtr->state == MTR_ACTIVE);
ut_ad(space || !zip_size);
free_block = buf_LRU_get_free_block(0);
......@@ -3431,7 +3446,8 @@ buf_page_io_complete(
read_space_id = mach_read_from_4(
frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
if (bpage->space == TRX_SYS_SPACE
if ((bpage->space == TRX_SYS_SPACE
|| (srv_doublewrite_file && bpage->space == TRX_DOUBLEWRITE_SPACE))
&& trx_doublewrite_page_inside(bpage->offset)) {
ut_print_timestamp(stderr);
......@@ -3503,7 +3519,7 @@ corrupt:
REFMAN "forcing-recovery.html\n"
"InnoDB: about forcing recovery.\n", stderr);
if (srv_pass_corrupt_table && bpage->space > 0
if (srv_pass_corrupt_table && !trx_sys_sys_space(bpage->space)
&& bpage->space < SRV_LOG_SPACE_FIRST_ID) {
fprintf(stderr,
"InnoDB: space %lu will be treated as corrupt.\n",
......
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
the terms of the GNU General Public License as published by the Free Software
......@@ -371,21 +371,39 @@ scan_again:
bpage = UT_LIST_GET_LAST(buf_pool->LRU);
while (bpage != NULL) {
mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
buf_page_t* prev_bpage;
ibool prev_bpage_buf_fix = FALSE;
ut_a(buf_page_in_file(bpage));
prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
if (!block_mutex) {
bpage = prev_bpage;
continue;
}
/* bpage->space and bpage->io_fix are protected by
buf_pool_mutex and block_mutex. It is safe to check
them while holding buf_pool_mutex only. */
if (buf_page_get_space(bpage) != id) {
/* Skip this block, as it does not belong to
the space that is being invalidated. */
} else if (buf_page_get_io_fix(bpage) != BUF_IO_NONE) {
/* We cannot remove this page during this scan
yet; maybe the system is currently reading it
in, or flushing the modifications to the file */
all_freed = FALSE;
} else {
mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
if (!block_mutex) {
/* It may be impossible case...
Something wrong, so will be scan_again */
all_freed = FALSE;
goto next_page_no_mutex;
}
if (buf_page_get_space(bpage) == id) {
if (bpage->buf_fix_count > 0
|| buf_page_get_io_fix(bpage) != BUF_IO_NONE) {
if (bpage->buf_fix_count > 0) {
/* We cannot remove this page during
this scan yet; maybe the system is
......@@ -405,8 +423,40 @@ scan_again:
(ulong) buf_page_get_page_no(bpage));
}
#endif
if (buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE
&& ((buf_block_t*) bpage)->is_hashed) {
if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
/* This is a compressed-only block
descriptor. Ensure that prev_bpage
cannot be relocated when bpage is freed. */
if (UNIV_LIKELY(prev_bpage != NULL)) {
switch (buf_page_get_state(
prev_bpage)) {
case BUF_BLOCK_FILE_PAGE:
/* Descriptors of uncompressed
blocks will not be relocated,
because we are holding the
buf_pool_mutex. */
break;
case BUF_BLOCK_ZIP_PAGE:
case BUF_BLOCK_ZIP_DIRTY:
/* Descriptors of compressed-
only blocks can be relocated,
unless they are buffer-fixed.
Because both bpage and
prev_bpage are protected by
buf_pool_zip_mutex, it is
not necessary to acquire
further mutexes. */
ut_ad(&buf_pool_zip_mutex
== block_mutex);
ut_ad(mutex_own(block_mutex));
prev_bpage_buf_fix = TRUE;
prev_bpage->buf_fix_count++;
break;
default:
ut_error;
}
}
} else if (((buf_block_t*) bpage)->is_hashed) {
ulint page_no;
ulint zip_size;
......@@ -432,7 +482,8 @@ scan_again:
buf_flush_remove(bpage);
}
/* Remove from the LRU list */
/* Remove from the LRU list. */
if (buf_LRU_block_remove_hashed_page(bpage, TRUE)
!= BUF_BLOCK_ZIP_FREE) {
buf_LRU_block_free_hashed_page((buf_block_t*)
......@@ -444,18 +495,27 @@ scan_again:
ut_ad(block_mutex == &buf_pool_zip_mutex);
ut_ad(!mutex_own(block_mutex));
/* The compressed block descriptor
(bpage) has been deallocated and
block_mutex released. Also,
buf_buddy_free() may have relocated
prev_bpage. Rescan the LRU list. */
if (prev_bpage_buf_fix) {
/* We temporarily buffer-fixed
prev_bpage, so that
buf_buddy_free() could not
relocate it, in case it was a
compressed-only block
descriptor. */
mutex_enter(block_mutex);
ut_ad(prev_bpage->buf_fix_count > 0);
prev_bpage->buf_fix_count--;
mutex_exit(block_mutex);
}
bpage = UT_LIST_GET_LAST(buf_pool->LRU);
continue;
goto next_page_no_mutex;
}
}
next_page:
mutex_exit(block_mutex);
mutex_exit(block_mutex);
}
next_page_no_mutex:
bpage = prev_bpage;
}
......@@ -1600,26 +1660,8 @@ not_freed:
if (b->state == BUF_BLOCK_ZIP_PAGE) {
buf_LRU_insert_zip_clean(b);
} else {
buf_page_t* prev;
ut_ad(b->in_flush_list);
ut_d(bpage->in_flush_list = FALSE);
prev = UT_LIST_GET_PREV(flush_list, b);
UT_LIST_REMOVE(flush_list, buf_pool->flush_list, b);
if (prev) {
ut_ad(prev->in_flush_list);
UT_LIST_INSERT_AFTER(
flush_list,
buf_pool->flush_list,
prev, b);
} else {
UT_LIST_ADD_FIRST(
flush_list,
buf_pool->flush_list,
b);
}
/* Relocate on buf_pool->flush_list. */
buf_flush_relocate_on_flush_list(bpage, b);
}
mutex_exit(&flush_list_mutex);
......
/*****************************************************************************
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
......@@ -86,7 +86,9 @@ buf_read_page_low(
wake_later = mode & OS_AIO_SIMULATED_WAKE_LATER;
mode = mode & ~OS_AIO_SIMULATED_WAKE_LATER;
if (trx_doublewrite && space == TRX_SYS_SPACE
if (trx_doublewrite
&& (space == TRX_SYS_SPACE
|| (srv_doublewrite_file && space == TRX_DOUBLEWRITE_SPACE))
&& ( (offset >= trx_doublewrite->block1
&& offset < trx_doublewrite->block1
+ TRX_SYS_DOUBLEWRITE_BLOCK_SIZE)
......@@ -656,6 +658,50 @@ buf_read_recv_pages(
/* It is a single table tablespace and the .ibd file is
missing: do nothing */
/* the log records should be treated here same reason
for http://bugs.mysql.com/bug.php?id=43948 */
if (recv_recovery_is_on()) {
recv_addr_t* recv_addr;
mutex_enter(&(recv_sys->mutex));
if (recv_sys->apply_log_recs == FALSE) {
mutex_exit(&(recv_sys->mutex));
goto not_to_recover;
}
for (i = 0; i < n_stored; i++) {
/* recv_get_fil_addr_struct() */
recv_addr = HASH_GET_FIRST(recv_sys->addr_hash,
hash_calc_hash(ut_fold_ulint_pair(space, page_nos[i]),
recv_sys->addr_hash));
while (recv_addr) {
if ((recv_addr->space == space)
&& (recv_addr->page_no == page_nos[i])) {
break;
}
recv_addr = HASH_GET_NEXT(addr_hash, recv_addr);
}
if ((recv_addr == NULL)
|| (recv_addr->state == RECV_BEING_PROCESSED)
|| (recv_addr->state == RECV_PROCESSED)) {
continue;
}
recv_addr->state = RECV_PROCESSED;
ut_a(recv_sys->n_addrs);
recv_sys->n_addrs--;
}
mutex_exit(&(recv_sys->mutex));
fprintf(stderr, " (cannot find space: %lu)", space);
}
not_to_recover:
return;
}
......@@ -674,10 +720,10 @@ buf_read_recv_pages(
count++;
if (count > 5000) {
if (count > 1000) {
fprintf(stderr,
"InnoDB: Error: InnoDB has waited for"
" 50 seconds for pending\n"
" 10 seconds for pending\n"
"InnoDB: reads to the buffer pool to"
" be finished.\n"
"InnoDB: Number of pending reads %lu,"
......
......@@ -666,6 +666,21 @@ dtuple_convert_big_rec(
goto skip_field;
}
/* In DYNAMIC and COMPRESSED format, store
locally any non-BLOB columns whose maximum
length does not exceed 256 bytes. This is
because there is no room for the "external
storage" flag when the maximum length is 255
bytes or less. This restriction trivially
holds in REDUNDANT and COMPACT format, because
there we always store locally columns whose
length is up to local_len == 788 bytes.
@see rec_init_offsets_comp_ordinary */
if (ifield->col->mtype != DATA_BLOB
&& ifield->col->len < 256) {
goto skip_field;
}
longest_i = i;
longest = savings;
......
/*****************************************************************************
Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
......@@ -275,6 +275,9 @@ dict_boot(void)
and (TYPE & DICT_TF_FORMAT_MASK) are nonzero and TYPE = table->flags */
dict_mem_table_add_col(table, heap, "TYPE", DATA_INT, 0, 4);
dict_mem_table_add_col(table, heap, "MIX_ID", DATA_BINARY, 0, 0);
/* MIX_LEN may contain additional table flags when
ROW_FORMAT!=REDUNDANT. Currently, these flags include
DICT_TF2_TEMPORARY. */
dict_mem_table_add_col(table, heap, "MIX_LEN", DATA_INT, 0, 4);
dict_mem_table_add_col(table, heap, "CLUSTER_NAME", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, heap, "SPACE", DATA_INT, 0, 4);
......@@ -358,7 +361,7 @@ dict_boot(void)
dict_mem_table_add_col(table, heap, "SPACE", DATA_INT, 0, 4);
dict_mem_table_add_col(table, heap, "PAGE_NO", DATA_INT, 0, 4);
/* The '+ 2' below comes from the 2 system fields */
/* The '+ 2' below comes from the fields DB_TRX_ID, DB_ROLL_PTR */
#if DICT_SYS_INDEXES_PAGE_NO_FIELD != 6 + 2
#error "DICT_SYS_INDEXES_PAGE_NO_FIELD != 6 + 2"
#endif
......@@ -367,6 +370,9 @@ dict_boot(void)
#endif
#if DICT_SYS_INDEXES_TYPE_FIELD != 4 + 2
#error "DICT_SYS_INDEXES_TYPE_FIELD != 4 + 2"
#endif
#if DICT_SYS_INDEXES_NAME_FIELD != 2 + 2
#error "DICT_SYS_INDEXES_NAME_FIELD != 2 + 2"
#endif
table->id = DICT_INDEXES_ID;
......
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
the terms of the GNU General Public License as published by the Free Software
......@@ -81,6 +81,10 @@ UNIV_INTERN rw_lock_t dict_operation_lock;
/** Identifies generated InnoDB foreign key names */
static char dict_ibfk[] = "_ibfk_";
/** array of mutexes protecting dict_index_t::stat_n_diff_key_vals[] */
#define DICT_INDEX_STAT_MUTEX_SIZE 32
mutex_t dict_index_stat_mutex[DICT_INDEX_STAT_MUTEX_SIZE];
/*******************************************************************//**
Tries to find column names for the index and sets the col field of the
index.
......@@ -141,7 +145,7 @@ static
void
dict_field_print_low(
/*=================*/
dict_field_t* field); /*!< in: field */
const dict_field_t* field); /*!< in: field */
/*********************************************************************//**
Frees a foreign key struct. */
static
......@@ -240,6 +244,45 @@ dict_mutex_exit_for_mysql(void)
mutex_exit(&(dict_sys->mutex));
}
/** Get the mutex that protects index->stat_n_diff_key_vals[] */
#define GET_INDEX_STAT_MUTEX(index) \
(&dict_index_stat_mutex[ut_fold_dulint(index->id) \
% DICT_INDEX_STAT_MUTEX_SIZE])
/**********************************************************************//**
Lock the appropriate mutex to protect index->stat_n_diff_key_vals[].
index->id is used to pick the right mutex and it should not change
before dict_index_stat_mutex_exit() is called on this index. */
UNIV_INTERN
void
dict_index_stat_mutex_enter(
/*========================*/
const dict_index_t* index) /*!< in: index */
{
ut_ad(index != NULL);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
ut_ad(index->cached);
ut_ad(!index->to_be_dropped);
mutex_enter(GET_INDEX_STAT_MUTEX(index));
}
/**********************************************************************//**
Unlock the appropriate mutex that protects index->stat_n_diff_key_vals[]. */
UNIV_INTERN
void
dict_index_stat_mutex_exit(
/*=======================*/
const dict_index_t* index) /*!< in: index */
{
ut_ad(index != NULL);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
ut_ad(index->cached);
ut_ad(!index->to_be_dropped);
mutex_exit(GET_INDEX_STAT_MUTEX(index));
}
/********************************************************************//**
Decrements the count of open MySQL handles to a table. */
UNIV_INTERN
......@@ -608,6 +651,8 @@ void
dict_init(void)
/*===========*/
{
int i;
dict_sys = mem_alloc(sizeof(dict_sys_t));
mutex_create(&dict_sys->mutex, SYNC_DICT);
......@@ -628,6 +673,10 @@ dict_init(void)
ut_a(dict_foreign_err_file);
mutex_create(&dict_foreign_err_mutex, SYNC_ANY_LATCH);
for (i = 0; i < DICT_INDEX_STAT_MUTEX_SIZE; i++) {
mutex_create(&dict_index_stat_mutex[i], SYNC_INDEX_TREE);
}
}
/**********************************************************************//**
......@@ -1442,11 +1491,7 @@ dict_index_too_big_for_tree(
goto add_field_size;
}
if (srv_relax_table_creation) {
field_max_size = dict_col_get_min_size(col);
} else {
field_max_size = dict_col_get_max_size(col);
}
field_ext_max_size = field_max_size < 256 ? 1 : 2;
if (field->prefix_len) {
......@@ -1527,6 +1572,7 @@ dict_index_add_to_cache(
if (!dict_index_find_cols(table, index)) {
dict_mem_index_free(index);
return(DB_CORRUPTION);
}
......@@ -4247,9 +4293,13 @@ dict_update_statistics_low(
index = dict_table_get_first_index(table);
dict_index_stat_mutex_enter(index);
table->stat_n_rows = index->stat_n_diff_key_vals[
dict_index_get_n_unique(index)];
dict_index_stat_mutex_exit(index);
table->stat_clustered_index_size = index->stat_index_size;
table->stat_sum_of_other_index_sizes = sum_of_index_sizes
......@@ -4428,6 +4478,8 @@ dict_index_print_low(
ut_ad(mutex_own(&(dict_sys->mutex)));
dict_index_stat_mutex_enter(index);
if (index->n_user_defined_cols > 0) {
n_vals = index->stat_n_diff_key_vals[
index->n_user_defined_cols];
......@@ -4435,6 +4487,8 @@ dict_index_print_low(
n_vals = index->stat_n_diff_key_vals[1];
}
dict_index_stat_mutex_exit(index);
if (dict_index_is_clust(index)) {
type_string = "clustered index";
} else if (dict_index_is_unique(index)) {
......@@ -4480,7 +4534,7 @@ static
void
dict_field_print_low(
/*=================*/
dict_field_t* field) /*!< in: field */
const dict_field_t* field) /*!< in: field */
{
ut_ad(mutex_own(&(dict_sys->mutex)));
......@@ -4844,8 +4898,10 @@ UNIV_INTERN
void
dict_table_check_for_dup_indexes(
/*=============================*/
const dict_table_t* table) /*!< in: Check for dup indexes
const dict_table_t* table, /*!< in: Check for dup indexes
in this table */
ibool tmp_ok) /*!< in: TRUE=allow temporary
index names */
{
/* Check for duplicates, ignoring indexes that are marked
as to be dropped */
......@@ -4853,13 +4909,17 @@ dict_table_check_for_dup_indexes(
const dict_index_t* index1;
const dict_index_t* index2;
ut_ad(mutex_own(&dict_sys->mutex));
/* The primary index _must_ exist */
ut_a(UT_LIST_GET_LEN(table->indexes) > 0);
index1 = UT_LIST_GET_FIRST(table->indexes);
index2 = UT_LIST_GET_NEXT(indexes, index1);
while (index1 && index2) {
do {
ut_ad(tmp_ok || *index1->name != TEMP_INDEX_PREFIX);
index2 = UT_LIST_GET_NEXT(indexes, index1);
while (index2) {
......@@ -4871,8 +4931,7 @@ dict_table_check_for_dup_indexes(
}
index1 = UT_LIST_GET_NEXT(indexes, index1);
index2 = UT_LIST_GET_NEXT(indexes, index1);
}
} while (index1);
}
#endif /* UNIV_DEBUG */
......@@ -4925,6 +4984,10 @@ dict_close(void)
mem_free(dict_sys);
dict_sys = NULL;
for (i = 0; i < DICT_INDEX_STAT_MUTEX_SIZE; i++) {
mutex_free(&dict_index_stat_mutex[i]);
}
}
/*************************************************************************
......@@ -4939,7 +5002,7 @@ dict_table_set_corrupt_by_space(
dict_table_t* table;
ibool found = FALSE;
ut_a(space_id != 0 && space_id < SRV_LOG_SPACE_FIRST_ID);
ut_a(!trx_sys_sys_space(space_id) && space_id < SRV_LOG_SPACE_FIRST_ID);
if (need_mutex)
mutex_enter(&(dict_sys->mutex));
......
/*****************************************************************************
Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
......@@ -260,7 +260,7 @@ dict_sys_tables_get_flags(
return(0);
}
field = rec_get_nth_field_old(rec, 4, &len);
field = rec_get_nth_field_old(rec, 4/*N_COLS*/, &len);
n_cols = mach_read_from_4(field);
if (UNIV_UNLIKELY(!(n_cols & 0x80000000UL))) {
......@@ -390,15 +390,35 @@ loop:
mtr_commit(&mtr);
if (space_id != 0 && in_crash_recovery) {
if (trx_sys_sys_space(space_id)) {
/* The system tablespace always exists. */
} else if (in_crash_recovery) {
/* Check that the tablespace (the .ibd file) really
exists; print a warning to the .err log if not */
fil_space_for_table_exists_in_mem(space_id, name,
FALSE, TRUE, TRUE);
}
exists; print a warning to the .err log if not.
Do not print warnings for temporary tables. */
ibool is_temp;
field = rec_get_nth_field_old(rec, 4, &len);
if (0x80000000UL & mach_read_from_4(field)) {
/* ROW_FORMAT=COMPACT: read the is_temp
flag from SYS_TABLES.MIX_LEN. */
field = rec_get_nth_field_old(rec, 7, &len);
is_temp = mach_read_from_4(field)
& DICT_TF2_TEMPORARY;
} else {
/* For tables created with old versions
of InnoDB, SYS_TABLES.MIX_LEN may contain
garbage. Such tables would always be
in ROW_FORMAT=REDUNDANT. Pretend that
all such tables are non-temporary. That is,
do not suppress error printouts about
temporary tables not being found. */
is_temp = FALSE;
}
if (space_id != 0 && !in_crash_recovery) {
fil_space_for_table_exists_in_mem(
space_id, name, is_temp, TRUE, !is_temp);
} else {
/* It is a normal database startup: create the space
object and check that the .ibd file exists. */
......@@ -878,7 +898,7 @@ err_exit:
space = mach_read_from_4(field);
/* Check if the tablespace exists and has the right name */
if (space != 0) {
if (!trx_sys_sys_space(space)) {
flags = dict_sys_tables_get_flags(rec);
if (UNIV_UNLIKELY(flags == ULINT_UNDEFINED)) {
......@@ -894,43 +914,72 @@ err_exit:
(ulong) flags);
goto err_exit;
}
} else {
flags = 0;
}
if (fil_space_for_table_exists_in_mem(space, name, FALSE,
FALSE, FALSE)) {
/* Ok; (if we did a crash recovery then the tablespace
can already be in the memory cache) */
} else {
/* In >= 4.1.9, InnoDB scans the data dictionary also
at a normal mysqld startup. It is an error if the
space object does not exist in memory. */
ut_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));
}
flags |= flags2 << DICT_TF2_SHIFT;
}
/* See if the tablespace is available. */
if (trx_sys_sys_space(space)) {
/* The system tablespace is always available. */
} else if (!fil_space_for_table_exists_in_mem(
space, name,
(flags >> DICT_TF2_SHIFT) & DICT_TF2_TEMPORARY,
FALSE, FALSE)) {
if ((flags >> DICT_TF2_SHIFT) & DICT_TF2_TEMPORARY) {
/* Do not bother to retry opening temporary tables. */
ibd_file_missing = TRUE;
} else {
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: error: space object of table %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."
" Retrying an open.\n",
name, (ulong)space);
(ulong) space);
/* Try to open the tablespace */
if (!fil_open_single_table_tablespace(
TRUE, space, flags, name)) {
/* We failed to find a sensible tablespace
file */
TRUE, space,
flags & ~(~0 << DICT_TF_BITS), name)) {
/* We failed to find a sensible
tablespace file */
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,
......
......@@ -59,7 +59,7 @@ dict_mem_table_create(
mem_heap_t* heap;
ut_ad(name);
ut_a(!(flags & (~0 << DICT_TF_BITS)));
ut_a(!(flags & (~0 << DICT_TF2_BITS)));
heap = mem_heap_create(DICT_HEAP_SIZE);
......
/*****************************************************************************
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
......@@ -38,6 +38,7 @@ Created 10/25/1995 Heikki Tuuri
#include "mtr0mtr.h"
#include "mtr0log.h"
#include "dict0dict.h"
#include "page0page.h"
#include "page0zip.h"
#include "trx0trx.h"
#include "trx0sys.h"
......@@ -673,14 +674,14 @@ fil_node_open_file(
size_bytes = (((ib_int64_t)size_high) << 32)
+ (ib_int64_t)size_low;
#ifdef UNIV_HOTBACKUP
if (space->id == 0) {
if (trx_sys_sys_space(space->id)) {
node->size = (ulint) (size_bytes / UNIV_PAGE_SIZE);
os_file_close(node->handle);
goto add_size;
}
#endif /* UNIV_HOTBACKUP */
ut_a(space->purpose != FIL_LOG);
ut_a(space->id != 0);
ut_a(!trx_sys_sys_space(space->id));
if (size_bytes < FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE) {
fprintf(stderr,
......@@ -726,7 +727,7 @@ fil_node_open_file(
}
if (UNIV_UNLIKELY(space_id == ULINT_UNDEFINED
|| space_id == 0)) {
|| trx_sys_sys_space(space_id))) {
fprintf(stderr,
"InnoDB: Error: tablespace id %lu"
" in file %s is not sensible\n",
......@@ -788,7 +789,7 @@ add_size:
system->n_open++;
if (space->purpose == FIL_TABLESPACE && space->id != 0) {
if (space->purpose == FIL_TABLESPACE && !trx_sys_sys_space(space->id)) {
/* Put the node to the LRU list */
UT_LIST_ADD_FIRST(LRU, system->LRU, node);
}
......@@ -821,7 +822,7 @@ fil_node_close_file(
ut_a(system->n_open > 0);
system->n_open--;
if (node->space->purpose == FIL_TABLESPACE && node->space->id != 0) {
if (node->space->purpose == FIL_TABLESPACE && !trx_sys_sys_space(node->space->id)) {
ut_a(UT_LIST_GET_LEN(system->LRU) > 0);
/* The node is in the LRU list, remove it */
......@@ -907,7 +908,7 @@ fil_mutex_enter_and_prepare_for_io(
retry:
mutex_enter(&fil_system->mutex);
if (space_id == 0 || space_id >= SRV_LOG_SPACE_FIRST_ID) {
if (trx_sys_sys_space(space_id) || space_id >= SRV_LOG_SPACE_FIRST_ID) {
/* We keep log files and system tablespace files always open;
this is important in preventing deadlocks in this module, as
a page read completion often performs another read from the
......@@ -1102,10 +1103,13 @@ fil_space_create(
fil_space_t* space;
/* The tablespace flags (FSP_SPACE_FLAGS) should be 0 for
ROW_FORMAT=COMPACT (table->flags == DICT_TF_COMPACT) and
ROW_FORMAT=COMPACT
((table->flags & ~(~0 << DICT_TF_BITS)) == DICT_TF_COMPACT) and
ROW_FORMAT=REDUNDANT (table->flags == 0). For any other
format, the tablespace flags should equal table->flags. */
format, the tablespace flags should equal
(table->flags & ~(~0 << DICT_TF_BITS)). */
ut_a(flags != DICT_TF_COMPACT);
ut_a(!(flags & (~0UL << DICT_TF_BITS)));
try_again:
/*printf(
......@@ -1134,7 +1138,7 @@ try_again:
" tablespace memory cache!\n",
(ulong) space->id);
if (id == 0 || purpose != FIL_TABLESPACE) {
if (trx_sys_sys_space(id) || purpose != FIL_TABLESPACE) {
mutex_exit(&fil_system->mutex);
......@@ -1528,7 +1532,7 @@ fil_init(
fil_system->max_n_open = max_n_open;
fil_system->modification_counter = 0;
fil_system->max_assigned_id = 0;
fil_system->max_assigned_id = TRX_SYS_SPACE_MAX;
fil_system->tablespace_version = 0;
......@@ -1555,7 +1559,7 @@ fil_open_log_and_system_tablespace_files(void)
space = UT_LIST_GET_FIRST(fil_system->space_list);
while (space != NULL) {
if (space->purpose != FIL_TABLESPACE || space->id == 0) {
if (space->purpose != FIL_TABLESPACE || trx_sys_sys_space(space->id)) {
node = UT_LIST_GET_FIRST(space->chain);
while (node != NULL) {
......@@ -2589,10 +2593,13 @@ fil_create_new_single_table_tablespace(
ut_a(size >= FIL_IBD_FILE_INITIAL_SIZE);
/* The tablespace flags (FSP_SPACE_FLAGS) should be 0 for
ROW_FORMAT=COMPACT (table->flags == DICT_TF_COMPACT) and
ROW_FORMAT=COMPACT
((table->flags & ~(~0 << DICT_TF_BITS)) == DICT_TF_COMPACT) and
ROW_FORMAT=REDUNDANT (table->flags == 0). For any other
format, the tablespace flags should equal table->flags. */
format, the tablespace flags should equal
(table->flags & ~(~0 << DICT_TF_BITS)). */
ut_a(flags != DICT_TF_COMPACT);
ut_a(!(flags & (~0UL << DICT_TF_BITS)));
path = fil_make_ibd_name(tablename, is_temp);
......@@ -2793,6 +2800,7 @@ fil_reset_too_high_lsns(
ib_int64_t offset;
ulint zip_size;
ibool success;
page_zip_des_t page_zip;
filepath = fil_make_ibd_name(name, FALSE);
......@@ -2840,6 +2848,12 @@ fil_reset_too_high_lsns(
space_id = fsp_header_get_space_id(page);
zip_size = fsp_header_get_zip_size(page);
page_zip_des_init(&page_zip);
page_zip_set_size(&page_zip, zip_size);
if (zip_size) {
page_zip.data = page + UNIV_PAGE_SIZE;
}
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Flush lsn in the tablespace file %lu"
......@@ -2874,20 +2888,23 @@ fil_reset_too_high_lsns(
/* We have to reset the lsn */
if (zip_size) {
memcpy(page + UNIV_PAGE_SIZE, page, zip_size);
memcpy(page_zip.data, page, zip_size);
buf_flush_init_for_writing(
page, page + UNIV_PAGE_SIZE,
current_lsn);
page, &page_zip, current_lsn);
success = os_file_write(
filepath, file, page_zip.data,
(ulint) offset & 0xFFFFFFFFUL,
(ulint) (offset >> 32), zip_size);
} else {
buf_flush_init_for_writing(
page, NULL, current_lsn);
success = os_file_write(
filepath, file, page,
(ulint)(offset & 0xFFFFFFFFUL),
(ulint)(offset >> 32),
UNIV_PAGE_SIZE);
}
success = os_file_write(filepath, file, page,
(ulint)(offset & 0xFFFFFFFFUL),
(ulint)(offset >> 32),
zip_size
? zip_size
: UNIV_PAGE_SIZE);
if (!success) {
goto func_exit;
......@@ -2963,10 +2980,13 @@ fil_open_single_table_tablespace(
filepath = fil_make_ibd_name(name, FALSE);
/* The tablespace flags (FSP_SPACE_FLAGS) should be 0 for
ROW_FORMAT=COMPACT (table->flags == DICT_TF_COMPACT) and
ROW_FORMAT=COMPACT
((table->flags & ~(~0 << DICT_TF_BITS)) == DICT_TF_COMPACT) and
ROW_FORMAT=REDUNDANT (table->flags == 0). For any other
format, the tablespace flags should equal table->flags. */
format, the tablespace flags should equal
(table->flags & ~(~0 << DICT_TF_BITS)). */
ut_a(flags != DICT_TF_COMPACT);
ut_a(!(flags & (~0UL << DICT_TF_BITS)));
file = os_file_create_simple_no_error_handling(
filepath, OS_FILE_OPEN, OS_FILE_READ_WRITE, &success);
......@@ -3016,7 +3036,8 @@ fil_open_single_table_tablespace(
space_id = fsp_header_get_space_id(page);
space_flags = fsp_header_get_flags(page);
if (srv_expand_import && (space_id != id || space_flags != flags)) {
if (srv_expand_import
&& (space_id != id || space_flags != (flags & ~(~0 << DICT_TF_BITS)))) {
dulint old_id[31];
dulint new_id[31];
ulint root_page[31];
......@@ -3357,7 +3378,8 @@ skip_write:
ut_free(buf2);
if (UNIV_UNLIKELY(space_id != id || space_flags != flags)) {
if (UNIV_UNLIKELY(space_id != id
|| space_flags != (flags & ~(~0 << DICT_TF_BITS)))) {
ut_print_timestamp(stderr);
fputs(" InnoDB: Error: tablespace id and flags in file ",
......@@ -3596,7 +3618,7 @@ fil_load_single_table_tablespace(
}
#ifndef UNIV_HOTBACKUP
if (space_id == ULINT_UNDEFINED || space_id == 0) {
if (space_id == ULINT_UNDEFINED || trx_sys_sys_space(space_id)) {
fprintf(stderr,
"InnoDB: Error: tablespace id %lu in file %s"
" is not sensible\n",
......@@ -3605,7 +3627,7 @@ fil_load_single_table_tablespace(
goto func_exit;
}
#else
if (space_id == ULINT_UNDEFINED || space_id == 0) {
if (space_id == ULINT_UNDEFINED || trx_sys_sys_space(space_id)) {
char* new_path;
fprintf(stderr,
......@@ -3884,7 +3906,7 @@ fil_print_orphaned_tablespaces(void)
space = UT_LIST_GET_FIRST(fil_system->space_list);
while (space) {
if (space->purpose == FIL_TABLESPACE && space->id != 0
if (space->purpose == FIL_TABLESPACE && !trx_sys_sys_space(space->id)
&& !space->mark) {
fputs("InnoDB: Warning: tablespace ", stderr);
ut_print_filename(stderr, space->name);
......@@ -4459,7 +4481,7 @@ fil_node_prepare_for_io(
}
if (node->n_pending == 0 && space->purpose == FIL_TABLESPACE
&& space->id != 0) {
&& !trx_sys_sys_space(space->id)) {
/* The node is in the LRU list, remove it */
ut_a(UT_LIST_GET_LEN(system->LRU) > 0);
......@@ -4505,7 +4527,7 @@ fil_node_complete_io(
}
if (node->n_pending == 0 && node->space->purpose == FIL_TABLESPACE
&& node->space->id != 0) {
&& !trx_sys_sys_space(node->space->id)) {
/* The node must be put back to the LRU list */
UT_LIST_ADD_FIRST(LRU, system->LRU, node);
}
......@@ -5136,7 +5158,7 @@ fil_validate(void)
ut_a(fil_node->n_pending == 0);
ut_a(fil_node->open);
ut_a(fil_node->space->purpose == FIL_TABLESPACE);
ut_a(fil_node->space->id != 0);
ut_a(!trx_sys_sys_space(fil_node->space->id));
fil_node = UT_LIST_GET_NEXT(LRU, fil_node);
}
......@@ -5218,8 +5240,10 @@ void
fil_close(void)
/*===========*/
{
#ifndef UNIV_HOTBACKUP
/* The mutex should already have been freed. */
ut_ad(fil_system->mutex.magic_n == 0);
#endif /* !UNIV_HOTBACKUP */
hash_table_free(fil_system->spaces);
......
/*****************************************************************************
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
......@@ -48,7 +48,7 @@ Created 11/29/1995 Heikki Tuuri
# include "log0log.h"
#endif /* UNIV_HOTBACKUP */
#include "dict0mem.h"
#include "trx0sys.h"
#define FSP_HEADER_OFFSET FIL_PAGE_DATA /* Offset of the space header
within a file page */
......@@ -392,11 +392,11 @@ UNIV_INLINE
ibool
xdes_get_bit(
/*=========*/
xdes_t* descr, /*!< in: descriptor */
ulint bit, /*!< in: XDES_FREE_BIT or XDES_CLEAN_BIT */
ulint offset, /*!< in: page offset within extent:
0 ... FSP_EXTENT_SIZE - 1 */
mtr_t* mtr) /*!< in: mtr */
const xdes_t* descr, /*!< in: descriptor */
ulint bit, /*!< in: XDES_FREE_BIT or XDES_CLEAN_BIT */
ulint offset, /*!< in: page offset within extent:
0 ... FSP_EXTENT_SIZE - 1 */
mtr_t* mtr) /*!< in: mtr */
{
ulint index;
ulint byte_index;
......@@ -533,8 +533,8 @@ UNIV_INLINE
ulint
xdes_get_n_used(
/*============*/
xdes_t* descr, /*!< in: descriptor */
mtr_t* mtr) /*!< in: mtr */
const xdes_t* descr, /*!< in: descriptor */
mtr_t* mtr) /*!< in: mtr */
{
ulint i;
ulint count = 0;
......@@ -557,8 +557,8 @@ UNIV_INLINE
ibool
xdes_is_free(
/*=========*/
xdes_t* descr, /*!< in: descriptor */
mtr_t* mtr) /*!< in: mtr */
const xdes_t* descr, /*!< in: descriptor */
mtr_t* mtr) /*!< in: mtr */
{
if (0 == xdes_get_n_used(descr, mtr)) {
......@@ -575,8 +575,8 @@ UNIV_INLINE
ibool
xdes_is_full(
/*=========*/
xdes_t* descr, /*!< in: descriptor */
mtr_t* mtr) /*!< in: mtr */
const xdes_t* descr, /*!< in: descriptor */
mtr_t* mtr) /*!< in: mtr */
{
if (FSP_EXTENT_SIZE == xdes_get_n_used(descr, mtr)) {
......@@ -592,7 +592,7 @@ UNIV_INLINE
void
xdes_set_state(
/*===========*/
xdes_t* descr, /*!< in: descriptor */
xdes_t* descr, /*!< in/out: descriptor */
ulint state, /*!< in: state to set */
mtr_t* mtr) /*!< in: mtr handle */
{
......@@ -611,8 +611,8 @@ UNIV_INLINE
ulint
xdes_get_state(
/*===========*/
xdes_t* descr, /*!< in: descriptor */
mtr_t* mtr) /*!< in: mtr handle */
const xdes_t* descr, /*!< in: descriptor */
mtr_t* mtr) /*!< in: mtr handle */
{
ulint state;
......@@ -712,7 +712,7 @@ UNIV_INLINE
xdes_t*
xdes_get_descriptor_with_space_hdr(
/*===============================*/
fsp_header_t* sp_header,/*!< in: space header, x-latched */
fsp_header_t* sp_header,/*!< in/out: space header, x-latched */
ulint space, /*!< in: space id */
ulint offset, /*!< in: page offset;
if equal to the free limit,
......@@ -882,9 +882,7 @@ fsp_init_file_page_low(
return;
}
#ifdef UNIV_BASIC_LOG_DEBUG
memset(page, 0xff, UNIV_PAGE_SIZE);
#endif
UNIV_MEM_INVALID(page, UNIV_PAGE_SIZE);
mach_write_to_4(page + FIL_PAGE_OFFSET, buf_block_get_page_no(block));
memset(page + FIL_PAGE_LSN, 0, 8);
mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID,
......@@ -1017,10 +1015,10 @@ fsp_header_init(
flst_init(header + FSP_SEG_INODES_FREE, mtr);
mlog_write_dulint(header + FSP_SEG_ID, ut_dulint_create(0, 1), mtr);
if (space == 0) {
if (space == TRX_SYS_SPACE || space == TRX_DOUBLEWRITE_SPACE) {
fsp_fill_free_list(FALSE, space, header, mtr);
btr_create(DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF,
0, 0, ut_dulint_add(DICT_IBUF_ID_MIN, space),
space, 0, ut_dulint_add(DICT_IBUF_ID_MIN, space),
dict_ind_redundant, mtr);
} else {
fsp_fill_free_list(TRUE, space, header, mtr);
......@@ -1355,7 +1353,7 @@ fsp_fill_free_list(
descriptor page and ibuf bitmap page;
then we do not allocate more extents */
ulint space, /*!< in: space */
fsp_header_t* header, /*!< in: space header */
fsp_header_t* header, /*!< in/out: space header */
mtr_t* mtr) /*!< in: mtr */
{
ulint limit;
......
......@@ -101,6 +101,8 @@ ha_clear(
ulint i;
ulint n;
ut_ad(table);
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
#ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EXCLUSIVE));
#endif /* UNIV_SYNC_DEBUG */
......@@ -146,7 +148,9 @@ ha_insert_for_fold_func(
ha_node_t* prev_node;
ulint hash;
ut_ad(table && data);
ut_ad(data);
ut_ad(table);
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
ut_a(block->frame == page_align(data));
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
......@@ -237,6 +241,8 @@ ha_delete_hash_node(
hash_table_t* table, /*!< in: hash table */
ha_node_t* del_node) /*!< in: node to be deleted */
{
ut_ad(table);
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
# ifndef UNIV_HOTBACKUP
if (table->adaptive) {
......@@ -267,6 +273,8 @@ ha_search_and_update_if_found_func(
{
ha_node_t* node;
ut_ad(table);
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
ASSERT_HASH_MUTEX_OWN(table, fold);
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
ut_a(new_block->frame == page_align(new_data));
......@@ -304,6 +312,8 @@ ha_remove_all_nodes_to_page(
{
ha_node_t* node;
ut_ad(table);
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
ASSERT_HASH_MUTEX_OWN(table, fold);
node = ha_chain_get_first(table, fold);
......@@ -353,6 +363,8 @@ ha_validate(
ibool ok = TRUE;
ulint i;
ut_ad(table);
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
ut_a(start_index <= end_index);
ut_a(start_index < hash_get_n_cells(table));
ut_a(end_index < hash_get_n_cells(table));
......@@ -404,6 +416,8 @@ builds, see http://bugs.mysql.com/36941 */
#endif /* PRINT_USED_CELLS */
ulint n_bufs;
ut_ad(table);
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
#ifdef PRINT_USED_CELLS
for (i = 0; i < hash_get_n_cells(table); i++) {
......
......@@ -119,7 +119,7 @@ hash_create(
table->heaps = NULL;
#endif /* !UNIV_HOTBACKUP */
table->heap = NULL;
table->magic_n = HASH_TABLE_MAGIC_N;
ut_d(table->magic_n = HASH_TABLE_MAGIC_N);
/* Initialize the cell array */
hash_table_clear(table);
......@@ -135,6 +135,8 @@ hash_table_free(
/*============*/
hash_table_t* table) /*!< in, own: hash table */
{
ut_ad(table);
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
#ifndef UNIV_HOTBACKUP
ut_a(table->mutexes == NULL);
#endif /* !UNIV_HOTBACKUP */
......@@ -160,6 +162,8 @@ hash_create_mutexes_func(
{
ulint i;
ut_ad(table);
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
ut_a(n_mutexes > 0);
ut_a(ut_is_2pow(n_mutexes));
......
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
the terms of the GNU General Public License as published by the Free Software
......@@ -27,16 +27,32 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#pragma interface /* gcc class implementation */
#endif
/* Structure defines translation table between mysql index and innodb
index structures */
typedef struct innodb_idx_translate_struct {
ulint index_count; /*!< number of valid index entries
in the index_mapping array */
ulint array_size; /*!< array size of index_mapping */
dict_index_t** index_mapping; /*!< index pointer array directly
maps to index in Innodb from MySQL
array index */
} innodb_idx_translate_t;
/** InnoDB table share */
typedef struct st_innobase_share {
THR_LOCK lock; /*!< MySQL lock protecting
this structure */
const char* table_name; /*!< InnoDB table name */
uint use_count; /*!< reference count,
incremented in get_share()
and decremented in free_share() */
void* table_name_hash;/*!< hash table chain node */
dict_table_t* ib_table;
THR_LOCK lock; /*!< MySQL lock protecting
this structure */
const char* table_name; /*!< InnoDB table name */
uint use_count; /*!< reference count,
incremented in get_share()
and decremented in
free_share() */
void* table_name_hash;/*!< hash table chain node */
innodb_idx_translate_t idx_trans_tbl; /*!< index translation
table between MySQL and
Innodb */
dict_table_t* ib_table;
} INNOBASE_SHARE;
......@@ -92,9 +108,8 @@ class ha_innobase: public handler
ulint innobase_reset_autoinc(ulonglong auto_inc);
ulint innobase_get_autoinc(ulonglong* value);
ulint innobase_update_autoinc(ulonglong auto_inc);
ulint innobase_initialize_autoinc();
void innobase_initialize_autoinc();
dict_index_t* innobase_get_index(uint keynr);
ulonglong innobase_get_int_col_max_value(const Field* field);
/* Init values for the class: */
public:
......
/*****************************************************************************
Copyright (c) 2005, 2009, Innobase Oy. All Rights Reserved.
Copyright (c) 2005, 2010, Innobase Oy. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
......@@ -229,9 +229,11 @@ static
int
innobase_check_index_keys(
/*======================*/
const KEY* key_info, /*!< in: Indexes to be created */
ulint num_of_keys) /*!< in: Number of indexes to
be created */
const KEY* key_info, /*!< in: Indexes to be
created */
ulint num_of_keys, /*!< in: Number of
indexes to be created */
const dict_table_t* table) /*!< in: Existing indexes */
{
ulint key_num;
......@@ -248,9 +250,22 @@ innobase_check_index_keys(
const KEY& key2 = key_info[i];
if (0 == strcmp(key.name, key2.name)) {
sql_print_error("InnoDB: key name `%s` appears"
" twice in CREATE INDEX\n",
key.name);
my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0),
key.name);
return(ER_WRONG_NAME_FOR_INDEX);
}
}
/* Check that the same index name does not already exist. */
for (const dict_index_t* index
= dict_table_get_first_index(table);
index; index = dict_table_get_next_index(index)) {
if (0 == strcmp(key.name, index->name)) {
my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0),
key.name);
return(ER_WRONG_NAME_FOR_INDEX);
}
......@@ -258,7 +273,7 @@ innobase_check_index_keys(
/* Check that MySQL does not try to create a column
prefix index field on an inappropriate data type and
that the same colum does not appear twice in the index. */
that the same column does not appear twice in the index. */
for (ulint i = 0; i < key.key_parts; i++) {
const KEY_PART_INFO& key_part1
......@@ -289,14 +304,8 @@ innobase_check_index_keys(
}
}
sql_print_error("InnoDB: MySQL is trying to"
" create a column prefix"
" index field on an"
" inappropriate data type."
" column `%s`,"
" index `%s`.\n",
field->field_name,
key.name);
my_error(ER_WRONG_KEY_COLUMN, MYF(0),
field->field_name);
return(ER_WRONG_KEY_COLUMN);
}
......@@ -309,11 +318,8 @@ innobase_check_index_keys(
continue;
}
sql_print_error("InnoDB: column `%s`"
" is not allowed to occur"
" twice in index `%s`.\n",
key_part1.field->field_name,
key.name);
my_error(ER_WRONG_KEY_COLUMN, MYF(0),
key_part1.field->field_name);
return(ER_WRONG_KEY_COLUMN);
}
}
......@@ -522,12 +528,14 @@ innobase_create_key_def(
key_info->name, "PRIMARY");
/* If there is a UNIQUE INDEX consisting entirely of NOT NULL
columns, MySQL will treat it as a PRIMARY KEY unless the
table already has one. */
columns and if the index does not contain column prefix(es)
(only prefix/part of the column is indexed), MySQL will treat the
index as a PRIMARY KEY unless the table already has one. */
if (!new_primary && (key_info->flags & HA_NOSAME)
&& (!(key_info->flags & HA_KEY_HAS_PART_KEY_SEG))
&& row_table_got_default_clust_index(table)) {
uint key_part = key_info->key_parts;
uint key_part = key_info->key_parts;
new_primary = TRUE;
......@@ -656,12 +664,18 @@ ha_innobase::add_index(
innodb_table = indexed_table
= dict_table_get(prebuilt->table->name, FALSE);
if (UNIV_UNLIKELY(!innodb_table)) {
error = HA_ERR_NO_SUCH_TABLE;
goto err_exit;
}
/* Check if the index name is reserved. */
if (innobase_index_name_is_reserved(trx, key_info, num_of_keys)) {
error = -1;
} else {
/* Check that index keys are sensible */
error = innobase_check_index_keys(key_info, num_of_keys);
error = innobase_check_index_keys(key_info, num_of_keys,
innodb_table);
}
if (UNIV_UNLIKELY(error)) {
......@@ -708,6 +722,8 @@ err_exit:
row_mysql_lock_data_dictionary(trx);
dict_locked = TRUE;
ut_d(dict_table_check_for_dup_indexes(innodb_table, FALSE));
/* If a new primary key is defined for the table we need
to drop the original table and rebuild all indexes. */
......@@ -740,6 +756,8 @@ err_exit:
user_thd);
}
ut_d(dict_table_check_for_dup_indexes(innodb_table,
FALSE));
row_mysql_unlock_data_dictionary(trx);
goto err_exit;
}
......@@ -764,6 +782,10 @@ err_exit:
ut_ad(error == DB_SUCCESS);
/* We will need to rebuild index translation table. Set
valid index entry count in the translation table to zero */
share->idx_trans_tbl.index_count = 0;
/* Commit the data dictionary transaction in order to release
the table locks on the system tables. This means that if
MySQL crashes while creating a new primary key inside
......@@ -799,18 +821,6 @@ err_exit:
index, num_of_idx, table);
error_handling:
#ifdef UNIV_DEBUG
/* TODO: At the moment we can't handle the following statement
in our debugging code below:
alter table t drop index b, add index (b);
The fix will have to parse the SQL and note that the index
being added has the same name as the one being dropped and
ignore that in the dup index check.*/
//dict_table_check_for_dup_indexes(prebuilt->table);
#endif
/* After an error, remove all those index definitions from the
dictionary which were defined. */
......@@ -822,6 +832,8 @@ error_handling:
row_mysql_lock_data_dictionary(trx);
dict_locked = TRUE;
ut_d(dict_table_check_for_dup_indexes(prebuilt->table, TRUE));
if (!new_primary) {
error = row_merge_rename_indexes(trx, indexed_table);
......@@ -909,6 +921,7 @@ convert_error:
}
if (dict_locked) {
ut_d(dict_table_check_for_dup_indexes(innodb_table, FALSE));
row_mysql_unlock_data_dictionary(trx);
}
......@@ -951,6 +964,7 @@ ha_innobase::prepare_drop_index(
/* Test and mark all the indexes to be dropped */
row_mysql_lock_data_dictionary(trx);
ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
/* Check that none of the indexes have previously been flagged
for deletion. */
......@@ -1116,6 +1130,7 @@ func_exit:
} while (index);
}
ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
row_mysql_unlock_data_dictionary(trx);
DBUG_RETURN(err);
......@@ -1162,6 +1177,7 @@ ha_innobase::final_drop_index(
prebuilt->table->flags, user_thd);
row_mysql_lock_data_dictionary(trx);
ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
if (UNIV_UNLIKELY(err)) {
......@@ -1198,11 +1214,12 @@ ha_innobase::final_drop_index(
ut_a(!index->to_be_dropped);
}
#ifdef UNIV_DEBUG
dict_table_check_for_dup_indexes(prebuilt->table);
#endif
/* We will need to rebuild index translation table. Set
valid index entry count in the translation table to zero */
share->idx_trans_tbl.index_count = 0;
func_exit:
ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
trx_commit_for_mysql(trx);
trx_commit_for_mysql(prebuilt->trx);
row_mysql_unlock_data_dictionary(trx);
......
......@@ -2900,6 +2900,9 @@ i_s_innodb_index_stats_fill(
i_s_table->field[3]->store(index->n_uniq);
row_per_keys[0] = '\0';
/* It is remained optimistic operation still for now */
//dict_index_stat_mutex_enter(index);
if (index->stat_n_diff_key_vals) {
for (i = 1; i <= index->n_uniq; i++) {
ib_int64_t rec_per_key;
......@@ -2913,6 +2916,8 @@ i_s_innodb_index_stats_fill(
strncat(row_per_keys, buff, 256 - strlen(row_per_keys));
}
}
//dict_index_stat_mutex_exit(index);
field_store_string(i_s_table->field[4], row_per_keys);
i_s_table->field[5]->store(index->stat_index_size);
......@@ -3169,6 +3174,14 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_admin_command =
static ST_FIELD_INFO i_s_innodb_sys_tables_info[] =
{
{STRUCT_FLD(field_name, "SCHEMA"),
STRUCT_FLD(field_length, NAME_LEN),
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, 0),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
{STRUCT_FLD(field_name, "NAME"),
STRUCT_FLD(field_length, NAME_LEN),
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
......@@ -3325,6 +3338,54 @@ copy_string_field(
return status;
}
static
int
copy_name_fields(
/*=============*/
TABLE* table,
int table_field_1,
const rec_t* rec,
int rec_field)
{
int status;
const byte* data;
ulint len;
data = rec_get_nth_field_old(rec, rec_field, &len);
if (len == UNIV_SQL_NULL) {
table->field[table_field_1]->set_null();
table->field[table_field_1 + 1]->set_null();
status = 0; /* success */
} else {
char buf[NAME_LEN * 2 + 2];
char* ptr;
if (len > NAME_LEN * 2 + 1) {
table->field[table_field_1]->set_null();
status = field_store_string(table->field[table_field_1 + 1],
"###TOO LONG NAME###");
goto end_func;
}
strncpy(buf, (char*)data, len);
buf[len] = '\0';
ptr = strchr(buf, '/');
if (ptr) {
*ptr = '\0';
++ptr;
status = field_store_string(table->field[table_field_1], buf);
status |= field_store_string(table->field[table_field_1 + 1], ptr);
} else {
table->field[table_field_1]->set_null();
status = field_store_string(table->field[table_field_1 + 1], buf);
}
}
end_func:
return status;
}
static
int
copy_int_field(
......@@ -3395,49 +3456,49 @@ copy_sys_tables_rec(
/* NAME */
field = dict_index_get_nth_col_pos(index, 0);
status = copy_string_field(table, 0, rec, field);
status = copy_name_fields(table, 0, rec, field);
if (status) {
return status;
}
/* ID */
field = dict_index_get_nth_col_pos(index, 1);
status = copy_id_field(table, 1, rec, field);
status = copy_id_field(table, 2, rec, field);
if (status) {
return status;
}
/* N_COLS */
field = dict_index_get_nth_col_pos(index, 2);
status = copy_int_field(table, 2, rec, field);
status = copy_int_field(table, 3, rec, field);
if (status) {
return status;
}
/* TYPE */
field = dict_index_get_nth_col_pos(index, 3);
status = copy_int_field(table, 3, rec, field);
status = copy_int_field(table, 4, rec, field);
if (status) {
return status;
}
/* MIX_ID */
field = dict_index_get_nth_col_pos(index, 4);
status = copy_id_field(table, 4, rec, field);
status = copy_id_field(table, 5, rec, field);
if (status) {
return status;
}
/* MIX_LEN */
field = dict_index_get_nth_col_pos(index, 5);
status = copy_int_field(table, 5, rec, field);
status = copy_int_field(table, 6, rec, field);
if (status) {
return status;
}
/* CLUSTER_NAME */
field = dict_index_get_nth_col_pos(index, 6);
status = copy_string_field(table, 6, rec, field);
status = copy_string_field(table, 7, rec, field);
if (status) {
return status;
}
/* SPACE */
field = dict_index_get_nth_col_pos(index, 7);
status = copy_int_field(table, 7, rec, field);
status = copy_int_field(table, 8, rec, field);
if (status) {
return status;
}
......
......@@ -41,8 +41,8 @@ struct innodb_enhancement {
{"innodb_admin_command_base","XtraDB specific command interface through i_s","","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_show_lock_name","Show mutex/lock name instead of crated file/line","","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_extend_slow","Extended statistics in slow.log","It is InnoDB-part only. It needs to patch also to mysqld.","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_relax_table_creation","Relax limitation of column size at table creation as builtin InnoDB.","","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_lru_dump_restore","Dump and restore command for content of buffer pool","","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_separate_doublewrite","Add option 'innodb_doublewrite_file' to separate doublewrite dedicated tablespace","","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_pass_corrupt_table","Treat tables as corrupt instead of crash, when meet corrupt blocks","","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_fast_checksum","Using the checksum on 32bit-unit calculation","incompatible for unpatched ver.","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_files_extend","allow >4GB transaction log files, and can vary universal page size of datafiles","incompatible for unpatched ver.","http://www.percona.com/docs/wiki/percona-xtradb"},
......
This diff is collapsed.
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
the terms of the GNU General Public License as published by the Free Software
......@@ -257,6 +257,10 @@ btr_page_set_prev(
/**************************************************************//**
Gets the child node file address in a node pointer.
NOTE: the offsets array must contain all offsets for the record since
we read the last field according to offsets and assume that it contains
the child page number. In other words offsets must have been retrieved
with rec_get_offsets(n_fields=ULINT_UNDEFINED).
@return child node address */
UNIV_INLINE
ulint
......
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_doublewrite_file=ib_doublewrite
This diff is collapsed.
--source include/have_innodb.inc
show variables like 'innodb_doublewrite%';
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.
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