Skip to content

Commit

Permalink
fix(region): auto clean invalid cached images (#20804)
Browse files Browse the repository at this point in the history
  • Loading branch information
ioito authored Aug 9, 2024
1 parent 0e5d5c6 commit 48fb201
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 40 deletions.
58 changes: 58 additions & 0 deletions pkg/cloudcommon/db/fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import (
"database/sql"
"fmt"
"reflect"
"strings"
"time"

"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
Expand Down Expand Up @@ -602,3 +604,59 @@ func FetchDistinctField(modelManager IModelManager, field string) ([]string, err
return q.Distinct()
})
}

func Purge(modelManager IModelManager, field string, ids []string, forceDelete bool) error {
if len(ids) == 0 {
return nil
}

var splitByLen = func(data []string, splitLen int) [][]string {
var result [][]string
for i := 0; i < len(data); i += splitLen {
end := i + splitLen
if end > len(data) {
end = len(data)
}
result = append(result, data[i:end])
}
return result
}

var purge = func(ids []string) error {
vars := []interface{}{}
placeholders := make([]string, len(ids))
for i := range placeholders {
placeholders[i] = "?"
vars = append(vars, ids[i])
}
placeholder := strings.Join(placeholders, ",")
sql := fmt.Sprintf(
"delete from %s where %s in (%s)",
modelManager.TableSpec().Name(), field, placeholder,
)

if !forceDelete {
sql = fmt.Sprintf(
"update %s set deleted=1, deleted_at= ? where %s in (%s)",
modelManager.TableSpec().Name(), field, placeholder,
)
vars = append([]interface{}{time.Now()}, vars...)
}
_, err := sqlchemy.GetDB().Exec(
sql, vars...,
)
if err != nil {
return errors.Wrapf(err, strings.ReplaceAll(sql, "?", "%s"), vars...)
}
return nil
}

idsArr := splitByLen(ids, 100)
for i := range idsArr {
err := purge(idsArr[i])
if err != nil {
return errors.Wrapf(err, "purge")
}
}
return nil
}
61 changes: 21 additions & 40 deletions pkg/compute/models/cachedimages.go
Original file line number Diff line number Diff line change
Expand Up @@ -945,6 +945,10 @@ func (manager *SCachedimageManager) AutoCleanImageCaches(ctx context.Context, us
if err != nil {
log.Errorf("cleanExternalImages error: %v", err)
}
err = manager.cleanStoragecachedimages()
if err != nil {
log.Errorf("cleanStoragecachedimages error: %v", err)
}
}()
lastSync := time.Now().Add(time.Duration(-1*api.CACHED_IMAGE_REFERENCE_SESSION_EXPIRE_SECONDS) * time.Second)
q := manager.Query()
Expand Down Expand Up @@ -1020,52 +1024,29 @@ func (manager *SCachedimageManager) cleanExternalImages() error {
return errors.Wrapf(err, "getExpireExternalImageIds")
}

if len(ids) == 0 {
return nil
err = db.Purge(manager, "id", ids, true)
if err != nil {
return errors.Wrapf(err, "purge")
}

var splitByLen = func(data []string, splitLen int) [][]string {
var result [][]string
for i := 0; i < len(data); i += splitLen {
end := i + splitLen
if end > len(data) {
end = len(data)
}
result = append(result, data[i:end])
}
return result
}
log.Debugf("clean %d expired external images", len(ids))
return nil
}

var purge = func(ids []string) error {
vars := []interface{}{}
placeholders := make([]string, len(ids))
for i := range placeholders {
placeholders[i] = "?"
vars = append(vars, ids[i])
}
placeholder := strings.Join(placeholders, ",")
sql := fmt.Sprintf(
"delete from %s where id in (%s)",
manager.TableSpec().Name(), placeholder,
)
_, err = sqlchemy.GetDB().Exec(
sql, vars...,
)
if err != nil {
return errors.Wrapf(err, strings.ReplaceAll(sql, "?", "%s"), vars...)
}
return nil
func (manager *SCachedimageManager) cleanStoragecachedimages() error {
ids, err := db.FetchField(StoragecachedimageManager, "row_id", func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
sq := manager.Query("id").Distinct().SubQuery()
return q.NotIn("cachedimage_id", sq)
})
if err != nil {
return errors.Wrapf(err, "getExpireExternalImageIds")
}

idsArr := splitByLen(ids, 100)
for i := range idsArr {
err = purge(idsArr[i])
if err != nil {
return errors.Wrapf(err, "purge")
}
err = db.Purge(StoragecachedimageManager, "row_id", ids, true)
if err != nil {
return errors.Wrapf(err, "purge")
}

log.Debugf("clean %d expired external images", len(ids))
log.Debugf("clean %d invalid storagecachedimages", len(ids))
return nil
}

Expand Down

0 comments on commit 48fb201

Please sign in to comment.