From 796d03f54fea7d5236fa6f922b600cbec958d10b Mon Sep 17 00:00:00 2001
From: Vlad Lesin <vlad_lesin@mail.ru>
Date: Thu, 28 Nov 2019 01:16:22 +0300
Subject: [PATCH] Add some extra logging to catch the case when page is written
 with wrong offset.

---
 extra/mariabackup/write_filt.cc | 17 +++++++++++++++++
 extra/mariabackup/write_filt.h  |  1 +
 extra/mariabackup/xtrabackup.cc | 14 ++++++++------
 storage/innobase/fil/fil0fil.cc | 24 ++++++++++++++++++++++++
 4 files changed, 50 insertions(+), 6 deletions(-)

diff --git a/extra/mariabackup/write_filt.cc b/extra/mariabackup/write_filt.cc
index 75ddf9fa99e..27b298048ab 100644
--- a/extra/mariabackup/write_filt.cc
+++ b/extra/mariabackup/write_filt.cc
@@ -199,6 +199,7 @@ wf_wt_init(xb_write_filt_ctxt_t *ctxt, char *dst_name __attribute__((unused)),
 	   xb_fil_cur_t *cursor)
 {
 	ctxt->cursor = cursor;
+	ctxt->dst_page = 0;
 
 	return(TRUE);
 }
@@ -212,6 +213,22 @@ wf_wt_process(xb_write_filt_ctxt_t *ctxt, ds_file_t *dstfile)
 {
 	xb_fil_cur_t			*cursor = ctxt->cursor;
 
+	if (cursor->node->space->id != SRV_LOG_SPACE_FIRST_ID &&
+			fil_is_user_tablespace_id(cursor->node->space->id)) {
+		ulint				i;
+		byte				*page;
+		const ulint			page_size
+			= cursor->page_size.physical();
+		for (i = 0, page = cursor->buf; i < cursor->buf_npages;
+				i++, page += page_size) {
+			if (mach_read_from_4(page + FIL_PAGE_OFFSET) != ctxt->dst_page + i)
+				msg("Warinig: page %u of file %s is written to wrong offset %llu",
+						mach_read_from_4(page + FIL_PAGE_OFFSET), cursor->node->name,
+						ctxt->dst_page + i);
+		}
+	}
+	ctxt->dst_page += cursor->buf_npages;
+
 	if (ds_write(dstfile, cursor->buf, cursor->buf_read)) {
 		return(FALSE);
 	}
diff --git a/extra/mariabackup/write_filt.h b/extra/mariabackup/write_filt.h
index febf25f2a8a..e511ffcddb5 100644
--- a/extra/mariabackup/write_filt.h
+++ b/extra/mariabackup/write_filt.h
@@ -41,6 +41,7 @@ typedef struct {
 	union {
 		xb_wf_incremental_ctxt_t	wf_incremental_ctxt;
 	} u;
+	my_off_t dst_page;
 } xb_write_filt_ctxt_t;
 
 
diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc
index 8775584bff0..95dbacc670d 100644
--- a/extra/mariabackup/xtrabackup.cc
+++ b/extra/mariabackup/xtrabackup.cc
@@ -2526,12 +2526,7 @@ xtrabackup_copy_datafile(fil_node_t* node, uint thread_n, const char *dest_name=
 		goto skip;
 	}
 
-	if (!changed_page_bitmap) {
-		read_filter = &rf_pass_through;
-	}
-	else {
-		read_filter = &rf_bitmap;
-	}
+	read_filter = &rf_pass_through;
 
 	res = xb_fil_cur_open(&cursor, read_filter, node, thread_n,max_size);
 	if (res == XB_FIL_CUR_SKIP) {
@@ -4979,6 +4974,13 @@ xtrabackup_apply_delta(
 				}
 			}
 
+			if (info.space_id != SRV_LOG_SPACE_FIRST_ID &&
+					fil_is_user_tablespace_id(info.space_id) &&
+					mach_read_from_4(buf + FIL_PAGE_OFFSET) != (off/page_size))
+				msg("Warning: page %u of file %s is written to wrong offset %lu",
+						mach_read_from_4(buf + FIL_PAGE_OFFSET), dst_path,
+						off/page_size);
+
 			success = os_file_write(IORequestWrite,
 						dst_path, dst_file, buf, off, page_size);
 			if (success != DB_SUCCESS) {
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index d796d2a7f2a..a587d770229 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -4378,10 +4378,34 @@ fil_io(
 
 	req_type.set_fil_node(node);
 
+/*
 	ut_ad(!req_type.is_write()
 	      || page_id.space() == SRV_LOG_SPACE_FIRST_ID
 	      || !fil_is_user_tablespace_id(page_id.space())
 	      || offset == page_id.page_no() * page_size.physical());
+*/
+
+	if (req_type.is_write()
+		&& page_id.space() != SRV_LOG_SPACE_FIRST_ID
+		&& fil_is_user_tablespace_id(page_id.space())
+		&& (offset != page_id.page_no() * page_size.physical()
+			|| mach_read_from_4(static_cast<const byte *>(buf) + FIL_PAGE_OFFSET)
+				!= page_id.page_no()
+			|| mach_read_from_4(static_cast<const byte *>(buf)
+				+ FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID) != page_id.space())
+		) {
+		ib::error() << "Page writes at the wrong offset in file '"
+			<< name << "' space id: " << page_id.space()
+			<< "page: " << page_id.page_no()
+			<< " space id read from buffer: "
+			<< mach_read_from_4(static_cast<const byte *>(buf)
+				+ FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID)
+			<< " page read from buffer: "
+			<< mach_read_from_4(static_cast<const byte *>(buf) + FIL_PAGE_OFFSET)
+			<<". Actual Offset should be "
+			<< offset * page_size.physical()
+			<< " but the wrong offset is " << offset;
+	}
 
 	/* Queue the aio request */
 	dberr_t err = os_aio(
-- 
2.30.9