iloveeyjafjalla opened a new issue, #6667:
URL: https://github.com/apache/rocketmq-dashboard/issues/6667
### Studio Version
branch: `rocketmq-studio` @ `e2f815fb` (baseline this was reproduced on)
### Runtime Environment
The repository's own stack: MySQL 8 (`studio-mysql`), the studio backend on
8888, the Apache provider pointed at a local broker. The database container
runs on the **UTC** clock (`date` → `Wed Oct 14 14:28:07 UTC 2026`, `SELECT
NOW(), @@global.time_zone` → `2026-10-14 14:28:08`, `SYSTEM`), while the studio
JVM is in **Asia/Shanghai** — that is the configuration the checked-in
`server/src/main/resources/application.yml` default describes
(`...&serverTimezone=UTC`) and the one any deployment has when the database is
a managed/containerised MySQL left in UTC.
### Connected RocketMQ Cluster
Apache 5.3.2 single broker (`local-broker`), only for the create RPC to
succeed.
### Describe the Bug
A topic (or consumer group) created through the studio reports two different
clocks in the same row. Creating `tz-probe-1` at local `22:26:44` produced:
```
mysql> SELECT id, name, gmt_create, gmt_modified FROM rmq_instance_topic
WHERE name = 'tz-probe-1';
31 tz-probe-1 2026-10-14 14:26:44 2026-10-14 22:26:45
```
`gmt_create` is the **database** wall clock (UTC) and `gmt_modified` is the
**studio** wall clock (Asia/Shanghai) — the row disagrees with itself by the
offset between the two hosts, and because the console renders both with the
local-time helper (`web/src/pages/instance/topic.tsx` formats
`gmtCreate`/`gmtModified` with `formatDateTime`), the *创建时间* column shows a
time eight hours before the topic existed. The audit row the same request
writes carries the studio clock (`2026-10-14T22:26:45`), so the console
disagrees with itself about when the topic was created.
### Root Cause
`ResourceOwnershipGuard` commits the claim with a raw INSERT that does
**not** name the bookkeeping columns:
```java
// ResourceOwnershipGuard:124 (write/4)
jdbc.update("INSERT INTO rmq_instance_topic (name, instance_id, cluster_id,
status, topic_type)"
+ " VALUES (?, ?, ?, 'PENDING', ?)", ...);
jdbc.update("INSERT INTO rmq_instance_group (name, instance_id, cluster_id,
status)"
+ " VALUES (?, ?, ?, 'PENDING')", ...);
```
Both tables declare `gmt_create datetime NOT NULL DEFAULT CURRENT_TIMESTAMP`
/ `gmt_modified ... ON UPDATE CURRENT_TIMESTAMP`
(`server/src/main/resources/db/schema.sql:124-125`, `:145-146`), so those two
columns are filled by the **database** clock.
The topic create path then reads the reserved row back and only stamps the
creation time when *it* created the row:
```java
// RocketMQAdminClientImpl:316-326
RmqTopic entity = topicMapper.selectOne(... name = topicName);
boolean isNew = entity == null; // false: the guard reserved the
row first
if (isNew) { entity.setGmtCreate(LocalDateTime.now()); }
...
entity.setGmtModified(LocalDateTime.now()); // studio clock,
unconditionally
```
Because the guard always wins that race, `isNew` is false for a
studio-created topic/group, `gmt_create` keeps the database clock, and
`gmt_modified` becomes the studio clock. Every other writer in the application
stamps its columns from the JVM clock (`LocalDateTime.now()`, or the explicit
UTC clock of the alert/notification surfaces), which is why the console and the
API normally agree — the reservation is the one writer that leans on the column
default.
This is why CI cannot see it: the CI MySQL service container runs in UTC and
so do the tests, so the two clocks coincide. It shows up whenever the database
zone differs from the studio zone, e.g. managed MySQL in UTC with the studio in
Asia/Shanghai.
### Expected Behavior
A row the studio writes carries bookkeeping stamps from one clock — the one
the update path already uses. The reservation should name
`gmt_create`/`gmt_modified` and pass the studio clock, so that (a) the creation
time in the console is the time the topic was created for the viewer, and (b)
the two columns of one row can never disagree.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]