Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions mysql-test/suite/rocksdb/r/index_merge_rocksdb.result
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ Table Op Msg_type Msg_text
test.t1 analyze status OK
explain select * from t1 where key1 = 1;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 NULL ref key1 key1 5 # 1 100.00 NULL
1 SIMPLE t1 NULL ref key1 key1 5 # 3 100.00 NULL
Warnings:
Note 1003 /* select#1 */ select `test`.`t1`.`key1` AS `key1`,`test`.`t1`.`key2` AS `key2`,`test`.`t1`.`key3` AS `key3` from `test`.`t1` where (`test`.`t1`.`key1` = 1)
explain select key1,key2 from t1 where key1 = 1 or key2 = 1;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 NULL index_merge key1,key2 key1,key2 5,5 # 2 100.00 Using union(key1,key2); Using where
1 SIMPLE t1 NULL index_merge key1,key2 key1,key2 5,5 # 4 100.00 Using union(key1,key2); Using where
Warnings:
Note 1003 /* select#1 */ select `test`.`t1`.`key1` AS `key1`,`test`.`t1`.`key2` AS `key2` from `test`.`t1` where ((`test`.`t1`.`key1` = 1) or (`test`.`t1`.`key2` = 1))
select * from t1 where key1 = 1;
Expand Down
108 changes: 108 additions & 0 deletions mysql-test/suite/rocksdb/r/records_in_range_dive.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
CREATE TABLE t1 (
i INT PRIMARY KEY AUTO_INCREMENT,
a INT NOT NULL,
b INT NOT NULL,
KEY ka(a),
KEY kb(b) comment 'cfname=rev:cf1'
) ENGINE = rocksdb;
SET @save_dive = @@session.rocksdb_records_in_range_dive_threshold;
SET SESSION rocksdb_records_in_range_dive_threshold = 10000;
#
# Memtable-only: the dive must count the narrow range exactly (200),
# instead of the pre-fix estimate of 1.
#
explain select * from t1 where a = 5000;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 NULL ref ka ka 4 const 200 100.00 NULL
Warnings:
Note 1003 /* select#1 */ select `test`.`t1`.`i` AS `i`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a` = 5000)
explain select * from t1 where b = 5000;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 NULL ref kb kb 4 const 200 100.00 NULL
Warnings:
Note 1003 /* select#1 */ select `test`.`t1`.`i` AS `i`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`b` = 5000)
explain select * from t1 where a > 4999 and a < 5001;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 NULL range ka ka 4 NULL 200 100.00 Using index condition
Warnings:
Note 1003 /* select#1 */ select `test`.`t1`.`i` AS `i`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`a` > 4999) and (`test`.`t1`.`a` < 5001))
#
# SST path: flush the memtable; the dive still counts the narrow
# range exactly.
#
set global rocksdb_force_flush_memtable_now = true;
analyze table t1;
Table Op Msg_type Msg_text
test.t1 analyze status OK
explain select * from t1 where a = 5000;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 NULL ref ka ka 4 const 200 100.00 NULL
Warnings:
Note 1003 /* select#1 */ select `test`.`t1`.`i` AS `i`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a` = 5000)
explain select * from t1 where b = 5000;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 NULL ref kb kb 4 const 200 100.00 NULL
Warnings:
Note 1003 /* select#1 */ select `test`.`t1`.`i` AS `i`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`b` = 5000)
explain select * from t1 where a > 4999 and a < 5001;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 NULL range ka ka 4 NULL 200 100.00 Using index condition
Warnings:
Note 1003 /* select#1 */ select `test`.`t1`.`i` AS `i`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`a` > 4999) and (`test`.`t1`.`a` < 5001))
#
# An empty range stays at the conventional 1 row.
#
explain select * from t1 where a = 9999;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 NULL ref ka ka 4 const 1 100.00 NULL
Warnings:
Note 1003 /* select#1 */ select `test`.`t1`.`i` AS `i`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a` = 9999)
#
# Deterministic single-block scenario: index kc lives in its own
# column family whose whole SST fits in one ~16KB data block, so
# GetApproximateSizes() is guaranteed to return 0 for any range that
# does not extend past the last key: the exact situation from the
# bug report.
#
CREATE TABLE t2 (
i INT PRIMARY KEY AUTO_INCREMENT,
c INT NOT NULL,
KEY kc(c) comment 'cfname=cf_dive'
) ENGINE = rocksdb;
set global rocksdb_force_flush_memtable_now = true;
analyze table t2;
Table Op Msg_type Msg_text
test.t2 analyze status OK
# Dive enabled: exact count (201 keys with c = 50).
SET SESSION rocksdb_records_in_range_dive_threshold = 10000;
explain select * from t2 where c = 50;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 NULL ref kc kc 4 const 201 100.00 Using index
Warnings:
Note 1003 /* select#1 */ select `test`.`t2`.`i` AS `i`,`test`.`t2`.`c` AS `c` from `test`.`t2` where (`test`.`t2`.`c` = 50)
# Cap semantics: the dive reads at most threshold keys, so a range
# with more keys than the threshold estimates as the threshold
# (a lower bound).
SET SESSION rocksdb_records_in_range_dive_threshold = 50;
explain select * from t2 where c = 50;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 NULL ref kc kc 4 const 50 100.00 Using index
Warnings:
Note 1003 /* select#1 */ select `test`.`t2`.`i` AS `i`,`test`.`t2`.`c` AS `c` from `test`.`t2` where (`test`.`t2`.`c` = 50)
SET SESSION rocksdb_records_in_range_dive_threshold = DEFAULT;
explain select * from t2 where c = 50;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 NULL ref kc kc 4 const 100 100.00 Using index
Warnings:
Note 1003 /* select#1 */ select `test`.`t2`.`i` AS `i`,`test`.`t2`.`c` AS `c` from `test`.`t2` where (`test`.`t2`.`c` = 50)
# 0 disables the dive: legacy behavior, the estimate collapses to
# 1 row (this is the PS-10110 bug).
SET SESSION rocksdb_records_in_range_dive_threshold = 0;
explain select * from t2 where c = 50;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 NULL ref kc kc 4 const 1 100.00 Using index
Warnings:
Note 1003 /* select#1 */ select `test`.`t2`.`i` AS `i`,`test`.`t2`.`c` AS `c` from `test`.`t2` where (`test`.`t2`.`c` = 50)
SET SESSION rocksdb_records_in_range_dive_threshold = @save_dive;
DROP TABLE t1;
DROP TABLE t2;
1 change: 1 addition & 0 deletions mysql-test/suite/rocksdb/r/rocksdb.result
Original file line number Diff line number Diff line change
Expand Up @@ -1036,6 +1036,7 @@ rocksdb_rate_limiter_bytes_per_sec 0
rocksdb_read_free_rpl OFF
rocksdb_read_free_rpl_tables .*
rocksdb_records_in_range 50
rocksdb_records_in_range_dive_threshold 100
rocksdb_reset_stats OFF
rocksdb_rollback_on_timeout OFF
rocksdb_rpl_skip_tx_api OFF
Expand Down
113 changes: 113 additions & 0 deletions mysql-test/suite/rocksdb/t/records_in_range_dive.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
--source include/have_rocksdb.inc

# PS-10110: records_in_range() returned 1 row for narrow ranges that fall
# within a single SST data block (or a narrow memtable range), because
# RocksDB size approximations work at data block granularity and return 0.
# The estimate is now refined with a bounded index dive controlled by
# rocksdb_records_in_range_dive_threshold: an exact key count if the range
# has fewer keys than the threshold, a lower bound of the threshold
# otherwise.
#
# Note: no FORCE INDEX in the queries below - with FORCE INDEX the SQL
# layer skips records_in_range() entirely.

CREATE TABLE t1 (
i INT PRIMARY KEY AUTO_INCREMENT,
a INT NOT NULL,
b INT NOT NULL,
KEY ka(a),
KEY kb(b) comment 'cfname=rev:cf1'
) ENGINE = rocksdb;

# 20000 rows spread over a = b = 1..1000 (20 rows each), plus exactly 200
# rows with a = b = 5000.
--disable_query_log
let $i = 1;
while ($i <= 1000) {
eval INSERT INTO t1(a, b) VALUES
($i,$i),($i,$i),($i,$i),($i,$i),($i,$i),
($i,$i),($i,$i),($i,$i),($i,$i),($i,$i),
($i,$i),($i,$i),($i,$i),($i,$i),($i,$i),
($i,$i),($i,$i),($i,$i),($i,$i),($i,$i);
inc $i;
}
let $i = 1;
while ($i <= 200) {
INSERT INTO t1(a, b) VALUES (5000, 5000);
inc $i;
}
--enable_query_log

SET @save_dive = @@session.rocksdb_records_in_range_dive_threshold;
SET SESSION rocksdb_records_in_range_dive_threshold = 10000;

--echo #
--echo # Memtable-only: the dive must count the narrow range exactly (200),
--echo # instead of the pre-fix estimate of 1.
--echo #
explain select * from t1 where a = 5000;
explain select * from t1 where b = 5000;
explain select * from t1 where a > 4999 and a < 5001;

--echo #
--echo # SST path: flush the memtable; the dive still counts the narrow
--echo # range exactly.
--echo #
set global rocksdb_force_flush_memtable_now = true;
analyze table t1;
explain select * from t1 where a = 5000;
explain select * from t1 where b = 5000;
explain select * from t1 where a > 4999 and a < 5001;

--echo #
--echo # An empty range stays at the conventional 1 row.
--echo #
explain select * from t1 where a = 9999;

--echo #
--echo # Deterministic single-block scenario: index kc lives in its own
--echo # column family whose whole SST fits in one ~16KB data block, so
--echo # GetApproximateSizes() is guaranteed to return 0 for any range that
--echo # does not extend past the last key: the exact situation from the
--echo # bug report.
--echo #
CREATE TABLE t2 (
i INT PRIMARY KEY AUTO_INCREMENT,
c INT NOT NULL,
KEY kc(c) comment 'cfname=cf_dive'
) ENGINE = rocksdb;
--disable_query_log
let $i = 1;
while ($i <= 100) {
eval INSERT INTO t2(c) VALUES ($i);
inc $i;
}
let $i = 1;
while ($i <= 200) {
INSERT INTO t2(c) VALUES (50);
inc $i;
}
--enable_query_log
set global rocksdb_force_flush_memtable_now = true;
analyze table t2;

--echo # Dive enabled: exact count (201 keys with c = 50).
SET SESSION rocksdb_records_in_range_dive_threshold = 10000;
explain select * from t2 where c = 50;

--echo # Cap semantics: the dive reads at most threshold keys, so a range
--echo # with more keys than the threshold estimates as the threshold
--echo # (a lower bound).
SET SESSION rocksdb_records_in_range_dive_threshold = 50;
explain select * from t2 where c = 50;
SET SESSION rocksdb_records_in_range_dive_threshold = DEFAULT;
explain select * from t2 where c = 50;

--echo # 0 disables the dive: legacy behavior, the estimate collapses to
--echo # 1 row (this is the PS-10110 bug).
SET SESSION rocksdb_records_in_range_dive_threshold = 0;
explain select * from t2 where c = 50;

SET SESSION rocksdb_records_in_range_dive_threshold = @save_dive;
DROP TABLE t1;
DROP TABLE t2;
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
CREATE TABLE valid_values (value varchar(255)) ENGINE=myisam;
INSERT INTO valid_values VALUES(1);
INSERT INTO valid_values VALUES(0);
INSERT INTO valid_values VALUES(100);
INSERT INTO valid_values VALUES(222333);
CREATE TABLE invalid_values (value varchar(255)) ENGINE=myisam;
INSERT INTO invalid_values VALUES('\'aaa\'');
INSERT INTO invalid_values VALUES('\'bbb\'');
SET @start_global_value = @@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD;
SELECT @start_global_value;
@start_global_value
100
SET @start_session_value = @@session.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD;
SELECT @start_session_value;
@start_session_value
100
'# Setting to valid values in global scope#'
"Trying to set variable @@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD to 1"
SET @@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD = 1;
SELECT @@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD;
@@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD
1
"Setting the global scope variable back to default"
SET @@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD = DEFAULT;
SELECT @@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD;
@@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD
100
"Trying to set variable @@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD to 0"
SET @@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD = 0;
SELECT @@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD;
@@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD
0
"Setting the global scope variable back to default"
SET @@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD = DEFAULT;
SELECT @@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD;
@@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD
100
"Trying to set variable @@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD to 100"
SET @@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD = 100;
SELECT @@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD;
@@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD
100
"Setting the global scope variable back to default"
SET @@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD = DEFAULT;
SELECT @@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD;
@@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD
100
"Trying to set variable @@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD to 222333"
SET @@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD = 222333;
SELECT @@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD;
@@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD
222333
"Setting the global scope variable back to default"
SET @@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD = DEFAULT;
SELECT @@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD;
@@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD
100
'# Setting to valid values in session scope#'
"Trying to set variable @@session.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD to 1"
SET @@session.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD = 1;
SELECT @@session.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD;
@@session.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD
1
"Setting the session scope variable back to default"
SET @@session.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD = DEFAULT;
SELECT @@session.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD;
@@session.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD
100
"Trying to set variable @@session.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD to 0"
SET @@session.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD = 0;
SELECT @@session.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD;
@@session.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD
0
"Setting the session scope variable back to default"
SET @@session.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD = DEFAULT;
SELECT @@session.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD;
@@session.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD
100
"Trying to set variable @@session.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD to 100"
SET @@session.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD = 100;
SELECT @@session.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD;
@@session.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD
100
"Setting the session scope variable back to default"
SET @@session.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD = DEFAULT;
SELECT @@session.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD;
@@session.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD
100
"Trying to set variable @@session.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD to 222333"
SET @@session.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD = 222333;
SELECT @@session.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD;
@@session.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD
222333
"Setting the session scope variable back to default"
SET @@session.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD = DEFAULT;
SELECT @@session.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD;
@@session.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD
100
'# Testing with invalid values in global scope #'
"Trying to set variable @@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD to 'aaa'"
SET @@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD = 'aaa';
Got one of the listed errors
SELECT @@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD;
@@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD
100
"Trying to set variable @@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD to 'bbb'"
SET @@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD = 'bbb';
Got one of the listed errors
SELECT @@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD;
@@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD
100
SET @@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD = @start_global_value;
SELECT @@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD;
@@global.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD
100
SET @@session.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD = @start_session_value;
SELECT @@session.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD;
@@session.ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD
100
DROP TABLE valid_values;
DROP TABLE invalid_values;
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
--source include/have_rocksdb.inc
--source include/have_myisam.inc

CREATE TABLE valid_values (value varchar(255)) ENGINE=myisam;
INSERT INTO valid_values VALUES(1);
INSERT INTO valid_values VALUES(0);
INSERT INTO valid_values VALUES(100);
INSERT INTO valid_values VALUES(222333);

CREATE TABLE invalid_values (value varchar(255)) ENGINE=myisam;
INSERT INTO invalid_values VALUES('\'aaa\'');
INSERT INTO invalid_values VALUES('\'bbb\'');

--let $sys_var=ROCKSDB_RECORDS_IN_RANGE_DIVE_THRESHOLD
--let $read_only=0
--let $session=1
--source ../include/rocksdb_sys_var.inc

DROP TABLE valid_values;
DROP TABLE invalid_values;
Loading
Loading