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).
This commit is contained in:
Marko Mäkelä 2017-06-06 14:59:42 +03:00
parent 68890fe7d4
commit fbeb9489cd
30 changed files with 323 additions and 433 deletions

View File

@ -231,6 +231,7 @@ set global innodb_buf_flush_list_now = 1;
check table t1; check table t1;
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
test.t1 check status OK test.t1 check status OK
FOUND /\[ERROR\] InnoDB: .* in tablespace.*test.t1.*/ in mysqld.1.err
select f1, f2 from t1; select f1, f2 from t1;
f1 f2 f1 f2
1 ############ 1 ############
@ -238,6 +239,13 @@ f1 f2
3 //////////// 3 ////////////
4 ------------ 4 ------------
5 ............ 5 ............
# Test End
# ---------------------------------------------------------------
drop table t1; 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

View File

@ -4,7 +4,7 @@
--echo # PAGE OF SYSTEM TABLESPACE --echo # PAGE OF SYSTEM TABLESPACE
--echo # --echo #
--source include/have_innodb.inc --source include/innodb_page_size.inc
--source include/have_debug.inc --source include/have_debug.inc
--source include/not_embedded.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("checksum mismatch in tablespace.*test.t1");
call mtr.add_suppression("Current page size .* != page size on page"); 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("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 --enable_query_log
--source include/restart_mysqld.inc --source include/restart_mysqld.inc
let INNODB_PAGE_SIZE=`select @@innodb_page_size`; let INNODB_PAGE_SIZE=`select @@innodb_page_size`;
let MYSQLD_DATADIR=`select @@datadir`; 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_doublewrite';
show variables like 'innodb_fil_make_page_dirty_debug'; show variables like 'innodb_fil_make_page_dirty_debug';
@ -393,9 +398,38 @@ EOF
--source include/start_mysqld.inc --source include/start_mysqld.inc
check table t1; check table t1;
--let SEARCH_PATTERN= \[ERROR\] InnoDB: .* in tablespace.*test.t1.*
--source include/search_pattern_in_file.inc
select f1, f2 from t1; select f1, f2 from t1;
--echo # Test End
--echo # ---------------------------------------------------------------
drop table 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

View File

@ -1,2 +1,2 @@
--loose-innodb-sys-indexes --loose-innodb-sys-indexes
--innodb-data-file-path=ibdata1:3M:autoextend --innodb-data-file-path=ibdata1:1M:autoextend

View File

@ -1,4 +1,4 @@
--source include/have_innodb.inc --source include/innodb_page_size.inc
--source include/not_embedded.inc --source include/not_embedded.inc
let INNODB_PAGE_SIZE=`select @@innodb_page_size`; let INNODB_PAGE_SIZE=`select @@innodb_page_size`;

View File

@ -2,7 +2,7 @@
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc. 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 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 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 */ dict_index_t* index, /*!< in: index */
mtr_t* mtr) /*!< in: mini-transaction handle */ mtr_t* mtr) /*!< in: mini-transaction handle */
{ {
ulint page_no;
buf_block_t* block; buf_block_t* block;
buf_frame_t* frame;
page_t* page; page_t* page;
page_zip_des_t* page_zip; page_zip_des_t* page_zip;
@ -1702,8 +1700,6 @@ btr_create(
IBUF_HEADER + IBUF_TREE_SEG_HEADER, mtr); IBUF_HEADER + IBUF_TREE_SEG_HEADER, mtr);
if (ibuf_hdr_block == NULL) { 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);
} }
@ -1721,11 +1717,16 @@ btr_create(
IBUF_TREE_ROOT_PAGE_NO, IBUF_TREE_ROOT_PAGE_NO,
FSP_UP, mtr); FSP_UP, mtr);
if (!block) { if (block == NULL) {
ib_logf(IB_LOG_LEVEL_ERROR, return(FIL_NULL);
"Allocation of the tree root page segment failed.");
} }
ut_ad(buf_block_get_page_no(block) == IBUF_TREE_ROOT_PAGE_NO); 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 { } else {
#ifdef UNIV_BLOB_DEBUG #ifdef UNIV_BLOB_DEBUG
if ((type & DICT_CLUSTERED) && !index->blobs) { if ((type & DICT_CLUSTERED) && !index->blobs) {
@ -1738,41 +1739,18 @@ btr_create(
block = fseg_create(space, 0, block = fseg_create(space, 0,
PAGE_HEADER + PAGE_BTR_SEG_TOP, mtr); PAGE_HEADER + PAGE_BTR_SEG_TOP, mtr);
if (!block) {
ib_logf(IB_LOG_LEVEL_ERROR,
"Allocation of the btree segment failed.");
}
}
if (block == NULL) { if (block == NULL) {
return(FIL_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); 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)) { PAGE_HEADER + PAGE_BTR_SEG_LEAF, mtr)) {
/* Not enough space for new segment, free root /* Not enough space for new segment, free root
segment before return. */ segment before return. */
btr_free_root(space, zip_size, page_no, mtr); btr_free_root(space, zip_size,
buf_block_get_page_no(block), mtr);
ib_logf(IB_LOG_LEVEL_ERROR,
"Allocation of the non-ibuf tree segment for leaf pages failed.");
return(FIL_NULL); return(FIL_NULL);
} }
@ -1816,7 +1794,7 @@ btr_create(
ut_ad(page_get_max_insert_size(page, 2) > 2 * BTR_PAGE_MAX_REC_SIZE); 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));
} }
/************************************************************//** /************************************************************//**

View File

@ -175,13 +175,14 @@ buf_dblwr_init(
mem_zalloc(buf_size * sizeof(void*))); mem_zalloc(buf_size * sizeof(void*)));
} }
/****************************************************************//** /** Create the doublewrite buffer if the doublewrite buffer header
Creates the doublewrite buffer to a new InnoDB installation. The header of the is not present in the TRX_SYS page.
doublewrite buffer is placed on the trx system header 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 UNIV_INTERN
void bool
buf_dblwr_create(void) buf_dblwr_create()
/*==================*/
{ {
buf_block_t* block2; buf_block_t* block2;
buf_block_t* new_block; buf_block_t* new_block;
@ -194,8 +195,7 @@ buf_dblwr_create(void)
if (buf_dblwr) { if (buf_dblwr) {
/* Already inited */ /* Already inited */
return(true);
return;
} }
start_again: start_again:
@ -213,39 +213,59 @@ start_again:
mtr_commit(&mtr); mtr_commit(&mtr);
buf_dblwr_being_created = FALSE; 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() if (buf_pool_get_curr_size()
< ((TRX_SYS_DOUBLEWRITE_BLOCKS * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE < ((TRX_SYS_DOUBLEWRITE_BLOCKS * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE
+ FSP_EXTENT_SIZE / 2 + 100) + FSP_EXTENT_SIZE / 2 + 100)
* UNIV_PAGE_SIZE)) { * UNIV_PAGE_SIZE)) {
ib_logf(IB_LOG_LEVEL_FATAL, ib_logf(IB_LOG_LEVEL_ERROR,
"Cannot create doublewrite buffer: you must " "Cannot create doublewrite buffer: "
"increase your buffer pool size. Cannot continue " "innodb_buffer_pool_size is too small.");
"operation."); 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, block2 = fseg_create(TRX_SYS_SPACE, TRX_SYS_PAGE_NO,
TRX_SYS_DOUBLEWRITE TRX_SYS_DOUBLEWRITE
+ TRX_SYS_DOUBLEWRITE_FSEG, &mtr); + 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, /* fseg_create acquires a second latch on the page,
therefore we must declare it: */ therefore we must declare it: */
buf_block_dbg_add_level(block2, SYNC_NO_ORDER_CHECK); 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; fseg_header = doublewrite + TRX_SYS_DOUBLEWRITE_FSEG;
prev_page_no = 0; prev_page_no = 0;
@ -482,6 +502,14 @@ buf_dblwr_process()
byte* unaligned_read_buf; byte* unaligned_read_buf;
recv_dblwr_t& recv_dblwr = recv_sys->dblwr; 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)); unaligned_read_buf = static_cast<byte*>(ut_malloc(2 * UNIV_PAGE_SIZE));
read_buf = static_cast<byte*>( read_buf = static_cast<byte*>(

View File

@ -321,13 +321,9 @@ dict_build_table_def_step(
mtr_start(&mtr); 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); mtr_commit(&mtr);
if (!res) {
return (DB_ERROR);
}
} else { } else {
/* Create in the system tablespace: disallow Barracuda /* Create in the system tablespace: disallow Barracuda
features by keeping only the first bit which says whether features by keeping only the first bit which says whether

View File

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. 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 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 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 len, /*!< in: I/O length */
ulint type) /*!< in: I/O type */ ulint type) /*!< in: I/O type */
{ {
ib_logf(IB_LOG_LEVEL_ERROR, ib_logf(IB_LOG_LEVEL_FATAL,
"Trying to access page number " ULINTPF "Trying to access page number " ULINTPF
" in space " ULINTPF " in space " ULINTPF
" space name %s," " space name %s,"
" which is outside the tablespace bounds." " 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, block_offset, space_id, space_name,
byte_offset, len, type); byte_offset, len, type,
space_id == 0 && !srv_was_started
ib_logf(IB_LOG_LEVEL_FATAL, ? "Please check that the configuration matches"
"If you get this error at mysqld startup," " the InnoDB system tablespace location (ibdata files)"
" please check that" : "");
" your my.cnf matches the ibdata files"
" that you have in the"
" MySQL server.");
} }
/********************************************************************//** /********************************************************************//**

View File

@ -670,18 +670,13 @@ fsp_header_init_fields(
} }
#ifndef UNIV_HOTBACKUP #ifndef UNIV_HOTBACKUP
/** Initializes the space header of a new created space and creates also the /** Initialize a tablespace header.
insert buffer tree root if space == 0.
@param[in] space_id space id @param[in] space_id space id
@param[in] size current size in blocks @param[in] size current size in blocks
@param[in,out] mtr min-transaction @param[in,out] mtr mini-transaction */
@return true on success, otherwise false. */
UNIV_INTERN UNIV_INTERN
bool void
fsp_header_init( fsp_header_init(ulint space_id, ulint size, mtr_t* mtr)
ulint space_id,
ulint size,
mtr_t* mtr)
{ {
fsp_header_t* header; fsp_header_t* header;
buf_block_t* block; buf_block_t* block;
@ -725,17 +720,7 @@ fsp_header_init(
mlog_write_ull(header + FSP_SEG_ID, 1, mtr); mlog_write_ull(header + FSP_SEG_ID, 1, mtr);
if (space_id == 0) { fsp_fill_free_list(space_id != TRX_SYS_SPACE, space_id, header, mtr);
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);
}
fil_space_t* space = fil_space_acquire(space_id); fil_space_t* space = fil_space_acquire(space_id);
ut_ad(space); ut_ad(space);
@ -745,8 +730,6 @@ fsp_header_init(
} }
fil_space_release(space); fil_space_release(space);
return (true);
} }
#endif /* !UNIV_HOTBACKUP */ #endif /* !UNIV_HOTBACKUP */
@ -2065,10 +2048,6 @@ fseg_create_general(
success = fsp_reserve_free_extents(&n_reserved, space, 2, success = fsp_reserve_free_extents(&n_reserved, space, 2,
FSP_NORMAL, mtr); FSP_NORMAL, mtr);
if (!success) { if (!success) {
ib_logf(IB_LOG_LEVEL_ERROR,
"Reserving %d free extents failed"
" could reserve only " ULINTPF " extents.",
2, n_reserved);
return(NULL); return(NULL);
} }
} }
@ -2078,9 +2057,6 @@ fseg_create_general(
inode = fsp_alloc_seg_inode(space_header, mtr); inode = fsp_alloc_seg_inode(space_header, mtr);
if (inode == NULL) { if (inode == NULL) {
ib_logf(IB_LOG_LEVEL_ERROR,
"Allocation of a new file segment inode page failed.");
goto funct_exit; goto funct_exit;
} }
@ -2109,9 +2085,6 @@ fseg_create_general(
inode, 0, FSP_UP, mtr, mtr); inode, 0, FSP_UP, mtr, mtr);
if (block == NULL) { 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); fsp_free_seg_inode(space, zip_size, inode, mtr);

View File

@ -3353,7 +3353,6 @@ innobase_init(
char *default_path; char *default_path;
uint format_id; uint format_id;
ulong num_pll_degree; ulong num_pll_degree;
ulint min_size = 0;
DBUG_ENTER("innobase_init"); DBUG_ENTER("innobase_init");
handlerton *innobase_hton= (handlerton*) p; handlerton *innobase_hton= (handlerton*) p;
@ -3564,19 +3563,6 @@ mem_free_and_error:
goto 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 ---------------------------*/ /* -------------- All log files ---------------------------*/
/* The default dir for log files is the datadir of MySQL */ /* The default dir for log files is the datadir of MySQL */

View File

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. 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 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 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 */ /** Set to TRUE when the doublewrite buffer is being created */
extern ibool buf_dblwr_being_created; extern ibool buf_dblwr_being_created;
/****************************************************************//** /** Create the doublewrite buffer if the doublewrite buffer header
Creates the doublewrite buffer to a new InnoDB installation. The header of the is not present in the TRX_SYS page.
doublewrite buffer is placed on the trx system header 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 UNIV_INTERN
void bool
buf_dblwr_create(void); buf_dblwr_create()
/*==================*/ MY_ATTRIBUTE((warn_unused_result));
/****************************************************************//** /****************************************************************//**
At a database startup initializes the doublewrite buffer memory structure if At a database startup initializes the doublewrite buffer memory structure if

View File

@ -520,19 +520,13 @@ fsp_header_init_fields(
ulint space_id, /*!< in: space id */ ulint space_id, /*!< in: space id */
ulint flags); /*!< in: tablespace flags (FSP_SPACE_FLAGS): ulint flags); /*!< in: tablespace flags (FSP_SPACE_FLAGS):
0, or table->flags if newer than COMPACT */ 0, or table->flags if newer than COMPACT */
/** Initializes the space header of a new created space and creates also the /** Initialize a tablespace header.
insert buffer tree root if space == 0.
@param[in] space_id space id @param[in] space_id space id
@param[in] size current size in blocks @param[in] size current size in blocks
@param[in,out] mtr min-transaction @param[in,out] mtr mini-transaction */
@return true on success, otherwise false. */
UNIV_INTERN UNIV_INTERN
bool void
fsp_header_init( fsp_header_init(ulint space_id, ulint size, mtr_t* mtr);
ulint space_id,
ulint size,
mtr_t* mtr)
MY_ATTRIBUTE((warn_unused_result));
/**********************************************************************//** /**********************************************************************//**
Increases the space size field of a space. */ Increases the space size field of a space. */

View File

@ -1,6 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. 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 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 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 */ trx_rseg_t* rseg); /*!< in, own: instance to free */
/********************************************************************* /** Create a rollback segment.
Creates a rollback segment. */ @param[in] space undo tablespace ID
@return pointer to new rollback segment
@retval NULL on failure */
UNIV_INTERN UNIV_INTERN
trx_rseg_t* trx_rseg_t*
trx_rseg_create( trx_rseg_create(ulint space);
/*============*/
ulint space); /*!< in: id of UNDO tablespace */
/******************************************************************** /********************************************************************
Get the number of unique rollback tablespaces in use except space id 0. Get the number of unique rollback tablespaces in use except space id 0.

View File

@ -2914,11 +2914,6 @@ recv_init_crash_recovery(void)
possible */ possible */
if (srv_force_recovery < SRV_FORCE_NO_LOG_REDO) { 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(); buf_dblwr_process();
/* Spawn the background thread to flush dirty pages /* Spawn the background thread to flush dirty pages
@ -3179,24 +3174,6 @@ recv_recovery_from_checkpoint_start_func(
user about recovery: */ user about recovery: */
if (checkpoint_lsn != flushed_lsn) { 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) { if (!recv_needed_recovery) {
ib_logf(IB_LOG_LEVEL_INFO, ib_logf(IB_LOG_LEVEL_INFO,
"The log sequence number " "The log sequence number "

View File

@ -3590,15 +3590,9 @@ row_truncate_table_for_mysql(
} while (index); } while (index);
mtr_start_trx(&mtr, trx); mtr_start_trx(&mtr, trx);
bool ret = fsp_header_init(space_id, fsp_header_init(space_id,
FIL_IBD_FILE_INITIAL_SIZE, &mtr); FIL_IBD_FILE_INITIAL_SIZE, &mtr);
mtr_commit(&mtr); mtr_commit(&mtr);
if (!ret) {
table->file_unreadable = true;
err = DB_ERROR;
goto funct_exit;
}
} }
} else { } else {
/* Lock all index trees for this table, as we will /* Lock all index trees for this table, as we will

View File

@ -1561,26 +1561,18 @@ srv_undo_tablespaces_init(
if (create_new_db) { if (create_new_db) {
mtr_t mtr; mtr_t mtr;
bool ret=true;
mtr_start(&mtr); mtr_start(&mtr);
/* The undo log tablespace */ /* The undo log tablespace */
for (i = 0; i < n_undo_tablespaces; ++i) { for (i = 0; i < n_undo_tablespaces; ++i) {
ret = fsp_header_init( fsp_header_init(
undo_tablespace_ids[i], undo_tablespace_ids[i],
SRV_UNDO_TABLESPACE_SIZE_IN_PAGES, &mtr); SRV_UNDO_TABLESPACE_SIZE_IN_PAGES, &mtr);
if (!ret) {
break;
}
} }
mtr_commit(&mtr); mtr_commit(&mtr);
if (!ret) {
return (srv_init_abort(create_new_db, __FILE__, __LINE__, DB_ERROR));
}
} }
return(DB_SUCCESS); return(DB_SUCCESS);
@ -2419,14 +2411,24 @@ files_checked:
mtr_start(&mtr); 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); mtr_commit(&mtr);
if (!ret) { if (ibuf_root == FIL_NULL) {
return (srv_init_abort(create_new_db, __FILE__, __LINE__, DB_ERROR)); 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 /* To maintain backward compatibility we create only
the first rollback segment before the double write buffer. the first rollback segment before the double write buffer.
All the remaining rollback segments will be created later, All the remaining rollback segments will be created later,
@ -2812,10 +2814,9 @@ files_checked:
/* fprintf(stderr, "Max allowed record size %lu\n", /* fprintf(stderr, "Max allowed record size %lu\n",
page_get_free_space_of_empty() / 2); */ page_get_free_space_of_empty() / 2); */
if (buf_dblwr == NULL) { if (!buf_dblwr_create()) {
/* Create the doublewrite buffer to a new tablespace */ return(srv_init_abort(create_new_db, __FILE__, __LINE__,
DB_ERROR));
buf_dblwr_create();
} }
/* Here the double write buffer has already been created and so /* Here the double write buffer has already been created and so

View File

@ -1,6 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. 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 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 the terms of the GNU General Public License as published by the Free Software
@ -293,14 +294,13 @@ trx_rseg_create_instance(
} }
} }
/********************************************************************* /** Create a rollback segment.
Creates a rollback segment. @param[in] space undo tablespace ID
@return pointer to new rollback segment if create successful */ @return pointer to new rollback segment
@retval NULL on failure */
UNIV_INTERN UNIV_INTERN
trx_rseg_t* trx_rseg_t*
trx_rseg_create( trx_rseg_create(ulint space)
/*============*/
ulint space) /*!< in: id of UNDO tablespace */
{ {
mtr_t mtr; mtr_t mtr;
ulint slot_no; ulint slot_no;
@ -323,11 +323,7 @@ trx_rseg_create(
page_no = trx_rseg_header_create( page_no = trx_rseg_header_create(
space, 0, ULINT_MAX, slot_no, &mtr); space, 0, ULINT_MAX, slot_no, &mtr);
if (page_no == FIL_NULL) { if (page_no != FIL_NULL) {
mtr_commit(&mtr);
return (rseg);
}
sys_header = trx_sysf_get(&mtr); sys_header = trx_sysf_get(&mtr);
id = trx_sysf_rseg_get_space(sys_header, slot_no, &mtr); id = trx_sysf_rseg_get_space(sys_header, slot_no, &mtr);
@ -339,9 +335,9 @@ trx_rseg_create(
slot_no, space, zip_size, page_no, slot_no, space, zip_size, page_no,
purge_sys->ib_bh, &mtr); purge_sys->ib_bh, &mtr);
} }
}
mtr_commit(&mtr); mtr_commit(&mtr);
return(rseg); return(rseg);
} }

View File

@ -2,7 +2,7 @@
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc. 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 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 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 */ dict_index_t* index, /*!< in: index */
mtr_t* mtr) /*!< in: mini-transaction handle */ mtr_t* mtr) /*!< in: mini-transaction handle */
{ {
ulint page_no;
buf_block_t* block; buf_block_t* block;
buf_frame_t* frame;
page_t* page; page_t* page;
page_zip_des_t* page_zip; page_zip_des_t* page_zip;
@ -1721,8 +1719,6 @@ btr_create(
IBUF_HEADER + IBUF_TREE_SEG_HEADER, mtr); IBUF_HEADER + IBUF_TREE_SEG_HEADER, mtr);
if (ibuf_hdr_block == NULL) { 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);
} }
@ -1740,11 +1736,16 @@ btr_create(
IBUF_TREE_ROOT_PAGE_NO, IBUF_TREE_ROOT_PAGE_NO,
FSP_UP, mtr); FSP_UP, mtr);
if (!block) { if (block == NULL) {
ib_logf(IB_LOG_LEVEL_ERROR, return(FIL_NULL);
"Allocation of the tree root page segment failed.");
} }
ut_ad(buf_block_get_page_no(block) == IBUF_TREE_ROOT_PAGE_NO); 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 { } else {
#ifdef UNIV_BLOB_DEBUG #ifdef UNIV_BLOB_DEBUG
if ((type & DICT_CLUSTERED) && !index->blobs) { if ((type & DICT_CLUSTERED) && !index->blobs) {
@ -1757,41 +1758,18 @@ btr_create(
block = fseg_create(space, 0, block = fseg_create(space, 0,
PAGE_HEADER + PAGE_BTR_SEG_TOP, mtr); PAGE_HEADER + PAGE_BTR_SEG_TOP, mtr);
if (!block) {
ib_logf(IB_LOG_LEVEL_ERROR,
"Allocation of the btree segment failed.");
}
}
if (block == NULL) { if (block == NULL) {
return(FIL_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); 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)) { PAGE_HEADER + PAGE_BTR_SEG_LEAF, mtr)) {
/* Not enough space for new segment, free root /* Not enough space for new segment, free root
segment before return. */ segment before return. */
btr_free_root(space, zip_size, page_no, mtr); btr_free_root(space, zip_size,
buf_block_get_page_no(block), mtr);
ib_logf(IB_LOG_LEVEL_ERROR,
"Allocation of the non-ibuf tree segment for leaf pages failed.");
return(FIL_NULL); return(FIL_NULL);
} }
@ -1835,7 +1813,7 @@ btr_create(
ut_ad(page_get_max_insert_size(page, 2) > 2 * BTR_PAGE_MAX_REC_SIZE); 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));
} }
/************************************************************//** /************************************************************//**

View File

@ -175,13 +175,14 @@ buf_dblwr_init(
mem_zalloc(buf_size * sizeof(void*))); mem_zalloc(buf_size * sizeof(void*)));
} }
/****************************************************************//** /** Create the doublewrite buffer if the doublewrite buffer header
Creates the doublewrite buffer to a new InnoDB installation. The header of the is not present in the TRX_SYS page.
doublewrite buffer is placed on the trx system header 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 UNIV_INTERN
void bool
buf_dblwr_create(void) buf_dblwr_create()
/*==================*/
{ {
buf_block_t* block2; buf_block_t* block2;
buf_block_t* new_block; buf_block_t* new_block;
@ -194,8 +195,7 @@ buf_dblwr_create(void)
if (buf_dblwr) { if (buf_dblwr) {
/* Already inited */ /* Already inited */
return(true);
return;
} }
start_again: start_again:
@ -213,39 +213,59 @@ start_again:
mtr_commit(&mtr); mtr_commit(&mtr);
buf_dblwr_being_created = FALSE; 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() if (buf_pool_get_curr_size()
< ((TRX_SYS_DOUBLEWRITE_BLOCKS * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE < ((TRX_SYS_DOUBLEWRITE_BLOCKS * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE
+ FSP_EXTENT_SIZE / 2 + 100) + FSP_EXTENT_SIZE / 2 + 100)
* UNIV_PAGE_SIZE)) { * UNIV_PAGE_SIZE)) {
ib_logf(IB_LOG_LEVEL_FATAL, ib_logf(IB_LOG_LEVEL_ERROR,
"Cannot create doublewrite buffer: you must " "Cannot create doublewrite buffer: "
"increase your buffer pool size. Cannot continue " "innodb_buffer_pool_size is too small.");
"operation."); 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, block2 = fseg_create(TRX_SYS_SPACE, TRX_SYS_PAGE_NO,
TRX_SYS_DOUBLEWRITE TRX_SYS_DOUBLEWRITE
+ TRX_SYS_DOUBLEWRITE_FSEG, &mtr); + 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, /* fseg_create acquires a second latch on the page,
therefore we must declare it: */ therefore we must declare it: */
buf_block_dbg_add_level(block2, SYNC_NO_ORDER_CHECK); 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; fseg_header = doublewrite + TRX_SYS_DOUBLEWRITE_FSEG;
prev_page_no = 0; prev_page_no = 0;
@ -482,6 +502,14 @@ buf_dblwr_process()
byte* unaligned_read_buf; byte* unaligned_read_buf;
recv_dblwr_t& recv_dblwr = recv_sys->dblwr; 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)); unaligned_read_buf = static_cast<byte*>(ut_malloc(2 * UNIV_PAGE_SIZE));
read_buf = static_cast<byte*>( read_buf = static_cast<byte*>(

View File

@ -323,13 +323,9 @@ dict_build_table_def_step(
mtr_start(&mtr); 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); mtr_commit(&mtr);
if(!res) {
return (DB_ERROR);
}
} else { } else {
/* Create in the system tablespace: disallow Barracuda /* Create in the system tablespace: disallow Barracuda
features by keeping only the first bit which says whether features by keeping only the first bit which says whether

View File

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. 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 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 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 len, /*!< in: I/O length */
ulint type) /*!< in: I/O type */ ulint type) /*!< in: I/O type */
{ {
ib_logf(IB_LOG_LEVEL_ERROR, ib_logf(IB_LOG_LEVEL_FATAL,
"Trying to access page number " ULINTPF "Trying to access page number " ULINTPF
" in space " ULINTPF " in space " ULINTPF
" space name %s," " space name %s,"
" which is outside the tablespace bounds." " 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, block_offset, space_id, space_name,
byte_offset, len, type); byte_offset, len, type,
space_id == 0 && !srv_was_started
ib_logf(IB_LOG_LEVEL_FATAL, ? "Please check that the configuration matches"
"If you get this error at mysqld startup," " the InnoDB system tablespace location (ibdata files)"
" please check that" : "");
" your my.cnf matches the ibdata files"
" that you have in the"
" MySQL server.");
} }
/********************************************************************//** /********************************************************************//**

View File

@ -673,18 +673,13 @@ fsp_header_init_fields(
} }
#ifndef UNIV_HOTBACKUP #ifndef UNIV_HOTBACKUP
/** Initializes the space header of a new created space and creates also the /** Initialize a tablespace header.
insert buffer tree root if space == 0.
@param[in] space_id space id @param[in] space_id space id
@param[in] size current size in blocks @param[in] size current size in blocks
@param[in,out] mtr min-transaction @param[in,out] mtr mini-transaction */
@return true on success, otherwise false. */
UNIV_INTERN UNIV_INTERN
bool void
fsp_header_init( fsp_header_init(ulint space_id, ulint size, mtr_t* mtr)
ulint space_id,
ulint size,
mtr_t* mtr)
{ {
fsp_header_t* header; fsp_header_t* header;
buf_block_t* block; buf_block_t* block;
@ -728,17 +723,7 @@ fsp_header_init(
mlog_write_ull(header + FSP_SEG_ID, 1, mtr); mlog_write_ull(header + FSP_SEG_ID, 1, mtr);
if (space_id == 0) { fsp_fill_free_list(space_id != TRX_SYS_SPACE, space_id, header, mtr);
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);
}
fil_space_t* space = fil_space_acquire(space_id); fil_space_t* space = fil_space_acquire(space_id);
ut_ad(space); ut_ad(space);
@ -748,8 +733,6 @@ fsp_header_init(
} }
fil_space_release(space); fil_space_release(space);
return (true);
} }
#endif /* !UNIV_HOTBACKUP */ #endif /* !UNIV_HOTBACKUP */
@ -2074,10 +2057,6 @@ fseg_create_general(
success = fsp_reserve_free_extents(&n_reserved, space, 2, success = fsp_reserve_free_extents(&n_reserved, space, 2,
FSP_NORMAL, mtr); FSP_NORMAL, mtr);
if (!success) { if (!success) {
ib_logf(IB_LOG_LEVEL_ERROR,
"Reserving %d free extents failed"
" could reserve only " ULINTPF " extents.",
2, n_reserved);
return(NULL); return(NULL);
} }
} }
@ -2087,9 +2066,6 @@ fseg_create_general(
inode = fsp_alloc_seg_inode(space_header, mtr); inode = fsp_alloc_seg_inode(space_header, mtr);
if (inode == NULL) { if (inode == NULL) {
ib_logf(IB_LOG_LEVEL_ERROR,
"Allocation of a new file segment inode page failed.");
goto funct_exit; goto funct_exit;
} }
@ -2118,9 +2094,6 @@ fseg_create_general(
inode, 0, FSP_UP, mtr, mtr); inode, 0, FSP_UP, mtr, mtr);
if (block == NULL) { 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); fsp_free_seg_inode(space, zip_size, inode, mtr);

View File

@ -3770,7 +3770,6 @@ innobase_init(
char *default_path; char *default_path;
uint format_id; uint format_id;
ulong num_pll_degree; ulong num_pll_degree;
ulint min_size = 0;
DBUG_ENTER("innobase_init"); DBUG_ENTER("innobase_init");
handlerton *innobase_hton= (handlerton*) p; handlerton *innobase_hton= (handlerton*) p;
@ -4021,19 +4020,6 @@ mem_free_and_error:
goto 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 ---------------------------*/ /* -------------- All log files ---------------------------*/
/* The default dir for log files is the datadir of MySQL */ /* The default dir for log files is the datadir of MySQL */

View File

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. 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 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 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 */ /** Set to TRUE when the doublewrite buffer is being created */
extern ibool buf_dblwr_being_created; extern ibool buf_dblwr_being_created;
/****************************************************************//** /** Create the doublewrite buffer if the doublewrite buffer header
Creates the doublewrite buffer to a new InnoDB installation. The header of the is not present in the TRX_SYS page.
doublewrite buffer is placed on the trx system header 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 UNIV_INTERN
void bool
buf_dblwr_create(void); buf_dblwr_create()
/*==================*/ MY_ATTRIBUTE((warn_unused_result));
/****************************************************************//** /****************************************************************//**
At a database startup initializes the doublewrite buffer memory structure if At a database startup initializes the doublewrite buffer memory structure if

View File

@ -519,19 +519,13 @@ fsp_header_init_fields(
ulint space_id, /*!< in: space id */ ulint space_id, /*!< in: space id */
ulint flags); /*!< in: tablespace flags (FSP_SPACE_FLAGS): ulint flags); /*!< in: tablespace flags (FSP_SPACE_FLAGS):
0, or table->flags if newer than COMPACT */ 0, or table->flags if newer than COMPACT */
/** Initializes the space header of a new created space and creates also the /** Initialize a tablespace header.
insert buffer tree root if space == 0.
@param[in] space_id space id @param[in] space_id space id
@param[in] size current size in blocks @param[in] size current size in blocks
@param[in,out] mtr min-transaction @param[in,out] mtr mini-transaction */
@return true on success, otherwise false. */
UNIV_INTERN UNIV_INTERN
bool void
fsp_header_init( fsp_header_init(ulint space_id, ulint size, mtr_t* mtr);
ulint space_id,
ulint size,
mtr_t* mtr)
MY_ATTRIBUTE((warn_unused_result));
/**********************************************************************//** /**********************************************************************//**
Increases the space size field of a space. */ Increases the space size field of a space. */

View File

@ -1,6 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. 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 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 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 */ trx_rseg_t* rseg); /*!< in, own: instance to free */
/********************************************************************* /** Create a rollback segment.
Creates a rollback segment. */ @param[in] space undo tablespace ID
@return pointer to new rollback segment
@retval NULL on failure */
UNIV_INTERN UNIV_INTERN
trx_rseg_t* trx_rseg_t*
trx_rseg_create( trx_rseg_create(ulint space);
/*============*/
ulint space); /*!< in: id of UNDO tablespace */
/******************************************************************** /********************************************************************
Get the number of unique rollback tablespaces in use except space id 0. Get the number of unique rollback tablespaces in use except space id 0.

View File

@ -3004,11 +3004,6 @@ recv_init_crash_recovery(void)
possible */ possible */
if (srv_force_recovery < SRV_FORCE_NO_LOG_REDO) { 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(); buf_dblwr_process();
/* Spawn the background thread to flush dirty pages /* Spawn the background thread to flush dirty pages
@ -3276,24 +3271,6 @@ recv_recovery_from_checkpoint_start_func(
user about recovery: */ user about recovery: */
if (checkpoint_lsn != flushed_lsn) { 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) { if (!recv_needed_recovery) {
ib_logf(IB_LOG_LEVEL_INFO, ib_logf(IB_LOG_LEVEL_INFO,
"The log sequence number " "The log sequence number "

View File

@ -3614,15 +3614,9 @@ row_truncate_table_for_mysql(
} while (index); } while (index);
mtr_start_trx(&mtr, trx); mtr_start_trx(&mtr, trx);
bool ret = fsp_header_init(space_id, fsp_header_init(space_id,
FIL_IBD_FILE_INITIAL_SIZE, &mtr); FIL_IBD_FILE_INITIAL_SIZE, &mtr);
mtr_commit(&mtr); mtr_commit(&mtr);
if (!ret) {
table->file_unreadable = true;
err = DB_ERROR;
goto funct_exit;
}
} }
} else { } else {
/* Lock all index trees for this table, as we will /* Lock all index trees for this table, as we will

View File

@ -1601,26 +1601,18 @@ srv_undo_tablespaces_init(
if (create_new_db) { if (create_new_db) {
mtr_t mtr; mtr_t mtr;
bool ret=true;
mtr_start(&mtr); mtr_start(&mtr);
/* The undo log tablespace */ /* The undo log tablespace */
for (i = 0; i < n_undo_tablespaces; ++i) { for (i = 0; i < n_undo_tablespaces; ++i) {
ret = fsp_header_init( fsp_header_init(
undo_tablespace_ids[i], undo_tablespace_ids[i],
SRV_UNDO_TABLESPACE_SIZE_IN_PAGES, &mtr); SRV_UNDO_TABLESPACE_SIZE_IN_PAGES, &mtr);
if (!ret) {
break;
}
} }
mtr_commit(&mtr); mtr_commit(&mtr);
if (!ret) {
return (srv_init_abort(create_new_db, __FILE__, __LINE__, DB_ERROR));
}
} }
return(DB_SUCCESS); return(DB_SUCCESS);
@ -2507,14 +2499,24 @@ files_checked:
mtr_start(&mtr); 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); mtr_commit(&mtr);
if (!ret) { if (ibuf_root == FIL_NULL) {
return (srv_init_abort(create_new_db, __FILE__, __LINE__, DB_ERROR)); 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 /* To maintain backward compatibility we create only
the first rollback segment before the double write buffer. the first rollback segment before the double write buffer.
All the remaining rollback segments will be created later, All the remaining rollback segments will be created later,
@ -2901,10 +2903,9 @@ files_checked:
/* fprintf(stderr, "Max allowed record size %lu\n", /* fprintf(stderr, "Max allowed record size %lu\n",
page_get_free_space_of_empty() / 2); */ page_get_free_space_of_empty() / 2); */
if (buf_dblwr == NULL) { if (!buf_dblwr_create()) {
/* Create the doublewrite buffer to a new tablespace */ return(srv_init_abort(create_new_db, __FILE__, __LINE__,
DB_ERROR));
buf_dblwr_create();
} }
/* Here the double write buffer has already been created and so /* Here the double write buffer has already been created and so

View File

@ -1,6 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. 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 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 the terms of the GNU General Public License as published by the Free Software
@ -293,14 +294,13 @@ trx_rseg_create_instance(
} }
} }
/********************************************************************* /** Create a rollback segment.
Creates a rollback segment. @param[in] space undo tablespace ID
@return pointer to new rollback segment if create successful */ @return pointer to new rollback segment
@retval NULL on failure */
UNIV_INTERN UNIV_INTERN
trx_rseg_t* trx_rseg_t*
trx_rseg_create( trx_rseg_create(ulint space)
/*============*/
ulint space) /*!< in: id of UNDO tablespace */
{ {
mtr_t mtr; mtr_t mtr;
ulint slot_no; ulint slot_no;
@ -323,11 +323,7 @@ trx_rseg_create(
page_no = trx_rseg_header_create( page_no = trx_rseg_header_create(
space, 0, ULINT_MAX, slot_no, &mtr); space, 0, ULINT_MAX, slot_no, &mtr);
if (page_no == FIL_NULL) { if (page_no != FIL_NULL) {
mtr_commit(&mtr);
return (rseg);
}
sys_header = trx_sysf_get(&mtr); sys_header = trx_sysf_get(&mtr);
id = trx_sysf_rseg_get_space(sys_header, slot_no, &mtr); id = trx_sysf_rseg_get_space(sys_header, slot_no, &mtr);
@ -339,9 +335,9 @@ trx_rseg_create(
slot_no, space, zip_size, page_no, slot_no, space, zip_size, page_no,
purge_sys->ib_bh, &mtr); purge_sys->ib_bh, &mtr);
} }
}
mtr_commit(&mtr); mtr_commit(&mtr);
return(rseg); return(rseg);
} }