Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
李少辉-开发者
gitlab-foss
提交
45999bfd
G
gitlab-foss
项目概览
李少辉-开发者
/
gitlab-foss
通知
15
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
gitlab-foss
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
45999bfd
编写于
4月 27, 2020
作者:
G
GitLab Bot
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add latest changes from gitlab-org/gitlab@master
上级
39fa1b59
变更
12
隐藏空白更改
内联
并排
Showing
12 changed file
with
172 addition
and
12 deletion
+172
-12
app/models/snippet.rb
app/models/snippet.rb
+4
-0
app/services/users/migrate_to_ghost_user_service.rb
app/services/users/migrate_to_ghost_user_service.rb
+6
-0
changelogs/unreleased/28560_cleanup_optimistic_locking_db_pt2-second-try.yml
...ed/28560_cleanup_optimistic_locking_db_pt2-second-try.yml
+5
-0
db/post_migrate/20200128210353_cleanup_optimistic_locking_nulls.rb
...igrate/20200128210353_cleanup_optimistic_locking_nulls.rb
+1
-1
db/post_migrate/20200217210353_cleanup_optimistic_locking_nulls_pt2.rb
...te/20200217210353_cleanup_optimistic_locking_nulls_pt2.rb
+7
-0
db/post_migrate/20200427064130_cleanup_optimistic_locking_nulls_pt2_fixed.rb
...00427064130_cleanup_optimistic_locking_nulls_pt2_fixed.rb
+47
-0
db/structure.sql
db/structure.sql
+8
-0
lib/gitlab/database/migration_helpers.rb
lib/gitlab/database/migration_helpers.rb
+9
-2
spec/lib/gitlab/database/migration_helpers_spec.rb
spec/lib/gitlab/database/migration_helpers_spec.rb
+25
-4
spec/migrations/cleanup_optimistic_locking_nulls_pt2_fixed_spec.rb
...ations/cleanup_optimistic_locking_nulls_pt2_fixed_spec.rb
+45
-0
spec/services/users/destroy_service_spec.rb
spec/services/users/destroy_service_spec.rb
+9
-5
spec/services/users/migrate_to_ghost_user_service_spec.rb
spec/services/users/migrate_to_ghost_user_service_spec.rb
+6
-0
未找到文件。
app/models/snippet.rb
浏览文件 @
45999bfd
...
...
@@ -102,6 +102,10 @@ class Snippet < ApplicationRecord
where
(
project_id:
nil
)
end
def
self
.
only_project_snippets
where
.
not
(
project_id:
nil
)
end
def
self
.
only_include_projects_visible_to
(
current_user
=
nil
)
levels
=
Gitlab
::
VisibilityLevel
.
levels_for_user
(
current_user
)
...
...
app/services/users/migrate_to_ghost_user_service.rb
浏览文件 @
45999bfd
...
...
@@ -52,6 +52,7 @@ module Users
migrate_notes
migrate_abuse_reports
migrate_award_emoji
migrate_snippets
end
# rubocop: disable CodeReuse/ActiveRecord
...
...
@@ -79,6 +80,11 @@ module Users
def
migrate_award_emoji
user
.
award_emoji
.
update_all
(
user_id:
ghost_user
.
id
)
end
def
migrate_snippets
snippets
=
user
.
snippets
.
only_project_snippets
snippets
.
update_all
(
author_id:
ghost_user
.
id
)
end
end
end
...
...
changelogs/unreleased/28560_cleanup_optimistic_locking_db_pt2-second-try.yml
0 → 100644
浏览文件 @
45999bfd
---
title
:
Set NULL `lock_version` values to 0 for CI objects
merge_request
:
30305
author
:
type
:
fixed
db/post_migrate/20200128210353_cleanup_optimistic_locking_nulls.rb
浏览文件 @
45999bfd
...
...
@@ -31,7 +31,7 @@ class CleanupOptimisticLockingNulls < ActiveRecord::Migration[5.2]
'CleanupOptimisticLockingNulls'
,
2
.
minutes
,
batch_size:
BATCH_SIZE
,
other_arguments:
[
table
]
other_
job_
arguments:
[
table
]
)
end
end
...
...
db/post_migrate/20200217210353_cleanup_optimistic_locking_nulls_pt2.rb
0 → 100644
浏览文件 @
45999bfd
# frozen_string_literal: true
class
CleanupOptimisticLockingNullsPt2
<
ActiveRecord
::
Migration
[
5.2
]
def
change
# no-op: the MR that contained this migration was reverted
end
end
db/post_migrate/20200427064130_cleanup_optimistic_locking_nulls_pt2_fixed.rb
0 → 100644
浏览文件 @
45999bfd
# frozen_string_literal: true
class
CleanupOptimisticLockingNullsPt2Fixed
<
ActiveRecord
::
Migration
[
6.0
]
include
Gitlab
::
Database
::
MigrationHelpers
DOWNTIME
=
false
disable_ddl_transaction!
TABLES
=
%w(ci_stages ci_builds ci_pipelines)
.
freeze
BATCH_SIZE
=
10_000
def
declare_class
(
table
)
Class
.
new
(
ActiveRecord
::
Base
)
do
include
EachBatch
self
.
table_name
=
table
self
.
inheritance_column
=
:_type_disabled
# Disable STI
end
end
def
up
last_table_final_delay
=
0
TABLES
.
each
do
|
table
|
# cleanup wrong index created in the previous migration, it might be there on staging
remove_concurrent_index
table
.
to_sym
,
:lock_version
,
where:
"lock_version IS NULL"
add_concurrent_index
table
.
to_sym
,
:id
,
where:
"lock_version IS NULL"
,
name:
"tmp_index_
#{
table
}
_lock_version"
last_table_final_delay
=
queue_background_migration_jobs_by_range_at_intervals
(
declare_class
(
table
).
where
(
lock_version:
nil
),
'CleanupOptimisticLockingNulls'
,
2
.
minutes
,
batch_size:
BATCH_SIZE
,
other_job_arguments:
[
table
],
initial_delay:
last_table_final_delay
)
end
end
def
down
TABLES
.
each
do
|
table
|
remove_concurrent_index
table
.
to_sym
,
:id
,
where:
"lock_version IS NULL"
,
name:
"tmp_index_
#{
table
}
_lock_version"
end
end
end
db/structure.sql
浏览文件 @
45999bfd
...
...
@@ -10723,6 +10723,12 @@ CREATE INDEX tmp_build_stage_position_index ON public.ci_builds USING btree (sta
CREATE
INDEX
tmp_idx_on_user_id_where_bio_is_filled
ON
public
.
users
USING
btree
(
id
)
WHERE
((
COALESCE
(
bio
,
''
::
character
varying
))::
text
IS
DISTINCT
FROM
''
::
text
);
CREATE
INDEX
tmp_index_ci_builds_lock_version
ON
public
.
ci_builds
USING
btree
(
id
)
WHERE
(
lock_version
IS
NULL
);
CREATE
INDEX
tmp_index_ci_pipelines_lock_version
ON
public
.
ci_pipelines
USING
btree
(
id
)
WHERE
(
lock_version
IS
NULL
);
CREATE
INDEX
tmp_index_ci_stages_lock_version
ON
public
.
ci_stages
USING
btree
(
id
)
WHERE
(
lock_version
IS
NULL
);
CREATE
UNIQUE
INDEX
users_security_dashboard_projects_unique_index
ON
public
.
users_security_dashboard_projects
USING
btree
(
project_id
,
user_id
);
CREATE
UNIQUE
INDEX
vulnerability_feedback_unique_idx
ON
public
.
vulnerability_feedback
USING
btree
(
project_id
,
category
,
feedback_type
,
project_fingerprint
);
...
...
@@ -13257,6 +13263,7 @@ COPY "schema_migrations" (version) FROM STDIN;
20200214214934
20200215222507
20200215225103
20200217210353
20200217223651
20200217225719
20200218113721
...
...
@@ -13484,5 +13491,6 @@ COPY "schema_migrations" (version) FROM STDIN;
20200423080607
20200423081409
20200424050250
20200427064130
\
.
lib/gitlab/database/migration_helpers.rb
浏览文件 @
45999bfd
...
...
@@ -1063,6 +1063,8 @@ into similar problems in the future (e.g. when new tables are created).
# batch_size - The maximum number of rows per job
# other_arguments - Other arguments to send to the job
#
# *Returns the final migration delay*
#
# Example:
#
# class Route < ActiveRecord::Base
...
...
@@ -1079,7 +1081,7 @@ into similar problems in the future (e.g. when new tables are created).
# # do something
# end
# end
def
queue_background_migration_jobs_by_range_at_intervals
(
model_class
,
job_class_name
,
delay_interval
,
batch_size:
BACKGROUND_MIGRATION_BATCH_SIZE
,
other_
arguments:
[]
)
def
queue_background_migration_jobs_by_range_at_intervals
(
model_class
,
job_class_name
,
delay_interval
,
batch_size:
BACKGROUND_MIGRATION_BATCH_SIZE
,
other_
job_arguments:
[],
initial_delay:
0
)
raise
"
#{
model_class
}
does not have an ID to use for batch ranges"
unless
model_class
.
column_names
.
include?
(
'id'
)
# To not overload the worker too much we enforce a minimum interval both
...
...
@@ -1088,14 +1090,19 @@ into similar problems in the future (e.g. when new tables are created).
delay_interval
=
BackgroundMigrationWorker
.
minimum_interval
end
final_delay
=
nil
model_class
.
each_batch
(
of:
batch_size
)
do
|
relation
,
index
|
start_id
,
end_id
=
relation
.
pluck
(
Arel
.
sql
(
'MIN(id), MAX(id)'
)).
first
# `BackgroundMigrationWorker.bulk_perform_in` schedules all jobs for
# the same time, which is not helpful in most cases where we wish to
# spread the work over time.
migrate_in
(
delay_interval
*
index
,
job_class_name
,
[
start_id
,
end_id
]
+
other_arguments
)
final_delay
=
initial_delay
+
delay_interval
*
index
migrate_in
(
final_delay
,
job_class_name
,
[
start_id
,
end_id
]
+
other_job_arguments
)
end
final_delay
end
# Fetches indexes on a column by name for postgres.
...
...
spec/lib/gitlab/database/migration_helpers_spec.rb
浏览文件 @
45999bfd
...
...
@@ -1365,6 +1365,14 @@ describe Gitlab::Database::MigrationHelpers do
end
end
it
'returns the final expected delay'
do
Sidekiq
::
Testing
.
fake!
do
final_delay
=
model
.
queue_background_migration_jobs_by_range_at_intervals
(
User
,
'FooJob'
,
10
.
minutes
,
batch_size:
2
)
expect
(
final_delay
.
to_f
).
to
eq
(
20
.
minutes
.
to_f
)
end
end
context
'with batch_size option'
do
it
'queues jobs correctly'
do
Sidekiq
::
Testing
.
fake!
do
...
...
@@ -1389,12 +1397,25 @@ describe Gitlab::Database::MigrationHelpers do
end
end
context
'with other_arguments option'
do
context
'with other_job_arguments option'
do
it
'queues jobs correctly'
do
Sidekiq
::
Testing
.
fake!
do
model
.
queue_background_migration_jobs_by_range_at_intervals
(
User
,
'FooJob'
,
10
.
minutes
,
other_job_arguments:
[
1
,
2
])
expect
(
BackgroundMigrationWorker
.
jobs
[
0
][
'args'
]).
to
eq
([
'FooJob'
,
[
id1
,
id3
,
1
,
2
]])
expect
(
BackgroundMigrationWorker
.
jobs
[
0
][
'at'
]).
to
eq
(
10
.
minutes
.
from_now
.
to_f
)
end
end
end
context
'with initial_delay option'
do
it
'queues jobs correctly'
do
model
.
queue_background_migration_jobs_by_range_at_intervals
(
User
,
'FooJob'
,
10
.
minutes
,
other_arguments:
[
1
,
2
])
Sidekiq
::
Testing
.
fake!
do
model
.
queue_background_migration_jobs_by_range_at_intervals
(
User
,
'FooJob'
,
10
.
minutes
,
other_job_arguments:
[
1
,
2
],
initial_delay:
10
.
minutes
)
expect
(
BackgroundMigrationWorker
.
jobs
[
0
][
'args'
]).
to
eq
([
'FooJob'
,
[
id1
,
id3
,
1
,
2
]])
expect
(
BackgroundMigrationWorker
.
jobs
[
0
][
'at'
]).
to
eq
(
10
.
minutes
.
from_now
.
to_f
)
expect
(
BackgroundMigrationWorker
.
jobs
[
0
][
'args'
]).
to
eq
([
'FooJob'
,
[
id1
,
id3
,
1
,
2
]])
expect
(
BackgroundMigrationWorker
.
jobs
[
0
][
'at'
]).
to
eq
(
20
.
minutes
.
from_now
.
to_f
)
end
end
end
end
...
...
spec/migrations/cleanup_optimistic_locking_nulls_pt2_fixed_spec.rb
0 → 100644
浏览文件 @
45999bfd
# frozen_string_literal: true
require
'spec_helper'
require
Rails
.
root
.
join
(
'db'
,
'post_migrate'
,
'20200427064130_cleanup_optimistic_locking_nulls_pt2_fixed.rb'
)
describe
CleanupOptimisticLockingNullsPt2Fixed
,
:migration
do
TABLES
=
%w(ci_stages ci_builds ci_pipelines)
.
freeze
TABLES
.
each
do
|
table
|
let
(
table
.
to_sym
)
{
table
(
table
.
to_sym
)
}
end
let
(
:tables
)
{
TABLES
.
map
{
|
t
|
method
(
t
.
to_sym
).
call
}
}
before
do
# Create necessary rows
ci_stages
.
create!
ci_builds
.
create!
ci_pipelines
.
create!
# Nullify `lock_version` column for all rows
# Needs to be done with a SQL fragment, otherwise Rails will coerce it to 0
tables
.
each
do
|
table
|
table
.
update_all
(
'lock_version = NULL'
)
end
end
it
'correctly migrates nullified lock_version column'
,
:sidekiq_might_not_need_inline
do
tables
.
each
do
|
table
|
expect
(
table
.
where
(
lock_version:
nil
).
count
).
to
eq
(
1
)
end
tables
.
each
do
|
table
|
expect
(
table
.
where
(
lock_version:
0
).
count
).
to
eq
(
0
)
end
migrate!
tables
.
each
do
|
table
|
expect
(
table
.
where
(
lock_version:
nil
).
count
).
to
eq
(
0
)
end
tables
.
each
do
|
table
|
expect
(
table
.
where
(
lock_version:
0
).
count
).
to
eq
(
1
)
end
end
end
spec/services/users/destroy_service_spec.rb
浏览文件 @
45999bfd
...
...
@@ -42,13 +42,11 @@ describe Users::DestroyService do
it
'calls the bulk snippet destroy service for the user personal snippets'
do
repo1
=
create
(
:personal_snippet
,
:repository
,
author:
user
).
snippet_repository
repo2
=
create
(
:project_snippet
,
:repository
,
author:
user
).
snippet_repository
repo3
=
create
(
:project_snippet
,
:repository
,
project:
project
,
author:
user
).
snippet_repository
repo2
=
create
(
:project_snippet
,
:repository
,
project:
project
,
author:
user
).
snippet_repository
aggregate_failures
do
expect
(
gitlab_shell
.
repository_exists?
(
repo1
.
shard_name
,
repo1
.
disk_path
+
'.git'
)).
to
be_truthy
expect
(
gitlab_shell
.
repository_exists?
(
repo2
.
shard_name
,
repo2
.
disk_path
+
'.git'
)).
to
be_truthy
expect
(
gitlab_shell
.
repository_exists?
(
repo3
.
shard_name
,
repo3
.
disk_path
+
'.git'
)).
to
be_truthy
end
# Call made when destroying user personal projects
...
...
@@ -59,17 +57,23 @@ describe Users::DestroyService do
# project snippets where projects are not user personal
# ones
expect
(
Snippets
::
BulkDestroyService
).
to
receive
(
:new
)
.
with
(
admin
,
user
.
snippets
).
and_call_original
.
with
(
admin
,
user
.
snippets
.
only_personal_snippets
).
and_call_original
service
.
execute
(
user
)
aggregate_failures
do
expect
(
gitlab_shell
.
repository_exists?
(
repo1
.
shard_name
,
repo1
.
disk_path
+
'.git'
)).
to
be_falsey
expect
(
gitlab_shell
.
repository_exists?
(
repo2
.
shard_name
,
repo2
.
disk_path
+
'.git'
)).
to
be_falsey
expect
(
gitlab_shell
.
repository_exists?
(
repo3
.
shard_name
,
repo3
.
disk_path
+
'.git'
)).
to
be_falsey
end
end
it
'does not delete project snippets that the user is the author of'
do
repo
=
create
(
:project_snippet
,
:repository
,
author:
user
).
snippet_repository
service
.
execute
(
user
)
expect
(
gitlab_shell
.
repository_exists?
(
repo
.
shard_name
,
repo
.
disk_path
+
'.git'
)).
to
be_truthy
expect
(
User
.
ghost
.
snippets
).
to
include
(
repo
.
snippet
)
end
context
'when an error is raised deleting snippets'
do
it
'does not delete user'
do
snippet
=
create
(
:personal_snippet
,
:repository
,
author:
user
)
...
...
spec/services/users/migrate_to_ghost_user_service_spec.rb
浏览文件 @
45999bfd
...
...
@@ -78,6 +78,12 @@ describe Users::MigrateToGhostUserService do
end
end
context
'snippets'
do
include_examples
"migrating a deleted user's associated records to the ghost user"
,
Snippet
do
let
(
:created_record
)
{
create
(
:snippet
,
project:
project
,
author:
user
)
}
end
end
context
"when record migration fails with a rollback exception"
do
before
do
expect_any_instance_of
(
ActiveRecord
::
Associations
::
CollectionProxy
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录