Skip to content

Commit

Permalink
PS-8258 feature: Make Percona Server buildable on MacOS with RocksDB …
Browse files Browse the repository at this point in the history
…enabled

https://jira.percona.com/browse/PS-8258

In the top-level 'CMakeList.txt' file we now include 'extra/libkmip'
subdirectory only when 'KMIP' keying component is configured to be built.

RocksDB Storage Engine 'CMakeLists.txt' file now detects MacOS ('Darwin')
platform and adds 'OS_MACOSX' preprocessor definition.

'rt' system library no longer added to 'ha_rocksdb.so' as a dependency
on MacOS.

'rdb_buff.h' header from the RocksDB Storage Engine code extended with
a set of macros for emulating big-endian / little-endian
byte-manipulation functions for MacOS.

Some RocksDB system variables declared with 'MYSQL_SYSVAR_ENUM' were
using global variables of type 'uint64_t'. This was incompatible with
the macro definition as it expected variables of type 'ulong'. On Linux
platform it was not a problem as 'uint64_t' was defined as 'unsigned long'
there. However, on MacOS 'uint64_t' is defined as 'unsigned long long'.
Fixed by changing the type of underlying variables from 'uint64_t' to
'ulong'.

The family of 'MYSQL_SYSVAR_XXX' macros extended with
'MYSQL_SYSVAR_UINT64_T' that is supposed to be used for 'uint64_t'
variables. Because of the same reasons ('uint64_t' being defined
differently on Linux and MacOS) we needed this new macro to be able
bind system variables directly to RocksDB library variables that have
'uint64_t' type (the type of which we cannot change as this is RocksDB
submodule code).

A number of 'xxxprintf()' calls in the RocksDB Storage Engine code were
incorrectly using '%lu' format specifier for 'uint64_t' types. Again,
this was not a problem on Linux as 'uint64_t' was defined as
'unsigned long' there. For compatibility with MacOS, fixed by using
proper 'PRIu64' format specifier instead.

Fixed problem with passing an empty string to the 'std::regexp'
constructor that used to work on Linux but is not allowed by the
standard.
  • Loading branch information
percona-ysorokin committed Jun 1, 2022
1 parent bba0569 commit 8d28305
Show file tree
Hide file tree
Showing 10 changed files with 130 additions and 68 deletions.
5 changes: 4 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1894,7 +1894,10 @@ IF(WITH_PROTOBUF STREQUAL "bundled" OR WITH_FIDO STREQUAL "bundled")
ENDIF()
ENDIF()

ADD_SUBDIRECTORY(extra/libkmip)
IF(NOT DEFINED WITH_COMPONENT_KEYRING_KMIP AND NOT DEFINED WITHOUT_COMPONENT_KEYRING_KMIP
OR WITH_COMPONENT_KEYRING_KMIP)
ADD_SUBDIRECTORY(extra/libkmip)
ENDIF()

#
# Setup maintainer mode options by the end. Platform checks are
Expand Down
14 changes: 14 additions & 0 deletions include/mysql/plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,20 @@ typedef void (*mysql_var_update_func)(MYSQL_THD thd, SYS_VAR *var,
max, \
blk}

#define MYSQL_SYSVAR_UINT64_T(name, varname, opt, comment, check, update, def, \
min, max, blk) \
DECLARE_MYSQL_SYSVAR_SIMPLE(name, uint64_t) = { \
PLUGIN_VAR_LONGLONG | PLUGIN_VAR_UNSIGNED | ((opt)&PLUGIN_VAR_MASK), \
#name, \
comment, \
check, \
update, \
&varname, \
def, \
min, \
max, \
blk}

#define MYSQL_SYSVAR_ENUM(name, varname, opt, comment, check, update, def, \
typelib) \
DECLARE_MYSQL_SYSVAR_TYPELIB(name, unsigned long) = { \
Expand Down
4 changes: 4 additions & 0 deletions storage/innobase/os/os0populate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include <sys/utsname.h> /* uname() */
#endif

#if OS_MAP_POPULATE

/** Retrieve and compare operating system release.
@return TRUE if the OS release is equal to, or later than release. */
static bool os_compare_release(const char *release [[maybe_unused]]) {
Expand All @@ -17,6 +19,8 @@ static bool os_compare_release(const char *release [[maybe_unused]]) {
#endif
}

#endif

void prefault_if_not_map_populate(void *ptr [[maybe_unused]],
size_t n_bytes [[maybe_unused]]) {
#if OS_MAP_POPULATE
Expand Down
7 changes: 6 additions & 1 deletion storage/rocksdb/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@ ENDIF()

IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
add_definitions(-DOS_LINUX)
ELSEIF(CMAKE_SYSTEM_NAME MATCHES "Darwin")
add_definitions(-DOS_MACOSX)
ENDIF()

ROCKSDB_SET_DEFINTIONS()
Expand Down Expand Up @@ -304,7 +306,10 @@ IF(HAVE_EXTERNAL_ROCKSDB)
SET(rocksdb_static_libs ${rocksdb_static_libs} "${ROCKSDB_LIB_PATH}/${ROCKSDB_LIB_NAME}")
ENDIF()

SET(rocksdb_static_libs ${rocksdb_static_libs} ${ZLIB_LIBRARY} ${ZSTD_LIBRARY} ${LZ4_LIBRARY} "-lrt" "-ldl" ${PLUGIN_LD})
SET(rocksdb_static_libs ${rocksdb_static_libs} ${ZLIB_LIBRARY} ${ZSTD_LIBRARY} ${LZ4_LIBRARY} "-ldl" ${PLUGIN_LD})
IF(NOT CMAKE_SYSTEM_NAME MATCHES "Darwin")
SET(rocksdb_static_libs ${rocksdb_static_libs} "-lrt")
ENDIF()

MYSQL_ADD_PLUGIN(rocksdb ${ROCKSDB_SOURCES} STORAGE_ENGINE DEFAULT MODULE_ONLY
LINK_LIBRARIES ${rocksdb_static_libs}
Expand Down
129 changes: 67 additions & 62 deletions storage/rocksdb/ha_rocksdb.cc
Original file line number Diff line number Diff line change
Expand Up @@ -660,11 +660,11 @@ static unsigned long long rocksdb_delayed_write_rate;
static uint32_t rocksdb_max_latest_deadlocks = RDB_DEADLOCK_DETECT_DEPTH;
static unsigned long // NOLINT(runtime/int)
rocksdb_persistent_cache_size_mb = 0;
static uint64_t rocksdb_info_log_level = rocksdb::InfoLogLevel::ERROR_LEVEL;
static ulong rocksdb_info_log_level = rocksdb::InfoLogLevel::ERROR_LEVEL;
static char *rocksdb_wal_dir = nullptr;
static char *rocksdb_persistent_cache_path = nullptr;
static char *rocksdb_wsenv_path = nullptr;
static uint64_t rocksdb_index_type =
static ulong rocksdb_index_type =
rocksdb::BlockBasedTableOptions::kBinarySearch;
static uint32_t rocksdb_flush_log_at_trx_commit = 1;
static uint32_t rocksdb_debug_optimizer_n_rows = 0;
Expand Down Expand Up @@ -725,8 +725,7 @@ static bool rpl_skip_tx_api_var = false;
static bool rocksdb_print_snapshot_conflict_queries = false;
static bool rocksdb_large_prefix = true;
static bool rocksdb_allow_to_start_after_corruption = false;
static uint64_t rocksdb_write_policy =
rocksdb::TxnDBWritePolicy::WRITE_COMMITTED;
static ulong rocksdb_write_policy = rocksdb::TxnDBWritePolicy::WRITE_COMMITTED;
char *rocksdb_read_free_rpl_tables;
ulong rocksdb_max_row_locks;
std::mutex rocksdb_read_free_rpl_tables_mutex;
Expand All @@ -736,7 +735,7 @@ Regex_list_handler rdb_read_free_regex_handler(key_rwlock_read_free_rpl_tables);
Regex_list_handler rdb_read_free_regex_handler;
#endif
enum read_free_rpl_type { OFF = 0, PK_ONLY, PK_SK };
static uint64_t rocksdb_read_free_rpl = read_free_rpl_type::OFF;
static ulong rocksdb_read_free_rpl = read_free_rpl_type::OFF;
static bool rocksdb_error_on_suboptimal_collation = false;
static uint32_t rocksdb_stats_recalc_rate = 0;
static bool rocksdb_no_create_column_family = false;
Expand Down Expand Up @@ -888,12 +887,13 @@ static int rocksdb_tracing(THD *const thd MY_ATTRIBUTE((__unused__)),
return HA_EXIT_FAILURE;
}
// NO_LINT_DEBUG
LogPluginErrMsg(
INFORMATION_LEVEL, 0,
"Start tracing block cache accesses or queries. Sampling frequency: %lu, "
"Maximum trace file size: %lu, Trace file path %s.\n",
trace_opt.sampling_frequency, trace_opt.max_trace_file_size,
trace_file_path.c_str());
LogPluginErrMsg(INFORMATION_LEVEL, 0,
"Start tracing block cache accesses or queries. Sampling "
"frequency: %" PRIu64
", "
"Maximum trace file size: %" PRIu64 ", Trace file path %s.\n",
trace_opt.sampling_frequency, trace_opt.max_trace_file_size,
trace_file_path.c_str());
// Save the trace option.
*static_cast<const char **>(save) = trace_opt_str_raw;
return HA_EXIT_SUCCESS;
Expand Down Expand Up @@ -1500,12 +1500,13 @@ static MYSQL_SYSVAR_INT(max_open_files, rocksdb_db_options->max_open_files,
nullptr, rocksdb_db_options->max_open_files,
/* min */ -2, /* max */ INT_MAX, 0);

static MYSQL_SYSVAR_ULONG(max_total_wal_size,
rocksdb_db_options->max_total_wal_size,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"DBOptions::max_total_wal_size for RocksDB", nullptr,
nullptr, rocksdb_db_options->max_total_wal_size,
/* min */ 0L, /* max */ LONG_MAX, 0);
static MYSQL_SYSVAR_UINT64_T(max_total_wal_size,
rocksdb_db_options->max_total_wal_size,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"DBOptions::max_total_wal_size for RocksDB",
nullptr, nullptr,
rocksdb_db_options->max_total_wal_size,
/* min */ 0L, /* max */ LONG_MAX, 0);

static MYSQL_SYSVAR_BOOL(use_fsync,
*static_cast<bool *>(&rocksdb_db_options->use_fsync),
Expand Down Expand Up @@ -1542,7 +1543,7 @@ static MYSQL_SYSVAR_STR(fault_injection_options,
"Fault injection options for running rocksdb tests",
nullptr, nullptr, nullptr);

static MYSQL_SYSVAR_ULONG(
static MYSQL_SYSVAR_UINT64_T(
delete_obsolete_files_period_micros,
rocksdb_db_options->delete_obsolete_files_period_micros,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
Expand Down Expand Up @@ -1623,13 +1624,13 @@ static MYSQL_SYSVAR_ULONG(keep_log_file_num,
nullptr, rocksdb_db_options->keep_log_file_num,
/* min */ 0L, /* max */ LONG_MAX, 0);

static MYSQL_SYSVAR_ULONG(max_manifest_file_size,
rocksdb_db_options->max_manifest_file_size,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"DBOptions::max_manifest_file_size for RocksDB",
nullptr, nullptr,
rocksdb_db_options->max_manifest_file_size,
/* min */ 0L, /* max */ ULONG_MAX, 0);
static MYSQL_SYSVAR_UINT64_T(max_manifest_file_size,
rocksdb_db_options->max_manifest_file_size,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"DBOptions::max_manifest_file_size for RocksDB",
nullptr, nullptr,
rocksdb_db_options->max_manifest_file_size,
/* min */ 0L, /* max */ ULONG_MAX, 0);

static MYSQL_SYSVAR_INT(table_cache_numshardbits,
rocksdb_db_options->table_cache_numshardbits,
Expand All @@ -1639,18 +1640,20 @@ static MYSQL_SYSVAR_INT(table_cache_numshardbits,
rocksdb_db_options->table_cache_numshardbits,
/* min */ 0, /* max */ 19, 0);

static MYSQL_SYSVAR_ULONG(wal_ttl_seconds, rocksdb_db_options->WAL_ttl_seconds,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"DBOptions::WAL_ttl_seconds for RocksDB", nullptr,
nullptr, rocksdb_db_options->WAL_ttl_seconds,
/* min */ 0L, /* max */ LONG_MAX, 0);
static MYSQL_SYSVAR_UINT64_T(wal_ttl_seconds,
rocksdb_db_options->WAL_ttl_seconds,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"DBOptions::WAL_ttl_seconds for RocksDB", nullptr,
nullptr, rocksdb_db_options->WAL_ttl_seconds,
/* min */ 0L, /* max */ LONG_MAX, 0);

static MYSQL_SYSVAR_ULONG(wal_size_limit_mb,
rocksdb_db_options->WAL_size_limit_MB,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"DBOptions::WAL_size_limit_MB for RocksDB", nullptr,
nullptr, rocksdb_db_options->WAL_size_limit_MB,
/* min */ 0L, /* max */ LONG_MAX, 0);
static MYSQL_SYSVAR_UINT64_T(wal_size_limit_mb,
rocksdb_db_options->WAL_size_limit_MB,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"DBOptions::WAL_size_limit_MB for RocksDB",
nullptr, nullptr,
rocksdb_db_options->WAL_size_limit_MB,
/* min */ 0L, /* max */ LONG_MAX, 0);

static MYSQL_SYSVAR_ULONG(manifest_preallocation_size,
rocksdb_db_options->manifest_preallocation_size,
Expand Down Expand Up @@ -1726,20 +1729,20 @@ static MYSQL_SYSVAR_BOOL(
"DBOptions::use_adaptive_mutex for RocksDB", nullptr, nullptr,
rocksdb_db_options->use_adaptive_mutex);

static MYSQL_SYSVAR_ULONG(bytes_per_sync, rocksdb_db_options->bytes_per_sync,
PLUGIN_VAR_RQCMDARG,
"DBOptions::bytes_per_sync for RocksDB", nullptr,
rocksdb_set_bytes_per_sync,
rocksdb_db_options->bytes_per_sync,
/* min */ 0L, /* max */ LONG_MAX, 0);
static MYSQL_SYSVAR_UINT64_T(bytes_per_sync, rocksdb_db_options->bytes_per_sync,
PLUGIN_VAR_RQCMDARG,
"DBOptions::bytes_per_sync for RocksDB", nullptr,
rocksdb_set_bytes_per_sync,
rocksdb_db_options->bytes_per_sync,
/* min */ 0L, /* max */ LONG_MAX, 0);

static MYSQL_SYSVAR_ULONG(wal_bytes_per_sync,
rocksdb_db_options->wal_bytes_per_sync,
PLUGIN_VAR_RQCMDARG,
"DBOptions::wal_bytes_per_sync for RocksDB", nullptr,
rocksdb_set_wal_bytes_per_sync,
rocksdb_db_options->wal_bytes_per_sync,
/* min */ 0L, /* max */ LONG_MAX, 0);
static MYSQL_SYSVAR_UINT64_T(wal_bytes_per_sync,
rocksdb_db_options->wal_bytes_per_sync,
PLUGIN_VAR_RQCMDARG,
"DBOptions::wal_bytes_per_sync for RocksDB",
nullptr, rocksdb_set_wal_bytes_per_sync,
rocksdb_db_options->wal_bytes_per_sync,
/* min */ 0L, /* max */ LONG_MAX, 0);

static MYSQL_SYSVAR_BOOL(
enable_thread_tracking,
Expand Down Expand Up @@ -1821,11 +1824,11 @@ static MYSQL_SYSVAR_BOOL(
"BlockBasedTableOptions::no_block_cache for RocksDB", nullptr, nullptr,
rocksdb_tbl_options->no_block_cache);

static MYSQL_SYSVAR_ULONG(block_size, rocksdb_tbl_options->block_size,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"BlockBasedTableOptions::block_size for RocksDB",
nullptr, nullptr, rocksdb_tbl_options->block_size,
/* min */ 1024L, /* max */ LONG_MAX, 0);
static MYSQL_SYSVAR_UINT64_T(block_size, rocksdb_tbl_options->block_size,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"BlockBasedTableOptions::block_size for RocksDB",
nullptr, nullptr, rocksdb_tbl_options->block_size,
/* min */ 1024L, /* max */ LONG_MAX, 0);

static MYSQL_SYSVAR_INT(
block_size_deviation, rocksdb_tbl_options->block_size_deviation,
Expand Down Expand Up @@ -5361,14 +5364,15 @@ static bool rocksdb_show_status(handlerton *const hton, THD *const thd,
// NB! We're replacing hyphens with underscores in output to better match
// the existing naming convention.
if (rdb->GetIntProperty("rocksdb.is-write-stopped", &v)) {
snprintf(buf, sizeof(buf), "rocksdb.is_write_stopped COUNT : %lu\n", v);
snprintf(buf, sizeof(buf),
"rocksdb.is_write_stopped COUNT : %" PRIu64 "\n", v);
str.append(buf);
}

if (rdb->GetIntProperty("rocksdb.actual-delayed-write-rate", &v)) {
snprintf(buf, sizeof(buf),
"rocksdb.actual_delayed_write_rate "
"COUNT : %lu\n",
"COUNT : %" PRIu64 "\n",
v);
str.append(buf);
}
Expand Down Expand Up @@ -5439,20 +5443,21 @@ static bool rocksdb_show_status(handlerton *const hton, THD *const thd,
rocksdb::MemoryUtil::GetApproximateMemoryUsageByType(dbs, cache_set,
&temp_usage_by_type);

snprintf(buf, sizeof(buf), "\nMemTable Total: %lu",
snprintf(buf, sizeof(buf), "\nMemTable Total: %" PRIu64,
temp_usage_by_type[rocksdb::MemoryUtil::kMemTableTotal]);
str.append(buf);
snprintf(buf, sizeof(buf), "\nMemTable Unflushed: %lu",
snprintf(buf, sizeof(buf), "\nMemTable Unflushed: %" PRIu64,
temp_usage_by_type[rocksdb::MemoryUtil::kMemTableUnFlushed]);
str.append(buf);
snprintf(buf, sizeof(buf), "\nTable Readers Total: %lu",
snprintf(buf, sizeof(buf), "\nTable Readers Total: %" PRIu64,
temp_usage_by_type[rocksdb::MemoryUtil::kTableReadersTotal]);
str.append(buf);
snprintf(buf, sizeof(buf), "\nCache Total: %lu",
snprintf(buf, sizeof(buf), "\nCache Total: %" PRIu64,
temp_usage_by_type[rocksdb::MemoryUtil::kCacheTotal]);
str.append(buf);
snprintf(buf, sizeof(buf), "\nDefault Cache Capacity: %lu",
internal_cache_count * kDefaultInternalCacheSize);
snprintf(buf, sizeof(buf), "\nDefault Cache Capacity: %" PRIu64,
internal_cache_count *
static_cast<uint64_t>(kDefaultInternalCacheSize));
str.append(buf);
res |= print_stats(thd, "MEMORY_STATS", "rocksdb", str, stat_print);

Expand Down
4 changes: 3 additions & 1 deletion storage/rocksdb/ib_ut0counter.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,9 @@ struct thread_id_indexer_t : public generic_indexer_t<Type, N> {
/* @return a random number, currently we use the thread id. Where
thread id is represented as a pointer, it may not work as
effectively. */
size_t get_rnd_index() const { return get_curr_thread_id(); }
size_t get_rnd_index() const {
return reinterpret_cast<std::uintptr_t>(get_curr_thread_id());
}
};

/** For counters wher N=1 */
Expand Down
3 changes: 2 additions & 1 deletion storage/rocksdb/properties_collector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,8 @@ void Rdb_index_stats::merge(const Rdb_index_stats &s, const bool increment,

void Rdb_index_stats::adjust_cardinality(double adjustment_factor) {
for (int64_t &num_keys : m_distinct_keys_per_prefix) {
num_keys = std::max(1L, static_cast<int64_t>(num_keys * adjustment_factor));
num_keys = std::max(static_cast<int64_t>(1),
static_cast<int64_t>(num_keys * adjustment_factor));
}
}

Expand Down
21 changes: 21 additions & 0 deletions storage/rocksdb/rdb_buff.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,27 @@
#include "rocksdb/slice.h"
#include "rocksdb/status.h"

#ifdef OS_MACOSX

#include <libkern/OSByteOrder.h>

#define htobe16(x) OSSwapHostToBigInt16(x)
#define htole16(x) OSSwapHostToLittleInt16(x)
#define be16toh(x) OSSwapBigToHostInt16(x)
#define le16toh(x) OSSwapLittleToHostInt16(x)

#define htobe32(x) OSSwapHostToBigInt32(x)
#define htole32(x) OSSwapHostToLittleInt32(x)
#define be32toh(x) OSSwapBigToHostInt32(x)
#define le32toh(x) OSSwapLittleToHostInt32(x)

#define htobe64(x) OSSwapHostToBigInt64(x)
#define htole64(x) OSSwapHostToLittleInt64(x)
#define be64toh(x) OSSwapBigToHostInt64(x)
#define le64toh(x) OSSwapLittleToHostInt64(x)

#endif

namespace myrocks {

/*
Expand Down
3 changes: 2 additions & 1 deletion storage/rocksdb/rdb_sst_info.cc
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,8 @@ rocksdb::Status Rdb_sst_file_ordered::Rdb_sst_file::commit() {
if (m_tracing) {
LogPluginErrMsg(INFORMATION_LEVEL, 0,
"SST Tracing: Adding file %s, smallest key: %s, "
"largest key: %s, file size: %lu, num_entries: %lu",
"largest key: %s, file size: %" PRIu64
", num_entries: %" PRIu64,
fileinfo.file_path.c_str(),
generateKey(fileinfo.smallest_key).c_str(),
generateKey(fileinfo.largest_key).c_str(),
Expand Down
8 changes: 7 additions & 1 deletion storage/rocksdb/rdb_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,13 @@ bool Regex_list_handler::set_patterns(
// 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.
m_pattern.reset(new std::regex(norm_pattern, flags));

// std::regex implementation on MacOS X does not allow empty strings in
// constructors
if (norm_pattern.empty())
m_pattern.reset(new std::regex);
else
m_pattern.reset(new std::regex(norm_pattern, flags));
} catch (const std::regex_error &e) {
// This pattern is invalid.
pattern_valid = false;
Expand Down

0 comments on commit 8d28305

Please sign in to comment.