Matikan sesi / koneksi postgresql


371

Bagaimana saya bisa membunuh semua koneksi postgresql saya?

Saya mencoba rake db:droptetapi saya mendapatkan:

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

Saya sudah mencoba mematikan proses yang saya lihat dari ps -ef | grep postgrestetapi ini tidak berhasil:

kill: kill 2358 failed: operation not permitted

Ketika semua upaya lain gagal, permata pgreset entah bagaimana memperbaiki rails / pg karena mengira ada koneksi, yang tidak berhasil.
JosephK

Jawaban:


673

Anda dapat menggunakan pg_terminate_backend () untuk mematikan koneksi. Anda harus menjadi pengguna super untuk menggunakan fungsi ini. Ini bekerja pada semua sistem operasi yang sama.

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

Sebelum mengeksekusi kueri ini, Anda harus MENDAPATKAN KEMBALI hak istimewa CONNECT untuk menghindari koneksi baru:

REVOKE CONNECT ON DATABASE dbname FROM PUBLIC, username;

Jika Anda menggunakan Postgres 8.4-9.1 gunakan procpid bukan 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'
    ;

68
Perhatikan bahwa dalam Postgres 9.2, procpid diganti namanya menjadi pid.
Devin

Jika dia seorang pengguna super, tidak bisakah dia sudotetap membunuh?
ndnenkov

3
@ndn Superuser basis data tidak sama dengan superuser tingkat OS. Tidak ada sudodalam PG.
jpmc26

Ini adalah satu-satunya jawaban yang berfungsi untuk banyak pertanyaan SO karena memiliki REVOKElangkah. Anda menyelamatkan seseorang, sekali lagi kurasa!
AymDev

Ini bekerja terima kasih ....
Ajay Kumar

205

Mungkin baru saja restart postgres=>sudo service postgresql restart


@Starkers Saya melewati sebagian besar jawaban di atas, sampai saya sadar :)
Haris Krajina

32
@Starkers Ya, terutama aman dalam produksi di bawah beban tinggi;)
Erathiel

10
brew services restart postgresqlJika Anda punya minuman
Sam Kah Chiin

28

Dengan semua info tentang proses yang berjalan:

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


13

OSX, Postgres 9.2 (diinstal dengan 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


Jika datadir Anda berada di tempat lain, Anda dapat mencari tahu di mana datadirasinya dengan memeriksa hasilnya ps aux | grep postgres


4
Ataubrew services restart postgresql
PJSCopeland

@PJSCopeland Terima kasih atas solusi simpel yang terbaik! Saya pikir komentar Anda layak menjadi jawaban nyata, oleh karena itu: stackoverflow.com/a/48226667/1097104
Juuso Ohtonen

Terima kasih untuk itu, @JuusoOhtonen. Namun, beri tahu Anda, jika Anda menginginkan reputasi darinya, setidaknya Anda dapat menautkan kembali ke komentar saya?
PJSCopeland

@PJSCopeland Selesai.
Juuso Ohtonen

Punya masalah dengan jawaban lain dan solusi posting SO serupa lainnya. Menjalankan Anda pg_ctl restart -D /usr/local/var/postgresberhasil! (Saya bahkan tidak menjalankan perintah pertama atau ketiga).
Iggy

8

Ini sepertinya berfungsi untuk 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

Diangkat dari intisari ditemukan di sini dan di sini .

Berikut adalah versi modifikasi yang berfungsi untuk PostgreSQL 9.1 dan 9.2.


6

Saya menggunakan tugas menyapu berikut untuk menimpa drop_databasemetode Rails .

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

Sunting: Ini untuk Postgresql 9.2+


Anda harus menggunakan pg_stat_activity.procpidbukannya pg_stat_activity.piduntuk Postgres 9.1 dan di bawah. Lihat stackoverflow.com/a/5408501/444774
talyric

1
Ini jawaban yang bagus! Ini lebih baik dan lebih aman daripada standar Rails. Terima kasih!
piersadrian

5

Cara yang lebih mudah dan lebih diperbarui adalah:

  1. Gunakan ps -ef | grep postgresuntuk menemukan koneksi #
  2. sudo kill -9 "#" koneksi

Catatan: Mungkin ada PID identik. Membunuh satu membunuh semua.


3

Saya memiliki masalah ini dan masalahnya adalah bahwa Navicat terhubung ke Postgres db lokal saya. Setelah saya memutus Navicat masalah menghilang.

EDIT:

Selain itu, sebagai upaya terakhir mutlak, Anda dapat mencadangkan data lalu menjalankan perintah ini:

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

... yang akan membunuh semua yang diakses oleh pengguna postgres. Hindari melakukan ini pada mesin produksi tetapi Anda seharusnya tidak memiliki masalah dengan lingkungan pengembangan. Sangat penting bahwa Anda memastikan setiap postgres proses benar-benar dihentikan sebelum mencoba me-restart PostgreSQL setelah ini.

EDIT 2:

Karena pos unix.SE ini saya berubah dari kill -9menjadi kill -15.


1
Dalam pengalaman saya yang terbatas dengan Navicat Lite, cukup menutup basis data atau koneksi server tidak selalu cukup. Navicat Lite tampaknya menjaga koneksi terbuka sesekali hingga aplikasi diakhiri.
ken

3

SAYA TELAH MEMENUHI CARA INI:

Di Windows8 64 bit saya, hanya restartlayanan: postgresql-x64-9.5


5
Itu hanya melakukan restart yang umumnya tidak diinginkan untuk lingkungan produksi, membunuh proses pelukan adalah pilihan yang jauh lebih diinginkan.
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

Hanya ingin menunjukkan bahwa Jawaban Haris mungkin tidak berfungsi jika beberapa proses latar belakang lainnya menggunakan database, dalam kasus saya itu adalah pekerjaan yang tertunda, saya lakukan:

script/delayed_job stop

Dan baru setelah itu saya bisa drop / reset database.


1

Keluar dari postgres dan mulai ulang. Sederhana, tetapi bekerja setiap saat untuk saya, di mana perintah cli lain terkadang tidak.


Sederhana dan berhasil! Untuk mengklarifikasi lebih lanjut cukup pgAdmin 4 dan restart
Ka Tech

0

Tidak perlu menjatuhkannya. Hapus dan buat ulang skema publik. Dalam kebanyakan kasus ini memiliki efek yang persis sama.

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

Skenario jarak jauh. Tetapi jika Anda mencoba menjalankan tes di aplikasi rel, dan Anda mendapatkan sesuatu seperti

"ActiveRecord :: StatementInvalid: PG :: ObjectInUse: ERROR: database" myapp_test "sedang diakses oleh pengguna lain. RINCIAN: Ada 1 sesi lain menggunakan database."

Pastikan Anda menutup pgAdmin atau alat GUI postgres lainnya sebelum menjalankan tes.


0

Kasus:
Gagal menjalankan kueri:

DROP TABLE dbo.t_tabelname

Solusi:
a. Tampilkan kueri Aktivitas Status sebagai berikut:

SELECT * FROM pg_stat_activity  ;

b. Temukan baris tempat kolom 'Kueri' berisi:

'DROP TABLE dbo.t_tabelname'

c. Di baris yang sama, dapatkan nilai Kolom 'PID'

example : 16409

d. Jalankan skrip ini:

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

Saya menggunakan mac dan saya menggunakan postgres via Postgres.app. Saya memecahkan masalah ini hanya berhenti dan mulai lagi aplikasi.


0

Buka PGadmin untuk melihat apakah ada halaman permintaan terbuka, tutup semua halaman permintaan dan putuskan server PostgresSQL dan Hubungkan lagi dan coba opsi hapus / jatuhkan. Ini membantu saya.


0

Di PG admin Anda dapat memutuskan koneksi server Anda (klik kanan pada server) & semua sesi akan terputus saat restart


0

Bagi saya bekerja sebagai berikut:

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

Saya menggunakan:
gitlab_edition: "gitlab-ce"
gitlab_version: '12 .4.0-ce.0.el7 '


0

Pertama, temukan Postgres yang menjalankan portnya

  1. ps -ef | grep postgres

    itu akan mengembalikan nomor port

  2. bunuh -9 port_number

Akhirnya kembali mulai Postgres

brew services start postgresql 
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.