~ubuntu-branches/ubuntu/precise/mysql-5.5/precise-201203300109

« back to all changes in this revision

Viewing changes to storage/innobase/ibuf/ibuf0ibuf.c

  • Committer: Package Import Robot
  • Author(s): Clint Byrum
  • Date: 2012-02-14 23:59:22 UTC
  • mfrom: (1.1.2)
  • Revision ID: package-import@ubuntu.com-20120214235922-cux5uek1e5l0hje9
Tags: 5.5.20-0ubuntu1
* New upstream release.
* d/mysql-server-5.5.mysql.upstart: Fix stop on to make sure mysql is
  fully stopped before shutdown commences. (LP: #688541) Also simplify
  start on as it is redundant.
* d/control: Depend on upstart version which has apparmor profile load
  script to prevent failure on upgrade from lucid to precise.
  (LP: #907465)
* d/apparmor-profile: need to allow /run since that is the true path
  of /var/run files. (LP: #917542)
* d/control: mysql-server-5.5 has files in it that used to be owned
  by libmysqlclient-dev, so it must break/replace it. (LP: #912487)
* d/rules, d/control: 5.5.20 Fixes segfault on tests with gcc 4.6,
  change compiler back to system default.
* d/rules: Turn off embedded libedit/readline.(Closes: #659566)

Show diffs side-by-side

added added

removed removed

Lines of Context:
254
254
                                        list of the ibuf */
255
255
/* @} */
256
256
 
 
257
#define IBUF_REC_FIELD_SPACE    0       /*!< in the pre-4.1 format,
 
258
                                        the page number. later, the space_id */
 
259
#define IBUF_REC_FIELD_MARKER   1       /*!< starting with 4.1, a marker
 
260
                                        consisting of 1 byte that is 0 */
 
261
#define IBUF_REC_FIELD_PAGE     2       /*!< starting with 4.1, the
 
262
                                        page number */
 
263
#define IBUF_REC_FIELD_METADATA 3       /* the metadata field */
 
264
#define IBUF_REC_FIELD_USER     4       /* first user field */
 
265
 
257
266
/* Various constants for checking the type of an ibuf record and extracting
258
267
data from it. For details, see the description of the record format at the
259
268
top of this file. */
260
269
 
261
 
/** @name Format of the fourth column of an insert buffer record
 
270
/** @name Format of the IBUF_REC_FIELD_METADATA of an insert buffer record
262
271
The fourth column in the MySQL 5.5 format contains an operation
263
272
type, counter, and some flags. */
264
273
/* @{ */
1233
1242
        ut_ad(ibuf_inside(mtr));
1234
1243
        ut_ad(rec_get_n_fields_old(rec) > 2);
1235
1244
 
1236
 
        field = rec_get_nth_field_old(rec, 1, &len);
 
1245
        field = rec_get_nth_field_old(rec, IBUF_REC_FIELD_MARKER, &len);
1237
1246
 
1238
1247
        if (len == 1) {
1239
1248
                /* This is of the >= 4.1.x record format */
1240
1249
                ut_a(trx_sys_multiple_tablespace_format);
1241
1250
 
1242
 
                field = rec_get_nth_field_old(rec, 2, &len);
 
1251
                field = rec_get_nth_field_old(rec, IBUF_REC_FIELD_PAGE, &len);
1243
1252
        } else {
1244
1253
                ut_a(trx_doublewrite_must_reset_space_ids);
1245
1254
                ut_a(!trx_sys_multiple_tablespace_format);
1279
1288
        ut_ad(ibuf_inside(mtr));
1280
1289
        ut_ad(rec_get_n_fields_old(rec) > 2);
1281
1290
 
1282
 
        field = rec_get_nth_field_old(rec, 1, &len);
 
1291
        field = rec_get_nth_field_old(rec, IBUF_REC_FIELD_MARKER, &len);
1283
1292
 
1284
1293
        if (len == 1) {
1285
1294
                /* This is of the >= 4.1.x record format */
1286
1295
 
1287
1296
                ut_a(trx_sys_multiple_tablespace_format);
1288
 
                field = rec_get_nth_field_old(rec, 0, &len);
 
1297
                field = rec_get_nth_field_old(rec, IBUF_REC_FIELD_SPACE, &len);
1289
1298
                ut_a(len == 4);
1290
1299
 
1291
1300
                return(mach_read_from_4(field));
1335
1344
              || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX));
1336
1345
        ut_ad(ibuf_inside(mtr));
1337
1346
        fields = rec_get_n_fields_old(rec);
1338
 
        ut_a(fields > 4);
 
1347
        ut_a(fields > IBUF_REC_FIELD_USER);
1339
1348
 
1340
 
        types = rec_get_nth_field_old(rec, 3, &len);
 
1349
        types = rec_get_nth_field_old(rec, IBUF_REC_FIELD_METADATA, &len);
1341
1350
 
1342
1351
        info_len_local = len % DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE;
1343
1352
 
1363
1372
 
1364
1373
        ut_a(op_local < IBUF_OP_COUNT);
1365
1374
        ut_a((len - info_len_local) ==
1366
 
             (fields - 4) * DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE);
 
1375
             (fields - IBUF_REC_FIELD_USER)
 
1376
             * DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE);
1367
1377
 
1368
1378
        if (op) {
1369
1379
                *op = op_local;
1407
1417
        ut_ad(ibuf_inside(mtr));
1408
1418
        ut_ad(rec_get_n_fields_old(rec) > 2);
1409
1419
 
1410
 
        (void) rec_get_nth_field_old(rec, 1, &len);
 
1420
        (void) rec_get_nth_field_old(rec, IBUF_REC_FIELD_MARKER, &len);
1411
1421
 
1412
1422
        if (len > 1) {
1413
1423
                /* This is a < 4.1.x format record */
1436
1446
        const byte*     ptr;
1437
1447
        ulint           len;
1438
1448
 
1439
 
        if (rec_get_n_fields_old(rec) < 4) {
 
1449
        if (rec_get_n_fields_old(rec) <= IBUF_REC_FIELD_METADATA) {
1440
1450
 
1441
1451
                return(ULINT_UNDEFINED);
1442
1452
        }
1443
1453
 
1444
 
        ptr = rec_get_nth_field_old(rec, 3, &len);
 
1454
        ptr = rec_get_nth_field_old(rec, IBUF_REC_FIELD_METADATA, &len);
1445
1455
 
1446
1456
        if (len >= 2) {
1447
1457
 
1666
1676
              || mtr_memo_contains_page(mtr, ibuf_rec, MTR_MEMO_PAGE_S_FIX));
1667
1677
        ut_ad(ibuf_inside(mtr));
1668
1678
 
1669
 
        data = rec_get_nth_field_old(ibuf_rec, 1, &len);
 
1679
        data = rec_get_nth_field_old(ibuf_rec, IBUF_REC_FIELD_MARKER, &len);
1670
1680
 
1671
1681
        if (len > 1) {
1672
1682
                /* This a < 4.1.x format record */
1678
1688
 
1679
1689
        ut_a(trx_sys_multiple_tablespace_format);
1680
1690
        ut_a(*data == 0);
1681
 
        ut_a(rec_get_n_fields_old(ibuf_rec) > 4);
 
1691
        ut_a(rec_get_n_fields_old(ibuf_rec) > IBUF_REC_FIELD_USER);
1682
1692
 
1683
 
        n_fields = rec_get_n_fields_old(ibuf_rec) - 4;
 
1693
        n_fields = rec_get_n_fields_old(ibuf_rec) - IBUF_REC_FIELD_USER;
1684
1694
 
1685
1695
        tuple = dtuple_create(heap, n_fields);
1686
1696
 
1687
 
        types = rec_get_nth_field_old(ibuf_rec, 3, &len);
 
1697
        types = rec_get_nth_field_old(ibuf_rec, IBUF_REC_FIELD_METADATA, &len);
1688
1698
 
1689
1699
        ibuf_rec_get_info(mtr, ibuf_rec, NULL, &comp, &info_len, NULL);
1690
1700
 
1698
1708
        for (i = 0; i < n_fields; i++) {
1699
1709
                field = dtuple_get_nth_field(tuple, i);
1700
1710
 
1701
 
                data = rec_get_nth_field_old(ibuf_rec, i + 4, &len);
 
1711
                data = rec_get_nth_field_old(
 
1712
                        ibuf_rec, i + IBUF_REC_FIELD_USER, &len);
1702
1713
 
1703
1714
                dfield_set_data(field, data, len);
1704
1715
 
1745
1756
                field_offset = 2;
1746
1757
                types_offset = DATA_ORDER_NULL_TYPE_BUF_SIZE;
1747
1758
        } else {
1748
 
                field_offset = 4;
 
1759
                field_offset = IBUF_REC_FIELD_USER;
1749
1760
                types_offset = DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE;
1750
1761
        }
1751
1762
 
1806
1817
        ut_ad(ibuf_inside(mtr));
1807
1818
        ut_ad(rec_get_n_fields_old(ibuf_rec) > 2);
1808
1819
 
1809
 
        data = rec_get_nth_field_old(ibuf_rec, 1, &len);
 
1820
        data = rec_get_nth_field_old(ibuf_rec, IBUF_REC_FIELD_MARKER, &len);
1810
1821
        pre_4_1 = (len > 1);
1811
1822
 
1812
1823
        if (pre_4_1) {
1829
1840
                ut_a(trx_sys_multiple_tablespace_format);
1830
1841
                ut_a(*data == 0);
1831
1842
 
1832
 
                types = rec_get_nth_field_old(ibuf_rec, 3, &len);
 
1843
                types = rec_get_nth_field_old(
 
1844
                        ibuf_rec, IBUF_REC_FIELD_METADATA, &len);
1833
1845
 
1834
1846
                ibuf_rec_get_info(mtr, ibuf_rec, &op, &comp, &info_len, NULL);
1835
1847
 
1859
1871
                }
1860
1872
 
1861
1873
                types += info_len;
1862
 
                n_fields = rec_get_n_fields_old(ibuf_rec) - 4;
 
1874
                n_fields = rec_get_n_fields_old(ibuf_rec)
 
1875
                        - IBUF_REC_FIELD_USER;
1863
1876
        }
1864
1877
 
1865
1878
        data_size = ibuf_rec_get_size(ibuf_rec, types, n_fields, pre_4_1, comp);
1914
1927
 
1915
1928
        n_fields = dtuple_get_n_fields(entry);
1916
1929
 
1917
 
        tuple = dtuple_create(heap, n_fields + 4);
 
1930
        tuple = dtuple_create(heap, n_fields + IBUF_REC_FIELD_USER);
1918
1931
 
1919
1932
        /* 1) Space Id */
1920
1933
 
1921
 
        field = dtuple_get_nth_field(tuple, 0);
 
1934
        field = dtuple_get_nth_field(tuple, IBUF_REC_FIELD_SPACE);
1922
1935
 
1923
1936
        buf = mem_heap_alloc(heap, 4);
1924
1937
 
1928
1941
 
1929
1942
        /* 2) Marker byte */
1930
1943
 
1931
 
        field = dtuple_get_nth_field(tuple, 1);
 
1944
        field = dtuple_get_nth_field(tuple, IBUF_REC_FIELD_MARKER);
1932
1945
 
1933
1946
        buf = mem_heap_alloc(heap, 1);
1934
1947
 
1940
1953
 
1941
1954
        /* 3) Page number */
1942
1955
 
1943
 
        field = dtuple_get_nth_field(tuple, 2);
 
1956
        field = dtuple_get_nth_field(tuple, IBUF_REC_FIELD_PAGE);
1944
1957
 
1945
1958
        buf = mem_heap_alloc(heap, 4);
1946
1959
 
1988
2001
                ulint                   fixed_len;
1989
2002
                const dict_field_t*     ifield;
1990
2003
 
1991
 
                /* We add 4 below because we have the 4 extra fields at the
1992
 
                start of an ibuf record */
1993
 
 
1994
 
                field = dtuple_get_nth_field(tuple, i + 4);
 
2004
                field = dtuple_get_nth_field(tuple, i + IBUF_REC_FIELD_USER);
1995
2005
                entry_field = dtuple_get_nth_field(entry, i);
1996
2006
                dfield_copy(field, entry_field);
1997
2007
 
2024
2034
 
2025
2035
        /* 4) Type info, part #2 */
2026
2036
 
2027
 
        field = dtuple_get_nth_field(tuple, 3);
 
2037
        field = dtuple_get_nth_field(tuple, IBUF_REC_FIELD_METADATA);
2028
2038
 
2029
2039
        dfield_set_data(field, type_info, ti - type_info);
2030
2040
 
2031
2041
        /* Set all the types in the new tuple binary */
2032
2042
 
2033
 
        dtuple_set_types_binary(tuple, n_fields + 4);
 
2043
        dtuple_set_types_binary(tuple, n_fields + IBUF_REC_FIELD_USER);
2034
2044
 
2035
2045
        return(tuple);
2036
2046
}
2090
2100
 
2091
2101
        ut_a(trx_sys_multiple_tablespace_format);
2092
2102
 
2093
 
        tuple = dtuple_create(heap, 3);
 
2103
        tuple = dtuple_create(heap, IBUF_REC_FIELD_METADATA);
2094
2104
 
2095
2105
        /* Store the space id in tuple */
2096
2106
 
2097
 
        field = dtuple_get_nth_field(tuple, 0);
 
2107
        field = dtuple_get_nth_field(tuple, IBUF_REC_FIELD_SPACE);
2098
2108
 
2099
2109
        buf = mem_heap_alloc(heap, 4);
2100
2110
 
2104
2114
 
2105
2115
        /* Store the new format record marker byte */
2106
2116
 
2107
 
        field = dtuple_get_nth_field(tuple, 1);
 
2117
        field = dtuple_get_nth_field(tuple, IBUF_REC_FIELD_MARKER);
2108
2118
 
2109
2119
        buf = mem_heap_alloc(heap, 1);
2110
2120
 
2114
2124
 
2115
2125
        /* Store the page number in tuple */
2116
2126
 
2117
 
        field = dtuple_get_nth_field(tuple, 2);
 
2127
        field = dtuple_get_nth_field(tuple, IBUF_REC_FIELD_PAGE);
2118
2128
 
2119
2129
        buf = mem_heap_alloc(heap, 4);
2120
2130
 
2122
2132
 
2123
2133
        dfield_set_data(field, buf, 4);
2124
2134
 
2125
 
        dtuple_set_types_binary(tuple, 3);
 
2135
        dtuple_set_types_binary(tuple, IBUF_REC_FIELD_METADATA);
2126
2136
 
2127
2137
        return(tuple);
2128
2138
}
2789
2799
        ulint           fold;
2790
2800
        ulint           bitmask;
2791
2801
 
2792
 
        len = ibuf_rec_get_size(rec, types, rec_get_n_fields_old(rec) - 4,
2793
 
                                FALSE, comp);
 
2802
        len = ibuf_rec_get_size(
 
2803
                rec, types,
 
2804
                rec_get_n_fields_old(rec) - IBUF_REC_FIELD_USER,
 
2805
                FALSE, comp);
2794
2806
        fold = ut_fold_binary(data, len);
2795
2807
 
2796
2808
        hash += (fold / (CHAR_BIT * sizeof *hash)) % size;
2842
2854
        ut_ad(ibuf_inside(mtr));
2843
2855
 
2844
2856
        n_fields = rec_get_n_fields_old(rec);
2845
 
        ut_ad(n_fields > 4);
2846
 
        n_fields -= 4;
 
2857
        ut_ad(n_fields > IBUF_REC_FIELD_USER);
 
2858
        n_fields -= IBUF_REC_FIELD_USER;
2847
2859
 
2848
2860
        rec_get_nth_field_offs_old(rec, 1, &len);
2849
2861
        /* This function is only invoked when buffering new
2852
2864
        ut_a(len == 1);
2853
2865
        ut_ad(trx_sys_multiple_tablespace_format);
2854
2866
 
2855
 
        types = rec_get_nth_field_old(rec, 3, &len);
 
2867
        types = rec_get_nth_field_old(rec, IBUF_REC_FIELD_METADATA, &len);
2856
2868
 
2857
2869
        switch (UNIV_EXPECT(len % DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE,
2858
2870
                            IBUF_REC_INFO_SIZE)) {
3164
3176
        } else {
3165
3177
                rec = btr_pcur_get_rec(&pcur);
3166
3178
 
3167
 
                field = rec_get_nth_field_old(rec, 0, &len);
 
3179
                field = rec_get_nth_field_old(rec, IBUF_REC_FIELD_SPACE, &len);
3168
3180
 
3169
3181
                ut_a(len == 4);
3170
3182
 
3186
3198
        ibuf_get_entry_counter_low_func(rec,space,page_no)
3187
3199
#endif
3188
3200
/****************************************************************//**
3189
 
Helper function for ibuf_set_entry_counter. Checks if rec is for (space,
3190
 
page_no), and if so, reads counter value from it and returns that + 1.
3191
 
Otherwise, returns 0.
3192
 
@return new counter value, or 0 */
 
3201
Helper function for ibuf_get_entry_counter_func. Checks if rec is for
 
3202
(space, page_no), and if so, reads counter value from it and returns
 
3203
that + 1.
 
3204
@retval ULINT_UNDEFINED if the record does not contain any counter
 
3205
@retval 0 if the record is not for (space, page_no)
 
3206
@retval 1 + previous counter value, otherwise */
3193
3207
static
3194
3208
ulint
3195
3209
ibuf_get_entry_counter_low_func(
3210
3224
              || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX));
3211
3225
        ut_ad(rec_get_n_fields_old(rec) > 2);
3212
3226
 
3213
 
        field = rec_get_nth_field_old(rec, 1, &len);
 
3227
        field = rec_get_nth_field_old(rec, IBUF_REC_FIELD_MARKER, &len);
3214
3228
 
3215
3229
        if (UNIV_UNLIKELY(len != 1)) {
3216
3230
                /* pre-4.1 format */
3223
3237
        ut_a(trx_sys_multiple_tablespace_format);
3224
3238
 
3225
3239
        /* Check the tablespace identifier. */
3226
 
        field = rec_get_nth_field_old(rec, 0, &len);
 
3240
        field = rec_get_nth_field_old(rec, IBUF_REC_FIELD_SPACE, &len);
3227
3241
        ut_a(len == 4);
3228
3242
 
3229
3243
        if (mach_read_from_4(field) != space) {
3232
3246
        }
3233
3247
 
3234
3248
        /* Check the page offset. */
3235
 
        field = rec_get_nth_field_old(rec, 2, &len);
 
3249
        field = rec_get_nth_field_old(rec, IBUF_REC_FIELD_PAGE, &len);
3236
3250
        ut_a(len == 4);
3237
3251
 
3238
3252
        if (mach_read_from_4(field) != page_no) {
3241
3255
        }
3242
3256
 
3243
3257
        /* Check if the record contains a counter field. */
3244
 
        field = rec_get_nth_field_old(rec, 3, &len);
 
3258
        field = rec_get_nth_field_old(rec, IBUF_REC_FIELD_METADATA, &len);
3245
3259
 
3246
3260
        switch (len % DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE) {
3247
3261
        default:
3257
3271
        }
3258
3272
}
3259
3273
 
 
3274
#ifdef UNIV_DEBUG
 
3275
# define ibuf_get_entry_counter(space,page_no,rec,mtr,exact_leaf) \
 
3276
        ibuf_get_entry_counter_func(space,page_no,rec,mtr,exact_leaf)
 
3277
#else /* UNIV_DEBUG */
 
3278
# define ibuf_get_entry_counter(space,page_no,rec,mtr,exact_leaf) \
 
3279
        ibuf_get_entry_counter_func(space,page_no,rec,exact_leaf)
 
3280
#endif
 
3281
 
3260
3282
/****************************************************************//**
3261
 
Set the counter field in entry to the correct value based on the current
 
3283
Calculate the counter field for an entry based on the current
3262
3284
last record in ibuf for (space, page_no).
3263
 
@return FALSE if we should abort this insertion to ibuf */
 
3285
@return the counter field, or ULINT_UNDEFINED
 
3286
if we should abort this insertion to ibuf */
3264
3287
static
3265
 
ibool
3266
 
ibuf_set_entry_counter(
3267
 
/*===================*/
3268
 
        dtuple_t*       entry,          /*!< in/out: entry to patch */
 
3288
ulint
 
3289
ibuf_get_entry_counter_func(
 
3290
/*========================*/
3269
3291
        ulint           space,          /*!< in: space id of entry */
3270
3292
        ulint           page_no,        /*!< in: page number of entry */
3271
 
        btr_pcur_t*     pcur,           /*!< in: pcur positioned on the record
3272
 
                                        found by btr_pcur_open(.., entry,
3273
 
                                        PAGE_CUR_LE, ..., pcur, ...) */
3274
 
        ibool           is_optimistic,  /*!< in: is this an optimistic insert */
3275
 
        mtr_t*          mtr)            /*!< in: mtr */
 
3293
        const rec_t*    rec,            /*!< in: the record preceding the
 
3294
                                        insertion point */
 
3295
#ifdef UNIV_DEBUG
 
3296
        mtr_t*          mtr,            /*!< in: mini-transaction */
 
3297
#endif /* UNIV_DEBUG */
 
3298
        ibool           only_leaf)      /*!< in: TRUE if this is the only
 
3299
                                        leaf page that can contain entries
 
3300
                                        for (space,page_no), that is, there
 
3301
                                        was no exact match for (space,page_no)
 
3302
                                        in the node pointer */
3276
3303
{
3277
 
        dfield_t*       field;
3278
 
        byte*           data;
3279
 
        ulint           counter = 0;
3280
 
 
3281
 
        /* pcur points to either a user rec or to a page's infimum record. */
3282
3304
        ut_ad(ibuf_inside(mtr));
3283
 
        ut_ad(mtr_memo_contains(mtr, btr_pcur_get_block(pcur),
3284
 
                                MTR_MEMO_PAGE_X_FIX));
3285
 
        ut_ad(page_validate(btr_pcur_get_page(pcur), ibuf->index));
3286
 
 
3287
 
        if (btr_pcur_is_on_user_rec(pcur)) {
3288
 
 
3289
 
                counter = ibuf_get_entry_counter_low(
3290
 
                        mtr, btr_pcur_get_rec(pcur), space, page_no);
3291
 
 
3292
 
                if (UNIV_UNLIKELY(counter == ULINT_UNDEFINED)) {
3293
 
                        /* The record lacks a counter field.
3294
 
                        Such old records must be merged before
3295
 
                        new records can be buffered. */
3296
 
 
3297
 
                        return(FALSE);
3298
 
                }
3299
 
        } else if (btr_pcur_is_before_first_in_tree(pcur, mtr)) {
3300
 
                /* Ibuf tree is either completely empty, or the insert
3301
 
                position is at the very first record of a non-empty tree. In
3302
 
                either case we have no previous records for (space,
3303
 
                page_no). */
3304
 
 
3305
 
                counter = 0;
3306
 
        } else if (btr_pcur_is_before_first_on_page(pcur)) {
3307
 
                btr_cur_t*      cursor = btr_pcur_get_btr_cur(pcur);
3308
 
 
3309
 
                if (cursor->low_match < 3) {
3310
 
                        /* If low_match < 3, we know that the father node
3311
 
                        pointer did not contain the searched for (space,
3312
 
                        page_no), which means that the search ended on the
3313
 
                        right page regardless of the counter value, and
3314
 
                        since we're at the infimum record, there are no
3315
 
                        existing records. */
3316
 
 
3317
 
                        counter = 0;
3318
 
                } else {
3319
 
                        rec_t*          rec;
3320
 
                        const page_t*   page;
3321
 
                        buf_block_t*    block;
3322
 
                        page_t*         prev_page;
3323
 
                        ulint           prev_page_no;
3324
 
 
3325
 
                        ut_a(cursor->ibuf_cnt != ULINT_UNDEFINED);
3326
 
 
3327
 
                        page = btr_pcur_get_page(pcur);
3328
 
                        prev_page_no = btr_page_get_prev(page, mtr);
3329
 
 
3330
 
                        ut_a(prev_page_no != FIL_NULL);
3331
 
 
3332
 
                        block = buf_page_get(
3333
 
                                IBUF_SPACE_ID, 0, prev_page_no,
3334
 
                                RW_X_LATCH, mtr);
3335
 
 
3336
 
                        buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE);
3337
 
 
3338
 
                        prev_page = buf_block_get_frame(block);
3339
 
 
3340
 
                        rec = page_rec_get_prev(
3341
 
                                page_get_supremum_rec(prev_page));
3342
 
 
3343
 
                        ut_ad(page_rec_is_user_rec(rec));
3344
 
 
3345
 
                        counter = ibuf_get_entry_counter_low(
3346
 
                                mtr, rec, space, page_no);
3347
 
 
3348
 
                        if (UNIV_UNLIKELY(counter == ULINT_UNDEFINED)) {
3349
 
                                /* The record lacks a counter field.
3350
 
                                Such old records must be merged before
3351
 
                                new records can be buffered. */
3352
 
 
3353
 
                                return(FALSE);
3354
 
                        }
3355
 
 
3356
 
                        if (counter < cursor->ibuf_cnt) {
3357
 
                                /* Search ended on the wrong page. */
3358
 
 
3359
 
                                if (is_optimistic) {
3360
 
                                        /* In an optimistic insert, we can
3361
 
                                        shift the insert position to the left
3362
 
                                        page, since it only needs an X-latch
3363
 
                                        on the page itself, which the
3364
 
                                        original search acquired for us. */
3365
 
 
3366
 
                                        btr_cur_position(
3367
 
                                                ibuf->index, rec, block,
3368
 
                                                btr_pcur_get_btr_cur(pcur));
3369
 
                                } else {
3370
 
                                        /* We can't shift the insert
3371
 
                                        position to the left page in a
3372
 
                                        pessimistic insert since it would
3373
 
                                        require an X-latch on the left
3374
 
                                        page's left page, so we have to
3375
 
                                        abort. */
3376
 
 
3377
 
                                        return(FALSE);
3378
 
                                }
3379
 
                        } else {
3380
 
                                /* The counter field in the father node is
3381
 
                                the same as we would insert; we don't know
3382
 
                                whether the insert should go to this page or
3383
 
                                the left page (the later fields can differ),
3384
 
                                so refuse the insert. */
3385
 
 
3386
 
                                return(FALSE);
3387
 
                        }
3388
 
                }
 
3305
        ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX));
 
3306
        ut_ad(page_validate(page_align(rec), ibuf->index));
 
3307
 
 
3308
        if (page_rec_is_supremum(rec)) {
 
3309
                /* This is just for safety. The record should be a
 
3310
                page infimum or a user record. */
 
3311
                ut_ad(0);
 
3312
                return(ULINT_UNDEFINED);
 
3313
        } else if (!page_rec_is_infimum(rec)) {
 
3314
                return(ibuf_get_entry_counter_low(mtr, rec, space, page_no));
 
3315
        } else if (only_leaf
 
3316
                   || fil_page_get_prev(page_align(rec)) == FIL_NULL) {
 
3317
                /* The parent node pointer did not contain the
 
3318
                searched for (space, page_no), which means that the
 
3319
                search ended on the correct page regardless of the
 
3320
                counter value, and since we're at the infimum record,
 
3321
                there are no existing records. */
 
3322
                return(0);
3389
3323
        } else {
3390
 
                /* The cursor is not positioned at or before a user record. */
3391
 
                return(FALSE);
 
3324
                /* We used to read the previous page here. It would
 
3325
                break the latching order, because the caller has
 
3326
                buffer-fixed an insert buffer bitmap page. */
 
3327
                return(ULINT_UNDEFINED);
3392
3328
        }
3393
 
 
3394
 
        /* Patch counter value in already built entry. */
3395
 
        field = dtuple_get_nth_field(entry, 3);
3396
 
        data = dfield_get_data(field);
3397
 
 
3398
 
        mach_write_to_2(data + IBUF_REC_OFFSET_COUNTER, counter);
3399
 
 
3400
 
        return(TRUE);
3401
3329
}
3402
3330
 
3403
3331
/*********************************************************************//**
3604
3532
                }
3605
3533
        }
3606
3534
 
3607
 
        /* Patch correct counter value to the entry to insert. This can
3608
 
        change the insert position, which can result in the need to abort in
3609
 
        some cases. */
3610
 
        if (!no_counter
3611
 
            && !ibuf_set_entry_counter(ibuf_entry, space, page_no, &pcur,
3612
 
                                       mode == BTR_MODIFY_PREV, &mtr)) {
 
3535
        if (!no_counter) {
 
3536
                /* Patch correct counter value to the entry to
 
3537
                insert. This can change the insert position, which can
 
3538
                result in the need to abort in some cases. */
 
3539
                ulint           counter = ibuf_get_entry_counter(
 
3540
                        space, page_no, btr_pcur_get_rec(&pcur), &mtr,
 
3541
                        btr_pcur_get_btr_cur(&pcur)->low_match
 
3542
                        < IBUF_REC_FIELD_METADATA);
 
3543
                dfield_t*       field;
 
3544
 
 
3545
                if (counter == ULINT_UNDEFINED) {
3613
3546
bitmap_fail:
3614
 
                ibuf_mtr_commit(&bitmap_mtr);
 
3547
                        ibuf_mtr_commit(&bitmap_mtr);
 
3548
                        goto fail_exit;
 
3549
                }
3615
3550
 
3616
 
                goto fail_exit;
 
3551
                field = dtuple_get_nth_field(
 
3552
                        ibuf_entry, IBUF_REC_FIELD_METADATA);
 
3553
                mach_write_to_2(
 
3554
                        (byte*) dfield_get_data(field)
 
3555
                        + IBUF_REC_OFFSET_COUNTER, counter);
3617
3556
        }
3618
3557
 
3619
3558
        /* Set the bitmap bit denoting that the insert buffer contains
3955
3894
 
3956
3895
        ut_ad(ibuf_inside(mtr));
3957
3896
        ut_ad(dtuple_check_typed(entry));
3958
 
        ut_ad(!buf_block_align(page)->is_hashed);
 
3897
        ut_ad(!buf_block_align(page)->index);
3959
3898
 
3960
3899
        if (UNIV_UNLIKELY(dict_table_is_comp(index->table)
3961
3900
                          != (ibool)!!page_is_comp(page))) {