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.

내가 본 프로세스를 종료하려고 시도했지만 ps -ef | grep postgres작동하지 않습니다.

kill: kill 2358 failed: operation not permitted

다른 모든 시도가 실패했을 때 pgreset gem은 연결이 존재한다고 생각하는 레일 / PG를 고정 시켰습니다.
JosephK

답변:


671

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

3
@ndn 데이터베이스 수퍼 유저는 OS 수준 수퍼 유저와 다릅니다. sudoPG 에는 없습니다 .
jpmc26

이것은 REVOKE단계 가 있기 때문에 많은 SO 질문에 대한 유일한 해결책입니다 . 당신은 누군가를 구 했어요
AymDev

이 작품은 감사합니다 ....
Ajay Kumar

205

아마 그냥 다시 시작 postgres=>sudo service postgresql restart


@Starkers 나는 그것이 나에게 새벽까지 때까지 위의 답변의 대부분을 겪었다 :)
Haris Krajina

32
@Starkers 예, 특히 고부하 생산에 안전;)
Erathiel

10
brew services restart postgresql유 양조가있는 경우
샘 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 1

@PJSCopeland 최대한 간단한 솔루션에 감사드립니다! : 나는 당신의 의견은 따라서 실제 대답 할 가치가 생각 stackoverflow.com/a/48226667/1097104
Juuso Ohtonen

감사합니다, @JuusoOhtonen. 그래도 평판을 원한다면 적어도 내 의견에 다시 연결할 수 있습니까?
PJSCopeland

@PJSCopeland 님.
Juuso Ohtonen

다른 답변 및 기타 유사한 SO 게시물 솔루션에 문제가 있습니다. 당신 pg_ctl restart -D /usr/local/var/postgres의 트릭을 실행 ! (저는 첫 번째 또는 세 번째 명령조차 실행하지 않았습니다).
Iggy

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메서드 를 재정의합니다 .

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
talyric

1
이것은 좋은 답변입니다! Rails 기본값보다 낫고 안전합니다. 감사!
piersadrian

5

더 쉽고 업데이트 된 방법은 다음과 같습니다.

  1. ps -ef | grep postgres연결 번호를 찾는 데 사용
  2. sudo kill -9 "#" 연결

참고 : 동일한 PID가있을 수 있습니다. 하나를 죽이면 모든 것이 죽습니다.


3

나는이 문제가 있었고 문제는 Navicat이 내 로컬 Postgres db에 연결되어 있다는 것입니다. Navicat의 연결을 끊으면 문제가 사라졌습니다.

편집하다:

또한, 최후의 수단으로 데이터를 백업 한 후 다음 명령을 실행할 수 있습니다.

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

... postgres 사용자가 액세스하는 모든 것을 죽일 것입니다. 프로덕션 시스템에서는이 작업을 수행하지 말고 개발 환경에 문제가 없어야합니다. PostgreSQL을 다시 시작하기 전에 모든 postgres 프로세스가 실제로 종료 되었는지 확인하는 것이 중요합니다 .

편집 2 :

이 unix.SE 게시물 로 인해 에서 (으) kill -9로 변경되었습니다 kill -15.


1
Navicat Lite에 대한 제한된 경험에서 단순히 데이터베이스 또는 서버 연결을 종료하는 것만으로는 충분하지 않습니다. Navicat Lite는 응용 프로그램이 종료 될 때까지 가끔 연결을 열어 놓은 것으로 보입니다.
ken

3

이 방법으로 해결했습니다.

Windows8 64 비트 restart에서 서비스를 posting : 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

원격 시나리오. 그러나 rails 앱에서 테스트를 실행하려고하면 다음과 같은 결과가 나타납니다.

"ActiveRecord :: StatementInvalid : PG :: ObjectInUse : 오류 : 다른 사용자가"myapp_test "데이터베이스에 액세스하고 있습니다. 세부 정보 : 데이터베이스를 사용하는 다른 세션이 1 개 있습니다."

테스트를 실행하기 전에 pgAdmin 또는 다른 postgres GUI 도구를 닫아야합니다.


0

사례 :
쿼리 실행에 실패 :

DROP TABLE dbo.t_tabelname

해결책 :
a. 다음과 같이 쿼리 상태 활동을 표시하십시오.

SELECT * FROM pg_stat_activity  ;

비. 'Query'열에 다음이 포함 된 행을 찾으십시오.

'DROP TABLE dbo.t_tabelname'

씨. 같은 행에서 'PID'열의 값을 가져옵니다.

example : 16409

디. 다음 스크립트를 실행하십시오.

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.