3

我必须使用 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
4

3 回答 3

1

用于--file=filename批量执行。

根据您对流控制的需要,您可能希望使用另一种具有更灵活 DB API 的语言(Python 将是我的选择,但使用任何可行的方法)。

于 2012-02-08T19:29:56.600 回答
0

在 psql 你可以使用

\o YOUR_PIPE
SELECT whatever;
\o

这将打开、写入和关闭管道。你的 BASH-fu 似乎比我的强很多,所以我会让你弄清楚细节:)

于 2012-02-09T22:51:37.120 回答
0
            echo >&5 "SELECT * FROM some_table"

应该读

            echo 'SELECT * FROM some_table' >&5

重定向运算符>&出现在参数 to 之后echo;而且,如果你使用""引号,一些标点符号可能会被 shell 特殊处理,导致后面的错误和神秘的错误。另一方面,引用'将是……丑陋的。SELECT * FROM some_table WHERE foo=\'Can\'\'t read\''

您可能还想在比/tmp. 存在一个很大的安全漏洞竞争条件,主机上的其他人可能会劫持您的连接。尝试创建一个/var/run/yournamehere/具有0700权限的文件夹,并在那里创建管道,理想情况下使用类似的名称PIPE_IN=/var/run/jinkimsqltool/sql.pipe.in.$$-$$将是您的进程 ID,因此同时执行的脚本不会相互干扰。(为了加剧安全漏洞,rm -rf管道不应该需要,但是一个聪明的破解者可以利用特权的提升来滥用-r那里。就rm -f足够了。)

于 2012-02-08T19:39:18.457 回答