You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-11-02 06:13:16 +03:00
- Add SharedStorageMonitor thread to periodically verify shared storage:
* Writes a temp file to the shared location and validates MD5 from all nodes.
* Skips nodes with unstable recent heartbeats; retries once; defers decision if any node is unreachable.
* Updates a cluster-wide stateful flag (shared_storage_on) only on conclusive checks.
- New CMAPI endpoints:
* PUT /cmapi/{ver}/cluster/check-shared-storage — orchestrates cross-node checks.
* GET /cmapi/{ver}/node/check-shared-file — validates a given file’s MD5 on a node.
* PUT /cmapi/{ver}/node/stateful-config — fast path to distribute stateful config updates.
- Introduce in-memory stateful config (AppStatefulConfig) with versioned flags (term/seq) and shared_storage_on flag:
* Broadcast via helpers.broadcast_stateful_config and enhanced broadcast_new_config.
* Config PUT is now validated with Pydantic models; supports stateful-only updates and set_mode requests.
- Failover behavior:
* NodeMonitor keeps failover inactive when shared_storage_on is false or cluster size < 3.
* Rebalancing DBRoots becomes a no-op when shared storage is OFF (safety guard).
- mcl status improvements: per-node 'state' (online/offline), better timeouts and error reporting.
- Routing/wiring: add dispatcher routes for new endpoints; add ClusterModeEnum.
- Tests: cover shared-storage monitor (unreachable nodes, HB-based skipping), node manipulation with shared storage ON/OFF, and server/config flows.
- Dependencies: add pydantic; minor cleanups and logging.
183 lines
6.6 KiB
Python
183 lines
6.6 KiB
Python
"""Module contains constants values for cmapi, failover and other .py files.
|
|
|
|
TODO: move main constant paths here and replace in files in next releases.
|
|
"""
|
|
import os
|
|
from dataclasses import dataclass
|
|
from enum import Enum
|
|
from typing import NamedTuple
|
|
|
|
# default MARIADB ColumnStore config path
|
|
MCS_ETC_PATH = '/etc/columnstore'
|
|
DEFAULT_MCS_CONF_PATH = os.path.join(MCS_ETC_PATH, 'Columnstore.xml')
|
|
|
|
# default Storage Manager config path
|
|
DEFAULT_SM_CONF_PATH = os.path.join(MCS_ETC_PATH, 'storagemanager.cnf')
|
|
|
|
# MCSDATADIR (in mcs engine code) and related paths
|
|
MCS_DATA_PATH = '/var/lib/columnstore'
|
|
MCS_MODULE_FILE_PATH = os.path.join(MCS_DATA_PATH, 'local/module')
|
|
EM_PATH_SUFFIX = 'data1/systemFiles/dbrm'
|
|
MCS_EM_PATH = os.path.join(MCS_DATA_PATH, EM_PATH_SUFFIX)
|
|
MCS_BRM_CURRENT_PATH = os.path.join(MCS_EM_PATH, 'BRM_saves_current')
|
|
S3_BRM_CURRENT_PATH = os.path.join(EM_PATH_SUFFIX, 'BRM_saves_current')
|
|
|
|
# keys file for CEJ password encryption\decryption
|
|
# (CrossEngineSupport section in Columnstore.xml)
|
|
MCS_SECRETS_FILENAME = '.secrets'
|
|
MCS_SECRETS_FILE_PATH = os.path.join(MCS_DATA_PATH, MCS_SECRETS_FILENAME)
|
|
|
|
# CMAPI SERVER
|
|
CMAPI_CONFIG_FILENAME = 'cmapi_server.conf'
|
|
CMAPI_ROOT_PATH = os.path.dirname(__file__)
|
|
PROJECT_PATH = os.path.dirname(CMAPI_ROOT_PATH)
|
|
# path to VERSION file
|
|
VERSION_PATH = os.path.join(PROJECT_PATH, 'VERSION')
|
|
CMAPI_LOG_CONF_PATH = os.path.join(CMAPI_ROOT_PATH, 'cmapi_logger.conf')
|
|
# path to CMAPI default config
|
|
CMAPI_DEFAULT_CONF_PATH = os.path.join(CMAPI_ROOT_PATH, CMAPI_CONFIG_FILENAME)
|
|
# CMAPI config path
|
|
CMAPI_CONF_PATH = os.path.join(MCS_ETC_PATH, CMAPI_CONFIG_FILENAME)
|
|
|
|
# TOTP secret key
|
|
SECRET_KEY = 'MCSIsTheBestEver' # not just a random string! (base32)
|
|
|
|
|
|
# network constants
|
|
# according to https://www.ibm.com/docs/en/storage-sentinel/1.1.2?topic=installation-map-your-local-host-loopback-address
|
|
|
|
LOCALHOST_IPS = {
|
|
'127.0.0.1',
|
|
'::1',
|
|
}
|
|
LOCALHOST_HOSTNAMES = {
|
|
'localhost', 'localhost.localdomain',
|
|
'localhost4', 'localhost4.localdomain4',
|
|
'localhost6', 'localhost6.localdomain6',
|
|
}
|
|
LOCALHOSTS = LOCALHOST_IPS.union(LOCALHOST_HOSTNAMES)
|
|
|
|
CMAPI_INSTALL_PATH = '/usr/share/columnstore/cmapi/'
|
|
CMAPI_PYTHON_BIN = os.path.join(CMAPI_INSTALL_PATH, "python/bin/python3")
|
|
CMAPI_PYTHON_DEPS_PATH = os.path.join(CMAPI_INSTALL_PATH, "deps")
|
|
CMAPI_PYTHON_BINARY_DEPS_PATH = os.path.join(CMAPI_PYTHON_DEPS_PATH, "bin")
|
|
CMAPI_SINGLE_NODE_XML = os.path.join(
|
|
CMAPI_INSTALL_PATH, 'cmapi_server/SingleNode.xml'
|
|
)
|
|
|
|
class MCSProgs(str, Enum):
|
|
STORAGE_MANAGER = 'StorageManager'
|
|
WORKER_NODE = 'workernode'
|
|
CONTROLLER_NODE = 'controllernode'
|
|
PRIM_PROC = 'PrimProc'
|
|
WRITE_ENGINE_SERVER = 'WriteEngineServer'
|
|
DML_PROC = 'DMLProc'
|
|
DDL_PROC = 'DDLProc'
|
|
|
|
# constants for dispatchers
|
|
class ProgInfo(NamedTuple):
|
|
"""NamedTuple for some additional info about handling mcs processes."""
|
|
stop_priority: int # priority for building stop sequence
|
|
service_name: str # systemd service name
|
|
subcommand: str # subcommand for process run in docker container
|
|
only_primary: bool # use this process only on primary
|
|
delay: int = 0 # delay after process start in docker container
|
|
|
|
# mcs-loadbrm and mcs-savebrm are dependencies for workernode and resolved
|
|
# on top level of process handling
|
|
# mcs-storagemanager starts conditionally inside mcs-loadbrm, but should be
|
|
# stopped using cmapi
|
|
ALL_MCS_PROGS: dict[MCSProgs, ProgInfo] = {
|
|
# workernode starts on primary and non primary node with 1 or 2 added
|
|
# to subcommand (DBRM_Worker1 - on primary, DBRM_Worker2 - non primary)
|
|
MCSProgs.STORAGE_MANAGER: ProgInfo(15, 'mcs-storagemanager', '', False, 1),
|
|
MCSProgs.WORKER_NODE: ProgInfo(13, 'mcs-workernode', 'DBRM_Worker{}', False, 1),
|
|
MCSProgs.CONTROLLER_NODE: ProgInfo(11, 'mcs-controllernode', 'fg', True),
|
|
MCSProgs.PRIM_PROC: ProgInfo(5, 'mcs-primproc', '', False, 1),
|
|
MCSProgs.WRITE_ENGINE_SERVER: ProgInfo(7, 'mcs-writeengineserver', '', False, 3),
|
|
MCSProgs.DML_PROC: ProgInfo(3, 'mcs-dmlproc', '', False),
|
|
MCSProgs.DDL_PROC: ProgInfo(1, 'mcs-ddlproc', '', False),
|
|
}
|
|
|
|
# constants for docker container dispatcher
|
|
MCS_INSTALL_BIN = '/usr/bin'
|
|
IFLAG = os.path.join(MCS_ETC_PATH, 'container-initialized')
|
|
LIBJEMALLOC_DEFAULT_PATH = os.path.join(MCS_DATA_PATH, 'libjemalloc.so.2')
|
|
MCS_LOG_PATH = '/var/log/mariadb/columnstore'
|
|
|
|
# BRM shmem lock inspection/reset tool
|
|
SHMEM_LOCKS_PATH = os.path.join(MCS_INSTALL_BIN, 'mcs-shmem-locks')
|
|
# mcs and cmapi constanst shared
|
|
MCS_BACKUP_MANAGER_SH = os.path.join(MCS_INSTALL_BIN, 'mcs_backup_manager.sh')
|
|
|
|
# client constants
|
|
CMAPI_PORT = 8640 #TODO: use it in all places
|
|
CURRENT_NODE_CMAPI_URL = f'https://localhost:{CMAPI_PORT}'
|
|
REQUEST_TIMEOUT: float = 30.0
|
|
TRANSACTION_TIMEOUT: float = 300.0 # 5 minutes
|
|
|
|
# API version
|
|
_version = '0.4.0'
|
|
|
|
# constants for packages and repositories
|
|
SUPPORTED_DISTROS = (
|
|
'ubuntu',
|
|
'debian',
|
|
'centos',
|
|
'rhel',
|
|
'rocky',
|
|
)
|
|
SUPPORTED_ARCHITECTURES = ('x86_64', 'amd64', 'aarch64', 'arm64')
|
|
|
|
@dataclass(frozen=True)
|
|
class MultiDistroNamer:
|
|
rhel: str
|
|
deb: str
|
|
|
|
MDB_SERVER_PACKAGE_NAME = MultiDistroNamer(
|
|
rhel='MariaDB-server',
|
|
deb='mariadb-server'
|
|
)
|
|
MDB_CS_PACKAGE_NAME = MultiDistroNamer(
|
|
rhel='MariaDB-columnstore-engine',
|
|
deb='mariadb-plugin-columnstore'
|
|
)
|
|
CMAPI_PACKAGE_NAME = MultiDistroNamer(
|
|
rhel='MariaDB-columnstore-cmapi',
|
|
deb='mariadb-columnstore-cmapi'
|
|
)
|
|
ES_REPO = MultiDistroNamer(
|
|
rhel=(
|
|
'''[mariadb-es-main]
|
|
name = MariaDB Enterprise Server
|
|
baseurl = https://dlm.mariadb.com/repo/{token}/mariadb-enterprise-server/{mdb_version}/rpm/rhel/{os_major_version}/{arch}
|
|
gpgkey = {gpg_key_url}
|
|
gpgcheck = 1
|
|
enabled = 1
|
|
module_hotfixes = 1
|
|
'''
|
|
),
|
|
deb='deb [arch=amd64,arm64] https://dlm.mariadb.com/repo/{token}/mariadb-enterprise-server/{mdb_version}/deb {os_version} main'
|
|
)
|
|
ES_REPO_PRIORITY_PREFS = '''
|
|
Package: *
|
|
Pin: origin dlm.mariadb.com
|
|
Pin-Priority: 1700
|
|
'''
|
|
ES_VERIFY_URL = MultiDistroNamer(
|
|
rhel='https://dlm.mariadb.com/repo/{token}/mariadb-enterprise-server/{mdb_version}/rpm/rhel/{os_major_version}/{arch}/repodata/repomd.xml',
|
|
deb='https://dlm.mariadb.com/repo/{token}/mariadb-enterprise-server/{mdb_version}/deb/dists/{os_version}/Release'
|
|
)
|
|
MDB_GPG_KEY_URL = 'https://supplychain.mariadb.com/MariaDB-Enterprise-GPG-KEY'
|
|
ES_TOKEN_VERIFY_URL = 'https://dlm.mariadb.com/browse/{token}/mariadb_enterprise_server/'
|
|
MDB_LATEST_TESTED_MAJOR = '10.6'
|
|
MDB_LATEST_RELEASES_URL = 'https://dlm.mariadb.com/rest/releases/mariadb_enterprise_server/'
|
|
PKG_GET_VER_CMD = MultiDistroNamer(
|
|
rhel="rpm -q --queryformat '%{{VERSION}}' {package_name}",
|
|
deb="dpkg-query -f '${{Version}}' -W {package_name}"
|
|
)
|
|
|
|
class ClusterModeEnum(str, Enum):
|
|
READONLY = 'readonly'
|
|
READWRITE = 'readwrite'
|