diff --git a/stores/metadata.go b/stores/metadata.go index 09201760e..0ce043874 100644 --- a/stores/metadata.go +++ b/stores/metadata.go @@ -2058,6 +2058,8 @@ LIMIT ? return err } else if err = tx.Exec("CREATE TEMPORARY TABLE src AS ?", healthQuery).Error; err != nil { return err + } else if err = tx.Exec("CREATE INDEX src_id ON src (id)").Error; err != nil { + return err } var res *gorm.DB @@ -2073,14 +2075,25 @@ LIMIT ? // Update the health of the objects associated with the updated slabs. if isSQLite(s.db) { - return tx.Exec(`UPDATE objects SET health = src.health FROM src - INNER JOIN slices ON slices.db_slab_id = src.id - WHERE slices.db_object_id = objects.id`).Error + return tx.Exec(`UPDATE objects SET health = i.health FROM ( + SELECT slices.db_object_id, MIN(s.health) AS health + FROM slices + INNER JOIN src s ON s.id = slices.db_slab_id + INNER JOIN objects o ON o.id = slices.db_object_id + GROUP BY slices.db_object_id + ) i + WHERE i.db_object_id = objects.id AND objects.health != i.health`).Error } else { return tx.Exec(`UPDATE objects - INNER JOIN slices sli ON sli.db_object_id = objects.id - INNER JOIN src s ON s.id = sli.db_slab_id - SET objects.health = s.health`).Error + INNER JOIN ( + SELECT slices.db_object_id, MIN(s.health) as health + FROM slices + INNER JOIN src s ON s.id = slices.db_slab_id + GROUP BY slices.db_object_id + ) i ON objects.id = i.db_object_id + SET objects.health = i.health + WHERE objects.health != i.health + `).Error } }) if err != nil { diff --git a/stores/sql.go b/stores/sql.go index d7ee636db..0da9a35f6 100644 --- a/stores/sql.go +++ b/stores/sql.go @@ -581,18 +581,20 @@ func initConsensusInfo(db *gorm.DB) (dbConsensusInfo, modules.ConsensusChangeID, } func (s *SQLStore) ResetConsensusSubscription() error { - // drop tables - err := s.db.Migrator().DropTable(&dbConsensusInfo{}, &dbSiacoinElement{}, &dbTransaction{}) - if err != nil { - return err - } - // recreate the tables. - err = s.db.Migrator().AutoMigrate(&dbConsensusInfo{}, &dbSiacoinElement{}, &dbTransaction{}) - if err != nil { - return err - } - // initialise the consenus_info table. - ci, _, err := initConsensusInfo(s.db) + // empty tables and reinit consensus_infos + var ci dbConsensusInfo + err := s.retryTransaction(func(tx *gorm.DB) error { + if err := s.db.Exec("DELETE FROM consensus_infos").Error; err != nil { + return err + } else if err := s.db.Exec("DELETE FROM siacoin_elements").Error; err != nil { + return err + } else if err := s.db.Exec("DELETE FROM transactions").Error; err != nil { + return err + } else if ci, _, err = initConsensusInfo(tx); err != nil { + return err + } + return nil + }) if err != nil { return err } diff --git a/stores/sql_test.go b/stores/sql_test.go index 9f072d3ad..5a5870a9f 100644 --- a/stores/sql_test.go +++ b/stores/sql_test.go @@ -190,6 +190,10 @@ func TestConsensusReset(t *testing.T) { t.Fatal(err) } + // Reopen the SQLStore. + ss = ss.Reopen() + defer ss.Close() + // Check tables. var count int64 if err := ss.db.Model(&dbConsensusInfo{}).Count(&count).Error; err != nil || count != 1 {