summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Vojtovich <svoj@sun.com>2010-03-25 23:57:06 +0400
committerSergey Vojtovich <svoj@sun.com>2010-03-25 23:57:06 +0400
commit298c067eeede9e086252390856c990633fe08231 (patch)
tree8da5e1f608ff17dba1f228baa4f37aa749ac116a
parentad6e00e3b2b9bf26805c90cbd7655c6d2b20cab4 (diff)
downloadmariadb-git-298c067eeede9e086252390856c990633fe08231.tar.gz
BUG#46565 - repair of partition fail for archive engine
There was no way to repair corrupt ARCHIVE data file, when unrecoverable data loss is inevitable. With this fix REPAIR ... EXTENDED attempts to restore as much rows as possible, ignoring unrecoverable data. Normal REPAIR is still able to repair meta-data file only. mysql-test/r/archive.result: A test case for BUG#46565. mysql-test/std_data/bug46565.ARZ: A test case for BUG#46565. mysql-test/std_data/bug46565.frm: A test case for BUG#46565. mysql-test/t/archive.test: A test case for BUG#46565. storage/archive/ha_archive.cc: Allow unrecoverable data loss when extended repair is requested.
-rw-r--r--mysql-test/r/archive.result19
-rw-r--r--mysql-test/std_data/bug46565.ARZbin0 -> 8670 bytes
-rw-r--r--mysql-test/std_data/bug46565.frmbin0 -> 8554 bytes
-rw-r--r--mysql-test/t/archive.test23
-rw-r--r--storage/archive/ha_archive.cc14
5 files changed, 52 insertions, 4 deletions
diff --git a/mysql-test/r/archive.result b/mysql-test/r/archive.result
index f14f6a39386..f90bcb521e1 100644
--- a/mysql-test/r/archive.result
+++ b/mysql-test/r/archive.result
@@ -12737,3 +12737,22 @@ SELECT * FROM t1;
ERROR HY000: Can't find file: 't1' (errno: 2)
DROP TABLE t1;
ERROR 42S02: Unknown table 't1'
+#
+# BUG#46565 - repair of partition fail for archive engine
+#
+# Installing corrupted table files for t1.
+SELECT * FROM t1;
+ERROR HY000: Table 't1' is marked as crashed and should be repaired
+REPAIR TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 repair error Corrupt
+SELECT * FROM t1;
+ERROR HY000: Table 't1' is marked as crashed and should be repaired
+REPAIR TABLE t1 EXTENDED;
+Table Op Msg_type Msg_text
+test.t1 repair status OK
+SELECT * FROM t1;
+a
+1
+2
+DROP TABLE t1;
diff --git a/mysql-test/std_data/bug46565.ARZ b/mysql-test/std_data/bug46565.ARZ
new file mode 100644
index 00000000000..f26b31218a1
--- /dev/null
+++ b/mysql-test/std_data/bug46565.ARZ
Binary files differ
diff --git a/mysql-test/std_data/bug46565.frm b/mysql-test/std_data/bug46565.frm
new file mode 100644
index 00000000000..5c0180bdc1e
--- /dev/null
+++ b/mysql-test/std_data/bug46565.frm
Binary files differ
diff --git a/mysql-test/t/archive.test b/mysql-test/t/archive.test
index 67ad0517ed2..7084f5f540e 100644
--- a/mysql-test/t/archive.test
+++ b/mysql-test/t/archive.test
@@ -1655,3 +1655,26 @@ FLUSH TABLE t1;
SELECT * FROM t1;
--error ER_BAD_TABLE_ERROR
DROP TABLE t1;
+
+
+--echo #
+--echo # BUG#46565 - repair of partition fail for archive engine
+--echo #
+--echo # Installing corrupted table files for t1.
+# bug46565 was created, filled and damaged as following:
+# CREATE TABLE bug46565(a INT) ENGINE=archive;
+# INSERT INTO bug46565 VALUES(1);
+# FLUSH TABLE bug46565;
+# INSERT INTO bug46565 VALUES(2),(3);
+# FLUSH TABLE bug46565;
+# dd if=bug46565.ARZ of=std_data/bug46565.ARZ bs=1 count=8670
+copy_file std_data/bug46565.frm $MYSQLD_DATADIR/test/t1.frm;
+copy_file std_data/bug46565.ARZ $MYSQLD_DATADIR/test/t1.ARZ;
+--error ER_CRASHED_ON_USAGE
+SELECT * FROM t1;
+REPAIR TABLE t1;
+--error ER_CRASHED_ON_USAGE
+SELECT * FROM t1;
+REPAIR TABLE t1 EXTENDED;
+SELECT * FROM t1;
+DROP TABLE t1;
diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc
index 364ffba0f6c..988337ec50e 100644
--- a/storage/archive/ha_archive.cc
+++ b/storage/archive/ha_archive.cc
@@ -1269,13 +1269,12 @@ int ha_archive::rnd_pos(uchar * buf, uchar *pos)
/*
This method repairs the meta file. It does this by walking the datafile and
- rewriting the meta file. Currently it does this by calling optimize with
- the extended flag.
+ rewriting the meta file. If EXTENDED repair is requested, we attempt to
+ recover as much data as possible.
*/
int ha_archive::repair(THD* thd, HA_CHECK_OPT* check_opt)
{
DBUG_ENTER("ha_archive::repair");
- check_opt->flags= T_EXTEND;
int rc= optimize(thd, check_opt);
if (rc)
@@ -1369,7 +1368,14 @@ int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt)
DBUG_PRINT("ha_archive", ("recovered %llu archive rows",
(unsigned long long)share->rows_recorded));
- if (rc && rc != HA_ERR_END_OF_FILE)
+ /*
+ If REPAIR ... EXTENDED is requested, try to recover as much data
+ from data file as possible. In this case if we failed to read a
+ record, we assume EOF. This allows massive data loss, but we can
+ hardly do more with broken zlib stream. And this is the only way
+ to restore at least what is still recoverable.
+ */
+ if (rc && rc != HA_ERR_END_OF_FILE && !(check_opt->flags & T_EXTEND))
goto error;
}