Linting postgres migration scripts

I have been working quite a bit on picking up dangerous migration patterns in migration scripts over at the eugene repository lately. A major feature I’ve added is syntax tree analysis, so that we can pick up some patterns without having to run the SQL scripts. This isn’t quite as precise as running the scripts, but it’s a lot faster and can catch quite a few common mistakes. So let’s take a look at how it works!...

May 16, 2024 · 7 min · 1475 words · Robin Kåveland

Porting an application from cats effects to ZIO

In my current project, we’re working on a large-ish code base that is written in Scala and uses cats effect as an effect system in large parts of the code base. If you’re not familiar with what an effect system is, I think the most important detail is that it’s a tool that gives you certain superpowers if you promise to be honest about it when your code does things that can be considered “effectful”, such as interacting with the network or reading files....

May 16, 2024 · 8 min · 1649 words · Robin Kåveland

Careful with That Lock, Eugene: Part 2

A while back, I wrote Careful with That Lock, Eugene about an idea for how to check if a database migration is likely to disturb production. That post came about after having an inspiring chat with a colleague about the advantages of transactional migration scripts and the ability to check the postgres system catalog views before committing a transaction. Over the past few weeks, I’ve been experimenting with this idea to test if I can use it to build valuable safety checks for DDL migrations....

May 6, 2024 · 13 min · 2581 words · Robin Kåveland

Careful with That Lock, Eugene

It is rewarding to work on software that people care about and use all around the clock. This constant usage means we can’t simply take the system offline for maintenance without upsetting users. Therefore, techniques that allow us to update the software seamlessly without downtime or compromising service quality are incredibly valuable. Most projects I’ve worked on use a relational database for persistence, and have some sort of migration tool like flyway or liquibase to make changes to the database schema....

April 12, 2024 · 9 min · 1759 words · Robin Kåveland

How to test for missing indexes on foreign keys

If you’re developing a transactional application backed by postgres, there’s a pretty cool trick you can use to check if you’re missing indexes that could potentially cause serious performance issues or even outages. In particular, I mean foreign keys where the referencing side of the constraint does not have an index. The idea is very simple, we can select all of the columns that take part in a foreign key, then remove the ones that take part in a complete index, and the remainder should be the empty set, or possibly match a known allowlist....

April 4, 2024 · 4 min · 665 words · Robin Kåveland

Friends don't let friends export to CSV

I worked for a few years in the intersection between data science and software engineering. On the whole, it was a really enjoyable time and I’d like to have the chance to do so again at some point. One of the least enjoyable experiences from that time was to deal with big CSV exports. Unfortunately, this file format is still very common in the data science space. It is easy to understand why – it seems to be ubiquitous, present everywhere, it’s human-readable, it’s less verbose than options like JSON and XML, it’s super easy to produce from almost any tool....

March 24, 2024 · 9 min · 1915 words · Robin Kåveland

Isolating integration tests that commit transactions

For tests that need to touch the database, it is generally a really good idea to roll back transactions. That way, you can run lots of tests in parallell or in any arbitrary order and the tests won’t interfere with each other. But sometimes, that just isn’t possible. One reason for this could be that the code base handles transactions in a way that makes it really hard to get a handle on them in the right place, or it could be a legacy code base where everything is running with auto-commit or some other explanation....

March 10, 2024 · 2 min · 403 words · Robin Kåveland

Protecting your postgres server from your application

There are 2 configuration options that every OLTP application that uses postgres should set, in order to protect the database from high load: statement_timeout idle_in_transaction_session_timeout These can both be set by client configuration and require no special permissions to set, and are easily overridden locally for transactions that have different requirements. They can be a bit scary to retrofit to existing applications, but we can activate two postgres extensions to help us measure our queries to find safe values to set:...

May 9, 2023 · 7 min · 1391 words · Robin Kåveland