Еще одна новая фича pg_filedump: восстанавливаем каталог PostgreSQL



    В прошлой статье мы узнали, как при помощи утилиты pg_filedump можно восстановить данные, или, по крайней мере, какую-то их часть, из полностью убитой базы PostgreSQL. При этом предполагалось, что мы откуда-то знаем номера сегментов, соответствующих таблице. Если мы знаем часть содержимого таблицы, ее сегменты действительно не сложно найти, например, простым grep'ом. Однако в более общем случае это не так-то просто сделать. К тому же, предполагалось, что мы знаем точную схему таблиц, что тоже далеко не факт. Так вот, недавно мы с коллегами сделали новый патч для pg_filedump, позволяющий решить названные проблемы.


    Итак, допустим, мы хотим восстановить таблицу с именем test. Если имя таблицы мы не помним, это не страшно, так так используя описанный далее прием можно получить имена всех таблиц в базе. Информация о таблицах храниться в каталожной таблице pg_class, сегмент которой всегда имеет номер 1259.


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


    ./pg_filedump -D name,oid,oid,oid,oid,oid,oid,~ /path/to/base/16384/1259 | grep COPY | grep test

    Обратите внимание на список типов для декодирования, который мы передаем pg_filedump:


    name,oid,oid,oid,oid,oid,oid,~

    Тут мы в начале передаем имена типов первых семи столбцов таблицы (схема pg_class известна и описана в документации), а тильда говорит игнорировать остальные столбцы. В данном случае они нам все равно не интересны, незачем перечислять их все.


    Пример вывода:


    COPY: test  2200    16387   0   10  0   16385
    COPY: test  2200    16387   0   10  0   16385
    COPY: test_pkey 2200    0   0   10  403 16391

    Последний столбец — это relfilenode, то есть номер сегмента. Он то нам и нужен! Запомним, 16385.


    Но постойте-ка, ведь мы не знаем схему таблицы. Узнать ее нам поможет каталожная таблица pg_attribute, relfilenode которой захардкожен и равен 1249. Кстати, relfilenode всех каталожных таблиц вы можете подсмотреть в файле pg_class.h.


    Открываем доку по pg_attribute, декодируем:


    ./pg_filedump -D oid,name,oid,int,smallint,~ /path/to/base/16384/1249 | grep COPY | grep 16385

    Пример вывода:


    COPY: 16385 k   23  -1  4
    COPY: 16385 v   25  -1  -1
    COPY: 16385 ctid    27  0   6
    COPY: 16385 xmin    28  0   4
    COPY: 16385 cmin    29  0   4
    COPY: 16385 xmax    28  0   4
    COPY: 16385 cmax    29  0   4
    COPY: 16385 tableoid    26  0   4

    Как видите, таблица имеет два столбца с именами k и v (остальные столбцы системные, они нужны для работы MVCC и вот этого всего). Здесь 23 и 25 — это atttypid, то есть, типы столбцов. Но как понять, что это за типы?


    Ответ содержится в каталожной таблице pg_type (relfilenode = 1247, дока):


    ./pg_filedump -i -D name,~ /path/to/base/16384/1247 | grep -A5 -E 'OID: (23|25)'

    Пример вывода:


      XMIN: 1  XMAX: 0  CID|XVAC: 0  OID: 23
      Block Id: 0  linp Index: 8   Attributes: 30   Size: 32
      infomask: 0x0909 (HASNULL|HASOID|XMIN_COMMITTED|XMAX_INVALID) 
      t_bits: [0]: 0xff [1]: 0xff [2]: 0xff [3]: 0x07 
    
    COPY: int4
    --
      XMIN: 1  XMAX: 0  CID|XVAC: 0  OID: 25
      Block Id: 0  linp Index: 10   Attributes: 30   Size: 32
      infomask: 0x0909 (HASNULL|HASOID|XMIN_COMMITTED|XMAX_INVALID) 
      t_bits: [0]: 0xff [1]: 0xff [2]: 0xff [3]: 0x07 
    
    COPY: text

    Итак, теперь у нас на руках есть вся необходимая информация. Таблица называется test, имеет relfilenode 16385 и содержит два столбца — k с типом int4 и v с типом text. Теперь мы можем сдампить ее содержимое, как было описано в предыдущей статье.


    Надеюсь, что на практике эти знания вам никогда не понадобятся :) Если у вас есть вопросы или дополнения, буду рад ознакомиться с ними в комментариях!

    • +27
    • 5,4k
    • 2
    Postgres Professional 110,41
    Российский вендор PostgreSQL
    Поделиться публикацией
    Комментарии 2
    • +1
      Надеюсь, что на практике эти знания вам никогда не понадобятся :)

      Реанимационные процедуры?

    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

    Самое читаемое