From 7ed35e06ba6c4e1950ca747efa890751001c00ef Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Thu, 14 Feb 2019 10:14:12 +0100 Subject: [PATCH] Allow to configure a database replica --- doc/admin/config.rst | 17 +++++++++++++++++ src/pretix/settings.py | 17 +++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/doc/admin/config.rst b/doc/admin/config.rst index aecfda11c..f1223d929 100644 --- a/doc/admin/config.rst +++ b/doc/admin/config.rst @@ -125,6 +125,23 @@ Example:: Indicates if the database backend is a MySQL/MariaDB Galera cluster and turns on some optimizations/special case handlers. Default: ``False`` +Database replica settings +------------------------- + +If you use a replicated database setup, pretix expects that the default database connection always points to the primary database node. +Routing read queries to a replica on databse layer is **strongly** discouraged since this can lead to inaccurate such as more tickets +being sold than are actually available. + +However, pretix can still make use of a database replica to keep some expensive queries with that can tolerate some latency from your +primary database, such as backend search queries. The ``replica`` configuration section can have the same settings as the ``database`` +section (except for the ``backend`` setting) and will default back to the ``database`` settings for all values that are not given. This +way, you just need to specify the settings that are different for the replica. + +Example:: + + [replica] + host=192.168.0.2 + URLs ---- diff --git a/src/pretix/settings.py b/src/pretix/settings.py index 5e831e137..8e04ccc96 100644 --- a/src/pretix/settings.py +++ b/src/pretix/settings.py @@ -92,6 +92,23 @@ DATABASES = { } if 'mysql' in db_backend else {} } } +DATABASE_REPLICA = 'default' +if config.has_section('replica'): + DATABASE_REPLICA = 'replica' + DATABASES['replica'] = { + 'ENGINE': 'django.db.backends.' + db_backend, + 'NAME': config.get('replica', 'name', fallback=DATABASES['default']['NAME']), + 'USER': config.get('replica', 'user', fallback=DATABASES['default']['USER']), + 'PASSWORD': config.get('replica', 'password', fallback=DATABASES['default']['PASSWORD']), + 'HOST': config.get('replica', 'host', fallback=DATABASES['default']['HOST']), + 'PORT': config.get('replica', 'port', fallback=DATABASES['default']['PORT']), + 'CONN_MAX_AGE': 0 if db_backend == 'sqlite3' else 120, + 'OPTIONS': db_options, + 'TEST': { + 'CHARSET': 'utf8mb4', + 'COLLATION': 'utf8mb4_unicode_ci', + } if 'mysql' in db_backend else {} + } STATIC_URL = config.get('urls', 'static', fallback='/static/')