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]

Reply via email to