Gra*_*ett 30 postgresql capistrano ruby-on-rails
我有一个Rails应用程序,它使用PostgreSQL作为后端,具有试图模仿生产的证书环境,除了它需要定期重置数据库以进行QA.
当我db:reset
在部署期间尝试从Capistrano任务执行时,我收到错误:
ERROR: database "database_name" is being accessed by other users
并且数据库不能作为重置任务的一部分被删除,从而导致部署失败.有没有办法可以从Capistrano重置数据库连接,这样我就可以成功删除表格?从Capistrano任务管道SQL到psql可能会有效,但我想知道是否有更好的方法来解决这个问题.
dbe*_*hur 55
使用PostgreSQL,您可以发出以下语句来返回除此之外的所有打开连接的后端pids:
SELECT pid FROM pg_stat_activity where pid <> pg_backend_pid();
Run Code Online (Sandbox Code Playgroud)
然后,您可以向每个后端发出终止请求
SELECT pg_terminate_backend($1);
Run Code Online (Sandbox Code Playgroud)
将从第一个语句返回的pid绑定到每个pg_terminate_backend exec.
如果其他连接未使用与您相同的用户,则必须以超级用户身份连接才能成功发出终止.
更新:合并评论并表达为Capistrano任务:
desc "Force disconnect of open backends and drop database"
task :force_close_and_drop_db do
dbname = 'your_database_name'
run "psql -U postgres",
:data => <<-"PSQL"
REVOKE CONNECT ON DATABASE #{dbname} FROM public;
ALTER DATABASE #{dbname} CONNECTION LIMIT 0;
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE pid <> pg_backend_pid()
AND datname='#{dbname}';
DROP DATABASE #{dbname};
PSQL
end
Run Code Online (Sandbox Code Playgroud)
我把dbenhur的答案与这个Capistrano任务结合起来,以达到我需要的效果,就像一个魅力:
desc 'kill pgsql users so database can be dropped'
task :kill_postgres_connections do
run 'echo "SELECT pg_terminate_backend(procpid) FROM pg_stat_activity WHERE datname=\'database_name\';" | psql -U postgres'
end
Run Code Online (Sandbox Code Playgroud)
这假设用户postgres的auth_method在pg_hba.conf中设置为"trust"
然后,您可以在部署任务update_code
之前和之后调用它migrate
after 'deploy:update_code', 'kill_postgres_connections'
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
28133 次 |
最近记录: |