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

politeiad: MySQL max placeholder limit hit. #1608

Closed
lukebp opened this issue Dec 20, 2021 · 0 comments · Fixed by #1605
Closed

politeiad: MySQL max placeholder limit hit. #1608

lukebp opened this issue Dec 20, 2021 · 0 comments · Fixed by #1605
Labels
bug A bug that made it into a production enviroment.

Comments

@lukebp
Copy link
Member

lukebp commented Dec 20, 2021

The maximum number of placeholders that can be included in a MySQL query is 65,535 placeholders. This number corresponds to the maximum value of an uint16.

Example, the query below contains 3 placeholders.

SELECT k, v FROM kv WHERE k IN (?,?,?);

When retrieving the vote results for a proposal, two blobs are retrieved from the key-value store for every vote that was cast. A blob for the vote itself and a blob that we refer to as a vote collider. The vote collider is a fail safe mechanism that causes a vote to fail at the tlog level if the dcr ticket has already been used to cast a previous vote and was not caught by the cast vote validation due to a bug or some other reason.

The recent subsidy split proposal had the highest voter participation rate yet and ran into this placeholder limit. Once the vote surpassed 32,767 votes, the vote results endpoint, which fetches all cast vote blobs and vote collider blobs from the key-value store, started running into the MySQL max placeholders limit and the vote results route would return an error.

Clients, such as politeiavoter, prepare votes before sending them to the server by fetching the vote results and filtering out any of their tickets that have already been cast. During the last ~25 hours of the vote, this process would error out due to the vote results endpoint not working properly. This prevented clients from voting if they had waited until the last ~25 hours to cast their votes or to start their politeiavoter trickler.

The server still accepted votes during this period that were being trickled in via politeiavoter clients that had started the trickling process prior to the last ~25 hours.

@lukebp lukebp added bug A bug that made it into a production enviroment. 91cfcc8 labels Dec 20, 2021
lukebp added a commit that referenced this issue Dec 20, 2021
Closes #1608 

This commit updates the mysql package to batch SELECT queries if the
number of records being requested exceedes the MySQL limit for the
maximum number placeholders that can be included in a prepared
statement (65,535 placeholders).

As a side note, manually testing this commit required loading a tlog
tree with >65,535 leaves. This was surprisingly difficult to do and
highlights how we're using tlog in a way that it's not really built for.
We will need to write our own append-only log implementation at some
point in order to remove the performance bottlenecks that tlog has.

Log statements from the manual testing are shown below.

```
2021-12-20 09:04:55.964 [DBG] STOR: Get 83698 blobs using 2 prepared statements
2021-12-20 09:04:55.965 [DBG] STOR: Executing select statement 1/2
2021-12-20 09:04:56.925 [DBG] STOR: Executing select statement 2/2
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A bug that made it into a production enviroment.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant