Skip to content

Commit 810570e

Browse files
badrishcTedHartMS
andauthored
Tsavorite allocator - tighten the packing of pages (#657)
* Change allocator to enqueue with the invariant that the first record of page (p+1) does not fit at the end of page (p). This allows replication to independently replay records and guarantee that they fit on the log exactly in the same way as the primary. * fixes based on comments * add another comment * add comments * fixes - we now always wrap TryAllocate with TryAllocateRetryNow. * Add Non-readcache "Insert At Tail" stress test * support 0% mutable fraction. * Fix InernalUpsert srcRecordInfo setting when found below ReadOnlyAddress Add some comments * Adjust mutable-page counts in stress test * fix typo * Enforce at least two pages of memory. * nit * update Garnet to use new allocator logic * Fix * update low memory to meet new constraint * re-enable warning * handle comments * fix bitmap tests to use at least 2 pages of memory. * fix hll tests * more testcase fixes * fix replication logic to handle micro-skips within the same page * PageAlignedShiftHeadAddress should always keep the head address, well, aligned. * update version to 1.0.25 --------- Co-authored-by: TedHartMS <[email protected]>
1 parent 7d866da commit 810570e

22 files changed

+626
-273
lines changed

.azure/pipelines/azure-pipelines-external-release.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# 1) update the name: string below (line 6) -- this is the version for the nuget package (e.g. 1.0.0)
44
# 2) update \libs\host\GarnetServer.cs readonly string version (~line 53) -- NOTE - these two values need to be the same
55
######################################
6-
name: 1.0.24
6+
name: 1.0.25
77
trigger:
88
branches:
99
include:

libs/cluster/Server/Replication/PrimaryOps/AofTaskStore.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public AofTaskStore(ClusterProvider clusterProvider, int initialSize = 1, ILogge
4141
logPageSizeMask = logPageSize - 1;
4242
if (clusterProvider.serverOptions.MainMemoryReplication)
4343
clusterProvider.storeWrapper.appendOnlyFile.SafeTailShiftCallback = SafeTailShiftCallback;
44-
TruncateLagAddress = clusterProvider.storeWrapper.appendOnlyFile.UnsafeGetReadOnlyLagAddress() - 2 * logPageSize;
44+
TruncateLagAddress = clusterProvider.storeWrapper.appendOnlyFile.UnsafeGetReadOnlyAddressLagOffset() - 2 * logPageSize;
4545
}
4646
TruncatedUntil = 0;
4747
}

libs/cluster/Server/Replication/ReplicaOps/ReplicationReplicaAofSync.cs

+12-15
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,19 @@ public unsafe void ProcessPrimaryStream(byte* record, int recordLength, long pre
3838

3939
if (clusterProvider.serverOptions.MainMemoryReplication)
4040
{
41-
var firstRecordLength = GetFirstAofEntryLength(record);
42-
if (previousAddress > ReplicationOffset ||
43-
currentAddress >= previousAddress + firstRecordLength)
41+
// If the incoming AOF chunk fits in the space between previousAddress and currentAddress (ReplicationOffset),
42+
// an enqueue will result in an offset mismatch. So, we have to first reset the AOF to point to currentAddress.
43+
if (currentAddress > previousAddress)
4444
{
45-
logger?.LogWarning("MainMemoryReplication: Skipping from {ReplicaReplicationOffset} to {currentAddress}", ReplicationOffset, currentAddress);
46-
storeWrapper.appendOnlyFile.Initialize(currentAddress, currentAddress);
47-
ReplicationOffset = currentAddress;
45+
if (
46+
(currentAddress % (1 << storeWrapper.appendOnlyFile.UnsafeGetLogPageSizeBits()) != 0) || // the skip was to a non-page-boundary
47+
(currentAddress >= previousAddress + recordLength) // the skip will not be auto-handled by the AOF enqueue
48+
)
49+
{
50+
logger?.LogWarning("MainMemoryReplication: Skipping from {ReplicaReplicationOffset} to {currentAddress}", ReplicationOffset, currentAddress);
51+
storeWrapper.appendOnlyFile.Initialize(currentAddress, currentAddress);
52+
ReplicationOffset = currentAddress;
53+
}
4854
}
4955
}
5056

@@ -56,15 +62,6 @@ public unsafe void ProcessPrimaryStream(byte* record, int recordLength, long pre
5662
throw new GarnetException($"Before ProcessPrimaryStream: Replication offset mismatch: ReplicaReplicationOffset {ReplicationOffset}, aof.TailAddress {storeWrapper.appendOnlyFile.TailAddress}", LogLevel.Warning, clientResponse: false);
5763
}
5864

59-
// If there is a gap between the local tail and incoming currentAddress, try to skip local AOF to the next page
60-
if (currentAddress >= storeWrapper.appendOnlyFile.TailAddress + recordLength
61-
&& storeWrapper.appendOnlyFile.GetPage(currentAddress) == storeWrapper.appendOnlyFile.GetPage(storeWrapper.appendOnlyFile.TailAddress) + 1)
62-
{
63-
logger?.LogWarning("SkipPage from {previousAddress} to {currentAddress}, tail is {tailAddress}", previousAddress, currentAddress, storeWrapper.appendOnlyFile.TailAddress);
64-
storeWrapper.appendOnlyFile.UnsafeSkipPage();
65-
logger?.LogWarning("New tail after SkipPage is {tailAddress}", storeWrapper.appendOnlyFile.TailAddress);
66-
}
67-
6865
// Enqueue to AOF
6966
_ = clusterProvider.storeWrapper.appendOnlyFile?.UnsafeEnqueueRaw(new Span<byte>(record, recordLength), noCommit: clusterProvider.serverOptions.EnableFastCommit);
7067

libs/host/GarnetServer.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public class GarnetServer : IDisposable
4949
protected StoreWrapper storeWrapper;
5050

5151
// IMPORTANT: Keep the version in sync with .azure\pipelines\azure-pipelines-external-release.yml line ~6.
52-
readonly string version = "1.0.24";
52+
readonly string version = "1.0.25";
5353

5454
/// <summary>
5555
/// Resp protocol version

libs/server/Resp/RespServerSession.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ private void ProcessMessages()
432432
}
433433
else
434434
{
435-
if (CanServeSlot(cmd))
435+
if (clusterSession == null || CanServeSlot(cmd))
436436
_ = ProcessBasicCommands(cmd, ref basicGarnetApi);
437437
}
438438
}

libs/server/Resp/RespServerSessionSlotVerify.cs

+2-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the MIT license.
33

44
using System;
5+
using System.Diagnostics;
56
using Garnet.common;
67

78
namespace Garnet.server
@@ -33,9 +34,7 @@ bool NetworkKeyArraySlotVerify(Span<ArgSlice> keys, bool readOnly, int count = -
3334

3435
bool CanServeSlot(RespCommand cmd)
3536
{
36-
// If cluster is disable all commands
37-
if (clusterSession == null)
38-
return true;
37+
Debug.Assert(clusterSession != null);
3938

4039
// Verify slot for command if it falls into data command category
4140
if (!cmd.IsDataCommand())

0 commit comments

Comments
 (0)