From 48493c517bfc41bc2a1de50d53e395cf8c46f567 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Sch=C3=A4fer?= Date: Wed, 3 Apr 2024 10:16:48 +0200 Subject: [PATCH] Add database.disable_server_side_cursors option (#4016) --- doc/admin/config.rst | 6 ++++++ src/pretix/settings.py | 3 +++ 2 files changed, 9 insertions(+) diff --git a/doc/admin/config.rst b/doc/admin/config.rst index 5c83dda3e1..5c2e74b2bb 100644 --- a/doc/admin/config.rst +++ b/doc/admin/config.rst @@ -158,6 +158,7 @@ Example:: host=localhost port=3306 advisory_lock_index=1 + disable_server_side_cursors=0 sslmode=require sslrootcert=/etc/pretix/postgresql-ca.crt sslcert=/etc/pretix/postgresql-client-crt.crt @@ -178,6 +179,11 @@ Example:: and are not scoped to a specific database. If you run multiple pretix applications with the same PostgreSQL server, you should set separate values for this setting (integers up to 256). +``disable_server_side_cursors`` + On PostgreSQL pretix might use server side cursors for certain operations. This is generally fine but will break in + specific circumstances, for example when connecting to PostgreSQL through a PGBouncer configured with a transaction + pool mode. Off by default (i.e. by default server side cursors will be used). + ``sslmode``, ``sslrootcert`` Connection TLS details for the PostgreSQL database connection. Possible values of ``sslmode`` are ``disable``, ``allow``, ``prefer``, ``require``, ``verify-ca``, and ``verify-full``. ``sslrootcert`` should be the accessible path of the ca certificate. Both values are empty by default. diff --git a/src/pretix/settings.py b/src/pretix/settings.py index ab939cd8d8..0d1d0ee042 100644 --- a/src/pretix/settings.py +++ b/src/pretix/settings.py @@ -142,6 +142,8 @@ if USE_DATABASE_TLS or USE_DATABASE_MTLS: db_options.update(tls_config) +db_disable_server_side_cursors = db_backend == 'postgresql' and config.getboolean('database', 'disable_server_side_cursors', fallback=False) + DATABASES = { 'default': { 'ENGINE': 'django.db.backends.' + db_backend, @@ -152,6 +154,7 @@ DATABASES = { 'PORT': config.get('database', 'port', fallback=''), 'CONN_MAX_AGE': 0 if db_backend == 'sqlite3' else 120, 'CONN_HEALTH_CHECKS': db_backend != 'sqlite3', # Will only be used from Django 4.1 onwards + 'DISABLE_SERVER_SIDE_CURSORS': db_disable_server_side_cursors, 'OPTIONS': db_options, 'TEST': {} }