orchestrator/clickhouse: add compatibility check for INTERPOLATE issue

I don't want to keep disabling the experimental analyzer forever. The
version check could be turned into disabling the experimental analyzer,
but this is better to push people to update their versions.

To be pushed only when 24.3 (LTS) and 24.4 gets the fix.
This commit is contained in:
Vincent Bernat
2024-06-02 14:21:49 +02:00
parent cffd6e42ab
commit 625429f27f
5 changed files with 51 additions and 28 deletions

View File

@@ -14,7 +14,6 @@ identified with a specific icon:
## Unreleased ## Unreleased
- 💥 *console*: persist metadata cache on the default `docker compose` setup - 💥 *console*: persist metadata cache on the default `docker compose` setup
- 🩹 *clickhouse*: disable experimental analyzer on recent versions of ClickHouse
- 🩹 *orchestrator*: fix population of `DstNetSite` and `SrcNetSite` - 🩹 *orchestrator*: fix population of `DstNetSite` and `SrcNetSite`
- 🩹 *orchestrator*: remove previous networks.csv temporary files on start - 🩹 *orchestrator*: remove previous networks.csv temporary files on start
- 🌱 *inlet*: add support Netflow V5 - 🌱 *inlet*: add support Netflow V5
@@ -22,6 +21,7 @@ identified with a specific icon:
- 🌱 *console*: add `console``homepage-graph-timerange` to define the time range for the homepage graph - 🌱 *console*: add `console``homepage-graph-timerange` to define the time range for the homepage graph
- 🌱 *console*: enable round-robin for ClickHouse connections - 🌱 *console*: enable round-robin for ClickHouse connections
- 🌱 *console*: display TCP and UDP port names if known - 🌱 *console*: display TCP and UDP port names if known
- 🌱 *orchestrator*: add ClickHouse version check for INTERPOLATE bug
- 🌱 *docker*: add monitoring stack with Prometheus and Grafana (work in progress) - 🌱 *docker*: add monitoring stack with Prometheus and Grafana (work in progress)
- 🌱 *docker*: update to Traefik 3.0 (not mandatory) - 🌱 *docker*: update to Traefik 3.0 (not mandatory)
- 🌱 *docker*: build IPinfo update image to make it available for non-x86 - 🌱 *docker*: build IPinfo update image to make it available for non-x86

View File

@@ -10,7 +10,6 @@ import (
"strings" "strings"
"time" "time"
"github.com/ClickHouse/clickhouse-go/v2"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"golang.org/x/exp/slices" "golang.org/x/exp/slices"
@@ -250,15 +249,6 @@ func (c *Component) graphLineHandlerFunc(gc *gin.Context) {
Xps float64 `ch:"xps"` Xps float64 `ch:"xps"`
Dimensions []string `ch:"dimensions"` Dimensions []string `ch:"dimensions"`
}{} }{}
// Introduced by: https://github.com/ClickHouse/ClickHouse/pull/61652
// Fixed in: https://github.com/ClickHouse/ClickHouse/pull/64096
// Impacted versions:
// - v24.3
// - v24.4
// - v24.5 until v24.5.1.1763-stable
ctx = clickhouse.Context(ctx, clickhouse.WithSettings(clickhouse.Settings{
"allow_experimental_analyzer": 0,
}))
if err := c.d.ClickHouseDB.Conn.Select(ctx, &results, sqlQuery); err != nil { if err := c.d.ClickHouseDB.Conn.Select(ctx, &results, sqlQuery); err != nil {
c.r.Err(err).Str("query", sqlQuery).Msg("unable to query database") c.r.Err(err).Str("query", sqlQuery).Msg("unable to query database")
gc.JSON(http.StatusInternalServerError, gin.H{"message": "Unable to query database."}) gc.JSON(http.StatusInternalServerError, gin.H{"message": "Unable to query database."})

View File

@@ -10,7 +10,6 @@ import (
"strings" "strings"
"time" "time"
"github.com/ClickHouse/clickhouse-go/v2"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"akvorado/common/schema" "akvorado/common/schema"
@@ -243,9 +242,6 @@ ORDER BY Time WITH FILL
Time time.Time `json:"t"` Time time.Time `json:"t"`
Gbps float64 `json:"gbps"` Gbps float64 `json:"gbps"`
}{} }{}
ctx = clickhouse.Context(ctx, clickhouse.WithSettings(clickhouse.Settings{
"allow_experimental_analyzer": 0,
}))
err := c.d.ClickHouseDB.Conn.Select(ctx, &results, strings.TrimSpace(query)) err := c.d.ClickHouseDB.Conn.Select(ctx, &results, strings.TrimSpace(query))
if err != nil { if err != nil {
c.r.Err(err).Msg("unable to query database") c.r.Err(err).Msg("unable to query database")

View File

@@ -9,6 +9,25 @@ import (
"github.com/hashicorp/go-version" "github.com/hashicorp/go-version"
) )
type versionRange struct {
min string
max string
}
// validateVersionRanges validate that ClickHouse version is not between the
// provided ranges.
func validateVersionRanges(current *version.Version, reason string, invalidRanges []versionRange) error {
for _, versions := range invalidRanges {
v1 := version.Must(version.NewVersion(versions.min))
v2 := version.Must(version.NewVersion(versions.max))
if current.GreaterThanOrEqual(v1) && current.LessThan(v2) {
return fmt.Errorf("incompatible ClickHouse version %s (%s): upgrade to %s",
current, reason, v2)
}
}
return nil
}
// validateVersion checks if ClickHouse version is supported. // validateVersion checks if ClickHouse version is supported.
func validateVersion(v string) error { func validateVersion(v string) error {
current, err := version.NewVersion(v) current, err := version.NewVersion(v)
@@ -27,23 +46,26 @@ func validateVersion(v string) error {
{ {
// Check for IPv6 encoding problems in 23.x // Check for IPv6 encoding problems in 23.x
// See: https://github.com/ClickHouse/ClickHouse/issues/49924 // See: https://github.com/ClickHouse/ClickHouse/issues/49924
nok := []struct { nok := []versionRange{
min string
max string
}{
{"23", "23.2.7.32"}, {"23", "23.2.7.32"},
{"23.2", "23.2.7.23"}, {"23.2", "23.2.7.23"},
{"23.3", "23.3.3.52"}, {"23.3", "23.3.3.52"},
{"23.4", "23.4.3.48"}, {"23.4", "23.4.3.48"},
{"23.5", "23.5.1.3174"}, {"23.5", "23.5.1.3174"},
} }
for _, versions := range nok { if err := validateVersionRanges(current, "IPv6 protobuf encoding bug", nok); err != nil {
v1 := version.Must(version.NewVersion(versions.min)) return err
v2 := version.Must(version.NewVersion(versions.max)) }
if current.GreaterThanOrEqual(v1) && current.LessThan(v2) { }
return fmt.Errorf("incompatible ClickHouse version %s (IPv6 protobuf encoding bug): upgrade to %s", {
current, v2) // Check for experimental analyzer and INTERPOLATE issue
} // Introduced by: https://github.com/ClickHouse/ClickHouse/pull/61652
// Fixed in: https://github.com/ClickHouse/ClickHouse/pull/64096
nok := []versionRange{
{"24.3", "24.5.1.1763"},
}
if err := validateVersionRanges(current, "experimental analyzer bug with INTERPOLATE", nok); err != nil {
return err
} }
} }

View File

@@ -5,8 +5,9 @@ package clickhouse
import "testing" import "testing"
func TestValidateVersion(t *testing.T) { func TestValidateVersionOK(t *testing.T) {
ok := []string{ ok := []string{
// IPv6 encoding issue
"24.1.1111.1111", "24.1.1111.1111",
"23.6.1111.1111", "23.6.1111.1111",
"23.5.3.24", "23.5.3.24",
@@ -16,18 +17,32 @@ func TestValidateVersion(t *testing.T) {
"22.12.5.34", "22.12.5.34",
"22.8.16.32", "22.8.16.32",
"22.4.3.3", "22.4.3.3",
// Experimental analyzer and INTERPOLATE
"24.5.1.1763", // fixed version
"24.2.3.70", // no experimental analyzer
} }
for _, v := range ok { for _, v := range ok {
if err := validateVersion(v); err != nil { if err := validateVersion(v); err != nil {
t.Errorf("validateVersion(%q) error:\n%+v", v, err) t.Errorf("validateVersion(%q) error:\n%+v", v, err)
} }
} }
}
func TestValidateVersionNOK(t *testing.T) {
nok := []string{ nok := []string{
// Too old
"22.3.11.12",
// IPv6 encoding issue
"23.4.1.1943", "23.4.1.1943",
"23.3.1.2823", "23.3.1.2823",
"23.2.2.20", "23.2.2.20",
"23.1.1.3077", "23.1.1.3077",
"22.3.11.12",
// Experimental analyzer and INTERPOLATE
"24.4.1.2088", // not fixed yet
"24.3.3.102", // not fixed yet
} }
for _, v := range nok { for _, v := range nok {
if err := validateVersion(v); err == nil { if err := validateVersion(v); err == nil {