রেল + পোস্টগ্রাস ড্রপ ত্রুটি: অন্যান্য ব্যবহারকারীদের দ্বারা ডাটাবেস অ্যাক্সেস করা হচ্ছে


92

আমার পোস্টগ্রিজের উপর দিয়ে চলছে একটি রেল অ্যাপ্লিকেশন।

আমার দুটি সার্ভার রয়েছে: একটি পরীক্ষার জন্য এবং অন্যটি উত্পাদনের জন্য।

খুব প্রায়ই আমার পরীক্ষার সার্ভারে প্রোডাকশন ডিবি ক্লোন করা প্রয়োজন।

ভ্লাদের মাধ্যমে আমি যে কমান্ডটি চালাচ্ছি তা হ'ল:

rake RAILS_ENV='test_server' db:drop db:create

আমার যে সমস্যা হচ্ছে তা হ'ল আমি নিম্নলিখিত ত্রুটিটি পেয়েছি:

ActiveRecord::StatementInvalid: PGError: ERROR: database <database_name> is being accessed by other users DROP DATABASE IF EXISTS <database_name>

কেউ যদি সম্প্রতি ওয়েবের মাধ্যমে অ্যাপ্লিকেশন অ্যাক্সেস করে থাকে তবে এটি ঘটে (পোস্টগ্রাগস একটি "সেশন" খোলা রাখে)

পোস্টগ্র্রেস ডিবিতে সেশনগুলি শেষ করার কোনও উপায় আছে কি?

ধন্যবাদ.

সম্পাদনা করুন

আমি phppgadmin এর ইন্টারফেস ব্যবহার করে ডাটাবেস মুছতে পারি তবে রেক টাস্কটি দিয়ে না।

আমি কীভাবে রেক টাস্কের সাহায্যে phppgadmin এর ড্রপ প্রতিলিপি করতে পারি?


আপনার ডেটাবেসে সংযোগ নেই তা নিশ্চিত করুন বা এটি এটিকে ছাড়বে না Make এখানে এই সম্পর্কে আরও চেক করুন
নেছা জোরিক

উত্তর:


82

আপনি যদি আপনার অ্যাপ্লিকেশনটির জন্য চলমান পোস্টগ্র্যাস্কিল সংযোগগুলি হত্যা করেন তবে আপনি db চালাতে পারবেন: ঠিক জরিমানা ছাড়ুন। তাহলে কীভাবে এই সংযোগগুলি মেরে ফেলবেন? আমি নিম্নলিখিত রেক টাস্কটি ব্যবহার করি:

# lib/tasks/kill_postgres_connections.rake
task :kill_postgres_connections => :environment do
  db_name = "#{File.basename(Rails.root)}_#{Rails.env}"
  sh = <<EOF
ps xa \
  | grep postgres: \
  | grep #{db_name} \
  | grep -v grep \
  | awk '{print $1}' \
  | xargs kill
EOF
  puts `#{sh}`
end

task "db:drop" => :kill_postgres_connections

রেলগুলির নীচে থেকে সংযোগগুলি মেরে ফেলার পরে কখনও কখনও আপনি যখন কোনও পৃষ্ঠা লোড করার চেষ্টা করবেন তখন কখনও কখনও তা বরফ হয়ে উঠবে, তবে পুনরায় লোড করা সংযোগটি পুনরায় প্রতিষ্ঠিত করে।


4
আমাকে xargs এ sudo যুক্ত করতে হয়েছিল এবং ডাটাবেসের নাম পরিবর্তন করতে হয়েছিল, তবে এটি কার্যকর হয়। টিওয়াই
এলজিপ

4
আমার জন্য একই ... "সুডো এক্সার্গস কিল" এবং হার্ড-কোডেড ডিবি_নেমকে "আমার-বিকাশ-ডাটাবেস-নাম"
কেভিন দেওয়াল্ট

7
task "db:drop" => :kill_postgres_connectionsআমি মনে করি এই লাইনটি সরানো উচিত, এটি আমার দৃষ্টিকোণ থেকে সিস্টেম টাস্কের আচরণকে প্রসারিত করার ঝুঁকিপূর্ণ।
msa.im

আপনার ডাটাবেসের নাম হার্ডকোডের পরিবর্তে কেবলমাত্র নিম্নলিখিতটি ব্যবহার করুন:db_name = Rails.configuration.database_configuration[Rails.env]['database']
তালা

41

সহজ এবং আরও আপডেট হওয়া উপায়: 1. ps -ef | grep postgres# 2 সংযোগটি সন্ধান করতে ব্যবহার করুন ।sudo kill -9 "# of the connection

দ্রষ্টব্য: অভিন্ন পিআইডি থাকতে পারে। একজনকে হত্যা করা সকলকে হত্যা করে।


ফলাফলের কোন সংখ্যাটি পিআইডি উপস্থাপন করে? আমি 3 টি শিরোনামহীন কলামগুলি এমন সংখ্যার সাথে দেখতে পাই যা পিআইডি এর মতো দেখাচ্ছে।
ব্র্যাডগ্রিনস 8:38

4
@ ব্র্যাডগ্রেনস দ্বিতীয় কলাম (আমি ম্যাক টার্মিনাল ব্যবহার করছি)
s2t2

পিএস সহ কিছুই পাওয়া যায় নি তবে তবুও ডিবি: ড্রপ এ ত্রুটি পান।
জোসেফকে

17

আপনার পোস্টগ্রিজ ডেটাবেজে সমস্ত সংযোগ নিহত করার জন্য এখানে একটি দ্রুত উপায়।

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

সতর্কতা: এটি postgresব্যবহারকারীর দ্বারা চালিত যে কোনও চলমান প্রক্রিয়াগুলিকে হত্যা করবে , সুতরাং আপনি প্রথমে এটি করতে চান তা নিশ্চিত করুন।


11
আমার সিস্টেমে sudo kill -9 `ps -u postgres -o pid=` পরিবর্তে আমি ব্যবহার করি , সুতরাং একটি পিআইডি শিরোনাম মুদ্রণ করা হবে না ps, সুতরাং একটি স্ট্রিং আর্গুমেন্টটি পাস করা হয় না kill, সুতরাং একটি ত্রুটি উত্থাপিত হবে না। যে কোনও ক্ষেত্রে দুর্দান্ত টিপ।
স্পষ্টত

4
আমি উত্সাহিত এবং অবনমিত হতে থাকি, ফলে শূন্যের কাছাকাছি রেটিং হয়। একটি বিতর্কিত বলে মনে হচ্ছে "দ্রুত সমাধান"। আমাকে রেকর্ড যে আমি জন্য রাষ্ট্র যাক করেনি একটি সতর্কবার্তা এটি বিপজ্জনক দেব। :)
জ্যামন হল্মগ্রেন

4
আপনি যদি উবুন্টুতে থাকেন তবে sudo service postgresql start
পোস্টগ্রেসকিএল

9

যখন আমরা উপরে থেকে "কিল প্রসেস" পদ্ধতিটি ব্যবহার করি, তখন ডিবি: ড্রপ ব্যর্থ হয় (যদি: কিল_পোস্টগ্রেস_ সংযোগ পূর্বশর্ত)। আমি বিশ্বাস করি এটি কারণ রেক কমান্ডটি যে সংযোগটি ব্যবহার করছিল তা হত্যার কারণ ছিল। পরিবর্তে, আমরা সংযোগটি ফেলে দেওয়ার জন্য একটি স্কিএল কমান্ড ব্যবহার করছি। এটি ডিবি এর পূর্বশর্ত হিসাবে কাজ করে: ড্রপ, বরং জটিল কমান্ডের মাধ্যমে হত্যা প্রক্রিয়াগুলি ঝুঁকি এড়ায় এবং এটি কোনও ওএসে কাজ করা উচিত (ধীরে ধীরে এর জন্য আলাদা সিনট্যাক্সের প্রয়োজন হয় kill)।

cmd = %(psql -c "SELECT pg_terminate_backend(procpid) FROM pg_stat_activity WHERE procpid <> pg_backend_pid();" -d '#{db_name}')

এখানে একটি রেক টাস্ক যা ডাটাবেস.আইএমএল থেকে ডাটাবেসের নাম পড়ে এবং একটি উন্নত (আইএমএইচও) কমান্ড চালায়। এটি ডিবি: কিল_পোস্টগ্রেস_ সংযোগকে ডিবি: ড্রপ করার পূর্বশর্ত হিসাবে যুক্ত করে। এটিতে একটি সতর্কতা অন্তর্ভুক্ত রয়েছে যা রেলগুলি আপগ্রেড করার পরে চিৎকার করে, এটি নির্দেশ করে যে এই প্যাচটির আর দরকার নেই।

দেখুন: https://gist.github.com/4455341 , উল্লেখ অন্তর্ভুক্ত


9

আমি রেল 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

আপনি কি কখনও সেই উত্পাদনের সতর্কতাটি পড়ে শেষ করেছেন? শুধু কৌতূহলী: পি
ভিনিস ব্রাসিল

6

আপনার রেল কনসোল বা সার্ভারটি অন্য ট্যাবে চলছে কিনা তা পরীক্ষা করে দেখুন

রেল সার্ভার এবং কনসোল বন্ধ করুন।

তারপর চালান

 rake db:drop

5

আপনার অ্যাপ্লিকেশনটির এটি শেষ হয়ে গেলে সংযোগটি বন্ধ করতে দিন। পোস্টগ্রিএসকিউএল সংযোগগুলি খোলা রাখে না, এটি অ্যাপ্লিকেশনটি সংযোগ রাখে।


4
আমি phppgadmin এর ইন্টারফেস ব্যবহার করে ডাটাবেস মুছতে পারি তবে রেক টাস্কটি দিয়ে না। আমি কীভাবে রেক টাস্কের সাহায্যে phppgadmin এর ড্রপ প্রতিলিপি করতে পারি?
ফুজুয়ান

দুঃখিত, আপনাকে সেখানে সাহায্য করতে পারে না, রাক নিয়ে আমার কোনও অভিজ্ঞতা নেই। তবে, ত্রুটিটি নির্দেশ করে যে অন্য ব্যবহারকারী এখনও ডেটাবেস ব্যবহার করছেন। এজন্য আপনি ডাটাবেস মুছতে পারবেন না, রেকের মাধ্যমে নয় পিএইচপিপিজিএডমিন, অসম্ভব। ম্যানুয়ালটি থেকে, DROP DATABASE: আপনি বা অন্য কেউ লক্ষ্য ডাটাবেসের সাথে সংযুক্ত থাকাকালীন এটি কার্যকর করা যায় না।
ফ্র্যাঙ্ক হেইকেন্স 19

3

রেলগুলি সম্ভবত এটি ফেলে দেওয়ার জন্য ডাটাবেসের সাথে সংযুক্ত হচ্ছে তবে আপনি যখন phppgadmin এর মাধ্যমে লগ ইন করেন তখন এটি টেমপ্লেট 1 বা পোস্টগ্রিস ডাটাবেসের মাধ্যমে লগ ইন করে, সুতরাং আপনি এটি দ্বারা প্রভাবিত হন না।


আমি কীভাবে রেলগুলিকে ডাটাবেস ছাড়তে বাধ্য করতে পারি? পোস্টগ্রিস এসকিউএল কমান্ড ব্যবহার করে আমার নিজের রেক অ্যাকশনটি সংজ্ঞায়িত করা উচিত?
ফুজুয়ান

3

এটি আমার পক্ষে কাজ করেছে (রেল 6): rake db:drop:_unsafe

আমি মনে করি আমাদের কোডবেসে এমন কিছু ছিল যা রেক টাস্কটি নামানোর চেষ্টা করার আগে একটি ডিবি সংযোগ শুরু করেছিল।


2

আমি পিগ্রেসেট নামক একটি রত্ন লিখেছি যা আপনি রেক ডিবি: ড্রপ (চালানোর সময় বা ডিবি: রিসেট, ইত্যাদি) প্রশ্নযুক্ত ডাটাবেসের সাথে সংযোগগুলি স্বয়ংক্রিয়ভাবে মেরে ফেলবেন। আপনাকে যা করতে হবে তা হ'ল এটি আপনার জেমফাইলে যুক্ত করা উচিত এবং এই সমস্যাটি সরিয়ে নেওয়া উচিত। এই লেখার সময় এটি 4 এবং তার বেশি রেলের সাথে কাজ করে এবং পোস্টগ্রিস 9.x এ পরীক্ষা করা হয়েছে। উত্স কোডটি আগ্রহী প্রত্যেকের জন্য গিথুবে উপলভ্য ।

gem 'pgreset'

আপনার রত্নটি ছাড়া এটি কিছুই করবে না - সংযোগটি বিদ্যমান ছিল না (পিএস গ্রেপ অনুসন্ধান ইত্যাদি), তবে রেল মনে করেছে এটি হয়েছে। অনেক ধন্যবাদ!!
জোসেফকে

1

আপনি কেবল অ্যাক্টিভেকর্ড কোডটি ড্রপিংয়ের মাধ্যমে monkeypatch করতে পারেন।

রেল 3.x এর জন্য:

# lib/tasks/databases.rake
def drop_database(config)
  raise 'Only for Postgres...' unless config['adapter'] == 'postgresql'
  Rake::Task['environment'].invoke
  ActiveRecord::Base.connection.select_all "select pg_terminate_backend(pg_stat_activity.pid) from pg_stat_activity where datname='#{config['database']}' AND state='idle';"
  ActiveRecord::Base.establish_connection config.merge('database' => 'postgres', 'schema_search_path' => 'public')
  ActiveRecord::Base.connection.drop_database config['database']
end

৪.x রেলগুলির জন্য:

# config/initializers/postgresql_database_tasks.rb
module ActiveRecord
  module Tasks
    class PostgreSQLDatabaseTasks
      def drop
        establish_master_connection
        connection.select_all "select pg_terminate_backend(pg_stat_activity.pid) from pg_stat_activity where datname='#{configuration['database']}' AND state='idle';"
        connection.drop_database configuration['database']
      end
    end
  end
end

(থেকে: http://www.krautcomputing.com/blog/2014/01/10/how-to-drop-your-postgres-database-with-rails-4/ )


1

উত্পাদনে একটি রেল 5.2 অ্যাপ্লিকেশন এবং পোস্টগ্রিসকিউএল ডাটাবেস নিয়ে কাজ করার সময় আমার একই সমস্যা ছিল।

আমি কীভাবে এটি সমাধান করেছি তা এখানে :

প্রথমে, পিজিএডমিনে ডাটাবেস সার্ভারে প্রতিটি সংযোগ লগ আউট করুন ক্লায়েন্টের ।

টার্মিনাল থেকে ডাটাবেস ব্যবহার করে প্রতিটি সেশন বন্ধ করুন।

sudo kill -9 `ps -u postgres -o pid=`

পোস্টগ্র্রেএসকিউএল সার্ভার শুরু করুন, যেহেতু উপরের কিল অপারেশনটি পোস্টগ্র্যাসকিউএল সার্ভারটি বন্ধ করে দিয়েছে।

sudo systemctl start postgresql

উত্পাদনের যুক্তি সংযুক্ত করে পরিবেশ পরিবেশে ডাটাবেসটি ফেলে দিন।

rails db:drop RAILS_ENV=production DISABLE_DATABASE_ENVIRONMENT_CHECK=1

এখানেই শেষ.

আশা করি এটা কাজে লাগবে


0

কেবল নিশ্চিত হয়ে নিন যে আপনি যে কোনও উন্মুক্ত টার্মিনাল উইন্ডোতে রেল কনসোলটি প্রস্থান করেছেন এবং রেল সার্ভারটি প্রস্থান করেছেন ... এটি লোকেদের দ্বারা করা সবচেয়ে সাধারণ ভুল of


0

আমার অনুরূপ ত্রুটি হয়েছিল যে 1 জন ব্যবহারকারী ডাটাবেসটি ব্যবহার করছে, আমি বুঝতে পেরেছিলাম এটি আমার ছিল! আমি আমার রেল সার্ভারটি বন্ধ করে দিয়ে রাকটি করেছি: ড্রপ কমান্ড এবং এটি কার্যকর হয়েছে!


0

সার্ভার বা কম্পিউটার পুনরায় চালু করার পরে, আবার চেষ্টা করুন।

এটি সহজ সমাধান হতে পারে।


0

সমাধান

বাশ স্ক্রিপ্ট

ENV=development

# restart postgresql
brew services restart postgresql

# get name of the db from rails app
RAILS_CONSOLE_COMMAND="bundle exec rails c -e $ENV"
DB_NAME=$(echo 'ActiveRecord::Base.connection_config[:database]' | $RAILS_CONSOLE_COMMAND | tail -2 | tr -d '\"')

# delete all connections to $DB_NAME
for pid in $(ps -ef | grep $DB_NAME | awk {'print$2'})
do
   kill -9 $pid
done

# drop db
DISABLE_DATABASE_ENVIRONMENT_CHECK=1 RAILS_ENV=$ENV bundle exec rails db:drop:_unsafe
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.