Skip to content

Conversation

@tiagolima90
Copy link
Contributor

What does it do?

Optimize the "getForeignKeys" when synchronizing with the database.

Why is it needed?

Using Strapi in a MySQL 5.7 database with lots of schemas and tables with foreign keys, the SQL query to get the foreign keys using inner joins is painfully slow, leading to the error "Knex: Timeout acquiring a connection. The pool is probably full. Are you missing a .transacting(trx) call?" on every single content type update.

How to test it?

Trigger database synchronization on startup updating any content type.

Related issue(s)/PR(s)

#11860

tiagolima90 and others added 2 commits March 15, 2022 00:16
make separate requests to each information_schema table instead of one with inner joins for much better performance on MySQL 5.7
@strapi-cla
Copy link

strapi-cla commented Mar 15, 2022

CLA assistant check
All committers have signed the CLA.

@derrickmehaffy
Copy link
Member

CLA assistant check Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.You have signed the CLA already but the status is still pending? Let us recheck it.

@tiagolima90 can you sign the CLA before the engineers take a look? Thank you!

@tiagolima90
Copy link
Contributor Author

@derrickmehaffy hi. CLA signed. Thanks.

@codecov
Copy link

codecov bot commented Mar 28, 2022

Codecov Report

Merging #12843 (01e38c1) into master (02768b6) will decrease coverage by 5.68%.
The diff coverage is n/a.

❗ Current head 01e38c1 differs from pull request most recent head ce27863. Consider uploading reports for the commit ce27863 to get more accurate results

@@            Coverage Diff             @@
##           master   #12843      +/-   ##
==========================================
- Coverage   54.25%   48.56%   -5.69%     
==========================================
  Files        1198      242     -956     
  Lines       30598     8940   -21658     
  Branches     5571     2006    -3565     
==========================================
- Hits        16601     4342   -12259     
+ Misses      12179     3789    -8390     
+ Partials     1818      809    -1009     
Flag Coverage Δ
front ?
unit 48.56% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
...gsPage/pages/Webhooks/EditView/utils/formatData.js
...ges/EditSettingsView/components/DisplayedFields.js
...ssions/utils/createDefaultPluginsFormFromLayout.js
...fosPage/components/LogoModalStepper/FromUrlForm.js
...kages/core/upload/admin/src/utils/getRequestUrl.js
...nents/SingleTypeFormWrapper/utils/getRequestUrl.js
...n/admin/src/components/ModalCreate/AdvancedForm.js
...dlewares/addCommonFieldsToInitialDataMiddleware.js
...ages/SettingsPage/pages/Webhooks/ListView/index.js
...n/src/pages/AdvancedSettings/tests/utils/server.js
... and 946 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 02768b6...ce27863. Read the comment docs.

@tiagolima90
Copy link
Contributor Author

Hi,

Did you have a chance to check this PR?

Currently I have to use my forked version to work with strapi 4, because on every single change I get a knex timeout on restart.

Thank you.

Tiago Lima

@strapi-bot
Copy link

This pull request has been mentioned on Strapi Community Forum. There might be relevant details there:

https://forum.strapi.io/t/strapi-postgres-connection-pool-breaks-connection/17926/16

Copy link
Member

@derrickmehaffy derrickmehaffy left a comment

Choose a reason for hiding this comment

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

I noticed this only really is being applied to MySQL/MariaDB and doesn't address possible issues in PostgreSQL and SQLite too maybe?

@tiagolima90
Copy link
Contributor Author

Hi,

Since I use MySQL at work, I focused on that dialect.

Since the changes are made only on this dialect, it shouldn't break anything for PostgreSQL and SQLite.

If those dialects are having the same issues, you can try to apply the same fixes. The only thing I have done was to query each table separately and merge the info later.
The joins is what leads to the timeout when the instance have a lot of foreign keys across the schemas.

I have been using this fix since I have made this PR and is working perfectly with MySQL. No timeouts since then.

@alexandrebodin alexandrebodin self-assigned this May 20, 2022
@alexandrebodin alexandrebodin added source: core:database Source is core/database package pr: fix This PR is fixing a bug labels May 20, 2022
@esiao
Copy link

esiao commented Jun 1, 2022

I can confirm that this issue exists on PostgreSQL too.

I came across this PR because I do experience the same issue on a PostgreSQL Database hosted on Digital Ocean Managed Databases.

As a matter of fact, I do have two projects there, one has few relations and database tables (~80) where I never had any issues so far. The other one has multiple relations and tables (~190) and it fails their automated health check when deploying because the DB work isn't done yet.
My workaround has been to restore the new relations and columns by connecting to the database directly.

@alexandrebodin alexandrebodin self-requested a review June 1, 2022 07:00
@meherchandan
Copy link
Contributor

Has anyone resolved it on postgres?

@meherchandan
Copy link
Contributor

meherchandan commented Jun 13, 2022

I was facing the same issue when adding a new component on strapi v4 on existing database. I have resolved it by applying the similar logic. Now no more knex error for me. i tried to raise a PR but looks like I am not authorize to push a new branch. Patch has been posted on.
https://forum.strapi.io/t/strapi-postgres-connection-pool-breaks-connection/17926/24?u=meher_chandan

@esiao
Copy link

esiao commented Jun 13, 2022

@meherchandan, thank you. I've tried applying your patch but ran into this server starting error:

[2022-06-13 16:32:24] [2022-06-13 16:32:24.004] debug: ⛔️ Server wasn't able to start properly.
[2022-06-13 16:32:24] [2022-06-13 16:32:24.005] error: insert into "admin_permissions" ("action", "conditions", "created_at", "properties", "subject", "updated_at") values ($1, $2, $3, $4, $5, $6) returning "id" - duplicate key value violates unique constraint "admin_permissions_pkey"
[2022-06-13 16:32:24] error: insert into "admin_permissions" ("action", "conditions", "created_at", "properties", "subject", "updated_at") values ($1, $2, $3, $4, $5, $6) returning "id" - duplicate key value violates unique constraint "admin_permissions_pkey"
[2022-06-13 16:32:24]     at Parser.parseErrorMessage (/workspace/node_modules/pg-protocol/dist/parser.js:287:98)
[2022-06-13 16:32:24]     at Parser.handlePacket (/workspace/node_modules/pg-protocol/dist/parser.js:126:29)
[2022-06-13 16:32:24]     at Parser.parse (/workspace/node_modules/pg-protocol/dist/parser.js:39:38)
[2022-06-13 16:32:24]     at TLSSocket.<anonymous> (/workspace/node_modules/pg-protocol/dist/index.js:11:42)
[2022-06-13 16:32:24]     at TLSSocket.emit (node:events:527:28)
[2022-06-13 16:32:24]     at TLSSocket.emit (node:domain:475:12)
[2022-06-13 16:32:24]     at addChunk (node:internal/streams/readable:315:12)
[2022-06-13 16:32:24]     at readableAddChunk (node:internal/streams/readable:289:9)
[2022-06-13 16:32:24]     at TLSSocket.Readable.push (node:internal/streams/readable:228:10)
[2022-06-13 16:32:24]     at TLSWrap.onStreamRead (node:internal/stream_base_commons:190:23)
[2022-06-13 16:32:24] error Command failed with exit code 1.
[2022-06-13 16:32:24] info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
[]

I suppose a check must be made for the permissions table or probably check all tables with an IF exists condition?

@derrickmehaffy
Copy link
Member

I was facing the same issue when adding a new component on strapi v4 on existing database. I have resolved it by applying the similar logic. Now no more knex error for me. i tried to raise a PR but looks like I am not authorize to push a new branch. Patch has been posted on. https://forum.strapi.io/t/strapi-postgres-connection-pool-breaks-connection/17926/24?u=meher_chandan

You need to make a fork and submit the PR from the fork.

@meherchandan
Copy link
Contributor

I was facing the same issue when adding a new component on strapi v4 on existing database. I have resolved it by applying the similar logic. Now no more knex error for me. i tried to raise a PR but looks like I am not authorize to push a new branch. Patch has been posted on. https://forum.strapi.io/t/strapi-postgres-connection-pool-breaks-connection/17926/24?u=meher_chandan

You need to make a fork and submit the PR from the fork.

Thank you. Created the PR #13550

@meherchandan
Copy link
Contributor

@meherchandan, thank you. I've tried applying your patch but ran into this server starting error:

[2022-06-13 16:32:24] [2022-06-13 16:32:24.004] debug: ⛔️ Server wasn't able to start properly.
[2022-06-13 16:32:24] [2022-06-13 16:32:24.005] error: insert into "admin_permissions" ("action", "conditions", "created_at", "properties", "subject", "updated_at") values ($1, $2, $3, $4, $5, $6) returning "id" - duplicate key value violates unique constraint "admin_permissions_pkey"
[2022-06-13 16:32:24] error: insert into "admin_permissions" ("action", "conditions", "created_at", "properties", "subject", "updated_at") values ($1, $2, $3, $4, $5, $6) returning "id" - duplicate key value violates unique constraint "admin_permissions_pkey"
[2022-06-13 16:32:24]     at Parser.parseErrorMessage (/workspace/node_modules/pg-protocol/dist/parser.js:287:98)
[2022-06-13 16:32:24]     at Parser.handlePacket (/workspace/node_modules/pg-protocol/dist/parser.js:126:29)
[2022-06-13 16:32:24]     at Parser.parse (/workspace/node_modules/pg-protocol/dist/parser.js:39:38)
[2022-06-13 16:32:24]     at TLSSocket.<anonymous> (/workspace/node_modules/pg-protocol/dist/index.js:11:42)
[2022-06-13 16:32:24]     at TLSSocket.emit (node:events:527:28)
[2022-06-13 16:32:24]     at TLSSocket.emit (node:domain:475:12)
[2022-06-13 16:32:24]     at addChunk (node:internal/streams/readable:315:12)
[2022-06-13 16:32:24]     at readableAddChunk (node:internal/streams/readable:289:9)
[2022-06-13 16:32:24]     at TLSSocket.Readable.push (node:internal/streams/readable:228:10)
[2022-06-13 16:32:24]     at TLSWrap.onStreamRead (node:internal/stream_base_commons:190:23)
[2022-06-13 16:32:24] error Command failed with exit code 1.
[2022-06-13 16:32:24] info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
[]

I suppose a check must be made for the permissions table or probably check all tables with an IF exists condition?

Can you try the updated patch on same forum post. For me this is working fine on prod server as well.

@derrickmehaffy derrickmehaffy changed the title Fix "Knex: Timeout acquiring a connection. The pool is probably full. Are you missing a .transacting(trx) call?" on Content Type updates Optimize database foreign keys references - MySQL/MariaDB Jun 27, 2022
@derrickmehaffy
Copy link
Member

patches-12843.zip
^ Patch files based on v4.2.0

@derrickmehaffy
Copy link
Member

Initial testing, I'm seeing the initial cold boot time drop by half, first time I've ever seen a Strapi app boot in less than a second.....

image

image

@derrickmehaffy derrickmehaffy added this to the 4.2.1 milestone Jun 27, 2022
Copy link
Member

@derrickmehaffy derrickmehaffy left a comment

Choose a reason for hiding this comment

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

Waiting for automated tests to go through but this is a HUGE improvement.

So far it LGTM but we need @alexandrebodin to review as well.
Something @sunnysonx mentioned though he still has some performance issues and might have an additional fix to improve this further and we might want to consider moving away from using the information schema in the future.

Copy link
Member

@alexandrebodin alexandrebodin left a comment

Choose a reason for hiding this comment

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

LGTM

@alexandrebodin alexandrebodin merged commit 8ad39de into strapi:master Jun 28, 2022
@alexandrebodin alexandrebodin added pr: enhancement This PR adds or updates some part of the codebase or features and removed pr: fix This PR is fixing a bug labels Jun 28, 2022
@alexandrebodin
Copy link
Member

Great contribution. That a good step for optimization. We can still work on optimization concurrency and pooling but that's great 👍

@Convly Convly modified the milestones: 4.2.1, 4.2.2 Jun 29, 2022
@strapi-bot
Copy link

This pull request has been mentioned on Strapi Community Forum. There might be relevant details there:

https://forum.strapi.io/t/new-release-strapi-v4-2-2/19927/1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr: enhancement This PR adds or updates some part of the codebase or features source: core:database Source is core/database package

Projects

No open projects

Development

Successfully merging this pull request may close these issues.

8 participants