lo — управление большими объектами
Эта страница переведена при помощи нейросети GigaChat.
Модуль lo
предоставляет поддержку для управления большими объектами (также называемыми LO (Large Objects) или BLOB (Binary Large OBjects)). Он реализует тип данных lo
и триггер lo_manage
.
Этот модуль считается «надежным», то есть его могут устанавливать обычные пользователи, обладающие привилегией CREATE
на текущей базе данных.
Обоснование
Одной из проблем с драйвером JDBC (и это также влияет на драйвер ODBC) является то, что спецификация предполагает, что ссылки на BLOB (двоичные большие объекты) хранятся внутри таблицы, и если эта запись изменяется, связанный BLOB удаляется из базы данных.
Но с PostgreSQL этого не происходит. Большие объекты рассматриваются как самостоятельные объекты, запись в таблице может ссылаться на большой объект по OID, но может быть несколько записей в таблице, ссылающихся на один и тот же большой объект OID, поэтому система не удаляет большой объект только потому, что изменяется или удаляется одна такая запись.
Теперь это нормально для приложений, специфичных для PostgreSQL, но стандартный код, использующий JDBC или ODBC, не будет удалять эти объекты, что приведет к появлению потерянных объектов – объектов, на которые ничего не ссылается, и они просто занимают место на диске.
Модуль lo
позволяет исправить это, прикрепив триггер к таблицам, содержащим столбцы ссылок LO. По сути, этот триггер просто выполняет lo_unlink
каждый раз при удалении или изменении значения, ссылающегося на большой объект. Когда этот триггер используется, предполагается, что существует только одна ссылка базы данных на любой большой объект, который упоминается в контролируемом триггером столбце.
Этот модуль также предоставляет тип данных lo
, который фактически является всего лишь доменом на базе oid
. Это полезно для различения столбцов базы данных, содержащих ссылки на большие объекты, и тех, которые являются OID других вещей. Не нужно использовать тип lo
, чтобы использовать триггер, но может быть удобно использовать его для отслеживания того, какие столбцы в базе данных представляют собой большие объекты, которые управляются с помощью триггера. Кроме того, поступали сообщения, что драйвер ODBC запутывается, если для столбцов BLOB используется не тип lo
.
Как использовать
Вот простой пример использования:
CREATE TABLE image (title text, raster lo);
CREATE TRIGGER t_raster BEFORE UPDATE OR DELETE ON image
FOR EACH ROW EXECUTE FUNCTION lo_manage(raster);
Для каждого столбца, который будет содержать уникальные ссылки на большие объекты, создайте триггер BEFORE UPDATE OR DELETE
, и укажите имя столбца в качестве единственного аргумента триггера. Также можно ограничить выполнение триггера только обновлениями столбцов с помощью BEFORE UPDATE OF
column_name
. Если нужно несколько lo
столбцов в одной таблице, создайте отдельный триггер для каждого из них, не забывая давать каждому триггеру на той же таблице уникальное имя.
Ограничения
-
Удаление таблицы все равно приведет к тому, что любые содержащиеся в ней объекты станут сиротами, поскольку триггер не выполняется. Можно избежать этого, предварив
DROP TABLE
с помощьюDELETE FROM
table
.TRUNCATE
имеет ту же опасность.Если уже есть или есть подозрение, что появились потерянные большие объекты, то используйте модуль vacuumlo, чтобы вычистить их. Хорошей идеей будет периодически запускать
vacuumlo
в качестве резервного варианта для триггераlo_manage
. -
Некоторые интерфейсы могут создавать свои собственные таблицы и не будут создавать соответствующие триггеры(ы). Кроме того, пользователи могут не помнить (или знать), как создать триггеры.