How ChaosBlade Uses SQLite to Track Experiment State: Internal Database Mechanisms
ChaosBlade persists every chaos experiment in a local SQLite file (chaosblade.dat) using the glebarez/sqlite driver, tracking lifecycle states through a singleton data.Source interface that manages the experiment table with columns for UID, status, error messages, and timestamps.
The chaosblade-io/chaosblade project implements a lightweight persistence layer to track the complete lifecycle of chaos engineering experiments. By leveraging a local SQLite database, the tool maintains a single source of truth for experiment state without requiring external database dependencies. This article examines how the SQLite database tracks experiment state through the data package, revealing the schema design, state transition logic, and CRUD operations that power ChaosBlade's experiment management.
SQLite Database Architecture in ChaosBlade
Database File Location and Configuration
The SQLite database file path is resolved by the GetDataFilePath() function in data/source.go. By default, the system creates a file named chaosblade.dat in the working directory. Administrators can override this location by setting the CHAOSBLADE_DATAFILE_PATH environment variable before starting the ChaosBlade CLI or server.
The Data Source Singleton Pattern
ChaosBlade opens the database through the standard database/sql package using the glebarez/sqlite driver. The GetSource() function implements a singleton pattern, ensuring that all components share a single data.Source instance. This singleton manages the database connection and provides thread-safe access to the experiment table across the application.
How the Experiment Table Tracks State
Table Schema and Initialization
The experiment table is created automatically on first run via CheckAndInitExperimentTable() in data/experiment.go. The initialization logic executes CREATE TABLE IF NOT EXISTS experiment with columns for uid, command, sub_command, flag, status, error, create_time, and update_time. This schema stores a single row per experiment, capturing the complete configuration and current state.
Status Column and Lifecycle Values
The status column implements the state machine for experiment lifecycle management. Valid values include Created, Running, Success, Error, and Destroyed. State transitions occur through the UpdateExperimentModelByUid() function, which atomically updates both the status and the update_time timestamp. This ensures that concurrent operations maintain consistency in the SQLite database track experiment state.
Error Handling and Audit Trails
When experiments fail, the error column stores the error message string alongside the status update. The create_time and update_time columns use RFC-3339 Nano format timestamps, providing a chronological audit trail for every state change. This design enables post-mortem analysis by preserving the exact sequence of events and any error messages generated during execution.
Code Examples: Working with Experiment State
Initializing the Database and Table
src := data.GetSource() // singleton creation
src.CheckAndInitExperimentTable() // auto-creates table if absent
Relevant source: data/source.go lines 50-59.
Creating a New Experiment Record
model := &data.ExperimentModel{
Uid: uid,
Command: cmd,
SubCommand: sub,
Flag: flag,
Status: "Created",
CreateTime: time.Now().Format(time.RFC3339Nano),
UpdateTime: time.Now().Format(time.RFC3339Nano),
}
src.InsertExperimentModel(model)
Relevant source: InsertExperimentModel in data/experiment.go lines 42-48.
Updating Status During Execution
src.UpdateExperimentModelByUid(uid, "Running", "")
// … after execution
src.UpdateExperimentModelByUid(uid, "Success", "")
// or on error
src.UpdateExperimentModelByUid(uid, "Error", errMsg)
Relevant source: UpdateExperimentModelByUid in data/experiment.go lines 64-68.
Querying Experiment State
exp, _ := src.QueryExperimentModelByUid(uid)
fmt.Printf("UID %s – status: %s, error: %s\n", exp.Uid, exp.Status, exp.Error)
Relevant source: QueryExperimentModelByUid in data/experiment.go lines 80-98.
Deleting Completed Experiments
src.DeleteExperimentModelByUid(uid)
Relevant source: DeleteExperimentModelByUid in data/experiment.go lines 4-11.
State Transitions During the Experiment Lifecycle
The SQLite database track experiment state through a well-defined lifecycle managed by the exec package executors. The flow follows these stages:
-
Bootstrap – The first call to
GetSource()creates the singletonSourceinstance and opens the SQLite file usingsql.Open("sqlite", GetDataFilePath()). -
Table Initialization –
CheckAndInitExperimentTable()verifies existence viaExperimentTableExists(); if missing,InitExperimentTable()executes the DDL to create theexperimenttable. -
Creation – When users run
blade create, the system callsInsertExperimentModelto persist a row with statusCreated, capturing the command, flags, and timestamps. -
Execution – Executors in
exec/*/executor.goinvokeUpdateExperimentModelByUid(uid, "Running", "")before injecting faults. Upon completion, they update toSuccessorErrorwith the error message. -
Query – The
blade statuscommand usesQueryExperimentModelByUidorQueryExperimentModelsto retrieve current state from the SQLite database track experiment state storage. -
Destruction – After
blade destroycompletes successfully, the status updates toDestroyedandDeleteExperimentModelByUidmay remove the row entirely.
This design ensures that the SQLite database track experiment state remains consistent even if the ChaosBlade process restarts, providing durable persistence for chaos engineering operations.
Summary
- ChaosBlade stores all experiment data in a local SQLite file (
chaosblade.dat) managed through thedata.Sourcesingleton. - The
experimenttable schema includes columns for UID, command configuration, status, error messages, and RFC-3339 Nano timestamps. - State transitions (Created → Running → Success/Error/Destroyed) occur through
UpdateExperimentModelByUidindata/experiment.go. - The SQLite database track experiment state without external dependencies, enabling both CLI and server modes to share persistent storage.
- All CRUD operations are thread-safe through the singleton pattern, ensuring consistency across concurrent chaos experiments.
Frequently Asked Questions
Where is the ChaosBlade SQLite database file located?
By default, ChaosBlade creates the chaosblade.dat file in the current working directory. You can override this location by setting the CHAOSBLADE_DATAFILE_PATH environment variable before starting the ChaosBlade CLI or server process. The path resolution logic is implemented in the GetDataFilePath() function within data/source.go.
What are the possible experiment statuses in the SQLite database?
The status column in the experiment table supports five lifecycle values: Created (initial state), Running (active execution), Success (completed without errors), Error (execution failed with error message stored), and Destroyed (cleaned up). These states are managed through the UpdateExperimentModelByUid function in data/experiment.go.
How does ChaosBlade ensure thread-safe access to the SQLite database?
ChaosBlade implements a singleton pattern through the GetSource() function in data/source.go, which returns a single data.Source instance shared across the application. This singleton manages the sql.DB connection pool returned by sql.Open("sqlite", ...), ensuring that all concurrent experiment operations access the SQLite database through a single coordinated entry point.
Can I query the ChaosBlade experiment state directly via SQL?
Yes, since ChaosBlade uses a standard SQLite file, you can query the experiment table directly using the sqlite3 command-line tool or any SQLite client. The table schema includes uid, command, sub_command, flag, status, error, create_time, and update_time columns. However, direct modifications are not recommended as they may interfere with ChaosBlade's internal state management logic.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →