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.