Това е ограничено приложение на репликация. Изискванията варират много, така че има няколко различни установени решения, които се отнасят до различни ситуации. Разгледайте общия преглед в ръководството.
Вашето ръчно плетено, базирано на спусък решение е една жизнеспособна опция за относително малко изтривания. Отварянето и затварянето на отделна връзка за всеки ред води до доста режийни разходи. Има и други различни опции.
Докато работейки с dblink, предлагам някои модификации. Най-важното:
-
Използвайте
format()
за по-елегантно избягване на низовете. -
Прекарайте целия ред вместо да пропуска и избягва всяка отделна колона.
-
Не поставяйте паролата във всяка отделна тригерна функция.
ИзползвайтеFOREIGN SERVER
плюсUSER MAPPING
. Подробни инструкции тук:
По принцип стартирайте веднъж на изходния сървър:
CREATE SERVER myserver FOREIGN DATA WRAPPER dblink_fdw
OPTIONS (hostaddr '127.0.0.1', dbname 'gtr_bd_archive');
CREATE USER MAPPING FOR role_source SERVER myserver
OPTIONS (user 'postgres', password 'secret');
За предпочитане е да не влизате като суперпотребител на целевия сървър. Използвайте специална роля с ограничени привилегии, за да избегнете ескалация на привилегии.
И използвайте файл с пароли
на целевия сървър, за да позволи достъп без парола. По този начин дори не е необходимо да съхранявате паролата в USER MAPPING
. Инструкции в последната глава на този свързан отговор:
След това:
CREATE OR REPLACE FUNCTION pg_temp.flux_tresorerie_historique_backup_row()
RETURNS trigger AS
$func$
BEGIN
PERFORM dblink_connect('myserver'); -- name of foreign server from above
PERFORM dblink_exec( format(
$$
INSERT INTO flux_tresorerie_historique -- provide target column list!
SELECT (r).id_flux_historique
, (r).date_operation_flux
, (r).date_valeur_flux
, (r).date_rapprochement_flux::date -- 'YYYY-MM-DD' is default ISO format anyway
, (r).libelle_flux
, (r).montant_flux
, (r).contre_valeur_dzd
, (r).rib_compte_bancaire
, (r).frais_flux
, (r).sens_flux
, (r).statut_flux
, (r).code_devise
, (r).code_mode_paiement
, (r).code_agence
, (r).code_compte
, (r).code_banque
, (r).date_maj_flux
, (r).statut_frais
, (r).reference_flux
, (r).code_commission
, (r).id_flux
FROM (SELECT %L::flux_tresorerie_historique) t(r)
$$, OLD::text)); -- cast whole row type
PERFORM dblink_disconnect();
RETURN NULL; -- only for AFTER trigger
END
$func$ LANGUAGE plpgsql;
Трябва да изпишете списъка с колони за целевата таблица, ако типовете редове не съвпадат.
Ако сте сериозни за това:
Т.е. вмъквате целия ред и целевият тип ред е идентичен (без извличане на дата от клеймо за време и т.н.), можете да опростите много повече, като прехвърлите целия ред.
CREATE OR REPLACE FUNCTION flux_tresorerie_historique_backup_row()
RETURNS trigger AS
$func$
BEGIN
PERFORM dblink_connect('myserver'); -- name of foreign server
PERFORM dblink_exec( format(
$$
INSERT INTO flux_tresorerie_historique
SELECT (%L::flux_tresorerie_historique).*
$$
, OLD::text));
PERFORM dblink_disconnect();
RETURN NULL; -- only for AFTER trigger
END
$func$ LANGUAGE plpgsql;
Свързани: