libfoedus-core
FOEDUS Core Library
foedus::snapshot::LogGleaner Class Referencefinal

A log-gleaner, which constructs a new set of snapshot files during snapshotting. More...

Detailed Description

A log-gleaner, which constructs a new set of snapshot files during snapshotting.

Log Gleaner Overview

LogGleaner is the main class that manages most mechanisms to construct a new set of snapshot files. Snapshot procedure constructs and calls this object during snapshot. It receives partitioning policy (which snapshot partitions to send ranges of keys) per storage and beginning/ending epoch of logs to glean while log-gleaning.

Log-gleaning consists of two components; mapper (foedus::snapshot::LogMapper) and reducer (foedus::snapshot::LogReducer), obviously named after the well-known map-reduce concepts.

Mapper

LogGleaner launches a set of mapper threads (foedus::snapshot::LogMapper) to read log files. Each LogMapper corresponds to foedus::log::Logger, the NUMA-local log writer which simply writes out log entries produced by local worker threads. Thus, the log files contain log entries that might be sent to any partitions. LogMapper maps each log entry to some partition and send it to a reducer corresponding to the partition. For more details, see foedus::snapshot::LogMapper.

Reducer

LogGleaner also launches a set of reducer threads (foedus::snapshot::LogReducer), one for each NUMA node. LogReducer sorts log entries sent from LogMapper. The log entries are sorted by key and ordinal (*), then processed just like usual APPLY at the end of transaction, but on top of snapshot files.

(*) otherwise correct result is not guaranteed. For example, imagine the following case:

  • UPDATE rec-1 to A. Log-ordinal 1.
  • UPDATE rec-1 to B. Log-ordinal 2.

Ordinal-1 must be processed before ordinal 2.

Synchronization

LogGleaner coordinates the synchronization between mappers and reducers during snapshotting. At the beginning of snapshotting, gleaner wakes up reducers and mappers. Mappers go in to sleep when they process all logs. When all mappers went to sleep, reducers start to also go into sleep when they process all logs they receive. When all of them are done, gleaner initiates the last wrap-up phase. Additionally, LogGleaner is in charge of receiving termination request from the engine if the user invokes Engine::uninitialize() and requesting reducers/mappers to stop.

Reducers/mappers occasionally check if they are requested to stop when they get idle or complete all work. They do the check at least once for a while so that the latency to stop can not be catastrophic.

Constructing Root Pages

After all mappers and reducers complete, the last phase of log gleaning is to construct root pages for the storages modified in this snapshotting. Gleaner collects root-page-info from each reducer and combines them to create the root page(s). When all set, gleaner produces maps from storage ID to a new root page ID. This will be written out in a snapshot metadata file by snapshot manager.

Note
This is a private implementation-details of Snapshot Manager, thus file name ends with _impl. Do not include this header from a client program. There is no case client program needs to access this internal class.

Definition at line 104 of file log_gleaner_impl.hpp.

#include <log_gleaner_impl.hpp>

Inheritance diagram for foedus::snapshot::LogGleaner:
Collaboration diagram for foedus::snapshot::LogGleaner:

Public Member Functions

 LogGleaner (Engine *engine, LogGleanerResource *gleaner_resource, const Snapshot &new_snapshot)
 
 LogGleaner ()=delete
 
 LogGleaner (const LogGleaner &other)=delete
 
LogGleaneroperator= (const LogGleaner &other)=delete
 
ErrorStack execute ()
 Main routine of log gleaner. More...
 
std::string to_string () const
 
const std::map< storage::StorageId, storage::SnapshotPagePointer > & get_new_root_page_pointers () const
 Returns pointers to new root pages constructed at the end of gleaning. More...
 
- Public Member Functions inherited from foedus::snapshot::LogGleanerRef
 LogGleanerRef ()
 
 LogGleanerRef (Engine *engine)
 
bool is_error () const
 
void wakeup ()
 
const Snapshotget_cur_snapshot () const
 
SnapshotId get_snapshot_id () const
 
Epoch get_base_epoch () const
 
Epoch get_valid_until_epoch () const
 
uint16_t increment_completed_count ()
 
uint16_t increment_completed_mapper_count ()
 
uint16_t increment_error_count ()
 
uint16_t increment_exit_count ()
 
bool is_all_exitted () const
 
bool is_all_completed () const
 
bool is_all_mappers_completed () const
 
uint16_t get_mappers_count () const
 
uint16_t get_reducers_count () const
 
uint16_t get_all_count () const
 
- Public Member Functions inherited from foedus::Attachable< LogGleanerControlBlock >
 Attachable ()
 
 Attachable (Engine *engine)
 
 Attachable (Engine *engine, LogGleanerControlBlock *control_block)
 
 Attachable (LogGleanerControlBlock *control_block)
 
 Attachable (const Attachable &other)
 
virtual ~Attachable ()
 
Attachableoperator= (const Attachable &other)
 
virtual void attach (LogGleanerControlBlock *control_block)
 Attaches to the given shared memory. More...
 
bool is_attached () const
 Returns whether the object has been already attached to some shared memory. More...
 
LogGleanerControlBlock * get_control_block () const
 
Engineget_engine () const
 
void set_engine (Engine *engine)
 

Friends

std::ostream & operator<< (std::ostream &o, const LogGleaner &v)
 

Additional Inherited Members

- Protected Attributes inherited from foedus::snapshot::LogGleanerRef
storage::PartitionerMetadatapartitioner_metadata_
 
void * partitioner_data_
 
- Protected Attributes inherited from foedus::Attachable< LogGleanerControlBlock >
Engineengine_
 Most attachable object stores an engine pointer (local engine), so we define it here. More...
 
LogGleanerControlBlock * control_block_
 The shared data on shared memory that has been initialized in some SOC or master engine. More...
 

Constructor & Destructor Documentation

foedus::snapshot::LogGleaner::LogGleaner ( Engine engine,
LogGleanerResource gleaner_resource,
const Snapshot new_snapshot 
)

Definition at line 52 of file log_gleaner_impl.cpp.

56  : LogGleanerRef(engine),
57  gleaner_resource_(gleaner_resource),
58  new_snapshot_(new_snapshot) {
59 }
foedus::snapshot::LogGleaner::LogGleaner ( )
delete
foedus::snapshot::LogGleaner::LogGleaner ( const LogGleaner other)
delete

Member Function Documentation

ErrorStack foedus::snapshot::LogGleaner::execute ( )

Main routine of log gleaner.

Definition at line 148 of file log_gleaner_impl.cpp.

References ASSERT_ND, CHECK_ERROR, foedus::Attachable< LogGleanerControlBlock >::control_block_, foedus::debugging::StopWatch::elapsed_sec(), foedus::Attachable< LogGleanerControlBlock >::engine_, foedus::soc::SharedMemoryRepo::get_global_memory_anchors(), foedus::soc::SocManager::get_shared_memory_repo(), foedus::snapshot::LogGleanerRef::get_snapshot_id(), foedus::Engine::get_soc_manager(), foedus::snapshot::LogGleanerRef::is_all_completed(), foedus::snapshot::LogGleanerRef::is_all_exitted(), foedus::snapshot::LogGleanerRef::is_error(), foedus::kRetOk, SPINLOCK_WHILE, and foedus::debugging::StopWatch::stop().

Referenced by foedus::snapshot::SnapshotManagerPimpl::glean_logs().

148  {
149  LOG(INFO) << "Gleaner starts running: snapshot_id=" << get_snapshot_id();
150  clear_all();
151 
152  LOG(INFO) << "Gleaner Step 1: Design partitions for all storages...";
153  debugging::StopWatch watch1;
154  // Another approach is to delay this step until some mapper really needs it so that we can
155  // skip partition-designing for storages that weren't modified.
156  // However, it requires synchronization in mapper/reducer and this step is anyway fast enough.
157  // So, we so far simply design partitions for all of them.
158  CHECK_ERROR(design_partitions());
159  watch1.stop();
160  LOG(INFO) << "Gleaner Step 1: Ended in " << watch1.elapsed_sec() << "s";
161 
162  LOG(INFO) << "Gleaner Step 2: Run mappers/reducers...";
163  debugging::StopWatch watch2;
164  // Request each node's snapshot manager to launch mappers/reducers threads
165  control_block_->gleaning_ = true;
167  snapshot_manager_memory_->wakeup_snapshot_children();
168 
169  // then, wait until all mappers/reducers are done
171  // snapshot is an infrequent operation, doesn't have to wake up immediately.
172  // just sleep for a while
173  std::this_thread::sleep_for(std::chrono::milliseconds(10));
174  }
175 
176  control_block_->gleaning_ = false;
177  watch2.stop();
178  LOG(INFO) << "Gleaner Step 2: Ended in " << watch2.elapsed_sec() << "s";
179 
180  LOG(INFO) << "Gleaner Step 3: Combine outputs from reducers (root page info)..." << *this;
181  debugging::StopWatch watch3;
182  if (is_error()) {
183  LOG(ERROR) << "Some mapper/reducer got an error. " << *this;
184  } else if (!is_all_completed()) {
185  LOG(WARNING) << "gleaner stopped without completion. cancelled? " << *this;
186  } else {
187  LOG(INFO) << "All mappers/reducers successfully done. Now on to the final phase." << *this;
188  CHECK_ERROR(construct_root_pages());
189  }
190  watch3.stop();
191  LOG(INFO) << "Gleaner Step 3: Ended in " << watch3.elapsed_sec() << "s";
192 
193  LOG(INFO) << "Gleaner Step 4: Uninitializing...";
194  CHECK_ERROR(cancel_reducers_mappers());
196  LOG(INFO) << "Gleaner ends";
197  return kRetOk;
198 }
GlobalMemoryAnchors * get_global_memory_anchors()
Engine * engine_
Most attachable object stores an engine pointer (local engine), so we define it here.
Definition: attachable.hpp:107
LogGleanerControlBlock * control_block_
The shared data on shared memory that has been initialized in some SOC or master engine.
Definition: attachable.hpp:111
#define SPINLOCK_WHILE(x)
A macro to busy-wait (spinlock) with occasional pause.
SnapshotId get_snapshot_id() const
#define CHECK_ERROR(x)
This macro calls x and checks its returned value.
const ErrorStack kRetOk
Normal return value for no-error case.
soc::SocManager * get_soc_manager() const
See SOC and IPC.
Definition: engine.cpp:59
#define ASSERT_ND(x)
A warning-free wrapper macro of assert() that has no performance effect in release mode even when 'x'...
Definition: assert_nd.hpp:72
SharedMemoryRepo * get_shared_memory_repo()
Returns the shared memories maintained across SOCs.
Definition: soc_manager.cpp:38

Here is the call graph for this function:

Here is the caller graph for this function:

const std::map<storage::StorageId, storage::SnapshotPagePointer>& foedus::snapshot::LogGleaner::get_new_root_page_pointers ( ) const
inline

Returns pointers to new root pages constructed at the end of gleaning.

Definition at line 119 of file log_gleaner_impl.hpp.

Referenced by foedus::snapshot::SnapshotManagerPimpl::glean_logs().

120  {
121  return new_root_page_pointers_;
122  }

Here is the caller graph for this function:

LogGleaner& foedus::snapshot::LogGleaner::operator= ( const LogGleaner other)
delete
std::string foedus::snapshot::LogGleaner::to_string ( ) const

Definition at line 307 of file log_gleaner_impl.cpp.

307  {
308  std::stringstream stream;
309  stream << *this;
310  return stream.str();
311 }

Friends And Related Function Documentation

std::ostream& operator<< ( std::ostream &  o,
const LogGleaner v 
)
friend

Definition at line 312 of file log_gleaner_impl.cpp.

312  {
313  o << "<LogGleaner>"
314  << v.new_snapshot_
315  << "<completed_count_>" << v.control_block_->completed_count_ << "</completed_count_>"
316  << "<completed_mapper_count_>"
317  << v.control_block_->completed_mapper_count_ << "</completed_mapper_count_>"
318  << "<error_count_>" << v.control_block_->error_count_ << "</error_count_>"
319  << "<exit_count_>" << v.control_block_->exit_count_ << "</exit_count_>";
320  o << "</LogGleaner>";
321  return o;
322 }

The documentation for this class was generated from the following files: