Я хотел бы использовать мой сервер postgres для обслуживания документов и изображений, которые я не хочу хранить в базе данных по нескольким причинам.Postgres чтение и запись внешних файлов
Существует расширение для этой цели https://github.com/darold/external_fileexternal fileexternal file и немного изменил код, чтобы удовлетворить мои потребности, не меняя ядро (см. Ниже). Я использую 9.5, как я надеюсь, эта версия является окончательным, прежде чем я закончу развитие ;-)
я сталкиваюсь со следующими проблемами:
- Запись работает быстро и, кажется надежным, но большие файлы приводят к из память (1Gig и выше).
- Чтение часто висит очень долго (выберите readEFile ('aPath');) и не является надежным.
- И WAL, и база данных быстро растут в размерах, хотя не используются таблицы базы данных.
Мои вопросы:
Что неправильно в следующем коде? Как я могу исключить все эти операции из WAL? Кто-нибудь написал что-то подобное и разделил бы его развитие?
CREATE OR REPLACE FUNCTION public.writeefile(
buffer bytea,
filename character varying)
RETURNS void AS
$BODY$
DECLARE
l_oid oid;
lfd integer;
lsize integer;
BEGIN
l_oid := lo_create(0);
lfd := lo_open(l_oid,131072); --0x00020000 write mode
lsize := lowrite(lfd,buffer);
PERFORM lo_close(lfd);
PERFORM lo_export(l_oid,filename);
PERFORM lo_unlink(l_oid);
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION public.writeefile(bytea, character varying)
OWNER TO itcms;
CREATE OR REPLACE FUNCTION public.readefile(filename character varying)
RETURNS bytea AS
$BODY$
DECLARE
l_oid oid;
r record;
buffer bytea;
BEGIN
buffer := '';
SELECT lo_import(filename) INTO l_oid;
FOR r IN (SELECT data
FROM pg_largeobject
WHERE loid = l_oid
ORDER BY pageno) LOOP
buffer = buffer || r.data;
END LOOP;
PERFORM lo_unlink(l_oid);
return buffer;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION public.readefile(character varying)
OWNER TO itcms;
Чтобы объяснить мою потребность выше: Это будет частью медицинской системы, которая служит также и хранит огромные documens и изображения через небезопасные соединения. хранение сотен ГБ в базе данных не кажется мне хорошей идеей. Поскольку они не меняются, и только новые документы добавляются, резервное копирование файлов намного проще. Поскольку база данных уже обрабатывает SSL-соединения, было бы неплохо развернуть дополнительный сервер sftp для обслуживания этих файлов!
Я просто хочу читать и записывать файлы, которые я также мог хранить в базе данных, вместо этого они находятся в файловой системе серверов. Я не понимаю, почему сервер базы данных также не должен служить этому, пока я использую базу данных SQL для тех вещей, которые имеют смысл. Как я уже сказал, это упростит развертывание моей системы, если мне не придется развертывать и настраивать дополнительный сервер sftp или ftps. – MichaSchumann
Не * вместо * но ** дополнительно **. Фактически, теперь ваша модель: 1. Сохраните большой файл в базе данных ('lowrite'), 2. сохраните его в файле (' lo_export'), 3. удалите его из базы данных ('lo_unlink'). Это не имеет никакого смысла. Это связано с большим количеством ненужных дорогостоящих операций с базами данных, включая запись на запись. – klin
Это я могу понять, поэтому этот подход на самом деле вздор, я действительно не понимал источник двух функций как документацию, поскольку я совершенно новичок в Postgres. Было бы здорово, если бы я мог просто «передать» двоичные файлы, и они не коснулись базы данных. Подобно tose data wrappers, но я не нашел его для двоичных файлов, таких как изображения и сжатые документы. Спасибо за ваше объяснение! – MichaSchumann