Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
dc96209c
Commit
dc96209c
authored
Jun 01, 2021
by
Grzegorz Bizon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Improve pending builds migration to use better batching
parent
30e8e272
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
51 additions
and
41 deletions
+51
-41
db/post_migrate/20210520105029_copy_pending_builds_to_pending_builds_table.rb
...0520105029_copy_pending_builds_to_pending_builds_table.rb
+33
-26
spec/migrations/copy_pending_builds_to_pending_builds_table_spec.rb
...tions/copy_pending_builds_to_pending_builds_table_spec.rb
+18
-15
No files found.
db/post_migrate/20210520105029_copy_pending_builds_to_pending_builds_table.rb
View file @
dc96209c
...
@@ -3,41 +3,48 @@
...
@@ -3,41 +3,48 @@
class
CopyPendingBuildsToPendingBuildsTable
<
ActiveRecord
::
Migration
[
6.0
]
class
CopyPendingBuildsToPendingBuildsTable
<
ActiveRecord
::
Migration
[
6.0
]
include
Gitlab
::
Database
::
MigrationHelpers
include
Gitlab
::
Database
::
MigrationHelpers
BUILDS_MAX_SIZE
=
1
<<
(
32
-
1
)
BATCH_SIZE
=
10000
PENDING_BUILDS_BATCH_SIZE
=
1000
PENDING_BUILDS_MAX_BATCHES
=
BUILDS_MAX_SIZE
/
PENDING_BUILDS_BATCH_SIZE
disable_ddl_transaction!
disable_ddl_transaction!
class
Build
<
ActiveRecord
::
Base
include
EachBatch
self
.
table_name
=
'ci_builds'
self
.
inheritance_column
=
:_type_disabled
scope
:pending
,
->
do
where
(
status:
'pending'
)
.
where
(
type:
'Ci::Build'
)
.
where
(
'updated_at > ?'
,
24
.
hours
.
ago
)
.
order
(
'id ASC'
)
end
end
def
up
def
up
1
.
step
do
|
i
|
Build
.
pending
.
limit
(
1
).
pluck
(
:id
).
first
.
try
do
|
id
|
inserts
=
execute
<<~
SQL
Build
.
where
(
'id >= ?'
,
id
).
each_batch
(
of:
BATCH_SIZE
)
do
|
batch
|
WITH pending_builds AS (
min_id
,
max_id
=
batch
.
pluck
(
'MIN(id), MAX(id)'
).
first
SELECT id,
project_id
execute
<<~
SQL
FROM ci_builds
WITH pending_builds AS (
WHERE status = 'pending'
SELECT id,
AND type = 'Ci::Build'
project_id
AND NOT EXISTS (
FROM ci_builds
SELECT 1 FROM ci_pending_builds
WHERE status = 'pending'
WHERE ci_pending_builds.build_id = ci_builds.id
AND type = 'Ci::Build'
)
AND NOT EXISTS (
LIMIT
#{
PENDING_BUILDS_BATCH_SIZE
}
SELECT 1 FROM ci_pending_builds
), inserts AS (
WHERE ci_pending_builds.build_id = ci_builds.id
)
AND id BETWEEN
#{
min_id
}
AND
#{
max_id
}
)
INSERT INTO ci_pending_builds (build_id, project_id)
INSERT INTO ci_pending_builds (build_id, project_id)
SELECT id,
SELECT id,
project_id
project_id
FROM pending_builds
FROM pending_builds
ON CONFLICT DO NOTHING
ON CONFLICT DO NOTHING
RETURNING id
SQL
)
SELECT COUNT(*) FROM inserts;
SQL
break
if
inserts
.
values
.
flatten
.
first
.
to_i
==
0
if
i
>
PENDING_BUILDS_MAX_BATCHES
raise
'There are too many pending builds in your database! Aborting.'
end
end
end
end
end
end
...
...
spec/migrations/copy_pending_builds_to_pending_builds_table_spec.rb
View file @
dc96209c
...
@@ -13,13 +13,14 @@ RSpec.describe CopyPendingBuildsToPendingBuildsTable do
...
@@ -13,13 +13,14 @@ RSpec.describe CopyPendingBuildsToPendingBuildsTable do
namespaces
.
create!
(
id:
123
,
name:
'sample'
,
path:
'sample'
)
namespaces
.
create!
(
id:
123
,
name:
'sample'
,
path:
'sample'
)
projects
.
create!
(
id:
123
,
name:
'sample'
,
path:
'sample'
,
namespace_id:
123
)
projects
.
create!
(
id:
123
,
name:
'sample'
,
path:
'sample'
,
namespace_id:
123
)
builds
.
create!
(
id:
1
,
project_id:
123
,
status:
'pending'
,
type:
'Ci::Build'
)
builds
.
create!
(
id:
1
,
project_id:
123
,
status:
'pending'
,
type:
'Ci::Build'
,
created_at:
4
.
days
.
ago
,
updated_at:
4
.
days
.
ago
)
builds
.
create!
(
id:
2
,
project_id:
123
,
status:
'pending'
,
type:
'
GenericCommitStatus
'
)
builds
.
create!
(
id:
2
,
project_id:
123
,
status:
'pending'
,
type:
'
Ci::Build
'
)
builds
.
create!
(
id:
3
,
project_id:
123
,
status:
'pending'
,
type:
'GenericCommitStatus'
)
builds
.
create!
(
id:
3
,
project_id:
123
,
status:
'pending'
,
type:
'GenericCommitStatus'
)
builds
.
create!
(
id:
4
,
project_id:
123
,
status:
'pending'
,
type:
'
Ci::Bridge
'
)
builds
.
create!
(
id:
4
,
project_id:
123
,
status:
'pending'
,
type:
'
GenericCommitStatus
'
)
builds
.
create!
(
id:
5
,
project_id:
123
,
status:
'
running'
,
type:
'Ci::Build
'
)
builds
.
create!
(
id:
5
,
project_id:
123
,
status:
'
pending'
,
type:
'Ci::Bridge
'
)
builds
.
create!
(
id:
6
,
project_id:
123
,
status:
'pending'
,
type:
'Ci::Build'
)
builds
.
create!
(
id:
6
,
project_id:
123
,
status:
'pending'
,
type:
'Ci::Build'
)
builds
.
create!
(
id:
7
,
project_id:
123
,
status:
'created'
,
type:
'Ci::Build'
)
builds
.
create!
(
id:
7
,
project_id:
123
,
status:
'running'
,
type:
'Ci::Build'
)
builds
.
create!
(
id:
8
,
project_id:
123
,
status:
'created'
,
type:
'Ci::Build'
)
end
end
context
'when there are new pending builds present'
do
context
'when there are new pending builds present'
do
...
@@ -27,13 +28,13 @@ RSpec.describe CopyPendingBuildsToPendingBuildsTable do
...
@@ -27,13 +28,13 @@ RSpec.describe CopyPendingBuildsToPendingBuildsTable do
migrate!
migrate!
expect
(
queue
.
all
.
count
).
to
eq
2
expect
(
queue
.
all
.
count
).
to
eq
2
expect
(
queue
.
all
.
pluck
(
:build_id
)).
to
match_array
([
1
,
6
])
expect
(
queue
.
all
.
pluck
(
:build_id
)).
to
match_array
([
2
,
6
])
end
end
end
end
context
'when there are pending builds already migrated present'
do
context
'when there are pending builds already migrated present'
do
before
do
before
do
queue
.
create!
(
id:
1
,
build_id:
1
,
project_id:
123
)
queue
.
create!
(
id:
1
,
build_id:
2
,
project_id:
123
)
end
end
it
'does not copy entries that have already been copied'
do
it
'does not copy entries that have already been copied'
do
...
@@ -42,31 +43,33 @@ RSpec.describe CopyPendingBuildsToPendingBuildsTable do
...
@@ -42,31 +43,33 @@ RSpec.describe CopyPendingBuildsToPendingBuildsTable do
migrate!
migrate!
expect
(
queue
.
all
.
count
).
to
eq
2
expect
(
queue
.
all
.
count
).
to
eq
2
expect
(
queue
.
all
.
pluck
(
:build_id
)).
to
match_array
([
1
,
6
])
expect
(
queue
.
all
.
pluck
(
:build_id
)).
to
match_array
([
2
,
6
])
end
end
end
end
context
'when there is more than one batch of pending builds to migrate'
do
context
'when there is more than one batch of pending builds to migrate'
do
before
do
before
do
stub_const
(
"
#{
described_class
}
::
PENDING_BUILDS_BATCH_SIZE"
,
1
)
stub_const
(
"
#{
described_class
}
::
BATCH_SIZE"
,
2
)
end
end
it
'correctly migrates data and exits after doing that'
do
it
'correctly migrates data and exits after doing that'
do
migrate!
migrate!
expect
(
queue
.
all
.
count
).
to
eq
2
expect
(
queue
.
all
.
count
).
to
eq
2
expect
(
queue
.
all
.
pluck
(
:build_id
)).
to
match_array
([
1
,
6
])
expect
(
queue
.
all
.
pluck
(
:build_id
)).
to
match_array
([
2
,
6
])
end
end
end
end
context
'when
batches limit has been exceed
ed'
do
context
'when
an old build has been recently updat
ed'
do
before
do
before
do
stub_const
(
"
#{
described_class
}
::PENDING_BUILDS_BATCH_SIZE"
,
1
)
builds
.
find
(
1
).
touch
stub_const
(
"
#{
described_class
}
::PENDING_BUILDS_MAX_BATCHES"
,
1
)
end
end
it
'raises an error'
do
it
'migrates it as well'
do
expect
{
migrate!
}.
to
raise_error
(
StandardError
,
/too many pending builds/
)
migrate!
expect
(
queue
.
all
.
count
).
to
eq
3
expect
(
queue
.
all
.
pluck
(
:build_id
)).
to
match_array
([
1
,
2
,
6
])
end
end
end
end
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment