【问题标题】:Kill a postgresql session/connection杀死一个 postgresql 会话/连接
【发布时间】:2011-02-24 18:30:10
【问题描述】:

我怎样才能杀死我所有的 postgresql 连接?

我正在尝试rake db:drop,但我得到了:

ERROR:  database "database_name" is being accessed by other users
DETAIL:  There are 1 other session(s) using the database.

我已尝试关闭从 ps -ef | grep postgres 看到的进程,但这也不起作用:

kill: kill 2358 failed: operation not permitted

【问题讨论】:

  • 当所有其他尝试都失败时,pgreset gem 以某种方式修复 rails/pg 认为存在连接,但事实并非如此。

标签: database postgresql


【解决方案1】:

您可以使用pg_terminate_backend() 来终止连接。您必须是超级用户才能使用此功能。这在所有操作系统上都相同。

SELECT 
    pg_terminate_backend(pid) 
FROM 
    pg_stat_activity 
WHERE 
    -- don't kill my own connection!
    pid <> pg_backend_pid()
    -- don't kill the connections to other databases
    AND datname = 'database_name'
    ;

在执行此查询之前,您必须REVOKE CONNECT 权限以避免新连接:

REVOKE CONNECT ON DATABASE dbname FROM PUBLIC, username;

如果您使用的是 Postgres 8.4-9.1,请使用 procpid 而不是 pid

SELECT 
    pg_terminate_backend(procpid) 
FROM 
    pg_stat_activity 
WHERE 
    -- don't kill my own connection!
    procpid <> pg_backend_pid()
    -- don't kill the connections to other databases
    AND datname = 'database_name'
    ;

【讨论】:

  • 请注意,在 Postgres 9.2 中,procpid 被重命名为 pid。
  • 如果他是超级用户,他就不能让sudo-ed 杀死吗?
  • @ndn 数据库超级用户与操作系统级别的超级用户不同。 PG中没有sudo
  • 这是许多 SO 问题的唯一有效答案,因为它具有 REVOKE 步骤。你救了一个人,我猜还有一次!
  • 我认为即使您不是超级用户,您也可以使用SELECT pg_terminate_backend(pid) 来终止您自己的连接,但是,对于您自己的用户来说,使用REVOKE CONNECT ON DATABASE 可能不是最好的主意:)跨度>
【解决方案2】:

也许只是重启postgres => sudo service postgresql restart

【讨论】:

  • @Starkers 我浏览了上面的大部分答案,直到我明白了:)
  • @Starkers 是的,在高负载下的生产中尤其安全;)
  • brew services restart postgresql 如果你有 brew
  • 终极解决方案,谢谢。在 Windows 上:在搜索栏输入 services -> 找到您的 postgresql 服务 -> 单击 postgresql 服务 -> 然后单击左侧的 restart the service
  • 没有解决我的问题,但这个想法是合理的。
【解决方案3】:

包含有关正在运行的进程的所有信息:

SELECT *, pg_terminate_backend(pid)
FROM pg_stat_activity 
WHERE pid <> pg_backend_pid()
AND datname = 'my_database_name';

【讨论】:

    【解决方案4】:

    MacOS,如果 postgresqlbrew 一起安装:

    brew services restart postgresql
    

    来源:Kill a postgresql session/connection

    【讨论】:

      【解决方案5】:

      OSX,Postgres 9.2(随自制软件安装)

      $ launchctl unload -w ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist
      $ pg_ctl restart -D /usr/local/var/postgres
      $ launchctl load -w ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist
      


      如果您的数据目录在其他地方,您可以通过检查ps aux | grep postgres 的输出来找出它的位置

      【讨论】:

      • brew services restart postgresql
      • @PJSCopeland 感谢您提供最简单的解决方案!我认为您的评论应该是一个真正的答案,因此:stackoverflow.com/a/48226667/1097104
      • 谢谢你,@JuusoOhtonen。告诉你什么,如果你想从中获得声誉,你至少可以链接回我的评论?
      • @PJSCopeland 完成。
      • 对其他答案和其他类似的 SO 帖子解决方案有疑问。运行你的pg_ctl restart -D /usr/local/var/postgres 就成功了! (我什至没有运行第一个或第三个命令)。
      【解决方案6】:

      更简单更新的方法是:

      1. 使用ps -ef | grep postgres查找连接#
      2. 连接的sudo kill -9 "#"

      注意:可能存在相同的 PID。杀一杀一杀。

      【讨论】:

        【解决方案7】:
        SELECT 
        pg_terminate_backend(pid) 
        FROM 
        pg_stat_activity 
        WHERE
        pid <> pg_backend_pid()
        -- no need to kill connections to other databases
        AND datname = current_database();
        -- use current_database by opening right query tool
        

        【讨论】:

          【解决方案8】:

          这似乎适用于 PostgreSQL 9.1:

          #{Rails.root}/lib/tasks/databases.rake
          # monkey patch ActiveRecord to avoid There are n other session(s) using the database.
          def drop_database(config)
            case config['adapter']
            when /mysql/
              ActiveRecord::Base.establish_connection(config)
              ActiveRecord::Base.connection.drop_database config['database']
            when /sqlite/
              require 'pathname'
              path = Pathname.new(config['database'])
              file = path.absolute? ? path.to_s : File.join(Rails.root, path)
          
              FileUtils.rm(file)
            when /postgresql/
              ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public'))
              ActiveRecord::Base.connection.select_all("select * from pg_stat_activity order by procpid;").each do |x|
                if config['database'] == x['datname'] && x['current_query'] =~ /<IDLE>/
                  ActiveRecord::Base.connection.execute("select pg_terminate_backend(#{x['procpid']})")
                end
              end
              ActiveRecord::Base.connection.drop_database config['database']
            end
          end
          

          从发现 herehere 的要点中提取。

          Here's a modified version 适用于 PostgreSQL 9.1 和 9.2。

          【讨论】:

            【解决方案9】:

            我使用以下 rake 任务来覆盖 Rails drop_database 方法。

            lib/database.rake

            require 'active_record/connection_adapters/postgresql_adapter'
            module ActiveRecord
              module ConnectionAdapters
                class PostgreSQLAdapter < AbstractAdapter
                  def drop_database(name)
                    raise "Nah, I won't drop the production database" if Rails.env.production?
                    execute <<-SQL
                      UPDATE pg_catalog.pg_database
                      SET datallowconn=false WHERE datname='#{name}'
                    SQL
            
                    execute <<-SQL
                      SELECT pg_terminate_backend(pg_stat_activity.pid)
                      FROM pg_stat_activity
                      WHERE pg_stat_activity.datname = '#{name}';
                    SQL
                    execute "DROP DATABASE IF EXISTS #{quote_table_name(name)}"
                  end
                end
              end
            end
            

            编辑:这是用于 Postgresql 9.2+

            【讨论】:

            • Postgres 9.1 及以下版本需要使用pg_stat_activity.procpid 而不是pg_stat_activity.pid。见stackoverflow.com/a/5408501/444774
            • 这是一个很好的答案!它比 Rails 的默认设置更好、更安全。谢谢!
            【解决方案10】:

            我遇到了这个问题,问题是 Navicat 连接到我本地的 Postgres 数据库。一旦我断开 Navicat,问题就消失了。

            编辑:

            另外,as an absolute last resort 你可以备份你的数据然后运行这个命令:

            sudo kill -15 `ps -u postgres -o pid`
            

            ... 这将杀死 postgres 用户正在访问的所有内容。避免在生产机器上执行此操作,但开发环境不应该有问题。在此之后尝试重新启动 PostgreSQL 之前,确保 每个 postgres 进程确实已终止,这一点至关重要。

            编辑 2:

            由于this unix.SE post,我已从kill -9 更改为kill -15

            【讨论】:

            • 在我对 Navicat Lite 的有限经验中,仅仅关闭数据库或服务器连接并不总是足够的。 Navicat Lite 似乎会保持偶尔的连接打开,直到应用程序终止。
            【解决方案11】:

            我已经解决了这个方法:

            在我的 Windows8 64 位中,只需 restarting 服务:postgresql-x64-9.5

            【讨论】:

            • 这只是重新启动,这对于生产环境来说通常是不可取的,杀死拥抱进程是一个更可取的选择。
            【解决方案12】:

            如果您需要断开特定用户的会话,这对我有帮助:

            检查所有当前连接:

            select * from pg_stat_activity; 
            

            向您的用户授予角色(不重要):

            set role "db_admin";
            

            终止会话:

            select pg_terminate_backend(pid)
            from pg_stat_activity
            where usename = '*** USER NAME TO DISCONNECT ***';
            

            【讨论】:

              【解决方案13】:

              MacOS,如果 postgresql 是用 brew 安装的:

              brew services restart postgresql
              

              UBUNTU,

              首先检查这个(杀死在后台运行的服务器)

              sudo kill -9 $(lsof -i :3000 -t)
              

              如果你没有找到 pid 那么你只需要重新启动 所提及的 Postgresql 服务命令如下:

              sudo service postgresql restart
              

              【讨论】:

                【解决方案14】:

                在 PG admin 中,您可以断开服务器(右键单击服务器)& 所有会话将在重新启动时断开

                【讨论】:

                  【解决方案15】:

                  退出 postgres 并重新启动它。很简单,但每次都对我有用,而其他 cli 命令有时却不行。

                  【讨论】:

                  • 简单有效!进一步澄清 pgAdmin 4 并重新启动
                  【解决方案16】:

                  只是想指出,如果其他后台进程正在使用数据库,Haris's Answer 可能不起作用,在我的情况下,它是延迟作业,我做到了:

                  script/delayed_job stop
                  

                  只有这样我才能删除/重置数据库。

                  【讨论】:

                    【解决方案17】:

                    远程场景。但是如果你尝试在 Rails 应用程序中运行测试,你会得到类似

                    “ActiveRecord::StatementInvalid: PG::ObjectInUse: ERROR: 数据库“myapp_test”正在被其他用户访问 详细信息:还有 1 个会话正在使用该数据库。”

                    确保在运行测试之前关闭 pgAdmin 或任何其他 postgres GUI 工具。

                    【讨论】:

                      【解决方案18】:

                      我在 Mac 上,我通过 Postgres.app 使用 postgres。我解决了这个问题,只是退出并重新启动应用程序。

                      【讨论】:

                        【解决方案19】:

                        打开 PGadmin 查看是否有任何查询页面打开,关闭所有查询页面并断开 PostgresSQL 服务器并再次连接并尝试删除/删除选项。这对我有帮助。

                        【讨论】:

                          【解决方案20】:

                          没有必要放弃它。只需删除并重新创建公共架构。在大多数情况下,这具有完全相同的效果。

                          namespace :db do
                          
                          desc 'Clear the database'
                          task :clear_db => :environment do |t,args|
                            ActiveRecord::Base.establish_connection
                            ActiveRecord::Base.connection.tables.each do |table|
                              next if table == 'schema_migrations'
                              ActiveRecord::Base.connection.execute("TRUNCATE #{table}")
                            end
                          end
                          
                          desc 'Delete all tables (but not the database)'
                          task :drop_schema => :environment do |t,args|
                            ActiveRecord::Base.establish_connection
                            ActiveRecord::Base.connection.execute("DROP SCHEMA public CASCADE")
                            ActiveRecord::Base.connection.execute("CREATE SCHEMA public")
                            ActiveRecord::Base.connection.execute("GRANT ALL ON SCHEMA public TO postgres")
                            ActiveRecord::Base.connection.execute("GRANT ALL ON SCHEMA public TO public")
                            ActiveRecord::Base.connection.execute("COMMENT ON SCHEMA public IS 'standard public schema'")
                          end
                          
                          desc 'Recreate the database and seed'
                          task :redo_db => :environment do |t,args|
                            # Executes the dependencies, but only once
                            Rake::Task["db:drop_schema"].invoke
                            Rake::Task["db:migrate"].invoke
                            Rake::Task["db:migrate:status"].invoke 
                            Rake::Task["db:structure:dump"].invoke
                            Rake::Task["db:seed"].invoke
                          end
                          
                          end
                          

                          【讨论】:

                            【解决方案21】:

                            案例:
                            查询执行失败:

                            DROP TABLE dbo.t_tabelname
                            

                            解决方案:
                            一种。显示查询状态活动如下:

                            SELECT * FROM pg_stat_activity  ;
                            

                            b.查找“查询”列包含的行:

                            'DROP TABLE dbo.t_tabelname'
                            

                            c。在同一行中,获取 'PID' 列的值

                            example : 16409
                            

                            d。执行这些脚本:

                            SELECT 
                                pg_terminate_backend(25263) 
                            FROM 
                                pg_stat_activity 
                            WHERE 
                                -- don't kill my own connection!
                                25263 <> pg_backend_pid()
                                -- don't kill the connections to other databases
                                AND datname = 'database_name'
                                ;
                            

                            【讨论】:

                              【解决方案22】:

                              我做了以下工作:

                              sudo gitlab-ctl stop
                              sudo gitlab-ctl start gitaly
                              sudo gitlab-rake gitlab:setup [type yes and let it finish]
                              sudo gitlab-ctl start
                              

                              我正在使用:
                              gitlab_edition:“gitlab-ce”
                              gitlab_version: '12.4.0-ce.0.el7'

                              【讨论】:

                                【解决方案23】:

                                上面的答案之一肯定给了我在 Windows 中解决它的想法。

                                从 Windows 打开服务,找到 Postgres 服务并重新启动它。

                                【讨论】:

                                  【解决方案24】:

                                  答案隐藏在上面的其中一个 cmets 中:brew services restart postgresql

                                  【讨论】:

                                    猜你喜欢
                                    • 1970-01-01
                                    • 2011-03-11
                                    • 1970-01-01
                                    • 1970-01-01
                                    • 1970-01-01
                                    • 2011-07-08
                                    • 1970-01-01
                                    • 2011-08-11
                                    • 2014-11-19
                                    相关资源
                                    最近更新 更多