Upgrading to Postgres 12
This page documents the findings of my investigation of upgrading the FOLIO project as a whole to postgres 12. The goal is to determine if an upgrade to version 12 causes any module unit tests to break. For background there is a ticket associated with this: - FOLIO-3094Getting issue details... STATUS .
The scope of the investigation is FOLIO-wide. This means we're interested in seeing how an upgrade to postgres 12 affects all modules.
Summary of findings
We're in a good position for upgrading to 12. See the details in the table below for each module tested.
Modules are in one of three states:
- Already upgraded to 12 (nothing should be required)
- Is in good shape to be upgraded (a green checkmark) having been tested
- Has issues with upgrading (a warning icon). See the notes in the table below for the problems encountered per module. There aren't that many.
Replicating the results for your module
If your module has issues in the module readiness table below you may want to investigate further by replicating the test results. Replicating results for modules with issues might be tricky and it might just be better to focus on upgrading to RMB 33 instead. If you really really want to replicate, first check the logs attached to the 3094 ticket to see the details (what failed for which version). Then you can try to replicate locally if the logs don't tell you enough. Things to note about that:
- You'll want to have 10 and 12 able to run locally. I used brew to grab these.
- See the script run-tests.sh attached to the ticket. It will run the tests if you have installed pg 10 and 12 via brew. If you don't use brew the script won't work.
- You'll need a postgres user with a password in your local dbs.
- You'll likely need to set the DB_ environment variables in your system. I added them to bash_profile.
- Run run-tests.sh. This will start and stop 10 and 12 and take care of running and logging results of mvn clean install.
Some modules require that you remove calls to PostgresClient.startEmbeddedPostgres in your tests. This call isn't needed and appears to override the DB_* env vars which you need in order to bypass embedded to hit your local version of 12. Running 12 in embedded isn't easily done since embedded is controlled by vertx, and not our code (not even RMB).
I don't recommend trying to replicate if you can avoid it.
Test method
To determine the impact of database upgrade I did following:
- Determine if the module has persistence.
- Clone the module code.
- Run the unit tests for the module, making a note of any failed tests.
- Determine a method for running the unit tests using postgres 12.
- Run the tests and compare the results with the results prior to the upgrade.
- If there are any breakages investigate them and document them.
I also ran pg_upgrade on the data in the testing-backend vagrant. See below (below the table) for the results of that. It seems to have gone well.
Notes on code this investigation used
I'm working off of clones of modules that were made on 2021-05-06, so the findings should be only relevant to the code in that snapshot.
Should we try to go to version 13?
The answer appears to be no, since, although RDS now supports version 13, the Aurora managed service does not:
- https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.Updates.20180305.html
- https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_PostgreSQL.html#PostgreSQL.Concepts.General.version13.
Determining if the module has persistence
See if the pom file containing domain-models-runtime or vertx-pg-client seem like good indications. A number of modules appear to not have persistence roles. For example mod-inventory doesn't, but mod-inventory-storage does. See below for a summary of the status of each module.
Determining if a module has been upgraded to postgres 12
Modules that new up the RMB's PostgresTesterContainer class, have been upgraded. PostgresTesterContainer is where the postgres version gets passed into the constructor on the RMB level (so not on the module level). See for example mod-configuration, mod-circulation-storage, mod-permissions, etc. This is documented in the table below for each module.
Note that not all modules that are using RMB 32.2, are using PostgresTesterContainer (for example mod-calendar is using RMB 32.2 but still uses embedded postgres for its tests).
Modules that depend on RMB 33
Modules that use RMB 33 use PostgresTesterContainer that uses postgres 12.
Modules that depend on RMB 32.2
Using 32.2 opened up the possibility for modules to use PostgresTesterContainer, but it isn't a guarantee. For example, mod-calendar uses 32.2, but still uses embedded postgres.
Open questions
Should we expand the scope of this spike to investigate other FOLIO code beyond modules?
Determining a method for running the unit tests using postgres 12
If a module has switched to testcontainers (moving away from embedded postgres), swapping out a version of postgres appears to be a simple matter of swapping out the docker image name in code like this:
postgresSQLContainer = new PostgreSQLContainer<>("postgres:12-alpine")
For some discussion on making the change to testcontainers see - FOLIO-1845Getting issue details... STATUS .
For modules that haven't yet made the switch to RMB 32.2+ and are still using embedded, testing against version 12 still seems be possible by bypassing embedded postgres by using a postgres-conf.json file or environment variables. For more info see: https://github.com/folio-org/raml-module-builder#postgresql-integration. Using this file I'm able to have the tests in mod-finance-storage run against my local postgres 9.6. However a lot of tests that don't fail with embedded are failing with local non-embedded, even though I appear to be connecting to the db and queries are hitting it.
Testing against a local version of 10.16, all tests pass, which leads me to believe that we're not using 9.6 anymore.
Module readiness for postgres 12
The following table goes into detail about where modules stand as far as upgrading to postgres 12 is concerned. A module is anything with "mod-" in its name. If we want to go beyond this definition of modules to include other FOLIO code, let me know.
Legend: - Everything is good. The module is ready for an upgrade to postgres or it has already upgraded. - Either a problem was encountered in testing or unit tests due to testing the upgrade failed. Probably means more work. Empty status - Means that I wasn't able to find anything that would indicate work needing to be done (because for example the module doesn't talk to postgres). In all cases see the notes for details.
Module | Current supported Postgres version per readme | Version info | Verification method | Status | Notes | Work impact |
raml-module-builder | N/A | Uses postgres:12-alpine in its test container. | Source code contains a reference to postgres:12-alpine. | Already using 12. No failed tests. This is the first row because is used by most of the modules below. The version of RMB that modules use has something to say about the state of postgres. See above for notes on that. | None | |
mod-agreements | It's a grails app. See the services sentry tools/testing/docker-compose.yml. It is using postgres 12. | None | ||||
mod-audit | RMB 32.2.0 | Able to bypass embedded postgres locally. Ran tests against version 10.16 and 12. No failed tests. Upgrading to 12 should be fine. Needed to remove PostgresClient.startEmbeddedPostgres call to get tests against local pg to work. | Upgrade to newest RMB. | |||
mod-authtoken | Does not appear to talk to postgres in any way. See pom.xml. No reference to vertx-db-client or domain model runtime (RMB). | None | ||||
mod-calendar | RMB 32.2.0 | Able to bypass embedded postgres locally. Ran tests against version 10.16 and 12. Tests run: 34. No errors or failures with 10 or 12. Upgrading to 12 should be fine. | Upgrade to newest RMB. | |||
mod-camunda | No vertx-sql or vertx-pg in pom. No reference to embedded pg in tests. | None | ||||
mod-circulation | No vertx-sql or vertx-pg in pom. No reference to embedded pg in tests. | None | ||||
mod-circulation-storage | Readme mentions 9.6.1. Probably needs to be updated to reflect the use of RMB 32.2.0. | RMB 32.2.0 | Uses PostgresTesterContainer | RMB 32.2 uses pg 12. | None | |
mod-codex-ekb | RMB 32.1.0 | No vertx-sql or vertx-pg in pom. No reference to embedded pg in tests. | None | |||
mod-codex-inventory | RMB 32.2.0 | No vertx-sql or vertx-pg in pom. No reference to embedded pg in tests. | None | |||
mod-codex-mux | RMB 32.1.0 | No vertx-sql or vertx-pg in pom. No reference to embedded pg in tests. | None | |||
mod-configuration | RMB 33.0.0 | Uses PostgresTesterContainer | No references to embedded pg. Uses RMB 33. | None | ||
mod-courses | RMB 32.2.2 | Able to bypass embedded postgres locally. Needed to remove PostgresClient.startEmbeddedPostgres (multiple calls) to get tests against local pg to work. Ran tests against version 10.16 and 12. Many test errors (not failures) with both 10 and 12. | Need to investigate large number of errors. These errors do not occur when running against embeded pg, so I have likely broken them. | |||
mod-datasets | Readme says it runs a glint server as an Okapi module. Unclear what that is. | Unknown | ||||
mod-data-export | RMB 32.2.0 | Able to bypass embedded postgres locally. Ran tests against version 10.16 and 12. Needed to remove PostgresClient.startEmbeddedPostgres call to get tests against local pg to work. One failed test when running tests with pg 10. Upgrading to 12 should be fine. | Upgrade to newest RMB. | |||
mod-data-export-worker | No vertx-sql or vertx-pg in pom. No reference to embedded pg in tests. | |||||
mod-data-import | RMB 32.1.0 | Able to bypass embedded postgres locally. Ran tests against version 10.16 and 12. Needed to remove PostgresClient.startEmbeddedPostgres call to get tests against local pg to work. One failed test when running tests with pg 10. Two different tests failed after upgrading to 12. See logs for details. | Investigate two failures (see logs) after upgrading to 12. | |||
mod-data-import-converter-storage | RMB 32.1.0 | Able to bypass embedded postgres locally. Ran tests against version 10.16 and 12. Tests run: 159. No errors or failures with 10 or 12. Upgrading to 12 should be fine. | Upgrade to newest RMB. | |||
mod-ebsconet | No vertx-sql or vertx-pg in pom. No reference to embedded pg in tests. No reference to RMB. | May still be using postgres. Unclear how to run tests against different version of pg, although the connection string appears to be something set in the ENV. See run-env.sh. | ||||
mod-erm-usage | It looks like this module was neglected from the testing as part of the spike. It does seem to have database connectivity and should be tested. | TODO - Testing needs to be done. | ||||
mod-erm-usage-harvester | RMB 32.1.0 | Able to bypass embedded postgres locally. Ran tests against version 10.16 and 12. Same tests that failed with version 10 failed with version 12. Same 1 test failed in both cases. Upgrading to 12 should be fine. Needed to remove PostgresClient.startEmbeddedPostgres call to get tests against local pg to work. | Upgrade to newest RMB. | |||
mod-eusage-reports | Tests do not appear to hit postgres. No apparent usage of embedded pg in tests. | None | ||||
mod-feesfines | RMB 32.1.0 | Able to bypass embedded postgres locally. Ran tests against version 10.16 and 12. Same tests that failed with version 10 failed with version 12. Tests run: 399. Same 3 failed in both cases. Upgrading to 12 should be fine. | Upgrade to newest RMB. | |||
mod-finance-storage | RMB 32.1.0 | Able to bypass embedded postgres locally. Ran tests against version 10.16 and 12. Tests run: 277. Errors: 4. Failures:0. Same errors with version 10 and version 12. Upgrading to 12 should be fine. | Upgrade to newest RMB. | |||
mod-gobi | RMB 32.1.0 | No vertx-sql or vertx-pg in pom. No reference to embedded pg in tests. | ||||
mod-graphql | Don't think it will be affected since it appears to sit on top of modules like mod-inventory-storage. | None | ||||
mod-inn-reach | No vertx-sql or vertx-pg in pom. No reference to embedded pg in tests. | None | ||||
mod-inventory | Does not appear to talk to postgres or reference RMB in its pom file. | None | ||||
mod-inventory-storage | Readme mentions 9.6.1. Probably needs to be updated to reflect the use of RMB 32.2.0. | RMB 32.2.0 | Uses PostgresTesterContainer | RMB 32.2 uses postgres 12. | None | |
mod-invoice | RMB 32.1.0 | No vertx-sql or vertx-pg in pom. No reference to embedded pg in tests. | None | |||
mod-invoice-storage | RMB 32.1.0 | Able to bypass embedded postgres locally. Ran tests against version 10.16 and 12. Needed to remove PostgresClient.startEmbeddedPostgres call to get tests against local pg to work. Tests run: 129. No tests failed. Upgrading to 12 should be fine. | Upgrade to newest RMB. | |||
mod-licenses | It is a grails app, so no pom file. Uses postgres. Not able to run tests locally. | Figure out how to run tests locally. | ||||
mod-login | RMB 32.1.0 | Able to bypass embedded postgres locally. Ran tests against version 10.16 and 12. Same tests that failed with version 10 failed with version 12. Tests run: 31. Errors: 12. Failures: 0. Saame errors with version 10 and 12. Upgrading to 12 should be fine. | Upgrade to newest RMB. | |||
mod-login-saml | RMB 33.0.0-pre1 | No references to embedded postgres in source. Using RMB 33 which uses postgres 12. | None | |||
mod-notes | RMB 32.1.0 | Able to bypass embedded postgres locally. Ran tests against version 10.16 and 12. No tests failed with 10 or 12. Upgrading to 12 should be fine. | Upgrade to newest RMB. | |||
mod-notify | RMB 32.1.0 | Able to bypass embedded postgres locally. Ran tests against version 10.16 and 12. One test (the same test) failed with 10 and 12. Upgrading to 12 should be fine. | Upgrade to newest RMB. | |||
mod-oai-pmh | RMB 31.1.5 | Uses embedded for tests. But appears to use embedded postgres in a way that is different from other modules. Logs indicate that maybe embedded pg (or some other pg process?) should be started manually using pg_ctl. | TODO - Figure out how to run tests. | |||
mod-orders-storage | RMB 32.1.0 | Able to bypass embedded postgres locally. Ran tests against version 10.16 and 12. Tests run: 236. One test failed (the same test) with 10 and 12. Upgrading to 12 should be fine. | Upgrade to newest RMB. | |||
mod-organizations | RMB 31.1.0 | Although it has RMB in the pom, there's no reference to vertx-pg-client or vertx-sql-client. Tests do not appear to make an reference to embedded or PostgresClient. | None | |||
mod-patron | RMB 32.1.0 | No reference to vertx-pg or vertex-sql in pom. I don't see any reference to embedded postgres in the tests. | None | |||
mod-patron-blocks | RMB 32.2.0 | Able to bypass embedded postgres locally. Ran tests against version 10.16 and 12. Needed to remove PostgresClient.startEmbeddedPostgres call to get tests against local pg to work. No test errors or failures. 248 tests run. Upgrading to 12 should be fine. | Upgrade to newest RMB. | |||
mod-permissions | Readme doesn't mention postgres. | RMB 33.0.0-pre2. This should mean it uses 12 for postgres access. | Uses PostgresTesterContainer | Dependencies reference org.testcontainers (probably the RMB). No reference to embedded pg. It looks like mod-permissions only talks to postgres through the RMB, and the RMB version uses postgres 12 in the test container. | None | |
mod-pubsub | RMB 32.1.0 | Was able to run tests against my local postgres by passing the value "external" in using org.folio.pubsub.test.database. I think this gets passed as a maven param. All tests pass when running against either version of postgres. | Upgrade to newest RMB. | |||
mod-remote-storage | No vertx-sql or vertx-pg in pom. No reference to embedded pg in tests. | None | ||||
mod-rtac | No reference to postres in readme. | RMB 32.1.0 | Not seeing any reference to embedded pg in source. No reference to vertx-sql or vertx-pg in pom. | None | ||
mod-search | No vertx-sql or vertx-pg in pom. No reference to embedded pg in tests. | None | ||||
mod-sender | RMB 32.1.0 | Has vertx-sql or vertx-pg in pom. But no reference to embedded pg in tests. No usage of PostgresClient in tests. | None | |||
mod-source-record-storage | RMB 32.1.0 | Even though it is using 32.1, it has already upgraded to postgres 12 by running pg in a container. See https://github.com/folio-org/mod-source-record-storage#compiling. | The amount of work here is fully known, since this module appears to not be taking the path of using testcontainers via RMB. | |||
mod-tags | RMB 32.1.0 | Able to bypass embedded postgres locally. Ran tests against version 10.16 and 12. Tests run: 3. No tests failed with either version. Upgrading to 12 should be fine. | Upgrade to newest RMB. | |||
mod-user-import | RMB 32.1.0 | Not seeing anything in source about embedded postgres. | Upgrade to newest RMB. | |||
mod-template-engine | RMB 32.1.0 | Able to bypass embedded postgres locally. Ran tests against version 10.16 and 12. Tests run: 43. No difference between postgres versions. | Upgrade to newest RMB. | |||
mod-users | RMB 32.1.0 | Able to bypass embedded postgres locally. Same two tests fail when running 10 and 12. Upgrading to 12 should be fine. | Upgrade to newest RMB. | |||
mod-users-bl | RMB 32.1.0 | Not seeing anything in source about embedded postgres. | None |
Results of running pg_upgrade
In our team meeting we thought that running pg_upgrade on 10 to upgrade to 12 would be worth doing. The release notes for pg 12 suggest running pg_upgrade as a way to port data between versions. This is the pg_upgrade doc: https://www.postgresql.org/docs/12/pgupgrade.html. No errors were encountered running pg_upgrade.
To run pg_upgrade I did the following:
- Grabbed the testing-backend vagrant box
- Installed pg 12 on it
- Migrated the data with pg_upgrade without errors
- Swapped the ports of the two versions so that 12 is running on 5432
- Started the postgres service
- Verified the version is 12 via "psql -c SELECT version();"
This is the pg_upgrade command I ran and the and output of the operation:
postgres@vagrant:~$ /usr/lib/postgresql/12/bin/pg_upgrade \
> --old-datadir=/var/lib/postgresql/10/main \
> --new-datadir=/var/lib/postgresql/12/main \
> --old-bindir=/usr/lib/postgresql/10/bin \
> --new-bindir=/usr/lib/postgresql/12/bin \
> --old-options '-c config_file=/etc/postgresql/10/main/postgresql.conf' \
> --new-options '-c config_file=/etc/postgresql/12/main/postgresql.conf'
Performing Consistency Checks
-----------------------------
Checking cluster versions ok
Checking database user is the install user ok
Checking database connection settings ok
Checking for prepared transactions ok
Checking for system-defined composite types in user tables ok
Checking for reg* data types in user tables ok
Checking for contrib/isn with bigint-passing mismatch ok
Checking for tables WITH OIDS ok
Checking for invalid "sql_identifier" user columns ok
Creating dump of global objects ok
Creating dump of database schemas ok
Checking for presence of required libraries ok
Checking database user is the install user ok
Checking for prepared transactions ok
Checking for new cluster tablespace directories ok
If pg_upgrade fails after this point, you must re-initdb the
new cluster before continuing.
Performing Upgrade
------------------
Analyzing all rows in the new cluster ok
Freezing all rows in the new cluster ok
Deleting files from new pg_xact ok
Copying old pg_xact to new server ok
Setting next transaction ID and epoch for new cluster ok
Deleting files from new pg_multixact/offsets ok
Copying old pg_multixact/offsets to new server ok
Deleting files from new pg_multixact/members ok
Copying old pg_multixact/members to new server ok
Setting next multixact ID and offset for new cluster ok
Resetting WAL archives ok
Setting frozenxid and minmxid counters in new cluster ok
Restoring global objects in the new cluster ok
Restoring database schemas in the new cluster
ok
Copying user relation files
ok
Setting next OID for new cluster ok
Sync data directory to disk ok
Creating script to analyze new cluster ok
Creating script to delete old cluster ok
Upgrade Complete
----------------
Optimizer statistics are not transferred by pg_upgrade so,
once you start the new server, consider running:
./analyze_new_cluster.sh
Running this script will delete the old cluster's data files:
./delete_old_cluster.sh
Running analyze_new_cluster generates some statistics that will be meaningful to perhaps someone who knows more about postgres than I do.