{"id":43285,"date":"2026-06-26T12:39:40","date_gmt":"2026-06-26T10:39:40","guid":{"rendered":"https:\/\/www.dbi-services.com\/blog\/?p=43285"},"modified":"2026-06-26T12:39:42","modified_gmt":"2026-06-26T10:39:42","slug":"upgrade-rhel-from-9-6-to-10-1-when-running-postgresql-patroni","status":"publish","type":"post","link":"https:\/\/www.dbi-services.com\/blog\/upgrade-rhel-from-9-6-to-10-1-when-running-postgresql-patroni\/","title":{"rendered":"Upgrade RHEL from 9.6 to 10.1 (when running PostgreSQL\/Patroni)"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Upgrading from RHEL 9.6 to 10.1 is not just a routine update, it\u2019s a major platform shift. When your server runs PostgreSQL compiled from source and a Patroni-managed cluster, the complexity increases significantly. System libraries change, Python environments break, ICU versions evolve, and your database binaries may no longer start after reboot.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In this guide, I walk through a real-world in-place upgrade using Leapp, covering preparation, resolving high-severity warnings, executing the upgrade, recompiling PostgreSQL, fixing collation mismatches, and restoring Patroni.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-i-preparation\">I. Preparation<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Before the upgrade, you must ensure the current OS is healthy and fully patched.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-1-pause-high-availability\">1. Pause High Availability<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Prevent Patroni from triggering a failover during the reboot cycles. If you are using a single PostgreSQL cluster, stop it by stopping the service or by using pg_ctl stop.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\npatronictl -c \/etc\/patroni\/patroni.yml pause\nsystemctl stop patroni\n<\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\" id=\"h-2-fix-subscription-amp-perform-full-update\">2. Fix Subscription &amp; Perform Full Update<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">I&#8217;m using an old VM for this blog, and If just like me, you see 403 Forbidden errors on repositories like codeready-builder, refresh your registration:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n&#x5B;root@patroni2 ~]# sudo dnf update -y\nUpdating Subscription Management repositories.\n\nThis system is registered with an entitlement server, but is not receiving updates. You can use subscription-manager to assign subscriptions.\n\nRed Hat CodeReady Linux Builder for RHEL 9 x86_64 (RPMs)                                                                                                     761  B\/s | 480  B     00:00\nErrors during downloading metadata for repository &#039;codeready-builder-for-rhel-9-x86_64-rpms&#039;:\n  - Status code: 403 for https:\/\/cdn.redhat.com\/content\/dist\/rhel9\/9\/x86_64\/codeready-builder\/os\/repodata\/repomd.xml (IP: 23.206.57.92)\nError: Failed to download metadata for repo &#039;codeready-builder-for-rhel-9-x86_64-rpms&#039;: Cannot download repomd.xml: Cannot download repodata\/repomd.xml: All mirrors were tried\n\n&#x5B;root@patroni2 ~]# sudo subscription-manager clean\n&#x5B;root@patroni2 ~]# sudo subscription-manager register --force\n&#x5B;root@patroni2 ~]# sudo subscription-manager attach --auto\n&#x5B;root@patroni2 ~]# sudo subscription-manager refresh\n\n&#x5B;root@patroni2 ~]# sudo dnf update -y\n...\nComplete!\n\n&#x5B;root@patroni2 ~]# reboot\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\" id=\"h-ii-the-leapp-upgrade-to-10-1\">II. The Leapp Upgrade to 10.1<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-1-install-amp-analyze\">1. Install &amp; Analyze<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">In this first phase, we are preparing the system for a major in-place upgrade using Leapp, the official upgrade framework for Red Hat\u2013based distributions. When we install the package:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n&#x5B;root@patroni2 ~]# dnf install leapp-upgrade -y\n...\nInstalled:\n  leapp-0.20.0-1.el9.noarch                leapp-deps-0.20.0-1.el9.noarch          leapp-upgrade-el9toel10-0.23.0-1.el9.noarch       leapp-upgrade-el9toel10-deps-0.23.0-1.el9.noarch\n  libdb-utils-5.3.28-57.el9_6.x86_64       python3-leapp-0.20.0-1.el9.noarch       systemd-container-252-55.el9_7.7.x86_64\n\nComplete!\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">When running leapp preupgrade &#8211;target 10.1, we are not performing the upgrade. Instead, Leapp performs a full system audit to determine if the server is ready for RHEL 10.1. It checks:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Installed packages and their compatibility<\/li>\n\n\n\n<li>Deprecated or removed libraries<\/li>\n\n\n\n<li>Kernel drivers that will not exist in RHEL 10<\/li>\n\n\n\n<li>Bootloader configuration (GRUB2)<\/li>\n\n\n\n<li>GPG key validity<\/li>\n\n\n\n<li>Custom system-level modifications (like dynamic linker changes)<\/li>\n\n\n\n<li>&#8230;<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Think of this step as a dry-run with intelligence.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n&#x5B;root@patroni2 ~]# sudo leapp preupgrade --target 10.1\n\n...\n\n============================================================\n                      REPORT OVERVIEW\n============================================================\n\nHIGH and MEDIUM severity reports:\n    1. GRUB2 core will be automatically updated during the upgrade\n    2. Detected customized configuration for dynamic linker.\n    3. Leapp detected loaded kernel drivers which are no longer maintained in RHEL 10.\n    4. Failed to read GPG keys from provided key files\n    5. Berkeley DB (libdb) has been detected on your system\n\nReports summary:\n    Errors:                      0\n    Inhibitors:                  0\n    HIGH severity reports:       4\n    MEDIUM severity reports:     1\n    LOW severity reports:        1\n    INFO severity reports:       3\n\nBefore continuing, review the full report below for details about discovered problems and possible remediation instructions:\n    A report has been generated at \/var\/log\/leapp\/leapp-report.txt\n    A report has been generated at \/var\/log\/leapp\/leapp-report.json\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">After running the pre-upgrade analysis, the next step is to carefully review:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/var\/log\/leapp\/leapp-report.txt<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">What we are looking for first is simple:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Errors: 0<\/li>\n\n\n\n<li>Inhibitors: 0<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">If an Inhibitor is present, the upgrade will be blocked entirely.<br>In my case, there were no blockers, but I did have several high severity warnings.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">High severity does not mean the upgrade will fail.<br>It means: This could break something, review it carefully.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let\u2019s look at one concrete example from my system.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-2-high-severity-example-dynamic-linker-customization\">2. High Severity Example \u2013 Dynamic Linker Customization<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Leapp detected that my system had a custom dynamic linker configuration:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\nRisk Factor: high\n\nTitle: Detected customized configuration for dynamic linker.\n\nSummary: Custom configurations to the dynamic linker could potentially impact the upgrade in a negative way. The custom configuration includes modifications to \/etc\/ld.so.conf, custom or modified drop in config files in the \/etc\/ld.so.conf.d directory and additional entries in the LD_LIBRARY_PATH or LD_PRELOAD variables. These modifications configure the dynamic linker to use different libraries that might not be provided by Red Hat products or might not be present during the whole upgrade process. The following custom configurations were detected by leapp:\n\n- The following drop in config files were marked as custom:\n\n    - \/etc\/ld.so.conf.d\/postgres.conf\n\nRemediation: &#x5B;hint] Remove or revert the custom dynamic linker configurations and apply the changes using the ldconfig command. In case of possible active software collections we suggest disabling them persistently.\n\nKey: cc9bd972af70b7a27f66a37b11a00dcfcb73b1bc\n\n----------------------------------------\n<\/pre><\/div>\n\n\n<h4 class=\"wp-block-heading\" id=\"h-what-does-this-actually-mean\">What does this actually mean?<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">The dynamic linker (ld.so) is responsible for loading shared libraries at runtime.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">By modifying:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\/etc\/ld.so.conf<\/li>\n\n\n\n<li>files in \/etc\/ld.so.conf.d\/<\/li>\n\n\n\n<li>LD_LIBRARY_PATH<\/li>\n\n\n\n<li><code>LD_PR<\/code>E<code>LOAD<\/code><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">we are telling the system to load non-standard or custom libraries. In PostgreSQL environments (especially with custom builds or extensions), this is common practice. However, during a major OS upgrade, these custom paths might:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Point to libraries that do not exist in RHEL 10<\/li>\n\n\n\n<li>Override new system libraries<\/li>\n\n\n\n<li>Break dependency resolution mid-upgrade<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Leapp flags this because it cannot guarantee consistency during the transition phase. In my case, it shouldn&#8217;t be an issue, because inside postgres.conf, I only have a path aiming to the lib directories of my PostgreSQL installation, which will not change, but we will still see how to prevent an error.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-understanding-the-remediation\">Understanding the Remediation<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">The report clearly suggests:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Remove or revert the custom dynamic linker configurations and apply the changes using the ldconfig command.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">In my case, the configuration was related to PostgreSQL, so temporarily removing it is safe for the upgrade preparation phase. Instead of deleting it permanently, I moved it aside:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n&#x5B;root@patroni2 ~]# sudo mv \/etc\/ld.so.conf.d\/postgres.conf \/tmp\/postgres.conf.bak\n&#x5B;root@patroni2 ~]# sudo ldconfig\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">ldconfig rebuilds the system library cache now based only on standard paths.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-re-run-the-preupgrade-check\">Re-Run the Preupgrade Check<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">After remediation, always re-run the preupgrade command and check the report again. If the fix was successful:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The severity should disappear from the REPORT OVERVIEW<\/li>\n\n\n\n<li>The issue should no longer appear in leapp-report.txt<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">This validation loop is important. We are progressively cleaning the system until it is fully compliant for upgrade.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n============================================================\n                      REPORT OVERVIEW\n============================================================\n\nHIGH and MEDIUM severity reports:\n    1. Leapp detected loaded kernel drivers which are no longer maintained in RHEL 10.\n    2. GRUB2 core will be automatically updated during the upgrade\n    3. Failed to read GPG keys from provided key files\n    4. Berkeley DB (libdb) has been detected on your system\n\nReports summary:\n    Errors:                      0\n    Inhibitors:                  0\n    HIGH severity reports:       3\n    MEDIUM severity reports:     1\n    LOW severity reports:        1\n    INFO severity reports:       3\n\nBefore continuing, review the full report below for details about discovered problems and possible remediation instructions:\n    A report has been generated at \/var\/log\/leapp\/leapp-report.txt\n    A report has been generated at \/var\/log\/leapp\/leapp-report.json\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Only once the report is clean, or fully understood, should we proceed to the actual upgrade execution.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-2-execute-the-upgrade\">2. Execute the upgrade<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Once all errors and inhibitors are resolved, and high-severity findings have been reviewed or remediated, we are finally ready to perform the actual in-place upgrade. This is the moment where Leapp transitions from analysis mode to execution mode.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-about-the-repository-warning\">About the Repository Warning<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">During the preupgrade phase, Leapp informed us that codeready-builder-&#8230; repositories are not officially supported during the upgrade process and are excluded by default.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This is expected behavior as Leapp only enables a minimal, controlled set of repositories to ensure:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Package consistency<\/li>\n\n\n\n<li>Dependency resolution stability<\/li>\n\n\n\n<li>Predictable upgrade paths<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">However, in PostgreSQL environments, some packages (extensions, development headers, libraries) may depend on CodeReady Builder. If a repository is truly required during the upgrade, we must explicitly enable it using:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n--enablerepo &lt;repoid&gt;\n<\/pre><\/div>\n\n\n<h4 class=\"wp-block-heading\" id=\"h-running-the-upgrade\">Running the Upgrade<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Since I need CodeReady Builder for PostgreSQLdependencies, I ran:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\nleapp upgrade --target 10.1 --enablerepo codeready-builder-for-rhel-10-x86_64-rpms\n<\/pre><\/div>\n\n\n<h4 class=\"wp-block-heading\">What happens when we run this command?<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">At this stage, Leapp:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Resolves and downloads required RHEL 10 packages<\/li>\n\n\n\n<li>Builds a temporary upgrade environment<\/li>\n\n\n\n<li>Prepares a special upgrade initramfs<\/li>\n\n\n\n<li>Modifies the bootloader (GRUB) to boot into the upgrade environment on next reboot<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The system is not upgraded immediately. The actual OS transition happens during the next boot.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">After the command completes, Leapp generates another report. Just like in the preupgrade phase, verify:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Errors: 0<\/li>\n\n\n\n<li>Inhibitors: 0<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">If everything looks clean, we can proceed.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-reboot-the-real-upgrade-begins\">Reboot \u2013 The Real Upgrade Begins<\/h4>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n# reboot\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">This is where the real upgrade starts. During boot:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The system enters a temporary upgrade environment<\/li>\n\n\n\n<li>Packages are replaced<\/li>\n\n\n\n<li>Obsolete components are removed<\/li>\n\n\n\n<li>Configuration files are migrated<\/li>\n\n\n\n<li>The new RHEL 10 kernel is installed<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">This phase can take several minutes depending on your VM\/server resources. My VM doesn&#8217;t have many resources and it took me around 30 minutes. Be patient, interrupting this process can leave the system in an inconsistent state.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-verifying-the-upgrade\">Verifying the Upgrade<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Once the server is back online, confirm the OS version:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n&#x5B;root@patroni2 ~]# cat \/etc\/os-release\nNAME=&quot;Red Hat Enterprise Linux&quot;\nVERSION=&quot;10.1 (Coughlan)&quot;\nID=&quot;rhel&quot;\nID_LIKE=&quot;centos fedora&quot;\nVERSION_ID=&quot;10.1&quot;\nPLATFORM_ID=&quot;platform:el10&quot;\nPRETTY_NAME=&quot;Red Hat Enterprise Linux 10.1 (Coughlan)&quot;\nANSI_COLOR=&quot;0;31&quot;\nLOGO=&quot;fedora-logo-icon&quot;\nCPE_NAME=&quot;cpe:\/o:redhat:enterprise_linux:10.1&quot;\nHOME_URL=&quot;https:\/\/www.redhat.com\/&quot;\nVENDOR_NAME=&quot;Red Hat&quot;\nVENDOR_URL=&quot;https:\/\/www.redhat.com\/&quot;\nDOCUMENTATION_URL=&quot;https:\/\/access.redhat.com\/documentation\/en-us\/red_hat_enterprise_linux\/10&quot;\nBUG_REPORT_URL=&quot;https:\/\/issues.redhat.com\/&quot;\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">REDHAT_BUGZILLA_PRODUCT=&#8221;Red Hat Enterprise Linux 10&#8243;<br>REDHAT_BUGZILLA_PRODUCT_VERSION=10.1<br>REDHAT_SUPPORT_PRODUCT=&#8221;Red Hat Enterprise Linux&#8221;<br>REDHAT_SUPPORT_PRODUCT_VERSION=&#8221;10.1&#8243;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This confirms that we are now running RHEL 10.1.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-iii-post-upgrade-database-recovery\">III. Post-Upgrade Database Recovery<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Once you login to RHEL 10.1, your Postgres binaries in \/u01 will fail because libicuuc.so.67 (from RHEL 9) is missing. It can also fail because of other libraries.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n14:45:55 postgres@patroni2:\/home\/postgres\/ &#x5B;test-op-patroni] pgstart\n\/u01\/app\/postgres\/product\/17\/db_6\/bin\/postgres: error while loading shared libraries: libicuuc.so.67: cannot open shared object file: No such file or directory\nno data was returned by command &quot;&quot;\/u01\/app\/postgres\/product\/17\/db_6\/bin\/postgres&quot; -V&quot;\ncommand not found\nprogram &quot;postgres&quot; is needed by pg_ctl but was not found in the same directory as &quot;\/u01\/app\/postgres\/product\/17\/db_6\/bin\/pg_ctl&quot;\n<\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\" id=\"h-1-recompile-postgresql\">1. Recompile PostgreSQL<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Since you installed from source, you must re compile PostgreSQL with the new RHEL 10 system libraries. Here is the command I personally use to build it, with the postgres user:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\npostgres@patroni2:\/home\/postgres\/ &#x5B;dummy] MAJOR=&quot;17&quot;\npostgres@patroni2:\/home\/postgres\/ &#x5B;dummy] MINOR=&quot;6&quot;\npostgres@patroni2:\/home\/postgres\/ &#x5B;dummy] tar axf postgresql-${MAJOR}.${MINOR}.tar.gz\npostgres@patroni2:\/home\/postgres\/ &#x5B;dummy] mkdir build; cd $_\npostgres@patroni2:\/home\/postgres\/ &#x5B;dummy] export PGHOME=&quot;\/u01\/app\/postgres\/product\/${MAJOR}\/db_${MINOR}&quot;\npostgres@patroni2:\/home\/postgres\/ &#x5B;dummy] export SEGSIZE=2\npostgres@patroni2:\/home\/postgres\/ &#x5B;dummy] export BLOCKSIZE=8\npostgres@patroni2:\/home\/postgres\/ &#x5B;dummy] meson setup . ..\/postgresql-${MAJOR}.${MINOR}\npostgres@patroni2:\/home\/postgres\/ &#x5B;dummy] meson configure -Dprefix=${PGHOME}                   -Dbindir=${PGHOME}\/bin                   -Ddatadir=${PGHOME}\/share                   -Dincludedir=${PGHOME}\/include                   -Dlibdir=${PGHOME}\/lib                   -Dsysconfdir=${PGHOME}\/etc                   -Dpgport=5432                   -Dplperl=enabled                   -Dplpython=enabled                   -Dssl=openssl                   -Dpam=enabled                   -Dldap=enabled                   -Dlibxml=enabled                   -Dlibxslt=enabled                   -Dsegsize=${SEGSIZE}                   -Dblocksize=${BLOCKSIZE}                   -Dllvm=enabled                   -Duuid=ossp                   -Dzstd=enabled                   -Dlz4=enabled                   -Dzstd=enabled                   -Dgssapi=enabled                   -Dsystemd=enabled                   -Dicu=enabled                   -Dsystem_tzdata=\/usr\/share\/zoneinfo                   -Dextra_version=&quot; dbi services build&quot;\npostgres@patroni2:\/home\/postgres\/ &#x5B;dummy] ninja\npostgres@patroni2:\/home\/postgres\/ &#x5B;dummy] ninja install\n<\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\" id=\"h-2-restore-library-paths\">2. Restore Library Paths<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">[root@patroni2 ~]# mv \/tmp\/postgres.conf.bak \/etc\/ld.so.conf.d\/postgres.conf<br>[root@patroni2 ~]# ldconfig<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-3-start-amp-fix-collation-mismatch\">3. Start &amp; Fix Collation Mismatch<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Postgres will now start, but will warn you about Collation Version Mismatches (2.34 vs 2.39).<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n15:09:55 postgres@patroni2:\/home\/postgres\/build\/ &#x5B;test-op-patroni] pgstart\nwaiting for server to start.... done\nserver started\n15:10:28 postgres@patroni2:\/home\/postgres\/build\/ &#x5B;test-op-patroni] psql\nWARNING:  database &quot;postgres&quot; has a collation version mismatch\nDETAIL:  The database was created using collation version 2.34, but the operating system provides version 2.39.\nHINT:  Rebuild all objects in this database that use the default collation and run ALTER DATABASE postgres REFRESH COLLATION VERSION, or build PostgreSQL with the right library version.\npsql (17.6 dbi services build)\nType &quot;help&quot; for help.\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Inside Postgres, run for every database:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; title: ; notranslate\" title=\"\">\nALTER DATABASE postgres REFRESH COLLATION VERSION;\nALTER DATABASE\n\n-- Repeat for other DBs if applicable\nREINDEX DATABASE postgres;\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Your PostgreSQL is now starting properly and your server has been upgraded.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-4-in-case-of-a-patroni-cluster\">4. In case of a patroni cluster<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Since the system Python version has changed after the OS upgrade, your old .local venv is invalid. You must recreate it. Here is how I install patroni using the postgres user:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">$ python3 -m venv .local<br>$ .local\/bin\/pip3 install &#8211;upgrade pip<br>$ .local\/bin\/pip3 install &#8211;upgrade setuptools<br>$ .local\/bin\/pip3 install wheel<br>$ .local\/bin\/pip3 install psycopg[binary]<br>$ .local\/bin\/pip3 install python-etcd<br>$ .local\/bin\/pip3 install patroni<br>$ .local\/bin\/patroni version<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Check if the cluster sees the member again. If patronictl list is empty, a restart of the service is usually required to re-register with etcd.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n10:45:40 postgres@patroni2:\/home\/postgres\/ &#x5B;test-op-patroni] patronictl list\n+ Cluster: test-op-patroni (7565882985963789761) -+-----+------------+-----+\n| Member | Host | Role | State | TL | Receive LSN | Lag | Replay LSN | Lag |\n+--------+------+------+-------+----+-------------+-----+------------+-----+\n+--------+------+------+-------+----+-------------+-----+------------+-----+\n10:45:48 postgres@patroni2:\/home\/postgres\/ &#x5B;test-op-patroni] sudo systemctl restart patroni\n10:45:55 postgres@patroni2:\/home\/postgres\/ &#x5B;test-op-patroni] patronictl list\n+ Cluster: test-op-patroni (7565882985963789761) --+---------+----+-------------+-----+------------+-----+\n| Member                 | Host           | Role   | State   | TL | Receive LSN | Lag | Replay LSN | Lag |\n+------------------------+----------------+--------+---------+----+-------------+-----+------------+-----+\n| patroni-tst-op-geapg02 | 192.168.56.142 | Leader | running | 11 |             |     |            |     |\n+------------------------+----------------+--------+---------+----+-------------+-----+------------+-----+\n\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\" id=\"h-iv-conclusion\">IV. Conclusion<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Upgrading from RHEL 9.6 to 10.1 is a big move. It\u2019s not just a simple update; it\u2019s a total shift in the system&#8217;s foundation. Between hardware driver changes and library updates, you really have to pay attention to the details to keep your database running.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">RHEL 10.1 is a great, modern platform, but you can&#8217;t just click &#8220;update&#8221; and hope for the best. By planning the upgrade, planning to rebuild your binaries, refreshing your database objects, you can make the jump without the drama. Take the pre-upgrade report seriously, it\u2019s there for a reason!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That said, for a production PostgreSQL cluster, especially one managed with Patroni and etcd, I would not recommend this in-place upgrade approach. Even if Leapp makes the process technically possible, you are still:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Modifying the operating system in place<\/li>\n\n\n\n<li>Replacing core libraries underneath a running database stack<\/li>\n\n\n\n<li>Trusting automated dependency resolution during a major version jump<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">In production, risk reduction should always be the priority.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Instead, I strongly recommend provisioning new VMs or physical servers, installing RHEL 10.1 from scratch, deploying PostgreSQL, Patroni, and etcd cleanly, rebuilding the cluster from best practices, and then migrating the data from the old environment to the new one using replication or another appropriate method.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Sometimes the safest upgrade\u2026 is a new cluster.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Upgrading from RHEL 9.6 to 10.1 is not just a routine update, it\u2019s a major platform shift. When your server runs PostgreSQL compiled from source and a Patroni-managed cluster, the complexity increases significantly. System libraries change, Python environments break, ICU versions evolve, and your database binaries may no longer start after reboot. In this guide, [&hellip;]<\/p>\n","protected":false},"author":87,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[229,42,83],"tags":[1248,3887,73,153,154,77,1326,2601],"type_dbi":[3588,2749],"class_list":["post-43285","post","type-post","status-publish","format-standard","hentry","category-database-administration-monitoring","category-operating-systems","category-postgresql","tag-1248","tag-leapp","tag-linux","tag-operating-system","tag-os","tag-postgresql","tag-rhel","tag-upgrade-2","type-linux","type-postgresql"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.8 (Yoast SEO v27.8) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Upgrade RHEL from 9.6 to 10.1 (when running PostgreSQL\/Patroni) - dbi Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.dbi-services.com\/blog\/upgrade-rhel-from-9-6-to-10-1-when-running-postgresql-patroni\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Upgrade RHEL from 9.6 to 10.1 (when running PostgreSQL\/Patroni)\" \/>\n<meta property=\"og:description\" content=\"Upgrading from RHEL 9.6 to 10.1 is not just a routine update, it\u2019s a major platform shift. When your server runs PostgreSQL compiled from source and a Patroni-managed cluster, the complexity increases significantly. System libraries change, Python environments break, ICU versions evolve, and your database binaries may no longer start after reboot. In this guide, [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.dbi-services.com\/blog\/upgrade-rhel-from-9-6-to-10-1-when-running-postgresql-patroni\/\" \/>\n<meta property=\"og:site_name\" content=\"dbi Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-06-26T10:39:40+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-06-26T10:39:42+00:00\" \/>\n<meta name=\"author\" content=\"Joan Frey\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Joan Frey\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/upgrade-rhel-from-9-6-to-10-1-when-running-postgresql-patroni\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/upgrade-rhel-from-9-6-to-10-1-when-running-postgresql-patroni\\\/\"},\"author\":{\"name\":\"Joan Frey\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#\\\/schema\\\/person\\\/c03c47649664fe73b27ce457e99f5b06\"},\"headline\":\"Upgrade RHEL from 9.6 to 10.1 (when running PostgreSQL\\\/Patroni)\",\"datePublished\":\"2026-06-26T10:39:40+00:00\",\"dateModified\":\"2026-06-26T10:39:42+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/upgrade-rhel-from-9-6-to-10-1-when-running-postgresql-patroni\\\/\"},\"wordCount\":1412,\"commentCount\":0,\"keywords\":[\"10\",\"leapp\",\"Linux\",\"operating system\",\"os\",\"PostgreSQL\",\"RHEL\",\"upgrade\"],\"articleSection\":[\"Database Administration &amp; Monitoring\",\"Operating systems\",\"PostgreSQL\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/upgrade-rhel-from-9-6-to-10-1-when-running-postgresql-patroni\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/upgrade-rhel-from-9-6-to-10-1-when-running-postgresql-patroni\\\/\",\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/upgrade-rhel-from-9-6-to-10-1-when-running-postgresql-patroni\\\/\",\"name\":\"Upgrade RHEL from 9.6 to 10.1 (when running PostgreSQL\\\/Patroni) - dbi Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#website\"},\"datePublished\":\"2026-06-26T10:39:40+00:00\",\"dateModified\":\"2026-06-26T10:39:42+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#\\\/schema\\\/person\\\/c03c47649664fe73b27ce457e99f5b06\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/upgrade-rhel-from-9-6-to-10-1-when-running-postgresql-patroni\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/upgrade-rhel-from-9-6-to-10-1-when-running-postgresql-patroni\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/upgrade-rhel-from-9-6-to-10-1-when-running-postgresql-patroni\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Upgrade RHEL from 9.6 to 10.1 (when running PostgreSQL\\\/Patroni)\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/\",\"name\":\"dbi Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#\\\/schema\\\/person\\\/c03c47649664fe73b27ce457e99f5b06\",\"name\":\"Joan Frey\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1e650cf665b4d44dd186355827c0b049d2f95c8cbb45fd10d4e7cb255be67ecb?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1e650cf665b4d44dd186355827c0b049d2f95c8cbb45fd10d4e7cb255be67ecb?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1e650cf665b4d44dd186355827c0b049d2f95c8cbb45fd10d4e7cb255be67ecb?s=96&d=mm&r=g\",\"caption\":\"Joan Frey\"},\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/author\\\/joanfrey\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Upgrade RHEL from 9.6 to 10.1 (when running PostgreSQL\/Patroni) - dbi Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.dbi-services.com\/blog\/upgrade-rhel-from-9-6-to-10-1-when-running-postgresql-patroni\/","og_locale":"en_US","og_type":"article","og_title":"Upgrade RHEL from 9.6 to 10.1 (when running PostgreSQL\/Patroni)","og_description":"Upgrading from RHEL 9.6 to 10.1 is not just a routine update, it\u2019s a major platform shift. When your server runs PostgreSQL compiled from source and a Patroni-managed cluster, the complexity increases significantly. System libraries change, Python environments break, ICU versions evolve, and your database binaries may no longer start after reboot. In this guide, [&hellip;]","og_url":"https:\/\/www.dbi-services.com\/blog\/upgrade-rhel-from-9-6-to-10-1-when-running-postgresql-patroni\/","og_site_name":"dbi Blog","article_published_time":"2026-06-26T10:39:40+00:00","article_modified_time":"2026-06-26T10:39:42+00:00","author":"Joan Frey","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Joan Frey","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.dbi-services.com\/blog\/upgrade-rhel-from-9-6-to-10-1-when-running-postgresql-patroni\/#article","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/upgrade-rhel-from-9-6-to-10-1-when-running-postgresql-patroni\/"},"author":{"name":"Joan Frey","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/c03c47649664fe73b27ce457e99f5b06"},"headline":"Upgrade RHEL from 9.6 to 10.1 (when running PostgreSQL\/Patroni)","datePublished":"2026-06-26T10:39:40+00:00","dateModified":"2026-06-26T10:39:42+00:00","mainEntityOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/upgrade-rhel-from-9-6-to-10-1-when-running-postgresql-patroni\/"},"wordCount":1412,"commentCount":0,"keywords":["10","leapp","Linux","operating system","os","PostgreSQL","RHEL","upgrade"],"articleSection":["Database Administration &amp; Monitoring","Operating systems","PostgreSQL"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.dbi-services.com\/blog\/upgrade-rhel-from-9-6-to-10-1-when-running-postgresql-patroni\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.dbi-services.com\/blog\/upgrade-rhel-from-9-6-to-10-1-when-running-postgresql-patroni\/","url":"https:\/\/www.dbi-services.com\/blog\/upgrade-rhel-from-9-6-to-10-1-when-running-postgresql-patroni\/","name":"Upgrade RHEL from 9.6 to 10.1 (when running PostgreSQL\/Patroni) - dbi Blog","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/#website"},"datePublished":"2026-06-26T10:39:40+00:00","dateModified":"2026-06-26T10:39:42+00:00","author":{"@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/c03c47649664fe73b27ce457e99f5b06"},"breadcrumb":{"@id":"https:\/\/www.dbi-services.com\/blog\/upgrade-rhel-from-9-6-to-10-1-when-running-postgresql-patroni\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.dbi-services.com\/blog\/upgrade-rhel-from-9-6-to-10-1-when-running-postgresql-patroni\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.dbi-services.com\/blog\/upgrade-rhel-from-9-6-to-10-1-when-running-postgresql-patroni\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/www.dbi-services.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Upgrade RHEL from 9.6 to 10.1 (when running PostgreSQL\/Patroni)"}]},{"@type":"WebSite","@id":"https:\/\/www.dbi-services.com\/blog\/#website","url":"https:\/\/www.dbi-services.com\/blog\/","name":"dbi Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.dbi-services.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/c03c47649664fe73b27ce457e99f5b06","name":"Joan Frey","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/1e650cf665b4d44dd186355827c0b049d2f95c8cbb45fd10d4e7cb255be67ecb?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/1e650cf665b4d44dd186355827c0b049d2f95c8cbb45fd10d4e7cb255be67ecb?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/1e650cf665b4d44dd186355827c0b049d2f95c8cbb45fd10d4e7cb255be67ecb?s=96&d=mm&r=g","caption":"Joan Frey"},"url":"https:\/\/www.dbi-services.com\/blog\/author\/joanfrey\/"}]}},"_links":{"self":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/43285","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/users\/87"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/comments?post=43285"}],"version-history":[{"count":39,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/43285\/revisions"}],"predecessor-version":[{"id":43640,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/43285\/revisions\/43640"}],"wp:attachment":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/media?parent=43285"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/categories?post=43285"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/tags?post=43285"},{"taxonomy":"type","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/type_dbi?post=43285"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}