How to Fix “su: /bin/bash: Resource temporarily unavailable” Error When Switching to PostgreSQL User


2 views

When attempting to switch to the PostgreSQL user using sudo su - postgres, you might encounter the frustrating error: su: /bin/bash: Resource temporarily unavailable. This typically occurs when system resource limits are exhausted, even though your ulimit settings appear reasonable.

# Process count for postgres
ps -auxww | grep -i postgr | wc -l
503

# Open file handles
lsof | grep -i postgr | wc -l
35225

# Established connections
netstat -plan | grep -i post | grep ESTABLISHED | wc -l
496

The error occurs because:

  • The process count (503) exceeds the configured nproc limit (400)
  • Open file handles (35,225) far exceed the nofile limit (4,096)
  • Each PostgreSQL connection consumes multiple file descriptors

The existing limits in /etc/security/limits.d/postgres_limits.conf:

postgres soft nofile 4096
postgres hard nofile 4096
postgres soft nproc 400
postgres hard nproc 400

Adjust the limits to accommodate PostgreSQL's requirements:

# Updated PostgreSQL limits configuration
postgres soft nofile 65536
postgres hard nofile 65536
postgres soft nproc 8192
postgres hard nproc 8192

1. Edit the limits file:

sudo nano /etc/security/limits.d/postgres_limits.conf

2. Apply the changes by either:

  • Logging out and back in as the postgres user
  • Restarting the PostgreSQL service

After applying changes, verify the new limits:

sudo su - postgres -c "ulimit -a"
cat /proc/$(pgrep -u postgres | head -1)/limits

For production systems, consider:

# Kernel-level adjustments
echo "fs.file-max = 2097152" >> /etc/sysctl.conf
echo "vm.max_map_count = 262144" >> /etc/sysctl.conf
sysctl -p

Create a monitoring script:

#!/bin/bash
# Monitor PostgreSQL resource usage
echo "Process count: $(ps -u postgres | wc -l)"
echo "Open files: $(lsof -u postgres | wc -l)"
echo "Connections: $(netstat -tulnp | grep postgres | wc -l)"

When attempting to switch to the postgres user via sudo su - postgres, many administrators encounter the frustrating "Resource temporarily unavailable" error. This typically occurs in active PostgreSQL production environments where resource consumption is high.

Before troubleshooting, gather these critical metrics:

# Check process count
ps -auxww | grep -i postgr | wc -l

# Examine open files
lsof | grep -i postgr | wc -l

# Verify established connections
netstat -plan | grep -i post | grep ESTABLISHED | wc -l

# Review process limits
cat /proc/$(pgrep -u postgres | head -1)/limits

From the metrics shown, we can identify several potential issues:

  • Process limit exhaustion (shown 503 Postgres processes vs. limit of 400)
  • High number of established connections (496)
  • Extensive file handle usage (35,225 open files)

The limits configuration (/etc/security/limits.d/postgres_limits.conf) shows:

postgres soft nofile 4096
postgres hard nofile 4096
postgres soft nproc 400
postgres hard nproc 400

These values are insufficient for production PostgreSQL instances with heavy workloads.

For production PostgreSQL servers, implement these changes:

1. Adjust Process Limits

# /etc/security/limits.d/postgres_limits.conf
postgres soft nofile 65536
postgres hard nofile 65536
postgres soft nproc 8192
postgres hard nproc 8192

2. PostgreSQL Connection Management

Modify postgresql.conf:

max_connections = 500
superuser_reserved_connections = 3
shared_buffers = 4GB
work_mem = 8MB

3. Implement Connection Pooling

Add this to pg_hba.conf for pgbouncer:

host all pgbouncer 127.0.0.1/32 scram-sha-256

After making changes:

# Reload limits
sysctl -p

# Verify new limits
su - postgres -c 'ulimit -a'

# Check PostgreSQL status
systemctl restart postgresql
psql -U postgres -c "SHOW max_connections;"
  • Implement monitoring for process and file handle usage
  • Set up alerts when reaching 80% of limits
  • Regularly review connection patterns and optimize queries