A consulta entre bancos de dados permite ler dados de tabelas internas do Hologres em outras instâncias e bancos de dados — inclusive em regiões diferentes — sem mover os dados. Esse recurso utiliza o mecanismo de foreign data wrapper (FDW) do PostgreSQL. Para mais informações sobre FDW, consulte a documentação do PostgreSQL FDW.
Limitações
Antes de configurar consultas entre bancos de dados, verifique as seguintes restrições:
O Hologres V1.1 ou superior é obrigatório tanto na instância de origem quanto na de destino. Se sua instância estiver em uma versão anterior à V1.1, consulte Erros comuns de falha na preparação de upgrade ou solicite suporte online para obter assistência na atualização. As consultas entre bancos de dados funcionam apenas entre instâncias da mesma versão principal. Por exemplo, uma instância V1.3 não pode consultar uma instância V1.1.
Objetos de origem compatíveis: apenas tabelas internas e tabelas pai particionadas. Tabelas externas, views e tabelas filho particionadas não são compatíveis.
Tipos de dados compatíveis: somente tipos básicos. Tipos complexos, como
JSON, não são aceitos.Operações permitidas em tabelas externas: exclusivamente
SELECT. Os comandosUPDATE,DELETEeTRUNCATEnão são suportados.Os endereços IP das instâncias Hologres não são fixos. Não configure listas de permissões de endereços IP ao utilizar este recurso, pois a conexão poderá ser interrompida caso o IP seja alterado.
Tipos de dados compatíveis
|
Compatíveis |
Não compatíveis |
|
|
|
|
|
Outros tipos complexos |
|
|
Pré-requisitos
Antes de começar, certifique-se de ter:
Uma instância Hologres executando a versão V1.1 ou superior (tanto local quanto remota).
Acesso de superusuário ao banco de dados local.
Um AccessKey ID e um AccessKey secret da Alibaba Cloud para a conta com permissão de
SELECTnas tabelas de origem. Obtenha-os no console RAM.
Configurar consulta entre bancos de dados
A configuração de uma consulta entre bancos de dados envolve quatro etapas, seguidas pela execução da consulta.
Etapa 1: Criar a extensão
Um superusuário deve executar a seguinte instrução uma vez por banco de dados para instalar a extensão FDW:
CREATE EXTENSION hologres_fdw;
Para desinstalar a extensão, execute DROP EXTENSION hologres_fdw;.
Etapa 2: Criar um servidor
Após instalar a extensão, crie um objeto de servidor que aponte para a instância remota do Hologres:
CREATE SERVER <server_name> FOREIGN DATA WRAPPER hologres_fdw OPTIONS (
host '<endpoint>',
port '<port>',
dbname '<dbname>'
);
|
Parâmetro |
Descrição |
Exemplo |
|
|
Nome atribuído ao servidor. |
|
|
|
Endpoint de rede clássica (rede interna) da instância remota do Hologres. Encontre-o na aba Instance Configuration no console do Hologres. |
|
|
|
Porta da instância remota do Hologres. Disponível na aba Instance Configuration do console do Hologres. |
|
|
|
Nome do banco de dados remoto a ser consultado. |
|
É possível criar vários servidores no mesmo banco de dados.
Etapa 3: Criar um mapeamento de usuário
Crie um mapeamento de usuário para autenticar a conexão entre bancos de dados. A conta mapeada precisa ter permissão de SELECT nas tabelas de origem.
CREATE USER MAPPING FOR <account_uid> SERVER <server_name>
OPTIONS (
access_id '<access_id>',
access_key '<access_key>'
);
|
Parâmetro |
Descrição |
|
|
Usuário local a ser mapeado. Utilize |
|
|
Nome do servidor definido na etapa 2. |
|
|
AccessKey ID da conta. |
|
|
AccessKey secret da conta. |
Exemplos:
-- Map the current user.
CREATE USER MAPPING FOR CURRENT_USER SERVER holo_fdw_server OPTIONS (
access_id 'yourAccessKeyId',
access_key 'yourAccessKeySecret'
);
-- Map a RAM user.
CREATE USER MAPPING FOR "p4_123xxx" SERVER holo_fdw_server OPTIONS (
access_id 'yourAccessKeyId',
access_key 'yourAccessKeySecret'
);
-- Remove a user mapping.
DROP USER MAPPING FOR CURRENT_USER SERVER holo_fdw_server;
DROP USER MAPPING FOR "p4_123xxx" SERVER holo_fdw_server;
É possível criar vários mapeamentos de usuário no mesmo banco de dados.
Etapa 4: Criar uma tabela externa
Utilize um dos dois métodos abaixo para criar uma tabela externa. O método IMPORT FOREIGN SCHEMA é mais simples e recomendado para a maioria dos casos.
Método 1 (recomendado): IMPORT FOREIGN SCHEMA
IMPORT FOREIGN SCHEMA <holo_remote_schema>
[{ LIMIT TO | EXCEPT } (<remote_table> [, ...])]
FROM SERVER <server_name>
INTO <holo_local_schema>
[OPTIONS (<option> '<value>' [, ...])];
|
Parâmetro |
Descrição |
Exemplo |
|
|
Nome do schema no banco de dados remoto onde a tabela de origem está localizada. |
|
|
|
Nome da tabela de origem. A tabela externa será criada com o mesmo nome no schema local. |
|
|
|
Nome do servidor configurado na etapa 2. |
|
|
|
Schema local onde a tabela externa será criada. |
|
Opções suportadas:
|
Opção |
Descrição |
Padrão |
|
|
Incluir configurações de collation das colunas. |
|
|
|
Incluir valores padrão das colunas. |
|
|
|
Incluir restrições |
|
Utilize LIMIT TO para importar apenas as tabelas necessárias. Importar todo o schema remoto pode ser lento se ele contiver muitas tabelas.
Método 2: CREATE FOREIGN TABLE
CREATE FOREIGN TABLE <local_table> (
col_name type,
...
) SERVER <server_name>
OPTIONS (schema_name '<remote_schema_name>', table_name '<remote_table>');
|
Parâmetro |
Descrição |
Exemplo |
|
|
Nome da tabela externa a ser criada localmente. Para colocá-la em um schema personalizado, use o formato |
|
|
|
Nome do servidor definido na etapa 2. |
|
|
|
Nome do schema no banco de dados remoto. |
|
|
|
Nome da tabela de origem no banco de dados remoto. |
|
Etapa 5: Consultar a tabela externa
Após criar a tabela externa, consulte-a diretamente:
SELECT * FROM <holo_local_table> LIMIT 10;
Etapa 6 (opcional): Importar dados para uma tabela interna local
Se o desempenho da consulta à tabela externa não atender às suas necessidades ou se você precisar de uma cópia local dos dados, importe-os para uma tabela interna do Hologres:
INSERT INTO <holo_table> SELECT * FROM <holo_local_table>;
Crie a tabela interna de destino antes de executar esta instrução. Consulte Gerenciar tabelas internas para mais detalhes.
Gerenciar servidores e mapeamentos de usuário
Listar servidores
SELECT
s.srvname AS "Name",
pg_catalog.pg_get_userbyid(s.srvowner) AS "Owner",
f.fdwname AS "Foreign-data wrapper",
pg_catalog.array_to_string(s.srvacl, E'\n') AS "Access privileges",
s.srvtype AS "Type",
s.srvversion AS "Version",
CASE WHEN srvoptions IS NULL THEN
''
ELSE
'(' || pg_catalog.array_to_string(ARRAY (
SELECT
pg_catalog.quote_ident(option_name) || ' ' || pg_catalog.quote_literal(option_value)
FROM pg_catalog.pg_options_to_table(srvoptions)), ', ') || ')'
END AS "FDW options",
d.description AS "Description"
FROM
pg_catalog.pg_foreign_server s
JOIN pg_catalog.pg_foreign_data_wrapper f ON f.oid = s.srvfdw
LEFT JOIN pg_catalog.pg_description d ON d.classoid = s.tableoid
AND d.objoid = s.oid
AND d.objsubid = 0
WHERE
f.fdwname = 'hologres_fdw';
Listar mapeamentos de usuário
SELECT
um.srvname AS "Server",
um.usename AS "User name",
CASE WHEN umoptions IS NULL THEN
''
ELSE
'(' || pg_catalog.array_to_string(ARRAY (
SELECT
pg_catalog.quote_ident(option_name) || ' ' || pg_catalog.quote_literal(option_value)
FROM pg_catalog.pg_options_to_table(umoptions)), ', ') || ')'
END AS "FDW options"
FROM
pg_catalog.pg_user_mappings um
WHERE
um.srvname != 'query_log_store_server';
Excluir um mapeamento de usuário
DROP USER MAPPING FOR <account_uid> SERVER <server_name>;
Excluir um servidor
Exclua todos os mapeamentos de usuário e tabelas externas relacionados antes de remover um servidor.
DROP SERVER <server_name>;
Exemplos
Os exemplos a seguir utilizam uma instância e um banco de dados de origem compartilhados. Execute todas as instruções no banco de dados local — aquele onde você realiza a consulta entre bancos de dados.
Configuração da instância de origem
|
Configuração |
Valor |
|
ID da instância de origem |
|
|
Banco de dados de origem |
|
|
Schema de origem |
|
|
Tabela não particionada |
|
|
Tabela pai particionada |
|
DDL da tabela interna de origem do Hologres
BEGIN;
CREATE SCHEMA remote;
CREATE TABLE "remote"."lineitem" (
"l_orderkey" int8 NOT NULL,
"l_linenumber" int8 NOT NULL,
"l_suppkey" int8 NOT NULL,
"l_partkey" int8 NOT NULL,
"l_quantity" int8 NOT NULL,
"l_extendedprice" int8 NOT NULL,
"l_discount" int8 NOT NULL,
"l_tax" int8 NOT NULL,
"l_returnflag" text NOT NULL,
"l_linestatus" text NOT NULL,
"l_shipdate" timestamptz NOT NULL,
"l_commitdate" timestamptz NOT NULL,
"l_receiptdate" timestamptz NOT NULL,
"l_shipinstruct" text NOT NULL,
"l_shipmode" text NOT NULL,
"l_comment" text NOT NULL
);
COMMIT;
DDL da tabela particionada de origem do Hologres
BEGIN;
CREATE TABLE "remote"."holo_dwd_product_movie_basic_info" (
"movie_name" text,
"director" text,
"scriptwriter" text,
"area" text,
"actors" text,
"type" text,
"movie_length" text,
"movie_date" text,
"movie_language" text,
"imdb_url" text,
"ds" text
)
PARTITION BY LIST (ds);
COMMIT;
-- Create a partition for '20170122'.
CREATE TABLE IF NOT EXISTS "remote".holo_dwd_product_movie_basic_info_20170122
PARTITION OF "remote".holo_dwd_product_movie_basic_info
FOR VALUES IN ('20170122');
Exemplo 1: Consultar uma tabela não particionada
-- Run as a superuser in the local database.
-- Step 1: Install the extension.
CREATE EXTENSION hologres_fdw;
-- Step 2: Create a server pointing to the remote instance.
CREATE SERVER holo_fdw_server FOREIGN DATA WRAPPER hologres_fdw OPTIONS (
host 'hgpostcn-cn-i7mxxxxxxxxx-cn-hangzhou-internal.hologres.aliyuncs.com',
port '80',
dbname 'remote_db'
);
-- Step 3: Create a user mapping for the current user.
CREATE USER MAPPING FOR CURRENT_USER SERVER holo_fdw_server
OPTIONS (access_id 'yourAccessKeyId', access_key 'yourAccessKeySecret');
-- Step 4: Create a local schema and import the foreign table.
CREATE SCHEMA local;
IMPORT FOREIGN SCHEMA remote
LIMIT TO (lineitem)
FROM SERVER holo_fdw_server
INTO local
OPTIONS (import_not_null 'true');
-- Step 5: Query the foreign table.
SELECT * FROM local.lineitem LIMIT 10;
Exemplo 2: Consultar uma tabela particionada
-- Run as a superuser in the local database.
CREATE EXTENSION hologres_fdw;
CREATE SERVER holo_fdw_server FOREIGN DATA WRAPPER hologres_fdw OPTIONS (
host 'hgpostcn-cn-i7mxxxxxxxxx-cn-hangzhou-internal.hologres.aliyuncs.com',
port '80',
dbname 'remote_db'
);
CREATE USER MAPPING FOR CURRENT_USER SERVER holo_fdw_server
OPTIONS (access_id 'yourAccessKeyId', access_key 'yourAccessKeySecret');
CREATE SCHEMA local;
-- Import the partitioned parent table (child tables are included automatically).
IMPORT FOREIGN SCHEMA remote
LIMIT TO (holo_dwd_product_movie_basic_info)
FROM SERVER holo_fdw_server
INTO local
OPTIONS (import_not_null 'true');
SELECT * FROM local.holo_dwd_product_movie_basic_info LIMIT 10;
Exemplo 3: Importar dados de uma tabela externa para uma tabela interna local
-- Create a local schema.
CREATE SCHEMA local;
-- Create the target internal table.
BEGIN;
CREATE TABLE "local"."dwd_product_movie_basic_info" (
"movie_name" text,
"director" text,
"scriptwriter" text,
"area" text,
"actors" text,
"type" text,
"movie_length" text,
"movie_date" text,
"movie_language" text,
"imdb_url" text,
"ds" text
);
COMMIT;
-- Copy data from the foreign table into the internal table.
INSERT INTO local.dwd_product_movie_basic_info
SELECT * FROM local.holo_dwd_product_movie_basic_info;
Solução de problemas
Erro ao consultar uma réplica somente leitura
Se você configurar uma instância de réplica somente leitura como alvo da consulta, poderá encontrar o seguinte erro:
internal error: Failed to get available shards for query[xxxxx], please retry later.
Execute a seguinte instrução tanto na instância primária da réplica somente leitura quanto na instância local (iniciadora):
ALTER DATABASE <database> SET hg_experimental_enable_dml_read_replica=ON;
Sempre que possível, utilize a instância primária como alvo da consulta.