Geo cannot be used to migrate a PostgreSQL database from one operating system to another. If you attempt to do so, the secondary site may appear to be 100% replicated when in fact some data is not replicated, leading to data loss. This is because Geo depends on PostgreSQL streaming replication, which suffers from the limitations described in this document. Also see Geo Troubleshooting - Check OS locale data compatibility.
If you upgrade the operating system on which PostgreSQL runs, any changes to locale data might corrupt your database indexes. In particular, the upgrade to glibc
2.28 is likely to cause this problem. To avoid this issue, migrate using one of the following options, roughly in order of complexity:
Be sure to backup before attempting any migration, and validate the migration process in a production-like environment. If the length of downtime might be a problem, then consider timing different approaches with a copy of production data in a production-like environment.
If you are running a scaled-out GitLab environment, and there are no other services running on the nodes where PostgreSQL is running, then we recommend upgrading the operating system of the PostgreSQL nodes by themselves. To reduce complexity and risk, do not combine the procedure with other changes, especially if those changes do not require downtime, such as upgrading the operating system of nodes running only Puma or Sidekiq.
For more information about how GitLab plans to address this issue, see epic 8573.
Backup and restoreBackup and restore recreates the entire database, including the indexes.
Take a scheduled downtime window. In all nodes, stop unnecessary GitLab services:
gitlab-ctl stop
gitlab-ctl start postgresql
Backup the PostgreSQL database with pg_dump
or the GitLab backup tool, with all data types except db
excluded (so only the database is backed up).
In all PostgreSQL nodes, upgrade the OS.
In all PostgreSQL nodes, update GitLab package sources after upgrading the OS.
In all PostgreSQL nodes, install the new GitLab package of the same GitLab version.
Restore the PostgreSQL database from backup.
In all nodes, start GitLab.
Advantages:
Disadvantages:
Take a scheduled downtime window. In all nodes of all sites, stop unnecessary GitLab services:
gitlab-ctl stop
gitlab-ctl start postgresql
In the primary site, backup the PostgreSQL database with pg_dump
or the GitLab backup tool, with all data types except db
excluded (so only the database is backed up).
In all PostgreSQL nodes of all sites, upgrade the OS.
In all PostgreSQL nodes of all sites, update GitLab package sources after upgrading the OS.
In all PostgreSQL nodes of all sites, install the new GitLab package of the same GitLab version.
In the primary site, restore the PostgreSQL database from backup.
Optionally, start using the primary site, at the risk of not having a secondary site as warm standby.
Set up PostgreSQL streaming replication to the secondary sites again.
If the secondary sites receive traffic from users, then let the read-replica databases catch up before starting GitLab.
In all nodes of all sites, start GitLab.
Take a scheduled downtime window. In all nodes, stop unnecessary GitLab services:
gitlab-ctl stop
gitlab-ctl start postgresql
In all PostgreSQL nodes, upgrade the OS.
In all PostgreSQL nodes, update GitLab package sources after upgrading the OS.
In all PostgreSQL nodes, install the new GitLab package of the same GitLab version.
In a database console, rebuild all indexes:
SET statement_timeout = 0;
REINDEX DATABASE gitlabhq_production;
After reindexing the database, the version must be refreshed for all affected collations. To update the system catalog to record the current collation version:
ALTER DATABASE gitlabhq_production REFRESH COLLATION VERSION;
In all nodes, start GitLab.
Advantages:
Disadvantages:
Take a scheduled downtime window. In all nodes of all sites, stop unnecessary GitLab services:
gitlab-ctl stop
gitlab-ctl start postgresql
In all PostgreSQL nodes, upgrade the OS.
In all PostgreSQL nodes, update GitLab package sources after upgrading the OS.
In all PostgreSQL nodes, install the new GitLab package of the same GitLab version.
In the primary site, in a database console, rebuild all indexes:
SET statement_timeout = 0;
REINDEX DATABASE gitlabhq_production;
After reindexing the database, the version must be refreshed for all affected collations. To update the system catalog to record the current collation version:
ALTER DATABASE <database_name> REFRESH COLLATION VERSION;
If the secondary sites receive traffic from users, then let the read-replica databases catch up before starting GitLab.
In all nodes of all sites, start GitLab.
This is similar to the approach used for GitLab.com. To learn more about this process and how the different types of indexes were handled, see the blog post about upgrading the operating system on our PostgreSQL database clusters.
Take a scheduled downtime window. In all nodes, stop unnecessary GitLab services:
gitlab-ctl stop
gitlab-ctl start postgresql
In all PostgreSQL nodes, upgrade the OS.
In all PostgreSQL nodes, update GitLab package sources after upgrading the OS.
In all PostgreSQL nodes, install the new GitLab package of the same GitLab version.
In a database console, reindex each affected index:
SET statement_timeout = 0;
REINDEX INDEX <index name> CONCURRENTLY;
After reindexing bad indexes, the collation must be refreshed. To update the system catalog to record the current collation version:
ALTER DATABASE <database_name> REFRESH COLLATION VERSION;
In all nodes, start GitLab.
Advantages:
Disadvantages:
Take a scheduled downtime window. In all nodes of all sites, stop unnecessary GitLab services:
gitlab-ctl stop
gitlab-ctl start postgresql
In all PostgreSQL nodes, upgrade the OS.
In all PostgreSQL nodes, update GitLab package sources after upgrading the OS.
In all PostgreSQL nodes, install the new GitLab package of the same GitLab version.
In the primary site, in a database console, reindex each affected index:
SET statement_timeout = 0;
REINDEX INDEX <index name> CONCURRENTLY;
After reindexing bad indexes, the collation must be refreshed. To update the system catalog to record the current collation version:
ALTER DATABASE <database_name> REFRESH COLLATION VERSION;
The existing PostgreSQL streaming replication should replicate the reindex changes to the read-replica databases.
In all nodes of all sites, start GitLab.
glibc
versions
To see what version of glibc
is used, run ldd --version
.
The following table shows the glibc
versions shipped for different operating systems:
glibc
version 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
For example, suppose you are upgrading from CentOS 7 to RedHat Enterprise 8. In this case, using PostgreSQL on this upgraded operating system requires using one of the two mentioned approaches, because glibc
is upgraded from 2.17 to 2.28. Failing to handle the collation changes properly causes significant failures in GitLab, such as runners not picking jobs with tags.
On the other hand, if PostgreSQL has already been running on glibc
2.28 or higher with no issues, your indexes should continue to work without further action. For example, if you have been running PostgreSQL on RedHat Enterprise 8 (glibc
2.28) for a while, and want to upgrade to RedHat Enterprise 9 (glibc
2.34), there should be no collations-related issues.
glibc
collation versions
For PostgreSQL 13 and higher, you can verify that your database collation version matches your system with this SQL query:
SELECT collname AS COLLATION_NAME,
collversion AS VERSION,
pg_collation_actual_version(oid) AS actual_version
FROM pg_collation
WHERE collprovider = 'c';
Matching collation example
For example, on a Ubuntu 22.04 system, the output of a properly indexed system looks like:
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)
Mismatched collation example
On the other hand, if you’ve upgraded from Ubuntu 18.04 to 22.04 without reindexing, you might see:
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)
Streaming replication
The corrupted index issue affects PostgreSQL streaming replication. You must rebuild all indexes or rebuild only affected indexes before allowing reads against a replica with different locale data.
Additional Geo variationsThe upgrade procedures documented previously are not set in stone. With Geo there are potentially more options, because there exists redundant infrastructure. You could consider modifications to suit your use-case, but be sure to weigh it against the added complexity. Here are some examples:
To reserve a secondary site as a warm standby in case of disaster during the OS upgrade of the primary site and the other secondary site:
To provide users with read-only access to GitLab during the OS upgrade (partial downtime):
Even though the secondary site already has a read-replica of the database, you cannot upgrade its operating system prior to promotion. If you were to attempt that, then the secondary site may miss replication of some Git repositories or files, due to the corrupted indexes. See Streaming replication.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4