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

[usage] Batch lookup Workspaces to fix too many placeholders error #10758

Merged
merged 1 commit into from
Jun 21, 2022

Conversation

easyCZ
Copy link
Member

@easyCZ easyCZ commented Jun 20, 2022

Description

Ensures that we do not include more than 2^16 placeholders in a WHERE field IN (values) prepared query.
https://bugs.mysql.com/bug.php?id=101630

Related Issue(s)

Fixes #10642

How to test

Unit tests

Release Notes

NONE

Documentation

NONE

@easyCZ easyCZ requested a review from a team June 20, 2022 09:10
@github-actions github-actions bot added the team: webapp Issue belongs to the WebApp team label Jun 20, 2022
@easyCZ easyCZ force-pushed the mp/usage-workspace-list-batch branch from 019e5ab to 3d5810a Compare June 20, 2022 09:11
@jankeromnes
Copy link
Contributor

jankeromnes commented Jun 20, 2022

Ensures that we do not include more than 2^16 placeholders in a WHERE field IN (values) prepared query.
https://bugs.mysql.com/bug.php?id=101630

🤯 is that limit really 2^16? I assumed it would be something like 1000. Anyway, I guess the unit tests will tell -- will take a look today. 👀

@jankeromnes jankeromnes self-assigned this Jun 20, 2022
@easyCZ
Copy link
Member Author

easyCZ commented Jun 20, 2022

Ensures that we do not include more than 2^16 placeholders in a WHERE field IN (values) prepared query.
bugs.mysql.com/bug.php?id=101630

🤯 is that limit really 2^16? I assumed it would be something like 1000. Anyway, I guess the unit tests will tell -- will take a look today. 👀

Yeah I was also surprised.

Comment on lines 73 to 74
batches := int(math.Ceil(float64(items / listBatchSize)))
for i := 0; i <= batches; i++ {
Copy link
Contributor

Choose a reason for hiding this comment

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

Won't this always process one more batch than necessary?

(math.Ceil already rounds up the number of necessary batches, then you go from 0 to batches both included?)

Suggested change
batches := int(math.Ceil(float64(items / listBatchSize)))
for i := 0; i <= batches; i++ {
batches := int(math.Ceil(float64(items / listBatchSize)))
for i := 0; i < batches; i++ {

Copy link
Member Author

Choose a reason for hiding this comment

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

I've simplified this a bit. The issue was with float64(items / listBatchSize) which actually performed integer division (div). What it needs to be is float64(items) / listBatchSize because the numerator determines the resulting type of the division operation, here it's floating point division. Which then works with Ceil to always run at least one batch.

Comment on lines +78 to +80
if upper > items {
upper = items
}
Copy link
Contributor

Choose a reason for hiding this comment

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

For my own curiosity: In Go, list[lower:upper] is already safe against out-of-bounds, right? E.g. list[0:10] on a list with 4 items would return a list with 4 items without errors?

Copy link
Member Author

Choose a reason for hiding this comment

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

In go, the upper bound from a slice is not safe for out of bounds, it panics https://goplay.tools/snippet/SgSiwcAPfXC

Copy link
Contributor

@jankeromnes jankeromnes left a comment

Choose a reason for hiding this comment

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

Code looks good and seems to work (according to the unit test).

I find it hard to trust code just based on unit tests (e.g. production workload might be significantly different than what the unit tests do, as we've seen for this bug), but in this case, it's okay to test in production since this component is not on the critical path yet. 😊

Adding a hold because of optional questions/remarks:

/hold

@easyCZ
Copy link
Member Author

easyCZ commented Jun 21, 2022

I find it hard to trust code just based on unit tests (e.g. production workload might be significantly different than what the unit tests do, as we've seen for this bug)

How do you propose we solve this problem?

In general there are a couple of constraints:

  1. There's only one production, staging helps (but questionably it's planned to be removed) but still doesn't come close to production
  2. Engineers shouldn't really have direct DB access to production. This should be used in emergency situations but not as part of a development cycle, it is a main source of compromised systems - attack on an employee.
  3. If CD exists, and so does a fast rollback, then it should be encouraged to "test in production" - given there are sufficient safe-guards to prevent the system going crazy - feature flags or read only mode are good examples

@easyCZ easyCZ force-pushed the mp/usage-workspace-list-batch branch from 7a1eafa to bce28a3 Compare June 21, 2022 06:49
@easyCZ
Copy link
Member Author

easyCZ commented Jun 21, 2022

/unhold

@roboquat roboquat merged commit 08a02d6 into main Jun 21, 2022
@roboquat roboquat deleted the mp/usage-workspace-list-batch branch June 21, 2022 07:19
@roboquat roboquat added deployed: webapp Meta team change is running in production deployed Change is completely running in production labels Jun 21, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
deployed: webapp Meta team change is running in production deployed Change is completely running in production release-note-none size/M team: webapp Issue belongs to the WebApp team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Usage] workspace.go:68 Error 1390: Prepared statement contains too many placeholders
3 participants