release: v1.2.0 Production GA (single-node)
CI / test (push) Has been cancelled
CI / verify (push) Has been cancelled
Clients CI / build-server (push) Has been cancelled
Clients CI / test-python (push) Has been cancelled
Clients CI / test-javascript (push) Has been cancelled
Clients CI / test-nim (push) Has been cancelled
Clients CI / test-rust (push) Has been cancelled
CI / test (push) Has been cancelled
CI / verify (push) Has been cancelled
Clients CI / build-server (push) Has been cancelled
Clients CI / test-python (push) Has been cancelled
Clients CI / test-javascript (push) Has been cancelled
Clients CI / test-nim (push) Has been cancelled
Clients CI / test-rust (push) Has been cancelled
- known-limitations, deployment runbook, release checklist - prod compose requires JWT secret; BARADB_ENV=production fail-closed - scripts/backup-restore-drill.sh (backup → wipe → restore → verify) - version bump 1.2.0 (nimble, Dockerfile, health, CHANGELOG dated)
This commit is contained in:
Executable
+135
@@ -0,0 +1,135 @@
|
||||
#!/usr/bin/env bash
|
||||
# Backup → wipe → restore → verify drill for BaraDB single-node GA.
|
||||
# Usage: ./scripts/backup-restore-drill.sh
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
cd "$ROOT"
|
||||
|
||||
BIN="${BARADB_BIN:-./build/baradadb}"
|
||||
BACKUP_BIN="${BARADB_BACKUP_BIN:-./build/backup}"
|
||||
PORT="${DRILL_PORT:-19472}"
|
||||
HTTP_PORT=$((PORT + 440))
|
||||
WORKDIR="${DRILL_WORKDIR:-/tmp/baradb_backup_drill_$$}"
|
||||
DATA_DIR="$WORKDIR/data"
|
||||
ARCHIVE="$WORKDIR/drill_backup.tar.gz"
|
||||
MARKER="drill-row-$$"
|
||||
|
||||
die() { echo "FAIL: $*" >&2; cleanup; exit 1; }
|
||||
log() { echo "[drill] $*"; }
|
||||
|
||||
cleanup() {
|
||||
if [[ -n "${SERVER_PID:-}" ]] && kill -0 "$SERVER_PID" 2>/dev/null; then
|
||||
kill "$SERVER_PID" 2>/dev/null || true
|
||||
wait "$SERVER_PID" 2>/dev/null || true
|
||||
fi
|
||||
if [[ "${DRILL_KEEP:-1}" == "0" ]]; then
|
||||
rm -rf "$WORKDIR"
|
||||
fi
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
[[ -x "$BIN" ]] || die "missing $BIN — build: nim c -o:build/baradadb src/baradadb.nim"
|
||||
if [[ ! -x "$BACKUP_BIN" ]]; then
|
||||
log "building backup tool..."
|
||||
nim c -d:release -o:build/backup src/barabadb/core/backup.nim || die "cannot build backup tool"
|
||||
BACKUP_BIN=./build/backup
|
||||
fi
|
||||
|
||||
rm -rf "$WORKDIR"
|
||||
mkdir -p "$DATA_DIR"
|
||||
|
||||
start_server() {
|
||||
log "starting server port=$PORT data=$DATA_DIR"
|
||||
# every = fsync each WAL write so kill/backup cannot lose recent puts
|
||||
BARADB_PORT="$PORT" \
|
||||
BARADB_ADDRESS=127.0.0.1 \
|
||||
BARADB_DATA_DIR="$DATA_DIR" \
|
||||
BARADB_LOG_LEVEL=warn \
|
||||
BARADB_AUTH_ENABLED=false \
|
||||
BARADB_WAL_SYNC_MODE=every \
|
||||
"$BIN" >"$WORKDIR/server.log" 2>&1 &
|
||||
SERVER_PID=$!
|
||||
local i=0
|
||||
while (( i < 80 )); do
|
||||
if curl -sf "http://127.0.0.1:${HTTP_PORT}/health" >/dev/null 2>&1; then
|
||||
log "server ready pid=$SERVER_PID"
|
||||
return 0
|
||||
fi
|
||||
sleep 0.15
|
||||
i=$((i + 1))
|
||||
done
|
||||
tail -50 "$WORKDIR/server.log" >&2 || true
|
||||
die "server not healthy on :$HTTP_PORT"
|
||||
}
|
||||
|
||||
stop_server() {
|
||||
if [[ -n "${SERVER_PID:-}" ]] && kill -0 "$SERVER_PID" 2>/dev/null; then
|
||||
log "stopping pid=$SERVER_PID"
|
||||
kill -TERM "$SERVER_PID" 2>/dev/null || true
|
||||
local i=0
|
||||
while kill -0 "$SERVER_PID" 2>/dev/null && (( i < 50 )); do
|
||||
sleep 0.1
|
||||
i=$((i + 1))
|
||||
done
|
||||
if kill -0 "$SERVER_PID" 2>/dev/null; then
|
||||
kill -KILL "$SERVER_PID" 2>/dev/null || true
|
||||
fi
|
||||
wait "$SERVER_PID" 2>/dev/null || true
|
||||
fi
|
||||
SERVER_PID=""
|
||||
sleep 0.3
|
||||
}
|
||||
|
||||
http_query() {
|
||||
local sql="$1"
|
||||
local payload
|
||||
payload=$(python3 -c "import json,sys; print(json.dumps({'query': sys.argv[1]}))" "$sql")
|
||||
curl -sf -H 'Content-Type: application/json' -d "$payload" \
|
||||
"http://127.0.0.1:${HTTP_PORT}/query"
|
||||
}
|
||||
|
||||
start_server
|
||||
|
||||
log "CREATE + INSERT marker"
|
||||
http_query "CREATE TABLE drill_t (id INT PRIMARY KEY, name STRING)" >/dev/null || die "CREATE failed"
|
||||
http_query "INSERT INTO drill_t (id, name) VALUES (1, '$MARKER')" >/dev/null || die "INSERT failed"
|
||||
body=$(http_query "SELECT name FROM drill_t WHERE id = 1") || die "SELECT before backup failed"
|
||||
echo "$body" | grep -q "$MARKER" || die "marker missing before backup: $body"
|
||||
# allow WAL group/fsync to settle
|
||||
sleep 0.5
|
||||
|
||||
stop_server
|
||||
|
||||
# Prefer multi-db layout used by the server registry
|
||||
DB_ROOT="$DATA_DIR/databases"
|
||||
[[ -d "$DB_ROOT" ]] || die "expected $DB_ROOT after server run"
|
||||
|
||||
log "backup from $DB_ROOT"
|
||||
"$BACKUP_BIN" backup --all-databases --data-root="$DB_ROOT" \
|
||||
--output="$ARCHIVE" --force || die "backup failed"
|
||||
# Sanity: archive must not be tiny empty shell only
|
||||
asize=$(stat -c%s "$ARCHIVE" 2>/dev/null || stat -f%z "$ARCHIVE")
|
||||
(( asize > 200 )) || die "backup archive suspiciously small ($asize bytes)"
|
||||
|
||||
log "wipe data"
|
||||
rm -rf "$DATA_DIR"
|
||||
mkdir -p "$DATA_DIR"
|
||||
|
||||
log "restore multi-db archive into $DB_ROOT"
|
||||
mkdir -p "$DATA_DIR"
|
||||
# Archive layout is databases/<name>/... ; --data-root is the databases/ parent leaf
|
||||
"$BACKUP_BIN" restore --input="$ARCHIVE" --all-databases \
|
||||
--data-root="$DB_ROOT" --force || die "restore failed"
|
||||
|
||||
start_server
|
||||
|
||||
log "verify after restore"
|
||||
body=$(http_query "SELECT name FROM drill_t WHERE id = 1") || die "SELECT after restore failed"
|
||||
echo "$body" | grep -q "$MARKER" || die "marker missing after restore: $body"
|
||||
|
||||
log "PASS backup/restore drill OK marker=$MARKER archive=$ARCHIVE"
|
||||
stop_server
|
||||
trap - EXIT
|
||||
[[ "${DRILL_KEEP:-1}" == "0" ]] && rm -rf "$WORKDIR"
|
||||
exit 0
|
||||
Reference in New Issue
Block a user