summaryrefslogtreecommitdiffstats
path: root/storage/innobase/fsp
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/fsp')
-rw-r--r--storage/innobase/fsp/fsp0file.cc26
-rw-r--r--storage/innobase/fsp/fsp0fsp.cc57
-rw-r--r--storage/innobase/fsp/fsp0sysspace.cc64
3 files changed, 70 insertions, 77 deletions
diff --git a/storage/innobase/fsp/fsp0file.cc b/storage/innobase/fsp/fsp0file.cc
index cafff419..1c20efcd 100644
--- a/storage/innobase/fsp/fsp0file.cc
+++ b/storage/innobase/fsp/fsp0file.cc
@@ -435,12 +435,22 @@ Datafile::validate_for_recovery()
return(err);
}
+ if (!m_space_id) {
+ m_space_id = recv_sys.dblwr.find_first_page(
+ m_filepath, m_handle);
+ if (m_space_id) {
+ m_defer= false;
+ goto free_first_page;
+ } else return err;
+ }
+
if (!m_defer) {
err = find_space_id();
if (err != DB_SUCCESS || m_space_id == 0) {
- ib::error() << "Datafile '" << m_filepath
- << "' is corrupted. Cannot determine "
- "the space ID from the first 64 pages.";
+ sql_print_error(
+ "InnoDB: Datafile '%s' is corrupted."
+ " Cannot determine the space ID from"
+ " the first 64 pages.", m_filepath);
return(err);
}
}
@@ -453,7 +463,7 @@ Datafile::validate_for_recovery()
m_space_id, m_filepath, m_handle)) {
return m_defer ? err : DB_CORRUPTION;
}
-
+free_first_page:
/* Free the previously read first page and then re-validate. */
free_first_page();
m_defer = false;
@@ -492,11 +502,11 @@ err_exit:
return DB_SUCCESS;
}
- ib::info() << error_txt << " in datafile: " << m_filepath
- << ", Space ID:" << m_space_id << ", Flags: "
- << m_flags;
+ sql_print_error("InnoDB: %s in datafile: %s, Space ID: "
+ UINT32PF ", " "Flags: " UINT32PF,
+ error_txt, m_filepath, m_space_id, m_flags);
m_is_valid = false;
- return(DB_CORRUPTION);
+ return DB_CORRUPTION;
}
/* Check if the whole page is blank. */
diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc
index 6c5c354e..87672a82 100644
--- a/storage/innobase/fsp/fsp0fsp.cc
+++ b/storage/innobase/fsp/fsp0fsp.cc
@@ -42,8 +42,6 @@ Created 11/29/1995 Heikki Tuuri
#include "fsp0types.h"
#include "log.h"
-typedef uint32_t page_no_t;
-
/** Returns the first extent descriptor for a segment.
We think of the extent lists of the segment catenated in the order
FSEG_FULL -> FSEG_NOT_FULL -> FSEG_FREE.
@@ -332,7 +330,7 @@ xdes_t*
xdes_get_descriptor_with_space_hdr(
buf_block_t* header,
const fil_space_t* space,
- page_no_t offset,
+ uint32_t offset,
mtr_t* mtr,
dberr_t* err = nullptr,
buf_block_t** desc_block = nullptr,
@@ -396,7 +394,7 @@ try to add new extents to the space free list
@param[out] err error code
@param[out] xdes extent descriptor page
@return the extent descriptor */
-static xdes_t *xdes_get_descriptor(const fil_space_t *space, page_no_t offset,
+static xdes_t *xdes_get_descriptor(const fil_space_t *space, uint32_t offset,
mtr_t *mtr, dberr_t *err= nullptr,
buf_block_t **xdes= nullptr)
{
@@ -842,8 +840,7 @@ fsp_fill_free_list(
if (i)
{
buf_block_t *f= buf_LRU_get_free_block(false);
- buf_block_t *block= buf_page_create(space, static_cast<uint32_t>(i),
- zip_size, mtr, f);
+ buf_block_t *block= buf_page_create(space, i, zip_size, mtr, f);
if (UNIV_UNLIKELY(block != f))
buf_pool.free_block(f);
fsp_init_file_page(space, block, mtr);
@@ -855,9 +852,7 @@ fsp_fill_free_list(
{
buf_block_t *f= buf_LRU_get_free_block(false);
buf_block_t *block=
- buf_page_create(space,
- static_cast<uint32_t>(i + FSP_IBUF_BITMAP_OFFSET),
- zip_size, mtr, f);
+ buf_page_create(space, i + FSP_IBUF_BITMAP_OFFSET, zip_size, mtr, f);
if (UNIV_UNLIKELY(block != f))
buf_pool.free_block(f);
fsp_init_file_page(space, block, mtr);
@@ -1028,40 +1023,13 @@ fsp_alloc_from_free_frag(buf_block_t *header, buf_block_t *xdes, xdes_t *descr,
@param[in] offset page number of the allocated page
@param[in,out] mtr mini-transaction
@return block, initialized */
-static
-buf_block_t*
-fsp_page_create(fil_space_t *space, page_no_t offset, mtr_t *mtr)
+static buf_block_t* fsp_page_create(fil_space_t *space, uint32_t offset,
+ mtr_t *mtr)
{
- buf_block_t *block, *free_block;
-
- if (UNIV_UNLIKELY(space->is_being_truncated))
- {
- const page_id_t page_id{space->id, offset};
- buf_pool_t::hash_chain &chain= buf_pool.page_hash.cell_get(page_id.fold());
- mysql_mutex_lock(&buf_pool.mutex);
- block= reinterpret_cast<buf_block_t*>
- (buf_pool.page_hash.get(page_id, chain));
- if (block && block->page.oldest_modification() <= 1)
- block= nullptr;
- mysql_mutex_unlock(&buf_pool.mutex);
-
- if (block)
- {
- ut_ad(block->page.buf_fix_count() >= 1);
- ut_ad(block->page.lock.x_lock_count() == 1);
- ut_ad(mtr->have_x_latch(*block));
- free_block= block;
- goto got_free_block;
- }
- }
-
- free_block= buf_LRU_get_free_block(false);
-got_free_block:
- block= buf_page_create(space, static_cast<uint32_t>(offset),
- space->zip_size(), mtr, free_block);
+ buf_block_t *free_block= buf_LRU_get_free_block(false),
+ *block= buf_page_create(space, offset, space->zip_size(), mtr, free_block);
if (UNIV_UNLIKELY(block != free_block))
buf_pool.free_block(free_block);
-
fsp_init_file_page(space, block, mtr);
return block;
}
@@ -1179,7 +1147,7 @@ MY_ATTRIBUTE((nonnull, warn_unused_result))
@param[in] offset page number in the extent
@param[in,out] mtr mini-transaction
@return error code */
-static dberr_t fsp_free_extent(fil_space_t* space, page_no_t offset,
+static dberr_t fsp_free_extent(fil_space_t* space, uint32_t offset,
mtr_t* mtr)
{
ut_ad(space->is_owner());
@@ -1216,7 +1184,7 @@ The page is marked as free and clean.
@param[in] offset page number
@param[in,out] mtr mini-transaction
@return error code */
-static dberr_t fsp_free_page(fil_space_t *space, page_no_t offset, mtr_t *mtr)
+static dberr_t fsp_free_page(fil_space_t *space, uint32_t offset, mtr_t *mtr)
{
xdes_t* descr;
ulint frag_n_used;
@@ -1756,7 +1724,6 @@ page_alloc:
ut_d(const auto x = block->page.lock.x_lock_count());
ut_ad(x || block->page.lock.not_recursive());
- ut_ad(x == 1 || space->is_being_truncated);
ut_ad(x <= 2);
ut_ad(!fil_page_get_type(block->page.frame));
mtr->write<1>(*block, FIL_PAGE_TYPE + 1 + block->page.frame,
@@ -2493,7 +2460,7 @@ fseg_free_page_low(
fseg_inode_t* seg_inode,
buf_block_t* iblock,
fil_space_t* space,
- page_no_t offset,
+ uint32_t offset,
mtr_t* mtr
#ifdef BTR_CUR_HASH_ADAPT
,bool ahi=false
@@ -2859,7 +2826,7 @@ fseg_free_step(
return true;
}
- page_no_t page_no = fseg_get_nth_frag_page_no(inode, n);
+ uint32_t page_no = fseg_get_nth_frag_page_no(inode, n);
if (fseg_free_page_low(inode, iblock, space, page_no, mtr
#ifdef BTR_CUR_HASH_ADAPT
diff --git a/storage/innobase/fsp/fsp0sysspace.cc b/storage/innobase/fsp/fsp0sysspace.cc
index e4a43e48..4ac9da50 100644
--- a/storage/innobase/fsp/fsp0sysspace.cc
+++ b/storage/innobase/fsp/fsp0sysspace.cc
@@ -33,6 +33,7 @@ Refactored 2013-7-26 by Kevin Lewis
#include "os0file.h"
#include "row0mysql.h"
#include "buf0dblwr.h"
+#include "log.h"
/** The server header file is included to access opt_initialize global variable.
If server passes the option for create/open DB to SE, we should remove such
@@ -568,7 +569,7 @@ inline dberr_t SysTablespace::read_lsn_and_check_flags()
}
err = it->read_first_page(
- m_ignore_read_only ? false : srv_read_only_mode);
+ m_ignore_read_only && srv_read_only_mode);
if (err != DB_SUCCESS) {
return(err);
@@ -582,47 +583,62 @@ inline dberr_t SysTablespace::read_lsn_and_check_flags()
/* Check the contents of the first page of the
first datafile. */
- for (int retry = 0; retry < 2; ++retry) {
+ err = it->validate_first_page();
- err = it->validate_first_page();
-
- if (err != DB_SUCCESS
- && (retry == 1
- || recv_sys.dblwr.restore_first_page(
+ if (err != DB_SUCCESS) {
+ if (recv_sys.dblwr.restore_first_page(
it->m_space_id, it->m_filepath,
- it->handle()))) {
-
+ it->handle())) {
it->close();
-
return(err);
}
+ err = it->read_first_page(
+ m_ignore_read_only && srv_read_only_mode);
}
/* Make sure the tablespace space ID matches the
space ID on the first page of the first datafile. */
- if (space_id() != it->m_space_id) {
-
- ib::error()
- << "The data file '" << it->filepath()
- << "' has the wrong space ID. It should be "
- << space_id() << ", but " << it->m_space_id
- << " was found";
-
+ if (err != DB_SUCCESS || space_id() != it->m_space_id) {
+ sql_print_error("InnoDB: The data file '%s'"
+ " has the wrong space ID."
+ " It should be " UINT32PF ", but " UINT32PF
+ " was found", it->filepath(),
+ space_id(), it->m_space_id);
it->close();
-
- return(err);
+ return err;
}
- if (srv_operation == SRV_OPERATION_NORMAL) {
+ if (srv_force_recovery != 6
+ && srv_operation == SRV_OPERATION_NORMAL
+ && !log_sys.next_checkpoint_lsn
+ && log_sys.format == log_t::FORMAT_3_23) {
+
+ log_sys.latch.wr_lock(SRW_LOCK_CALL);
/* Prepare for possible upgrade from 0-sized ib_logfile0. */
- ut_ad(!log_sys.next_checkpoint_lsn);
log_sys.next_checkpoint_lsn = mach_read_from_8(
it->m_first_page + 26/*FIL_PAGE_FILE_FLUSH_LSN*/);
+ if (log_sys.next_checkpoint_lsn < 8204) {
+ /* Before MDEV-14425, InnoDB had a minimum LSN
+ of 8192+12=8204. Likewise, mariadb-backup
+ --prepare would create an empty ib_logfile0
+ after applying the log. We will allow an
+ upgrade from such an empty log. */
+ sql_print_error("InnoDB: ib_logfile0 is "
+ "empty, and LSN is unknown.");
+ err = DB_CORRUPTION;
+ } else {
+ log_sys.last_checkpoint_lsn =
+ recv_sys.lsn = recv_sys.file_checkpoint =
+ log_sys.next_checkpoint_lsn;
+ log_sys.set_recovered_lsn(log_sys.next_checkpoint_lsn);
+ log_sys.next_checkpoint_no = 0;
+ }
+
+ log_sys.latch.wr_unlock();
}
it->close();
-
- return(DB_SUCCESS);
+ return err;
}
/** Check if a file can be opened in the correct mode.