{"record":{"id":"c8fbe099b2126c50","repo":"MyCATApache/Mycat-Server","slug":"clock-moved-backwards-refusing-to-generate-id-fo","errorCode":null,"errorMessage":"Clock moved backwards.  Refusing to generate id for %d milliseconds","messagePattern":"Clock moved backwards\\.  Refusing to generate id for (.+?) milliseconds","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"critical","filePath":"src/main/java/io/mycat/route/sequence/handler/SnowflakeIdSequenceHandler.java","lineNumber":102,"sourceCode":"\t}\n\n\tpublic SnowflakeIdSequenceHandler(long workerId) {\n\t\tthis(workerId, 13);\n\t}\n\n\t// 默认\n\tpublic SnowflakeIdSequenceHandler() {\n\t\tthis(23, 13);\n\t}\n\n\t@Override\n\tpublic synchronized long nextId(String prefixName) {\n\t\tlong timestamp = this.timeGen();\n\t\tif (timestamp < this.lastTimestamp) {\n\t\t\tlogger.error(\n\t\t\t\t\t\"clock is moving backwards.  Rejecting requests until %d.\",\n\t\t\t\t\tlastTimestamp);\n\t\t\tthrow new RuntimeException(\n\t\t\t\t\tString.format(\n\t\t\t\t\t\t\t\"Clock moved backwards.  Refusing to generate id for %d milliseconds\",\n\t\t\t\t\t\t\t(this.lastTimestamp - timestamp)));\n\t\t}\n\t\tif (this.lastTimestamp == timestamp) {\n\t\t\tthis.sequence = this.sequence + 1 & this.sequenceMask;\n\t\t\tif (this.sequence == 0) {\n\t\t\t\ttimestamp = this.tilNextMillis(this.lastTimestamp);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.sequence = 0;\n\t\t}\n\n\t\tthis.lastTimestamp = timestamp;\n\t\treturn timestamp - this.twepoch << this.timestampLeftShift\n\t\t\t\t| this.datacenterId << this.datacenterIdShift\n\t\t\t\t| this.workerId << this.workerIdShift | this.sequence;\n\t}","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/MyCATApache/Mycat-Server/blob/65f8d8beb752f935752f2a0eec0ab017facab9ef/src/main/java/io/mycat/route/sequence/handler/SnowflakeIdSequenceHandler.java#L84-L120","documentation":"Snowflake ids embed the generation timestamp; generating an id with a clock older than the last used timestamp could produce duplicates. nextId() detects timestamp regression and throws a RuntimeException refusing id generation for the delta milliseconds until the clock catches back up.","triggerScenarios":"nextId() called when timeGen() returns a value less than lastTimestamp, i.e. the system clock was set backwards (NTP correction, VM snapshot rollback, manual time change).","commonSituations":"NTP stepping the clock back on a busy id-generating node; restoring a VM from a snapshot; container migrated to a host with an earlier clock.","solutions":["Wait the reported number of milliseconds until the clock passes lastTimestamp, then retry.","Ensure NTP uses gradual slewing instead of step changes on Mycat hosts.","Persist/restore lastTimestamp on restart to detect regressions; never roll back VM snapshots for id-issuing nodes.","If frequent, switch to the ZK-based or DB-based sequence which does not depend on wall-clock monotonicity."],"exampleFix":"// before\nlong id = handler.nextId(\"ORDERID\"); // throws after clock rollback\n// after\ntry {\n    long id = handler.nextId(\"ORDERID\");\n} catch (RuntimeException e) {\n    Thread.sleep(parseRefusalMs(e.getMessage())); // wait out the regression\n    long id = handler.nextId(\"ORDERID\");\n}","handlingStrategy":"retry","validationCode":"// caller-side check\nif (System.currentTimeMillis() < lastKnownTimestamp) { /* clock regression detected: pause id generation */ }","typeGuard":null,"tryCatchPattern":"try { id = handler.nextId(prefix); } catch (RuntimeException e) {\n    Thread.sleep(waitMsFromMessage(e.getMessage())); // wait out refusal window\n    id = handler.nextId(prefix);\n}","preventionTips":["Configure NTP with slewing, not stepping, on id-generating nodes","Avoid VM snapshot restores on id-issuing hosts","Monitor clock offsets (chrony/ntpd) and alert on regressions","Consider ZK/DB sequences where clock monotonicity cannot be guaranteed"],"tags":["java","snowflake","clock-skew","id-generation","ntp"],"backgroundTag":"clock-skew","analyzedSha":"65f8d8beb752f935752f2a0eec0ab017facab9ef","analyzedAt":"2026-09-11T00:12:21.696Z","contentChangedAt":"2026-09-11T00:12:21.696Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}