Перейти к основному содержимому

vacuumlo. Утилита для удаления потерянных больших объектов

В исходном дистрибутиве установлено по умолчанию: да.

Связанные компоненты: отсутствуют.

Схема размещения: не используется.

Программа vacuumlo представляет собой утилиту, которая удаляет все «потерянные» большие объекты (LO, Large Objects) из базы данных PostgreSQL. Потерянным считается такой объект, OID которого не фигурирует ни в одном из столбцов oid или lo.

Если в работе появляется необходимость применения утилиты vacuumlo, следует обратить внимание на триггер lo_manage в модуле lo. Триггер lo_manage полезен возможностью предотвратить потерю больших объектов.

Параметры

Обработке подвергаются все базы данных, перечисленные в командной строке при запуске утилиты.

Программа vacuumlo принимает следующие аргументы командной строки:

АргументОписание
-l предел
--limit=предел
Максимальное количество больших объектов, которые следует удалять в пределах одной транзакции.
Сервер запрашивает блокировку для каждого удаляемого большого объекта, поэтому удаление слишком большого количества больших объектов в одной транзакции может привести к превышению лимита, заданного параметром СУБД max_locks_per_transaction.
– Значение 0 задает режим, при котором все удаления будут происходить в одной транзакции;
– значение по умолчанию – 1000
-n
--dry-run
Пробный (тестовый) прогон; программа не будет ничего удалять, а только покажет, какие операции должны будут выполняться
-v
--verbose
Вывод подробного сообщения о прогрессе
-V
--version
Вывод версии утилиты
-?
--help
Вывод справки об аргументах командной строки утилиты
-h сервер
--host=сервер
Параметр подключения: адрес сервера баз данных
-p порт
--port=порт
Параметр подключения: порт сервера баз данных
-U имя_пользователя
--username=имя_пользователя
Параметр подключения: имя пользователя, под которым производится подключение
-w
--no-password
Параметр подключения: Не выдавать запрос на ввод пароля. Если сервер требует аутентификацию по паролю, который недоступен с помощью специальных средств (утилита pg_auth_config или файл .pgpass), попытка соединения будет неудачной. Этот параметр может использоваться в пакетных заданиях и скриптах, где нет пользователя, который вводит пароль
-W
--password
Параметр подключения: Принудительно запрашивать пароль перед подключением к базе данных. Несущественный параметр, так как vacuumlo запрашивает пароль автоматически, если сервер проверяет подлинность по паролю. В этом случае vacuumlo лишний раз подключается к серверу, поэтому для исключения лишней попытки подключения имеет смысл ввести ключ -W

Переменные окружения

Параметры подключения по умолчанию:

  • PGHOST;
  • PGPORT;
  • PGUSER.

Утилита vacuumlo использует переменные среды, поддерживаемые libpq.

Алгоритм работы

Программа vacuumlo работает следующим образом:

  • строит временную таблицу, содержащую все OID больших объектов в выбранной базе данных;
  • сканирует все столбцы в базе данных, имеющие тип oid или lo;
  • удаляет соответствующие записи из временной таблицы, при этом рассматриваются только типы именно с такими именами, оставшиеся записи во временной таблице указывают на потерянные БО, которые затем и удаляются.

Доработка

Доработка не проводилась.

Ограничения

Ограничения отсутствуют.

Установка

Установка не требуется.

Исполняемый файл vacuumlo по умолчанию расположен в каталоге $PGHOME/bin.

Настройка

Настройка не требуется.

Использование модуля

  1. Создайте простой файл lo_file.txt для импорта в базу данных:

    echo abcdefghqwerty > /tmp/lo_file.txt
  2. Вызовите функцию lo_import и передайте имя файла, который требуется загрузить:

    SELECT lo_import('/tmp/lo_file.txt');

    Пример вывода результата выполнения запроса:

    lo_import 
    -----------
    19014
    (1 row)

    В ответ СУБД выдает число – это идентификатор объекта.

  3. Создайте таблицу и сохраните в ней полученный идентификатор, используйте тип данных OID для хранения идентификаторов объектов:

    CREATE TABLE lo_file (name text, oid_number oid);
    INSERT INTO lo_file VALUES ('/tmp/lo_file.txt', lo_import('/tmp/lo_file.txt')) RETURNING *;

    Пример вывода результата выполнения запроса:

        name          | oid_number 
    ------------------+------------
    /tmp/lo_file.txt | 19021
    (1 row)

    INSERT 0 1

    Большой объект полностью независим от файла в файловой системе.

  4. Для проверки работы программы импортируйте указанный файл большое количество раз, в данном примере - 100 тысяч раз:

    INSERT INTO lo_file 
    SELECT '/tmp/lo_file.txt', lo_import('/tmp/lo_file.txt')
    FROM generate_series(1, 100000);

    Проверка результата выполнения запроса:

    lo_tst=# SELECT * FROM lo_file LIMIT 10;
    name | oid_number
    -----------------+------------
    /tmp/lo_file.txt | 19021
    /tmp/lo_file.txt | 19022
    /tmp/lo_file.txt | 19023
    /tmp/lo_file.txt | 19024
    /tmp/lo_file.txt | 19025
    /tmp/lo_file.txt | 19026
    /tmp/lo_file.txt | 19027
    /tmp/lo_file.txt | 19028
    /tmp/lo_file.txt | 19029
    /tmp/lo_file.txt | 19030
    (10 rows)

    Файл был импортирован. Каждый файл имеет новый идентификатор объекта, как показано в списке.

  5. Просмотрите внутренние компоненты при помощи системного каталога pg_largeobject, чтобы понимать, как данные хранятся в СУБД:

    lo_tst=# \d pg_largeobject

    Вывод результата:

            Table "pg_catalog.pg_largeobject"
    Column | Type | Collation | Nullable | Default
    -------+---------+-----------+----------+---------
    loid | oid | | not null |
    pageno | integer | | not null |
    data | bytea | | not null |
    Indexes:
    "pg_largeobject_loid_pn_index" UNIQUE, btree (loid, pageno)

    Подробное описание значений столбцов таблицы pg_largeobject в документации: https://www.postgresql.org/docs/15/catalog-pg-largeobject.html.

  6. Отобразите массив байтов столбца data с типом bytea:

    SELECT * FROM pg_largeobject WHERE loid = 19029 ORDER BY pageno;

    Пример вывода результата выполнения запроса:

    loid  | pageno |               data               
    ------+--------+----------------------------------
    19029 | 0 | \x61626364656667687177657274790a
    (1 row)

    Для удобства чтения переведите вывод двоичных данных в формат escape:

    SET bytea_output TO escape;
    SELECT * FROM pg_largeobject WHERE loid = 19029 ORDER BY pageno;

    Пример вывода результата выполнения запроса:

    loid  | pageno |        data        
    ------+--------+--------------------
    19029 | 0 | abcdefghqwerty\012
    (1 row)
  7. С помощью функции lo_unlink() удалите большой объект с OID 19029:

    SELECT lo_unlink(19029);

    Пример вывода результата выполнения запроса:

    lo_unlink 
    -----------
    1
    (1 row)

    Подробное описание функции lo_unlink() в документации https://www.postgresql.org/docs/15/lo-funcs.html.

  8. Запустите утилиту с аргументом --dry-run или -n для проверки количества больших объектов, подлежащих удалению:

    vacuumlo --dry-run --verbose lo_tst
    Connected to database "lo_tst"
    Test run: no large objects will be removed!
    Checking oid_number in ext.lo_file
    Would remove 1 large objects from database "lo_tst".
  9. Удалите найденный потерянный большой объект:

    vacuumlo --verbose lo_tst
    Connected to database "lo_tst"
    Checking oid_number in ext.lo_file
    Successfully removed 1 large objects from database "lo_tst".
  10. Убедитесь, что повторная проверка не находит потерянных больших объектов в выбранной базе данных:

    vacuumlo --dry-run --verbose lo_tst
    Connected to database "lo_tst"
    Test run: no large objects will be removed!
    Checking oid_number in ext.lo_file
    Would remove 0 large objects from database "lo_tst".
  11. Проверьте отсутствие объекта с OID 19029, который присутствовал на этапе 6 данного примера:

    SELECT * FROM pg_largeobject WHERE loid = 19029 ORDER BY pageno;
    loid | pageno | data
    -----+--------+------
    (0 rows)

Ссылки на документацию разработчика

Исходная документация PosgreSQL по утилите vacuumlo: https://www.postgresql.org/docs/15/vacuumlo.html.