Postgresql - ডিবিতে কিছু অটো সংযোগের কারণে ডাটাবেস ছাড়তে অক্ষম


161

যখনই আমি ডেটাবেস ছাড়ার চেষ্টা করি তখনই:

ERROR:  database "pilot" is being accessed by other users
DETAIL:  There is 1 other session using the database.

যখন আমি ব্যবহার করি:

SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE pg_stat_activity.datname = 'TARGET_DB';

আমি সেই ডিবি থেকে সংযোগটি শেষ করে দিয়েছি, তবে এর পরে যদি আমি কোনওভাবেই ডাটাবেস ফেলে দেওয়ার চেষ্টা করি তবে কেউ স্বয়ংক্রিয়ভাবে সেই ডাটাবেসের সাথে সংযুক্ত হয়ে এই ত্রুটি দেয়। এটা কি হতে পারে? আমি ছাড়া কেউ এই ডাটাবেস ব্যবহার করে না।

উত্তর:


193

আপনি ভবিষ্যতের সংযোগগুলি আটকাতে পারবেন:

REVOKE CONNECT ON DATABASE thedb FROM public;

(এবং সম্ভবত অন্যান্য ব্যবহারকারীদের / ভূমিকা কিন্তু দেখ \l+মধ্যে psql)

তারপরে আপনি নিজের ব্যতীত এই ডিবিতে সমস্ত সংযোগ বন্ধ করতে পারেন:

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

পুরানো সংস্করণগুলিতে pidবলা হয়েছিল procpidতাই আপনাকে এটি মোকাবেলা করতে হবে।

আপনি যেহেতু CONNECTঅধিকারগুলি বাতিল করেছেন তাই যেহেতু স্বয়ংক্রিয়ভাবে সংযোগ দেওয়ার চেষ্টা করা হয়েছে তা আর সক্ষম না হওয়া উচিত।

আপনি এখন ডিবি বাদ দিতে সক্ষম হবেন।

আপনি যদি সাধারণ ক্রিয়াকলাপগুলির জন্য সুপারজার সংযোগগুলি ব্যবহার করেন তবে এটি কাজ করবে না, তবে আপনি যদি এটি করছেন তবে আপনাকে প্রথমে সেই সমস্যাটি সমাধান করা দরকার।


19
আপনি যদি পরে একই নামের সাথে অন্য একটি ডাটাবেস আমদানি করেন তবে জনসাধারণের কাছে ফিরে সংযোগের ক্ষমতাটি প্রদান করুন:GRANT CONNECT ON DATABASE thedb TO public;
মিখাইল ভাসিন

153

যখনই আমি ডেটাবেস ছাড়ার চেষ্টা করি তখনই:

ERROR:  database "pilot" is being accessed by other users
DETAIL:  There is 1 other session using the database.

প্রথমে আপনাকে প্রত্যাহার করা দরকার

REVOKE CONNECT ON DATABASE TARGET_DB FROM public;

তারপরে ব্যবহার করুন:

SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE pg_stat_activity.datname = 'TARGET_DB';

এটা অবশ্যই কাজ করবে।


5
এটা আমার জন্য এটি। ধন্যবাদ
rpivovar

চিহ্নিত করা! ধন্যবাদ! 🎉
স্লেজমা

নিখুঁত কাজ করেছেন। ধন্যবাদ.
মোস্তফা মাগদী

34

আমি এই সমস্যার সমাধান পেয়েছি টার্মিনালটিতে এই কমান্ডটি চালানোর চেষ্টা করুন

ps -ef | grep postgres

এই আদেশ দ্বারা হত্যা প্রক্রিয়া

sudo kill -9 PID

না, এটি খুব হার্ডকোড, আপনি যদি পিজি প্রসেসটি কিল না করতে পারেন তবে আপনার অন্যান্য ডাটাবেসগুলি অ্যাক্সেস করা হচ্ছে?
ভ্লাদিমির স্টাজিলভ

2
@ ভ্লাদিমিরস্টাজিলভ এটি ডাটাবেসের ডাটাবেসের নাম এবং পিড প্রদর্শন করবে। কেউ নির্দিষ্ট পিড কিল নির্বাচন করতে পারেন কেবলমাত্র সেই নির্দিষ্ট ডেটাবেস।
দিনেশ পল্লাপ

29

সংযোগটি কী, কোথা থেকে আসছে তা কেবল খতিয়ে দেখুন। আপনি এই সব দেখতে পারেন:

select * from pg_stat_activity where datname = 'TARGET_DB';

সম্ভবত এটি আপনার সংযোগ?


4
ফলাফল দেখার পরে টার্মিনালে sudo হত্যা -9 পিআইডি
ড্যান রে ওকুইন্ডো

24

এর অর্থ অন্য ব্যবহারকারী ডেটাবেস অ্যাক্সেস করছে। কেবল পোস্টগ্রিজ এসকিউএল পুনরায় চালু করুন। এই আদেশটি কৌশলটি করবে

root@kalilinux:~#sudo service postgresql restart

তারপরে ডাটাবেস বাদ দেওয়ার চেষ্টা করুন:

postgres=# drop database test_database;

এই কৌশলটি করবে।


11

pgAdmin 4 সমাধান ইউআই ব্যবহার করে

আপনার যদি না থাকলে প্রথমে ড্যাশবোর্ডে শো ক্রিয়াকলাপ সক্ষম করুন:

File > Preferences > Dashboards > Display > Show Activity > true

এখন ডিবি ব্যবহার করে সমস্ত প্রক্রিয়াটি অক্ষম করুন:

  1. ডিবি নাম ক্লিক করুন
  2. ড্যাশবোর্ড> সেশনগুলিতে ক্লিক করুন
  3. রিফ্রেশ আইকন ক্লিক করুন
  4. এগুলি শেষ করতে প্রতিটি প্রক্রিয়ার পাশে মুছুন (এক্স) আইকনটি ক্লিক করুন

এখন ডিবি মুছে ফেলতে সক্ষম হওয়া উচিত।


এটি ভালভাবে কাজ করে - আমি এটি PgAdmin 4.5 দিয়ে এবং পোস্টগ্রিসকিউএল 11.2 দিয়ে পরীক্ষা করেছি, ভিজ্যুয়াল সি ++ বিল্ড 1914, 64-বিট (উইন্ডোজ) দ্বারা সংকলিত।
vab2048

2
এটি আমার মনে হয় সেরা সমাধান। এটি সত্যিই ভাল কাজ করে!
লাহিরু

10

আপনার মেশিনে অন্য পরিষেবায় কোনও সম্ভাব্য প্রভাব না থাকলে, সহজভাবে service postgresql restart


8

সমাধান:
1. পিজি সার্ভারটি বন্ধ করুন ২. এটি সমস্ত সক্রিয় সংযোগটি সংযোগ বিচ্ছিন্ন করবে ৩. পিজি সার্ভার পুনরায় চালু করুন 4.. আপনার কমান্ড ব্যবহার করে দেখুন
এখানে চিত্র বর্ণনা লিখুন




এটি ম্যাকের পোস্টগ্র্রেস.অ্যাপের সাথে আমার জন্যও কাজ করেছিল। সেক্ষেত্রে আপনি সার্ভারটি থামান / শুরু করেন
জুয়ান জোসে রামেরেজ


3

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

ERROR:  database "XYZ" is being accessed by other users

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

SELECT * FROM stv_sessions;

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

SELECT * FROM stv_sessions where db_name = 'XYZ';

সারিগুলি পাওয়া গেলে, প্রতিটি পিআইডি, একে একে মুছে ফেলতে এগিয়ে যান।

SELECT pg_terminate_backend(PUT_PID_HERE);

যদি কোনও সারি পাওয়া যায় না, তবে ডাটাবেসটি ফেলে দিন

DROP DATABASE XYZ;

দ্রষ্টব্য: আমার ক্ষেত্রে আমি জাভা ইউনিট / সিস্টেম পরীক্ষা লিখছি, যেখানে এটি গ্রহণযোগ্য হিসাবে বিবেচিত হতে পারে। এটি উত্পাদন কোডের জন্য গ্রহণযোগ্য নয়।


জাভাতে সম্পূর্ণ হ্যাক এখানে (আমার পরীক্ষা / ইউটিলিটি ক্লাস উপেক্ষা করুন)।

  int i = 0;
  while (i < 10) {
    try {
      i++;
      logStandardOut("First try to delete session PIDs, before dropping the DB");
      String getSessionPIDs = String.format("SELECT stv_sessions.process, stv_sessions.* FROM stv_sessions where db_name = '%s'", dbNameToReset);
      ResultSet resultSet = databaseConnection.execQuery(getSessionPIDs);
      while (resultSet.next()) {
        int sessionPID = resultSet.getInt(1);
        logStandardOut("killPID: %s", sessionPID);
        String killSessionPID = String.format("select pg_terminate_backend(%s)", sessionPID);
        try {
          databaseConnection.execQuery(killSessionPID);
        } catch (DatabaseException dbEx) {
          //This is most commonly when a session PID is transient, where it ended between my query and kill lines
          logStandardOut("Ignore it, you did your best: %s, %s", dbEx.getMessage(), dbEx.getCause());
        }
      }

      //Drop the DB now
      String dropDbSQL = String.format("DROP DATABASE %s", dbNameToReset);
      logStandardOut(dropDbSQL);
      databaseConnection.execStatement(dropDbSQL);
      break;
    } catch (MissingDatabaseException ex) {
      //ignore, if the DB was not there (to be dropped)
      logStandardOut(ex.getMessage());
      break;
    } catch (Exception ex) {
      logStandardOut("Something went wrong, sleeping for a bit: %s, %s", ex.getMessage(), ex.getCause());
      sleepMilliSec(1000);
    }
  }

2

আমার মতে ব্যাকগ্রাউডে কিছু নিষ্ক্রিয় অনুসন্ধান চলছে।

  1. প্রথমে চলমান ক্যোয়ারী দেখানোর চেষ্টা করুন
SELECT pid, age(clock_timestamp(), query_start), usename, query 
FROM pg_stat_activity 
WHERE query != '<IDLE>' AND query NOT ILIKE '%pg_stat_activity%' 
ORDER BY query_start desc;
  1. নিষ্ক্রিয় ক্যোরিয়াকে হত্যা করুন (তারা প্রশ্নে ডাটাবেসটি উল্লেখ করছে কিনা তা পরীক্ষা করুন বা আপনি তাদের সমস্তকে মেরে ফেলতে পারেন বা নির্বাচিত ফলাফলগুলি থেকে পিড ব্যবহার করে কোনও নির্দিষ্টকে হত্যা করতে পারেন)

নির্বাচন করুন পিজি_টারমিনিট_ব্যাকেন্ড (প্রোপিড);

দ্রষ্টব্য: একটি নির্বাচিত ক্যোয়ারী হত্যা করা কোনও খারাপ প্রভাব ফেলবে না


2

REVOKE CONNECTডিবি মালিক বা সুপারউজার থেকে সংযোগগুলি আটকাবে না। সুতরাং আপনি যদি কারও ডিবি সংযোগ করতে না চান, ফোল্ড কমান্ডটি কার্যকর হতে পারে।

alter database pilot allow_connections = off;

তারপরে ব্যবহার করুন:

SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE datname = 'pilot';

1
ধন্যবাদ ... রিভোক কানেক্ট আমার দৃশ্যে যথেষ্ট ছিল না।
ভোলপাটো

1

আমি যখন দুটি উপলভ্য উত্তর দুটি অন্যান্য সময়ে দরকারী হিসাবে খুঁজে পেয়েছি, আজ, সমস্যাটি সমাধান করার সহজতম উপায়টি বুঝতে পেরেছিল যে পাইচার্ম সম্ভবত একটি অধিবেশন উন্মুক্ত রেখেছিল, এবং যদি আমি Stopপাইচার্মে ক্লিক করি তবে এটি সাহায্য করতে পারে। PgAdmin4 ব্রাউজারে খোলা থাকলে, আমি এটি করেছিলাম এবং প্রায় সঙ্গে সঙ্গেই ডেটাবেস সেশনগুলির পরিসংখ্যান 0 তে নেমে আসে, সেই সময়ে আমি ডাটাবেসটি ফেলে দিতে সক্ষম হয়েছি।


"পাইচার্ম সম্ভবত কোনও অধিবেশন খোলা রাখবে"? কিভাবে? আমি পাইচার্মের টার্মিনালে ইউনিট পরীক্ষা চালিয়েছি (পেরু, ব্যাকএন্ড পোস্টগ্রিসের সাথে সম্মুখভাগ পাইথন), অর্থাৎ "স্টপ" বোতামটি
ধুয়ে ফেলা

@ ল্যারিক্সডিসিদুয়া আমি বিশ্বাস করি যে, আমার ক্ষেত্রে আমার অবশ্যই পাইচার্মে কোনও পরিষেবা চলার উদাহরণ থাকতে হবে যা ডিবি ব্যবহার করেছিল। যদি আপনি পাইচার্ম থেকে প্রস্থান করেন, উদাহরণস্বরূপের সংখ্যাটি 0 এ নেমে যায়, আপনাকে ডিবি ছাড়তে দেয়? যদি তা হয় তবে অবশ্যই কিছু সংযুক্ত থাকতে হবে (ডাটাবেস এক্সপ্লোরার, এসকিউএল কোয়েরি, অন্য কিছু) যা এখনও সংযুক্ত রয়েছে।
hlongmore

1

ম্যাকোস-এ কমান্ডটি ব্যবহার করে postgresql ডাটাবেস পুনরায় চালু করার চেষ্টা করুন:

brew services restart postgresql

-1

টার্মিনালে এই কমান্ডটি ব্যবহার করে দেখুন:

ps -ef | grep postgres

আপনি দেখতে পাবেন:

501 1445 3645 0 12:05 পূর্বাহ্ণ 0: 00.03 পোস্টগ্র্যাস: সাশা ডিবিনেম [স্থানীয়] নিষ্ক্রিয়

তৃতীয় সংখ্যা (3645) পিআইডি।

আপনি এটি মুছতে পারেন

sudo kill -9 3645

এবং এর পরে আপনার পোস্টগ্রিজ এসকিউএল সংযোগ শুরু করুন।

ম্যানুয়ালি শুরু করুন:

pg_ctl -D /usr/local/var/postgres start
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.