@@ -8,7 +8,6 @@ pub mod object_store;
88pub mod serialize;
99mod snapshot_tracker;
1010
11- use crate :: snapshot_tracker:: SnapshotInfo ;
1211use async_trait:: async_trait;
1312use data_types:: Timestamp ;
1413use hashbrown:: HashMap ;
@@ -77,16 +76,25 @@ pub trait Wal: Debug + Send + Sync + 'static {
7776 /// permit to release when done. The caller is responsible for cleaning up the wal.
7877 async fn flush_buffer (
7978 & self ,
80- ) -> Option < (
81- oneshot:: Receiver < SnapshotDetails > ,
82- SnapshotInfo ,
83- OwnedSemaphorePermit ,
84- ) > ;
79+ ) -> Option < ( oneshot:: Receiver < SnapshotDetails > , OwnedSemaphorePermit ) > ;
80+
81+ /// This is similar to flush buffer but it allows for snapshot to be done immediately rather
82+ /// than waiting for query buffer to get to a certain capacity. It would be nicer to not
83+ /// require an external interface to force flush the buffer however to decide whether to
84+ /// snapshot immediately is based on query buffer's capacity which is not visible to snapshot
85+ /// tracker which usually decides whether to snapshot or not. To bubble up the query buffer's
86+ /// size or even to indicate that buffer is full we need a shared state and because flushing
87+ /// the buffer is in hot path, this additional method acts as a compromise as this can be
88+ /// called by making the decision to force the snapshot externally to `WalObjectStore` (that
89+ /// implements this trait)
90+ async fn force_flush_buffer (
91+ & self ,
92+ ) -> Option < ( oneshot:: Receiver < SnapshotDetails > , OwnedSemaphorePermit ) > ;
8593
8694 /// Removes any snapshot wal files
8795 async fn cleanup_snapshot (
8896 & self ,
89- snapshot_details : SnapshotInfo ,
97+ snapshot_details : SnapshotDetails ,
9098 snapshot_permit : OwnedSemaphorePermit ,
9199 ) ;
92100
@@ -96,37 +104,29 @@ pub trait Wal: Debug + Send + Sync + 'static {
96104 /// Returns the last persisted wal file sequence number
97105 async fn last_snapshot_sequence_number ( & self ) -> SnapshotSequenceNumber ;
98106
99- /// Returns the snapshot info, if force snapshot is set it avoids checking
100- /// certain cases and returns snapshot info leaving only the last wal period
101- async fn snapshot_info_and_permit (
102- & self ,
103- force_snapshot : bool ,
104- ) -> Option < ( SnapshotInfo , OwnedSemaphorePermit ) > ;
107+ /// Get snapshot details based on conditions
108+ async fn get_snapshot_details ( & self , force_snapshot : bool ) -> Option < SnapshotDetails > ;
105109
106110 /// Stop all writes to the WAL and flush the buffer to a WAL file.
107111 async fn shutdown ( & self ) ;
108112
109113 async fn flush_buffer_and_cleanup_snapshot ( self : Arc < Self > ) {
110114 let maybe_snapshot = self . flush_buffer ( ) . await ;
111- if let Some ( ( snapshot_complete, snapshot_info, permit) ) = maybe_snapshot {
112- self . cleanup_after_snapshot ( snapshot_complete, snapshot_info, permit)
113- . await ;
115+ if let Some ( ( snapshot_complete, permit) ) = maybe_snapshot {
116+ self . cleanup_after_snapshot ( snapshot_complete, permit) . await ;
114117 }
115118 }
116119
117120 async fn cleanup_after_snapshot (
118121 self : Arc < Self > ,
119122 snapshot_complete : oneshot:: Receiver < SnapshotDetails > ,
120- snapshot_info : SnapshotInfo ,
121123 permit : OwnedSemaphorePermit ,
122124 ) {
123125 // handle snapshot cleanup outside of the flush loop
124126 let arcd_wal = Arc :: clone ( & self ) ;
125127 tokio:: spawn ( async move {
126128 let snapshot_details = snapshot_complete. await . expect ( "snapshot failed" ) ;
127- assert_eq ! ( snapshot_info. snapshot_details, snapshot_details) ;
128-
129- arcd_wal. cleanup_snapshot ( snapshot_info, permit) . await ;
129+ arcd_wal. cleanup_snapshot ( snapshot_details, permit) . await ;
130130 } ) ;
131131 }
132132}
@@ -136,22 +136,26 @@ pub trait Wal: Debug + Send + Sync + 'static {
136136#[ async_trait]
137137pub trait WalFileNotifier : Debug + Send + Sync + ' static {
138138 /// Notify the handler that a new WAL file has been persisted with the given contents.
139- fn notify ( & self , write : WalContents ) ;
140-
141- /// Notify the handler that a new WAL file has been persisted with the given contents and tell
142- /// it to snapshot the data. The returned receiver will be signalled when the snapshot is complete.
143- async fn notify_and_snapshot (
139+ async fn notify (
144140 & self ,
145141 write : WalContents ,
146- snapshot_details : SnapshotDetails ,
147- ) -> oneshot:: Receiver < SnapshotDetails > ;
148-
149- /// Snapshot only, currently used to force the snapshot
150- async fn snapshot (
151- & self ,
152- snapshot_details : SnapshotDetails ,
153- ) -> oneshot:: Receiver < SnapshotDetails > ;
154-
142+ do_snapshot : bool ,
143+ ) -> Option < oneshot:: Receiver < SnapshotDetails > > ;
144+
145+ // /// Notify the handler that a new WAL file has been persisted with the given contents and tell
146+ // /// it to snapshot the data. The returned receiver will be signalled when the snapshot is complete.
147+ // async fn notify_and_snapshot(
148+ // &self,
149+ // write: WalContents,
150+ // snapshot_details: SnapshotDetails,
151+ // ) -> oneshot::Receiver<SnapshotDetails>;
152+
153+ // /// Snapshot only, currently used to force the snapshot
154+ // async fn snapshot(
155+ // &self,
156+ // snapshot_details: SnapshotDetails,
157+ // ) -> oneshot::Receiver<SnapshotDetails>;
158+ //
155159 fn as_any ( & self ) -> & dyn Any ;
156160}
157161
@@ -251,6 +255,8 @@ impl Default for Gen1Duration {
251255pub enum WalOp {
252256 Write ( WriteBatch ) ,
253257 Catalog ( OrderedCatalogBatch ) ,
258+ ForcedSnapshot ( SnapshotDetails ) ,
259+ Snapshot ( SnapshotDetails ) ,
254260}
255261
256262impl PartialOrd for WalOp {
@@ -273,6 +279,18 @@ impl Ord for WalOp {
273279
274280 // For two Write ops, consider them equal
275281 ( WalOp :: Write ( _) , WalOp :: Write ( _) ) => Ordering :: Equal ,
282+ ( WalOp :: Write ( _) , WalOp :: ForcedSnapshot ( _) ) => Ordering :: Equal ,
283+ ( WalOp :: Write ( _) , WalOp :: Snapshot ( _) ) => Ordering :: Equal ,
284+ ( WalOp :: Catalog ( _) , WalOp :: ForcedSnapshot ( _) ) => Ordering :: Equal ,
285+ ( WalOp :: Catalog ( _) , WalOp :: Snapshot ( _) ) => Ordering :: Equal ,
286+ ( WalOp :: ForcedSnapshot ( _) , WalOp :: Write ( _) ) => Ordering :: Equal ,
287+ ( WalOp :: ForcedSnapshot ( _) , WalOp :: Catalog ( _) ) => Ordering :: Equal ,
288+ ( WalOp :: ForcedSnapshot ( _) , WalOp :: ForcedSnapshot ( _) ) => Ordering :: Equal ,
289+ ( WalOp :: ForcedSnapshot ( _) , WalOp :: Snapshot ( _) ) => Ordering :: Equal ,
290+ ( WalOp :: Snapshot ( _) , WalOp :: Write ( _) ) => Ordering :: Equal ,
291+ ( WalOp :: Snapshot ( _) , WalOp :: Catalog ( _) ) => Ordering :: Equal ,
292+ ( WalOp :: Snapshot ( _) , WalOp :: ForcedSnapshot ( _) ) => Ordering :: Equal ,
293+ ( WalOp :: Snapshot ( _) , WalOp :: Snapshot ( _) ) => Ordering :: Equal ,
276294 }
277295 }
278296}
@@ -282,13 +300,17 @@ impl WalOp {
282300 match self {
283301 WalOp :: Write ( w) => Some ( w) ,
284302 WalOp :: Catalog ( _) => None ,
303+ WalOp :: ForcedSnapshot ( _) => None ,
304+ WalOp :: Snapshot ( _) => None ,
285305 }
286306 }
287307
288308 pub fn as_catalog ( & self ) -> Option < & CatalogBatch > {
289309 match self {
290310 WalOp :: Write ( _) => None ,
291311 WalOp :: Catalog ( c) => Some ( & c. catalog ) ,
312+ WalOp :: ForcedSnapshot ( _) => None ,
313+ WalOp :: Snapshot ( _) => None ,
292314 }
293315 }
294316}
@@ -837,13 +859,29 @@ pub struct WalContents {
837859 pub wal_file_number : WalFileSequenceNumber ,
838860 /// The operations contained in the WAL file
839861 pub ops : Vec < WalOp > ,
840- /// If present, the buffer should be snapshot after the contents of this file are loaded.
841- pub snapshot : Option < SnapshotDetails > ,
842862}
843863
844864impl WalContents {
845865 pub fn is_empty ( & self ) -> bool {
846- self . ops . is_empty ( ) && self . snapshot . is_none ( )
866+ self . ops . is_empty ( )
867+ }
868+
869+ pub fn add_snapshot_op ( & mut self , snapshot_details : SnapshotDetails ) {
870+ self . ops . push ( WalOp :: Snapshot ( snapshot_details) ) ;
871+ }
872+
873+ pub fn add_force_snapshot_op ( & mut self , snapshot_details : SnapshotDetails ) {
874+ self . ops . push ( WalOp :: ForcedSnapshot ( snapshot_details) ) ;
875+ }
876+
877+ pub fn find_snapshot_details ( & self ) -> Option < SnapshotDetails > {
878+ // There should be only one snapshot in a wal file?
879+ // should assert that
880+ self . ops . iter ( ) . find_map ( |item| match item {
881+ WalOp :: Snapshot ( details) => Some ( * details) ,
882+ WalOp :: ForcedSnapshot ( details) => Some ( * details) ,
883+ _ => None ,
884+ } )
847885 }
848886}
849887
@@ -912,6 +950,8 @@ pub struct SnapshotDetails {
912950 pub snapshot_sequence_number : SnapshotSequenceNumber ,
913951 /// All chunks with data before this time can be snapshot and persisted
914952 pub end_time_marker : i64 ,
953+ /// All wal files with a sequence number >= to this can be deleted once snapshotting is complete
954+ pub first_wal_sequence_number : WalFileSequenceNumber ,
915955 /// All wal files with a sequence number <= to this can be deleted once snapshotting is complete
916956 pub last_wal_sequence_number : WalFileSequenceNumber ,
917957}
0 commit comments