storcon: use shard 0's initdb for timeline creation (#11727)

## Problem

In princple, pageservers with different postgres binaries might generate
different initdbs, resulting in inconsistency between shards. To avoid
that, we should have shard 0 generate the initdb and other shards re-use
it.

Fixes: https://github.com/neondatabase/neon/issues/11340

## Summary of changes

- For shards with index greater than zero, set
`existing_initdb_timeline_id` in timeline creation to consume the
existing initdb rather than creating a new one
This commit is contained in:
John Spray
2025-04-28 17:43:35 +01:00
committed by GitHub
parent b1fa68f659
commit 998d2c2ce9

View File

@@ -3720,6 +3720,10 @@ impl Service {
// Because the caller might not provide an explicit LSN, we must do the creation first on a single shard, and then
// use whatever LSN that shard picked when creating on subsequent shards. We arbitrarily use shard zero as the shard
// that will get the first creation request, and propagate the LSN to all the >0 shards.
//
// This also enables non-zero shards to use the initdb that shard 0 generated and uploaded to S3, rather than
// independently generating their own initdb. This guarantees that shards cannot end up with different initial
// states if e.g. they have different postgres binary versions.
let timeline_info = create_one(
shard_zero_tid,
shard_zero_locations,
@@ -3729,11 +3733,16 @@ impl Service {
)
.await?;
// Propagate the LSN that shard zero picked, if caller didn't provide one
// Update the create request for shards >= 0
match &mut create_req.mode {
models::TimelineCreateRequestMode::Branch { ancestor_start_lsn, .. } if ancestor_start_lsn.is_none() => {
// Propagate the LSN that shard zero picked, if caller didn't provide one
*ancestor_start_lsn = timeline_info.ancestor_lsn;
},
models::TimelineCreateRequestMode::Bootstrap { existing_initdb_timeline_id, .. } => {
// For shards >= 0, do not run initdb: use the one that shard 0 uploaded to S3
*existing_initdb_timeline_id = Some(create_req.new_timeline_id)
}
_ => {}
}