ฆ่าเซสชัน / การเชื่อมต่อ postgresql


369

ฉันจะฆ่าการเชื่อมต่อ postgresql ทั้งหมดได้อย่างไร

ฉันพยายามrake db:dropแต่ฉันได้รับ:

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

ฉันได้ลองปิดกระบวนการที่ฉันเห็นจาก a ps -ef | grep postgresแต่มันไม่ทำงาน:

kill: kill 2358 failed: operation not permitted

เมื่อความพยายามอื่น ๆ ล้มเหลวอัญมณี pgreset จะแก้ไขราง / pg โดยคิดว่ามีการเชื่อมต่ออยู่ซึ่งไม่ได้
JosephK

คำตอบ:


671

คุณสามารถใช้pg_terminate_backend ()เพื่อฆ่าการเชื่อมต่อ คุณต้องเป็น superuser เพื่อใช้งานฟังก์ชั่นนี้ สิ่งนี้ใช้ได้กับทุกระบบปฏิบัติการเหมือนกัน

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 ให้ใช้ 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'
    ;

68
โปรดทราบว่าใน Postgres 9.2 procpid จะถูกเปลี่ยนชื่อเป็น pid
Devin

ถ้าเขาเป็น superuser เขาจะไม่สามารถsudoฆ่าคนต่อไปได้หรือไม่?
ndnenkov

3
@ndn superuser ฐานข้อมูลไม่เหมือนกับ superuser ระดับ OS ไม่มีsudoใน PG
jpmc26

นี่เป็นคำตอบที่ใช้งานได้สำหรับคำถาม SO หลายข้อเนื่องจากมีREVOKEขั้นตอน คุณช่วยใครซักคนอีกครั้งที่ฉันเดา!
AymDev

ขอบคุณการทำงานนี้ ....
Ajay Kumar

205

อาจเพิ่งเริ่มใหม่postgres=>sudo service postgresql restart


@ คนที่ผ่านมาฉันได้รับคำตอบส่วนใหญ่ข้างต้นจนกว่าจะถึงตัวฉัน :)
Haris Krajina

32
@ ผู้เริ่มต้นใช่โดยเฉพาะอย่างยิ่งความปลอดภัยในการผลิตภายใต้ภาระสูง;)
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 (ติดตั้งด้วยโฮมบรูว์)

$ 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

@PJSCopeland ขอบคุณสำหรับทางออกที่ง่ายที่สุด! ฉันคิดว่าความคิดเห็นของคุณควรเป็นคำตอบที่แท้จริงดังนั้น: stackoverflow.com/a/48226667/1097104
Juuso Ohtonen

ขอบคุณสำหรับสิ่งนั้น @JuusoOhtonen บอกคุณว่าถ้าคุณต้องการชื่อเสียงจากมันคุณอย่างน้อยก็สามารถลิงค์กลับไปที่ความคิดเห็นของฉันได้?
PJSCopeland

@PJSCopeland เสร็จสิ้น
Juuso Ohtonen

มีปัญหากับคำตอบอื่น ๆ และโซลูชันการโพสต์ SO อื่นที่คล้ายคลึงกัน ใช้pg_ctl restart -D /usr/local/var/postgresเคล็ดลับของคุณ! (ฉันไม่ได้เรียกใช้คำสั่งที่หนึ่งหรือที่สาม)
อิกกี้

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

ฉันใช้งานเรคต่อไปนี้เพื่อแทนที่drop_databaseเมธอด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

แก้ไข: นี่สำหรับ Postgresql 9.2+


คุณต้องใช้pg_stat_activity.procpidแทนpg_stat_activity.pidPostgres 9.1 และต่ำกว่า ดูstackoverflow.com/a/5408501/444774
talyric

1
นี่เป็นคำตอบที่ยอดเยี่ยม! ดีกว่าและปลอดภัยกว่าค่าเริ่มต้นของ Rails ขอบคุณ!
piersadrian

5

วิธีที่ง่ายและปรับปรุงมากขึ้นคือ:

  1. ใช้ps -ef | grep postgresเพื่อค้นหาการเชื่อมต่อ #
  2. sudo kill -9 "#" ของการเชื่อมต่อ

หมายเหตุ: อาจมี PID ที่เหมือนกัน ฆ่าคนหนึ่งฆ่าทั้งหมด


3

ฉันมีปัญหานี้และปัญหาคือ Navicat เชื่อมต่อกับฐานข้อมูล Postgres ในพื้นที่ของฉัน เมื่อฉันยกเลิกการเชื่อมต่อ Navicat ปัญหาก็จะหายไป

แก้ไข:

นอกจากนี้ในฐานะทางเลือกสุดท้ายคุณสามารถสำรองข้อมูลของคุณจากนั้นเรียกใช้คำสั่งนี้:

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

... ซึ่งจะฆ่าทุกสิ่งที่ผู้ใช้ postgres กำลังเข้าถึง หลีกเลี่ยงการทำสิ่งนี้กับเครื่องจักรที่ผลิต แต่คุณไม่ควรมีปัญหากับสภาพแวดล้อมการพัฒนา เป็นสิ่งสำคัญที่คุณต้องมั่นใจในทุกสิ่ง postgresกระบวนการสิ้นสุดลงก่อนที่จะพยายามเริ่ม PostgreSQL ใหม่หลังจากนี้

แก้ไข 2:

เนื่องจากการโพสต์ unix.SE นี้ผมได้เปลี่ยนจากการkill -9kill -15


1
จากประสบการณ์ที่ จำกัด ของฉันกับ Navicat Lite เพียงแค่ปิดการเชื่อมต่อฐานข้อมูลหรือเซิร์ฟเวอร์ไม่เพียงพอเสมอไป ดูเหมือนว่า Navicat Lite จะเปิดการเชื่อมต่อเป็นครั้งคราวจนกว่าแอปพลิเคชั่นจะถูกยกเลิก
เคน

3

ฉันได้รับการแก้ไขวิธีนี้:

ในWindows8 64บิตของฉันเพียงแค่restartใช้บริการ: postgresql-x64-9.5


5
นั่นเป็นเพียงการเริ่มต้นใหม่ซึ่งโดยทั่วไปไม่ต้องการสภาพแวดล้อมการผลิตการฆ่ากระบวนการกอดเป็นตัวเลือกที่ต้องการมากขึ้น
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

แค่ต้องการชี้ให้เห็นว่าคำตอบของ 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

สถานการณ์ระยะไกล แต่ถ้าคุณพยายามที่จะทำการทดสอบในแอพรางและคุณจะได้รับสิ่งที่ชอบ

"ActiveRecord :: StatementInvalid: PG :: ObjectInUse: ERROR: ฐานข้อมูล" myapp_test "กำลังถูกเข้าถึงโดยผู้ใช้รายอื่นรายละเอียด: มีอีก 1 เซสชันที่ใช้ฐานข้อมูล"

ตรวจสอบให้แน่ใจว่าคุณปิด pgAdmin หรือเครื่องมือ GUI อื่น ๆ ของ postgres ก่อนทำการทดสอบ


0

กรณี:
ล้มเหลวในการดำเนินการค้นหา:

DROP TABLE dbo.t_tabelname

การแก้ไข:
แสดงกิจกรรมสถานะการสืบค้นดังนี้:

SELECT * FROM pg_stat_activity  ;

ข ค้นหาแถวที่มีคอลัมน์ 'ข้อความค้นหา' ประกอบด้วย:

'DROP TABLE dbo.t_tabelname'

ค. ในแถวเดียวกันรับค่าของคอลัมน์ '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

ในผู้ดูแลระบบ PG คุณสามารถยกเลิกการเชื่อมต่อเซิร์ฟเวอร์ของคุณ (คลิกขวาบนเซิร์ฟเวอร์) และการเชื่อมต่อทั้งหมดจะถูกยกเลิกเมื่อเริ่มต้นใหม่


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.