Используете открытое подключение к базе данных к PostgreSQL в BASH?

Мне нужно использовать BASH для подключения к нашему серверу базы данных PostgreSQL 9.1 для выполнения различных операторов SQL.

У нас проблема с производительностью, вызванная многократным открытием / закрытием слишком большого количества соединений с базой данных (прямо сейчас мы отправляем каждый оператор в команду psql).

Я рассматриваю возможность поддержания открытого соединения с базой данных для блока операторов SQL с использованием именованных каналов.

У меня проблема в том, что как только я открываю соединение и выполняю инструкцию SQL, я не знаю, когда прекратить чтение из psql. Я подумал о синтаксическом анализе вывода для поиска подсказки, хотя я не знаю, безопасно ли это, учитывая возможность того, что символ может быть встроен в вывод SELECT.

Есть ли у кого-нибудь предложения?

Вот упрощенный пример того, что у меня есть ...

#!/bin/bash

PIPE_IN=/tmp/pipe.in
PIPE_OUT=/tmp/pipe.out

mkfifo $PIPE_IN $PIPE_OUT
psql -A -t jkim_edr_md_xxx_db < $PIPE_IN > $PIPE_OUT &
exec 5> $PIPE_IN; rm -f $PIPE_IN
exec 4< $PIPE_OUT; rm -f $PIPE_OUT

echo 'SELECT * FROM some_table' >&5

# unfortunately, this loop blocks
while read -u 4 LINE
do
    echo LINE=$LINE
done

person Jin Kim    schedule 08.02.2012    source источник
comment
PostgreSQL поддерживает постоянные соединения. Вам не нужно постоянно открывать и закрывать связи.   -  person Xeoncross    schedule 08.02.2012


Ответы (3)


Используйте --file=filename для пакетного выполнения.

В зависимости от вашей потребности в управлении потоком вы можете использовать другой язык с более гибким API БД (я бы выбрал Python, но используйте все, что работает).

person Milen A. Radev    schedule 08.02.2012
comment
Мне нужно обрабатывать результаты операторов SQL индивидуально, поэтому я не думаю, что пакетное выполнение для меня подойдет. - person Jin Kim; 08.02.2012

            echo >&5 "SELECT * FROM some_table"

должен прочесть

            echo 'SELECT * FROM some_table' >&5

Оператор перенаправления >& идет после параметров на echo; а также, если вы используете "" кавычки, некоторые знаки препинания могут обрабатываться оболочкой особым образом, что впоследствии приведет к появлению грязных и загадочных ошибок. С другой стороны, цитировать ' будет… некрасиво. SELECT * FROM some_table WHERE foo=\'Can\'\'t read\''

Возможно, вы захотите также создать эти трубы в более безопасном месте, чем /tmp. Существует большое состояние гонки с дырой в безопасности, когда кто-то другой на хосте может перехватить ваше соединение. Попробуйте создать папку типа /var/run/yournamehere/ с 0700 привилегиями и создайте там каналы, в идеале с такими именами, как PIPE_IN=/var/run/jinkimsqltool/sql.pipe.in.$$ - $$ будет вашим идентификатором процесса, чтобы одновременно выполняемые скрипты не сбивали друг друга. (Чтобы усугубить брешь в безопасности, rm -rf не нужно для канала, но умный взломщик мог бы использовать это повышение привилегий, чтобы злоупотребить -r там. Достаточно всего rm -f.)

person BRPocock    schedule 08.02.2012
comment
Спасибо, я обновил свой пост с некоторыми вашими рекомендациями. - person Jin Kim; 08.02.2012

в psql вы можете использовать

\o YOUR_PIPE
SELECT whatever;
\o

который откроет, напишет и закроет трубу. Ваш БАШ-фу кажется намного сильнее моего, так что я позволю Вам разобраться в деталях :)

person maniek    schedule 09.02.2012