Решение проблем с сортировкой строк в PostgreSQL после обновления glibc
Версия библиотеки glibc (GNU C) в Ubuntu 18.04 содержит существенные изменения в правилах сортировки строк. Это изменение влияет на отображение данных и структуру индексов в PostgreSQL, что может привести к нарушению уникальности первичного ключа.
Пример:
CREATE TABLE t (id int, str text PRIMARY KEY);
INSERT INTO t VALUES (1, 'yndkpx'), (2, 'ynd_kpx'), (3, 'ynd-kpx'), (4, 'kpx');
Результат сортировки в выводе SELECT * FROM t ORDER BY str;
:
-
На Ubuntu 14.04:
id | str ----+--------- 1 | yndkpx 2 | ynd_kpx 3 | ynd-kpx 4 | kpx
-
На Ubuntu 18.04:
id | str ----+--------- 3 | ynd-kpx 2 | ynd_kpx 1 | yndkpx 4 | kpx
Критичность проблемы
Изменение порядка сортировки приводит к следующим последствиям:
-
Нарушение уникальности
PRIMARY KEY
. PostgreSQL допускает вставку дубликатов:INSERT INTO t VALUES (5, 'ynd_kpx'); INSERT 0 1 -- Операция успешна, что является нарушением
-
Некорректная работа индексов:
Проверка через
amcheck
:CREATE EXTENSION IF NOT EXISTS amcheck; SELECT bt_index_check('t_pkey');
Результат:
ERROR: item order invariant violated for index "t_pkey" DETAIL: Lower index tid=(1,1) (points to heap tid=(0,1)) higher index tid=(1,2) (points to heap tid=(0,5)) page lsn=0/1665F88.
-
Изменение результатов сравнения строк:
-- Ubuntu 14.04: SELECT '1-1' < '11'; ?column? ---------- f -- Ubuntu 18.04: SELECT '1-1' < '11'; ?column? ---------- t
Техническое решение
Решение реализовано в виде пакета mdb-locales
- Библиотеку
libmdblocales
для загрузки локалей. - Патч для PostgreSQL.
- Фиксированные локали из предыдущей версии
glibc
.
Принцип работы
mdb-locales
обеспечивает перехват системных вызовов локалей с их переадресацией в библиотеку, что стабилизирует поведение сортировки:
-- После установки mdb-locales:
SELECT * FROM pg_collation WHERE collprovider='c';
Результат:
oid | collname | collnamespace | collowner | collversion
-------+------------+---------------+-----------+-------------
12547 | en_US.utf8 | 11 | 10 | 2.27
12548 | en_US | 11 | 10 | 2.27
Верификация
Проверка корректности работы после установки mdb-locales
:
-- Проверка уникальности PRIMARY KEY
INSERT INTO t VALUES (5, 'ynd_kpx');
ERROR: duplicate key value violates unique constraint "t_pkey"
-- Проверка целостности индекса
SELECT bt_index_check('t_pkey');
bt_index_check
---------------
(1 row)
Рекомендации при обновлении Ubuntu до 18.04
-
Перед обновлением:
- Создайте полную резервную копию данных.
- Проведите аудит индексов.
- Установите и настройте
mdb-locales
.
-
После обновления:
- Выполните проверки индексов через
amcheck
. - Протестируйте критичные запросы с сортировкой.
- Верифицируйте уникальные ограничения.
- Выполните проверки индексов через
Важно
Обновление glibc
может нарушить фундаментальные гарантии базы данных. Необходимо провести полное тестирование после обновления системы.