You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
eloqkv2rdb: exported values silently corrupted — int32_t narrowing of numeric strings, TTL ms→s truncation, zset score precision loss #494
Three data-fidelity bugs in the offline RDB exporter (src/tools/eloqkv2rdb/eloqkv2rdb.cpp):
1. Numeric strings narrowed through int32_t (data corruption)
RedisRdbUtil::OutputString (~line 139):
if (std::regex_match(s, number_pattern))
{
int32_t n = std::stol(s); // <-- narrowing
...
elseif (n >= -2147483648 && n <= 2147483647) // always true for int32_t
Digit strings between 2^31 and 2^63 (10–19 digits, e.g. a user ID "9876543210") wrap on the long → int32_t conversion and are emitted as a different INT32-encoded value — silent corruption in the exported RDB.
Digit strings ≥ 20 chars make std::stol throw std::out_of_range, uncaught in worker threads → crash.
Fix: parse into int64_t, fall through to raw-string encoding when the value exceeds the INT32 range (matching Redis rdbTryIntegerEncoding), and catch/route parse failures to the string path.
2. TTL truncated from milliseconds to seconds
OutputTTL (~line 230) emits a second-resolution EXPIRETIME (uint32_t expire = ttl / 1000). Redis RDB supports millisecond expiry (0xFC, 8-byte ms). Sub-second precision is lost on every exported key.
3. zset score precision loss
Line ~352 serializes scores with OutputString(std::to_string(score)) — std::to_string(double) formats with 6 fixed decimals, so scores that need full double precision (or large magnitudes) round-trip incorrectly. Use %.17g (or RDB binary score encoding) instead.
Impact
Exports used for migration produce silently wrong data: corrupted numeric values, shifted expiry, rounded scores.
Found during the module-docs review (#492); see docs/07-persistence-and-tools.md Gotchas.
Activity