TimescaleDB Troubleshooting
This guide covers common issues and solutions for TimescaleDB in the PRS production environment.
Overview
This troubleshooting guide addresses:
- Installation and setup issues - Extension and migration problems
- Performance problems - Slow queries and resource issues
- Storage issues - Disk space and compression problems
- Connection problems - Database connectivity issues
- Backup and recovery issues - Data protection problems
Common Issues and Solutions
1. Installation and Setup Issues
TimescaleDB Extension Not Available
Symptoms:
- Error: "extension 'timescaledb' is not available"
- Migration fails with extension errors
Diagnosis:
| Bash |
|---|
| # Check if TimescaleDB image is being used
docker ps | grep timescale
# Check available extensions
docker exec -e PGPASSWORD="${POSTGRES_PASSWORD}" prs-ec2-postgres-timescale \
psql -U "${POSTGRES_USER}" -d "${POSTGRES_DB}" \
-c "SELECT name FROM pg_available_extensions WHERE name = 'timescaledb';"
|
Solutions:
| Bash |
|---|
| # 1. Verify Docker image
docker images | grep timescale
# 2. Update docker-compose.yml to use TimescaleDB image
# Change: postgres:15-alpine
# To: timescale/timescaledb:latest-pg15
# 3. Restart services
./scripts/deploy-ec2.sh restart
# 4. Re-run initialization
./scripts/deploy-ec2.sh init-db
|
Migration Fails with SSL Errors
Symptoms:
- "ERROR: self-signed certificate"
- "SSL connection failed"
Diagnosis:
| Bash |
|---|
| # Check SSL configuration
grep -i ssl prs-production-deployment/ec2-graviton-setup/.env
|
Solutions:
| Bash |
|---|
| # Update .env file SSL settings
DISABLE_SSL=true
POSTGRES_SSL_REQUIRE=false
POSTGRES_SSL_REJECT_UNAUTHORIZED=false
# Restart services
./scripts/deploy-ec2.sh restart
# Re-run initialization
./scripts/deploy-ec2.sh init-db
|
Hypertables Not Created
Symptoms:
- Migration completes but no hypertables exist
- TimescaleDB queries fail
Diagnosis:
| Bash |
|---|
| # Check if hypertables exist
./scripts/deploy-ec2.sh timescaledb-status
# Check migration status
docker exec -e PGPASSWORD="${POSTGRES_PASSWORD}" prs-ec2-postgres-timescale \
psql -U "${POSTGRES_USER}" -d "${POSTGRES_DB}" \
-c "SELECT name FROM \"SequelizeMeta\" WHERE name LIKE '%timescaledb%';"
|
Solutions:
| Bash |
|---|
| # 1. Check if TimescaleDB extension is enabled
docker exec -e PGPASSWORD="${POSTGRES_PASSWORD}" prs-ec2-postgres-timescale \
psql -U "${POSTGRES_USER}" -d "${POSTGRES_DB}" \
-c "CREATE EXTENSION IF NOT EXISTS timescaledb;"
# 2. Re-run specific migration
cd /path/to/prs-backend-a
npx sequelize-cli db:migrate --env production
# 3. Manual hypertable creation (if needed)
docker exec -e PGPASSWORD="${POSTGRES_PASSWORD}" prs-ec2-postgres-timescale \
psql -U "${POSTGRES_USER}" -d "${POSTGRES_DB}" \
-c "SELECT create_hypertable('audit_logs', 'created_at');"
|
Symptoms:
- Queries taking longer than expected
- High CPU usage
- Application timeouts
Diagnosis:
| Bash |
|---|
| # Check slow queries
docker exec -e PGPASSWORD="${POSTGRES_PASSWORD}" prs-ec2-postgres-timescale \
psql -U "${POSTGRES_USER}" -d "${POSTGRES_DB}" \
-c "SELECT query, mean_time, calls FROM pg_stat_statements
WHERE mean_time > 1000 ORDER BY mean_time DESC LIMIT 5;"
# Check active queries
docker exec -e PGPASSWORD="${POSTGRES_PASSWORD}" prs-ec2-postgres-timescale \
psql -U "${POSTGRES_USER}" -d "${POSTGRES_DB}" \
-c "SELECT pid, now() - query_start as duration, query
FROM pg_stat_activity WHERE state = 'active';"
|
Solutions:
| Bash |
|---|
| # 1. Run optimization
./scripts/deploy-ec2.sh timescaledb-optimize
# 2. Check for missing time constraints in queries
# Ensure queries include WHERE created_at >= ...
# 3. Verify chunk exclusion is working
EXPLAIN (ANALYZE, BUFFERS)
SELECT COUNT(*) FROM audit_logs
WHERE created_at >= NOW() - INTERVAL '30 days';
# 4. Add appropriate indexes
CREATE INDEX CONCURRENTLY idx_table_time_column
ON table_name (time_column DESC);
|
High Memory Usage
Symptoms:
- Out of memory errors
- Container restarts
- System slowdown
Diagnosis:
| Bash |
|---|
| # Check memory usage
free -h
docker stats prs-ec2-postgres-timescale --no-stream
# Check PostgreSQL memory settings
docker exec -e PGPASSWORD="${POSTGRES_PASSWORD}" prs-ec2-postgres-timescale \
psql -U "${POSTGRES_USER}" -d "${POSTGRES_DB}" \
-c "SELECT name, setting, unit FROM pg_settings
WHERE name IN ('shared_buffers', 'work_mem', 'maintenance_work_mem');"
|
Solutions:
| Bash |
|---|
| # 1. Adjust memory settings in .env
POSTGRES_SHARED_BUFFERS=128MB
POSTGRES_WORK_MEM=4MB
POSTGRES_MAINTENANCE_WORK_MEM=32MB
# 2. Restart services
./scripts/deploy-ec2.sh restart
# 3. Kill long-running queries if needed
docker exec -e PGPASSWORD="${POSTGRES_PASSWORD}" prs-ec2-postgres-timescale \
psql -U "${POSTGRES_USER}" -d "${POSTGRES_DB}" \
-c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity
WHERE state = 'active' AND now() - query_start > interval '10 minutes';"
|
3. Storage Issues
High Disk Usage
Symptoms:
- Disk space warnings
- "No space left on device" errors
- Slow I/O performance
Diagnosis:
| Bash |
|---|
| # Check disk usage
df -h
du -sh /var/lib/docker/
# Check database size
./scripts/deploy-ec2.sh timescaledb-maintenance storage
# Check compression status
./scripts/deploy-ec2.sh timescaledb-maintenance status
|
Solutions:
| Bash |
|---|
| # 1. Force compression of eligible chunks
./scripts/deploy-ec2.sh timescaledb-maintenance compress
# 2. Clean up old backups
find ./backups -name "*.dump" -mtime +30 -delete
find ./backups -name "*.sql.gz" -mtime +30 -delete
# 3. Clean up Docker resources
docker system prune -f
docker volume prune -f
# 4. Check for uncompressed old chunks
docker exec -e PGPASSWORD="${POSTGRES_PASSWORD}" prs-ec2-postgres-timescale \
psql -U "${POSTGRES_USER}" -d "${POSTGRES_DB}" \
-c "SELECT chunk_name, range_end, is_compressed
FROM timescaledb_information.chunks
WHERE NOT is_compressed AND range_end < NOW() - INTERVAL '7 days';"
|
Compression Not Working
Symptoms:
- Low compression ratios
- Storage not decreasing as expected
- Compression policies not running
Diagnosis:
| Bash |
|---|
| # Check compression policies
./scripts/deploy-ec2.sh timescaledb-maintenance status
# Check compression jobs
docker exec -e PGPASSWORD="${POSTGRES_PASSWORD}" prs-ec2-postgres-timescale \
psql -U "${POSTGRES_USER}" -d "${POSTGRES_DB}" \
-c "SELECT * FROM timescaledb_information.jobs
WHERE proc_name = 'policy_compression';"
|
Solutions:
| Bash |
|---|
| # 1. Re-setup compression policies
./scripts/deploy-ec2.sh timescaledb-compression
# 2. Manual compression
./scripts/deploy-ec2.sh timescaledb-maintenance compress
# 3. Check if tables have compression enabled
docker exec -e PGPASSWORD="${POSTGRES_PASSWORD}" prs-ec2-postgres-timescale \
psql -U "${POSTGRES_USER}" -d "${POSTGRES_DB}" \
-c "SELECT hypertable_name, compression_enabled
FROM timescaledb_information.hypertables;"
# 4. Enable compression on specific table
docker exec -e PGPASSWORD="${POSTGRES_PASSWORD}" prs-ec2-postgres-timescale \
psql -U "${POSTGRES_USER}" -d "${POSTGRES_DB}" \
-c "ALTER TABLE table_name SET (timescaledb.compress);"
|
4. Connection Issues
Connection Refused
Symptoms:
- "Connection refused" errors
- Application cannot connect to database
- Database appears down
Diagnosis:
| Bash |
|---|
| # Check container status
docker ps | grep timescale
# Check container logs
docker logs prs-ec2-postgres-timescale
# Check database readiness
docker exec prs-ec2-postgres-timescale pg_isready -U "${POSTGRES_USER}" -d "${POSTGRES_DB}"
|
Solutions:
| Bash |
|---|
| # 1. Restart database container
docker restart prs-ec2-postgres-timescale
# 2. Check if container is running
./scripts/deploy-ec2.sh status
# 3. Restart all services
./scripts/deploy-ec2.sh restart
# 4. Check for port conflicts
netstat -tlnp | grep 5432
|
Too Many Connections
Symptoms:
- "too many connections" errors
- Connection pool exhausted
- Application timeouts
Diagnosis:
| Bash |
|---|
| # Check current connections
docker exec -e PGPASSWORD="${POSTGRES_PASSWORD}" prs-ec2-postgres-timescale \
psql -U "${POSTGRES_USER}" -d "${POSTGRES_DB}" \
-c "SELECT count(*) as connections, state FROM pg_stat_activity GROUP BY state;"
# Check connection limit
docker exec -e PGPASSWORD="${POSTGRES_PASSWORD}" prs-ec2-postgres-timescale \
psql -U "${POSTGRES_USER}" -d "${POSTGRES_DB}" \
-c "SHOW max_connections;"
|
Solutions:
| Bash |
|---|
| # 1. Kill idle connections
docker exec -e PGPASSWORD="${POSTGRES_PASSWORD}" prs-ec2-postgres-timescale \
psql -U "${POSTGRES_USER}" -d "${POSTGRES_DB}" \
-c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity
WHERE state = 'idle' AND now() - state_change > interval '1 hour';"
# 2. Adjust connection pool settings in application
# Reduce max connections in Sequelize config
# 3. Increase max_connections (if needed)
# In .env: POSTGRES_MAX_CONNECTIONS=50
./scripts/deploy-ec2.sh restart
|
5. Backup and Recovery Issues
Backup Failures
Symptoms:
- Backup scripts fail
- Empty or corrupted backup files
- Backup process hangs
Diagnosis:
| Bash |
|---|
| # Check backup logs
tail -f /var/log/timescaledb-backup.log
# Test backup manually
./scripts/deploy-ec2.sh timescaledb-backup
# Check backup directory
ls -la ./backups/
|
Solutions:
| Bash |
|---|
| # 1. Check disk space for backups
df -h ./backups/
# 2. Test database connectivity
docker exec -e PGPASSWORD="${POSTGRES_PASSWORD}" prs-ec2-postgres-timescale \
pg_isready -U "${POSTGRES_USER}" -d "${POSTGRES_DB}"
# 3. Manual backup
docker exec -e PGPASSWORD="${POSTGRES_PASSWORD}" prs-ec2-postgres-timescale \
pg_dump -U "${POSTGRES_USER}" -d "${POSTGRES_DB}" -Fc > manual_backup.dump
# 4. Check backup script permissions
chmod +x ./scripts/timescaledb-production-backup.sh
|
Recovery Failures
Symptoms:
- Restore process fails
- Data corruption after restore
- Missing data after recovery
Diagnosis:
| Bash |
|---|
| # Test backup integrity
docker exec prs-ec2-postgres-timescale \
pg_restore --list /tmp/backup.dump > /dev/null
# Check backup file
file ./backups/backup.dump
|
Solutions:
| Bash |
|---|
| # 1. Verify backup integrity before restore
pg_restore --list backup.dump
# 2. Use different restore method
# Try SQL backup instead of binary
gunzip -c backup.sql.gz | docker exec -i prs-ec2-postgres-timescale \
psql -U "${POSTGRES_USER}" -d "${POSTGRES_DB}"
# 3. Restore to test database first
docker exec -e PGPASSWORD="${POSTGRES_PASSWORD}" prs-ec2-postgres-timescale \
psql -U "${POSTGRES_USER}" -d "postgres" \
-c "CREATE DATABASE test_restore;"
|
Diagnostic Commands
System Health Check
| Bash |
|---|
| # Comprehensive health check
./scripts/timescaledb-alerts.sh
# Quick status check
./scripts/deploy-ec2.sh timescaledb-status
# Resource monitoring
./scripts/deploy-ec2.sh monitor
|
Database Diagnostics
| SQL |
|---|
| -- Check TimescaleDB version
SELECT extversion FROM pg_extension WHERE extname = 'timescaledb';
-- Check hypertables
SELECT * FROM timescaledb_information.hypertables;
-- Check chunks
SELECT count(*) as total_chunks,
count(*) FILTER (WHERE is_compressed) as compressed_chunks
FROM timescaledb_information.chunks;
-- Check active queries
SELECT pid, now() - query_start as duration, query
FROM pg_stat_activity
WHERE state = 'active' AND query NOT LIKE '%pg_stat_activity%';
|
| Bash |
|---|
| # Check slow queries
docker exec -e PGPASSWORD="${POSTGRES_PASSWORD}" prs-ec2-postgres-timescale \
psql -U "${POSTGRES_USER}" -d "${POSTGRES_DB}" \
-c "SELECT query, mean_time, calls FROM pg_stat_statements
ORDER BY mean_time DESC LIMIT 10;"
# Check table sizes
docker exec -e PGPASSWORD="${POSTGRES_PASSWORD}" prs-ec2-postgres-timescale \
psql -U "${POSTGRES_USER}" -d "${POSTGRES_DB}" \
-c "SELECT schemaname, tablename,
pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) as size
FROM pg_tables WHERE schemaname = 'public'
ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC;"
|
Emergency Procedures
Database Recovery
| Bash |
|---|
| # 1. Stop application
./scripts/deploy-ec2.sh stop
# 2. Backup current state (if possible)
./scripts/deploy-ec2.sh timescaledb-backup
# 3. Restore from latest backup
./scripts/restore-latest-backup.sh
# 4. Verify restoration
./scripts/deploy-ec2.sh timescaledb-status
# 5. Start application
./scripts/deploy-ec2.sh start
|
| Bash |
|---|
| # 1. Kill long-running queries
docker exec -e PGPASSWORD="${POSTGRES_PASSWORD}" prs-ec2-postgres-timescale \
psql -U "${POSTGRES_USER}" -d "${POSTGRES_DB}" \
-c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity
WHERE state = 'active' AND now() - query_start > interval '5 minutes';"
# 2. Run immediate optimization
./scripts/deploy-ec2.sh timescaledb-optimize
# 3. Check resource usage
./scripts/deploy-ec2.sh monitor
# 4. Restart if necessary
./scripts/deploy-ec2.sh restart
|
Getting Help
Log Files to Check
/var/log/timescaledb-alerts.log - Health monitoring alerts
/var/log/timescaledb-backup.log - Backup operation logs
/var/log/timescaledb-maintenance.log - Maintenance operation logs
docker logs prs-ec2-postgres-timescale - Database container logs
Useful Commands for Support
| Bash |
|---|
| # System information
uname -a
docker --version
docker-compose --version
# TimescaleDB information
./scripts/deploy-ec2.sh timescaledb-status
./scripts/timescaledb-alerts.sh
./scripts/deploy-ec2.sh monitor
# Configuration
cat prs-production-deployment/ec2-graviton-setup/.env | grep -v PASSWORD
|
When in doubt, check the logs, run health checks, and don't hesitate to restart services if needed!