mirror of
https://github.com/inventree/InvenTree.git
synced 2026-06-06 08:54:24 +00:00
[db] Postgresql setup (#12051)
* Adjust default postgres connection settings * Support tcp_user_timeout * Set application name based on running context * Add CONN_MAX_AGE and CONN_HEALTH_CHECKS * Add connection timeout option for mysql
This commit is contained in:
@@ -256,6 +256,9 @@ The following database options can be configured:
|
||||
{{ configsetting("INVENTREE_DB_PASSWORD") }} Database password (if required) |
|
||||
{{ configsetting("INVENTREE_DB_HOST") }} Database host address (if required) |
|
||||
{{ configsetting("INVENTREE_DB_PORT") }} Database host port (if required) |
|
||||
{{ configsetting("INVENTREE_DB_CONN_MAX_AGE") }} Database connection max age (s) |
|
||||
{{ configsetting("INVENTREE_DB_CONN_HEALTH_CHECKS") }} Enable database connection health checks |
|
||||
|
||||
{{ configsetting("INVENTREE_DB_OPTIONS") }} Additional database options (as a JSON object) |
|
||||
|
||||
!!! tip "Database Password"
|
||||
@@ -266,11 +269,12 @@ The following database options can be configured:
|
||||
If running with a PostgreSQL database backend, the following additional options are available:
|
||||
|
||||
{{ configtable() }}
|
||||
{{ configsetting("INVENTREE_DB_TIMEOUT", default="2") }} Database connection timeout (s) |
|
||||
{{ configsetting("INVENTREE_DB_TIMEOUT", default="10") }} Database connection timeout (s) |
|
||||
| `INVENTREE_DB_TCP_KEEPALIVES` | database.tcp_keepalives | 1 | TCP keepalive |
|
||||
| `INVENTREE_DB_TCP_KEEPALIVES_IDLE` | database.tcp_keepalives_idle | 1 | Idle TCP keepalive |
|
||||
| `INVENTREE_DB_TCP_KEEPALIVES_INTERVAL` | database.tcp_keepalives_interval | 1| TCP keepalive interval |
|
||||
| `INVENTREE_DB_TCP_KEEPALIVES_IDLE` | database.tcp_keepalives_idle | 5 | Idle TCP keepalive |
|
||||
| `INVENTREE_DB_TCP_KEEPALIVES_INTERVAL` | database.tcp_keepalives_interval | 5 | TCP keepalive interval |
|
||||
| `INVENTREE_DB_TCP_KEEPALIVES_COUNT` | database.tcp_keepalives_count | 5 | TCP keepalive count |
|
||||
| `INVENTREE_DB_TCP_USER_TIMEOUT` | database.tcp_user_timeout | 2000 | TCP user timeout (ms) |
|
||||
| `INVENTREE_DB_ISOLATION_SERIALIZABLE` | database.serializable | False | Database isolation level configured to "serializable" |
|
||||
|
||||
### MySQL Settings
|
||||
@@ -278,6 +282,7 @@ If running with a PostgreSQL database backend, the following additional options
|
||||
If running with a MySQL database backend, the following additional options are available:
|
||||
|
||||
{{ configtable() }}
|
||||
{{ configsetting("INVENTREE_DB_TIMEOUT", default="10") }} Database connection timeout (s) |
|
||||
| `INVENTREE_DB_ISOLATION_SERIALIZABLE` | database.serializable | False | Database isolation level configured to "serializable" |
|
||||
|
||||
### SQLite Settings
|
||||
|
||||
@@ -5,10 +5,23 @@ from pathlib import Path
|
||||
import structlog
|
||||
|
||||
from InvenTree.config import get_boolean_setting, get_config_value, get_setting
|
||||
from InvenTree.ready import isInWorkerThread
|
||||
|
||||
logger = structlog.get_logger('inventree')
|
||||
|
||||
|
||||
def _get_conn_max_age() -> int | None:
|
||||
"""Return the configured CONN_MAX_AGE value.
|
||||
|
||||
Accepts an integer number of seconds, or 'None' for unlimited persistence.
|
||||
Defaults to 0 (close the connection after each request).
|
||||
"""
|
||||
value = get_setting('INVENTREE_DB_CONN_MAX_AGE', 'database.conn_max_age', 0)
|
||||
if value is None or str(value).strip().lower() == 'none':
|
||||
return None
|
||||
return int(value)
|
||||
|
||||
|
||||
def get_db_backend():
|
||||
"""Return the database backend configuration."""
|
||||
# For the core database configuration values, we test for UPPERCASE configuration values as a backup,
|
||||
@@ -43,6 +56,13 @@ def get_db_backend():
|
||||
)
|
||||
or get_config_value('database.OPTIONS')
|
||||
or {},
|
||||
# Seconds to keep idle connections open across requests (0 = close after each request).
|
||||
# Set to None for unlimited. Enable CONN_HEALTH_CHECKS alongside any non-zero value
|
||||
# so stale connections are detected before use rather than causing request failures.
|
||||
'CONN_MAX_AGE': _get_conn_max_age(),
|
||||
'CONN_HEALTH_CHECKS': get_boolean_setting(
|
||||
'INVENTREE_DB_CONN_HEALTH_CHECKS', 'database.conn_health_checks', False
|
||||
),
|
||||
}
|
||||
|
||||
# Check for required keys
|
||||
@@ -113,9 +133,9 @@ def set_postgres_options(db_options: dict):
|
||||
if 'connect_timeout' not in db_options:
|
||||
# The DB server is in the same data center, it should not take very
|
||||
# long to connect to the database server
|
||||
# # seconds, 2 is minimum allowed by libpq
|
||||
db_options['connect_timeout'] = int(
|
||||
get_setting('INVENTREE_DB_TIMEOUT', 'database.timeout', 2)
|
||||
# Note: 2 seconds is minimum allowed by libpq
|
||||
db_options['connect_timeout'] = max(
|
||||
2, int(get_setting('INVENTREE_DB_TIMEOUT', 'database.timeout', 10))
|
||||
)
|
||||
|
||||
# Setup TCP keepalive
|
||||
@@ -133,7 +153,7 @@ def set_postgres_options(db_options: dict):
|
||||
if 'keepalives_idle' not in db_options:
|
||||
db_options['keepalives_idle'] = int(
|
||||
get_setting(
|
||||
'INVENTREE_DB_TCP_KEEPALIVES_IDLE', 'database.tcp_keepalives_idle', 1
|
||||
'INVENTREE_DB_TCP_KEEPALIVES_IDLE', 'database.tcp_keepalives_idle', 5
|
||||
)
|
||||
)
|
||||
|
||||
@@ -143,7 +163,7 @@ def set_postgres_options(db_options: dict):
|
||||
get_setting(
|
||||
'INVENTREE_DB_TCP_KEEPALIVES_INTERVAL',
|
||||
'database.tcp_keepalives_interval',
|
||||
'1',
|
||||
'5',
|
||||
)
|
||||
)
|
||||
|
||||
@@ -157,10 +177,13 @@ def set_postgres_options(db_options: dict):
|
||||
)
|
||||
)
|
||||
|
||||
# # Milliseconds for how long pending data should remain unacked
|
||||
# by the remote server
|
||||
# TODO: Supported starting in PSQL 11
|
||||
# "tcp_user_timeout": int(os.getenv("PGTCP_USER_TIMEOUT", "1000"),
|
||||
# # Milliseconds for how long pending data should remain unacked by the remote server
|
||||
if 'tcp_user_timeout' not in db_options:
|
||||
db_options['tcp_user_timeout'] = int(
|
||||
get_setting(
|
||||
'INVENTREE_DB_TCP_USER_TIMEOUT', 'database.tcp_user_timeout', '2000'
|
||||
)
|
||||
)
|
||||
|
||||
# Postgres's default isolation level is Read Committed which is
|
||||
# normally fine, but most developers think the database server is
|
||||
@@ -178,10 +201,21 @@ def set_postgres_options(db_options: dict):
|
||||
else IsolationLevel.READ_COMMITTED
|
||||
)
|
||||
|
||||
# Specify the application name for the database connection
|
||||
# This can be useful for debugging and monitoring purposes
|
||||
if 'application_name' not in db_options:
|
||||
db_options['application_name'] = (
|
||||
'inventree-worker' if isInWorkerThread() else 'inventree-server'
|
||||
)
|
||||
|
||||
|
||||
def set_mysql_options(db_options: dict):
|
||||
"""Set database options specific to mysql backend."""
|
||||
# TODO TCP time outs and keepalives
|
||||
# Timeout values
|
||||
if 'connect_timeout' not in db_options:
|
||||
db_options['connect_timeout'] = int(
|
||||
get_setting('INVENTREE_DB_TIMEOUT', 'database.timeout', 10)
|
||||
)
|
||||
|
||||
# MariaDB's default isolation level is Repeatable Read which is
|
||||
# normally fine, but most developers think the database server is
|
||||
|
||||
Reference in New Issue
Block a user