You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In order to support converged db, we need to extract the data substrate related initialization into a separate function.
Motivation
Proposed Solution
In the init function, it should read a config file that has all configs related to data substrate. This config file should not have any database engine related configs.
It should initialize store_hd, log_service and tx_service in the right order. As the three core component of data substrate, they should be able to be accessed globally.
After data substrate initialization is done, database engine can do their own initialization and pass in its engine specific configs to data substrate (i.e. catalog factory)
Research: Data Substrate Initialization Analysis for Converged Database
Date: 2025-09-25T06:40:15Z Researcher: Claude Git Commit: N/A (not a git repository) Branch: N/A (not a git repository) Repository: converged
Research Question
What needs to be extracted into a shared data substrate initialization function to enable eloqkv and eloqsql to share the same data substrate components (tx_service, store_hd, log_service)? The data substrate will support multiple database engines (eloqsql, eloqkv, eloqdoc) simultaneously and use a unified configuration system.
Summary
Both eloqkv and eloqsql currently initialize their own data substrate components during their respective init functions. The data substrate consists of three core components: tx_service, store_hd (storage handler), and log_service (log agent). The new approach will use a unified configuration file + gflags pattern, with the data substrate reading from a separate config file without any engine-specific patterns. The TxService will accept multiple catalog factories (array of size 3) to support multiple engines simultaneously, with engine-specific dependencies wrapped in compile-time macros.
Unified Config File: Single data substrate config file with standardized naming
Gflags Integration: Use gflags for command-line overrides and defaults
Engine-Specific Configs: Engines pass their specific configurations to data substrate
No Engine Dependencies: Data substrate config file contains no engine-specific patterns
Potential Issues with Multi-Engine Data Substrate Initialization
1. Multi-Engine Catalog Factory Management
Issue: TxService needs to support multiple catalog factories simultaneously Impact: Current implementation expects single catalog factory Solution: Modify TxService to accept CatalogFactory* catalog_factory[3] array
2. Compile-Time Engine Selection
Issue: Engine-specific code needs to be conditionally compiled Impact: Data substrate must compile with or without specific engines Solution: Wrap all engine-specific dependencies in #ifdef ELOQSQL, #ifdef ELOQKV, #ifdef ELOQDOC macros
3. Engine Registration and Initialization Order
Issue: Multiple engines need to register with data substrate in correct order Impact: Initialization sequence becomes more complex Solution: Implement engine registration system with dependency management
4. Unified Configuration Management
Issue: Single config file must serve multiple engines without conflicts Impact: Configuration namespace and parameter management Solution: Use unified config file with engine-specific parameter passing
5. Resource Sharing and Isolation
Issue: Multiple engines sharing same data substrate resources Impact: Potential resource conflicts and performance isolation Solution: Implement resource partitioning and isolation mechanisms
Code References
eloqsql Key Files:
eloqsql/storage/eloq/ha_eloq.cc:2397 - Main initialization function
This plan implements a unified data substrate initialization system that supports multiple database engines (eloqsql, eloqkv, eloqdoc) simultaneously. The data substrate will use a unified INI configuration file with gflags support, and all engine-specific code will be wrapped in compile-time macros.
Current State Analysis
What exists now:
Separate initialization functions in eloqsql/storage/eloq/ha_eloq.cc:2397 and eloqkv/src/redis_service.cpp
Duplicate data substrate components (tx_service, store_hd, log_service) in both projects
Different configuration systems (MySQL variables vs gflags+INI)
Engine-specific catalog factories and system handlers
What's missing:
Unified data substrate initialization function
Multi-engine catalog factory support in TxService
Unified configuration system
Compile-time engine selection mechanism
Desired End State
After this plan is complete:
Single DataSubstrate class that can be initialized with multiple engines
Unified INI configuration file with no engine-specific patterns
TxService modified to accept catalog factory array for multiple engines
All engine-specific code wrapped in #ifdef ELOQSQL, #ifdef ELOQKV, #ifdef ELOQDOC macros
Modular initialization with separate helper functions for each component
Key Discoveries:
Both projects use identical data substrate components but with different initialization patterns
TxService currently expects single catalog factory but needs to support array of 3 engines
Configuration systems are fundamentally different and need unification
Engine-specific dependencies (CatalogFactory, SystemHandler) must be passed as parameters
What We're NOT Doing
Maintaining backward compatibility with existing configuration systems
Create a modular DataSubstrate class with separate helper functions for each component initialization. All helper functions will be implemented in the same data_substrate.cpp file to avoid file fragmentation while maintaining modularity. Use compile-time macros for engine-specific code and unified INI configuration.
File Structure
data_substrate/
├── include/
│ └── data_substrate.h # Main class definition
├── src/
│ └── data_substrate.cpp # All initialization functions
└── config/
└── sample_data_substrate.ini # Sample configuration
Note: All helper functions (configuration loading, storage handler init, log service init, engine registration, TxService init, service startup) are implemented as separate functions within the same data_substrate.cpp file to maintain modularity while reducing file fragmentation.
Phase 1: Create Data Substrate Foundation
Overview
Create the core DataSubstrate class structure and configuration system.
Changes Required:
1. Create Data Substrate Header
File: data_substrate/include/data_substrate.h Changes: Create main DataSubstrate class with configuration structures
Create helper function to initialize log service with unified configuration.
Changes Required:
1. Create Log Service Helper
File: data_substrate/src/data_substrate.cpp Changes: Implement log service initialization logic in the same file
#include"data_substrate.h"
#include"log_service/log_server.h"
#include"log_service/log_agent.h"boolDataSubstrate::InitializeLogService() {
// Parse txlog service list
std::vector<std::string> txlog_ips;
std::vector<uint16_t> txlog_ports;
if (!config_.txlog_service_list.empty()) {
std::string token;
std::istringstream txlog_ip_list_stream(config_.txlog_service_list);
while (std::getline(txlog_ip_list_stream, token, ',')) {
size_t c_idx = token.find_first_of(':');
if (c_idx != std::string::npos) {
txlog_ips.emplace_back(token.substr(0, c_idx));
txlog_ports.emplace_back(std::stoi(token.substr(c_idx + 1)));
}
}
}
// Create log agent
log_agent_ = std::make_unique<txservice::LogAgent>(
static_cast<uint32_t>(config_.txlog_group_replica_num)
);
// Initialize log server if no standalone service providedif (txlog_ips.empty()) {
// Initialize local log server
std::string log_path = config_.data_path + "/log_service";
log_server_ = std::make_unique<txlog::LogServer>(
0, // node_id - will be set by engine0, // port - will be set by engine
log_path,
config_.rocksdb_scan_threads
);
if (!log_server_->Start()) {
returnfalse;
}
}
returntrue;
}
Success Criteria:
Automated Verification:
Log service initialization compiles successfully
Log agent creation works correctly
Log server initialization handles both standalone and local modes
Manual Verification:
Local log server starts successfully
Standalone log service connection works
Log agent is properly configured
Phase 4: Implement Engine Registration System
Overview
Create helper function to register engines with compile-time macro support.
Changes Required:
1. Create Engine Registration Helper
File: data_substrate/src/data_substrate.cpp Changes: Implement hard-coded engine registration in the same file
Create helper function to initialize TxService with all registered engines.
Changes Required:
1. Create TxService Initialization Helper
File: data_substrate/src/data_substrate.cpp Changes: Implement TxService initialization with multi-engine support in the same file
#include"data_substrate.h"
#include"tx_service/tx_service.h"boolDataSubstrate::InitializeTxService() {
if (engines_.empty()) {
returnfalse;
}
// Prepare catalog factory and system handler arrays
CatalogFactory* catalog_factories[3] = {nullptr, nullptr, nullptr};
SystemHandler* system_handlers[3] = {nullptr, nullptr, nullptr};
// Fill arrays with registered enginesfor (size_t i = 0; i < engines_.size() && i < 3; i++) {
catalog_factories[i] = engines_[i].catalog_factory;
system_handlers[i] = engines_[i].system_handler;
}
// Create TxService with multi-engine support
tx_service_ = std::make_unique<txservice::TxService>(
catalog_factories,
system_handlers,
config_.tx_service_config,
0, // node_id - will be set by engine0, // native_ng_id - will be set by enginenullptr, // ng_configs - will be set by engine0, // cluster_config_version - will be set by engine
store_hd_.get(),
log_agent_.get(),
false, // enable_mvccfalse, // skip_redo_logfalse, // skip_kv
config_.enable_cache_replacement,
true, // auto_redirectnullptr, // metrics_registry - will be set by engine
{} // common_labels - will be set by engine
);
if (!tx_service_) {
returnfalse;
}
// Set tx_service reference in storage handlerif (store_hd_) {
store_hd_->SetTxService(tx_service_.get());
}
returntrue;
}
Success Criteria:
Automated Verification:
TxService initialization compiles successfully
Multi-engine arrays are properly populated
Storage handler reference is correctly set
Manual Verification:
TxService is created with all registered engines
Storage handler can access TxService
All engines are properly initialized
Phase 7: Implement Service Startup Helper
Overview
Create helper function to start all services in correct order.
Changes Required:
1. Create Service Startup Helper
File: data_substrate/src/data_substrate.cpp Changes: Implement service startup sequence in the same file
#include"data_substrate.h"boolDataSubstrate::StartServices() {
if (!tx_service_) {
returnfalse;
}
// Start TxService// Note: Engine-specific parameters will be provided by engines
std::vector<std::string> txlog_ips;
std::vector<uint16_t> txlog_ports;
// Parse txlog service list for startupif (!config_.txlog_service_list.empty()) {
std::string token;
std::istringstream txlog_ip_list_stream(config_.txlog_service_list);
while (std::getline(txlog_ip_list_stream, token, ',')) {
size_t c_idx = token.find_first_of(':');
if (c_idx != std::string::npos) {
txlog_ips.emplace_back(token.substr(0, c_idx));
txlog_ports.emplace_back(std::stoi(token.substr(c_idx + 1)));
}
}
}
// Start TxService (engine-specific parameters will be provided by engines)int start_result = tx_service_->Start(
0, // node_id - will be set by engine0, // native_ng_id - will be set by enginenullptr, // ng_configs - will be set by engine0, // cluster_config_version - will be set by engine
&txlog_ips,
&txlog_ports,
nullptr, // hm_ip - will be set by enginenullptr, // hm_port - will be set by enginenullptr, // hm_bin_path - will be set by engine
config_.tx_service_config,
std::move(log_agent_),
config_.data_path,
""// cluster_config_file - will be set by engine
);
return start_result >= 0;
}
Success Criteria:
Automated Verification:
Service startup compiles successfully
TxService start method is called correctly
Error handling is properly implemented
Manual Verification:
TxService starts successfully
All services are running after startup
Error conditions are handled gracefully
Phase 8: Implement Main DataSubstrate Initialization
Overview
Create the main initialization function that orchestrates all helper functions.
Changes Required:
1. Create Main Initialization Function
File: data_substrate/src/data_substrate.cpp Changes: Implement main initialization orchestration
Init function has been refactored into a separate data substrate init.
Eloqkv and eloqsql can be built with the new data substrate.
ConvergeDB can build and run eloqkv and eloqsql together.
In progress:
clean up eloqkv code and merge into main. Maintain backward compatibility and update build script/doc.
TODO:
same for eloqsql
Refactor code to clarify start up process in convergedb
Activity
liunyl commentedon Sep 25, 2025
Research: Data Substrate Initialization Analysis for Converged Database
Date: 2025-09-25T06:40:15Z
Researcher: Claude
Git Commit: N/A (not a git repository)
Branch: N/A (not a git repository)
Repository: converged
Research Question
What needs to be extracted into a shared data substrate initialization function to enable eloqkv and eloqsql to share the same data substrate components (tx_service, store_hd, log_service)? The data substrate will support multiple database engines (eloqsql, eloqkv, eloqdoc) simultaneously and use a unified configuration system.
Summary
Both eloqkv and eloqsql currently initialize their own data substrate components during their respective init functions. The data substrate consists of three core components: tx_service, store_hd (storage handler), and log_service (log agent). The new approach will use a unified configuration file + gflags pattern, with the data substrate reading from a separate config file without any engine-specific patterns. The TxService will accept multiple catalog factories (array of size 3) to support multiple engines simultaneously, with engine-specific dependencies wrapped in compile-time macros.
Detailed Findings
Current Initialization Functions
eloqsql Initialization (
ha_eloq.cc:2397)eloq_init_func(void *p)eloqsql/storage/eloq/ha_eloq.cc:2397-3283eloq_prefixstorage_hd) - lines 2558, 2573, 2750log_agent) - line 3095tx_service) - lines 3209, 3227eloqkv Initialization (
redis_service.cpp)RedisServiceImpl::Init()(main initialization)eloqkv/src/redis_service.cppFLAGS_prefix + INI config filesstore_hd_) - lines 961, 978, 1138log_agent) - line 1374tx_service_) - line 1437Data Substrate Components Analysis
1. TxService
Purpose: Core transaction management service
Initialization Pattern:
std::unique_ptr<TxService>CatalogFactory(engine-specific)SystemHandler(engine-specific:MariaSystemHandlervsnullptr)DataStoreHandler(store_hd)LogAgent(log_service)Configuration Parameters (from both projects):
2. Store Handler (store_hd)
Purpose: Data storage abstraction layer
Implementation Types:
EloqDS::DynamoHandler- DynamoDB backendEloqKV::RocksDBHandlerImpl- RocksDB backendEloqDS::DataStoreServiceClient- Data store service clientEloqDS::BigTableHandler- BigTable backendInitialization Dependencies:
Connect()methodSetTxService()call after tx_service creation3. Log Service (log_agent)
Purpose: Write-ahead logging and replication
Implementation:
MyEloqLogAgent(eloqsql) vsEloqKV::EloqLogAgent(eloqkv)InitTxLogService()Configuration Pattern Differences
Current eloqsql Configuration System
eloq_eloq_local_ip,eloq_core_num,eloq_txlog_service_listeloq_enable_tx_metrics,eloq_enable_log_service_metricsmysql_real_data_home_ptrCurrent eloqkv Configuration System
FLAGS_for command line, config file sectionsFLAGS_txlog_service_list,FLAGS_core_numconfig_reader.GetString("cluster", "txlog_service_list")eloq_data_path(configurable)New Unified Configuration System
Initialization Sequence Analysis
Current eloqsql Sequence:
storage_hd)log_agent)Current eloqkv Sequence:
store_hd_)Key Dependencies and Order Requirements
Critical Dependencies:
SetTxService()Multi-Engine Considerations:
CatalogFactory* catalog_factory[3]for eloqsql, eloqkv, eloqdoc#ifdefmacrosArchitecture Insights
Shared vs Engine-Specific Components
Shared Components (extracted to data substrate):
Engine-Specific Components (wrapped in compile macros):
#ifdef ELOQSQLMariaCatalogFactory,#ifdef ELOQKVengine-specific, etc.)#ifdef ELOQSQLMariaSystemHandler,#ifdef ELOQKVnullptr, etc.)Configuration Unification Approach
Potential Issues with Multi-Engine Data Substrate Initialization
1. Multi-Engine Catalog Factory Management
Issue: TxService needs to support multiple catalog factories simultaneously
Impact: Current implementation expects single catalog factory
Solution: Modify TxService to accept
CatalogFactory* catalog_factory[3]array2. Compile-Time Engine Selection
Issue: Engine-specific code needs to be conditionally compiled
Impact: Data substrate must compile with or without specific engines
Solution: Wrap all engine-specific dependencies in
#ifdef ELOQSQL,#ifdef ELOQKV,#ifdef ELOQDOCmacros3. Engine Registration and Initialization Order
Issue: Multiple engines need to register with data substrate in correct order
Impact: Initialization sequence becomes more complex
Solution: Implement engine registration system with dependency management
4. Unified Configuration Management
Issue: Single config file must serve multiple engines without conflicts
Impact: Configuration namespace and parameter management
Solution: Use unified config file with engine-specific parameter passing
5. Resource Sharing and Isolation
Issue: Multiple engines sharing same data substrate resources
Impact: Potential resource conflicts and performance isolation
Solution: Implement resource partitioning and isolation mechanisms
Code References
eloqsql Key Files:
eloqsql/storage/eloq/ha_eloq.cc:2397- Main initialization functioneloqsql/storage/eloq/ha_eloq.cc:3209,3227- TxService creationeloqsql/storage/eloq/ha_eloq.cc:2558,2573,2750- Storage handler creationeloqsql/storage/eloq/ha_eloq.cc:3095- Log agent creationeloqsql/storage/eloq/ha_eloq.cc:3253- SetTxService calleloqkv Key Files:
eloqkv/src/redis_service.cpp- Main initialization logiceloqkv/src/redis_service.cpp:1437- TxService creationeloqkv/src/redis_service.cpp:961,978,1138- Storage handler creationeloqkv/src/redis_service.cpp:1374- Log agent creationeloqkv/src/redis_service.cpp:1469- SetTxService callShared Components:
eloqkv/tx_service/include/tx_service.h- TxService interfaceeloqsql/storage/eloq/tx_service/include/tx_service.h- TxService interface (identical)eloqkv/tx_service/include/store/data_store_handler.h- Storage handler interfaceeloqsql/storage/eloq/tx_service/include/store/data_store_handler.h- Storage handler interface (identical)Recommendations
1. Create Multi-Engine Data Substrate Initialization Function
2. Compile-Time Engine Selection
3. Multi-Engine TxService Modification
4. Hard-Coded Engine Registration System
5. Phased Multi-Engine Initialization
Open Questions - Resolved
#ifdef ELOQKV,#ifdef ELOQDOC,#ifdef ELOQSQL- Current approach is correctImplementation Notes
Key Design Decisions
#ifdefmacros for conditional compilationConfiguration File Structure (INI Format)
Engine Registration Order
Related Research
liunyl commentedon Sep 25, 2025
Data Substrate Initialization Implementation Plan
Overview
This plan implements a unified data substrate initialization system that supports multiple database engines (eloqsql, eloqkv, eloqdoc) simultaneously. The data substrate will use a unified INI configuration file with gflags support, and all engine-specific code will be wrapped in compile-time macros.
Current State Analysis
What exists now:
eloqsql/storage/eloq/ha_eloq.cc:2397andeloqkv/src/redis_service.cppWhat's missing:
Desired End State
After this plan is complete:
DataSubstrateclass that can be initialized with multiple engines#ifdef ELOQSQL,#ifdef ELOQKV,#ifdef ELOQDOCmacrosKey Discoveries:
What We're NOT Doing
Implementation Approach
Create a modular
DataSubstrateclass with separate helper functions for each component initialization. All helper functions will be implemented in the samedata_substrate.cppfile to avoid file fragmentation while maintaining modularity. Use compile-time macros for engine-specific code and unified INI configuration.File Structure
Note: All helper functions (configuration loading, storage handler init, log service init, engine registration, TxService init, service startup) are implemented as separate functions within the same
data_substrate.cppfile to maintain modularity while reducing file fragmentation.Phase 1: Create Data Substrate Foundation
Overview
Create the core
DataSubstrateclass structure and configuration system.Changes Required:
1. Create Data Substrate Header
File:
data_substrate/include/data_substrate.hChanges: Create main DataSubstrate class with configuration structures
2. Create Configuration Loading Helper
File:
data_substrate/src/data_substrate.cppChanges: Implement configuration loading from INI file in the same file as main class
Success Criteria:
Automated Verification:
Manual Verification:
Phase 2: Implement Storage Handler Initialization
Overview
Create helper function to initialize storage handler with unified configuration.
Changes Required:
1. Create Storage Handler Helper
File:
data_substrate/src/data_substrate.cppChanges: Implement storage handler initialization logic in the same file
Success Criteria:
Automated Verification:
Manual Verification:
Phase 3: Implement Log Service Initialization
Overview
Create helper function to initialize log service with unified configuration.
Changes Required:
1. Create Log Service Helper
File:
data_substrate/src/data_substrate.cppChanges: Implement log service initialization logic in the same file
Success Criteria:
Automated Verification:
Manual Verification:
Phase 4: Implement Engine Registration System
Overview
Create helper function to register engines with compile-time macro support.
Changes Required:
1. Create Engine Registration Helper
File:
data_substrate/src/data_substrate.cppChanges: Implement hard-coded engine registration in the same file
Success Criteria:
Automated Verification:
Manual Verification:
Phase 5: Modify TxService for Multi-Engine Support
Overview
Modify TxService to accept catalog factory array and system handler array for multiple engines.
Changes Required:
1. Update TxService Constructor
File:
tx_service/include/tx_service.hChanges: Modify constructor to accept arrays for multiple engines
2. Update TxService Implementation
File:
tx_service/src/tx_service.cppChanges: Update constructor implementation to handle multiple engines
Success Criteria:
Automated Verification:
Manual Verification:
Phase 6: Implement TxService Initialization Helper
Overview
Create helper function to initialize TxService with all registered engines.
Changes Required:
1. Create TxService Initialization Helper
File:
data_substrate/src/data_substrate.cppChanges: Implement TxService initialization with multi-engine support in the same file
Success Criteria:
Automated Verification:
Manual Verification:
Phase 7: Implement Service Startup Helper
Overview
Create helper function to start all services in correct order.
Changes Required:
1. Create Service Startup Helper
File:
data_substrate/src/data_substrate.cppChanges: Implement service startup sequence in the same file
Success Criteria:
Automated Verification:
Manual Verification:
Phase 8: Implement Main DataSubstrate Initialization
Overview
Create the main initialization function that orchestrates all helper functions.
Changes Required:
1. Create Main Initialization Function
File:
data_substrate/src/data_substrate.cppChanges: Implement main initialization orchestration
Success Criteria:
Automated Verification:
Manual Verification:
Phase 9: Create Sample Configuration File
Overview
Create sample configuration file for testing and documentation.
Changes Required:
1. Create Sample Configuration
File:
data_substrate/config/sample_data_substrate.iniChanges: Create comprehensive sample configuration
Success Criteria:
Automated Verification:
Manual Verification:
Testing Strategy
Unit Tests:
Integration Tests:
Manual Testing Steps:
Performance Considerations
Migration Notes
References
thoughts/shared/research/2025-09-25-ENG-128-data-substrate-initialization.mdeloqsql/storage/eloq/ha_eloq.cc:2397eloqkv/src/redis_service.cpptx_service/include/tx_service.htx_service/include/store/data_store_handler.hliunyl commentedon Oct 24, 2025
Init function has been refactored into a separate data substrate init.
Eloqkv and eloqsql can be built with the new data substrate.
ConvergeDB can build and run eloqkv and eloqsql together.
liunyl commentedon Oct 24, 2025
In progress:
clean up eloqkv code and merge into main. Maintain backward compatibility and update build script/doc.
TODO:
same for eloqsql
Refactor code to clarify start up process in convergedb