Skip to content

Commit

Permalink
[GAIAPLAT-1749] INDEX: Keep track of updated txn id, mark committed t…
Browse files Browse the repository at this point in the history
…xn ids and skip if no work to be done (#1121)

* Add watermarks to indexes to determine if gc needs to be done.

* removed <atomic> include

* Added more comments.

* Cleaned up comments.

Co-authored-by: yiwen-wong <[email protected]>
  • Loading branch information
yiwen-wong and yiwen-wong authored Dec 8, 2021
1 parent 3a23917 commit ef647b0
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 10 deletions.
8 changes: 4 additions & 4 deletions production/db/core/src/index_builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -462,10 +462,10 @@ void index_builder_t::update_indexes_from_txn_log(
}

template <class T_index>
void remove_entries_with_offsets(base_index_t* base_index, const std::unordered_set<gaia_offset_t>& offsets)
void remove_entries_with_offsets(base_index_t* base_index, const std::unordered_set<gaia_offset_t>& offsets, gaia_txn_id_t txn_id)
{
auto index = static_cast<T_index*>(base_index);
index->remove_index_entry_with_offsets(offsets);
index->remove_index_entry_with_offsets(offsets, txn_id);
}

void index_builder_t::gc_indexes_from_txn_log(const txn_log_t& records, bool deallocate_new_offsets)
Expand Down Expand Up @@ -513,10 +513,10 @@ void index_builder_t::gc_indexes_from_txn_log(const txn_log_t& records, bool dea
switch (it.second->type())
{
case catalog::index_type_t::range:
remove_entries_with_offsets<range_index_t>(it.second.get(), collected_offsets);
remove_entries_with_offsets<range_index_t>(it.second.get(), collected_offsets, records.begin_ts);
break;
case catalog::index_type_t::hash:
remove_entries_with_offsets<hash_index_t>(it.second.get(), collected_offsets);
remove_entries_with_offsets<hash_index_t>(it.second.get(), collected_offsets, records.begin_ts);
break;
}
}
Expand Down
13 changes: 10 additions & 3 deletions production/db/inc/index/index.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,11 @@ class index_t : public base_index_t

// Index structure maintenance.
void insert_index_entry(index_key_t&& key, index_record_t record);
void remove_index_entry_with_offsets(const std::unordered_set<gaia_offset_t>& offsets);
void remove_index_entry_with_offsets(const std::unordered_set<gaia_offset_t>& offsets, gaia_txn_id_t gc_txn_id);

// This method will mark all entries below a specified txn_id as committed.
// This must only be called once all aborted/terminated index entries below the txn_id are garbage collected.
void mark_entries_committed(gaia_txn_id_t txn_id);
// This must only be called after all aborted/terminated index entries below the txn_id are garbage collected.
void mark_entries_committed(gaia_txn_id_t metadata_truncation_txn_id);

// Clear index structure.
void clear() override;
Expand All @@ -92,6 +92,13 @@ class index_t : public base_index_t
// Find physical key corresponding to a logical_key + record or return the end iterator.
// Returns the iterator type of the underlying structure.
typename T_structure::iterator find_physical_key(const index_key_t& key, const index_record_t& record);

// The following txn_ids are internal markers to determine if any work needs to be done for garbage collection.
//
// last_updated_txn_id - txn_id where the index was last updated/modified.
// last_mark_committed_txn_id - the txn_id below which all index entries have been marked committed.
gaia_txn_id_t m_last_updated_txn_id;
gaia_txn_id_t m_last_mark_committed_txn_id;
};

#include "index.inc"
Expand Down
44 changes: 41 additions & 3 deletions production/db/inc/index/index.inc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ template <typename T_structure, typename T_iterator>
void index_t<T_structure, T_iterator>::insert_index_entry(index_key_t&& key, index_record_t record)
{
std::lock_guard lock(m_index_lock);

// Update the last updated txn id if necessary.
if (record.txn_id > m_last_updated_txn_id)
{
m_last_updated_txn_id = record.txn_id;
}

auto old_it = find_physical_key(key, record);
if (old_it != m_data.end())
{
Expand All @@ -22,9 +29,17 @@ void index_t<T_structure, T_iterator>::insert_index_entry(index_key_t&& key, ind
}

template <typename T_structure, typename T_iterator>
void index_t<T_structure, T_iterator>::remove_index_entry_with_offsets(const std::unordered_set<gaia_offset_t>& offsets)
void index_t<T_structure, T_iterator>::remove_index_entry_with_offsets(const std::unordered_set<gaia_offset_t>& offsets, gaia_txn_id_t gc_txn_id)
{
std::lock_guard lock(m_index_lock);

if (gc_txn_id > m_last_updated_txn_id)
{
// Nothing to do here. We have not made any updates to this index past the gc point, so the offsets associated with
// the gc_txn_id do not exist in this index.
return;
}

for (auto it = m_data.begin(); it != m_data.end();)
{
if (offsets.find(it->second.offset) != offsets.end())
Expand All @@ -39,19 +54,40 @@ void index_t<T_structure, T_iterator>::remove_index_entry_with_offsets(const std
}

template <typename T_structure, typename T_iterator>
void index_t<T_structure, T_iterator>::mark_entries_committed(gaia_txn_id_t txn_id)
void index_t<T_structure, T_iterator>::mark_entries_committed(gaia_txn_id_t metadata_truncation_txn_id)
{
{
std::lock_guard lock(m_index_lock);
if (m_last_mark_committed_txn_id >= m_last_updated_txn_id)
{
// Nothing to do here. All index entries have already been marked and we have not modified the index since.
//
// It is unsafe to check m_last_updated_txn_id against the metadata truncation id since metadata_truncation_txn_id can advance
// ahead of the last mark committed point without updating the index. This situation leads to required lookups
// on truncated metadata on the next index lookup.
return;
}
}

for (auto it = m_data.begin(); it != m_data.end(); ++it)
{
auto& record = it->second;

if (record.txn_id <= txn_id)
if (record.txn_id <= metadata_truncation_txn_id)
{
// This should ideally be atomic, but the records stop becoming copyable.
std::lock_guard lock(m_index_lock);
mark_committed(record);
}
}

{
std::lock_guard lock(m_index_lock);
if (metadata_truncation_txn_id > m_last_mark_committed_txn_id)
{
m_last_mark_committed_txn_id = metadata_truncation_txn_id;
}
}
}

// Clear index structure.
Expand All @@ -60,6 +96,8 @@ void index_t<T_structure, T_iterator>::clear()
{
std::lock_guard lock(m_index_lock);
m_data.clear();
m_last_updated_txn_id = c_invalid_gaia_txn_id;
m_last_mark_committed_txn_id = c_invalid_gaia_txn_id;
}

// RAII class for bulk index maintenance operations.
Expand Down

0 comments on commit ef647b0

Please sign in to comment.