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

SubscribeToAllFiltered delivers log positions with prepare value 0 #3989

Open
ahjohannessen opened this issue Oct 11, 2023 · 14 comments
Open
Labels
kind/bug Issues which are a software defect linear

Comments

@ahjohannessen
Copy link
Contributor

ahjohannessen commented Oct 11, 2023

Describe the bug
When I subscribe to all stream with filter I get a lot of checkpoints with prepare value being 0.
An example output using 23.6.0-alpha.184-focal:

ReadResp(Confirmation(SubscriptionConfirmation(c2ffb591-41a2-4662-a6e2-155744d67fff,UnknownFieldSet(Map()))),UnknownFieldSet(Map()))
ReadResp(Checkpoint(Checkpoint(15465,0,UnknownFieldSet(Map()))),UnknownFieldSet(Map()))
ReadResp(Checkpoint(Checkpoint(36609,0,UnknownFieldSet(Map()))),UnknownFieldSet(Map()))
ReadResp(Checkpoint(Checkpoint(58593,0,UnknownFieldSet(Map()))),UnknownFieldSet(Map()))
ReadResp(Checkpoint(Checkpoint(83772,0,UnknownFieldSet(Map()))),UnknownFieldSet(Map()))
ReadResp(Checkpoint(Checkpoint(106874,0,UnknownFieldSet(Map()))),UnknownFieldSet(Map()))
ReadResp(Checkpoint(Checkpoint(126266,0,UnknownFieldSet(Map()))),UnknownFieldSet(Map()))
ReadResp(Checkpoint(Checkpoint(147770,0,UnknownFieldSet(Map()))),UnknownFieldSet(Map()))
ReadResp(Checkpoint(Checkpoint(173190,0,UnknownFieldSet(Map()))),UnknownFieldSet(Map()))
ReadResp(Checkpoint(Checkpoint(196596,0,UnknownFieldSet(Map()))),UnknownFieldSet(Map()))
ReadResp(Checkpoint(Checkpoint(216468,0,UnknownFieldSet(Map()))),UnknownFieldSet(Map()))
ReadResp(Checkpoint(Checkpoint(237204,0,UnknownFieldSet(Map()))),UnknownFieldSet(Map()))
ReadResp(Checkpoint(Checkpoint(262869,0,UnknownFieldSet(Map()))),UnknownFieldSet(Map()))
ReadResp(Checkpoint(Checkpoint(291897,0,UnknownFieldSet(Map()))),UnknownFieldSet(Map()))
ReadResp(Checkpoint(Checkpoint(312085,0,UnknownFieldSet(Map()))),UnknownFieldSet(Map()))
ReadResp(CaughtUp(CaughtUp(UnknownFieldSet(Map()))),UnknownFieldSet(Map()))
ReadResp(Checkpoint(Checkpoint(344091,344091,UnknownFieldSet(Map()))),UnknownFieldSet(Map()))

It is not until after the CaughtUp message above we see a log position with commit and prepare being equal.
Similar behavior is on other tested versions except the caught up message.

To Reproduce
Subscribe to all stream with a prefix filter and output messages from ESDB in order to see the checkpoint values. Turn on debug on server as well.

Expected behavior
I am not sure what the expected behavior should be. I would expect log positions with equal prepare and commit values. But if it is expected to use log positions with values like C:216468/:P0 then I suppose this issue can be closed. Just want to be certain.

Actual behavior
Lots of log positions with prepare value being 0.

EventStore details

  • EventStore server version:
    • 23.6.0-alpha.184-focal
    • 22.10.3
    • 21.10.9
  • Operating system: Docker images

DB-487

@ahjohannessen ahjohannessen added the kind/bug Issues which are a software defect label Oct 11, 2023
@alexeyzimarev
Copy link
Member

It looks weird, but I don't think there's a real issue there. In 99.9% of cases, commit position is the only one you want. Prepare position can only be different if you use explicit transactions, and it's a very marginal, as well as very questionable feature, which we might remove at some point.

@ahjohannessen
Copy link
Contributor Author

@alexeyzimarev It seems a bit meaningless to filter out checkpoints with commit != prepare and prepare == 0 as the majority of the checkpoints have prepare == 0 until caughtup. Especially, If I have 10 millions events and the events that my filter predicates true are in the last 1000.

@ahjohannessen
Copy link
Contributor Author

ahjohannessen commented Oct 11, 2023

@alexeyzimarev It might be that I used too few events for my testing and the log positions with prepare 0 I see is from esdb internal events or something like that. I will investigate this further with more data.

Edit: Seems like it is not just in the beginning I get prepare == 0. In another run when writing more events, I see:

Checkpoint(Exact(1279622,1279622))
...
Checkpoint(Exact(1294333,0))
Checkpoint(Exact(1313437,0))
Checkpoint(Exact(1332541,0))
Checkpoint(Exact(1351645,0))
Checkpoint(Exact(1370749,0))
Checkpoint(Exact(1389853,0))
Checkpoint(Exact(1408957,0))
Checkpoint(Exact(1428061,0))
Checkpoint(Exact(1447165,0))
Checkpoint(Exact(1466269,0))
Checkpoint(Exact(1485373,0))
Checkpoint(Exact(1504477,0))
Checkpoint(Exact(1523581,0))
Checkpoint(Exact(1542685,0))
Checkpoint(Exact(1561789,0))
Checkpoint(Exact(1580893,0))
Checkpoint(Exact(1599997,0))
Checkpoint(Exact(1619101,0))
Checkpoint(Exact(1638205,0))
Checkpoint(Exact(1657309,0))
Checkpoint(Exact(1676413,0))
Checkpoint(Exact(1695517,0))
Checkpoint(Exact(1714621,0))
Checkpoint(Exact(1733725,0))
Checkpoint(Exact(1752829,0))
Checkpoint(Exact(1771933,0))
Checkpoint(Exact(1791037,0))
Checkpoint(Exact(1810141,0))
Checkpoint(Exact(1829245,0))
Checkpoint(Exact(1848349,0))
Checkpoint(Exact(1867453,0))
Checkpoint(Exact(1886557,0))
Checkpoint(Exact(1905661,0))
Checkpoint(Exact(1924765,0))
Checkpoint(Exact(1943869,0))
Checkpoint(Exact(1962973,0))
Checkpoint(Exact(1982077,0))
Checkpoint(Exact(2001181,0))
Checkpoint(Exact(2020285,0))
Checkpoint(Exact(2039389,0))
Checkpoint(Exact(2058493,0))
Checkpoint(Exact(2080781,0))
Checkpoint(Exact(2106146,2106146))
...
Checkpoint(Exact(2135084,2135084))

@alexeyzimarev
Copy link
Member

I still don't understand why are you interested in prepare position. My reply was about that.

@ahjohannessen
Copy link
Contributor Author

ahjohannessen commented Oct 12, 2023

I still don't understand why are you interested in prepare position. My reply was about that.

I am not interested in it per say, I wanted to know the reason for getting checkpoints where prepare is 0 (I am not using transactions) and if storing log positions where prepare equals 0 in read model db is expected of SubscribeToAllFiltered consumers.

@timothycoleman
Copy link
Contributor

I'm curious about this too. It seems it originates here

91f929b#diff-0a8d496f35c459188e6f3669d71414e3fefa57e162ccfac14a2c5692079e47afR86

but it is quite likely that there isnt a need for the 0 any longer, I'll give this some thought.

Aside from being mysterious, this should work fine as a checkpoint to persist and continue the reads or subscription from later

@ahjohannessen
Copy link
Contributor Author

Aside from being mysterious, this should work fine as a checkpoint to persist and continue the reads or subscription from later

This is what I was fishing a bit for. According to the commit message it should be safe to use prepare with 0:

It is safe to use 0 as the prepare position for a position returned from
a committed prepare in this case as we use the provided commit position
to move the reader to where we will be reading from an upon reading a
commit, we will use the transaction position to adjust the reader
position, however we still use the provided position to validate
whether the prepare is one we actually care about.

So, I'll go with prepares with 0 returned from SubscribeToAllFiltered as valid positions.

@timothycoleman You are welcome to close this, but I am curious about what you are going to do with this.

@ylorph ylorph added the linear label Nov 6, 2023
@alexeyzimarev
Copy link
Member

Concerning the expected behaviour, unless you are doing explicit transactions (which are only available via the old client), the commit and prepare positions will always be the same. I don't think it's a big issue. Do you have events appended using explicit transactions in the database?

@ahjohannessen
Copy link
Contributor Author

ahjohannessen commented Nov 14, 2023

Concerning the expected behaviour, unless you are doing explicit transactions (which are only available via the old client), the commit and prepare positions will always be the same. I don't think it's a big issue. Do you have events appended using explicit transactions in the database?

I am not appending with explicit transactions and I get commit and prepare versions with different values as stated earlier:

I am not interested in it per say, I wanted to know the reason for getting checkpoints where prepare is 0 (I am not using transactions)

@alexeyzimarev
Copy link
Member

I mean, we realise it is weird, and it can be fixed. My thoughts were more around the issue importance. Right now, it doesn't seem to be creating any problems, so we don't plan fixing it right now. Unless, of course, you actually have a problem. That's what I am trying to clarify :)

@ahjohannessen
Copy link
Contributor Author

ahjohannessen commented Nov 16, 2023

I do not have any actual problem with that as long it is expected that clients can get checkpoints with prepare values with 0.

I am just curious about how the eventstore event / index reader behaves when it gets a log position with prepare values that are 0 compared to values where commit and prepare are the same.

I probably just update my client to ignore checkpoints with 0 based prepare values because I am not any wiser about semantics.

@alexeyzimarev
Copy link
Member

You can always use the position composed from the commit position value you received, and prepare position set to the same value as the commit position. Unless you are using explicit transactions, they are both the same.

@ahjohannessen
Copy link
Contributor Author

Unless you are using explicit transactions, they are both the same.

This seems not to be the case. I am not using transactions and I get those prepares with 0. So what you are saying is not true. Anyway, feel free to close this.

@alexeyzimarev
Copy link
Member

What I meant that in the log those positions are the same, and there's no need to explicitly provide prepare position that is different from commit position. Prepare position is never null. Consider getting zero value as an indicator of prepare position being the same as commit position. In fact, we only keep prepare position being used for subscriptions to ensure compatibility as it's lo longer possible to use explicit transactions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/bug Issues which are a software defect linear
Projects
None yet
Development

No branches or pull requests

4 participants