Database – DB Migration Strategy for Docker Containers in AWS ECS

awsdatabasemicroservices

I am working on creating a set of microservices in Docker (using .net core and AWS RDS as the backbone, but that is not relevant).

As part of the deployment, the old container and new container co-exist for a short period of time (under 30 seconds usually) to ensure there is no downtime.

However, this means that if my schema is incompatible with the previous version of the microservice (or the old schema is incompatible with the new version), one set of containers will not function correctly.

My thoughts are:

  1. Do backwards-compatible migrations only. Meaning, there is no delete column migrations. I am not impressed with this approach as it would result in some clutter accumulating (granted, with the size of the microservice it won't be too bad, but it will be an unsightly schema in a couple of years time)

  2. Obsolete-remove two step deployments. Meaning in v2 we remove code consuming the schema, but not the schema itself and in v3 we remove the schema. The issue here is that either we need to do two consecutive deployments in a row, which seems stupid, or make sure developers remember to checkin those removals into the next version, which is potentially human error prone and will result in clutter accumulating again

  3. Have two types of deployments – breaking and non-breaking; with breaking deployment doing the old school stop service, migrate, bring up new service. The issue here is that there is downtime for the end users.

What would you go with, and why? (or, if you already have something else, please do tell).

Best Answer

A change should only change that which is necessary. Removing unused columns in a DB schema isn't a necessary change, it's a non-functional, maintainability kind of change. So there's no reason to lock in those changes to occur in the same iteration of any service (or, for that matter, be part of a service deployment at all).

While you certainly could work out a system that enforces a migration every deployment after a given 'breaking change' kind of deployment, this strikes me as a bit of over-optimization or YAGNI.

The way I'd handle it in one of my apps is to simply add the step to my change control process, wherein any microservice deployment has to be non-breaking as in your #1, but I'd keep track of which columns are removal candidates, and do a quarterly (or so) cleanup (with buy-in from the business users), possibly on a rolling schedule such that any proposed removed column has to go some amount of time before we actually remove it, b/c you know in many business settings the thing we're sure we'll never need again is actually a feature we see requested in six months or so.

Related Topic