~drizzle-trunk/drizzle/7.1-staging

« back to all changes in this revision

Viewing changes to plugin/innobase/ibuf/ibuf0ibuf.cc

  • Committer: Continuous Integration
  • Date: 2012-05-24 06:47:13 UTC
  • mfrom: (2549.1.5 7.1)
  • Revision ID: ci@drizzle.org-20120524064713-xg2jthrq5fy8rkct
removed:
  plugin/innobase/include/thr0loc.h
  plugin/innobase/include/thr0loc.ic
  plugin/innobase/thr/thr0loc.cc
added:
  plugin/innobase/include/ut0bh.h
  plugin/innobase/include/ut0bh.ic
  plugin/innobase/ut/ut0bh.cc
modified:
  plugin/innobase/CMakeLists.txt
  plugin/innobase/btr/btr0btr.cc
  plugin/innobase/btr/btr0cur.cc
  plugin/innobase/btr/btr0sea.cc
  plugin/innobase/buf/buf0buddy.cc
  plugin/innobase/buf/buf0buf.cc
  plugin/innobase/buf/buf0flu.cc
  plugin/innobase/buf/buf0lru.cc
  plugin/innobase/buf/buf0rea.cc
  plugin/innobase/dict/dict0dict.cc
  plugin/innobase/dict/dict0load.cc
  plugin/innobase/dict/dict0mem.cc
  plugin/innobase/fil/fil0fil.cc
  plugin/innobase/fsp/fsp0fsp.cc
  plugin/innobase/handler/ha_innodb.cc
  plugin/innobase/handler/handler0alter.cc
  plugin/innobase/handler/internal_dictionary.cc
  plugin/innobase/handler/replication_dictionary.cc
  plugin/innobase/handler/replication_log.cc
  plugin/innobase/ibuf/ibuf0ibuf.cc
  plugin/innobase/include/btr0btr.h
  plugin/innobase/include/btr0cur.h
  plugin/innobase/include/btr0pcur.h
  plugin/innobase/include/btr0pcur.ic
  plugin/innobase/include/btr0types.h
  plugin/innobase/include/buf0buf.h
  plugin/innobase/include/buf0flu.h
  plugin/innobase/include/buf0lru.h
  plugin/innobase/include/buf0rea.h
  plugin/innobase/include/data0data.h
  plugin/innobase/include/data0data.ic
  plugin/innobase/include/dict0dict.h
  plugin/innobase/include/dict0dict.ic
  plugin/innobase/include/dict0load.h
  plugin/innobase/include/dict0mem.h
  plugin/innobase/include/dict0types.h
  plugin/innobase/include/ha_prototypes.h
  plugin/innobase/include/ibuf0ibuf.h
  plugin/innobase/include/ibuf0ibuf.ic
  plugin/innobase/include/mem0mem.h
  plugin/innobase/include/mem0mem.ic
  plugin/innobase/include/mtr0mtr.h
  plugin/innobase/include/mtr0mtr.ic
  plugin/innobase/include/os0file.h
  plugin/innobase/include/page0page.h
  plugin/innobase/include/page0zip.h
  plugin/innobase/include/rem0cmp.h
  plugin/innobase/include/rem0cmp.ic
  plugin/innobase/include/rem0rec.h
  plugin/innobase/include/rem0rec.ic
  plugin/innobase/include/row0upd.h
  plugin/innobase/include/srv0srv.h
  plugin/innobase/include/sync0arr.h
  plugin/innobase/include/sync0rw.h
  plugin/innobase/include/sync0sync.h
  plugin/innobase/include/trx0purge.h
  plugin/innobase/include/trx0rseg.h
  plugin/innobase/include/trx0sys.h
  plugin/innobase/include/trx0sys.ic
  plugin/innobase/include/trx0trx.h
  plugin/innobase/include/univ.i
  plugin/innobase/include/ut0ut.h
  plugin/innobase/include/ut0vec.h
  plugin/innobase/include/ut0vec.ic
  plugin/innobase/lock/lock0lock.cc
  plugin/innobase/log/log0recv.cc
  plugin/innobase/mem/mem0dbg.cc
  plugin/innobase/mem/mem0mem.cc
  plugin/innobase/mtr/mtr0mtr.cc
  plugin/innobase/os/os0file.cc
  plugin/innobase/page/page0cur.cc
  plugin/innobase/page/page0page.cc
  plugin/innobase/page/page0zip.cc
  plugin/innobase/plugin.am
  plugin/innobase/rem/rem0cmp.cc
  plugin/innobase/row/row0ins.cc
  plugin/innobase/row/row0merge.cc
  plugin/innobase/row/row0mysql.cc
  plugin/innobase/row/row0purge.cc
  plugin/innobase/row/row0umod.cc
  plugin/innobase/row/row0upd.cc
  plugin/innobase/row/row0vers.cc
  plugin/innobase/srv/srv0srv.cc
  plugin/innobase/srv/srv0start.cc
  plugin/innobase/sync/sync0arr.cc
  plugin/innobase/sync/sync0rw.cc
  plugin/innobase/sync/sync0sync.cc
  plugin/innobase/trx/trx0i_s.cc
  plugin/innobase/trx/trx0purge.cc
  plugin/innobase/trx/trx0roll.cc
  plugin/innobase/trx/trx0rseg.cc
  plugin/innobase/trx/trx0sys.cc
  plugin/innobase/trx/trx0trx.cc
  plugin/innobase/ut/ut0dbg.cc
  plugin/innobase/ut/ut0ut.cc
  plugin/innobase/xtrabackup/xtrabackup.cc
pending merge tips: (use -v to see all merge revisions)
  Stewart Smith 2012-05-23 Merge InnoDB from MySQL 5.5.12 (no InnoDB version bump)

Show diffs side-by-side

added added

removed removed

Lines of Context:
44
44
#include "fsp0fsp.h"
45
45
#include "trx0sys.h"
46
46
#include "fil0fil.h"
47
 
#include "thr0loc.h"
48
47
#include "rem0rec.h"
49
48
#include "btr0cur.h"
50
49
#include "btr0pcur.h"
324
323
dropped! So, there seems to be no problem. */
325
324
 
326
325
/******************************************************************//**
327
 
Sets the flag in the current OS thread local storage denoting that it is
 
326
Sets the flag in the current mini-transaction record indicating we're
328
327
inside an insert buffer routine. */
329
328
UNIV_INLINE
330
329
void
331
 
ibuf_enter(void)
332
 
/*============*/
 
330
ibuf_enter(
 
331
/*=======*/
 
332
        mtr_t*  mtr)    /*!< in/out: mini-transaction */
333
333
{
334
 
        ibool*  ptr;
335
 
 
336
 
        ptr = thr_local_get_in_ibuf_field();
337
 
 
338
 
        ut_ad(*ptr == FALSE);
339
 
 
340
 
        *ptr = TRUE;
 
334
        ut_ad(!mtr->inside_ibuf);
 
335
        mtr->inside_ibuf = TRUE;
341
336
}
342
337
 
343
338
/******************************************************************//**
344
 
Sets the flag in the current OS thread local storage denoting that it is
 
339
Sets the flag in the current mini-transaction record indicating we're
345
340
exiting an insert buffer routine. */
346
341
UNIV_INLINE
347
342
void
348
 
ibuf_exit(void)
349
 
/*===========*/
 
343
ibuf_exit(
 
344
/*======*/
 
345
        mtr_t*  mtr)    /*!< in/out: mini-transaction */
350
346
{
351
 
        ibool*  ptr;
352
 
 
353
 
        ptr = thr_local_get_in_ibuf_field();
354
 
 
355
 
        ut_ad(*ptr == TRUE);
356
 
 
357
 
        *ptr = FALSE;
 
347
        ut_ad(mtr->inside_ibuf);
 
348
        mtr->inside_ibuf = FALSE;
358
349
}
359
350
 
360
 
/******************************************************************//**
361
 
Returns TRUE if the current OS thread is performing an insert buffer
362
 
routine.
363
 
 
364
 
For instance, a read-ahead of non-ibuf pages is forbidden by threads
365
 
that are executing an insert buffer routine.
366
 
@return TRUE if inside an insert buffer routine */
367
 
UNIV_INTERN
368
 
ibool
369
 
ibuf_inside(void)
370
 
/*=============*/
 
351
/**************************************************************//**
 
352
Commits an insert buffer mini-transaction and sets the persistent
 
353
cursor latch mode to BTR_NO_LATCHES, that is, detaches the cursor. */
 
354
UNIV_INLINE
 
355
void
 
356
ibuf_btr_pcur_commit_specify_mtr(
 
357
/*=============================*/
 
358
        btr_pcur_t*     pcur,   /*!< in/out: persistent cursor */
 
359
        mtr_t*          mtr)    /*!< in/out: mini-transaction */
371
360
{
372
 
        return(*thr_local_get_in_ibuf_field());
 
361
        ut_d(ibuf_exit(mtr));
 
362
        btr_pcur_commit_specify_mtr(pcur, mtr);
373
363
}
374
364
 
375
365
/******************************************************************//**
379
369
page_t*
380
370
ibuf_header_page_get(
381
371
/*=================*/
382
 
        mtr_t*  mtr)    /*!< in: mtr */
 
372
        mtr_t*  mtr)    /*!< in/out: mini-transaction */
383
373
{
384
374
        buf_block_t*    block;
385
375
 
386
 
        ut_ad(!ibuf_inside());
 
376
        ut_ad(!ibuf_inside(mtr));
387
377
 
388
378
        block = buf_page_get(
389
379
                IBUF_SPACE_ID, 0, FSP_IBUF_HEADER_PAGE_NO, RW_X_LATCH, mtr);
404
394
        buf_block_t*    block;
405
395
        page_t*         root;
406
396
 
407
 
        ut_ad(ibuf_inside());
 
397
        ut_ad(ibuf_inside(mtr));
408
398
        ut_ad(mutex_own(&ibuf_mutex));
409
399
 
410
400
        mtr_x_lock(dict_index_get_lock(ibuf->index), mtr);
549
539
 
550
540
        fseg_n_reserved_pages(header_page + IBUF_HEADER + IBUF_TREE_SEG_HEADER,
551
541
                              &n_used, &mtr);
552
 
        ibuf_enter();
 
542
        ibuf_enter(&mtr);
553
543
 
554
544
        ut_ad(n_used >= 2);
555
545
 
570
560
        mutex_exit(&ibuf_mutex);
571
561
 
572
562
        ibuf->empty = (page_get_n_recs(root) == 0);
573
 
        mtr_commit(&mtr);
574
 
 
575
 
        ibuf_exit();
 
563
        ibuf_mtr_commit(&mtr);
576
564
 
577
565
        heap = mem_heap_create(450);
578
566
 
658
646
        return(ptr);
659
647
}
660
648
#ifndef UNIV_HOTBACKUP
 
649
# ifdef UNIV_DEBUG
 
650
/** Gets the desired bits for a given page from a bitmap page.
 
651
@param page     in: bitmap page
 
652
@param offset   in: page whose bits to get
 
653
@param zs       in: compressed page size in bytes; 0 for uncompressed pages
 
654
@param bit      in: IBUF_BITMAP_FREE, IBUF_BITMAP_BUFFERED, ...
 
655
@param mtr      in: mini-transaction holding an x-latch on the bitmap page
 
656
@return value of bits */
 
657
#  define ibuf_bitmap_page_get_bits(page, offset, zs, bit, mtr) \
 
658
        ibuf_bitmap_page_get_bits_low(page, offset, zs, \
 
659
                                      MTR_MEMO_PAGE_X_FIX, mtr, bit)
 
660
# else /* UNIV_DEBUG */
 
661
/** Gets the desired bits for a given page from a bitmap page.
 
662
@param page     in: bitmap page
 
663
@param offset   in: page whose bits to get
 
664
@param zs       in: compressed page size in bytes; 0 for uncompressed pages
 
665
@param bit      in: IBUF_BITMAP_FREE, IBUF_BITMAP_BUFFERED, ...
 
666
@param mtr      in: mini-transaction holding an x-latch on the bitmap page
 
667
@return value of bits */
 
668
#  define ibuf_bitmap_page_get_bits(page, offset, zs, bit, mtr)         \
 
669
        ibuf_bitmap_page_get_bits_low(page, offset, zs, bit)
 
670
# endif /* UNIV_DEBUG */
 
671
 
661
672
/********************************************************************//**
662
673
Gets the desired bits for a given page from a bitmap page.
663
674
@return value of bits */
664
675
UNIV_INLINE
665
676
ulint
666
 
ibuf_bitmap_page_get_bits(
667
 
/*======================*/
 
677
ibuf_bitmap_page_get_bits_low(
 
678
/*==========================*/
668
679
        const page_t*   page,   /*!< in: bitmap page */
669
680
        ulint           page_no,/*!< in: page whose bits to get */
670
681
        ulint           zip_size,/*!< in: compressed page size in bytes;
671
682
                                0 for uncompressed pages */
672
 
        ulint           bit,    /*!< in: IBUF_BITMAP_FREE,
 
683
#ifdef UNIV_DEBUG
 
684
        ulint           latch_type,
 
685
                                /*!< in: MTR_MEMO_PAGE_X_FIX,
 
686
                                MTR_MEMO_BUF_FIX, ... */
 
687
        mtr_t*          mtr,    /*!< in: mini-transaction holding latch_type
 
688
                                on the bitmap page */
 
689
#endif /* UNIV_DEBUG */
 
690
        ulint           bit)    /*!< in: IBUF_BITMAP_FREE,
 
691
 
673
692
                                IBUF_BITMAP_BUFFERED, ... */
674
 
        mtr_t*          /*mtr __attribute__((unused))*/)
675
 
                                /*!< in: mtr containing an
676
 
                                x-latch to the bitmap page */
677
693
{
678
694
        ulint   byte_offset;
679
695
        ulint   bit_offset;
685
701
# error "IBUF_BITS_PER_PAGE % 2 != 0"
686
702
#endif
687
703
        ut_ad(ut_is_2pow(zip_size));
688
 
        ut_ad(mtr_memo_contains_page(mtr, page, MTR_MEMO_PAGE_X_FIX));
 
704
        ut_ad(mtr_memo_contains_page(mtr, page, latch_type));
689
705
 
690
706
        if (!zip_size) {
691
707
                bit_offset = (page_no % UNIV_PAGE_SIZE) * IBUF_BITS_PER_PAGE
1111
1127
@return TRUE if level 2 or level 3 page */
1112
1128
UNIV_INTERN
1113
1129
ibool
1114
 
ibuf_page(
1115
 
/*======*/
1116
 
        ulint   space,  /*!< in: space id */
1117
 
        ulint   zip_size,/*!< in: compressed page size in bytes, or 0 */
1118
 
        ulint   page_no,/*!< in: page number */
1119
 
        mtr_t*  mtr)    /*!< in: mtr which will contain an x-latch to the
1120
 
                        bitmap page if the page is not one of the fixed
1121
 
                        address ibuf pages, or NULL, in which case a new
1122
 
                        transaction is created. */
 
1130
ibuf_page_low(
 
1131
/*==========*/
 
1132
        ulint           space,  /*!< in: space id */
 
1133
        ulint           zip_size,/*!< in: compressed page size in bytes, or 0 */
 
1134
        ulint           page_no,/*!< in: page number */
 
1135
#ifdef UNIV_DEBUG
 
1136
        ibool           x_latch,/*!< in: FALSE if relaxed check
 
1137
                                (avoid latching the bitmap page) */
 
1138
#endif /* UNIV_DEBUG */
 
1139
        const char*     file,   /*!< in: file name */
 
1140
        ulint           line,   /*!< in: line where called */
 
1141
        mtr_t*          mtr)    /*!< in: mtr which will contain an
 
1142
                                x-latch to the bitmap page if the page
 
1143
                                is not one of the fixed address ibuf
 
1144
                                pages, or NULL, in which case a new
 
1145
                                transaction is created. */
1123
1146
{
1124
1147
        ibool   ret;
1125
1148
        mtr_t   local_mtr;
1126
1149
        page_t* bitmap_page;
1127
1150
 
1128
1151
        ut_ad(!recv_no_ibuf_operations);
 
1152
        ut_ad(x_latch || mtr == NULL);
1129
1153
 
1130
1154
        if (srv_fake_write)
1131
1155
          return(FALSE);
1140
1164
 
1141
1165
        ut_ad(fil_space_get_type(IBUF_SPACE_ID) == FIL_TABLESPACE);
1142
1166
 
 
1167
#ifdef UNIV_DEBUG
 
1168
        if (!x_latch) {
 
1169
                mtr_start(&local_mtr);
 
1170
 
 
1171
                /* Get the bitmap page without a page latch, so that
 
1172
                we will not be violating the latching order when
 
1173
                another bitmap page has already been latched by this
 
1174
                thread. The page will be buffer-fixed, and thus it
 
1175
                cannot be removed or relocated while we are looking at
 
1176
                it. The contents of the page could change, but the
 
1177
                IBUF_BITMAP_IBUF bit that we are interested in should
 
1178
                not be modified by any other thread. Nobody should be
 
1179
                calling ibuf_add_free_page() or ibuf_remove_free_page()
 
1180
                while the page is linked to the insert buffer b-tree. */
 
1181
 
 
1182
                bitmap_page = buf_block_get_frame(
 
1183
                        buf_page_get_gen(
 
1184
                                space, zip_size,
 
1185
                                ibuf_bitmap_page_no_calc(zip_size, page_no),
 
1186
                                RW_NO_LATCH, NULL, BUF_GET_NO_LATCH,
 
1187
                                file, line, &local_mtr));
 
1188
# ifdef UNIV_SYNC_DEBUG
 
1189
                /* This is for tracking Bug #58212. This check and message can
 
1190
                be removed once it has been established that our assumptions
 
1191
                about this condition are correct. The bug was only a one-time
 
1192
                occurrence, unable to repeat since then. */
 
1193
                void* latch = sync_thread_levels_contains(SYNC_IBUF_BITMAP);
 
1194
                if (latch) {
 
1195
                        fprintf(stderr, "Bug#58212 UNIV_SYNC_DEBUG"
 
1196
                                " levels %p (%u,%u)\n",
 
1197
                                latch, (unsigned) space, (unsigned) page_no);
 
1198
                }
 
1199
# endif /* UNIV_SYNC_DEBUG */
 
1200
                ret = ibuf_bitmap_page_get_bits_low(
 
1201
                        bitmap_page, page_no, zip_size,
 
1202
                        MTR_MEMO_BUF_FIX, &local_mtr, IBUF_BITMAP_IBUF);
 
1203
 
 
1204
                mtr_commit(&local_mtr);
 
1205
                return(ret);
 
1206
        }
 
1207
#endif /* UNIV_DEBUG */
 
1208
 
1143
1209
        if (mtr == NULL) {
1144
1210
                mtr = &local_mtr;
1145
1211
                mtr_start(mtr);
1146
1212
        }
1147
1213
 
1148
 
        bitmap_page = ibuf_bitmap_get_map_page(space, page_no, zip_size, mtr);
 
1214
        bitmap_page = ibuf_bitmap_get_map_page_func(space, page_no, zip_size,
 
1215
                                                    file, line, mtr);
1149
1216
 
1150
1217
        ret = ibuf_bitmap_page_get_bits(bitmap_page, page_no, zip_size,
1151
1218
                                        IBUF_BITMAP_IBUF, mtr);
1157
1224
        return(ret);
1158
1225
}
1159
1226
 
 
1227
#ifdef UNIV_DEBUG
 
1228
# define ibuf_rec_get_page_no(mtr,rec) ibuf_rec_get_page_no_func(mtr,rec)
 
1229
#else /* UNIV_DEBUG */
 
1230
# define ibuf_rec_get_page_no(mtr,rec) ibuf_rec_get_page_no_func(rec)
 
1231
#endif /* UNIV_DEBUG */
 
1232
 
1160
1233
/********************************************************************//**
1161
1234
Returns the page number field of an ibuf record.
1162
1235
@return page number */
1163
1236
static
1164
1237
ulint
1165
 
ibuf_rec_get_page_no(
1166
 
/*=================*/
 
1238
ibuf_rec_get_page_no_func(
 
1239
/*======================*/
 
1240
#ifdef UNIV_DEBUG
 
1241
        mtr_t*          mtr,    /*!< in: mini-transaction owning rec */
 
1242
#endif /* UNIV_DEBUG */
1167
1243
        const rec_t*    rec)    /*!< in: ibuf record */
1168
1244
{
1169
1245
        const byte*     field;
1170
1246
        ulint           len;
1171
1247
 
1172
 
        ut_ad(ibuf_inside());
 
1248
        ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX)
 
1249
              || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX));
 
1250
        ut_ad(ibuf_inside(mtr));
1173
1251
        ut_ad(rec_get_n_fields_old(rec) > 2);
1174
1252
 
1175
1253
        field = rec_get_nth_field_old(rec, 1, &len);
1191
1269
        return(mach_read_from_4(field));
1192
1270
}
1193
1271
 
 
1272
#ifdef UNIV_DEBUG
 
1273
# define ibuf_rec_get_space(mtr,rec) ibuf_rec_get_space_func(mtr,rec)
 
1274
#else /* UNIV_DEBUG */
 
1275
# define ibuf_rec_get_space(mtr,rec) ibuf_rec_get_space_func(rec)
 
1276
#endif /* UNIV_DEBUG */
 
1277
 
1194
1278
/********************************************************************//**
1195
1279
Returns the space id field of an ibuf record. For < 4.1.x format records
1196
1280
returns 0.
1197
1281
@return space id */
1198
1282
static
1199
1283
ulint
1200
 
ibuf_rec_get_space(
1201
 
/*===============*/
 
1284
ibuf_rec_get_space_func(
 
1285
/*====================*/
 
1286
#ifdef UNIV_DEBUG
 
1287
        mtr_t*          mtr,    /*!< in: mini-transaction owning rec */
 
1288
#endif /* UNIV_DEBUG */
1202
1289
        const rec_t*    rec)    /*!< in: ibuf record */
1203
1290
{
1204
1291
        const byte*     field;
1205
1292
        ulint           len;
1206
1293
 
1207
 
        ut_ad(ibuf_inside());
 
1294
        ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX)
 
1295
              || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX));
 
1296
        ut_ad(ibuf_inside(mtr));
1208
1297
        ut_ad(rec_get_n_fields_old(rec) > 2);
1209
1298
 
1210
1299
        field = rec_get_nth_field_old(rec, 1, &len);
1225
1314
        return(0);
1226
1315
}
1227
1316
 
 
1317
#ifdef UNIV_DEBUG
 
1318
# define ibuf_rec_get_info(mtr,rec,op,comp,info_len,counter)    \
 
1319
        ibuf_rec_get_info_func(mtr,rec,op,comp,info_len,counter)
 
1320
#else /* UNIV_DEBUG */
 
1321
# define ibuf_rec_get_info(mtr,rec,op,comp,info_len,counter)    \
 
1322
        ibuf_rec_get_info_func(rec,op,comp,info_len,counter)
 
1323
#endif
1228
1324
/****************************************************************//**
1229
1325
Get various information about an ibuf record in >= 4.1.x format. */
1230
1326
static
1231
1327
void
1232
 
ibuf_rec_get_info(
1233
 
/*==============*/
 
1328
ibuf_rec_get_info_func(
 
1329
/*===================*/
 
1330
#ifdef UNIV_DEBUG
 
1331
        mtr_t*          mtr,    /*!< in: mini-transaction owning rec */
 
1332
#endif /* UNIV_DEBUG */
1234
1333
        const rec_t*    rec,            /*!< in: ibuf record */
1235
1334
        ibuf_op_t*      op,             /*!< out: operation type, or NULL */
1236
1335
        ibool*          comp,           /*!< out: compact flag, or NULL */
1249
1348
        ulint           info_len_local;
1250
1349
        ulint           counter_local;
1251
1350
 
1252
 
        ut_ad(ibuf_inside());
 
1351
        ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX)
 
1352
              || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX));
 
1353
        ut_ad(ibuf_inside(mtr));
1253
1354
        fields = rec_get_n_fields_old(rec);
1254
1355
        ut_a(fields > 4);
1255
1356
 
1298
1399
        }
1299
1400
}
1300
1401
 
 
1402
#ifdef UNIV_DEBUG
 
1403
# define ibuf_rec_get_op_type(mtr,rec) ibuf_rec_get_op_type_func(mtr,rec)
 
1404
#else /* UNIV_DEBUG */
 
1405
# define ibuf_rec_get_op_type(mtr,rec) ibuf_rec_get_op_type_func(rec)
 
1406
#endif
 
1407
 
1301
1408
/****************************************************************//**
1302
1409
Returns the operation type field of an ibuf record.
1303
1410
@return operation type */
1304
1411
static
1305
1412
ibuf_op_t
1306
 
ibuf_rec_get_op_type(
1307
 
/*=================*/
 
1413
ibuf_rec_get_op_type_func(
 
1414
/*======================*/
 
1415
#ifdef UNIV_DEBUG
 
1416
        mtr_t*          mtr,    /*!< in: mini-transaction owning rec */
 
1417
#endif /* UNIV_DEBUG */
1308
1418
        const rec_t*    rec)    /*!< in: ibuf record */
1309
1419
{
1310
1420
        ulint           len;
1311
1421
 
1312
 
        ut_ad(ibuf_inside());
 
1422
        ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX)
 
1423
              || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX));
 
1424
        ut_ad(ibuf_inside(mtr));
1313
1425
        ut_ad(rec_get_n_fields_old(rec) > 2);
1314
1426
 
1315
1427
        (void) rec_get_nth_field_old(rec, 1, &len);
1321
1433
        } else {
1322
1434
                ibuf_op_t       op;
1323
1435
 
1324
 
                ibuf_rec_get_info(rec, &op, NULL, NULL, NULL);
 
1436
                ibuf_rec_get_info(mtr, rec, &op, NULL, NULL, NULL);
1325
1437
 
1326
1438
                return(op);
1327
1439
        }
1520
1632
        return(tuple);
1521
1633
}
1522
1634
 
 
1635
#ifdef UNIV_DEBUG
 
1636
# define ibuf_build_entry_from_ibuf_rec(mtr,ibuf_rec,heap,pindex)       \
 
1637
        ibuf_build_entry_from_ibuf_rec_func(mtr,ibuf_rec,heap,pindex)
 
1638
#else /* UNIV_DEBUG */
 
1639
# define ibuf_build_entry_from_ibuf_rec(mtr,ibuf_rec,heap,pindex)       \
 
1640
        ibuf_build_entry_from_ibuf_rec_func(ibuf_rec,heap,pindex)
 
1641
#endif
 
1642
 
1523
1643
/*********************************************************************//**
1524
1644
Builds the entry used to
1525
1645
 
1538
1658
@return own: entry to insert to a non-clustered index */
1539
1659
static
1540
1660
dtuple_t*
1541
 
ibuf_build_entry_from_ibuf_rec(
1542
 
/*===========================*/
 
1661
ibuf_build_entry_from_ibuf_rec_func(
 
1662
/*================================*/
 
1663
#ifdef UNIV_DEBUG
 
1664
        mtr_t*          mtr,    /*!< in: mini-transaction owning rec */
 
1665
#endif /* UNIV_DEBUG */
1543
1666
        const rec_t*    ibuf_rec,       /*!< in: record in an insert buffer */
1544
1667
        mem_heap_t*     heap,           /*!< in: heap where built */
1545
1668
        dict_index_t**  pindex)         /*!< out, own: dummy index that
1556
1679
        ulint           comp;
1557
1680
        dict_index_t*   index;
1558
1681
 
 
1682
        ut_ad(mtr_memo_contains_page(mtr, ibuf_rec, MTR_MEMO_PAGE_X_FIX)
 
1683
              || mtr_memo_contains_page(mtr, ibuf_rec, MTR_MEMO_PAGE_S_FIX));
 
1684
        ut_ad(ibuf_inside(mtr));
 
1685
 
1559
1686
        data = rec_get_nth_field_old(ibuf_rec, 1, &len);
1560
1687
 
1561
1688
        if (len > 1) {
1576
1703
 
1577
1704
        types = rec_get_nth_field_old(ibuf_rec, 3, &len);
1578
1705
 
1579
 
        ibuf_rec_get_info(ibuf_rec, NULL, &comp, &info_len, NULL);
 
1706
        ibuf_rec_get_info(mtr, ibuf_rec, NULL, &comp, &info_len, NULL);
1580
1707
 
1581
1708
        index = ibuf_dummy_index_create(n_fields, comp);
1582
1709
 
1663
1790
        return(size);
1664
1791
}
1665
1792
 
 
1793
#ifdef UNIV_DEBUG
 
1794
# define ibuf_rec_get_volume(mtr,rec) ibuf_rec_get_volume_func(mtr,rec)
 
1795
#else /* UNIV_DEBUG */
 
1796
# define ibuf_rec_get_volume(mtr,rec) ibuf_rec_get_volume_func(rec)
 
1797
#endif
 
1798
 
1666
1799
/********************************************************************//**
1667
1800
Returns the space taken by a stored non-clustered index entry if converted to
1668
1801
an index record.
1670
1803
taken in the page directory */
1671
1804
static
1672
1805
ulint
1673
 
ibuf_rec_get_volume(
1674
 
/*================*/
 
1806
ibuf_rec_get_volume_func(
 
1807
/*=====================*/
 
1808
#ifdef UNIV_DEBUG
 
1809
        mtr_t*          mtr,    /*!< in: mini-transaction owning rec */
 
1810
#endif /* UNIV_DEBUG */
1675
1811
        const rec_t*    ibuf_rec)/*!< in: ibuf record */
1676
1812
{
1677
1813
        ulint           len;
1682
1818
        ibool           pre_4_1;
1683
1819
        ulint           comp;
1684
1820
 
1685
 
        ut_ad(ibuf_inside());
 
1821
        ut_ad(mtr_memo_contains_page(mtr, ibuf_rec, MTR_MEMO_PAGE_X_FIX)
 
1822
              || mtr_memo_contains_page(mtr, ibuf_rec, MTR_MEMO_PAGE_S_FIX));
 
1823
        ut_ad(ibuf_inside(mtr));
1686
1824
        ut_ad(rec_get_n_fields_old(ibuf_rec) > 2);
1687
1825
 
1688
1826
        data = rec_get_nth_field_old(ibuf_rec, 1, &len);
1710
1848
 
1711
1849
                types = rec_get_nth_field_old(ibuf_rec, 3, &len);
1712
1850
 
1713
 
                ibuf_rec_get_info(ibuf_rec, &op, &comp, &info_len, NULL);
 
1851
                ibuf_rec_get_info(mtr, ibuf_rec, &op, &comp, &info_len, NULL);
1714
1852
 
1715
1853
                if (op == IBUF_OP_DELETE_MARK || op == IBUF_OP_DELETE) {
1716
1854
                        /* Delete-marking a record doesn't take any
1727
1865
                        mem_heap_t*     heap = mem_heap_create(500);
1728
1866
 
1729
1867
                        entry = ibuf_build_entry_from_ibuf_rec(
1730
 
                                ibuf_rec, heap, &dummy_index);
 
1868
                                mtr, ibuf_rec, heap, &dummy_index);
1731
1869
 
1732
1870
                        volume = rec_get_converted_size(dummy_index, entry, 0);
1733
1871
 
2085
2223
                mtr_commit(&mtr);
2086
2224
 
2087
2225
                return(FALSE);
2088
 
        }
2089
 
 
2090
 
        {
2091
 
                buf_block_t*    block;
2092
 
 
2093
 
                block = buf_page_get(
 
2226
        } else {
 
2227
                buf_block_t*    block = buf_page_get(
2094
2228
                        IBUF_SPACE_ID, 0, page_no, RW_X_LATCH, &mtr);
2095
 
 
2096
2229
                buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW);
2097
2230
 
2098
 
 
2099
2231
                page = buf_block_get_frame(block);
2100
2232
        }
2101
2233
 
2102
 
        ibuf_enter();
 
2234
        ibuf_enter(&mtr);
2103
2235
 
2104
2236
        mutex_enter(&ibuf_mutex);
2105
2237
 
2127
2259
        ibuf_bitmap_page_set_bits(
2128
2260
                bitmap_page, page_no, zip_size, IBUF_BITMAP_IBUF, TRUE, &mtr);
2129
2261
 
2130
 
        mtr_commit(&mtr);
2131
 
 
2132
 
        ibuf_exit();
 
2262
        ibuf_mtr_commit(&mtr);
2133
2263
 
2134
2264
        return(TRUE);
2135
2265
}
2161
2291
        header_page = ibuf_header_page_get(&mtr);
2162
2292
 
2163
2293
        /* Prevent pessimistic inserts to insert buffer trees for a while */
2164
 
        ibuf_enter();
 
2294
        ibuf_enter(&mtr);
2165
2295
        mutex_enter(&ibuf_pessimistic_insert_mutex);
2166
2296
        mutex_enter(&ibuf_mutex);
2167
2297
 
2170
2300
                mutex_exit(&ibuf_mutex);
2171
2301
                mutex_exit(&ibuf_pessimistic_insert_mutex);
2172
2302
 
2173
 
                ibuf_exit();
2174
 
 
2175
 
                mtr_commit(&mtr);
 
2303
                ibuf_mtr_commit(&mtr);
2176
2304
 
2177
2305
                return;
2178
2306
        }
2179
2307
 
2180
 
        mtr_start(&mtr2);
 
2308
        ibuf_mtr_start(&mtr2);
2181
2309
 
2182
2310
        root = ibuf_tree_root_get(&mtr2);
2183
2311
 
2190
2318
        because in fseg_free_page we access level 1 pages, and the root
2191
2319
        is a level 2 page. */
2192
2320
 
2193
 
        mtr_commit(&mtr2);
2194
 
 
2195
 
        ibuf_exit();
 
2321
        ibuf_mtr_commit(&mtr2);
 
2322
        ibuf_exit(&mtr);
2196
2323
 
2197
2324
        /* Since pessimistic inserts were prevented, we know that the
2198
2325
        page is still in the free list. NOTE that also deletes may take
2203
2330
        fseg_free_page(header_page + IBUF_HEADER + IBUF_TREE_SEG_HEADER,
2204
2331
                       IBUF_SPACE_ID, page_no, &mtr);
2205
2332
 
2206
 
#ifdef UNIV_DEBUG_FILE_ACCESSES
 
2333
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
2207
2334
        buf_page_reset_file_page_was_freed(IBUF_SPACE_ID, page_no);
2208
 
#endif
 
2335
#endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
2209
2336
 
2210
 
        ibuf_enter();
 
2337
        ibuf_enter(&mtr);
2211
2338
 
2212
2339
        mutex_enter(&ibuf_mutex);
2213
2340
 
2249
2376
        ibuf_bitmap_page_set_bits(
2250
2377
                bitmap_page, page_no, zip_size, IBUF_BITMAP_IBUF, FALSE, &mtr);
2251
2378
 
2252
 
#ifdef UNIV_DEBUG_FILE_ACCESSES
 
2379
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
2253
2380
        buf_page_set_file_page_was_freed(IBUF_SPACE_ID, page_no);
2254
 
#endif
2255
 
        mtr_commit(&mtr);
2256
 
 
2257
 
        ibuf_exit();
 
2381
#endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
 
2382
        ibuf_mtr_commit(&mtr);
2258
2383
}
2259
2384
 
2260
2385
/***********************************************************************//**
2276
2401
        ut_ad(rw_lock_get_x_lock_count(
2277
2402
                fil_space_get_latch(IBUF_SPACE_ID, NULL)) == 1);
2278
2403
 
2279
 
        ut_ad(!ibuf_inside());
2280
 
 
2281
2404
        /* NOTE: We require that the thread did not own the latch before,
2282
2405
        because then we know that we can obey the correct latching order
2283
2406
        for ibuf latches */
2308
2431
        }
2309
2432
}
2310
2433
 
 
2434
#ifdef UNIV_DEBUG
 
2435
# define ibuf_get_merge_page_nos(contract,rec,mtr,ids,vers,pages,n_stored) \
 
2436
        ibuf_get_merge_page_nos_func(contract,rec,mtr,ids,vers,pages,n_stored)
 
2437
#else /* UNIV_DEBUG */
 
2438
# define ibuf_get_merge_page_nos(contract,rec,mtr,ids,vers,pages,n_stored) \
 
2439
        ibuf_get_merge_page_nos_func(contract,rec,ids,vers,pages,n_stored)
 
2440
#endif /* UNIV_DEBUG */
 
2441
 
2311
2442
/*********************************************************************//**
2312
2443
Reads page numbers from a leaf in an ibuf tree.
2313
2444
@return a lower limit for the combined volume of records which will be
2314
2445
merged */
2315
2446
static
2316
2447
ulint
2317
 
ibuf_get_merge_page_nos(
2318
 
/*====================*/
 
2448
ibuf_get_merge_page_nos_func(
 
2449
/*=========================*/
2319
2450
        ibool           contract,/*!< in: TRUE if this function is called to
2320
2451
                                contract the tree, FALSE if this is called
2321
2452
                                when a single page becomes full and we look
2322
2453
                                if it pays to read also nearby pages */
2323
 
        rec_t*          rec,    /*!< in: record from which we read up and down
2324
 
                                in the chain of records */
 
2454
        const rec_t*    rec,    /*!< in: insert buffer record */
 
2455
#ifdef UNIV_DEBUG
 
2456
        mtr_t*          mtr,    /*!< in: mini-transaction holding rec */
 
2457
#endif /* UNIV_DEBUG */
2325
2458
        ulint*          space_ids,/*!< in/out: space id's of the pages */
2326
2459
        ib_int64_t*     space_versions,/*!< in/out: tablespace version
2327
2460
                                timestamps; used to prevent reading in old
2344
2477
        ulint   limit;
2345
2478
        ulint   n_pages;
2346
2479
 
 
2480
        ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX)
 
2481
              || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX));
 
2482
        ut_ad(ibuf_inside(mtr));
 
2483
 
2347
2484
        *n_stored = 0;
2348
2485
 
2349
2486
        limit = ut_min(IBUF_MAX_N_PAGES_MERGED, buf_pool_get_curr_size() / 4);
2350
2487
 
2351
2488
        if (page_rec_is_supremum(rec)) {
2352
2489
 
2353
 
                rec = page_rec_get_prev(rec);
 
2490
                rec = page_rec_get_prev_const(rec);
2354
2491
        }
2355
2492
 
2356
2493
        if (page_rec_is_infimum(rec)) {
2357
2494
 
2358
 
                rec = page_rec_get_next(rec);
 
2495
                rec = page_rec_get_next_const(rec);
2359
2496
        }
2360
2497
 
2361
2498
        if (page_rec_is_supremum(rec)) {
2363
2500
                return(0);
2364
2501
        }
2365
2502
 
2366
 
        first_page_no = ibuf_rec_get_page_no(rec);
2367
 
        first_space_id = ibuf_rec_get_space(rec);
 
2503
        first_page_no = ibuf_rec_get_page_no(mtr, rec);
 
2504
        first_space_id = ibuf_rec_get_space(mtr, rec);
2368
2505
        n_pages = 0;
2369
2506
        prev_page_no = 0;
2370
2507
        prev_space_id = 0;
2375
2512
 
2376
2513
        while (!page_rec_is_infimum(rec) && UNIV_LIKELY(n_pages < limit)) {
2377
2514
 
2378
 
                rec_page_no = ibuf_rec_get_page_no(rec);
2379
 
                rec_space_id = ibuf_rec_get_space(rec);
 
2515
                rec_page_no = ibuf_rec_get_page_no(mtr, rec);
 
2516
                rec_space_id = ibuf_rec_get_space(mtr, rec);
2380
2517
 
2381
2518
                if (rec_space_id != first_space_id
2382
2519
                    || (rec_page_no / IBUF_MERGE_AREA)
2393
2530
                prev_page_no = rec_page_no;
2394
2531
                prev_space_id = rec_space_id;
2395
2532
 
2396
 
                rec = page_rec_get_prev(rec);
 
2533
                rec = page_rec_get_prev_const(rec);
2397
2534
        }
2398
2535
 
2399
 
        rec = page_rec_get_next(rec);
 
2536
        rec = page_rec_get_next_const(rec);
2400
2537
 
2401
2538
        /* At the loop start there is no prev page; we mark this with a pair
2402
2539
        of space id, page no (0, 0) for which there can never be entries in
2414
2551
                        rec_page_no = 1;
2415
2552
                        rec_space_id = 0;
2416
2553
                } else {
2417
 
                        rec_page_no = ibuf_rec_get_page_no(rec);
2418
 
                        rec_space_id = ibuf_rec_get_space(rec);
 
2554
                        rec_page_no = ibuf_rec_get_page_no(mtr, rec);
 
2555
                        rec_space_id = ibuf_rec_get_space(mtr, rec);
2419
2556
                        ut_ad(rec_page_no > IBUF_TREE_ROOT_PAGE_NO);
2420
2557
                }
2421
2558
 
2426
2563
                     || rec_page_no != prev_page_no)
2427
2564
                    && (prev_space_id != 0 || prev_page_no != 0)) {
2428
2565
 
2429
 
                        if ((prev_page_no == first_page_no
2430
 
                             && prev_space_id == first_space_id)
2431
 
                            || contract
 
2566
                        if (contract
 
2567
                            || (prev_page_no == first_page_no
 
2568
                                && prev_space_id == first_space_id)
2432
2569
                            || (volume_for_page
2433
2570
                                > ((IBUF_MERGE_THRESHOLD - 1)
2434
2571
                                   * 4 * UNIV_PAGE_SIZE
2461
2598
                        break;
2462
2599
                }
2463
2600
 
2464
 
                rec_volume = ibuf_rec_get_volume(rec);
 
2601
                rec_volume = ibuf_rec_get_volume(mtr, rec);
2465
2602
 
2466
2603
                volume_for_page += rec_volume;
2467
2604
 
2468
2605
                prev_page_no = rec_page_no;
2469
2606
                prev_space_id = rec_space_id;
2470
2607
 
2471
 
                rec = page_rec_get_next(rec);
 
2608
                rec = page_rec_get_next_const(rec);
2472
2609
        }
2473
2610
 
2474
2611
#ifdef UNIV_IBUF_DEBUG
2503
2640
        mtr_t           mtr;
2504
2641
 
2505
2642
        *n_pages = 0;
2506
 
        ut_ad(!ibuf_inside());
2507
2643
 
2508
2644
        /* We perform a dirty read of ibuf->empty, without latching
2509
2645
        the insert buffer root page. We trust this dirty read except
2512
2648
 
2513
2649
        if (UNIV_UNLIKELY(ibuf->empty)
2514
2650
            && UNIV_LIKELY(!srv_shutdown_state)) {
2515
 
ibuf_is_empty:
2516
 
 
2517
 
#if 0 /* TODO */
2518
 
                if (srv_shutdown_state) {
2519
 
                        /* If the insert buffer becomes empty during
2520
 
                        shutdown, note it in the system tablespace. */
2521
 
 
2522
 
                        trx_sys_set_ibuf_format(TRX_SYS_IBUF_EMPTY);
2523
 
                }
2524
 
 
2525
 
                /* TO DO: call trx_sys_set_ibuf_format() at startup
2526
 
                and whenever ibuf_use is changed to allow buffered
2527
 
                delete-marking or deleting.  Never downgrade the
2528
 
                stamped format except when the insert buffer becomes
2529
 
                empty. */
2530
 
#endif
2531
 
 
2532
2651
                return(0);
2533
2652
        }
2534
2653
 
2535
 
        mtr_start(&mtr);
2536
 
 
2537
 
        ibuf_enter();
 
2654
        ibuf_mtr_start(&mtr);
2538
2655
 
2539
2656
        /* Open a cursor to a randomly chosen leaf of the tree, at a random
2540
2657
        position within the leaf */
2553
2670
                ut_ad(page_get_page_no(btr_pcur_get_page(&pcur))
2554
2671
                      == FSP_IBUF_TREE_ROOT_PAGE_NO);
2555
2672
 
2556
 
                ibuf_exit();
2557
 
 
2558
 
                mtr_commit(&mtr);
 
2673
                ibuf_mtr_commit(&mtr);
2559
2674
                btr_pcur_close(&pcur);
2560
2675
 
2561
 
                goto ibuf_is_empty;
 
2676
                return(0);
2562
2677
        }
2563
2678
 
2564
 
        sum_sizes = ibuf_get_merge_page_nos(TRUE, btr_pcur_get_rec(&pcur),
 
2679
        sum_sizes = ibuf_get_merge_page_nos(TRUE,
 
2680
                                            btr_pcur_get_rec(&pcur), &mtr,
2565
2681
                                            space_ids, space_versions,
2566
2682
                                            page_nos, n_pages);
2567
2683
#if 0 /* defined UNIV_IBUF_DEBUG */
2568
2684
        fprintf(stderr, "Ibuf contract sync %lu pages %lu volume %lu\n",
2569
2685
                sync, *n_pages, sum_sizes);
2570
2686
#endif
2571
 
        ibuf_exit();
2572
 
 
2573
 
        mtr_commit(&mtr);
 
2687
        ibuf_mtr_commit(&mtr);
2574
2688
        btr_pcur_close(&pcur);
2575
2689
 
2576
2690
        buf_read_ibuf_merge_pages(sync, space_ids, space_versions, page_nos,
2714
2828
        return(TRUE);
2715
2829
}
2716
2830
 
 
2831
#ifdef UNIV_DEBUG
 
2832
# define ibuf_get_volume_buffered_count(mtr,rec,hash,size,n_recs)       \
 
2833
        ibuf_get_volume_buffered_count_func(mtr,rec,hash,size,n_recs)
 
2834
#else /* UNIV_DEBUG */
 
2835
# define ibuf_get_volume_buffered_count(mtr,rec,hash,size,n_recs)       \
 
2836
        ibuf_get_volume_buffered_count_func(rec,hash,size,n_recs)
 
2837
#endif
2717
2838
/*********************************************************************//**
2718
2839
Update the estimate of the number of records on a page, and
2719
2840
get the space taken by merging the buffered record to the index page.
2721
2842
taken in the page directory */
2722
2843
static
2723
2844
ulint
2724
 
ibuf_get_volume_buffered_count(
2725
 
/*===========================*/
 
2845
ibuf_get_volume_buffered_count_func(
 
2846
/*================================*/
 
2847
#ifdef UNIV_DEBUG
 
2848
        mtr_t*          mtr,    /*!< in: mini-transaction owning rec */
 
2849
#endif /* UNIV_DEBUG */
2726
2850
        const rec_t*    rec,    /*!< in: insert buffer record */
2727
2851
        ulint*          hash,   /*!< in/out: hash array */
2728
2852
        ulint           size,   /*!< in: number of elements in hash array */
2732
2856
        ulint           len;
2733
2857
        ibuf_op_t       ibuf_op;
2734
2858
        const byte*     types;
2735
 
        ulint           n_fields        = rec_get_n_fields_old(rec);
2736
 
 
2737
 
        ut_ad(ibuf_inside());
 
2859
        ulint           n_fields;
 
2860
 
 
2861
        ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX)
 
2862
              || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX));
 
2863
        ut_ad(ibuf_inside(mtr));
 
2864
 
 
2865
        n_fields = rec_get_n_fields_old(rec);
2738
2866
        ut_ad(n_fields > 4);
2739
2867
        n_fields -= 4;
2740
2868
 
2819
2947
                mem_heap_t*     heap = mem_heap_create(500);
2820
2948
 
2821
2949
                entry = ibuf_build_entry_from_ibuf_rec(
2822
 
                        rec, heap, &dummy_index);
 
2950
                        mtr, rec, heap, &dummy_index);
2823
2951
 
2824
2952
                volume = rec_get_converted_size(dummy_index, entry, 0);
2825
2953
 
2840
2968
ulint
2841
2969
ibuf_get_volume_buffered(
2842
2970
/*=====================*/
2843
 
        btr_pcur_t*     pcur,   /*!< in: pcur positioned at a place in an
 
2971
        const btr_pcur_t*pcur,  /*!< in: pcur positioned at a place in an
2844
2972
                                insert buffer tree where we would insert an
2845
2973
                                entry for the index page whose number is
2846
2974
                                page_no, latch mode has to be BTR_MODIFY_PREV
2850
2978
        lint*           n_recs, /*!< in/out: minimum number of records on the
2851
2979
                                page after the buffered changes have been
2852
2980
                                applied, or NULL to disable the counting */
2853
 
        mtr_t*          mtr)    /*!< in: mtr */
 
2981
        mtr_t*          mtr)    /*!< in: mini-transaction of pcur */
2854
2982
{
2855
 
        ulint   volume;
2856
 
        rec_t*  rec;
2857
 
        page_t* page;
2858
 
        ulint   prev_page_no;
2859
 
        page_t* prev_page;
2860
 
        ulint   next_page_no;
2861
 
        page_t* next_page;
2862
 
        ulint   hash_bitmap[128 / sizeof(ulint)]; /* bitmap of buffered recs */
 
2983
        ulint           volume;
 
2984
        const rec_t*    rec;
 
2985
        const page_t*   page;
 
2986
        ulint           prev_page_no;
 
2987
        const page_t*   prev_page;
 
2988
        ulint           next_page_no;
 
2989
        const page_t*   next_page;
 
2990
        /* bitmap of buffered recs */
 
2991
        ulint           hash_bitmap[128 / sizeof(ulint)];
2863
2992
 
2864
2993
        ut_a(trx_sys_multiple_tablespace_format);
2865
2994
 
2880
3009
        ut_ad(page_validate(page, ibuf->index));
2881
3010
 
2882
3011
        if (page_rec_is_supremum(rec)) {
2883
 
                rec = page_rec_get_prev(rec);
 
3012
                rec = page_rec_get_prev_const(rec);
2884
3013
        }
2885
3014
 
2886
 
        for (;;) {
2887
 
                if (page_rec_is_infimum(rec)) {
2888
 
 
2889
 
                        break;
2890
 
                }
2891
 
 
2892
 
                if (page_no != ibuf_rec_get_page_no(rec)
2893
 
                    || space != ibuf_rec_get_space(rec)) {
2894
 
 
2895
 
                        goto count_later;
2896
 
                }
2897
 
 
2898
 
                volume += ibuf_get_volume_buffered_count(
2899
 
                        rec, hash_bitmap, UT_ARR_SIZE(hash_bitmap), n_recs);
2900
 
 
2901
 
                rec = page_rec_get_prev(rec);
 
3015
        for (; !page_rec_is_infimum(rec);
 
3016
             rec = page_rec_get_prev_const(rec)) {
2902
3017
                ut_ad(page_align(rec) == page);
 
3018
 
 
3019
                if (page_no != ibuf_rec_get_page_no(mtr, rec)
 
3020
                    || space != ibuf_rec_get_space(mtr, rec)) {
 
3021
 
 
3022
                        goto count_later;
 
3023
                }
 
3024
 
 
3025
                volume += ibuf_get_volume_buffered_count(
 
3026
                        mtr, rec,
 
3027
                        hash_bitmap, UT_ARR_SIZE(hash_bitmap), n_recs);
2903
3028
        }
2904
3029
 
2905
3030
        /* Look at the previous page */
2915
3040
                buf_block_t*    block;
2916
3041
 
2917
3042
                block = buf_page_get(
2918
 
                        IBUF_SPACE_ID, 0, prev_page_no, RW_X_LATCH, mtr);
 
3043
                        IBUF_SPACE_ID, 0, prev_page_no, RW_X_LATCH,
 
3044
                        mtr);
2919
3045
 
2920
3046
                buf_block_dbg_add_level(block, SYNC_TREE_NODE);
2921
3047
 
2925
3051
        }
2926
3052
 
2927
3053
#ifdef UNIV_BTR_DEBUG
2928
 
        ut_a(btr_page_get_next(prev_page, mtr)
2929
 
             == page_get_page_no(page));
 
3054
        ut_a(btr_page_get_next(prev_page, mtr) == page_get_page_no(page));
2930
3055
#endif /* UNIV_BTR_DEBUG */
2931
3056
 
2932
3057
        rec = page_get_supremum_rec(prev_page);
2933
 
        rec = page_rec_get_prev(rec);
2934
 
 
2935
 
        for (;;) {
 
3058
        rec = page_rec_get_prev_const(rec);
 
3059
 
 
3060
        for (;; rec = page_rec_get_prev_const(rec)) {
 
3061
                ut_ad(page_align(rec) == prev_page);
 
3062
 
2936
3063
                if (page_rec_is_infimum(rec)) {
2937
3064
 
2938
3065
                        /* We cannot go to yet a previous page, because we
2942
3069
                        return(UNIV_PAGE_SIZE);
2943
3070
                }
2944
3071
 
2945
 
                if (page_no != ibuf_rec_get_page_no(rec)
2946
 
                    || space != ibuf_rec_get_space(rec)) {
 
3072
                if (page_no != ibuf_rec_get_page_no(mtr, rec)
 
3073
                    || space != ibuf_rec_get_space(mtr, rec)) {
2947
3074
 
2948
3075
                        goto count_later;
2949
3076
                }
2950
3077
 
2951
3078
                volume += ibuf_get_volume_buffered_count(
2952
 
                        rec, hash_bitmap, UT_ARR_SIZE(hash_bitmap), n_recs);
2953
 
 
2954
 
                rec = page_rec_get_prev(rec);
2955
 
                ut_ad(page_align(rec) == prev_page);
 
3079
                        mtr, rec,
 
3080
                        hash_bitmap, UT_ARR_SIZE(hash_bitmap), n_recs);
2956
3081
        }
2957
3082
 
2958
3083
count_later:
2959
3084
        rec = btr_pcur_get_rec(pcur);
2960
3085
 
2961
3086
        if (!page_rec_is_supremum(rec)) {
2962
 
                rec = page_rec_get_next(rec);
 
3087
                rec = page_rec_get_next_const(rec);
2963
3088
        }
2964
3089
 
2965
 
        for (;;) {
2966
 
                if (page_rec_is_supremum(rec)) {
2967
 
 
2968
 
                        break;
2969
 
                }
2970
 
 
2971
 
                if (page_no != ibuf_rec_get_page_no(rec)
2972
 
                    || space != ibuf_rec_get_space(rec)) {
 
3090
        for (; !page_rec_is_supremum(rec);
 
3091
             rec = page_rec_get_next_const(rec)) {
 
3092
                if (page_no != ibuf_rec_get_page_no(mtr, rec)
 
3093
                    || space != ibuf_rec_get_space(mtr, rec)) {
2973
3094
 
2974
3095
                        return(volume);
2975
3096
                }
2976
3097
 
2977
3098
                volume += ibuf_get_volume_buffered_count(
2978
 
                        rec, hash_bitmap, UT_ARR_SIZE(hash_bitmap), n_recs);
2979
 
 
2980
 
                rec = page_rec_get_next(rec);
 
3099
                        mtr, rec,
 
3100
                        hash_bitmap, UT_ARR_SIZE(hash_bitmap), n_recs);
2981
3101
        }
2982
3102
 
2983
3103
        /* Look at the next page */
2993
3113
                buf_block_t*    block;
2994
3114
 
2995
3115
                block = buf_page_get(
2996
 
                        IBUF_SPACE_ID, 0, next_page_no, RW_X_LATCH, mtr);
 
3116
                        IBUF_SPACE_ID, 0, next_page_no, RW_X_LATCH,
 
3117
                        mtr);
2997
3118
 
2998
3119
                buf_block_dbg_add_level(block, SYNC_TREE_NODE);
2999
3120
 
3007
3128
#endif /* UNIV_BTR_DEBUG */
3008
3129
 
3009
3130
        rec = page_get_infimum_rec(next_page);
3010
 
        rec = page_rec_get_next(rec);
3011
 
 
3012
 
        for (;;) {
 
3131
        rec = page_rec_get_next_const(rec);
 
3132
 
 
3133
        for (;; rec = page_rec_get_next_const(rec)) {
 
3134
                ut_ad(page_align(rec) == next_page);
 
3135
 
3013
3136
                if (page_rec_is_supremum(rec)) {
3014
3137
 
3015
3138
                        /* We give up */
3017
3140
                        return(UNIV_PAGE_SIZE);
3018
3141
                }
3019
3142
 
3020
 
                if (page_no != ibuf_rec_get_page_no(rec)
3021
 
                    || space != ibuf_rec_get_space(rec)) {
 
3143
                if (page_no != ibuf_rec_get_page_no(mtr, rec)
 
3144
                    || space != ibuf_rec_get_space(mtr, rec)) {
3022
3145
 
3023
3146
                        return(volume);
3024
3147
                }
3025
3148
 
3026
3149
                volume += ibuf_get_volume_buffered_count(
3027
 
                        rec, hash_bitmap, UT_ARR_SIZE(hash_bitmap), n_recs);
3028
 
 
3029
 
                rec = page_rec_get_next(rec);
3030
 
                ut_ad(page_align(rec) == next_page);
 
3150
                        mtr, rec,
 
3151
                        hash_bitmap, UT_ARR_SIZE(hash_bitmap), n_recs);
3031
3152
        }
3032
3153
}
3033
3154
 
3048
3169
 
3049
3170
        ut_a(!dict_table_is_comp(ibuf->index->table));
3050
3171
 
3051
 
        ibuf_enter();
3052
 
 
3053
 
        mtr_start(&mtr);
 
3172
        ibuf_mtr_start(&mtr);
3054
3173
 
3055
3174
        btr_pcur_open_at_index_side(
3056
3175
                FALSE, ibuf->index, BTR_SEARCH_LEAF, &pcur, TRUE, &mtr);
3073
3192
                max_space_id = mach_read_from_4(field);
3074
3193
        }
3075
3194
 
3076
 
        mtr_commit(&mtr);
3077
 
        ibuf_exit();
 
3195
        ibuf_mtr_commit(&mtr);
3078
3196
 
3079
3197
        /* printf("Maximum space id in insert buffer %lu\n", max_space_id); */
3080
3198
 
3081
3199
        fil_set_max_space_id_if_bigger(max_space_id);
3082
3200
}
3083
3201
 
 
3202
#ifdef UNIV_DEBUG
 
3203
# define ibuf_get_entry_counter_low(mtr,rec,space,page_no)      \
 
3204
        ibuf_get_entry_counter_low_func(mtr,rec,space,page_no)
 
3205
#else /* UNIV_DEBUG */
 
3206
# define ibuf_get_entry_counter_low(mtr,rec,space,page_no)      \
 
3207
        ibuf_get_entry_counter_low_func(rec,space,page_no)
 
3208
#endif
3084
3209
/****************************************************************//**
3085
3210
Helper function for ibuf_set_entry_counter. Checks if rec is for (space,
3086
3211
page_no), and if so, reads counter value from it and returns that + 1.
3088
3213
@return new counter value, or 0 */
3089
3214
static
3090
3215
ulint
3091
 
ibuf_get_entry_counter_low(
3092
 
/*=======================*/
 
3216
ibuf_get_entry_counter_low_func(
 
3217
/*============================*/
 
3218
#ifdef UNIV_DEBUG
 
3219
        mtr_t*          mtr,            /*!< in: mini-transaction of rec */
 
3220
#endif /* UNIV_DEBUG */
3093
3221
        const rec_t*    rec,            /*!< in: insert buffer record */
3094
3222
        ulint           space,          /*!< in: space id */
3095
3223
        ulint           page_no)        /*!< in: page number */
3098
3226
        const byte*     field;
3099
3227
        ulint           len;
3100
3228
 
3101
 
        ut_ad(ibuf_inside());
 
3229
        ut_ad(ibuf_inside(mtr));
 
3230
        ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX)
 
3231
              || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX));
3102
3232
        ut_ad(rec_get_n_fields_old(rec) > 2);
3103
3233
 
3104
3234
        field = rec_get_nth_field_old(rec, 1, &len);
3170
3300
        ulint           counter = 0;
3171
3301
 
3172
3302
        /* pcur points to either a user rec or to a page's infimum record. */
 
3303
        ut_ad(ibuf_inside(mtr));
 
3304
        ut_ad(mtr_memo_contains(mtr, btr_pcur_get_block(pcur),
 
3305
                                MTR_MEMO_PAGE_X_FIX));
3173
3306
        ut_ad(page_validate(btr_pcur_get_page(pcur), ibuf->index));
3174
3307
 
3175
3308
        if (btr_pcur_is_on_user_rec(pcur)) {
3176
3309
 
3177
3310
                counter = ibuf_get_entry_counter_low(
3178
 
                        btr_pcur_get_rec(pcur), space, page_no);
 
3311
                        mtr, btr_pcur_get_rec(pcur), space, page_no);
3179
3312
 
3180
3313
                if (UNIV_UNLIKELY(counter == ULINT_UNDEFINED)) {
3181
3314
                        /* The record lacks a counter field.
3231
3364
                        ut_ad(page_rec_is_user_rec(rec));
3232
3365
 
3233
3366
                        counter = ibuf_get_entry_counter_low(
3234
 
                                rec, space, page_no);
 
3367
                                mtr, rec, space, page_no);
3235
3368
 
3236
3369
                        if (UNIV_UNLIKELY(counter == ULINT_UNDEFINED)) {
3237
3370
                                /* The record lacks a counter field.
3383
3516
 
3384
3517
        if (mode == BTR_MODIFY_TREE) {
3385
3518
                for (;;) {
3386
 
                        ibuf_enter();
3387
3519
                        mutex_enter(&ibuf_pessimistic_insert_mutex);
3388
3520
                        mutex_enter(&ibuf_mutex);
3389
3521
 
3394
3526
 
3395
3527
                        mutex_exit(&ibuf_mutex);
3396
3528
                        mutex_exit(&ibuf_pessimistic_insert_mutex);
3397
 
                        ibuf_exit();
3398
3529
 
3399
3530
                        if (UNIV_UNLIKELY(!ibuf_add_free_page())) {
3400
3531
 
3402
3533
                                return(DB_STRONG_FAIL);
3403
3534
                        }
3404
3535
                }
3405
 
        } else {
3406
 
                ibuf_enter();
3407
3536
        }
3408
3537
 
3409
 
        mtr_start(&mtr);
 
3538
        ibuf_mtr_start(&mtr);
3410
3539
 
3411
3540
        btr_pcur_open(ibuf->index, ibuf_entry, PAGE_CUR_LE, mode, &pcur, &mtr);
3412
3541
        ut_ad(page_validate(btr_pcur_get_page(&pcur), ibuf->index));
3461
3590
#ifdef UNIV_IBUF_COUNT_DEBUG
3462
3591
        ut_a((buffered == 0) || ibuf_count_get(space, page_no));
3463
3592
#endif
3464
 
        mtr_start(&bitmap_mtr);
 
3593
        ibuf_mtr_start(&bitmap_mtr);
3465
3594
 
3466
3595
        bitmap_page = ibuf_bitmap_get_map_page(space, page_no,
3467
3596
                                               zip_size, &bitmap_mtr);
3482
3611
                if (buffered + entry_size + page_dir_calc_reserved_space(1)
3483
3612
                    > ibuf_index_page_calc_free_from_bits(zip_size, bits)) {
3484
3613
                        /* Release the bitmap page latch early. */
3485
 
                        mtr_commit(&bitmap_mtr);
 
3614
                        ibuf_mtr_commit(&bitmap_mtr);
3486
3615
 
3487
3616
                        /* It may not fit */
3488
3617
                        do_merge = TRUE;
3489
3618
 
3490
 
                        ibuf_get_merge_page_nos(
3491
 
                                FALSE, btr_pcur_get_rec(&pcur),
3492
 
                                space_ids, space_versions,
3493
 
                                page_nos, &n_stored);
 
3619
                        ibuf_get_merge_page_nos(FALSE,
 
3620
                                                btr_pcur_get_rec(&pcur), &mtr,
 
3621
                                                space_ids, space_versions,
 
3622
                                                page_nos, &n_stored);
3494
3623
 
3495
3624
                        goto fail_exit;
3496
3625
                }
3503
3632
            && !ibuf_set_entry_counter(ibuf_entry, space, page_no, &pcur,
3504
3633
                                       mode == BTR_MODIFY_PREV, &mtr)) {
3505
3634
bitmap_fail:
3506
 
                mtr_commit(&bitmap_mtr);
 
3635
                ibuf_mtr_commit(&bitmap_mtr);
3507
3636
 
3508
3637
                goto fail_exit;
3509
3638
        }
3521
3650
                                          &bitmap_mtr);
3522
3651
        }
3523
3652
 
3524
 
        mtr_commit(&bitmap_mtr);
 
3653
        ibuf_mtr_commit(&bitmap_mtr);
3525
3654
 
3526
3655
        cursor = btr_pcur_get_btr_cur(&pcur);
3527
3656
 
3586
3715
        }
3587
3716
#endif
3588
3717
 
3589
 
        mtr_commit(&mtr);
 
3718
        ibuf_mtr_commit(&mtr);
3590
3719
        btr_pcur_close(&pcur);
3591
 
        ibuf_exit();
3592
3720
 
3593
3721
        mem_heap_free(heap);
3594
3722
 
3846
3974
        page_t*         page            = buf_block_get_frame(block);
3847
3975
        rec_t*          rec;
3848
3976
 
3849
 
        ut_ad(ibuf_inside());
 
3977
        ut_ad(ibuf_inside(mtr));
3850
3978
        ut_ad(dtuple_check_typed(entry));
3851
3979
        ut_ad(!buf_block_align(page)->is_hashed);
3852
3980
 
3993
4121
        page_cur_t      page_cur;
3994
4122
        ulint           low_match;
3995
4123
 
3996
 
        ut_ad(ibuf_inside());
 
4124
        ut_ad(ibuf_inside(mtr));
3997
4125
        ut_ad(dtuple_check_typed(entry));
3998
4126
 
3999
4127
        low_match = page_cur_search(
4050
4178
        page_cur_t      page_cur;
4051
4179
        ulint           low_match;
4052
4180
 
4053
 
        ut_ad(ibuf_inside());
 
4181
        ut_ad(ibuf_inside(mtr));
4054
4182
        ut_ad(dtuple_check_typed(entry));
4055
4183
 
4056
4184
        low_match = page_cur_search(
4138
4266
                /* The tablespace has been dropped.  It is possible
4139
4267
                that another thread has deleted the insert buffer
4140
4268
                entry.  Do not complain. */
4141
 
                btr_pcur_commit_specify_mtr(pcur, mtr);
 
4269
                ibuf_btr_pcur_commit_specify_mtr(pcur, mtr);
4142
4270
        } else {
4143
4271
                fprintf(stderr,
4144
4272
                        "InnoDB: ERROR: Submit the output to"
4156
4284
                              page_rec_get_next(btr_pcur_get_rec(pcur)));
4157
4285
                fflush(stderr);
4158
4286
 
4159
 
                btr_pcur_commit_specify_mtr(pcur, mtr);
 
4287
                ibuf_btr_pcur_commit_specify_mtr(pcur, mtr);
4160
4288
 
4161
4289
                fputs("InnoDB: Validating insert buffer tree:\n", stderr);
4162
4290
                if (!btr_validate_index(ibuf->index, NULL)) {
4180
4308
ibuf_delete_rec(
4181
4309
/*============*/
4182
4310
        ulint           space,  /*!< in: space id */
4183
 
        ulint           page_no,/*!< in: index page number where the record
4184
 
                                should belong */
 
4311
        ulint           page_no,/*!< in: index page number that the record
 
4312
                                should belong to */
4185
4313
        btr_pcur_t*     pcur,   /*!< in: pcur positioned on the record to
4186
4314
                                delete, having latch mode BTR_MODIFY_LEAF */
4187
4315
        const dtuple_t* search_tuple,
4192
4320
        page_t*         root;
4193
4321
        ulint           err;
4194
4322
 
4195
 
        ut_ad(ibuf_inside());
 
4323
        ut_ad(ibuf_inside(mtr));
4196
4324
        ut_ad(page_rec_is_user_rec(btr_pcur_get_rec(pcur)));
4197
 
        ut_ad(ibuf_rec_get_page_no(btr_pcur_get_rec(pcur)) == page_no);
4198
 
        ut_ad(ibuf_rec_get_space(btr_pcur_get_rec(pcur)) == space);
 
4325
        ut_ad(ibuf_rec_get_page_no(mtr, btr_pcur_get_rec(pcur)) == page_no);
 
4326
        ut_ad(ibuf_rec_get_space(mtr, btr_pcur_get_rec(pcur)) == space);
4199
4327
 
4200
4328
        success = btr_cur_optimistic_delete(btr_pcur_get_btr_cur(pcur), mtr);
4201
4329
 
4228
4356
        }
4229
4357
 
4230
4358
        ut_ad(page_rec_is_user_rec(btr_pcur_get_rec(pcur)));
4231
 
        ut_ad(ibuf_rec_get_page_no(btr_pcur_get_rec(pcur)) == page_no);
4232
 
        ut_ad(ibuf_rec_get_space(btr_pcur_get_rec(pcur)) == space);
 
4359
        ut_ad(ibuf_rec_get_page_no(mtr, btr_pcur_get_rec(pcur)) == page_no);
 
4360
        ut_ad(ibuf_rec_get_space(mtr, btr_pcur_get_rec(pcur)) == space);
4233
4361
 
4234
4362
        /* We have to resort to a pessimistic delete from ibuf */
4235
4363
        btr_pcur_store_position(pcur, mtr);
4236
 
 
4237
 
        btr_pcur_commit_specify_mtr(pcur, mtr);
4238
 
 
 
4364
        ibuf_btr_pcur_commit_specify_mtr(pcur, mtr);
 
4365
 
 
4366
        ibuf_mtr_start(mtr);
4239
4367
        mutex_enter(&ibuf_mutex);
4240
4368
 
4241
 
        mtr_start(mtr);
4242
 
 
4243
4369
        if (!ibuf_restore_pos(space, page_no, search_tuple,
4244
4370
                              BTR_MODIFY_TREE, pcur, mtr)) {
4245
4371
 
4246
4372
                mutex_exit(&ibuf_mutex);
 
4373
                ut_ad(!ibuf_inside(mtr));
 
4374
                ut_ad(mtr->state == MTR_COMMITTED);
4247
4375
                goto func_exit;
4248
4376
        }
4249
4377
 
4260
4388
        mutex_exit(&ibuf_mutex);
4261
4389
 
4262
4390
        ibuf->empty = (page_get_n_recs(root) == 0);
4263
 
        btr_pcur_commit_specify_mtr(pcur, mtr);
 
4391
        ibuf_btr_pcur_commit_specify_mtr(pcur, mtr);
4264
4392
 
4265
4393
func_exit:
 
4394
        ut_ad(!ibuf_inside(mtr));
 
4395
        ut_ad(mtr->state == MTR_COMMITTED);
4266
4396
        btr_pcur_close(pcur);
4267
4397
 
4268
4398
        return(TRUE);
4354
4484
                        update_ibuf_bitmap = FALSE;
4355
4485
                } else {
4356
4486
                        page_t* bitmap_page;
 
4487
                        ulint   bitmap_bits;
4357
4488
 
4358
 
                        mtr_start(&mtr);
 
4489
                        ibuf_mtr_start(&mtr);
4359
4490
 
4360
4491
                        bitmap_page = ibuf_bitmap_get_map_page(
4361
4492
                                space, page_no, zip_size, &mtr);
4362
 
 
4363
 
                        if (!ibuf_bitmap_page_get_bits(bitmap_page, page_no,
4364
 
                                                       zip_size,
4365
 
                                                       IBUF_BITMAP_BUFFERED,
4366
 
                                                       &mtr)) {
 
4493
                        bitmap_bits = ibuf_bitmap_page_get_bits(
 
4494
                                bitmap_page, page_no, zip_size,
 
4495
                                IBUF_BITMAP_BUFFERED, &mtr);
 
4496
 
 
4497
                        ibuf_mtr_commit(&mtr);
 
4498
 
 
4499
                        if (!bitmap_bits) {
4367
4500
                                /* No inserts buffered for this page */
4368
 
                                mtr_commit(&mtr);
4369
4501
 
4370
4502
                                if (!tablespace_being_deleted) {
4371
4503
                                        fil_decr_pending_ibuf_merges(space);
4373
4505
 
4374
4506
                                return;
4375
4507
                        }
4376
 
                        mtr_commit(&mtr);
4377
4508
                }
4378
4509
        } else if (block
4379
4510
                   && (ibuf_fixed_addr_page(space, zip_size, page_no)
4382
4513
                return;
4383
4514
        }
4384
4515
 
4385
 
        ibuf_enter();
4386
 
 
4387
4516
        heap = mem_heap_create(512);
4388
4517
 
4389
 
        if (!trx_sys_multiple_tablespace_format) {
 
4518
        if (UNIV_UNLIKELY(!trx_sys_multiple_tablespace_format)) {
4390
4519
                ut_a(trx_doublewrite_must_reset_space_ids);
4391
4520
                search_tuple = ibuf_search_tuple_build(space, page_no, heap);
4392
4521
        } else {
4413
4542
 
4414
4543
                        ut_print_timestamp(stderr);
4415
4544
 
4416
 
                        mtr_start(&mtr);
 
4545
                        ibuf_mtr_start(&mtr);
4417
4546
 
4418
4547
                        fputs("  InnoDB: Dump of the ibuf bitmap page:\n",
4419
4548
                              stderr);
4421
4550
                        bitmap_page = ibuf_bitmap_get_map_page(space, page_no,
4422
4551
                                                               zip_size, &mtr);
4423
4552
                        buf_page_print(bitmap_page, 0);
4424
 
 
4425
 
                        mtr_commit(&mtr);
 
4553
                        ibuf_mtr_commit(&mtr);
4426
4554
 
4427
4555
                        fputs("\nInnoDB: Dump of the page:\n", stderr);
4428
4556
 
4453
4581
        memset(dops, 0, sizeof(dops));
4454
4582
 
4455
4583
loop:
4456
 
        mtr_start(&mtr);
 
4584
        ibuf_mtr_start(&mtr);
4457
4585
 
4458
4586
        if (block) {
4459
4587
                ibool success;
4487
4615
                rec = btr_pcur_get_rec(&pcur);
4488
4616
 
4489
4617
                /* Check if the entry is for this index page */
4490
 
                if (ibuf_rec_get_page_no(rec) != page_no
4491
 
                    || ibuf_rec_get_space(rec) != space) {
 
4618
                if (ibuf_rec_get_page_no(&mtr, rec) != page_no
 
4619
                    || ibuf_rec_get_space(&mtr, rec) != space) {
4492
4620
 
4493
4621
                        if (block) {
4494
4622
                                page_header_reset_last_insert(
4511
4639
                        dtuple_t*       entry;
4512
4640
                        trx_id_t        max_trx_id;
4513
4641
                        dict_index_t*   dummy_index;
4514
 
                        ibuf_op_t       op = ibuf_rec_get_op_type(rec);
 
4642
                        ibuf_op_t       op = ibuf_rec_get_op_type(&mtr, rec);
4515
4643
 
4516
4644
                        max_trx_id = page_get_max_trx_id(page_align(rec));
4517
4645
                        page_update_max_trx_id(block, page_zip, max_trx_id,
4520
4648
                        ut_ad(page_validate(page_align(rec), ibuf->index));
4521
4649
 
4522
4650
                        entry = ibuf_build_entry_from_ibuf_rec(
4523
 
                                rec, heap, &dummy_index);
 
4651
                                &mtr, rec, heap, &dummy_index);
4524
4652
 
4525
4653
                        ut_ad(page_validate(block->frame, dummy_index));
4526
4654
 
4553
4681
                                Store and restore the cursor position. */
4554
4682
                                ut_ad(rec == btr_pcur_get_rec(&pcur));
4555
4683
                                ut_ad(page_rec_is_user_rec(rec));
4556
 
                                ut_ad(ibuf_rec_get_page_no(rec) == page_no);
4557
 
                                ut_ad(ibuf_rec_get_space(rec) == space);
 
4684
                                ut_ad(ibuf_rec_get_page_no(&mtr, rec)
 
4685
                                      == page_no);
 
4686
                                ut_ad(ibuf_rec_get_space(&mtr, rec) == space);
4558
4687
 
4559
4688
                                btr_pcur_store_position(&pcur, &mtr);
4560
 
                                btr_pcur_commit_specify_mtr(&pcur, &mtr);
 
4689
                                ibuf_btr_pcur_commit_specify_mtr(&pcur, &mtr);
4561
4690
 
4562
 
                                mtr_start(&mtr);
 
4691
                                ibuf_mtr_start(&mtr);
4563
4692
 
4564
4693
                                success = buf_page_get_known_nowait(
4565
4694
                                        RW_X_LATCH, block,
4574
4703
                                                      BTR_MODIFY_LEAF,
4575
4704
                                                      &pcur, &mtr)) {
4576
4705
 
4577
 
                                        mtr_commit(&mtr);
 
4706
                                        ut_ad(!ibuf_inside(&mtr));
 
4707
                                        ut_ad(mtr.state == MTR_COMMITTED);
4578
4708
                                        mops[op]++;
4579
4709
                                        ibuf_dummy_index_free(dummy_index);
4580
4710
                                        goto loop;
4589
4719
 
4590
4720
                        ibuf_dummy_index_free(dummy_index);
4591
4721
                } else {
4592
 
                        dops[ibuf_rec_get_op_type(rec)]++;
 
4722
                        dops[ibuf_rec_get_op_type(&mtr, rec)]++;
4593
4723
                }
4594
4724
 
4595
4725
                /* Delete the record from ibuf */
4600
4730
 
4601
4731
                        goto loop;
4602
4732
                } else if (btr_pcur_is_after_last_on_page(&pcur)) {
4603
 
                        mtr_commit(&mtr);
 
4733
                        ibuf_mtr_commit(&mtr);
4604
4734
                        btr_pcur_close(&pcur);
4605
4735
 
4606
4736
                        goto loop;
4634
4764
                }
4635
4765
        }
4636
4766
 
4637
 
        mtr_commit(&mtr);
 
4767
        ibuf_mtr_commit(&mtr);
4638
4768
        btr_pcur_close(&pcur);
4639
4769
        mem_heap_free(heap);
4640
4770
 
4658
4788
                fil_decr_pending_ibuf_merges(space);
4659
4789
        }
4660
4790
 
4661
 
        ibuf_exit();
4662
 
 
4663
4791
#ifdef UNIV_IBUF_COUNT_DEBUG
4664
4792
        ut_a(ibuf_count_get(space, page_no) == 0);
4665
4793
#endif
4679
4807
        mem_heap_t*     heap;
4680
4808
        btr_pcur_t      pcur;
4681
4809
        dtuple_t*       search_tuple;
4682
 
        rec_t*          ibuf_rec;
 
4810
        const rec_t*    ibuf_rec;
4683
4811
        ulint           page_no;
4684
 
        ibool           closed;
4685
4812
        mtr_t           mtr;
4686
4813
 
4687
4814
        /* Counts for discarded operations. */
4696
4823
 
4697
4824
        memset(dops, 0, sizeof(dops));
4698
4825
loop:
4699
 
        ibuf_enter();
4700
 
 
4701
 
        mtr_start(&mtr);
 
4826
        ibuf_mtr_start(&mtr);
4702
4827
 
4703
4828
        /* Position pcur in the insert buffer at the first entry for the
4704
4829
        space */
4718
4843
                ibuf_rec = btr_pcur_get_rec(&pcur);
4719
4844
 
4720
4845
                /* Check if the entry is for this space */
4721
 
                if (ibuf_rec_get_space(ibuf_rec) != space) {
 
4846
                if (ibuf_rec_get_space(&mtr, ibuf_rec) != space) {
4722
4847
 
4723
4848
                        goto leave_loop;
4724
4849
                }
4725
4850
 
4726
 
                page_no = ibuf_rec_get_page_no(ibuf_rec);
 
4851
                page_no = ibuf_rec_get_page_no(&mtr, ibuf_rec);
4727
4852
 
4728
 
                dops[ibuf_rec_get_op_type(ibuf_rec)]++;
 
4853
                dops[ibuf_rec_get_op_type(&mtr, ibuf_rec)]++;
4729
4854
 
4730
4855
                /* Delete the record from ibuf */
4731
 
                closed = ibuf_delete_rec(space, page_no, &pcur, search_tuple,
4732
 
                                         &mtr);
4733
 
                if (closed) {
 
4856
                if (ibuf_delete_rec(space, page_no, &pcur, search_tuple,
 
4857
                                    &mtr)) {
4734
4858
                        /* Deletion was pessimistic and mtr was committed:
4735
4859
                        we start from the beginning again */
4736
4860
 
4737
 
                        ibuf_exit();
4738
 
 
4739
4861
                        goto loop;
4740
4862
                }
4741
4863
 
4742
4864
                if (btr_pcur_is_after_last_on_page(&pcur)) {
4743
 
                        mtr_commit(&mtr);
 
4865
                        ibuf_mtr_commit(&mtr);
4744
4866
                        btr_pcur_close(&pcur);
4745
4867
 
4746
 
                        ibuf_exit();
4747
 
 
4748
4868
                        goto loop;
4749
4869
                }
4750
4870
        }
4751
4871
 
4752
4872
leave_loop:
4753
 
        mtr_commit(&mtr);
 
4873
        ibuf_mtr_commit(&mtr);
4754
4874
        btr_pcur_close(&pcur);
4755
4875
 
4756
4876
#ifdef HAVE_ATOMIC_BUILTINS
4762
4882
        mutex_exit(&ibuf_mutex);
4763
4883
#endif /* HAVE_ATOMIC_BUILTINS */
4764
4884
 
4765
 
        ibuf_exit();
4766
 
 
4767
4885
        mem_heap_free(heap);
4768
4886
}
4769
4887
 
4779
4897
        const page_t*   root;
4780
4898
        mtr_t           mtr;
4781
4899
 
4782
 
        ibuf_enter();
4783
 
        mtr_start(&mtr);
 
4900
        ibuf_mtr_start(&mtr);
4784
4901
 
4785
4902
        mutex_enter(&ibuf_mutex);
4786
4903
        root = ibuf_tree_root_get(&mtr);
4787
4904
        mutex_exit(&ibuf_mutex);
4788
4905
 
4789
4906
        is_empty = (page_get_n_recs(root) == 0);
4790
 
        mtr_commit(&mtr);
4791
 
        ibuf_exit();
4792
 
 
4793
4907
        ut_a(is_empty == ibuf->empty);
 
4908
        ibuf_mtr_commit(&mtr);
4794
4909
 
4795
4910
        return(is_empty);
4796
4911
}