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:
parent
68890fe7d4
commit
fbeb9489cd
@ -231,6 +231,7 @@ set global innodb_buf_flush_list_now = 1;
|
||||
check table t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 check status OK
|
||||
FOUND /\[ERROR\] InnoDB: .* in tablespace.*test.t1.*/ in mysqld.1.err
|
||||
select f1, f2 from t1;
|
||||
f1 f2
|
||||
1 ############
|
||||
@ -238,6 +239,13 @@ f1 f2
|
||||
3 ////////////
|
||||
4 ------------
|
||||
5 ............
|
||||
# Test End
|
||||
# ---------------------------------------------------------------
|
||||
drop table t1;
|
||||
#
|
||||
# MDEV-12600 crash during install_db with innodb_page_size=32K
|
||||
# and ibdata1=3M
|
||||
#
|
||||
SELECT * FROM INFORMATION_SCHEMA.ENGINES
|
||||
WHERE engine = 'innodb'
|
||||
AND support IN ('YES', 'DEFAULT', 'ENABLED');
|
||||
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
|
||||
FOUND /\[ERROR\] InnoDB: Cannot create doublewrite buffer/ in mysqld.1.err
|
||||
|
@ -4,7 +4,7 @@
|
||||
--echo # PAGE OF SYSTEM TABLESPACE
|
||||
--echo #
|
||||
|
||||
--source include/have_innodb.inc
|
||||
--source include/innodb_page_size.inc
|
||||
--source include/have_debug.inc
|
||||
--source include/not_embedded.inc
|
||||
|
||||
@ -15,12 +15,17 @@ call mtr.add_suppression("space header page consists of zero bytes.*test.t1");
|
||||
call mtr.add_suppression("checksum mismatch in tablespace.*test.t1");
|
||||
call mtr.add_suppression("Current page size .* != page size on page");
|
||||
call mtr.add_suppression("innodb-page-size mismatch in tablespace.*test.t1");
|
||||
call mtr.add_suppression("Trying to recover page.*from the doublewrite buffer");
|
||||
call mtr.add_suppression("InnoDB: New log files created");
|
||||
call mtr.add_suppression("InnoDB: Cannot create doublewrite buffer: the first file in innodb_data_file_path must be at least (3|6|12)M\\.");
|
||||
call mtr.add_suppression("InnoDB: Database creation was aborted");
|
||||
call mtr.add_suppression("Plugin 'InnoDB' (init function returned error|registration as a STORAGE ENGINE failed)");
|
||||
--enable_query_log
|
||||
--source include/restart_mysqld.inc
|
||||
|
||||
let INNODB_PAGE_SIZE=`select @@innodb_page_size`;
|
||||
let MYSQLD_DATADIR=`select @@datadir`;
|
||||
let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err;
|
||||
let SEARCH_RANGE= -50000;
|
||||
|
||||
show variables like 'innodb_doublewrite';
|
||||
show variables like 'innodb_fil_make_page_dirty_debug';
|
||||
@ -393,9 +398,38 @@ EOF
|
||||
--source include/start_mysqld.inc
|
||||
|
||||
check table t1;
|
||||
--let SEARCH_PATTERN= \[ERROR\] InnoDB: .* in tablespace.*test.t1.*
|
||||
--source include/search_pattern_in_file.inc
|
||||
|
||||
select f1, f2 from t1;
|
||||
|
||||
--echo # Test End
|
||||
--echo # ---------------------------------------------------------------
|
||||
|
||||
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
|
||||
|
@ -1,2 +1,2 @@
|
||||
--loose-innodb-sys-indexes
|
||||
--innodb-data-file-path=ibdata1:3M:autoextend
|
||||
--innodb-data-file-path=ibdata1:1M:autoextend
|
||||
|
@ -1,4 +1,4 @@
|
||||
--source include/have_innodb.inc
|
||||
--source include/innodb_page_size.inc
|
||||
--source include/not_embedded.inc
|
||||
|
||||
let INNODB_PAGE_SIZE=`select @@innodb_page_size`;
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2012, Facebook Inc.
|
||||
Copyright (c) 2014, 2017, MariaDB Corporation
|
||||
Copyright (c) 2014, 2017, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
@ -1684,9 +1684,7 @@ btr_create(
|
||||
dict_index_t* index, /*!< in: index */
|
||||
mtr_t* mtr) /*!< in: mini-transaction handle */
|
||||
{
|
||||
ulint page_no;
|
||||
buf_block_t* block;
|
||||
buf_frame_t* frame;
|
||||
page_t* page;
|
||||
page_zip_des_t* page_zip;
|
||||
|
||||
@ -1702,9 +1700,7 @@ btr_create(
|
||||
IBUF_HEADER + IBUF_TREE_SEG_HEADER, mtr);
|
||||
|
||||
if (ibuf_hdr_block == NULL) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Allocation of the first ibuf header page failed.");
|
||||
return (FIL_NULL);
|
||||
return(FIL_NULL);
|
||||
}
|
||||
|
||||
buf_block_dbg_add_level(
|
||||
@ -1721,11 +1717,16 @@ btr_create(
|
||||
IBUF_TREE_ROOT_PAGE_NO,
|
||||
FSP_UP, mtr);
|
||||
|
||||
if (!block) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Allocation of the tree root page segment failed.");
|
||||
if (block == NULL) {
|
||||
return(FIL_NULL);
|
||||
}
|
||||
|
||||
ut_ad(buf_block_get_page_no(block) == IBUF_TREE_ROOT_PAGE_NO);
|
||||
|
||||
buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE_NEW);
|
||||
|
||||
flst_init(block->frame + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST,
|
||||
mtr);
|
||||
} else {
|
||||
#ifdef UNIV_BLOB_DEBUG
|
||||
if ((type & DICT_CLUSTERED) && !index->blobs) {
|
||||
@ -1738,41 +1739,18 @@ btr_create(
|
||||
block = fseg_create(space, 0,
|
||||
PAGE_HEADER + PAGE_BTR_SEG_TOP, mtr);
|
||||
|
||||
if (!block) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Allocation of the btree segment failed.");
|
||||
if (block == NULL) {
|
||||
return(FIL_NULL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (block == NULL) {
|
||||
|
||||
return(FIL_NULL);
|
||||
}
|
||||
|
||||
page_no = buf_block_get_page_no(block);
|
||||
frame = buf_block_get_frame(block);
|
||||
|
||||
if (type & DICT_IBUF) {
|
||||
/* It is an insert buffer tree: initialize the free list */
|
||||
buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE_NEW);
|
||||
|
||||
ut_ad(page_no == IBUF_TREE_ROOT_PAGE_NO);
|
||||
|
||||
flst_init(frame + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST, mtr);
|
||||
} else {
|
||||
/* It is a non-ibuf tree: create a file segment for leaf
|
||||
pages */
|
||||
buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW);
|
||||
|
||||
if (!fseg_create(space, page_no,
|
||||
if (!fseg_create(space, buf_block_get_page_no(block),
|
||||
PAGE_HEADER + PAGE_BTR_SEG_LEAF, mtr)) {
|
||||
/* Not enough space for new segment, free root
|
||||
segment before return. */
|
||||
btr_free_root(space, zip_size, page_no, mtr);
|
||||
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Allocation of the non-ibuf tree segment for leaf pages failed.");
|
||||
btr_free_root(space, zip_size,
|
||||
buf_block_get_page_no(block), mtr);
|
||||
return(FIL_NULL);
|
||||
}
|
||||
|
||||
@ -1816,7 +1794,7 @@ btr_create(
|
||||
|
||||
ut_ad(page_get_max_insert_size(page, 2) > 2 * BTR_PAGE_MAX_REC_SIZE);
|
||||
|
||||
return(page_no);
|
||||
return(buf_block_get_page_no(block));
|
||||
}
|
||||
|
||||
/************************************************************//**
|
||||
|
@ -175,13 +175,14 @@ buf_dblwr_init(
|
||||
mem_zalloc(buf_size * sizeof(void*)));
|
||||
}
|
||||
|
||||
/****************************************************************//**
|
||||
Creates the doublewrite buffer to a new InnoDB installation. The header of the
|
||||
doublewrite buffer is placed on the trx system header page. */
|
||||
/** Create the doublewrite buffer if the doublewrite buffer header
|
||||
is not present in the TRX_SYS page.
|
||||
@return whether the operation succeeded
|
||||
@retval true if the doublewrite buffer exists or was created
|
||||
@retval false if the creation failed (too small first data file) */
|
||||
UNIV_INTERN
|
||||
void
|
||||
buf_dblwr_create(void)
|
||||
/*==================*/
|
||||
bool
|
||||
buf_dblwr_create()
|
||||
{
|
||||
buf_block_t* block2;
|
||||
buf_block_t* new_block;
|
||||
@ -194,8 +195,7 @@ buf_dblwr_create(void)
|
||||
|
||||
if (buf_dblwr) {
|
||||
/* Already inited */
|
||||
|
||||
return;
|
||||
return(true);
|
||||
}
|
||||
|
||||
start_again:
|
||||
@ -213,39 +213,59 @@ start_again:
|
||||
|
||||
mtr_commit(&mtr);
|
||||
buf_dblwr_being_created = FALSE;
|
||||
return;
|
||||
return(true);
|
||||
}
|
||||
|
||||
ib_logf(IB_LOG_LEVEL_INFO,
|
||||
"Doublewrite buffer not found: creating new");
|
||||
|
||||
if (buf_pool_get_curr_size()
|
||||
< ((TRX_SYS_DOUBLEWRITE_BLOCKS * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE
|
||||
+ FSP_EXTENT_SIZE / 2 + 100)
|
||||
* UNIV_PAGE_SIZE)) {
|
||||
|
||||
ib_logf(IB_LOG_LEVEL_FATAL,
|
||||
"Cannot create doublewrite buffer: you must "
|
||||
"increase your buffer pool size. Cannot continue "
|
||||
"operation.");
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Cannot create doublewrite buffer: "
|
||||
"innodb_buffer_pool_size is too small.");
|
||||
mtr_commit(&mtr);
|
||||
return(false);
|
||||
} else {
|
||||
fil_space_t* space = fil_space_acquire(TRX_SYS_SPACE);
|
||||
const bool fail = UT_LIST_GET_FIRST(space->chain)->size
|
||||
< 3 * FSP_EXTENT_SIZE;
|
||||
fil_space_release(space);
|
||||
|
||||
if (fail) {
|
||||
goto too_small;
|
||||
}
|
||||
}
|
||||
|
||||
block2 = fseg_create(TRX_SYS_SPACE, TRX_SYS_PAGE_NO,
|
||||
TRX_SYS_DOUBLEWRITE
|
||||
+ TRX_SYS_DOUBLEWRITE_FSEG, &mtr);
|
||||
|
||||
if (block2 == NULL) {
|
||||
too_small:
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Cannot create doublewrite buffer: "
|
||||
"the first file in innodb_data_file_path"
|
||||
" must be at least %luM.",
|
||||
3 * (FSP_EXTENT_SIZE * UNIV_PAGE_SIZE) >> 20);
|
||||
mtr_commit(&mtr);
|
||||
return(false);
|
||||
}
|
||||
|
||||
ib_logf(IB_LOG_LEVEL_INFO,
|
||||
"Doublewrite buffer not found: creating new");
|
||||
|
||||
/* FIXME: After this point, the doublewrite buffer creation
|
||||
is not atomic. The doublewrite buffer should not exist in
|
||||
the InnoDB system tablespace file in the first place.
|
||||
It could be located in separate optional file(s) in a
|
||||
user-specified location. */
|
||||
|
||||
/* fseg_create acquires a second latch on the page,
|
||||
therefore we must declare it: */
|
||||
|
||||
buf_block_dbg_add_level(block2, SYNC_NO_ORDER_CHECK);
|
||||
|
||||
if (block2 == NULL) {
|
||||
ib_logf(IB_LOG_LEVEL_FATAL,
|
||||
"Cannot create doublewrite buffer: you must "
|
||||
"increase your tablespace size. "
|
||||
"Cannot continue operation.");
|
||||
}
|
||||
|
||||
fseg_header = doublewrite + TRX_SYS_DOUBLEWRITE_FSEG;
|
||||
prev_page_no = 0;
|
||||
|
||||
@ -482,6 +502,14 @@ buf_dblwr_process()
|
||||
byte* unaligned_read_buf;
|
||||
recv_dblwr_t& recv_dblwr = recv_sys->dblwr;
|
||||
|
||||
if (!buf_dblwr) {
|
||||
return;
|
||||
}
|
||||
|
||||
ib_logf(IB_LOG_LEVEL_INFO,
|
||||
"Restoring possible half-written data pages "
|
||||
"from the doublewrite buffer...");
|
||||
|
||||
unaligned_read_buf = static_cast<byte*>(ut_malloc(2 * UNIV_PAGE_SIZE));
|
||||
|
||||
read_buf = static_cast<byte*>(
|
||||
|
@ -321,13 +321,9 @@ dict_build_table_def_step(
|
||||
|
||||
mtr_start(&mtr);
|
||||
|
||||
bool res = fsp_header_init(table->space, FIL_IBD_FILE_INITIAL_SIZE, &mtr);
|
||||
fsp_header_init(table->space, FIL_IBD_FILE_INITIAL_SIZE, &mtr);
|
||||
|
||||
mtr_commit(&mtr);
|
||||
|
||||
if (!res) {
|
||||
return (DB_ERROR);
|
||||
}
|
||||
} else {
|
||||
/* Create in the system tablespace: disallow Barracuda
|
||||
features by keeping only the first bit which says whether
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2014, 2017, MariaDB Corporation. All Rights Reserved.
|
||||
Copyright (c) 2014, 2017, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
@ -5812,21 +5812,19 @@ fil_report_invalid_page_access(
|
||||
ulint len, /*!< in: I/O length */
|
||||
ulint type) /*!< in: I/O type */
|
||||
{
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
ib_logf(IB_LOG_LEVEL_FATAL,
|
||||
"Trying to access page number " ULINTPF
|
||||
" in space " ULINTPF
|
||||
" space name %s,"
|
||||
" which is outside the tablespace bounds."
|
||||
" Byte offset " ULINTPF ", len " ULINTPF " i/o type " ULINTPF ".",
|
||||
" Byte offset " ULINTPF ", len " ULINTPF
|
||||
" i/o type " ULINTPF ".%s",
|
||||
block_offset, space_id, space_name,
|
||||
byte_offset, len, type);
|
||||
|
||||
ib_logf(IB_LOG_LEVEL_FATAL,
|
||||
"If you get this error at mysqld startup,"
|
||||
" please check that"
|
||||
" your my.cnf matches the ibdata files"
|
||||
" that you have in the"
|
||||
" MySQL server.");
|
||||
byte_offset, len, type,
|
||||
space_id == 0 && !srv_was_started
|
||||
? "Please check that the configuration matches"
|
||||
" the InnoDB system tablespace location (ibdata files)"
|
||||
: "");
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
|
@ -670,18 +670,13 @@ fsp_header_init_fields(
|
||||
}
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
/** Initializes the space header of a new created space and creates also the
|
||||
insert buffer tree root if space == 0.
|
||||
/** Initialize a tablespace header.
|
||||
@param[in] space_id space id
|
||||
@param[in] size current size in blocks
|
||||
@param[in,out] mtr min-transaction
|
||||
@return true on success, otherwise false. */
|
||||
@param[in,out] mtr mini-transaction */
|
||||
UNIV_INTERN
|
||||
bool
|
||||
fsp_header_init(
|
||||
ulint space_id,
|
||||
ulint size,
|
||||
mtr_t* mtr)
|
||||
void
|
||||
fsp_header_init(ulint space_id, ulint size, mtr_t* mtr)
|
||||
{
|
||||
fsp_header_t* header;
|
||||
buf_block_t* block;
|
||||
@ -725,17 +720,7 @@ fsp_header_init(
|
||||
|
||||
mlog_write_ull(header + FSP_SEG_ID, 1, mtr);
|
||||
|
||||
if (space_id == 0) {
|
||||
fsp_fill_free_list(FALSE, space_id, header, mtr);
|
||||
|
||||
if (btr_create(DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF,
|
||||
0, 0, DICT_IBUF_ID_MIN + space_id,
|
||||
dict_ind_redundant, mtr) == FIL_NULL) {
|
||||
return (false);
|
||||
}
|
||||
} else {
|
||||
fsp_fill_free_list(TRUE, space_id, header, mtr);
|
||||
}
|
||||
fsp_fill_free_list(space_id != TRX_SYS_SPACE, space_id, header, mtr);
|
||||
|
||||
fil_space_t* space = fil_space_acquire(space_id);
|
||||
ut_ad(space);
|
||||
@ -745,8 +730,6 @@ fsp_header_init(
|
||||
}
|
||||
|
||||
fil_space_release(space);
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
@ -2065,10 +2048,6 @@ fseg_create_general(
|
||||
success = fsp_reserve_free_extents(&n_reserved, space, 2,
|
||||
FSP_NORMAL, mtr);
|
||||
if (!success) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Reserving %d free extents failed"
|
||||
" could reserve only " ULINTPF " extents.",
|
||||
2, n_reserved);
|
||||
return(NULL);
|
||||
}
|
||||
}
|
||||
@ -2078,9 +2057,6 @@ fseg_create_general(
|
||||
inode = fsp_alloc_seg_inode(space_header, mtr);
|
||||
|
||||
if (inode == NULL) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Allocation of a new file segment inode page failed.");
|
||||
|
||||
goto funct_exit;
|
||||
}
|
||||
|
||||
@ -2109,9 +2085,6 @@ fseg_create_general(
|
||||
inode, 0, FSP_UP, mtr, mtr);
|
||||
|
||||
if (block == NULL) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Allocation of a free page from space " ULINTPF " failed.",
|
||||
space);
|
||||
|
||||
fsp_free_seg_inode(space, zip_size, inode, mtr);
|
||||
|
||||
|
@ -3353,7 +3353,6 @@ innobase_init(
|
||||
char *default_path;
|
||||
uint format_id;
|
||||
ulong num_pll_degree;
|
||||
ulint min_size = 0;
|
||||
|
||||
DBUG_ENTER("innobase_init");
|
||||
handlerton *innobase_hton= (handlerton*) p;
|
||||
@ -3564,19 +3563,6 @@ mem_free_and_error:
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* All doublewrite buffer pages must fit to first system
|
||||
datafile and first datafile must be at least 3M. */
|
||||
min_size = ut_max((3*1024*1024U), (192U*UNIV_PAGE_SIZE));
|
||||
|
||||
if ((srv_data_file_sizes[0]*1024*1024) < min_size) {
|
||||
sql_print_error(
|
||||
"InnoDB: first datafile is too small current=" ULINTPF
|
||||
"M it should be at least " ULINTPF "M.",
|
||||
srv_data_file_sizes[0],
|
||||
min_size / (1024 * 1024));
|
||||
goto mem_free_and_error;
|
||||
}
|
||||
|
||||
/* -------------- All log files ---------------------------*/
|
||||
|
||||
/* The default dir for log files is the datadir of MySQL */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2017, MariaDB Corporation. All Rights Reserved.
|
||||
Copyright (c) 2017, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
@ -39,13 +39,15 @@ extern buf_dblwr_t* buf_dblwr;
|
||||
/** Set to TRUE when the doublewrite buffer is being created */
|
||||
extern ibool buf_dblwr_being_created;
|
||||
|
||||
/****************************************************************//**
|
||||
Creates the doublewrite buffer to a new InnoDB installation. The header of the
|
||||
doublewrite buffer is placed on the trx system header page. */
|
||||
/** Create the doublewrite buffer if the doublewrite buffer header
|
||||
is not present in the TRX_SYS page.
|
||||
@return whether the operation succeeded
|
||||
@retval true if the doublewrite buffer exists or was created
|
||||
@retval false if the creation failed (too small first data file) */
|
||||
UNIV_INTERN
|
||||
void
|
||||
buf_dblwr_create(void);
|
||||
/*==================*/
|
||||
bool
|
||||
buf_dblwr_create()
|
||||
MY_ATTRIBUTE((warn_unused_result));
|
||||
|
||||
/****************************************************************//**
|
||||
At a database startup initializes the doublewrite buffer memory structure if
|
||||
|
@ -520,19 +520,13 @@ fsp_header_init_fields(
|
||||
ulint space_id, /*!< in: space id */
|
||||
ulint flags); /*!< in: tablespace flags (FSP_SPACE_FLAGS):
|
||||
0, or table->flags if newer than COMPACT */
|
||||
/** Initializes the space header of a new created space and creates also the
|
||||
insert buffer tree root if space == 0.
|
||||
/** Initialize a tablespace header.
|
||||
@param[in] space_id space id
|
||||
@param[in] size current size in blocks
|
||||
@param[in,out] mtr min-transaction
|
||||
@return true on success, otherwise false. */
|
||||
@param[in,out] mtr mini-transaction */
|
||||
UNIV_INTERN
|
||||
bool
|
||||
fsp_header_init(
|
||||
ulint space_id,
|
||||
ulint size,
|
||||
mtr_t* mtr)
|
||||
MY_ATTRIBUTE((warn_unused_result));
|
||||
void
|
||||
fsp_header_init(ulint space_id, ulint size, mtr_t* mtr);
|
||||
|
||||
/**********************************************************************//**
|
||||
Increases the space size field of a space. */
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2017, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
@ -124,13 +125,13 @@ trx_rseg_mem_free(
|
||||
/*==============*/
|
||||
trx_rseg_t* rseg); /*!< in, own: instance to free */
|
||||
|
||||
/*********************************************************************
|
||||
Creates a rollback segment. */
|
||||
/** Create a rollback segment.
|
||||
@param[in] space undo tablespace ID
|
||||
@return pointer to new rollback segment
|
||||
@retval NULL on failure */
|
||||
UNIV_INTERN
|
||||
trx_rseg_t*
|
||||
trx_rseg_create(
|
||||
/*============*/
|
||||
ulint space); /*!< in: id of UNDO tablespace */
|
||||
trx_rseg_create(ulint space);
|
||||
|
||||
/********************************************************************
|
||||
Get the number of unique rollback tablespaces in use except space id 0.
|
||||
|
@ -2914,11 +2914,6 @@ recv_init_crash_recovery(void)
|
||||
possible */
|
||||
|
||||
if (srv_force_recovery < SRV_FORCE_NO_LOG_REDO) {
|
||||
|
||||
ib_logf(IB_LOG_LEVEL_INFO,
|
||||
"Restoring possible half-written data pages "
|
||||
"from the doublewrite buffer...");
|
||||
|
||||
buf_dblwr_process();
|
||||
|
||||
/* Spawn the background thread to flush dirty pages
|
||||
@ -3179,24 +3174,6 @@ recv_recovery_from_checkpoint_start_func(
|
||||
user about recovery: */
|
||||
|
||||
if (checkpoint_lsn != flushed_lsn) {
|
||||
|
||||
if (checkpoint_lsn < flushed_lsn) {
|
||||
|
||||
ib_logf(IB_LOG_LEVEL_WARN,
|
||||
"The log sequence number "
|
||||
"in the ibdata files is higher "
|
||||
"than the log sequence number "
|
||||
"in the ib_logfiles! Are you sure "
|
||||
"you are using the right "
|
||||
"ib_logfiles to start up the database. "
|
||||
"Log sequence number in the "
|
||||
"ib_logfiles is " LSN_PF ", log"
|
||||
"sequence number stamped "
|
||||
"to ibdata file header is " LSN_PF ".",
|
||||
checkpoint_lsn,
|
||||
flushed_lsn);
|
||||
}
|
||||
|
||||
if (!recv_needed_recovery) {
|
||||
ib_logf(IB_LOG_LEVEL_INFO,
|
||||
"The log sequence number "
|
||||
|
@ -3590,15 +3590,9 @@ row_truncate_table_for_mysql(
|
||||
} while (index);
|
||||
|
||||
mtr_start_trx(&mtr, trx);
|
||||
bool ret = fsp_header_init(space_id,
|
||||
fsp_header_init(space_id,
|
||||
FIL_IBD_FILE_INITIAL_SIZE, &mtr);
|
||||
mtr_commit(&mtr);
|
||||
|
||||
if (!ret) {
|
||||
table->file_unreadable = true;
|
||||
err = DB_ERROR;
|
||||
goto funct_exit;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Lock all index trees for this table, as we will
|
||||
|
@ -1561,26 +1561,18 @@ srv_undo_tablespaces_init(
|
||||
|
||||
if (create_new_db) {
|
||||
mtr_t mtr;
|
||||
bool ret=true;
|
||||
|
||||
mtr_start(&mtr);
|
||||
|
||||
/* The undo log tablespace */
|
||||
for (i = 0; i < n_undo_tablespaces; ++i) {
|
||||
|
||||
ret = fsp_header_init(
|
||||
fsp_header_init(
|
||||
undo_tablespace_ids[i],
|
||||
SRV_UNDO_TABLESPACE_SIZE_IN_PAGES, &mtr);
|
||||
if (!ret) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mtr_commit(&mtr);
|
||||
|
||||
if (!ret) {
|
||||
return (srv_init_abort(create_new_db, __FILE__, __LINE__, DB_ERROR));
|
||||
}
|
||||
}
|
||||
|
||||
return(DB_SUCCESS);
|
||||
@ -2419,14 +2411,24 @@ files_checked:
|
||||
|
||||
mtr_start(&mtr);
|
||||
|
||||
bool ret = fsp_header_init(0, sum_of_new_sizes, &mtr);
|
||||
fsp_header_init(0, sum_of_new_sizes, &mtr);
|
||||
compile_time_assert(TRX_SYS_SPACE == 0);
|
||||
compile_time_assert(IBUF_SPACE_ID == 0);
|
||||
|
||||
ulint ibuf_root = btr_create(
|
||||
DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF,
|
||||
0, 0, DICT_IBUF_ID_MIN,
|
||||
dict_ind_redundant, &mtr);
|
||||
|
||||
mtr_commit(&mtr);
|
||||
|
||||
if (!ret) {
|
||||
return (srv_init_abort(create_new_db, __FILE__, __LINE__, DB_ERROR));
|
||||
if (ibuf_root == FIL_NULL) {
|
||||
return(srv_init_abort(true, __FILE__, __LINE__,
|
||||
DB_ERROR));
|
||||
}
|
||||
|
||||
ut_ad(ibuf_root == IBUF_TREE_ROOT_PAGE_NO);
|
||||
|
||||
/* To maintain backward compatibility we create only
|
||||
the first rollback segment before the double write buffer.
|
||||
All the remaining rollback segments will be created later,
|
||||
@ -2812,10 +2814,9 @@ files_checked:
|
||||
/* fprintf(stderr, "Max allowed record size %lu\n",
|
||||
page_get_free_space_of_empty() / 2); */
|
||||
|
||||
if (buf_dblwr == NULL) {
|
||||
/* Create the doublewrite buffer to a new tablespace */
|
||||
|
||||
buf_dblwr_create();
|
||||
if (!buf_dblwr_create()) {
|
||||
return(srv_init_abort(create_new_db, __FILE__, __LINE__,
|
||||
DB_ERROR));
|
||||
}
|
||||
|
||||
/* Here the double write buffer has already been created and so
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2017, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
@ -293,14 +294,13 @@ trx_rseg_create_instance(
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
Creates a rollback segment.
|
||||
@return pointer to new rollback segment if create successful */
|
||||
/** Create a rollback segment.
|
||||
@param[in] space undo tablespace ID
|
||||
@return pointer to new rollback segment
|
||||
@retval NULL on failure */
|
||||
UNIV_INTERN
|
||||
trx_rseg_t*
|
||||
trx_rseg_create(
|
||||
/*============*/
|
||||
ulint space) /*!< in: id of UNDO tablespace */
|
||||
trx_rseg_create(ulint space)
|
||||
{
|
||||
mtr_t mtr;
|
||||
ulint slot_no;
|
||||
@ -323,25 +323,21 @@ trx_rseg_create(
|
||||
page_no = trx_rseg_header_create(
|
||||
space, 0, ULINT_MAX, slot_no, &mtr);
|
||||
|
||||
if (page_no == FIL_NULL) {
|
||||
mtr_commit(&mtr);
|
||||
return (rseg);
|
||||
if (page_no != FIL_NULL) {
|
||||
sys_header = trx_sysf_get(&mtr);
|
||||
|
||||
id = trx_sysf_rseg_get_space(sys_header, slot_no, &mtr);
|
||||
ut_a(id == space);
|
||||
|
||||
zip_size = space ? fil_space_get_zip_size(space) : 0;
|
||||
|
||||
rseg = trx_rseg_mem_create(
|
||||
slot_no, space, zip_size, page_no,
|
||||
purge_sys->ib_bh, &mtr);
|
||||
}
|
||||
|
||||
sys_header = trx_sysf_get(&mtr);
|
||||
|
||||
id = trx_sysf_rseg_get_space(sys_header, slot_no, &mtr);
|
||||
ut_a(id == space);
|
||||
|
||||
zip_size = space ? fil_space_get_zip_size(space) : 0;
|
||||
|
||||
rseg = trx_rseg_mem_create(
|
||||
slot_no, space, zip_size, page_no,
|
||||
purge_sys->ib_bh, &mtr);
|
||||
}
|
||||
|
||||
mtr_commit(&mtr);
|
||||
|
||||
return(rseg);
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2012, Facebook Inc.
|
||||
Copyright (c) 2014, 2017, MariaDB Corporation
|
||||
Copyright (c) 2014, 2017, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
@ -1703,9 +1703,7 @@ btr_create(
|
||||
dict_index_t* index, /*!< in: index */
|
||||
mtr_t* mtr) /*!< in: mini-transaction handle */
|
||||
{
|
||||
ulint page_no;
|
||||
buf_block_t* block;
|
||||
buf_frame_t* frame;
|
||||
page_t* page;
|
||||
page_zip_des_t* page_zip;
|
||||
|
||||
@ -1721,9 +1719,7 @@ btr_create(
|
||||
IBUF_HEADER + IBUF_TREE_SEG_HEADER, mtr);
|
||||
|
||||
if (ibuf_hdr_block == NULL) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Allocation of the first ibuf header page failed.");
|
||||
return (FIL_NULL);
|
||||
return(FIL_NULL);
|
||||
}
|
||||
|
||||
buf_block_dbg_add_level(
|
||||
@ -1740,11 +1736,16 @@ btr_create(
|
||||
IBUF_TREE_ROOT_PAGE_NO,
|
||||
FSP_UP, mtr);
|
||||
|
||||
if (!block) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Allocation of the tree root page segment failed.");
|
||||
if (block == NULL) {
|
||||
return(FIL_NULL);
|
||||
}
|
||||
|
||||
ut_ad(buf_block_get_page_no(block) == IBUF_TREE_ROOT_PAGE_NO);
|
||||
|
||||
buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE_NEW);
|
||||
|
||||
flst_init(block->frame + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST,
|
||||
mtr);
|
||||
} else {
|
||||
#ifdef UNIV_BLOB_DEBUG
|
||||
if ((type & DICT_CLUSTERED) && !index->blobs) {
|
||||
@ -1757,41 +1758,18 @@ btr_create(
|
||||
block = fseg_create(space, 0,
|
||||
PAGE_HEADER + PAGE_BTR_SEG_TOP, mtr);
|
||||
|
||||
if (!block) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Allocation of the btree segment failed.");
|
||||
if (block == NULL) {
|
||||
return(FIL_NULL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (block == NULL) {
|
||||
|
||||
return(FIL_NULL);
|
||||
}
|
||||
|
||||
page_no = buf_block_get_page_no(block);
|
||||
frame = buf_block_get_frame(block);
|
||||
|
||||
if (type & DICT_IBUF) {
|
||||
/* It is an insert buffer tree: initialize the free list */
|
||||
buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE_NEW);
|
||||
|
||||
ut_ad(page_no == IBUF_TREE_ROOT_PAGE_NO);
|
||||
|
||||
flst_init(frame + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST, mtr);
|
||||
} else {
|
||||
/* It is a non-ibuf tree: create a file segment for leaf
|
||||
pages */
|
||||
buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW);
|
||||
|
||||
if (!fseg_create(space, page_no,
|
||||
if (!fseg_create(space, buf_block_get_page_no(block),
|
||||
PAGE_HEADER + PAGE_BTR_SEG_LEAF, mtr)) {
|
||||
/* Not enough space for new segment, free root
|
||||
segment before return. */
|
||||
btr_free_root(space, zip_size, page_no, mtr);
|
||||
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Allocation of the non-ibuf tree segment for leaf pages failed.");
|
||||
btr_free_root(space, zip_size,
|
||||
buf_block_get_page_no(block), mtr);
|
||||
return(FIL_NULL);
|
||||
}
|
||||
|
||||
@ -1835,7 +1813,7 @@ btr_create(
|
||||
|
||||
ut_ad(page_get_max_insert_size(page, 2) > 2 * BTR_PAGE_MAX_REC_SIZE);
|
||||
|
||||
return(page_no);
|
||||
return(buf_block_get_page_no(block));
|
||||
}
|
||||
|
||||
/************************************************************//**
|
||||
|
@ -175,13 +175,14 @@ buf_dblwr_init(
|
||||
mem_zalloc(buf_size * sizeof(void*)));
|
||||
}
|
||||
|
||||
/****************************************************************//**
|
||||
Creates the doublewrite buffer to a new InnoDB installation. The header of the
|
||||
doublewrite buffer is placed on the trx system header page. */
|
||||
/** Create the doublewrite buffer if the doublewrite buffer header
|
||||
is not present in the TRX_SYS page.
|
||||
@return whether the operation succeeded
|
||||
@retval true if the doublewrite buffer exists or was created
|
||||
@retval false if the creation failed (too small first data file) */
|
||||
UNIV_INTERN
|
||||
void
|
||||
buf_dblwr_create(void)
|
||||
/*==================*/
|
||||
bool
|
||||
buf_dblwr_create()
|
||||
{
|
||||
buf_block_t* block2;
|
||||
buf_block_t* new_block;
|
||||
@ -194,8 +195,7 @@ buf_dblwr_create(void)
|
||||
|
||||
if (buf_dblwr) {
|
||||
/* Already inited */
|
||||
|
||||
return;
|
||||
return(true);
|
||||
}
|
||||
|
||||
start_again:
|
||||
@ -213,39 +213,59 @@ start_again:
|
||||
|
||||
mtr_commit(&mtr);
|
||||
buf_dblwr_being_created = FALSE;
|
||||
return;
|
||||
return(true);
|
||||
}
|
||||
|
||||
ib_logf(IB_LOG_LEVEL_INFO,
|
||||
"Doublewrite buffer not found: creating new");
|
||||
|
||||
if (buf_pool_get_curr_size()
|
||||
< ((TRX_SYS_DOUBLEWRITE_BLOCKS * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE
|
||||
+ FSP_EXTENT_SIZE / 2 + 100)
|
||||
* UNIV_PAGE_SIZE)) {
|
||||
|
||||
ib_logf(IB_LOG_LEVEL_FATAL,
|
||||
"Cannot create doublewrite buffer: you must "
|
||||
"increase your buffer pool size. Cannot continue "
|
||||
"operation.");
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Cannot create doublewrite buffer: "
|
||||
"innodb_buffer_pool_size is too small.");
|
||||
mtr_commit(&mtr);
|
||||
return(false);
|
||||
} else {
|
||||
fil_space_t* space = fil_space_acquire(TRX_SYS_SPACE);
|
||||
const bool fail = UT_LIST_GET_FIRST(space->chain)->size
|
||||
< 3 * FSP_EXTENT_SIZE;
|
||||
fil_space_release(space);
|
||||
|
||||
if (fail) {
|
||||
goto too_small;
|
||||
}
|
||||
}
|
||||
|
||||
block2 = fseg_create(TRX_SYS_SPACE, TRX_SYS_PAGE_NO,
|
||||
TRX_SYS_DOUBLEWRITE
|
||||
+ TRX_SYS_DOUBLEWRITE_FSEG, &mtr);
|
||||
|
||||
if (block2 == NULL) {
|
||||
too_small:
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Cannot create doublewrite buffer: "
|
||||
"the first file in innodb_data_file_path"
|
||||
" must be at least %luM.",
|
||||
3 * (FSP_EXTENT_SIZE * UNIV_PAGE_SIZE) >> 20);
|
||||
mtr_commit(&mtr);
|
||||
return(false);
|
||||
}
|
||||
|
||||
ib_logf(IB_LOG_LEVEL_INFO,
|
||||
"Doublewrite buffer not found: creating new");
|
||||
|
||||
/* FIXME: After this point, the doublewrite buffer creation
|
||||
is not atomic. The doublewrite buffer should not exist in
|
||||
the InnoDB system tablespace file in the first place.
|
||||
It could be located in separate optional file(s) in a
|
||||
user-specified location. */
|
||||
|
||||
/* fseg_create acquires a second latch on the page,
|
||||
therefore we must declare it: */
|
||||
|
||||
buf_block_dbg_add_level(block2, SYNC_NO_ORDER_CHECK);
|
||||
|
||||
if (block2 == NULL) {
|
||||
ib_logf(IB_LOG_LEVEL_FATAL,
|
||||
"Cannot create doublewrite buffer: you must "
|
||||
"increase your tablespace size. "
|
||||
"Cannot continue operation.");
|
||||
}
|
||||
|
||||
fseg_header = doublewrite + TRX_SYS_DOUBLEWRITE_FSEG;
|
||||
prev_page_no = 0;
|
||||
|
||||
@ -482,6 +502,14 @@ buf_dblwr_process()
|
||||
byte* unaligned_read_buf;
|
||||
recv_dblwr_t& recv_dblwr = recv_sys->dblwr;
|
||||
|
||||
if (!buf_dblwr) {
|
||||
return;
|
||||
}
|
||||
|
||||
ib_logf(IB_LOG_LEVEL_INFO,
|
||||
"Restoring possible half-written data pages "
|
||||
"from the doublewrite buffer...");
|
||||
|
||||
unaligned_read_buf = static_cast<byte*>(ut_malloc(2 * UNIV_PAGE_SIZE));
|
||||
|
||||
read_buf = static_cast<byte*>(
|
||||
|
@ -323,13 +323,9 @@ dict_build_table_def_step(
|
||||
|
||||
mtr_start(&mtr);
|
||||
|
||||
bool res = fsp_header_init(table->space, FIL_IBD_FILE_INITIAL_SIZE, &mtr);
|
||||
fsp_header_init(table->space, FIL_IBD_FILE_INITIAL_SIZE, &mtr);
|
||||
|
||||
mtr_commit(&mtr);
|
||||
|
||||
if(!res) {
|
||||
return (DB_ERROR);
|
||||
}
|
||||
} else {
|
||||
/* Create in the system tablespace: disallow Barracuda
|
||||
features by keeping only the first bit which says whether
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2014, 2017, MariaDB Corporation. All Rights Reserved.
|
||||
Copyright (c) 2014, 2017, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
@ -6115,21 +6115,19 @@ fil_report_invalid_page_access(
|
||||
ulint len, /*!< in: I/O length */
|
||||
ulint type) /*!< in: I/O type */
|
||||
{
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
ib_logf(IB_LOG_LEVEL_FATAL,
|
||||
"Trying to access page number " ULINTPF
|
||||
" in space " ULINTPF
|
||||
" space name %s,"
|
||||
" which is outside the tablespace bounds."
|
||||
" Byte offset " ULINTPF ", len " ULINTPF " i/o type " ULINTPF ".",
|
||||
" Byte offset " ULINTPF ", len " ULINTPF
|
||||
" i/o type " ULINTPF ".%s",
|
||||
block_offset, space_id, space_name,
|
||||
byte_offset, len, type);
|
||||
|
||||
ib_logf(IB_LOG_LEVEL_FATAL,
|
||||
"If you get this error at mysqld startup,"
|
||||
" please check that"
|
||||
" your my.cnf matches the ibdata files"
|
||||
" that you have in the"
|
||||
" MySQL server.");
|
||||
byte_offset, len, type,
|
||||
space_id == 0 && !srv_was_started
|
||||
? "Please check that the configuration matches"
|
||||
" the InnoDB system tablespace location (ibdata files)"
|
||||
: "");
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
|
@ -673,18 +673,13 @@ fsp_header_init_fields(
|
||||
}
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
/** Initializes the space header of a new created space and creates also the
|
||||
insert buffer tree root if space == 0.
|
||||
/** Initialize a tablespace header.
|
||||
@param[in] space_id space id
|
||||
@param[in] size current size in blocks
|
||||
@param[in,out] mtr min-transaction
|
||||
@return true on success, otherwise false. */
|
||||
@param[in,out] mtr mini-transaction */
|
||||
UNIV_INTERN
|
||||
bool
|
||||
fsp_header_init(
|
||||
ulint space_id,
|
||||
ulint size,
|
||||
mtr_t* mtr)
|
||||
void
|
||||
fsp_header_init(ulint space_id, ulint size, mtr_t* mtr)
|
||||
{
|
||||
fsp_header_t* header;
|
||||
buf_block_t* block;
|
||||
@ -728,17 +723,7 @@ fsp_header_init(
|
||||
|
||||
mlog_write_ull(header + FSP_SEG_ID, 1, mtr);
|
||||
|
||||
if (space_id == 0) {
|
||||
fsp_fill_free_list(FALSE, space_id, header, mtr);
|
||||
|
||||
if (btr_create(DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF,
|
||||
0, 0, DICT_IBUF_ID_MIN + space_id,
|
||||
dict_ind_redundant, mtr) == FIL_NULL) {
|
||||
return (false);
|
||||
}
|
||||
} else {
|
||||
fsp_fill_free_list(TRUE, space_id, header, mtr);
|
||||
}
|
||||
fsp_fill_free_list(space_id != TRX_SYS_SPACE, space_id, header, mtr);
|
||||
|
||||
fil_space_t* space = fil_space_acquire(space_id);
|
||||
ut_ad(space);
|
||||
@ -748,8 +733,6 @@ fsp_header_init(
|
||||
}
|
||||
|
||||
fil_space_release(space);
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
@ -2074,10 +2057,6 @@ fseg_create_general(
|
||||
success = fsp_reserve_free_extents(&n_reserved, space, 2,
|
||||
FSP_NORMAL, mtr);
|
||||
if (!success) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Reserving %d free extents failed"
|
||||
" could reserve only " ULINTPF " extents.",
|
||||
2, n_reserved);
|
||||
return(NULL);
|
||||
}
|
||||
}
|
||||
@ -2087,9 +2066,6 @@ fseg_create_general(
|
||||
inode = fsp_alloc_seg_inode(space_header, mtr);
|
||||
|
||||
if (inode == NULL) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Allocation of a new file segment inode page failed.");
|
||||
|
||||
goto funct_exit;
|
||||
}
|
||||
|
||||
@ -2118,9 +2094,6 @@ fseg_create_general(
|
||||
inode, 0, FSP_UP, mtr, mtr);
|
||||
|
||||
if (block == NULL) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Allocation of a free page from space " ULINTPF " failed.",
|
||||
space);
|
||||
|
||||
fsp_free_seg_inode(space, zip_size, inode, mtr);
|
||||
|
||||
|
@ -3770,7 +3770,6 @@ innobase_init(
|
||||
char *default_path;
|
||||
uint format_id;
|
||||
ulong num_pll_degree;
|
||||
ulint min_size = 0;
|
||||
|
||||
DBUG_ENTER("innobase_init");
|
||||
handlerton *innobase_hton= (handlerton*) p;
|
||||
@ -4021,19 +4020,6 @@ mem_free_and_error:
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* All doublewrite buffer pages must fit to first system
|
||||
datafile and first datafile must be at least 3M. */
|
||||
min_size = ut_max((3*1024*1024U), (192U*UNIV_PAGE_SIZE));
|
||||
|
||||
if ((srv_data_file_sizes[0]*1024*1024) < min_size) {
|
||||
sql_print_error(
|
||||
"InnoDB: first datafile is too small current=" ULINTPF
|
||||
"M it should be at least " ULINTPF "M.",
|
||||
srv_data_file_sizes[0],
|
||||
min_size / (1024 * 1024));
|
||||
goto mem_free_and_error;
|
||||
}
|
||||
|
||||
/* -------------- All log files ---------------------------*/
|
||||
|
||||
/* The default dir for log files is the datadir of MySQL */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2017, MariaDB Corporation. All Rights Reserved.
|
||||
Copyright (c) 2017, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
@ -39,13 +39,15 @@ extern buf_dblwr_t* buf_dblwr;
|
||||
/** Set to TRUE when the doublewrite buffer is being created */
|
||||
extern ibool buf_dblwr_being_created;
|
||||
|
||||
/****************************************************************//**
|
||||
Creates the doublewrite buffer to a new InnoDB installation. The header of the
|
||||
doublewrite buffer is placed on the trx system header page. */
|
||||
/** Create the doublewrite buffer if the doublewrite buffer header
|
||||
is not present in the TRX_SYS page.
|
||||
@return whether the operation succeeded
|
||||
@retval true if the doublewrite buffer exists or was created
|
||||
@retval false if the creation failed (too small first data file) */
|
||||
UNIV_INTERN
|
||||
void
|
||||
buf_dblwr_create(void);
|
||||
/*==================*/
|
||||
bool
|
||||
buf_dblwr_create()
|
||||
MY_ATTRIBUTE((warn_unused_result));
|
||||
|
||||
/****************************************************************//**
|
||||
At a database startup initializes the doublewrite buffer memory structure if
|
||||
|
@ -519,19 +519,13 @@ fsp_header_init_fields(
|
||||
ulint space_id, /*!< in: space id */
|
||||
ulint flags); /*!< in: tablespace flags (FSP_SPACE_FLAGS):
|
||||
0, or table->flags if newer than COMPACT */
|
||||
/** Initializes the space header of a new created space and creates also the
|
||||
insert buffer tree root if space == 0.
|
||||
/** Initialize a tablespace header.
|
||||
@param[in] space_id space id
|
||||
@param[in] size current size in blocks
|
||||
@param[in,out] mtr min-transaction
|
||||
@return true on success, otherwise false. */
|
||||
@param[in,out] mtr mini-transaction */
|
||||
UNIV_INTERN
|
||||
bool
|
||||
fsp_header_init(
|
||||
ulint space_id,
|
||||
ulint size,
|
||||
mtr_t* mtr)
|
||||
MY_ATTRIBUTE((warn_unused_result));
|
||||
void
|
||||
fsp_header_init(ulint space_id, ulint size, mtr_t* mtr);
|
||||
|
||||
/**********************************************************************//**
|
||||
Increases the space size field of a space. */
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2017, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
@ -124,13 +125,13 @@ trx_rseg_mem_free(
|
||||
/*==============*/
|
||||
trx_rseg_t* rseg); /*!< in, own: instance to free */
|
||||
|
||||
/*********************************************************************
|
||||
Creates a rollback segment. */
|
||||
/** Create a rollback segment.
|
||||
@param[in] space undo tablespace ID
|
||||
@return pointer to new rollback segment
|
||||
@retval NULL on failure */
|
||||
UNIV_INTERN
|
||||
trx_rseg_t*
|
||||
trx_rseg_create(
|
||||
/*============*/
|
||||
ulint space); /*!< in: id of UNDO tablespace */
|
||||
trx_rseg_create(ulint space);
|
||||
|
||||
/********************************************************************
|
||||
Get the number of unique rollback tablespaces in use except space id 0.
|
||||
|
@ -3004,11 +3004,6 @@ recv_init_crash_recovery(void)
|
||||
possible */
|
||||
|
||||
if (srv_force_recovery < SRV_FORCE_NO_LOG_REDO) {
|
||||
|
||||
ib_logf(IB_LOG_LEVEL_INFO,
|
||||
"Restoring possible half-written data pages "
|
||||
"from the doublewrite buffer...");
|
||||
|
||||
buf_dblwr_process();
|
||||
|
||||
/* Spawn the background thread to flush dirty pages
|
||||
@ -3276,24 +3271,6 @@ recv_recovery_from_checkpoint_start_func(
|
||||
user about recovery: */
|
||||
|
||||
if (checkpoint_lsn != flushed_lsn) {
|
||||
|
||||
if (checkpoint_lsn <flushed_lsn) {
|
||||
|
||||
ib_logf(IB_LOG_LEVEL_WARN,
|
||||
"The log sequence number "
|
||||
"in the ibdata files is higher "
|
||||
"than the log sequence number "
|
||||
"in the ib_logfiles! Are you sure "
|
||||
"you are using the right "
|
||||
"ib_logfiles to start up the database. "
|
||||
"Log sequence number in the "
|
||||
"ib_logfiles is " LSN_PF ", log"
|
||||
"sequence number stamped "
|
||||
"to ibdata file header is " LSN_PF ".",
|
||||
checkpoint_lsn,
|
||||
flushed_lsn);
|
||||
}
|
||||
|
||||
if (!recv_needed_recovery) {
|
||||
ib_logf(IB_LOG_LEVEL_INFO,
|
||||
"The log sequence number "
|
||||
|
@ -3614,15 +3614,9 @@ row_truncate_table_for_mysql(
|
||||
} while (index);
|
||||
|
||||
mtr_start_trx(&mtr, trx);
|
||||
bool ret = fsp_header_init(space_id,
|
||||
fsp_header_init(space_id,
|
||||
FIL_IBD_FILE_INITIAL_SIZE, &mtr);
|
||||
mtr_commit(&mtr);
|
||||
|
||||
if (!ret) {
|
||||
table->file_unreadable = true;
|
||||
err = DB_ERROR;
|
||||
goto funct_exit;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Lock all index trees for this table, as we will
|
||||
|
@ -1601,26 +1601,18 @@ srv_undo_tablespaces_init(
|
||||
|
||||
if (create_new_db) {
|
||||
mtr_t mtr;
|
||||
bool ret=true;
|
||||
|
||||
mtr_start(&mtr);
|
||||
|
||||
/* The undo log tablespace */
|
||||
for (i = 0; i < n_undo_tablespaces; ++i) {
|
||||
|
||||
ret = fsp_header_init(
|
||||
fsp_header_init(
|
||||
undo_tablespace_ids[i],
|
||||
SRV_UNDO_TABLESPACE_SIZE_IN_PAGES, &mtr);
|
||||
if (!ret) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mtr_commit(&mtr);
|
||||
|
||||
if (!ret) {
|
||||
return (srv_init_abort(create_new_db, __FILE__, __LINE__, DB_ERROR));
|
||||
}
|
||||
}
|
||||
|
||||
return(DB_SUCCESS);
|
||||
@ -2507,14 +2499,24 @@ files_checked:
|
||||
|
||||
mtr_start(&mtr);
|
||||
|
||||
bool ret = fsp_header_init(0, sum_of_new_sizes, &mtr);
|
||||
fsp_header_init(0, sum_of_new_sizes, &mtr);
|
||||
compile_time_assert(TRX_SYS_SPACE == 0);
|
||||
compile_time_assert(IBUF_SPACE_ID == 0);
|
||||
|
||||
ulint ibuf_root = btr_create(
|
||||
DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF,
|
||||
0, 0, DICT_IBUF_ID_MIN,
|
||||
dict_ind_redundant, &mtr);
|
||||
|
||||
mtr_commit(&mtr);
|
||||
|
||||
if (!ret) {
|
||||
return (srv_init_abort(create_new_db, __FILE__, __LINE__, DB_ERROR));
|
||||
if (ibuf_root == FIL_NULL) {
|
||||
return(srv_init_abort(true, __FILE__, __LINE__,
|
||||
DB_ERROR));
|
||||
}
|
||||
|
||||
ut_ad(ibuf_root == IBUF_TREE_ROOT_PAGE_NO);
|
||||
|
||||
/* To maintain backward compatibility we create only
|
||||
the first rollback segment before the double write buffer.
|
||||
All the remaining rollback segments will be created later,
|
||||
@ -2901,10 +2903,9 @@ files_checked:
|
||||
/* fprintf(stderr, "Max allowed record size %lu\n",
|
||||
page_get_free_space_of_empty() / 2); */
|
||||
|
||||
if (buf_dblwr == NULL) {
|
||||
/* Create the doublewrite buffer to a new tablespace */
|
||||
|
||||
buf_dblwr_create();
|
||||
if (!buf_dblwr_create()) {
|
||||
return(srv_init_abort(create_new_db, __FILE__, __LINE__,
|
||||
DB_ERROR));
|
||||
}
|
||||
|
||||
/* Here the double write buffer has already been created and so
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2017, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
@ -293,14 +294,13 @@ trx_rseg_create_instance(
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
Creates a rollback segment.
|
||||
@return pointer to new rollback segment if create successful */
|
||||
/** Create a rollback segment.
|
||||
@param[in] space undo tablespace ID
|
||||
@return pointer to new rollback segment
|
||||
@retval NULL on failure */
|
||||
UNIV_INTERN
|
||||
trx_rseg_t*
|
||||
trx_rseg_create(
|
||||
/*============*/
|
||||
ulint space) /*!< in: id of UNDO tablespace */
|
||||
trx_rseg_create(ulint space)
|
||||
{
|
||||
mtr_t mtr;
|
||||
ulint slot_no;
|
||||
@ -323,25 +323,21 @@ trx_rseg_create(
|
||||
page_no = trx_rseg_header_create(
|
||||
space, 0, ULINT_MAX, slot_no, &mtr);
|
||||
|
||||
if (page_no == FIL_NULL) {
|
||||
mtr_commit(&mtr);
|
||||
return (rseg);
|
||||
if (page_no != FIL_NULL) {
|
||||
sys_header = trx_sysf_get(&mtr);
|
||||
|
||||
id = trx_sysf_rseg_get_space(sys_header, slot_no, &mtr);
|
||||
ut_a(id == space);
|
||||
|
||||
zip_size = space ? fil_space_get_zip_size(space) : 0;
|
||||
|
||||
rseg = trx_rseg_mem_create(
|
||||
slot_no, space, zip_size, page_no,
|
||||
purge_sys->ib_bh, &mtr);
|
||||
}
|
||||
|
||||
sys_header = trx_sysf_get(&mtr);
|
||||
|
||||
id = trx_sysf_rseg_get_space(sys_header, slot_no, &mtr);
|
||||
ut_a(id == space);
|
||||
|
||||
zip_size = space ? fil_space_get_zip_size(space) : 0;
|
||||
|
||||
rseg = trx_rseg_mem_create(
|
||||
slot_no, space, zip_size, page_no,
|
||||
purge_sys->ib_bh, &mtr);
|
||||
}
|
||||
|
||||
mtr_commit(&mtr);
|
||||
|
||||
return(rseg);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user