summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Lindström <jplindst@mariadb.org>2014-05-09 11:03:39 +0300
committerJan Lindström <jplindst@mariadb.org>2014-05-09 11:03:39 +0300
commit124428a9e28e59f98b25d8ee07b57d264f63cbe4 (patch)
treed151131aaae9ccd5fbd6d368189ff123f3584510
parent45a91d8cbbfb38926f839b9c3cec73a39c5ebffd (diff)
downloadmariadb-git-124428a9e28e59f98b25d8ee07b57d264f63cbe4.tar.gz
MDEV-4791: Assertion range_end >= range_start fails in log0online.c
on select from I_S.INNODB_CHANGED_PAGES Analysis: limit_lsn_range_from_condition() incorrectly parses start_lsn and/or end_lsn conditions. Fix from SergeyP. Added some test cases.
-rw-r--r--mysql-test/suite/innodb/r/innodb-changed-pages.result72
-rw-r--r--mysql-test/suite/innodb/t/innodb-changed-pages-master.opt1
-rw-r--r--mysql-test/suite/innodb/t/innodb-changed-pages.test63
-rw-r--r--storage/xtradb/handler/i_s.cc59
4 files changed, 170 insertions, 25 deletions
diff --git a/mysql-test/suite/innodb/r/innodb-changed-pages.result b/mysql-test/suite/innodb/r/innodb-changed-pages.result
new file mode 100644
index 00000000000..392b5e64e2e
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb-changed-pages.result
@@ -0,0 +1,72 @@
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn < 10 AND end_lsn > 20 ;
+space_id page_id start_lsn end_lsn
+SELECT * FROM INFORMATION_SCHEMA . `INNODB_CHANGED_PAGES` AS table1 WHERE ( ( (NOT ( ( ( ( (NOT ( table1 . `page_id` <> table1 . `start_lsn` AND table1 . `space_id` <> 8) AND table1 . `page_id` >= table1 . `end_lsn`) OR table1 . `end_lsn` = table1 . `space_id`) AND table1 . `end_lsn` <> table1 . `page_id`) OR table1 . `end_lsn` < 8) AND table1 . `space_id` >= '2000-06-10 11:33:07.046821') AND table1 . `end_lsn` >= 5) AND table1 . `start_lsn` < 'mm') OR table1 . `end_lsn` != table1 . `end_lsn`) HAVING ( table1 . `start_lsn` < '2005-09-09 01:34:19.012946' OR table1 . `page_id` < 6) ORDER BY table1 . `start_lsn`
+LIMIT 3;
+space_id page_id start_lsn end_lsn
+Warnings:
+Warning 1292 Truncated incorrect DOUBLE value: 'mm'
+Warning 1292 Truncated incorrect DOUBLE value: '2005-09-09 01:34:19.012946'
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES;
+space_id page_id start_lsn end_lsn
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn < 2000000;
+space_id page_id start_lsn end_lsn
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn <= 2000000;
+space_id page_id start_lsn end_lsn
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE end_lsn > 2000000;
+space_id page_id start_lsn end_lsn
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE end_lsn >= 2000000;
+space_id page_id start_lsn end_lsn
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn > 2000000;
+space_id page_id start_lsn end_lsn
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn >= 2000000;
+space_id page_id start_lsn end_lsn
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE end_lsn > 2000000;
+space_id page_id start_lsn end_lsn
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE end_lsn >= 2000000;
+space_id page_id start_lsn end_lsn
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn > 2000000 and end_lsn < 3000000;
+space_id page_id start_lsn end_lsn
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn >= 2000000 and end_lsn < 3000000;
+space_id page_id start_lsn end_lsn
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn > 2000000 and end_lsn <= 3000000;
+space_id page_id start_lsn end_lsn
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn >= 2000000 and end_lsn <= 3000000;
+space_id page_id start_lsn end_lsn
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn = 2000000;
+space_id page_id start_lsn end_lsn
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE end_lsn = 2000000;
+space_id page_id start_lsn end_lsn
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn < 2000000 or end_lsn < 3000000;
+space_id page_id start_lsn end_lsn
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn <= 2000000 or end_lsn < 3000000;
+space_id page_id start_lsn end_lsn
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn < 2000000 or end_lsn <= 3000000;
+space_id page_id start_lsn end_lsn
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn <= 2000000 or end_lsn <= 3000000;
+space_id page_id start_lsn end_lsn
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn > 2000000 or end_lsn < 3000000;
+space_id page_id start_lsn end_lsn
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn >= 2000000 or end_lsn < 3000000;
+space_id page_id start_lsn end_lsn
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn > 2000000 or end_lsn <= 3000000;
+space_id page_id start_lsn end_lsn
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn >= 2000000 or end_lsn <= 3000000;
+space_id page_id start_lsn end_lsn
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn < 2000000 or end_lsn > 3000000;
+space_id page_id start_lsn end_lsn
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn <= 2000000 or end_lsn > 3000000;
+space_id page_id start_lsn end_lsn
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn < 2000000 or end_lsn >= 3000000;
+space_id page_id start_lsn end_lsn
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn <= 2000000 or end_lsn >= 3000000;
+space_id page_id start_lsn end_lsn
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn > 2000000 or end_lsn > 3000000;
+space_id page_id start_lsn end_lsn
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn >= 2000000 or end_lsn > 3000000;
+space_id page_id start_lsn end_lsn
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn > 2000000 or end_lsn >= 3000000;
+space_id page_id start_lsn end_lsn
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn >= 2000000 or end_lsn >= 3000000;
+space_id page_id start_lsn end_lsn
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE (start_lsn > 2000000 and end_lsn < 3000000) or (start_lsn > 4000000 and end_lsn < 5000000);
+space_id page_id start_lsn end_lsn
diff --git a/mysql-test/suite/innodb/t/innodb-changed-pages-master.opt b/mysql-test/suite/innodb/t/innodb-changed-pages-master.opt
new file mode 100644
index 00000000000..bdee9614faa
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb-changed-pages-master.opt
@@ -0,0 +1 @@
+--innodb-track-changed-pages=0 --innodb-changed-pages=1 \ No newline at end of file
diff --git a/mysql-test/suite/innodb/t/innodb-changed-pages.test b/mysql-test/suite/innodb/t/innodb-changed-pages.test
new file mode 100644
index 00000000000..14668af25cb
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb-changed-pages.test
@@ -0,0 +1,63 @@
+-- source include/have_xtradb.inc
+
+#
+# This test requires innodb-changed-pages=1 so that necessary information schema table exists
+# and innodb-track-changed-pages=0 to disable actual changed pages tracking, because
+# page number are not consistent from run to run
+#
+
+#
+# MDEV-4791: ssertion range_end >= range_start fails in log0online.c
+# on select from I_S.INNODB_CHANGED_PAGES
+
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn < 10 AND end_lsn > 20 ;
+
+SELECT * FROM INFORMATION_SCHEMA . `INNODB_CHANGED_PAGES` AS table1 WHERE ( ( (NOT ( ( ( ( (NOT ( table1 . `page_id` <> table1 . `start_lsn` AND table1 . `space_id` <> 8) AND table1 . `page_id` >= table1 . `end_lsn`) OR table1 . `end_lsn` = table1 . `space_id`) AND table1 . `end_lsn` <> table1 . `page_id`) OR table1 . `end_lsn` < 8) AND table1 . `space_id` >= '2000-06-10 11:33:07.046821') AND table1 . `end_lsn` >= 5) AND table1 . `start_lsn` < 'mm') OR table1 . `end_lsn` != table1 . `end_lsn`) HAVING ( table1 . `start_lsn` < '2005-09-09 01:34:19.012946' OR table1 . `page_id` < 6) ORDER BY table1 . `start_lsn`
+LIMIT 3;
+
+#
+# Basic tests
+#
+
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES;
+
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn < 2000000;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn <= 2000000;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE end_lsn > 2000000;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE end_lsn >= 2000000;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn > 2000000;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn >= 2000000;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE end_lsn > 2000000;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE end_lsn >= 2000000;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn > 2000000 and end_lsn < 3000000;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn >= 2000000 and end_lsn < 3000000;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn > 2000000 and end_lsn <= 3000000;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn >= 2000000 and end_lsn <= 3000000;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn = 2000000;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE end_lsn = 2000000;
+
+#
+# OR
+#
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn < 2000000 or end_lsn < 3000000;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn <= 2000000 or end_lsn < 3000000;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn < 2000000 or end_lsn <= 3000000;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn <= 2000000 or end_lsn <= 3000000;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn > 2000000 or end_lsn < 3000000;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn >= 2000000 or end_lsn < 3000000;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn > 2000000 or end_lsn <= 3000000;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn >= 2000000 or end_lsn <= 3000000;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn < 2000000 or end_lsn > 3000000;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn <= 2000000 or end_lsn > 3000000;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn < 2000000 or end_lsn >= 3000000;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn <= 2000000 or end_lsn >= 3000000;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn > 2000000 or end_lsn > 3000000;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn >= 2000000 or end_lsn > 3000000;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn > 2000000 or end_lsn >= 3000000;
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE start_lsn >= 2000000 or end_lsn >= 3000000;
+
+#
+# Range
+#
+SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES WHERE (start_lsn > 2000000 and end_lsn < 3000000) or (start_lsn > 4000000 and end_lsn < 5000000);
+
diff --git a/storage/xtradb/handler/i_s.cc b/storage/xtradb/handler/i_s.cc
index 9bede650549..4b0c77c4cfb 100644
--- a/storage/xtradb/handler/i_s.cc
+++ b/storage/xtradb/handler/i_s.cc
@@ -7302,38 +7302,47 @@ limit_lsn_range_from_condition(
if (left->type() == Item::FIELD_ITEM
&& right->type() == Item::INT_ITEM) {
- /* The case of start_lsn|end_lsn <|<= const, i.e. the
- upper bound. */
-
- tmp_result = right->val_int();
- if (((func_type == Item_func::LE_FUNC)
- || (func_type == Item_func::GE_FUNC))
- && (tmp_result != IB_ULONGLONG_MAX)) {
-
- tmp_result++;
- }
- if (tmp_result < *end_lsn) {
- *end_lsn = tmp_result;
+ /* The case of start_lsn|end_lsn <|<= const
+ "end_lsn <=? const" gives a valid upper bound.
+ "start_lsn <=? const" is not a valid upper bound.
+ */
+
+ if (is_end_lsn) {
+ tmp_result = right->val_int();
+ if (((func_type == Item_func::LE_FUNC)
+ || (func_type == Item_func::GE_FUNC))
+ && (tmp_result != IB_ULONGLONG_MAX)) {
+
+ tmp_result++;
+ }
+ if (tmp_result < *end_lsn) {
+ *end_lsn = tmp_result;
+ }
}
} else if (left->type() == Item::INT_ITEM
&& right->type() == Item::FIELD_ITEM) {
- /* The case of const <|<= start_lsn|end_lsn, i.e. the
- lower bound */
+ /* The case of const <|<= start_lsn|end_lsn
+ turning it around: start_lsn|end_lsn >|>= const
+ "start_lsn >=? const " is a valid loer bound.
+ "end_lsn >=? const" is not a valid lower bound.
+ */
- tmp_result = left->val_int();
- if (is_end_lsn && tmp_result != 0) {
- tmp_result--;
- }
- if (((func_type == Item_func::LT_FUNC)
- || (func_type == Item_func::GT_FUNC))
- && (tmp_result != IB_ULONGLONG_MAX)) {
+ if (!is_end_lsn) {
+ tmp_result = left->val_int();
+ if (is_end_lsn && tmp_result != 0) {
+ tmp_result--;
+ }
+ if (((func_type == Item_func::LT_FUNC)
+ || (func_type == Item_func::GT_FUNC))
+ && (tmp_result != IB_ULONGLONG_MAX)) {
- tmp_result++;
- }
- if (tmp_result > *start_lsn) {
- *start_lsn = tmp_result;
+ tmp_result++;
+ }
+ if (tmp_result > *start_lsn) {
+ *start_lsn = tmp_result;
+ }
}
}