182 lines
No EOL
4.9 KiB
Markdown
182 lines
No EOL
4.9 KiB
Markdown
# PostgreSQL Server Configuration for APRS.me
|
|
|
|
This Ansible configuration deploys a high-performance PostgreSQL server on the CM3588 with RAID0 storage configuration, optimized for the APRS.me workload.
|
|
|
|
## Hardware
|
|
|
|
- **Server**: CM3588 with RK3588 SoC
|
|
- **Storage**: 2x 2TB NVMe SSDs in RAID0 (4TB total capacity)
|
|
- **Network**: 2.5 Gigabit Ethernet
|
|
- **RAM**: 32GB (assumed)
|
|
|
|
## Features
|
|
|
|
- Software RAID0 configuration for maximum performance
|
|
- PostgreSQL 16 with PostGIS for spatial data
|
|
- PgBouncer for connection pooling
|
|
- Optimized for high insert rates and spatial queries
|
|
- Automated backups with retention policy
|
|
- Health monitoring and alerting
|
|
- Kernel and systemd tuning for database workloads
|
|
|
|
## Prerequisites
|
|
|
|
1. Ubuntu 22.04 or later installed on the CM3588
|
|
2. SSH access to the server with the user 'graham'
|
|
3. Ansible installed on your control machine
|
|
|
|
## Initial Setup
|
|
|
|
**Note**: This playbook assumes a fresh PostgreSQL installation. All data will be stored on the RAID array from the start.
|
|
|
|
1. First, create a vault file for sensitive data:
|
|
```bash
|
|
ansible-vault create group_vars/all/vault.yml
|
|
```
|
|
|
|
Add the following to the vault file:
|
|
```yaml
|
|
vault_postgresql_aprsme_password: "your-secure-password-here"
|
|
```
|
|
|
|
2. Bootstrap the server (first time only):
|
|
```bash
|
|
ansible-playbook -i inventory.yml bootstrap.yml --ask-pass --ask-become-pass
|
|
```
|
|
|
|
3. Deploy PostgreSQL:
|
|
```bash
|
|
ansible-playbook -i inventory.yml postgres-playbook.yml --ask-vault-pass
|
|
```
|
|
|
|
The playbook will:
|
|
- Create RAID0 array from both NVMe drives
|
|
- Initialize PostgreSQL cluster directly on the RAID array
|
|
- Configure all PostgreSQL data, WAL, archives, and backups on the RAID array
|
|
- No data migration needed since this is a fresh installation
|
|
|
|
## Configuration Details
|
|
|
|
### RAID0 Configuration
|
|
- Creates `/dev/md0` from `/dev/nvme0n1` and `/dev/nvme1n1`
|
|
- Formatted as ext4 with optimizations for SSDs
|
|
- Mounted at `/mnt/pgdata` with noatime,nodiratime options
|
|
- All PostgreSQL data stored on RAID array:
|
|
- Data directory: `/mnt/pgdata/16/main`
|
|
- WAL directory: `/mnt/pgdata/wal`
|
|
- Archive directory: `/mnt/pgdata/archive`
|
|
- Backup directory: `/mnt/pgdata/backups`
|
|
|
|
### PostgreSQL Optimization
|
|
- **shared_buffers**: 8GB (25% of RAM)
|
|
- **effective_cache_size**: 24GB (75% of RAM)
|
|
- **work_mem**: 64MB (for complex spatial queries)
|
|
- **max_connections**: 200
|
|
- **autovacuum**: Tuned for high insert rate
|
|
- **checkpoint**: Optimized for write performance
|
|
|
|
### PgBouncer Settings
|
|
- **pool_mode**: transaction (optimal for APRS.me)
|
|
- **default_pool_size**: 25
|
|
- **max_client_conn**: 1000
|
|
|
|
### Security
|
|
- PostgreSQL listening on all interfaces (configure firewall accordingly)
|
|
- SCRAM-SHA-256 authentication
|
|
- Access restricted to 10.0.0.0/8 network (adjust as needed)
|
|
|
|
## Maintenance
|
|
|
|
### Check RAID Status
|
|
```bash
|
|
ssh postgres@10.0.16.230 'sudo mdadm --detail /dev/md0'
|
|
```
|
|
|
|
### PostgreSQL Logs
|
|
```bash
|
|
ssh postgres@10.0.16.230 'sudo journalctl -u postgresql -f'
|
|
```
|
|
|
|
### Backup Status
|
|
```bash
|
|
ssh postgres@10.0.16.230 'ls -la /mnt/pgdata/backups/'
|
|
```
|
|
|
|
### Performance Monitoring
|
|
```bash
|
|
# Connect to PostgreSQL
|
|
psql -h 10.0.16.230 -p 5432 -U postgres -d aprsme_prod
|
|
|
|
# Check slow queries
|
|
SELECT * FROM pg_stat_statements ORDER BY total_time DESC LIMIT 10;
|
|
|
|
# Check table sizes
|
|
SELECT schemaname, tablename, pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) AS size
|
|
FROM pg_tables
|
|
ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC;
|
|
|
|
# Check index usage
|
|
SELECT schemaname, tablename, indexname, idx_scan
|
|
FROM pg_stat_user_indexes
|
|
ORDER BY idx_scan;
|
|
```
|
|
|
|
## Connecting from APRS.me
|
|
|
|
Update your APRS.me configuration:
|
|
|
|
```elixir
|
|
# config/runtime.exs
|
|
config :aprsme, Aprsme.Repo,
|
|
url: "postgresql://aprsme:password@10.0.16.230:6432/aprsme_prod",
|
|
pool_size: 5
|
|
```
|
|
|
|
Or use environment variable:
|
|
```bash
|
|
DATABASE_URL=postgresql://aprsme:password@10.0.16.230:6432/aprsme_prod
|
|
```
|
|
|
|
## Disaster Recovery
|
|
|
|
1. **RAID Failure**: While RAID0 provides no redundancy, the backup script runs nightly
|
|
2. **Backup Restore**:
|
|
```bash
|
|
pg_restore -h localhost -U postgres -d aprsme_prod_restore /mnt/pgdata/backups/aprsme_prod_20240126_020000.sql.gz
|
|
```
|
|
3. **Replication**: Consider setting up streaming replication to a standby server
|
|
|
|
## Performance Expectations
|
|
|
|
With this configuration, expect:
|
|
- Insert rate: 1000+ packets/second sustained
|
|
- Spatial query response: <10ms for indexed queries
|
|
- Connection overhead: Minimal with PgBouncer
|
|
- Storage capacity: ~4TB usable (years of APRS data)
|
|
|
|
## Troubleshooting
|
|
|
|
### RAID Issues
|
|
```bash
|
|
# Check RAID status
|
|
cat /proc/mdstat
|
|
mdadm --detail /dev/md0
|
|
|
|
# Check disk health
|
|
smartctl -a /dev/nvme0n1
|
|
smartctl -a /dev/nvme1n1
|
|
```
|
|
|
|
### PostgreSQL Performance
|
|
```bash
|
|
# Check current connections
|
|
SELECT count(*) FROM pg_stat_activity;
|
|
|
|
# Check cache hit ratio
|
|
SELECT sum(heap_blks_hit) / (sum(heap_blks_hit) + sum(heap_blks_read)) AS cache_hit_ratio FROM pg_statio_user_tables;
|
|
```
|
|
|
|
### PgBouncer Stats
|
|
```bash
|
|
psql -h 10.0.16.230 -p 6432 -U postgres pgbouncer -c "SHOW STATS;"
|
|
``` |