Merge lp:~akopytov/percona-server/ahi-fixes-5.5 into lp:percona-server/5.5

Proposed by Alexey Kopytov
Status: Merged
Approved by: Laurynas Biveinis
Approved revision: no longer in the source branch.
Merged at revision: 569
Proposed branch: lp:~akopytov/percona-server/ahi-fixes-5.5
Merge into: lp:percona-server/5.5
Diff against target: 1935 lines (+448/-373) (has conflicts)
22 files modified
Percona-Server/mysql-test/r/percona_bug1218330.result (+8/-0)
Percona-Server/mysql-test/t/percona_bug1218330-master.opt (+1/-0)
Percona-Server/mysql-test/t/percona_bug1218330.test (+42/-0)
Percona-Server/storage/innobase/btr/btr0cur.c (+6/-5)
Percona-Server/storage/innobase/btr/btr0sea.c (+119/-139)
Percona-Server/storage/innobase/buf/buf0buf.c (+1/-3)
Percona-Server/storage/innobase/dict/dict0boot.c (+8/-0)
Percona-Server/storage/innobase/dict/dict0dict.c (+3/-1)
Percona-Server/storage/innobase/dict/dict0load.c (+2/-0)
Percona-Server/storage/innobase/handler/ha_innodb.cc (+11/-6)
Percona-Server/storage/innobase/ibuf/ibuf0ibuf.c (+2/-0)
Percona-Server/storage/innobase/include/btr0sea.h (+36/-15)
Percona-Server/storage/innobase/include/btr0sea.ic (+67/-35)
Percona-Server/storage/innobase/include/btr0types.h (+6/-7)
Percona-Server/storage/innobase/include/buf0buf.h (+0/-1)
Percona-Server/storage/innobase/include/dict0mem.h (+4/-0)
Percona-Server/storage/innobase/include/trx0trx.h (+7/-5)
Percona-Server/storage/innobase/include/trx0trx.ic (+13/-0)
Percona-Server/storage/innobase/row/row0mysql.c (+6/-2)
Percona-Server/storage/innobase/row/row0sel.c (+36/-97)
Percona-Server/storage/innobase/srv/srv0srv.c (+64/-36)
Percona-Server/storage/innobase/trx/trx0trx.c (+6/-21)
Text conflict in Percona-Server/storage/innobase/handler/ha_innodb.cc
To merge this branch: bzr merge lp:~akopytov/percona-server/ahi-fixes-5.5
Reviewer Review Type Date Requested Status
Laurynas Biveinis (community) Approve
Review via email: mp+183471@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote :

    - In percona_bug1218330.test, consider replacing MTR variables
      with SQL variables. Then the need to hide the exact values by
      disable_query_log is removed from the adaptive_hash_mem_2 point
      onwards, resulting in an easier-to-understand test result file.
    - btr_search_info_get_ref_count header comment in btr0sea.c has
      "the ." Also, this header comment should be synced with
      btr0sea.h after editing.
    - It seems that now every index structure in memory create must
      be accompanied by a btr_search_index_init() call. This is OK,
      but I'm wondering if there is any way to merge-proof this
      further. For example, poison index->search_latch and
      search_table pointers in dict_mem_fill_index_struct() if
      UNIV_DEBUG?
    - The ha_innodb.cc conflict needs either you fixing it, if
      possible on GCA, otherwise me fixing it on merge. Note that
      the snippet which was supposed to go to
      innodb_release_stat_resources() went to
      innodb_srv_conc_force_exit_innodb() instead.
    - Why do innobase_release_stat_resources(),
      innobase_commit_ordered(), and innobase_commit() appear to have
      new calls to trx_search_latch_release_if_reserved() added
      anyway, if they are? Or is it a bzr mismerge and only comments
      next to the calls have been added?
    - Diff line 1273: "These latches"
    - It appears that sync_thread_levels_nonempty_trx() is dead code
      now, and all its calls may be replaced by
      sync_thread_levels_nonempty_gen(FALSE).
    - trx->search_latch_timeout now becomes a never-changing constant
      BTR_SEA_TIMEOUT. It can be removed and
      I_S.INNODB_TRX.TRX_ADAPTIVE_HASH_TIMEOUT field can return
      BTR_SEA_TIMEOUT directly, always.
    - Not fully sure but it appears that there are some
      locking/unlocking assymetries wrt UNIV_SEARCH_DEBUG, preceding
      this MP. Not if actionable, probably no need to waste time on
      this. One suspicious example is the target code of
      release_search_latch goto label.

review: Needs Fixing
Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote :

I forgot that I can just look at the ha_innodb.cc diff on your branch directly. It answered both the ha_innodb.cc-related questions I had, no need to address it in any way, I'll be able to merge GCA to trunk correctly there.

Revision history for this message
Alexey Kopytov (akopytov) wrote :
Download full text (4.6 KiB)

Hi Laurynas,

On Wed, 04 Sep 2013 14:50:31 -0000, Laurynas Biveinis wrote:
> Review: Needs Fixing
>
> - In percona_bug1218330.test, consider replacing MTR variables
> with SQL variables. Then the need to hide the exact values by
> disable_query_log is removed from the adaptive_hash_mem_2 point
> onwards, resulting in an easier-to-understand test result file.
> - btr_search_info_get_ref_count header comment in btr0sea.c has
> "the ." Also, this header comment should be synced with
> btr0sea.h after editing.

I considered SQL variables when implementing the test, but preferred MTR
variables, because the .test file is easier to read this way. And the
.result file is for MTR to read.

> - It seems that now every index structure in memory create must
> be accompanied by a btr_search_index_init() call. This is OK,
> but I'm wondering if there is any way to merge-proof this
> further. For example, poison index->search_latch and
> search_table pointers in dict_mem_fill_index_struct() if
> UNIV_DEBUG?

Yes, btr_search_index_init() must be called. The main reason is that
dict_mem_index_create() does not set the index id, it is supposed to be
assigned by the caller and btr_search_index_init() needs an ID.

Now the callers of dict_mem_index_create() do assign an ID in most, but
not all cases. For instance, when a "dummy" index is created, it doesn't
get an ID.

One way to fix that would be to modify dict_mem_index_create() to accept
an ID argument, and make dummy index pass some bogus value (0) as an ID.
But that's almost as fragile as the current approach. Consider a
potential index copy routine that copies an existing index (i.e.
bypassing dict_mem_index_create()) and assigning an ID separately.

I don't see any value in poisoning index->search_latch, as index
structure is created with mem_heap_zalloc(), so if an uninitialized
value is used, we'll know.

> - The ha_innodb.cc conflict needs either you fixing it, if
> possible on GCA, otherwise me fixing it on merge. Note that
> the snippet which was supposed to go to
> innodb_release_stat_resources() went to
> innodb_srv_conc_force_exit_innodb() instead.

Yes, saw the conflict. The reason is that 5.5 GCA tree is behind the
refactoring which made it into the 5.6 tree.

Basically, do what 5.6 code does when merging. It's rather trivial to
resolve.

> - Why do innobase_release_stat_resources(),
> innobase_commit_ordered(), and innobase_commit() appear to have
> new calls to trx_search_latch_release_if_reserved() added
> anyway, if they are? Or is it a bzr mismerge and only comments
> next to the calls have been added?

It's just that the GCA branch has those calls, but they were removed
later. Null-merge those conflicts.

> - Diff line 1273: "These latches"

Oh noes :) But since that is just a "typo in a comment" kind of issue,
and the recommit/merge procedure is quite complicated in this specific
case, I'd keep it as is.

> - It appears that sync_thread_levels_nonempty_trx() is dead code
> now, and all its calls may be...

Read more...

Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote :

Alexey -

> > - btr_search_info_get_ref_count header comment in btr0sea.c has
> > "the ." Also, this header comment should be synced with
> > btr0sea.h after editing.

You haven't acknowledged this "oh noes :)" comment. I think I can just fix those typos on trunk merge if a repush is not needed otherwise.

> > - It seems that now every index structure in memory create must
> > be accompanied by a btr_search_index_init() call. This is OK,
> > but I'm wondering if there is any way to merge-proof this
> > further. For example, poison index->search_latch and
> > search_table pointers in dict_mem_fill_index_struct() if
> > UNIV_DEBUG?
...
> I don't see any value in poisoning index->search_latch, as index
> structure is created with mem_heap_zalloc(), so if an uninitialized
> value is used, we'll know.

I guess then index->search_table poisoning is not that needed neither. Thus no need to do anything about poisoning.

> > - It appears that sync_thread_levels_nonempty_trx() is dead code
> > now, and all its calls may be replaced by
> > sync_thread_levels_nonempty_gen(FALSE).
>
> It's not "dead code", it's more a debug validation check that we _think_
> is now unnecessary because on the current code paths we believe
> trx->has_search_latch is always FALSE. We may be wrong. Or code paths
> may change in the future. The more debug checks, the better.

I don't think I fully agree: sync_thread_levels_nonempty_gen(FALSE) is a stricter condition than sync_thread_levels_nonempty_trx(). Thus if we replaced all the calls of the latter with the former, we wouldn't lose any debug checks. The problem of course if we are wrong as you say and may have to add the checks back.

review: Approve
Revision history for this message
Alexey Kopytov (akopytov) wrote :

Hi Laurynas,

On Fri, 06 Sep 2013 12:46:10 -0000, Laurynas Biveinis wrote:
> Review: Approve
>
> Alexey -
>
>>> - btr_search_info_get_ref_count header comment in btr0sea.c has
>>> "the ." Also, this header comment should be synced with
>>> btr0sea.h after editing.
>
> You haven't acknowledged this "oh noes :)" comment. I think I can just fix those typos on trunk merge if a repush is not needed otherwise.
>

Yes, missed that one. I originally intended to fix all comments to
reflect AHI partitioning, as that introduced unnecessary maintenance
burden. But then I changed my mind and forgot to fully rollback some of
the changes.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file 'Percona-Server/mysql-test/r/percona_bug1218330.result'
--- Percona-Server/mysql-test/r/percona_bug1218330.result 1970-01-01 00:00:00 +0000
+++ Percona-Server/mysql-test/r/percona_bug1218330.result 2013-09-02 14:07:43 +0000
@@ -0,0 +1,8 @@
1CREATE TABLE t1 (
2a INT PRIMARY KEY, b INT,
3c CHAR(200),
4UNIQUE INDEX b(b)) ENGINE=InnoDB;
5INSERT INTO t1 VALUES (1, 1, REPEAT("a", 200));
6should_be_1
71
8DROP TABLE t1;
09
=== added file 'Percona-Server/mysql-test/t/percona_bug1218330-master.opt'
--- Percona-Server/mysql-test/t/percona_bug1218330-master.opt 1970-01-01 00:00:00 +0000
+++ Percona-Server/mysql-test/t/percona_bug1218330-master.opt 2013-09-02 14:07:43 +0000
@@ -0,0 +1,1 @@
1--innodb-adaptive-hash-index-partitions=32
02
=== added file 'Percona-Server/mysql-test/t/percona_bug1218330.test'
--- Percona-Server/mysql-test/t/percona_bug1218330.test 1970-01-01 00:00:00 +0000
+++ Percona-Server/mysql-test/t/percona_bug1218330.test 2013-09-02 14:07:43 +0000
@@ -0,0 +1,42 @@
1############################################################################
2# Bug #1218330: Adaptive hash index memory is incorrectly calculated in SHOW
3# ENGINE INNODB STATUS and I_S
4############################################################################
5
6--source include/have_innodb.inc
7
8let $adaptive_hash_mem_1=`SELECT VARIABLE_VALUE FROM
9 INFORMATION_SCHEMA.GLOBAL_STATUS WHERE
10 VARIABLE_NAME='Innodb_mem_adaptive_hash'`;
11
12CREATE TABLE t1 (
13 a INT PRIMARY KEY, b INT,
14 c CHAR(200),
15 UNIQUE INDEX b(b)) ENGINE=InnoDB;
16
17INSERT INTO t1 VALUES (1, 1, REPEAT("a", 200));
18
19--disable_query_log
20
21--let $i=200
22--disable_result_log
23while ($i)
24{
25 SELECT a FROM t1 WHERE a=1;
26 SELECT b FROM t1 WHERE b=1;
27 --dec $i
28}
29--enable_result_log
30
31let $adaptive_hash_mem_2=`SELECT VARIABLE_VALUE FROM
32 INFORMATION_SCHEMA.GLOBAL_STATUS WHERE
33 VARIABLE_NAME='Innodb_mem_adaptive_hash'`;
34
35# The original implementation would should identical values in
36# adaptive_hash_mem_1 and adaptive_hash_mem_2
37
38--eval SELECT $adaptive_hash_mem_1 != $adaptive_hash_mem_2 as should_be_1
39
40--enable_query_log
41
42DROP TABLE t1;
043
=== modified file 'Percona-Server/storage/innobase/btr/btr0cur.c'
--- Percona-Server/storage/innobase/btr/btr0cur.c 2013-06-27 15:35:20 +0000
+++ Percona-Server/storage/innobase/btr/btr0cur.c 2013-09-02 14:07:43 +0000
@@ -520,7 +520,8 @@
520#ifdef UNIV_SEARCH_PERF_STAT520#ifdef UNIV_SEARCH_PERF_STAT
521 info->n_searches++;521 info->n_searches++;
522#endif522#endif
523 if (rw_lock_get_writer(btr_search_get_latch(cursor->index->id)) == RW_LOCK_NOT_LOCKED523 if (rw_lock_get_writer(btr_search_get_latch(cursor->index)) ==
524 RW_LOCK_NOT_LOCKED
524 && latch_mode <= BTR_MODIFY_LEAF525 && latch_mode <= BTR_MODIFY_LEAF
525 && info->last_hash_succ526 && info->last_hash_succ
526 && !estimate527 && !estimate
@@ -556,7 +557,7 @@
556557
557 if (has_search_latch) {558 if (has_search_latch) {
558 /* Release possible search latch to obey latching order */559 /* Release possible search latch to obey latching order */
559 rw_lock_s_unlock(btr_search_get_latch(cursor->index->id));560 rw_lock_s_unlock(btr_search_get_latch(cursor->index));
560 }561 }
561562
562 /* Store the position of the tree latch we push to mtr so that we563 /* Store the position of the tree latch we push to mtr so that we
@@ -871,7 +872,7 @@
871872
872 if (has_search_latch) {873 if (has_search_latch) {
873874
874 rw_lock_s_lock(btr_search_get_latch(cursor->index->id));875 rw_lock_s_lock(btr_search_get_latch(cursor->index));
875 }876 }
876}877}
877878
@@ -2056,13 +2057,13 @@
2056 btr_search_update_hash_on_delete(cursor);2057 btr_search_update_hash_on_delete(cursor);
2057 }2058 }
20582059
2059 rw_lock_x_lock(btr_search_get_latch(cursor->index->id));2060 rw_lock_x_lock(btr_search_get_latch(cursor->index));
2060 }2061 }
20612062
2062 row_upd_rec_in_place(rec, index, offsets, update, page_zip);2063 row_upd_rec_in_place(rec, index, offsets, update, page_zip);
20632064
2064 if (is_hashed) {2065 if (is_hashed) {
2065 rw_lock_x_unlock(btr_search_get_latch(cursor->index->id));2066 rw_lock_x_unlock(btr_search_get_latch(cursor->index));
2066 }2067 }
20672068
2068 if (page_zip && !dict_index_is_clust(index)2069 if (page_zip && !dict_index_is_clust(index)
20692070
=== modified file 'Percona-Server/storage/innobase/btr/btr0sea.c'
--- Percona-Server/storage/innobase/btr/btr0sea.c 2013-08-14 03:52:04 +0000
+++ Percona-Server/storage/innobase/btr/btr0sea.c 2013-09-02 14:07:43 +0000
@@ -69,17 +69,14 @@
69cache line as btr_search_latch */69cache line as btr_search_latch */
70UNIV_INTERN byte btr_sea_pad1[64];70UNIV_INTERN byte btr_sea_pad1[64];
7171
72/** The latch protecting the adaptive search system: this latch protects the72/** Array of latches protecting individual AHI partitions. The latches
73(1) positions of records on those pages where a hash index has been built.73protect: (1) positions of records on those pages where a hash index from the
74NOTE: It does not protect values of non-ordering fields within a record from74corresponding AHI partition has been built.
75NOTE: They do not protect values of non-ordering fields within a record from
75being updated in-place! We can use fact (1) to perform unique searches to76being updated in-place! We can use fact (1) to perform unique searches to
76indexes. */77indexes. */
7778
78/* We will allocate the latch from dynamic memory to get it to the79UNIV_INTERN rw_lock_t* btr_search_latch_arr;
79same DRAM page as other hotspot semaphores */
80//UNIV_INTERN rw_lock_t* btr_search_latch_temp;
81
82UNIV_INTERN rw_lock_t** btr_search_latch_part;
8380
84/** padding to prevent other memory update hotspots from residing on81/** padding to prevent other memory update hotspots from residing on
85the same memory cache line */82the same memory cache line */
@@ -133,17 +130,17 @@
133void130void
134btr_search_check_free_space_in_heap(131btr_search_check_free_space_in_heap(
135/*=====================================*/132/*=====================================*/
136 index_id_t key)133 dict_index_t* index)
137{134{
138 hash_table_t* table;135 hash_table_t* table;
139 mem_heap_t* heap;136 mem_heap_t* heap;
140137
141#ifdef UNIV_SYNC_DEBUG138#ifdef UNIV_SYNC_DEBUG
142 ut_ad(!rw_lock_own(btr_search_get_latch(key), RW_LOCK_SHARED));139 ut_ad(!rw_lock_own(btr_search_get_latch(index), RW_LOCK_SHARED));
143 ut_ad(!rw_lock_own(btr_search_get_latch(key), RW_LOCK_EX));140 ut_ad(!rw_lock_own(btr_search_get_latch(index), RW_LOCK_EX));
144#endif /* UNIV_SYNC_DEBUG */141#endif /* UNIV_SYNC_DEBUG */
145142
146 table = btr_search_get_hash_index(key);143 table = btr_search_get_hash_table(index);
147144
148 heap = table->heap;145 heap = table->heap;
149146
@@ -154,7 +151,7 @@
154 if (heap->free_block == NULL) {151 if (heap->free_block == NULL) {
155 buf_block_t* block = buf_block_alloc(NULL);152 buf_block_t* block = buf_block_alloc(NULL);
156153
157 rw_lock_x_lock(btr_search_get_latch(key));154 rw_lock_x_lock(btr_search_get_latch(index));
158155
159 if (heap->free_block == NULL) {156 if (heap->free_block == NULL) {
160 heap->free_block = block;157 heap->free_block = block;
@@ -162,7 +159,7 @@
162 buf_block_free(block);159 buf_block_free(block);
163 }160 }
164161
165 rw_lock_x_unlock(btr_search_get_latch(key));162 rw_lock_x_unlock(btr_search_get_latch(index));
166 }163 }
167}164}
168165
@@ -194,16 +191,19 @@
194191
195 btr_search_sys = mem_alloc(sizeof(btr_search_sys_t));192 btr_search_sys = mem_alloc(sizeof(btr_search_sys_t));
196193
197 /* btr_search_index_num should be <= 32. (bits of trx->has_search_latch) */194 /* btr_search_index_num is constrained to machine word size for
198 btr_search_latch_part = mem_alloc(sizeof(rw_lock_t*) * btr_search_index_num);195 historical reasons. This limitation can be easily removed later. */
199 btr_search_sys->hash_index = mem_alloc(sizeof(hash_table_t*) * btr_search_index_num);196
197 btr_search_latch_arr = mem_alloc(sizeof(rw_lock_t) *
198 btr_search_index_num);
199 btr_search_sys->hash_tables = mem_alloc(sizeof(hash_table_t *) *
200 btr_search_index_num);
200 for (i = 0; i < btr_search_index_num; i++) {201 for (i = 0; i < btr_search_index_num; i++) {
201 btr_search_latch_part[i] = mem_alloc(sizeof(rw_lock_t));
202202
203 rw_lock_create(btr_search_latch_key,203 rw_lock_create(btr_search_latch_key,
204 btr_search_latch_part[i], SYNC_SEARCH_SYS);204 &btr_search_latch_arr[i], SYNC_SEARCH_SYS);
205205
206 btr_search_sys->hash_index[i] = ha_create(hash_size, 0, 0);206 btr_search_sys->hash_tables[i] = ha_create(hash_size, 0, 0);
207 }207 }
208}208}
209209
@@ -217,15 +217,13 @@
217 ulint i;217 ulint i;
218218
219 for (i = 0; i < btr_search_index_num; i++) {219 for (i = 0; i < btr_search_index_num; i++) {
220 mem_heap_free(btr_search_sys->hash_index[i]->heap);220 mem_heap_free(btr_search_sys->hash_tables[i]->heap);
221 hash_table_free(btr_search_sys->hash_index[i]);221 hash_table_free(btr_search_sys->hash_tables[i]);
222222
223 rw_lock_free(btr_search_latch_part[i]);223 rw_lock_free(&btr_search_latch_arr[i]);
224
225 mem_free(btr_search_latch_part[i]);
226 }224 }
227 mem_free(btr_search_sys->hash_index);225 mem_free(btr_search_sys->hash_tables);
228 mem_free(btr_search_latch_part);226 mem_free(btr_search_latch_arr);
229227
230 //rw_lock_free(&btr_search_latch);228 //rw_lock_free(&btr_search_latch);
231 //mem_free(btr_search_latch_temp);229 //mem_free(btr_search_latch_temp);
@@ -270,8 +268,8 @@
270268
271 /* Clear the adaptive hash index. */269 /* Clear the adaptive hash index. */
272 for (i = 0; i < btr_search_index_num; i++) {270 for (i = 0; i < btr_search_index_num; i++) {
273 hash_table_clear(btr_search_sys->hash_index[i]);271 hash_table_clear(btr_search_sys->hash_tables[i]);
274 mem_heap_empty(btr_search_sys->hash_index[i]->heap);272 mem_heap_empty(btr_search_sys->hash_tables[i]->heap);
275 }273 }
276274
277 btr_search_x_unlock_all();275 btr_search_x_unlock_all();
@@ -334,27 +332,27 @@
334332
335/*****************************************************************//**333/*****************************************************************//**
336Returns the value of ref_count. The value is protected by334Returns the value of ref_count. The value is protected by
337btr_search_latch.335the .
338@return ref_count value. */336@return ref_count value. */
339UNIV_INTERN337UNIV_INTERN
340ulint338ulint
341btr_search_info_get_ref_count(339btr_search_info_get_ref_count(
342/*==========================*/340/*==========================*/
343 btr_search_t* info, /*!< in: search info. */341 btr_search_t* info, /*!< in: search info. */
344 index_id_t key)342 dict_index_t* index) /*!< in: index */
345{343{
346 ulint ret;344 ulint ret;
347345
348 ut_ad(info);346 ut_ad(info);
349347
350#ifdef UNIV_SYNC_DEBUG348#ifdef UNIV_SYNC_DEBUG
351 ut_ad(!rw_lock_own(btr_search_get_latch(key), RW_LOCK_SHARED));349 ut_ad(!rw_lock_own(btr_search_get_latch(index), RW_LOCK_SHARED));
352 ut_ad(!rw_lock_own(btr_search_get_latch(key), RW_LOCK_EX));350 ut_ad(!rw_lock_own(btr_search_get_latch(index), RW_LOCK_EX));
353#endif /* UNIV_SYNC_DEBUG */351#endif /* UNIV_SYNC_DEBUG */
354352
355 rw_lock_s_lock(btr_search_get_latch(key));353 rw_lock_s_lock(btr_search_get_latch(index));
356 ret = info->ref_count;354 ret = info->ref_count;
357 rw_lock_s_unlock(btr_search_get_latch(key));355 rw_lock_s_unlock(btr_search_get_latch(index));
358356
359 return(ret);357 return(ret);
360}358}
@@ -375,8 +373,8 @@
375 int cmp;373 int cmp;
376374
377#ifdef UNIV_SYNC_DEBUG375#ifdef UNIV_SYNC_DEBUG
378 ut_ad(!rw_lock_own(btr_search_get_latch(cursor->index->id), RW_LOCK_SHARED));376 ut_ad(!rw_lock_own(btr_search_get_latch(cursor->index), RW_LOCK_SHARED));
379 ut_ad(!rw_lock_own(btr_search_get_latch(cursor->index->id), RW_LOCK_EX));377 ut_ad(!rw_lock_own(btr_search_get_latch(cursor->index), RW_LOCK_EX));
380#endif /* UNIV_SYNC_DEBUG */378#endif /* UNIV_SYNC_DEBUG */
381379
382 index = cursor->index;380 index = cursor->index;
@@ -494,8 +492,8 @@
494 /*!< in: cursor */492 /*!< in: cursor */
495{493{
496#ifdef UNIV_SYNC_DEBUG494#ifdef UNIV_SYNC_DEBUG
497 ut_ad(!rw_lock_own(btr_search_get_latch(cursor->index->id), RW_LOCK_SHARED));495 ut_ad(!rw_lock_own(btr_search_get_latch(cursor->index), RW_LOCK_SHARED));
498 ut_ad(!rw_lock_own(btr_search_get_latch(cursor->index->id), RW_LOCK_EX));496 ut_ad(!rw_lock_own(btr_search_get_latch(cursor->index), RW_LOCK_EX));
499 ut_ad(rw_lock_own(&block->lock, RW_LOCK_SHARED)497 ut_ad(rw_lock_own(&block->lock, RW_LOCK_SHARED)
500 || rw_lock_own(&block->lock, RW_LOCK_EX));498 || rw_lock_own(&block->lock, RW_LOCK_EX));
501#endif /* UNIV_SYNC_DEBUG */499#endif /* UNIV_SYNC_DEBUG */
@@ -579,7 +577,7 @@
579577
580 ut_ad(cursor->flag == BTR_CUR_HASH_FAIL);578 ut_ad(cursor->flag == BTR_CUR_HASH_FAIL);
581#ifdef UNIV_SYNC_DEBUG579#ifdef UNIV_SYNC_DEBUG
582 ut_ad(rw_lock_own(btr_search_get_latch(cursor->index->id), RW_LOCK_EX));580 ut_ad(rw_lock_own(btr_search_get_latch(cursor->index), RW_LOCK_EX));
583 ut_ad(rw_lock_own(&(block->lock), RW_LOCK_SHARED)581 ut_ad(rw_lock_own(&(block->lock), RW_LOCK_SHARED)
584 || rw_lock_own(&(block->lock), RW_LOCK_EX));582 || rw_lock_own(&(block->lock), RW_LOCK_EX));
585#endif /* UNIV_SYNC_DEBUG */583#endif /* UNIV_SYNC_DEBUG */
@@ -620,11 +618,12 @@
620 mem_heap_free(heap);618 mem_heap_free(heap);
621 }619 }
622#ifdef UNIV_SYNC_DEBUG620#ifdef UNIV_SYNC_DEBUG
623 ut_ad(rw_lock_own(btr_search_get_latch(cursor->index->id), RW_LOCK_EX));621 ut_ad(rw_lock_own(btr_search_get_latch(cursor->index),
622 RW_LOCK_EX));
624#endif /* UNIV_SYNC_DEBUG */623#endif /* UNIV_SYNC_DEBUG */
625624
626 ha_insert_for_fold(btr_search_get_hash_index(cursor->index->id), fold,625 ha_insert_for_fold(btr_search_get_hash_table(cursor->index),
627 block, rec);626 fold, block, rec);
628 }627 }
629}628}
630629
@@ -643,8 +642,8 @@
643 ulint* params2;642 ulint* params2;
644643
645#ifdef UNIV_SYNC_DEBUG644#ifdef UNIV_SYNC_DEBUG
646 ut_ad(!rw_lock_own(btr_search_get_latch(cursor->index->id), RW_LOCK_SHARED));645 ut_ad(!rw_lock_own(btr_search_get_latch(cursor->index), RW_LOCK_SHARED));
647 ut_ad(!rw_lock_own(btr_search_get_latch(cursor->index->id), RW_LOCK_EX));646 ut_ad(!rw_lock_own(btr_search_get_latch(cursor->index), RW_LOCK_EX));
648#endif /* UNIV_SYNC_DEBUG */647#endif /* UNIV_SYNC_DEBUG */
649648
650 block = btr_cur_get_block(cursor);649 block = btr_cur_get_block(cursor);
@@ -662,7 +661,7 @@
662661
663 if (build_index || (cursor->flag == BTR_CUR_HASH_FAIL)) {662 if (build_index || (cursor->flag == BTR_CUR_HASH_FAIL)) {
664663
665 btr_search_check_free_space_in_heap(cursor->index->id);664 btr_search_check_free_space_in_heap(cursor->index);
666 }665 }
667666
668 if (cursor->flag == BTR_CUR_HASH_FAIL) {667 if (cursor->flag == BTR_CUR_HASH_FAIL) {
@@ -672,11 +671,11 @@
672 btr_search_n_hash_fail++;671 btr_search_n_hash_fail++;
673#endif /* UNIV_SEARCH_PERF_STAT */672#endif /* UNIV_SEARCH_PERF_STAT */
674673
675 rw_lock_x_lock(btr_search_get_latch(cursor->index->id));674 rw_lock_x_lock(btr_search_get_latch(cursor->index));
676675
677 btr_search_update_hash_ref(info, block, cursor);676 btr_search_update_hash_ref(info, block, cursor);
678677
679 rw_lock_x_unlock(btr_search_get_latch(cursor->index->id));678 rw_lock_x_unlock(btr_search_get_latch(cursor->index));
680 }679 }
681680
682 if (build_index) {681 if (build_index) {
@@ -921,17 +920,17 @@
921 cursor->flag = BTR_CUR_HASH;920 cursor->flag = BTR_CUR_HASH;
922921
923 if (UNIV_LIKELY(!has_search_latch)) {922 if (UNIV_LIKELY(!has_search_latch)) {
924 rw_lock_s_lock(btr_search_get_latch(index_id));923 rw_lock_s_lock(btr_search_get_latch(index));
925924
926 if (UNIV_UNLIKELY(!btr_search_enabled)) {925 if (UNIV_UNLIKELY(!btr_search_enabled)) {
927 goto failure_unlock;926 goto failure_unlock;
928 }927 }
929 }928 }
930929
931 ut_ad(rw_lock_get_writer(btr_search_get_latch(index_id)) != RW_LOCK_EX);930 ut_ad(rw_lock_get_writer(btr_search_get_latch(index)) != RW_LOCK_EX);
932 ut_ad(rw_lock_get_reader_count(btr_search_get_latch(index_id)) > 0);931 ut_ad(rw_lock_get_reader_count(btr_search_get_latch(index)) > 0);
933932
934 rec = ha_search_and_get_data(btr_search_get_hash_index(index_id), fold);933 rec = ha_search_and_get_data(btr_search_get_hash_table(index), fold);
935934
936 if (UNIV_UNLIKELY(!rec)) {935 if (UNIV_UNLIKELY(!rec)) {
937 goto failure_unlock;936 goto failure_unlock;
@@ -949,7 +948,7 @@
949 goto failure_unlock;948 goto failure_unlock;
950 }949 }
951950
952 rw_lock_s_unlock(btr_search_get_latch(index_id));951 rw_lock_s_unlock(btr_search_get_latch(index));
953952
954 buf_block_dbg_add_level(block, SYNC_TREE_NODE_FROM_HASH);953 buf_block_dbg_add_level(block, SYNC_TREE_NODE_FROM_HASH);
955 }954 }
@@ -1046,7 +1045,7 @@
1046 /*-------------------------------------------*/1045 /*-------------------------------------------*/
1047failure_unlock:1046failure_unlock:
1048 if (UNIV_LIKELY(!has_search_latch)) {1047 if (UNIV_LIKELY(!has_search_latch)) {
1049 rw_lock_s_unlock(btr_search_get_latch(index_id));1048 rw_lock_s_unlock(btr_search_get_latch(index));
1050 }1049 }
1051failure:1050failure:
1052 cursor->flag = BTR_CUR_HASH_FAIL;1051 cursor->flag = BTR_CUR_HASH_FAIL;
@@ -1091,48 +1090,26 @@
1091 ulint* offsets;1090 ulint* offsets;
10921091
1093retry:1092retry:
1094 if (btr_search_index_num > 1) {1093 /* Do a dirty check on block->index, return if the block is not in the
1095 rw_lock_t* btr_search_latch;1094 adaptive hash index. This is to avoid acquiring an AHI latch for
10961095 performance considerations. */
1097 /* FIXME: This may be optimistic implementation still. */1096
1098 btr_search_latch = (rw_lock_t*)(block->btr_search_latch);1097 index = block->index;
1099 if (UNIV_LIKELY(!btr_search_latch)) {1098 if (!index) {
1100 if (block->index) {
1101 goto retry;
1102 }
1103 return;
1104 }
1105 rw_lock_s_lock(btr_search_latch);
1106 if (UNIV_LIKELY(btr_search_latch != block->btr_search_latch)) {
1107 rw_lock_s_unlock(btr_search_latch);
1108 goto retry;
1109 }
1110 if (UNIV_LIKELY(!block->index)) {
1111 rw_lock_s_unlock(btr_search_latch);
1112 goto retry;
1113 }
1114 index = block->index;
1115 ut_a(btr_search_latch == btr_search_get_latch(index->id));
1116 } else {
1117 /* btr_search_index_num == 1 */
1118 /* btr_search_latch is only one and able to obtain
1119 before evaluating block->index. */
1120 rw_lock_s_lock(btr_search_latch_part[0]);
1121 if (UNIV_LIKELY(!block->index)) {
1122 rw_lock_s_unlock(btr_search_latch_part[0]);
1123 return;
1124 }
1125 index = block->index;
1126 }
1127
1128 if (UNIV_LIKELY(!index)) {
1129
1130 rw_lock_s_unlock(btr_search_get_latch(index->id));
11311099
1132 return;1100 return;
1133 }1101 }
11341102
1135 table = btr_search_get_hash_index(index->id);1103 rw_lock_s_lock(btr_search_get_latch(index));
1104
1105 if (UNIV_UNLIKELY(index != block->index)) {
1106
1107 rw_lock_s_unlock(btr_search_get_latch(index));
1108
1109 goto retry;
1110 }
1111
1112 table = btr_search_get_hash_table(index);
11361113
1137#ifdef UNIV_SYNC_DEBUG1114#ifdef UNIV_SYNC_DEBUG
1138 ut_ad(rw_lock_own(&(block->lock), RW_LOCK_SHARED)1115 ut_ad(rw_lock_own(&(block->lock), RW_LOCK_SHARED)
@@ -1149,7 +1126,7 @@
1149 releasing btr_search_latch, as the index page might only1126 releasing btr_search_latch, as the index page might only
1150 be s-latched! */1127 be s-latched! */
11511128
1152 rw_lock_s_unlock(btr_search_get_latch(index->id));1129 rw_lock_s_unlock(btr_search_get_latch(index));
11531130
1154 ut_a(n_fields + n_bytes > 0);1131 ut_a(n_fields + n_bytes > 0);
11551132
@@ -1200,7 +1177,7 @@
1200 mem_heap_free(heap);1177 mem_heap_free(heap);
1201 }1178 }
12021179
1203 rw_lock_x_lock(btr_search_get_latch(index->id));1180 rw_lock_x_lock(btr_search_get_latch(index));
12041181
1205 if (UNIV_UNLIKELY(!block->index)) {1182 if (UNIV_UNLIKELY(!block->index)) {
1206 /* Someone else has meanwhile dropped the hash index */1183 /* Someone else has meanwhile dropped the hash index */
@@ -1216,7 +1193,7 @@
1216 /* Someone else has meanwhile built a new hash index on the1193 /* Someone else has meanwhile built a new hash index on the
1217 page, with different parameters */1194 page, with different parameters */
12181195
1219 rw_lock_x_unlock(btr_search_get_latch(index->id));1196 rw_lock_x_unlock(btr_search_get_latch(index));
12201197
1221 mem_free(folds);1198 mem_free(folds);
1222 goto retry;1199 goto retry;
@@ -1231,7 +1208,6 @@
1231 index->search_info->ref_count--;1208 index->search_info->ref_count--;
12321209
1233 block->index = NULL;1210 block->index = NULL;
1234 block->btr_search_latch = NULL;
12351211
1236cleanup:1212cleanup:
1237#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG1213#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
@@ -1244,14 +1220,14 @@
1244 "InnoDB: the hash index to a page of %s,"1220 "InnoDB: the hash index to a page of %s,"
1245 " still %lu hash nodes remain.\n",1221 " still %lu hash nodes remain.\n",
1246 index->name, (ulong) block->n_pointers);1222 index->name, (ulong) block->n_pointers);
1247 rw_lock_x_unlock(btr_search_get_latch(index->id));1223 rw_lock_x_unlock(btr_search_get_latch(index));
12481224
1249 ut_ad(btr_search_validate());1225 ut_ad(btr_search_validate());
1250 } else {1226 } else {
1251 rw_lock_x_unlock(btr_search_get_latch(index->id));1227 rw_lock_x_unlock(btr_search_get_latch(index));
1252 }1228 }
1253#else /* UNIV_AHI_DEBUG || UNIV_DEBUG */1229#else /* UNIV_AHI_DEBUG || UNIV_DEBUG */
1254 rw_lock_x_unlock(btr_search_get_latch(index->id));1230 rw_lock_x_unlock(btr_search_get_latch(index));
1255#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */1231#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
12561232
1257 mem_free(folds);1233 mem_free(folds);
@@ -1283,9 +1259,9 @@
1283 ulint* offsets;1259 ulint* offsets;
1284 ibool released_search_latch;1260 ibool released_search_latch;
12851261
1286 rw_lock_s_lock(btr_search_get_latch(index->id));1262 rw_lock_s_lock(btr_search_get_latch(index));
12871263
1288 table = btr_search_get_hash_index(index->id);1264 table = btr_search_get_hash_table(index);
12891265
1290 for (j = 0; j < srv_buf_pool_instances; j++) {1266 for (j = 0; j < srv_buf_pool_instances; j++) {
1291 buf_pool_t* buf_pool;1267 buf_pool_t* buf_pool;
@@ -1319,7 +1295,8 @@
13191295
13201296
1321 /* keeping latch order */1297 /* keeping latch order */
1322 rw_lock_s_unlock(btr_search_get_latch(index->id));1298 rw_lock_s_unlock(
1299 btr_search_get_latch(index));
1323 released_search_latch = TRUE;1300 released_search_latch = TRUE;
1324 rw_lock_x_lock(&block->lock);1301 rw_lock_x_lock(&block->lock);
13251302
@@ -1371,7 +1348,8 @@
1371 mem_heap_empty(heap);1348 mem_heap_empty(heap);
1372 }1349 }
13731350
1374 rw_lock_x_lock(btr_search_get_latch(index->id));1351 rw_lock_x_lock(
1352 btr_search_get_latch(index));
13751353
1376 if (UNIV_UNLIKELY(!block->index)) {1354 if (UNIV_UNLIKELY(!block->index)) {
1377 goto cleanup;1355 goto cleanup;
@@ -1381,12 +1359,14 @@
13811359
1382 if (UNIV_UNLIKELY(block->curr_n_fields != n_fields)1360 if (UNIV_UNLIKELY(block->curr_n_fields != n_fields)
1383 || UNIV_UNLIKELY(block->curr_n_bytes != n_bytes)) {1361 || UNIV_UNLIKELY(block->curr_n_bytes != n_bytes)) {
1384 rw_lock_x_unlock(btr_search_get_latch(index->id));1362 rw_lock_x_unlock(
1363 btr_search_get_latch(index));
1385 rw_lock_x_unlock(&block->lock);1364 rw_lock_x_unlock(&block->lock);
13861365
1387 mem_free(folds);1366 mem_free(folds);
13881367
1389 rw_lock_s_lock(btr_search_get_latch(index->id));1368 rw_lock_s_lock(
1369 btr_search_get_latch(index));
1390 goto retry;1370 goto retry;
1391 }1371 }
13921372
@@ -1399,7 +1379,6 @@
1399 index->search_info->ref_count--;1379 index->search_info->ref_count--;
14001380
1401 block->index = NULL;1381 block->index = NULL;
1402 block->btr_search_latch = NULL;
14031382
1404cleanup:1383cleanup:
1405#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG1384#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
@@ -1412,18 +1391,20 @@
1412 index->name, (ulong) block->n_pointers);1391 index->name, (ulong) block->n_pointers);
1413 }1392 }
1414#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */1393#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
1415 rw_lock_x_unlock(btr_search_get_latch(index->id));1394 rw_lock_x_unlock(
1395 btr_search_get_latch(index));
1416 rw_lock_x_unlock(&block->lock);1396 rw_lock_x_unlock(&block->lock);
14171397
1418 mem_free(folds);1398 mem_free(folds);
14191399
1420 rw_lock_s_lock(btr_search_get_latch(index->id));1400 rw_lock_s_lock(
1401 btr_search_get_latch(index));
1421 }1402 }
1422 }1403 }
1423 } while (released_search_latch);1404 } while (released_search_latch);
1424 }1405 }
14251406
1426 rw_lock_s_unlock(btr_search_get_latch(index->id));1407 rw_lock_s_unlock(btr_search_get_latch(index));
14271408
1428 if (UNIV_LIKELY_NULL(heap)) {1409 if (UNIV_LIKELY_NULL(heap)) {
1429 mem_heap_free(heap);1410 mem_heap_free(heap);
@@ -1502,7 +1483,7 @@
1502 ut_ad(index);1483 ut_ad(index);
1503 ut_a(!dict_index_is_ibuf(index));1484 ut_a(!dict_index_is_ibuf(index));
15041485
1505 table = btr_search_get_hash_index(index->id);1486 table = btr_search_get_hash_table(index);
1506 page = buf_block_get_frame(block);1487 page = buf_block_get_frame(block);
15071488
1508#ifdef UNIV_SYNC_DEBUG1489#ifdef UNIV_SYNC_DEBUG
@@ -1511,17 +1492,17 @@
1511 || rw_lock_own(&(block->lock), RW_LOCK_EX));1492 || rw_lock_own(&(block->lock), RW_LOCK_EX));
1512#endif /* UNIV_SYNC_DEBUG */1493#endif /* UNIV_SYNC_DEBUG */
15131494
1514 rw_lock_s_lock(btr_search_get_latch(index->id));1495 rw_lock_s_lock(btr_search_get_latch(index));
15151496
1516 if (block->index && ((block->curr_n_fields != n_fields)1497 if (block->index && ((block->curr_n_fields != n_fields)
1517 || (block->curr_n_bytes != n_bytes)1498 || (block->curr_n_bytes != n_bytes)
1518 || (block->curr_left_side != left_side))) {1499 || (block->curr_left_side != left_side))) {
15191500
1520 rw_lock_s_unlock(btr_search_get_latch(index->id));1501 rw_lock_s_unlock(btr_search_get_latch(index));
15211502
1522 btr_search_drop_page_hash_index(block);1503 btr_search_drop_page_hash_index(block);
1523 } else {1504 } else {
1524 rw_lock_s_unlock(btr_search_get_latch(index->id));1505 rw_lock_s_unlock(btr_search_get_latch(index));
1525 }1506 }
15261507
1527 n_recs = page_get_n_recs(page);1508 n_recs = page_get_n_recs(page);
@@ -1615,9 +1596,9 @@
1615 fold = next_fold;1596 fold = next_fold;
1616 }1597 }
16171598
1618 btr_search_check_free_space_in_heap(index->id);1599 btr_search_check_free_space_in_heap(index);
16191600
1620 rw_lock_x_lock(btr_search_get_latch(index->id));1601 rw_lock_x_lock(btr_search_get_latch(index));
16211602
1622 if (UNIV_UNLIKELY(!btr_search_enabled)) {1603 if (UNIV_UNLIKELY(!btr_search_enabled)) {
1623 goto exit_func;1604 goto exit_func;
@@ -1644,7 +1625,6 @@
1644 block->curr_n_bytes = n_bytes;1625 block->curr_n_bytes = n_bytes;
1645 block->curr_left_side = left_side;1626 block->curr_left_side = left_side;
1646 block->index = index;1627 block->index = index;
1647 block->btr_search_latch = btr_search_get_latch(index->id);
16481628
1649 for (i = 0; i < n_cached; i++) {1629 for (i = 0; i < n_cached; i++) {
16501630
@@ -1652,7 +1632,7 @@
1652 }1632 }
16531633
1654exit_func:1634exit_func:
1655 rw_lock_x_unlock(btr_search_get_latch(index->id));1635 rw_lock_x_unlock(btr_search_get_latch(index));
16561636
1657 mem_free(folds);1637 mem_free(folds);
1658 mem_free(recs);1638 mem_free(recs);
@@ -1687,7 +1667,7 @@
1687 ut_ad(rw_lock_own(&(new_block->lock), RW_LOCK_EX));1667 ut_ad(rw_lock_own(&(new_block->lock), RW_LOCK_EX));
1688#endif /* UNIV_SYNC_DEBUG */1668#endif /* UNIV_SYNC_DEBUG */
16891669
1690 rw_lock_s_lock(btr_search_get_latch(index->id));1670 rw_lock_s_lock(btr_search_get_latch(index));
16911671
1692 ut_a(!new_block->index || new_block->index == index);1672 ut_a(!new_block->index || new_block->index == index);
1693 ut_a(!block->index || block->index == index);1673 ut_a(!block->index || block->index == index);
@@ -1696,7 +1676,7 @@
16961676
1697 if (new_block->index) {1677 if (new_block->index) {
16981678
1699 rw_lock_s_unlock(btr_search_get_latch(index->id));1679 rw_lock_s_unlock(btr_search_get_latch(index));
17001680
1701 btr_search_drop_page_hash_index(block);1681 btr_search_drop_page_hash_index(block);
17021682
@@ -1713,7 +1693,7 @@
1713 new_block->n_bytes = block->curr_n_bytes;1693 new_block->n_bytes = block->curr_n_bytes;
1714 new_block->left_side = left_side;1694 new_block->left_side = left_side;
17151695
1716 rw_lock_s_unlock(btr_search_get_latch(index->id));1696 rw_lock_s_unlock(btr_search_get_latch(index));
17171697
1718 ut_a(n_fields + n_bytes > 0);1698 ut_a(n_fields + n_bytes > 0);
17191699
@@ -1725,7 +1705,7 @@
1725 return;1705 return;
1726 }1706 }
17271707
1728 rw_lock_s_unlock(btr_search_get_latch(index->id));1708 rw_lock_s_unlock(btr_search_get_latch(index));
1729}1709}
17301710
1731/********************************************************************//**1711/********************************************************************//**
@@ -1764,7 +1744,7 @@
1764 ut_a(block->curr_n_fields + block->curr_n_bytes > 0);1744 ut_a(block->curr_n_fields + block->curr_n_bytes > 0);
1765 ut_a(!dict_index_is_ibuf(index));1745 ut_a(!dict_index_is_ibuf(index));
17661746
1767 table = btr_search_get_hash_index(cursor->index->id);1747 table = btr_search_get_hash_table(cursor->index);
17681748
1769 rec = btr_cur_get_rec(cursor);1749 rec = btr_cur_get_rec(cursor);
17701750
@@ -1775,7 +1755,7 @@
1775 mem_heap_free(heap);1755 mem_heap_free(heap);
1776 }1756 }
17771757
1778 rw_lock_x_lock(btr_search_get_latch(cursor->index->id));1758 rw_lock_x_lock(btr_search_get_latch(cursor->index));
17791759
1780 if (block->index) {1760 if (block->index) {
1781 ut_a(block->index == index);1761 ut_a(block->index == index);
@@ -1783,7 +1763,7 @@
1783 ha_search_and_delete_if_found(table, fold, rec);1763 ha_search_and_delete_if_found(table, fold, rec);
1784 }1764 }
17851765
1786 rw_lock_x_unlock(btr_search_get_latch(cursor->index->id));1766 rw_lock_x_unlock(btr_search_get_latch(cursor->index));
1787}1767}
17881768
1789/********************************************************************//**1769/********************************************************************//**
@@ -1820,7 +1800,7 @@
1820 ut_a(cursor->index == index);1800 ut_a(cursor->index == index);
1821 ut_a(!dict_index_is_ibuf(index));1801 ut_a(!dict_index_is_ibuf(index));
18221802
1823 rw_lock_x_lock(btr_search_get_latch(cursor->index->id));1803 rw_lock_x_lock(btr_search_get_latch(cursor->index));
18241804
1825 if (!block->index) {1805 if (!block->index) {
18261806
@@ -1834,15 +1814,15 @@
1834 && (cursor->n_bytes == block->curr_n_bytes)1814 && (cursor->n_bytes == block->curr_n_bytes)
1835 && !block->curr_left_side) {1815 && !block->curr_left_side) {
18361816
1837 table = btr_search_get_hash_index(cursor->index->id);1817 table = btr_search_get_hash_table(cursor->index);
18381818
1839 ha_search_and_update_if_found(table, cursor->fold, rec,1819 ha_search_and_update_if_found(table, cursor->fold, rec,
1840 block, page_rec_get_next(rec));1820 block, page_rec_get_next(rec));
18411821
1842func_exit:1822func_exit:
1843 rw_lock_x_unlock(btr_search_get_latch(cursor->index->id));1823 rw_lock_x_unlock(btr_search_get_latch(cursor->index));
1844 } else {1824 } else {
1845 rw_lock_x_unlock(btr_search_get_latch(cursor->index->id));1825 rw_lock_x_unlock(btr_search_get_latch(cursor->index));
18461826
1847 btr_search_update_hash_on_insert(cursor);1827 btr_search_update_hash_on_insert(cursor);
1848 }1828 }
@@ -1877,9 +1857,9 @@
1877 ulint* offsets = offsets_;1857 ulint* offsets = offsets_;
1878 rec_offs_init(offsets_);1858 rec_offs_init(offsets_);
18791859
1880 table = btr_search_get_hash_index(cursor->index->id);1860 table = btr_search_get_hash_table(cursor->index);
18811861
1882 btr_search_check_free_space_in_heap(cursor->index->id);1862 btr_search_check_free_space_in_heap(cursor->index);
18831863
1884 rec = btr_cur_get_rec(cursor);1864 rec = btr_cur_get_rec(cursor);
18851865
@@ -1924,7 +1904,7 @@
1924 } else {1904 } else {
1925 if (left_side) {1905 if (left_side) {
19261906
1927 rw_lock_x_lock(btr_search_get_latch(index->id));1907 rw_lock_x_lock(btr_search_get_latch(index));
19281908
1929 locked = TRUE;1909 locked = TRUE;
19301910
@@ -1942,7 +1922,7 @@
19421922
1943 if (!locked) {1923 if (!locked) {
19441924
1945 rw_lock_x_lock(btr_search_get_latch(index->id));1925 rw_lock_x_lock(btr_search_get_latch(index));
19461926
1947 locked = TRUE;1927 locked = TRUE;
19481928
@@ -1964,7 +1944,7 @@
1964 if (!left_side) {1944 if (!left_side) {
19651945
1966 if (!locked) {1946 if (!locked) {
1967 rw_lock_x_lock(btr_search_get_latch(index->id));1947 rw_lock_x_lock(btr_search_get_latch(index));
19681948
1969 locked = TRUE;1949 locked = TRUE;
19701950
@@ -1983,7 +1963,7 @@
19831963
1984 if (!locked) {1964 if (!locked) {
19851965
1986 rw_lock_x_lock(btr_search_get_latch(index->id));1966 rw_lock_x_lock(btr_search_get_latch(index));
19871967
1988 locked = TRUE;1968 locked = TRUE;
19891969
@@ -2010,7 +1990,7 @@
2010 mem_heap_free(heap);1990 mem_heap_free(heap);
2011 }1991 }
2012 if (locked) {1992 if (locked) {
2013 rw_lock_x_unlock(btr_search_get_latch(index->id));1993 rw_lock_x_unlock(btr_search_get_latch(index));
2014 }1994 }
2015}1995}
20161996
@@ -2043,7 +2023,7 @@
20432023
2044 for (j = 0; j < btr_search_index_num; j++) {2024 for (j = 0; j < btr_search_index_num; j++) {
20452025
2046 cell_count = hash_get_n_cells(btr_search_sys->hash_index[j]);2026 cell_count = hash_get_n_cells(btr_search_sys->hash_tables[j]);
20472027
2048 for (i = 0; i < cell_count; i++) {2028 for (i = 0; i < cell_count; i++) {
2049 /* We release btr_search_latch every once in a while to2029 /* We release btr_search_latch every once in a while to
@@ -2056,7 +2036,7 @@
2056 buf_pool_page_hash_x_lock_all();2036 buf_pool_page_hash_x_lock_all();
2057 }2037 }
20582038
2059 node = hash_get_nth_cell(btr_search_sys->hash_index[j], i)->node;2039 node = hash_get_nth_cell(btr_search_sys->hash_tables[j], i)->node;
20602040
2061 for (; node != NULL; node = node->next) {2041 for (; node != NULL; node = node->next) {
2062 const buf_block_t* block2042 const buf_block_t* block
@@ -2171,7 +2151,7 @@
2171 buf_pool_page_hash_x_lock_all();2151 buf_pool_page_hash_x_lock_all();
2172 }2152 }
21732153
2174 if (!ha_validate(btr_search_sys->hash_index[j], i, end_index)) {2154 if (!ha_validate(btr_search_sys->hash_tables[j], i, end_index)) {
2175 ok = FALSE;2155 ok = FALSE;
2176 }2156 }
2177 }2157 }
21782158
=== modified file 'Percona-Server/storage/innobase/buf/buf0buf.c'
--- Percona-Server/storage/innobase/buf/buf0buf.c 2013-08-16 13:17:34 +0000
+++ Percona-Server/storage/innobase/buf/buf0buf.c 2013-09-02 14:07:43 +0000
@@ -989,7 +989,6 @@
989989
990 block->check_index_page_at_flush = FALSE;990 block->check_index_page_at_flush = FALSE;
991 block->index = NULL;991 block->index = NULL;
992 block->btr_search_latch = NULL;
993992
994#ifdef UNIV_DEBUG993#ifdef UNIV_DEBUG
995 block->page.in_page_hash = FALSE;994 block->page.in_page_hash = FALSE;
@@ -1468,7 +1467,7 @@
1468 ulint j;1467 ulint j;
14691468
1470 for (j = 0; j < btr_search_index_num; j++) {1469 for (j = 0; j < btr_search_index_num; j++) {
1471 ut_ad(rw_lock_own(btr_search_latch_part[j], RW_LOCK_EX));1470 ut_ad(rw_lock_own(&btr_search_latch_arr[j], RW_LOCK_EX));
1472 }1471 }
1473#endif /* UNIV_SYNC_DEBUG */1472#endif /* UNIV_SYNC_DEBUG */
1474 ut_ad(!btr_search_enabled);1473 ut_ad(!btr_search_enabled);
@@ -2147,7 +2146,6 @@
2147{2146{
2148 block->check_index_page_at_flush = FALSE;2147 block->check_index_page_at_flush = FALSE;
2149 block->index = NULL;2148 block->index = NULL;
2150 block->btr_search_latch = NULL;
21512149
2152 block->n_hash_helps = 0;2150 block->n_hash_helps = 0;
2153 block->n_fields = 1;2151 block->n_fields = 1;
21542152
=== modified file 'Percona-Server/storage/innobase/dict/dict0boot.c'
--- Percona-Server/storage/innobase/dict/dict0boot.c 2013-08-14 03:52:04 +0000
+++ Percona-Server/storage/innobase/dict/dict0boot.c 2013-09-02 14:07:43 +0000
@@ -31,6 +31,7 @@
3131
32#include "dict0crea.h"32#include "dict0crea.h"
33#include "btr0btr.h"33#include "btr0btr.h"
34#include "btr0sea.h"
34#include "dict0load.h"35#include "dict0load.h"
35#include "dict0load.h"36#include "dict0load.h"
36#include "trx0trx.h"37#include "trx0trx.h"
@@ -346,6 +347,7 @@
346 dict_mem_index_add_field(index, "KEY_COLS", 0);347 dict_mem_index_add_field(index, "KEY_COLS", 0);
347348
348 index->id = DICT_STATS_ID;349 index->id = DICT_STATS_ID;
350 btr_search_index_init(index);
349351
350 root_page_id = mtr_read_ulint(dict_hdr + DICT_HDR_STATS, MLOG_4BYTES,352 root_page_id = mtr_read_ulint(dict_hdr + DICT_HDR_STATS, MLOG_4BYTES,
351 mtr);353 mtr);
@@ -481,6 +483,7 @@
481 dict_mem_index_add_field(index, "NAME", 0);483 dict_mem_index_add_field(index, "NAME", 0);
482484
483 index->id = DICT_TABLES_ID;485 index->id = DICT_TABLES_ID;
486 btr_search_index_init(index);
484487
485 error = dict_index_add_to_cache(table, index,488 error = dict_index_add_to_cache(table, index,
486 mtr_read_ulint(dict_hdr489 mtr_read_ulint(dict_hdr
@@ -495,6 +498,8 @@
495 dict_mem_index_add_field(index, "ID", 0);498 dict_mem_index_add_field(index, "ID", 0);
496499
497 index->id = DICT_TABLE_IDS_ID;500 index->id = DICT_TABLE_IDS_ID;
501 btr_search_index_init(index);
502
498 error = dict_index_add_to_cache(table, index,503 error = dict_index_add_to_cache(table, index,
499 mtr_read_ulint(dict_hdr504 mtr_read_ulint(dict_hdr
500 + DICT_HDR_TABLE_IDS,505 + DICT_HDR_TABLE_IDS,
@@ -528,6 +533,7 @@
528 dict_mem_index_add_field(index, "POS", 0);533 dict_mem_index_add_field(index, "POS", 0);
529534
530 index->id = DICT_COLUMNS_ID;535 index->id = DICT_COLUMNS_ID;
536 btr_search_index_init(index);
531 error = dict_index_add_to_cache(table, index,537 error = dict_index_add_to_cache(table, index,
532 mtr_read_ulint(dict_hdr538 mtr_read_ulint(dict_hdr
533 + DICT_HDR_COLUMNS,539 + DICT_HDR_COLUMNS,
@@ -574,6 +580,7 @@
574 dict_mem_index_add_field(index, "ID", 0);580 dict_mem_index_add_field(index, "ID", 0);
575581
576 index->id = DICT_INDEXES_ID;582 index->id = DICT_INDEXES_ID;
583 btr_search_index_init(index);
577 error = dict_index_add_to_cache(table, index,584 error = dict_index_add_to_cache(table, index,
578 mtr_read_ulint(dict_hdr585 mtr_read_ulint(dict_hdr
579 + DICT_HDR_INDEXES,586 + DICT_HDR_INDEXES,
@@ -602,6 +609,7 @@
602 dict_mem_index_add_field(index, "POS", 0);609 dict_mem_index_add_field(index, "POS", 0);
603610
604 index->id = DICT_FIELDS_ID;611 index->id = DICT_FIELDS_ID;
612 btr_search_index_init(index);
605 error = dict_index_add_to_cache(table, index,613 error = dict_index_add_to_cache(table, index,
606 mtr_read_ulint(dict_hdr614 mtr_read_ulint(dict_hdr
607 + DICT_HDR_FIELDS,615 + DICT_HDR_FIELDS,
608616
=== modified file 'Percona-Server/storage/innobase/dict/dict0dict.c'
--- Percona-Server/storage/innobase/dict/dict0dict.c 2013-08-14 03:52:04 +0000
+++ Percona-Server/storage/innobase/dict/dict0dict.c 2013-09-02 14:07:43 +0000
@@ -1972,7 +1972,7 @@
1972 zero. */1972 zero. */
19731973
1974 for (;;) {1974 for (;;) {
1975 ulint ref_count = btr_search_info_get_ref_count(info, index->id);1975 ulint ref_count = btr_search_info_get_ref_count(info, index);
1976 if (ref_count == 0) {1976 if (ref_count == 0) {
1977 break;1977 break;
1978 }1978 }
@@ -2224,6 +2224,7 @@
2224 new_index->n_user_defined_cols = index->n_fields;2224 new_index->n_user_defined_cols = index->n_fields;
22252225
2226 new_index->id = index->id;2226 new_index->id = index->id;
2227 btr_search_index_init(new_index);
22272228
2228 /* Copy the fields of index */2229 /* Copy the fields of index */
2229 dict_index_copy(new_index, index, table, 0, index->n_fields);2230 dict_index_copy(new_index, index, table, 0, index->n_fields);
@@ -2394,6 +2395,7 @@
2394 new_index->n_user_defined_cols = index->n_fields;2395 new_index->n_user_defined_cols = index->n_fields;
23952396
2396 new_index->id = index->id;2397 new_index->id = index->id;
2398 btr_search_index_init(new_index);
23972399
2398 /* Copy fields from index to new_index */2400 /* Copy fields from index to new_index */
2399 dict_index_copy(new_index, index, table, 0, index->n_fields);2401 dict_index_copy(new_index, index, table, 0, index->n_fields);
24002402
=== modified file 'Percona-Server/storage/innobase/dict/dict0load.c'
--- Percona-Server/storage/innobase/dict/dict0load.c 2013-08-14 03:52:04 +0000
+++ Percona-Server/storage/innobase/dict/dict0load.c 2013-09-02 14:07:43 +0000
@@ -33,6 +33,7 @@
3333
34#include "btr0pcur.h"34#include "btr0pcur.h"
35#include "btr0btr.h"35#include "btr0btr.h"
36#include "btr0sea.h"
36#include "page0page.h"37#include "page0page.h"
37#include "mach0data.h"38#include "mach0data.h"
38#include "dict0dict.h"39#include "dict0dict.h"
@@ -1432,6 +1433,7 @@
14321433
1433 (*index)->id = id;1434 (*index)->id = id;
1434 (*index)->page = mach_read_from_4(field);1435 (*index)->page = mach_read_from_4(field);
1436 btr_search_index_init(*index);
1435 ut_ad((*index)->page);1437 ut_ad((*index)->page);
14361438
1437 return(NULL);1439 return(NULL);
14381440
=== modified file 'Percona-Server/storage/innobase/handler/ha_innodb.cc'
--- Percona-Server/storage/innobase/handler/ha_innodb.cc 2013-08-23 07:35:34 +0000
+++ Percona-Server/storage/innobase/handler/ha_innodb.cc 2013-09-02 14:07:43 +0000
@@ -963,9 +963,14 @@
963/*==============================*/963/*==============================*/
964 trx_t* trx) /*!< in: transaction handle */964 trx_t* trx) /*!< in: transaction handle */
965{965{
966<<<<<<< TREE
966#ifdef UNIV_SYNC_DEBUG967#ifdef UNIV_SYNC_DEBUG
967 ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));968 ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));
968#endif /* UNIV_SYNC_DEBUG */969#endif /* UNIV_SYNC_DEBUG */
970=======
971 /* No-op in XtraDB */
972 trx_search_latch_release_if_reserved(trx);
973>>>>>>> MERGE-SOURCE
969974
970 if (trx->declared_to_be_inside_innodb) {975 if (trx->declared_to_be_inside_innodb) {
971976
@@ -3564,9 +3569,8 @@
3564 /* Since we will reserve the kernel mutex, we have to release3569 /* Since we will reserve the kernel mutex, we have to release
3565 the search system latch first to obey the latching order. */3570 the search system latch first to obey the latching order. */
35663571
3567 if (trx->has_search_latch) {3572 /* No-op in XtraDB */
3568 trx_search_latch_release_if_reserved(trx);3573 trx_search_latch_release_if_reserved(trx);
3569 }
35703574
3571 if (!trx_is_registered_for_2pc(trx) && trx_is_started(trx)) {3575 if (!trx_is_registered_for_2pc(trx) && trx_is_started(trx)) {
3572 /* We cannot throw error here; instead we will catch this error3576 /* We cannot throw error here; instead we will catch this error
@@ -3612,9 +3616,8 @@
3612 /* Since we will reserve the kernel mutex, we have to release3616 /* Since we will reserve the kernel mutex, we have to release
3613 the search system latch first to obey the latching order. */3617 the search system latch first to obey the latching order. */
36143618
3615 if (trx->has_search_latch) {3619 /* No-op in XtraDB */
3616 trx_search_latch_release_if_reserved(trx);3620 trx_search_latch_release_if_reserved(trx);
3617 }
36183621
3619 if (trx->fake_changes && (all || (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))) {3622 if (trx->fake_changes && (all || (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))) {
3620 innobase_rollback(hton, thd, all); /* rollback implicitly */3623 innobase_rollback(hton, thd, all); /* rollback implicitly */
@@ -12820,6 +12823,8 @@
12820 "Disable with --skip-innodb-adaptive-hash-index.",12823 "Disable with --skip-innodb-adaptive-hash-index.",
12821 NULL, innodb_adaptive_hash_index_update, TRUE);12824 NULL, innodb_adaptive_hash_index_update, TRUE);
1282212825
12826/* btr_search_index_num is constrained to machine word size for historical
12827reasons. This limitation can be easily removed later. */
12823static MYSQL_SYSVAR_ULONG(adaptive_hash_index_partitions, btr_search_index_num,12828static MYSQL_SYSVAR_ULONG(adaptive_hash_index_partitions, btr_search_index_num,
12824 PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,12829 PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
12825 "Number of InnoDB adaptive hash index partitions (default 1: disable partitioning)",12830 "Number of InnoDB adaptive hash index partitions (default 1: disable partitioning)",
1282612831
=== modified file 'Percona-Server/storage/innobase/ibuf/ibuf0ibuf.c'
--- Percona-Server/storage/innobase/ibuf/ibuf0ibuf.c 2013-08-14 03:52:04 +0000
+++ Percona-Server/storage/innobase/ibuf/ibuf0ibuf.c 2013-09-02 14:07:43 +0000
@@ -48,6 +48,7 @@
48#include "btr0cur.h"48#include "btr0cur.h"
49#include "btr0pcur.h"49#include "btr0pcur.h"
50#include "btr0btr.h"50#include "btr0btr.h"
51#include "btr0sea.h"
51#include "row0upd.h"52#include "row0upd.h"
52#include "sync0sync.h"53#include "sync0sync.h"
53#include "dict0boot.h"54#include "dict0boot.h"
@@ -631,6 +632,7 @@
631 dict_mem_index_add_field(index, "DUMMY_COLUMN", 0);632 dict_mem_index_add_field(index, "DUMMY_COLUMN", 0);
632633
633 index->id = DICT_IBUF_ID_MIN + IBUF_SPACE_ID;634 index->id = DICT_IBUF_ID_MIN + IBUF_SPACE_ID;
635 btr_search_index_init(index);
634636
635 error = dict_index_add_to_cache(table, index,637 error = dict_index_add_to_cache(table, index,
636 FSP_IBUF_TREE_ROOT_PAGE_NO, FALSE);638 FSP_IBUF_TREE_ROOT_PAGE_NO, FALSE);
637639
=== modified file 'Percona-Server/storage/innobase/include/btr0sea.h'
--- Percona-Server/storage/innobase/include/btr0sea.h 2013-08-14 03:52:04 +0000
+++ Percona-Server/storage/innobase/include/btr0sea.h 2013-09-02 14:07:43 +0000
@@ -86,7 +86,7 @@
86btr_search_info_get_ref_count(86btr_search_info_get_ref_count(
87/*==========================*/87/*==========================*/
88 btr_search_t* info, /*!< in: search info. */88 btr_search_t* info, /*!< in: search info. */
89 index_id_t key);89 dict_index_t* index); /*!< in: index */
90/*********************************************************************//**90/*********************************************************************//**
91Updates the search info. */91Updates the search info. */
92UNIV_INLINE92UNIV_INLINE
@@ -204,15 +204,35 @@
204New functions to control split btr_search_index */204New functions to control split btr_search_index */
205UNIV_INLINE205UNIV_INLINE
206hash_table_t*206hash_table_t*
207btr_search_get_hash_index(207btr_search_get_hash_table(
208/*======================*/208/*======================*/
209 index_id_t key);209 const dict_index_t* index) /*!< in: index */
210 __attribute__((nonnull,pure,warn_unused_result));
210211
211UNIV_INLINE212UNIV_INLINE
212rw_lock_t*213rw_lock_t*
213btr_search_get_latch(214btr_search_get_latch(
214/*=================*/215/*=================*/
215 index_id_t key);216 const dict_index_t* index) /*!< in: index */
217 __attribute__((nonnull,pure,warn_unused_result));
218
219/*********************************************************************//**
220Returns the AHI partition number corresponding to a give index ID. */
221UNIV_INLINE
222ulint
223btr_search_get_key(
224/*===============*/
225 index_id_t index_id) /*!< in: index ID */
226 __attribute__((pure,warn_unused_result));
227
228/*********************************************************************//**
229Initializes AHI-related fields in a newly created index. */
230UNIV_INLINE
231void
232btr_search_index_init(
233/*===============*/
234 dict_index_t* index) /*!< in: index */
235 __attribute__((nonnull));
216236
217UNIV_INLINE237UNIV_INLINE
218void238void
@@ -224,15 +244,16 @@
224btr_search_x_unlock_all(void);244btr_search_x_unlock_all(void);
225/*==========================*/245/*==========================*/
226246
227UNIV_INLINE247#ifdef UNIV_SYNC_DEBUG
228void248/********************************************************************//**
229btr_search_s_lock_all(void);249Checks if the thread owns any adaptive hash latches in either S or X mode.
230/*========================*/250@return TRUE if the thread owns at least one latch in any mode. */
231251UNIV_INLINE
232UNIV_INLINE252ibool
233void253btr_search_own_any(void)
234btr_search_s_unlock_all(void);254/*=====================*/
235/*==========================*/255 __attribute__((warn_unused_result));
256#endif
236257
237/** The search info struct in an index */258/** The search info struct in an index */
238struct btr_search_struct{259struct btr_search_struct{
@@ -294,8 +315,8 @@
294315
295/** The hash index system */316/** The hash index system */
296struct btr_search_sys_struct{317struct btr_search_sys_struct{
297 hash_table_t** hash_index; /*!< the adaptive hash index,318 hash_table_t** hash_tables; /*!< the array of adaptive hash index,
298 mapping dtuple_fold values319 tables mapping dtuple_fold values
299 to rec_t pointers on index pages */320 to rec_t pointers on index pages */
300};321};
301322
302323
=== modified file 'Percona-Server/storage/innobase/include/btr0sea.ic'
--- Percona-Server/storage/innobase/include/btr0sea.ic 2013-08-02 09:40:55 +0000
+++ Percona-Server/storage/innobase/include/btr0sea.ic 2013-09-02 14:07:43 +0000
@@ -87,20 +87,55 @@
87New functions to control split btr_search_index */87New functions to control split btr_search_index */
88UNIV_INLINE88UNIV_INLINE
89hash_table_t*89hash_table_t*
90btr_search_get_hash_index(90btr_search_get_hash_table(
91/*======================*/91/*======================*/
92 index_id_t key)92 const dict_index_t* index) /*!< in: index */
93{93{
94 return(btr_search_sys->hash_index[key % btr_search_index_num]);94 ut_ad(index);
95 ut_ad(index->search_table);
96
97 return(index->search_table);
95}98}
9699
97UNIV_INLINE100UNIV_INLINE
98rw_lock_t*101rw_lock_t*
99btr_search_get_latch(102btr_search_get_latch(
100/*=================*/103/*=================*/
101 index_id_t key)104 const dict_index_t* index) /*!< in: index */
102{105{
103 return(btr_search_latch_part[key % btr_search_index_num]);106 ut_ad(index);
107 ut_ad(index->search_latch >= btr_search_latch_arr &&
108 index->search_latch < btr_search_latch_arr +
109 btr_search_index_num);
110
111 return(index->search_latch);
112}
113
114/*********************************************************************//**
115Returns the AHI partition number corresponding to a give index ID. */
116UNIV_INLINE
117ulint
118btr_search_get_key(
119/*===============*/
120 index_id_t index_id) /*!< in: index ID */
121{
122 return(index_id % btr_search_index_num);
123}
124
125/*********************************************************************//**
126Initializes AHI-related fields in a newly created index. */
127UNIV_INLINE
128void
129btr_search_index_init(
130/*===============*/
131 dict_index_t* index) /*!< in: index */
132{
133 ut_ad(index);
134
135 index->search_latch =
136 &btr_search_latch_arr[btr_search_get_key(index->id)];
137 index->search_table =
138 btr_search_sys->hash_tables[btr_search_get_key(index->id)];
104}139}
105140
106UNIV_INLINE141UNIV_INLINE
@@ -111,7 +146,7 @@
111 ulint i;146 ulint i;
112147
113 for (i = 0; i < btr_search_index_num; i++) {148 for (i = 0; i < btr_search_index_num; i++) {
114 rw_lock_x_lock(btr_search_latch_part[i]);149 rw_lock_x_lock(&btr_search_latch_arr[i]);
115 }150 }
116}151}
117152
@@ -123,31 +158,28 @@
123 ulint i;158 ulint i;
124159
125 for (i = 0; i < btr_search_index_num; i++) {160 for (i = 0; i < btr_search_index_num; i++) {
126 rw_lock_x_unlock(btr_search_latch_part[i]);161 rw_lock_x_unlock(&btr_search_latch_arr[i]);
127 }162 }
128}163}
129164
130UNIV_INLINE165#ifdef UNIV_SYNC_DEBUG
131void166/********************************************************************//**
132btr_search_s_lock_all(void)167Checks if the thread owns any adaptive hash latches in either S or X mode.
133/*=======================*/168@return TRUE if the thread owns at least one latch in any mode. */
134{169UNIV_INLINE
135 ulint i;170ibool
136171btr_search_own_any(void)
137 for (i = 0; i < btr_search_index_num; i++) {172/*====================*/
138 rw_lock_s_lock(btr_search_latch_part[i]);173{
139 }174 ulint i;
140}175
141176 for (i = 0; i < btr_search_index_num; i++) {
142UNIV_INLINE177 if (rw_lock_own(&btr_search_latch_arr[i], RW_LOCK_SHARED) ||
143void178 rw_lock_own(&btr_search_latch_arr[i], RW_LOCK_EX)) {
144btr_search_s_unlock_all(void)179 return(TRUE);
145/*=========================*/180 }
146{181 }
147 ulint i;182
148183 return(FALSE);
149 for (i = 0; i < btr_search_index_num; i++) {184}
150 rw_lock_s_unlock(btr_search_latch_part[i]);185#endif
151 }
152}
153
154186
=== modified file 'Percona-Server/storage/innobase/include/btr0types.h'
--- Percona-Server/storage/innobase/include/btr0types.h 2013-08-02 09:40:55 +0000
+++ Percona-Server/storage/innobase/include/btr0types.h 2013-09-02 14:07:43 +0000
@@ -41,22 +41,21 @@
4141
42#ifndef UNIV_HOTBACKUP42#ifndef UNIV_HOTBACKUP
4343
44/** @brief The latch protecting the adaptive search system44/** @brief The array of latches protecting the adaptive search partitions
4545
46This latch protects the46These latch protect the
47(1) hash index;47(1) hash index from the corresponding AHI partition;
48(2) columns of a record to which we have a pointer in the hash index;48(2) columns of a record to which we have a pointer in the hash index;
4949
50but does NOT protect:50but do NOT protect:
5151
52(3) next record offset field in a record;52(3) next record offset field in a record;
53(4) next or previous records on the same page.53(4) next or previous records on the same page.
5454
55Bear in mind (3) and (4) when using the hash index.55Bear in mind (3) and (4) when using the hash indexes.
56*/56*/
57//extern rw_lock_t* btr_search_latch_temp;
5857
59extern rw_lock_t** btr_search_latch_part;58extern rw_lock_t* btr_search_latch_arr;
6059
61#endif /* UNIV_HOTBACKUP */60#endif /* UNIV_HOTBACKUP */
6261
6362
=== modified file 'Percona-Server/storage/innobase/include/buf0buf.h'
--- Percona-Server/storage/innobase/include/buf0buf.h 2013-08-16 08:58:49 +0000
+++ Percona-Server/storage/innobase/include/buf0buf.h 2013-09-02 14:07:43 +0000
@@ -1714,7 +1714,6 @@
1714 complete, though: there may1714 complete, though: there may
1715 have been hash collisions,1715 have been hash collisions,
1716 record deletions, etc. */1716 record deletions, etc. */
1717 volatile rw_lock_t* btr_search_latch;
1718 /* @} */1717 /* @} */
1719# ifdef UNIV_SYNC_DEBUG1718# ifdef UNIV_SYNC_DEBUG
1720 /** @name Debug fields */1719 /** @name Debug fields */
17211720
=== modified file 'Percona-Server/storage/innobase/include/dict0mem.h'
--- Percona-Server/storage/innobase/include/dict0mem.h 2013-06-27 15:35:20 +0000
+++ Percona-Server/storage/innobase/include/dict0mem.h 2013-09-02 14:07:43 +0000
@@ -365,6 +365,10 @@
365initialized to 0, NULL or FALSE in dict_mem_index_create(). */365initialized to 0, NULL or FALSE in dict_mem_index_create(). */
366struct dict_index_struct{366struct dict_index_struct{
367 index_id_t id; /*!< id of the index */367 index_id_t id; /*!< id of the index */
368 rw_lock_t* search_latch; /*!< latch protecting the AHI partition
369 corresponding to this index */
370 hash_table_t* search_table; /*!< hash table protected by
371 search_latch */
368 mem_heap_t* heap; /*!< memory heap */372 mem_heap_t* heap; /*!< memory heap */
369 const char* name; /*!< index name */373 const char* name; /*!< index name */
370 const char* table_name;/*!< table name */374 const char* table_name;/*!< table name */
371375
=== modified file 'Percona-Server/storage/innobase/include/trx0trx.h'
--- Percona-Server/storage/innobase/include/trx0trx.h 2013-08-14 03:52:04 +0000
+++ Percona-Server/storage/innobase/include/trx0trx.h 2013-09-02 14:07:43 +0000
@@ -49,12 +49,14 @@
49extern ulint trx_n_prepared;49extern ulint trx_n_prepared;
5050
51/********************************************************************//**51/********************************************************************//**
52Releases the search latch if trx has reserved it. */52In XtraDB it is impossible for a transaction to own a search latch outside of
53UNIV_INTERN53InnoDB code, so there is nothing to release on demand. We keep this function to
54simplify maintenance.*/
55UNIV_INLINE
54void56void
55trx_search_latch_release_if_reserved(57trx_search_latch_release_if_reserved(
56/*=================================*/58/*=================================*/
57 trx_t* trx); /*!< in: transaction */59 trx_t* trx __attribute__((unused))); /*!< in: transaction */
58/******************************************************************//**60/******************************************************************//**
59Set detailed error message for the transaction. */61Set detailed error message for the transaction. */
60UNIV_INTERN62UNIV_INTERN
@@ -555,8 +557,8 @@
555 in that case we must flush the log557 in that case we must flush the log
556 in trx_commit_complete_for_mysql() */558 in trx_commit_complete_for_mysql() */
557 ulint duplicates; /*!< TRX_DUP_IGNORE | TRX_DUP_REPLACE */559 ulint duplicates; /*!< TRX_DUP_IGNORE | TRX_DUP_REPLACE */
558 ulint has_search_latch;560 ibool has_search_latch;
559 /* TRUE if this trx has latched the561 /* TRUE if this trx has latched any
560 search system latch in S-mode */562 search system latch in S-mode */
561 ulint deadlock_mark; /*!< a mark field used in deadlock563 ulint deadlock_mark; /*!< a mark field used in deadlock
562 checking algorithm. */564 checking algorithm. */
563565
=== modified file 'Percona-Server/storage/innobase/include/trx0trx.ic'
--- Percona-Server/storage/innobase/include/trx0trx.ic 2013-08-02 09:40:55 +0000
+++ Percona-Server/storage/innobase/include/trx0trx.ic 2013-09-02 14:07:43 +0000
@@ -23,6 +23,19 @@
23Created 3/26/1996 Heikki Tuuri23Created 3/26/1996 Heikki Tuuri
24*******************************************************/24*******************************************************/
2525
26/********************************************************************//**
27In XtraDB it is impossible for a transaction to own a search latch outside of
28InnoDB code, so there is nothing to release on demand. We keep this function to
29simplify maintenance.*/
30UNIV_INLINE
31void
32trx_search_latch_release_if_reserved(
33/*=================================*/
34 trx_t* trx __attribute__((unused))) /*!< in: transaction */
35{
36 ut_ad(!trx->has_search_latch);
37}
38
26/*************************************************************//**39/*************************************************************//**
27Starts the transaction if it is not yet started. */40Starts the transaction if it is not yet started. */
28UNIV_INLINE41UNIV_INLINE
2942
=== modified file 'Percona-Server/storage/innobase/row/row0mysql.c'
--- Percona-Server/storage/innobase/row/row0mysql.c 2013-08-14 03:52:04 +0000
+++ Percona-Server/storage/innobase/row/row0mysql.c 2013-09-02 14:07:43 +0000
@@ -2664,7 +2664,9 @@
2664 /* check adaptive hash entries */2664 /* check adaptive hash entries */
2665 index = dict_table_get_first_index(table);2665 index = dict_table_get_first_index(table);
2666 while (index) {2666 while (index) {
2667 ulint ref_count = btr_search_info_get_ref_count(index->search_info, index->id);2667 ulint ref_count =
2668 btr_search_info_get_ref_count(
2669 index->search_info, index);
2668 if (ref_count) {2670 if (ref_count) {
2669 fprintf(stderr, "InnoDB: Warning:"2671 fprintf(stderr, "InnoDB: Warning:"
2670 " hash index ref_count (%lu) is not zero"2672 " hash index ref_count (%lu) is not zero"
@@ -3025,7 +3027,9 @@
3025 table->space = space;3027 table->space = space;
3026 index = dict_table_get_first_index(table);3028 index = dict_table_get_first_index(table);
3027 do {3029 do {
3028 ulint ref_count = btr_search_info_get_ref_count(index->search_info, index->id);3030 ulint ref_count =
3031 btr_search_info_get_ref_count(
3032 index->search_info, index);
3029 /* check adaptive hash entries */3033 /* check adaptive hash entries */
3030 if (ref_count) {3034 if (ref_count) {
3031 fprintf(stderr, "InnoDB: Warning:"3035 fprintf(stderr, "InnoDB: Warning:"
30323036
=== modified file 'Percona-Server/storage/innobase/row/row0sel.c'
--- Percona-Server/storage/innobase/row/row0sel.c 2013-08-14 03:52:04 +0000
+++ Percona-Server/storage/innobase/row/row0sel.c 2013-09-02 14:07:43 +0000
@@ -1224,7 +1224,7 @@
1224 ut_ad(plan->unique_search);1224 ut_ad(plan->unique_search);
1225 ut_ad(!plan->must_get_clust);1225 ut_ad(!plan->must_get_clust);
1226#ifdef UNIV_SYNC_DEBUG1226#ifdef UNIV_SYNC_DEBUG
1227 ut_ad(rw_lock_own(btr_search_get_latch(index->id), RW_LOCK_SHARED));1227 ut_ad(rw_lock_own(btr_search_get_latch(index), RW_LOCK_SHARED));
1228#endif /* UNIV_SYNC_DEBUG */1228#endif /* UNIV_SYNC_DEBUG */
12291229
1230 row_sel_open_pcur(plan, TRUE, mtr);1230 row_sel_open_pcur(plan, TRUE, mtr);
@@ -1395,10 +1395,11 @@
1395 && !plan->must_get_clust1395 && !plan->must_get_clust
1396 && !plan->table->big_rows) {1396 && !plan->table->big_rows) {
1397 if (!search_latch_locked) {1397 if (!search_latch_locked) {
1398 rw_lock_s_lock(btr_search_get_latch(index->id));1398 rw_lock_s_lock(btr_search_get_latch(index));
13991399
1400 search_latch_locked = TRUE;1400 search_latch_locked = TRUE;
1401 } else if (rw_lock_get_writer(btr_search_get_latch(index->id)) == RW_LOCK_WAIT_EX) {1401 } else if (rw_lock_get_writer(btr_search_get_latch(index))
1402 == RW_LOCK_WAIT_EX) {
14021403
1403 /* There is an x-latch request waiting: release the1404 /* There is an x-latch request waiting: release the
1404 s-latch for a moment; as an s-latch here is often1405 s-latch for a moment; as an s-latch here is often
@@ -1407,8 +1408,8 @@
1407 from acquiring an s-latch for a long time, lowering1408 from acquiring an s-latch for a long time, lowering
1408 performance significantly in multiprocessors. */1409 performance significantly in multiprocessors. */
14091410
1410 rw_lock_s_unlock(btr_search_get_latch(index->id));1411 rw_lock_s_unlock(btr_search_get_latch(index));
1411 rw_lock_s_lock(btr_search_get_latch(index->id));1412 rw_lock_s_lock(btr_search_get_latch(index));
1412 }1413 }
14131414
1414 found_flag = row_sel_try_search_shortcut(node, plan, &mtr);1415 found_flag = row_sel_try_search_shortcut(node, plan, &mtr);
@@ -1431,7 +1432,7 @@
1431 }1432 }
14321433
1433 if (search_latch_locked) {1434 if (search_latch_locked) {
1434 rw_lock_s_unlock(btr_search_get_latch(index->id));1435 rw_lock_s_unlock(btr_search_get_latch(index));
14351436
1436 search_latch_locked = FALSE;1437 search_latch_locked = FALSE;
1437 }1438 }
@@ -2007,7 +2008,7 @@
20072008
2008func_exit:2009func_exit:
2009 if (search_latch_locked) {2010 if (search_latch_locked) {
2010 rw_lock_s_unlock(btr_search_get_latch(index->id));2011 rw_lock_s_unlock(btr_search_get_latch(index));
2011 }2012 }
2012 if (UNIV_LIKELY_NULL(heap)) {2013 if (UNIV_LIKELY_NULL(heap)) {
2013 mem_heap_free(heap);2014 mem_heap_free(heap);
@@ -2744,6 +2745,9 @@
2744 heap */2745 heap */
27452746
2746 ut_a(!prebuilt->trx->has_search_latch);2747 ut_a(!prebuilt->trx->has_search_latch);
2748#ifdef UNIV_SYNC_DEBUG
2749 ut_ad(!btr_search_own_any());
2750#endif
27472751
2748 if (UNIV_UNLIKELY(templ->type == DATA_BLOB)) {2752 if (UNIV_UNLIKELY(templ->type == DATA_BLOB)) {
2749 if (prebuilt->blob_heap == NULL) {2753 if (prebuilt->blob_heap == NULL) {
@@ -3320,6 +3324,8 @@
3320 ut_ad(!prebuilt->templ_contains_blob);3324 ut_ad(!prebuilt->templ_contains_blob);
33213325
3322#ifndef UNIV_SEARCH_DEBUG3326#ifndef UNIV_SEARCH_DEBUG
3327 ut_ad(trx->has_search_latch);
3328
3323 btr_pcur_open_with_no_init(index, search_tuple, PAGE_CUR_GE,3329 btr_pcur_open_with_no_init(index, search_tuple, PAGE_CUR_GE,
3324 BTR_SEARCH_LEAF, pcur,3330 BTR_SEARCH_LEAF, pcur,
3325 RW_S_LATCH,3331 RW_S_LATCH,
@@ -3420,8 +3426,6 @@
3420 /* if the returned record was locked and we did a semi-consistent3426 /* if the returned record was locked and we did a semi-consistent
3421 read (fetch the newest committed version), then this is set to3427 read (fetch the newest committed version), then this is set to
3422 TRUE */3428 TRUE */
3423 ulint i;
3424 ulint should_release;
3425#ifdef UNIV_SEARCH_DEBUG3429#ifdef UNIV_SEARCH_DEBUG
3426 ulint cnt = 0;3430 ulint cnt = 0;
3427#endif /* UNIV_SEARCH_DEBUG */3431#endif /* UNIV_SEARCH_DEBUG */
@@ -3438,6 +3442,12 @@
34383442
3439 ut_ad(index && pcur && search_tuple);3443 ut_ad(index && pcur && search_tuple);
34403444
3445 ut_ad(!trx->has_search_latch);
3446#ifdef UNIV_SYNC_DEBUG
3447 ut_ad(!btr_search_own_any());
3448 ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));
3449#endif /* UNIV_SYNC_DEBUG */
3450
3441 if (UNIV_UNLIKELY(prebuilt->table->ibd_file_missing)) {3451 if (UNIV_UNLIKELY(prebuilt->table->ibd_file_missing)) {
3442 ut_print_timestamp(stderr);3452 ut_print_timestamp(stderr);
3443 fprintf(stderr, " InnoDB: Error:\n"3453 fprintf(stderr, " InnoDB: Error:\n"
@@ -3453,24 +3463,15 @@
3453 "InnoDB: how you can resolve the problem.\n",3463 "InnoDB: how you can resolve the problem.\n",
3454 prebuilt->table->name);3464 prebuilt->table->name);
34553465
3456#ifdef UNIV_SYNC_DEBUG
3457 ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));
3458#endif /* UNIV_SYNC_DEBUG */
3459 return(DB_ERROR);3466 return(DB_ERROR);
3460 }3467 }
34613468
3462 if (UNIV_UNLIKELY(!prebuilt->index_usable)) {3469 if (UNIV_UNLIKELY(!prebuilt->index_usable)) {
34633470
3464#ifdef UNIV_SYNC_DEBUG
3465 ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));
3466#endif /* UNIV_SYNC_DEBUG */
3467 return(DB_MISSING_HISTORY);3471 return(DB_MISSING_HISTORY);
3468 }3472 }
34693473
3470 if (dict_index_is_corrupted(index)) {3474 if (dict_index_is_corrupted(index)) {
3471#ifdef UNIV_SYNC_DEBUG
3472 ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));
3473#endif /* UNIV_SYNC_DEBUG */
3474 return(DB_CORRUPTION);3475 return(DB_CORRUPTION);
3475 }3476 }
34763477
@@ -3515,38 +3516,6 @@
3515 fprintf(stderr, "N tables locked %lu\n",3516 fprintf(stderr, "N tables locked %lu\n",
3516 (ulong) trx->mysql_n_tables_locked);3517 (ulong) trx->mysql_n_tables_locked);
3517#endif3518#endif
3518 /*-------------------------------------------------------------*/
3519 /* PHASE 0: Release a possible s-latch we are holding on the
3520 adaptive hash index latch if there is someone waiting behind */
3521
3522 should_release = 0;
3523 for (i = 0; i < btr_search_index_num; i++) {
3524 /* we should check all latches (fix Bug#791030) */
3525 if (UNIV_UNLIKELY(rw_lock_get_writer(btr_search_latch_part[i])
3526 != RW_LOCK_NOT_LOCKED)) {
3527 should_release |= ((ulint)1 << i);
3528 }
3529 }
3530
3531 if (UNIV_UNLIKELY(should_release)) {
3532
3533 /* There is an x-latch request on the adaptive hash index:
3534 release the s-latch to reduce starvation and wait for
3535 BTR_SEA_TIMEOUT rounds before trying to keep it again over
3536 calls from MySQL */
3537
3538 for (i = 0; i < btr_search_index_num; i++) {
3539 /* we should release all s-latches (fix Bug#791030) */
3540 if (trx->has_search_latch & ((ulint)1 << i)) {
3541 rw_lock_s_unlock(btr_search_latch_part[i]);
3542 trx->has_search_latch &= (~((ulint)1 << i));
3543 }
3544 }
3545
3546 if (!trx->has_search_latch) {
3547 trx->search_latch_timeout = BTR_SEA_TIMEOUT;
3548 }
3549 }
35503519
3551 /* Reset the new record lock info if srv_locks_unsafe_for_binlog3520 /* Reset the new record lock info if srv_locks_unsafe_for_binlog
3552 is set or session is using a READ COMMITED isolation level. Then3521 is set or session is using a READ COMMITED isolation level. Then
@@ -3696,29 +3665,9 @@
3696 hash index semaphore! */3665 hash index semaphore! */
36973666
3698#ifndef UNIV_SEARCH_DEBUG3667#ifndef UNIV_SEARCH_DEBUG
3699 if (!(trx->has_search_latch3668 ut_ad(!trx->has_search_latch);
3700 & ((ulint)1 << (index->id % btr_search_index_num)))) {3669 rw_lock_s_lock(btr_search_get_latch(index));
3701 if (trx->has_search_latch3670 trx->has_search_latch = TRUE;
3702 < ((ulint)1 << (index->id % btr_search_index_num))) {
3703 rw_lock_s_lock(btr_search_get_latch(index->id));
3704 trx->has_search_latch |=
3705 ((ulint)1 << (index->id % btr_search_index_num));
3706 } else {
3707 /* should re-lock to obay latch-order */
3708 for (i = 0; i < btr_search_index_num; i++) {
3709 if (trx->has_search_latch & ((ulint)1 << i)) {
3710 rw_lock_s_unlock(btr_search_latch_part[i]);
3711 }
3712 }
3713 trx->has_search_latch |=
3714 ((ulint)1 << (index->id % btr_search_index_num));
3715 for (i = 0; i < btr_search_index_num; i++) {
3716 if (trx->has_search_latch & ((ulint)1 << i)) {
3717 rw_lock_s_lock(btr_search_latch_part[i]);
3718 }
3719 }
3720 }
3721 }
3722#endif3671#endif
3723 switch (row_sel_try_search_shortcut_for_mysql(3672 switch (row_sel_try_search_shortcut_for_mysql(
3724 &rec, prebuilt, &offsets, &heap,3673 &rec, prebuilt, &offsets, &heap,
@@ -3763,7 +3712,7 @@
3763 srv_n_rows_read++;3712 srv_n_rows_read++;
37643713
3765 err = DB_SUCCESS;3714 err = DB_SUCCESS;
3766 goto release_search_latch_if_needed;3715 goto release_search_latch;
37673716
3768 case SEL_EXHAUSTED:3717 case SEL_EXHAUSTED:
3769 mtr_commit(&mtr);3718 mtr_commit(&mtr);
@@ -3772,19 +3721,10 @@
3772 fputs(" record not found 2\n", stderr); */3721 fputs(" record not found 2\n", stderr); */
37733722
3774 err = DB_RECORD_NOT_FOUND;3723 err = DB_RECORD_NOT_FOUND;
3775release_search_latch_if_needed:3724release_search_latch:
3776 if (trx->search_latch_timeout > 03725 rw_lock_s_unlock(
3777 && trx->has_search_latch) {3726 btr_search_get_latch(index));
37783727 trx->has_search_latch = FALSE;
3779 trx->search_latch_timeout--;
3780
3781 for (i = 0; i < btr_search_index_num; i++) {
3782 if (trx->has_search_latch & ((ulint)1 << i)) {
3783 rw_lock_s_unlock(btr_search_latch_part[i]);
3784 }
3785 }
3786 trx->has_search_latch = FALSE;
3787 }
37883728
3789 /* NOTE that we do NOT store the cursor3729 /* NOTE that we do NOT store the cursor
3790 position */3730 position */
@@ -3799,22 +3739,19 @@
37993739
3800 mtr_commit(&mtr);3740 mtr_commit(&mtr);
3801 mtr_start(&mtr);3741 mtr_start(&mtr);
3742
3743 rw_lock_s_unlock(btr_search_get_latch(index));
3744 trx->has_search_latch = FALSE;
3802 }3745 }
3803 }3746 }
38043747
3805 /*-------------------------------------------------------------*/3748 /*-------------------------------------------------------------*/
3806 /* PHASE 3: Open or restore index cursor position */3749 /* PHASE 3: Open or restore index cursor position */
38073750
3808 if (trx->has_search_latch) {3751 ut_ad(!trx->has_search_latch);
38093752#ifdef UNIV_SYNC_DEBUG
3810 for (i = 0; i < btr_search_index_num; i++) {3753 ut_ad(!btr_search_own_any());
3811 if (trx->has_search_latch & ((ulint)1 << i)) {3754#endif
3812 rw_lock_s_unlock(btr_search_latch_part[i]);
3813 }
3814 }
3815 trx->has_search_latch = FALSE;
3816 }
3817
3818 ut_ad(prebuilt->sql_stat_start || trx->state == TRX_ACTIVE);3755 ut_ad(prebuilt->sql_stat_start || trx->state == TRX_ACTIVE);
3819 ut_ad(trx->state == TRX_NOT_STARTED3756 ut_ad(trx->state == TRX_NOT_STARTED
3820 || trx->state == TRX_ACTIVE);3757 || trx->state == TRX_ACTIVE);
@@ -4851,7 +4788,9 @@
4851 }4788 }
4852 }4789 }
48534790
4791 ut_ad(!trx->has_search_latch);
4854#ifdef UNIV_SYNC_DEBUG4792#ifdef UNIV_SYNC_DEBUG
4793 ut_ad(!btr_search_own_any());
4855 ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));4794 ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));
4856#endif /* UNIV_SYNC_DEBUG */4795#endif /* UNIV_SYNC_DEBUG */
4857 return(err);4796 return(err);
48584797
=== modified file 'Percona-Server/storage/innobase/srv/srv0srv.c'
--- Percona-Server/storage/innobase/srv/srv0srv.c 2013-08-14 03:52:04 +0000
+++ Percona-Server/storage/innobase/srv/srv0srv.c 2013-09-02 14:07:43 +0000
@@ -1275,8 +1275,10 @@
1275 os_thread_yield();1275 os_thread_yield();
1276 goto retry;1276 goto retry;
1277 }1277 }
1278 if (trx->has_search_latch1278
1279 || NULL != UT_LIST_GET_FIRST(trx->trx_locks)) {1279 ut_ad(!trx->has_search_latch);
1280
1281 if (NULL != UT_LIST_GET_FIRST(trx->trx_locks)) {
12801282
1281 conc_n_threads = os_atomic_increment_lint(&srv_conc_n_threads, 1);1283 conc_n_threads = os_atomic_increment_lint(&srv_conc_n_threads, 1);
1282 enter_innodb_with_tickets(trx);1284 enter_innodb_with_tickets(trx);
@@ -1319,7 +1321,9 @@
1319 ulint sec;1321 ulint sec;
1320 ulint ms;1322 ulint ms;
13211323
1324 ut_ad(!trx->has_search_latch);
1322#ifdef UNIV_SYNC_DEBUG1325#ifdef UNIV_SYNC_DEBUG
1326 ut_ad(!btr_search_own_any());
1323 ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));1327 ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));
1324#endif /* UNIV_SYNC_DEBUG */1328#endif /* UNIV_SYNC_DEBUG */
13251329
@@ -1379,7 +1383,9 @@
1379 /* If the transaction is not holding resources, let it sleep1383 /* If the transaction is not holding resources, let it sleep
1380 for SRV_THREAD_SLEEP_DELAY microseconds, and try again then */1384 for SRV_THREAD_SLEEP_DELAY microseconds, and try again then */
13811385
1382 if (!has_slept && !trx->has_search_latch1386 ut_ad(!trx->has_search_latch);
1387
1388 if (!has_slept
1383 && NULL == UT_LIST_GET_FIRST(trx->trx_locks)) {1389 && NULL == UT_LIST_GET_FIRST(trx->trx_locks)) {
13841390
1385 has_slept = TRUE; /* We let it sleep only once to avoid1391 has_slept = TRUE; /* We let it sleep only once to avoid
@@ -1434,10 +1440,8 @@
1434 return;1440 return;
1435 }1441 }
14361442
1437 /* Release possible search system latch this thread has */1443 /* No-op for XtraDB. */
1438 if (trx->has_search_latch) {1444 trx_search_latch_release_if_reserved(trx);
1439 trx_search_latch_release_if_reserved(trx);
1440 }
14411445
1442 /* Add to the queue */1446 /* Add to the queue */
1443 slot->reserved = TRUE;1447 slot->reserved = TRUE;
@@ -1456,6 +1460,7 @@
14561460
1457 ut_ad(!trx->has_search_latch);1461 ut_ad(!trx->has_search_latch);
1458#ifdef UNIV_SYNC_DEBUG1462#ifdef UNIV_SYNC_DEBUG
1463 ut_ad(!btr_search_own_any());
1459 ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));1464 ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));
1460#endif /* UNIV_SYNC_DEBUG */1465#endif /* UNIV_SYNC_DEBUG */
14611466
@@ -1507,7 +1512,9 @@
1507 trx_t* trx) /*!< in: transaction object associated with the1512 trx_t* trx) /*!< in: transaction object associated with the
1508 thread */1513 thread */
1509{1514{
1515 ut_ad(!trx->has_search_latch);
1510#ifdef UNIV_SYNC_DEBUG1516#ifdef UNIV_SYNC_DEBUG
1517 ut_ad(!btr_search_own_any());
1511 ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));1518 ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));
1512#endif /* UNIV_SYNC_DEBUG */1519#endif /* UNIV_SYNC_DEBUG */
15131520
@@ -1598,7 +1605,9 @@
1598 os_event_set(slot->event);1605 os_event_set(slot->event);
1599 }1606 }
16001607
1608 ut_ad(!trx->has_search_latch);
1601#ifdef UNIV_SYNC_DEBUG1609#ifdef UNIV_SYNC_DEBUG
1610 ut_ad(!btr_search_own_any());
1602 ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));1611 ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));
1603#endif /* UNIV_SYNC_DEBUG */1612#endif /* UNIV_SYNC_DEBUG */
1604}1613}
@@ -1612,7 +1621,9 @@
1612 trx_t* trx) /*!< in: transaction object associated with the1621 trx_t* trx) /*!< in: transaction object associated with the
1613 thread */1622 thread */
1614{1623{
1624 ut_ad(!trx->has_search_latch);
1615#ifdef UNIV_SYNC_DEBUG1625#ifdef UNIV_SYNC_DEBUG
1626 ut_ad(!btr_search_own_any());
1616 ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));1627 ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));
1617#endif /* UNIV_SYNC_DEBUG */1628#endif /* UNIV_SYNC_DEBUG */
16181629
@@ -1885,7 +1896,9 @@
1885 os_event_wait(event);1896 os_event_wait(event);
1886 thd_wait_end(trx->mysql_thd);1897 thd_wait_end(trx->mysql_thd);
18871898
1899 ut_ad(!trx->has_search_latch);
1888#ifdef UNIV_SYNC_DEBUG1900#ifdef UNIV_SYNC_DEBUG
1901 ut_ad(!btr_search_own_any());
1889 ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));1902 ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));
1890#endif /* UNIV_SYNC_DEBUG */1903#endif /* UNIV_SYNC_DEBUG */
18911904
@@ -2047,7 +2060,8 @@
2047 ulint n_reserved;2060 ulint n_reserved;
2048 ibool ret;2061 ibool ret;
20492062
2050 ulint btr_search_sys_subtotal;2063 ulong btr_search_sys_constant;
2064 ulong btr_search_sys_variable;
2051 ulint lock_sys_subtotal;2065 ulint lock_sys_subtotal;
2052 ulint recv_sys_subtotal;2066 ulint recv_sys_subtotal;
20532067
@@ -2113,7 +2127,7 @@
2113 ibuf_print(file);2127 ibuf_print(file);
21142128
2115 for (i = 0; i < btr_search_index_num; i++) {2129 for (i = 0; i < btr_search_index_num; i++) {
2116 ha_print_info(file, btr_search_get_hash_index((index_id_t)i));2130 ha_print_info(file, btr_search_sys->hash_tables[i]);
2117 }2131 }
21182132
2119 fprintf(file,2133 fprintf(file,
@@ -2141,16 +2155,28 @@
2141 fprintf(file,2155 fprintf(file,
2142 "Total memory allocated by read views " ULINTPF "\n",2156 "Total memory allocated by read views " ULINTPF "\n",
2143 srv_read_views_memory);2157 srv_read_views_memory);
2144 /* Calcurate reserved memories */2158
2145 if (btr_search_sys && btr_search_sys->hash_index[0]->heap) {2159 /* Calculate AHI constant and variable memory allocations */
2146 btr_search_sys_subtotal = mem_heap_get_size(btr_search_sys->hash_index[0]->heap);2160
2147 } else {2161 btr_search_sys_constant = 0;
2148 btr_search_sys_subtotal = 0;2162 btr_search_sys_variable = 0;
2149 for (i=0; i < btr_search_sys->hash_index[0]->n_mutexes; i++) {2163
2150 btr_search_sys_subtotal += mem_heap_get_size(btr_search_sys->hash_index[0]->heaps[i]);2164 ut_ad(btr_search_sys->hash_tables);
2151 }2165
2166 for (i = 0; i < btr_search_index_num; i++) {
2167 hash_table_t* ht = btr_search_sys->hash_tables[i];
2168
2169 ut_ad(ht);
2170 ut_ad(ht->heap);
2171
2172 /* Multiple mutexes/heaps are currently never used for adaptive
2173 hash index tables. */
2174 ut_ad(!ht->n_mutexes);
2175 ut_ad(!ht->heaps);
2176
2177 btr_search_sys_variable += mem_heap_get_size(ht->heap);
2178 btr_search_sys_constant += ht->n_cells * sizeof(hash_cell_t);
2152 }2179 }
2153 btr_search_sys_subtotal *= btr_search_index_num;
21542180
2155 lock_sys_subtotal = 0;2181 lock_sys_subtotal = 0;
2156 if (trx_sys) {2182 if (trx_sys) {
@@ -2175,12 +2201,9 @@
2175 " Lock system %lu \t(%lu + %lu)\n"2201 " Lock system %lu \t(%lu + %lu)\n"
2176 " Recovery system %lu \t(%lu + %lu)\n",2202 " Recovery system %lu \t(%lu + %lu)\n",
21772203
2178 (ulong) (btr_search_sys2204 btr_search_sys_constant + btr_search_sys_variable,
2179 ? (btr_search_sys->hash_index[0]->n_cells * btr_search_index_num * sizeof(hash_cell_t)) : 0)2205 btr_search_sys_constant,
2180 + btr_search_sys_subtotal,2206 btr_search_sys_variable,
2181 (ulong) (btr_search_sys
2182 ? (btr_search_sys->hash_index[0]->n_cells * btr_search_index_num * sizeof(hash_cell_t)) : 0),
2183 (ulong) btr_search_sys_subtotal,
21842207
2185 (ulong) (buf_pool_from_array(0)->page_hash->n_cells * sizeof(hash_cell_t)),2208 (ulong) (buf_pool_from_array(0)->page_hash->n_cells * sizeof(hash_cell_t)),
21862209
@@ -2342,17 +2365,22 @@
2342 buf_get_total_list_len(&LRU_len, &free_len, &flush_list_len);2365 buf_get_total_list_len(&LRU_len, &free_len, &flush_list_len);
2343 buf_get_total_list_size_in_bytes(&buf_pools_list_size);2366 buf_get_total_list_size_in_bytes(&buf_pools_list_size);
23442367
2345 if (btr_search_sys && btr_search_sys->hash_index[0]->heap) {2368 mem_adaptive_hash = 0;
2346 mem_adaptive_hash = mem_heap_get_size(btr_search_sys->hash_index[0]->heap);2369
2347 } else {2370 ut_ad(btr_search_sys->hash_tables);
2348 mem_adaptive_hash = 0;2371
2349 for (i=0; i < btr_search_sys->hash_index[0]->n_mutexes; i++) {2372 for (i = 0; i < btr_search_index_num; i++) {
2350 mem_adaptive_hash += mem_heap_get_size(btr_search_sys->hash_index[0]->heaps[i]);2373 hash_table_t* ht = btr_search_sys->hash_tables[i];
2351 }2374
2352 }2375 ut_ad(ht);
2353 mem_adaptive_hash *= btr_search_index_num;2376 ut_ad(ht->heap);
2354 if (btr_search_sys) {2377 /* Multiple mutexes/heaps are currently never used for adaptive
2355 mem_adaptive_hash += (btr_search_sys->hash_index[0]->n_cells * btr_search_index_num * sizeof(hash_cell_t));2378 hash index tables. */
2379 ut_ad(!ht->n_mutexes);
2380 ut_ad(!ht->heaps);
2381
2382 mem_adaptive_hash += mem_heap_get_size(ht->heap);
2383 mem_adaptive_hash += ht->n_cells * sizeof(hash_cell_t);
2356 }2384 }
23572385
2358 mem_dictionary = (dict_sys ? ((dict_sys->table_hash->n_cells2386 mem_dictionary = (dict_sys ? ((dict_sys->table_hash->n_cells
@@ -2365,7 +2393,7 @@
2365 export_vars.innodb_adaptive_hash_cells = 0;2393 export_vars.innodb_adaptive_hash_cells = 0;
2366 export_vars.innodb_adaptive_hash_heap_buffers = 0;2394 export_vars.innodb_adaptive_hash_heap_buffers = 0;
2367 for (i = 0; i < btr_search_index_num; i++) {2395 for (i = 0; i < btr_search_index_num; i++) {
2368 hash_table_t* table = btr_search_get_hash_index((index_id_t)i);2396 hash_table_t* table = btr_search_sys->hash_tables[i];
23692397
2370 export_vars.innodb_adaptive_hash_cells2398 export_vars.innodb_adaptive_hash_cells
2371 += hash_get_n_cells(table);2399 += hash_get_n_cells(table);
23722400
=== modified file 'Percona-Server/storage/innobase/trx/trx0trx.c'
--- Percona-Server/storage/innobase/trx/trx0trx.c 2013-08-14 03:52:04 +0000
+++ Percona-Server/storage/innobase/trx/trx0trx.c 2013-09-02 14:07:43 +0000
@@ -386,27 +386,6 @@
386}386}
387387
388/********************************************************************//**388/********************************************************************//**
389Releases the search latch if trx has reserved it. */
390UNIV_INTERN
391void
392trx_search_latch_release_if_reserved(
393/*=================================*/
394 trx_t* trx) /*!< in: transaction */
395{
396 ulint i;
397
398 if (trx->has_search_latch) {
399 for (i = 0; i < btr_search_index_num; i++) {
400 if (trx->has_search_latch & ((ulint)1 << i)) {
401 rw_lock_s_unlock(btr_search_latch_part[i]);
402 }
403 }
404
405 trx->has_search_latch = FALSE;
406 }
407}
408
409/********************************************************************//**
410Frees a transaction object. */389Frees a transaction object. */
411UNIV_INTERN390UNIV_INTERN
412void391void
@@ -468,6 +447,9 @@
468 ut_a(UT_LIST_GET_LEN(trx->wait_thrs) == 0);447 ut_a(UT_LIST_GET_LEN(trx->wait_thrs) == 0);
469448
470 ut_a(!trx->has_search_latch);449 ut_a(!trx->has_search_latch);
450#ifdef UNIV_SYNC_DEBUG
451 ut_ad(!btr_search_own_any());
452#endif
471453
472 ut_a(trx->dict_operation_lock_mode == 0);454 ut_a(trx->dict_operation_lock_mode == 0);
473455
@@ -527,6 +509,9 @@
527 ut_a(UT_LIST_GET_LEN(trx->wait_thrs) == 0);509 ut_a(UT_LIST_GET_LEN(trx->wait_thrs) == 0);
528510
529 ut_a(!trx->has_search_latch);511 ut_a(!trx->has_search_latch);
512#ifdef UNIV_SYNC_DEBUG
513 ut_ad(!btr_search_own_any());
514#endif
530515
531 ut_a(trx->dict_operation_lock_mode == 0);516 ut_a(trx->dict_operation_lock_mode == 0);
532517

Subscribers

People subscribed via source and target branches