From 9009927800639ff5b45d19b6d3d331eb3919643f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= <marko.makela@mariadb.com>
Date: Thu, 6 Feb 2020 12:15:23 +0200
Subject: [PATCH] Test: Remove FlushObserver and innodb_log_optimize_ddl from
 10.3

Even with this change, the tests

	encryption.innodb-discard-import innodb.innodb-wl5522

will not fail.

During native table rebuild or index creation, InnoDB used to skip
redo logging and write MLOG_INDEX_LOAD records to inform crash recovery
and Mariabackup of the gaps in redo log. This is fragile and prohibits
some optimizations, such as skipping the doublewrite buffer for
newly (re)initialized pages (MDEV-19738).

row_merge_write_redo(): Remove. We do not write MLOG_INDEX_LOAD
records any more. Instead, we write full redo log.

FlushObserver: Remove.

fil_space_t::redo_skipped_count: Remove.

We cannot remove buf_block_t::skip_flush_check, because PageBulk
will temporarily generate invalid B-tree pages in the buffer pool.
---
 storage/innobase/btr/btr0bulk.cc      |  41 ++-----
 storage/innobase/btr/btr0cur.cc       |   3 -
 storage/innobase/buf/buf0buf.cc       |   4 +-
 storage/innobase/buf/buf0flu.cc       | 155 +-------------------------
 storage/innobase/buf/buf0lru.cc       |  95 +++++-----------
 storage/innobase/fil/fil0fil.cc       |   6 +-
 storage/innobase/fsp/fsp0fsp.cc       |   3 +-
 storage/innobase/handler/ha_innodb.cc |   8 --
 storage/innobase/include/btr0bulk.h   |  39 +------
 storage/innobase/include/buf0buf.h    |   4 +-
 storage/innobase/include/buf0flu.h    |  90 +--------------
 storage/innobase/include/buf0flu.ic   |  10 +-
 storage/innobase/include/buf0lru.h    |   8 +-
 storage/innobase/include/buf0types.h  |   3 +-
 storage/innobase/include/fil0fil.h    |   7 --
 storage/innobase/include/mtr0log.ic   |   3 +-
 storage/innobase/include/mtr0mtr.h    |  17 +--
 storage/innobase/include/row0merge.h  |   8 +-
 storage/innobase/include/trx0trx.h    |  20 ----
 storage/innobase/mtr/mtr0mtr.cc       |  16 +--
 storage/innobase/row/row0ftsort.cc    |   8 +-
 storage/innobase/row/row0import.cc    |  13 +--
 storage/innobase/row/row0merge.cc     |  82 +-------------
 storage/innobase/row/row0quiesce.cc   |   8 +-
 storage/innobase/srv/srv0start.cc     |   8 +-
 storage/innobase/trx/trx0purge.cc     |  10 +-
 storage/innobase/trx/trx0trx.cc       |  19 +---
 27 files changed, 75 insertions(+), 613 deletions(-)

diff --git a/storage/innobase/btr/btr0bulk.cc b/storage/innobase/btr/btr0bulk.cc
index 3e170017408..f448e86add5 100644
--- a/storage/innobase/btr/btr0bulk.cc
+++ b/storage/innobase/btr/btr0bulk.cc
@@ -1,7 +1,7 @@
 /*****************************************************************************
 
 Copyright (c) 2014, 2019, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, 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
@@ -33,8 +33,6 @@ Created 03/11/2014 Shaohua Wang
 
 /** Innodb B-tree index fill factor for bulk load. */
 uint	innobase_fill_factor;
-/** whether to reduce redo logging during ALTER TABLE */
-my_bool	innodb_log_optimize_ddl;
 
 /** Initialize members, allocate page if needed and start mtr.
 Note: we commit all mtrs on failure.
@@ -51,13 +49,7 @@ PageBulk::init()
 	m_heap = mem_heap_create(1000);
 
 	m_mtr.start();
-
-	if (m_flush_observer) {
-		m_mtr.set_log_mode(MTR_LOG_NO_REDO);
-		m_mtr.set_flush_observer(m_flush_observer);
-	} else {
-		m_index->set_modified(m_mtr);
-	}
+	m_index->set_modified(m_mtr);
 
 	if (m_page_no == FIL_NULL) {
 		mtr_t	alloc_mtr;
@@ -233,7 +225,7 @@ PageBulk::insert(
 	m_heap_top += rec_size;
 	m_rec_no += 1;
 
-	if (!m_flush_observer && !m_page_zip) {
+	if (!m_page_zip) {
 		/* For ROW_FORMAT=COMPRESSED, redo log may be written
 		in PageBulk::compress(). */
 		page_cur_insert_rec_write_log(insert_rec, rec_size,
@@ -306,7 +298,7 @@ PageBulk::finish()
 	ut_ad(!dict_index_is_spatial(m_index));
 	ut_ad(!page_get_instant(m_page));
 
-	if (!m_flush_observer && !m_page_zip) {
+	if (!m_page_zip) {
 		mlog_write_ulint(PAGE_HEADER + PAGE_N_DIR_SLOTS + m_page,
 				 2 + slot_index, MLOG_2BYTES, &m_mtr);
 		mlog_write_ulint(PAGE_HEADER + PAGE_HEAP_TOP + m_page,
@@ -649,13 +641,7 @@ dberr_t
 PageBulk::latch()
 {
 	m_mtr.start();
-
-	if (m_flush_observer) {
-		m_mtr.set_log_mode(MTR_LOG_NO_REDO);
-		m_mtr.set_flush_observer(m_flush_observer);
-	} else {
-		m_index->set_modified(m_mtr);
-	}
+	m_index->set_modified(m_mtr);
 
 	/* In case the block is S-latched by page_cleaner. */
 	if (!buf_page_optimistic_get(RW_X_LATCH, m_block, m_modify_clock,
@@ -698,7 +684,7 @@ BtrBulk::pageSplit(
 
 	/* 2. create a new page. */
 	PageBulk new_page_bulk(m_index, m_trx->id, FIL_NULL,
-			       page_bulk->getLevel(), m_flush_observer);
+			       page_bulk->getLevel());
 	dberr_t	err = new_page_bulk.init();
 	if (err != DB_SUCCESS) {
 		return(err);
@@ -832,7 +818,7 @@ BtrBulk::insert(
 	if (level + 1 > m_page_bulks.size()) {
 		PageBulk*	new_page_bulk
 			= UT_NEW_NOKEY(PageBulk(m_index, m_trx->id, FIL_NULL,
-						level, m_flush_observer));
+						level));
 		err = new_page_bulk->init();
 		if (err != DB_SUCCESS) {
 			UT_DELETE(new_page_bulk);
@@ -886,8 +872,7 @@ BtrBulk::insert(
 		/* Create a sibling page_bulk. */
 		PageBulk*	sibling_page_bulk;
 		sibling_page_bulk = UT_NEW_NOKEY(PageBulk(m_index, m_trx->id,
-							  FIL_NULL, level,
-							  m_flush_observer));
+							  FIL_NULL, level));
 		err = sibling_page_bulk->init();
 		if (err != DB_SUCCESS) {
 			UT_DELETE(sibling_page_bulk);
@@ -912,10 +897,6 @@ BtrBulk::insert(
 		/* Important: log_free_check whether we need a checkpoint. */
 		if (page_is_leaf(sibling_page_bulk->getPage())) {
 			if (trx_is_interrupted(m_trx)) {
-				if (m_flush_observer) {
-					m_flush_observer->interrupted();
-				}
-
 				err = DB_INTERRUPTED;
 				goto func_exit;
 			}
@@ -1009,8 +990,7 @@ BtrBulk::finish(dberr_t	err)
 		mtr_t		mtr;
 		buf_block_t*	last_block;
 		PageBulk	root_page_bulk(m_index, m_trx->id,
-					       m_index->page, m_root_level,
-					       m_flush_observer);
+					       m_index->page, m_root_level);
 
 		mtr.start();
 		m_index->set_modified(mtr);
@@ -1036,9 +1016,6 @@ BtrBulk::finish(dberr_t	err)
 		/* Remove last page. */
 		btr_page_free(m_index, last_block, &mtr);
 
-		/* Do not flush the last page. */
-		last_block->page.flush_observer = NULL;
-
 		mtr.commit();
 
 		err = pageCommit(&root_page_bulk, NULL, false);
diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc
index c79ea1c5467..b6f688792f6 100644
--- a/storage/innobase/btr/btr0cur.cc
+++ b/storage/innobase/btr/btr0cur.cc
@@ -7137,7 +7137,6 @@ struct btr_blob_log_check_t {
 		dict_index_t*	index = m_pcur->index();
 		ulint		offs = 0;
 		ulint		page_no = ULINT_UNDEFINED;
-		FlushObserver*	observer = m_mtr->get_flush_observer();
 
 		if (UNIV_UNLIKELY(m_op == BTR_STORE_INSERT_BULK)) {
 			offs = page_offset(*m_rec);
@@ -7160,7 +7159,6 @@ struct btr_blob_log_check_t {
 		m_mtr->start();
 		m_mtr->set_log_mode(log_mode);
 		index->set_modified(*m_mtr);
-		m_mtr->set_flush_observer(observer);
 
 		if (UNIV_UNLIKELY(m_op == BTR_STORE_INSERT_BULK)) {
 			m_pcur->btr_cur.page_cur.block = btr_block_get(
@@ -7363,7 +7361,6 @@ btr_store_big_rec_extern_fields(
 			mtr.start();
 			index->set_modified(mtr);
 			mtr.set_log_mode(btr_mtr->get_log_mode());
-			mtr.set_flush_observer(btr_mtr->get_flush_observer());
 
 			buf_page_get(rec_block->page.id,
 				     rec_block->page.size, RW_X_LATCH, &mtr);
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc
index 6fc01a9491f..c37815e9209 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -2,7 +2,7 @@
 
 Copyright (c) 1995, 2018, Oracle and/or its affiliates. All Rights Reserved.
 Copyright (c) 2008, Google Inc.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
 
 Portions of this file contain modifications contributed and copyrighted by
 Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -1543,7 +1543,6 @@ buf_block_init(
 	block->page.state = BUF_BLOCK_NOT_USED;
 	block->page.buf_fix_count = 0;
 	block->page.io_fix = BUF_IO_NONE;
-	block->page.flush_observer = NULL;
 	block->page.real_size = 0;
 	block->page.write_size = 0;
 	block->modify_clock = 0;
@@ -5547,7 +5546,6 @@ buf_page_init_for_read(
 
 		bpage->state = BUF_BLOCK_ZIP_PAGE;
 		bpage->id = page_id;
-		bpage->flush_observer = NULL;
 
 		ut_d(bpage->in_page_hash = FALSE);
 		ut_d(bpage->in_zip_hash = FALSE);
diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc
index b116ca919fd..fbe6f38bc4f 100644
--- a/storage/innobase/buf/buf0flu.cc
+++ b/storage/innobase/buf/buf0flu.cc
@@ -702,14 +702,6 @@ buf_flush_remove(
 	ut_a(buf_flush_validate_skip(buf_pool));
 #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
 
-	/* If there is an observer that want to know if the asynchronous
-	flushing was done then notify it. */
-	if (bpage->flush_observer != NULL) {
-		bpage->flush_observer->notify_remove(buf_pool, bpage);
-
-		bpage->flush_observer = NULL;
-	}
-
 	buf_flush_list_mutex_exit(buf_pool);
 }
 
@@ -1240,19 +1232,6 @@ buf_flush_page(
 			rw_lock_sx_lock_gen(rw_lock, BUF_IO_WRITE);
 		}
 
-		/* If there is an observer that want to know if the asynchronous
-		flushing was sent then notify it.
-		Note: we set flush observer to a page with x-latch, so we can
-		guarantee that notify_flush and notify_remove are called in pair
-		with s-latch on a uncompressed page. */
-		if (bpage->flush_observer != NULL) {
-			buf_pool_mutex_enter(buf_pool);
-
-			bpage->flush_observer->notify_flush(buf_pool, bpage);
-
-			buf_pool_mutex_exit(buf_pool);
-		}
-
 		/* Even though bpage is not protected by any mutex at this
 		point, it is safe to access bpage, because it is io_fixed and
 		oldest_modification != 0.  Thus, it cannot be relocated in the
@@ -3676,9 +3655,7 @@ ulint
 buf_pool_get_dirty_pages_count(
 /*===========================*/
 	buf_pool_t*	buf_pool,	/*!< in: buffer pool */
-	ulint		id,		/*!< in: space id to check */
-	FlushObserver*	observer)	/*!< in: flush observer to check */
-
+	ulint		id)		/*!< in: space id to check */
 {
 	ulint		count = 0;
 
@@ -3695,10 +3672,7 @@ buf_pool_get_dirty_pages_count(
 		ut_ad(bpage->in_flush_list);
 		ut_ad(bpage->oldest_modification > 0);
 
-		if ((observer != NULL
-		     && observer == bpage->flush_observer)
-		    || (observer == NULL
-			&& id == bpage->id.space())) {
+		if (id == bpage->id.space()) {
 			++count;
 		}
 	}
@@ -3708,128 +3682,3 @@ buf_pool_get_dirty_pages_count(
 
 	return(count);
 }
-
-/******************************************************************//**
-Check if there are any dirty pages that belong to a space id in the flush list.
-@return number of dirty pages present in all the buffer pools */
-static
-ulint
-buf_flush_get_dirty_pages_count(
-/*============================*/
-	ulint		id,		/*!< in: space id to check */
-	FlushObserver*	observer)	/*!< in: flush observer to check */
-{
-	ulint		count = 0;
-
-	for (ulint i = 0; i < srv_buf_pool_instances; ++i) {
-		buf_pool_t*	buf_pool;
-
-		buf_pool = buf_pool_from_array(i);
-
-		count += buf_pool_get_dirty_pages_count(buf_pool, id, observer);
-	}
-
-	return(count);
-}
-
-/** FlushObserver constructor
-@param[in]	space		tablespace
-@param[in]	trx		trx instance
-@param[in]	stage		performance schema accounting object,
-used by ALTER TABLE. It is passed to log_preflush_pool_modified_pages()
-for accounting. */
-FlushObserver::FlushObserver(
-	fil_space_t*		space,
-	trx_t*			trx,
-	ut_stage_alter_t*	stage)
-	:
-	m_space(space),
-	m_trx(trx),
-	m_stage(stage),
-	m_interrupted(false)
-{
-	m_flushed = UT_NEW_NOKEY(std::vector<ulint>(srv_buf_pool_instances));
-	m_removed = UT_NEW_NOKEY(std::vector<ulint>(srv_buf_pool_instances));
-
-	for (ulint i = 0; i < srv_buf_pool_instances; i++) {
-		m_flushed->at(i) = 0;
-		m_removed->at(i) = 0;
-	}
-
-	DBUG_LOG("flush", "FlushObserver(): trx->id=" << m_trx->id);
-}
-
-/** FlushObserver deconstructor */
-FlushObserver::~FlushObserver()
-{
-	ut_ad(buf_flush_get_dirty_pages_count(m_space->id, this) == 0);
-
-	UT_DELETE(m_flushed);
-	UT_DELETE(m_removed);
-
-	DBUG_LOG("flush", "~FlushObserver(): trx->id=" << m_trx->id);
-}
-
-/** Check whether the operation has been interrupted */
-void FlushObserver::check_interrupted()
-{
-	if (trx_is_interrupted(m_trx)) {
-		interrupted();
-	}
-}
-
-/** Notify observer of a flush
-@param[in]	buf_pool	buffer pool instance
-@param[in]	bpage		buffer page to flush */
-void
-FlushObserver::notify_flush(
-	buf_pool_t*	buf_pool,
-	buf_page_t*	bpage)
-{
-	ut_ad(buf_pool_mutex_own(buf_pool));
-
-	m_flushed->at(buf_pool->instance_no)++;
-
-	if (m_stage != NULL) {
-		m_stage->inc();
-	}
-
-	DBUG_LOG("flush", "Flush " << bpage->id);
-}
-
-/** Notify observer of a remove
-@param[in]	buf_pool	buffer pool instance
-@param[in]	bpage		buffer page flushed */
-void
-FlushObserver::notify_remove(
-	buf_pool_t*	buf_pool,
-	buf_page_t*	bpage)
-{
-	ut_ad(buf_pool_mutex_own(buf_pool));
-
-	m_removed->at(buf_pool->instance_no)++;
-
-	DBUG_LOG("flush", "Remove " << bpage->id);
-}
-
-/** Flush dirty pages and wait. */
-void
-FlushObserver::flush()
-{
-	ut_ad(m_trx);
-
-	if (!m_interrupted && m_stage) {
-		m_stage->begin_phase_flush(buf_flush_get_dirty_pages_count(
-						   m_space->id, this));
-	}
-
-	buf_LRU_flush_or_remove_pages(m_space->id, this);
-
-	/* Wait for all dirty pages were flushed. */
-	for (ulint i = 0; i < srv_buf_pool_instances; i++) {
-		while (!is_complete(i)) {
-
-			os_thread_sleep(2000);
-		}
-	}
-}
diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc
index cfe3f9a6bcb..24857d97f30 100644
--- a/storage/innobase/buf/buf0lru.cc
+++ b/storage/innobase/buf/buf0lru.cc
@@ -1,7 +1,7 @@
 /*****************************************************************************
 
 Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, 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
@@ -466,19 +466,13 @@ buf_flush_try_yield(
 	return(false);
 }
 
-/******************************************************************//**
-Removes a single page from a given tablespace inside a specific
-buffer pool instance.
+/** Remove a single page from flush_list.
+@param[in,out]	buf_pool	buffer pool
+@param[in,out]	bpage		buffer page to remove
+@param[in]	flush		whether to flush the page before removing
 @return true if page was removed. */
-static	MY_ATTRIBUTE((warn_unused_result))
-bool
-buf_flush_or_remove_page(
-/*=====================*/
-	buf_pool_t*	buf_pool,	/*!< in/out: buffer pool instance */
-	buf_page_t*	bpage,		/*!< in/out: bpage to remove */
-	bool		flush)		/*!< in: flush to disk if true but
-					don't remove else remove without
-					flushing to disk */
+static bool buf_flush_or_remove_page(buf_pool_t* buf_pool, buf_page_t* bpage,
+				     bool flush)
 {
 	ut_ad(buf_pool_mutex_own(buf_pool));
 	ut_ad(buf_flush_list_mutex_own(buf_pool));
@@ -554,17 +548,11 @@ tablespace. The pages still remain a part of LRU and are evicted from
 the list as they age towards the tail of the LRU.
 @param[in,out]	buf_pool	buffer pool
 @param[in]	id		tablespace identifier
-@param[in]	observer	flush observer (to check for interrupt),
-				or NULL if the files should not be written to
+@param[in]	flush		whether to flush the pages before removing
 @param[in]	first		first page to be flushed or evicted
 @return	whether all matching dirty pages were removed */
-static	MY_ATTRIBUTE((warn_unused_result))
-bool
-buf_flush_or_remove_pages(
-	buf_pool_t*	buf_pool,
-	ulint		id,
-	FlushObserver*	observer,
-	ulint		first)
+static bool buf_flush_or_remove_pages(buf_pool_t* buf_pool, ulint id,
+				      bool flush, ulint first)
 {
 	buf_page_t*	prev;
 	buf_page_t*	bpage;
@@ -586,36 +574,19 @@ buf_flush_or_remove_pages(
 
 		prev = UT_LIST_GET_PREV(list, bpage);
 
-		/* Flush the pages matching space id,
-		or pages matching the flush observer. */
-		if (observer && observer->is_partial_flush()) {
-			if (observer != bpage->flush_observer) {
-				/* Skip this block. */
-			} else if (!buf_flush_or_remove_page(
-					   buf_pool, bpage,
-					   !observer->is_interrupted())) {
-				all_freed = false;
-			} else if (!observer->is_interrupted()) {
-				/* The processing was successful. And during the
-				processing we have released the buf_pool mutex
-				when calling buf_page_flush(). We cannot trust
-				prev pointer. */
-				goto rescan;
-			}
-		} else if (id != bpage->id.space()) {
+		if (id != bpage->id.space()) {
 			/* Skip this block, because it is for a
 			different tablespace. */
 		} else if (bpage->id.page_no() < first) {
 			/* Skip this block, because it is below the limit. */
-		} else if (!buf_flush_or_remove_page(
-				   buf_pool, bpage, observer != NULL)) {
+		} else if (!buf_flush_or_remove_page(buf_pool, bpage, flush)) {
 
 			/* Remove was unsuccessful, we have to try again
 			by scanning the entire list from the end.
 			This also means that we never released the
 			buf_pool mutex. Therefore we can trust the prev
 			pointer.
-			buf_flush_or_remove_page() released the
+			buf_remove_page() released the
 			flush list mutex but not the buf_pool mutex.
 			Therefore it is possible that a new page was
 			added to the flush list. For example, in case
@@ -631,7 +602,7 @@ buf_flush_or_remove_pages(
 			iteration. */
 
 			all_freed = false;
-		} else if (observer) {
+		} else if (flush) {
 
 			/* The processing was successful. And during the
 			processing we have released the buf_pool mutex
@@ -649,12 +620,6 @@ buf_flush_or_remove_pages(
 
 			processed = 0;
 		}
-
-		/* The check for trx is interrupted is expensive, we want
-		to check every N iterations. */
-		if (!processed && observer) {
-			observer->check_interrupted();
-		}
 	}
 
 	buf_flush_list_mutex_exit(buf_pool);
@@ -668,21 +633,15 @@ list and will be evicted from the LRU list as they age and move towards
 the tail of the LRU list.
 @param[in,out]	buf_pool	buffer pool
 @param[in]	id		tablespace identifier
-@param[in]	observer	flush observer,
-				or NULL if the files should not be written to
+@param[in]	flush		whether to flush the pages before removing
 @param[in]	first		first page to be flushed or evicted */
-static
-void
-buf_flush_dirty_pages(
-	buf_pool_t*	buf_pool,
-	ulint		id,
-	FlushObserver*	observer,
-	ulint		first)
+static void buf_flush_dirty_pages(buf_pool_t* buf_pool, ulint id, bool flush,
+				  ulint first)
 {
 	for (;;) {
 		buf_pool_mutex_enter(buf_pool);
 
-		bool freed = buf_flush_or_remove_pages(buf_pool, id, observer,
+		bool freed = buf_flush_or_remove_pages(buf_pool, id, flush,
 						       first);
 
 		buf_pool_mutex_exit(buf_pool);
@@ -697,28 +656,25 @@ buf_flush_dirty_pages(
 		ut_ad(buf_flush_validate(buf_pool));
 	}
 
-	ut_ad((observer && observer->is_interrupted())
-	      || first
-	      || buf_pool_get_dirty_pages_count(buf_pool, id, observer) == 0);
+	ut_ad(first
+	      || buf_pool_get_dirty_pages_count(buf_pool, id) == 0);
 }
 
 /** Empty the flush list for all pages belonging to a tablespace.
 @param[in]	id		tablespace identifier
-@param[in]	observer	flush observer,
-				or NULL if nothing is to be written
+@param[in]	flush		whether to write the pages to files
 @param[in]	first		first page to be flushed or evicted */
-void buf_LRU_flush_or_remove_pages(ulint id, FlushObserver* observer,
-				   ulint first)
+void buf_LRU_flush_or_remove_pages(ulint id, bool flush, ulint first)
 {
 	/* Pages in the system tablespace must never be discarded. */
-	ut_ad(id || observer);
+	ut_ad(id || flush);
 
 	for (ulint i = 0; i < srv_buf_pool_instances; i++) {
-		buf_flush_dirty_pages(buf_pool_from_array(i), id, observer,
+		buf_flush_dirty_pages(buf_pool_from_array(i), id, flush,
 				      first);
 	}
 
-	if (observer && !observer->is_interrupted()) {
+	if (flush) {
 		/* Ensure that all asynchronous IO is completed. */
 		os_aio_wait_until_no_pending_writes();
 		fil_flush(id);
@@ -1108,7 +1064,6 @@ buf_LRU_get_free_block(
 		memset(&block->page.zip, 0, sizeof block->page.zip);
 
 		block->skip_flush_check = false;
-		block->page.flush_observer = NULL;
 		return(block);
 	}
 
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index 434490c002c..d092ba47281 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -2456,11 +2456,7 @@ fil_close_tablespace(
 	buffer pool. Thus we can clean the tablespace out of the buffer pool
 	completely and permanently. The flag stop_new_ops also prevents
 	fil_flush() from being applied to this tablespace. */
-
-	{
-		FlushObserver observer(space, trx, NULL);
-		buf_LRU_flush_or_remove_pages(id, &observer);
-	}
+	buf_LRU_flush_or_remove_pages(id, true);
 
 	/* If the free is successful, the X lock will be released before
 	the space memory data structure is freed. */
diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc
index 6942b1f4730..f92d811b178 100644
--- a/storage/innobase/fsp/fsp0fsp.cc
+++ b/storage/innobase/fsp/fsp0fsp.cc
@@ -1,7 +1,7 @@
 /*****************************************************************************
 
 Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, 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
@@ -612,7 +612,6 @@ void fil_space_t::modify_check(const mtr_t& mtr) const
 	case MTR_LOG_NO_REDO:
 		ut_ad(purpose == FIL_TYPE_TEMPORARY
 		      || purpose == FIL_TYPE_IMPORT
-		      || my_atomic_loadlint(&redo_skipped_count)
 		      || is_being_truncated
 		      || srv_is_tablespace_truncated(id));
 		return;
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 79051b9c247..9a0f133983b 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -19493,13 +19493,6 @@ static MYSQL_SYSVAR_BOOL(log_compressed_pages, page_zip_log_pages,
   " compression algorithm doesn't change.",
   NULL, NULL, TRUE);
 
-static MYSQL_SYSVAR_BOOL(log_optimize_ddl, innodb_log_optimize_ddl,
-  PLUGIN_VAR_OPCMDARG,
-  "Reduce redo logging when natively creating indexes or rebuilding tables."
-  " Setting this OFF avoids delay due to page flushing and"
-  " allows concurrent backup.",
-  NULL, NULL, TRUE);
-
 static MYSQL_SYSVAR_ULONG(autoextend_increment,
   sys_tablespace_auto_extend_increment,
   PLUGIN_VAR_RQCMDARG,
@@ -20418,7 +20411,6 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
   MYSQL_SYSVAR(log_write_ahead_size),
   MYSQL_SYSVAR(log_group_home_dir),
   MYSQL_SYSVAR(log_compressed_pages),
-  MYSQL_SYSVAR(log_optimize_ddl),
   MYSQL_SYSVAR(max_dirty_pages_pct),
   MYSQL_SYSVAR(max_dirty_pages_pct_lwm),
   MYSQL_SYSVAR(adaptive_flushing_lwm),
diff --git a/storage/innobase/include/btr0bulk.h b/storage/innobase/include/btr0bulk.h
index 9384cb578ed..c0c18d1ea67 100644
--- a/storage/innobase/include/btr0bulk.h
+++ b/storage/innobase/include/btr0bulk.h
@@ -1,7 +1,7 @@
 /*****************************************************************************
 
 Copyright (c) 2014, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2019, MariaDB Corporation.
+Copyright (c) 2019, 2020, 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
@@ -55,14 +55,12 @@ class PageBulk
 	@param[in]	index		B-tree index
 	@param[in]	page_no		page number
 	@param[in]	level		page level
-	@param[in]	trx_id		transaction id
-	@param[in]	observer	flush observer */
+	@param[in]	trx_id		transaction id */
 	PageBulk(
 		dict_index_t*	index,
 		trx_id_t	trx_id,
 		ulint		page_no,
-		ulint		level,
-		FlushObserver*	observer)
+		ulint		level)
 		:
 		m_heap(NULL),
 		m_index(index),
@@ -83,7 +81,6 @@ class PageBulk
 		m_total_data(0),
 #endif /* UNIV_DEBUG */
 		m_modify_clock(0),
-		m_flush_observer(observer),
 		m_err(DB_SUCCESS)
 	{
 		ut_ad(!dict_index_is_spatial(m_index));
@@ -260,9 +257,6 @@ class PageBulk
 	when the block is re-pinned */
 	ib_uint64_t     m_modify_clock;
 
-	/** Flush observer, or NULL if redo logging is enabled */
-	FlushObserver*	m_flush_observer;
-
 	/** Operation result DB_SUCCESS or error code */
 	dberr_t		m_err;
 };
@@ -275,33 +269,15 @@ class BtrBulk
 public:
 	/** Constructor
 	@param[in]	index		B-tree index
-	@param[in]	trx		transaction
-	@param[in]	observer	flush observer */
+	@param[in]	trx		transaction */
 	BtrBulk(
 		dict_index_t*	index,
-		const trx_t*	trx,
-		FlushObserver*	observer)
+		const trx_t*	trx)
 		:
 		m_index(index),
-		m_trx(trx),
-		m_flush_observer(observer)
+		m_trx(trx)
 	{
 		ut_ad(!dict_index_is_spatial(index));
-#ifdef UNIV_DEBUG
-		if (m_flush_observer)
-		my_atomic_addlint(&m_index->table->space->redo_skipped_count,
-				  1);
-#endif /* UNIV_DEBUG */
-	}
-
-	/** Destructor */
-	~BtrBulk()
-	{
-#ifdef UNIV_DEBUG
-		if (m_flush_observer)
-		my_atomic_addlint(&m_index->table->space->redo_skipped_count,
-				  ulint(-1));
-#endif /* UNIV_DEBUG */
 	}
 
 	/** Insert a tuple
@@ -373,9 +349,6 @@ class BtrBulk
 	/** Root page level */
 	ulint			m_root_level;
 
-	/** Flush observer, or NULL if redo logging is enabled */
-	FlushObserver*const	m_flush_observer;
-
 	/** Page cursor vector for all level */
 	page_bulk_vector	m_page_bulks;
 };
diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
index c9529ee4b73..04cdec7cb44 100644
--- a/storage/innobase/include/buf0buf.h
+++ b/storage/innobase/include/buf0buf.h
@@ -1,7 +1,7 @@
 /*****************************************************************************
 
 Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, 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
@@ -1552,8 +1552,6 @@ class buf_page_t {
 					== (state == BUF_BLOCK_NOT_USED) */
 #endif /* UNIV_DEBUG */
 
-	FlushObserver*	flush_observer;	/*!< flush observer */
-
 	lsn_t		newest_modification;
 					/*!< log sequence number of
 					the youngest modification to
diff --git a/storage/innobase/include/buf0flu.h b/storage/innobase/include/buf0flu.h
index a0122d1c3f8..a27bd79578a 100644
--- a/storage/innobase/include/buf0flu.h
+++ b/storage/innobase/include/buf0flu.h
@@ -1,7 +1,7 @@
 /*****************************************************************************
 
 Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2014, 2018, MariaDB Corporation.
+Copyright (c) 2014, 2020, 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
@@ -178,9 +178,8 @@ buf_flush_note_modification(
 	buf_block_t*	block,		/*!< in: block which is modified */
 	lsn_t		start_lsn,	/*!< in: start lsn of the first mtr in a
 					set of mtr's */
-	lsn_t		end_lsn,	/*!< in: end lsn of the last mtr in the
+	lsn_t		end_lsn);	/*!< in: end lsn of the last mtr in the
 					set of mtr's */
-	FlushObserver*	observer);	/*!< in: flush observer */
 
 /********************************************************************//**
 This function should be called when recovery has modified a buffer page. */
@@ -303,8 +302,7 @@ ulint
 buf_pool_get_dirty_pages_count(
 /*===========================*/
 	buf_pool_t*	buf_pool,	/*!< in: buffer pool */
-	ulint		id,		/*!< in: space id to check */
-	FlushObserver*	observer);	/*!< in: flush observer to check */
+	ulint		id);		/*!< in: space id to check */
 
 /*******************************************************************//**
 Synchronously flush dirty blocks from the end of the flush list of all buffer
@@ -320,88 +318,6 @@ void
 buf_flush_request_force(
 	lsn_t	lsn_limit);
 
-/** We use FlushObserver to track flushing of non-redo logged pages in bulk
-create index(BtrBulk.cc).Since we disable redo logging during a index build,
-we need to make sure that all dirty pages modifed by the index build are
-flushed to disk before any redo logged operations go to the index. */
-
-class FlushObserver {
-public:
-	/** Constructor
-	@param[in,out]	space		tablespace
-	@param[in]	trx		trx instance
-	@param[in]	stage		performance schema accounting object,
-	used by ALTER TABLE. It is passed to log_preflush_pool_modified_pages()
-	for accounting. */
-	FlushObserver(fil_space_t* space, trx_t* trx, ut_stage_alter_t* stage);
-
-	/** Deconstructor */
-	~FlushObserver();
-
-	/** Check pages have been flushed and removed from the flush list
-	in a buffer pool instance.
-	@param[in]	instance_no	buffer pool instance no
-	@return true if the pages were removed from the flush list */
-	bool is_complete(ulint	instance_no)
-	{
-		return(m_flushed->at(instance_no) == m_removed->at(instance_no)
-		       || m_interrupted);
-	}
-
-	/** @return whether to flush only some pages of the tablespace */
-	bool is_partial_flush() const { return m_stage != NULL; }
-
-	/** @return whether the operation was interrupted */
-	bool is_interrupted() const { return m_interrupted; }
-
-	/** Interrupt observer not to wait. */
-	void interrupted()
-	{
-		m_interrupted = true;
-	}
-
-	/** Check whether the operation has been interrupted */
-	void check_interrupted();
-
-	/** Flush dirty pages. */
-	void flush();
-	/** Notify observer of flushing a page
-	@param[in]	buf_pool	buffer pool instance
-	@param[in]	bpage		buffer page to flush */
-	void notify_flush(
-		buf_pool_t*	buf_pool,
-		buf_page_t*	bpage);
-
-	/** Notify observer of removing a page from flush list
-	@param[in]	buf_pool	buffer pool instance
-	@param[in]	bpage		buffer page flushed */
-	void notify_remove(
-		buf_pool_t*	buf_pool,
-		buf_page_t*	bpage);
-private:
-	/** Tablespace */
-	fil_space_t*		m_space;
-
-	/** Trx instance */
-	const trx_t* const	m_trx;
-
-	/** Performance schema accounting object, used by ALTER TABLE.
-	If not NULL, then stage->begin_phase_flush() will be called initially,
-	specifying the number of pages to be attempted to be flushed and
-	subsequently, stage->inc() will be called for each page we attempt to
-	flush. */
-	ut_stage_alter_t*	m_stage;
-
-	/* Flush request sent */
-	std::vector<ulint>*	m_flushed;
-
-	/* Flush request finished */
-	std::vector<ulint>*	m_removed;
-
-	/* True if the operation was interrupted. */
-	bool			m_interrupted;
-};
-
 #include "buf0flu.ic"
 
 #endif
diff --git a/storage/innobase/include/buf0flu.ic b/storage/innobase/include/buf0flu.ic
index 8d06a53c547..70769d8a0cb 100644
--- a/storage/innobase/include/buf0flu.ic
+++ b/storage/innobase/include/buf0flu.ic
@@ -1,6 +1,7 @@
 /*****************************************************************************
 
 Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2019, 2020, 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
@@ -59,9 +60,8 @@ buf_flush_note_modification(
 	buf_block_t*	block,		/*!< in: block which is modified */
 	lsn_t		start_lsn,	/*!< in: start lsn of the mtr that
 					modified this block */
-	lsn_t		end_lsn,	/*!< in: end lsn of the mtr that
+	lsn_t		end_lsn)	/*!< in: end lsn of the mtr that
 					modified this block */
-	FlushObserver*	observer)	/*!< in: flush observer */
 {
 #ifdef UNIV_DEBUG
 	{
@@ -84,12 +84,6 @@ buf_flush_note_modification(
 	ut_ad(block->page.newest_modification <= end_lsn);
 	block->page.newest_modification = end_lsn;
 
-	/* Don't allow to set flush observer from non-null to null,
-	or from one observer to another. */
-	ut_ad(block->page.flush_observer == NULL
-	      || block->page.flush_observer == observer);
-	block->page.flush_observer = observer;
-
 	if (block->page.oldest_modification == 0) {
 		buf_pool_t*	buf_pool = buf_pool_from_block(block);
 
diff --git a/storage/innobase/include/buf0lru.h b/storage/innobase/include/buf0lru.h
index 2468efb193f..2eb483381b4 100644
--- a/storage/innobase/include/buf0lru.h
+++ b/storage/innobase/include/buf0lru.h
@@ -1,7 +1,7 @@
 /*****************************************************************************
 
 Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, 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
@@ -63,11 +63,9 @@ bool buf_LRU_drop_page_hash_for_tablespace(dict_table_t* table)
 
 /** Empty the flush list for all pages belonging to a tablespace.
 @param[in]	id		tablespace identifier
-@param[in,out]	observer	flush observer,
-				or NULL if nothing is to be written
+@param[in]	flush		whether to write the pages to files
 @param[in]	first		first page to be flushed or evicted */
-void buf_LRU_flush_or_remove_pages(ulint id, FlushObserver* observer,
-				   ulint first = 0);
+void buf_LRU_flush_or_remove_pages(ulint id, bool flush, ulint first = 0);
 
 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
 /********************************************************************//**
diff --git a/storage/innobase/include/buf0types.h b/storage/innobase/include/buf0types.h
index bd5e26df47b..897861032e5 100644
--- a/storage/innobase/include/buf0types.h
+++ b/storage/innobase/include/buf0types.h
@@ -1,6 +1,7 @@
 /*****************************************************************************
 
 Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 2020, 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
@@ -43,8 +44,6 @@ struct buf_pool_stat_t;
 struct buf_buddy_stat_t;
 /** Doublewrite memory struct */
 struct buf_dblwr_t;
-/** Flush observer for bulk create index */
-class FlushObserver;
 
 /** A buffer frame. @see page_t */
 typedef	byte	buf_frame_t;
diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
index d9840ea80f5..a63b6893109 100644
--- a/storage/innobase/include/fil0fil.h
+++ b/storage/innobase/include/fil0fil.h
@@ -107,13 +107,6 @@ struct fil_space_t : intrusive::list_node<unflushed_spaces_tag_t>,
 				batches. */
 	/** whether undo tablespace truncation is in progress */
 	bool		is_being_truncated;
-#ifdef UNIV_DEBUG
-	ulint		redo_skipped_count;
-				/*!< reference count for operations who want
-				to skip redo log in the file space in order
-				to make modify_check() pass.
-				Uses my_atomic_loadlint() and friends. */
-#endif
 	fil_type_t	purpose;/*!< purpose */
 	UT_LIST_BASE_NODE_T(fil_node_t) chain;
 				/*!< base node for the file chain */
diff --git a/storage/innobase/include/mtr0log.ic b/storage/innobase/include/mtr0log.ic
index 70bcaf43b9e..9f79e50f556 100644
--- a/storage/innobase/include/mtr0log.ic
+++ b/storage/innobase/include/mtr0log.ic
@@ -1,7 +1,7 @@
 /*****************************************************************************
 
 Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, 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
@@ -162,7 +162,6 @@ mlog_write_initial_log_record_low(
 	      || type == MLOG_FILE_DELETE
 	      || type == MLOG_FILE_CREATE2
 	      || type == MLOG_FILE_RENAME2
-	      || type == MLOG_INDEX_LOAD
 	      || type == MLOG_FILE_WRITE_CRYPT_DATA
 	      || mtr->is_named_space(space_id));
 
diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h
index 074f55971b3..29abd74f436 100644
--- a/storage/innobase/include/mtr0mtr.h
+++ b/storage/innobase/include/mtr0mtr.h
@@ -2,7 +2,7 @@
 
 Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
 Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, 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
@@ -350,18 +350,6 @@ struct mtr_t {
 	@return true if the mini-transaction is active */
 	bool is_active() const { return m_state == MTR_STATE_ACTIVE; }
 
-	/** Get flush observer
-	@return flush observer */
-	FlushObserver* get_flush_observer() const { return m_flush_observer; }
-
-	/** Set flush observer
-	@param[in]	observer	flush observer */
-	void set_flush_observer(FlushObserver*	observer)
-	{
-		ut_ad(observer == NULL || m_log_mode == MTR_LOG_NO_REDO);
-		m_flush_observer = observer;
-	}
-
 #ifdef UNIV_DEBUG
 	/** Check if memo contains the given item.
 	@param memo	memo stack
@@ -482,9 +470,6 @@ struct mtr_t {
 	/** State of the transaction */
 	mtr_state_t	m_state;
 
-	/** Flush Observer */
-	FlushObserver*	m_flush_observer;
-
 	/** LSN at commit time */
 	lsn_t		m_commit_lsn;
 };
diff --git a/storage/innobase/include/row0merge.h b/storage/innobase/include/row0merge.h
index fd9050d0a48..3ba7508911a 100644
--- a/storage/innobase/include/row0merge.h
+++ b/storage/innobase/include/row0merge.h
@@ -1,7 +1,7 @@
 /*****************************************************************************
 
 Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2019, MariaDB Corporation.
+Copyright (c) 2015, 2020, MariaDB Corporation.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -292,12 +292,6 @@ row_merge_drop_table(
 	dict_table_t*	table)		/*!< in: table instance to drop */
 	MY_ATTRIBUTE((nonnull, warn_unused_result));
 
-/** Write an MLOG_INDEX_LOAD record to indicate in the redo-log
-that redo-logging of individual index pages was disabled, and
-the flushing of such pages to the data files was completed.
-@param[in]	index	an index tree on which redo logging was disabled */
-void row_merge_write_redo(const dict_index_t* index);
-
 /** Build indexes on a table by reading a clustered index, creating a temporary
 file containing index entries, merge sorting these index entries and inserting
 sorted index entries to indexes.
diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h
index 8cd4d2018c6..382d9a5af94 100644
--- a/storage/innobase/include/trx0trx.h
+++ b/storage/innobase/include/trx0trx.h
@@ -41,7 +41,6 @@ Created 3/26/1996 Heikki Tuuri
 
 // Forward declaration
 struct mtr_t;
-class FlushObserver;
 struct rw_trx_hash_element_t;
 
 /******************************************************************//**
@@ -1035,11 +1034,6 @@ struct trx_t {
 	/*------------------------------*/
 	char*		detailed_error;	/*!< detailed error message for last
 					error, or empty. */
-private:
-	/** flush observer used to track flushing of non-redo logged pages
-	during bulk create index */
-	FlushObserver*	flush_observer;
-public:
 	/* Lock wait statistics */
 	ulint		n_rec_lock_waits;
 					/*!< Number of record lock waits,
@@ -1092,20 +1086,6 @@ struct trx_t {
 		return(assign_temp_rseg());
 	}
 
-	/** Set the innodb_log_optimize_ddl page flush observer
-	@param[in,out]	space	tablespace
-	@param[in,out]	stage	performance_schema accounting */
-	void set_flush_observer(fil_space_t* space, ut_stage_alter_t* stage);
-
-	/** Remove the flush observer */
-	void remove_flush_observer();
-
-	/** @return the flush observer */
-	FlushObserver* get_flush_observer() const
-	{
-		return flush_observer;
-	}
-
   /** Transition to committed state, to release implicit locks. */
   inline void commit_state();
 
diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc
index 14c274b5b40..bf6d489f93b 100644
--- a/storage/innobase/mtr/mtr0mtr.cc
+++ b/storage/innobase/mtr/mtr0mtr.cc
@@ -297,11 +297,10 @@ struct DebugCheck {
 /** Release a resource acquired by the mini-transaction. */
 struct ReleaseBlocks {
 	/** Release specific object */
-	ReleaseBlocks(lsn_t start_lsn, lsn_t end_lsn, FlushObserver* observer)
+	ReleaseBlocks(lsn_t start_lsn, lsn_t end_lsn)
 		:
 		m_end_lsn(end_lsn),
-		m_start_lsn(start_lsn),
-		m_flush_observer(observer)
+		m_start_lsn(start_lsn)
 	{
 		/* Do nothing */
 	}
@@ -316,8 +315,7 @@ struct ReleaseBlocks {
 
 		block = reinterpret_cast<buf_block_t*>(slot->object);
 
-		buf_flush_note_modification(block, m_start_lsn,
-					    m_end_lsn, m_flush_observer);
+		buf_flush_note_modification(block, m_start_lsn, m_end_lsn);
 	}
 
 	/** @return true always. */
@@ -340,9 +338,6 @@ struct ReleaseBlocks {
 
 	/** Mini-transaction REDO end LSN */
 	lsn_t		m_start_lsn;
-
-	/** Flush observer */
-	FlushObserver*	m_flush_observer;
 };
 
 /** Write the block contents to the REDO log */
@@ -391,7 +386,6 @@ void mtr_t::start()
   ut_d(m_user_space_id= TRX_SYS_SPACE);
   m_user_space= NULL;
   m_state= MTR_STATE_ACTIVE;
-  m_flush_observer= NULL;
   m_commit_lsn= 0;
 }
 
@@ -436,8 +430,7 @@ mtr_t::commit()
     log_mutex_exit();
 
     m_memo.for_each_block_in_reverse(CIterate<const ReleaseBlocks>
-                                     (ReleaseBlocks(start_lsn, m_commit_lsn,
-                                                    m_flush_observer)));
+                                     (ReleaseBlocks(start_lsn, m_commit_lsn)));
     if (m_made_dirty)
       log_flush_order_mutex_exit();
 
@@ -564,7 +557,6 @@ mtr_t::x_lock_space(ulint space_id, const char* file, unsigned line)
 		ut_ad(get_log_mode() != MTR_LOG_NO_REDO
 		      || space->purpose == FIL_TYPE_TEMPORARY
 		      || space->purpose == FIL_TYPE_IMPORT
-		      || my_atomic_loadlint(&space->redo_skipped_count) > 0
 		      || srv_is_tablespace_truncated(space->id));
 	}
 
diff --git a/storage/innobase/row/row0ftsort.cc b/storage/innobase/row/row0ftsort.cc
index d439d7563d9..6c913f4f4d5 100644
--- a/storage/innobase/row/row0ftsort.cc
+++ b/storage/innobase/row/row0ftsort.cc
@@ -1672,9 +1672,7 @@ row_fts_merge_insert(
 	      == UT_BITS_IN_BYTES(aux_index->n_nullable));
 
 	/* Create bulk load instance */
-	ins_ctx.btr_bulk = UT_NEW_NOKEY(
-		BtrBulk(aux_index, trx, psort_info[0].psort_common->trx
-			->get_flush_observer()));
+	ins_ctx.btr_bulk = UT_NEW_NOKEY(BtrBulk(aux_index, trx));
 
 	/* Create tuple for insert */
 	ins_ctx.tuple = dtuple_create(heap, dict_index_get_n_fields(aux_index));
@@ -1807,9 +1805,5 @@ row_fts_merge_insert(
 		ib::info() << "InnoDB_FTS: inserted " << count << " records";
 	}
 
-	if (psort_info[0].psort_common->trx->get_flush_observer()) {
-		row_merge_write_redo(aux_index);
-	}
-
 	return(error);
 }
diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc
index 268d196036a..2657c0cc66d 100644
--- a/storage/innobase/row/row0import.cc
+++ b/storage/innobase/row/row0import.cc
@@ -4164,18 +4164,7 @@ row_import_for_mysql(
 	/* Ensure that all pages dirtied during the IMPORT make it to disk.
 	The only dirty pages generated should be from the pessimistic purge
 	of delete marked records that couldn't be purged in Phase I. */
-
-	{
-		FlushObserver observer(prebuilt->table->space, trx, NULL);
-		buf_LRU_flush_or_remove_pages(prebuilt->table->space_id,
-					      &observer);
-
-		if (observer.is_interrupted()) {
-			ib::info() << "Phase III - Flush interrupted";
-			return(row_import_error(prebuilt, trx,
-						DB_INTERRUPTED));
-		}
-	}
+	buf_LRU_flush_or_remove_pages(prebuilt->table->space_id, true);
 
 	ib::info() << "Phase IV - Flush complete";
 	prebuilt->table->space->set_imported();
diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc
index 68166705a3b..1c4ab88c374 100644
--- a/storage/innobase/row/row0merge.cc
+++ b/storage/innobase/row/row0merge.cc
@@ -2363,15 +2363,6 @@ row_merge_read_clustered_index(
 					conv_heap, &err,
 					&v_heap, eval_table, trx)))) {
 
-				/* Set the page flush observer for the
-				transaction when buffering the very first
-				record for a non-redo-logged operation. */
-				if (file->n_rec == 0 && i == 0
-				    && innodb_log_optimize_ddl) {
-					trx->set_flush_observer(
-						new_table->space, stage);
-				}
-
 				/* If we are creating FTS index,
 				a single row can generate more
 				records for tokenized word */
@@ -2510,8 +2501,7 @@ row_merge_read_clustered_index(
 					if (clust_btr_bulk == NULL) {
 						clust_btr_bulk = UT_NEW_NOKEY(
 							BtrBulk(index[i],
-								trx,
-								trx->get_flush_observer()));
+								trx));
 					} else {
 						clust_btr_bulk->latch();
 					}
@@ -2625,9 +2615,7 @@ row_merge_read_clustered_index(
 						trx->error_key_num = i;
 						goto all_done;);
 
-					BtrBulk	btr_bulk(
-						index[i], trx,
-						trx->get_flush_observer());
+					BtrBulk	btr_bulk(index[i], trx);
 
 					err = row_merge_insert_index_tuples(
 						index[i], old_table,
@@ -4494,26 +4482,6 @@ row_merge_drop_table(
 			trx, SQLCOM_DROP_TABLE, false, false));
 }
 
-/** Write an MLOG_INDEX_LOAD record to indicate in the redo-log
-that redo-logging of individual index pages was disabled, and
-the flushing of such pages to the data files was completed.
-@param[in]	index	an index tree on which redo logging was disabled */
-void row_merge_write_redo(const dict_index_t* index)
-{
-	ut_ad(!index->table->is_temporary());
-	ut_ad(!(index->type & (DICT_SPATIAL | DICT_FTS)));
-
-	mtr_t mtr;
-	mtr.start();
-	byte* log_ptr = mlog_open(&mtr, 11 + 8);
-	log_ptr = mlog_write_initial_log_record_low(
-		MLOG_INDEX_LOAD,
-		index->table->space_id, index->page, log_ptr, &mtr);
-	mach_write_to_8(log_ptr, index->id);
-	mlog_close(&mtr, log_ptr + 8);
-	mtr.commit();
-}
-
 /** Build indexes on a table by reading a clustered index, creating a temporary
 file containing index entries, merge sorting these index entries and inserting
 sorted index entries to indexes.
@@ -4866,8 +4834,7 @@ row_merge_build_indexes(
 				os_thread_sleep(20000000););  /* 20 sec */
 
 			if (error == DB_SUCCESS) {
-				BtrBulk	btr_bulk(sort_idx, trx,
-						 trx->get_flush_observer());
+				BtrBulk	btr_bulk(sort_idx, trx);
 
 				pct_cost = (COST_BUILD_INDEX_STATIC +
 					(total_dynamic_cost * merge_files[k].offset /
@@ -4913,21 +4880,10 @@ row_merge_build_indexes(
 		if (indexes[i]->type & DICT_FTS) {
 			row_fts_psort_info_destroy(psort_info, merge_info);
 			fts_psort_initiated = false;
-		} else if (dict_index_is_spatial(indexes[i])) {
-			/* We never disable redo logging for
-			creating SPATIAL INDEX. Avoid writing any
-			unnecessary MLOG_INDEX_LOAD record. */
 		} else if (old_table != new_table) {
 			ut_ad(!sort_idx->online_log);
 			ut_ad(sort_idx->online_status
 			      == ONLINE_INDEX_COMPLETE);
-		} else if (FlushObserver* flush_observer =
-			   trx->get_flush_observer()) {
-			if (error != DB_SUCCESS) {
-				flush_observer->interrupted();
-			}
-			flush_observer->flush();
-			row_merge_write_redo(indexes[i]);
 		}
 
 		if (old_table != new_table
@@ -5028,37 +4984,5 @@ row_merge_build_indexes(
 	}
 
 	DBUG_EXECUTE_IF("ib_index_crash_after_bulk_load", DBUG_SUICIDE(););
-
-	if (FlushObserver* flush_observer = trx->get_flush_observer()) {
-
-		DBUG_EXECUTE_IF("ib_index_build_fail_before_flush",
-			error = DB_INTERRUPTED;
-		);
-
-		if (error != DB_SUCCESS) {
-			flush_observer->interrupted();
-		}
-
-		flush_observer->flush();
-
-		if (old_table != new_table) {
-			for (const dict_index_t* index
-				     = dict_table_get_first_index(new_table);
-			     index != NULL;
-			     index = dict_table_get_next_index(index)) {
-				if (!(index->type
-				      & (DICT_FTS | DICT_SPATIAL))) {
-					row_merge_write_redo(index);
-				}
-			}
-		}
-
-		trx->remove_flush_observer();
-
-		if (trx_is_interrupted(trx)) {
-			error = DB_INTERRUPTED;
-		}
-	}
-
 	DBUG_RETURN(error);
 }
diff --git a/storage/innobase/row/row0quiesce.cc b/storage/innobase/row/row0quiesce.cc
index 94a372bd046..5da60e7729b 100644
--- a/storage/innobase/row/row0quiesce.cc
+++ b/storage/innobase/row/row0quiesce.cc
@@ -1,7 +1,7 @@
 /*****************************************************************************
 
 Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
+Copyright (c) 2017, 2020, 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
@@ -536,11 +536,7 @@ row_quiesce_table_start(
 	}
 
 	if (!trx_is_interrupted(trx)) {
-		{
-			FlushObserver observer(table->space, trx, NULL);
-			buf_LRU_flush_or_remove_pages(table->space_id,
-						      &observer);
-		}
+		buf_LRU_flush_or_remove_pages(table->space_id, true);
 
 		if (trx_is_interrupted(trx)) {
 
diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc
index 15b4ab8395c..5c29e493719 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, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
 
 Portions of this file contain modifications contributed and copyrighted by
 Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -1056,10 +1056,8 @@ srv_undo_tablespaces_init(bool create_new_db)
 			     = undo::Truncate::s_fix_up_spaces.begin();
 		     it != undo::Truncate::s_fix_up_spaces.end();
 		     ++it) {
-			FlushObserver dummy(fil_system.sys_space, NULL, NULL);
-			buf_LRU_flush_or_remove_pages(TRX_SYS_SPACE, &dummy);
-			FlushObserver dummy2(fil_space_get(*it), NULL, NULL);
-			buf_LRU_flush_or_remove_pages(*it, &dummy2);
+			buf_LRU_flush_or_remove_pages(TRX_SYS_SPACE, true);
+			buf_LRU_flush_or_remove_pages(*it, true);
 
 			/* Remove the truncate redo log file. */
 			undo::done(*it);
diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc
index cd1a57998f3..48df8fa5419 100644
--- a/storage/innobase/trx/trx0purge.cc
+++ b/storage/innobase/trx/trx0purge.cc
@@ -1,7 +1,7 @@
 /*****************************************************************************
 
 Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, 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
@@ -941,13 +941,7 @@ trx_purge_initiate_truncate(
 	mini-transaction commit and the server was killed, then
 	discarding the to-be-trimmed pages without flushing would
 	break crash recovery. So, we cannot avoid the write. */
-	{
-		FlushObserver observer(
-			space,
-			UT_LIST_GET_FIRST(purge_sys.query->thrs)->graph->trx,
-			NULL);
-		buf_LRU_flush_or_remove_pages(space_id, &observer);
-	}
+	buf_LRU_flush_or_remove_pages(space_id, true);
 
 	log_free_check();
 
diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc
index 359ea694536..316104edd4b 100644
--- a/storage/innobase/trx/trx0trx.cc
+++ b/storage/innobase/trx/trx0trx.cc
@@ -1,7 +1,7 @@
 /*****************************************************************************
 
 Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2019, MariaDB Corporation.
+Copyright (c) 2015, 2020, 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
@@ -161,8 +161,6 @@ trx_init(
 	trx->lock.rec_cached = 0;
 
 	trx->lock.table_cached = 0;
-
-	ut_ad(trx->get_flush_observer() == NULL);
 }
 
 /** For managing the life-cycle of the trx_t instance that we get
@@ -897,21 +895,6 @@ static trx_rseg_t* trx_assign_rseg_low()
 	return(rseg);
 }
 
-/** Set the innodb_log_optimize_ddl page flush observer
-@param[in,out]	space	tablespace
-@param[in,out]	stage	performance_schema accounting */
-void trx_t::set_flush_observer(fil_space_t* space, ut_stage_alter_t* stage)
-{
-	flush_observer = UT_NEW_NOKEY(FlushObserver(space, this, stage));
-}
-
-/** Remove the flush observer */
-void trx_t::remove_flush_observer()
-{
-	UT_DELETE(flush_observer);
-	flush_observer = NULL;
-}
-
 /** Assign a rollback segment for modifying temporary tables.
 @return the assigned rollback segment */
 trx_rseg_t*
-- 
2.25.0

