~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

Tags: innodb-plugin-1.0.3
InnoDB Plugin 1.0.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*****************************************************************************
 
2
 
 
3
Copyright (c) 1997, 2009, Innobase Oy. All Rights Reserved.
 
4
 
 
5
This program is free software; you can redistribute it and/or modify it under
 
6
the terms of the GNU General Public License as published by the Free Software
 
7
Foundation; version 2 of the License.
 
8
 
 
9
This program is distributed in the hope that it will be useful, but WITHOUT
 
10
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 
11
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
12
 
 
13
You should have received a copy of the GNU General Public License along with
 
14
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 
15
Place, Suite 330, Boston, MA 02111-1307 USA
 
16
 
 
17
*****************************************************************************/
 
18
 
1
19
/******************************************************
2
20
Insert buffer
3
21
 
4
 
(c) 1997 Innobase Oy
5
 
 
6
22
Created 7/19/1997 Heikki Tuuri
7
23
*******************************************************/
8
24
 
137
153
/* Buffer pool size per the maximum insert buffer size */
138
154
#define IBUF_POOL_SIZE_PER_MAX_SIZE     2
139
155
 
140
 
/* The insert buffer control structure */
 
156
/* Table name for the insert buffer. */
 
157
#define IBUF_TABLE_NAME         "SYS_IBUF_TABLE"
 
158
 
 
159
/** Operations that can currently be buffered. */
 
160
UNIV_INTERN ibuf_use_t  ibuf_use                = IBUF_USE_INSERT;
 
161
 
 
162
/** The insert buffer control structure */
141
163
UNIV_INTERN ibuf_t*     ibuf                    = NULL;
142
164
 
143
 
static ulint ibuf_rnd                           = 986058871;
144
 
 
145
165
UNIV_INTERN ulint       ibuf_flush_count        = 0;
146
166
 
147
167
#ifdef UNIV_IBUF_COUNT_DEBUG
148
168
/* Dimensions for the ibuf_count array */
149
 
#define IBUF_COUNT_N_SPACES     500
150
 
#define IBUF_COUNT_N_PAGES      2000
 
169
#define IBUF_COUNT_N_SPACES     4
 
170
#define IBUF_COUNT_N_PAGES      130000
151
171
 
152
172
/* Buffered entry counts for file pages, used in debugging */
153
173
static ulint    ibuf_counts[IBUF_COUNT_N_SPACES][IBUF_COUNT_N_PAGES];
230
250
still physically like the index page even if the index would have been
231
251
dropped! So, there seems to be no problem. */
232
252
 
233
 
#ifdef UNIV_DEBUG
234
 
/**********************************************************************
235
 
Validates the ibuf data structures when the caller owns ibuf_mutex. */
236
 
static
237
 
ibool
238
 
ibuf_validate_low(void);
239
 
/*===================*/
240
 
                        /* out: TRUE if ok */
241
 
#endif /* UNIV_DEBUG */
242
253
/**********************************************************************
243
254
Sets the flag in the current OS thread local storage denoting that it is
244
255
inside an insert buffer routine. */
293
304
ibuf_header_page_get(
294
305
/*=================*/
295
306
                        /* out: insert buffer header page */
296
 
        ulint   space,  /* in: space id */
297
307
        mtr_t*  mtr)    /* in: mtr */
298
308
{
299
309
        buf_block_t*    block;
300
310
 
301
 
        ut_a(space == 0);
302
 
 
303
311
        ut_ad(!ibuf_inside());
304
312
 
305
 
        block = buf_page_get(space, 0, FSP_IBUF_HEADER_PAGE_NO,
306
 
                             RW_X_LATCH, mtr);
 
313
        block = buf_page_get(
 
314
                IBUF_SPACE_ID, 0, FSP_IBUF_HEADER_PAGE_NO, RW_X_LATCH, mtr);
307
315
        buf_block_dbg_add_level(block, SYNC_IBUF_HEADER);
308
316
 
309
317
        return(buf_block_get_frame(block));
316
324
ibuf_tree_root_get(
317
325
/*===============*/
318
326
                                /* out: insert buffer tree root page */
319
 
        ibuf_data_t*    data,   /* in: ibuf data */
320
 
        ulint           space,  /* in: space id */
321
327
        mtr_t*          mtr)    /* in: mtr */
322
328
{
323
329
        buf_block_t*    block;
324
330
 
325
 
        ut_a(space == 0);
326
331
        ut_ad(ibuf_inside());
327
332
 
328
 
        mtr_x_lock(dict_index_get_lock(data->index), mtr);
329
 
 
330
 
        block = buf_page_get(space, 0, FSP_IBUF_TREE_ROOT_PAGE_NO, RW_X_LATCH,
331
 
                             mtr);
 
333
        mtr_x_lock(dict_index_get_lock(ibuf->index), mtr);
 
334
 
 
335
        block = buf_page_get(
 
336
                IBUF_SPACE_ID, 0, FSP_IBUF_TREE_ROOT_PAGE_NO, RW_X_LATCH, mtr);
 
337
 
332
338
        buf_block_dbg_add_level(block, SYNC_TREE_NODE);
333
339
 
334
340
        return(buf_block_get_frame(block));
369
375
#endif
370
376
 
371
377
/**********************************************************************
 
378
Updates the size information of the ibuf, assuming the segment size has not
 
379
changed. */
 
380
static
 
381
void
 
382
ibuf_size_update(
 
383
/*=============*/
 
384
        const page_t*   root,   /* in: ibuf tree root */
 
385
        mtr_t*          mtr)    /* in: mtr */
 
386
{
 
387
        ut_ad(mutex_own(&ibuf_mutex));
 
388
 
 
389
        ibuf->free_list_len = flst_get_len(root + PAGE_HEADER
 
390
                                           + PAGE_BTR_IBUF_FREE_LIST, mtr);
 
391
 
 
392
        ibuf->height = 1 + btr_page_get_level(root, mtr);
 
393
 
 
394
        /* the '1 +' is the ibuf header page */
 
395
        ibuf->size = ibuf->seg_size - (1 + ibuf->free_list_len);
 
396
 
 
397
        ibuf->empty = page_get_n_recs(root) == 0;
 
398
}
 
399
 
 
400
/**********************************************************************
372
401
Creates the insert buffer data structure at a database startup and initializes
373
402
the data structures for the insert buffer. */
374
403
UNIV_INTERN
376
405
ibuf_init_at_db_start(void)
377
406
/*=======================*/
378
407
{
 
408
        page_t*         root;
 
409
        mtr_t           mtr;
 
410
        dict_table_t*   table;
 
411
        mem_heap_t*     heap;
 
412
        dict_index_t*   index;
 
413
        ulint           n_used;
 
414
        page_t*         header_page;
 
415
        ulint           error;
 
416
 
379
417
        ibuf = mem_alloc(sizeof(ibuf_t));
380
418
 
 
419
        memset(ibuf, 0, sizeof(*ibuf));
 
420
 
381
421
        /* Note that also a pessimistic delete can sometimes make a B-tree
382
422
        grow in size, as the references on the upper levels of the tree can
383
423
        change */
385
425
        ibuf->max_size = buf_pool_get_curr_size() / UNIV_PAGE_SIZE
386
426
                / IBUF_POOL_SIZE_PER_MAX_SIZE;
387
427
 
388
 
        UT_LIST_INIT(ibuf->data_list);
389
 
 
390
 
        ibuf->size = 0;
391
 
 
392
428
        mutex_create(&ibuf_pessimistic_insert_mutex,
393
429
                     SYNC_IBUF_PESS_INSERT_MUTEX);
394
430
 
396
432
 
397
433
        mutex_create(&ibuf_bitmap_mutex, SYNC_IBUF_BITMAP_MUTEX);
398
434
 
399
 
        fil_ibuf_init_at_db_start();
400
 
}
401
 
 
402
 
/**********************************************************************
403
 
Updates the size information in an ibuf data, assuming the segment size has
404
 
not changed. */
405
 
static
406
 
void
407
 
ibuf_data_sizes_update(
408
 
/*===================*/
409
 
        ibuf_data_t*    data,   /* in: ibuf data struct */
410
 
        const page_t*   root,   /* in: ibuf tree root */
411
 
        mtr_t*          mtr)    /* in: mtr */
412
 
{
413
 
        ulint   old_size;
414
 
 
415
 
        ut_ad(mutex_own(&ibuf_mutex));
416
 
 
417
 
        old_size = data->size;
418
 
 
419
 
        data->free_list_len = flst_get_len(root + PAGE_HEADER
420
 
                                           + PAGE_BTR_IBUF_FREE_LIST, mtr);
421
 
 
422
 
        data->height = 1 + btr_page_get_level(root, mtr);
423
 
 
424
 
        data->size = data->seg_size - (1 + data->free_list_len);
425
 
        /* the '1 +' is the ibuf header page */
426
 
        ut_ad(data->size < data->seg_size);
427
 
 
428
 
        if (page_get_n_recs(root) == 0) {
429
 
 
430
 
                data->empty = TRUE;
431
 
        } else {
432
 
                data->empty = FALSE;
433
 
        }
434
 
 
435
 
        ut_ad(ibuf->size + data->size >= old_size);
436
 
 
437
 
        ibuf->size = ibuf->size + data->size - old_size;
438
 
 
439
 
#if 0
440
 
        fprintf(stderr, "ibuf size %lu, space ibuf size %lu\n",
441
 
                ibuf->size, data->size);
442
 
#endif
443
 
}
444
 
 
445
 
/**********************************************************************
446
 
Creates the insert buffer data struct for a single tablespace. Reads the
447
 
root page of the insert buffer tree in the tablespace. This function can
448
 
be called only after the dictionary system has been initialized, as this
449
 
creates also the insert buffer table and index into this tablespace. */
450
 
UNIV_INTERN
451
 
ibuf_data_t*
452
 
ibuf_data_init_for_space(
453
 
/*=====================*/
454
 
                        /* out, own: ibuf data struct, linked to the list
455
 
                        in ibuf control structure */
456
 
        ulint   space)  /* in: space id */
457
 
{
458
 
        ibuf_data_t*    data;
459
 
        page_t*         root;
460
 
        page_t*         header_page;
461
 
        mtr_t           mtr;
462
 
        char*           buf;
463
 
        mem_heap_t*     heap;
464
 
        dict_table_t*   table;
465
 
        dict_index_t*   index;
466
 
        ulint           n_used;
467
 
        ulint           error;
468
 
 
469
 
        ut_a(space == 0);
470
 
 
471
 
        data = mem_alloc(sizeof(ibuf_data_t));
472
 
 
473
 
        data->space = space;
474
 
 
475
435
        mtr_start(&mtr);
476
436
 
477
437
        mutex_enter(&ibuf_mutex);
478
438
 
479
 
        mtr_x_lock(fil_space_get_latch(space, NULL), &mtr);
 
439
        mtr_x_lock(fil_space_get_latch(IBUF_SPACE_ID, NULL), &mtr);
480
440
 
481
 
        header_page = ibuf_header_page_get(space, &mtr);
 
441
        header_page = ibuf_header_page_get(&mtr);
482
442
 
483
443
        fseg_n_reserved_pages(header_page + IBUF_HEADER + IBUF_TREE_SEG_HEADER,
484
444
                              &n_used, &mtr);
486
446
 
487
447
        ut_ad(n_used >= 2);
488
448
 
489
 
        data->seg_size = n_used;
 
449
        ibuf->seg_size = n_used;
490
450
 
491
451
        {
492
 
                buf_block_t*    block = buf_page_get(
493
 
                        space, 0, FSP_IBUF_TREE_ROOT_PAGE_NO,
 
452
                buf_block_t*    block;
 
453
 
 
454
                block = buf_page_get(
 
455
                        IBUF_SPACE_ID, 0, FSP_IBUF_TREE_ROOT_PAGE_NO,
494
456
                        RW_X_LATCH, &mtr);
495
457
                buf_block_dbg_add_level(block, SYNC_TREE_NODE);
496
458
 
497
459
                root = buf_block_get_frame(block);
498
460
        }
499
461
 
500
 
        data->size = 0;
501
 
        data->n_inserts = 0;
502
 
        data->n_merges = 0;
503
 
        data->n_merged_recs = 0;
504
 
 
505
 
        ibuf_data_sizes_update(data, root, &mtr);
506
 
        /*
507
 
        if (!data->empty) {
508
 
        fprintf(stderr,
509
 
        "InnoDB: index entries found in the insert buffer\n");
510
 
        } else {
511
 
        fprintf(stderr,
512
 
        "InnoDB: insert buffer empty\n");
513
 
        }
514
 
        */
 
462
        ibuf_size_update(root, &mtr);
515
463
        mutex_exit(&ibuf_mutex);
516
464
 
517
465
        mtr_commit(&mtr);
519
467
        ibuf_exit();
520
468
 
521
469
        heap = mem_heap_create(450);
522
 
        buf = mem_heap_alloc(heap, 50);
523
 
 
524
 
        sprintf(buf, "SYS_IBUF_TABLE_%lu", (ulong) space);
525
 
        /* use old-style record format for the insert buffer */
526
 
        table = dict_mem_table_create(buf, space, 2, 0);
527
 
 
528
 
        dict_mem_table_add_col(table, heap, "PAGE_NO", DATA_BINARY, 0, 0);
529
 
        dict_mem_table_add_col(table, heap, "TYPES", DATA_BINARY, 0, 0);
530
 
 
531
 
        table->id = ut_dulint_add(DICT_IBUF_ID_MIN, space);
 
470
 
 
471
        /* Use old-style record format for the insert buffer. */
 
472
        table = dict_mem_table_create(IBUF_TABLE_NAME, IBUF_SPACE_ID, 1, 0);
 
473
 
 
474
        dict_mem_table_add_col(table, heap, "DUMMY_COLUMN", DATA_BINARY, 0, 0);
 
475
 
 
476
        table->id = ut_dulint_add(DICT_IBUF_ID_MIN, IBUF_SPACE_ID);
532
477
 
533
478
        dict_table_add_to_cache(table, heap);
534
479
        mem_heap_free(heap);
535
480
 
536
481
        index = dict_mem_index_create(
537
 
                buf, "CLUST_IND", space,
538
 
                DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF, 2);
539
 
 
540
 
        dict_mem_index_add_field(index, "PAGE_NO", 0);
541
 
        dict_mem_index_add_field(index, "TYPES", 0);
542
 
 
543
 
        index->id = ut_dulint_add(DICT_IBUF_ID_MIN, space);
 
482
                IBUF_TABLE_NAME, "CLUST_IND",
 
483
                IBUF_SPACE_ID, DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF, 1);
 
484
 
 
485
        dict_mem_index_add_field(index, "DUMMY_COLUMN", 0);
 
486
 
 
487
        index->id = ut_dulint_add(DICT_IBUF_ID_MIN, IBUF_SPACE_ID);
544
488
 
545
489
        error = dict_index_add_to_cache(table, index,
546
490
                                        FSP_IBUF_TREE_ROOT_PAGE_NO, FALSE);
547
491
        ut_a(error == DB_SUCCESS);
548
492
 
549
 
        data->index = dict_table_get_first_index(table);
550
 
 
551
 
        mutex_enter(&ibuf_mutex);
552
 
 
553
 
        UT_LIST_ADD_LAST(data_list, ibuf->data_list, data);
554
 
 
555
 
        mutex_exit(&ibuf_mutex);
556
 
 
557
 
        return(data);
 
493
        ibuf->index = dict_table_get_first_index(table);
558
494
}
559
495
 
560
496
/*************************************************************************
1040
976
                        0 for uncompressed pages */
1041
977
        ulint   page_no)/* in: page number */
1042
978
{
1043
 
        return((space == 0 && page_no == IBUF_TREE_ROOT_PAGE_NO)
 
979
        return((space == IBUF_SPACE_ID && page_no == IBUF_TREE_ROOT_PAGE_NO)
1044
980
               || ibuf_bitmap_page(zip_size, page_no));
1045
981
}
1046
982
 
1047
983
/***************************************************************************
1048
 
Checks if a page is a level 2 or 3 page in the ibuf hierarchy of pages. */
 
984
Checks if a page is a level 2 or 3 page in the ibuf hierarchy of pages.
 
985
Must not be called when recv_no_ibuf_operations==TRUE. */
1049
986
UNIV_INTERN
1050
987
ibool
1051
988
ibuf_page(
1053
990
                        /* out: TRUE if level 2 or level 3 page */
1054
991
        ulint   space,  /* in: space id */
1055
992
        ulint   zip_size,/* in: compressed page size in bytes, or 0 */
1056
 
        ulint   page_no)/* in: page number */
 
993
        ulint   page_no,/* in: page number */
 
994
        mtr_t*  mtr)    /* in: mtr which will contain an x-latch to the
 
995
                        bitmap page if the page is not one of the fixed
 
996
                        address ibuf pages, or NULL, in which case a new
 
997
                        transaction is created. */
1057
998
{
1058
 
        page_t* bitmap_page;
1059
 
        mtr_t   mtr;
1060
999
        ibool   ret;
1061
 
 
1062
 
        if (recv_no_ibuf_operations) {
1063
 
                /* Recovery is running: no ibuf operations should be
1064
 
                performed */
1065
 
 
1066
 
                return(FALSE);
1067
 
        }
 
1000
        mtr_t   local_mtr;
 
1001
        page_t* bitmap_page;
 
1002
 
 
1003
        ut_ad(!recv_no_ibuf_operations);
1068
1004
 
1069
1005
        if (ibuf_fixed_addr_page(space, zip_size, page_no)) {
1070
1006
 
1071
1007
                return(TRUE);
1072
 
        }
1073
 
 
1074
 
        if (space != 0) {
1075
 
                /* Currently we only have an ibuf tree in space 0 */
 
1008
        } else if (space != IBUF_SPACE_ID) {
1076
1009
 
1077
1010
                return(FALSE);
1078
1011
        }
1079
1012
 
1080
 
        ut_ad(fil_space_get_type(space) == FIL_TABLESPACE);
1081
 
 
1082
 
        mtr_start(&mtr);
1083
 
 
1084
 
        bitmap_page = ibuf_bitmap_get_map_page(space, page_no, zip_size, &mtr);
 
1013
        ut_ad(fil_space_get_type(IBUF_SPACE_ID) == FIL_TABLESPACE);
 
1014
 
 
1015
        if (mtr == NULL) {
 
1016
                mtr = &local_mtr;
 
1017
                mtr_start(mtr);
 
1018
        }
 
1019
 
 
1020
        bitmap_page = ibuf_bitmap_get_map_page(space, page_no, zip_size, mtr);
1085
1021
 
1086
1022
        ret = ibuf_bitmap_page_get_bits(bitmap_page, page_no, zip_size,
1087
 
                                        IBUF_BITMAP_IBUF, &mtr);
1088
 
        mtr_commit(&mtr);
 
1023
                                        IBUF_BITMAP_IBUF, mtr);
 
1024
 
 
1025
        if (mtr == &local_mtr) {
 
1026
                mtr_commit(mtr);
 
1027
        }
1089
1028
 
1090
1029
        return(ret);
1091
1030
}
1092
1031
 
1093
 
/***************************************************************************
1094
 
Checks if a page is a level 2 or 3 page in the ibuf hierarchy of pages. */
1095
 
UNIV_INTERN
1096
 
ibool
1097
 
ibuf_page_low(
1098
 
/*==========*/
1099
 
                        /* out: TRUE if level 2 or level 3 page */
1100
 
        ulint   space,  /* in: space id */
1101
 
        ulint   zip_size,/* in: compressed page size in bytes, or 0 */
1102
 
        ulint   page_no,/* in: page number */
1103
 
        mtr_t*  mtr)    /* in: mtr which will contain an x-latch to the
1104
 
                        bitmap page if the page is not one of the fixed
1105
 
                        address ibuf pages */
1106
 
{
1107
 
        page_t* bitmap_page;
1108
 
 
1109
 
        if (ibuf_fixed_addr_page(space, zip_size, page_no)) {
1110
 
 
1111
 
                return(TRUE);
1112
 
        }
1113
 
 
1114
 
        bitmap_page = ibuf_bitmap_get_map_page(space, page_no, zip_size, mtr);
1115
 
 
1116
 
        return(ibuf_bitmap_page_get_bits(bitmap_page, page_no, zip_size,
1117
 
                                         IBUF_BITMAP_IBUF, mtr));
1118
 
}
1119
 
 
1120
1032
/************************************************************************
1121
1033
Returns the page number field of an ibuf record. */
1122
1034
static
1249
1161
/*************************************************************************
1250
1162
Builds the entry to insert into a non-clustered index when we have the
1251
1163
corresponding record in an ibuf index. */
 
1164
UNIV_INLINE
 
1165
dtuple_t*
 
1166
ibuf_build_entry_pre_4_1_x(
 
1167
/*=======================*/
 
1168
                                        /* out, own: entry to insert to
 
1169
                                        a non-clustered index; NOTE that
 
1170
                                        as we copy pointers to fields in
 
1171
                                        ibuf_rec, the caller must hold a
 
1172
                                        latch to the ibuf_rec page as long
 
1173
                                        as the entry is used! */
 
1174
        const rec_t*    ibuf_rec,       /* in: record in an insert buffer */
 
1175
        mem_heap_t*     heap,           /* in: heap where built */
 
1176
        dict_index_t**  pindex)         /* out, own: dummy index that
 
1177
                                        describes the entry */
 
1178
{
 
1179
        ulint           i;
 
1180
        ulint           len;
 
1181
        const byte*     types;
 
1182
        dtuple_t*       tuple;
 
1183
        ulint           n_fields;
 
1184
 
 
1185
        ut_a(trx_doublewrite_must_reset_space_ids);
 
1186
        ut_a(!trx_sys_multiple_tablespace_format);
 
1187
 
 
1188
        n_fields = rec_get_n_fields_old(ibuf_rec) - 2;
 
1189
        tuple = dtuple_create(heap, n_fields);
 
1190
        types = rec_get_nth_field_old(ibuf_rec, 1, &len);
 
1191
 
 
1192
        ut_a(len == n_fields * DATA_ORDER_NULL_TYPE_BUF_SIZE);
 
1193
 
 
1194
        for (i = 0; i < n_fields; i++) {
 
1195
                const byte*     data;
 
1196
                dfield_t*       field;
 
1197
 
 
1198
                field = dtuple_get_nth_field(tuple, i);
 
1199
 
 
1200
                data = rec_get_nth_field_old(ibuf_rec, i + 2, &len);
 
1201
 
 
1202
                dfield_set_data(field, data, len);
 
1203
 
 
1204
                dtype_read_for_order_and_null_size(
 
1205
                        dfield_get_type(field),
 
1206
                        types + i * DATA_ORDER_NULL_TYPE_BUF_SIZE);
 
1207
        }
 
1208
 
 
1209
        *pindex = ibuf_dummy_index_create(n_fields, FALSE);
 
1210
 
 
1211
        return(tuple);
 
1212
}
 
1213
 
 
1214
/*************************************************************************
 
1215
Builds the entry to insert into a non-clustered index when we have the
 
1216
corresponding record in an ibuf index. */
1252
1217
static
1253
1218
dtuple_t*
1254
1219
ibuf_build_entry_from_ibuf_rec(
1278
1243
        if (len > 1) {
1279
1244
                /* This a < 4.1.x format record */
1280
1245
 
1281
 
                ut_a(trx_doublewrite_must_reset_space_ids);
1282
 
                ut_a(!trx_sys_multiple_tablespace_format);
1283
 
 
1284
 
                n_fields = rec_get_n_fields_old(ibuf_rec) - 2;
1285
 
                tuple = dtuple_create(heap, n_fields);
1286
 
                types = rec_get_nth_field_old(ibuf_rec, 1, &len);
1287
 
 
1288
 
                ut_a(len == n_fields * DATA_ORDER_NULL_TYPE_BUF_SIZE);
1289
 
 
1290
 
                for (i = 0; i < n_fields; i++) {
1291
 
                        field = dtuple_get_nth_field(tuple, i);
1292
 
 
1293
 
                        data = rec_get_nth_field_old(ibuf_rec, i + 2, &len);
1294
 
 
1295
 
                        dfield_set_data(field, data, len);
1296
 
 
1297
 
                        dtype_read_for_order_and_null_size(
1298
 
                                dfield_get_type(field),
1299
 
                                types + i * DATA_ORDER_NULL_TYPE_BUF_SIZE);
1300
 
                }
1301
 
 
1302
 
                *pindex = ibuf_dummy_index_create(n_fields, FALSE);
1303
 
                return(tuple);
 
1246
                return(ibuf_build_entry_pre_4_1_x(ibuf_rec, heap, pindex));
1304
1247
        }
1305
1248
 
1306
1249
        /* This a >= 4.1.x format record */
1350
1293
        ut_d(dict_table_add_system_columns(index->table, index->table->heap));
1351
1294
 
1352
1295
        *pindex = index;
 
1296
 
1353
1297
        return(tuple);
1354
1298
}
1355
1299
 
1680
1624
dare to start a pessimistic insert to the insert buffer. */
1681
1625
UNIV_INLINE
1682
1626
ibool
1683
 
ibuf_data_enough_free_for_insert(
1684
 
/*=============================*/
 
1627
ibuf_data_enough_free_for_insert(void)
 
1628
/*==================================*/
1685
1629
                                /* out: TRUE if enough free pages in list */
1686
 
        ibuf_data_t*    data)   /* in: ibuf data for the space */
1687
1630
{
1688
1631
        ut_ad(mutex_own(&ibuf_mutex));
1689
1632
 
1693
1636
        inserts buffered for pages that we read to the buffer pool, without
1694
1637
        any risk of running out of free space in the insert buffer. */
1695
1638
 
1696
 
        return(data->free_list_len >= data->size / 2 + 3 * data->height);
 
1639
        return(ibuf->free_list_len >= (ibuf->size / 2) + 3 * ibuf->height);
1697
1640
}
1698
1641
 
1699
1642
/*************************************************************************
1701
1644
should remove them and free to the file space management. */
1702
1645
UNIV_INLINE
1703
1646
ibool
1704
 
ibuf_data_too_much_free(
1705
 
/*====================*/
 
1647
ibuf_data_too_much_free(void)
 
1648
/*=========================*/
1706
1649
                                /* out: TRUE if enough free pages in list */
1707
 
        ibuf_data_t*    data)   /* in: ibuf data for the space */
1708
1650
{
1709
1651
        ut_ad(mutex_own(&ibuf_mutex));
1710
1652
 
1711
 
        return(data->free_list_len >= 3 + data->size / 2 + 3 * data->height);
 
1653
        return(ibuf->free_list_len >= 3 + (ibuf->size / 2) + 3 * ibuf->height);
1712
1654
}
1713
1655
 
1714
1656
/*************************************************************************
1716
1658
list. */
1717
1659
static
1718
1660
ulint
1719
 
ibuf_add_free_page(
1720
 
/*===============*/
 
1661
ibuf_add_free_page(void)
 
1662
/*====================*/
1721
1663
                                        /* out: DB_SUCCESS, or DB_STRONG_FAIL
1722
1664
                                        if no space left */
1723
 
        ulint           space,          /* in: space id */
1724
 
        ibuf_data_t*    ibuf_data)      /* in: ibuf data for the space */
1725
1665
{
1726
1666
        mtr_t   mtr;
1727
1667
        page_t* header_page;
1732
1672
        page_t* root;
1733
1673
        page_t* bitmap_page;
1734
1674
 
1735
 
        ut_a(space == 0);
1736
 
 
1737
1675
        mtr_start(&mtr);
1738
1676
 
1739
1677
        /* Acquire the fsp latch before the ibuf header, obeying the latching
1740
1678
        order */
1741
 
        mtr_x_lock(fil_space_get_latch(space, &flags), &mtr);
 
1679
        mtr_x_lock(fil_space_get_latch(IBUF_SPACE_ID, &flags), &mtr);
1742
1680
        zip_size = dict_table_flags_to_zip_size(flags);
1743
1681
 
1744
 
        header_page = ibuf_header_page_get(space, &mtr);
 
1682
        header_page = ibuf_header_page_get(&mtr);
1745
1683
 
1746
1684
        /* Allocate a new page: NOTE that if the page has been a part of a
1747
1685
        non-clustered index which has subsequently been dropped, then the
1753
1691
        of a deadlock. This is the reason why we created a special ibuf
1754
1692
        header page apart from the ibuf tree. */
1755
1693
 
1756
 
        page_no = fseg_alloc_free_page(header_page + IBUF_HEADER
1757
 
                                       + IBUF_TREE_SEG_HEADER, 0, FSP_UP,
1758
 
                                       &mtr);
 
1694
        page_no = fseg_alloc_free_page(
 
1695
                header_page + IBUF_HEADER + IBUF_TREE_SEG_HEADER, 0, FSP_UP,
 
1696
                &mtr);
 
1697
 
1759
1698
        if (page_no == FIL_NULL) {
1760
1699
                mtr_commit(&mtr);
1761
1700
 
1763
1702
        }
1764
1703
 
1765
1704
        {
1766
 
                buf_block_t*    block = buf_page_get(
1767
 
                        space, 0, page_no, RW_X_LATCH, &mtr);
 
1705
                buf_block_t*    block;
 
1706
 
 
1707
                block = buf_page_get(
 
1708
                        IBUF_SPACE_ID, 0, page_no, RW_X_LATCH, &mtr);
 
1709
 
1768
1710
                buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW);
1769
1711
 
 
1712
 
1770
1713
                page = buf_block_get_frame(block);
1771
1714
        }
1772
1715
 
1774
1717
 
1775
1718
        mutex_enter(&ibuf_mutex);
1776
1719
 
1777
 
        root = ibuf_tree_root_get(ibuf_data, space, &mtr);
 
1720
        root = ibuf_tree_root_get(&mtr);
1778
1721
 
1779
1722
        /* Add the page to the free list and update the ibuf size data */
1780
1723
 
1784
1727
        mlog_write_ulint(page + FIL_PAGE_TYPE, FIL_PAGE_IBUF_FREE_LIST,
1785
1728
                         MLOG_2BYTES, &mtr);
1786
1729
 
1787
 
        ibuf_data->seg_size++;
1788
 
        ibuf_data->free_list_len++;
 
1730
        ibuf->seg_size++;
 
1731
        ibuf->free_list_len++;
1789
1732
 
1790
1733
        /* Set the bit indicating that this page is now an ibuf tree page
1791
1734
        (level 2 page) */
1792
1735
 
1793
 
        bitmap_page = ibuf_bitmap_get_map_page(space, page_no, zip_size, &mtr);
1794
 
 
1795
 
        ibuf_bitmap_page_set_bits(bitmap_page, page_no, zip_size,
1796
 
                                  IBUF_BITMAP_IBUF, TRUE, &mtr);
 
1736
        bitmap_page = ibuf_bitmap_get_map_page(
 
1737
                IBUF_SPACE_ID, page_no, zip_size, &mtr);
 
1738
 
 
1739
        ibuf_bitmap_page_set_bits(
 
1740
                bitmap_page, page_no, zip_size, IBUF_BITMAP_IBUF, TRUE, &mtr);
 
1741
 
1797
1742
        mtr_commit(&mtr);
1798
1743
 
1799
1744
        mutex_exit(&ibuf_mutex);
1807
1752
Removes a page from the free list and frees it to the fsp system. */
1808
1753
static
1809
1754
void
1810
 
ibuf_remove_free_page(
1811
 
/*==================*/
1812
 
        ulint           space,          /* in: space id */
1813
 
        ibuf_data_t*    ibuf_data)      /* in: ibuf data for the space */
 
1755
ibuf_remove_free_page(void)
 
1756
/*=======================*/
1814
1757
{
1815
1758
        mtr_t   mtr;
1816
1759
        mtr_t   mtr2;
1822
1765
        page_t* root;
1823
1766
        page_t* bitmap_page;
1824
1767
 
1825
 
        ut_a(space == 0);
1826
 
 
1827
1768
        mtr_start(&mtr);
1828
1769
 
1829
1770
        /* Acquire the fsp latch before the ibuf header, obeying the latching
1830
1771
        order */
1831
 
        mtr_x_lock(fil_space_get_latch(space, &flags), &mtr);
 
1772
        mtr_x_lock(fil_space_get_latch(IBUF_SPACE_ID, &flags), &mtr);
1832
1773
        zip_size = dict_table_flags_to_zip_size(flags);
1833
1774
 
1834
 
        header_page = ibuf_header_page_get(space, &mtr);
 
1775
        header_page = ibuf_header_page_get(&mtr);
1835
1776
 
1836
1777
        /* Prevent pessimistic inserts to insert buffer trees for a while */
1837
1778
        mutex_enter(&ibuf_pessimistic_insert_mutex);
1840
1781
 
1841
1782
        mutex_enter(&ibuf_mutex);
1842
1783
 
1843
 
        if (!ibuf_data_too_much_free(ibuf_data)) {
 
1784
        if (!ibuf_data_too_much_free()) {
1844
1785
 
1845
1786
                mutex_exit(&ibuf_mutex);
1846
1787
 
1855
1796
 
1856
1797
        mtr_start(&mtr2);
1857
1798
 
1858
 
        root = ibuf_tree_root_get(ibuf_data, space, &mtr2);
 
1799
        root = ibuf_tree_root_get(&mtr2);
1859
1800
 
1860
1801
        page_no = flst_get_last(root + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST,
1861
 
                                &mtr2)
1862
 
                .page;
 
1802
                                &mtr2).page;
1863
1803
 
1864
1804
        /* NOTE that we must release the latch on the ibuf tree root
1865
1805
        because in fseg_free_page we access level 1 pages, and the root
1877
1817
        page from it. */
1878
1818
 
1879
1819
        fseg_free_page(header_page + IBUF_HEADER + IBUF_TREE_SEG_HEADER,
1880
 
                       space, page_no, &mtr);
 
1820
                       IBUF_SPACE_ID, page_no, &mtr);
 
1821
 
1881
1822
#ifdef UNIV_DEBUG_FILE_ACCESSES
1882
 
        buf_page_reset_file_page_was_freed(space, page_no);
 
1823
        buf_page_reset_file_page_was_freed(IBUF_SPACE_ID, page_no);
1883
1824
#endif
 
1825
 
1884
1826
        ibuf_enter();
1885
1827
 
1886
1828
        mutex_enter(&ibuf_mutex);
1887
1829
 
1888
 
        root = ibuf_tree_root_get(ibuf_data, space, &mtr);
 
1830
        root = ibuf_tree_root_get(&mtr);
1889
1831
 
1890
1832
        ut_ad(page_no == flst_get_last(root + PAGE_HEADER
1891
 
                                       + PAGE_BTR_IBUF_FREE_LIST, &mtr)
1892
 
              .page);
 
1833
                                       + PAGE_BTR_IBUF_FREE_LIST, &mtr).page);
1893
1834
 
1894
1835
        {
1895
 
                buf_block_t*    block = buf_page_get(
1896
 
                        space, 0, page_no, RW_X_LATCH, &mtr);
 
1836
                buf_block_t*    block;
 
1837
 
 
1838
                block = buf_page_get(
 
1839
                        IBUF_SPACE_ID, 0, page_no, RW_X_LATCH, &mtr);
 
1840
 
1897
1841
                buf_block_dbg_add_level(block, SYNC_TREE_NODE);
1898
1842
 
 
1843
 
1899
1844
                page = buf_block_get_frame(block);
1900
1845
        }
1901
1846
 
1904
1849
        flst_remove(root + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST,
1905
1850
                    page + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST_NODE, &mtr);
1906
1851
 
1907
 
        ibuf_data->seg_size--;
1908
 
        ibuf_data->free_list_len--;
 
1852
        ibuf->seg_size--;
 
1853
        ibuf->free_list_len--;
1909
1854
 
1910
1855
        mutex_exit(&ibuf_pessimistic_insert_mutex);
1911
1856
 
1912
1857
        /* Set the bit indicating that this page is no more an ibuf tree page
1913
1858
        (level 2 page) */
1914
1859
 
1915
 
        bitmap_page = ibuf_bitmap_get_map_page(space, page_no, zip_size, &mtr);
1916
 
 
1917
 
        ibuf_bitmap_page_set_bits(bitmap_page, page_no, zip_size,
1918
 
                                  IBUF_BITMAP_IBUF, FALSE, &mtr);
 
1860
        bitmap_page = ibuf_bitmap_get_map_page(
 
1861
                IBUF_SPACE_ID, page_no, zip_size, &mtr);
 
1862
 
 
1863
        ibuf_bitmap_page_set_bits(
 
1864
                bitmap_page, page_no, zip_size, IBUF_BITMAP_IBUF, FALSE, &mtr);
 
1865
 
1919
1866
#ifdef UNIV_DEBUG_FILE_ACCESSES
1920
 
        buf_page_set_file_page_was_freed(space, page_no);
 
1867
        buf_page_set_file_page_was_freed(IBUF_SPACE_ID, page_no);
1921
1868
#endif
1922
1869
        mtr_commit(&mtr);
1923
1870
 
1932
1879
file segment, and the thread did not own the fsp latch before this call. */
1933
1880
UNIV_INTERN
1934
1881
void
1935
 
ibuf_free_excess_pages(
1936
 
/*===================*/
1937
 
        ulint   space)  /* in: compressed page size in bytes, or 0 */
 
1882
ibuf_free_excess_pages(void)
 
1883
/*========================*/
1938
1884
{
1939
 
        ibuf_data_t*    ibuf_data;
1940
1885
        ulint           i;
1941
1886
 
1942
 
        if (space != 0) {
1943
 
                fprintf(stderr,
1944
 
                        "InnoDB: Error: calling ibuf_free_excess_pages"
1945
 
                        " for space %lu\n", (ulong) space);
1946
 
                return;
1947
 
        }
1948
 
 
1949
1887
#ifdef UNIV_SYNC_DEBUG
1950
 
        ut_ad(rw_lock_own(fil_space_get_latch(space, NULL), RW_LOCK_EX));
 
1888
        ut_ad(rw_lock_own(fil_space_get_latch(IBUF_SPACE_ID, NULL),
 
1889
                          RW_LOCK_EX));
1951
1890
#endif /* UNIV_SYNC_DEBUG */
1952
 
        ut_ad(rw_lock_get_x_lock_count(fil_space_get_latch(space, NULL)) == 1);
 
1891
 
 
1892
        ut_ad(rw_lock_get_x_lock_count(
 
1893
                fil_space_get_latch(IBUF_SPACE_ID, NULL)) == 1);
 
1894
 
1953
1895
        ut_ad(!ibuf_inside());
1954
1896
 
1955
1897
        /* NOTE: We require that the thread did not own the latch before,
1956
1898
        because then we know that we can obey the correct latching order
1957
1899
        for ibuf latches */
1958
1900
 
1959
 
        ibuf_data = fil_space_get_ibuf_data(space);
1960
 
 
1961
 
        if (ibuf_data == NULL) {
1962
 
                /* Not yet initialized */
1963
 
 
1964
 
#if 0 /* defined UNIV_DEBUG */
1965
 
                fprintf(stderr,
1966
 
                        "Ibuf for space %lu not yet initialized\n", space);
1967
 
#endif
 
1901
        if (!ibuf) {
 
1902
                /* Not yet initialized; not sure if this is possible, but
 
1903
                does no harm to check for it. */
1968
1904
 
1969
1905
                return;
1970
1906
        }
1976
1912
 
1977
1913
                mutex_enter(&ibuf_mutex);
1978
1914
 
1979
 
                if (!ibuf_data_too_much_free(ibuf_data)) {
 
1915
                if (!ibuf_data_too_much_free()) {
1980
1916
 
1981
1917
                        mutex_exit(&ibuf_mutex);
1982
1918
 
1985
1921
 
1986
1922
                mutex_exit(&ibuf_mutex);
1987
1923
 
1988
 
                ibuf_remove_free_page(space, ibuf_data);
 
1924
                ibuf_remove_free_page();
1989
1925
        }
1990
1926
}
1991
1927
 
2060
1996
                rec_space_id = ibuf_rec_get_space(rec);
2061
1997
 
2062
1998
                if (rec_space_id != first_space_id
2063
 
                    || rec_page_no / IBUF_MERGE_AREA
2064
 
                    != first_page_no / IBUF_MERGE_AREA) {
 
1999
                    || (rec_page_no / IBUF_MERGE_AREA)
 
2000
                    != (first_page_no / IBUF_MERGE_AREA)) {
2065
2001
 
2066
2002
                        break;
2067
2003
                }
2176
2112
                        issued read with the highest tablespace address
2177
2113
                        to complete */
2178
2114
{
2179
 
        ulint           rnd_pos;
2180
 
        ibuf_data_t*    data;
2181
2115
        btr_pcur_t      pcur;
2182
 
        ulint           space;
2183
 
        ibool           all_trees_empty;
2184
2116
        ulint           page_nos[IBUF_MAX_N_PAGES_MERGED];
2185
2117
        ulint           space_ids[IBUF_MAX_N_PAGES_MERGED];
2186
2118
        ib_int64_t      space_versions[IBUF_MAX_N_PAGES_MERGED];
2189
2121
        mtr_t           mtr;
2190
2122
 
2191
2123
        *n_pages = 0;
2192
 
loop:
2193
2124
        ut_ad(!ibuf_inside());
2194
2125
 
2195
2126
        mutex_enter(&ibuf_mutex);
2196
2127
 
2197
 
        ut_ad(ibuf_validate_low());
2198
 
 
2199
 
        /* Choose an ibuf tree at random (though there really is only one tree
2200
 
        in the current implementation) */
2201
 
        ibuf_rnd += 865558671;
2202
 
 
2203
 
        rnd_pos = ibuf_rnd % ibuf->size;
2204
 
 
2205
 
        all_trees_empty = TRUE;
2206
 
 
2207
 
        data = UT_LIST_GET_FIRST(ibuf->data_list);
2208
 
 
2209
 
        for (;;) {
2210
 
                if (!data->empty) {
2211
 
                        all_trees_empty = FALSE;
2212
 
 
2213
 
                        if (rnd_pos < data->size) {
2214
 
 
2215
 
                                break;
2216
 
                        }
2217
 
 
2218
 
                        rnd_pos -= data->size;
2219
 
                }
2220
 
 
2221
 
                data = UT_LIST_GET_NEXT(data_list, data);
2222
 
 
2223
 
                if (data == NULL) {
2224
 
                        if (all_trees_empty) {
2225
 
                                mutex_exit(&ibuf_mutex);
2226
 
 
2227
 
                                return(0);
2228
 
                        }
2229
 
 
2230
 
                        data = UT_LIST_GET_FIRST(ibuf->data_list);
2231
 
                }
 
2128
        if (ibuf->empty) {
 
2129
ibuf_is_empty:
 
2130
                mutex_exit(&ibuf_mutex);
 
2131
 
 
2132
                return(0);
2232
2133
        }
2233
2134
 
2234
 
        ut_ad(data);
2235
 
 
2236
 
        space = data->index->space;
2237
 
 
2238
 
        ut_a(space == 0);       /* We currently only have an ibuf tree in
2239
 
                                space 0 */
2240
2135
        mtr_start(&mtr);
2241
2136
 
2242
2137
        ibuf_enter();
2244
2139
        /* Open a cursor to a randomly chosen leaf of the tree, at a random
2245
2140
        position within the leaf */
2246
2141
 
2247
 
        btr_pcur_open_at_rnd_pos(data->index, BTR_SEARCH_LEAF, &pcur, &mtr);
2248
 
 
2249
 
        if (0 == page_get_n_recs(btr_pcur_get_page(&pcur))) {
2250
 
 
2251
 
                /* This tree is empty */
2252
 
 
2253
 
                data->empty = TRUE;
 
2142
        btr_pcur_open_at_rnd_pos(ibuf->index, BTR_SEARCH_LEAF, &pcur, &mtr);
 
2143
 
 
2144
        if (page_get_n_recs(btr_pcur_get_page(&pcur)) == 0) {
 
2145
                /* When the ibuf tree is emptied completely, the last record
 
2146
                is removed using an optimistic delete and ibuf_size_update
 
2147
                is not called, causing ibuf->empty to remain FALSE. If we do
 
2148
                not reset it to TRUE here then database shutdown will hang
 
2149
                in the loop in ibuf_contract_for_n_pages. */
 
2150
 
 
2151
                ibuf->empty = TRUE;
2254
2152
 
2255
2153
                ibuf_exit();
2256
2154
 
2257
2155
                mtr_commit(&mtr);
2258
2156
                btr_pcur_close(&pcur);
2259
2157
 
2260
 
                mutex_exit(&ibuf_mutex);
2261
 
 
2262
 
                goto loop;
 
2158
                goto ibuf_is_empty;
2263
2159
        }
2264
2160
 
2265
2161
        mutex_exit(&ibuf_mutex);
2450
2346
        }
2451
2347
 
2452
2348
        {
2453
 
                buf_block_t*    block = buf_page_get(
2454
 
                        0, 0, prev_page_no, RW_X_LATCH, mtr);
 
2349
                buf_block_t*    block;
 
2350
 
 
2351
                block = buf_page_get(
 
2352
                        IBUF_SPACE_ID, 0, prev_page_no, RW_X_LATCH, mtr);
 
2353
 
2455
2354
                buf_block_dbg_add_level(block, SYNC_TREE_NODE);
2456
2355
 
 
2356
 
2457
2357
                prev_page = buf_block_get_frame(block);
2458
2358
        }
 
2359
 
2459
2360
#ifdef UNIV_BTR_DEBUG
2460
2361
        ut_a(btr_page_get_next(prev_page, mtr)
2461
2362
             == page_get_page_no(page));
2519
2420
        }
2520
2421
 
2521
2422
        {
2522
 
                buf_block_t*    block = buf_page_get(
2523
 
                        0, 0, next_page_no, RW_X_LATCH, mtr);
 
2423
                buf_block_t*    block;
 
2424
 
 
2425
                block = buf_page_get(
 
2426
                        IBUF_SPACE_ID, 0, next_page_no, RW_X_LATCH, mtr);
 
2427
 
2524
2428
                buf_block_dbg_add_level(block, SYNC_TREE_NODE);
2525
2429
 
 
2430
 
2526
2431
                next_page = buf_block_get_frame(block);
2527
2432
        }
 
2433
 
2528
2434
#ifdef UNIV_BTR_DEBUG
2529
 
        ut_a(btr_page_get_prev(next_page, mtr)
2530
 
             == page_get_page_no(page));
 
2435
        ut_a(btr_page_get_prev(next_page, mtr) == page_get_page_no(page));
2531
2436
#endif /* UNIV_BTR_DEBUG */
2532
2437
 
2533
2438
        rec = page_get_infimum_rec(next_page);
2565
2470
        const rec_t*    rec;
2566
2471
        const byte*     field;
2567
2472
        ulint           len;
2568
 
        ibuf_data_t*    ibuf_data;
2569
 
        dict_index_t*   ibuf_index;
2570
2473
        btr_pcur_t      pcur;
2571
2474
        mtr_t           mtr;
2572
2475
 
2573
 
        ibuf_data = fil_space_get_ibuf_data(0);
2574
 
 
2575
 
        ibuf_index = ibuf_data->index;
2576
 
        ut_a(!dict_table_is_comp(ibuf_index->table));
 
2476
        ut_a(!dict_table_is_comp(ibuf->index->table));
2577
2477
 
2578
2478
        ibuf_enter();
2579
2479
 
2580
2480
        mtr_start(&mtr);
2581
2481
 
2582
 
        btr_pcur_open_at_index_side(FALSE, ibuf_index, BTR_SEARCH_LEAF,
2583
 
                                    &pcur, TRUE, &mtr);
 
2482
        btr_pcur_open_at_index_side(
 
2483
                FALSE, ibuf->index, BTR_SEARCH_LEAF, &pcur, TRUE, &mtr);
 
2484
 
2584
2485
        btr_pcur_move_to_prev(&pcur, &mtr);
2585
2486
 
2586
2487
        if (btr_pcur_is_before_first_on_page(&pcur)) {
2633
2534
        rec_t*          ins_rec;
2634
2535
        ibool           old_bit_value;
2635
2536
        page_t*         bitmap_page;
2636
 
        ibuf_data_t*    ibuf_data;
2637
 
        dict_index_t*   ibuf_index;
2638
2537
        page_t*         root;
2639
2538
        ulint           err;
2640
2539
        ibool           do_merge;
2654
2553
 
2655
2554
        do_merge = FALSE;
2656
2555
 
2657
 
        /* Currently the insert buffer of space 0 takes care of inserts to all
2658
 
        tablespaces */
2659
 
 
2660
 
        ibuf_data = fil_space_get_ibuf_data(0);
2661
 
 
2662
 
        ibuf_index = ibuf_data->index;
2663
 
 
2664
2556
        mutex_enter(&ibuf_mutex);
2665
2557
 
2666
2558
        if (ibuf->size >= ibuf->max_size + IBUF_CONTRACT_DO_NOT_INSERT) {
2687
2579
 
2688
2580
                mutex_enter(&ibuf_mutex);
2689
2581
 
2690
 
                while (!ibuf_data_enough_free_for_insert(ibuf_data)) {
 
2582
                while (!ibuf_data_enough_free_for_insert()) {
2691
2583
 
2692
2584
                        mutex_exit(&ibuf_mutex);
2693
2585
 
2695
2587
 
2696
2588
                        mutex_exit(&ibuf_pessimistic_insert_mutex);
2697
2589
 
2698
 
                        err = ibuf_add_free_page(0, ibuf_data);
 
2590
                        err = ibuf_add_free_page();
2699
2591
 
2700
2592
                        if (err == DB_STRONG_FAIL) {
2701
2593
 
2726
2618
 
2727
2619
        mtr_start(&mtr);
2728
2620
 
2729
 
        btr_pcur_open(ibuf_index, ibuf_entry, PAGE_CUR_LE, mode, &pcur, &mtr);
 
2621
        btr_pcur_open(ibuf->index, ibuf_entry, PAGE_CUR_LE, mode, &pcur, &mtr);
2730
2622
 
2731
2623
        /* Find out the volume of already buffered inserts for the same index
2732
2624
        page */
2775
2667
        old_bit_value = ibuf_bitmap_page_get_bits(
2776
2668
                bitmap_page, page_no, zip_size,
2777
2669
                IBUF_BITMAP_BUFFERED, &bitmap_mtr);
 
2670
 
2778
2671
        if (!old_bit_value) {
2779
2672
                ibuf_bitmap_page_set_bits(bitmap_page, page_no, zip_size,
2780
2673
                                          IBUF_BITMAP_BUFFERED, TRUE,
2802
2695
                which would cause the x-latching of the root after that to
2803
2696
                break the latching order. */
2804
2697
 
2805
 
                root = ibuf_tree_root_get(ibuf_data, 0, &mtr);
 
2698
                root = ibuf_tree_root_get(&mtr);
2806
2699
 
2807
2700
                err = btr_cur_pessimistic_insert(BTR_NO_LOCKING_FLAG
2808
2701
                                                 | BTR_NO_UNDO_LOG_FLAG,
2815
2708
                                               thr_get_trx(thr)->id);
2816
2709
                }
2817
2710
 
2818
 
                ibuf_data_sizes_update(ibuf_data, root, &mtr);
 
2711
                ibuf_size_update(root, &mtr);
2819
2712
        }
2820
2713
 
2821
2714
function_exit:
2831
2724
        }
2832
2725
#endif
2833
2726
        if (mode == BTR_MODIFY_TREE) {
2834
 
                ut_ad(ibuf_validate_low());
2835
2727
 
2836
2728
                mutex_exit(&ibuf_mutex);
2837
2729
                mutex_exit(&ibuf_pessimistic_insert_mutex);
2846
2738
        if (err == DB_SUCCESS) {
2847
2739
                mutex_enter(&ibuf_mutex);
2848
2740
 
2849
 
                ibuf_data->empty = FALSE;
2850
 
                ibuf_data->n_inserts++;
 
2741
                ibuf->empty = FALSE;
 
2742
                ibuf->n_inserts++;
2851
2743
 
2852
2744
                mutex_exit(&ibuf_mutex);
2853
2745
 
2892
2784
 
2893
2785
        ut_a(!dict_index_is_clust(index));
2894
2786
 
 
2787
        switch (UNIV_EXPECT(ibuf_use, IBUF_USE_INSERT)) {
 
2788
        case IBUF_USE_NONE:
 
2789
                return(FALSE);
 
2790
        case IBUF_USE_INSERT:
 
2791
                goto do_insert;
 
2792
        case IBUF_USE_COUNT:
 
2793
                break;
 
2794
        }
 
2795
 
 
2796
        ut_error; /* unknown value of ibuf_use */
 
2797
 
 
2798
do_insert:
2895
2799
        entry_size = rec_get_converted_size(index, entry, 0);
2896
2800
 
2897
2801
        if (entry_size
3068
2972
        mtr_t*          mtr)    /* in: mtr */
3069
2973
{
3070
2974
        ibool           success;
3071
 
        ibuf_data_t*    ibuf_data;
3072
2975
        page_t*         root;
3073
2976
        ulint           err;
3074
2977
 
3100
3003
 
3101
3004
        btr_pcur_commit_specify_mtr(pcur, mtr);
3102
3005
 
3103
 
        /* Currently the insert buffer of space 0 takes care of inserts to all
3104
 
        tablespaces */
3105
 
 
3106
 
        ibuf_data = fil_space_get_ibuf_data(0);
3107
 
 
3108
3006
        mutex_enter(&ibuf_mutex);
3109
3007
 
3110
3008
        mtr_start(mtr);
3116
3014
                        /* The tablespace has been dropped.  It is possible
3117
3015
                        that another thread has deleted the insert buffer
3118
3016
                        entry.  Do not complain. */
3119
 
                        goto func_exit;
 
3017
                        goto commit_and_exit;
3120
3018
                }
3121
3019
 
3122
3020
                fprintf(stderr,
3138
3036
                btr_pcur_commit_specify_mtr(pcur, mtr);
3139
3037
 
3140
3038
                fputs("InnoDB: Validating insert buffer tree:\n", stderr);
3141
 
                if (!btr_validate_index(ibuf_data->index, NULL)) {
 
3039
                if (!btr_validate_index(ibuf->index, NULL)) {
3142
3040
                        ut_error;
3143
3041
                }
3144
3042
 
3148
3046
                goto func_exit;
3149
3047
        }
3150
3048
 
3151
 
        root = ibuf_tree_root_get(ibuf_data, 0, mtr);
 
3049
        root = ibuf_tree_root_get(mtr);
3152
3050
 
3153
3051
        btr_cur_pessimistic_delete(&err, TRUE, btr_pcur_get_btr_cur(pcur),
3154
3052
                                   RB_NONE, mtr);
3157
3055
#ifdef UNIV_IBUF_COUNT_DEBUG
3158
3056
        ibuf_count_set(space, page_no, ibuf_count_get(space, page_no) - 1);
3159
3057
#endif
3160
 
        ibuf_data_sizes_update(ibuf_data, root, mtr);
3161
 
 
3162
 
        ut_ad(ibuf_validate_low());
3163
 
 
 
3058
        ibuf_size_update(root, mtr);
 
3059
 
 
3060
commit_and_exit:
3164
3061
        btr_pcur_commit_specify_mtr(pcur, mtr);
3165
3062
 
3166
3063
func_exit:
3197
3094
{
3198
3095
        mem_heap_t*     heap;
3199
3096
        btr_pcur_t      pcur;
3200
 
        dtuple_t*       entry;
3201
3097
        dtuple_t*       search_tuple;
3202
 
        rec_t*          ibuf_rec;
3203
 
        page_t*         bitmap_page;
3204
 
        ibuf_data_t*    ibuf_data;
3205
3098
        ulint           n_inserts;
3206
3099
#ifdef UNIV_IBUF_DEBUG
3207
3100
        ulint           volume;
3215
3108
        ut_ad(!block || buf_block_get_page_no(block) == page_no);
3216
3109
        ut_ad(!block || buf_block_get_zip_size(block) == zip_size);
3217
3110
 
3218
 
        if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
3219
 
 
3220
 
                return;
3221
 
        }
3222
 
 
3223
 
        if (trx_sys_hdr_page(space, page_no)) {
3224
 
                return;
3225
 
        }
3226
 
 
3227
 
        /* The following assumes that the uncompressed page size
3228
 
        is a power-of-2 multiple of zip_size. */
 
3111
        if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE
 
3112
            || trx_sys_hdr_page(space, page_no)) {
 
3113
                return;
 
3114
        }
 
3115
 
 
3116
        /* We cannot refer to zip_size in the following, because
 
3117
        zip_size is passed as ULINT_UNDEFINED (it is unknown) when
 
3118
        buf_read_ibuf_merge_pages() is merging (discarding) changes
 
3119
        for a dropped tablespace.  When block != NULL or
 
3120
        update_ibuf_bitmap is specified, the zip_size must be known.
 
3121
        That is why we will repeat the check below, with zip_size in
 
3122
        place of 0.  Passing zip_size as 0 assumes that the
 
3123
        uncompressed page size always is a power-of-2 multiple of the
 
3124
        compressed page size. */
 
3125
 
3229
3126
        if (ibuf_fixed_addr_page(space, 0, page_no)
3230
3127
            || fsp_descr_page(0, page_no)) {
3231
3128
                return;
3253
3150
                        block = NULL;
3254
3151
                        update_ibuf_bitmap = FALSE;
3255
3152
                } else {
 
3153
                        page_t* bitmap_page;
 
3154
 
3256
3155
                        mtr_start(&mtr);
3257
 
                        bitmap_page = ibuf_bitmap_get_map_page(space, page_no,
3258
 
                                                               zip_size, &mtr);
 
3156
 
 
3157
                        bitmap_page = ibuf_bitmap_get_map_page(
 
3158
                                space, page_no, zip_size, &mtr);
3259
3159
 
3260
3160
                        if (!ibuf_bitmap_page_get_bits(bitmap_page, page_no,
3261
3161
                                                       zip_size,
3272
3172
                        }
3273
3173
                        mtr_commit(&mtr);
3274
3174
                }
3275
 
        } else if (block) {
3276
 
                if (ibuf_fixed_addr_page(space, zip_size, page_no)
3277
 
                    || fsp_descr_page(zip_size, page_no)) {
3278
 
                        return;
3279
 
                }
 
3175
        } else if (block
 
3176
                   && (ibuf_fixed_addr_page(space, zip_size, page_no)
 
3177
                      || fsp_descr_page(zip_size, page_no))) {
 
3178
 
 
3179
                return;
3280
3180
        }
3281
3181
 
3282
 
        /* Currently the insert buffer of space 0 takes care of inserts to all
3283
 
        tablespaces */
3284
 
 
3285
 
        ibuf_data = fil_space_get_ibuf_data(0);
3286
 
 
3287
3182
        ibuf_enter();
3288
3183
 
3289
3184
        heap = mem_heap_create(512);
3309
3204
                                  != FIL_PAGE_INDEX)
3310
3205
                    || UNIV_UNLIKELY(!page_is_leaf(block->frame))) {
3311
3206
 
 
3207
                        page_t* bitmap_page;
 
3208
 
3312
3209
                        corruption_noticed = TRUE;
3313
3210
 
3314
3211
                        ut_print_timestamp(stderr);
3357
3254
        mtr_start(&mtr);
3358
3255
 
3359
3256
        if (block) {
3360
 
                ibool success = buf_page_get_known_nowait(RW_X_LATCH, block,
3361
 
                                                          BUF_KEEP_OLD,
3362
 
                                                          __FILE__, __LINE__,
3363
 
                                                          &mtr);
 
3257
                ibool success;
 
3258
 
 
3259
                success = buf_page_get_known_nowait(
 
3260
                        RW_X_LATCH, block,
 
3261
                        BUF_KEEP_OLD, __FILE__, __LINE__, &mtr);
 
3262
 
3364
3263
                ut_a(success);
3365
3264
 
3366
3265
                buf_block_dbg_add_level(block, SYNC_TREE_NODE);
3368
3267
 
3369
3268
        /* Position pcur in the insert buffer at the first entry for this
3370
3269
        index page */
3371
 
        btr_pcur_open_on_user_rec(ibuf_data->index, search_tuple, PAGE_CUR_GE,
3372
 
                                  BTR_MODIFY_LEAF, &pcur, &mtr);
 
3270
        btr_pcur_open_on_user_rec(
 
3271
                ibuf->index, search_tuple, PAGE_CUR_GE, BTR_MODIFY_LEAF,
 
3272
                &pcur, &mtr);
 
3273
 
3373
3274
        if (!btr_pcur_is_on_user_rec(&pcur)) {
3374
3275
                ut_ad(btr_pcur_is_after_last_in_tree(&pcur, &mtr));
3375
3276
 
3377
3278
        }
3378
3279
 
3379
3280
        for (;;) {
 
3281
                rec_t*  rec;
 
3282
 
3380
3283
                ut_ad(btr_pcur_is_on_user_rec(&pcur));
3381
3284
 
3382
 
                ibuf_rec = btr_pcur_get_rec(&pcur);
 
3285
                rec = btr_pcur_get_rec(&pcur);
3383
3286
 
3384
3287
                /* Check if the entry is for this index page */
3385
 
                if (ibuf_rec_get_page_no(ibuf_rec) != page_no
3386
 
                    || ibuf_rec_get_space(ibuf_rec) != space) {
 
3288
                if (ibuf_rec_get_page_no(rec) != page_no
 
3289
                    || ibuf_rec_get_space(rec) != space) {
 
3290
 
3387
3291
                        if (block) {
3388
3292
                                page_header_reset_last_insert(
3389
3293
                                        block->frame, page_zip, &mtr);
3390
3294
                        }
 
3295
 
3391
3296
                        goto reset_bit;
3392
3297
                }
3393
3298
 
3394
3299
                if (UNIV_UNLIKELY(corruption_noticed)) {
3395
3300
                        fputs("InnoDB: Discarding record\n ", stderr);
3396
 
                        rec_print_old(stderr, ibuf_rec);
 
3301
                        rec_print_old(stderr, rec);
3397
3302
                        fputs("\nInnoDB: from the insert buffer!\n\n", stderr);
3398
3303
                } else if (block) {
3399
3304
                        /* Now we have at pcur a record which should be
3400
3305
                        inserted to the index page; NOTE that the call below
3401
 
                        copies pointers to fields in ibuf_rec, and we must
3402
 
                        keep the latch to the ibuf_rec page until the
 
3306
                        copies pointers to fields in rec, and we must
 
3307
                        keep the latch to the rec page until the
3403
3308
                        insertion is finished! */
 
3309
                        dtuple_t*       entry;
 
3310
                        dulint          max_trx_id;
3404
3311
                        dict_index_t*   dummy_index;
3405
 
                        dulint          max_trx_id = page_get_max_trx_id(
3406
 
                                page_align(ibuf_rec));
 
3312
 
 
3313
                        max_trx_id = page_get_max_trx_id(page_align(rec));
3407
3314
                        page_update_max_trx_id(block, page_zip, max_trx_id);
3408
3315
 
3409
3316
                        entry = ibuf_build_entry_from_ibuf_rec(
3410
 
                                ibuf_rec, heap, &dummy_index);
 
3317
                                rec, heap, &dummy_index);
3411
3318
#ifdef UNIV_IBUF_DEBUG
3412
3319
                        volume += rec_get_converted_size(dummy_index, entry, 0)
3413
3320
                                + page_dir_calc_reserved_space(1);
3428
3335
                        we start from the beginning again */
3429
3336
 
3430
3337
                        goto loop;
3431
 
                }
3432
 
 
3433
 
                if (btr_pcur_is_after_last_on_page(&pcur)) {
 
3338
                } else if (btr_pcur_is_after_last_on_page(&pcur)) {
3434
3339
                        mtr_commit(&mtr);
3435
3340
                        btr_pcur_close(&pcur);
3436
3341
 
3446
3351
        }
3447
3352
#endif
3448
3353
        if (UNIV_LIKELY(update_ibuf_bitmap)) {
3449
 
                bitmap_page = ibuf_bitmap_get_map_page(space, page_no,
3450
 
                                                       zip_size, &mtr);
3451
 
                ibuf_bitmap_page_set_bits(bitmap_page, page_no, zip_size,
3452
 
                                          IBUF_BITMAP_BUFFERED, FALSE, &mtr);
 
3354
                page_t* bitmap_page;
 
3355
 
 
3356
                bitmap_page = ibuf_bitmap_get_map_page(
 
3357
                        space, page_no, zip_size, &mtr);
 
3358
 
 
3359
                ibuf_bitmap_page_set_bits(
 
3360
                        bitmap_page, page_no, zip_size,
 
3361
                        IBUF_BITMAP_BUFFERED, FALSE, &mtr);
 
3362
 
3453
3363
                if (block) {
3454
3364
                        ulint old_bits = ibuf_bitmap_page_get_bits(
3455
3365
                                bitmap_page, page_no, zip_size,
3456
3366
                                IBUF_BITMAP_FREE, &mtr);
 
3367
 
3457
3368
                        ulint new_bits = ibuf_index_page_calc_free(
3458
3369
                                zip_size, block);
3459
 
#if 0 /* defined UNIV_IBUF_DEBUG */
3460
 
                        fprintf(stderr, "Old bits %lu new bits %lu"
3461
 
                                " max size %lu\n",
3462
 
                                old_bits, new_bits,
3463
 
                                page_get_max_insert_size_after_reorganize(
3464
 
                                        page, 1));
3465
 
#endif
 
3370
 
3466
3371
                        if (old_bits != new_bits) {
3467
 
                                ibuf_bitmap_page_set_bits(bitmap_page, page_no,
3468
 
                                                          zip_size,
3469
 
                                                          IBUF_BITMAP_FREE,
3470
 
                                                          new_bits, &mtr);
 
3372
                                ibuf_bitmap_page_set_bits(
 
3373
                                        bitmap_page, page_no, zip_size,
 
3374
                                        IBUF_BITMAP_FREE, new_bits, &mtr);
3471
3375
                        }
3472
3376
                }
3473
3377
        }
3474
 
#if 0 /* defined UNIV_IBUF_DEBUG */
3475
 
        fprintf(stderr,
3476
 
                "Ibuf merge %lu records volume %lu to page no %lu\n",
3477
 
                n_inserts, volume, page_no);
3478
 
#endif
 
3378
 
3479
3379
        mtr_commit(&mtr);
3480
3380
        btr_pcur_close(&pcur);
3481
3381
        mem_heap_free(heap);
3483
3383
        /* Protect our statistics keeping from race conditions */
3484
3384
        mutex_enter(&ibuf_mutex);
3485
3385
 
3486
 
        ibuf_data->n_merges++;
3487
 
        ibuf_data->n_merged_recs += n_inserts;
 
3386
        ibuf->n_merges++;
 
3387
        ibuf->n_merged_recs += n_inserts;
3488
3388
 
3489
3389
        mutex_exit(&ibuf_mutex);
3490
3390
 
3494
3394
        }
3495
3395
 
3496
3396
        ibuf_exit();
 
3397
 
3497
3398
#ifdef UNIV_IBUF_COUNT_DEBUG
3498
3399
        ut_a(ibuf_count_get(space, page_no) == 0);
3499
3400
#endif
3516
3417
        rec_t*          ibuf_rec;
3517
3418
        ulint           page_no;
3518
3419
        ibool           closed;
3519
 
        ibuf_data_t*    ibuf_data;
3520
3420
        ulint           n_inserts;
3521
3421
        mtr_t           mtr;
3522
3422
 
3523
 
        /* Currently the insert buffer of space 0 takes care of inserts to all
3524
 
        tablespaces */
3525
 
 
3526
 
        ibuf_data = fil_space_get_ibuf_data(0);
3527
 
 
3528
3423
        heap = mem_heap_create(512);
3529
3424
 
3530
3425
        /* Use page number 0 to build the search tuple so that we get the
3540
3435
 
3541
3436
        /* Position pcur in the insert buffer at the first entry for the
3542
3437
        space */
3543
 
        btr_pcur_open_on_user_rec(ibuf_data->index, search_tuple, PAGE_CUR_GE,
3544
 
                                  BTR_MODIFY_LEAF, &pcur, &mtr);
 
3438
        btr_pcur_open_on_user_rec(
 
3439
                ibuf->index, search_tuple, PAGE_CUR_GE, BTR_MODIFY_LEAF,
 
3440
                &pcur, &mtr);
 
3441
 
3545
3442
        if (!btr_pcur_is_on_user_rec(&pcur)) {
3546
3443
                ut_ad(btr_pcur_is_after_last_in_tree(&pcur, &mtr));
3547
3444
 
3592
3489
        /* Protect our statistics keeping from race conditions */
3593
3490
        mutex_enter(&ibuf_mutex);
3594
3491
 
3595
 
        ibuf_data->n_merges++;
3596
 
        ibuf_data->n_merged_recs += n_inserts;
 
3492
        ibuf->n_merges++;
 
3493
        ibuf->n_merged_recs += n_inserts;
3597
3494
 
3598
3495
        mutex_exit(&ibuf_mutex);
3599
 
        /*
3600
 
        fprintf(stderr,
3601
 
        "InnoDB: Discarded %lu ibuf entries for space %lu\n",
3602
 
        (ulong) n_inserts, (ulong) space);
3603
 
        */
 
3496
 
3604
3497
        ibuf_exit();
3605
3498
 
3606
3499
        mem_heap_free(heap);
3607
3500
}
3608
3501
 
3609
 
#ifdef UNIV_DEBUG
3610
 
/**********************************************************************
3611
 
Validates the ibuf data structures when the caller owns ibuf_mutex. */
3612
 
static
3613
 
ibool
3614
 
ibuf_validate_low(void)
3615
 
/*===================*/
3616
 
                        /* out: TRUE if ok */
3617
 
{
3618
 
        ibuf_data_t*    data;
3619
 
        ulint           sum_sizes;
3620
 
 
3621
 
        ut_ad(mutex_own(&ibuf_mutex));
3622
 
 
3623
 
        sum_sizes = 0;
3624
 
 
3625
 
        data = UT_LIST_GET_FIRST(ibuf->data_list);
3626
 
 
3627
 
        while (data) {
3628
 
                sum_sizes += data->size;
3629
 
 
3630
 
                data = UT_LIST_GET_NEXT(data_list, data);
3631
 
        }
3632
 
 
3633
 
        ut_a(sum_sizes == ibuf->size);
3634
 
 
3635
 
        return(TRUE);
3636
 
}
3637
 
#endif /* UNIV_DEBUG */
3638
 
 
3639
3502
/**********************************************************************
3640
3503
Looks if the insert buffer is empty. */
3641
3504
UNIV_INTERN
3644
3507
/*===============*/
3645
3508
                        /* out: TRUE if empty */
3646
3509
{
3647
 
        ibuf_data_t*    data;
3648
3510
        ibool           is_empty;
3649
3511
        const page_t*   root;
3650
3512
        mtr_t           mtr;
3653
3515
 
3654
3516
        mutex_enter(&ibuf_mutex);
3655
3517
 
3656
 
        data = UT_LIST_GET_FIRST(ibuf->data_list);
3657
 
 
3658
3518
        mtr_start(&mtr);
3659
3519
 
3660
 
        root = ibuf_tree_root_get(data, 0, &mtr);
 
3520
        root = ibuf_tree_root_get(&mtr);
3661
3521
 
3662
3522
        if (page_get_n_recs(root) == 0) {
3663
3523
 
3664
3524
                is_empty = TRUE;
3665
3525
 
3666
 
                if (data->empty == FALSE) {
 
3526
                if (ibuf->empty == FALSE) {
3667
3527
                        fprintf(stderr,
3668
3528
                                "InnoDB: Warning: insert buffer tree is empty"
3669
3529
                                " but the data struct does not\n"
3672
3532
                                "InnoDB: run to completion.\n");
3673
3533
                }
3674
3534
        } else {
3675
 
                ut_a(data->empty == FALSE);
 
3535
                ut_a(ibuf->empty == FALSE);
3676
3536
 
3677
3537
                is_empty = FALSE;
3678
3538
        }
3679
3539
 
3680
3540
        mtr_commit(&mtr);
3681
3541
 
3682
 
        ut_a(data->space == 0);
3683
 
 
3684
3542
        mutex_exit(&ibuf_mutex);
3685
3543
 
3686
3544
        ibuf_exit();
3696
3554
/*=======*/
3697
3555
        FILE*   file)   /* in: file where to print */
3698
3556
{
3699
 
        ibuf_data_t*    data;
3700
3557
#ifdef UNIV_IBUF_COUNT_DEBUG
3701
3558
        ulint           i;
 
3559
        ulint           j;
3702
3560
#endif
3703
3561
 
3704
3562
        mutex_enter(&ibuf_mutex);
3705
3563
 
3706
 
        data = UT_LIST_GET_FIRST(ibuf->data_list);
3707
 
 
3708
 
        while (data) {
3709
 
                fprintf(file,
3710
 
                        "Ibuf: size %lu, free list len %lu, seg size %lu,\n"
3711
 
                        "%lu inserts, %lu merged recs, %lu merges\n",
3712
 
                        (ulong) data->size,
3713
 
                        (ulong) data->free_list_len,
3714
 
                        (ulong) data->seg_size,
3715
 
                        (ulong) data->n_inserts,
3716
 
                        (ulong) data->n_merged_recs,
3717
 
                        (ulong) data->n_merges);
 
3564
        fprintf(file,
 
3565
                "Ibuf: size %lu, free list len %lu, seg size %lu,\n"
 
3566
                "%lu inserts, %lu merged recs, %lu merges\n",
 
3567
                (ulong) ibuf->size,
 
3568
                (ulong) ibuf->free_list_len,
 
3569
                (ulong) ibuf->seg_size,
 
3570
                (ulong) ibuf->n_inserts,
 
3571
                (ulong) ibuf->n_merged_recs,
 
3572
                (ulong) ibuf->n_merges);
3718
3573
#ifdef UNIV_IBUF_COUNT_DEBUG
3719
 
                for (i = 0; i < IBUF_COUNT_N_PAGES; i++) {
3720
 
                        if (ibuf_count_get(data->space, i) > 0) {
 
3574
        for (i = 0; i < IBUF_COUNT_N_SPACES; i++) {
 
3575
                for (j = 0; j < IBUF_COUNT_N_PAGES; j++) {
 
3576
                        ulint   count = ibuf_count_get(i, j);
3721
3577
 
 
3578
                        if (count > 0) {
3722
3579
                                fprintf(stderr,
3723
 
                                        "Ibuf count for page %lu is %lu\n",
3724
 
                                        (ulong) i,
3725
 
                                        (ulong)
3726
 
                                        ibuf_count_get(data->space, i));
 
3580
                                        "Ibuf count for space/page %lu/%lu"
 
3581
                                        " is %lu\n",
 
3582
                                        (ulong) i, (ulong) j, (ulong) count);
3727
3583
                        }
3728
3584
                }
3729
 
#endif
3730
 
                data = UT_LIST_GET_NEXT(data_list, data);
3731
3585
        }
 
3586
#endif /* UNIV_IBUF_COUNT_DEBUG */
3732
3587
 
3733
3588
        mutex_exit(&ibuf_mutex);
3734
3589
}