deploy/assets/postgres/db-init/init-redis-fdw.sh

213 lines
5.9 KiB
Bash
Executable File

#!/bin/bash
set -e
# Function to log errors
log_error() {
echo "ERROR: $1" >&2
}
log_info() {
echo "INFO: $1"
}
# Trap errors and log them
trap 'log_error "Script failed at line $LINENO"' ERR
log_info "Starting Redis FDW initialization..."
log_info "Redis connection details:"
log_info " Host: ${REDIS_HOST:-redis}"
log_info " Port: 6379"
log_info " Password: $(if [ -n "$REDIS_PASSWORD" ]; then echo "[SET]"; else echo "[NOT SET]"; fi)"
# Wait for Redis to be ready
log_info "Waiting for Redis to be ready..."
REDIS_READY=false
MAX_ATTEMPTS=30
ATTEMPT=0
while [ $ATTEMPT -lt $MAX_ATTEMPTS ]; do
if redis-cli -h ${REDIS_HOST:-redis} -a "${REDIS_PASSWORD}" ping 2>/dev/null | grep -q PONG; then
REDIS_READY=true
log_info "Redis is ready after $ATTEMPT attempts"
break
fi
ATTEMPT=$((ATTEMPT + 1))
log_info "Redis is unavailable - attempt $ATTEMPT/$MAX_ATTEMPTS"
sleep 2
done
if [ "$REDIS_READY" = false ]; then
log_error "Redis failed to become ready after $MAX_ATTEMPTS attempts"
log_error "Check if Redis container is running and accessible at ${REDIS_HOST:-redis}:6379"
exit 1
fi
# Get Redis info
log_info "Fetching Redis server information..."
REDIS_VERSION=$(redis-cli -h ${REDIS_HOST:-redis} -a "${REDIS_PASSWORD}" INFO server 2>/dev/null | grep "redis_version" | cut -d: -f2 | tr -d '\r' || echo "unknown")
REDIS_MODE=$(redis-cli -h ${REDIS_HOST:-redis} -a "${REDIS_PASSWORD}" INFO server 2>/dev/null | grep "redis_mode" | cut -d: -f2 | tr -d '\r' || echo "unknown")
REDIS_UPTIME=$(redis-cli -h ${REDIS_HOST:-redis} -a "${REDIS_PASSWORD}" INFO server 2>/dev/null | grep "uptime_in_seconds" | cut -d: -f2 | tr -d '\r' || echo "unknown")
TOTAL_KEYS=$(redis-cli -h ${REDIS_HOST:-redis} -a "${REDIS_PASSWORD}" DBSIZE 2>/dev/null | awk '{print $2}' || echo "0")
log_info "Redis server info:"
log_info " Version: $REDIS_VERSION"
log_info " Mode: $REDIS_MODE"
log_info " Uptime: $REDIS_UPTIME seconds"
log_info " Total keys in DB 0: $TOTAL_KEYS"
# Test Redis connectivity with a test key
log_info "Testing Redis write/read operations..."
if redis-cli -h ${REDIS_HOST:-redis} -a "${REDIS_PASSWORD}" SET fdw_test_key "fdw_init_$(date +%s)" EX 60 >/dev/null 2>&1; then
TEST_VALUE=$(redis-cli -h ${REDIS_HOST:-redis} -a "${REDIS_PASSWORD}" GET fdw_test_key 2>/dev/null)
log_info "Redis write/read test successful (value: $TEST_VALUE)"
else
log_error "Redis write/read test failed"
exit 1
fi
log_info "Setting up redis_fdw extension..."
log_info "PostgreSQL connection:"
log_info " User: $POSTGRES_USER"
log_info " Database: $POSTGRES_DB"
# Run SQL setup as postgres user with error handling
if psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL; then
-- Create redis_fdw extension
DO \$\$
BEGIN
CREATE EXTENSION IF NOT EXISTS redis_fdw;
RAISE NOTICE 'redis_fdw extension created/verified';
EXCEPTION WHEN OTHERS THEN
RAISE EXCEPTION 'Failed to create redis_fdw extension: %', SQLERRM;
END;
\$\$;
-- Create foreign server
DO \$\$
BEGIN
DROP SERVER IF EXISTS redis_server CASCADE;
CREATE SERVER redis_server
FOREIGN DATA WRAPPER redis_fdw
OPTIONS (
address '${REDIS_HOST:-redis}',
port '6379'
);
RAISE NOTICE 'Foreign server redis_server created (host: ${REDIS_HOST:-redis}, port: 6379)';
EXCEPTION WHEN OTHERS THEN
RAISE EXCEPTION 'Failed to create foreign server: %', SQLERRM;
END;
\$\$;
-- Create user mapping
DO \$\$
BEGIN
CREATE USER MAPPING FOR CURRENT_USER
SERVER redis_server
OPTIONS (password '${REDIS_PASSWORD}');
RAISE NOTICE 'User mapping created for CURRENT_USER';
EXCEPTION WHEN OTHERS THEN
RAISE EXCEPTION 'Failed to create user mapping: %', SQLERRM;
END;
\$\$;
-- Create foreign table for Redis hashes
DO \$\$
BEGIN
DROP FOREIGN TABLE IF EXISTS redis_hashes;
CREATE FOREIGN TABLE redis_hashes (
key TEXT,
value TEXT
)
SERVER redis_server
OPTIONS (
database '0',
tabletype 'hash'
);
RAISE NOTICE 'Foreign table redis_hashes created (database: 0, tabletype: hash)';
EXCEPTION WHEN OTHERS THEN
RAISE EXCEPTION 'Failed to create redis_hashes: %', SQLERRM;
END;
\$\$;
-- Create foreign table for Redis lists
DO \$\$
BEGIN
DROP FOREIGN TABLE IF EXISTS redis_lists;
CREATE FOREIGN TABLE redis_lists (
key TEXT,
value TEXT
)
SERVER redis_server
OPTIONS (
database '0',
tabletype 'list'
);
RAISE NOTICE 'Foreign table redis_lists created (database: 0, tabletype: list)';
EXCEPTION WHEN OTHERS THEN
RAISE EXCEPTION 'Failed to create redis_lists: %', SQLERRM;
END;
\$\$;
-- Create foreign table for Redis sets
DO \$\$
BEGIN
DROP FOREIGN TABLE IF EXISTS redis_sets;
CREATE FOREIGN TABLE redis_sets (
key TEXT,
value TEXT
)
SERVER redis_server
OPTIONS (
database '0',
tabletype 'set'
);
RAISE NOTICE 'Foreign table redis_sets created (database: 0, tabletype: set)';
EXCEPTION WHEN OTHERS THEN
RAISE EXCEPTION 'Failed to create redis_sets: %', SQLERRM;
END;
\$\$;
-- Create foreign table for Redis sorted sets
DO \$\$
BEGIN
DROP FOREIGN TABLE IF EXISTS redis_zsets;
CREATE FOREIGN TABLE redis_zsets (
key TEXT,
value TEXT
)
SERVER redis_server
OPTIONS (
database '0',
tabletype 'zset'
);
RAISE NOTICE 'Foreign table redis_zsets created (database: 0, tabletype: zset)';
EXCEPTION WHEN OTHERS THEN
RAISE EXCEPTION 'Failed to create redis_zsets: %', SQLERRM;
END;
\$\$;
-- Grant permissions
DO \$\$
BEGIN
GRANT SELECT ON redis_hashes TO PUBLIC;
GRANT SELECT ON redis_lists TO PUBLIC;
GRANT SELECT ON redis_sets TO PUBLIC;
GRANT SELECT ON redis_zsets TO PUBLIC;
RAISE NOTICE 'Permissions granted on all Redis foreign tables';
EXCEPTION WHEN OTHERS THEN
RAISE EXCEPTION 'Failed to grant permissions: %', SQLERRM;
END;
\$\$;
-- Final verification
SELECT 'Redis FDW setup completed successfully!' as status;
EOSQL
log_info "Redis FDW SQL setup completed successfully"
else
log_error "Redis FDW SQL setup failed with exit code $?"
exit 1
fi
log_info "Redis FDW initialization complete"