You've already forked mariadb-columnstore-engine
							
							
				mirror of
				https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
				synced 2025-11-03 17:13:17 +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.
		
	
		
			
				
	
	
		
			46 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			46 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
import unittest
 | 
						|
import requests
 | 
						|
import configparser
 | 
						|
from pathlib import Path
 | 
						|
from datetime import datetime
 | 
						|
 | 
						|
from cmapi_server.constants import _version
 | 
						|
 | 
						|
config_filename = './cmapi_server/cmapi_server.conf'
 | 
						|
 | 
						|
url = f"https://localhost:8640/cmapi/{_version}/node/config"
 | 
						|
begin_url = f"https://localhost:8640/cmapi/{_version}/node/begin"
 | 
						|
config_path = './cmapi_server/test/Columnstore_apply_config.xml'
 | 
						|
 | 
						|
# create tmp dir
 | 
						|
tmp_prefix = '/tmp/mcs_config_test'
 | 
						|
tmp_path = Path(tmp_prefix)
 | 
						|
tmp_path.mkdir(parents = True, exist_ok = True)
 | 
						|
copyfile(config_path_old, tmp_prefix + '/Columnstore.xml')
 | 
						|
 | 
						|
 | 
						|
def get_current_key():
 | 
						|
    app_config = configparser.ConfigParser()
 | 
						|
    try:
 | 
						|
        with open(config_filename, 'r') as _config_file:
 | 
						|
            app_config.read_file(_config_file)
 | 
						|
    except FileNotFoundError:
 | 
						|
        return ''
 | 
						|
    if 'Authentication' not in app_config.sections():
 | 
						|
        return ''
 | 
						|
    return app_config['Authentication'].get('x-api-key', '')
 | 
						|
 | 
						|
headers = {'x-api-key': get_current_key()}
 | 
						|
body = {'id': 42, 'timeout': 120}
 | 
						|
r = requests.put(begin_url, verify=False, headers=headers, json=body)
 | 
						|
 | 
						|
config_file = Path(config_path)
 | 
						|
config = config_file.read_text()
 | 
						|
 | 
						|
body = {
 | 
						|
    'revision': '42',
 | 
						|
    'manager': '1.1.1.1',
 | 
						|
    'timeout': 0,
 | 
						|
    'config': config,
 | 
						|
}
 |