mirror of
https://github.com/neondatabase/neon.git
synced 2026-01-07 21:42:56 +00:00
Do not write image layers during enforced checkpoint (#1057)
* Do not write image layers during enforced checkpoint refer #1056 * Add Flush option to CheckpointConfig refer #1057
This commit is contained in:
committed by
GitHub
parent
8f0cd7fb9f
commit
1c47fbae81
@@ -360,7 +360,8 @@ fn shutdown_timeline(
|
||||
.store(false, atomic::Ordering::Relaxed);
|
||||
walreceiver::stop_wal_receiver(timeline_id);
|
||||
trace!("repo shutdown. checkpoint timeline {}", timeline_id);
|
||||
timeline.checkpoint(CheckpointConfig::Forced)?;
|
||||
// Do not reconstruct pages to reduce shutdown time
|
||||
timeline.checkpoint(CheckpointConfig::Flush)?;
|
||||
//TODO Wait for walredo process to shutdown too
|
||||
}
|
||||
LayeredTimelineEntry::Remote { .. } => warn!(
|
||||
@@ -975,12 +976,15 @@ impl Timeline for LayeredTimeline {
|
||||
/// metrics collection.
|
||||
fn checkpoint(&self, cconf: CheckpointConfig) -> Result<()> {
|
||||
match cconf {
|
||||
CheckpointConfig::Flush => STORAGE_TIME
|
||||
.with_label_values(&["flush checkpoint"])
|
||||
.observe_closure_duration(|| self.checkpoint_internal(0, false)),
|
||||
CheckpointConfig::Forced => STORAGE_TIME
|
||||
.with_label_values(&["forced checkpoint"])
|
||||
.observe_closure_duration(|| self.checkpoint_internal(0)),
|
||||
.observe_closure_duration(|| self.checkpoint_internal(0, true)),
|
||||
CheckpointConfig::Distance(distance) => STORAGE_TIME
|
||||
.with_label_values(&["checkpoint"])
|
||||
.observe_closure_duration(|| self.checkpoint_internal(distance)),
|
||||
.observe_closure_duration(|| self.checkpoint_internal(distance, true)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1429,7 +1433,7 @@ impl LayeredTimeline {
|
||||
/// Flush to disk all data that was written with the put_* functions
|
||||
///
|
||||
/// NOTE: This has nothing to do with checkpoint in PostgreSQL.
|
||||
fn checkpoint_internal(&self, checkpoint_distance: u64) -> Result<()> {
|
||||
fn checkpoint_internal(&self, checkpoint_distance: u64, reconstruct_pages: bool) -> Result<()> {
|
||||
let mut write_guard = self.write_lock.lock().unwrap();
|
||||
let mut layers = self.layers.lock().unwrap();
|
||||
|
||||
@@ -1486,7 +1490,7 @@ impl LayeredTimeline {
|
||||
drop(layers);
|
||||
drop(write_guard);
|
||||
|
||||
let mut this_layer_uploads = self.evict_layer(oldest_layer_id)?;
|
||||
let mut this_layer_uploads = self.evict_layer(oldest_layer_id, reconstruct_pages)?;
|
||||
layer_uploads.append(&mut this_layer_uploads);
|
||||
|
||||
write_guard = self.write_lock.lock().unwrap();
|
||||
@@ -1566,7 +1570,7 @@ impl LayeredTimeline {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn evict_layer(&self, layer_id: LayerId) -> Result<Vec<PathBuf>> {
|
||||
fn evict_layer(&self, layer_id: LayerId, reconstruct_pages: bool) -> Result<Vec<PathBuf>> {
|
||||
// Mark the layer as no longer accepting writes and record the end_lsn.
|
||||
// This happens in-place, no new layers are created now.
|
||||
// We call `get_last_record_lsn` again, which may be different from the
|
||||
@@ -1591,7 +1595,7 @@ impl LayeredTimeline {
|
||||
drop(layers);
|
||||
drop(write_guard);
|
||||
|
||||
let new_historics = oldest_layer.write_to_disk(self)?;
|
||||
let new_historics = oldest_layer.write_to_disk(self, reconstruct_pages)?;
|
||||
|
||||
write_guard = self.write_lock.lock().unwrap();
|
||||
layers = self.layers.lock().unwrap();
|
||||
|
||||
@@ -575,12 +575,16 @@ impl InMemoryLayer {
|
||||
/// Write the this frozen in-memory layer to disk.
|
||||
///
|
||||
/// Returns new layers that replace this one.
|
||||
/// If not dropped, returns a new image layer containing the page versions
|
||||
/// If not dropped and reconstruct_pages is true, returns a new image layer containing the page versions
|
||||
/// at the `end_lsn`. Can also return a DeltaLayer that includes all the
|
||||
/// WAL records between start and end LSN. (The delta layer is not needed
|
||||
/// when a new relish is created with a single LSN, so that the start and
|
||||
/// end LSN are the same.)
|
||||
pub fn write_to_disk(&self, timeline: &LayeredTimeline) -> Result<LayersOnDisk> {
|
||||
pub fn write_to_disk(
|
||||
&self,
|
||||
timeline: &LayeredTimeline,
|
||||
reconstruct_pages: bool,
|
||||
) -> Result<LayersOnDisk> {
|
||||
trace!(
|
||||
"write_to_disk {} get_end_lsn is {}",
|
||||
self.filename().display(),
|
||||
@@ -606,7 +610,7 @@ impl InMemoryLayer {
|
||||
// Figure out if we should create a delta layer, image layer, or both.
|
||||
let image_lsn: Option<Lsn>;
|
||||
let delta_end_lsn: Option<Lsn>;
|
||||
if self.is_dropped() {
|
||||
if self.is_dropped() || !reconstruct_pages {
|
||||
// The segment was dropped. Create just a delta layer containing all the
|
||||
// changes up to and including the drop.
|
||||
delta_end_lsn = Some(end_lsn_exclusive);
|
||||
|
||||
@@ -38,5 +38,7 @@ pub enum CheckpointConfig {
|
||||
// Flush in-memory data that is older than this
|
||||
Distance(u64),
|
||||
// Flush all in-memory data
|
||||
Flush,
|
||||
// Flush all in-memory data and reconstruct all page images
|
||||
Forced,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user