summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2022-04-06 08:06:49 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2022-04-06 08:06:49 +0300
commite9735a81859f172b73f75eccc043540a58d91cbc (patch)
tree9d37a99749581b4baff7fdaec0f0869c02d87495
parent7c584d8270cf192496f36e993e7759616f3b650b (diff)
downloadmariadb-git-e9735a81859f172b73f75eccc043540a58d91cbc.tar.gz
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
-rw-r--r--extra/mariabackup/xtrabackup.cc12
-rw-r--r--mysql-test/include/have_innodb_disallow_writes.inc6
-rw-r--r--mysql-test/suite/galera/r/galera_bf_abort_shutdown.result11
-rw-r--r--mysql-test/suite/galera/r/galera_drop_database.result3
-rw-r--r--mysql-test/suite/galera/r/galera_events2.result1
-rw-r--r--mysql-test/suite/galera/r/galera_restart_on_unknown_option.result1
-rw-r--r--mysql-test/suite/galera/r/galera_var_innodb_disallow_writes.result28
-rw-r--r--mysql-test/suite/galera/t/galera_bf_abort_shutdown.test34
-rw-r--r--mysql-test/suite/galera/t/galera_drop_database.test1
-rw-r--r--mysql-test/suite/galera/t/galera_events2.test2
-rw-r--r--mysql-test/suite/galera/t/galera_restart_on_unknown_option.test1
-rw-r--r--mysql-test/suite/galera/t/galera_var_innodb_disallow_writes.test71
-rw-r--r--mysql-test/suite/sys_vars/r/innodb_disallow_writes_basic.result45
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_innodb.result2
-rw-r--r--mysql-test/suite/sys_vars/t/innodb_disallow_writes_basic.test42
-rw-r--r--mysql-test/suite/sys_vars/t/sysvars_innodb.test2
-rw-r--r--scripts/wsrep_sst_rsync.sh14
-rw-r--r--sql/handler.cc16
-rw-r--r--sql/handler.h5
-rw-r--r--sql/wsrep_sst.cc92
-rw-r--r--storage/innobase/dict/dict0stats_bg.cc12
-rw-r--r--storage/innobase/fts/fts0opt.cc30
-rw-r--r--storage/innobase/handler/ha_innodb.cc96
-rw-r--r--storage/innobase/include/srv0srv.h7
-rw-r--r--storage/innobase/innodb.cmake8
-rw-r--r--storage/innobase/log/log0log.cc20
-rw-r--r--storage/innobase/os/os0file.cc29
-rw-r--r--storage/innobase/row/row0merge.cc2
-rw-r--r--storage/innobase/srv/srv0srv.cc28
-rw-r--r--storage/innobase/srv/srv0start.cc6
30 files changed, 229 insertions, 398 deletions
diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc
index 70542a35514..41461d6ece1 100644
--- a/extra/mariabackup/xtrabackup.cc
+++ b/extra/mariabackup/xtrabackup.cc
@@ -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();
diff --git a/mysql-test/include/have_innodb_disallow_writes.inc b/mysql-test/include/have_innodb_disallow_writes.inc
deleted file mode 100644
index 83b516b7a34..00000000000
--- a/mysql-test/include/have_innodb_disallow_writes.inc
+++ /dev/null
@@ -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'
-}
diff --git a/mysql-test/suite/galera/r/galera_bf_abort_shutdown.result b/mysql-test/suite/galera/r/galera_bf_abort_shutdown.result
new file mode 100644
index 00000000000..bf77fd7eae7
--- /dev/null
+++ b/mysql-test/suite/galera/r/galera_bf_abort_shutdown.result
@@ -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;
diff --git a/mysql-test/suite/galera/r/galera_drop_database.result b/mysql-test/suite/galera/r/galera_drop_database.result
index 914cdffceed..794e934206f 100644
--- a/mysql-test/suite/galera/r/galera_drop_database.result
+++ b/mysql-test/suite/galera/r/galera_drop_database.result
@@ -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'
diff --git a/mysql-test/suite/galera/r/galera_events2.result b/mysql-test/suite/galera/r/galera_events2.result
index 36441e15f7d..8fb98e03fab 100644
--- a/mysql-test/suite/galera/r/galera_events2.result
+++ b/mysql-test/suite/galera/r/galera_events2.result
@@ -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
diff --git a/mysql-test/suite/galera/r/galera_restart_on_unknown_option.result b/mysql-test/suite/galera/r/galera_restart_on_unknown_option.result
index ba6f30fcf30..e748859beb7 100644
--- a/mysql-test/suite/galera/r/galera_restart_on_unknown_option.result
+++ b/mysql-test/suite/galera/r/galera_restart_on_unknown_option.result
@@ -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
diff --git a/mysql-test/suite/galera/r/galera_var_innodb_disallow_writes.result b/mysql-test/suite/galera/r/galera_var_innodb_disallow_writes.result
deleted file mode 100644
index 8750651612d..00000000000
--- a/mysql-test/suite/galera/r/galera_var_innodb_disallow_writes.result
+++ /dev/null
@@ -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;
diff --git a/mysql-test/suite/galera/t/galera_bf_abort_shutdown.test b/mysql-test/suite/galera/t/galera_bf_abort_shutdown.test
new file mode 100644
index 00000000000..42f85ecf7c2
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_bf_abort_shutdown.test
@@ -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;
diff --git a/mysql-test/suite/galera/t/galera_drop_database.test b/mysql-test/suite/galera/t/galera_drop_database.test
index 8dc73c1ce38..c1a66e1f66c 100644
--- a/mysql-test/suite/galera/t/galera_drop_database.test
+++ b/mysql-test/suite/galera/t/galera_drop_database.test
@@ -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';
diff --git a/mysql-test/suite/galera/t/galera_events2.test b/mysql-test/suite/galera/t/galera_events2.test
index 3dfbe406fc4..b29ad3ba2f2 100644
--- a/mysql-test/suite/galera/t/galera_events2.test
+++ b/mysql-test/suite/galera/t/galera_events2.test
@@ -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
diff --git a/mysql-test/suite/galera/t/galera_restart_on_unknown_option.test b/mysql-test/suite/galera/t/galera_restart_on_unknown_option.test
index ed7f106c123..6a0f24dbaae 100644
--- a/mysql-test/suite/galera/t/galera_restart_on_unknown_option.test
+++ b/mysql-test/suite/galera/t/galera_restart_on_unknown_option.test
@@ -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
diff --git a/mysql-test/suite/galera/t/galera_var_innodb_disallow_writes.test b/mysql-test/suite/galera/t/galera_var_innodb_disallow_writes.test
deleted file mode 100644
index 0d2a6effd92..00000000000
--- a/mysql-test/suite/galera/t/galera_var_innodb_disallow_writes.test
+++ /dev/null
@@ -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
-
diff --git a/mysql-test/suite/sys_vars/r/innodb_disallow_writes_basic.result b/mysql-test/suite/sys_vars/r/innodb_disallow_writes_basic.result
deleted file mode 100644
index bfb6b67b5d8..00000000000
--- a/mysql-test/suite/sys_vars/r/innodb_disallow_writes_basic.result
+++ /dev/null
@@ -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
diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb.result b/mysql-test/suite/sys_vars/r/sysvars_innodb.result
index ff6c6d310cf..f47c7de8132 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_innodb.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_innodb.result
@@ -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
diff --git a/mysql-test/suite/sys_vars/t/innodb_disallow_writes_basic.test b/mysql-test/suite/sys_vars/t/innodb_disallow_writes_basic.test
deleted file mode 100644
index b8e5c127377..00000000000
--- a/mysql-test/suite/sys_vars/t/innodb_disallow_writes_basic.test
+++ /dev/null
@@ -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
diff --git a/mysql-test/suite/sys_vars/t/sysvars_innodb.test b/mysql-test/suite/sys_vars/t/sysvars_innodb.test
index ef52ee3264a..15fd99e9984 100644
--- a/mysql-test/suite/sys_vars/t/sysvars_innodb.test
+++ b/mysql-test/suite/sys_vars/t/sysvars_innodb.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
diff --git a/scripts/wsrep_sst_rsync.sh b/scripts/wsrep_sst_rsync.sh
index 5f7ae4298b5..29e2b390e27 100644
--- a/scripts/wsrep_sst_rsync.sh
+++ b/scripts/wsrep_sst_rsync.sh
@@ -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"
diff --git a/sql/handler.cc b/sql/handler.cc
index cad9019c969..e4c377451c6 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -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 ===================================*/
diff --git a/sql/handler.h b/sql/handler.h
index a39de4b7180..1c971b2f831 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -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);
diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc
index 0549d3e1c1d..db31b019a59 100644
--- a/sql/wsrep_sst.cc
+++ b/sql/wsrep_sst.cc
@@ -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
{
- WSREP_INFO("Tables flushed.");
+ ha_disable_internal_writes(true);
- /* disable further disk IO */
- sst_disallow_writes(thd, true);
- WSREP_INFO("Disabled further disk IO.");
+ WSREP_INFO("Tables flushed.");
- /*
- 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)
{
+ locked= false;
+ 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);
- locked= false;
+ 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
diff --git a/storage/innobase/dict/dict0stats_bg.cc b/storage/innobase/dict/dict0stats_bg.cc
index 386c7864579..4abcf9cb09f 100644
--- a/storage/innobase/dict/dict0stats_bg.cc
+++ b/storage/innobase/dict/dict0stats_bg.cc
@@ -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);
diff --git a/storage/innobase/fts/fts0opt.cc b/storage/innobase/fts/fts0opt.cc
index 376f09b8ff5..d0ea888202e 100644
--- a/storage/innobase/fts/fts0opt.cc
+++ b/storage/innobase/fts/fts0opt.cc
@@ -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);
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 02ac53e22dd..3866eb79853 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -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),
diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
index 10bfa2d0e82..a7bed269fa4 100644
--- a/storage/innobase/include/srv0srv.h
+++ b/storage/innobase/include/srv0srv.h
@@ -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 */
diff --git a/storage/innobase/innodb.cmake b/storage/innobase/innodb.cmake
index 8262d95030b..833793b65c1 100644
--- a/storage/innobase/innodb.cmake
+++ b/storage/innobase/innodb.cmake
@@ -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
diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc
index e2a40b06ba4..afd4fa278ea 100644
--- a/storage/innobase/log/log0log.cc
+++ b/storage/innobase/log/log0log.cc
@@ -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
diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc
index 329fd29b119..8c76e86ef0f 100644
--- a/storage/innobase/os/os0file.cc
+++ b/storage/innobase/os/os0file.cc
@@ -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) {
diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc
index d6ace914c23..71df96c5be1 100644
--- a/storage/innobase/row/row0merge.cc
+++ b/storage/innobase/row/row0merge.cc
@@ -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
diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc
index 93efe7ed3f4..2bc5500ef91 100644
--- a/storage/innobase/srv/srv0srv.cc
+++ b/storage/innobase/srv/srv0srv.cc
@@ -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
diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc
index 4144ae86578..48f71db73e4 100644
--- a/storage/innobase/srv/srv0start.cc
+++ b/storage/innobase/srv/srv0start.cc
@@ -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