修复访问日志表可能无法自动创建的Bug

This commit is contained in:
GoEdgeLab
2022-03-23 10:05:42 +08:00
parent 26f22a39c9
commit b4d0f49802
4 changed files with 46 additions and 12 deletions

View File

@@ -220,10 +220,26 @@ func (this *HTTPAccessLogDAO) CreateHTTPAccessLog(tx *dbs.Tx, dao *HTTPAccessLog
Table(tableDef.Name). Table(tableDef.Name).
Sets(fields). Sets(fields).
Insert() Insert()
if err != nil {
// 错误重试
if CheckSQLErrCode(err, 1146) { // Error 1146: Table 'xxx' doesn't exist
err = SharedHTTPAccessLogManager.CreateTable(dao.Instance, tableDef.Name)
if err != nil { if err != nil {
return err return err
} }
// 重新尝试
lastId, err = dao.Query(tx).
Table(tableDef.Name).
Sets(fields).
Insert()
}
if err != nil {
return err
}
}
if accessLogEnableAutoPartial && accessLogRowsPerTable > 0 && lastId%accessLogRowsPerTable == 0 { if accessLogEnableAutoPartial && accessLogRowsPerTable > 0 && lastId%accessLogRowsPerTable == 0 {
SharedHTTPAccessLogManager.ResetTable(dao.Instance, day) SharedHTTPAccessLogManager.ResetTable(dao.Instance, day)
} }

View File

@@ -5,7 +5,6 @@ package models
import ( import (
"fmt" "fmt"
"github.com/TeaOSLab/EdgeAPI/internal/errors" "github.com/TeaOSLab/EdgeAPI/internal/errors"
"github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/dbs" "github.com/iwind/TeaGo/dbs"
"github.com/iwind/TeaGo/lists" "github.com/iwind/TeaGo/lists"
"github.com/iwind/TeaGo/types" "github.com/iwind/TeaGo/types"
@@ -144,7 +143,10 @@ func (this *HTTPAccessLogManager) FindTable(db *dbs.DB, day string, force bool)
return nil, err return nil, err
} }
// 只有存在的表格才缓存
if def != nil && def.Exists {
this.currentTableMapping[cacheKey] = def this.currentTableMapping[cacheKey] = def
}
return def, nil return def, nil
} }
@@ -152,14 +154,7 @@ func (this *HTTPAccessLogManager) FindTable(db *dbs.DB, day string, force bool)
func (this *HTTPAccessLogManager) CreateTable(db *dbs.DB, tableName string) error { func (this *HTTPAccessLogManager) CreateTable(db *dbs.DB, tableName string) error {
_, err := db.Exec("CREATE TABLE `" + tableName + "` (\n `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',\n `serverId` int(11) unsigned DEFAULT '0' COMMENT '服务ID',\n `nodeId` int(11) unsigned DEFAULT '0' COMMENT '节点ID',\n `status` int(3) unsigned DEFAULT '0' COMMENT '状态码',\n `createdAt` bigint(11) unsigned DEFAULT '0' COMMENT '创建时间',\n `content` json DEFAULT NULL COMMENT '日志内容',\n `requestId` varchar(128) DEFAULT NULL COMMENT '请求ID',\n `firewallPolicyId` int(11) unsigned DEFAULT '0' COMMENT 'WAF策略ID',\n `firewallRuleGroupId` int(11) unsigned DEFAULT '0' COMMENT 'WAF分组ID',\n `firewallRuleSetId` int(11) unsigned DEFAULT '0' COMMENT 'WAF集ID',\n `firewallRuleId` int(11) unsigned DEFAULT '0' COMMENT 'WAF规则ID',\n `remoteAddr` varchar(64) DEFAULT NULL COMMENT 'IP地址',\n `domain` varchar(128) DEFAULT NULL COMMENT '域名',\n `requestBody` mediumblob COMMENT '请求内容',\n `responseBody` mediumblob COMMENT '响应内容',\n PRIMARY KEY (`id`),\n KEY `serverId` (`serverId`),\n KEY `nodeId` (`nodeId`),\n KEY `serverId_status` (`serverId`,`status`),\n KEY `requestId` (`requestId`),\n KEY `firewallPolicyId` (`firewallPolicyId`),\n KEY `firewallRuleGroupId` (`firewallRuleGroupId`),\n KEY `firewallRuleSetId` (`firewallRuleSetId`),\n KEY `firewallRuleId` (`firewallRuleId`),\n KEY `remoteAddr` (`remoteAddr`),\n KEY `domain` (`domain`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='访问日志';") _, err := db.Exec("CREATE TABLE `" + tableName + "` (\n `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',\n `serverId` int(11) unsigned DEFAULT '0' COMMENT '服务ID',\n `nodeId` int(11) unsigned DEFAULT '0' COMMENT '节点ID',\n `status` int(3) unsigned DEFAULT '0' COMMENT '状态码',\n `createdAt` bigint(11) unsigned DEFAULT '0' COMMENT '创建时间',\n `content` json DEFAULT NULL COMMENT '日志内容',\n `requestId` varchar(128) DEFAULT NULL COMMENT '请求ID',\n `firewallPolicyId` int(11) unsigned DEFAULT '0' COMMENT 'WAF策略ID',\n `firewallRuleGroupId` int(11) unsigned DEFAULT '0' COMMENT 'WAF分组ID',\n `firewallRuleSetId` int(11) unsigned DEFAULT '0' COMMENT 'WAF集ID',\n `firewallRuleId` int(11) unsigned DEFAULT '0' COMMENT 'WAF规则ID',\n `remoteAddr` varchar(64) DEFAULT NULL COMMENT 'IP地址',\n `domain` varchar(128) DEFAULT NULL COMMENT '域名',\n `requestBody` mediumblob COMMENT '请求内容',\n `responseBody` mediumblob COMMENT '响应内容',\n PRIMARY KEY (`id`),\n KEY `serverId` (`serverId`),\n KEY `nodeId` (`nodeId`),\n KEY `serverId_status` (`serverId`,`status`),\n KEY `requestId` (`requestId`),\n KEY `firewallPolicyId` (`firewallPolicyId`),\n KEY `firewallRuleGroupId` (`firewallRuleGroupId`),\n KEY `firewallRuleSetId` (`firewallRuleSetId`),\n KEY `firewallRuleId` (`firewallRuleId`),\n KEY `remoteAddr` (`remoteAddr`),\n KEY `domain` (`domain`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='访问日志';")
if err != nil { if err != nil {
// 快速判断错误方法 if CheckSQLErrCode(err, 1050) { // Error 1050: Table 'xxx' already exists
mysqlErr, ok := err.(*mysql.MySQLError)
if ok && mysqlErr.Number == 1050 { // Error 1050: Table 'xxx' already exists
return nil
}
// 防止二次包装过程中错误丢失的保底错误判断方法
if strings.Contains(err.Error(), "Error 1050") {
return nil return nil
} }

View File

@@ -1,7 +1,10 @@
package models package models
import ( import (
"github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/dbs" "github.com/iwind/TeaGo/dbs"
"github.com/iwind/TeaGo/types"
"strings"
"sync" "sync"
) )
@@ -38,3 +41,23 @@ func NewQuery(tx *dbs.Tx, dao dbs.DAOWrapper, adminId int64, userId int64) *dbs.
} }
return query return query
} }
// CheckSQLErrCode 检查数据库错误代码
func CheckSQLErrCode(err error, code uint16) bool {
if err == nil {
return false
}
// 快速判断错误方法
mysqlErr, ok := err.(*mysql.MySQLError)
if ok && mysqlErr.Number == code { // Error 1050: Table 'xxx' already exists
return true
}
// 防止二次包装过程中错误丢失的保底错误判断方法
if strings.Contains(err.Error(), "Error "+types.String(code)) {
return true
}
return false
}

File diff suppressed because one or more lines are too long