Skip to content

Implement with_lock_retries migration helper

Adam Hegyi requested to merge 36859-implement-db-lock-retry-mechanism into master

What does this MR do?

Retries SQL statements with built in sleep time and lock timeout.

How to test

  1. Create a test migration.
rails g migration test_migration
  1. Change the content to drop analytics_repository_file_commits table. (Don't worry, it's not in use)
# frozen_string_literal: true

class TestMigration < ActiveRecord::Migration[5.2]
  include Gitlab::Database::MigrationHelpers

  DOWNTIME = false

  def up
    with_lock_retries do
      drop_table :analytics_repository_file_commits
    end
  end

  def down
    with_lock_retries do
      create_table :analytics_repository_file_commits do |t|
        t.references :analytics_repository_file, index: { name: 'index_analytics_repository_file_commits_file_id' }, foreign_key: { on_delete: :cascade }, null: false
        t.references :project, index: false, foreign_key: { on_delete: :cascade }, null: false
        t.date :committed_date, null: false
        t.integer :commit_count, limit: 2, null: false
      end

      add_index :analytics_repository_file_commits,
        [:project_id, :committed_date, :analytics_repository_file_id],
        name: 'index_file_commits_on_committed_date_file_id_and_project_id',
        unique: true

    end
  end
end
  1. Lock the projects table.

Notice that the table has a reference to projects, let's lock it in the dbconsole: rails dbconsole (separate terminal)

begin;
LOCK TABLE projects in exclusive mode;
  1. Tail migrations.log (separate terminal)
# cd gitlab rails root

touch log/migrations.log
tail -f log/migrations.log
  1. Migrate the DB
rake db:migrate
  1. Notice the retry log messages showing up.
  2. Finish the transaction in the dbconsole: END;
  3. Next iteration should finish the migration.

Conformity

Availability and Testing

Closes #36859 (closed)

Edited by 🤖 GitLab Bot 🤖

Merge request reports