La fonctionnalité de requête inter-bases de données permet de lire les données des tables internes Hologres situées dans d'autres instances et bases de données, y compris celles hébergées dans différentes régions, sans déplacer les données. Elle s'appuie sur le mécanisme PostgreSQL Foreign Data Wrapper (FDW). Pour plus d'informations sur FDW, consultez la documentation PostgreSQL FDW.
Limites
Avant de configurer les requêtes inter-bases de données, examinez les contraintes suivantes :
Les instances source et destination doivent toutes deux exécuter Hologres V1.1 ou une version ultérieure. Si votre instance utilise une version antérieure à la V1.1, consultez les Erreurs courantes lors de la préparation de la mise à niveau ou contactez le support en ligne pour obtenir de l'aide. Les requêtes inter-bases de données ne sont prises en charge qu'entre instances partageant la même version majeure ; par exemple, une instance V1.3 ne peut pas interroger une instance V1.1.
Objets source pris en charge : uniquement les tables internes et les tables parentes partitionnées. Les tables distantes, les vues et les tables enfants partitionnées ne sont pas prises en charge.
Types de données pris en charge : types de base uniquement. Les types complexes tels que
JSONne sont pas pris en charge.Opérations prises en charge sur les tables distantes :
SELECTuniquement. Les opérationsUPDATE,DELETEetTRUNCATEne sont pas prises en charge.Les adresses IP des instances Hologres ne sont pas fixes. Ne configurez pas de listes d'autorisation basées sur l'adresse IP lorsque vous utilisez cette fonctionnalité, car la connexion risque d'être interrompue en cas de changement d'adresse IP.
Types de données pris en charge
| Pris en charge | Non pris en charge |
|---|---|
INT |
JSON |
BIGINT |
Autres types complexes |
DATE |
Prérequis
Avant de commencer, vérifiez que vous disposez des éléments suivants :
Une instance Hologres exécutant la version V1.1 ou ultérieure (à la fois locale et distante)
Un accès superutilisateur à la base de données locale
Un AccessKey ID et un AccessKey Secret Alibaba Cloud pour le compte disposant de l'autorisation
SELECTsur les tables source. Obtenez-les depuis la console RAM
Configurer une requête inter-bases de données
La configuration d'une requête inter-bases de données comprend quatre étapes, suivies de l'exécution de la requête.
Étape 1 : Créer l'extension
Un superutilisateur doit exécuter l'instruction suivante une fois par base de données pour installer l'extension FDW :
CREATE EXTENSION hologres_fdw;
Pour désinstaller l'extension, exécutez DROP EXTENSION hologres_fdw;.
Étape 2 : Créer un serveur
Une fois l'extension installée, créez un objet serveur pointant vers l'instance Hologres distante :
CREATE SERVER <server_name> FOREIGN DATA WRAPPER hologres_fdw OPTIONS (
host '<endpoint>',
port '<port>',
dbname '<dbname>'
);
| Paramètre | Description | Exemple |
|---|---|---|
server_name |
Nom que vous attribuez au serveur. | holo_fdw_server |
host |
Endpoint du réseau classique (réseau interne) de l'instance Hologres distante. Vous le trouverez dans l'onglet Instance Configuration de la console Hologres. | hgpostcn-cn-xxx-cn-hangzhou-internal.hologres.aliyuncs.com |
port |
Port de l'instance Hologres distante. Vous le trouverez dans l'onglet Instance Configuration de la console Hologres. | 80 |
dbname |
Nom de la base de données distante à interroger. | testdb |
Vous pouvez créer plusieurs serveurs dans la même base de données.
Étape 3 : Créer un mappage d'utilisateur
Créez un mappage d'utilisateur pour authentifier la connexion inter-bases de données. Le compte mappé doit disposer de l'autorisation SELECT sur les tables source.
CREATE USER MAPPING FOR <account_uid> SERVER <server_name>
OPTIONS (
access_id '<access_id>',
access_key '<access_key>'
);
| Paramètre | Description |
|---|---|
account_uid |
Utilisateur local à mapper. Utilisez CURRENT_USER pour l'utilisateur de la session actuelle, ou un utilisateur RAM au format p4_<uid>. |
server_name |
Nom du serveur défini à l'étape 2. |
access_id |
AccessKey ID du compte. |
access_key |
AccessKey Secret du compte. |
Exemples :
-- 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;
Vous pouvez créer plusieurs mappages d'utilisateurs dans la même base de données.
Étape 4 : Créer une table distante
Utilisez l'une des deux méthodes suivantes pour créer une table distante. La méthode IMPORT FOREIGN SCHEMA est plus simple et recommandée dans la plupart des cas.
Méthode 1 (recommandée) : 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>' [, ...])];
| Paramètre | Description | Exemple |
|---|---|---|
holo_remote_schema |
Nom du schéma dans la base de données distante où réside la table source. | remote |
remote_table |
Nom de la table source. La table distante est créée avec le même nom dans le schéma local. | lineitem |
server_name |
Nom du serveur défini à l'étape 2. | holo_fdw_server |
holo_local_schema |
Schéma local dans lequel la table distante est créée. | local |
Options prises en charge :
| Option | Description | Valeur par défaut |
|---|---|---|
import_collate |
Inclure les paramètres de classement des colonnes. | true |
import_default |
Inclure les valeurs par défaut des colonnes. | false |
import_not_null |
Inclure les contraintes NOT NULL. |
true |
Utilisez LIMIT TO pour importer uniquement les tables nécessaires. L'importation du schéma distant complet peut être lente s'il contient de nombreuses tables.
Méthode 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>');
| Paramètre | Description | Exemple |
|---|---|---|
local_table |
Nom de la table distante à créer localement. Pour la placer dans un schéma personnalisé, utilisez le format schema.table. |
public.lineitem |
server_name |
Nom du serveur défini à l'étape 2. | holo_fdw_server |
remote_schema_name |
Nom du schéma dans la base de données distante. | public |
remote_table |
Nom de la table source dans la base de données distante. | holo_lineitem |
Étape 5 : Interroger la table distante
Une fois la table distante créée, interrogez-la directement :
SELECT * FROM <holo_local_table> LIMIT 10;
Étape 6 (facultative) : Importer les données dans une table interne locale
Si les performances de requête de la table distante ne répondent pas à vos besoins, ou si vous avez besoin d'une copie locale des données, importez-les dans une table interne Hologres :
INSERT INTO <holo_table> SELECT * FROM <holo_local_table>;
Créez la table interne cible avant d'exécuter cette instruction. Consultez la rubrique Gérer les tables internes pour plus de détails.
Gérer les serveurs et les mappages d'utilisateurs
Répertorier les serveurs
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';
Répertorier les mappages d'utilisateurs
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';
Supprimer un mappage d'utilisateur
DROP USER MAPPING FOR <account_uid> SERVER <server_name>;
Supprimer un serveur
Supprimez tous les mappages d'utilisateurs et les tables distantes associés avant de supprimer un serveur.
DROP SERVER <server_name>;
Exemples
Les exemples suivants utilisent une instance et une base de données source partagées. Exécutez toutes les instructions dans la base de données locale, c'est-à-dire celle depuis laquelle vous effectuez la requête inter-bases de données.
Configuration de l'instance source
| Configuration | Valeur |
|---|---|
| ID de l'instance source | hgpostcn-cn-i7mxxxxxxxxx |
| Base de données source | remote_db |
| Schéma source | remote |
| Table non partitionnée | lineitem |
| Table parente partitionnée | holo_dwd_product_movie_basic_info |
DDL de la table interne Hologres source
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 de la table partitionnée Hologres source
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');
Exemple 1 : Interroger une table non partitionnée
-- 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;
Exemple 2 : Interroger une table partitionnée
-- 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;
Exemple 3 : Importer les données d'une table distante dans une table interne locale
-- 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;
Dépannage
Erreur lors de l'interrogation d'un réplica en lecture seule
Si vous configurez une instance de réplica en lecture seule comme cible de requête, l'erreur suivante peut s'afficher :
internal error: Failed to get available shards for query[xxxxx], please retry later.
Exécutez l'instruction suivante à la fois dans l'instance principale du réplica en lecture seule et dans l'instance locale (initiatrice) :
ALTER DATABASE <database> SET hg_experimental_enable_dml_read_replica=ON;
Utilisez l'instance principale comme cible de requête chaque fois que possible.