1
1
/*****************************************************************************
3
Copyright (C) 1996, 2009, Innobase Oy. All Rights Reserved.
4
Copyright (C) 2008, Google Inc.
3
Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
4
Copyright (c) 2008, Google Inc.
6
6
Portions of this file contain modifications contributed and copyrighted by
7
7
Google, Inc. Those modifications are gratefully acknowledged and are described
18
18
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
20
20
You should have received a copy of the GNU General Public License along with
21
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
22
St, Fifth Floor, Boston, MA 02110-1301 USA
21
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
22
Place, Suite 330, Boston, MA 02111-1307 USA
24
24
*****************************************************************************/
46
46
/** Flag: has the search system been enabled?
47
47
Protected by btr_search_latch and btr_search_enabled_mutex. */
48
UNIV_INTERN bool btr_search_enabled = TRUE;
49
UNIV_INTERN ibool btr_search_fully_disabled = FALSE;
48
UNIV_INTERN bool btr_search_enabled = TRUE;
51
50
/** Mutex protecting btr_search_enabled */
52
51
static mutex_t btr_search_enabled_mutex;
83
82
/** The adaptive hash index */
84
83
UNIV_INTERN btr_search_sys_t* btr_search_sys;
86
#ifdef UNIV_PFS_RWLOCK
87
/* Key to register btr_search_sys with performance schema */
88
UNIV_INTERN mysql_pfs_key_t btr_search_latch_key;
89
#endif /* UNIV_PFS_RWLOCK */
91
85
/** If the number of records on the page divided by this parameter
92
86
would have been successfully accessed using a hash index, the index
93
87
is then built on the page, assuming the global limit has been reached */
146
140
be enough free space in the hash table. */
148
142
if (heap->free_block == NULL) {
149
buf_block_t* block = buf_block_alloc(NULL, 0);
143
buf_block_t* block = buf_block_alloc(0);
151
145
rw_lock_x_lock(&btr_search_latch);
171
165
/* We allocate the search latch from dynamic memory:
172
166
see above at the global variable definition */
174
btr_search_latch_temp = static_cast<rw_lock_t *>(mem_alloc(sizeof(rw_lock_t)));
176
rw_lock_create(btr_search_latch_key, &btr_search_latch,
178
mutex_create(btr_search_enabled_mutex_key,
179
&btr_search_enabled_mutex, SYNC_SEARCH_SYS_CONF);
181
btr_search_sys = (btr_search_sys_t *)mem_alloc(sizeof(btr_search_sys_t));
168
btr_search_latch_temp = mem_alloc(sizeof(rw_lock_t));
170
rw_lock_create(&btr_search_latch, SYNC_SEARCH_SYS);
171
mutex_create(&btr_search_enabled_mutex, SYNC_SEARCH_SYS_CONF);
173
btr_search_sys = mem_alloc(sizeof(btr_search_sys_t));
183
175
btr_search_sys->hash_index = ha_create(hash_size, 0, 0);
186
/*****************************************************************//**
187
Frees the adaptive search system at a database shutdown. */
190
btr_search_sys_free(void)
191
/*=====================*/
193
rw_lock_free(&btr_search_latch);
194
mem_free(btr_search_latch_temp);
195
btr_search_latch_temp = NULL;
196
mem_heap_free(btr_search_sys->hash_index->heap);
197
hash_table_free(btr_search_sys->hash_index);
198
mem_free(btr_search_sys);
199
btr_search_sys = NULL;
202
178
/********************************************************************//**
203
179
Disable the adaptive hash search system and empty the index. */
209
185
mutex_enter(&btr_search_enabled_mutex);
210
186
rw_lock_x_lock(&btr_search_latch);
212
/* Disable access to hash index, also tell ha_insert_for_fold()
213
stop adding new nodes to hash index, but still allow updating
215
188
btr_search_enabled = FALSE;
217
190
/* Clear all block->is_hashed flags and remove all entries
218
191
from btr_search_sys->hash_index. */
219
192
buf_pool_drop_hash_index();
221
/* hash index has been cleaned up, disallow any operation to
223
btr_search_fully_disabled = TRUE;
225
194
/* btr_search_enabled_mutex should guarantee this. */
226
195
ut_ad(!btr_search_enabled);
240
209
rw_lock_x_lock(&btr_search_latch);
242
211
btr_search_enabled = TRUE;
243
btr_search_fully_disabled = FALSE;
245
213
rw_lock_x_unlock(&btr_search_latch);
246
214
mutex_exit(&btr_search_enabled_mutex);
444
412
/*==============================*/
445
413
btr_search_t* info, /*!< in: search info */
446
414
buf_block_t* block, /*!< in: buffer block */
447
btr_cur_t* /*cursor __attribute__((unused))*/)
415
btr_cur_t* cursor __attribute__((unused)))
448
416
/*!< in: cursor */
450
418
#ifdef UNIV_SYNC_DEBUG
639
607
inside the called function. It might be that the compiler
640
608
would optimize the call just to pass pointers to block. */
642
params = (ulint *)mem_alloc(3 * sizeof(ulint));
610
params = mem_alloc(3 * sizeof(ulint));
643
611
params[0] = block->n_fields;
644
612
params[1] = block->n_bytes;
645
613
params[2] = block->left_side;
881
848
ut_ad(rw_lock_get_writer(&btr_search_latch) != RW_LOCK_EX);
882
849
ut_ad(rw_lock_get_reader_count(&btr_search_latch) > 0);
884
rec = (rec_t *)ha_search_and_get_data(btr_search_sys->hash_index, fold);
851
rec = ha_search_and_get_data(btr_search_sys->hash_index, fold);
886
853
if (UNIV_UNLIKELY(!rec)) {
887
854
goto failure_unlock;
926
893
is positioned on. We cannot look at the next of the previous
927
894
record to determine if our guess for the cursor position is
929
if (UNIV_UNLIKELY(index_id != btr_page_get_index_id(block->frame))
897
(ut_dulint_cmp(index_id, btr_page_get_index_id(block->frame)), 0)
930
898
|| !btr_search_check_guess(cursor,
931
899
has_search_latch,
932
900
tuple, mode, mtr)) {
1307
1275
/* Calculate and cache fold values and corresponding records into
1308
1276
an array for fast insertion to the hash index */
1310
folds = (ulint *)mem_alloc(n_recs * sizeof(ulint));
1311
recs = (rec_t **)mem_alloc(n_recs * sizeof(rec_t*));
1278
folds = mem_alloc(n_recs * sizeof(ulint));
1279
recs = mem_alloc(n_recs * sizeof(rec_t*));
1535
1504
rw_lock_x_lock(&btr_search_latch);
1537
ha_search_and_delete_if_found(table, fold, rec);
1506
found = ha_search_and_delete_if_found(table, fold, rec);
1539
1508
rw_lock_x_unlock(&btr_search_latch);
1773
1741
/* We release btr_search_latch every once in a while to
1774
1742
give other queries a chance to run. */
1775
1743
if ((i != 0) && ((i % chunk_size) == 0)) {
1776
buf_pool_mutex_exit_all();
1744
buf_pool_mutex_exit();
1777
1745
rw_lock_x_unlock(&btr_search_latch);
1778
1746
os_thread_yield();
1779
1747
rw_lock_x_lock(&btr_search_latch);
1780
buf_pool_mutex_enter_all();
1748
buf_pool_mutex_enter();
1783
1751
node = hash_get_nth_cell(btr_search_sys->hash_index, i)->node;
1786
1754
const buf_block_t* block
1787
1755
= buf_block_align(node->data);
1788
1756
const buf_block_t* hash_block;
1789
buf_pool_t* buf_pool;
1790
index_id_t page_index_id;
1792
buf_pool = buf_pool_from_bpage((buf_page_t*) block);
1794
1758
if (UNIV_LIKELY(buf_block_get_state(block)
1795
1759
== BUF_BLOCK_FILE_PAGE)) {
1800
1764
(BUF_BLOCK_REMOVE_HASH, see the
1801
1765
assertion and the comment below) */
1802
1766
hash_block = buf_block_hash_get(
1804
1767
buf_block_get_space(block),
1805
1768
buf_block_get_page_no(block));
1832
1795
+ (block->curr_n_bytes > 0),
1835
page_index_id = btr_page_get_index_id(block->frame);
1838
(!block->is_hashed || node->fold
1839
!= rec_fold((rec_t*)(node->data),
1841
block->curr_n_fields,
1842
block->curr_n_bytes,
1798
if (!block->is_hashed || node->fold
1799
!= rec_fold((rec_t*)(node->data),
1801
block->curr_n_fields,
1802
block->curr_n_bytes,
1803
btr_page_get_index_id(block->frame))) {
1844
1804
const page_t* page = block->frame;
1850
1810
" InnoDB: Error in an adaptive hash"
1851
1811
" index pointer to page %lu\n"
1852
1812
"InnoDB: ptr mem address %p"
1813
" index id %lu %lu,"
1854
1814
" node fold %lu, rec fold %lu\n",
1855
1815
(ulong) page_get_page_no(page),
1857
(ullint) page_index_id,
1817
(ulong) ut_dulint_get_high(
1818
btr_page_get_index_id(page)),
1819
(ulong) ut_dulint_get_low(
1820
btr_page_get_index_id(page)),
1858
1821
(ulong) node->fold,
1859
1822
(ulong) rec_fold((rec_t*)(node->data),
1861
1824
block->curr_n_fields,
1862
1825
block->curr_n_bytes,
1826
btr_page_get_index_id(
1865
1829
fputs("InnoDB: Record ", stderr);
1866
1830
rec_print_new(stderr, (rec_t*)node->data,
1888
1852
/* We release btr_search_latch every once in a while to
1889
1853
give other queries a chance to run. */
1891
buf_pool_mutex_exit_all();
1855
buf_pool_mutex_exit();
1892
1856
rw_lock_x_unlock(&btr_search_latch);
1893
1857
os_thread_yield();
1894
1858
rw_lock_x_lock(&btr_search_latch);
1895
buf_pool_mutex_enter_all();
1859
buf_pool_mutex_enter();
1898
1862
if (!ha_validate(btr_search_sys->hash_index, i, end_index)) {