Bytea/Large Objects/external files best practices - Mailing list pgsql-general

From David Helgason
Subject Bytea/Large Objects/external files best practices
Date
Msg-id C29D4850-477C-11D8-BAA4-000A9566DA8A@uti.is
Whole thread Raw
Responses Re: Bytea/Large Objects/external files best practices
Re: Bytea/Large Objects/external files best practices
List pgsql-general
I think those best practices threads are a treat to follow (might even
consider archiving some of them in a sort of best-practices faq), so
here's one more.

In coding an game asset server I want to keep a large number of file
revisions of varying sizes (1Kb-50Mb) inside the database.

Naturally I want to avoid having to allocate whole buffers of 50Mb too
often.

I am also throwing around rsync-style deltas (with librsync), that I
run through functions to generate new objects. The librsync functions
have an elegant buffer oriented approach to reading&writing data, so I
need a way to read through my objects inside the database, again
without having them allocated in RAM too often.

I tried browsing around, but couldn't find any good discussion of this
(or just plain good advice), but of course that may be due to
google-impairment on my part.

I see several options:


1) Bytea column. Seems the cleanest solution, but
    *) it includes lots of escaping-unescaping with associated allocation
of huge buffers.
    *) I seem to remember reading in a discussion in the [hackers] list
that the TOAST column substring operation had been optimized so that
partial fetches might be viable.
    *) Incremental inserts (using a series of "update file set data = data
|| moredata where id=666") probably won't scale nicely.
    *) However it's fully ACID,
    *) and recommended by the docs, if that's a good reason.
    *) TOAST compression. Can't quite figure out if this happens, but in
many cases would store a lot of disk-space & -access.
    *) passing them as arguments to the librsync functions may be a hassle.
    open questions: I wonder what timeframe for this to be viable. It
seems that two things are being worked on that would fix this. The
wire-protocol to avoid having to escape all communications, and methods
for fast incremental update. Both seem to be at least a year away (Pg
7.5, and someone even suggested jumping to 8.0 with the wire-protocol
changes).

2) Bytea column with many rows per file.
    *) Also some escaping-unescaping, but with small buffers
    *) Simple and fast to do partial inserts/selects.
    *) Full ACID (and with a couple of triggers, also easy to keep
completely correct)
    *) Butt ugly solution, but what we used to do with ye olde versions of
MSQL.
    *) Compression, but probably lesser space savings with smaller chunks.
    open questions: What would the chunk-size be? I would imagine 5-20Kb
per row.

3) Large Objects.
    *) Requires special interface to talk to, not that its so bad.
    *) Need a trigger to garbage collect them (simple to do though)
    *) Fully ACID.
    *) I've actually implemented the librsync functions using this
allready, and it seems to work nicely with large files.

4) External files. I really don't like the idea of this.
    *) As high performance as anything.
    *) Need an alternate mechanism to access the server, with security
implications etc.
    *) Complications trying to maintain more-or-less full ACIDity
    open questions: What tricks to use to keep this ACID-ish? I won't have
any updating of content once it's committed, so just keeping the files
read-only most of the time would do most of the trick. Also, I imagine

I'm going with 3) for now, but even tempted by 2) when looking this
over.

At one point I was playing around with 4), and made a plperlu server to
run inside the database to ease this. The security was implemented by
the client receiving a ticket from the database when requesting to
create a file, and then having to send this ticket before being allowed
to send any data to the perl-server. Not an un-clever system, I think,
that I'd be happy to share.

I wonder what other people are doing and if anyone has other arguments.



David Helgason,
Over the Edge Entertainments


pgsql-general by date:

Previous
From: Jan Wieck
Date:
Subject: Re: Oracle -> Postgres live translation?
Next
From: "Marc G. Fournier"
Date:
Subject: Re: Mailing list? was Postgress and MYSQL