El módulo postgres_fdw proporciona el adaptador de datos externos (foreign-data wrapper)
postgres_fdw, que se puede utilizar para acceder a los datos
almacenados en servidores externos de PostgreSQL.
La funcionalidad proporcionada por este módulo se superpone sustancialmente
con la funcionalidad del módulo anterior dblink.
Pero postgres_fdw proporciona una sintaxis más transparente y
compatible con los estándares para acceder a tablas remotas, y puede ofrecer
un mejor rendimiento en muchos casos.
Para prepararte para el acceso remoto usando postgres_fdw:
Instala la extensión postgres_fdw usando CREATE EXTENSION.
Crea un objeto de servidor externo usando CREATE SERVER,
para representar cada base de datos remota a la que te quieras conectar.
Especifica la información de conexión, excepto user y
password, como opciones del objeto de servidor.
Crea un mapeo de usuario usando CREATE USER MAPPING, para
cada usuario de la base de datos al que quieras permitir acceder a cada servidor externo.
Especifica el nombre de usuario y la contraseña remotos que se utilizarán como
opciones user y password del
mapeo de usuario.
Crea una tabla externa usando CREATE FOREIGN TABLE o IMPORT FOREIGN SCHEMA, para cada tabla remota a la que quieras acceder. Las columnas de la tabla externa deben coincidir con la tabla remota referenciada. Sin embargo, puedes usar nombres de tabla y/o columnas diferentes a los de la tabla remota si especificas los nombres remotos correctos como opciones del objeto de tabla externa.
Ahora solo necesitas hacer un SELECT en una tabla externa para acceder
a los datos almacenados en su tabla remota subyacente. También puedes modificar
la tabla remota usando INSERT, UPDATE,
DELETE, COPY o
TRUNCATE.
(Por supuesto, el usuario remoto que hayas especificado en tu mapeo de usuario debe
tener privilegios para hacer estas cosas).
Ten en cuenta que la opción ONLY especificada en
SELECT, UPDATE,
DELETE o TRUNCATE
no tiene efecto al acceder o modificar la tabla remota.
Ten en cuenta que postgres_fdw actualmente carece de soporte para
sentencias INSERT con una cláusula ON CONFLICT DO
UPDATE. Sin embargo, la cláusula ON CONFLICT DO NOTHING
está soportada, siempre que se omita una especificación de inferencia de índice único.
Ten en cuenta también que postgres_fdw soporta el movimiento de filas
provocado por sentencias UPDATE ejecutadas en tablas particionadas,
pero actualmente no maneja el caso en el que una partición remota
elegida para insertar una fila movida sea también una partición de destino de UPDATE
que se actualizará en otro lugar del mismo comando.
En general, se recomienda que las columnas de una tabla externa se declaren
con exactamente los mismos tipos de datos, y ordenaciones (collations) si corresponde, que las
columnas referenciadas de la tabla remota. Aunque postgres_fdw
es actualmente bastante flexible a la hora de realizar conversiones de tipos de datos cuando es
necesario, pueden surgir anomalías semánticas sorprendentes cuando los tipos o las ordenaciones no
coinciden, debido a que el servidor remoto interpreta las condiciones de la consulta
de manera diferente al servidor local.
Ten en cuenta que una tabla externa se puede declarar con menos columnas, o con un orden de columnas diferente al que tiene su tabla remota subyacente. La coincidencia de las columnas con la tabla remota se realiza por nombre, no por posición.
Un servidor externo que utiliza el adaptador de datos externos postgres_fdw
puede tener las mismas opciones que acepta libpq en
las cadenas de conexión, como se describe en Section 32.1.2,
excepto que estas opciones no están permitidas o tienen un manejo especial:
user, password y sslpassword (especifícalas
en un mapeo de usuario en su lugar, o utiliza un archivo de servicio)
client_encoding (esta se establece automáticamente a partir de la codificación
del servidor local)
application_name — esto puede aparecer en
una o en ambas de una conexión y
de la variable postgres_fdw.application_name.
Si ambas están presentes, postgres_fdw.application_name
anula la configuración de la conexión.
A diferencia de libpq,
postgres_fdw permite que
application_name incluya
“secuencias de escape”.
Consulta postgres_fdw.application_name para obtener más detalles.
fallback_application_name (siempre se establece en
postgres_fdw)
sslkey y sslcert — estas pueden
aparecer en una o en ambas de una conexión y de un
mapeo de usuario. Si ambas están presentes, la configuración del mapeo de usuario
anula la configuración de la conexión.
Solo los superusuarios pueden crear o modificar mapeos de usuario con las
configuraciones sslcert o sslkey.
Los usuarios que no sean superusuarios pueden conectarse a servidores externos utilizando
autenticación por contraseña o con credenciales delegadas de GSSAPI, así que especifica la
opción password para los mapeos de usuario pertenecientes a
usuarios que no sean superusuarios donde se requiera autenticación por contraseña.
Un superusuario puede anular esta comprobación de forma individual para cada mapeo de usuario
estableciendo la opción de mapeo de usuario password_required 'false', por ejemplo:
ALTER USER MAPPING FOR some_non_superuser SERVER loopback_nopw OPTIONS (ADD password_required 'false');
Para evitar que los usuarios sin privilegios aprovechen los derechos de autenticación del usuario de Unix bajo el cual se ejecuta el servidor de postgres para escalar a derechos de superusuario, solo el superusuario puede establecer esta opción en un mapeo de usuario.
Se requiere cuidado para garantizar que esto no permita al usuario mapeado la capacidad
de conectarse como superusuario a la base de datos mapeada según
CVE-2007-3278 y CVE-2007-6601. No establezcas
password_required=false
en el rol public. Ten en cuenta que el usuario mapeado
puede potencialmente usar cualquier certificado de cliente,
.pgpass,
.pg_service.conf, etc. en el directorio personal de Unix del
usuario del sistema bajo el cual se ejecuta el servidor de postgres. (Para obtener detalles sobre cómo
se encuentran los directorios personales, consulta Section 32.16). También pueden
usar cualquier relación de confianza
otorgada por modos de autenticación como la autenticación peer
o ident.
Estas opciones se pueden usar para controlar los nombres utilizados en las sentencias SQL enviadas al servidor remoto de PostgreSQL. Estas opciones son necesarias cuando se crea una tabla externa con nombres diferentes a los de la tabla remota subyacente.
schema_name (string)Esta opción, que se puede especificar para una tabla externa, indica el nombre del esquema que se usará para la tabla externa en el servidor remoto. Si esta opción se omite, se utiliza el nombre del esquema de la tabla externa.
table_name (string)Esta opción, que se puede especificar para una tabla externa, indica el nombre de la tabla que se usará para la tabla externa en el servidor remoto. Si esta opción se omite, se utiliza el nombre de la tabla externa.
column_name (string)Esta opción, que se puede especificar para una columna de una tabla externa, indica el nombre de la columna que se usará para la columna en el servidor remoto. Si esta opción se omite, se utiliza el nombre de la columna.
postgres_fdw recupera datos remotos ejecutando consultas
contra servidores remotos, por lo que idealmente el costo estimado de escanear una
tabla externa debería ser el costo de hacerlo en el servidor remoto,
más un costo adicional por la comunicación. La forma más confiable de
obtener dicha estimación es preguntar al servidor remoto y luego agregar algo
para el costo adicional — pero para consultas simples, puede no valer el costo
de una consulta remota adicional para obtener una estimación de costos.
Por lo tanto, postgres_fdw proporciona las siguientes opciones para controlar
cómo se realiza la estimación de costos:
use_remote_estimate (boolean)
Esta opción, que se puede especificar para una tabla externa o un servidor externo,
controla si postgres_fdw emite comandos
EXPLAIN remotos para obtener estimaciones de costos.
Una configuración para una tabla externa anula cualquier configuración para su servidor,
pero solo para esa tabla.
El valor predeterminado es false.
fdw_startup_cost (floating point)
Esta opción, que se puede especificar para un servidor externo, es un valor de punto
flotante que se agrega al costo estimado de inicio de cualquier
escaneo de tabla externa en ese servidor. Esto representa el costo adicional
de establecer una conexión, analizar y planificar la consulta en el
lado remoto, etc.
El valor predeterminado es 100.
fdw_tuple_cost (floating point)
Esta opción, que se puede especificar para un servidor externo, es un valor de punto
flotante que se utiliza como costo adicional por tupla para los escaneos
de tablas externas en ese servidor. Esto representa el costo adicional de la
transferencia de datos entre servidores. Puedes aumentar o disminuir este
número para reflejar un retraso de red mayor o menor hacia el servidor remoto.
El valor predeterminado es 0.2.
Cuando use_remote_estimate es true,
postgres_fdw obtiene las estimaciones de recuento de filas y costos del
servidor remoto y luego agrega fdw_startup_cost y
fdw_tuple_cost a las estimaciones de costos. Cuando
use_remote_estimate es false,
postgres_fdw realiza una estimación local del recuento de filas y costos
y luego agrega fdw_startup_cost and
fdw_tuple_cost a las estimaciones de costos. Es poco probable
que esta estimación local sea muy precisa a menos que estén disponibles copias locales de las
estadísticas de la tabla remota. Ejecutar
ANALYZE en la tabla externa es la forma de actualizar
las estadísticas locales; esto realizará un escaneo de la tabla remota y
luego calculará y almacenará las estadísticas tal como si la tabla fuera local.
Mantener estadísticas locales puede ser una forma útil de reducir el costo de planificación por consulta
para una tabla remota — pero si la tabla remota se actualiza con frecuencia,
las estadísticas locales pronto quedarán obsoletas.
La siguiente opción controla cómo se comporta dicha operación ANALYZE:
analyze_sampling (string)
Esta opción, que se puede especificar para una tabla externa o un servidor externo,
determina si ANALYZE en una tabla externa
toma muestras de los datos en el lado remoto, o lee y transfiere todos los datos
y realiza el muestreo localmente. Los valores admitidos
son off, random,
system, bernoulli
y auto. off desactiva el muestreo remoto,
por lo que todos los datos se transfieren y se muestrean localmente.
random realiza un muestreo remoto utilizando la
función random() para elegir las filas devueltas,
mientras que system y bernoulli se basan
en los métodos integrados de TABLESAMPLE con esos
nombres. random funciona en todas las versiones de servidores remotos,
mientras que TABLESAMPLE solo se admite desde la versión 9.5.
auto (el valor predeterminado) elige automáticamente el método de muestreo
recomendado; actualmente esto significa
ya sea bernoulli o random
según la versión del servidor remoto.
Por defecto, solo las cláusulas WHERE que utilizan operadores y
funciones integrados se considerarán para su ejecución en el servidor remoto. Las cláusulas
que involucran funciones no integradas se comprueban localmente después de recuperar las filas.
Si dichas funciones están disponibles en el servidor remoto y se puede confiar en que
produzcan los mismos resultados que localmente, se puede mejorar el rendimiento enviando dichas
cláusulas WHERE para su ejecución remota. Este comportamiento se puede controlar
mediante la siguiente opción:
extensions (string)Esta opción es una lista separada por comas de nombres de extensiones de PostgreSQL que están instaladas, en versiones compatibles, tanto en el servidor local como en el remoto. Las funciones y los operadores que son inmutables y pertenecen a una extensión de la lista se considerarán aptos para ser enviados al servidor remoto. Esta opción solo se puede especificar para servidores externos, no por tabla.
Al utilizar la opción extensions, es responsabilidad del
usuario que las extensiones enumeradas existan y se comporten de manera idéntica
tanto en el servidor local como en el remoto. De lo contrario, las consultas remotas
pueden fallar o comportarse de manera inesperada.
fetch_size (integer)
Esta opción especifica el número de filas que postgres_fdw
debe obtener en cada operación de recuperación (fetch). Se puede especificar para una
tabla externa o un servidor externo. La opción especificada en una tabla anula
una opción especificada para el servidor.
El valor predeterminado es 100.
batch_size (integer)
Esta opción especifica el número de filas que postgres_fdw
debe insertar en cada operación de inserción. Se puede especificar para una
tabla externa o un servidor externo. La opción especificada en una tabla
anula una opción especificada para el servidor.
El valor predeterminado es 1.
Ten en cuenta que el número real de filas que postgres_fdw inserta a la
vez depende del número de columnas y del valor de batch_size
proporcionado. El lote se ejecuta como una sola consulta, y el protocolo libpq (que
postgres_fdw utiliza para conectarse a un servidor remoto) limita
el número de parámetros en una sola consulta a 65535. Cuando el número de columnas *
batch_size supera el límite, el batch_size se ajustará
para evitar un error.
Esta opción también se aplica cuando se copia en tablas externas. En ese caso,
el número real de filas que postgres_fdw copia a la vez se determina
de forma similar al caso de inserción, pero está limitado a un máximo de 1000 debido
a restricciones de implementación del comando COPY.
postgres_fdw admite la ejecución asíncrona, que
ejecuta múltiples partes de un nodo Append
de forma concurrente en lugar de secuencial para mejorar el rendimiento.
Esta ejecución se puede controlar mediante la siguiente opción:
async_capable (boolean)
Esta opción controla si postgres_fdw permite que
las tablas externas se escaneen de forma concurrente para la ejecución asíncrona.
Se puede especificar para una tabla externa o un servidor externo.
Una opción a nivel de tabla anula una opción a nivel de servidor.
El valor predeterminado es false.
Para garantizar que los datos devueltos desde un servidor externo
sean consistentes, postgres_fdw solo abrirá una
conexión para un servidor externo determinado y ejecutará todas las consultas contra
ese servidor de forma secuencial, incluso si hay múltiples tablas externas
involucradas, a menos que esas tablas estén sujetas a mapeos de usuario diferentes.
En tal caso, puede ser más eficiente desactivar esta opción para
eliminar el costo adicional asociado con la ejecución de consultas de forma asíncrona.
La ejecución asíncrona se aplica incluso cuando un
nodo Append contiene subplan(es) ejecutados
de forma síncrona, así como subplan(es) ejecutados de forma asíncrona.
En tal caso, si los subplanes asíncronos son procesados usando
postgres_fdw, las tuplas de los subplanes
asíncronos no se devuelven hasta después de que al menos un subplan síncrono
devuelva todas las tuplas, ya que ese subplan se ejecuta mientras los subplanes
asíncronos esperan los resultados de las consultas asíncronas enviadas a los
servidores externos.
Este comportamiento podría cambiar en una versión futura.
Como se describe en la sección de Gestión de Transacciones, en
postgres_fdw las transacciones se gestionan creando las
correspondientes transacciones remotas, y las subtransacciones se gestionan creando las
correspondientes subtransacciones remotas. Cuando se involucran múltiples transacciones
remotas en la transacción local actual, por defecto
postgres_fdw confirma o aborta esas transacciones
remotas de forma secuencial cuando la transacción local se confirma o se aborta.
Cuando se involucran múltiples subtransacciones remotas en la subtransacción
local actual, por defecto postgres_fdw confirma o
aborta esas subtransacciones remotas de forma secuencial cuando la subtransacción local
se confirma o se aborta.
El rendimiento se puede mejorar con las siguientes opciones:
parallel_commit (boolean)
Esta opción controla si postgres_fdw confirma,
en paralelo, las transacciones remotas abiertas en un servidor externo en una transacción
local cuando la transacción local se confirma. Esta configuración también
se aplica a las subtransacciones remotas y locales. Esta opción solo se puede
especificar para servidores externos, no por tabla. El valor predeterminado es
false.
parallel_abort (boolean)
Esta opción controla si postgres_fdw aborta,
en paralelo, las transacciones remotas abiertas en un servidor externo en una transacción
local cuando la transacción local se aborta. Esta configuración también
se aplica a las subtransacciones remotas y locales. Esta opción solo se puede
especificar para servidores externos, no por tabla. El valor predeterminado es
false.
Si se involucran múltiples servidores externos con estas opciones habilitadas en una transacción local, las múltiples transacciones remotas en esos servidores externos se confirman o se abortan en paralelo a través de esos servidores externos cuando la transacción local se confirma o se aborta.
Cuando estas opciones están habilitadas, un servidor externo con muchas transacciones remotas puede experimentar un impacto negativo en el rendimiento cuando la transacción local se confirma o se aborta.
Por defecto, se asume que todas las tablas externas que utilizan postgres_fdw
son actualizables. Esto se puede anular mediante la siguiente opción:
updatable (boolean)
Esta opción controla si postgres_fdw permite que las tablas
externas se modifiquen mediante comandos INSERT, UPDATE y
DELETE. Se puede especificar para una tabla externa
o un servidor externo. Una opción a nivel de tabla anula una opción a nivel de
servidor.
El valor predeterminado es true.
Por supuesto, si la tabla remota no es de hecho actualizable, ocurriría un error
de todos modos. El uso de esta opción permite principalmente que el error se lance
localmente sin consultar al servidor remoto. Ten en cuenta, sin embargo, que las vistas
de information_schema informarán que una tabla externa de
postgres_fdw es actualizable (o no) según la configuración
de esta opción, sin ninguna verificación del servidor remoto.
Por defecto, se asume que todas las tablas externas que utilizan postgres_fdw
se pueden vaciar. Esto se puede anular mediante la siguiente opción:
truncatable (boolean)
Esta opción controla si postgres_fdw permite que las
tablas externas se vacíen mediante el comando TRUNCATE.
Se puede especificar para una tabla externa o un servidor externo.
Una opción a nivel de tabla anula una opción a nivel de servidor.
El valor predeterminado es true.
Por supuesto, si la tabla remota no es de hecho vaciable, ocurriría un error de todos modos. El uso de esta opción permite principalmente que el error se lance localmente sin consultar al servidor remoto.
postgres_fdw es capaz de importar definiciones de tablas externas
utilizando IMPORT FOREIGN SCHEMA. Este comando crea
definiciones de tablas externas en el servidor local que coinciden con las tablas o
vistas presentes en el servidor remoto. Si las tablas remotas a importar
tienen columnas de tipos de datos definidos por el usuario, el servidor local debe tener
tipos compatibles con los mismos nombres.
El comportamiento de importación se puede personalizar con las siguientes opciones
(dadas en el comando IMPORT FOREIGN SCHEMA):
import_collate (boolean)
Esta opción controla si las opciones COLLATE de la columna
se incluyen en las definiciones de las tablas externas importadas
desde un servidor externo. El valor predeterminado es true. Es posible que
debas desactivar esto si el servidor remoto tiene un conjunto diferente de
nombres de ordenación que el servidor local, lo cual es probable que ocurra
si se está ejecutando en un sistema operativo diferente.
Sin embargo, si lo haces, existe un riesgo muy grave de que las ordenaciones de las
columnas de la tabla importada no coincidan con los datos subyacentes, lo que resultará
en un comportamiento de consulta anómalo.
Incluso cuando este parámetro se establece en true, importar
columnas cuya ordenación es la predeterminada del servidor remoto puede ser arriesgado.
Se importarán con COLLATE "default", lo cual seleccionará la
ordenación predeterminada del servidor local, que podría ser diferente.
import_default (boolean)
Esta opción controla si las expresiones DEFAULT de la columna
se incluyen en las definiciones de las tablas externas importadas
desde un servidor externo. El valor predeterminado es false. Si
habilitas esta opción, ten cuidado con los valores predeterminados que podrían calcularse
de manera diferente en el servidor local que en el servidor remoto;
nextval() es una fuente común de problemas.
La importación (IMPORT) fallará por completo si una expresión predeterminada importada
utiliza una función o un operador que no existe localmente.
import_generated (boolean)
Esta opción controla si las expresiones GENERATED de la columna
se incluyen en las definiciones de las tablas externas importadas
desde un servidor externo. El valor predeterminado es true.
La importación (IMPORT) fallará por completo si una expresión generada importada
utiliza una función o un operador que no existe localmente.
import_not_null (boolean)
Esta opción controla si las restricciones NOT NULL de la columna
se incluyen en las definiciones de las tablas externas importadas
desde un servidor externo. El valor predeterminado es true.
Note that constraints other than NOT NULL will never be
imported from the remote tables. Although PostgreSQL
does support check constraints on foreign tables, there is no
provision for importing them automatically, because of the risk that a
constraint expression could evaluate differently on the local and remote
servers. Any such inconsistency in the behavior of a check
constraint could lead to hard-to-detect errors in query optimization.
So if you wish to import check constraints, you must do so
manually, and you should verify the semantics of each one carefully.
For more detail about the treatment of check constraints on
foreign tables, see CREATE FOREIGN TABLE.
Tables or foreign tables which are partitions of some other table are
imported only when they are explicitly specified in
LIMIT TO clause. Otherwise they are automatically
excluded from IMPORT FOREIGN SCHEMA.
Since all data can be accessed through the partitioned table
which is the root of the partitioning hierarchy, importing only
partitioned tables should allow access to all the data without
creating extra objects.
Por defecto, todas las conexiones que postgres_fdw
establece con los servidores externos se mantienen abiertas en la sesión local
para su reutilización.
keep_connections (boolean) #
Esta opción controla si postgres_fdw mantiene
abiertas las conexiones al servidor externo para que las consultas posteriores
puedan reutilizarlas. Solo se puede especificar para un servidor externo.
El valor predeterminado es on. Si se establece en off,
todas las conexiones a este servidor externo se descartarán al final de
cada transacción.
use_scram_passthrough (boolean) #
Esta opción controla si postgres_fdw utilizará
la autenticación de paso de SCRAM (SCRAM pass-through authentication) para conectarse al servidor externo.
Con la autenticación de paso de SCRAM,
postgres_fdw utiliza secretos con hash SCRAM en lugar de
contraseñas de usuario en texto plano para conectarse al servidor remoto. Esto
evita almacenar contraseñas de usuario en texto plano en los catálogos del sistema
de PostgreSQL.
Para utilizar la autenticación de paso de SCRAM:
El servidor remoto debe solicitar el método de autenticación scram-sha-256;
de lo contrario, la conexión fallará.
El servidor remoto puede ser de cualquier versión de PostgreSQL que admita
SCRAM. El soporte para use_scram_passthrough
solo se requiere en el lado del cliente (lado FDW).
No se utiliza la contraseña del mapeo de usuario.
El servidor que ejecuta postgres_fdw y el servidor remoto
deben tener secretos SCRAM idénticos (contraseñas cifradas) para
el usuario que se utiliza en postgres_fdw para
autenticarse en el servidor externo (misma sal e iteraciones, no
simplemente la misma contraseña).
Como corolario, si se van a realizar conexiones FDW a múltiples hosts, por ejemplo para tablas externas particionadas/sharding, entonces todos los hosts deben tener secretos SCRAM idénticos para los usuarios involucrados.
La sesión actual en la instancia de PostgreSQL que realiza las conexiones FDW salientes también debe utilizar autenticación SCRAM para su conexión de cliente entrante. (De ahí la “autenticación de paso”: se debe usar SCRAM tanto al entrar como al salir). Este es un requisito técnico del protocolo SCRAM.
postgres_fdw_get_connections(
IN check_conn boolean DEFAULT false, OUT server_name text,
OUT user_name text, OUT valid boolean, OUT used_in_xact boolean,
OUT closed boolean, OUT remote_backend_pid int4)
returns setof recordEsta función devuelve información sobre todas las conexiones abiertas que postgres_fdw ha establecido desde la sesión local a los servidores externos. Si no hay conexiones abiertas, no se devuelven registros.
Si check_conn se establece en true,
la función comprueba el estado de cada conexión y muestra
el resultado en la columna closed.
Esta característica está disponible actualmente solo en sistemas que admiten
la extensión no estándar POLLRDHUP para
la llamada al sistema poll, incluido Linux.
Esto es útil para comprobar si todas las conexiones utilizadas dentro
de una transacción siguen abiertas. Si alguna conexión se cierra,
la transacción no se puede confirmar con éxito,
por lo que es mejor revertirla tan pronto como se detecte una conexión cerrada,
en lugar de continuar hasta el final. Los usuarios pueden revertir la transacción
inmediatamente si la función informa de conexiones donde tanto
used_in_xact como closed son
true.
Ejemplo de uso de la función:
postgres=# SELECT * FROM postgres_fdw_get_connections(true); server_name | user_name | valid | used_in_xact | closed | remote_backend_pid -------------+-----------+-------+--------------+----------------------------- loopback1 | postgres | t | t | f | 1353340 loopback2 | public | t | t | f | 1353120 loopback3 | | f | t | f | 1353156
Las columnas de salida se describen en Table F.28.
Table F.28. Columnas de salida de postgres_fdw_get_connections
| Columna | Tipo | Descripción |
|---|---|---|
server_name | text |
El nombre del servidor externo de esta conexión. Si el servidor se
elimina pero la conexión permanece abierta (es decir, marcada como
inválida), esto será NULL.
|
user_name | text |
Nombre del usuario local mapeado al servidor externo de esta
conexión, o public si se utiliza un mapeo público.
Si el mapeo de usuario se elimina pero la conexión permanece abierta
(es decir, marcada como inválida), esto será NULL.
|
valid | boolean | Falso si esta conexión no es válida, lo que significa que se utiliza en la transacción actual, pero su servidor externo o mapeo de usuario ha sido modificado o eliminado. La conexión no válida se cerrará al final de la transacción. En caso contrario, se devuelve True. |
used_in_xact | boolean | True si esta conexión se utiliza en la transacción actual. |
closed | boolean |
True si esta conexión está cerrada, false en caso contrario.
Se devuelve NULL si check_conn
se establece en false o si la comprobación del estado de la conexión
no está disponible en esta plataforma.
|
remote_backend_pid | int4 |
ID de proceso del backend remoto, en el servidor externo,
que maneja la conexión. Si el backend remoto se termina y
la conexión se cierra (con closed establecido en
true), esto todavía muestra el ID de proceso del
backend terminado.
|
postgres_fdw_disconnect(server_name text) returns boolean
Esta función descarta las conexiones abiertas que están establecidas por
postgres_fdw desde la sesión local al
servidor externo con el nombre dado. Ten en cuenta que puede haber
múltiples conexiones al servidor dado utilizando diferentes mapeos de usuario.
Si las conexiones se utilizan en la transacción local actual,
no se desconectan y se informan mensajes de advertencia.
Esta función devuelve true si desconecta
al menos una conexión, de lo contrario false.
Si no se encuentra ningún servidor externo con el nombre dado, se informa de un error.
Ejemplo de uso de la función:
postgres=# SELECT postgres_fdw_disconnect('loopback1');
postgres_fdw_disconnect
-------------------------
t
postgres_fdw_disconnect_all() returns boolean
Esta función descarta todas las conexiones abiertas que están establecidas por
postgres_fdw desde la sesión local a los
servidores externos. Si las conexiones se utilizan en la transacción local
actual, no se desconectan y se informan mensajes de advertencia.
Esta función devuelve true si desconecta
al menos una conexión, de lo contrario false.
Ejemplo de uso de la función:
postgres=# SELECT postgres_fdw_disconnect_all(); postgres_fdw_disconnect_all ----------------------------- t
postgres_fdw establece una conexión a un
servidor externo durante la primera consulta que utiliza una tabla externa
asociada con el servidor externo. Por defecto, esta conexión
se mantiene y se reutiliza para consultas posteriores en la misma sesión.
Este comportamiento se puede controlar mediante la opción
keep_connections para un servidor externo. Si
se utilizan múltiples identidades de usuario (mapeos de usuario) para acceder al servidor
externo, se establece una conexión para cada mapeo de usuario.
Al cambiar la definición o eliminar un servidor externo o un mapeo de usuario, se cierran las conexiones asociadas. Pero ten en cuenta que si alguna conexión se está utilizando en la transacción local actual, se mantiene hasta el final de la transacción. Las conexiones cerradas se volverán a establecer cuando sean necesarias por futuras consultas que utilicen una tabla externa.
Una vez establecida una conexión a un servidor externo,
por defecto se mantiene hasta que finaliza la sesión local o la correspondiente
sesión remota. Para desconectar una conexión explícitamente, se puede
desactivar la opción keep_connections para un servidor externo,
o se pueden usar las funciones postgres_fdw_disconnect y
postgres_fdw_disconnect_all. Por ejemplo, estas son útiles para cerrar
conexiones que ya no son necesarias, liberando así conexiones en el servidor externo.
Durante una consulta que hace referencia a cualquier tabla remota en un servidor externo,
postgres_fdw abre una transacción en el
servidor remoto si no hay una ya abierta correspondiente a la transacción
local actual. La transacción remota se confirma o se aborta cuando
la transacción local se confirma o se aborta. Los puntos de salvaguarda (savepoints) se
gestionan de manera similar mediante la creación de los correspondientes puntos de salvaguarda remotos.
La transacción remota utiliza el nivel de aislamiento SERIALIZABLE
cuando la transacción local tiene el nivel de aislamiento SERIALIZABLE;
de lo contrario, utiliza el nivel de aislamiento REPEATABLE READ.
Esta elección garantiza que si una consulta realiza múltiples escaneos de tablas
en el servidor remoto, obtendrá resultados consistentes con la instantánea (snapshot-consistent)
para todos los escaneos. Una consecuencia es que las consultas sucesivas dentro de una
sola transacción verán los mismos datos del servidor remoto, incluso si se están produciendo
actualizaciones concurrentes en el servidor remoto debido a otras actividades.
Ese comportamiento se esperaría de todos modos si la transacción local utiliza el nivel de aislamiento
SERIALIZABLE o REPEATABLE READ,
pero podría resultar sorprendente para una transacción local READ COMMITTED.
Una versión futura de PostgreSQL podría modificar estas reglas.
Ten en cuenta que actualmente postgres_fdw no admite
la preparación de la transacción remota para una confirmación en dos fases (two-phase commit).
postgres_fdw intenta optimizar las consultas remotas para reducir
la cantidad de datos transferidos desde los servidores externos. Esto se hace enviando
las cláusulas WHERE de la consulta al servidor remoto para su
ejecución, y no recuperando las columnas de la tabla que no son necesarias para
la consulta actual. Para reducir el riesgo de una ejecución incorrecta de las consultas,
las cláusulas WHERE no se envían al servidor remoto a menos que utilicen
únicamente tipos de datos, operadores y funciones que sean integrados o pertenezcan a una
extensión que figure en la opción extensions del servidor externo.
Los operadores y funciones en tales cláusulas también deben ser IMMUTABLE.
Para una consulta UPDATE o DELETE,
postgres_fdw intenta optimizar la ejecución de la consulta
enviando toda la consulta al servidor remoto si no hay cláusulas WHERE
de la consulta que no se puedan enviar al servidor remoto, no hay uniones (joins) locales
para la consulta, no hay disparadores (triggers) locales a nivel de fila BEFORE o
AFTER o columnas generadas almacenadas en la tabla de destino,
y no hay restricciones CHECK OPTION de las vistas principales.
En UPDATE,
las expresiones a asignar a las columnas de destino deben usar únicamente tipos de datos integrados,
operadores IMMUTABLE o funciones IMMUTABLE,
para reducir el riesgo de una ejecución incorrecta de la consulta.
Cuando postgres_fdw encuentra una unión (join) entre tablas externas en
el mismo servidor externo, envía toda la unión al servidor externo, a menos que por alguna razón
crea que será más eficiente recuperar las filas de cada tabla individualmente, o a menos que las
referencias de tabla involucradas estén sujetas a mapeos de usuario diferentes. Al enviar las
cláusulas JOIN, toma las mismas precauciones mencionadas anteriormente para las
cláusulas WHERE.
La consulta que realmente se envía al servidor remoto para su ejecución se puede examinar
utilizando EXPLAIN VERBOSE.
En las sesiones remotas abiertas por postgres_fdw,
el parámetro search_path se establece únicamente en
pg_catalog, de modo que solo los objetos integrados son visibles
sin calificación de esquema. Esto no es un problema para las consultas
generadas por la propia herramienta postgres_fdw, porque siempre
proporciona dicha calificación. Sin embargo, esto puede representar un riesgo para
las funciones que se ejecutan en el servidor remoto a través de disparadores o reglas
en tablas remotas. Por ejemplo, si una tabla remota es en realidad una vista,
cualquier función utilizada en esa vista se ejecutará con la ruta de búsqueda restringida.
Se recomienda calificar con el esquema todos los nombres en dichas funciones, o bien adjuntar
opciones SET search_path (consulta CREATE FUNCTION)
a dichas funciones para establecer el entorno de ruta de búsqueda esperado.
postgres_fdw del mismo modo establece la configuración de la sesión remota
para varios parámetros:
TimeZone se establece en UTC
DateStyle se establece en ISO
IntervalStyle se establece en postgres
extra_float_digits se establece en 3 para servidores remotos
9.0 y posteriores y en 2 para versiones anteriores.
Es menos probable que estos parámetros sean problemáticos que search_path, pero
se pueden manejar con las opciones SET de la función si surge la necesidad.
No se recomienda que sobrescribas este comportamiento cambiando la configuración a nivel
de sesión de estos parámetros; es probable que eso cause un mal funcionamiento de
postgres_fdw.
postgres_fdw se puede utilizar con servidores remotos desde la versión
8.3 de PostgreSQL. La capacidad de solo lectura está disponible
hasta la versión 8.1.
Sin embargo, una limitación es que postgres_fdw generalmente asume
que las funciones y operadores integrados inmutables son seguros de enviar al servidor remoto
para su ejecución, si aparecen en una cláusula WHERE de una tabla externa.
Por lo tanto, una función integrada que se agregó desde el lanzamiento del servidor remoto podría
enviarse a él para su ejecución, lo que provocaría un error del tipo “la función no existe”
o similar. Este tipo de fallo se puede solucionar reescribiendo la consulta, por ejemplo,
envolviendo la referencia de la tabla externa en una subconsulta SELECT con
OFFSET 0 como una barrera de optimización y colocando la función u operador
problemático fuera de la subconsulta SELECT.
Otra limitación es que al ejecutar sentencias INSERT con una cláusula
ON CONFLICT DO NOTHING en una tabla externa, el servidor remoto debe
estar ejecutando PostgreSQL 9.5 o posterior, ya que las versiones anteriores
no admiten esta característica.
postgres_fdw puede informar los siguientes eventos de espera
bajo el tipo de evento de espera Extension:
PostgresFdwCleanupResultEsperando el aborto de la transacción en el servidor remoto.
PostgresFdwConnectEsperando establecer una conexión con un servidor remoto.
PostgresFdwGetResultEsperando recibir los resultados de una consulta de un servidor remoto.
postgres_fdw.application_name (string)
#
Especifica un valor para el parámetro de configuración application_name
utilizado cuando postgres_fdw establece una conexión con un servidor externo.
Esto anula la opción application_name del objeto de servidor.
Ten en cuenta que el cambio de este parámetro no afecta a ninguna de las conexiones existentes
hasta que se vuelvan a establecer.
postgres_fdw.application_name puede ser cualquier cadena de cualquier longitud
y contener incluso caracteres no ASCII. Sin embargo, cuando se pasa y se utiliza como
application_name en un servidor externo, ten en cuenta que se truncará a menos
de NAMEDATALEN caracteres. Cualquier carácter que no sea ASCII imprimible se
reemplaza con escapes hexadecimales de estilo C.
Consulta application_name para obtener más detalles.
Los caracteres % inician “secuencias de escape” que se reemplazan
con información de estado como se detalla a continuación. Los escapes no reconocidos se ignoran.
Otros caracteres se copian directamente al nombre de la aplicación. Ten en cuenta que no está permitido
especificar un signo más/menos o un literal numérico después del % y antes de la
opción para fines de alineación y relleno.
| Escape | Efecto |
|---|---|
%a | Nombre de la aplicación en el servidor local |
%c | ID de sesión en el servidor local (consulta log_line_prefix para obtener más detalles) |
%C | Nombre del clúster en el servidor local (consulta cluster_name para obtener más detalles) |
%u | Nombre de usuario en el servidor local |
%d | Nombre de la base de datos en el servidor local |
%p | ID de proceso del backend en el servidor local |
%% | Carácter % literal |
Por ejemplo, supongamos que el usuario local_user establece una conexión desde la
base de datos local_db a foreign_db como el usuario
foreign_user, la configuración 'db=%d, user=%u' se reemplaza por
'db=local_db, user=local_user'.
Aquí tienes un ejemplo de cómo crear una tabla externa con
postgres_fdw. Primero instala la extensión:
CREATE EXTENSION postgres_fdw;
Luego crea un servidor externo utilizando CREATE SERVER.
En este ejemplo queremos conectarnos a un servidor de PostgreSQL
en el host 192.83.123.89 escuchando en el puerto 5432.
La base de datos a la que se realiza la conexión se llama foreign_db en el servidor remoto:
CREATE SERVER foreign_server
FOREIGN DATA WRAPPER postgres_fdw
OPTIONS (host '192.83.123.89', port '5432', dbname 'foreign_db');
También se necesita un mapeo de usuario, definido con CREATE USER MAPPING, para identificar el rol que se utilizará en el servidor remoto:
CREATE USER MAPPING FOR local_user
SERVER foreign_server
OPTIONS (user 'foreign_user', password 'password');
Ahora es posible crear una tabla externa con CREATE FOREIGN TABLE.
En este ejemplo queremos acceder a la tabla llamada some_schema.some_table
en el servidor remoto. El nombre local para ella será foreign_table:
CREATE FOREIGN TABLE foreign_table (
id integer NOT NULL,
data text
)
SERVER foreign_server
OPTIONS (schema_name 'some_schema', table_name 'some_table');
Es fundamental que los tipos de datos y otras propiedades de las columnas declaradas en
CREATE FOREIGN TABLE coincidan con la tabla remota real. Los nombres de las columnas
también deben coincidir, a menos que adjuntes opciones column_name a las columnas
individuales para mostrar cómo se llaman en la tabla remota. En muchos casos, el uso de
IMPORT FOREIGN SCHEMA es preferible
a construir definiciones de tablas externas manualmente.
Shigeru Hanada <[email protected]>