@@ -170,20 +170,13 @@ class server_t
170170 // eligible for GC. GC cannot be started for any committed txn until the
171171 // post-apply watermark has advanced to its commit_ts. The "post-GC"
172172 // watermark represents a lower bound on the latest commit_ts whose txn log
173- // could have had GC reclaim all its resources. Finally, the "pre-truncate"
174- // watermark represents an (exclusive) upper bound on the timestamps whose
175- // metadata entries could have had their memory reclaimed (e.g., via
176- // zeroing, unmapping, or overwriting). Any timestamp whose metadata entry
177- // could potentially be dereferenced must be "reserved" via the "safe_ts"
178- // API to prevent the pre-truncate watermark from advancing past it and
179- // allowing its metadata entry to be reclaimed.
173+ // could have had GC reclaim all its resources. The txn table cannot be
174+ // safely truncated at any timestamp after the post-GC watermark.
180175 //
181176 // The pre-apply watermark must either be equal to the post-apply watermark or greater by 1.
182177 //
183178 // Schematically:
184- // commit timestamps of transactions whose metadata entries have been reclaimed
185- // < pre-truncate watermark
186- // <= commit timestamps of transactions completely garbage-collected
179+ // commit timestamps of transactions completely garbage-collected
187180 // <= post-GC watermark
188181 // <= commit timestamps of transactions applied to shared view
189182 // <= post-apply watermark
@@ -196,114 +189,24 @@ class server_t
196189 pre_apply,
197190 post_apply,
198191 post_gc,
199- pre_truncate,
200192 // This should always be last.
201193 count
202194 };
203195
204- // An array of monotonically nondecreasing timestamps, or "watermarks", that
205- // represent the progress of system maintenance tasks with respect to txn
206- // timestamps. See `watermark_type_t` for a full explanation.
207196 static inline std::array<std::atomic<gaia_txn_id_t >, common::get_enum_value(watermark_type_t ::count)> s_watermarks{};
208197
209- // A global array in which each session thread publishes a "safe timestamp"
210- // that it needs to protect from memory reclamation. The minimum of all
211- // published "safe timestamps" is an upper bound below which all txn
212- // metadata entries can be safely reclaimed.
213- //
214- // Each thread maintains 2 publication entries rather than 1, in order to
215- // tolerate validation failures. See the reserve_safe_ts() implementation
216- // for a full explanation.
217- //
218- // Before using the safe_ts API, a thread must first reserve an index in
219- // this array using reserve_safe_ts_index(). When a thread is no longer
220- // using the safe_ts API (e.g., at session exit), it should call
221- // release_safe_ts_index() to make this index available for use by other
222- // threads.
223- //
224- // The only clients of the safe_ts API are expected to be session threads,
225- // so we only allocate enough entries for the maximum allowed number of
226- // session threads.
227- static inline std::array<std::array<std::atomic<gaia_txn_id_t >, 2 >, c_session_limit>
228- s_safe_ts_per_thread_entries{};
229-
230- // The reserved status of each index into `s_safe_ts_per_thread_entries` is
231- // tracked in this bitmap. Before calling any safe_ts API functions, each
232- // thread must reserve an index by setting a cleared bit in this bitmap.
233- // When it is no longer using the safe_ts API (e.g., at session exit), each
234- // thread should clear the bit that it set.
235- static inline std::array<
236- std::atomic<uint64_t >, s_safe_ts_per_thread_entries.size() / memory_manager::c_uint64_bit_count>
237- s_safe_ts_reserved_indexes_bitmap{};
238-
239- static constexpr size_t c_invalid_safe_ts_index{s_safe_ts_per_thread_entries.size ()};
240-
241- // The current thread's index in `s_safe_ts_per_thread_entries`.
242- thread_local static inline size_t s_safe_ts_index{c_invalid_safe_ts_index};
243-
244- private:
245- // Returns the current value of the given watermark.
246198 static inline gaia_txn_id_t get_watermark (watermark_type_t watermark)
247199 {
248200 return s_watermarks[common::get_enum_value (watermark)].load ();
249201 }
250202
251- // Returns a reference to the array entry of the given watermark.
252203 static inline std::atomic<gaia_txn_id_t >& get_watermark_entry (watermark_type_t watermark)
253204 {
254205 return s_watermarks[common::get_enum_value (watermark)];
255206 }
256207
257- // Atomically advances the given watermark to the given timestamp, if the
258- // given timestamp is larger than the watermark's current value. It thus
259- // guarantees that the watermark is monotonically nondecreasing in time.
260- //
261- // Returns true if the watermark was advanced to the given value, false
262- // otherwise.
263208 static bool advance_watermark (watermark_type_t watermark, gaia_txn_id_t ts);
264209
265- // Reserves an index for the current thread in
266- // `s_safe_ts_per_thread_entries`. The entries at this index are read-write
267- // for the current thread and read-only for all other threads.
268- //
269- // Returns true if an index was successfully reserved, false otherwise.
270- static bool reserve_safe_ts_index ();
271-
272- // Releases the current thread's index in `s_safe_ts_per_thread_entries`,
273- // allowing the entries at that index to be used by other threads.
274- //
275- // This method cannot fail or throw.
276- static void release_safe_ts_index ();
277-
278- // Reserves a "safe timestamp" that protects its own and all subsequent
279- // metadata entries from memory reclamation, by ensuring that the
280- // pre-truncate watermark can never advance past it until release_safe_ts()
281- // is called on that timestamp.
282- //
283- // Any previously reserved "safe timestamp" value for this thread will be
284- // atomically replaced by the new "safe timestamp" value.
285- //
286- // This operation can fail if post-publication validation fails. See the
287- // reserve_safe_ts() implementation for details.
288- //
289- // Returns true if the given timestamp was successfully reserved, false
290- // otherwise.
291- static bool reserve_safe_ts (gaia_txn_id_t safe_ts);
292-
293- // Releases the current thread's "safe timestamp", allowing the pre-truncate
294- // watermark to advance past it, signaling to GC tasks that its metadata
295- // entry is eligible for reclamation.
296- //
297- // This method cannot fail or throw.
298- static void release_safe_ts ();
299-
300- // This method computes a "safe truncation timestamp", i.e., an (exclusive)
301- // upper bound below which all txn metadata entries can be safely reclaimed.
302- //
303- // The timestamp returned is guaranteed not to exceed any "safe timestamp"
304- // that was reserved before this method was called.
305- static gaia_txn_id_t get_safe_truncation_ts ();
306-
307210private:
308211 // A list of data mappings that we manage together.
309212 // The order of declarations must be the order of data_mapping_t::index_t values!
@@ -438,7 +341,7 @@ class server_t
438341
439342 static void gc_applied_txn_logs ();
440343
441- static void truncate_txn_table ();
344+ static void update_txn_table_safe_truncation_point ();
442345
443346 static gaia_txn_id_t submit_txn (gaia_txn_id_t begin_ts, int log_fd);
444347
0 commit comments