Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix UnbufferedFileStream.SetLength() bug #1930

Merged
merged 2 commits into from Jun 21, 2019

Conversation

@shaan1337
Copy link
Member

commented May 16, 2019

This is a critical bug that affects versions 4.1.0 up to 5.0.1

Prerequisites:

  • Unbuffered set to True in config

Symptoms:
The following fatal exception occurs when completing a chunk file (while writing the footer):

DEBUG TFChunk             ] Buffer size is 268423040

EXCEPTION OCCURRED
System.NotSupportedException: Unable to expand length of this stream beyond its capacity.
   at System.IO.UnmanagedMemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count)
   at EventStore.Core.TransactionLog.Chunks.TFChunk.TFChunk.WriteRawData(WriterWorkItem workItem, Byte[] buf, Int32 len) in TFChunk.cs

Subsequent restarts of the node show the following stack trace:

[PID:06428:001 2019.05.10 08:22:00.387 FATAL ProgramBase`1       ] Unhandled exception while starting application:
EXCEPTION OCCURRED
EventStore.Core.Exceptions.CorruptDatabaseException: Corrupt database detected. ---> EventStore.Core.Exceptions.InvalidFileException: Exception of type 'EventStore.Core.Exceptions.InvalidFileException' was thrown.
   --- End of inner exception stack trace ---

Root cause:
The position of an unbuffered file stream was wrongly being set to 0 when the stream was resized.
The bug was first triggered when this commit was introduced: d100bf2 due to this resize operation

Resolution:
Move the position to the end of the stream only if it has been truncated according to https://docs.microsoft.com/en-us/dotnet/api/system.io.filestream.setlength
If the given value is less than the current length of the stream, the stream is truncated. In this scenario, if the current position is greater than the new length, the current position is moved to the last byte of the stream. If the given value is larger than the current length of the stream, the stream is expanded, and the current position remains the same.

shaan1337 added some commits May 16, 2019

Bug fix: Wrong seek operation. Change the position of an unbuffered s…
…tream to the end of the stream only if it has been truncated past the original position.

@shaan1337 shaan1337 requested a review from jageall May 16, 2019

@shaan1337 shaan1337 requested a review from avish0694 Jun 18, 2019

@avish0694 avish0694 merged commit 50e9566 into master Jun 21, 2019

9 checks passed

EventStore.EventStore Build #20190528.4 succeeded
Details
EventStore.EventStore (Centos 7 x64 Debug) Centos 7 x64 Debug succeeded
Details
EventStore.EventStore (Centos 7 x64 Release) Centos 7 x64 Release succeeded
Details
EventStore.EventStore (Ubuntu 14.04 x64 Debug) Ubuntu 14.04 x64 Debug succeeded
Details
EventStore.EventStore (Ubuntu 14.04 x64 Release) Ubuntu 14.04 x64 Release succeeded
Details
EventStore.EventStore (Windows x64 Debug) Windows x64 Debug succeeded
Details
EventStore.EventStore (Windows x64 Release) Windows x64 Release succeeded
Details
EventStore.EventStore (macOS x64 Debug) macOS x64 Debug succeeded
Details
EventStore.EventStore (macOS x64 Release) macOS x64 Release succeeded
Details

@avish0694 avish0694 deleted the unbuffered-fix branch Jun 21, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.