Skip to content

Commit 6bc04c8

Browse files
committed
feat: cli,events: speed up backfill with temporary index
1 parent 41ebef8 commit 6bc04c8

File tree

2 files changed

+55
-4
lines changed

2 files changed

+55
-4
lines changed

chain/events/filter/index.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ var pragmas = []string{
3232
"PRAGMA read_uncommitted = ON",
3333
}
3434

35+
// Any changes to this schema should be matched for the `lotus-shed indexes backfill-events` command
36+
3537
var ddls = []string{
3638
`CREATE TABLE IF NOT EXISTS event (
3739
id INTEGER PRIMARY KEY,

cmd/lotus-shed/indexes.go

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"path"
88
"path/filepath"
99
"strings"
10+
"time"
1011

1112
"github.com/mitchellh/go-homedir"
1213
"github.com/urfave/cli/v2"
@@ -54,6 +55,16 @@ var backfillEventsCmd = &cli.Command{
5455
Value: 2000,
5556
Usage: "the number of epochs to backfill",
5657
},
58+
&cli.BoolFlag{
59+
Name: "temporary-index",
60+
Value: false,
61+
Usage: "use a temporary index to speed up the backfill process",
62+
},
63+
&cli.BoolFlag{
64+
Name: "vacuum",
65+
Value: false,
66+
Usage: "run VACUUM on the database after backfilling is complete; this will reclaim space from deleted rows, but may take a long time",
67+
},
5768
},
5869
Action: func(cctx *cli.Context) error {
5970
srv, err := lcli.GetFullNodeServices(cctx)
@@ -92,8 +103,12 @@ var backfillEventsCmd = &cli.Command{
92103
return err
93104
}
94105

106+
log.Infof(
107+
"WARNING: If this command is run against a node that is currently collecting events with DisableHistoricFilterAPI=false, " +
108+
"it may cause the node to fail to record recent events due to the need to obtain an exclusive lock on the database for writes.")
109+
95110
dbPath := path.Join(basePath, "sqlite", "events.db")
96-
db, err := sql.Open("sqlite3", dbPath)
111+
db, err := sql.Open("sqlite3", dbPath+"?_txlock=immediate")
97112
if err != nil {
98113
return err
99114
}
@@ -105,6 +120,14 @@ var backfillEventsCmd = &cli.Command{
105120
}
106121
}()
107122

123+
if cctx.Bool("temporary-index") {
124+
log.Info("creating temporary index (tmp_event_backfill_index) on event table to speed up backfill")
125+
_, err := db.Exec("CREATE INDEX IF NOT EXISTS tmp_event_backfill_index ON event (height, tipset_key, tipset_key_cid, emitter_addr, event_index, message_cid, message_index, reverted);")
126+
if err != nil {
127+
return err
128+
}
129+
}
130+
108131
addressLookups := make(map[abi.ActorID]address.Address)
109132

110133
// TODO: We don't need this address resolution anymore once https://github.com/filecoin-project/lotus/issues/11594 lands
@@ -134,9 +157,19 @@ var backfillEventsCmd = &cli.Command{
134157
var totalEntriesAffected int64
135158

136159
processHeight := func(ctx context.Context, cnt int, msgs []lapi.Message, receipts []*types.MessageReceipt) error {
137-
tx, err := db.BeginTx(ctx, nil)
138-
if err != nil {
139-
return fmt.Errorf("failed to start transaction: %w", err)
160+
var tx *sql.Tx
161+
for {
162+
var err error
163+
tx, err = db.BeginTx(ctx, nil)
164+
if err != nil {
165+
if err.Error() == "database is locked" {
166+
log.Warnf("database is locked, retrying in 200ms")
167+
time.Sleep(200 * time.Millisecond)
168+
continue
169+
}
170+
return err
171+
}
172+
break
140173
}
141174
defer tx.Rollback() //nolint:errcheck
142175

@@ -312,6 +345,22 @@ var backfillEventsCmd = &cli.Command{
312345

313346
log.Infof("backfilling events complete, totalEventsAffected:%d, totalEntriesAffected:%d", totalEventsAffected, totalEntriesAffected)
314347

348+
if cctx.Bool("temporary-index") {
349+
log.Info("dropping temporary index (tmp_event_backfill_index) on event table")
350+
_, err := db.Exec("DROP INDEX IF EXISTS tmp_event_backfill_index;")
351+
if err != nil {
352+
fmt.Printf("ERROR: dropping index: %s", err)
353+
}
354+
}
355+
356+
if cctx.Bool("vacuum") {
357+
log.Info("running VACUUM on the database")
358+
_, err := db.Exec("VACUUM;")
359+
if err != nil {
360+
return fmt.Errorf("failed to run VACUUM on the database: %w", err)
361+
}
362+
}
363+
315364
return nil
316365
},
317366
}

0 commit comments

Comments
 (0)