Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Required version of postgres is now >= 12 #12155

Merged
merged 3 commits into from
Feb 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ regarding Chainlink social accounts, news, and networking.
- Example Path for macOS `export PATH=$GOPATH/bin:$PATH` & `export GOPATH=/Users/$USER/go`
2. Install [NodeJS v16](https://nodejs.org/en/download/package-manager/) & [pnpm via npm](https://pnpm.io/installation#using-npm).
- It might be easier long term to use [nvm](https://nodejs.org/en/download/package-manager/#nvm) to switch between node versions for different projects. For example, assuming $NODE_VERSION was set to a valid version of NodeJS, you could run: `nvm install $NODE_VERSION && nvm use $NODE_VERSION`
3. Install [Postgres (>= 11.x and <= 15.x)](https://wiki.postgresql.org/wiki/Detailed_installation_guides).
- You should [configure Postgres](https://www.postgresql.org/docs/12/ssl-tcp.html) to use SSL connection (or for testing you can set `?sslmode=disable` in your Postgres query string).
3. Install [Postgres (>= 12.x)](https://wiki.postgresql.org/wiki/Detailed_installation_guides). It is recommended to run the latest major version of postgres.
jmank88 marked this conversation as resolved.
Show resolved Hide resolved
- Note if you are running the official Chainlink docker image, the highest supported Postgres version is 15.x due to the bundled client.
- You should [configure Postgres](https://www.postgresql.org/docs/current/ssl-tcp.html) to use SSL connection (or for testing you can set `?sslmode=disable` in your Postgres query string).
4. Ensure you have Python 3 installed (this is required by [solc-select](https://github.com/crytic/solc-select) which is needed to compile solidity contracts)
5. Download Chainlink: `git clone https://github.com/smartcontractkit/chainlink && cd chainlink`
6. Build and install Chainlink: `make install`
Expand Down
46 changes: 46 additions & 0 deletions core/services/pg/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package pg

import (
"fmt"
"log"
"os"
"time"

"github.com/google/uuid"
Expand All @@ -16,6 +18,24 @@ import (
"github.com/XSAM/otelsql"
)

var MinRequiredPGVersion = 110000

func init() {
// from: https://www.postgresql.org/support/versioning/
now := time.Now()
if now.Year() > 2023 {
MinRequiredPGVersion = 120000
} else if now.Year() > 2024 {
MinRequiredPGVersion = 130000
} else if now.Year() > 2025 {
MinRequiredPGVersion = 140000
} else if now.Year() > 2026 {
MinRequiredPGVersion = 150000
} else if now.Year() > 2027 {
MinRequiredPGVersion = 160000
}
}

type ConnectionConfig interface {
DefaultIdleInTxSessionTimeout() time.Duration
DefaultLockTimeout() time.Duration
Expand Down Expand Up @@ -65,9 +85,35 @@ func NewConnection(uri string, dialect dialects.DialectName, config ConnectionCo
db.SetMaxOpenConns(config.MaxOpenConns())
db.SetMaxIdleConns(config.MaxIdleConns())

if os.Getenv("SKIP_PG_VERSION_CHECK") != "true" {
if err := checkVersion(db, MinRequiredPGVersion); err != nil {
return nil, err
}
}

return db, disallowReplica(db)
}

type Getter interface {
Get(dest interface{}, query string, args ...interface{}) error
}

func checkVersion(db Getter, minVersion int) error {
var version int
if err := db.Get(&version, "SHOW server_version_num"); err != nil {
log.Printf("Error getting server version, skipping Postgres version check: %s", err.Error())
return nil
}
if version < 10000 {
log.Printf("Unexpectedly small version, skipping Postgres version check (you are running: %d)", version)
return nil
}
if version < minVersion {
return fmt.Errorf("The minimum required Postgres server version is %d, you are running: %d, which is EOL (see: https://www.postgresql.org/support/versioning/). It is recommended to upgrade your Postgres server. To forcibly override this check, set SKIP_PG_VERSION_CHECK=true", minVersion/10000, version/10000)
}
return nil
}

func disallowReplica(db *sqlx.DB) error {
var val string
err := db.Get(&val, "SHOW session_replication_role")
Expand Down
54 changes: 53 additions & 1 deletion core/services/pg/connection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,70 @@ package pg

import (
"testing"
"time"

"github.com/google/uuid"
_ "github.com/jackc/pgx/v4/stdlib"
"github.com/jmoiron/sqlx"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"github.com/smartcontractkit/chainlink/v2/core/store/dialects"
)

func Test_disallowReplica(t *testing.T) {
var _ Getter = &mockGetter{}

type mockGetter struct {
version int
err error
}

func (m *mockGetter) Get(dest interface{}, query string, args ...interface{}) error {
if m.err != nil {
return m.err
}
*(dest.(*int)) = m.version
return nil
}

func Test_checkVersion(t *testing.T) {
if time.Now().Year() > 2027 {
t.Fatal("Postgres version numbers only registered until 2028, please update the postgres version check using: https://www.postgresql.org/support/versioning/ then fix this test")
}
t.Run("when the version is too low", func(t *testing.T) {
m := &mockGetter{version: 100000}
err := checkVersion(m, 110000)
require.Error(t, err)
assert.Contains(t, err.Error(), "The minimum required Postgres server version is 11, you are running: 10")
})
t.Run("when the version is at minimum", func(t *testing.T) {
m := &mockGetter{version: 110000}
err := checkVersion(m, 110000)
require.NoError(t, err)
})
t.Run("when the version is above minimum", func(t *testing.T) {
m := &mockGetter{version: 110001}
err := checkVersion(m, 110000)
require.NoError(t, err)
m = &mockGetter{version: 120000}
err = checkVersion(m, 110001)
require.NoError(t, err)
})
t.Run("ignores wildly small versions, 0 etc", func(t *testing.T) {
m := &mockGetter{version: 9000}
err := checkVersion(m, 110001)
require.NoError(t, err)
})
t.Run("ignores errors", func(t *testing.T) {
m := &mockGetter{err: errors.New("some error")}
err := checkVersion(m, 110001)
require.NoError(t, err)
})
}

func Test_disallowReplica(t *testing.T) {
testutils.SkipShortDB(t)
db, err := sqlx.Open(string(dialects.TransactionWrappedPostgres), uuid.New().String())
require.NoError(t, err)
Expand Down
4 changes: 4 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- `P2P.V2` is required in configuration when either `OCR` or `OCR2` are enabled. The node will fail to boot if `P2P.V2` is not enabled.

### Changed

- Minimum required version of Postgres is now >= 12. Postgres 11 was EOL'd in November 2023. Added a new version check that will prevent Chainlink from running on EOL'd Postgres. If you are running Postgres <= 11 you should upgrade to the latest version. The check can be forcibly overridden by setting SKIP_PG_VERSION_CHECK=true.

## 2.9.0 - UNRELEASED

### Added
Expand Down
Loading