summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2017-06-06 14:59:42 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2017-06-08 11:55:47 +0300
commitfbeb9489cd7d6ad859a49ae5ab8f876f3d988470 (patch)
treecd9a8d916f888a38a684af220abccb8c878c38de
parent68890fe7d48b6fee505f294400224fe01107950c (diff)
downloadmariadb-git-fbeb9489cd7d6ad859a49ae5ab8f876f3d988470.tar.gz
Cleanup of MDEV-12600: crash during install_db with innodb_page_size=32K and ibdata1=3M
The doublewrite buffer pages must fit in the first InnoDB system tablespace data file. The checks that were added in the initial patch (commit 112b21da37dad0fbb28bc65f9ab5a3ba6c0c2186) were at too high level and did not cover all cases. innodb.log_data_file_size: Test all innodb_page_size combinations. fsp_header_init(): Never return an error. Move the change buffer creation to the only caller that needs to do it. btr_create(): Clean up the logic. Remove the error log messages. buf_dblwr_create(): Try to return an error on non-fatal failure. Check that the first data file is big enough for creating the doublewrite buffers. buf_dblwr_process(): Check if the doublewrite buffer is available. Display the message only if it is available. recv_recovery_from_checkpoint_start_func(): Remove a redundant message about FIL_PAGE_FILE_FLUSH_LSN mismatch when crash recovery has already been initiated. fil_report_invalid_page_access(): Simplify the message. fseg_create_general(): Do not emit messages to the error log. innobase_init(): Revert the changes. trx_rseg_create(): Refactor (no functional change).
-rw-r--r--mysql-test/suite/innodb/r/doublewrite.result12
-rw-r--r--mysql-test/suite/innodb/t/doublewrite.test44
-rw-r--r--mysql-test/suite/innodb/t/log_data_file_size.opt2
-rw-r--r--mysql-test/suite/innodb/t/log_data_file_size.test2
-rw-r--r--storage/innobase/btr/btr0btr.cc54
-rw-r--r--storage/innobase/buf/buf0dblwr.cc74
-rw-r--r--storage/innobase/dict/dict0crea.cc6
-rw-r--r--storage/innobase/fil/fil0fil.cc20
-rw-r--r--storage/innobase/fsp/fsp0fsp.cc37
-rw-r--r--storage/innobase/handler/ha_innodb.cc14
-rw-r--r--storage/innobase/include/buf0dblwr.h16
-rw-r--r--storage/innobase/include/fsp0fsp.h14
-rw-r--r--storage/innobase/include/trx0rseg.h11
-rw-r--r--storage/innobase/log/log0recv.cc23
-rw-r--r--storage/innobase/row/row0mysql.cc8
-rw-r--r--storage/innobase/srv/srv0start.cc33
-rw-r--r--storage/innobase/trx/trx0rseg.cc34
-rw-r--r--storage/xtradb/btr/btr0btr.cc54
-rw-r--r--storage/xtradb/buf/buf0dblwr.cc74
-rw-r--r--storage/xtradb/dict/dict0crea.cc6
-rw-r--r--storage/xtradb/fil/fil0fil.cc20
-rw-r--r--storage/xtradb/fsp/fsp0fsp.cc37
-rw-r--r--storage/xtradb/handler/ha_innodb.cc14
-rw-r--r--storage/xtradb/include/buf0dblwr.h16
-rw-r--r--storage/xtradb/include/fsp0fsp.h14
-rw-r--r--storage/xtradb/include/trx0rseg.h11
-rw-r--r--storage/xtradb/log/log0recv.cc23
-rw-r--r--storage/xtradb/row/row0mysql.cc8
-rw-r--r--storage/xtradb/srv/srv0start.cc33
-rw-r--r--storage/xtradb/trx/trx0rseg.cc34
30 files changed, 319 insertions, 429 deletions
diff --git a/mysql-test/suite/innodb/r/doublewrite.result b/mysql-test/suite/innodb/r/doublewrite.result
index 6b913f49972..7cc4a436e5c 100644
--- a/mysql-test/suite/innodb/r/doublewrite.result
+++ b/mysql-test/suite/innodb/r/doublewrite.result
@@ -231,6 +231,7 @@ set global innodb_buf_flush_list_now = 1;
check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
+FOUND /\[ERROR\] InnoDB: .* in tablespace.*test.t1.*/ in mysqld.1.err
select f1, f2 from t1;
f1 f2
1 ############
@@ -238,6 +239,13 @@ f1 f2
3 ////////////
4 ------------
5 ............
-# Test End
-# ---------------------------------------------------------------
drop table t1;
+#
+# MDEV-12600 crash during install_db with innodb_page_size=32K
+# and ibdata1=3M
+#
+SELECT * FROM INFORMATION_SCHEMA.ENGINES
+WHERE engine = 'innodb'
+AND support IN ('YES', 'DEFAULT', 'ENABLED');
+ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
+FOUND /\[ERROR\] InnoDB: Cannot create doublewrite buffer/ in mysqld.1.err
diff --git a/mysql-test/suite/innodb/t/doublewrite.test b/mysql-test/suite/innodb/t/doublewrite.test
index b4604a44731..aba3d6ecff5 100644
--- a/mysql-test/suite/innodb/t/doublewrite.test
+++ b/mysql-test/suite/innodb/t/doublewrite.test
@@ -4,7 +4,7 @@
--echo # PAGE OF SYSTEM TABLESPACE
--echo #
---source include/have_innodb.inc
+--source include/innodb_page_size.inc
--source include/have_debug.inc
--source include/not_embedded.inc
@@ -15,12 +15,17 @@ call mtr.add_suppression("space header page consists of zero bytes.*test.t1");
call mtr.add_suppression("checksum mismatch in tablespace.*test.t1");
call mtr.add_suppression("Current page size .* != page size on page");
call mtr.add_suppression("innodb-page-size mismatch in tablespace.*test.t1");
-call mtr.add_suppression("Trying to recover page.*from the doublewrite buffer");
+call mtr.add_suppression("InnoDB: New log files created");
+call mtr.add_suppression("InnoDB: Cannot create doublewrite buffer: the first file in innodb_data_file_path must be at least (3|6|12)M\\.");
+call mtr.add_suppression("InnoDB: Database creation was aborted");
+call mtr.add_suppression("Plugin 'InnoDB' (init function returned error|registration as a STORAGE ENGINE failed)");
--enable_query_log
--source include/restart_mysqld.inc
let INNODB_PAGE_SIZE=`select @@innodb_page_size`;
let MYSQLD_DATADIR=`select @@datadir`;
+let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err;
+let SEARCH_RANGE= -50000;
show variables like 'innodb_doublewrite';
show variables like 'innodb_fil_make_page_dirty_debug';
@@ -393,9 +398,38 @@ EOF
--source include/start_mysqld.inc
check table t1;
-select f1, f2 from t1;
+--let SEARCH_PATTERN= \[ERROR\] InnoDB: .* in tablespace.*test.t1.*
+--source include/search_pattern_in_file.inc
---echo # Test End
---echo # ---------------------------------------------------------------
+select f1, f2 from t1;
drop table t1;
+
+--echo #
+--echo # MDEV-12600 crash during install_db with innodb_page_size=32K
+--echo # and ibdata1=3M
+--echo #
+let bugdir= $MYSQLTEST_VARDIR/tmp/doublewrite;
+--mkdir $bugdir
+
+let $check_no_innodb=SELECT * FROM INFORMATION_SCHEMA.ENGINES
+WHERE engine = 'innodb'
+AND support IN ('YES', 'DEFAULT', 'ENABLED');
+
+--let $ibp=--innodb-log-group-home-dir=$bugdir --innodb-data-home-dir=$bugdir
+--let $ibd=$ibp --innodb-undo-tablespaces=0 --innodb-log-files-in-group=2
+--let $ibp=$ibp --innodb-data-file-path=ibdata1:1M;ibdata2:1M:autoextend
+
+--let $restart_parameters= $ibp
+--source include/restart_mysqld.inc
+eval $check_no_innodb;
+--let SEARCH_PATTERN= \[ERROR\] InnoDB: Cannot create doublewrite buffer
+--source include/search_pattern_in_file.inc
+--let $restart_parameters=
+--source include/restart_mysqld.inc
+
+--remove_file $bugdir/ibdata1
+--remove_file $bugdir/ibdata2
+--remove_file $bugdir/ib_logfile0
+--remove_file $bugdir/ib_logfile1
+--rmdir $bugdir
diff --git a/mysql-test/suite/innodb/t/log_data_file_size.opt b/mysql-test/suite/innodb/t/log_data_file_size.opt
index fe36abe4701..d9a364a3287 100644
--- a/mysql-test/suite/innodb/t/log_data_file_size.opt
+++ b/mysql-test/suite/innodb/t/log_data_file_size.opt
@@ -1,2 +1,2 @@
--loose-innodb-sys-indexes
---innodb-data-file-path=ibdata1:3M:autoextend
+--innodb-data-file-path=ibdata1:1M:autoextend
diff --git a/mysql-test/suite/innodb/t/log_data_file_size.test b/mysql-test/suite/innodb/t/log_data_file_size.test
index 9328f3bbe6d..2f1c497595b 100644
--- a/mysql-test/suite/innodb/t/log_data_file_size.test
+++ b/mysql-test/suite/innodb/t/log_data_file_size.test
@@ -1,4 +1,4 @@
---source include/have_innodb.inc
+--source include/innodb_page_size.inc
--source include/not_embedded.inc
let INNODB_PAGE_SIZE=`select @@innodb_page_size`;
diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc
index e200a2b9677..b7afcf12b39 100644
--- a/storage/innobase/btr/btr0btr.cc
+++ b/storage/innobase/btr/btr0btr.cc
@@ -2,7 +2,7 @@
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2014, 2017, MariaDB Corporation
+Copyright (c) 2014, 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -1684,9 +1684,7 @@ btr_create(
dict_index_t* index, /*!< in: index */
mtr_t* mtr) /*!< in: mini-transaction handle */
{
- ulint page_no;
buf_block_t* block;
- buf_frame_t* frame;
page_t* page;
page_zip_des_t* page_zip;
@@ -1702,9 +1700,7 @@ btr_create(
IBUF_HEADER + IBUF_TREE_SEG_HEADER, mtr);
if (ibuf_hdr_block == NULL) {
- ib_logf(IB_LOG_LEVEL_ERROR,
- "Allocation of the first ibuf header page failed.");
- return (FIL_NULL);
+ return(FIL_NULL);
}
buf_block_dbg_add_level(
@@ -1721,11 +1717,16 @@ btr_create(
IBUF_TREE_ROOT_PAGE_NO,
FSP_UP, mtr);
- if (!block) {
- ib_logf(IB_LOG_LEVEL_ERROR,
- "Allocation of the tree root page segment failed.");
+ if (block == NULL) {
+ return(FIL_NULL);
}
+
ut_ad(buf_block_get_page_no(block) == IBUF_TREE_ROOT_PAGE_NO);
+
+ buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE_NEW);
+
+ flst_init(block->frame + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST,
+ mtr);
} else {
#ifdef UNIV_BLOB_DEBUG
if ((type & DICT_CLUSTERED) && !index->blobs) {
@@ -1738,41 +1739,18 @@ btr_create(
block = fseg_create(space, 0,
PAGE_HEADER + PAGE_BTR_SEG_TOP, mtr);
- if (!block) {
- ib_logf(IB_LOG_LEVEL_ERROR,
- "Allocation of the btree segment failed.");
+ if (block == NULL) {
+ return(FIL_NULL);
}
- }
-
- if (block == NULL) {
-
- return(FIL_NULL);
- }
-
- page_no = buf_block_get_page_no(block);
- frame = buf_block_get_frame(block);
-
- if (type & DICT_IBUF) {
- /* It is an insert buffer tree: initialize the free list */
- buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE_NEW);
-
- ut_ad(page_no == IBUF_TREE_ROOT_PAGE_NO);
-
- flst_init(frame + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST, mtr);
- } else {
- /* It is a non-ibuf tree: create a file segment for leaf
- pages */
buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW);
- if (!fseg_create(space, page_no,
+ if (!fseg_create(space, buf_block_get_page_no(block),
PAGE_HEADER + PAGE_BTR_SEG_LEAF, mtr)) {
/* Not enough space for new segment, free root
segment before return. */
- btr_free_root(space, zip_size, page_no, mtr);
-
- ib_logf(IB_LOG_LEVEL_ERROR,
- "Allocation of the non-ibuf tree segment for leaf pages failed.");
+ btr_free_root(space, zip_size,
+ buf_block_get_page_no(block), mtr);
return(FIL_NULL);
}
@@ -1816,7 +1794,7 @@ btr_create(
ut_ad(page_get_max_insert_size(page, 2) > 2 * BTR_PAGE_MAX_REC_SIZE);
- return(page_no);
+ return(buf_block_get_page_no(block));
}
/************************************************************//**
diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc
index e2c7ae9bae1..8ff5428d3a5 100644
--- a/storage/innobase/buf/buf0dblwr.cc
+++ b/storage/innobase/buf/buf0dblwr.cc
@@ -175,13 +175,14 @@ buf_dblwr_init(
mem_zalloc(buf_size * sizeof(void*)));
}
-/****************************************************************//**
-Creates the doublewrite buffer to a new InnoDB installation. The header of the
-doublewrite buffer is placed on the trx system header page. */
+/** Create the doublewrite buffer if the doublewrite buffer header
+is not present in the TRX_SYS page.
+@return whether the operation succeeded
+@retval true if the doublewrite buffer exists or was created
+@retval false if the creation failed (too small first data file) */
UNIV_INTERN
-void
-buf_dblwr_create(void)
-/*==================*/
+bool
+buf_dblwr_create()
{
buf_block_t* block2;
buf_block_t* new_block;
@@ -194,8 +195,7 @@ buf_dblwr_create(void)
if (buf_dblwr) {
/* Already inited */
-
- return;
+ return(true);
}
start_again:
@@ -213,39 +213,59 @@ start_again:
mtr_commit(&mtr);
buf_dblwr_being_created = FALSE;
- return;
+ return(true);
}
- ib_logf(IB_LOG_LEVEL_INFO,
- "Doublewrite buffer not found: creating new");
-
if (buf_pool_get_curr_size()
< ((TRX_SYS_DOUBLEWRITE_BLOCKS * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE
+ FSP_EXTENT_SIZE / 2 + 100)
* UNIV_PAGE_SIZE)) {
- ib_logf(IB_LOG_LEVEL_FATAL,
- "Cannot create doublewrite buffer: you must "
- "increase your buffer pool size. Cannot continue "
- "operation.");
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "Cannot create doublewrite buffer: "
+ "innodb_buffer_pool_size is too small.");
+ mtr_commit(&mtr);
+ return(false);
+ } else {
+ fil_space_t* space = fil_space_acquire(TRX_SYS_SPACE);
+ const bool fail = UT_LIST_GET_FIRST(space->chain)->size
+ < 3 * FSP_EXTENT_SIZE;
+ fil_space_release(space);
+
+ if (fail) {
+ goto too_small;
+ }
}
block2 = fseg_create(TRX_SYS_SPACE, TRX_SYS_PAGE_NO,
TRX_SYS_DOUBLEWRITE
+ TRX_SYS_DOUBLEWRITE_FSEG, &mtr);
+ if (block2 == NULL) {
+too_small:
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "Cannot create doublewrite buffer: "
+ "the first file in innodb_data_file_path"
+ " must be at least %luM.",
+ 3 * (FSP_EXTENT_SIZE * UNIV_PAGE_SIZE) >> 20);
+ mtr_commit(&mtr);
+ return(false);
+ }
+
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "Doublewrite buffer not found: creating new");
+
+ /* FIXME: After this point, the doublewrite buffer creation
+ is not atomic. The doublewrite buffer should not exist in
+ the InnoDB system tablespace file in the first place.
+ It could be located in separate optional file(s) in a
+ user-specified location. */
+
/* fseg_create acquires a second latch on the page,
therefore we must declare it: */
buf_block_dbg_add_level(block2, SYNC_NO_ORDER_CHECK);
- if (block2 == NULL) {
- ib_logf(IB_LOG_LEVEL_FATAL,
- "Cannot create doublewrite buffer: you must "
- "increase your tablespace size. "
- "Cannot continue operation.");
- }
-
fseg_header = doublewrite + TRX_SYS_DOUBLEWRITE_FSEG;
prev_page_no = 0;
@@ -482,6 +502,14 @@ buf_dblwr_process()
byte* unaligned_read_buf;
recv_dblwr_t& recv_dblwr = recv_sys->dblwr;
+ if (!buf_dblwr) {
+ return;
+ }
+
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "Restoring possible half-written data pages "
+ "from the doublewrite buffer...");
+
unaligned_read_buf = static_cast<byte*>(ut_malloc(2 * UNIV_PAGE_SIZE));
read_buf = static_cast<byte*>(
diff --git a/storage/innobase/dict/dict0crea.cc b/storage/innobase/dict/dict0crea.cc
index 1ec7123bbc2..f6cd294884b 100644
--- a/storage/innobase/dict/dict0crea.cc
+++ b/storage/innobase/dict/dict0crea.cc
@@ -321,13 +321,9 @@ dict_build_table_def_step(
mtr_start(&mtr);
- bool res = fsp_header_init(table->space, FIL_IBD_FILE_INITIAL_SIZE, &mtr);
+ fsp_header_init(table->space, FIL_IBD_FILE_INITIAL_SIZE, &mtr);
mtr_commit(&mtr);
-
- if (!res) {
- return (DB_ERROR);
- }
} else {
/* Create in the system tablespace: disallow Barracuda
features by keeping only the first bit which says whether
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index e19ef110b4f..f88bb2add59 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2014, 2017, MariaDB Corporation. All Rights Reserved.
+Copyright (c) 2014, 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -5812,21 +5812,19 @@ fil_report_invalid_page_access(
ulint len, /*!< in: I/O length */
ulint type) /*!< in: I/O type */
{
- ib_logf(IB_LOG_LEVEL_ERROR,
+ ib_logf(IB_LOG_LEVEL_FATAL,
"Trying to access page number " ULINTPF
" in space " ULINTPF
" space name %s,"
" which is outside the tablespace bounds."
- " Byte offset " ULINTPF ", len " ULINTPF " i/o type " ULINTPF ".",
+ " Byte offset " ULINTPF ", len " ULINTPF
+ " i/o type " ULINTPF ".%s",
block_offset, space_id, space_name,
- byte_offset, len, type);
-
- ib_logf(IB_LOG_LEVEL_FATAL,
- "If you get this error at mysqld startup,"
- " please check that"
- " your my.cnf matches the ibdata files"
- " that you have in the"
- " MySQL server.");
+ byte_offset, len, type,
+ space_id == 0 && !srv_was_started
+ ? "Please check that the configuration matches"
+ " the InnoDB system tablespace location (ibdata files)"
+ : "");
}
/********************************************************************//**
diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc
index 98cd11f3369..4f05549bc1c 100644
--- a/storage/innobase/fsp/fsp0fsp.cc
+++ b/storage/innobase/fsp/fsp0fsp.cc
@@ -670,18 +670,13 @@ fsp_header_init_fields(
}
#ifndef UNIV_HOTBACKUP
-/** Initializes the space header of a new created space and creates also the
-insert buffer tree root if space == 0.
+/** Initialize a tablespace header.
@param[in] space_id space id
@param[in] size current size in blocks
-@param[in,out] mtr min-transaction
-@return true on success, otherwise false. */
+@param[in,out] mtr mini-transaction */
UNIV_INTERN
-bool
-fsp_header_init(
- ulint space_id,
- ulint size,
- mtr_t* mtr)
+void
+fsp_header_init(ulint space_id, ulint size, mtr_t* mtr)
{
fsp_header_t* header;
buf_block_t* block;
@@ -725,17 +720,7 @@ fsp_header_init(
mlog_write_ull(header + FSP_SEG_ID, 1, mtr);
- if (space_id == 0) {
- fsp_fill_free_list(FALSE, space_id, header, mtr);
-
- if (btr_create(DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF,
- 0, 0, DICT_IBUF_ID_MIN + space_id,
- dict_ind_redundant, mtr) == FIL_NULL) {
- return (false);
- }
- } else {
- fsp_fill_free_list(TRUE, space_id, header, mtr);
- }
+ fsp_fill_free_list(space_id != TRX_SYS_SPACE, space_id, header, mtr);
fil_space_t* space = fil_space_acquire(space_id);
ut_ad(space);
@@ -745,8 +730,6 @@ fsp_header_init(
}
fil_space_release(space);
-
- return (true);
}
#endif /* !UNIV_HOTBACKUP */
@@ -2065,10 +2048,6 @@ fseg_create_general(
success = fsp_reserve_free_extents(&n_reserved, space, 2,
FSP_NORMAL, mtr);
if (!success) {
- ib_logf(IB_LOG_LEVEL_ERROR,
- "Reserving %d free extents failed"
- " could reserve only " ULINTPF " extents.",
- 2, n_reserved);
return(NULL);
}
}
@@ -2078,9 +2057,6 @@ fseg_create_general(
inode = fsp_alloc_seg_inode(space_header, mtr);
if (inode == NULL) {
- ib_logf(IB_LOG_LEVEL_ERROR,
- "Allocation of a new file segment inode page failed.");
-
goto funct_exit;
}
@@ -2109,9 +2085,6 @@ fseg_create_general(
inode, 0, FSP_UP, mtr, mtr);
if (block == NULL) {
- ib_logf(IB_LOG_LEVEL_ERROR,
- "Allocation of a free page from space " ULINTPF " failed.",
- space);
fsp_free_seg_inode(space, zip_size, inode, mtr);
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index b68a96c8846..012539d1ace 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -3353,7 +3353,6 @@ innobase_init(
char *default_path;
uint format_id;
ulong num_pll_degree;
- ulint min_size = 0;
DBUG_ENTER("innobase_init");
handlerton *innobase_hton= (handlerton*) p;
@@ -3564,19 +3563,6 @@ mem_free_and_error:
goto error;
}
- /* All doublewrite buffer pages must fit to first system
- datafile and first datafile must be at least 3M. */
- min_size = ut_max((3*1024*1024U), (192U*UNIV_PAGE_SIZE));
-
- if ((srv_data_file_sizes[0]*1024*1024) < min_size) {
- sql_print_error(
- "InnoDB: first datafile is too small current=" ULINTPF
- "M it should be at least " ULINTPF "M.",
- srv_data_file_sizes[0],
- min_size / (1024 * 1024));
- goto mem_free_and_error;
- }
-
/* -------------- All log files ---------------------------*/
/* The default dir for log files is the datadir of MySQL */
diff --git a/storage/innobase/include/buf0dblwr.h b/storage/innobase/include/buf0dblwr.h
index 8e1b00db83c..7b7464761cc 100644
--- a/storage/innobase/include/buf0dblwr.h
+++ b/storage/innobase/include/buf0dblwr.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation. All Rights Reserved.
+Copyright (c) 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -39,13 +39,15 @@ extern buf_dblwr_t* buf_dblwr;
/** Set to TRUE when the doublewrite buffer is being created */
extern ibool buf_dblwr_being_created;
-/****************************************************************//**
-Creates the doublewrite buffer to a new InnoDB installation. The header of the
-doublewrite buffer is placed on the trx system header page. */
+/** Create the doublewrite buffer if the doublewrite buffer header
+is not present in the TRX_SYS page.
+@return whether the operation succeeded
+@retval true if the doublewrite buffer exists or was created
+@retval false if the creation failed (too small first data file) */
UNIV_INTERN
-void
-buf_dblwr_create(void);
-/*==================*/
+bool
+buf_dblwr_create()
+ MY_ATTRIBUTE((warn_unused_result));
/****************************************************************//**
At a database startup initializes the doublewrite buffer memory structure if
diff --git a/storage/innobase/include/fsp0fsp.h b/storage/innobase/include/fsp0fsp.h
index 905e98cc1e6..d8d044ba2ec 100644
--- a/storage/innobase/include/fsp0fsp.h
+++ b/storage/innobase/include/fsp0fsp.h
@@ -520,19 +520,13 @@ fsp_header_init_fields(
ulint space_id, /*!< in: space id */
ulint flags); /*!< in: tablespace flags (FSP_SPACE_FLAGS):
0, or table->flags if newer than COMPACT */
-/** Initializes the space header of a new created space and creates also the
-insert buffer tree root if space == 0.
+/** Initialize a tablespace header.
@param[in] space_id space id
@param[in] size current size in blocks
-@param[in,out] mtr min-transaction
-@return true on success, otherwise false. */
+@param[in,out] mtr mini-transaction */
UNIV_INTERN
-bool
-fsp_header_init(
- ulint space_id,
- ulint size,
- mtr_t* mtr)
- MY_ATTRIBUTE((warn_unused_result));
+void
+fsp_header_init(ulint space_id, ulint size, mtr_t* mtr);
/**********************************************************************//**
Increases the space size field of a space. */
diff --git a/storage/innobase/include/trx0rseg.h b/storage/innobase/include/trx0rseg.h
index 185b05876b4..2fe5df14cee 100644
--- a/storage/innobase/include/trx0rseg.h
+++ b/storage/innobase/include/trx0rseg.h
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -124,13 +125,13 @@ trx_rseg_mem_free(
/*==============*/
trx_rseg_t* rseg); /*!< in, own: instance to free */
-/*********************************************************************
-Creates a rollback segment. */
+/** Create a rollback segment.
+@param[in] space undo tablespace ID
+@return pointer to new rollback segment
+@retval NULL on failure */
UNIV_INTERN
trx_rseg_t*
-trx_rseg_create(
-/*============*/
- ulint space); /*!< in: id of UNDO tablespace */
+trx_rseg_create(ulint space);
/********************************************************************
Get the number of unique rollback tablespaces in use except space id 0.
diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc
index bf00cd8e8d9..4e6e66e808e 100644
--- a/storage/innobase/log/log0recv.cc
+++ b/storage/innobase/log/log0recv.cc
@@ -2914,11 +2914,6 @@ recv_init_crash_recovery(void)
possible */
if (srv_force_recovery < SRV_FORCE_NO_LOG_REDO) {
-
- ib_logf(IB_LOG_LEVEL_INFO,
- "Restoring possible half-written data pages "
- "from the doublewrite buffer...");
-
buf_dblwr_process();
/* Spawn the background thread to flush dirty pages
@@ -3179,24 +3174,6 @@ recv_recovery_from_checkpoint_start_func(
user about recovery: */
if (checkpoint_lsn != flushed_lsn) {
-
- if (checkpoint_lsn < flushed_lsn) {
-
- ib_logf(IB_LOG_LEVEL_WARN,
- "The log sequence number "
- "in the ibdata files is higher "
- "than the log sequence number "
- "in the ib_logfiles! Are you sure "
- "you are using the right "
- "ib_logfiles to start up the database. "
- "Log sequence number in the "
- "ib_logfiles is " LSN_PF ", log"
- "sequence number stamped "
- "to ibdata file header is " LSN_PF ".",
- checkpoint_lsn,
- flushed_lsn);
- }
-
if (!recv_needed_recovery) {
ib_logf(IB_LOG_LEVEL_INFO,
"The log sequence number "
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index 6ca9443dc7d..82938995e93 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -3590,15 +3590,9 @@ row_truncate_table_for_mysql(
} while (index);
mtr_start_trx(&mtr, trx);
- bool ret = fsp_header_init(space_id,
+ fsp_header_init(space_id,
FIL_IBD_FILE_INITIAL_SIZE, &mtr);
mtr_commit(&mtr);
-
- if (!ret) {
- table->file_unreadable = true;
- err = DB_ERROR;
- goto funct_exit;
- }
}
} else {
/* Lock all index trees for this table, as we will
diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc
index 4e59ddd1f87..c7026b4f04a 100644
--- a/storage/innobase/srv/srv0start.cc
+++ b/storage/innobase/srv/srv0start.cc
@@ -1561,26 +1561,18 @@ srv_undo_tablespaces_init(
if (create_new_db) {
mtr_t mtr;
- bool ret=true;
mtr_start(&mtr);
/* The undo log tablespace */
for (i = 0; i < n_undo_tablespaces; ++i) {
- ret = fsp_header_init(
+ fsp_header_init(
undo_tablespace_ids[i],
SRV_UNDO_TABLESPACE_SIZE_IN_PAGES, &mtr);
- if (!ret) {
- break;
- }
}
mtr_commit(&mtr);
-
- if (!ret) {
- return (srv_init_abort(create_new_db, __FILE__, __LINE__, DB_ERROR));
- }
}
return(DB_SUCCESS);
@@ -2419,14 +2411,24 @@ files_checked:
mtr_start(&mtr);
- bool ret = fsp_header_init(0, sum_of_new_sizes, &mtr);
+ fsp_header_init(0, sum_of_new_sizes, &mtr);
+ compile_time_assert(TRX_SYS_SPACE == 0);
+ compile_time_assert(IBUF_SPACE_ID == 0);
+
+ ulint ibuf_root = btr_create(
+ DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF,
+ 0, 0, DICT_IBUF_ID_MIN,
+ dict_ind_redundant, &mtr);
mtr_commit(&mtr);
- if (!ret) {
- return (srv_init_abort(create_new_db, __FILE__, __LINE__, DB_ERROR));
+ if (ibuf_root == FIL_NULL) {
+ return(srv_init_abort(true, __FILE__, __LINE__,
+ DB_ERROR));
}
+ ut_ad(ibuf_root == IBUF_TREE_ROOT_PAGE_NO);
+
/* To maintain backward compatibility we create only
the first rollback segment before the double write buffer.
All the remaining rollback segments will be created later,
@@ -2812,10 +2814,9 @@ files_checked:
/* fprintf(stderr, "Max allowed record size %lu\n",
page_get_free_space_of_empty() / 2); */
- if (buf_dblwr == NULL) {
- /* Create the doublewrite buffer to a new tablespace */
-
- buf_dblwr_create();
+ if (!buf_dblwr_create()) {
+ return(srv_init_abort(create_new_db, __FILE__, __LINE__,
+ DB_ERROR));
}
/* Here the double write buffer has already been created and so
diff --git a/storage/innobase/trx/trx0rseg.cc b/storage/innobase/trx/trx0rseg.cc
index 21dbab98e48..16fa334872b 100644
--- a/storage/innobase/trx/trx0rseg.cc
+++ b/storage/innobase/trx/trx0rseg.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -293,14 +294,13 @@ trx_rseg_create_instance(
}
}
-/*********************************************************************
-Creates a rollback segment.
-@return pointer to new rollback segment if create successful */
+/** Create a rollback segment.
+@param[in] space undo tablespace ID
+@return pointer to new rollback segment
+@retval NULL on failure */
UNIV_INTERN
trx_rseg_t*
-trx_rseg_create(
-/*============*/
- ulint space) /*!< in: id of UNDO tablespace */
+trx_rseg_create(ulint space)
{
mtr_t mtr;
ulint slot_no;
@@ -323,25 +323,21 @@ trx_rseg_create(
page_no = trx_rseg_header_create(
space, 0, ULINT_MAX, slot_no, &mtr);
- if (page_no == FIL_NULL) {
- mtr_commit(&mtr);
- return (rseg);
- }
-
- sys_header = trx_sysf_get(&mtr);
+ if (page_no != FIL_NULL) {
+ sys_header = trx_sysf_get(&mtr);
- id = trx_sysf_rseg_get_space(sys_header, slot_no, &mtr);
- ut_a(id == space);
+ id = trx_sysf_rseg_get_space(sys_header, slot_no, &mtr);
+ ut_a(id == space);
- zip_size = space ? fil_space_get_zip_size(space) : 0;
+ zip_size = space ? fil_space_get_zip_size(space) : 0;
- rseg = trx_rseg_mem_create(
- slot_no, space, zip_size, page_no,
- purge_sys->ib_bh, &mtr);
+ rseg = trx_rseg_mem_create(
+ slot_no, space, zip_size, page_no,
+ purge_sys->ib_bh, &mtr);
+ }
}
mtr_commit(&mtr);
-
return(rseg);
}
diff --git a/storage/xtradb/btr/btr0btr.cc b/storage/xtradb/btr/btr0btr.cc
index 7b5b3bb6cba..e66599e206d 100644
--- a/storage/xtradb/btr/btr0btr.cc
+++ b/storage/xtradb/btr/btr0btr.cc
@@ -2,7 +2,7 @@
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2014, 2017, MariaDB Corporation
+Copyright (c) 2014, 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -1703,9 +1703,7 @@ btr_create(
dict_index_t* index, /*!< in: index */
mtr_t* mtr) /*!< in: mini-transaction handle */
{
- ulint page_no;
buf_block_t* block;
- buf_frame_t* frame;
page_t* page;
page_zip_des_t* page_zip;
@@ -1721,9 +1719,7 @@ btr_create(
IBUF_HEADER + IBUF_TREE_SEG_HEADER, mtr);
if (ibuf_hdr_block == NULL) {
- ib_logf(IB_LOG_LEVEL_ERROR,
- "Allocation of the first ibuf header page failed.");
- return (FIL_NULL);
+ return(FIL_NULL);
}
buf_block_dbg_add_level(
@@ -1740,11 +1736,16 @@ btr_create(
IBUF_TREE_ROOT_PAGE_NO,
FSP_UP, mtr);
- if (!block) {
- ib_logf(IB_LOG_LEVEL_ERROR,
- "Allocation of the tree root page segment failed.");
+ if (block == NULL) {
+ return(FIL_NULL);
}
+
ut_ad(buf_block_get_page_no(block) == IBUF_TREE_ROOT_PAGE_NO);
+
+ buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE_NEW);
+
+ flst_init(block->frame + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST,
+ mtr);
} else {
#ifdef UNIV_BLOB_DEBUG
if ((type & DICT_CLUSTERED) && !index->blobs) {
@@ -1757,41 +1758,18 @@ btr_create(
block = fseg_create(space, 0,
PAGE_HEADER + PAGE_BTR_SEG_TOP, mtr);
- if (!block) {
- ib_logf(IB_LOG_LEVEL_ERROR,
- "Allocation of the btree segment failed.");
+ if (block == NULL) {
+ return(FIL_NULL);
}
- }
-
- if (block == NULL) {
-
- return(FIL_NULL);
- }
-
- page_no = buf_block_get_page_no(block);
- frame = buf_block_get_frame(block);
-
- if (type & DICT_IBUF) {
- /* It is an insert buffer tree: initialize the free list */
- buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE_NEW);
-
- ut_ad(page_no == IBUF_TREE_ROOT_PAGE_NO);
-
- flst_init(frame + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST, mtr);
- } else {
- /* It is a non-ibuf tree: create a file segment for leaf
- pages */
buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW);
- if (!fseg_create(space, page_no,
+ if (!fseg_create(space, buf_block_get_page_no(block),
PAGE_HEADER + PAGE_BTR_SEG_LEAF, mtr)) {
/* Not enough space for new segment, free root
segment before return. */
- btr_free_root(space, zip_size, page_no, mtr);
-
- ib_logf(IB_LOG_LEVEL_ERROR,
- "Allocation of the non-ibuf tree segment for leaf pages failed.");
+ btr_free_root(space, zip_size,
+ buf_block_get_page_no(block), mtr);
return(FIL_NULL);
}
@@ -1835,7 +1813,7 @@ btr_create(
ut_ad(page_get_max_insert_size(page, 2) > 2 * BTR_PAGE_MAX_REC_SIZE);
- return(page_no);
+ return(buf_block_get_page_no(block));
}
/************************************************************//**
diff --git a/storage/xtradb/buf/buf0dblwr.cc b/storage/xtradb/buf/buf0dblwr.cc
index c0c52deb57f..49371f9a6f1 100644
--- a/storage/xtradb/buf/buf0dblwr.cc
+++ b/storage/xtradb/buf/buf0dblwr.cc
@@ -175,13 +175,14 @@ buf_dblwr_init(
mem_zalloc(buf_size * sizeof(void*)));
}
-/****************************************************************//**
-Creates the doublewrite buffer to a new InnoDB installation. The header of the
-doublewrite buffer is placed on the trx system header page. */
+/** Create the doublewrite buffer if the doublewrite buffer header
+is not present in the TRX_SYS page.
+@return whether the operation succeeded
+@retval true if the doublewrite buffer exists or was created
+@retval false if the creation failed (too small first data file) */
UNIV_INTERN
-void
-buf_dblwr_create(void)
-/*==================*/
+bool
+buf_dblwr_create()
{
buf_block_t* block2;
buf_block_t* new_block;
@@ -194,8 +195,7 @@ buf_dblwr_create(void)
if (buf_dblwr) {
/* Already inited */
-
- return;
+ return(true);
}
start_again:
@@ -213,39 +213,59 @@ start_again:
mtr_commit(&mtr);
buf_dblwr_being_created = FALSE;
- return;
+ return(true);
}
- ib_logf(IB_LOG_LEVEL_INFO,
- "Doublewrite buffer not found: creating new");
-
if (buf_pool_get_curr_size()
< ((TRX_SYS_DOUBLEWRITE_BLOCKS * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE
+ FSP_EXTENT_SIZE / 2 + 100)
* UNIV_PAGE_SIZE)) {
- ib_logf(IB_LOG_LEVEL_FATAL,
- "Cannot create doublewrite buffer: you must "
- "increase your buffer pool size. Cannot continue "
- "operation.");
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "Cannot create doublewrite buffer: "
+ "innodb_buffer_pool_size is too small.");
+ mtr_commit(&mtr);
+ return(false);
+ } else {
+ fil_space_t* space = fil_space_acquire(TRX_SYS_SPACE);
+ const bool fail = UT_LIST_GET_FIRST(space->chain)->size
+ < 3 * FSP_EXTENT_SIZE;
+ fil_space_release(space);
+
+ if (fail) {
+ goto too_small;
+ }
}
block2 = fseg_create(TRX_SYS_SPACE, TRX_SYS_PAGE_NO,
TRX_SYS_DOUBLEWRITE
+ TRX_SYS_DOUBLEWRITE_FSEG, &mtr);
+ if (block2 == NULL) {
+too_small:
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "Cannot create doublewrite buffer: "
+ "the first file in innodb_data_file_path"
+ " must be at least %luM.",
+ 3 * (FSP_EXTENT_SIZE * UNIV_PAGE_SIZE) >> 20);
+ mtr_commit(&mtr);
+ return(false);
+ }
+
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "Doublewrite buffer not found: creating new");
+
+ /* FIXME: After this point, the doublewrite buffer creation
+ is not atomic. The doublewrite buffer should not exist in
+ the InnoDB system tablespace file in the first place.
+ It could be located in separate optional file(s) in a
+ user-specified location. */
+
/* fseg_create acquires a second latch on the page,
therefore we must declare it: */
buf_block_dbg_add_level(block2, SYNC_NO_ORDER_CHECK);
- if (block2 == NULL) {
- ib_logf(IB_LOG_LEVEL_FATAL,
- "Cannot create doublewrite buffer: you must "
- "increase your tablespace size. "
- "Cannot continue operation.");
- }
-
fseg_header = doublewrite + TRX_SYS_DOUBLEWRITE_FSEG;
prev_page_no = 0;
@@ -482,6 +502,14 @@ buf_dblwr_process()
byte* unaligned_read_buf;
recv_dblwr_t& recv_dblwr = recv_sys->dblwr;
+ if (!buf_dblwr) {
+ return;
+ }
+
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "Restoring possible half-written data pages "
+ "from the doublewrite buffer...");
+
unaligned_read_buf = static_cast<byte*>(ut_malloc(2 * UNIV_PAGE_SIZE));
read_buf = static_cast<byte*>(
diff --git a/storage/xtradb/dict/dict0crea.cc b/storage/xtradb/dict/dict0crea.cc
index faaa6d1bdc7..6d5b12474eb 100644
--- a/storage/xtradb/dict/dict0crea.cc
+++ b/storage/xtradb/dict/dict0crea.cc
@@ -323,13 +323,9 @@ dict_build_table_def_step(
mtr_start(&mtr);
- bool res = fsp_header_init(table->space, FIL_IBD_FILE_INITIAL_SIZE, &mtr);
+ fsp_header_init(table->space, FIL_IBD_FILE_INITIAL_SIZE, &mtr);
mtr_commit(&mtr);
-
- if(!res) {
- return (DB_ERROR);
- }
} else {
/* Create in the system tablespace: disallow Barracuda
features by keeping only the first bit which says whether
diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc
index b669d35ff15..d979c05c9a6 100644
--- a/storage/xtradb/fil/fil0fil.cc
+++ b/storage/xtradb/fil/fil0fil.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2014, 2017, MariaDB Corporation. All Rights Reserved.
+Copyright (c) 2014, 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -6115,21 +6115,19 @@ fil_report_invalid_page_access(
ulint len, /*!< in: I/O length */
ulint type) /*!< in: I/O type */
{
- ib_logf(IB_LOG_LEVEL_ERROR,
+ ib_logf(IB_LOG_LEVEL_FATAL,
"Trying to access page number " ULINTPF
" in space " ULINTPF
" space name %s,"
" which is outside the tablespace bounds."
- " Byte offset " ULINTPF ", len " ULINTPF " i/o type " ULINTPF ".",
+ " Byte offset " ULINTPF ", len " ULINTPF
+ " i/o type " ULINTPF ".%s",
block_offset, space_id, space_name,
- byte_offset, len, type);
-
- ib_logf(IB_LOG_LEVEL_FATAL,
- "If you get this error at mysqld startup,"
- " please check that"
- " your my.cnf matches the ibdata files"
- " that you have in the"
- " MySQL server.");
+ byte_offset, len, type,
+ space_id == 0 && !srv_was_started
+ ? "Please check that the configuration matches"
+ " the InnoDB system tablespace location (ibdata files)"
+ : "");
}
/********************************************************************//**
diff --git a/storage/xtradb/fsp/fsp0fsp.cc b/storage/xtradb/fsp/fsp0fsp.cc
index 7929372ae6c..bd87b88f58d 100644
--- a/storage/xtradb/fsp/fsp0fsp.cc
+++ b/storage/xtradb/fsp/fsp0fsp.cc
@@ -673,18 +673,13 @@ fsp_header_init_fields(
}
#ifndef UNIV_HOTBACKUP
-/** Initializes the space header of a new created space and creates also the
-insert buffer tree root if space == 0.
+/** Initialize a tablespace header.
@param[in] space_id space id
@param[in] size current size in blocks
-@param[in,out] mtr min-transaction
-@return true on success, otherwise false. */
+@param[in,out] mtr mini-transaction */
UNIV_INTERN
-bool
-fsp_header_init(
- ulint space_id,
- ulint size,
- mtr_t* mtr)
+void
+fsp_header_init(ulint space_id, ulint size, mtr_t* mtr)
{
fsp_header_t* header;
buf_block_t* block;
@@ -728,17 +723,7 @@ fsp_header_init(
mlog_write_ull(header + FSP_SEG_ID, 1, mtr);
- if (space_id == 0) {
- fsp_fill_free_list(FALSE, space_id, header, mtr);
-
- if (btr_create(DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF,
- 0, 0, DICT_IBUF_ID_MIN + space_id,
- dict_ind_redundant, mtr) == FIL_NULL) {
- return (false);
- }
- } else {
- fsp_fill_free_list(TRUE, space_id, header, mtr);
- }
+ fsp_fill_free_list(space_id != TRX_SYS_SPACE, space_id, header, mtr);
fil_space_t* space = fil_space_acquire(space_id);
ut_ad(space);
@@ -748,8 +733,6 @@ fsp_header_init(
}
fil_space_release(space);
-
- return (true);
}
#endif /* !UNIV_HOTBACKUP */
@@ -2074,10 +2057,6 @@ fseg_create_general(
success = fsp_reserve_free_extents(&n_reserved, space, 2,
FSP_NORMAL, mtr);
if (!success) {
- ib_logf(IB_LOG_LEVEL_ERROR,
- "Reserving %d free extents failed"
- " could reserve only " ULINTPF " extents.",
- 2, n_reserved);
return(NULL);
}
}
@@ -2087,9 +2066,6 @@ fseg_create_general(
inode = fsp_alloc_seg_inode(space_header, mtr);
if (inode == NULL) {
- ib_logf(IB_LOG_LEVEL_ERROR,
- "Allocation of a new file segment inode page failed.");
-
goto funct_exit;
}
@@ -2118,9 +2094,6 @@ fseg_create_general(
inode, 0, FSP_UP, mtr, mtr);
if (block == NULL) {
- ib_logf(IB_LOG_LEVEL_ERROR,
- "Allocation of a free page from space " ULINTPF " failed.",
- space);
fsp_free_seg_inode(space, zip_size, inode, mtr);
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index 7be6c64407b..dd5d041aed9 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -3770,7 +3770,6 @@ innobase_init(
char *default_path;
uint format_id;
ulong num_pll_degree;
- ulint min_size = 0;
DBUG_ENTER("innobase_init");
handlerton *innobase_hton= (handlerton*) p;
@@ -4021,19 +4020,6 @@ mem_free_and_error:
goto error;
}
- /* All doublewrite buffer pages must fit to first system
- datafile and first datafile must be at least 3M. */
- min_size = ut_max((3*1024*1024U), (192U*UNIV_PAGE_SIZE));
-
- if ((srv_data_file_sizes[0]*1024*1024) < min_size) {
- sql_print_error(
- "InnoDB: first datafile is too small current=" ULINTPF
- "M it should be at least " ULINTPF "M.",
- srv_data_file_sizes[0],
- min_size / (1024 * 1024));
- goto mem_free_and_error;
- }
-
/* -------------- All log files ---------------------------*/
/* The default dir for log files is the datadir of MySQL */
diff --git a/storage/xtradb/include/buf0dblwr.h b/storage/xtradb/include/buf0dblwr.h
index 8e1b00db83c..7b7464761cc 100644
--- a/storage/xtradb/include/buf0dblwr.h
+++ b/storage/xtradb/include/buf0dblwr.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation. All Rights Reserved.
+Copyright (c) 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -39,13 +39,15 @@ extern buf_dblwr_t* buf_dblwr;
/** Set to TRUE when the doublewrite buffer is being created */
extern ibool buf_dblwr_being_created;
-/****************************************************************//**
-Creates the doublewrite buffer to a new InnoDB installation. The header of the
-doublewrite buffer is placed on the trx system header page. */
+/** Create the doublewrite buffer if the doublewrite buffer header
+is not present in the TRX_SYS page.
+@return whether the operation succeeded
+@retval true if the doublewrite buffer exists or was created
+@retval false if the creation failed (too small first data file) */
UNIV_INTERN
-void
-buf_dblwr_create(void);
-/*==================*/
+bool
+buf_dblwr_create()
+ MY_ATTRIBUTE((warn_unused_result));
/****************************************************************//**
At a database startup initializes the doublewrite buffer memory structure if
diff --git a/storage/xtradb/include/fsp0fsp.h b/storage/xtradb/include/fsp0fsp.h
index d8f851a0846..715572199ab 100644
--- a/storage/xtradb/include/fsp0fsp.h
+++ b/storage/xtradb/include/fsp0fsp.h
@@ -519,19 +519,13 @@ fsp_header_init_fields(
ulint space_id, /*!< in: space id */
ulint flags); /*!< in: tablespace flags (FSP_SPACE_FLAGS):
0, or table->flags if newer than COMPACT */
-/** Initializes the space header of a new created space and creates also the
-insert buffer tree root if space == 0.
+/** Initialize a tablespace header.
@param[in] space_id space id
@param[in] size current size in blocks
-@param[in,out] mtr min-transaction
-@return true on success, otherwise false. */
+@param[in,out] mtr mini-transaction */
UNIV_INTERN
-bool
-fsp_header_init(
- ulint space_id,
- ulint size,
- mtr_t* mtr)
- MY_ATTRIBUTE((warn_unused_result));
+void
+fsp_header_init(ulint space_id, ulint size, mtr_t* mtr);
/**********************************************************************//**
Increases the space size field of a space. */
diff --git a/storage/xtradb/include/trx0rseg.h b/storage/xtradb/include/trx0rseg.h
index b9c84ef2b06..e2853df7045 100644
--- a/storage/xtradb/include/trx0rseg.h
+++ b/storage/xtradb/include/trx0rseg.h
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -124,13 +125,13 @@ trx_rseg_mem_free(
/*==============*/
trx_rseg_t* rseg); /*!< in, own: instance to free */
-/*********************************************************************
-Creates a rollback segment. */
+/** Create a rollback segment.
+@param[in] space undo tablespace ID
+@return pointer to new rollback segment
+@retval NULL on failure */
UNIV_INTERN
trx_rseg_t*
-trx_rseg_create(
-/*============*/
- ulint space); /*!< in: id of UNDO tablespace */
+trx_rseg_create(ulint space);
/********************************************************************
Get the number of unique rollback tablespaces in use except space id 0.
diff --git a/storage/xtradb/log/log0recv.cc b/storage/xtradb/log/log0recv.cc
index 037bc9d35d3..fb64309cee4 100644
--- a/storage/xtradb/log/log0recv.cc
+++ b/storage/xtradb/log/log0recv.cc
@@ -3004,11 +3004,6 @@ recv_init_crash_recovery(void)
possible */
if (srv_force_recovery < SRV_FORCE_NO_LOG_REDO) {
-
- ib_logf(IB_LOG_LEVEL_INFO,
- "Restoring possible half-written data pages "
- "from the doublewrite buffer...");
-
buf_dblwr_process();
/* Spawn the background thread to flush dirty pages
@@ -3276,24 +3271,6 @@ recv_recovery_from_checkpoint_start_func(
user about recovery: */
if (checkpoint_lsn != flushed_lsn) {
-
- if (checkpoint_lsn <flushed_lsn) {
-
- ib_logf(IB_LOG_LEVEL_WARN,
- "The log sequence number "
- "in the ibdata files is higher "
- "than the log sequence number "
- "in the ib_logfiles! Are you sure "
- "you are using the right "
- "ib_logfiles to start up the database. "
- "Log sequence number in the "
- "ib_logfiles is " LSN_PF ", log"
- "sequence number stamped "
- "to ibdata file header is " LSN_PF ".",
- checkpoint_lsn,
- flushed_lsn);
- }
-
if (!recv_needed_recovery) {
ib_logf(IB_LOG_LEVEL_INFO,
"The log sequence number "
diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc
index 9f1f216bccb..59568f5c91b 100644
--- a/storage/xtradb/row/row0mysql.cc
+++ b/storage/xtradb/row/row0mysql.cc
@@ -3614,15 +3614,9 @@ row_truncate_table_for_mysql(
} while (index);
mtr_start_trx(&mtr, trx);
- bool ret = fsp_header_init(space_id,
+ fsp_header_init(space_id,
FIL_IBD_FILE_INITIAL_SIZE, &mtr);
mtr_commit(&mtr);
-
- if (!ret) {
- table->file_unreadable = true;
- err = DB_ERROR;
- goto funct_exit;
- }
}
} else {
/* Lock all index trees for this table, as we will
diff --git a/storage/xtradb/srv/srv0start.cc b/storage/xtradb/srv/srv0start.cc
index cbab9b2f8c4..6fd8e8944f5 100644
--- a/storage/xtradb/srv/srv0start.cc
+++ b/storage/xtradb/srv/srv0start.cc
@@ -1601,26 +1601,18 @@ srv_undo_tablespaces_init(
if (create_new_db) {
mtr_t mtr;
- bool ret=true;
mtr_start(&mtr);
/* The undo log tablespace */
for (i = 0; i < n_undo_tablespaces; ++i) {
- ret = fsp_header_init(
+ fsp_header_init(
undo_tablespace_ids[i],
SRV_UNDO_TABLESPACE_SIZE_IN_PAGES, &mtr);
- if (!ret) {
- break;
- }
}
mtr_commit(&mtr);
-
- if (!ret) {
- return (srv_init_abort(create_new_db, __FILE__, __LINE__, DB_ERROR));
- }
}
return(DB_SUCCESS);
@@ -2507,14 +2499,24 @@ files_checked:
mtr_start(&mtr);
- bool ret = fsp_header_init(0, sum_of_new_sizes, &mtr);
+ fsp_header_init(0, sum_of_new_sizes, &mtr);
+ compile_time_assert(TRX_SYS_SPACE == 0);
+ compile_time_assert(IBUF_SPACE_ID == 0);
+
+ ulint ibuf_root = btr_create(
+ DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF,
+ 0, 0, DICT_IBUF_ID_MIN,
+ dict_ind_redundant, &mtr);
mtr_commit(&mtr);
- if (!ret) {
- return (srv_init_abort(create_new_db, __FILE__, __LINE__, DB_ERROR));
+ if (ibuf_root == FIL_NULL) {
+ return(srv_init_abort(true, __FILE__, __LINE__,
+ DB_ERROR));
}
+ ut_ad(ibuf_root == IBUF_TREE_ROOT_PAGE_NO);
+
/* To maintain backward compatibility we create only
the first rollback segment before the double write buffer.
All the remaining rollback segments will be created later,
@@ -2901,10 +2903,9 @@ files_checked:
/* fprintf(stderr, "Max allowed record size %lu\n",
page_get_free_space_of_empty() / 2); */
- if (buf_dblwr == NULL) {
- /* Create the doublewrite buffer to a new tablespace */
-
- buf_dblwr_create();
+ if (!buf_dblwr_create()) {
+ return(srv_init_abort(create_new_db, __FILE__, __LINE__,
+ DB_ERROR));
}
/* Here the double write buffer has already been created and so
diff --git a/storage/xtradb/trx/trx0rseg.cc b/storage/xtradb/trx/trx0rseg.cc
index 21dbab98e48..16fa334872b 100644
--- a/storage/xtradb/trx/trx0rseg.cc
+++ b/storage/xtradb/trx/trx0rseg.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -293,14 +294,13 @@ trx_rseg_create_instance(
}
}
-/*********************************************************************
-Creates a rollback segment.
-@return pointer to new rollback segment if create successful */
+/** Create a rollback segment.
+@param[in] space undo tablespace ID
+@return pointer to new rollback segment
+@retval NULL on failure */
UNIV_INTERN
trx_rseg_t*
-trx_rseg_create(
-/*============*/
- ulint space) /*!< in: id of UNDO tablespace */
+trx_rseg_create(ulint space)
{
mtr_t mtr;
ulint slot_no;
@@ -323,25 +323,21 @@ trx_rseg_create(
page_no = trx_rseg_header_create(
space, 0, ULINT_MAX, slot_no, &mtr);
- if (page_no == FIL_NULL) {
- mtr_commit(&mtr);
- return (rseg);
- }
-
- sys_header = trx_sysf_get(&mtr);
+ if (page_no != FIL_NULL) {
+ sys_header = trx_sysf_get(&mtr);
- id = trx_sysf_rseg_get_space(sys_header, slot_no, &mtr);
- ut_a(id == space);
+ id = trx_sysf_rseg_get_space(sys_header, slot_no, &mtr);
+ ut_a(id == space);
- zip_size = space ? fil_space_get_zip_size(space) : 0;
+ zip_size = space ? fil_space_get_zip_size(space) : 0;
- rseg = trx_rseg_mem_create(
- slot_no, space, zip_size, page_no,
- purge_sys->ib_bh, &mtr);
+ rseg = trx_rseg_mem_create(
+ slot_no, space, zip_size, page_no,
+ purge_sys->ib_bh, &mtr);
+ }
}
mtr_commit(&mtr);
-
return(rseg);
}