Todos os produtos
Search
Central de documentação

ApsaraDB RDS:Horizontal splitting (PL/Proxy)

Última atualização: Jun 26, 2026

O PL/Proxy é uma extensão do PostgreSQL que encaminha chamadas SQL de um nó de proxy para bancos de dados remotos. No ApsaraDB RDS for PostgreSQL, use-o no modo CLUSTER para distribuir gravações entre shards ou replicar dados entre nós, ou no modo CONNECT para direcionar consultas a um banco de dados específico.

Pré-requisitos

Antes de começar, verifique se você tem:

Como funciona

O PL/Proxy opera em um nó de proxy dedicado. Quando um cliente chama uma função PL/Proxy, a extensão intercepta a chamada e a encaminha para um ou mais nós de dados conforme as regras de roteamento definidas no corpo da função.

O modo CLUSTER agrupa nós de dados em um cluster nomeado por meio da instrução SQL/MED CREATE SERVER. Cada função de proxy especifica uma cláusula RUN ON que determina o roteamento da chamada:

Cláusula

Comportamento de roteamento

RUN ON ANY

Envia a chamada para um nó de dados selecionado aleatoriamente

RUN ON ALL

Transmite a chamada para todos os nós de dados (ideal para replicação SQL ou leituras entre shards)

O modo CONNECT dispensa a configuração de cluster. Cada função incorpora diretamente uma string de conexão e direciona a consulta para um banco de dados de destino fixo.

Observações de uso

  • Instâncias RDS na mesma Virtual Private Cloud (VPC) acessam umas às outras diretamente.

  • Para rotear consultas entre instâncias RDS em VPCs diferentes, use uma instância Elastic Compute Service (ECS) na mesma VPC como proxy intermediário.

  • A quantidade de nós de dados em um CLUSTER deve ser uma potência de 2 (2, 4, 8, etc.).

Instale a extensão

Conecte-se ao banco de dados do nó de proxy e execute:

CREATE EXTENSION plproxy;

Configure um CLUSTER (apenas modo CLUSTER)

Ignore esta seção se estiver usando o modo CONNECT.

Defina o cluster via CREATE SERVER. Registre cada nó de dados como uma opção (p0, p1, e assim por diante). O número de opções deve ser uma potência de 2.

  1. Crie o servidor do cluster e registre seus nós de dados:

    CREATE SERVER cluster_srv1 FOREIGN DATA WRAPPER plproxy
    OPTIONS (
        connection_lifetime '1800',
        disable_binary '1',
        p0 'dbname=pl_db0 host=100.xxx.xxx.72 port=5678',
        p1 'dbname=pl_db1 host=11.xxx.xxx.9 port=5678'
    );
  2. Conceda acesso ao cluster:

    GRANT USAGE ON FOREIGN SERVER cluster_srv1 TO postgres;
  3. Crie um mapeamento de usuário para que o PL/Proxy possa autenticar-se nos nós de dados:

    CREATE USER MAPPING FOR postgres SERVER cluster_srv1 OPTIONS (user 'postgres');

Configuração de teste

As seções a seguir usam três instâncias RDS para demonstrar ambos os modos.

IP

Função

Banco de dados

Nome de usuário

100.xx.xx.136

Nó de proxy

postgres

postgres

100.xx.xx.72

Nó de dados

pl_db0

postgres

11.xx.xx.9

Nó de dados

pl_db1

postgres

Crie uma tabela users em cada nó de dados:

CREATE TABLE users (userid int, name text);

Teste o modo CLUSTER

Sharding horizontal

A cláusula RUN ON ANY roteia cada INSERT aleatoriamente para um dos nós de dados e distribui as gravações pelo cluster.

  1. Crie a função insert_user em cada nó de dados:

    CREATE OR REPLACE FUNCTION insert_user(i_id int, i_name text)
    RETURNS integer AS $$
        INSERT INTO users (userid, name) VALUES ($1, $2);
        SELECT 1;
    $$ LANGUAGE SQL;
  2. Crie a função de proxy no nó de proxy. O PL/Proxy associa chamadas pelo nome da função; portanto, a função de proxy e a função do nó de dados devem ter o mesmo nome.

    CREATE OR REPLACE FUNCTION insert_user(i_id int, i_name text)
    RETURNS integer AS $$
        CLUSTER 'cluster_srv1';
        RUN ON ANY;
    $$ LANGUAGE plproxy;
  3. Crie uma função de leitura no nó de proxy. A instrução RUN ON ALL consulta todos os nós de dados e mescla os resultados.

    CREATE OR REPLACE FUNCTION get_user_name()
    RETURNS TABLE(userid int, name text) AS $$
        CLUSTER 'cluster_srv1';
        RUN ON ALL;
        SELECT userid, name FROM users;
    $$ LANGUAGE plproxy;
  4. Insira 10 registros a partir do nó de proxy:

    SELECT insert_user(1001, 'Sven');
    SELECT insert_user(1002, 'Marko');
    SELECT insert_user(1003, 'Steve');
    SELECT insert_user(1004, 'lottu');
    SELECT insert_user(1005, 'rax');
    SELECT insert_user(1006, 'ak');
    SELECT insert_user(1007, 'jack');
    SELECT insert_user(1008, 'molica');
    SELECT insert_user(1009, 'pg');
    SELECT insert_user(1010, 'oracle');
  5. Consulte cada nó de dados para verificar a distribuição dos dados:

    Como RUN ON ANY roteia gravações aleatoriamente, a distribuição é desigual.
    -- On pl_db0
    SELECT * FROM users;
     userid |  name
    --------+--------
       1001 | Sven
       1003 | Steve
       1004 | lottu
       1005 | rax
       1006 | ak
       1007 | jack
       1008 | molica
       1009 | pg
    (8 rows)
    
    -- On pl_db1
    SELECT * FROM users;
     userid |  name
    --------+--------
       1002 | Marko
       1010 | oracle
    (2 rows)
  6. Leia todas as linhas pelo nó de proxy:

    SELECT userid, name FROM get_user_name();
     userid |  name
    --------+--------
       1001 | Sven
       1003 | Steve
       1004 | lottu
       1005 | rax
       1006 | ak
       1007 | jack
       1008 | molica
       1009 | pg
       1002 | Marko
       1010 | oracle
    (10 rows)

Replicação SQL

A diretiva RUN ON ALL transmite cada gravação para todos os nós de dados e os mantém sincronizados.

  1. Crie uma função trunc_user em cada nó de dados e também no nó de proxy:

    -- On pl_db0 and pl_db1
    CREATE OR REPLACE FUNCTION trunc_user()
    RETURNS integer AS $$
        TRUNCATE TABLE users;
        SELECT 1;
    $$ LANGUAGE SQL;
    
    -- On the proxy node
    CREATE OR REPLACE FUNCTION trunc_user()
    RETURNS SETOF integer AS $$
        CLUSTER 'cluster_srv1';
        RUN ON ALL;
    $$ LANGUAGE plproxy;
  2. Trunque a tabela em todos os nós:

    SELECT trunc_user();
     trunc_user
    ------------
              1
              1
    (2 rows)
  3. Crie a função de inserção com replicação no nó de proxy. O parâmetro TARGET insert_user instrui o PL/Proxy a chamar a função insert_user (já definida nos nós de dados) em cada nó:

    CREATE OR REPLACE FUNCTION insert_user_2(i_id int, i_name text)
    RETURNS SETOF integer AS $$
        CLUSTER 'cluster_srv1';
        RUN ON ALL;
        TARGET insert_user;
    $$ LANGUAGE plproxy;
  4. Insira 4 registros:

    SELECT insert_user_2(1004, 'lottu');
    SELECT insert_user_2(1005, 'rax');
    SELECT insert_user_2(1006, 'ak');
    SELECT insert_user_2(1007, 'jack');
  5. Verifique se ambos os nós de dados contêm dados idênticos:

    -- On pl_db0
    SELECT * FROM users;
     userid | name
    --------+-------
       1004 | lottu
       1005 | rax
       1006 | ak
       1007 | jack
    (4 rows)
    
    -- On pl_db1
    SELECT * FROM users;
     userid | name
    --------+-------
       1004 | lottu
       1005 | rax
       1006 | ak
       1007 | jack
    (4 rows)
  6. Leia os dados pelo nó de proxy usando RUN ON ANY — como todos os nós possuem dados idênticos, qualquer um deles retorna o resultado completo:

    CREATE OR REPLACE FUNCTION get_user_name_2()
    RETURNS TABLE(userid int, name text) AS $$
        CLUSTER 'cluster_srv1';
        RUN ON ANY;
        SELECT userid, name FROM users;
    $$ LANGUAGE plproxy;
    
    SELECT userid, name FROM get_user_name_2();
     userid | name
    --------+-------
       1004 | lottu
       1005 | rax
       1006 | ak
       1007 | jack
    (4 rows)

Teste o modo CONNECT

O modo CONNECT direciona uma consulta para um único banco de dados especificado, sem exigir configuração de cluster. Incorpore a string de conexão diretamente na função.

CREATE OR REPLACE FUNCTION get_user_name_3()
RETURNS TABLE(userid int, name text) AS $$
    CONNECT 'dbname=pl_db0 host=100.81.137.72 port=56789';
    SELECT userid, name FROM users;
$$ LANGUAGE plproxy;

SELECT userid, name FROM get_user_name_3();
 userid | name
--------+-------
   1004 | lottu
   1005 | rax
   1006 | ak
   1007 | jack
(4 rows)

Escolha um modo

Modo CLUSTER

Modo CONNECT

Indicado quando

Você precisa de sharding horizontal ou deseja replicar gravações entre nós

É necessário consultar um banco de dados remoto específico via string de conexão

Configuração de cluster necessária

Sim (CREATE SERVER, mapeamento de usuário)

Não

Restrição de quantidade de nós de dados

Deve ser uma potência de 2

Nenhuma

Roteamento

RUN ON ANY (aleatório) ou RUN ON ALL (broadcast)

String de conexão fixa por função

Caso de uso típico

Distribuição de grandes conjuntos de dados entre várias instâncias RDS

Consultas entre instâncias ou federação ad-hoc

Próximos passos