Re: [HACKERS] Drastic performance loss in assert-enabled build in HEAD

2013-04-05 Thread Nicolas Barbier
2013/4/5 Noah Misch n...@leadboat.com:

 On Thu, Apr 04, 2013 at 12:28:01PM +0200, Nicolas Barbier wrote:

 +1. Having unlogged matviews without having incremental updates yet,
 isn't super useful anyway.

 I would have surmised the opposite: since an unlogged MV requires a full
 refresh at unpredictable moments, logged MVs will be preferred where a refresh
 is prohibitively expensive.

That sounds like a good reason to choose your matview to be logged indeed.

I.e., very expensive to rebuild → choose logged

The opposite is also true: If your matview is not so expensive to
rebuild, why would it matter that much if it is logged? (Rebuilding
would be a tad slower, but it is not that slow to start with, so who
cares?)

I.e., not so expensive to rebuild → logged or unlogged are fine

This would mean “always choose logged,” except for the restricted case
of “incremental updates of a matview that is not so expensive to
rebuild” that I describe next:

 Why might unlogged-MV applications desire incremental updates more acutely
 than logged-MV applications?

My reasoning was more like: If you have incremental updates, there
will probably be some overhead linked to executing any transaction
that updates the base tables, namely for storing the changesets
somewhere. I imagined it could at least be this storing of changesets
that one would want to be unlogged, lest it slowing down the commit of
most transactions that don’t even touch the matview.

(Note that losing any changeset is the same as losing the contents of
the whole matview in the “always guaranteed to be 100% up-to-date when
read” case.)

Of course, because of the previous reasoning, we should always make a
matview logged if it is very expensive to rebuild. That leaves the
case of a not-so-expensive matview: It is smart to make it unlogged
when the changesets are stored in a way similar to what I just
described.

Anyway, I conclude that (especially as we don’t have incremental
updates yet), unlogged matviews are, as things stand now, not very
useful.


As a sidenote, I see two ways to avoid storing changesets as part of a
commit that changes the base tables. Choosing any of those would
invalidate my previous logic, and even more diminish the need for
unlogged matviews:

(1) WAL is used as the source for the changesets; Andres’ logical
replication work comes to mind. Probably mostly useful for the “always
guaranteed to be 100% up-to-date when read” case.

(2) The base tables are scanned and the xmin/xmax values are used to
determine what changed since last time. This probably requires keeping
VACUUM from removing rows that are still needed to determine how to
change any matviews that depend on that base table. Probably mostly
useful for the case where bulk-incremental updates are performed only
sporadically, and where the base tables are not so big that they
cannot usefully be scanned in full.

Nicolas

--
A. Because it breaks the logical sequence of discussion.
Q. Why is top posting bad?


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] Drastic performance loss in assert-enabled build in HEAD

2013-04-05 Thread Kevin Grittner
Noah Misch n...@leadboat.com wrote:
 On Thu, Apr 04, 2013 at 12:28:01PM +0200, Nicolas Barbier wrote:

 +1. Having unlogged matviews without having incremental updates
 yet, isn't super useful anyway.

 I would have surmised the opposite

Hmm.  I was thinking about the fact that a full refresh can be
unlogged anyway, but that's only true if you're not using WAL for
replication.  If you need a matview on the master but not on the
replica(s), then there is still benefit to declaring it to be
unlogged in the absence of incremental maintenance.

--
Kevin Grittner
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] Drastic performance loss in assert-enabled build in HEAD

2013-04-05 Thread Noah Misch
On Fri, Apr 05, 2013 at 11:17:30AM +0200, Nicolas Barbier wrote:
 2013/4/5 Noah Misch n...@leadboat.com:
  On Thu, Apr 04, 2013 at 12:28:01PM +0200, Nicolas Barbier wrote:
  +1. Having unlogged matviews without having incremental updates yet,
  isn't super useful anyway.
 
  I would have surmised the opposite: since an unlogged MV requires a full
  refresh at unpredictable moments, logged MVs will be preferred where a 
  refresh
  is prohibitively expensive.
 
 That sounds like a good reason to choose your matview to be logged indeed.
 
 I.e., very expensive to rebuild → choose logged
 
 The opposite is also true: If your matview is not so expensive to
 rebuild, why would it matter that much if it is logged? (Rebuilding
 would be a tad slower, but it is not that slow to start with, so who
 cares?)
 
 I.e., not so expensive to rebuild → logged or unlogged are fine
 
 This would mean “always choose logged,” except for the restricted case
 of “incremental updates of a matview that is not so expensive to
 rebuild” that I describe next:

Cheap is good, but cheaper is better.  Since a refresh locks out readers, mild
wins do count.

  Why might unlogged-MV applications desire incremental updates more acutely
  than logged-MV applications?
 
 My reasoning was more like: If you have incremental updates, there
 will probably be some overhead linked to executing any transaction
 that updates the base tables, namely for storing the changesets
 somewhere. I imagined it could at least be this storing of changesets
 that one would want to be unlogged, lest it slowing down the commit of
 most transactions that don’t even touch the matview.

That's a good point.  However, the same holds when refreshing a logged MV,
especially at wal_level  minimal.  The refresh exerts pressure on the WAL
stream, likely delaying other WAL-using transactions.

 As a sidenote, I see two ways to avoid storing changesets as part of a
 commit that changes the base tables. Choosing any of those would
 invalidate my previous logic, and even more diminish the need for
 unlogged matviews:

Regardless of the change storage method, actually applying incremental changes
to a logged MV will require WAL.  UNLOGGED MVs will stay relevant.

-- 
Noah Misch
EnterpriseDB http://www.enterprisedb.com


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] Drastic performance loss in assert-enabled build in HEAD

2013-04-04 Thread Nicolas Barbier
2013/4/3 Tom Lane t...@sss.pgh.pa.us:

 Kevin Grittner kgri...@ymail.com writes:

 To be honest, I don't think I've personally seen a single use case
 for matviews where they could be used if you couldn't count on an
 error if attempting to use them without the contents reflecting a
 materialization of the associated query at *some* point in time.

 Well, if we remove the WITH NO DATA clause from CREATE MATERIALIZED
 VIEW, that minimum requirement is satisfied no?

An argument against that is that computing the contents may be very expensive.

 Granting that throwing an error is actually of some use to some people,
 I would not think that people would want to turn it on via a command
 that throws away the existing view contents altogether, nor turn it off
 with a full-throated REFRESH.  There are going to need to be ways to
 incrementally update matviews, and ways to disable/enable access that
 are not tied to a complete rebuild, not to mention being based on
 user-determined rather than hard-wired criteria for what's too stale.
 So I don't think this is a useful base to build on.

Am I correct when I think that you are saying here, that the “zero
pages == unscannable” logic is not very future-proof? In that case I
concur, and I also think that this knowledge leaks in way too many
other places (the VACUUM bug mentioned by Kevin is a good example).

 If you feel that scannability disable is an absolute must for version 0,
 let's invent a matview reloption or some such to implement it and let
 users turn it on and off as they wish.  That seems a lot more likely
 to still be useful two years from now.

(In the context of making an unlogged matview unscannable after a crash:)

Is it imaginable that such a reloption could (in a future
implementation) be changed during or right after crash recovery? For
example, by storing the set of “truncated by crash recovery” relations
in a shared catalog table, which is then inspected when connecting to
a database to continue the truncation (in the case of a matview by
making it unscannable)?

 And if you're absolutely convinced that unlogged matviews mustn't work as I
 suggest, we can lose those from 9.3, too.

+1. Having unlogged matviews without having incremental updates yet,
isn’t super useful anyway.

 What I'd actually rather see us spending time on right now is making
 some provision for incremental updates, which I will boldly propose
 could be supported by user-written triggers on the underlying tables
 if we only diked out the prohibitions against INSERT/UPDATE/DELETE on
 matviews, and allowed them to operate on a matview's contents just like
 it was a table.  Now admittedly that would foreclose allowing matviews
 to be updatable in the updatable-view sense, but that's a feature I
 would readily give up if it meant users could build incremental update
 mechanisms this year and not two years down the road.

Please make the syntax for updating the “extent” (physical
representation) of a matview different from updating the view’s
logical contents. Examples:

(1) Require to use a special function to update the extent:

SELECT pg_mv_maintain('INSERT INTO example_matview ...');

While parsing the INSERT, the parser would know that it must interpret
“example_matview” as the matview’s extent; As currently the extent and
the view are the same, nothing must be done except for only allowing
the INSERT when it is parsed in the context of pg_mv_maintain, and
otherwise saying that matviews aren’t updatable yet (“NOTICE: did you
mean to update the extent? in that case use pg_mv_maintain”).

(2) Use a different schema (cf. TOAST) for the extent, e.g., view
“public.example_matview” vs. extent “pg_mv_extent.example_matview”. I
imagine future implementations to possibly require multiple extents
anyway, e.g., for storing the “not yet applied changesets” or other
intermediate things.

 Why exactly do you think that what I'm suggesting would cause a dump and
 reload to not regenerate the data?

Expensiveness: Matviews are used in cases where the data is expensive
to compute.

 We *need* to get rid of that aspect of things.  If you must have
 scannability state in version 0, okay, but it has to be a catalog property
 not this.

+1

Nicolas

--
A. Because it breaks the logical sequence of discussion.
Q. Why is top posting bad?


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] Drastic performance loss in assert-enabled build in HEAD

2013-04-04 Thread Kevin Grittner
Early versions of the matview patch had a relisvalid flag in
pg_class to determine whether the relation was scannable.  The name
was chosen based on a similarity to the purpose of indisvalid,
although the proliferation of new bools for related issues left me
wondering if a char would be a better idea.  Based on on-list
reviews I removed that in favor of basing the state on a
zero-length heap file, in an attempt to work better with unlogged
matviews.  I can easily look back through my development branch to
find the commits which made this change and revert them if this
approach is preferred.

I realize this would need to be Real Soon Now, but before reverting
to the earlier code I want to allow a *little* more time for
opinions.

Responses to particular points below.


Tom Lane t...@sss.pgh.pa.us wrote:

 Granting that throwing an error is actually of some use to some people,
 I would not think that people would want to turn it on via a command
 that throws away the existing view contents altogether, nor turn it off
 with a full-throated REFRESH.

There is no doubt that in future versions we will want to be able
to disallow scans based on other criteria than just whether the
data is valid as of *some* point in time.  I can't imagine a
circumstance under which we would want to allow scans if it
doesn't.  So, at least for this release and as a default for future
releases, I think it makes sense that a matview last CREATEd or
REFRESHed WITH NO DATA should not be scannable.  Additional knobs
for the users to control this can and should be added in future
releases.

 There are going to need to be ways to incrementally update
 matviews, and ways to disable/enable access that are not tied to
 a complete rebuild, not to mention being based on user-determined
 rather than hard-wired criteria for what's too stale.

Absolutely.  So far as I know, nobody has ever suggested or
expected otherwise.  This paper provides a useful summary of
techniques for incremental updates, with references to more
detailed papers:

http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.40.2254rep=rep1type=pdf

I expect to be working on implementing the most obvious special
cases and a catch-all general solution for 9.4.  Efficient
incremental update seems to depend on the ability to have at least
one new hidden system column, so once we get to a good point for
discussing 9.4 issues, I'll be on about that.

 If you feel that scannability disable is an absolute must for version 0,
 let's invent a matview reloption or some such to implement it and let
 users turn it on and off as they wish.  That seems a lot more likely
 to still be useful two years from now.

What about the idea of a relisvalid bool or some char column in
pg_class?

 And if you're absolutely convinced that unlogged matviews mustn't
 work as I suggest, we can lose those from 9.3, too.

I was loath to do that, but as Nicolas points out, they really
aren't that interesting without incremental update.  Perhaps it is
better to drop those until next release and have a more
sophisticated way to deal with invalidation of those -- or as you
suggested, just punt them to be empty.  (I would hate to do that,
but it might be the lesser of evils.)

 What I'd actually rather see us spending time on right now is making
 some provision for incremental updates, which I will boldly propose
 could be supported by user-written triggers on the underlying tables
 if we only diked out the prohibitions against INSERT/UPDATE/DELETE on
 matviews, and allowed them to operate on a matview's contents just like
 it was a table.  Now admittedly that would foreclose allowing matviews
 to be updatable in the updatable-view sense, but that's a feature I
 would readily give up if it meant users could build incremental update
 mechanisms this year and not two years down the road.

I think that should be the last resort, after we have a more
automated declarative way of maintaining the majority of cases.
Since I don't see too much there where using that technique with
matviews would give you more than you could do right now with
tables and triggers, hand-coding the incremental maintenance is
very low on my list of priorities.  In any event, I don't want to
rush into any such thing this close to release; that seems to me to
be clearly 9.4 material.

 Individual judges have a dashboard showing such things as the
 number of court cases which have gone beyond certain thresholds
 without action

 If you need 100% accuracy, which is what this scenario appears to be
 demanding, matviews are not for you (yet).  The existing implementation
 certainly is nowhere near satisfying this scenario.

No, we're talking about timelines measured in weeks or months.  A
nightly update is acceptable, although there are occasional gripes
by a judge that they would like to see the results of cleaning up
such cases sooner than the next morning.  An hour latency would
probably make them happy.  If async incremental update could give a

Re: [HACKERS] Drastic performance loss in assert-enabled build in HEAD

2013-04-04 Thread Noah Misch
On Thu, Apr 04, 2013 at 12:28:01PM +0200, Nicolas Barbier wrote:
 2013/4/3 Tom Lane t...@sss.pgh.pa.us:
  And if you're absolutely convinced that unlogged matviews mustn't work as I
  suggest, we can lose those from 9.3, too.
 
 +1. Having unlogged matviews without having incremental updates yet,
 isn't super useful anyway.

I would have surmised the opposite: since an unlogged MV requires a full
refresh at unpredictable moments, logged MVs will be preferred where a refresh
is prohibitively expensive.  Why might unlogged-MV applications desire
incremental updates more acutely than logged-MV applications?

-- 
Noah Misch
EnterpriseDB http://www.enterprisedb.com


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] Drastic performance loss in assert-enabled build in HEAD

2013-04-03 Thread Tom Lane
[ sorry for being slow to respond, things are crazy this week ]

Kevin Grittner kgri...@ymail.com writes:
 Tom Lane t...@sss.pgh.pa.us wrote:
 Anyway, the immediate takeaway is that this represents a horribly
 expensive way for pg_dump to find out which matviews aren't
 scannable.  The cheap way for it to find out would be if we had a
 boolean flag for that in pg_class.  Would you review the bidding
 as to why things were done the way they are?  Because in general,
 having to ask the kernel something is going to suck in any case,
 so basing it on the size of the disk file doesn't seem to me to
 be basically a good thing.

 The early versions of the patch had a boolean in pg_class to track
 this, but I got complaints from Robert and Noah (and possibly
 others?) that this got too ugly in combination with the support for
 unlogged matviews, and they suggested the current approach.

Meh.  I don't think that we should allow that corner case to drive the
design like this.  I would *far* rather not have unlogged matviews at
all than this boondoggle.  I'm not even convinced that the existing
semantics are desirable: who's to say that having an unlogged matview
revert to empty on crash renders it invalid?  If it's a summary of
underlying unlogged tables, then that's actually the right thing.
(If someone is desperately unhappy with such a behavior, why are they
insisting on it being unlogged, anyway?)

If we go with this implementation, I think we are going to be painting
ourselves into a corner that will be difficult or impossible to get out
of, because the scannability state of a matview is not just a matter of
catalog contents but of on-disk files.  That will make it difficult to
impossible for pg_upgrade to cope reasonably with any future rethinking
of scannability status.

In fact, I'm going to go further and say that I do not like the entire
concept of scannability, either as to design or implementation, and
I think we should just plain rip it out.  We can rethink that for 9.4
or later, but what we've got right now is a kluge, and I don't want
to find ourselves required to be bug-compatible with it forevermore.
To take just the most salient point: assuming that we've somehow
determined that some matview is too out-of-date to be usable, why is the
appropriate response to that to cause queries on it to fail altogether?
That seems like about the least useful feature that could be devised.
Why not, say, have queries fall back to expanding the view definition as
though it were a regular view?

I think matviews without any scannability control are already a pretty
useful feature, and one I'd not be ashamed to ship just like that for
9.3.  But the scannability stuff is clearly going to need to be
revisited.  IMO, driving a stake in the ground at the exact spot that
this stake is placed is not a good plan.  If we simply remove that
aspect altogether for now, I think we'll have more room to maneuver in
future releases.

I apologize for not having griped about this earlier, but I've really
paid no attention to the matviews work up to now; there are only so
many cycles in a day.

regards, tom lane


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] Drastic performance loss in assert-enabled build in HEAD

2013-04-03 Thread Robert Haas
On Wed, Apr 3, 2013 at 10:59 AM, Tom Lane t...@sss.pgh.pa.us wrote:
 In fact, I'm going to go further and say that I do not like the entire
 concept of scannability, either as to design or implementation, and
 I think we should just plain rip it out.

This has been my feeling from the beginning, so I'm happy to support
this position.  I think the current version - where scan-ability is
tracked in just one way - is an improvement over the previous version
of the patch - where it was tracked in two different ways with a
confusing shuffle of information from one place to the other.  But my
favorite number of places to track it would be zero.

...Robert


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] Drastic performance loss in assert-enabled build in HEAD

2013-04-03 Thread Tom Lane
Robert Haas robertmh...@gmail.com writes:
 On Wed, Apr 3, 2013 at 10:59 AM, Tom Lane t...@sss.pgh.pa.us wrote:
 In fact, I'm going to go further and say that I do not like the entire
 concept of scannability, either as to design or implementation, and
 I think we should just plain rip it out.

 This has been my feeling from the beginning, so I'm happy to support
 this position.  I think the current version - where scan-ability is
 tracked in just one way - is an improvement over the previous version
 of the patch - where it was tracked in two different ways with a
 confusing shuffle of information from one place to the other.  But my
 favorite number of places to track it would be zero.

To be clear, I think we'll end up tracking some notion of scannability
eventually.  I just don't think the current notion is sufficiently baked
to want to promise to be upward-compatible with it in future.

regards, tom lane


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] Drastic performance loss in assert-enabled build in HEAD

2013-04-03 Thread Kevin Grittner
Tom Lane t...@sss.pgh.pa.us wrote:
 Robert Haas robertmh...@gmail.com writes:
 Tom Lane t...@sss.pgh.pa.us wrote:

 In fact, I'm going to go further and say that I do not like the
 entire concept of scannability, either as to design or
 implementation, and I think we should just plain rip it out.

 This has been my feeling from the beginning, so I'm happy to
 support this position.  I think the current version - where
 scan-ability is tracked in just one way - is an improvement over
 the previous version of the patch - where it was tracked in two
 different ways with a confusing shuffle of information from one
 place to the other. But my favorite number of places to track it
 would be zero.

 To be clear, I think we'll end up tracking some notion of
 scannability eventually.  I just don't think the current notion
 is sufficiently baked to want to promise to be upward-compatible
 with it in future.

To be honest, I don't think I've personally seen a single use case
for matviews where they could be used if you couldn't count on an
error if attempting to use them without the contents reflecting a
materialization of the associated query at *some* point in time.
There probably are such, but I think removing this entirely takes
the percentage of use cases covered by the implementation in this
release down from 10% to 2%.

Consider where the Wisconsin Courts use home-grown materialized
views currently:

(1) On the public web site for circuit court data, visibility is
based on supreme court rules and the advice of a committee
consisting of judges, representatives of the press, defense
attorneys, prosecuting attorneys, etc.  There are cases in the
database which, for one reason or another, should not show up on
the public web site.  On a weekly basis, where monitoring shows the
lowest usage, the table of cases which are too old to be shown
according to the rules thus determined is regenerated.  If there
was the possibility that a dump and load could fail to fill this,
and the queries would run without error, they could not move from
ad hoc matview techniques to the new feature without excessive
risk.

(2) Individual judges have a dashboard showing such things as the
number of court cases which have gone beyond certain thresholds
without action.  They can drill down to detail so that cases
which have slipped through the cracks can be scheduled for some
appropriate action.  Justice delayed... and all of that.  It
would be much better to get an error which would result in
information currently unavailable than to give the impression
that there are no such cases.

Since the main point of this patch is to get the basis for a more
complete matview feature into place while still supporting *some*
use cases, and a high priority needs to be place on not painting
ourselves into a corner, I agree we should rip this out if we think
it does so.  I have spent some time looking at what we will want to
add in future releases, and a more sophisticated concept of what is
fresh enough to allow use of the materialized data is certainly
on the list, and falling back to running the underlying query like
a normal view would be a reasonable option to be able to choose
in some cases; but I think that will *always* need to start with
information about whether data *has* been generated, and an empty
set has to be considered valid data if it has been.  If we come up
with a way to track that which isn't too fragile, I'm confident
that it will remain useful as the feature evolves. Making sure that
the heap has at least one page if data has been generated seems
like a not-entirely-unreasonable way to do that, although there
remains at least one vacuum bug to fix if we keep it, in addition
to Tom's concerns.  It has the advantage of playing nicely with
unlogged tables.  If this is not going to be what we use long term,
do we have a clue what is?

Personally, I think it would be sad to reduce the use cases for
which matviews in 9.3 can be used to those which can tolerate an
error-free reference to a matview for which data has not been
generated, but I'll rip out support for that distinction if that is
the consensus.

--
Kevin Grittner
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] Drastic performance loss in assert-enabled build in HEAD

2013-04-03 Thread Tom Lane
Kevin Grittner kgri...@ymail.com writes:
 Tom Lane t...@sss.pgh.pa.us wrote:
 In fact, I'm going to go further and say that I do not like the
 entire concept of scannability, either as to design or
 implementation, and I think we should just plain rip it out.

 To be honest, I don't think I've personally seen a single use case
 for matviews where they could be used if you couldn't count on an
 error if attempting to use them without the contents reflecting a
 materialization of the associated query at *some* point in time.

Well, if we remove the WITH NO DATA clause from CREATE MATERIALIZED
VIEW, that minimum requirement is satisfied no?

I wouldn't actually want to remove that option, because pg_dump will
need it to avoid circular-reference problems.  But if you simply don't
use it then you have the minimum guarantee.  And I do not see where
the current implementation is giving you any more guarantees.

What it *is* doing is setting a rather dubious behavioral precedent that
we will no doubt hear Robert complaining about when (not if) we decide
we don't want to be backward-compatible with it anymore.

Granting that throwing an error is actually of some use to some people,
I would not think that people would want to turn it on via a command
that throws away the existing view contents altogether, nor turn it off
with a full-throated REFRESH.  There are going to need to be ways to
incrementally update matviews, and ways to disable/enable access that
are not tied to a complete rebuild, not to mention being based on
user-determined rather than hard-wired criteria for what's too stale.
So I don't think this is a useful base to build on.

If you feel that scannability disable is an absolute must for version 0,
let's invent a matview reloption or some such to implement it and let
users turn it on and off as they wish.  That seems a lot more likely
to still be useful two years from now.  And if you're absolutely
convinced that unlogged matviews mustn't work as I suggest, we can
lose those from 9.3, too.

What I'd actually rather see us spending time on right now is making
some provision for incremental updates, which I will boldly propose
could be supported by user-written triggers on the underlying tables
if we only diked out the prohibitions against INSERT/UPDATE/DELETE on
matviews, and allowed them to operate on a matview's contents just like
it was a table.  Now admittedly that would foreclose allowing matviews
to be updatable in the updatable-view sense, but that's a feature I
would readily give up if it meant users could build incremental update
mechanisms this year and not two years down the road.

 (1) On the public web site for circuit court data, visibility is
 based on supreme court rules and the advice of a committee
 consisting of judges, representatives of the press, defense
 attorneys, prosecuting attorneys, etc.  There are cases in the
 database which, for one reason or another, should not show up on
 the public web site.  On a weekly basis, where monitoring shows the
 lowest usage, the table of cases which are too old to be shown
 according to the rules thus determined is regenerated.  If there
 was the possibility that a dump and load could fail to fill this,
 and the queries would run without error, they could not move from
 ad hoc matview techniques to the new feature without excessive
 risk.

Why exactly do you think that what I'm suggesting would cause a dump and
reload to not regenerate the data?  (Personally, I think pg_dump ought
to have an option selecting whether or not to repopulate matviews, but
again, if that's not what you want *don't use it*.)

 (2) Individual judges have a dashboard showing such things as the
 number of court cases which have gone beyond certain thresholds
 without action.  They can drill down to detail so that cases
 which have slipped through the cracks can be scheduled for some
 appropriate action.  Justice delayed... and all of that.  It
 would be much better to get an error which would result in
 information currently unavailable than to give the impression
 that there are no such cases.

If you need 100% accuracy, which is what this scenario appears to be
demanding, matviews are not for you (yet).  The existing implementation
certainly is nowhere near satisfying this scenario.

 ... Making sure that
 the heap has at least one page if data has been generated seems
 like a not-entirely-unreasonable way to do that, although there
 remains at least one vacuum bug to fix if we keep it, in addition
 to Tom's concerns.

No.  This is an absolute disaster.  It's taking something we have always
considered to be an irrelevant implementation detail and making it into
user-visible DDL state, despite the fact that it doesn't begin to satisfy
basic transactional behaviors.  We *need* to get rid of that aspect of
things.  If you must have scannability state in version 0, okay, but
it has to be a catalog property not this.

 It has the advantage of playing nicely with
 

Re: [HACKERS] Drastic performance loss in assert-enabled build in HEAD

2013-04-02 Thread Kevin Grittner
Tom Lane t...@sss.pgh.pa.us wrote:
 Kevin Grittner kgri...@ymail.com writes:
 Tom Lane t...@sss.pgh.pa.us wrote:
 So maybe I'm nuts to care about the performance of an
 assert-enabled backend, but I don't really find a 4X runtime
 degradation acceptable, even for development work.  Does anyone
 want to fess up to having caused this, or do I need to start
 tracking down what changed?

 I checked master HEAD for a dump of regression and got about 4
 seconds.  I checked right after my initial push of matview code
 and got 2.5 seconds.  I checked just before that and got 1
 second.  There was some additional pg_dump work for matviews
 after the initial push which may or may not account for the rest
 of the time.

 I poked at this a bit, and eventually found that the performance
 differential goes away if I dike out the
 pg_relation_is_scannable() call in getTables()'s table-collection
 query.  What appears to be happening is that those calls cause a
 great many more relcache entries to be made than used to happen,
 plus many entries are made earlier in the run than they used to
 be.  Many of those entries have subsidiary memory contexts, which
 results in an O(N^2) growth in the time spent in AllocSetCheck,
 since postgres.c does MemoryContextCheck(TopMemoryContext) once
 per received command, and pg_dump will presumably issue O(N)
 commands in an N-table database.

 So one question that brings up is whether we need to dial back
 the amount of work done in memory context checking, but I'm loath
 to do so in development builds.  That code has fingered an awful
 lot of bugs.  OTOH, if the number of tables in the regression DB
 continues to grow, we may have little choice.

 Anyway, the immediate takeaway is that this represents a horribly
 expensive way for pg_dump to find out which matviews aren't
 scannable.  The cheap way for it to find out would be if we had a
 boolean flag for that in pg_class.  Would you review the bidding
 as to why things were done the way they are?  Because in general,
 having to ask the kernel something is going to suck in any case,
 so basing it on the size of the disk file doesn't seem to me to
 be basically a good thing.

The early versions of the patch had a boolean in pg_class to track
this, but I got complaints from Robert and Noah (and possibly
others?) that this got too ugly in combination with the support for
unlogged matviews, and they suggested the current approach.  For an
unlogged matview we need to replace the heap (main fork) with the
init fork before the database is up and running, so there would
need to be some way for that to result in forcing the flag in
pg_class.  I was attempting to do that when a matview which was
flagged as scannable in pg_class was opened, but I gotta agree that
it wasn't pretty.  Noah suggested a function based on testing the
heap to see if it looked like the init fork, and the current state
of affairs I my attempt to make it work that way.

We could definitely minimize the overhead by only testing this for
matviews.  It seemed potentially useful for the function to have
some purpose for other types of relations, so I was trying to avoid
that.  Maybe that was a bad idea.

 We could alleviate the pain by changing pg_dump's query to
 something like

 (case when c.relkind = 'm'
  then pg_relation_is_scannable(c.oid)
  else false end)

Yeah, that's the sort of thing I was thinking of.  If we're going
to go that way, we may want to touch one or two other spots.

 but TBH this feels like bandaging a bad design.

So far nobody has been able to suggest a better way to support both
unlogged matviews and some way to prevent a matview from being used
if it does not contain materialized data for its query from *some*
point in time.  Suggestions welcome.

 Another reason why I don't like this code is that
 pg_relation_is_scannable is broken by design:

 relid = PG_GETARG_OID(0);
 relation = RelationIdGetRelation(relid);
 result = relation-rd_isscannable;
 RelationClose(relation);

 You can't do that: if the relcache entry doesn't already exist,
 this will try to construct one while not holding any lock on the
 relation, which is subject to all sorts of race conditions.

Hmm.  I think I had that covered earlier but messed up in
rearranging to respond to review comments.  Will review both new
calling locations.

 In general, direct calls on RelationIdGetRelation are probably
 broken.

If valid contexts for use of the function are that limited, it
might merit a comment where the function is defined.  I'm not sure
what a good alternative to this would be.

--
Kevin Grittner
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] Drastic performance loss in assert-enabled build in HEAD

2013-04-02 Thread Kevin Grittner
Kevin Grittner kgri...@ymail.com wrote:
 Tom Lane t...@sss.pgh.pa.us wrote:

 Another reason why I don't like this code is that
 pg_relation_is_scannable is broken by design:

  relid = PG_GETARG_OID(0);
  relation = RelationIdGetRelation(relid);
  result = relation-rd_isscannable;
  RelationClose(relation);

 You can't do that: if the relcache entry doesn't already exist,
 this will try to construct one while not holding any lock on the
 relation, which is subject to all sorts of race conditions.

 Hmm.  I think I had that covered earlier but messed up in
 rearranging to respond to review comments.  Will review both new
 calling locations.

For the SQL-level function, does this look OK?:

diff --git a/src/backend/utils/adt/dbsize.c
b/src/backend/utils/adt/dbsize.c
index d589d26..94e55f0 100644
--- a/src/backend/utils/adt/dbsize.c
+++ b/src/backend/utils/adt/dbsize.c
@@ -850,9 +850,13 @@ pg_relation_is_scannable(PG_FUNCTION_ARGS)
    bool    result;
 
    relid = PG_GETARG_OID(0);
-   relation = RelationIdGetRelation(relid);
+   relation = try_relation_open(relid, AccessShareLock);
+
+   if (relation == NULL)
+   PG_RETURN_BOOL(false);
+
    result = relation-rd_isscannable;
-   RelationClose(relation);
+   relation_close(relation, AccessShareLock);
 
    PG_RETURN_BOOL(result);
 }

I think the call in ExecCheckRelationsScannable() is safe because
it comes after the tables are all already locked.  I put it there
so that the appropriate lock strength should be used based on the
whether it was locked by ExecInitNode() or something before it.  Am
I missing something?  Can I not count on the lock being held at
that point?  Would the right level of API here be relation_open()
with NoLock rather than RelationIdGetRelation()?  Or is there some
other call which is more appropriate there?

-- 
Kevin Grittner
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] Drastic performance loss in assert-enabled build in HEAD

2013-03-29 Thread Tom Lane
Kevin Grittner kgri...@ymail.com writes:
 Tom Lane t...@sss.pgh.pa.us wrote:
 So maybe I'm nuts to care about the performance of an assert-enabled
 backend, but I don't really find a 4X runtime degradation acceptable,
 even for development work.  Does anyone want to fess up to having caused
 this, or do I need to start tracking down what changed?

 I checked master HEAD for a dump of regression and got about 4
 seconds.  I checked right after my initial push of matview code and
 got 2.5 seconds.  I checked just before that and got 1 second. 
 There was some additional pg_dump work for matviews after the
 initial push which may or may not account for the rest of the time.

I poked at this a bit, and eventually found that the performance
differential goes away if I dike out the pg_relation_is_scannable() call
in getTables()'s table-collection query.  What appears to be happening
is that those calls cause a great many more relcache entries to be made
than used to happen, plus many entries are made earlier in the run than
they used to be.  Many of those entries have subsidiary memory contexts,
which results in an O(N^2) growth in the time spent in AllocSetCheck,
since postgres.c does MemoryContextCheck(TopMemoryContext) once per
received command, and pg_dump will presumably issue O(N) commands in an
N-table database.

So one question that brings up is whether we need to dial back the
amount of work done in memory context checking, but I'm loath to do so
in development builds.  That code has fingered an awful lot of bugs.
OTOH, if the number of tables in the regression DB continues to grow,
we may have little choice.

Anyway, the immediate takeaway is that this represents a horribly
expensive way for pg_dump to find out which matviews aren't scannable.
The cheap way for it to find out would be if we had a boolean flag for
that in pg_class.  Would you review the bidding as to why things were
done the way they are?  Because in general, having to ask the kernel
something is going to suck in any case, so basing it on the size of the
disk file doesn't seem to me to be basically a good thing.

We could alleviate the pain by changing pg_dump's query to something
like

(case when c.relkind = 'm' then pg_relation_is_scannable(c.oid)
 else false end)

but TBH this feels like bandaging a bad design.

Another reason why I don't like this code is that
pg_relation_is_scannable is broken by design:

relid = PG_GETARG_OID(0);
relation = RelationIdGetRelation(relid);
result = relation-rd_isscannable;
RelationClose(relation);

You can't do that: if the relcache entry doesn't already exist, this
will try to construct one while not holding any lock on the relation,
which is subject to all sorts of race conditions.  (In general, direct
calls on RelationIdGetRelation are probably broken.  I see you
introduced more than one such in the matviews patch, and I'm willing to
bet they are all unsafe.)

regards, tom lane


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] Drastic performance loss in assert-enabled build in HEAD

2013-03-26 Thread Kevin Grittner
Tom Lane t...@sss.pgh.pa.us wrote:

 Using HEAD's pg_dump, I see pg_dump -s regression taking 5
 seconds.
 On the other hand, running the same executable against the regression
 database on a 9.2 postmaster takes 1.2 seconds.  Looks to me like we
 broke something performance-wise.

 A quick check with oprofile says it's all AllocSetCheck's fault:

 samples  %    image name  symbol name
 8    83.6059  postgres    AllocSetCheck
 1140  1.0858  postgres    base_yyparse
 918  0.8744  postgres    AllocSetAlloc
 778  0.7410  postgres    SearchCatCache
 406  0.3867  postgres    pg_strtok
 394  0.3753  postgres    hash_search_with_hash_value
 387  0.3686  postgres    core_yylex
 373  0.3553  postgres    MemoryContextCheck
 256  0.2438  postgres    nocachegetattr
 231  0.2200  postgres    ScanKeywordLookup
 207  0.1972  postgres    palloc

 So maybe I'm nuts to care about the performance of an assert-enabled
 backend, but I don't really find a 4X runtime degradation acceptable,
 even for development work.  Does anyone want to fess up to having caused
 this, or do I need to start tracking down what changed?

I checked master HEAD for a dump of regression and got about 4
seconds.  I checked right after my initial push of matview code and
got 2.5 seconds.  I checked just before that and got 1 second. 
There was some additional pg_dump work for matviews after the
initial push which may or may not account for the rest of the time.

Investigating now.

--
Kevin Grittner
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers