public synchronized QueryId createNextQueryId() {
    long now = nowInMillis();

    // restart counter if it is at the limit
    if (counter > 99_999) {
      // Wait for the timestamp to change to reset the counter to avoid duplicates
      // in the very unlikely case we generated all 100,000 in the previous second
      while (MILLISECONDS.toSeconds(now) == lastTimeInSeconds) {
        long delta = SECONDS.toMillis(lastTimeInSeconds + 1) - now;
        sleepUninterruptibly(delta, MILLISECONDS);
        now = nowInMillis();
      }
      counter = 0;
    }

    // if the second changed since the last ID was generated, generate a new timestamp
    if (MILLISECONDS.toSeconds(now) != lastTimeInSeconds) {
      // generate new timestamp
      lastTimeInSeconds = MILLISECONDS.toSeconds(now);
      lastTimestamp = formatEpochMilli(now);

      // if the day has rolled over, restart the counter
      if (MILLISECONDS.toDays(now) != lastTimeInDays) {
        lastTimeInDays = MILLISECONDS.toDays(now);
        counter = 0;
      }

      // restart the counter if it is close to the limit, to avoid sleep on rollover
      if (counter >= 90_000) {
        counter = 0;
      }
    }

    long index = counter;
    counter++;

    return new QueryId(format("%s_%05d_%s", lastTimestamp, index, dataNodeId));
  }
Generate next queryId using the following format: {@code yyyyMMdd_HHmmss_index_dataNodeId}

<p>{@code index} rolls at the start of every day or when it is close to reaching {@code
99,999}. {@code dataNodeId} is a unique id generated by config node when this data node is
created.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/QueryIdGenerator.java