mirror of
https://github.com/dragonflydb/dragonfly.git
synced 2025-05-10 18:05:44 +02:00
fix(hset_family): Fix val being overwritten by TTL (#5094)
When hset is loaded from rdb, if a ttl is specified by the user, the code recreates a string_view on top of the same memory location, tset_blob_, that was used for val earlier. This causes the val string view to point to the same value now as TTL has. For example if the val string view was 'x' earlier (points to tset_blob_, size 1), and ttl is 7777777, val now becomes '7'. To fix this val is now given it's own string. TTL is kept as string view as the pointer is not reused anywhere in the following loop. Signed-off-by: Abhijat Malviya <abhijat@dragonflydb.io>
This commit is contained in:
parent
8ce8ee68df
commit
e341819256
2 changed files with 31 additions and 15 deletions
|
@ -482,11 +482,12 @@ void RdbLoaderBase::OpaqueObjLoader::CreateHMap(const LoadTrace* ltrace) {
|
|||
}
|
||||
});
|
||||
std::string key;
|
||||
std::string val;
|
||||
for (size_t i = 0; i < ltrace->arr.size(); i += increment) {
|
||||
// ToSV may reference an internal buffer, therefore we can use only before the
|
||||
// next call to ToSV. To workaround, copy the key locally.
|
||||
key = ToSV(ltrace->arr[i].rdb_var);
|
||||
string_view val = ToSV(ltrace->arr[i + 1].rdb_var);
|
||||
val = ToSV(ltrace->arr[i + 1].rdb_var);
|
||||
|
||||
if (ec_)
|
||||
return;
|
||||
|
|
|
@ -1,23 +1,18 @@
|
|||
import random
|
||||
|
||||
from itertools import chain, repeat
|
||||
import re
|
||||
import pytest
|
||||
import asyncio
|
||||
import async_timeout
|
||||
import platform
|
||||
import pymemcache
|
||||
import logging
|
||||
import shutil
|
||||
import tarfile
|
||||
import urllib.request
|
||||
import shutil
|
||||
from redis import asyncio as aioredis
|
||||
from .utility import *
|
||||
from .instance import DflyInstanceFactory, DflyInstance
|
||||
from .seeder import Seeder as SeederV2
|
||||
from itertools import chain, repeat
|
||||
|
||||
import async_timeout
|
||||
import pymemcache
|
||||
|
||||
from . import dfly_args
|
||||
from .instance import DflyInstanceFactory, DflyInstance
|
||||
from .proxy import Proxy
|
||||
from .seeder import DebugPopulateSeeder
|
||||
from .seeder import Seeder as SeederV2
|
||||
from .utility import *
|
||||
|
||||
ADMIN_PORT = 1211
|
||||
|
||||
|
@ -3115,3 +3110,23 @@ async def test_partial_replication_on_same_source_master(df_factory, use_takeove
|
|||
lines = replica2.find_in_logs(f"Started full with localhost:{replica1.port}")
|
||||
assert len(lines) == 0
|
||||
assert len(replica1.find_in_logs("No partial sync due to diff")) > 0
|
||||
|
||||
|
||||
async def test_replicate_hset_with_expiry(df_factory: DflyInstanceFactory):
|
||||
master = df_factory.create(proactor_threads=2)
|
||||
replica = df_factory.create(proactor_threads=2)
|
||||
|
||||
master.start()
|
||||
replica.start()
|
||||
|
||||
cm = master.client()
|
||||
await cm.execute_command("HSETEX key 86400 name 1234")
|
||||
|
||||
cr = replica.client()
|
||||
await cr.execute_command(f"REPLICAOF localhost {master.port}")
|
||||
await wait_available_async(cr)
|
||||
|
||||
result = await cr.hgetall("key")
|
||||
|
||||
assert "name" in result
|
||||
assert result["name"] == "1234"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue