[lxc-devel] [lxd/master] Database fixes
stgraber on Github
lxc-bot at linuxcontainers.org
Tue Jan 14 15:50:44 UTC 2020
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 301 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200114/646d088f/attachment.bin>
-------------- next part --------------
From 7068b83834e6db10c01acd560b276c514aae4c5f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Tue, 14 Jan 2020 10:21:43 -0500
Subject: [PATCH 1/2] lxd/db: Silence normal sql errors
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
lxd/db/db.go | 10 ----------
lxd/db/query/retry.go | 15 ++++++++++++---
2 files changed, 12 insertions(+), 13 deletions(-)
diff --git a/lxd/db/db.go b/lxd/db/db.go
index c0f5d1f5b5..1ca81e60dd 100644
--- a/lxd/db/db.go
+++ b/lxd/db/db.go
@@ -420,16 +420,6 @@ func (c *Cluster) Begin() (*sql.Tx, error) {
return begin(c.db)
}
-func isNoMatchError(err error) bool {
- if err == nil {
- return false
- }
- if err.Error() == "sql: no rows in result set" {
- return true
- }
- return false
-}
-
func begin(db *sql.DB) (*sql.Tx, error) {
for i := 0; i < 1000; i++ {
tx, err := db.Begin()
diff --git a/lxd/db/query/retry.go b/lxd/db/query/retry.go
index 240f75e1ac..a67f3dc5ac 100644
--- a/lxd/db/query/retry.go
+++ b/lxd/db/query/retry.go
@@ -1,12 +1,14 @@
package query
import (
+ "database/sql"
"strings"
"time"
- "github.com/lxc/lxd/shared/logger"
"github.com/mattn/go-sqlite3"
"github.com/pkg/errors"
+
+ "github.com/lxc/lxd/shared/logger"
)
// Retry wraps a function that interacts with the database, and retries it in
@@ -19,8 +21,13 @@ func Retry(f func() error) error {
for i := 0; i < 5; i++ {
err = f()
if err != nil {
- logger.Debugf("Database error: %#v", err)
+ // No point in re-trying or logging a no-row error.
+ if err == sql.ErrNoRows {
+ break
+ }
+ // Process actual errors.
+ logger.Debugf("Database error: %#v", err)
if IsRetriableError(err) {
logger.Debugf("Retry failed db interaction (%v)", err)
time.Sleep(250 * time.Millisecond)
@@ -29,6 +36,7 @@ func Retry(f func() error) error {
}
break
}
+
return err
}
@@ -36,10 +44,10 @@ func Retry(f func() error) error {
// interaction can be safely retried.
func IsRetriableError(err error) bool {
err = errors.Cause(err)
-
if err == nil {
return false
}
+
if err == sqlite3.ErrLocked || err == sqlite3.ErrBusy {
return true
}
@@ -47,6 +55,7 @@ func IsRetriableError(err error) bool {
if strings.Contains(err.Error(), "database is locked") {
return true
}
+
if strings.Contains(err.Error(), "bad connection") {
return true
}
From 364900bfb7cc9bbd1a168715d865c4b834b0f0b7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Tue, 14 Jan 2020 10:50:26 -0500
Subject: [PATCH 2/2] lxd/db: Fix image profile copying logic
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
lxd/db/images.go | 26 +++++++++++++++++++++-----
1 file changed, 21 insertions(+), 5 deletions(-)
diff --git a/lxd/db/images.go b/lxd/db/images.go
index 4a2f9c00dc..4fd1fbfc26 100644
--- a/lxd/db/images.go
+++ b/lxd/db/images.go
@@ -794,10 +794,26 @@ func (c *Cluster) ImageAliasUpdate(id int, imageID int, desc string) error {
// ImageCopyDefaultProfiles copies default profiles from id to new_id.
func (c *Cluster) ImageCopyDefaultProfiles(id int, newID int) error {
- stmt := `INSERT INTO images_profiles (image_id, profile_id)
- SELECT ?, profile_id FROM images_profiles WHERE image_id=?`
- err := exec(c.db, stmt, newID, id)
- return err
+ err := c.Transaction(func(tx *ClusterTx) error {
+ // Delete all current associations.
+ _, err := tx.tx.Exec("DELETE FROM images_profiles WHERE image_id=?", newID)
+ if err != nil {
+ return err
+ }
+
+ // Copy the entries over.
+ _, err = tx.tx.Exec("INSERT INTO images_profiles (image_id, profile_id) SELECT ?, profile_id FROM images_profiles WHERE image_id=?", newID, id)
+ if err != nil {
+ return err
+ }
+
+ return nil
+ })
+ if err != nil {
+ return err
+ }
+
+ return nil
}
// ImageLastAccessUpdate updates the last_use_date field of the image with the
@@ -808,7 +824,7 @@ func (c *Cluster) ImageLastAccessUpdate(fingerprint string, date time.Time) erro
return err
}
-//ImageLastAccessInit inits the last_use_date field of the image with the given fingerprint.
+// ImageLastAccessInit inits the last_use_date field of the image with the given fingerprint.
func (c *Cluster) ImageLastAccessInit(fingerprint string) error {
stmt := `UPDATE images SET cached=1, last_use_date=strftime("%s") WHERE fingerprint=?`
err := exec(c.db, stmt, fingerprint)
More information about the lxc-devel
mailing list