diff --git a/PostgreSQL/build_rdbms_01/Readme.md b/PostgreSQL/build_rdbms_01/Readme.md index c98a37c..67995eb 100644 --- a/PostgreSQL/build_rdbms_01/Readme.md +++ b/PostgreSQL/build_rdbms_01/Readme.md @@ -41,10 +41,13 @@ The orchestrator runs the installers in this order: 4. pgAudit 5. set_user 6. pg_stat_statements -7. passwordcheck -8. pg_repack -9. pg_stat_monitor -10. pgvector +7. auto_explain +8. passwordcheck +9. pg_repack +10. pg_stat_monitor +11. pgvector +12. HypoPG +13. pg_hint_plan After a successful run, the orchestrator: @@ -66,10 +69,13 @@ Each component can also be installed independently. The PostgreSQL installation ./install_pgaudit.sh --version 18.6 ./install_set_user.sh --version 18.6 ./install_pg_stat_statements.sh --version 18.6 +./install_auto_explain.sh --version 18.6 ./install_passwordcheck.sh --version 18.6 ./install_pg_repack.sh --version 18.6 ./install_pg_stat_monitor.sh --version 18.6 ./install_pgvector.sh --version 18.6 +./install_hypopg.sh --version 18.6 +./install_pg_hint_plan.sh --version 18.6 ``` Each installer also accepts `-v 18.6` and the previous positional form (`./install_pg_cron.sh 18.6`). The all-in-one orchestrator passes its complete `--version` value to every component installer. @@ -137,6 +143,18 @@ Builds and installs Percona's `pg_stat_monitor` extension. Builds and installs pgvector against the selected PostgreSQL installation. +### `install_auto_explain.sh` + +Builds and installs PostgreSQL's `auto_explain` contrib module from the matching PostgreSQL source. It has no `CREATE EXTENSION` control file; load it in sessions with `LOAD 'auto_explain'` or configure it for server startup. + +### `install_hypopg.sh` + +Builds and installs HypoPG against the selected PostgreSQL installation. Create the extension in each database where it will be used with `CREATE EXTENSION hypopg`. + +### `install_pg_hint_plan.sh` + +Builds and installs the pg_hint_plan tag matching the PostgreSQL major version when available. Create it in each database where it will be used with `CREATE EXTENSION pg_hint_plan`. + ### `install_common.sh` Shared helper functions used by the installers, including: @@ -167,6 +185,8 @@ The following environment variables can override defaults: | `PG_REPACK_TAG` | Latest release/tag | pg_repack source tag | | `PG_STAT_MONITOR_TAG` | Latest release/tag | pg_stat_monitor source tag | | `PGVECTOR_TAG` | Latest release/tag | pgvector source tag | +| `HYPOPG_TAG` | Latest release/tag | HypoPG source tag | +| `PG_HINT_PLAN_TAG` | PostgreSQL-major-compatible tag | pg_hint_plan source tag | Repository variables can also be overridden when using a custom mirror: @@ -178,6 +198,8 @@ SET_USER_REPOSITORY=owner/repository PG_REPACK_REPOSITORY=owner/repository PG_STAT_MONITOR_REPOSITORY=owner/repository PGVECTOR_REPOSITORY=owner/repository +HYPOPG_REPOSITORY=owner/repository +PG_HINT_PLAN_REPOSITORY=owner/repository ``` Example: @@ -197,7 +219,7 @@ When `CONFIG_FILE` is supplied, the orchestrator adds the modules and extensions shared_preload_libraries = 'pg_cron,timescaledb,pgaudit,pg_stat_statements,pg_stat_monitor,passwordcheck' ``` -`pg_repack`, pgvector, and `set_user` do not require `shared_preload_libraries`. `passwordcheck` is a PostgreSQL contrib module (not a SQL extension), and `pg_stat_activity` is a built-in PostgreSQL system view. +`pg_repack`, pgvector, HypoPG, and `set_user` do not require `shared_preload_libraries`. `auto_explain` and pg_hint_plan can be loaded per session or configured for server startup; they are not added automatically. `passwordcheck` and `auto_explain` are PostgreSQL contrib modules (not SQL extensions), and `pg_stat_activity` is a built-in PostgreSQL system view. ## Prerequisites @@ -237,7 +259,10 @@ ls \ /app/postgres/rdbms/18.6/lib/timescaledb.so \ /app/postgres/rdbms/18.6/lib/pgaudit.so \ /app/postgres/rdbms/18.6/lib/set_user.so \ - /app/postgres/rdbms/18.6/lib/pg_stat_monitor.so + /app/postgres/rdbms/18.6/lib/pg_stat_monitor.so \ + /app/postgres/rdbms/18.6/lib/auto_explain.so \ + /app/postgres/rdbms/18.6/lib/hypopg.so \ + /app/postgres/rdbms/18.6/lib/pg_hint_plan.so ``` The extension SQL objects still need to be created in each target database with PostgreSQL's `CREATE EXTENSION` command. diff --git a/PostgreSQL/build_rdbms_01/install_auto_explain.sh b/PostgreSQL/build_rdbms_01/install_auto_explain.sh new file mode 100644 index 0000000..0b85ea1 --- /dev/null +++ b/PostgreSQL/build_rdbms_01/install_auto_explain.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash + +set -Eeuo pipefail + +SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" +# shellcheck source=install_common.sh +source "$SCRIPT_DIR/install_common.sh" + +readonly STAGING_DIR="${STAGING_DIR:-$SCRIPT_DIR/tmp}" +readonly POSTGRES_ROOT="${POSTGRES_ROOT:-/app/postgres/rdbms}" + +if [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]]; then + show_help "$0" "Build and install PostgreSQL's auto_explain module." + exit 0 +fi + +POSTGRES_VERSION="$(parse_postgresql_version "$@")" +readonly POSTGRES_VERSION +require_tools curl tar make +readonly PREFIX="${PREFIX:-$POSTGRES_ROOT/$POSTGRES_VERSION}" +readonly PG_CONFIG="$PREFIX/bin/pg_config" +require_postgresql_installation "$PREFIX" +reset_staging_dir "$STAGING_DIR" + +printf 'Building auto_explain from PostgreSQL %s\n' "$POSTGRES_VERSION" +readonly POSTGRES_ARCHIVE="$STAGING_DIR/postgresql-$POSTGRES_VERSION.tar.gz" +readonly POSTGRES_SOURCE="$STAGING_DIR/postgresql-$POSTGRES_VERSION" +curl -fL --retry 3 --retry-delay 2 \ + -o "$POSTGRES_ARCHIVE" \ + "https://ftp.postgresql.org/pub/source/v$POSTGRES_VERSION/postgresql-$POSTGRES_VERSION.tar.gz" +tar -xzf "$POSTGRES_ARCHIVE" -C "$STAGING_DIR" + +readonly AUTO_EXPLAIN_SOURCE="$POSTGRES_SOURCE/contrib/auto_explain" +make -C "$AUTO_EXPLAIN_SOURCE" \ + -j"${JOBS:-$(nproc)}" USE_PGXS=1 PG_CONFIG="$PG_CONFIG" +make -C "$AUTO_EXPLAIN_SOURCE" \ + install USE_PGXS=1 PG_CONFIG="$PG_CONFIG" +test -f "$PREFIX/lib/auto_explain.so" + +readonly SAVED_SOURCE_DIR="$(copy_install_source "$AUTO_EXPLAIN_SOURCE" "$PREFIX" "auto_explain-$POSTGRES_VERSION")" +write_install_recipe "$SAVED_SOURCE_DIR" "$POSTGRES_VERSION" "$PREFIX" <<'RECIPE' +cd "$SCRIPT_DIR" + +# Configure +# auto_explain uses PGXS directly and does not require a separate configure step. + +# Make +make -j"$JOBS" USE_PGXS=1 PG_CONFIG="$PG_CONFIG" + +# Make install +make install USE_PGXS=1 PG_CONFIG="$PG_CONFIG" +RECIPE diff --git a/PostgreSQL/build_rdbms_01/install_common.sh b/PostgreSQL/build_rdbms_01/install_common.sh index c3839d9..db2ceb8 100644 --- a/PostgreSQL/build_rdbms_01/install_common.sh +++ b/PostgreSQL/build_rdbms_01/install_common.sh @@ -98,6 +98,20 @@ latest_pgaudit_tag() { printf '%s\n' "${tag:-$(latest_tag "$repository")}" } +latest_pg_hint_plan_tag() { + local repository="$1" + local major="$2" + local tag + + tag="$( + curl -fsSL "https://api.github.com/repos/$repository/tags?per_page=100" | + sed -nE 's/^[[:space:]]*"name":[[:space:]]*"([^"]+)".*/\1/p' | + grep -E "^REL${major}_" | + head -n 1 || true + )" + printf '%s\n' "${tag:-$(latest_tag "$repository")}" +} + reset_staging_dir() { local staging_dir="$1" [[ "$staging_dir" != "/" ]] || die "STAGING_DIR must not be the filesystem root" diff --git a/PostgreSQL/build_rdbms_01/install_hypopg.sh b/PostgreSQL/build_rdbms_01/install_hypopg.sh new file mode 100644 index 0000000..b0d90c9 --- /dev/null +++ b/PostgreSQL/build_rdbms_01/install_hypopg.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash + +set -Eeuo pipefail + +SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" +# shellcheck source=install_common.sh +source "$SCRIPT_DIR/install_common.sh" + +readonly STAGING_DIR="${STAGING_DIR:-$SCRIPT_DIR/tmp}" +readonly POSTGRES_ROOT="${POSTGRES_ROOT:-/app/postgres/rdbms}" +readonly HYPOPG_REPOSITORY="${HYPOPG_REPOSITORY:-HypoPG/HypoPG}" + +if [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]]; then + show_help "$0" "Build and install HypoPG for an existing PostgreSQL installation." + exit 0 +fi + +POSTGRES_VERSION="$(parse_postgresql_version "$@")" +readonly POSTGRES_VERSION +require_tools curl tar make +readonly PREFIX="${PREFIX:-$POSTGRES_ROOT/$POSTGRES_VERSION}" +readonly PG_CONFIG="$PREFIX/bin/pg_config" +require_postgresql_installation "$PREFIX" +reset_staging_dir "$STAGING_DIR" + +readonly HYPOPG_TAG="${HYPOPG_TAG:-$(latest_tag "$HYPOPG_REPOSITORY")}" +[[ -n "$HYPOPG_TAG" ]] || die "could not determine the latest HypoPG release" +readonly HYPOPG_DIR="$STAGING_DIR/hypopg-${HYPOPG_TAG#v}" + +printf 'Building HypoPG %s\n' "$HYPOPG_TAG" +download_source "$STAGING_DIR" "$HYPOPG_REPOSITORY" "$HYPOPG_TAG" \ + "hypopg-${HYPOPG_TAG#v}.tar.gz" "$HYPOPG_DIR" +cd "$HYPOPG_DIR" +make -j"${JOBS:-$(nproc)}" USE_PGXS=1 PG_CONFIG="$PG_CONFIG" +make install USE_PGXS=1 PG_CONFIG="$PG_CONFIG" +test -f "$PREFIX/lib/hypopg.so" +test -f "$PREFIX/share/extension/hypopg.control" + +readonly SAVED_SOURCE_DIR="$(copy_install_source "$HYPOPG_DIR" "$PREFIX" "hypopg-$HYPOPG_TAG")" +write_install_recipe "$SAVED_SOURCE_DIR" "$POSTGRES_VERSION" "$PREFIX" <<'RECIPE' +cd "$SCRIPT_DIR" + +# Configure +# HypoPG uses PGXS directly and does not require a separate configure step. + +# Make +make -j"$JOBS" USE_PGXS=1 PG_CONFIG="$PG_CONFIG" + +# Make install +make install USE_PGXS=1 PG_CONFIG="$PG_CONFIG" +RECIPE diff --git a/PostgreSQL/build_rdbms_01/install_pg_hint_plan.sh b/PostgreSQL/build_rdbms_01/install_pg_hint_plan.sh new file mode 100644 index 0000000..d73778a --- /dev/null +++ b/PostgreSQL/build_rdbms_01/install_pg_hint_plan.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash + +set -Eeuo pipefail + +SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" +# shellcheck source=install_common.sh +source "$SCRIPT_DIR/install_common.sh" + +readonly STAGING_DIR="${STAGING_DIR:-$SCRIPT_DIR/tmp}" +readonly POSTGRES_ROOT="${POSTGRES_ROOT:-/app/postgres/rdbms}" +readonly PG_HINT_PLAN_REPOSITORY="${PG_HINT_PLAN_REPOSITORY:-ossc-db/pg_hint_plan}" + +if [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]]; then + show_help "$0" "Build and install pg_hint_plan for an existing PostgreSQL installation." + exit 0 +fi + +POSTGRES_VERSION="$(parse_postgresql_version "$@")" +readonly POSTGRES_VERSION +require_tools curl tar make +readonly PREFIX="${PREFIX:-$POSTGRES_ROOT/$POSTGRES_VERSION}" +readonly PG_CONFIG="$PREFIX/bin/pg_config" +require_postgresql_installation "$PREFIX" +reset_staging_dir "$STAGING_DIR" + +readonly PG_HINT_PLAN_TAG="${PG_HINT_PLAN_TAG:-$(latest_pg_hint_plan_tag "$PG_HINT_PLAN_REPOSITORY" "${POSTGRES_VERSION%%.*}")}" +[[ -n "$PG_HINT_PLAN_TAG" ]] || die "could not determine a pg_hint_plan tag" +readonly PG_HINT_PLAN_DIR="$STAGING_DIR/pg_hint_plan-$PG_HINT_PLAN_TAG" + +printf 'Building pg_hint_plan %s\n' "$PG_HINT_PLAN_TAG" +download_source "$STAGING_DIR" "$PG_HINT_PLAN_REPOSITORY" "$PG_HINT_PLAN_TAG" \ + "pg_hint_plan-$PG_HINT_PLAN_TAG.tar.gz" "$PG_HINT_PLAN_DIR" +cd "$PG_HINT_PLAN_DIR" +make -j"${JOBS:-$(nproc)}" USE_PGXS=1 PG_CONFIG="$PG_CONFIG" +make install USE_PGXS=1 PG_CONFIG="$PG_CONFIG" +test -f "$PREFIX/lib/pg_hint_plan.so" +test -f "$PREFIX/share/extension/pg_hint_plan.control" + +readonly SAVED_SOURCE_DIR="$(copy_install_source "$PG_HINT_PLAN_DIR" "$PREFIX" "pg_hint_plan-$PG_HINT_PLAN_TAG")" +write_install_recipe "$SAVED_SOURCE_DIR" "$POSTGRES_VERSION" "$PREFIX" <<'RECIPE' +cd "$SCRIPT_DIR" + +# Configure +# pg_hint_plan uses PGXS directly and does not require a separate configure step. + +# Make +make -j"$JOBS" USE_PGXS=1 PG_CONFIG="$PG_CONFIG" + +# Make install +make install USE_PGXS=1 PG_CONFIG="$PG_CONFIG" +RECIPE diff --git a/PostgreSQL/build_rdbms_01/install_postgresql_extensions.sh b/PostgreSQL/build_rdbms_01/install_postgresql_extensions.sh index 4411668..5aae6d2 100644 --- a/PostgreSQL/build_rdbms_01/install_postgresql_extensions.sh +++ b/PostgreSQL/build_rdbms_01/install_postgresql_extensions.sh @@ -152,10 +152,13 @@ mkdir -p "$SOURCES_DIR" "$SCRIPT_DIR/install_pgaudit.sh" --version "$POSTGRES_VERSION" "$SCRIPT_DIR/install_set_user.sh" --version "$POSTGRES_VERSION" "$SCRIPT_DIR/install_pg_stat_statements.sh" --version "$POSTGRES_VERSION" +"$SCRIPT_DIR/install_auto_explain.sh" --version "$POSTGRES_VERSION" "$SCRIPT_DIR/install_passwordcheck.sh" --version "$POSTGRES_VERSION" "$SCRIPT_DIR/install_pg_repack.sh" --version "$POSTGRES_VERSION" "$SCRIPT_DIR/install_pg_stat_monitor.sh" --version "$POSTGRES_VERSION" "$SCRIPT_DIR/install_pgvector.sh" --version "$POSTGRES_VERSION" +"$SCRIPT_DIR/install_hypopg.sh" --version "$POSTGRES_VERSION" +"$SCRIPT_DIR/install_pg_hint_plan.sh" --version "$POSTGRES_VERSION" readonly CONFIG_FILE="${CONFIG_FILE:-}" readonly SHARED_PRELOAD_LIBRARIES="pg_cron,timescaledb,pgaudit,pg_stat_statements,pg_stat_monitor,passwordcheck" @@ -207,10 +210,13 @@ printf ' TimescaleDB: %s\n' "$(extension_version timescaledb)" printf ' pgaudit: %s\n' "$(extension_version pgaudit)" printf ' set_user: %s\n' "$(extension_version set_user)" printf ' pg_stat_statements: %s\n' "$(extension_version pg_stat_statements)" +printf ' auto_explain: PostgreSQL %s contrib module\n' "$POSTGRES_VERSION" printf ' passwordcheck: PostgreSQL %s contrib module\n' "$POSTGRES_VERSION" printf ' pg_repack: %s\n' "$(extension_version pg_repack)" printf ' pg_stat_monitor: %s\n' "$(extension_version pg_stat_monitor)" printf ' pgvector: %s\n' "$(extension_version vector)" +printf ' hypopg: %s\n' "$(extension_version hypopg)" +printf ' pg_hint_plan: %s\n' "$(extension_version pg_hint_plan)" printf " shared_preload_libraries = '%s'\n" "$SHARED_PRELOAD_LIBRARIES" rm -f -- "$ENGINE_ARCHIVE" diff --git a/PostgreSQL/build_rdbms_01/resume.sh b/PostgreSQL/build_rdbms_01/resume.sh new file mode 100644 index 0000000..01df251 --- /dev/null +++ b/PostgreSQL/build_rdbms_01/resume.sh @@ -0,0 +1 @@ +copilot --resume=a01ab833-94d2-4484-b588-d28e3c944552 diff --git a/PostgreSQL/build_rdbms_01/wrapper.sh b/PostgreSQL/build_rdbms_01/wrapper.sh new file mode 100644 index 0000000..110a7b0 --- /dev/null +++ b/PostgreSQL/build_rdbms_01/wrapper.sh @@ -0,0 +1,5 @@ +./install_postgresql_extensions.sh \ + --version 17.11 \ + --prefix /app/staging_area/postgres/rdbms/17.11 \ + --options="--with-ssl=openssl,--with-ls4" +