summaryrefslogtreecommitdiff
path: root/storage/innobase
diff options
context:
space:
mode:
authorMichael Widenius <monty@askmonty.org>2010-05-26 21:55:40 +0300
committerMichael Widenius <monty@askmonty.org>2010-05-26 21:55:40 +0300
commit4aa9d903c11554cc4887eeffe7f0592c52e8bc99 (patch)
treeaf3f0dfb833c3c4aabaa69ce50cfb64202ecd479 /storage/innobase
parent9febcb4776e563a93eb8fff247174b0e2eb2ae0b (diff)
parentaf6d89a6aa9feb3545de068f461cf91bfb281dd2 (diff)
downloadmariadb-git-4aa9d903c11554cc4887eeffe7f0592c52e8bc99.tar.gz
Merge with MySQL 5.1.47
Fixed some bugs introduced in 5.1.47 Disabled some tests until we have merged with latest Xtradb configure.in: Added testing if valgrind/memcheck.h exists storage/pbxt/src/ha_pbxt.cc: LOCK_plugin is not anymore locked in init
Diffstat (limited to 'storage/innobase')
-rw-r--r--[-rwxr-xr-x]storage/innobase/CMakeLists.txt2
-rw-r--r--storage/innobase/buf/buf0buf.c2
-rw-r--r--storage/innobase/handler/ha_innodb.cc22
-rw-r--r--storage/innobase/include/mem0mem.h11
-rw-r--r--storage/innobase/include/mem0mem.ic17
-rw-r--r--storage/innobase/include/trx0sys.ic2
-rw-r--r--storage/innobase/include/univ.i11
-rw-r--r--storage/innobase/lock/lock0lock.c27
-rw-r--r--storage/innobase/log/log0recv.c4
-rw-r--r--storage/innobase/row/row0ins.c6
-rw-r--r--storage/innobase/row/row0mysql.c2
-rw-r--r--storage/innobase/row/row0sel.c27
-rw-r--r--storage/innobase/srv/srv0srv.c12
-rw-r--r--storage/innobase/srv/srv0start.c2
14 files changed, 96 insertions, 51 deletions
diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt
index 5cc62c63507..5918db7ab11 100755..100644
--- a/storage/innobase/CMakeLists.txt
+++ b/storage/innobase/CMakeLists.txt
@@ -63,5 +63,5 @@ SET(INNOBASE_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c
usr/usr0sess.c
ut/ut0byte.c ut/ut0dbg.c ut/ut0mem.c ut/ut0rnd.c ut/ut0ut.c ut/ut0vec.c ut/ut0list.c ut/ut0wqueue.c)
- ## psergey: MYSQL_STORAGE_ENGINE(INNOBASE)
+MYSQL_STORAGE_ENGINE(INNOBASE)
diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
index 7d43532ea3d..45867388a61 100644
--- a/storage/innobase/buf/buf0buf.c
+++ b/storage/innobase/buf/buf0buf.c
@@ -759,7 +759,7 @@ buf_pool_init(
/* Wipe contents of frame to eliminate a Purify
warning */
-#ifdef HAVE_valgrind
+#ifdef HAVE_purify
memset(block->frame, '\0', UNIV_PAGE_SIZE);
#endif
if (srv_use_awe) {
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 7927d003546..ebf01fbc296 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -238,7 +238,7 @@ static MYSQL_THDVAR_BOOL(table_locks, PLUGIN_VAR_OPCMDARG,
/* default */ TRUE);
static handler *innobase_create_handler(handlerton *hton,
- TABLE_SHARE *table,
+ TABLE_SHARE *table,
MEM_ROOT *mem_root)
{
return new (mem_root) ha_innobase(hton, table);
@@ -350,7 +350,7 @@ int
innobase_start_trx_and_assign_read_view(
/*====================================*/
/* out: 0 */
- handlerton* hton, /* in: Innodb handlerton */
+ handlerton* hton, /* in: Innodb handlerton */
THD* thd); /* in: MySQL thread handle of the user for whom
the transaction should be committed */
/********************************************************************
@@ -1714,9 +1714,6 @@ innobase_init(
int err;
bool ret;
char *default_path;
-#ifdef SAFE_MUTEX
- my_bool old_safe_mutex_deadlock_detector;
-#endif
DBUG_ENTER("innobase_init");
handlerton *innobase_hton= (handlerton *)p;
@@ -1971,15 +1968,8 @@ innobase_init(
srv_sizeof_trx_t_in_ha_innodb_cc = sizeof(trx_t);
-#ifdef SAFE_MUTEX
- /* Disable deadlock detection as it's very slow for the buffer pool */
- old_safe_mutex_deadlock_detector= safe_mutex_deadlock_detector;
- safe_mutex_deadlock_detector= 0;
-#endif
err = innobase_start_or_create_for_mysql();
-#ifdef SAFE_MUTEX
- safe_mutex_deadlock_detector= old_safe_mutex_deadlock_detector;
-#endif
+
if (err != DB_SUCCESS) {
my_free(internal_innobase_data_file_path,
MYF(MY_ALLOW_ZERO_PTR));
@@ -4445,7 +4435,7 @@ ha_innobase::unlock_row(void)
case ROW_READ_WITH_LOCKS:
if (!srv_locks_unsafe_for_binlog
&& prebuilt->trx->isolation_level
- != TRX_ISO_READ_COMMITTED) {
+ > TRX_ISO_READ_COMMITTED) {
break;
}
/* fall through */
@@ -4482,7 +4472,7 @@ ha_innobase::try_semi_consistent_read(bool yes)
if (yes
&& (srv_locks_unsafe_for_binlog
- || prebuilt->trx->isolation_level == TRX_ISO_READ_COMMITTED)) {
+ || prebuilt->trx->isolation_level <= TRX_ISO_READ_COMMITTED)) {
prebuilt->row_read_type = ROW_READ_TRY_SEMI_CONSISTENT;
} else {
prebuilt->row_read_type = ROW_READ_WITH_LOCKS;
@@ -7778,7 +7768,7 @@ ha_innobase::store_lock(
isolation_level = trx->isolation_level;
if ((srv_locks_unsafe_for_binlog
- || isolation_level == TRX_ISO_READ_COMMITTED)
+ || isolation_level <= TRX_ISO_READ_COMMITTED)
&& isolation_level != TRX_ISO_SERIALIZABLE
&& (lock_type == TL_READ || lock_type == TL_READ_NO_INSERT)
&& (sql_command == SQLCOM_INSERT_SELECT
diff --git a/storage/innobase/include/mem0mem.h b/storage/innobase/include/mem0mem.h
index 2d5fd1db6c3..ce99a680418 100644
--- a/storage/innobase/include/mem0mem.h
+++ b/storage/innobase/include/mem0mem.h
@@ -138,6 +138,17 @@ mem_heap_free_func(
mem_heap_t* heap, /* in, own: heap to be freed */
const char* file_name, /* in: file name where freed */
ulint line); /* in: line where freed */
+/***************************************************************//**
+Allocates and zero-fills n bytes of memory from a memory heap.
+@return allocated, zero-filled storage */
+UNIV_INLINE
+void*
+mem_heap_zalloc(
+/*============*/
+ mem_heap_t* heap, /*!< in: memory heap */
+ ulint n); /*!< in: number of bytes; if the heap is allowed
+ to grow into the buffer pool, this must be
+ <= MEM_MAX_ALLOC_IN_BUF */
/*******************************************************************
Allocates n bytes of memory from a memory heap. */
UNIV_INLINE
diff --git a/storage/innobase/include/mem0mem.ic b/storage/innobase/include/mem0mem.ic
index 6227a27f277..782672dbc18 100644
--- a/storage/innobase/include/mem0mem.ic
+++ b/storage/innobase/include/mem0mem.ic
@@ -122,6 +122,23 @@ mem_block_get_start(mem_block_t* block)
return(block->start);
}
+/***************************************************************//**
+Allocates and zero-fills n bytes of memory from a memory heap.
+@return allocated, zero-filled storage */
+UNIV_INLINE
+void*
+mem_heap_zalloc(
+/*============*/
+ mem_heap_t* heap, /*!< in: memory heap */
+ ulint n) /*!< in: number of bytes; if the heap is allowed
+ to grow into the buffer pool, this must be
+ <= MEM_MAX_ALLOC_IN_BUF */
+{
+ ut_ad(heap);
+ ut_ad(!(heap->type & MEM_HEAP_BTR_SEARCH));
+ return(memset(mem_heap_alloc(heap, n), 0, n));
+}
+
/*******************************************************************
Allocates n bytes of memory from a memory heap. */
UNIV_INLINE
diff --git a/storage/innobase/include/trx0sys.ic b/storage/innobase/include/trx0sys.ic
index 55bcc12a414..1142fb60398 100644
--- a/storage/innobase/include/trx0sys.ic
+++ b/storage/innobase/include/trx0sys.ic
@@ -19,7 +19,7 @@ typedef byte trx_sysf_rseg_t;
#define TRX_SYS_RSEG_SPACE 0 /* space where the the segment
header is placed; starting with
MySQL/InnoDB 5.1.7, this is
- UNIV_UNDEFINED if the slot is unused */
+ ULINT_UNDEFINED for unused slots */
#define TRX_SYS_RSEG_PAGE_NO 4 /* page number where the the segment
header is placed; this is FIL_NULL
if the slot is unused */
diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i
index e5e3577b4e6..ee3a0b27b20 100644
--- a/storage/innobase/include/univ.i
+++ b/storage/innobase/include/univ.i
@@ -55,10 +55,10 @@ of the 32-bit x86 assembler in mutex operations. */
# define UNIV_CAN_USE_X86_ASSEMBLER
# endif
-/* Enable explicit inlining of functions only for compilers known to
-support it. */
+/* We only try to do explicit inlining of functions with gcc and
+Microsoft Visual C++ */
-# if !defined(__GNUC__) && !defined(__SUNPRO_C)
+# if !defined(__GNUC__)
# undef UNIV_MUST_NOT_INLINE /* Remove compiler warning */
# define UNIV_MUST_NOT_INLINE
# endif
@@ -82,6 +82,9 @@ memory is read outside the allocated blocks. */
/* Make a non-inline debug version */
+#ifdef HAVE_purify
+# define UNIV_DEBUG_VALGRIND
+#endif /* HAVE_purify */
#if 0
#define UNIV_DEBUG_VALGRIND /* Enable extra
Valgrind instrumentation */
@@ -107,7 +110,7 @@ operations (very slow); also UNIV_DEBUG must be defined */
#define UNIV_BTR_DEBUG /* check B-tree links */
#define UNIV_LIGHT_MEM_DEBUG /* light memory debugging */
-#ifdef HAVE_valgrind
+#ifdef HAVE_purify
/* The following sets all new allocated memory to zero before use:
this can be used to eliminate unnecessary Purify warnings, but note that
it also masks many bugs Purify could detect. For detailed Purify analysis it
diff --git a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c
index 8f4b64cda96..7df8ea50887 100644
--- a/storage/innobase/lock/lock0lock.c
+++ b/storage/innobase/lock/lock0lock.c
@@ -2362,7 +2362,7 @@ lock_rec_inherit_to_gap(
if (!lock_rec_get_insert_intention(lock)
&& !((srv_locks_unsafe_for_binlog
|| lock->trx->isolation_level
- == TRX_ISO_READ_COMMITTED)
+ <= TRX_ISO_READ_COMMITTED)
&& lock_get_mode(lock) == LOCK_X)) {
lock_rec_add_to_queue(LOCK_REC | lock_get_mode(lock)
@@ -4538,13 +4538,34 @@ lock_rec_queue_validate(
rec, impl_trx));
}
}
-
+#if 0
if (index && !(index->type & DICT_CLUSTERED)) {
/* The kernel mutex may get released temporarily in the
next function call: we have to release lock table mutex
to obey the latching order */
+ /* NOTE: This is a bogus check that would fail in the
+ following case: Our transaction is updating a
+ row. After it has updated the clustered index record,
+ it goes to a secondary index record and finds someone
+ else holding an explicit S- or X-lock on that
+ secondary index record, presumably from a locking
+ read. Our transaction cannot update the secondary
+ index immediately, but places a waiting X-lock request
+ on the secondary index record. There is nothing
+ illegal in this. The assertion is simply too strong. */
+
+ /* From the locking point of view, each secondary
+ index is a separate table. A lock that is held on
+ secondary index rec does not give any rights to modify
+ or read the clustered index rec. Therefore, we can
+ think of the sec index as a separate 'table' from the
+ clust index 'table'. Conversely, a transaction that
+ has acquired a lock on and modified a clustered index
+ record may need to wait for a lock on the
+ corresponding record in a secondary index. */
+
impl_trx = lock_sec_rec_some_has_impl_off_kernel(
rec, index, offsets);
@@ -4555,7 +4576,7 @@ lock_rec_queue_validate(
rec, impl_trx));
}
}
-
+#endif
lock = lock_rec_get_first(rec);
while (lock) {
diff --git a/storage/innobase/log/log0recv.c b/storage/innobase/log/log0recv.c
index 5d309768064..e6524eeefbf 100644
--- a/storage/innobase/log/log0recv.c
+++ b/storage/innobase/log/log0recv.c
@@ -167,7 +167,7 @@ recv_sys_init(
recv_sys->len = 0;
recv_sys->recovered_offset = 0;
- recv_sys->addr_hash = hash_create(available_memory / 64);
+ recv_sys->addr_hash = hash_create(available_memory / 512);
recv_sys->n_addrs = 0;
recv_sys->apply_log_recs = FALSE;
@@ -207,7 +207,7 @@ recv_sys_empty_hash(void)
hash_table_free(recv_sys->addr_hash);
mem_heap_empty(recv_sys->heap);
- recv_sys->addr_hash = hash_create(buf_pool_get_curr_size() / 256);
+ recv_sys->addr_hash = hash_create(buf_pool_get_curr_size() / 512);
}
#ifndef UNIV_LOG_DEBUG
diff --git a/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c
index ad14b927170..51c295b5098 100644
--- a/storage/innobase/row/row0ins.c
+++ b/storage/innobase/row/row0ins.c
@@ -140,7 +140,7 @@ row_ins_alloc_sys_fields(
dfield = dtuple_get_nth_field(row, dict_col_get_no(col));
- ptr = mem_heap_alloc(heap, DATA_ROW_ID_LEN);
+ ptr = mem_heap_zalloc(heap, DATA_ROW_ID_LEN);
dfield_set_data(dfield, ptr, DATA_ROW_ID_LEN);
@@ -151,7 +151,7 @@ row_ins_alloc_sys_fields(
col = dict_table_get_sys_col(table, DATA_TRX_ID);
dfield = dtuple_get_nth_field(row, dict_col_get_no(col));
- ptr = mem_heap_alloc(heap, DATA_TRX_ID_LEN);
+ ptr = mem_heap_zalloc(heap, DATA_TRX_ID_LEN);
dfield_set_data(dfield, ptr, DATA_TRX_ID_LEN);
@@ -162,7 +162,7 @@ row_ins_alloc_sys_fields(
col = dict_table_get_sys_col(table, DATA_ROLL_PTR);
dfield = dtuple_get_nth_field(row, dict_col_get_no(col));
- ptr = mem_heap_alloc(heap, DATA_ROLL_PTR_LEN);
+ ptr = mem_heap_zalloc(heap, DATA_ROLL_PTR_LEN);
dfield_set_data(dfield, ptr, DATA_ROLL_PTR_LEN);
}
diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c
index f7156403247..a0e0ee99775 100644
--- a/storage/innobase/row/row0mysql.c
+++ b/storage/innobase/row/row0mysql.c
@@ -1485,7 +1485,7 @@ row_unlock_for_mysql(
if (UNIV_UNLIKELY
(!srv_locks_unsafe_for_binlog
- && trx->isolation_level != TRX_ISO_READ_COMMITTED)) {
+ && trx->isolation_level > TRX_ISO_READ_COMMITTED)) {
fprintf(stderr,
"InnoDB: Error: calling row_unlock_for_mysql though\n"
diff --git a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c
index eee74f280af..1d30249c53e 100644
--- a/storage/innobase/row/row0sel.c
+++ b/storage/innobase/row/row0sel.c
@@ -744,7 +744,7 @@ row_sel_get_clust_rec(
trx = thr_get_trx(thr);
if (srv_locks_unsafe_for_binlog
- || trx->isolation_level == TRX_ISO_READ_COMMITTED) {
+ || trx->isolation_level <= TRX_ISO_READ_COMMITTED) {
lock_type = LOCK_REC_NOT_GAP;
} else {
lock_type = LOCK_ORDINARY;
@@ -1358,7 +1358,7 @@ rec_loop:
if (srv_locks_unsafe_for_binlog
|| trx->isolation_level
- == TRX_ISO_READ_COMMITTED) {
+ <= TRX_ISO_READ_COMMITTED) {
if (page_rec_is_supremum(next_rec)) {
@@ -1414,7 +1414,7 @@ skip_lock:
trx = thr_get_trx(thr);
if (srv_locks_unsafe_for_binlog
- || trx->isolation_level == TRX_ISO_READ_COMMITTED) {
+ || trx->isolation_level <= TRX_ISO_READ_COMMITTED) {
if (page_rec_is_supremum(rec)) {
@@ -3596,7 +3596,7 @@ shortcut_fails_too_big_rec:
&& !page_rec_is_supremum(rec)
&& set_also_gap_locks
&& !(srv_locks_unsafe_for_binlog
- || trx->isolation_level == TRX_ISO_READ_COMMITTED)
+ || trx->isolation_level <= TRX_ISO_READ_COMMITTED)
&& prebuilt->select_lock_type != LOCK_NONE) {
/* Try to place a gap lock on the next index record
@@ -3692,7 +3692,7 @@ rec_loop:
if (set_also_gap_locks
&& !(srv_locks_unsafe_for_binlog
- || trx->isolation_level == TRX_ISO_READ_COMMITTED)
+ || trx->isolation_level <= TRX_ISO_READ_COMMITTED)
&& prebuilt->select_lock_type != LOCK_NONE) {
/* Try to place a lock on the index record */
@@ -3827,7 +3827,7 @@ wrong_offs:
if (set_also_gap_locks
&& !(srv_locks_unsafe_for_binlog
|| trx->isolation_level
- == TRX_ISO_READ_COMMITTED)
+ <= TRX_ISO_READ_COMMITTED)
&& prebuilt->select_lock_type != LOCK_NONE) {
/* Try to place a gap lock on the index
@@ -3862,7 +3862,7 @@ wrong_offs:
if (set_also_gap_locks
&& !(srv_locks_unsafe_for_binlog
|| trx->isolation_level
- == TRX_ISO_READ_COMMITTED)
+ <= TRX_ISO_READ_COMMITTED)
&& prebuilt->select_lock_type != LOCK_NONE) {
/* Try to place a gap lock on the index
@@ -3909,7 +3909,7 @@ wrong_offs:
if (!set_also_gap_locks
|| srv_locks_unsafe_for_binlog
- || trx->isolation_level == TRX_ISO_READ_COMMITTED
+ || trx->isolation_level <= TRX_ISO_READ_COMMITTED
|| (unique_search
&& !UNIV_UNLIKELY(rec_get_deleted_flag(rec, comp)))) {
@@ -3947,7 +3947,7 @@ no_gap_lock:
rec_t* old_vers;
case DB_SUCCESS:
if (srv_locks_unsafe_for_binlog
- || trx->isolation_level == TRX_ISO_READ_COMMITTED) {
+ || trx->isolation_level <= TRX_ISO_READ_COMMITTED) {
/* Note that a record of
prebuilt->index was locked. */
prebuilt->new_rec_locks = 1;
@@ -3956,6 +3956,7 @@ no_gap_lock:
case DB_LOCK_WAIT:
if (UNIV_LIKELY(prebuilt->row_read_type
!= ROW_READ_TRY_SEMI_CONSISTENT)
+ || unique_search
|| index != clust_index) {
goto lock_wait_or_error;
@@ -4080,7 +4081,7 @@ no_gap_lock:
/* The record is delete-marked: we can skip it */
if ((srv_locks_unsafe_for_binlog
- || trx->isolation_level == TRX_ISO_READ_COMMITTED)
+ || trx->isolation_level <= TRX_ISO_READ_COMMITTED)
&& prebuilt->select_lock_type != LOCK_NONE
&& !did_semi_consistent_read) {
@@ -4147,7 +4148,7 @@ requires_clust_rec:
}
if ((srv_locks_unsafe_for_binlog
- || trx->isolation_level == TRX_ISO_READ_COMMITTED)
+ || trx->isolation_level <= TRX_ISO_READ_COMMITTED)
&& prebuilt->select_lock_type != LOCK_NONE) {
/* Note that both the secondary index record
and the clustered index record were locked. */
@@ -4160,7 +4161,7 @@ requires_clust_rec:
/* The record is delete marked: we can skip it */
if ((srv_locks_unsafe_for_binlog
- || trx->isolation_level == TRX_ISO_READ_COMMITTED)
+ || trx->isolation_level <= TRX_ISO_READ_COMMITTED)
&& prebuilt->select_lock_type != LOCK_NONE) {
/* No need to keep a lock on a delete-marked
@@ -4367,7 +4368,7 @@ lock_wait_or_error:
moves_up, &mtr);
if ((srv_locks_unsafe_for_binlog
- || trx->isolation_level == TRX_ISO_READ_COMMITTED)
+ || trx->isolation_level <= TRX_ISO_READ_COMMITTED)
&& !same_user_rec) {
/* Since we were not able to restore the cursor
diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
index 26ea7958d0d..a2eed3f171c 100644
--- a/storage/innobase/srv/srv0srv.c
+++ b/storage/innobase/srv/srv0srv.c
@@ -1554,8 +1554,9 @@ srv_suspend_mysql_thread(
mutex_exit(&kernel_mutex);
- if (srv_lock_wait_timeout < 100000000
- && wait_time > (double)srv_lock_wait_timeout) {
+ if (trx_is_interrupted(trx)
+ || (srv_lock_wait_timeout < 100000000
+ && wait_time > (double)srv_lock_wait_timeout)) {
trx->error_state = DB_LOCK_WAIT_TIMEOUT;
}
@@ -2104,9 +2105,10 @@ loop:
wait_time = ut_difftime(ut_time(), slot->suspend_time);
- if (srv_lock_wait_timeout < 100000000
- && (wait_time > (double) srv_lock_wait_timeout
- || wait_time < 0)) {
+ if (trx_is_interrupted(thr_get_trx(slot->thr))
+ || (srv_lock_wait_timeout < 100000000
+ && (wait_time > (double) srv_lock_wait_timeout
+ || wait_time < 0))) {
/* Timeout exceeded or a wrap-around in system
time counter: cancel the lock request queued
diff --git a/storage/innobase/srv/srv0start.c b/storage/innobase/srv/srv0start.c
index d117ff16608..a7950473a17 100644
--- a/storage/innobase/srv/srv0start.c
+++ b/storage/innobase/srv/srv0start.c
@@ -104,7 +104,7 @@ static char* srv_monitor_file_name;
/* Avoid warnings when using purify */
-#ifdef HAVE_valgrind
+#ifdef HAVE_purify
static int inno_bcmp(register const char *s1, register const char *s2,
register uint len)
{