Programing

postgresql 세션 / 연결 종료

lottogame 2020. 3. 5. 22:43
반응형

postgresql 세션 / 연결 종료


모든 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

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

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


실행중인 프로세스에 대한 모든 정보 :

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

brew 와 함께 postgresql 을 설치 한 경우 MacOS :

brew services restart postgresql

출처 : postgresql 세션 / 연결 종료


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


이것은 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 모두에서 작동 하는 수정 된 버전 입니다.


다음 갈퀴 작업을 사용하여 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 이상입니다


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

편집하다:

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

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

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

편집 2 :

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


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

Windows8 64 비트 restart에서 서비스를 posting : postgresql-x64-9.5


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

다른 백그라운드 프로세스가 데이터베이스를 사용하는 경우 Haris의 답변이 작동하지 않을 수 있음을 지적하고 싶었습니다. 제 경우에는 작업이 지연되었으므로 다음과 같이했습니다.

script/delayed_job stop

그런 다음에야 데이터베이스를 삭제 / 재설정 할 수있었습니다.


postgres를 종료하고 다시 시작하십시오. 간단하지만 다른 cli 명령이 때로는 그렇지 않은 매번 작동합니다.


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

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

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


떨어 뜨릴 필요가 없습니다. 퍼블릭 스키마를 삭제하고 다시 만드십시오. 대부분의 경우 이것은 정확히 동일한 효과가 있습니다.

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

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

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

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


나는 Mac에 있고를 통해 postgres를 사용 Postgres.app합니다. 앱을 종료하고 다시 시작 하여이 문제를 해결했습니다.


PGadmin을 열고 쿼리 페이지가 열려 있는지 확인하고 모든 쿼리 페이지를 닫은 다음 PostgresSQL 서버 연결을 끊고 다시 연결하고 삭제 / 삭제 옵션을 시도하십시오.


사례 :
쿼리 실행에 실패 :

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

참고 URL : https://stackoverflow.com/questions/5108876/kill-a-postgresql-session-connection



반응형