mirror of
https://gitee.com/samwaf/SamWaf.git
synced 2026-11-03 11:41:55 +08:00
+25
-92
@@ -81,87 +81,14 @@ func InitCoreDb(currentDir string) (bool, error) {
|
||||
//db.Use(crypto.NewCryptoPlugin())
|
||||
// 注册默认的AES加解密策略
|
||||
//crypto.RegisterCryptoStrategy(strategy.NewAesCryptoStrategy("3Y)(27EtO^tK8Bj~"))
|
||||
// Migrate the schema
|
||||
db.AutoMigrate(&model.Hosts{})
|
||||
db.AutoMigrate(&model.Rules{})
|
||||
|
||||
//隐私处理
|
||||
db.AutoMigrate(&model.LDPUrl{})
|
||||
|
||||
//白名单处理
|
||||
db.AutoMigrate(&model.IPAllowList{})
|
||||
db.AutoMigrate(&model.URLAllowList{})
|
||||
|
||||
//限制处理
|
||||
db.AutoMigrate(&model.IPBlockList{})
|
||||
db.AutoMigrate(&model.URLBlockList{})
|
||||
|
||||
//抵抗CC
|
||||
db.AutoMigrate(&model.AntiCC{})
|
||||
|
||||
//waf自身账号
|
||||
db.AutoMigrate(&model.TokenInfo{})
|
||||
db.AutoMigrate(&model.Account{})
|
||||
|
||||
//系统参数
|
||||
db.AutoMigrate(&model.SystemConfig{})
|
||||
|
||||
//延迟信息
|
||||
db.AutoMigrate(&model.DelayMsg{})
|
||||
|
||||
//分库信息表
|
||||
db.AutoMigrate(&model.ShareDb{})
|
||||
|
||||
//中心管控数据
|
||||
db.AutoMigrate(&model.Center{})
|
||||
|
||||
//敏感词管理
|
||||
db.AutoMigrate(&model.Sensitive{})
|
||||
|
||||
//负载均衡
|
||||
db.AutoMigrate(&model.LoadBalance{})
|
||||
|
||||
//SSL证书
|
||||
db.AutoMigrate(&model.SslConfig{})
|
||||
|
||||
//IPTag
|
||||
db.AutoMigrate(&model.IPTag{})
|
||||
|
||||
//自动任务
|
||||
db.AutoMigrate(&model.BatchTask{})
|
||||
|
||||
//SSL证书申请订单
|
||||
db.AutoMigrate(&model.SslOrder{})
|
||||
|
||||
//SSL到期检测
|
||||
db.AutoMigrate(&model.SslExpire{})
|
||||
|
||||
//HTTP AUTH
|
||||
db.AutoMigrate(&model.HttpAuthBase{})
|
||||
|
||||
//任务
|
||||
db.AutoMigrate(&model.Task{})
|
||||
|
||||
//自定义拦截界面
|
||||
db.AutoMigrate(&model.BlockingPage{})
|
||||
|
||||
//OTP
|
||||
db.AutoMigrate(&model.Otp{})
|
||||
|
||||
//密钥信息
|
||||
db.AutoMigrate(&model.PrivateInfo{})
|
||||
|
||||
//密钥分组信息
|
||||
db.AutoMigrate(&model.PrivateGroup{})
|
||||
|
||||
//缓存规则
|
||||
db.AutoMigrate(&model.CacheRule{})
|
||||
|
||||
//隧道
|
||||
db.AutoMigrate(&model.Tunnel{})
|
||||
|
||||
//CA服务器信息
|
||||
db.AutoMigrate(&model.CaServerInfo{})
|
||||
// ============ 使用 gormigrate 替代 AutoMigrate(完全向后兼容) ============
|
||||
zlog.Info("开始执行core数据库迁移...")
|
||||
if err := RunCoreDBMigrations(db); err != nil {
|
||||
zlog.Error("core数据库迁移失败", "error", err)
|
||||
panic("core database migration failed: " + err.Error())
|
||||
}
|
||||
// ============ 迁移代码结束 ============
|
||||
|
||||
global.GWAF_LOCAL_DB.Callback().Query().Before("gorm:query").Register("tenant_plugin:before_query", before_query)
|
||||
global.GWAF_LOCAL_DB.Callback().Query().Before("gorm:update").Register("tenant_plugin:before_update", before_update)
|
||||
@@ -169,6 +96,7 @@ func InitCoreDb(currentDir string) (bool, error) {
|
||||
//重启需要删除无效规则
|
||||
db.Where("user_code = ? and rule_status = 999", global.GWAF_USER_CODE).Delete(model.Rules{})
|
||||
|
||||
// 执行数据补丁和默认值初始化(幂等操作,每次启动都执行)
|
||||
pathCoreSql(db)
|
||||
return isNewDb, nil
|
||||
} else {
|
||||
@@ -211,12 +139,15 @@ func InitLogDb(currentDir string) (bool, error) {
|
||||
//logDB.Use(crypto.NewCryptoPlugin())
|
||||
// 注册默认的AES加解密策略
|
||||
//crypto.RegisterCryptoStrategy(strategy.NewAesCryptoStrategy("3Y)(27EtO^tK8Bj~"))
|
||||
// Migrate the schema
|
||||
//统计处理
|
||||
db.AutoMigrate(&innerbean.WebLog{})
|
||||
db.AutoMigrate(&model.AccountLog{})
|
||||
db.AutoMigrate(&model.WafSysLog{})
|
||||
db.AutoMigrate(&model.OneKeyMod{})
|
||||
|
||||
// ============ 使用 gormigrate 替代 AutoMigrate(完全向后兼容) ============
|
||||
zlog.Info("开始执行log数据库迁移...")
|
||||
if err := RunLogDBMigrations(db); err != nil {
|
||||
zlog.Error("log数据库迁移失败", "error", err)
|
||||
panic("log database migration failed: " + err.Error())
|
||||
}
|
||||
// ============ 迁移代码结束 ============
|
||||
|
||||
global.GWAF_LOCAL_LOG_DB.Callback().Query().Before("gorm:query").Register("tenant_plugin:before_query", before_query)
|
||||
global.GWAF_LOCAL_LOG_DB.Callback().Query().Before("gorm:update").Register("tenant_plugin:before_update", before_update)
|
||||
|
||||
@@ -280,12 +211,14 @@ func InitManaulLogDb(currentDir string, custFileName string) {
|
||||
//logDB.Use(crypto.NewCryptoPlugin())
|
||||
// 注册默认的AES加解密策略
|
||||
//crypto.RegisterCryptoStrategy(strategy.NewAesCryptoStrategy("3Y)(27EtO^tK8Bj~"))
|
||||
// Migrate the schema
|
||||
//统计处理
|
||||
db.AutoMigrate(&innerbean.WebLog{})
|
||||
db.AutoMigrate(&model.AccountLog{})
|
||||
db.AutoMigrate(&model.WafSysLog{})
|
||||
db.AutoMigrate(&model.OneKeyMod{})
|
||||
|
||||
// ============ 使用 gormigrate 替代 AutoMigrate(完全向后兼容) ============
|
||||
zlog.Info("开始执行手动log数据库迁移...", "file", custFileName)
|
||||
if err := RunLogDBMigrations(db); err != nil {
|
||||
zlog.Error("手动log数据库迁移失败", "file", custFileName, "error", err)
|
||||
panic("manual log database migration failed: " + err.Error())
|
||||
}
|
||||
// ============ 迁移代码结束 ============
|
||||
|
||||
global.GDATA_CURRENT_LOG_DB_MAP[custFileName].Callback().Query().Before("gorm:query").Register("tenant_plugin:before_query", before_query)
|
||||
global.GDATA_CURRENT_LOG_DB_MAP[custFileName].Callback().Query().Before("gorm:update").Register("tenant_plugin:before_update", before_update)
|
||||
|
||||
@@ -0,0 +1,279 @@
|
||||
package wafdb
|
||||
|
||||
import (
|
||||
"SamWaf/common/zlog"
|
||||
"SamWaf/model"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/go-gormigrate/gormigrate/v2"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// RunCoreDBMigrations 执行主数据库迁移(完全兼容老用户)
|
||||
func RunCoreDBMigrations(db *gorm.DB) error {
|
||||
zlog.Info("开始执行core数据库迁移检查...")
|
||||
|
||||
// 检测表和索引的存在情况
|
||||
tablesExist := checkCoreTablesExist(db)
|
||||
indexesExist := checkCoreIndexesExist(db)
|
||||
|
||||
zlog.Info("数据库状态检测",
|
||||
"表是否存在", tablesExist,
|
||||
"索引是否完整", indexesExist)
|
||||
|
||||
m := gormigrate.New(db, gormigrate.DefaultOptions, []*gormigrate.Migration{
|
||||
// 迁移1: 创建表(如果不存在)
|
||||
{
|
||||
ID: "202511140001_initial_core_tables",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
if tablesExist {
|
||||
zlog.Info("迁移 202511140001: 表已存在,执行结构同步")
|
||||
// 表已存在,只做结构同步(安全操作,不会删除字段/数据)
|
||||
if err := tx.AutoMigrate(
|
||||
&model.Hosts{},
|
||||
&model.Rules{},
|
||||
&model.LDPUrl{},
|
||||
&model.IPAllowList{},
|
||||
&model.URLAllowList{},
|
||||
&model.IPBlockList{},
|
||||
&model.URLBlockList{},
|
||||
&model.AntiCC{},
|
||||
&model.TokenInfo{},
|
||||
&model.Account{},
|
||||
&model.SystemConfig{},
|
||||
&model.DelayMsg{},
|
||||
&model.ShareDb{},
|
||||
&model.Center{},
|
||||
&model.Sensitive{},
|
||||
&model.LoadBalance{},
|
||||
&model.SslConfig{},
|
||||
&model.IPTag{},
|
||||
&model.BatchTask{},
|
||||
&model.SslOrder{},
|
||||
&model.SslExpire{},
|
||||
&model.HttpAuthBase{},
|
||||
&model.Task{},
|
||||
&model.BlockingPage{},
|
||||
&model.Otp{},
|
||||
&model.PrivateInfo{},
|
||||
&model.PrivateGroup{},
|
||||
&model.CacheRule{},
|
||||
&model.Tunnel{},
|
||||
&model.CaServerInfo{},
|
||||
); err != nil {
|
||||
return fmt.Errorf("同步表结构失败: %w", err)
|
||||
}
|
||||
zlog.Info("表结构同步成功(数据完整保留)")
|
||||
} else {
|
||||
zlog.Info("迁移 202511140001: 创建新表")
|
||||
// 表不存在,创建所有表
|
||||
if err := tx.AutoMigrate(
|
||||
&model.Hosts{},
|
||||
&model.Rules{},
|
||||
&model.LDPUrl{},
|
||||
&model.IPAllowList{},
|
||||
&model.URLAllowList{},
|
||||
&model.IPBlockList{},
|
||||
&model.URLBlockList{},
|
||||
&model.AntiCC{},
|
||||
&model.TokenInfo{},
|
||||
&model.Account{},
|
||||
&model.SystemConfig{},
|
||||
&model.DelayMsg{},
|
||||
&model.ShareDb{},
|
||||
&model.Center{},
|
||||
&model.Sensitive{},
|
||||
&model.LoadBalance{},
|
||||
&model.SslConfig{},
|
||||
&model.IPTag{},
|
||||
&model.BatchTask{},
|
||||
&model.SslOrder{},
|
||||
&model.SslExpire{},
|
||||
&model.HttpAuthBase{},
|
||||
&model.Task{},
|
||||
&model.BlockingPage{},
|
||||
&model.Otp{},
|
||||
&model.PrivateInfo{},
|
||||
&model.PrivateGroup{},
|
||||
&model.CacheRule{},
|
||||
&model.Tunnel{},
|
||||
&model.CaServerInfo{},
|
||||
); err != nil {
|
||||
return fmt.Errorf("创建core表失败: %w", err)
|
||||
}
|
||||
zlog.Info("core表创建成功")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
Rollback: func(tx *gorm.DB) error {
|
||||
if tablesExist {
|
||||
// 如果是老数据库,不执行删除操作(保护数据)
|
||||
zlog.Info("回滚 202511140001: 检测到已存在数据,跳过表删除(保护用户数据)")
|
||||
return nil
|
||||
}
|
||||
// 新数据库可以安全删除
|
||||
zlog.Info("回滚 202511140001: 删除表")
|
||||
return tx.Migrator().DropTable(
|
||||
&model.Hosts{},
|
||||
&model.Rules{},
|
||||
&model.LDPUrl{},
|
||||
&model.IPAllowList{},
|
||||
&model.URLAllowList{},
|
||||
&model.IPBlockList{},
|
||||
&model.URLBlockList{},
|
||||
&model.AntiCC{},
|
||||
&model.TokenInfo{},
|
||||
&model.Account{},
|
||||
&model.SystemConfig{},
|
||||
&model.DelayMsg{},
|
||||
&model.ShareDb{},
|
||||
&model.Center{},
|
||||
&model.Sensitive{},
|
||||
&model.LoadBalance{},
|
||||
&model.SslConfig{},
|
||||
&model.IPTag{},
|
||||
&model.BatchTask{},
|
||||
&model.SslOrder{},
|
||||
&model.SslExpire{},
|
||||
&model.HttpAuthBase{},
|
||||
&model.Task{},
|
||||
&model.BlockingPage{},
|
||||
&model.Otp{},
|
||||
&model.PrivateInfo{},
|
||||
&model.PrivateGroup{},
|
||||
&model.CacheRule{},
|
||||
&model.Tunnel{},
|
||||
&model.CaServerInfo{},
|
||||
)
|
||||
},
|
||||
},
|
||||
// 迁移2: 创建索引(幂等操作)
|
||||
{
|
||||
ID: "202511140002_create_core_indexes",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
if indexesExist {
|
||||
zlog.Info("迁移 202511140002: 索引已完整,跳过创建")
|
||||
return nil
|
||||
}
|
||||
zlog.Info("迁移 202511140002: 开始创建索引")
|
||||
return createCoreIndexes(tx)
|
||||
},
|
||||
Rollback: func(tx *gorm.DB) error {
|
||||
zlog.Info("回滚 202511140002: 删除索引")
|
||||
return dropCoreIndexes(tx)
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// 执行迁移
|
||||
if err := m.Migrate(); err != nil {
|
||||
return fmt.Errorf("core数据库迁移失败: %w", err)
|
||||
}
|
||||
|
||||
zlog.Info("core数据库迁移成功完成")
|
||||
return nil
|
||||
}
|
||||
|
||||
// checkCoreTablesExist 检查核心表是否存在(检查几个关键表)
|
||||
func checkCoreTablesExist(db *gorm.DB) bool {
|
||||
// 检查几个关键表,如果都存在则认为是老数据库
|
||||
keyTables := []interface{}{
|
||||
&model.Hosts{},
|
||||
&model.Rules{},
|
||||
&model.Account{},
|
||||
&model.SystemConfig{},
|
||||
}
|
||||
|
||||
for _, table := range keyTables {
|
||||
if !db.Migrator().HasTable(table) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// checkCoreIndexesExist 检查所有core索引是否存在
|
||||
func checkCoreIndexesExist(db *gorm.DB) bool {
|
||||
// 需要检查的索引列表(表名, 索引名)
|
||||
indexes := []struct {
|
||||
TableName string
|
||||
IndexName string
|
||||
}{
|
||||
{"ip_tags", "uni_iptags_full"},
|
||||
{"ip_tags", "idx_iptag_ip"},
|
||||
}
|
||||
|
||||
for _, idx := range indexes {
|
||||
if !checkIndexExists(db, idx.TableName, idx.IndexName) {
|
||||
zlog.Info("索引不存在", "table", idx.TableName, "index", idx.IndexName)
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// createCoreIndexes 创建所有core索引(幂等操作)
|
||||
func createCoreIndexes(tx *gorm.DB) error {
|
||||
zlog.Info("开始创建core索引...")
|
||||
startTime := time.Now()
|
||||
|
||||
indexes := []struct {
|
||||
Name string
|
||||
SQL string
|
||||
}{
|
||||
{
|
||||
Name: "uni_iptags_full",
|
||||
SQL: "CREATE UNIQUE INDEX IF NOT EXISTS uni_iptags_full ON ip_tags (user_code, tenant_id, ip, ip_tag)",
|
||||
},
|
||||
{
|
||||
Name: "idx_iptag_ip",
|
||||
SQL: "CREATE INDEX IF NOT EXISTS idx_iptag_ip ON ip_tags (user_code, tenant_id, ip)",
|
||||
},
|
||||
}
|
||||
|
||||
for _, idx := range indexes {
|
||||
if err := tx.Exec(idx.SQL).Error; err != nil {
|
||||
return fmt.Errorf("创建索引失败 %s: %w", idx.Name, err)
|
||||
}
|
||||
zlog.Info("索引创建成功", "index", idx.Name)
|
||||
}
|
||||
|
||||
duration := time.Since(startTime)
|
||||
zlog.Info("所有core索引创建完成", "耗时", duration.String())
|
||||
return nil
|
||||
}
|
||||
|
||||
// dropCoreIndexes 删除所有core索引
|
||||
func dropCoreIndexes(tx *gorm.DB) error {
|
||||
zlog.Info("开始删除core索引")
|
||||
|
||||
indexes := []string{
|
||||
"uni_iptags_full",
|
||||
"idx_iptag_ip",
|
||||
}
|
||||
|
||||
for _, indexName := range indexes {
|
||||
if err := tx.Exec(fmt.Sprintf("DROP INDEX IF EXISTS %s", indexName)).Error; err != nil {
|
||||
zlog.Warn("删除索引失败(可能不存在)", "index", indexName, "error", err)
|
||||
} else {
|
||||
zlog.Info("索引删除成功", "index", indexName)
|
||||
}
|
||||
}
|
||||
|
||||
zlog.Info("所有core索引删除完成")
|
||||
return nil
|
||||
}
|
||||
|
||||
// RollbackCoreDBMigration 回滚到指定版本
|
||||
func RollbackCoreDBMigration(db *gorm.DB, migrationID string) error {
|
||||
zlog.Info("准备回滚core迁移", "target_version", migrationID)
|
||||
|
||||
m := gormigrate.New(db, gormigrate.DefaultOptions, []*gormigrate.Migration{})
|
||||
if err := m.RollbackTo(migrationID); err != nil {
|
||||
return fmt.Errorf("回滚失败: %w", err)
|
||||
}
|
||||
|
||||
zlog.Info("回滚成功完成", "version", migrationID)
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,231 @@
|
||||
package wafdb
|
||||
|
||||
import (
|
||||
"SamWaf/common/zlog"
|
||||
"SamWaf/innerbean"
|
||||
"SamWaf/model"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/go-gormigrate/gormigrate/v2"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// RunLogDBMigrations 执行日志数据库迁移(完全兼容老用户)
|
||||
func RunLogDBMigrations(db *gorm.DB) error {
|
||||
zlog.Info("开始执行log数据库迁移检查...")
|
||||
|
||||
// 检测表和索引的存在情况
|
||||
tablesExist := checkLogTablesExist(db)
|
||||
indexesExist := checkLogIndexesExist(db)
|
||||
|
||||
zlog.Info("数据库状态检测",
|
||||
"表是否存在", tablesExist,
|
||||
"索引是否完整", indexesExist)
|
||||
|
||||
m := gormigrate.New(db, gormigrate.DefaultOptions, []*gormigrate.Migration{
|
||||
// 迁移1: 创建表(如果不存在)
|
||||
{
|
||||
ID: "202511140001_initial_log_tables",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
if tablesExist {
|
||||
zlog.Info("迁移 202511140001: 表已存在,执行结构同步")
|
||||
// 表已存在,只做结构同步(安全操作,不会删除字段/数据)
|
||||
if err := tx.AutoMigrate(
|
||||
&innerbean.WebLog{},
|
||||
&model.AccountLog{},
|
||||
&model.WafSysLog{},
|
||||
&model.OneKeyMod{},
|
||||
); err != nil {
|
||||
return fmt.Errorf("同步表结构失败: %w", err)
|
||||
}
|
||||
zlog.Info("表结构同步成功(数据完整保留)")
|
||||
} else {
|
||||
zlog.Info("迁移 202511140001: 创建新表")
|
||||
// 表不存在,创建所有表
|
||||
if err := tx.AutoMigrate(
|
||||
&innerbean.WebLog{},
|
||||
&model.AccountLog{},
|
||||
&model.WafSysLog{},
|
||||
&model.OneKeyMod{},
|
||||
); err != nil {
|
||||
return fmt.Errorf("创建log表失败: %w", err)
|
||||
}
|
||||
zlog.Info("log表创建成功")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
Rollback: func(tx *gorm.DB) error {
|
||||
if tablesExist {
|
||||
// 如果是老数据库,不执行删除操作(保护数据)
|
||||
zlog.Info("回滚 202511140001: 检测到已存在数据,跳过表删除(保护用户数据)")
|
||||
return nil
|
||||
}
|
||||
// 新数据库可以安全删除
|
||||
zlog.Info("回滚 202511140001: 删除表")
|
||||
return tx.Migrator().DropTable(
|
||||
&innerbean.WebLog{},
|
||||
&model.AccountLog{},
|
||||
&model.WafSysLog{},
|
||||
&model.OneKeyMod{},
|
||||
)
|
||||
},
|
||||
},
|
||||
// 迁移2: 创建索引(幂等操作)
|
||||
{
|
||||
ID: "202511140002_create_log_indexes",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
if indexesExist {
|
||||
zlog.Info("迁移 202511140002: 索引已完整,跳过创建")
|
||||
return nil
|
||||
}
|
||||
zlog.Info("迁移 202511140002: 开始创建索引")
|
||||
return createLogIndexes(tx)
|
||||
},
|
||||
Rollback: func(tx *gorm.DB) error {
|
||||
zlog.Info("回滚 202511140002: 删除索引")
|
||||
return dropLogIndexes(tx)
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// 执行迁移
|
||||
if err := m.Migrate(); err != nil {
|
||||
return fmt.Errorf("log数据库迁移失败: %w", err)
|
||||
}
|
||||
|
||||
zlog.Info("log数据库迁移成功完成")
|
||||
return nil
|
||||
}
|
||||
|
||||
// checkLogTablesExist 检查所有log表是否存在
|
||||
func checkLogTablesExist(db *gorm.DB) bool {
|
||||
tables := []interface{}{
|
||||
&innerbean.WebLog{},
|
||||
&model.AccountLog{},
|
||||
&model.WafSysLog{},
|
||||
&model.OneKeyMod{},
|
||||
}
|
||||
|
||||
for _, table := range tables {
|
||||
if !db.Migrator().HasTable(table) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// checkLogIndexesExist 检查所有log索引是否存在
|
||||
func checkLogIndexesExist(db *gorm.DB) bool {
|
||||
// 需要检查的索引列表(表名, 索引名)
|
||||
indexes := []struct {
|
||||
TableName string
|
||||
IndexName string
|
||||
}{
|
||||
{"web_logs", "idx_web_logs_task_flag_time"},
|
||||
{"web_logs", "idx_web_time_tenant_user_code"},
|
||||
{"web_logs", "idx_req_uuid_web_logs"},
|
||||
{"web_logs", "idx_tenant_usercode_web_logs"},
|
||||
{"web_logs", "idx_web_time_desc_tenant_user_code"},
|
||||
{"web_logs", "idx_web_time_desc_tenant_user_code_ip"},
|
||||
{"web_logs", "idx_web_guest_id_entification"},
|
||||
}
|
||||
|
||||
for _, idx := range indexes {
|
||||
if !checkIndexExists(db, idx.TableName, idx.IndexName) {
|
||||
zlog.Info("索引不存在", "table", idx.TableName, "index", idx.IndexName)
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// createLogIndexes 创建所有log索引(幂等操作)
|
||||
func createLogIndexes(tx *gorm.DB) error {
|
||||
zlog.Info("开始创建log索引(可能需要几分钟)...")
|
||||
startTime := time.Now()
|
||||
|
||||
indexes := []struct {
|
||||
Name string
|
||||
SQL string
|
||||
}{
|
||||
{
|
||||
Name: "idx_web_logs_task_flag_time",
|
||||
SQL: "CREATE INDEX IF NOT EXISTS idx_web_logs_task_flag_time ON web_logs (task_flag, unix_add_time)",
|
||||
},
|
||||
{
|
||||
Name: "idx_web_time_tenant_user_code",
|
||||
SQL: "CREATE INDEX IF NOT EXISTS idx_web_time_tenant_user_code ON web_logs (unix_add_time, tenant_id, user_code)",
|
||||
},
|
||||
{
|
||||
Name: "idx_req_uuid_web_logs",
|
||||
SQL: "CREATE INDEX IF NOT EXISTS idx_req_uuid_web_logs ON web_logs (REQ_UUID, tenant_id, user_code)",
|
||||
},
|
||||
{
|
||||
Name: "idx_tenant_usercode_web_logs",
|
||||
SQL: "CREATE INDEX IF NOT EXISTS idx_tenant_usercode_web_logs ON web_logs (tenant_id, user_code)",
|
||||
},
|
||||
{
|
||||
Name: "idx_web_time_desc_tenant_user_code",
|
||||
SQL: "CREATE INDEX IF NOT EXISTS idx_web_time_desc_tenant_user_code ON web_logs (unix_add_time desc, tenant_id, user_code)",
|
||||
},
|
||||
{
|
||||
Name: "idx_web_time_desc_tenant_user_code_ip",
|
||||
SQL: "CREATE INDEX IF NOT EXISTS idx_web_time_desc_tenant_user_code_ip ON web_logs (unix_add_time desc, tenant_id, user_code, src_ip)",
|
||||
},
|
||||
{
|
||||
Name: "idx_web_guest_id_entification",
|
||||
SQL: "CREATE INDEX IF NOT EXISTS idx_web_guest_id_entification ON web_logs (guest_id_entification, day, is_bot, host_code)",
|
||||
},
|
||||
}
|
||||
|
||||
for _, idx := range indexes {
|
||||
if err := tx.Exec(idx.SQL).Error; err != nil {
|
||||
return fmt.Errorf("创建索引失败 %s: %w", idx.Name, err)
|
||||
}
|
||||
zlog.Info("索引创建成功", "index", idx.Name)
|
||||
}
|
||||
|
||||
duration := time.Since(startTime)
|
||||
zlog.Info("所有log索引创建完成", "耗时", duration.String())
|
||||
return nil
|
||||
}
|
||||
|
||||
// dropLogIndexes 删除所有log索引
|
||||
func dropLogIndexes(tx *gorm.DB) error {
|
||||
zlog.Info("开始删除log索引")
|
||||
|
||||
indexes := []string{
|
||||
"idx_web_logs_task_flag_time",
|
||||
"idx_web_time_tenant_user_code",
|
||||
"idx_req_uuid_web_logs",
|
||||
"idx_tenant_usercode_web_logs",
|
||||
"idx_web_time_desc_tenant_user_code",
|
||||
"idx_web_time_desc_tenant_user_code_ip",
|
||||
"idx_web_guest_id_entification",
|
||||
}
|
||||
|
||||
for _, indexName := range indexes {
|
||||
if err := tx.Exec(fmt.Sprintf("DROP INDEX IF EXISTS %s", indexName)).Error; err != nil {
|
||||
zlog.Warn("删除索引失败(可能不存在)", "index", indexName, "error", err)
|
||||
} else {
|
||||
zlog.Info("索引删除成功", "index", indexName)
|
||||
}
|
||||
}
|
||||
|
||||
zlog.Info("所有log索引删除完成")
|
||||
return nil
|
||||
}
|
||||
|
||||
// RollbackLogDBMigration 回滚到指定版本
|
||||
func RollbackLogDBMigration(db *gorm.DB, migrationID string) error {
|
||||
zlog.Info("准备回滚log迁移", "target_version", migrationID)
|
||||
|
||||
m := gormigrate.New(db, gormigrate.DefaultOptions, []*gormigrate.Migration{})
|
||||
if err := m.RollbackTo(migrationID); err != nil {
|
||||
return fmt.Errorf("回滚失败: %w", err)
|
||||
}
|
||||
|
||||
zlog.Info("回滚成功完成", "version", migrationID)
|
||||
return nil
|
||||
}
|
||||
+10
-87
@@ -3,8 +3,6 @@ package waftask
|
||||
import (
|
||||
"SamWaf/common/zlog"
|
||||
"SamWaf/enums"
|
||||
"SamWaf/global"
|
||||
"time"
|
||||
)
|
||||
|
||||
// TaskCreateIndex 创建索引
|
||||
@@ -37,95 +35,20 @@ func TaskCreateIndexByDbName(dbName string) {
|
||||
}
|
||||
|
||||
func createMainDbIndex() {
|
||||
db := global.GWAF_LOCAL_DB
|
||||
if db == nil {
|
||||
return
|
||||
}
|
||||
startTime := time.Now()
|
||||
// ============ 已废弃:索引创建已迁移到 gormigrate ============
|
||||
// 从 2025-11-14 开始,core 数据库索引通过 gormigrate 在数据库初始化时自动创建
|
||||
// ============================================================
|
||||
|
||||
zlog.Info("ready create core index maybe use a few minutes ")
|
||||
|
||||
//20241106 创建iptagtag索引
|
||||
err := db.Exec("CREATE UNIQUE INDEX IF NOT EXISTS uni_iptags_full ON ip_tags (user_code, tenant_id, ip, ip_tag)").Error
|
||||
if err != nil {
|
||||
panic("failed to create index : uni_iptags_full " + err.Error())
|
||||
} else {
|
||||
zlog.Info("db", "uni_iptags_full created")
|
||||
}
|
||||
// 创建iptag ip索引
|
||||
err = db.Exec("CREATE INDEX IF NOT EXISTS idx_iptag_ip ON ip_tags ( user_code, tenant_id, ip)").Error
|
||||
if err != nil {
|
||||
panic("failed to create index: idx_iptag_ip " + err.Error())
|
||||
} else {
|
||||
zlog.Info("db", "idx_iptag_ip created")
|
||||
}
|
||||
// 记录结束时间并计算耗时
|
||||
duration := time.Since(startTime)
|
||||
zlog.Info("create core index completely", "duration", duration.String())
|
||||
zlog.Info("createMainDbIndex 已废弃,索引由 gormigrate 自动管理")
|
||||
return
|
||||
}
|
||||
func createLogDbIndex() {
|
||||
db := global.GWAF_LOCAL_LOG_DB
|
||||
if db == nil {
|
||||
return
|
||||
}
|
||||
// 20241018 创建联合索引 weblog
|
||||
startTime := time.Now()
|
||||
// ============ 已废弃:索引创建已迁移到 gormigrate ============
|
||||
// 从 2025-11-14 开始,log 数据库索引通过 gormigrate 在数据库初始化时自动创建
|
||||
// ============================================================
|
||||
|
||||
zlog.Info("ready create log index maybe use a few minutes ")
|
||||
err := db.Exec("CREATE INDEX IF NOT EXISTS idx_web_logs_task_flag_time ON web_logs (task_flag, unix_add_time)").Error
|
||||
if err != nil {
|
||||
panic("failed to create index: idx_web_logs_task_flag_time " + err.Error())
|
||||
} else {
|
||||
zlog.Info("db", "idx_web_logs_task_flag_time created")
|
||||
}
|
||||
// 创建联合索引
|
||||
err = db.Exec("CREATE INDEX IF NOT EXISTS idx_web_time_tenant_user_code ON web_logs (unix_add_time, tenant_id,user_code)").Error
|
||||
if err != nil {
|
||||
panic("failed to create index: idx_web_time_tenant_user_code " + err.Error())
|
||||
} else {
|
||||
zlog.Info("db", "idx_web_time_tenant_user_code created")
|
||||
}
|
||||
// 详情索引
|
||||
err = db.Exec("CREATE INDEX IF NOT EXISTS idx_req_uuid_web_logs ON web_logs (REQ_UUID, tenant_id, user_code)").Error
|
||||
if err != nil {
|
||||
panic("failed to create index:idx_req_uuid_web_logs " + err.Error())
|
||||
} else {
|
||||
zlog.Info("db", "idx_unique_req_uuid_web_logs created")
|
||||
}
|
||||
// 整体索引
|
||||
err = db.Exec("CREATE INDEX IF NOT EXISTS idx_tenant_usercode_web_logs ON web_logs ( tenant_id, user_code)").Error
|
||||
if err != nil {
|
||||
panic("failed to create index: idx_tenant_usercode_web_logs " + err.Error())
|
||||
} else {
|
||||
zlog.Info("db", "idx_tenant_usercode_web_logs created")
|
||||
}
|
||||
|
||||
// 20250123 创建联合索引
|
||||
err = db.Exec("CREATE INDEX IF NOT EXISTS idx_web_time_desc_tenant_user_code ON web_logs (unix_add_time desc, tenant_id,user_code)").Error
|
||||
if err != nil {
|
||||
panic("failed to create index: idx_web_time_desc_tenant_user_code " + err.Error())
|
||||
} else {
|
||||
zlog.Info("db", "idx_web_time_desc_tenant_user_code created")
|
||||
}
|
||||
//20250123 建立带IP得
|
||||
err = db.Exec("CREATE INDEX IF NOT EXISTS idx_web_time_desc_tenant_user_code_ip ON web_logs (unix_add_time desc, tenant_id,user_code,src_ip)").Error
|
||||
if err != nil {
|
||||
panic("failed to create index: idx_web_time_desc_tenant_user_code_ip " + err.Error())
|
||||
} else {
|
||||
zlog.Info("db", "idx_web_time_desc_tenant_user_code_ip created")
|
||||
}
|
||||
|
||||
// 2025-05-02 添加新索引:为guest_id_entification字段创建索引,优化机器人识别查询
|
||||
err = db.Exec("CREATE INDEX IF NOT EXISTS idx_web_guest_id_entification ON web_logs (guest_id_entification, day, is_bot, host_code)").Error
|
||||
if err != nil {
|
||||
panic("failed to create index: idx_web_guest_id_entification " + err.Error())
|
||||
} else {
|
||||
zlog.Info("db", "idx_web_guest_id_entification created")
|
||||
}
|
||||
|
||||
// 记录结束时间并计算耗时
|
||||
duration := time.Since(startTime)
|
||||
zlog.Info("create log index completely", "duration", duration.String())
|
||||
zlog.Info("createLogDbIndex 已废弃,索引由 gormigrate 自动管理")
|
||||
return
|
||||
}
|
||||
func createStatDbIndex() {
|
||||
// ============ 已废弃:索引创建已迁移到 gormigrate ============
|
||||
|
||||
Reference in New Issue
Block a user