У нас есть сценарии хранения в БД остывающих UGC-данных. Чем старше данные, тем реже за ними приходят. Таблицы с такими данными мы партиционируем по времени и по мере остывания данных перемещаем их с SSD-дисков на SATA. Это даёт очень некислую экономию на стоимости железа. В PostgreSQL есть родной механизм табличных пространств, которые можно положить на разные устройства, и есть родная команда ALTER TABLE foo SET TABLESPACE bar, с помощью которой можно решать нашу задачу. Но у этой команды есть существенный недостаток — в момент перемещения партиции на неё берётся эксклюзивная блокировка, а потому в неё не просто нельзя писать, но и читать, а это уже совсем нехорошо.

К счастью, есть замечательная штука, которая называется pg_repack и создана для решения задач вроде вышеописанной. Мы успешно используем её с PostgreSQL 9.3, но в декабре уже вышла 9.4 и мы стали задумываться об обновлении.

На github уже давно открыта задача про поддержку 9.4, но никто ей не занимался. Поскольку мне было надо и никто этим заниматься не хотел, пришлось делать самому. На выходе получился вот такой pull request.

Он проходит тесты на 9.3 и 9.4 и точно перемещает табличку со всеми индексами из одного табличного пространства в другое. Но строго говоря, этот патч не слишком правильный — он не накрывает случай с несколькими TOAST-индексами, который может случаться в будущем. Надеюсь, разработчики найдут силы и время поправить проблему на совесть, пусть для этого и надо будет много чего переписать.

А вообще основным достижением является не патч, а полученный мной опыт в результате:

  • ковыряния структуры pg_catalog,
  • отладки своих изменения с помощью GDB (кстати, хорошая презентация на эту тему),
  • разбирательств с регрeссионными тестами PostgreSQL.

Comments

comments powered by Disqus