diff --git a/libs/server/Resp/Vector/VectorManager.cs b/libs/server/Resp/Vector/VectorManager.cs index 6e8b34da4c0..92cd60e33ee 100644 --- a/libs/server/Resp/Vector/VectorManager.cs +++ b/libs/server/Resp/Vector/VectorManager.cs @@ -40,8 +40,8 @@ public sealed partial class VectorManager : IDisposable internal const int IndexSizeBytes = Index.Size; internal const long VADDAppendLogArg = long.MinValue; - internal const long DeleteAfterDropArg = VADDAppendLogArg + 1; - internal const long RecreateIndexArg = DeleteAfterDropArg + 1; + // DeleteAfterDropArg used to be here + internal const long RecreateIndexArg = VADDAppendLogArg + 2; internal const long VREMAppendLogArg = RecreateIndexArg + 1; internal const long MigrateElementKeyLogArg = VREMAppendLogArg + 1; internal const long MigrateIndexKeyLogArg = MigrateElementKeyLogArg + 1; diff --git a/libs/server/Storage/Functions/MainStore/RMWMethods.cs b/libs/server/Storage/Functions/MainStore/RMWMethods.cs index 56dba7fa1f8..f64c7da7791 100644 --- a/libs/server/Storage/Functions/MainStore/RMWMethods.cs +++ b/libs/server/Storage/Functions/MainStore/RMWMethods.cs @@ -812,20 +812,15 @@ private readonly IPUResult InPlaceUpdaterWorker(ref LogRecord logRecord, ref Str case RespCommand.VADD: // Adding to an existing VectorSet is modeled as a read operations // - // However, we do synthesize some (pointless) writes to implement replication - // and a "make me delete=able"-update during drop. + // However, we do synthesize some (pointless) writes to implement replication (which we ignore here). // // Another "not quite write" is the recreate an index write operation // that occurs if we're adding to an index that was restored from disk // or a primary node. - // Handle "make me delete-able" - if (input.arg1 == VectorManager.DeleteAfterDropArg) - { - logRecord.ValueSpan.Clear(); - } - else if (input.arg1 == VectorManager.RecreateIndexArg) + if (input.arg1 == VectorManager.RecreateIndexArg) { + // Recreate index var newIndexPtr = MemoryMarshal.Read(input.parseState.GetArgSliceByRef(11).Span); functionsState.vectorManager.RecreateIndex(newIndexPtr, logRecord.ValueSpan); @@ -1327,19 +1322,20 @@ public readonly bool CopyUpdater(in TSourceLogRecord srcLogRec break; case RespCommand.VADD: - // Handle "make me delete-able" - if (input.arg1 == VectorManager.DeleteAfterDropArg) - { - dstLogRecord.ValueSpan.Clear(); - } - else if (input.arg1 == VectorManager.RecreateIndexArg) + if (input.arg1 == VectorManager.RecreateIndexArg) { + // Recreate index var newIndexPtr = MemoryMarshal.Read(input.parseState.GetArgSliceByRef(11).Span); oldValue.CopyTo(dstLogRecord.ValueSpan); functionsState.vectorManager.RecreateIndex(newIndexPtr, dstLogRecord.ValueSpan); } + else if (input.arg1 is VectorManager.VADDAppendLogArg or VectorManager.VREMAppendLogArg) + { + // VADD has triggered a CU of the index key - we want to do nothing but we have to copy to prevent corruption + oldValue.CopyTo(dstLogRecord.ValueSpan); + } break; diff --git a/libs/server/Storage/Functions/MainStore/VarLenInputMethods.cs b/libs/server/Storage/Functions/MainStore/VarLenInputMethods.cs index 0b2a0a02ec3..dfba68e0b6e 100644 --- a/libs/server/Storage/Functions/MainStore/VarLenInputMethods.cs +++ b/libs/server/Storage/Functions/MainStore/VarLenInputMethods.cs @@ -361,6 +361,12 @@ public RecordFieldInfo GetRMWModifiedFieldInfo(in TSourceLogRe case RespCommand.VADD: case RespCommand.VREM: + if (input.arg1 is VectorManager.VADDAppendLogArg or VectorManager.VREMAppendLogArg) + { + // During replication we might trigger a CU, in which case... make sure there's space for the index we'll copy over + fieldInfo.ValueSize = VectorManager.IndexSize; + } + return fieldInfo; default: