summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/suite/innodb/t/log_data_file_size.opt2
-rw-r--r--storage/innobase/btr/btr0btr.cc19
-rw-r--r--storage/innobase/dict/dict0crea.cc6
-rw-r--r--storage/innobase/fil/fil0fil.cc42
-rw-r--r--storage/innobase/fsp/fsp0fsp.cc37
-rw-r--r--storage/innobase/handler/ha_innodb.cc14
-rw-r--r--storage/innobase/include/fsp0fsp.h20
-rw-r--r--storage/innobase/row/row0mysql.cc8
-rw-r--r--storage/innobase/srv/srv0start.cc52
-rw-r--r--storage/innobase/trx/trx0rseg.cc5
-rw-r--r--storage/xtradb/btr/btr0btr.cc19
-rw-r--r--storage/xtradb/dict/dict0crea.cc6
-rw-r--r--storage/xtradb/fil/fil0fil.cc42
-rw-r--r--storage/xtradb/fsp/fsp0fsp.cc37
-rw-r--r--storage/xtradb/handler/ha_innodb.cc14
-rw-r--r--storage/xtradb/include/fsp0fsp.h20
-rw-r--r--storage/xtradb/row/row0mysql.cc8
-rw-r--r--storage/xtradb/srv/srv0start.cc52
-rw-r--r--storage/xtradb/trx/trx0rseg.cc5
19 files changed, 319 insertions, 89 deletions
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 d9a364a3287..fe36abe4701 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:1M:autoextend
+--innodb-data-file-path=ibdata1:3M:autoextend
diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc
index cccae031b88..e200a2b9677 100644
--- a/storage/innobase/btr/btr0btr.cc
+++ b/storage/innobase/btr/btr0btr.cc
@@ -1701,6 +1701,12 @@ btr_create(
space, 0,
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);
+ }
+
buf_block_dbg_add_level(
ibuf_hdr_block, SYNC_IBUF_TREE_NODE_NEW);
@@ -1714,6 +1720,11 @@ btr_create(
+ IBUF_HEADER + IBUF_TREE_SEG_HEADER,
IBUF_TREE_ROOT_PAGE_NO,
FSP_UP, mtr);
+
+ if (!block) {
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "Allocation of the tree root page segment failed.");
+ }
ut_ad(buf_block_get_page_no(block) == IBUF_TREE_ROOT_PAGE_NO);
} else {
#ifdef UNIV_BLOB_DEBUG
@@ -1726,6 +1737,12 @@ btr_create(
#endif /* UNIV_BLOB_DEBUG */
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) {
@@ -1754,6 +1771,8 @@ btr_create(
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.");
return(FIL_NULL);
}
diff --git a/storage/innobase/dict/dict0crea.cc b/storage/innobase/dict/dict0crea.cc
index f6cd294884b..1ec7123bbc2 100644
--- a/storage/innobase/dict/dict0crea.cc
+++ b/storage/innobase/dict/dict0crea.cc
@@ -321,9 +321,13 @@ dict_build_table_def_step(
mtr_start(&mtr);
- fsp_header_init(table->space, FIL_IBD_FILE_INITIAL_SIZE, &mtr);
+ bool res = 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 9d4a464460f..e19ef110b4f 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -5812,19 +5812,21 @@ fil_report_invalid_page_access(
ulint len, /*!< in: I/O length */
ulint type) /*!< in: I/O type */
{
- fprintf(stderr,
- "InnoDB: Error: trying to access page number %lu"
- " in space %lu,\n"
- "InnoDB: space name %s,\n"
- "InnoDB: which is outside the tablespace bounds.\n"
- "InnoDB: Byte offset %lu, len %lu, i/o type %lu.\n"
- "InnoDB: If you get this error at mysqld startup,"
- " please check that\n"
- "InnoDB: your my.cnf matches the ibdata files"
- " that you have in the\n"
- "InnoDB: MySQL server.\n",
- (ulong) block_offset, (ulong) space_id, space_name,
- (ulong) byte_offset, (ulong) len, (ulong) type);
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "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 ".",
+ 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.");
}
/********************************************************************//**
@@ -6043,11 +6045,10 @@ fil_io(
mutex_exit(&fil_system->mutex);
return(DB_ERROR);
}
+
fil_report_invalid_page_access(
block_offset, space_id, space->name,
byte_offset, len, type);
-
- ut_error;
}
/* Open file if closed */
@@ -6059,10 +6060,11 @@ fil_io(
ib_logf(IB_LOG_LEVEL_ERROR,
"Trying to do i/o to a tablespace which "
"exists without .ibd data file. "
- "i/o type %lu, space id %lu, page no %lu, "
- "i/o length %lu bytes",
- (ulong) type, (ulong) space_id,
- (ulong) block_offset, (ulong) len);
+ "i/o type " ULINTPF ", space id "
+ ULINTPF ", page no " ULINTPF ", "
+ "i/o length " ULINTPF " bytes",
+ type, space_id,
+ block_offset, len);
return(DB_TABLESPACE_DELETED);
}
@@ -6082,8 +6084,6 @@ fil_io(
fil_report_invalid_page_access(
block_offset, space_id, space->name, byte_offset,
len, type);
-
- ut_error;
}
/* Now we have made the changes in the data structures of fil_system */
diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc
index a40283412e2..98cd11f3369 100644
--- a/storage/innobase/fsp/fsp0fsp.cc
+++ b/storage/innobase/fsp/fsp0fsp.cc
@@ -670,16 +670,18 @@ 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. */
+/** Initializes the space header of a new created space and creates also the
+insert buffer tree root if space == 0.
+@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. */
UNIV_INTERN
-void
+bool
fsp_header_init(
-/*============*/
- ulint space_id, /*!< in: space id */
- ulint size, /*!< in: current size in blocks */
- mtr_t* mtr) /*!< in/out: mini-transaction */
+ ulint space_id,
+ ulint size,
+ mtr_t* mtr)
{
fsp_header_t* header;
buf_block_t* block;
@@ -722,11 +724,15 @@ fsp_header_init(
flst_init(header + FSP_SEG_INODES_FREE, mtr);
mlog_write_ull(header + FSP_SEG_ID, 1, mtr);
+
if (space_id == 0) {
fsp_fill_free_list(FALSE, space_id, header, mtr);
- btr_create(DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF,
+
+ if (btr_create(DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF,
0, 0, DICT_IBUF_ID_MIN + space_id,
- dict_ind_redundant, mtr);
+ dict_ind_redundant, mtr) == FIL_NULL) {
+ return (false);
+ }
} else {
fsp_fill_free_list(TRUE, space_id, header, mtr);
}
@@ -739,6 +745,8 @@ fsp_header_init(
}
fil_space_release(space);
+
+ return (true);
}
#endif /* !UNIV_HOTBACKUP */
@@ -2057,6 +2065,10 @@ 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);
}
}
@@ -2066,6 +2078,8 @@ 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;
}
@@ -2095,6 +2109,9 @@ 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 012539d1ace..b68a96c8846 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -3353,6 +3353,7 @@ 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;
@@ -3563,6 +3564,19 @@ 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/fsp0fsp.h b/storage/innobase/include/fsp0fsp.h
index 2a162100dc1..905e98cc1e6 100644
--- a/storage/innobase/include/fsp0fsp.h
+++ b/storage/innobase/include/fsp0fsp.h
@@ -520,16 +520,20 @@ 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. */
+/** Initializes the space header of a new created space and creates also the
+insert buffer tree root if space == 0.
+@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. */
UNIV_INTERN
-void
+bool
fsp_header_init(
-/*============*/
- ulint space, /*!< in: space id */
- ulint size, /*!< in: current size in blocks */
- mtr_t* mtr); /*!< in/out: mini-transaction */
+ ulint space_id,
+ ulint size,
+ mtr_t* mtr)
+ MY_ATTRIBUTE((warn_unused_result));
+
/**********************************************************************//**
Increases the space size field of a space. */
UNIV_INTERN
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index 82938995e93..6ca9443dc7d 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -3590,9 +3590,15 @@ row_truncate_table_for_mysql(
} while (index);
mtr_start_trx(&mtr, trx);
- fsp_header_init(space_id,
+ bool ret = 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 f601ff17ebc..032b902c633 100644
--- a/storage/innobase/srv/srv0start.cc
+++ b/storage/innobase/srv/srv0start.cc
@@ -188,6 +188,39 @@ UNIV_INTERN mysql_pfs_key_t srv_master_thread_key;
UNIV_INTERN mysql_pfs_key_t srv_purge_thread_key;
#endif /* UNIV_PFS_THREAD */
+/** Innobase start-up aborted. Perform cleanup actions.
+@param[in] create_new_db TRUE if new db is being created
+@param[in] file File name
+@param[in] line Line number
+@param[in] err Reason for aborting InnoDB startup
+@return DB_SUCCESS or error code. */
+static
+dberr_t
+srv_init_abort(
+ bool create_new_db,
+ const char* file,
+ ulint line,
+ dberr_t err)
+{
+ if (create_new_db) {
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "Database creation was aborted"
+ " at %s [" ULINTPF "]"
+ " with error %s. You may need"
+ " to delete the ibdata1 file before trying to start"
+ " up again.",
+ file, line, ut_strerr(err));
+ } else {
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "Plugin initialization aborted"
+ " at %s [" ULINTPF "]"
+ " with error %s.",
+ file, line, ut_strerr(err));
+ }
+
+ return(err);
+}
+
/*********************************************************************//**
Convert a numeric string that optionally ends in G or M or K, to a number
containing megabytes.
@@ -1528,18 +1561,26 @@ 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) {
- fsp_header_init(
+ ret = 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);
@@ -2378,10 +2419,14 @@ files_checked:
mtr_start(&mtr);
- fsp_header_init(0, sum_of_new_sizes, &mtr);
+ bool ret = fsp_header_init(0, sum_of_new_sizes, &mtr);
mtr_commit(&mtr);
+ if (!ret) {
+ return (srv_init_abort(create_new_db, __FILE__, __LINE__, DB_ERROR));
+ }
+
/* 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,
@@ -2809,6 +2854,9 @@ files_checked:
/* Can only happen if server is read only. */
ut_a(srv_read_only_mode);
srv_undo_logs = ULONG_UNDEFINED;
+ } else if (srv_available_undo_logs < srv_undo_logs) {
+ /* Should due to out of file space. */
+ return (srv_init_abort(create_new_db, __FILE__, __LINE__, DB_ERROR));
}
if (!srv_read_only_mode) {
diff --git a/storage/innobase/trx/trx0rseg.cc b/storage/innobase/trx/trx0rseg.cc
index 003d1036a8c..21dbab98e48 100644
--- a/storage/innobase/trx/trx0rseg.cc
+++ b/storage/innobase/trx/trx0rseg.cc
@@ -323,7 +323,10 @@ trx_rseg_create(
page_no = trx_rseg_header_create(
space, 0, ULINT_MAX, slot_no, &mtr);
- ut_a(page_no != FIL_NULL);
+ if (page_no == FIL_NULL) {
+ mtr_commit(&mtr);
+ return (rseg);
+ }
sys_header = trx_sysf_get(&mtr);
diff --git a/storage/xtradb/btr/btr0btr.cc b/storage/xtradb/btr/btr0btr.cc
index d84c93f8b3e..7b5b3bb6cba 100644
--- a/storage/xtradb/btr/btr0btr.cc
+++ b/storage/xtradb/btr/btr0btr.cc
@@ -1720,6 +1720,12 @@ btr_create(
space, 0,
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);
+ }
+
buf_block_dbg_add_level(
ibuf_hdr_block, SYNC_IBUF_TREE_NODE_NEW);
@@ -1733,6 +1739,11 @@ btr_create(
+ IBUF_HEADER + IBUF_TREE_SEG_HEADER,
IBUF_TREE_ROOT_PAGE_NO,
FSP_UP, mtr);
+
+ if (!block) {
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "Allocation of the tree root page segment failed.");
+ }
ut_ad(buf_block_get_page_no(block) == IBUF_TREE_ROOT_PAGE_NO);
} else {
#ifdef UNIV_BLOB_DEBUG
@@ -1745,6 +1756,12 @@ btr_create(
#endif /* UNIV_BLOB_DEBUG */
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) {
@@ -1773,6 +1790,8 @@ btr_create(
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.");
return(FIL_NULL);
}
diff --git a/storage/xtradb/dict/dict0crea.cc b/storage/xtradb/dict/dict0crea.cc
index 6d5b12474eb..faaa6d1bdc7 100644
--- a/storage/xtradb/dict/dict0crea.cc
+++ b/storage/xtradb/dict/dict0crea.cc
@@ -323,9 +323,13 @@ dict_build_table_def_step(
mtr_start(&mtr);
- fsp_header_init(table->space, FIL_IBD_FILE_INITIAL_SIZE, &mtr);
+ bool res = 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 17e9a1be973..b669d35ff15 100644
--- a/storage/xtradb/fil/fil0fil.cc
+++ b/storage/xtradb/fil/fil0fil.cc
@@ -6115,19 +6115,21 @@ fil_report_invalid_page_access(
ulint len, /*!< in: I/O length */
ulint type) /*!< in: I/O type */
{
- fprintf(stderr,
- "InnoDB: Error: trying to access page number %lu"
- " in space %lu,\n"
- "InnoDB: space name %s,\n"
- "InnoDB: which is outside the tablespace bounds.\n"
- "InnoDB: Byte offset %lu, len %lu, i/o type %lu.\n"
- "InnoDB: If you get this error at mysqld startup,"
- " please check that\n"
- "InnoDB: your my.cnf matches the ibdata files"
- " that you have in the\n"
- "InnoDB: MySQL server.\n",
- (ulong) block_offset, (ulong) space_id, space_name,
- (ulong) byte_offset, (ulong) len, (ulong) type);
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "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 ".",
+ 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.");
}
/********************************************************************//**
@@ -6347,11 +6349,10 @@ _fil_io(
mutex_exit(&fil_system->mutex);
return(DB_ERROR);
}
+
fil_report_invalid_page_access(
block_offset, space_id, space->name,
byte_offset, len, type);
-
- ut_error;
}
/* Open file if closed */
@@ -6363,10 +6364,11 @@ _fil_io(
ib_logf(IB_LOG_LEVEL_ERROR,
"Trying to do i/o to a tablespace which "
"exists without .ibd data file. "
- "i/o type %lu, space id %lu, page no %lu, "
- "i/o length %lu bytes",
- (ulong) type, (ulong) space_id,
- (ulong) block_offset, (ulong) len);
+ "i/o type " ULINTPF ", space id "
+ ULINTPF ", page no " ULINTPF ", "
+ "i/o length " ULINTPF " bytes",
+ type, space_id,
+ block_offset, len);
return(DB_TABLESPACE_DELETED);
}
@@ -6386,8 +6388,6 @@ _fil_io(
fil_report_invalid_page_access(
block_offset, space_id, space->name, byte_offset,
len, type);
-
- ut_error;
}
/* Now we have made the changes in the data structures of fil_system */
diff --git a/storage/xtradb/fsp/fsp0fsp.cc b/storage/xtradb/fsp/fsp0fsp.cc
index 934824c6462..7929372ae6c 100644
--- a/storage/xtradb/fsp/fsp0fsp.cc
+++ b/storage/xtradb/fsp/fsp0fsp.cc
@@ -673,16 +673,18 @@ 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. */
+/** Initializes the space header of a new created space and creates also the
+insert buffer tree root if space == 0.
+@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. */
UNIV_INTERN
-void
+bool
fsp_header_init(
-/*============*/
- ulint space_id, /*!< in: space id */
- ulint size, /*!< in: current size in blocks */
- mtr_t* mtr) /*!< in/out: mini-transaction */
+ ulint space_id,
+ ulint size,
+ mtr_t* mtr)
{
fsp_header_t* header;
buf_block_t* block;
@@ -725,11 +727,15 @@ fsp_header_init(
flst_init(header + FSP_SEG_INODES_FREE, mtr);
mlog_write_ull(header + FSP_SEG_ID, 1, mtr);
+
if (space_id == 0) {
fsp_fill_free_list(FALSE, space_id, header, mtr);
- btr_create(DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF,
+
+ if (btr_create(DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF,
0, 0, DICT_IBUF_ID_MIN + space_id,
- dict_ind_redundant, mtr);
+ dict_ind_redundant, mtr) == FIL_NULL) {
+ return (false);
+ }
} else {
fsp_fill_free_list(TRUE, space_id, header, mtr);
}
@@ -742,6 +748,8 @@ fsp_header_init(
}
fil_space_release(space);
+
+ return (true);
}
#endif /* !UNIV_HOTBACKUP */
@@ -2066,6 +2074,10 @@ 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);
}
}
@@ -2075,6 +2087,8 @@ 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;
}
@@ -2104,6 +2118,9 @@ 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 dd5d041aed9..7be6c64407b 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -3770,6 +3770,7 @@ 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;
@@ -4020,6 +4021,19 @@ 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/fsp0fsp.h b/storage/xtradb/include/fsp0fsp.h
index 6ed78eba6f9..d8f851a0846 100644
--- a/storage/xtradb/include/fsp0fsp.h
+++ b/storage/xtradb/include/fsp0fsp.h
@@ -519,16 +519,20 @@ 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. */
+/** Initializes the space header of a new created space and creates also the
+insert buffer tree root if space == 0.
+@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. */
UNIV_INTERN
-void
+bool
fsp_header_init(
-/*============*/
- ulint space, /*!< in: space id */
- ulint size, /*!< in: current size in blocks */
- mtr_t* mtr); /*!< in/out: mini-transaction */
+ ulint space_id,
+ ulint size,
+ mtr_t* mtr)
+ MY_ATTRIBUTE((warn_unused_result));
+
/**********************************************************************//**
Increases the space size field of a space. */
UNIV_INTERN
diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc
index 59568f5c91b..9f1f216bccb 100644
--- a/storage/xtradb/row/row0mysql.cc
+++ b/storage/xtradb/row/row0mysql.cc
@@ -3614,9 +3614,15 @@ row_truncate_table_for_mysql(
} while (index);
mtr_start_trx(&mtr, trx);
- fsp_header_init(space_id,
+ bool ret = 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 9e2bd483511..9491d5328e7 100644
--- a/storage/xtradb/srv/srv0start.cc
+++ b/storage/xtradb/srv/srv0start.cc
@@ -206,6 +206,39 @@ UNIV_INTERN mysql_pfs_key_t srv_purge_thread_key;
UNIV_INTERN mysql_pfs_key_t srv_log_tracking_thread_key;
#endif /* UNIV_PFS_THREAD */
+/** Innobase start-up aborted. Perform cleanup actions.
+@param[in] create_new_db TRUE if new db is being created
+@param[in] file File name
+@param[in] line Line number
+@param[in] err Reason for aborting InnoDB startup
+@return DB_SUCCESS or error code. */
+static
+dberr_t
+srv_init_abort(
+ bool create_new_db,
+ const char* file,
+ ulint line,
+ dberr_t err)
+{
+ if (create_new_db) {
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "Database creation was aborted"
+ " at %s [" ULINTPF "]"
+ " with error %s. You may need"
+ " to delete the ibdata1 file before trying to start"
+ " up again.",
+ file, line, ut_strerr(err));
+ } else {
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "Plugin initialization aborted"
+ " at %s [" ULINTPF "]"
+ " with error %s.",
+ file, line, ut_strerr(err));
+ }
+
+ return(err);
+}
+
/*********************************************************************//**
Convert a numeric string that optionally ends in G or M or K, to a number
containing megabytes.
@@ -1568,18 +1601,26 @@ 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) {
- fsp_header_init(
+ ret = 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);
@@ -2466,10 +2507,14 @@ files_checked:
mtr_start(&mtr);
- fsp_header_init(0, sum_of_new_sizes, &mtr);
+ bool ret = fsp_header_init(0, sum_of_new_sizes, &mtr);
mtr_commit(&mtr);
+ if (!ret) {
+ return (srv_init_abort(create_new_db, __FILE__, __LINE__, DB_ERROR));
+ }
+
/* 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,
@@ -2899,6 +2944,9 @@ files_checked:
/* Can only happen if server is read only. */
ut_a(srv_read_only_mode);
srv_undo_logs = ULONG_UNDEFINED;
+ } else if (srv_available_undo_logs < srv_undo_logs) {
+ /* Should due to out of file space. */
+ return (srv_init_abort(create_new_db, __FILE__, __LINE__, DB_ERROR));
}
if (!srv_read_only_mode) {
diff --git a/storage/xtradb/trx/trx0rseg.cc b/storage/xtradb/trx/trx0rseg.cc
index 003d1036a8c..21dbab98e48 100644
--- a/storage/xtradb/trx/trx0rseg.cc
+++ b/storage/xtradb/trx/trx0rseg.cc
@@ -323,7 +323,10 @@ trx_rseg_create(
page_no = trx_rseg_header_create(
space, 0, ULINT_MAX, slot_no, &mtr);
- ut_a(page_no != FIL_NULL);
+ if (page_no == FIL_NULL) {
+ mtr_commit(&mtr);
+ return (rseg);
+ }
sys_header = trx_sysf_get(&mtr);