7
7
"path"
8
8
"path/filepath"
9
9
"strings"
10
+ "time"
10
11
11
12
"github.com/mitchellh/go-homedir"
12
13
"github.com/urfave/cli/v2"
@@ -54,6 +55,16 @@ var backfillEventsCmd = &cli.Command{
54
55
Value : 2000 ,
55
56
Usage : "the number of epochs to backfill" ,
56
57
},
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
+ },
57
68
},
58
69
Action : func (cctx * cli.Context ) error {
59
70
srv , err := lcli .GetFullNodeServices (cctx )
@@ -92,8 +103,12 @@ var backfillEventsCmd = &cli.Command{
92
103
return err
93
104
}
94
105
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
+
95
110
dbPath := path .Join (basePath , "sqlite" , "events.db" )
96
- db , err := sql .Open ("sqlite3" , dbPath )
111
+ db , err := sql .Open ("sqlite3" , dbPath + "?_txlock=immediate" )
97
112
if err != nil {
98
113
return err
99
114
}
@@ -105,6 +120,14 @@ var backfillEventsCmd = &cli.Command{
105
120
}
106
121
}()
107
122
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
+
108
131
addressLookups := make (map [abi.ActorID ]address.Address )
109
132
110
133
// 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{
134
157
var totalEntriesAffected int64
135
158
136
159
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
140
173
}
141
174
defer tx .Rollback () //nolint:errcheck
142
175
@@ -312,6 +345,22 @@ var backfillEventsCmd = &cli.Command{
312
345
313
346
log .Infof ("backfilling events complete, totalEventsAffected:%d, totalEntriesAffected:%d" , totalEventsAffected , totalEntriesAffected )
314
347
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
+
315
364
return nil
316
365
},
317
366
}
0 commit comments