MyCATApache/Mycat-Server · critical · RuntimeException
can't fetch sequnce in db,sequnce
Error message
can't fetch sequnce in db,sequnce :{seqName} detail:{lastestError} What it means
IncrSequenceMySQLHandler.getSeqValueFromDB delegates to SequenceVal.fetchSequenceFromDB to load the next sequence segment from MySQL; a single thread enters with retry logic built in. If the fetch still returns null after retries, the handler throws this RuntimeException, appending the sequence name and the last recorded error from the MySQL fetcher. It means MyCat could not obtain a new ID segment from the database and cannot hand out IDs.
Solutions
- Inspect the detail appended in the message (mysqlSeqFetcher.getLastestError) and fix the root cause — typically connectivity, credentials, or SQL errors against the sequence DB.
- Verify the sequence table and the row for seqName exist and are readable by MyCat's configured sequence datasource.
- Restore/restart the MySQL backend and check network/firewall between MyCat and the DB, then retry ID generation.
- Monitor DB load and tune timeouts/retries so transient lock waits don't exhaust the fetch attempts.
Example fix
// before
long id = handler.nextId("ORDER_SEQ"); // RuntimeException: can't fetch sequnce in db
// after
-- on the sequence DB: ensure definition exists and is reachable
SELECT * FROM MYCAT_SEQUENCE WHERE name = 'ORDER_SEQ';
GRANT SELECT, UPDATE ON mycat.* TO 'mycat_seq_user'@'%'; Defensive patterns
Strategy: retry
Validate before calling
public static boolean canFetchSequence(DataSource ds, String seqName) {
try (Connection c = ds.getConnection(); PreparedStatement ps =
c.prepareStatement("SELECT current_value, increment FROM MYCAT_SEQUENCE WHERE name = ?")) {
ps.setString(1, seqName);
try (ResultSet rs = ps.executeQuery()) { return rs.next(); }
} catch (SQLException e) { return false; }
} Try / catch
try {
long id = handler.nextId(seqName);
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().startsWith("can't fetch sequnce in db")) {
if (!canFetchSequence(seqDataSource, seqName)) {
throw new SequenceBackendUnavailableException(seqName, e); // fail fast, don't hot-loop
}
return handler.nextId(seqName); // backend healthy again: bounded retry
}
throw e;
} Prevention
- Monitor the sequence MySQL backend (health checks on connection and the sequence table).
- Grant the MyCat sequence user the required SELECT/UPDATE privileges on the sequence table.
- Keep the built-in retry budget small and fail fast when the DB is down instead of recursing indefinitely.
- Alert on repeated segment-fetch failures so the backend is fixed before ID generation exhausts in-memory segments.
When it happens
Trigger: Calling nextId (directly or via getNextValidSeqVal or recursion) when fetchSequenceFromDB(mysqlSeqFetcher, 1, true) returns null — i.e. the SELECT on the sequence table repeatedly fails (connection error, missing table, lock timeout, malformed sequence row).
Common situations: MySQL backend for sequences down or unreachable from MyCat; MYCAT_SEQUENCE table missing/dropped or row deleted; insufficient DB privileges for the MyCat sequence user; network timeouts under load exhausting the built-in retries.
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
- fetch Param Values error.
- SelfCheck### there are some datasource connection failed…
- can't find definition for sequence
- fetching sequence can not support the db driver
- sequnce not found in db table
AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11).
Data as JSON: /api/errors/b3fcb83a6f802f7e.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/io/mycat/route/sequence/handler/IncrSequenceMySQLHandler.java:143
LOGGER.debug("get next segement of sequence from db for sequnce:"
+ seqVal.seqName + " curVal " + seqVal.curVal);
}
//设置正在获取
boolean isLock = seqVal.fetching.compareAndSet(false, true);
if(isLock) {
//判断当前的是否有效。
if(seqVal.successFetched == true) {
Long nexVal = seqVal.nextValue();
if (seqVal.isNexValValid(nexVal)) {
seqVal.fetching.compareAndSet(true, false);
return nexVal;
}
}
//发起请求sql 等待到返回 或者进行
Long[] values = seqVal.fetchSequenceFromDB( mysqlSeqFetcher, 1, true); //只有一个线程可以进 并且有重试机制。
if (values == null) {
throw new RuntimeException("can't fetch sequnce in db,sequnce :"
+ seqVal.seqName + " detail:"
+ mysqlSeqFetcher.getLastestError(seqVal.seqName));
} else {
seqVal.setCurValue(values[0]);
seqVal.maxSegValue = values[1];
seqVal.successFetched = true; //设置successFetched
return values[0];
}
} else {
long count = 0 ;
//正在获取 ,或者还未返回
while(seqVal.fetching.get() || seqVal.successFetched == false){
try {
Thread.sleep(10);
if(++count > 10000L) {
return this.getSeqValueFromDB(seqVal);
}View on GitHub (pinned to 65f8d8beb7)