LostSnowfluff opened a new issue, #11013:
URL: https://github.com/apache/rocketmq/issues/11013

   ### Before Creating the Bug Report
   
   - [x] I found a bug, not just asking a question, which should be created in 
[GitHub Discussions](https://github.com/apache/rocketmq/discussions).
   
   - [x] I have searched the [GitHub 
Issues](https://github.com/apache/rocketmq/issues) and [GitHub 
Discussions](https://github.com/apache/rocketmq/discussions)  of this 
repository and believe that this is not a duplicate.
   
   - [x] I have confirmed that this bug belongs to the current repository, not 
other repositories of RocketMQ.
   
   
   ### Runtime platform environment
   
   Ubuntu 22.04.5 LTS, Linux x86_64.
   
   ### RocketMQ version
   
   Branch: `develop`  
   Version: `5.5.1`  
   Git commit id: `e90303810a14`
   
   ### JDK Version
   
   OpenJDK 8u502.
   
   ### Describe the Bug
   
   `MessageRocksDBStorage` creates a `ScheduledExecutorService` and registers a
   periodic timer-WAL flush task in `postLoad()`:
   
   ```java
   private final ScheduledExecutorService scheduler =
       Executors.newScheduledThreadPool(1);
   
   scheduler.scheduleAtFixedRate(this::flushTimerWal, 5, 5, TimeUnit.MINUTES);
   ```
   
   However, `preShutdown()` does not cancel the scheduled task or shut down the
   scheduler. `AbstractRocksDBStorage.reloadRocksdb()` uses the existing
   `shutdown()` followed by `start()` lifecycle. Because the same scheduler
   remains active, every successful reload registers another periodic flush task
   on the same executor.
   
   This also leaves a non-daemon scheduler and its delayed task alive after the
   RocksDB resources have been closed.
   
   ### Steps to Reproduce
   
   1. Create a `MessageRocksDBStorage` with a temporary `MessageStoreConfig`.
   2. Inspect its private scheduler as a `ScheduledThreadPoolExecutor` using a
      focused test or debugger. After construction, one periodic task is queued.
   3. Call `storage.shutdown()`.
   4. Inspect the scheduler again and observe that it is not shut down and that
      its queue still contains one periodic task.
   5. Call `storage.start()` to simulate the lifecycle used by
      `AbstractRocksDBStorage.reloadRocksdb()`.
   6. Call `storage.shutdown()` and `storage.start()` once more.
   7. Inspect the scheduler after each start.
   
   The affected code shows the following stable state transition:
   
   | Lifecycle state | Scheduler state | Queued periodic tasks |
   | --- | --- | ---: |
   | After construction | active | 1 |
   | After first shutdown | not shut down | 1 |
   | After first start | active | 2 |
   | After second shutdown | not shut down | 2 |
   | After second start | active | 3 |
   
   ### What Did You Expect to See?
   
   - `storage.shutdown()` should cancel the periodic timer-WAL flush task and
     shut down its scheduler.
   - Each subsequent `start()` should create one scheduler with exactly one
     periodic flush task.
   - A scheduled task should not access RocksDB resources after they have been
     closed.
   
   ### What Did You See Instead?
   
   - The scheduler remains active after `storage.shutdown()`.
   - The delayed periodic task remains queued after the RocksDB instance and its
     options have been closed.
   - Each shutdown/start reload adds another periodic flush task to the same
     executor.
   - The scheduled runnable directly accesses `db`, `flushOptions`, and
     `timerCFHandle` without a lifecycle guard. If it runs during shutdown, it 
can
     access resources that are being closed or have already been cleared.
   
   ### Additional Context
   
   _No response_


-- 
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