Postgresql oturumunu / bağlantısını öldür


369

Tüm postgresql bağlantılarımı nasıl öldürebilirim?

Deniyorum rake db:dropama anladım:

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

Gördüğüm süreçleri kapatmayı denedim ps -ef | grep postgresama bu da işe yaramıyor:

kill: kill 2358 failed: operation not permitted

Diğer tüm denemeler başarısız olduğunda, pgreset mücevher bir şekilde var olan bir bağlantı olduğunu düşünerek sabit raylar / pg sabitledi.
JosephK

Yanıtlar:


671

Bir bağlantıyı öldürmek için pg_terminate_backend () kullanabilirsiniz. Bu işlevi kullanabilmek için süper kullanıcı olmalısınız. Bu, tüm işletim sistemlerinde aynı şekilde çalışır.

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

Bu sorguyu yürütmeden önce, yeni bağlantılardan kaçınmak için CONNECT ayrıcalıklarını REVOKE yapmanız gerekir :

REVOKE CONNECT ON DATABASE dbname FROM PUBLIC, username;

Postgres 8.4-9.1 kullanıyorsanız pid yerine procpid kullanın

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'de procpid'in pid olarak yeniden adlandırıldığını unutmayın.
Devin

Eğer bir süper kullanıcı olsaydı sudo, öldürmeyi yine de yapamaz mıydı ?
ndnenkov

3
@ndn Bir veritabanı süper kullanıcısı, işletim sistemi düzeyinde bir süper kullanıcıyla aynı şey değildir. sudoPG'de yok .
jpmc26

Bu, birçok SO sorusunun tek çalışma cevabıdır çünkü bir REVOKEadım vardır. Birini kurtardın, sanırım bir kez daha!
AymDev

Bu çalışıyor teşekkürler ....
Ajay Kumar

205

Belki sadece yeniden başlat postgres=>sudo service postgresql restart


@ Başlatıcılar Yukarıdaki cevapların çoğundan geçtim, bu benim üzerime gelene kadar :)
Haris Krajina

32
@ Starkers Evet, özellikle yüksek yük altında üretimde güvenlidir;)
Erathiel

10
brew services restart postgresqlEğer u
demlediysen

28

Çalışan işlemle ilgili tüm bilgilerle:

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 ile kurulu)

$ 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'iniz başka bir yerde ise, çıktısını inceleyerek bunun nerede olduğunu öğrenebilirsiniz. ps aux | grep postgres


4
Veyabrew services restart postgresql
PJSCopeland

@PJSCopeland En basit çözüm için teşekkürler! Bence yorumunuz gerçek bir cevap olmayı hak ediyor: stackoverflow.com/a/48226667/1097104
Juuso Ohtonen

Bunun için teşekkürler, @JuusoOhtonen. Ne söyleyeyim, ondan itibar istiyorsanız, en azından yorumuma geri dönebilirsiniz?
PJSCopeland

@PJSCopeland Tamamlandı.
Juuso Ohtonen

Diğer cevaplar ve diğer benzer SO post çözümleri ile ilgili sorunlar vardı. Koşmak pg_ctl restart -D /usr/local/var/postgreshile yaptı! (Birinci veya üçüncü komutu bile çalıştırmadım).
Iggy

8

Bu PostgreSQL 9.1 için çalışıyor gibi görünüyor:

#{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

Burada ve burada bulunan gistlerden kaldırıldı .

İşte PostgreSQL 9.1 ve 9.2 için çalışan değiştirilmiş bir sürüm .


6

Rails drop_databaseyöntemini geçersiz kılmak için aşağıdaki komisyon görevini kullanın .

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

Düzenle: Bu Postgresql 9.2+ içindir


Postgres 9.1 ve altı için pg_stat_activity.procpidyerine kullanmanız gerekir pg_stat_activity.pid. Bkz. Stackoverflow.com/a/5408501/444774
talyric

1
Bu harika bir cevap! Rails varsayılanından daha iyi ve daha güvenlidir. Teşekkürler!
piersadrian

5

Daha kolay ve daha güncel bir yol:

  1. ps -ef | grep postgres# Bağlantısını bulmak için kullanın
  2. sudo kill -9 "#" bağlantının

Not: Aynı PID olabilir. Birini öldürmek hepsini öldürür.


3

Bu sorun vardı ve sorun Navicat benim yerel Postgres db bağlı oldu. Navicat'ın bağlantısını kestikten sonra sorun ortadan kalktı.

DÜZENLE:

Ayrıca, mutlak son çare olarak verilerinizi yedekleyebilir ve şu komutu çalıştırabilirsiniz:

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

... postgres kullanıcısının eriştiği her şeyi öldürecek. Bunu bir üretim makinesinde yapmaktan kaçının, ancak geliştirme ortamıyla ilgili bir sorununuz olmamalıdır. Bundan sonra PostgreSQL'i yeniden başlatmadan önce her postgres sürecin gerçekten sonlandırıldığından emin olmanız çok önemlidir .

DÜZENLEME 2:

Nedeniyle bu unix.SE yazı ben den değiştirdik kill -9için kill -15.


1
Navicat Lite ile sınırlı deneyimimde, sadece veritabanını veya sunucu bağlantısını kapatmak her zaman yeterli değildir. Navicat Lite, uygulama sonlandırılana kadar ara sıra bağlantıyı açık tutuyor gibi görünüyor.
ken

3

BU YOLU ÇÖZDÜM:

Benim içinde Windows8 64 bit, sadece restarthizmet ing: postgresql-x64-9.5


5
Bu sadece üretim ortamları için genellikle arzu edilmeyen bir yeniden başlatma yapmaktır, kucaklama sürecini öldürmek çok daha arzu edilen bir seçenektir.
BrianC

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

Sadece başka bir arka plan işlemi veritabanını kullanıyorsa, Haris'in cevabının işe yaramayabileceğini belirtmek istedim, benim durumumda işler gecikti, yaptım:

script/delayed_job stop

Ve ancak o zaman veritabanını bırakıp sıfırlayabildim.


1

Postgreslerden çıkın ve yeniden başlatın. Basit, ama benim için her zaman çalışır, diğer cli komutları bazen işe yaramaz.


Basit ve çalışıyor! Daha fazla netleştirmek için pgAdmin 4 ve yeniden başlatın
Ka Tech

0

Onu düşürmeye gerek yok. Genel şemayı silin ve yeniden oluşturun. Çoğu durumda bunun etkisi tamamen aynıdır.

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

Uzak senaryo. Ancak, bir raylar uygulamasında testler yapmaya çalışıyorsanız ve

"ActiveRecord :: StatementInvalid: PG :: ObjectInUse: HATA: veritabanı" myapp_test "diğer kullanıcılar tarafından erişiliyor DETAY: Veritabanını kullanan 1 oturum daha var."

Testleri çalıştırmadan önce pgAdmin veya diğer postgres GUI araçlarını kapattığınızdan emin olun.


0

Vaka:
Sorgu yürütülemedi:

DROP TABLE dbo.t_tabelname

Çözüm:
a. Sorgu Durum Etkinliğini aşağıdaki gibi görüntüle:

SELECT * FROM pg_stat_activity  ;

b. 'Sorgu' sütununun bulunduğu satırı bulun:

'DROP TABLE dbo.t_tabelname'

c. Aynı satırda, 'PID' Sütununun değerini alın

example : 16409

d. Şu komut dosyalarını yürütün:

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'liyim ve üzerinden postgres kullanıyorum Postgres.app. Ben sadece app çıkıp ve tekrar başlayan bu sorunu çözdü.


0

PGadmin'i açın, açık bir sorgu sayfası olup olmadığını görün, tüm sorgu sayfasını kapatın ve PostgresSQL sunucusunun bağlantısını kesin ve tekrar bağlayın ve sil / bırak seçeneğini deneyin.Bu bana yardımcı oldu.


0

PG yöneticisinde sunucunuzun bağlantısını kesebilirsiniz (sunucuya sağ tıklayın) ve yeniden başlatma sırasında tüm oturumların bağlantısı kesilir


0

Benim için çalıştı:

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


Kullanıyorum : gitlab_edition: "gitlab-ce"
gitlab_version: '12 .4.0-ce.0.el7 '


0

İlk olarak, çalıştığını gösteren Postgres'i bulun

  1. ps -ef | grep postgres

    bağlantı noktası numarasını döndürür

  2. öldür -9 port_number

Sonunda tekrar Postgres'i başlat

brew services start postgresql 
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.