Merge 5.5 into 10.0

Also, implement MDEV-11027 a little differently from 5.5:

recv_sys_t::report(ib_time_t): Determine whether progress should
be reported.

recv_apply_hashed_log_recs(): Rename the parameter to last_batch.
This commit is contained in:
Marko Mäkelä 2017-03-08 11:40:43 +02:00
commit 47396ddea9
21 changed files with 504 additions and 582 deletions

View File

@ -2436,5 +2436,39 @@ EXECUTE stmt;
i
6
drop table t1, t2, t3;
#
# MDEV-11078: NULL NOT IN (non-empty subquery) should never return results
#
create table t1(a int,b int);
create table t2(a int,b int);
insert into t1 value (1,2);
select (NULL) in (select 1 from t1);
(NULL) in (select 1 from t1)
NULL
select (null) in (select 1 from t2);
(null) in (select 1 from t2)
0
select 1 in (select 1 from t1);
1 in (select 1 from t1)
1
select 1 in (select 1 from t2);
1 in (select 1 from t2)
0
select 1 from dual where null in (select 1 from t1);
1
select 1 from dual where null in (select 1 from t2);
1
select (null,null) in (select * from t1);
(null,null) in (select * from t1)
NULL
select (null,null) in (select * from t2);
(null,null) in (select * from t2)
0
select 1 from dual where null not in (select 1 from t1);
1
select 1 from dual where null not in (select 1 from t2);
1
1
drop table t1,t2;
SET optimizer_switch= @@global.optimizer_switch;
set @@tmp_table_size= @@global.tmp_table_size;

View File

@ -496,6 +496,21 @@ HAVING SQ2_alias1 . col_int_key >= 7
drop table t1;
set optimizer_switch=@subselect_innodb_tmp;
#
# MDEV-9635:Server crashes in part_of_refkey or assertion
# `!created && key_to_save < (int)s->keys' failed in
# TABLE::use_index(int) or with join_cache_level>2
#
SET join_cache_level=3;
CREATE TABLE t1 (f1 VARCHAR(1024)) ENGINE=InnoDB;
CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
CREATE TABLE t2 (f2 VARCHAR(4)) ENGINE=InnoDB;
INSERT INTO t2 VALUES ('foo'),('bar');
SELECT * FROM v1, t2 WHERE ( f1, f2 ) IN ( SELECT f1, f1 FROM t1 );
f1 f2
set join_cache_level = default;
drop view v1;
drop table t1,t2;
#
# MDEV-6041: ORDER BY+subqueries: subquery_table.key=outer_table.col is not recongized as binding
#
create table t1(a int) engine=innodb;

View File

@ -20,28 +20,24 @@ ERROR 42000: Unknown storage engine 'InnoDB'
FOUND /syntax error in innodb_log_group_home_dir/ in mysqld.1.err
SELECT * FROM t1;
ERROR 42000: Unknown storage engine 'InnoDB'
FOUND /InnoDB: Starting an apply batch of log records/ in mysqld.1.err
FOUND /InnoDB: Starting crash recovery from checkpoint LSN=/ in mysqld.1.err
SELECT * FROM t1;
ERROR 42000: Unknown storage engine 'InnoDB'
FOUND /InnoDB: Starting an apply batch of log records/ in mysqld.1.err
SELECT * FROM t1;
ERROR 42000: Unknown storage engine 'InnoDB'
FOUND /InnoDB: innodb_read_only prevents crash recovery/ in mysqld.1.err
SELECT * FROM t1;
ERROR 42000: Unknown storage engine 'InnoDB'
FOUND /InnoDB: Starting an apply batch of log records/ in mysqld.1.err
FOUND /InnoDB: Resizing redo log from 3\*[0-9]+ to 2\*[0-9]+ pages/ in mysqld.1.err
FOUND /redo log from 3\*[0-9]+ to 2\*[0-9]+ pages/ in mysqld.1.err
SELECT * FROM t1;
ERROR 42000: Unknown storage engine 'InnoDB'
FOUND /InnoDB: Starting an apply batch of log records/ in mysqld.1.err
FOUND /InnoDB: Resizing redo log from 3\*[0-9]+ to 2\*[0-9]+ pages/ in mysqld.1.err
FOUND /redo log from 3\*[0-9]+ to 2\*[0-9]+ pages/ in mysqld.1.err
SELECT * FROM t1;
ERROR 42000: Unknown storage engine 'InnoDB'
FOUND /InnoDB: innodb_read_only prevents crash recovery/ in mysqld.1.err
SELECT * FROM t1;
ERROR 42000: Unknown storage engine 'InnoDB'
FOUND /InnoDB: Starting an apply batch of log records/ in mysqld.1.err
FOUND /InnoDB: Resizing redo log from 3\*[0-9]+ to 2\*[0-9]+ pages/ in mysqld.1.err
FOUND /redo log from 3\*[0-9]+ to 2\*[0-9]+ pages/ in mysqld.1.err
SELECT * FROM t1;
ERROR 42000: Unknown storage engine 'InnoDB'
SELECT * FROM t1;

View File

@ -76,15 +76,13 @@ let SEARCH_PATTERN= syntax error in innodb_log_group_home_dir;
--source include/restart_mysqld.inc
--error ER_UNKNOWN_STORAGE_ENGINE
SELECT * FROM t1;
let SEARCH_PATTERN= InnoDB: Starting an apply batch of log records;
let SEARCH_PATTERN= InnoDB: Starting crash recovery from checkpoint LSN=;
--source include/search_pattern_in_file.inc
--let $restart_parameters= --debug=d,innodb_log_abort_3
--source include/restart_mysqld.inc
--error ER_UNKNOWN_STORAGE_ENGINE
SELECT * FROM t1;
let SEARCH_PATTERN= InnoDB: Starting an apply batch of log records;
--source include/search_pattern_in_file.inc
--let $restart_parameters= --innodb-read-only
--source include/restart_mysqld.inc
@ -98,18 +96,14 @@ let SEARCH_PATTERN= InnoDB: innodb_read_only prevents crash recovery;
--source include/restart_mysqld.inc
--error ER_UNKNOWN_STORAGE_ENGINE
SELECT * FROM t1;
let SEARCH_PATTERN= InnoDB: Starting an apply batch of log records;
--source include/search_pattern_in_file.inc
let SEARCH_PATTERN= InnoDB: Resizing redo log from 3\*[0-9]+ to 2\*[0-9]+ pages;
let SEARCH_PATTERN= redo log from 3\*[0-9]+ to 2\*[0-9]+ pages;
--source include/search_pattern_in_file.inc
--let $restart_parameters= --debug=d,innodb_log_abort_5
--source include/restart_mysqld.inc
--error ER_UNKNOWN_STORAGE_ENGINE
SELECT * FROM t1;
let SEARCH_PATTERN= InnoDB: Starting an apply batch of log records;
--source include/search_pattern_in_file.inc
let SEARCH_PATTERN= InnoDB: Resizing redo log from 3\*[0-9]+ to 2\*[0-9]+ pages;
let SEARCH_PATTERN= redo log from 3\*[0-9]+ to 2\*[0-9]+ pages;
--source include/search_pattern_in_file.inc
--let $restart_parameters= --innodb-read-only
@ -124,9 +118,7 @@ let SEARCH_PATTERN= InnoDB: innodb_read_only prevents crash recovery;
--error ER_UNKNOWN_STORAGE_ENGINE
SELECT * FROM t1;
let SEARCH_PATTERN= InnoDB: Starting an apply batch of log records;
--source include/search_pattern_in_file.inc
let SEARCH_PATTERN= InnoDB: Resizing redo log from 3\*[0-9]+ to 2\*[0-9]+ pages;
let SEARCH_PATTERN= redo log from 3\*[0-9]+ to 2\*[0-9]+ pages;
--source include/search_pattern_in_file.inc
--let $restart_parameters= --debug=d,innodb_log_abort_7

View File

@ -1997,5 +1997,24 @@ EXECUTE stmt;
drop table t1, t2, t3;
--echo #
--echo # MDEV-11078: NULL NOT IN (non-empty subquery) should never return results
--echo #
create table t1(a int,b int);
create table t2(a int,b int);
insert into t1 value (1,2);
select (NULL) in (select 1 from t1);
select (null) in (select 1 from t2);
select 1 in (select 1 from t1);
select 1 in (select 1 from t2);
select 1 from dual where null in (select 1 from t1);
select 1 from dual where null in (select 1 from t2);
select (null,null) in (select * from t1);
select (null,null) in (select * from t2);
select 1 from dual where null not in (select 1 from t1);
select 1 from dual where null not in (select 1 from t2);
drop table t1,t2;
SET optimizer_switch= @@global.optimizer_switch;
set @@tmp_table_size= @@global.tmp_table_size;

View File

@ -483,56 +483,21 @@ drop table t1;
set optimizer_switch=@subselect_innodb_tmp;
--echo #
--echo # MDEV-6041: ORDER BY+subqueries: subquery_table.key=outer_table.col is not recongized as binding
--echo #
create table t1(a int) engine=innodb;
insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t2(
id int primary key,
key1 int,
col1 int,
key(key1)
) engine=innodb;
insert into t2
select
A.a + B.a*10 + C.a*100 + D.a* 1000,
A.a + 10*B.a,
123456
from t1 A, t1 B, t1 C, t1 D;
--echo # Table tsubq:
--echo # - must use 'ref' (not 'index'), and must not use 'Using filesort'
--echo # - shows a bad estimate for 'rows' (but I'm not sure if one can do better w/o histograms)
explain select
(SELECT
concat(id, '-', key1, '-', col1)
FROM t2
WHERE t2.key1 = t1.a
ORDER BY t2.id ASC LIMIT 1)
from
t1;
--echo #
--echo # MDEV-6081: ORDER BY+ref(const): selectivity is very incorrect (MySQL Bug#14338686)
--echo # MDEV-9635:Server crashes in part_of_refkey or assertion
--echo # `!created && key_to_save < (int)s->keys' failed in
--echo # TABLE::use_index(int) or with join_cache_level>2
--echo #
alter table t2 add key2 int;
update t2 set key2=key1;
alter table t2 add key(key2);
analyze table t2;
flush tables;
--echo # Table tsubq must use 'ref' + Using filesort (not 'index' w/o filesort)
--replace_column 9 #
explain select
(SELECT
concat(id, '-', key1, '-', col1)
FROM t2
WHERE t2.key1 = t1.a
ORDER BY t2.key2 ASC LIMIT 1)
from
t1;
SET join_cache_level=3;
CREATE TABLE t1 (f1 VARCHAR(1024)) ENGINE=InnoDB;
CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
CREATE TABLE t2 (f2 VARCHAR(4)) ENGINE=InnoDB;
INSERT INTO t2 VALUES ('foo'),('bar');
SELECT * FROM v1, t2 WHERE ( f1, f2 ) IN ( SELECT f1, f1 FROM t1 );
set join_cache_level = default;
drop view v1;
drop table t1,t2;

View File

@ -15,7 +15,7 @@
#define PLUGIN_VERSION 0x104
#define PLUGIN_STR_VERSION "1.4.0"
#define PLUGIN_STR_VERSION "1.4.1"
#define _my_thread_var loc_thread_var

View File

@ -2048,6 +2048,7 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join,
We can encounter "NULL IN (SELECT ...)". Wrap the added condition
within a trig_cond.
*/
disable_cond_guard_for_const_null_left_expr(0);
item= new Item_func_trig_cond(item, get_cond_guard(0));
}
@ -2072,6 +2073,7 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join,
having= new Item_is_not_null_test(this, having);
if (left_expr->maybe_null)
{
disable_cond_guard_for_const_null_left_expr(0);
if (!(having= new Item_func_trig_cond(having,
get_cond_guard(0))))
DBUG_RETURN(true);
@ -2090,6 +2092,7 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join,
*/
if (!abort_on_null && left_expr->maybe_null)
{
disable_cond_guard_for_const_null_left_expr(0);
if (!(item= new Item_func_trig_cond(item, get_cond_guard(0))))
DBUG_RETURN(true);
}
@ -2116,6 +2119,7 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join,
(char *)"<result>"));
if (!abort_on_null && left_expr->maybe_null)
{
disable_cond_guard_for_const_null_left_expr(0);
if (!(new_having= new Item_func_trig_cond(new_having,
get_cond_guard(0))))
DBUG_RETURN(true);
@ -2311,6 +2315,7 @@ Item_in_subselect::create_row_in_to_exists_cond(JOIN * join,
Item *col_item= new Item_cond_or(item_eq, item_isnull);
if (!abort_on_null && left_expr->element_index(i)->maybe_null)
{
disable_cond_guard_for_const_null_left_expr(i);
if (!(col_item= new Item_func_trig_cond(col_item, get_cond_guard(i))))
DBUG_RETURN(true);
}
@ -2325,6 +2330,7 @@ Item_in_subselect::create_row_in_to_exists_cond(JOIN * join,
(char *)"<list ref>"));
if (!abort_on_null && left_expr->element_index(i)->maybe_null)
{
disable_cond_guard_for_const_null_left_expr(i);
if (!(item_nnull_test=
new Item_func_trig_cond(item_nnull_test, get_cond_guard(i))))
DBUG_RETURN(true);
@ -2381,6 +2387,7 @@ Item_in_subselect::create_row_in_to_exists_cond(JOIN * join,
item= new Item_cond_or(item, item_isnull);
if (left_expr->element_index(i)->maybe_null)
{
disable_cond_guard_for_const_null_left_expr(i);
if (!(item= new Item_func_trig_cond(item, get_cond_guard(i))))
DBUG_RETURN(true);
if (!(having_col_item=

View File

@ -619,6 +619,15 @@ public:
bool expr_cache_is_needed(THD *thd);
inline bool left_expr_has_null();
void disable_cond_guard_for_const_null_left_expr(int i)
{
if (left_expr->const_item() && !left_expr->is_expensive())
{
if (left_expr->element_index(i)->is_null())
set_cond_guard_var(i,FALSE);
}
}
int optimize(double *out_rows, double *cost);
/*
Return the identifier that we could use to identify the subquery for the

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2009 Monty Program Ab
/* Copyright (C) 2009, 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -16,23 +16,22 @@
/* Defining what to log to slow log */
#define LOG_SLOW_VERBOSITY_INIT 0
#define LOG_SLOW_VERBOSITY_INNODB (1 << 0)
#define LOG_SLOW_VERBOSITY_QUERY_PLAN (1 << 1)
#define LOG_SLOW_VERBOSITY_EXPLAIN (1 << 2)
#define LOG_SLOW_VERBOSITY_INNODB (1U << 0)
#define LOG_SLOW_VERBOSITY_QUERY_PLAN (1U << 1)
#define LOG_SLOW_VERBOSITY_EXPLAIN (1U << 2)
#define QPLAN_INIT QPLAN_QC_NO
#define QPLAN_ADMIN (1 << 0)
#define QPLAN_FILESORT (1 << 1)
#define QPLAN_FILESORT_DISK (1 << 2)
#define QPLAN_FULL_JOIN (1 << 3)
#define QPLAN_FULL_SCAN (1 << 4)
#define QPLAN_QC (1 << 5)
#define QPLAN_QC_NO (1 << 6)
#define QPLAN_TMP_DISK (1 << 7)
#define QPLAN_TMP_TABLE (1 << 8)
#define QPLAN_FILESORT_PRIORITY_QUEUE (1 << 9)
#define QPLAN_ADMIN (1U << 0)
#define QPLAN_FILESORT (1U << 1)
#define QPLAN_FILESORT_DISK (1U << 2)
#define QPLAN_FULL_JOIN (1U << 3)
#define QPLAN_FULL_SCAN (1U << 4)
#define QPLAN_QC (1U << 5)
#define QPLAN_QC_NO (1U << 6)
#define QPLAN_TMP_DISK (1U << 7)
#define QPLAN_TMP_TABLE (1U << 8)
#define QPLAN_FILESORT_PRIORITY_QUEUE (1U << 9)
/* ... */
#define QPLAN_MAX (((ulong) 1) << 31) /* reserved as placeholder */
#define QPLAN_MAX (1U << 31) /* reserved as placeholder */

View File

@ -10149,7 +10149,7 @@ void JOIN::drop_unused_derived_keys()
continue;
if (!table->pos_in_table_list->is_materialized_derived())
continue;
if (table->max_keys > 1)
if (table->max_keys > 1 && !tab->is_ref_for_hash_join())
table->use_index(tab->ref.key);
if (table->s->keys)
{

View File

@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -271,20 +272,12 @@ void
recv_sys_var_init(void);
/*===================*/
#endif /* !UNIV_HOTBACKUP */
/*******************************************************************//**
Empties the hash table of stored log records, applying them to appropriate
pages. */
/** Apply the hash table of stored log records to persistent data pages.
@param[in] last_batch whether the change buffer merge will be
performed as part of the operation */
UNIV_INTERN
void
recv_apply_hashed_log_recs(
/*=======================*/
ibool allow_ibuf); /*!< in: if TRUE, also ibuf operations are
allowed during the application; if FALSE,
no ibuf operations are allowed, and after
the application all file pages are flushed to
disk and invalidated in buffer pool: this
alternative means that no new log records
can be generated during the application */
recv_apply_hashed_log_recs(bool last_batch);
#ifdef UNIV_HOTBACKUP
/*******************************************************************//**
Applies log records in the hash table to a backup. */
@ -434,6 +427,8 @@ struct recv_sys_t{
scan find a corrupt log block, or a corrupt
log record, or there is a log parsing
buffer overflow */
/** the time when progress was last reported */
ib_time_t progress_time;
#ifdef UNIV_LOG_ARCHIVE
log_group_t* archive_group;
/*!< in archive recovery: the log group whose
@ -446,6 +441,20 @@ struct recv_sys_t{
addresses in the hash table */
recv_dblwr_t dblwr;
/** Determine whether redo log recovery progress should be reported.
@param[in] time the current time
@return whether progress should be reported
(the last report was at least 15 seconds ago) */
bool report(ib_time_t time)
{
if (time - progress_time < 15) {
return false;
}
progress_time = time;
return true;
}
};
/** The recovery system */

View File

@ -2,7 +2,7 @@
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2009, Google Inc.
Copyright (c) 2017, MariaDB Corporation. All Rights Reserved.
Copyright (c) 2017, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@ -1746,7 +1746,7 @@ log_preflush_pool_modified_pages(
and we could not make a new checkpoint on the basis of the
info on the buffer pool only. */
recv_apply_hashed_log_recs(TRUE);
recv_apply_hashed_log_recs(true);
}
success = buf_flush_list(ULINT_MAX, new_oldest, &n_pages);
@ -2085,7 +2085,7 @@ log_checkpoint(
ut_ad(!srv_read_only_mode);
if (recv_recovery_is_on()) {
recv_apply_hashed_log_recs(TRUE);
recv_apply_hashed_log_recs(true);
}
if (srv_unix_file_flush_method != SRV_UNIX_NOSYNC) {
@ -2336,6 +2336,11 @@ loop:
start_lsn += len;
buf += len;
if (recv_sys->report(ut_time())) {
ib_logf(IB_LOG_LEVEL_INFO, "Read redo log up to LSN=" LSN_PF,
start_lsn);
}
if (start_lsn != end_lsn) {
goto loop;

View File

@ -2,7 +2,7 @@
Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
Copyright (c) 2017, MariaDB Corporation. All Rights Reserved.
Copyright (c) 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -73,7 +73,7 @@ this must be less than UNIV_PAGE_SIZE as it is stored in the buffer pool */
#define RECV_READ_AHEAD_AREA 32
/** The recovery system */
UNIV_INTERN recv_sys_t* recv_sys = NULL;
UNIV_INTERN recv_sys_t* recv_sys;
/** TRUE when applying redo log records during crash recovery; FALSE
otherwise. Note that this is FALSE while a background thread is
rolling back incomplete transactions. */
@ -129,9 +129,6 @@ UNIV_INTERN ibool recv_is_making_a_backup = FALSE;
UNIV_INTERN ibool recv_is_from_backup = FALSE;
# define buf_pool_get_curr_size() (5 * 1024 * 1024)
#endif /* !UNIV_HOTBACKUP */
/** The following counter is used to decide when to print info on
log scan */
static ulint recv_scan_print_counter;
/** The type of the previous parsed redo log record */
static ulint recv_previous_parsed_rec_type;
@ -306,8 +303,6 @@ recv_sys_var_init(void)
recv_no_ibuf_operations = FALSE;
recv_scan_print_counter = 0;
recv_previous_parsed_rec_type = 999999;
recv_previous_parsed_rec_offset = 0;
@ -418,6 +413,7 @@ recv_sys_init(
recv_sys->last_block_buf_start, OS_FILE_LOG_BLOCK_SIZE));
recv_sys->found_corrupt_log = FALSE;
recv_sys->progress_time = ut_time();
recv_max_page_lsn = 0;
@ -1587,6 +1583,7 @@ recv_recover_page_func(
ibool success;
#endif /* !UNIV_HOTBACKUP */
mtr_t mtr;
ib_time_t time;
mutex_enter(&(recv_sys->mutex));
@ -1762,6 +1759,8 @@ recv_recover_page_func(
mtr_commit(&mtr);
time = ut_time();
mutex_enter(&(recv_sys->mutex));
if (recv_max_page_lsn < page_lsn) {
@ -1770,11 +1769,16 @@ recv_recover_page_func(
recv_addr->state = RECV_PROCESSED;
ut_a(recv_sys->n_addrs);
recv_sys->n_addrs--;
mutex_exit(&(recv_sys->mutex));
ut_a(recv_sys->n_addrs > 0);
if (--recv_sys->n_addrs && recv_sys->progress_time - time >= 15) {
recv_sys->progress_time = time;
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: To recover: " ULINTPF " pages from log\n",
recv_sys->n_addrs);
}
mutex_exit(&recv_sys->mutex);
}
#ifndef UNIV_HOTBACKUP
@ -1820,59 +1824,48 @@ recv_read_in_area(
}
buf_read_recv_pages(FALSE, space, zip_size, page_nos, n);
/*
fprintf(stderr, "Recv pages at %lu n %lu\n", page_nos[0], n);
*/
return(n);
}
/*******************************************************************//**
Empties the hash table of stored log records, applying them to appropriate
pages. */
/** Apply the hash table of stored log records to persistent data pages.
@param[in] last_batch whether the change buffer merge will be
performed as part of the operation */
UNIV_INTERN
void
recv_apply_hashed_log_recs(
/*=======================*/
ibool allow_ibuf) /*!< in: if TRUE, also ibuf operations are
allowed during the application; if FALSE,
no ibuf operations are allowed, and after
the application all file pages are flushed to
disk and invalidated in buffer pool: this
alternative means that no new log records
can be generated during the application;
the caller must in this case own the log
mutex */
recv_apply_hashed_log_recs(bool last_batch)
{
recv_addr_t* recv_addr;
ulint i;
ibool has_printed = FALSE;
mtr_t mtr;
loop:
mutex_enter(&(recv_sys->mutex));
for (;;) {
mutex_enter(&recv_sys->mutex);
if (recv_sys->apply_batch_on) {
mutex_exit(&(recv_sys->mutex));
if (!recv_sys->apply_batch_on) {
break;
}
mutex_exit(&recv_sys->mutex);
os_thread_sleep(500000);
goto loop;
}
ut_ad((!allow_ibuf) == mutex_own(&log_sys->mutex));
ut_ad(!last_batch == mutex_own(&log_sys->mutex));
if (!allow_ibuf) {
if (!last_batch) {
recv_no_ibuf_operations = TRUE;
}
if (ulint n = recv_sys->n_addrs) {
const char* msg = last_batch
? "Starting final batch to recover "
: "Starting a batch to recover ";
ib_logf(IB_LOG_LEVEL_INFO,
"%s" ULINTPF " pages from redo log", msg, n);
}
recv_sys->apply_log_recs = TRUE;
recv_sys->apply_batch_on = TRUE;
for (i = 0; i < hash_get_n_cells(recv_sys->addr_hash); i++) {
for (recv_addr = static_cast<recv_addr_t*>(
HASH_GET_FIRST(recv_sys->addr_hash, i));
recv_addr != 0;
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))) {
@ -1881,24 +1874,12 @@ loop:
ulint page_no = recv_addr->page_no;
if (recv_addr->state == RECV_NOT_PROCESSED) {
if (!has_printed) {
ib_logf(IB_LOG_LEVEL_INFO,
"Starting an apply batch"
" of log records"
" to the database...");
fputs("InnoDB: Progress in percent: ",
stderr);
has_printed = TRUE;
}
mutex_exit(&(recv_sys->mutex));
mutex_exit(&recv_sys->mutex);
if (buf_page_peek(space, page_no)) {
buf_block_t* block;
mtr_t mtr;
mtr_start(&mtr);
block = buf_page_get(
buf_block_t* block = buf_page_get(
space, zip_size, page_no,
RW_X_LATCH, &mtr);
buf_block_dbg_add_level(
@ -1911,19 +1892,9 @@ loop:
page_no);
}
mutex_enter(&(recv_sys->mutex));
mutex_enter(&recv_sys->mutex);
}
}
if (has_printed
&& (i * 100) / hash_get_n_cells(recv_sys->addr_hash)
!= ((i + 1) * 100)
/ hash_get_n_cells(recv_sys->addr_hash)) {
fprintf(stderr, "%lu ", (ulong)
((i * 100)
/ hash_get_n_cells(recv_sys->addr_hash)));
}
}
/* Wait until all the pages have been processed */
@ -1937,12 +1908,7 @@ loop:
mutex_enter(&(recv_sys->mutex));
}
if (has_printed) {
fprintf(stderr, "\n");
}
if (!allow_ibuf) {
if (!last_batch) {
bool success;
/* Flush all the file pages to disk and invalidate them in
@ -1982,11 +1948,7 @@ loop:
recv_sys_empty_hash();
if (has_printed) {
fprintf(stderr, "InnoDB: Apply batch completed\n");
}
mutex_exit(&(recv_sys->mutex));
mutex_exit(&recv_sys->mutex);
}
#else /* !UNIV_HOTBACKUP */
/*******************************************************************//**
@ -2009,11 +1971,6 @@ recv_apply_log_recs_for_backup(void)
block = back_block1;
ib_logf(IB_LOG_LEVEL_INFO,
"Starting an apply batch of log records to the database...");
fputs("InnoDB: Progress in percent: ", stderr);
n_hash_cells = hash_get_n_cells(recv_sys->addr_hash);
for (i = 0; i < n_hash_cells; i++) {
@ -2125,13 +2082,6 @@ recv_apply_log_recs_for_backup(void)
skip_this_recv_addr:
recv_addr = HASH_GET_NEXT(addr_hash, recv_addr);
}
if ((100 * i) / n_hash_cells
!= (100 * (i + 1)) / n_hash_cells) {
fprintf(stderr, "%lu ",
(ulong) ((100 * i) / n_hash_cells));
fflush(stderr);
}
}
recv_sys_empty_hash();
@ -2795,11 +2745,10 @@ recv_scan_log_recs(
#ifndef UNIV_HOTBACKUP
if (recv_log_scan_is_startup_type
&& !recv_needed_recovery) {
if (!srv_read_only_mode) {
ib_logf(IB_LOG_LEVEL_INFO,
"Log scan progressed past the "
"checkpoint lsn " LSN_PF "",
"Starting crash recovery from "
"checkpoint LSN=" LSN_PF,
recv_sys->scanned_lsn);
recv_init_crash_recovery();
@ -2858,19 +2807,6 @@ recv_scan_log_recs(
*group_scanned_lsn = scanned_lsn;
if (recv_needed_recovery
|| (recv_is_from_backup && !recv_is_making_a_backup)) {
recv_scan_print_counter++;
if (finished || (recv_scan_print_counter % 80 == 0)) {
fprintf(stderr,
"InnoDB: Doing recovery: scanned up to"
" log sequence number " LSN_PF "\n",
*group_scanned_lsn);
}
}
if (more_data && !recv_sys->found_corrupt_log) {
/* Try to parse more log records */
@ -2886,7 +2822,7 @@ recv_scan_log_recs(
log yet: they would be produced by ibuf
operations */
recv_apply_hashed_log_recs(FALSE);
recv_apply_hashed_log_recs(false);
}
#endif /* !UNIV_HOTBACKUP */
@ -2962,11 +2898,6 @@ recv_init_crash_recovery(void)
recv_needed_recovery = TRUE;
ib_logf(IB_LOG_LEVEL_INFO, "Database was not shutdown normally!");
ib_logf(IB_LOG_LEVEL_INFO, "Starting crash recovery.");
ib_logf(IB_LOG_LEVEL_INFO,
"Reading tablespace information from the .ibd files...");
fil_load_single_table_tablespaces();
/* If we are using the doublewrite method, we will
@ -2977,9 +2908,7 @@ recv_init_crash_recovery(void)
if (srv_force_recovery < SRV_FORCE_NO_LOG_REDO) {
ib_logf(IB_LOG_LEVEL_INFO,
"Restoring possible half-written data pages ");
ib_logf(IB_LOG_LEVEL_INFO,
"Restoring possible half-written data pages "
"from the doublewrite buffer...");
buf_dblwr_process();
@ -3950,7 +3879,7 @@ recv_recovery_from_archive_start(
if (limit_lsn != LSN_MAX) {
recv_apply_hashed_log_recs(FALSE);
recv_apply_hashed_log_recs(false);
recv_reset_logs(0, FALSE, recv_sys->recovered_lsn);
}

View File

@ -3,7 +3,7 @@
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2008, Google Inc.
Copyright (c) 2009, Percona Inc.
Copyright (c) 2013, 2017, MariaDB Corporation
Copyright (c) 2013, 2017, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@ -2520,7 +2520,7 @@ files_checked:
}
}
/* This must precede recv_apply_hashed_log_recs(TRUE). */
/* This must precede recv_apply_hashed_log_recs(true). */
ib_bh = trx_sys_init_at_db_start();
if (srv_force_recovery < SRV_FORCE_NO_LOG_REDO) {
@ -2528,7 +2528,7 @@ files_checked:
respective file pages, for the last batch of
recv_group_scan_log_recs(). */
recv_apply_hashed_log_recs(TRUE);
recv_apply_hashed_log_recs(true);
DBUG_PRINT("ib_log", ("apply completed"));
}

View File

@ -1,6 +1,6 @@
/* Copyright (C) 2004-2008 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
Copyright (C) 2008-2009 Sun Microsystems, Inc.
Copyright (c) 2009, 2014, SkySQL Ab.
Copyright (c) 2009, 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -1284,75 +1284,75 @@ int ha_maria::write_row(uchar * buf)
int ha_maria::check(THD * thd, HA_CHECK_OPT * check_opt)
{
int error;
HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
HA_CHECK *param= (HA_CHECK*) thd->alloc(sizeof *param);
MARIA_SHARE *share= file->s;
const char *old_proc_info;
TRN *old_trn= file->trn;
if (!file || !&param) return HA_ADMIN_INTERNAL_ERROR;
if (!file || !param) return HA_ADMIN_INTERNAL_ERROR;
maria_chk_init(&param);
param.thd= thd;
param.op_name= "check";
param.db_name= table->s->db.str;
param.table_name= table->alias.c_ptr();
param.testflag= check_opt->flags | T_CHECK | T_SILENT;
param.stats_method= (enum_handler_stats_method)THDVAR(thd,stats_method);
maria_chk_init(param);
param->thd= thd;
param->op_name= "check";
param->db_name= table->s->db.str;
param->table_name= table->alias.c_ptr();
param->testflag= check_opt->flags | T_CHECK | T_SILENT;
param->stats_method= (enum_handler_stats_method)THDVAR(thd,stats_method);
if (!(table->db_stat & HA_READ_ONLY))
param.testflag |= T_STATISTICS;
param.using_global_keycache= 1;
param->testflag |= T_STATISTICS;
param->using_global_keycache= 1;
if (!maria_is_crashed(file) &&
(((param.testflag & T_CHECK_ONLY_CHANGED) &&
(((param->testflag & T_CHECK_ONLY_CHANGED) &&
!(share->state.changed & (STATE_CHANGED | STATE_CRASHED_FLAGS |
STATE_IN_REPAIR)) &&
share->state.open_count == 0) ||
((param.testflag & T_FAST) && (share->state.open_count ==
((param->testflag & T_FAST) && (share->state.open_count ==
(uint) (share->global_changed ? 1 :
0)))))
return HA_ADMIN_ALREADY_DONE;
maria_chk_init_for_check(&param, file);
maria_chk_init_for_check(param, file);
if ((file->s->state.changed & (STATE_CRASHED_FLAGS | STATE_MOVED)) ==
STATE_MOVED)
{
_ma_check_print_error(&param, "%s", zerofill_error_msg);
_ma_check_print_error(param, "%s", zerofill_error_msg);
return HA_ADMIN_CORRUPT;
}
old_proc_info= thd_proc_info(thd, "Checking status");
thd_progress_init(thd, 3);
error= maria_chk_status(&param, file); // Not fatal
if (maria_chk_size(&param, file))
error= maria_chk_status(param, file); // Not fatal
if (maria_chk_size(param, file))
error= 1;
if (!error)
error|= maria_chk_del(&param, file, param.testflag);
error|= maria_chk_del(param, file, param->testflag);
thd_proc_info(thd, "Checking keys");
thd_progress_next_stage(thd);
if (!error)
error= maria_chk_key(&param, file);
error= maria_chk_key(param, file);
thd_proc_info(thd, "Checking data");
thd_progress_next_stage(thd);
if (!error)
{
if ((!(param.testflag & T_QUICK) &&
if ((!(param->testflag & T_QUICK) &&
((share->options &
(HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ||
(param.testflag & (T_EXTEND | T_MEDIUM)))) || maria_is_crashed(file))
(param->testflag & (T_EXTEND | T_MEDIUM)))) || maria_is_crashed(file))
{
ulonglong old_testflag= param.testflag;
param.testflag |= T_MEDIUM;
if (!(error= init_io_cache(&param.read_cache, file->dfile.file,
ulonglong old_testflag= param->testflag;
param->testflag |= T_MEDIUM;
if (!(error= init_io_cache(&param->read_cache, file->dfile.file,
my_default_record_cache_size, READ_CACHE,
share->pack.header_length, 1, MYF(MY_WME))))
{
error= maria_chk_data_link(&param, file,
MY_TEST(param.testflag & T_EXTEND));
end_io_cache(&(param.read_cache));
error= maria_chk_data_link(param, file,
MY_TEST(param->testflag & T_EXTEND));
end_io_cache(&param->read_cache);
}
param.testflag= old_testflag;
param->testflag= old_testflag;
}
}
if (!error)
@ -1360,7 +1360,7 @@ int ha_maria::check(THD * thd, HA_CHECK_OPT * check_opt)
if ((share->state.changed & (STATE_CHANGED |
STATE_CRASHED_FLAGS |
STATE_IN_REPAIR | STATE_NOT_ANALYZED)) ||
(param.testflag & T_STATISTICS) || maria_is_crashed(file))
(param->testflag & T_STATISTICS) || maria_is_crashed(file))
{
file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
mysql_mutex_lock(&share->intern_lock);
@ -1368,7 +1368,7 @@ int ha_maria::check(THD * thd, HA_CHECK_OPT * check_opt)
share->state.changed&= ~(STATE_CHANGED | STATE_CRASHED_FLAGS |
STATE_IN_REPAIR);
if (!(table->db_stat & HA_READ_ONLY))
error= maria_update_state_info(&param, file,
error= maria_update_state_info(param, file,
UPDATE_TIME | UPDATE_OPEN_COUNT |
UPDATE_STAT);
mysql_mutex_unlock(&share->intern_lock);
@ -1399,33 +1399,33 @@ int ha_maria::check(THD * thd, HA_CHECK_OPT * check_opt)
int ha_maria::analyze(THD *thd, HA_CHECK_OPT * check_opt)
{
int error= 0;
HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
HA_CHECK *param= (HA_CHECK*) thd->alloc(sizeof *param);
MARIA_SHARE *share= file->s;
const char *old_proc_info;
if (!&param)
if (!param)
return HA_ADMIN_INTERNAL_ERROR;
maria_chk_init(&param);
param.thd= thd;
param.op_name= "analyze";
param.db_name= table->s->db.str;
param.table_name= table->alias.c_ptr();
param.testflag= (T_FAST | T_CHECK | T_SILENT | T_STATISTICS |
maria_chk_init(param);
param->thd= thd;
param->op_name= "analyze";
param->db_name= table->s->db.str;
param->table_name= table->alias.c_ptr();
param->testflag= (T_FAST | T_CHECK | T_SILENT | T_STATISTICS |
T_DONT_CHECK_CHECKSUM);
param.using_global_keycache= 1;
param.stats_method= (enum_handler_stats_method)THDVAR(thd,stats_method);
param->using_global_keycache= 1;
param->stats_method= (enum_handler_stats_method)THDVAR(thd,stats_method);
if (!(share->state.changed & STATE_NOT_ANALYZED))
return HA_ADMIN_ALREADY_DONE;
old_proc_info= thd_proc_info(thd, "Scanning");
thd_progress_init(thd, 1);
error= maria_chk_key(&param, file);
error= maria_chk_key(param, file);
if (!error)
{
mysql_mutex_lock(&share->intern_lock);
error= maria_update_state_info(&param, file, UPDATE_STAT);
error= maria_update_state_info(param, file, UPDATE_STAT);
mysql_mutex_unlock(&share->intern_lock);
}
else if (!maria_is_crashed(file) && !thd->killed)
@ -1438,46 +1438,46 @@ int ha_maria::analyze(THD *thd, HA_CHECK_OPT * check_opt)
int ha_maria::repair(THD * thd, HA_CHECK_OPT *check_opt)
{
int error;
HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
HA_CHECK *param= (HA_CHECK*) thd->alloc(sizeof *param);
ha_rows start_records;
const char *old_proc_info;
if (!file || !&param)
if (!file || !param)
return HA_ADMIN_INTERNAL_ERROR;
maria_chk_init(&param);
param.thd= thd;
param.op_name= "repair";
param.testflag= ((check_opt->flags & ~(T_EXTEND)) |
maria_chk_init(param);
param->thd= thd;
param->op_name= "repair";
param->testflag= ((check_opt->flags & ~(T_EXTEND)) |
T_SILENT | T_FORCE_CREATE | T_CALC_CHECKSUM |
(check_opt->flags & T_EXTEND ? T_REP : T_REP_BY_SORT));
param.sort_buffer_length= THDVAR(thd, sort_buffer_size);
param.backup_time= check_opt->start_time;
param->sort_buffer_length= THDVAR(thd, sort_buffer_size);
param->backup_time= check_opt->start_time;
start_records= file->state->records;
old_proc_info= thd_proc_info(thd, "Checking table");
thd_progress_init(thd, 1);
while ((error= repair(thd, &param, 0)) && param.retry_repair)
while ((error= repair(thd, param, 0)) && param->retry_repair)
{
param.retry_repair= 0;
if (test_all_bits(param.testflag,
param->retry_repair= 0;
if (test_all_bits(param->testflag,
(uint) (T_RETRY_WITHOUT_QUICK | T_QUICK)))
{
param.testflag&= ~(T_RETRY_WITHOUT_QUICK | T_QUICK);
param->testflag&= ~(T_RETRY_WITHOUT_QUICK | T_QUICK);
/* Ensure we don't loose any rows when retrying without quick */
param.testflag|= T_SAFE_REPAIR;
param->testflag|= T_SAFE_REPAIR;
if (thd->vio_ok())
_ma_check_print_info(&param, "Retrying repair without quick");
_ma_check_print_info(param, "Retrying repair without quick");
else
sql_print_information("Retrying repair of: '%s' without quick",
table->s->path.str);
continue;
}
param.testflag &= ~T_QUICK;
if ((param.testflag & T_REP_BY_SORT))
param->testflag &= ~T_QUICK;
if (param->testflag & T_REP_BY_SORT)
{
param.testflag= (param.testflag & ~T_REP_BY_SORT) | T_REP;
param->testflag= (param->testflag & ~T_REP_BY_SORT) | T_REP;
if (thd->vio_ok())
_ma_check_print_info(&param, "Retrying repair with keycache");
_ma_check_print_info(param, "Retrying repair with keycache");
sql_print_information("Retrying repair of: '%s' with keycache",
table->s->path.str);
continue;
@ -1501,20 +1501,20 @@ int ha_maria::repair(THD * thd, HA_CHECK_OPT *check_opt)
int ha_maria::zerofill(THD * thd, HA_CHECK_OPT *check_opt)
{
int error;
HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
HA_CHECK *param= (HA_CHECK*) thd->alloc(sizeof *param);
TRN *old_trn;
MARIA_SHARE *share= file->s;
if (!file || !&param)
if (!file || !param)
return HA_ADMIN_INTERNAL_ERROR;
old_trn= file->trn;
maria_chk_init(&param);
param.thd= thd;
param.op_name= "zerofill";
param.testflag= check_opt->flags | T_SILENT | T_ZEROFILL;
param.sort_buffer_length= THDVAR(thd, sort_buffer_size);
error=maria_zerofill(&param, file, share->open_file_name.str);
maria_chk_init(param);
param->thd= thd;
param->op_name= "zerofill";
param->testflag= check_opt->flags | T_SILENT | T_ZEROFILL;
param->sort_buffer_length= THDVAR(thd, sort_buffer_size);
error=maria_zerofill(param, file, share->open_file_name.str);
/* Reset trn, that may have been set by repair */
_ma_set_trn_for_table(file, old_trn);
@ -1524,7 +1524,7 @@ int ha_maria::zerofill(THD * thd, HA_CHECK_OPT *check_opt)
TrID create_trid= trnman_get_min_safe_trid();
mysql_mutex_lock(&share->intern_lock);
share->state.changed|= STATE_NOT_MOVABLE;
maria_update_state_info(&param, file, UPDATE_TIME | UPDATE_OPEN_COUNT);
maria_update_state_info(param, file, UPDATE_TIME | UPDATE_OPEN_COUNT);
_ma_update_state_lsns_sub(share, LSN_IMPOSSIBLE, create_trid,
TRUE, TRUE);
mysql_mutex_unlock(&share->intern_lock);
@ -1535,24 +1535,24 @@ int ha_maria::zerofill(THD * thd, HA_CHECK_OPT *check_opt)
int ha_maria::optimize(THD * thd, HA_CHECK_OPT *check_opt)
{
int error;
HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
HA_CHECK *param= (HA_CHECK*) thd->alloc(sizeof *param);
if (!file || !&param)
if (!file || !param)
return HA_ADMIN_INTERNAL_ERROR;
maria_chk_init(&param);
param.thd= thd;
param.op_name= "optimize";
param.testflag= (check_opt->flags | T_SILENT | T_FORCE_CREATE |
maria_chk_init(param);
param->thd= thd;
param->op_name= "optimize";
param->testflag= (check_opt->flags | T_SILENT | T_FORCE_CREATE |
T_REP_BY_SORT | T_STATISTICS | T_SORT_INDEX);
param.sort_buffer_length= THDVAR(thd, sort_buffer_size);
param->sort_buffer_length= THDVAR(thd, sort_buffer_size);
thd_progress_init(thd, 1);
if ((error= repair(thd, &param, 1)) && param.retry_repair)
if ((error= repair(thd, param, 1)) && param->retry_repair)
{
sql_print_warning("Warning: Optimize table got errno %d on %s.%s, retrying",
my_errno, param.db_name, param.table_name);
param.testflag &= ~T_REP_BY_SORT;
error= repair(thd, &param, 0);
my_errno, param->db_name, param->table_name);
param->testflag &= ~T_REP_BY_SORT;
error= repair(thd, param, 0);
}
thd_progress_end(thd);
return error;
@ -1802,17 +1802,17 @@ int ha_maria::assign_to_keycache(THD * thd, HA_CHECK_OPT *check_opt)
if (error != HA_ADMIN_OK)
{
/* Send error to user */
HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
if (!&param)
HA_CHECK *param= (HA_CHECK*) thd->alloc(sizeof *param);
if (!param)
return HA_ADMIN_INTERNAL_ERROR;
maria_chk_init(&param);
param.thd= thd;
param.op_name= "assign_to_keycache";
param.db_name= table->s->db.str;
param.table_name= table->s->table_name.str;
param.testflag= 0;
_ma_check_print_error(&param, errmsg);
maria_chk_init(param);
param->thd= thd;
param->op_name= "assign_to_keycache";
param->db_name= table->s->db.str;
param->table_name= table->s->table_name.str;
param->testflag= 0;
_ma_check_print_error(param, errmsg);
}
DBUG_RETURN(error);
#else
@ -1866,17 +1866,17 @@ int ha_maria::preload_keys(THD * thd, HA_CHECK_OPT *check_opt)
errmsg= buf;
}
HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
if (!&param)
HA_CHECK *param= (HA_CHECK*) thd->alloc(sizeof *param);
if (!param)
return HA_ADMIN_INTERNAL_ERROR;
maria_chk_init(&param);
param.thd= thd;
param.op_name= "preload_keys";
param.db_name= table->s->db.str;
param.table_name= table->s->table_name.str;
param.testflag= 0;
_ma_check_print_error(&param, "%s", errmsg);
maria_chk_init(param);
param->thd= thd;
param->op_name= "preload_keys";
param->db_name= table->s->db.str;
param->table_name= table->s->table_name.str;
param->testflag= 0;
_ma_check_print_error(param, "%s", errmsg);
DBUG_RETURN(HA_ADMIN_FAILED);
}
DBUG_RETURN(HA_ADMIN_OK);
@ -1977,25 +1977,25 @@ int ha_maria::enable_indexes(uint mode)
else if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE)
{
THD *thd= table->in_use;
HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
if (!&param)
HA_CHECK *param= (HA_CHECK*) thd->alloc(sizeof *param);
if (!param)
return HA_ADMIN_INTERNAL_ERROR;
const char *save_proc_info= thd_proc_info(thd, "Creating index");
maria_chk_init(&param);
param.op_name= "recreating_index";
param.testflag= (T_SILENT | T_REP_BY_SORT | T_QUICK |
maria_chk_init(param);
param->op_name= "recreating_index";
param->testflag= (T_SILENT | T_REP_BY_SORT | T_QUICK |
T_CREATE_MISSING_KEYS | T_SAFE_REPAIR);
/*
Don't lock and unlock table if it's locked.
Normally table should be locked. This test is mostly for safety.
*/
if (likely(file->lock_type != F_UNLCK))
param.testflag|= T_NO_LOCKS;
param->testflag|= T_NO_LOCKS;
if (file->create_unique_index_by_sort)
param.testflag|= T_CREATE_UNIQUE_BY_SORT;
param->testflag|= T_CREATE_UNIQUE_BY_SORT;
if (bulk_insert_single_undo == BULK_INSERT_SINGLE_UNDO_AND_NO_REPAIR)
{
@ -2004,23 +2004,23 @@ int ha_maria::enable_indexes(uint mode)
Don't bump create_rename_lsn, because UNDO_BULK_INSERT
should not be skipped in case of crash during repair.
*/
param.testflag|= T_NO_CREATE_RENAME_LSN;
param->testflag|= T_NO_CREATE_RENAME_LSN;
}
param.myf_rw &= ~MY_WAIT_IF_FULL;
param.sort_buffer_length= THDVAR(thd,sort_buffer_size);
param.stats_method= (enum_handler_stats_method)THDVAR(thd,stats_method);
param.tmpdir= &mysql_tmpdir_list;
if ((error= (repair(thd, &param, 0) != HA_ADMIN_OK)) && param.retry_repair)
param->myf_rw &= ~MY_WAIT_IF_FULL;
param->sort_buffer_length= THDVAR(thd,sort_buffer_size);
param->stats_method= (enum_handler_stats_method)THDVAR(thd,stats_method);
param->tmpdir= &mysql_tmpdir_list;
if ((error= (repair(thd, param, 0) != HA_ADMIN_OK)) && param->retry_repair)
{
sql_print_warning("Warning: Enabling keys got errno %d on %s.%s, "
"retrying",
my_errno, param.db_name, param.table_name);
my_errno, param->db_name, param->table_name);
/* This should never fail normally */
DBUG_ASSERT(thd->killed != 0);
/* Repairing by sort failed. Now try standard repair method. */
param.testflag &= ~T_REP_BY_SORT;
error= (repair(thd, &param, 0) != HA_ADMIN_OK);
param->testflag &= ~T_REP_BY_SORT;
error= (repair(thd, param, 0) != HA_ADMIN_OK);
/*
If the standard repair succeeded, clear all error messages which
might have been set by the first repair. They can still be seen

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2012, Oracle and/or its affiliates.
Copyright (c) 2009, 2014, SkySQL Ab.
Copyright (c) 2009, 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -872,59 +872,59 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
{
if (!file) return HA_ADMIN_INTERNAL_ERROR;
int error;
HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
HA_CHECK *param= (HA_CHECK*) thd->alloc(sizeof *param);
MYISAM_SHARE* share = file->s;
const char *old_proc_info=thd->proc_info;
if (!&param)
if (!param)
return HA_ADMIN_INTERNAL_ERROR;
thd_proc_info(thd, "Checking table");
myisamchk_init(&param);
param.thd = thd;
param.op_name = "check";
param.db_name= table->s->db.str;
param.table_name= table->alias.c_ptr();
param.testflag = check_opt->flags | T_CHECK | T_SILENT;
param.stats_method= (enum_handler_stats_method)THDVAR(thd, stats_method);
myisamchk_init(param);
param->thd = thd;
param->op_name = "check";
param->db_name= table->s->db.str;
param->table_name= table->alias.c_ptr();
param->testflag = check_opt->flags | T_CHECK | T_SILENT;
param->stats_method= (enum_handler_stats_method)THDVAR(thd, stats_method);
if (!(table->db_stat & HA_READ_ONLY))
param.testflag|= T_STATISTICS;
param.using_global_keycache = 1;
param->testflag|= T_STATISTICS;
param->using_global_keycache = 1;
if (!mi_is_crashed(file) &&
(((param.testflag & T_CHECK_ONLY_CHANGED) &&
(((param->testflag & T_CHECK_ONLY_CHANGED) &&
!(share->state.changed & (STATE_CHANGED | STATE_CRASHED |
STATE_CRASHED_ON_REPAIR)) &&
share->state.open_count == 0) ||
((param.testflag & T_FAST) && (share->state.open_count ==
((param->testflag & T_FAST) && (share->state.open_count ==
(uint) (share->global_changed ? 1 : 0)))))
return HA_ADMIN_ALREADY_DONE;
error = chk_status(&param, file); // Not fatal
error = chk_size(&param, file);
error = chk_status(param, file); // Not fatal
error = chk_size(param, file);
if (!error)
error |= chk_del(&param, file, param.testflag);
error |= chk_del(param, file, param->testflag);
if (!error)
error = chk_key(&param, file);
error = chk_key(param, file);
if (!error)
{
if ((!(param.testflag & T_QUICK) &&
if ((!(param->testflag & T_QUICK) &&
((share->options &
(HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ||
(param.testflag & (T_EXTEND | T_MEDIUM)))) ||
(param->testflag & (T_EXTEND | T_MEDIUM)))) ||
mi_is_crashed(file))
{
ulonglong old_testflag= param.testflag;
param.testflag|=T_MEDIUM;
if (!(error= init_io_cache(&param.read_cache, file->dfile,
ulonglong old_testflag= param->testflag;
param->testflag|=T_MEDIUM;
if (!(error= init_io_cache(&param->read_cache, file->dfile,
my_default_record_cache_size, READ_CACHE,
share->pack.header_length, 1, MYF(MY_WME))))
{
error= chk_data_link(&param, file, MY_TEST(param.testflag & T_EXTEND));
end_io_cache(&(param.read_cache));
error= chk_data_link(param, file, MY_TEST(param->testflag & T_EXTEND));
end_io_cache(&param->read_cache);
}
param.testflag= old_testflag;
param->testflag= old_testflag;
}
}
if (!error)
@ -932,7 +932,7 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
if ((share->state.changed & (STATE_CHANGED |
STATE_CRASHED_ON_REPAIR |
STATE_CRASHED | STATE_NOT_ANALYZED)) ||
(param.testflag & T_STATISTICS) ||
(param->testflag & T_STATISTICS) ||
mi_is_crashed(file))
{
file->update|=HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
@ -940,7 +940,7 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
share->state.changed&= ~(STATE_CHANGED | STATE_CRASHED |
STATE_CRASHED_ON_REPAIR);
if (!(table->db_stat & HA_READ_ONLY))
error=update_state_info(&param,file,UPDATE_TIME | UPDATE_OPEN_COUNT |
error=update_state_info(param,file,UPDATE_TIME | UPDATE_OPEN_COUNT |
UPDATE_STAT);
mysql_mutex_unlock(&share->intern_lock);
info(HA_STATUS_NO_LOCK | HA_STATUS_TIME | HA_STATUS_VARIABLE |
@ -967,30 +967,30 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
int ha_myisam::analyze(THD *thd, HA_CHECK_OPT* check_opt)
{
int error=0;
HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
HA_CHECK *param= (HA_CHECK*) thd->alloc(sizeof *param);
MYISAM_SHARE* share = file->s;
if (!&param)
if (!param)
return HA_ADMIN_INTERNAL_ERROR;
myisamchk_init(&param);
param.thd = thd;
param.op_name= "analyze";
param.db_name= table->s->db.str;
param.table_name= table->alias.c_ptr();
param.testflag= (T_FAST | T_CHECK | T_SILENT | T_STATISTICS |
myisamchk_init(param);
param->thd = thd;
param->op_name= "analyze";
param->db_name= table->s->db.str;
param->table_name= table->alias.c_ptr();
param->testflag= (T_FAST | T_CHECK | T_SILENT | T_STATISTICS |
T_DONT_CHECK_CHECKSUM);
param.using_global_keycache = 1;
param.stats_method= (enum_handler_stats_method)THDVAR(thd, stats_method);
param->using_global_keycache = 1;
param->stats_method= (enum_handler_stats_method)THDVAR(thd, stats_method);
if (!(share->state.changed & STATE_NOT_ANALYZED))
return HA_ADMIN_ALREADY_DONE;
error = chk_key(&param, file);
error = chk_key(param, file);
if (!error)
{
mysql_mutex_lock(&share->intern_lock);
error=update_state_info(&param,file,UPDATE_STAT);
error=update_state_info(param,file,UPDATE_STAT);
mysql_mutex_unlock(&share->intern_lock);
}
else if (!mi_is_crashed(file) && !thd->killed)
@ -1002,37 +1002,37 @@ int ha_myisam::analyze(THD *thd, HA_CHECK_OPT* check_opt)
int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt)
{
int error;
HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
HA_CHECK *param= (HA_CHECK*) thd->alloc(sizeof *param);
ha_rows start_records;
if (!file || !&param) return HA_ADMIN_INTERNAL_ERROR;
if (!file || !param) return HA_ADMIN_INTERNAL_ERROR;
myisamchk_init(&param);
param.thd = thd;
param.op_name= "repair";
param.testflag= ((check_opt->flags & ~(T_EXTEND)) |
myisamchk_init(param);
param->thd = thd;
param->op_name= "repair";
param->testflag= ((check_opt->flags & ~(T_EXTEND)) |
T_SILENT | T_FORCE_CREATE | T_CALC_CHECKSUM |
(check_opt->flags & T_EXTEND ? T_REP : T_REP_BY_SORT));
param.sort_buffer_length= THDVAR(thd, sort_buffer_size);
param.backup_time= check_opt->start_time;
param->sort_buffer_length= THDVAR(thd, sort_buffer_size);
param->backup_time= check_opt->start_time;
start_records=file->state->records;
while ((error=repair(thd,param,0)) && param.retry_repair)
while ((error=repair(thd,*param,0)) && param->retry_repair)
{
param.retry_repair=0;
if (test_all_bits(param.testflag,
param->retry_repair=0;
if (test_all_bits(param->testflag,
(uint) (T_RETRY_WITHOUT_QUICK | T_QUICK)))
{
param.testflag&= ~(T_RETRY_WITHOUT_QUICK | T_QUICK);
param->testflag&= ~(T_RETRY_WITHOUT_QUICK | T_QUICK);
/* Ensure we don't loose any rows when retrying without quick */
param.testflag|= T_SAFE_REPAIR;
param->testflag|= T_SAFE_REPAIR;
sql_print_information("Retrying repair of: '%s' including modifying data file",
table->s->path.str);
continue;
}
param.testflag&= ~T_QUICK;
if ((param.testflag & T_REP_BY_SORT))
param->testflag&= ~T_QUICK;
if ((param->testflag & T_REP_BY_SORT))
{
param.testflag= (param.testflag & ~T_REP_BY_SORT) | T_REP;
param->testflag= (param->testflag & ~T_REP_BY_SORT) | T_REP;
sql_print_information("Retrying repair of: '%s' with keycache",
table->s->path.str);
continue;
@ -1054,22 +1054,22 @@ int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt)
int ha_myisam::optimize(THD* thd, HA_CHECK_OPT *check_opt)
{
int error;
HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
HA_CHECK *param= (HA_CHECK*) thd->alloc(sizeof *param);
if (!file || !&param) return HA_ADMIN_INTERNAL_ERROR;
if (!file || !param) return HA_ADMIN_INTERNAL_ERROR;
myisamchk_init(&param);
param.thd = thd;
param.op_name= "optimize";
param.testflag= (check_opt->flags | T_SILENT | T_FORCE_CREATE |
myisamchk_init(param);
param->thd = thd;
param->op_name= "optimize";
param->testflag= (check_opt->flags | T_SILENT | T_FORCE_CREATE |
T_REP_BY_SORT | T_STATISTICS | T_SORT_INDEX);
param.sort_buffer_length= THDVAR(thd, sort_buffer_size);
if ((error= repair(thd,param,1)) && param.retry_repair)
param->sort_buffer_length= THDVAR(thd, sort_buffer_size);
if ((error= repair(thd,*param,1)) && param->retry_repair)
{
sql_print_warning("Warning: Optimize table got errno %d on %s.%s, retrying",
my_errno, param.db_name, param.table_name);
param.testflag&= ~T_REP_BY_SORT;
error= repair(thd,param,1);
my_errno, param->db_name, param->table_name);
param->testflag&= ~T_REP_BY_SORT;
error= repair(thd,*param,1);
}
return error;
}
@ -1274,17 +1274,17 @@ int ha_myisam::assign_to_keycache(THD* thd, HA_CHECK_OPT *check_opt)
if (error != HA_ADMIN_OK)
{
/* Send error to user */
HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
if (!&param)
HA_CHECK *param= (HA_CHECK*) thd->alloc(sizeof *param);
if (!param)
return HA_ADMIN_INTERNAL_ERROR;
myisamchk_init(&param);
param.thd= thd;
param.op_name= "assign_to_keycache";
param.db_name= table->s->db.str;
param.table_name= table->s->table_name.str;
param.testflag= 0;
mi_check_print_error(&param, errmsg);
myisamchk_init(param);
param->thd= thd;
param->op_name= "assign_to_keycache";
param->db_name= table->s->db.str;
param->table_name= table->s->table_name.str;
param->testflag= 0;
mi_check_print_error(param, errmsg);
}
DBUG_RETURN(error);
}
@ -1341,16 +1341,16 @@ int ha_myisam::preload_keys(THD* thd, HA_CHECK_OPT *check_opt)
err:
{
HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
if (!&param)
HA_CHECK *param= (HA_CHECK*) thd->alloc(sizeof *param);
if (!param)
return HA_ADMIN_INTERNAL_ERROR;
myisamchk_init(&param);
param.thd= thd;
param.op_name= "preload_keys";
param.db_name= table->s->db.str;
param.table_name= table->s->table_name.str;
param.testflag= 0;
mi_check_print_error(&param, errmsg);
myisamchk_init(param);
param->thd= thd;
param->op_name= "preload_keys";
param->db_name= table->s->db.str;
param->table_name= table->s->table_name.str;
param->testflag= 0;
mi_check_print_error(param, errmsg);
DBUG_RETURN(error);
}
}
@ -1455,45 +1455,45 @@ int ha_myisam::enable_indexes(uint mode)
{
THD *thd= table->in_use;
int was_error= thd->is_error();
HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
HA_CHECK *param= (HA_CHECK*) thd->alloc(sizeof *param);
const char *save_proc_info=thd->proc_info;
if (!&param)
if (!param)
DBUG_RETURN(HA_ADMIN_INTERNAL_ERROR);
thd_proc_info(thd, "Creating index");
myisamchk_init(&param);
param.op_name= "recreating_index";
param.testflag= (T_SILENT | T_REP_BY_SORT | T_QUICK |
myisamchk_init(param);
param->op_name= "recreating_index";
param->testflag= (T_SILENT | T_REP_BY_SORT | T_QUICK |
T_CREATE_MISSING_KEYS);
/*
Don't lock and unlock table if it's locked.
Normally table should be locked. This test is mostly for safety.
*/
if (likely(file->lock_type != F_UNLCK))
param.testflag|= T_NO_LOCKS;
if (file->create_unique_index_by_sort)
param.testflag|= T_CREATE_UNIQUE_BY_SORT;
param->testflag|= T_NO_LOCKS;
param.myf_rw&= ~MY_WAIT_IF_FULL;
param.sort_buffer_length= THDVAR(thd, sort_buffer_size);
param.stats_method= (enum_handler_stats_method)THDVAR(thd, stats_method);
param.tmpdir=&mysql_tmpdir_list;
if ((error= (repair(thd,param,0) != HA_ADMIN_OK)) && param.retry_repair)
if (file->create_unique_index_by_sort)
param->testflag|= T_CREATE_UNIQUE_BY_SORT;
param->myf_rw&= ~MY_WAIT_IF_FULL;
param->sort_buffer_length= THDVAR(thd, sort_buffer_size);
param->stats_method= (enum_handler_stats_method)THDVAR(thd, stats_method);
param->tmpdir=&mysql_tmpdir_list;
if ((error= (repair(thd,*param,0) != HA_ADMIN_OK)) && param->retry_repair)
{
sql_print_warning("Warning: Enabling keys got errno %d on %s.%s, retrying",
my_errno, param.db_name, param.table_name);
my_errno, param->db_name, param->table_name);
/*
Repairing by sort failed. Now try standard repair method.
Still we want to fix only index file. If data file corruption
was detected (T_RETRY_WITHOUT_QUICK), we shouldn't do much here.
Let implicit repair do this job.
*/
if (!(param.testflag & T_RETRY_WITHOUT_QUICK))
if (!(param->testflag & T_RETRY_WITHOUT_QUICK))
{
param.testflag&= ~T_REP_BY_SORT;
error= (repair(thd,param,0) != HA_ADMIN_OK);
param->testflag&= ~T_REP_BY_SORT;
error= (repair(thd,*param,0) != HA_ADMIN_OK);
}
/*
If the standard repair succeeded, clear all error messages which

View File

@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -299,20 +300,12 @@ void
recv_sys_var_init(void);
/*===================*/
#endif /* !UNIV_HOTBACKUP */
/*******************************************************************//**
Empties the hash table of stored log records, applying them to appropriate
pages. */
/** Apply the hash table of stored log records to persistent data pages.
@param[in] last_batch whether the change buffer merge will be
performed as part of the operation */
UNIV_INTERN
void
recv_apply_hashed_log_recs(
/*=======================*/
ibool allow_ibuf); /*!< in: if TRUE, also ibuf operations are
allowed during the application; if FALSE,
no ibuf operations are allowed, and after
the application all file pages are flushed to
disk and invalidated in buffer pool: this
alternative means that no new log records
can be generated during the application */
recv_apply_hashed_log_recs(bool last_batch);
#ifdef UNIV_HOTBACKUP
/*******************************************************************//**
Applies log records in the hash table to a backup. */
@ -438,6 +431,8 @@ struct recv_sys_t{
scan find a corrupt log block, or a corrupt
log record, or there is a log parsing
buffer overflow */
/** the time when progress was last reported */
ib_time_t progress_time;
#ifdef UNIV_LOG_ARCHIVE
log_group_t* archive_group;
/*!< in archive recovery: the log group whose
@ -450,6 +445,20 @@ struct recv_sys_t{
addresses in the hash table */
recv_dblwr_t dblwr;
/** Determine whether redo log recovery progress should be reported.
@param[in] time the current time
@return whether progress should be reported
(the last report was at least 15 seconds ago) */
bool report(ib_time_t time)
{
if (time - progress_time < 15) {
return false;
}
progress_time = time;
return true;
}
};
/** The recovery system */

View File

@ -2,7 +2,7 @@
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2009, Google Inc.
Copyright (c) 2017, MariaDB Corporation. All Rights Reserved.
Copyright (c) 2017, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@ -1858,7 +1858,7 @@ log_preflush_pool_modified_pages(
and we could not make a new checkpoint on the basis of the
info on the buffer pool only. */
recv_apply_hashed_log_recs(TRUE);
recv_apply_hashed_log_recs(true);
}
if (!buf_page_cleaner_is_active
@ -2229,7 +2229,7 @@ log_checkpoint(
ut_ad(!srv_read_only_mode);
if (recv_recovery_is_on()) {
recv_apply_hashed_log_recs(TRUE);
recv_apply_hashed_log_recs(true);
}
if (srv_unix_file_flush_method != SRV_UNIX_NOSYNC &&
@ -2568,6 +2568,11 @@ loop:
start_lsn += len;
buf += len;
if (recv_sys->report(ut_time())) {
ib_logf(IB_LOG_LEVEL_INFO, "Read redo log up to LSN=" LSN_PF,
start_lsn);
}
if (start_lsn != end_lsn) {
if (release_mutex) {

View File

@ -2,7 +2,7 @@
Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
Copyright (c) 2017, MariaDB Corporation. All Rights Reserved.
Copyright (c) 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -80,7 +80,7 @@ this must be less than UNIV_PAGE_SIZE as it is stored in the buffer pool */
#define RECV_READ_AHEAD_AREA 32
/** The recovery system */
UNIV_INTERN recv_sys_t* recv_sys = NULL;
UNIV_INTERN recv_sys_t* recv_sys;
/** TRUE when applying redo log records during crash recovery; FALSE
otherwise. Note that this is FALSE while a background thread is
rolling back incomplete transactions. */
@ -132,9 +132,6 @@ UNIV_INTERN ibool recv_is_making_a_backup = FALSE;
UNIV_INTERN ibool recv_is_from_backup = FALSE;
# define buf_pool_get_curr_size() (5 * 1024 * 1024)
#endif /* !UNIV_HOTBACKUP */
/** The following counter is used to decide when to print info on
log scan */
static ulint recv_scan_print_counter;
/** The type of the previous parsed redo log record */
static ulint recv_previous_parsed_rec_type;
@ -305,8 +302,6 @@ recv_sys_var_init(void)
recv_no_ibuf_operations = FALSE;
recv_scan_print_counter = 0;
recv_previous_parsed_rec_type = 999999;
recv_previous_parsed_rec_offset = 0;
@ -417,6 +412,7 @@ recv_sys_init(
recv_sys->last_block_buf_start, OS_FILE_LOG_BLOCK_SIZE));
recv_sys->found_corrupt_log = FALSE;
recv_sys->progress_time = ut_time();
recv_max_page_lsn = 0;
@ -1675,6 +1671,7 @@ recv_recover_page_func(
ibool success;
#endif /* !UNIV_HOTBACKUP */
mtr_t mtr;
ib_time_t time;
mutex_enter(&(recv_sys->mutex));
@ -1852,6 +1849,8 @@ recv_recover_page_func(
mtr_commit(&mtr);
time = ut_time();
mutex_enter(&(recv_sys->mutex));
if (recv_max_page_lsn < page_lsn) {
@ -1860,11 +1859,16 @@ recv_recover_page_func(
recv_addr->state = RECV_PROCESSED;
ut_a(recv_sys->n_addrs);
recv_sys->n_addrs--;
mutex_exit(&(recv_sys->mutex));
ut_a(recv_sys->n_addrs > 0);
if (--recv_sys->n_addrs && recv_sys->progress_time - time >= 15) {
recv_sys->progress_time = time;
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: To recover: " ULINTPF " pages from log\n",
recv_sys->n_addrs);
}
mutex_exit(&recv_sys->mutex);
}
#ifndef UNIV_HOTBACKUP
@ -1910,59 +1914,48 @@ recv_read_in_area(
}
buf_read_recv_pages(FALSE, space, zip_size, page_nos, n);
/*
fprintf(stderr, "Recv pages at %lu n %lu\n", page_nos[0], n);
*/
return(n);
}
/*******************************************************************//**
Empties the hash table of stored log records, applying them to appropriate
pages. */
/** Apply the hash table of stored log records to persistent data pages.
@param[in] last_batch whether the change buffer merge will be
performed as part of the operation */
UNIV_INTERN
void
recv_apply_hashed_log_recs(
/*=======================*/
ibool allow_ibuf) /*!< in: if TRUE, also ibuf operations are
allowed during the application; if FALSE,
no ibuf operations are allowed, and after
the application all file pages are flushed to
disk and invalidated in buffer pool: this
alternative means that no new log records
can be generated during the application;
the caller must in this case own the log
mutex */
recv_apply_hashed_log_recs(bool last_batch)
{
recv_addr_t* recv_addr;
ulint i;
ibool has_printed = FALSE;
mtr_t mtr;
loop:
mutex_enter(&(recv_sys->mutex));
for (;;) {
mutex_enter(&recv_sys->mutex);
if (recv_sys->apply_batch_on) {
mutex_exit(&(recv_sys->mutex));
if (!recv_sys->apply_batch_on) {
break;
}
mutex_exit(&recv_sys->mutex);
os_thread_sleep(500000);
goto loop;
}
ut_ad((allow_ibuf == 0) == (mutex_own(&log_sys->mutex) != 0));
ut_ad(!last_batch == mutex_own(&log_sys->mutex));
if (!allow_ibuf) {
if (!last_batch) {
recv_no_ibuf_operations = TRUE;
}
if (ulint n = recv_sys->n_addrs) {
const char* msg = last_batch
? "Starting final batch to recover "
: "Starting a batch to recover ";
ib_logf(IB_LOG_LEVEL_INFO,
"%s" ULINTPF " pages from redo log", msg, n);
}
recv_sys->apply_log_recs = TRUE;
recv_sys->apply_batch_on = TRUE;
for (i = 0; i < hash_get_n_cells(recv_sys->addr_hash); i++) {
for (recv_addr = static_cast<recv_addr_t*>(
HASH_GET_FIRST(recv_sys->addr_hash, i));
recv_addr != 0;
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))) {
@ -1971,24 +1964,12 @@ loop:
ulint page_no = recv_addr->page_no;
if (recv_addr->state == RECV_NOT_PROCESSED) {
if (!has_printed) {
ib_logf(IB_LOG_LEVEL_INFO,
"Starting an apply batch"
" of log records"
" to the database...");
fputs("InnoDB: Progress in percent: ",
stderr);
has_printed = TRUE;
}
mutex_exit(&(recv_sys->mutex));
mutex_exit(&recv_sys->mutex);
if (buf_page_peek(space, page_no)) {
buf_block_t* block;
mtr_t mtr;
mtr_start(&mtr);
block = buf_page_get(
buf_block_t* block = buf_page_get(
space, zip_size, page_no,
RW_X_LATCH, &mtr);
buf_block_dbg_add_level(
@ -2001,19 +1982,9 @@ loop:
page_no);
}
mutex_enter(&(recv_sys->mutex));
mutex_enter(&recv_sys->mutex);
}
}
if (has_printed
&& (i * 100) / hash_get_n_cells(recv_sys->addr_hash)
!= ((i + 1) * 100)
/ hash_get_n_cells(recv_sys->addr_hash)) {
fprintf(stderr, "%lu ", (ulong)
((i * 100)
/ hash_get_n_cells(recv_sys->addr_hash)));
}
}
/* Wait until all the pages have been processed */
@ -2027,12 +1998,7 @@ loop:
mutex_enter(&(recv_sys->mutex));
}
if (has_printed) {
fprintf(stderr, "\n");
}
if (!allow_ibuf) {
if (!last_batch) {
bool success;
/* Flush all the file pages to disk and invalidate them in
@ -2072,11 +2038,7 @@ loop:
recv_sys_empty_hash();
if (has_printed) {
fprintf(stderr, "InnoDB: Apply batch completed\n");
}
mutex_exit(&(recv_sys->mutex));
mutex_exit(&recv_sys->mutex);
}
#else /* !UNIV_HOTBACKUP */
/*******************************************************************//**
@ -2099,11 +2061,6 @@ recv_apply_log_recs_for_backup(void)
block = back_block1;
ib_logf(IB_LOG_LEVEL_INFO,
"Starting an apply batch of log records to the database...");
fputs("InnoDB: Progress in percent: ", stderr);
n_hash_cells = hash_get_n_cells(recv_sys->addr_hash);
for (i = 0; i < n_hash_cells; i++) {
@ -2215,13 +2172,6 @@ recv_apply_log_recs_for_backup(void)
skip_this_recv_addr:
recv_addr = HASH_GET_NEXT(addr_hash, recv_addr);
}
if ((100 * i) / n_hash_cells
!= (100 * (i + 1)) / n_hash_cells) {
fprintf(stderr, "%lu ",
(ulong) ((100 * i) / n_hash_cells));
fflush(stderr);
}
}
recv_sys_empty_hash();
@ -2885,11 +2835,10 @@ recv_scan_log_recs(
#ifndef UNIV_HOTBACKUP
if (recv_log_scan_is_startup_type
&& !recv_needed_recovery) {
if (!srv_read_only_mode) {
ib_logf(IB_LOG_LEVEL_INFO,
"Log scan progressed past the "
"checkpoint lsn " LSN_PF "",
"Starting crash recovery from "
"checkpoint LSN=" LSN_PF,
recv_sys->scanned_lsn);
recv_init_crash_recovery();
@ -2948,19 +2897,6 @@ recv_scan_log_recs(
*group_scanned_lsn = scanned_lsn;
if (recv_needed_recovery
|| (recv_is_from_backup && !recv_is_making_a_backup)) {
recv_scan_print_counter++;
if (finished || (recv_scan_print_counter % 80 == 0)) {
fprintf(stderr,
"InnoDB: Doing recovery: scanned up to"
" log sequence number " LSN_PF "\n",
*group_scanned_lsn);
}
}
if (more_data && !recv_sys->found_corrupt_log) {
/* Try to parse more log records */
@ -2976,7 +2912,7 @@ recv_scan_log_recs(
log yet: they would be produced by ibuf
operations */
recv_apply_hashed_log_recs(FALSE);
recv_apply_hashed_log_recs(false);
}
#endif /* !UNIV_HOTBACKUP */
@ -3052,11 +2988,6 @@ recv_init_crash_recovery(void)
recv_needed_recovery = TRUE;
ib_logf(IB_LOG_LEVEL_INFO, "Database was not shutdown normally!");
ib_logf(IB_LOG_LEVEL_INFO, "Starting crash recovery.");
ib_logf(IB_LOG_LEVEL_INFO,
"Reading tablespace information from the .ibd files...");
fil_load_single_table_tablespaces();
/* If we are using the doublewrite method, we will
@ -3067,9 +2998,7 @@ recv_init_crash_recovery(void)
if (srv_force_recovery < SRV_FORCE_NO_LOG_REDO) {
ib_logf(IB_LOG_LEVEL_INFO,
"Restoring possible half-written data pages ");
ib_logf(IB_LOG_LEVEL_INFO,
"Restoring possible half-written data pages "
"from the doublewrite buffer...");
buf_dblwr_process();

View File

@ -2588,7 +2588,7 @@ files_checked:
}
}
/* This must precede recv_apply_hashed_log_recs(TRUE). */
/* This must precede recv_apply_hashed_log_recs(true). */
ib_bh = trx_sys_init_at_db_start();
if (srv_force_recovery < SRV_FORCE_NO_LOG_REDO) {
@ -2596,7 +2596,7 @@ files_checked:
respective file pages, for the last batch of
recv_group_scan_log_recs(). */
recv_apply_hashed_log_recs(TRUE);
recv_apply_hashed_log_recs(true);
DBUG_PRINT("ib_log", ("apply completed"));
}