Thread: Restore postgresql data directory to tablespace on new host? Or swap tablespaces?

Restore postgresql data directory to tablespace on new host? Or swap tablespaces?

From
"Antman, Jason (CMG-Atlanta)"
Date:

I have a bunch of test/development databases which we currently refresh with production data as-needed using a NetApp filer's snapshot capabilities - we have a production slave with its datadir on a filer mount (NFS), and once a night (via cron) we shutdown the slave, snapshot the filer volume, and then start the database back up. When we need to do data refresh in a test/dev environment, we stop postgres there, clone the NetApp snapshot, and use that clone as the test/dev environment data directory. This is wonderful from a storage point of view, as the clones only store changed blocks on the filer. We have a ~1.5TB datadir, but these clones are only a few MB each, because there's little changed data. (We're running postgres 9.0.13, but if what I'm about to ask is "more possible" with a newer version, that's a vague possibility)

Up until now, each test/dev environment has had its own postgres server. That's pretty bad on resources, since they're largely idle most of the time.

Now, we have to spin up somewhere around 100-150 of these environments. The NetApp is about the only way we can do it, because we simply don't have 150-225TB of disk to spare. It would also be a real pain (and inefficient) to run 100-150 separate machines, each running a single instance of postgres.

What I'd like to do is take a disk/filer snapshot of a stopped database (i.e. the actual files on disk, not a pg_dump) on one postgres instance (one physical server) and restore it on a different one. Ideally the database would have a different name, but that's flexible. Even more ideally this would all happen without a restart of the destination postgres instance, but I suppose we can work around that too.

Is this even possible? Anyone have experience with, essentially, creating a tablespace that points to an existing data directory? Or, alternatively, swapping out the data directory of one tablespace with that of another?

Any advice or suggestions would be greatly appreciated.
I apologize if there's something obvious in the documentation that I missed, but I'm not much of a database guru, and am relatively new to pgsql in general.
Jason Antman

PS - The slightly-less-abstract explanation:

We're spinning up nearly 100 (maybe 150) new test environments. We simply don't have the ~200T of disk to maintain a separate DB for each of them, so using the NetApp filer and letting it do thin clones is an absolute requirement. We also need to be able to do quick restores to the latest daily production snapshot. Quick as in, the developers and testers run a script in their test environment that does the restore. We're currently doing this for ~50 environments, and we run a separate VM with postgres for each one, so it's relatively straightforward - stop postgres, unmount the datadir, do the filer magic to refresh it with a clone of this morning's production DB, then re-mount the new filer volume (clone) and start postgres. Unfortunately, the massive overhead of running a separate virtual machine with a separate postgres instance for every DB is more than we can handle when scaling 2-3x. In addition to that, the resource waste is awful (a dedicated VM running a dedicated postgres instance for each DB, most of which are idle about 14 hours/day). So, we'd like to run multiple databases in separate tablespaces, but on the same host and the same postgres instance, so N databases can use the same shared memory, etc.

The developers and testers who use these instances need to be able to "get fresh data" as often as need (sometimes 3x/day). Ideally we'd be able to refresh one of these filer volumes without stopping postgres. But it's also an acceptable alternative to build out, say, 3x the number of DBs we need, and refresh all of the not-currently-in-use ones on a schedule every night, during a maintenance/downtime window.

Re: Restore postgresql data directory to tablespace on new host? Or swap tablespaces?

From
"Antman, Jason (CMG-Atlanta)"
Date:
I also asked this question on dba.stackexchange.com, where it received a very detailed enumeration of the associated problems from Craig Ringer:
http://dba.stackexchange.com/questions/58896/restore-postgres-data-tablespace-to-new-tablespace-at-new-mount-point/58967?noredirect=1#58967

Perhaps there's a postgres internals expert around, someone intimitely familiar with pg_xlog/pg_clog/pg_control, who can comment on whether it's possible to take the on-disk files from a single database in a single tablespace, and make them usable by a different postgres server, running multiple databases?

Thanks,
Jason

On 02/13/2014 04:41 PM, Antman, Jason (CMG-Atlanta) wrote:

I have a bunch of test/development databases which we currently refresh with production data as-needed using a NetApp filer's snapshot capabilities - we have a production slave with its datadir on a filer mount (NFS), and once a night (via cron) we shutdown the slave, snapshot the filer volume, and then start the database back up. When we need to do data refresh in a test/dev environment, we stop postgres there, clone the NetApp snapshot, and use that clone as the test/dev environment data directory. This is wonderful from a storage point of view, as the clones only store changed blocks on the filer. We have a ~1.5TB datadir, but these clones are only a few MB each, because there's little changed data. (We're running postgres 9.0.13, but if what I'm about to ask is "more possible" with a newer version, that's a vague possibility)

Up until now, each test/dev environment has had its own postgres server. That's pretty bad on resources, since they're largely idle most of the time.

Now, we have to spin up somewhere around 100-150 of these environments. The NetApp is about the only way we can do it, because we simply don't have 150-225TB of disk to spare. It would also be a real pain (and inefficient) to run 100-150 separate machines, each running a single instance of postgres.

What I'd like to do is take a disk/filer snapshot of a stopped database (i.e. the actual files on disk, not a pg_dump) on one postgres instance (one physical server) and restore it on a different one. Ideally the database would have a different name, but that's flexible. Even more ideally this would all happen without a restart of the destination postgres instance, but I suppose we can work around that too.

Is this even possible? Anyone have experience with, essentially, creating a tablespace that points to an existing data directory? Or, alternatively, swapping out the data directory of one tablespace with that of another?

Any advice or suggestions would be greatly appreciated.
I apologize if there's something obvious in the documentation that I missed, but I'm not much of a database guru, and am relatively new to pgsql in general.
Jason Antman

PS - The slightly-less-abstract explanation:

We're spinning up nearly 100 (maybe 150) new test environments. We simply don't have the ~200T of disk to maintain a separate DB for each of them, so using the NetApp filer and letting it do thin clones is an absolute requirement. We also need to be able to do quick restores to the latest daily production snapshot. Quick as in, the developers and testers run a script in their test environment that does the restore. We're currently doing this for ~50 environments, and we run a separate VM with postgres for each one, so it's relatively straightforward - stop postgres, unmount the datadir, do the filer magic to refresh it with a clone of this morning's production DB, then re-mount the new filer volume (clone) and start postgres. Unfortunately, the massive overhead of running a separate virtual machine with a separate postgres instance for every DB is more than we can handle when scaling 2-3x. In addition to that, the resource waste is awful (a dedicated VM running a dedicated postgres instance for each DB, most of which are idle about 14 hours/day). So, we'd like to run multiple databases in separate tablespaces, but on the same host and the same postgres instance, so N databases can use the same shared memory, etc.

The developers and testers who use these instances need to be able to "get fresh data" as often as need (sometimes 3x/day). Ideally we'd be able to refresh one of these filer volumes without stopping postgres. But it's also an acceptable alternative to build out, say, 3x the number of DBs we need, and refresh all of the not-currently-in-use ones on a schedule every night, during a maintenance/downtime window.


Click here to report this email as spam.



--
Jason Antman | Systems Engineer | CMGdigital
jason.antman@coxinc.com | p: 678-645-4155
"Antman, Jason (CMG-Atlanta)" <Jason.Antman@coxinc.com> writes:
> Perhaps there's a postgres internals expert around, someone intimitely familiar with pg_xlog/pg_clog/pg_control, who
cancomment on whether it's possible to take the on-disk files from a single database in a single tablespace, and make
themusable by a different postgres server, running multiple databases? 

It is not.  There's no need for detailed discussion.

            regards, tom lane


On 2/15/2014 10:15 AM, Antman, Jason (CMG-Atlanta) wrote:
> I also asked this question on dba.stackexchange.com, where it received
> a very detailed enumeration of the associated problems from Craig Ringer:
>
http://dba.stackexchange.com/questions/58896/restore-postgres-data-tablespace-to-new-tablespace-at-new-mount-point/58967?noredirect=1#58967
>
> Perhaps there's a postgres internals expert around, someone intimitely
> familiar with pg_xlog/pg_clog/pg_control, who can comment on whether
> it's possible to take the on-disk files from a single database in a
> single tablespace, and make them usable by a different postgres
> server, running multiple databases?

Craig's answer covers all the bases, quite accurately.    Because you
don't like it, you think someone else is going to give you some magic to
make all that go away?



--
john r pierce                                      37N 122W
somewhere on the middle of the left coast



Re: Restore postgresql data directory to tablespace on new host? Or swap tablespaces?

From
"Antman, Jason (CMG-Atlanta)"
Date:
Well thanks for someone at least sending a reply, though I suppose I
should have asked "how do I do this", or "what are the major hurdles to
doing this", as it obviously has to be *possible* given unlimited
knowledge, resources and time.

Perhaps I should frame the question differently:

If you had a single ~1TB database, and needed to be able to give fresh
data copies to dev/test environments (which are usually largely idle)
either on demand or daily, how would you do it? The only other thing
that comes to mind is separate postgres instances (running multiple
postgres instances per server?), one per database, for every
environment. Which means that if 80% of the environments are idle at a
given time, I'm effectively wasting 80% of the memory that I have
allocated to shared buffers, etc. and I actually need 4x the resources
I'm using? Unless postgres supports balooning of memory?

Thanks,
Jason

On 02/15/2014 01:20 PM, Tom Lane wrote:
> "Antman, Jason (CMG-Atlanta)" <Jason.Antman@coxinc.com> writes:
>> Perhaps there's a postgres internals expert around, someone intimitely familiar with pg_xlog/pg_clog/pg_control, who
cancomment on whether it's possible to take the on-disk files from a single database in a single tablespace, and make
themusable by a different postgres server, running multiple databases? 
> It is not.  There's no need for detailed discussion.
>
>             regards, tom lane


--

Jason Antman | Systems Engineer | CMGdigital
jason.antman@coxinc.com | p: 678-645-4155


Re: Restore postgresql data directory to tablespace on new host? Or swap tablespaces?

From
Karsten Hilbert
Date:
On Sat, Feb 15, 2014 at 06:15:04PM +0000, Antman, Jason (CMG-Atlanta) wrote:

> I also asked this question on dba.stackexchange.com, where it received a very detailed enumeration of the associated
problemsfrom Craig Ringer: 

...

> Perhaps there's a postgres internals expert around, someone
> intimitely familiar with pg_xlog/pg_clog/pg_control,

Uhm, like, Craig Ringer ?

Karsten
--
GPG key ID E4071346 @ gpg-keyserver.de
E167 67FD A291 2BEA 73BD  4537 78B9 A9F9 E407 1346


On 2/15/2014 10:31 AM, Antman, Jason (CMG-Atlanta) wrote:
> If you had a single ~1TB database, and needed to be able to give fresh
> data copies to dev/test environments (which are usually largely idle)
> either on demand or daily, how would you do it? The only other thing
> that comes to mind is separate postgres instances (running multiple
> postgres instances per server?), one per database, for every
> environment. Which means that if 80% of the environments are idle at a
> given time, I'm effectively wasting 80% of the memory that I have
> allocated to shared buffers, etc. and I actually need 4x the resources
> I'm using? Unless postgres supports balooning of memory?

perhaps you could start/stop the test instances on demand as needed ?

--
john r pierce                                      37N 122W
somewhere on the middle of the left coast



Re: Restore postgresql data directory to tablespace on new host? Or swap tablespaces?

From
"Antman, Jason (CMG-Atlanta)"
Date:
On 02/15/2014 01:22 PM, John R Pierce wrote:
> On 2/15/2014 10:15 AM, Antman, Jason (CMG-Atlanta) wrote:
>> I also asked this question on dba.stackexchange.com, where it
>> received a very detailed enumeration of the associated problems from
>> Craig Ringer:
>>
http://dba.stackexchange.com/questions/58896/restore-postgres-data-tablespace-to-new-tablespace-at-new-mount-point/58967?noredirect=1#58967

>>
>>
>> Perhaps there's a postgres internals expert around, someone
>> intimitely familiar with pg_xlog/pg_clog/pg_control, who can comment
>> on whether it's possible to take the on-disk files from a single
>> database in a single tablespace, and make them usable by a different
>> postgres server, running multiple databases?
>
> Craig's answer covers all the bases, quite accurately.    Because you
> don't like it, you think someone else is going to give you some magic
> to make all that go away?
>
>
>
1) The second-to-last paragraph in Craig's answer is,
"This is quite an interesting problem, and I suggest raising it on the
pgsql-general mailing list. Link back here for context (and so people
can explain all the things I got wrong in the above explanation)."

2) I was hoping that someone else would either (a) correct "all the
things that [Craig] got wrong in the above explanation", or (b) give me
some pointers on possible ways to do this. If the answer is "well, it
would be a lot easier if you imported a schema-only pgdump of each
database, and then mucked with the internals of the tablespace", that's
a good starting point. Honestly, if the answer is "this simply will not
happen unless you hire a postgresql core developer to code it", that's
still a more complete answer to bring to management than "not possible."
I work in a software development shop... there's a general hatred of the
idea of "impossible" (as opposed to impractical) when it comes to software.

Thanks,
Jason

--

Jason Antman | Systems Engineer | CMGdigital
jason.antman@coxinc.com | p: 678-645-4155


On 02/15/2014 10:31 AM, Antman, Jason (CMG-Atlanta) wrote:
> Well thanks for someone at least sending a reply, though I suppose I
> should have asked "how do I do this", or "what are the major hurdles to
> doing this", as it obviously has to be *possible* given unlimited
> knowledge, resources and time.
>
> Perhaps I should frame the question differently:
>
> If you had a single ~1TB database, and needed to be able to give fresh
> data copies to dev/test environments (which are usually largely idle)
> either on demand or daily, how would you do it? The only other thing
> that comes to mind is separate postgres instances (running multiple
> postgres instances per server?), one per database, for every
> environment. Which means that if 80% of the environments are idle at a
> given time, I'm effectively wasting 80% of the memory that I have
> allocated to shared buffers, etc. and I actually need 4x the resources
> I'm using? Unless postgres supports balooning of memory?

<<Thinking out loud>>

Your requirements:

If I am following correctly you want a single universal data set that is
accessible by multiple databases at will. There will be 100-150
different databases to which presumably different things are being done.
With, ideally, the databases having different names. Also it would be
helpful if the data could be refreshed without stopping the cluster.

The process:

Start at known point, the state of the production server at point in time.

Apply that state as the starting point for 100-150 databases.

Do things to those 100-150 databases that cause them to deviate from the
starting point and each other.

Periodically reset some portion of the databases to a new starting point
based on a different state of the production database.

The issue:

The killer would seem to be the global(cluster)/local(database) problem.
The cluster has the database at one state and then you try impose a
database state from another cluster on it. Even given your
stipulation-.."to be *possible* given unlimited knowledge, resources and
time.", I would say not in a time frame that is going to help you in the
practical future.

Solution or not;

Not seeing how you can do it without using some variation of what you do
now. Part of the problem in trying to come up with a solution is not
knowing what is being done to the test/dev databases.

Is the full dataset a requirement for testing or would a subset do?

Are there 100-150 users/tests each needing a database or could databases
be shared?

Is the 80% idle figure you mention manageable?
In other words do the tests run whenever, so the instances have to
always be available or can they be spun up on demand?


>
> Thanks,
> Jason
>
> On 02/15/2014 01:20 PM, Tom Lane wrote:
>> "Antman, Jason (CMG-Atlanta)" <Jason.Antman@coxinc.com> writes:
>>> Perhaps there's a postgres internals expert around, someone intimitely familiar with pg_xlog/pg_clog/pg_control,
whocan comment on whether it's possible to take the on-disk files from a single database in a single tablespace, and
makethem usable by a different postgres server, running multiple databases? 
>> It is not.  There's no need for detailed discussion.
>>
>>             regards, tom lane
>
>


--
Adrian Klaver
adrian.klaver@gmail.com


Re: Restore postgresql data directory to tablespace on new host? Or swap tablespaces?

From
"Antman, Jason (CMG-Atlanta)"
Date:
On 02/15/2014 02:00 PM, Francisco Olarte wrote:
> Hi:
>
> On Sat, Feb 15, 2014 at 7:31 PM, Antman, Jason (CMG-Atlanta)
> <Jason.Antman@coxinc.com> wrote:
>> Well thanks for someone at least sending a reply, though I suppose I
>> should have asked "how do I do this", or "what are the major hurdles to
>> doing this", as it obviously has to be *possible* given unlimited
>> knowledge, resources and time.
> Some things have been proven impossible, maybe this is one of those.
> Maybe the lack of answers is due people having the same impression to
> your your original message as me. I mean he NEEDS 100-150 dev/test
> copies?
The short answer is... due to too much technical debt, and some perhaps
bad decisions made in the past... yeah. We've dug ourselves into this
hole, and there's no feasible way out. Currently we have ~50 dev/test
environments, each of which has a clone of the full production database
(on a NetApp, using flexclones, so it's *much* smaller in terms of
actual disk usage). Each of them is backed up its own postgres instance
running in a dedicated VM. Data refreshes are done on-demand by stopping
the postgres instance, unmounting and deleting the volume backing it,
making a new clone of the daily snapshot, mounting it, and bringing
postgres back up. But we don't have the money (or, more importantly,
datacenter space) to dedicate a piece of hardware to each of these. So
most dev environments can only handle ~1 person using the application at
a time, due to trying to run a complex ORM (Django) against a ~1T
database on a host with < 24G RAM. Actual testing happens in a different
environment, which runs on bare metal. Load tests happen in an even more
different environment, with a master and slave.

So, we really need ~50 copies that can be refreshed at arbitrary
intervals. Since I've already determined that's absolutely impossible
without stopping postgres, I calculated 100-150 assuming we do bulk
refreshes at night, and each developer is allocated 2-3 possible
refreshes in a given 24-hour period.

Since we've allowed the database to grow without using Django's
facilities to split largely unrelated objects into different databases
and handle any JOINs in the application, and we've gradually let the
database diverge from the models actually in the ORM, every attempt at
crafting a DB with a restricted set of recent data has failed. And yes,
unfortunately, individual developers have had their own private database
instance for long enough that migrating to a shared DB approach has been
discarded as an option.

>
>> Perhaps I should frame the question differently:
>> If you had a single ~1TB database, and needed to be able to give fresh
>> data copies to dev/test environments (which are usually largely idle)
>> either on demand or daily, how would you do it? The only other thing
>> that comes to mind is separate postgres instances (running multiple
>> postgres instances per server?), one per database, for every
>> environment. Which means that if 80% of the environments are idle at a
>> given time, I'm effectively wasting 80% of the memory that I have
>> allocated to shared buffers, etc. and I actually need 4x the resources
>> I'm using? Unless postgres supports balooning of memory?
> If I NEEDED to be able to provide 100-150 snapshots to test/dev
> environments 20% of which maybe active, I'll setup a cluster, buy
> somewhere above a quarter terabyte RAM and some big snapshot
> appliances. They are not that expensive, and someone NEEDING that big
> dev/test systems must be on a humoungous project, where the cost of
> throwing hardware at the problem would be dwarfed by any small delay
> trying to set that up with minimal resources. A postgres instance
> should happily run in half a gig, using proper snapshots would let you
> share cache among them, so you could put quite a lot of them in one of
> these 384G machines floating around, even on a 192G one, throw a
> snapshotting filesystem or appliance on the mix and is not that
> complex.
I'm not sure what you mean by "snapshot appliance". If you mean
something like a NetApp filer, yeah, that's what we're using.
Unfortunately, no, we're on a project that's far from having an
unlimited budget. The requirement for that big of a dev/test system is
above... essentially, a lot of bad decisions that got us to the point of
having a single ~1T database and no successful attempt at removing any
significant amount of data from it.

So you're suggesting running multiple instances of postgres in the same
operating system, and they'll be able to share cache, instead of trying
to get multiple DBs in the same instance? Is there any accepted method
of managing N postgres instances on one host? Any tools or documentation
for that, or best practices? Seems scary to me, but I suppose it's the
best option we have...

By "A postgres instance should happily run in half a gig" I assume
you're not counting cache/buffers, etc.? Because when trying to run
automation (i.e. automated testing) on our application, we can't get
query execution time down to an acceptable level with anything less than
~48GB memory available in the host.

Thanks for the suggestion though. I was considering this as an
alternative, but every experience I've had of running multiple (let's
say, more than 2 or 3) instances of the same application/daemon on the
same host has inevitably led to all sorts of strange issues and
problems... I suppose it sounds like it's going to be the only option
though...

>
> Francisco Olarte.


--

Jason Antman | Systems Engineer | CMGdigital
jason.antman@coxinc.com | p: 678-645-4155


Re: Restore postgresql data directory to tablespace on new host? Or swap tablespaces?

From
"Antman, Jason (CMG-Atlanta)"
Date:
Replies inline below.

Thanks to everyone who's responded so far. The more I explain this, and
answer questions, the more I see how my original "brilliant" idea
(multiple DBs per postgres instance on one host, instead of 1:1:1
DB:postgres:host) is insane, without some specific support for it in
postgres. So... I suppose, barring some suggestion nobody's made yet,
the best we'll be able to do is try to run multiple postgres instances
on each host, and manage the whole "service postgresql-9.0-24 stop"
craziness that comes with that...

Is anyone aware of documentation or best practices for running multiple
postgres instances on the same host, and how to maximize resource
sharing between them?

Thanks,
Jason

On 02/15/2014 04:26 PM, Adrian Klaver wrote:
> On 02/15/2014 10:31 AM, Antman, Jason (CMG-Atlanta) wrote:
>> Well thanks for someone at least sending a reply, though I suppose I
>> should have asked "how do I do this", or "what are the major hurdles to
>> doing this", as it obviously has to be *possible* given unlimited
>> knowledge, resources and time.
>>
>> Perhaps I should frame the question differently:
>>
>> If you had a single ~1TB database, and needed to be able to give fresh
>> data copies to dev/test environments (which are usually largely idle)
>> either on demand or daily, how would you do it? The only other thing
>> that comes to mind is separate postgres instances (running multiple
>> postgres instances per server?), one per database, for every
>> environment. Which means that if 80% of the environments are idle at a
>> given time, I'm effectively wasting 80% of the memory that I have
>> allocated to shared buffers, etc. and I actually need 4x the resources
>> I'm using? Unless postgres supports balooning of memory?
>
> <<Thinking out loud>>
>
> Your requirements:
>
> If I am following correctly you want a single universal data set that
> is accessible by multiple databases at will. There will be 100-150
> different databases to which presumably different things are being
> done. With, ideally, the databases having different names. Also it
> would be helpful if the data could be refreshed without stopping the
> cluster.
Yup, that's the gist of it (what we do now for ~50 copies, each on their
own virtual machine).
>
> The process:
>
> Start at known point, the state of the production server at point in
> time.
>
> Apply that state as the starting point for 100-150 databases.
>
> Do things to those 100-150 databases that cause them to deviate from
> the starting point and each other.
>
> Periodically reset some portion of the databases to a new starting
> point based on a different state of the production database.
Yup. Exactly.
>
> The issue:
>
> The killer would seem to be the global(cluster)/local(database)
> problem. The cluster has the database at one state and then you try
> impose a database state from another cluster on it. Even given your
> stipulation-.."to be *possible* given unlimited knowledge, resources
> and time.", I would say not in a time frame that is going to help you
> in the practical future.
Yeah, I guess. it's sounding like, aside from getting way down into the
internals of postgres and spending months coding a really bad hack that
won't work half the time, there's no sane way to stop the cluster (or
not?) and force it to throw away everything it knows about a database,
or replace that "knowledge" with fixed information... which would be
what I'd need to do, I guess.
>
> Solution or not;
>
> Not seeing how you can do it without using some variation of what you
> do now. Part of the problem in trying to come up with a solution is
> not knowing what is being done to the test/dev databases.
>
> Is the full dataset a requirement for testing or would a subset do?
Answered in my last post... effectively, yes, because the application
ORM is so broken that nobody can get a valid-but-reduced dataset. The
last attempt at deleting old data *through* the application's ORM ended
up shrinking the DB size on disk (after vacuum) by under 50% in... I
think 2 weeks of running around the clock.
> Are there 100-150 users/tests each needing a database or could
> databases be shared?
That was based on 50 users each needing a maximum of 2-3 databases per
day. No sharing, as it invalidates any testing they're doing.
>
> Is the 80% idle figure you mention manageable?
> In other words do the tests run whenever, so the instances have to
> always be available or can they be spun up on demand?
Well... define "on demand". Currently they're always available, except
when someone runs the command to refresh one, which currently takes
approx. 120 seconds. If we could figure out how to, perhaps, snapshot
virtual machines with the OS already booted, maybe that would work. But
given the current expectation (~2 minutes start to finish for a refresh)
I'm not sure we could reasonably spin them up on demand. Moreover, if we
were spinning up a VM on demand, we'd end up with the same situation
we're in now - every dev comes in in the morning and spins up their VM.
>
>
>>
>> Thanks,
>> Jason
>>
>> On 02/15/2014 01:20 PM, Tom Lane wrote:
>>> "Antman, Jason (CMG-Atlanta)" <Jason.Antman@coxinc.com> writes:
>>>> Perhaps there's a postgres internals expert around, someone
>>>> intimitely familiar with pg_xlog/pg_clog/pg_control, who can
>>>> comment on whether it's possible to take the on-disk files from a
>>>> single database in a single tablespace, and make them usable by a
>>>> different postgres server, running multiple databases?
>>> It is not.  There's no need for detailed discussion.
>>>
>>>             regards, tom lane
>>
>>
>
>


--

Jason Antman | Systems Engineer | CMGdigital
jason.antman@coxinc.com | p: 678-645-4155

Re: Restore postgresql data directory to tablespace on new host? Or swap tablespaces?

From
Karsten Hilbert
Date:
On Sat, Feb 15, 2014 at 10:17:05PM +0000, Antman, Jason (CMG-Atlanta) wrote:

> [...] I see how my original "brilliant" idea
> (multiple DBs per postgres instance on one host, [...]) is insane,
> without some specific support for it in  postgres.

"multiple DBs per PostgreSQL instance on one host" is quite
a usual setup unless I am misinterpreting what you say.

> I'm not sure we could reasonably spin them up on demand. Moreover, if we
> were spinning up a VM on demand, we'd end up with the same situation
> we're in now - every dev comes in in the morning and spins up their VM.

Would a cron-ed serialized-into-batches spinup
help with that ?

Karsten
--
GPG key ID E4071346 @ gpg-keyserver.de
E167 67FD A291 2BEA 73BD  4537 78B9 A9F9 E407 1346


Re: Restore postgresql data directory to tablespace on new host? Or swap tablespaces?

From
"Antman, Jason (CMG-Atlanta)"
Date:
On 02/15/2014 05:27 PM, Karsten Hilbert wrote:
> On Sat, Feb 15, 2014 at 10:17:05PM +0000, Antman, Jason (CMG-Atlanta) wrote:
>
>> [...] I see how my original "brilliant" idea
>> (multiple DBs per postgres instance on one host, [...]) is insane,
>> without some specific support for it in  postgres.
> "multiple DBs per PostgreSQL instance on one host" is quite
> a usual setup unless I am misinterpreting what you say.
The context there is "multiple DBs" where each DB is so big that the
only way we can deal with it is filesystem snapshots (and using NetApp's
flexclone technology, which only stores *changed* blocks for clones, not
the whole thing), so we can't restore a pg_dump... we have to clone the
actual files on disk.
>
>> I'm not sure we could reasonably spin them up on demand. Moreover, if we
>> were spinning up a VM on demand, we'd end up with the same situation
>> we're in now - every dev comes in in the morning and spins up their VM.
> Would a cron-ed serialized-into-batches spinup
> help with that ?
Yeah, but then we're back to square one with the resource utilization.
The idea of using one postgres instance per physical server, and running
multiple independent clones of the same database on it, is that we could
allocate a large amount of memory to shared cache/buffers, and simply
allow the in-use-at-this-instant databases to utilize it, and the idle
ones to expire out of cache. I.e. we have hardware with 192G of RAM. If
each database is only queried, say, for 10 seconds out of each 5 minute
interval, how do we maximize resource utilization / squeeze as many DBs
onto as few pieces of hardware as possible. If we spin up VMs every
morning, we're back to where we are now, with one postgres sever per VM,
and a large amount of physical memory being used up by virtualization
overhead (guest OS) and idle postgres processes.

>
> Karsten
-Jason

--

Jason Antman | Systems Engineer | CMGdigital
jason.antman@coxinc.com | p: 678-645-4155


Re: Restore postgresql data directory to tablespace on new host? Or swap tablespaces?

From
"Antman, Jason (CMG-Atlanta)"
Date:
On 02/15/2014 04:55 PM, Antman, Jason (CMG-Atlanta) wrote:
> On 02/15/2014 02:00 PM, Francisco Olarte wrote:
>>
>> If I NEEDED to be able to provide 100-150 snapshots to test/dev
>> environments 20% of which maybe active, I'll setup a cluster, buy
>> somewhere above a quarter terabyte RAM and some big snapshot
>> appliances. They are not that expensive, and someone NEEDING that big
>> dev/test systems must be on a humoungous project, where the cost of
>> throwing hardware at the problem would be dwarfed by any small delay
>> trying to set that up with minimal resources. A postgres instance
>> should happily run in half a gig, using proper snapshots would let you
>> share cache among them, so you could put quite a lot of them in one of
>> these 384G machines floating around, even on a 192G one, throw a
>> snapshotting filesystem or appliance on the mix and is not that
>> complex.
> So you're suggesting running multiple instances of postgres in the same
> operating system, and they'll be able to share cache, instead of trying
> to get multiple DBs in the same instance? Is there any accepted method
> of managing N postgres instances on one host? Any tools or documentation
> for that, or best practices? Seems scary to me, but I suppose it's the
> best option we have...
>
> By "A postgres instance should happily run in half a gig" I assume
> you're not counting cache/buffers, etc.? Because when trying to run
> automation (i.e. automated testing) on our application, we can't get
> query execution time down to an acceptable level with anything less than
> ~48GB memory available in the host.
>
> Thanks for the suggestion though. I was considering this as an
> alternative, but every experience I've had of running multiple (let's
> say, more than 2 or 3) instances of the same application/daemon on the
> same host has inevitably led to all sorts of strange issues and
> problems... I suppose it sounds like it's going to be the only option
> though...
>
>> Francisco Olarte.
>

I think I jumped on this without really understanding what you were
saying, or the implications of it. If I run N postgres server instances
on the same physical host, I can do away with the overhead of running
each of them in their own virtualized operating system, but they can't
really share resources other than *OS* cache, right?

My current postgres instances for testing have 16GB shared_buffers (and
5MB work_mem, 24GB effective_cache_size). So if, hypothetically (to give
a mathematically simple example), I have a host machine with 100GB RAM,
I can't run 10 postgres instances with those settings, right? I'd still
need to provide for the memory needs of each postgres server/instance
separately? In which case, from an ease of management/sanity
perspective, it would probably be best to try running each one in
containers (LXC) or some sort of ultra-low-overhead virtualization,
rather than ending up with 10 separate instances of postgres running
directly in the same OS?

-Jason


On 2/15/2014 4:30 PM, Antman, Jason (CMG-Atlanta) wrote:
> My current postgres instances for testing have 16GB shared_buffers (and
> 5MB work_mem, 24GB effective_cache_size). So if, hypothetically (to give
> a mathematically simple example), I have a host machine with 100GB RAM,
> I can't run 10 postgres instances with those settings, right? I'd still
> need to provide for the memory needs of each postgres server/instance
> separately?

does 16GB shared_buffers really give that much better performance than 2
or 4 GB for your application, under a development workload?

effective_cache_size is not an allocation, its just an estimate of how
much system cache is likely to contain recently accessed postgres data,
the planner uses it guess the cost of 'disk' accesses.

--
john r pierce                                      37N 122W
somewhere on the middle of the left coast



Re: Restore postgresql data directory to tablespace on new host? Or swap tablespaces?

From
Francisco Olarte
Date:
Hi Jason:

On Sat, Feb 15, 2014 at 10:55 PM, Antman, Jason (CMG-Atlanta)
<Jason.Antman@coxinc.com> wrote:
> The short answer is... due to too much technical debt, and some perhaps
> bad decisions made in the past... yeah. We've dug ourselves into this
> hole, and there's no feasible way out.

The more I read about your problem, the more I think you've nailed it
in that phrase.

I'll just comment somethings in case you find them useful, but it
seems joining the above with the lack of appropiate resources you will
have a bad time. You seem to be in a big shop, terabyte database, 50
test environments, you must have a lot of developers. In your case I
would start by estimating how much developer time you could save by
buying hardware.

>  Currently we have ~50 dev/test
> environments, each of which has a clone of the full production database
> (on a NetApp, using flexclones, so it's *much* smaller in terms of
> actual disk usage).

I'm not familiar with netapp, but if your flexclones are exported as
different filesystems you have a problem with that. Even if say, 100
clones of the database use only 5 Tb when you export it the instances
see them at 100 Tb.

> Each of them is backed up its own postgres instance
> running in a dedicated VM.

Some problem here, each VM needs its own cache. If I would need to
spin a lot of databases on limited hardware what I would try is to use
a single host with a snapshoting filesystem, ie ZFS or BTRFS or
whatever running a lot of instances. This way you share the code mem
between all the instances and you have a single OS instance, which can
easily save hundreds or megs per machine. But, what is more important,
you cannot do anything for shared buffers, work mem et al, they are
per-instance, but postgres also uses an estimate of the cache. If your
instances run on the same machine, with say 32Gb cache and the OS in
this box runs the snapshots it can use cached blocks for one instance
on another one, this is not possible if you are net-mounting it. I do
not know how much you would gain, as it woill be heavily dependent on
your concrete access patterns, but it's gonna be faster. BTW, I
suppose you've already optimized the access stuff for tests, like
running without fsync, minimal logging, etc in dev environements.

> Data refreshes are done on-demand by stopping
> the postgres instance, unmounting and deleting the volume backing it,
> making a new clone of the daily snapshot, mounting it, and bringing
> postgres back up.

This would be the same in which I told you, just on a different place.
Postgres doesn't meen wether it has a full VM or just a data directory
and a port.

> But we don't have the money (or, more importantly,
> datacenter space) to dedicate a piece of hardware to each of these. So
> most dev environments can only handle ~1 person using the application at
> a time, due to trying to run a complex ORM (Django) against a ~1T
> database on a host with < 24G RAM.

Every time you quote one of this things it seems more and more like
you are in big place and you have a really weird set of requisites.
AFAIK Django is not that big, the problem may be more with the kind of
things you are trying to do with them. And I do not quite understand
what are you calling 'a testing environment'. With only what I've
read, if the netapp thingy you mention is fast enough to serve the
snapshots, I'll normally think, ram is cheap, why not put 32Gb in each
developer machine and run everything there? But I suppose you have lot
of other constraints.

...
> So, we really need ~50 copies that can be refreshed at arbitrary
> intervals. Since I've already determined that's absolutely impossible
> without stopping postgres, I calculated 100-150 assuming we do bulk
> refreshes at night, and each developer is allocated 2-3 possible
> refreshes in a given 24-hour period.

That left me still more puzzled.

> Since we've allowed the database to grow without using Django's
> facilities to split largely unrelated objects into different databases
> and handle any JOINs in the application, and we've gradually let the
> database diverge from the models actually in the ORM, every attempt at
> crafting a DB with a restricted set of recent data has failed. And yes,
> unfortunately, individual developers have had their own private database
> instance for long enough that migrating to a shared DB approach has been
> discarded as an option.

As you say in your fist paragrapah, it seems you have dug a really deep hole.

From what I've read so far, a lot more knowledge about your problem is
needed to dessign a solution, and I'm not gonna try to do it. The only
thing I can do is tell you what I've said above, virtualization is
nice, but running several instances in the same machine ( be it
virtual or real ) will decrease your requisites. NetApps are nice, but
they virtualize the disks and hide potential sharings from the OS
under the db server, so moving the snapshots nearer will decrease them
too.

.....
> Unfortunately, no, we're on a project that's far from having an
> unlimited budget.

That I supposed. The things is it seems that, as you stated, you may
already be over budget. The thing about the machines is that given the
numbers you quote I have a mental picture of your project. From that
mental picture, for me, the cheapest way seems to be throwing
hardware, as it seems you are trading some k EURO/k$/whatever for lost
productivity on a whole lot of developers, and, time being money
specially in this cases, it seems cheaper. Although, as I said, I do
not know the restrictions.

> So you're suggesting running multiple instances of postgres in the same
> operating system, and they'll be able to share cache, instead of trying
> to get multiple DBs in the same instance? Is there any accepted method
> of managing N postgres instances on one host? Any tools or documentation
> for that, or best practices? Seems scary to me, but I suppose it's the
> best option we have...

You are scared of N servers? Someone who was looking to copy the
tablespaces? Do not worry, that is easy. If you want tools, Debian and
ubuntu installations install with the ability to run multiple server
instances, although that may not be adequate for you, you could grab
some ideas from there. We have done this kind of thing for version
upgrades ( running two versions in paralell, using pgbouncer to be
able to migrate databases one by one, and it was easy. Basically, all
a postgres instance uses is a directory for the data and a port
number. If you configure a master volume with has every data inside (
even the conf files ), you can then spin up an instance easily by
mounting COW copy of it elsewhere, changing the port in the conf and
firing a postmaster. IIRC you do not to even edit the conf and can
pass the port at start if it is not in the conf file. You may have a
problem if you are using tablespaces in the snapshot, this would
probably need a little fixing of links before starting the instance.


> By "A postgres instance should happily run in half a gig" I assume
> you're not counting cache/buffers, etc.? Because when trying to run
> automation (i.e. automated testing) on our application, we can't get
> query execution time down to an acceptable level with anything less than
> ~48GB memory available in the host.

There it comes again. Big problem, little resources. You use more RAM
for automation testing than I use to run production for our whole shop
( counting every process, not just the DB ). Postgres will run
happily, but slowly in your case. If you need to run automation on
every one of your 50 copies, you have the minimum requirement, 48Gb.
With VM I doubt you could squeeze it in less than 2400Gb, although
memory deduplication may help you. But if you run 50 copies of
postgres in the same OS and the OS knows the datadirs are COW, so it
automatically shares caches, you may be able to do better. As always
it depends on what your 48G are used for, if they are for work mem, it
wont help you. If they are for cache it might. If they are for shared
buffers, you may investigate some tunning. Anyway, the numbers you
quote everytime you put one always remember me of the classical film
words 'He is dead, but still does not know it', sorry, but this is my
impression.

> Thanks for the suggestion though. I was considering this as an
> alternative, but every experience I've had of running multiple (let's
> say, more than 2 or 3) instances of the same application/daemon on the
> same host has inevitably led to all sorts of strange issues and
> problems... I suppose it sounds like it's going to be the only option
> though...

Running multiple copies of the same program requires a little
planning, but is a great resource saver. You only have one OS, one
cache, one cpu / disk scheduler running ( and one init daemon, one
cron daemon, etc... ). It's a kind of lightweight virtualization. And
postgres is normally very well behaved in this scenarios.

Francisco Olarte.


Re: Restore postgresql data directory to tablespace on new host? Or swap tablespaces?

From
Francisco Olarte
Date:
Hi Jason:

On Sat, Feb 15, 2014 at 11:17 PM, Antman, Jason (CMG-Atlanta)
<Jason.Antman@coxinc.com> wrote:
> the best we'll be able to do is try to run multiple postgres instances
> on each host, and manage the whole "service postgresql-9.0-24 stop"
> craziness that comes with that...

Just a sugestion, I would not try to integrate them with the normal
service infrastructure. I'll shoot more for confining them under a
single user account, probably the postgres one, and have a nice tree
of dirs under it, with scripts going more along the way 'testpg 5432
start/stop/copy/create'

Francisco Olarte.


Re: Restore postgresql data directory to tablespace on new host? Or swap tablespaces?

From
Francisco Olarte
Date:
Hi:

On Sun, Feb 16, 2014 at 1:02 AM, Antman, Jason (CMG-Atlanta)
<Jason.Antman@coxinc.com> wrote:

> ones to expire out of cache. I.e. we have hardware with 192G of RAM. If
> each database is only queried, say, for 10 seconds out of each 5 minute
> interval, how do we maximize resource utilization / squeeze as many DBs
> onto as few pieces of hardware as possible. If we spin up VMs every
> morning, we're back to where we are now, with one postgres sever per VM,
> and a large amount of physical memory being used up by virtualization
> overhead (guest OS) and idle postgres processes.

If you run many instances on the same machine, and make sure this 10
seconds are connection time ( beware of connection pools ) memory
reuse is between processes, not VMs, which OS are currently very good
at. You should try to minimize the shared-buffers used, as they are
tied per-instance, but it will help. I say this because my devs have
the nasty having of running their single user test environments with
heavy multiuser setups for the connection pool ( something like
minimum 8 connections, leave up to 10 free if unused, which, given
they only use 1 on tests, leads to 7 permanently unused backends, plus
one scarcely used but always resident ).

Francisco Olarte.


Re: Restore postgresql data directory to tablespace on new host? Or swap tablespaces?

From
Francisco Olarte
Date:
Hi Jason:

On Sun, Feb 16, 2014 at 1:30 AM, Antman, Jason (CMG-Atlanta)
<Jason.Antman@coxinc.com> wrote:
> I think I jumped on this without really understanding what you were
> saying, or the implications of it. If I run N postgres server instances
> on the same physical host, I can do away with the overhead of running
> each of them in their own virtualized operating system, but they can't
> really share resources other than *OS* cache, right?

Physical or virtual host, is the same.

They are going to share much more. They will share schedulers,
filesystems and a lost of things. Also, I do not know your connection
patterns, but if your testters disconnect promptly you will share used
memory for work mem, among other things.

> My current postgres instances for testing have 16GB shared_buffers (and
> 5MB work_mem, 24GB effective_cache_size). So if, hypothetically (to give
> a mathematically simple example), I have a host machine with 100GB RAM,
> I can't run 10 postgres instances with those settings, right?

No. You cannot properly run  10 instances with 16Gb shared buffers
properly with less than 160 Gb of RAM ( leave aside cache ) unless you
count on lot of thems being passive and swapped out. What I would do
in your case is to really tune trying to trade shared buffers with
effective cache, but say this is correct. BTW, this settings will need
a 48G machine easily ( 16G+24 = 40G + work_mem*N + OS overhead, as
always your numbers continue to puzzle me ). The point is using a
netapp which hides the commonaitly in disks and going for full os
virtualization you would need 40G per copy, which may be slightly
reduced if your vitualization techniques are really good and do
ballooning or deduplicating, but deduplicating at this scale is going
to be hard, and balloning is difficult if you don't tune a lot of the
images ( to free ballon the disk cache ). OTOH if you put all this as
10 copies in a single machine you do not need balloning, as all
instances reuse the work mem, not only among instances on the same
image. Also, if the COW snapshots are done by the OS on this machine,
instead of using 240G for cache you may be able to use only, say, 120
but tell the instance the effective cache size is 24 if they share
blocks, as the OS knows which blocks are shared amount snapshots and
only keeps one copy of them. If you can tune the machine for 8G
shared, 32Gb effective you could probably squeeze more.

What I mean is, you will always be able to squeeze more databases
using these than with full virtualization solutions. On a normal
setup, with 50 developers, with a normal database, I'll normally say
you couls squeze 2-3 more instances, but your numbers are really
difficult to understand, you've given the more strange sets of
parameters I've ever seen. It seems your system has had an organic
growth for a really long time and has gone into a very problematic
corner.

I forgot before, but if your test instances are short lived, depending
on the access pattern you use you may want to turn off autovacuum in
all of them ( and just do not use it if they are short lived and not
too much written or fire manual ones periodically, this way you can do
only one at a time ).

> I'd still
> need to provide for the memory needs of each postgres server/instance
> separately?

This I do not understand. You'll need to provide memory, and just experiment.

> In which case, from an ease of management/sanity
> perspective, it would probably be best to try running each one in
> containers (LXC) or some sort of ultra-low-overhead virtualization,
> rather than ending up with 10 separate instances of postgres running
> directly in the same OS?

IMO it will be much more easier, from a m/s persp. , to run them
WITHOUT any kind of vitualization solution. Remember, you already have
a virtualizer, it is called OS and, although limited, is very good at
what it does. I wouldn't even bother with chroot unless neccessary, in
my experience it just complicates things. Postgres is very well
behaved, and does not need the isolations which virtualization
solutions provide. Remember an instance is just a directory plus a
port number, it does not need more.

Francisco Olarte.