Reject max_replicated_logs_to_keep = 0
The setting is documented as accepting any positive integer, but it had no lower bound, so 0 was accepted. With 0 the cleanup thread indexed entries with entries.size(), one past the end, and libc++ hardening turns that into an abort in release builds as well: cmake/cxx.cmake sets _LIBCPP_HARDENING_MODE_FAST for every non-debug build, and vector::operator[] is guarded there by _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS. The caller is a background thread, so the process aborts rather than one query failing. Reject the value in MergeTreeSettingsImpl::sanityCheck, next to the existing index_granularity bound. That covers CREATE TABLE and ALTER TABLE ... MODIFY SETTING, the two paths that call it. The clamp in the cleanup thread stays, because settings are not checked when a table is loaded from metadata that already exists: MergeTreeData calls sanityCheck only for LoadingStrictnessLevel::CREATE, so ATTACH, server startup (FORCE_ATTACH), RESTORE and the secondary CREATE of a Replicated database (SECONDARY_CREATE) all skip it. A table created by an older server keeps its value and still reaches the log threshold computation with 0. The test asserts both halves: the value is rejected on CREATE and on ALTER, and the cleanup thread trims /log for a table that carries 0 in through an ATTACH with a full definition. Reverting only the clamp makes that ATTACH path abort the server with "vector[] index out of bounds" in clearOldLogs, which is the signature the fuzzer reported.
G
Groene AI committed
34543f5f77d4c26c5bebf747d41d32c66b251d26
Parent: 3bbddc8