Sources SQL en mode query
Tables SQL distantes, portée exacte des catalogues et exécution gouvernée
Une source avec ingest.mode: 'query' expose les tables distantes déclarées dans un catalogue JDBC StarRocks. Un champ facultatif ingest.intervalSec au niveau de la source, d’au moins 60 secondes, planifie aussi une copie gérée de chaque table déclarée. Sans intervalle, les sources existantes restent limitées aux requêtes directes. La source installée doit disposer d’une inscription active à jour et d’identifiants de connexion utilisables pour apparaître dans l’explorateur de catalogues Analytics.
Utilisez les coordonnées complètes du catalogue, du schéma et de la table affichées dans Remote SQL catalogs, par exemple SELECT * FROM query_example.public.ports LIMIT 20. Chaque catalogue appartient à une seule organisation, un espace de travail, un environnement et une source. Un nom provenant d’une autre portée est refusé. Seules les tables déclarées par la source sont accessibles ; une table distante portant le même nom ne suffit pas.
Toutes les références sont vérifiées, y compris les jointures, les corps des CTE et les sous-requêtes. Seules les instructions SELECT uniques sont prises en charge. Les écritures, fonctions de table, lectures avec verrouillage et exports de fichiers sont refusés. Les références aux tables gérées passent par le registre de l’environnement sélectionné et ses vues gouvernées. Les bases physiques arbitraires, références non résolues et formes groupées de FROM non prises en charge sont refusées. Les lectures impliquant des tables gérées nécessitent l’activation de la gouvernance native ; les lectures portant uniquement sur des catalogues distants inscrits utilisent l’autorisation centrale fondée sur la classification. Les tables de notebook s’exécutent actuellement séparément des requêtes sur les tables gérées et les catalogues distants. Les plans de requête approfondis d’Analyst prennent uniquement en charge les tables de notebook.
Les classifications utilisent le schéma actif de l’organisation. Une table déclarée sans étiquette utilise le rang par défaut de l’organisation pour les données non étiquetées ; elle n’accorde pas un accès illimité. Les étiquettes inconnues ou ambiguës sont refusées. L’appelant doit réellement être membre de l’organisation et avoir accès à l’espace de travail, ou disposer de l’autorité d’administrateur de l’organisation, ainsi que d’une habilitation effective suffisante. Ces vérifications s’exécutent dans le service central d’autorisation ; l’autorité d’administrateur ne contourne pas l’habilitation.
Les administrateurs de l’organisation peuvent définir ou supprimer une classification de remplacement via PATCH /query-catalogs/{catalogName}/classification, avec workspaceEnvironmentId, schemaName, tableName, une classification pouvant être nulle et le champ facultatif clearOverride. L’étiquette effective actuelle et l’étiquette proposée doivent toutes deux respecter l’habilitation de l’administrateur. La suppression rétablit l’étiquette du manifeste. La modification est auditée.
La mise en pause, la suppression de la source, les changements de descripteur, la rotation des identifiants et les générations obsolètes révoquent les nouvelles lectures jusqu’à ce que l’inscription actuelle soit à nouveau active. Ces changements ne garantissent pas l’annulation immédiate d’une requête déjà en cours.
Les résultats sont limités à 1 000 lignes et à 8 MiB de données de lignes sérialisées. Un LIMIT explicite supérieur ne peut pas contourner la limite de lignes. Chaque requête dispose du délai configuré dans API Table et d’un délai côté moteur. L’annulation de la requête ferme sa propre connexion de pilote ; le travail dans la base distante peut prendre davantage de temps à s’arrêter. Les limites de concurrence s’appliquent à chaque processus API Table. Les résultats trop volumineux et l’indisponibilité de l’autorisation produisent des erreurs plutôt qu’un résultat vide réussi.
Endpoint fourni par une connexion
ingest.endpoint écrit soit l'hôte, le port, la base de données et trustedCaRef dans le
manifeste, soit désigne les champs de connexion qui les contiennent :
endpoint: { endpointRefs: { host: 'dbHost', port: 'dbPort', database: 'dbName' }, trustedCaRef: 'partner-ca' }.
Chaque champ désigné est un champ de configuration type: 'text' déclaré par l'extension, et
chaque valeur est soumise à la même règle qu'une valeur littérale. L'ancre de confiance peut
aussi venir d'un champ (endpointRefs.trustedCaRef), mais elle est désignée exactement une fois ;
TLS vérifie toujours l'identité du serveur. Le credentialRef de la source désigne un identifiant
basicAuth de l'extension. Voir Endpoints fournis par une connexion.
Tables choisies à l'installation
Définissez ingest.selectable: true pour que la personne qui ajoute la source choisisse
ses tables au lieu de les lister dans le manifeste. tables peut alors être vide (ou
contenir un premier choix suggéré). Chaque source installée est une copie distincte avec
ses propres tables : une copie supplémentaire de la source démarre sans aucune table, et
une nouvelle version de l'extension conserve le choix de chaque copie installée tant que
la version reste sélectionnable et accepte toujours ces tables.
ingest: {
mode: 'query',
engine: 'postgres',
intervalSec: 3600,
selectable: true,
endpoint: { endpointRefs: { host: 'dbHost', port: 'dbPort', database: 'dbName' }, trustedCaRef: 'warehouse-ca' },
tables: [],
}Pendant le choix, la personne parcourt la base de données — ses schémas, puis les tables
d'un schéma, puis les types de colonnes d'une table — au travers du catalogue de la source,
qui détient déjà l'identifiant en lecture seule de la connexion. Le parcours exige le droit
Utiliser sur la connexion de la source ; sans ce droit, il est refusé. La liste des tables
n'affiche ni estimation du nombre de lignes ni clé primaire : PostgreSQL et MySQL les
conservent là où le catalogue ne peut pas les lire, si bien que la clé d'une table en upsert
est une colonne que la personne désigne. L'aperçu des colonnes n'affiche que les noms et les
types, jamais une ligne. Les tables déjà choisies affichent le marquage de classification que
portent leurs lectures. Seuls les identifiants en minuscules peuvent être choisis ; les autres
noms sont listés mais ne sont pas sélectionnables.
Chaque table choisie est une entrée ordinaire de tables, avec six réglages facultatifs :
| Réglage | Signification |
|---|---|
destination | Le nom de la table dans laquelle la copie écrit. Lettres minuscules, chiffres et tirets bas simples, commençant par une lettre, 30 caractères au plus ; les préfixes mirror_ et agent_ sont réservés. Deux tables d'une même source ne peuvent pas partager une destination, et un nom dans lequel une autre source écrit déjà est refusé lors de la première écriture. Sans ce réglage, la plateforme dérive un nom. |
mode | upsert : les lignes fusionnent sur tablePK, qui devient alors obligatoire ; une exécution n'écrit que les lignes dont les valeurs ont changé. append : chaque exécution ne copie que les lignes dont timestampColumn est plus récent que celui de la dernière exécution terminée, et n'ajoute qu'elles, chacune horodatée par __snapshotAt ; timestampColumn devient alors obligatoire. Sans ce réglage, une table avec tablePK fusionne et une table sans clé ajoute. Une relecture complète ajoutée à chaque exécution n'est pas proposée : elle ajouterait de nouveau chaque ligne à chaque fois. |
timestampColumn | Une colonne de date ou de date-heure de la table. Pour append, la colonne selon laquelle les nouvelles lignes sont copiées : sa valeur ne doit que croître (création ou dernière modification de la ligne), et une ligne sans valeur n'est pas copiée. Pour upsert, l'heure propre à la ligne, conservée dans la destination. |
historyDays | Le nombre de jours de lignes que la destination conserve (1 à 36 500). Sans ce réglage, toutes les lignes sont conservées. Un upsert sans timestampColumn ne conserve pas d'historique : ses lignes gardent l'heure de leur première lecture, et les faire expirer supprimerait des lignes que la base contient encore (history_without_timestamp). |
newColumns | Ce que fait la copie lorsque la table distante gagne des colonnes. allow : elles sont enregistrées, et la destination les reçoit. ask : les colonnes que possède la destination continuent d'arriver, et les nouvelles attendent qu'une personne autorisée à modifier la source les accepte dans Analytics. block : les nouvelles colonnes sont ignorées, et chaque exécution indique lesquelles. Sans ce réglage, ask. Une table déclarée peut aussi le fixer. |
columns | Les colonnes que lit la copie, chacune un identifiant en minuscules, nommée une seule fois. Seules celles-ci sont lues : une colonne exclue n'atteint jamais la politique de données ni la destination. La clé sur laquelle fusionne un upsert et timestampColumn doivent en faire partie. Sans ce réglage, toutes les colonnes sont lues. Une table déclarée peut aussi le fixer. |
Une table sans tablePK ni timestampColumn ne peut pas être choisie : chaque exécution
la recopierait entièrement. Une table installée avant cette règle qui ajoute sans
timestampColumn s'arrête avec mirror_increment_missing au lieu d'ajouter de nouveau ses
lignes ; nommer une timestampColumn la relance, et sa première exécution copie encore une
fois chaque ligne qui a une valeur avant de ne copier que les nouvelles.
Le nom, la clé, la colonne d'horodatage et l'historique d'une destination sont fixés dès la
première écriture : une sélection qui les modifierait est refusée au moment du choix
(data_source_table_destination_exists, qui nomme chaque table), et la table n'est jamais
réécrite. Un append qui copie déjà selon une timestampColumn la conserve. Ses
colonnes ne font que s'ajouter, comme newColumns le permet : une colonne que la table
distante supprime ou change de type arrête la copie avec mirror_destination_changed, quel
que soit le réglage. Modifier
les tables choisies réinscrit le catalogue de la source : le parcours et la copie attendent
qu'il soit de nouveau actif.
Copies planifiées
Déclarez ingest.intervalSec: 300 une seule fois sur la source. Chaque table peut
indiquer tablePK: ['id'] et timestampColumn: 'updated_at'. Les clés déclarées
sélectionnent UPSERT ; les suppressions distantes ne sont pas synchronisées. Sans
clé, une table ajoute de façon incrémentale : chaque exécution ne lit que les lignes
dont timestampColumn est plus récent que la plus récente copiée par la dernière
exécution terminée (WHERE updated_at > …), et les ajoute, chacune horodatée par le
__snapshotAt de l'exécution. La position n'avance que lorsque chaque lot d'une
exécution est validé : une exécution qui échoue ou est reprise relit les mêmes lignes
plutôt que d'en sauter. Un champ distant __snapshotAt est refusé.
Une exécution UPSERT relit la table et n'écrit que les lignes dont les valeurs ont
changé : une ligne dont les valeurs sont celles que la destination contient déjà n'est
pas réécrite et garde le _run_id et le _loaded_at de l'exécution qui l'a modifiée
en dernier, et une exécution qui ne change rien n'écrit aucune ligne. Une table avec
clés mais sans horodatage déclaré garde l'heure de lecture d'une ligne dans
__snapshotAt ; cette heure n'est pas comparée, si bien qu'une ligne inchangée garde
l'heure de sa première lecture avec ses valeurs actuelles, et la table ne conserve pas
d'historique. Les métadonnées
du pilote fournissent le schéma même pour une table vide ; les types non pris en
charge, les pertes de précision et les clés invalides font échouer la copie.
Les anciens intervalles expérimentaux par table activent la copie uniquement s’ils sont tous identiques et d’au moins 60 secondes. Sinon, les requêtes directes restent disponibles et la copie est désactivée jusqu’à une mise à niveau explicite. Aucun descripteur sauvegardé ni son empreinte de version n’est réécrit silencieusement.
La copie est planifiée par le service d’ingestion de la plateforme — le même planificateur que celui des sources interrogées périodiquement (poll) — présent dans toute installation par défaut. Une seule réplique détient le bail de la source et demande une exécution de la copie quand elle est due : au moment fixe propre à la source dans son intervalle, jamais plus d’un intervalle après la dernière synchronisation, ou tout de suite quand quelqu’un choisit Synchroniser maintenant. L’exécution elle-même reste dans le moteur de tables : la base est lue à travers le catalogue, jamais par le service d’ingestion, qui ne reçoit jamais l’identifiant de la base. Un lot n’est écrit que tant que l’exécution détient encore le bail de la source, si bien que deux répliques n’écrivent jamais la même copie en même temps. Synchroniser maintenant sur une source consultée uniquement en direct n’a rien à exécuter ; sur une source en pause, la demande est refusée jusqu’à sa reprise.
Chaque table distante possède une destination gérée distincte. Une autorisation
interne dédiée vérifie la source, l’environnement, la génération du catalogue et le
schéma actif de classification. La destination doit représenter une classification
de rang égal ou supérieur. Sinon, mirror_classification_unrepresentable est affiché ;
l’autorisation des requêtes directes reste indépendante. Un échec de copie ne suspend
pas automatiquement le catalogue. Une pause opérateur bloque les nouvelles lectures
et publications ; la reprise permet la prochaine tentative planifiée. La suppression
de la source supprime toutes ses destinations gérées.
Le détail Analytics affiche le catalogue, la fréquence, les liens des destinations et l’historique par table. Une sauvegarde incomplète n’est jamais un instantané terminé. Une table vide peut terminer avec zéro ligne, sans écriture artificielle. Des lots déjà confirmés peuvent rester visibles si une écriture suivante échoue. La réussite exige la fin réelle du parcours distant et toutes les confirmations d’écriture.
Le parcours est limité à 30 secondes et à 8 MiB de stockage temporaire durable, avec
des lots de 1 000 lignes et 768 KiB au maximum. Une exécution cesse de planifier des lots après cinq minutes et respecte les limites
d’admission existantes ; une écriture déjà autorisée peut encore se terminer. Un dépassement échoue
explicitement, sans résultat tronqué présenté comme complet. Les reprises conservent
les mêmes octets, reçus et horodatages. Un changement de source révoquant un lot non
confirmé, qui a pu atteindre la table de destination, conserve ses données et bloque
la suite avec mirror_recovery_required ; une récupération opérateur est nécessaire.
Une exécution dont la table de destination n’a jamais été créée n’a rien pu écrire :
un changement de source la remplace simplement. Les données temporaires des parcours
terminés ou échoués sont nettoyées ; l’historique garde au plus 50 exécutions par destination.
Chaque lot est écrit exactement une fois. La destination garde le dernier lot validé pour le miroir — son exécution et sa place dans l’exécution — : un lot enregistré à nouveau après une reprise ou une prise de relais est reconnu comme déjà écrit, quel que soit son retard, et un miroir peut fonctionner aussi longtemps qu’il est planifié : le nombre de lots qu’une destination accepte n’est pas limité. Un lot est lié aux lignes que le parcours a stockées, et non aux lignes écrites : une règle de protection des données qui masque une valeur d’un lot ne l’empêche pas d’être écrit.
La suppression met d’abord une source en mode query en pause. Si un parcours, le
provisionnement d’une destination ou une sauvegarde est encore en cours, la suppression
renvoie mirror_operation_in_progress et laisse la source en pause ; relancez la
suppression une fois cette opération terminée. La reprise, les mises à niveau de la
source et le nettoyage du registre ne peuvent pas rouvrir une source dont la suppression
a commencé.
Un parcours, un provisionnement ou une sauvegarde interrompu conserve son enregistrement
d’opération. L’exécution de copie suivante de la source ne reprend cet enregistrement
qu’une fois qu’elle détient une clôture plus récente du bail de la source ; elle reprend
alors les mêmes lots sous les mêmes identifiants de reçu, si bien que rien n’est perdu ni
écrit deux fois. Un enregistrement laissé avant l’existence de cette reprise, qui ne porte
aucune clôture, nécessite toujours un opérateur. L’enregistrement n’est jamais
effacé par le temps, et il n’existe toujours pas d’API de suppression forcée : effacer un
enregistrement incertain pourrait permettre une création ou une sauvegarde tardive après
la suppression de sa destination. mirror_operation_recovery_required signale un échec
externe ambigu : un opérateur doit établir l’issue de cette opération précise avant que
la copie ou la suppression puisse continuer. Une destination que StarRocks refuse de
créer — par exemple quand aucun backend n’a l’espace disque ou les réplicas que la table
demande — n’est pas ambiguë : rien n’a été créé, l’opération est libérée et la copie
suivante la provisionne de nouveau. Le panneau de détail de la source affiche la
suppression en attente et la récupération séparément de l’historique ordinaire des copies.