Skip to main content

openedge-replication

Implements three-tier replication architecture (DRBD+AI, ZFS+AI, AI-only rsync) for Progress OpenEdge 12.x databases without OER license.

Zur Installation springen

Quellinformationen

Repository
paulpas/agent-skill-router
Letzte Quellaktivität
14. Juni 2026 um 14:35
Erkannte Sprache von SKILL.md
Englisch
Sterne
6
Forks
0

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
openedge-replication
description
Implements three-tier replication architecture (DRBD+AI, ZFS+AI, AI-only rsync) for Progress OpenEdge 12.x databases without OER license.
license
MIT
compatibility
opencode
metadata
{"version":"1.0.0","domain":"linux","role":"reference","scope":"infrastructure","output-format":"manifests","content-types":["guidance","config","examples","diagrams"],"triggers":"openedge replication, DRBD, ZFS snapshot, AI shipping, failover runbook, rfutil roll-forward, keepalived VIP","archetypes":["tactical","strategic"],"anti_triggers":["brainstorming","vague ideation"],"response_profile":{"verbosity":"medium","directive_strength":"high","abstraction_level":"tactical"},"related-skills":"linux-services, storage-architecture, shell-process-management","maturity":"stable","completeness":95,"exampleCount":5}
# OpenEdge Replication System (Homemade DR) Configures and operates a three-tier database replication architecture for Progress OpenEdge 12.x databases without the OER license — using After-Image shipping, DRBD block replication, ZFS snapshots, keepalived VIP failover, and rfutil roll-forward for sub-second to five-minute RPO/RTO targets. ## TL;DR Checklist - [ ] Select tier based on infrastructure (DRBD+AI for <2s RPO, ZFS+AI for geo-distributed, AI-only rsync as simplest fallback) - [ ] Enable After-Imaging on source with `proutil -C aimage begin` and configure archiver directory - [ ] Deploy AI ship daemon (inotifywait + rsync) on source and AI apply daemon (rfutil roll-forward) on target - [ ] Configure split-brain prevention: lock files, quorum checks, DRBD fence-peer scripts - [ ] Set up keepalived VIP for transparent client failover with health check script - [ ] Validate replication lag stays within RPO thresholds using the health monitor - [ ] Test failover procedure end-to-end before relying on it in production --- ## When to Use Use this skill when: - **Deploying OpenEdge HA without OER** — You need database high availability for Progress OpenEdge 12.x but do not have (or cannot purchase) the OER licensed product - **Designing tiered DR strategy** — You must choose between block-level replication, snapshot-based replication, or AI-only shipping based on RPO/RTO requirements and infrastructure - **Configuring After-Image shipping** — You need to set up continuous transaction-level replication using OpenEdge's built-in AI logging (`proutil -C aimage`) and `rfutil roll-forward` - **Implementing VIP failover** — You want clients to connect to a floating IP that automatically moves between primary and standby on failure (keepalived + VRRP) - **Running a planned or emergency failover** — You need the step-by-step procedures from the runbook for graceful migration or source-server loss scenarios - **Setting up read-only standby** — You want to offload report/BI queries to a standby OpenEdge instance running in `-RO` mode --- ## When NOT to Use Avoid this skill for: - **New database deployments without replication needs** — If you do not need high availability, a single primary with regular backups is simpler - **Sub-millisecond RPO requirements** — This homemade solution cannot match dedicated OER or native clustering products for ultra-low latency failover; use OER instead - **Non-Linux platforms** — DRBD and the provided scripts require Linux kernel modules and systemd; Tier 3 (AI-only) works on any OS but loses BI protection - **Replacing a fully functional OER setup** — If you already have OER replication running, do not migrate to this system without thorough testing - **Database versions before 10.2B** — OPLOCK-based roll-forward requires OpenEdge 10.2B or later; earlier versions need manual `rfutil` apply --- ## Core Workflow ### 1. Assess Requirements and Select Tier Determine which replication tier matches your RPO, RTO, infrastructure, and budget constraints. | Tier | Mechanism | RPO | RTO | BI Protected | Complexity | |------|-----------|-----|-----|-------------|------------| | **Tier 1** | DRBD async + AI shipping | < 2s | < 30s | Yes (DRBD replicates .bi) | Medium | | **Tier 2** | ZFS snapshot + AI shipping | < 5min | < 2min | Yes (in snapshot) | Medium-High | | **Tier 3** | AI-only rsync | 1-5min | < 2min | No | Low | **Checkpoint:** Confirm your RPO and RTO targets, verify available infrastructure (DRBD kernel module, ZFS pool, or neither), and decide if BI protection is required. Tier 3 has no BI protection — uncommitted transactions at crash time are lost. ### 2. Enable After-Imaging on Source Database After-Imaging records committed transaction changes that can be replayed on the target via `rfutil roll-forward`. ```bash # Connect to the source database broker proenv # Enable AI logging (online, no restart required) proutil mydb -C aimage begin # Verify AI is enabled and archiver is running proutil mydb -C aimage list # Expected: After Image Enabled: Yes, Archive Destination: /data/ai-archive, Archive Status: Active # Configure AI archiver directory (copies completed extents for shipping) proutil mydb -C aiarchive enable -aiarcdir /data/ai-archive ``` **Checkpoint:** Verify `Archive Status: Active` in the output. The archiver copies completed AI extents to `/data/ai-archive/`, which is the source for rsync transport. ### 3. Configure Tier-Specific Block/Snapshot Replication #### Tier 1: DRBD Configuration (`/etc/drbd.d/mydb.res`) ``` resource mydb { protocol C; on primary-server { device /dev/drbd1; disk /dev/sda3; address 10.0.0.1:7788; meta-disk internal; } on standby-server { device /dev/drbd1; disk /dev/sda3; address 10.0.0.2:7788; meta-disk internal; } syncer { rate 100M; al-extents 3833; verify-alg sha1; } disk { on-io-error detach; fencing resource-only; } net { cram-hmac-alg sha256; shared-secret "your-secret-here"; after-sb-0p disconnect; after-sb-1p disconnect; after-sb-2p disconnect; } fence-peer { program "/usr/lib/drbd/crm-fence-peer.sh"; } } ``` Initialize: ```bash drbdadm create-md mydb drbdadm -- --overwrite-data-of-primary primary mydb drbdadm secondary mydb # On standby cat /proc/drbd # Verify sync progress ``` **Checkpoint:** DRBD must show `Connected` state and syncing must reach 100% before going live. The `after-sb-2p disconnect` policy prevents split-brain by dropping the connection if both sides are primary. #### Tier 2: ZFS Snapshot Replication ```bash # Source pool setup zpool create -f mirror /dev/sda /dev/sdb -o ashift=12 dbdata zfs set compression=lz4 dbdata zfs set atime=off dbdata zfs set sync=always dbdata/db # Durability for database zfs set checksum=sha256 dbdata/db zfs create dbdata/db zfs create dbdata/ai-archive # Initial full replication zfs send -v dbdata/db | ssh target zfs receive -F dbdata/db # Incremental (run via cron every 5 min) zfs send -v -i dbdata/db@repl-202601011200 dbdata/db@repl-202601011205 \ | ssh target zfs receive -F dbdata/db ``` **Checkpoint:** Verify incremental send completes successfully and ZFS pool has sufficient space for snapshot retention. Use `zfs list -t snapshot -r dbdata/db` to review snapshot history. ### 4. Deploy AI Ship and AI Apply Daemons The AI shipping layer provides transaction-level replication independent of block/snapshot replication, catching transactions between DRBD sync or ZFS snapshot intervals. **Source — AI Ship Daemon** (`/opt/repl/bin/ai-ship-daemon.sh`): ```bash #!/usr/bin/env bash set -euo pipefail SOURCE_DIR="/data/ai-archive" TARGET_HOST="target-server" TARGET_DIR="/data/ai-received" DB_NAME="mydb" LOG_FILE="/var/log/repl/ai-ship.log" PID_FILE="/var/run/repl/ai-ship.pid" running() { kill -0 "$1" 2>/dev/null; } start_daemon() { if [ -f "$PID_FILE" ] && running "$(cat "$PID_FILE")"; then echo "Already running (PID $(cat "$PID_FILE"))" >&2 return 1 fi mkdir -p "$(dirname "$LOG_FILE")" ( while true; do inotifywait -e close_write,moved_to "$SOURCE_DIR" 2>/dev/null || continue sleep 2 latest_ai=$(ls -t "$SOURCE_DIR"/${DB_NAME}.ai* 2>/dev/null | head -1) if [ -n "$latest_ai" ]; then rsync --checksum --compress --timeout=60 "$latest_ai" "$TARGET_HOST:$TARGET_DIR/" \ >> "$LOG_FILE" 2>&1 fi done ) & echo $! > "$PID_FILE" } stop_daemon() { [ -f "$PID_FILE" ] && kill "$(cat "$PID_FILE")" 2>/dev/null || true rm -f "$PID_FILE" } case "${1:-}" in start) start_daemon ;; stop) stop_daemon ;; status) [ -f "$PID_FILE" ] && running "$(cat "$PID_FILE")" && echo "Running" || echo "Stopped" ;; *) echo "Usage: $0 {start|stop|status}"; exit 1 ;; esac ``` **Target — AI Apply Daemon** (`/opt/repl/bin/ai-apply-daemon.sh`): ```sh #!/usr/bin/env bash set -euo pipefail DB_NAME="mydb" RECEIVE_DIR="/data/ai-received" APPLY_DIR="/data/ai-pending" LOG_FILE="/var/log/repl/ai-apply.log" PID_FILE="/var/run/repl/ai-apply.pid" LOCK_FILE="/var/run/repl/ai-apply.lock" APPLY_INTERVAL=60 acquire_lock() { [ -f "$LOCK_FILE" ] && return 1 echo $$ > "$LOCK_FILE" } release_lock() { rm -f "$LOCK_FILE"; } apply_ai() { local pending pending=$(ls -1 "$RECEIVE_DIR"/${DB_NAME}.ai* 2>/dev/null | wc -l) [ "$pending" -eq 0 ] && return 0 ls -1 "$RECEIVE_DIR"/${DB_NAME}.ai* | sort > /tmp/ai-apply-list.txt rfutil "$DB_NAME" -C roll forward oplock -ailist /tmp/ai-apply-list.txt >> "$LOG_FILE" 2>&1 || true rm -f /tmp/ai-apply-list.txt proutil "$DB_NAME" -C aimage begin 2>/dev/null || true for f in "$RECEIVE_DIR"/${DB_NAME}.ai*; do [ -f "$f" ] && mv "$f" "$APPLY_DIR/.applied/" 2>/dev/null || true done } start_daemon() { mkdir -p "$APPLY_DIR/.applied" "$(dirname "$LOG_FILE")" ( while true; do if acquire_lock; then apply_ai; release_lock; fi sleep "$APPLY_INTERVAL" done ) & echo $! > "$PID_FILE" } stop_daemon() { [ -f "$PID_FILE" ] && kill "$(cat "$PID_FILE")" 2>/dev/null || true rm -f "$PID_FILE"; release_lock } case "${1:-}" in start) start_daemon ;; stop) stop_daemon ;; status) [ -f "$PID_FILE" ] && kill -0 "$(cat "$PID_FILE")" 2>/dev/null && echo "Running" || echo "Stopped" ;; *) echo "Usage: $0 {start|stop|status}"; exit 1 ;; esac ``` **Checkpoint:** Both daemons must show `Running` status. Verify AI files appear in `$TARGET_DIR/ai-received/` and get applied to `$APPLY_DIR/.applied/`. ### 5. Configure Keepalived VIP (Tier 1 + Optional for All Tiers) The Virtual IP floats between servers, allowing clients to connect without reconnection code on failover. **Keepalived config** (`/etc/keepalived/keepalived.conf`): ``` global_defs { router_id mydb-repl } vrrp_script chk_proserve { script "/opt/repl/bin/check-proserve.sh" interval 5 timeout 3 fall 2 rise 1 } vrrp_instance mydb_vip { state BACKUP interface eth0 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass mydbsecret } virtual_ipaddress { 192.168.1.100/24 dev eth0 } track_script { chk_proserve } notify /etc/keepalived/notify.sh } ``` **Health check script** (`/opt/repl/bin/check-proserve.sh`): ```bash #!/usr/bin/env bash DB_NAME="${DB_NAME:-mydb}" if proshut "$DB_NAME" -C status 2>/dev/null | grep -q "Multi-User"; then exit 0 else exit 1 fi ``` **Standby startup command:** ```bash # Primary (read-write) proserve mydb -H primary-server -S 3001 # Standby (read-only, for offloading SELECT queries) proserve mydb -RO -H standby-server -S 3001 ``` **Checkpoint:** `ip addr show eth0 | grep 192.168.1.100` must show the VIP on the primary. Stopping the primary should cause the VIP to migrate to standby within ~5 seconds (3 failed checks at 5s interval + fall count). ### 6. Configure systemd Services ```ini # /etc/systemd/system/ai-ship.service [Unit] Description=AI Ship Daemon for OpenEdge Database Replication After=network.target remote-fs.target [Service] Type=forking ExecStart=/opt/repl/bin/ai-ship-daemon.sh start ExecStop=/opt/repl/bin/ai-ship-daemon.sh stop PIDFile=/var/run/repl/ai-ship.pid Restart=on-failure RestartSec=10 [Install] WantedBy=multi-user.target # /etc/systemd/system/ai-apply.service [Unit] Description=AI Apply Daemon for OpenEdge Database Replication After=network.target remote-fs.target [Service] Type=forking ExecStart=/opt/repl/bin/ai-apply-daemon.sh start ExecStop=/opt/repl/bin/ai-apply-daemon.sh stop PIDFile=/var/run/repl/ai-apply.pid Restart=on-failure RestartSec=10 [Install] WantedBy=multi-user.target # /etc/systemd/system/keepalived.service [Unit] Description=Keepalived VRRP for OpenEdge VIP Failover After=network.target [Service] Type=forking ExecStart=/usr/sbin/keepalived --vrrp --dump-conf /tmp/keepalived.conf ExecStop=/usr/sbin/keepalived -k PIDFile=/var/run/keepalived.pid [Install] WantedBy=multi-user.target ``` Enable and start: ```bash systemctl daemon-reload systemctl enable --now ai-ship.service ai-apply.service keepalived.service ```
Auf GitHub ansehen
Diese SKILL.md ist sehr gross, daher zeigt SkillsMP hier nur den ersten Abschnitt. Auf GitHub ansehen