碰到的问题
使用apt包管理器,将gitlab从18.8.2更新到18.9的时候,出现了下列的报错。
update-initramfs: Generating /boot/initrd.img-6.8.0-54-generic
Errors were encountered while processing:
gitlab-ce
needrestart is being skipped since dpkg has failed
E: Sub-process /usr/bin/dpkg returned an error code (1)
详细的报错内容是:
/opt/gitlab/embedded/bin/bundle:25:in `<main>'
Caused by:
PG::CheckViolation: ERROR: check constraint "check_96233d37c0" of relation "pool_repositories" is violated by some row
/opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/database/migrations/constraints_helpers.rb:122:in `block in validate_check_constraint'
/opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/database/migrations/timeout_helpers.rb:31:in `disable_statement_timeout'
/opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/database/migrations/constraints_helpers.rb:119:in `validate_check_constraint'
/opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/database/migrations/constraints_helpers.rb:109:in `add_check_constraint'
/opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/database/migrations/constraints_helpers.rb:218:in `add_not_null_constraint'
/opt/gitlab/embedded/service/gitlab-rails/db/post_migrate/20260209093954_add_not_null_constraint_to_pool_repositories_organization_id.rb:9:in `up'
/opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/database/migration_helpers/restrict_gitlab_schema.rb:33:in `block in exec_migration'
/opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/database/query_analyzer.rb:94:in `within'
/opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/database/migration_helpers/restrict_gitlab_schema.rb:30:in `exec_migration'
/opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/database/migration_helpers/automatic_lock_writes_on_tables.rb:21:in `exec_migration'
/opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/database/migration_helpers/require_disable_ddl_transaction_for_multiple_locks.rb:40:in `exec_migration'
/opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/database/migrations/lock_retry_mixin.rb:46:in `ddl_transaction'
/opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/database/migrations/runner_backoff/active_record_mixin.rb:21:in `execute_migration_in_transaction'
/opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/database/migrations/pg_backend_pid.rb:14:in `with_advisory_lock'
/opt/gitlab/embedded/service/gitlab-rails/lib/tasks/gitlab/db.rake:226:in `configure_database'
/opt/gitlab/embedded/service/gitlab-rails/lib/tasks/gitlab/db.rake:182:in `configure_pg_databases'
/opt/gitlab/embedded/service/gitlab-rails/lib/tasks/gitlab/db.rake:114:in `block (3 levels) in <top (required)>'
/opt/gitlab/embedded/bin/bundle:25:in `<main>'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
STDERR:
---- End output of "bash" ----
Ran "bash" returned 1
===
There was an error running gitlab-ctl reconfigure. Please check the output above for more
details.
===
dpkg: error processing package gitlab-ce (--configure):
installed gitlab-ce package post-installation script subprocess returned error exit status 1
Errors were encountered while processing:
gitlab-ce
needrestart is being skipped since dpkg has failed
E: Sub-process /usr/bin/dpkg returned an error code (1)
原因解释
这是gitlab在版本升级的时候,进行数据库迁移导致了出错。升级的时候程序正在给pool_repositories.organization_id这个数值加约束,但是原有的数据库已经存在一些行不满足这个约束。
解决方案
我们需要手动解决数据库冲突。
首先,我们先看下这个约束的具体内容
sudo gitlab-psql -d gitlabhq_production -c \
"SELECT conname, pg_get_constraintdef(oid) AS def
FROM pg_constraint
WHERE conname='check_96233d37c0';"
执行后输出内容如下:
conname | def
------------------+-------------------------------------------------
check_96233d37c0 | CHECK ((organization_id IS NOT NULL)) NOT VALID
(1 row)
可以看到这样约束是要求检查下 organization_id 是否是Null。然后我们检查下我们gitlab数据库中的organization_id
sudo gitlab-psql -d gitlabhq_production -c \
"SELECT id, organization_id
FROM pool_repositories
WHERE organization_id IS NULL
LIMIT 50;"
输出内容如下
id | organization_id
----+-----------------
1 |
(1 row)
可以看到organization_id是空值。找到了不符合的表,现在我们要手动修改下数据表,使得organization_id不为Null,让校验通过。
首先我们查一下,在当前gitlab实例中有哪些organization。查询命令如下:
sudo gitlab-psql -d gitlabhq_production -c \
"SELECT id, name, path FROM organizations ORDER BY id;"
在私有化部署中,这个输出结果中应该只有一个organization(id为1)。我的实例的输出结果如下
id | name | path
----+---------+---------
1 | Default | default
(1 row)
然后我们将表中错误的null值改为1,命令如下
sudo gitlab-psql -d gitlabhq_production -c \
"UPDATE pool_repositories
SET organization_id = 1
WHERE organization_id IS NULL;"
改完后,重新更新gitlab(重新使用apt-get upgrade指令),gitlab便能正确更新到18.9版本了。