Skip to content

Commit

Permalink
Add pg-mig README and reuse common files, reshuffle files to internal/
Browse files Browse the repository at this point in the history
  • Loading branch information
dimikot committed Jan 15, 2024
1 parent 2f8abbd commit 8434660
Show file tree
Hide file tree
Showing 36 changed files with 312 additions and 130 deletions.
1 change: 1 addition & 0 deletions .eslintrc.base.js
8 changes: 6 additions & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
"use strict";
module.exports = require("../../.eslintrc.base.js")(__dirname, {
module.exports = require("./.eslintrc.base.js")(__dirname, {
"import/no-extraneous-dependencies": "error",
"lodash/import-scope": ["error", "method"],
"@typescript-eslint/explicit-function-return-type": [
"error",
{ allowExpressions: true, allowedNames: ["configure"] },
],
"lodash/import-scope": ["error", "method"]
});
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
1 change: 1 addition & 0 deletions .github/workflows/semgrep.yml
1 change: 1 addition & 0 deletions .gitignore.public
1 change: 1 addition & 0 deletions .npmignore
1 change: 1 addition & 0 deletions .npmrc
1 change: 1 addition & 0 deletions .vscode/extensions.json
1 change: 1 addition & 0 deletions .vscode/tasks.json
22 changes: 0 additions & 22 deletions LICENSE

This file was deleted.

1 change: 1 addition & 0 deletions LICENSE
126 changes: 126 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# @clickup/pg-mig: PostgreSQL schema migration tool with micro-sharding and clustering support

See also [Full API documentation](https://github.com/clickup/pg-mig/blob/master/docs/modules.md).

![CI run](https://github.com/clickup/pg-mig/actions/workflows/ci.yml/badge.svg?branch=main)

The tool allows to create a PostgreSQL database schema (with tables, indexes,
sequences, functions etc.) and apply it consistently across multiple PG hosts
(even more, across multiple micro-shard schemas on multiple hosts). The behavior
is transactional per each micro-shard per version ("all or nothing").

In other words, `pg-mig` helps to keep your database clusters' schemas identical
(each micro-shard schema will have exactly the same DDL structure as any other
schema on all other PG hosts).

# Usage

```
pg-mig
[--migdir=path/to/my-migrations/directory]
[--hosts=master1,master2,...]
[--port=5432]
[--user=user-which-can-apply-ddl]
[--pass=password]
[--db=my-database-name]
[--undo=20191107201239.my-migration-name.sh]
[--make=my-migration-name@sh]
[--parallelism=8]
[--dry]
[--list]
[--ci]
```

All of the arguments are optional: the tool tries to use `PGHOST`, `PGPORT`,
`PGUSER`, `PGPASSWORD`, `PGDATABASE` environment variables which are standard
for e.g. `psql`.

It also uses `PGMIGDIR` environment variable as a default value for `--migdir`
option.

When running in default mode, `pg-mig` tool reads (in order) the migration
versions `*.up.sql` files from the migration directory and applies them all of
the hostnames passed (of course, checking whether it has already been applied
before or not). See below for more details.

## Migration Version File Format

The migration version file name has the following format, examples:

```
20191107201239.add-table-abc.sh0000.up.sql
20191107201239.add-table-abc.sh0000.dn.sql
20231317204837.some-other-name.sh.up.sql
20231317204837.some-other-name.sh.dn.sql
20231203493744.anything-works.public.up.sql
20231203493744.anything-works.public.dn.sql
```

Here,

- the 1st part is a UTC timestamp when the migration version file was created,
- the 2nd part is a descriptive name of the migration (can be arbitrary),
- the 3rd part is the "PostgreSQL schema name prefix" (micro-shard name prefix)
- the 4th part is either "up" ("up" migration) or "dn" ("down" migration).
Up-migrations roll the database schema version forward, and down-migrations
allow to undo the changes.

It is the responsibility of the user to create up- and down-migration SQL files.
Basically, the user provides DDL SQL queries on how to roll the database schema
forward and how to roll it backward.

You can use any `psql`-specific instructions in `*.sql` files: they are fed to
`psql` tool directly. E.g. you can use environment variables, `\echo`, `\ir` for
inclusion etc. See [psql
documentation](https://www.postgresql.org/docs/current/app-psql.html) for
details.

## Applying the Migrations

Each migration version will be applied (in order) to all PG schemas (aka
micro-shards) on all hosts whose names start from the provided prefix (if
multiple migration files match some schema, then only the file with the longest
prefix will be used; in the above example, prefix "sh" effectively works as "sh*
except sh0000" wildcard).

The main idea is that, if the migration file application succeeds, then it will
be remembered on the corresponding PG host, in the corresponding schema
(micro-shard) itself. So next time when you run the tool, it will understand
that the migration version has already been applied, and won't try to apply it
again.

When the tool runs, it prints a live-updating progress, which migration version
file is in progress on which PG host in which schema (micro-shard). In the end,
it prints the final versions map across all of the hosts and schemas.

## Undoing the Migrations

If `--undo` argument is used, then the tool will try to run the down-migration
for the the corresponding version everywhere. If it succeeds, then it will
remember that fact on the corresponding PG host in the corresponding schema.
Only the very latest migration version applied can be undone.

Undoing migrations in production is not recommended (since the code which uses
the database may rely on its new structure), although you can use it of course.
The main use case for undoing the migrations is while development: you may want
to test your DDL statements multiple times, or you may pull from Git and get
someone else's migration before yours, so you'll need to undo your migration and
recreate its files.

## Creating the New Migration Files

If `--make` argument is used, `pg-mig` creates a new pair of empty files in the
migration directory. E.g. if you run:

```
pg-mig --migdir=my-dir --make=my-migration-name@sh
```

then it will create a pair of files which looks like
`my-dir/20231203493744.my-migration-name.sh.up.sql` and
`my-dir/20231203493744.my-migration-name.sh.dn.sql` which you can edit further.

New migration version files can only be appended in the end. If `pg-mig` detects
that you try to apply migrations which conflict with the existing migration
versions remembered in the database, it will print the error and refuse to
continue. This is similar to "fast-forward" mode in Git.
1 change: 1 addition & 0 deletions SECURITY.md
1 change: 1 addition & 0 deletions internal/clean.sh
1 change: 1 addition & 0 deletions internal/deploy.sh
1 change: 1 addition & 0 deletions internal/docs.sh
1 change: 1 addition & 0 deletions internal/lint.sh
5 changes: 0 additions & 5 deletions jest.config.js

This file was deleted.

1 change: 1 addition & 0 deletions jest.config.js
52 changes: 40 additions & 12 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
{
"name": "pg-mig",
"description": "Postgres database migration tool with multi-schema (sharding) support",
"version": "2.10.291",
"name": "@clickup/pg-mig",
"description": "PostgreSQL schema migration tool with micro-sharding and clustering support",
"version": "2.10.296",
"license": "MIT",
"main": "dist/cli.js",
"types": "dist/cli.d.ts",
"bin": {
"pg-mig": "./dist/cli.js"
},
"scripts": {
"build": "tsc.sh",
"dev": "tight-loop.sh tsc.sh --watch",
"lint": "lint.sh",
"test": "test.sh"
"build": "tsc",
"dev": "tsc --watch --preserveWatchOutput",
"lint": "bash internal/lint.sh",
"test": "jest",
"docs": "bash internal/docs.sh",
"clean": "bash internal/clean.sh",
"copy-package-to-public-dir": "copy-package-to-public-dir.sh",
"backport-package-from-public-dir": "backport-package-from-public-dir.sh",
"deploy": "bash internal/deploy.sh"
},
"dependencies": {
"await-semaphore": "^0.1.3",
Expand All @@ -26,13 +31,36 @@
"table-layout": "^1.0.2"
},
"devDependencies": {
"@types/shell-quote": "^1.7.1"
"@types/jest": "^29.5.5",
"@types/lodash": "^4.14.175",
"@types/minimist": "^1.2.2",
"@types/node": "^20.4.1",
"@types/pg": "^8.6.1",
"@types/prompts": "^2.4.0",
"@types/shell-quote": "^1.7.1",
"@types/sprintf-js": "^1.1.2",
"@typescript-eslint/eslint-plugin": "^5.59.6",
"@typescript-eslint/parser": "^5.59.6",
"eslint-import-resolver-typescript": "^3.5.5",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-lodash": "^7.4.0",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-typescript-enum": "^2.1.0",
"eslint-plugin-typescript-sort-keys": "^2.3.0",
"eslint-plugin-unused-imports": "^2.0.0",
"eslint": "^8.40.0",
"jest": "^29.7.0",
"prettier": "3.2.1",
"ts-jest": "^29.1.1",
"typedoc-plugin-markdown": "^3.16.0",
"typedoc-plugin-merge-modules": "^5.1.0",
"typedoc": "^0.25.2",
"typescript": "^5.2.2"
},
"repository": {
"type": "git",
"url": "git://github.com/time-loop/github-packages"
},
"publishConfig": {
"registry": "https://npm.pkg.github.com/"
"url": "git://github.com/clickup/pg-mig"
}
}
Loading

0 comments on commit 8434660

Please sign in to comment.