Добрый день.
Проблема фактически связана с версией
libc6, если речь о Linux. Т.к. PG берет значение версии сортировки оттуда.
Что здесь происходит?
Например, возьмем 2 сервера на Ubuntu, server_1 (Ubuntu 20.04, версия libc6 - 2.31-0ubuntu9.14) и server_2 (Ubuntu 22.04, версия libc6 - 2.35-0ubuntu3.6). Проверить версию можно командой dpkg -l libc6. Поднимем и там и там Postgres одной и той же версии. Создаем БД, например my_db, на server_1, далее с помощью бэкапа (неважно какого) переносим и поднимаем БД на server_2. На первый взгляд все ОК, но если выполнить select * from pg_collation where collversion = '2.31' (прошу обратить внимание), то видим версию правил сортировки с server_1, а в логе то что вы прислали выше.
Предлагаю заранее определиться какая в системе/БД локаль по умолчанию, узнать можно с помощью
locale -a. В примере рассмотрю БД с локалью
ru_RU.UTF-8.
Что будет если не обращать внимания?
Здесь важно понять будут ли отличия в функционале сортировки, например:
$ ( echo 1-; echo 11; echo 1-1; echo 111; echo 1a; echo 1b; echo 1-aa; echo 1-a) | LC_COLLATE=ru_RU.UTF-8 sort
1-
1-1
11
111
1-a
1a
1-aa
1b
$ ( echo 1-; echo 11; echo 1-1; echo 111; echo 1a; echo 1b; echo 1-aa; echo 1-a) | LC_COLLATE=ru_RU.UTF-8 sort
1-
1-1
11
111
1-a
1a
1-aa
1b
Видим одинаковый вывод, значит данные, предварительно, сортируются одинаково.
В указанном примере нам повезло, сортировка одинаковая, но что если взять server_3 на Ubuntu 16.04, где версия libc6 2.27?
$ ( echo 1-; echo 11; echo 1-1; echo 111; echo 1a; echo 1b; echo 1-aa; echo 1-a) | LC_COLLATE=en_US.UTF-8 sort
1-
11
1-1
111
1a
1-a
1-aa
1b
!!! А вот это уже не очень хорошо, так и БД поломать можно. Здесь срочно нужно что-то делать
!!!
Тем не менее, хотя это и не является исчерпывающим, но дает немного больше информации о том, как параметры сортировки меняются в разных версиях glibc.
Как решить?
Вариант 1 (если нет кластера):
1. Подключаемся к базе из консоли:
$ psql -h 127.0.0.1 -U postgres
2. Создаем правило для новой версии:
postgres=# CREATE COLLATION russian (provider = libc, locale = 'ru_RU.utf8');
4. Обновляем базу my_db (и остальные тоже, если на них ругается в логе):
postgres=# ALTER DATABASE my_db REFRESH COLLATION VERSION;
5. Выходим:
postgres=# \q
6. Делаем рестарт postgresql
$ sudo service postgresql restart
7. Идем в лог посмотреть как дела
Вариант 2 (если есть кластер, например Patroni):
1. Обновлять ОС на server_1, а вместе с ней и libc6
2. Откатывать текущую версию libc6 на server_2 на более старую (FYI: у меня не получилось это сделать, не сломав ОС)
3. Обновить версию библиотеки на старой версии ОС (https://askubuntu.com/questions/1408049/how-can-i-get-glibc-2-35-on-ubuntu-20-04)
2 и 3 пункты на свой страх и риск.
Очень рекомендую ознакомиться со
статьей об этом.