我想用我的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和圖像的一部分。將數百GB存儲在數據庫中對我來說似乎不是個好主意。由於它們不會改變,只需添加新的文檔,文件的備份就更容易了。由於數據庫已經處理了SSL連接,因此不必部署額外的sftp服務器來提供這些文件!
我只想讀取和寫入我也可以存儲在數據庫中的文件 - 而不是它們駐留在服務器文件系統中。我不明白爲什麼數據庫服務器不應該爲此服務,同時我使用SQL數據庫來處理那些有意義的事情。正如我所說的那樣,如果我不需要部署和配置額外的sftp或ftps服務器,這將使部署我的系統變得更加容易。 – MichaSchumann
不是*而是**另外**。事實上,現在你的模型是:1.將大文件存儲在數據庫中('lowrite'),2.將它保存到文件('lo_export'),3.從數據庫中移除它('lo_unlink')。這個不成立。它涉及大量不必要的昂貴的數據庫操作,包括預寫日誌。 – klin
這個我可以理解,所以這個方法真的是無稽之談,我並沒有真正理解這兩個函數的來源,因爲我對Postgres相當陌生。如果我能夠「傳遞」二進制文件並且不會觸及數據庫,那將是非常棒的。就像數據包裝器,但我沒有找到一個二進制文件,如圖像和壓縮文件。謝謝你的解釋! – MichaSchumann