~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/btr/btr0sea.c

  • Committer: Brian Aker
  • Date: 2010-06-28 16:17:36 UTC
  • mfrom: (1637.4.1 drizzle)
  • Revision ID: brian@gaz-20100628161736-eormhb2mnd551i2h
Merge unused

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*****************************************************************************
2
2
 
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.
5
5
 
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.
19
19
 
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
23
23
 
24
24
*****************************************************************************/
25
25
 
45
45
 
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;
50
49
 
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;
85
84
 
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 */
90
 
 
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. */
147
141
 
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);
150
144
 
151
145
                rw_lock_x_lock(&btr_search_latch);
152
146
 
171
165
        /* We allocate the search latch from dynamic memory:
172
166
        see above at the global variable definition */
173
167
 
174
 
        btr_search_latch_temp = static_cast<rw_lock_t *>(mem_alloc(sizeof(rw_lock_t)));
175
 
 
176
 
        rw_lock_create(btr_search_latch_key, &btr_search_latch,
177
 
                       SYNC_SEARCH_SYS);
178
 
        mutex_create(btr_search_enabled_mutex_key,
179
 
                     &btr_search_enabled_mutex, SYNC_SEARCH_SYS_CONF);
180
 
 
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));
 
169
 
 
170
        rw_lock_create(&btr_search_latch, SYNC_SEARCH_SYS);
 
171
        mutex_create(&btr_search_enabled_mutex, SYNC_SEARCH_SYS_CONF);
 
172
 
 
173
        btr_search_sys = mem_alloc(sizeof(btr_search_sys_t));
182
174
 
183
175
        btr_search_sys->hash_index = ha_create(hash_size, 0, 0);
184
176
}
185
177
 
186
 
/*****************************************************************//**
187
 
Frees the adaptive search system at a database shutdown. */
188
 
UNIV_INTERN
189
 
void
190
 
btr_search_sys_free(void)
191
 
/*=====================*/
192
 
{
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;
200
 
}
201
 
 
202
178
/********************************************************************//**
203
179
Disable the adaptive hash search system and empty the index. */
204
180
UNIV_INTERN
209
185
        mutex_enter(&btr_search_enabled_mutex);
210
186
        rw_lock_x_lock(&btr_search_latch);
211
187
 
212
 
        /* Disable access to hash index, also tell ha_insert_for_fold()
213
 
        stop adding new nodes to hash index, but still allow updating
214
 
        existing nodes */
215
188
        btr_search_enabled = FALSE;
216
189
 
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();
220
193
 
221
 
        /* hash index has been cleaned up, disallow any operation to
222
 
        the hash index */
223
 
        btr_search_fully_disabled = TRUE;
224
 
 
225
194
        /* btr_search_enabled_mutex should guarantee this. */
226
195
        ut_ad(!btr_search_enabled);
227
196
 
240
209
        rw_lock_x_lock(&btr_search_latch);
241
210
 
242
211
        btr_search_enabled = TRUE;
243
 
        btr_search_fully_disabled = FALSE;
244
212
 
245
213
        rw_lock_x_unlock(&btr_search_latch);
246
214
        mutex_exit(&btr_search_enabled_mutex);
257
225
{
258
226
        btr_search_t*   info;
259
227
 
260
 
        info = (btr_search_t *)mem_heap_alloc(heap, sizeof(btr_search_t));
 
228
        info = mem_heap_alloc(heap, sizeof(btr_search_t));
261
229
 
262
230
#ifdef UNIV_DEBUG
263
231
        info->magic_n = BTR_SEARCH_MAGIC_N;
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 */
449
417
{
450
418
#ifdef UNIV_SYNC_DEBUG
527
495
        buf_block_t*    block,  /*!< in: buffer block where cursor positioned */
528
496
        btr_cur_t*      cursor) /*!< in: cursor */
529
497
{
530
 
        ulint           fold;
531
 
        rec_t*          rec;
532
 
        index_id_t      index_id;
 
498
        ulint   fold;
 
499
        rec_t*  rec;
 
500
        dulint  index_id;
533
501
 
534
502
        ut_ad(cursor->flag == BTR_CUR_HASH_FAIL);
535
503
#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. */
641
609
 
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;
830
798
                                        RW_S_LATCH, RW_X_LATCH, or 0 */
831
799
        mtr_t*          mtr)            /*!< in: mtr */
832
800
{
833
 
        buf_pool_t*     buf_pool;
834
801
        buf_block_t*    block;
835
802
        rec_t*          rec;
836
803
        ulint           fold;
837
 
        index_id_t      index_id;
 
804
        dulint          index_id;
838
805
#ifdef notdefined
839
806
        btr_cur_t       cursor2;
840
807
        btr_pcur_t      pcur;
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);
883
850
 
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);
885
852
 
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
928
895
        right. */
929
 
        if (UNIV_UNLIKELY(index_id != btr_page_get_index_id(block->frame))
 
896
        if (UNIV_EXPECT
 
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)) {
988
956
 
989
957
        /* Increment the page get statistics though we did not really
990
958
        fix the page: for user info only */
991
 
        buf_pool = buf_pool_from_bpage(&block->page);
992
 
        buf_pool->stat.n_page_gets++;
 
959
 
 
960
        buf_pool->n_page_gets++;
993
961
 
994
962
        return(TRUE);
995
963
 
1031
999
        const rec_t*            rec;
1032
1000
        ulint                   fold;
1033
1001
        ulint                   prev_fold;
1034
 
        index_id_t              index_id;
 
1002
        dulint                  index_id;
1035
1003
        ulint                   n_cached;
1036
1004
        ulint                   n_recs;
1037
1005
        ulint*                  folds;
1082
1050
        /* Calculate and cache fold values into an array for fast deletion
1083
1051
        from the hash index */
1084
1052
 
1085
 
        folds = (ulint *)mem_alloc(n_recs * sizeof(ulint));
 
1053
        folds = mem_alloc(n_recs * sizeof(ulint));
1086
1054
 
1087
1055
        n_cached = 0;
1088
1056
 
1091
1059
 
1092
1060
        index_id = btr_page_get_index_id(page);
1093
1061
 
1094
 
        ut_a(index_id == index->id);
 
1062
        ut_a(0 == ut_dulint_cmp(index_id, index->id));
1095
1063
 
1096
1064
        prev_fold = 0;
1097
1065
 
1248
1216
        rec_t*          next_rec;
1249
1217
        ulint           fold;
1250
1218
        ulint           next_fold;
1251
 
        index_id_t      index_id;
 
1219
        dulint          index_id;
1252
1220
        ulint           n_cached;
1253
1221
        ulint           n_recs;
1254
1222
        ulint*          folds;
1307
1275
        /* Calculate and cache fold values and corresponding records into
1308
1276
        an array for fast insertion to the hash index */
1309
1277
 
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*));
1312
1280
 
1313
1281
        n_cached = 0;
1314
1282
 
1379
1347
 
1380
1348
        rw_lock_x_lock(&btr_search_latch);
1381
1349
 
1382
 
        if (UNIV_UNLIKELY(btr_search_fully_disabled)) {
 
1350
        if (UNIV_UNLIKELY(!btr_search_enabled)) {
1383
1351
                goto exit_func;
1384
1352
        }
1385
1353
 
1501
1469
        buf_block_t*    block;
1502
1470
        rec_t*          rec;
1503
1471
        ulint           fold;
1504
 
        index_id_t      index_id;
 
1472
        dulint          index_id;
 
1473
        ibool           found;
1505
1474
        ulint           offsets_[REC_OFFS_NORMAL_SIZE];
1506
1475
        mem_heap_t*     heap            = NULL;
1507
1476
        rec_offs_init(offsets_);
1534
1503
        }
1535
1504
        rw_lock_x_lock(&btr_search_latch);
1536
1505
 
1537
 
        ha_search_and_delete_if_found(table, fold, rec);
 
1506
        found = ha_search_and_delete_if_found(table, fold, rec);
1538
1507
 
1539
1508
        rw_lock_x_unlock(&btr_search_latch);
1540
1509
}
1606
1575
        rec_t*          rec;
1607
1576
        rec_t*          ins_rec;
1608
1577
        rec_t*          next_rec;
1609
 
        index_id_t      index_id;
 
1578
        dulint          index_id;
1610
1579
        ulint           fold;
1611
1580
        ulint           ins_fold;
1612
1581
        ulint           next_fold = 0; /* remove warning (??? bug ???) */
1740
1709
        }
1741
1710
}
1742
1711
 
1743
 
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
1744
1712
/********************************************************************//**
1745
1713
Validates the search system.
1746
1714
@return TRUE if ok */
1765
1733
        rec_offs_init(offsets_);
1766
1734
 
1767
1735
        rw_lock_x_lock(&btr_search_latch);
1768
 
        buf_pool_mutex_enter_all();
 
1736
        buf_pool_mutex_enter();
1769
1737
 
1770
1738
        cell_count = hash_get_n_cells(btr_search_sys->hash_index);
1771
1739
 
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();
1781
1749
                }
1782
1750
 
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;
1791
 
 
1792
 
                        buf_pool = buf_pool_from_bpage((buf_page_t*) block);
1793
1757
 
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(
1803
 
                                        buf_pool,
1804
1767
                                        buf_block_get_space(block),
1805
1768
                                        buf_block_get_page_no(block));
1806
1769
                        } else {
1832
1795
                                                  + (block->curr_n_bytes > 0),
1833
1796
                                                  &heap);
1834
1797
 
1835
 
                        page_index_id = btr_page_get_index_id(block->frame);
1836
 
 
1837
 
                        if (UNIV_UNLIKELY
1838
 
                            (!block->is_hashed || node->fold
1839
 
                             != rec_fold((rec_t*)(node->data),
1840
 
                                         offsets,
1841
 
                                         block->curr_n_fields,
1842
 
                                         block->curr_n_bytes,
1843
 
                                         page_index_id))) {
 
1798
                        if (!block->is_hashed || node->fold
 
1799
                            != rec_fold((rec_t*)(node->data),
 
1800
                                        offsets,
 
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;
1845
1805
 
1846
1806
                                ok = FALSE;
1850
1810
                                        "  InnoDB: Error in an adaptive hash"
1851
1811
                                        " index pointer to page %lu\n"
1852
1812
                                        "InnoDB: ptr mem address %p"
1853
 
                                        " index id %llu,"
 
1813
                                        " index id %lu %lu,"
1854
1814
                                        " node fold %lu, rec fold %lu\n",
1855
1815
                                        (ulong) page_get_page_no(page),
1856
1816
                                        node->data,
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),
1860
1823
                                                         offsets,
1861
1824
                                                         block->curr_n_fields,
1862
1825
                                                         block->curr_n_bytes,
1863
 
                                                         page_index_id));
 
1826
                                                         btr_page_get_index_id(
 
1827
                                                                 page)));
1864
1828
 
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. */
1890
1854
                if (i != 0) {
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();
1896
1860
                }
1897
1861
 
1898
1862
                if (!ha_validate(btr_search_sys->hash_index, i, end_index)) {
1900
1864
                }
1901
1865
        }
1902
1866
 
1903
 
        buf_pool_mutex_exit_all();
 
1867
        buf_pool_mutex_exit();
1904
1868
        rw_lock_x_unlock(&btr_search_latch);
1905
1869
        if (UNIV_LIKELY_NULL(heap)) {
1906
1870
                mem_heap_free(heap);
1908
1872
 
1909
1873
        return(ok);
1910
1874
}
1911
 
#endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */