Ответы пользователя по тегу PostgreSQL
  • PostgresPro 12 не совпадает правило сортировки. Как исправить?

    @rus_99_pk
    Добрый день.
    Проблема фактически связана с версией 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.

    Что будет если не обращать внимания?
    Здесь важно понять будут ли отличия в функционале сортировки, например:
    • server_1 (2.31):

    $ ( 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_2 (2.35):

    $ ( 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 пункты на свой страх и риск.


    Очень рекомендую ознакомиться со статьей об этом.
    Ответ написан
    Комментировать