Skip to content

NuCache corruption when block size set > 8192 #12103

Closed
@robertjf

Description

@robertjf

Which exact Umbraco version are you using? For example: 9.0.1 - don't just write v9

9.3.1

Bug summary

Firstly, this is a bug in the CSharpTest.Net.Collections dependency, described here in 2020:
csharptest/CSharpTest.Net.Collections#17
and has a PR which resolves it here:
csharptest/CSharpTest.Net.Collections#18

I've confirmed that the issue still exists in the Net20standard build that Umbraco depends on (https://github.com/mamift/CSharpTest.Net.Collections/) and I've submitted a PR on that repository, however Umbraco may want to consider taking on maintaining the library if mamift doesn't want to, the last update was back in 2019.

The reason this is such an issue is because of the Block Editor - I have a page with around 10 blocks of content in the block editor, the length of the serialised data attempting to be saved in the NuCache is 33,589,226 bytes. At a BlockSize of 8096 this failed with an invalid length error, and increasing to anything larger (e.g. 16384) was creating a corrupted localdb file.

Additionally, if the data being stored is too large for the default Block Size (512?) then a meaningful message should be logged to help the developer determine the reason and resolution.

Perhaps a Health Check can be created to assist with this?

The only work around currently is to disable the localDb generation altogether as per the documentation: https://our.umbraco.com/documentation/Reference/V9-Config/NuCacheSettings/#additional-settings

Specifics

Error message when Umbraco.CMS.NuCache.BTreeBlockSize <= 8192:

ArgumentOutOfRangeException: Specified argument was out of the range of valid values. (Parameter 'length')
CSharpTest.Net.IO.TransactedCompoundFile.Write(uint handle, byte[] bytes, int offset, int length)
CSharpTest.Net.Storage.BTreeFileStoreV2.Update<T>(IStorageHandle handleIn, ISerializer<T> serializer, T node)
CSharpTest.Net.Collections.BPlusTree<TKey, TValue>+NodeCacheBase.SaveChanges(NodePin pin)
CSharpTest.Net.Collections.BPlusTree<TKey, TValue>+NodeTransaction.PerformCommit()
CSharpTest.Net.Collections.BPlusTree<TKey, TValue>.Insert<T>(NodePin thisLock, TKey key, ref T value, NodePin parent, int parentIx)
CSharpTest.Net.Collections.BPlusTree<TKey, TValue>.Insert<T>(NodePin thisLock, TKey key, ref T value, NodePin parent, int parentIx)
CSharpTest.Net.Collections.BPlusTree<TKey, TValue>.Insert<T>(NodePin thisLock, TKey key, ref T value, NodePin parent, int parentIx)
CSharpTest.Net.Collections.BPlusTree<TKey, TValue>.Insert<T>(NodePin thisLock, TKey key, ref T value, NodePin parent, int parentIx)
CSharpTest.Net.Collections.BPlusTree<TKey, TValue>.AddEntry<T>(TKey key, ref T info)
Umbraco.Cms.Infrastructure.PublishedCache.ContentStore.Release(WriteLockInfo lockInfo, bool commit)
Umbraco.Cms.Infrastructure.PublishedCache.ContentStore+ScopedWriteLock.Release(bool completed)
Umbraco.Cms.Core.Scoping.ScopeContextualBase.Dispose()
Umbraco.Cms.Infrastructure.PublishedCache.PublishedSnapshotService.LockAndLoadContent(Func<bool> action)
Umbraco.Cms.Infrastructure.PublishedCache.PublishedSnapshotService.<EnsureCaches>b__47_0()

Error message when Umbraco.CMS.NuCache.BTreeBlockSize > 8192 (16384):

InvalidDataException: Found invalid data while decoding.
CSharpTest.Net.IO.TransactedCompoundFile+FileSection.Read(ref BlockRef block, bool headerOnly, FGet fget)
CSharpTest.Net.IO.TransactedCompoundFile.Read(uint handle)
CSharpTest.Net.Storage.BTreeFileStoreV2.TryGetNode<TNode>(IStorageHandle handleIn, out TNode node, ISerializer<TNode> serializer)
CSharpTest.Net.Collections.BPlusTree<TKey, TValue>+NodeCacheNone.Lock(NodePin parent, LockType ltype, NodeHandle child)
CSharpTest.Net.Collections.BPlusTree<TKey, TValue>.Insert<T>(NodePin thisLock, TKey key, ref T value, NodePin parent, int parentIx)
CSharpTest.Net.Collections.BPlusTree<TKey, TValue>.Insert<T>(NodePin thisLock, TKey key, ref T value, NodePin parent, int parentIx)
CSharpTest.Net.Collections.BPlusTree<TKey, TValue>.Insert<T>(NodePin thisLock, TKey key, ref T value, NodePin parent, int parentIx)
CSharpTest.Net.Collections.BPlusTree<TKey, TValue>.AddEntry<T>(TKey key, ref T info)
Umbraco.Cms.Infrastructure.PublishedCache.ContentStore.Release(WriteLockInfo lockInfo, bool commit)
Umbraco.Cms.Infrastructure.PublishedCache.ContentStore+ScopedWriteLock.Release(bool completed)
Umbraco.Cms.Core.Scoping.ScopeContextualBase.Dispose()
Umbraco.Cms.Infrastructure.PublishedCache.PublishedSnapshotService.LockAndLoadContent(Func<bool> action)
Umbraco.Cms.Infrastructure.PublishedCache.PublishedSnapshotService.<EnsureCaches>b__47_0()

Steps to reproduce

  1. Increase Umbraco.CMS.NuCache.BTreeBlockSize to 16384 in the appSettings.json file
  2. Generate enough content in a node to exceed a length of > 3 bytes (16,777,216) in the NuCache.

Expected result / actual result

NuCache should be populated successfully.

If the data is too large for NuCache, then a meaningful and helpful error should be logged instead of the default ArgumentOutOfRangeException.


This item has been added to our backlog AB#17823

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions