diff --git a/db/post_migrate/20221002234454_finalize_group_member_namespace_id_migration.rb b/db/post_migrate/20221002234454_finalize_group_member_namespace_id_migration.rb
new file mode 100644
index 0000000000000000000000000000000000000000..9c5ca6cbb422001c32150c9ef0ac8dd644458f15
--- /dev/null
+++ b/db/post_migrate/20221002234454_finalize_group_member_namespace_id_migration.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+class FinalizeGroupMemberNamespaceIdMigration < Gitlab::Database::Migration[2.0]
+  MIGRATION = 'BackfillMemberNamespaceForGroupMembers'
+  disable_ddl_transaction!
+
+  restrict_gitlab_migration gitlab_schema: :gitlab_main
+
+  def up
+    ensure_batched_background_migration_is_finished(
+      job_class_name: MIGRATION,
+      table_name: :members,
+      column_name: :id,
+      job_arguments: [],
+      finalize: true
+    )
+  end
+
+  def down
+    # no-op
+  end
+end
diff --git a/db/schema_migrations/20221002234454 b/db/schema_migrations/20221002234454
new file mode 100644
index 0000000000000000000000000000000000000000..d01230136beda27586254a0e35e14b709773b53b
--- /dev/null
+++ b/db/schema_migrations/20221002234454
@@ -0,0 +1 @@
+781ed5eaf05091e5d01ec23a9f66f3722c41b4a87ecdabe48158ce82c5cbb325
\ No newline at end of file
diff --git a/lib/gitlab/background_migration/destroy_invalid_members.rb b/lib/gitlab/background_migration/destroy_invalid_members.rb
index 17a141860ecb0e06e1d3abf6e2db90dde907735f..b274c71f24fff4a215771cdbe348e777b2fbc7ce 100644
--- a/lib/gitlab/background_migration/destroy_invalid_members.rb
+++ b/lib/gitlab/background_migration/destroy_invalid_members.rb
@@ -9,7 +9,7 @@ class DestroyInvalidMembers < Gitlab::BackgroundMigration::BatchedMigrationJob #
       def perform
         each_sub_batch do |sub_batch|
           deleted_members_data = sub_batch.map do |m|
-            { id: m.id, source_id: m.source_id, source_type: m.source_type }
+            { id: m.id, source_id: m.source_id, source_type: m.source_type, access_level: m.access_level }
           end
 
           deleted_count = sub_batch.delete_all
diff --git a/spec/lib/gitlab/background_migration/destroy_invalid_members_spec.rb b/spec/lib/gitlab/background_migration/destroy_invalid_members_spec.rb
index 9b0cb96b30b7d72a335f3c9d9186a28c8c5248aa..5059ad620aac53b9a5b3801652092fccde65ec21 100644
--- a/spec/lib/gitlab/background_migration/destroy_invalid_members_spec.rb
+++ b/spec/lib/gitlab/background_migration/destroy_invalid_members_spec.rb
@@ -103,7 +103,7 @@ def create_members
       members = create_members
 
       member_data = members.map do |m|
-        { id: m.id, source_id: m.source_id, source_type: m.source_type }
+        { id: m.id, source_id: m.source_id, source_type: m.source_type, access_level: m.access_level }
       end
 
       expect(Gitlab::AppLogger).to receive(:info).with({ message: 'Removing invalid member records',
diff --git a/spec/migrations/20221002234454_finalize_group_member_namespace_id_migration_spec.rb b/spec/migrations/20221002234454_finalize_group_member_namespace_id_migration_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..9c27005065daf393d8fa1ec6aca9bc962ada64b2
--- /dev/null
+++ b/spec/migrations/20221002234454_finalize_group_member_namespace_id_migration_spec.rb
@@ -0,0 +1,72 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe FinalizeGroupMemberNamespaceIdMigration, :migration do
+  let(:batched_migrations) { table(:batched_background_migrations) }
+
+  let_it_be(:migration) { described_class::MIGRATION }
+
+  describe '#up' do
+    shared_examples 'finalizes the migration' do
+      it 'finalizes the migration' do
+        allow_next_instance_of(Gitlab::Database::BackgroundMigration::BatchedMigrationRunner) do |runner|
+          expect(runner).to receive(:finalize).with('BackfillMemberNamespaceForGroupMembers', :members, :id, [])
+        end
+      end
+    end
+
+    context 'when migration is missing' do
+      it 'warns migration not found' do
+        expect(Gitlab::AppLogger)
+          .to receive(:warn).with(/Could not find batched background migration for the given configuration:/)
+
+        migrate!
+      end
+    end
+
+    context 'with migration present' do
+      let!(:group_member_namespace_id_backfill) do
+        batched_migrations.create!(
+          job_class_name: 'BackfillMemberNamespaceForGroupMembers',
+          table_name: :members,
+          column_name: :id,
+          job_arguments: [],
+          interval: 2.minutes,
+          min_value: 1,
+          max_value: 2,
+          batch_size: 1000,
+          sub_batch_size: 200,
+          gitlab_schema: :gitlab_main,
+          status: 3 # finished
+        )
+      end
+
+      context 'when migration finished successfully' do
+        it 'does not raise exception' do
+          expect { migrate! }.not_to raise_error
+        end
+      end
+
+      context 'with different migration statuses' do
+        using RSpec::Parameterized::TableSyntax
+
+        where(:status, :description) do
+          0 | 'paused'
+          1 | 'active'
+          4 | 'failed'
+          5 | 'finalizing'
+        end
+
+        with_them do
+          before do
+            group_member_namespace_id_backfill.update!(status: status)
+          end
+
+          it_behaves_like 'finalizes the migration'
+        end
+      end
+    end
+  end
+end