org.postgresql.util.PSQLException: FATAL: ขออภัยมีลูกค้ามากเกินไปแล้ว


93

ฉันพยายามเชื่อมต่อกับฐานข้อมูล Postgresql ฉันได้รับข้อผิดพลาดต่อไปนี้:

ข้อผิดพลาด: org.postgresql.util.PSQLException: FATAL: ขออภัยมีลูกค้ามากเกินไปแล้ว

ข้อผิดพลาดหมายถึงอะไรและฉันจะแก้ไขได้อย่างไร

server.propertiesไฟล์ของฉันกำลังติดตาม:

serverPortData=9042
serverPortCommand=9078
trackConnectionURL=jdbc:postgresql://127.0.0.1:5432/vTrack?user=postgres password=postgres
dst=1
DatabaseName=vTrack
ServerName=127.0.0.1
User=postgres
Password=admin
MaxConnections=90
InitialConnections=80
PoolSize=100
MaxPoolSize=100
KeepAliveTime=100
TrackPoolSize=120
TrackMaxPoolSize=120
TrackKeepAliveTime=100
PortNumber=5432
Logging=1

คำตอบ:


39

เราไม่รู้ว่าไฟล์server.propertiesคืออะไรเราไม่รู้ว่าSimocoPoolSizeหมายถึงอะไร (คุณ?)

ลองเดาว่าคุณกำลังใช้กลุ่มการเชื่อมต่อฐานข้อมูลแบบกำหนดเอง จากนั้นผมคิดว่าปัญหาคือสระว่ายน้ำของคุณมีการกำหนดค่าที่จะเปิด 100 หรือ 120 เชื่อมต่อ แต่คุณเซิร์ฟเวอร์ PostgreSQL MaxConnections=90มีการกำหนดค่าที่จะยอมรับ สิ่งเหล่านี้ดูเหมือนการตั้งค่าที่ขัดแย้งกัน MaxConnections=120ลองเพิ่ม

แต่ก่อนอื่นคุณควรทำความเข้าใจโครงสร้างพื้นฐานเลเยอร์ db ของคุณก่อนรู้ว่าคุณใช้พูลอะไรหากคุณต้องการการเชื่อมต่อแบบเปิดจำนวนมากในพูล และโดยเฉพาะอย่างยิ่งหากคุณส่งคืนการเชื่อมต่อที่เปิดไปยังพูลอย่างสง่างาม


168

คำอธิบายข้อผิดพลาดต่อไปนี้:

org.postgresql.util.PSQLException: FATAL: sorry, too many clients already.

สรุป:

คุณเปิดการเชื่อมต่อกับฐานข้อมูลเกินขีด จำกัด ที่อนุญาต คุณวิ่งบางอย่างเช่นนี้ภายในของวงและลืมที่จะทำงานConnection conn = myconn.Open(); conn.close();เพียงเพราะชั้นเรียนของคุณถูกทำลายและขยะที่เก็บรวบรวมไม่ได้ปล่อยการเชื่อมต่อกับฐานข้อมูล วิธีแก้ไขที่เร็วที่สุดคือตรวจสอบให้แน่ใจว่าคุณมีรหัสต่อไปนี้กับคลาสใดก็ตามที่สร้างการเชื่อมต่อ:

protected void finalize() throws Throwable  
{  
    try { your_connection.close(); } 
    catch (SQLException e) { 
        e.printStackTrace();
    }
    super.finalize();  
}  

วางรหัสนั้นในคลาสใดก็ได้ที่คุณสร้าง Connection จากนั้นเมื่อชั้นเรียนของคุณถูกเก็บขยะการเชื่อมต่อของคุณจะถูกปลดปล่อย

เรียกใช้ SQL นี้เพื่อดูการเชื่อมต่อสูงสุด postgresql ที่อนุญาต:

show max_connections;

ค่าเริ่มต้นคือ 100 PostgreSQL บนฮาร์ดแวร์ที่ดีสามารถรองรับการเชื่อมต่อได้ครั้งละไม่กี่ร้อย หากคุณต้องการมีหลายพันคุณควรพิจารณาใช้ซอฟต์แวร์การรวมการเชื่อมต่อเพื่อลดค่าใช้จ่ายในการเชื่อมต่อ

ดูว่าใคร / อะไร / เมื่อใด / ที่ไหนกำลังเปิดการเชื่อมต่อของคุณ:

SELECT * FROM pg_stat_activity;

จำนวนการเชื่อมต่อที่ใช้ในปัจจุบันคือ:

SELECT COUNT(*) from pg_stat_activity;

กลยุทธ์การแก้จุดบกพร่อง

  1. คุณสามารถให้ชื่อผู้ใช้ / รหัสผ่านที่แตกต่างกันให้กับโปรแกรมที่อาจไม่ปล่อยการเชื่อมต่อเพื่อค้นหาว่ามันคือชื่อใดจากนั้นดูใน pg_stat_activity เพื่อดูว่าอันไหนไม่ได้ถูกล้างออก

  2. ทำการติดตามสแต็กข้อยกเว้นเต็มรูปแบบเมื่อไม่สามารถสร้างการเชื่อมต่อและทำตามรหัสสำรองไปยังตำแหน่งที่คุณสร้างใหม่Connectionตรวจสอบให้แน่ใจว่าทุกบรรทัดรหัสที่คุณสร้างการเชื่อมต่อลงท้ายด้วยconnection.close();

วิธีตั้งค่า max_connections ให้สูงขึ้น:

max_connections ใน postgresql.conf ตั้งค่าจำนวนสูงสุดของการเชื่อมต่อพร้อมกันไปยังเซิร์ฟเวอร์ฐานข้อมูล

  1. ขั้นแรกให้ค้นหาไฟล์ postgresql.conf ของคุณ
  2. หากคุณไม่ทราบว่าอยู่ที่ไหนให้ค้นหาฐานข้อมูลด้วย sql: SHOW config_file;
  3. เหมืองอยู่ใน: /var/lib/pgsql/data/postgresql.conf
  4. ล็อกอินด้วยรูทและแก้ไขไฟล์นั้น
  5. ค้นหาสตริง: "max_connections"
  6. max_connections=100คุณจะเห็นบรรทัดที่ระบุว่า
  7. กำหนดจำนวนให้ใหญ่ขึ้นตรวจสอบขีด จำกัด สำหรับเวอร์ชัน postgresql ของคุณ
  8. รีสตาร์ทฐานข้อมูล postgresql เพื่อให้การเปลี่ยนแปลงมีผล

max_connections สูงสุดคือเท่าใด

ใช้แบบสอบถามนี้:

select min_val, max_val from pg_settings where name='max_connections';

ฉันได้รับคุณค่าตาม8388607ทฤษฎีแล้วนั่นคือสิ่งที่มากที่สุดที่คุณได้รับอนุญาต แต่แล้วกระบวนการที่หลบหนีสามารถกินการเชื่อมต่อหลายพันครั้งและแปลกใจฐานข้อมูลของคุณไม่ตอบสนองจนกว่าจะรีบูต หากคุณมี max_connections ที่สมเหตุสมผลเช่น 100 โปรแกรมที่กระทำผิดจะถูกปฏิเสธการเชื่อมต่อใหม่


4
ทำไมบางคนถึงลืม ';' หลังจากคำสั่ง SQL! ทำการคัดลอกและวางการลาก :)
coderv ตั้งแต่

@codervince คุณต้องใส่ใจ ฉันเกือบจะพูดได้ว่าคุณควรถอดเสียงคำสั่งมากกว่าคัดลอก + วาง
AVProgrammer

4

ไม่จำเป็นต้องเพิ่ม MaxConnections & InitialConnections เพียงปิดการเชื่อมต่อของคุณหลังจากทำงานเสร็จแล้ว ตัวอย่างเช่นหากคุณกำลังสร้างการเชื่อมต่อ:

try {
     connection = DriverManager.getConnection(
                    "jdbc:postgresql://127.0.0.1/"+dbname,user,pass);

   } catch (SQLException e) {
    e.printStackTrace();
    return;
}

หลังจากทำการปิดการทำงานของคุณแล้ว:

try {
    connection.commit();
    connection.close();
} catch (SQLException e) {
    e.printStackTrace();
}

11
ปิดการเชื่อมต่อเสมอในบล็อกสุดท้าย! มิฉะนั้นการเชื่อมต่อจะยังคงเปิดอยู่หากเกิดข้อผิดพลาด
tine2k

1

บรรทัดที่กระทำผิดมีดังต่อไปนี้:

MaxConnections=90
InitialConnections=80

คุณสามารถเพิ่มค่าเพื่อให้สามารถเชื่อมต่อได้มากขึ้น


4
และหากคุณจะมีการเชื่อมต่อเพิ่มเติมอนุญาตให้ปรับพารามิเตอร์หน่วยความจำเช่นกันเพื่อให้สอดคล้องกับการเชื่อมต่อที่เพิ่มขึ้น
Kuberchaun

0

คุณจำเป็นต้องปิดการเชื่อมต่อทั้งหมดของคุณตัวอย่างเช่นหากคุณสร้างคำสั่ง INSERT INTO คุณจำเป็นต้องปิดคำสั่งและการเชื่อมต่อของคุณด้วยวิธีนี้:

statement.close();
Connexion.close():

และหากคุณสร้างคำสั่ง SELECT คุณจำเป็นต้องปิดคำสั่งการเชื่อมต่อและผลลัพธ์ด้วยวิธีนี้:

resultset.close();
statement.close();
Connexion.close();

ฉันทำสิ่งนี้และได้ผล

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.