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

Backfill teams - CE #4925

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open

Backfill teams - CE #4925

wants to merge 3 commits into from

Conversation

aerosol
Copy link
Member

@aerosol aerosol commented Dec 18, 2024

No description provided.

site: s,
inviter: inv
}
# preload: [inviter: inv, site: s]
Copy link
Contributor

Choose a reason for hiding this comment

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

🔥

@aerosol aerosol requested a review from ruslandoga December 18, 2024 10:10
@aerosol
Copy link
Member Author

aerosol commented Dec 18, 2024

@ruslandoga the belief here is, running this (with dry_run?: false) should be the only step required for self-hosters to update to current master. Would you mind giving it a look? Thanks

@ruslandoga
Copy link
Contributor

ruslandoga commented Dec 18, 2024

👋

Could you please summarise the changes / possible problems here? I don't know what to be looking out for :)

Application.get_env(:plausible, Plausible.Repo)[:url]
)

@repo.start(db_url, pool_size: 2 * @max_concurrency)
Copy link
Contributor

@ruslandoga ruslandoga Dec 18, 2024

Choose a reason for hiding this comment

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

Can this be lowered? Some free-tier / entry level hosted PostgreSQL instances limit the pool size to 25. So the "normal" repo and this data migration repo would compete for available connections and flood the logs with non-actionable 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.

Yes, this is adapted from what we've been running on prod.


orphaned_teams =
from(
t in Plausible.Teams.Team,
Copy link
Contributor

@ruslandoga ruslandoga Dec 18, 2024

Choose a reason for hiding this comment

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

Since CE can run this migration at any point in the future, would it be safer to hard code table names (here and in every other Ecto query) at the moment of the next CE release?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think we have already had a similar problem with sites.

Copy link
Member Author

Choose a reason for hiding this comment

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

Because it's compiled within lib/, I think we'll get warnings sooner?

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think there would be any warnings.

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 think we have already had a similar problem with sites.

Sorry, what problem exactly?

Copy link
Contributor

Choose a reason for hiding this comment

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

I cannot find it but basically there was a similar query that was using a schema and no select and it was failing in CE because some column in the Ecto schema didn't yet exist in the database because the migration for that column was being run afterwards. I think you were the one who fixed it by adding an explicit select: :)

Copy link
Contributor

Choose a reason for hiding this comment

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

The problem with these is that they only warn / raise at runtime.

Copy link
Contributor

Choose a reason for hiding this comment

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

Found it: #4459 (comment)

Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if Elixir 1.18 would surface this at compile time 🤔

backfill(dry_run?)
end

defp backfill(dry_run?) do
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it benefit from being a single transaction?

Copy link
Contributor

Choose a reason for hiding this comment

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

Otherwise it seems like if it fails half-way, it would always fail in the future due to insert conflicts.

Copy link
Member Author

Choose a reason for hiding this comment

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

The only reason for multiple transactions is to speed up execution time for many sites. Any specific insert conflicts you're predicting? We've been re-running it successfully. It will only catch up with records that require attention on subsequent executions. Setting up the pool size to one should make it possible to wrap in a single transaction, even with parallel Tasks spawned I think.

Copy link
Contributor

@ruslandoga ruslandoga Dec 19, 2024

Choose a reason for hiding this comment

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

Any of the repo calls can raise (db pool timeout, no connection, etc.) and stop the execution thus leaving the DB in a potentially inconsistent state, where some records have already been inserted and inserting them again would cause a conflict. I don't know the specifics of this migration so I can't immediately provide examples where exactly that can happen. But simply wrapping it in a single transaction is easy and safe.

Copy link
Contributor

Choose a reason for hiding this comment

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

This backfill procedure was specifically designed in a away where it can be resumed at any point. Operation where consistency needs to be ensured across multiple db operations are wrapped up in a transaction. We can of course wrap it all up in a single transaction as well, if you prefer.

Copy link
Contributor

@ruslandoga ruslandoga Dec 19, 2024

Choose a reason for hiding this comment

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

Yes, let's wrap it in a single transaction and remove async operations.

Copy link
Contributor

@ruslandoga ruslandoga Dec 19, 2024

Choose a reason for hiding this comment

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

If it would be easier, I can make the changes I commented about and then re-request review from the core team to make sure the intended migration logic is preserved.

:pass
end)
|> Enum.with_index()
|> Task.async_stream(
Copy link
Contributor

Choose a reason for hiding this comment

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

Does it have to be async?

Copy link
Member Author

Choose a reason for hiding this comment

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

Only if we want to utilize the pool, shouldn't matter for small CE instances. I think we can remove any parallel processing then.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think we can remove any parallel processing then.

Let's do this, I think it would be easier to understand and debug if it goes wrong for one of the self-hosters.

|> Ecto.Changeset.put_change(:updated_at, guest_invitation.updated_at)
|> @repo.update!()

if rem(idx, 1000) == 0 do
Copy link
Contributor

Choose a reason for hiding this comment

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

It can probably be lowered for CE. Or just print each site that's being updated right now.

Copy link
Member Author

Choose a reason for hiding this comment

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

Absolutely 👍

@ruslandoga
Copy link
Contributor

ruslandoga commented Dec 18, 2024

Btw, does it mean the Teams is ready to be released and I don't need to cherry-pick v2.1.5? Or should we still wait? If we should wait, then I think it's better to merge this migration right before the CE release to avoid problems with the schemas.

Uku said it might still be too early to include Teams into CE, even after this PR. And we should instead wait until there are new features using the new Teams schemas. I'll keep on cherry-picking for the next release for now. I think this can stay open until the next full CE release.

@aerosol
Copy link
Member Author

aerosol commented Dec 19, 2024

I think this can stay open until the next full CE release.

Great, thanks. Roughly, when will that be?

@aerosol
Copy link
Member Author

aerosol commented Dec 19, 2024

Could you please summarise the changes / possible problems here? I don't know what to be looking out for :)

Gah I'm sorry for not providing much context.
We're working on introducing Teams to Plausible, that will, among other things, change how memberships and subscriptions are managed. That significantly affects the underlying data model. For users that are sole guests, or sole owners, not much should change even at the UI level, so we've been trying to remap data from the old model to the new one gradually, without disruptions, before actually implementing any of the new features. So we've switched all the reads first (to use backfilled/mirrored data) and then started writing to those new tables exclusively, silently deprecating the old schema. For CE it's hopefully much simpler: shutdown, run quick backfill, bring it back up with upgraded code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants