Skip to content

fix(mysql, mariadb): release connection on deadlocks#12841

Merged
papb merged 2 commits intosequelize:mainfrom
hsource:harry-deadlocks
Jan 25, 2021
Merged

fix(mysql, mariadb): release connection on deadlocks#12841
papb merged 2 commits intosequelize:mainfrom
hsource:harry-deadlocks

Conversation

@hsource
Copy link
Copy Markdown
Contributor

@hsource hsource commented Nov 16, 2020

Pull Request check-list

Please make sure to review and check all of these items:

  • Does npm run test or npm run test-DIALECT pass with this change (including linting)?
  • Does the description below contain a link to an existing issue (Closes #[issue]) or a description of the issue you are solving?
  • Have you added new tests to prevent regressions?
  • Is a documentation update included (if this change modifies existing APIs, or introduces new ones)?
  • Did you update the typescript typings accordingly (if applicable)?
  • Did you follow the commit message conventions explained in CONTRIBUTING.md?

Description of change

Closes #11571

This change makes deadlocked queries release the MariaDB/MySQL connection and does a redundant rollback. These ensure that subsequent queries work properly.

Debugging

While running sequelize in production for a collaborative document editor, we found that deadlocks on MariaDB would sometimes cause other queries to stall. After debugging, we realized that this is because MySQL/MariaDB has custom deadlock handling in Sequelize.

  1. Because InnoDB (MariaDB/MySQL engine) automatically rolls back one query in the case of deadlocks, sequelize marks the transaction.finished = 'rollback' in the run function of query.js
  2. In transaction() of sequelize.js, transaction.rollback() isn't called if transaction.finished is set
  3. As such, transaction.cleanup(), which releases the connection is never called for this connection, and can cause hangs in this case

Fix

The fix was to ensure we call transaction.cleanup(), even if we don't rollback the transaction. I added a test for this case too.

Interestingly, on MariaDB, we still need to do an explicit rollback query. Without it, a follow-up READ COMMITTED transaction wouldn't behave as expected. I added this to the testcase too.

@codecov
Copy link
Copy Markdown

codecov bot commented Nov 16, 2020

Codecov Report

Merging #12841 (828430e) into master (2de3377) will decrease coverage by 0.12%.
The diff coverage is 95.80%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master   #12841      +/-   ##
==========================================
- Coverage   96.44%   96.32%   -0.13%     
==========================================
  Files          95       95              
  Lines        9154     9262     +108     
  Branches        0       90      +90     
==========================================
+ Hits         8829     8922      +93     
+ Misses        325      323       -2     
- Partials        0       17      +17     
Impacted Files Coverage Δ
index.js 100.00% <ø> (ø)
src/associations/index.js 100.00% <ø> (ø)
src/dialects/abstract/connection-manager.js 91.80% <0.00%> (ø)
src/dialects/abstract/index.js 100.00% <ø> (ø)
src/dialects/abstract/query-generator/operators.js 90.90% <ø> (ø)
...c/dialects/abstract/query-generator/transaction.js 87.50% <ø> (ø)
src/dialects/mssql/index.js 100.00% <ø> (ø)
src/dialects/mysql/data-types.js 98.43% <ø> (ø)
src/dialects/mysql/index.js 100.00% <ø> (ø)
src/dialects/parserStore.js 100.00% <ø> (ø)
... and 101 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 2de3377...a494b7e. Read the comment docs.

Copy link
Copy Markdown
Member

@papb papb left a comment

Choose a reason for hiding this comment

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

Hi! Thanks for the PR!

@hsource
Copy link
Copy Markdown
Contributor Author

hsource commented Nov 18, 2020

Thanks for the prompt review! I improved the comments and pushed some new changes. @papb - feel free to take another look

@hsource hsource requested a review from papb November 19, 2020 23:43
@hsource
Copy link
Copy Markdown
Contributor Author

hsource commented Dec 11, 2020

@papb - quick ping on this - can you take a look? We're currently using our own branch, and would love to get this checked in so we can get back to the normal releases.

@hsource
Copy link
Copy Markdown
Contributor Author

hsource commented Dec 19, 2020

Quick follow-up ping! @papb - thanks again!

@ckeboss
Copy link
Copy Markdown
Contributor

ckeboss commented Jan 2, 2021

Looks like this is more robust than #12588

@papb
Copy link
Copy Markdown
Member

papb commented Jan 25, 2021

Hello!! Thank you very much for this super high quality PR. Great work! Sorry to take so long!

@papb papb changed the base branch from master to main January 25, 2021 13:25
Copy link
Copy Markdown
Member

@papb papb left a comment

Choose a reason for hiding this comment

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

Great work!!

@github-actions
Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 6.5.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

papb added a commit that referenced this pull request Feb 1, 2021
This is a follow-up for a problem not covered by #12841

This commit also contains some refactoring.
@arbieo
Copy link
Copy Markdown

arbieo commented Feb 22, 2021

Thanks for this. I believe the scope of this fix includes postgres as well. We were seeing unreleased connections after deadlocks caused by non-transaction calls within transactions.

@papb
Copy link
Copy Markdown
Member

papb commented Feb 24, 2021

Hi @arbieo, if I understand correctly you are saying this PR also fixed a similar postgres issue? Great news then :)

@arbieo
Copy link
Copy Markdown

arbieo commented Feb 24, 2021

@papb Correct. I made a tentative fix in my local for the issue we had and then found this online afterwards that is largely the same (I probably should have checked here first).

papb added a commit that referenced this pull request Mar 14, 2021
This is a follow-up for a problem not covered by #12841.
papb added a commit that referenced this pull request Mar 14, 2021
* test(mysql, mariadb): improve transaction tests

- Greatly improve test for `SELECT ... LOCK IN SHARE MODE`
- Greatly improve test for deadlock handling

* fix(mysql): release connection on deadlocks

This is a follow-up for a problem not covered by #12841.

* refactor(mariadb): `query.js` similar to mysql's

* Update comments with a reference to this PR
danielschwartz pushed a commit to danielschwartz/sequelize that referenced this pull request Mar 15, 2021
* test(mysql, mariadb): improve transaction tests

- Greatly improve test for `SELECT ... LOCK IN SHARE MODE`
- Greatly improve test for deadlock handling

* fix(mysql): release connection on deadlocks

This is a follow-up for a problem not covered by sequelize#12841.

* refactor(mariadb): `query.js` similar to mysql's

* Update comments with a reference to this PR
jctaveras pushed a commit to jctaveras/sequelize that referenced this pull request Mar 29, 2021
jctaveras pushed a commit to jctaveras/sequelize that referenced this pull request Mar 29, 2021
* test(mysql, mariadb): improve transaction tests

- Greatly improve test for `SELECT ... LOCK IN SHARE MODE`
- Greatly improve test for deadlock handling

* fix(mysql): release connection on deadlocks

This is a follow-up for a problem not covered by sequelize#12841.

* refactor(mariadb): `query.js` similar to mysql's

* Update comments with a reference to this PR
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

mariadb transaction deadlock does not release connection

4 participants