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

Retry partially applied no-txn migrations from last failed statement #187

Merged
merged 28 commits into from
Apr 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
44d8ba5
Make `multiQueryStatement_` return a Stream, and count statements
mzabani Mar 7, 2024
2131406
Register number of applied statements in codd_schema
mzabani Mar 8, 2024
1eedf44
Also register if a no-txn migration failed
mzabani Mar 8, 2024
40483a1
Changing code so we can insert into codd_schema even on sql statement…
mzabani Mar 9, 2024
c7fac6a
Don't group no-txn migs together so retrying the block means retrying a
mzabani Mar 10, 2024
b2a3b72
Properly compute the statement number of the last `BEGIN` statement
mzabani Mar 10, 2024
f8472b8
Precise types for blocks of in/no-txn migrations, cleaner code
mzabani Mar 11, 2024
40fdf55
Correctly skip runnable-countable statements when retrying no-txn migs
mzabani Mar 17, 2024
ea2a790
Make registering applied migrations an MVar to avoid state-updating p…
mzabani Mar 21, 2024
946f9dc
Register failing no-txn migrations properly
mzabani Mar 21, 2024
d08fc02
Add runtime txnStatus check and fix places where it fails
mzabani Mar 23, 2024
cb23797
Comment on hole in type-level sandbox for transaction handling
mzabani Mar 23, 2024
e4568c3
Add new tests
mzabani Mar 23, 2024
bd351e7
Return error types instead of using exceptions, make new test pass
mzabani Mar 23, 2024
b7d2ccf
Make some error states unrepresentable with associated type families
mzabani Mar 23, 2024
0c829a2
Resuming partially applied no-txn migration on `codd up`
mzabani Mar 27, 2024
b3e5d3c
Apply in-txn migrations on non-default connection atomically when pos…
mzabani Mar 30, 2024
babcf61
Add a test for partially applied no-txn migrations
mzabani Mar 30, 2024
3aa3eb1
Move some tests from RetrySpec to ApplicationSpec
mzabani Mar 30, 2024
cd51b02
More tests for how applied migrations are registered
mzabani Mar 30, 2024
19a34d0
Test statement skipping more thoroughly
mzabani Mar 30, 2024
c202286
Tidying up a little
mzabani Mar 30, 2024
58f4c82
Avoid extraneous `COMMIT` statements being sent
mzabani Mar 30, 2024
f911023
More retry tests, fix cases broken due to COPY related exceptions
mzabani Mar 31, 2024
a8a785d
Use postgresql-simple's COPY functions and exception catching
mzabani Mar 31, 2024
0d16270
Amending documentation to include retry examples
mzabani Mar 31, 2024
6ba3513
Add test for in-txn migrations failing on COMMIT and fix this scenario
mzabani Apr 1, 2024
4dc0983
Remove `--no-apply` from `codd add`
mzabani Apr 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 21 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,21 @@

# What is Codd?

<!--toc:start-->
- [What is Codd?](#what-is-codd)
- [Installing Codd](#installing-codd)
- [1. Self-contained executable](#1-self-contained-executable)
- [2. Nix](#2-nix)
- [3. Docker](#3-docker)
- [Get codd up and running in 15 minutes](#get-codd-up-and-running-in-15-minutes)
- [Start using codd with an existing database](#start-using-codd-with-an-existing-database)
- [Safety considerations](#safety-considerations)
- [Frequently Asked Questions](#frequently-asked-questions)
- [Why does taking and restoring a database dump affect my expected codd schema?](#why-does-taking-and-restoring-a-database-dump-affect-my-expected-codd-schema)
- [Will codd run out of memory or system resources if my migration files are too large or too many?](#will-codd-run-out-of-memory-or-system-resources-if-my-migration-files-are-too-large-or-too-many)
- [Will codd handle SQL errors nicely?](#will-codd-handle-sql-errors-nicely)
<!--toc:end-->

Codd is a CLI tool that applies plain SQL migrations atomically (when PostgreSQL allows it) and includes schema equality checks that practically ensure your development database's schema matches the database schema in every other environment,
checking table columns' names, types, order, available functions, roles, table privileges, object ownership, row security policies, database encoding [and much more](/docs/DATABASE-EQUALITY.md).
These schema equality checks happen automatically; you only need to write .sql files and `codd add migration-file.sql` them. No configuration files, JSON, or YAML; just 3 environment variables and .sql files and you can use codd.
Expand Down Expand Up @@ -89,23 +104,6 @@ Automatic merge failed; fix conflicts and then commit the result.
¹ Some SQL must run without explicit transactions; single-transaction application only works when none of that is present.
² There can be false positives and false negatives in some cases.

<!-- vscode-markdown-toc -->
- [What is Codd?](#what-is-codd)
- [Installing Codd](#installing-codd)
- [1. Self-contained executable](#1-self-contained-executable)
- [2. Nix](#2-nix)
- [3. Docker](#3-docker)
- [Get codd up and running in 15 minutes](#get-codd-up-and-running-in-15-minutes)
- [Start using codd with an existing database](#start-using-codd-with-an-existing-database)
- [Safety considerations](#safety-considerations)
- [Frequently Asked Questions](#frequently-asked-questions)

<!-- vscode-markdown-toc-config
numbering=false
autoSave=true
/vscode-markdown-toc-config -->
<!-- /vscode-markdown-toc -->

## Installing Codd

### 1. Self-contained executable
Expand Down Expand Up @@ -205,3 +203,9 @@ We recommend following these instructions closely to catch as many possible issu

1. ### Why does taking and restoring a database dump affect my expected codd schema?
`pg_dump` does not dump all of the schema state that codd checks. A few examples include (at least with PG 13) role related state, the database's default transaction isolation level and deferredness, among possibly others. So check that it isn't the case that you get different schemas when that happens. We recommend using `pg_dumpall` to preserve more when possible instead. If you've checked with `psql` and everything looks to be the same please report a bug in codd.

2. ### Will codd run out of memory or system resources if my migration files are too large or too many?
Most likely not. Codd reads migrations from disk in streaming fashion and keeps in memory only a single statement at a time (modulo the garbage collector, but our CI-run benchmarks show no more than 4MB RAM are ever used on my x86 linux machine even for 1 million statements). For `COPY` statements, codd uses a constant-size buffer to stream read the contents to achieve bounded memory usage while staying fast. Also, codd does not open more than one migration file simultaneously to stay well below typical file handle limits imposed by the shell or operating system, and that is also assured through an automated test that runs in CI with `strace`.

3. ### Will codd handle SQL errors nicely?
Codd tries to do the "best possible thing" even in rather unusual situations. It will retry sets of consecutive in-txn migrations atomically so as not to leave your database in an intermediary state. Even for no-txn migrations, codd will retry the failing statement instead of entire migrations, and _even_ if you write explicit `BEGIN..COMMIT` sections in no-txn migrations, codd will be smart enough to retry from the `BEGIN` if a statement inside that section fails. See the [retry examples](/docs/SQL-MIGRATIONS.md#examples) if you're interested. What codd currently cannot handle well is having its connection killed by an external agent while it's applying a _no-txn_ migration, a scenario which should be extremely rare. Basically, we hope you should be able to write your migrations however you want and rely comfortably on the fact that codd should do the reasonable thing when handling errors.
19 changes: 5 additions & 14 deletions app/Main.hs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
module Main where

import qualified Codd
import Codd.AppCommands.AddMigration ( AddMigrationOptions(..)
, addMigration
)
import Codd.AppCommands.AddMigration ( addMigration )
import Codd.AppCommands.VerifySchema ( verifySchema )
import Codd.AppCommands.WriteSchema ( WriteSchemaOpts(..)
, writeSchema
Expand All @@ -24,7 +22,7 @@ import Options.Applicative
import qualified System.IO as IO
import qualified Text.Read as Text

data Cmd = Up (Maybe Codd.VerifySchemas) DiffTime | Add AddMigrationOptions (Maybe FilePath) (LogLevel -> Bool) SqlFilePath | WriteSchema WriteSchemaOpts | VerifySchema (LogLevel -> Bool) Bool
data Cmd = Up (Maybe Codd.VerifySchemas) DiffTime | Add (Maybe FilePath) (LogLevel -> Bool) SqlFilePath | WriteSchema WriteSchemaOpts | VerifySchema (LogLevel -> Bool) Bool

cmdParser :: Parser Cmd
cmdParser = hsubparser
Expand Down Expand Up @@ -101,13 +99,7 @@ upParser =
addParser :: Parser Cmd
addParser =
Add
<$> (AddMigrationOptions <$> switch
( long "no-apply"
<> help
"Do not apply any pending migrations, including the one being added."
)
)
<*> optionalStrOption
<$> optionalStrOption
( long "dest-folder"
<> help
"Specify the folder path where the .sql migration shall be put. If unspecified, the first folder in the 'CODD_MIGRATION_DIRS' environment variable will be used"
Expand Down Expand Up @@ -191,9 +183,8 @@ doWork dbInfo (Up mCheckSchemas connectTimeout) =
Nothing
connectTimeout
checkSchemas
doWork dbInfo (Add addOpts destFolder verbosity fp) =
runCoddLoggerLevelFilter verbosity
$ addMigration dbInfo addOpts destFolder fp
doWork dbInfo (Add destFolder verbosity fp) =
runCoddLoggerLevelFilter verbosity $ addMigration dbInfo destFolder fp
doWork dbInfo (VerifySchema verbosity fromStdin) =
runCoddLoggerLevelFilter verbosity $ verifySchema dbInfo fromStdin
doWork dbInfo (WriteSchema opts) = writeSchema dbInfo opts
1 change: 1 addition & 0 deletions codd.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ test-suite codd-test
DbDependentSpecs.AnalysisSpec
DbDependentSpecs.AppCommandsSpec
DbDependentSpecs.ApplicationSpec
DbDependentSpecs.RetrySpec
DbDependentSpecs.SchemaVerificationSpec
DbDependentSpecs.InvariantsSpec
DbUtils
Expand Down
Loading
Loading