When I queried `system.metrics` table, I found some negative values which hint to some potential internal overflows.

```
SELECT *
FROM system.metrics
FORMAT Vertical

...

Row 31:
───────
metric:      MemoryTrackingInBackgroundProcessingPool
value:       -580863171
description: Total amount of memory (bytes) allocated in background processing pool (that is dedicated for backround merges, mutations and fetches). Note that this value may include a drift when the memory was allocated in a context of background processing pool and freed in other context or vice-versa. This happens naturally due to caches for tables indexes and doesn't indicate memory leaks.

Row 32:
───────
metric:      MemoryTrackingInBackgroundMoveProcessingPool
value:       0
description: Total amount of memory (bytes) allocated in background processing pool (that is dedicated for backround moves). Note that this value may include a drift when the memory was allocated in a context of background processing pool and freed in other context or vice-versa. This happens naturally due to caches for tables indexes and doesn't indicate memory leaks.

Row 33:
───────
metric:      MemoryTrackingInBackgroundSchedulePool
value:       -4461308831
description: Total amount of memory (bytes) allocated in background schedule pool (that is dedicated for bookkeeping tasks of Replicated tables).

...

56 rows in set. Elapsed: 0.003 sec.
```

Server version: 20.8.2.3.
{
            SipHash hash;
            hash.update(key.first);
            hash.update(key.second);
            return hash.get64();
        }
    };
    
    using Container = std::unordered_map<Key, std::shared_ptr<NamedSession>, SessionKeyHash>;
    using CloseTimes = std::deque<std::vector<Key>>;
    Container sessions;
    CloseTimes close_times;
    std::chrono::steady_clock::duration close_interval = std::chrono::seconds(1);
    std::chrono::steady_clock::time_point close_cycle_time = std::chrono::steady_clock::now();
    UInt64 close_cycle = 0;
    void scheduleCloseSession(NamedSession & session, std::unique_lock<std::mutex> &)
    {
        
        
        const UInt64 close_index = session.timeout / close_interval + 1;
        const auto new_close_cycle = close_cycle + close_index;
        if (session.close_cycle != new_close_cycle)
        {
            session.close_cycle = new_close_cycle;
            if (close_times.size() < close_index + 1)
                close_times.resize(close_index + 1);
            close_times[close_index].emplace_back(session.key);
        }
    }
    void cleanThread()