Skip to content

Commit 7b814db

Browse files
authored
Merge pull request #10 from poyrazK/feature/phase-8-analytics-v2
Phase 8: Analytics (Columnar Storage & Vectorized Execution)
2 parents 1402b26 + 1f9d04a commit 7b814db

22 files changed

Lines changed: 1377 additions & 74 deletions

.github/workflows/ci.yml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,21 @@ on:
99
jobs:
1010
style-check:
1111
runs-on: ubuntu-latest
12+
permissions:
13+
contents: write
1214
steps:
1315
- uses: actions/checkout@v4
14-
- name: Run clang-format check
16+
with:
17+
ref: ${{ github.head_ref }}
18+
- name: Run clang-format fix
1519
run: |
1620
sudo apt-get update
1721
sudo apt-get install -y clang-format
1822
find src include tests -name "*.cpp" -o -name "*.hpp" | xargs clang-format -i
19-
git diff --exit-code
23+
- name: Commit style fixes
24+
uses: stefanzweifel/git-auto-commit-action@v5
25+
with:
26+
commit_message: "style: automated clang-format fixes"
2027

2128
build-and-test:
2229
needs: style-check

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ set(CORE_SOURCES
4848
src/distributed/raft_group.cpp
4949
src/distributed/raft_manager.cpp
5050
src/distributed/distributed_executor.cpp
51+
src/storage/columnar_table.cpp
5152
)
5253

5354
add_library(sqlEngineCore ${CORE_SOURCES})
@@ -96,6 +97,7 @@ if(BUILD_TESTS)
9697
add_cloudsql_test(raft_sim_tests tests/raft_simulation_tests.cpp)
9798
add_cloudsql_test(multi_raft_tests tests/multi_raft_tests.cpp)
9899
add_cloudsql_test(distributed_txn_tests tests/distributed_txn_tests.cpp)
100+
add_cloudsql_test(analytics_tests tests/analytics_tests.cpp)
99101

100102
add_custom_target(run-tests
101103
COMMAND ${CMAKE_CTEST_COMMAND}

README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,14 @@ A lightweight, distributed SQL database engine. Designed for cloud environments
1010
- **Distributed Query Optimization**:
1111
- **Shard Pruning**: Intelligent routing to avoid cluster-wide broadcasts.
1212
- **Aggregation Merging**: Global coordination for `COUNT`, `SUM`, and other aggregates.
13-
- **Broadcast Joins**: Optimized cross-shard joins for small-to-large table scenarios.
13+
- **Broadcast & Shuffle Joins**: Optimized cross-shard joins for small-to-large and large-to-large table scenarios.
14+
- **Data Replication & HA**: Fully redundant data storage with multi-group Raft and automatic leader failover.
15+
- **Analytics Performance**:
16+
- **Columnar Storage**: Binary-per-column persistence for efficient analytical scanning.
17+
- **Vectorized Execution**: Batch-at-a-time processing model for high-throughput query execution.
1418
- **Multi-Node Transactions**: ACID guarantees across the cluster via Two-Phase Commit (2PC).
1519
- **Type-Safe Value System**: Robust handling of SQL data types using `std::variant`.
16-
- **Volcano Execution Engine**: Iterator-based execution supporting sequential scans, index scans, filtering, projection, hash joins, sorting, and aggregation.
20+
- **Volcano & Vectorized Engine**: Flexible execution models supporting traditional row-based and high-performance columnar processing.
1721
- **PostgreSQL Wire Protocol**: Handshake and simple query protocol implementation for tool compatibility.
1822

1923
## Project Structure
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Phase 6: Distributed Multi-Shard Joins (Shuffle Join)
2+
3+
## Overview
4+
Phase 6 focused on implementing high-performance data redistribution (Shuffle) to enable complex JOIN operations across multiple shards without requiring a full broadcast of tables.
5+
6+
## Key Components
7+
8+
### 1. Context-Aware Shuffle Infrastructure (`common/cluster_manager.hpp`)
9+
Introduced isolated staging areas for inter-node data movement.
10+
- **Shuffle Buffering**: Thread-safe memory regions in `ClusterManager` to store incoming data fragments.
11+
- **Isolation**: Each shuffle context is uniquely identified, allowing multiple concurrent join operations without data corruption.
12+
13+
### 2. Shuffle RPC Protocol (`network/rpc_message.hpp`)
14+
Developed a dedicated binary protocol for efficient data redistribution.
15+
- **ShuffleFragment**: Metadata describing the fragment being pushed (target context, source node, schema).
16+
- **PushData**: High-speed binary payload containing the actual tuple data for the shuffle phase.
17+
18+
### 3. Two-Phase Join Orchestration (`distributed/distributed_executor.cpp`)
19+
Implemented the control logic for distributed shuffle joins.
20+
- **Phase 1 (Redistribute)**: Coordinates all data nodes to re-hash and push their local data to the appropriate target nodes based on the join key.
21+
- **Phase 2 (Local Join)**: Triggers local `HashJoin` operations on each node using the redistributed data stored in shuffle buffers.
22+
23+
### 4. BufferScanOperator Integration (`executor/operator.hpp`)
24+
Seamlessly integrated shuffle buffers into the Volcano execution model.
25+
- **Vectorized Buffering**: Optimized the `BufferScanOperator` to handle large volumes of redistributed data with minimal overhead.
26+
27+
## Lessons Learned
28+
- Shuffle joins significantly reduce network traffic compared to broadcast joins for large-to-large table joins.
29+
- Fine-grained locking in the shuffle buffers is critical for maintaining high throughput during the redistribution phase.
30+
31+
## Status: 100% Test Pass
32+
Verified the end-to-end shuffle join flow, including multi-node data movement and final result merging, through automated integration tests.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Phase 7: Replication & High Availability
2+
3+
## Overview
4+
Phase 7 introduced data redundancy and automatic failover capabilities to the cloudSQL engine, transforming it into a truly fault-tolerant distributed system.
5+
6+
## Key Components
7+
8+
### 1. Multi-Group Raft Management (`distributed/raft_manager.hpp`)
9+
Developed a sophisticated manager to handle multiple independent consensus groups.
10+
- **Dynamic Raft Instances**: Orchestrates `RaftGroup` objects for different shards and the global catalog.
11+
- **Leadership Tracking**: Real-time monitoring of leader status across the entire cluster.
12+
13+
### 2. Log-Based Data Replication (`distributed/raft_group.cpp`)
14+
Implemented high-performance replication for DML operations.
15+
- **Binary Log Entries**: Serializes SQL statements into binary logs for replication across nodes.
16+
- **State Machine Application**: Automatically applies replicated logs to the underlying `StorageManager`, ensuring consistency across all nodes.
17+
18+
### 3. Leader-Aware Routing (`distributed/distributed_executor.cpp`)
19+
Optimized query execution to leverage the replicated state.
20+
- **Dynamic Shard Location**: Resolves which node currently leads a specific shard for write operations.
21+
- **Read-Replica Support**: Enabled the engine to optionally route read queries to non-leader nodes for improved throughput.
22+
23+
### 4. Automatic Failover & Recovery
24+
Engineered robust mechanisms for maintaining system availability.
25+
- **Leader Election**: Verified that the Raft consensus protocol correctly handles node failures and elects new leaders.
26+
- **Persistence**: Full persistence of Raft logs and state ensures cluster recovery after full restarts.
27+
28+
## Lessons Learned
29+
- Managing multiple Raft groups significantly increases coordination complexity but is essential for scaling distributed data.
30+
- Leader-aware routing must be highly dynamic to avoid performance bottlenecks during cluster transitions.
31+
32+
## Status: 100% Test Pass
33+
Successfully verified the entire replication and failover cycle, including node failures during active workloads and final data consistency checks, via automated integration tests.

docs/phases/PHASE_8_ANALYTICS.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Phase 8: Analytics Performance (Columnar & Vectorized)
2+
3+
## Overview
4+
Phase 8 introduced native columnar storage and a vectorized execution engine to drastically improve the performance of analytical workloads.
5+
6+
## Key Components
7+
8+
### 1. Columnar Storage Layer (`src/storage/columnar_table.cpp`)
9+
Implemented a high-performance column-oriented data store.
10+
- **Binary Column Files**: Stores data in contiguous binary files on disk, one per column.
11+
- **Batch Read/Write**: Optimized I/O paths for loading and retrieving large blocks of data efficiently.
12+
- **Schema-Defined Layout**: Automatically organizes data based on the table's schema definition.
13+
14+
### 2. Vectorized Data Structures (`include/executor/types.hpp`)
15+
Developed SIMD-friendly contiguous memory buffers for batch processing.
16+
- **ColumnVector & NumericVector**: Specialized C++ templates for storing a "vector" of data for a single column.
17+
- **VectorBatch**: A collection of `ColumnVector` objects representing a chunk of rows (typically 1024 rows).
18+
19+
### 3. Vectorized Execution Engine (`include/executor/vectorized_operator.hpp`)
20+
Built a batch-at-a-time physical execution model.
21+
- **Vectorized Operators**: Implemented `Scan`, `Filter`, `Project`, and `Aggregate` operators designed for chunk-based execution.
22+
- **Batch-at-a-Time Interface**: Operators pass entire `VectorBatch` objects between themselves, minimizing virtual function call overhead.
23+
24+
### 4. High-Performance Aggregation
25+
Optimized global analytical queries (`COUNT`, `SUM`).
26+
- **Vectorized Global Aggregate**: Aggregates entire batches of data with minimal branching and high cache locality.
27+
- **Type-Specific Aggregation**: Leverages C++ templates to generate highly efficient aggregation logic for different data types.
28+
29+
## Lessons Learned
30+
- Vectorized execution significantly outperforms the traditional Volcano model for large-scale analytical queries.
31+
- Columnar storage is essential for minimizing I/O overhead when only a subset of columns is accessed.
32+
33+
## Status: 100% Test Pass
34+
Successfully verified the end-to-end vectorized pipeline, including columnar data persistence and complex analytical query patterns, through dedicated integration tests.

docs/phases/README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,24 @@ This directory contains the technical documentation for the lifecycle of the clo
3636
- Broadcast Join orchestration.
3737
- Inter-node data redistribution (Shuffle infrastructure).
3838

39+
### [Phase 6: Distributed Multi-Shard Joins](./PHASE_6_DISTRIBUTED_JOIN.md)
40+
**Focus**: High-throughput Data Redistribution.
41+
- Context-aware Shuffle infrastructure in `ClusterManager`.
42+
- Implementation of `ShuffleFragment` and `PushData` RPC protocols.
43+
- Two-phase Shuffle Join orchestration in `DistributedExecutor`.
44+
45+
### [Phase 7: Replication & High Availability](./PHASE_7_REPLICATION_HA.md)
46+
**Focus**: Fault Tolerance & Data Redundancy.
47+
- Multi-Group Raft management via `RaftManager`.
48+
- Log-based data replication for DML operations.
49+
- Leader-aware query routing and automatic failover.
50+
51+
### [Phase 8: Analytics Performance](./PHASE_8_ANALYTICS.md)
52+
**Focus**: Columnar Storage & Vectorized Execution.
53+
- Native Columnar storage implementation with binary persistence.
54+
- Batch-at-a-time vectorized execution model (Scan, Filter, Project, Aggregate).
55+
- High-performance `NumericVector` and `VectorBatch` data structures.
56+
3957
---
4058

4159
## Technical Standards

include/distributed/raft_types.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ struct RequestVoteArgs {
5757

5858
[[nodiscard]] std::vector<uint8_t> serialize() const {
5959
std::vector<uint8_t> out;
60-
constexpr size_t BASE_SIZE = 24;
60+
constexpr size_t BASE_SIZE = 32;
6161
out.resize(BASE_SIZE + candidate_id.size());
6262
std::memcpy(out.data(), &term, sizeof(term_t));
6363
const uint64_t id_len = candidate_id.size();

include/executor/operator.hpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,6 @@ enum class OperatorType : uint8_t {
4242
BufferScan
4343
};
4444

45-
/**
46-
* @brief Execution state
47-
*/
48-
enum class ExecState : uint8_t { Init, Open, Executing, Done, Error };
49-
5045
/**
5146
* @brief Base operator class (Volcano iterator model)
5247
*/
@@ -242,11 +237,6 @@ class SortOperator : public Operator {
242237
[[nodiscard]] Schema& output_schema() override;
243238
};
244239

245-
/**
246-
* @brief Aggregate types
247-
*/
248-
enum class AggregateType : uint8_t { Count, Sum, Avg, Min, Max };
249-
250240
/**
251241
* @brief Aggregate specification
252242
*/

0 commit comments

Comments
 (0)