-
Notifications
You must be signed in to change notification settings - Fork 724
数据模式迁移
hikyuu系统通过版本化的SQL脚本和C++层的DBUpgrade组件,实现了安全、可靠的数据库模式演进机制。该机制确保了在系统升级过程中,数据库模式能够自动、原子性地更新到最新版本,同时保护现有数据的完整性和一致性。本文档详细阐述了hikyuu的数据库迁移策略、实现机制和最佳实践。
hikyuu使用位于hikyuu/data/{database_type}_upgrade/目录下的版本化SQL脚本(如0001.sql, 0002.sql等)来管理数据库模式的演进。每个脚本文件对应一个特定的数据库版本升级。
升级脚本采用零填充的四位数字命名(如0001.sql),数字代表目标数据库版本号。脚本按数字顺序执行,确保模式变更按预定顺序应用。例如,0001.sql创建初始数据库结构,0002.sql在此基础上进行修改。
每个升级脚本都设计为原子操作。脚本通常包含一系列数据库变更语句,最后以更新version表的语句结束。例如,在MySQL中,0002.sql脚本的最后一条语句是UPDATE hku_base.version set version = 2;。这种设计确保了只有当所有变更成功执行后,数据库版本号才会被更新,从而保证了升级过程的原子性。
对于全新的数据库,hikyuu提供了createdb.sql脚本。该脚本负责创建所有必需的数据库表和初始数据。例如,mysql_upgrade/createdb.sql脚本创建了version、market、stock等核心表,并插入了初始数据。
Section sources
- 0001.sql
- 0002.sql
- createdb.sql
hikyuu的C++层通过DBUpgrade组件实现数据库的自动检测和升级。该组件位于hikyuu_cpp/hikyuu/utilities/db_connect/DBUpgrade.cpp。
DBUpgrade函数是核心接口,其功能包括:
-
版本检测:检查数据库中
module_version表的当前版本。 - 条件判断:根据当前版本和可用的升级脚本,决定是否需要升级。
- 自动升级:按顺序执行必要的升级脚本,将数据库更新到最新版本。
-
初始化检查:如果
module_version表不存在,则创建该表。 -
获取当前版本:查询
module_version表获取当前数据库版本。 -
升级决策:
- 如果当前版本为0且有创建脚本,则执行创建脚本并设置版本为1。
- 如果当前版本低于升级脚本的起始版本,则拒绝升级(防止版本跳跃)。
- 如果当前版本已达到或超过目标版本,则无需升级。
- 执行升级:从需要开始的脚本索引处,顺序执行所有后续升级脚本。
-
更新版本:所有脚本执行成功后,更新
module_version表中的版本号。
flowchart TD
Start([开始]) --> CheckTableExist["检查 module_version 表是否存在"]
CheckTableExist --> |不存在| CreateTable["创建 module_version 表"]
CreateTable --> GetVersion
CheckTableExist --> |存在| GetVersion["获取当前数据库版本"]
GetVersion --> CheckVersion["检查当前版本"]
CheckVersion --> |版本为0且有创建脚本| CreateDB["执行创建脚本"]
CreateDB --> SetVersion1["设置版本为1"]
SetVersion1 --> End
CheckVersion --> |版本 < 起始版本-1| Error["版本过旧,无法升级"]
Error --> End
CheckVersion --> |版本 >= 目标版本| NoUpgrade["无需升级"]
NoUpgrade --> End
CheckVersion --> |需要升级| ExecuteScripts["从正确索引开始执行升级脚本"]
ExecuteScripts --> UpdateVersion["更新 module_version 表版本号"]
UpdateVersion --> End([结束])
**Diagram sources **
- DBUpgrade.cpp
Section sources
- DBUpgrade.cpp
- DBUpgrade.h
- 备份数据库:在执行任何升级操作前,务必备份现有数据库。这是防止数据丢失的最重要步骤。
- 确认版本:检查当前hikyuu版本和数据库版本,确保了解需要应用的升级脚本。
- 停止应用:关闭所有使用hikyuu数据库的应用程序。
-
执行升级:启动hikyuu应用,其内部的
DBUpgrade组件会自动检测并应用必要的升级脚本。 -
监控过程:观察应用日志,确保升级过程无错误。
DBUpgrade组件会输出详细的跟踪信息,如当前版本和执行的脚本索引。
如果升级失败或出现问题,应立即停止应用,并使用备份的数据库进行恢复。由于升级脚本是按版本顺序设计的,不建议手动执行回滚SQL,而应直接恢复到备份状态。
Section sources
- common_mysql.py
- common_sqlite3.py
对于ClickHouse数据库,hikyuu使用clickhouse_upgrade目录下的脚本。createdb.sql脚本不仅创建表,还定义了复杂的表引擎(如MergeTree)和分区策略。Python脚本common_clickhouse.py中的create_database函数负责按顺序执行这些脚本。
sqlite_mem_sql目录包含为内存数据库设计的createdb.sql脚本。该脚本使用BEGIN TRANSACTION和COMMIT来确保内存数据库初始化的原子性。
Section sources
- createdb.sql
- createdb.sql
hikyuu通过多种机制保护数据完整性:
- 原子性升级:每个升级脚本的最后一步是更新版本号,确保只有完全成功的升级才会被记录。
-
版本检查:
DBUpgrade组件会检查版本连续性,防止因缺失中间版本脚本而导致的不一致状态。 -
事务支持:对于支持事务的数据库(如SQLite),
createdb.sql脚本使用事务来保证初始化的原子性。 -
错误处理:
DBUpgrade组件包含异常捕获机制,确保在查询版本号失败时能优雅处理。
这些措施共同确保了在数据库模式演进过程中,数据的完整性和一致性得到最大程度的保护。
Section sources
- DBUpgrade.cpp
- createdb.sql