Commit a9d00db1 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-11799 InnoDB can abort if the doublewrite buffer

contains a bad and a good copy

Clean up the InnoDB doublewrite buffer code.

buf_dblwr_init_or_load_pages(): Do not add empty pages to the buffer.

buf_dblwr_process(): Do consider changes to pages that are all zero.
Do not abort when finding a corrupted copy of a page in the doublewrite
buffer, because there could be multiple copies in the doublewrite buffer,
and only one of them needs to be good.
parent 9b99d9be
call mtr.add_suppression("InnoDB: Warning: database page corruption or a failed");
CREATE TABLE t1(a CHAR(255), CREATE TABLE t1(a CHAR(255),
b CHAR(255), b CHAR(255),
c CHAR(255), c CHAR(255),
......
call mtr.add_suppression("InnoDB: Warning: database page corruption or a failed");
CREATE TABLE t1(a CHAR(255), CREATE TABLE t1(a CHAR(255),
b CHAR(255), b CHAR(255),
c CHAR(255), c CHAR(255),
......
...@@ -4,10 +4,6 @@ ...@@ -4,10 +4,6 @@
# Temporary tablename will be unique. This makes sure that future # Temporary tablename will be unique. This makes sure that future
# in-place ALTERs of the same table will not be blocked due to # in-place ALTERs of the same table will not be blocked due to
# temporary tablename. # temporary tablename.
call mtr.add_suppression("InnoDB: Warning: database page corruption or a failed
");
call mtr.add_suppression("InnoDB: file read of space .* page .*");
call mtr.add_suppression("InnoDB: Trying to recover it from the doublewrite buffer.");
# Crash the server in ha_innobase::commit_inplace_alter_table() # Crash the server in ha_innobase::commit_inplace_alter_table()
CREATE TABLE t1 (f1 INT NOT NULL, f2 INT NOT NULL) ENGINE=innodb; CREATE TABLE t1 (f1 INT NOT NULL, f2 INT NOT NULL) ENGINE=innodb;
SET debug='d,innodb_alter_commit_crash_before_commit'; SET debug='d,innodb_alter_commit_crash_before_commit';
......
call mtr.add_suppression("InnoDB: Database page corruption on disk or a failed.*"); call mtr.add_suppression("InnoDB: Database page corruption on disk or a failed.*");
CALL mtr.add_suppression("InnoDB: Error: Unable to read tablespace .* page no .* into the buffer pool after 100 attempts"); CALL mtr.add_suppression("InnoDB: Error: Unable to read tablespace .* page no .* into the buffer pool after 100 attempts");
CALL mtr.add_suppression("InnoDB: Warning: database page corruption or a failed");
CALL mtr.add_suppression("InnoDB: Database page corruption on disk or a failed"); CALL mtr.add_suppression("InnoDB: Database page corruption on disk or a failed");
CALL mtr.add_suppression("InnoDB: Space .* file test/t1 read of page .*"); CALL mtr.add_suppression("InnoDB: Space .* file test/t1 read of page .*");
CALL mtr.add_suppression("InnoDB: You may have to recover from a backup."); CALL mtr.add_suppression("InnoDB: You may have to recover from a backup.");
......
call mtr.add_suppression("InnoDB: Warning: database page corruption or a failed");
CREATE TABLE t1 (a INT) ENGINE=InnoDB; CREATE TABLE t1 (a INT) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1); INSERT INTO t1 VALUES (1);
XA START 'x'; XA START 'x';
...@@ -6,6 +5,7 @@ UPDATE t1 set a=2; ...@@ -6,6 +5,7 @@ UPDATE t1 set a=2;
XA END 'x'; XA END 'x';
XA PREPARE 'x'; XA PREPARE 'x';
call mtr.add_suppression("Found 1 prepared XA transactions"); call mtr.add_suppression("Found 1 prepared XA transactions");
# Kill the server
SELECT * FROM t1 LOCK IN SHARE MODE; SELECT * FROM t1 LOCK IN SHARE MODE;
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT * FROM t1; SELECT * FROM t1;
......
...@@ -9,8 +9,6 @@ ...@@ -9,8 +9,6 @@
--source include/have_debug.inc --source include/have_debug.inc
--source include/have_log_bin.inc --source include/have_log_bin.inc
call mtr.add_suppression("InnoDB: Warning: database page corruption or a failed");
let $file_format_max=`SELECT @@innodb_file_format_max`; let $file_format_max=`SELECT @@innodb_file_format_max`;
CREATE TABLE t1(a CHAR(255), CREATE TABLE t1(a CHAR(255),
b CHAR(255), b CHAR(255),
......
...@@ -9,8 +9,6 @@ ...@@ -9,8 +9,6 @@
--source include/have_debug.inc --source include/have_debug.inc
--source include/have_log_bin.inc --source include/have_log_bin.inc
call mtr.add_suppression("InnoDB: Warning: database page corruption or a failed");
let $file_format_max=`SELECT @@innodb_file_format_max`; let $file_format_max=`SELECT @@innodb_file_format_max`;
CREATE TABLE t1(a CHAR(255), CREATE TABLE t1(a CHAR(255),
b CHAR(255), b CHAR(255),
......
...@@ -20,13 +20,6 @@ ...@@ -20,13 +20,6 @@
--echo # in-place ALTERs of the same table will not be blocked due to --echo # in-place ALTERs of the same table will not be blocked due to
--echo # temporary tablename. --echo # temporary tablename.
# As we intentionally crash below, there could be partially written
# pages that are then recovered from the doublewrite buffer
call mtr.add_suppression("InnoDB: Warning: database page corruption or a failed
");
call mtr.add_suppression("InnoDB: file read of space .* page .*");
call mtr.add_suppression("InnoDB: Trying to recover it from the doublewrite buffer.");
let datadir= `select @@datadir`; let datadir= `select @@datadir`;
--let $_server_id= `SELECT @@server_id` --let $_server_id= `SELECT @@server_id`
......
...@@ -21,7 +21,6 @@ source include/have_debug.inc; ...@@ -21,7 +21,6 @@ source include/have_debug.inc;
source include/not_windows.inc; source include/not_windows.inc;
CALL mtr.add_suppression("InnoDB: Error: Unable to read tablespace .* page no .* into the buffer pool after 100 attempts"); CALL mtr.add_suppression("InnoDB: Error: Unable to read tablespace .* page no .* into the buffer pool after 100 attempts");
CALL mtr.add_suppression("InnoDB: Warning: database page corruption or a failed");
CALL mtr.add_suppression("InnoDB: Database page corruption on disk or a failed"); CALL mtr.add_suppression("InnoDB: Database page corruption on disk or a failed");
CALL mtr.add_suppression("InnoDB: Space .* file test/t1 read of page .*"); CALL mtr.add_suppression("InnoDB: Space .* file test/t1 read of page .*");
CALL mtr.add_suppression("InnoDB: You may have to recover from a backup."); CALL mtr.add_suppression("InnoDB: You may have to recover from a backup.");
......
...@@ -12,11 +12,6 @@ if (`select plugin_auth_version <= "5.6.24" from information_schema.plugins wher ...@@ -12,11 +12,6 @@ if (`select plugin_auth_version <= "5.6.24" from information_schema.plugins wher
FLUSH TABLES; FLUSH TABLES;
--enable_query_log --enable_query_log
#
# We kill server belown with timeout 0 that is not fully safe
#
call mtr.add_suppression("InnoDB: Warning: database page corruption or a failed");
CREATE TABLE t1 (a INT) ENGINE=InnoDB; CREATE TABLE t1 (a INT) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1); INSERT INTO t1 VALUES (1);
connect (con1,localhost,root); connect (con1,localhost,root);
...@@ -25,15 +20,8 @@ connection default; ...@@ -25,15 +20,8 @@ connection default;
call mtr.add_suppression("Found 1 prepared XA transactions"); call mtr.add_suppression("Found 1 prepared XA transactions");
# Kill and restart the server. --source include/kill_mysqld.inc
-- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --source include/start_mysqld.inc
-- shutdown_server 0
-- source include/wait_until_disconnected.inc
-- exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
-- enable_reconnect
-- source include/wait_until_connected_again.inc
-- disable_reconnect
disconnect con1; disconnect con1;
connect (con1,localhost,root); connect (con1,localhost,root);
......
...@@ -3,7 +3,6 @@ include/rpl_init.inc [topology=1->2] ...@@ -3,7 +3,6 @@ include/rpl_init.inc [topology=1->2]
call mtr.add_suppression("Checking table:"); call mtr.add_suppression("Checking table:");
call mtr.add_suppression("client is using or hasn't closed the table properly"); call mtr.add_suppression("client is using or hasn't closed the table properly");
call mtr.add_suppression("Table .* is marked as crashed and should be repaired"); call mtr.add_suppression("Table .* is marked as crashed and should be repaired");
call mtr.add_suppression("InnoDB: Warning: database page corruption or a failed");
flush tables; flush tables;
ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB;
......
...@@ -12,11 +12,6 @@ ...@@ -12,11 +12,6 @@
call mtr.add_suppression("Checking table:"); call mtr.add_suppression("Checking table:");
call mtr.add_suppression("client is using or hasn't closed the table properly"); call mtr.add_suppression("client is using or hasn't closed the table properly");
call mtr.add_suppression("Table .* is marked as crashed and should be repaired"); call mtr.add_suppression("Table .* is marked as crashed and should be repaired");
# We have seen this warning a couple of times in Buildbot. Since we crash the
# server deliberately, it seems possible that we could in rare cases crash in
# the middle of a page write. The page is recovered from the doublewrite
# buffer ("[Note] InnoDB: Recovered the page from the doublewrite buffer.").
call mtr.add_suppression("InnoDB: Warning: database page corruption or a failed");
flush tables; flush tables;
ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
......
...@@ -455,8 +455,11 @@ buf_dblwr_init_or_load_pages( ...@@ -455,8 +455,11 @@ buf_dblwr_init_or_load_pages(
os_file_write(path, file, page, os_file_write(path, file, page,
source_page_no * UNIV_PAGE_SIZE, source_page_no * UNIV_PAGE_SIZE,
UNIV_PAGE_SIZE); UNIV_PAGE_SIZE);
} else if (load_corrupt_pages) { } else if (load_corrupt_pages
&& !buf_page_is_zeroes(page, FIL_PAGE_DATA)) {
/* Each valid page header must contain some
nonzero bytes, such as FIL_PAGE_OFFSET
or FIL_PAGE_LSN. */
recv_dblwr.add(page); recv_dblwr.add(page);
} }
...@@ -492,8 +495,6 @@ buf_dblwr_process() ...@@ -492,8 +495,6 @@ buf_dblwr_process()
for (std::list<byte*>::iterator i = recv_dblwr.pages.begin(); for (std::list<byte*>::iterator i = recv_dblwr.pages.begin();
i != recv_dblwr.pages.end(); ++i, ++page_no_dblwr ) { i != recv_dblwr.pages.end(); ++i, ++page_no_dblwr ) {
bool is_compressed = false;
page = *i; page = *i;
page_no = mach_read_from_4(page + FIL_PAGE_OFFSET); page_no = mach_read_from_4(page + FIL_PAGE_OFFSET);
space_id = mach_read_from_4(page + FIL_PAGE_SPACE_ID); space_id = mach_read_from_4(page + FIL_PAGE_SPACE_ID);
...@@ -501,18 +502,20 @@ buf_dblwr_process() ...@@ -501,18 +502,20 @@ buf_dblwr_process()
if (!fil_tablespace_exists_in_mem(space_id)) { if (!fil_tablespace_exists_in_mem(space_id)) {
/* Maybe we have dropped the single-table tablespace /* Maybe we have dropped the single-table tablespace
and this page once belonged to it: do nothing */ and this page once belonged to it: do nothing */
continue;
}
} else if (!fil_check_adress_in_tablespace(space_id, if (!fil_check_adress_in_tablespace(space_id, page_no)) {
page_no)) {
ib_logf(IB_LOG_LEVEL_WARN, ib_logf(IB_LOG_LEVEL_WARN,
"A page in the doublewrite buffer is not " "A copy of page " ULINTPF ":" ULINTPF
"within space bounds; space id %lu " " in the doublewrite buffer slot " ULINTPF
"page number %lu, page %lu in " " is not within space bounds",
"doublewrite buf.", space_id, page_no, page_no_dblwr);
(ulong) space_id, (ulong) page_no, continue;
page_no_dblwr); }
} else {
ulint zip_size = fil_space_get_zip_size(space_id); ulint zip_size = fil_space_get_zip_size(space_id);
ut_ad(!buf_page_is_zeroes(page, zip_size));
/* Read in the actual page from the file */ /* Read in the actual page from the file */
fil_io(OS_FILE_READ, fil_io(OS_FILE_READ,
...@@ -526,114 +529,77 @@ buf_dblwr_process() ...@@ -526,114 +529,77 @@ buf_dblwr_process()
NULL, NULL,
0); 0);
/* Is page compressed ? */ const bool is_all_zero = buf_page_is_zeroes(
is_compressed = fil_page_is_compressed_encrypted(read_buf) | read_buf, zip_size);
fil_page_is_compressed(read_buf);
/* If page was compressed, decompress it before we if (is_all_zero) {
check checksum. */ /* We will check if the copy in the
if (is_compressed) { doublewrite buffer is valid. If not, we will
fil_decompress_page(NULL, read_buf, UNIV_PAGE_SIZE, NULL, true); ignore this page (there should be redo log
records to initialize it). */
} else {
if (fil_page_is_compressed_encrypted(read_buf) ||
fil_page_is_compressed(read_buf)) {
/* Decompress the page before
validating the checksum. */
fil_decompress_page(
NULL, read_buf, UNIV_PAGE_SIZE,
NULL, true);
} }
if (fil_space_verify_crypt_checksum(read_buf, zip_size)) { if (fil_space_verify_crypt_checksum(
/* page is encrypted and checksum is OK */ read_buf, zip_size)
} else if (buf_page_is_corrupted(true, read_buf, zip_size)) { || !buf_page_is_corrupted(
true, read_buf, zip_size)) {
/* The page is good; there is no need
to consult the doublewrite buffer. */
continue;
}
fprintf(stderr, /* We intentionally skip this message for
"InnoDB: Warning: database page" is_all_zero pages. */
" corruption or a failed\n" ib_logf(IB_LOG_LEVEL_INFO,
"InnoDB: file read of" "Trying to recover page " ULINTPF ":" ULINTPF
" space %lu page %lu.\n" " from the doublewrite buffer.",
"InnoDB: Trying to recover it from" space_id, page_no);
" the doublewrite buffer.\n",
(ulong) space_id, (ulong) page_no);
/* Is page compressed ? */
is_compressed = fil_page_is_compressed_encrypted(page) |
fil_page_is_compressed(page);
/* If page was compressed, decompress it before we
check checksum. */
if (is_compressed) {
fil_decompress_page(NULL, page, UNIV_PAGE_SIZE, NULL, true);
} }
if (fil_space_verify_crypt_checksum(page, zip_size)) { /* Next, validate the doublewrite page. */
/* the doublewrite buffer page is encrypted and OK */ if (fil_page_is_compressed_encrypted(page) ||
} else if (buf_page_is_corrupted(true, fil_page_is_compressed(page)) {
page, /* Decompress the page before
zip_size)) { validating the checksum. */
fprintf(stderr, fil_decompress_page(
"InnoDB: Dump of the page:\n"); NULL, page, UNIV_PAGE_SIZE, NULL, true);
buf_page_print( }
read_buf, zip_size,
BUF_PAGE_PRINT_NO_CRASH);
fprintf(stderr,
"InnoDB: Dump of"
" corresponding page"
" in doublewrite buffer:\n");
buf_page_print(
page, zip_size,
BUF_PAGE_PRINT_NO_CRASH);
fprintf(stderr, if (!fil_space_verify_crypt_checksum(page, zip_size)
"InnoDB: Also the page in the" && buf_page_is_corrupted(true, page, zip_size)) {
" doublewrite buffer" if (!is_all_zero) {
" is corrupt.\n" ib_logf(IB_LOG_LEVEL_WARN,
"InnoDB: Cannot continue" "A doublewrite copy of page "
" operation.\n" ULINTPF ":" ULINTPF " is corrupted.",
"InnoDB: You can try to" space_id, page_no);
" recover the database" }
" with the my.cnf\n" /* Theoretically we could have another good
"InnoDB: option:\n" copy for this page in the doublewrite
"InnoDB:" buffer. If not, we will report a fatal error
" innodb_force_recovery=6\n"); for a corrupted page somewhere else if that
ut_error; page was truly needed. */
continue;
} }
/* Write the good page from the /* Write the good page from the doublewrite buffer to
doublewrite buffer to the intended the intended position. */
position */
fil_io(OS_FILE_WRITE, fil_io(OS_FILE_WRITE, true, space_id, zip_size, page_no, 0,
true,
space_id,
zip_size,
page_no,
0,
zip_size ? zip_size : UNIV_PAGE_SIZE, zip_size ? zip_size : UNIV_PAGE_SIZE,
page, page, NULL, 0);
NULL,
0);
ib_logf(IB_LOG_LEVEL_INFO, ib_logf(IB_LOG_LEVEL_INFO,
"Recovered the page from" "Recovered page " ULINTPF ":" ULINTPF " from"
" the doublewrite buffer."); " the doublewrite buffer.",
space_id, page_no);
} else if (buf_page_is_zeroes(read_buf, zip_size)) {
if (!buf_page_is_zeroes(page, zip_size)
&& !buf_page_is_corrupted(true, page,
zip_size)) {
/* Database page contained only
zeroes, while a valid copy is
available in dblwr buffer. */
fil_io(OS_FILE_WRITE,
true,
space_id,
zip_size,
page_no,
0,
zip_size ? zip_size : UNIV_PAGE_SIZE,
page,
NULL,
0);
}
}
}
} }
ut_free(unaligned_read_buf); ut_free(unaligned_read_buf);
......
...@@ -455,8 +455,11 @@ buf_dblwr_init_or_load_pages( ...@@ -455,8 +455,11 @@ buf_dblwr_init_or_load_pages(
os_file_write(path, file, page, os_file_write(path, file, page,
source_page_no * UNIV_PAGE_SIZE, source_page_no * UNIV_PAGE_SIZE,
UNIV_PAGE_SIZE); UNIV_PAGE_SIZE);
} else if (load_corrupt_pages) { } else if (load_corrupt_pages
&& !buf_page_is_zeroes(page, FIL_PAGE_DATA)) {
/* Each valid page header must contain some
nonzero bytes, such as FIL_PAGE_OFFSET
or FIL_PAGE_LSN. */
recv_dblwr.add(page); recv_dblwr.add(page);
} }
...@@ -492,8 +495,6 @@ buf_dblwr_process() ...@@ -492,8 +495,6 @@ buf_dblwr_process()
for (std::list<byte*>::iterator i = recv_dblwr.pages.begin(); for (std::list<byte*>::iterator i = recv_dblwr.pages.begin();
i != recv_dblwr.pages.end(); ++i, ++page_no_dblwr ) { i != recv_dblwr.pages.end(); ++i, ++page_no_dblwr ) {
bool is_compressed = false;
page = *i; page = *i;
page_no = mach_read_from_4(page + FIL_PAGE_OFFSET); page_no = mach_read_from_4(page + FIL_PAGE_OFFSET);
space_id = mach_read_from_4(page + FIL_PAGE_SPACE_ID); space_id = mach_read_from_4(page + FIL_PAGE_SPACE_ID);
...@@ -501,18 +502,20 @@ buf_dblwr_process() ...@@ -501,18 +502,20 @@ buf_dblwr_process()
if (!fil_tablespace_exists_in_mem(space_id)) { if (!fil_tablespace_exists_in_mem(space_id)) {
/* Maybe we have dropped the single-table tablespace /* Maybe we have dropped the single-table tablespace
and this page once belonged to it: do nothing */ and this page once belonged to it: do nothing */
continue;
}
} else if (!fil_check_adress_in_tablespace(space_id, if (!fil_check_adress_in_tablespace(space_id, page_no)) {
page_no)) {
ib_logf(IB_LOG_LEVEL_WARN, ib_logf(IB_LOG_LEVEL_WARN,
"A page in the doublewrite buffer is not " "A copy of page " ULINTPF ":" ULINTPF
"within space bounds; space id %lu " " in the doublewrite buffer slot " ULINTPF
"page number %lu, page %lu in " " is not within space bounds",
"doublewrite buf.", space_id, page_no, page_no_dblwr);
(ulong) space_id, (ulong) page_no, continue;
page_no_dblwr); }
} else {
ulint zip_size = fil_space_get_zip_size(space_id); ulint zip_size = fil_space_get_zip_size(space_id);
ut_ad(!buf_page_is_zeroes(page, zip_size));
/* Read in the actual page from the file */ /* Read in the actual page from the file */
fil_io(OS_FILE_READ, fil_io(OS_FILE_READ,
...@@ -526,113 +529,77 @@ buf_dblwr_process() ...@@ -526,113 +529,77 @@ buf_dblwr_process()
NULL, NULL,
0); 0);
/* Is page compressed ? */ const bool is_all_zero = buf_page_is_zeroes(
is_compressed = fil_page_is_compressed_encrypted(read_buf) | read_buf, zip_size);
fil_page_is_compressed(read_buf);
/* If page was compressed, decompress it before we if (is_all_zero) {
check checksum. */ /* We will check if the copy in the
if (is_compressed) { doublewrite buffer is valid. If not, we will
fil_decompress_page(NULL, read_buf, UNIV_PAGE_SIZE, NULL, true); ignore this page (there should be redo log
records to initialize it). */
} else {
if (fil_page_is_compressed_encrypted(read_buf) ||
fil_page_is_compressed(read_buf)) {
/* Decompress the page before
validating the checksum. */
fil_decompress_page(
NULL, read_buf, UNIV_PAGE_SIZE,
NULL, true);
} }
if (fil_space_verify_crypt_checksum(read_buf, zip_size)) { if (fil_space_verify_crypt_checksum(
/* page is encrypted and checksum is OK */ read_buf, zip_size)
} else if (buf_page_is_corrupted(true, read_buf, zip_size)) { || !buf_page_is_corrupted(
true, read_buf, zip_size)) {
/* The page is good; there is no need
to consult the doublewrite buffer. */
continue;
}
fprintf(stderr, /* We intentionally skip this message for
"InnoDB: Database page" is_all_zero pages. */
" corruption or a failed\n" ib_logf(IB_LOG_LEVEL_INFO,
"InnoDB: file read of" "Trying to recover page " ULINTPF ":" ULINTPF
" space %lu page %lu.\n" " from the doublewrite buffer.",
"InnoDB: Trying to recover it from" space_id, page_no);
" the doublewrite buffer.\n",
(ulong) space_id, (ulong) page_no);
/* Is page compressed ? */
is_compressed = fil_page_is_compressed_encrypted(page) |
fil_page_is_compressed(page);
/* If page was compressed, decompress it before we
check checksum. */
if (is_compressed) {
fil_decompress_page(NULL, page, UNIV_PAGE_SIZE, NULL, true);
} }
if (fil_space_verify_crypt_checksum(page, zip_size)) { /* Next, validate the doublewrite page. */
/* the doublewrite buffer page is encrypted and OK */ if (fil_page_is_compressed_encrypted(page) ||
} else if (buf_page_is_corrupted(true, fil_page_is_compressed(page)) {
page, /* Decompress the page before
zip_size)) { validating the checksum. */
fprintf(stderr, fil_decompress_page(
"InnoDB: Dump of the page:\n"); NULL, page, UNIV_PAGE_SIZE, NULL, true);
buf_page_print( }
read_buf, zip_size,
BUF_PAGE_PRINT_NO_CRASH);
fprintf(stderr,
"InnoDB: Dump of"
" corresponding page"
" in doublewrite buffer:\n");
buf_page_print(
page, zip_size,
BUF_PAGE_PRINT_NO_CRASH);
fprintf(stderr, if (!fil_space_verify_crypt_checksum(page, zip_size)
"InnoDB: Also the page in the" && buf_page_is_corrupted(true, page, zip_size)) {
" doublewrite buffer" if (!is_all_zero) {
" is corrupt.\n" ib_logf(IB_LOG_LEVEL_WARN,
"InnoDB: Cannot continue" "A doublewrite copy of page "
" operation.\n" ULINTPF ":" ULINTPF " is corrupted.",
"InnoDB: You can try to" space_id, page_no);
" recover the database" }
" with the my.cnf\n" /* Theoretically we could have another good
"InnoDB: option:\n" copy for this page in the doublewrite
"InnoDB:" buffer. If not, we will report a fatal error
" innodb_force_recovery=6\n"); for a corrupted page somewhere else if that
ut_error; page was truly needed. */
continue;
} }
/* Write the good page from the /* Write the good page from the doublewrite buffer to
doublewrite buffer to the intended the intended position. */
position */
fil_io(OS_FILE_WRITE, fil_io(OS_FILE_WRITE, true, space_id, zip_size, page_no, 0,
true,
space_id,
zip_size,
page_no,
0,
zip_size ? zip_size : UNIV_PAGE_SIZE, zip_size ? zip_size : UNIV_PAGE_SIZE,
page, page, NULL, 0);
NULL,
0);
ib_logf(IB_LOG_LEVEL_INFO, ib_logf(IB_LOG_LEVEL_INFO,
"Recovered the page from" "Recovered page " ULINTPF ":" ULINTPF " from"
" the doublewrite buffer."); " the doublewrite buffer.",
space_id, page_no);
} else if (buf_page_is_zeroes(read_buf, zip_size)) {
if (!buf_page_is_zeroes(page, zip_size)
&& !buf_page_is_corrupted(true, page,
zip_size)) {
/* Database page contained only
zeroes, while a valid copy is
available in dblwr buffer. */
fil_io(OS_FILE_WRITE,
true,
space_id,
zip_size,
page_no, 0,
zip_size ? zip_size : UNIV_PAGE_SIZE,
page,
NULL,
0);
}
}
}
} }
ut_free(unaligned_read_buf); ut_free(unaligned_read_buf);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment