postgresqlセッション/接続を強制終了します


370

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はなんらかの方法でレール/ pgを修正し、接続が存在すると考えていましたが、そうではありませんでした。
JosephK

回答:


672

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'
    ;

このクエリを実行する前に、新しい接続を回避するためにCONNECT権限を取り消す必要があります。

REVOKE CONNECT ON DATABASE dbname FROM PUBLIC, username;

Postgres 8.4-9.1を使用している場合は、pidの代わりにprocpidを使用します

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'
    ;

68
Postgres 9.2では、procpidの名前がpidに変更されています。
Devin

彼がスーパーユーザーだったら、sudoとにかく殺すことができなかったのではないでしょうか。
ndnenkov 2016年

3
@ndnデータベースのスーパーユーザーは、OSレベルのスーパーユーザーとは異なります。sudoPGにはありません。
jpmc26 2016

これにはREVOKEステップがあるため、多くのSOの質問に対する唯一の有効な答えです。あなたは誰かを救った、私が推測するもう一度もう一度!
AymDev

これは感謝します...
Ajay Kumar

205

多分ちょうど再起動postgres=>sudo service postgresql restart


@Starkers私は上の答えのほとんどを通り抜けました、それが私に気づいたまでです:)
Haris Krajina '18

32
@Starkersはい、特に高負荷下での生産で安全です;)
Erathiel

10
brew services restart postgresql醸造している場合
Sam Kah Chiin

28

実行中のプロセスに関するすべての情報:

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


13

OSX、Postgres 9.2(homebrewとともにインストール)

$ 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


datadirが他の場所にある場合は、次の出力を調べることで、それがどこにあるかを確認できます ps aux | grep postgres


4
またはbrew services restart postgresql
PJSCopeland 2017年

@PJSCopeland非常にシンプルなソリューションをありがとう!私はあなたのコメントが本当の答えになるに値すると思います:したがって、stackoverflow.com
a / 48226667/1097104

@JuusoOhtonen、ありがとうございます。ただし、評判が欲しい場合は、少なくとも私のコメントにリンクを張ることができますか。
PJSCopeland 2018年

@PJSCopeland完了。
Juuso Ohtonen

他の回答や他の同様のSO投稿ソリューションに問題がありました。あなたの実行pg_ctl restart -D /usr/local/var/postgresはトリックをしました!(私は最初または3番目のコマンドも実行しませんでした)。
イギー

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

ここここで見つかっ要点から解放さました

これは、PostgreSQL 9.1と9.2の両方で機能する修正バージョンです。


6

Rails drop_databaseメソッドをオーバーライドするには、次のrakeタスクを使用します。

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以降用です


pg_stat_activity.procpid代わりにpg_stat_activity.pidPostgres 9.1以下を使用する必要があります。「stackoverflow.com/a/5408501/444774
talyric

1
これは素晴らしい答えです!Railsのデフォルトよりも優れており、安全です。ありがとう!
piersadrian 2013

5

より簡単で更新された方法は次のとおりです。

  1. ps -ef | grep postgres接続を見つけるために使用#
  2. sudo kill -9 "#" 接続の

注:同一のPIDが存在する場合があります。1人を殺すと、すべてが殺されます。


3

私にはこの問題があり、問題はNavicatが私のローカルのPostgres dbに接続されていることでした。Navicatを切断すると、問題は消えました。

編集:

また、最後の手段として、データをバックアップしてから次のコマンドを実行できます。

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

... postgresユーザーがアクセスしているものすべてを殺します。本番マシンではこれを行わないでください。ただし、開発環境に問題はないはずです。あなたがすべてを確保することが重要です postgresこの後、PostgreSQLを再起動する前に、プロセスが本当に終了して。

編集2:

このunix.SEの投稿により、からkill -9に変更しましたkill -15


1
Navicat Liteの私の限られた経験では、データベースまたはサーバー接続を閉じるだけでは必ずしも十分ではありません。Navicat Liteはアプリケーションが終了するまで時々接続を開いたままにしているようです。

3

私はこれを解決しました:

私のWindows8 64ビットでrestartは、サービスを使用するだけです:postgresql-x64-9.5


5
それは単に再起動を行うだけであり、一般に本番環境では望ましくありません。ハグプロセスを強制終了することは、はるかに望ましいオプションです。
BrianC 2017

3
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

1

他のバックグラウンドプロセスがデータベースを使用している場合はHarisの回答が機能しない可能性があることを指摘したかったのですが、私の場合は遅延ジョブでした。

script/delayed_job stop

それから初めて、データベースを削除/リセットすることができました。


1

postgresを終了して再起動します。単純ですが、他のcliコマンドが機能しない場合があるため、私にとっては常に機能します。


シンプルで動作します!pgAdmin 4をさらに明確にして再起動するには
Ka Tech

0

落とす必要はありません。パブリックスキーマを削除して再作成するだけです。ほとんどの場合、これはまったく同じ効果があります。

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

0

リモートシナリオ。しかし、railsアプリでテストを実行しようとしていて、次のような結果が得られた場合

"ActiveRecord :: StatementInvalid:PG :: ObjectInUse:ERROR:データベース" myapp_test "が他のユーザーによってアクセスされています詳細:データベースを使用している他のセッションが1つあります。"

テストを実行する前に、pgAdminまたは他のpostgres GUIツールを必ず閉じてください。


0

ケース:
クエリの実行に失敗しました:

DROP TABLE dbo.t_tabelname

解決策:
a。クエリステータスアクティビティを次のように表示します。

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'
    ;

0

私はMacを使用していて、経由でpostgresを使用していPostgres.appます。アプリを終了して再起動するだけでこの問題を解決しました。


0

PGadminを開いて、クエリページが開いているかどうかを確認し、すべてのクエリページを閉じて、PostgresSQLサーバーを切断し、再度接続して、削除/ドロップオプションを試してください。これが役に立ちました。



0

私にとっては次のように働きました:

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 '


0

まず、実行を移植しているPostgresを見つけます。

  1. ps -ef | grep postgres

    ポート番号を返します

  2. -9を殺す port_number

ついに再びPostgresを起動します

brew services start postgresql 
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.