How Golang DB migration tool work?
--
migrate
Database migrations tool is written in Go. Use as CLI or import as a library.
The migration tool uses a schema_migrations table. One table exists for one DB.
mysql> select * from schema_migrations;
+---------+-------+
| version | dirty |
+---------+-------+
| 33 | 0 |
+---------+-------+
1 row in set (0.00 sec)
The command to apply all migrations to a DB would check-in schema_migrations
table and pick migrations after the version (for the current case – 34 and onwards).
migration upmigration down 33
The down
migration executes the down file for version 33 and updates the schema_migrations table.
Code
Migration files are read from 1..N if no version is specified.
migrate/migrate.go
// read reads either up or down migrations from source `from` to `to`.// Each migration is then written to the ret channel.// If an error occurs during reading, that error is written to the ret channel, too.// Once read is done reading it will close the ret channel.
func (m *Migrate) read(from int, to int, ret chan<- interface{})
Troubleshooting
no migration found for version
Explanation: The migration version was updated in schema_registry marked dirty but the migration files are deleted/ missing. So maybe the previous migration was done with N and then Nth files were deleted. Nowup
ordown
would not work as the schema_registry has version N.
So the solution is either to bring back Nth migrations or force the schema_regsitry version to N-1.migrate force N-1
error: Dirty database version 32. Fix and force version.
Explanation: The 33rd migration file was corrupted or had an error.
mysql> select * from schema_migrations;
+---------+-------+
| version | dirty |
+---------+-------+
| 32 | 1 |
+---------+-------+
1 row in set (0.01 sec)
Manually undo the changes of version 33 (refer to 33 down migration file) and run migrate force 32