diff options
-rw-r--r-- | mysql-test/suite/innodb/t/log_data_file_size.opt | 2 | ||||
-rw-r--r-- | storage/innobase/btr/btr0btr.cc | 19 | ||||
-rw-r--r-- | storage/innobase/dict/dict0crea.cc | 6 | ||||
-rw-r--r-- | storage/innobase/fil/fil0fil.cc | 42 | ||||
-rw-r--r-- | storage/innobase/fsp/fsp0fsp.cc | 37 | ||||
-rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 14 | ||||
-rw-r--r-- | storage/innobase/include/fsp0fsp.h | 20 | ||||
-rw-r--r-- | storage/innobase/row/row0mysql.cc | 8 | ||||
-rw-r--r-- | storage/innobase/srv/srv0start.cc | 52 | ||||
-rw-r--r-- | storage/innobase/trx/trx0rseg.cc | 5 | ||||
-rw-r--r-- | storage/xtradb/btr/btr0btr.cc | 19 | ||||
-rw-r--r-- | storage/xtradb/dict/dict0crea.cc | 6 | ||||
-rw-r--r-- | storage/xtradb/fil/fil0fil.cc | 42 | ||||
-rw-r--r-- | storage/xtradb/fsp/fsp0fsp.cc | 37 | ||||
-rw-r--r-- | storage/xtradb/handler/ha_innodb.cc | 14 | ||||
-rw-r--r-- | storage/xtradb/include/fsp0fsp.h | 20 | ||||
-rw-r--r-- | storage/xtradb/row/row0mysql.cc | 8 | ||||
-rw-r--r-- | storage/xtradb/srv/srv0start.cc | 52 | ||||
-rw-r--r-- | storage/xtradb/trx/trx0rseg.cc | 5 |
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); |