在PostgreSQL 12上使用单个CLI命令终止所有打开的连接



我有一个CLI命令,如下所示:

$ psql -U postgres < <(psql -U postgres -Atc "select 'SELECT pg_terminate_backend(pid) 
FROM pg_stat_activity WHERE datname = ''||datname||''; /* I WILL ADD MORE QUERIES HERE LATER. */
'from pg_database where 
datistemplate=false AND datname != 'postgres';")

实际结果:

ERROR:  syntax error at or near ""
LINE 2: FROM pg_stat_activity WHERE datname = ''||datname||'';
^

预期结果:

WHERE datname = 'database_name'
-- instead of
WHERE datname = ''||datname||''

这将为每个找到的数据库实例打印并回显到psql。但是,datname未正确填充。这是因为'(Escape?(。如何在此CLI命令中终止与postgres以外的数据库的打开连接修复此命令?为什么我不能在这里填充||datname||

目标:

我的目标是删除除postgres数据库之外的所有数据库的所有连接(如果有的话(。但是通过在CLI/Bash中执行此操作。不是通过登录sudo -u postgres。我只想通过CLI断开所有连接。我将在CI/CD系统中使用它,因此用户交互是不可能的。

您的单引号不需要受到shell的保护,因为它们已经在双引号中了。为了保护它们免受psql的攻击,你可以加倍它们,而不是反击它们。所以

psql -U postgres < <(psql -U postgres -Atc "select 'SELECT pg_terminate_backend(pid) 
FROM pg_stat_activity WHERE datname = '''||datname||'''; /* I WILL ADD MORE QUERIES HERE LATER. */
'from pg_database where 
datistemplate=false AND datname != 'postgres';")

但是,您可能可以使用gexec来改进这一点,只需要一个psql调用,而不是两个。

最新更新