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_PASSWORD") }} Database password (if required) |
|
||||||
{{ configsetting("INVENTREE_DB_HOST") }} Database host address (if required) |
|
{{ configsetting("INVENTREE_DB_HOST") }} Database host address (if required) |
|
||||||
{{ configsetting("INVENTREE_DB_PORT") }} Database host port (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) |
|
{{ configsetting("INVENTREE_DB_OPTIONS") }} Additional database options (as a JSON object) |
|
||||||
|
|
||||||
!!! tip "Database Password"
|
!!! 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:
|
If running with a PostgreSQL database backend, the following additional options are available:
|
||||||
|
|
||||||
{{ configtable() }}
|
{{ 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` | database.tcp_keepalives | 1 | TCP keepalive |
|
||||||
| `INVENTREE_DB_TCP_KEEPALIVES_IDLE` | database.tcp_keepalives_idle | 1 | Idle TCP keepalive |
|
| `INVENTREE_DB_TCP_KEEPALIVES_IDLE` | database.tcp_keepalives_idle | 5 | Idle TCP keepalive |
|
||||||
| `INVENTREE_DB_TCP_KEEPALIVES_INTERVAL` | database.tcp_keepalives_interval | 1| TCP keepalive interval |
|
| `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_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" |
|
| `INVENTREE_DB_ISOLATION_SERIALIZABLE` | database.serializable | False | Database isolation level configured to "serializable" |
|
||||||
|
|
||||||
### MySQL Settings
|
### 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:
|
If running with a MySQL database backend, the following additional options are available:
|
||||||
|
|
||||||
{{ configtable() }}
|
{{ configtable() }}
|
||||||
|
{{ configsetting("INVENTREE_DB_TIMEOUT", default="10") }} Database connection timeout (s) |
|
||||||
| `INVENTREE_DB_ISOLATION_SERIALIZABLE` | database.serializable | False | Database isolation level configured to "serializable" |
|
| `INVENTREE_DB_ISOLATION_SERIALIZABLE` | database.serializable | False | Database isolation level configured to "serializable" |
|
||||||
|
|
||||||
### SQLite Settings
|
### SQLite Settings
|
||||||
|
|||||||
@@ -5,10 +5,23 @@ from pathlib import Path
|
|||||||
import structlog
|
import structlog
|
||||||
|
|
||||||
from InvenTree.config import get_boolean_setting, get_config_value, get_setting
|
from InvenTree.config import get_boolean_setting, get_config_value, get_setting
|
||||||
|
from InvenTree.ready import isInWorkerThread
|
||||||
|
|
||||||
logger = structlog.get_logger('inventree')
|
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():
|
def get_db_backend():
|
||||||
"""Return the database backend configuration."""
|
"""Return the database backend configuration."""
|
||||||
# For the core database configuration values, we test for UPPERCASE configuration values as a backup,
|
# 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 get_config_value('database.OPTIONS')
|
||||||
or {},
|
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
|
# Check for required keys
|
||||||
@@ -113,9 +133,9 @@ def set_postgres_options(db_options: dict):
|
|||||||
if 'connect_timeout' not in db_options:
|
if 'connect_timeout' not in db_options:
|
||||||
# The DB server is in the same data center, it should not take very
|
# The DB server is in the same data center, it should not take very
|
||||||
# long to connect to the database server
|
# long to connect to the database server
|
||||||
# # seconds, 2 is minimum allowed by libpq
|
# Note: 2 seconds is minimum allowed by libpq
|
||||||
db_options['connect_timeout'] = int(
|
db_options['connect_timeout'] = max(
|
||||||
get_setting('INVENTREE_DB_TIMEOUT', 'database.timeout', 2)
|
2, int(get_setting('INVENTREE_DB_TIMEOUT', 'database.timeout', 10))
|
||||||
)
|
)
|
||||||
|
|
||||||
# Setup TCP keepalive
|
# Setup TCP keepalive
|
||||||
@@ -133,7 +153,7 @@ def set_postgres_options(db_options: dict):
|
|||||||
if 'keepalives_idle' not in db_options:
|
if 'keepalives_idle' not in db_options:
|
||||||
db_options['keepalives_idle'] = int(
|
db_options['keepalives_idle'] = int(
|
||||||
get_setting(
|
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(
|
get_setting(
|
||||||
'INVENTREE_DB_TCP_KEEPALIVES_INTERVAL',
|
'INVENTREE_DB_TCP_KEEPALIVES_INTERVAL',
|
||||||
'database.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
|
# # Milliseconds for how long pending data should remain unacked by the remote server
|
||||||
# by the remote server
|
if 'tcp_user_timeout' not in db_options:
|
||||||
# TODO: Supported starting in PSQL 11
|
db_options['tcp_user_timeout'] = int(
|
||||||
# "tcp_user_timeout": int(os.getenv("PGTCP_USER_TIMEOUT", "1000"),
|
get_setting(
|
||||||
|
'INVENTREE_DB_TCP_USER_TIMEOUT', 'database.tcp_user_timeout', '2000'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
# Postgres's default isolation level is Read Committed which is
|
# Postgres's default isolation level is Read Committed which is
|
||||||
# normally fine, but most developers think the database server 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
|
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):
|
def set_mysql_options(db_options: dict):
|
||||||
"""Set database options specific to mysql backend."""
|
"""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
|
# MariaDB's default isolation level is Repeatable Read which is
|
||||||
# normally fine, but most developers think the database server is
|
# normally fine, but most developers think the database server is
|
||||||
|
|||||||
Reference in New Issue
Block a user