O PostgreSQL é o sistema de banco de dados relacional de código aberto mais avançado em uso produtivo atualmente. Confiável por organizações que vão desde startups até grandes empresas, ele impulsiona desde pequenas aplicações web até sistemas massivos de armazenamento de dados que processam bilhões de linhas. Este guia conduz você pela instalação do PostgreSQL no Ubuntu Server, configuração para uso em produção, configuração de autenticação e acesso remoto, implementação de estratégias de backup e otimização de parâmetros de desempenho para rendimento ideal.

Pré-requisitos

Antes de começar, certifique-se de ter:

  • Ubuntu Server 20.04, 22.04 ou 24.04 LTS
  • Acesso ao terminal com privilégios sudo
  • Pelo menos 1 GB de RAM (2 GB ou mais recomendado para produção)
  • Familiaridade básica com SQL e operações de linha de comando no Linux
  • Um firewall configurado (consulte nosso guia de UFW para a configuração)

O Que É PostgreSQL?

PostgreSQL (frequentemente chamado de “Postgres”) é um sistema de gerenciamento de banco de dados objeto-relacional (ORDBMS) que está em desenvolvimento ativo há mais de 35 anos. Originalmente desenvolvido na Universidade da Califórnia, Berkeley, agora é mantido por uma comunidade global de contribuidores.

Características principais do PostgreSQL:

  • Conformidade ACID — suporte completo para atomicidade, consistência, isolamento e durabilidade
  • MVCC (Controle de Concorrência Multi-Versão) — leitores nunca bloqueiam escritores e escritores nunca bloqueiam leitores
  • Extensível — tipos de dados personalizados, operadores, funções e métodos de índice
  • Conformidade com padrões — a implementação mais próxima do padrão SQL entre todos os bancos de dados
  • Recursos avançados — JSON/JSONB, busca de texto completo, particionamento de tabelas, replicação lógica, CTEs, funções de janela
  • Segurança robusta — segurança em nível de linha, SSL/TLS, múltiplos métodos de autenticação

Instalação do PostgreSQL no Ubuntu

Opção 1: Instalar a Partir dos Repositórios do Ubuntu

A abordagem mais simples usa os pacotes padrão do Ubuntu:

sudo apt update
sudo apt install postgresql postgresql-contrib

Isso instala a versão incluída com sua versão do Ubuntu (PostgreSQL 14 no 22.04, PostgreSQL 16 no 24.04).

Opção 2: Instalar a Versão Mais Recente do Repositório Oficial

Para obter a versão mais recente do PostgreSQL (versão 17 no momento da escrita), adicione o repositório APT oficial do PostgreSQL:

sudo apt install -y gnupg2 wget
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo gpg --dearmor -o /usr/share/keyrings/postgresql-archive-keyring.gpg

Atualize as referências do repositório na lista de fontes para usar o chaveiro assinado:

sudo sed -i 's|deb http://apt.postgresql.org|deb [signed-by=/usr/share/keyrings/postgresql-archive-keyring.gpg] http://apt.postgresql.org|' /etc/apt/sources.list.d/pgdg.list
sudo apt update
sudo apt install -y postgresql-17 postgresql-contrib-17

Verificar a Instalação

Após a instalação, o PostgreSQL inicia automaticamente. Verifique se está em execução:

sudo systemctl status postgresql

Verifique a versão instalada:

psql --version

Saída esperada:

psql (PostgreSQL) 17.x

Configuração Inicial

O PostgreSQL armazena sua configuração em dois arquivos principais. No Ubuntu, eles estão localizados em /etc/postgresql/<versão>/main/.

postgresql.conf — Configuração do Servidor

Este arquivo controla o comportamento do servidor, configurações de desempenho, registro e parâmetros de conexão:

sudo nano /etc/postgresql/17/main/postgresql.conf

Configurações principais para revisar imediatamente:

# Configurações de conexão
listen_addresses = 'localhost'    # Altere para '*' ou IP específico para acesso remoto
port = 5432                       # Porta padrão do PostgreSQL
max_connections = 100             # Conexões simultâneas máximas

# Configurações de memória (ajuste com base na RAM do seu servidor)
shared_buffers = 256MB            # Comece com 25% da RAM total
work_mem = 4MB                    # Memória de ordenação por operação
maintenance_work_mem = 128MB      # Para VACUUM, CREATE INDEX

# Write-Ahead Logging
wal_level = replica               # Habilita replicação e PITR
max_wal_size = 1GB
min_wal_size = 80MB

# Registro
logging_collector = on
log_directory = 'log'
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
log_statement = 'ddl'             # Registrar instruções DDL
log_min_duration_statement = 1000 # Registrar consultas que demorem mais de 1 segundo

pg_hba.conf — Autenticação de Clientes

Este arquivo controla quem pode conectar, de onde e como se autenticam:

sudo nano /etc/postgresql/17/main/pg_hba.conf

A configuração padrão tipicamente se parece com:

# TYPE  DATABASE  USER      ADDRESS         METHOD
local   all       postgres                  peer
local   all       all                       peer
host    all       all       127.0.0.1/32    scram-sha-256
host    all       all       ::1/128         scram-sha-256

Após fazer alterações em qualquer um dos arquivos, reinicie o PostgreSQL:

sudo systemctl restart postgresql

Ou recarregue sem reiniciar (para a maioria das alterações no pg_hba.conf):

sudo systemctl reload postgresql

Métodos de Autenticação

O PostgreSQL suporta múltiplos métodos de autenticação. Compreendê-los é essencial para proteger seu banco de dados.

Autenticação peer

Mapeia o nome de usuário do sistema operacional para uma função do PostgreSQL. Se você está conectado como o usuário do sistema postgres, pode conectar-se à função de banco de dados postgres sem senha:

sudo -u postgres psql

Este é o padrão para conexões locais por socket Unix e é seguro porque depende da autenticação do sistema operacional.

Autenticação md5

Usa senhas com hash MD5. Embora ainda funcional, é considerado legado:

host    all    all    192.168.1.0/24    md5

Autenticação scram-sha-256 (Recomendada)

O método baseado em senha mais seguro, usando o mecanismo de desafio-resposta SCRAM-SHA-256:

host    all    all    192.168.1.0/24    scram-sha-256

Para garantir que novas senhas usem SCRAM-SHA-256, defina isso no postgresql.conf:

password_encryption = scram-sha-256

Importante: Se você mudar de md5 para scram-sha-256, as senhas de usuários existentes devem ser redefinidas porque o formato de hash armazenado é diferente.

Criação de Bancos de Dados e Usuários

Conecte-se ao PostgreSQL como superusuário:

sudo -u postgres psql

Criar uma Nova Função (Usuário)

CREATE ROLE appuser WITH LOGIN PASSWORD 'StrongPassword123!';

Conceder capacidades específicas:

ALTER ROLE appuser CREATEDB;

Criar um Banco de Dados

CREATE DATABASE myappdb OWNER appuser;

Ou pela linha de comando:

sudo -u postgres createdb -O appuser myappdb

Conceder Privilégios

GRANT ALL PRIVILEGES ON DATABASE myappdb TO appuser;

Para controle mais granular em esquemas e tabelas:

\c myappdb
GRANT USAGE ON SCHEMA public TO appuser;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO appuser;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO appuser;

Conectar como o Novo Usuário

psql -U appuser -d myappdb -h localhost

Configuração de Acesso Remoto

Por padrão, o PostgreSQL aceita apenas conexões de localhost. Para habilitar o acesso remoto:

Passo 1: Atualizar listen_addresses

Edite postgresql.conf:

listen_addresses = '*'

Ou restrinja a uma interface específica:

listen_addresses = '192.168.1.10'

Passo 2: Adicionar Entrada no pg_hba.conf

Permitir uma sub-rede específica:

host    myappdb    appuser    192.168.1.0/24    scram-sha-256

Permitir um único host:

host    all    all    10.0.0.50/32    scram-sha-256

Passo 3: Configurar o Firewall

Permita o PostgreSQL através do UFW:

sudo ufw allow from 192.168.1.0/24 to any port 5432

Ou permita de qualquer lugar (não recomendado para produção):

sudo ufw allow 5432/tcp

Passo 4: Reiniciar e Testar

sudo systemctl restart postgresql

Teste a partir da máquina remota:

psql -h 192.168.1.10 -U appuser -d myappdb

Comandos Essenciais do psql

O terminal interativo psql é a ferramenta principal para trabalhar com o PostgreSQL. Aqui estão os comandos que você usará diariamente:

Conectar

# Conectar como superusuário postgres
sudo -u postgres psql

# Conectar a um banco de dados específico
psql -U appuser -d myappdb -h localhost

# Conectar com uma string de conexão
psql "postgresql://appuser:password@localhost:5432/myappdb"
-- Listar todos os bancos de dados
\l

-- Conectar a um banco de dados diferente
\c myappdb

-- Listar todas as tabelas no esquema atual
\dt

-- Descrever a estrutura de uma tabela
\d tablename

-- Listar todos os esquemas
\dn

-- Listar todas as funções/usuários
\du

-- Mostrar informações da conexão atual
\conninfo

Execução de Consultas

-- Executar uma consulta
SELECT * FROM users LIMIT 10;

-- Habilitar exibição expandida para tabelas largas
\x auto

-- Medir tempo de execução de consultas
\timing on

-- Executar um arquivo SQL
\i /path/to/script.sql

-- Salvar saída da consulta em um arquivo
\o /tmp/output.txt
SELECT * FROM users;
\o

Sair

-- Sair do psql
\q

Backup e Restauração

Uma estratégia de backup sólida é inegociável para bancos de dados em produção.

pg_dump — Backups Lógicos

Exportar um único banco de dados:

# Formato SQL (legível por humanos)
sudo -u postgres pg_dump myappdb > /backups/myappdb_$(date +%Y%m%d).sql

# Formato personalizado (comprimido, suporta restauração paralela)
sudo -u postgres pg_dump -Fc myappdb > /backups/myappdb_$(date +%Y%m%d).dump

# Apenas tabelas específicas
sudo -u postgres pg_dump -t users -t orders myappdb > /backups/tables_$(date +%Y%m%d).sql

Exportar todos os bancos de dados:

sudo -u postgres pg_dumpall > /backups/all_databases_$(date +%Y%m%d).sql

pg_restore — Restaurar Backups

Restaurar a partir de formato personalizado:

sudo -u postgres pg_restore -d myappdb /backups/myappdb_20260128.dump

Restaurar com trabalhos paralelos para recuperação mais rápida:

sudo -u postgres pg_restore -j 4 -d myappdb /backups/myappdb_20260128.dump

Restaurar a partir de formato SQL:

sudo -u postgres psql myappdb < /backups/myappdb_20260128.sql

pg_basebackup — Backups Físicos

Para recuperação em um ponto no tempo (PITR) e configuração de replicação:

sudo -u postgres pg_basebackup -D /backups/base -Ft -Xs -P

Opções explicadas:

  • -D — diretório de destino
  • -Ft — formato tar
  • -Xs — transmitir arquivos WAL durante o backup
  • -P — mostrar progresso

Script de Backup Automatizado

Crie um trabalho cron para backups diários:

sudo nano /usr/local/bin/pg_backup.sh
#!/bin/bash
BACKUP_DIR="/backups/postgresql"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=30

mkdir -p "$BACKUP_DIR"

# Exportar todos os bancos de dados em formato personalizado
for DB in $(sudo -u postgres psql -At -c "SELECT datname FROM pg_database WHERE datistemplate = false AND datname != 'postgres';"); do
    sudo -u postgres pg_dump -Fc "$DB" > "$BACKUP_DIR/${DB}_${TIMESTAMP}.dump"
done

# Remover backups mais antigos que o período de retenção
find "$BACKUP_DIR" -name "*.dump" -mtime +$RETENTION_DAYS -delete

echo "Backup completed: $TIMESTAMP"
sudo chmod +x /usr/local/bin/pg_backup.sh
sudo crontab -e

Adicione a entrada do cron:

0 2 * * * /usr/local/bin/pg_backup.sh >> /var/log/pg_backup.log 2>&1

Otimização de Desempenho

O desempenho do PostgreSQL depende fortemente de uma configuração adequada. As configurações padrão são conservadoras e projetadas para executar em hardware mínimo.

shared_buffers

O parâmetro de memória mais importante. Define quanta memória o PostgreSQL usa para armazenar em cache blocos de dados:

# Recomendado: 25% da RAM total do sistema
# Para um servidor com 16 GB de RAM:
shared_buffers = 4GB

work_mem

Memória alocada para cada operação de ordenação, hash join ou operação similar. Tenha cuidado — isso é por operação, não por conexão:

# Para cargas OLTP com muitas conexões:
work_mem = 4MB

# Para consultas analíticas com menos conexões:
work_mem = 64MB

effective_cache_size

Informa ao planejador de consultas quanta memória está disponível para cache (cache do SO + shared_buffers). Não aloca memória — apenas influencia o planejamento de consultas:

# Recomendado: 50-75% da RAM total do sistema
# Para um servidor com 16 GB de RAM:
effective_cache_size = 12GB

Configuração WAL

As configurações de Write-Ahead Logging impactam significativamente o desempenho de escrita:

# Configurações de checkpoint
checkpoint_completion_target = 0.9
max_wal_size = 2GB
min_wal_size = 1GB

# Para cargas de escrita intensiva
wal_buffers = 64MB
synchronous_commit = on          # Defina como 'off' apenas se puder tolerar perda mínima de dados

Conexões e Paralelismo

# Conexões máximas (cada uma consome ~10MB de RAM)
max_connections = 200

# Execução de consultas paralelas
max_parallel_workers_per_gather = 2
max_parallel_workers = 4
max_worker_processes = 8

Após a Otimização

Aplique as alterações reiniciando o PostgreSQL:

sudo systemctl restart postgresql

Verifique as configurações:

SHOW shared_buffers;
SHOW work_mem;
SHOW effective_cache_size;

Monitoramento com pg_stat_activity

A visão pg_stat_activity fornece informações em tempo real sobre todas as conexões e consultas ativas.

Ver Consultas Ativas

SELECT pid, usename, datname, state, query, query_start,
       now() - query_start AS duration
FROM pg_stat_activity
WHERE state = 'active'
ORDER BY duration DESC;

Encontrar Consultas de Longa Duração

SELECT pid, usename, datname, query,
       now() - query_start AS duration
FROM pg_stat_activity
WHERE state = 'active'
  AND now() - query_start > interval '5 minutes';

Cancelar ou Encerrar uma Consulta

-- Cancelamento elegante (envia SIGINT)
SELECT pg_cancel_backend(12345);

-- Encerramento forçado (envia SIGTERM)
SELECT pg_terminate_backend(12345);

Estatísticas do Banco de Dados

-- Estatísticas em nível de banco de dados
SELECT datname, numbackends, xact_commit, xact_rollback,
       blks_read, blks_hit,
       round(blks_hit::numeric / (blks_read + blks_hit) * 100, 2) AS cache_hit_ratio
FROM pg_stat_database
WHERE datname = 'myappdb';

Estatísticas de Tabelas

-- Estatísticas de acesso a tabelas
SELECT relname, seq_scan, idx_scan, n_tup_ins, n_tup_upd, n_tup_del, n_live_tup
FROM pg_stat_user_tables
ORDER BY seq_scan DESC;

Monitoramento de Bloqueios

-- Ver bloqueios atuais
SELECT pid, locktype, relation::regclass, mode, granted
FROM pg_locks
WHERE NOT granted;

Tabela de Referência de Comandos psql

ComandoDescrição
\lListar todos os bancos de dados
\c dbnameConectar a um banco de dados
\dtListar tabelas no esquema atual
\dt+Listar tabelas com tamanhos
\d tablenameDescrever uma tabela
\diListar índices
\dvListar visões
\dfListar funções
\duListar funções/usuários
\dnListar esquemas
\dpListar privilégios de acesso a tabelas
\xAlternar exibição expandida
\timingAlternar medição de tempo de consultas
\i file.sqlExecutar um arquivo SQL
\o file.txtEnviar saída para arquivo
\eAbrir consulta no editor
\copyComando COPY do lado do cliente
\passwordAlterar senha do usuário
\conninfoMostrar informações de conexão
\qSair do psql

Solução de Problemas

PostgreSQL Não Inicia

Verifique os registros em busca de erros:

sudo journalctl -u postgresql -n 50
sudo cat /var/log/postgresql/postgresql-17-main.log

Causas comuns:

  • A porta 5432 já está em uso por outra instância
  • Arquivos de configuração corrompidos (erros de sintaxe no postgresql.conf)
  • Memória compartilhada insuficiente — verifique o valor de shared_buffers

Conexão Recusada

Se você receber psql: error: connection refused:

# Verificar se o PostgreSQL está em execução
sudo systemctl status postgresql

# Verificar em qual endereço e porta está escutando
sudo ss -tlnp | grep 5432

# Verificar se o pg_hba.conf permite sua conexão
sudo cat /etc/postgresql/17/main/pg_hba.conf

Autenticação Falhou

FATAL: password authentication failed for user "appuser"

Verifique a senha e o método de autenticação:

# Verificar o método de autenticação no pg_hba.conf
sudo grep -v '^#' /etc/postgresql/17/main/pg_hba.conf | grep -v '^$'

# Redefinir senha via autenticação peer
sudo -u postgres psql -c "ALTER USER appuser PASSWORD 'NewPassword123!';"

Consultas Lentas

Habilite o registro de consultas lentas:

# No postgresql.conf
log_min_duration_statement = 500  # Registrar consultas que demorem mais de 500ms

Use EXPLAIN ANALYZE para diagnosticar:

EXPLAIN ANALYZE SELECT * FROM orders WHERE customer_id = 42;

Procure por varreduras sequenciais em tabelas grandes e adicione índices onde necessário:

CREATE INDEX idx_orders_customer_id ON orders(customer_id);

Problemas de Espaço em Disco

Verifique os tamanhos dos bancos de dados:

SELECT pg_database.datname,
       pg_size_pretty(pg_database_size(pg_database.datname)) AS size
FROM pg_database
ORDER BY pg_database_size(pg_database.datname) DESC;

Encontre as maiores tabelas:

SELECT relname, pg_size_pretty(pg_total_relation_size(relid)) AS total_size
FROM pg_catalog.pg_statio_user_tables
ORDER BY pg_total_relation_size(relid) DESC
LIMIT 10;

Execute VACUUM para recuperar espaço:

sudo -u postgres vacuumdb --all --analyze

Resumo

O PostgreSQL é um banco de dados poderoso e pronto para produção que recompensa a configuração adequada. Neste guia, você aprendeu como instalar o PostgreSQL a partir do repositório oficial, configurar a autenticação com scram-sha-256, criar bancos de dados e funções, habilitar o acesso remoto com segurança, implementar estratégias de backup com pg_dump e pg_basebackup, otimizar parâmetros de desempenho para seu hardware e monitorar a atividade do banco de dados com pg_stat_activity.

Para uma abordagem completa de endurecimento do servidor, combine esta configuração com um firewall corretamente configurado — consulte nosso guia de Firewall UFW para instruções detalhadas. Você também deve revisar nossa Lista de Verificação de Segurança para Servidores Linux para garantir que toda a sua pilha de servidor siga as melhores práticas de segurança desde o nível do sistema operacional.

Próximos passos a considerar:

  • Configurar replicação em streaming para alta disponibilidade
  • Implementar pool de conexões com PgBouncer para aplicações de alto tráfego
  • Configurar conexões SSL/TLS para comunicação criptografada entre cliente e servidor
  • Explorar replicação lógica para migrações sem tempo de inatividade