postgrespro / pg_pathman

Partitioning tool for PostgreSQL
Other
584 stars 68 forks source link

Добавить варианты обработки потери связи с fdw-партицией #89

Open darthunix opened 7 years ago

darthunix commented 7 years ago

Если в родительскую таблицу добавить партицию, располагающейся на внешнем сервере через fdw, и симулировать потерю связи с внешним сервером, родительская таблица становится недоступной. sandbox=# select * from parent; ERROR: could not connect to server "pgpro" DETAIL: could not connect to server: Connection refused Is the server running on host "192.168.5.179" and accepting TCP/IP connections on port 5433? В некоторых случаях это правильное поведение. Но иногда хотелось бы, чтобы родительская таблица оставалась доступна на чтение, просто из нее пропадали данные из внешней партиции. Это возможно? P.S. Я понимаю, что скорее всего нет, так как вы сейчас добавляете возможность ссылаться внешними ключами на родительскую таблицу и часть пропавших данных может стать проблемой. Но вдруг...))

funbringer commented 7 years ago

Привет, @darthunix!

В некоторых случаях это правильное поведение. Но иногда хотелось бы, чтобы родительская таблица оставалась доступна на чтение, просто из нее пропадали данные из внешней партиции.

Я думаю, это можно устроить, но для такой фичи потребуется модификация postgres_fdw.

В данный момент мы работаем над шардингом и связанными с ним фичами, для которых уже требуется модифицированный postgres_fdw. Мы подумаем, но я не обещаю, что эта возможность будет добавлена.

funbringer commented 7 years ago

Обсуждал с коллегами похожую задачу, в результате чего удалось кое-что придумать.

Для foreign server можно перечислить несколько хостов через запятую:

select srvname, srvoptions from pg_foreign_server ;
    srvname     |                             srvoptions
----------------+--------------------------------------------------------------------
 pathman_server | {port=5432,"host=192.168.27.193,localhost",dbname=pathman_foreign}
(1 row)

Если мы создадим локальную базу pathman_foreign с пустой копией таблицы, то при потере соединения следующий запрос переключится на локальную копию:

select * from test;
 val 
-----
   1
(1 row)

select * from test;
ERROR:  server closed the connection unexpectedly
        This probably means the server terminated abnormally
        before or while processing the request.
CONTEXT:  Remote SQL command: START TRANSACTION ISOLATION LEVEL REPEATABLE READ

select * from test;
 val 
-----
(0 rows)
darthunix commented 7 years ago

Вы используете пропатченную версию foreign server? У меня не получается на ванильном pg 9.6 завести работу с внешним сервером, подключенным к нескольким хостам...

Как я проверял. Есть два сервера - localhost и 192.168.5.179. На каждом поднят экземпляр pg 9.6 на порту 5432 с базой, содержащей одинаковую по структуре таблицу public.slave(id integer) - на localhost она пустая, на 192.168.5.179 содержит записи. Так же на localhost базе есть внешняя таблица slave_fdw, подключенная к таблице slave с записями на 192.168.5.179. Когда я создаю на localhost foreign server с одним хостом, то вполне успешно запрашиваю данные из внешней таблицы

test=# select srvname, srvoptions from pg_foreign_server;
 srvname |                 srvoptions                 
---------+--------------------------------------------
 slave   | {dbname=test,host=192.168.5.179,port=5432}

test=# select * from slave_fdw;
 id 
----
  1
  2

Когда прописываю в хосты внешнего сервера 192.168.5.179 и localhost, то получаю ошибку.

test=# select srvname, srvoptions from pg_foreign_server;
 srvname |                       srvoptions                       
---------+--------------------------------------------------------
 slave   | {dbname=test,"host=192.168.5.179,localhost",port=5432}

test=# select * from slave_fdw;
ERROR:  could not connect to server "slave"
DETAIL:  could not translate host name "192.168.5.179,localhost" to address: Name or service not known

У озвученного вами решения сразу заметна одна проблема - базы должны иметь одно и то же имя и экземпляры pg слушать одинаковый порт.

funbringer commented 7 years ago

Вы используете пропатченную версию foreign server? У меня не получается на ванильном pg 9.6 завести работу с внешним сервером, подключенным к нескольким хостам...

Это я сплоховал: тестировал на сборке Postgres Pro Enterprise. У нас есть патчи для libpq, благодаря которым она умеет работать с несколькими хостами. Так как postgres_fdw сделан именно через libpq, он автоматически поддерживает такое поведение. В 10 версии постгреса будет похожая функциональность.

У озвученного вами решения сразу заметна одна проблема - базы должны иметь одно и то же имя и экземпляры pg слушать одинаковый порт.

Справедливо.