Commit cd180bc2 authored by Vadim Tkachenko's avatar Vadim Tkachenko

sync to extension rev 58

parent e76737c2
......@@ -713,8 +713,7 @@ check_have_atomic_pthread_t:
echo '#define HAVE_ATOMIC_PTHREAD_T' > include/ut0auxconf.h ; \
fi
# This is temprary fix for http://bugs.mysql.com/43740
all: all-am
all: check_have_atomic_pthread_t all-am
.SUFFIXES:
.SUFFIXES: .c .cc .lo .o .obj
......
......@@ -26,7 +26,6 @@ struct innodb_enhancement {
{"xtradb_show_enhancements","I_S.XTRADB_ENHANCEMENTS","","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_show_status","Improvements to SHOW INNODB STATUS","Memory information and lock info fixes","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_io","Improvements to InnoDB IO","","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_rw_lock","InnoDB RW-lock fixes","Useful for 8+ cores SMP systems","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_opt_lru_count","Fix of buffer_pool mutex","Decreases contention on buffer_pool mutex on LRU operations","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_buffer_pool_pages","Information of buffer pool content","","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_split_buf_pool_mutex","More fix of buffer_pool mutex","Spliting buf_pool_mutex and optimizing based on innodb_opt_lru_count","http://www.percona.com/docs/wiki/percona-xtradb"},
......
......@@ -359,17 +359,7 @@ rw_lock_get_x_lock_count(
Accessor functions for rw lock. */
UNIV_INLINE
ulint
rw_lock_get_s_waiters(
/*==================*/
rw_lock_t* lock);
UNIV_INLINE
ulint
rw_lock_get_x_waiters(
/*==================*/
rw_lock_t* lock);
UNIV_INLINE
ulint
rw_lock_get_wx_waiters(
rw_lock_get_waiters(
/*================*/
rw_lock_t* lock);
UNIV_INLINE
......@@ -488,14 +478,6 @@ rw_lock_debug_print(
rw_lock_debug_t* info); /* in: debug struct */
#endif /* UNIV_SYNC_DEBUG */
#ifndef INNODB_RW_LOCKS_USE_ATOMICS
#error INNODB_RW_LOCKS_USE_ATOMICS is not defined. Do you use enough new GCC or compatibles?
#error Or do you use exact options for CFLAGS?
#error e.g. (for x86_32): "-m32 -march=i586 -mtune=i686"
#error e.g. (for Sparc_64): "-m64 -mcpu=v9"
#error Otherwise, this build may be slower than normal version.
#endif
/* NOTE! The structure appears here only for the compiler to know its size.
Do not use its fields directly! The structure used in the spin lock
implementation of a read-write lock. Several threads may have a shared lock
......@@ -507,16 +489,7 @@ no new readers will be let in while the thread waits for readers to exit. */
struct rw_lock_struct {
volatile lint lock_word;
/* Holds the state of the lock. */
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
volatile ulint s_waiters; /* 1: there are waiters (s_lock) */
volatile ulint x_waiters; /* 1: there are waiters (x_lock) */
volatile ulint wait_ex_waiters; /* 1: there are waiters (wait_ex) */
volatile ulint reader_count; /* Number of readers who have locked this
lock in the shared mode */
volatile ulint writer;
#else
volatile ulint waiters;/* 1: there are waiters */
#endif
volatile ibool recursive;/* Default value FALSE which means the lock
is non-recursive. The value is typically set
to TRUE making normal rw_locks recursive. In
......@@ -533,16 +506,7 @@ struct rw_lock_struct {
/* Thread id of writer thread. Is only
guaranteed to have sane and non-stale
value iff recursive flag is set. */
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
volatile ulint writer_count; /* Number of times the same thread has
recursively locked the lock in the exclusive
mode */
/* Used by sync0arr.c for thread queueing */
os_event_t s_event; /* Used for s_lock */
os_event_t x_event; /* Used for x_lock */
#else
os_event_t event; /* Used by sync0arr.c for thread queueing */
#endif
os_event_t wait_ex_event;
/* Event for next-writer to wait on. A thread
must decrement lock_word before waiting. */
......@@ -564,7 +528,7 @@ struct rw_lock_struct {
/* last s-lock file/line is not guaranteed to be correct */
const char* last_s_file_name;/* File name where last s-locked */
const char* last_x_file_name;/* File name where last x-locked */
volatile ibool writer_is_wait_ex;
ibool writer_is_wait_ex;
/* This is TRUE if the writer field is
RW_LOCK_WAIT_EX; this field is located far
from the memory update hotspot fields which
......
......@@ -70,28 +70,12 @@ rw_lock_remove_debug_info(
Accessor functions for rw lock. */
UNIV_INLINE
ulint
rw_lock_get_s_waiters(
rw_lock_get_waiters(
/*================*/
/* out: 1 if waiters, 0 otherwise */
rw_lock_t* lock) /* in: rw-lock */
{
return(lock->s_waiters);
}
UNIV_INLINE
ulint
rw_lock_get_x_waiters(
/*================*/
rw_lock_t* lock)
{
return(lock->x_waiters);
}
UNIV_INLINE
ulint
rw_lock_get_wx_waiters(
/*================*/
rw_lock_t* lock)
{
return(lock->wait_ex_waiters);
return(lock->waiters);
}
/************************************************************************
......@@ -100,38 +84,14 @@ Sets lock->waiters to 1. It is not an error if lock->waiters is already
memory barrier. */
UNIV_INLINE
void
rw_lock_set_s_waiter_flag(
/*====================*/
rw_lock_t* lock) /* in: rw-lock */
{
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
os_compare_and_swap(&lock->s_waiters, 0, 1);
#else /* INNODB_RW_LOCKS_USE_ATOMICS */
lock->s_waiters = 1;
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
}
UNIV_INLINE
void
rw_lock_set_x_waiter_flag(
/*====================*/
rw_lock_t* lock) /* in: rw-lock */
{
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
os_compare_and_swap(&lock->x_waiters, 0, 1);
#else /* INNODB_RW_LOCKS_USE_ATOMICS */
lock->x_waiters = 1;
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
}
UNIV_INLINE
void
rw_lock_set_wx_waiter_flag(
rw_lock_set_waiter_flag(
/*====================*/
rw_lock_t* lock) /* in: rw-lock */
{
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
os_compare_and_swap(&lock->wait_ex_waiters, 0, 1);
os_compare_and_swap(&lock->waiters, 0, 1);
#else /* INNODB_RW_LOCKS_USE_ATOMICS */
lock->wait_ex_waiters = 1;
lock->waiters = 1;
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
}
......@@ -141,38 +101,14 @@ Resets lock->waiters to 0. It is not an error if lock->waiters is already
memory barrier. */
UNIV_INLINE
void
rw_lock_reset_s_waiter_flag(
/*======================*/
rw_lock_t* lock) /* in: rw-lock */
{
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
os_compare_and_swap(&lock->s_waiters, 1, 0);
#else /* INNODB_RW_LOCKS_USE_ATOMICS */
lock->s_waiters = 0;
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
}
UNIV_INLINE
void
rw_lock_reset_x_waiter_flag(
rw_lock_reset_waiter_flag(
/*======================*/
rw_lock_t* lock) /* in: rw-lock */
{
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
os_compare_and_swap(&lock->x_waiters, 1, 0);
os_compare_and_swap(&lock->waiters, 1, 0);
#else /* INNODB_RW_LOCKS_USE_ATOMICS */
lock->x_waiters = 0;
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
}
UNIV_INLINE
void
rw_lock_reset_wx_waiter_flag(
/*======================*/
rw_lock_t* lock) /* in: rw-lock */
{
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
os_compare_and_swap(&lock->wait_ex_waiters, 1, 0);
#else /* INNODB_RW_LOCKS_USE_ATOMICS */
lock->wait_ex_waiters = 0;
lock->waiters = 0;
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
}
......@@ -185,17 +121,6 @@ rw_lock_get_writer(
/*===============*/
rw_lock_t* lock)
{
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
if (lock->writer == RW_LOCK_NOT_LOCKED) {
return(RW_LOCK_NOT_LOCKED);
}
if (lock->writer_is_wait_ex) {
return(RW_LOCK_WAIT_EX);
} else {
return(RW_LOCK_EX);
}
#else
lint lock_word = lock->lock_word;
if(lock_word > 0) {
/* return NOT_LOCKED in s-lock state, like the writer
......@@ -207,7 +132,6 @@ rw_lock_get_writer(
ut_ad(lock_word > -X_LOCK_DECR);
return(RW_LOCK_WAIT_EX);
}
#endif
}
/**********************************************************************
......@@ -218,9 +142,6 @@ rw_lock_get_reader_count(
/*=====================*/
rw_lock_t* lock)
{
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
return(lock->reader_count);
#else
lint lock_word = lock->lock_word;
if(lock_word > 0) {
/* s-locked, no x-waiters */
......@@ -230,7 +151,6 @@ rw_lock_get_reader_count(
return((ulint)(-lock_word));
}
return(0);
#endif
}
#ifndef INNODB_RW_LOCKS_USE_ATOMICS
......@@ -254,16 +174,12 @@ rw_lock_get_x_lock_count(
/* out: value of writer_count */
rw_lock_t* lock) /* in: rw-lock */
{
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
return(lock->writer_count);
#else
lint lock_copy = lock->lock_word;
/* If there is a reader, lock_word is not divisible by X_LOCK_DECR */
if(lock_copy > 0 || (-lock_copy) % X_LOCK_DECR != 0) {
return(0);
}
return(((-lock_copy) / X_LOCK_DECR) + 1);
#endif
}
/**********************************************************************
......@@ -401,26 +317,11 @@ rw_lock_s_lock_low(
const char* file_name, /* in: file name where lock requested */
ulint line) /* in: line where requested */
{
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
if (UNIV_LIKELY(rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED)) {
/* try s-lock */
if(__sync_sub_and_fetch(&(lock->lock_word),1) <= 0) {
/* fail */
__sync_fetch_and_add(&(lock->lock_word),1);
return(FALSE); /* locking did not succeed */
}
/* success */
__sync_fetch_and_add(&(lock->reader_count),1);
} else {
return(FALSE); /* locking did not succeed */
}
#else
/* TODO: study performance of UNIV_LIKELY branch prediction hints. */
if (!rw_lock_lock_word_decr(lock, 1)) {
/* Locking did not succeed */
return(FALSE);
}
#endif
#ifdef UNIV_SYNC_DEBUG
rw_lock_add_debug_info(lock, pass, RW_LOCK_SHARED, file_name, line);
......@@ -445,17 +346,10 @@ rw_lock_s_lock_direct(
const char* file_name, /* in: file name where requested */
ulint line) /* in: line where lock requested */
{
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
ut_ad(rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED);
ut_ad(rw_lock_get_reader_count(lock) == 0);
__sync_fetch_and_add(&(lock->reader_count),1);
#else
ut_ad(lock->lock_word == X_LOCK_DECR);
/* Indicate there is a new reader by decrementing lock_word */
lock->lock_word--;
#endif
lock->last_s_file_name = file_name;
lock->last_s_line = line;
......@@ -478,17 +372,9 @@ rw_lock_x_lock_direct(
ulint line) /* in: line where lock requested */
{
ut_ad(rw_lock_validate(lock));
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
ut_ad(rw_lock_get_reader_count(lock) == 0);
ut_ad(rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED);
lock->writer = RW_LOCK_EX;
__sync_fetch_and_add(&(lock->writer_count),1);
#else
ut_ad(lock->lock_word == X_LOCK_DECR);
lock->lock_word -= X_LOCK_DECR;
#endif
lock->writer_thread = os_thread_get_curr_id();
lock->recursive = TRUE;
......@@ -562,53 +448,7 @@ rw_lock_x_lock_func_nowait(
ibool success;
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
success = FALSE;
if (lock->reader_count == 0) {
/* try to lock writer */
if(__sync_lock_test_and_set(&(lock->writer),RW_LOCK_EX)
== RW_LOCK_NOT_LOCKED) {
/* success */
retry_x_lock:
/* try x-lock */
if(__sync_sub_and_fetch(&(lock->lock_word),
X_LOCK_DECR) == 0) {
/* success */
lock->writer_thread = curr_thread;
lock->recursive = TRUE;
lock->writer_is_wait_ex = FALSE;
/* next function may work as memory barrier */
relock:
__sync_fetch_and_add(&(lock->writer_count),1);
#ifdef UNIV_SYNC_DEBUG
rw_lock_add_debug_info(lock, 0, RW_LOCK_EX, file_name, line);
#endif
lock->last_x_file_name = file_name;
lock->last_x_line = line;
ut_ad(rw_lock_validate(lock));
return(TRUE);
} else {
/* fail (x-lock) */
if (__sync_fetch_and_add(&(lock->lock_word),X_LOCK_DECR)
== 0)
goto retry_x_lock;
}
__sync_lock_test_and_set(&(lock->writer),RW_LOCK_NOT_LOCKED);
}
}
if (lock->recursive
&& os_thread_eq(lock->writer_thread, curr_thread)) {
goto relock;
}
//ut_ad(rw_lock_validate(lock));
return(FALSE);
success = os_compare_and_swap(&(lock->lock_word), X_LOCK_DECR, 0);
#else
success = FALSE;
......@@ -619,6 +459,7 @@ retry_x_lock:
}
mutex_exit(&(lock->mutex));
#endif
if (success) {
rw_lock_set_writer_id_and_recursion_flag(lock, TRUE);
......@@ -645,7 +486,6 @@ retry_x_lock:
ut_ad(rw_lock_validate(lock));
return(TRUE);
#endif
}
/**********************************************************************
......@@ -661,31 +501,6 @@ rw_lock_s_unlock_func(
#endif
)
{
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
ibool last = FALSE;
ut_a(lock->reader_count > 0);
/* unlock lock_word */
__sync_fetch_and_add(&(lock->lock_word),1);
if(__sync_sub_and_fetch(&(lock->reader_count),1) == 0) {
last = TRUE;
}
#ifdef UNIV_SYNC_DEBUG
rw_lock_remove_debug_info(lock, pass, RW_LOCK_SHARED);
#endif
if (UNIV_UNLIKELY(last && os_compare_and_swap(&lock->wait_ex_waiters, 1, 0))) {
os_event_set(lock->wait_ex_event);
sync_array_object_signalled(sync_primary_wait_array);
}
else if (UNIV_UNLIKELY(last && os_compare_and_swap(&lock->x_waiters, 1, 0))) {
os_event_set(lock->x_event);
sync_array_object_signalled(sync_primary_wait_array);
}
#else
ut_ad((lock->lock_word % X_LOCK_DECR) != 0);
#ifdef UNIV_SYNC_DEBUG
......@@ -702,7 +517,6 @@ rw_lock_s_unlock_func(
sync_array_object_signalled(sync_primary_wait_array);
}
#endif
ut_ad(rw_lock_validate(lock));
......@@ -720,19 +534,6 @@ rw_lock_s_unlock_direct(
/*====================*/
rw_lock_t* lock) /* in: rw-lock */
{
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
ut_ad(lock->reader_count > 0);
__sync_sub_and_fetch(&(lock->reader_count),1);
#ifdef UNIV_SYNC_DEBUG
rw_lock_remove_debug_info(lock, 0, RW_LOCK_SHARED);
#endif
ut_ad(!lock->s_waiters);
ut_ad(!lock->x_waiters);
ut_ad(!lock->wait_ex_waiters);
#else
ut_ad(lock->lock_word < X_LOCK_DECR);
#ifdef UNIV_SYNC_DEBUG
......@@ -743,7 +544,6 @@ rw_lock_s_unlock_direct(
lock->lock_word++;
ut_ad(!lock->waiters);
#endif
ut_ad(rw_lock_validate(lock));
#ifdef UNIV_SYNC_PERF_STAT
rw_s_exit_count++;
......@@ -763,49 +563,6 @@ rw_lock_x_unlock_func(
#endif
)
{
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
ibool last = FALSE;
ibool s_sg = FALSE;
ibool x_sg = FALSE;
ut_ad(lock->writer_count > 0);
if(__sync_sub_and_fetch(&(lock->writer_count),1) == 0) {
last = TRUE;
}
if (last) {
/* unlock lock_word */
__sync_fetch_and_add(&(lock->lock_word),X_LOCK_DECR);
lock->recursive = FALSE;
/* FIXME: It is a value of bad manners for pthread.
But we shouldn't keep an ID of not-owner. */
lock->writer_thread = -1;
__sync_lock_test_and_set(&(lock->writer),RW_LOCK_NOT_LOCKED);
}
#ifdef UNIV_SYNC_DEBUG
rw_lock_remove_debug_info(lock, pass, RW_LOCK_EX);
#endif
if (last) {
if(os_compare_and_swap(&lock->s_waiters, 1, 0)){
s_sg = TRUE;
}
if(os_compare_and_swap(&lock->x_waiters, 1, 0)){
x_sg = TRUE;
}
}
if (UNIV_UNLIKELY(s_sg)) {
os_event_set(lock->s_event);
sync_array_object_signalled(sync_primary_wait_array);
}
if (UNIV_UNLIKELY(x_sg)) {
os_event_set(lock->x_event);
sync_array_object_signalled(sync_primary_wait_array);
}
#else
ut_ad((lock->lock_word % X_LOCK_DECR) == 0);
/* lock->recursive flag also indicates if lock->writer_thread is
......@@ -836,7 +593,6 @@ rw_lock_x_unlock_func(
}
}
#endif
ut_ad(rw_lock_validate(lock));
#ifdef UNIV_SYNC_PERF_STAT
......@@ -856,19 +612,6 @@ rw_lock_x_unlock_direct(
/* Reset the exclusive lock if this thread no longer has an x-mode
lock */
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
if(__sync_sub_and_fetch(&(lock->writer_count),1) == 0) {
lock->writer = RW_LOCK_NOT_LOCKED;
}
#ifdef UNIV_SYNC_DEBUG
rw_lock_remove_debug_info(lock, 0, RW_LOCK_EX);
#endif
ut_ad(!lock->s_waiters);
ut_ad(!lock->x_waiters);
ut_ad(!lock->wait_ex_waiters);
#else
ut_ad((lock->lock_word % X_LOCK_DECR) == 0);
#ifdef UNIV_SYNC_DEBUG
......@@ -884,7 +627,6 @@ rw_lock_x_unlock_direct(
lock->lock_word += X_LOCK_DECR;
ut_ad(!lock->waiters);
#endif
ut_ad(rw_lock_validate(lock));
#ifdef UNIV_SYNC_PERF_STAT
......
......@@ -35,7 +35,7 @@ Created 1/20/1994 Heikki Tuuri
#define INNODB_VERSION_MAJOR 1
#define INNODB_VERSION_MINOR 0
#define INNODB_VERSION_BUGFIX 3
#define PERCONA_INNODB_VERSION 3
#define PERCONA_INNODB_VERSION 5
/* The following is the InnoDB version as shown in
SELECT plugin_version FROM information_schema.plugins;
......
......@@ -12,8 +12,3 @@ If by any chance Makefile.in and ./configure are regenerated and thus
the hack from Makefile.in wiped away then the "real" check from plug.in
will take over.
*/
/* This is temprary fix for http://bugs.mysql.com/43740 */
/* force to enable */
#ifdef HAVE_GCC_ATOMIC_BUILTINS
#define HAVE_ATOMIC_PTHREAD_T
#endif
......@@ -46,6 +46,13 @@ t1 CREATE TABLE `t1` (
KEY `d2` (`d`),
KEY `b` (`b`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
CREATE TABLE `t1#1`(a INT PRIMARY KEY) ENGINE=InnoDB;
alter table t1 add unique index (c), add index (d);
ERROR HY000: Table 'test.t1#1' already exists
rename table `t1#1` to `t1#2`;
alter table t1 add unique index (c), add index (d);
ERROR HY000: Table 'test.t1#2' already exists
drop table `t1#2`;
alter table t1 add unique index (c), add index (d);
show create table t1;
Table Create Table
......
......@@ -17,6 +17,16 @@ show create table t1;
alter table t1 add index (b);
show create table t1;
# Check how existing tables interfere with temporary tables.
CREATE TABLE `t1#1`(a INT PRIMARY KEY) ENGINE=InnoDB;
--error 156
alter table t1 add unique index (c), add index (d);
rename table `t1#1` to `t1#2`;
--error 156
alter table t1 add unique index (c), add index (d);
drop table `t1#2`;
alter table t1 add unique index (c), add index (d);
show create table t1;
explain select * from t1 force index(c) order by c;
......
......@@ -30,4 +30,3 @@ ALTER TABLE bug34300 ADD COLUMN (f10 INT);
SELECT f4, f8 FROM bug34300;
DROP TABLE bug34300;
SET @@global.max_allowed_packet=1048576;
set @old_innodb_file_per_table=@@innodb_file_per_table;
set @old_innodb_file_format=@@innodb_file_format;
set @old_innodb_file_format_check=@@innodb_file_format_check;
SET GLOBAL innodb_file_format='Barracuda';
SET GLOBAL innodb_file_per_table=ON;
......@@ -4,9 +4,6 @@
#
-- source include/have_innodb.inc
set @old_innodb_file_per_table=@@innodb_file_per_table;
set @old_innodb_file_format=@@innodb_file_format;
set @old_innodb_file_format_check=@@innodb_file_format_check;
SET GLOBAL innodb_file_format='Barracuda';
SET GLOBAL innodb_file_per_table=ON;
......@@ -1156,7 +1153,3 @@ DROP TABLE IF EXISTS table4;
DROP TABLE IF EXISTS table5;
DROP TABLE IF EXISTS table6;
set global innodb_file_per_table=@old_innodb_file_per_table;
set global innodb_file_format=@old_innodb_file_format;
set global innodb_file_format_check=@old_innodb_file_format_check;
......@@ -13,9 +13,6 @@ SET storage_engine=InnoDB;
-- disable_query_log
-- disable_result_log
set @old_innodb_file_per_table=@@innodb_file_per_table;
set @old_innodb_file_format=@@innodb_file_format;
set @old_innodb_file_format_check=@@innodb_file_format_check;
SET GLOBAL innodb_file_format='Barracuda';
SET GLOBAL innodb_file_per_table=on;
......@@ -27,7 +24,3 @@ CHECK TABLE table0 EXTENDED;
INSERT IGNORE INTO `table0` SET `col19` = '19940127002709', `col20` = 2383927.9055146948, `col21` = 4293243420.5621204000, `col22` = '20511211123705', `col23` = 4289899778.6573381000, `col24` = 4293449279.0540481000, `col25` = 'emphysemic', `col26` = 'dentally', `col27` = '2347406', `col28` = 'eruct', `col30` = 1222, `col31` = 4294372994.9941406000, `col32` = 4291385574.1173744000, `col33` = 'borrowing\'s', `col34` = 'septics', `col35` = 'ratter\'s', `col36` = 'Kaye', `col37` = 'Florentia', `col38` = 'allium', `col39` = 'barkeep', `col40` = '19510407003441', `col41` = 4293559200.4215522000, `col42` = 22482, `col43` = 'decussate', `col44` = 'Brom\'s', `col45` = 'violated', `col46` = 4925506.4635456400, `col47` = 930549, `col48` = '51296066', `col49` = 'voluminously', `col50` = '29306676', `col51` = -88, `col52` = -2153690, `col53` = 4290250202.1464887000, `col54` = 'expropriation', `col55` = 'Aberdeen\'s', `col56` = 20343, `col58` = '19640415171532', `col59` = 'extern', `col60` = 'Ubana', `col61` = 4290487961.8539081000, `col62` = '2147', `col63` = -24271, `col64` = '20750801194548', `col65` = 'Cunaxa\'s', `col66` = 'pasticcio', `col67` = 2795817, `col68` = 'Indore\'s', `col70` = 6864127, `col71` = '1817832', `col72` = '20540506114211', `col73` = '20040101012300', `col74` = 'rationalized', `col75` = '45522', `col76` = 'indene', `col77` = -6964559, `col78` = 4247535.5266884370, `col79` = '20720416124357', `col80` = '2143', `col81` = 4292060102.4466386000, `col82` = 'striving', `col83` = 'boneblack\'s', `col84` = 'redolent', `col85` = 6489697.9009369183, `col86` = 4287473465.9731131000, `col87` = 7726015, `col88` = 'perplexed', `col89` = '17153791', `col90` = 5478587.1108127078, `col91` = 4287091404.7004304000, `col92` = 'Boulez\'s', `col93` = '2931278';
CHECK TABLE table0 EXTENDED;
DROP TABLE table0;
set global innodb_file_per_table=@old_innodb_file_per_table;
set global innodb_file_format=@old_innodb_file_format;
set global innodb_file_format_check=@old_innodb_file_format_check;
set @old_innodb_file_per_table=@@innodb_file_per_table;
set @old_innodb_file_format=@@innodb_file_format;
set @old_innodb_file_format_check=@@innodb_file_format_check;
SET GLOBAL innodb_file_format='Barracuda';
SET GLOBAL innodb_file_per_table=ON;
-- source include/have_innodb.inc
set @old_innodb_file_per_table=@@innodb_file_per_table;
set @old_innodb_file_format=@@innodb_file_format;
set @old_innodb_file_format_check=@@innodb_file_format_check;
SET GLOBAL innodb_file_format='Barracuda';
SET GLOBAL innodb_file_per_table=ON;
......@@ -39,7 +36,3 @@ DROP PROCEDURE insert_many;
ALTER TABLE test1 ENGINE=MyISAM;
DROP TABLE test1;
set global innodb_file_per_table=@old_innodb_file_per_table;
set global innodb_file_format=@old_innodb_file_format;
set global innodb_file_format_check=@old_innodb_file_format_check;
--- mysql-test/r/information_schema.result.orig 2009-04-16 19:59:13.000000000 +0000
+++ mysql-test/r/information_schema.result 2009-04-16 20:00:16.000000000 +0000
@@ -71,6 +71,18 @@
--- mysql-test/r/information_schema.result.orig 2009-01-31 03:38:50.000000000 +0200
+++ mysql-test/r/information_schema.result 2009-01-31 07:51:58.000000000 +0200
@@ -71,6 +71,13 @@
TRIGGERS
USER_PRIVILEGES
VIEWS
+INNODB_BUFFER_POOL_PAGES_INDEX
+INNODB_RSEG
+INNODB_LOCKS
+INNODB_BUFFER_POOL_PAGES
+XTRADB_ENHANCEMENTS
+INNODB_TRX
+INNODB_BUFFER_POOL_PAGES_BLOB
+INNODB_LOCK_WAITS
+INNODB_CMP_RESET
+INNODB_CMP
+INNODB_TRX
+INNODB_CMPMEM_RESET
+INNODB_LOCK_WAITS
+INNODB_CMPMEM
+INNODB_CMP
+INNODB_LOCKS
columns_priv
db
event
@@ -799,6 +811,8 @@
@@ -799,6 +806,8 @@
TABLES UPDATE_TIME datetime
TABLES CHECK_TIME datetime
TRIGGERS CREATED datetime
......@@ -28,92 +23,102 @@
event execute_at datetime
event last_executed datetime
event starts datetime
@@ -847,12 +861,13 @@
TABLE_CONSTRAINTS TABLE_NAME select
TABLE_PRIVILEGES TABLE_NAME select
VIEWS TABLE_NAME select
+INNODB_BUFFER_POOL_PAGES_INDEX table_name select
delete from mysql.user where user='mysqltest_4';
delete from mysql.db where user='mysqltest_4';
@@ -852,7 +861,7 @@
flush privileges;
SELECT table_schema, count(*) FROM information_schema.TABLES WHERE table_schema IN ('mysql', 'INFORMATION_SCHEMA', 'test', 'mysqltest') AND table_name<>'ndb_binlog_index' AND table_name<>'ndb_apply_status' GROUP BY TABLE_SCHEMA;
table_schema count(*)
-information_schema 28
+information_schema 40
+information_schema 35
mysql 22
create table t1 (i int, j int);
create trigger trg1 before insert on t1 for each row
@@ -1267,6 +1282,18 @@
@@ -1267,6 +1276,13 @@
TRIGGERS TRIGGER_SCHEMA
USER_PRIVILEGES GRANTEE
VIEWS TABLE_SCHEMA
+INNODB_BUFFER_POOL_PAGES_INDEX schema_name
+INNODB_RSEG rseg_id
+INNODB_LOCKS lock_id
+INNODB_BUFFER_POOL_PAGES page_type
+XTRADB_ENHANCEMENTS name
+INNODB_TRX trx_id
+INNODB_BUFFER_POOL_PAGES_BLOB space_id
+INNODB_LOCK_WAITS requesting_trx_id
+INNODB_CMP_RESET page_size
+INNODB_CMP page_size
+INNODB_TRX trx_id
+INNODB_CMPMEM_RESET page_size
+INNODB_LOCK_WAITS requesting_trx_id
+INNODB_CMPMEM page_size
+INNODB_CMP page_size
+INNODB_LOCKS lock_id
SELECT t.table_name, c1.column_name
FROM information_schema.tables t
INNER JOIN
@@ -1310,14 +1337,26 @@
@@ -1310,6 +1326,13 @@
TRIGGERS TRIGGER_SCHEMA
USER_PRIVILEGES GRANTEE
VIEWS TABLE_SCHEMA
+INNODB_BUFFER_POOL_PAGES_INDEX schema_name
+INNODB_RSEG rseg_id
+INNODB_LOCKS lock_id
+INNODB_BUFFER_POOL_PAGES page_type
+XTRADB_ENHANCEMENTS name
+INNODB_TRX trx_id
+INNODB_BUFFER_POOL_PAGES_BLOB space_id
+INNODB_LOCK_WAITS requesting_trx_id
+INNODB_CMP_RESET page_size
+INNODB_CMP page_size
+INNODB_TRX trx_id
+INNODB_CMPMEM_RESET page_size
+INNODB_LOCK_WAITS requesting_trx_id
+INNODB_CMPMEM page_size
+INNODB_CMP page_size
+INNODB_LOCKS lock_id
SELECT MAX(table_name) FROM information_schema.tables WHERE table_schema IN ('mysql', 'INFORMATION_SCHEMA', 'test');
MAX(table_name)
-VIEWS
+XTRADB_ENHANCEMENTS
SELECT table_name from information_schema.tables
WHERE table_name=(SELECT MAX(table_name)
FROM information_schema.tables WHERE table_schema IN ('mysql', 'INFORMATION_SCHEMA', 'test'));
table_name
-VIEWS
+XTRADB_ENHANCEMENTS
DROP TABLE IF EXISTS bug23037;
DROP FUNCTION IF EXISTS get_value;
SELECT COLUMN_NAME, MD5(COLUMN_DEFAULT), LENGTH(COLUMN_DEFAULT) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='bug23037';
@@ -1386,6 +1425,17 @@
VIEWS
@@ -1386,6 +1409,13 @@
FILES information_schema.FILES 1
GLOBAL_STATUS information_schema.GLOBAL_STATUS 1
GLOBAL_VARIABLES information_schema.GLOBAL_VARIABLES 1
+INNODB_BUFFER_POOL_PAGES information_schema.INNODB_BUFFER_POOL_PAGES 1
+INNODB_BUFFER_POOL_PAGES_BLOB information_schema.INNODB_BUFFER_POOL_PAGES_BLOB 1
+INNODB_BUFFER_POOL_PAGES_INDEX information_schema.INNODB_BUFFER_POOL_PAGES_INDEX 1
+INNODB_CMP information_schema.INNODB_CMP 1
+INNODB_CMPMEM information_schema.INNODB_CMPMEM 1
+INNODB_CMPMEM_RESET information_schema.INNODB_CMPMEM_RESET 1
+INNODB_CMP_RESET information_schema.INNODB_CMP_RESET 1
+INNODB_LOCKS information_schema.INNODB_LOCKS 1
+INNODB_LOCK_WAITS information_schema.INNODB_LOCK_WAITS 1
+INNODB_RSEG information_schema.INNODB_RSEG 1
+INNODB_TRX information_schema.INNODB_TRX 1
KEY_COLUMN_USAGE information_schema.KEY_COLUMN_USAGE 1
PARTITIONS information_schema.PARTITIONS 1
PLUGINS information_schema.PLUGINS 1
@@ -1404,6 +1454,7 @@
TRIGGERS information_schema.TRIGGERS 1
USER_PRIVILEGES information_schema.USER_PRIVILEGES 1
VIEWS information_schema.VIEWS 1
+XTRADB_ENHANCEMENTS information_schema.XTRADB_ENHANCEMENTS 1
create table t1(f1 int);
create view v1 as select f1+1 as a from t1;
create table t2 (f1 int, f2 int);
diff mysql-test/r/information_schema_db.result.orig mysql-test/r/information_schema_db.result
--- mysql-test/r/information_schema_db.result.orig 2008-08-04 09:27:49.000000000 +0300
+++ mysql-test/r/information_schema_db.result 2008-10-07 12:26:31.000000000 +0300
@@ -33,6 +33,13 @@
TRIGGERS
USER_PRIVILEGES
VIEWS
+INNODB_CMP_RESET
+INNODB_TRX
+INNODB_CMPMEM_RESET
+INNODB_LOCK_WAITS
+INNODB_CMPMEM
+INNODB_CMP
+INNODB_LOCKS
show tables from INFORMATION_SCHEMA like 'T%';
Tables_in_information_schema (T%)
TABLES
diff mysql-test/r/mysqlshow.result.orig mysql-test/r/mysqlshow.result
--- mysql-test/r/mysqlshow.result.orig 2008-08-04 09:27:51.000000000 +0300
+++ mysql-test/r/mysqlshow.result 2008-10-07 12:35:39.000000000 +0300
@@ -107,6 +107,13 @@
| TRIGGERS |
| USER_PRIVILEGES |
| VIEWS |
+| INNODB_CMP_RESET |
+| INNODB_TRX |
+| INNODB_CMPMEM_RESET |
+| INNODB_LOCK_WAITS |
+| INNODB_CMPMEM |
+| INNODB_CMP |
+| INNODB_LOCKS |
+---------------------------------------+
Database: INFORMATION_SCHEMA
+---------------------------------------+
@@ -140,6 +147,13 @@
| TRIGGERS |
| USER_PRIVILEGES |
| VIEWS |
+| INNODB_CMP_RESET |
+| INNODB_TRX |
+| INNODB_CMPMEM_RESET |
+| INNODB_LOCK_WAITS |
+| INNODB_CMPMEM |
+| INNODB_CMP |
+| INNODB_LOCKS |
+---------------------------------------+
Wildcard: inf_rmation_schema
+--------------------+
--- mysql-test/t/innodb-index.test.orig 2009-04-16 22:12:38.000000000 +0000
+++ mysql-test/t/innodb-index.test 2009-04-16 22:16:58.000000000 +0000
@@ -344,6 +344,11 @@
let $per_table=`select @@innodb_file_per_table`;
let $format=`select @@innodb_file_format`;
+
+set @old_innodb_file_per_table=@@innodb_file_per_table;
+set @old_innodb_file_format=@@innodb_file_format;
+set @old_innodb_file_format_check=@@innodb_file_format_check;
+
set global innodb_file_per_table=on;
set global innodb_file_format='Barracuda';
# Test creating a table that could lead to undo log overflow.
@@ -499,3 +504,8 @@
DROP TABLE t2;
DROP TABLE t1;
+
+set global innodb_file_per_table=@old_innodb_file_per_table;
+set global innodb_file_format=@old_innodb_file_format;
+set global innodb_file_format_check=@old_innodb_file_format_check;
+
--- mysql-test/r/innodb-index.result.orig 2009-04-16 22:18:18.000000000 +0000
+++ mysql-test/r/innodb-index.result 2009-04-16 22:18:47.000000000 +0000
@@ -877,6 +877,9 @@
44
commit;
drop table t1;
+set @old_innodb_file_per_table=@@innodb_file_per_table;
+set @old_innodb_file_format=@@innodb_file_format;
+set @old_innodb_file_format_check=@@innodb_file_format_check;
set global innodb_file_per_table=on;
set global innodb_file_format='Barracuda';
create table t1(a blob,b blob,c blob,d blob,e blob,f blob,g blob,h blob,
@@ -1125,3 +1128,6 @@
This part of the innodb-index test causes mysqld to print some warnings
and subsequently the whole mysql-test suite to fail.
A permanent solution is probably to remove the printouts from the source
code or to somehow tell the mysql-test suite that warnings are expected.
Currently we simply do not execute the problematic tests. Please
coordinate a permanent solution with Marko, who added those tests.
This cannot be proposed to MySQL because it touches files that are not
in the MySQL source repository.
Index: storage/innobase/mysql-test/innodb-index.result
===================================================================
--- storage/innobase/mysql-test/innodb-index.result (revision 2870)
+++ storage/innobase/mysql-test/innodb-index.result (working copy)
@@ -43,19 +43,12 @@ t1 CREATE TABLE `t1` (
`b` int(11) DEFAULT NULL,
`c` char(10) NOT NULL,
`d` varchar(20) DEFAULT NULL,
KEY `d2` (`d`),
KEY `b` (`b`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
DROP TABLE t2;
DROP TABLE t1;
+set global innodb_file_per_table=@old_innodb_file_per_table;
+set global innodb_file_format=@old_innodb_file_format;
+set global innodb_file_format_check=@old_innodb_file_format_check;
-CREATE TABLE `t1#1`(a INT PRIMARY KEY) ENGINE=InnoDB;
-alter table t1 add unique index (c), add index (d);
-ERROR HY000: Table 'test.t1#1' already exists
-rename table `t1#1` to `t1#2`;
-alter table t1 add unique index (c), add index (d);
-ERROR HY000: Table 'test.t1#2' already exists
-drop table `t1#2`;
alter table t1 add unique index (c), add index (d);
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL,
`b` int(11) DEFAULT NULL,
Index: storage/innobase/mysql-test/innodb-index.test
===================================================================
--- storage/innobase/mysql-test/innodb-index.test (revision 2870)
+++ storage/innobase/mysql-test/innodb-index.test (working copy)
@@ -14,22 +14,12 @@ select * from t1 force index (d2) order
--error ER_DUP_ENTRY
alter table t1 add unique index (b);
show create table t1;
alter table t1 add index (b);
show create table t1;
-# Check how existing tables interfere with temporary tables.
-CREATE TABLE `t1#1`(a INT PRIMARY KEY) ENGINE=InnoDB;
-
---error 156
-alter table t1 add unique index (c), add index (d);
-rename table `t1#1` to `t1#2`;
---error 156
-alter table t1 add unique index (c), add index (d);
-drop table `t1#2`;
-
alter table t1 add unique index (c), add index (d);
show create table t1;
explain select * from t1 force index(c) order by c;
alter table t1 add primary key (a), drop index c;
show create table t1;
--error ER_MULTIPLE_PRI_KEY
......@@ -331,15 +331,8 @@ sync_cell_get_event(
return(((mutex_t *) cell->wait_object)->event);
} else if (type == RW_LOCK_WAIT_EX) {
return(((rw_lock_t *) cell->wait_object)->wait_ex_event);
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
} else if (type == RW_LOCK_SHARED) {
return(((rw_lock_t *) cell->wait_object)->s_event);
} else { /* RW_LOCK_EX */
return(((rw_lock_t *) cell->wait_object)->x_event);
#else
} else { /* RW_LOCK_SHARED and RW_LOCK_EX wait on the same event */
return(((rw_lock_t *) cell->wait_object)->event);
#endif
}
}
......@@ -510,7 +503,7 @@ sync_array_cell_print(
|| type == RW_LOCK_WAIT_EX
|| type == RW_LOCK_SHARED) {
fputs(type == RW_LOCK_SHARED ? "S-lock on" : "X-lock on", file);
fputs(type == RW_LOCK_EX ? "X-lock on" : "S-lock on", file);
rwlock = cell->old_wait_rw_lock;
......@@ -530,21 +523,12 @@ sync_array_cell_print(
}
fprintf(file,
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
"number of readers %lu, s_waiters flag %lu, x_waiters flag %lu, "
#else
"number of readers %lu, waiters flag %lu, "
#endif
"lock_word: %lx\n"
"Last time read locked in file %s line %lu\n"
"Last time write locked in file %s line %lu\n",
(ulong) rw_lock_get_reader_count(rwlock),
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
(ulong) rwlock->s_waiters,
(ulong) (rwlock->x_waiters || rwlock->wait_ex_waiters),
#else
(ulong) rwlock->waiters,
#endif
rwlock->lock_word,
rwlock->last_s_file_name,
(ulong) rwlock->last_s_line,
......
......@@ -250,17 +250,7 @@ rw_lock_create_func(
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
lock->lock_word = X_LOCK_DECR;
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
lock->s_waiters = 0;
lock->x_waiters = 0;
lock->wait_ex_waiters = 0;
lock->writer = RW_LOCK_NOT_LOCKED;
lock->writer_count = 0;
lock->reader_count = 0;
lock->writer_is_wait_ex = FALSE;
#else
lock->waiters = 0;
#endif
/* We set this value to signify that lock->writer_thread
contains garbage at initialization and cannot be used for
......@@ -283,12 +273,7 @@ rw_lock_create_func(
lock->last_x_file_name = "not yet reserved";
lock->last_s_line = 0;
lock->last_x_line = 0;
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
lock->s_event = os_event_create(NULL);
lock->x_event = os_event_create(NULL);
#else
lock->event = os_event_create(NULL);
#endif
lock->wait_ex_event = os_event_create(NULL);
mutex_enter(&rw_lock_list_mutex);
......@@ -314,15 +299,7 @@ rw_lock_free(
rw_lock_t* lock) /* in: rw-lock */
{
ut_ad(rw_lock_validate(lock));
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
ut_a(rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED);
ut_a(rw_lock_get_s_waiters(lock) == 0);
ut_a(rw_lock_get_x_waiters(lock) == 0);
ut_a(rw_lock_get_wx_waiters(lock) == 0);
ut_a(rw_lock_get_reader_count(lock) == 0);
#else
ut_a(lock->lock_word == X_LOCK_DECR);
#endif
lock->magic_n = 0;
......@@ -331,12 +308,7 @@ rw_lock_free(
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
mutex_enter(&rw_lock_list_mutex);
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
os_event_free(lock->s_event);
os_event_free(lock->x_event);
#else
os_event_free(lock->event);
#endif
os_event_free(lock->wait_ex_event);
......@@ -364,23 +336,12 @@ rw_lock_validate(
{
ut_a(lock);
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
ut_a(lock->magic_n == RW_LOCK_MAGIC_N);
ulint waiters = rw_lock_get_s_waiters(lock);
ut_a(waiters == 0 || waiters == 1);
waiters = rw_lock_get_x_waiters(lock);
ut_a(waiters == 0 || waiters == 1);
waiters = rw_lock_get_wx_waiters(lock);
ut_a(waiters == 0 || waiters == 1);
#else
ulint waiters = rw_lock_get_waiters(lock);
lint lock_word = lock->lock_word;
ut_a(lock->magic_n == RW_LOCK_MAGIC_N);
ut_a(waiters == 0 || waiters == 1);
ut_a(lock_word > -X_LOCK_DECR ||(-lock_word) % X_LOCK_DECR == 0);
#endif
return(TRUE);
}
......@@ -410,12 +371,7 @@ rw_lock_s_lock_spin(
lock_loop:
/* Spin waiting for the writer field to become free */
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
while (i < SYNC_SPIN_ROUNDS
&& rw_lock_get_writer(lock) != RW_LOCK_NOT_LOCKED) {
#else
while (i < SYNC_SPIN_ROUNDS && lock->lock_word <= 0) {
#endif
if (srv_spin_wait_delay) {
ut_delay(ut_rnd_interval(0, srv_spin_wait_delay));
}
......@@ -456,29 +412,12 @@ lock_loop:
/* Set waiters before checking lock_word to ensure wake-up
signal is sent. This may lead to some unnecessary signals. */
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
rw_lock_set_s_waiter_flag(lock);
#else
rw_lock_set_waiter_flag(lock);
#endif
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
for (i = 0; i < 4; i++) {
#endif
if (TRUE == rw_lock_s_lock_low(lock, pass, file_name, line)) {
sync_array_free_cell(sync_primary_wait_array, index);
return; /* Success */
}
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
}
/* If wait_ex_waiter stalls, wakes it. */
if (lock->reader_count == 0
&& os_compare_and_swap(&lock->wait_ex_waiters, 1, 0)) {
os_event_set(lock->wait_ex_event);
sync_array_object_signalled(sync_primary_wait_array);
}
#endif
if (srv_print_latch_waits) {
fprintf(stderr,
......@@ -517,12 +456,7 @@ rw_lock_x_lock_move_ownership(
{
ut_ad(rw_lock_is_locked(lock, RW_LOCK_EX));
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
lock->writer_thread = os_thread_get_curr_id();
lock->recursive = TRUE;
#else
rw_lock_set_writer_id_and_recursion_flag(lock, TRUE);
#endif
}
/**********************************************************************
......@@ -596,11 +530,7 @@ rw_lock_x_lock_wait(
/**********************************************************************
Low-level function for acquiring an exclusive lock. */
UNIV_INLINE
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
ulint
#else
ibool
#endif
rw_lock_x_lock_low(
/*===============*/
/* out: RW_LOCK_NOT_LOCKED if did
......@@ -613,90 +543,6 @@ rw_lock_x_lock_low(
{
os_thread_id_t curr_thread = os_thread_get_curr_id();
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
retry_writer:
/* try to lock writer */
if(__sync_lock_test_and_set(&(lock->writer),RW_LOCK_EX)
== RW_LOCK_NOT_LOCKED) {
/* success */
/* obtain RW_LOCK_WAIT_EX right */
lock->writer_thread = curr_thread;
lock->recursive = pass ? FALSE : TRUE;
lock->writer_is_wait_ex = TRUE;
/* atomic operation may be safer about memory order. */
__sync_synchronize();
#ifdef UNIV_SYNC_DEBUG
rw_lock_add_debug_info(lock, pass, RW_LOCK_WAIT_EX,
file_name, line);
#endif
}
if (!os_thread_eq(lock->writer_thread, curr_thread)) {
return(RW_LOCK_NOT_LOCKED);
}
switch(rw_lock_get_writer(lock)) {
case RW_LOCK_WAIT_EX:
/* have right to try x-lock */
retry_x_lock:
/* try x-lock */
if(__sync_sub_and_fetch(&(lock->lock_word),
X_LOCK_DECR) == 0) {
/* success */
lock->recursive = pass ? FALSE : TRUE;
lock->writer_is_wait_ex = FALSE;
__sync_fetch_and_add(&(lock->writer_count),1);
#ifdef UNIV_SYNC_DEBUG
rw_lock_remove_debug_info(lock, pass, RW_LOCK_WAIT_EX);
rw_lock_add_debug_info(lock, pass, RW_LOCK_EX,
file_name, line);
#endif
lock->last_x_file_name = file_name;
lock->last_x_line = line;
/* Locking succeeded, we may return */
return(RW_LOCK_EX);
} else if(__sync_fetch_and_add(&(lock->lock_word),
X_LOCK_DECR) == 0) {
/* retry x-lock */
goto retry_x_lock;
}
/* There are readers, we have to wait */
return(RW_LOCK_WAIT_EX);
break;
case RW_LOCK_EX:
/* already have x-lock */
if (lock->recursive && (pass == 0)) {
__sync_fetch_and_add(&(lock->writer_count),1);
#ifdef UNIV_SYNC_DEBUG
rw_lock_add_debug_info(lock, pass, RW_LOCK_EX, file_name,
line);
#endif
lock->last_x_file_name = file_name;
lock->last_x_line = line;
/* Locking succeeded, we may return */
return(RW_LOCK_EX);
}
return(RW_LOCK_NOT_LOCKED);
break;
default: /* RW_LOCK_NOT_LOCKED? maybe impossible */
goto retry_writer;
}
/* Locking did not succeed */
return(RW_LOCK_NOT_LOCKED);
#else
if (rw_lock_lock_word_decr(lock, X_LOCK_DECR)) {
/* lock->recursive also tells us if the writer_thread
......@@ -734,7 +580,6 @@ retry_x_lock:
lock->last_x_line = (unsigned int) line;
return(TRUE);
#endif
}
/**********************************************************************
......@@ -759,55 +604,18 @@ rw_lock_x_lock_func(
ulint index; /* index of the reserved wait cell */
ulint i; /* spin round count */
ibool spinning = FALSE;
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
ulint state = RW_LOCK_NOT_LOCKED; /* lock state acquired */
ulint prev_state = RW_LOCK_NOT_LOCKED;
#endif
ut_ad(rw_lock_validate(lock));
i = 0;
lock_loop:
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
prev_state = state;
state = rw_lock_x_lock_low(lock, pass, file_name, line);
lock_loop_2:
if (state != prev_state) i=0; /* if progress, reset counter. */
if (state == RW_LOCK_EX) {
#else
if (rw_lock_x_lock_low(lock, pass, file_name, line)) {
#endif
rw_x_spin_round_count += i;
return; /* Locking succeeded */
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
} else if (state == RW_LOCK_WAIT_EX) {
if (!spinning) {
spinning = TRUE;
rw_x_spin_wait_count++;
}
/* Spin waiting for the reader count field to become zero */
while (i < SYNC_SPIN_ROUNDS
&& lock->lock_word != X_LOCK_DECR) {
if (srv_spin_wait_delay) {
ut_delay(ut_rnd_interval(0,
srv_spin_wait_delay));
}
i++;
}
if (i == SYNC_SPIN_ROUNDS) {
os_thread_yield();
} else {
goto lock_loop;
}
#endif
} else {
if (!spinning) {
......@@ -817,11 +625,7 @@ lock_loop_2:
/* Spin waiting for the lock_word to become free */
while (i < SYNC_SPIN_ROUNDS
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
&& rw_lock_get_writer(lock) != RW_LOCK_NOT_LOCKED) {
#else
&& lock->lock_word <= 0) {
#endif
if (srv_spin_wait_delay) {
ut_delay(ut_rnd_interval(0,
srv_spin_wait_delay));
......@@ -848,46 +652,18 @@ lock_loop_2:
sync_array_reserve_cell(sync_primary_wait_array,
lock,
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
(state == RW_LOCK_WAIT_EX)
? RW_LOCK_WAIT_EX : RW_LOCK_EX,
#else
RW_LOCK_EX,
#endif
file_name, line,
&index);
/* Waiters must be set before checking lock_word, to ensure signal
is sent. This could lead to a few unnecessary wake-up signals. */
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
if (state == RW_LOCK_WAIT_EX) {
rw_lock_set_wx_waiter_flag(lock);
} else {
rw_lock_set_x_waiter_flag(lock);
}
#else
rw_lock_set_waiter_flag(lock);
#endif
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
for (i = 0; i < 4; i++) {
prev_state = state;
state = rw_lock_x_lock_low(lock, pass, file_name, line);
if (state == RW_LOCK_EX) {
sync_array_free_cell(sync_primary_wait_array, index);
return; /* Locking succeeded */
} else if (state != prev_state) {
/* retry! */
sync_array_free_cell(sync_primary_wait_array, index);
goto lock_loop_2;
}
}
#else
if (rw_lock_x_lock_low(lock, pass, file_name, line)) {
sync_array_free_cell(sync_primary_wait_array, index);
return; /* Locking succeeded */
}
#endif
if (srv_print_latch_waits) {
fprintf(stderr,
......@@ -1138,24 +914,11 @@ rw_lock_list_print_info(
fprintf(file, "RW-LOCK: %p ", (void*) lock);
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
if (rw_lock_get_s_waiters(lock)) {
fputs(" s_waiters for the lock exist", file);
}
if (rw_lock_get_x_waiters(lock)) {
fputs(" x_waiters for the lock exist", file);
}
if (rw_lock_get_wx_waiters(lock)) {
fputs(" wait_ex_waiters for the lock exist", file);
}
putc('\n', file);
#else
if (rw_lock_get_waiters(lock)) {
fputs(" Waiters for the lock exist\n", file);
} else {
putc('\n', file);
}
#endif
info = UT_LIST_GET_FIRST(lock->debug_list);
while (info != NULL) {
......@@ -1194,24 +957,11 @@ rw_lock_print(
#endif
if (lock->lock_word != X_LOCK_DECR) {
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
if (rw_lock_get_s_waiters(lock)) {
fputs(" s_waiters for the lock exist", stderr);
}
if (rw_lock_get_x_waiters(lock)) {
fputs(" x_waiters for the lock exist", stderr);
}
if (rw_lock_get_wx_waiters(lock)) {
fputs(" wait_ex_waiters for the lock exist", stderr);
}
putc('\n', stderr);
#else
if (rw_lock_get_waiters(lock)) {
fputs(" Waiters for the lock exist\n", stderr);
} else {
putc('\n', stderr);
}
#endif
info = UT_LIST_GET_FIRST(lock->debug_list);
while (info != NULL) {
......
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