Considering that to handle this we'd need to figure out how link libicu.so.55, libicu.so.56, ... etc into the same backend, and yet they presumably have the same collation names,
There's an option when compiling ICU to version extend the API names. So, instead of calling ucol_open(), you'd call ucol_open_55() or ucol_open_56() then you can link to both libixu.so.55 and libicu.so.56 without getting name collisions.
The side effect of this is that it's the application's responsibility to figure out which version of ICU "en_US" should be routed to. In DB2, we started the collation names with UCAxxx (later changed to CLDRxxx) to let us distinguish which version of the API to call.
Admittedly that creates a whole can of worms for initdb-time catalog creation, package maintainers' jobs, how long old versions have to be supported and how you upgraded database objects to new ICU versions.
Yep. We never come up with a good answer for that before I left IBM. At the time, DB2 only supported 2 or 3 version of ICU, so they were all shipped as part of the install bundle.
Long term, I think the only viable approach to supporting multiple versions of ICU is runtime loading of the libraries. Then it's up to the system administrator to make sure the necessary versions are installed on the system.
Yeah, it seems like ICU is *also* subject to minor changes that happen under your feet, much like libc. For example maintenance release 60.2 (you can't install that at the same time as 60.1, but you can install it at the same time as 59.2). You'd be linked against libicu.so.60 (and thence libicudata.so.60), and it gets upgraded in place when you run the local equivalent of apt-get upgrade.
This always worried me because an unexpected collation change is so painful for a database. And I was never able to think of a way of reliably testing compatibility either because of ICU's ability to reorder and group characters when collating.