Postgres读写外部文件

时间:2015-11-12 09:43:29

标签: postgresql

我想使用我的postgres服务器来提供我不想存储在数据库中的文档和图像,原因有几个。

为此目的有一个扩展https://github.com/darold/external_file external file external file并且稍微更改了代码以满足我的需求而不更改核心(请参阅下文)。我正在使用9.5,因为我希望在完成开发之前这个版本是最终的; - )

我遇到以下问题:

  • 写作速度快,似乎可靠但大文件导致内存不足(1G及以上)。
  • 阅读常常会持续很长时间(选择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;

解释我对上述内容的需求:这将是医疗系统的一部分,该系统还通过不安全的连接服务和存储巨大的文件和图像。在数据库中存储数百GB似乎对我来说不是一个好主意。由于他们不会改变,只是添加了新的文档,因此备份文件要容易得多。由于数据库已经处理了SSL连接,因此不必部署额外的sftp服务器来提供这些文件!

1 个答案:

答案 0 :(得分:0)

你的观念注定要失败。您正在使用数据库服务器作为大型文件上磁盘操作的缓存。这显然是浪费时间和资源,因为服务器每次都必须保存文件的全部内容以暂时将其删除。

在我看来,使用ftp服务器将更简单,更自然,更有效的解决方案。