summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2017-05-09 11:41:35 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2017-05-09 11:41:35 +0300
commitb3939a35aa5e67d6204810e3e8c150772e60c422 (patch)
treeabd77cd4460dc2f298bd3be05b0bf60e46f650e2
parentd0ce8704665c63005c599579ff86692f23240496 (diff)
downloadmariadb-git-b3939a35aa5e67d6204810e3e8c150772e60c422.tar.gz
MDEV-12720 recovery fails with "Generic error" for ROW_FORMAT=compressed
This bug was introduced in the fix of MDEV-12123, which invoked page_zip_write_header() in the wrong way. page_zip_write_header(): Assert that the length is not zero, to be compatible with page_zip_parse_write_header(). btr_root_raise_and_insert(): Update the uncompressed page and then invoke page_zip_write_header() with the correct length.
-rw-r--r--mysql-test/suite/innodb_zip/r/recover.result17
-rw-r--r--mysql-test/suite/innodb_zip/t/recover.test24
-rw-r--r--storage/innobase/btr/btr0btr.cc14
-rw-r--r--storage/innobase/page/page0zip.cc1
4 files changed, 48 insertions, 8 deletions
diff --git a/mysql-test/suite/innodb_zip/r/recover.result b/mysql-test/suite/innodb_zip/r/recover.result
new file mode 100644
index 00000000000..97051efb645
--- /dev/null
+++ b/mysql-test/suite/innodb_zip/r/recover.result
@@ -0,0 +1,17 @@
+#
+# MDEV-12720 recovery fails with "Generic error"
+# for ROW_FORMAT=compressed
+#
+CREATE TABLE a(i INT PRIMARY KEY AUTO_INCREMENT, s VARCHAR(255)) ENGINE=InnoDB
+ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1;
+BEGIN;
+insert into a(i) select null;
+insert into a select null, uuid() from a a, a b, a c;
+insert into a select null, uuid() from a a, a b, a c;
+insert into a select null, uuid() from a a, a b, a c;
+SET GLOBAL innodb_flush_log_at_trx_commit=1;
+COMMIT;
+SELECT COUNT(*) from a;
+COUNT(*)
+1010
+DROP TABLE a;
diff --git a/mysql-test/suite/innodb_zip/t/recover.test b/mysql-test/suite/innodb_zip/t/recover.test
new file mode 100644
index 00000000000..3969cd2f44e
--- /dev/null
+++ b/mysql-test/suite/innodb_zip/t/recover.test
@@ -0,0 +1,24 @@
+--source include/have_innodb.inc
+--source include/have_innodb_max_16k.inc
+--source include/not_embedded.inc
+
+--echo #
+--echo # MDEV-12720 recovery fails with "Generic error"
+--echo # for ROW_FORMAT=compressed
+--echo #
+CREATE TABLE a(i INT PRIMARY KEY AUTO_INCREMENT, s VARCHAR(255)) ENGINE=InnoDB
+ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1;
+
+BEGIN;
+insert into a(i) select null;
+insert into a select null, uuid() from a a, a b, a c;
+insert into a select null, uuid() from a a, a b, a c;
+insert into a select null, uuid() from a a, a b, a c;
+SET GLOBAL innodb_flush_log_at_trx_commit=1;
+COMMIT;
+
+--let $shutdown_timeout=0
+--source include/restart_mysqld.inc
+
+SELECT COUNT(*) from a;
+DROP TABLE a;
diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc
index 338620d2574..a20769310cc 100644
--- a/storage/innobase/btr/btr0btr.cc
+++ b/storage/innobase/btr/btr0btr.cc
@@ -1991,10 +1991,9 @@ btr_root_raise_and_insert(
longer is a leaf page. (Older versions of InnoDB did
set PAGE_MAX_TRX_ID on all secondary index pages.) */
if (root_page_zip) {
- page_zip_write_header(
- root_page_zip,
- PAGE_HEADER + PAGE_MAX_TRX_ID
- + root, 0, mtr);
+ byte* p = PAGE_HEADER + PAGE_MAX_TRX_ID + root;
+ memset(p, 0, 8);
+ page_zip_write_header(root_page_zip, p, 8, mtr);
} else {
mlog_write_ull(PAGE_HEADER + PAGE_MAX_TRX_ID
+ root, 0, mtr);
@@ -2004,10 +2003,9 @@ btr_root_raise_and_insert(
root page; on other clustered index pages, we want to reserve
the field PAGE_MAX_TRX_ID for future use. */
if (new_page_zip) {
- page_zip_write_header(
- new_page_zip,
- PAGE_HEADER + PAGE_MAX_TRX_ID
- + new_page, 0, mtr);
+ byte* p = PAGE_HEADER + PAGE_MAX_TRX_ID + new_page;
+ memset(p, 0, 8);
+ page_zip_write_header(new_page_zip, p, 8, mtr);
} else {
mlog_write_ull(PAGE_HEADER + PAGE_MAX_TRX_ID
+ new_page, 0, mtr);
diff --git a/storage/innobase/page/page0zip.cc b/storage/innobase/page/page0zip.cc
index e718081ed63..59022dbe301 100644
--- a/storage/innobase/page/page0zip.cc
+++ b/storage/innobase/page/page0zip.cc
@@ -4634,6 +4634,7 @@ page_zip_write_header_log(
#if PAGE_DATA > 255
# error "PAGE_DATA > 255"
#endif
+ ut_ad(length > 0);
ut_ad(length < 256);
/* If no logging is requested, we may return now */