mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
MDEV-12113: install_db shows corruption for rest encryption with innodb_data_file_path=ibdata1:3M;
Problem was that FIL_PAGE_FLUSH_LSN_OR_KEY_VERSION field that for encrypted pages even in system datafiles should contain key_version except very first page (0:0) is after encryption overwritten with flush lsn. Ported WL#7990 Repurpose FIL_PAGE_FLUSH_LSN to 10.1 The field FIL_PAGE_FLUSH_LSN_OR_KEY_VERSION is consulted during InnoDB startup. At startup, InnoDB reads the FIL_PAGE_FLUSH_LSN_OR_KEY_VERSION from the first page of each file in the InnoDB system tablespace. If there are multiple files, the minimum and maximum LSN can differ. These numbers are passed to InnoDB startup. Having the number in other files than the first file of the InnoDB system tablespace is not providing much additional value. It is conflicting with other use of the field, such as on InnoDB R-tree index pages and encryption key_version. This worklog will stop writing FIL_PAGE_FLUSH_LSN_OR_KEY_VERSION to other files than the first file of the InnoDB system tablespace (page number 0:0) when system tablespace is encrypted. If tablespace is not encrypted we continue writing FIL_PAGE_FLUSH_LSN_OR_KEY_VERSION to all first pages of system tablespace to avoid unnecessary warnings on downgrade. open_or_create_data_files(): pass only one flushed_lsn parameter xb_load_tablespaces(): pass only one flushed_lsn parameter. buf_page_create(): Improve comment about where FIL_PAGE_FIL_FLUSH_LSN_OR_KEY_VERSION is set. fil_write_flushed_lsn(): A new function, merged from fil_write_lsn_and_arch_no_to_file() and fil_write_flushed_lsn_to_data_files(). Only write to the first page of the system tablespace (page 0:0) if tablespace is encrypted, or write all first pages of system tablespace and invoke fil_flush_file_spaces(FIL_TYPE_TABLESPACE) afterwards. fil_read_first_page(): read flush_lsn and crypt_data only from first datafile. fil_open_single_table_tablespace(): Remove output of LSN, because it was only valid for the system tablespace and the undo tablespaces, not user tablespaces. fil_validate_single_table_tablespace(): Remove output of LSN. checkpoint_now_set(): Use fil_write_flushed_lsn and output a error if operation fails. Remove lsn variable from fsp_open_info. recv_recovery_from_checkpoint_start(): Remove unnecessary second flush_lsn parameter. log_empty_and_mark_files_at_shutdown(): Use fil_writte_flushed_lsn and output error if it fails. open_or_create_data_files(): Pass only one flushed_lsn variable.
This commit is contained in:
parent
473f4a65e1
commit
1af8bf39ca
18 changed files with 557 additions and 604 deletions
|
@ -27,13 +27,12 @@ extern pfs_os_file_t files[1000];
|
|||
extern const char *innodb_checksum_algorithm_names[];
|
||||
extern TYPELIB innodb_checksum_algorithm_typelib;
|
||||
extern dberr_t open_or_create_data_files(
|
||||
ibool* create_new_db,
|
||||
bool* create_new_db,
|
||||
#ifdef UNIV_LOG_ARCHIVE
|
||||
lsn_t* min_arch_log_no,
|
||||
lsn_t* max_arch_log_no,
|
||||
#endif
|
||||
lsn_t* min_flushed_lsn,
|
||||
lsn_t* max_flushed_lsn,
|
||||
#endif
|
||||
lsn_t* flushed_lsn,
|
||||
ulint* sum_of_new_sizes)
|
||||
;
|
||||
int
|
||||
|
|
|
@ -309,8 +309,7 @@ my_bool xtrabackup_rebuild_indexes = FALSE;
|
|||
my_bool xtrabackup_incremental_force_scan = FALSE;
|
||||
|
||||
/* The flushed lsn which is read from data files */
|
||||
lsn_t min_flushed_lsn= 0;
|
||||
lsn_t max_flushed_lsn= 0;
|
||||
lsn_t flushed_lsn= 0;
|
||||
|
||||
/* The size of archived log file */
|
||||
ib_int64_t xtrabackup_arch_file_size = 0ULL;
|
||||
|
@ -3249,7 +3248,7 @@ xb_load_tablespaces(void)
|
|||
/*=====================*/
|
||||
{
|
||||
ulint i;
|
||||
ibool create_new_db;
|
||||
bool create_new_db;
|
||||
ulint err;
|
||||
ulint sum_of_new_sizes;
|
||||
lsn_t min_arch_logno, max_arch_logno;
|
||||
|
@ -3265,7 +3264,7 @@ xb_load_tablespaces(void)
|
|||
|
||||
err = open_or_create_data_files(&create_new_db,
|
||||
&min_arch_logno, &max_arch_logno,
|
||||
&min_flushed_lsn, &max_flushed_lsn,
|
||||
&flushed_lsn,
|
||||
&sum_of_new_sizes);
|
||||
if (err != DB_SUCCESS) {
|
||||
msg("xtrabackup: Could not open or create data files.\n"
|
||||
|
@ -6475,13 +6474,13 @@ skip_check:
|
|||
metadata_last_lsn);
|
||||
xtrabackup_archived_to_lsn = metadata_last_lsn;
|
||||
}
|
||||
if (xtrabackup_archived_to_lsn < min_flushed_lsn) {
|
||||
if (xtrabackup_archived_to_lsn < flushed_lsn) {
|
||||
msg("xtrabackup: error: logs applying "
|
||||
"lsn limit " UINT64PF " is less than "
|
||||
"min_flushed_lsn " UINT64PF
|
||||
", there is nothing to do\n",
|
||||
xtrabackup_archived_to_lsn,
|
||||
min_flushed_lsn);
|
||||
flushed_lsn);
|
||||
goto error_cleanup;
|
||||
}
|
||||
}
|
||||
|
@ -6492,7 +6491,7 @@ skip_check:
|
|||
*/
|
||||
xtrabackup_apply_log_only = srv_apply_log_only = true;
|
||||
|
||||
if (!xtrabackup_arch_search_files(min_flushed_lsn)) {
|
||||
if (!xtrabackup_arch_search_files(flushed_lsn)) {
|
||||
goto error_cleanup;
|
||||
}
|
||||
|
||||
|
|
|
@ -4291,11 +4291,11 @@ buf_page_create(
|
|||
memset(frame + FIL_PAGE_NEXT, 0xff, 4);
|
||||
mach_write_to_2(frame + FIL_PAGE_TYPE, FIL_PAGE_TYPE_ALLOCATED);
|
||||
|
||||
/* Reset to zero the file flush lsn field in the page; if the first
|
||||
page of an ibdata file is 'created' in this function into the buffer
|
||||
pool then we lose the original contents of the file flush lsn stamp.
|
||||
Then InnoDB could in a crash recovery print a big, false, corruption
|
||||
warning if the stamp contains an lsn bigger than the ib_logfile lsn. */
|
||||
/* FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION is only used on the
|
||||
following pages:
|
||||
(1) The first page of the InnoDB system tablespace (page 0:0)
|
||||
(2) FIL_RTREE_SPLIT_SEQ_NUM on R-tree pages
|
||||
(3) key_version on encrypted pages (not page 0:0) */
|
||||
|
||||
memset(frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, 0, 8);
|
||||
|
||||
|
|
|
@ -2211,99 +2211,70 @@ fil_set_max_space_id_if_bigger(
|
|||
mutex_exit(&fil_system->mutex);
|
||||
}
|
||||
|
||||
/****************************************************************//**
|
||||
Writes the flushed lsn and the latest archived log number to the page header
|
||||
of the first page of a data file of the system tablespace (space 0),
|
||||
which is uncompressed. */
|
||||
static MY_ATTRIBUTE((warn_unused_result))
|
||||
/** Write the flushed LSN to the page header of the first page in the
|
||||
system tablespace.
|
||||
@param[in] lsn flushed LSN
|
||||
@return DB_SUCCESS or error number */
|
||||
dberr_t
|
||||
fil_write_lsn_and_arch_no_to_file(
|
||||
/*==============================*/
|
||||
ulint space, /*!< in: space to write to */
|
||||
ulint sum_of_sizes, /*!< in: combined size of previous files
|
||||
in space, in database pages */
|
||||
lsn_t lsn, /*!< in: lsn to write */
|
||||
ulint arch_log_no MY_ATTRIBUTE((unused)))
|
||||
/*!< in: archived log number to write */
|
||||
fil_write_flushed_lsn(
|
||||
lsn_t lsn)
|
||||
{
|
||||
byte* buf1;
|
||||
byte* buf;
|
||||
dberr_t err;
|
||||
|
||||
buf1 = static_cast<byte*>(mem_alloc(2 * UNIV_PAGE_SIZE));
|
||||
buf1 = static_cast<byte*>(ut_malloc(2 * UNIV_PAGE_SIZE));
|
||||
buf = static_cast<byte*>(ut_align(buf1, UNIV_PAGE_SIZE));
|
||||
|
||||
err = fil_read(TRUE, space, 0, sum_of_sizes, 0,
|
||||
UNIV_PAGE_SIZE, buf, NULL, 0);
|
||||
if (err == DB_SUCCESS) {
|
||||
mach_write_to_8(buf + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION,
|
||||
lsn);
|
||||
/* Acquire system tablespace */
|
||||
fil_space_t* space = fil_space_acquire(0);
|
||||
|
||||
err = fil_write(TRUE, space, 0, sum_of_sizes, 0,
|
||||
UNIV_PAGE_SIZE, buf, NULL, 0);
|
||||
}
|
||||
/* If tablespace is not encrypted, stamp flush_lsn to
|
||||
first page of all system tablespace datafiles to avoid
|
||||
unnecessary error messages on possible downgrade. */
|
||||
if (space->crypt_data->min_key_version == 0) {
|
||||
fil_node_t* node;
|
||||
ulint sum_of_sizes = 0;
|
||||
|
||||
mem_free(buf1);
|
||||
for (node = UT_LIST_GET_FIRST(space->chain);
|
||||
node != NULL;
|
||||
node = UT_LIST_GET_NEXT(chain, node)) {
|
||||
|
||||
return(err);
|
||||
}
|
||||
err = fil_read(TRUE, 0, 0, sum_of_sizes, 0,
|
||||
UNIV_PAGE_SIZE, buf, NULL, 0);
|
||||
|
||||
/****************************************************************//**
|
||||
Writes the flushed lsn and the latest archived log number to the page
|
||||
header of the first page of each data file in the system tablespace.
|
||||
@return DB_SUCCESS or error number */
|
||||
UNIV_INTERN
|
||||
dberr_t
|
||||
fil_write_flushed_lsn_to_data_files(
|
||||
/*================================*/
|
||||
lsn_t lsn, /*!< in: lsn to write */
|
||||
ulint arch_log_no) /*!< in: latest archived log file number */
|
||||
{
|
||||
fil_space_t* space;
|
||||
fil_node_t* node;
|
||||
dberr_t err;
|
||||
if (err == DB_SUCCESS) {
|
||||
mach_write_to_8(buf + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION,
|
||||
lsn);
|
||||
|
||||
mutex_enter(&fil_system->mutex);
|
||||
|
||||
for (space = UT_LIST_GET_FIRST(fil_system->space_list);
|
||||
space != NULL;
|
||||
space = UT_LIST_GET_NEXT(space_list, space)) {
|
||||
|
||||
/* We only write the lsn to all existing data files which have
|
||||
been open during the lifetime of the mysqld process; they are
|
||||
represented by the space objects in the tablespace memory
|
||||
cache. Note that all data files in the system tablespace 0
|
||||
and the UNDO log tablespaces (if separate) are always open. */
|
||||
|
||||
if (space->purpose == FIL_TABLESPACE
|
||||
&& !fil_is_user_tablespace_id(space->id)) {
|
||||
ulint sum_of_sizes = 0;
|
||||
|
||||
for (node = UT_LIST_GET_FIRST(space->chain);
|
||||
node != NULL;
|
||||
node = UT_LIST_GET_NEXT(chain, node)) {
|
||||
|
||||
mutex_exit(&fil_system->mutex);
|
||||
|
||||
err = fil_write_lsn_and_arch_no_to_file(
|
||||
space->id, sum_of_sizes, lsn,
|
||||
arch_log_no);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
|
||||
return(err);
|
||||
}
|
||||
|
||||
mutex_enter(&fil_system->mutex);
|
||||
err = fil_write(TRUE, 0, 0, sum_of_sizes, 0,
|
||||
UNIV_PAGE_SIZE, buf, NULL, 0);
|
||||
|
||||
sum_of_sizes += node->size;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* When system tablespace is encrypted stamp flush_lsn to
|
||||
only the first page of the first datafile (rest of pages
|
||||
are encrypted). */
|
||||
err = fil_read(TRUE, 0, 0, 0, 0,
|
||||
UNIV_PAGE_SIZE, buf, NULL, 0);
|
||||
|
||||
if (err == DB_SUCCESS) {
|
||||
mach_write_to_8(buf + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION,
|
||||
lsn);
|
||||
|
||||
err = fil_write(TRUE, 0, 0, 0, 0,
|
||||
UNIV_PAGE_SIZE, buf, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
mutex_exit(&fil_system->mutex);
|
||||
fil_flush_file_spaces(FIL_TABLESPACE);
|
||||
fil_space_release(space);
|
||||
|
||||
return(DB_SUCCESS);
|
||||
ut_free(buf1);
|
||||
|
||||
return(err);
|
||||
}
|
||||
|
||||
/** Check the consistency of the first data page of a tablespace
|
||||
|
@ -2356,36 +2327,37 @@ fil_check_first_page(const page_t* page, ulint space_id, ulint flags)
|
|||
return("inconsistent data in space header");
|
||||
}
|
||||
|
||||
/*******************************************************************//**
|
||||
Reads the flushed lsn, arch no, space_id and tablespace flag fields from
|
||||
the first page of a data file at database startup.
|
||||
/** Reads the flushed lsn, arch no, space_id and tablespace flag fields from
|
||||
the first page of a first data file at database startup.
|
||||
@param[in] data_file open data file
|
||||
@param[in] one_read_only true if first datafile is already
|
||||
read
|
||||
@param[out] flags FSP_SPACE_FLAGS
|
||||
@param[out] space_id tablepspace ID
|
||||
@param[out] min_arch_log_no min of archived log numbers in
|
||||
data files
|
||||
@param[out] max_arch_log_no max of archived log numbers in
|
||||
data files
|
||||
@param[out] flushed_lsn flushed lsn value
|
||||
@param[out] crypt_data encryption crypt data
|
||||
@retval NULL on success, or if innodb_force_recovery is set
|
||||
@return pointer to an error message string */
|
||||
UNIV_INTERN
|
||||
const char*
|
||||
fil_read_first_page(
|
||||
/*================*/
|
||||
pfs_os_file_t data_file, /*!< in: open data file */
|
||||
ibool one_read_already, /*!< in: TRUE if min and max
|
||||
parameters below already
|
||||
contain sensible data */
|
||||
ulint* flags, /*!< out: FSP_SPACE_FLAGS */
|
||||
ulint* space_id, /*!< out: tablespace ID */
|
||||
pfs_os_file_t data_file,
|
||||
ibool one_read_already,
|
||||
ulint* flags,
|
||||
ulint* space_id,
|
||||
#ifdef UNIV_LOG_ARCHIVE
|
||||
ulint* min_arch_log_no, /*!< out: min of archived
|
||||
log numbers in data files */
|
||||
ulint* max_arch_log_no, /*!< out: max of archived
|
||||
log numbers in data files */
|
||||
ulint* min_arch_log_no,
|
||||
ulint* max_arch_log_no,
|
||||
#endif /* UNIV_LOG_ARCHIVE */
|
||||
lsn_t* min_flushed_lsn, /*!< out: min of flushed
|
||||
lsn values in data files */
|
||||
lsn_t* max_flushed_lsn, /*!< out: max of flushed
|
||||
lsn values in data files */
|
||||
fil_space_crypt_t** crypt_data) /*< out: crypt data */
|
||||
lsn_t* flushed_lsn,
|
||||
fil_space_crypt_t** crypt_data)
|
||||
{
|
||||
byte* buf;
|
||||
byte* page;
|
||||
lsn_t flushed_lsn;
|
||||
const char* check_msg = NULL;
|
||||
fil_space_crypt_t* cdata;
|
||||
|
||||
|
@ -2407,6 +2379,11 @@ fil_read_first_page(
|
|||
*space_id = fsp_header_get_space_id(page);
|
||||
*flags = fsp_header_get_flags(page);
|
||||
|
||||
if (flushed_lsn) {
|
||||
*flushed_lsn = mach_read_from_8(page +
|
||||
FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
|
||||
}
|
||||
|
||||
if (!fsp_flags_is_valid(*flags)) {
|
||||
ulint cflags = fsp_flags_convert_from_101(*flags);
|
||||
if (cflags == ULINT_UNDEFINED) {
|
||||
|
@ -2420,33 +2397,33 @@ fil_read_first_page(
|
|||
}
|
||||
|
||||
check_msg = fil_check_first_page(page, *space_id, *flags);
|
||||
}
|
||||
|
||||
flushed_lsn = mach_read_from_8(page +
|
||||
FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
|
||||
/* Possible encryption crypt data is also stored only to first page
|
||||
of the first datafile. */
|
||||
|
||||
ulint space = fsp_header_get_space_id(page);
|
||||
ulint offset = fsp_header_get_crypt_offset(
|
||||
fsp_flags_get_zip_size(*flags));
|
||||
ulint offset = fsp_header_get_crypt_offset(
|
||||
fsp_flags_get_zip_size(*flags));
|
||||
|
||||
cdata = fil_space_read_crypt_data(space, page, offset);
|
||||
cdata = fil_space_read_crypt_data(*space_id, page, offset);
|
||||
|
||||
if (crypt_data) {
|
||||
*crypt_data = cdata;
|
||||
}
|
||||
if (crypt_data) {
|
||||
*crypt_data = cdata;
|
||||
}
|
||||
|
||||
/* If file space is encrypted we need to have at least some
|
||||
encryption service available where to get keys */
|
||||
if (cdata && cdata->should_encrypt()) {
|
||||
/* If file space is encrypted we need to have at least some
|
||||
encryption service available where to get keys */
|
||||
if (cdata && cdata->should_encrypt()) {
|
||||
|
||||
if (!encryption_key_id_exists(cdata->key_id)) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Tablespace id %ld is encrypted but encryption service"
|
||||
" or used key_id %u is not available. Can't continue opening tablespace.",
|
||||
space, cdata->key_id);
|
||||
|
||||
return ("table encrypted but encryption service not available.");
|
||||
if (!encryption_key_id_exists(cdata->key_id)) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Tablespace id " ULINTPF
|
||||
" is encrypted but encryption service"
|
||||
" or used key_id %u is not available. "
|
||||
"Can't continue opening tablespace.",
|
||||
*space_id, cdata->key_id);
|
||||
|
||||
return ("table encrypted but encryption service not available.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2457,8 +2434,6 @@ fil_read_first_page(
|
|||
}
|
||||
|
||||
if (!one_read_already) {
|
||||
*min_flushed_lsn = flushed_lsn;
|
||||
*max_flushed_lsn = flushed_lsn;
|
||||
#ifdef UNIV_LOG_ARCHIVE
|
||||
*min_arch_log_no = arch_log_no;
|
||||
*max_arch_log_no = arch_log_no;
|
||||
|
@ -2466,16 +2441,11 @@ fil_read_first_page(
|
|||
return(NULL);
|
||||
}
|
||||
|
||||
if (*min_flushed_lsn > flushed_lsn) {
|
||||
*min_flushed_lsn = flushed_lsn;
|
||||
}
|
||||
if (*max_flushed_lsn < flushed_lsn) {
|
||||
*max_flushed_lsn = flushed_lsn;
|
||||
}
|
||||
#ifdef UNIV_LOG_ARCHIVE
|
||||
if (*min_arch_log_no > arch_log_no) {
|
||||
*min_arch_log_no = arch_log_no;
|
||||
}
|
||||
|
||||
if (*max_arch_log_no < arch_log_no) {
|
||||
*max_arch_log_no = arch_log_no;
|
||||
}
|
||||
|
@ -4173,6 +4143,7 @@ fil_open_single_table_tablespace(
|
|||
def.file = os_file_create_simple_no_error_handling(
|
||||
innodb_file_data_key, def.filepath, OS_FILE_OPEN,
|
||||
OS_FILE_READ_ONLY, &def.success, atomic_writes);
|
||||
|
||||
if (def.success) {
|
||||
tablespaces_found++;
|
||||
}
|
||||
|
@ -4187,11 +4158,11 @@ fil_open_single_table_tablespace(
|
|||
/* Read the first page of the datadir tablespace, if found. */
|
||||
if (def.success) {
|
||||
def.check_msg = fil_read_first_page(
|
||||
def.file, FALSE, &def.flags, &def.id,
|
||||
def.file, false, &def.flags, &def.id,
|
||||
#ifdef UNIV_LOG_ARCHIVE
|
||||
&space_arch_log_no, &space_arch_log_no,
|
||||
#endif /* UNIV_LOG_ARCHIVE */
|
||||
&def.lsn, &def.lsn, &def.crypt_data);
|
||||
NULL, &def.crypt_data);
|
||||
|
||||
if (table) {
|
||||
table->crypt_data = def.crypt_data;
|
||||
|
@ -4200,6 +4171,7 @@ fil_open_single_table_tablespace(
|
|||
|
||||
def.valid = !def.check_msg && def.id == id
|
||||
&& fsp_flags_match(flags, def.flags);
|
||||
|
||||
if (def.valid) {
|
||||
valid_tablespaces_found++;
|
||||
} else {
|
||||
|
@ -4213,11 +4185,11 @@ fil_open_single_table_tablespace(
|
|||
/* Read the first page of the remote tablespace */
|
||||
if (remote.success) {
|
||||
remote.check_msg = fil_read_first_page(
|
||||
remote.file, FALSE, &remote.flags, &remote.id,
|
||||
remote.file, false, &remote.flags, &remote.id,
|
||||
#ifdef UNIV_LOG_ARCHIVE
|
||||
&remote.arch_log_no, &remote.arch_log_no,
|
||||
#endif /* UNIV_LOG_ARCHIVE */
|
||||
&remote.lsn, &remote.lsn, &remote.crypt_data);
|
||||
NULL, &remote.crypt_data);
|
||||
|
||||
if (table) {
|
||||
table->crypt_data = remote.crypt_data;
|
||||
|
@ -4227,6 +4199,7 @@ fil_open_single_table_tablespace(
|
|||
/* Validate this single-table-tablespace with SYS_TABLES. */
|
||||
remote.valid = !remote.check_msg && remote.id == id
|
||||
&& fsp_flags_match(flags, remote.flags);
|
||||
|
||||
if (remote.valid) {
|
||||
valid_tablespaces_found++;
|
||||
} else {
|
||||
|
@ -4241,11 +4214,11 @@ fil_open_single_table_tablespace(
|
|||
/* Read the first page of the datadir tablespace, if found. */
|
||||
if (dict.success) {
|
||||
dict.check_msg = fil_read_first_page(
|
||||
dict.file, FALSE, &dict.flags, &dict.id,
|
||||
dict.file, false, &dict.flags, &dict.id,
|
||||
#ifdef UNIV_LOG_ARCHIVE
|
||||
&dict.arch_log_no, &dict.arch_log_no,
|
||||
#endif /* UNIV_LOG_ARCHIVE */
|
||||
&dict.lsn, &dict.lsn, &dict.crypt_data);
|
||||
NULL, &dict.crypt_data);
|
||||
|
||||
if (table) {
|
||||
table->crypt_data = dict.crypt_data;
|
||||
|
@ -4289,26 +4262,32 @@ fil_open_single_table_tablespace(
|
|||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"A tablespace for %s has been found in "
|
||||
"multiple places;", tablename);
|
||||
|
||||
if (def.success) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Default location; %s, LSN=" LSN_PF
|
||||
", Space ID=%lu, Flags=%lu",
|
||||
def.filepath, def.lsn,
|
||||
(ulong) def.id, (ulong) def.flags);
|
||||
"Default location; %s"
|
||||
", Space ID=" ULINTPF " , Flags=" ULINTPF " .",
|
||||
def.filepath,
|
||||
def.id,
|
||||
def.flags);
|
||||
}
|
||||
|
||||
if (remote.success) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Remote location; %s, LSN=" LSN_PF
|
||||
", Space ID=%lu, Flags=%lu",
|
||||
remote.filepath, remote.lsn,
|
||||
(ulong) remote.id, (ulong) remote.flags);
|
||||
"Remote location; %s"
|
||||
", Space ID=" ULINTPF " , Flags=" ULINTPF " .",
|
||||
remote.filepath,
|
||||
remote.id,
|
||||
remote.flags);
|
||||
}
|
||||
|
||||
if (dict.success) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Dictionary location; %s, LSN=" LSN_PF
|
||||
", Space ID=%lu, Flags=%lu",
|
||||
dict.filepath, dict.lsn,
|
||||
(ulong) dict.id, (ulong) dict.flags);
|
||||
"Dictionary location; %s"
|
||||
", Space ID=" ULINTPF " , Flags=" ULINTPF " .",
|
||||
dict.filepath,
|
||||
dict.id,
|
||||
dict.flags);
|
||||
}
|
||||
|
||||
/* Force-recovery will allow some tablespaces to be
|
||||
|
@ -4341,6 +4320,7 @@ fil_open_single_table_tablespace(
|
|||
os_file_close(def.file);
|
||||
tablespaces_found--;
|
||||
}
|
||||
|
||||
if (dict.success && !dict.valid) {
|
||||
dict.success = false;
|
||||
os_file_close(dict.file);
|
||||
|
@ -4348,6 +4328,7 @@ fil_open_single_table_tablespace(
|
|||
can be corrected below. */
|
||||
tablespaces_found--;
|
||||
}
|
||||
|
||||
if (remote.success && !remote.valid) {
|
||||
remote.success = false;
|
||||
os_file_close(remote.file);
|
||||
|
@ -4698,7 +4679,7 @@ check_first_page:
|
|||
#ifdef UNIV_LOG_ARCHIVE
|
||||
&fsp->arch_log_no, &fsp->arch_log_no,
|
||||
#endif /* UNIV_LOG_ARCHIVE */
|
||||
&fsp->lsn, &fsp->lsn, &fsp->crypt_data)) {
|
||||
NULL, &fsp->crypt_data)) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"%s in tablespace %s (table %s)",
|
||||
check_msg, fsp->filepath, tablename);
|
||||
|
@ -4928,11 +4909,11 @@ will_not_choose:
|
|||
if (def.success && remote.success) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Tablespaces for %s have been found in two places;\n"
|
||||
"Location 1: SpaceID: %lu LSN: %lu File: %s\n"
|
||||
"Location 2: SpaceID: %lu LSN: %lu File: %s\n"
|
||||
"Location 1: SpaceID: " ULINTPF " File: %s\n"
|
||||
"Location 2: SpaceID: " ULINTPF " File: %s\n"
|
||||
"You must delete one of them.",
|
||||
tablename, (ulong) def.id, (ulong) def.lsn,
|
||||
def.filepath, (ulong) remote.id, (ulong) remote.lsn,
|
||||
tablename, def.id,
|
||||
def.filepath, remote.id,
|
||||
remote.filepath);
|
||||
|
||||
def.success = FALSE;
|
||||
|
|
|
@ -18221,8 +18221,15 @@ checkpoint_now_set(
|
|||
log_make_checkpoint_at(LSN_MAX, TRUE);
|
||||
fil_flush_file_spaces(FIL_LOG);
|
||||
}
|
||||
fil_write_flushed_lsn_to_data_files(log_sys->lsn, 0);
|
||||
fil_flush_file_spaces(FIL_TABLESPACE);
|
||||
|
||||
dberr_t err = fil_write_flushed_lsn(log_sys->lsn);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Failed to write flush lsn to the "
|
||||
"system tablespace at checkpoint err=%s",
|
||||
ut_strerr(err));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -215,7 +215,6 @@ struct fsp_open_info {
|
|||
ibool valid; /*!< Is the tablespace valid? */
|
||||
pfs_os_file_t file; /*!< File handle */
|
||||
char* filepath; /*!< File path to open */
|
||||
lsn_t lsn; /*!< Flushed LSN from header page */
|
||||
ulint id; /*!< Space ID */
|
||||
ulint flags; /*!< Tablespace flags */
|
||||
ulint encryption_error; /*!< if an encryption error occurs */
|
||||
|
@ -637,17 +636,17 @@ void
|
|||
fil_set_max_space_id_if_bigger(
|
||||
/*===========================*/
|
||||
ulint max_id);/*!< in: maximum known id */
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
/****************************************************************//**
|
||||
Writes the flushed lsn and the latest archived log number to the page
|
||||
header of the first page of each data file in the system tablespace.
|
||||
@return DB_SUCCESS or error number */
|
||||
UNIV_INTERN
|
||||
|
||||
/** Write the flushed LSN to the page header of the first page in the
|
||||
system tablespace.
|
||||
@param[in] lsn flushed LSN
|
||||
@return DB_SUCCESS or error number */
|
||||
dberr_t
|
||||
fil_write_flushed_lsn_to_data_files(
|
||||
/*================================*/
|
||||
lsn_t lsn, /*!< in: lsn to write */
|
||||
ulint arch_log_no); /*!< in: latest archived log file number */
|
||||
fil_write_flushed_lsn(
|
||||
lsn_t lsn)
|
||||
MY_ATTRIBUTE((warn_unused_result));
|
||||
|
||||
/** Acquire a tablespace when it could be dropped concurrently.
|
||||
Used by background threads that do not necessarily hold proper locks
|
||||
|
@ -793,35 +792,37 @@ private:
|
|||
fil_space_t* m_space;
|
||||
};
|
||||
|
||||
/*******************************************************************//**
|
||||
Reads the flushed lsn, arch no, and tablespace flag fields from a data
|
||||
file at database startup.
|
||||
/** Reads the flushed lsn, arch no, space_id and tablespace flag fields from
|
||||
the first page of a first data file at database startup.
|
||||
@param[in] data_file open data file
|
||||
@param[in] one_read_only true if first datafile is already
|
||||
read
|
||||
@param[out] flags FSP_SPACE_FLAGS
|
||||
@param[out] space_id tablepspace ID
|
||||
@param[out] min_arch_log_no min of archived log numbers in
|
||||
data files
|
||||
@param[out] max_arch_log_no max of archived log numbers in
|
||||
data files
|
||||
@param[out] flushed_lsn flushed lsn value
|
||||
@param[out] crypt_data encryption crypt data
|
||||
@retval NULL on success, or if innodb_force_recovery is set
|
||||
@return pointer to an error message string */
|
||||
UNIV_INTERN
|
||||
const char*
|
||||
fil_read_first_page(
|
||||
/*================*/
|
||||
pfs_os_file_t data_file, /*!< in: open data file */
|
||||
ibool one_read_already, /*!< in: TRUE if min and max
|
||||
parameters below already
|
||||
contain sensible data */
|
||||
ulint* flags, /*!< out: FSP_SPACE_FLAGS */
|
||||
ulint* space_id, /*!< out: tablespace ID */
|
||||
pfs_os_file_t data_file,
|
||||
ibool one_read_already,
|
||||
ulint* flags,
|
||||
ulint* space_id,
|
||||
#ifdef UNIV_LOG_ARCHIVE
|
||||
ulint* min_arch_log_no, /*!< out: min of archived
|
||||
log numbers in data files */
|
||||
ulint* max_arch_log_no, /*!< out: max of archived
|
||||
log numbers in data files */
|
||||
ulint* min_arch_log_no,
|
||||
ulint* max_arch_log_no,
|
||||
#endif /* UNIV_LOG_ARCHIVE */
|
||||
lsn_t* min_flushed_lsn, /*!< out: min of flushed
|
||||
lsn values in data files */
|
||||
lsn_t* max_flushed_lsn, /*!< out: max of flushed
|
||||
lsn values in data files */
|
||||
fil_space_crypt_t** crypt_data) /*!< out: crypt data */
|
||||
|
||||
__attribute__((warn_unused_result));
|
||||
lsn_t* flushed_lsn,
|
||||
fil_space_crypt_t** crypt_data)
|
||||
MY_ATTRIBUTE((warn_unused_result));
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
|
||||
/*******************************************************************//**
|
||||
Parses the body of a log record written about an .ibd file operation. That is,
|
||||
the log record part after the standard (type, space id, page no) header of the
|
||||
|
|
|
@ -123,26 +123,25 @@ a freshly read page)
|
|||
*/
|
||||
# define recv_recover_page(jri, block) recv_recover_page_func(block)
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
/********************************************************//**
|
||||
Recovers from a checkpoint. When this function returns, the database is able
|
||||
|
||||
/** Recovers from a checkpoint. When this function returns, the database is able
|
||||
to start processing of new user transactions, but the function
|
||||
recv_recovery_from_checkpoint_finish should be called later to complete
|
||||
the recovery and free the resources used in it.
|
||||
@param[in] type LOG_CHECKPOINT or LOG_ARCHIVE
|
||||
@param[in] limit_lsn recover up to this lsn if possible
|
||||
@param[in] flushed_lsn flushed lsn from first data file
|
||||
@return error code or DB_SUCCESS */
|
||||
UNIV_INTERN
|
||||
dberr_t
|
||||
recv_recovery_from_checkpoint_start_func(
|
||||
/*=====================================*/
|
||||
#ifdef UNIV_LOG_ARCHIVE
|
||||
ulint type, /*!< in: LOG_CHECKPOINT or
|
||||
LOG_ARCHIVE */
|
||||
lsn_t limit_lsn, /*!< in: recover up to this lsn
|
||||
if possible */
|
||||
ulint type,
|
||||
lsn_t limit_lsn,
|
||||
#endif /* UNIV_LOG_ARCHIVE */
|
||||
lsn_t min_flushed_lsn,/*!< in: min flushed lsn from
|
||||
data files */
|
||||
lsn_t max_flushed_lsn);/*!< in: max flushed lsn from
|
||||
data files */
|
||||
lsn_t flushed_lsn)
|
||||
MY_ATTRIBUTE((warn_unused_result));
|
||||
|
||||
#ifdef UNIV_LOG_ARCHIVE
|
||||
/** Wrapper for recv_recovery_from_checkpoint_start_func().
|
||||
Recovers from a checkpoint. When this function returns, the database is able
|
||||
|
@ -151,11 +150,10 @@ recv_recovery_from_checkpoint_finish should be called later to complete
|
|||
the recovery and free the resources used in it.
|
||||
@param type in: LOG_CHECKPOINT or LOG_ARCHIVE
|
||||
@param lim in: recover up to this log sequence number if possible
|
||||
@param min in: minimum flushed log sequence number from data files
|
||||
@param max in: maximum flushed log sequence number from data files
|
||||
@param lsn in: flushed log sequence number from first data file
|
||||
@return error code or DB_SUCCESS */
|
||||
# define recv_recovery_from_checkpoint_start(type,lim,min,max) \
|
||||
recv_recovery_from_checkpoint_start_func(type,lim,min,max)
|
||||
# define recv_recovery_from_checkpoint_start(type,lim,lsn) \
|
||||
recv_recovery_from_checkpoint_start_func(type,lim,lsn)
|
||||
#else /* UNIV_LOG_ARCHIVE */
|
||||
/** Wrapper for recv_recovery_from_checkpoint_start_func().
|
||||
Recovers from a checkpoint. When this function returns, the database is able
|
||||
|
@ -164,12 +162,12 @@ recv_recovery_from_checkpoint_finish should be called later to complete
|
|||
the recovery and free the resources used in it.
|
||||
@param type ignored: LOG_CHECKPOINT or LOG_ARCHIVE
|
||||
@param lim ignored: recover up to this log sequence number if possible
|
||||
@param min in: minimum flushed log sequence number from data files
|
||||
@param max in: maximum flushed log sequence number from data files
|
||||
@param lsn in: flushed log sequence number from first data file
|
||||
@return error code or DB_SUCCESS */
|
||||
# define recv_recovery_from_checkpoint_start(type,lim,min,max) \
|
||||
recv_recovery_from_checkpoint_start_func(min,max)
|
||||
# define recv_recovery_from_checkpoint_start(type,lim,lsn) \
|
||||
recv_recovery_from_checkpoint_start_func(lsn)
|
||||
#endif /* UNIV_LOG_ARCHIVE */
|
||||
|
||||
/********************************************************//**
|
||||
Completes recovery from a checkpoint. */
|
||||
UNIV_INTERN
|
||||
|
|
|
@ -3246,7 +3246,9 @@ logs_empty_and_mark_files_at_shutdown(void)
|
|||
/*=======================================*/
|
||||
{
|
||||
lsn_t lsn;
|
||||
#ifdef UNIV_LOG_ARCHIVE
|
||||
ulint arch_log_no;
|
||||
#endif
|
||||
ulint count = 0;
|
||||
ulint pending_io;
|
||||
ibool server_busy;
|
||||
|
@ -3454,9 +3456,9 @@ wait_suspend_loop:
|
|||
goto loop;
|
||||
}
|
||||
|
||||
#ifdef UNIV_LOG_ARCHIVE
|
||||
arch_log_no = 0;
|
||||
|
||||
#ifdef UNIV_LOG_ARCHIVE
|
||||
UT_LIST_GET_FIRST(log_sys->log_groups)->archived_file_no;
|
||||
|
||||
if (!UT_LIST_GET_FIRST(log_sys->log_groups)->archived_offset) {
|
||||
|
@ -3511,9 +3513,14 @@ wait_suspend_loop:
|
|||
srv_shutdown_lsn = lsn;
|
||||
|
||||
if (!srv_read_only_mode) {
|
||||
fil_write_flushed_lsn_to_data_files(lsn, arch_log_no);
|
||||
dberr_t err = fil_write_flushed_lsn(lsn);
|
||||
|
||||
fil_flush_file_spaces(FIL_TABLESPACE);
|
||||
if (err != DB_SUCCESS) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Failed to write flush lsn to the "
|
||||
"system tablespace at shutdown err=%s",
|
||||
ut_strerr(err));
|
||||
}
|
||||
}
|
||||
|
||||
fil_close_all_files();
|
||||
|
|
|
@ -2929,22 +2929,22 @@ recv_init_crash_recovery(void)
|
|||
}
|
||||
}
|
||||
|
||||
/********************************************************//**
|
||||
Recovers from a checkpoint. When this function returns, the database is able
|
||||
/** Recovers from a checkpoint. When this function returns, the database is able
|
||||
to start processing of new user transactions, but the function
|
||||
recv_recovery_from_checkpoint_finish should be called later to complete
|
||||
the recovery and free the resources used in it.
|
||||
@param[in] type LOG_CHECKPOINT or LOG_ARCHIVE
|
||||
@param[in] limit_lsn recover up to this lsn if possible
|
||||
@param[in] flushed_lsn flushed lsn from first data file
|
||||
@return error code or DB_SUCCESS */
|
||||
UNIV_INTERN
|
||||
dberr_t
|
||||
recv_recovery_from_checkpoint_start_func(
|
||||
/*=====================================*/
|
||||
#ifdef UNIV_LOG_ARCHIVE
|
||||
ulint type, /*!< in: LOG_CHECKPOINT or LOG_ARCHIVE */
|
||||
lsn_t limit_lsn, /*!< in: recover up to this lsn if possible */
|
||||
ulint type,
|
||||
lsn_t limit_lsn,
|
||||
#endif /* UNIV_LOG_ARCHIVE */
|
||||
lsn_t min_flushed_lsn,/*!< in: min flushed lsn from data files */
|
||||
lsn_t max_flushed_lsn)/*!< in: max flushed lsn from data files */
|
||||
lsn_t flushed_lsn)
|
||||
{
|
||||
log_group_t* group;
|
||||
log_group_t* max_cp_group;
|
||||
|
@ -3165,6 +3165,7 @@ recv_recovery_from_checkpoint_start_func(
|
|||
|
||||
group = UT_LIST_GET_NEXT(log_groups, group);
|
||||
}
|
||||
|
||||
/* Done with startup scan. Clear the flag. */
|
||||
recv_log_scan_is_startup_type = FALSE;
|
||||
|
||||
|
@ -3177,10 +3178,9 @@ recv_recovery_from_checkpoint_start_func(
|
|||
there is something wrong we will print a message to the
|
||||
user about recovery: */
|
||||
|
||||
if (checkpoint_lsn != max_flushed_lsn
|
||||
|| checkpoint_lsn != min_flushed_lsn) {
|
||||
if (checkpoint_lsn != flushed_lsn) {
|
||||
|
||||
if (checkpoint_lsn < max_flushed_lsn) {
|
||||
if (checkpoint_lsn < flushed_lsn) {
|
||||
|
||||
ib_logf(IB_LOG_LEVEL_WARN,
|
||||
"The log sequence number "
|
||||
|
@ -3191,24 +3191,21 @@ recv_recovery_from_checkpoint_start_func(
|
|||
"ib_logfiles to start up the database. "
|
||||
"Log sequence number in the "
|
||||
"ib_logfiles is " LSN_PF ", log"
|
||||
"sequence numbers stamped "
|
||||
"to ibdata file headers are between "
|
||||
"" LSN_PF " and " LSN_PF ".",
|
||||
"sequence number stamped "
|
||||
"to ibdata file header is " LSN_PF ".",
|
||||
checkpoint_lsn,
|
||||
min_flushed_lsn,
|
||||
max_flushed_lsn);
|
||||
flushed_lsn);
|
||||
}
|
||||
|
||||
if (!recv_needed_recovery) {
|
||||
ib_logf(IB_LOG_LEVEL_INFO,
|
||||
"The log sequence numbers "
|
||||
LSN_PF " and " LSN_PF
|
||||
" in ibdata files do not match"
|
||||
"The log sequence number "
|
||||
LSN_PF
|
||||
" in ibdata file do not match"
|
||||
" the log sequence number "
|
||||
LSN_PF
|
||||
" in the ib_logfiles!",
|
||||
min_flushed_lsn,
|
||||
max_flushed_lsn,
|
||||
flushed_lsn,
|
||||
checkpoint_lsn);
|
||||
|
||||
if (!srv_read_only_mode) {
|
||||
|
|
|
@ -786,27 +786,26 @@ open_log_file(
|
|||
return(DB_SUCCESS);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
Creates or opens database data files and closes them.
|
||||
/** Creates or opens database data files and closes them.
|
||||
@param[out] create_new_db true = create new database
|
||||
@param[out] min_arch_log_no min of archived log numbers in
|
||||
data files
|
||||
@param[out] max_arch_log_no max of archived log numbers in
|
||||
data files
|
||||
@param[out] flushed_lsn flushed lsn in fist datafile
|
||||
@param[out] sum_of_new_sizes sum of sizes of the new files
|
||||
added
|
||||
@return DB_SUCCESS or error code */
|
||||
static MY_ATTRIBUTE((nonnull, warn_unused_result))
|
||||
dberr_t
|
||||
open_or_create_data_files(
|
||||
/*======================*/
|
||||
ibool* create_new_db, /*!< out: TRUE if new database should be
|
||||
created */
|
||||
bool* create_new_db,
|
||||
#ifdef UNIV_LOG_ARCHIVE
|
||||
ulint* min_arch_log_no,/*!< out: min of archived log
|
||||
numbers in data files */
|
||||
ulint* max_arch_log_no,/*!< out: max of archived log
|
||||
numbers in data files */
|
||||
ulint* min_arch_log_no,
|
||||
ulint* max_arch_log_no,
|
||||
#endif /* UNIV_LOG_ARCHIVE */
|
||||
lsn_t* min_flushed_lsn,/*!< out: min of flushed lsn
|
||||
values in data files */
|
||||
lsn_t* max_flushed_lsn,/*!< out: max of flushed lsn
|
||||
values in data files */
|
||||
ulint* sum_of_new_sizes)/*!< out: sum of sizes of the
|
||||
new files added */
|
||||
lsn_t* flushed_lsn,
|
||||
ulint* sum_of_new_sizes)
|
||||
{
|
||||
ibool ret;
|
||||
ulint i;
|
||||
|
@ -830,7 +829,7 @@ open_or_create_data_files(
|
|||
|
||||
*sum_of_new_sizes = 0;
|
||||
|
||||
*create_new_db = FALSE;
|
||||
*create_new_db = false;
|
||||
|
||||
srv_normalize_path_for_win(srv_data_home);
|
||||
|
||||
|
@ -918,12 +917,13 @@ open_or_create_data_files(
|
|||
}
|
||||
|
||||
const char* check_msg;
|
||||
|
||||
check_msg = fil_read_first_page(
|
||||
files[i], FALSE, &flags, &space,
|
||||
#ifdef UNIV_LOG_ARCHIVE
|
||||
min_arch_log_no, max_arch_log_no,
|
||||
#endif /* UNIV_LOG_ARCHIVE */
|
||||
min_flushed_lsn, max_flushed_lsn, NULL);
|
||||
flushed_lsn, NULL);
|
||||
|
||||
/* If first page is valid, don't overwrite DB.
|
||||
It prevents overwriting DB when mysql_install_db
|
||||
|
@ -954,6 +954,7 @@ open_or_create_data_files(
|
|||
name);
|
||||
return(DB_ERROR);
|
||||
}
|
||||
|
||||
if (srv_data_file_is_raw_partition[i] == SRV_OLD_RAW) {
|
||||
ut_a(!srv_read_only_mode);
|
||||
files[i] = os_file_create(
|
||||
|
@ -973,7 +974,6 @@ open_or_create_data_files(
|
|||
}
|
||||
|
||||
if (!ret) {
|
||||
|
||||
os_file_get_last_error(true);
|
||||
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
|
@ -983,7 +983,6 @@ open_or_create_data_files(
|
|||
}
|
||||
|
||||
if (srv_data_file_is_raw_partition[i] == SRV_OLD_RAW) {
|
||||
|
||||
goto skip_size_check;
|
||||
}
|
||||
|
||||
|
@ -1010,16 +1009,15 @@ size_check:
|
|||
"auto-extending "
|
||||
"data file %s is "
|
||||
"of a different size "
|
||||
"%lu pages (rounded "
|
||||
ULINTPF " pages (rounded "
|
||||
"down to MB) than specified "
|
||||
"in the .cnf file: "
|
||||
"initial %lu pages, "
|
||||
"max %lu (relevant if "
|
||||
"initial " ULINTPF " pages, "
|
||||
"max " ULINTPF " (relevant if "
|
||||
"non-zero) pages!",
|
||||
name,
|
||||
(ulong) rounded_size_pages,
|
||||
(ulong) srv_data_file_sizes[i],
|
||||
(ulong)
|
||||
rounded_size_pages,
|
||||
srv_data_file_sizes[i],
|
||||
srv_last_file_size_max);
|
||||
|
||||
return(DB_ERROR);
|
||||
|
@ -1032,12 +1030,12 @@ size_check:
|
|||
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Data file %s is of a different "
|
||||
"size %lu pages (rounded down to MB) "
|
||||
"size " ULINTPF " pages (rounded down to MB) "
|
||||
"than specified in the .cnf file "
|
||||
"%lu pages!",
|
||||
ULINTPF " pages!",
|
||||
name,
|
||||
(ulong) rounded_size_pages,
|
||||
(ulong) srv_data_file_sizes[i]);
|
||||
rounded_size_pages,
|
||||
srv_data_file_sizes[i]);
|
||||
|
||||
return(DB_ERROR);
|
||||
}
|
||||
|
@ -1057,7 +1055,7 @@ check_first_page:
|
|||
#ifdef UNIV_LOG_ARCHIVE
|
||||
min_arch_log_no, max_arch_log_no,
|
||||
#endif /* UNIV_LOG_ARCHIVE */
|
||||
min_flushed_lsn, max_flushed_lsn, &crypt_data);
|
||||
flushed_lsn, &crypt_data);
|
||||
|
||||
if (check_msg) {
|
||||
|
||||
|
@ -1094,9 +1092,9 @@ check_first_page:
|
|||
!= fsp_flags_get_page_size(flags)) {
|
||||
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Data file \"%s\" uses page size %lu,"
|
||||
"Data file \"%s\" uses page size " ULINTPF " ,"
|
||||
"but the start-up parameter "
|
||||
"is --innodb-page-size=%lu",
|
||||
"is --innodb-page-size=" ULINTPF " .",
|
||||
name,
|
||||
fsp_flags_get_page_size(flags),
|
||||
UNIV_PAGE_SIZE);
|
||||
|
@ -1127,9 +1125,9 @@ check_first_page:
|
|||
}
|
||||
|
||||
ib_logf(IB_LOG_LEVEL_INFO,
|
||||
"Setting file %s size to %lu MB",
|
||||
"Setting file %s size to " ULINTPF " MB",
|
||||
name,
|
||||
(ulong) (srv_data_file_sizes[i]
|
||||
(srv_data_file_sizes[i]
|
||||
>> (20 - UNIV_PAGE_SIZE_SHIFT)));
|
||||
|
||||
ret = os_file_set_size(
|
||||
|
@ -1592,9 +1590,8 @@ dberr_t
|
|||
innobase_start_or_create_for_mysql(void)
|
||||
/*====================================*/
|
||||
{
|
||||
ibool create_new_db;
|
||||
lsn_t min_flushed_lsn;
|
||||
lsn_t max_flushed_lsn;
|
||||
bool create_new_db;
|
||||
lsn_t flushed_lsn;
|
||||
#ifdef UNIV_LOG_ARCHIVE
|
||||
ulint min_arch_log_no;
|
||||
ulint max_arch_log_no;
|
||||
|
@ -2152,7 +2149,7 @@ innobase_start_or_create_for_mysql(void)
|
|||
#ifdef UNIV_LOG_ARCHIVE
|
||||
&min_arch_log_no, &max_arch_log_no,
|
||||
#endif /* UNIV_LOG_ARCHIVE */
|
||||
&min_flushed_lsn, &max_flushed_lsn,
|
||||
&flushed_lsn,
|
||||
&sum_of_new_sizes);
|
||||
if (err == DB_FAIL) {
|
||||
|
||||
|
@ -2197,12 +2194,12 @@ innobase_start_or_create_for_mysql(void)
|
|||
bool success = buf_flush_list(ULINT_MAX, LSN_MAX, NULL);
|
||||
ut_a(success);
|
||||
|
||||
min_flushed_lsn = max_flushed_lsn = log_get_lsn();
|
||||
flushed_lsn = log_get_lsn();
|
||||
|
||||
buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST);
|
||||
|
||||
err = create_log_files(create_new_db, logfilename, dirnamelen,
|
||||
max_flushed_lsn, logfile0);
|
||||
flushed_lsn, logfile0);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
return(err);
|
||||
|
@ -2222,19 +2219,8 @@ innobase_start_or_create_for_mysql(void)
|
|||
|
||||
if (err == DB_NOT_FOUND) {
|
||||
if (i == 0) {
|
||||
if (max_flushed_lsn
|
||||
!= min_flushed_lsn) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Cannot create"
|
||||
" log files because"
|
||||
" data files are"
|
||||
" corrupt or"
|
||||
" not in sync"
|
||||
" with each other");
|
||||
return(DB_ERROR);
|
||||
}
|
||||
|
||||
if (max_flushed_lsn < (lsn_t) 1000) {
|
||||
if (flushed_lsn < (lsn_t) 1000) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Cannot create"
|
||||
" log files because"
|
||||
|
@ -2249,14 +2235,14 @@ innobase_start_or_create_for_mysql(void)
|
|||
|
||||
err = create_log_files(
|
||||
create_new_db, logfilename,
|
||||
dirnamelen, max_flushed_lsn,
|
||||
dirnamelen, flushed_lsn,
|
||||
logfile0);
|
||||
|
||||
if (err == DB_SUCCESS) {
|
||||
err = create_log_files_rename(
|
||||
logfilename,
|
||||
dirnamelen,
|
||||
max_flushed_lsn,
|
||||
flushed_lsn,
|
||||
logfile0);
|
||||
}
|
||||
|
||||
|
@ -2266,8 +2252,7 @@ innobase_start_or_create_for_mysql(void)
|
|||
|
||||
/* Suppress the message about
|
||||
crash recovery. */
|
||||
max_flushed_lsn = min_flushed_lsn
|
||||
= log_get_lsn();
|
||||
flushed_lsn = log_get_lsn();
|
||||
goto files_checked;
|
||||
} else if (i < 2) {
|
||||
/* must have at least 2 log files */
|
||||
|
@ -2422,17 +2407,19 @@ files_checked:
|
|||
bool success = buf_flush_list(ULINT_MAX, LSN_MAX, NULL);
|
||||
ut_a(success);
|
||||
|
||||
min_flushed_lsn = max_flushed_lsn = log_get_lsn();
|
||||
flushed_lsn = log_get_lsn();
|
||||
|
||||
buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST);
|
||||
|
||||
/* Stamp the LSN to the data files. */
|
||||
fil_write_flushed_lsn_to_data_files(max_flushed_lsn, 0);
|
||||
err = fil_write_flushed_lsn(flushed_lsn);
|
||||
|
||||
fil_flush_file_spaces(FIL_TABLESPACE);
|
||||
if (err != DB_SUCCESS) {
|
||||
return(err);
|
||||
}
|
||||
|
||||
err = create_log_files_rename(logfilename, dirnamelen,
|
||||
max_flushed_lsn, logfile0);
|
||||
flushed_lsn, logfile0);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
return(err);
|
||||
|
@ -2504,7 +2491,7 @@ files_checked:
|
|||
|
||||
err = recv_recovery_from_checkpoint_start(
|
||||
LOG_CHECKPOINT, LSN_MAX,
|
||||
min_flushed_lsn, max_flushed_lsn);
|
||||
flushed_lsn);
|
||||
|
||||
if (err == DB_SUCCESS) {
|
||||
/* Initialize the change buffer. */
|
||||
|
@ -2672,7 +2659,7 @@ files_checked:
|
|||
DBUG_EXECUTE_IF("innodb_log_abort_1",
|
||||
return(DB_ERROR););
|
||||
|
||||
min_flushed_lsn = max_flushed_lsn = log_get_lsn();
|
||||
flushed_lsn = log_get_lsn();
|
||||
|
||||
ib_logf(IB_LOG_LEVEL_WARN,
|
||||
"Resizing redo log from %u*%u to %u*%u pages"
|
||||
|
@ -2681,7 +2668,7 @@ files_checked:
|
|||
(unsigned) srv_log_file_size,
|
||||
(unsigned) srv_n_log_files,
|
||||
(unsigned) srv_log_file_size_requested,
|
||||
max_flushed_lsn);
|
||||
flushed_lsn);
|
||||
|
||||
buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST);
|
||||
|
||||
|
@ -2691,7 +2678,7 @@ files_checked:
|
|||
we need to explicitly flush the log buffers. */
|
||||
fil_flush(SRV_LOG_SPACE_FIRST_ID);
|
||||
|
||||
ut_ad(max_flushed_lsn == log_get_lsn());
|
||||
ut_ad(flushed_lsn == log_get_lsn());
|
||||
|
||||
/* Prohibit redo log writes from any other
|
||||
threads until creating a log checkpoint at the
|
||||
|
@ -2703,8 +2690,7 @@ files_checked:
|
|||
return(DB_ERROR););
|
||||
|
||||
/* Stamp the LSN to the data files. */
|
||||
fil_write_flushed_lsn_to_data_files(
|
||||
max_flushed_lsn, 0);
|
||||
err = fil_write_flushed_lsn(flushed_lsn);
|
||||
|
||||
DBUG_EXECUTE_IF("innodb_log_abort_4", err = DB_ERROR;);
|
||||
|
||||
|
@ -2712,8 +2698,6 @@ files_checked:
|
|||
return(err);
|
||||
}
|
||||
|
||||
fil_flush_file_spaces(FIL_TABLESPACE);
|
||||
|
||||
/* Close and free the redo log files, so that
|
||||
we can replace them. */
|
||||
fil_close_log_files(true);
|
||||
|
@ -2730,13 +2714,23 @@ files_checked:
|
|||
srv_log_file_size = srv_log_file_size_requested;
|
||||
|
||||
err = create_log_files(create_new_db, logfilename,
|
||||
dirnamelen, max_flushed_lsn,
|
||||
dirnamelen, flushed_lsn,
|
||||
logfile0);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
return(err);
|
||||
}
|
||||
|
||||
/* create_log_files() can increase system lsn that is
|
||||
why FIL_PAGE_FILE_FLUSH_LSN have to be updated */
|
||||
flushed_lsn = log_get_lsn();
|
||||
|
||||
err = fil_write_flushed_lsn(flushed_lsn);
|
||||
|
||||
if (err == DB_SUCCESS) {
|
||||
err = create_log_files_rename(
|
||||
logfilename, dirnamelen,
|
||||
max_flushed_lsn, logfile0);
|
||||
flushed_lsn, logfile0);
|
||||
}
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
|
|
|
@ -4371,11 +4371,11 @@ buf_page_create(
|
|||
memset(frame + FIL_PAGE_NEXT, 0xff, 4);
|
||||
mach_write_to_2(frame + FIL_PAGE_TYPE, FIL_PAGE_TYPE_ALLOCATED);
|
||||
|
||||
/* Reset to zero the file flush lsn field in the page; if the first
|
||||
page of an ibdata file is 'created' in this function into the buffer
|
||||
pool then we lose the original contents of the file flush lsn stamp.
|
||||
Then InnoDB could in a crash recovery print a big, false, corruption
|
||||
warning if the stamp contains an lsn bigger than the ib_logfile lsn. */
|
||||
/* FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION is only used on the
|
||||
following pages:
|
||||
(1) The first page of the InnoDB system tablespace (page 0:0)
|
||||
(2) FIL_RTREE_SPLIT_SEQ_NUM on R-tree pages
|
||||
(3) key_version on encrypted pages (not page 0:0) */
|
||||
|
||||
memset(frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, 0, 8);
|
||||
|
||||
|
|
|
@ -2265,99 +2265,70 @@ fil_set_max_space_id_if_bigger(
|
|||
mutex_exit(&fil_system->mutex);
|
||||
}
|
||||
|
||||
/****************************************************************//**
|
||||
Writes the flushed lsn and the latest archived log number to the page header
|
||||
of the first page of a data file of the system tablespace (space 0),
|
||||
which is uncompressed. */
|
||||
static MY_ATTRIBUTE((warn_unused_result))
|
||||
/** Write the flushed LSN to the page header of the first page in the
|
||||
system tablespace.
|
||||
@param[in] lsn flushed LSN
|
||||
@return DB_SUCCESS or error number */
|
||||
dberr_t
|
||||
fil_write_lsn_and_arch_no_to_file(
|
||||
/*==============================*/
|
||||
ulint space, /*!< in: space to write to */
|
||||
ulint sum_of_sizes, /*!< in: combined size of previous files
|
||||
in space, in database pages */
|
||||
lsn_t lsn, /*!< in: lsn to write */
|
||||
ulint arch_log_no MY_ATTRIBUTE((unused)))
|
||||
/*!< in: archived log number to write */
|
||||
fil_write_flushed_lsn(
|
||||
lsn_t lsn)
|
||||
{
|
||||
byte* buf1;
|
||||
byte* buf;
|
||||
dberr_t err;
|
||||
|
||||
buf1 = static_cast<byte*>(mem_alloc(2 * UNIV_PAGE_SIZE));
|
||||
buf1 = static_cast<byte*>(ut_malloc(2 * UNIV_PAGE_SIZE));
|
||||
buf = static_cast<byte*>(ut_align(buf1, UNIV_PAGE_SIZE));
|
||||
|
||||
err = fil_read(TRUE, space, 0, sum_of_sizes, 0,
|
||||
UNIV_PAGE_SIZE, buf, NULL, 0);
|
||||
if (err == DB_SUCCESS) {
|
||||
mach_write_to_8(buf + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION,
|
||||
lsn);
|
||||
/* Acquire system tablespace */
|
||||
fil_space_t* space = fil_space_acquire(0);
|
||||
|
||||
err = fil_write(TRUE, space, 0, sum_of_sizes, 0,
|
||||
UNIV_PAGE_SIZE, buf, NULL, 0);
|
||||
}
|
||||
/* If tablespace is not encrypted, stamp flush_lsn to
|
||||
first page of all system tablespace datafiles to avoid
|
||||
unnecessary error messages on possible downgrade. */
|
||||
if (space->crypt_data->min_key_version == 0) {
|
||||
fil_node_t* node;
|
||||
ulint sum_of_sizes = 0;
|
||||
|
||||
mem_free(buf1);
|
||||
for (node = UT_LIST_GET_FIRST(space->chain);
|
||||
node != NULL;
|
||||
node = UT_LIST_GET_NEXT(chain, node)) {
|
||||
|
||||
return(err);
|
||||
}
|
||||
err = fil_read(TRUE, 0, 0, sum_of_sizes, 0,
|
||||
UNIV_PAGE_SIZE, buf, NULL, 0);
|
||||
|
||||
/****************************************************************//**
|
||||
Writes the flushed lsn and the latest archived log number to the page
|
||||
header of the first page of each data file in the system tablespace.
|
||||
@return DB_SUCCESS or error number */
|
||||
UNIV_INTERN
|
||||
dberr_t
|
||||
fil_write_flushed_lsn_to_data_files(
|
||||
/*================================*/
|
||||
lsn_t lsn, /*!< in: lsn to write */
|
||||
ulint arch_log_no) /*!< in: latest archived log file number */
|
||||
{
|
||||
fil_space_t* space;
|
||||
fil_node_t* node;
|
||||
dberr_t err;
|
||||
if (err == DB_SUCCESS) {
|
||||
mach_write_to_8(buf + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION,
|
||||
lsn);
|
||||
|
||||
mutex_enter(&fil_system->mutex);
|
||||
|
||||
for (space = UT_LIST_GET_FIRST(fil_system->space_list);
|
||||
space != NULL;
|
||||
space = UT_LIST_GET_NEXT(space_list, space)) {
|
||||
|
||||
/* We only write the lsn to all existing data files which have
|
||||
been open during the lifetime of the mysqld process; they are
|
||||
represented by the space objects in the tablespace memory
|
||||
cache. Note that all data files in the system tablespace 0
|
||||
and the UNDO log tablespaces (if separate) are always open. */
|
||||
|
||||
if (space->purpose == FIL_TABLESPACE
|
||||
&& !fil_is_user_tablespace_id(space->id)) {
|
||||
ulint sum_of_sizes = 0;
|
||||
|
||||
for (node = UT_LIST_GET_FIRST(space->chain);
|
||||
node != NULL;
|
||||
node = UT_LIST_GET_NEXT(chain, node)) {
|
||||
|
||||
mutex_exit(&fil_system->mutex);
|
||||
|
||||
err = fil_write_lsn_and_arch_no_to_file(
|
||||
space->id, sum_of_sizes, lsn,
|
||||
arch_log_no);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
|
||||
return(err);
|
||||
}
|
||||
|
||||
mutex_enter(&fil_system->mutex);
|
||||
err = fil_write(TRUE, 0, 0, sum_of_sizes, 0,
|
||||
UNIV_PAGE_SIZE, buf, NULL, 0);
|
||||
|
||||
sum_of_sizes += node->size;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* When system tablespace is encrypted stamp flush_lsn to
|
||||
only the first page of the first datafile (rest of pages
|
||||
are encrypted). */
|
||||
err = fil_read(TRUE, 0, 0, 0, 0,
|
||||
UNIV_PAGE_SIZE, buf, NULL, 0);
|
||||
|
||||
if (err == DB_SUCCESS) {
|
||||
mach_write_to_8(buf + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION,
|
||||
lsn);
|
||||
|
||||
err = fil_write(TRUE, 0, 0, 0, 0,
|
||||
UNIV_PAGE_SIZE, buf, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
mutex_exit(&fil_system->mutex);
|
||||
fil_flush_file_spaces(FIL_TABLESPACE);
|
||||
fil_space_release(space);
|
||||
|
||||
return(DB_SUCCESS);
|
||||
ut_free(buf1);
|
||||
|
||||
return(err);
|
||||
}
|
||||
|
||||
/** Check the consistency of the first data page of a tablespace
|
||||
|
@ -2410,30 +2381,29 @@ fil_check_first_page(const page_t* page, ulint space_id, ulint flags)
|
|||
return("inconsistent data in space header");
|
||||
}
|
||||
|
||||
/*******************************************************************//**
|
||||
Reads the flushed lsn, arch no, space_id and tablespace flag fields from
|
||||
the first page of a data file at database startup.
|
||||
/** Reads the flushed lsn, arch no, space_id and tablespace flag fields from
|
||||
the first page of a first data file at database startup.
|
||||
@param[in] data_file open data file
|
||||
@param[in] one_read_only true if first datafile is already
|
||||
read
|
||||
@param[out] flags FSP_SPACE_FLAGS
|
||||
@param[out] space_id tablepspace ID
|
||||
@param[out] flushed_lsn flushed lsn value
|
||||
@param[out] crypt_data encryption crypt data
|
||||
@retval NULL on success, or if innodb_force_recovery is set
|
||||
@return pointer to an error message string */
|
||||
UNIV_INTERN
|
||||
const char*
|
||||
fil_read_first_page(
|
||||
/*================*/
|
||||
pfs_os_file_t data_file, /*!< in: open data file */
|
||||
ibool one_read_already, /*!< in: TRUE if min and max
|
||||
parameters below already
|
||||
contain sensible data */
|
||||
ulint* flags, /*!< out: FSP_SPACE_FLAGS */
|
||||
ulint* space_id, /*!< out: tablespace ID */
|
||||
lsn_t* min_flushed_lsn, /*!< out: min of flushed
|
||||
lsn values in data files */
|
||||
lsn_t* max_flushed_lsn, /*!< out: max of flushed
|
||||
lsn values in data files */
|
||||
fil_space_crypt_t** crypt_data) /*< out: crypt data */
|
||||
pfs_os_file_t data_file,
|
||||
ibool one_read_already,
|
||||
ulint* flags,
|
||||
ulint* space_id,
|
||||
lsn_t* flushed_lsn,
|
||||
fil_space_crypt_t** crypt_data)
|
||||
{
|
||||
byte* buf;
|
||||
byte* page;
|
||||
lsn_t flushed_lsn;
|
||||
const char* check_msg = NULL;
|
||||
fil_space_crypt_t* cdata;
|
||||
|
||||
|
@ -2450,6 +2420,7 @@ fil_read_first_page(
|
|||
return "File size is less than minimum";
|
||||
}
|
||||
}
|
||||
|
||||
buf = static_cast<byte*>(ut_malloc(2 * UNIV_PAGE_SIZE));
|
||||
|
||||
/* Align the memory for a possible read from a raw device */
|
||||
|
@ -2468,6 +2439,11 @@ fil_read_first_page(
|
|||
*space_id = fsp_header_get_space_id(page);
|
||||
*flags = fsp_header_get_flags(page);
|
||||
|
||||
if (flushed_lsn) {
|
||||
*flushed_lsn = mach_read_from_8(page +
|
||||
FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
|
||||
}
|
||||
|
||||
if (!fsp_flags_is_valid(*flags)) {
|
||||
ulint cflags = fsp_flags_convert_from_101(*flags);
|
||||
if (cflags == ULINT_UNDEFINED) {
|
||||
|
@ -2480,37 +2456,36 @@ fil_read_first_page(
|
|||
}
|
||||
}
|
||||
|
||||
if (!(IS_XTRABACKUP() && srv_backup_mode)) {
|
||||
check_msg = fil_check_first_page(page, *space_id, *flags);
|
||||
if (!(IS_XTRABACKUP() && srv_backup_mode)) {
|
||||
check_msg = fil_check_first_page(page, *space_id, *flags);
|
||||
}
|
||||
}
|
||||
|
||||
flushed_lsn = mach_read_from_8(page +
|
||||
FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
|
||||
/* Possible encryption crypt data is also stored only to first page
|
||||
of the first datafile. */
|
||||
|
||||
ulint offset = fsp_header_get_crypt_offset(
|
||||
fsp_flags_get_zip_size(*flags));
|
||||
|
||||
ulint space = fsp_header_get_space_id(page);
|
||||
ulint offset = fsp_header_get_crypt_offset(
|
||||
fsp_flags_get_zip_size(*flags));
|
||||
cdata = fil_space_read_crypt_data(*space_id, page, offset);
|
||||
|
||||
cdata = fil_space_read_crypt_data(space, page, offset);
|
||||
if (crypt_data) {
|
||||
*crypt_data = cdata;
|
||||
}
|
||||
|
||||
if (crypt_data) {
|
||||
*crypt_data = cdata;
|
||||
}
|
||||
/* If file space is encrypted we need to have at least some
|
||||
encryption service available where to get keys */
|
||||
if (cdata && cdata->should_encrypt()) {
|
||||
|
||||
/* If file space is encrypted we need to have at least some
|
||||
encryption service available where to get keys */
|
||||
if (cdata && cdata->should_encrypt()) {
|
||||
|
||||
if (!encryption_key_id_exists(cdata->key_id)) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Tablespace id %ld is encrypted but encryption service"
|
||||
" or used key_id %u is not available. Can't continue opening tablespace.",
|
||||
space, cdata->key_id);
|
||||
|
||||
return ("table encrypted but encryption service not available.");
|
||||
if (!encryption_key_id_exists(cdata->key_id)) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Tablespace id " ULINTPF
|
||||
" is encrypted but encryption service"
|
||||
" or used key_id %u is not available. "
|
||||
"Can't continue opening tablespace.",
|
||||
*space_id, cdata->key_id);
|
||||
|
||||
return ("table encrypted but encryption service not available.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2520,20 +2495,6 @@ fil_read_first_page(
|
|||
return(check_msg);
|
||||
}
|
||||
|
||||
if (!one_read_already) {
|
||||
*min_flushed_lsn = flushed_lsn;
|
||||
*max_flushed_lsn = flushed_lsn;
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if (*min_flushed_lsn > flushed_lsn) {
|
||||
*min_flushed_lsn = flushed_lsn;
|
||||
}
|
||||
if (*max_flushed_lsn < flushed_lsn) {
|
||||
*max_flushed_lsn = flushed_lsn;
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
@ -4377,6 +4338,7 @@ fil_open_single_table_tablespace(
|
|||
def.file = os_file_create_simple_no_error_handling(
|
||||
innodb_file_data_key, def.filepath, OS_FILE_OPEN,
|
||||
OS_FILE_READ_ONLY, &def.success, atomic_writes);
|
||||
|
||||
if (def.success) {
|
||||
tablespaces_found++;
|
||||
}
|
||||
|
@ -4391,8 +4353,8 @@ fil_open_single_table_tablespace(
|
|||
/* Read the first page of the datadir tablespace, if found. */
|
||||
if (def.success) {
|
||||
def.check_msg = fil_read_first_page(
|
||||
def.file, FALSE, &def.flags, &def.id,
|
||||
&def.lsn, &def.lsn, &def.crypt_data);
|
||||
def.file, false, &def.flags, &def.id,
|
||||
NULL, &def.crypt_data);
|
||||
|
||||
if (table) {
|
||||
table->crypt_data = def.crypt_data;
|
||||
|
@ -4401,6 +4363,7 @@ fil_open_single_table_tablespace(
|
|||
|
||||
def.valid = !def.check_msg && def.id == id
|
||||
&& fsp_flags_match(flags, def.flags);
|
||||
|
||||
if (def.valid) {
|
||||
valid_tablespaces_found++;
|
||||
} else {
|
||||
|
@ -4414,8 +4377,8 @@ fil_open_single_table_tablespace(
|
|||
/* Read the first page of the remote tablespace */
|
||||
if (remote.success) {
|
||||
remote.check_msg = fil_read_first_page(
|
||||
remote.file, FALSE, &remote.flags, &remote.id,
|
||||
&remote.lsn, &remote.lsn, &remote.crypt_data);
|
||||
remote.file, false, &remote.flags, &remote.id,
|
||||
NULL, &remote.crypt_data);
|
||||
|
||||
if (table) {
|
||||
table->crypt_data = remote.crypt_data;
|
||||
|
@ -4425,6 +4388,7 @@ fil_open_single_table_tablespace(
|
|||
/* Validate this single-table-tablespace with SYS_TABLES. */
|
||||
remote.valid = !remote.check_msg && remote.id == id
|
||||
&& fsp_flags_match(flags, remote.flags);
|
||||
|
||||
if (remote.valid) {
|
||||
valid_tablespaces_found++;
|
||||
} else {
|
||||
|
@ -4439,8 +4403,8 @@ fil_open_single_table_tablespace(
|
|||
/* Read the first page of the datadir tablespace, if found. */
|
||||
if (dict.success) {
|
||||
dict.check_msg = fil_read_first_page(
|
||||
dict.file, FALSE, &dict.flags, &dict.id,
|
||||
&dict.lsn, &dict.lsn, &dict.crypt_data);
|
||||
dict.file, false, &dict.flags, &dict.id,
|
||||
NULL, &dict.crypt_data);
|
||||
|
||||
if (table) {
|
||||
table->crypt_data = dict.crypt_data;
|
||||
|
@ -4472,14 +4436,16 @@ fil_open_single_table_tablespace(
|
|||
"See " REFMAN "innodb-troubleshooting-datadict.html "
|
||||
"for how to resolve the issue.",
|
||||
tablename);
|
||||
|
||||
if (IS_XTRABACKUP() && fix_dict) {
|
||||
ib_logf(IB_LOG_LEVEL_WARN,
|
||||
"It will be removed from the data dictionary.");
|
||||
"It will be removed from the data dictionary.");
|
||||
|
||||
if (purge_sys) {
|
||||
fil_remove_invalid_table_from_data_dict(tablename);
|
||||
}
|
||||
}
|
||||
|
||||
err = DB_CORRUPTION;
|
||||
|
||||
goto cleanup_and_exit;
|
||||
|
@ -4491,26 +4457,32 @@ fil_open_single_table_tablespace(
|
|||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"A tablespace for %s has been found in "
|
||||
"multiple places;", tablename);
|
||||
|
||||
if (def.success) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Default location; %s, LSN=" LSN_PF
|
||||
", Space ID=%lu, Flags=%lu",
|
||||
def.filepath, def.lsn,
|
||||
(ulong) def.id, (ulong) def.flags);
|
||||
"Default location; %s"
|
||||
", Space ID=" ULINTPF " , Flags=" ULINTPF " .",
|
||||
def.filepath,
|
||||
def.id,
|
||||
def.flags);
|
||||
}
|
||||
|
||||
if (remote.success) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Remote location; %s, LSN=" LSN_PF
|
||||
", Space ID=%lu, Flags=%lu",
|
||||
remote.filepath, remote.lsn,
|
||||
(ulong) remote.id, (ulong) remote.flags);
|
||||
"Remote location; %s"
|
||||
", Space ID=" ULINTPF " , Flags=" ULINTPF " .",
|
||||
remote.filepath,
|
||||
remote.id,
|
||||
remote.flags);
|
||||
}
|
||||
|
||||
if (dict.success) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Dictionary location; %s, LSN=" LSN_PF
|
||||
", Space ID=%lu, Flags=%lu",
|
||||
dict.filepath, dict.lsn,
|
||||
(ulong) dict.id, (ulong) dict.flags);
|
||||
"Dictionary location; %s"
|
||||
", Space ID=" ULINTPF " , Flags=" ULINTPF " .",
|
||||
dict.filepath,
|
||||
dict.id,
|
||||
dict.flags);
|
||||
}
|
||||
|
||||
/* Force-recovery will allow some tablespaces to be
|
||||
|
@ -4543,6 +4515,7 @@ fil_open_single_table_tablespace(
|
|||
os_file_close(def.file);
|
||||
tablespaces_found--;
|
||||
}
|
||||
|
||||
if (dict.success && !dict.valid) {
|
||||
dict.success = false;
|
||||
os_file_close(dict.file);
|
||||
|
@ -4895,8 +4868,8 @@ fil_validate_single_table_tablespace(
|
|||
check_first_page:
|
||||
fsp->success = TRUE;
|
||||
if (const char* check_msg = fil_read_first_page(
|
||||
fsp->file, FALSE, &fsp->flags, &fsp->id,
|
||||
&fsp->lsn, &fsp->lsn, &fsp->crypt_data)) {
|
||||
fsp->file, false, &fsp->flags, &fsp->id,
|
||||
NULL, &fsp->crypt_data)) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"%s in tablespace %s (table %s)",
|
||||
check_msg, fsp->filepath, tablename);
|
||||
|
@ -4909,6 +4882,7 @@ check_first_page:
|
|||
in Xtrabackup, this does not work.*/
|
||||
return;
|
||||
}
|
||||
|
||||
if (!restore_attempted) {
|
||||
if (!fil_user_tablespace_find_space_id(fsp)) {
|
||||
return;
|
||||
|
@ -5152,11 +5126,11 @@ will_not_choose:
|
|||
if (def.success && remote.success) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Tablespaces for %s have been found in two places;\n"
|
||||
"Location 1: SpaceID: %lu LSN: %lu File: %s\n"
|
||||
"Location 2: SpaceID: %lu LSN: %lu File: %s\n"
|
||||
"Location 1: SpaceID: " ULINTPF " File: %s\n"
|
||||
"Location 2: SpaceID: " ULINTPF " File: %s\n"
|
||||
"You must delete one of them.",
|
||||
tablename, (ulong) def.id, (ulong) def.lsn,
|
||||
def.filepath, (ulong) remote.id, (ulong) remote.lsn,
|
||||
tablename, def.id,
|
||||
def.filepath, remote.id,
|
||||
remote.filepath);
|
||||
|
||||
def.success = FALSE;
|
||||
|
|
|
@ -19238,8 +19238,15 @@ checkpoint_now_set(
|
|||
log_make_checkpoint_at(LSN_MAX, TRUE);
|
||||
fil_flush_file_spaces(FIL_LOG);
|
||||
}
|
||||
fil_write_flushed_lsn_to_data_files(log_sys->lsn, 0);
|
||||
fil_flush_file_spaces(FIL_TABLESPACE);
|
||||
|
||||
dberr_t err = fil_write_flushed_lsn(log_sys->lsn);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Failed to write flush lsn to the "
|
||||
"system tablespace at checkpoint err=%s",
|
||||
ut_strerr(err));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -212,7 +212,6 @@ struct fsp_open_info {
|
|||
ibool valid; /*!< Is the tablespace valid? */
|
||||
pfs_os_file_t file; /*!< File handle */
|
||||
char* filepath; /*!< File path to open */
|
||||
lsn_t lsn; /*!< Flushed LSN from header page */
|
||||
ulint id; /*!< Space ID */
|
||||
ulint flags; /*!< Tablespace flags */
|
||||
ulint encryption_error; /*!< if an encryption error occurs */
|
||||
|
@ -643,17 +642,17 @@ void
|
|||
fil_set_max_space_id_if_bigger(
|
||||
/*===========================*/
|
||||
ulint max_id);/*!< in: maximum known id */
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
/****************************************************************//**
|
||||
Writes the flushed lsn and the latest archived log number to the page
|
||||
header of the first page of each data file in the system tablespace.
|
||||
@return DB_SUCCESS or error number */
|
||||
UNIV_INTERN
|
||||
|
||||
/** Write the flushed LSN to the page header of the first page in the
|
||||
system tablespace.
|
||||
@param[in] lsn flushed LSN
|
||||
@return DB_SUCCESS or error number */
|
||||
dberr_t
|
||||
fil_write_flushed_lsn_to_data_files(
|
||||
/*================================*/
|
||||
lsn_t lsn, /*!< in: lsn to write */
|
||||
ulint arch_log_no); /*!< in: latest archived log file number */
|
||||
fil_write_flushed_lsn(
|
||||
lsn_t lsn)
|
||||
MY_ATTRIBUTE((warn_unused_result));
|
||||
|
||||
/** Acquire a tablespace when it could be dropped concurrently.
|
||||
Used by background threads that do not necessarily hold proper locks
|
||||
|
@ -799,28 +798,28 @@ private:
|
|||
fil_space_t* m_space;
|
||||
};
|
||||
|
||||
/*******************************************************************//**
|
||||
Reads the flushed lsn, arch no, and tablespace flag fields from a data
|
||||
file at database startup.
|
||||
/** Reads the flushed lsn, arch no, space_id and tablespace flag fields from
|
||||
the first page of a first data file at database startup.
|
||||
@param[in] data_file open data file
|
||||
@param[in] one_read_only true if first datafile is already
|
||||
read
|
||||
@param[out] flags FSP_SPACE_FLAGS
|
||||
@param[out] space_id tablepspace ID
|
||||
@param[out] flushed_lsn flushed lsn value
|
||||
@param[out] crypt_data encryption crypt data
|
||||
@retval NULL on success, or if innodb_force_recovery is set
|
||||
@return pointer to an error message string */
|
||||
UNIV_INTERN
|
||||
const char*
|
||||
fil_read_first_page(
|
||||
/*================*/
|
||||
pfs_os_file_t data_file, /*!< in: open data file */
|
||||
ibool one_read_already, /*!< in: TRUE if min and max
|
||||
parameters below already
|
||||
contain sensible data */
|
||||
ulint* flags, /*!< out: FSP_SPACE_FLAGS */
|
||||
ulint* space_id, /*!< out: tablespace ID */
|
||||
lsn_t* min_flushed_lsn, /*!< out: min of flushed
|
||||
lsn values in data files */
|
||||
lsn_t* max_flushed_lsn, /*!< out: max of flushed
|
||||
lsn values in data files */
|
||||
fil_space_crypt_t** crypt_data) /*!< out: crypt data */
|
||||
pfs_os_file_t data_file,
|
||||
ibool one_read_already,
|
||||
ulint* flags,
|
||||
ulint* space_id,
|
||||
lsn_t* flushed_lsn,
|
||||
fil_space_crypt_t** crypt_data)
|
||||
MY_ATTRIBUTE((warn_unused_result));
|
||||
|
||||
__attribute__((warn_unused_result));
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
/*******************************************************************//**
|
||||
Parses the body of a log record written about an .ibd file operation. That is,
|
||||
|
|
|
@ -137,26 +137,25 @@ a freshly read page)
|
|||
*/
|
||||
# define recv_recover_page(jri, block) recv_recover_page_func(block)
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
/********************************************************//**
|
||||
Recovers from a checkpoint. When this function returns, the database is able
|
||||
|
||||
/** Recovers from a checkpoint. When this function returns, the database is able
|
||||
to start processing of new user transactions, but the function
|
||||
recv_recovery_from_checkpoint_finish should be called later to complete
|
||||
the recovery and free the resources used in it.
|
||||
@param[in] type LOG_CHECKPOINT or LOG_ARCHIVE
|
||||
@param[in] limit_lsn recover up to this lsn if possible
|
||||
@param[in] flushed_lsn flushed lsn from first data file
|
||||
@return error code or DB_SUCCESS */
|
||||
UNIV_INTERN
|
||||
dberr_t
|
||||
recv_recovery_from_checkpoint_start_func(
|
||||
/*=====================================*/
|
||||
#ifdef UNIV_LOG_ARCHIVE
|
||||
ulint type, /*!< in: LOG_CHECKPOINT or
|
||||
LOG_ARCHIVE */
|
||||
lsn_t limit_lsn, /*!< in: recover up to this lsn
|
||||
if possible */
|
||||
ulint type,
|
||||
lsn_t limit_lsn,
|
||||
#endif /* UNIV_LOG_ARCHIVE */
|
||||
lsn_t min_flushed_lsn,/*!< in: min flushed lsn from
|
||||
data files */
|
||||
lsn_t max_flushed_lsn);/*!< in: max flushed lsn from
|
||||
data files */
|
||||
lsn_t flushed_lsn)
|
||||
MY_ATTRIBUTE((warn_unused_result));
|
||||
|
||||
#ifdef UNIV_LOG_ARCHIVE
|
||||
/** Wrapper for recv_recovery_from_checkpoint_start_func().
|
||||
Recovers from a checkpoint. When this function returns, the database is able
|
||||
|
@ -165,11 +164,10 @@ recv_recovery_from_checkpoint_finish should be called later to complete
|
|||
the recovery and free the resources used in it.
|
||||
@param type in: LOG_CHECKPOINT or LOG_ARCHIVE
|
||||
@param lim in: recover up to this log sequence number if possible
|
||||
@param min in: minimum flushed log sequence number from data files
|
||||
@param max in: maximum flushed log sequence number from data files
|
||||
@param lsn in: flushed log sequence number from first data file
|
||||
@return error code or DB_SUCCESS */
|
||||
# define recv_recovery_from_checkpoint_start(type,lim,min,max) \
|
||||
recv_recovery_from_checkpoint_start_func(type,lim,min,max)
|
||||
# define recv_recovery_from_checkpoint_start(type,lim,lsn) \
|
||||
recv_recovery_from_checkpoint_start_func(type,lim,lsn)
|
||||
#else /* UNIV_LOG_ARCHIVE */
|
||||
/** Wrapper for recv_recovery_from_checkpoint_start_func().
|
||||
Recovers from a checkpoint. When this function returns, the database is able
|
||||
|
@ -178,12 +176,12 @@ recv_recovery_from_checkpoint_finish should be called later to complete
|
|||
the recovery and free the resources used in it.
|
||||
@param type ignored: LOG_CHECKPOINT or LOG_ARCHIVE
|
||||
@param lim ignored: recover up to this log sequence number if possible
|
||||
@param min in: minimum flushed log sequence number from data files
|
||||
@param max in: maximum flushed log sequence number from data files
|
||||
@param lsn in: flushed log sequence number from first data file
|
||||
@return error code or DB_SUCCESS */
|
||||
# define recv_recovery_from_checkpoint_start(type,lim,min,max) \
|
||||
recv_recovery_from_checkpoint_start_func(min,max)
|
||||
# define recv_recovery_from_checkpoint_start(type,lim,lsn) \
|
||||
recv_recovery_from_checkpoint_start_func(lsn)
|
||||
#endif /* UNIV_LOG_ARCHIVE */
|
||||
|
||||
/********************************************************//**
|
||||
Completes recovery from a checkpoint. */
|
||||
UNIV_INTERN
|
||||
|
|
|
@ -3836,9 +3836,14 @@ wait_suspend_loop:
|
|||
srv_shutdown_lsn = lsn;
|
||||
|
||||
if (!srv_read_only_mode) {
|
||||
fil_write_flushed_lsn_to_data_files(lsn, 0);
|
||||
dberr_t err = fil_write_flushed_lsn(lsn);
|
||||
|
||||
fil_flush_file_spaces(FIL_TABLESPACE);
|
||||
if (err != DB_SUCCESS) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Failed to write flush lsn to the "
|
||||
"system tablespace at shutdown err=%s",
|
||||
ut_strerr(err));
|
||||
}
|
||||
}
|
||||
|
||||
fil_close_all_files();
|
||||
|
|
|
@ -3019,22 +3019,22 @@ recv_init_crash_recovery(void)
|
|||
}
|
||||
}
|
||||
|
||||
/********************************************************//**
|
||||
Recovers from a checkpoint. When this function returns, the database is able
|
||||
/** Recovers from a checkpoint. When this function returns, the database is able
|
||||
to start processing of new user transactions, but the function
|
||||
recv_recovery_from_checkpoint_finish should be called later to complete
|
||||
the recovery and free the resources used in it.
|
||||
@param[in] type LOG_CHECKPOINT or LOG_ARCHIVE
|
||||
@param[in] limit_lsn recover up to this lsn if possible
|
||||
@param[in] flushed_lsn flushed lsn from first data file
|
||||
@return error code or DB_SUCCESS */
|
||||
UNIV_INTERN
|
||||
dberr_t
|
||||
recv_recovery_from_checkpoint_start_func(
|
||||
/*=====================================*/
|
||||
#ifdef UNIV_LOG_ARCHIVE
|
||||
ulint type, /*!< in: LOG_CHECKPOINT or LOG_ARCHIVE */
|
||||
lsn_t limit_lsn, /*!< in: recover up to this lsn if possible */
|
||||
ulint type,
|
||||
lsn_t limit_lsn,
|
||||
#endif /* UNIV_LOG_ARCHIVE */
|
||||
lsn_t min_flushed_lsn,/*!< in: min flushed lsn from data files */
|
||||
lsn_t max_flushed_lsn)/*!< in: max flushed lsn from data files */
|
||||
lsn_t flushed_lsn)
|
||||
{
|
||||
log_group_t* group;
|
||||
log_group_t* max_cp_group;
|
||||
|
@ -3262,6 +3262,7 @@ recv_recovery_from_checkpoint_start_func(
|
|||
|
||||
group = UT_LIST_GET_NEXT(log_groups, group);
|
||||
}
|
||||
|
||||
/* Done with startup scan. Clear the flag. */
|
||||
recv_log_scan_is_startup_type = FALSE;
|
||||
|
||||
|
@ -3274,10 +3275,9 @@ recv_recovery_from_checkpoint_start_func(
|
|||
there is something wrong we will print a message to the
|
||||
user about recovery: */
|
||||
|
||||
if (checkpoint_lsn != max_flushed_lsn
|
||||
|| checkpoint_lsn != min_flushed_lsn) {
|
||||
if (checkpoint_lsn != flushed_lsn) {
|
||||
|
||||
if (checkpoint_lsn < max_flushed_lsn) {
|
||||
if (checkpoint_lsn <flushed_lsn) {
|
||||
|
||||
ib_logf(IB_LOG_LEVEL_WARN,
|
||||
"The log sequence number "
|
||||
|
@ -3288,24 +3288,21 @@ recv_recovery_from_checkpoint_start_func(
|
|||
"ib_logfiles to start up the database. "
|
||||
"Log sequence number in the "
|
||||
"ib_logfiles is " LSN_PF ", log"
|
||||
"sequence numbers stamped "
|
||||
"to ibdata file headers are between "
|
||||
"" LSN_PF " and " LSN_PF ".",
|
||||
"sequence number stamped "
|
||||
"to ibdata file header is " LSN_PF ".",
|
||||
checkpoint_lsn,
|
||||
min_flushed_lsn,
|
||||
max_flushed_lsn);
|
||||
flushed_lsn);
|
||||
}
|
||||
|
||||
if (!recv_needed_recovery) {
|
||||
ib_logf(IB_LOG_LEVEL_INFO,
|
||||
"The log sequence numbers "
|
||||
LSN_PF " and " LSN_PF
|
||||
" in ibdata files do not match"
|
||||
"The log sequence number "
|
||||
LSN_PF
|
||||
" in ibdata file do not match"
|
||||
" the log sequence number "
|
||||
LSN_PF
|
||||
" in the ib_logfiles!",
|
||||
min_flushed_lsn,
|
||||
max_flushed_lsn,
|
||||
flushed_lsn,
|
||||
checkpoint_lsn);
|
||||
|
||||
if (!srv_read_only_mode) {
|
||||
|
|
|
@ -826,32 +826,32 @@ open_log_file(
|
|||
return(DB_SUCCESS);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
Creates or opens database data files and closes them.
|
||||
|
||||
/** Creates or opens database data files and closes them.
|
||||
@param[out] create_new_db true = create new database
|
||||
@param[out] min_arch_log_no min of archived log numbers in
|
||||
data files
|
||||
@param[out] max_arch_log_no max of archived log numbers in
|
||||
data files
|
||||
@param[out] flushed_lsn flushed lsn in fist datafile
|
||||
@param[out] sum_of_new_sizes sum of sizes of the new files
|
||||
added
|
||||
@return DB_SUCCESS or error code */
|
||||
MY_ATTRIBUTE((nonnull, warn_unused_result))
|
||||
dberr_t
|
||||
open_or_create_data_files(
|
||||
/*======================*/
|
||||
ibool* create_new_db, /*!< out: TRUE if new database should be
|
||||
created */
|
||||
bool* create_new_db,
|
||||
#ifdef UNIV_LOG_ARCHIVE
|
||||
lsn_t* min_arch_log_no,/*!< out: min of archived log
|
||||
numbers in data files */
|
||||
lsn_t* max_arch_log_no,/*!< out: max of archived log
|
||||
numbers in data files */
|
||||
lsn_t* min_arch_log_no,
|
||||
lsn_t* max_arch_log_no,
|
||||
#endif /* UNIV_LOG_ARCHIVE */
|
||||
lsn_t* min_flushed_lsn,/*!< out: min of flushed lsn
|
||||
values in data files */
|
||||
lsn_t* max_flushed_lsn,/*!< out: max of flushed lsn
|
||||
values in data files */
|
||||
ulint* sum_of_new_sizes)/*!< out: sum of sizes of the
|
||||
new files added */
|
||||
lsn_t* flushed_lsn,
|
||||
ulint* sum_of_new_sizes)
|
||||
{
|
||||
ibool ret;
|
||||
ulint i;
|
||||
ibool one_opened = FALSE;
|
||||
ibool one_created = FALSE;
|
||||
bool one_opened = false;
|
||||
bool one_created = false;
|
||||
os_offset_t size;
|
||||
ulint flags;
|
||||
ulint space;
|
||||
|
@ -870,7 +870,7 @@ open_or_create_data_files(
|
|||
|
||||
*sum_of_new_sizes = 0;
|
||||
|
||||
*create_new_db = FALSE;
|
||||
*create_new_db = false;
|
||||
|
||||
srv_normalize_path_for_win(srv_data_home);
|
||||
|
||||
|
@ -958,9 +958,10 @@ open_or_create_data_files(
|
|||
}
|
||||
|
||||
const char* check_msg;
|
||||
|
||||
check_msg = fil_read_first_page(
|
||||
files[i], FALSE, &flags, &space,
|
||||
min_flushed_lsn, max_flushed_lsn, NULL);
|
||||
flushed_lsn, NULL);
|
||||
|
||||
/* If first page is valid, don't overwrite DB.
|
||||
It prevents overwriting DB when mysql_install_db
|
||||
|
@ -991,6 +992,7 @@ open_or_create_data_files(
|
|||
name);
|
||||
return(DB_ERROR);
|
||||
}
|
||||
|
||||
if (srv_data_file_is_raw_partition[i] == SRV_OLD_RAW) {
|
||||
ut_a(!srv_read_only_mode);
|
||||
files[i] = os_file_create(
|
||||
|
@ -1010,7 +1012,6 @@ open_or_create_data_files(
|
|||
}
|
||||
|
||||
if (!ret) {
|
||||
|
||||
os_file_get_last_error(true);
|
||||
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
|
@ -1020,7 +1021,6 @@ open_or_create_data_files(
|
|||
}
|
||||
|
||||
if (srv_data_file_is_raw_partition[i] == SRV_OLD_RAW) {
|
||||
|
||||
goto skip_size_check;
|
||||
}
|
||||
|
||||
|
@ -1047,16 +1047,15 @@ size_check:
|
|||
"auto-extending "
|
||||
"data file %s is "
|
||||
"of a different size "
|
||||
"%lu pages (rounded "
|
||||
ULINTPF " pages (rounded "
|
||||
"down to MB) than specified "
|
||||
"in the .cnf file: "
|
||||
"initial %lu pages, "
|
||||
"max %lu (relevant if "
|
||||
"initial " ULINTPF " pages, "
|
||||
"max " ULINTPF " (relevant if "
|
||||
"non-zero) pages!",
|
||||
name,
|
||||
(ulong) rounded_size_pages,
|
||||
(ulong) srv_data_file_sizes[i],
|
||||
(ulong)
|
||||
rounded_size_pages,
|
||||
srv_data_file_sizes[i],
|
||||
srv_last_file_size_max);
|
||||
|
||||
return(DB_ERROR);
|
||||
|
@ -1069,12 +1068,12 @@ size_check:
|
|||
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Data file %s is of a different "
|
||||
"size %lu pages (rounded down to MB) "
|
||||
"size " ULINTPF " pages (rounded down to MB) "
|
||||
"than specified in the .cnf file "
|
||||
"%lu pages!",
|
||||
ULINTPF " pages!",
|
||||
name,
|
||||
(ulong) rounded_size_pages,
|
||||
(ulong) srv_data_file_sizes[i]);
|
||||
rounded_size_pages,
|
||||
srv_data_file_sizes[i]);
|
||||
|
||||
return(DB_ERROR);
|
||||
}
|
||||
|
@ -1093,7 +1092,7 @@ skip_size_check:
|
|||
check_first_page:
|
||||
check_msg = fil_read_first_page(
|
||||
files[i], one_opened, &flags, &space,
|
||||
min_flushed_lsn, max_flushed_lsn, &crypt_data);
|
||||
flushed_lsn, &crypt_data);
|
||||
|
||||
if (check_msg) {
|
||||
|
||||
|
@ -1130,9 +1129,9 @@ check_first_page:
|
|||
!= fsp_flags_get_page_size(flags)) {
|
||||
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Data file \"%s\" uses page size %lu,"
|
||||
"Data file \"%s\" uses page size " ULINTPF " ,"
|
||||
"but the start-up parameter "
|
||||
"is --innodb-page-size=%lu",
|
||||
"is --innodb-page-size=" ULINTPF " .",
|
||||
name,
|
||||
fsp_flags_get_page_size(flags),
|
||||
UNIV_PAGE_SIZE);
|
||||
|
@ -1163,9 +1162,9 @@ check_first_page:
|
|||
}
|
||||
|
||||
ib_logf(IB_LOG_LEVEL_INFO,
|
||||
"Setting file %s size to %lu MB",
|
||||
"Setting file %s size to " ULINTPF " MB",
|
||||
name,
|
||||
(ulong) (srv_data_file_sizes[i]
|
||||
(srv_data_file_sizes[i]
|
||||
>> (20 - UNIV_PAGE_SIZE_SHIFT)));
|
||||
|
||||
ret = os_file_set_size(
|
||||
|
@ -1655,9 +1654,8 @@ dberr_t
|
|||
innobase_start_or_create_for_mysql(void)
|
||||
/*====================================*/
|
||||
{
|
||||
ibool create_new_db;
|
||||
lsn_t min_flushed_lsn;
|
||||
lsn_t max_flushed_lsn;
|
||||
bool create_new_db;
|
||||
lsn_t flushed_lsn;
|
||||
#ifdef UNIV_LOG_ARCHIVE
|
||||
lsn_t min_arch_log_no = LSN_MAX;
|
||||
lsn_t max_arch_log_no = LSN_MAX;
|
||||
|
@ -2237,7 +2235,7 @@ innobase_start_or_create_for_mysql(void)
|
|||
#ifdef UNIV_LOG_ARCHIVE
|
||||
&min_arch_log_no, &max_arch_log_no,
|
||||
#endif /* UNIV_LOG_ARCHIVE */
|
||||
&min_flushed_lsn, &max_flushed_lsn,
|
||||
&flushed_lsn,
|
||||
&sum_of_new_sizes);
|
||||
if (err == DB_FAIL) {
|
||||
|
||||
|
@ -2281,12 +2279,12 @@ innobase_start_or_create_for_mysql(void)
|
|||
bool success = buf_flush_list(ULINT_MAX, LSN_MAX, NULL);
|
||||
ut_a(success);
|
||||
|
||||
min_flushed_lsn = max_flushed_lsn = log_get_lsn();
|
||||
flushed_lsn = log_get_lsn();
|
||||
|
||||
buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST);
|
||||
|
||||
err = create_log_files(create_new_db, logfilename, dirnamelen,
|
||||
max_flushed_lsn, logfile0);
|
||||
flushed_lsn, logfile0);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
return(err);
|
||||
|
@ -2306,19 +2304,8 @@ innobase_start_or_create_for_mysql(void)
|
|||
|
||||
if (err == DB_NOT_FOUND) {
|
||||
if (i == 0) {
|
||||
if (max_flushed_lsn
|
||||
!= min_flushed_lsn) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Cannot create"
|
||||
" log files because"
|
||||
" data files are"
|
||||
" corrupt or"
|
||||
" not in sync"
|
||||
" with each other");
|
||||
return(DB_ERROR);
|
||||
}
|
||||
|
||||
if (max_flushed_lsn < (lsn_t) 1000) {
|
||||
if (flushed_lsn < (lsn_t) 1000) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
"Cannot create"
|
||||
" log files because"
|
||||
|
@ -2333,14 +2320,14 @@ innobase_start_or_create_for_mysql(void)
|
|||
|
||||
err = create_log_files(
|
||||
create_new_db, logfilename,
|
||||
dirnamelen, max_flushed_lsn,
|
||||
dirnamelen, flushed_lsn,
|
||||
logfile0);
|
||||
|
||||
if (err == DB_SUCCESS) {
|
||||
err = create_log_files_rename(
|
||||
logfilename,
|
||||
dirnamelen,
|
||||
max_flushed_lsn,
|
||||
flushed_lsn,
|
||||
logfile0);
|
||||
}
|
||||
|
||||
|
@ -2350,8 +2337,7 @@ innobase_start_or_create_for_mysql(void)
|
|||
|
||||
/* Suppress the message about
|
||||
crash recovery. */
|
||||
max_flushed_lsn = min_flushed_lsn
|
||||
= log_get_lsn();
|
||||
flushed_lsn = log_get_lsn();
|
||||
goto files_checked;
|
||||
} else if (i < 2 && !IS_XTRABACKUP()) {
|
||||
/* must have at least 2 log files */
|
||||
|
@ -2509,17 +2495,19 @@ files_checked:
|
|||
bool success = buf_flush_list(ULINT_MAX, LSN_MAX, NULL);
|
||||
ut_a(success);
|
||||
|
||||
min_flushed_lsn = max_flushed_lsn = log_get_lsn();
|
||||
flushed_lsn = log_get_lsn();
|
||||
|
||||
buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST);
|
||||
|
||||
/* Stamp the LSN to the data files. */
|
||||
fil_write_flushed_lsn_to_data_files(max_flushed_lsn, 0);
|
||||
err = fil_write_flushed_lsn(flushed_lsn);
|
||||
|
||||
fil_flush_file_spaces(FIL_TABLESPACE);
|
||||
if (err != DB_SUCCESS) {
|
||||
return(err);
|
||||
}
|
||||
|
||||
err = create_log_files_rename(logfilename, dirnamelen,
|
||||
max_flushed_lsn, logfile0);
|
||||
flushed_lsn, logfile0);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
return(err);
|
||||
|
@ -2574,7 +2562,7 @@ files_checked:
|
|||
|
||||
err = recv_recovery_from_checkpoint_start(
|
||||
LOG_CHECKPOINT, LSN_MAX,
|
||||
min_flushed_lsn, max_flushed_lsn);
|
||||
flushed_lsn);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
return(err);
|
||||
|
@ -2757,7 +2745,7 @@ files_checked:
|
|||
DBUG_EXECUTE_IF("innodb_log_abort_1",
|
||||
return(DB_ERROR););
|
||||
|
||||
min_flushed_lsn = max_flushed_lsn = log_get_lsn();
|
||||
flushed_lsn = log_get_lsn();
|
||||
|
||||
ib_logf(IB_LOG_LEVEL_WARN,
|
||||
"Resizing redo log from %u*%u to %u*%u pages"
|
||||
|
@ -2766,7 +2754,7 @@ files_checked:
|
|||
(unsigned) srv_log_file_size,
|
||||
(unsigned) srv_n_log_files,
|
||||
(unsigned) srv_log_file_size_requested,
|
||||
max_flushed_lsn);
|
||||
flushed_lsn);
|
||||
|
||||
buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST);
|
||||
|
||||
|
@ -2776,7 +2764,7 @@ files_checked:
|
|||
we need to explicitly flush the log buffers. */
|
||||
fil_flush(SRV_LOG_SPACE_FIRST_ID);
|
||||
|
||||
ut_ad(max_flushed_lsn == log_get_lsn());
|
||||
ut_ad(flushed_lsn == log_get_lsn());
|
||||
|
||||
/* Prohibit redo log writes from any other
|
||||
threads until creating a log checkpoint at the
|
||||
|
@ -2788,8 +2776,7 @@ files_checked:
|
|||
return(DB_ERROR););
|
||||
|
||||
/* Stamp the LSN to the data files. */
|
||||
fil_write_flushed_lsn_to_data_files(
|
||||
max_flushed_lsn, 0);
|
||||
err = fil_write_flushed_lsn(flushed_lsn);
|
||||
|
||||
DBUG_EXECUTE_IF("innodb_log_abort_4", err = DB_ERROR;);
|
||||
|
||||
|
@ -2797,8 +2784,6 @@ files_checked:
|
|||
return(err);
|
||||
}
|
||||
|
||||
fil_flush_file_spaces(FIL_TABLESPACE);
|
||||
|
||||
/* Close and free the redo log files, so that
|
||||
we can replace them. */
|
||||
fil_close_log_files(true);
|
||||
|
@ -2815,7 +2800,7 @@ files_checked:
|
|||
srv_log_file_size = srv_log_file_size_requested;
|
||||
|
||||
err = create_log_files(create_new_db, logfilename,
|
||||
dirnamelen, max_flushed_lsn,
|
||||
dirnamelen, flushed_lsn,
|
||||
logfile0);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
|
@ -2824,12 +2809,17 @@ files_checked:
|
|||
|
||||
/* create_log_files() can increase system lsn that is
|
||||
why FIL_PAGE_FILE_FLUSH_LSN have to be updated */
|
||||
min_flushed_lsn = max_flushed_lsn = log_get_lsn();
|
||||
fil_write_flushed_lsn_to_data_files(min_flushed_lsn, 0);
|
||||
fil_flush_file_spaces(FIL_TABLESPACE);
|
||||
flushed_lsn = log_get_lsn();
|
||||
|
||||
err = fil_write_flushed_lsn(flushed_lsn);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
return(err);
|
||||
}
|
||||
|
||||
err = create_log_files_rename(logfilename, dirnamelen,
|
||||
log_get_lsn(), logfile0);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
return(err);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue