summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Lindström <jan.lindstrom@mariadb.com>2017-07-20 11:24:01 +0300
committerJan Lindström <jan.lindstrom@mariadb.com>2017-07-20 11:24:01 +0300
commit9b2817a7702c075c9123b23e2d404a0a1f4f1c1e (patch)
treebd9316558abf090894a3b8d66704a5b5c8841fd3
parent9284e8b2c64aba1ac108512ecc415a2ea563c387 (diff)
downloadmariadb-git-bb-10.1-MDEV-13227.tar.gz
MDEV-13227: Assertion failure len < 16384 in file rem0rec.cc line 1285bb-10.1-MDEV-13227
Crashes with innodb_page_size=64K. Does not crash at <= 32K. Problem was that when blob record that was earlier < 16k is enlarged at update wo that length > 16K it should be stored externally. However, that was not enforced when page-size = 64K (note that 16K+1 < 64K/2 i.e. half of the btree leaf page). btr_cur_optimistic_update: limit max record size to 16K or in REDUNDANT row format to 16K-1.
-rw-r--r--mysql-test/suite/innodb/r/innodb-enlarge-blob.result38
-rw-r--r--mysql-test/suite/innodb/t/innodb-enlarge-blob.opt6
-rw-r--r--mysql-test/suite/innodb/t/innodb-enlarge-blob.test50
-rw-r--r--storage/innobase/btr/btr0cur.cc8
-rw-r--r--storage/xtradb/btr/btr0cur.cc8
5 files changed, 102 insertions, 8 deletions
diff --git a/mysql-test/suite/innodb/r/innodb-enlarge-blob.result b/mysql-test/suite/innodb/r/innodb-enlarge-blob.result
new file mode 100644
index 00000000000..e74e954e360
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb-enlarge-blob.result
@@ -0,0 +1,38 @@
+CREATE TABLE t1 (a LONGTEXT) ENGINE=INNODB DEFAULT CHARSET=UTF8 ROW_FORMAT=DYNAMIC;
+SHOW WARNINGS;
+Level Code Message
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B');
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+UPDATE t1 SET a=CONCAT(a, RAND(), a);
+UPDATE t1 SET a=CONCAT(a, RAND(), a);
+UPDATE t1 SET a=CONCAT(a, RAND(), a);
+SELECT * from t1;
+DROP TABLE t1;
+CREATE TABLE t1 (a LONGTEXT) ENGINE=INNODB DEFAULT CHARSET=UTF8 ROW_FORMAT=REDUNDANT;
+SHOW WARNINGS;
+Level Code Message
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B');
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+UPDATE t1 SET a=CONCAT(a, RAND(), a);
+UPDATE t1 SET a=CONCAT(a, RAND(), a);
+UPDATE t1 SET a=CONCAT(a, RAND(), a);
+SELECT * from t1;
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/t/innodb-enlarge-blob.opt b/mysql-test/suite/innodb/t/innodb-enlarge-blob.opt
new file mode 100644
index 00000000000..4c2cd9b3e3c
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb-enlarge-blob.opt
@@ -0,0 +1,6 @@
+--innodb-file-per-table
+--innodb-file-format='Barracuda'
+--innodb-buffer-pool-size=32M
+--innodb-log-file-size=32M
+--innodb-strict-mode=OFF
+
diff --git a/mysql-test/suite/innodb/t/innodb-enlarge-blob.test b/mysql-test/suite/innodb/t/innodb-enlarge-blob.test
new file mode 100644
index 00000000000..84c23465a5c
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb-enlarge-blob.test
@@ -0,0 +1,50 @@
+--source include/have_innodb.inc
+--source include/innodb_page_size.inc
+
+#
+# MDEV-13227: Assertion failure len < 16384 in file rem0rec.cc line 1285
+# Crashes with innodb_page_size=64K. Does not crash at <= 32K.
+#
+CREATE TABLE t1 (a LONGTEXT) ENGINE=INNODB DEFAULT CHARSET=UTF8 ROW_FORMAT=DYNAMIC;
+SHOW WARNINGS;
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B');
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+UPDATE t1 SET a=CONCAT(a, RAND(), a);
+UPDATE t1 SET a=CONCAT(a, RAND(), a);
+UPDATE t1 SET a=CONCAT(a, RAND(), a);
+# random data no output we are only interested if fails
+--disable_result_log
+SELECT * from t1;
+--enable_result_log
+DROP TABLE t1;
+
+CREATE TABLE t1 (a LONGTEXT) ENGINE=INNODB DEFAULT CHARSET=UTF8 ROW_FORMAT=REDUNDANT;
+SHOW WARNINGS;
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B');
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+INSERT INTO t1 SELECT CONCAT('A', SPACE(4087), 'B') FROM t1;
+UPDATE t1 SET a=CONCAT(a, RAND(), a);
+UPDATE t1 SET a=CONCAT(a, RAND(), a);
+UPDATE t1 SET a=CONCAT(a, RAND(), a);
+# random data no output we are only interested if fails
+--disable_result_log
+SELECT * from t1;
+--enable_result_log
+DROP TABLE t1;
diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc
index 2ae6da00549..d848ee538c6 100644
--- a/storage/innobase/btr/btr0cur.cc
+++ b/storage/innobase/btr/btr0cur.cc
@@ -2316,10 +2316,10 @@ any_extern:
rec = page_cur_get_rec(page_cursor);
}
- /* We limit max record size to 16k for 64k page size. */
- if (!dict_table_is_comp(index->table)
- && new_rec_size > REDUNDANT_REC_MAX_DATA_SIZE) {
- ut_ad(srv_page_size == UNIV_PAGE_SIZE_MAX);
+ /* We limit max record size to 16k even for 64k page size. */
+ if (new_rec_size >= COMPRESSED_REC_MAX_DATA_SIZE ||
+ (!dict_table_is_comp(index->table)
+ && new_rec_size >= REDUNDANT_REC_MAX_DATA_SIZE)) {
err = DB_OVERFLOW;
goto func_exit;
diff --git a/storage/xtradb/btr/btr0cur.cc b/storage/xtradb/btr/btr0cur.cc
index 6480b756f4e..1a27fd0d6ea 100644
--- a/storage/xtradb/btr/btr0cur.cc
+++ b/storage/xtradb/btr/btr0cur.cc
@@ -2466,10 +2466,10 @@ any_extern:
rec = page_cur_get_rec(page_cursor);
}
- /* We limit max record size to 16k for 64k page size. */
- if (!dict_table_is_comp(index->table)
- && new_rec_size > REDUNDANT_REC_MAX_DATA_SIZE) {
- ut_ad(srv_page_size == UNIV_PAGE_SIZE_MAX);
+ /* We limit max record size to 16k even for 64k page size. */
+ if (new_rec_size >= COMPRESSED_REC_MAX_DATA_SIZE ||
+ (!dict_table_is_comp(index->table)
+ && new_rec_size >= REDUNDANT_REC_MAX_DATA_SIZE)) {
err = DB_OVERFLOW;
goto func_exit;