Commit 8e2cfde9 authored by Sergei Petrunia's avatar Sergei Petrunia

MariaRocks port: fix rocksdb.collation, rocksdb.collation_exception

- port Regex_list_handler from facebook/mysql-5.6/sql/handler.cc
  put it into a separate file in storage/rocksdb directory

- Adjust the build process so that the main library is build with
  Regex_list_handler (which has dependencies on the server),
  while RocksDB tools are built without it.

- Un-comment @@rdb_collation_exceptions handling in ha_rocksdb.cc
- Also adjust rocksdb_set_collation_exception_list() to free the
  old variable value and alloc the new one.
parent 34b66fcc
...@@ -43,9 +43,9 @@ set_source_files_properties(${ROCKSDB_LIB_SOURCES} PROPERTIES COMPILE_FLAGS -frt ...@@ -43,9 +43,9 @@ set_source_files_properties(${ROCKSDB_LIB_SOURCES} PROPERTIES COMPILE_FLAGS -frt
set_source_files_properties(event_listener.cc PROPERTIES COMPILE_FLAGS -frtti) set_source_files_properties(event_listener.cc PROPERTIES COMPILE_FLAGS -frtti)
set_source_files_properties(rdb_cf_options.cc PROPERTIES COMPILE_FLAGS -frtti) set_source_files_properties(rdb_cf_options.cc PROPERTIES COMPILE_FLAGS -frtti)
ADD_CONVENIENCE_LIBRARY(
SET(ROCKSDB_SOURCES ROCKSDB_AUX_LIB
ha_rocksdb.cc ha_rocksdb.h ha_rocksdb_proto.h ha_rocksdb_proto.h
logger.h logger.h
rdb_comparator.h rdb_comparator.h
rdb_datadic.cc rdb_datadic.h rdb_datadic.cc rdb_datadic.h
...@@ -64,6 +64,11 @@ SET(ROCKSDB_SOURCES ...@@ -64,6 +64,11 @@ SET(ROCKSDB_SOURCES
${ROCKSDB_LIB_SOURCES} ${ROCKSDB_LIB_SOURCES}
) )
SET(ROCKSDB_SOURCES
rdb_mariadb_server_port.cc rdb_mariadb_server_port.h
ha_rocksdb.cc ha_rocksdb.h
)
IF(WITH_FB_TSAN) IF(WITH_FB_TSAN)
SET(PIC_EXT "_pic") SET(PIC_EXT "_pic")
ELSE() ELSE()
...@@ -102,7 +107,7 @@ IF (NOT "$ENV{WITH_ZSTD}" STREQUAL "") ...@@ -102,7 +107,7 @@ IF (NOT "$ENV{WITH_ZSTD}" STREQUAL "")
ADD_DEFINITIONS(-DZSTD) ADD_DEFINITIONS(-DZSTD)
ENDIF() ENDIF()
SET(rocksdb_static_libs ${rocksdb_static_libs} ${ZLIB_LIBRARY} "-lrt") SET(rocksdb_static_libs ROCKSDB_AUX_LIB ${rocksdb_static_libs} ${ZLIB_LIBRARY} "-lrt")
MYSQL_ADD_PLUGIN(rocksdb_se ${ROCKSDB_SOURCES} STORAGE_ENGINE DEFAULT STATIC_ONLY MYSQL_ADD_PLUGIN(rocksdb_se ${ROCKSDB_SOURCES} STORAGE_ENGINE DEFAULT STATIC_ONLY
LINK_LIBRARIES ${rocksdb_static_libs} LINK_LIBRARIES ${rocksdb_static_libs}
...@@ -121,11 +126,11 @@ IF (WITH_ROCKSDB_SE_STORAGE_ENGINE) ...@@ -121,11 +126,11 @@ IF (WITH_ROCKSDB_SE_STORAGE_ENGINE)
) )
set_source_files_properties(${ROCKSDB_TOOL_SOURCES} PROPERTIES COMPILE_FLAGS -frtti) set_source_files_properties(${ROCKSDB_TOOL_SOURCES} PROPERTIES COMPILE_FLAGS -frtti)
MYSQL_ADD_EXECUTABLE(sst_dump ${CMAKE_SOURCE_DIR}/storage/rocksdb/rocksdb/tools/sst_dump.cc ${ROCKSDB_TOOL_SOURCES}) MYSQL_ADD_EXECUTABLE(sst_dump ${CMAKE_SOURCE_DIR}/storage/rocksdb/rocksdb/tools/sst_dump.cc ${ROCKSDB_TOOL_SOURCES})
TARGET_LINK_LIBRARIES(sst_dump rocksdb_se) TARGET_LINK_LIBRARIES(sst_dump ${rocksdb_static_libs})
MYSQL_ADD_EXECUTABLE(ldb ${CMAKE_SOURCE_DIR}/storage/rocksdb/rocksdb/tools/ldb.cc ${ROCKSDB_TOOL_SOURCES}) MYSQL_ADD_EXECUTABLE(ldb ${CMAKE_SOURCE_DIR}/storage/rocksdb/rocksdb/tools/ldb.cc ${ROCKSDB_TOOL_SOURCES})
TARGET_LINK_LIBRARIES(ldb rocksdb_se) TARGET_LINK_LIBRARIES(ldb ${rocksdb_static_libs})
MYSQL_ADD_EXECUTABLE(mysql_ldb ${CMAKE_SOURCE_DIR}/storage/rocksdb/tools/mysql_ldb.cc ${ROCKSDB_TOOL_SOURCES}) MYSQL_ADD_EXECUTABLE(mysql_ldb ${CMAKE_SOURCE_DIR}/storage/rocksdb/tools/mysql_ldb.cc ${ROCKSDB_TOOL_SOURCES})
TARGET_LINK_LIBRARIES(mysql_ldb rocksdb_se) TARGET_LINK_LIBRARIES(mysql_ldb ${rocksdb_static_libs})
ENDIF() ENDIF()
...@@ -62,6 +62,7 @@ ...@@ -62,6 +62,7 @@
#include "./rdb_index_merge.h" #include "./rdb_index_merge.h"
#include "./rdb_mutex_wrapper.h" #include "./rdb_mutex_wrapper.h"
#include "./rdb_threads.h" #include "./rdb_threads.h"
#include "./rdb_mariadb_server_port.h"
#ifdef TARGET_OS_LINUX #ifdef TARGET_OS_LINUX
extern my_bool cachedev_enabled; extern my_bool cachedev_enabled;
...@@ -155,11 +156,9 @@ Rdb_binlog_manager binlog_manager; ...@@ -155,11 +156,9 @@ Rdb_binlog_manager binlog_manager;
static Rdb_background_thread rdb_bg_thread; static Rdb_background_thread rdb_bg_thread;
#ifdef MARIAROCKS_NOT_YET
// List of table names (using regex) that are exceptions to the strict // List of table names (using regex) that are exceptions to the strict
// collation check requirement. // collation check requirement.
Regex_list_handler *rdb_collation_exceptions; Regex_list_handler *rdb_collation_exceptions;
#endif
static const char* const ERRSTR_ROLLBACK_ONLY static const char* const ERRSTR_ROLLBACK_ONLY
= "This transaction was rolled back and cannot be " = "This transaction was rolled back and cannot be "
...@@ -3345,13 +3344,11 @@ static int rocksdb_init_func(void *p) ...@@ -3345,13 +3344,11 @@ static int rocksdb_init_func(void *p)
mysql_mutex_init(rdb_mem_cmp_space_mutex_key, &rdb_mem_cmp_space_mutex, mysql_mutex_init(rdb_mem_cmp_space_mutex_key, &rdb_mem_cmp_space_mutex,
MY_MUTEX_INIT_FAST); MY_MUTEX_INIT_FAST);
#ifdef MARIAROCKS_NOT_YET
#if defined(HAVE_PSI_INTERFACE) #if defined(HAVE_PSI_INTERFACE)
rdb_collation_exceptions = new Regex_list_handler( rdb_collation_exceptions = new Regex_list_handler(
key_rwlock_collation_exception_list); key_rwlock_collation_exception_list);
#else #else
rdb_collation_exceptions = new Regex_list_handler(); rdb_collation_exceptions = new Regex_list_handler();
#endif
#endif #endif
mysql_mutex_init(rdb_sysvars_psi_mutex_key, &rdb_sysvars_mutex, mysql_mutex_init(rdb_sysvars_psi_mutex_key, &rdb_sysvars_mutex,
...@@ -3731,9 +3728,9 @@ static int rocksdb_done_func(void *p) ...@@ -3731,9 +3728,9 @@ static int rocksdb_done_func(void *p)
mysql_mutex_destroy(&rdb_open_tables.m_mutex); mysql_mutex_destroy(&rdb_open_tables.m_mutex);
mysql_mutex_destroy(&rdb_sysvars_mutex); mysql_mutex_destroy(&rdb_sysvars_mutex);
#ifdef MARIAROCKS_NOT_YET
delete rdb_collation_exceptions; delete rdb_collation_exceptions;
#endif
mysql_mutex_destroy(&rdb_collation_data_mutex); mysql_mutex_destroy(&rdb_collation_data_mutex);
mysql_mutex_destroy(&rdb_mem_cmp_space_mutex); mysql_mutex_destroy(&rdb_mem_cmp_space_mutex);
...@@ -5126,11 +5123,7 @@ int ha_rocksdb::create_cfs(const TABLE *table_arg, Rdb_tbl_def *tbl_def_arg, ...@@ -5126,11 +5123,7 @@ int ha_rocksdb::create_cfs(const TABLE *table_arg, Rdb_tbl_def *tbl_def_arg,
{ {
if (!rdb_is_index_collation_supported( if (!rdb_is_index_collation_supported(
table_arg->key_info[i].key_part[part].field) && table_arg->key_info[i].key_part[part].field) &&
#ifdef MARIAROCKS_NOT_YET
!rdb_collation_exceptions->matches(tablename_sys)) !rdb_collation_exceptions->matches(tablename_sys))
#else
true)
#endif
{ {
std::string collation_err; std::string collation_err;
for (auto coll : RDB_INDEX_COLLATIONS) for (auto coll : RDB_INDEX_COLLATIONS)
...@@ -10715,7 +10708,6 @@ rocksdb_set_rate_limiter_bytes_per_sec( ...@@ -10715,7 +10708,6 @@ rocksdb_set_rate_limiter_bytes_per_sec(
void rdb_set_collation_exception_list(const char *exception_list) void rdb_set_collation_exception_list(const char *exception_list)
{ {
#ifdef MARIAROCKS_NOT_YET
DBUG_ASSERT(rdb_collation_exceptions != nullptr); DBUG_ASSERT(rdb_collation_exceptions != nullptr);
if (!rdb_collation_exceptions->set_patterns(exception_list)) if (!rdb_collation_exceptions->set_patterns(exception_list))
...@@ -10723,7 +10715,6 @@ void rdb_set_collation_exception_list(const char *exception_list) ...@@ -10723,7 +10715,6 @@ void rdb_set_collation_exception_list(const char *exception_list)
my_core::warn_about_bad_patterns(rdb_collation_exceptions, my_core::warn_about_bad_patterns(rdb_collation_exceptions,
"strict_collation_exceptions"); "strict_collation_exceptions");
} }
#endif
} }
void void
...@@ -10736,7 +10727,9 @@ rocksdb_set_collation_exception_list(THD* thd, ...@@ -10736,7 +10727,9 @@ rocksdb_set_collation_exception_list(THD* thd,
rdb_set_collation_exception_list(val); rdb_set_collation_exception_list(val);
*static_cast<const char**>(var_ptr) = val; const char *val_copy= my_strdup(val, MYF(0));
my_free(*static_cast<char**>(var_ptr));
*static_cast<const char**>(var_ptr) = val_copy;
} }
void void
......
...@@ -116,6 +116,7 @@ CREATE TABLE b (id INT PRIMARY KEY, value varchar(50), index(value)) engine=rock ...@@ -116,6 +116,7 @@ CREATE TABLE b (id INT PRIMARY KEY, value varchar(50), index(value)) engine=rock
CREATE TABLE c (id INT PRIMARY KEY, value varchar(50), index(value)) engine=rocksdb charset utf8; CREATE TABLE c (id INT PRIMARY KEY, value varchar(50), index(value)) engine=rocksdb charset utf8;
ERROR HY000: Unsupported collation on string indexed column test.c.value Use binary collation (binary, latin1_bin, utf8_bin). ERROR HY000: Unsupported collation on string indexed column test.c.value Use binary collation (binary, latin1_bin, utf8_bin).
DROP TABLE a, b; DROP TABLE a, b;
call mtr.add_suppression("Invalid pattern in strict_collation_exceptions:");
SET GLOBAL rocksdb_strict_collation_exceptions="abc\\"; SET GLOBAL rocksdb_strict_collation_exceptions="abc\\";
Invalid pattern in strict_collation_exceptions: abc\ Invalid pattern in strict_collation_exceptions: abc\
CREATE TABLE abc (id INT PRIMARY KEY, value varchar(50), index(value)) engine=rocksdb charset utf8; CREATE TABLE abc (id INT PRIMARY KEY, value varchar(50), index(value)) engine=rocksdb charset utf8;
......
--source include/have_rocksdb.inc --source include/have_rocksdb.inc
--source include/have_fullregex.inc # MariaDB doesn't have server variables to check for GCC version, so the
# following check is commented out:
# --source include/have_fullregex.inc
SET @start_global_value = @@global.ROCKSDB_STRICT_COLLATION_EXCEPTIONS; SET @start_global_value = @@global.ROCKSDB_STRICT_COLLATION_EXCEPTIONS;
...@@ -165,6 +167,7 @@ CREATE TABLE b (id INT PRIMARY KEY, value varchar(50), index(value)) engine=rock ...@@ -165,6 +167,7 @@ CREATE TABLE b (id INT PRIMARY KEY, value varchar(50), index(value)) engine=rock
CREATE TABLE c (id INT PRIMARY KEY, value varchar(50), index(value)) engine=rocksdb charset utf8; CREATE TABLE c (id INT PRIMARY KEY, value varchar(50), index(value)) engine=rocksdb charset utf8;
DROP TABLE a, b; DROP TABLE a, b;
call mtr.add_suppression("Invalid pattern in strict_collation_exceptions:");
# test invalid regex (trailing escape) # test invalid regex (trailing escape)
--exec echo "" >$MYSQLTEST_VARDIR/log/mysqld.1.err --exec echo "" >$MYSQLTEST_VARDIR/log/mysqld.1.err
SET GLOBAL rocksdb_strict_collation_exceptions="abc\\"; SET GLOBAL rocksdb_strict_collation_exceptions="abc\\";
......
#include <my_config.h>
/* MySQL includes */
#include "./debug_sync.h"
#include "./my_bit.h"
#include "./my_stacktrace.h"
#include "./sql_table.h"
#include "./my_global.h"
#include "./log.h"
#include <mysys_err.h>
#include <mysql/psi/mysql_table.h>
#ifdef MARIAROCKS_NOT_YET
#include <mysql/thread_pool_priv.h>
#endif
#include <string>
/* MyRocks includes */
#include "./rdb_threads.h"
#include "rdb_mariadb_server_port.h"
void warn_about_bad_patterns(const Regex_list_handler* regex_list_handler,
const char *name)
{
// There was some invalid regular expression data in the patterns supplied
// NO_LINT_DEBUG
sql_print_warning("Invalid pattern in %s: %s", name,
regex_list_handler->bad_pattern().c_str());
}
/*
Set the patterns string. If there are invalid regex patterns they will
be stored in m_bad_patterns and the result will be false, otherwise the
result will be true.
*/
bool Regex_list_handler::set_patterns(const std::string& pattern_str)
{
bool pattern_valid= true;
// Create a normalized version of the pattern string with all delimiters
// replaced by the '|' character
std::string norm_pattern= pattern_str;
std::replace(norm_pattern.begin(), norm_pattern.end(), m_delimiter, '|');
// Make sure no one else is accessing the list while we are changing it.
mysql_rwlock_wrlock(&m_rwlock);
// Clear out any old error information
m_bad_pattern_str.clear();
try
{
// Replace all delimiters with the '|' operator and create the regex
// Note that this means the delimiter can not be part of a regular
// expression. This is currently not a problem as we are using the comma
// character as a delimiter and commas are not valid in table names.
const std::regex* pattern= new std::regex(norm_pattern);
// Free any existing regex information and setup the new one
delete m_pattern;
m_pattern= pattern;
}
catch (const std::regex_error& e)
{
// This pattern is invalid.
pattern_valid= false;
// Put the bad pattern into a member variable so it can be retrieved later.
m_bad_pattern_str= pattern_str;
}
// Release the lock
mysql_rwlock_unlock(&m_rwlock);
return pattern_valid;
}
bool Regex_list_handler::matches(const std::string& str) const
{
DBUG_ASSERT(m_pattern != nullptr);
// Make sure no one else changes the list while we are accessing it.
mysql_rwlock_rdlock(&m_rwlock);
// See if the table name matches the regex we have created
bool found= std::regex_match(str, *m_pattern);
// Release the lock
mysql_rwlock_unlock(&m_rwlock);
return found;
}
/*
A temporary header to resolve WebScaleSQL vs MariaDB differences
when porting MyRocks to MariaDB.
*/
#ifndef RDB_MARIADB_SERVER_PORT_H
#define RDB_MARIADB_SERVER_PORT_H
#include "my_global.h" /* ulonglong */
#include "atomic_stat.h"
#include "my_pthread.h"
#include <mysql/psi/mysql_table.h>
#include <mysql/psi/mysql_thread.h>
/*
Code that is on SQL layer in facebook/mysql-5.6,
but is part of the storage engine in MariaRocks
*/
#include <regex>
class Regex_list_handler
{
private:
#if defined(HAVE_PSI_INTERFACE)
const PSI_rwlock_key& m_key;
#endif
char m_delimiter;
std::string m_bad_pattern_str;
const std::regex* m_pattern;
mutable mysql_rwlock_t m_rwlock;
Regex_list_handler(const Regex_list_handler& other)= delete;
Regex_list_handler& operator=(const Regex_list_handler& other)= delete;
public:
#if defined(HAVE_PSI_INTERFACE)
Regex_list_handler(const PSI_rwlock_key& key,
char delimiter= ',') :
m_key(key),
#else
Regex_list_handler(char delimiter= ',') :
#endif
m_delimiter(delimiter),
m_bad_pattern_str(""),
m_pattern(nullptr)
{
mysql_rwlock_init(key, &m_rwlock);
}
~Regex_list_handler()
{
mysql_rwlock_destroy(&m_rwlock);
delete m_pattern;
}
// Set the list of patterns
bool set_patterns(const std::string& patterns);
// See if a string matches at least one pattern
bool matches(const std::string& str) const;
// See the list of bad patterns
const std::string& bad_pattern() const
{
return m_bad_pattern_str;
}
};
void warn_about_bad_patterns(const Regex_list_handler* regex_list_handler,
const char *name);
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment