Compartilhar via


Mensagens de erro comuns

Ao trabalhar com bancos de dados distribuídos do Citus, você pode encontrar mensagens de erro relacionadas a conexões, transações, restrições e operações distribuídas. Este guia de referência fornece explicações e resoluções para os erros mais comuns encontrados durante o desenvolvimento e o uso da produção. Entender esses erros ajuda você a solucionar problemas e criar aplicativos distribuídos robustos.

Não foi possível receber resultados da consulta

Esse erro ocorre quando o nó coordenador não pode se conectar a um nó de trabalho.

SELECT 1 FROM companies WHERE id = 2928;

ERRO: a conexão com o localhost do nó remoto:5432 falhou com o seguinte erro: não foi possível se conectar ao servidor: a conexão recusada É o servidor em execução no host "localhost" (127.0.0.1) e aceitando conexões TCP/IP na porta 5432?

Resolução

Para corrigir esse erro, verifique se o nó de trabalho aceita conexões e se o DNS do Azure é resolvido corretamente.

Cancelando a transação desde que ela estava envolvida em um deadlock distribuído

Deadlocks podem ocorrer não apenas em um banco de dados de nó único, mas também em um banco de dados distribuído. Consultas executadas em vários nós podem causar deadlocks. O Citus reconhece deadlocks distribuídos e os desarma anulando uma das consultas envolvidas.

Você pode ver esse comportamento distribuindo linhas entre nós de trabalho e executando duas transações simultâneas com atualizações conflitantes:

CREATE TABLE lockme (id int, x int);
SELECT create_distributed_table('lockme', 'id');

-- id=1 goes to one worker, and id=2 another
INSERT INTO lockme VALUES (1,1), (2,2);

--------------- TX 1 ----------------  --------------- TX 2 ----------------
BEGIN;
                                       BEGIN;
UPDATE lockme SET x = 3 WHERE id = 1;
                                       UPDATE lockme SET x = 4 WHERE id = 2;
UPDATE lockme SET x = 3 WHERE id = 2;
                                       UPDATE lockme SET x = 4 WHERE id = 1;

ERRO: cancelando a transação desde que ela estava envolvida em um deadlock distribuído

Resolução

Detectar deadlocks e pará-los faz parte do tratamento normal de transações distribuídas. Ele permite que um aplicativo repita consultas ou siga outro curso de ação.

Não foi possível se conectar ao servidor: não é possível atribuir o endereço solicitado

WARNING: connection error: localhost:9703
DETAIL: could not connect to server: Cannot assign requested address

Esse erro ocorre quando não há mais soquetes disponíveis pelos quais o coordenador pode responder às solicitações de trabalho.

Resolução

Configure o sistema operacional para reutilizar soquetes TCP. Execute esta resolução no shell no nó coordenador:

sysctl -w net.ipv4.tcp_tw_reuse=1

Essa resolução permite reutilizando soquetes em TIME_WAIT estado para novas conexões quando estiver seguro em um ponto de vista de protocolo. O valor padrão é 0 (desabilitado).

Erro SSL: falha na verificação de certificado

A partir do Citus 8.1, os nós são necessários para conversar uns com os outros usando SSL por padrão. Se o SSL não estiver habilitado em um servidor PostgreSQL quando o Citus for instalado pela primeira vez, o processo de instalação o habilitará. Essa habilitação inclui a criação e a auto-assinatura de um certificado SSL.

No entanto, se houver um arquivo de autoridade de certificação raiz (normalmente em ~/.postgresql/root.crt), o certificado será verificado sem sucesso em relação a essa AC no momento da conexão. A documentação do PostgreSQL sobre o suporte a SSL avisa:

Para compatibilidade com versões anteriores do PostgreSQL, se houver um arquivo de AC raiz, o comportamento de sslmode=require será o mesmo que o de verify-ca, o que significa que o certificado do servidor será validado na AC. Depender desse comportamento é desencorajado e os aplicativos que precisam de validação de certificado sempre devem usar verify-ca ou verify-full.

Resolução

As soluções possíveis são assinar o certificado, desativar o SSL ou remover o certificado raiz. Além disso, um nó pode ter problemas para se conectar a si mesmo sem a ajuda de local_hostname.

Não foi possível se conectar a nenhum posicionamento ativo

Quando todos os slots de conexão de trabalho disponíveis estiverem em uso, novas conexões falharão.

WARNING: connection error: hostname:5432
ERROR: could not connect to any active placements

Resolução

Esse erro ocorre com mais frequência ao copiar dados para o Citus em paralelo. O comando COPY abre uma conexão por fragmento. Executar cópias simultâneas M em um destino com N fragmentos resulta em conexões M*N. Para resolver o erro, reduza a contagem de fragmentos de tabelas distribuídas de destino ou execute menos \copy comandos em paralelo.

Os slots de conexão restantes são reservados para conexões de superusuário de não duplicação

Esse erro ocorre quando o PostgreSQL fica sem conexões disponíveis para atender a solicitações de cliente simultâneas.

Resolução

O MAX_CONNECTIONS GUC ajusta o limite, com um padrão típico de 100 conexões. Cada conexão consome recursos, portanto, ajuste de forma sensata. Ao aumentar max_connections, você também deve aumentar os limites de memória .

O PgBouncer também pode ajudar na fila de solicitações de conexão que excedem o limite de conexão. (Nossa cloud_topic instância interna do PgBouncer.)

O PgBouncer não pode se conectar ao servidor

Em um cluster Citus auto-hospedado, esse erro indica que o nó coordenador não está respondendo ao PgBouncer.

Resolução

Para garantir que o servidor esteja executando e aceitando conexões, tente se conectar diretamente ao servidor com psql.

A relação foo não é distribuída

Esse erro não ocorre mais na versão atual do Citus. Isso foi causado pela tentativa de unir tabelas locais e distribuídas na mesma consulta.

Resolução

Atualize para o Citus 10.0 ou superior.

Tipo de cláusula sem suporte

Esse erro não ocorre mais na versão atual do Citus. Isso costumava acontecer ao executar uma junção com uma condição de desigualdade:

SELECT *
 FROM identified_event ie
 JOIN field_calculator_watermark w ON ie.org_id = w.org_id
WHERE w.org_id = 42
  AND ie.version > w.version
LIMIT 10;

ERRO: tipo de cláusula sem suporte

Resolução

Atualize para o Citus 7.2 ou superior.

Não é possível abrir novas conexões após o primeiro comando de modificação dentro de uma transação

Esse erro não ocorre mais na versão atual do Citus, exceto em determinados cenários incomuns de reparo de fragmentos. Isso costumava acontecer ao atualizar linhas em uma transação e, em seguida, executar outro comando, o que abriria novas conexões de coordenador para trabalho.

BEGIN;
-- run modification command that uses one connection
DELETE FROM http_request
 WHERE site_id = 8
   AND ingest_time < now() - '1 week'::interval;

-- now run a query that opens connections to more workers
SELECT count(*) FROM http_request;
ERROR: cannot open new connections after the first modification command within a transaction

Resolução

Atualize para o Citus 7.2 ou superior.

Não é possível criar restrição de exclusividade

Como um sistema distribuído, o Citus só poderá garantir a exclusividade se uma restrição de chave primária ou índice exclusivo incluir a coluna de distribuição de uma tabela. Os fragmentos são divididos para que cada fragmento contenha valores de coluna de partição não sobrepostos. O índice em cada nó de trabalho pode impor localmente sua parte da restrição.

Tentar criar um índice exclusivo em uma coluna de não distribuição gera um erro:

ERROR: creating unique indexes on non-partition columns is currently unsupported

Impor a exclusividade em uma coluna de não distribuição exigiria que Citus verificasse cada fragmento em cada INSERT para validar, o que derrota a meta de escalabilidade.

Resolução

Há duas maneiras de impor a exclusividade em uma coluna de não distribuição:

  • Crie um índice exclusivo composto ou uma chave primária que inclua a coluna desejada (C), mas também inclui a coluna de distribuição (D). Essa resolução não é uma condição tão forte quanto a exclusividade apenas em C , mas garante que os valores de C sejam exclusivos para cada valor de D. Por exemplo, se a distribuição por company_id meio de um sistema multilocatário, essa abordagem tornaria C exclusivo em cada empresa.
  • Use uma tabela de referência em vez de uma tabela distribuída de hash. Essa resolução só é adequada para tabelas pequenas, pois o conteúdo da tabela de referência é duplicado em todos os nós.

O create_distributed_table de função não existe

SELECT create_distributed_table('foo', 'id');
/*
ERROR:  function create_distributed_table(unknown, unknown) does not exist
LINE 1: SELECT create_distributed_table('foo', 'id');
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
*/

Resolução

Quando o básico user_defined_functions não estiver disponível, verifique se a extensão citus está instalada corretamente. A execução \dx no psql lista as extensões instaladas.

Uma maneira de acabar sem extensões é criando um novo banco de dados em um servidor PostgreSQL, que exige que as extensões sejam reinstaladas. Veja create_db como fazer isso direito.

Funções ESTÁVEIS usadas em consultas UPDATE não podem ser chamadas com referências de coluna

Cada função PostgreSQL é marcada com uma volatilidade, o que indica se a função pode atualizar o banco de dados e se o valor retornado da função pode variar ao longo do tempo dadas as mesmas entradas. Uma STABLE função é garantida para retornar os mesmos resultados, considerando os mesmos argumentos para todas as linhas em uma única instrução, enquanto uma IMMUTABLE função tem a garantia de retornar os mesmos resultados, considerando os mesmos argumentos para sempre.

As funções não imutáveis podem ser inconvenientes em sistemas distribuídos porque podem introduzir alterações sutis quando executadas em momentos ligeiramente diferentes entre fragmentos. As diferenças na configuração do banco de dados entre nós também podem interagir prejudicialmente com funções não imutáveis.

Uma das maneiras mais comuns de esse problema ocorrer é usando o timestamp tipo no PostgreSQL, que diferentemente timestamptz de não mantém um registro de fuso horário. Interpretar uma coluna de carimbo de data/hora faz referência ao fuso horário do banco de dados, que pode ser alterado entre consultas, portanto, as funções que operam em carimbos de data/hora não são imutáveis.

O Citus não permite consultas distribuídas que filtram resultados usando funções estáveis em colunas. Por exemplo:

-- foo_timestamp is timestamp, not timestamptz
UPDATE foo SET ... WHERE foo_timestamp < now();
ERROR: STABLE functions used in UPDATE queries cannot be called with column references

Nesse caso, o operador < de comparação entre o carimbo de data/hora e o carimbo de data/hora não é imutável.

Resolução

Evite funções estáveis em colunas em uma instrução UPDATE distribuída. Em particular, sempre que trabalhar com horários, use timestamptz em vez de timestamp. Ter um fuso horário no carimbo de data/hora torna os cálculos imutáveis.