Как преодолеть проблему с dblink, когда один сервер недоступен - PullRequest
0 голосов
/ 10 февраля 2020

Я создаю вид, подобный этому

 CREATE view  zaliha as
    SELECT * FROM public.dblink
('meteor','SELECT z.skladiste,ar.sifra,z.velicina,z.kolicina,z.rezervacija,z.kolicina - z.rezervacija
 as raspolozivo
 from zaliha z, artikli ar
 where ar.id=z.artikal
 and (kolicina <> 0 or kolicina <> 0)') 
AS DATA(skladiste CHARACTER VARYING, sifra CHARACTER VARYING, velicina CHARACTER VARYING, kolicina NUMERIC,
        rezervacija NUMERIC, raspolozivo NUMERIC)

        union

SELECT * FROM public.dblink
('dorcol','SELECT z.skladiste,ar.sifra,z.velicina,z.kolicina,z.rezervacija,z.kolicina - z.rezervacija
 as raspolozivo
 from zaliha z, artikli ar
 where ar.id=z.artikal
 and (kolicina <> 0 or kolicina <> 0)') 
AS DATA(skladiste CHARACTER VARYING, sifra CHARACTER VARYING, velicina CHARACTER VARYING, kolicina NUMERIC,
        rezervacija NUMERIC, raspolozivo NUMERIC)

        union

SELECT * FROM public.dblink
('uzice','SELECT z.skladiste,ar.sifra,z.velicina,z.kolicina,z.rezervacija,z.kolicina - z.rezervacija
 as raspolozivo
 from zaliha z, artikli ar
 where ar.id=z.artikal
 and (kolicina <> 0 or kolicina <> 0)') 
AS DATA(skladiste CHARACTER VARYING, sifra CHARACTER VARYING, velicina CHARACTER VARYING, kolicina NUMERIC,
        rezervacija NUMERIC, raspolozivo NUMERIC)

На самом деле это объединение трех одинаковых избранных, но с разных серверов. Что мне нужно, так это то, что я получаю результат всех доступных серверов, и если есть ошибка с 1 сервером, этот результат нужно исключить. Например, сервер meteor и dorcol доступны, а сервер uzice - нет, я хочу, чтобы этот результат отображался только для meteor и dorcol, и исключил ошибку с uzice.

ОШИБКА, когда один сервер недоступен:

ERROR:  could not establish connection

    DETAIL:  could not connect to server: Connection timed out
        Is the server running on host "x.x.x.x" and accepting
        TCP/IP connections on port 5432?

Возможно ли это?

1 Ответ

1 голос
/ 10 февраля 2020

Вы не можете сделать это с представлением, но вы можете сделать это с помощью функции возврата набора.

Я изменил это, чтобы использовать таблицу pgbench_branches для простоты.

CREATE OR REPLACE FUNCTION public.fail_tolerant()                                                                                                        
 RETURNS SETOF pgbench_branches
 LANGUAGE plpgsql
AS $function$ 
declare 
connections text[]='{host=127.0.0.1,host=192.168.0.bad}';
conn text;  
begin 
  foreach conn in array connections loop 
    begin
      return query SELECT * FROM public.dblink (conn,'SELECT * from pgbench_branches') AS DATA(bid integer, bbalance integer, filler character(88));
    EXCEPTION when others then          
       RAISE NOTICE 'exception caught';
    END;
  end loop;
end $function$;

Это не делает функцию дедупликации в UNION, поэтому вы хотели бы добавить это отдельно:

select distinct * from fail_tolerant();

Возможно, вы захотите сделать запись лучше, чем я здесь. Если какая-либо попытка подключения станет черной дырой, а не будет принята или отклонена немедленно, это может занять много времени. Таким образом, вы можете установить connect_timeout в каждой строке подключения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...