Skip to content

[Bug]: E2E image swap replaces shared Operator and restarts unrelated MO clusters #619

Open

Description

@Ariznawlll

Description

A UDF E2E MatrixOne Operator started as the shared cluster-level operator and reconciled an unrelated, already-running big-data MatrixOne cluster in another namespace. During reconciliation it changed the existing MO configuration and triggered in-place restarts of LogService, DN, and both Proxy containers. The second Proxy restart terminated an active 100M-row UPDATE connection.

This is not a second MatrixOne cluster and not a query-triggered OOM. It is cross-test/operator isolation: a test Operator must not mutate workloads outside its own test namespace.

Environment

Steps to reproduce

  1. Keep an existing MO cluster running in namespace mo-big-data-commit-d2a3391-suite-1y.

  2. Start the UDF E2E Operator as a cluster-level controller rather than scoping it to the E2E namespace.

  3. Run a long query through Proxy. In this incident the query was:

    UPDATE big_data_test.table_with_pk_index_for_write_100M_copy01
    SET col3 = col3 + 1;
  4. Observe the Operator reconcile the unrelated namespace and update the existing ConfigMap.

  5. Observe LogService, DN, and Proxy containers restart in place and the active client connection fail.

Actual behavior

The UDF E2E Operator started its controllers at 03:30:10Z and immediately reconciled the unrelated big-data namespace. Its logs included:

config key start.sh is not in use, will be deleted.
configmap mo-big-data-commit-d2a3391-suite-1y/nightly-regression-dis-log-config

config key logservice.toml-620d8e6 is not in use, will be deleted.
configmap mo-big-data-commit-d2a3391-suite-1y/nightly-regression-dis-log-config

The same Operator repeatedly reported that the existing cluster used a configuration incompatible with this Operator build:

LegacyPythonUdfSidecarUnsupported: recreate the function with spec.udfWorker

Component restart timeline:

Time (UTC) Event
03:30:16 log-2 received SIGTERM
03:30:24 log-1 received SIGTERM
03:30:33 log-0 received SIGTERM
03:31:07 DN received SIGTERM
03:31:16 Proxy qd7w9 received SIGTERM
03:31:45.768 Proxy qdzd5 received SIGTERM
03:31:45.774 Client returned (2013, 'Lost connection to MySQL server during query')

The Proxy shutdown and client failure were approximately 6 ms apart. Pod UIDs remained unchanged while restart counts increased, consistent with OpenKruise in-place updates.

The UPDATE did not partially commit. The post-failure SUM differed from the expected value by exactly 100,000,000, showing that all 100M row modifications were rolled back.

Expected behavior

  • An Operator deployed for an E2E test must only watch and mutate resources owned by that test.
  • Starting or replacing an E2E Operator must not reconcile or restart MO components in unrelated namespaces.
  • Existing client connections in unrelated clusters must not be interrupted.

Stability and controls

  • The same LOG/DN/Proxy group accumulated a second restart later in the same run, while all three CNs remained at zero restarts.
  • No container reported OOMKilled.
  • DN peak working set was about 24.3 GiB with a 55 GiB limit; CN peaks were also below the 55 GiB limits.
  • DN exit 137 occurred after it had received SIGTERM and exceeded the shutdown grace period; it was not a cgroup OOM kill.
  • Queries executed after reconnection succeeded, confirming a transient infrastructure-induced connection interruption rather than persistent database failure.

Code analysis

SyncConfigMap documents that ConfigMap data changes cause a rolling update. For OperatorVersion >= 1.3, the generated configuration suffix is propagated to the Pod template; OpenKruise then restarts the container in place.

Relevant code:

  • pkg/controllers/common/configmap.go: ConfigMap synchronization and deletion of no-longer-used keys
  • pkg/controllers/common/podset.go: matrixorigin.io/config-suffix propagation
  • LogSet/DNSet/ProxySet controllers: in-place ConfigMap update support

The immediate trigger in this incident was the UDF E2E Operator reconciling a pre-existing cluster outside its test scope. The configuration-diff rollout risk is related to #606, but this issue tracks the missing E2E/operator namespace isolation and the resulting real service interruption.

Proposed fix

  1. Scope E2E Operator watches to the E2E namespace (WATCH_NAMESPACE or equivalent cache selector).
  2. Do not replace or reuse the shared cluster-level Operator deployment for E2E binaries.
  3. Give E2E Operator deployments unique leader-election IDs and resource ownership boundaries.
  4. Add a pre-existing sentinel MO cluster to the Operator E2E environment and assert that its CR, ConfigMaps, pod UIDs, config suffixes, and restart counters do not change.
  5. Add a guard that prevents a test Operator from starting with unrestricted cluster scope in a shared environment.

Related

Activity

  1. added theissue type on Sep 17, 2026
  2. Ariznawlll commented on Sep 17, 2026

    @Ariznawlll
    CollaboratorAuthor

    进一步核对 mo-srv-129 的 shell history 和共享 Operator Deployment 后,根因已确认并修正如下:

    1. 直接触发条件不是 Operator 自发越界,也不是同时启动了两套相同的 MO 集群。
    2. UDF E2E 流程在共享环境中执行了 kubectl -n matrixone set image deployment/$OP_DEP matrixone-operator=$OP_IMG,将集群级共享 Operator 的镜像临时替换成测试镜像。
    3. Deployment 的 managed fields 中存在 kubectl-set,并且故障时间窗口内 Operator ReplicaSet 镜像发生了多次切换,与组件滚动重启时间吻合。
    4. 因为被替换的仍是共享、集群级 Operator,它继续拥有跨 namespace 的正常调谐权限,所以对既有 big-data MO 集群进行配置同步并触发 LogService、DN、Proxy 原地重启;活跃 UPDATE 连接因此断开。
    5. 因此本问题应归类为 E2E 安装/隔离流程缺少防护,而不是 MO SQL、OOM 或 Operator 在未被替换时无缘无故越界。

    已提交修复 PR #620:

    • 新增独立 E2E Operator 安装脚本,禁止使用 matrixone 等共享 namespace;
    • 要求独立 namespace 带有显式 E2E 标签;
    • 强制 onlyWatchReleasedNS=true;
    • 将全部 admission webhook 限定到该 E2E namespace;
    • 禁用重复安装 Kruise controller;
    • 增加脚本单测、Helm 渲染校验和共享集群使用说明。

    PR: #620

    在 PR 合入并由 UDF E2E 调用方切换到该安装入口前,仍不得在共享环境中通过 kubectl set image 替换共享 Operator。

  3. changed the title [-][Bug]: UDF E2E operator reconciles unrelated namespaces and restarts live MO components[/-] [+][Bug]: E2E image swap replaces shared Operator and restarts unrelated MO clusters[/+] on Sep 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions