Don't hold 'timelines' lock over checkpoint.

It was very noticeable that you while the checkpointer was busy, you
could not e.g. open a new connection.
This commit is contained in:
Heikki Linnakangas
2021-12-03 07:42:10 -05:00
parent d39608c367
commit 5bad2deff8

View File

@@ -238,16 +238,22 @@ impl Repository for LayeredRepository {
}
fn checkpoint_iteration(&self, cconf: CheckpointConfig) -> Result<()> {
{
let timelines = self.timelines.lock().unwrap();
// Scan through the hashmap and collect a list of all the timelines,
// while holding the lock. Then drop the lock and actually perform the
// checkpoints. We don't want to block everything else while the
// checkpoint runs.
let timelines = self.timelines.lock().unwrap();
let timelines_to_checkpoint: Vec<(ZTimelineId, Arc<LayeredTimeline>)> = timelines
.iter()
.map(|(timelineid, timeline)| (*timelineid, timeline.clone()))
.collect();
drop(timelines);
for (timelineid, timeline) in timelines.iter() {
let _entered =
info_span!("checkpoint", timeline = %timelineid, tenant = %self.tenantid)
.entered();
for (timelineid, timeline) in timelines_to_checkpoint.iter() {
let _entered =
info_span!("checkpoint", timeline = %timelineid, tenant = %self.tenantid).entered();
timeline.checkpoint(cconf)?;
}
timeline.checkpoint(cconf)?;
}
Ok(())