From 45a80e16bee45706df120708947e61ffb1aa3857 Mon Sep 17 00:00:00 2001 From: Raja Kolli Date: Sun, 31 Aug 2025 16:08:18 +0000 Subject: [PATCH 1/5] chore : switch to official postgres --- .../jpa-boot-read-replica-postgresql.yml | 2 +- .vscode/launch.json | 10 ++++ .../docker-compose.yaml | 46 ----------------- .../docker/configure-master.sh | 25 ++++++++++ .../docker/docker-compose.yml | 48 ++++++++++++++++++ .../docker/init-master.sql | 18 +++++++ .../docker/setup-slave.sh | 49 +++++++++++++++++++ .../readreplica/ReadReplicaApplication.java | 4 ++ .../src/main/resources/application.yml | 7 ++- 9 files changed, 160 insertions(+), 49 deletions(-) delete mode 100644 jpa/boot-read-replica-postgresql/docker-compose.yaml create mode 100644 jpa/boot-read-replica-postgresql/docker/configure-master.sh create mode 100644 jpa/boot-read-replica-postgresql/docker/docker-compose.yml create mode 100644 jpa/boot-read-replica-postgresql/docker/init-master.sql create mode 100755 jpa/boot-read-replica-postgresql/docker/setup-slave.sh diff --git a/.github/workflows/jpa-boot-read-replica-postgresql.yml b/.github/workflows/jpa-boot-read-replica-postgresql.yml index 6f57533ed..d8af25506 100644 --- a/.github/workflows/jpa-boot-read-replica-postgresql.yml +++ b/.github/workflows/jpa-boot-read-replica-postgresql.yml @@ -33,7 +33,7 @@ jobs: cache: "maven" - name: Start up databases via docker compose run: | - docker compose up -d postgresql-master postgresql-slave + docker compose -f docker/docker-compose.yml up -d postgresql-master postgresql-slave sleep 5 docker ps -a - name: Build and analyze diff --git a/.vscode/launch.json b/.vscode/launch.json index fd5cad552..516c647fd 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -292,6 +292,16 @@ "projectName": "boot-scheduler-quartz", "args": "--spring.profiles.active=local", "envFile": "${workspaceFolder}/.env" + }, + { + "type": "java", + "name": "Spring Boot-ReadReplicaApplication", + "request": "launch", + "cwd": "${workspaceFolder}", + "mainClass": "com.example.demo.readreplica.ReadReplicaApplication", + "projectName": "boot-read-replica-postgresql", + "args": "", + "envFile": "${workspaceFolder}/.env" } ] } diff --git a/jpa/boot-read-replica-postgresql/docker-compose.yaml b/jpa/boot-read-replica-postgresql/docker-compose.yaml deleted file mode 100644 index 3e7644958..000000000 --- a/jpa/boot-read-replica-postgresql/docker-compose.yaml +++ /dev/null @@ -1,46 +0,0 @@ -services: - postgresql-master: - image: 'bitnami/postgresql:latest' - ports: - - '5432:5432' - volumes: - - 'postgresql_master_data:/bitnami/postgresql' - environment: - - POSTGRESQL_PGAUDIT_LOG=READ,WRITE - - POSTGRESQL_LOG_HOSTNAME=TRUE - - POSTGRESQL_REPLICATION_MODE=master - - POSTGRESQL_REPLICATION_USER=repl_user - - POSTGRESQL_REPLICATION_PASSWORD=repl_password - - POSTGRESQL_USERNAME=postgres_write - - POSTGRESQL_PASSWORD=postgres_write - - POSTGRESQL_DATABASE=my_database - postgresql-slave: - image: 'bitnami/postgresql:latest' - ports: - - '15432:5432' - depends_on: - - postgresql-master - environment: - - POSTGRESQL_REPLICATION_MODE=slave - - POSTGRESQL_REPLICATION_USER=repl_user - - POSTGRESQL_REPLICATION_PASSWORD=repl_password - - POSTGRESQL_MASTER_HOST=postgresql-master - - POSTGRESQL_USERNAME=postgres_write - - POSTGRESQL_PASSWORD=postgres_write - - POSTGRESQL_MASTER_PORT_NUMBER=5432 - - POSTGRESQL_PGAUDIT_LOG=READ,WRITE - - POSTGRESQL_LOG_HOSTNAME=TRUE - - pgadmin4: - image: dpage/pgadmin4 - ports: - - "5050:80" - depends_on: - - postgresql-master - environment: - - PGADMIN_DEFAULT_EMAIL=pgadmin4@pgadmin.org - - PGADMIN_DEFAULT_PASSWORD=admin - -volumes: - postgresql_master_data: - driver: local \ No newline at end of file diff --git a/jpa/boot-read-replica-postgresql/docker/configure-master.sh b/jpa/boot-read-replica-postgresql/docker/configure-master.sh new file mode 100644 index 000000000..432ba6209 --- /dev/null +++ b/jpa/boot-read-replica-postgresql/docker/configure-master.sh @@ -0,0 +1,25 @@ +#!/bin/bash +set -e + +echo "Configuring PostgreSQL master for replication..." + +# Update postgresql.conf for replication +cat >> "$PGDATA/postgresql.conf" <> "$PGDATA/pg_hba.conf" < /dev/null 2>&1 +do + echo "Waiting for master database..." + sleep 3 +done + +echo "Master is ready. Checking if slave data exists..." + +if [ "$(ls -A $PGDATA 2>/dev/null)" ]; then + echo "Data directory exists, starting PostgreSQL..." + # Change ownership and start as postgres user + chown -R postgres:postgres "$PGDATA" + exec gosu postgres postgres -c hot_standby=on -c hot_standby_feedback=on +else + echo "Data directory is empty, creating base backup..." + + # Create base backup from master + PGPASSWORD="$REPLICATION_PASSWORD" pg_basebackup \ + -h "$POSTGRES_MASTER_HOST" \ + -p "$POSTGRES_MASTER_PORT" \ + -U "$REPLICATION_USER" \ + -D "$PGDATA" \ + -W \ + -v \ + -R \ + -X stream + + # Set proper permissions + chmod 700 "$PGDATA" + chown -R postgres:postgres "$PGDATA" + + # Add standby configuration + cat >> "$PGDATA/postgresql.conf" < Date: Sun, 31 Aug 2025 16:27:50 +0000 Subject: [PATCH 2/5] add health checks --- .../docker/docker-compose.yml | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/jpa/boot-read-replica-postgresql/docker/docker-compose.yml b/jpa/boot-read-replica-postgresql/docker/docker-compose.yml index 0a0ae615d..724dead54 100644 --- a/jpa/boot-read-replica-postgresql/docker/docker-compose.yml +++ b/jpa/boot-read-replica-postgresql/docker/docker-compose.yml @@ -6,23 +6,30 @@ services: - '5432:5432' volumes: - 'postgresql_master_data:/var/lib/postgresql/data' - - './init-master.sql:/docker-entrypoint-initdb.d/01-init-master.sql' - - './configure-master.sh:/docker-entrypoint-initdb.d/02-configure-master.sh' + - './init-master.sql:/docker-entrypoint-initdb.d/01-init-master.sql:ro' + - './configure-master.sh:/docker-entrypoint-initdb.d/02-configure-master.sh:ro' environment: - POSTGRES_USER=postgres_write - POSTGRES_PASSWORD=postgres_write - POSTGRES_DB=my_database + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres_write -d my_database -h 127.0.0.1 -p 5432"] + interval: 5s + timeout: 3s + retries: 20 + start_period: 10s postgresql-slave: image: 'postgres:17' ports: - '15432:5432' depends_on: - - postgresql-master + postgresql-master: + condition: service_healthy volumes: - 'postgresql_slave_data:/var/lib/postgresql/data' - - './setup-slave.sh:/setup-slave.sh' + - './setup-slave.sh:/setup-slave.sh:ro' environment: - - POSTGRES_USER=postgres_write + - POSTGRES_USER=postgres_write - POSTGRES_PASSWORD=postgres_write - PGUSER=postgres_write - POSTGRES_MASTER_HOST=postgresql-master @@ -30,6 +37,12 @@ services: - REPLICATION_USER=repl_user - REPLICATION_PASSWORD=repl_password entrypoint: ["/setup-slave.sh"] + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres_write -h 127.0.0.1 -p 5432"] + interval: 5s + timeout: 3s + retries: 20 + start_period: 15s pgadmin4: image: dpage/pgadmin4 From 6edf8c4dd38fcf3a57d7ab9c6ff1e474f99cd26f Mon Sep 17 00:00:00 2001 From: Raja Kolli Date: Sun, 31 Aug 2025 16:41:38 +0000 Subject: [PATCH 3/5] adds health check --- jpa/boot-read-replica-postgresql/docker/docker-compose.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/jpa/boot-read-replica-postgresql/docker/docker-compose.yml b/jpa/boot-read-replica-postgresql/docker/docker-compose.yml index 724dead54..999fcef2d 100644 --- a/jpa/boot-read-replica-postgresql/docker/docker-compose.yml +++ b/jpa/boot-read-replica-postgresql/docker/docker-compose.yml @@ -49,7 +49,8 @@ services: ports: - "5050:80" depends_on: - - postgresql-master + postgresql-master: + condition: service_healthy environment: - PGADMIN_DEFAULT_EMAIL=pgadmin4@pgadmin.org - PGADMIN_DEFAULT_PASSWORD=admin @@ -58,4 +59,4 @@ volumes: postgresql_master_data: driver: local postgresql_slave_data: - driver: local \ No newline at end of file + driver: local From 3c1d1615f9c0a9180d846ec2cba8599d1e350377 Mon Sep 17 00:00:00 2001 From: Raja Kolli Date: Sun, 31 Aug 2025 16:48:40 +0000 Subject: [PATCH 4/5] fix db options --- .../com/example/demo/readreplica/ReadReplicaApplication.java | 1 - .../src/main/resources/application.yml | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/ReadReplicaApplication.java b/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/ReadReplicaApplication.java index 675b7a3a3..7fbbb1909 100644 --- a/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/ReadReplicaApplication.java +++ b/jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/ReadReplicaApplication.java @@ -10,7 +10,6 @@ public class ReadReplicaApplication { public static void main(String[] args) { // Set default timezone to UTC to avoid timezone conflicts TimeZone.setDefault(TimeZone.getTimeZone("UTC")); - System.setProperty("user.timezone", "UTC"); SpringApplication.run(ReadReplicaApplication.class, args); } } diff --git a/jpa/boot-read-replica-postgresql/src/main/resources/application.yml b/jpa/boot-read-replica-postgresql/src/main/resources/application.yml index 236bcf14a..0a2d8f0b9 100644 --- a/jpa/boot-read-replica-postgresql/src/main/resources/application.yml +++ b/jpa/boot-read-replica-postgresql/src/main/resources/application.yml @@ -5,7 +5,7 @@ spring: password: postgres_write username: postgres_write driverClassName: org.postgresql.Driver - url: jdbc:postgresql://localhost:5432/my_database?TimeZone=UTC&serverTimezone=UTC + url: jdbc:postgresql://localhost:5432/my_database?options=-c%20timezone=UTC hikari: auto-commit: false pool-name: primaryHikariPool @@ -17,7 +17,7 @@ spring: password: repl_password username: repl_user driverClassName: org.postgresql.Driver - url: jdbc:postgresql://localhost:15432/my_database?TimeZone=UTC&serverTimezone=UTC + url: jdbc:postgresql://localhost:15432/my_database?options=-c%20timezone=UTC hikari: auto-commit: false poolName: replicaHikariPool From 327b79c892751b558bce01d0a2a8a78b540306d0 Mon Sep 17 00:00:00 2001 From: Raja Kolli Date: Sun, 31 Aug 2025 16:51:07 +0000 Subject: [PATCH 5/5] solves bash --- jpa/boot-read-replica-postgresql/docker/configure-master.sh | 2 +- jpa/boot-read-replica-postgresql/docker/setup-slave.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jpa/boot-read-replica-postgresql/docker/configure-master.sh b/jpa/boot-read-replica-postgresql/docker/configure-master.sh index 432ba6209..ac563c18e 100644 --- a/jpa/boot-read-replica-postgresql/docker/configure-master.sh +++ b/jpa/boot-read-replica-postgresql/docker/configure-master.sh @@ -1,5 +1,5 @@ #!/bin/bash -set -e +set -euo pipefail echo "Configuring PostgreSQL master for replication..." diff --git a/jpa/boot-read-replica-postgresql/docker/setup-slave.sh b/jpa/boot-read-replica-postgresql/docker/setup-slave.sh index a66b1e354..f67e8be0a 100755 --- a/jpa/boot-read-replica-postgresql/docker/setup-slave.sh +++ b/jpa/boot-read-replica-postgresql/docker/setup-slave.sh @@ -1,5 +1,5 @@ #!/bin/bash -set -e +set -Eeuo pipefail export PGDATA=/var/lib/postgresql/data