brentjanderson

brentjanderson

Blog Post: Zero downtime Postgres upgrades | Knock

We recently performed a zero downtime Postgres upgrade at Knock. This blog post goes into details about the Postgres considerations, although the BEAM & Elixir ecosystem were invaluable in managing the cutover process.

Some Elixir-related bits:

  1. We used DynamicSupervisor to start/stop Oban during the cutover. Without going into too much detail, Oban needs a Notifier to coordinate global state, and we rely on the default Postgres notifier (Although there is a new PubSub notifier that we have our eyes on). This Notifier establishes a persistent Postgres connection that is managed outside of your Ecto Repo, and the easiest way to move Oban over to the new instance was to stop and restart it with a new configuration using DynamicSupervisor
  2. Metaprogramming made it easier to build facade interfaces to our Ecto Repos so that database requests could be routed to the old or new database instance, based on the state of a launch darkly flag. Internally, LD uses ETS and a persistent websocket connection, which helps lookups be fast and up to date. ETS is still not quite fast enough for the volume of DB queries in our system, and so we also used :persistent_term to set the flag that determined what state we were in during the cutover process. Benchee helped us verify that we weren’t going to have a performance regression.
  3. We looked at Ecto Repo’s get_dynamic_repo function, but determined that using a facade was a better fit for our use case. It’s worth knowing what’s available, though, since Ecto comes with a lot of extensibility out of the box.
  4. The concurrency model of the BEAM makes it so much easier to reason about all of the stuff involved in a migration like this. Although you can take a similar approach with most languages, the BEAM didn’t get in the way of reasoning through the specifics of the cutover, especially around how we maintain uptime and data consistency during a cutover like this.

We may do a full post on the BEAM-related details of this upgrade in the future.

Where Next?

Popular in Blog Posts Top

AstonJ
Elixir Blog Posts How to use this section You can post links to your blog posts either in one of the Official Blog Posts threads, or, vi...
New
ErlangSolutions
An infographic that compares Erlang, Elixir, and Go’s strengths in the respect to the programming languages’ concurrency, reliability, sc...
New
shanesveller
Introduction and first content post in my new series about running Elixir Phoenix apps on Kubernetes are live! I’m describing an opiniona...
New
T0ha666
In this article, we discuss how to create a Docker image for a Phoenix application. https://t0ha.ru/en/devops/elixir/2023/11/10/how-to-b...
New
danschultzer
How to set up the Content Security Policy header with Phoenix LiveView and support inline styles and scripts with CSP nonces.
New
New
John-BoothIQ
TL;DR: Good: AI is great at Elixir. It gets better as your codebase grows. Bad: It defaults to defensive, imperative code. You need...
New

Other popular topics Top

minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New
saif
Hello everyone, Long time lurker first time poster here. I’ve recently begun working on Elixir full-time again! :raised_hands: It’s been...
New

We're in Beta

About us Mission Statement