@@ -90,6 +90,8 @@ impl LocalShard {
9090 let temp_path = temp_path. to_owned ( ) ;
9191
9292 let tar_c = tar. clone ( ) ;
93+ let update_lock = self . update_operation_lock . clone ( ) ;
94+
9395 tokio:: task:: spawn_blocking ( move || {
9496 // Do not change segments while snapshotting
9597 snapshot_all_segments (
@@ -101,6 +103,7 @@ impl LocalShard {
101103 & tar_c. descend ( Path :: new ( SEGMENTS_PATH ) ) ?,
102104 format,
103105 manifest. as_ref ( ) ,
106+ update_lock,
104107 ) ?;
105108
106109 if save_wal {
@@ -210,6 +213,9 @@ pub fn snapshot_all_segments(
210213 tar : & tar_ext:: BuilderExt ,
211214 format : SnapshotFormat ,
212215 manifest : Option < & SnapshotManifest > ,
216+ // Update lock prevents segment operations during update.
217+ // For instance, we can't unproxy segments while update operation is in progress.
218+ update_lock : Arc < tokio:: sync:: RwLock < ( ) > > ,
213219) -> OperationResult < ( ) > {
214220 // Snapshotting may take long-running read locks on segments blocking incoming writes, do
215221 // this through proxied segments to allow writes to continue.
@@ -232,6 +238,7 @@ pub fn snapshot_all_segments(
232238 ) ?;
233239 Ok ( ( ) )
234240 } ,
241+ update_lock,
235242 )
236243}
237244
@@ -264,6 +271,7 @@ pub fn proxy_all_segments_and_apply<F>(
264271 segment_config : Option < SegmentConfig > ,
265272 payload_index_schema : Arc < SaveOnDisk < PayloadIndexSchema > > ,
266273 mut operation : F ,
274+ update_lock : Arc < tokio:: sync:: RwLock < ( ) > > ,
267275) -> OperationResult < ( ) >
268276where
269277 F : FnMut ( & RwLock < dyn SegmentEntry > ) -> OperationResult < ( ) > ,
@@ -318,6 +326,7 @@ where
318326 // by `Self::unproxy_all_segments` afterwards to maintain the read consistency.
319327 let remaining = proxies. len ( ) - unproxied_segment_ids. len ( ) ;
320328 if remaining > 1 {
329+ let _update_guard = update_lock. blocking_read ( ) ;
321330 match SegmentHolder :: try_unproxy_segment (
322331 segments_lock,
323332 * segment_id,
@@ -336,6 +345,7 @@ where
336345 // Unproxy all segments
337346 // Always do this to prevent leaving proxy segments behind
338347 log:: trace!( "Unproxying all shard segments after function is applied" ) ;
348+ let _update_guard = update_lock. blocking_read ( ) ;
339349 SegmentHolder :: unproxy_all_segments ( segments_lock, proxies, tmp_segment) ?;
340350
341351 result
0 commit comments