Thanks Jason. Those changes make sense to me. I will update the KIP.
On Fri, Jan 6, 2023 at 3:31 PM Jason Gustafson <ja...@confluent.io.invalid> wrote: > Hey Justine, > > > I was wondering about compatibility here. When we send requests > between brokers, we want to ensure that the receiving broker understands > the request (specifically the new fields). Typically this is done via > IBP/metadata version. > I'm trying to think if there is a way around it but I'm not sure there is. > > Yes. I think we would gate usage of this behind an IBP bump. Does that seem > reasonable? > > > As for the improvements -- can you clarify how the multiple transactional > IDs would help here? Were you thinking of a case where we wait/batch > multiple produce requests together? My understanding for now was 1 > transactional ID and one validation per 1 produce request. > > Each call to `AddPartitionsToTxn` is essentially a write to the transaction > log and must block on replication. The more we can fit into a single > request, the more writes we can do in parallel. The alternative is to make > use of more connections, but usually we prefer batching since the network > stack is not really optimized for high connection/request loads. > > > Finally with respect to the authorizations, I think it makes sense to > skip > topic authorizations, but I'm a bit confused by the "leader ID" field. > Wouldn't we just want to flag the request as from a broker (does it matter > which one?). > > We could also make it version-based. For the next version, we could require > CLUSTER auth. So clients would not be able to use the API anymore, which is > probably what we want. > > -Jason > > On Fri, Jan 6, 2023 at 10:43 AM Justine Olshan > <jols...@confluent.io.invalid> > wrote: > > > As a follow up, I was just thinking about the batching a bit more. > > I suppose if we have one request in flight and we queue up the other > > produce requests in some sort of purgatory, we could send information out > > for all of them rather than one by one. So that would be a benefit of > > batching partitions to add per transaction. > > > > I'll need to think a bit more on the design of this part of the KIP, and > > will update the KIP in the next few days. > > > > Thanks, > > Justine > > > > On Fri, Jan 6, 2023 at 10:22 AM Justine Olshan <jols...@confluent.io> > > wrote: > > > > > Hey Jason -- thanks for the input -- I was just digging a bit deeper > into > > > the design + implementation of the validation calls here and what you > say > > > makes sense. > > > > > > I was wondering about compatibility here. When we send requests > > > between brokers, we want to ensure that the receiving broker > understands > > > the request (specifically the new fields). Typically this is done via > > > IBP/metadata version. > > > I'm trying to think if there is a way around it but I'm not sure there > > is. > > > > > > As for the improvements -- can you clarify how the multiple > transactional > > > IDs would help here? Were you thinking of a case where we wait/batch > > > multiple produce requests together? My understanding for now was 1 > > > transactional ID and one validation per 1 produce request. > > > > > > Finally with respect to the authorizations, I think it makes sense to > > skip > > > topic authorizations, but I'm a bit confused by the "leader ID" field. > > > Wouldn't we just want to flag the request as from a broker (does it > > matter > > > which one?). > > > > > > I think I want to adopt these suggestions, just had a few questions on > > the > > > details. > > > > > > Thanks, > > > Justine > > > > > > On Thu, Jan 5, 2023 at 5:05 PM Jason Gustafson > > <ja...@confluent.io.invalid> > > > wrote: > > > > > >> Hi Justine, > > >> > > >> Thanks for the proposal. > > >> > > >> I was thinking about the implementation a little bit. In the current > > >> proposal, the behavior depends on whether we have an old or new > client. > > >> For > > >> old clients, we send `DescribeTransactions` and verify the result and > > for > > >> new clients, we send `AddPartitionsToTxn`. We might be able to > simplify > > >> the > > >> implementation if we can use the same request type. For example, what > if > > >> we > > >> bump the protocol version for `AddPartitionsToTxn` and add a > > >> `validateOnly` > > >> flag? For older versions, we can set `validateOnly=true` so that the > > >> request only returns successfully if the partition had already been > > added. > > >> For new versions, we can set `validateOnly=false` and the partition > will > > >> be > > >> added to the transaction. The other slightly annoying thing that this > > >> would > > >> get around is the need to collect the transaction state for all > > partitions > > >> even when we only care about a subset. > > >> > > >> Some additional improvements to consider: > > >> > > >> - We can give `AddPartitionsToTxn` better batch support for > inter-broker > > >> usage. Currently we only allow one `TransactionalId` to be specified, > > but > > >> the broker may get some benefit being able to batch across multiple > > >> transactions. > > >> - Another small improvement is skipping topic authorization checks for > > >> `AddPartitionsToTxn` when the request is from a broker. Perhaps we can > > add > > >> a field for the `LeaderId` or something like that and require CLUSTER > > >> permission when set. > > >> > > >> Best, > > >> Jason > > >> > > >> > > >> > > >> On Mon, Dec 19, 2022 at 3:56 PM Jun Rao <j...@confluent.io.invalid> > > wrote: > > >> > > >> > Hi, Justine, > > >> > > > >> > Thanks for the explanation. It makes sense to me now. > > >> > > > >> > Jun > > >> > > > >> > On Mon, Dec 19, 2022 at 1:42 PM Justine Olshan > > >> > <jols...@confluent.io.invalid> > > >> > wrote: > > >> > > > >> > > Hi Jun, > > >> > > > > >> > > My understanding of the mechanism is that when we get to the last > > >> epoch, > > >> > we > > >> > > increment to the fencing/last epoch and if any further requests > come > > >> in > > >> > for > > >> > > this producer ID they are fenced. Then the producer gets a new ID > > and > > >> > > restarts with epoch/sequence 0. The fenced epoch sticks around for > > the > > >> > > duration of producer.id.expiration.ms and blocks any late > messages > > >> > there. > > >> > > The new ID will get to take advantage of the improved semantics > > around > > >> > > non-zero start sequences. So I think we are covered. > > >> > > > > >> > > The only potential issue is overloading the cache, but hopefully > the > > >> > > improvements (lowered producer.id.expiration.ms) will help with > > that. > > >> > Let > > >> > > me know if you still have concerns. > > >> > > > > >> > > Thanks, > > >> > > Justine > > >> > > > > >> > > On Mon, Dec 19, 2022 at 10:24 AM Jun Rao <j...@confluent.io.invalid > > > > >> > wrote: > > >> > > > > >> > > > Hi, Justine, > > >> > > > > > >> > > > Thanks for the explanation. > > >> > > > > > >> > > > 70. The proposed fencing logic doesn't apply when pid changes, > is > > >> that > > >> > > > right? If so, I am not sure how complete we are addressing this > > >> issue > > >> > if > > >> > > > the pid changes more frequently. > > >> > > > > > >> > > > Thanks, > > >> > > > > > >> > > > Jun > > >> > > > > > >> > > > > > >> > > > > > >> > > > On Fri, Dec 16, 2022 at 9:16 AM Justine Olshan > > >> > > > <jols...@confluent.io.invalid> > > >> > > > wrote: > > >> > > > > > >> > > > > Hi Jun, > > >> > > > > > > >> > > > > Thanks for replying! > > >> > > > > > > >> > > > > 70.We already do the overflow mechanism, so my change would > just > > >> make > > >> > > it > > >> > > > > happen more often. > > >> > > > > I was also not suggesting a new field in the log, but in the > > >> > response, > > >> > > > > which would be gated by the client version. Sorry if something > > >> there > > >> > is > > >> > > > > unclear. I think we are starting to diverge. > > >> > > > > The goal of this KIP is to not change to the marker format at > > all. > > >> > > > > > > >> > > > > 71. Yes, I guess I was going under the assumption that the log > > >> would > > >> > > just > > >> > > > > look at its last epoch and treat it as the current epoch. I > > >> suppose > > >> > we > > >> > > > can > > >> > > > > have some special logic that if the last epoch was on a marker > > we > > >> > > > actually > > >> > > > > expect the next epoch or something like that. We just need to > > >> > > distinguish > > >> > > > > based on whether we had a commit/abort marker. > > >> > > > > > > >> > > > > 72. > > >> > > > > > if the producer epoch hasn't been bumped on the > > >> > > > > broker, it seems that the stucked message will fail the > sequence > > >> > > > validation > > >> > > > > and will be ignored. If the producer epoch has been bumped, we > > >> ignore > > >> > > the > > >> > > > > sequence check and the stuck message could be appended to the > > log. > > >> > So, > > >> > > is > > >> > > > > the latter case that we want to guard? > > >> > > > > > > >> > > > > I'm not sure I follow that "the message will fail the sequence > > >> > > > validation". > > >> > > > > In some of these cases, we had an abort marker (due to an > error) > > >> and > > >> > > then > > >> > > > > the late message comes in with the correct sequence number. > This > > >> is a > > >> > > > case > > >> > > > > covered by the KIP. > > >> > > > > The latter case is actually not something we've considered > > here. I > > >> > > think > > >> > > > > generally when we bump the epoch, we are accepting that the > > >> sequence > > >> > > does > > >> > > > > not need to be checked anymore. My understanding is also that > we > > >> > don't > > >> > > > > typically bump epoch mid transaction (based on a quick look at > > the > > >> > > code) > > >> > > > > but let me know if that is the case. > > >> > > > > > > >> > > > > Thanks, > > >> > > > > Justine > > >> > > > > > > >> > > > > On Thu, Dec 15, 2022 at 12:23 PM Jun Rao > > <j...@confluent.io.invalid > > >> > > > >> > > > wrote: > > >> > > > > > > >> > > > > > Hi, Justine, > > >> > > > > > > > >> > > > > > Thanks for the reply. > > >> > > > > > > > >> > > > > > 70. Assigning a new pid on int overflow seems a bit hacky. > If > > we > > >> > > need a > > >> > > > > txn > > >> > > > > > level id, it will be better to model this explicitly. > Adding a > > >> new > > >> > > > field > > >> > > > > > would require a bit more work since it requires a new txn > > marker > > >> > > format > > >> > > > > in > > >> > > > > > the log. So, we probably need to guard it with an IBP or > > >> metadata > > >> > > > version > > >> > > > > > and document the impact on downgrade once the new format is > > >> written > > >> > > to > > >> > > > > the > > >> > > > > > log. > > >> > > > > > > > >> > > > > > 71. Hmm, once the marker is written, the partition will > expect > > >> the > > >> > > next > > >> > > > > > append to be on the next epoch. Does that cover the case you > > >> > > mentioned? > > >> > > > > > > > >> > > > > > 72. Also, just to be clear on the stucked message issue > > >> described > > >> > in > > >> > > > the > > >> > > > > > motivation. With EoS, we also validate the sequence id for > > >> > > idempotency. > > >> > > > > So, > > >> > > > > > with the current logic, if the producer epoch hasn't been > > >> bumped on > > >> > > the > > >> > > > > > broker, it seems that the stucked message will fail the > > sequence > > >> > > > > validation > > >> > > > > > and will be ignored. If the producer epoch has been bumped, > we > > >> > ignore > > >> > > > the > > >> > > > > > sequence check and the stuck message could be appended to > the > > >> log. > > >> > > So, > > >> > > > is > > >> > > > > > the latter case that we want to guard? > > >> > > > > > > > >> > > > > > Thanks, > > >> > > > > > > > >> > > > > > Jun > > >> > > > > > > > >> > > > > > On Wed, Dec 14, 2022 at 10:44 AM Justine Olshan > > >> > > > > > <jols...@confluent.io.invalid> wrote: > > >> > > > > > > > >> > > > > > > Matthias — thanks again for taking time to look a this. > You > > >> said: > > >> > > > > > > > > >> > > > > > > > My proposal was only focusing to avoid dangling > > >> > > > > > > > > >> > > > > > > transactions if records are added without registered > > >> partition. > > >> > -- > > >> > > > > Maybe > > >> > > > > > > > > >> > > > > > > you can add a few more details to the KIP about this > > scenario > > >> for > > >> > > > > better > > >> > > > > > > > > >> > > > > > > documentation purpose? > > >> > > > > > > > > >> > > > > > > > > >> > > > > > > I'm not sure I understand what you mean here. The > motivation > > >> > > section > > >> > > > > > > describes two scenarios about how the record can be added > > >> > without a > > >> > > > > > > registered partition: > > >> > > > > > > > > >> > > > > > > > > >> > > > > > > > This can happen when a message gets stuck or delayed due > > to > > >> > > > > networking > > >> > > > > > > issues or a network partition, the transaction aborts, and > > >> then > > >> > the > > >> > > > > > delayed > > >> > > > > > > message finally comes in. > > >> > > > > > > > > >> > > > > > > > > >> > > > > > > > Another way hanging transactions can occur is that a > > client > > >> is > > >> > > > buggy > > >> > > > > > and > > >> > > > > > > may somehow try to write to a partition before it adds the > > >> > > partition > > >> > > > to > > >> > > > > > the > > >> > > > > > > transaction. > > >> > > > > > > > > >> > > > > > > > > >> > > > > > > > > >> > > > > > > For the first example of this would it be helpful to say > > that > > >> > this > > >> > > > > > message > > >> > > > > > > comes in after the abort, but before the partition is > added > > to > > >> > the > > >> > > > next > > >> > > > > > > transaction so it becomes "hanging." Perhaps the next > > sentence > > >> > > > > describing > > >> > > > > > > the message becoming part of the next transaction (a > > different > > >> > > case) > > >> > > > > was > > >> > > > > > > not properly differentiated. > > >> > > > > > > > > >> > > > > > > > > >> > > > > > > > > >> > > > > > > Jun — thanks for reading the KIP. > > >> > > > > > > > > >> > > > > > > 70. The int typing was a concern. Currently we have a > > >> mechanism > > >> > in > > >> > > > > place > > >> > > > > > to > > >> > > > > > > fence the final epoch when the epoch is about to overflow > > and > > >> > > assign > > >> > > > a > > >> > > > > > new > > >> > > > > > > producer ID with epoch 0. Of course, this is a bit tricky > > >> when it > > >> > > > comes > > >> > > > > > to > > >> > > > > > > the response back to the client. > > >> > > > > > > Making this a long could be another option, but I wonder > are > > >> > there > > >> > > > any > > >> > > > > > > implications on changing this field if the epoch is > > persisted > > >> to > > >> > > > disk? > > >> > > > > > I'd > > >> > > > > > > need to check the usages. > > >> > > > > > > > > >> > > > > > > 71.This was something Matthias asked about as well. I was > > >> > > > considering a > > >> > > > > > > possible edge case where a produce request from a new > > >> transaction > > >> > > > > somehow > > >> > > > > > > gets sent right after the marker is written, but before > the > > >> > > producer > > >> > > > is > > >> > > > > > > alerted of the newly bumped epoch. In this case, we may > > >> include > > >> > > this > > >> > > > > > record > > >> > > > > > > when we don't want to. I suppose we could try to do > > something > > >> > > client > > >> > > > > side > > >> > > > > > > to bump the epoch after sending an endTxn as well in this > > >> > scenario > > >> > > — > > >> > > > > but > > >> > > > > > I > > >> > > > > > > wonder how it would work when the server is aborting based > > on > > >> a > > >> > > > > > server-side > > >> > > > > > > error. I could also be missing something and this scenario > > is > > >> > > > actually > > >> > > > > > not > > >> > > > > > > possible. > > >> > > > > > > > > >> > > > > > > Thanks again to everyone reading and commenting. Let me > know > > >> > about > > >> > > > any > > >> > > > > > > further questions or comments. > > >> > > > > > > > > >> > > > > > > Justine > > >> > > > > > > > > >> > > > > > > On Wed, Dec 14, 2022 at 9:41 AM Jun Rao > > >> <j...@confluent.io.invalid > > >> > > > > >> > > > > > wrote: > > >> > > > > > > > > >> > > > > > > > Hi, Justine, > > >> > > > > > > > > > >> > > > > > > > Thanks for the KIP. A couple of comments. > > >> > > > > > > > > > >> > > > > > > > 70. Currently, the producer epoch is an int. I am not > sure > > >> if > > >> > > it's > > >> > > > > > enough > > >> > > > > > > > to accommodate all transactions in the lifetime of a > > >> producer. > > >> > > > Should > > >> > > > > > we > > >> > > > > > > > change that to a long or add a new long field like > txnId? > > >> > > > > > > > > > >> > > > > > > > 71. "it will write the prepare commit message with a > > bumped > > >> > epoch > > >> > > > and > > >> > > > > > > send > > >> > > > > > > > WriteTxnMarkerRequests with the bumped epoch." Hmm, the > > >> epoch > > >> > is > > >> > > > > > > associated > > >> > > > > > > > with the current txn right? So, it seems weird to write > a > > >> > commit > > >> > > > > > message > > >> > > > > > > > with a bumped epoch. Should we only bump up the epoch in > > >> > > > > EndTxnResponse > > >> > > > > > > and > > >> > > > > > > > rename the field to sth like nextProducerEpoch? > > >> > > > > > > > > > >> > > > > > > > Thanks, > > >> > > > > > > > > > >> > > > > > > > Jun > > >> > > > > > > > > > >> > > > > > > > > > >> > > > > > > > > > >> > > > > > > > On Mon, Dec 12, 2022 at 8:54 PM Matthias J. Sax < > > >> > > mj...@apache.org> > > >> > > > > > > wrote: > > >> > > > > > > > > > >> > > > > > > > > Thanks for the background. > > >> > > > > > > > > > > >> > > > > > > > > 20/30: SGTM. My proposal was only focusing to avoid > > >> dangling > > >> > > > > > > > > transactions if records are added without registered > > >> > partition. > > >> > > > -- > > >> > > > > > > Maybe > > >> > > > > > > > > you can add a few more details to the KIP about this > > >> scenario > > >> > > for > > >> > > > > > > better > > >> > > > > > > > > documentation purpose? > > >> > > > > > > > > > > >> > > > > > > > > 40: I think you hit a fair point about race conditions > > or > > >> > > client > > >> > > > > bugs > > >> > > > > > > > > (incorrectly not bumping the epoch). The > > >> complexity/confusion > > >> > > for > > >> > > > > > using > > >> > > > > > > > > the bumped epoch I see, is mainly for internal > > debugging, > > >> ie, > > >> > > > > > > inspecting > > >> > > > > > > > > log segment dumps -- it seems harder to reason about > the > > >> > system > > >> > > > for > > >> > > > > > us > > >> > > > > > > > > humans. But if we get better guarantees, it would be > > >> worth to > > >> > > use > > >> > > > > the > > >> > > > > > > > > bumped epoch. > > >> > > > > > > > > > > >> > > > > > > > > 60: as I mentioned already, I don't know the broker > > >> internals > > >> > > to > > >> > > > > > > provide > > >> > > > > > > > > more input. So if nobody else chimes in, we should > just > > >> move > > >> > > > > forward > > >> > > > > > > > > with your proposal. > > >> > > > > > > > > > > >> > > > > > > > > > > >> > > > > > > > > -Matthias > > >> > > > > > > > > > > >> > > > > > > > > > > >> > > > > > > > > On 12/6/22 4:22 PM, Justine Olshan wrote: > > >> > > > > > > > > > Hi all, > > >> > > > > > > > > > After Artem's questions about error behavior, I've > > >> > > re-evaluated > > >> > > > > the > > >> > > > > > > > > > unknown producer ID exception and had some > discussions > > >> > > offline. > > >> > > > > > > > > > > > >> > > > > > > > > > I think generally it makes sense to simplify error > > >> handling > > >> > > in > > >> > > > > > cases > > >> > > > > > > > like > > >> > > > > > > > > > this and the UNKNOWN_PRODUCER_ID error has a pretty > > long > > >> > and > > >> > > > > > > > complicated > > >> > > > > > > > > > history. Because of this, I propose adding a new > error > > >> code > > >> > > > > > > > > ABORTABLE_ERROR > > >> > > > > > > > > > that when encountered by new clients (gated by the > > >> produce > > >> > > > > request > > >> > > > > > > > > version) > > >> > > > > > > > > > will simply abort the transaction. This allows the > > >> server > > >> > to > > >> > > > have > > >> > > > > > > some > > >> > > > > > > > > say > > >> > > > > > > > > > in whether the client aborts and makes handling much > > >> > simpler. > > >> > > > In > > >> > > > > > the > > >> > > > > > > > > > future, we can also use this error in other > situations > > >> > where > > >> > > we > > >> > > > > > want > > >> > > > > > > to > > >> > > > > > > > > > abort the transactions. We can even use on other > apis. > > >> > > > > > > > > > > > >> > > > > > > > > > I've added this to the KIP. Let me know if there are > > any > > >> > > > > questions > > >> > > > > > or > > >> > > > > > > > > > issues. > > >> > > > > > > > > > > > >> > > > > > > > > > Justine > > >> > > > > > > > > > > > >> > > > > > > > > > On Fri, Dec 2, 2022 at 10:22 AM Justine Olshan < > > >> > > > > > jols...@confluent.io > > >> > > > > > > > > > >> > > > > > > > > wrote: > > >> > > > > > > > > > > > >> > > > > > > > > >> Hey Matthias, > > >> > > > > > > > > >> > > >> > > > > > > > > >> > > >> > > > > > > > > >> 20/30 — Maybe I also didn't express myself clearly. > > For > > >> > > older > > >> > > > > > > clients > > >> > > > > > > > we > > >> > > > > > > > > >> don't have a way to distinguish between a previous > > and > > >> the > > >> > > > > current > > >> > > > > > > > > >> transaction since we don't have the epoch bump. > This > > >> means > > >> > > > that > > >> > > > > a > > >> > > > > > > late > > >> > > > > > > > > >> message from the previous transaction may be added > to > > >> the > > >> > > new > > >> > > > > one. > > >> > > > > > > > With > > >> > > > > > > > > >> older clients — we can't guarantee this won't > happen > > >> if we > > >> > > > > already > > >> > > > > > > > sent > > >> > > > > > > > > the > > >> > > > > > > > > >> addPartitionsToTxn call (why we make changes for > the > > >> newer > > >> > > > > client) > > >> > > > > > > but > > >> > > > > > > > > we > > >> > > > > > > > > >> can at least gate some by ensuring that the > partition > > >> has > > >> > > been > > >> > > > > > added > > >> > > > > > > > to > > >> > > > > > > > > the > > >> > > > > > > > > >> transaction. The rationale here is that there are > > >> likely > > >> > > LESS > > >> > > > > late > > >> > > > > > > > > arrivals > > >> > > > > > > > > >> as time goes on, so hopefully most late arrivals > will > > >> come > > >> > > in > > >> > > > > > BEFORE > > >> > > > > > > > the > > >> > > > > > > > > >> addPartitionsToTxn call. Those that arrive before > > will > > >> be > > >> > > > > properly > > >> > > > > > > > gated > > >> > > > > > > > > >> with the describeTransactions approach. > > >> > > > > > > > > >> > > >> > > > > > > > > >> If we take the approach you suggested, ANY late > > arrival > > >> > > from a > > >> > > > > > > > previous > > >> > > > > > > > > >> transaction will be added. And we don't want that. > I > > >> also > > >> > > > don't > > >> > > > > > see > > >> > > > > > > > any > > >> > > > > > > > > >> benefit in sending addPartitionsToTxn over the > > >> > describeTxns > > >> > > > > call. > > >> > > > > > > They > > >> > > > > > > > > will > > >> > > > > > > > > >> both be one extra RPC to the Txn coordinator. > > >> > > > > > > > > >> > > >> > > > > > > > > >> > > >> > > > > > > > > >> To be clear — newer clients will use > > addPartitionsToTxn > > >> > > > instead > > >> > > > > of > > >> > > > > > > the > > >> > > > > > > > > >> DescribeTxns. > > >> > > > > > > > > >> > > >> > > > > > > > > >> > > >> > > > > > > > > >> 40) > > >> > > > > > > > > >> My concern is that if we have some delay in the > > client > > >> to > > >> > > bump > > >> > > > > the > > >> > > > > > > > > epoch, > > >> > > > > > > > > >> it could continue to send epoch 73 and those > records > > >> would > > >> > > not > > >> > > > > be > > >> > > > > > > > > fenced. > > >> > > > > > > > > >> Perhaps this is not an issue if we don't allow the > > next > > >> > > > produce > > >> > > > > to > > >> > > > > > > go > > >> > > > > > > > > >> through before the EndTxn request returns. I'm also > > >> > thinking > > >> > > > > about > > >> > > > > > > > > cases of > > >> > > > > > > > > >> failure. I will need to think on this a bit. > > >> > > > > > > > > >> > > >> > > > > > > > > >> I wasn't sure if it was that confusing. But if we > > >> think it > > >> > > is, > > >> > > > > we > > >> > > > > > > can > > >> > > > > > > > > >> investigate other ways. > > >> > > > > > > > > >> > > >> > > > > > > > > >> > > >> > > > > > > > > >> 60) > > >> > > > > > > > > >> > > >> > > > > > > > > >> I'm not sure these are the same purgatories since > one > > >> is a > > >> > > > > produce > > >> > > > > > > > > >> purgatory (I was planning on using a callback > rather > > >> than > > >> > > > > > purgatory) > > >> > > > > > > > and > > >> > > > > > > > > >> the other is simply a request to append to the log. > > Not > > >> > sure > > >> > > > we > > >> > > > > > have > > >> > > > > > > > any > > >> > > > > > > > > >> structure here for ordering, but my understanding > is > > >> that > > >> > > the > > >> > > > > > broker > > >> > > > > > > > > could > > >> > > > > > > > > >> handle the write request before it hears back from > > the > > >> Txn > > >> > > > > > > > Coordinator. > > >> > > > > > > > > >> > > >> > > > > > > > > >> Let me know if I misunderstood something or > something > > >> was > > >> > > > > unclear. > > >> > > > > > > > > >> > > >> > > > > > > > > >> Justine > > >> > > > > > > > > >> > > >> > > > > > > > > >> On Thu, Dec 1, 2022 at 12:15 PM Matthias J. Sax < > > >> > > > > mj...@apache.org > > >> > > > > > > > > >> > > > > > > > > wrote: > > >> > > > > > > > > >> > > >> > > > > > > > > >>> Thanks for the details Justine! > > >> > > > > > > > > >>> > > >> > > > > > > > > >>>> 20) > > >> > > > > > > > > >>>> > > >> > > > > > > > > >>>> The client side change for 2 is removing the > > >> > addPartitions > > >> > > > to > > >> > > > > > > > > >>> transaction > > >> > > > > > > > > >>>> call. We don't need to make this from the > producer > > to > > >> > the > > >> > > > txn > > >> > > > > > > > > >>> coordinator, > > >> > > > > > > > > >>>> only server side. > > >> > > > > > > > > >>> > > >> > > > > > > > > >>> I think I did not express myself clearly. I > > understand > > >> > that > > >> > > > we > > >> > > > > > can > > >> > > > > > > > (and > > >> > > > > > > > > >>> should) change the producer to not send the > > >> > `addPartitions` > > >> > > > > > request > > >> > > > > > > > any > > >> > > > > > > > > >>> longer. But I don't thinks it's requirement to > > change > > >> the > > >> > > > > broker? > > >> > > > > > > > > >>> > > >> > > > > > > > > >>> What I am trying to say is: as a safe-guard and > > >> > improvement > > >> > > > for > > >> > > > > > > older > > >> > > > > > > > > >>> producers, the partition leader can just send the > > >> > > > > `addPartitions` > > >> > > > > > > > > >>> request to the TX-coordinator in any case -- if > the > > >> old > > >> > > > > producer > > >> > > > > > > > > >>> correctly did send the `addPartition` request to > the > > >> > > > > > TX-coordinator > > >> > > > > > > > > >>> already, the TX-coordinator can just "ignore" is > as > > >> > > > idempotent. > > >> > > > > > > > > However, > > >> > > > > > > > > >>> if the old producer has a bug and did forget to > sent > > >> the > > >> > > > > > > > `addPartition` > > >> > > > > > > > > >>> request, we would now ensure that the partition is > > >> indeed > > >> > > > added > > >> > > > > > to > > >> > > > > > > > the > > >> > > > > > > > > >>> TX and thus fix a potential producer bug (even if > we > > >> > don't > > >> > > > get > > >> > > > > > the > > >> > > > > > > > > >>> fencing via the bump epoch). -- It seems to be a > > good > > >> > > > > > improvement? > > >> > > > > > > Or > > >> > > > > > > > > is > > >> > > > > > > > > >>> there a reason to not do this? > > >> > > > > > > > > >>> > > >> > > > > > > > > >>> > > >> > > > > > > > > >>> > > >> > > > > > > > > >>>> 30) > > >> > > > > > > > > >>>> > > >> > > > > > > > > >>>> Transaction is ongoing = partition was added to > > >> > > transaction > > >> > > > > via > > >> > > > > > > > > >>>> addPartitionsToTxn. We check this with the > > >> > > > > DescribeTransactions > > >> > > > > > > > call. > > >> > > > > > > > > >>> Let > > >> > > > > > > > > >>>> me know if this wasn't sufficiently explained > here: > > >> > > > > > > > > >>> > > >> > > > > > > > > >>> If we do what I propose in (20), we don't really > > need > > >> to > > >> > > make > > >> > > > > > this > > >> > > > > > > > > >>> `DescribeTransaction` call, as the partition > leader > > >> adds > > >> > > the > > >> > > > > > > > partition > > >> > > > > > > > > >>> for older clients and we get this check for free. > > >> > > > > > > > > >>> > > >> > > > > > > > > >>> > > >> > > > > > > > > >>>> 40) > > >> > > > > > > > > >>>> > > >> > > > > > > > > >>>> The idea here is that if any messages somehow > come > > in > > >> > > before > > >> > > > > we > > >> > > > > > > get > > >> > > > > > > > > the > > >> > > > > > > > > >>> new > > >> > > > > > > > > >>>> epoch to the producer, they will be fenced. > > However, > > >> if > > >> > we > > >> > > > > don't > > >> > > > > > > > think > > >> > > > > > > > > >>> this > > >> > > > > > > > > >>>> is necessary, it can be discussed > > >> > > > > > > > > >>> > > >> > > > > > > > > >>> I agree that we should have epoch fencing. My > > >> question is > > >> > > > > > > different: > > >> > > > > > > > > >>> Assume we are at epoch 73, and we have an ongoing > > >> > > > transaction, > > >> > > > > > that > > >> > > > > > > > is > > >> > > > > > > > > >>> committed. It seems natural to write the "prepare > > >> commit" > > >> > > > > marker > > >> > > > > > > and > > >> > > > > > > > > the > > >> > > > > > > > > >>> `WriteTxMarkerRequest` both with epoch 73, too, as > > it > > >> > > belongs > > >> > > > > to > > >> > > > > > > the > > >> > > > > > > > > >>> current transaction. Of course, we now also bump > the > > >> > epoch > > >> > > > and > > >> > > > > > > expect > > >> > > > > > > > > >>> the next requests to have epoch 74, and would > reject > > >> an > > >> > > > request > > >> > > > > > > with > > >> > > > > > > > > >>> epoch 73, as the corresponding TX for epoch 73 was > > >> > already > > >> > > > > > > committed. > > >> > > > > > > > > >>> > > >> > > > > > > > > >>> It seems you propose to write the "prepare commit > > >> marker" > > >> > > and > > >> > > > > > > > > >>> `WriteTxMarkerRequest` with epoch 74 though, what > > >> would > > >> > > work, > > >> > > > > but > > >> > > > > > > it > > >> > > > > > > > > >>> seems confusing. Is there a reason why we would > use > > >> the > > >> > > > bumped > > >> > > > > > > epoch > > >> > > > > > > > 74 > > >> > > > > > > > > >>> instead of the current epoch 73? > > >> > > > > > > > > >>> > > >> > > > > > > > > >>> > > >> > > > > > > > > >>>> 60) > > >> > > > > > > > > >>>> > > >> > > > > > > > > >>>> When we are checking if the transaction is > ongoing, > > >> we > > >> > > need > > >> > > > to > > >> > > > > > > make > > >> > > > > > > > a > > >> > > > > > > > > >>> round > > >> > > > > > > > > >>>> trip from the leader partition to the transaction > > >> > > > coordinator. > > >> > > > > > In > > >> > > > > > > > the > > >> > > > > > > > > >>> time > > >> > > > > > > > > >>>> we are waiting for this message to come back, in > > >> theory > > >> > we > > >> > > > > could > > >> > > > > > > > have > > >> > > > > > > > > >>> sent > > >> > > > > > > > > >>>> a commit/abort call that would make the original > > >> result > > >> > of > > >> > > > the > > >> > > > > > > check > > >> > > > > > > > > >>> out of > > >> > > > > > > > > >>>> date. That is why we can check the leader state > > >> before > > >> > we > > >> > > > > write > > >> > > > > > to > > >> > > > > > > > the > > >> > > > > > > > > >>> log. > > >> > > > > > > > > >>> > > >> > > > > > > > > >>> Thanks. Got it. > > >> > > > > > > > > >>> > > >> > > > > > > > > >>> However, is this really an issue? We put the > produce > > >> > > request > > >> > > > in > > >> > > > > > > > > >>> purgatory, so how could we process the > > >> > > > `WriteTxnMarkerRequest` > > >> > > > > > > first? > > >> > > > > > > > > >>> Don't we need to put the `WriteTxnMarkerRequest` > > into > > >> > > > > purgatory, > > >> > > > > > > too, > > >> > > > > > > > > >>> for this case, and process both request in-order? > > >> (Again, > > >> > > my > > >> > > > > > broker > > >> > > > > > > > > >>> knowledge is limited and maybe we don't maintain > > >> request > > >> > > > order > > >> > > > > > for > > >> > > > > > > > this > > >> > > > > > > > > >>> case, what seems to be an issue IMHO, and I am > > >> wondering > > >> > if > > >> > > > > > > changing > > >> > > > > > > > > >>> request handling to preserve order for this case > > >> might be > > >> > > the > > >> > > > > > > cleaner > > >> > > > > > > > > >>> solution?) > > >> > > > > > > > > >>> > > >> > > > > > > > > >>> > > >> > > > > > > > > >>> > > >> > > > > > > > > >>> -Matthias > > >> > > > > > > > > >>> > > >> > > > > > > > > >>> > > >> > > > > > > > > >>> > > >> > > > > > > > > >>> > > >> > > > > > > > > >>> On 11/30/22 3:28 PM, Artem Livshits wrote: > > >> > > > > > > > > >>>> Hi Justine, > > >> > > > > > > > > >>>> > > >> > > > > > > > > >>>> I think the interesting part is not in this logic > > >> > (because > > >> > > > it > > >> > > > > > > tries > > >> > > > > > > > to > > >> > > > > > > > > >>>> figure out when UNKNOWN_PRODUCER_ID is retriable > > and > > >> if > > >> > > it's > > >> > > > > > > > > retryable, > > >> > > > > > > > > >>>> it's definitely not fatal), but what happens when > > >> this > > >> > > logic > > >> > > > > > > doesn't > > >> > > > > > > > > >>> return > > >> > > > > > > > > >>>> 'true' and falls through. In the old clients it > > >> seems > > >> > to > > >> > > be > > >> > > > > > > fatal, > > >> > > > > > > > if > > >> > > > > > > > > >>> we > > >> > > > > > > > > >>>> keep the behavior in the new clients, I'd expect > it > > >> > would > > >> > > be > > >> > > > > > fatal > > >> > > > > > > > as > > >> > > > > > > > > >>> well. > > >> > > > > > > > > >>>> > > >> > > > > > > > > >>>> -Artem > > >> > > > > > > > > >>>> > > >> > > > > > > > > >>>> On Tue, Nov 29, 2022 at 11:57 AM Justine Olshan > > >> > > > > > > > > >>>> <jols...@confluent.io.invalid> wrote: > > >> > > > > > > > > >>>> > > >> > > > > > > > > >>>>> Hi Artem and Jeff, > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> Thanks for taking a look and sorry for the slow > > >> > response. > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> You both mentioned the change to handle > > >> > > UNKNOWN_PRODUCER_ID > > >> > > > > > > errors. > > >> > > > > > > > > To > > >> > > > > > > > > >>> be > > >> > > > > > > > > >>>>> clear — this error code will only be sent again > > when > > >> > the > > >> > > > > > client's > > >> > > > > > > > > >>> request > > >> > > > > > > > > >>>>> version is high enough to ensure we handle it > > >> > correctly. > > >> > > > > > > > > >>>>> The current (Java) client handles this by the > > >> following > > >> > > > > > (somewhat > > >> > > > > > > > > long) > > >> > > > > > > > > >>>>> code snippet: > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> // An UNKNOWN_PRODUCER_ID means that we have > lost > > >> the > > >> > > > > producer > > >> > > > > > > > state > > >> > > > > > > > > >>> on the > > >> > > > > > > > > >>>>> broker. Depending on the log start > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> // offset, we may want to retry these, as > > described > > >> for > > >> > > > each > > >> > > > > > case > > >> > > > > > > > > >>> below. If > > >> > > > > > > > > >>>>> none of those apply, then for the > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> // idempotent producer, we will locally bump the > > >> epoch > > >> > > and > > >> > > > > > reset > > >> > > > > > > > the > > >> > > > > > > > > >>>>> sequence numbers of in-flight batches from > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> // sequence 0, then retry the failed batch, > which > > >> > should > > >> > > > now > > >> > > > > > > > succeed. > > >> > > > > > > > > >>> For > > >> > > > > > > > > >>>>> the transactional producer, allow the > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> // batch to fail. When processing the failed > > batch, > > >> we > > >> > > will > > >> > > > > > > > > transition > > >> > > > > > > > > >>> to > > >> > > > > > > > > >>>>> an abortable error and set a flag > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> // indicating that we need to bump the epoch (if > > >> > > supported > > >> > > > by > > >> > > > > > the > > >> > > > > > > > > >>> broker). > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> if (error == Errors.*UNKNOWN_PRODUCER_ID*) { > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> if (response.logStartOffset == -1) { > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> // We don't know the log start offset > > with > > >> > this > > >> > > > > > > response. > > >> > > > > > > > > We > > >> > > > > > > > > >>> should > > >> > > > > > > > > >>>>> just retry the request until we get it. > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> // The UNKNOWN_PRODUCER_ID error code > > was > > >> > added > > >> > > > > along > > >> > > > > > > > with > > >> > > > > > > > > >>> the new > > >> > > > > > > > > >>>>> ProduceResponse which includes the > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> // logStartOffset. So the '-1' > sentinel > > is > > >> > not > > >> > > > for > > >> > > > > > > > backward > > >> > > > > > > > > >>>>> compatibility. Instead, it is possible for > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> // a broker to not know the > > >> logStartOffset at > > >> > > > when > > >> > > > > it > > >> > > > > > > is > > >> > > > > > > > > >>> returning > > >> > > > > > > > > >>>>> the response because the partition > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> // may have moved away from the broker > > >> from > > >> > the > > >> > > > > time > > >> > > > > > > the > > >> > > > > > > > > >>> error was > > >> > > > > > > > > >>>>> initially raised to the time the > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> // response was being constructed. In > > >> these > > >> > > > cases, > > >> > > > > we > > >> > > > > > > > > should > > >> > > > > > > > > >>> just > > >> > > > > > > > > >>>>> retry the request: we are guaranteed > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> // to eventually get a logStartOffset > > once > > >> > > things > > >> > > > > > > settle > > >> > > > > > > > > down. > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> return true; > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> } > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> if (batch.sequenceHasBeenReset()) { > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> // When the first inflight batch fails > > >> due to > > >> > > the > > >> > > > > > > > > truncation > > >> > > > > > > > > >>> case, > > >> > > > > > > > > >>>>> then the sequences of all the other > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> // in flight batches would have been > > >> > restarted > > >> > > > from > > >> > > > > > the > > >> > > > > > > > > >>> beginning. > > >> > > > > > > > > >>>>> However, when those responses > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> // come back from the broker, they > would > > >> also > > >> > > > come > > >> > > > > > with > > >> > > > > > > > an > > >> > > > > > > > > >>>>> UNKNOWN_PRODUCER_ID error. In this case, we > should > > >> not > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> // reset the sequence numbers to the > > >> > beginning. > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> return true; > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> } else if > > >> > > > > (lastAckedOffset(batch.topicPartition).orElse( > > >> > > > > > > > > >>>>> *NO_LAST_ACKED_SEQUENCE_NUMBER*) < > > >> > > > response.logStartOffset) { > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> // The head of the log has been > removed, > > >> > > probably > > >> > > > > due > > >> > > > > > > to > > >> > > > > > > > > the > > >> > > > > > > > > >>>>> retention time elapsing. In this case, > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> // we expect to lose the producer > state. > > >> For > > >> > > the > > >> > > > > > > > > transactional > > >> > > > > > > > > >>>>> producer, reset the sequences of all > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> // inflight batches to be from the > > >> beginning > > >> > > and > > >> > > > > > retry > > >> > > > > > > > > them, > > >> > > > > > > > > >>> so > > >> > > > > > > > > >>>>> that the transaction does not need to > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> // be aborted. For the idempotent > > >> producer, > > >> > > bump > > >> > > > > the > > >> > > > > > > > epoch > > >> > > > > > > > > to > > >> > > > > > > > > >>> avoid > > >> > > > > > > > > >>>>> reusing (sequence, epoch) pairs > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> if (isTransactional()) { > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>> > > >> > > > txnPartitionMap.startSequencesAtBeginning(batch.topicPartition, > > >> > > > > > > > > >>>>> this.producerIdAndEpoch); > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> } else { > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> > > >> > > > > > requestEpochBumpForPartition(batch.topicPartition); > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> } > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> return true; > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> } > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> if (!isTransactional()) { > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> // For the idempotent producer, always > > >> retry > > >> > > > > > > > > >>> UNKNOWN_PRODUCER_ID > > >> > > > > > > > > >>>>> errors. If the batch has the current > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> // producer ID and epoch, request a > bump > > >> of > > >> > the > > >> > > > > > epoch. > > >> > > > > > > > > >>> Otherwise > > >> > > > > > > > > >>>>> just retry the produce. > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> > > >> > > > requestEpochBumpForPartition(batch.topicPartition); > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> return true; > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> } > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> } > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> I was considering keeping this behavior — but am > > >> open > > >> > to > > >> > > > > > > > simplifying > > >> > > > > > > > > >>> it. > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> We are leaving changes to older clients off the > > >> table > > >> > > here > > >> > > > > > since > > >> > > > > > > it > > >> > > > > > > > > >>> caused > > >> > > > > > > > > >>>>> many issues for clients in the past. Previously > > this > > >> > was > > >> > > a > > >> > > > > > fatal > > >> > > > > > > > > error > > >> > > > > > > > > >>> and > > >> > > > > > > > > >>>>> we didn't have the mechanisms in place to detect > > >> when > > >> > > this > > >> > > > > was > > >> > > > > > a > > >> > > > > > > > > >>> legitimate > > >> > > > > > > > > >>>>> case vs some bug or gap in the protocol. > Ensuring > > >> each > > >> > > > > > > transaction > > >> > > > > > > > > has > > >> > > > > > > > > >>> its > > >> > > > > > > > > >>>>> own epoch should close this gap. > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> And to address Jeff's second point: > > >> > > > > > > > > >>>>> *does the typical produce request path append > > >> records > > >> > to > > >> > > > > local > > >> > > > > > > log > > >> > > > > > > > > >>> along* > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> *with the currentTxnFirstOffset information? I > > would > > >> > like > > >> > > > to > > >> > > > > > > > > >>> understand* > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> *when the field is written to disk.* > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> Yes, the first produce request populates this > > field > > >> and > > >> > > > > writes > > >> > > > > > > the > > >> > > > > > > > > >>> offset > > >> > > > > > > > > >>>>> as part of the record batch and also to the > > producer > > >> > > state > > >> > > > > > > > snapshot. > > >> > > > > > > > > >>> When > > >> > > > > > > > > >>>>> we reload the records on restart and/or > > >> reassignment, > > >> > we > > >> > > > > > > repopulate > > >> > > > > > > > > >>> this > > >> > > > > > > > > >>>>> field with the snapshot from disk along with the > > >> rest > > >> > of > > >> > > > the > > >> > > > > > > > producer > > >> > > > > > > > > >>>>> state. > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> Let me know if there are further comments and/or > > >> > > questions. > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> Thanks, > > >> > > > > > > > > >>>>> Justine > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>> On Tue, Nov 22, 2022 at 9:00 PM Jeff Kim > > >> > > > > > > > > <jeff....@confluent.io.invalid > > >> > > > > > > > > >>>> > > >> > > > > > > > > >>>>> wrote: > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>>>> Hi Justine, > > >> > > > > > > > > >>>>>> > > >> > > > > > > > > >>>>>> Thanks for the KIP! I have two questions: > > >> > > > > > > > > >>>>>> > > >> > > > > > > > > >>>>>> 1) For new clients, we can once again return an > > >> error > > >> > > > > > > > > >>> UNKNOWN_PRODUCER_ID > > >> > > > > > > > > >>>>>> for sequences > > >> > > > > > > > > >>>>>> that are non-zero when there is no producer > state > > >> > > present > > >> > > > on > > >> > > > > > the > > >> > > > > > > > > >>> server. > > >> > > > > > > > > >>>>>> This will indicate we missed the 0 sequence and > > we > > >> > don't > > >> > > > yet > > >> > > > > > > want > > >> > > > > > > > to > > >> > > > > > > > > >>>>> write > > >> > > > > > > > > >>>>>> to the log. > > >> > > > > > > > > >>>>>> > > >> > > > > > > > > >>>>>> I would like to understand the current behavior > > to > > >> > > handle > > >> > > > > > older > > >> > > > > > > > > >>> clients, > > >> > > > > > > > > >>>>>> and if there are any changes we are making. > Maybe > > >> I'm > > >> > > > > missing > > >> > > > > > > > > >>> something, > > >> > > > > > > > > >>>>>> but we would want to identify whether we missed > > >> the 0 > > >> > > > > sequence > > >> > > > > > > for > > >> > > > > > > > > >>> older > > >> > > > > > > > > >>>>>> clients, no? > > >> > > > > > > > > >>>>>> > > >> > > > > > > > > >>>>>> 2) Upon returning from the transaction > > >> coordinator, we > > >> > > can > > >> > > > > set > > >> > > > > > > the > > >> > > > > > > > > >>>>>> transaction > > >> > > > > > > > > >>>>>> as ongoing on the leader by populating > > >> > > > currentTxnFirstOffset > > >> > > > > > > > > >>>>>> through the typical produce request handling. > > >> > > > > > > > > >>>>>> > > >> > > > > > > > > >>>>>> does the typical produce request path append > > >> records > > >> > to > > >> > > > > local > > >> > > > > > > log > > >> > > > > > > > > >>> along > > >> > > > > > > > > >>>>>> with the currentTxnFirstOffset information? I > > would > > >> > like > > >> > > > to > > >> > > > > > > > > understand > > >> > > > > > > > > >>>>>> when the field is written to disk. > > >> > > > > > > > > >>>>>> > > >> > > > > > > > > >>>>>> Thanks, > > >> > > > > > > > > >>>>>> Jeff > > >> > > > > > > > > >>>>>> > > >> > > > > > > > > >>>>>> > > >> > > > > > > > > >>>>>> On Tue, Nov 22, 2022 at 4:44 PM Artem Livshits > > >> > > > > > > > > >>>>>> <alivsh...@confluent.io.invalid> wrote: > > >> > > > > > > > > >>>>>> > > >> > > > > > > > > >>>>>>> Hi Justine, > > >> > > > > > > > > >>>>>>> > > >> > > > > > > > > >>>>>>> Thank you for the KIP. I have one question. > > >> > > > > > > > > >>>>>>> > > >> > > > > > > > > >>>>>>> 5) For new clients, we can once again return > an > > >> error > > >> > > > > > > > > >>>>> UNKNOWN_PRODUCER_ID > > >> > > > > > > > > >>>>>>> > > >> > > > > > > > > >>>>>>> I believe we had problems in the past with > > >> returning > > >> > > > > > > > > >>>>> UNKNOWN_PRODUCER_ID > > >> > > > > > > > > >>>>>>> because it was considered fatal and required > > >> client > > >> > > > > restart. > > >> > > > > > > It > > >> > > > > > > > > >>> would > > >> > > > > > > > > >>>>> be > > >> > > > > > > > > >>>>>>> good to spell out the new client behavior when > > it > > >> > > > receives > > >> > > > > > the > > >> > > > > > > > > error. > > >> > > > > > > > > >>>>>>> > > >> > > > > > > > > >>>>>>> -Artem > > >> > > > > > > > > >>>>>>> > > >> > > > > > > > > >>>>>>> On Tue, Nov 22, 2022 at 10:00 AM Justine > Olshan > > >> > > > > > > > > >>>>>>> <jols...@confluent.io.invalid> wrote: > > >> > > > > > > > > >>>>>>> > > >> > > > > > > > > >>>>>>>> Thanks for taking a look Matthias. I've tried > > to > > >> > > answer > > >> > > > > your > > >> > > > > > > > > >>>>> questions > > >> > > > > > > > > >>>>>>>> below: > > >> > > > > > > > > >>>>>>>> > > >> > > > > > > > > >>>>>>>> 10) > > >> > > > > > > > > >>>>>>>> > > >> > > > > > > > > >>>>>>>> Right — so the hanging transaction only > occurs > > >> when > > >> > we > > >> > > > > have > > >> > > > > > a > > >> > > > > > > > late > > >> > > > > > > > > >>>>>>> message > > >> > > > > > > > > >>>>>>>> come in and the partition is never added to a > > >> > > > transaction > > >> > > > > > > again. > > >> > > > > > > > > If > > >> > > > > > > > > >>>>> we > > >> > > > > > > > > >>>>>>>> never add the partition to a transaction, we > > will > > >> > > never > > >> > > > > > write > > >> > > > > > > a > > >> > > > > > > > > >>>>> marker > > >> > > > > > > > > >>>>>>> and > > >> > > > > > > > > >>>>>>>> never advance the LSO. > > >> > > > > > > > > >>>>>>>> > > >> > > > > > > > > >>>>>>>> If we do end up adding the partition to the > > >> > > transaction > > >> > > > (I > > >> > > > > > > > suppose > > >> > > > > > > > > >>>>> this > > >> > > > > > > > > >>>>>>> can > > >> > > > > > > > > >>>>>>>> happen before or after the late message comes > > in) > > >> > then > > >> > > > we > > >> > > > > > will > > >> > > > > > > > > >>>>> include > > >> > > > > > > > > >>>>>>> the > > >> > > > > > > > > >>>>>>>> late message in the next (incorrect) > > transaction. > > >> > > > > > > > > >>>>>>>> > > >> > > > > > > > > >>>>>>>> So perhaps it is clearer to make the > > distinction > > >> > > between > > >> > > > > > > > messages > > >> > > > > > > > > >>>>> that > > >> > > > > > > > > >>>>>>>> eventually get added to the transaction (but > > the > > >> > wrong > > >> > > > > one) > > >> > > > > > or > > >> > > > > > > > > >>>>> messages > > >> > > > > > > > > >>>>>>>> that never get added and become hanging. > > >> > > > > > > > > >>>>>>>> > > >> > > > > > > > > >>>>>>>> > > >> > > > > > > > > >>>>>>>> 20) > > >> > > > > > > > > >>>>>>>> > > >> > > > > > > > > >>>>>>>> The client side change for 2 is removing the > > >> > > > addPartitions > > >> > > > > > to > > >> > > > > > > > > >>>>>> transaction > > >> > > > > > > > > >>>>>>>> call. We don't need to make this from the > > >> producer > > >> > to > > >> > > > the > > >> > > > > > txn > > >> > > > > > > > > >>>>>>> coordinator, > > >> > > > > > > > > >>>>>>>> only server side. > > >> > > > > > > > > >>>>>>>> > > >> > > > > > > > > >>>>>>>> > > >> > > > > > > > > >>>>>>>> In my opinion, the issue with the > > >> addPartitionsToTxn > > >> > > > call > > >> > > > > > for > > >> > > > > > > > > older > > >> > > > > > > > > >>>>>>> clients > > >> > > > > > > > > >>>>>>>> is that we don't have the epoch bump, so we > > don't > > >> > know > > >> > > > if > > >> > > > > > the > > >> > > > > > > > > >>> message > > >> > > > > > > > > >>>>>>>> belongs to the previous transaction or this > > one. > > >> We > > >> > > need > > >> > > > > to > > >> > > > > > > > check > > >> > > > > > > > > if > > >> > > > > > > > > >>>>>> the > > >> > > > > > > > > >>>>>>>> partition has been added to this transaction. > > Of > > >> > > course, > > >> > > > > > this > > >> > > > > > > > > means > > >> > > > > > > > > >>>>> we > > >> > > > > > > > > >>>>>>>> won't completely cover the case where we > have a > > >> > really > > >> > > > > late > > >> > > > > > > > > message > > >> > > > > > > > > >>>>> and > > >> > > > > > > > > >>>>>>> we > > >> > > > > > > > > >>>>>>>> have added the partition to the new > > transaction, > > >> but > > >> > > > > that's > > >> > > > > > > > > >>>>>> unfortunately > > >> > > > > > > > > >>>>>>>> something we will need the new clients to > > cover. > > >> > > > > > > > > >>>>>>>> > > >> > > > > > > > > >>>>>>>> > > >> > > > > > > > > >>>>>>>> 30) > > >> > > > > > > > > >>>>>>>> > > >> > > > > > > > > >>>>>>>> Transaction is ongoing = partition was added > to > > >> > > > > transaction > > >> > > > > > > via > > >> > > > > > > > > >>>>>>>> addPartitionsToTxn. We check this with the > > >> > > > > > > DescribeTransactions > > >> > > > > > > > > >>> call. > > >> > > > > > > > > >>>>>> Let > > >> > > > > > > > > >>>>>>>> me know if this wasn't sufficiently explained > > >> here: > > >> > > > > > > > > >>>>>>>> > > >> > > > > > > > > >>>>>>>> > > >> > > > > > > > > >>>>>>> > > >> > > > > > > > > >>>>>> > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>> > > >> > > > > > > > > > > >> > > > > > > > > > >> > > > > > > > > >> > > > > > > > >> > > > > > > >> > > > > > >> > > > > >> > > > >> > > > https://cwiki.apache.org/confluence/display/KAFKA/KIP-890%3A+Transactions+Server-Side+Defense#KIP890:TransactionsServerSideDefense-EnsureOngoingTransactionforOlderClients(3) > > >> > > > > > > > > >>>>>>>> > > >> > > > > > > > > >>>>>>>> > > >> > > > > > > > > >>>>>>>> 40) > > >> > > > > > > > > >>>>>>>> > > >> > > > > > > > > >>>>>>>> The idea here is that if any messages somehow > > >> come > > >> > in > > >> > > > > before > > >> > > > > > > we > > >> > > > > > > > > get > > >> > > > > > > > > >>>>> the > > >> > > > > > > > > >>>>>>> new > > >> > > > > > > > > >>>>>>>> epoch to the producer, they will be fenced. > > >> However, > > >> > > if > > >> > > > we > > >> > > > > > > don't > > >> > > > > > > > > >>>>> think > > >> > > > > > > > > >>>>>>> this > > >> > > > > > > > > >>>>>>>> is necessary, it can be discussed > > >> > > > > > > > > >>>>>>>> > > >> > > > > > > > > >>>>>>>> > > >> > > > > > > > > >>>>>>>> 50) > > >> > > > > > > > > >>>>>>>> > > >> > > > > > > > > >>>>>>>> It should be synchronous because if we have > an > > >> event > > >> > > > (ie, > > >> > > > > an > > >> > > > > > > > > error) > > >> > > > > > > > > >>>>>> that > > >> > > > > > > > > >>>>>>>> causes us to need to abort the transaction, > we > > >> need > > >> > to > > >> > > > > know > > >> > > > > > > > which > > >> > > > > > > > > >>>>>>>> partitions to send transaction markers to. We > > >> know > > >> > the > > >> > > > > > > > partitions > > >> > > > > > > > > >>>>>> because > > >> > > > > > > > > >>>>>>>> we added them to the coordinator via the > > >> > > > > addPartitionsToTxn > > >> > > > > > > > call. > > >> > > > > > > > > >>>>>>>> Previously we have had asynchronous calls in > > the > > >> > past > > >> > > > (ie, > > >> > > > > > > > writing > > >> > > > > > > > > >>>>> the > > >> > > > > > > > > >>>>>>>> commit markers when the transaction is > > completed) > > >> > but > > >> > > > > often > > >> > > > > > > this > > >> > > > > > > > > >>> just > > >> > > > > > > > > >>>>>>>> causes confusion as we need to wait for some > > >> > > operations > > >> > > > to > > >> > > > > > > > > complete. > > >> > > > > > > > > >>>>> In > > >> > > > > > > > > >>>>>>> the > > >> > > > > > > > > >>>>>>>> writing commit markers case, clients often > see > > >> > > > > > > > > >>>>> CONCURRENT_TRANSACTIONs > > >> > > > > > > > > >>>>>>>> error messages and that can be confusing. For > > >> that > > >> > > > reason, > > >> > > > > > it > > >> > > > > > > > may > > >> > > > > > > > > be > > >> > > > > > > > > >>>>>>>> simpler to just have synchronous calls — > > >> especially > > >> > if > > >> > > > we > > >> > > > > > need > > >> > > > > > > > to > > >> > > > > > > > > >>>>> block > > >> > > > > > > > > >>>>>>> on > > >> > > > > > > > > >>>>>>>> some operation's completion anyway before we > > can > > >> > start > > >> > > > the > > >> > > > > > > next > > >> > > > > > > > > >>>>>>>> transaction. And yes, I meant coordinator. I > > will > > >> > fix > > >> > > > > that. > > >> > > > > > > > > >>>>>>>> > > >> > > > > > > > > >>>>>>>> > > >> > > > > > > > > >>>>>>>> 60) > > >> > > > > > > > > >>>>>>>> > > >> > > > > > > > > >>>>>>>> When we are checking if the transaction is > > >> ongoing, > > >> > we > > >> > > > > need > > >> > > > > > to > > >> > > > > > > > > make > > >> > > > > > > > > >>> a > > >> > > > > > > > > >>>>>>> round > > >> > > > > > > > > >>>>>>>> trip from the leader partition to the > > transaction > > >> > > > > > coordinator. > > >> > > > > > > > In > > >> > > > > > > > > >>> the > > >> > > > > > > > > >>>>>>> time > > >> > > > > > > > > >>>>>>>> we are waiting for this message to come back, > > in > > >> > > theory > > >> > > > we > > >> > > > > > > could > > >> > > > > > > > > >>> have > > >> > > > > > > > > >>>>>>> sent > > >> > > > > > > > > >>>>>>>> a commit/abort call that would make the > > original > > >> > > result > > >> > > > of > > >> > > > > > the > > >> > > > > > > > > check > > >> > > > > > > > > >>>>>> out > > >> > > > > > > > > >>>>>>> of > > >> > > > > > > > > >>>>>>>> date. That is why we can check the leader > state > > >> > before > > >> > > > we > > >> > > > > > > write > > >> > > > > > > > to > > >> > > > > > > > > >>>>> the > > >> > > > > > > > > >>>>>>> log. > > >> > > > > > > > > >>>>>>>> > > >> > > > > > > > > >>>>>>>> > > >> > > > > > > > > >>>>>>>> I'm happy to update the KIP if some of these > > >> things > > >> > > were > > >> > > > > not > > >> > > > > > > > > clear. > > >> > > > > > > > > >>>>>>>> Thanks, > > >> > > > > > > > > >>>>>>>> Justine > > >> > > > > > > > > >>>>>>>> > > >> > > > > > > > > >>>>>>>> On Mon, Nov 21, 2022 at 7:11 PM Matthias J. > > Sax < > > >> > > > > > > > mj...@apache.org > > >> > > > > > > > > > > > >> > > > > > > > > >>>>>>> wrote: > > >> > > > > > > > > >>>>>>>> > > >> > > > > > > > > >>>>>>>>> Thanks for the KIP. > > >> > > > > > > > > >>>>>>>>> > > >> > > > > > > > > >>>>>>>>> Couple of clarification questions (I am not > a > > >> > broker > > >> > > > > expert > > >> > > > > > > do > > >> > > > > > > > > >>>>> maybe > > >> > > > > > > > > >>>>>>>>> some question are obvious for others, but > not > > >> for > > >> > me > > >> > > > with > > >> > > > > > my > > >> > > > > > > > lack > > >> > > > > > > > > >>>>> of > > >> > > > > > > > > >>>>>>>>> broker knowledge). > > >> > > > > > > > > >>>>>>>>> > > >> > > > > > > > > >>>>>>>>> > > >> > > > > > > > > >>>>>>>>> > > >> > > > > > > > > >>>>>>>>> (10) > > >> > > > > > > > > >>>>>>>>> > > >> > > > > > > > > >>>>>>>>>> The delayed message case can also violate > EOS > > >> if > > >> > the > > >> > > > > > delayed > > >> > > > > > > > > >>>>>> message > > >> > > > > > > > > >>>>>>>>> comes in after the next addPartitionsToTxn > > >> request > > >> > > > comes > > >> > > > > > in. > > >> > > > > > > > > >>>>>>> Effectively > > >> > > > > > > > > >>>>>>>> we > > >> > > > > > > > > >>>>>>>>> may see a message from a previous (aborted) > > >> > > transaction > > >> > > > > > > become > > >> > > > > > > > > part > > >> > > > > > > > > >>>>>> of > > >> > > > > > > > > >>>>>>>> the > > >> > > > > > > > > >>>>>>>>> next transaction. > > >> > > > > > > > > >>>>>>>>> > > >> > > > > > > > > >>>>>>>>> What happens if the message come in before > the > > >> next > > >> > > > > > > > > >>>>>> addPartitionsToTxn > > >> > > > > > > > > >>>>>>>>> request? It seems the broker hosting the > data > > >> > > > partitions > > >> > > > > > > won't > > >> > > > > > > > > know > > >> > > > > > > > > >>>>>>>>> anything about it and append it to the > > >> partition, > > >> > > too? > > >> > > > > What > > >> > > > > > > is > > >> > > > > > > > > the > > >> > > > > > > > > >>>>>>>>> difference between both cases? > > >> > > > > > > > > >>>>>>>>> > > >> > > > > > > > > >>>>>>>>> Also, it seems a TX would only hang, if > there > > >> is no > > >> > > > > > following > > >> > > > > > > > TX > > >> > > > > > > > > >>>>> that > > >> > > > > > > > > >>>>>>> is > > >> > > > > > > > > >>>>>>>>> either committer or aborted? Thus, for the > > case > > >> > > above, > > >> > > > > the > > >> > > > > > TX > > >> > > > > > > > > might > > >> > > > > > > > > >>>>>>>>> actually not hang (of course, we might get > an > > >> EOS > > >> > > > > violation > > >> > > > > > > if > > >> > > > > > > > > the > > >> > > > > > > > > >>>>>>> first > > >> > > > > > > > > >>>>>>>>> TX was aborted and the second committed, or > > the > > >> > other > > >> > > > way > > >> > > > > > > > > around). > > >> > > > > > > > > >>>>>>>>> > > >> > > > > > > > > >>>>>>>>> > > >> > > > > > > > > >>>>>>>>> (20) > > >> > > > > > > > > >>>>>>>>> > > >> > > > > > > > > >>>>>>>>>> Of course, 1 and 2 require client-side > > >> changes, so > > >> > > for > > >> > > > > > older > > >> > > > > > > > > >>>>>> clients, > > >> > > > > > > > > >>>>>>>>> those approaches won’t apply. > > >> > > > > > > > > >>>>>>>>> > > >> > > > > > > > > >>>>>>>>> For (1) I understand why a client change is > > >> > > necessary, > > >> > > > > but > > >> > > > > > > not > > >> > > > > > > > > sure > > >> > > > > > > > > >>>>>> why > > >> > > > > > > > > >>>>>>>>> we need a client change for (2). Can you > > >> elaborate? > > >> > > -- > > >> > > > > > Later > > >> > > > > > > > you > > >> > > > > > > > > >>>>>>> explain > > >> > > > > > > > > >>>>>>>>> that we should send a > > >> DescribeTransactionRequest, > > >> > > but I > > >> > > > > am > > >> > > > > > > not > > >> > > > > > > > > sure > > >> > > > > > > > > >>>>>>> why? > > >> > > > > > > > > >>>>>>>>> Can't we not just do an implicit > > >> AddPartiitonToTx, > > >> > > too? > > >> > > > > If > > >> > > > > > > the > > >> > > > > > > > > old > > >> > > > > > > > > >>>>>>>>> producer correctly registered the partition > > >> > already, > > >> > > > the > > >> > > > > > > > > >>>>>> TX-coordinator > > >> > > > > > > > > >>>>>>>>> can just ignore it as it's an idempotent > > >> operation? > > >> > > > > > > > > >>>>>>>>> > > >> > > > > > > > > >>>>>>>>> > > >> > > > > > > > > >>>>>>>>> (30) > > >> > > > > > > > > >>>>>>>>> > > >> > > > > > > > > >>>>>>>>>> To cover older clients, we will ensure a > > >> > transaction > > >> > > > is > > >> > > > > > > > ongoing > > >> > > > > > > > > >>>>>>> before > > >> > > > > > > > > >>>>>>>>> we write to a transaction > > >> > > > > > > > > >>>>>>>>> > > >> > > > > > > > > >>>>>>>>> Not sure what you mean by this? Can you > > >> elaborate? > > >> > > > > > > > > >>>>>>>>> > > >> > > > > > > > > >>>>>>>>> > > >> > > > > > > > > >>>>>>>>> (40) > > >> > > > > > > > > >>>>>>>>> > > >> > > > > > > > > >>>>>>>>>> [the TX-coordinator] will write the prepare > > >> commit > > >> > > > > message > > >> > > > > > > > with > > >> > > > > > > > > a > > >> > > > > > > > > >>>>>>>> bumped > > >> > > > > > > > > >>>>>>>>> epoch and send WriteTxnMarkerRequests with > the > > >> > bumped > > >> > > > > > epoch. > > >> > > > > > > > > >>>>>>>>> > > >> > > > > > > > > >>>>>>>>> Why do we use the bumped epoch for both? It > > >> seems > > >> > > more > > >> > > > > > > > intuitive > > >> > > > > > > > > to > > >> > > > > > > > > >>>>>> use > > >> > > > > > > > > >>>>>>>>> the current epoch, and only return the > bumped > > >> epoch > > >> > > to > > >> > > > > the > > >> > > > > > > > > >>>>> producer? > > >> > > > > > > > > >>>>>>>>> > > >> > > > > > > > > >>>>>>>>> > > >> > > > > > > > > >>>>>>>>> (50) "Implicit AddPartitionToTransaction" > > >> > > > > > > > > >>>>>>>>> > > >> > > > > > > > > >>>>>>>>> Why does the implicitly sent request need to > > be > > >> > > > > > synchronous? > > >> > > > > > > > The > > >> > > > > > > > > >>>>> KIP > > >> > > > > > > > > >>>>>>>>> also says > > >> > > > > > > > > >>>>>>>>> > > >> > > > > > > > > >>>>>>>>>> in case we need to abort and need to know > > which > > >> > > > > partitions > > >> > > > > > > > > >>>>>>>>> > > >> > > > > > > > > >>>>>>>>> What do you mean by this? > > >> > > > > > > > > >>>>>>>>> > > >> > > > > > > > > >>>>>>>>> > > >> > > > > > > > > >>>>>>>>>> we don’t want to write to it before we > store > > in > > >> > the > > >> > > > > > > > transaction > > >> > > > > > > > > >>>>>>> manager > > >> > > > > > > > > >>>>>>>>> > > >> > > > > > > > > >>>>>>>>> Do you mean TX-coordinator instead of > > "manager"? > > >> > > > > > > > > >>>>>>>>> > > >> > > > > > > > > >>>>>>>>> > > >> > > > > > > > > >>>>>>>>> (60) > > >> > > > > > > > > >>>>>>>>> > > >> > > > > > > > > >>>>>>>>> For older clients and ensuring that the TX > is > > >> > > ongoing, > > >> > > > > you > > >> > > > > > > > > >>>>> describe a > > >> > > > > > > > > >>>>>>>>> race condition. I am not sure if I can > follow > > >> here. > > >> > > Can > > >> > > > > you > > >> > > > > > > > > >>>>>> elaborate? > > >> > > > > > > > > >>>>>>>>> > > >> > > > > > > > > >>>>>>>>> > > >> > > > > > > > > >>>>>>>>> > > >> > > > > > > > > >>>>>>>>> -Matthias > > >> > > > > > > > > >>>>>>>>> > > >> > > > > > > > > >>>>>>>>> > > >> > > > > > > > > >>>>>>>>> > > >> > > > > > > > > >>>>>>>>> On 11/18/22 1:21 PM, Justine Olshan wrote: > > >> > > > > > > > > >>>>>>>>>> Hey all! > > >> > > > > > > > > >>>>>>>>>> > > >> > > > > > > > > >>>>>>>>>> I'd like to start a discussion on my > proposal > > >> to > > >> > add > > >> > > > > some > > >> > > > > > > > > >>>>>> server-side > > >> > > > > > > > > >>>>>>>>>> checks on transactions to avoid hanging > > >> > > transactions. > > >> > > > I > > >> > > > > > know > > >> > > > > > > > > this > > >> > > > > > > > > >>>>>> has > > >> > > > > > > > > >>>>>>>>> been > > >> > > > > > > > > >>>>>>>>>> an issue for some time, so I really hope > this > > >> KIP > > >> > > will > > >> > > > > be > > >> > > > > > > > > helpful > > >> > > > > > > > > >>>>>> for > > >> > > > > > > > > >>>>>>>>> many > > >> > > > > > > > > >>>>>>>>>> users of EOS. > > >> > > > > > > > > >>>>>>>>>> > > >> > > > > > > > > >>>>>>>>>> The KIP includes changes that will be > > >> compatible > > >> > > with > > >> > > > > old > > >> > > > > > > > > clients > > >> > > > > > > > > >>>>>> and > > >> > > > > > > > > >>>>>>>>>> changes to improve performance and > > correctness > > >> on > > >> > > new > > >> > > > > > > clients. > > >> > > > > > > > > >>>>>>>>>> > > >> > > > > > > > > >>>>>>>>>> Please take a look and leave any comments > you > > >> may > > >> > > > have! > > >> > > > > > > > > >>>>>>>>>> > > >> > > > > > > > > >>>>>>>>>> KIP: > > >> > > > > > > > > >>>>>>>>>> > > >> > > > > > > > > >>>>>>>>> > > >> > > > > > > > > >>>>>>>> > > >> > > > > > > > > >>>>>>> > > >> > > > > > > > > >>>>>> > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>> > > >> > > > > > > > > > > >> > > > > > > > > > >> > > > > > > > > >> > > > > > > > >> > > > > > > >> > > > > > >> > > > > >> > > > >> > > > https://cwiki.apache.org/confluence/display/KAFKA/KIP-890%3A+Transactions+Server-Side+Defense > > >> > > > > > > > > >>>>>>>>>> JIRA: > > >> > > > https://issues.apache.org/jira/browse/KAFKA-14402 > > >> > > > > > > > > >>>>>>>>>> > > >> > > > > > > > > >>>>>>>>>> Thanks! > > >> > > > > > > > > >>>>>>>>>> Justine > > >> > > > > > > > > >>>>>>>>>> > > >> > > > > > > > > >>>>>>>>> > > >> > > > > > > > > >>>>>>>> > > >> > > > > > > > > >>>>>>> > > >> > > > > > > > > >>>>>> > > >> > > > > > > > > >>>>> > > >> > > > > > > > > >>>> > > >> > > > > > > > > >>> > > >> > > > > > > > > >> > > >> > > > > > > > > > > > >> > > > > > > > > > > >> > > > > > > > > > >> > > > > > > > > >> > > > > > > > >> > > > > > > >> > > > > > >> > > > > >> > > > >> > > > > > >