Cara menambah batas waktu koneksi di postgresql

Apakah Anda menggunakan PostgreSQL dan terkadang mengalami PSQLException: This connection has been closed.?

Di sini, di ImmobilienScout24 kami baru mulai menggunakan PostgreSQL; . Salah satu parameter yang kami pilih untuk disetel adalah socketTimeout, menggunakan 16 detik. Mengingat bahwa kami bertujuan untuk API yang merespons sub 100ms, yang tampaknya sangat liberal sambil tetap memberikan keamanan terkait kemacetan utas
Bagus;

Sambungan ini telah ditutup
Kami menjalankan beberapa minggu di lingkungan produksi, memberi selamat kepada diri kami sendiri karena telah memilih PostgreSQL daripada MySQL ketika kami tiba-tiba mengalami semburan masalah konektivitas database, semuanya melaporkan
Caused by: org.postgresql.util.PSQLException: This connection has been closed.
Hm. Kami mencatat bahwa sebagian besar waktu masalah seperti itu terjadi, ada penyedot debu otomatis yang berjalan atau selesai tidak lama sebelumnya, kami melibatkan banyak orang, mencatat banyak sekali, mengonfigurasi kumpulan koneksi kami, dan, untuk mempersingkat cerita - menemukan bahwa

Seperti yang sering terjadi, lucunya semuanya masuk akal dan berfungsi seperti yang diharapkan

Nilai batas waktu yang digunakan untuk operasi pembacaan soket. Jika membaca dari server membutuhkan waktu lebih lama dari nilai ini, sambungan ditutup. Ini dapat digunakan sebagai waktu tunggu permintaan global brute force dan metode untuk mendeteksi masalah jaringan. Batas waktu ditentukan dalam detik dan nilai nol berarti dinonaktifkan. 1

Konfigurasikan waktu tunggu koneksi saat menghubungkan ke Cloud SQL untuk PostgreSQL menggunakan paket database/sql Go

Jelajahi lebih jauh

Untuk dokumentasi mendetail yang menyertakan contoh kode ini, lihat berikut ini

  • Kelola koneksi basis data

Contoh kode

Pergi

Lihat di GitHub

// Set Maximum time (in seconds) that a connection can remain open.
db.SetConnMaxLifetime(1800 * time.Second)

Apa berikutnya

Untuk menelusuri dan memfilter contoh kode untuk produk Google Cloud lainnya, lihat browser contoh Google Cloud

e = create_engine("postgresql+psycopg2. //skot. tiger@localhost/test", connect_args={"connect_timeout". 2})

itu juga akan menerimanya sebagai

e = create_engine("postgresql+psycopg2. //skot. tiger@localhost/test?connect_timeout=2")

namun, dalam kasus di atas batas waktu diteruskan sebagai string "2" dan bukan bilangan bulat, yang dapat mengganggu kerjanya, saya tidak yakin. pendekatan connect_args terpisah lebih aman

Saya baru-baru ini berjuang dengan dokumentasi PHP yang buruk tentang cara mengatur batas waktu koneksi di driver PHP PDO pgsql. Setelah menggali sedikit di sumber PHP dan libpq, saya mengerti cara kerjanya di bawah terpal dan di posting ini saya membagikan temuan saya

TL;DR

Anda dapat menyetel batas waktu koneksi menggunakan opsi PDO::ATTR_TIMEOUT

$dbh = new PDO($dsn, $username, $password, array(PDO::ATTR_TIMEOUT => $connect_timeout_in_seconds));
_

Harap dicatat bahwa

  1. Batas waktu hanya berlaku dan eksklusif untuk sambungan TCP, dan ini bukan batas waktu diam pada soket. Yaitu. jika Anda menetapkan nilai 3_ detik, new PDO() akan memunculkan pengecualian jika tidak dapat terhubung ke PostgreSQL dalam waktu 3 detik, sedangkan eksekusi kueri berikutnya dapat memakan waktu lebih lama
  2. Jika tidak disetel, defaultnya adalah 30 detik (ditentukan dalam driver PDO pgsql)
  3. Nilai minimumnya adalah 2_ detik. Jika Anda menetapkan nilai yang lebih rendah, libpq akan memaksanya secara internal ke 2 detik

Bagaimana itu bekerja

Driver PHP PDO pgsql menggunakan libpq, pustaka klien PostgreSQL resmi, untuk terhubung ke PostgreSQL. Karena libpq mendukung

// Be aware - doesn't work
new PDO("pgsql:host=localhost;port=5432;connect_timeout=5");
5 di DSN, saya berharap dapat melakukan sesuatu seperti berikut

// Be aware - doesn't work
new PDO("pgsql:host=localhost;port=5432;connect_timeout=5");

Sayangnya itu tidak berhasil, karena driver PDO pgsql secara membabi buta menambahkan

// Be aware - doesn't work
new PDO("pgsql:host=localhost;port=5432;connect_timeout=5");
7 di akhir DSN, dan - setelah beberapa manipulasi - libpq akan menerima string koneksi berikut

host=localhost port=5432 connect_timeout=5 connect_timeout=30

Karena cara libpq bekerja secara internal, opsi terakhir menang, dan

// Be aware - doesn't work
new PDO("pgsql:host=localhost;port=5432;connect_timeout=5");
5 akan selalu disetel ke
host=localhost port=5432 connect_timeout=5 connect_timeout=30
1 detik. Kemungkinan, driver PDO pgsql mendukung PDO::ATTR_TIMEOUT untuk mengesampingkan batas waktu koneksi default
host=localhost port=5432 connect_timeout=5 connect_timeout=30
1 detik. Koneksi PDO sebelumnya dapat dibuat dengan benar dengan yang berikut ini

new PDO(
    "pgsql:host=localhost;port=5432",
    null,
    null,
    array(PDO::ATTR_TIMEOUT => 5)
);
_

Perhatikan bahwa libpq memaksa

// Be aware - doesn't work
new PDO("pgsql:host=localhost;port=5432;connect_timeout=5");
5 setidaknya menjadi 2 detik, jadi jika Anda mencoba menetapkan nilai yang lebih rendah, nilai tersebut akan dipaksa menjadi 2 detik

Bagaimana cara mengubah batas waktu di PostgreSQL?

Postgres memungkinkan Anda mengatur parameter konfigurasi seperti statement_timeout pada level per peran (pengguna). UBAH PERAN ; .

Berapa batas waktu tunggu koneksi untuk Postgres?

Batas waktu tunggu koneksi default untuk sumber data PostgreSQL adalah 30 detik .

Bagaimana cara mengatur batas waktu koneksi idle di PostgreSQL?

Hentikan sesi apa pun yang telah menganggur (yaitu, menunggu kueri klien), tetapi tidak dalam transaksi terbuka, lebih lama dari jumlah waktu yang ditentukan . Jika nilai ini ditentukan tanpa satuan, ini diambil sebagai milidetik. Nilai nol (default) menonaktifkan batas waktu.

Bagaimana cara mensimulasikan batas waktu di postgres?

Jika Anda hanya mencoba mensimulasikan batas waktu di sisi aplikasi Anda, Anda bisa menggunakan kueri dummy seperti. SELECT pg_sleep(seconds); Di mana detik adalah beberapa nilai bilangan bulat yang akan mensimulasikan kueri yang tidak kembali dalam jangka waktu yang wajar.