From bb3fb5fc9393b8bf81b388337c5e1a8c8faeff9a Mon Sep 17 00:00:00 2001 From: Chris Sun Date: Fri, 9 Jan 2026 14:56:58 +0800 Subject: [PATCH 1/5] optimize getting sys client (#882) --- api/v1alpha1/helpers.go | 6 ++++++ .../dashboard/business/oceanbase/obcluster_usage.go | 7 +++++++ internal/dashboard/utils/connection.go | 6 ++++++ internal/resource/utils/connections.go | 10 ++++++++++ 4 files changed, 29 insertions(+) diff --git a/api/v1alpha1/helpers.go b/api/v1alpha1/helpers.go index 593db9a31..95bcc6517 100644 --- a/api/v1alpha1/helpers.go +++ b/api/v1alpha1/helpers.go @@ -14,6 +14,7 @@ package v1alpha1 import ( "context" + "sort" "github.com/go-logr/logr" "github.com/pkg/errors" @@ -23,6 +24,7 @@ import ( oceanbaseconst "github.com/oceanbase/ob-operator/internal/const/oceanbase" clusterstatus "github.com/oceanbase/ob-operator/internal/const/status/obcluster" + observerstatus "github.com/oceanbase/ob-operator/internal/const/status/observer" "github.com/oceanbase/ob-operator/pkg/oceanbase-sdk/connector" "github.com/oceanbase/ob-operator/pkg/oceanbase-sdk/operation" ) @@ -51,6 +53,10 @@ func getSysClient(c client.Client, logger *logr.Logger, obcluster *OBCluster, us return nil, errors.Errorf("No observer belongs to cluster %s", obcluster.Name) } + sort.Slice(observerList.Items, func(i, j int) bool { + return observerList.Items[i].Status.Status == observerstatus.Running && observerList.Items[j].Status.Status != observerstatus.Running + }) + var s *connector.OceanBaseDataSource password, err := readPassword(c, obcluster.Namespace, secretName) if err != nil { diff --git a/internal/dashboard/business/oceanbase/obcluster_usage.go b/internal/dashboard/business/oceanbase/obcluster_usage.go index be772ca40..320132fb6 100644 --- a/internal/dashboard/business/oceanbase/obcluster_usage.go +++ b/internal/dashboard/business/oceanbase/obcluster_usage.go @@ -14,6 +14,7 @@ package oceanbase import ( "context" + "sort" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -21,6 +22,7 @@ import ( "github.com/oceanbase/ob-operator/api/v1alpha1" "github.com/oceanbase/ob-operator/internal/clients" oceanbaseconst "github.com/oceanbase/ob-operator/internal/const/oceanbase" + observerstatus "github.com/oceanbase/ob-operator/internal/const/status/observer" "github.com/oceanbase/ob-operator/internal/dashboard/model/param" "github.com/oceanbase/ob-operator/internal/dashboard/model/response" httpErr "github.com/oceanbase/ob-operator/pkg/errors" @@ -43,6 +45,11 @@ func GetOBClusterUsages(ctx context.Context, nn *param.K8sObjectIdentity) (*resp if err != nil { return nil, httpErr.NewInternal(err.Error()) } + + sort.Slice(serverList.Items, func(i, j int) bool { + return serverList.Items[i].Status.Status == observerstatus.Running && serverList.Items[j].Status.Status != observerstatus.Running + }) + rootSecret, err := clt.ClientSet.CoreV1().Secrets(nn.Namespace).Get(ctx, obcluster.Spec.UserSecrets.Root, metav1.GetOptions{}) if err != nil { return nil, httpErr.NewInternal(err.Error()) diff --git a/internal/dashboard/utils/connection.go b/internal/dashboard/utils/connection.go index d989aacfd..20967eea9 100644 --- a/internal/dashboard/utils/connection.go +++ b/internal/dashboard/utils/connection.go @@ -14,6 +14,7 @@ package utils import ( "context" + "sort" "github.com/go-logr/logr" "github.com/pkg/errors" @@ -22,6 +23,7 @@ import ( "github.com/oceanbase/ob-operator/api/v1alpha1" "github.com/oceanbase/ob-operator/internal/clients" oceanbaseconst "github.com/oceanbase/ob-operator/internal/const/oceanbase" + observerstatus "github.com/oceanbase/ob-operator/internal/const/status/observer" "github.com/oceanbase/ob-operator/pkg/k8s/client" "github.com/oceanbase/ob-operator/pkg/oceanbase-sdk/connector" "github.com/oceanbase/ob-operator/pkg/oceanbase-sdk/operation" @@ -39,6 +41,10 @@ func GetOBConnection(ctx context.Context, obcluster *v1alpha1.OBCluster, userNam return nil, errors.Errorf("No observer belongs to cluster %s", obcluster.Name) } + sort.Slice(observerList.Items, func(i, j int) bool { + return observerList.Items[i].Status.Status == observerstatus.Running && observerList.Items[j].Status.Status != observerstatus.Running + }) + var s *connector.OceanBaseDataSource secret, err := client.GetClient().ClientSet.CoreV1().Secrets(obcluster.Namespace).Get(ctx, secretName, metav1.GetOptions{}) if err != nil { diff --git a/internal/resource/utils/connections.go b/internal/resource/utils/connections.go index 38b51f350..fc26f4adf 100644 --- a/internal/resource/utils/connections.go +++ b/internal/resource/utils/connections.go @@ -14,6 +14,7 @@ package utils import ( "context" + "sort" "strconv" "strings" @@ -24,6 +25,7 @@ import ( "github.com/oceanbase/ob-operator/api/v1alpha1" oceanbaseconst "github.com/oceanbase/ob-operator/internal/const/oceanbase" clusterstatus "github.com/oceanbase/ob-operator/internal/const/status/obcluster" + observerstatus "github.com/oceanbase/ob-operator/internal/const/status/observer" "github.com/oceanbase/ob-operator/pkg/oceanbase-sdk/connector" "github.com/oceanbase/ob-operator/pkg/oceanbase-sdk/operation" ) @@ -53,6 +55,10 @@ func GetTenantRootOperationClient(c client.Client, logger *logr.Logger, obcluste if len(observerList.Items) == 0 { return nil, errors.Errorf("No observer belongs to cluster %s", obcluster.Name) } + + sort.Slice(observerList.Items, func(i, j int) bool { + return observerList.Items[i].Status.Status == observerstatus.Running && observerList.Items[j].Status.Status != observerstatus.Running + }) var password string if credential != "" { password, err = ReadPassword(c, obcluster.Namespace, credential) @@ -134,6 +140,10 @@ func getSysClient(c client.Client, logger *logr.Logger, obcluster *v1alpha1.OBCl return nil, errors.Errorf("No observer belongs to cluster %s", obcluster.Name) } + sort.Slice(observerList.Items, func(i, j int) bool { + return observerList.Items[i].Status.Status == observerstatus.Running && observerList.Items[j].Status.Status != observerstatus.Running + }) + var s *connector.OceanBaseDataSource password, err := ReadPassword(c, obcluster.Namespace, secretName) if err != nil { From 6a3cb150898ec4908ab2684a3483213056ff9abf Mon Sep 17 00:00:00 2001 From: Chris Sun Date: Fri, 9 Jan 2026 17:22:05 +0800 Subject: [PATCH 2/5] Optimize rolling upgrade (#884) --- internal/resource/obcluster/utils.go | 19 +++++++++++++++++-- internal/resource/obzone/obzone_task.go | 3 +++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/internal/resource/obcluster/utils.go b/internal/resource/obcluster/utils.go index 2fb4a6645..d5ab8b715 100644 --- a/internal/resource/obcluster/utils.go +++ b/internal/resource/obcluster/utils.go @@ -14,6 +14,7 @@ package obcluster import ( "fmt" + "reflect" "strings" "time" @@ -238,13 +239,15 @@ func (m *OBClusterManager) modifyOBZonesAndCheckStatus(changer obzoneChanger, st func (m *OBClusterManager) rollingUpdateZones(changer obzoneChanger, workingStatus, targetStatus string, timeoutSeconds int) tasktypes.TaskFunc { return func() tasktypes.TaskError { - tk := time.NewTicker(time.Duration(timeoutSeconds*2) * time.Second) - defer tk.Stop() obzoneList, err := m.listOBZones() if err != nil { return errors.Wrap(err, "list obzones") } for _, obzone := range obzoneList.Items { + tk := time.NewTicker(time.Duration(timeoutSeconds) * time.Second) + defer tk.Stop() + m.Logger.Info(fmt.Sprintf("Update obzone %s", obzone.Name)) + var specChanged bool m.Recorder.Event(m.OBCluster, "Normal", "RollingUpdateOBZone", "Rolling update OBZone "+obzone.Name) err = retry.RetryOnConflict(retry.DefaultRetry, func() error { targetZone := v1alpha1.OBZone{} @@ -255,12 +258,22 @@ func (m *OBClusterManager) rollingUpdateZones(changer obzoneChanger, workingStat if err != nil { return errors.Wrap(err, "get obzone") } + originalZone := targetZone.DeepCopy() changer(&targetZone) + if reflect.DeepEqual(originalZone.Spec, targetZone.Spec) { + specChanged = false + return nil + } + specChanged = true return m.Client.Update(m.Ctx, &targetZone) }) if err != nil { return errors.Wrap(err, "update obzone") } + if !specChanged { + m.Logger.Info("OBZone not changed, skip checking this zone", "obzone", obzone.Name) + continue + } for i := 0; i < timeoutSeconds; i++ { select { case <-tk.C: @@ -280,6 +293,7 @@ func (m *OBClusterManager) rollingUpdateZones(changer obzoneChanger, workingStat break } } + m.Logger.Info("OBZone has changed to working status", "obzone", obzone.Name, "status", workingStatus) for i := 0; i < timeoutSeconds; i++ { select { case <-tk.C: @@ -299,6 +313,7 @@ func (m *OBClusterManager) rollingUpdateZones(changer obzoneChanger, workingStat break } } + m.Logger.Info("OBZone has changed to target status", "obzone", obzone.Name, "status", targetStatus) } return nil } diff --git a/internal/resource/obzone/obzone_task.go b/internal/resource/obzone/obzone_task.go index b756df6b9..b537a9f30 100644 --- a/internal/resource/obzone/obzone_task.go +++ b/internal/resource/obzone/obzone_task.go @@ -404,6 +404,7 @@ func RollingReplaceOBServers(m *OBZoneManager) tasktypes.TaskError { return errors.Wrap(err, "List observers") } for _, server := range servers.Items { + m.Logger.Info(fmt.Sprintf("Replacing observer %s", server.Name)) newServerName := m.generateServerName() newServer, err := m.createOneOBServer(newServerName) if err != nil { @@ -422,6 +423,7 @@ func RollingReplaceOBServers(m *OBZoneManager) tasktypes.TaskError { if newServer.Status.Status != serverstatus.Running { return errors.New("Wait for new observer get running status, timeout") } + m.Logger.Info(fmt.Sprintf("New observer %s created", newServer.Name)) err = m.Client.Delete(m.Ctx, &server) if err != nil { return errors.Wrap(err, "Delete old observer") @@ -442,6 +444,7 @@ func RollingReplaceOBServers(m *OBZoneManager) tasktypes.TaskError { if !deleted { m.Logger.Error(errors.New("Delete old observer timeout"), "observer", server.Name) } + m.Logger.Info(fmt.Sprintf("Old observer %s deleted", server.Name)) } return nil } From 8d9581ef7409ba5d2025b3be1bc38c7c59d10203 Mon Sep 17 00:00:00 2001 From: Chris Sun Date: Tue, 13 Jan 2026 16:48:55 +0800 Subject: [PATCH 3/5] set timeout (#888) --- pkg/oceanbase-sdk/operation/manager.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pkg/oceanbase-sdk/operation/manager.go b/pkg/oceanbase-sdk/operation/manager.go index 3f0542908..fe608721a 100644 --- a/pkg/oceanbase-sdk/operation/manager.go +++ b/pkg/oceanbase-sdk/operation/manager.go @@ -71,8 +71,14 @@ func GetOceanbaseOperationManager(p *connector.OceanBaseDataSource) (*OceanbaseO func (m *OceanbaseOperationManager) ExecWithTimeout(ctx context.Context, timeout time.Duration, sql string, params ...any) error { c, cancel := context.WithTimeout(ctx, timeout) defer cancel() + m.Logger.Info(fmt.Sprintf("set timeout to %d seconds", int64(timeout/time.Second))) + _, err := m.Connector.GetClient().ExecContext(c, "set ob_query_timeout=?", int64(timeout/time.Microsecond)) + if err != nil { + return errors.Wrap(err, "Failed to set timeout variable") + + } m.Logger.Info(fmt.Sprintf("Execute sql %s with param %v", sql, params)) - _, err := m.Connector.GetClient().ExecContext(c, sql, params...) + _, err = m.Connector.GetClient().ExecContext(c, sql, params...) if err != nil { err = errors.Wrapf(err, "Execute sql failed, sql %s, param %v", sql, params) m.Logger.Error(err, "Execute sql failed") From d811301a4380acc2f107858d41a6a6c81c5a1a3b Mon Sep 17 00:00:00 2001 From: Chris Sun Date: Tue, 13 Jan 2026 17:06:53 +0800 Subject: [PATCH 4/5] bump version of ob-operator to 2.3.4 (#889) --- Makefile | 2 +- charts/ob-operator/Chart.yaml | 4 ++-- charts/ob-operator/templates/operator.yaml | 2 +- config/manager/kustomization.yaml | 2 +- deploy/operator.yaml | 2 +- docsite/src/pages/changelog.md | 2 +- example/argocd/apps/ob-operator.yaml | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index 4ec5393e9..9d59c30a6 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ endif include make/* -VERSION ?= 2.3.3 +VERSION ?= 2.3.4 # Image URL to use all building/pushing image targets IMG ?= quay.io/oceanbase/ob-operator:${VERSION} # ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary. diff --git a/charts/ob-operator/Chart.yaml b/charts/ob-operator/Chart.yaml index e9b8816c6..0fa9a2128 100644 --- a/charts/ob-operator/Chart.yaml +++ b/charts/ob-operator/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 -appVersion: 2.3.3 +appVersion: 2.3.4 description: A Helm chart for OB-Operator name: ob-operator type: application -version: 2.3.3 +version: 2.3.4 diff --git a/charts/ob-operator/templates/operator.yaml b/charts/ob-operator/templates/operator.yaml index 406b7684c..b32c17a69 100644 --- a/charts/ob-operator/templates/operator.yaml +++ b/charts/ob-operator/templates/operator.yaml @@ -21851,7 +21851,7 @@ spec: env: - name: TELEMETRY_REPORTER value: {{ .Values.reporter }} - image: quay.io/oceanbase/ob-operator:2.3.3 + image: quay.io/oceanbase/ob-operator:2.3.4 livenessProbe: httpGet: path: /healthz diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml index fff35bccb..ce15a7c24 100644 --- a/config/manager/kustomization.yaml +++ b/config/manager/kustomization.yaml @@ -5,4 +5,4 @@ kind: Kustomization images: - name: controller newName: quay.io/oceanbase/ob-operator - newTag: 2.3.3 + newTag: 2.3.4 diff --git a/deploy/operator.yaml b/deploy/operator.yaml index 09b6c1727..42a71c6b3 100644 --- a/deploy/operator.yaml +++ b/deploy/operator.yaml @@ -21864,7 +21864,7 @@ spec: env: - name: TELEMETRY_REPORTER value: ob-operator - image: quay.io/oceanbase/ob-operator:2.3.3 + image: quay.io/oceanbase/ob-operator:2.3.4 livenessProbe: httpGet: path: /healthz diff --git a/docsite/src/pages/changelog.md b/docsite/src/pages/changelog.md index f8a37f655..c1116a26e 100644 --- a/docsite/src/pages/changelog.md +++ b/docsite/src/pages/changelog.md @@ -1,6 +1,6 @@ # Changelog -## 2.3.2 (Release on 2025.09.08) +## 2.3.3 (Release on 2025.09.08) ### New Feature 1. Support setting addressingModel for S3_COMPATIBLE storage. 2. Support setting variables while creating tenant, for setting variables which are not able to be modifed after tenant creation. diff --git a/example/argocd/apps/ob-operator.yaml b/example/argocd/apps/ob-operator.yaml index 880ac6a23..5212afe14 100644 --- a/example/argocd/apps/ob-operator.yaml +++ b/example/argocd/apps/ob-operator.yaml @@ -10,7 +10,7 @@ spec: source: repoURL: https://oceanbase.github.io/ob-operator chart: ob-operator - targetRevision: 2.3.3 + targetRevision: 2.3.4 helm: parameters: - name: reporter From acd4a96a3e2fcde75e7ec8c49fd88076c4195a05 Mon Sep 17 00:00:00 2001 From: Chris Sun Date: Wed, 14 Jan 2026 14:34:56 +0800 Subject: [PATCH 5/5] add changelog of 2.3.4 (#893) --- .../docusaurus-plugin-content-pages/changelog.md | 14 ++++++++++++++ docsite/src/pages/changelog.md | 13 +++++++++++++ 2 files changed, 27 insertions(+) diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-pages/changelog.md b/docsite/i18n/zh-Hans/docusaurus-plugin-content-pages/changelog.md index 4340d9c23..8ac1b8d7d 100644 --- a/docsite/i18n/zh-Hans/docusaurus-plugin-content-pages/changelog.md +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-pages/changelog.md @@ -1,5 +1,19 @@ # 变更日志 +## 2.3.4 (发布于 2026.01.13) + +功能优化 +1. 支持通过环境变量设置 oceanbase-sdk 的超时时间。 +2. 重启过程中,跳过处于恢复状态的 observer。 +3. 优化了部分默认超时时间的设置。 +4. 优化了获取 OceanBase 系统租户连接客户端的逻辑。 + +缺陷修复 +1. 为新添加的 obzone 增加了 support-static-ip 注解。 +2. 修复了在 observer 恢复过程中,若 pod 被删除会导致任务失败的问题。 +3. 修复了当 obtenant 的 unit 态异常时导致的程序 panic 问题。 +4. 增加了在 obzone 滚动更新期间对其 spec 变更的检查。 + ## 2.3.3 (发布于 2025.09.08) ### 新增特性 diff --git a/docsite/src/pages/changelog.md b/docsite/src/pages/changelog.md index c1116a26e..02a10abec 100644 --- a/docsite/src/pages/changelog.md +++ b/docsite/src/pages/changelog.md @@ -1,5 +1,18 @@ # Changelog +## 2.3.4 (Release on 2026.01.13) +### Enhancement +1. Support setting oceanbase-sdk's timeout via environment variables +2. Skip observer in recover status when restarting +3. Optimize some default timeout setting +4. Optimize getting oceanbase's sys client + +### Bugfix +1. Add annotation support-static-ip to newly added obzone +2. Fix task fall back policy when pod is deleted during observer recovery process +3. Fix panic problem when obtenant's unit is unexpected +4. Check obzone spec changes during obzone rolling update + ## 2.3.3 (Release on 2025.09.08) ### New Feature 1. Support setting addressingModel for S3_COMPATIBLE storage.