mirror of
https://github.com/TeaOSLab/EdgeAPI.git
synced 2025-11-07 10:40:25 +08:00
自动检测本地数据库磁盘是否已满,如果已满,则不再写入访问日志
This commit is contained in:
@@ -2,6 +2,7 @@ package models
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
dbutils "github.com/TeaOSLab/EdgeAPI/internal/db/utils"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/goman"
|
"github.com/TeaOSLab/EdgeAPI/internal/goman"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||||
@@ -31,6 +32,7 @@ var httpAccessLogDAOMapping = map[int64]*HTTPAccessLogDAOWrapper{} // dbNodeId =
|
|||||||
type HTTPAccessLogDAOWrapper struct {
|
type HTTPAccessLogDAOWrapper struct {
|
||||||
DAO *HTTPAccessLogDAO
|
DAO *HTTPAccessLogDAO
|
||||||
NodeId int64
|
NodeId int64
|
||||||
|
IsLocal bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@@ -195,7 +197,7 @@ func (this *DBNodeInitializer) loop() error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
daoObject := dbs.DAOObject{
|
var daoObject = dbs.DAOObject{
|
||||||
Instance: db,
|
Instance: db,
|
||||||
DB: node.Name + "(id:" + strconv.Itoa(int(node.Id)) + ")",
|
DB: node.Name + "(id:" + strconv.Itoa(int(node.Id)) + ")",
|
||||||
Table: tableDef.Name,
|
Table: tableDef.Name,
|
||||||
@@ -210,12 +212,13 @@ func (this *DBNodeInitializer) loop() error {
|
|||||||
|
|
||||||
accessLogLocker.Lock()
|
accessLogLocker.Lock()
|
||||||
accessLogDBMapping[nodeId] = db
|
accessLogDBMapping[nodeId] = db
|
||||||
dao := &HTTPAccessLogDAO{
|
var dao = &HTTPAccessLogDAO{
|
||||||
DAOObject: daoObject,
|
DAOObject: daoObject,
|
||||||
}
|
}
|
||||||
httpAccessLogDAOMapping[nodeId] = &HTTPAccessLogDAOWrapper{
|
httpAccessLogDAOMapping[nodeId] = &HTTPAccessLogDAOWrapper{
|
||||||
DAO: dao,
|
DAO: dao,
|
||||||
NodeId: nodeId,
|
NodeId: nodeId,
|
||||||
|
IsLocal: dbutils.IsLocalAddr(node.Host),
|
||||||
}
|
}
|
||||||
accessLogLocker.Unlock()
|
accessLogLocker.Unlock()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -161,16 +161,27 @@ func (this *HTTPAccessLogDAO) DumpAccessLogsFromQueue(size int) (hasMore bool, e
|
|||||||
size = 100
|
size = 100
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(oldAccessLogQueue) == 0 && len(accessLogQueue) == 0 {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
var dao = randomHTTPAccessLogDAO()
|
var dao = randomHTTPAccessLogDAO()
|
||||||
if dao == nil {
|
if dao == nil {
|
||||||
dao = &HTTPAccessLogDAOWrapper{
|
dao = &HTTPAccessLogDAOWrapper{
|
||||||
DAO: SharedHTTPAccessLogDAO,
|
DAO: SharedHTTPAccessLogDAO,
|
||||||
NodeId: 0,
|
NodeId: 0,
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if len(oldAccessLogQueue) == 0 && len(accessLogQueue) == 0 {
|
// 检查本地数据库空间
|
||||||
return false, nil
|
if dbutils.IsLocalDatabase && !dbutils.HasFreeSpace {
|
||||||
|
return false, errors.New("dump accesslog failed: there is no enough space left for database (" + dbutils.LocalDatabaseDataDir + ")")
|
||||||
|
}
|
||||||
|
} else if dao.IsLocal {
|
||||||
|
// 检查本地数据库空间
|
||||||
|
// 我们假定本地只能安装一个数据库,访问日志中的数据库和当前API连接的数据库一致
|
||||||
|
if !dbutils.HasFreeSpace {
|
||||||
|
return true, errors.New("dump accesslog failed: there is no enough space left for database (" + dbutils.LocalDatabaseDataDir + ")")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 开始事务
|
// 开始事务
|
||||||
|
|||||||
73
internal/db/utils/disk.go
Normal file
73
internal/db/utils/disk.go
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
|
||||||
|
package dbutils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/goman"
|
||||||
|
"github.com/go-sql-driver/mysql"
|
||||||
|
"github.com/iwind/TeaGo/dbs"
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const minFreeSpaceGB = 3
|
||||||
|
|
||||||
|
var HasFreeSpace = true
|
||||||
|
var IsLocalDatabase = false
|
||||||
|
var LocalDatabaseDataDir = ""
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
var ticker = time.NewTicker(5 * time.Minute)
|
||||||
|
|
||||||
|
dbs.OnReadyDone(func() {
|
||||||
|
goman.New(func() {
|
||||||
|
for range ticker.C {
|
||||||
|
HasFreeSpace = CheckHasFreeSpace()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckHasFreeSpace 检查当前数据库是否有剩余空间
|
||||||
|
func CheckHasFreeSpace() bool {
|
||||||
|
db, _ := dbs.Default()
|
||||||
|
if db == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
config, _ := db.Config()
|
||||||
|
if config == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
dsnConfig, _ := mysql.ParseDSN(config.Dsn)
|
||||||
|
if dsnConfig == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if IsLocalAddr(dsnConfig.Addr) {
|
||||||
|
IsLocalDatabase = true
|
||||||
|
|
||||||
|
// only for local database
|
||||||
|
one, err := db.FindOne("SHOW VARIABLES WHERE variable_name='datadir'")
|
||||||
|
if err != nil || len(one) == 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
var dir = one.GetString("Value")
|
||||||
|
if len(dir) == 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
LocalDatabaseDataDir = dir
|
||||||
|
|
||||||
|
var stat unix.Statfs_t
|
||||||
|
err = unix.Statfs(dir, &stat)
|
||||||
|
if err != nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
var availableSpace = (stat.Bavail * uint64(stat.Bsize)) / (1 << 30) // GB
|
||||||
|
return availableSpace > minFreeSpaceGB
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
14
internal/db/utils/disk_test.go
Normal file
14
internal/db/utils/disk_test.go
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
|
||||||
|
package dbutils_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
dbutils "github.com/TeaOSLab/EdgeAPI/internal/db/utils"
|
||||||
|
_ "github.com/iwind/TeaGo/bootstrap"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestHasFreeSpace(t *testing.T) {
|
||||||
|
t.Log(dbutils.CheckHasFreeSpace())
|
||||||
|
t.Log(dbutils.LocalDatabaseDataDir)
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ package dbutils
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/iwind/TeaGo/dbs"
|
"github.com/iwind/TeaGo/dbs"
|
||||||
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -69,3 +70,26 @@ func SetGlobalVarMax(db *dbs.DB, variableName string, maxValue int) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsLocalAddr 是否为本地数据库
|
||||||
|
func IsLocalAddr(addr string) bool {
|
||||||
|
var host = addr
|
||||||
|
if strings.Contains(addr, ":") {
|
||||||
|
host, _, _ = net.SplitHostPort(addr)
|
||||||
|
if len(host) == 0 {
|
||||||
|
host = addr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if host == "127.0.0.1" || host == "::1" || host == "localhost" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
interfaceAddrs, _ := net.InterfaceAddrs()
|
||||||
|
for _, interfaceAddr := range interfaceAddrs {
|
||||||
|
if strings.HasPrefix(interfaceAddr.String(), host+"/") {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ package dbutils_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
dbutils "github.com/TeaOSLab/EdgeAPI/internal/db/utils"
|
dbutils "github.com/TeaOSLab/EdgeAPI/internal/db/utils"
|
||||||
|
"github.com/iwind/TeaGo/assert"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -12,3 +13,13 @@ func TestQuoteLike(t *testing.T) {
|
|||||||
t.Log(s + " => " + dbutils.QuoteLike(s))
|
t.Log(s + " => " + dbutils.QuoteLike(s))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIsLocalAddr(t *testing.T) {
|
||||||
|
var a = assert.NewAssertion(t)
|
||||||
|
a.IsTrue(dbutils.IsLocalAddr("127.0.0.1"))
|
||||||
|
a.IsTrue(dbutils.IsLocalAddr("localhost"))
|
||||||
|
a.IsTrue(dbutils.IsLocalAddr("::1"))
|
||||||
|
a.IsTrue(dbutils.IsLocalAddr("127.0.0.1:3306"))
|
||||||
|
a.IsFalse(dbutils.IsLocalAddr("192.168.2.200"))
|
||||||
|
a.IsFalse(dbutils.IsLocalAddr("192.168.2.200:3306"))
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user