首页 文章

如果有一个活动的连接,如何删除PostgreSQL数据库?

提问于
浏览
531

我需要编写一个将删除PostgreSQL数据库的脚本 . 它可能有很多连接,但脚本应该忽略它 .

当存在打开的连接时,标准 DROP DATABASE db_name 查询不起作用 .

我该如何解决这个问题?

10 回答

  • 12

    在我的情况下,我必须执行一个命令来删除所有连接,包括我的活动管理员连接

    SELECT pg_terminate_backend(pg_stat_activity.pid)
    FROM pg_stat_activity
    WHERE datname = current_database()
    

    它终止了所有连接,并向我显示致命的“错误”消息:

    FATAL: terminating connection due to administrator command SQL state: 57P01

    之后可以删除数据库

  • 102

    在PostgreSQL 9.2及更高版本中,要从连接到的数据库中断开除会话之外的所有内容:

    SELECT pg_terminate_backend(pg_stat_activity.pid)
    FROM pg_stat_activity
    WHERE datname = current_database()
      AND pid <> pg_backend_pid();
    

    在旧版本中它是相同的,只需将 pid 更改为 procpid . 要断开与其他数据库的连接,只需将 current_database() 更改为要断开用户连接的数据库的名称 .

    在断开用户连接之前,您可能希望从数据库用户那里获得 CONNECT 权利,否则用户将继续重新连接,您将永远不会有机会丢弃数据库 . 请参阅this comment以及与之关联的问题How do I detach all other users from the database .

    如果您只想断开空闲用户,请参阅this question .

  • 0

    我只是在Ubuntu中重启服务以断开连接的客户端 .

    sudo service postgresql stop
    sudo service postgresql start
    
    psql
    DROP DATABASE DB_NAME;
    
  • 7

    根据您的postgresql版本,您可能会遇到错误,这会使 pg_stat_activity 省略被删除用户的活动连接 . 这些连接也未在pgAdminIII中显示 .

    如果您正在进行自动测试(您也在其中创建用户),这可能是一种可能的情况 .

    在这种情况下,您需要恢复以下查询:

    SELECT pg_terminate_backend(procpid) 
     FROM pg_stat_get_activity(NULL::integer) 
     WHERE datid=(SELECT oid from pg_database where datname = 'your_database');
    

    注意:在9.2中,您将 procpid 更改为 pid .

  • 919

    您可以在使用 pg_terminate_backend(int) 函数删除数据库之前终止所有连接 .

    您可以使用系统视图 pg_stat_activity 获取所有正在运行的后端

    我不完全确定,但以下可能会杀死所有会话:

    select pg_terminate_backend(procpid)
    from pg_stat_activity
    where datname = 'doomed_database'
    

    当然,您可能无法将自己连接到该数据库

  • 4

    我注意到postgres 9.2现在调用列pid而不是procpid .

    我倾向于从shell中调用它:

    #!/usr/bin/env bash
    # kill all connections to the postgres server
    if [ -n "$1" ] ; then
      where="where pg_stat_activity.datname = '$1'"
      echo "killing all connections to database '$1'"
    else
      echo "killing all connections to database"
    fi
    
    cat <<-EOF | psql -U postgres -d postgres 
    SELECT pg_terminate_backend(pg_stat_activity.pid)
    FROM pg_stat_activity
    ${where}
    EOF
    

    希望有所帮助 . 感谢@JustBob为sql .

  • 16

    在Linux命令提示符中,我将首先通过绑定此命令来停止所有正在运行的postgresql进程 sudo /etc/init.d/postgresql restart

    键入命令 bg 以检查其他postgresql进程是否仍在运行

    然后 dropdb dbname 删除数据库

    sudo /etc/init.d/postgresql restart
    bg
    dropdb dbname
    

    这对我在linux命令提示符下工作

  • 7

    PostgreSQL 9.2 and above:

    SELECT pg_terminate_backend(pid)FROM pg_stat_activity WHERE datname = 'YOUR_DATABASE_NAME_HERE'

  • 3

    这将删除除您的连接之外的现有连接:

    查询 pg_stat_activity 并获取要杀死的pid值,然后向它们发出 SELECT pg_terminate_backend(pid int) .

    PostgreSQL 9.2 and above:

    SELECT pg_terminate_backend(pg_stat_activity.pid)
    FROM pg_stat_activity
    WHERE pg_stat_activity.datname = 'TARGET_DB' -- ← change this to your DB
      AND pid <> pg_backend_pid();
    

    PostgreSQL 9.1 and below:

    SELECT pg_terminate_backend(pg_stat_activity.procpid)
    FROM pg_stat_activity
    WHERE pg_stat_activity.datname = 'TARGET_DB' -- ← change this to your DB
      AND procpid <> pg_backend_pid();
    

    一旦断开所有人的连接,您将不得不断开连接,并从另一个数据库(即您尝试删除的数据库)的连接发出DROP DATABASE命令 .

    请注意将 procpid 列重命名为 pid . 见this mailing list thread .

  • 25

    这是我的黑客... = D.

    # Make sure no one can connect to this database except you!
    sudo -u postgres /usr/pgsql-9.4/bin/psql -c "UPDATE pg_database SET datallowconn=false WHERE datname='<DATABASE_NAME>';"
    
    # Drop all existing connections except for yours!
    sudo -u postgres /usr/pgsql-9.4/bin/psql -c "SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = '<DATABASE_NAME>' AND pid <> pg_backend_pid();"
    
    # Drop database! =D
    sudo -u postgres /usr/pgsql-9.4/bin/psql -c "DROP DATABASE <DATABASE_NAME>;"
    

    我把这个答案放在一边,因为包含一个命令(上面)来阻止新连接,因为 any attempt with the command ...

    REVOKE CONNECT ON DATABASE <DATABASE_NAME> FROM PUBLIC, <USERS_ETC>;
    

    ...不能阻止新连接!

    感谢@araqnid @GoatWalker! = d

    https://stackoverflow.com/a/3185413/3223785

相关问题