summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Petrunia <psergey@askmonty.org>2018-08-31 16:36:27 +0300
committerSergei Petrunia <psergey@askmonty.org>2018-08-31 16:36:27 +0300
commit865831c683933d2308cb9770212d116188e2a26d (patch)
tree17cab13ed932e80ac270cbb081a4d272e5814c88
parentc8a3c2bc96b4aae4c5edc27e0fe7ff14ad73e88c (diff)
parent52e0dee037b009fa1a0aade1c810765b55935939 (diff)
downloadmariadb-git-865831c683933d2308cb9770212d116188e2a26d.tar.gz
Merge branch 'bb-10.2-mariarocks-merge' into 10.2
-rw-r--r--mysql-test/include/search_pattern_in_file.inc16
-rw-r--r--storage/rocksdb/CMakeLists.txt17
-rw-r--r--storage/rocksdb/build_rocksdb.cmake6
-rw-r--r--storage/rocksdb/ha_rocksdb.cc1234
-rw-r--r--storage/rocksdb/ha_rocksdb.h53
-rw-r--r--storage/rocksdb/ha_rocksdb_proto.h7
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/combinations6
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/include/have_write_committed.inc3
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/add_index_inplace.result24
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/add_index_inplace_sstfilewriter.result2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/autoinc_debug.result40
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/autoinc_vars.result18
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/bloomfilter_bulk_load.result15
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/bulk_load_sk.result229
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/cardinality.result17
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/collation.result20
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/com_rpc_tx.result21
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/create_no_primary_key_table.result38
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/ddl_high_priority.result71
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/deadlock_tracking.result57
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/drop_table.result19
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/explicit_snapshot.result265
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/i_s_deadlock.result55
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/index_file_map.result3
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/index_merge_rocksdb2.result52
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/information_schema.result1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/lock.result15
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/mysqldump.result5
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/percona_nonflushing_analyze_debug.result19
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/prefix_extractor_override.result7
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/rocksdb.result24
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/rocksdb_checksums.result27
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/rocksdb_deadlock_detect_rc.result23
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/rocksdb_deadlock_detect_rr.result23
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/secondary_key_update_lock.result18
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/show_engine.result53
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/transaction.result17
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/trx_info_rpl.result2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/update.result8
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/use_direct_reads.result18
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/validate_datadic.result5
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace.test18
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace_crash.test1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace_sstfilewriter.test2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/autoinc_debug.test17
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/autoinc_vars.test23
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/bloomfilter5-master.opt4
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/bloomfilter_bulk_load-master.opt2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/bloomfilter_bulk_load.test35
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/bulk_load_sk.test119
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/cardinality.test21
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/check_ignore_unknown_options.test6
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/collation.test36
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/com_rpc_tx.cnf4
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/com_rpc_tx.test87
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/create_no_primary_key_table-master.opt1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/create_no_primary_key_table.test44
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/deadlock_tracking.test76
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/disabled.def6
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/drop_table.test27
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/explicit_snapshot-master.opt1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/explicit_snapshot.test263
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/i_s_deadlock.test14
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/index_file_map.test3
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/index_merge_rocksdb2-master.opt2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/information_schema.test1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/insert_optimized_config-master.opt8
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/insert_optimized_config.test10
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/lock.test22
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/percona_nonflushing_analyze_debug.test11
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/prefix_extractor_override.test14
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/rocksdb.test3
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/rocksdb_checksums.test23
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/rocksdb_deadlock_detect.inc35
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/secondary_key_update_lock.test26
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/set_checkpoint.inc2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/show_engine.test13
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/transaction.test23
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/trx_info_rpl.test4
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/update.test10
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/use_direct_reads.test37
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/validate_datadic.test25
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/combinations8
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_missing_columns_sk_update.result62
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_mts_dependency_unique_key_conflicts.result44
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_rocksdb_snapshot.result4
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/disabled.def1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_wal_corrupt.inc2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_missing_columns_sk_update.cnf13
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_missing_columns_sk_update.test69
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_mts_dependency_unique_key_conflicts.test64
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_2pc_crash_recover.test1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_stress/combinations5
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_block_cache_size_basic.result84
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_bulk_load_allow_sk_basic.result100
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_commit_time_batch_for_recovery_basic.result121
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_create_checkpoint_basic.result2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_debug_manual_compaction_delay_basic.result46
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_error_on_suboptimal_collation_basic.result7
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_manual_compaction_threads_basic.result93
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_max_manifest_file_size_basic.result2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_max_manual_compactions_basic.result57
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_max_row_locks_basic.result21
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_stats_recalc_rate_basic.result53
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_write_batch_max_bytes_basic.result4
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_write_policy_basic.result15
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_block_cache_size_basic.test16
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_bulk_load_allow_sk_basic.test18
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_commit_time_batch_for_recovery_basic.test20
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_create_checkpoint_basic.test2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_debug_manual_compaction_delay_basic.test16
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_error_on_suboptimal_collation_basic.test6
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_manual_compaction_threads_basic.test17
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_max_manual_compactions_basic.test17
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_max_row_locks_basic.test1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_stats_recalc_rate_basic.test17
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_write_batch_max_bytes_basic.test4
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_write_policy_basic.test17
-rw-r--r--storage/rocksdb/properties_collector.cc61
-rw-r--r--storage/rocksdb/properties_collector.h3
-rw-r--r--storage/rocksdb/rdb_cf_options.cc2
-rw-r--r--storage/rocksdb/rdb_comparator.h46
-rw-r--r--storage/rocksdb/rdb_datadic.cc6
-rw-r--r--storage/rocksdb/rdb_datadic.h5
-rw-r--r--storage/rocksdb/rdb_i_s.cc167
-rw-r--r--storage/rocksdb/rdb_i_s.h1
-rw-r--r--storage/rocksdb/rdb_index_merge.cc5
-rw-r--r--storage/rocksdb/rdb_perf_context.cc2
-rw-r--r--storage/rocksdb/rdb_psi.cc17
-rw-r--r--storage/rocksdb/rdb_psi.h10
-rw-r--r--storage/rocksdb/rdb_sst_info.cc4
-rw-r--r--storage/rocksdb/rdb_threads.h31
-rw-r--r--storage/rocksdb/rdb_utils.cc23
m---------storage/rocksdb/rocksdb0
135 files changed, 4395 insertions, 650 deletions
diff --git a/mysql-test/include/search_pattern_in_file.inc b/mysql-test/include/search_pattern_in_file.inc
index 21192b55efb..6bead628fb0 100644
--- a/mysql-test/include/search_pattern_in_file.inc
+++ b/mysql-test/include/search_pattern_in_file.inc
@@ -18,6 +18,11 @@
# Optionally, SEARCH_ABORT can be set to "FOUND" or "NOT FOUND" and this
# will abort if the search result doesn't match the requested one.
#
+# Optionally, SEARCH_OUTPUT can be set to control the format of output.
+# Supported formats:
+# - (default) : "FOUND n /pattern/ in FILE " or "NOT FOUND ..."
+# - "matches" : Each match is printed, on a separate line
+#
# In case of
# - SEARCH_FILE and/or SEARCH_PATTERN is not set
# - SEARCH_FILE cannot be opened
@@ -75,7 +80,14 @@ perl;
my @matches=($content =~ m/$search_pattern/gs);
my $res=@matches ? "FOUND " . scalar(@matches) : "NOT FOUND";
$ENV{SEARCH_FILE} =~ s{^.*?([^/\\]+)$}{$1};
- print "$res /$search_pattern/ in $ENV{SEARCH_FILE}\n";
+
+ if ($ENV{SEARCH_OUTPUT} eq "matches") {
+ foreach (@matches) {
+ print $_ . "\n";
+ }
+ } else {
+ print "$res /$search_pattern/ in $ENV{SEARCH_FILE}\n";
+ }
die "$ENV{SEARCH_ABORT}\n"
- if $ENV{SEARCH_ABORT} && $res =~ /^$ENV{SEARCH_ABORT}/;
+ if $ENV{SEARCH_ABORT} && $res =~ /^$ENV{SEARCH_ABORT}/;
EOF
diff --git a/storage/rocksdb/CMakeLists.txt b/storage/rocksdb/CMakeLists.txt
index 2a4ea4dfc0f..7aab8034b07 100644
--- a/storage/rocksdb/CMakeLists.txt
+++ b/storage/rocksdb/CMakeLists.txt
@@ -43,6 +43,15 @@ IF (WIN32 AND CMAKE_SIZEOF_VOID_P EQUAL 4)
SKIP_ROCKSDB_PLUGIN("32-Bit Windows are temporarily disabled")
ENDIF()
+#
+# RocksDB's port/win/env_win.cc uses parts of Windows API that are not part
+# of the LEAN_AND_MEAN set. Ideally we should undef LEAN_AND_MEAN only for
+# that file, but REMOVE_DEFINITIONS only works per-directory?
+#
+IF (WIN32)
+ REMOVE_DEFINITIONS(-DWIN32_LEAN_AND_MEAN)
+ENDIF()
+
# This plugin needs recent C++ compilers (it is using C++11 features)
# Skip build for the old compilers
SET(CXX11_FLAGS)
@@ -155,6 +164,9 @@ if (UNIX AND NOT APPLE)
endif()
TARGET_LINK_LIBRARIES(rocksdb rocksdb_aux_lib)
+ FIND_LIBRARY(LZ4_LIBRARY
+ NAMES liblz4${PIC_EXT}.a lz4
+ HINTS ${WITH_LZ4}/lib)
IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
@@ -182,8 +194,11 @@ IF(HAVE_SCHED_GETCPU)
ENDIF()
IF (WITH_TBB)
+ FIND_LIBRARY(TBB_LIBRARY
+ NAMES libtbb${PIC_EXT}.a tbb
+ HINTS ${WITH_TBB}/lib)
SET(rocksdb_static_libs ${rocksdb_static_libs}
- ${WITH_TBB}/lib/libtbb${PIC_EXT}.a)
+ ${TBB_LIBRARY})
ADD_DEFINITIONS(-DTBB)
ENDIF()
diff --git a/storage/rocksdb/build_rocksdb.cmake b/storage/rocksdb/build_rocksdb.cmake
index 895d473c2d4..f09024ef800 100644
--- a/storage/rocksdb/build_rocksdb.cmake
+++ b/storage/rocksdb/build_rocksdb.cmake
@@ -178,6 +178,7 @@ set(ROCKSDB_SOURCES
db/db_info_dumper.cc
db/db_iter.cc
db/dbformat.cc
+ db/error_handler.cc
db/event_helpers.cc
db/experimental.cc
db/external_sst_file_ingestion_job.cc
@@ -188,6 +189,7 @@ set(ROCKSDB_SOURCES
db/internal_stats.cc
db/log_reader.cc
db/log_writer.cc
+ db/logs_with_prep_tracker.cc
db/malloc_stats.cc
db/managed_iterator.cc
db/memtable.cc
@@ -284,6 +286,7 @@ set(ROCKSDB_SOURCES
util/coding.cc
util/compaction_job_stats_impl.cc
util/comparator.cc
+ util/compression_context_cache.cc
util/concurrent_arena.cc
util/crc32c.cc
util/delete_scheduler.cc
@@ -304,6 +307,7 @@ set(ROCKSDB_SOURCES
util/status_message.cc
util/string_util.cc
util/sync_point.cc
+ util/sync_point_impl.cc
util/testutil.cc
util/thread_local.cc
util/threadpool_imp.cc
@@ -352,6 +356,8 @@ set(ROCKSDB_SOURCES
utilities/transactions/transaction_util.cc
utilities/transactions/write_prepared_txn.cc
utilities/transactions/write_prepared_txn_db.cc
+ utilities/transactions/write_unprepared_txn.cc
+ utilities/transactions/write_unprepared_txn_db.cc
utilities/ttl/db_ttl_impl.cc
utilities/write_batch_with_index/write_batch_with_index.cc
utilities/write_batch_with_index/write_batch_with_index_internal.cc
diff --git a/storage/rocksdb/ha_rocksdb.cc b/storage/rocksdb/ha_rocksdb.cc
index adef71e4e4a..565bbf01d8b 100644
--- a/storage/rocksdb/ha_rocksdb.cc
+++ b/storage/rocksdb/ha_rocksdb.cc
@@ -32,6 +32,7 @@
/* C++ standard header files */
#include <algorithm>
+#include <inttypes.h>
#include <limits>
#include <map>
#include <queue>
@@ -127,6 +128,60 @@ const std::string DEFAULT_CF_NAME("default");
const std::string DEFAULT_SYSTEM_CF_NAME("__system__");
const std::string PER_INDEX_CF_NAME("$per_index_cf");
+class Rdb_explicit_snapshot;
+
+std::mutex explicit_snapshot_mutex;
+ulonglong explicit_snapshot_counter = 0;
+std::unordered_map<ulonglong, std::weak_ptr<Rdb_explicit_snapshot>>
+ explicit_snapshots;
+static std::vector<GL_INDEX_ID> rdb_indexes_to_recalc;
+
+#ifdef MARIADB_NOT_YET
+class Rdb_explicit_snapshot : public explicit_snapshot {
+ std::unique_ptr<rocksdb::ManagedSnapshot> snapshot;
+
+ public:
+ static std::shared_ptr<Rdb_explicit_snapshot>
+ create(snapshot_info_st *ss_info, rocksdb::DB *db,
+ const rocksdb::Snapshot *snapshot) {
+ std::lock_guard<std::mutex> lock(explicit_snapshot_mutex);
+ auto s = std::unique_ptr<rocksdb::ManagedSnapshot>(
+ new rocksdb::ManagedSnapshot(db, snapshot));
+ if (!s) {
+ return nullptr;
+ }
+ ss_info->snapshot_id = ++explicit_snapshot_counter;
+ auto ret = std::make_shared<Rdb_explicit_snapshot>(*ss_info, std::move(s));
+ if (!ret) {
+ return nullptr;
+ }
+ explicit_snapshots[ss_info->snapshot_id] = ret;
+ return ret;
+ }
+
+ static std::shared_ptr<Rdb_explicit_snapshot>
+ get(const ulonglong snapshot_id) {
+ std::lock_guard<std::mutex> lock(explicit_snapshot_mutex);
+ auto elem = explicit_snapshots.find(snapshot_id);
+ if (elem == explicit_snapshots.end()) {
+ return nullptr;
+ }
+ return elem->second.lock();
+ }
+
+ rocksdb::ManagedSnapshot *get_snapshot() { return snapshot.get(); }
+
+ Rdb_explicit_snapshot(snapshot_info_st ss_info,
+ std::unique_ptr<rocksdb::ManagedSnapshot> snapshot)
+ : explicit_snapshot(ss_info), snapshot(std::move(snapshot)) {}
+
+ virtual ~Rdb_explicit_snapshot() {
+ std::lock_guard<std::mutex> lock(explicit_snapshot_mutex);
+ explicit_snapshots.erase(ss_info.snapshot_id);
+ }
+};
+#endif
+
/**
Updates row counters based on the table type and operation type.
*/
@@ -144,11 +199,15 @@ static handler *rocksdb_create_handler(my_core::handlerton *hton,
my_core::TABLE_SHARE *table_arg,
my_core::MEM_ROOT *mem_root);
-static rocksdb::CompactRangeOptions getCompactRangeOptions() {
+static rocksdb::CompactRangeOptions
+getCompactRangeOptions(int concurrency = 0) {
rocksdb::CompactRangeOptions compact_range_options;
compact_range_options.bottommost_level_compaction =
rocksdb::BottommostLevelCompaction::kForce;
compact_range_options.exclusive_manual_compaction = false;
+ if (concurrency > 0) {
+ compact_range_options.max_subcompactions = concurrency;
+ }
return compact_range_options;
}
@@ -187,6 +246,8 @@ Rdb_io_watchdog *io_watchdog = nullptr;
static Rdb_background_thread rdb_bg_thread;
+static Rdb_manual_compaction_thread rdb_mc_thread;
+
// List of table names (using regex) that are exceptions to the strict
// collation check requirement.
Regex_list_handler *rdb_collation_exceptions;
@@ -200,30 +261,6 @@ static void rocksdb_flush_all_memtables() {
}
}
-static void rocksdb_compact_column_family_stub(
- THD *const thd, struct st_mysql_sys_var *const var, void *const var_ptr,
- const void *const save) {}
-
-static int rocksdb_compact_column_family(THD *const thd,
- struct st_mysql_sys_var *const var,
- void *const var_ptr,
- struct st_mysql_value *const value) {
- char buff[STRING_BUFFER_USUAL_SIZE];
- int len = sizeof(buff);
-
- DBUG_ASSERT(value != nullptr);
-
- if (const char *const cf = value->val_str(value, buff, &len)) {
- auto cfh = cf_manager.get_cf(cf);
- if (cfh != nullptr && rdb != nullptr) {
- sql_print_verbose_info("RocksDB: Manual compaction of column family: %s\n",
- cf);
- rdb->CompactRange(getCompactRangeOptions(), cfh, nullptr, nullptr);
- }
- }
- return HA_EXIT_SUCCESS;
-}
-
///////////////////////////////////////////////////////////
// Hash map: table name => open table handler
///////////////////////////////////////////////////////////
@@ -249,6 +286,8 @@ struct Rdb_open_tables_map {
Rdb_open_tables_map() : m_hash(get_hash_key, system_charset_info) { }
+ void free_hash(void) { m_hash.~Rdb_table_set(); }
+
std::vector<std::string> get_table_names(void) const;
};
@@ -368,6 +407,7 @@ static void rocksdb_drop_index_wakeup_thread(
static my_bool rocksdb_pause_background_work = 0;
static mysql_mutex_t rdb_sysvars_mutex;
+static mysql_mutex_t rdb_block_cache_resize_mutex;
static void rocksdb_set_pause_background_work(
my_core::THD *const thd MY_ATTRIBUTE((__unused__)),
@@ -450,6 +490,9 @@ static void rocksdb_set_wal_bytes_per_sync(THD *thd,
struct st_mysql_sys_var *const var,
void *const var_ptr,
const void *const save);
+static int rocksdb_validate_set_block_cache_size(
+ THD *thd, struct st_mysql_sys_var *const var, void *var_ptr,
+ struct st_mysql_value *value);
//////////////////////////////////////////////////////////////////////////////
// Options definitions
//////////////////////////////////////////////////////////////////////////////
@@ -510,11 +553,19 @@ static char* rocksdb_git_hash;
char *compression_types_val=
const_cast<char*>(get_rocksdb_supported_compression_types());
+static unsigned long rocksdb_write_policy =
+ rocksdb::TxnDBWritePolicy::WRITE_COMMITTED;
+static my_bool rocksdb_error_on_suboptimal_collation = 1;
+static uint32_t rocksdb_stats_recalc_rate = 0;
+static uint32_t rocksdb_debug_manual_compaction_delay = 0;
+static uint32_t rocksdb_max_manual_compactions = 0;
std::atomic<uint64_t> rocksdb_row_lock_deadlocks(0);
std::atomic<uint64_t> rocksdb_row_lock_wait_timeouts(0);
std::atomic<uint64_t> rocksdb_snapshot_conflict_errors(0);
std::atomic<uint64_t> rocksdb_wal_group_syncs(0);
+std::atomic<uint64_t> rocksdb_manual_compactions_processed(0);
+std::atomic<uint64_t> rocksdb_manual_compactions_running(0);
@@ -600,6 +651,14 @@ static std::unique_ptr<rocksdb::DBOptions> rocksdb_db_options =
static std::shared_ptr<rocksdb::RateLimiter> rocksdb_rate_limiter;
+/* This enum needs to be kept up to date with rocksdb::TxnDBWritePolicy */
+static const char *write_policy_names[] = {"write_committed", "write_prepared",
+ "write_unprepared", NullS};
+
+static TYPELIB write_policy_typelib = {array_elements(write_policy_names) - 1,
+ "write_policy_typelib",
+ write_policy_names, nullptr};
+
/* This enum needs to be kept up to date with rocksdb::InfoLogLevel */
static const char *info_log_level_names[] = {"debug_level", "info_level",
"warn_level", "error_level",
@@ -694,6 +753,14 @@ static int rocksdb_validate_flush_log_at_trx_commit(
*static_cast<uint32_t *>(var_ptr) = static_cast<uint32_t>(new_value);
return HA_EXIT_SUCCESS;
}
+static void rocksdb_compact_column_family_stub(
+ THD *const thd, struct st_mysql_sys_var *const var, void *const var_ptr,
+ const void *const save) {}
+
+static int rocksdb_compact_column_family(THD *const thd,
+ struct st_mysql_sys_var *const var,
+ void *const var_ptr,
+ struct st_mysql_value *const value);
static const char *index_type_names[] = {"kBinarySearch", "kHashSearch", NullS};
@@ -702,7 +769,8 @@ static TYPELIB index_type_typelib = {array_elements(index_type_names) - 1,
nullptr};
const ulong RDB_MAX_LOCK_WAIT_SECONDS = 1024 * 1024 * 1024;
-const ulong RDB_MAX_ROW_LOCKS = 1024 * 1024;
+const ulong RDB_DEFAULT_MAX_ROW_LOCKS = 1024 * 1024;
+const ulong RDB_MAX_ROW_LOCKS = 1024 * 1024 * 1024;
const ulong RDB_DEFAULT_BULK_LOAD_SIZE = 1000;
const ulong RDB_MAX_BULK_LOAD_SIZE = 1024 * 1024 * 1024;
const size_t RDB_DEFAULT_MERGE_BUF_SIZE = 64 * 1024 * 1024;
@@ -734,6 +802,11 @@ static MYSQL_THDVAR_ULONG(deadlock_detect_depth, PLUGIN_VAR_RQCMDARG,
/*max*/ ULONG_MAX, 0);
static MYSQL_THDVAR_BOOL(
+ commit_time_batch_for_recovery, PLUGIN_VAR_RQCMDARG,
+ "TransactionOptions::commit_time_batch_for_recovery for RocksDB", nullptr,
+ nullptr, FALSE);
+
+static MYSQL_THDVAR_BOOL(
trace_sst_api, PLUGIN_VAR_RQCMDARG,
"Generate trace output in the log for each call to the SstFileWriter",
nullptr, nullptr, FALSE);
@@ -744,6 +817,13 @@ static MYSQL_THDVAR_BOOL(
"unique_checks and enables rocksdb_commit_in_the_middle.",
rocksdb_check_bulk_load, nullptr, FALSE);
+static MYSQL_THDVAR_BOOL(bulk_load_allow_sk, PLUGIN_VAR_RQCMDARG,
+ "Allow bulk loading of sk keys during bulk-load. "
+ "Can be changed only when bulk load is disabled.",
+ /* Intentionally reuse unsorted's check function */
+ rocksdb_check_bulk_load_allow_unsorted, nullptr,
+ FALSE);
+
static MYSQL_THDVAR_BOOL(bulk_load_allow_unsorted, PLUGIN_VAR_RQCMDARG,
"Allow unsorted input during bulk-load. "
"Can be changed only when bulk load is disabled.",
@@ -794,7 +874,7 @@ static MYSQL_THDVAR_BOOL(skip_bloom_filter_on_read, PLUGIN_VAR_RQCMDARG,
static MYSQL_THDVAR_ULONG(max_row_locks, PLUGIN_VAR_RQCMDARG,
"Maximum number of locks a transaction can have",
nullptr, nullptr,
- /*default*/ RDB_MAX_ROW_LOCKS,
+ /*default*/ RDB_DEFAULT_MAX_ROW_LOCKS,
/*min*/ 1,
/*max*/ RDB_MAX_ROW_LOCKS, 0);
@@ -846,6 +926,12 @@ static MYSQL_THDVAR_ULONGLONG(
/* min (0ms) */ RDB_MIN_MERGE_TMP_FILE_REMOVAL_DELAY,
/* max */ SIZE_T_MAX, 1);
+static MYSQL_THDVAR_INT(
+ manual_compaction_threads, PLUGIN_VAR_RQCMDARG,
+ "How many rocksdb threads to run for manual compactions", nullptr, nullptr,
+ /* default rocksdb.dboption max_subcompactions */ 0,
+ /* min */ 0, /* max */ 128, 0);
+
static MYSQL_SYSVAR_BOOL(
create_if_missing,
*reinterpret_cast<my_bool *>(&rocksdb_db_options->create_if_missing),
@@ -867,6 +953,12 @@ static MYSQL_SYSVAR_BOOL(
"DBOptions::manual_wal_flush for RocksDB", nullptr, nullptr,
rocksdb_db_options->manual_wal_flush);
+static MYSQL_SYSVAR_ENUM(write_policy, rocksdb_write_policy,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "DBOptions::write_policy for RocksDB", nullptr,
+ nullptr, rocksdb::TxnDBWritePolicy::WRITE_COMMITTED,
+ &write_policy_typelib);
+
static MYSQL_SYSVAR_BOOL(
create_missing_column_families,
*reinterpret_cast<my_bool *>(
@@ -1077,7 +1169,9 @@ static MYSQL_SYSVAR_INT(table_cache_numshardbits,
"DBOptions::table_cache_numshardbits for RocksDB",
nullptr, nullptr,
rocksdb_db_options->table_cache_numshardbits,
- /* min */ 0, /* max */ INT_MAX, 0);
+ // LRUCache limits this to 19 bits, anything greater
+ // fails to create a cache and returns a nullptr
+ /* min */ 0, /* max */ 19, 0);
static MYSQL_SYSVAR_UINT64_T(wal_ttl_seconds, rocksdb_db_options->WAL_ttl_seconds,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
@@ -1187,8 +1281,9 @@ static MYSQL_SYSVAR_BOOL(
"DBOptions::enable_thread_tracking for RocksDB", nullptr, nullptr, true);
static MYSQL_SYSVAR_LONGLONG(block_cache_size, rocksdb_block_cache_size,
- PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
- "block_cache size for RocksDB", nullptr, nullptr,
+ PLUGIN_VAR_RQCMDARG,
+ "block_cache size for RocksDB",
+ rocksdb_validate_set_block_cache_size, nullptr,
/* default */ RDB_DEFAULT_BLOCK_CACHE_SIZE,
/* min */ RDB_MIN_BLOCK_CACHE_SIZE,
/* max */ LONGLONG_MAX,
@@ -1435,6 +1530,18 @@ static MYSQL_SYSVAR_BOOL(
"on PK TTL data. This variable is a no-op in non-debug builds.",
nullptr, nullptr, FALSE);
+static MYSQL_SYSVAR_UINT(
+ max_manual_compactions, rocksdb_max_manual_compactions, PLUGIN_VAR_RQCMDARG,
+ "Maximum number of pending + ongoing number of manual compactions.",
+ nullptr, nullptr, /* default */ 10, /* min */ 0, /* max */ UINT_MAX, 0);
+
+static MYSQL_SYSVAR_UINT(
+ debug_manual_compaction_delay, rocksdb_debug_manual_compaction_delay,
+ PLUGIN_VAR_RQCMDARG,
+ "For debugging purposes only. Sleeping specified seconds "
+ "for simulating long running compactions.",
+ nullptr, nullptr, 0, /* min */ 0, /* max */ UINT_MAX, 0);
+
static MYSQL_SYSVAR_BOOL(
reset_stats, rocksdb_reset_stats, PLUGIN_VAR_RQCMDARG,
"Reset the RocksDB internal statistics without restarting the DB.", nullptr,
@@ -1597,6 +1704,13 @@ static MYSQL_SYSVAR_UINT(
RDB_DEFAULT_TBL_STATS_SAMPLE_PCT, /* everything */ 0,
/* max */ RDB_TBL_STATS_SAMPLE_PCT_MAX, 0);
+static MYSQL_SYSVAR_UINT(
+ stats_recalc_rate, rocksdb_stats_recalc_rate, PLUGIN_VAR_RQCMDARG,
+ "The number of indexes per second to recalculate statistics for. 0 to "
+ "disable background recalculation.",
+ nullptr, nullptr, 0 /* default value */, 0 /* min value */,
+ UINT_MAX /* max value */, 0);
+
static MYSQL_SYSVAR_BOOL(
large_prefix, rocksdb_large_prefix, PLUGIN_VAR_RQCMDARG,
"Support large index prefix length of 3072 bytes. If off, the maximum "
@@ -1610,16 +1724,25 @@ static MYSQL_SYSVAR_BOOL(
"detected.",
nullptr, nullptr, FALSE);
+static MYSQL_SYSVAR_BOOL(error_on_suboptimal_collation,
+ rocksdb_error_on_suboptimal_collation,
+ PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
+ "Raise an error instead of warning if a sub-optimal "
+ "collation is used",
+ nullptr, nullptr, TRUE);
+
static const int ROCKSDB_ASSUMED_KEY_VALUE_DISK_SIZE = 100;
static struct st_mysql_sys_var *rocksdb_system_variables[] = {
MYSQL_SYSVAR(lock_wait_timeout),
MYSQL_SYSVAR(deadlock_detect),
MYSQL_SYSVAR(deadlock_detect_depth),
+ MYSQL_SYSVAR(commit_time_batch_for_recovery),
MYSQL_SYSVAR(max_row_locks),
MYSQL_SYSVAR(write_batch_max_bytes),
MYSQL_SYSVAR(lock_scanned_rows),
MYSQL_SYSVAR(bulk_load),
+ MYSQL_SYSVAR(bulk_load_allow_sk),
MYSQL_SYSVAR(bulk_load_allow_unsorted),
MYSQL_SYSVAR(skip_unique_check_tables),
MYSQL_SYSVAR(trace_sst_api),
@@ -1637,6 +1760,7 @@ static struct st_mysql_sys_var *rocksdb_system_variables[] = {
MYSQL_SYSVAR(create_if_missing),
MYSQL_SYSVAR(two_write_queues),
MYSQL_SYSVAR(manual_wal_flush),
+ MYSQL_SYSVAR(write_policy),
MYSQL_SYSVAR(create_missing_column_families),
MYSQL_SYSVAR(error_if_exists),
MYSQL_SYSVAR(paranoid_checks),
@@ -1754,6 +1878,11 @@ static struct st_mysql_sys_var *rocksdb_system_variables[] = {
MYSQL_SYSVAR(large_prefix),
MYSQL_SYSVAR(allow_to_start_after_corruption),
MYSQL_SYSVAR(git_hash),
+ MYSQL_SYSVAR(error_on_suboptimal_collation),
+ MYSQL_SYSVAR(stats_recalc_rate),
+ MYSQL_SYSVAR(debug_manual_compaction_delay),
+ MYSQL_SYSVAR(max_manual_compactions),
+ MYSQL_SYSVAR(manual_compaction_threads),
nullptr};
static rocksdb::WriteOptions
@@ -1768,6 +1897,50 @@ rdb_get_rocksdb_write_options(my_core::THD *const thd) {
return opt;
}
+static int rocksdb_compact_column_family(THD *const thd,
+ struct st_mysql_sys_var *const var,
+ void *const var_ptr,
+ struct st_mysql_value *const value) {
+ char buff[STRING_BUFFER_USUAL_SIZE];
+ int len = sizeof(buff);
+
+ DBUG_ASSERT(value != nullptr);
+
+ if (const char *const cf = value->val_str(value, buff, &len)) {
+ auto cfh = cf_manager.get_cf(cf);
+ if (cfh != nullptr && rdb != nullptr) {
+ int mc_id = rdb_mc_thread.request_manual_compaction(
+ cfh, nullptr, nullptr, THDVAR(thd, manual_compaction_threads));
+ if (mc_id == -1) {
+ my_error(ER_INTERNAL_ERROR, MYF(0),
+ "Can't schedule more manual compactions. "
+ "Increase rocksdb_max_manual_compactions or stop issuing "
+ "more manual compactions.");
+ return HA_EXIT_FAILURE;
+ } else if (mc_id < 0) {
+ return HA_EXIT_FAILURE;
+ }
+ // NO_LINT_DEBUG
+ sql_print_information("RocksDB: Manual compaction of column family: %s\n",
+ cf);
+ // Checking thd state every short cycle (100ms). This is for allowing to
+ // exiting this function without waiting for CompactRange to finish.
+ do {
+ my_sleep(100000);
+ } while (!thd->killed &&
+ !rdb_mc_thread.is_manual_compaction_finished(mc_id));
+
+ if (thd->killed) {
+ // This cancels if requested compaction state is INITED.
+ // TODO(yoshinorim): Cancel running compaction as well once
+ // it is supported in RocksDB.
+ rdb_mc_thread.clear_manual_compaction_request(mc_id, true);
+ }
+ }
+ }
+ return HA_EXIT_SUCCESS;
+}
+
///////////////////////////////////////////////////////////////////////////////////////////
/**
@@ -1887,8 +2060,6 @@ protected:
bool m_is_two_phase = false;
private:
- /* Number of RockDB savepoints taken */
- int m_n_savepoints;
/*
Number of write operations this transaction had when we took the last
savepoint (the idea is not to take another savepoint if we haven't made
@@ -1897,9 +2068,9 @@ private:
ulonglong m_writes_at_last_savepoint;
protected:
- THD *m_thd = nullptr;
- rocksdb::ReadOptions m_read_opts;
+protected:
+ THD *m_thd = nullptr;
static std::multiset<Rdb_transaction *> s_tx_list;
static mysql_mutex_t s_tx_list_mutex;
@@ -1957,6 +2128,7 @@ protected:
}
public:
+ rocksdb::ReadOptions m_read_opts;
const char *m_mysql_log_file_name;
my_off_t m_mysql_log_offset;
#ifdef MARIAROCKS_NOT_YET
@@ -1967,6 +2139,7 @@ protected:
String m_detailed_error;
int64_t m_snapshot_timestamp = 0;
bool m_ddl_transaction;
+ std::shared_ptr<Rdb_explicit_snapshot> m_explicit_snapshot;
/*
Tracks the number of tables in use through external_lock.
@@ -2032,7 +2205,7 @@ protected:
if (s.IsDeadlock()) {
my_core::thd_mark_transaction_to_rollback(thd,
- false /* just statement */);
+ true /* whole transaction */);
m_detailed_error = String();
table_handler->m_deadlock_counter.inc();
rocksdb_row_lock_deadlocks++;
@@ -2049,7 +2222,7 @@ protected:
}
m_detailed_error = String(" (snapshot conflict)", system_charset_info);
table_handler->m_deadlock_counter.inc();
- return HA_ERR_LOCK_DEADLOCK;
+ return HA_ERR_ROCKSDB_STATUS_BUSY;
}
if (s.IsIOError() || s.IsCorruption()) {
@@ -2462,7 +2635,6 @@ public:
entire transaction.
*/
do_set_savepoint();
- m_n_savepoints= 1;
m_writes_at_last_savepoint= m_write_count;
}
@@ -2479,7 +2651,6 @@ public:
{
do_set_savepoint();
m_writes_at_last_savepoint= m_write_count;
- m_n_savepoints++;
}
}
@@ -2490,10 +2661,14 @@ public:
void rollback_to_stmt_savepoint() {
if (m_writes_at_last_savepoint != m_write_count) {
do_rollback_to_savepoint();
- if (!--m_n_savepoints) {
- do_set_savepoint();
- m_n_savepoints= 1;
- }
+ /*
+ RollbackToSavePoint "removes the most recent SetSavePoint()", so
+ we need to set it again so that next statement can roll back to this
+ stage.
+ It's ok to do it here at statement end (instead of doing it at next
+ statement start) because setting a savepoint is cheap.
+ */
+ do_set_savepoint();
m_writes_at_last_savepoint= m_write_count;
}
}
@@ -2666,6 +2841,17 @@ public:
void acquire_snapshot(bool acquire_now) override {
if (m_read_opts.snapshot == nullptr) {
+#ifdef MARIAROCKS_NOT_YET
+ const auto thd_ss = std::static_pointer_cast<Rdb_explicit_snapshot>(
+ m_thd->get_explicit_snapshot());
+ if (thd_ss) {
+ m_explicit_snapshot = thd_ss;
+ }
+ if (m_explicit_snapshot) {
+ auto snapshot = m_explicit_snapshot->get_snapshot()->snapshot();
+ snapshot_created(snapshot);
+ } else
+#endif
if (is_tx_read_only()) {
snapshot_created(rdb->GetSnapshot());
} else if (acquire_now) {
@@ -2683,6 +2869,12 @@ public:
if (m_read_opts.snapshot != nullptr) {
m_snapshot_timestamp = 0;
+#ifdef MARIAROCKS_NOT_YET
+ if (m_explicit_snapshot) {
+ m_explicit_snapshot.reset();
+ need_clear = false;
+ } else
+#endif
if (is_tx_read_only()) {
rdb->ReleaseSnapshot(m_read_opts.snapshot);
need_clear = false;
@@ -2792,6 +2984,10 @@ public:
tx_opts.lock_timeout = rdb_convert_sec_to_ms(m_timeout_sec);
tx_opts.deadlock_detect = THDVAR(m_thd, deadlock_detect);
tx_opts.deadlock_detect_depth = THDVAR(m_thd, deadlock_detect_depth);
+ // If this variable is set, this will write commit time write batch
+ // information on recovery or memtable flush.
+ tx_opts.use_only_the_last_commit_time_batch_for_recovery =
+ THDVAR(m_thd, commit_time_batch_for_recovery);
tx_opts.max_write_batch_size = THDVAR(m_thd, write_batch_max_bytes);
write_opts.sync = (rocksdb_flush_log_at_trx_commit == FLUSH_LOG_SYNC);
@@ -2886,7 +3082,7 @@ public:
/* This is a rocksdb write batch. This class doesn't hold or wait on any
transaction locks (skips rocksdb transaction API) thus giving better
- performance. The commit is done through rdb->GetBaseDB()->Commit().
+ performance.
Currently this is only used for replication threads which are guaranteed
to be non-conflicting. Any further usage of this class should completely
@@ -2908,6 +3104,8 @@ private:
bool commit_no_binlog() override {
bool res = false;
rocksdb::Status s;
+ rocksdb::TransactionDBWriteOptimizations optimize;
+ optimize.skip_concurrency_control = true;
s = merge_auto_incr_map(m_batch->GetWriteBatch());
if (!s.ok()) {
@@ -2918,7 +3116,7 @@ private:
release_snapshot();
- s = rdb->GetBaseDB()->Write(write_opts, m_batch->GetWriteBatch());
+ s = rdb->Write(write_opts, optimize, m_batch->GetWriteBatch());
if (!s.ok()) {
rdb_handle_io_error(s, RDB_IO_ERROR_TX_COMMIT);
res = true;
@@ -2936,7 +3134,6 @@ error:
return res;
}
-protected:
/* Implementations of do_*savepoint based on rocksdB::WriteBatch savepoints */
void do_set_savepoint() override {
m_batch->SetSavePoint();
@@ -2946,6 +3143,7 @@ protected:
m_batch->RollbackToSavePoint();
}
+
public:
bool is_writebatch_trx() const override { return true; }
@@ -3033,6 +3231,13 @@ public:
get_for_update(rocksdb::ColumnFamilyHandle *const column_family,
const rocksdb::Slice &key, rocksdb::PinnableSlice *const value,
bool exclusive) override {
+ if (value == nullptr) {
+ rocksdb::PinnableSlice pin_val;
+ rocksdb::Status s = get(column_family, key, &pin_val);
+ pin_val.Reset();
+ return s;
+ }
+
return get(column_family, key, value);
}
@@ -3564,6 +3769,7 @@ static int rocksdb_commit(handlerton* hton, THD* thd, bool commit_tx)
We get here when committing a statement within a transaction.
*/
tx->make_stmt_savepoint_permanent();
+ tx->make_stmt_savepoint_permanent();
}
if (my_core::thd_tx_isolation(thd) <= ISO_READ_COMMITTED) {
@@ -3752,6 +3958,7 @@ private:
if (!path_entry.path.empty() && !path_entry.limit_exceeded) {
auto deadlocking_txn = *(path_entry.path.end() - 1);
deadlock_info.victim_trx_id = deadlocking_txn.m_txn_id;
+ deadlock_info.deadlock_time = path_entry.deadlock_time;
}
return deadlock_info;
}
@@ -3799,16 +4006,18 @@ private:
path_data += "\n*** DEADLOCK PATH\n"
"=========================================\n";
const auto dl_info = get_dl_path_trx_info(path_entry);
+ const auto deadlock_time = dl_info.deadlock_time;
for (auto it = dl_info.path.begin(); it != dl_info.path.end(); it++) {
const auto trx_info = *it;
path_data += format_string(
+ "TIMESTAMP: %" PRId64 "\n"
"TRANSACTION ID: %u\n"
"COLUMN FAMILY NAME: %s\n"
"WAITING KEY: %s\n"
"LOCK TYPE: %s\n"
"INDEX NAME: %s\n"
"TABLE NAME: %s\n",
- trx_info.trx_id, trx_info.cf_name.c_str(),
+ deadlock_time, trx_info.trx_id, trx_info.cf_name.c_str(),
trx_info.waiting_key.c_str(),
trx_info.exclusive_lock ? "EXCLUSIVE" : "SHARED",
trx_info.index_name.c_str(), trx_info.table_name.c_str());
@@ -4082,7 +4291,7 @@ static bool rocksdb_show_status(handlerton *const hton, THD *const thd,
(ulonglong)internal_cache_count * kDefaultInternalCacheSize);
str.append(buf);
res |= print_stats(thd, "MEMORY_STATS", "rocksdb", str, stat_print);
-#ifdef MARIAROCKS_NOT_YET
+
/* Show the background thread status */
std::vector<rocksdb::ThreadStatus> thread_list;
rocksdb::Status s = rdb->GetEnv()->GetThreadList(&thread_list);
@@ -4119,8 +4328,27 @@ static bool rocksdb_show_status(handlerton *const hton, THD *const thd,
str, stat_print);
}
}
+
+#ifdef MARIAROCKS_NOT_YET
+ /* Explicit snapshot information */
+ str.clear();
+ {
+ std::lock_guard<std::mutex> lock(explicit_snapshot_mutex);
+ for (const auto &elem : explicit_snapshots) {
+ const auto &ss = elem.second.lock();
+ DBUG_ASSERT(ss != nullptr);
+ const auto &info = ss->ss_info;
+ str += "\nSnapshot ID: " + std::to_string(info.snapshot_id) +
+ "\nBinlog File: " + info.binlog_file +
+ "\nBinlog Pos: " + std::to_string(info.binlog_pos) +
+ "\nGtid Executed: " + info.gtid_executed + "\n";
+ }
+ }
#endif
+ if (!str.empty()) {
+ res |= print_stats(thd, "EXPLICIT_SNAPSHOTS", "rocksdb", str, stat_print);
+ }
#ifdef MARIAROCKS_NOT_YET
} else if (stat_type == HA_ENGINE_TRX) {
/* Handle the SHOW ENGINE ROCKSDB TRANSACTION STATUS command */
@@ -4143,6 +4371,50 @@ static inline void rocksdb_register_tx(handlerton *const hton, THD *const thd,
static const char *ha_rocksdb_exts[] = {NullS};
+#ifdef MARIAROCKS_NOT_YET
+static bool rocksdb_explicit_snapshot(
+ handlerton *const /* hton */, /*!< in: RocksDB handlerton */
+ THD *const thd, /*!< in: MySQL thread handle */
+ snapshot_info_st *ss_info) /*!< out: Snapshot information */
+{
+ switch (ss_info->op) {
+ case snapshot_operation::SNAPSHOT_CREATE: {
+ if (mysql_bin_log_is_open()) {
+ mysql_bin_log_lock_commits(ss_info);
+ }
+ auto s = Rdb_explicit_snapshot::create(ss_info, rdb, rdb->GetSnapshot());
+ if (mysql_bin_log_is_open()) {
+ mysql_bin_log_unlock_commits(ss_info);
+ }
+
+ thd->set_explicit_snapshot(s);
+ return s == nullptr;
+ }
+ case snapshot_operation::SNAPSHOT_ATTACH: {
+ auto s = Rdb_explicit_snapshot::get(ss_info->snapshot_id);
+ if (!s) {
+ return true;
+ }
+ *ss_info = s->ss_info;
+ thd->set_explicit_snapshot(s);
+ return false;
+ }
+ case snapshot_operation::SNAPSHOT_RELEASE: {
+ if (!thd->get_explicit_snapshot()) {
+ return true;
+ }
+ *ss_info = thd->get_explicit_snapshot()->ss_info;
+ thd->set_explicit_snapshot(nullptr);
+ return false;
+ }
+ default:
+ DBUG_ASSERT(false);
+ return true;
+ }
+ return true;
+}
+#endif
+
/*
Supporting START TRANSACTION WITH CONSISTENT [ROCKSDB] SNAPSHOT
@@ -4165,10 +4437,15 @@ static const char *ha_rocksdb_exts[] = {NullS};
InnoDB and RocksDB transactions.
*/
static int rocksdb_start_tx_and_assign_read_view(
- handlerton *const hton, /*!< in: RocksDB handlerton */
- THD* thd) /*!< in: MySQL thread handle of the
- user for whom the transaction should
- be committed */
+ handlerton *const hton, /*!< in: RocksDB handlerton */
+ THD *const thd /*!< in: MySQL thread handle of the
+ user for whom the transaction should
+ be committed */
+)
+#ifdef MARIAROCKS_NOT_YET
+ snapshot_info_st *ss_info) /*!< in/out: Snapshot info like binlog file, pos,
+ gtid executed and snapshot ID */
+#endif
{
ulong const tx_isolation = my_core::thd_tx_isolation(thd);
@@ -4176,14 +4453,25 @@ static int rocksdb_start_tx_and_assign_read_view(
my_error(ER_ISOLATION_LEVEL_WITH_CONSISTENT_SNAPSHOT, MYF(0));
return HA_EXIT_FAILURE;
}
+
+#ifdef MARIADB_NOT_YET
+ if (ss_info) {
+ if (mysql_bin_log_is_open()) {
+ mysql_bin_log_lock_commits(ss_info);
+ } else {
+ return HA_EXIT_FAILURE;
+ }
+#endif
+
/*
MariaDB: there is no need to call mysql_bin_log_lock_commits and then
unlock back.
SQL layer calls start_consistent_snapshot() for all engines, including the
binlog under LOCK_commit_ordered mutex.
+
The mutex prevents binlog commits from happening (right?) while the storage
engine(s) allocate read snapshots. That way, each storage engine is
- synchronized with current binlog position.
+ synchronized with current binlog position.
*/
mysql_mutex_assert_owner(&LOCK_commit_ordered);
@@ -4195,9 +4483,106 @@ static int rocksdb_start_tx_and_assign_read_view(
rocksdb_register_tx(hton, thd, tx);
tx->acquire_snapshot(true);
+#ifdef MARIADB_NOT_YET
+ if (ss_info) {
+ mysql_bin_log_unlock_commits(ss_info);
+ }
+#endif
return HA_EXIT_SUCCESS;
}
+#ifdef MARIADB_NOT_YET
+static int rocksdb_start_tx_with_shared_read_view(
+ handlerton *const hton, /*!< in: RocksDB handlerton */
+ THD *const thd) /*!< in: MySQL thread handle of the
+ user for whom the transaction should
+ be committed */
+#ifdef MARIADB_NOT_YET
+ snapshot_info_st *ss_info) /*!< out: Snapshot info like binlog file, pos,
+ gtid executed and snapshot ID */
+#endif
+{
+ DBUG_ASSERT(thd != nullptr);
+
+ int error = HA_EXIT_SUCCESS;
+
+ ulong const tx_isolation = my_core::thd_tx_isolation(thd);
+ if (tx_isolation != ISO_REPEATABLE_READ) {
+ my_error(ER_ISOLATION_LEVEL_WITH_CONSISTENT_SNAPSHOT, MYF(0));
+ return HA_EXIT_FAILURE;
+ }
+
+ Rdb_transaction *tx = nullptr;
+#ifdef MARIADB_NOT_YET
+ std::shared_ptr<Rdb_explicit_snapshot> explicit_snapshot;
+ const auto op = ss_info->op;
+
+ DBUG_ASSERT(op == snapshot_operation::SNAPSHOT_CREATE ||
+ op == snapshot_operation::SNAPSHOT_ATTACH);
+
+ // case: if binlogs are available get binlog file/pos and gtid info
+ if (op == snapshot_operation::SNAPSHOT_CREATE && mysql_bin_log_is_open()) {
+ mysql_bin_log_lock_commits(ss_info);
+ }
+
+ if (op == snapshot_operation::SNAPSHOT_ATTACH) {
+ explicit_snapshot = Rdb_explicit_snapshot::get(ss_info->snapshot_id);
+ if (!explicit_snapshot) {
+ my_printf_error(ER_UNKNOWN_ERROR, "Snapshot %llu does not exist", MYF(0),
+ ss_info->snapshot_id);
+ error = HA_EXIT_FAILURE;
+ }
+ }
+#endif
+
+ // case: all good till now
+ if (error == HA_EXIT_SUCCESS) {
+ tx = get_or_create_tx(thd);
+ Rdb_perf_context_guard guard(tx, rocksdb_perf_context_level(thd));
+
+#ifdef MARIADB_NOT_YET
+ if (explicit_snapshot) {
+ tx->m_explicit_snapshot = explicit_snapshot;
+ }
+#endif
+
+ DBUG_ASSERT(!tx->has_snapshot());
+ tx->set_tx_read_only(true);
+ rocksdb_register_tx(hton, thd, tx);
+ tx->acquire_snapshot(true);
+
+#ifdef MARIADB_NOT_YET
+ // case: an explicit snapshot was not assigned to this transaction
+ if (!tx->m_explicit_snapshot) {
+ tx->m_explicit_snapshot =
+ Rdb_explicit_snapshot::create(ss_info, rdb, tx->m_read_opts.snapshot);
+ if (!tx->m_explicit_snapshot) {
+ my_printf_error(ER_UNKNOWN_ERROR, "Could not create snapshot", MYF(0));
+ error = HA_EXIT_FAILURE;
+ }
+ }
+#endif
+ }
+
+#ifdef MARIADB_NOT_YET
+ // case: unlock the binlog
+ if (op == snapshot_operation::SNAPSHOT_CREATE && mysql_bin_log_is_open()) {
+ mysql_bin_log_unlock_commits(ss_info);
+ }
+
+ DBUG_ASSERT(error == HA_EXIT_FAILURE || tx->m_explicit_snapshot);
+
+ // copy over the snapshot details to pass to the upper layers
+ if (tx->m_explicit_snapshot) {
+ *ss_info = tx->m_explicit_snapshot->ss_info;
+ ss_info->op = op;
+ }
+#endif
+
+ return error;
+}
+#endif
+
/* Dummy SAVEPOINT support. This is needed for long running transactions
* like mysqldump (https://bugs.mysql.com/bug.php?id=71017).
* Current SAVEPOINT does not correctly handle ROLLBACK and does not return
@@ -4422,9 +4807,11 @@ static int rocksdb_init_func(void *const p) {
rdb_bg_thread.init(rdb_signal_bg_psi_mutex_key, rdb_signal_bg_psi_cond_key);
rdb_drop_idx_thread.init(rdb_signal_drop_idx_psi_mutex_key,
rdb_signal_drop_idx_psi_cond_key);
+ rdb_mc_thread.init(rdb_signal_mc_psi_mutex_key, rdb_signal_mc_psi_cond_key);
#else
rdb_bg_thread.init();
rdb_drop_idx_thread.init();
+ rdb_mc_thread.init();
#endif
mysql_mutex_init(rdb_collation_data_mutex_key, &rdb_collation_data_mutex,
MY_MUTEX_INIT_FAST);
@@ -4445,6 +4832,8 @@ static int rocksdb_init_func(void *const p) {
mysql_mutex_init(rdb_sysvars_psi_mutex_key, &rdb_sysvars_mutex,
MY_MUTEX_INIT_FAST);
+ mysql_mutex_init(rdb_block_cache_resize_mutex_key,
+ &rdb_block_cache_resize_mutex, MY_MUTEX_INIT_FAST);
Rdb_transaction::init_mutex();
rocksdb_hton->state = SHOW_OPTION_YES;
@@ -4465,8 +4854,14 @@ static int rocksdb_init_func(void *const p) {
rocksdb_hton->rollback = rocksdb_rollback;
rocksdb_hton->show_status = rocksdb_show_status;
+#ifdef MARIADB_NOT_YET
+ rocksdb_hton->explicit_snapshot = rocksdb_explicit_snapshot;
+#endif
rocksdb_hton->start_consistent_snapshot =
rocksdb_start_tx_and_assign_read_view;
+#ifdef MARIADB_NOT_YET
+ rocksdb_hton->start_shared_snapshot = rocksdb_start_tx_with_shared_read_view;
+#endif
rocksdb_hton->savepoint_set = rocksdb_savepoint;
rocksdb_hton->savepoint_rollback = rocksdb_rollback_to_savepoint;
rocksdb_hton->savepoint_rollback_can_release_mdl =
@@ -4535,6 +4930,35 @@ static int rocksdb_init_func(void *const p) {
DBUG_RETURN(HA_EXIT_FAILURE);
}
+ // Check whether the filesystem backing rocksdb_datadir allows O_DIRECT
+ if (rocksdb_db_options->use_direct_reads) {
+ rocksdb::EnvOptions soptions;
+ rocksdb::Status check_status;
+ rocksdb::Env *const env = rocksdb_db_options->env;
+
+ std::string fname = format_string("%s/DIRECT_CHECK", rocksdb_datadir);
+ if (env->FileExists(fname).ok()) {
+ std::unique_ptr<rocksdb::SequentialFile> file;
+ soptions.use_direct_reads = true;
+ check_status = env->NewSequentialFile(fname, &file, soptions);
+ } else {
+ std::unique_ptr<rocksdb::WritableFile> file;
+ soptions.use_direct_writes = true;
+ check_status = env->ReopenWritableFile(fname, &file, soptions);
+ if (file != nullptr) {
+ file->Close();
+ }
+ env->DeleteFile(fname);
+ }
+
+ if (!check_status.ok()) {
+ sql_print_error("RocksDB: Unable to use direct io in rocksdb-datadir:"
+ "(%s)", check_status.getState());
+ rdb_open_tables.free_hash();
+ DBUG_RETURN(HA_EXIT_FAILURE);
+ }
+ }
+
if (rocksdb_db_options->allow_mmap_writes &&
rocksdb_db_options->use_direct_io_for_flush_and_compaction) {
// See above comment for allow_mmap_reads. (NO_LINT_DEBUG)
@@ -4687,8 +5111,10 @@ static int rocksdb_init_func(void *const p) {
cf_options_map->get_defaults());
rocksdb::TransactionDBOptions tx_db_options;
- tx_db_options.transaction_lock_timeout = 2; // 2 seconds
+ tx_db_options.transaction_lock_timeout = 2000; // 2 seconds
tx_db_options.custom_mutex_factory = std::make_shared<Rdb_mutex_factory>();
+ tx_db_options.write_policy =
+ static_cast<rocksdb::TxnDBWritePolicy>(rocksdb_write_policy);
status =
check_rocksdb_options_compatibility(rocksdb_datadir, main_opts, cf_descr);
@@ -4710,7 +5136,7 @@ static int rocksdb_init_func(void *const p) {
}
cf_manager.init(std::move(cf_options_map), &cf_handles);
- if (dict_manager.init(rdb->GetBaseDB(), &cf_manager)) {
+ if (dict_manager.init(rdb, &cf_manager)) {
// NO_LINT_DEBUG
sql_print_error("RocksDB: Failed to initialize data dictionary.");
DBUG_RETURN(HA_EXIT_FAILURE);
@@ -4771,6 +5197,21 @@ static int rocksdb_init_func(void *const p) {
DBUG_RETURN(HA_EXIT_FAILURE);
}
+ err = rdb_mc_thread.create_thread(MANUAL_COMPACTION_THREAD_NAME
+#ifdef HAVE_PSI_INTERFACE
+ ,
+ rdb_mc_psi_thread_key
+#endif
+ );
+ if (err != 0) {
+ // NO_LINT_DEBUG
+ sql_print_error(
+ "RocksDB: Couldn't start the manual compaction thread: (errno=%d)",
+ err);
+ rdb_open_tables.free_hash();
+ DBUG_RETURN(HA_EXIT_FAILURE);
+ }
+
rdb_set_collation_exception_list(rocksdb_strict_collation_exceptions);
if (rocksdb_pause_background_work) {
@@ -4877,6 +5318,16 @@ static int rocksdb_done_func(void *const p) {
sql_print_error("RocksDB: Couldn't stop the index thread: (errno=%d)", err);
}
+ // signal the manual compaction thread to stop
+ rdb_mc_thread.signal(true);
+ // Wait for the manual compaction thread to finish.
+ err = rdb_mc_thread.join();
+ if (err != 0) {
+ // NO_LINT_DEBUG
+ sql_print_error(
+ "RocksDB: Couldn't stop the manual compaction thread: (errno=%d)", err);
+ }
+
if (rdb_open_tables.m_hash.size()) {
// Looks like we are getting unloaded and yet we have some open tables
// left behind.
@@ -4933,6 +5384,7 @@ static int rocksdb_done_func(void *const p) {
rdb_open_tables.m_hash.~Rdb_table_set();
mysql_mutex_destroy(&rdb_open_tables.m_mutex);
mysql_mutex_destroy(&rdb_sysvars_mutex);
+ mysql_mutex_destroy(&rdb_block_cache_resize_mutex);
delete rdb_collation_exceptions;
@@ -5348,7 +5800,6 @@ longlong ha_rocksdb::update_hidden_pk_val() {
/* Get the id of the hidden pk id from m_last_rowkey */
int ha_rocksdb::read_hidden_pk_id_from_rowkey(longlong *const hidden_pk_id) {
- DBUG_ASSERT(hidden_pk_id != nullptr);
DBUG_ASSERT(table != nullptr);
DBUG_ASSERT(has_hidden_pk(table));
@@ -5404,14 +5855,14 @@ ha_rocksdb::ha_rocksdb(my_core::handlerton *const hton,
my_core::TABLE_SHARE *const table_arg)
: handler(hton, table_arg), m_table_handler(nullptr), m_scan_it(nullptr),
m_scan_it_skips_bloom(false), m_scan_it_snapshot(nullptr),
+ m_scan_it_lower_bound(nullptr), m_scan_it_upper_bound(nullptr),
m_tbl_def(nullptr), m_pk_descr(nullptr), m_key_descr_arr(nullptr),
m_pk_can_be_decoded(false), m_maybe_unpack_info(false),
m_pk_tuple(nullptr), m_pk_packed_tuple(nullptr),
m_sk_packed_tuple(nullptr), m_end_key_packed_tuple(nullptr),
m_sk_match_prefix(nullptr), m_sk_match_prefix_buf(nullptr),
m_sk_packed_tuple_old(nullptr), m_dup_sk_packed_tuple(nullptr),
- m_dup_sk_packed_tuple_old(nullptr), m_eq_cond_lower_bound(nullptr),
- m_eq_cond_upper_bound(nullptr), m_pack_buffer(nullptr),
+ m_dup_sk_packed_tuple_old(nullptr), m_pack_buffer(nullptr),
m_lock_rows(RDB_LOCK_NONE), m_keyread_only(FALSE), m_encoder_arr(nullptr),
m_row_checksums_checked(0), m_in_rpl_delete_rows(false),
m_in_rpl_update_rows(false), m_force_skip_unique_check(false) {}
@@ -5950,9 +6401,6 @@ int ha_rocksdb::convert_field_from_storage_format(
int ha_rocksdb::convert_record_from_storage_format(
const rocksdb::Slice *const key, const rocksdb::Slice *const value,
uchar *const buf) {
- DBUG_ASSERT(key != nullptr);
- DBUG_ASSERT(buf != nullptr);
-
Rdb_string_reader reader(value);
/*
@@ -6196,7 +6644,6 @@ int ha_rocksdb::alloc_key_buffers(const TABLE *const table_arg,
DBUG_ENTER_FUNC();
DBUG_ASSERT(m_pk_tuple == nullptr);
- DBUG_ASSERT(tbl_def_arg != nullptr);
std::shared_ptr<Rdb_key_def> *const kd_arr = tbl_def_arg->m_key_descr_arr;
@@ -6248,9 +6695,9 @@ int ha_rocksdb::alloc_key_buffers(const TABLE *const table_arg,
m_pack_buffer =
reinterpret_cast<uchar *>(my_malloc(max_packed_sk_len, MYF(0)));
- m_eq_cond_upper_bound =
+ m_scan_it_lower_bound =
reinterpret_cast<uchar *>(my_malloc(max_packed_sk_len, MYF(0)));
- m_eq_cond_lower_bound =
+ m_scan_it_upper_bound =
reinterpret_cast<uchar *>(my_malloc(max_packed_sk_len, MYF(0)));
/*
@@ -6267,7 +6714,7 @@ int ha_rocksdb::alloc_key_buffers(const TABLE *const table_arg,
if (m_pk_tuple == nullptr || m_pk_packed_tuple == nullptr ||
m_sk_packed_tuple == nullptr || m_sk_packed_tuple_old == nullptr ||
m_end_key_packed_tuple == nullptr || m_pack_buffer == nullptr ||
- m_eq_cond_upper_bound == nullptr || m_eq_cond_lower_bound == nullptr ||
+ m_scan_it_upper_bound == nullptr || m_scan_it_lower_bound == nullptr ||
(alloc_alter_buffers && (m_dup_sk_packed_tuple == nullptr ||
m_dup_sk_packed_tuple_old == nullptr))) {
// One or more of the above allocations failed. Clean up and exit
@@ -6307,11 +6754,11 @@ void ha_rocksdb::free_key_buffers() {
my_free(m_dup_sk_packed_tuple_old);
m_dup_sk_packed_tuple_old = nullptr;
- my_free(m_eq_cond_upper_bound);
- m_eq_cond_upper_bound = nullptr;
+ my_free(m_scan_it_lower_bound);
+ m_scan_it_lower_bound = nullptr;
- my_free(m_eq_cond_lower_bound);
- m_eq_cond_lower_bound = nullptr;
+ my_free(m_scan_it_upper_bound);
+ m_scan_it_upper_bound = nullptr;
}
#ifdef MARIAROCKS_NOT_YET
@@ -6569,9 +7016,8 @@ bool ha_rocksdb::get_error_message(const int error, String *const buf) {
static_assert(HA_ERR_ROCKSDB_LAST > HA_ERR_LAST,
"HA_ERR_ROCKSDB_LAST > HA_ERR_LAST");
- DBUG_ASSERT(buf != nullptr);
-
- if (error == HA_ERR_LOCK_WAIT_TIMEOUT || error == HA_ERR_LOCK_DEADLOCK) {
+ if (error == HA_ERR_LOCK_WAIT_TIMEOUT || error == HA_ERR_LOCK_DEADLOCK ||
+ error == HA_ERR_ROCKSDB_STATUS_BUSY) {
Rdb_transaction *const tx = get_tx_from_thd(ha_thd());
DBUG_ASSERT(tx != nullptr);
buf->append(tx->m_detailed_error);
@@ -6653,10 +7099,10 @@ int ha_rocksdb::rdb_error_to_mysql(const rocksdb::Status &s,
}
if (opt_msg) {
- my_error(ER_RDB_STATUS_MSG, MYF(0), opt_msg, s.code(),
- s.ToString().c_str());
+ std::string concatenated_error = s.ToString() + " (" + std::string(opt_msg) + ")";
+ my_error(ER_GET_ERRMSG, MYF(0), s.code(), concatenated_error.c_str(), rocksdb_hton_name);
} else {
- my_error(ER_RDB_STATUS_GENERAL, MYF(0), s.code(), s.ToString().c_str());
+ my_error(ER_GET_ERRMSG, MYF(0), s.code(), s.ToString().c_str(), rocksdb_hton_name);
}
return err;
@@ -6725,7 +7171,6 @@ int ha_rocksdb::create_key_defs(
/* = nullptr */) const {
DBUG_ENTER_FUNC();
- DBUG_ASSERT(table_arg != nullptr);
DBUG_ASSERT(table_arg->s != nullptr);
uint i;
@@ -6796,9 +7241,7 @@ int ha_rocksdb::create_cfs(
std::array<struct key_def_cf_info, MAX_INDEXES + 1> *const cfs) const {
DBUG_ENTER_FUNC();
- DBUG_ASSERT(table_arg != nullptr);
DBUG_ASSERT(table_arg->s != nullptr);
- DBUG_ASSERT(tbl_def_arg != nullptr);
char tablename_sys[NAME_LEN + 1];
bool tsys_set= false;
@@ -6904,10 +7347,6 @@ int ha_rocksdb::create_inplace_key_defs(
const std::array<key_def_cf_info, MAX_INDEXES + 1> &cfs) const {
DBUG_ENTER_FUNC();
- DBUG_ASSERT(table_arg != nullptr);
- DBUG_ASSERT(tbl_def_arg != nullptr);
- DBUG_ASSERT(old_tbl_def_arg != nullptr);
-
std::shared_ptr<Rdb_key_def> *const old_key_descr =
old_tbl_def_arg->m_key_descr_arr;
std::shared_ptr<Rdb_key_def> *const new_key_descr =
@@ -6975,11 +7414,6 @@ std::unordered_map<std::string, uint> ha_rocksdb::get_old_key_positions(
const Rdb_tbl_def *const old_tbl_def_arg) const {
DBUG_ENTER_FUNC();
- DBUG_ASSERT(table_arg != nullptr);
- DBUG_ASSERT(old_table_arg != nullptr);
- DBUG_ASSERT(tbl_def_arg != nullptr);
- DBUG_ASSERT(old_tbl_def_arg != nullptr);
-
std::shared_ptr<Rdb_key_def> *const old_key_descr =
old_tbl_def_arg->m_key_descr_arr;
std::unordered_map<std::string, uint> old_key_pos;
@@ -7045,9 +7479,6 @@ int ha_rocksdb::compare_keys(const KEY *const old_key,
const KEY *const new_key) const {
DBUG_ENTER_FUNC();
- DBUG_ASSERT(old_key != nullptr);
- DBUG_ASSERT(new_key != nullptr);
-
/* Check index name. */
if (strcmp(old_key->name, new_key->name) != 0) {
DBUG_RETURN(HA_EXIT_FAILURE);
@@ -7078,9 +7509,6 @@ int ha_rocksdb::compare_key_parts(const KEY *const old_key,
const KEY *const new_key) const {
DBUG_ENTER_FUNC();
- DBUG_ASSERT(old_key != nullptr);
- DBUG_ASSERT(new_key != nullptr);
-
/* Skip if key parts do not match, as it is a different key */
if (new_key->user_defined_key_parts != old_key->user_defined_key_parts) {
DBUG_RETURN(HA_EXIT_FAILURE);
@@ -7125,7 +7553,6 @@ int ha_rocksdb::create_key_def(const TABLE *const table_arg, const uint &i,
const struct key_def_cf_info &cf_info) const {
DBUG_ENTER_FUNC();
- DBUG_ASSERT(new_key_def != nullptr);
DBUG_ASSERT(*new_key_def == nullptr);
uint64 ttl_duration = 0;
@@ -7212,8 +7639,6 @@ int ha_rocksdb::create_key_def(const TABLE *const table_arg, const uint &i,
int rdb_normalize_tablename(const std::string &tablename,
std::string *const strbuf) {
- DBUG_ASSERT(strbuf != nullptr);
-
if (tablename.size() < 2 || tablename[0] != '.' ||
(tablename[1] != FN_LIBCHAR && tablename[1] != FN_LIBCHAR2)) {
DBUG_ASSERT(0); // We were not passed table name?
@@ -7537,8 +7962,6 @@ int ha_rocksdb::read_key_exact(const Rdb_key_def &kd,
const bool &full_key_match,
const rocksdb::Slice &key_slice,
const int64_t ttl_filter_ts) {
- DBUG_ASSERT(iter != nullptr);
-
/*
We are looking for the first record such that
index_tuple= lookup_tuple.
@@ -7746,8 +8169,6 @@ int ha_rocksdb::calc_eq_cond_len(const Rdb_key_def &kd,
}
int ha_rocksdb::read_row_from_primary_key(uchar *const buf) {
- DBUG_ASSERT(buf != nullptr);
-
int rc;
const rocksdb::Slice &rkey = m_scan_it->key();
const uint pk_size = rkey.size();
@@ -7771,8 +8192,6 @@ int ha_rocksdb::read_row_from_primary_key(uchar *const buf) {
int ha_rocksdb::read_row_from_secondary_key(uchar *const buf,
const Rdb_key_def &kd,
bool move_forward) {
- DBUG_ASSERT(buf != nullptr);
-
int rc = 0;
uint pk_size;
@@ -7875,7 +8294,6 @@ ulong ha_rocksdb::index_flags(uint inx, uint part, bool all_parts) const {
pair for.
*/
int ha_rocksdb::secondary_index_read(const int keyno, uchar *const buf) {
- DBUG_ASSERT(buf != nullptr);
DBUG_ASSERT(table != nullptr);
#ifdef MARIAROCKS_NOT_YET
stats.rows_requested++;
@@ -8192,7 +8610,7 @@ int ha_rocksdb::index_read_map_impl(uchar *const buf, const uchar *const key,
else
rc = read_row_from_secondary_key(buf, kd, move_forward);
- if (rc != HA_ERR_LOCK_DEADLOCK || !is_new_snapshot)
+ if (rc != HA_ERR_ROCKSDB_STATUS_BUSY || !is_new_snapshot)
break; /* Exit the loop */
// release the snapshot and iterator so they will be regenerated
@@ -8237,8 +8655,6 @@ int ha_rocksdb::index_read_map_impl(uchar *const buf, const uchar *const key,
int ha_rocksdb::find_icp_matching_index_rec(const bool &move_forward,
uchar *const buf) {
- DBUG_ASSERT(buf != nullptr);
-
if (pushed_idx_cond && pushed_idx_cond_keyno == active_index) {
const Rdb_key_def &kd = *m_key_descr_arr[active_index];
@@ -8552,8 +8968,6 @@ int ha_rocksdb::get_row_by_rowid(uchar *const buf, const char *const rowid,
const bool skip_ttl_check) {
DBUG_ENTER_FUNC();
- DBUG_ASSERT(buf != nullptr);
- DBUG_ASSERT(rowid != nullptr);
DBUG_ASSERT(table != nullptr);
int rc;
@@ -8766,8 +9180,6 @@ int ha_rocksdb::index_last(uchar *const buf) {
int ha_rocksdb::index_first_intern(uchar *const buf) {
DBUG_ENTER_FUNC();
- DBUG_ASSERT(buf != nullptr);
-
uchar *key;
uint key_size;
int rc;
@@ -8797,7 +9209,7 @@ int ha_rocksdb::index_first_intern(uchar *const buf) {
m_skip_scan_it_next_call = true;
rc = index_next_with_direction(buf, true);
- if (rc != HA_ERR_LOCK_DEADLOCK || !is_new_snapshot)
+ if (rc != HA_ERR_ROCKSDB_STATUS_BUSY || !is_new_snapshot)
break; // exit the loop
// release the snapshot and iterator so they will be regenerated
@@ -8859,8 +9271,6 @@ int ha_rocksdb::index_first_intern(uchar *const buf) {
int ha_rocksdb::index_last_intern(uchar *const buf) {
DBUG_ENTER_FUNC();
- DBUG_ASSERT(buf != nullptr);
-
uchar *key;
uint key_size;
int rc;
@@ -8902,7 +9312,7 @@ int ha_rocksdb::index_last_intern(uchar *const buf) {
rc = secondary_index_read(active_index, buf);
}
- if (rc != HA_ERR_LOCK_DEADLOCK || !is_new_snapshot)
+ if (rc != HA_ERR_ROCKSDB_STATUS_BUSY || !is_new_snapshot)
break; /* exit the loop */
// release the snapshot and iterator so they will be regenerated
@@ -8987,7 +9397,6 @@ bool ha_rocksdb::commit_in_the_middle() {
@retval false if bulk commit was skipped or succeeded
*/
bool ha_rocksdb::do_bulk_commit(Rdb_transaction *const tx) {
- DBUG_ASSERT(tx != nullptr);
return commit_in_the_middle() &&
tx->get_write_count() >= THDVAR(table->in_use, bulk_load_size) &&
tx->flush_batch();
@@ -9000,7 +9409,6 @@ bool ha_rocksdb::do_bulk_commit(Rdb_transaction *const tx) {
'auto-incremented' pk.)
*/
bool ha_rocksdb::has_hidden_pk(const TABLE *const table) const {
- DBUG_ASSERT(table != nullptr);
return Rdb_key_def::table_has_hidden_pk(table);
}
@@ -9010,9 +9418,7 @@ bool ha_rocksdb::has_hidden_pk(const TABLE *const table) const {
*/
bool ha_rocksdb::is_hidden_pk(const uint index, const TABLE *const table_arg,
const Rdb_tbl_def *const tbl_def_arg) {
- DBUG_ASSERT(table_arg != nullptr);
DBUG_ASSERT(table_arg->s != nullptr);
- DBUG_ASSERT(tbl_def_arg != nullptr);
return (table_arg->s->primary_key == MAX_INDEXES &&
index == tbl_def_arg->m_key_count - 1);
@@ -9021,9 +9427,7 @@ bool ha_rocksdb::is_hidden_pk(const uint index, const TABLE *const table_arg,
/* Returns index of primary key */
uint ha_rocksdb::pk_index(const TABLE *const table_arg,
const Rdb_tbl_def *const tbl_def_arg) {
- DBUG_ASSERT(table_arg != nullptr);
DBUG_ASSERT(table_arg->s != nullptr);
- DBUG_ASSERT(tbl_def_arg != nullptr);
return table_arg->s->primary_key == MAX_INDEXES ? tbl_def_arg->m_key_count - 1
: table_arg->s->primary_key;
@@ -9032,9 +9436,7 @@ uint ha_rocksdb::pk_index(const TABLE *const table_arg,
/* Returns true if given index number is a primary key */
bool ha_rocksdb::is_pk(const uint index, const TABLE *const table_arg,
const Rdb_tbl_def *const tbl_def_arg) {
- DBUG_ASSERT(table_arg != nullptr);
DBUG_ASSERT(table_arg->s != nullptr);
- DBUG_ASSERT(tbl_def_arg != nullptr);
return index == table_arg->s->primary_key ||
is_hidden_pk(index, table_arg, tbl_def_arg);
@@ -9049,9 +9451,6 @@ uint ha_rocksdb::max_supported_key_part_length() const {
const char *ha_rocksdb::get_key_name(const uint index,
const TABLE *const table_arg,
const Rdb_tbl_def *const tbl_def_arg) {
- DBUG_ASSERT(table_arg != nullptr);
- DBUG_ASSERT(tbl_def_arg != nullptr);
-
if (is_hidden_pk(index, table_arg, tbl_def_arg)) {
return HIDDEN_PK_NAME;
}
@@ -9065,9 +9464,6 @@ const char *ha_rocksdb::get_key_name(const uint index,
const char *ha_rocksdb::get_key_comment(const uint index,
const TABLE *const table_arg,
const Rdb_tbl_def *const tbl_def_arg) {
- DBUG_ASSERT(table_arg != nullptr);
- DBUG_ASSERT(tbl_def_arg != nullptr);
-
if (is_hidden_pk(index, table_arg, tbl_def_arg)) {
return nullptr;
}
@@ -9119,7 +9515,6 @@ const std::string ha_rocksdb::generate_cf_name(const uint index,
}
const std::string ha_rocksdb::get_table_comment(const TABLE *const table_arg) {
- DBUG_ASSERT(table_arg != nullptr);
DBUG_ASSERT(table_arg->s != nullptr);
return table_arg->s->comment.str;
@@ -9236,8 +9631,7 @@ int ha_rocksdb::check_and_lock_unique_pk(const uint &key_id,
/*
If the keys are the same, then no lock is needed
*/
- if (!Rdb_pk_comparator::bytewise_compare(row_info.new_pk_slice,
- row_info.old_pk_slice)) {
+ if (!row_info.new_pk_slice.compare(row_info.old_pk_slice)) {
*found = false;
return HA_EXIT_SUCCESS;
}
@@ -9326,8 +9720,7 @@ int ha_rocksdb::check_and_lock_sk(const uint &key_id,
rocksdb::Slice((const char *)m_sk_packed_tuple, size);
/*
- For UPDATEs, if the key has changed, we need to obtain a lock. INSERTs
- always require locking.
+ Acquire lock on the old key in case of UPDATE
*/
if (row_info.old_data != nullptr) {
size = kd.pack_record(table, m_pack_buffer, row_info.old_data,
@@ -9336,14 +9729,18 @@ int ha_rocksdb::check_and_lock_sk(const uint &key_id,
const rocksdb::Slice old_slice =
rocksdb::Slice((const char *)m_sk_packed_tuple_old, size);
- /*
- For updates, if the keys are the same, then no lock is needed
+ const rocksdb::Status s =
+ get_for_update(row_info.tx, kd.get_cf(), old_slice, nullptr);
+ if (!s.ok()) {
+ return row_info.tx->set_status_error(table->in_use, s, kd, m_tbl_def,
+ m_table_handler);
+ }
- Also check to see if the key has any fields set to NULL. If it does, then
- this key is unique since NULL is not equal to each other, so no lock is
- needed.
+ /*
+ If the old and new keys are the same we're done since we've already taken
+ the lock on the old key
*/
- if (!Rdb_pk_comparator::bytewise_compare(new_slice, old_slice)) {
+ if (!new_slice.compare(old_slice)) {
return HA_EXIT_SUCCESS;
}
}
@@ -9369,16 +9766,14 @@ int ha_rocksdb::check_and_lock_sk(const uint &key_id,
The bloom filter may need to be disabled for this lookup.
*/
- uchar min_bound_buf[MAX_KEY_LENGTH];
- uchar max_bound_buf[MAX_KEY_LENGTH];
- rocksdb::Slice min_bound_slice;
- rocksdb::Slice max_bound_slice;
+ uchar lower_bound_buf[Rdb_key_def::INDEX_NUMBER_SIZE];
+ uchar upper_bound_buf[Rdb_key_def::INDEX_NUMBER_SIZE];
+ rocksdb::Slice lower_bound_slice;
+ rocksdb::Slice upper_bound_slice;
+
const bool total_order_seek = !check_bloom_and_set_bounds(
- ha_thd(), kd, new_slice, all_parts_used,
- min_bound_buf,
- max_bound_buf,
- &min_bound_slice,
- &max_bound_slice);
+ ha_thd(), kd, new_slice, all_parts_used, Rdb_key_def::INDEX_NUMBER_SIZE,
+ lower_bound_buf, upper_bound_buf, &lower_bound_slice, &upper_bound_slice);
const bool fill_cache = !THDVAR(ha_thd(), skip_fill_cache);
const rocksdb::Status s =
@@ -9389,9 +9784,8 @@ int ha_rocksdb::check_and_lock_sk(const uint &key_id,
}
rocksdb::Iterator *const iter = row_info.tx->get_iterator(
- kd.get_cf(), total_order_seek, fill_cache,
- min_bound_slice, max_bound_slice,
- true /* read current data */,
+ kd.get_cf(), total_order_seek, fill_cache, lower_bound_slice,
+ upper_bound_slice, true /* read current data */,
false /* acquire snapshot */);
/*
Need to scan the transaction to see if there is a duplicate key.
@@ -9601,9 +9995,11 @@ int ha_rocksdb::update_pk(const Rdb_key_def &kd,
}
int ha_rocksdb::update_sk(const TABLE *const table_arg, const Rdb_key_def &kd,
- const struct update_row_info &row_info) {
+ const struct update_row_info &row_info,
+ const bool bulk_load_sk) {
int new_packed_size;
int old_packed_size;
+ int rc = HA_EXIT_SUCCESS;
rocksdb::Slice new_key_slice;
rocksdb::Slice new_value_slice;
@@ -9681,18 +10077,23 @@ int ha_rocksdb::update_sk(const TABLE *const table_arg, const Rdb_key_def &kd,
rocksdb::Slice(reinterpret_cast<const char *>(m_sk_tails.ptr()),
m_sk_tails.get_current_pos());
- row_info.tx->get_indexed_write_batch()->Put(kd.get_cf(), new_key_slice,
- new_value_slice);
+ if (bulk_load_sk && row_info.old_data == nullptr) {
+ rc = bulk_load_key(row_info.tx, kd, new_key_slice, new_value_slice, true);
+ } else {
+ row_info.tx->get_indexed_write_batch()->Put(kd.get_cf(), new_key_slice,
+ new_value_slice);
+ }
row_info.tx->update_bytes_written(bytes_written + new_key_slice.size() +
new_value_slice.size());
- return HA_EXIT_SUCCESS;
+ return rc;
}
int ha_rocksdb::update_indexes(const struct update_row_info &row_info,
const bool &pk_changed) {
int rc;
+ bool bulk_load_sk;
// The PK must be updated first to pull out the TTL value.
rc = update_pk(*m_pk_descr, row_info, pk_changed);
@@ -9700,13 +10101,17 @@ int ha_rocksdb::update_indexes(const struct update_row_info &row_info,
return rc;
}
- // Update the remaining indexes.
+ // Update the remaining indexes. Allow bulk loading only if
+ // allow_sk is enabled
+ bulk_load_sk = rocksdb_enable_bulk_load_api &&
+ THDVAR(table->in_use, bulk_load) &&
+ THDVAR(table->in_use, bulk_load_allow_sk);
for (uint key_id = 0; key_id < m_tbl_def->m_key_count; key_id++) {
if (is_pk(key_id, table, m_tbl_def)) {
continue;
}
- rc = update_sk(table, *m_key_descr_arr[key_id], row_info);
+ rc = update_sk(table, *m_key_descr_arr[key_id], row_info, bulk_load_sk);
if (rc != HA_EXIT_SUCCESS) {
return rc;
}
@@ -9804,28 +10209,22 @@ int ha_rocksdb::update_write_row(const uchar *const old_data,
@param outer_u
*/
-void ha_rocksdb::setup_iterator_bounds(const Rdb_key_def &kd,
- const rocksdb::Slice &eq_cond,
- uchar *lower_bound_buf,
- uchar *upper_bound_buf,
- rocksdb::Slice *out_lower_bound,
- rocksdb::Slice *out_upper_bound) {
- uint eq_cond_len = eq_cond.size();
- memcpy(upper_bound_buf, eq_cond.data(), eq_cond_len);
- kd.successor(upper_bound_buf, eq_cond_len);
- memcpy(lower_bound_buf, eq_cond.data(), eq_cond_len);
- kd.predecessor(lower_bound_buf, eq_cond_len);
+void ha_rocksdb::setup_iterator_bounds(
+ const Rdb_key_def &kd, const rocksdb::Slice &eq_cond, size_t bound_len,
+ uchar *const lower_bound, uchar *const upper_bound,
+ rocksdb::Slice *lower_bound_slice, rocksdb::Slice *upper_bound_slice) {
+ uint min_len = std::min(eq_cond.size(), bound_len);
+ memcpy(upper_bound, eq_cond.data(), min_len);
+ kd.successor(upper_bound, min_len);
+ memcpy(lower_bound, eq_cond.data(), min_len);
+ kd.predecessor(lower_bound, min_len);
if (kd.m_is_reverse_cf) {
- *out_upper_bound =
- rocksdb::Slice((const char *)lower_bound_buf, eq_cond_len);
- *out_lower_bound =
- rocksdb::Slice((const char *)upper_bound_buf, eq_cond_len);
+ *upper_bound_slice = rocksdb::Slice((const char *)lower_bound, min_len);
+ *lower_bound_slice = rocksdb::Slice((const char *)upper_bound, min_len);
} else {
- *out_upper_bound =
- rocksdb::Slice((const char *)upper_bound_buf, eq_cond_len);
- *out_lower_bound =
- rocksdb::Slice((const char *)lower_bound_buf, eq_cond_len);
+ *upper_bound_slice = rocksdb::Slice((const char *)upper_bound, min_len);
+ *lower_bound_slice = rocksdb::Slice((const char *)lower_bound, min_len);
}
}
@@ -9837,7 +10236,6 @@ void ha_rocksdb::setup_scan_iterator(const Rdb_key_def &kd,
rocksdb::Slice *const slice,
const bool use_all_keys,
const uint eq_cond_len) {
- DBUG_ASSERT(slice != nullptr);
DBUG_ASSERT(slice->size() >= eq_cond_len);
Rdb_transaction *const tx = get_or_create_tx(table->in_use);
@@ -9845,11 +10243,10 @@ void ha_rocksdb::setup_scan_iterator(const Rdb_key_def &kd,
bool skip_bloom = true;
const rocksdb::Slice eq_cond(slice->data(), eq_cond_len);
- if (check_bloom_and_set_bounds(ha_thd(), kd, eq_cond, use_all_keys,
- m_eq_cond_lower_bound,
- m_eq_cond_upper_bound,
- &m_eq_cond_lower_bound_slice,
- &m_eq_cond_upper_bound_slice)) {
+ if (check_bloom_and_set_bounds(
+ ha_thd(), kd, eq_cond, use_all_keys, eq_cond_len,
+ m_scan_it_lower_bound, m_scan_it_upper_bound,
+ &m_scan_it_lower_bound_slice, &m_scan_it_upper_bound_slice)) {
skip_bloom = false;
}
@@ -9890,8 +10287,8 @@ void ha_rocksdb::setup_scan_iterator(const Rdb_key_def &kd,
m_scan_it = rdb->NewIterator(read_opts, kd.get_cf());
} else {
m_scan_it = tx->get_iterator(kd.get_cf(), skip_bloom, fill_cache,
- m_eq_cond_lower_bound_slice,
- m_eq_cond_upper_bound_slice);
+ m_scan_it_lower_bound_slice,
+ m_scan_it_upper_bound_slice);
}
m_scan_it_skips_bloom = skip_bloom;
}
@@ -9957,7 +10354,7 @@ int ha_rocksdb::rnd_next(uchar *const buf) {
int rc;
for (;;) {
rc = rnd_next_with_direction(buf, true);
- if (rc != HA_ERR_LOCK_DEADLOCK || !m_rnd_scan_is_new_snapshot)
+ if (rc != HA_ERR_ROCKSDB_STATUS_BUSY || !m_rnd_scan_is_new_snapshot)
break; /* exit the loop */
// release the snapshot and iterator and then regenerate them
@@ -10286,7 +10683,7 @@ int ha_rocksdb::info(uint flag) {
if (static_cast<longlong>(stats.data_file_length) < 0 ||
static_cast<longlong>(stats.index_file_length) < 0 ||
static_cast<longlong>(stats.records) < 0) {
- if (analyze(nullptr, nullptr)) {
+ if (calculate_stats_for_table()) {
DBUG_RETURN(HA_EXIT_FAILURE);
}
@@ -10364,10 +10761,21 @@ int ha_rocksdb::info(uint flag) {
KEY *const k = &table->key_info[i];
for (uint j = 0; j < k->ext_key_parts; j++) {
const Rdb_index_stats &k_stats = m_key_descr_arr[i]->m_stats;
- uint x = k_stats.m_distinct_keys_per_prefix.size() > j &&
- k_stats.m_distinct_keys_per_prefix[j] > 0
- ? k_stats.m_rows / k_stats.m_distinct_keys_per_prefix[j]
- : 0;
+ uint x;
+
+ if (k_stats.m_distinct_keys_per_prefix.size() > j &&
+ k_stats.m_distinct_keys_per_prefix[j] > 0) {
+ x = k_stats.m_rows / k_stats.m_distinct_keys_per_prefix[j];
+ /*
+ If the number of rows is less than the number of prefixes (due to
+ sampling), the average number of rows with the same prefix is 1.
+ */
+ if (x == 0) {
+ x = 1;
+ }
+ } else {
+ x = 0;
+ }
if (x > stats.records)
x = stats.records;
if ((x == 0 && rocksdb_debug_optimizer_no_zero_cardinality) ||
@@ -10571,7 +10979,7 @@ THR_LOCK_DATA **ha_rocksdb::store_lock(THD *const thd, THR_LOCK_DATA **to,
m_lock_rows = RDB_LOCK_WRITE;
} else if (lock_type == TL_READ_WITH_SHARED_LOCKS) {
m_lock_rows = RDB_LOCK_READ;
- } else {
+ } else if (lock_type != TL_IGNORE) {
m_lock_rows = RDB_LOCK_NONE;
if (THDVAR(thd, lock_scanned_rows)) {
/*
@@ -10736,6 +11144,13 @@ int ha_rocksdb::external_lock(THD *const thd, int lock_type) {
DBUG_RETURN(HA_ERR_UNSUPPORTED);
}
+#ifdef MARIADB_NOT_YET
+ if (thd->get_explicit_snapshot()) {
+ my_error(ER_UPDATES_WITH_EXPLICIT_SNAPSHOT, MYF(0));
+ DBUG_RETURN(HA_ERR_UNSUPPORTED);
+ }
+#endif
+
/*
SQL layer signals us to take a write lock. It does so when starting DML
statement. We should put locks on the rows we're reading.
@@ -10957,8 +11372,6 @@ void Rdb_drop_index_thread::run() {
}
Rdb_tbl_def *ha_rocksdb::get_table_if_exists(const char *const tablename) {
- DBUG_ASSERT(tablename != nullptr);
-
std::string str;
if (rdb_normalize_tablename(tablename, &str) != HA_EXIT_SUCCESS) {
// We were not passed table name?
@@ -11021,6 +11434,12 @@ int ha_rocksdb::remove_rows(Rdb_tbl_def *const tbl) {
char key_buf[MAX_KEY_LENGTH];
uint key_len;
ulonglong bytes_written = 0;
+
+ uchar lower_bound_buf[Rdb_key_def::INDEX_NUMBER_SIZE];
+ uchar upper_bound_buf[Rdb_key_def::INDEX_NUMBER_SIZE];
+ rocksdb::Slice lower_bound_slice;
+ rocksdb::Slice upper_bound_slice;
+
/*
Remove all records in each index.
(This is is not crash-safe, but it doesn't matter, because bulk row
@@ -11031,13 +11450,12 @@ int ha_rocksdb::remove_rows(Rdb_tbl_def *const tbl) {
kd.get_infimum_key(reinterpret_cast<uchar *>(key_buf), &key_len);
rocksdb::ColumnFamilyHandle *cf = kd.get_cf();
const rocksdb::Slice table_key(key_buf, key_len);
- setup_iterator_bounds(kd, table_key,
- m_eq_cond_lower_bound,
- m_eq_cond_upper_bound,
- &m_eq_cond_lower_bound_slice,
- &m_eq_cond_upper_bound_slice);
- opts.iterate_lower_bound = &m_eq_cond_lower_bound_slice;
- opts.iterate_upper_bound = &m_eq_cond_upper_bound_slice;
+ setup_iterator_bounds(kd, table_key, Rdb_key_def::INDEX_NUMBER_SIZE,
+ lower_bound_buf, upper_bound_buf, &lower_bound_slice,
+ &upper_bound_slice);
+ DBUG_ASSERT(key_len == Rdb_key_def::INDEX_NUMBER_SIZE);
+ opts.iterate_lower_bound = &lower_bound_slice;
+ opts.iterate_upper_bound = &upper_bound_slice;
std::unique_ptr<rocksdb::Iterator> it(rdb->NewIterator(opts, cf));
it->Seek(table_key);
@@ -11076,9 +11494,6 @@ int ha_rocksdb::remove_rows(Rdb_tbl_def *const tbl) {
int ha_rocksdb::rename_table(const char *const from, const char *const to) {
DBUG_ENTER_FUNC();
- DBUG_ASSERT(from != nullptr);
- DBUG_ASSERT(to != nullptr);
-
std::string from_str;
std::string to_str;
std::string from_db;
@@ -11329,29 +11744,28 @@ int ha_rocksdb::optimize(THD *const thd, HA_CHECK_OPT *const check_opt) {
DBUG_RETURN(HA_EXIT_SUCCESS);
}
-int ha_rocksdb::calculate_stats(const TABLE *const table_arg, THD *const thd,
- HA_CHECK_OPT *const check_opt) {
+static int calculate_stats(
+ const std::unordered_map<GL_INDEX_ID, std::shared_ptr<const Rdb_key_def>>
+ &to_recalc,
+ bool include_memtables) {
DBUG_ENTER_FUNC();
// find per column family key ranges which need to be queried
std::unordered_map<rocksdb::ColumnFamilyHandle *, std::vector<rocksdb::Range>>
ranges;
- std::unordered_set<GL_INDEX_ID> ids_to_check;
- std::vector<uchar> buf(table_arg->s->keys * 2 *
- Rdb_key_def::INDEX_NUMBER_SIZE);
std::unordered_map<GL_INDEX_ID, Rdb_index_stats> stats;
- for (uint i = 0; i < table_arg->s->keys; i++) {
- const auto bufp = &buf[i * 2 * Rdb_key_def::INDEX_NUMBER_SIZE];
- const Rdb_key_def &kd = *m_key_descr_arr[i];
- const GL_INDEX_ID index_id = kd.get_gl_index_id();
- ranges[kd.get_cf()].push_back(get_range(i, bufp));
-
- ids_to_check.insert(index_id);
- // Initialize the stats to 0. If there are no files that contain
- // this gl_index_id, then 0 should be stored for the cached stats.
+ std::vector<uchar> buf(to_recalc.size() * 2 * Rdb_key_def::INDEX_NUMBER_SIZE);
+
+ uchar *bufp = buf.data();
+ for (const auto &it : to_recalc) {
+ const GL_INDEX_ID index_id = it.first;
+ auto &kd = it.second;
+ ranges[kd->get_cf()].push_back(myrocks::get_range(*kd, bufp));
+ bufp += 2 * Rdb_key_def::INDEX_NUMBER_SIZE;
+
stats[index_id] = Rdb_index_stats(index_id);
- DBUG_ASSERT(kd.get_key_parts() > 0);
- stats[index_id].m_distinct_keys_per_prefix.resize(kd.get_key_parts());
+ DBUG_ASSERT(kd->get_key_parts() > 0);
+ stats[index_id].m_distinct_keys_per_prefix.resize(kd->get_key_parts());
}
// get RocksDB table properties for these ranges
@@ -11362,8 +11776,8 @@ int ha_rocksdb::calculate_stats(const TABLE *const table_arg, THD *const thd,
it.first, &it.second[0], it.second.size(), &props);
DBUG_ASSERT(props.size() >= old_size);
if (!status.ok()) {
- DBUG_RETURN(
- rdb_error_to_mysql(status, "Could not access RocksDB properties"));
+ DBUG_RETURN(ha_rocksdb::rdb_error_to_mysql(
+ status, "Could not access RocksDB properties"));
}
}
@@ -11384,61 +11798,62 @@ int ha_rocksdb::calculate_stats(const TABLE *const table_arg, THD *const thd,
other SQL tables, it can be that we're only seeing a small fraction
of table's entries (and so we can't update statistics based on that).
*/
- if (ids_to_check.find(it1.m_gl_index_id) == ids_to_check.end())
+ if (stats.find(it1.m_gl_index_id) == stats.end()) {
continue;
+ }
- auto kd = ddl_manager.safe_find(it1.m_gl_index_id);
- DBUG_ASSERT(kd != nullptr);
- stats[it1.m_gl_index_id].merge(it1, true, kd->max_storage_fmt_length());
+ auto it_index = to_recalc.find(it1.m_gl_index_id);
+ DBUG_ASSERT(it_index != to_recalc.end());
+ if (it_index == to_recalc.end()) {
+ continue;
+ }
+ stats[it1.m_gl_index_id].merge(
+ it1, true, it_index->second->max_storage_fmt_length());
}
num_sst++;
}
- // calculate memtable cardinality
- Rdb_tbl_card_coll cardinality_collector(rocksdb_table_stats_sampling_pct);
- auto read_opts = rocksdb::ReadOptions();
- read_opts.read_tier = rocksdb::ReadTier::kMemtableTier;
- for (uint i = 0; i < table_arg->s->keys; i++) {
- const Rdb_key_def &kd = *m_key_descr_arr[i];
- Rdb_index_stats &stat = stats[kd.get_gl_index_id()];
-
- uchar r_buf[Rdb_key_def::INDEX_NUMBER_SIZE * 2];
- auto r = get_range(i, r_buf);
- uint64_t memtableCount;
- uint64_t memtableSize;
- rdb->GetApproximateMemTableStats(kd.get_cf(), r, &memtableCount,
- &memtableSize);
- if (memtableCount < (uint64_t)stat.m_rows / 10) {
- // skip tables that already have enough stats from SST files to reduce
- // overhead and avoid degradation of big tables stats by sampling from
- // relatively tiny (less than 10% of full data set) memtable dataset
- continue;
- }
+ if (include_memtables) {
+ // calculate memtable cardinality
+ Rdb_tbl_card_coll cardinality_collector(rocksdb_table_stats_sampling_pct);
+ auto read_opts = rocksdb::ReadOptions();
+ read_opts.read_tier = rocksdb::ReadTier::kMemtableTier;
+ for (const auto &it_kd : to_recalc) {
+ const std::shared_ptr<const Rdb_key_def> &kd = it_kd.second;
+ Rdb_index_stats &stat = stats[kd->get_gl_index_id()];
+
+ uchar r_buf[Rdb_key_def::INDEX_NUMBER_SIZE * 2];
+ auto r = myrocks::get_range(*kd, r_buf);
+ uint64_t memtableCount;
+ uint64_t memtableSize;
+ rdb->GetApproximateMemTableStats(kd->get_cf(), r, &memtableCount,
+ &memtableSize);
+ if (memtableCount < (uint64_t)stat.m_rows / 10) {
+ // skip tables that already have enough stats from SST files to reduce
+ // overhead and avoid degradation of big tables stats by sampling from
+ // relatively tiny (less than 10% of full data set) memtable dataset
+ continue;
+ }
- std::unique_ptr<rocksdb::Iterator> it = std::unique_ptr<rocksdb::Iterator>(
- rdb->NewIterator(read_opts, kd.get_cf()));
+ std::unique_ptr<rocksdb::Iterator> it =
+ std::unique_ptr<rocksdb::Iterator>(
+ rdb->NewIterator(read_opts, kd->get_cf()));
- uchar *first_key;
- uint key_size;
- if (is_pk(i, table, m_tbl_def)) {
- first_key = m_pk_packed_tuple;
- } else {
- first_key = m_sk_packed_tuple;
- }
- kd.get_first_key(first_key, &key_size);
- rocksdb::Slice first_index_key((const char *)first_key, key_size);
+ rocksdb::Slice first_index_key((const char *)r_buf,
+ Rdb_key_def::INDEX_NUMBER_SIZE);
- cardinality_collector.Reset();
- for (it->Seek(first_index_key); is_valid(it.get()); it->Next()) {
- const rocksdb::Slice key = it->key();
- if (!kd.covers_key(key)) {
- break; // end of this index
- }
- stat.m_rows++;
+ cardinality_collector.Reset();
+ for (it->Seek(first_index_key); is_valid(it.get()); it->Next()) {
+ const rocksdb::Slice key = it->key();
+ if (!kd->covers_key(key)) {
+ break; // end of this index
+ }
+ stat.m_rows++;
- cardinality_collector.ProcessKey(key, &kd, &stat);
+ cardinality_collector.ProcessKey(key, kd.get(), &stat);
+ }
+ cardinality_collector.AdjustStats(&stat);
}
- cardinality_collector.AdjustStats(&stat);
}
// set and persist new stats
@@ -11448,6 +11863,19 @@ int ha_rocksdb::calculate_stats(const TABLE *const table_arg, THD *const thd,
DBUG_RETURN(HA_EXIT_SUCCESS);
}
+int ha_rocksdb::calculate_stats_for_table() {
+ DBUG_ENTER_FUNC();
+
+ std::unordered_map<GL_INDEX_ID, std::shared_ptr<const Rdb_key_def>>
+ ids_to_check;
+ for (uint i = 0; i < table->s->keys; i++) {
+ ids_to_check.insert(std::make_pair(m_key_descr_arr[i]->get_gl_index_id(),
+ m_key_descr_arr[i]));
+ }
+
+ DBUG_RETURN(calculate_stats(ids_to_check, true));
+}
+
/*
@return
HA_ADMIN_OK OK
@@ -11456,7 +11884,16 @@ int ha_rocksdb::calculate_stats(const TABLE *const table_arg, THD *const thd,
int ha_rocksdb::analyze(THD *const thd, HA_CHECK_OPT *const check_opt) {
DBUG_ENTER_FUNC();
- if (table && calculate_stats(table, thd, check_opt) != HA_EXIT_SUCCESS) {
+ if (table) {
+ if (calculate_stats_for_table() != HA_EXIT_SUCCESS) {
+ DBUG_RETURN(HA_ADMIN_FAILED);
+ }
+ }
+
+ // A call to ::info is needed to repopulate some SQL level structs. This is
+ // necessary for online analyze because we cannot rely on another ::open
+ // call to call info for us.
+ if (info(HA_STATUS_CONST | HA_STATUS_VARIABLE) != HA_EXIT_SUCCESS) {
DBUG_RETURN(HA_ADMIN_FAILED);
}
@@ -12286,18 +12723,6 @@ bool ha_rocksdb::commit_inplace_alter_table(
dict_manager.finish_indexes_operation(
create_index_ids, Rdb_key_def::DDL_CREATE_INDEX_ONGOING);
- /*
- We need to recalculate the index stats here manually. The reason is that
- the secondary index does not exist inside
- m_index_num_to_keydef until it is committed to the data dictionary, which
- prevents us from updating the stats normally as the ddl_manager cannot
- find the proper gl_index_ids yet during adjust_stats calls.
- */
- if (calculate_stats(altered_table, nullptr, nullptr)) {
- /* Failed to update index statistics, should never happen */
- DBUG_ASSERT(0);
- }
-
rdb_drop_idx_thread.signal();
}
@@ -12369,6 +12794,8 @@ struct rocksdb_status_counters_t {
uint64_t block_cache_data_hit;
uint64_t block_cache_data_add;
uint64_t bloom_filter_useful;
+ uint64_t bloom_filter_full_positive;
+ uint64_t bloom_filter_full_true_positive;
uint64_t memtable_hit;
uint64_t memtable_miss;
uint64_t get_hit_l0;
@@ -12443,6 +12870,8 @@ DEF_SHOW_FUNC(block_cache_data_miss, BLOCK_CACHE_DATA_MISS)
DEF_SHOW_FUNC(block_cache_data_hit, BLOCK_CACHE_DATA_HIT)
DEF_SHOW_FUNC(block_cache_data_add, BLOCK_CACHE_DATA_ADD)
DEF_SHOW_FUNC(bloom_filter_useful, BLOOM_FILTER_USEFUL)
+DEF_SHOW_FUNC(bloom_filter_full_positive, BLOOM_FILTER_FULL_POSITIVE)
+DEF_SHOW_FUNC(bloom_filter_full_true_positive, BLOOM_FILTER_FULL_TRUE_POSITIVE)
DEF_SHOW_FUNC(memtable_hit, MEMTABLE_HIT)
DEF_SHOW_FUNC(memtable_miss, MEMTABLE_MISS)
DEF_SHOW_FUNC(get_hit_l0, GET_HIT_L0)
@@ -12677,6 +13106,8 @@ static SHOW_VAR rocksdb_status_vars[] = {
DEF_STATUS_VAR(block_cache_data_hit),
DEF_STATUS_VAR(block_cache_data_add),
DEF_STATUS_VAR(bloom_filter_useful),
+ DEF_STATUS_VAR(bloom_filter_full_positive),
+ DEF_STATUS_VAR(bloom_filter_full_true_positive),
DEF_STATUS_VAR(memtable_hit),
DEF_STATUS_VAR(memtable_miss),
DEF_STATUS_VAR(get_hit_l0),
@@ -12734,6 +13165,10 @@ static SHOW_VAR rocksdb_status_vars[] = {
&rocksdb_snapshot_conflict_errors, SHOW_LONGLONG),
DEF_STATUS_VAR_PTR("wal_group_syncs", &rocksdb_wal_group_syncs,
SHOW_LONGLONG),
+ DEF_STATUS_VAR_PTR("manual_compactions_processed",
+ &rocksdb_manual_compactions_processed, SHOW_LONGLONG),
+ DEF_STATUS_VAR_PTR("manual_compactions_running",
+ &rocksdb_manual_compactions_running, SHOW_LONGLONG),
DEF_STATUS_VAR_PTR("number_sst_entry_put", &rocksdb_num_sst_entry_put,
SHOW_LONGLONG),
DEF_STATUS_VAR_PTR("number_sst_entry_delete", &rocksdb_num_sst_entry_delete,
@@ -12807,24 +13242,193 @@ void Rdb_background_thread::run() {
rdb_handle_io_error(s, RDB_IO_ERROR_BG_THREAD);
}
}
+ // Recalculate statistics for indexes.
+ if (rocksdb_stats_recalc_rate) {
+ std::unordered_map<GL_INDEX_ID, std::shared_ptr<const Rdb_key_def>>
+ to_recalc;
+
+ if (rdb_indexes_to_recalc.empty()) {
+ struct Rdb_index_collector : public Rdb_tables_scanner {
+ int add_table(Rdb_tbl_def *tdef) override {
+ for (uint i = 0; i < tdef->m_key_count; i++) {
+ rdb_indexes_to_recalc.push_back(
+ tdef->m_key_descr_arr[i]->get_gl_index_id());
+ }
+ return HA_EXIT_SUCCESS;
+ }
+ } collector;
+ ddl_manager.scan_for_tables(&collector);
+ }
+
+ while (to_recalc.size() < rocksdb_stats_recalc_rate &&
+ !rdb_indexes_to_recalc.empty()) {
+ const auto index_id = rdb_indexes_to_recalc.back();
+ rdb_indexes_to_recalc.pop_back();
+
+ std::shared_ptr<const Rdb_key_def> keydef =
+ ddl_manager.safe_find(index_id);
+
+ if (keydef) {
+ to_recalc.insert(std::make_pair(keydef->get_gl_index_id(), keydef));
+ }
+ }
+
+ if (!to_recalc.empty()) {
+ calculate_stats(to_recalc, false);
+ }
+ }
+
}
// save remaining stats which might've left unsaved
ddl_manager.persist_stats();
}
-bool ha_rocksdb::check_bloom_and_set_bounds(THD *thd, const Rdb_key_def &kd,
- const rocksdb::Slice &eq_cond,
- const bool use_all_keys,
- uchar *lower_bound_buf,
- uchar *upper_bound_buf,
- rocksdb::Slice *out_lower_bound,
- rocksdb::Slice *out_upper_bound) {
+/*
+ A background thread to handle manual compactions,
+ except for dropping indexes/tables. Every second, it checks
+ pending manual compactions, and it calls CompactRange if there is.
+*/
+void Rdb_manual_compaction_thread::run() {
+ mysql_mutex_init(0, &m_mc_mutex, MY_MUTEX_INIT_FAST);
+ RDB_MUTEX_LOCK_CHECK(m_signal_mutex);
+ for (;;) {
+ if (m_stop) {
+ break;
+ }
+ timespec ts;
+ set_timespec(ts, 1);
+
+ const auto ret MY_ATTRIBUTE((__unused__)) =
+ mysql_cond_timedwait(&m_signal_cond, &m_signal_mutex, &ts);
+ if (m_stop) {
+ break;
+ }
+ // make sure, no program error is returned
+ DBUG_ASSERT(ret == 0 || ret == ETIMEDOUT);
+ RDB_MUTEX_UNLOCK_CHECK(m_signal_mutex);
+
+ RDB_MUTEX_LOCK_CHECK(m_mc_mutex);
+ // Grab the first item and proceed, if not empty.
+ if (m_requests.empty()) {
+ RDB_MUTEX_UNLOCK_CHECK(m_mc_mutex);
+ RDB_MUTEX_LOCK_CHECK(m_signal_mutex);
+ continue;
+ }
+ Manual_compaction_request &mcr = m_requests.begin()->second;
+ DBUG_ASSERT(mcr.cf != nullptr);
+ DBUG_ASSERT(mcr.state == Manual_compaction_request::INITED);
+ mcr.state = Manual_compaction_request::RUNNING;
+ RDB_MUTEX_UNLOCK_CHECK(m_mc_mutex);
+
+ DBUG_ASSERT(mcr.state == Manual_compaction_request::RUNNING);
+ // NO_LINT_DEBUG
+ sql_print_information("Manual Compaction id %d cf %s started.", mcr.mc_id,
+ mcr.cf->GetName().c_str());
+ rocksdb_manual_compactions_running++;
+ if (rocksdb_debug_manual_compaction_delay > 0) {
+ my_sleep(rocksdb_debug_manual_compaction_delay * 1000000);
+ }
+ // CompactRange may take a very long time. On clean shutdown,
+ // it is cancelled by CancelAllBackgroundWork, then status is
+ // set to shutdownInProgress.
+ const rocksdb::Status s = rdb->CompactRange(
+ getCompactRangeOptions(mcr.concurrency), mcr.cf, mcr.start, mcr.limit);
+ rocksdb_manual_compactions_running--;
+ if (s.ok()) {
+ // NO_LINT_DEBUG
+ sql_print_information("Manual Compaction id %d cf %s ended.", mcr.mc_id,
+ mcr.cf->GetName().c_str());
+ } else {
+ // NO_LINT_DEBUG
+ sql_print_information("Manual Compaction id %d cf %s aborted. %s",
+ mcr.mc_id, mcr.cf->GetName().c_str(), s.getState());
+ if (!s.IsShutdownInProgress()) {
+ rdb_handle_io_error(s, RDB_IO_ERROR_BG_THREAD);
+ } else {
+ DBUG_ASSERT(m_requests.size() == 1);
+ }
+ }
+ rocksdb_manual_compactions_processed++;
+ clear_manual_compaction_request(mcr.mc_id, false);
+ RDB_MUTEX_LOCK_CHECK(m_signal_mutex);
+ }
+ clear_all_manual_compaction_requests();
+ DBUG_ASSERT(m_requests.empty());
+ RDB_MUTEX_UNLOCK_CHECK(m_signal_mutex);
+ mysql_mutex_destroy(&m_mc_mutex);
+}
+
+void Rdb_manual_compaction_thread::clear_all_manual_compaction_requests() {
+ RDB_MUTEX_LOCK_CHECK(m_mc_mutex);
+ m_requests.clear();
+ RDB_MUTEX_UNLOCK_CHECK(m_mc_mutex);
+}
+
+void Rdb_manual_compaction_thread::clear_manual_compaction_request(
+ int mc_id, bool init_only) {
+ bool erase = true;
+ RDB_MUTEX_LOCK_CHECK(m_mc_mutex);
+ auto it = m_requests.find(mc_id);
+ if (it != m_requests.end()) {
+ if (init_only) {
+ Manual_compaction_request mcr = it->second;
+ if (mcr.state != Manual_compaction_request::INITED) {
+ erase = false;
+ }
+ }
+ if (erase) {
+ m_requests.erase(it);
+ }
+ } else {
+ // Current code path guarantees that erasing by the same mc_id happens
+ // at most once. INITED state may be erased by a thread that requested
+ // the compaction. RUNNING state is erased by mc thread only.
+ DBUG_ASSERT(0);
+ }
+ RDB_MUTEX_UNLOCK_CHECK(m_mc_mutex);
+}
+
+int Rdb_manual_compaction_thread::request_manual_compaction(
+ rocksdb::ColumnFamilyHandle *cf, rocksdb::Slice *start,
+ rocksdb::Slice *limit, int concurrency) {
+ int mc_id = -1;
+ RDB_MUTEX_LOCK_CHECK(m_mc_mutex);
+ if (m_requests.size() >= rocksdb_max_manual_compactions) {
+ RDB_MUTEX_UNLOCK_CHECK(m_mc_mutex);
+ return mc_id;
+ }
+ Manual_compaction_request mcr;
+ mc_id = mcr.mc_id = ++m_latest_mc_id;
+ mcr.state = Manual_compaction_request::INITED;
+ mcr.cf = cf;
+ mcr.start = start;
+ mcr.limit = limit;
+ mcr.concurrency = concurrency;
+ m_requests.insert(std::make_pair(mcr.mc_id, mcr));
+ RDB_MUTEX_UNLOCK_CHECK(m_mc_mutex);
+ return mc_id;
+}
+
+bool Rdb_manual_compaction_thread::is_manual_compaction_finished(int mc_id) {
+ bool finished = false;
+ RDB_MUTEX_LOCK_CHECK(m_mc_mutex);
+ if (m_requests.count(mc_id) == 0) {
+ finished = true;
+ }
+ RDB_MUTEX_UNLOCK_CHECK(m_mc_mutex);
+ return finished;
+}
+
+bool ha_rocksdb::check_bloom_and_set_bounds(
+ THD *thd, const Rdb_key_def &kd, const rocksdb::Slice &eq_cond,
+ const bool use_all_keys, size_t bound_len, uchar *const lower_bound,
+ uchar *const upper_bound, rocksdb::Slice *lower_bound_slice,
+ rocksdb::Slice *upper_bound_slice) {
bool can_use_bloom = can_use_bloom_filter(thd, kd, eq_cond, use_all_keys);
if (!can_use_bloom) {
- setup_iterator_bounds(kd, eq_cond,
- lower_bound_buf, upper_bound_buf,
- out_lower_bound, out_upper_bound);
+ setup_iterator_bounds(kd, eq_cond, bound_len, lower_bound, upper_bound,
+ lower_bound_slice, upper_bound_slice);
}
return can_use_bloom;
}
@@ -12934,7 +13538,6 @@ void rdb_update_global_stats(const operation_type &type, uint count,
int rdb_get_table_perf_counters(const char *const tablename,
Rdb_perf_counters *const counters) {
- DBUG_ASSERT(counters != nullptr);
DBUG_ASSERT(tablename != nullptr);
Rdb_table_handler *table_handler;
@@ -12974,10 +13577,7 @@ const char *get_rdb_io_error_string(const RDB_IO_ERROR_TYPE err_type) {
// so that we can capture as much data as possible to debug the root cause
// more efficiently.
#ifdef __GNUC__
-#pragma GCC push_options
-#pragma GCC optimize("O0")
#endif
-
void rdb_handle_io_error(const rocksdb::Status status,
const RDB_IO_ERROR_TYPE err_type) {
if (status.IsIOError()) {
@@ -12992,6 +13592,9 @@ void rdb_handle_io_error(const rocksdb::Status status,
}
case RDB_IO_ERROR_BG_THREAD: {
rdb_log_status_error(status, "BG thread failed to write to RocksDB");
+ /* NO_LINT_DEBUG */
+ sql_print_error("MyRocks: aborting on BG write error.");
+ abort();
break;
}
case RDB_IO_ERROR_GENERAL: {
@@ -13027,9 +13630,7 @@ void rdb_handle_io_error(const rocksdb::Status status,
}
}
#ifdef __GNUC__
-#pragma GCC pop_options
#endif
-
Rdb_dict_manager *rdb_get_dict_manager(void) { return &dict_manager; }
Rdb_ddl_manager *rdb_get_ddl_manager(void) { return &ddl_manager; }
@@ -13330,6 +13931,42 @@ static void rocksdb_set_wal_bytes_per_sync(
RDB_MUTEX_UNLOCK_CHECK(rdb_sysvars_mutex);
}
+/*
+ Validating and updating block cache size via sys_var::check path.
+ SetCapacity may take seconds when reducing block cache, and
+ sys_var::update holds LOCK_global_system_variables mutex, so
+ updating block cache size is done at check path instead.
+*/
+static int rocksdb_validate_set_block_cache_size(
+ THD *thd MY_ATTRIBUTE((__unused__)),
+ struct st_mysql_sys_var *const var MY_ATTRIBUTE((__unused__)),
+ void *var_ptr, struct st_mysql_value *value) {
+ DBUG_ASSERT(value != nullptr);
+
+ long long new_value;
+
+ /* value is NULL */
+ if (value->val_int(value, &new_value)) {
+ return HA_EXIT_FAILURE;
+ }
+
+ if (new_value < RDB_MIN_BLOCK_CACHE_SIZE ||
+ (uint64_t)new_value > (uint64_t)LONGLONG_MAX) {
+ return HA_EXIT_FAILURE;
+ }
+
+ RDB_MUTEX_LOCK_CHECK(rdb_block_cache_resize_mutex);
+ const rocksdb::BlockBasedTableOptions &table_options =
+ rdb_get_table_options();
+
+ if (rocksdb_block_cache_size != new_value && table_options.block_cache) {
+ table_options.block_cache->SetCapacity(new_value);
+ }
+ *static_cast<int64_t *>(var_ptr) = static_cast<int64_t>(new_value);
+ RDB_MUTEX_UNLOCK_CHECK(rdb_block_cache_resize_mutex);
+ return HA_EXIT_SUCCESS;
+}
+
static int
rocksdb_validate_update_cf_options(THD * /* unused */,
struct st_mysql_sys_var * /*unused*/,
@@ -13511,6 +14148,13 @@ double ha_rocksdb::read_time(uint index, uint ranges, ha_rows rows) {
DBUG_RETURN((rows / 20.0) + 1);
}
+void ha_rocksdb::print_error(int error, myf errflag) {
+ if (error == HA_ERR_ROCKSDB_STATUS_BUSY) {
+ error = HA_ERR_LOCK_DEADLOCK;
+ }
+ handler::print_error(error, errflag);
+}
+
std::string rdb_corruption_marker_file_name() {
std::string ret(rocksdb_datadir);
ret.append("/ROCKSDB_CORRUPTED");
@@ -13573,7 +14217,7 @@ maria_declare_plugin(rocksdb_se){
myrocks::rdb_i_s_perf_context, myrocks::rdb_i_s_perf_context_global,
myrocks::rdb_i_s_cfoptions, myrocks::rdb_i_s_compact_stats,
myrocks::rdb_i_s_global_info, myrocks::rdb_i_s_ddl,
- myrocks::rdb_i_s_index_file_map, myrocks::rdb_i_s_lock_info,
- myrocks::rdb_i_s_trx_info,
+ myrocks::rdb_i_s_sst_props, myrocks::rdb_i_s_index_file_map,
+ myrocks::rdb_i_s_lock_info, myrocks::rdb_i_s_trx_info,
myrocks::rdb_i_s_deadlock_info
maria_declare_plugin_end;
diff --git a/storage/rocksdb/ha_rocksdb.h b/storage/rocksdb/ha_rocksdb.h
index 739a2c8cdd6..c4447109b0d 100644
--- a/storage/rocksdb/ha_rocksdb.h
+++ b/storage/rocksdb/ha_rocksdb.h
@@ -107,6 +107,7 @@ struct Rdb_deadlock_info {
std::string table_name;
};
std::vector <Rdb_dl_trx_info> path;
+ int64_t deadlock_time;
ulonglong victim_trx_id;
};
@@ -148,6 +149,11 @@ const char *const BG_THREAD_NAME = "myrocks-bg";
const char *const INDEX_THREAD_NAME = "myrocks-index";
/*
+ Name for the manual compaction thread.
+*/
+const char *const MANUAL_COMPACTION_THREAD_NAME = "myrocks-mc";
+
+/*
Separator between partition name and the qualifier. Sample usage:
- p0_cfname=foo
@@ -503,6 +509,12 @@ class ha_rocksdb : public my_core::handler {
const rocksdb::Snapshot *m_scan_it_snapshot;
+ /* Buffers used for upper/lower bounds for m_scan_it. */
+ uchar *m_scan_it_lower_bound;
+ uchar *m_scan_it_upper_bound;
+ rocksdb::Slice m_scan_it_lower_bound_slice;
+ rocksdb::Slice m_scan_it_upper_bound_slice;
+
Rdb_tbl_def *m_tbl_def;
/* Primary Key encoder from KeyTupleFormat to StorageFormat */
@@ -566,12 +578,6 @@ class ha_rocksdb : public my_core::handler {
uchar *m_dup_sk_packed_tuple;
uchar *m_dup_sk_packed_tuple_old;
- /* Buffers used for passing upper/bound eq conditions. */
- uchar *m_eq_cond_lower_bound;
- uchar *m_eq_cond_upper_bound;
- rocksdb::Slice m_eq_cond_lower_bound_slice;
- rocksdb::Slice m_eq_cond_upper_bound_slice;
-
/*
Temporary space for packing VARCHARs (we provide it to
pack_record()/pack_index_tuple() calls).
@@ -653,21 +659,20 @@ class ha_rocksdb : public my_core::handler {
enum ha_rkey_function find_flag) const
MY_ATTRIBUTE((__nonnull__, __warn_unused_result__));
void setup_iterator_bounds(const Rdb_key_def &kd,
- const rocksdb::Slice &eq_cond,
- uchar *lower_bound_buf,
- uchar *upper_bound_buf,
- rocksdb::Slice *out_lower_bound,
- rocksdb::Slice *out_upper_bound);
+ const rocksdb::Slice &eq_cond, size_t bound_len,
+ uchar *const lower_bound, uchar *const upper_bound,
+ rocksdb::Slice *lower_bound_slice,
+ rocksdb::Slice *upper_bound_slice);
bool can_use_bloom_filter(THD *thd, const Rdb_key_def &kd,
const rocksdb::Slice &eq_cond,
const bool use_all_keys);
bool check_bloom_and_set_bounds(THD *thd, const Rdb_key_def &kd,
const rocksdb::Slice &eq_cond,
- const bool use_all_keys,
- uchar *lower_bound_buf,
- uchar *upper_bound_buf,
- rocksdb::Slice *out_lower_bound,
- rocksdb::Slice *out_upper_bound);
+ const bool use_all_keys, size_t bound_len,
+ uchar *const lower_bound,
+ uchar *const upper_bound,
+ rocksdb::Slice *lower_bound_slice,
+ rocksdb::Slice *upper_bound_slice);
void setup_scan_iterator(const Rdb_key_def &kd, rocksdb::Slice *slice,
const bool use_all_keys, const uint eq_cond_len)
MY_ATTRIBUTE((__nonnull__));
@@ -1053,6 +1058,7 @@ public:
}
virtual double read_time(uint, uint, ha_rows rows) override;
+ virtual void print_error(int error, myf errflag) override;
int open(const char *const name, int mode, uint test_if_locked) override
MY_ATTRIBUTE((__warn_unused_result__));
@@ -1167,8 +1173,8 @@ private:
MY_ATTRIBUTE((__nonnull__));
int compare_key_parts(const KEY *const old_key,
- const KEY *const new_key) const;
- MY_ATTRIBUTE((__nonnull__, __warn_unused_result__));
+ const KEY *const new_key) const
+ MY_ATTRIBUTE((__nonnull__, __warn_unused_result__));
int compare_keys(const KEY *const old_key, const KEY *const new_key) const
MY_ATTRIBUTE((__nonnull__, __warn_unused_result__));
@@ -1223,7 +1229,7 @@ private:
int update_pk(const Rdb_key_def &kd, const struct update_row_info &row_info,
const bool &pk_changed) MY_ATTRIBUTE((__warn_unused_result__));
int update_sk(const TABLE *const table_arg, const Rdb_key_def &kd,
- const struct update_row_info &row_info)
+ const struct update_row_info &row_info, const bool bulk_load_sk)
MY_ATTRIBUTE((__warn_unused_result__));
int update_indexes(const struct update_row_info &row_info,
const bool &pk_changed)
@@ -1277,7 +1283,9 @@ private:
int finalize_bulk_load(bool print_client_error = true)
MY_ATTRIBUTE((__warn_unused_result__));
-public:
+ int calculate_stats_for_table() MY_ATTRIBUTE((__warn_unused_result__));
+
+ public:
int index_init(uint idx, bool sorted) override
MY_ATTRIBUTE((__warn_unused_result__));
int index_end() override MY_ATTRIBUTE((__warn_unused_result__));
@@ -1370,9 +1378,6 @@ public:
MY_ATTRIBUTE((__warn_unused_result__));
int analyze(THD *const thd, HA_CHECK_OPT *const check_opt) override
MY_ATTRIBUTE((__warn_unused_result__));
- int calculate_stats(const TABLE *const table_arg, THD *const thd,
- HA_CHECK_OPT *const check_opt)
- MY_ATTRIBUTE((__warn_unused_result__));
enum_alter_inplace_result check_if_supported_inplace_alter(
TABLE *altered_table,
@@ -1402,7 +1407,7 @@ public:
virtual void rpl_after_delete_rows() override;
virtual void rpl_before_update_rows() override;
virtual void rpl_after_update_rows() override;
- virtual bool use_read_free_rpl();
+ virtual bool use_read_free_rpl() override;
#endif // MARIAROCKS_NOT_YET
private:
diff --git a/storage/rocksdb/ha_rocksdb_proto.h b/storage/rocksdb/ha_rocksdb_proto.h
index 85c3968cc99..deb65edddd3 100644
--- a/storage/rocksdb/ha_rocksdb_proto.h
+++ b/storage/rocksdb/ha_rocksdb_proto.h
@@ -39,7 +39,12 @@ enum RDB_IO_ERROR_TYPE {
const char *get_rdb_io_error_string(const RDB_IO_ERROR_TYPE err_type);
void rdb_handle_io_error(const rocksdb::Status status,
- const RDB_IO_ERROR_TYPE err_type);
+ const RDB_IO_ERROR_TYPE err_type)
+#if defined(__clang__)
+ MY_ATTRIBUTE((optnone));
+#else
+ MY_ATTRIBUTE((optimize("O0")));
+#endif
int rdb_normalize_tablename(const std::string &tablename, std::string *str)
MY_ATTRIBUTE((__nonnull__, __warn_unused_result__));
diff --git a/storage/rocksdb/mysql-test/rocksdb/combinations b/storage/rocksdb/mysql-test/rocksdb/combinations
new file mode 100644
index 00000000000..d49de3d38b3
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/combinations
@@ -0,0 +1,6 @@
+[write_committed]
+loose-rocksdb_write_policy=write_committed
+
+[write_prepared]
+loose-rocksdb_write_policy=write_prepared
+loose-rocksdb_commit_time_batch_for_recovery=on
diff --git a/storage/rocksdb/mysql-test/rocksdb/include/have_write_committed.inc b/storage/rocksdb/mysql-test/rocksdb/include/have_write_committed.inc
new file mode 100644
index 00000000000..681b966f680
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/include/have_write_committed.inc
@@ -0,0 +1,3 @@
+if (`select count(*) = 0 from information_schema.session_variables where variable_name = 'rocksdb_write_policy' and variable_value = 'write_committed';`) {
+ --skip Test requires write_committed policy
+}
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/add_index_inplace.result b/storage/rocksdb/mysql-test/rocksdb/r/add_index_inplace.result
index 6325dc97cf5..32c0537c780 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/add_index_inplace.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/add_index_inplace.result
@@ -299,11 +299,13 @@ connection con1;
show global variables like 'rocksdb_bulk_load%';
Variable_name Value
rocksdb_bulk_load ON
+rocksdb_bulk_load_allow_sk OFF
rocksdb_bulk_load_allow_unsorted OFF
rocksdb_bulk_load_size 1000
show session variables like 'rocksdb_bulk_load%';
Variable_name Value
rocksdb_bulk_load ON
+rocksdb_bulk_load_allow_sk OFF
rocksdb_bulk_load_allow_unsorted OFF
rocksdb_bulk_load_size 1000
CREATE TABLE t1 (i INT, j INT, PRIMARY KEY (i)) ENGINE = ROCKSDB;
@@ -356,6 +358,7 @@ SET session rocksdb_merge_buf_size = 340;
show variables like 'rocksdb_bulk_load%';
Variable_name Value
rocksdb_bulk_load OFF
+rocksdb_bulk_load_allow_sk OFF
rocksdb_bulk_load_allow_unsorted OFF
rocksdb_bulk_load_size 1000
CREATE TABLE t1 (a VARCHAR(80)) ENGINE=RocksDB;
@@ -463,3 +466,24 @@ t1 CREATE TABLE `t1` (
KEY `kb` (`b`(8))
) ENGINE=ROCKSDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin
DROP TABLE t1;
+SET @prior_rocksdb_table_stats_sampling_pct = @@rocksdb_table_stats_sampling_pct;
+set global rocksdb_table_stats_sampling_pct = 100;
+CREATE TABLE t1 (a INT, b INT, PRIMARY KEY ka(a)) ENGINE=RocksDB;
+INSERT INTO t1 (a, b) VALUES (1, 10);
+INSERT INTO t1 (a, b) VALUES (2, 10);
+INSERT INTO t1 (a, b) VALUES (3, 20);
+INSERT INTO t1 (a, b) VALUES (4, 20);
+set global rocksdb_force_flush_memtable_now=1;
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+SHOW INDEX in t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
+t1 0 PRIMARY 1 a A 4 NULL NULL LSMTREE
+ALTER TABLE t1 ADD INDEX kb(b), ALGORITHM=INPLACE;
+SHOW INDEX in t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
+t1 0 PRIMARY 1 a A 4 NULL NULL LSMTREE
+t1 1 kb 1 b A 2 NULL NULL YES LSMTREE
+DROP TABLE t1;
+SET global rocksdb_table_stats_sampling_pct = @prior_rocksdb_table_stats_sampling_pct;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/add_index_inplace_sstfilewriter.result b/storage/rocksdb/mysql-test/rocksdb/r/add_index_inplace_sstfilewriter.result
index 08f2329f688..0617232f1e3 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/add_index_inplace_sstfilewriter.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/add_index_inplace_sstfilewriter.result
@@ -17,7 +17,7 @@ ALTER TABLE t1 ADD INDEX kb(b), ALGORITHM=INPLACE;
set @tmp= @@rocksdb_max_row_locks;
set session rocksdb_max_row_locks=1000;
ALTER TABLE t1 ADD INDEX kb_copy(b), ALGORITHM=COPY;
-ERROR HY000: Status error 10 received from RocksDB: Operation aborted: Failed to acquire lock due to max_num_locks limit
+ERROR HY000: Got error 10 'Operation aborted: Failed to acquire lock due to max_num_locks limit' from ROCKSDB
set session rocksdb_bulk_load=1;
ALTER TABLE t1 ADD INDEX kb_copy(b), ALGORITHM=COPY;
set session rocksdb_bulk_load=0;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/autoinc_debug.result b/storage/rocksdb/mysql-test/rocksdb/r/autoinc_debug.result
index fe08cd7c361..604e5572eab 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/autoinc_debug.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/autoinc_debug.result
@@ -59,12 +59,10 @@ insert into t values ();
set debug_dbug="+d,crash_commit_before";
commit;
ERROR HY000: Lost connection to MySQL server during query
-select table_schema, table_name, auto_increment from information_schema.tables where table_name = 't';
-table_schema table_name auto_increment
-test t 4
-select max(i) from t;
-max(i)
-3
+select max(i) into @row_max from t;
+select table_schema, table_name, auto_increment > @row_max from information_schema.tables where table_name = 't';
+table_schema table_name auto_increment > @row_max
+test t 1
# After engine prepare
begin;
insert into t values ();
@@ -72,12 +70,10 @@ insert into t values ();
set debug_dbug="+d,crash_commit_after_prepare";
commit;
ERROR HY000: Lost connection to MySQL server during query
-select table_schema, table_name, auto_increment from information_schema.tables where table_name = 't';
-table_schema table_name auto_increment
-test t 4
-select max(i) from t;
-max(i)
-3
+select max(i) into @row_max from t;
+select table_schema, table_name, auto_increment > @row_max from information_schema.tables where table_name = 't';
+table_schema table_name auto_increment > @row_max
+test t 1
# After binlog
begin;
insert into t values ();
@@ -85,12 +81,10 @@ insert into t values ();
set debug_dbug="+d,crash_commit_after_log";
commit;
ERROR HY000: Lost connection to MySQL server during query
-select table_schema, table_name, auto_increment from information_schema.tables where table_name = 't';
-table_schema table_name auto_increment
-test t 6
-select max(i) from t;
-max(i)
-5
+select max(i) into @row_max from t;
+select table_schema, table_name, auto_increment > @row_max from information_schema.tables where table_name = 't';
+table_schema table_name auto_increment > @row_max
+test t 1
# After everything
begin;
insert into t values ();
@@ -98,10 +92,8 @@ insert into t values ();
set debug_dbug="+d,crash_commit_after";
commit;
ERROR HY000: Lost connection to MySQL server during query
-select table_schema, table_name, auto_increment from information_schema.tables where table_name = 't';
-table_schema table_name auto_increment
-test t 8
-select max(i) from t;
-max(i)
-7
+select max(i) into @row_max from t;
+select table_schema, table_name, auto_increment > @row_max from information_schema.tables where table_name = 't';
+table_schema table_name auto_increment > @row_max
+test t 1
drop table t;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/autoinc_vars.result b/storage/rocksdb/mysql-test/rocksdb/r/autoinc_vars.result
index 0c496227006..f59b841a595 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/autoinc_vars.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/autoinc_vars.result
@@ -158,3 +158,21 @@ INSERT INTO t1 (a) VALUES (1);
UPDATE t1 SET pk = 3;
ALTER TABLE t1 AUTO_INCREMENT 2;
DROP TABLE t1;
+#----------------------------------
+# Issue #792 Crash in autoincrement
+#----------------------------------
+CREATE TABLE t1(C1 DOUBLE AUTO_INCREMENT KEY,C2 CHAR) ENGINE=ROCKSDB;
+INSERT INTO t1 VALUES(2177,0);
+DROP TABLE t1;
+CREATE TABLE t0(c0 BLOB) ENGINE=ROCKSDB;
+INSERT INTO t0 VALUES(0);
+ALTER TABLE t0 AUTO_INCREMENT=0;
+DROP TABLE t0;
+#----------------------------------
+# Issue #869 Crash in autoincrement
+#----------------------------------
+CREATE TABLE t1 (pk INT AUTO_INCREMENT, a INT, PRIMARY KEY(pk)) ENGINE=RocksDB;
+INSERT INTO t1 (a) VALUES (1);
+UPDATE t1 SET pk = 3;
+ALTER TABLE t1 AUTO_INCREMENT 2;
+DROP TABLE t1;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/bloomfilter_bulk_load.result b/storage/rocksdb/mysql-test/rocksdb/r/bloomfilter_bulk_load.result
new file mode 100644
index 00000000000..4b02d1103cf
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/r/bloomfilter_bulk_load.result
@@ -0,0 +1,15 @@
+create table r1 (id bigint primary key, value bigint) engine=rocksdb;
+create table r2 (id bigint, value bigint, primary key (id) comment 'cf2') engine=rocksdb;
+set session rocksdb_bulk_load=1;
+set session rocksdb_bulk_load=0;
+select variable_value into @h from information_schema.global_status where variable_name='rocksdb_block_cache_filter_hit';
+insert into r1 values (100, 100);
+select variable_value-@h from information_schema.global_status where variable_name='rocksdb_block_cache_filter_hit';
+variable_value-@h
+1
+select variable_value into @h from information_schema.global_status where variable_name='rocksdb_block_cache_filter_hit';
+insert into r2 values (100, 100);
+select variable_value-@h from information_schema.global_status where variable_name='rocksdb_block_cache_filter_hit';
+variable_value-@h
+0
+DROP TABLE r1, r2;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/bulk_load_sk.result b/storage/rocksdb/mysql-test/rocksdb/r/bulk_load_sk.result
new file mode 100644
index 00000000000..42f820a2a42
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/r/bulk_load_sk.result
@@ -0,0 +1,229 @@
+SET rocksdb_bulk_load_size=15;
+CREATE TABLE t4 (a INT, b INT, c INT,
+PRIMARY KEY (a),
+KEY (b),
+KEY (c) COMMENT "rev:cf") ENGINE=ROCKSDB;
+CREATE TABLE t3 (a INT, b INT, c INT,
+PRIMARY KEY (a),
+KEY (b),
+KEY (c) COMMENT "rev:cf") ENGINE=ROCKSDB;
+CREATE TABLE t2 (a INT, b INT, c INT,
+PRIMARY KEY (a),
+KEY (b),
+KEY (c) COMMENT "rev:cf") ENGINE=ROCKSDB;
+CREATE TABLE t1 (a INT, b INT, c INT,
+PRIMARY KEY (a),
+KEY (b),
+KEY (c) COMMENT "rev:cf") ENGINE=ROCKSDB;
+SET rocksdb_bulk_load=1;
+INSERT INTO t1 SELECT * FROM t3 FORCE INDEX (PRIMARY) ORDER BY a;
+SELECT count(*) FROM t1 FORCE INDEX (PRIMARY);
+count(*)
+0
+SELECT count(*) FROM t1 FORCE INDEX (b);
+count(*)
+10
+SELECT count(*) FROM t1 FORCE INDEX (c);
+count(*)
+10
+SET rocksdb_bulk_load=0;
+SELECT * FROM t1 FORCE INDEX (PRIMARY);
+a b c
+-9 11 11
+-7 9 9
+-5 7 7
+-3 5 5
+-1 3 3
+2 0 0
+4 -2 -2
+6 -4 -4
+8 -6 -6
+10 -8 -8
+SELECT b FROM t1 FORCE INDEX (b);
+b
+-8
+-6
+-4
+-2
+0
+3
+5
+7
+9
+11
+SELECT c FROM t1 FORCE INDEX (c);
+c
+-8
+-6
+-4
+-2
+0
+3
+5
+7
+9
+11
+Checksums should match
+CHECKSUM TABLE t3;
+Table Checksum
+test.t3 3862424802
+CHECKSUM TABLE t1;
+Table Checksum
+test.t1 3862424802
+SET rocksdb_bulk_load_allow_sk=1;
+SET rocksdb_bulk_load=1;
+INSERT INTO t4 SELECT * FROM t3 FORCE INDEX (PRIMARY) ORDER BY a;
+SELECT count(*) FROM t4 FORCE INDEX (PRIMARY);
+count(*)
+0
+SELECT count(*) FROM t4 FORCE INDEX (b);
+count(*)
+0
+SELECT count(*) FROM t4 FORCE INDEX (c);
+count(*)
+0
+SET rocksdb_bulk_load=0;
+SELECT * FROM t4 FORCE INDEX (PRIMARY);
+a b c
+-9 11 11
+-7 9 9
+-5 7 7
+-3 5 5
+-1 3 3
+2 0 0
+4 -2 -2
+6 -4 -4
+8 -6 -6
+10 -8 -8
+SELECT b FROM t4 FORCE INDEX (b);
+b
+-8
+-6
+-4
+-2
+0
+3
+5
+7
+9
+11
+SELECT c FROM t4 FORCE INDEX (c);
+c
+-8
+-6
+-4
+-2
+0
+3
+5
+7
+9
+11
+Checksums should match
+CHECKSUM TABLE t3;
+Table Checksum
+test.t3 3862424802
+CHECKSUM TABLE t4;
+Table Checksum
+test.t4 3862424802
+SET rocksdb_bulk_load_allow_unsorted=1;
+SET rocksdb_bulk_load_allow_sk=1;
+SET rocksdb_bulk_load=1;
+INSERT INTO t2 SELECT * FROM t3 WHERE b >= 0 ORDER BY b;
+INSERT INTO t2 SELECT * FROM t3 WHERE b < 0 ORDER BY b;
+SELECT count(*) FROM t2 FORCE INDEX (PRIMARY);
+count(*)
+0
+SELECT count(*) FROM t2 FORCE INDEX (b);
+count(*)
+0
+SELECT count(*) FROM t2 FORCE INDEX (c);
+count(*)
+0
+SELECT count(*) FROM t2 FORCE INDEX (PRIMARY);
+count(*)
+0
+SELECT count(*) FROM t2 FORCE INDEX (b);
+count(*)
+0
+SELECT count(*) FROM t2 FORCE INDEX (c);
+count(*)
+0
+SET rocksdb_bulk_load=0;
+SELECT * FROM t2 FORCE INDEX (PRIMARY);
+a b c
+-19 21 21
+-17 19 19
+-15 17 17
+-13 15 15
+-11 13 13
+-9 11 11
+-7 9 9
+-5 7 7
+-3 5 5
+-1 3 3
+2 0 0
+4 -2 -2
+6 -4 -4
+8 -6 -6
+10 -8 -8
+12 -10 -10
+14 -12 -12
+16 -14 -14
+18 -16 -16
+20 -18 -18
+SELECT b FROM t2 FORCE INDEX (b);
+b
+-18
+-16
+-14
+-12
+-10
+-8
+-6
+-4
+-2
+0
+3
+5
+7
+9
+11
+13
+15
+17
+19
+21
+SELECT c FROM t2 FORCE INDEX (c);
+c
+-18
+-16
+-14
+-12
+-10
+-8
+-6
+-4
+-2
+0
+3
+5
+7
+9
+11
+13
+15
+17
+19
+21
+Checksums should match
+CHECKSUM TABLE t3;
+Table Checksum
+test.t3 1495594118
+CHECKSUM TABLE t2;
+Table Checksum
+test.t2 1495594118
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+DROP TABLE t4;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/cardinality.result b/storage/rocksdb/mysql-test/rocksdb/r/cardinality.result
index 4b201d523d9..d037c636a16 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/cardinality.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/cardinality.result
@@ -82,4 +82,19 @@ t1 1 t1_5 2 c1 A 100000 NULL NULL YES LSMTREE
SELECT table_name, table_rows FROM information_schema.tables WHERE table_schema = DATABASE();
table_name table_rows
t1 100000
-drop table t1;
+CREATE TABLE t2 (a INT, b INT, c INT, d INT, e INT, f INT, g INT,
+PRIMARY KEY (a), KEY (c, b, a, d, e, f, g))
+ENGINE=ROCKSDB;
+SET GLOBAL rocksdb_force_flush_memtable_now = 1;
+ANALYZE TABLE t2;
+Table Op Msg_type Msg_text
+test.t2 analyze status OK
+cardinality of the columns after 'a' must be equal to the cardinality of column 'a'
+SELECT CARDINALITY INTO @c FROM information_schema.statistics WHERE TABLE_NAME='t2' AND INDEX_NAME='c' AND COLUMN_NAME='a';
+SELECT COLUMN_NAME, CARDINALITY = @c FROM information_schema.statistics WHERE TABLE_NAME='t2' AND INDEX_NAME='c' AND SEQ_IN_INDEX > 3;
+COLUMN_NAME CARDINALITY = @c
+d 1
+e 1
+f 1
+g 1
+drop table t1, t2;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/collation.result b/storage/rocksdb/mysql-test/rocksdb/r/collation.result
index e372cbe2109..10e0d9b0002 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/collation.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/collation.result
@@ -1,6 +1,7 @@
-SET @start_global_value = @@global.ROCKSDB_STRICT_COLLATION_EXCEPTIONS;
-DROP TABLE IF EXISTS t1;
+call mtr.add_suppression("Invalid pattern");
CREATE TABLE t1 (id INT primary key, value varchar(50), value2 varbinary(50), value3 text) engine=rocksdb charset utf8;
+ALTER TABLE t1 ADD INDEX (value);
+ERROR HY000: Unsupported collation on string indexed column test.t1.value Use binary collation (binary, latin1_bin, utf8_bin).
DROP TABLE t1;
CREATE TABLE t1 (id INT primary key, value varchar(50), value2 varbinary(50), value3 text, index(value)) engine=rocksdb charset utf8;
ERROR HY000: Unsupported collation on string indexed column test.t1.value Use binary collation (latin1_bin, binary, utf8_bin).
@@ -13,6 +14,7 @@ SET GLOBAL rocksdb_strict_collation_check=1;
CREATE TABLE t1 (id INT primary key, value varchar(50), value2 varbinary(50), value3 text, index(value2)) engine=rocksdb charset utf8;
DROP TABLE t1;
CREATE TABLE t1 (id varchar(20), value varchar(50), value2 varchar(50), value3 text, primary key (id), index(value, value2)) engine=rocksdb charset latin1 collate latin1_bin;
+ALTER TABLE t1 collate=latin1_general_ci;
DROP TABLE t1;
CREATE TABLE t1 (id varchar(20), value varchar(50), value2 varchar(50), value3 text, primary key (id), index(value, value2)) engine=rocksdb charset utf8 collate utf8_bin;
DROP TABLE t1;
@@ -127,4 +129,16 @@ CREATE TABLE abcd (id INT PRIMARY KEY, value varchar(50), index(value)) engine=r
ERROR HY000: Unsupported collation on string indexed column test.abcd.value Use binary collation (latin1_bin, binary, utf8_bin).
DROP TABLE abc;
SET GLOBAL rocksdb_strict_collation_exceptions=null;
-SET GLOBAL rocksdb_strict_collation_exceptions=@start_global_value;
+SET GLOBAL rocksdb_strict_collation_check=1;
+CREATE TABLE t1 (id INT primary key, value varchar(50), value2 varbinary(50), value3 text, index(value)) engine=rocksdb charset utf8;
+Warnings:
+Warning 1210 Unsupported collation on string indexed column test.t1.value Use binary collation (binary, latin1_bin, utf8_bin).
+DROP TABLE t1;
+CREATE TABLE t1 (id INT primary key, value varchar(50), value2 varbinary(50), value3 text) engine=rocksdb charset utf8;
+ALTER TABLE t1 ADD INDEX (value);
+Warnings:
+Warning 1210 Unsupported collation on string indexed column test.t1.value Use binary collation (binary, latin1_bin, utf8_bin).
+DROP TABLE t1;
+CREATE TABLE t1 (id varchar(20), value varchar(50), value2 varchar(50), value3 text, primary key (id), index(value, value2)) engine=rocksdb charset latin1 collate latin1_bin;
+ALTER TABLE t1 collate=latin1_general_ci;
+DROP TABLE t1;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/com_rpc_tx.result b/storage/rocksdb/mysql-test/rocksdb/r/com_rpc_tx.result
new file mode 100644
index 00000000000..789ce12e900
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/r/com_rpc_tx.result
@@ -0,0 +1,21 @@
+CREATE DATABASE db_rpc;
+USE db_rpc;
+CREATE TABLE t1(pk INT PRIMARY KEY) ENGINE=rocksdb;
+SET GLOBAL rocksdb_enable_2pc=1;
+SET autocommit = 0;
+SET autocommit = 0;
+BEGIN;
+BEGIN;
+SELECT * from t1;
+pk
+SELECT * from t1;
+pk
+INSERT INTO t1 VALUES(1);
+INSERT INTO t1 VALUES(2);
+COMMIT;
+COMMIT;
+SELECT * from db_rpc.t1;
+pk
+1
+2
+DROP DATABASE db_rpc;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/create_no_primary_key_table.result b/storage/rocksdb/mysql-test/rocksdb/r/create_no_primary_key_table.result
new file mode 100644
index 00000000000..e5aeb57ebdf
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/r/create_no_primary_key_table.result
@@ -0,0 +1,38 @@
+USE mysql;
+CREATE TABLE mysql_table (a INT) ENGINE=ROCKSDB;
+CREATE TABLE test.mysql_table (a INT) ENGINE=ROCKSDB;
+ERROR HY000: Table without primary key cannot be created outside mysql schema.
+USE test;
+CREATE TABLE mysql_table (a INT) ENGINE=ROCKSDB;
+ERROR HY000: Table without primary key cannot be created outside mysql schema.
+CREATE TABLE IF NOT EXISTS mysql_table_2 (a INT) ENGINE=ROCKSDB;
+ERROR HY000: Table without primary key cannot be created outside mysql schema.
+CREATE TABLE mysql_table_no_cols ENGINE=ROCKSDB;
+ERROR HY000: Table without primary key cannot be created outside mysql schema.
+CREATE TABLE mysql.mysql_table_2 (a INT) ENGINE=ROCKSDB;
+CREATE TABLE mysql_primkey (a INT PRIMARY KEY, b INT, c INT, d INT, INDEX (c)) ENGINE=ROCKSDB;
+ALTER TABLE mysql_primkey DROP b, DROP a, ADD (f INT PRIMARY KEY);
+ALTER TABLE mysql_primkey DROP PRIMARY KEY;
+ERROR HY000: Table without primary key cannot be created outside mysql schema.
+CREATE TABLE mysql_primkey2 (a INT PRIMARY KEY, b INT, c INT) ENGINE=ROCKSDB;
+ALTER TABLE mysql_primkey2 DROP b;
+ALTER TABLE mysql_primkey2 ADD (b INT);
+ALTER TABLE mysql_primkey2 DROP c, DROP A;
+ERROR HY000: Table without primary key cannot be created outside mysql schema.
+CREATE TABLE mysql_primkey3 (a INT PRIMARY KEY, b INT, c INT, INDEX indexonb (b), INDEX indexonc (c)) ENGINE=ROCKSDB;
+ALTER TABLE mysql_primkey3 DROP INDEX indexonb;
+ALTER TABLE mysql_primkey3 DROP c;
+ALTER TABLE mysql_primkey3 DROP PRIMARY KEY, ADD PRIMARY KEY(b);
+CREATE TABLE mysql_primkey4(a INT, b INT, PRIMARY KEY(a), INDEX si (a, b)) ENGINE=ROCKSDB;
+DROP INDEX si ON mysql_primkey4;
+DROP INDEX `PRIMARY` ON mysql_primkey4;
+ERROR HY000: Table without primary key cannot be created outside mysql schema.
+ALTER TABLE mysql.mysql_table ADD PRIMARY KEY (a);
+ALTER TABLE mysql.mysql_table DROP PRIMARY KEY;
+DROP TABLE mysql_primkey;
+DROP TABLE mysql_primkey2;
+DROP TABLE mysql_primkey3;
+DROP TABLE mysql_primkey4;
+USE mysql;
+DROP TABLE mysql_table;
+DROP TABLE mysql_table_2;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/ddl_high_priority.result b/storage/rocksdb/mysql-test/rocksdb/r/ddl_high_priority.result
index 39130475349..50733f81598 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/ddl_high_priority.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/ddl_high_priority.result
@@ -45,7 +45,7 @@ set high_priority_ddl = 1;
select @@high_priority_ddl;
@@high_priority_ddl
1
-lock tables t1 write;
+rename table t1 to t2;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction: Timeout on table metadata: test.t1
alter table t1 modify i bigint;;
set high_priority_ddl = 0;
@@ -98,7 +98,7 @@ set high_priority_ddl = 1;
select @@high_priority_ddl;
@@high_priority_ddl
1
-lock tables t1 write;
+rename table t1 to t2;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction: Timeout on table metadata: test.t1
alter table t1 rename t1_new;;
set high_priority_ddl = 0;
@@ -152,7 +152,7 @@ set high_priority_ddl = 1;
select @@high_priority_ddl;
@@high_priority_ddl
1
-lock tables t1 write;
+rename table t1 to t2;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction: Timeout on table metadata: test.t1
drop table t1;;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction: Timeout on table metadata: test.t1
@@ -202,7 +202,7 @@ set high_priority_ddl = 1;
select @@high_priority_ddl;
@@high_priority_ddl
1
-lock tables t1 write;
+rename table t1 to t2;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction: Timeout on table metadata: test.t1
drop table t1;;
set high_priority_ddl = 0;
@@ -251,7 +251,7 @@ set high_priority_ddl = 1;
select @@high_priority_ddl;
@@high_priority_ddl
1
-lock tables t1 write;
+rename table t1 to t2;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction: Timeout on table metadata: test.t1
alter table t1 modify i bigint;;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction: Timeout on table metadata: test.t1
@@ -302,7 +302,7 @@ set high_priority_ddl = 1;
select @@high_priority_ddl;
@@high_priority_ddl
1
-lock tables t1 write;
+rename table t1 to t2;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction: Timeout on table metadata: test.t1
create index idx1 on t1 (i);;
set high_priority_ddl = 0;
@@ -342,7 +342,7 @@ set high_priority_ddl = 1;
select @@high_priority_ddl;
@@high_priority_ddl
1
-lock tables t1 write;
+rename table t1 to t2;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction: Timeout on table metadata: test.t1
drop index idx1 on t1;;
set high_priority_ddl = 0;
@@ -390,7 +390,7 @@ set high_priority_ddl = 1;
select @@high_priority_ddl;
@@high_priority_ddl
1
-lock tables t1 write;
+rename table t1 to t2;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction: Timeout on table metadata: test.t1
truncate t1;;
set high_priority_ddl = 0;
@@ -438,7 +438,7 @@ set high_priority_ddl = 1;
select @@high_priority_ddl;
@@high_priority_ddl
1
-lock tables t1 write;
+rename table t1 to t2;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction: Timeout on table metadata: test.t1
create trigger ins_sum before insert on t1 for each row set @sum = @sum + new.i;;
set high_priority_ddl = 0;
@@ -478,7 +478,7 @@ set high_priority_ddl = 1;
select @@high_priority_ddl;
@@high_priority_ddl
1
-lock tables t1 write;
+rename table t1 to t2;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction: Timeout on table metadata: test.t1
drop trigger ins_sum;;
set high_priority_ddl = 0;
@@ -528,7 +528,7 @@ set high_priority_ddl = 1;
select @@high_priority_ddl;
@@high_priority_ddl
1
-lock tables t1 write;
+rename table t1 to t2;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction: Timeout on table metadata: test.t1
optimize table t1;;
Table Op Msg_type Msg_text
@@ -538,6 +538,55 @@ connection: default (for show processlist)
show processlist;
Id User Host db Command Time State Info Rows examined Rows sent Tid Srv_Id
<Id> root <Host> test <Command> <Time> <State> <Info> <RExam> <RSent> <TID> 0
+
+## Test parameters:
+## use_sys_var = 1;
+## con_block = con1
+## con_kill = default
+## cmd = lock tables t1 write;
+## high_priority_cmd = optimize high_priority table t1;
+## should_kill = 1
+## recreate_table = 1
+## throw_error = 1
+
+drop table if exists t1;
+create table t1 (i int);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `i` int(11) DEFAULT NULL
+) ENGINE=ROCKSDB DEFAULT CHARSET=latin1
+insert into t1 values (1), (2), (3);
+connection: con1
+lock tables t1 read;;
+connection: default
+set lock_wait_timeout = 0.02;
+set high_priority_lock_wait_timeout = 0.02;
+describe t1;
+Field Type Null Key Default Extra
+i int(11) YES NULL
+connection: default (for show processlist)
+# both con1 and default exist
+show processlist;
+Id User Host db Command Time State Info Rows examined Rows sent Tid Srv_Id
+<Id> root <Host> test <Command> <Time> <State> <Info> <RExam> <RSent> <TID> 0
+<Id> test_user1 <Host> test <Command> <Time> <State> <Info> <RExam> <RSent> <TID> 0
+connection: default
+lock tables t1 write;;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction: Timeout on table metadata: test.t1
+set high_priority_ddl = 1;
+select @@high_priority_ddl;
+@@high_priority_ddl
+1
+rename table t1 to t2;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction: Timeout on table metadata: test.t1
+lock tables t1 write;;
+set high_priority_ddl = 0;
+connection: default (for show processlist)
+show processlist;
+Id User Host db Command Time State Info Rows examined Rows sent Tid Srv_Id
+<Id> root <Host> test <Command> <Time> <State> <Info> <RExam> <RSent> <TID> 0
+unlock tables;
drop user test_user1@localhost;
drop user test_user2@localhost;
drop table if exists t1;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/deadlock_tracking.result b/storage/rocksdb/mysql-test/rocksdb/r/deadlock_tracking.result
index 1e7509172cb..fffae916c12 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/deadlock_tracking.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/deadlock_tracking.result
@@ -53,6 +53,7 @@ LIST OF SNAPSHOTS FOR EACH SESSION:
*** DEADLOCK PATH
=========================================
+TSTAMP
TXN_ID
COLUMN FAMILY NAME: default
KEY
@@ -60,6 +61,7 @@ LOCK TYPE: EXCLUSIVE
INDEX NAME: PRIMARY
TABLE NAME: test.t
---------------WAITING FOR---------------
+TSTAMP
TXN_ID
COLUMN FAMILY NAME: default
KEY
@@ -102,6 +104,7 @@ LIST OF SNAPSHOTS FOR EACH SESSION:
*** DEADLOCK PATH
=========================================
+TSTAMP
TXN_ID
COLUMN FAMILY NAME: default
KEY
@@ -109,6 +112,7 @@ LOCK TYPE: EXCLUSIVE
INDEX NAME: PRIMARY
TABLE NAME: test.t
---------------WAITING FOR---------------
+TSTAMP
TXN_ID
COLUMN FAMILY NAME: default
KEY
@@ -120,6 +124,7 @@ TABLE NAME: test.t
*** DEADLOCK PATH
=========================================
+TSTAMP
TXN_ID
COLUMN FAMILY NAME: default
KEY
@@ -127,6 +132,7 @@ LOCK TYPE: EXCLUSIVE
INDEX NAME: PRIMARY
TABLE NAME: test.t
---------------WAITING FOR---------------
+TSTAMP
TXN_ID
COLUMN FAMILY NAME: default
KEY
@@ -170,6 +176,7 @@ LIST OF SNAPSHOTS FOR EACH SESSION:
*** DEADLOCK PATH
=========================================
+TSTAMP
TXN_ID
COLUMN FAMILY NAME: default
KEY
@@ -177,6 +184,7 @@ LOCK TYPE: EXCLUSIVE
INDEX NAME: PRIMARY
TABLE NAME: test.t
---------------WAITING FOR---------------
+TSTAMP
TXN_ID
COLUMN FAMILY NAME: default
KEY
@@ -188,6 +196,7 @@ TABLE NAME: test.t
*** DEADLOCK PATH
=========================================
+TSTAMP
TXN_ID
COLUMN FAMILY NAME: default
KEY
@@ -195,6 +204,7 @@ LOCK TYPE: EXCLUSIVE
INDEX NAME: PRIMARY
TABLE NAME: test.t
---------------WAITING FOR---------------
+TSTAMP
TXN_ID
COLUMN FAMILY NAME: default
KEY
@@ -206,6 +216,7 @@ TABLE NAME: test.t
*** DEADLOCK PATH
=========================================
+TSTAMP
TXN_ID
COLUMN FAMILY NAME: default
KEY
@@ -213,6 +224,7 @@ LOCK TYPE: EXCLUSIVE
INDEX NAME: PRIMARY
TABLE NAME: test.t
---------------WAITING FOR---------------
+TSTAMP
TXN_ID
COLUMN FAMILY NAME: default
KEY
@@ -240,6 +252,7 @@ LIST OF SNAPSHOTS FOR EACH SESSION:
*** DEADLOCK PATH
=========================================
+TSTAMP
TXN_ID
COLUMN FAMILY NAME: default
KEY
@@ -247,6 +260,7 @@ LOCK TYPE: EXCLUSIVE
INDEX NAME: PRIMARY
TABLE NAME: test.t
---------------WAITING FOR---------------
+TSTAMP
TXN_ID
COLUMN FAMILY NAME: default
KEY
@@ -352,6 +366,7 @@ LIST OF SNAPSHOTS FOR EACH SESSION:
*** DEADLOCK PATH
=========================================
+TSTAMP
TXN_ID
COLUMN FAMILY NAME: default
KEY
@@ -359,6 +374,7 @@ LOCK TYPE: EXCLUSIVE
INDEX NAME: PRIMARY
TABLE NAME: test.t
---------------WAITING FOR---------------
+TSTAMP
TXN_ID
COLUMN FAMILY NAME: default
KEY
@@ -373,6 +389,25 @@ TABLE NAME: test.t
END OF ROCKSDB TRANSACTION MONITOR OUTPUT
=========================================
+Deadlock #6
+create table t1 (id int primary key, value int) engine=rocksdb;
+insert into t1 values (1,1),(2,2),(3,3),(4,4),(5,5);
+begin;
+update t1 set value=value+100 where id=1;
+update t1 set value=value+100 where id=2;
+begin;
+update t1 set value=value+200 where id=3;
+update t1 set value=value+100 where id=3;
+update t1 set value=value+200 where id=1;
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+select * from t1;
+id value
+1 101
+2 102
+3 103
+4 4
+5 5
+drop table t1;
set global rocksdb_lock_wait_timeout = @prior_lock_wait_timeout;
set global rocksdb_deadlock_detect = @prior_deadlock_detect;
drop table t;
@@ -390,6 +425,27 @@ LIST OF SNAPSHOTS FOR EACH SESSION:
*** DEADLOCK PATH
=========================================
+TSTAMP
+TXN_ID
+COLUMN FAMILY NAME: default
+KEY
+LOCK TYPE: EXCLUSIVE
+INDEX NAME: NOT FOUND; IDX_ID
+TABLE NAME: NOT FOUND; IDX_ID
+---------------WAITING FOR---------------
+TSTAMP
+TXN_ID
+COLUMN FAMILY NAME: default
+KEY
+LOCK TYPE: EXCLUSIVE
+INDEX NAME: NOT FOUND; IDX_ID
+TABLE NAME: NOT FOUND; IDX_ID
+
+--------TXN_ID GOT DEADLOCK---------
+
+*** DEADLOCK PATH
+=========================================
+TSTAMP
TXN_ID
COLUMN FAMILY NAME: default
KEY
@@ -397,6 +453,7 @@ LOCK TYPE: EXCLUSIVE
INDEX NAME: NOT FOUND; IDX_ID
TABLE NAME: NOT FOUND; IDX_ID
---------------WAITING FOR---------------
+TSTAMP
TXN_ID
COLUMN FAMILY NAME: default
KEY
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/drop_table.result b/storage/rocksdb/mysql-test/rocksdb/r/drop_table.result
index dba49d8ff41..4d20242f43e 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/drop_table.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/drop_table.result
@@ -45,6 +45,25 @@ DELETE FROM t4;
drop table t3;
DELETE FROM t1;
DELETE FROM t4;
+SET GLOBAL rocksdb_max_manual_compactions = 2;
+SET GLOBAL rocksdb_debug_manual_compaction_delay = 3600;
+connect con1, localhost, root,,;
+connect con2, localhost, root,,;
+connect con3, localhost, root,,;
+connection con1;
+SET GLOBAL rocksdb_compact_cf='cf1';
+connection con2;
+SET GLOBAL rocksdb_compact_cf='rev:cf2';
+connection default;
+select * from information_schema.global_status where variable_name='rocksdb_manual_compactions_running';
+VARIABLE_NAME VARIABLE_VALUE
+ROCKSDB_MANUAL_COMPACTIONS_RUNNING 1
+connection con3;
+SET GLOBAL rocksdb_compact_cf='cf1';
+ERROR HY000: Internal error: Can't schedule more manual compactions. Increase rocksdb_max_manual_compactions or stop issuing more manual compactions.
+SET GLOBAL rocksdb_compact_cf='rev:cf2';
+ERROR HY000: Internal error: Can't schedule more manual compactions. Increase rocksdb_max_manual_compactions or stop issuing more manual compactions.
+connection default;
drop table t4;
CREATE TABLE t5 (
a int not null,
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/explicit_snapshot.result b/storage/rocksdb/mysql-test/rocksdb/r/explicit_snapshot.result
new file mode 100644
index 00000000000..14f5ef65c59
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/r/explicit_snapshot.result
@@ -0,0 +1,265 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE T1 (a INT PRIMARY KEY AUTO_INCREMENT) ENGINE=ROCKSDB;
+INSERT INTO T1 VALUES();
+"con1: Creating explict snapshot"
+SELECT * FROM T1;
+a
+1
+"con2: Inserting a row"
+INSERT INTO T1 VALUES();
+SELECT * FROM T1;
+a
+1
+2
+"con2: Attaching snapshot id 1"
+ATTACH EXPLICIT ROCKSDB SNAPSHOT 1;
+"con2: New row should not be visible"
+SELECT * FROM T1;
+a
+1
+"con2: Releasing snapshot"
+RELEASE EXPLICIT ROCKSDB SNAPSHOT;
+"con2: New row should be visible"
+SELECT * FROM T1;
+a
+1
+2
+"con1: New row should not be visible"
+SELECT * FROM T1;
+a
+1
+"con1: Releasing snapshot"
+RELEASE EXPLICIT ROCKSDB SNAPSHOT;
+"con1: New row should be visible"
+SELECT * FROM T1;
+a
+1
+2
+"con1: Starting shared snapshot"
+SELECT * FROM T1;
+a
+1
+2
+"con2: Inserting a row"
+INSERT INTO T1 VALUES();
+SELECT * FROM T1;
+a
+1
+2
+3
+"con2: Starting existing snapshot"
+START TRANSACTION WITH EXISTING ROCKSDB SNAPSHOT 2;
+"con2: New row should not be visible"
+SELECT * FROM T1;
+a
+1
+2
+COMMIT;
+"con2: New row should be visible"
+SELECT * FROM T1;
+a
+1
+2
+3
+COMMIT;
+"con1: New row should be visible"
+SELECT * FROM T1;
+a
+1
+2
+3
+"con1: Creating explict snapshot"
+"con2: Trying to insert row"
+INSERT INTO T1 VALUES();
+ERROR HY000: Can't execute updates when an explicit snapshot is associated with the connection using CREATE|ATTACH EXPLICIT [ENGINE] SNAPSHOT
+"con2: Attaching existing snapshot"
+ATTACH EXPLICIT ROCKSDB SNAPSHOT 3;
+"con2: Trying to insert row"
+INSERT INTO T1 VALUES();
+ERROR HY000: Can't execute updates when an explicit snapshot is associated with the connection using CREATE|ATTACH EXPLICIT [ENGINE] SNAPSHOT
+RELEASE EXPLICIT ROCKSDB SNAPSHOT;
+RELEASE EXPLICIT ROCKSDB SNAPSHOT;
+"con1: Starting shared snapshot"
+"con1: Trying to insert row"
+INSERT INTO T1 VALUES();
+ERROR HY000: Can't execute updates when you started a transaction with START TRANSACTION WITH CONSISTENT|SHARED|EXISTING [ROCKSDB] SNAPSHOT.
+"con2: Starting existing snapshot"
+START TRANSACTION WITH EXISTING ROCKSDB SNAPSHOT 4;
+"con2: Trying to insert row"
+INSERT INTO T1 VALUES();
+ERROR HY000: Can't execute updates when you started a transaction with START TRANSACTION WITH CONSISTENT|SHARED|EXISTING [ROCKSDB] SNAPSHOT.
+COMMIT;
+COMMIT;
+"con1: Creating explicit snapshot"
+CREATE EXPLICIT ROCKSDB SNAPSHOT;
+SELECT * FROM T1;
+a
+1
+2
+3
+"con2: Inserting a row"
+INSERT INTO T1 VALUES();
+SELECT * FROM T1;
+a
+1
+2
+3
+4
+"con1: New row should not be seen"
+SELECT * FROM T1;
+a
+1
+2
+3
+"con1: Creating another explicit snapshot"
+CREATE EXPLICIT ROCKSDB SNAPSHOT;
+"con1: Now the new row should be seen"
+SELECT * FROM T1;
+a
+1
+2
+3
+4
+"con1: Starting transaction with consistent snapshot"
+START TRANSACTION WITH CONSISTENT ROCKSDB SNAPSHOT;
+SELECT * FROM T1;
+a
+1
+2
+3
+4
+"con2: Inserting a row"
+INSERT INTO T1 VALUES();
+SELECT * FROM T1;
+a
+1
+2
+3
+4
+5
+"con1: The new row should not be seen"
+SELECT * FROM T1;
+a
+1
+2
+3
+4
+"con1: Creating another explicit snapshot"
+CREATE EXPLICIT ROCKSDB SNAPSHOT;
+"con1: The new row should still not be seen"
+SELECT * FROM T1;
+a
+1
+2
+3
+4
+"con1: Committing trx"
+COMMIT;
+"con1: The new row should now be seen because of the new explicit snapshot created above"
+SELECT * FROM T1;
+a
+1
+2
+3
+4
+5
+"con1: Releasing explicit snapshot"
+RELEASE EXPLICIT ROCKSDB SNAPSHOT;
+"con1: Starting transaction with shared snapshot"
+START TRANSACTION WITH SHARED ROCKSDB SNAPSHOT;
+SELECT * FROM T1;
+a
+1
+2
+3
+4
+5
+"con2: Inserting a row"
+INSERT INTO T1 VALUES();
+SELECT * FROM T1;
+a
+1
+2
+3
+4
+5
+6
+"con1: The new row should not be seen"
+SELECT * FROM T1;
+a
+1
+2
+3
+4
+5
+"con1: Starting another transaction with shared snapshot"
+START TRANSACTION WITH SHARED ROCKSDB SNAPSHOT;
+"con1: The new row should now be seen"
+SELECT * FROM T1;
+a
+1
+2
+3
+4
+5
+6
+COMMIT;
+"con1: Creating explicit snapshot"
+CREATE EXPLICIT ROCKSDB SNAPSHOT;
+SELECT * FROM T1;
+a
+1
+2
+3
+4
+5
+6
+"con1: Releasing explicit snapshot"
+RELEASE EXPLICIT ROCKSDB SNAPSHOT;
+"con1: Releasing explicit snapshot again"
+RELEASE EXPLICIT ROCKSDB SNAPSHOT;
+ERROR HY000: Cannot process explicit snapshot
+"con1: Starting transaction with shared snapshot"
+START TRANSACTION WITH SHARED ROCKSDB SNAPSHOT;
+SELECT * FROM T1;
+a
+1
+2
+3
+4
+5
+6
+"con2: Inserting a row"
+INSERT INTO T1 VALUES();
+SELECT * FROM T1;
+a
+1
+2
+3
+4
+5
+6
+7
+"con1: Creating explicit snapshot"
+CREATE EXPLICIT ROCKSDB SNAPSHOT;
+SELECT * FROM T1;
+a
+1
+2
+3
+4
+5
+6
+"con1: Releasing explicit snapshot"
+RELEASE EXPLICIT ROCKSDB SNAPSHOT;
+"con1: The new row should not be seen"
+SELECT* FROM T1;
+a
+1
+2
+3
+4
+5
+6
+COMMIT;
+DROP TABLE T1;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/i_s_deadlock.result b/storage/rocksdb/mysql-test/rocksdb/r/i_s_deadlock.result
index 36db92095e9..3ec9294e3a1 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/i_s_deadlock.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/i_s_deadlock.result
@@ -14,6 +14,7 @@ show create table information_schema.rocksdb_deadlock;
Table Create Table
ROCKSDB_DEADLOCK CREATE TEMPORARY TABLE `ROCKSDB_DEADLOCK` (
`DEADLOCK_ID` bigint(8) NOT NULL DEFAULT 0,
+ `TIMESTAMP` bigint(8) NOT NULL DEFAULT 0,
`TRANSACTION_ID` bigint(8) NOT NULL DEFAULT 0,
`CF_NAME` varchar(193) NOT NULL DEFAULT '',
`WAITING_KEY` varchar(513) NOT NULL DEFAULT '',
@@ -25,7 +26,7 @@ ROCKSDB_DEADLOCK CREATE TEMPORARY TABLE `ROCKSDB_DEADLOCK` (
create table t (i int primary key) engine=rocksdb;
insert into t values (1), (2), (3);
select * from information_schema.rocksdb_deadlock;
-DEADLOCK_ID TRANSACTION_ID CF_NAME WAITING_KEY LOCK_TYPE INDEX_NAME TABLE_NAME ROLLED_BACK
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID CF_NAME WAITING_KEY LOCK_TYPE INDEX_NAME TABLE_NAME ROLLED_BACK
Deadlock #1
connection con1;
begin;
@@ -49,9 +50,9 @@ i
rollback;
connection default;
select * from information_schema.rocksdb_deadlock;
-DEADLOCK_ID TRANSACTION_ID CF_NAME WAITING_KEY LOCK_TYPE INDEX_NAME TABLE_NAME ROLLED_BACK
-DEADLOCK_ID TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 0
-DEADLOCK_ID TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 1
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID CF_NAME WAITING_KEY LOCK_TYPE INDEX_NAME TABLE_NAME ROLLED_BACK
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 0
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 1
Deadlock #2
connection con1;
begin;
@@ -75,11 +76,11 @@ i
rollback;
connection default;
select * from information_schema.rocksdb_deadlock;
-DEADLOCK_ID TRANSACTION_ID CF_NAME WAITING_KEY LOCK_TYPE INDEX_NAME TABLE_NAME ROLLED_BACK
-DEADLOCK_ID TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 0
-DEADLOCK_ID TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 1
-DEADLOCK_ID TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 0
-DEADLOCK_ID TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 1
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID CF_NAME WAITING_KEY LOCK_TYPE INDEX_NAME TABLE_NAME ROLLED_BACK
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 0
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 1
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 0
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 1
set global rocksdb_max_latest_deadlocks = 10;
Deadlock #3
connection con1;
@@ -104,18 +105,18 @@ i
rollback;
connection default;
select * from information_schema.rocksdb_deadlock;
-DEADLOCK_ID TRANSACTION_ID CF_NAME WAITING_KEY LOCK_TYPE INDEX_NAME TABLE_NAME ROLLED_BACK
-DEADLOCK_ID TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 0
-DEADLOCK_ID TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 1
-DEADLOCK_ID TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 0
-DEADLOCK_ID TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 1
-DEADLOCK_ID TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 0
-DEADLOCK_ID TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 1
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID CF_NAME WAITING_KEY LOCK_TYPE INDEX_NAME TABLE_NAME ROLLED_BACK
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 0
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 1
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 0
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 1
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 0
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 1
set global rocksdb_max_latest_deadlocks = 1;
select * from information_schema.rocksdb_deadlock;
-DEADLOCK_ID TRANSACTION_ID CF_NAME WAITING_KEY LOCK_TYPE INDEX_NAME TABLE_NAME ROLLED_BACK
-DEADLOCK_ID TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 0
-DEADLOCK_ID TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 1
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID CF_NAME WAITING_KEY LOCK_TYPE INDEX_NAME TABLE_NAME ROLLED_BACK
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 0
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 1
connection con3;
set rocksdb_deadlock_detect_depth = 2;
Deadlock #4
@@ -153,7 +154,7 @@ rollback;
connection default;
set global rocksdb_max_latest_deadlocks = 5;
select * from information_schema.rocksdb_deadlock;
-DEADLOCK_ID TRANSACTION_ID CF_NAME WAITING_KEY LOCK_TYPE INDEX_NAME TABLE_NAME ROLLED_BACK
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID CF_NAME WAITING_KEY LOCK_TYPE INDEX_NAME TABLE_NAME ROLLED_BACK
Deadlock #5
connection con1;
begin;
@@ -195,9 +196,9 @@ connection con3;
rollback;
connection default;
select * from information_schema.rocksdb_deadlock;
-DEADLOCK_ID TRANSACTION_ID CF_NAME WAITING_KEY LOCK_TYPE INDEX_NAME TABLE_NAME ROLLED_BACK
-DEADLOCK_ID TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 0
-DEADLOCK_ID TRANSACTION_ID default WAITING_KEY SHARED PRIMARY test.t 1
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID CF_NAME WAITING_KEY LOCK_TYPE INDEX_NAME TABLE_NAME ROLLED_BACK
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 0
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID default WAITING_KEY SHARED PRIMARY test.t 1
disconnect con1;
disconnect con2;
disconnect con3;
@@ -205,11 +206,11 @@ set global rocksdb_lock_wait_timeout = @prior_lock_wait_timeout;
set global rocksdb_deadlock_detect = @prior_deadlock_detect;
drop table t;
select * from information_schema.rocksdb_deadlock;
-DEADLOCK_ID TRANSACTION_ID CF_NAME WAITING_KEY LOCK_TYPE INDEX_NAME TABLE_NAME ROLLED_BACK
-DEADLOCK_ID TRANSACTION_ID default WAITING_KEY EXCLUSIVE INDEX_NAME TABLE_NAME 0
-DEADLOCK_ID TRANSACTION_ID default WAITING_KEY SHARED INDEX_NAME TABLE_NAME 1
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID CF_NAME WAITING_KEY LOCK_TYPE INDEX_NAME TABLE_NAME ROLLED_BACK
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID default WAITING_KEY EXCLUSIVE INDEX_NAME TABLE_NAME 0
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID default WAITING_KEY SHARED INDEX_NAME TABLE_NAME 1
set global rocksdb_max_latest_deadlocks = 0;
# Clears deadlock buffer of any existent deadlocks.
set global rocksdb_max_latest_deadlocks = @prior_max_latest_deadlocks;
select * from information_schema.rocksdb_deadlock;
-DEADLOCK_ID TRANSACTION_ID CF_NAME WAITING_KEY LOCK_TYPE INDEX_NAME TABLE_NAME ROLLED_BACK
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID CF_NAME WAITING_KEY LOCK_TYPE INDEX_NAME TABLE_NAME ROLLED_BACK
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/index_file_map.result b/storage/rocksdb/mysql-test/rocksdb/r/index_file_map.result
index 2c7d37c053f..ad007d71e15 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/index_file_map.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/index_file_map.result
@@ -24,5 +24,8 @@ WHERE INDEX_NUMBER =
WHERE TABLE_NAME = 't2' AND INDEX_NAME = "PRIMARY");
COLUMN_FAMILY INDEX_NUMBER SST_NAME NUM_ROWS DATA_SIZE ENTRY_DELETES ENTRY_SINGLEDELETES ENTRY_MERGES ENTRY_OTHERS DISTINCT_KEYS_PREFIX
# # SSTNAME 4 # # # # # 4
+select count(*) > 0 from information_schema.rocksdb_sst_props;
+count(*) > 0
+1
DROP TABLE t1;
DROP TABLE t2;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/index_merge_rocksdb2.result b/storage/rocksdb/mysql-test/rocksdb/r/index_merge_rocksdb2.result
index 4370715925a..e0248737381 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/index_merge_rocksdb2.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/index_merge_rocksdb2.result
@@ -30,7 +30,7 @@ id select_type table type possible_keys key key_len ref rows Extra
explain
select * from t0 where key1 < 3 or key2 > 1020;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t0 index_merge i1,i2 i1,i2 4,4 NULL 2 Using sort_union(i1,i2); Using where
+1 SIMPLE t0 index_merge i1,i2 i1,i2 4,4 NULL 4 Using sort_union(i1,i2); Using where
select * from t0 where key1 < 3 or key2 > 1020;
key1 key2 key3 key4 key5 key6 key7 key8
1 1 1 1 1 1 1 1023
@@ -68,7 +68,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t0 index_merge i1,i2 i1,i2 4,4 NULL # Using sort_union(i1,i2); Using where
explain select * from t0 where (key1 > 1 or key2 > 2);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t0 ALL i1,i2 NULL NULL NULL # Using where
+1 SIMPLE t0 index_merge i1,i2 i1,i2 4,4 NULL # Using sort_union(i1,i2); Using where
explain select * from t0 force index (i1,i2) where (key1 > 1 or key2 > 2);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t0 index_merge i1,i2 i1,i2 4,4 NULL # Using sort_union(i1,i2); Using where
@@ -124,13 +124,13 @@ id select_type table type possible_keys key key_len ref rows Extra
explain select * from t0 where
(key1 < 3 or key2 < 3) and (key3 < 1000);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t0 index_merge i1,i2,i3 i1,i2 4,4 NULL # Using sort_union(i1,i2); Using where
+1 SIMPLE t0 range i1,i2,i3 i3 4 NULL # Using index condition; Using where
explain select * from t0 where
((key1 < 3 or key2 < 3) and (key2 <4 or key3 < 3))
or
key2 > 4;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t0 ALL i1,i2,i3 NULL NULL NULL # Using where
+1 SIMPLE t0 index_merge i1,i2,i3 i1,i2 4,4 NULL # Using sort_union(i1,i2); Using where
explain select * from t0 where
((key1 < 4 or key2 < 4) and (key2 <4 or key3 < 3))
or
@@ -175,7 +175,7 @@ explain select * from t0 where
or
((key3 >5 or key5 < 2) and (key5 < 5 or key6 < 6));
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t0 ALL i1,i2,i3,i5,i6 NULL NULL NULL # Using where
+1 SIMPLE t0 index_merge i1,i2,i3,i5,i6 i3,i5 4,4 NULL # Using sort_union(i3,i5); Using where
explain select * from t0 force index(i1, i2, i3, i4, i5, i6 ) where
((key3 <3 or key5 < 4) and (key1 < 3 or key2 < 3))
or
@@ -235,13 +235,13 @@ key1a key1b key2 key2_1 key2_2 key3
4 4 0 4 4 4
explain select * from t4 where key1a = 3 or key1b = 4;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t4 index_merge i1a,i1b i1a,i1b 4,4 NULL 2 Using sort_union(i1a,i1b); Using where
+1 SIMPLE t4 index_merge i1a,i1b i1a,i1b 4,4 NULL 4 Using sort_union(i1a,i1b); Using where
explain select * from t4 where key2 = 1 and (key2_1 = 1 or key3 = 5);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t4 ref i2_1,i2_2 i2_1 4 const 1 Using where
+1 SIMPLE t4 ref i2_1,i2_2 i2_1 4 const 2 Using where
explain select * from t4 where key2 = 1 and (key2_1 = 1 or key2_2 = 5);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t4 ref i2_1,i2_2 i2_1 4 const 1 Using where
+1 SIMPLE t4 ref i2_1,i2_2 i2_1 4 const 2 Using where
explain select * from t4 where key2_1 = 1 or key2_2 = 5;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL NULL NULL NULL NULL # Using where
@@ -266,7 +266,7 @@ explain
select * from t0,t1 where (t0.key1=t1.key1) and
(t0.key1=3 or t0.key2<4) and t1.key1=2;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t0 ref i1,i2 i1 4 const 1 Using where
+1 SIMPLE t0 ref i1,i2 i1 4 const 2 Using where
1 SIMPLE t1 ref i1 i1 4 const 1
explain select * from t0,t1 where t0.key1 = 5 and
(t1.key1 = t0.key1 or t1.key8 = t0.key1);
@@ -281,8 +281,8 @@ id select_type table type possible_keys key key_len ref rows Extra
explain select * from t1 where key1=3 or key2=4
union select * from t1 where key1<4 or key3=5;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index_merge i1,i2 i1,i2 4,4 NULL 2 Using union(i1,i2); Using where
-2 UNION t1 index_merge i1,i3 i1,i3 4,4 NULL 2 Using sort_union(i1,i3); Using where
+1 PRIMARY t1 index_merge i1,i2 i1,i2 4,4 NULL 4 Using union(i1,i2); Using where
+2 UNION t1 index_merge i1,i3 i1,i3 4,4 NULL 4 Using sort_union(i1,i3); Using where
NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL
explain select * from (select * from t1 where key1 = 3 or key2 =3) as Z where key8 >5;
id select_type table type possible_keys key key_len ref rows Extra
@@ -299,7 +299,7 @@ key1=1 or key2=2 or key3=3 or key4=4 or
key5=5 or key6=6 or key7=7 or key8=8 or
key9=9 or keyA=10 or keyB=11 or keyC=12;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t3 index_merge i1,i2,i3,i4,i5,i6,i7,i8,i9,iA,iB,iC i1,i2,i3,i4,i5,i6,i7,i8,i9,iA,iB,iC 4,4,4,4,4,4,4,4,4,4,4,4 NULL 12 Using union(i1,i2,i3,i4,i5,i6,i7,i8,i9,iA,iB,iC); Using where
+1 SIMPLE t3 index_merge i1,i2,i3,i4,i5,i6,i7,i8,i9,iA,iB,iC i1,i2,i3,i4,i5,i6,i7,i8,i9,iA,iB,iC 4,4,4,4,4,4,4,4,4,4,4,4 NULL 24 Using union(i1,i2,i3,i4,i5,i6,i7,i8,i9,iA,iB,iC); Using where
select * from t3 where
key1=1 or key2=2 or key3=3 or key4=4 or
key5=5 or key6=6 or key7=7 or key8=8 or
@@ -319,7 +319,7 @@ key1 key2 key3 key4 key5 key6 key7 key8 key9 keyA keyB keyC
1016 1016 1016 1016 1016 1016 1016 8 1016 1016 1016 1016
explain select * from t0 where key1 < 3 or key2 < 4;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t0 index_merge i1,i2 i1,i2 4,4 NULL 2 Using sort_union(i1,i2); Using where
+1 SIMPLE t0 index_merge i1,i2 i1,i2 4,4 NULL 4 Using sort_union(i1,i2); Using where
select * from t0 where key1 < 3 or key2 < 4;
key1 key2 key3 key4 key5 key6 key7 key8
1 1 1 1 1 1 1 1023
@@ -696,7 +696,7 @@ count(a)
4
expla_or_bin select count(a_or_b) from t2 where a_or_b='AAAAAAAA' a_or_bnd a_or_b='AAAAAAAA';
id select_type ta_or_ba_or_ble type possia_or_ble_keys key key_len ref rows Extra_or_b
-1 SIMPLE t2 ref a_or_b,a_or_b a_or_b 6 const 1 Using where
+1 SIMPLE t2 ref a_or_b,a_or_b a_or_b 6 const 2 Using where
select count(a) from t2 where a='AAAAAAAA' and b='AAAAAAAA';
count(a)
4
@@ -706,7 +706,7 @@ count(a)
insert into t2 values ('ab', 'ab', 'uh', 'oh');
explain select a from t2 where a='ab';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ref a a 6 const 1 Using where
+1 SIMPLE t2 ref a a 6 const 2 Using where
drop table t2;
CREATE TABLE t1(c1 INT, c2 INT DEFAULT 0, c3 CHAR(255) DEFAULT '',
KEY(c1), KEY(c2), KEY(c3));
@@ -732,7 +732,7 @@ INDEX i2(key2)
);
explain select * from t1 where key1 < 5 or key2 > 197;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 index_merge i1,i2 i1,i2 4,4 NULL 2 Using sort_union(i1,i2); Using where
+1 SIMPLE t1 index_merge i1,i2 i1,i2 4,4 NULL 4 Using sort_union(i1,i2); Using where
select * from t1 where key1 < 5 or key2 > 197;
key1 key2
0 200
@@ -742,7 +742,7 @@ key1 key2
4 196
explain select * from t1 where key1 < 3 or key2 > 195;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 index_merge i1,i2 i1,i2 4,4 NULL 2 Using sort_union(i1,i2); Using where
+1 SIMPLE t1 index_merge i1,i2 i1,i2 4,4 NULL 4 Using sort_union(i1,i2); Using where
select * from t1 where key1 < 3 or key2 > 195;
key1 key2
0 200
@@ -758,7 +758,7 @@ update t1 set str1='aaa', str2='bbb', str3=concat(key2, '-', key1 div 2, '_' ,if
alter table t1 add primary key (str1, zeroval, str2, str3);
explain select * from t1 where key1 < 5 or key2 > 197;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL i1,i2 NULL NULL NULL 200 Using where
+1 SIMPLE t1 index_merge i1,i2 i1,i2 4,4 NULL 4 Using sort_union(i1,i2); Using where
select * from t1 where key1 < 5 or key2 > 197;
key1 key2 str1 zeroval str2 str3
4 196 aaa 0 bbb 196-2_a
@@ -768,7 +768,7 @@ key1 key2 str1 zeroval str2 str3
0 200 aaa 0 bbb 200-0_a
explain select * from t1 where key1 < 3 or key2 > 195;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL i1,i2 NULL NULL NULL 200 Using where
+1 SIMPLE t1 index_merge i1,i2 i1,i2 4,4 NULL 4 Using sort_union(i1,i2); Using where
select * from t1 where key1 < 3 or key2 > 195;
key1 key2 str1 zeroval str2 str3
4 196 aaa 0 bbb 196-2_a
@@ -789,7 +789,7 @@ show warnings;
Level Code Message
explain select pk from t1 where key1 = 1 and key2 = 1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref key1,key2 key1 5 const 1 Using where
+1 SIMPLE t1 ref key1,key2 key1 5 const 2 Using where
select pk from t1 where key2 = 1 and key1 = 1;
pk
26
@@ -1057,7 +1057,7 @@ SELECT a
FROM t1
WHERE c = 1 AND b = 1 AND d = 1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref c,bd c 5 const 1 Using where
+1 SIMPLE t1 ref c,bd c 5 const 2 Using where
CREATE TABLE t2 ( a INT )
SELECT a
FROM t1
@@ -1303,7 +1303,7 @@ pk1 pk2 key1 key2 pktail1ok pktail2ok pktail3bad pktail4bad pktail5bad pk2copy b
1 19 0 0 0 0 0 0 0 19 0 filler-data-19 filler2
explain select pk1,pk2 from t1 where key1 = 10 and key2=10 and 2*pk1+1 < 2*96+1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref key1,key2 key1 4 const 1 Using index condition; Using where
+1 SIMPLE t1 index_merge key1,key2 key1,key2 4,4 NULL 1 Using intersect(key1,key2); Using where; Using index
select pk1,pk2 from t1 where key1 = 10 and key2=10 and 2*pk1+1 < 2*96+1;
pk1 pk2
95 50
@@ -1324,13 +1324,13 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range PRIMARY,key1 key1 8 NULL ROWS Using index condition
explain select * from t1 where pktail1ok=1 and key1=10;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref key1,pktail1ok key1 4 const 1 Using where
+1 SIMPLE t1 index_merge key1,pktail1ok key1,pktail1ok 4,4 NULL 1 Using intersect(key1,pktail1ok); Using where
explain select * from t1 where pktail2ok=1 and key1=10;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref key1,pktail2ok key1 4 const 1 Using where
+1 SIMPLE t1 index_merge key1,pktail2ok key1,pktail2ok 4,4 NULL 1 Using intersect(key1,pktail2ok); Using where
explain select * from t1 where (pktail2ok=1 and pk1< 50000) or key1=10;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 index_merge PRIMARY,key1,pktail2ok pktail2ok,key1 8,4 NULL ROWS Using sort_union(pktail2ok,key1); Using where
+1 SIMPLE t1 index_merge PRIMARY,key1,pktail2ok PRIMARY,key1 4,4 NULL ROWS Using union(PRIMARY,key1); Using where
explain select * from t1 where pktail3bad=1 and key1=10;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref key1,pktail3bad EITHER_KEY 4 const ROWS Using where
@@ -1342,7 +1342,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref key1,pktail5bad key1 4 const ROWS Using where
explain select pk1,pk2,key1,key2 from t1 where key1 = 10 and key2=10 limit 10;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref key1,key2 key1 4 const 1 Using where
+1 SIMPLE t1 index_merge key1,key2 key1,key2 4,4 NULL 1 Using intersect(key1,key2); Using where; Using index
select pk1,pk2,key1,key2 from t1 where key1 = 10 and key2=10 limit 10;
pk1 pk2 key1 key2
95 50 10 10
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/information_schema.result b/storage/rocksdb/mysql-test/rocksdb/r/information_schema.result
index aba14e3c076..e22a85fd5c6 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/information_schema.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/information_schema.result
@@ -16,6 +16,7 @@ SET GLOBAL ROCKSDB_PAUSE_BACKGROUND_WORK=0;
select VALUE into @keysIn from INFORMATION_SCHEMA.ROCKSDB_COMPACTION_STATS where CF_NAME = 'default' and LEVEL = 'Sum' and TYPE = 'KeyIn';
CREATE TABLE t1 (i1 INT, i2 INT, PRIMARY KEY (i1)) ENGINE = ROCKSDB;
INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3);
+set global rocksdb_force_flush_memtable_now = true;
select * from INFORMATION_SCHEMA.ROCKSDB_GLOBAL_INFO;
TYPE NAME VALUE
MAX_INDEX_ID MAX_INDEX_ID max_index_id
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/lock.result b/storage/rocksdb/mysql-test/rocksdb/r/lock.result
index 36fea5b937f..7c4f54778d0 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/lock.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/lock.result
@@ -104,3 +104,18 @@ SELECT a,b FROM t1;
a b
UNLOCK TABLES;
DROP TABLE t1, t2;
+CREATE TABLE t1 (i INT) ENGINE=MyISAM;
+HANDLER t1 OPEN h;
+CREATE TABLE t2 (i INT) ENGINE=RocksDB;
+LOCK TABLES t2 WRITE;
+connect con1,localhost,root,,test;
+connection con1;
+FLUSH TABLES WITH READ LOCK;
+connection default;
+INSERT INTO t2 VALUES (1);
+UNLOCK TABLES;
+HANDLER h CLOSE;
+connection con1;
+disconnect con1;
+connection default;
+DROP TABLE t1, t2;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result b/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result
index aab6e82ae67..df27fbeddf1 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result
@@ -78,6 +78,7 @@ ROCKSDB_CF_OPTIONS Stable
ROCKSDB_COMPACTION_STATS Stable
ROCKSDB_GLOBAL_INFO Stable
ROCKSDB_DDL Stable
+ROCKSDB_SST_PROPS Stable
ROCKSDB_INDEX_FILE_MAP Stable
ROCKSDB_LOCKS Stable
ROCKSDB_TRX Stable
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/mysqldump.result b/storage/rocksdb/mysql-test/rocksdb/r/mysqldump.result
index 7e17c98668c..5ac36e1f4ba 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/mysqldump.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/mysqldump.result
@@ -34,7 +34,10 @@ update r1 set value1=value1+100 where id1=1 and id2=1 and id3='1';
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
-/*!50601 SELECT count(*) INTO @is_rocksdb_supported FROM information_schema.SESSION_VARIABLES WHERE variable_name='rocksdb_bulk_load' */;
+/*!50601 SELECT count(*) INTO @is_mysql8 FROM information_schema.TABLES WHERE table_schema='performance_schema' AND table_name='session_variables' */;
+/*!50601 SET @check_rocksdb = CONCAT( 'SELECT count(*) INTO @is_rocksdb_supported FROM ', IF (@is_mysql8, 'performance', 'information'), '_schema.session_variables WHERE variable_name=\'rocksdb_bulk_load\'') */;
+/*!50601 PREPARE s FROM @check_rocksdb */;
+/*!50601 EXECUTE s */;
/*!50601 SET @enable_bulk_load = IF (@is_rocksdb_supported, 'SET SESSION rocksdb_bulk_load=1', 'SET @dummy = 0') */;
/*!50601 PREPARE s FROM @enable_bulk_load */;
/*!50601 EXECUTE s */;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/percona_nonflushing_analyze_debug.result b/storage/rocksdb/mysql-test/rocksdb/r/percona_nonflushing_analyze_debug.result
new file mode 100644
index 00000000000..84176da34fe
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/r/percona_nonflushing_analyze_debug.result
@@ -0,0 +1,19 @@
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=RocksDB;
+INSERT INTO t1 VALUES (1), (2), (3);
+SET DEBUG_SYNC="handler_ha_index_next_end SIGNAL idx_scan_in_progress WAIT_FOR finish_scan";
+SELECT * FROM t1;
+SET DEBUG_SYNC="now WAIT_FOR idx_scan_in_progress";
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+SELECT * FROM t1;
+a
+1
+2
+3
+SET DEBUG_SYNC="now SIGNAL finish_scan";
+a
+1
+2
+3
+DROP TABLE t1;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/prefix_extractor_override.result b/storage/rocksdb/mysql-test/rocksdb/r/prefix_extractor_override.result
index 9c7d189e935..c0903eda663 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/prefix_extractor_override.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/prefix_extractor_override.result
@@ -24,11 +24,9 @@ CF_NAME OPTION_TYPE VALUE
__system__ PREFIX_EXTRACTOR rocksdb.CappedPrefix.24
cf1 PREFIX_EXTRACTOR rocksdb.CappedPrefix.24
default PREFIX_EXTRACTOR rocksdb.CappedPrefix.24
+SET @@global.rocksdb_update_cf_options = 'cf1={prefix_extractor=capped:26};';
-Restarting with new Prefix Extractor...
-
-
-Changed Prefix Extractor (after restart):
+Changed Prefix Extractor (after update_cf_options set, without restart):
SELECT * FROM information_schema.rocksdb_cf_options WHERE option_type like '%prefix_extractor%';
CF_NAME OPTION_TYPE VALUE
@@ -65,6 +63,7 @@ COUNT(*)
select variable_value-@u from information_schema.global_status where variable_name='rocksdb_bloom_filter_prefix_checked';
variable_value-@u
2
+SET @@global.rocksdb_update_cf_options = '';
set global rocksdb_compact_cf='cf1';
select variable_value into @u from information_schema.global_status where variable_name='rocksdb_bloom_filter_prefix_checked';
SELECT COUNT(*) FROM t1 WHERE id1=1 AND id2=30 AND id3=30;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/rocksdb.result b/storage/rocksdb/mysql-test/rocksdb/r/rocksdb.result
index dc13bb375b8..2044310782d 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/rocksdb.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/rocksdb.result
@@ -880,6 +880,7 @@ rocksdb_block_restart_interval 16
rocksdb_block_size 4096
rocksdb_block_size_deviation 10
rocksdb_bulk_load OFF
+rocksdb_bulk_load_allow_sk OFF
rocksdb_bulk_load_allow_unsorted OFF
rocksdb_bulk_load_size 1000
rocksdb_bytes_per_sync 0
@@ -887,6 +888,7 @@ rocksdb_cache_index_and_filter_blocks ON
rocksdb_checksums_pct 100
rocksdb_collect_sst_properties ON
rocksdb_commit_in_the_middle OFF
+rocksdb_commit_time_batch_for_recovery OFF
rocksdb_compact_cf
rocksdb_compaction_readahead_size 0
rocksdb_compaction_sequential_deletes 0
@@ -900,6 +902,7 @@ rocksdb_datadir ./#rocksdb
rocksdb_db_write_buffer_size 0
rocksdb_deadlock_detect OFF
rocksdb_deadlock_detect_depth 50
+rocksdb_debug_manual_compaction_delay 0
rocksdb_debug_optimizer_no_zero_cardinality ON
rocksdb_debug_ttl_ignore_pk OFF
rocksdb_debug_ttl_read_filter_ts 0
@@ -915,6 +918,7 @@ rocksdb_enable_ttl ON
rocksdb_enable_ttl_read_filtering ON
rocksdb_enable_write_thread_adaptive_yield OFF
rocksdb_error_if_exists OFF
+rocksdb_error_on_suboptimal_collation ON
rocksdb_flush_log_at_trx_commit 0
rocksdb_force_compute_memtable_stats ON
rocksdb_force_compute_memtable_stats_cachetime 0
@@ -934,12 +938,14 @@ rocksdb_lock_scanned_rows OFF
rocksdb_lock_wait_timeout 1
rocksdb_log_file_time_to_roll 0
rocksdb_manifest_preallocation_size 4194304
+rocksdb_manual_compaction_threads 0
rocksdb_manual_wal_flush ON
rocksdb_master_skip_tx_api OFF
rocksdb_max_background_jobs 2
rocksdb_max_latest_deadlocks 5
rocksdb_max_log_file_size 0
-rocksdb_max_manifest_file_size 18446744073709551615
+rocksdb_max_manifest_file_size 1073741824
+rocksdb_max_manual_compactions 10
rocksdb_max_row_locks 1048576
rocksdb_max_subcompactions 1
rocksdb_max_total_wal_size 0
@@ -969,6 +975,7 @@ rocksdb_skip_fill_cache OFF
rocksdb_skip_unique_check_tables .*
rocksdb_sst_mgr_rate_bytes_per_sec 0
rocksdb_stats_dump_period_sec 600
+rocksdb_stats_recalc_rate 0
rocksdb_store_row_debug_checksums OFF
rocksdb_strict_collation_check OFF
rocksdb_strict_collation_exceptions
@@ -995,6 +1002,7 @@ rocksdb_whole_key_filtering ON
rocksdb_write_batch_max_bytes 0
rocksdb_write_disable_wal OFF
rocksdb_write_ignore_missing_column_families OFF
+rocksdb_write_policy write_committed
create table t47 (pk int primary key, col1 varchar(12)) engine=rocksdb;
insert into t47 values (1, 'row1');
insert into t47 values (2, 'row2');
@@ -1351,7 +1359,7 @@ insert into t1 select (@a:=@a+1), 1234 from information_schema.session_variables
set @tmp1= @@rocksdb_max_row_locks;
set rocksdb_max_row_locks= 20;
update t1 set a=a+10;
-ERROR HY000: Status error 10 received from RocksDB: Operation aborted: Failed to acquire lock due to max_num_locks limit
+ERROR HY000: Got error 10 'Operation aborted: Failed to acquire lock due to max_num_locks limit' from ROCKSDB
DROP TABLE t1;
#
# Test AUTO_INCREMENT behavior problem,
@@ -1495,6 +1503,8 @@ Rocksdb_block_cache_index_miss #
Rocksdb_block_cache_miss #
Rocksdb_block_cachecompressed_hit #
Rocksdb_block_cachecompressed_miss #
+Rocksdb_bloom_filter_full_positive #
+Rocksdb_bloom_filter_full_true_positive #
Rocksdb_bloom_filter_prefix_checked #
Rocksdb_bloom_filter_prefix_useful #
Rocksdb_bloom_filter_useful #
@@ -1511,6 +1521,8 @@ Rocksdb_get_hit_l1 #
Rocksdb_get_hit_l2_and_up #
Rocksdb_getupdatessince_calls #
Rocksdb_iter_bytes_read #
+Rocksdb_manual_compactions_processed #
+Rocksdb_manual_compactions_running #
Rocksdb_memtable_hit #
Rocksdb_memtable_miss #
Rocksdb_no_file_closes #
@@ -1602,6 +1614,8 @@ ROCKSDB_BLOCK_CACHE_INDEX_MISS
ROCKSDB_BLOCK_CACHE_MISS
ROCKSDB_BLOCK_CACHECOMPRESSED_HIT
ROCKSDB_BLOCK_CACHECOMPRESSED_MISS
+ROCKSDB_BLOOM_FILTER_FULL_POSITIVE
+ROCKSDB_BLOOM_FILTER_FULL_TRUE_POSITIVE
ROCKSDB_BLOOM_FILTER_PREFIX_CHECKED
ROCKSDB_BLOOM_FILTER_PREFIX_USEFUL
ROCKSDB_BLOOM_FILTER_USEFUL
@@ -1618,6 +1632,8 @@ ROCKSDB_GET_HIT_L1
ROCKSDB_GET_HIT_L2_AND_UP
ROCKSDB_GETUPDATESSINCE_CALLS
ROCKSDB_ITER_BYTES_READ
+ROCKSDB_MANUAL_COMPACTIONS_PROCESSED
+ROCKSDB_MANUAL_COMPACTIONS_RUNNING
ROCKSDB_MEMTABLE_HIT
ROCKSDB_MEMTABLE_MISS
ROCKSDB_NO_FILE_CLOSES
@@ -1711,6 +1727,8 @@ ROCKSDB_BLOCK_CACHE_INDEX_MISS
ROCKSDB_BLOCK_CACHE_MISS
ROCKSDB_BLOCK_CACHECOMPRESSED_HIT
ROCKSDB_BLOCK_CACHECOMPRESSED_MISS
+ROCKSDB_BLOOM_FILTER_FULL_POSITIVE
+ROCKSDB_BLOOM_FILTER_FULL_TRUE_POSITIVE
ROCKSDB_BLOOM_FILTER_PREFIX_CHECKED
ROCKSDB_BLOOM_FILTER_PREFIX_USEFUL
ROCKSDB_BLOOM_FILTER_USEFUL
@@ -1727,6 +1745,8 @@ ROCKSDB_GET_HIT_L1
ROCKSDB_GET_HIT_L2_AND_UP
ROCKSDB_GETUPDATESSINCE_CALLS
ROCKSDB_ITER_BYTES_READ
+ROCKSDB_MANUAL_COMPACTIONS_PROCESSED
+ROCKSDB_MANUAL_COMPACTIONS_RUNNING
ROCKSDB_MEMTABLE_HIT
ROCKSDB_MEMTABLE_MISS
ROCKSDB_NO_FILE_CLOSES
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_checksums.result b/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_checksums.result
index 0ec2540e8dd..505487c08ba 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_checksums.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_checksums.result
@@ -11,7 +11,12 @@ insert into t1 values (1,1,1),(2,2,2),(3,3,3);
check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
-FOUND 1 /0 table records had checksums/ in mysqld.1.err
+CHECKTABLE t1: Checking table t1
+CHECKTABLE t1: Checking index a
+CHECKTABLE t1: ... 3 index entries checked (0 had checksums)
+CHECKTABLE t1: Checking index b
+CHECKTABLE t1: ... 3 index entries checked (0 had checksums)
+CHECKTABLE t1: 0 table records had checksums
drop table t1;
set session rocksdb_store_row_debug_checksums=on;
create table t2 (pk int primary key, a int, b int, key(a), key(b)) engine=rocksdb;
@@ -19,7 +24,12 @@ insert into t2 values (1,1,1),(2,2,2),(3,3,3);
check table t2;
Table Op Msg_type Msg_text
test.t2 check status OK
-FOUND 1 /3 table records had checksums/ in mysqld.1.err
+CHECKTABLE t2: Checking table t2
+CHECKTABLE t2: Checking index a
+CHECKTABLE t2: ... 3 index entries checked (3 had checksums)
+CHECKTABLE t2: Checking index b
+CHECKTABLE t2: ... 3 index entries checked (3 had checksums)
+CHECKTABLE t2: 3 table records had checksums
# Now, make a table that has both rows with checksums and without
create table t3 (pk int primary key, a int, b int, key(a), key(b)) engine=rocksdb;
insert into t3 values (1,1,1),(2,2,2),(3,3,3);
@@ -29,16 +39,21 @@ set session rocksdb_store_row_debug_checksums=on;
check table t3;
Table Op Msg_type Msg_text
test.t3 check status OK
-FOUND 1 /2 table records had checksums/ in mysqld.1.err
+CHECKTABLE t3: Checking table t3
+CHECKTABLE t3: Checking index a
+CHECKTABLE t3: ... 3 index entries checked (3 had checksums)
+CHECKTABLE t3: Checking index b
+CHECKTABLE t3: ... 3 index entries checked (2 had checksums)
+CHECKTABLE t3: 2 table records had checksums
set session rocksdb_store_row_debug_checksums=on;
set session rocksdb_checksums_pct=5;
create table t4 (pk int primary key, a int, b int, key(a), key(b)) engine=rocksdb;
check table t4;
Table Op Msg_type Msg_text
test.t4 check status OK
-10000 index entries had around 500 checksums
-10000 index entries had around 500 checksums
-Around 500 table records had checksums
+4000 index entries had around 200 checksums
+4000 index entries had around 200 checksums
+Around 200 table records had checksums
set session rocksdb_checksums_pct=100;
#
# Ok, table t2 has all rows with checksums. Simulate a few checksum mismatches.
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_deadlock_detect_rc.result b/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_deadlock_detect_rc.result
index e52f495e7d5..ea2506941b2 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_deadlock_detect_rc.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_deadlock_detect_rc.result
@@ -50,10 +50,9 @@ i
3
insert into t values (4), (1);
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
-# Statement should be rolled back
+# Transaction should be rolled back
select * from t;
i
-3
rollback;
connection con2;
i
@@ -62,6 +61,26 @@ connection con1;
i
rollback;
connection default;
+create table t1 (id int primary key, value int, value2 int, index(value)) engine=rocksdb;
+insert into t1 values (1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10);
+connection con1;
+begin;
+update t1 force index (value) set value2=value2+1 where value=3;
+connection con2;
+begin;
+update t1 force index (value) set value2=value2+1 where value=2;
+update t1 force index (value) set value2=value2+1 where value=4;
+connection con1;
+update t1 force index (value) set value2=value2+1 where value=4;
+connection con2;
+update t1 force index (value) set value2=value2+1 where value=3;
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+connection con1;
+rollback;
+connection con2;
+rollback;
+drop table t1;
+connection default;
disconnect con1;
disconnect con2;
disconnect con3;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_deadlock_detect_rr.result b/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_deadlock_detect_rr.result
index e52f495e7d5..ea2506941b2 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_deadlock_detect_rr.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_deadlock_detect_rr.result
@@ -50,10 +50,9 @@ i
3
insert into t values (4), (1);
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
-# Statement should be rolled back
+# Transaction should be rolled back
select * from t;
i
-3
rollback;
connection con2;
i
@@ -62,6 +61,26 @@ connection con1;
i
rollback;
connection default;
+create table t1 (id int primary key, value int, value2 int, index(value)) engine=rocksdb;
+insert into t1 values (1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10);
+connection con1;
+begin;
+update t1 force index (value) set value2=value2+1 where value=3;
+connection con2;
+begin;
+update t1 force index (value) set value2=value2+1 where value=2;
+update t1 force index (value) set value2=value2+1 where value=4;
+connection con1;
+update t1 force index (value) set value2=value2+1 where value=4;
+connection con2;
+update t1 force index (value) set value2=value2+1 where value=3;
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+connection con1;
+rollback;
+connection con2;
+rollback;
+drop table t1;
+connection default;
disconnect con1;
disconnect con2;
disconnect con3;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/secondary_key_update_lock.result b/storage/rocksdb/mysql-test/rocksdb/r/secondary_key_update_lock.result
new file mode 100644
index 00000000000..14217824bb4
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/r/secondary_key_update_lock.result
@@ -0,0 +1,18 @@
+connect con, localhost, root,,;
+connection default;
+create table t1 (a int primary key, b int unique key) engine = rocksdb;
+insert into t1 values(1, 1);
+connection con;
+begin;
+update t1 set b = 2 where b = 1;
+connection default;
+insert into t1 values(2, 1);
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+connection con;
+rollback;
+select * from t1;
+a b
+1 1
+connection default;
+drop table t1;
+disconnect con;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/show_engine.result b/storage/rocksdb/mysql-test/rocksdb/r/show_engine.result
index 9fc5db98d7d..eb23b71808b 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/show_engine.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/show_engine.result
@@ -136,6 +136,7 @@ __system__ TABLE_FACTORY::FLUSH_BLOCK_POLICY_FACTORY #
__system__ TABLE_FACTORY::CACHE_INDEX_AND_FILTER_BLOCKS #
__system__ TABLE_FACTORY::CACHE_INDEX_AND_FILTER_BLOCKS_WITH_HIGH_PRIORITY #
__system__ TABLE_FACTORY::PIN_L0_FILTER_AND_INDEX_BLOCKS_IN_CACHE #
+__system__ TABLE_FACTORY::PIN_TOP_LEVEL_INDEX_AND_FILTER #
__system__ TABLE_FACTORY::INDEX_TYPE #
__system__ TABLE_FACTORY::HASH_INDEX_ALLOW_COLLISION #
__system__ TABLE_FACTORY::CHECKSUM #
@@ -162,6 +163,7 @@ __system__ TABLE_FACTORY::VERIFY_COMPRESSION #
__system__ TABLE_FACTORY::READ_AMP_BYTES_PER_BIT #
__system__ TABLE_FACTORY::FORMAT_VERSION #
__system__ TABLE_FACTORY::ENABLE_INDEX_COMPRESSION #
+__system__ TABLE_FACTORY::BLOCK_ALIGN #
cf_t1 COMPARATOR #
cf_t1 MERGE_OPERATOR #
cf_t1 COMPACTION_FILTER #
@@ -207,6 +209,7 @@ cf_t1 TABLE_FACTORY::FLUSH_BLOCK_POLICY_FACTORY #
cf_t1 TABLE_FACTORY::CACHE_INDEX_AND_FILTER_BLOCKS #
cf_t1 TABLE_FACTORY::CACHE_INDEX_AND_FILTER_BLOCKS_WITH_HIGH_PRIORITY #
cf_t1 TABLE_FACTORY::PIN_L0_FILTER_AND_INDEX_BLOCKS_IN_CACHE #
+cf_t1 TABLE_FACTORY::PIN_TOP_LEVEL_INDEX_AND_FILTER #
cf_t1 TABLE_FACTORY::INDEX_TYPE #
cf_t1 TABLE_FACTORY::HASH_INDEX_ALLOW_COLLISION #
cf_t1 TABLE_FACTORY::CHECKSUM #
@@ -233,6 +236,7 @@ cf_t1 TABLE_FACTORY::VERIFY_COMPRESSION #
cf_t1 TABLE_FACTORY::READ_AMP_BYTES_PER_BIT #
cf_t1 TABLE_FACTORY::FORMAT_VERSION #
cf_t1 TABLE_FACTORY::ENABLE_INDEX_COMPRESSION #
+cf_t1 TABLE_FACTORY::BLOCK_ALIGN #
default COMPARATOR #
default MERGE_OPERATOR #
default COMPACTION_FILTER #
@@ -278,6 +282,7 @@ default TABLE_FACTORY::FLUSH_BLOCK_POLICY_FACTORY #
default TABLE_FACTORY::CACHE_INDEX_AND_FILTER_BLOCKS #
default TABLE_FACTORY::CACHE_INDEX_AND_FILTER_BLOCKS_WITH_HIGH_PRIORITY #
default TABLE_FACTORY::PIN_L0_FILTER_AND_INDEX_BLOCKS_IN_CACHE #
+default TABLE_FACTORY::PIN_TOP_LEVEL_INDEX_AND_FILTER #
default TABLE_FACTORY::INDEX_TYPE #
default TABLE_FACTORY::HASH_INDEX_ALLOW_COLLISION #
default TABLE_FACTORY::CHECKSUM #
@@ -304,6 +309,7 @@ default TABLE_FACTORY::VERIFY_COMPRESSION #
default TABLE_FACTORY::READ_AMP_BYTES_PER_BIT #
default TABLE_FACTORY::FORMAT_VERSION #
default TABLE_FACTORY::ENABLE_INDEX_COMPRESSION #
+default TABLE_FACTORY::BLOCK_ALIGN #
rev:cf_t2 COMPARATOR #
rev:cf_t2 MERGE_OPERATOR #
rev:cf_t2 COMPACTION_FILTER #
@@ -349,6 +355,7 @@ rev:cf_t2 TABLE_FACTORY::FLUSH_BLOCK_POLICY_FACTORY #
rev:cf_t2 TABLE_FACTORY::CACHE_INDEX_AND_FILTER_BLOCKS #
rev:cf_t2 TABLE_FACTORY::CACHE_INDEX_AND_FILTER_BLOCKS_WITH_HIGH_PRIORITY #
rev:cf_t2 TABLE_FACTORY::PIN_L0_FILTER_AND_INDEX_BLOCKS_IN_CACHE #
+rev:cf_t2 TABLE_FACTORY::PIN_TOP_LEVEL_INDEX_AND_FILTER #
rev:cf_t2 TABLE_FACTORY::INDEX_TYPE #
rev:cf_t2 TABLE_FACTORY::HASH_INDEX_ALLOW_COLLISION #
rev:cf_t2 TABLE_FACTORY::CHECKSUM #
@@ -375,6 +382,7 @@ rev:cf_t2 TABLE_FACTORY::VERIFY_COMPRESSION #
rev:cf_t2 TABLE_FACTORY::READ_AMP_BYTES_PER_BIT #
rev:cf_t2 TABLE_FACTORY::FORMAT_VERSION #
rev:cf_t2 TABLE_FACTORY::ENABLE_INDEX_COMPRESSION #
+rev:cf_t2 TABLE_FACTORY::BLOCK_ALIGN #
DROP TABLE t1;
DROP TABLE t2;
DROP TABLE t3;
@@ -419,4 +427,49 @@ END OF ROCKSDB TRANSACTION MONITOR OUTPUT
=========================================
ROLLBACK;
+START TRANSACTION WITH SHARED ROCKSDB SNAPSHOT;
+File Position Gtid_executed Snapshot_ID
+ 0 1
+SHOW ENGINE rocksdb STATUS;
+Type Name Status
+STATISTICS # #
+DBSTATS # #
+CF_COMPACTION # #
+CF_COMPACTION # #
+CF_COMPACTION # #
+CF_COMPACTION # #
+MEMORY_STATS # #
+BG_THREADS # #
+BG_THREADS # #
+EXPLICIT_SNAPSHOTS # #
+ROLLBACK;
+CREATE EXPLICIT rocksdb SNAPSHOT;
+File Position Gtid_executed Snapshot_ID
+ 0 2
+SHOW ENGINE rocksdb STATUS;
+Type Name Status
+STATISTICS # #
+DBSTATS # #
+CF_COMPACTION # #
+CF_COMPACTION # #
+CF_COMPACTION # #
+CF_COMPACTION # #
+MEMORY_STATS # #
+BG_THREADS # #
+BG_THREADS # #
+EXPLICIT_SNAPSHOTS # #
+RELEASE EXPLICIT rocksdb SNAPSHOT;
+File Position Gtid_executed Snapshot_ID
+ 0 2
+SHOW ENGINE rocksdb STATUS;
+Type Name Status
+STATISTICS # #
+DBSTATS # #
+CF_COMPACTION # #
+CF_COMPACTION # #
+CF_COMPACTION # #
+CF_COMPACTION # #
+MEMORY_STATS # #
+BG_THREADS # #
+BG_THREADS # #
SET GLOBAL rocksdb_max_background_jobs= @save.rocksdb_max_background_jobs;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/transaction.result b/storage/rocksdb/mysql-test/rocksdb/r/transaction.result
index 006baaf1339..8a5825b9291 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/transaction.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/transaction.result
@@ -958,3 +958,20 @@ a
rollback;
drop function func;
drop table t1,t2,t3;
+#
+# MDEV-16710: Slave SQL: Could not execute Update_rows_v1 event with RocksDB and triggers
+# Issue#857: MyRocks: Incorrect behavior when multiple statements fail inside a transaction
+#
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=RocksDB;
+INSERT INTO t1 VALUES (1);
+CREATE TABLE t2 (b INT PRIMARY KEY) ENGINE=RocksDB;
+CREATE TRIGGER tr AFTER INSERT ON t2 FOR EACH ROW INSERT INTO non_existing_table VALUES (NULL);
+BEGIN;
+DELETE FROM t1;
+INSERT INTO t2 VALUES (1);
+INSERT INTO t2 VALUES (2);
+# Must return empty result:
+SELECT * FROM t1;
+a
+COMMIT;
+drop table t1,t2;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/trx_info_rpl.result b/storage/rocksdb/mysql-test/rocksdb/r/trx_info_rpl.result
index 24466d982b9..b096e42a11b 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/trx_info_rpl.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/trx_info_rpl.result
@@ -3,8 +3,8 @@ include/master-slave.inc
DROP TABLE IF EXISTS t1;
connection slave;
include/stop_slave.inc
+create table t1 (a int, b int, primary key (a), unique key (b)) engine=rocksdb;
connection master;
-create table t1 (a int) engine=rocksdb;
connection slave;
show variables like 'rpl_skip_tx_api';
Variable_name Value
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/update.result b/storage/rocksdb/mysql-test/rocksdb/r/update.result
index 33bf8d09405..791fddd27ef 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/update.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/update.result
@@ -111,3 +111,11 @@ a b pk
55 NULL 11
10050 NULL 12
DROP TABLE t1;
+CREATE TABLE t1 (a INT, b CHAR(8), UNIQUE INDEX(a)) ENGINE=RocksDB;
+INSERT INTO t1 (a,b) VALUES (1,'foo'),(2,'bar');
+UPDATE t1 SET a=a+100;
+SELECT * FROM t1;
+a b
+101 foo
+102 bar
+DROP TABLE t1;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/use_direct_reads.result b/storage/rocksdb/mysql-test/rocksdb/r/use_direct_reads.result
new file mode 100644
index 00000000000..8a4ee14c116
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/r/use_direct_reads.result
@@ -0,0 +1,18 @@
+Checking direct reads
+CREATE TABLE t1 (pk INT PRIMARY KEY DEFAULT '0', a INT(11), b CHAR(8)) ENGINE=rocksdb;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `pk` int(11) NOT NULL DEFAULT 0,
+ `a` int(11) DEFAULT NULL,
+ `b` char(8) DEFAULT NULL,
+ PRIMARY KEY (`pk`)
+) ENGINE=ROCKSDB DEFAULT CHARSET=latin1
+INSERT INTO t1 VALUES (1, 1,'a');
+INSERT INTO t1 (a,b) VALUES (2,'b');
+set global rocksdb_force_flush_memtable_now=1;
+SELECT a,b FROM t1;
+a b
+1 a
+2 b
+DROP TABLE t1;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/validate_datadic.result b/storage/rocksdb/mysql-test/rocksdb/r/validate_datadic.result
index b5ab85d14c6..5d9a6342ae9 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/validate_datadic.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/validate_datadic.result
@@ -2,7 +2,8 @@ call mtr.add_suppression('RocksDB: Schema mismatch');
CREATE TABLE t1 (pk int primary key) ENGINE=ROCKSDB;
CREATE TABLE t2 (pk int primary key) ENGINE=ROCKSDB PARTITION BY KEY(pk) PARTITIONS 4;
"Expect errors that we are missing two .frm files"
-FOUND 2 /Schema mismatch/ in mysqld.1.err
+FOUND 1 /RocksDB: Schema mismatch - Table test.t1 is registered in RocksDB but does not have a .frm file/ in validate_datadic.err
+FOUND 1 /RocksDB: Schema mismatch - Table test.t2 is registered in RocksDB but does not have a .frm file/ in validate_datadic.err
"Expect an error that we have an extra .frm file"
-FOUND 3 /Schema mismatch/ in mysqld.1.err
+FOUND 1 /Schema mismatch - A .frm file exists for table test.t1_dummy, but that table is not registered in RocksDB/ in validate_datadic.err
DROP TABLE t1, t2;
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace.test b/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace.test
index 876ef2c9965..df7790ee4c2 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace.test
@@ -394,6 +394,24 @@ if ($end_max_index_id <= $start_max_index_id) {
SHOW CREATE TABLE t1;
DROP TABLE t1;
+# Cardinality checks for indexes statistics
+SET @prior_rocksdb_table_stats_sampling_pct = @@rocksdb_table_stats_sampling_pct;
+set global rocksdb_table_stats_sampling_pct = 100;
+CREATE TABLE t1 (a INT, b INT, PRIMARY KEY ka(a)) ENGINE=RocksDB;
+INSERT INTO t1 (a, b) VALUES (1, 10);
+INSERT INTO t1 (a, b) VALUES (2, 10);
+INSERT INTO t1 (a, b) VALUES (3, 20);
+INSERT INTO t1 (a, b) VALUES (4, 20);
+set global rocksdb_force_flush_memtable_now=1;
+analyze table t1;
+
+SHOW INDEX in t1;
+
+ALTER TABLE t1 ADD INDEX kb(b), ALGORITHM=INPLACE;
+SHOW INDEX in t1;
+
+DROP TABLE t1;
+SET global rocksdb_table_stats_sampling_pct = @prior_rocksdb_table_stats_sampling_pct;
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace_crash.test b/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace_crash.test
index d715eb7df7a..4f34cbe8f8a 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace_crash.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace_crash.test
@@ -1,6 +1,7 @@
--source include/have_rocksdb.inc
--source include/have_debug.inc
--source include/have_partition.inc
+--source include/not_valgrind.inc
--disable_warnings
drop table if exists t1;
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace_sstfilewriter.test b/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace_sstfilewriter.test
index 5eac8595f7b..61a10a60e7f 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace_sstfilewriter.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace_sstfilewriter.test
@@ -68,7 +68,7 @@ ALTER TABLE t1 ADD INDEX kb(b), ALGORITHM=INPLACE;
# hitting max row locks (1M)
set @tmp= @@rocksdb_max_row_locks;
set session rocksdb_max_row_locks=1000;
---error ER_RDB_STATUS_GENERAL
+--error ER_GET_ERRMSG
ALTER TABLE t1 ADD INDEX kb_copy(b), ALGORITHM=COPY;
set session rocksdb_bulk_load=1;
ALTER TABLE t1 ADD INDEX kb_copy(b), ALGORITHM=COPY;
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/autoinc_debug.test b/storage/rocksdb/mysql-test/rocksdb/t/autoinc_debug.test
index abcae8d98a5..b17548063d9 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/autoinc_debug.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/autoinc_debug.test
@@ -1,6 +1,7 @@
--source include/have_rocksdb.inc
--source include/have_debug.inc
--source include/have_log_bin.inc
+--source include/not_valgrind.inc
--echo #
--echo # Testing upgrading from server without merges for auto_increment
@@ -64,8 +65,8 @@ commit;
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--source include/wait_until_connected_again.inc
--disable_reconnect
-select table_schema, table_name, auto_increment from information_schema.tables where table_name = 't';
-select max(i) from t;
+select max(i) into @row_max from t;
+select table_schema, table_name, auto_increment > @row_max from information_schema.tables where table_name = 't';
--echo # After engine prepare
begin;
@@ -80,8 +81,8 @@ commit;
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--source include/wait_until_connected_again.inc
--disable_reconnect
-select table_schema, table_name, auto_increment from information_schema.tables where table_name = 't';
-select max(i) from t;
+select max(i) into @row_max from t;
+select table_schema, table_name, auto_increment > @row_max from information_schema.tables where table_name = 't';
--echo # After binlog
begin;
@@ -96,8 +97,8 @@ commit;
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--source include/wait_until_connected_again.inc
--disable_reconnect
-select table_schema, table_name, auto_increment from information_schema.tables where table_name = 't';
-select max(i) from t;
+select max(i) into @row_max from t;
+select table_schema, table_name, auto_increment > @row_max from information_schema.tables where table_name = 't';
--echo # After everything
begin;
@@ -112,7 +113,7 @@ commit;
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--source include/wait_until_connected_again.inc
--disable_reconnect
-select table_schema, table_name, auto_increment from information_schema.tables where table_name = 't';
-select max(i) from t;
+select max(i) into @row_max from t;
+select table_schema, table_name, auto_increment > @row_max from information_schema.tables where table_name = 't';
drop table t;
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/autoinc_vars.test b/storage/rocksdb/mysql-test/rocksdb/t/autoinc_vars.test
index 86a0a7f2a53..f4da0b7cb58 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/autoinc_vars.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/autoinc_vars.test
@@ -126,3 +126,26 @@ INSERT INTO t1 (a) VALUES (1);
UPDATE t1 SET pk = 3;
ALTER TABLE t1 AUTO_INCREMENT 2;
DROP TABLE t1;
+
+--echo #----------------------------------
+--echo # Issue #792 Crash in autoincrement
+--echo #----------------------------------
+
+CREATE TABLE t1(C1 DOUBLE AUTO_INCREMENT KEY,C2 CHAR) ENGINE=ROCKSDB;
+INSERT INTO t1 VALUES(2177,0);
+DROP TABLE t1;
+
+CREATE TABLE t0(c0 BLOB) ENGINE=ROCKSDB;
+INSERT INTO t0 VALUES(0);
+ALTER TABLE t0 AUTO_INCREMENT=0;
+DROP TABLE t0;
+
+--echo #----------------------------------
+--echo # Issue #869 Crash in autoincrement
+--echo #----------------------------------
+
+CREATE TABLE t1 (pk INT AUTO_INCREMENT, a INT, PRIMARY KEY(pk)) ENGINE=RocksDB;
+INSERT INTO t1 (a) VALUES (1);
+UPDATE t1 SET pk = 3;
+ALTER TABLE t1 AUTO_INCREMENT 2;
+DROP TABLE t1;
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/bloomfilter5-master.opt b/storage/rocksdb/mysql-test/rocksdb/t/bloomfilter5-master.opt
index 7d63dc74bb8..efcd69ba5bf 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/bloomfilter5-master.opt
+++ b/storage/rocksdb/mysql-test/rocksdb/t/bloomfilter5-master.opt
@@ -1 +1,3 @@
---rocksdb_override_cf_options=rev:bf5_1={prefix_extractor=capped:4;block_based_table_factory={filter_policy=bloomfilter:10:false;whole_key_filtering=0;}};
+--rocksdb_default_cf_options=write_buffer_size=256k;block_based_table_factory={filter_policy=bloomfilter:10:false;whole_key_filtering=0;}
+--rocksdb_override_cf_options=rev:bf5_1={prefix_extractor=capped:4};
+
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/bloomfilter_bulk_load-master.opt b/storage/rocksdb/mysql-test/rocksdb/t/bloomfilter_bulk_load-master.opt
new file mode 100644
index 00000000000..c28681ef030
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/t/bloomfilter_bulk_load-master.opt
@@ -0,0 +1,2 @@
+--rocksdb_default_cf_options=write_buffer_size=16k;block_based_table_factory={filter_policy=bloomfilter:10:false;whole_key_filtering=0;};prefix_extractor=capped:12
+--rocksdb_override_cf_options=cf2={optimize_filters_for_hits=true}
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/bloomfilter_bulk_load.test b/storage/rocksdb/mysql-test/rocksdb/t/bloomfilter_bulk_load.test
new file mode 100644
index 00000000000..09d9d734f9e
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/t/bloomfilter_bulk_load.test
@@ -0,0 +1,35 @@
+--source include/have_rocksdb.inc
+
+create table r1 (id bigint primary key, value bigint) engine=rocksdb;
+create table r2 (id bigint, value bigint, primary key (id) comment 'cf2') engine=rocksdb;
+set session rocksdb_bulk_load=1;
+--disable_query_log
+let $t = 1;
+let $i = 1;
+while ($t <= 2) {
+ while ($i <= 1000) {
+ let $insert = INSERT INTO r$t VALUES($i, $i);
+ #skipping a row
+ if ($i != 100) {
+ eval $insert;
+ }
+ inc $i;
+ }
+ inc $t;
+}
+--enable_query_log
+set session rocksdb_bulk_load=0;
+
+# bloom filter should be useful on insert (calling GetForUpdate)
+select variable_value into @h from information_schema.global_status where variable_name='rocksdb_block_cache_filter_hit';
+insert into r1 values (100, 100);
+select variable_value-@h from information_schema.global_status where variable_name='rocksdb_block_cache_filter_hit';
+
+# cf2 has no bloo filter in the bottommost level
+select variable_value into @h from information_schema.global_status where variable_name='rocksdb_block_cache_filter_hit';
+insert into r2 values (100, 100);
+select variable_value-@h from information_schema.global_status where variable_name='rocksdb_block_cache_filter_hit';
+
+DROP TABLE r1, r2;
+
+
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/bulk_load_sk.test b/storage/rocksdb/mysql-test/rocksdb/t/bulk_load_sk.test
new file mode 100644
index 00000000000..0fb47f74669
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/t/bulk_load_sk.test
@@ -0,0 +1,119 @@
+--source include/have_rocksdb.inc
+
+SET rocksdb_bulk_load_size=15;
+
+CREATE TABLE t4 (a INT, b INT, c INT,
+ PRIMARY KEY (a),
+ KEY (b),
+ KEY (c) COMMENT "rev:cf") ENGINE=ROCKSDB;
+CREATE TABLE t3 (a INT, b INT, c INT,
+ PRIMARY KEY (a),
+ KEY (b),
+ KEY (c) COMMENT "rev:cf") ENGINE=ROCKSDB;
+CREATE TABLE t2 (a INT, b INT, c INT,
+ PRIMARY KEY (a),
+ KEY (b),
+ KEY (c) COMMENT "rev:cf") ENGINE=ROCKSDB;
+CREATE TABLE t1 (a INT, b INT, c INT,
+ PRIMARY KEY (a),
+ KEY (b),
+ KEY (c) COMMENT "rev:cf") ENGINE=ROCKSDB;
+
+### Setup the control table ###
+--disable_query_log
+let $sign = 1;
+let $max = 10;
+let $i = 1;
+while ($i <= $max) {
+ let $a = 1 + $sign * $i;
+ let $b = 1 - $sign * $i;
+ let $sign = -$sign;
+ let $insert = INSERT INTO t3 VALUES ($a, $b, $b);
+ eval $insert;
+ inc $i;
+}
+--enable_query_log
+
+### Bulk load PK only ###
+SET rocksdb_bulk_load=1;
+INSERT INTO t1 SELECT * FROM t3 FORCE INDEX (PRIMARY) ORDER BY a;
+SELECT count(*) FROM t1 FORCE INDEX (PRIMARY);
+SELECT count(*) FROM t1 FORCE INDEX (b);
+SELECT count(*) FROM t1 FORCE INDEX (c);
+SET rocksdb_bulk_load=0;
+SELECT * FROM t1 FORCE INDEX (PRIMARY);
+SELECT b FROM t1 FORCE INDEX (b);
+SELECT c FROM t1 FORCE INDEX (c);
+--echo Checksums should match
+CHECKSUM TABLE t3;
+CHECKSUM TABLE t1;
+
+### Bulk load PK and SK but require PK order ###
+SET rocksdb_bulk_load_allow_sk=1;
+SET rocksdb_bulk_load=1;
+INSERT INTO t4 SELECT * FROM t3 FORCE INDEX (PRIMARY) ORDER BY a;
+SELECT count(*) FROM t4 FORCE INDEX (PRIMARY);
+SELECT count(*) FROM t4 FORCE INDEX (b);
+SELECT count(*) FROM t4 FORCE INDEX (c);
+SET rocksdb_bulk_load=0;
+SELECT * FROM t4 FORCE INDEX (PRIMARY);
+SELECT b FROM t4 FORCE INDEX (b);
+SELECT c FROM t4 FORCE INDEX (c);
+--echo Checksums should match
+CHECKSUM TABLE t3;
+CHECKSUM TABLE t4;
+
+### Bulk load both PK and SK in random order for all ###
+SET rocksdb_bulk_load_allow_unsorted=1;
+SET rocksdb_bulk_load_allow_sk=1;
+SET rocksdb_bulk_load=1;
+
+INSERT INTO t2 SELECT * FROM t3 WHERE b >= 0 ORDER BY b;
+INSERT INTO t2 SELECT * FROM t3 WHERE b < 0 ORDER BY b;
+SELECT count(*) FROM t2 FORCE INDEX (PRIMARY);
+SELECT count(*) FROM t2 FORCE INDEX (b);
+SELECT count(*) FROM t2 FORCE INDEX (c);
+
+--disable_query_log
+let $sign = 1;
+let $max = 20;
+let $i = 11;
+while ($i <= $max) {
+ let $a = 1 + $sign * $i;
+ let $b = 1 - $sign * $i;
+ let $sign = -$sign;
+ let $insert = INSERT INTO t2 VALUES ($a, $b, $b);
+ eval $insert;
+ inc $i;
+}
+--enable_query_log
+SELECT count(*) FROM t2 FORCE INDEX (PRIMARY);
+SELECT count(*) FROM t2 FORCE INDEX (b);
+SELECT count(*) FROM t2 FORCE INDEX (c);
+SET rocksdb_bulk_load=0;
+
+--disable_query_log
+let $sign = 1;
+let $max = 20;
+let $i = 11;
+while ($i <= $max) {
+ let $a = 1 + $sign * $i;
+ let $b = 1 - $sign * $i;
+ let $sign = -$sign;
+ let $insert = INSERT INTO t3 VALUES ($a, $b, $b);
+ eval $insert;
+ inc $i;
+}
+--enable_query_log
+
+SELECT * FROM t2 FORCE INDEX (PRIMARY);
+SELECT b FROM t2 FORCE INDEX (b);
+SELECT c FROM t2 FORCE INDEX (c);
+--echo Checksums should match
+CHECKSUM TABLE t3;
+CHECKSUM TABLE t2;
+
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+DROP TABLE t4;
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/cardinality.test b/storage/rocksdb/mysql-test/rocksdb/t/cardinality.test
index 14a82d7e462..21e4b49e560 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/cardinality.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/cardinality.test
@@ -94,5 +94,24 @@ SELECT table_name, table_rows FROM information_schema.tables WHERE table_schema
show index in t1;
SELECT table_name, table_rows FROM information_schema.tables WHERE table_schema = DATABASE();
-drop table t1;
+CREATE TABLE t2 (a INT, b INT, c INT, d INT, e INT, f INT, g INT,
+ PRIMARY KEY (a), KEY (c, b, a, d, e, f, g))
+ ENGINE=ROCKSDB;
+--disable_query_log
+let $i=0;
+while ($i<100)
+{
+ inc $i;
+ eval insert t2 values($i, $i div 10, 1, 1, 1, 1, 1);
+}
+--enable_query_log
+
+# Cardinality of key c should be 1 for c, 10 for b, 100 for a and the other fields.
+SET GLOBAL rocksdb_force_flush_memtable_now = 1;
+ANALYZE TABLE t2;
+--echo cardinality of the columns after 'a' must be equal to the cardinality of column 'a'
+SELECT CARDINALITY INTO @c FROM information_schema.statistics WHERE TABLE_NAME='t2' AND INDEX_NAME='c' AND COLUMN_NAME='a';
+SELECT COLUMN_NAME, CARDINALITY = @c FROM information_schema.statistics WHERE TABLE_NAME='t2' AND INDEX_NAME='c' AND SEQ_IN_INDEX > 3;
+
+drop table t1, t2;
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/check_ignore_unknown_options.test b/storage/rocksdb/mysql-test/rocksdb/t/check_ignore_unknown_options.test
index 9e7c816ae6e..b39c022fc46 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/check_ignore_unknown_options.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/check_ignore_unknown_options.test
@@ -8,7 +8,9 @@ let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect;
let $error_log= $MYSQLTEST_VARDIR/log/my_restart.err;
select variable_name, variable_value from information_schema.global_variables where variable_name="rocksdb_ignore_unknown_options";
---exec find $MYSQLD_DATADIR/#rocksdb/OPTIONS* | sort -n | tail -1 | xargs -0 -I {} -t sh -c "echo hello=world>>{}"
+--exec find $MYSQLD_DATADIR/#rocksdb/OPTIONS* | sort -t- -k 2 -n | tail -1 | xargs -0 -I {} -t sh -c "sed -i 's/rocksdb_version=.*/rocksdb_version=99.9.9/' {}"
+--exec find $MYSQLD_DATADIR/#rocksdb/OPTIONS* | sort -t- -k 2 -n | tail -1 | xargs -0 -I {} -t sh -c "echo hello=world>>{}"
+
--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--shutdown_server 10
@@ -19,8 +21,8 @@ select variable_name, variable_value from information_schema.global_variables wh
let SEARCH_FILE= $error_log;
let SEARCH_PATTERN= RocksDB: Compatibility check against existing database options failed;
--source include/search_pattern_in_file.inc
+--remove_file $error_log
--enable_reconnect
--exec echo "restart" > $restart_file
--source include/wait_until_connected_again.inc
---exec find $MYSQLD_DATADIR/#rocksdb/OPTIONS* | sort -n | tail -1 | xargs -0 -I {} -t sh -c "sed -i'' -e '/hello=world/d' {}"
select variable_name, variable_value from information_schema.global_variables where variable_name="rocksdb_ignore_unknown_options";
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/collation.test b/storage/rocksdb/mysql-test/rocksdb/t/collation.test
index 7152925dca4..3b808bc329a 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/collation.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/collation.test
@@ -3,14 +3,13 @@
# following check is commented out:
# --source include/have_fullregex.inc
-SET @start_global_value = @@global.ROCKSDB_STRICT_COLLATION_EXCEPTIONS;
-
---disable_warnings
-DROP TABLE IF EXISTS t1;
---enable_warnings
+call mtr.add_suppression("Invalid pattern");
# ci non-indexed column is allowed
CREATE TABLE t1 (id INT primary key, value varchar(50), value2 varbinary(50), value3 text) engine=rocksdb charset utf8;
+# ci indexed column is not allowed
+--error ER_UNSUPPORTED_COLLATION
+ALTER TABLE t1 ADD INDEX (value);
DROP TABLE t1;
# ci indexed column is not allowed
@@ -30,6 +29,8 @@ DROP TABLE t1;
# cs latin1_bin is allowed
CREATE TABLE t1 (id varchar(20), value varchar(50), value2 varchar(50), value3 text, primary key (id), index(value, value2)) engine=rocksdb charset latin1 collate latin1_bin;
+# THIS SHOULD FAIL BUT IT DOES NOT
+ALTER TABLE t1 collate=latin1_general_ci;
DROP TABLE t1;
# cs utf8_bin is allowed
@@ -183,5 +184,28 @@ DROP TABLE abc;
# test bad regex (null caused a crash) - Issue 493
SET GLOBAL rocksdb_strict_collation_exceptions=null;
+# test for warnings instead of errors
+--let $_mysqld_option=--rocksdb_error_on_suboptimal_collation=0
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+--source include/restart_mysqld_with_option.inc
+
+SET GLOBAL rocksdb_strict_collation_check=1;
+
+# ci indexed column is not optimal, should emit a warning
+CREATE TABLE t1 (id INT primary key, value varchar(50), value2 varbinary(50), value3 text, index(value)) engine=rocksdb charset utf8;
+DROP TABLE t1;
+
+# ci non-indexed column is allowed
+CREATE TABLE t1 (id INT primary key, value varchar(50), value2 varbinary(50), value3 text) engine=rocksdb charset utf8;
+# ci indexed column is not allowed, should emit a warning
+ALTER TABLE t1 ADD INDEX (value);
+DROP TABLE t1;
+
+# cs latin1_bin is allowed
+CREATE TABLE t1 (id varchar(20), value varchar(50), value2 varchar(50), value3 text, primary key (id), index(value, value2)) engine=rocksdb charset latin1 collate latin1_bin;
+# THIS SHOULD WARN BUT IT DOES NOT
+ALTER TABLE t1 collate=latin1_general_ci;
+DROP TABLE t1;
+
# cleanup
-SET GLOBAL rocksdb_strict_collation_exceptions=@start_global_value;
+--source include/restart_mysqld.inc
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/com_rpc_tx.cnf b/storage/rocksdb/mysql-test/rocksdb/t/com_rpc_tx.cnf
new file mode 100644
index 00000000000..49ebd28c793
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/t/com_rpc_tx.cnf
@@ -0,0 +1,4 @@
+!include suite/rpl/my.cnf
+
+[mysqld.1]
+binlog_format=row
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/com_rpc_tx.test b/storage/rocksdb/mysql-test/rocksdb/t/com_rpc_tx.test
new file mode 100644
index 00000000000..c2058474b01
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/t/com_rpc_tx.test
@@ -0,0 +1,87 @@
+--source "include/have_rocksdb.inc"
+--source "include/have_log_bin.inc"
+
+#
+# This test was created because 2pc transactions were failing in MyRocks
+# when using detached sessions. The test generates two separate transactions
+# in two detached sessions and then attempts to commit them as simultaneously
+# as possible. This consistently showed the problem but succeeds after the
+# fix was put in place.
+
+CREATE DATABASE db_rpc;
+USE db_rpc;
+CREATE TABLE t1(pk INT PRIMARY KEY) ENGINE=rocksdb;
+
+SET GLOBAL rocksdb_enable_2pc=1;
+
+connect(con2,localhost,root,,);
+connection default;
+
+query_attrs_add rpc_role root;
+query_attrs_add rpc_db db_rpc;
+SET autocommit = 0;
+let $rpc_id1 = get_rpc_id();
+if ($rpc_id1 == "") {
+ echo "Fail: rpc_id not returned as expected";
+}
+
+SET autocommit = 0;
+let $rpc_id2 = get_rpc_id();
+if ($rpc_id2 == "") {
+ echo "Fail: rpc_id not returned as expected";
+}
+
+query_attrs_delete rpc_role;
+query_attrs_delete rpc_db;
+
+query_attrs_add rpc_id $rpc_id1;
+BEGIN;
+query_attrs_delete rpc_id;
+
+query_attrs_add rpc_id $rpc_id2;
+BEGIN;
+query_attrs_delete rpc_id;
+
+query_attrs_add rpc_id $rpc_id1;
+SELECT * from t1;
+query_attrs_delete rpc_id;
+
+query_attrs_add rpc_id $rpc_id2;
+SELECT * from t1;
+query_attrs_delete rpc_id;
+
+query_attrs_add rpc_id $rpc_id1;
+INSERT INTO t1 VALUES(1);
+query_attrs_delete rpc_id;
+
+query_attrs_add rpc_id $rpc_id2;
+INSERT INTO t1 VALUES(2);
+query_attrs_delete rpc_id;
+
+query_attrs_add rpc_id $rpc_id1;
+send COMMIT;
+
+connection con2;
+query_attrs_add rpc_id $rpc_id2;
+send COMMIT;
+
+connection default;
+reap;
+query_attrs_delete rpc_id;
+
+connection con2;
+reap;
+query_attrs_delete rpc_id;
+
+connection default;
+disconnect con2;
+
+SELECT * from db_rpc.t1;
+
+disable_query_log;
+eval KILL $rpc_id1;
+eval KILL $rpc_id2;
+enable_query_log;
+
+DROP DATABASE db_rpc;
+
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/create_no_primary_key_table-master.opt b/storage/rocksdb/mysql-test/rocksdb/t/create_no_primary_key_table-master.opt
new file mode 100644
index 00000000000..ce274af3507
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/t/create_no_primary_key_table-master.opt
@@ -0,0 +1 @@
+--block_create_no_primary_key=TRUE
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/create_no_primary_key_table.test b/storage/rocksdb/mysql-test/rocksdb/t/create_no_primary_key_table.test
new file mode 100644
index 00000000000..c5650359d8c
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/t/create_no_primary_key_table.test
@@ -0,0 +1,44 @@
+USE mysql;
+CREATE TABLE mysql_table (a INT) ENGINE=ROCKSDB;
+-- error ER_BLOCK_NO_PRIMARY_KEY
+CREATE TABLE test.mysql_table (a INT) ENGINE=ROCKSDB;
+USE test;
+-- error ER_BLOCK_NO_PRIMARY_KEY
+CREATE TABLE mysql_table (a INT) ENGINE=ROCKSDB;
+-- error ER_BLOCK_NO_PRIMARY_KEY
+CREATE TABLE IF NOT EXISTS mysql_table_2 (a INT) ENGINE=ROCKSDB;
+-- error ER_BLOCK_NO_PRIMARY_KEY
+CREATE TABLE mysql_table_no_cols ENGINE=ROCKSDB;
+CREATE TABLE mysql.mysql_table_2 (a INT) ENGINE=ROCKSDB;
+
+CREATE TABLE mysql_primkey (a INT PRIMARY KEY, b INT, c INT, d INT, INDEX (c)) ENGINE=ROCKSDB;
+ALTER TABLE mysql_primkey DROP b, DROP a, ADD (f INT PRIMARY KEY);
+-- error ER_BLOCK_NO_PRIMARY_KEY
+ALTER TABLE mysql_primkey DROP PRIMARY KEY;
+
+CREATE TABLE mysql_primkey2 (a INT PRIMARY KEY, b INT, c INT) ENGINE=ROCKSDB;
+ALTER TABLE mysql_primkey2 DROP b;
+ALTER TABLE mysql_primkey2 ADD (b INT);
+-- error ER_BLOCK_NO_PRIMARY_KEY
+ALTER TABLE mysql_primkey2 DROP c, DROP A;
+
+CREATE TABLE mysql_primkey3 (a INT PRIMARY KEY, b INT, c INT, INDEX indexonb (b), INDEX indexonc (c)) ENGINE=ROCKSDB;
+ALTER TABLE mysql_primkey3 DROP INDEX indexonb;
+ALTER TABLE mysql_primkey3 DROP c;
+ALTER TABLE mysql_primkey3 DROP PRIMARY KEY, ADD PRIMARY KEY(b);
+
+CREATE TABLE mysql_primkey4(a INT, b INT, PRIMARY KEY(a), INDEX si (a, b)) ENGINE=ROCKSDB;
+DROP INDEX si ON mysql_primkey4;
+-- error ER_BLOCK_NO_PRIMARY_KEY
+DROP INDEX `PRIMARY` ON mysql_primkey4;
+
+ALTER TABLE mysql.mysql_table ADD PRIMARY KEY (a);
+ALTER TABLE mysql.mysql_table DROP PRIMARY KEY;
+
+DROP TABLE mysql_primkey;
+DROP TABLE mysql_primkey2;
+DROP TABLE mysql_primkey3;
+DROP TABLE mysql_primkey4;
+USE mysql;
+DROP TABLE mysql_table;
+DROP TABLE mysql_table_2;
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/deadlock_tracking.test b/storage/rocksdb/mysql-test/rocksdb/t/deadlock_tracking.test
index 9677d2dbbaa..8ceebef8f72 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/deadlock_tracking.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/deadlock_tracking.test
@@ -1,7 +1,7 @@
-set @prior_lock_wait_timeout = @@rocksdb_lock_wait_timeout;
-set @prior_deadlock_detect = @@rocksdb_deadlock_detect;
-set @prior_max_latest_deadlocks = @@rocksdb_max_latest_deadlocks;
-set global rocksdb_deadlock_detect = on;
+set @prior_lock_wait_timeout = @@rocksdb_lock_wait_timeout;
+set @prior_deadlock_detect = @@rocksdb_deadlock_detect;
+set @prior_max_latest_deadlocks = @@rocksdb_max_latest_deadlocks;
+set global rocksdb_deadlock_detect = on;
set global rocksdb_lock_wait_timeout = 10000;
--echo # Clears deadlock buffer of any prior deadlocks.
set global rocksdb_max_latest_deadlocks = 0;
@@ -21,29 +21,29 @@ let $con3= `SELECT CONNECTION_ID()`;
connection default;
eval create table t (i int primary key) engine=$engine;
insert into t values (1), (2), (3);
---replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/TIMESTAMP/ /WAITING KEY: [0-9a-f]{16}/KEY/ /TRANSACTION ID: [0-9]*/TXN_ID/
+--replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/TIMESTAMP/ /WAITING KEY: [0-9a-f]{16}/KEY/ /TRANSACTION ID: [0-9]*/TXN_ID/ /TIMESTAMP: [0-9]*/TSTAMP/
show engine rocksdb transaction status;
echo Deadlock #1;
--source include/simple_deadlock.inc
connection default;
---replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/TIMESTAMP/ /WAITING KEY: [0-9a-f]{16}/KEY/ /TRANSACTION ID: [0-9]*/TXN_ID/
+--replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/TIMESTAMP/ /WAITING KEY: [0-9a-f]{16}/KEY/ /TRANSACTION ID: [0-9]*/TXN_ID/ /TIMESTAMP: [0-9]*/TSTAMP/
show engine rocksdb transaction status;
echo Deadlock #2;
--source include/simple_deadlock.inc
connection default;
---replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/TIMESTAMP/ /WAITING KEY: [0-9a-f]{16}/KEY/ /TRANSACTION ID: [0-9]*/TXN_ID/
+--replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/TIMESTAMP/ /WAITING KEY: [0-9a-f]{16}/KEY/ /TRANSACTION ID: [0-9]*/TXN_ID/ /TIMESTAMP: [0-9]*/TSTAMP/
show engine rocksdb transaction status;
set global rocksdb_max_latest_deadlocks = 10;
echo Deadlock #3;
--source include/simple_deadlock.inc
connection default;
---replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/TIMESTAMP/ /WAITING KEY: [0-9a-f]{16}/KEY/ /TRANSACTION ID: [0-9]*/TXN_ID/
+--replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/TIMESTAMP/ /WAITING KEY: [0-9a-f]{16}/KEY/ /TRANSACTION ID: [0-9]*/TXN_ID/ /TIMESTAMP: [0-9]*/TSTAMP/
show engine rocksdb transaction status;
set global rocksdb_max_latest_deadlocks = 1;
---replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/TIMESTAMP/ /WAITING KEY: [0-9a-f]{16}/KEY/ /TRANSACTION ID: [0-9]*/TXN_ID/
+--replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/TIMESTAMP/ /WAITING KEY: [0-9a-f]{16}/KEY/ /TRANSACTION ID: [0-9]*/TXN_ID/ /TIMESTAMP: [0-9]*/TSTAMP/
show engine rocksdb transaction status;
connection con3;
@@ -51,15 +51,15 @@ set rocksdb_deadlock_detect_depth = 2;
echo Deadlock #4;
connection con1;
-begin;
+begin;
select * from t where i=1 for update;
connection con2;
-begin;
+begin;
select * from t where i=2 for update;
connection con3;
-begin;
+begin;
select * from t where i=3 for update;
connection con1;
@@ -84,29 +84,29 @@ select case when variable_value-@a = 1 then 'true' else 'false' end as deadlocks
rollback;
connection con2;
-reap;
+reap;
rollback;
connection con1;
-reap;
+reap;
rollback;
connection default;
set global rocksdb_max_latest_deadlocks = 5;
---replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/TIMESTAMP/ /WAITING KEY: [0-9a-f]{16}/KEY/ /TRANSACTION ID: [0-9]*/TXN_ID/
+--replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/TIMESTAMP/ /WAITING KEY: [0-9a-f]{16}/KEY/ /TRANSACTION ID: [0-9]*/TXN_ID/ /TIMESTAMP: [0-9]*/TSTAMP/
show engine rocksdb transaction status;
echo Deadlock #5;
connection con1;
-begin;
+begin;
select * from t where i=1 for update;
connection con2;
-begin;
+begin;
select * from t where i=2 for update;
connection con3;
-begin;
+begin;
select * from t where i=3 lock in share mode;
connection con1;
@@ -128,28 +128,58 @@ select * from t where i=1 lock in share mode;
rollback;
connection con1;
-reap;
+reap;
rollback;
connection con3;
rollback;
connection default;
---replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/TIMESTAMP/ /WAITING KEY: [0-9a-f]{16}/KEY/ /TRANSACTION ID: [0-9]*/TXN_ID/
+--replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/TIMESTAMP/ /WAITING KEY: [0-9a-f]{16}/KEY/ /TRANSACTION ID: [0-9]*/TXN_ID/ /TIMESTAMP: [0-9]*/TSTAMP/
show engine rocksdb transaction status;
+echo Deadlock #6;
+connection con1;
+create table t1 (id int primary key, value int) engine=rocksdb;
+insert into t1 values (1,1),(2,2),(3,3),(4,4),(5,5);
+begin;
+update t1 set value=value+100 where id=1;
+update t1 set value=value+100 where id=2;
+
+connection con2;
+begin;
+update t1 set value=value+200 where id=3;
+
+connection con1;
+send update t1 set value=value+100 where id=3;
+
+connection con2;
+let $wait_condition = select count(*) = 1 from information_schema.rocksdb_trx
+where thread_id = $con1 and waiting_key != "";
+--source include/wait_condition.inc
+--error ER_LOCK_DEADLOCK
+update t1 set value=value+200 where id=1;
+
+# con2 tx is automatically rolled back
+connection con1;
+reap;
+select * from t1;
+drop table t1;
+
+connection default;
+
disconnect con1;
disconnect con2;
disconnect con3;
-set global rocksdb_lock_wait_timeout = @prior_lock_wait_timeout;
+set global rocksdb_lock_wait_timeout = @prior_lock_wait_timeout;
set global rocksdb_deadlock_detect = @prior_deadlock_detect;
drop table t;
---replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/TIMESTAMP/ /WAITING KEY: [0-9a-f]{16}/KEY/ /TRANSACTION ID: [0-9]*/TXN_ID/ /INDEX_ID: [0-9a-f]*/IDX_ID/
+--replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/TIMESTAMP/ /WAITING KEY: [0-9a-f]{16}/KEY/ /TRANSACTION ID: [0-9]*/TXN_ID/ /INDEX_ID: [0-9a-f]*/IDX_ID/ /TIMESTAMP: [0-9]*/TSTAMP/
show engine rocksdb transaction status;
set global rocksdb_max_latest_deadlocks = 0;
--echo # Clears deadlock buffer of any existent deadlocks.
set global rocksdb_max_latest_deadlocks = @prior_max_latest_deadlocks;
---replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/TIMESTAMP/ /WAITING KEY: [0-9a-f]{16}/KEY/ /TRANSACTION ID: [0-9]*/TXN_ID/ /INDEX_ID: [0-9a-f]*/IDX_ID/
+--replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/TIMESTAMP/ /WAITING KEY: [0-9a-f]{16}/KEY/ /TRANSACTION ID: [0-9]*/TXN_ID/ /INDEX_ID: [0-9a-f]*/IDX_ID/ /TIMESTAMP: [0-9]*/TSTAMP/
show engine rocksdb transaction status;
--source include/wait_until_count_sessions.inc
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/disabled.def b/storage/rocksdb/mysql-test/rocksdb/t/disabled.def
index 60f658ec7e1..6237afaa283 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/disabled.def
+++ b/storage/rocksdb/mysql-test/rocksdb/t/disabled.def
@@ -21,7 +21,9 @@ mysqldump2 : MariaDB's mysqldump doesn't support --print-ordering-key
native_procedure : Not supported in MariaDB
slow_query_log: MDEV-11480
select_for_update_skip_locked_nowait: MDEV-11481
-
+create_no_primary_key_table: MariaDB doesn't have --block_create_no_primary_key
+explicit_snapshot: MariaDB doesn't support Shared/Explicit snapshots
+percona_nonflushing_analyze_debug : Requires Percona Server's Non-flushing ANALYZE feature
##
## Tests that do not fit MariaDB's test environment. Upstream seems to test
@@ -34,7 +36,7 @@ rqg_transactions : Test that use RQG are disabled
allow_no_pk_concurrent_insert: stress test
rocksdb_deadlock_stress_rc: stress test
rocksdb_deadlock_stress_rr: stress test
-
+use_direct_reads: Direct IO is not supported on all filesystems
##
## Tests which hit a problem elsewhere (Upstream, SQL layer, etc)
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/drop_table.test b/storage/rocksdb/mysql-test/rocksdb/t/drop_table.test
index 0d3dee5ab17..9667c7ba650 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/drop_table.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/drop_table.test
@@ -78,6 +78,33 @@ let $table = t1;
let $table = t4;
--source drop_table_repopulate_table.inc
+# Run manual compaction, then restarting mysqld
+# and confirming it is not blocked.
+SET GLOBAL rocksdb_max_manual_compactions = 2;
+SET GLOBAL rocksdb_debug_manual_compaction_delay = 3600;
+connect (con1, localhost, root,,);
+connect (con2, localhost, root,,);
+connect (con3, localhost, root,,);
+connection con1;
+send SET GLOBAL rocksdb_compact_cf='cf1';
+connection con2;
+send SET GLOBAL rocksdb_compact_cf='rev:cf2';
+connection default;
+let $wait_condition = select count(*) = 2 from information_schema.processlist where info like 'SET GLOBAL rocksdb_compact_cf%';
+--source include/wait_condition.inc
+# longer enough than manual compaction thread to start compaction
+--sleep 2
+select * from information_schema.global_status where variable_name='rocksdb_manual_compactions_running';
+
+connection con3;
+--error ER_INTERNAL_ERROR
+SET GLOBAL rocksdb_compact_cf='cf1';
+--error ER_INTERNAL_ERROR
+SET GLOBAL rocksdb_compact_cf='rev:cf2';
+
+connection default;
+--source include/restart_mysqld.inc
+
drop table t4;
# Restart the server before t4's indices are deleted
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/explicit_snapshot-master.opt b/storage/rocksdb/mysql-test/rocksdb/t/explicit_snapshot-master.opt
new file mode 100644
index 00000000000..d7dd66b4480
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/t/explicit_snapshot-master.opt
@@ -0,0 +1 @@
+--log-bin --binlog_format=row --gtid_mode=ON --enforce_gtid_consistency --log-slave-updates
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/explicit_snapshot.test b/storage/rocksdb/mysql-test/rocksdb/t/explicit_snapshot.test
new file mode 100644
index 00000000000..efe1980b694
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/t/explicit_snapshot.test
@@ -0,0 +1,263 @@
+source include/have_log_bin.inc;
+source include/have_rocksdb.inc;
+
+disable_warnings;
+DROP TABLE IF EXISTS t1;
+enable_warnings;
+
+connect (con1,localhost,root,,);
+connect (con2,localhost,root,,);
+
+connection con1;
+CREATE TABLE T1 (a INT PRIMARY KEY AUTO_INCREMENT) ENGINE=ROCKSDB;
+INSERT INTO T1 VALUES();
+
+#
+
+echo "con1: Creating explict snapshot";
+let $snapshot=
+ query_get_value(CREATE EXPLICIT ROCKSDB SNAPSHOT, Snapshot_ID, 1);
+SELECT * FROM T1;
+
+connection con2;
+echo "con2: Inserting a row";
+INSERT INTO T1 VALUES();
+SELECT * FROM T1;
+echo "con2: Attaching snapshot id $snapshot";
+disable_result_log;
+eval ATTACH EXPLICIT ROCKSDB SNAPSHOT $snapshot;
+enable_result_log;
+echo "con2: New row should not be visible";
+SELECT * FROM T1;
+echo "con2: Releasing snapshot";
+disable_result_log;
+RELEASE EXPLICIT ROCKSDB SNAPSHOT;
+enable_result_log;
+echo "con2: New row should be visible";
+SELECT * FROM T1;
+
+connection con1;
+echo "con1: New row should not be visible";
+SELECT * FROM T1;
+echo "con1: Releasing snapshot";
+disable_result_log;
+RELEASE EXPLICIT ROCKSDB SNAPSHOT;
+enable_result_log;
+echo "con1: New row should be visible";
+SELECT * FROM T1;
+
+#
+
+echo "con1: Starting shared snapshot";
+let $snapshot=
+query_get_value(START TRANSACTION WITH SHARED ROCKSDB SNAPSHOT, Snapshot_ID, 1);
+SELECT * FROM T1;
+
+connection con2;
+echo "con2: Inserting a row";
+INSERT INTO T1 VALUES();
+SELECT * FROM T1;
+echo "con2: Starting existing snapshot";
+disable_result_log;
+eval START TRANSACTION WITH EXISTING ROCKSDB SNAPSHOT $snapshot;
+enable_result_log;
+echo "con2: New row should not be visible";
+SELECT * FROM T1;
+COMMIT;
+echo "con2: New row should be visible";
+SELECT * FROM T1;
+
+connection con1;
+COMMIT;
+echo "con1: New row should be visible";
+SELECT * FROM T1;
+
+## Negative test cases
+
+connection con1;
+echo "con1: Creating explict snapshot";
+let $snapshot=
+ query_get_value(CREATE EXPLICIT ROCKSDB SNAPSHOT, Snapshot_ID, 1);
+echo "con2: Trying to insert row";
+error ER_UPDATES_WITH_EXPLICIT_SNAPSHOT;
+INSERT INTO T1 VALUES();
+
+connection con2;
+echo "con2: Attaching existing snapshot";
+disable_result_log;
+eval ATTACH EXPLICIT ROCKSDB SNAPSHOT $snapshot;
+enable_result_log;
+echo "con2: Trying to insert row";
+error ER_UPDATES_WITH_EXPLICIT_SNAPSHOT;
+INSERT INTO T1 VALUES();
+
+connection con1;
+disable_result_log;
+RELEASE EXPLICIT ROCKSDB SNAPSHOT;
+enable_result_log;
+connection con2;
+disable_result_log;
+RELEASE EXPLICIT ROCKSDB SNAPSHOT;
+enable_result_log;
+
+connection con1;
+echo "con1: Starting shared snapshot";
+let $snapshot=
+query_get_value(START TRANSACTION WITH SHARED ROCKSDB SNAPSHOT, Snapshot_ID, 1);
+echo "con1: Trying to insert row";
+error ER_UPDATES_WITH_CONSISTENT_SNAPSHOT;
+INSERT INTO T1 VALUES();
+
+connection con2;
+echo "con2: Starting existing snapshot";
+disable_result_log;
+eval START TRANSACTION WITH EXISTING ROCKSDB SNAPSHOT $snapshot;
+enable_result_log;
+echo "con2: Trying to insert row";
+error ER_UPDATES_WITH_CONSISTENT_SNAPSHOT;
+INSERT INTO T1 VALUES();
+
+connection con1;
+COMMIT;
+connection con2;
+COMMIT;
+
+## Test how overlapping explicit snapshot statements work
+
+connection con1;
+echo "con1: Creating explicit snapshot";
+disable_result_log;
+CREATE EXPLICIT ROCKSDB SNAPSHOT;
+enable_result_log;
+SELECT * FROM T1;
+
+connection con2;
+echo "con2: Inserting a row";
+INSERT INTO T1 VALUES();
+SELECT * FROM T1;
+
+connection con1;
+echo "con1: New row should not be seen";
+SELECT * FROM T1;
+echo "con1: Creating another explicit snapshot";
+disable_result_log;
+CREATE EXPLICIT ROCKSDB SNAPSHOT;
+enable_result_log;
+echo "con1: Now the new row should be seen";
+SELECT * FROM T1;
+
+#
+
+echo "con1: Starting transaction with consistent snapshot";
+disable_result_log;
+START TRANSACTION WITH CONSISTENT ROCKSDB SNAPSHOT;
+enable_result_log;
+SELECT * FROM T1;
+
+connection con2;
+echo "con2: Inserting a row";
+INSERT INTO T1 VALUES();
+SELECT * FROM T1;
+
+connection con1;
+echo "con1: The new row should not be seen";
+SELECT * FROM T1;
+
+echo "con1: Creating another explicit snapshot";
+disable_result_log;
+CREATE EXPLICIT ROCKSDB SNAPSHOT;
+enable_result_log;
+echo "con1: The new row should still not be seen";
+SELECT * FROM T1;
+
+echo "con1: Committing trx";
+COMMIT;
+echo "con1: The new row should now be seen because of the new explicit snapshot created above";
+SELECT * FROM T1;
+
+connection con1;
+echo "con1: Releasing explicit snapshot";
+disable_result_log;
+RELEASE EXPLICIT ROCKSDB SNAPSHOT;
+enable_result_log;
+
+#
+
+echo "con1: Starting transaction with shared snapshot";
+disable_result_log;
+START TRANSACTION WITH SHARED ROCKSDB SNAPSHOT;
+enable_result_log;
+SELECT * FROM T1;
+
+connection con2;
+echo "con2: Inserting a row";
+INSERT INTO T1 VALUES();
+SELECT * FROM T1;
+
+connection con1;
+echo "con1: The new row should not be seen";
+SELECT * FROM T1;
+
+echo "con1: Starting another transaction with shared snapshot";
+disable_result_log;
+START TRANSACTION WITH SHARED ROCKSDB SNAPSHOT;
+enable_result_log;
+echo "con1: The new row should now be seen";
+SELECT * FROM T1;
+COMMIT;
+
+#
+
+echo "con1: Creating explicit snapshot";
+disable_result_log;
+CREATE EXPLICIT ROCKSDB SNAPSHOT;
+enable_result_log;
+SELECT * FROM T1;
+
+echo "con1: Releasing explicit snapshot";
+disable_result_log;
+RELEASE EXPLICIT ROCKSDB SNAPSHOT;
+enable_result_log;
+
+echo "con1: Releasing explicit snapshot again";
+error ER_UNKNOWN_ERROR;
+RELEASE EXPLICIT ROCKSDB SNAPSHOT;
+
+#
+
+echo "con1: Starting transaction with shared snapshot";
+disable_result_log;
+START TRANSACTION WITH SHARED ROCKSDB SNAPSHOT;
+enable_result_log;
+SELECT * FROM T1;
+
+connection con2;
+echo "con2: Inserting a row";
+INSERT INTO T1 VALUES();
+SELECT * FROM T1;
+
+connection con1;
+echo "con1: Creating explicit snapshot";
+disable_result_log;
+CREATE EXPLICIT ROCKSDB SNAPSHOT;
+enable_result_log;
+SELECT * FROM T1;
+
+echo "con1: Releasing explicit snapshot";
+disable_result_log;
+RELEASE EXPLICIT ROCKSDB SNAPSHOT;
+enable_result_log;
+
+echo "con1: The new row should not be seen";
+SELECT* FROM T1;
+COMMIT;
+
+#
+
+## Cleanup
+DROP TABLE T1;
+
+connection default;
+disconnect con1;
+disconnect con2;
+
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/i_s_deadlock.test b/storage/rocksdb/mysql-test/rocksdb/t/i_s_deadlock.test
index 21558899782..e0479d6a337 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/i_s_deadlock.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/i_s_deadlock.test
@@ -32,23 +32,23 @@ select * from information_schema.rocksdb_deadlock;
echo Deadlock #1;
--source include/simple_deadlock.inc
connection default;
---replace_column 1 DEADLOCK_ID 2 TRANSACTION_ID 4 WAITING_KEY
+--replace_column 1 DEADLOCK_ID 2 TIMESTAMP 3 TRANSACTION_ID 5 WAITING_KEY
select * from information_schema.rocksdb_deadlock;
echo Deadlock #2;
--source include/simple_deadlock.inc
connection default;
---replace_column 1 DEADLOCK_ID 2 TRANSACTION_ID 4 WAITING_KEY
+--replace_column 1 DEADLOCK_ID 2 TIMESTAMP 3 TRANSACTION_ID 5 WAITING_KEY
select * from information_schema.rocksdb_deadlock;
set global rocksdb_max_latest_deadlocks = 10;
echo Deadlock #3;
--source include/simple_deadlock.inc
connection default;
---replace_column 1 DEADLOCK_ID 2 TRANSACTION_ID 4 WAITING_KEY
+--replace_column 1 DEADLOCK_ID 2 TIMESTAMP 3 TRANSACTION_ID 5 WAITING_KEY
select * from information_schema.rocksdb_deadlock;
set global rocksdb_max_latest_deadlocks = 1;
---replace_column 1 DEADLOCK_ID 2 TRANSACTION_ID 4 WAITING_KEY
+--replace_column 1 DEADLOCK_ID 2 TIMESTAMP 3 TRANSACTION_ID 5 WAITING_KEY
select * from information_schema.rocksdb_deadlock;
connection con3;
@@ -96,7 +96,7 @@ rollback;
connection default;
set global rocksdb_max_latest_deadlocks = 5;
---replace_column 1 DEADLOCK_ID 2 TRANSACTION_ID 4 WAITING_KEY
+--replace_column 1 DEADLOCK_ID 2 TIMESTAMP 3 TRANSACTION_ID 5 WAITING_KEY
select * from information_schema.rocksdb_deadlock;
echo Deadlock #5;
@@ -138,7 +138,7 @@ connection con3;
rollback;
connection default;
---replace_column 1 DEADLOCK_ID 2 TRANSACTION_ID 4 WAITING_KEY
+--replace_column 1 DEADLOCK_ID 2 TIMESTAMP 3 TRANSACTION_ID 5 WAITING_KEY
select * from information_schema.rocksdb_deadlock;
disconnect con1;
@@ -148,7 +148,7 @@ disconnect con3;
set global rocksdb_lock_wait_timeout = @prior_lock_wait_timeout;
set global rocksdb_deadlock_detect = @prior_deadlock_detect;
drop table t;
---replace_column 1 DEADLOCK_ID 2 TRANSACTION_ID 4 WAITING_KEY 6 INDEX_NAME 7 TABLE_NAME
+--replace_column 1 DEADLOCK_ID 2 TIMESTAMP 3 TRANSACTION_ID 5 WAITING_KEY 7 INDEX_NAME 8 TABLE_NAME
select * from information_schema.rocksdb_deadlock;
set global rocksdb_max_latest_deadlocks = 0;
--echo # Clears deadlock buffer of any existent deadlocks.
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/index_file_map.test b/storage/rocksdb/mysql-test/rocksdb/t/index_file_map.test
index 1021846c508..8b0e2339426 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/index_file_map.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/index_file_map.test
@@ -46,6 +46,9 @@ WHERE INDEX_NUMBER =
(SELECT INDEX_NUMBER FROM INFORMATION_SCHEMA.ROCKSDB_DDL
WHERE TABLE_NAME = 't2' AND INDEX_NAME = "PRIMARY");
+# The number of sst files should be 1 or more
+select count(*) > 0 from information_schema.rocksdb_sst_props;
+
# cleanup
DROP TABLE t1;
DROP TABLE t2;
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/index_merge_rocksdb2-master.opt b/storage/rocksdb/mysql-test/rocksdb/t/index_merge_rocksdb2-master.opt
index c07b063f07c..7681c42eeb3 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/index_merge_rocksdb2-master.opt
+++ b/storage/rocksdb/mysql-test/rocksdb/t/index_merge_rocksdb2-master.opt
@@ -1 +1 @@
---rocksdb_strict_collation_check=off --binlog_format=row --log-bin
+--rocksdb_strict_collation_check=off --binlog_format=row --log-bin --rocksdb_records_in_range=2
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/information_schema.test b/storage/rocksdb/mysql-test/rocksdb/t/information_schema.test
index 67dae5d6263..09998b9ae5f 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/information_schema.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/information_schema.test
@@ -28,6 +28,7 @@ select VALUE into @keysIn from INFORMATION_SCHEMA.ROCKSDB_COMPACTION_STATS where
CREATE TABLE t1 (i1 INT, i2 INT, PRIMARY KEY (i1)) ENGINE = ROCKSDB;
INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3);
+set global rocksdb_force_flush_memtable_now = true;
# No binlog coordinates in MariaDB: --let $MASTER_UUID = query_get_value(SELECT @@SERVER_UUID, @@SERVER_UUID, 1)
--let $max_index_id = query_get_value(SELECT * from INFORMATION_SCHEMA.ROCKSDB_GLOBAL_INFO where type = 'MAX_INDEX_ID', VALUE, 1)
# No binlog coordinates in MariaDB: --replace_result $MASTER_UUID uuid $max_index_id max_index_id
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/insert_optimized_config-master.opt b/storage/rocksdb/mysql-test/rocksdb/t/insert_optimized_config-master.opt
deleted file mode 100644
index 3b7d80662db..00000000000
--- a/storage/rocksdb/mysql-test/rocksdb/t/insert_optimized_config-master.opt
+++ /dev/null
@@ -1,8 +0,0 @@
---rocksdb_write_disable_wal=1
---rocksdb_flush_log_at_trx_commit=0
---rocksdb_default_cf_options=write_buffer_size=16k;target_file_size_base=16k;level0_file_num_compaction_trigger=4;level0_slowdown_writes_trigger=256;level0_stop_writes_trigger=256;max_write_buffer_number=16;compression_per_level=kNoCompression;memtable=vector:1024
---rocksdb_override_cf_options=__system__={memtable=skip_list:16}
---rocksdb_compaction_sequential_deletes=0
---rocksdb_compaction_sequential_deletes_window=0
---rocksdb_allow_concurrent_memtable_write=0
-
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/insert_optimized_config.test b/storage/rocksdb/mysql-test/rocksdb/t/insert_optimized_config.test
index 3e1cf7375e8..46ea7f0eb0a 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/insert_optimized_config.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/insert_optimized_config.test
@@ -1,9 +1,19 @@
--source include/have_rocksdb.inc
+--source include/have_write_committed.inc
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
+# reload with load optimized config
+let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect;
+--exec echo "wait" > $restart_file
+--shutdown_server 10
+--source include/wait_until_disconnected.inc
+-- exec echo "restart:--rocksdb_write_disable_wal=1 --rocksdb_flush_log_at_trx_commit=0 --rocksdb_default_cf_options=write_buffer_size=16k;target_file_size_base=16k;level0_file_num_compaction_trigger=4;level0_slowdown_writes_trigger=256;level0_stop_writes_trigger=256;max_write_buffer_number=16;compression_per_level=kNoCompression;memtable=vector:1024 --rocksdb_override_cf_options=__system__={memtable=skip_list:16} --rocksdb_compaction_sequential_deletes=0 --rocksdb_compaction_sequential_deletes_window=0 --rocksdb_allow_concurrent_memtable_write=0" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+-- enable_reconnect
+-- source include/wait_until_connected_again.inc
+
create table t1(
id bigint not null primary key,
i1 bigint, #unique
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/lock.test b/storage/rocksdb/mysql-test/rocksdb/t/lock.test
index 015a08bef57..9ce5e566505 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/lock.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/lock.test
@@ -196,6 +196,28 @@ SELECT a,b FROM t1;
UNLOCK TABLES;
DROP TABLE t1, t2;
+CREATE TABLE t1 (i INT) ENGINE=MyISAM;
+HANDLER t1 OPEN h;
+CREATE TABLE t2 (i INT) ENGINE=RocksDB;
+LOCK TABLES t2 WRITE;
+
+--connect (con1,localhost,root,,test)
+--connection con1
+--send
+FLUSH TABLES WITH READ LOCK;
+
+--connection default
+INSERT INTO t2 VALUES (1);
+UNLOCK TABLES;
+HANDLER h CLOSE;
+
+--connection con1
+--reap
+--disconnect con1
+
+--connection default
+DROP TABLE t1, t2;
+
# Check that all connections opened by test cases in this file are really
# gone so execution of other tests won't be affected by their presence.
--source include/wait_until_count_sessions.inc
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/percona_nonflushing_analyze_debug.test b/storage/rocksdb/mysql-test/rocksdb/t/percona_nonflushing_analyze_debug.test
new file mode 100644
index 00000000000..c0c73e683bf
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/t/percona_nonflushing_analyze_debug.test
@@ -0,0 +1,11 @@
+--source include/have_debug_sync.inc
+--source include/have_rocksdb.inc
+
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=RocksDB;
+INSERT INTO t1 VALUES (1), (2), (3);
+
+--let $percona_nonflushing_analyze_table= t1
+--source include/percona_nonflushing_analyze_debug.inc
+
+DROP TABLE t1;
+
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/prefix_extractor_override.test b/storage/rocksdb/mysql-test/rocksdb/t/prefix_extractor_override.test
index c6b91071171..161f7b566f5 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/prefix_extractor_override.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/prefix_extractor_override.test
@@ -26,9 +26,6 @@ select variable_value into @u from information_schema.global_status where variab
SELECT COUNT(*) FROM t1 WHERE id1=1 AND id2=1 AND id3=1;
select variable_value-@u from information_schema.global_status where variable_name='rocksdb_bloom_filter_prefix_checked';
-# MariaDB: the following doesn't work on Windows and doesn't seem to be needed
-# on Linux:
-#--exec echo "" > $MYSQLTEST_VARDIR/log/mysqld.1.err
--let $_mysqld_option=--rocksdb_override_cf_options=cf1={prefix_extractor=capped:26};
--echo
@@ -37,16 +34,12 @@ select variable_value-@u from information_schema.global_status where variable_na
--sorted_result
SELECT * FROM information_schema.rocksdb_cf_options WHERE option_type like '%prefix_extractor%';
-# This should no longer crash. See https://github.com/facebook/mysql-5.6/issues/641
+SET @@global.rocksdb_update_cf_options = 'cf1={prefix_extractor=capped:26};';
--echo
---echo Restarting with new Prefix Extractor...
---echo
---source include/restart_mysqld_with_option.inc
-
---echo
---echo Changed Prefix Extractor (after restart):
+--echo Changed Prefix Extractor (after update_cf_options set, without restart):
--echo
--sorted_result
+# Restart no longer needed
SELECT * FROM information_schema.rocksdb_cf_options WHERE option_type like '%prefix_extractor%';
# Satisfies can_use_bloom_filter (4+8+8+8), but can't use because the old SST
@@ -88,6 +81,7 @@ select variable_value into @u from information_schema.global_status where variab
SELECT COUNT(*) FROM t1 WHERE id1=1 AND id2=1 AND id3=1;
select variable_value-@u from information_schema.global_status where variable_name='rocksdb_bloom_filter_prefix_checked';
+SET @@global.rocksdb_update_cf_options = '';
set global rocksdb_compact_cf='cf1';
# Select the updated, make sure bloom filter is checked now
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/rocksdb.test b/storage/rocksdb/mysql-test/rocksdb/t/rocksdb.test
index b884738424f..13f1bd68a72 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/rocksdb.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/rocksdb.test
@@ -1,5 +1,6 @@
--source include/have_rocksdb.inc
--source include/have_partition.inc
+--source include/have_write_committed.inc
#
# RocksDB Storage Engine tests
@@ -1150,7 +1151,7 @@ set @a=-1;
insert into t1 select (@a:=@a+1), 1234 from information_schema.session_variables limit 100;
set @tmp1= @@rocksdb_max_row_locks;
set rocksdb_max_row_locks= 20;
---error ER_RDB_STATUS_GENERAL
+--error ER_GET_ERRMSG
update t1 set a=a+10;
DROP TABLE t1;
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/rocksdb_checksums.test b/storage/rocksdb/mysql-test/rocksdb/t/rocksdb_checksums.test
index 9a7704c7ab0..42a4c83ff04 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/rocksdb_checksums.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/rocksdb_checksums.test
@@ -5,6 +5,11 @@
#
--source include/have_debug.inc
+--let LOG=$MYSQLTEST_VARDIR/tmp/rocksdb_checksum.err
+--let $_mysqld_option=--log-error=$LOG
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+--source include/restart_mysqld_with_option.inc
+
set @save_rocksdb_store_row_debug_checksums=@@global.rocksdb_store_row_debug_checksums;
set @save_rocksdb_verify_row_debug_checksums=@@global.rocksdb_verify_row_debug_checksums;
set @save_rocksdb_checksums_pct=@@global.rocksdb_checksums_pct;
@@ -14,8 +19,10 @@ show variables like 'rocksdb_%checksum%';
create table t1 (pk int primary key, a int, b int, key(a), key(b)) engine=rocksdb;
insert into t1 values (1,1,1),(2,2,2),(3,3,3);
check table t1;
---let SEARCH_FILE=$MYSQLTEST_VARDIR/log/mysqld.1.err
+--let SEARCH_FILE=$LOG
--let SEARCH_PATTERN=0 table records had checksums
+--let SEARCH_PATTERN=CHECKTABLE t1[^\n]*
+--let SEARCH_OUTPUT=matches
--source include/search_pattern_in_file.inc
drop table t1;
@@ -24,7 +31,7 @@ set session rocksdb_store_row_debug_checksums=on;
create table t2 (pk int primary key, a int, b int, key(a), key(b)) engine=rocksdb;
insert into t2 values (1,1,1),(2,2,2),(3,3,3);
check table t2;
---let SEARCH_PATTERN=3 table records had checksums
+--let SEARCH_PATTERN=CHECKTABLE t2[^\n]*
--source include/search_pattern_in_file.inc
--echo # Now, make a table that has both rows with checksums and without
@@ -34,7 +41,7 @@ set session rocksdb_store_row_debug_checksums=off;
update t3 set b=3 where a=2;
set session rocksdb_store_row_debug_checksums=on;
check table t3;
---let SEARCH_PATTERN=2 table records had checksums
+--let SEARCH_PATTERN=CHECKTABLE t3[^\n]*
--source include/search_pattern_in_file.inc
set session rocksdb_store_row_debug_checksums=on;
@@ -43,7 +50,7 @@ create table t4 (pk int primary key, a int, b int, key(a), key(b)) engine=rocksd
--disable_query_log
let $i=0;
let $x= 100000;
-while ($i<10000)
+while ($i<4000)
{
inc $i;
eval insert t4(pk,a,b) values($i, $i, $i div 10);
@@ -53,11 +60,12 @@ while ($i<10000)
--enable_query_log
check table t4;
perl;
-$total=10000;
+$total=4000;
$pct=5;
@out=();
-$filename= "$ENV{MYSQLTEST_VARDIR}/log/mysqld.1.err";
+$filename= "$ENV{LOG}";
+print $filename "\n";
open(F, '<', $filename) || die("Can't open file $filename: $!");
while(<F>) {
@out=() if /^CURRENT_TEST:/;
@@ -138,4 +146,7 @@ set @@global.rocksdb_store_row_debug_checksums=@save_rocksdb_store_row_debug_che
set @@global.rocksdb_verify_row_debug_checksums=@save_rocksdb_verify_row_debug_checksums;
set @@global.rocksdb_checksums_pct=@save_rocksdb_checksums_pct;
+--source include/restart_mysqld.inc
+#--remove_file $LOG
+
drop table t2,t3,t4;
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/rocksdb_deadlock_detect.inc b/storage/rocksdb/mysql-test/rocksdb/t/rocksdb_deadlock_detect.inc
index 01180ea29a8..082c61308f3 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/rocksdb_deadlock_detect.inc
+++ b/storage/rocksdb/mysql-test/rocksdb/t/rocksdb_deadlock_detect.inc
@@ -68,7 +68,7 @@ let $wait_condition =
select * from t;
--error ER_LOCK_DEADLOCK
insert into t values (4), (1);
---echo # Statement should be rolled back
+--echo # Transaction should be rolled back
select * from t;
rollback;
@@ -80,6 +80,39 @@ connection con1;
--reap
rollback;
+
+connection default;
+create table t1 (id int primary key, value int, value2 int, index(value)) engine=rocksdb;
+insert into t1 values (1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10);
+
+connection con1;
+begin;
+update t1 force index (value) set value2=value2+1 where value=3;
+
+connection con2;
+begin;
+update t1 force index (value) set value2=value2+1 where value=2;
+update t1 force index (value) set value2=value2+1 where value=4;
+
+connection con1;
+send update t1 force index (value) set value2=value2+1 where value=4;
+
+connection con2;
+let $wait_condition =
+`SELECT CONCAT('select count(*) = 1 from information_schema.rocksdb_trx where THREAD_ID = ', '$con1', ' and WAITING_KEY != ""')`;
+--source include/wait_condition.inc
+--error ER_LOCK_DEADLOCK
+update t1 force index (value) set value2=value2+1 where value=3;
+
+connection con1;
+--reap
+rollback;
+
+connection con2;
+rollback;
+drop table t1;
+
+
connection default;
disconnect con1;
disconnect con2;
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/secondary_key_update_lock.test b/storage/rocksdb/mysql-test/rocksdb/t/secondary_key_update_lock.test
new file mode 100644
index 00000000000..b43a32b6a0d
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/t/secondary_key_update_lock.test
@@ -0,0 +1,26 @@
+--source include/have_rocksdb.inc
+
+# Tests if locks are held for the secondary keys of old rows in updates
+
+connect (con, localhost, root,,);
+
+connection default;
+create table t1 (a int primary key, b int unique key) engine = rocksdb;
+insert into t1 values(1, 1);
+
+connection con;
+begin;
+update t1 set b = 2 where b = 1; # this should lock the row where b = 1
+
+connection default;
+error ER_LOCK_WAIT_TIMEOUT;
+insert into t1 values(2, 1); # should error out with lock_wait_timeout
+
+connection con;
+rollback;
+select * from t1;
+
+# Cleanup
+connection default;
+drop table t1;
+disconnect con;
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/set_checkpoint.inc b/storage/rocksdb/mysql-test/rocksdb/t/set_checkpoint.inc
index 558e2413256..aae9db6c927 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/set_checkpoint.inc
+++ b/storage/rocksdb/mysql-test/rocksdb/t/set_checkpoint.inc
@@ -23,7 +23,7 @@ if (!$succeeds)
{
--disable_result_log
--disable_query_log
- --error ER_RDB_STATUS_GENERAL
+ --error ER_GET_ERRMSG
eval SET GLOBAL ROCKSDB_CREATE_CHECKPOINT = '$checkpoint';
--enable_query_log
--enable_result_log
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/show_engine.test b/storage/rocksdb/mysql-test/rocksdb/t/show_engine.test
index 06f64ddb3fa..ccca197d317 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/show_engine.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/show_engine.test
@@ -86,5 +86,18 @@ SHOW ENGINE rocksdb TRANSACTION STATUS;
ROLLBACK;
+# Check if explicit snapshots are correctly populated
+START TRANSACTION WITH SHARED ROCKSDB SNAPSHOT;
+--replace_column 2 # 3 #
+SHOW ENGINE rocksdb STATUS;
+ROLLBACK;
+CREATE EXPLICIT rocksdb SNAPSHOT;
+--replace_column 2 # 3 #
+SHOW ENGINE rocksdb STATUS;
+RELEASE EXPLICIT rocksdb SNAPSHOT;
+--replace_column 2 # 3 #
+SHOW ENGINE rocksdb STATUS;
+
+
# Restore old values
SET GLOBAL rocksdb_max_background_jobs= @save.rocksdb_max_background_jobs;
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/transaction.test b/storage/rocksdb/mysql-test/rocksdb/t/transaction.test
index 3350db99dab..129484bac91 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/transaction.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/transaction.test
@@ -133,3 +133,26 @@ rollback;
drop function func;
drop table t1,t2,t3;
+--echo #
+--echo # MDEV-16710: Slave SQL: Could not execute Update_rows_v1 event with RocksDB and triggers
+--echo # Issue#857: MyRocks: Incorrect behavior when multiple statements fail inside a transaction
+--echo #
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=RocksDB;
+INSERT INTO t1 VALUES (1);
+
+CREATE TABLE t2 (b INT PRIMARY KEY) ENGINE=RocksDB;
+
+CREATE TRIGGER tr AFTER INSERT ON t2 FOR EACH ROW INSERT INTO non_existing_table VALUES (NULL);
+
+BEGIN;
+DELETE FROM t1;
+--error 0,ER_NO_SUCH_TABLE
+INSERT INTO t2 VALUES (1);
+--error 0,ER_NO_SUCH_TABLE
+INSERT INTO t2 VALUES (2);
+--echo # Must return empty result:
+SELECT * FROM t1;
+COMMIT;
+
+drop table t1,t2;
+
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/trx_info_rpl.test b/storage/rocksdb/mysql-test/rocksdb/t/trx_info_rpl.test
index af3cce19630..91ab266cdc4 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/trx_info_rpl.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/trx_info_rpl.test
@@ -9,11 +9,11 @@ connection slave;
--enable_warnings
connection master;
-create table t1 (a int) engine=rocksdb;
+create table t1 (a int, b int, primary key (a), unique key (b)) engine=rocksdb;
--disable_query_log
--let $aa= 0
while ($aa < 1000) {
- eval insert into t1 values ($aa);
+ eval insert into t1 values ($aa, $aa);
--inc $aa
}
--enable_query_log
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/update.test b/storage/rocksdb/mysql-test/rocksdb/t/update.test
index 51e2c5be0a6..6220c4f55a3 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/update.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/update.test
@@ -70,3 +70,13 @@ SELECT * FROM t1 ORDER BY pk;
DROP TABLE t1;
+
+#
+# Issue #830 UPDATE with unique constraint does not work
+#
+
+CREATE TABLE t1 (a INT, b CHAR(8), UNIQUE INDEX(a)) ENGINE=RocksDB;
+INSERT INTO t1 (a,b) VALUES (1,'foo'),(2,'bar');
+UPDATE t1 SET a=a+100;
+SELECT * FROM t1;
+DROP TABLE t1;
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/use_direct_reads.test b/storage/rocksdb/mysql-test/rocksdb/t/use_direct_reads.test
new file mode 100644
index 00000000000..c347a85518f
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/t/use_direct_reads.test
@@ -0,0 +1,37 @@
+--source include/have_rocksdb.inc
+
+--perl
+use Cwd 'abs_path';
+
+open(FILE, ">", "$ENV{MYSQL_TMP_DIR}/data_in_shm.inc") or die;
+my $real_path= abs_path($ENV{'MYSQLTEST_VARDIR'});
+my $in_shm= index($real_path, "/dev/shm") != -1;
+print FILE "let \$DATA_IN_SHM= $in_shm;\n";
+close FILE;
+EOF
+
+--source $MYSQL_TMP_DIR/data_in_shm.inc
+--remove_file $MYSQL_TMP_DIR/data_in_shm.inc
+
+if ($DATA_IN_SHM)
+{
+ --skip DATADIR is in /dev/shm, possibly due to --mem
+}
+
+--echo Checking direct reads
+--let $_mysqld_option=--rocksdb_use_direct_reads=1
+--source include/restart_mysqld_with_option.inc
+
+CREATE TABLE t1 (pk INT PRIMARY KEY DEFAULT '0', a INT(11), b CHAR(8)) ENGINE=rocksdb;
+SHOW CREATE TABLE t1;
+INSERT INTO t1 VALUES (1, 1,'a');
+INSERT INTO t1 (a,b) VALUES (2,'b');
+set global rocksdb_force_flush_memtable_now=1;
+--sorted_result
+SELECT a,b FROM t1;
+DROP TABLE t1;
+
+# cleanup
+--let _$mysqld_option=
+--source include/restart_mysqld.inc
+
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/validate_datadic.test b/storage/rocksdb/mysql-test/rocksdb/t/validate_datadic.test
index e9dcc604155..ec48dc03ec8 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/validate_datadic.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/validate_datadic.test
@@ -19,6 +19,8 @@ CREATE TABLE t2 (pk int primary key) ENGINE=ROCKSDB PARTITION BY KEY(pk) PARTITI
# server until it is told to
--let $_server_id= `SELECT @@server_id`
--let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.$_server_id.expect
+--let LOG=$MYSQLTEST_VARDIR/tmp/validate_datadic.err
+
--exec echo "wait" >$_expect_file_name
# Send shutdown to the connected server and give it 10 seconds to die before
@@ -47,7 +49,7 @@ shutdown_server 10;
--move_file $MYSQLTEST_VARDIR/mysqld.1/data/test/t2.frm $MYSQLTEST_VARDIR/mysqld.1/data/test/t2.frm.tmp
# Attempt to restart the server
---exec echo "restart:--rocksdb_validate_tables=2" >$_expect_file_name
+--exec echo "restart:--rocksdb_validate_tables=2 --log-error=$LOG" >$_expect_file_name
--enable_reconnect
--source include/wait_until_connected_again.inc
@@ -55,21 +57,28 @@ shutdown_server 10;
# We should now have an error message
--echo "Expect errors that we are missing two .frm files"
---let SEARCH_FILE=$MYSQLTEST_VARDIR/log/mysqld.1.err
---let SEARCH_PATTERN=Schema mismatch
+#--let SEARCH_FILE=$MYSQLTEST_VARDIR/log/mysqld.1.err
+#--let SEARCH_PATTERN=Schema mismatch
+#--source include/search_pattern_in_file.inc
+#--let SEARCH_PATTERN=RocksDB: Schema mismatch - Table test.t2 is registered in RocksDB but does not have a .frm file
+#--source include/search_pattern_in_file.inc
+--let SEARCH_FILE=$LOG
+--let SEARCH_PATTERN=RocksDB: Schema mismatch - Table test.t1 is registered in RocksDB but does not have a .frm file
+--source include/search_pattern_in_file.inc
+--let SEARCH_PATTERN=RocksDB: Schema mismatch - Table test.t2 is registered in RocksDB but does not have a .frm file
--source include/search_pattern_in_file.inc
# Now shut down again and rename one the .frm file back and make a copy of it
--exec echo "wait" >$_expect_file_name
shutdown_server 10;
-
+--remove_file $LOG
# Rename the file
--move_file $MYSQLTEST_VARDIR/mysqld.1/data/test/t1.frm.tmp $MYSQLTEST_VARDIR/mysqld.1/data/test/t1.frm
--move_file $MYSQLTEST_VARDIR/mysqld.1/data/test/t2.frm.tmp $MYSQLTEST_VARDIR/mysqld.1/data/test/t2.frm
--copy_file $MYSQLTEST_VARDIR/mysqld.1/data/test/t1.frm $MYSQLTEST_VARDIR/mysqld.1/data/test/t1_dummy.frm
# Attempt to restart the server
---exec echo "restart:--rocksdb_validate_tables=2" >$_expect_file_name
+--exec echo "restart:--rocksdb_validate_tables=2 --log-error=$LOG" >$_expect_file_name
--enable_reconnect
--source include/wait_until_connected_again.inc
@@ -77,7 +86,8 @@ shutdown_server 10;
# We should now have an error message for the second case
--echo "Expect an error that we have an extra .frm file"
---let SEARCH_PATTERN=Schema mismatch
+--let SEARCH_FILE=$LOG
+--let SEARCH_PATTERN=Schema mismatch - A .frm file exists for table test.t1_dummy, but that table is not registered in RocksDB
--source include/search_pattern_in_file.inc
# Shut down an clean up
@@ -89,6 +99,9 @@ shutdown_server 10;
--source include/wait_until_connected_again.inc
--disable_reconnect
+# Remove log file
+--remove_file $LOG
+
--disable_warnings
DROP TABLE t1, t2;
--enable_warnings
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/combinations b/storage/rocksdb/mysql-test/rocksdb_rpl/combinations
index f09d338c357..fe97111940a 100644
--- a/storage/rocksdb/mysql-test/rocksdb_rpl/combinations
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/combinations
@@ -1,2 +1,8 @@
-[row]
+[row-write-committed]
binlog-format=row
+rocksdb_write_policy=write_committed
+
+[row-write-prepared]
+binlog-format=row
+rocksdb_write_policy=write_prepared
+rocksdb_commit_time_batch_for_recovery=on
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_missing_columns_sk_update.result b/storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_missing_columns_sk_update.result
new file mode 100644
index 00000000000..19b0a191a1b
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_missing_columns_sk_update.result
@@ -0,0 +1,62 @@
+include/master-slave.inc
+Warnings:
+Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
+Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
+[connection master]
+set @@sql_log_bin = 0;
+CREATE TABLE `t1` (
+`a` int(10) unsigned NOT NULL DEFAULT '0',
+`b` bigint(20) unsigned NOT NULL DEFAULT '0',
+`c` bigint(20) unsigned NOT NULL DEFAULT '0',
+`d` bigint(20) unsigned NOT NULL DEFAULT '0',
+`e` varbinary(64) DEFAULT NULL,
+`f` int(10) NOT NULL DEFAULT '0',
+`g` int(10) NOT NULL DEFAULT '0',
+`h` int(10) unsigned NOT NULL DEFAULT '0',
+PRIMARY KEY (`a`,`b`),
+KEY `key1` (`a`, `e`(1)),
+KEY `key2` (`a`,`h`)
+) ENGINE=RocksDB;
+set @@sql_log_bin = 1;
+set @@sql_log_bin = 0;
+CREATE TABLE `t1` (
+`a` int(10) unsigned NOT NULL DEFAULT '0',
+`b` bigint(20) unsigned NOT NULL DEFAULT '0',
+`c` bigint(20) unsigned NOT NULL DEFAULT '0',
+`d` bigint(20) unsigned NOT NULL DEFAULT '0',
+`e` varbinary(64) DEFAULT NULL,
+`f` int(10) NOT NULL DEFAULT '0',
+`g` int(10) NOT NULL DEFAULT '0',
+`x` TINYINT(3) UNSIGNED DEFAULT NULL,
+`y` INT(10) DEFAULT NULL,
+`h` int(10) unsigned NOT NULL DEFAULT '0',
+PRIMARY KEY (`a`,`b`),
+KEY `key1` (`a`, `e`(1)),
+KEY `key2` (`a`,`h`)
+) ENGINE=RocksDB;
+set @@sql_log_bin = 1;
+INSERT INTO t1 VALUES (1, 1, 1, 1, 'a', 1, 1, 1);
+SELECT * FROM t1;
+a b c d e f g h
+1 1 1 1 a 1 1 1
+SELECT * FROM t1;
+a b c d e f g x y h
+1 1 1 1 a 1 1 NULL NULL 1
+UPDATE t1 SET h = 10 WHERE h = 1;
+SELECT * FROM t1;
+a b c d e f g h
+1 1 1 1 a 1 1 10
+SELECT * FROM t1;
+a b c d e f g x y h
+1 1 1 1 a 1 1 NULL NULL 10
+SELECT COUNT(*) FROM t1 FORCE INDEX (key1) WHERE h = 10 AND a = 1;
+COUNT(*)
+1
+SELECT COUNT(*) FROM t1 FORCE INDEX (key2) WHERE h = 10 AND a = 1;
+COUNT(*)
+1
+SELECT COUNT(*) FROM t1 FORCE INDEX (PRIMARY) WHERE h = 10 AND a = 1;
+COUNT(*)
+1
+DROP TABLE t1;
+include/rpl_end.inc
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_mts_dependency_unique_key_conflicts.result b/storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_mts_dependency_unique_key_conflicts.result
new file mode 100644
index 00000000000..0eadc7deafe
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_mts_dependency_unique_key_conflicts.result
@@ -0,0 +1,44 @@
+include/master-slave.inc
+Warnings:
+Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
+Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
+[connection master]
+include/stop_slave.inc
+set @save.slave_parallel_workers= @@global.slave_parallel_workers;
+set @save.slave_use_idempotent_for_recovery= @@global.slave_use_idempotent_for_recovery;
+set @save.mts_dependency_replication= @@global.mts_dependency_replication;
+set @save.mts_dependency_order_commits= @@global.mts_dependency_order_commits;
+set @save.debug= @@global.debug;
+set @@global.slave_parallel_workers= 2;
+set @@global.slave_use_idempotent_for_recovery= YES;
+set @@global.mts_dependency_replication= STMT;
+set @@global.mts_dependency_order_commits= false;
+set @@global.debug= '+d,dbug.dep_wait_before_update_execution';
+include/start_slave.inc
+create table t1 (a int primary key, b int unique key) engine = rocksdb;
+insert into t1 values(1, 1);
+include/sync_slave_sql_with_master.inc
+include/stop_slave.inc
+update t1 set b = 2 where a = 1;
+insert into t1 values(2, 1);
+include/start_slave.inc
+set debug_sync="now wait_for signal.reached";
+select * from t1;
+a b
+1 1
+set debug_sync="now signal signal.done";
+include/sync_slave_sql_with_master.inc
+select * from t1;
+a b
+2 1
+1 2
+drop table t1;
+include/sync_slave_sql_with_master.inc
+include/stop_slave.inc
+set @@global.slave_parallel_workers= @save.slave_parallel_workers;
+set @@global.mts_dependency_replication= @save.mts_dependency_replication;
+set @@global.slave_use_idempotent_for_recovery= @save.slave_use_idempotent_for_recovery;
+set @@global.mts_dependency_order_commits= @save.mts_dependency_order_commits;
+set @@global.debug= @save.debug;
+include/start_slave.inc
+include/rpl_end.inc
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_rocksdb_snapshot.result b/storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_rocksdb_snapshot.result
index eb2c6cfcda3..f5e861feddc 100644
--- a/storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_rocksdb_snapshot.result
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_rocksdb_snapshot.result
@@ -23,9 +23,9 @@ CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=rocksdb;
INSERT INTO t1 VALUES(1);
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
START TRANSACTION WITH CONSISTENT SNAPSHOT;
-ERROR HY000: Only REPEATABLE READ isolation level is supported for START TRANSACTION WITH CONSISTENT SNAPSHOT in RocksDB Storage Engine.
+ERROR HY000: Only REPEATABLE READ isolation level is supported for START TRANSACTION WITH CONSISTENT|SHARED|EXISTING SNAPSHOT in RocksDB Storage Engine.
START TRANSACTION WITH CONSISTENT ROCKSDB SNAPSHOT;
-ERROR HY000: Only REPEATABLE READ isolation level is supported for START TRANSACTION WITH CONSISTENT SNAPSHOT in RocksDB Storage Engine.
+ERROR HY000: Only REPEATABLE READ isolation level is supported for START TRANSACTION WITH CONSISTENT|SHARED|EXISTING SNAPSHOT in RocksDB Storage Engine.
ROLLBACK;
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
START TRANSACTION WITH CONSISTENT ROCKSDB SNAPSHOT;
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/disabled.def b/storage/rocksdb/mysql-test/rocksdb_rpl/t/disabled.def
index 956355dceee..1e8c0df0564 100644
--- a/storage/rocksdb/mysql-test/rocksdb_rpl/t/disabled.def
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/disabled.def
@@ -9,6 +9,7 @@ rpl_skip_trx_api_binlog_format : requires @@rpl_skip_tx_api
rpl_ddl_high_priority : DDL commands with HIGH_PRIORITY syntax are not in MariaDB
rpl_gtid_rocksdb_sys_header : MariaDB doesn't support printing "RocksDB: Last MySQL Gtid UUID" into server stderr on startup
singledelete_idempotent_recovery: MariaDB doesn't support --slave-use-idempotent-for-recovery
+rpl_missing_columns_sk_update : Uses log_column_names=ON feature which is only present in FB/MySQL
##
## Tests that do not fit MariaDB's test environment (Functional tests only,
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_wal_corrupt.inc b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_wal_corrupt.inc
index 5e5961f3aef..16ad535ff9e 100644
--- a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_wal_corrupt.inc
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_wal_corrupt.inc
@@ -42,7 +42,7 @@ select * from mysql.slave_gtid_info;
F=`ls -t $slave_data_dir/\#rocksdb/*.log | head -n 1`
SIZE=`stat -c %s $F`
-NEW_SIZE=`expr $SIZE - 10`
+NEW_SIZE=`expr $SIZE - 30`
truncate -s $NEW_SIZE $F
rc=$?
if [[ $rc != 0 ]]; then
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_missing_columns_sk_update.cnf b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_missing_columns_sk_update.cnf
new file mode 100644
index 00000000000..92ed71986fe
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_missing_columns_sk_update.cnf
@@ -0,0 +1,13 @@
+!include include/default_mysqld.cnf
+
+[mysqld.1]
+binlog_row_image = COMPLETE
+log_column_names= ON
+
+[mysqld.2]
+binlog_row_image = COMPLETE
+log_column_names= ON
+
+[ENV]
+SERVER_MYPORT_1= @mysqld.1.port
+SERVER_MYPORT_2= @mysqld.2.port
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_missing_columns_sk_update.test b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_missing_columns_sk_update.test
new file mode 100644
index 00000000000..624f54ac326
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_missing_columns_sk_update.test
@@ -0,0 +1,69 @@
+source include/master-slave.inc;
+source include/have_binlog_format_row.inc;
+
+# Create a table with SKs on master
+connection master;
+set @@sql_log_bin = 0;
+CREATE TABLE `t1` (
+ `a` int(10) unsigned NOT NULL DEFAULT '0',
+ `b` bigint(20) unsigned NOT NULL DEFAULT '0',
+ `c` bigint(20) unsigned NOT NULL DEFAULT '0',
+ `d` bigint(20) unsigned NOT NULL DEFAULT '0',
+ `e` varbinary(64) DEFAULT NULL,
+ `f` int(10) NOT NULL DEFAULT '0',
+ `g` int(10) NOT NULL DEFAULT '0',
+ `h` int(10) unsigned NOT NULL DEFAULT '0',
+ PRIMARY KEY (`a`,`b`),
+ KEY `key1` (`a`, `e`(1)),
+ KEY `key2` (`a`,`h`)
+) ENGINE=RocksDB;
+set @@sql_log_bin = 1;
+
+# Create same table on slaves but with two extra columns in the middle (x, y)
+connection slave;
+set @@sql_log_bin = 0;
+CREATE TABLE `t1` (
+ `a` int(10) unsigned NOT NULL DEFAULT '0',
+ `b` bigint(20) unsigned NOT NULL DEFAULT '0',
+ `c` bigint(20) unsigned NOT NULL DEFAULT '0',
+ `d` bigint(20) unsigned NOT NULL DEFAULT '0',
+ `e` varbinary(64) DEFAULT NULL,
+ `f` int(10) NOT NULL DEFAULT '0',
+ `g` int(10) NOT NULL DEFAULT '0',
+ `x` TINYINT(3) UNSIGNED DEFAULT NULL,
+ `y` INT(10) DEFAULT NULL,
+ `h` int(10) unsigned NOT NULL DEFAULT '0',
+ PRIMARY KEY (`a`,`b`),
+ KEY `key1` (`a`, `e`(1)),
+ KEY `key2` (`a`,`h`)
+) ENGINE=RocksDB;
+set @@sql_log_bin = 1;
+
+# Insert something in the table
+connection master;
+INSERT INTO t1 VALUES (1, 1, 1, 1, 'a', 1, 1, 1);
+SELECT * FROM t1;
+sync_slave_with_master;
+
+connection slave;
+SELECT * FROM t1;
+
+# Update a column that belongs to an SK
+connection master;
+UPDATE t1 SET h = 10 WHERE h = 1;
+SELECT * FROM t1;
+sync_slave_with_master;
+
+# Check if all keys are updated on the slave
+connection slave;
+SELECT * FROM t1;
+SELECT COUNT(*) FROM t1 FORCE INDEX (key1) WHERE h = 10 AND a = 1;
+SELECT COUNT(*) FROM t1 FORCE INDEX (key2) WHERE h = 10 AND a = 1;
+SELECT COUNT(*) FROM t1 FORCE INDEX (PRIMARY) WHERE h = 10 AND a = 1;
+
+# Cleanup
+connection master;
+DROP TABLE t1;
+sync_slave_with_master;
+
+source include/rpl_end.inc;
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_mts_dependency_unique_key_conflicts.test b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_mts_dependency_unique_key_conflicts.test
new file mode 100644
index 00000000000..5869b9a39b9
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_mts_dependency_unique_key_conflicts.test
@@ -0,0 +1,64 @@
+# RocksDB clone of rpl_mts.rpl_mts_dependency_unique_key_conflicts
+source include/have_rocksdb.inc;
+source include/have_debug_sync.inc;
+source include/master-slave.inc;
+
+connection slave;
+source include/stop_slave.inc;
+set @save.slave_parallel_workers= @@global.slave_parallel_workers;
+set @save.slave_use_idempotent_for_recovery= @@global.slave_use_idempotent_for_recovery;
+set @save.mts_dependency_replication= @@global.mts_dependency_replication;
+set @save.mts_dependency_order_commits= @@global.mts_dependency_order_commits;
+set @save.debug= @@global.debug;
+set @@global.slave_parallel_workers= 2;
+set @@global.slave_use_idempotent_for_recovery= YES;
+set @@global.mts_dependency_replication= STMT;
+set @@global.mts_dependency_order_commits= false;
+set @@global.debug= '+d,dbug.dep_wait_before_update_execution';
+source include/start_slave.inc;
+
+connection master;
+create table t1 (a int primary key, b int unique key) engine = rocksdb;
+insert into t1 values(1, 1);
+source include/sync_slave_sql_with_master.inc;
+source include/stop_slave.inc;
+
+connection master;
+update t1 set b = 2 where a = 1; # this will stall on slave due to dbug_sync
+insert into t1 values(2, 1); # this should wait for the update to finish
+
+connection slave;
+source include/start_slave.inc;
+# wait till one of the workers reach the point just before execution of update
+set debug_sync="now wait_for signal.reached";
+
+# wait till the other worker is waiting after executing the table map for the
+# insert
+let $wait_condition=
+ select count(*)= 1 from information_schema.processlist
+ where state = 'Waiting for dependencies to be satisfied';
+source include/wait_condition.inc;
+
+select * from t1;
+set debug_sync="now signal signal.done";
+
+connection master;
+source include/sync_slave_sql_with_master.inc;
+
+connection slave;
+select * from t1;
+
+# Cleanup
+connection master;
+drop table t1;
+source include/sync_slave_sql_with_master.inc;
+connection slave;
+source include/stop_slave.inc;
+set @@global.slave_parallel_workers= @save.slave_parallel_workers;
+set @@global.mts_dependency_replication= @save.mts_dependency_replication;
+set @@global.slave_use_idempotent_for_recovery= @save.slave_use_idempotent_for_recovery;
+set @@global.mts_dependency_order_commits= @save.mts_dependency_order_commits;
+set @@global.debug= @save.debug;
+source include/start_slave.inc;
+
+source include/rpl_end.inc;
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_2pc_crash_recover.test b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_2pc_crash_recover.test
index 3aa006c84be..58b3720904c 100644
--- a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_2pc_crash_recover.test
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_2pc_crash_recover.test
@@ -1,6 +1,7 @@
--source include/have_binlog_format_row.inc
--source include/have_rocksdb.inc
--source include/have_debug.inc
+--source include/not_valgrind.inc
--disable_warnings
DROP TABLE IF EXISTS t1;
diff --git a/storage/rocksdb/mysql-test/rocksdb_stress/combinations b/storage/rocksdb/mysql-test/rocksdb_stress/combinations
new file mode 100644
index 00000000000..b7316c71485
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_stress/combinations
@@ -0,0 +1,5 @@
+[write_committed]
+rocksdb_write_policy=write_committed
+
+[write_prepared]
+rocksdb_write_policy=write_prepared
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_block_cache_size_basic.result b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_block_cache_size_basic.result
index 1cfe5385d5c..b319c39a1cd 100644
--- a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_block_cache_size_basic.result
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_block_cache_size_basic.result
@@ -1,7 +1,85 @@
+CREATE TABLE valid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO valid_values VALUES(65536);
+INSERT INTO valid_values VALUES(1024);
+INSERT INTO valid_values VALUES(1*1024*1024);
+CREATE TABLE invalid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO invalid_values VALUES('\'aaa\'');
+INSERT INTO invalid_values VALUES('\'bbb\'');
+INSERT INTO invalid_values VALUES('\'-1\'');
+INSERT INTO invalid_values VALUES('\'101\'');
+INSERT INTO invalid_values VALUES('\'484436\'');
SET @start_global_value = @@global.ROCKSDB_BLOCK_CACHE_SIZE;
SELECT @start_global_value;
@start_global_value
536870912
-"Trying to set variable @@global.ROCKSDB_BLOCK_CACHE_SIZE to 444. It should fail because it is readonly."
-SET @@global.ROCKSDB_BLOCK_CACHE_SIZE = 444;
-ERROR HY000: Variable 'rocksdb_block_cache_size' is a read only variable
+'# Setting to valid values in global scope#'
+"Trying to set variable @@global.ROCKSDB_BLOCK_CACHE_SIZE to 65536"
+SET @@global.ROCKSDB_BLOCK_CACHE_SIZE = 65536;
+SELECT @@global.ROCKSDB_BLOCK_CACHE_SIZE;
+@@global.ROCKSDB_BLOCK_CACHE_SIZE
+65536
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_BLOCK_CACHE_SIZE = DEFAULT;
+SELECT @@global.ROCKSDB_BLOCK_CACHE_SIZE;
+@@global.ROCKSDB_BLOCK_CACHE_SIZE
+536870912
+"Trying to set variable @@global.ROCKSDB_BLOCK_CACHE_SIZE to 1024"
+SET @@global.ROCKSDB_BLOCK_CACHE_SIZE = 1024;
+SELECT @@global.ROCKSDB_BLOCK_CACHE_SIZE;
+@@global.ROCKSDB_BLOCK_CACHE_SIZE
+1024
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_BLOCK_CACHE_SIZE = DEFAULT;
+SELECT @@global.ROCKSDB_BLOCK_CACHE_SIZE;
+@@global.ROCKSDB_BLOCK_CACHE_SIZE
+536870912
+"Trying to set variable @@global.ROCKSDB_BLOCK_CACHE_SIZE to 1048576"
+SET @@global.ROCKSDB_BLOCK_CACHE_SIZE = 1048576;
+SELECT @@global.ROCKSDB_BLOCK_CACHE_SIZE;
+@@global.ROCKSDB_BLOCK_CACHE_SIZE
+1048576
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_BLOCK_CACHE_SIZE = DEFAULT;
+SELECT @@global.ROCKSDB_BLOCK_CACHE_SIZE;
+@@global.ROCKSDB_BLOCK_CACHE_SIZE
+536870912
+"Trying to set variable @@session.ROCKSDB_BLOCK_CACHE_SIZE to 444. It should fail because it is not session."
+SET @@session.ROCKSDB_BLOCK_CACHE_SIZE = 444;
+ERROR HY000: Variable 'rocksdb_block_cache_size' is a GLOBAL variable and should be set with SET GLOBAL
+'# Testing with invalid values in global scope #'
+"Trying to set variable @@global.ROCKSDB_BLOCK_CACHE_SIZE to 'aaa'"
+SET @@global.ROCKSDB_BLOCK_CACHE_SIZE = 'aaa';
+Got one of the listed errors
+SELECT @@global.ROCKSDB_BLOCK_CACHE_SIZE;
+@@global.ROCKSDB_BLOCK_CACHE_SIZE
+536870912
+"Trying to set variable @@global.ROCKSDB_BLOCK_CACHE_SIZE to 'bbb'"
+SET @@global.ROCKSDB_BLOCK_CACHE_SIZE = 'bbb';
+Got one of the listed errors
+SELECT @@global.ROCKSDB_BLOCK_CACHE_SIZE;
+@@global.ROCKSDB_BLOCK_CACHE_SIZE
+536870912
+"Trying to set variable @@global.ROCKSDB_BLOCK_CACHE_SIZE to '-1'"
+SET @@global.ROCKSDB_BLOCK_CACHE_SIZE = '-1';
+Got one of the listed errors
+SELECT @@global.ROCKSDB_BLOCK_CACHE_SIZE;
+@@global.ROCKSDB_BLOCK_CACHE_SIZE
+536870912
+"Trying to set variable @@global.ROCKSDB_BLOCK_CACHE_SIZE to '101'"
+SET @@global.ROCKSDB_BLOCK_CACHE_SIZE = '101';
+Got one of the listed errors
+SELECT @@global.ROCKSDB_BLOCK_CACHE_SIZE;
+@@global.ROCKSDB_BLOCK_CACHE_SIZE
+536870912
+"Trying to set variable @@global.ROCKSDB_BLOCK_CACHE_SIZE to '484436'"
+SET @@global.ROCKSDB_BLOCK_CACHE_SIZE = '484436';
+Got one of the listed errors
+SELECT @@global.ROCKSDB_BLOCK_CACHE_SIZE;
+@@global.ROCKSDB_BLOCK_CACHE_SIZE
+536870912
+SET @@global.ROCKSDB_BLOCK_CACHE_SIZE = @start_global_value;
+SELECT @@global.ROCKSDB_BLOCK_CACHE_SIZE;
+@@global.ROCKSDB_BLOCK_CACHE_SIZE
+536870912
+DROP TABLE valid_values;
+DROP TABLE invalid_values;
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_bulk_load_allow_sk_basic.result b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_bulk_load_allow_sk_basic.result
new file mode 100644
index 00000000000..c0d09d89c11
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_bulk_load_allow_sk_basic.result
@@ -0,0 +1,100 @@
+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('on');
+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_BULK_LOAD_ALLOW_SK;
+SELECT @start_global_value;
+@start_global_value
+0
+SET @start_session_value = @@session.ROCKSDB_BULK_LOAD_ALLOW_SK;
+SELECT @start_session_value;
+@start_session_value
+0
+'# Setting to valid values in global scope#'
+"Trying to set variable @@global.ROCKSDB_BULK_LOAD_ALLOW_SK to 1"
+SET @@global.ROCKSDB_BULK_LOAD_ALLOW_SK = 1;
+SELECT @@global.ROCKSDB_BULK_LOAD_ALLOW_SK;
+@@global.ROCKSDB_BULK_LOAD_ALLOW_SK
+1
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_BULK_LOAD_ALLOW_SK = DEFAULT;
+SELECT @@global.ROCKSDB_BULK_LOAD_ALLOW_SK;
+@@global.ROCKSDB_BULK_LOAD_ALLOW_SK
+0
+"Trying to set variable @@global.ROCKSDB_BULK_LOAD_ALLOW_SK to 0"
+SET @@global.ROCKSDB_BULK_LOAD_ALLOW_SK = 0;
+SELECT @@global.ROCKSDB_BULK_LOAD_ALLOW_SK;
+@@global.ROCKSDB_BULK_LOAD_ALLOW_SK
+0
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_BULK_LOAD_ALLOW_SK = DEFAULT;
+SELECT @@global.ROCKSDB_BULK_LOAD_ALLOW_SK;
+@@global.ROCKSDB_BULK_LOAD_ALLOW_SK
+0
+"Trying to set variable @@global.ROCKSDB_BULK_LOAD_ALLOW_SK to on"
+SET @@global.ROCKSDB_BULK_LOAD_ALLOW_SK = on;
+SELECT @@global.ROCKSDB_BULK_LOAD_ALLOW_SK;
+@@global.ROCKSDB_BULK_LOAD_ALLOW_SK
+1
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_BULK_LOAD_ALLOW_SK = DEFAULT;
+SELECT @@global.ROCKSDB_BULK_LOAD_ALLOW_SK;
+@@global.ROCKSDB_BULK_LOAD_ALLOW_SK
+0
+'# Setting to valid values in session scope#'
+"Trying to set variable @@session.ROCKSDB_BULK_LOAD_ALLOW_SK to 1"
+SET @@session.ROCKSDB_BULK_LOAD_ALLOW_SK = 1;
+SELECT @@session.ROCKSDB_BULK_LOAD_ALLOW_SK;
+@@session.ROCKSDB_BULK_LOAD_ALLOW_SK
+1
+"Setting the session scope variable back to default"
+SET @@session.ROCKSDB_BULK_LOAD_ALLOW_SK = DEFAULT;
+SELECT @@session.ROCKSDB_BULK_LOAD_ALLOW_SK;
+@@session.ROCKSDB_BULK_LOAD_ALLOW_SK
+0
+"Trying to set variable @@session.ROCKSDB_BULK_LOAD_ALLOW_SK to 0"
+SET @@session.ROCKSDB_BULK_LOAD_ALLOW_SK = 0;
+SELECT @@session.ROCKSDB_BULK_LOAD_ALLOW_SK;
+@@session.ROCKSDB_BULK_LOAD_ALLOW_SK
+0
+"Setting the session scope variable back to default"
+SET @@session.ROCKSDB_BULK_LOAD_ALLOW_SK = DEFAULT;
+SELECT @@session.ROCKSDB_BULK_LOAD_ALLOW_SK;
+@@session.ROCKSDB_BULK_LOAD_ALLOW_SK
+0
+"Trying to set variable @@session.ROCKSDB_BULK_LOAD_ALLOW_SK to on"
+SET @@session.ROCKSDB_BULK_LOAD_ALLOW_SK = on;
+SELECT @@session.ROCKSDB_BULK_LOAD_ALLOW_SK;
+@@session.ROCKSDB_BULK_LOAD_ALLOW_SK
+1
+"Setting the session scope variable back to default"
+SET @@session.ROCKSDB_BULK_LOAD_ALLOW_SK = DEFAULT;
+SELECT @@session.ROCKSDB_BULK_LOAD_ALLOW_SK;
+@@session.ROCKSDB_BULK_LOAD_ALLOW_SK
+0
+'# Testing with invalid values in global scope #'
+"Trying to set variable @@global.ROCKSDB_BULK_LOAD_ALLOW_SK to 'aaa'"
+SET @@global.ROCKSDB_BULK_LOAD_ALLOW_SK = 'aaa';
+Got one of the listed errors
+SELECT @@global.ROCKSDB_BULK_LOAD_ALLOW_SK;
+@@global.ROCKSDB_BULK_LOAD_ALLOW_SK
+0
+"Trying to set variable @@global.ROCKSDB_BULK_LOAD_ALLOW_SK to 'bbb'"
+SET @@global.ROCKSDB_BULK_LOAD_ALLOW_SK = 'bbb';
+Got one of the listed errors
+SELECT @@global.ROCKSDB_BULK_LOAD_ALLOW_SK;
+@@global.ROCKSDB_BULK_LOAD_ALLOW_SK
+0
+SET @@global.ROCKSDB_BULK_LOAD_ALLOW_SK = @start_global_value;
+SELECT @@global.ROCKSDB_BULK_LOAD_ALLOW_SK;
+@@global.ROCKSDB_BULK_LOAD_ALLOW_SK
+0
+SET @@session.ROCKSDB_BULK_LOAD_ALLOW_SK = @start_session_value;
+SELECT @@session.ROCKSDB_BULK_LOAD_ALLOW_SK;
+@@session.ROCKSDB_BULK_LOAD_ALLOW_SK
+0
+DROP TABLE valid_values;
+DROP TABLE invalid_values;
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_commit_time_batch_for_recovery_basic.result b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_commit_time_batch_for_recovery_basic.result
new file mode 100644
index 00000000000..1d409bbedb4
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_commit_time_batch_for_recovery_basic.result
@@ -0,0 +1,121 @@
+CREATE TABLE valid_values (value varchar(255));
+INSERT INTO valid_values VALUES(1);
+INSERT INTO valid_values VALUES(0);
+INSERT INTO valid_values VALUES('on');
+INSERT INTO valid_values VALUES('off');
+CREATE TABLE invalid_values (value varchar(255));
+INSERT INTO invalid_values VALUES('\'aaa\'');
+INSERT INTO invalid_values VALUES('\'bbb\'');
+SET @start_global_value = @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+SELECT @start_global_value;
+@start_global_value
+0
+SET @start_session_value = @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+SELECT @start_session_value;
+@start_session_value
+0
+'# Setting to valid values in global scope#'
+"Trying to set variable @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY to 1"
+SET @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = 1;
+SELECT @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+1
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = DEFAULT;
+SELECT @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+0
+"Trying to set variable @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY to 0"
+SET @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = 0;
+SELECT @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+0
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = DEFAULT;
+SELECT @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+0
+"Trying to set variable @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY to on"
+SET @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = on;
+SELECT @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+1
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = DEFAULT;
+SELECT @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+0
+"Trying to set variable @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY to off"
+SET @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = off;
+SELECT @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+0
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = DEFAULT;
+SELECT @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+0
+'# Setting to valid values in session scope#'
+"Trying to set variable @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY to 1"
+SET @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = 1;
+SELECT @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+1
+"Setting the session scope variable back to default"
+SET @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = DEFAULT;
+SELECT @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+0
+"Trying to set variable @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY to 0"
+SET @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = 0;
+SELECT @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+0
+"Setting the session scope variable back to default"
+SET @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = DEFAULT;
+SELECT @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+0
+"Trying to set variable @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY to on"
+SET @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = on;
+SELECT @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+1
+"Setting the session scope variable back to default"
+SET @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = DEFAULT;
+SELECT @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+0
+"Trying to set variable @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY to off"
+SET @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = off;
+SELECT @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+0
+"Setting the session scope variable back to default"
+SET @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = DEFAULT;
+SELECT @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+0
+'# Testing with invalid values in global scope #'
+"Trying to set variable @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY to 'aaa'"
+SET @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = 'aaa';
+Got one of the listed errors
+SELECT @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+0
+"Trying to set variable @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY to 'bbb'"
+SET @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = 'bbb';
+Got one of the listed errors
+SELECT @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+0
+SET @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = @start_global_value;
+SELECT @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+0
+SET @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = @start_session_value;
+SELECT @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+0
+DROP TABLE valid_values;
+DROP TABLE invalid_values;
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_create_checkpoint_basic.result b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_create_checkpoint_basic.result
index ba280a32ab2..630fa78e933 100644
--- a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_create_checkpoint_basic.result
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_create_checkpoint_basic.result
@@ -12,4 +12,4 @@ SET @@global.ROCKSDB_CREATE_CHECKPOINT = DEFAULT;
SET @@session.ROCKSDB_CREATE_CHECKPOINT = 444;
ERROR HY000: Variable 'rocksdb_create_checkpoint' is a GLOBAL variable and should be set with SET GLOBAL
SET @@global.ROCKSDB_CREATE_CHECKPOINT = @start_value;
-ERROR HY000: Status error 5 received from RocksDB: IO error: While renaming a file to : .tmp: No such file or directory
+ERROR HY000: Got error 4 'Invalid argument: invalid checkpoint directory name' from ROCKSDB
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_debug_manual_compaction_delay_basic.result b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_debug_manual_compaction_delay_basic.result
new file mode 100644
index 00000000000..6c5db01533b
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_debug_manual_compaction_delay_basic.result
@@ -0,0 +1,46 @@
+CREATE TABLE valid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO valid_values VALUES(2400);
+INSERT INTO valid_values VALUES(100000);
+CREATE TABLE invalid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO invalid_values VALUES('\'aaa\'');
+SET @start_global_value = @@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY;
+SELECT @start_global_value;
+@start_global_value
+0
+'# Setting to valid values in global scope#'
+"Trying to set variable @@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY to 2400"
+SET @@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY = 2400;
+SELECT @@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY;
+@@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY
+2400
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY = DEFAULT;
+SELECT @@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY;
+@@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY
+0
+"Trying to set variable @@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY to 100000"
+SET @@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY = 100000;
+SELECT @@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY;
+@@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY
+100000
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY = DEFAULT;
+SELECT @@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY;
+@@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY
+0
+"Trying to set variable @@session.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY to 444. It should fail because it is not session."
+SET @@session.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY = 444;
+ERROR HY000: Variable 'rocksdb_debug_manual_compaction_delay' is a GLOBAL variable and should be set with SET GLOBAL
+'# Testing with invalid values in global scope #'
+"Trying to set variable @@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY to 'aaa'"
+SET @@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY = 'aaa';
+Got one of the listed errors
+SELECT @@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY;
+@@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY
+0
+SET @@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY = @start_global_value;
+SELECT @@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY;
+@@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY
+0
+DROP TABLE valid_values;
+DROP TABLE invalid_values;
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_error_on_suboptimal_collation_basic.result b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_error_on_suboptimal_collation_basic.result
new file mode 100644
index 00000000000..e10583bff09
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_error_on_suboptimal_collation_basic.result
@@ -0,0 +1,7 @@
+SET @start_global_value = @@global.ROCKSDB_ERROR_ON_SUBOPTIMAL_COLLATION;
+SELECT @start_global_value;
+@start_global_value
+1
+"Trying to set variable @@global.ROCKSDB_ERROR_ON_SUBOPTIMAL_COLLATION to 444. It should fail because it is readonly."
+SET @@global.ROCKSDB_ERROR_ON_SUBOPTIMAL_COLLATION = 444;
+ERROR HY000: Variable 'rocksdb_error_on_suboptimal_collation' is a read only variable
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_manual_compaction_threads_basic.result b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_manual_compaction_threads_basic.result
new file mode 100644
index 00000000000..3d599e1768e
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_manual_compaction_threads_basic.result
@@ -0,0 +1,93 @@
+CREATE TABLE valid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO valid_values VALUES(0);
+INSERT INTO valid_values VALUES(1);
+INSERT INTO valid_values VALUES(99);
+CREATE TABLE invalid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO invalid_values VALUES('\'aaa\'');
+SET @start_global_value = @@global.ROCKSDB_MANUAL_COMPACTION_THREADS;
+SELECT @start_global_value;
+@start_global_value
+0
+SET @start_session_value = @@session.ROCKSDB_MANUAL_COMPACTION_THREADS;
+SELECT @start_session_value;
+@start_session_value
+0
+'# Setting to valid values in global scope#'
+"Trying to set variable @@global.ROCKSDB_MANUAL_COMPACTION_THREADS to 0"
+SET @@global.ROCKSDB_MANUAL_COMPACTION_THREADS = 0;
+SELECT @@global.ROCKSDB_MANUAL_COMPACTION_THREADS;
+@@global.ROCKSDB_MANUAL_COMPACTION_THREADS
+0
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_MANUAL_COMPACTION_THREADS = DEFAULT;
+SELECT @@global.ROCKSDB_MANUAL_COMPACTION_THREADS;
+@@global.ROCKSDB_MANUAL_COMPACTION_THREADS
+0
+"Trying to set variable @@global.ROCKSDB_MANUAL_COMPACTION_THREADS to 1"
+SET @@global.ROCKSDB_MANUAL_COMPACTION_THREADS = 1;
+SELECT @@global.ROCKSDB_MANUAL_COMPACTION_THREADS;
+@@global.ROCKSDB_MANUAL_COMPACTION_THREADS
+1
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_MANUAL_COMPACTION_THREADS = DEFAULT;
+SELECT @@global.ROCKSDB_MANUAL_COMPACTION_THREADS;
+@@global.ROCKSDB_MANUAL_COMPACTION_THREADS
+0
+"Trying to set variable @@global.ROCKSDB_MANUAL_COMPACTION_THREADS to 99"
+SET @@global.ROCKSDB_MANUAL_COMPACTION_THREADS = 99;
+SELECT @@global.ROCKSDB_MANUAL_COMPACTION_THREADS;
+@@global.ROCKSDB_MANUAL_COMPACTION_THREADS
+99
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_MANUAL_COMPACTION_THREADS = DEFAULT;
+SELECT @@global.ROCKSDB_MANUAL_COMPACTION_THREADS;
+@@global.ROCKSDB_MANUAL_COMPACTION_THREADS
+0
+'# Setting to valid values in session scope#'
+"Trying to set variable @@session.ROCKSDB_MANUAL_COMPACTION_THREADS to 0"
+SET @@session.ROCKSDB_MANUAL_COMPACTION_THREADS = 0;
+SELECT @@session.ROCKSDB_MANUAL_COMPACTION_THREADS;
+@@session.ROCKSDB_MANUAL_COMPACTION_THREADS
+0
+"Setting the session scope variable back to default"
+SET @@session.ROCKSDB_MANUAL_COMPACTION_THREADS = DEFAULT;
+SELECT @@session.ROCKSDB_MANUAL_COMPACTION_THREADS;
+@@session.ROCKSDB_MANUAL_COMPACTION_THREADS
+0
+"Trying to set variable @@session.ROCKSDB_MANUAL_COMPACTION_THREADS to 1"
+SET @@session.ROCKSDB_MANUAL_COMPACTION_THREADS = 1;
+SELECT @@session.ROCKSDB_MANUAL_COMPACTION_THREADS;
+@@session.ROCKSDB_MANUAL_COMPACTION_THREADS
+1
+"Setting the session scope variable back to default"
+SET @@session.ROCKSDB_MANUAL_COMPACTION_THREADS = DEFAULT;
+SELECT @@session.ROCKSDB_MANUAL_COMPACTION_THREADS;
+@@session.ROCKSDB_MANUAL_COMPACTION_THREADS
+0
+"Trying to set variable @@session.ROCKSDB_MANUAL_COMPACTION_THREADS to 99"
+SET @@session.ROCKSDB_MANUAL_COMPACTION_THREADS = 99;
+SELECT @@session.ROCKSDB_MANUAL_COMPACTION_THREADS;
+@@session.ROCKSDB_MANUAL_COMPACTION_THREADS
+99
+"Setting the session scope variable back to default"
+SET @@session.ROCKSDB_MANUAL_COMPACTION_THREADS = DEFAULT;
+SELECT @@session.ROCKSDB_MANUAL_COMPACTION_THREADS;
+@@session.ROCKSDB_MANUAL_COMPACTION_THREADS
+0
+'# Testing with invalid values in global scope #'
+"Trying to set variable @@global.ROCKSDB_MANUAL_COMPACTION_THREADS to 'aaa'"
+SET @@global.ROCKSDB_MANUAL_COMPACTION_THREADS = 'aaa';
+Got one of the listed errors
+SELECT @@global.ROCKSDB_MANUAL_COMPACTION_THREADS;
+@@global.ROCKSDB_MANUAL_COMPACTION_THREADS
+0
+SET @@global.ROCKSDB_MANUAL_COMPACTION_THREADS = @start_global_value;
+SELECT @@global.ROCKSDB_MANUAL_COMPACTION_THREADS;
+@@global.ROCKSDB_MANUAL_COMPACTION_THREADS
+0
+SET @@session.ROCKSDB_MANUAL_COMPACTION_THREADS = @start_session_value;
+SELECT @@session.ROCKSDB_MANUAL_COMPACTION_THREADS;
+@@session.ROCKSDB_MANUAL_COMPACTION_THREADS
+0
+DROP TABLE valid_values;
+DROP TABLE invalid_values;
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_max_manifest_file_size_basic.result b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_max_manifest_file_size_basic.result
index 27cddc9f60a..45330b82702 100644
--- a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_max_manifest_file_size_basic.result
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_max_manifest_file_size_basic.result
@@ -1,7 +1,7 @@
SET @start_global_value = @@global.ROCKSDB_MAX_MANIFEST_FILE_SIZE;
SELECT @start_global_value;
@start_global_value
-18446744073709551615
+1073741824
"Trying to set variable @@global.ROCKSDB_MAX_MANIFEST_FILE_SIZE to 444. It should fail because it is readonly."
SET @@global.ROCKSDB_MAX_MANIFEST_FILE_SIZE = 444;
ERROR HY000: Variable 'rocksdb_max_manifest_file_size' is a read only variable
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_max_manual_compactions_basic.result b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_max_manual_compactions_basic.result
new file mode 100644
index 00000000000..815506ccac8
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_max_manual_compactions_basic.result
@@ -0,0 +1,57 @@
+CREATE TABLE valid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO valid_values VALUES(1);
+INSERT INTO valid_values VALUES(1024);
+INSERT INTO valid_values VALUES(512*1024*1024);
+CREATE TABLE invalid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO invalid_values VALUES('\'aaa\'');
+SET @start_global_value = @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS;
+SELECT @start_global_value;
+@start_global_value
+10
+'# Setting to valid values in global scope#'
+"Trying to set variable @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS to 1"
+SET @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS = 1;
+SELECT @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS;
+@@global.ROCKSDB_MAX_MANUAL_COMPACTIONS
+1
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS = DEFAULT;
+SELECT @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS;
+@@global.ROCKSDB_MAX_MANUAL_COMPACTIONS
+10
+"Trying to set variable @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS to 1024"
+SET @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS = 1024;
+SELECT @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS;
+@@global.ROCKSDB_MAX_MANUAL_COMPACTIONS
+1024
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS = DEFAULT;
+SELECT @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS;
+@@global.ROCKSDB_MAX_MANUAL_COMPACTIONS
+10
+"Trying to set variable @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS to 536870912"
+SET @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS = 536870912;
+SELECT @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS;
+@@global.ROCKSDB_MAX_MANUAL_COMPACTIONS
+536870912
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS = DEFAULT;
+SELECT @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS;
+@@global.ROCKSDB_MAX_MANUAL_COMPACTIONS
+10
+"Trying to set variable @@session.ROCKSDB_MAX_MANUAL_COMPACTIONS to 444. It should fail because it is not session."
+SET @@session.ROCKSDB_MAX_MANUAL_COMPACTIONS = 444;
+ERROR HY000: Variable 'rocksdb_max_manual_compactions' is a GLOBAL variable and should be set with SET GLOBAL
+'# Testing with invalid values in global scope #'
+"Trying to set variable @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS to 'aaa'"
+SET @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS = 'aaa';
+Got one of the listed errors
+SELECT @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS;
+@@global.ROCKSDB_MAX_MANUAL_COMPACTIONS
+10
+SET @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS = @start_global_value;
+SELECT @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS;
+@@global.ROCKSDB_MAX_MANUAL_COMPACTIONS
+10
+DROP TABLE valid_values;
+DROP TABLE invalid_values;
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_max_row_locks_basic.result b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_max_row_locks_basic.result
index c925a68d4ed..b195df092dc 100644
--- a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_max_row_locks_basic.result
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_max_row_locks_basic.result
@@ -1,6 +1,7 @@
CREATE TABLE valid_values (value varchar(255)) ENGINE=myisam;
INSERT INTO valid_values VALUES(1);
INSERT INTO valid_values VALUES(1024);
+INSERT INTO valid_values VALUES(512*1024*1024);
CREATE TABLE invalid_values (value varchar(255)) ENGINE=myisam;
INSERT INTO invalid_values VALUES('\'aaa\'');
SET @start_global_value = @@global.ROCKSDB_MAX_ROW_LOCKS;
@@ -32,6 +33,16 @@ SET @@global.ROCKSDB_MAX_ROW_LOCKS = DEFAULT;
SELECT @@global.ROCKSDB_MAX_ROW_LOCKS;
@@global.ROCKSDB_MAX_ROW_LOCKS
1048576
+"Trying to set variable @@global.ROCKSDB_MAX_ROW_LOCKS to 536870912"
+SET @@global.ROCKSDB_MAX_ROW_LOCKS = 536870912;
+SELECT @@global.ROCKSDB_MAX_ROW_LOCKS;
+@@global.ROCKSDB_MAX_ROW_LOCKS
+536870912
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_MAX_ROW_LOCKS = DEFAULT;
+SELECT @@global.ROCKSDB_MAX_ROW_LOCKS;
+@@global.ROCKSDB_MAX_ROW_LOCKS
+1048576
'# Setting to valid values in session scope#'
"Trying to set variable @@session.ROCKSDB_MAX_ROW_LOCKS to 1"
SET @@session.ROCKSDB_MAX_ROW_LOCKS = 1;
@@ -53,6 +64,16 @@ SET @@session.ROCKSDB_MAX_ROW_LOCKS = DEFAULT;
SELECT @@session.ROCKSDB_MAX_ROW_LOCKS;
@@session.ROCKSDB_MAX_ROW_LOCKS
1048576
+"Trying to set variable @@session.ROCKSDB_MAX_ROW_LOCKS to 536870912"
+SET @@session.ROCKSDB_MAX_ROW_LOCKS = 536870912;
+SELECT @@session.ROCKSDB_MAX_ROW_LOCKS;
+@@session.ROCKSDB_MAX_ROW_LOCKS
+536870912
+"Setting the session scope variable back to default"
+SET @@session.ROCKSDB_MAX_ROW_LOCKS = DEFAULT;
+SELECT @@session.ROCKSDB_MAX_ROW_LOCKS;
+@@session.ROCKSDB_MAX_ROW_LOCKS
+1048576
'# Testing with invalid values in global scope #'
"Trying to set variable @@global.ROCKSDB_MAX_ROW_LOCKS to 'aaa'"
SET @@global.ROCKSDB_MAX_ROW_LOCKS = 'aaa';
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_stats_recalc_rate_basic.result b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_stats_recalc_rate_basic.result
new file mode 100644
index 00000000000..4f337b84e3c
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_stats_recalc_rate_basic.result
@@ -0,0 +1,53 @@
+CREATE TABLE valid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO valid_values VALUES(100);
+INSERT INTO valid_values VALUES(1);
+CREATE TABLE invalid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO invalid_values VALUES('\'aaa\'');
+INSERT INTO invalid_values VALUES('\'123\'');
+SET @start_global_value = @@global.ROCKSDB_STATS_RECALC_RATE;
+SELECT @start_global_value;
+@start_global_value
+0
+'# Setting to valid values in global scope#'
+"Trying to set variable @@global.ROCKSDB_STATS_RECALC_RATE to 100"
+SET @@global.ROCKSDB_STATS_RECALC_RATE = 100;
+SELECT @@global.ROCKSDB_STATS_RECALC_RATE;
+@@global.ROCKSDB_STATS_RECALC_RATE
+100
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_STATS_RECALC_RATE = DEFAULT;
+SELECT @@global.ROCKSDB_STATS_RECALC_RATE;
+@@global.ROCKSDB_STATS_RECALC_RATE
+0
+"Trying to set variable @@global.ROCKSDB_STATS_RECALC_RATE to 1"
+SET @@global.ROCKSDB_STATS_RECALC_RATE = 1;
+SELECT @@global.ROCKSDB_STATS_RECALC_RATE;
+@@global.ROCKSDB_STATS_RECALC_RATE
+1
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_STATS_RECALC_RATE = DEFAULT;
+SELECT @@global.ROCKSDB_STATS_RECALC_RATE;
+@@global.ROCKSDB_STATS_RECALC_RATE
+0
+"Trying to set variable @@session.ROCKSDB_STATS_RECALC_RATE to 444. It should fail because it is not session."
+SET @@session.ROCKSDB_STATS_RECALC_RATE = 444;
+ERROR HY000: Variable 'rocksdb_stats_recalc_rate' is a GLOBAL variable and should be set with SET GLOBAL
+'# Testing with invalid values in global scope #'
+"Trying to set variable @@global.ROCKSDB_STATS_RECALC_RATE to 'aaa'"
+SET @@global.ROCKSDB_STATS_RECALC_RATE = 'aaa';
+Got one of the listed errors
+SELECT @@global.ROCKSDB_STATS_RECALC_RATE;
+@@global.ROCKSDB_STATS_RECALC_RATE
+0
+"Trying to set variable @@global.ROCKSDB_STATS_RECALC_RATE to '123'"
+SET @@global.ROCKSDB_STATS_RECALC_RATE = '123';
+Got one of the listed errors
+SELECT @@global.ROCKSDB_STATS_RECALC_RATE;
+@@global.ROCKSDB_STATS_RECALC_RATE
+0
+SET @@global.ROCKSDB_STATS_RECALC_RATE = @start_global_value;
+SELECT @@global.ROCKSDB_STATS_RECALC_RATE;
+@@global.ROCKSDB_STATS_RECALC_RATE
+0
+DROP TABLE valid_values;
+DROP TABLE invalid_values;
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_write_batch_max_bytes_basic.result b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_write_batch_max_bytes_basic.result
index af4da8177d4..8f6d91b2780 100644
--- a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_write_batch_max_bytes_basic.result
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_write_batch_max_bytes_basic.result
@@ -4,12 +4,12 @@ set session rocksdb_write_batch_max_bytes = 1000;
insert into t values (1), (2), (3), (4), (5);
set session rocksdb_write_batch_max_bytes = 10;
insert into t values (1), (2), (3), (4), (5);
-ERROR HY000: Status error 10 received from RocksDB: Operation aborted: Memory limit reached
+ERROR HY000: Got error 10 'Operation aborted: Memory limit reached' from ROCKSDB
set session rocksdb_write_batch_max_bytes = 0;
insert into t values (1), (2), (3), (4), (5);
set session rocksdb_write_batch_max_bytes = 10;
begin;
insert into t values (1), (2), (3), (4), (5);
-ERROR HY000: Status error 10 received from RocksDB: Operation aborted: Memory limit reached
+ERROR HY000: Got error 10 'Operation aborted: Memory limit reached' from ROCKSDB
rollback;
drop table t;
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_write_policy_basic.result b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_write_policy_basic.result
new file mode 100644
index 00000000000..58e040e05f1
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_write_policy_basic.result
@@ -0,0 +1,15 @@
+CREATE TABLE valid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO valid_values VALUES("write_committed");
+INSERT INTO valid_values VALUES("write_prepared");
+INSERT INTO valid_values VALUES("write_unprepared");
+CREATE TABLE invalid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO invalid_values VALUES('\'aaa\'');
+SET @start_global_value = @@global.ROCKSDB_WRITE_POLICY;
+SELECT @start_global_value;
+@start_global_value
+write_committed
+"Trying to set variable @@global.ROCKSDB_WRITE_POLICY to 444. It should fail because it is readonly."
+SET @@global.ROCKSDB_WRITE_POLICY = 444;
+ERROR HY000: Variable 'rocksdb_write_policy' is a read only variable
+DROP TABLE valid_values;
+DROP TABLE invalid_values;
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_block_cache_size_basic.test b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_block_cache_size_basic.test
index 39688e63556..8d3bab4e5ec 100644
--- a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_block_cache_size_basic.test
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_block_cache_size_basic.test
@@ -1,7 +1,21 @@
--source include/have_rocksdb.inc
+CREATE TABLE valid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO valid_values VALUES(65536);
+INSERT INTO valid_values VALUES(1024);
+INSERT INTO valid_values VALUES(1*1024*1024);
+
+CREATE TABLE invalid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO invalid_values VALUES('\'aaa\'');
+INSERT INTO invalid_values VALUES('\'bbb\'');
+INSERT INTO invalid_values VALUES('\'-1\'');
+INSERT INTO invalid_values VALUES('\'101\'');
+INSERT INTO invalid_values VALUES('\'484436\'');
+
--let $sys_var=ROCKSDB_BLOCK_CACHE_SIZE
---let $read_only=1
+--let $read_only=0
--let $session=0
--source include/rocksdb_sys_var.inc
+DROP TABLE valid_values;
+DROP TABLE invalid_values;
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_bulk_load_allow_sk_basic.test b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_bulk_load_allow_sk_basic.test
new file mode 100644
index 00000000000..14e5f38b335
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_bulk_load_allow_sk_basic.test
@@ -0,0 +1,18 @@
+--source include/have_rocksdb.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('on');
+
+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_BULK_LOAD_ALLOW_SK
+--let $read_only=0
+--let $session=1
+--source ../include/rocksdb_sys_var.inc
+
+DROP TABLE valid_values;
+DROP TABLE invalid_values;
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_commit_time_batch_for_recovery_basic.test b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_commit_time_batch_for_recovery_basic.test
new file mode 100644
index 00000000000..0d36e0a173d
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_commit_time_batch_for_recovery_basic.test
@@ -0,0 +1,20 @@
+--source include/have_rocksdb.inc
+
+CREATE TABLE valid_values (value varchar(255));
+INSERT INTO valid_values VALUES(1);
+INSERT INTO valid_values VALUES(0);
+INSERT INTO valid_values VALUES('on');
+INSERT INTO valid_values VALUES('off');
+
+CREATE TABLE invalid_values (value varchar(255));
+INSERT INTO invalid_values VALUES('\'aaa\'');
+INSERT INTO invalid_values VALUES('\'bbb\'');
+
+--let $sys_var=ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+--let $read_only=0
+--let $session=1
+--let $sticky=1
+--source ../include/rocksdb_sys_var.inc
+
+DROP TABLE valid_values;
+DROP TABLE invalid_values;
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_create_checkpoint_basic.test b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_create_checkpoint_basic.test
index a53df21524f..32d4a6a23bc 100644
--- a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_create_checkpoint_basic.test
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_create_checkpoint_basic.test
@@ -21,7 +21,7 @@
# Set back to original value
# validate that DEFAULT causes failure in creating checkpoint since
# DEFAULT == ''
---error ER_RDB_STATUS_GENERAL
+--error ER_GET_ERRMSG
--eval SET @@global.ROCKSDB_CREATE_CHECKPOINT = @start_value
# clean up
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_debug_manual_compaction_delay_basic.test b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_debug_manual_compaction_delay_basic.test
new file mode 100644
index 00000000000..518c284c0cf
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_debug_manual_compaction_delay_basic.test
@@ -0,0 +1,16 @@
+--source include/have_rocksdb.inc
+
+CREATE TABLE valid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO valid_values VALUES(2400);
+INSERT INTO valid_values VALUES(100000);
+
+CREATE TABLE invalid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO invalid_values VALUES('\'aaa\'');
+
+--let $sys_var=ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY
+--let $read_only=0
+--let $session=0
+--source ../include/rocksdb_sys_var.inc
+
+DROP TABLE valid_values;
+DROP TABLE invalid_values;
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_error_on_suboptimal_collation_basic.test b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_error_on_suboptimal_collation_basic.test
new file mode 100644
index 00000000000..9278fa31933
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_error_on_suboptimal_collation_basic.test
@@ -0,0 +1,6 @@
+--source include/have_rocksdb.inc
+
+--let $sys_var=ROCKSDB_ERROR_ON_SUBOPTIMAL_COLLATION
+--let $read_only=1
+--let $session=0
+--source ../include/rocksdb_sys_var.inc
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_manual_compaction_threads_basic.test b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_manual_compaction_threads_basic.test
new file mode 100644
index 00000000000..4f166a9ca8e
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_manual_compaction_threads_basic.test
@@ -0,0 +1,17 @@
+--source include/have_rocksdb.inc
+
+CREATE TABLE valid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO valid_values VALUES(0);
+INSERT INTO valid_values VALUES(1);
+INSERT INTO valid_values VALUES(99);
+
+CREATE TABLE invalid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO invalid_values VALUES('\'aaa\'');
+
+--let $sys_var=ROCKSDB_MANUAL_COMPACTION_THREADS
+--let $read_only=0
+--let $session=1
+--source ../include/rocksdb_sys_var.inc
+
+DROP TABLE valid_values;
+DROP TABLE invalid_values;
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_max_manual_compactions_basic.test b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_max_manual_compactions_basic.test
new file mode 100644
index 00000000000..1c66316858b
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_max_manual_compactions_basic.test
@@ -0,0 +1,17 @@
+--source include/have_rocksdb.inc
+
+CREATE TABLE valid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO valid_values VALUES(1);
+INSERT INTO valid_values VALUES(1024);
+INSERT INTO valid_values VALUES(512*1024*1024);
+
+CREATE TABLE invalid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO invalid_values VALUES('\'aaa\'');
+
+--let $sys_var=ROCKSDB_MAX_MANUAL_COMPACTIONS
+--let $read_only=0
+--let $session=0
+--source ../include/rocksdb_sys_var.inc
+
+DROP TABLE valid_values;
+DROP TABLE invalid_values;
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_max_row_locks_basic.test b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_max_row_locks_basic.test
index 4eb00329cf2..8a26ae91411 100644
--- a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_max_row_locks_basic.test
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_max_row_locks_basic.test
@@ -3,6 +3,7 @@
CREATE TABLE valid_values (value varchar(255)) ENGINE=myisam;
INSERT INTO valid_values VALUES(1);
INSERT INTO valid_values VALUES(1024);
+INSERT INTO valid_values VALUES(512*1024*1024);
CREATE TABLE invalid_values (value varchar(255)) ENGINE=myisam;
INSERT INTO invalid_values VALUES('\'aaa\'');
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_stats_recalc_rate_basic.test b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_stats_recalc_rate_basic.test
new file mode 100644
index 00000000000..a3b9059b2b1
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_stats_recalc_rate_basic.test
@@ -0,0 +1,17 @@
+--source include/have_rocksdb.inc
+
+CREATE TABLE valid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO valid_values VALUES(100);
+INSERT INTO valid_values VALUES(1);
+
+CREATE TABLE invalid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO invalid_values VALUES('\'aaa\'');
+INSERT INTO invalid_values VALUES('\'123\'');
+
+--let $sys_var=ROCKSDB_STATS_RECALC_RATE
+--let $read_only=0
+--let $session=0
+--source ../include/rocksdb_sys_var.inc
+
+DROP TABLE valid_values;
+DROP TABLE invalid_values;
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_write_batch_max_bytes_basic.test b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_write_batch_max_bytes_basic.test
index 295d8e1594b..40d22373fbe 100644
--- a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_write_batch_max_bytes_basic.test
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_write_batch_max_bytes_basic.test
@@ -10,7 +10,7 @@ insert into t values (1), (2), (3), (4), (5);
set session rocksdb_write_batch_max_bytes = 10;
---error ER_RDB_STATUS_GENERAL
+--error ER_GET_ERRMSG
insert into t values (1), (2), (3), (4), (5);
set session rocksdb_write_batch_max_bytes = 0;
@@ -19,7 +19,7 @@ insert into t values (1), (2), (3), (4), (5);
set session rocksdb_write_batch_max_bytes = 10;
begin;
---error ER_RDB_STATUS_GENERAL
+--error ER_GET_ERRMSG
insert into t values (1), (2), (3), (4), (5);
rollback;
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_write_policy_basic.test b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_write_policy_basic.test
new file mode 100644
index 00000000000..720b9d67378
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_write_policy_basic.test
@@ -0,0 +1,17 @@
+--source include/have_rocksdb.inc
+
+CREATE TABLE valid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO valid_values VALUES("write_committed");
+INSERT INTO valid_values VALUES("write_prepared");
+INSERT INTO valid_values VALUES("write_unprepared");
+
+CREATE TABLE invalid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO invalid_values VALUES('\'aaa\'');
+
+--let $sys_var=ROCKSDB_WRITE_POLICY
+--let $read_only=1
+--let $session=0
+--source ../include/rocksdb_sys_var.inc
+
+DROP TABLE valid_values;
+DROP TABLE invalid_values;
diff --git a/storage/rocksdb/properties_collector.cc b/storage/rocksdb/properties_collector.cc
index 92396b23f7e..8bc4f34691f 100644
--- a/storage/rocksdb/properties_collector.cc
+++ b/storage/rocksdb/properties_collector.cc
@@ -54,7 +54,7 @@ Rdb_tbl_prop_coll::Rdb_tbl_prop_coll(Rdb_ddl_manager *const ddl_manager,
: m_cf_id(cf_id), m_ddl_manager(ddl_manager), m_last_stats(nullptr),
m_rows(0l), m_window_pos(0l), m_deleted_rows(0l), m_max_deleted_rows(0l),
m_file_size(0), m_params(params),
- m_cardinality_collector(table_stats_sampling_pct) {
+ m_cardinality_collector(table_stats_sampling_pct), m_recorded(false) {
DBUG_ASSERT(ddl_manager != nullptr);
m_deleted_rows_window.resize(m_params.m_window, false);
@@ -210,28 +210,31 @@ Rdb_tbl_prop_coll::Finish(rocksdb::UserCollectedProperties *const properties) {
num_sst_entry_other += it->m_entry_others;
}
- if (num_sst_entry_put > 0) {
- rocksdb_num_sst_entry_put += num_sst_entry_put;
- }
+ if (!m_recorded) {
+ if (num_sst_entry_put > 0) {
+ rocksdb_num_sst_entry_put += num_sst_entry_put;
+ }
- if (num_sst_entry_delete > 0) {
- rocksdb_num_sst_entry_delete += num_sst_entry_delete;
- }
+ if (num_sst_entry_delete > 0) {
+ rocksdb_num_sst_entry_delete += num_sst_entry_delete;
+ }
- if (num_sst_entry_singledelete > 0) {
- rocksdb_num_sst_entry_singledelete += num_sst_entry_singledelete;
- }
+ if (num_sst_entry_singledelete > 0) {
+ rocksdb_num_sst_entry_singledelete += num_sst_entry_singledelete;
+ }
- if (num_sst_entry_merge > 0) {
- rocksdb_num_sst_entry_merge += num_sst_entry_merge;
- }
+ if (num_sst_entry_merge > 0) {
+ rocksdb_num_sst_entry_merge += num_sst_entry_merge;
+ }
- if (num_sst_entry_other > 0) {
- rocksdb_num_sst_entry_other += num_sst_entry_other;
- }
+ if (num_sst_entry_other > 0) {
+ rocksdb_num_sst_entry_other += num_sst_entry_other;
+ }
- for (Rdb_index_stats &stat : m_stats) {
- m_cardinality_collector.AdjustStats(&stat);
+ for (Rdb_index_stats &stat : m_stats) {
+ m_cardinality_collector.AdjustStats(&stat);
+ }
+ m_recorded = true;
}
properties->insert({INDEXSTATS_KEY, Rdb_index_stats::materialize(m_stats)});
return rocksdb::Status::OK();
@@ -441,15 +444,8 @@ void Rdb_index_stats::merge(const Rdb_index_stats &s, const bool &increment,
m_entry_single_deletes += s.m_entry_single_deletes;
m_entry_merges += s.m_entry_merges;
m_entry_others += s.m_entry_others;
- if (s.m_distinct_keys_per_prefix.size() > 0) {
- for (i = 0; i < s.m_distinct_keys_per_prefix.size(); i++) {
- m_distinct_keys_per_prefix[i] += s.m_distinct_keys_per_prefix[i];
- }
- } else {
- for (i = 0; i < m_distinct_keys_per_prefix.size(); i++) {
- m_distinct_keys_per_prefix[i] +=
- s.m_rows >> (m_distinct_keys_per_prefix.size() - i - 1);
- }
+ for (i = 0; i < s.m_distinct_keys_per_prefix.size(); i++) {
+ m_distinct_keys_per_prefix[i] += s.m_distinct_keys_per_prefix[i];
}
} else {
m_rows -= s.m_rows;
@@ -460,15 +456,8 @@ void Rdb_index_stats::merge(const Rdb_index_stats &s, const bool &increment,
m_entry_single_deletes -= s.m_entry_single_deletes;
m_entry_merges -= s.m_entry_merges;
m_entry_others -= s.m_entry_others;
- if (s.m_distinct_keys_per_prefix.size() > 0) {
- for (i = 0; i < s.m_distinct_keys_per_prefix.size(); i++) {
- m_distinct_keys_per_prefix[i] -= s.m_distinct_keys_per_prefix[i];
- }
- } else {
- for (i = 0; i < m_distinct_keys_per_prefix.size(); i++) {
- m_distinct_keys_per_prefix[i] -=
- s.m_rows >> (m_distinct_keys_per_prefix.size() - i - 1);
- }
+ for (i = 0; i < s.m_distinct_keys_per_prefix.size(); i++) {
+ m_distinct_keys_per_prefix[i] -= s.m_distinct_keys_per_prefix[i];
}
}
}
diff --git a/storage/rocksdb/properties_collector.h b/storage/rocksdb/properties_collector.h
index 1441d893420..c4a48265a50 100644
--- a/storage/rocksdb/properties_collector.h
+++ b/storage/rocksdb/properties_collector.h
@@ -118,7 +118,7 @@ public:
const rocksdb::Slice &value,
rocksdb::EntryType type,
rocksdb::SequenceNumber seq,
- uint64_t file_size);
+ uint64_t file_size) override;
virtual rocksdb::Status
Finish(rocksdb::UserCollectedProperties *properties) override;
@@ -164,6 +164,7 @@ private:
uint64_t m_file_size;
Rdb_compact_params m_params;
Rdb_tbl_card_coll m_cardinality_collector;
+ bool m_recorded;
};
class Rdb_tbl_prop_coll_factory
diff --git a/storage/rocksdb/rdb_cf_options.cc b/storage/rocksdb/rdb_cf_options.cc
index 4d97ab8058d..befcd3c0829 100644
--- a/storage/rocksdb/rdb_cf_options.cc
+++ b/storage/rocksdb/rdb_cf_options.cc
@@ -334,8 +334,6 @@ Rdb_cf_options::get_cf_merge_operator(const std::string &cf_name) {
void Rdb_cf_options::get_cf_options(const std::string &cf_name,
rocksdb::ColumnFamilyOptions *const opts) {
- DBUG_ASSERT(opts != nullptr);
-
*opts = m_default_cf_opts;
get(cf_name, opts);
diff --git a/storage/rocksdb/rdb_comparator.h b/storage/rocksdb/rdb_comparator.h
index 47b83abc70a..963a8615c6b 100644
--- a/storage/rocksdb/rdb_comparator.h
+++ b/storage/rocksdb/rdb_comparator.h
@@ -41,27 +41,9 @@ public:
Rdb_pk_comparator &operator=(const Rdb_pk_comparator &) = delete;
Rdb_pk_comparator() = default;
- static int bytewise_compare(const rocksdb::Slice &a,
- const rocksdb::Slice &b) {
- const size_t a_size = a.size();
- const size_t b_size = b.size();
- const size_t len = (a_size < b_size) ? a_size : b_size;
- int res;
-
- if ((res = memcmp(a.data(), b.data(), len)))
- return res;
-
- /* Ok, res== 0 */
- if (a_size != b_size) {
- return a_size < b_size ? -1 : 1;
- }
- return HA_EXIT_SUCCESS;
- }
-
- /* Override virtual methods of interest */
-
+ // extracting from rocksdb::BytewiseComparator()->Compare() for optimization
int Compare(const rocksdb::Slice &a, const rocksdb::Slice &b) const override {
- return bytewise_compare(a, b);
+ return a.compare(b);
}
const char *Name() const override { return "RocksDB_SE_v3.10"; }
@@ -72,8 +54,12 @@ public:
// for now, do-nothing implementations:
void FindShortestSeparator(std::string *start,
- const rocksdb::Slice &limit) const override {}
- void FindShortSuccessor(std::string *key) const override {}
+ const rocksdb::Slice &limit) const override {
+ rocksdb::BytewiseComparator()->FindShortestSeparator(start, limit);
+ }
+ void FindShortSuccessor(std::string *key) const override {
+ rocksdb::BytewiseComparator()->FindShortSuccessor(key);
+ }
};
class Rdb_rev_comparator : public rocksdb::Comparator {
@@ -82,18 +68,18 @@ public:
Rdb_rev_comparator &operator=(const Rdb_rev_comparator &) = delete;
Rdb_rev_comparator() = default;
- static int bytewise_compare(const rocksdb::Slice &a,
- const rocksdb::Slice &b) {
- return -Rdb_pk_comparator::bytewise_compare(a, b);
- }
-
+ // extracting from rocksdb::BytewiseComparator()->Compare() for optimization
int Compare(const rocksdb::Slice &a, const rocksdb::Slice &b) const override {
- return -Rdb_pk_comparator::bytewise_compare(a, b);
+ return -a.compare(b);
}
const char *Name() const override { return "rev:RocksDB_SE_v3.10"; }
void FindShortestSeparator(std::string *start,
- const rocksdb::Slice &limit) const override {}
- void FindShortSuccessor(std::string *key) const override {}
+ const rocksdb::Slice &limit) const override {
+ rocksdb::ReverseBytewiseComparator()->FindShortestSeparator(start, limit);
+ }
+ void FindShortSuccessor(std::string *key) const override {
+ rocksdb::ReverseBytewiseComparator()->FindShortSuccessor(key);
+ }
};
} // namespace myrocks
diff --git a/storage/rocksdb/rdb_datadic.cc b/storage/rocksdb/rdb_datadic.cc
index 33c30ebb71a..38da527a7ab 100644
--- a/storage/rocksdb/rdb_datadic.cc
+++ b/storage/rocksdb/rdb_datadic.cc
@@ -4583,7 +4583,7 @@ void Rdb_binlog_manager::update_slave_gtid_info(
}
}
-bool Rdb_dict_manager::init(rocksdb::DB *const rdb_dict,
+bool Rdb_dict_manager::init(rocksdb::TransactionDB *const rdb_dict,
Rdb_cf_manager *const cf_manager) {
DBUG_ASSERT(rdb_dict != nullptr);
DBUG_ASSERT(cf_manager != nullptr);
@@ -4657,7 +4657,9 @@ int Rdb_dict_manager::commit(rocksdb::WriteBatch *const batch,
int res = HA_EXIT_SUCCESS;
rocksdb::WriteOptions options;
options.sync = sync;
- rocksdb::Status s = m_db->Write(options, batch);
+ rocksdb::TransactionDBWriteOptimizations optimize;
+ optimize.skip_concurrency_control = true;
+ rocksdb::Status s = m_db->Write(options, optimize, batch);
res = !s.ok(); // we return true when something failed
if (res) {
rdb_handle_io_error(s, RDB_IO_ERROR_DICT_COMMIT);
diff --git a/storage/rocksdb/rdb_datadic.h b/storage/rocksdb/rdb_datadic.h
index f97c0d08d29..2f699a9cd70 100644
--- a/storage/rocksdb/rdb_datadic.h
+++ b/storage/rocksdb/rdb_datadic.h
@@ -1257,7 +1257,7 @@ private:
class Rdb_dict_manager {
private:
mysql_mutex_t m_mutex;
- rocksdb::DB *m_db = nullptr;
+ rocksdb::TransactionDB *m_db = nullptr;
rocksdb::ColumnFamilyHandle *m_system_cfh = nullptr;
/* Utility to put INDEX_INFO and CF_DEFINITION */
@@ -1283,7 +1283,8 @@ public:
Rdb_dict_manager &operator=(const Rdb_dict_manager &) = delete;
Rdb_dict_manager() = default;
- bool init(rocksdb::DB *const rdb_dict, Rdb_cf_manager *const cf_manager);
+ bool init(rocksdb::TransactionDB *const rdb_dict,
+ Rdb_cf_manager *const cf_manager);
inline void cleanup() { mysql_mutex_destroy(&m_mutex); }
diff --git a/storage/rocksdb/rdb_i_s.cc b/storage/rocksdb/rdb_i_s.cc
index de33d69ddb5..d541922dfd6 100644
--- a/storage/rocksdb/rdb_i_s.cc
+++ b/storage/rocksdb/rdb_i_s.cc
@@ -1130,6 +1130,150 @@ static std::string rdb_filename_without_path(const std::string &path) {
}
/*
+ Support for INFORMATION_SCHEMA.ROCKSDB_SST_PROPS dynamic table
+ */
+namespace RDB_SST_PROPS_FIELD {
+enum {
+ SST_NAME = 0,
+ COLUMN_FAMILY,
+ DATA_BLOCKS,
+ ENTRIES,
+ RAW_KEY_SIZE,
+ RAW_VALUE_SIZE,
+ DATA_BLOCK_SIZE,
+ INDEX_BLOCK_SIZE,
+ INDEX_PARTITIONS,
+ TOP_LEVEL_INDEX_SIZE,
+ FILTER_BLOCK_SIZE,
+ COMPRESSION_ALGO,
+ CREATION_TIME
+};
+} // namespace RDB_SST_PROPS_FIELD
+
+static ST_FIELD_INFO rdb_i_s_sst_props_fields_info[] = {
+ ROCKSDB_FIELD_INFO("SST_NAME", NAME_LEN + 1, MYSQL_TYPE_STRING, 0),
+ ROCKSDB_FIELD_INFO("COLUMN_FAMILY", sizeof(uint32_t), MYSQL_TYPE_LONG, 0),
+ ROCKSDB_FIELD_INFO("DATA_BLOCKS", sizeof(int64_t), MYSQL_TYPE_LONGLONG, 0),
+ ROCKSDB_FIELD_INFO("ENTRIES", sizeof(int64_t), MYSQL_TYPE_LONGLONG, 0),
+ ROCKSDB_FIELD_INFO("RAW_KEY_SIZE", sizeof(int64_t), MYSQL_TYPE_LONGLONG, 0),
+ ROCKSDB_FIELD_INFO("RAW_VALUE_SIZE", sizeof(int64_t), MYSQL_TYPE_LONGLONG,
+ 0),
+ ROCKSDB_FIELD_INFO("DATA_BLOCK_SIZE", sizeof(int64_t), MYSQL_TYPE_LONGLONG,
+ 0),
+ ROCKSDB_FIELD_INFO("INDEX_BLOCK_SIZE", sizeof(int64_t), MYSQL_TYPE_LONGLONG,
+ 0),
+ ROCKSDB_FIELD_INFO("INDEX_PARTITIONS", sizeof(uint32_t), MYSQL_TYPE_LONG,
+ 0),
+ ROCKSDB_FIELD_INFO("TOP_LEVEL_INDEX_SIZE", sizeof(int64_t),
+ MYSQL_TYPE_LONGLONG, 0),
+ ROCKSDB_FIELD_INFO("FILTER_BLOCK_SIZE", sizeof(int64_t),
+ MYSQL_TYPE_LONGLONG, 0),
+ ROCKSDB_FIELD_INFO("COMPRESSION_ALGO", NAME_LEN + 1, MYSQL_TYPE_STRING, 0),
+ ROCKSDB_FIELD_INFO("CREATION_TIME", sizeof(int64_t), MYSQL_TYPE_LONGLONG,
+ 0),
+ ROCKSDB_FIELD_INFO_END};
+
+static int rdb_i_s_sst_props_fill_table(
+ my_core::THD *const thd, my_core::TABLE_LIST *const tables,
+ my_core::Item *const cond MY_ATTRIBUTE((__unused__))) {
+ DBUG_ENTER_FUNC();
+
+ DBUG_ASSERT(thd != nullptr);
+ DBUG_ASSERT(tables != nullptr);
+ DBUG_ASSERT(tables->table != nullptr);
+
+ int ret = 0;
+ Field **field = tables->table->field;
+ DBUG_ASSERT(field != nullptr);
+
+ /* Iterate over all the column families */
+ rocksdb::DB *const rdb = rdb_get_rocksdb_db();
+
+ if (!rdb) {
+ DBUG_RETURN(ret);
+ }
+
+ const Rdb_cf_manager &cf_manager = rdb_get_cf_manager();
+
+ for (const auto &cf_handle : cf_manager.get_all_cf()) {
+ /* Grab the the properties of all the tables in the column family */
+ rocksdb::TablePropertiesCollection table_props_collection;
+ const rocksdb::Status s =
+ rdb->GetPropertiesOfAllTables(cf_handle, &table_props_collection);
+
+ if (!s.ok()) {
+ continue;
+ }
+
+ /* Iterate over all the items in the collection, each of which contains a
+ * name and the actual properties */
+ for (const auto &props : table_props_collection) {
+ /* Add the SST name into the output */
+ const std::string sst_name = rdb_filename_without_path(props.first);
+
+ field[RDB_SST_PROPS_FIELD::SST_NAME]->store(
+ sst_name.data(), sst_name.size(), system_charset_info);
+
+ field[RDB_SST_PROPS_FIELD::COLUMN_FAMILY]->store(
+ props.second->column_family_id, true);
+ field[RDB_SST_PROPS_FIELD::DATA_BLOCKS]->store(
+ props.second->num_data_blocks, true);
+ field[RDB_SST_PROPS_FIELD::ENTRIES]->store(props.second->num_entries,
+ true);
+ field[RDB_SST_PROPS_FIELD::RAW_KEY_SIZE]->store(
+ props.second->raw_key_size, true);
+ field[RDB_SST_PROPS_FIELD::RAW_VALUE_SIZE]->store(
+ props.second->raw_value_size, true);
+ field[RDB_SST_PROPS_FIELD::DATA_BLOCK_SIZE]->store(
+ props.second->data_size, true);
+ field[RDB_SST_PROPS_FIELD::INDEX_BLOCK_SIZE]->store(
+ props.second->index_size, true);
+ field[RDB_SST_PROPS_FIELD::INDEX_PARTITIONS]->store(
+ props.second->index_partitions, true);
+ field[RDB_SST_PROPS_FIELD::TOP_LEVEL_INDEX_SIZE]->store(
+ props.second->top_level_index_size, true);
+ field[RDB_SST_PROPS_FIELD::FILTER_BLOCK_SIZE]->store(
+ props.second->filter_size, true);
+ if (props.second->compression_name.empty()) {
+ field[RDB_SST_PROPS_FIELD::COMPRESSION_ALGO]->set_null();
+ } else {
+ field[RDB_SST_PROPS_FIELD::COMPRESSION_ALGO]->store(
+ props.second->compression_name.c_str(),
+ props.second->compression_name.size(), system_charset_info);
+ }
+ field[RDB_SST_PROPS_FIELD::CREATION_TIME]->store(
+ props.second->creation_time, true);
+
+ /* Tell MySQL about this row in the virtual table */
+ ret = static_cast<int>(
+ my_core::schema_table_store_record(thd, tables->table));
+
+ if (ret != 0) {
+ DBUG_RETURN(ret);
+ }
+ }
+ }
+
+ DBUG_RETURN(ret);
+}
+
+/* Initialize the information_schema.rocksdb_sst_props virtual table */
+static int rdb_i_s_sst_props_init(void *const p) {
+ DBUG_ENTER_FUNC();
+
+ DBUG_ASSERT(p != nullptr);
+
+ my_core::ST_SCHEMA_TABLE *schema;
+
+ schema = (my_core::ST_SCHEMA_TABLE *)p;
+
+ schema->fields_info = rdb_i_s_sst_props_fields_info;
+ schema->fill_table = rdb_i_s_sst_props_fill_table;
+
+ DBUG_RETURN(0);
+}
+
+/*
Support for INFORMATION_SCHEMA.ROCKSDB_INDEX_FILE_MAP dynamic table
*/
namespace RDB_INDEX_FILE_MAP_FIELD {
@@ -1519,19 +1663,21 @@ static int rdb_i_s_trx_info_init(void *const p) {
namespace RDB_DEADLOCK_FIELD {
enum {
DEADLOCK_ID = 0,
+ TIMESTAMP,
TRANSACTION_ID,
CF_NAME,
WAITING_KEY,
LOCK_TYPE,
INDEX_NAME,
TABLE_NAME,
- ROLLED_BACK
+ ROLLED_BACK,
};
} // namespace RDB_TRX_FIELD
static ST_FIELD_INFO rdb_i_s_deadlock_info_fields_info[] = {
ROCKSDB_FIELD_INFO("DEADLOCK_ID", sizeof(ulonglong), MYSQL_TYPE_LONGLONG,
0),
+ ROCKSDB_FIELD_INFO("TIMESTAMP", sizeof(ulonglong), MYSQL_TYPE_LONGLONG, 0),
ROCKSDB_FIELD_INFO("TRANSACTION_ID", sizeof(ulonglong), MYSQL_TYPE_LONGLONG,
0),
ROCKSDB_FIELD_INFO("CF_NAME", NAME_LEN + 1, MYSQL_TYPE_STRING, 0),
@@ -1568,8 +1714,11 @@ static int rdb_i_s_deadlock_info_fill_table(
ulonglong id = 0;
for (const auto &info : all_dl_info) {
+ auto deadlock_time = info.deadlock_time;
for (const auto &trx_info : info.path) {
tables->table->field[RDB_DEADLOCK_FIELD::DEADLOCK_ID]->store(id, true);
+ tables->table->field[RDB_DEADLOCK_FIELD::TIMESTAMP]->store(deadlock_time,
+ true);
tables->table->field[RDB_DEADLOCK_FIELD::TRANSACTION_ID]->store(
trx_info.trx_id, true);
tables->table->field[RDB_DEADLOCK_FIELD::CF_NAME]->store(
@@ -1760,6 +1909,22 @@ struct st_maria_plugin rdb_i_s_ddl = {
MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL
};
+struct st_maria_plugin rdb_i_s_sst_props = {
+ MYSQL_INFORMATION_SCHEMA_PLUGIN,
+ &rdb_i_s_info,
+ "ROCKSDB_SST_PROPS",
+ "Facebook",
+ "RocksDB SST Properties",
+ PLUGIN_LICENSE_GPL,
+ rdb_i_s_sst_props_init,
+ rdb_i_s_deinit,
+ 0x0001, /* version number (0.1) */
+ nullptr, /* status variables */
+ nullptr, /* system variables */
+ nullptr, /* config options */
+ MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL
+};
+
struct st_maria_plugin rdb_i_s_index_file_map = {
MYSQL_INFORMATION_SCHEMA_PLUGIN,
&rdb_i_s_info,
diff --git a/storage/rocksdb/rdb_i_s.h b/storage/rocksdb/rdb_i_s.h
index d6a48bf3fec..f4c4b04a68d 100644
--- a/storage/rocksdb/rdb_i_s.h
+++ b/storage/rocksdb/rdb_i_s.h
@@ -29,6 +29,7 @@ extern struct st_maria_plugin rdb_i_s_cfoptions;
extern struct st_maria_plugin rdb_i_s_compact_stats;
extern struct st_maria_plugin rdb_i_s_global_info;
extern struct st_maria_plugin rdb_i_s_ddl;
+extern struct st_maria_plugin rdb_i_s_sst_props;
extern struct st_maria_plugin rdb_i_s_index_file_map;
extern struct st_maria_plugin rdb_i_s_lock_info;
extern struct st_maria_plugin rdb_i_s_trx_info;
diff --git a/storage/rocksdb/rdb_index_merge.cc b/storage/rocksdb/rdb_index_merge.cc
index 44cec7c2a9c..66c7955abf9 100644
--- a/storage/rocksdb/rdb_index_merge.cc
+++ b/storage/rocksdb/rdb_index_merge.cc
@@ -54,6 +54,11 @@ Rdb_index_merge::~Rdb_index_merge() {
}
my_sleep(m_merge_tmp_file_removal_delay * 1000);
+ // Not aborting on fsync error since the tmp file is not used anymore
+ if (mysql_file_sync(m_merge_file.m_fd, MYF(MY_WME))) {
+ // NO_LINT_DEBUG
+ sql_print_error("Error flushing truncated MyRocks merge buffer.");
+ }
curr_size -= m_merge_buf_size;
}
}
diff --git a/storage/rocksdb/rdb_perf_context.cc b/storage/rocksdb/rdb_perf_context.cc
index 0c561c62ab2..a35b410e8d1 100644
--- a/storage/rocksdb/rdb_perf_context.cc
+++ b/storage/rocksdb/rdb_perf_context.cc
@@ -180,8 +180,6 @@ static void harvest_diffs(Rdb_atomic_perf_counters *const counters) {
static Rdb_atomic_perf_counters rdb_global_perf_counters;
void rdb_get_global_perf_counters(Rdb_perf_counters *const counters) {
- DBUG_ASSERT(counters != nullptr);
-
counters->load(rdb_global_perf_counters);
}
diff --git a/storage/rocksdb/rdb_psi.cc b/storage/rocksdb/rdb_psi.cc
index b5309df5973..361a648bba4 100644
--- a/storage/rocksdb/rdb_psi.cc
+++ b/storage/rocksdb/rdb_psi.cc
@@ -38,22 +38,25 @@ my_core::PSI_stage_info stage_waiting_on_row_lock = {0, "Waiting for row lock",
my_core::PSI_stage_info *all_rocksdb_stages[] = {&stage_waiting_on_row_lock};
my_core::PSI_thread_key rdb_background_psi_thread_key,
- rdb_drop_idx_psi_thread_key;
+ rdb_drop_idx_psi_thread_key, rdb_mc_psi_thread_key;
my_core::PSI_thread_info all_rocksdb_threads[] = {
{&rdb_background_psi_thread_key, "background", PSI_FLAG_GLOBAL},
{&rdb_drop_idx_psi_thread_key, "drop index", PSI_FLAG_GLOBAL},
+ {&rdb_mc_psi_thread_key, "manual compaction", PSI_FLAG_GLOBAL},
};
my_core::PSI_mutex_key rdb_psi_open_tbls_mutex_key, rdb_signal_bg_psi_mutex_key,
- rdb_signal_drop_idx_psi_mutex_key, rdb_collation_data_mutex_key,
- rdb_mem_cmp_space_mutex_key, key_mutex_tx_list, rdb_sysvars_psi_mutex_key,
- rdb_cfm_mutex_key, rdb_sst_commit_key;
+ rdb_signal_drop_idx_psi_mutex_key, rdb_signal_mc_psi_mutex_key,
+ rdb_collation_data_mutex_key, rdb_mem_cmp_space_mutex_key,
+ key_mutex_tx_list, rdb_sysvars_psi_mutex_key, rdb_cfm_mutex_key,
+ rdb_sst_commit_key, rdb_block_cache_resize_mutex_key;
my_core::PSI_mutex_info all_rocksdb_mutexes[] = {
{&rdb_psi_open_tbls_mutex_key, "open tables", PSI_FLAG_GLOBAL},
{&rdb_signal_bg_psi_mutex_key, "stop background", PSI_FLAG_GLOBAL},
{&rdb_signal_drop_idx_psi_mutex_key, "signal drop index", PSI_FLAG_GLOBAL},
+ {&rdb_signal_mc_psi_mutex_key, "signal manual compaction", PSI_FLAG_GLOBAL},
{&rdb_collation_data_mutex_key, "collation data init", PSI_FLAG_GLOBAL},
{&rdb_mem_cmp_space_mutex_key, "collation space char data init",
PSI_FLAG_GLOBAL},
@@ -61,6 +64,8 @@ my_core::PSI_mutex_info all_rocksdb_mutexes[] = {
{&rdb_sysvars_psi_mutex_key, "setting sysvar", PSI_FLAG_GLOBAL},
{&rdb_cfm_mutex_key, "column family manager", PSI_FLAG_GLOBAL},
{&rdb_sst_commit_key, "sst commit", PSI_FLAG_GLOBAL},
+ {&rdb_block_cache_resize_mutex_key, "resizing block cache",
+ PSI_FLAG_GLOBAL},
};
my_core::PSI_rwlock_key key_rwlock_collation_exception_list,
@@ -75,12 +80,14 @@ my_core::PSI_rwlock_info all_rocksdb_rwlocks[] = {
};
my_core::PSI_cond_key rdb_signal_bg_psi_cond_key,
- rdb_signal_drop_idx_psi_cond_key;
+ rdb_signal_drop_idx_psi_cond_key, rdb_signal_mc_psi_cond_key;
my_core::PSI_cond_info all_rocksdb_conds[] = {
{&rdb_signal_bg_psi_cond_key, "cond signal background", PSI_FLAG_GLOBAL},
{&rdb_signal_drop_idx_psi_cond_key, "cond signal drop index",
PSI_FLAG_GLOBAL},
+ {&rdb_signal_mc_psi_cond_key, "cond signal manual compaction",
+ PSI_FLAG_GLOBAL},
};
void init_rocksdb_psi_keys() {
diff --git a/storage/rocksdb/rdb_psi.h b/storage/rocksdb/rdb_psi.h
index d4318ee3dba..e0d6e7e3a47 100644
--- a/storage/rocksdb/rdb_psi.h
+++ b/storage/rocksdb/rdb_psi.h
@@ -35,19 +35,19 @@ extern my_core::PSI_stage_info stage_waiting_on_row_lock;
#ifdef HAVE_PSI_INTERFACE
extern my_core::PSI_thread_key rdb_background_psi_thread_key,
- rdb_drop_idx_psi_thread_key;
+ rdb_drop_idx_psi_thread_key, rdb_mc_psi_thread_key;
extern my_core::PSI_mutex_key rdb_psi_open_tbls_mutex_key,
rdb_signal_bg_psi_mutex_key, rdb_signal_drop_idx_psi_mutex_key,
- rdb_collation_data_mutex_key, rdb_mem_cmp_space_mutex_key,
- key_mutex_tx_list, rdb_sysvars_psi_mutex_key, rdb_cfm_mutex_key,
- rdb_sst_commit_key;
+ rdb_signal_mc_psi_mutex_key, rdb_collation_data_mutex_key,
+ rdb_mem_cmp_space_mutex_key, key_mutex_tx_list, rdb_sysvars_psi_mutex_key,
+ rdb_cfm_mutex_key, rdb_sst_commit_key, rdb_block_cache_resize_mutex_key;
extern my_core::PSI_rwlock_key key_rwlock_collation_exception_list,
key_rwlock_read_free_rpl_tables, key_rwlock_skip_unique_check_tables;
extern my_core::PSI_cond_key rdb_signal_bg_psi_cond_key,
- rdb_signal_drop_idx_psi_cond_key;
+ rdb_signal_drop_idx_psi_cond_key, rdb_signal_mc_psi_cond_key;
#endif // HAVE_PSI_INTERFACE
void init_rocksdb_psi_keys();
diff --git a/storage/rocksdb/rdb_sst_info.cc b/storage/rocksdb/rdb_sst_info.cc
index e0dfb011f87..8186f497d2b 100644
--- a/storage/rocksdb/rdb_sst_info.cc
+++ b/storage/rocksdb/rdb_sst_info.cc
@@ -83,7 +83,9 @@ rocksdb::Status Rdb_sst_file_ordered::Rdb_sst_file::open() {
const rocksdb::Options options(m_db_options, cf_descr.options);
m_sst_file_writer =
- new rocksdb::SstFileWriter(env_options, options, m_comparator, m_cf);
+ new rocksdb::SstFileWriter(env_options, options, m_comparator, m_cf, true,
+ rocksdb::Env::IOPriority::IO_TOTAL,
+ cf_descr.options.optimize_filters_for_hits);
s = m_sst_file_writer->Open(m_name);
if (m_tracing) {
diff --git a/storage/rocksdb/rdb_threads.h b/storage/rocksdb/rdb_threads.h
index a93e4fc93f2..3c2dd680d41 100644
--- a/storage/rocksdb/rdb_threads.h
+++ b/storage/rocksdb/rdb_threads.h
@@ -17,6 +17,7 @@
#pragma once
/* C++ standard header files */
+#include <map>
#include <string>
/* MySQL includes */
@@ -39,6 +40,7 @@
/* MyRocks header files */
#include "./rdb_utils.h"
+#include "rocksdb/db.h"
namespace myrocks {
@@ -118,8 +120,8 @@ public:
{
// NO_LINT_DEBUG
sql_print_warning(
- "MyRocks: Failed to set name (%s) for current thread, errno=%d",
- m_name.c_str(), errno);
+ "MyRocks: Failed to set name (%s) for current thread, errno=%d,%d",
+ m_name.c_str(), errno, err);
}
#endif
}
@@ -160,6 +162,31 @@ public:
}
};
+class Rdb_manual_compaction_thread : public Rdb_thread {
+ private:
+ struct Manual_compaction_request {
+ int mc_id;
+ enum mc_state { INITED = 0, RUNNING } state;
+ rocksdb::ColumnFamilyHandle *cf;
+ rocksdb::Slice *start;
+ rocksdb::Slice *limit;
+ int concurrency = 0;
+ };
+
+ int m_latest_mc_id;
+ mysql_mutex_t m_mc_mutex;
+ std::map<int, Manual_compaction_request> m_requests;
+
+ public:
+ virtual void run() override;
+ int request_manual_compaction(rocksdb::ColumnFamilyHandle *cf,
+ rocksdb::Slice *start, rocksdb::Slice *limit,
+ int concurrency = 0);
+ bool is_manual_compaction_finished(int mc_id);
+ void clear_manual_compaction_request(int mc_id, bool init_only = false);
+ void clear_all_manual_compaction_requests();
+};
+
/*
Drop index thread control
*/
diff --git a/storage/rocksdb/rdb_utils.cc b/storage/rocksdb/rdb_utils.cc
index 723e079a165..457a3312a03 100644
--- a/storage/rocksdb/rdb_utils.cc
+++ b/storage/rocksdb/rdb_utils.cc
@@ -49,9 +49,6 @@ namespace myrocks {
*/
const char *rdb_skip_spaces(const struct charset_info_st *const cs,
const char *str) {
- DBUG_ASSERT(cs != nullptr);
- DBUG_ASSERT(str != nullptr);
-
while (my_isspace(cs, *str)) {
str++;
}
@@ -65,9 +62,6 @@ const char *rdb_skip_spaces(const struct charset_info_st *const cs,
of characters in str2.
*/
bool rdb_compare_strings_ic(const char *const str1, const char *const str2) {
- DBUG_ASSERT(str1 != nullptr);
- DBUG_ASSERT(str2 != nullptr);
-
// Scan through the strings
size_t ii;
for (ii = 0; str2[ii]; ii++) {
@@ -89,10 +83,6 @@ const char *rdb_find_in_string(const char *str, const char *pattern,
char quote = '\0';
bool escape = false;
- DBUG_ASSERT(str != nullptr);
- DBUG_ASSERT(pattern != nullptr);
- DBUG_ASSERT(succeeded != nullptr);
-
*succeeded = false;
for (; *str; str++) {
@@ -136,11 +126,6 @@ const char *rdb_find_in_string(const char *str, const char *pattern,
const char *rdb_check_next_token(const struct charset_info_st *const cs,
const char *str, const char *const pattern,
bool *const succeeded) {
- DBUG_ASSERT(cs != nullptr);
- DBUG_ASSERT(str != nullptr);
- DBUG_ASSERT(pattern != nullptr);
- DBUG_ASSERT(succeeded != nullptr);
-
// Move past any spaces
str = rdb_skip_spaces(cs, str);
@@ -159,9 +144,6 @@ const char *rdb_check_next_token(const struct charset_info_st *const cs,
*/
const char *rdb_parse_id(const struct charset_info_st *const cs,
const char *str, std::string *const id) {
- DBUG_ASSERT(cs != nullptr);
- DBUG_ASSERT(str != nullptr);
-
// Move past any spaces
str = rdb_skip_spaces(cs, str);
@@ -221,9 +203,6 @@ const char *rdb_parse_id(const struct charset_info_st *const cs,
*/
const char *rdb_skip_id(const struct charset_info_st *const cs,
const char *str) {
- DBUG_ASSERT(cs != nullptr);
- DBUG_ASSERT(str != nullptr);
-
return rdb_parse_id(cs, str, nullptr);
}
@@ -254,8 +233,6 @@ static const std::array<char, 16> rdb_hexdigit = {{'0', '1', '2', '3', '4', '5',
*/
std::string rdb_hexdump(const char *data, const std::size_t data_len,
const std::size_t maxsize) {
- DBUG_ASSERT(data != nullptr);
-
// Count the elements in the string
std::size_t elems = data_len;
// Calculate the amount of output needed
diff --git a/storage/rocksdb/rocksdb b/storage/rocksdb/rocksdb
-Subproject ba295cda29daee3ffe58549542804efdfd96978
+Subproject 926f3a78a64b327475ee6c60b6c8ab4f3425320