Commit b38eada6 authored by Vasil Dimov's avatar Vasil Dimov

Merge mysql-5.5-innodb -> mysql-5.5-bugfixing

parents 49652079 02492ae3
......@@ -528,6 +528,7 @@ long long thd_test_options(const MYSQL_THD thd, long long test_options);
int thd_sql_command(const MYSQL_THD thd);
const char *thd_proc_info(MYSQL_THD thd, const char *info);
void **thd_ha_data(const MYSQL_THD thd, const struct handlerton *hton);
void thd_storage_lock_wait(MYSQL_THD thd, long long value);
int thd_tx_isolation(const MYSQL_THD thd);
char *thd_security_context(MYSQL_THD thd, char *buffer, unsigned int length,
unsigned int max_query_len);
......
......@@ -151,6 +151,7 @@ long long thd_test_options(const void* thd, long long test_options);
int thd_sql_command(const void* thd);
const char *thd_proc_info(void* thd, const char *info);
void **thd_ha_data(const void* thd, const struct handlerton *hton);
void thd_storage_lock_wait(void* thd, long long value);
int thd_tx_isolation(const void* thd);
char *thd_security_context(void* thd, char *buffer, unsigned int length,
unsigned int max_query_len);
......
......@@ -54,8 +54,8 @@ text1 like 'teststring_%' ORDER BY text1;
text1
teststring
teststring
select concat('|', text1, '|') from t1 where text1='teststring' or text1 like 'teststring_%';
concat('|', text1, '|')
select concat('|', text1, '|') as c from t1 where text1='teststring' or text1 like 'teststring_%' order by c;
c
|teststring |
|teststring|
select concat('|', text1, '|') from t1 where text1='teststring' or text1 > 'teststring\t';
......@@ -105,11 +105,11 @@ select concat('|', text1, '|') from t1 where text1 like 'teststring_%';
concat('|', text1, '|')
|teststring |
|teststring |
select concat('|', text1, '|') from t1 where text1='teststring' or text1 like 'teststring_%';
concat('|', text1, '|')
select concat('|', text1, '|') as c from t1 where text1='teststring' or text1 like 'teststring_%' order by c;
c
|teststring |
|teststring|
|teststring |
|teststring|
select concat('|', text1, '|') from t1 where text1='teststring' or text1 > 'teststring\t';
concat('|', text1, '|')
|teststring|
......@@ -123,8 +123,8 @@ concat('|', text1, '|')
drop table t1;
create table t1 (text1 varchar(32) not NULL, KEY key1 (text1)) pack_keys=0;
insert into t1 values ('teststring'), ('nothing'), ('teststring\t');
select concat('|', text1, '|') from t1 where text1='teststring' or text1 like 'teststring_%';
concat('|', text1, '|')
select concat('|', text1, '|') as c from t1 where text1='teststring' or text1 like 'teststring_%' order by c;
c
|teststring |
|teststring|
select concat('|', text1, '|') from t1 where text1='teststring' or text1 >= 'teststring\t';
......@@ -203,13 +203,13 @@ teststring
teststring
select text1, length(text1) from t1 where text1='teststring' or text1 like 'teststring_%';
text1 length(text1)
teststring 11
teststring 10
teststring 11
teststring 11
select text1, length(text1) from t1 where text1='teststring' or text1 >= 'teststring\t';
text1 length(text1)
teststring 11
teststring 10
teststring 11
teststring 11
select concat('|', text1, '|') from t1 order by text1;
concat('|', text1, '|')
......
......@@ -15,7 +15,7 @@ insert into t1 values (-5, 1, 1),
(10, 1, 1);
explain select * from t1 force index(key1, key2) where key1 < 3 or key2 < 3;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index_merge key1,key2 key1,key2 5,5 NULL 4 Using sort_union(key1,key2); Using where
1 SIMPLE t1 index_merge key1,key2 key1,key2 5,5 NULL 5 Using sort_union(key1,key2); Using where
select * from t1 force index(key1, key2) where key1 < 3 or key2 < 3;
pk1 key1 key2
-100 1 1
......
......@@ -233,7 +233,7 @@ a+0 b+0
127 403
explain select a+0, b+0 from t1 where a > 40 and b > 200 order by 1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 2 NULL 19 Using where; Using index; Using filesort
1 SIMPLE t1 range a a 2 NULL 27 Using where; Using index; Using filesort
select a+0, b+0 from t1 where a > 40 and b > 200 order by 1;
a+0 b+0
44 307
......
......@@ -572,7 +572,7 @@ COUNT(*)
EXPLAIN
SELECT COUNT(*) FROM t2 WHERE p=POINTFROMTEXT('POINT(1 2)');
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ref p p 28 const 1 Using where
1 SIMPLE t2 ref p p 28 const 2 Using where
SELECT COUNT(*) FROM t2 WHERE p=POINTFROMTEXT('POINT(1 2)');
COUNT(*)
2
......
......@@ -889,13 +889,13 @@ EXPLAIN SELECT * FROM t1 WHERE b BETWEEN 1 AND 2 ORDER BY a;
id 1
select_type SIMPLE
table t1
type range
type index
possible_keys bkey
key bkey
key_len 5
key PRIMARY
key_len 4
ref NULL
rows 16
Extra Using where; Using index; Using filesort
rows 32
Extra Using where
SELECT * FROM t1 WHERE b BETWEEN 1 AND 2 ORDER BY a;
a b
1 2
......@@ -934,12 +934,12 @@ EXPLAIN SELECT * FROM t1 WHERE b BETWEEN 1 AND 2 ORDER BY b,a;
id 1
select_type SIMPLE
table t1
type range
type index
possible_keys bkey
key bkey
key_len 5
ref NULL
rows 16
rows 32
Extra Using where; Using index
SELECT * FROM t1 WHERE b BETWEEN 1 AND 2 ORDER BY b,a;
a b
......@@ -989,7 +989,7 @@ possible_keys bkey
key bkey
key_len 5
ref const
rows 8
rows 16
Extra Using where; Using index; Using filesort
SELECT * FROM t2 WHERE b=1 ORDER BY a;
a b c
......@@ -1018,7 +1018,7 @@ possible_keys bkey
key bkey
key_len 10
ref const,const
rows 8
rows 16
Extra Using where; Using index
SELECT * FROM t2 WHERE b=1 AND c=1 ORDER BY a;
a b c
......@@ -1047,7 +1047,7 @@ possible_keys bkey
key bkey
key_len 10
ref const,const
rows 8
rows 16
Extra Using where; Using index
SELECT * FROM t2 WHERE b=1 AND c=1 ORDER BY b,c,a;
a b c
......@@ -1076,7 +1076,7 @@ possible_keys bkey
key bkey
key_len 10
ref const,const
rows 8
rows 16
Extra Using where; Using index
SELECT * FROM t2 WHERE b=1 AND c=1 ORDER BY c,a;
a b c
......@@ -1213,7 +1213,7 @@ possible_keys b
key b
key_len 5
ref const
rows 1
rows 2
Extra Using where; Using index
SELECT * FROM t1 WHERE b=2 ORDER BY a ASC;
a b
......@@ -1228,7 +1228,7 @@ possible_keys b
key b
key_len 5
ref const
rows 1
rows 2
Extra Using where; Using index
SELECT * FROM t1 WHERE b=2 ORDER BY a DESC;
a b
......@@ -1372,7 +1372,7 @@ INSERT INTO t1 (a,b,c) VALUES (1,1,1), (2,1,1), (3,1,1), (4,1,1);
INSERT INTO t1 (a,b,c) SELECT a+4,b,c FROM t1;
EXPLAIN SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index t1_b PRIMARY 4 NULL 8 Using where
1 SIMPLE t1 range t1_b t1_b 5 NULL 8 Using where
SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5;
a b c
8 1 1
......@@ -1735,7 +1735,7 @@ SELECT 1 FROM (SELECT COUNT(DISTINCT c1)
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> system NULL NULL NULL NULL 1
2 DERIVED t1 index c3,c2 c2 10 NULL 5
2 DERIVED t1 ALL c3,c2 c3 5 5 Using filesort
DROP TABLE t1;
CREATE TABLE t1 (c1 REAL, c2 REAL, c3 REAL, KEY (c3), KEY (c2, c3))
ENGINE=InnoDB;
......@@ -1749,7 +1749,7 @@ SELECT 1 FROM (SELECT COUNT(DISTINCT c1)
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> system NULL NULL NULL NULL 1
2 DERIVED t1 index c3,c2 c2 18 NULL 5
2 DERIVED t1 ALL c3,c2 c3 9 5 Using filesort
DROP TABLE t1;
CREATE TABLE t1 (c1 DECIMAL(12,2), c2 DECIMAL(12,2), c3 DECIMAL(12,2),
KEY (c3), KEY (c2, c3))
......@@ -1764,7 +1764,7 @@ SELECT 1 FROM (SELECT COUNT(DISTINCT c1)
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> system NULL NULL NULL NULL 1
2 DERIVED t1 index c3,c2 c2 14 NULL 5
2 DERIVED t1 ALL c3,c2 c3 7 5 Using filesort
DROP TABLE t1;
End of 5.1 tests
#
......@@ -1871,7 +1871,7 @@ possible_keys b
key b
key_len 5
ref NULL
rows 3
rows 5
Extra Using where; Using index
EXPLAIN SELECT c FROM bar WHERE c>2;;
id 1
......@@ -2536,7 +2536,7 @@ f1 f2 f3 f4
EXPLAIN SELECT * FROM t1 WHERE f2 = 1 AND f4 = TRUE
ORDER BY f1 DESC LIMIT 5;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range f2,f4 f4 1 NULL 11 Using where
1 SIMPLE t1 range f2,f4 f4 1 NULL 22 Using where
DROP TABLE t1;
#
# Bug#54117 crash in thr_multi_unlock, temporary table
......
SET @start_global_value = @@global.innodb_strict_mode;
SELECT @start_global_value;
@start_global_value
1
0
Valid values are 'ON' and 'OFF'
select @@global.innodb_strict_mode in (0, 1);
@@global.innodb_strict_mode in (0, 1)
1
select @@global.innodb_strict_mode;
@@global.innodb_strict_mode
1
0
select @@session.innodb_strict_mode in (0, 1);
@@session.innodb_strict_mode in (0, 1)
1
select @@session.innodb_strict_mode;
@@session.innodb_strict_mode
1
0
show global variables like 'innodb_strict_mode';
Variable_name Value
innodb_strict_mode ON
innodb_strict_mode OFF
show session variables like 'innodb_strict_mode';
Variable_name Value
innodb_strict_mode ON
innodb_strict_mode OFF
select * from information_schema.global_variables where variable_name='innodb_strict_mode';
VARIABLE_NAME VARIABLE_VALUE
INNODB_STRICT_MODE ON
INNODB_STRICT_MODE OFF
select * from information_schema.session_variables where variable_name='innodb_strict_mode';
VARIABLE_NAME VARIABLE_VALUE
INNODB_STRICT_MODE ON
INNODB_STRICT_MODE OFF
set global innodb_strict_mode='OFF';
set session innodb_strict_mode='OFF';
select @@global.innodb_strict_mode;
......@@ -117,4 +117,4 @@ INNODB_STRICT_MODE ON
SET @@global.innodb_strict_mode = @start_global_value;
SELECT @@global.innodb_strict_mode;
@@global.innodb_strict_mode
1
0
......@@ -27,7 +27,7 @@ alter table t1 modify text1 char(32) binary not null;
check table t1;
select * from t1 ignore key (key1) where text1='teststring' or
text1 like 'teststring_%' ORDER BY text1;
select concat('|', text1, '|') from t1 where text1='teststring' or text1 like 'teststring_%';
select concat('|', text1, '|') as c from t1 where text1='teststring' or text1 like 'teststring_%' order by c;
select concat('|', text1, '|') from t1 where text1='teststring' or text1 > 'teststring\t';
select text1, length(text1) from t1 order by text1;
select text1, length(text1) from t1 order by binary text1;
......@@ -44,14 +44,14 @@ select concat('|', text1, '|') from t1 where text1='teststring';
select concat('|', text1, '|') from t1 where text1='teststring ';
explain select concat('|', text1, '|') from t1 where text1='teststring ';
select concat('|', text1, '|') from t1 where text1 like 'teststring_%';
select concat('|', text1, '|') from t1 where text1='teststring' or text1 like 'teststring_%';
select concat('|', text1, '|') as c from t1 where text1='teststring' or text1 like 'teststring_%' order by c;
select concat('|', text1, '|') from t1 where text1='teststring' or text1 > 'teststring\t';
select concat('|', text1, '|') from t1 order by text1;
drop table t1;
create table t1 (text1 varchar(32) not NULL, KEY key1 (text1)) pack_keys=0;
insert into t1 values ('teststring'), ('nothing'), ('teststring\t');
select concat('|', text1, '|') from t1 where text1='teststring' or text1 like 'teststring_%';
select concat('|', text1, '|') as c from t1 where text1='teststring' or text1 like 'teststring_%' order by c;
select concat('|', text1, '|') from t1 where text1='teststring' or text1 >= 'teststring\t';
drop table t1;
......
......@@ -306,6 +306,11 @@ void **thd_ha_data(const THD *thd, const struct handlerton *hton)
return (void **) &thd->ha_data[hton->slot].ha_ptr;
}
extern "C"
void thd_storage_lock_wait(THD *thd, long long value)
{
thd->utime_after_lock+= value;
}
/**
Provide a handler data getter to simplify coding
......
......@@ -1501,7 +1501,7 @@ public:
// track down slow pthread_create
ulonglong prior_thr_create_utime, thr_create_utime;
ulonglong start_utime, utime_after_lock;
thr_lock_type update_lock_default;
Delayed_insert *di;
......
......@@ -3153,6 +3153,7 @@ btr_cur_add_path_info(
{
btr_path_t* slot;
rec_t* rec;
page_t* page;
ut_a(cursor->path_arr);
......@@ -3175,8 +3176,155 @@ btr_cur_add_path_info(
slot = cursor->path_arr + (root_height - height);
page = page_align(rec);
slot->nth_rec = page_rec_get_n_recs_before(rec);
slot->n_recs = page_get_n_recs(page_align(rec));
slot->n_recs = page_get_n_recs(page);
slot->page_no = page_get_page_no(page);
slot->page_level = btr_page_get_level_low(page);
}
/*******************************************************************//**
Estimate the number of rows between slot1 and slot2 for any level on a
B-tree. This function starts from slot1->page and reads a few pages to
the right, counting their records. If we reach slot2->page quickly then
we know exactly how many records there are between slot1 and slot2 and
we set is_n_rows_exact to TRUE. If we cannot reach slot2->page quickly
then we calculate the average number of records in the pages scanned
so far and assume that all pages that we did not scan up to slot2->page
contain the same number of records, then we multiply that average to
the number of pages between slot1->page and slot2->page (which is
n_rows_on_prev_level). In this case we set is_n_rows_exact to FALSE.
@return number of rows (exact or estimated) */
static
ib_int64_t
btr_estimate_n_rows_in_range_on_level(
/*==================================*/
dict_index_t* index, /*!< in: index */
btr_path_t* slot1, /*!< in: left border */
btr_path_t* slot2, /*!< in: right border */
ib_int64_t n_rows_on_prev_level, /*!< in: number of rows
on the previous level for the
same descend paths; used to
determine the numbe of pages
on this level */
ibool* is_n_rows_exact) /*!< out: TRUE if the returned
value is exact i.e. not an
estimation */
{
ulint space;
ib_int64_t n_rows;
ulint n_pages_read;
ulint page_no;
ulint zip_size;
ulint level;
space = dict_index_get_space(index);
n_rows = 0;
n_pages_read = 0;
/* Assume by default that we will scan all pages between
slot1->page_no and slot2->page_no */
*is_n_rows_exact = TRUE;
/* add records from slot1->page_no which are to the right of
the record which serves as a left border of the range, if any */
if (slot1->nth_rec < slot1->n_recs) {
n_rows += slot1->n_recs - slot1->nth_rec;
}
/* add records from slot2->page_no which are to the left of
the record which servers as a right border of the range, if any */
if (slot2->nth_rec > 1) {
n_rows += slot2->nth_rec - 1;
}
/* count the records in the pages between slot1->page_no and
slot2->page_no (non inclusive), if any */
zip_size = fil_space_get_zip_size(space);
/* Do not read more than this number of pages in order not to hurt
performance with this code which is just an estimation. If we read
this many pages before reaching slot2->page_no then we estimate the
average from the pages scanned so far */
#define N_PAGES_READ_LIMIT 10
page_no = slot1->page_no;
level = slot1->page_level;
do {
mtr_t mtr;
page_t* page;
buf_block_t* block;
mtr_start(&mtr);
/* fetch the page */
block = buf_page_get(space, zip_size, page_no, RW_S_LATCH,
&mtr);
page = buf_block_get_frame(block);
/* It is possible that the tree has been reorganized in the
meantime and this is a different page. If this happens the
calculated estimate will be bogus, which is not fatal as
this is only an estimate. We are sure that a page with
page_no exists because InnoDB never frees pages, only
reuses them. */
if (fil_page_get_type(page) != FIL_PAGE_INDEX
|| btr_page_get_index_id(page) != index->id
|| btr_page_get_level_low(page) != level) {
/* The page got reused for something else */
goto inexact;
}
n_pages_read++;
if (page_no != slot1->page_no) {
/* Do not count the records on slot1->page_no,
we already counted them before this loop. */
n_rows += page_get_n_recs(page);
}
page_no = btr_page_get_next(page, &mtr);
mtr_commit(&mtr);
if (n_pages_read == N_PAGES_READ_LIMIT
|| page_no == FIL_NULL) {
/* Either we read too many pages or
we reached the end of the level without passing
through slot2->page_no, the tree must have changed
in the meantime */
goto inexact;
}
} while (page_no != slot2->page_no);
return(n_rows);
inexact:
*is_n_rows_exact = FALSE;
/* We did interrupt before reaching slot2->page */
if (n_pages_read > 0) {
/* The number of pages on this level is
n_rows_on_prev_level, multiply it by the
average number of recs per page so far */
n_rows = n_rows_on_prev_level
* n_rows / n_pages_read;
} else {
/* The tree changed before we could even
start with slot1->page_no */
n_rows = 10;
}
return(n_rows);
}
/*******************************************************************//**
......@@ -3201,6 +3349,7 @@ btr_estimate_n_rows_in_range(
ibool diverged_lot;
ulint divergence_level;
ib_int64_t n_rows;
ibool is_n_rows_exact;
ulint i;
mtr_t mtr;
......@@ -3243,6 +3392,7 @@ btr_estimate_n_rows_in_range(
/* We have the path information for the range in path1 and path2 */
n_rows = 1;
is_n_rows_exact = TRUE;
diverged = FALSE; /* This becomes true when the path is not
the same any more */
diverged_lot = FALSE; /* This becomes true when the paths are
......@@ -3258,7 +3408,7 @@ btr_estimate_n_rows_in_range(
if (slot1->nth_rec == ULINT_UNDEFINED
|| slot2->nth_rec == ULINT_UNDEFINED) {
if (i > divergence_level + 1) {
if (i > divergence_level + 1 && !is_n_rows_exact) {
/* In trees whose height is > 1 our algorithm
tends to underestimate: multiply the estimate
by 2: */
......@@ -3270,7 +3420,9 @@ btr_estimate_n_rows_in_range(
to over 1 / 2 of the estimated rows in the whole
table */
if (n_rows > index->table->stat_n_rows / 2) {
if (n_rows > index->table->stat_n_rows / 2
&& !is_n_rows_exact) {
n_rows = index->table->stat_n_rows / 2;
/* If there are just 0 or 1 rows in the table,
......@@ -3296,10 +3448,15 @@ btr_estimate_n_rows_in_range(
divergence_level = i;
}
} else {
/* Maybe the tree has changed between
searches */
return(10);
/* It is possible that
slot1->nth_rec >= slot2->nth_rec
if, for example, we have a single page
tree which contains (inf, 5, 6, supr)
and we select where x > 20 and x < 30;
in this case slot1->nth_rec will point
to the supr record and slot2->nth_rec
will point to 6 */
n_rows = 0;
}
} else if (diverged && !diverged_lot) {
......@@ -3323,8 +3480,9 @@ btr_estimate_n_rows_in_range(
}
} else if (diverged_lot) {
n_rows = (n_rows * (slot1->n_recs + slot2->n_recs))
/ 2;
n_rows = btr_estimate_n_rows_in_range_on_level(
index, slot1, slot2, n_rows,
&is_n_rows_exact);
}
}
}
......
......@@ -1746,6 +1746,7 @@ function_exit:
}
}
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
/********************************************************************//**
Validates the search system.
@return TRUE if ok */
......@@ -1913,3 +1914,4 @@ btr_search_validate(void)
return(ok);
}
#endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */
......@@ -1248,8 +1248,12 @@ buf_flush_try_neighbors(
/*====================*/
ulint space, /*!< in: space id */
ulint offset, /*!< in: page offset */
enum buf_flush flush_type) /*!< in: BUF_FLUSH_LRU or
enum buf_flush flush_type, /*!< in: BUF_FLUSH_LRU or
BUF_FLUSH_LIST */
ulint n_flushed, /*!< in: number of pages
flushed so far in this batch */
ulint n_to_flush) /*!< in: maximum number of pages
we are allowed to flush */
{
ulint i;
ulint low;
......@@ -1290,6 +1294,21 @@ buf_flush_try_neighbors(
buf_page_t* bpage;
if ((count + n_flushed) >= n_to_flush) {
/* We have already flushed enough pages and
should call it a day. There is, however, one
exception. If the page whose neighbors we
are flushing has not been flushed yet then
we'll try to flush the victim that we
selected originally. */
if (i <= offset) {
i = offset;
} else {
break;
}
}
buf_pool = buf_pool_get(space, i);
buf_pool_mutex_enter(buf_pool);
......@@ -1357,6 +1376,8 @@ buf_flush_page_and_try_neighbors(
buf_page_in_file(bpage) */
enum buf_flush flush_type, /*!< in: BUF_FLUSH_LRU
or BUF_FLUSH_LIST */
ulint n_to_flush, /*!< in: number of pages to
flush */
ulint* count) /*!< in/out: number of pages
flushed */
{
......@@ -1390,7 +1411,11 @@ buf_flush_page_and_try_neighbors(
mutex_exit(block_mutex);
/* Try to flush also all the neighbors */
*count += buf_flush_try_neighbors(space, offset, flush_type);
*count += buf_flush_try_neighbors(space,
offset,
flush_type,
*count,
n_to_flush);
buf_pool_mutex_enter(buf_pool);
flushed = TRUE;
......@@ -1430,7 +1455,7 @@ buf_flush_LRU_list_batch(
a page that isn't ready for flushing. */
while (bpage != NULL
&& !buf_flush_page_and_try_neighbors(
bpage, BUF_FLUSH_LRU, &count)) {
bpage, BUF_FLUSH_LRU, max, &count)) {
bpage = UT_LIST_GET_PREV(LRU, bpage);
}
......@@ -1511,7 +1536,7 @@ buf_flush_flush_list_batch(
while (bpage != NULL
&& len > 0
&& !buf_flush_page_and_try_neighbors(
bpage, BUF_FLUSH_LIST, &count)) {
bpage, BUF_FLUSH_LIST, min_n, &count)) {
buf_flush_list_mutex_enter(buf_pool);
......
......@@ -1175,23 +1175,23 @@ static const char* dict_load_index_id_err = "SYS_INDEXES.TABLE_ID mismatch";
/********************************************************************//**
Loads an index definition from a SYS_INDEXES record to dict_index_t.
If "cached" is set to "TRUE", we will create a dict_index_t structure
and fill it accordingly. Otherwise, the dict_index_t will
be supplied by the caller and filled with information read from
the record.
@return error message, or NULL on success */
If allocate=TRUE, we will create a dict_index_t structure and fill it
accordingly. If allocated=FALSE, the dict_index_t will be supplied by
the caller and filled with information read from the record. @return
error message, or NULL on success */
UNIV_INTERN
const char*
dict_load_index_low(
/*================*/
byte* table_id, /*!< in/out: table id (8 bytes),
an "in" value if cached=TRUE
and "out" when cached=FALSE */
an "in" value if allocate=TRUE
and "out" when allocate=FALSE */
const char* table_name, /*!< in: table name */
mem_heap_t* heap, /*!< in/out: temporary memory heap */
const rec_t* rec, /*!< in: SYS_INDEXES record */
ibool cached, /*!< in: TRUE = add to cache,
FALSE = do not */
ibool allocate, /*!< in: TRUE=allocate *index,
FALSE=fill in a pre-allocated
*index */
dict_index_t** index) /*!< out,own: index, or NULL */
{
const byte* field;
......@@ -1203,8 +1203,8 @@ dict_load_index_low(
ulint type;
ulint space;
if (cached) {
/* If "cached" is set to TRUE, no dict_index_t will
if (allocate) {
/* If allocate=TRUE, no dict_index_t will
be supplied. Initialize "*index" to NULL */
*index = NULL;
}
......@@ -1223,7 +1223,7 @@ err_len:
return("incorrect column length in SYS_INDEXES");
}
if (!cached) {
if (!allocate) {
/* We are reading a SYS_INDEXES record. Copy the table_id */
memcpy(table_id, (const char*)field, 8);
} else if (memcmp(field, table_id, 8)) {
......@@ -1279,7 +1279,7 @@ err_len:
goto err_len;
}
if (cached) {
if (allocate) {
*index = dict_mem_index_create(table_name, name_buf,
space, type, n_fields);
} else {
......
......@@ -354,6 +354,7 @@ ha_remove_all_nodes_to_page(
#endif
}
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
/*************************************************************//**
Validates a given range of the cells in hash table.
@return TRUE if ok */
......@@ -400,6 +401,7 @@ ha_validate(
return(ok);
}
#endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */
/*************************************************************//**
Prints info of a hash table. */
......
......@@ -425,7 +425,7 @@ static MYSQL_THDVAR_BOOL(table_locks, PLUGIN_VAR_OPCMDARG,
static MYSQL_THDVAR_BOOL(strict_mode, PLUGIN_VAR_OPCMDARG,
"Use strict mode when evaluating create options.",
NULL, NULL, TRUE);
NULL, NULL, FALSE);
static MYSQL_THDVAR_ULONG(lock_wait_timeout, PLUGIN_VAR_RQCMDARG,
"Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout.",
......@@ -807,6 +807,20 @@ thd_lock_wait_timeout(
return(THDVAR((THD*) thd, lock_wait_timeout));
}
/******************************************************************//**
Set the time waited for the lock for the current query. */
extern "C" UNIV_INTERN
void
thd_set_lock_wait_time(
/*===================*/
void* thd, /*!< in: thread handle (THD*) */
ulint value) /*!< in: time waited for the lock */
{
if (thd) {
thd_storage_lock_wait((THD*)thd, value);
}
}
/********************************************************************//**
Obtain the InnoDB transaction of a MySQL thread.
@return reference to transaction pointer */
......
This diff is collapsed.
......@@ -615,6 +615,11 @@ struct btr_path_struct{
order); value ULINT_UNDEFINED
denotes array end */
ulint n_recs; /*!< number of records on the page */
ulint page_no; /*!< no of the page containing the record */
ulint page_level; /*!< level of the page, if later we fetch
the page under page_no and it is no different
level then we know that the tree has been
reorganized */
};
#define BTR_PATH_ARRAY_N_SLOTS 250 /*!< size of path array (in slots) */
......
......@@ -180,6 +180,7 @@ btr_search_update_hash_on_delete(
btr_cur_t* cursor);/*!< in: cursor which was positioned on the
record to delete using btr_cur_search_...,
the record is not yet deleted */
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
/********************************************************************//**
Validates the search system.
@return TRUE if ok */
......@@ -187,6 +188,9 @@ UNIV_INTERN
ibool
btr_search_validate(void);
/*======================*/
#else
# define btr_search_validate() TRUE
#endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */
/** Flag: has the search system been enabled?
Protected by btr_search_latch and btr_search_enabled_mutex. */
......
......@@ -116,19 +116,23 @@ dict_load_column_low(
const rec_t* rec); /*!< in: SYS_COLUMNS record */
/********************************************************************//**
Loads an index definition from a SYS_INDEXES record to dict_index_t.
@return error message, or NULL on success */
If allocate=TRUE, we will create a dict_index_t structure and fill it
accordingly. If allocated=FALSE, the dict_index_t will be supplied by
the caller and filled with information read from the record. @return
error message, or NULL on success */
UNIV_INTERN
const char*
dict_load_index_low(
/*================*/
byte* table_id, /*!< in/out: table id (8 bytes_,
an "in" value if cached=TRUE
and "out" when cached=FALSE */
byte* table_id, /*!< in/out: table id (8 bytes),
an "in" value if allocate=TRUE
and "out" when allocate=FALSE */
const char* table_name, /*!< in: table name */
mem_heap_t* heap, /*!< in/out: temporary memory heap */
const rec_t* rec, /*!< in: SYS_INDEXES record */
ibool cached, /*!< in: TRUE = add to cache
FALSE = do not */
ibool allocate, /*!< in: TRUE=allocate *index,
FALSE=fill in a pre-allocated
*index */
dict_index_t** index); /*!< out,own: index, or NULL */
/********************************************************************//**
Loads an index field definition from a SYS_FIELDS record to
......
......@@ -186,6 +186,7 @@ ha_remove_all_nodes_to_page(
hash_table_t* table, /*!< in: hash table */
ulint fold, /*!< in: fold value */
const page_t* page); /*!< in: buffer page */
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
/*************************************************************//**
Validates a given range of the cells in hash table.
@return TRUE if ok */
......@@ -196,6 +197,7 @@ ha_validate(
hash_table_t* table, /*!< in: hash table */
ulint start_index, /*!< in: start index */
ulint end_index); /*!< in: end index */
#endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */
/*************************************************************//**
Prints info of a hash table. */
UNIV_INTERN
......
......@@ -267,5 +267,13 @@ thd_lock_wait_timeout(
/*==================*/
void* thd); /*!< in: thread handle (THD*), or NULL to query
the global innodb_lock_wait_timeout */
/******************************************************************//**
Add up the time waited for the lock for the current query. */
UNIV_INTERN
void
thd_set_lock_wait_time(
/*===================*/
void* thd, /*!< in: thread handle (THD*) */
ulint value); /*!< in: time waited for the lock */
#endif
......@@ -46,11 +46,12 @@ struct ibuf_struct{
ulint seg_size; /*!< allocated pages of the file
segment containing ibuf header and
tree */
ibool empty; /*!< after an insert to the ibuf tree
is performed, this is set to FALSE,
and if a contract operation finds
the tree empty, this is set to
TRUE */
ibool empty; /*!< Protected by the page
latch of the root page of the
insert buffer tree
(FSP_IBUF_TREE_ROOT_PAGE_NO). TRUE
if and only if the insert
buffer tree is empty. */
ulint free_list_len; /*!< length of the free list */
ulint height; /*!< tree height */
dict_index_t* index; /*!< insert buffer index */
......
......@@ -254,8 +254,10 @@ by one. */
option off; also some ibuf tests are suppressed */
/* Linkage specifier for non-static InnoDB symbols (variables and functions)
that are only referenced from within InnoDB, not from MySQL */
#if defined(__GNUC__) && (__GNUC__ >= 4) || defined(__INTEL_COMPILER)
that are only referenced from within InnoDB, not from MySQL. We disable the
GCC visibility directive on all Sun operating systems because there is no
easy way to get it to work. See http://bugs.mysql.com/bug.php?id=52263. */
#if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(sun) || defined(__INTEL_COMPILER)
# define UNIV_INTERN __attribute__((visibility ("hidden")))
#else
# define UNIV_INTERN
......
......@@ -1643,6 +1643,9 @@ srv_suspend_mysql_thread(
start_time != -1 && finish_time != -1) {
srv_n_lock_max_wait_time = diff_time;
}
/* Record the lock wait time for this thread */
thd_set_lock_wait_time(trx->mysql_thd, diff_time);
}
if (trx->was_chosen_as_deadlock_victim) {
......
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