Production Deployment: Troubleshooting
Part of: Production Deployment Guide
Every diagnostic on this page uses the server log, psql (or any PostgreSQL client),
curl against the HTTP gateway, and the server’s own flags. See the
Server Configuration Reference for every flag
mentioned here.
9.1 Common Issues
The server does not start
Read the last lines of the log (journalctl -u heliosdb -n 50, docker logs heliosdb).
The server states the reason and the fix:
| Log message | Cause | Fix |
|---|---|---|
Refusing to bind '0.0.0.0' (non-loopback) without explicit opt-in | --bind-addr is not a loopback address | Add --allow-external (or HELIOSDB_ALLOW_EXTERNAL=true) after configuring authentication and a firewall |
Refusing to start with --auth-mode trust while binding ... | trust on an external address | Use --auth-mode scram, or bind to 127.0.0.1 |
Configuration sets options heliosdb-full does not honour | The TOML file has keys the server does not read | Remove them (the message lists them and the honoured keys) or set HELIOSDB_CONFIG_ALLOW_UNSUPPORTED=1 |
HELIOSDB_DATA_DIR=... is not read by heliosdb-full | Legacy variable from an old environment file | Use HELIOSDB_STORAGE_DATA_DIR (or --data-dir) and unset HELIOSDB_DATA_DIR |
PostgreSQL TLS: cannot load ... | Certificate or key unreadable or invalid | Check the paths, file permissions and PEM format |
Failed to bind PostgreSQL port ...: Address already in use | Another process owns the port | ss -ltnp 'sport = :5432'; change the port flag or stop the other process |
No protocols enabled! | Every listener disabled or failed to bind | Check the earlier Failed to bind lines |
Clients cannot connect
- Check the listener is open. The startup log prints one line per listener, for
example
MySQL protocol listening on 10.0.0.12:3306. MySQL, Oracle, SQL Server, MongoDB, Cassandra and Redis are off until enabled with--enable-<protocol>. - Check the address. The default bind is
127.0.0.1; remote clients need--bind-addrwith--allow-external, and the container port must be published. - Check authentication:
- PostgreSQL: user
postgreswithHELIOSDB_SUPERUSER_PASSWORD, or a role created withCREATE ROLE ... LOGIN PASSWORD. If the variable was not set, the generated password is printed once in the first startup log. - A
VALID UNTILin the past or aCONNECTION LIMITthat is reached refuses the login;SHOW ROLESandSHOW CONNECTIONSshow both. - Other listeners use their own variables; see Authentication and credentials.
- PostgreSQL: user
- With
--tls-require(native PostgreSQL TLS, planned for the next release; current listeners do not terminate TLS), clients must connect withsslmode=requireor stricter. - Rate limits: more than 500 new connections per minute from one IP are refused by
default (
--conn-rate-limit), and the total is capped by--max-connections(default 10000). Connection pools in front of the database avoid both.
High query latency
-- What is running right nowSHOW CONNECTIONS;SELECT pid, usename, state, query FROM pg_stat_activity;
-- Plan of a slow statementEXPLAIN ANALYZE SELECT ... ;Statements slower than --log-min-duration-statement (default 1000 ms) are logged at
WARN with their duration; lower the threshold for a session with
SET log_min_duration_statement = 200; while you investigate.
Common fixes:
- Indexes.
CREATE INDEXbuilds and maintains an index only when the server runs with--enable-secondary-indexes; without it,CREATE INDEXrecords catalog metadata only. Enable the flag, then create the indexes yourWHEREand join columns need. - Read cache.
--read-cache-mb(default 0, off) caches decoded SSTable blocks for repeated reads and scans; start with a quarter of the memory you can spare. - Compaction. Without
--enable-compaction, SSTables accumulate and reads touch more files over time. Enable it on long-running servers; cap its I/O with--compaction-max-mbpsif foreground latency matters more. - Write latency. Each commit is fsynced by default. Batch inserts in transactions
or multi-row
INSERTs; use--synchronous-commit offonly where losing the last few milliseconds of writes after a crash is acceptable.
Out of memory
The memtable (64 MB by default, memtable_size_mb in the config file or
HELIOSDB_STORAGE_MEMTABLE_SIZE_MB), the read cache (--read-cache-mb) and per-query
working memory make up most of the server’s memory. To reduce it:
- Lower
--read-cache-mb. - Lower
--max-connectionsand put a connection pool in front of the server. - Set
statement_timeoutfor ad-hoc or reporting users so runaway queries end. - Give the container or systemd unit a memory limit with headroom above these sizes, so the kernel does not kill the process under pressure.
Disk usage grows
- Enable background compaction (
--enable-compaction) so overwritten and deleted rows are reclaimed. - Check
SHOW STORAGE STATUSand the size of<data-dir>/wal. - The periodic memtable flush (
--flush-interval-secs, default 60) keeps the WAL bounded; do not set it to0on long-running servers.
A statement returns SQLSTATE 0A000
The statement belongs to a subsystem that this server does not run, for example
SHOW REPLICATION STATUS, FAILOVER, GRANT, CREATE SNAPSHOT or
ALTER TABLE ... ENABLE ROW LEVEL SECURITY. The message names the subsystem and
nothing was changed. heliosdb-full --show-features --all lists them.
9.2 Debug Procedures
More logging
# Debug logging for the whole serverheliosdb-full --verbose ...
RUST_BACKTRACE=1 # backtraces on errors (set in the container image)-- Log every statement of this session with its durationSET log_min_duration_statement = 0;Collect a diagnostic bundle
mkdir -p /tmp/heliosdb-diag && cd /tmp/heliosdb-diagheliosdb-full --version > version.txtheliosdb-full --show-features --all > features.txtjournalctl -u heliosdb --since "1 hour ago" > server.log # or: docker logs --since 1h heliosdbcurl -s http://127.0.0.1:8443/health > health.jsonpsql "host=127.0.0.1 user=postgres" -c "SHOW SERVER STATUS" -c "SHOW PROTOCOLS" \ -c "SHOW CONNECTIONS" -c "SHOW STORAGE STATUS" -c "SHOW WAL STATUS" > status.txtdu -sh /var/lib/heliosdb /var/lib/heliosdb/wal > disk.txttar -czf ../heliosdb-diag-$(date +%Y%m%d-%H%M).tar.gz .Remove secrets before sharing logs: the environment file is not part of the bundle,
and the server never logs the superuser password when you set it through
HELIOSDB_SUPERUSER_PASSWORD.
Health checks
curl -fsS http://127.0.0.1:8443/health # {"status":"healthy","version":"..."}curl -fsS http://127.0.0.1:8443/ready # {"ready":true}pg_isready -h 127.0.0.1 -p 54329.3 Performance Tuning
| Goal | Setting |
|---|---|
| Faster repeated reads | --read-cache-mb 1024 (with --prefetch-depth for scans) |
| Stable read latency over time | --enable-compaction, --compaction-max-mbps 200 |
| Index lookups | --enable-secondary-indexes, then CREATE INDEX |
| Higher write throughput | Batch writes; --synchronous-commit off if the bounded loss window is acceptable |
| Protect against runaway queries | SET statement_timeout at session start (most connection pools have an init-SQL hook) |
| Protect against connection storms | --conn-rate-limit, --max-connections, a pooler |
The Performance Tuning Guide covers each setting in more detail.
Navigation
- Previous: Backup & Disaster Recovery
- Next: Advanced Deployment Scenarios
- Index: Production Deployment Guide