diff --git a/.dockerignore b/.dockerignore index a6e11805e9..b63ef4b7af 100644 --- a/.dockerignore +++ b/.dockerignore @@ -18,6 +18,7 @@ !trace/ !vendor/postgres-v14/ !vendor/postgres-v15/ +!vendor/postgres-v16/ !workspace_hack/ !neon_local/ !scripts/ninstall.sh diff --git a/Dockerfile b/Dockerfile index 9467e41ae4..34b428cbbb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,6 +12,7 @@ WORKDIR /home/nonroot COPY --chown=nonroot vendor/postgres-v14 vendor/postgres-v14 COPY --chown=nonroot vendor/postgres-v15 vendor/postgres-v15 +COPY --chown=nonroot vendor/postgres-v16 vendor/postgres-v16 COPY --chown=nonroot pgxn pgxn COPY --chown=nonroot Makefile Makefile COPY --chown=nonroot scripts/ninstall.sh scripts/ninstall.sh @@ -39,6 +40,7 @@ ARG CACHEPOT_BUCKET=neon-github-dev COPY --from=pg-build /home/nonroot/pg_install/v14/include/postgresql/server pg_install/v14/include/postgresql/server COPY --from=pg-build /home/nonroot/pg_install/v15/include/postgresql/server pg_install/v15/include/postgresql/server +COPY --from=pg-build /home/nonroot/pg_install/v16/include/postgresql/server pg_install/v16/include/postgresql/server COPY --chown=nonroot . . # Show build caching stats to check if it was used in the end. @@ -79,6 +81,7 @@ COPY --from=build --chown=neon:neon /home/nonroot/target/release/proxy COPY --from=pg-build /home/nonroot/pg_install/v14 /usr/local/v14/ COPY --from=pg-build /home/nonroot/pg_install/v15 /usr/local/v15/ +COPY --from=pg-build /home/nonroot/pg_install/v16 /usr/local/v16/ COPY --from=pg-build /home/nonroot/postgres_install.tar.gz /data/ # By default, pageserver uses `.neon/` working directory in WORKDIR, so create one and fill it with the dummy config. diff --git a/Makefile b/Makefile index ae979b8b4c..258154848d 100644 --- a/Makefile +++ b/Makefile @@ -83,6 +83,8 @@ $(POSTGRES_INSTALL_DIR)/build/%/config.status: # I'm not sure why it wouldn't work, but this is the only place (apart from # the "build-all-versions" entry points) where direct mention of PostgreSQL # versions is used. +.PHONY: postgres-configure-v16 +postgres-configure-v16: $(POSTGRES_INSTALL_DIR)/build/v16/config.status .PHONY: postgres-configure-v15 postgres-configure-v15: $(POSTGRES_INSTALL_DIR)/build/v15/config.status .PHONY: postgres-configure-v14 @@ -165,28 +167,33 @@ neon-pg-ext-clean-%: .PHONY: neon-pg-ext neon-pg-ext: \ neon-pg-ext-v14 \ - neon-pg-ext-v15 + neon-pg-ext-v15 \ + neon-pg-ext-v16 .PHONY: neon-pg-ext-clean neon-pg-ext-clean: \ neon-pg-ext-clean-v14 \ - neon-pg-ext-clean-v15 + neon-pg-ext-clean-v15 \ + neon-pg-ext-clean-v16 # shorthand to build all Postgres versions .PHONY: postgres postgres: \ postgres-v14 \ - postgres-v15 + postgres-v15 \ + postgres-v16 .PHONY: postgres-headers postgres-headers: \ postgres-headers-v14 \ - postgres-headers-v15 + postgres-headers-v15 \ + postgres-headers-v16 .PHONY: postgres-clean postgres-clean: \ postgres-clean-v14 \ - postgres-clean-v15 + postgres-clean-v15 \ + postgres-clean-v16 # This doesn't remove the effects of 'configure'. .PHONY: clean diff --git a/control_plane/src/local_env.rs b/control_plane/src/local_env.rs index 208eb9e7ec..e339735321 100644 --- a/control_plane/src/local_env.rs +++ b/control_plane/src/local_env.rs @@ -169,6 +169,7 @@ impl LocalEnv { match pg_version { 14 => Ok(path.join(format!("v{pg_version}"))), 15 => Ok(path.join(format!("v{pg_version}"))), + 16 => Ok(path.join(format!("v{pg_version}"))), _ => bail!("Unsupported postgres version: {}", pg_version), } } @@ -177,6 +178,7 @@ impl LocalEnv { match pg_version { 14 => Ok(self.pg_distrib_dir(pg_version)?.join("bin")), 15 => Ok(self.pg_distrib_dir(pg_version)?.join("bin")), + 16 => Ok(self.pg_distrib_dir(pg_version)?.join("bin")), _ => bail!("Unsupported postgres version: {}", pg_version), } } @@ -184,6 +186,7 @@ impl LocalEnv { match pg_version { 14 => Ok(self.pg_distrib_dir(pg_version)?.join("lib")), 15 => Ok(self.pg_distrib_dir(pg_version)?.join("lib")), + 16 => Ok(self.pg_distrib_dir(pg_version)?.join("lib")), _ => bail!("Unsupported postgres version: {}", pg_version), } } diff --git a/libs/postgres_ffi/build.rs b/libs/postgres_ffi/build.rs index f7e39751ef..8fba4fc9e4 100644 --- a/libs/postgres_ffi/build.rs +++ b/libs/postgres_ffi/build.rs @@ -56,7 +56,7 @@ fn main() -> anyhow::Result<()> { PathBuf::from("pg_install") }; - for pg_version in &["v14", "v15"] { + for pg_version in &["v14", "v15", "v16"] { let mut pg_install_dir_versioned = pg_install_dir.join(pg_version); if pg_install_dir_versioned.is_relative() { let cwd = env::current_dir().context("Failed to get current_dir")?; diff --git a/libs/postgres_ffi/src/lib.rs b/libs/postgres_ffi/src/lib.rs index cc115664d5..fc6aa95e38 100644 --- a/libs/postgres_ffi/src/lib.rs +++ b/libs/postgres_ffi/src/lib.rs @@ -51,6 +51,7 @@ macro_rules! for_all_postgres_versions { ($macro:tt) => { $macro!(v14); $macro!(v15); + $macro!(v16); }; } @@ -92,9 +93,10 @@ pub use v14::bindings::DBState_DB_SHUTDOWNED; pub fn bkpimage_is_compressed(bimg_info: u8, version: u32) -> anyhow::Result { match version { 14 => Ok(bimg_info & v14::bindings::BKPIMAGE_IS_COMPRESSED != 0), - 15 => Ok(bimg_info & v15::bindings::BKPIMAGE_COMPRESS_PGLZ != 0 + 15 | 16 => Ok(bimg_info & v15::bindings::BKPIMAGE_COMPRESS_PGLZ != 0 || bimg_info & v15::bindings::BKPIMAGE_COMPRESS_LZ4 != 0 || bimg_info & v15::bindings::BKPIMAGE_COMPRESS_ZSTD != 0), + _ => anyhow::bail!("Unknown version {}", version), } } @@ -110,6 +112,7 @@ pub fn generate_wal_segment( match pg_version { 14 => v14::xlog_utils::generate_wal_segment(segno, system_id, lsn), 15 => v15::xlog_utils::generate_wal_segment(segno, system_id, lsn), + 16 => v16::xlog_utils::generate_wal_segment(segno, system_id, lsn), _ => Err(SerializeError::BadInput), } } @@ -123,6 +126,7 @@ pub fn generate_pg_control( match pg_version { 14 => v14::xlog_utils::generate_pg_control(pg_control_bytes, checkpoint_bytes, lsn), 15 => v15::xlog_utils::generate_pg_control(pg_control_bytes, checkpoint_bytes, lsn), + 16 => v16::xlog_utils::generate_pg_control(pg_control_bytes, checkpoint_bytes, lsn), _ => anyhow::bail!("Unknown version {}", pg_version), } } @@ -197,7 +201,7 @@ pub fn fsm_logical_to_physical(addr: BlockNumber) -> BlockNumber { pub mod waldecoder { - use crate::{v14, v15}; + use crate::{v14, v15, v16}; use bytes::{Buf, Bytes, BytesMut}; use std::num::NonZeroU32; use thiserror::Error; @@ -259,6 +263,10 @@ pub mod waldecoder { use self::v15::waldecoder_handler::WalStreamDecoderHandler; self.poll_decode_internal() } + 16 => { + use self::v16::waldecoder_handler::WalStreamDecoderHandler; + self.poll_decode_internal() + } _ => Err(WalDecodeError { msg: format!("Unknown version {}", self.pg_version), lsn: self.lsn, diff --git a/libs/postgres_ffi/src/pg_constants_v16.rs b/libs/postgres_ffi/src/pg_constants_v16.rs new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/libs/postgres_ffi/src/pg_constants_v16.rs @@ -0,0 +1 @@ + diff --git a/libs/postgres_ffi/wal_craft/src/lib.rs b/libs/postgres_ffi/wal_craft/src/lib.rs index d4aed88048..d2f853646c 100644 --- a/libs/postgres_ffi/wal_craft/src/lib.rs +++ b/libs/postgres_ffi/wal_craft/src/lib.rs @@ -52,6 +52,7 @@ impl Conf { match self.pg_version { 14 => Ok(path.join(format!("v{}", self.pg_version))), 15 => Ok(path.join(format!("v{}", self.pg_version))), + 16 => Ok(path.join(format!("v{}", self.pg_version))), _ => bail!("Unsupported postgres version: {}", self.pg_version), } } diff --git a/pageserver/src/config.rs b/pageserver/src/config.rs index 4c6df469aa..c49db27ae6 100644 --- a/pageserver/src/config.rs +++ b/pageserver/src/config.rs @@ -655,6 +655,7 @@ impl PageServerConf { match pg_version { 14 => Ok(path.join(format!("v{pg_version}"))), 15 => Ok(path.join(format!("v{pg_version}"))), + 16 => Ok(path.join(format!("v{pg_version}"))), _ => bail!("Unsupported postgres version: {}", pg_version), } } @@ -663,6 +664,7 @@ impl PageServerConf { match pg_version { 14 => Ok(self.pg_distrib_dir(pg_version)?.join("bin")), 15 => Ok(self.pg_distrib_dir(pg_version)?.join("bin")), + 16 => Ok(self.pg_distrib_dir(pg_version)?.join("bin")), _ => bail!("Unsupported postgres version: {}", pg_version), } } @@ -670,6 +672,7 @@ impl PageServerConf { match pg_version { 14 => Ok(self.pg_distrib_dir(pg_version)?.join("lib")), 15 => Ok(self.pg_distrib_dir(pg_version)?.join("lib")), + 16 => Ok(self.pg_distrib_dir(pg_version)?.join("lib")), _ => bail!("Unsupported postgres version: {}", pg_version), } } diff --git a/pageserver/src/walrecord.rs b/pageserver/src/walrecord.rs index 1a34168fed..30a9dbb914 100644 --- a/pageserver/src/walrecord.rs +++ b/pageserver/src/walrecord.rs @@ -360,6 +360,7 @@ impl XlXactParsedRecord { } } let mut xnodes = Vec::::new(); + // In v16 this XACT_XINFO_HAS_RELFILENODES is renamed to XACT_XINFO_HAS_RELFILELOCATORS if xinfo & pg_constants::XACT_XINFO_HAS_RELFILENODES != 0 { let nrels = buf.get_i32_le(); for _i in 0..nrels { diff --git a/safekeeper/src/wal_storage.rs b/safekeeper/src/wal_storage.rs index d728312de4..25a5eb1724 100644 --- a/safekeeper/src/wal_storage.rs +++ b/safekeeper/src/wal_storage.rs @@ -149,6 +149,11 @@ impl PhysicalStorage { wal_seg_size, state.commit_lsn, )?, + 16 => postgres_ffi::v16::xlog_utils::find_end_of_wal( + &timeline_dir, + wal_seg_size, + state.commit_lsn, + )?, _ => bail!("unsupported postgres version: {}", state.server.pg_version), } }; diff --git a/test_runner/fixtures/pg_version.py b/test_runner/fixtures/pg_version.py index b61f52be3c..657718da00 100644 --- a/test_runner/fixtures/pg_version.py +++ b/test_runner/fixtures/pg_version.py @@ -17,6 +17,7 @@ This fixture is used to determine which version of Postgres to use for tests. class PgVersion(str, enum.Enum): V14 = "14" V15 = "15" + V16 = "16" # Instead of making version an optional parameter in methods, we can use this fake entry # to explicitly rely on the default server version (could be different from pg_version fixture value) NOT_SET = "<-POSTRGRES VERSION IS NOT SET->"