From 81cfb678befbd9a7b2ae0a8a3abe966bb343962c Mon Sep 17 00:00:00 2001 From: Adolfo Builes Date: Tue, 30 Jun 2020 11:13:40 -0500 Subject: [PATCH] services/horizon: Remove db2/core. (#2759) * Remove db2/core. * Remove Horizon config values related with CoreDB. --- services/horizon/CHANGELOG.md | 5 ++ services/horizon/cmd/root.go | 18 +----- services/horizon/internal/app.go | 18 ------ services/horizon/internal/config.go | 2 - services/horizon/internal/db2/core/main.go | 41 ------------ .../horizon/internal/db2/core/main_test.go | 63 ------------------- .../docs/reference/endpoints/metrics.md | 5 +- .../expingest/database_backend_test.go | 6 +- services/horizon/internal/init.go | 24 ------- 9 files changed, 9 insertions(+), 173 deletions(-) delete mode 100644 services/horizon/internal/db2/core/main.go delete mode 100644 services/horizon/internal/db2/core/main_test.go diff --git a/services/horizon/CHANGELOG.md b/services/horizon/CHANGELOG.md index 694cb419cf..6aa5c5dfa2 100644 --- a/services/horizon/CHANGELOG.md +++ b/services/horizon/CHANGELOG.md @@ -6,6 +6,11 @@ file. This project adheres to [Semantic Versioning](http://semver.org/).x ## Unreleased * Add `--parallel-workers` and `--parallel-job-size` to `horizon db reingest range`. `--parallel-workers` will parallelize reingestion using the supplied number of workers. +* Remove Stellar Core's database dependency for non-ingesting instances of Horizon ((#2759)[https://github.com/stellar/go/pull/2759]). + Horizon doesn't require access to a Stellar Core database if it is only serving HTTP request, this allows the separation of front-end and ingesting instances. + The following config parameters were removed: + - `core-db-max-open-connections` + - `core-db-max-idle-connections` ## v1.5.0 diff --git a/services/horizon/cmd/root.go b/services/horizon/cmd/root.go index a64db31bc8..8ed3975f6c 100644 --- a/services/horizon/cmd/root.go +++ b/services/horizon/cmd/root.go @@ -174,7 +174,7 @@ var configOpts = support.ConfigOptions{ ConfigKey: &config.MaxDBConnections, OptType: types.Int, FlagDefault: 0, - Usage: "when set has a priority over horizon-db-max-open-connections, horizon-db-max-idle-connections, core-db-max-open-connections, core-db-max-idle-connections. max horizon database open connections. may need to be increased when responses are slow but DB CPU is normal", + Usage: "when set has a priority over horizon-db-max-open-connections, horizon-db-max-idle-connections. max horizon database open connections may need to be increased when responses are slow but DB CPU is normal", }, &support.ConfigOption{ Name: "horizon-db-max-open-connections", @@ -190,20 +190,6 @@ var configOpts = support.ConfigOptions{ FlagDefault: 20, Usage: "max horizon database idle connections. may need to be set to the same value as horizon-db-max-open-connections when responses are slow and DB CPU is normal, because it may indicate that a lot of time is spent closing/opening idle connections. This can happen in case of high variance in number of requests. must be equal or lower than max open connections", }, - &support.ConfigOption{ - Name: "core-db-max-open-connections", - ConfigKey: &config.CoreDBMaxOpenConnections, - OptType: types.Int, - FlagDefault: 20, - Usage: "max core database open connections. may need to be increased when responses are slow but DB CPU is normal", - }, - &support.ConfigOption{ - Name: "core-db-max-idle-connections", - ConfigKey: &config.CoreDBMaxIdleConnections, - OptType: types.Int, - FlagDefault: 20, - Usage: "max core database idle connections. may need to be set to the same value as core-db-max-open-connections when responses are slow and DB CPU is normal, because it may indicate that a lot of time is spent closing/opening idle connections. This can happen in case of high variance in number of requests. must be equal or lower than max open connections", - }, &support.ConfigOption{ Name: "sse-update-frequency", ConfigKey: &config.SSEUpdateFrequency, @@ -430,8 +416,6 @@ func initRootConfig() { if config.MaxDBConnections != 0 { config.HorizonDBMaxOpenConnections = config.MaxDBConnections config.HorizonDBMaxIdleConnections = config.MaxDBConnections - config.CoreDBMaxOpenConnections = config.MaxDBConnections - config.CoreDBMaxIdleConnections = config.MaxDBConnections } } diff --git a/services/horizon/internal/app.go b/services/horizon/internal/app.go index 4561a3a6a8..04b0d9f5d4 100644 --- a/services/horizon/internal/app.go +++ b/services/horizon/internal/app.go @@ -14,7 +14,6 @@ import ( "github.com/stellar/go/clients/stellarcore" proto "github.com/stellar/go/protocols/stellarcore" horizonContext "github.com/stellar/go/services/horizon/internal/context" - "github.com/stellar/go/services/horizon/internal/db2/core" "github.com/stellar/go/services/horizon/internal/db2/history" "github.com/stellar/go/services/horizon/internal/expingest" "github.com/stellar/go/services/horizon/internal/ledger" @@ -61,7 +60,6 @@ type App struct { config Config web *web historyQ *history.Q - coreQ *core.Q ctx context.Context cancel func() horizonVersion string @@ -79,7 +77,6 @@ type App struct { historyElderLedgerGauge metrics.Gauge horizonConnGauge metrics.Gauge coreLatestLedgerGauge metrics.Gauge - coreConnGauge metrics.Gauge goroutineGauge metrics.Gauge } @@ -181,7 +178,6 @@ func (a *App) Close() { // closed" errors. func (a *App) CloseDB() { a.historyQ.Session.DB.Close() - a.coreQ.Session.DB.Close() } // HistoryQ returns a helper object for performing sql queries against the @@ -196,18 +192,6 @@ func (a *App) HorizonSession(ctx context.Context) *db.Session { return &db.Session{DB: a.historyQ.Session.DB, Ctx: ctx} } -// CoreSession returns a new session that loads data from the stellar core -// database. The returned session is bound to `ctx`. -func (a *App) CoreSession(ctx context.Context) *db.Session { - return &db.Session{DB: a.coreQ.Session.DB, Ctx: ctx} -} - -// CoreQ returns a helper object for performing sql queries aginst the -// stellar core database. -func (a *App) CoreQ() *core.Q { - return a.coreQ -} - // IsHistoryStale returns true if the latest history ledger is more than // `StaleThreshold` ledgers behind the latest core ledger func (a *App) IsHistoryStale() bool { @@ -427,7 +411,6 @@ func (a *App) UpdateMetrics() { a.coreLatestLedgerGauge.Update(int64(ls.CoreLatest)) a.horizonConnGauge.Update(int64(a.historyQ.Session.DB.Stats().OpenConnections)) - a.coreConnGauge.Update(int64(a.coreQ.Session.DB.Stats().OpenConnections)) } // DeleteUnretainedHistory forwards to the app's reaper. See @@ -479,7 +462,6 @@ func (a *App) init() { // horizon-db and core-db mustInitHorizonDB(a) - mustInitCoreDB(a) if a.config.Ingest { // expingester diff --git a/services/horizon/internal/config.go b/services/horizon/internal/config.go index 22e1c0a5c6..6669053e4d 100644 --- a/services/horizon/internal/config.go +++ b/services/horizon/internal/config.go @@ -24,8 +24,6 @@ type Config struct { MaxDBConnections int HorizonDBMaxOpenConnections int HorizonDBMaxIdleConnections int - CoreDBMaxOpenConnections int - CoreDBMaxIdleConnections int SSEUpdateFrequency time.Duration ConnectionTimeout time.Duration diff --git a/services/horizon/internal/db2/core/main.go b/services/horizon/internal/db2/core/main.go deleted file mode 100644 index 5c3a35b76c..0000000000 --- a/services/horizon/internal/db2/core/main.go +++ /dev/null @@ -1,41 +0,0 @@ -// Package core contains database record definitions useable for -// reading rows from a Stellar Core db -package core - -import ( - "github.com/stellar/go/support/db" -) - -// Q is a helper struct on which to hang common queries against a stellar -// core database. -type Q struct { - *db.Session -} - -// ElderLedger represents the oldest "ingestable" ledger known to the -// stellar-core database this ingestion system is communicating with. Horizon, -// which wants to operate on a contiguous range of ledger data (i.e. free from -// gaps) uses the elder ledger to start importing in the case of an empty -// database. NOTE: This current query used is correct, but slow. Please keep -// this query out of latency sensitive or frequently trafficked code paths. -func (q *Q) ElderLedger(dest *int32) error { - err := q.GetRaw(dest, ` - SELECT COALESCE(ledgerseq, 0) - FROM ( - SELECT - ledgerseq, - LAG(ledgerseq, 1) OVER ( ORDER BY ledgerseq) as prev - FROM ledgerheaders - ) seqs - WHERE COALESCE(prev, -1) < ledgerseq - 1 - ORDER BY ledgerseq DESC - LIMIT 1; - `) - - return err -} - -// LatestLedger loads the latest known ledger -func (q *Q) LatestLedger(dest interface{}) error { - return q.GetRaw(dest, `SELECT COALESCE(MAX(ledgerseq), 0) FROM ledgerheaders`) -} diff --git a/services/horizon/internal/db2/core/main_test.go b/services/horizon/internal/db2/core/main_test.go deleted file mode 100644 index 787492adc7..0000000000 --- a/services/horizon/internal/db2/core/main_test.go +++ /dev/null @@ -1,63 +0,0 @@ -package core - -import ( - "testing" - - "github.com/stellar/go/services/horizon/internal/test" -) - -func TestLatestLedger(t *testing.T) { - tt := test.Start(t).Scenario("base") - defer tt.Finish() - q := &Q{tt.CoreSession()} - - var seq int - err := q.LatestLedger(&seq) - - if tt.Assert.NoError(err) { - tt.Assert.Equal(3, seq) - } -} - -func TestElderLedger(t *testing.T) { - tt := test.Start(t).ScenarioWithoutHorizon("kahuna") - defer tt.Finish() - q := &Q{tt.CoreSession()} - - var elder int32 - err := q.ElderLedger(&elder) - if tt.Assert.NoError(err) { - tt.Assert.Equal(elder, int32(1)) - } - - // ledger 3 gets picked properly - _, err = tt.CoreDB.Exec(`DELETE FROM ledgerheaders WHERE ledgerseq = 2`) - tt.Require.NoError(err, "failed to remove ledgerheader") - - err = q.ElderLedger(&elder) - if tt.Assert.NoError(err) { - tt.Assert.Equal(elder, int32(3)) - } - - // a bigger inital gap is properly dealt with - _, err = tt.CoreDB.Exec(` - DELETE FROM ledgerheaders WHERE ledgerseq > 1 AND ledgerseq < 10 - `) - tt.Require.NoError(err, "failed to remove ledgerheader") - - err = q.ElderLedger(&elder) - if tt.Assert.NoError(err) { - tt.Assert.Equal(elder, int32(10)) - } - - // only the latest gap is considered for determining the elder ledger - _, err = tt.CoreDB.Exec(` - DELETE FROM ledgerheaders WHERE ledgerseq > 15 AND ledgerseq < 20 - `) - tt.Require.NoError(err, "failed to remove ledgerheader") - - err = q.ElderLedger(&elder) - if tt.Assert.NoError(err) { - tt.Assert.Equal(elder, int32(20)) - } -} diff --git a/services/horizon/internal/docs/reference/endpoints/metrics.md b/services/horizon/internal/docs/reference/endpoints/metrics.md index f8f039f469..4b245d03ff 100644 --- a/services/horizon/internal/docs/reference/endpoints/metrics.md +++ b/services/horizon/internal/docs/reference/endpoints/metrics.md @@ -228,10 +228,7 @@ As noted above, Horizon relies on Stellar Core to stay in sync with the Stellar ```shell "stellar_core.latest_ledger": { "value": 19203710 -}, -"stellar_core.open_connections": { - "value": 4 -}, +} ``` #### Transaction Submission diff --git a/services/horizon/internal/expingest/database_backend_test.go b/services/horizon/internal/expingest/database_backend_test.go index be29437b80..d368ec4e19 100644 --- a/services/horizon/internal/expingest/database_backend_test.go +++ b/services/horizon/internal/expingest/database_backend_test.go @@ -1,11 +1,10 @@ package expingest import ( - "github.com/stellar/go/network" "testing" "github.com/stellar/go/exp/ingest/ledgerbackend" - "github.com/stellar/go/services/horizon/internal/db2/core" + "github.com/stellar/go/network" "github.com/stellar/go/services/horizon/internal/test" ) @@ -23,12 +22,11 @@ func TestGetLatestLedger(t *testing.T) { func TestGetLatestLedgerNotFound(t *testing.T) { tt := test.Start(t).ScenarioWithoutHorizon("base") defer tt.Finish() - q := &core.Q{tt.CoreSession()} _, err := tt.CoreDB.Exec(`DELETE FROM ledgerheaders`) tt.Assert.NoError(err, "failed to remove ledgerheaders") - backend, err := ledgerbackend.NewDatabaseBackendFromSession(q.Session, network.TestNetworkPassphrase) + backend, err := ledgerbackend.NewDatabaseBackendFromSession(tt.CoreSession(), network.TestNetworkPassphrase) tt.Assert.NoError(err) _, err = backend.GetLatestLedgerSequence() tt.Assert.EqualError(err, "no ledgers exist in ledgerheaders table") diff --git a/services/horizon/internal/init.go b/services/horizon/internal/init.go index 8da9860d3f..b312cbec0a 100644 --- a/services/horizon/internal/init.go +++ b/services/horizon/internal/init.go @@ -8,7 +8,6 @@ import ( "github.com/rcrowley/go-metrics" "github.com/stellar/go/exp/orderbook" - "github.com/stellar/go/services/horizon/internal/db2/core" "github.com/stellar/go/services/horizon/internal/db2/history" "github.com/stellar/go/services/horizon/internal/expingest" "github.com/stellar/go/services/horizon/internal/simplepath" @@ -51,27 +50,6 @@ func mustInitHorizonDB(app *App) { )} } -func mustInitCoreDB(app *App) { - maxIdle := app.config.CoreDBMaxIdleConnections - maxOpen := app.config.CoreDBMaxOpenConnections - if app.config.Ingest { - maxIdle -= expingest.MaxDBConnections - maxOpen -= expingest.MaxDBConnections - if maxIdle <= 0 { - log.Fatalf("max idle connections to stellar-core db must be greater than %d", expingest.MaxDBConnections) - } - if maxOpen <= 0 { - log.Fatalf("max open connections to stellar-core db must be greater than %d", expingest.MaxDBConnections) - } - } - - app.coreQ = &core.Q{mustNewDBSession( - app.config.StellarCoreDatabaseURL, - maxIdle, - maxOpen, - )} -} - func initExpIngester(app *App) { var err error app.expingester, err = expingest.NewSystem(expingest.Config{ @@ -144,14 +122,12 @@ func initDbMetrics(app *App) { app.historyElderLedgerGauge = metrics.NewGauge() app.coreLatestLedgerGauge = metrics.NewGauge() app.horizonConnGauge = metrics.NewGauge() - app.coreConnGauge = metrics.NewGauge() app.goroutineGauge = metrics.NewGauge() app.metrics.Register("history.latest_ledger", app.historyLatestLedgerGauge) app.metrics.Register("history.elder_ledger", app.historyElderLedgerGauge) app.metrics.Register("stellar_core.latest_ledger", app.coreLatestLedgerGauge) app.metrics.Register("order_book_stream.latest_ledger", app.orderBookStream.LatestLedgerGauge) app.metrics.Register("history.open_connections", app.horizonConnGauge) - app.metrics.Register("stellar_core.open_connections", app.coreConnGauge) app.metrics.Register("goroutines", app.goroutineGauge) }