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.
66 lines
1.9 KiB
Python
66 lines
1.9 KiB
Python
from typing import Annotated, Optional, Union, Literal
|
|
|
|
from pydantic import BaseModel, Discriminator, RootModel, Tag
|
|
|
|
from cmapi_server.constants import (
|
|
DEFAULT_MCS_CONF_PATH, DEFAULT_SM_CONF_PATH, ClusterModeEnum,
|
|
)
|
|
from cmapi_server.managers.application import StatefulConfigModel
|
|
|
|
|
|
class BaseConfigPutRequestModel(BaseModel):
|
|
timeout: int
|
|
test: Optional[bool] = False
|
|
|
|
|
|
class BaseFullStatefulConfigPutRequestModel(BaseConfigPutRequestModel):
|
|
only_stateful_config: Optional[bool] = False
|
|
stateful_config_dict: StatefulConfigModel
|
|
|
|
|
|
class StatefulConfigPutRequestModel(BaseFullStatefulConfigPutRequestModel):
|
|
type: Literal['stateful'] = 'stateful'
|
|
|
|
|
|
class PutConfigSetModeRequestModel(BaseConfigPutRequestModel):
|
|
type: Literal['set_mode'] = 'set_mode'
|
|
revision: str
|
|
manager: str
|
|
cluster_mode: ClusterModeEnum
|
|
|
|
|
|
class FullConfigPutRequestModel(BaseFullStatefulConfigPutRequestModel):
|
|
type: Literal['full'] = 'full'
|
|
revision: str
|
|
manager: str
|
|
cluster_mode: Optional[str] = None
|
|
config: Optional[str] = None
|
|
sm_config: Optional[str] = None
|
|
mcs_config_filename: Optional[str] = DEFAULT_MCS_CONF_PATH
|
|
sm_config_filename: Optional[str] = DEFAULT_SM_CONF_PATH
|
|
secrets: Optional[dict] = None
|
|
|
|
|
|
def get_discriminator_value(data: dict) -> str:
|
|
"""Custom discriminator function for ConfigRequest union."""
|
|
if data.get('cluster_mode') is not None:
|
|
return 'set_mode'
|
|
if data.get('only_stateful_config', False):
|
|
return 'stateful'
|
|
return 'full'
|
|
|
|
|
|
class ConfigPutRequestRootModel(
|
|
RootModel[
|
|
Annotated[
|
|
Union[
|
|
Annotated[StatefulConfigPutRequestModel, Tag('stateful')],
|
|
Annotated[PutConfigSetModeRequestModel, Tag('set_mode')],
|
|
Annotated[FullConfigPutRequestModel, Tag('full')]
|
|
],
|
|
Discriminator(get_discriminator_value),
|
|
]
|
|
]
|
|
):
|
|
pass
|