diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc
index db31553999a..190bf6f6de6 100644
--- a/extra/mariabackup/xtrabackup.cc
+++ b/extra/mariabackup/xtrabackup.cc
@@ -1600,11 +1600,11 @@ struct my_option xb_client_options[]= {
      GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
     {"rsync", OPT_RSYNC,
-     "Obsolete depricated option",
+     "Obsolete, deprecated option",
      &ignored_option, &ignored_option,  0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
     {"no-backup-locks", OPT_NO_BACKUP_LOCKS,
-     "Obsolete depricated option",
+     "Obsolete, deprecated option",
      &ignored_option, &ignored_option,  0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
     {"force-non-empty-directories", OPT_FORCE_NON_EMPTY_DIRS,
diff --git a/mysql-test/suite/innodb/r/row_format_redundant.result b/mysql-test/suite/innodb/r/row_format_redundant.result
index 04101ae98ec..3fa0bf8eea2 100644
--- a/mysql-test/suite/innodb/r/row_format_redundant.result
+++ b/mysql-test/suite/innodb/r/row_format_redundant.result
@@ -1,5 +1,5 @@
 SET GLOBAL innodb_fast_shutdown=0;
-# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-data-file-path=ibdata1:1M:autoextend --innodb-undo-tablespaces=0 --innodb-stats-persistent=0
+# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-data-file-path=ibdata1:1M:autoextend --innodb_undo_directory=MYSQLTEST_VARDIR/tmp/undo_dir --innodb-undo-tablespaces=0 --innodb-stats-persistent=0
 #
 # Bug#21644827 - FTS, ASSERT !SRV_READ_ONLY_MODE || M_IMPL.M_LOG_MODE ==
 #                MTR_LOG_NO_REDO
@@ -25,7 +25,7 @@ c varchar(150), index k1(c(99), b(56)), index k2(b(5), c(10))) engine=InnoDB
 row_format=redundant;
 insert into t3 values(444, 'dddd', 'bbbbb', 'aaaaa');
 insert into t3 values(555, 'eeee', 'ccccc', 'aaaaa');
-# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-data-file-path=ibdata1:1M:autoextend --innodb-undo-tablespaces=0 --innodb-stats-persistent=0 --innodb-read-only
+# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-data-file-path=ibdata1:1M:autoextend --innodb_undo_directory=MYSQLTEST_VARDIR/tmp/undo_dir --innodb-undo-tablespaces=0 --innodb-stats-persistent=0 --innodb-read-only
 SELECT COUNT(*) FROM t1;
 COUNT(*)
 4096
@@ -41,14 +41,14 @@ TRUNCATE TABLE t2;
 ERROR HY000: Table 't2' is read only
 TRUNCATE TABLE t3;
 ERROR HY000: Table 't3' is read only
-# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-data-file-path=ibdata1:1M:autoextend --innodb-undo-tablespaces=0 --innodb-stats-persistent=0 --skip-innodb-fast-shutdown
+# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-data-file-path=ibdata1:1M:autoextend --innodb_undo_directory=MYSQLTEST_VARDIR/tmp/undo_dir --innodb-undo-tablespaces=0 --innodb-stats-persistent=0 --skip-innodb-fast-shutdown
 TRUNCATE TABLE t1;
 TRUNCATE TABLE t2;
 TRUNCATE TABLE t3;
 corrupted SYS_TABLES.MIX_LEN for test/t1
 corrupted SYS_TABLES.MIX_LEN for test/t2
 corrupted SYS_TABLES.MIX_LEN for test/t3
-# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-data-file-path=ibdata1:1M:autoextend --innodb-undo-tablespaces=0 --innodb-stats-persistent=0 --skip-innodb-fast-shutdown
+# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-data-file-path=ibdata1:1M:autoextend --innodb_undo_directory=MYSQLTEST_VARDIR/tmp/undo_dir --innodb-undo-tablespaces=0 --innodb-stats-persistent=0 --skip-innodb-fast-shutdown
 TRUNCATE TABLE t1;
 ERROR 42S02: Table 'test.t1' doesn't exist in engine
 TRUNCATE TABLE t2;
diff --git a/mysql-test/suite/innodb/r/undo_upgrade.result b/mysql-test/suite/innodb/r/undo_upgrade.result
index f2eca9e2a7c..0f0b72f2987 100644
--- a/mysql-test/suite/innodb/r/undo_upgrade.result
+++ b/mysql-test/suite/innodb/r/undo_upgrade.result
@@ -62,3 +62,27 @@ SELECT @@global.innodb_undo_tablespaces;
 # Should list 2 undo log tablespaces, not 4
 undo001
 undo002
+#
+# MDEV-34200 InnoDB tries to write to read-only
+#    system tablespace in buf_dblwr_t::init_or_load_pages()
+#
+SET GLOBAL innodb_fast_shutdown=0;
+# restart: --innodb_undo_tablespaces=4
+# Should list 4 undo log tablespaces
+undo001
+undo002
+undo003
+undo004
+set global innodb_fast_shutdown=0;
+# restart: --innodb_read_only=1
+set global innodb_fast_shutdown=0;
+# restart: --innodb-data-file-path=ibdata1:1M:autoextend --innodb_undo_directory=MYSQLTEST_VARDIR/tmp/undo_dir --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/bugdir --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/bugdir --innodb_undo_tablespaces=3
+# Should list 3 undo log tablespaces
+undo001
+undo002
+undo003
+set global innodb_fast_shutdown=0;
+# restart: --innodb-data-file-path=ibdata1:1M:autoextend --innodb_undo_directory=MYSQLTEST_VARDIR/tmp/undo_dir --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/bugdir_1 --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/bugdir_1 --innodb_undo_tablespaces=0
+# Shouldn't list 0 undo log tablespaces
+set global innodb_fast_shutdown=0;
+# restart
diff --git a/mysql-test/suite/innodb/t/row_format_redundant.test b/mysql-test/suite/innodb/t/row_format_redundant.test
index b11347766b5..9f85c45455b 100644
--- a/mysql-test/suite/innodb/t/row_format_redundant.test
+++ b/mysql-test/suite/innodb/t/row_format_redundant.test
@@ -16,11 +16,14 @@ let INNODB_PAGE_SIZE=`select @@innodb_page_size`;
 
 let bugdir= $MYSQLTEST_VARDIR/tmp/row_format_redundant;
 --mkdir $bugdir
+let undodir= $MYSQLTEST_VARDIR/tmp/undo_dir;
+--mkdir $undodir
+
 --let SEARCH_FILE = $MYSQLTEST_VARDIR/log/mysqld.1.err
 
 --let $d=--innodb-data-home-dir=$bugdir --innodb-log-group-home-dir=$bugdir
 --let $d=$d --innodb-data-file-path=ibdata1:1M:autoextend
---let $d=$d --innodb-undo-tablespaces=0 --innodb-stats-persistent=0
+--let $d=$d --innodb_undo_directory=$undodir --innodb-undo-tablespaces=0 --innodb-stats-persistent=0
 --let $restart_parameters= $d
 # Ensure that any DDL records from previous tests have been purged.
 SET GLOBAL innodb_fast_shutdown=0;
@@ -153,6 +156,7 @@ DROP TABLE t2,t3;
 --list_files $bugdir
 --remove_files_wildcard $bugdir
 --rmdir $bugdir
+--rmdir $undodir
 
 # Remove the data file, because DROP TABLE skipped it for the "corrupted" table
 --let MYSQLD_DATADIR=`select @@datadir`
diff --git a/mysql-test/suite/innodb/t/table_flags.test b/mysql-test/suite/innodb/t/table_flags.test
index a17b8dc32b6..e88499a4278 100644
--- a/mysql-test/suite/innodb/t/table_flags.test
+++ b/mysql-test/suite/innodb/t/table_flags.test
@@ -29,12 +29,15 @@ let MYSQLD_DATADIR=`select @@datadir`;
 
 let bugdir= $MYSQLTEST_VARDIR/tmp/table_flags;
 --mkdir $bugdir
+let undodir= $MYSQLTEST_VARDIR/tmp/undo_dir;
+--mkdir $undodir
+
 --let SEARCH_FILE = $MYSQLTEST_VARDIR/log/mysqld.1.err
 
 --let $d=--innodb-data-home-dir=$bugdir --innodb-log-group-home-dir=$bugdir
 --let $d=$d --innodb-data-file-path=ibdata1:1M:autoextend
 --let $d=$d --innodb-undo-tablespaces=0
---let $d=$d --skip-innodb-fast-shutdown
+--let $d=$d --skip-innodb-fast-shutdown --innodb_undo_directory=$undodir
 --let $restart_noprint=1
 --let $restart_parameters=$d --innodb-stats-persistent=0
 --source include/restart_mysqld.inc
@@ -233,6 +236,7 @@ DROP TABLE tr,tc,td,tz,tp;
 --list_files $bugdir
 --remove_files_wildcard $bugdir
 --rmdir $bugdir
+--rmdir $undodir
 
 call mtr.add_suppression("ERROR HY000: Can't create table `test`.`t1`");
 --error ER_CANT_CREATE_TABLE
diff --git a/mysql-test/suite/innodb/t/undo_upgrade.test b/mysql-test/suite/innodb/t/undo_upgrade.test
index 9c0da017fa7..f27eae334d8 100644
--- a/mysql-test/suite/innodb/t/undo_upgrade.test
+++ b/mysql-test/suite/innodb/t/undo_upgrade.test
@@ -76,3 +76,46 @@ SELECT @@global.innodb_undo_tablespaces;
 
 --echo # Should list 2 undo log tablespaces, not 4
 list_files $MYSQLD_DATADIR undo*;
+
+--echo #
+--echo # MDEV-34200 InnoDB tries to write to read-only
+--echo #    system tablespace in buf_dblwr_t::init_or_load_pages()
+--echo #
+
+SET GLOBAL innodb_fast_shutdown=0;
+let $restart_parameters=--innodb_undo_tablespaces=4;
+--source include/restart_mysqld.inc
+--echo # Should list 4 undo log tablespaces
+list_files $MYSQLD_DATADIR undo*;
+
+set global innodb_fast_shutdown=0;
+let $restart_parameters=--innodb_read_only=1;
+--source include/restart_mysqld.inc
+
+set global innodb_fast_shutdown=0;
+let bugdir= $MYSQLTEST_VARDIR/tmp/bugdir;
+mkdir $bugdir;
+let undodir= $MYSQLTEST_VARDIR/tmp/undo_dir;
+mkdir $undodir;
+let $d= --innodb-data-file-path=ibdata1:1M:autoextend;
+let $d=$d --innodb_undo_directory=$undodir;
+let $restart_parameters= $d --innodb-data-home-dir=$bugdir --innodb-log-group-home-dir=$bugdir --innodb_undo_tablespaces=3;
+--source include/restart_mysqld.inc
+--echo # Should list 3 undo log tablespaces
+list_files $undodir undo*;
+
+let bugdir_1= $MYSQLTEST_VARDIR/tmp/bugdir_1;
+mkdir $bugdir_1;
+
+set global innodb_fast_shutdown=0;
+let $restart_parameters= $d --innodb-data-home-dir=$bugdir_1 --innodb-log-group-home-dir=$bugdir_1 --innodb_undo_tablespaces=0;
+--source include/restart_mysqld.inc
+--echo # Shouldn't list 0 undo log tablespaces
+list_files $undodir undo*;
+
+set global innodb_fast_shutdown=0;
+let $restart_parameters=;
+--source include/restart_mysqld.inc
+rmdir $bugdir;
+rmdir $bugdir_1;
+rmdir $undodir;
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 2e7933b38c1..04086be689c 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -1381,6 +1381,12 @@ bool Item_func_sformat::fix_length_and_dec(THD *thd)
 */
 namespace fmt {
   template <> struct formatter<String>: formatter<string_view> {
+    template <typename FormatContext>
+    auto format(String c, FormatContext& ctx) const -> decltype(ctx.out()) {
+      string_view name = { c.ptr(), c.length() };
+      return formatter<string_view>::format(name, ctx);
+    };
+    /* needed below function for libfmt-7.1.3 compatibility, (not 9.1.0+) */
     template <typename FormatContext>
     auto format(String c, FormatContext& ctx) -> decltype(ctx.out()) {
       string_view name = { c.ptr(), c.length() };
diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc
index ec64d8d46ff..2bf4960819f 100644
--- a/storage/innobase/buf/buf0dblwr.cc
+++ b/storage/innobase/buf/buf0dblwr.cc
@@ -284,6 +284,7 @@ func_exit:
   init(TRX_SYS_DOUBLEWRITE + read_buf);
 
   const bool upgrade_to_innodb_file_per_table=
+    !srv_read_only_mode &&
     mach_read_from_4(TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED +
                      TRX_SYS_DOUBLEWRITE + read_buf) !=
     TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N;
diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc
index 1d8115ff489..c2b8d1cc183 100644
--- a/storage/innobase/srv/srv0start.cc
+++ b/storage/innobase/srv/srv0start.cc
@@ -369,6 +369,11 @@ inline dberr_t trx_sys_t::reset_page(mtr_t *mtr)
       sys_header->page.frame + TRX_SYS_DOUBLEWRITE
       + FSEG_HEADER_SIZE + TRX_SYS_DOUBLEWRITE_REPEAT,
       sys_header->page.frame + TRX_SYS_DOUBLEWRITE + FSEG_HEADER_SIZE, 12);
+    mtr->write<4>(
+      *sys_header,
+      TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED +
+      sys_header->page.frame,
+      TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N);
   }
 
   return DB_SUCCESS;
@@ -822,7 +827,7 @@ unused_undo:
   {
      char name[OS_FILE_MAX_PATH];
      snprintf(name, sizeof name, "%s/undo%03u", srv_undo_dir, i);
-     uint32_t space_id= srv_undo_tablespace_open(create_new_undo, name, i);
+     uint32_t space_id= srv_undo_tablespace_open(false, name, i);
      if (!space_id || space_id == ~0U)
        break;
      if (0 == srv_undo_tablespaces_open++)