升级 PostgreSQL 的操作系统
如果您升级了运行 PostgreSQL 的操作系统,对区域设置数据的更改可能会损坏数据库索引。特别是,升级到 glibc
2.28 可能会导致此问题。为了避免此问题,可以使用以下选项之一进行迁移,按复杂性顺序排列:
在尝试任何迁移之前,请务必备份,并在类似生产环境中验证迁移过程。如果停机时间可能成为问题,请考虑使用生产数据副本在类似生产环境中测试不同的方法。
如果您运行的是扩展的极狐GitLab 环境,并且在运行 PostgreSQL 的节点上没有其他服务运行,那么我们建议仅升级 PostgreSQL 节点的操作系统。为减少复杂性和风险,请不要将此过程与其他更改结合,特别是那些不需要停机的更改,例如仅升级运行 Puma 或 Sidekiq 的节点的操作系统。
备份和恢复
备份和恢复会重新创建整个数据库,包括索引。
-
安排一个停机窗口。在所有节点中,停止不必要的极狐GitLab 服务:
gitlab-ctl stop gitlab-ctl start postgresql
- 使用
pg_dump
或 极狐GitLab 备份工具,排除所有数据类型(除db
) 备份 PostgreSQL 数据库(因此仅备份数据库)。 - 在所有 PostgreSQL 节点中,升级操作系统。
- 在所有 PostgreSQL 节点中,升级操作系统后更新极狐GitLab 软件包源。
- 在所有 PostgreSQL 节点中,安装相同极狐GitLab 版本的新极狐GitLab 软件包。
- 从备份中恢复 PostgreSQL 数据库。
- 在所有节点中,启动极狐GitLab。
优点:
- 简单明了。
- 消除索引和表中的任何数据库膨胀,减少磁盘使用。
缺点:
- 随着数据库大小增加,停机时间也增加,在某些情况下可能成为问题。取决于许多因素,但如果您的数据库超过 100 GB,则可能需要大约 24 小时。
备份和恢复,带 Geo 辅助站点
-
安排一个停机窗口。在所有站点的所有节点中,停止不必要的极狐GitLab 服务:
gitlab-ctl stop gitlab-ctl start postgresql
- 在主站点,使用
pg_dump
或 极狐GitLab 备份工具,排除所有数据类型(除db
) 备份 PostgreSQL 数据库(因此仅备份数据库)。 - 在所有站点的所有 PostgreSQL 节点中,升级操作系统。
- 在所有站点的所有 PostgreSQL 节点中,升级操作系统后更新极狐GitLab 软件包源。
- 在所有站点的所有 PostgreSQL 节点中,安装相同极狐GitLab 版本的新极狐GitLab 软件包。
- 在主站点,从备份中恢复 PostgreSQL 数据库。
- 可选地,开始使用主站点,冒着没有辅助站点作为热备用的风险。
- 再次设置 PostgreSQL 流复制到辅助站点。
- 如果辅助站点从用户接收流量,则让只读副本数据库赶上后再启动极狐GitLab。
- 在所有站点的所有节点中,启动极狐GitLab。
重建所有索引
-
安排一个停机窗口。在所有节点中,停止不必要的极狐GitLab 服务:
gitlab-ctl stop gitlab-ctl start postgresql
- 在所有 PostgreSQL 节点中,升级操作系统。
- 在所有 PostgreSQL 节点中,升级操作系统后更新极狐GitLab 软件包源。
- 在所有 PostgreSQL 节点中,安装相同极狐GitLab 版本的新极狐GitLab 软件包。
-
在 数据库控制台 中,重建所有索引:
SET statement_timeout = 0; REINDEX DATABASE gitlabhq_production;
-
在重新索引数据库后,必须刷新所有受影响的排序版本。要更新系统目录以记录当前的排序版本:
ALTER COLLATION <collation_name> REFRESH VERSION;
- 在所有节点中,启动极狐GitLab。
优点:
- 简单明了。
- 可能比备份和恢复更快,具体取决于许多因素。
- 消除索引中的任何数据库膨胀,减少磁盘使用。
缺点:
- 随着数据库大小增加,停机时间也增加,在某些情况下可能成为问题。
重建所有索引,带 Geo 辅助站点
-
安排一个停机窗口。在所有站点的所有节点中,停止不必要的极狐GitLab 服务:
gitlab-ctl stop gitlab-ctl start postgresql
- 在所有 PostgreSQL 节点中,升级操作系统。
- 在所有 PostgreSQL 节点中,升级操作系统后更新极狐GitLab 软件包源。
- 在所有 PostgreSQL 节点中,安装相同极狐GitLab 版本的新极狐GitLab 软件包。
-
在主站点,在 数据库控制台 中,重建所有索引:
SET statement_timeout = 0; REINDEX DATABASE gitlabhq_production;
-
在重新索引数据库后,必须刷新所有受影响的排序版本。要更新系统目录以记录当前的排序版本:
ALTER COLLATION <collation_name> REFRESH VERSION;
- 如果辅助站点从用户接收流量,则让只读副本数据库赶上后再启动极狐GitLab。
- 在所有站点的所有节点中,启动极狐GitLab。
仅重建受影响的索引
这类似于用于 JihuLab.com 的方法。
-
安排一个停机窗口。在所有节点中,停止不必要的极狐GitLab 服务:
gitlab-ctl stop gitlab-ctl start postgresql
- 在所有 PostgreSQL 节点中,升级操作系统。
- 在所有 PostgreSQL 节点中,升级操作系统后更新极狐GitLab 软件包源。
- 在所有 PostgreSQL 节点中,安装相同极狐GitLab 版本的新极狐GitLab 软件包。
- 确定哪些索引受到影响。
-
在 数据库控制台 中,重新索引每个受影响的索引:
SET statement_timeout = 0; REINDEX INDEX <index name> CONCURRENTLY;
-
在重新索引坏的索引后,必须刷新排序。要更新系统目录以记录当前的排序版本:
ALTER COLLATION <collation_name> REFRESH VERSION;
- 在所有节点中,启动极狐GitLab。
优点:
- 停机时间不花在重建不受影响的索引上。
缺点:
- 更容易出错。
- 需要 PostgreSQL 专家知识以应对迁移过程中出现的意外问题。
- 保留数据库膨胀。
仅重建受影响的索引,带 Geo 辅助站点
-
安排一个停机窗口。在所有站点的所有节点中,停止不必要的极狐GitLab 服务:
gitlab-ctl stop gitlab-ctl start postgresql
- 在所有 PostgreSQL 节点中,升级操作系统。
- 在所有 PostgreSQL 节点中,升级操作系统后更新极狐GitLab 软件包源。
- 在所有 PostgreSQL 节点中,安装相同极狐GitLab 版本的新极狐GitLab 软件包。
- 确定哪些索引受到影响。
-
在主站点,在 数据库控制台 中,重新索引每个受影响的索引:
SET statement_timeout = 0; REINDEX INDEX <index name> CONCURRENTLY;
-
在重新索引坏的索引后,必须刷新排序。要更新系统目录以记录当前的排序版本:
ALTER COLLATION <collation_name> REFRESH VERSION;
- 现有的 PostgreSQL 流复制应将重新索引更改复制到只读副本数据库。
- 在所有站点的所有节点中,启动极狐GitLab。
检查 glibc
版本
要查看使用的 glibc
版本,请运行 ldd --version
。
下表显示了不同操作系统附带的 glibc
版本:
操作系统 |
glibc 版本
|
---|---|
CentOS 7 | 2.17 |
RedHat Enterprise 8 | 2.28 |
RedHat Enterprise 9 | 2.34 |
Ubuntu 18.04 | 2.27 |
Ubuntu 20.04 | 2.31 |
Ubuntu 22.04 | 2.35 |
Ubuntu 24.04 | 2.39 |
例如,假设您从 CentOS 7 升级到 RedHat Enterprise 8。在这种情况下,在此升级的操作系统上使用 PostgreSQL 需要使用提到的两种方法之一,因为 glibc
从 2.17 升级到 2.28。如果未能正确处理排序更改,会导致极狐GitLab 中出现重大故障,例如 runner 无法挑选带标签的作业。
另一方面,如果 PostgreSQL 已经在 glibc
2.28 或更高版本上运行且没有问题,则您的索引应该可以继续工作而无需进一步操作。例如,如果您已经在 RedHat Enterprise 8 (glibc
2.28) 上运行 PostgreSQL 一段时间,并且想要升级到 RedHat Enterprise 9 (glibc
2.34),那么应该不会出现与排序相关的问题。
验证 glibc
排序版本
对于 PostgreSQL 13 及更高版本,您可以通过以下 SQL 查询验证您的数据库排序版本是否与您的系统匹配:
SELECT collname AS COLLATION_NAME,
collversion AS VERSION,
pg_collation_actual_version(oid) AS actual_version
FROM pg_collation
WHERE collprovider = 'c';
匹配排序示例
例如,在 Ubuntu 22.04 系统上,正确索引的系统输出如下:
gitlabhq_production=# SELECT collname AS COLLATION_NAME,
collversion AS VERSION,
pg_collation_actual_version(oid) AS actual_version
FROM pg_collation
WHERE collprovider = 'c';
collation_name | version | actual_version
----------------+---------+----------------
C | |
POSIX | |
ucs_basic | |
C.utf8 | |
en_US.utf8 | 2.35 | 2.35
en_US | 2.35 | 2.35
(6 rows)
不匹配排序示例
另一方面,如果您从 Ubuntu 18.04 升级到 22.04 而没有重新索引,您可能会看到:
gitlabhq_production=# SELECT collname AS COLLATION_NAME,
collversion AS VERSION,
pg_collation_actual_version(oid) AS actual_version
FROM pg_collation
WHERE collprovider = 'c';
collation_name | version | actual_version
----------------+---------+----------------
C | |
POSIX | |
ucs_basic | |
C.utf8 | |
en_US.utf8 | 2.27 | 2.35
en_US | 2.27 | 2.35
(6 rows)
流复制
损坏的索引问题会影响 PostgreSQL 流复制。在允许具有不同区域设置数据的副本进行读取之前,您必须 重建所有索引 或 仅重建受影响的索引。
其他 Geo 变体
上述升级程序并非一成不变。由于 Geo 存在冗余基础设施,因此可能有更多选项。您可以考虑根据您的用例进行修改,但务必权衡增加的复杂性。以下是一些示例:
为了在主站点和其他辅助站点的操作系统升级过程中保留辅助站点作为热备用,以防灾难发生:
- 将辅助站点的数据与主站点的更改隔离:暂停辅助站点。
- 在主站点执行操作系统升级。
- 如果操作系统升级失败且主站点无法恢复,则提升辅助站点,路由用户到它,然后稍后再试。
- 请注意,这会导致您没有最新的辅助站点。
为了在操作系统升级期间为用户提供极狐GitLab 的只读访问(部分停机):
- 在主站点启用 维护模式,而不是停止它。
- 提升辅助站点,但尚未将用户路由到它。
- 在提升的站点上执行操作系统升级。
- 将用户路由到提升的站点,而不是旧的主站点。
- 将旧的主站点设置为新的辅助站点。