summaryrefslogtreecommitdiff
path: root/innobase
diff options
context:
space:
mode:
authorunknown <heikki@donna.mysql.fi>2001-05-01 20:57:49 +0300
committerunknown <heikki@donna.mysql.fi>2001-05-01 20:57:49 +0300
commita9d2e5dd17fc9b3b7a8db302fdc94712b1f39d82 (patch)
treea6c3cc3b62ccbb655d4125773ee6e9afb02e0a9c /innobase
parent449c819b444e71915931645d49ba855400f3e216 (diff)
downloadmariadb-git-a9d2e5dd17fc9b3b7a8db302fdc94712b1f39d82.tar.gz
log0recv.c Add checksum to written pages to check that they are also read in unchanged
buf0buf.h Add checksum to written pages to check that they are also read in unchanged buf0flu.c Add checksum to written pages to check that they are also read in unchanged buf0buf.c Add checksum to written pages to check that they are also read in unchanged innobase/buf/buf0buf.c: Add checksum to written pages to check that they are also read in unchanged innobase/buf/buf0flu.c: Add checksum to written pages to check that they are also read in unchanged innobase/include/buf0buf.h: Add checksum to written pages to check that they are also read in unchanged innobase/log/log0recv.c: Add checksum to written pages to check that they are also read in unchanged
Diffstat (limited to 'innobase')
-rw-r--r--innobase/buf/buf0buf.c56
-rw-r--r--innobase/buf/buf0flu.c6
-rw-r--r--innobase/include/buf0buf.h10
-rw-r--r--innobase/log/log0recv.c6
4 files changed, 62 insertions, 16 deletions
diff --git a/innobase/buf/buf0buf.c b/innobase/buf/buf0buf.c
index 34fbc5b9f98..0046a3761a6 100644
--- a/innobase/buf/buf0buf.c
+++ b/innobase/buf/buf0buf.c
@@ -204,7 +204,28 @@ ulint buf_dbg_counter = 0; /* This is used to insert validation
ibool buf_debug_prints = FALSE; /* If this is set TRUE,
the program prints info whenever
read-ahead or flush occurs */
-
+
+/************************************************************************
+Calculates a page checksum which is stored to the page when it is written
+to a file. Note that we must be careful to calculate the same value
+on 32-bit and 64-bit architectures. */
+
+ulint
+buf_calc_page_checksum(
+/*===================*/
+ /* out: checksum */
+ byte* page) /* in: buffer page */
+{
+ ulint checksum;
+
+ checksum = ut_fold_binary(page, FIL_PAGE_FILE_FLUSH_LSN);
+ + ut_fold_binary(page + FIL_PAGE_DATA, UNIV_PAGE_SIZE - FIL_PAGE_DATA
+ - FIL_PAGE_END_LSN);
+ checksum = checksum & 0xFFFFFFFF;
+
+ return(checksum);
+}
+
/************************************************************************
Initializes a buffer control block when the buf_pool is created. */
static
@@ -1171,12 +1192,36 @@ buf_page_io_complete(
dulint id;
dict_index_t* index;
ulint io_type;
+ ulint checksum;
ut_ad(block);
io_type = block->io_fix;
if (io_type == BUF_IO_READ) {
+ checksum = buf_calc_page_checksum(block->frame);
+
+ /* From version 3.23.38 up we store the page checksum
+ to the 4 upper bytes of the page end lsn field */
+
+ if ((mach_read_from_4(block->frame + FIL_PAGE_LSN + 4)
+ != mach_read_from_4(block->frame + UNIV_PAGE_SIZE
+ - FIL_PAGE_END_LSN + 4))
+ || (checksum != mach_read_from_4(block->frame
+ + UNIV_PAGE_SIZE
+ - FIL_PAGE_END_LSN)
+ && mach_read_from_4(block->frame + FIL_PAGE_LSN)
+ != mach_read_from_4(block->frame
+ + UNIV_PAGE_SIZE
+ - FIL_PAGE_END_LSN))) {
+ fprintf(stderr,
+ "InnoDB: Database page corruption or a failed\n"
+ "InnoDB: file read of page %lu.\n", block->offset);
+ fprintf(stderr,
+ "InnoDB: You may have to recover from a backup.\n");
+ exit(1);
+ }
+
if (recv_recovery_is_on()) {
recv_recover_page(TRUE, block->frame, block->space,
block->offset);
@@ -1208,17 +1253,8 @@ buf_page_io_complete(
ut_ad(buf_pool->n_pend_reads > 0);
buf_pool->n_pend_reads--;
buf_pool->n_pages_read++;
-/*
- if (0 != ut_dulint_cmp(
- mach_read_from_8(block->frame + FIL_PAGE_LSN),
- mach_read_from_8(block->frame + UNIV_PAGE_SIZE
- - FIL_PAGE_END_LSN))) {
- printf("DB error: file page corrupted!\n");
- ut_error;
- }
-*/
rw_lock_x_unlock_gen(&(block->lock), BUF_IO_READ);
rw_lock_x_unlock_gen(&(block->read_lock), BUF_IO_READ);
diff --git a/innobase/buf/buf0flu.c b/innobase/buf/buf0flu.c
index 443256cca34..90bdde1ebc6 100644
--- a/innobase/buf/buf0flu.c
+++ b/innobase/buf/buf0flu.c
@@ -222,6 +222,12 @@ buf_flush_write_block_low(
mach_write_to_8(block->frame + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN,
block->newest_modification);
+ /* We overwrite the first 4 bytes of the end lsn field to store
+ a page checksum */
+
+ mach_write_to_4(block->frame + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN,
+ buf_calc_page_checksum(block->frame));
+
fil_io(OS_FILE_WRITE | OS_AIO_SIMULATED_WAKE_LATER,
FALSE, block->space, block->offset, 0, UNIV_PAGE_SIZE,
(void*)block->frame, (void*)block);
diff --git a/innobase/include/buf0buf.h b/innobase/include/buf0buf.h
index 09883fbb037..5e90f5952fc 100644
--- a/innobase/include/buf0buf.h
+++ b/innobase/include/buf0buf.h
@@ -342,6 +342,16 @@ buf_frame_get_modify_clock(
/*=======================*/
/* out: value */
buf_frame_t* frame); /* in: pointer to a frame */
+/************************************************************************
+Calculates a page checksum which is stored to the page when it is written
+to a file. Note that we must be careful to calculate the same value
+on 32-bit and 64-bit architectures. */
+
+ulint
+buf_calc_page_checksum(
+/*===================*/
+ /* out: checksum */
+ byte* page); /* in: buffer page */
/**************************************************************************
Gets the page number of a pointer pointing within a buffer frame containing
a file page. */
diff --git a/innobase/log/log0recv.c b/innobase/log/log0recv.c
index 894ef9c3840..e93cd3f0364 100644
--- a/innobase/log/log0recv.c
+++ b/innobase/log/log0recv.c
@@ -882,12 +882,6 @@ recv_recover_page(
recv = UT_LIST_GET_NEXT(rec_list, recv);
}
- /* If the following assert fails, the file page is incompletely
- written, and a recovery from a backup is required */
-
- ut_a(0 == ut_dulint_cmp(mach_read_from_8(page + FIL_PAGE_LSN),
- mach_read_from_8(page + UNIV_PAGE_SIZE
- - FIL_PAGE_END_LSN)));
mutex_enter(&(recv_sys->mutex));
recv_addr->state = RECV_PROCESSED;