diff options
Diffstat (limited to 'doc/development/what_requires_downtime.md')
-rw-r--r-- | doc/development/what_requires_downtime.md | 67 |
1 files changed, 33 insertions, 34 deletions
diff --git a/doc/development/what_requires_downtime.md b/doc/development/what_requires_downtime.md index 9ece6eff41e..8ea9f70fc7a 100644 --- a/doc/development/what_requires_downtime.md +++ b/doc/development/what_requires_downtime.md @@ -5,38 +5,6 @@ GitLab offline, others do require a downtime period. This guide describes various operations, their impact, and how to perform them without requiring downtime. -## Adding Columns - -You can safely add a new column to an existing table as long as it does **not** -have a default value. For example, this query would not require downtime: - -```sql -ALTER TABLE projects ADD COLUMN random_value int; -``` - -Add a column _with_ a default however does require downtime. For example, -consider this query: - -```sql -ALTER TABLE projects ADD COLUMN random_value int DEFAULT 42; -``` - -This requires updating every single row in the `projects` table so that -`random_value` is set to `42` by default. This requires updating all rows and -indexes in a table. This in turn acquires enough locks on the table for it to -effectively block any other queries. - -Adding a column with a default value _can_ be done without requiring downtime -when using the migration helper method -`Gitlab::Database::MigrationHelpers#add_column_with_default`. This method works -similar to `add_column` except it updates existing rows in batches without -blocking access to the table being modified. See ["Adding Columns With Default -Values"](migration_style_guide.md#adding-columns-with-default-values) for more -information on how to use this method. - -Note that usage of `add_column_with_default` with `allow_null: false` to also add -a `NOT NULL` constraint is [discouraged](https://gitlab.com/gitlab-org/gitlab/issues/38060). - ## Dropping Columns Removing columns is tricky because running GitLab processes may still be using @@ -171,8 +139,39 @@ Adding or removing a NOT NULL clause (or another constraint) can typically be done without requiring downtime. However, this does require that any application changes are deployed _first_. Thus, changing the constraints of a column should happen in a post-deployment migration. -NOTE: Avoid using `change_column` as it produces inefficient query because it re-defines -the whole column type. For example, to add a NOT NULL constraint, prefer `change_column_null` + +NOTE: Avoid using `change_column` as it produces an inefficient query because it re-defines +the whole column type. + +To add a NOT NULL constraint, use the `add_not_null_constraint` migration helper: + +```ruby +# A post-deployment migration in db/post_migrate +class AddNotNull < ActiveRecord::Migration[4.2] + include Gitlab::Database::MigrationHelpers + + disable_ddl_transaction! + + def up + add_not_null_constraint :users, :username + end + + def down + remove_not_null_constraint :users, :username + end +end +``` + +If the column to be updated requires cleaning first (e.g. there are `NULL` values), you should: + +1. Add the `NOT NULL` constraint with `validate: false` + + `add_not_null_constraint :users, :username, validate: false` + +1. Clean up the data with a data migration +1. Validate the `NOT NULL` constraint with a followup migration + + `validate_not_null_constraint :users, :username` ## Changing Column Types |