Giter Site home page Giter Site logo

foedus_code's Introduction

FOEDUS: Fast Optimistic Engine for Data Unification Services

Overview

FOEDUS is a new transactional key-value store developed at Hewlett-Packard Labs that is optimized for a large number of CPU cores and NVRAM storage (or fast SSD). It is a handy C++ library you can either include in your source code (by invoking CMake script) or dynamically link to. In a nutshell, it is something like BerkeleyDB, but it is much more efficient on new hardware.

For more details, take a look at the overview paper.

Alpha-Version WARNING

The repository is currently in ALPHA state. Nothing is guaranteed. Please expect that many parts of the code are unstable and might lack critical features. We are working hard to move on to next steps hinted below, but without any promises. If you want to expedite the development, PLEASE JOIN US. That's the spirit of open-source.

  • Alpha Version (aka first open sourcing): This happened at the beginning of June 2015, when SIGMOD conference is held. By this time, we have added most of critical features, But, still some are missing, and no guarantee for stable behavior, data migration to next version, etc. Important APIs and even the library name might change in next versions. This version is for people who want to take a look at FOEDUS, and for early adopters who are okay to adjust their programs when the APIs significantly change.
  • Beta Version: This is supposed to be released sometime in 2016, hopefully early 2016. We should fix most of critical issues/features by this time so that users can start developing their programs on top of FOEDUS. We will start release versioning from this point, probably from ver 0.1.
  • Stable Version (aka ver 1.0): Some time between 2018 to 2020. We really need more people to make this happen on time, especially for stabilizing/documenting FOEDUS and for establishing/helping the community.

Again, we are in ALPHA now. We list missing features, known bugs, etc in issues. Check it out if you encounter some issue.

How to Contribute

You can help us in different ways:

  1. Reporting issues [^1].
  2. Contributing code and sending a Pull Request.

In order to contribute the code base of this project, you must agree to the Developer Certificate of Origin 1.1 for this project under GPLv2+ with classpath exception as indicated in the accompanying license.

By making a contribution to this project, I certify that:

(a) The contribution was created in whole or in part by me and I have the
    right to submit it under the open source license indicated in the file; or
(b) The contribution is based upon previous work that, to the best of my
    knowledge, is covered under an appropriate open source license and I
    have the right under that license to submit that work with modifications,
    whether created in whole or in part by me, under the same open source
    license (unless I am permitted to submit under a different license),
    as indicated in the file; or
(c) The contribution was provided directly to me by some other person who
    certified (a), (b) or (c) and I have not modified it.
(d) I understand and agree that this project and the contribution are public and
    that a record of the contribution (including all personal information I submit
    with it, including my sign-off) is maintained indefinitely and may be
    redistributed consistent with this project or the open source license(s) involved.

To indicate acceptance of the DCO you need to add a Signed-off-by line to every commit. E.g.:

Signed-off-by: John Doe <[email protected]>

To automatically add that line use the -s switch when running git commit:

$ git commit -s

[^1] Before reporting a bug, please make sure you have passed "ctest -R test_check_env".

Folder Structure (For Everyone)

This root project contains a few sub-projects. Some of them are NOT supposed to be directly linked from client programs (your programs).

  • foedus-core : Key-value store library.
  • foedus-util : A series of utility programs to help use libfoedus.
  • tests-[core/util] : Unit testcase projects.
  • experiments-[core/util] : Performance experiments projects.
  • third_party : Third party source code used in our programs.

You are supposed to link only to foedus-core. Other projects are for internal use or to provide executables, rather than libraries. You can still contain all projects (or this folder's CMakeLists.txt) in your source code, but note that some restrictions on compiler options apply if you do so.

libfoedus-core (For FOEDUS Users)

For more details of how your client program links to and uses our library, start from foedus-core and its API document. Licensing, short get-started examples, etc for users are there. The sections below are for people developing FOEDUS itself.

Current Build Status on Jenkins (For FOEDUS Developers)

Build Type master Branch develop Branch
x86 FC21 release Build Status: master-release Build Status: develop-release
x86 FC21 relwithdebinfo Build Status: master-relwithdebinfo Build Status: develop-relwithdebinfo
x86 FC21 debug Build Status: master-debug Build Status: develop-debug
x86 FC21 release-valgrind Build Status: master-release-valgrind Build Status: develop-release-valgrind
x86 FC21 doxygen Build Status: master-doxygen Build Status: develop-doxygen
x86 UB15 release Build Status: master-release Build Status: develop-release
x86 UB15 relwithdebinfo Build Status: master-relwithdebinfo Build Status: develop-relwithdebinfo
x86 UB15 debug Build Status: master-debug Build Status: develop-debug
x86 UB15 release-valgrind Build Status: master-release-valgrind Build Status: develop-release-valgrind
aarch64 release Build Status: master-release Build Status: develop-release
aarch64 relwithdebinfo Build Status: master-relwithdebinfo Build Status: develop-relwithdebinfo
aarch64 debug Build Status: master-debug Build Status: develop-debug
aarch64 release-valgrind Build Status: master-release-valgrind Build Status: develop-release-valgrind

To get an email notification for build failure (aka the hall of embarrassment), join our build-notification mailing list. You can simply subscribe the Jenkins's RSS, too.

Building Development Environment (For FOEDUS Developers)

We recommend newer Fedora, Ubuntu/Debian, etc. There are a few things you have to configure with sudo permission. See the Environment Setup section in foedus-core.

In Fedora/RedHat/CentOS etc, run the following:

sudo yum install gcc gcc-c++ libstdc* cmake glibc glibc-* valgrind valgrind-devel
sudo yum install libunwind libunwind-devel libdwarf libdwarf-devel
sudo yum install numactl numactl-devel google-perftools google-perftools-devel
sudo yum install papi papi-devel papi-static
sudo yum install python python-*
sudo yum install doxygen texlive-eps* graphviz mscgen texlive-epspdf sloccount kdevelop cloc

For valgrind, check its version after installation. If it is not 3.9 or later, we recommend installing a newer one. See the section below.

If you want to generate doxygen-pdf, also run the following:

sudo yum install texlive texlive-* okular

If you are the person to compile our rpm packages ("make package"), also run the following:

sudo yum install rpm-build

For Ubuntu/Debian, install equivalent modules. TBD: Ubuntu/Debian user, please provide an equivalent command. Especially, I know little about .deb packaging.

Compilation (For FOEDUS Developers)

To compile this project, simply build it as a CMake project. For example:

# Suppose you are at foedus_code.
# We prohibit in-source build, so you have to create a build folder and compile there.
mkdir build
cd build
# You can also use Release/RelWithDebInfo just like usual CMake projects.
cmake ../  -DCMAKE_BUILD_TYPE=Debug
make

Or, import it to C++ IDE, such as kdevelop. Any IDEs that support CMake build should work.

If you use kdevelop, don't forget to increase the degree of parallel compilation after importing the CMake project. The default is 2. You must get a new machine if this is a good number. Right click project, Click "Open Configuration", Click "Make" icon, "Number of simultaneous jobs".

Running Tests (For FOEDUS Developers)

First, make sure you have set up the environment, especially hugepages/shared memory. See the Environment Setup section in foedus-core. If a large number of tests fail, it's most likely cauesed by memory/permission issues.

Go to build folder, and:

ctest

or

ctest -j4
# Pick a test parallelization level according to your machine power. Remember some tests
# run many threads in them. 4 should be a good number.

If you want to particularly check environment setup, run the following:

ctest -R test_check_env

In order to skip valgrind versions of the tests (because it takes long time!),

ctest -E valgrind

On the other hand, if you want to run only valgrind versions,

ctest -R valgrind

We strongly recommend to use valgrind 3.9 or later to run all tests on valgrind due to a performance issue fixed in valgrind 3.9. See the section below.

If valgrind reports a false positive or third party's bug, add them to foedus-core/tools/valgrind.supp.

valgrind --leak-check=full --suppressions=<path_to_valgrind.supp> --gen-suppressions=all ./<your_program>

For more details, check out CTEST/CMAKE documentation.

Notes for valgrind and installing the latest version of valgrind (For FOEDUS Developers)

Valgrind is a powerful tool to debug programs, and we keep our program free from memory-leak and bogus memory accesses by regularly running valgrind tests (once per hour on Jenkins).

You are also encouraged to run valgrind versions of tests on your machine. However, there is one issue in valgrind ~3.8 that makes it quite troublesome.

Valgrind executes programs in a single-threaded fashion. Thus, if your program has an infinite loop (eg spinlock) without yielding to other threads, valgrind never finishes the execution. This is why we must use our SPINLOCK_WHILE macro in such places, which occasionally calls foedus::assorted::spinlock_yield() (not too much to avoid unnecessary overhead, of course).

Even with these yielding, valgrind ~3.8 sometimes causes an infinite or semi-infinite loop in condition variables, or std::condition_variables::wait()/pthread_cond_wait(). This problem is fixed in valgrind 3.9, and you can see the difference by running tests-core/src/foedus/assorted/test_raw_atomics on valgrind 3.8.1 (almost always infinite loop) and valgrind 3.9.0 (always within a few sec).

If you are using an older linux distro (eg Fedora 19 whose latest valgrind in yum repo is 3.8.1), we strongly recommend to install latest valgrind from source. Follow these steps:

  • Download the source from here.
  • Usual triplet: "./configure --prefix=$HOME/local; make; make install" or "./configure --prefix=/usr/local; make; sudo make install" if you are a sudoer and others on the machine would like it.
  • Cleanly rebuild foedus so that our cmake script finds the newer valgrind installation. (the cmake script searches in this order: ~/local, /usr/local, /usr)
  • (Optional) Edit your environment variable to see $HOME/local/bin before /usr/bin. This is useful when you type "valgrind" in terminal, which might not happen often.

Notes for PAPI on Ivy Bridge (For FOEDUS Developers)

PAPI 5.1 (which is the version on FC19) does not support Ivy Bridge Family 6. You should source-build the latest PAPI. Make sure you have gfortran

sudo yum install gcc-gfortran
tar -xf papi-5.3.2.tar.gz
cd papi-5.3.2/src
./configure --prefix=$HOME/local; make; make install

Then cleanly build FOEDUS so that it picks up the latest version.

Git Push/Branch Convention (For FOEDUS Developers)

We follow the git-flow convention. Never ever directly push to master branch (most likely you do not have the permission anyways).

Each person should usually work on her/his own branch made from develop branch. On your own branch, do what you want. We recommend to run at least non-valgrind testcases either on relwithdebinfo or debug before commit, but it is really up to you.

Before pull request to develop branch, you must pass all testcases on relwithdebinfo, debug, and release, preferrably including valgrind versions (not mandatory if you are in hurry). But, if Jenkins reports an error on develop branch, others will yell at you.

We will process your pull requests on develop, then occasionally merge develop to master. The pull requests might have a few iterations of review/resubmit process. See Code Review Policy below.

Coding Convention (For FOEDUS Developers)

We conform to Google C++ Style Guide except the arguable rule on streams. See the discussions if you are interested (Dec 2014: I have realized that the latest cpplint actually disables this warning as well as allowing most C++11 features. The guide seems thoroughly revised around Sep14. Great!). Other minor differences from the convention:

  • Max 100 characters per line rather than 80 (you are welcomed to keep it within 80, though).
  • C++ file names are ".cpp" rather than ".cc", header files are ".hpp" rather than ".h".

We enforce the coding convention by cpplint.py. All projects run cpplint for every build and report violations as warnings.

In addition to the Google c++ convention, we have the following house-rules:

  • cpp/hpp are placed in folders that fully correspond to namespace hierarchy like a Java project.
  • Header include order: Same as what Google style defines, but there is something unclear in the guide; "alphabetical in each category". What cpplint.py enforces is actually "ASCII order". So, "aaa.hpp" comes before "aaaa.hpp". "aaa_abc.hpp" comes before "aaazabc.hpp". Also, we place headers under folders in a hierarchically consistent order. "aaa/a.hpp", "aaa/z.hpp", "aaa/b/foo.hpp", "aaa/b/hoge.hpp", "aaa/c/ccc.hpp" in this order. This is a bit different from original cpplint.py implementation (we modified the script for this).
  • We also force a blank line between categories of headers. So, it should be Include own-header (hpp with the same path as the cpp file), <blank line>, Include C system headers (eg <stdint.h>, <numa.h>), <blank line>, Include C++ system headers (eg <string>, <iostream>) <blank line>, Include other our headers (eg "foedus/memory/engine_memory.hpp"). Notice that we always use angle brackets for system headers and double quotes for our headers.
  • No importing or aliasing ("using") of namespace at all, even in c++ files. You might initially feel this results in lengthy code, but you will soon find it easier to understand others' code and not requiring additional typing as much as you thought.
  • If you are calling classes/methods in global namespace (which shouldn't exist in our code, so third party's), put "::" as prefix to clarify it's in global namespace (eg "::posix_memalign(foo)").
  • Class/function/variable comments must be in Doxygen format. Be beefy.
  • Each folder (== package, == namespace) has a header file named "namespace-info.hpp" which gives Doxygen documentation of the folder, just like "package-info.java" in Java projects.
  • Each folder has a header file named "fwd.hpp" which gives forward declarations of classes in the package. As the Google style guide recommends, prefer forward declarations as much as possible.
  • In addition to general C++ coding conventions, there are several foedus-specific programming idioms. Read our Doxygen document first to get familiar with them (see "FOEDUS Programming Idioms").

Code Review Policy (For FOEDUS Developers)

Each pull request must meet the following requirements before being merged.

  • Compile without errors and warnings (either compiler warnings or cpplint warnings).
  • Conform to our coding standards and house rules (see above).
  • Pass all testcases on debug and release (or relwithdebinfo), including valgrind versions in at least one of them.
  • A reasonable amount/quality of new unit testcases, depending on how much you changed/added.
  • A reasonable amount/quality of code comments, especially doxygen comments in hpp.
  • A summary of the changes in pull request comments.

Depending on the content of the change and your commit history, expect a few iterations. When the change is only in documentations (e.g., README, namespace-info.hpp), we will most likely process it immediately and you do not have to worry about testing the changes.

kdevelop-specific Recommendations (For FOEDUS Developers)

Only if you use kdevelop, and not if you have your own configuration (which is totally okay).

  • Settings, Configure Editor, Appearance, Borders, Enable "Show folding markers", "Show line numbers"
  • Settings, Configure Editor, Editing, "Show static word wrap marker" with 100 characters.
  • Settings, Configure Editor, Editing, Indentation, "Spaces" 2 characters.
  • Settings, Configure Editor, Open/Save, General, Append newline at end of file.

We also have a template file for creating new classes in kdevelop.

Right click a folder, "Create From Template", "Load Template From File", choose kdevtemplate.desktop under foedus-core/tools.

When you use it, specify your class name such as foedus::storage::masstree::MyNewClass. Unfortunately, kdevelop template has limited flexibility in a few things:

  • Manually edit the generated file name so that words are separated by "_" (eg my_new_class.cpp)
  • Manually edit the generated cpp/hpp path so that hpp is under include, cpp is under src.
  • Don't let the wizard add new cpp to a target. Most likely it puts it in a stupid place. Add it to a right place yourself.

At least kdevelop up to 4.x didn't like the almost-standard style where .cpp and .h are placed in separate folders (src and include).

eclipse-specific Recommendations (For FOEDUS Developers)

While eclipse-CDT doesn't support CMake projects as nicely as kdevelop, we know it's a great IDE in general. If you prefer eclipse, follow the following tips recommended here (again, we strongly prefer out-of-source builds, but you need a bit of trick to do it in eclipse):

# http://www.nightshadesoftware.org/projects/nightshade/wiki/CMake_and_Eclipse
# Suppose you are at foedus_code.
cd ..
mkdir foedus_code_eclipse_build   # build directory root at the same level as the source root
cd foedus_code_eclipse_build
cmake ../foedus_code -G"Eclipse CDT4 - Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug

Now start up Eclipse and do the following to import the project.

  • File->Import...
  • General->Existing Projects into Workspace
  • For the root directory enter the build root directory, not the source root
  • Leave other options unchecked and click Finish

If you want to edit CMakeLists.txt or add new ones, we recommend repeating the same process. Eclipse sometimes works without it, sometimes not. We let yourself figure out other eclipse configurations for ctest/cpplint/git/etc and find cool plugins for them. Good luck, and let us know if there were some gotchas. You might find this helpful.

foedus_code's People

Contributors

hkimura avatar kirbychris avatar ssinghal53 avatar wangtzh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

foedus_code's Issues

Too-short-record error for repeated record expansions in a single transaction

Reported by Gustavo:

Hi Hideaki,

we are facing an issue with the upsert_record that we would like to double check with you.

assume the scenario that we inserted 5 records with a 2 bytes payload each in a masstree.

consider 3 tests:
test 1: update all 5 records to a 10 bytes payload in the same transaction
test 2: update all 5 records to a 700 bytes payload. Each update call in its own transaction (each update is committed separately)
test 3: update all 5 records to a 700 bytes payload in the same transaction (all four updates are committed at the same time)

test 1 and 2 pass, but test 3 fails. we attached a unit test that we created for FOEDUS that shows the issue.

test_masstree_extra.cpp.txt

Haven't taken a look at the code yet, but I (wildly) guess the check on physical record length is seeing the current physical record, thus it returns too-short-payload error on second upsert.

If that's the case, one solution is to apply physical record-expansion during transaction rather than during precommit.

default option's value gets bus error

I wrote some simple client code with develop branch's commit 3c1dd8f

#include <assert.h>

#include <iostream>

#include <foedus/engine.hpp>
#include <foedus/engine_options.hpp>
#include <foedus/proc/proc_manager.hpp>  // ProcManager
#include <foedus/storage/storage_manager.hpp>
#include <foedus/storage/metadata.hpp>
#include <foedus/storage/masstree/masstree_metadata.hpp>
#include <foedus/storage/masstree/masstree_storage.hpp>
#include <foedus/fs/path.hpp>
#include <foedus/thread/thread.hpp>
#include <foedus/thread/thread_pool.hpp>
#include <foedus/xct/xct_manager.hpp>

int main() {
  foedus::EngineOptions options;
  options.memory_.rigorous_memory_boundary_check_ = true;
  options.log_.folder_path_pattern_.assign("/tmp/pfoedus_log");
  options.snapshot_.folder_path_pattern_.assign("/tmp/pfoedus_snapshot");
  options.savepoint_.savepoint_path_.assign("/tmp/pfoedus_save");
  options.debugging_.debug_log_dir_.assign("/tmp/debug_log");  // caution SLOW!

  foedus::Engine engine(options);
  engine.get_proc_manager()->pre_register(
    "simple_task",
    [](const foedus::proc::ProcArguments& args) -> foedus::ErrorStack {
      return foedus::kRetOk;
    });
  foedus::ErrorStack ret = engine.initialize();
  if (ret.is_error()) {
    std::cout << "failed" << std::endl;
  }
  {
    foedus::UninitializeGuard guard(&engine);
    foedus::storage::masstree::MasstreeMetadata mass_meta("simple");
    foedus::storage::masstree::MasstreeStorage masstree;
    foedus::Epoch epoch;
    engine.get_storage_manager()->create_masstree(&mass_meta, &masstree, &epoch);
    assert(masstree.exists());
    engine.get_thread_pool()->impersonate_synchronous("simple_task");
    engine.uninitialize();
  }
  foedus::fs::remove_all(foedus::fs::Path(options.savepoint_.savepoint_path_.str()).parent_path());
}

that gets bus error.

I0617 19:50:55.512516  8646 debugging_supports.cpp:98] initialize_glog(): Initialized GLOG
I0617 19:50:55.518527  8648 proc_manager_pimpl.cpp:50] Initializing ProcManager(CHILD-0)..
I0617 19:50:55.522929  8646 engine_memory.cpp:44] Initializing EngineMemory..
I0617 19:50:55.523660  8648 engine_memory.cpp:44] Initializing EngineMemory..
I0617 19:50:55.523732  8648 numa_node_memory.cpp:58] Initializing NumaNodeMemory for node 0. BEFORE: numa_node_size=33688031232
[2]    8646 bus error (core dumped)  ./a.out

with gdb, it happens at foedus::memory::AlignedMemory::alloc

#0  memset () at ../sysdeps/x86_64/memset.S:93
#1  0x00007ffff7801712 in foedus::memory::AlignedMemory::alloc (this=0x7ffff0011370, 
    size=1073741824, alignment=2097152, 
    alloc_type=foedus::memory::AlignedMemory::kNumaAllocOnnode, numa_node=0)
    at /home/kumagi/develop/foedus_code/foedus-core/src/foedus/memory/aligned_memory.cpp:169

alignment value seems to be too huge(2MB alignment).
I add some configuration of memory as test code does

  options.memory_.page_pool_size_mb_per_node_ = 2;
  options.memory_.private_page_pool_initial_grab_ = 32;

then, the error disappeared.

  • Why default alignment is so huge?
  • How about reduce default value?
  • Or output unambiguous message(instead of bus error)

Thank you.

RLL under high contention TPCC

Infinite lock spinning when running with RLL and the number of whs < number of threads. Hyeontaek Lim (https://www.cs.cmu.edu/~hl/) found this problem. To reproduce:

./tpcc -fork_workers=false -take_snapshot=false -nvm_folder=/dev/shm -volatile_pool_size=10 -snapshot_pool_size=1 -reducer_buffer_size=1 -loggers_per_node=1 -neworder_remote_percent=1 -payment_remote_percent=15 -thread_per_node=10 -numa_nodes=2 -log_buffer_mb=1024 -null_log_device=true -high_priority=false -warehouses=4 -duration_micro=10000000 -hcc_policy=0

I got infinite spinning under relwithdebinfo, and an assertion failure under debug mode, see stack traces in the end.

Looks like the problem is in last_locked_entry_: I got different results returned by calculate_last_locked_entry() and calculate_last_locked_entry_from(pos-1), the former is larger.
retrospective_lock_list.hpp:591 updates last_locked_entry_ by scanning backward only from [pos], but beyond [pos] there might be locked entries. One possibility I guess is in a previous round the transaction followed RLL and made sure all are locked, then in another round it tries to upgrade, at retrospective_lock_list.hpp:591 last_locked_entry_ will be smaller than it should be.

I did the following, it seems to be working:

  1. Replacing calculate_last_locked_entry_from() with calculate_last_locked_entry() at retrospective_lock_list.hpp:591, and reset lock_entry->mcs_block_ to 0 (so it won't hit assertion failure later in non-canonical mode acquire);
  2. Return immediately if the RLL will actually be empty (ie when last_active_entry_ == kLockListPositionInvalid, before the assertion at line 300) in construct() (retrospective_lock_list.cpp:296, after the write-set loop); for read-only transactions, in this example I hit abort in stock-level.

Always using calculate_last_locked_entry() might be inefficient, maybe we should do:
last_locked_entry_ = std::max(last_locked_entry_, calculate_last_locked_entry(pos-1))?

@hkimura it's been a while since I touched the code last time, could you see if these changes make sense? thanks!

============== The stack traces===========
==== Infinite spinning under relwithdebinfo ====
#0 atomic_load_acquire (target=0x2aafd30d0009 "\202") at /home/wantianz/foedus_code/foedus-core/include/foedus/assorted/atomic_fences.hpp:115
#1 read_state (this=) at /home/wantianz/foedus_code/foedus-core/include/foedus/xct/xct_id.hpp:439
#2 is_blocked (this=) at /home/wantianz/foedus_code/foedus-core/include/foedus/xct/xct_id.hpp:448
#3 is_granted (this=) at /home/wantianz/foedus_code/foedus-core/include/foedus/xct/xct_id.hpp:451
#4 operator() (__closure=) at /home/wantianz/foedus_code/foedus-core/src/foedus/xct/xct_mcs_impl.cpp:513
#5 spin_until<foedus::xct::McsImpl<ADAPTOR, foedus::xct::McsRwSimpleBlock>::acquire_unconditional_rw_writer(foedus::xct::McsRwLock*) [with ADAPTOR = foedus::thread::ThreadPimplMcsAdaptorfoedus::xct::McsRwSimpleBlock; foedus::xct::McsBlockIndex = unsigned int]::__lambda7> (spin_until_cond=...) at /home/wantianz/foedus_code/foedus-core/include/foedus/assorted/spin_until_impl.hpp:65
#6 spin_until<foedus::xct::McsImpl<ADAPTOR, foedus::xct::McsRwSimpleBlock>::acquire_unconditional_rw_writer(foedus::xct::McsRwLock*) [with ADAPTOR = foedus::thread::ThreadPimplMcsAdaptorfoedus::xct::McsRwSimpleBlock; foedus::xct::McsBlockIndex = unsigned int]::__lambda7> (spin_until_cond=...) at /home/wantianz/foedus_code/foedus-core/src/foedus/xct/xct_mcs_impl.cpp:42
#7 foedus::xct::McsImplfoedus::thread::ThreadPimplMcsAdaptor<foedus::xct::McsRwSimpleBlock, foedus::xct::McsRwSimpleBlock>::acquire_unconditional_rw_writer (this=,

mcs_rw_lock=<optimized out>) at /home/wantianz/foedus_code/foedus-core/src/foedus/xct/xct_mcs_impl.cpp:513

#8 0x00007ffff7b2494d in try_or_acquire_single_lockfoedus::xct::McsImpl<foedus::thread::ThreadPimplMcsAdaptor<foedus::xct::McsRwSimpleBlock, foedus::xct::McsRwSimpleBlock> > (mcs_rw_impl=0x7fffaa7fae30,

pos=1, this=0x7fffe802d340) at /home/wantianz/foedus_code/foedus-core/include/foedus/xct/retrospective_lock_list.hpp:603

#9 try_or_acquire_multiple_locksfoedus::xct::McsImpl<foedus::thread::ThreadPimplMcsAdaptor<foedus::xct::McsRwSimpleBlock, foedus::xct::McsRwSimpleBlock> > (mcs_rw_impl=0x7fffaa7fae30, upto_pos=122,

this=0x7fffe802d340) at /home/wantianz/foedus_code/foedus-core/include/foedus/xct/retrospective_lock_list.hpp:643

#10 foedus::thread::ThreadPimpl::cll_try_or_acquire_multiple_locks (this=0x7fffe802c3c0, upto_pos=122) at /home/wantianz/foedus_code/foedus-core/src/foedus/thread/thread_pimpl.cpp:913
#11 0x00007ffff7b24979 in foedus::thread::Thread::cll_try_or_acquire_multiple_locks (this=, upto_pos=)

at /home/wantianz/foedus_code/foedus-core/src/foedus/thread/thread_pimpl.cpp:854

#12 0x00007ffff7b2c649 in foedus::xct::Xct::on_record_read_take_locks_if_needed (this=0x7fffe802d298, intended_for_write=, page_address=page_address@entry=0x2aafe86cf000,

lock_id=lock_id@entry=85378080, tid_address=tid_address@entry=0x2aafe86cf420) at /home/wantianz/foedus_code/foedus-core/src/foedus/xct/xct.cpp:380

#13 0x00007ffff7b2c7cf in foedus::xct::Xct::on_record_read (this=0x7fffe802d298, intended_for_write=, tid_address=0x2aafe86cf420, observed_xid=observed_xid@entry=0x7fffaa7fb100,

read_set_address=read_set_address@entry=0x7fffaa7fb108, no_readset_if_moved=no_readset_if_moved@entry=true, no_readset_if_next_layer=no_readset_if_next_layer@entry=true)
at /home/wantianz/foedus_code/foedus-core/src/foedus/xct/xct.cpp:307

#14 0x00007ffff7adba9b in foedus::storage::masstree::RecordLocation::populate_logical (this=this@entry=0x7fffaa7fb0f0, cur_xct=, page=page@entry=0x2aafe86cf000, index=,

intended_for_write=<optimized out>) at /home/wantianz/foedus_code/foedus-core/src/foedus/storage/masstree/masstree_record_location.cpp:38

#15 0x00007ffff7acbe69 in foedus::storage::masstree::MasstreeCursor::fetch_cur_record_logical (this=this@entry=0x7fffaa7fb0a0, page=page@entry=0x2aafe86cf000, record=)

at /home/wantianz/foedus_code/foedus-core/src/foedus/storage/masstree/masstree_cursor.cpp:547

#16 0x00007ffff7accaf4 in foedus::storage::masstree::MasstreeCursor::locate_border (this=this@entry=0x7fffaa7fb0a0, slice=slice@entry=25769803776)

at /home/wantianz/foedus_code/foedus-core/src/foedus/storage/masstree/masstree_cursor.cpp:1118

#17 0x00007ffff7ad1828 in locate_layer (layer=0 '\000', this=0x7fffaa7fb0a0) at /home/wantianz/foedus_code/foedus-core/src/foedus/storage/masstree/masstree_cursor.cpp:1040
#18 foedus::storage::masstree::MasstreeCursor::open (this=this@entry=0x7fffaa7fb0a0, begin_key=begin_key@entry=0x7fffaa7fb078 "", begin_key_length=begin_key_length@entry=8,

end_key=end_key@entry=0x7fffaa7fb080 "", end_key_length=end_key_length@entry=8, forward_cursor=forward_cursor@entry=false, for_writes=for_writes@entry=true, begin_inclusive=begin_inclusive@entry=false, 
end_inclusive=end_inclusive@entry=true) at /home/wantianz/foedus_code/foedus-core/src/foedus/storage/masstree/masstree_cursor.cpp:974

#19 0x0000000000412152 in open_normalized (end_inclusive=true, begin_inclusive=false, for_writes=true, forward_cursor=false, end_key=23622320128, begin_key=25769803776, this=0x7fffaa7fb0a0)

at /home/wantianz/foedus_code/foedus-core/include/foedus/storage/masstree/masstree_cursor.hpp:220

#20 foedus::tpcc::TpccClientTask::pop_neworder (this=this@entry=0x7fffaa7fb3b0, wid=wid@entry=1, did=did@entry=1 '\001', oid=oid@entry=0x7fffaa7fb1c4)

at /home/wantianz/foedus_code/experiments-core/src/foedus/tpcc/tpcc_delivery.cpp:104

#21 0x0000000000412474 in foedus::tpcc::TpccClientTask::do_delivery (this=this@entry=0x7fffaa7fb3b0, wid=wid@entry=1) at /home/wantianz/foedus_code/experiments-core/src/foedus/tpcc/tpcc_delivery.cpp:38

==== Assertion failure under debug mode ====


**** Assertion failed! "correct == last_locked_entry_" did not hold in assert_last_locked_entry(): /home/wantianz/foedus_code/foedus-core/include/foedus/xct/retrospective_lock_list.hpp:408


#4 0x00007ffff7a1ea1f in foedus::xct::CurrentLockList::assert_last_locked_entry (this=0x7ffff0008ed0) at /home/wantianz/foedus_code/foedus-core/include/foedus/xct/retrospective_lock_list.hpp:408
#5 0x00007ffff7a206ee in foedus::xct::CurrentLockList::try_or_acquire_single_lockfoedus::xct::McsImpl<foedus::thread::ThreadPimplMcsAdaptor<foedus::xct::McsRwSimpleBlock, foedus::xct::McsRwSimpleBlock> >

(this=0x7ffff0008ed0, pos=1, mcs_rw_impl=0x7fffe29ce400) at /home/wantianz/foedus_code/foedus-core/include/foedus/xct/retrospective_lock_list.hpp:591

#6 0x00007ffff7a2112b in foedus::xct::CurrentLockList::try_or_acquire_multiple_locksfoedus::xct::McsImpl<foedus::thread::ThreadPimplMcsAdaptor<foedus::xct::McsRwSimpleBlock, foedus::xct::McsRwSimpleBlock> > (this=0x7ffff0008ed0, upto_pos=1, mcs_rw_impl=0x7fffe29ce400) at /home/wantianz/foedus_code/foedus-core/include/foedus/xct/retrospective_lock_list.hpp:643
#7 0x00007ffff7a1dafe in foedus::thread::ThreadPimpl::cll_try_or_acquire_multiple_locks (this=0x7ffff0007f50, upto_pos=1) at /home/wantianz/foedus_code/foedus-core/src/foedus/thread/thread_pimpl.cpp:913
#8 0x00007ffff7a1d7f6 in foedus::thread::Thread::cll_try_or_acquire_multiple_locks (this=0x7ffff0005d00, upto_pos=1) at /home/wantianz/foedus_code/foedus-core/src/foedus/thread/thread_pimpl.cpp:854
#9 0x00007ffff7a31647 in foedus::xct::Xct::on_record_read_take_locks_if_needed (this=0x7ffff0008e28, intended_for_write=true, page_address=0x2aafe46ce000, lock_id=18266496, tid_address=0x2aafe46ce980)

at /home/wantianz/foedus_code/foedus-core/src/foedus/xct/xct.cpp:380

#10 0x00007ffff7a31000 in foedus::xct::Xct::on_record_read (this=0x7ffff0008e28, intended_for_write=true, tid_address=0x2aafe46ce980, observed_xid=0x7fffe29cee70, read_set_address=0x7fffe29cee78,

no_readset_if_moved=true, no_readset_if_next_layer=true) at /home/wantianz/foedus_code/foedus-core/src/foedus/xct/xct.cpp:307

#11 0x00007ffff792ecf4 in foedus::storage::masstree::RecordLocation::populate_logical (this=0x7fffe29cee60, cur_xct=0x7ffff0008e28, page=0x2aafe46ce000, index=51, intended_for_write=true)

at /home/wantianz/foedus_code/foedus-core/src/foedus/storage/masstree/masstree_record_location.cpp:38

#12 0x00007ffff78fa55c in foedus::storage::masstree::MasstreeCursor::fetch_cur_record_logical (this=0x7fffe29cee10, page=0x2aafe46ce000, record=51)

at /home/wantianz/foedus_code/foedus-core/src/foedus/storage/masstree/masstree_cursor.cpp:547

#13 0x00007ffff78fcf78 in foedus::storage::masstree::MasstreeCursor::locate_border (this=0x7fffe29cee10, slice=12884901888)

at /home/wantianz/foedus_code/foedus-core/src/foedus/storage/masstree/masstree_cursor.cpp:1118

#14 0x00007ffff7905b88 in foedus::storage::masstree::MasstreeCursor::locate_layer (this=0x7fffe29cee10, layer=0 '\000')

at /home/wantianz/foedus_code/foedus-core/src/foedus/storage/masstree/masstree_cursor.cpp:1040

#15 0x00007ffff78fb6aa in foedus::storage::masstree::MasstreeCursor::open (this=0x7fffe29cee10, begin_key=0x7fffe29cedd8 "", begin_key_length=8, end_key=0x7fffe29cedd0 "", end_key_length=8,

forward_cursor=false, for_writes=true, begin_inclusive=false, end_inclusive=true) at /home/wantianz/foedus_code/foedus-core/src/foedus/storage/masstree/masstree_cursor.cpp:974

#16 0x00000000004357a8 in foedus::storage::masstree::MasstreeCursor::open_normalized (this=0x7fffe29cee10, begin_key=12884901888, end_key=10737418240, forward_cursor=false, for_writes=true,

begin_inclusive=false, end_inclusive=true) at /home/wantianz/foedus_code/foedus-core/include/foedus/storage/masstree/masstree_cursor.hpp:220

#17 0x00000000004363b1 in foedus::tpcc::TpccClientTask::pop_neworder (this=0x7fffe29cf2b0, wid=0, did=5 '\005', oid=0x7fffe29cf01c)

at /home/wantianz/foedus_code/experiments-core/src/foedus/tpcc/tpcc_delivery.cpp:104

#18 0x0000000000435de0 in foedus::tpcc::TpccClientTask::do_delivery (this=0x7fffe29cf2b0, wid=0) at /home/wantianz/foedus_code/experiments-core/src/foedus/tpcc/tpcc_delivery.cpp:38

Trouble compiling

Hi I'm having issues compiling the benchmarks. When running cmake, it complains:

CMake Error at third_party/gflags-2.1.1/CMakeLists.txt:129 (message):
  Do not know how to define a 32-bit integer quantity on your system! Neither
  uint32_t, u_int32_t, nor __int32 seem to be available.  Set
  GFLAGS_INTTYPES_FORMAT to either C99, BSD, or VC7 and try again.

I was able to bypass it by manually setting the CFLAGS_INTTYPES_FORMAT value in the cmake cache file, but the compilation fails at the last linking step about some errors with the -fPIE option.

Is my workaround of the cmake error correct, and where should I go to set the -fPIE compile time flag when building the gflags library?

I am building on Ubuntu 18.04 with gcc-7.3.

Record expand/shrink methods in hash/masstree packages

Higher priority than other beta-milestone tickets.

The current plan is:
shrink: don't bother. it will be solved when snapshot is taken.
expand: use "moved" flag. In masstree package, this necessitates page split. hash doesn't. our hash traversal logic already takes care of it.

Requiring page split for expand is arguable. We might change the plan.

Masstree's pointer index in minipage doesn't match

Failing assertion:
"pointer_index == minipage.find_pointer(searching_slice)" in adopt_from_child(): foedus-core/src/foedus/storage/masstree/masstree_page_impl.cpp:1300

Setting metadata's min_layer_hint_ to higher value (currently 1) seems working for now.

check environment(hugepagess, shamem limits, etc) on engine start-up

as @hkimura said at #31

Or output unambiguous message(instead of bus error)

This is definitely an issue. I'm thinking about a pre-screening of the environment on engine start-up.
It checks the number of hugepages, shmem limits, etc and immediately fails with a page-full of warning messages explaining the steps the user must take.

I think it should be enabled at least debug mode(defined NDEBUG macro).
On production mode, I can't decide it should be enabled or not(for start-up performance).

Implement YCSB

Everyone else provides it. Why not.
Even simpler than TPCC, so just a copy-paste then a bit of modification.

Probably a good warming-up for a new member.

Bug: Restart code assumed at least one durable log in each logger

Already fixed, but leave this as a record.
When the user doesn't issue any transaction and then shutsdown FOEDUS, loggers don't have emit any log, even no epoch-markers. The snapshot code didn't tolerate this case.

7b10bb1 fixed this by allowing this case.

Feels like this might not be the best solution for robustness (what if it's really a missing log..?)
Maybe a better solution is to always emit at least one dummy log in all loggers right after startup.
let's revisit later

Compact in-memory epoch-history in logger

Currently we keep every single history even though they are thousands of epochs earlier.
We don't need to keep all of them in-memory. We can discard 9/10 of them, for instance.
If a gleaner is lagging behind, it might have to scan more logs due to the history compaction, so we have to find a right balance between wasted memory and wasted work.

Or, write the history out to a file.

related code:

void LoggerRef::add_epoch_history(const EpochMarkerLogType& epoch_marker) {
...
if (control_block_->epoch_history_count_ >= LoggerControlBlock::kMaxEpochHistory) {
// TASK(Hideaki) To avoid this, we should maintain sparse history, like one history per
// tens of epochs. So far kMaxEpochHistory is enough big, so it won't happen.
LOG(FATAL) << "Exceeded kMaxEpochHistory. Unexpected.";
}

Truncate feature in sequential storage

The plan is to provide an API that specifies an epoch up to which we truncate all records.
If the truncate epoch is exactly same as some snapshot epoch, we can just discard some head pointers.
If not, we will probably leave snapshot pages unmodified and discard too-old records at scan time.
This can be trivially achieved by modifying from_epoch in SequentialCursor.
We just need one member in SequentialMetadata to remember "truncated_epoch".

Setup-script or at least more beefy document

Hugepages/shmem/ulimit/dependency/etc. They are super-confusing.
We should have a handy script to do that automatically.

Must be super-careful though. A script run by sudoer to modify /etc/security, grub.cfg, etc... Ohhhh.

masstree manupulation without impersonate?

I'm integrating FOEDUS into MySQL storage engine.

MySQL storage interface requires fine grained manipulation.
But FOEDUS masstree provides only impersonate interface for manipulation.

I know FOEDUS's impersonate interface is owe to performance.
But impersonate for every storage manipulation is too slow and crazy hack is needed for cursor manipulation.

Is there any way to use foedus::storage::MasstreeStorage without impersonation?

Snapshot file compaction and truncation

Currently all snapshot files must be kept forever.
What we should have is a feature to occasionally migrate "ancient" snapshot pages to new snapshots so that we can delete old snapshot files.

We need some kind of statistics to see when we should trigger it, and have to think about the API to expose the feature. This a big TODO.

In the meantime, it might be okay to have a tentative "compact-all" feature to migrate all snapshot pages to a single new snapshot, and delete all snapshot files.

Needs page lock without owner

Marked with "// TODO(Hideaki) PAGE LOCK HERE"

In MasstreeComposeContext::install_snapshot_pointers(), we must take a page lock because the page might be split at the moment. For that, we need a page lock without owner.

The plan is to assign either some node or core ID to a special "no-owner".
Waiters then either spin remotely or locally if they observe such ID.
Now that SGI already (wow) has 256 sockets machines, we shouldn't use node ID for this purpose.
I'm sure one node won't have 256 cores, so probably core-ID 255 can be saved for this.

array/hash/sequential don't need this. Only masstree package needs it.

Test Failure in foedus.soc.SharedPollingTest.Timeout on valgrind

Stacktrace

/var/lib/jenkins/workspace/foedus-develop-release-valgrind/tests-core/src/foedus/soc/test_shared_polling.cpp:99
Value of: received
Actual: true
Expected: false
Standard Output

This issue happens only when we run it on valgrind.
Looks like this is a bug in testcase.

This thread:

void run_thread_hold_longtime(SharedPolling* polling) {
  std::this_thread::sleep_for(std::chrono::milliseconds(100));
  polling->signal();
}

Probably exit the sleep before the main thread detects timeout because valgrind is single-threaded.

Automatic log file truncation or rotation

Currently we never delete xlog files even after snapshot is taken.
This should be easy to implement, but the behavior should be configurable in case the user wants to take backup of the logs to be safe.

In the meantime, it might be ok to just have a script to delete xlog files, which the user occasionally runs.

SIGBUS error

Hi,
I configured a DL380 Gen 8 with Linux for the machine installed on it for FOEDUS as per the documentation. BTW - more accurate instructions for Debian are given by https://wiki.debian.org/Hugepages. Did a simple init as follows:

foedus::EngineOptions options;
myEngine =  new foedus::Engine(options);
//engine.get_proc_manager()->pre_register(kProc, my_proc);
COERCE_ERROR(myEngine->initialize());
foedus::UninitializeGuard guard(myEngine);
foedus::Epoch create_epoch;

Got a SIGBUS error, here is the trace:

I0603 13:35:24.451062  1795 debugging_supports.cpp:98] initialize_glog(): Initialized GLOG
I0603 13:35:24.456940  1802 proc_manager_pimpl.cpp:50] Initializing ProcManager(CHILD-0)..
I0603 13:35:24.457032  1803 proc_manager_pimpl.cpp:50] Initializing ProcManager(CHILD-1)..
I0603 13:35:24.461616  1795 engine_memory.cpp:44] Initializing EngineMemory..
I0603 13:35:24.462049  1802 engine_memory.cpp:44] Initializing EngineMemory..
I0603 13:35:24.462188  1803 engine_memory.cpp:44] Initializing EngineMemory..
I0603 13:35:24.462188  1802 numa_node_memory.cpp:58] Initializing NumaNodeMemory for node 0. BEFORE: numa_node_size=33704828928
I0603 13:35:24.462311  1803 numa_node_memory.cpp:58] Initializing NumaNodeMemory for node 1. BEFORE: numa_node_size=33817817088
Signal: SIGBUS (Bus error)

Error was caused by line 169 in aligned_memory.cpp:

std::memset(block_, 0, size_);

Bug? Config issue?
Thanks,
Tomer

Dynamically load .so for user stored procedures.

The proc package is yet to implement the remote-register feature that copies .so files and loads them at the child nodes.
This is a bit of work because we have to check several things (eg dependency) to load .so.
It must come with lots of trouble shooting functionality. Otherwise will be super-hard to use.

LogMapper::handle_process bug that skips more than io_buffer_size bytes in file

Yupu reported this one.
After the first buffer (status.end_inbuf_aligned_ bytes, which is option.log_mapper_io_buffer_mb_), seems like status.more_in_the_file_ becomes false after LogMapper::handle_process_buffer(). Weird.

Task 1: Make a unit test to concisely reproduce this situation (ggrr, it needs at least 2 MB logs).
Task 2: Fix it.

This didn't happen in TPCC... oh wait, that code immediately invokes log gleaner before shutting down. That might be the difference?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.