Skip to content

VReplication: Pad binlog values for binary() columns to match the value returned by mysql selects#7969

Merged
rohit-nayak-ps merged 3 commits intovitessio:masterfrom
planetscale:rn-vr-binary-bug
May 5, 2021
Merged

VReplication: Pad binlog values for binary() columns to match the value returned by mysql selects#7969
rohit-nayak-ps merged 3 commits intovitessio:masterfrom
planetscale:rn-vr-binary-bug

Conversation

@rohit-nayak-ps
Copy link
Copy Markdown
Member

@rohit-nayak-ps rohit-nayak-ps commented Apr 27, 2021

Signed-off-by: Rohit Nayak rohit@planetscale.com

Description

For fixed length binary columns, mysql internally pads the values on the right will nulls. However the binlogs contain the original value. This leads to a problem in vreplication workflows if a binary column is used as a sharding key.

During the copy phase the row is read using a mysql select and the column has the padded value. However while replicating we get the unpadded value. This means that we get different keyspace_ids. We found bugs where the copy phase inserted the row in one shard but the update during the catchup phase routed this row to another shard where, of course, the update failed.

The PR pads the value found in the binlog to match the value returned my mysql to fix this issue.

Related Issue(s)

#3984

Checklist

  • Tests were added or are not required
  • Documentation was added or is not required

@rohit-nayak-ps rohit-nayak-ps marked this pull request as ready for review April 27, 2021 18:40
@systay systay added Component: VReplication Type: Enhancement Logical improvement (somewhere between a bug and feature) labels Apr 28, 2021
Copy link
Copy Markdown
Collaborator

@deepthi deepthi left a comment

Choose a reason for hiding this comment

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

LGTM

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.

What a catch this one!!

@rohit-nayak-ps rohit-nayak-ps marked this pull request as draft May 2, 2021 21:40
@rohit-nayak-ps
Copy link
Copy Markdown
Member Author

Just reviewed with Sugu and he recommended that the padding should be done right when it is read from the binlog and not just for computing the keyspace id. That way the padded value, which is also the result of a mysql select, will be sent to all consumers of the vstream.

So moving it to draft for now.

@rohit-nayak-ps rohit-nayak-ps added Type: Bug and removed Type: Enhancement Logical improvement (somewhere between a bug and feature) labels May 3, 2021
… a select query. This also ensures that if such columns are used as sharding keys we get the same keyspace_id

Signed-off-by: Rohit Nayak <rohit@planetscale.com>
…rs see the padded value instead of doing it later in vstreamer or doint it just for keyspace id computation

Signed-off-by: Rohit Nayak <rohit@planetscale.com>
Signed-off-by: Rohit Nayak <rohit@planetscale.com>
@rohit-nayak-ps rohit-nayak-ps marked this pull request as ready for review May 4, 2021 11:47
@rohit-nayak-ps
Copy link
Copy Markdown
Member Author

@sougou I was able to pad the binary columns in the binlog reader. One benefit with this fix is that we could remove the cast we had added earlier to cast binary pks in sql which should improve workflow performance too.

@deepthi, please re-review

@rohit-nayak-ps rohit-nayak-ps requested a review from a team May 4, 2021 11:54
Copy link
Copy Markdown
Contributor

@shlomi-noach shlomi-noach left a comment

Choose a reason for hiding this comment

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

It's painful to see how small the change is :)

paddedData := make([]byte, max)
copy(paddedData[:l], mdata)
mdata = paddedData
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

👍

Copy link
Copy Markdown
Member

@mattlord mattlord Aug 30, 2021

Choose a reason for hiding this comment

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

There's a bug here for CHAR columns using binary collations. If you have e.g. CHAR (3) COLLATE UTF8MB4_BIN then the padding goes out to the max byte length of 12 and you get this in the vreplication stream:
'FOO\0\0\0\0\0\0\0\0\0' and the SQL fails because it's too long for the column.

Copy link
Copy Markdown
Contributor

@sougou sougou left a comment

Choose a reason for hiding this comment

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

I feel like a similar bug may exist with CHAR(N), where we may need to pad with spaces.

}
},
"tables": {
"tables": {
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 nit - extra whitespace.

Copy link
Copy Markdown
Member

@rafael rafael left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Copy Markdown
Collaborator

@deepthi deepthi left a comment

Choose a reason for hiding this comment

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

LGTM

@deepthi
Copy link
Copy Markdown
Collaborator

deepthi commented May 4, 2021

Let us plan to backport this to 10.0, 9.0 and 8.0.
We also need to document it as a "Known Issue" in the 10.0 release notes.

@shlomi-noach
Copy link
Copy Markdown
Contributor

Also, just realized there was an almost identical recent contribution to gh-ost. I should be more wary.

@rohit-nayak-ps rohit-nayak-ps merged commit f3a2411 into vitessio:master May 5, 2021
@rohit-nayak-ps rohit-nayak-ps deleted the rn-vr-binary-bug branch May 5, 2021 08:34
systay pushed a commit to planetscale/vitess that referenced this pull request May 6, 2021
…ue returned by mysql selects

Backport of vitessio#7969

* Pad binlog values for binary() columns to match the value returned by a select query. This also ensures that if such columns are used as sharding keys we get the same keyspace_id

* Pad binary() values in the binlog reader directly so that all consumers see the padded value instead of doing it later in vstreamer or doint it just for keyspace id computation

Signed-off-by: Rohit Nayak <rohit@planetscale.com>
Signed-off-by: Andres Taylor <andres@planetscale.com>
rohit-nayak-ps added a commit to planetscale/vitess that referenced this pull request Aug 5, 2021
Signed-off-by: Rohit Nayak <rohit@planetscale.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants