Commit 115a2967 authored by Sergei Golubchik's avatar Sergei Golubchik

merge with XtraDB as of Percona-Server-5.1.63-rel13.4

parent cefc30b1
......@@ -10,10 +10,5 @@
#
##############################################################################
innodb_bug13635833: Disabled until merging with XtraDB 5.1.63
innodb-lock: Disabled until merging with XtraDB 5.1.60
innodb_replace: Disabled until merging with XtraDB 5.1.60
innodb_bug14007649: Disabled until merging with XtraDB 5.1.65
......@@ -10,11 +10,5 @@
#
##############################################################################
innodb_bug13635833: Disabled until merging with XtraDB 5.1.63
innodb_bug52745: Disabled as this has valgrind failures (also in MySQL 5.1.50)
innodb-index: Disabled until merging with XtraDB 5.1.60
innodb-lock: Disabled until merging with XtraDB 5.1.60
innodb_replace: Disabled until merging with XtraDB 5.1.60
innodb-blob: Disabled until merging with XtraDB 5.1.63
innodb_bug14007649: Disabled until merging with XtraDB 5.1.65
2012-03-15 The InnoDB Team
* fil/fil0fil.c, ibuf/ibuf0ibuf.c, include/fil0fil.h,
lock/lock0lock.c:
Fix Bug#13825266 RACE IN LOCK_VALIDATE() WHEN ACCESSING PAGES
DIRECTLY FROM BUFFER POOL
2012-03-15 The InnoDB Team
* handler/ha_innodb.cc:
Fix Bug#13851171STRING OVERFLOW IN INNODB CODE FOUND BY STATIC
ANALYSIS
2012-03-15 The InnoDB Team
* include/sync0rw.ic:
Fix Bug#13537504 VALGRIND: COND. JUMP/MOVE DEPENDS ON
UNINITIALISED VALUES IN OS_THREAD_EQ
2012-03-08 The InnoDB Team
* btr/btr0pcur.c:
Fix Bug#13807811 BTR_PCUR_RESTORE_POSITION() CAN SKIP A RECORD
2012-02-28 The InnoDB Team
* btr/btr0btr.c, dict/dict0dict.c, include/btr0btr.h,
include/dict0dict.h, include/dict0dict.ic, include/dict0mem.h,
handler/handler0alter.cc, row/row0mysql.c:
Fix Bug#12861864 RACE CONDITION IN BTR_GET_SIZE() AND
DROP INDEX/TABLE/DATABASE
2012-02-15 The InnoDB Team
* btr/btr0btr.c, btr/btr0cur.c, fsp/fsp0fsp.c, ibuf/ibuf0ibuf.c,
include/btr0btr.h, include/btr0cur.h, include/btr0cur.ic,
include/buf0buf.h, include/buf0buf.ic, include/fsp0fsp.h,
include/mtr0mtr.h, include/mtr0mtr.ic, include/page0page.h,
include/page0page.ic, include/trx0rec.ic, include/trx0undo.h,
mtr/mtr0mtr.c, page/page0cur.c, page/page0page.c, row/row0ins.c,
row/row0row.c, row/row0upd.c, trx/trx0rec.c, trx/trx0sys.c,
trx/trx0undo.c:
Fix Bug#13721257 RACE CONDITION IN UPDATES OR INSERTS OF WIDE RECORDS
2012-02-06 The InnoDB Team
* handler/ha_innodb.cc:
Fix Bug#11754376 45976: INNODB LOST FILES FOR TEMPORARY TABLES ON
GRACEFUL SHUTDOWN
2012-01-30 The InnoDB Team
* fil/fil0fil.c:
Fix Bug#13636122 THE ORIGINAL TABLE MISSING WHILE EXECUTE THE
DDL 'ALTER TABLE ADD COLUMN'
2012-01-16 The InnoDB Team
* ibuf/ibuf0ibuf.c:
Fix Bug#13496818 ASSERTION: REC_PAGE_NO > 4 IN IBUF CONTRACTION
2012-01-16 The InnoDB Team
* handler/ha_innodb.cc:
Fix Bug#11765438: 58406: ISSUES WITH COPYING PARTITIONED INNODB
TABLES FROM LINUX TO WINDOWS
2012-01-04 The InnoDB Team
* row/row0mysql.c:
Fix Bug#12400341: INNODB CAN LEAVE ORPHAN IBD FILES AROUND
2011-12-22 The InnoDB Team
* row/row0sel.c:
Fix Bug#63775 Server crash on handler read next after delete record.
2011-12-21 The InnoDB Team
* include/ut0rnd.ic:
Fix Bug#11866367:FPE WHEN SETTING INNODB_SPIN_WAIT_DELAY
2011-12-13 The InnoDB Team
* handler/ha_innodb.cc, innodb.test, innodb.result:
Fix Bug#13117023: InnoDB was incrementing the handler_read_key,
also the SSV::ha_read_key_count, at the wrong place.
2011-12-10 The InnoDB Team
* include/page0page.h, page/page0page.c:
Fix Bug#13418887 ERROR IN DIAGNOSTIC FUNCTION PAGE_REC_PRINT()
2011-11-10 The InnoDB Team
* handler/ha_innodb.cc, row/row0ins.c, innodb_replace.test:
Fix Bug#11759688 52020: InnoDB can still deadlock
on just INSERT...ON DUPLICATE KEY a.k.a. the reintroduction of
Bug#7975 deadlock without any locking, simple select and update
2011-11-08 The InnoDB Team
* btr/btr0pcur.c, include/btr0pcur.h, include/btr0pcur.ic:
Fix Bug#13358468 ASSERTION FAILURE IN BTR_PCUR_GET_BLOCK
2011-10-27 The InnoDB Team
* row/row0mysql.c:
Fix Bug #12884631 62146: TABLES ARE LOST FOR DDL
2011-10-25 The InnoDB Team
* handler/ha_innodb.cc, row/row0ins.c:
Fix Bug#13002783 PARTIALLY UNINITIALIZED CASCADE UPDATE VECTOR
2011-10-20 The InnoDB Team
* btr/btr0cur.c:
Fix Bug#13116045 Compilation failure using GCC 4.6.1 in btr/btr0cur.c
2011-10-12 The InnoDB Team
* btr/btr0cur.c, btr/btr0sea.c, buf/buf0buf.c, buf/buf0lru.c,
ha/ha0ha.c, handler/ha_innodb.cc, ibuf/ibuf0ibuf.c, include/btr0sea.h,
include/btr0types.h, include/buf0buf.h, include/ha0ha.h,
include/ha0ha.ic, include/row0upd.ic, include/sync0sync.h,
page/page0page.c, sync/sync0sync.c:
Fix Bug#13006367 62487: innodb takes 3 minutes to clean up
the adaptive hash index at shutdown
2011-10-04 The InnoDB Team
* include/sync0rw.h, sync/sync0rw.c:
Fix Bug#13034534 RQG TESTS FAIL ON WINDOWS WITH CRASH NEAR
RW_LOCK_DEBUG_PRINT
2011-09-20 The InnoDB Team
* row/row0purge.c:
Fix Bug#12963823 CRASH IN PURGE THREAD UNDER UNUSUAL CIRCUMSTANCES
2011-09-12 The InnoDB Team
* row/row0sel.c:
Fix Bug#12601439 CONSISTENT READ FAILURE IN COLUMN PREFIX INDEX
2011-09-08 The InnoDB Team
* btr/btr0cur.c, include/page0page.h, include/row0upd.ic:
Fix Bug#12948130 UNNECESSARY X-LOCKING OF ADAPTIVE HASH INDEX
2011-09-06 The InnoDB Team
* buf/buf0buddy.c:
Fix Bug#12950803 62294: BUF_BUDDY_RELOCATE CALLS GETTIMEOFDAY
WHILE HOLDING BUFFER POOL MUTEX
2011-09-06 The InnoDB Team
* include/trx0undo.h, trx/trx0rec.c, trx/trx0undo.c:
Fix Bug#12547647 UPDATE LOGGING COULD EXCEED LOG PAGE SIZE
2011-08-29 The InnoDB Team
* btr/btr0btr.c, btr/btr0cur.c, fsp/fsp0fsp.c,
include/btr0btr.h, include/btr0cur.h, include/fsp0fsp.h,
include/mtr0mtr.h, include/mtr0mtr.ic, mtr/mtr0mtr.c,
row/row0ins.c, row/row0row.c, row/row0upd.c, trx/trx0undo.c:
Fix Bug#12704861 Corruption after a crash during BLOB update
and other regressions from the fix of Bug#12612184
2011-08-15 The InnoDB Team
* btr/btr0btr.c, btr/btr0cur.c, btr/btr0pcur.c, btr/btr0sea.c,
dict/dict0crea.c, dict/dict0dict.c, ibuf/ibuf0ibuf.c,
include/btr0btr.h, include/btr0btr.ic, include/sync0sync.h,
sync/sync0sync.c:
Fix Bug#11766591 59733: Possible deadlock when buffered changes
are to be discarded in buf_page_create()
2011-08-08 The InnoDB Team
* row/row0sel.c:
......@@ -170,7 +344,7 @@
2011-01-06 The InnoDB Team
* dict/dict0dict.c, handler/ha_innodb.cc, handler/i_s.cc,
include/univ.i:
include/univ.i:
Fix Bug#58643 InnoDB: too long table name
2011-01-06 The InnoDB Team
......@@ -436,7 +610,7 @@
* handler/ha_innodb.cc, include/row0mysql.h, row/row0mysql.c:
Fix Bug#53592: crash replacing duplicates into table after fast
alter table added unique key
alter table added unique key
2010-05-24 The InnoDB Team
......
This diff is collapsed.
This diff is collapsed.
/*****************************************************************************
Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 1996, 2012, Oracle and/or its affiliates. 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
......@@ -127,6 +127,8 @@ btr_pcur_store_position(
ut_a(btr_page_get_next(page, mtr) == FIL_NULL);
ut_a(btr_page_get_prev(page, mtr) == FIL_NULL);
ut_ad(page_is_leaf(page));
ut_ad(page_get_page_no(page) == index->page);
cursor->old_stored = BTR_PCUR_OLD_STORED;
......@@ -253,6 +255,8 @@ btr_pcur_restore_position_func(
cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE,
index, latch_mode, btr_pcur_get_btr_cur(cursor), mtr);
cursor->latch_mode = latch_mode;
cursor->pos_state = BTR_PCUR_IS_POSITIONED;
cursor->block_when_stored = btr_pcur_get_block(cursor);
return(FALSE);
......@@ -272,8 +276,10 @@ btr_pcur_restore_position_func(
file, line, mtr))) {
cursor->pos_state = BTR_PCUR_IS_POSITIONED;
buf_block_dbg_add_level(btr_pcur_get_block(cursor),
SYNC_TREE_NODE);
buf_block_dbg_add_level(
btr_pcur_get_block(cursor),
dict_index_is_ibuf(index)
? SYNC_IBUF_TREE_NODE : SYNC_TREE_NODE);
if (cursor->rel_pos == BTR_PCUR_ON) {
#ifdef UNIV_DEBUG
......@@ -315,13 +321,19 @@ btr_pcur_restore_position_func(
/* Save the old search mode of the cursor */
old_mode = cursor->search_mode;
if (UNIV_LIKELY(cursor->rel_pos == BTR_PCUR_ON)) {
switch (cursor->rel_pos) {
case BTR_PCUR_ON:
mode = PAGE_CUR_LE;
} else if (cursor->rel_pos == BTR_PCUR_AFTER) {
break;
case BTR_PCUR_AFTER:
mode = PAGE_CUR_G;
} else {
ut_ad(cursor->rel_pos == BTR_PCUR_BEFORE);
break;
case BTR_PCUR_BEFORE:
mode = PAGE_CUR_L;
break;
default:
ut_error;
mode = 0;
}
btr_pcur_open_with_no_init_func(index, tuple, mode, latch_mode,
......@@ -330,25 +342,44 @@ btr_pcur_restore_position_func(
/* Restore the old search mode */
cursor->search_mode = old_mode;
if (cursor->rel_pos == BTR_PCUR_ON
&& btr_pcur_is_on_user_rec(cursor)
&& 0 == cmp_dtuple_rec(tuple, btr_pcur_get_rec(cursor),
rec_get_offsets(
btr_pcur_get_rec(cursor), index,
NULL, ULINT_UNDEFINED, &heap))) {
/* We have to store the NEW value for the modify clock, since
the cursor can now be on a different page! But we can retain
the value of old_rec */
if (btr_pcur_is_on_user_rec(cursor)) {
switch (cursor->rel_pos) {
case BTR_PCUR_ON:
if (!cmp_dtuple_rec(
tuple, btr_pcur_get_rec(cursor),
rec_get_offsets(btr_pcur_get_rec(cursor),
index, NULL,
ULINT_UNDEFINED, &heap))) {
/* We have to store the NEW value for
the modify clock, since the cursor can
now be on a different page! But we can
retain the value of old_rec */
cursor->block_when_stored =
btr_pcur_get_block(cursor);
cursor->modify_clock =
buf_block_get_modify_clock(
cursor->block_when_stored);
cursor->old_stored = BTR_PCUR_OLD_STORED;
cursor->block_when_stored = btr_pcur_get_block(cursor);
cursor->modify_clock = buf_block_get_modify_clock(
cursor->block_when_stored);
cursor->old_stored = BTR_PCUR_OLD_STORED;
mem_heap_free(heap);
mem_heap_free(heap);
return(TRUE);
}
return(TRUE);
break;
case BTR_PCUR_BEFORE:
page_cur_move_to_next(btr_pcur_get_page_cur(cursor));
break;
case BTR_PCUR_AFTER:
page_cur_move_to_prev(btr_pcur_get_page_cur(cursor));
break;
#ifdef UNIV_DEBUG
default:
ut_error;
#endif /* UNIV_DEBUG */
}
}
mem_heap_free(heap);
......@@ -396,7 +427,8 @@ btr_pcur_move_to_next_page(
ut_ad(next_page_no != FIL_NULL);
next_block = btr_block_get(space, zip_size, next_page_no,
cursor->latch_mode, mtr);
cursor->latch_mode,
btr_pcur_get_btr_cur(cursor)->index, mtr);
next_page = buf_block_get_frame(next_block);
if (srv_pass_corrupt_table && !next_page) {
......
This diff is collapsed.
......@@ -354,7 +354,6 @@ buf_buddy_relocate(
{
buf_page_t* bpage;
const ulint size = BUF_BUDDY_LOW << i;
ullint usec = ut_time_us(NULL);
mutex_t* mutex;
ulint space;
ulint page_no;
......@@ -442,6 +441,7 @@ buf_buddy_relocate(
if (mutex && buf_page_can_relocate(bpage)) {
/* Relocate the compressed page. */
ullint usec = ut_time_us(NULL);
ut_a(bpage->zip.data == src);
memcpy(dst, src, size);
bpage->zip.data = dst;
......
......@@ -57,7 +57,9 @@ Created 11/5/1995 Heikki Tuuri
/* prototypes for new functions added to ha_innodb.cc */
trx_t* innobase_get_trx();
inline void _increment_page_get_statistics(buf_block_t* block, trx_t* trx)
static inline
void
_increment_page_get_statistics(buf_block_t* block, trx_t* trx)
{
ulint block_hash;
ulint block_hash_byte;
......@@ -829,11 +831,8 @@ buf_chunk_init(
for (i = chunk->size; i--; ) {
buf_block_init(block, frame);
UNIV_MEM_INVALID(block->frame, UNIV_PAGE_SIZE);
#ifdef HAVE_valgrind
/* Wipe contents of frame to eliminate a Purify warning */
memset(block->frame, '\0', UNIV_PAGE_SIZE);
#endif
/* Add the block to the free list */
mutex_enter(&free_list_mutex);
UT_LIST_ADD_LAST(free, buf_pool->free, (&block->page));
......@@ -1043,6 +1042,24 @@ buf_pool_free(void)
{
buf_chunk_t* chunk;
buf_chunk_t* chunks;
buf_page_t* bpage;
bpage = UT_LIST_GET_LAST(buf_pool->LRU);
while (bpage != NULL) {
buf_page_t* prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
enum buf_page_state state = buf_page_get_state(bpage);
ut_ad(buf_page_in_file(bpage));
ut_ad(bpage->in_LRU_list);
if (state != BUF_BLOCK_FILE_PAGE) {
/* We must not have any dirty block. */
ut_ad(state == BUF_BLOCK_ZIP_PAGE);
buf_page_free_descriptor(bpage);
}
bpage = prev_bpage;
}
chunks = buf_pool->chunks;
chunk = chunks + buf_pool->n_chunks;
......@@ -1059,86 +1076,42 @@ buf_pool_free(void)
}
/********************************************************************//**
Drops the adaptive hash index. To prevent a livelock, this function
is only to be called while holding btr_search_latch and while
btr_search_enabled == FALSE. */
Clears the adaptive hash index on all pages in the buffer pool. */
UNIV_INTERN
void
buf_pool_drop_hash_index(void)
/*==========================*/
buf_pool_clear_hash_index(void)
/*===========================*/
{
ibool released_search_latch;
buf_chunk_t* chunks = buf_pool->chunks;
buf_chunk_t* chunk = chunks + buf_pool->n_chunks;
#ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
#endif /* UNIV_SYNC_DEBUG */
ut_ad(!btr_search_enabled);
do {
buf_chunk_t* chunks = buf_pool->chunks;
buf_chunk_t* chunk = chunks + buf_pool->n_chunks;
released_search_latch = FALSE;
while (--chunk >= chunks) {
buf_block_t* block = chunk->blocks;
ulint i = chunk->size;
while (--chunk >= chunks) {
buf_block_t* block = chunk->blocks;
ulint i = chunk->size;
for (; i--; block++) {
/* block->is_hashed cannot be modified
when we have an x-latch on btr_search_latch;
see the comment in buf0buf.h */
for (; i--; block++) {
dict_index_t* index = block->index;
if (buf_block_get_state(block)
!= BUF_BLOCK_FILE_PAGE
|| !block->is_hashed) {
continue;
}
/* We can set block->index = NULL
when we have an x-latch on btr_search_latch;
see the comment in buf0buf.h */
/* To follow the latching order, we
have to release btr_search_latch
before acquiring block->latch. */
rw_lock_x_unlock(&btr_search_latch);
/* When we release the search latch,
we must rescan all blocks, because
some may become hashed again. */
released_search_latch = TRUE;
rw_lock_x_lock(&block->lock);
/* This should be guaranteed by the
callers, which will be holding
btr_search_enabled_mutex. */
ut_ad(!btr_search_enabled);
/* Because we did not buffer-fix the
block by calling buf_block_get_gen(),
it is possible that the block has been
allocated for some other use after
btr_search_latch was released above.
We do not care which file page the
block is mapped to. All we want to do
is to drop any hash entries referring
to the page. */
/* It is possible that
block->page.state != BUF_FILE_PAGE.
Even that does not matter, because
btr_search_drop_page_hash_index() will
check block->is_hashed before doing
anything. block->is_hashed can only
be set on uncompressed file pages. */
btr_search_drop_page_hash_index(block);
rw_lock_x_unlock(&block->lock);
rw_lock_x_lock(&btr_search_latch);
ut_ad(!btr_search_enabled);
if (!index) {
/* Not hashed */
continue;
}
block->index = NULL;
# if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
block->n_pointers = 0;
# endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
}
} while (released_search_latch);
}
}
/********************************************************************//**
......@@ -1283,63 +1256,6 @@ buf_page_set_accessed_make_young(
}
}
/********************************************************************//**
Resets the check_index_page_at_flush field of a page if found in the buffer
pool. */
UNIV_INTERN
void
buf_reset_check_index_page_at_flush(
/*================================*/
ulint space, /*!< in: space id */
ulint offset) /*!< in: page number */
{
buf_block_t* block;
//buf_pool_mutex_enter();
rw_lock_s_lock(&page_hash_latch);
block = (buf_block_t*) buf_page_hash_get(space, offset);
if (block && buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE) {
block->check_index_page_at_flush = FALSE;
}
//buf_pool_mutex_exit();
rw_lock_s_unlock(&page_hash_latch);
}
/********************************************************************//**
Returns the current state of is_hashed of a page. FALSE if the page is
not in the pool. NOTE that this operation does not fix the page in the
pool if it is found there.
@return TRUE if page hash index is built in search system */
UNIV_INTERN
ibool
buf_page_peek_if_search_hashed(
/*===========================*/
ulint space, /*!< in: space id */
ulint offset) /*!< in: page number */
{
buf_block_t* block;
ibool is_hashed;
//buf_pool_mutex_enter();
rw_lock_s_lock(&page_hash_latch);
block = (buf_block_t*) buf_page_hash_get(space, offset);
if (!block || buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE) {
is_hashed = FALSE;
} else {
is_hashed = block->is_hashed;
}
//buf_pool_mutex_exit();
rw_lock_s_unlock(&page_hash_latch);
return(is_hashed);
}
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
/********************************************************************//**
Sets file_page_was_freed TRUE if the page is found in the buffer pool.
......@@ -1623,7 +1539,6 @@ buf_block_init_low(
block->index = NULL;
block->n_hash_helps = 0;
block->is_hashed = FALSE;
block->n_fields = 1;
block->n_bytes = 0;
block->left_side = TRUE;
......@@ -2540,7 +2455,7 @@ buf_page_get_known_nowait(
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
ut_a(block->page.file_page_was_freed == FALSE);
ut_a(mode == BUF_KEEP_OLD || !block->page.file_page_was_freed);
#endif
#ifdef UNIV_IBUF_COUNT_DEBUG
......@@ -3312,14 +3227,8 @@ buf_page_io_complete(
}
}
//enum buf_flush flush_type;
//buf_pool_mutex_enter();
if (io_type == BUF_IO_WRITE) {
//flush_type = buf_page_get_flush_type(bpage);
/* to keep consistency at buf_LRU_insert_zip_clean() */
//if (flush_type == BUF_FLUSH_LRU) { /* optimistic! */
mutex_enter(&LRU_list_mutex);
//}
mutex_enter(&LRU_list_mutex);
}
block_mutex = buf_page_get_mutex_enter(bpage);
ut_a(block_mutex);
......
......@@ -292,7 +292,7 @@ buf_LRU_drop_page_hash_for_tablespace(
//mutex_enter(&((buf_block_t*) bpage)->mutex);
is_fixed = bpage->buf_fix_count > 0
|| !((buf_block_t*) bpage)->is_hashed;
|| !((buf_block_t*) bpage)->index;
//mutex_exit(&((buf_block_t*) bpage)->mutex);
if (is_fixed) {
......@@ -451,7 +451,7 @@ buf_LRU_invalidate_tablespace(
if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
/* This is a compressed-only block
descriptor. Do nothing. */
} else if (((buf_block_t*) bpage)->is_hashed) {
} else if (((buf_block_t*) bpage)->index) {
ulint page_no;
ulint zip_size;
......@@ -465,7 +465,7 @@ buf_LRU_invalidate_tablespace(
mutex_exit(block_mutex);
/* Note that the following call will acquire
an S-latch on the page */
and release an X-latch on the page. */
btr_search_drop_page_hash_when_freed(
id, zip_size, page_no);
......@@ -537,7 +537,7 @@ buf_LRU_mark_space_was_deleted(
for (j = chunk->size; j--; block++) {
if (buf_block_get_state(block)
!= BUF_BLOCK_FILE_PAGE
|| !block->is_hashed
|| !(block->index != NULL)
|| buf_page_get_space(&block->page) != id) {
continue;
}
......
#! /bin/sh
#
# Copyright (c) 2006, 2009, Innobase Oy. All Rights Reserved.
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 USA
#
path=`dirname $0`
. "$path/SETUP.sh"
extra_flags="$pentium_cflags $fast_cflags -g"
extra_configs="$pentium_configs $static_link --with-plugins=innobase"
. "$path/FINISH.sh"
#! /bin/sh
#
# Copyright (c) 2005, 2009, Innobase Oy. All Rights Reserved.
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 USA
#
path=`dirname $0`
. "$path/SETUP.sh" $@ --with-debug=full
extra_flags="$pentium_cflags $debug_cflags"
extra_configs="$pentium_configs $debug_configs --with-plugins=innobase"
. "$path/FINISH.sh"
/*****************************************************************************
Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
Copyright (c) 1996, 2011, Oracle and/or its affiliates. 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
......@@ -899,7 +899,7 @@ dict_truncate_index_tree(
appropriate field in the SYS_INDEXES record: this mini-transaction
marks the B-tree totally truncated */
btr_block_get(space, zip_size, root_page_no, RW_X_LATCH, mtr);
btr_block_get(space, zip_size, root_page_no, RW_X_LATCH, NULL, mtr);
btr_free_root(space, zip_size, root_page_no, mtr);
create:
......
/*****************************************************************************
Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
Copyright (c) 1996, 2011, Oracle and/or its affiliates. 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
......@@ -24,6 +24,8 @@ Created 1/8/1996 Heikki Tuuri
***********************************************************************/
#include "dict0dict.h"
#include "m_string.h"
#include "my_sys.h"
#ifdef UNIV_NONINL
#include "dict0dict.ic"
......@@ -270,15 +272,39 @@ dict_table_stats_lock(
ulint latch_mode) /*!< in: RW_S_LATCH or
RW_X_LATCH */
{
rw_lock_t *want, *got;
ut_ad(table != NULL);
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
switch (latch_mode) {
case RW_S_LATCH:
rw_lock_s_lock(GET_TABLE_STATS_LATCH(table));
/* Lock one of dict_table_stats_latches in S-mode.
Latch is picked using table->id. table->id might be
changed while we are waiting for lock to be grabbed */
for (;;) {
want= GET_TABLE_STATS_LATCH(table);
rw_lock_s_lock(want);
got= GET_TABLE_STATS_LATCH(table);
if (want == got) {
break;
}
rw_lock_s_unlock(want);
}
break;
case RW_X_LATCH:
rw_lock_x_lock(GET_TABLE_STATS_LATCH(table));
/* Lock one of dict_table_stats_latches in X-mode.
Latch is picked using table->id. table->id might be
changed while we are waiting for lock to be grabbed */
for (;;) {
want= GET_TABLE_STATS_LATCH(table);
rw_lock_x_lock(want);
got= GET_TABLE_STATS_LATCH(table);
if (want == got) {
break;
}
rw_lock_x_unlock(want);
}
break;
case RW_NO_LATCH:
/* fall through */
......@@ -1164,12 +1190,21 @@ dict_table_change_id_in_cache(
dict_table_t* table, /*!< in/out: table object already in cache */
dulint new_id) /*!< in: new id to set */
{
dict_table_t table_tmp;
ut_ad(table);
ut_ad(mutex_own(&(dict_sys->mutex)));
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
/* Remove the table from the hash table of id's */
/* Lock is needed to prevent dict_table_stats_latches from
being leaked. dict_table_stats_lock picks one latch using
table->id. We are changing table->id below. That is why
we also should remember the old value to unlock table */
dict_table_stats_lock(table, RW_X_LATCH);
table_tmp= *table;
HASH_DELETE(dict_table_t, id_hash, dict_sys->table_id_hash,
ut_fold_dulint(table->id), table);
table->id = new_id;
......@@ -1177,6 +1212,8 @@ dict_table_change_id_in_cache(
/* Add the table back to the hash table */
HASH_INSERT(dict_table_t, id_hash, dict_sys->table_id_hash,
ut_fold_dulint(table->id), table);
dict_table_stats_unlock(&table_tmp, RW_X_LATCH);
}
/**********************************************************************//**
......@@ -1724,7 +1761,9 @@ dict_index_add_to_cache(
new_index->stat_n_leaf_pages = 1;
new_index->page = page_no;
rw_lock_create(&new_index->lock, SYNC_INDEX_TREE);
rw_lock_create(&new_index->lock,
dict_index_is_ibuf(index)
? SYNC_IBUF_INDEX_TREE : SYNC_INDEX_TREE);
if (!UNIV_UNLIKELY(new_index->type & DICT_UNIVERSAL)) {
......@@ -2338,6 +2377,8 @@ dict_foreign_free(
/*==============*/
dict_foreign_t* foreign) /*!< in, own: foreign key struct */
{
ut_a(foreign->foreign_table->n_foreign_key_checks_running == 0);
mem_heap_free(foreign->heap);
}
......@@ -4306,19 +4347,26 @@ dict_reload_statistics(
heap = mem_heap_create(1000);
while (index) {
mtr_t mtr;
if (table->is_corrupt) {
ut_a(srv_pass_corrupt_table);
mem_heap_free(heap);
return(FALSE);
}
size = btr_get_size(index, BTR_TOTAL_SIZE);
mtr_start(&mtr);
mtr_s_lock(dict_index_get_lock(index), &mtr);
size = btr_get_size(index, BTR_TOTAL_SIZE, &mtr);
index->stat_index_size = size;
*sum_of_index_sizes += size;
size = btr_get_size(index, BTR_N_LEAF_PAGES);
size = btr_get_size(index, BTR_N_LEAF_PAGES, &mtr);
mtr_commit(&mtr);
if (size == 0) {
/* The root node of the tree is a leaf */
......@@ -4668,16 +4716,27 @@ dict_update_statistics(
(srv_force_recovery < SRV_FORCE_NO_IBUF_MERGE
|| (srv_force_recovery < SRV_FORCE_NO_LOG_REDO
&& dict_index_is_clust(index)))) {
mtr_t mtr;
ulint size;
size = btr_get_size(index, BTR_TOTAL_SIZE);
index->stat_index_size = size;
mtr_start(&mtr);
mtr_s_lock(dict_index_get_lock(index), &mtr);
sum_of_index_sizes += size;
size = btr_get_size(index, BTR_TOTAL_SIZE, &mtr);
size = btr_get_size(index, BTR_N_LEAF_PAGES);
if (size != ULINT_UNDEFINED) {
sum_of_index_sizes += size;
index->stat_index_size = size;
size = btr_get_size(
index, BTR_N_LEAF_PAGES, &mtr);
}
mtr_commit(&mtr);
if (size == 0) {
switch (size) {
case ULINT_UNDEFINED:
goto fake_statistics;
case 0:
/* The root node of the tree is a leaf */
size = 1;
}
......@@ -4694,6 +4753,7 @@ dict_update_statistics(
various means, also via secondary indexes. */
ulint i;
fake_statistics:
sum_of_index_sizes++;
index->stat_index_size = index->stat_n_leaf_pages = 1;
......
......@@ -430,7 +430,7 @@ dict_check_tablespaces_and_store_max_id(
object and check that the .ibd file exists. */
fil_open_single_table_tablespace(FALSE, space_id,
flags, name);
flags, name, NULL);
}
mem_free(name);
......@@ -1023,7 +1023,7 @@ dict_load_table(
if (!fil_open_single_table_tablespace(
TRUE, space,
flags == DICT_TF_COMPACT ? 0 :
flags & ~(~0 << DICT_TF_BITS), name)) {
flags & ~(~0 << DICT_TF_BITS), name, NULL)) {
/* We failed to find a sensible
tablespace file */
......
......@@ -183,7 +183,7 @@ struct fil_space_struct {
.ibd file of tablespace and want to
stop temporarily posting of new i/o
requests on the file */
ibool stop_ibuf_merges;
ibool stop_new_ops;
/*!< we set this TRUE when we start
deleting a single-table tablespace */
ibool is_being_deleted;
......@@ -208,12 +208,13 @@ struct fil_space_struct {
ulint n_pending_flushes; /*!< this is positive when flushing
the tablespace to disk; dropping of the
tablespace is forbidden if this is positive */
ulint n_pending_ibuf_merges;/*!< this is positive
when merging insert buffer entries to
a page so that we may need to access
the ibuf bitmap page in the
tablespade: dropping of the tablespace
is forbidden if this is positive */
ulint n_pending_ops;/*!< this is positive when we
have pending operations against this
tablespace. The pending operations can
be ibuf merges or lock validation code
trying to read a block.
Dropping of the tablespace is forbidden
if this is positive */
hash_node_t hash; /*!< hash chain node */
hash_node_t name_hash;/*!< hash chain the name_hash table */
#ifndef UNIV_HOTBACKUP
......@@ -928,11 +929,6 @@ fil_mutex_enter_and_prepare_for_io(
return;
}
if (fil_system->n_open < fil_system->max_n_open) {
return;
}
space = fil_space_get_by_id(space_id);
if (space != NULL && space->stop_ios) {
......@@ -949,6 +945,25 @@ fil_mutex_enter_and_prepare_for_io(
mutex_exit(&fil_system->mutex);
#ifndef UNIV_HOTBACKUP
/* Wake the i/o-handler threads to make sure pending
i/o's are performed */
os_aio_simulated_wake_handler_threads();
/* The sleep here is just to give IO helper threads a
bit of time to do some work. It is not required that
all IO related to the tablespace being renamed must
be flushed here as we do fil_flush() in
fil_rename_tablespace() as well. */
os_thread_sleep(20000);
#endif /* UNIV_HOTBACKUP */
/* Flush tablespaces so that we can close modified
files in the LRU list */
fil_flush_file_spaces(FIL_TABLESPACE);
os_thread_sleep(20000);
count2++;
......@@ -956,6 +971,11 @@ fil_mutex_enter_and_prepare_for_io(
goto retry;
}
if (fil_system->n_open < fil_system->max_n_open) {
return;
}
/* If the file is already open, no need to do anything; if the space
does not exist, we handle the situation in the function which called
this function */
......@@ -1228,7 +1248,7 @@ fil_space_create(
}
space->stop_ios = FALSE;
space->stop_ibuf_merges = FALSE;
space->stop_new_ops = FALSE;
space->is_being_deleted = FALSE;
space->purpose = purpose;
space->size = 0;
......@@ -1237,7 +1257,7 @@ fil_space_create(
space->n_reserved_extents = 0;
space->n_pending_flushes = 0;
space->n_pending_ibuf_merges = 0;
space->n_pending_ops = 0;
UT_LIST_INIT(space->chain);
space->magic_n = FIL_SPACE_MAGIC_N;
......@@ -1840,13 +1860,12 @@ fil_read_flushed_lsn_and_arch_log_no(
#ifndef UNIV_HOTBACKUP
/*******************************************************************//**
Increments the count of pending insert buffer page merges, if space is not
being deleted.
@return TRUE if being deleted, and ibuf merges should be skipped */
Increments the count of pending operation, if space is not being deleted.
@return TRUE if being deleted, and operation should be skipped */
UNIV_INTERN
ibool
fil_inc_pending_ibuf_merges(
/*========================*/
fil_inc_pending_ops(
/*================*/
ulint id) /*!< in: space id */
{
fil_space_t* space;
......@@ -1862,13 +1881,13 @@ fil_inc_pending_ibuf_merges(
(ulong) id);
}
if (space == NULL || space->stop_ibuf_merges) {
if (space == NULL || space->stop_new_ops) {
mutex_exit(&fil_system->mutex);
return(TRUE);
}
space->n_pending_ibuf_merges++;
space->n_pending_ops++;
mutex_exit(&fil_system->mutex);
......@@ -1876,11 +1895,11 @@ fil_inc_pending_ibuf_merges(
}
/*******************************************************************//**
Decrements the count of pending insert buffer page merges. */
Decrements the count of pending operations. */
UNIV_INTERN
void
fil_decr_pending_ibuf_merges(
/*=========================*/
fil_decr_pending_ops(
/*=================*/
ulint id) /*!< in: space id */
{
fil_space_t* space;
......@@ -1891,13 +1910,13 @@ fil_decr_pending_ibuf_merges(
if (space == NULL) {
fprintf(stderr,
"InnoDB: Error: decrementing ibuf merge of a"
" dropped tablespace %lu\n",
"InnoDB: Error: decrementing pending operation"
" of a dropped tablespace %lu\n",
(ulong) id);
}
if (space != NULL) {
space->n_pending_ibuf_merges--;
space->n_pending_ops--;
}
mutex_exit(&fil_system->mutex);
......@@ -2187,15 +2206,15 @@ fil_delete_tablespace(
char* path;
ut_a(id != 0);
stop_ibuf_merges:
stop_new_ops:
mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(id);
if (space != NULL) {
space->stop_ibuf_merges = TRUE;
space->stop_new_ops = TRUE;
if (space->n_pending_ibuf_merges == 0) {
if (space->n_pending_ops == 0) {
mutex_exit(&fil_system->mutex);
count = 0;
......@@ -2209,9 +2228,10 @@ fil_delete_tablespace(
ut_print_filename(stderr, space->name);
fprintf(stderr, ",\n"
"InnoDB: but there are %lu pending"
" ibuf merges on it.\n"
" operations (most likely ibuf merges)"
" on it.\n"
"InnoDB: Loop %lu.\n",
(ulong) space->n_pending_ibuf_merges,
(ulong) space->n_pending_ops,
(ulong) count);
}
......@@ -2220,7 +2240,7 @@ fil_delete_tablespace(
os_thread_sleep(20000);
count++;
goto stop_ibuf_merges;
goto stop_new_ops;
}
}
......@@ -2246,7 +2266,7 @@ fil_delete_tablespace(
}
ut_a(space);
ut_a(space->n_pending_ibuf_merges == 0);
ut_a(space->n_pending_ops == 0);
space->is_being_deleted = TRUE;
......@@ -2523,7 +2543,7 @@ fil_rename_tablespace(
retry:
count++;
if (count > 1000) {
if (!(count % 1000)) {
ut_print_timestamp(stderr);
fputs(" InnoDB: Warning: problems renaming ", stderr);
ut_print_filename(stderr, old_name);
......@@ -3124,8 +3144,11 @@ fil_open_single_table_tablespace(
accessing the first page of the file */
ulint id, /*!< in: space id */
ulint flags, /*!< in: tablespace flags */
const char* name) /*!< in: table name in the
const char* name, /*!< in: table name in the
databasename/tablename format */
trx_t* trx) /*!< in: transaction. This is only used
for IMPORT TABLESPACE, must be NULL
otherwise */
{
os_file_t file;
char* filepath;
......@@ -3342,6 +3365,11 @@ fil_open_single_table_tablespace(
/* over write space id of all pages */
rec_offs_init(offsets_);
/* Unlock the data dictionary to not block queries
accessing other tables */
ut_a(trx);
row_mysql_unlock_data_dictionary(trx);
fprintf(stderr, "InnoDB: Progress in %%:");
for (offset = 0; offset < free_limit_bytes;
......@@ -3543,6 +3571,9 @@ fil_open_single_table_tablespace(
fprintf(stderr, " done.\n");
/* Reacquire the data dictionary lock */
row_mysql_lock_data_dictionary(trx);
/* update SYS_INDEXES set root page */
index = dict_table_get_first_index(table);
while (index) {
......@@ -3835,7 +3866,7 @@ fil_open_single_table_tablespace(
level = btr_page_get_level(page, &mtr);
new_block = btr_page_alloc(index, 0, FSP_NO_DIR, level, &mtr);
new_block = btr_page_alloc(index, 0, FSP_NO_DIR, level, &mtr, &mtr);
new_page = buf_block_get_frame(new_block);
new_page_zip = buf_block_get_page_zip(new_block);
btr_page_create(new_block, new_page_zip, index, level, &mtr);
......@@ -3883,7 +3914,7 @@ fil_open_single_table_tablespace(
split_rec = page_get_middle_rec(page);
new_block = btr_page_alloc(index, page_no + 1, FSP_UP,
btr_page_get_level(page, &mtr), &mtr);
btr_page_get_level(page, &mtr), &mtr, &mtr);
new_page = buf_block_get_frame(new_block);
new_page_zip = buf_block_get_page_zip(new_block);
btr_page_create(new_block, new_page_zip, index,
......
This diff is collapsed.
/*****************************************************************************
Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
Copyright (c) 1994, 2011, Oracle and/or its affiliates. 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
......@@ -88,40 +88,6 @@ ha_create_func(
return(table);
}
/*************************************************************//**
Empties a hash table and frees the memory heaps. */
UNIV_INTERN
void
ha_clear(
/*=====*/
hash_table_t* table) /*!< in, own: hash table */
{
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 */
#ifndef UNIV_HOTBACKUP
/* Free the memory heaps. */
n = table->n_mutexes;
for (i = 0; i < n; i++) {
mem_heap_free(table->heaps[i]);
}
#endif /* !UNIV_HOTBACKUP */
/* Clear the hash table. */
n = hash_get_n_cells(table);
for (i = 0; i < n; i++) {
hash_get_nth_cell(table, i)->node = NULL;
}
}
/*************************************************************//**
Inserts an entry into a hash table. If an entry with the same fold number
is found, its node is updated to point to the new data, and no new node
......@@ -140,7 +106,7 @@ ha_insert_for_fold_func(
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
buf_block_t* block, /*!< in: buffer block containing the data */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
void* data) /*!< in: data, must not be NULL */
const rec_t* data) /*!< in: data, must not be NULL */
{
hash_cell_t* cell;
ha_node_t* node;
......@@ -153,7 +119,11 @@ ha_insert_for_fold_func(
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
ut_a(block->frame == page_align(data));
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
#ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
#endif /* UNIV_SYNC_DEBUG */
ASSERT_HASH_MUTEX_OWN(table, fold);
ut_ad(btr_search_enabled);
hash = hash_calc_hash(fold, table);
......@@ -173,7 +143,6 @@ ha_insert_for_fold_func(
prev_block->n_pointers--;
block->n_pointers++;
}
ut_ad(!btr_search_fully_disabled);
# endif /* !UNIV_HOTBACKUP */
prev_node->block = block;
......@@ -186,13 +155,6 @@ ha_insert_for_fold_func(
prev_node = prev_node->next;
}
/* We are in the process of disabling hash index, do not add
new chain node */
if (!btr_search_enabled) {
ut_ad(!btr_search_fully_disabled);
return(TRUE);
}
/* We have to allocate a new chain node */
node = mem_heap_alloc(hash_get_heap(table, fold), sizeof(ha_node_t));
......@@ -250,6 +212,10 @@ ha_delete_hash_node(
{
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_EX));
#endif /* UNIV_SYNC_DEBUG */
ut_ad(btr_search_enabled);
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
# ifndef UNIV_HOTBACKUP
if (table->adaptive) {
......@@ -272,11 +238,11 @@ ha_search_and_update_if_found_func(
/*===============================*/
hash_table_t* table, /*!< in/out: hash table */
ulint fold, /*!< in: folded value of the searched data */
void* data, /*!< in: pointer to the data */
const rec_t* data, /*!< in: pointer to the data */
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
buf_block_t* new_block,/*!< in: block containing new_data */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
void* new_data)/*!< in: new pointer to the data */
const rec_t* new_data)/*!< in: new pointer to the data */
{
ha_node_t* node;
......@@ -286,6 +252,13 @@ ha_search_and_update_if_found_func(
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
ut_a(new_block->frame == page_align(new_data));
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
#ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
#endif /* UNIV_SYNC_DEBUG */
if (!btr_search_enabled) {
return;
}
node = ha_search_with_data(table, fold, data);
......@@ -322,6 +295,10 @@ ha_remove_all_nodes_to_page(
ut_ad(table);
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
ASSERT_HASH_MUTEX_OWN(table, fold);
#ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
#endif /* UNIV_SYNC_DEBUG */
ut_ad(btr_search_enabled);
node = ha_chain_get_first(table, fold);
......
This diff is collapsed.
......@@ -136,6 +136,7 @@ class ha_innobase: public handler
int close(void);
double scan_time();
double read_time(uint index, uint ranges, ha_rows rows);
my_bool is_fake_change_enabled(THD *thd);
bool is_corrupt() const;
int write_row(uchar * buf);
......
/*****************************************************************************
Copyright (c) 2005, 2010, Innobase Oy. All Rights Reserved.
Copyright (c) 2005, 2012, Oracle and/or its affiliates. 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
......@@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*****************************************************************************/
......@@ -1024,7 +1024,9 @@ ha_innobase::prepare_drop_index(
goto func_exit;
}
rw_lock_x_lock(dict_index_get_lock(index));
index->to_be_dropped = TRUE;
rw_lock_x_unlock(dict_index_get_lock(index));
}
/* If FOREIGN_KEY_CHECKS = 1 you may not drop an index defined
......@@ -1143,7 +1145,9 @@ ha_innobase::prepare_drop_index(
= dict_table_get_first_index(prebuilt->table);
do {
rw_lock_x_lock(dict_index_get_lock(index));
index->to_be_dropped = FALSE;
rw_lock_x_unlock(dict_index_get_lock(index));
index = dict_table_get_next_index(index);
} while (index);
}
......@@ -1209,7 +1213,9 @@ ha_innobase::final_drop_index(
for (index = dict_table_get_first_index(prebuilt->table);
index; index = dict_table_get_next_index(index)) {
rw_lock_x_lock(dict_index_get_lock(index));
index->to_be_dropped = FALSE;
rw_lock_x_unlock(dict_index_get_lock(index));
}
goto func_exit;
......
......@@ -768,7 +768,7 @@ i_s_innodb_buffer_pool_pages_index_fill(
table->field[2]->store(block->page.offset);
table->field[3]->store(page_get_n_recs(frame));
table->field[4]->store(page_get_data_size(frame));
table->field[5]->store(block->is_hashed);
table->field[5]->store(block->index != NULL); /* is_hashed */
table->field[6]->store(block->page.access_time);
table->field[7]->store(block->page.newest_modification != 0);
table->field[8]->store(block->page.oldest_modification != 0);
......
/*****************************************************************************
Copyright (c) 1997, 2009, Innobase Oy. All Rights Reserved.
Copyright (c) 1997, 2012, Oracle and/or its affiliates. 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
......@@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*****************************************************************************/
......@@ -356,7 +356,7 @@ ibuf_tree_root_get(
block = buf_page_get(
IBUF_SPACE_ID, 0, FSP_IBUF_TREE_ROOT_PAGE_NO, RW_X_LATCH, mtr);
buf_block_dbg_add_level(block, SYNC_TREE_NODE);
buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE);
return(buf_block_get_frame(block));
}
......@@ -498,7 +498,7 @@ ibuf_init_at_db_start(void)
block = buf_page_get(
IBUF_SPACE_ID, 0, FSP_IBUF_TREE_ROOT_PAGE_NO,
RW_X_LATCH, &mtr);
buf_block_dbg_add_level(block, SYNC_TREE_NODE);
buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE);
root = buf_block_get_frame(block);
}
......@@ -1725,14 +1725,14 @@ ulint
ibuf_add_free_page(void)
/*====================*/
{
mtr_t mtr;
page_t* header_page;
ulint flags;
ulint zip_size;
ulint page_no;
page_t* page;
page_t* root;
page_t* bitmap_page;
mtr_t mtr;
page_t* header_page;
ulint flags;
ulint zip_size;
buf_block_t* block;
page_t* page;
page_t* root;
page_t* bitmap_page;
mtr_start(&mtr);
......@@ -1753,34 +1753,24 @@ ibuf_add_free_page(void)
of a deadlock. This is the reason why we created a special ibuf
header page apart from the ibuf tree. */
page_no = fseg_alloc_free_page(
block = fseg_alloc_free_page(
header_page + IBUF_HEADER + IBUF_TREE_SEG_HEADER, 0, FSP_UP,
&mtr);
if (page_no == FIL_NULL) {
if (block == NULL) {
mtr_commit(&mtr);
return(DB_STRONG_FAIL);
}
{
buf_block_t* block;
block = buf_page_get(
IBUF_SPACE_ID, 0, page_no, RW_X_LATCH, &mtr);
buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW);
page = buf_block_get_frame(block);
}
ut_ad(rw_lock_get_x_lock_count(&block->lock) == 1);
ibuf_enter();
mutex_enter(&ibuf_mutex);
root = ibuf_tree_root_get(&mtr);
buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE_NEW);
page = buf_block_get_frame(block);
/* Add the page to the free list and update the ibuf size data */
flst_add_last(root + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST,
......@@ -1796,10 +1786,11 @@ ibuf_add_free_page(void)
(level 2 page) */
bitmap_page = ibuf_bitmap_get_map_page(
IBUF_SPACE_ID, page_no, zip_size, &mtr);
IBUF_SPACE_ID, buf_block_get_page_no(block), zip_size, &mtr);
ibuf_bitmap_page_set_bits(
bitmap_page, page_no, zip_size, IBUF_BITMAP_IBUF, TRUE, &mtr);
bitmap_page, buf_block_get_page_no(block), zip_size,
IBUF_BITMAP_IBUF, TRUE, &mtr);
mtr_commit(&mtr);
......@@ -1900,8 +1891,7 @@ ibuf_remove_free_page(void)
block = buf_page_get(
IBUF_SPACE_ID, 0, page_no, RW_X_LATCH, &mtr);
buf_block_dbg_add_level(block, SYNC_TREE_NODE);
buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE);
page = buf_block_get_frame(block);
}
......@@ -2095,7 +2085,15 @@ ibuf_get_merge_page_nos(
} else {
rec_page_no = ibuf_rec_get_page_no(rec);
rec_space_id = ibuf_rec_get_space(rec);
ut_ad(rec_page_no > IBUF_TREE_ROOT_PAGE_NO);
/* In the system tablespace, the smallest
possible secondary index leaf page number is
bigger than IBUF_TREE_ROOT_PAGE_NO (4). In
other tablespaces, the clustered index tree is
created at page 3, which makes page 4 the
smallest possible secondary index leaf page
(and that only after DROP INDEX). */
ut_ad(rec_page_no
> IBUF_TREE_ROOT_PAGE_NO - (rec_space_id != 0));
}
#ifdef UNIV_IBUF_DEBUG
......@@ -2413,7 +2411,7 @@ ibuf_get_volume_buffered(
block = buf_page_get(
IBUF_SPACE_ID, 0, prev_page_no, RW_X_LATCH, mtr);
buf_block_dbg_add_level(block, SYNC_TREE_NODE);
buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE);
prev_page = buf_block_get_frame(block);
......@@ -2487,7 +2485,7 @@ ibuf_get_volume_buffered(
block = buf_page_get(
IBUF_SPACE_ID, 0, next_page_no, RW_X_LATCH, mtr);
buf_block_dbg_add_level(block, SYNC_TREE_NODE);
buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE);
next_page = buf_block_get_frame(block);
......@@ -2980,7 +2978,7 @@ ibuf_insert_to_index_page(
ut_ad(ibuf_inside());
ut_ad(dtuple_check_typed(entry));
ut_ad(!buf_block_align(page)->is_hashed);
ut_ad(!buf_block_align(page)->index);
if (UNIV_UNLIKELY(dict_table_is_comp(index->table)
!= (ibool)!!page_is_comp(page))) {
......@@ -3255,6 +3253,7 @@ ibuf_merge_or_delete_for_page(
ut_ad(!block || buf_block_get_space(block) == space);
ut_ad(!block || buf_block_get_page_no(block) == page_no);
ut_ad(!block || buf_block_get_zip_size(block) == zip_size);
ut_ad(!block || buf_block_get_io_fix(block) == BUF_IO_READ);
if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE
|| trx_sys_hdr_page(space, page_no)) {
......@@ -3289,7 +3288,7 @@ ibuf_merge_or_delete_for_page(
function. When the counter is > 0, that prevents tablespace
from being dropped. */
tablespace_being_deleted = fil_inc_pending_ibuf_merges(space);
tablespace_being_deleted = fil_inc_pending_ops(space);
if (UNIV_UNLIKELY(tablespace_being_deleted)) {
/* Do not try to read the bitmap page from space;
......@@ -3313,7 +3312,7 @@ ibuf_merge_or_delete_for_page(
mtr_commit(&mtr);
if (!tablespace_being_deleted) {
fil_decr_pending_ibuf_merges(space);
fil_decr_pending_ops(space);
}
return;
......@@ -3410,7 +3409,13 @@ ibuf_merge_or_delete_for_page(
ut_a(success);
buf_block_dbg_add_level(block, SYNC_TREE_NODE);
/* This is a user page (secondary index leaf page),
but we pretend that it is a change buffer page in
order to obey the latching order. This should be OK,
because buffered changes are applied immediately while
the block is io-fixed. Other threads must not try to
latch an io-fixed block. */
buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE);
}
/* Position pcur in the insert buffer at the first entry for this
......@@ -3539,7 +3544,7 @@ ibuf_merge_or_delete_for_page(
if (update_ibuf_bitmap && !tablespace_being_deleted) {
fil_decr_pending_ibuf_merges(space);
fil_decr_pending_ops(space);
}
ibuf_exit();
......
/*****************************************************************************
Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 1994, 2012, Oracle and/or its affiliates. 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
......@@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*****************************************************************************/
......@@ -188,26 +188,45 @@ btr_block_get_func(
ulint mode, /*!< in: latch mode */
const char* file, /*!< in: file name */
ulint line, /*!< in: line where called */
mtr_t* mtr) /*!< in/out: mtr */
__attribute__((nonnull));
# ifdef UNIV_SYNC_DEBUG
const dict_index_t* index, /*!< in: index tree, may be NULL
if it is not an insert buffer tree */
# endif /* UNIV_SYNC_DEBUG */
mtr_t* mtr); /*!< in/out: mini-transaction */
# ifdef UNIV_SYNC_DEBUG
/** Gets a buffer page and declares its latching order level.
@param space tablespace identifier
@param zip_size compressed page size in bytes or 0 for uncompressed pages
@param page_no page number
@param mode latch mode
@param index index tree, may be NULL if not the insert buffer tree
@param mtr mini-transaction handle
@return the block descriptor */
# define btr_block_get(space,zip_size,page_no,mode,mtr) \
# define btr_block_get(space,zip_size,page_no,mode,index,mtr) \
btr_block_get_func(space,zip_size,page_no,mode, \
__FILE__,__LINE__,index,mtr)
# else /* UNIV_SYNC_DEBUG */
/** Gets a buffer page and declares its latching order level.
@param space tablespace identifier
@param zip_size compressed page size in bytes or 0 for uncompressed pages
@param page_no page number
@param mode latch mode
@param idx index tree, may be NULL if not the insert buffer tree
@param mtr mini-transaction handle
@return the block descriptor */
# define btr_block_get(space,zip_size,page_no,mode,idx,mtr) \
btr_block_get_func(space,zip_size,page_no,mode,__FILE__,__LINE__,mtr)
# endif /* UNIV_SYNC_DEBUG */
/** Gets a buffer page and declares its latching order level.
@param space tablespace identifier
@param zip_size compressed page size in bytes or 0 for uncompressed pages
@param page_no page number
@param mode latch mode
@param idx index tree, may be NULL if not the insert buffer tree
@param mtr mini-transaction handle
@return the uncompressed page frame */
# define btr_page_get(space,zip_size,page_no,mode,mtr) \
buf_block_get_frame(btr_block_get(space,zip_size,page_no,mode,mtr))
# define btr_page_get(space,zip_size,page_no,mode,idx,mtr) \
buf_block_get_frame(btr_block_get(space,zip_size,page_no,mode,idx,mtr))
/**************************************************************//**
Sets the index id field of a page. */
UNIV_INLINE
......@@ -378,8 +397,7 @@ btr_free_root(
ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
ulint root_page_no, /*!< in: root page number */
mtr_t* mtr); /*!< in: a mini-transaction which has already
been started */
mtr_t* mtr); /*!< in/out: mini-transaction */
/*************************************************************//**
Makes tree one level higher by splitting the root, and inserts
the tuple. It is assumed that mtr contains an x-latch on the tree.
......@@ -588,17 +606,23 @@ btr_parse_page_reorganize(
#ifndef UNIV_HOTBACKUP
/**************************************************************//**
Gets the number of pages in a B-tree.
@return number of pages */
@return number of pages, or ULINT_UNDEFINED if the index is unavailable */
UNIV_INTERN
ulint
btr_get_size(
/*=========*/
dict_index_t* index, /*!< in: index */
ulint flag); /*!< in: BTR_N_LEAF_PAGES or BTR_TOTAL_SIZE */
ulint flag, /*!< in: BTR_N_LEAF_PAGES or BTR_TOTAL_SIZE */
mtr_t* mtr) /*!< in/out: mini-transaction where index
is s-latched */
__attribute__((nonnull, warn_unused_result));
/**************************************************************//**
Allocates a new file page to be used in an index tree. NOTE: we assume
that the caller has made the reservation for free extents!
@return new allocated block, x-latched; NULL if out of space */
@retval NULL if no page could be allocated
@retval block, rw_lock_x_lock_count(&block->lock) == 1 if allocation succeeded
(init_mtr == mtr, or the page was not previously freed in mtr)
@retval block (not allocated or initialized) otherwise */
UNIV_INTERN
buf_block_t*
btr_page_alloc(
......@@ -609,7 +633,12 @@ btr_page_alloc(
page split is made */
ulint level, /*!< in: level where the page is placed
in the tree */
mtr_t* mtr); /*!< in: mtr */
mtr_t* mtr, /*!< in/out: mini-transaction
for the allocation */
mtr_t* init_mtr) /*!< in/out: mini-transaction
for x-latching and initializing
the page */
__attribute__((nonnull, warn_unused_result));
/**************************************************************//**
Frees a file page used in an index tree. NOTE: cannot free field external
storage pages because the page must contain info on its level. */
......
/*****************************************************************************
Copyright (c) 1994, 2010, Innobase Oy. All Rights Reserved.
Copyright (c) 1994, 2011, Oracle and/or its affiliates. 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,6 +48,10 @@ btr_block_get_func(
ulint mode, /*!< in: latch mode */
const char* file, /*!< in: file name */
ulint line, /*!< in: line where called */
#ifdef UNIV_SYNC_DEBUG
const dict_index_t* index, /*!< in: index tree, may be NULL
if it is not an insert buffer tree */
#endif /* UNIV_SYNC_DEBUG */
mtr_t* mtr) /*!< in/out: mtr */
{
buf_block_t* block;
......@@ -59,7 +63,9 @@ btr_block_get_func(
if (block && mode != RW_NO_LATCH) {
buf_block_dbg_add_level(block, SYNC_TREE_NODE);
buf_block_dbg_add_level(
block, index != NULL && dict_index_is_ibuf(index)
? SYNC_IBUF_TREE_NODE : SYNC_TREE_NODE);
}
return(block);
......
/*****************************************************************************
Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 1994, 2012, Oracle and/or its affiliates. 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
......@@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*****************************************************************************/
......@@ -326,16 +326,6 @@ btr_cur_pessimistic_update(
que_thr_t* thr, /*!< in: query thread */
mtr_t* mtr); /*!< in: mtr; must be committed before
latching any further pages */
/*****************************************************************
Commits and restarts a mini-transaction so that it will retain an
x-lock on index->lock and the cursor page. */
UNIV_INTERN
void
btr_cur_mtr_commit_and_start(
/*=========================*/
btr_cur_t* cursor, /*!< in: cursor */
mtr_t* mtr) /*!< in/out: mini-transaction */
__attribute__((nonnull));
/***********************************************************//**
Marks a clustered index record deleted. Writes an undo log record to
undo log on this delete marking. Writes in the trx id field the id
......@@ -522,6 +512,27 @@ btr_cur_disown_inherited_fields(
const upd_t* update, /*!< in: update vector */
mtr_t* mtr) /*!< in/out: mini-transaction */
__attribute__((nonnull(2,3,4,5,6)));
/** Operation code for btr_store_big_rec_extern_fields(). */
enum blob_op {
/** Store off-page columns for a freshly inserted record */
BTR_STORE_INSERT = 0,
/** Store off-page columns for an insert by update */
BTR_STORE_INSERT_UPDATE,
/** Store off-page columns for an update */
BTR_STORE_UPDATE
};
/*******************************************************************//**
Determine if an operation on off-page columns is an update.
@return TRUE if op != BTR_STORE_INSERT */
UNIV_INLINE
ibool
btr_blob_op_is_update(
/*==================*/
enum blob_op op) /*!< in: operation */
__attribute__((warn_unused_result));
/*******************************************************************//**
Stores the fields in big_rec_vec to the tablespace and puts pointers to
them in rec. The extern flags in rec will have to be set beforehand.
......@@ -529,52 +540,23 @@ The fields are stored on pages allocated from leaf node
file segment of the index tree.
@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
UNIV_INTERN
ulint
btr_store_big_rec_extern_fields_func(
/*=================================*/
enum db_err
btr_store_big_rec_extern_fields(
/*============================*/
dict_index_t* index, /*!< in: index of rec; the index tree
MUST be X-latched */
buf_block_t* rec_block, /*!< in/out: block containing rec */
rec_t* rec, /*!< in: record */
rec_t* rec, /*!< in/out: record */
const ulint* offsets, /*!< in: rec_get_offsets(rec, index);
the "external storage" flags in offsets
will not correspond to rec when
this function returns */
#ifdef UNIV_DEBUG
mtr_t* local_mtr, /*!< in: mtr containing the
latch to rec and to the tree */
#endif /* UNIV_DEBUG */
#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
ibool update_in_place,/*! in: TRUE if the record is updated
in place (not delete+insert) */
#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
const big_rec_t*big_rec_vec) /*!< in: vector containing fields
const big_rec_t*big_rec_vec, /*!< in: vector containing fields
to be stored externally */
__attribute__((nonnull));
/** Stores the fields in big_rec_vec to the tablespace and puts pointers to
them in rec. The extern flags in rec will have to be set beforehand.
The fields are stored on pages allocated from leaf node
file segment of the index tree.
@param index in: clustered index; MUST be X-latched by mtr
@param b in/out: block containing rec; MUST be X-latched by mtr
@param rec in/out: clustered index record
@param offsets in: rec_get_offsets(rec, index);
the "external storage" flags in offsets will not be adjusted
@param mtr in: mini-transaction that holds x-latch on index and b
@param upd in: TRUE if the record is updated in place (not delete+insert)
@param big in: vector containing fields to be stored externally
@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
#ifdef UNIV_DEBUG
# define btr_store_big_rec_extern_fields(index,b,rec,offsets,mtr,upd,big) \
btr_store_big_rec_extern_fields_func(index,b,rec,offsets,mtr,upd,big)
#elif defined UNIV_BLOB_LIGHT_DEBUG
# define btr_store_big_rec_extern_fields(index,b,rec,offsets,mtr,upd,big) \
btr_store_big_rec_extern_fields_func(index,b,rec,offsets,upd,big)
#else
# define btr_store_big_rec_extern_fields(index,b,rec,offsets,mtr,upd,big) \
btr_store_big_rec_extern_fields_func(index,b,rec,offsets,big)
#endif
mtr_t* btr_mtr, /*!< in: mtr containing the
latches to the clustered index */
enum blob_op op) /*! in: operation code */
__attribute__((nonnull, warn_unused_result));
/*******************************************************************//**
Frees the space in an externally stored field to the file space
......
/*****************************************************************************
Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 1994, 2012, Oracle and/or its affiliates. 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
......@@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*****************************************************************************/
......@@ -139,7 +139,7 @@ btr_cur_compress_recommendation(
btr_cur_t* cursor, /*!< in: btr cursor */
mtr_t* mtr) /*!< in: mtr */
{
const page_t* page;
const page_t* page;
ut_ad(mtr_memo_contains(mtr, btr_cur_get_block(cursor),
MTR_MEMO_PAGE_X_FIX));
......@@ -197,4 +197,25 @@ btr_cur_can_delete_without_compress(
return(TRUE);
}
/*******************************************************************//**
Determine if an operation on off-page columns is an update.
@return TRUE if op != BTR_STORE_INSERT */
UNIV_INLINE
ibool
btr_blob_op_is_update(
/*==================*/
enum blob_op op) /*!< in: operation */
{
switch (op) {
case BTR_STORE_INSERT:
return(FALSE);
case BTR_STORE_INSERT_UPDATE:
case BTR_STORE_UPDATE:
return(TRUE);
}
ut_ad(0);
return(FALSE);
}
#endif /* !UNIV_HOTBACKUP */
......@@ -279,14 +279,6 @@ btr_pcur_commit_specify_mtr(
/*========================*/
btr_pcur_t* pcur, /*!< in: persistent cursor */
mtr_t* mtr); /*!< in: mtr to commit */
/**************************************************************//**
Tests if a cursor is detached: that is the latch mode is BTR_NO_LATCHES.
@return TRUE if detached */
UNIV_INLINE
ibool
btr_pcur_is_detached(
/*=================*/
btr_pcur_t* pcur); /*!< in: persistent cursor */
/*********************************************************//**
Moves the persistent cursor to the next record in the tree. If no records are
left, the cursor stays 'after last in tree'.
......
......@@ -415,38 +415,6 @@ btr_pcur_commit_specify_mtr(
pcur->pos_state = BTR_PCUR_WAS_POSITIONED;
}
/**************************************************************//**
Sets the pcur latch mode to BTR_NO_LATCHES. */
UNIV_INLINE
void
btr_pcur_detach(
/*============*/
btr_pcur_t* pcur) /*!< in: persistent cursor */
{
ut_a(pcur->pos_state == BTR_PCUR_IS_POSITIONED);
pcur->latch_mode = BTR_NO_LATCHES;
pcur->pos_state = BTR_PCUR_WAS_POSITIONED;
}
/**************************************************************//**
Tests if a cursor is detached: that is the latch mode is BTR_NO_LATCHES.
@return TRUE if detached */
UNIV_INLINE
ibool
btr_pcur_is_detached(
/*=================*/
btr_pcur_t* pcur) /*!< in: persistent cursor */
{
if (pcur->latch_mode == BTR_NO_LATCHES) {
return(TRUE);
}
return(FALSE);
}
/**************************************************************//**
Sets the old_rec_buf field to NULL. */
UNIV_INLINE
......
This diff is collapsed.
/*****************************************************************************
Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
......@@ -30,6 +30,7 @@ Created 2/17/1996 Heikki Tuuri
#include "rem0types.h"
#include "page0types.h"
#include "sync0rw.h"
/** Persistent cursor */
typedef struct btr_pcur_struct btr_pcur_t;
......@@ -38,6 +39,28 @@ typedef struct btr_cur_struct btr_cur_t;
/** B-tree search information for the adaptive hash index */
typedef struct btr_search_struct btr_search_t;
/** @brief The latch protecting the adaptive search system
This latch protects the
(1) hash index;
(2) columns of a record to which we have a pointer in the hash index;
but does NOT protect:
(3) next record offset field in a record;
(4) next or previous records on the same page.
Bear in mind (3) and (4) when using the hash index.
*/
extern rw_lock_t* btr_search_latch_temp;
/** The latch protecting the adaptive search system */
#define btr_search_latch (*btr_search_latch_temp)
/** Flag: has the search system been enabled?
Protected by btr_search_latch. */
extern char btr_search_enabled;
#ifdef UNIV_BLOB_DEBUG
# include "buf0types.h"
/** An index->blobs entry for keeping track of off-page column references */
......
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.
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