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

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

Merged
merged 3 commits into from
May 5, 2021

Conversation

rohit-nayak-ps
Copy link
Contributor

@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
Member

@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

// the data without this padding. In particular, this causes an issue if a binary(n) column is part of the
// sharding key: the keyspace_id() returned during the copy phase (where the value is the result of a mysql query)
// is different from the one during replication (where the value is the one from the binlogs)
// Hence we need to add the padding here
Copy link
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
Contributor 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
Contributor 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
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
Contributor

Choose a reason for hiding this comment

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

👍

Copy link
Contributor

@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
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
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
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
Member

@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
Member

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
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.

None yet

7 participants