2015-11-12 3 views
1

Я хотел бы использовать мой сервер 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 для обслуживания этих файлов!

ответ

0

Ваша концепция обречена на провал. Вы используете сервер базы данных как кеш для операций с дисками в больших файлах. Это очевидная трата времени и ресурсов, потому что сервер каждый раз должен сохранить все содержимое файла, чтобы удалить его на мгновение.

На мой взгляд, использование ftp-сервера будет более простым, более естественным и более эффективным решением.

+0

Я просто хочу читать и записывать файлы, которые я также мог хранить в базе данных, вместо этого они находятся в файловой системе серверов. Я не понимаю, почему сервер базы данных также не должен служить этому, пока я использую базу данных SQL для тех вещей, которые имеют смысл. Как я уже сказал, это упростит развертывание моей системы, если мне не придется развертывать и настраивать дополнительный сервер sftp или ftps. – MichaSchumann

+0

Не * вместо * но ** дополнительно **. Фактически, теперь ваша модель: 1. Сохраните большой файл в базе данных ('lowrite'), 2. сохраните его в файле (' lo_export'), 3. удалите его из базы данных ('lo_unlink'). Это не имеет никакого смысла. Это связано с большим количеством ненужных дорогостоящих операций с базами данных, включая запись на запись. – klin

+0

Это я могу понять, поэтому этот подход на самом деле вздор, я действительно не понимал источник двух функций как документацию, поскольку я совершенно новичок в Postgres. Было бы здорово, если бы я мог просто «передать» двоичные файлы, и они не коснулись базы данных. Подобно tose data wrappers, но я не нашел его для двоичных файлов, таких как изображения и сжатые документы. Спасибо за ваше объяснение! – MichaSchumann

Смежные вопросы