Skip to content

Commit e6bb88e

Browse files
committed
Bug#22179133 - INNODB: TOO SMALL BUFFER POOL FOR INNODB_PAGE_SIZE=64K
Problem: -------- When initializing rollback segment headers(max TRX_SYS_N_RSEGS), all rollback segment headers are accessed using single mtr. With buf_pool_size of 5M and innodb_page_size=64k, the maximum number of pages available is 80. When a single mtr accesses more than 80 pages, all the blocks are buffer fixed and cannot be replaced from buf pool. So we cannot find a free block. Fix: ---- Access each rollback segment header in a separate mini-transaction. Reviewed-By: Marko Mäkelä <[email protected]> RB: 11367
1 parent f80b757 commit e6bb88e

File tree

5 files changed

+32
-28
lines changed

5 files changed

+32
-28
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--innodb_buffer_pool_size=5M

mysql-test/suite/innodb/t/innodb_64k.test

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@
66
# Test COMPRESSED table
77
-- source suite/innodb/include/create_options_invalid.inc
88

9+
# This test is run with 5M buffer pool size
10+
let $buf_pool_size = `SELECT @@innodb_buffer_pool_size`;
11+
12+
if ($buf_pool_size != 5242880) {
13+
--skip "Test requires 5M buffer pool size"
14+
}
15+
916
# Test max inline field length should < 16384.
1017
CREATE TABLE t1 (id int, a TEXT) ROW_FORMAT=COMPACT;
1118

storage/innobase/include/trx0rseg.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*****************************************************************************
22
3-
Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved.
3+
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
44
55
This program is free software; you can redistribute it and/or modify it under
66
the terms of the GNU General Public License as published by the Free Software
@@ -122,9 +122,8 @@ rseg array in trx_sys at a database startup. */
122122
void
123123
trx_rseg_array_init(
124124
/*================*/
125-
trx_sysf_t* sys_header, /*!< in/out: trx system header */
126-
purge_pq_t* purge_queue, /*!< in: rseg queue */
127-
mtr_t* mtr); /*!< in/out: mtr */
125+
purge_pq_t* purge_queue); /*!< in: rseg queue */
126+
128127
/***************************************************************************
129128
Free's an instance of the rollback segment in memory. */
130129
void

storage/innobase/trx/trx0rseg.cc

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -319,15 +319,19 @@ static
319319
void
320320
trx_rseg_create_instance(
321321
/*=====================*/
322-
trx_sysf_t* sys_header, /*!< in: trx system header */
323-
purge_pq_t* purge_queue, /*!< in/out: rseg queue */
324-
mtr_t* mtr) /*!< in: mtr */
322+
purge_pq_t* purge_queue) /*!< in/out: rseg queue */
325323
{
326324
ulint i;
327325

328326
for (i = 0; i < TRX_SYS_N_RSEGS; i++) {
329327
ulint page_no;
330328

329+
mtr_t mtr;
330+
mtr.start();
331+
trx_sysf_t* sys_header = trx_sysf_get(&mtr);
332+
333+
page_no = trx_sysf_rseg_get_page_no(sys_header, i, &mtr);
334+
331335
/* Slot-1....Slot-n are reserved for non-redo rsegs.
332336
Non-redo rsegs are recreated on server re-start so
333337
avoid initializing the existing non-redo rsegs. */
@@ -337,20 +341,15 @@ trx_rseg_create_instance(
337341
in range from slot-1....slot-n needs to be scheduled
338342
for purge if there are pending purge operation. */
339343
trx_rseg_schedule_pending_purge(
340-
sys_header, purge_queue, i, mtr);
344+
sys_header, purge_queue, i, &mtr);
341345

342-
continue;
343-
}
344-
345-
page_no = trx_sysf_rseg_get_page_no(sys_header, i, mtr);
346-
347-
if (page_no != FIL_NULL) {
346+
} else if (page_no != FIL_NULL) {
348347
ulint space;
349348
trx_rseg_t* rseg = NULL;
350349

351350
ut_a(!trx_rseg_get_on_id(i, true));
352351

353-
space = trx_sysf_rseg_get_space(sys_header, i, mtr);
352+
space = trx_sysf_rseg_get_space(sys_header, i, &mtr);
354353

355354
bool found = true;
356355
const page_size_t& page_size
@@ -365,12 +364,13 @@ trx_rseg_create_instance(
365364

366365
rseg = trx_rseg_mem_create(
367366
i, space, page_no, page_size,
368-
purge_queue, rseg_array, mtr);
367+
purge_queue, rseg_array, &mtr);
369368

370369
ut_a(rseg->id == i);
371370
} else {
372371
ut_a(trx_sys->rseg_array[i] == NULL);
373372
}
373+
mtr.commit();
374374
}
375375
}
376376

@@ -447,13 +447,11 @@ rseg array in trx_sys at a database startup. */
447447
void
448448
trx_rseg_array_init(
449449
/*================*/
450-
trx_sysf_t* sys_header, /* in/out: trx system header */
451-
purge_pq_t* purge_queue, /*!< in: rseg queue */
452-
mtr_t* mtr) /*!< in: mtr */
450+
purge_pq_t* purge_queue) /*!< in: rseg queue */
453451
{
454452
trx_sys->rseg_history_len = 0;
455453

456-
trx_rseg_create_instance(sys_header, purge_queue, mtr);
454+
trx_rseg_create_instance(purge_queue);
457455
}
458456

459457
/********************************************************************

storage/innobase/trx/trx0sys.cc

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,6 @@ purge_pq_t*
453453
trx_sys_init_at_db_start(void)
454454
/*==========================*/
455455
{
456-
mtr_t mtr;
457456
purge_pq_t* purge_queue;
458457
trx_sysf_t* sys_header;
459458
ib_uint64_t rows_to_undo = 0;
@@ -465,12 +464,8 @@ trx_sys_init_at_db_start(void)
465464
purge_queue = UT_NEW_NOKEY(purge_pq_t());
466465
ut_a(purge_queue != NULL);
467466

468-
mtr_start(&mtr);
469-
470-
sys_header = trx_sysf_get(&mtr);
471-
472467
if (srv_force_recovery < SRV_FORCE_NO_UNDO_LOG_SCAN) {
473-
trx_rseg_array_init(sys_header, purge_queue, &mtr);
468+
trx_rseg_array_init(purge_queue);
474469
}
475470

476471
/* VERY important: after the database is started, max_trx_id value is
@@ -480,11 +475,17 @@ trx_sys_init_at_db_start(void)
480475
to the disk-based header! Thus trx id values will not overlap when
481476
the database is repeatedly started! */
482477

478+
mtr_t mtr;
479+
mtr.start();
480+
481+
sys_header = trx_sysf_get(&mtr);
482+
483483
trx_sys->max_trx_id = 2 * TRX_SYS_TRX_ID_WRITE_MARGIN
484484
+ ut_uint64_align_up(mach_read_from_8(sys_header
485485
+ TRX_SYS_TRX_ID_STORE),
486486
TRX_SYS_TRX_ID_WRITE_MARGIN);
487487

488+
mtr.commit();
488489
ut_d(trx_sys->rw_max_trx_id = trx_sys->max_trx_id);
489490

490491
trx_dummy_sess = sess_open();
@@ -527,8 +528,6 @@ trx_sys_init_at_db_start(void)
527528

528529
trx_sys_mutex_exit();
529530

530-
mtr_commit(&mtr);
531-
532531
return(purge_queue);
533532
}
534533

0 commit comments

Comments
 (0)