Skip to content

KAFKA-9669; Loosen validation of inner offsets for older message formats#8647

Merged
hachikuji merged 2 commits into
apache:trunkfrom
hachikuji:KAFKA-9669
May 12, 2020
Merged

KAFKA-9669; Loosen validation of inner offsets for older message formats#8647
hachikuji merged 2 commits into
apache:trunkfrom
hachikuji:KAFKA-9669

Conversation

@hachikuji

@hachikuji hachikuji commented May 12, 2020

Copy link
Copy Markdown
Contributor

Prior to KAFKA-8106, we allowed the v0 and v1 message formats to contain non-consecutive inner offsets. Inside LogValidator, we would detect this case and rewrite the batch. After KAFKA-8106, we changed the logic to raise an error in the case of the v1 message format (v0 was still expected to be rewritten). This caused an incompatibility for older clients which were depending on the looser validation. This patch reverts the old logic of rewriting the batch to fix the invalid inner offsets.

Note that the v2 message format has always had stricter validation. This patch also adds a test case for this.

Committer Checklist (excluded from commit message)

  • Verify design and implementation
  • Verify test coverage and CI build status
  • Verify documentation (including upgrade notes)

@jsancio jsancio left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR. Looks good based on my understanding. Just have a few questions.

@@ -423,8 +413,11 @@ private[log] object LogValidator extends Logging {
if (batch.magic > RecordBatch.MAGIC_VALUE_V0 && toMagic > RecordBatch.MAGIC_VALUE_V0) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First, I don't fully understand the different between version 0, 1, and 2. I am concern if this check (if statement) it still accurate.

  1. Why do we only update the maxTimestamp if the version is not v0?
  2. Why do we disallow in place assignment of records with invalid offsets if the version is not v0?

For 1, is it because we are only allow to update it in v1 and v2? E.g.

if (toMagic >= RecordBatch.MAGIC_VALUE_V1)
        batch.setMaxTimestamp(timestampType, maxTimestamp)

For 2. is it because in place assignment is always false for v0? E.g.:

    if (firstBatch.magic != toMagic || toMagic == RecordBatch.MAGIC_VALUE_V0)
      inPlaceAssignment = false

@hachikuji hachikuji May 12, 2020

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For 1), it is because the v0 format has no field for the timestamp. For 2), you are right: we never do in place assignment for v0 because it does not support relative internal offsets.

* @param offset The offset of the record
* @param record The record to add
*/
public void appendUncheckedWithOffset(long offset, SimpleRecord record) throws IOException {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit nervous about this method being in the public interface. Could we make it package private and then add a test utility method in the same package that calls it, exposing it only for tests?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, we already have a public appendUncheckedWithOffset for LegacyRecord.

@hachikuji hachikuji May 12, 2020

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could move these methods to a TestMemoryRecordsBuilder or something. I think risk of misuse is probably not high though.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. Since we already had one such method, I'm ok with keeping as is.

@ijuma ijuma left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR, LGTM. Just a couple of nits below.

validateOffset(batchIndex, record, expectedOffset)
} else None

if (record.offset != expectedOffset)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a comment here?

}
} else {
val result = validateMessages(invalidRecords, magicValue, CompressionType.GZIP, CompressionType.GZIP)
assertEquals(0 until 20, result.validatedRecords.records.asScala.map(_.offset))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Replace 20 with numRecords

@hachikuji
hachikuji merged commit 81cf3fa into apache:trunk May 12, 2020
hachikuji added a commit that referenced this pull request May 12, 2020
…ats (#8647)

Prior to KAFKA-8106, we allowed the v0 and v1 message formats to contain non-consecutive inner offsets. Inside `LogValidator`, we would detect this case and rewrite the batch. After KAFKA-8106, we changed the logic to raise an error in the case of the v1 message format (v0 was still expected to be rewritten). This caused an incompatibility for older clients which were depending on the looser validation. This patch reverts the old logic of rewriting the batch to fix the invalid inner offsets.

Note that the v2 message format has always had stricter validation. This patch also adds a test case for this.

Reviewers: José Armando García Sancio <jsancio@users.noreply.github.com>, Ismael Juma <ismael@juma.me.uk>
hachikuji added a commit that referenced this pull request May 12, 2020
…ats (#8647)

Prior to KAFKA-8106, we allowed the v0 and v1 message formats to contain non-consecutive inner offsets. Inside `LogValidator`, we would detect this case and rewrite the batch. After KAFKA-8106, we changed the logic to raise an error in the case of the v1 message format (v0 was still expected to be rewritten). This caused an incompatibility for older clients which were depending on the looser validation. This patch reverts the old logic of rewriting the batch to fix the invalid inner offsets.

Note that the v2 message format has always had stricter validation. This patch also adds a test case for this.

Reviewers: José Armando García Sancio <jsancio@users.noreply.github.com>, Ismael Juma <ismael@juma.me.uk>
Kvicii added a commit to Kvicii/kafka that referenced this pull request May 14, 2020
* 'trunk' of github.com:apache/kafka:
  MINOR: add option to rebuild source for system tests (apache#6656)
  KAFKA-9850 Move KStream#repartition operator validation during Topolo… (apache#8550)
  MINOR: Add a duplicate() method to Message classes (apache#8556)
  KAFKA-9966: add internal assignment listener to stabilize eos-beta upgrade test (apache#8648)
  MINOR: Replace null with an actual value for timestamp field in InsertField SMT unit tests (apache#8649)
  MINOR: Fix ProcessorContext JavaDocs and stream-time computation (apache#8603)
  MINOR: improve tests for TopologyTestDriver (apache#8631)
  KAFKA-9821: consolidate Streams rebalance triggering mechanisms (apache#8596)
  KAFKA-9669; Loosen validation of inner offsets for older message formats (apache#8647)
  KAFKA-8770: KIP-557: Drop idempotent KTable source updates (apache#8254)
  MINOR: Remove allow concurrent test (apache#8641)
jwijgerd pushed a commit to buxapp/kafka that referenced this pull request May 14, 2020
…ats (apache#8647)

Prior to KAFKA-8106, we allowed the v0 and v1 message formats to contain non-consecutive inner offsets. Inside `LogValidator`, we would detect this case and rewrite the batch. After KAFKA-8106, we changed the logic to raise an error in the case of the v1 message format (v0 was still expected to be rewritten). This caused an incompatibility for older clients which were depending on the looser validation. This patch reverts the old logic of rewriting the batch to fix the invalid inner offsets.

Note that the v2 message format has always had stricter validation. This patch also adds a test case for this.

Reviewers: José Armando García Sancio <jsancio@users.noreply.github.com>, Ismael Juma <ismael@juma.me.uk>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants