mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 02:05:57 +01:00
MDEV-25975 innodb_disallow_writes causes shutdown to hang
We will remove the parameter innodb_disallow_writes because it is badly designed and implemented. The parameter was never allowed at startup. It was only internally used by Galera snapshot transfer. If a user executed SET GLOBAL innodb_disallow_writes=ON; the server could hang even on subsequent read operations. During Galera snapshot transfer, we will block writes to implement an rsync friendly snapshot, as follows: sst_flush_tables() will acquire a global lock by executing FLUSH TABLES WITH READ LOCK, which will block any writes at the high level. sst_disable_innodb_writes(), invoked via ha_disable_internal_writes(true), will suspend or disable InnoDB background tasks or threads that could initiate writes. As part of this, log_make_checkpoint() will be invoked to ensure that anything in the InnoDB buf_pool.flush_list will be written to the data files. This has the nice side effect that the Galera joiner will avoid crash recovery. The changes to sql/wsrep.cc and to the tests are based on a prototype that was developed by Jan Lindström. Reviewed by: Jan Lindström
This commit is contained in:
parent
7c584d8270
commit
e9735a8185
30 changed files with 230 additions and 399 deletions
|
@ -4372,11 +4372,6 @@ fail:
|
|||
crc_init();
|
||||
recv_sys_init();
|
||||
|
||||
#ifdef WITH_INNODB_DISALLOW_WRITES
|
||||
srv_allow_writes_event = os_event_create(0);
|
||||
os_event_set(srv_allow_writes_event);
|
||||
#endif
|
||||
|
||||
xb_filters_init();
|
||||
|
||||
xb_fil_io_init();
|
||||
|
@ -5837,10 +5832,6 @@ static bool xtrabackup_prepare_func(char** argv)
|
|||
log_sys.create();
|
||||
recv_recovery_on = true;
|
||||
|
||||
#ifdef WITH_INNODB_DISALLOW_WRITES
|
||||
srv_allow_writes_event = os_event_create(0);
|
||||
os_event_set(srv_allow_writes_event);
|
||||
#endif
|
||||
dberr_t err = xb_data_files_init();
|
||||
if (err != DB_SUCCESS) {
|
||||
msg("mariabackup: error: xb_data_files_init() failed "
|
||||
|
@ -5862,9 +5853,6 @@ static bool xtrabackup_prepare_func(char** argv)
|
|||
xb_filter_hash_free(inc_dir_tables_hash);
|
||||
|
||||
fil_system.close();
|
||||
#ifdef WITH_INNODB_DISALLOW_WRITES
|
||||
os_event_destroy(srv_allow_writes_event);
|
||||
#endif
|
||||
innodb_free_param();
|
||||
log_sys.close();
|
||||
sync_check_close();
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
--source include/have_innodb.inc
|
||||
|
||||
if (`SELECT COUNT(*) = 0 from INFORMATION_SCHEMA.GLOBAL_VARIABLES
|
||||
WHERE VARIABLE_NAME = 'INNODB_DISALLOW_WRITES'`) {
|
||||
--skip Test requires 'innodb_disallow_writes'
|
||||
}
|
11
mysql-test/suite/galera/r/galera_bf_abort_shutdown.result
Normal file
11
mysql-test/suite/galera/r/galera_bf_abort_shutdown.result
Normal file
|
@ -0,0 +1,11 @@
|
|||
connection node_1;
|
||||
connection node_2;
|
||||
connection node_1;
|
||||
CREATE TABLE t1 (f1 INT PRIMARY KEY);
|
||||
connection node_2;
|
||||
call mtr.add_suppression("WSREP: Failed to scan the last segment to the end. Last events may be missing. Last recovered event:.*");
|
||||
SET DEBUG_SYNC = 'wsrep_before_certification WAIT_FOR continue';
|
||||
INSERT INTO t1 VALUES (1);
|
||||
connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2;
|
||||
connection node_1;
|
||||
DROP TABLE t1;
|
|
@ -46,3 +46,6 @@ SHOW TABLES;
|
|||
Tables_in_fts
|
||||
DROP DATABASE fts;
|
||||
connection node_2;
|
||||
call mtr.add_suppression("WSREP: Failed to scan the last segment to the end. Last events may be missing. Last recovered event:");
|
||||
Warnings:
|
||||
Note 1049 Unknown database 'fts'
|
||||
|
|
|
@ -109,6 +109,7 @@ f1 f2
|
|||
SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_NAME='one_event';
|
||||
EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER EVENT_BODY EVENT_DEFINITION EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD STATUS ON_COMPLETION EVENT_COMMENT
|
||||
def test one_event root@localhost SQL SELECT 123 RECURRING NULL 10 SECOND SLAVESIDE_DISABLED NOT PRESERVE
|
||||
call mtr.add_suppression("WSREP: Failed to scan the last segment to the end. Last events may be missing. Last recovered event:.*");
|
||||
connection node_1;
|
||||
SELECT * FROM t1;
|
||||
f1 f2
|
||||
|
|
|
@ -39,6 +39,7 @@ f1 f2
|
|||
connection node_2;
|
||||
Starting server ...
|
||||
Starting server ...
|
||||
call mtr.add_suppression("WSREP: Failed to scan the last segment to the end. Last events may be missing. Last recovered event:");
|
||||
SELECT * FROM t1;
|
||||
f1 f2
|
||||
1 a
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
connection node_1a;
|
||||
SET SESSION wsrep_sync_wait = 0;
|
||||
connection node_1;
|
||||
CREATE TABLE t1 (f1 INTEGER, f2 varchar(1024)) Engine=InnoDB;
|
||||
CREATE TABLE ten (f1 INTEGER) ENGINE=InnoDB;
|
||||
INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
|
||||
SET GLOBAL innodb_disallow_writes=ON;
|
||||
INSERT INTO t1 (f2) SELECT 'abcde ' FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4;;
|
||||
connection node_2;
|
||||
INSERT INTO t1 (f2) SELECT 'fghij ' FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4;
|
||||
SELECT COUNT(*) AS EXPECT_10000 FROM t1;
|
||||
EXPECT_10000
|
||||
10000
|
||||
connection node_1a;
|
||||
SET GLOBAL innodb_disallow_writes=OFF;
|
||||
connection node_1;
|
||||
SELECT COUNT(*) AS EXPECT_20000 FROM t1;
|
||||
EXPECT_20000
|
||||
20000
|
||||
connection node_2;
|
||||
SELECT COUNT(*) AS EXPECT_20000 FROM t1;
|
||||
EXPECT_20000
|
||||
20000
|
||||
connection node_1;
|
||||
connection node_2;
|
||||
DROP TABLE t1;
|
||||
DROP TABLE ten;
|
||||
disconnect node_1a;
|
34
mysql-test/suite/galera/t/galera_bf_abort_shutdown.test
Normal file
34
mysql-test/suite/galera/t/galera_bf_abort_shutdown.test
Normal file
|
@ -0,0 +1,34 @@
|
|||
#
|
||||
# This test verifies that the server can be shut down even if
|
||||
# some of the wsrep transactions are in QUERY_COMMITTING state.
|
||||
# In this case the shutdown sequence may do a BF abort for the
|
||||
# connection.
|
||||
#
|
||||
|
||||
--source include/have_innodb.inc
|
||||
--source include/galera_cluster.inc
|
||||
--source include/have_debug_sync.inc
|
||||
|
||||
# Save original auto_increment_offset values.
|
||||
--let $node_1=node_1
|
||||
--let $node_2=node_2
|
||||
--source include/auto_increment_offset_save.inc
|
||||
|
||||
--connection node_1
|
||||
CREATE TABLE t1 (f1 INT PRIMARY KEY);
|
||||
|
||||
--connection node_2
|
||||
call mtr.add_suppression("WSREP: Failed to scan the last segment to the end. Last events may be missing. Last recovered event:.*");
|
||||
SET DEBUG_SYNC = 'wsrep_before_certification WAIT_FOR continue';
|
||||
--send INSERT INTO t1 VALUES (1)
|
||||
|
||||
--connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2
|
||||
--source include/restart_mysqld.inc
|
||||
|
||||
# Restore original auto_increment_offset values.
|
||||
--let $node_2=node_2a
|
||||
--source include/auto_increment_offset_restore.inc
|
||||
|
||||
--connection node_1
|
||||
|
||||
DROP TABLE t1;
|
|
@ -56,6 +56,7 @@ SHOW TABLES;
|
|||
DROP DATABASE fts;
|
||||
|
||||
--connection node_2
|
||||
call mtr.add_suppression("WSREP: Failed to scan the last segment to the end. Last events may be missing. Last recovered event:");
|
||||
--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'fts_t1';
|
||||
--source include/wait_condition.inc
|
||||
--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'fts_t2';
|
||||
|
|
|
@ -137,6 +137,8 @@ SELECT * FROM t1;
|
|||
--echo # node_2 Event should be SERVERSIDE_DISABLED
|
||||
SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_NAME='one_event';
|
||||
|
||||
call mtr.add_suppression("WSREP: Failed to scan the last segment to the end. Last events may be missing. Last recovered event:.*");
|
||||
|
||||
--connection node_1
|
||||
SELECT * FROM t1;
|
||||
--echo # node_1 Event should be ENABLED
|
||||
|
|
|
@ -125,6 +125,7 @@ SELECT * FROM t1;
|
|||
|
||||
# Sanity check (node 2 is running now and can perform SQL operators):
|
||||
|
||||
call mtr.add_suppression("WSREP: Failed to scan the last segment to the end. Last events may be missing. Last recovered event:");
|
||||
SELECT * FROM t1;
|
||||
|
||||
--connection node_1
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
#
|
||||
# This test checks that innodb_disallow_writes works as expected
|
||||
#
|
||||
# Note that we need to enable binlog for this test: If the commit
|
||||
# to InnoDB is done in one phase, the transaction is committed in
|
||||
# memory before it is persisted to disk. This means that the
|
||||
# innodb_disallow_writes=ON may not prevent transaction to
|
||||
# become visible to other readers. On the other hand, if the
|
||||
# commit is two phase (as it is with binlog), the transaction
|
||||
# will be blocked in prepare phase.
|
||||
#
|
||||
|
||||
--source include/galera_cluster.inc
|
||||
--source include/have_innodb.inc
|
||||
|
||||
--let $datadir= `SELECT @@datadir`
|
||||
|
||||
|
||||
# Open a separate connection to be used to run SHOW PROCESSLIST
|
||||
--let $galera_connection_name = node_1a
|
||||
--let $galera_server_number = 1
|
||||
--source include/galera_connect.inc
|
||||
--connection node_1a
|
||||
SET SESSION wsrep_sync_wait = 0;
|
||||
|
||||
--connection node_1
|
||||
CREATE TABLE t1 (f1 INTEGER, f2 varchar(1024)) Engine=InnoDB;
|
||||
CREATE TABLE ten (f1 INTEGER) ENGINE=InnoDB;
|
||||
INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
|
||||
|
||||
SET GLOBAL innodb_disallow_writes=ON;
|
||||
--exec find $datadir -type f-exec md5sum {} \; | md5sum >$MYSQLTEST_VARDIR/tmp/innodb_before
|
||||
|
||||
#
|
||||
# This insert has no effect before innodb_disallow_writes is OFF
|
||||
#
|
||||
--send INSERT INTO t1 (f2) SELECT 'abcde ' FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4;
|
||||
|
||||
--connection node_2
|
||||
INSERT INTO t1 (f2) SELECT 'fghij ' FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4;
|
||||
SELECT COUNT(*) AS EXPECT_10000 FROM t1;
|
||||
|
||||
--connection node_1a
|
||||
--sleep 5
|
||||
|
||||
--exec find $datadir -type f-exec md5sum {} \; | md5sum >$MYSQLTEST_VARDIR/tmp/innodb_after
|
||||
|
||||
SET GLOBAL innodb_disallow_writes=OFF;
|
||||
|
||||
--connection node_1
|
||||
--reap
|
||||
--let $wait_condition = SELECT COUNT(*) = 20000 FROM t1;
|
||||
--source include/wait_condition.inc
|
||||
|
||||
SELECT COUNT(*) AS EXPECT_20000 FROM t1;
|
||||
|
||||
--connection node_2
|
||||
--let $wait_condition = SELECT COUNT(*) = 20000 FROM t1;
|
||||
--source include/wait_condition.inc
|
||||
SELECT COUNT(*) AS EXPECT_20000 FROM t1;
|
||||
|
||||
--connection node_1
|
||||
--diff_files $MYSQLTEST_VARDIR/tmp/innodb_before $MYSQLTEST_VARDIR/tmp/innodb_after
|
||||
|
||||
--connection node_2
|
||||
|
||||
DROP TABLE t1;
|
||||
DROP TABLE ten;
|
||||
|
||||
--disconnect node_1a
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
#
|
||||
# innodb_disallow_writes
|
||||
#
|
||||
# save the initial value
|
||||
SET @innodb_disallow_writes_global_saved = @@global.innodb_disallow_writes;
|
||||
# default
|
||||
SELECT @@global.innodb_disallow_writes;
|
||||
@@global.innodb_disallow_writes
|
||||
0
|
||||
|
||||
# scope
|
||||
SELECT @@session.innodb_disallow_writes;
|
||||
ERROR HY000: Variable 'innodb_disallow_writes' is a GLOBAL variable
|
||||
SET @@global.innodb_disallow_writes=OFF;
|
||||
SELECT @@global.innodb_disallow_writes;
|
||||
@@global.innodb_disallow_writes
|
||||
0
|
||||
SET @@global.innodb_disallow_writes=ON;
|
||||
SELECT @@global.innodb_disallow_writes;
|
||||
@@global.innodb_disallow_writes
|
||||
1
|
||||
|
||||
# valid values
|
||||
SET @@global.innodb_disallow_writes='OFF';
|
||||
SELECT @@global.innodb_disallow_writes;
|
||||
@@global.innodb_disallow_writes
|
||||
0
|
||||
SET @@global.innodb_disallow_writes=ON;
|
||||
SELECT @@global.innodb_disallow_writes;
|
||||
@@global.innodb_disallow_writes
|
||||
1
|
||||
SET @@global.innodb_disallow_writes=default;
|
||||
SELECT @@global.innodb_disallow_writes;
|
||||
@@global.innodb_disallow_writes
|
||||
0
|
||||
|
||||
# invalid values
|
||||
SET @@global.innodb_disallow_writes=NULL;
|
||||
ERROR 42000: Variable 'innodb_disallow_writes' can't be set to the value of 'NULL'
|
||||
SET @@global.innodb_disallow_writes='junk';
|
||||
ERROR 42000: Variable 'innodb_disallow_writes' can't be set to the value of 'junk'
|
||||
|
||||
# restore the initial value
|
||||
SET @@global.innodb_disallow_writes = @innodb_disallow_writes_global_saved;
|
||||
# End of test
|
|
@ -2,9 +2,7 @@ select VARIABLE_NAME, SESSION_VALUE, DEFAULT_VALUE, VARIABLE_SCOPE, VARIABLE_TYP
|
|||
where variable_name like 'innodb%' and
|
||||
variable_name not in (
|
||||
'innodb_version', # always the same as the server version
|
||||
'innodb_disallow_writes', # only available WITH_WSREP
|
||||
'innodb_numa_interleave', # only available WITH_NUMA
|
||||
'innodb_sched_priority_cleaner', # linux only
|
||||
'innodb_evict_tables_on_commit_debug', # one may want to override this
|
||||
'innodb_use_native_aio', # default value depends on OS
|
||||
'innodb_buffer_pool_load_pages_abort') # debug build only, and is only for testing
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
--source include/have_innodb_disallow_writes.inc
|
||||
|
||||
--echo #
|
||||
--echo # innodb_disallow_writes
|
||||
--echo #
|
||||
|
||||
--echo # save the initial value
|
||||
SET @innodb_disallow_writes_global_saved = @@global.innodb_disallow_writes;
|
||||
|
||||
--echo # default
|
||||
SELECT @@global.innodb_disallow_writes;
|
||||
|
||||
--echo
|
||||
--echo # scope
|
||||
--error ER_INCORRECT_GLOBAL_LOCAL_VAR
|
||||
SELECT @@session.innodb_disallow_writes;
|
||||
SET @@global.innodb_disallow_writes=OFF;
|
||||
SELECT @@global.innodb_disallow_writes;
|
||||
SET @@global.innodb_disallow_writes=ON;
|
||||
SELECT @@global.innodb_disallow_writes;
|
||||
|
||||
--echo
|
||||
--echo # valid values
|
||||
SET @@global.innodb_disallow_writes='OFF';
|
||||
SELECT @@global.innodb_disallow_writes;
|
||||
SET @@global.innodb_disallow_writes=ON;
|
||||
SELECT @@global.innodb_disallow_writes;
|
||||
SET @@global.innodb_disallow_writes=default;
|
||||
SELECT @@global.innodb_disallow_writes;
|
||||
|
||||
--echo
|
||||
--echo # invalid values
|
||||
--error ER_WRONG_VALUE_FOR_VAR
|
||||
SET @@global.innodb_disallow_writes=NULL;
|
||||
--error ER_WRONG_VALUE_FOR_VAR
|
||||
SET @@global.innodb_disallow_writes='junk';
|
||||
|
||||
--echo
|
||||
--echo # restore the initial value
|
||||
SET @@global.innodb_disallow_writes = @innodb_disallow_writes_global_saved;
|
||||
|
||||
--echo # End of test
|
|
@ -9,9 +9,7 @@ select VARIABLE_NAME, SESSION_VALUE, DEFAULT_VALUE, VARIABLE_SCOPE, VARIABLE_TYP
|
|||
where variable_name like 'innodb%' and
|
||||
variable_name not in (
|
||||
'innodb_version', # always the same as the server version
|
||||
'innodb_disallow_writes', # only available WITH_WSREP
|
||||
'innodb_numa_interleave', # only available WITH_NUMA
|
||||
'innodb_sched_priority_cleaner', # linux only
|
||||
'innodb_evict_tables_on_commit_debug', # one may want to override this
|
||||
'innodb_use_native_aio', # default value depends on OS
|
||||
'innodb_buffer_pool_load_pages_abort') # debug build only, and is only for testing
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
set -ue
|
||||
|
||||
# Copyright (C) 2017-2022 MariaDB
|
||||
# Copyright (C) 2010-2014 Codership Oy
|
||||
# Copyright (C) 2010-2022 Codership Oy
|
||||
#
|
||||
# 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
|
||||
|
@ -416,6 +416,8 @@ EOF
|
|||
|
||||
sync
|
||||
|
||||
wsrep_log_info "Tables flushed"
|
||||
|
||||
if [ -n "$WSREP_SST_OPT_BINLOG" ]; then
|
||||
# Change the directory to binlog base (if possible):
|
||||
cd "$DATA"
|
||||
|
@ -557,6 +559,8 @@ FILTER="-f '- /lost+found'
|
|||
exit $RC
|
||||
fi
|
||||
|
||||
wsrep_log_info "Transfer of normal directories done"
|
||||
|
||||
# Transfer InnoDB data files
|
||||
rsync ${STUNNEL:+--rsh="$STUNNEL"} \
|
||||
--owner --group --perms --links --specials \
|
||||
|
@ -570,6 +574,8 @@ FILTER="-f '- /lost+found'
|
|||
exit 255 # unknown error
|
||||
fi
|
||||
|
||||
wsrep_log_info "Transfer of InnoDB data files done"
|
||||
|
||||
# second, we transfer InnoDB and Aria log files
|
||||
rsync ${STUNNEL:+--rsh="$STUNNEL"} \
|
||||
--owner --group --perms --links --specials \
|
||||
|
@ -583,6 +589,8 @@ FILTER="-f '- /lost+found'
|
|||
exit 255 # unknown error
|
||||
fi
|
||||
|
||||
wsrep_log_info "Transfer of InnoDB and Aria log files done"
|
||||
|
||||
# then, we parallelize the transfer of database directories,
|
||||
# use '.' so that path concatenation works:
|
||||
|
||||
|
@ -610,6 +618,9 @@ FILTER="-f '- /lost+found'
|
|||
exit 255 # unknown error
|
||||
fi
|
||||
|
||||
wsrep_log_info "Transfer of data done"
|
||||
|
||||
|
||||
else # BYPASS
|
||||
|
||||
wsrep_log_info "Bypassing state dump."
|
||||
|
@ -620,6 +631,7 @@ FILTER="-f '- /lost+found'
|
|||
|
||||
fi
|
||||
|
||||
wsrep_log_info "Sending continue to donor"
|
||||
echo 'continue' # now server can resume updating data
|
||||
|
||||
echo "$STATE" > "$MAGIC_FILE"
|
||||
|
|
|
@ -849,6 +849,22 @@ void ha_kill_query(THD* thd, enum thd_kill_levels level)
|
|||
}
|
||||
|
||||
|
||||
static my_bool plugin_disable_internal_writes(THD *, plugin_ref plugin,
|
||||
void *disable)
|
||||
{
|
||||
if (void(*diw)(bool)= plugin_hton(plugin)->disable_internal_writes)
|
||||
diw(*static_cast<bool*>(disable));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
void ha_disable_internal_writes(bool disable)
|
||||
{
|
||||
plugin_foreach(NULL, plugin_disable_internal_writes,
|
||||
MYSQL_STORAGE_ENGINE_PLUGIN, &disable);
|
||||
}
|
||||
|
||||
|
||||
/* ========================================================================
|
||||
======================= TRANSACTIONS ===================================*/
|
||||
|
||||
|
|
|
@ -1537,6 +1537,9 @@ struct handlerton
|
|||
@return transaction commit ID
|
||||
@retval 0 if no system-versioned data was affected by the transaction */
|
||||
ulonglong (*prepare_commit_versioned)(THD *thd, ulonglong *trx_id);
|
||||
|
||||
/** Disable or enable the internal writes of a storage engine */
|
||||
void (*disable_internal_writes)(bool disable);
|
||||
};
|
||||
|
||||
|
||||
|
@ -4713,6 +4716,8 @@ int ha_create_table(THD *thd, const char *path,
|
|||
int ha_delete_table(THD *thd, handlerton *db_type, const char *path,
|
||||
const LEX_CSTRING *db, const LEX_CSTRING *alias, bool generate_warning);
|
||||
|
||||
void ha_disable_internal_writes(bool disable);
|
||||
|
||||
/* statistics and info */
|
||||
bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat);
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* Copyright 2008-2022 Codership Oy <http://www.codership.com>
|
||||
Copyright (c) 2008, 2022, 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
|
||||
|
@ -1403,47 +1404,18 @@ static int run_sql_command(THD *thd, const char *query)
|
|||
}
|
||||
|
||||
mysql_parse(thd, thd->query(), thd->query_length(), &ps, FALSE, FALSE);
|
||||
|
||||
if (thd->is_error())
|
||||
{
|
||||
int const err= thd->get_stmt_da()->sql_errno();
|
||||
WSREP_WARN ("Error executing '%s': %d (%s)%s",
|
||||
query, err, thd->get_stmt_da()->message(),
|
||||
err == ER_UNKNOWN_SYSTEM_VARIABLE ?
|
||||
". Was mysqld built with --with-innodb-disallow-writes ?" : "");
|
||||
WSREP_WARN ("Error executing '%s': %d (%s)",
|
||||
query, err, thd->get_stmt_da()->message());
|
||||
thd->clear_error();
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sst_disallow_writes (THD* thd, bool yes)
|
||||
{
|
||||
char query_str[64]= { 0, };
|
||||
ssize_t const query_max= sizeof(query_str) - 1;
|
||||
CHARSET_INFO *current_charset;
|
||||
|
||||
current_charset= thd->variables.character_set_client;
|
||||
|
||||
if (!is_supported_parser_charset(current_charset))
|
||||
{
|
||||
/* Do not use non-supported parser character sets */
|
||||
WSREP_WARN("Current client character set is non-supported parser character set: %s", current_charset->csname);
|
||||
thd->variables.character_set_client= &my_charset_latin1;
|
||||
WSREP_WARN("For SST temporally setting character set to : %s",
|
||||
my_charset_latin1.csname);
|
||||
}
|
||||
|
||||
snprintf (query_str, query_max, "SET GLOBAL innodb_disallow_writes=%d",
|
||||
yes ? 1 : 0);
|
||||
|
||||
if (run_sql_command(thd, query_str))
|
||||
{
|
||||
WSREP_ERROR("Failed to disallow InnoDB writes");
|
||||
}
|
||||
thd->variables.character_set_client= current_charset;
|
||||
}
|
||||
|
||||
|
||||
static int sst_flush_tables(THD* thd)
|
||||
{
|
||||
WSREP_INFO("Flushing tables for SST...");
|
||||
|
@ -1503,23 +1475,21 @@ static int sst_flush_tables(THD* thd)
|
|||
}
|
||||
else
|
||||
{
|
||||
ha_disable_internal_writes(true);
|
||||
|
||||
WSREP_INFO("Tables flushed.");
|
||||
|
||||
/* disable further disk IO */
|
||||
sst_disallow_writes(thd, true);
|
||||
WSREP_INFO("Disabled further disk IO.");
|
||||
|
||||
/*
|
||||
Tables have been flushed. Create a file with cluster state ID and
|
||||
wsrep_gtid_domain_id.
|
||||
*/
|
||||
// Create a file with cluster state ID and wsrep_gtid_domain_id.
|
||||
char content[100];
|
||||
snprintf(content, sizeof(content), "%s:%lld %d\n", wsrep_cluster_state_uuid,
|
||||
(long long)wsrep_locked_seqno, wsrep_gtid_domain_id);
|
||||
err= sst_create_file(flush_success, content);
|
||||
|
||||
if(err)
|
||||
if (err)
|
||||
{
|
||||
WSREP_INFO("Creating file for flush_success failed %d",err);
|
||||
ha_disable_internal_writes(false);
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
|
@ -1570,31 +1540,30 @@ wait_signal:
|
|||
if (!strcasecmp (out, magic_flush))
|
||||
{
|
||||
err= sst_flush_tables (thd.ptr);
|
||||
|
||||
if (!err)
|
||||
{
|
||||
/*
|
||||
locked= true;
|
||||
/*
|
||||
Lets also keep statements that modify binary logs (like RESET LOGS,
|
||||
RESET MASTER) from proceeding until the files have been transferred
|
||||
to the joiner node.
|
||||
*/
|
||||
if (mysql_bin_log.is_open())
|
||||
{
|
||||
mysql_mutex_lock(mysql_bin_log.get_log_lock());
|
||||
}
|
||||
|
||||
locked= true;
|
||||
|
||||
WSREP_INFO("Donor state reached");
|
||||
WSREP_INFO("Donor state reached");
|
||||
|
||||
DBUG_EXECUTE_IF("sync.wsrep_donor_state",
|
||||
{
|
||||
const char act[]=
|
||||
"now "
|
||||
"SIGNAL sync.wsrep_donor_state_reached "
|
||||
"WAIT_FOR signal.wsrep_donor_state";
|
||||
assert(!debug_sync_set_action(thd.ptr,
|
||||
STRING_WITH_LEN(act)));
|
||||
};);
|
||||
{
|
||||
const char act[]=
|
||||
"now "
|
||||
"SIGNAL sync.wsrep_donor_state_reached "
|
||||
"WAIT_FOR signal.wsrep_donor_state";
|
||||
assert(!debug_sync_set_action(thd.ptr,
|
||||
STRING_WITH_LEN(act)));
|
||||
};);
|
||||
|
||||
goto wait_signal;
|
||||
}
|
||||
}
|
||||
|
@ -1602,14 +1571,11 @@ wait_signal:
|
|||
{
|
||||
if (locked)
|
||||
{
|
||||
if (mysql_bin_log.is_open())
|
||||
{
|
||||
mysql_mutex_assert_owner(mysql_bin_log.get_log_lock());
|
||||
mysql_mutex_unlock(mysql_bin_log.get_log_lock());
|
||||
}
|
||||
sst_disallow_writes (thd.ptr, false);
|
||||
thd.ptr->global_read_lock.unlock_global_read_lock (thd.ptr);
|
||||
locked= false;
|
||||
ha_disable_internal_writes(false);
|
||||
if (mysql_bin_log.is_open())
|
||||
mysql_mutex_unlock(mysql_bin_log.get_log_lock());
|
||||
thd.ptr->global_read_lock.unlock_global_read_lock(thd.ptr);
|
||||
}
|
||||
err= 0;
|
||||
goto wait_signal;
|
||||
|
@ -1639,13 +1605,13 @@ wait_signal:
|
|||
|
||||
if (locked) // don't forget to unlock server before return
|
||||
{
|
||||
ha_disable_internal_writes(false);
|
||||
if (mysql_bin_log.is_open())
|
||||
{
|
||||
mysql_mutex_assert_owner(mysql_bin_log.get_log_lock());
|
||||
mysql_mutex_unlock(mysql_bin_log.get_log_lock());
|
||||
}
|
||||
sst_disallow_writes (thd.ptr, false);
|
||||
thd.ptr->global_read_lock.unlock_global_read_lock (thd.ptr);
|
||||
thd.ptr->global_read_lock.unlock_global_read_lock(thd.ptr);
|
||||
}
|
||||
|
||||
// signal to donor that SST is over
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 2012, 2017, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2017, 2021, MariaDB Corporation.
|
||||
Copyright (c) 2017, 2022, 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
|
||||
|
@ -37,6 +37,11 @@ Created Apr 25, 2012 Vasil Dimov
|
|||
# include "wsrep.h"
|
||||
# include "log.h"
|
||||
# include "wsrep_mysqld.h"
|
||||
extern uint32 wsrep_sst_disable_writes;
|
||||
# define wsrep_sst_disable_writes \
|
||||
my_atomic_load32_explicit(&wsrep_sst_disable_writes, MY_MEMORY_ORDER_RELAXED)
|
||||
#else
|
||||
# define wsrep_sst_disable_writes false
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
|
@ -490,6 +495,11 @@ DECLARE_THREAD(dict_stats_thread)(void*)
|
|||
os_event_wait_time(
|
||||
dict_stats_event, MIN_RECALC_INTERVAL * 1000000);
|
||||
|
||||
if (wsrep_sst_disable_writes) {
|
||||
os_thread_sleep(1000000);
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
while (innodb_dict_stats_disabled_debug) {
|
||||
os_event_set(dict_stats_disabled_event);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2016, 2021, MariaDB Corporation.
|
||||
Copyright (c) 2016, 2022, 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
|
||||
|
@ -37,6 +37,15 @@ Completed 2011/7/10 Sunny and Jimmy Yang
|
|||
#include "zlib.h"
|
||||
#include "fts0opt.h"
|
||||
#include "fts0vlc.h"
|
||||
#include "wsrep.h"
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
extern uint32 wsrep_sst_disable_writes;
|
||||
# define wsrep_sst_disable_writes \
|
||||
my_atomic_load32_explicit(&wsrep_sst_disable_writes, MY_MEMORY_ORDER_RELAXED)
|
||||
#else
|
||||
# define wsrep_sst_disable_writes false
|
||||
#endif
|
||||
|
||||
/** The FTS optimize thread's work queue. */
|
||||
ib_wqueue_t* fts_optimize_wq;
|
||||
|
@ -2824,6 +2833,16 @@ DECLARE_THREAD(fts_optimize_thread)(
|
|||
&& ib_wqueue_is_empty(wq)
|
||||
&& n_tables > 0
|
||||
&& n_optimize > 0) {
|
||||
|
||||
/* The queue is empty but we have tables
|
||||
to optimize. */
|
||||
while (UNIV_UNLIKELY(wsrep_sst_disable_writes)
|
||||
&& srv_shutdown_state
|
||||
<= SRV_SHUTDOWN_INITIATED) {
|
||||
os_thread_sleep(1000000);
|
||||
continue;
|
||||
}
|
||||
|
||||
fts_slot_t* slot = static_cast<fts_slot_t*>(
|
||||
ib_vector_get(fts_slots, current));
|
||||
|
||||
|
@ -2882,6 +2901,13 @@ DECLARE_THREAD(fts_optimize_thread)(
|
|||
break;
|
||||
|
||||
case FTS_MSG_SYNC_TABLE:
|
||||
if (UNIV_UNLIKELY(wsrep_sst_disable_writes)) {
|
||||
ib_wqueue_add(wq, msg, msg->heap,
|
||||
false);
|
||||
os_thread_sleep(1000000);
|
||||
goto next;
|
||||
}
|
||||
|
||||
DBUG_EXECUTE_IF(
|
||||
"fts_instrument_msg_sync_sleep",
|
||||
os_thread_sleep(300000););
|
||||
|
@ -2895,6 +2921,7 @@ DECLARE_THREAD(fts_optimize_thread)(
|
|||
}
|
||||
|
||||
mem_heap_free(msg->heap);
|
||||
next:
|
||||
n_optimize = done ? 0 : fts_optimize_how_many();
|
||||
}
|
||||
}
|
||||
|
@ -2943,7 +2970,6 @@ fts_optimize_init(void)
|
|||
|
||||
/* Create FTS optimize work queue */
|
||||
fts_optimize_wq = ib_wqueue_create();
|
||||
ut_a(fts_optimize_wq != NULL);
|
||||
|
||||
/* Create FTS vector to store fts_slot_t */
|
||||
heap = mem_heap_create(sizeof(dict_table_t*) * 64);
|
||||
|
|
|
@ -104,9 +104,7 @@ this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "srv0srv.h"
|
||||
#include "srv0start.h"
|
||||
#include "rem0rec.h"
|
||||
#ifdef UNIV_DEBUG
|
||||
#include "trx0purge.h"
|
||||
#endif /* UNIV_DEBUG */
|
||||
#include "trx0roll.h"
|
||||
#include "trx0rseg.h"
|
||||
#include "trx0trx.h"
|
||||
|
@ -1894,6 +1892,57 @@ thd_to_trx_id(
|
|||
{
|
||||
return(thd_to_trx(thd)->id);
|
||||
}
|
||||
|
||||
uint32 wsrep_sst_disable_writes;
|
||||
|
||||
static void sst_disable_innodb_writes()
|
||||
{
|
||||
const uint old_count= srv_n_fil_crypt_threads;
|
||||
fil_crypt_set_thread_cnt(0);
|
||||
srv_n_fil_crypt_threads= old_count;
|
||||
|
||||
my_atomic_store32_explicit(&wsrep_sst_disable_writes, true,
|
||||
MY_MEMORY_ORDER_RELAXED);
|
||||
purge_sys.stop();
|
||||
/* We are holding a global MDL thanks to FLUSH TABLES WITH READ LOCK.
|
||||
|
||||
That will prevent any writes from arriving into InnoDB, but it will
|
||||
not prevent writes of modified pages from the buffer pool, or log
|
||||
checkpoints.
|
||||
|
||||
Let us perform a log checkpoint to ensure that the entire buffer
|
||||
pool is clean, so that no writes to persistent files will be
|
||||
possible during the snapshot, and to guarantee that no crash
|
||||
recovery will be necessary when starting up on the snapshot. */
|
||||
log_make_checkpoint();
|
||||
/* If any FILE_MODIFY records were written by the checkpoint, an
|
||||
extra write of a FILE_CHECKPOINT record could still be invoked by
|
||||
buf_flush_page_cleaner(). Let us prevent that by invoking another
|
||||
checkpoint (which will write the FILE_CHECKPOINT record). */
|
||||
log_make_checkpoint();
|
||||
ut_d(recv_no_log_write= true);
|
||||
/* If this were not a no-op, an assertion would fail due to
|
||||
recv_no_log_write. */
|
||||
ut_d(log_make_checkpoint());
|
||||
}
|
||||
|
||||
static void sst_enable_innodb_writes()
|
||||
{
|
||||
ut_ad(recv_no_log_write);
|
||||
ut_d(recv_no_log_write= false);
|
||||
purge_sys.resume();
|
||||
my_atomic_store32_explicit(&wsrep_sst_disable_writes, false,
|
||||
MY_MEMORY_ORDER_RELAXED);
|
||||
fil_crypt_set_thread_cnt(srv_n_fil_crypt_threads);
|
||||
}
|
||||
|
||||
static void innodb_disable_internal_writes(bool disable)
|
||||
{
|
||||
if (disable)
|
||||
sst_disable_innodb_writes();
|
||||
else
|
||||
sst_enable_innodb_writes();
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
/********************************************************************//**
|
||||
|
@ -2387,9 +2436,6 @@ os_file_t
|
|||
innobase_mysql_tmpfile(
|
||||
const char* path)
|
||||
{
|
||||
#ifdef WITH_INNODB_DISALLOW_WRITES
|
||||
os_event_wait(srv_allow_writes_event);
|
||||
#endif /* WITH_INNODB_DISALLOW_WRITES */
|
||||
File fd;
|
||||
|
||||
DBUG_EXECUTE_IF(
|
||||
|
@ -3543,9 +3589,6 @@ static int innodb_init_abort()
|
|||
}
|
||||
srv_tmp_space.shutdown();
|
||||
|
||||
#ifdef WITH_INNODB_DISALLOW_WRITES
|
||||
os_event_destroy(srv_allow_writes_event);
|
||||
#endif /* WITH_INNODB_DISALLOW_WRITES */
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
|
@ -4252,6 +4295,7 @@ static int innodb_init(void* p)
|
|||
innobase_hton->set_checkpoint=innobase_wsrep_set_checkpoint;
|
||||
innobase_hton->get_checkpoint=innobase_wsrep_get_checkpoint;
|
||||
innobase_hton->fake_trx_id=wsrep_fake_trx_id;
|
||||
innobase_hton->disable_internal_writes=innodb_disable_internal_writes;
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
innobase_hton->tablefile_extensions = ha_innobase_exts;
|
||||
|
@ -20056,39 +20100,6 @@ static MYSQL_SYSVAR_ULONG(buf_dump_status_frequency, srv_buf_dump_status_frequen
|
|||
"dumped. Default is 0 (only start and end status is printed).",
|
||||
NULL, NULL, 0, 0, 100, 0);
|
||||
|
||||
#ifdef WITH_INNODB_DISALLOW_WRITES
|
||||
/*******************************************************
|
||||
* innobase_disallow_writes variable definition *
|
||||
*******************************************************/
|
||||
|
||||
/* Must always init to FALSE. */
|
||||
static my_bool innobase_disallow_writes = FALSE;
|
||||
|
||||
/**************************************************************************
|
||||
An "update" method for innobase_disallow_writes variable. */
|
||||
static
|
||||
void
|
||||
innobase_disallow_writes_update(THD*, st_mysql_sys_var*,
|
||||
void* var_ptr, const void* save)
|
||||
{
|
||||
const my_bool val = *static_cast<const my_bool*>(save);
|
||||
*static_cast<my_bool*>(var_ptr) = val;
|
||||
ut_a(srv_allow_writes_event);
|
||||
mysql_mutex_unlock(&LOCK_global_system_variables);
|
||||
if (val) {
|
||||
os_event_reset(srv_allow_writes_event);
|
||||
} else {
|
||||
os_event_set(srv_allow_writes_event);
|
||||
}
|
||||
mysql_mutex_lock(&LOCK_global_system_variables);
|
||||
}
|
||||
|
||||
static MYSQL_SYSVAR_BOOL(disallow_writes, innobase_disallow_writes,
|
||||
PLUGIN_VAR_NOCMDOPT,
|
||||
"Tell InnoDB to stop any writes to disk",
|
||||
NULL, innobase_disallow_writes_update, FALSE);
|
||||
#endif /* WITH_INNODB_DISALLOW_WRITES */
|
||||
|
||||
static MYSQL_SYSVAR_BOOL(random_read_ahead, srv_random_read_ahead,
|
||||
PLUGIN_VAR_NOCMDARG,
|
||||
"Whether to use read ahead for random access within an extent.",
|
||||
|
@ -20519,9 +20530,6 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
|
|||
MYSQL_SYSVAR(change_buffering_debug),
|
||||
MYSQL_SYSVAR(disable_background_merge),
|
||||
#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
|
||||
#ifdef WITH_INNODB_DISALLOW_WRITES
|
||||
MYSQL_SYSVAR(disallow_writes),
|
||||
#endif /* WITH_INNODB_DISALLOW_WRITES */
|
||||
MYSQL_SYSVAR(random_read_ahead),
|
||||
MYSQL_SYSVAR(read_ahead_threshold),
|
||||
MYSQL_SYSVAR(read_only),
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
Copyright (c) 2008, 2009, Google Inc.
|
||||
Copyright (c) 2009, Percona Inc.
|
||||
Copyright (c) 2013, 2021, MariaDB Corporation.
|
||||
Copyright (c) 2013, 2022, MariaDB Corporation.
|
||||
|
||||
Portions of this file contain modifications contributed and copyrighted by
|
||||
Google, Inc. Those modifications are gratefully acknowledged and are described
|
||||
|
@ -353,11 +353,6 @@ extern ulong srv_log_write_ahead_size;
|
|||
extern my_bool srv_adaptive_flushing;
|
||||
extern my_bool srv_flush_sync;
|
||||
|
||||
#ifdef WITH_INNODB_DISALLOW_WRITES
|
||||
/* When this event is reset we do not allow any file writes to take place. */
|
||||
extern os_event_t srv_allow_writes_event;
|
||||
#endif /* WITH_INNODB_DISALLOW_WRITES */
|
||||
|
||||
/* If this flag is TRUE, then we will load the indexes' (and tables') metadata
|
||||
even if they are marked as "corrupted". Mostly it is for DBA to process
|
||||
corrupted index and table */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2017, 2019, MariaDB Corporation.
|
||||
# Copyright (c) 2017, 2022, 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
|
||||
|
@ -214,12 +214,6 @@ ELSE()
|
|||
ADD_DEFINITIONS(-DMUTEX_SYS)
|
||||
ENDIF()
|
||||
|
||||
OPTION(WITH_INNODB_DISALLOW_WRITES "InnoDB freeze writes patch from Google" ${WITH_WSREP})
|
||||
IF (WITH_INNODB_DISALLOW_WRITES)
|
||||
ADD_DEFINITIONS(-DWITH_INNODB_DISALLOW_WRITES)
|
||||
ENDIF()
|
||||
ADD_FEATURE_INFO(INNODB_DISALLOW_WRITES WITH_INNODB_DISALLOW_WRITES "Expose innodb_disallow_writes switch to stop innodb from writing to disk")
|
||||
|
||||
|
||||
# Include directories under innobase
|
||||
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/storage/innobase/include
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2009, Google Inc.
|
||||
Copyright (c) 2014, 2021, MariaDB Corporation.
|
||||
Copyright (c) 2014, 2022, MariaDB Corporation.
|
||||
|
||||
Portions of this file contain modifications contributed and copyrighted by
|
||||
Google, Inc. Those modifications are gratefully acknowledged and are described
|
||||
|
@ -886,7 +886,6 @@ loop:
|
|||
#endif
|
||||
|
||||
log_write_mutex_enter();
|
||||
ut_ad(!recv_no_log_write);
|
||||
|
||||
lsn_t limit_lsn = flush_to_disk
|
||||
? log_sys.flushed_to_disk_lsn
|
||||
|
@ -897,6 +896,8 @@ loop:
|
|||
return;
|
||||
}
|
||||
|
||||
ut_ad(!recv_no_log_write);
|
||||
|
||||
/* If it is a write call we should just go ahead and do it
|
||||
as we checked that write_lsn is not where we'd like it to
|
||||
be. If we have to flush as well then we check if there is a
|
||||
|
@ -1452,7 +1453,6 @@ bool log_checkpoint(bool sync)
|
|||
|
||||
log_mutex_enter();
|
||||
|
||||
ut_ad(!recv_no_log_write);
|
||||
oldest_lsn = log_buf_pool_get_oldest_modification();
|
||||
|
||||
/* Because log also contains headers and dummy log records,
|
||||
|
@ -1464,9 +1464,16 @@ bool log_checkpoint(bool sync)
|
|||
flushed up to oldest_lsn. */
|
||||
|
||||
ut_ad(oldest_lsn >= log_sys.last_checkpoint_lsn);
|
||||
if (oldest_lsn
|
||||
> log_sys.last_checkpoint_lsn + SIZE_OF_MLOG_CHECKPOINT) {
|
||||
const lsn_t age = oldest_lsn - log_sys.last_checkpoint_lsn;
|
||||
if (age > SIZE_OF_MLOG_CHECKPOINT
|
||||
+ LOG_BLOCK_HDR_SIZE + LOG_BLOCK_CHECKSUM) {
|
||||
/* Some log has been written since the previous checkpoint. */
|
||||
} else if (age > SIZE_OF_MLOG_CHECKPOINT
|
||||
&& !((log_sys.log.calc_lsn_offset(oldest_lsn)
|
||||
^ log_sys.log.calc_lsn_offset(
|
||||
log_sys.last_checkpoint_lsn))
|
||||
& ~lsn_t(OS_FILE_LOG_BLOCK_SIZE - 1))) {
|
||||
/* Some log has been written to the same log block. */
|
||||
} else if (srv_shutdown_state > SRV_SHUTDOWN_INITIATED) {
|
||||
/* MariaDB 10.3 startup expects the redo log file to be
|
||||
logically empty (not even containing a MLOG_CHECKPOINT record)
|
||||
|
@ -1478,6 +1485,9 @@ bool log_checkpoint(bool sync)
|
|||
log_mutex_exit();
|
||||
return(true);
|
||||
}
|
||||
|
||||
ut_ad(!recv_no_log_write);
|
||||
|
||||
/* Repeat the MLOG_FILE_NAME records after the checkpoint, in
|
||||
case some log records between the checkpoint and log_sys.lsn
|
||||
need them. Finally, write a MLOG_CHECKPOINT marker. Redo log
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
Copyright (c) 1995, 2019, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2009, Percona Inc.
|
||||
Copyright (c) 2013, 2021, MariaDB Corporation.
|
||||
Copyright (c) 2013, 2022, MariaDB Corporation.
|
||||
|
||||
Portions of this file contain modifications contributed and copyrighted
|
||||
by Percona Inc.. Those modifications are
|
||||
|
@ -114,12 +114,6 @@ static const ulint OS_AIO_MERGE_N_CONSECUTIVE = 64;
|
|||
/** Flag indicating if the page_cleaner is in active state. */
|
||||
extern bool buf_page_cleaner_is_active;
|
||||
|
||||
#ifdef WITH_INNODB_DISALLOW_WRITES
|
||||
#define WAIT_ALLOW_WRITES() os_event_wait(srv_allow_writes_event)
|
||||
#else
|
||||
#define WAIT_ALLOW_WRITES() do { } while (0)
|
||||
#endif /* WITH_INNODB_DISALLOW_WRITES */
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
InnoDB AIO Implementation:
|
||||
|
@ -1247,7 +1241,6 @@ FILE*
|
|||
os_file_create_tmpfile()
|
||||
{
|
||||
FILE* file = NULL;
|
||||
WAIT_ALLOW_WRITES();
|
||||
os_file_t fd = innobase_mysql_tmpfile(NULL);
|
||||
|
||||
if (fd != OS_FILE_CLOSED) {
|
||||
|
@ -2611,7 +2604,6 @@ os_file_flush_func(
|
|||
{
|
||||
int ret;
|
||||
|
||||
WAIT_ALLOW_WRITES();
|
||||
ret = os_file_fsync_posix(file);
|
||||
|
||||
if (ret == 0) {
|
||||
|
@ -2663,10 +2655,6 @@ os_file_create_simple_func(
|
|||
int create_flag;
|
||||
const char* mode_str = NULL;
|
||||
|
||||
if (create_mode != OS_FILE_OPEN && create_mode != OS_FILE_OPEN_RAW) {
|
||||
WAIT_ALLOW_WRITES();
|
||||
}
|
||||
|
||||
ut_a(!(create_mode & OS_FILE_ON_ERROR_SILENT));
|
||||
ut_a(!(create_mode & OS_FILE_ON_ERROR_NO_EXIT));
|
||||
|
||||
|
@ -2784,7 +2772,6 @@ os_file_create_directory(
|
|||
{
|
||||
int rcode;
|
||||
|
||||
WAIT_ALLOW_WRITES();
|
||||
rcode = mkdir(pathname, 0770);
|
||||
|
||||
if (!(rcode == 0 || (errno == EEXIST && !fail_if_exists))) {
|
||||
|
@ -3119,10 +3106,6 @@ os_file_create_simple_no_error_handling_func(
|
|||
os_file_t file;
|
||||
int create_flag;
|
||||
|
||||
if (create_mode != OS_FILE_OPEN && create_mode != OS_FILE_OPEN_RAW) {
|
||||
WAIT_ALLOW_WRITES();
|
||||
}
|
||||
|
||||
ut_a(!(create_mode & OS_FILE_ON_ERROR_SILENT));
|
||||
ut_a(!(create_mode & OS_FILE_ON_ERROR_NO_EXIT));
|
||||
|
||||
|
@ -3197,7 +3180,6 @@ os_file_delete_if_exists_func(
|
|||
}
|
||||
|
||||
int ret;
|
||||
WAIT_ALLOW_WRITES();
|
||||
|
||||
ret = unlink(name);
|
||||
|
||||
|
@ -3222,7 +3204,6 @@ os_file_delete_func(
|
|||
const char* name)
|
||||
{
|
||||
int ret;
|
||||
WAIT_ALLOW_WRITES();
|
||||
|
||||
ret = unlink(name);
|
||||
|
||||
|
@ -3261,7 +3242,6 @@ os_file_rename_func(
|
|||
#endif /* UNIV_DEBUG */
|
||||
|
||||
int ret;
|
||||
WAIT_ALLOW_WRITES();
|
||||
|
||||
ret = rename(oldpath, newpath);
|
||||
|
||||
|
@ -3435,7 +3415,6 @@ bool
|
|||
os_file_set_eof(
|
||||
FILE* file) /*!< in: file to be truncated */
|
||||
{
|
||||
WAIT_ALLOW_WRITES();
|
||||
return(!ftruncate(fileno(file), ftell(file)));
|
||||
}
|
||||
|
||||
|
@ -4157,10 +4136,6 @@ os_file_create_func(
|
|||
? FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE
|
||||
: FILE_SHARE_READ | FILE_SHARE_DELETE;
|
||||
|
||||
if (create_mode != OS_FILE_OPEN && create_mode != OS_FILE_OPEN_RAW) {
|
||||
WAIT_ALLOW_WRITES();
|
||||
}
|
||||
|
||||
on_error_no_exit = create_mode & OS_FILE_ON_ERROR_NO_EXIT
|
||||
? true : false;
|
||||
|
||||
|
@ -5008,8 +4983,6 @@ os_file_write_func(
|
|||
ut_ad(type.validate());
|
||||
ut_ad(n > 0);
|
||||
|
||||
WAIT_ALLOW_WRITES();
|
||||
|
||||
ssize_t n_bytes = os_file_pwrite(type, file, (byte*)buf, n, offset, &err);
|
||||
|
||||
if ((ulint) n_bytes != n && !os_has_said_disk_full) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 2005, 2017, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2014, 2021, MariaDB Corporation.
|
||||
Copyright (c) 2014, 2022, 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
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2008, 2009 Google Inc.
|
||||
Copyright (c) 2009, Percona Inc.
|
||||
Copyright (c) 2013, 2021, MariaDB Corporation.
|
||||
Copyright (c) 2013, 2022, MariaDB Corporation.
|
||||
|
||||
Portions of this file contain modifications contributed and copyrighted by
|
||||
Google, Inc. Those modifications are gratefully acknowledged and are described
|
||||
|
@ -218,10 +218,6 @@ srv_printf_innodb_monitor() will request mutex acquisition
|
|||
with mutex_enter(), which will wait until it gets the mutex. */
|
||||
#define MUTEX_NOWAIT(mutex_skipped) ((mutex_skipped) < MAX_MUTEX_NOWAIT)
|
||||
|
||||
#ifdef WITH_INNODB_DISALLOW_WRITES
|
||||
UNIV_INTERN os_event_t srv_allow_writes_event;
|
||||
#endif /* WITH_INNODB_DISALLOW_WRITES */
|
||||
|
||||
/** copy of innodb_buffer_pool_size */
|
||||
ulint srv_buf_pool_size;
|
||||
/** Requested buffer pool chunk size. Each buffer pool instance consists
|
||||
|
@ -1059,15 +1055,6 @@ srv_init()
|
|||
|
||||
dict_ind_init();
|
||||
|
||||
#ifdef WITH_INNODB_DISALLOW_WRITES
|
||||
/* Writes have to be enabled on init or else we hang. Thus, we
|
||||
always set the event here regardless of innobase_disallow_writes.
|
||||
That flag will always be 0 at this point because it isn't settable
|
||||
via my.cnf or command line arg. */
|
||||
srv_allow_writes_event = os_event_create(0);
|
||||
os_event_set(srv_allow_writes_event);
|
||||
#endif /* WITH_INNODB_DISALLOW_WRITES */
|
||||
|
||||
/* Initialize some INFORMATION SCHEMA internal structures */
|
||||
trx_i_s_cache_init(trx_i_s_cache);
|
||||
|
||||
|
@ -1822,20 +1809,7 @@ loop:
|
|||
|
||||
if (sync_array_print_long_waits(&waiter, &sema)
|
||||
&& sema == old_sema && os_thread_eq(waiter, old_waiter)) {
|
||||
#if defined(WITH_WSREP) && defined(WITH_INNODB_DISALLOW_WRITES)
|
||||
if (os_event_is_set(srv_allow_writes_event)) {
|
||||
#endif /* WITH_WSREP */
|
||||
fatal_cnt++;
|
||||
#if defined(WITH_WSREP) && defined(WITH_INNODB_DISALLOW_WRITES)
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
"WSREP: avoiding InnoDB self crash due to long "
|
||||
"semaphore wait of > %lu seconds\n"
|
||||
"Server is processing SST donor operation, "
|
||||
"fatal_cnt now: " ULINTPF,
|
||||
srv_fatal_semaphore_wait_threshold, fatal_cnt);
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
if (fatal_cnt > 10) {
|
||||
ib::fatal() << "Semaphore wait has lasted > "
|
||||
<< srv_fatal_semaphore_wait_threshold
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
Copyright (c) 2008, Google Inc.
|
||||
Copyright (c) 2009, Percona Inc.
|
||||
Copyright (c) 2013, 2021, MariaDB Corporation.
|
||||
Copyright (c) 2013, 2022, MariaDB Corporation.
|
||||
|
||||
Portions of this file contain modifications contributed and copyrighted by
|
||||
Google, Inc. Those modifications are gratefully acknowledged and are described
|
||||
|
@ -2680,10 +2680,6 @@ void innodb_shutdown()
|
|||
}
|
||||
srv_tmp_space.shutdown();
|
||||
|
||||
#ifdef WITH_INNODB_DISALLOW_WRITES
|
||||
os_event_destroy(srv_allow_writes_event);
|
||||
#endif /* WITH_INNODB_DISALLOW_WRITES */
|
||||
|
||||
if (srv_was_started && srv_print_verbose_log) {
|
||||
ib::info() << "Shutdown completed; log sequence number "
|
||||
<< srv_shutdown_lsn
|
||||
|
|
Loading…
Add table
Reference in a new issue