Merge 10.2 into 10.3

This commit is contained in:
Marko Mäkelä 2019-04-07 11:49:50 +03:00
commit cc492bfd4f
29 changed files with 376 additions and 436 deletions

View File

@ -2748,8 +2748,13 @@ static bool xtrabackup_copy_logfile(bool last = false)
my_sleep(1000);
}
start_lsn = (lsn == start_lsn)
? 0 : xtrabackup_copy_log(start_lsn, lsn, last);
if (lsn == start_lsn) {
start_lsn = 0;
} else {
mutex_enter(&recv_sys->mutex);
start_lsn = xtrabackup_copy_log(start_lsn, lsn, last);
mutex_exit(&recv_sys->mutex);
}
log_mutex_exit();

View File

@ -1659,3 +1659,17 @@ a
2
drop view v1;
drop table t1,t2;
#
# MDEV-19112: CTE usage when information_schema is set as default db
#
with t as (select 1 as t ) select * from t;
t
1
use information_schema;
with t as (select 1 as t) select * from t;
t
1
with columns as (select 1 as t) select * from columns;
t
1
use test;

View File

@ -1168,3 +1168,15 @@ select * from v1;
drop view v1;
drop table t1,t2;
--echo #
--echo # MDEV-19112: CTE usage when information_schema is set as default db
--echo #
with t as (select 1 as t ) select * from t;
use information_schema;
with t as (select 1 as t) select * from t;
with columns as (select 1 as t) select * from columns;
use test;

View File

@ -3,6 +3,8 @@
# Embedded server does not support restarting
--source include/not_embedded.inc
let $MYSQLD_DATADIR=`select @@datadir`;
CREATE TABLE t(c0 SERIAL, c1 INT, c2 INT, c3 INT, c4 INT,
KEY(c1), KEY(c2), KEY(c2,c1),
KEY(c3), KEY(c3,c1), KEY(c3,c2), KEY(c3,c2,c1),
@ -32,7 +34,9 @@ CREATE TABLE target (PRIMARY KEY(c1)) ENGINE=InnoDB SELECT * FROM t;
--error ER_NO_SUCH_TABLE
SELECT * from target;
DROP TABLE t;
--source include/restart_mysqld.inc
--source include/shutdown_mysqld.inc
--remove_files_wildcard $MYSQLD_DATADIR/test #sql-*.ibd
--source include/start_mysqld.inc
CREATE TABLE t (a INT) ENGINE=InnoDB;
DROP TABLE t;
--error ER_BAD_TABLE_ERROR

View File

@ -6,7 +6,7 @@ select * from information_schema.feedback where variable_name like 'feed%'
and variable_name not like '%_uid'
and variable_name not like '%debug%';
VARIABLE_NAME VARIABLE_VALUE
FEEDBACK used 1
FEEDBACK used 2
FEEDBACK version 1.1
FEEDBACK_HTTP_PROXY
FEEDBACK_SEND_RETRY_WAIT 60

View File

@ -4,7 +4,7 @@ ACTIVE
SELECT variable_value INTO @feedback_used FROM information_schema.feedback where variable_name = 'FEEDBACK used';
SELECT variable_value = @feedback_used + 1 FROM information_schema.feedback where variable_name = 'FEEDBACK used';
variable_value = @feedback_used + 1
1
0
select * from information_schema.feedback where variable_name like 'feed%'
and variable_name not like '%_uid' and variable_name not like 'FEEDBACK used'
and variable_name not like '%debug%';

View File

@ -4,7 +4,7 @@ ACTIVE
SELECT variable_value INTO @feedback_used FROM information_schema.feedback where variable_name = 'FEEDBACK used';
SELECT variable_value = @feedback_used + 1 FROM information_schema.feedback where variable_name = 'FEEDBACK used';
variable_value = @feedback_used + 1
1
0
select * from information_schema.feedback where variable_name like 'feed%'
and variable_name not like '%_uid' and variable_name not like 'FEEDBACK used'
and variable_name not like '%debug%';

View File

@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2016, Oracle and/or its affiliates.
Copyright (c) 2010, 2016, MariaDB
Copyright (c) 2010, 2019, MariaDB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -3447,6 +3447,29 @@ open_and_process_table(THD *thd, LEX *lex, TABLE_LIST *tables,
goto end;
}
}
if (!tables->derived && is_infoschema_db(&tables->db))
{
/*
Check whether the information schema contains a table
whose name is tables->schema_table_name
*/
ST_SCHEMA_TABLE *schema_table;
schema_table= find_schema_table(thd, &tables->schema_table_name);
if (!schema_table ||
(schema_table->hidden &&
((sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND) == 0 ||
/*
this check is used for show columns|keys from I_S hidden table
*/
lex->sql_command == SQLCOM_SHOW_FIELDS ||
lex->sql_command == SQLCOM_SHOW_KEYS)))
{
my_error(ER_UNKNOWN_TABLE, MYF(0),
tables->schema_table_name.str, INFORMATION_SCHEMA_NAME.str);
DBUG_RETURN(1);
}
}
/*
If this TABLE_LIST object is a placeholder for an information_schema
table, create a temporary table to represent the information_schema

View File

@ -1109,6 +1109,7 @@ bool TABLE_LIST::set_as_with_table(THD *thd, With_element *with_elem)
table= 0;
}
with= with_elem;
schema_table= NULL;
if (!with_elem->is_referenced() || with_elem->is_recursive)
{
derived= with_elem->spec;

View File

@ -8304,7 +8304,6 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
ptr->derived= table->sel;
if (!ptr->derived && is_infoschema_db(&ptr->db))
{
ST_SCHEMA_TABLE *schema_table;
if (ptr->updating &&
/* Special cases which are processed by commands itself */
lex->sql_command != SQLCOM_CHECK &&
@ -8316,20 +8315,8 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
INFORMATION_SCHEMA_NAME.str);
DBUG_RETURN(0);
}
ST_SCHEMA_TABLE *schema_table;
schema_table= find_schema_table(thd, &ptr->table_name);
if (unlikely(!schema_table) ||
(schema_table->hidden &&
((sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND) == 0 ||
/*
this check is used for show columns|keys from I_S hidden table
*/
lex->sql_command == SQLCOM_SHOW_FIELDS ||
lex->sql_command == SQLCOM_SHOW_KEYS)))
{
my_error(ER_UNKNOWN_TABLE, MYF(0),
ptr->table_name.str, INFORMATION_SCHEMA_NAME.str);
DBUG_RETURN(0);
}
ptr->schema_table_name= ptr->table_name;
ptr->schema_table= schema_table;
}

View File

@ -273,11 +273,6 @@ btr_root_get(
And block the segment list access by others.*/
buf_block_t* root = btr_root_block_get(index, RW_SX_LATCH,
mtr);
if (root && root->page.encrypted == true) {
root = NULL;
}
return(root ? buf_block_get_frame(root) : NULL);
}
@ -1081,17 +1076,17 @@ void btr_page_get_father(dict_index_t* index, buf_block_t* block, mtr_t* mtr,
mem_heap_free(heap);
}
/** PAGE_INDEX_ID value for freed index B-trees */
static const index_id_t BTR_FREED_INDEX_ID = 0;
/** Free a B-tree root page. btr_free_but_not_root() must already
have been called.
In a persistent tablespace, the caller must invoke fsp_init_file_page()
before mtr.commit().
@param[in,out] block index root page
@param[in,out] mtr mini-transaction */
static
void
btr_free_root(
buf_block_t* block,
mtr_t* mtr)
@param[in,out] block index root page
@param[in,out] mtr mini-transaction
@param[in] invalidate whether to invalidate PAGE_INDEX_ID */
static void btr_free_root(buf_block_t* block, mtr_t* mtr, bool invalidate)
{
fseg_header_t* header;
@ -1105,31 +1100,18 @@ btr_free_root(
#ifdef UNIV_BTR_DEBUG
ut_a(btr_root_fseg_validate(header, block->page.id.space()));
#endif /* UNIV_BTR_DEBUG */
if (invalidate) {
btr_page_set_index_id(
buf_block_get_frame(block),
buf_block_get_page_zip(block),
BTR_FREED_INDEX_ID, mtr);
}
while (!fseg_free_step(header, true, mtr)) {
/* Free the entire segment in small steps. */
}
}
/** PAGE_INDEX_ID value for freed index B-trees */
static const index_id_t BTR_FREED_INDEX_ID = 0;
/** Invalidate an index root page so that btr_free_root_check()
will not find it.
@param[in,out] block index root page
@param[in,out] mtr mini-transaction */
static
void
btr_free_root_invalidate(
buf_block_t* block,
mtr_t* mtr)
{
btr_page_set_index_id(
buf_block_get_frame(block),
buf_block_get_page_zip(block),
BTR_FREED_INDEX_ID, mtr);
}
/** Prepare to free a B-tree.
@param[in] page_id page id
@param[in] page_size page size
@ -1247,11 +1229,8 @@ btr_create(
PAGE_HEADER + PAGE_BTR_SEG_LEAF, mtr)) {
/* Not enough space for new segment, free root
segment before return. */
btr_free_root(block, mtr);
if (!index->table->is_temporary()) {
btr_free_root_invalidate(block, mtr);
}
btr_free_root(block, mtr,
!index->table->is_temporary());
return(FIL_NULL);
}
@ -1424,8 +1403,7 @@ btr_free_if_exists(
btr_free_but_not_root(root, mtr->get_log_mode());
mtr->set_named_space_id(page_id.space());
btr_free_root(root, mtr);
btr_free_root_invalidate(root, mtr);
btr_free_root(root, mtr, true);
}
/** Free an index tree in a temporary tablespace or during TRUNCATE TABLE.
@ -1445,7 +1423,7 @@ btr_free(
if (block) {
btr_free_but_not_root(block, MTR_LOG_NO_REDO);
btr_free_root(block, &mtr);
btr_free_root(block, &mtr, false);
}
mtr.commit();
}
@ -5423,8 +5401,8 @@ btr_validate_index(
page_t* root = btr_root_get(index, &mtr);
if (root == NULL && !index->is_readable()) {
err = DB_DECRYPTION_FAILED;
if (!root) {
err = DB_CORRUPTION;
mtr_commit(&mtr);
return err;
}

View File

@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2014, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2018, MariaDB Corporation.
Copyright (c) 2017, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -662,11 +662,11 @@ PageBulk::latch()
/* In case the block is S-latched by page_cleaner. */
if (!buf_page_optimistic_get(RW_X_LATCH, m_block, m_modify_clock,
__FILE__, __LINE__, &m_mtr)) {
m_block = buf_page_get_gen(
page_id_t(m_index->table->space_id, m_page_no),
page_size_t(m_index->table->space->flags),
RW_X_LATCH, m_block, BUF_GET_IF_IN_POOL,
__FILE__, __LINE__, &m_mtr, &m_err);
m_block = buf_page_get_gen(page_id_t(m_index->table->space_id,
m_page_no),
univ_page_size, RW_X_LATCH,
m_block, BUF_GET_IF_IN_POOL,
__FILE__, __LINE__, &m_mtr, &m_err);
if (m_err != DB_SUCCESS) {
return (m_err);

View File

@ -4263,7 +4263,8 @@ buf_page_get_gen(
Skip the assertion on space_page_size. */
break;
case BUF_PEEK_IF_IN_POOL:
/* In this mode, the caller may pass a dummy page size,
case BUF_GET_IF_IN_POOL:
/* The caller may pass a dummy page size,
because it does not really matter. */
break;
default:
@ -4272,7 +4273,6 @@ buf_page_get_gen(
ut_ad(rw_latch == RW_NO_LATCH);
/* fall through */
case BUF_GET:
case BUF_GET_IF_IN_POOL:
case BUF_GET_IF_IN_POOL_OR_WATCH:
case BUF_GET_POSSIBLY_FREED:
bool found;
@ -6101,9 +6101,7 @@ database_corrupted:
page_not_corrupt: bpage = bpage; );
if (recv_recovery_is_on()) {
/* Pages must be uncompressed for crash recovery. */
ut_a(uncompressed);
recv_recover_page(TRUE, (buf_block_t*) bpage);
recv_recover_page(bpage);
}
/* If space is being truncated then avoid ibuf operation.
@ -6123,7 +6121,7 @@ database_corrupted:
<< " encrypted. However key "
"management plugin or used "
<< "key_version " << key_version
<< "is not found or"
<< " is not found or"
" used encryption algorithm or method does not match."
" Can't continue opening the table.";
} else {

View File

@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2015, 2018, MariaDB Corporation.
Copyright (c) 2015, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -186,13 +186,13 @@ buf_read_page_low(
thd_wait_end(NULL);
}
if (*err != DB_SUCCESS) {
if (UNIV_UNLIKELY(*err != DB_SUCCESS)) {
if (*err == DB_TABLESPACE_TRUNCATED) {
/* Remove the page which is outside the
truncated tablespace bounds when recovering
from a crash happened during a truncation */
buf_read_page_handle_error(bpage);
if (recv_recovery_on) {
if (recv_recovery_is_on()) {
mutex_enter(&recv_sys->mutex);
ut_ad(recv_sys->n_addrs > 0);
recv_sys->n_addrs--;

View File

@ -1422,7 +1422,7 @@ next:
look to see if it is already in the tablespace cache. */
if (const fil_space_t* space
= fil_space_for_table_exists_in_mem(
space_id, table_name.m_name, false, flags)) {
space_id, table_name.m_name, flags)) {
/* Recovery can open a datafile that does not
match SYS_DATAFILES. If they don't match, update
SYS_DATAFILES. */
@ -2797,11 +2797,16 @@ dict_load_tablespace(
/* The tablespace may already be open. */
table->space = fil_space_for_table_exists_in_mem(
table->space_id, table->name.m_name, false, table->flags);
table->space_id, table->name.m_name, table->flags);
if (table->space) {
return;
}
if (ignore_err == DICT_ERR_IGNORE_DROP) {
table->file_unreadable = true;
return;
}
if (!(ignore_err & DICT_ERR_IGNORE_RECOVER_LOCK)) {
ib::error() << "Failed to find tablespace for table "
<< table->name << " in the cache. Attempting"

View File

@ -1271,9 +1271,7 @@ fil_space_free(
rw_lock_x_unlock(&space->latch);
}
bool need_mutex = !recv_recovery_on;
if (need_mutex) {
if (!recv_recovery_is_on()) {
log_mutex_enter();
}
@ -1284,7 +1282,7 @@ fil_space_free(
UT_LIST_REMOVE(fil_system.named_spaces, space);
}
if (need_mutex) {
if (!recv_recovery_is_on()) {
log_mutex_exit();
}
@ -1343,9 +1341,8 @@ fil_space_create(
UT_LIST_INIT(space->chain, &fil_node_t::chain);
if ((purpose == FIL_TYPE_TABLESPACE || purpose == FIL_TYPE_IMPORT)
&& !recv_recovery_on
&& !recv_recovery_is_on()
&& id > fil_system.max_assigned_id) {
if (!fil_system.space_id_reuse_warned) {
fil_system.space_id_reuse_warned = true;
@ -2905,7 +2902,7 @@ fil_rename_tablespace(
ut_ad(strchr(old_file_name, OS_PATH_SEPARATOR) != NULL);
ut_ad(strchr(new_file_name, OS_PATH_SEPARATOR) != NULL);
if (!recv_recovery_on) {
if (!recv_recovery_is_on()) {
fil_name_write_rename(id, old_file_name, new_file_name);
log_mutex_enter();
}
@ -2927,7 +2924,7 @@ fil_rename_tablespace(
node->name = new_file_name;
}
if (!recv_recovery_on) {
if (!recv_recovery_is_on()) {
log_mutex_exit();
}
@ -3949,9 +3946,6 @@ memory cache. Note that if we have not done a crash recovery at the database
startup, there may be many tablespaces which are not yet in the memory cache.
@param[in] id Tablespace ID
@param[in] name Tablespace name used in fil_space_create().
@param[in] print_error_if_does_not_exist
Print detailed error information to the
error log if a matching tablespace is not found from memory.
@param[in] table_flags table flags
@return the tablespace
@retval NULL if no matching tablespace exists in the memory cache */
@ -3959,7 +3953,6 @@ fil_space_t*
fil_space_for_table_exists_in_mem(
ulint id,
const char* name,
bool print_error_if_does_not_exist,
ulint table_flags)
{
const ulint expected_flags = dict_tf_to_fsp_flags(table_flags);
@ -3977,7 +3970,8 @@ fil_space_for_table_exists_in_mem(
<< ", but the tablespace"
" with that id has name " << space->name << "."
" Have you deleted or moved .ibd files?";
goto error_exit;
ib::info() << TROUBLESHOOT_DATADICT_MSG;
goto func_exit;
}
/* Adjust the flags that are in FSP_FLAGS_MEM_MASK.
@ -3991,17 +3985,6 @@ fil_space_for_table_exists_in_mem(
return space;
}
if (print_error_if_does_not_exist) {
ib::error() << "Table " << name
<< " in the InnoDB data dictionary"
" has tablespace id " << id
<< ", but tablespace with that id"
" or name does not exist. Have"
" you deleted or moved .ibd files?";
error_exit:
ib::info() << TROUBLESHOOT_DATADICT_MSG;
}
func_exit:
mutex_exit(&fil_system.mutex);
return NULL;

View File

@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2018, MariaDB Corporation.
Copyright (c) 2017, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -574,13 +574,9 @@ xdes_get_offset(
* FSP_EXTENT_SIZE);
}
/***********************************************************//**
Inits a file page whose prior contents should be ignored. */
static
void
fsp_init_file_page_low(
/*===================*/
buf_block_t* block) /*!< in: pointer to a page */
/** Initialize a file page whose prior contents should be ignored.
@param[in,out] block buffer pool block */
void fsp_apply_init_file_page(buf_block_t* block)
{
page_t* page = buf_block_get_frame(block);
@ -638,14 +634,10 @@ fsp_space_modify_check(
/** Initialize a file page.
@param[in,out] block file page
@param[in,out] mtr mini-transaction */
static
void
fsp_init_file_page(buf_block_t* block, mtr_t* mtr)
static void fsp_init_file_page(buf_block_t* block, mtr_t* mtr)
{
fsp_init_file_page_low(block);
mlog_write_initial_log_record(buf_block_get_frame(block),
MLOG_INIT_FILE_PAGE2, mtr);
fsp_apply_init_file_page(block);
mlog_write_initial_log_record(block->frame, MLOG_INIT_FILE_PAGE2, mtr);
}
#ifdef UNIV_DEBUG
@ -661,26 +653,6 @@ fsp_init_file_page(const fil_space_t* space, buf_block_t* block, mtr_t* mtr)
# define fsp_init_file_page(space, block, mtr) fsp_init_file_page(block, mtr)
#endif
/***********************************************************//**
Parses a redo log record of a file page init.
@return end of log record or NULL */
byte*
fsp_parse_init_file_page(
/*=====================*/
byte* ptr, /*!< in: buffer */
byte* end_ptr MY_ATTRIBUTE((unused)), /*!< in: buffer end */
buf_block_t* block) /*!< in: block or NULL */
{
ut_ad(ptr != NULL);
ut_ad(end_ptr != NULL);
if (block) {
fsp_init_file_page_low(block);
}
return(ptr);
}
/**********************************************************************//**
Writes the space id and flags to a tablespace header. The flags contain
row type, physical/compressed page size, and logical/uncompressed page

View File

@ -78,7 +78,10 @@ enum dict_err_ignore_t {
Silently load a missing
tablespace, and do not load
incomplete index definitions. */
DICT_ERR_IGNORE_ALL = 0xFFFF /*!< ignore all errors */
/** ignore all errors above */
DICT_ERR_IGNORE_ALL = 15,
/** prepare to drop the table; do not attempt to load tablespace */
DICT_ERR_IGNORE_DROP = 31
};
/** Quiescing states for flushing tables to disk. */

View File

@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2013, 2018, MariaDB Corporation.
Copyright (c) 2013, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -1034,9 +1034,6 @@ memory cache. Note that if we have not done a crash recovery at the database
startup, there may be many tablespaces which are not yet in the memory cache.
@param[in] id Tablespace ID
@param[in] name Tablespace name used in fil_space_create().
@param[in] print_error_if_does_not_exist
Print detailed error information to the
error log if a matching tablespace is not found from memory.
@param[in] table_flags table flags
@return the tablespace
@retval NULL if no matching tablespace exists in the memory cache */
@ -1044,7 +1041,6 @@ fil_space_t*
fil_space_for_table_exists_in_mem(
ulint id,
const char* name,
bool print_error_if_does_not_exist,
ulint table_flags);
/** Try to extend a tablespace if it is smaller than the specified size.
@ -1250,16 +1246,12 @@ fil_names_write_if_was_clean(
return(was_clean);
}
extern volatile bool recv_recovery_on;
/** During crash recovery, open a tablespace if it had not been opened
yet, to get valid size and flags.
@param[in,out] space tablespace */
inline
void
fil_space_open_if_needed(
fil_space_t* space)
inline void fil_space_open_if_needed(fil_space_t* space)
{
ut_d(extern volatile bool recv_recovery_on);
ut_ad(recv_recovery_on);
if (space->size == 0) {
@ -1267,10 +1259,7 @@ fil_space_open_if_needed(
until the files are opened for the first time.
fil_space_get_size() will open the file
and adjust the size and flags. */
#ifdef UNIV_DEBUG
ulint size =
#endif /* UNIV_DEBUG */
fil_space_get_size(space->id);
ut_d(ulint size =) fil_space_get_size(space->id);
ut_ad(size == space->size);
}
}

View File

@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2013, 2018, MariaDB Corporation.
Copyright (c) 2013, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -627,15 +627,10 @@ fsp_descr_page(
const page_id_t page_id,
const page_size_t& page_size);
/***********************************************************//**
Parses a redo log record of a file page init.
@return end of log record or NULL */
byte*
fsp_parse_init_file_page(
/*=====================*/
byte* ptr, /*!< in: buffer */
byte* end_ptr, /*!< in: buffer end */
buf_block_t* block); /*!< in: block or NULL */
/** Initialize a file page whose prior contents should be ignored.
@param[in,out] block buffer pool block */
void fsp_apply_init_file_page(buf_block_t* block);
#ifdef UNIV_BTR_PRINT
/*******************************************************************//**
Writes info of a segment. */

View File

@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2018, MariaDB Corporation.
Copyright (c) 2017, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -40,7 +40,7 @@ Created 9/20/1997 Heikki Tuuri
extern bool recv_writer_thread_active;
/** @return whether recovery is currently running. */
#define recv_recovery_is_on() recv_recovery_on
#define recv_recovery_is_on() UNIV_UNLIKELY(recv_recovery_on)
/** Find the latest checkpoint in the log header.
@param[out] max_field LOG_CHECKPOINT_1 or LOG_CHECKPOINT_2
@ -49,12 +49,9 @@ dberr_t
recv_find_max_checkpoint(ulint* max_field)
MY_ATTRIBUTE((nonnull, warn_unused_result));
/** Apply the hashed log records to the page, if the page lsn is less than the
lsn of a log record.
@param just_read_in whether the page recently arrived to the I/O handler
@param block the page in the buffer pool */
void
recv_recover_page(bool just_read_in, buf_block_t* block);
/** Apply any buffered redo log to a page that was just read from a data file.
@param[in,out] bpage buffer pool page */
ATTRIBUTE_COLD void recv_recover_page(buf_page_t* bpage);
/** Start recovering from a redo log checkpoint.
@see recv_recovery_from_checkpoint_finish

View File

@ -2,7 +2,7 @@
Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
Copyright (c) 2017, MariaDB Corporation.
Copyright (c) 2017, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -496,16 +496,14 @@ page_zip_copy_recs(
dict_index_t* index, /*!< in: index of the B-tree */
mtr_t* mtr); /*!< in: mini-transaction */
/**********************************************************************//**
Parses a log record of compressing an index page.
@return end of log record or NULL */
byte*
page_zip_parse_compress(
/*====================*/
byte* ptr, /*!< in: buffer */
byte* end_ptr, /*!< in: buffer end */
page_t* page, /*!< out: uncompressed page */
page_zip_des_t* page_zip); /*!< out: compressed page */
/** Parse and optionally apply MLOG_ZIP_PAGE_COMPRESS.
@param[in] ptr log record
@param[in] end_ptr end of log
@param[in,out] block ROW_FORMAT=COMPRESSED block, or NULL for parsing only
@return end of log record
@retval NULL if the log record is incomplete */
byte* page_zip_parse_compress(const byte* ptr, const byte* end_ptr,
buf_block_t* block);
#endif /* !UNIV_INNOCHECKSUM */

View File

@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2015, 2017, MariaDB Corporation.
Copyright (c) 2015, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -292,6 +292,12 @@ row_merge_drop_table(
dict_table_t* table) /*!< in: table instance to drop */
MY_ATTRIBUTE((nonnull, warn_unused_result));
/** Write an MLOG_INDEX_LOAD record to indicate in the redo-log
that redo-logging of individual index pages was disabled, and
the flushing of such pages to the data files was completed.
@param[in] index an index tree on which redo logging was disabled */
void row_merge_write_redo(const dict_index_t* index);
/** Build indexes on a table by reading a clustered index, creating a temporary
file containing index entries, merge sorting these index entries and inserting
sorted index entries to indexes.

View File

@ -2,7 +2,7 @@
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2009, Google Inc.
Copyright (c) 2014, 2018, MariaDB Corporation.
Copyright (c) 2014, 2019, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@ -1193,14 +1193,11 @@ synchronization objects!
this lsn
@return false if there was a flush batch of the same type running,
which means that we could not start this flush batch */
static
bool
log_preflush_pool_modified_pages(
lsn_t new_oldest)
static bool log_preflush_pool_modified_pages(lsn_t new_oldest)
{
bool success;
if (recv_recovery_on) {
if (recv_recovery_is_on()) {
/* If the recovery is running, we must first apply all
log records to their respective file pages to get the
right modify lsn values to these pages: otherwise, there

View File

@ -675,7 +675,7 @@ DECLARE_THREAD(recv_writer_thread)(
mutex_enter(&recv_sys->writer_mutex);
if (!recv_recovery_on) {
if (!recv_recovery_is_on()) {
mutex_exit(&recv_sys->writer_mutex);
break;
}
@ -770,7 +770,7 @@ recv_sys_debug_free(void)
/* wake page cleaner up to progress */
if (!srv_read_only_mode) {
ut_ad(!recv_recovery_on);
ut_ad(!recv_recovery_is_on());
ut_ad(!recv_writer_thread_active);
os_event_reset(buf_flush_event);
os_event_set(recv_sys->flush_start);
@ -1615,7 +1615,7 @@ parse_log:
break;
case MLOG_INIT_FILE_PAGE2:
/* Allow anything in page_type when creating a page. */
ptr = fsp_parse_init_file_page(ptr, end_ptr, block);
if (block) fsp_apply_init_file_page(block);
break;
case MLOG_WRITE_STRING:
ptr = mlog_parse_string(ptr, end_ptr, page, page_zip);
@ -1637,7 +1637,7 @@ parse_log:
break;
case MLOG_ZIP_PAGE_COMPRESS:
/* Allow anything in page_type when creating a page. */
ptr = page_zip_parse_compress(ptr, end_ptr, page, page_zip);
ptr = page_zip_parse_compress(ptr, end_ptr, block);
break;
case MLOG_ZIP_PAGE_COMPRESS_NO_DATA:
if (NULL != (ptr = mlog_parse_index(
@ -1719,6 +1719,8 @@ recv_get_fil_addr_struct(
ulint space, /*!< in: space id */
ulint page_no)/*!< in: page number */
{
ut_ad(mutex_own(&recv_sys->mutex));
recv_addr_t* recv_addr;
for (recv_addr = static_cast<recv_addr_t*>(
@ -1792,10 +1794,6 @@ recv_add_to_hash_table(
HASH_INSERT(recv_addr_t, addr_hash, recv_sys->addr_hash,
recv_fold(space, page_no), recv_addr);
recv_sys->n_addrs++;
#if 0
fprintf(stderr, "Inserting log rec for space %lu, page %lu\n",
space, page_no);
#endif
}
UT_LIST_ADD_LAST(recv_addr->rec_list, recv);
@ -1864,48 +1862,20 @@ recv_data_copy_to_buf(
/** Apply the hashed log records to the page, if the page lsn is less than the
lsn of a log record.
@param just_read_in whether the page recently arrived to the I/O handler
@param block the page in the buffer pool */
void
recv_recover_page(bool just_read_in, buf_block_t* block)
@param[in,out] block buffer pool page
@param[in,out] mtr mini-transaction
@param[in,out] recv_addr recovery address */
static void recv_recover_page(buf_block_t* block, mtr_t& mtr,
recv_addr_t* recv_addr)
{
page_t* page;
page_zip_des_t* page_zip;
recv_addr_t* recv_addr;
recv_t* recv;
byte* buf;
lsn_t start_lsn;
lsn_t end_lsn;
lsn_t page_lsn;
lsn_t page_newest_lsn;
ibool modification_to_page;
mtr_t mtr;
mutex_enter(&(recv_sys->mutex));
if (recv_sys->apply_log_recs == FALSE) {
/* Log records should not be applied now */
mutex_exit(&(recv_sys->mutex));
return;
}
recv_addr = recv_get_fil_addr_struct(block->page.id.space(),
block->page.id.page_no());
if ((recv_addr == NULL)
|| (recv_addr->state == RECV_BEING_PROCESSED)
|| (recv_addr->state == RECV_PROCESSED)) {
ut_ad(recv_addr == NULL || recv_needed_recovery);
mutex_exit(&(recv_sys->mutex));
return;
}
ut_ad(mutex_own(&recv_sys->mutex));
ut_ad(recv_sys->apply_log_recs);
ut_ad(recv_needed_recovery);
ut_ad(recv_addr->state != RECV_BEING_PROCESSED);
ut_ad(recv_addr->state != RECV_PROCESSED);
if (UNIV_UNLIKELY(srv_print_verbose_log == 2)) {
fprintf(stderr, "Applying log to page %u:%u\n",
@ -1915,95 +1885,53 @@ recv_recover_page(bool just_read_in, buf_block_t* block)
DBUG_LOG("ib_log", "Applying log to page " << block->page.id);
recv_addr->state = RECV_BEING_PROCESSED;
mutex_exit(&(recv_sys->mutex));
mtr_start(&mtr);
mtr_set_log_mode(&mtr, MTR_LOG_NONE);
mutex_exit(&recv_sys->mutex);
page = block->frame;
page_zip = buf_block_get_page_zip(block);
if (just_read_in) {
/* Move the ownership of the x-latch on the page to
this OS thread, so that we can acquire a second
x-latch on it. This is needed for the operations to
the page to pass the debug checks. */
rw_lock_x_lock_move_ownership(&block->lock);
/* The page may have been modified in the buffer pool.
FIL_PAGE_LSN would only be updated right before flushing. */
lsn_t page_lsn = buf_page_get_newest_modification(&block->page);
if (!page_lsn) {
page_lsn = mach_read_from_8(page + FIL_PAGE_LSN);
}
ibool success = buf_page_get_known_nowait(
RW_X_LATCH, block, BUF_KEEP_OLD,
__FILE__, __LINE__, &mtr);
ut_a(success);
lsn_t start_lsn = 0, end_lsn = 0;
fil_space_t* space;
buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
/* Read the newest modification lsn from the page */
page_lsn = mach_read_from_8(page + FIL_PAGE_LSN);
/* It may be that the page has been modified in the buffer
pool: read the newest modification lsn there */
page_newest_lsn = buf_page_get_newest_modification(&block->page);
if (page_newest_lsn) {
page_lsn = page_newest_lsn;
if (srv_is_tablespace_truncated(recv_addr->space)) {
/* The table will be truncated after applying
normal redo log records. */
goto skip_log;
}
modification_to_page = FALSE;
start_lsn = end_lsn = 0;
space = fil_space_acquire(recv_addr->space);
if (!space) {
goto skip_log;
}
recv = UT_LIST_GET_FIRST(recv_addr->rec_list);
fil_space_t* space = fil_space_acquire(block->page.id.space());
while (recv) {
for (recv_t* recv = UT_LIST_GET_FIRST(recv_addr->rec_list);
recv; recv = UT_LIST_GET_NEXT(rec_list, recv)) {
ut_ad(recv->start_lsn);
end_lsn = recv->end_lsn;
ut_ad(end_lsn <= log_sys.log.scanned_lsn);
if (recv->len > RECV_DATA_BLOCK_SIZE) {
/* We have to copy the record body to a separate
buffer */
buf = static_cast<byte*>(ut_malloc_nokey(recv->len));
recv_data_copy_to_buf(buf, recv);
if (recv->start_lsn < page_lsn) {
/* Ignore this record, because there are later changes
for this page. */
} else if (srv_was_tablespace_truncated(space)
&& recv->start_lsn
< truncate_t::get_truncated_tablespace_init_lsn(
recv_addr->space)) {
/* If per-table tablespace was truncated and
there exist REDO records before truncate that
are to be applied as part of recovery
(checkpoint didn't happen since truncate was
done) skip such records using lsn check as
they may not stand valid post truncate. */
} else {
buf = ((byte*)(recv->data)) + sizeof(recv_data_t);
}
/* If per-table tablespace was truncated and there exist REDO
records before truncate that are to be applied as part of
recovery (checkpoint didn't happen since truncate was done)
skip such records using lsn check as they may not stand valid
post truncate.
LSN at start of truncate is recorded and any redo record
with LSN less than recorded LSN is skipped.
Note: We can't skip complete recv_addr as same page may have
valid REDO records post truncate those needs to be applied. */
/* Ignore applying the redo logs for tablespace that is
truncated. Post recovery there is fixup action that will
restore the tablespace back to normal state.
Applying redo at this stage can result in error given that
redo will have action recorded on page before tablespace
was re-inited and that would lead to an error while applying
such action. */
if (recv->start_lsn >= page_lsn
&& !srv_is_tablespace_truncated(space->id)
&& !(srv_was_tablespace_truncated(space)
&& recv->start_lsn
< truncate_t::get_truncated_tablespace_init_lsn(
space->id))) {
lsn_t end_lsn;
if (!modification_to_page) {
modification_to_page = TRUE;
if (!start_lsn) {
start_lsn = recv->start_lsn;
}
@ -2019,11 +1947,23 @@ recv_recover_page(bool just_read_in, buf_block_t* block)
<< " len " << recv->len
<< " page " << block->page.id);
byte* buf;
if (recv->len > RECV_DATA_BLOCK_SIZE) {
/* We have to copy the record body to
a separate buffer */
buf = static_cast<byte*>
(ut_malloc_nokey(recv->len));
recv_data_copy_to_buf(buf, recv);
} else {
buf = reinterpret_cast<byte*>(recv->data)
+ sizeof *recv->data;
}
recv_parse_or_apply_log_rec_body(
recv->type, buf, buf + recv->len,
block->page.id.space(),
block->page.id.page_no(),
true, block, &mtr);
block->page.id.page_no(), true, block, &mtr);
end_lsn = recv->start_lsn + recv->len;
mach_write_to_8(FIL_PAGE_LSN + page, end_lsn);
@ -2032,32 +1972,26 @@ recv_recover_page(bool just_read_in, buf_block_t* block)
+ page, end_lsn);
if (page_zip) {
mach_write_to_8(FIL_PAGE_LSN
+ page_zip->data, end_lsn);
mach_write_to_8(FIL_PAGE_LSN + page_zip->data,
end_lsn);
}
if (recv->len > RECV_DATA_BLOCK_SIZE) {
ut_free(buf);
}
}
if (recv->len > RECV_DATA_BLOCK_SIZE) {
ut_free(buf);
}
recv = UT_LIST_GET_NEXT(rec_list, recv);
}
space->release();
skip_log:
#ifdef UNIV_ZIP_DEBUG
if (fil_page_index_page_check(page)) {
page_zip_des_t* page_zip = buf_block_get_page_zip(block);
ut_a(!page_zip
|| page_zip_validate_low(page_zip, page, NULL, FALSE));
}
ut_ad(!fil_page_index_page_check(page)
|| !page_zip
|| page_zip_validate_low(page_zip, page, NULL, FALSE));
#endif /* UNIV_ZIP_DEBUG */
if (modification_to_page) {
ut_a(block);
if (start_lsn) {
log_flush_order_mutex_enter();
buf_flush_recv_note_modification(block, start_lsn, end_lsn);
log_flush_order_mutex_exit();
@ -2067,8 +2001,7 @@ recv_recover_page(bool just_read_in, buf_block_t* block)
lsn values of page */
mtr.discard_modifications();
mtr_commit(&mtr);
mtr.commit();
ib_time_t time = ut_time();
@ -2078,6 +2011,7 @@ recv_recover_page(bool just_read_in, buf_block_t* block)
recv_max_page_lsn = page_lsn;
}
ut_ad(recv_addr->state == RECV_BEING_PROCESSED);
recv_addr->state = RECV_PROCESSED;
ut_a(recv_sys->n_addrs > 0);
@ -2088,52 +2022,76 @@ recv_recover_page(bool just_read_in, buf_block_t* block)
INNODB_EXTEND_TIMEOUT_INTERVAL, "To recover: " ULINTPF " pages from log", n);
}
}
}
/** Apply any buffered redo log to a page that was just read from a data file.
@param[in,out] bpage buffer pool page */
void recv_recover_page(buf_page_t* bpage)
{
mtr_t mtr;
mtr.start();
mtr.set_log_mode(MTR_LOG_NONE);
ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE);
buf_block_t* block = reinterpret_cast<buf_block_t*>(bpage);
/* Move the ownership of the x-latch on the page to
this OS thread, so that we can acquire a second
x-latch on it. This is needed for the operations to
the page to pass the debug checks. */
rw_lock_x_lock_move_ownership(&block->lock);
buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
ibool success = buf_page_get_known_nowait(
RW_X_LATCH, block, BUF_KEEP_OLD,
__FILE__, __LINE__, &mtr);
ut_a(success);
mutex_enter(&recv_sys->mutex);
if (!recv_sys->apply_log_recs) {
} else if (recv_addr_t* recv_addr = recv_get_fil_addr_struct(
bpage->id.space(), bpage->id.page_no())) {
switch (recv_addr->state) {
case RECV_BEING_PROCESSED:
case RECV_PROCESSED:
break;
default:
recv_recover_page(block, mtr, recv_addr);
goto func_exit;
}
}
mtr.commit();
func_exit:
mutex_exit(&recv_sys->mutex);
ut_ad(mtr.has_committed());
}
/** Reads in pages which have hashed log records, from an area around a given
page number.
@param[in] page_id page id
@return number of pages found */
static ulint recv_read_in_area(const page_id_t page_id)
@param[in] page_id page id */
static void recv_read_in_area(const page_id_t page_id)
{
recv_addr_t* recv_addr;
ulint page_nos[RECV_READ_AHEAD_AREA];
ulint low_limit;
ulint n;
low_limit = page_id.page_no()
ulint page_no = page_id.page_no()
- (page_id.page_no() % RECV_READ_AHEAD_AREA);
ulint* p = page_nos;
n = 0;
for (ulint page_no = low_limit;
page_no < low_limit + RECV_READ_AHEAD_AREA;
page_no++) {
recv_addr = recv_get_fil_addr_struct(page_id.space(), page_no);
const page_id_t cur_page_id(page_id.space(), page_no);
if (recv_addr && !buf_page_peek(cur_page_id)) {
mutex_enter(&(recv_sys->mutex));
if (recv_addr->state == RECV_NOT_PROCESSED) {
recv_addr->state = RECV_BEING_READ;
page_nos[n] = page_no;
n++;
}
mutex_exit(&(recv_sys->mutex));
for (const ulint up_limit = page_no + RECV_READ_AHEAD_AREA;
page_no < up_limit; page_no++) {
recv_addr_t* recv_addr = recv_get_fil_addr_struct(
page_id.space(), page_no);
if (recv_addr
&& recv_addr->state == RECV_NOT_PROCESSED
&& !buf_page_peek(page_id_t(page_id.space(), page_no))) {
recv_addr->state = RECV_BEING_READ;
*p++ = page_no;
}
}
buf_read_recv_pages(FALSE, page_id.space(), page_nos, n);
return(n);
mutex_exit(&recv_sys->mutex);
buf_read_recv_pages(FALSE, page_id.space(), page_nos,
ulint(p - page_nos));
mutex_enter(&recv_sys->mutex);
}
/** Apply the hash table of stored log records to persistent data pages.
@ -2186,59 +2144,55 @@ void recv_apply_hashed_log_recs(bool last_batch)
}
}
mtr_t mtr;
for (ulint i = 0; i < hash_get_n_cells(recv_sys->addr_hash); i++) {
for (recv_addr_t* recv_addr = static_cast<recv_addr_t*>(
HASH_GET_FIRST(recv_sys->addr_hash, i));
recv_addr;
recv_addr = static_cast<recv_addr_t*>(
HASH_GET_NEXT(addr_hash, recv_addr))) {
if (!UT_LIST_GET_LEN(recv_addr->rec_list)) {
ignore:
ut_a(recv_sys->n_addrs);
recv_sys->n_addrs--;
continue;
}
switch (recv_addr->state) {
case RECV_BEING_READ:
case RECV_BEING_PROCESSED:
case RECV_PROCESSED:
continue;
case RECV_DISCARDED:
goto ignore;
case RECV_NOT_PROCESSED:
break;
}
if (srv_is_tablespace_truncated(recv_addr->space)) {
/* Avoid applying REDO log for the tablespace
that is schedule for TRUNCATE. */
ut_a(recv_sys->n_addrs);
recv_addr->state = RECV_DISCARDED;
recv_sys->n_addrs--;
continue;
goto ignore;
}
if (recv_addr->state == RECV_DISCARDED
|| !UT_LIST_GET_LEN(recv_addr->rec_list)) {
ut_a(recv_sys->n_addrs);
recv_sys->n_addrs--;
continue;
}
const page_id_t page_id(recv_addr->space,
recv_addr->page_no);
const page_id_t page_id(recv_addr->space,
recv_addr->page_no);
bool found;
const page_size_t& page_size
= fil_space_get_page_size(recv_addr->space,
&found);
ut_ad(found);
if (recv_addr->state == RECV_NOT_PROCESSED) {
mutex_exit(&recv_sys->mutex);
if (buf_page_peek(page_id)) {
mtr_t mtr;
mtr.start();
buf_block_t* block = buf_page_get(
page_id, page_size,
RW_X_LATCH, &mtr);
buf_block_dbg_add_level(
block, SYNC_NO_ORDER_CHECK);
recv_recover_page(FALSE, block);
mtr.commit();
} else {
recv_read_in_area(page_id);
}
mutex_enter(&recv_sys->mutex);
mtr.start();
mtr.set_log_mode(MTR_LOG_NONE);
if (buf_block_t* block = buf_page_get_gen(
page_id, univ_page_size, RW_X_LATCH,
NULL, BUF_GET_IF_IN_POOL,
__FILE__, __LINE__, &mtr, NULL)) {
buf_block_dbg_add_level(
block, SYNC_NO_ORDER_CHECK);
recv_recover_page(block, mtr, recv_addr);
ut_ad(mtr.has_committed());
} else {
mtr.commit();
recv_read_in_area(page_id);
}
}
}
@ -2485,6 +2439,15 @@ recv_report_corrupt_log(
return(true);
}
/** Report a MLOG_INDEX_LOAD operation.
@param[in] space_id tablespace identifier */
ATTRIBUTE_COLD static void recv_mlog_index_load(ulint space_id)
{
if (log_optimized_ddl_op) {
log_optimized_ddl_op(space_id);
}
}
/** Parse log records from a buffer and optionally store them to a
hash table to wait merging to file pages.
@param[in] checkpoint_lsn the LSN of the latest checkpoint
@ -2506,6 +2469,7 @@ bool recv_parse_log_recs(lsn_t checkpoint_lsn, store_t store, bool apply)
byte* body;
ut_ad(log_mutex_own());
ut_ad(mutex_own(&recv_sys->mutex));
ut_ad(recv_sys->parse_start_lsn != 0);
loop:
ptr = recv_sys->buf + recv_sys->recovered_offset;
@ -2640,9 +2604,7 @@ loop:
/* fall through */
case MLOG_INDEX_LOAD:
if (type == MLOG_INDEX_LOAD) {
if (log_optimized_ddl_op) {
log_optimized_ddl_op(space);
}
recv_mlog_index_load(space);
}
/* fall through */
case MLOG_FILE_NAME:
@ -2796,10 +2758,7 @@ corrupted_log:
break;
#endif /* UNIV_LOG_LSN_DEBUG */
case MLOG_INDEX_LOAD:
/* Mariabackup FIXME: Report an error
when encountering MLOG_INDEX_LOAD on
--prepare or already on --backup. */
ut_a(srv_operation == SRV_OPERATION_NORMAL);
recv_mlog_index_load(space);
break;
case MLOG_FILE_NAME:
case MLOG_FILE_DELETE:
@ -3077,6 +3036,8 @@ recv_scan_log_recs(
*group_scanned_lsn = scanned_lsn;
mutex_enter(&recv_sys->mutex);
if (more_data && !recv_sys->found_corrupt_log) {
/* Try to parse more log records */
@ -3086,7 +3047,8 @@ recv_scan_log_recs(
|| recv_sys->found_corrupt_fs
|| recv_sys->mlog_checkpoint_lsn
== recv_sys->recovered_lsn);
return(true);
finished = true;
goto func_exit;
}
if (*store_to_hash != STORE_NO
@ -3107,6 +3069,8 @@ recv_scan_log_recs(
}
}
func_exit:
mutex_exit(&recv_sys->mutex);
return(finished);
}

View File

@ -4917,23 +4917,20 @@ page_zip_copy_recs(
page_zip_compress_write_log(page_zip, page, index, mtr);
}
/**********************************************************************//**
Parses a log record of compressing an index page.
@return end of log record or NULL */
byte*
page_zip_parse_compress(
/*====================*/
byte* ptr, /*!< in: buffer */
byte* end_ptr,/*!< in: buffer end */
page_t* page, /*!< out: uncompressed page */
page_zip_des_t* page_zip)/*!< out: compressed page */
/** Parse and optionally apply MLOG_ZIP_PAGE_COMPRESS.
@param[in] ptr log record
@param[in] end_ptr end of log
@param[in,out] block ROW_FORMAT=COMPRESSED block, or NULL for parsing only
@return end of log record
@retval NULL if the log record is incomplete */
byte* page_zip_parse_compress(const byte* ptr, const byte* end_ptr,
buf_block_t* block)
{
ulint size;
ulint trailer_size;
ut_ad(ptr != NULL);
ut_ad(end_ptr!= NULL);
ut_ad(!page == !page_zip);
if (UNIV_UNLIKELY(ptr + (2 + 2) > end_ptr)) {
@ -4950,14 +4947,22 @@ page_zip_parse_compress(
return(NULL);
}
if (page) {
if (!page_zip || page_zip_get_size(page_zip) < size) {
if (block) {
ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
page_zip_des_t* page_zip = buf_block_get_page_zip(block);
if (!page_zip || page_zip_get_size(page_zip) < size
|| block->page.id.page_no() < 3) {
corrupt:
recv_sys->found_corrupt_log = TRUE;
return(NULL);
}
memset(page_zip->data, 0, page_zip_get_size(page_zip));
mach_write_to_4(FIL_PAGE_OFFSET
+ page_zip->data, block->page.id.page_no());
mach_write_to_4(FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID
+ page_zip->data, block->page.id.space());
memcpy(page_zip->data + FIL_PAGE_PREV, ptr, 4);
memcpy(page_zip->data + FIL_PAGE_NEXT, ptr + 4, 4);
memcpy(page_zip->data + FIL_PAGE_TYPE, ptr + 8, size);
@ -4967,14 +4972,14 @@ corrupt:
memcpy(page_zip->data + page_zip_get_size(page_zip)
- trailer_size, ptr + 8 + size, trailer_size);
if (UNIV_UNLIKELY(!page_zip_decompress(page_zip, page,
if (UNIV_UNLIKELY(!page_zip_decompress(page_zip, block->frame,
TRUE))) {
goto corrupt;
}
}
return(ptr + 8 + size + trailer_size);
return(const_cast<byte*>(ptr) + 8 + size + trailer_size);
}
#endif /* !UNIV_INNOCHECKSUM */

View File

@ -1806,5 +1806,9 @@ exit:
ib::info() << "InnoDB_FTS: inserted " << count << " records";
}
if (psort_info[0].psort_common->trx->get_flush_observer()) {
row_merge_write_redo(aux_index);
}
return(error);
}

View File

@ -4519,17 +4519,14 @@ row_merge_drop_table(
that redo-logging of individual index pages was disabled, and
the flushing of such pages to the data files was completed.
@param[in] index an index tree on which redo logging was disabled */
static
void
row_merge_write_redo(
const dict_index_t* index)
void row_merge_write_redo(const dict_index_t* index)
{
mtr_t mtr;
byte* log_ptr;
ut_ad(!index->table->is_temporary());
ut_ad(!(index->type & (DICT_SPATIAL | DICT_FTS)));
mtr_t mtr;
mtr.start();
log_ptr = mlog_open(&mtr, 11 + 8);
byte* log_ptr = mlog_open(&mtr, 11 + 8);
log_ptr = mlog_write_initial_log_record_low(
MLOG_INDEX_LOAD,
index->table->space_id, index->page, log_ptr, &mtr);
@ -5070,7 +5067,10 @@ func_exit:
= dict_table_get_first_index(new_table);
index != NULL;
index = dict_table_get_next_index(index)) {
row_merge_write_redo(index);
if (!(index->type
& (DICT_FTS | DICT_SPATIAL))) {
row_merge_write_redo(index);
}
}
}
}

View File

@ -2771,7 +2771,7 @@ row_mysql_drop_garbage_tables()
btr_pcur_commit_specify_mtr(&pcur, &mtr);
if (dict_load_table(table_name, true,
DICT_ERR_IGNORE_ALL)) {
DICT_ERR_IGNORE_DROP)) {
row_drop_table_for_mysql(table_name, trx,
SQLCOM_DROP_TABLE);
trx_commit_for_mysql(trx);