mirror of
https://github.com/facebook/rocksdb.git
synced 2026-11-07 11:32:34 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
04f6516185 | ||
|
|
a3fd64e040 | ||
|
|
05550569db | ||
|
|
1d65b3d4f2 | ||
|
|
626550343f | ||
|
|
e12d15320a | ||
|
|
6a5e8486b6 | ||
|
|
940641c3cc | ||
|
|
b6c49fc5b4 | ||
|
|
a9ed4139fc |
No files matched your search
@@ -1,4 +1,11 @@
|
||||
# Rocksdb Change Log
|
||||
|
||||
## 5.14.3 (8/21/2018)
|
||||
### Public API Change
|
||||
* The merge operands are passed to `MergeOperator::ShouldMerge` in the reversed order relative to how they were merged (passed to FullMerge or FullMergeV2) for performance reasons
|
||||
### Bug Fixes
|
||||
* Fixes DBImpl::FindObsoleteFiles() calling GetChildren() on the same path
|
||||
|
||||
## 5.14.2 (7/3/2018)
|
||||
### Bug Fixes
|
||||
* Change default value of `bytes_max_delete_chunk` to 0 in NewSstFileManager() as it doesn't work well with checkpoints.
|
||||
|
||||
@@ -1587,7 +1587,7 @@ ZLIB_SHA256 ?= c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1
|
||||
ZLIB_DOWNLOAD_BASE ?= http://zlib.net
|
||||
BZIP2_VER ?= 1.0.6
|
||||
BZIP2_SHA256 ?= a2848f34fcd5d6cf47def00461fcb528a0484d8edef8208d6d2e2909dc61d9cd
|
||||
BZIP2_DOWNLOAD_BASE ?= http://www.bzip.org
|
||||
BZIP2_DOWNLOAD_BASE ?= https://web.archive.org/web/20180624184835/http://www.bzip.org
|
||||
SNAPPY_VER ?= 1.1.4
|
||||
SNAPPY_SHA256 ?= 134bfe122fd25599bb807bb8130e7ba6d9bdb851e0b16efcb83ac4f5d0b70057
|
||||
SNAPPY_DOWNLOAD_BASE ?= https://github.com/google/snappy/releases/download
|
||||
|
||||
@@ -1069,14 +1069,3 @@ if not is_opt_mode:
|
||||
command = [TEST_RUNNER, BUCK_BINS + test_bin]
|
||||
)
|
||||
|
||||
custom_unittest(
|
||||
name = "make_rocksdbjavastatic",
|
||||
command = ["internal_repo_rocksdb/make_rocksdbjavastatic.sh"],
|
||||
type = "simple",
|
||||
)
|
||||
|
||||
custom_unittest(
|
||||
name = "make_rocksdb_lite_release",
|
||||
command = ["internal_repo_rocksdb/make_rocksdb_lite_release.sh"],
|
||||
type = "simple",
|
||||
)
|
||||
@@ -135,15 +135,4 @@ if not is_opt_mode:
|
||||
command = [TEST_RUNNER, BUCK_BINS + test_bin]
|
||||
)
|
||||
|
||||
custom_unittest(
|
||||
name = "make_rocksdbjavastatic",
|
||||
command = ["internal_repo_rocksdb/make_rocksdbjavastatic.sh"],
|
||||
type = "simple",
|
||||
)
|
||||
|
||||
custom_unittest(
|
||||
name = "make_rocksdb_lite_release",
|
||||
command = ["internal_repo_rocksdb/make_rocksdb_lite_release.sh"],
|
||||
type = "simple",
|
||||
)
|
||||
"""
|
||||
@@ -53,11 +53,13 @@ if [ -z "$ROCKSDB_NO_FBCODE" -a -d /mnt/gvfs/third-party ]; then
|
||||
FBCODE_BUILD="true"
|
||||
# If we're compiling with TSAN we need pic build
|
||||
PIC_BUILD=$COMPILE_WITH_TSAN
|
||||
if [ -z "$ROCKSDB_FBCODE_BUILD_WITH_481" ]; then
|
||||
source "$PWD/build_tools/fbcode_config.sh"
|
||||
else
|
||||
if [ -n "$ROCKSDB_FBCODE_BUILD_WITH_481" ]; then
|
||||
# we need this to build with MySQL. Don't use for other purposes.
|
||||
source "$PWD/build_tools/fbcode_config4.8.1.sh"
|
||||
elif [ -n "$ROCKSDB_FBCODE_BUILD_WITH_5xx" ]; then
|
||||
source "$PWD/build_tools/fbcode_config.sh"
|
||||
else
|
||||
source "$PWD/build_tools/fbcode_config_platform007.sh"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
GCC_BASE=/mnt/gvfs/third-party2/gcc/6e8e715624fd15256a7970073387793dfcf79b46/7.x/centos7-native/b2ef2b6
|
||||
CLANG_BASE=/mnt/gvfs/third-party2/llvm-fb/ef37e1faa1c29782abfac1ae65a291b9b7966f6d/stable/centos7-native/c9f9104
|
||||
LIBGCC_BASE=/mnt/gvfs/third-party2/libgcc/c67031f0f739ac61575a061518d6ef5038f99f90/7.x/platform007/5620abc
|
||||
GLIBC_BASE=/mnt/gvfs/third-party2/glibc/60d6f124a78798b73944f5ba87c2306ae3460153/2.26/platform007/f259413
|
||||
SNAPPY_BASE=/mnt/gvfs/third-party2/snappy/7f9bdaada18f59bc27ec2b0871eb8a6144343aef/1.1.3/platform007/ca4da3d
|
||||
ZLIB_BASE=/mnt/gvfs/third-party2/zlib/22c2d65676fb7c23cfa797c4f6937f38b026f3cf/1.2.8/platform007/ca4da3d
|
||||
BZIP2_BASE=/mnt/gvfs/third-party2/bzip2/dc49a21c5fceec6456a7a28a94dcd16690af1337/1.0.6/platform007/ca4da3d
|
||||
LZ4_BASE=/mnt/gvfs/third-party2/lz4/907b498203d297947f3bb70b9466f47e100f1873/r131/platform007/ca4da3d
|
||||
ZSTD_BASE=/mnt/gvfs/third-party2/zstd/3ee276cbacfad3074e3f07bf826ac47f06970f4e/1.3.5/platform007/15a3614
|
||||
GFLAGS_BASE=/mnt/gvfs/third-party2/gflags/0b9929d2588991c65a57168bf88aff2db87c5d48/2.2.0/platform007/ca4da3d
|
||||
JEMALLOC_BASE=/mnt/gvfs/third-party2/jemalloc/9c910d36d6235cc40e8ff559358f1833452300ca/master/platform007/5b0f53e
|
||||
NUMA_BASE=/mnt/gvfs/third-party2/numa/9cbf2460284c669ed19c3ccb200a71f7dd7e53c7/2.0.11/platform007/ca4da3d
|
||||
LIBUNWIND_BASE=/mnt/gvfs/third-party2/libunwind/bf3d7497fe4e6d007354f0adffa16ce3003f8338/1.3/platform007/6f3e0a9
|
||||
TBB_BASE=/mnt/gvfs/third-party2/tbb/ff4e0b093534704d8abab678a4fd7f5ea7b094c7/2018_U5/platform007/ca4da3d
|
||||
KERNEL_HEADERS_BASE=/mnt/gvfs/third-party2/kernel-headers/b5c4a61a5c483ba24722005ae07895971a2ac707/fb/platform007/da39a3e
|
||||
BINUTILS_BASE=/mnt/gvfs/third-party2/binutils/92ff90349e2f43ea0a8246d8b1cf17b6869013e3/2.29.1/centos7-native/da39a3e
|
||||
VALGRIND_BASE=/mnt/gvfs/third-party2/valgrind/f3f697a28122e6bcd513273dd9c1ff23852fc59f/3.13.0/platform007/ca4da3d
|
||||
LUA_BASE=/mnt/gvfs/third-party2/lua/f0cd714433206d5139df61659eb7b28b1dea6683/5.3.4/platform007/5007832
|
||||
@@ -0,0 +1,157 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Set environment variables so that we can compile rocksdb using
|
||||
# fbcode settings. It uses the latest g++ and clang compilers and also
|
||||
# uses jemalloc
|
||||
# Environment variables that change the behavior of this script:
|
||||
# PIC_BUILD -- if true, it will only take pic versions of libraries from fbcode. libraries that don't have pic variant will not be included
|
||||
|
||||
|
||||
BASEDIR=`dirname $BASH_SOURCE`
|
||||
source "$BASEDIR/dependencies_platform007.sh"
|
||||
|
||||
CFLAGS=""
|
||||
|
||||
# libgcc
|
||||
LIBGCC_INCLUDE="$LIBGCC_BASE/include/c++/7.3.0"
|
||||
LIBGCC_LIBS=" -L $LIBGCC_BASE/lib"
|
||||
|
||||
# glibc
|
||||
GLIBC_INCLUDE="$GLIBC_BASE/include"
|
||||
GLIBC_LIBS=" -L $GLIBC_BASE/lib"
|
||||
|
||||
# snappy
|
||||
SNAPPY_INCLUDE=" -I $SNAPPY_BASE/include/"
|
||||
if test -z $PIC_BUILD; then
|
||||
SNAPPY_LIBS=" $SNAPPY_BASE/lib/libsnappy.a"
|
||||
else
|
||||
SNAPPY_LIBS=" $SNAPPY_BASE/lib/libsnappy_pic.a"
|
||||
fi
|
||||
CFLAGS+=" -DSNAPPY"
|
||||
|
||||
if test -z $PIC_BUILD; then
|
||||
# location of zlib headers and libraries
|
||||
ZLIB_INCLUDE=" -I $ZLIB_BASE/include/"
|
||||
ZLIB_LIBS=" $ZLIB_BASE/lib/libz.a"
|
||||
CFLAGS+=" -DZLIB"
|
||||
|
||||
# location of bzip headers and libraries
|
||||
BZIP_INCLUDE=" -I $BZIP2_BASE/include/"
|
||||
BZIP_LIBS=" $BZIP2_BASE/lib/libbz2.a"
|
||||
CFLAGS+=" -DBZIP2"
|
||||
|
||||
LZ4_INCLUDE=" -I $LZ4_BASE/include/"
|
||||
LZ4_LIBS=" $LZ4_BASE/lib/liblz4.a"
|
||||
CFLAGS+=" -DLZ4"
|
||||
fi
|
||||
|
||||
ZSTD_INCLUDE=" -I $ZSTD_BASE/include/"
|
||||
if test -z $PIC_BUILD; then
|
||||
ZSTD_LIBS=" $ZSTD_BASE/lib/libzstd.a"
|
||||
else
|
||||
ZSTD_LIBS=" $ZSTD_BASE/lib/libzstd_pic.a"
|
||||
fi
|
||||
CFLAGS+=" -DZSTD"
|
||||
|
||||
# location of gflags headers and libraries
|
||||
GFLAGS_INCLUDE=" -I $GFLAGS_BASE/include/"
|
||||
if test -z $PIC_BUILD; then
|
||||
GFLAGS_LIBS=" $GFLAGS_BASE/lib/libgflags.a"
|
||||
else
|
||||
GFLAGS_LIBS=" $GFLAGS_BASE/lib/libgflags_pic.a"
|
||||
fi
|
||||
CFLAGS+=" -DGFLAGS=gflags"
|
||||
|
||||
# location of jemalloc
|
||||
JEMALLOC_INCLUDE=" -I $JEMALLOC_BASE/include/"
|
||||
JEMALLOC_LIB=" $JEMALLOC_BASE/lib/libjemalloc.a"
|
||||
|
||||
if test -z $PIC_BUILD; then
|
||||
# location of numa
|
||||
NUMA_INCLUDE=" -I $NUMA_BASE/include/"
|
||||
NUMA_LIB=" $NUMA_BASE/lib/libnuma.a"
|
||||
CFLAGS+=" -DNUMA"
|
||||
|
||||
# location of libunwind
|
||||
LIBUNWIND="$LIBUNWIND_BASE/lib/libunwind.a"
|
||||
fi
|
||||
|
||||
# location of TBB
|
||||
TBB_INCLUDE=" -isystem $TBB_BASE/include/"
|
||||
if test -z $PIC_BUILD; then
|
||||
TBB_LIBS="$TBB_BASE/lib/libtbb.a"
|
||||
else
|
||||
TBB_LIBS="$TBB_BASE/lib/libtbb_pic.a"
|
||||
fi
|
||||
CFLAGS+=" -DTBB"
|
||||
|
||||
# use Intel SSE support for checksum calculations
|
||||
export USE_SSE=1
|
||||
export PORTABLE=1
|
||||
|
||||
BINUTILS="$BINUTILS_BASE/bin"
|
||||
AR="$BINUTILS/ar"
|
||||
|
||||
DEPS_INCLUDE="$SNAPPY_INCLUDE $ZLIB_INCLUDE $BZIP_INCLUDE $LZ4_INCLUDE $ZSTD_INCLUDE $GFLAGS_INCLUDE $NUMA_INCLUDE $TBB_INCLUDE"
|
||||
|
||||
STDLIBS="-L $GCC_BASE/lib64"
|
||||
|
||||
CLANG_BIN="$CLANG_BASE/bin"
|
||||
CLANG_LIB="$CLANG_BASE/lib"
|
||||
CLANG_SRC="$CLANG_BASE/../../src"
|
||||
|
||||
CLANG_ANALYZER="$CLANG_BIN/clang++"
|
||||
CLANG_SCAN_BUILD="$CLANG_SRC/llvm/tools/clang/tools/scan-build/bin/scan-build"
|
||||
|
||||
if [ -z "$USE_CLANG" ]; then
|
||||
# gcc
|
||||
CC="$GCC_BASE/bin/gcc"
|
||||
CXX="$GCC_BASE/bin/g++"
|
||||
|
||||
CFLAGS+=" -B$BINUTILS/gold"
|
||||
CFLAGS+=" -isystem $LIBGCC_INCLUDE"
|
||||
CFLAGS+=" -isystem $GLIBC_INCLUDE"
|
||||
JEMALLOC=1
|
||||
else
|
||||
# clang
|
||||
CLANG_INCLUDE="$CLANG_LIB/clang/stable/include"
|
||||
CC="$CLANG_BIN/clang"
|
||||
CXX="$CLANG_BIN/clang++"
|
||||
|
||||
KERNEL_HEADERS_INCLUDE="$KERNEL_HEADERS_BASE/include"
|
||||
|
||||
CFLAGS+=" -B$BINUTILS/gold -nostdinc -nostdlib"
|
||||
CFLAGS+=" -isystem $LIBGCC_BASE/include/c++/7.x "
|
||||
CFLAGS+=" -isystem $LIBGCC_BASE/include/c++/7.x/x86_64-facebook-linux "
|
||||
CFLAGS+=" -isystem $GLIBC_INCLUDE"
|
||||
CFLAGS+=" -isystem $LIBGCC_INCLUDE"
|
||||
CFLAGS+=" -isystem $CLANG_INCLUDE"
|
||||
CFLAGS+=" -isystem $KERNEL_HEADERS_INCLUDE/linux "
|
||||
CFLAGS+=" -isystem $KERNEL_HEADERS_INCLUDE "
|
||||
CFLAGS+=" -Wno-expansion-to-defined "
|
||||
CXXFLAGS="-nostdinc++"
|
||||
fi
|
||||
|
||||
CFLAGS+=" $DEPS_INCLUDE"
|
||||
CFLAGS+=" -DROCKSDB_PLATFORM_POSIX -DROCKSDB_LIB_IO_POSIX -DROCKSDB_FALLOCATE_PRESENT -DROCKSDB_MALLOC_USABLE_SIZE -DROCKSDB_RANGESYNC_PRESENT -DROCKSDB_SCHED_GETCPU_PRESENT -DROCKSDB_SUPPORT_THREAD_LOCAL -DHAVE_SSE42"
|
||||
CXXFLAGS+=" $CFLAGS"
|
||||
|
||||
EXEC_LDFLAGS=" $SNAPPY_LIBS $ZLIB_LIBS $BZIP_LIBS $LZ4_LIBS $ZSTD_LIBS $GFLAGS_LIBS $NUMA_LIB $TBB_LIBS"
|
||||
EXEC_LDFLAGS+=" -B$BINUTILS/gold"
|
||||
EXEC_LDFLAGS+=" -Wl,--dynamic-linker,/usr/local/fbcode/platform007/lib/ld.so"
|
||||
EXEC_LDFLAGS+=" $LIBUNWIND"
|
||||
EXEC_LDFLAGS+=" -Wl,-rpath=/usr/local/fbcode/platform007/lib"
|
||||
# required by libtbb
|
||||
EXEC_LDFLAGS+=" -ldl"
|
||||
|
||||
PLATFORM_LDFLAGS="$LIBGCC_LIBS $GLIBC_LIBS $STDLIBS -lgcc -lstdc++"
|
||||
|
||||
EXEC_LDFLAGS_SHARED="$SNAPPY_LIBS $ZLIB_LIBS $BZIP_LIBS $LZ4_LIBS $ZSTD_LIBS $GFLAGS_LIBS $TBB_LIBS"
|
||||
|
||||
VALGRIND_VER="$VALGRIND_BASE/bin/"
|
||||
|
||||
# lua not supported because it's on track for deprecation, I think
|
||||
LUA_PATH=
|
||||
LUA_LIB=
|
||||
|
||||
export CC CXX AR CFLAGS CXXFLAGS EXEC_LDFLAGS EXEC_LDFLAGS_SHARED VALGRIND_VER JEMALLOC_LIB JEMALLOC_INCLUDE CLANG_ANALYZER CLANG_SCAN_BUILD LUA_PATH LUA_LIB
|
||||
@@ -85,8 +85,9 @@ NON_SHM="TMPD=/tmp/rocksdb_test_tmp"
|
||||
GCC_481="ROCKSDB_FBCODE_BUILD_WITH_481=1"
|
||||
ASAN="COMPILE_WITH_ASAN=1"
|
||||
CLANG="USE_CLANG=1"
|
||||
LITE="OPT=\"-DROCKSDB_LITE -g\""
|
||||
TSAN="COMPILE_WITH_TSAN=1"
|
||||
# in gcc-5 there are known problems with TSAN like https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71090.
|
||||
# using platform007 gives us gcc-8 or higher which has that bug fixed.
|
||||
TSAN="ROCKSDB_FBCODE_BUILD_WITH_PLATFORM007=1 COMPILE_WITH_TSAN=1"
|
||||
UBSAN="COMPILE_WITH_UBSAN=1"
|
||||
DISABLE_JEMALLOC="DISABLE_JEMALLOC=1"
|
||||
HTTP_PROXY="https_proxy=http://fwdproxy.29.prn1:8080 http_proxy=http://fwdproxy.29.prn1:8080 ftp_proxy=http://fwdproxy.29.prn1:8080"
|
||||
|
||||
@@ -53,6 +53,45 @@ function get_lib_base()
|
||||
log_variable $__res_var
|
||||
}
|
||||
|
||||
###########################################################
|
||||
# platform007 dependencies #
|
||||
###########################################################
|
||||
|
||||
OUTPUT="$BASEDIR/dependencies_platform007.sh"
|
||||
|
||||
rm -f "$OUTPUT"
|
||||
touch "$OUTPUT"
|
||||
|
||||
echo "Writing dependencies to $OUTPUT"
|
||||
|
||||
# Compilers locations
|
||||
GCC_BASE=`readlink -f $TP2_LATEST/gcc/7.x/centos7-native/*/`
|
||||
CLANG_BASE=`readlink -f $TP2_LATEST/llvm-fb/stable/centos7-native/*/`
|
||||
|
||||
log_variable GCC_BASE
|
||||
log_variable CLANG_BASE
|
||||
|
||||
# Libraries locations
|
||||
get_lib_base libgcc 7.x platform007
|
||||
get_lib_base glibc 2.26 platform007
|
||||
get_lib_base snappy LATEST platform007
|
||||
get_lib_base zlib LATEST platform007
|
||||
get_lib_base bzip2 LATEST platform007
|
||||
get_lib_base lz4 LATEST platform007
|
||||
get_lib_base zstd LATEST platform007
|
||||
get_lib_base gflags LATEST platform007
|
||||
get_lib_base jemalloc LATEST platform007
|
||||
get_lib_base numa LATEST platform007
|
||||
get_lib_base libunwind LATEST platform007
|
||||
get_lib_base tbb LATEST platform007
|
||||
|
||||
get_lib_base kernel-headers fb platform007
|
||||
get_lib_base binutils LATEST centos7-native
|
||||
get_lib_base valgrind LATEST platform007
|
||||
get_lib_base lua 5.3.4 platform007
|
||||
|
||||
git diff $OUTPUT
|
||||
|
||||
###########################################################
|
||||
# 5.x dependencies #
|
||||
###########################################################
|
||||
|
||||
+8
-3
@@ -12,6 +12,7 @@
|
||||
#define __STDC_FORMAT_MACROS
|
||||
#endif
|
||||
#include <inttypes.h>
|
||||
#include <set>
|
||||
#include <unordered_set>
|
||||
#include "db/event_helpers.h"
|
||||
#include "db/memtable_list.h"
|
||||
@@ -99,10 +100,10 @@ void DBImpl::FindObsoleteFiles(JobContext* job_context, bool force,
|
||||
if (doing_the_full_scan) {
|
||||
InfoLogPrefix info_log_prefix(!immutable_db_options_.db_log_dir.empty(),
|
||||
dbname_);
|
||||
std::vector<std::string> paths;
|
||||
std::set<std::string> paths;
|
||||
for (size_t path_id = 0; path_id < immutable_db_options_.db_paths.size();
|
||||
path_id++) {
|
||||
paths.emplace_back(immutable_db_options_.db_paths[path_id].path);
|
||||
paths.insert(immutable_db_options_.db_paths[path_id].path);
|
||||
}
|
||||
|
||||
// Note that if cf_paths is not specified in the ColumnFamilyOptions
|
||||
@@ -113,7 +114,11 @@ void DBImpl::FindObsoleteFiles(JobContext* job_context, bool force,
|
||||
for (auto cfd : *versions_->GetColumnFamilySet()) {
|
||||
for (size_t path_id = 0; path_id < cfd->ioptions()->cf_paths.size();
|
||||
path_id++) {
|
||||
paths.emplace_back(cfd->ioptions()->cf_paths[path_id].path);
|
||||
auto& path = cfd->ioptions()->cf_paths[path_id].path;
|
||||
|
||||
if (paths.find(path) == paths.end()) {
|
||||
paths.insert(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -696,7 +696,7 @@ static bool SaveValue(void* arg, const char* entry) {
|
||||
*(s->merge_in_progress) = true;
|
||||
merge_context->PushOperand(
|
||||
v, s->inplace_update_support == false /* operand_pinned */);
|
||||
if (merge_operator->ShouldMerge(merge_context->GetOperands())) {
|
||||
if (merge_operator->ShouldMerge(merge_context->GetOperandsDirectionBackward())) {
|
||||
*(s->status) = MergeHelper::TimedFullMerge(
|
||||
merge_operator, s->key->user_key(), nullptr,
|
||||
merge_context->GetOperands(), s->value, s->logger, s->statistics,
|
||||
|
||||
+16
-1
@@ -74,8 +74,13 @@ class MergeContext {
|
||||
return (*operand_list_)[index];
|
||||
}
|
||||
|
||||
// Return all the operands.
|
||||
// Same as GetOperandsDirectionForward
|
||||
const std::vector<Slice>& GetOperands() {
|
||||
return GetOperandsDirectionForward();
|
||||
}
|
||||
|
||||
// Return all the operands in the order as they were merged (passed to FullMerge or FullMergeV2)
|
||||
const std::vector<Slice>& GetOperandsDirectionForward() {
|
||||
if (!operand_list_) {
|
||||
return empty_operand_list;
|
||||
}
|
||||
@@ -84,6 +89,16 @@ class MergeContext {
|
||||
return *operand_list_;
|
||||
}
|
||||
|
||||
// Return all the operands in the reversed order relative to how they were merged (passed to FullMerge or FullMergeV2)
|
||||
const std::vector<Slice>& GetOperandsDirectionBackward() {
|
||||
if (!operand_list_) {
|
||||
return empty_operand_list;
|
||||
}
|
||||
|
||||
SetDirectionBackward();
|
||||
return *operand_list_;
|
||||
}
|
||||
|
||||
private:
|
||||
void Initialize() {
|
||||
if (!operand_list_) {
|
||||
|
||||
@@ -195,6 +195,11 @@ class MergeOperator {
|
||||
// during a point lookup, thereby helping in limiting the number of levels to
|
||||
// read from.
|
||||
// Doesn't help with iterators.
|
||||
//
|
||||
// Note: the merge operands are passed to this function in the reversed order
|
||||
// relative to how they were merged (passed to FullMerge or FullMergeV2)
|
||||
// for performance reasons, see also:
|
||||
// https://github.com/facebook/rocksdb/issues/3865
|
||||
virtual bool ShouldMerge(const std::vector<Slice>& /*operands*/) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -210,12 +210,20 @@ class LDBCommand {
|
||||
bool ParseStringOption(const std::map<std::string, std::string>& options,
|
||||
const std::string& option, std::string* value);
|
||||
|
||||
/**
|
||||
* Returns the value of the specified option as a boolean.
|
||||
* default_val is used if the option is not found in options.
|
||||
* Throws an exception if the value of the option is not
|
||||
* "true" or "false" (case insensitive).
|
||||
*/
|
||||
bool ParseBooleanOption(const std::map<std::string, std::string>& options,
|
||||
const std::string& option, bool default_val);
|
||||
|
||||
Options options_;
|
||||
std::vector<ColumnFamilyDescriptor> column_families_;
|
||||
LDBOptions ldb_options_;
|
||||
|
||||
private:
|
||||
friend class WALDumperCommand;
|
||||
/**
|
||||
* Interpret command line options and flags to determine if the key
|
||||
* should be input/output in hex.
|
||||
@@ -230,15 +238,6 @@ class LDBCommand {
|
||||
bool IsValueHex(const std::map<std::string, std::string>& options,
|
||||
const std::vector<std::string>& flags);
|
||||
|
||||
/**
|
||||
* Returns the value of the specified option as a boolean.
|
||||
* default_val is used if the option is not found in options.
|
||||
* Throws an exception if the value of the option is not
|
||||
* "true" or "false" (case insensitive).
|
||||
*/
|
||||
bool ParseBooleanOption(const std::map<std::string, std::string>& options,
|
||||
const std::string& option, bool default_val);
|
||||
|
||||
/**
|
||||
* Converts val to a boolean.
|
||||
* val must be either true or false (case insensitive).
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#define ROCKSDB_MAJOR 5
|
||||
#define ROCKSDB_MINOR 14
|
||||
#define ROCKSDB_PATCH 2
|
||||
#define ROCKSDB_PATCH 3
|
||||
|
||||
// Do not use these. We made the mistake of declaring macros starting with
|
||||
// double underscore. Now we have to live with our choice. We'll deprecate these
|
||||
|
||||
@@ -200,7 +200,7 @@ bool GetContext::SaveValue(const ParsedInternalKey& parsed_key,
|
||||
merge_context_->PushOperand(value, false);
|
||||
}
|
||||
if (merge_operator_ != nullptr &&
|
||||
merge_operator_->ShouldMerge(merge_context_->GetOperands())) {
|
||||
merge_operator_->ShouldMerge(merge_context_->GetOperandsDirectionBackward())) {
|
||||
state_ = kFound;
|
||||
if (LIKELY(pinnable_val_ != nullptr)) {
|
||||
Status merge_status = MergeHelper::TimedFullMerge(
|
||||
|
||||
@@ -242,6 +242,14 @@ LDBCommand* LDBCommand::SelectCommand(const ParsedParams& parsed_params) {
|
||||
} else if (parsed_params.cmd == RestoreCommand::Name()) {
|
||||
return new RestoreCommand(parsed_params.cmd_params,
|
||||
parsed_params.option_map, parsed_params.flags);
|
||||
} else if (parsed_params.cmd == WriteExternalSstFilesCommand::Name()) {
|
||||
return new WriteExternalSstFilesCommand(parsed_params.cmd_params,
|
||||
parsed_params.option_map,
|
||||
parsed_params.flags);
|
||||
} else if (parsed_params.cmd == IngestExternalSstFilesCommand::Name()) {
|
||||
return new IngestExternalSstFilesCommand(parsed_params.cmd_params,
|
||||
parsed_params.option_map,
|
||||
parsed_params.flags);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@@ -2936,5 +2944,180 @@ void DBFileDumperCommand::DoCommand() {
|
||||
}
|
||||
}
|
||||
|
||||
void WriteExternalSstFilesCommand::Help(std::string& ret) {
|
||||
ret.append(" ");
|
||||
ret.append(WriteExternalSstFilesCommand::Name());
|
||||
ret.append(" <output_sst_path>");
|
||||
ret.append("\n");
|
||||
}
|
||||
|
||||
WriteExternalSstFilesCommand::WriteExternalSstFilesCommand(
|
||||
const std::vector<std::string>& params,
|
||||
const std::map<std::string, std::string>& options,
|
||||
const std::vector<std::string>& flags)
|
||||
: LDBCommand(
|
||||
options, flags, false /* is_read_only */,
|
||||
BuildCmdLineOptions({ARG_HEX, ARG_KEY_HEX, ARG_VALUE_HEX, ARG_FROM,
|
||||
ARG_TO, ARG_CREATE_IF_MISSING})) {
|
||||
create_if_missing_ =
|
||||
IsFlagPresent(flags, ARG_CREATE_IF_MISSING) ||
|
||||
ParseBooleanOption(options, ARG_CREATE_IF_MISSING, false);
|
||||
if (params.size() != 1) {
|
||||
exec_state_ = LDBCommandExecuteResult::Failed(
|
||||
"output SST file path must be specified");
|
||||
} else {
|
||||
output_sst_path_ = params.at(0);
|
||||
}
|
||||
}
|
||||
|
||||
void WriteExternalSstFilesCommand::DoCommand() {
|
||||
if (!db_) {
|
||||
assert(GetExecuteState().IsFailed());
|
||||
return;
|
||||
}
|
||||
ColumnFamilyHandle* cfh = GetCfHandle();
|
||||
SstFileWriter sst_file_writer(EnvOptions(), db_->GetOptions(), cfh);
|
||||
Status status = sst_file_writer.Open(output_sst_path_);
|
||||
if (!status.ok()) {
|
||||
exec_state_ = LDBCommandExecuteResult::Failed("failed to open SST file: " +
|
||||
status.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
int bad_lines = 0;
|
||||
std::string line;
|
||||
std::ifstream ifs_stdin("/dev/stdin");
|
||||
std::istream* istream_p = ifs_stdin.is_open() ? &ifs_stdin : &std::cin;
|
||||
while (getline(*istream_p, line, '\n')) {
|
||||
std::string key;
|
||||
std::string value;
|
||||
if (ParseKeyValue(line, &key, &value, is_key_hex_, is_value_hex_)) {
|
||||
status = sst_file_writer.Put(key, value);
|
||||
if (!status.ok()) {
|
||||
exec_state_ = LDBCommandExecuteResult::Failed(
|
||||
"failed to write record to file: " + status.ToString());
|
||||
return;
|
||||
}
|
||||
} else if (0 == line.find("Keys in range:")) {
|
||||
// ignore this line
|
||||
} else if (0 == line.find("Created bg thread 0x")) {
|
||||
// ignore this line
|
||||
} else {
|
||||
bad_lines++;
|
||||
}
|
||||
}
|
||||
|
||||
status = sst_file_writer.Finish();
|
||||
if (!status.ok()) {
|
||||
exec_state_ = LDBCommandExecuteResult::Failed(
|
||||
"Failed to finish writing to file: " + status.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
if (bad_lines > 0) {
|
||||
fprintf(stderr, "Warning: %d bad lines ignored.\n", bad_lines);
|
||||
}
|
||||
exec_state_ = LDBCommandExecuteResult::Succeed(
|
||||
"external SST file written to " + output_sst_path_);
|
||||
}
|
||||
|
||||
Options WriteExternalSstFilesCommand::PrepareOptionsForOpenDB() {
|
||||
Options opt = LDBCommand::PrepareOptionsForOpenDB();
|
||||
opt.create_if_missing = create_if_missing_;
|
||||
return opt;
|
||||
}
|
||||
|
||||
const std::string IngestExternalSstFilesCommand::ARG_MOVE_FILES = "move_files";
|
||||
const std::string IngestExternalSstFilesCommand::ARG_SNAPSHOT_CONSISTENCY =
|
||||
"snapshot_consistency";
|
||||
const std::string IngestExternalSstFilesCommand::ARG_ALLOW_GLOBAL_SEQNO =
|
||||
"allow_global_seqno";
|
||||
const std::string IngestExternalSstFilesCommand::ARG_ALLOW_BLOCKING_FLUSH =
|
||||
"allow_blocking_flush";
|
||||
const std::string IngestExternalSstFilesCommand::ARG_INGEST_BEHIND =
|
||||
"ingest_behind";
|
||||
|
||||
void IngestExternalSstFilesCommand::Help(std::string& ret) {
|
||||
ret.append(" ");
|
||||
ret.append(IngestExternalSstFilesCommand::Name());
|
||||
ret.append(" <input_sst_path>");
|
||||
ret.append(" [--" + ARG_MOVE_FILES + "] ");
|
||||
ret.append(" [--" + ARG_SNAPSHOT_CONSISTENCY + "] ");
|
||||
ret.append(" [--" + ARG_ALLOW_GLOBAL_SEQNO + "] ");
|
||||
ret.append(" [--" + ARG_ALLOW_BLOCKING_FLUSH + "] ");
|
||||
ret.append(" [--" + ARG_INGEST_BEHIND + "] ");
|
||||
ret.append("\n");
|
||||
}
|
||||
|
||||
IngestExternalSstFilesCommand::IngestExternalSstFilesCommand(
|
||||
const std::vector<std::string>& params,
|
||||
const std::map<std::string, std::string>& options,
|
||||
const std::vector<std::string>& flags)
|
||||
: LDBCommand(
|
||||
options, flags, false /* is_read_only */,
|
||||
BuildCmdLineOptions({ARG_MOVE_FILES, ARG_SNAPSHOT_CONSISTENCY,
|
||||
ARG_ALLOW_GLOBAL_SEQNO, ARG_CREATE_IF_MISSING,
|
||||
ARG_ALLOW_BLOCKING_FLUSH, ARG_INGEST_BEHIND})),
|
||||
move_files_(false),
|
||||
snapshot_consistency_(true),
|
||||
allow_global_seqno_(true),
|
||||
allow_blocking_flush_(true),
|
||||
ingest_behind_(false) {
|
||||
create_if_missing_ =
|
||||
IsFlagPresent(flags, ARG_CREATE_IF_MISSING) ||
|
||||
ParseBooleanOption(options, ARG_CREATE_IF_MISSING, false);
|
||||
move_files_ = IsFlagPresent(flags, ARG_MOVE_FILES) ||
|
||||
ParseBooleanOption(options, ARG_MOVE_FILES, false);
|
||||
snapshot_consistency_ =
|
||||
IsFlagPresent(flags, ARG_SNAPSHOT_CONSISTENCY) ||
|
||||
ParseBooleanOption(options, ARG_SNAPSHOT_CONSISTENCY, true);
|
||||
allow_global_seqno_ =
|
||||
IsFlagPresent(flags, ARG_ALLOW_GLOBAL_SEQNO) ||
|
||||
ParseBooleanOption(options, ARG_ALLOW_GLOBAL_SEQNO, true);
|
||||
allow_blocking_flush_ =
|
||||
IsFlagPresent(flags, ARG_ALLOW_BLOCKING_FLUSH) ||
|
||||
ParseBooleanOption(options, ARG_ALLOW_BLOCKING_FLUSH, true);
|
||||
ingest_behind_ = IsFlagPresent(flags, ARG_INGEST_BEHIND) ||
|
||||
ParseBooleanOption(options, ARG_INGEST_BEHIND, false);
|
||||
|
||||
if (params.size() != 1) {
|
||||
exec_state_ =
|
||||
LDBCommandExecuteResult::Failed("input SST path must be specified");
|
||||
} else {
|
||||
input_sst_path_ = params.at(0);
|
||||
}
|
||||
}
|
||||
|
||||
void IngestExternalSstFilesCommand::DoCommand() {
|
||||
if (!db_) {
|
||||
assert(GetExecuteState().IsFailed());
|
||||
return;
|
||||
}
|
||||
if (GetExecuteState().IsFailed()) {
|
||||
return;
|
||||
}
|
||||
ColumnFamilyHandle* cfh = GetCfHandle();
|
||||
IngestExternalFileOptions ifo;
|
||||
ifo.move_files = move_files_;
|
||||
ifo.snapshot_consistency = snapshot_consistency_;
|
||||
ifo.allow_global_seqno = allow_global_seqno_;
|
||||
ifo.allow_blocking_flush = allow_blocking_flush_;
|
||||
ifo.ingest_behind = ingest_behind_;
|
||||
Status status = db_->IngestExternalFile(cfh, {input_sst_path_}, ifo);
|
||||
if (!status.ok()) {
|
||||
exec_state_ = LDBCommandExecuteResult::Failed(
|
||||
"failed to ingest external SST: " + status.ToString());
|
||||
} else {
|
||||
exec_state_ =
|
||||
LDBCommandExecuteResult::Succeed("external SST files ingested");
|
||||
}
|
||||
}
|
||||
|
||||
Options IngestExternalSstFilesCommand::PrepareOptionsForOpenDB() {
|
||||
Options opt = LDBCommand::PrepareOptionsForOpenDB();
|
||||
opt.create_if_missing = create_if_missing_;
|
||||
return opt;
|
||||
}
|
||||
|
||||
} // namespace rocksdb
|
||||
#endif // ROCKSDB_LITE
|
||||
@@ -522,4 +522,55 @@ class RestoreCommand : public BackupableCommand {
|
||||
static void Help(std::string& ret);
|
||||
};
|
||||
|
||||
class WriteExternalSstFilesCommand : public LDBCommand {
|
||||
public:
|
||||
static std::string Name() { return "write_extern_sst"; }
|
||||
WriteExternalSstFilesCommand(
|
||||
const std::vector<std::string>& params,
|
||||
const std::map<std::string, std::string>& options,
|
||||
const std::vector<std::string>& flags);
|
||||
|
||||
virtual void DoCommand() override;
|
||||
|
||||
virtual bool NoDBOpen() override { return false; }
|
||||
|
||||
virtual Options PrepareOptionsForOpenDB() override;
|
||||
|
||||
static void Help(std::string& ret);
|
||||
|
||||
private:
|
||||
std::string output_sst_path_;
|
||||
};
|
||||
|
||||
class IngestExternalSstFilesCommand : public LDBCommand {
|
||||
public:
|
||||
static std::string Name() { return "ingest_extern_sst"; }
|
||||
IngestExternalSstFilesCommand(
|
||||
const std::vector<std::string>& params,
|
||||
const std::map<std::string, std::string>& options,
|
||||
const std::vector<std::string>& flags);
|
||||
|
||||
virtual void DoCommand() override;
|
||||
|
||||
virtual bool NoDBOpen() override { return false; }
|
||||
|
||||
virtual Options PrepareOptionsForOpenDB() override;
|
||||
|
||||
static void Help(std::string& ret);
|
||||
|
||||
private:
|
||||
std::string input_sst_path_;
|
||||
bool move_files_;
|
||||
bool snapshot_consistency_;
|
||||
bool allow_global_seqno_;
|
||||
bool allow_blocking_flush_;
|
||||
bool ingest_behind_;
|
||||
|
||||
static const std::string ARG_MOVE_FILES;
|
||||
static const std::string ARG_SNAPSHOT_CONSISTENCY;
|
||||
static const std::string ARG_ALLOW_GLOBAL_SEQNO;
|
||||
static const std::string ARG_ALLOW_BLOCKING_FLUSH;
|
||||
static const std::string ARG_INGEST_BEHIND;
|
||||
};
|
||||
|
||||
} // namespace rocksdb
|
||||
+42
-1
@@ -76,7 +76,7 @@ class LDBTestCase(unittest.TestCase):
|
||||
|
||||
my_check_output("./ldb %s >/dev/null 2>&1 |grep -v \"Created bg \
|
||||
thread\"" % params, shell=True)
|
||||
except Exception, e:
|
||||
except Exception:
|
||||
return
|
||||
self.fail(
|
||||
"Exception should have been raised for command with params: %s" %
|
||||
@@ -146,6 +146,14 @@ class LDBTestCase(unittest.TestCase):
|
||||
def loadDb(self, params, dumpFile):
|
||||
return 0 == run_err_null("cat %s | ./ldb load %s" % (dumpFile, params))
|
||||
|
||||
def writeExternSst(self, params, inputDumpFile, outputSst):
|
||||
return 0 == run_err_null("cat %s | ./ldb write_extern_sst %s %s"
|
||||
% (inputDumpFile, outputSst, params))
|
||||
|
||||
def ingestExternSst(self, params, inputSst):
|
||||
return 0 == run_err_null("./ldb ingest_extern_sst %s %s"
|
||||
% (inputSst, params))
|
||||
|
||||
def testStringBatchPut(self):
|
||||
print "Running testStringBatchPut..."
|
||||
self.assertRunOK("batchput x1 y1 --create_if_missing", "OK")
|
||||
@@ -547,5 +555,38 @@ class LDBTestCase(unittest.TestCase):
|
||||
# non-existing column family.
|
||||
self.assertRunFAIL("get cf3_1 --column_family=four")
|
||||
|
||||
def testIngestExternalSst(self):
|
||||
print "Running testIngestExternalSst..."
|
||||
|
||||
# Dump, load, write external sst and ingest it in another db
|
||||
dbPath = os.path.join(self.TMP_DIR, "db1")
|
||||
self.assertRunOK(
|
||||
"batchput --db=%s --create_if_missing x1 y1 x2 y2 x3 y3 x4 y4"
|
||||
% dbPath,
|
||||
"OK")
|
||||
self.assertRunOK("scan --db=%s" % dbPath,
|
||||
"x1 : y1\nx2 : y2\nx3 : y3\nx4 : y4")
|
||||
dumpFilePath = os.path.join(self.TMP_DIR, "dump1")
|
||||
with open(dumpFilePath, 'w') as f:
|
||||
f.write("x1 ==> y10\nx2 ==> y20\nx3 ==> y30\nx4 ==> y40")
|
||||
externSstPath = os.path.join(self.TMP_DIR, "extern_data1.sst")
|
||||
self.assertTrue(self.writeExternSst("--create_if_missing --db=%s"
|
||||
% dbPath,
|
||||
dumpFilePath,
|
||||
externSstPath))
|
||||
# cannot ingest if allow_global_seqno is false
|
||||
self.assertFalse(
|
||||
self.ingestExternSst(
|
||||
"--create_if_missing --allow_global_seqno=false --db=%s"
|
||||
% dbPath,
|
||||
externSstPath))
|
||||
self.assertTrue(
|
||||
self.ingestExternSst(
|
||||
"--create_if_missing --allow_global_seqno --db=%s"
|
||||
% dbPath,
|
||||
externSstPath))
|
||||
self.assertRunOKFull("scan --db=%s" % dbPath,
|
||||
"x1 : y10\nx2 : y20\nx3 : y30\nx4 : y40")
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -88,6 +88,8 @@ void LDBCommandRunner::PrintHelp(const LDBOptions& ldb_options,
|
||||
BackupCommand::Help(ret);
|
||||
RestoreCommand::Help(ret);
|
||||
CheckPointCommand::Help(ret);
|
||||
WriteExternalSstFilesCommand::Help(ret);
|
||||
IngestExternalSstFilesCommand::Help(ret);
|
||||
|
||||
fprintf(stderr, "%s\n", ret.c_str());
|
||||
}
|
||||
|
||||
+10
-8
@@ -9,25 +9,27 @@
|
||||
|
||||
#include "rocksdb/status.h"
|
||||
#include <stdio.h>
|
||||
#ifdef OS_WIN
|
||||
#include <string.h>
|
||||
#endif
|
||||
#include <cstring>
|
||||
#include "port/port.h"
|
||||
|
||||
namespace rocksdb {
|
||||
|
||||
const char* Status::CopyState(const char* state) {
|
||||
const size_t cch =
|
||||
std::strlen(state) + 1; // +1 for the null terminator
|
||||
char* const result =
|
||||
new char[cch];
|
||||
result[cch - 1] = '\0';
|
||||
#ifdef OS_WIN
|
||||
const size_t cch = std::strlen(state) + 1; // +1 for the null terminator
|
||||
char* result = new char[cch];
|
||||
errno_t ret;
|
||||
ret = strncpy_s(result, cch, state, cch - 1);
|
||||
result[cch - 1] = '\0';
|
||||
assert(ret == 0);
|
||||
#else
|
||||
std::strncpy(result, state, cch - 1);
|
||||
#endif
|
||||
return result;
|
||||
#else
|
||||
const size_t cch = std::strlen(state) + 1; // +1 for the null terminator
|
||||
return std::strncpy(new char[cch], state, cch);
|
||||
#endif
|
||||
}
|
||||
|
||||
Status::Status(Code _code, SubCode _subcode, const Slice& msg, const Slice& msg2)
|
||||
|
||||
Reference in new issue
Block a user