Received: from localhost (unknown [200.46.204.183]) by postgresql.org (Postfix) with ESMTP id 4501865039C for ; Fri, 25 Jul 2008 20:16:48 -0300 (ADT) Received: from postgresql.org ([200.46.204.86]) by localhost (mx1.hub.org [200.46.204.183]) (amavisd-maia, port 10024) with ESMTP id 46920-06 for ; Fri, 25 Jul 2008 20:16:37 -0300 (ADT) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from sss.pgh.pa.us (sss.pgh.pa.us [66.207.139.130]) by postgresql.org (Postfix) with ESMTP id 0B7BA65039D for ; Fri, 25 Jul 2008 20:16:40 -0300 (ADT) Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) by sss.pgh.pa.us (8.14.2/8.14.2) with ESMTP id m6PNGOIP002819; Fri, 25 Jul 2008 19:16:24 -0400 (EDT) To: Simon Riggs cc: Stephen Frost , pgsql-patches@postgresql.org Subject: Re: pg_dump additional options for performance In-reply-to: <1216889809.3894.747.camel@ebony.2ndQuadrant> References: <20080720214335.GB18846@tamriel.snowman.net> <1216591180.19656.848.camel@ebony.2ndQuadrant> <20080721011829.GC18846@tamriel.snowman.net> <20080721014942.GC30869@sonic.net> <20080721015850.GD18846@tamriel.snowman.net> <18415.1216611275@sss.pgh.pa.us> <1216621040.19656.867.camel@ebony.2ndQuadrant> <20080721115602.GG18846@tamriel.snowman.net> <1216831237.3894.676.camel@ebony.2ndQuadrant> <1216832987.3894.678.camel@ebony.2ndQuadrant> <20080724032047.GI18846@tamriel.snowman.net> <1216885031.3894.739.camel@ebony.2ndQuadrant> <21687.1216886041@sss.pgh.pa.us> <1216889809.3894.747.camel@ebony.2ndQuadrant> Comments: In-reply-to Simon Riggs message dated "Thu, 24 Jul 2008 09:56:49 +0100" MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0" Content-ID: <2697.1217027098.0@sss.pgh.pa.us> Date: Fri, 25 Jul 2008 19:16:24 -0400 Message-ID: <2818.1217027784@sss.pgh.pa.us> From: Tom Lane X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=0 tagged_above=0 required=5 tests=none X-Spam-Level: X-Archive-Number: 200807/251 X-Sequence-Number: 6945 ------- =_aaaaaaaaaa0 Content-Type: text/plain; charset="us-ascii" Content-ID: <2697.1217027098.1@sss.pgh.pa.us> Simon Riggs writes: > [ pg_dump_beforeafter.v6.patch ] I looked over this patch a bit. I have a proposal for a slightly different way of defining the new switches: * --schema-before-data, --data-only, and --schema-after-data can be specified in any combination to obtain any subset of the full dump. If none are specified (which would in itself be a useless combination) then the default is to dump all three sections, just as if all three were specified. * --schema-only is defined as equivalent to specifying both --schema-before-data and --schema-after-data. The patch as submitted enforces what seem largely arbitrary restrictions on combining these switches. It made some sense before to treat specifying both --schema-only and --data-only as an error, but it's not clear to me why you shouldn't be able to write both --schema-before-data and --schema-after-data, especially when there's a switch right beside them that appears to be equivalent to that combination. So let's just allow all the combinations. The attached updated patch implements and documents this behavior, and gets rid of the special linkage between --disable-triggers and --data-only as previously discussed. Unfortunately there's still a lot of work to do, and I don't feel like doing it so I'm bouncing this patch back for further work. The key problem is that pg_restore is broken: it emits nearly the same output for --schema-before-data and --schema-after-data, because it doesn't have any way to distinguish which objects in a full dump file belong where. This is because the filtering logic was put in the wrong place, namely in the ArchiveEntry creation routines in pg_dump.c, when where it really needs to happen is while scanning the TocEntry list in RestoreArchive(). (Note: it is perhaps worth keeping the pg_dump.c filters so as to avoid doing extra server queries for objects that we aren't going to dump anyway, but the core logic has to be in RestoreArchive.) Another issue is that the rules for deciding which objects are "before data" and which are "after data" are wrong. In particular ACLs are after data not before data, which is relatively easy to fix. Not so easy to fix is that COMMENTs might be either before or after data depending on what kind of object they are attached to. (BTW, what about BLOB COMMENTS? They definitely can't be "before data". ISTM you could make a case for them being "after data", if you think that comments are always schema. But there is also a case for considering them as data, because the objects they are attached to are data. I kind of like the latter approach because it would create an invariant that comments appear in the same dump section as the object commented on. Thoughts?) Implementing the filtering by examining the type of a TocEntry in RestoreArchive is a bit of a PITA, but it's probably possible. The main bad thing about that is the need to make an explicit list of every type of TocEntry that exists now or ever has been emitted by any past version of pg_dump. The design concept was that the type tags are mainly documentation, and while we've had to bend that in places (mostly for backward-compatibility reasons) this would be the first place we'd have to throw it overboard completely. And there's yet another issue here, which is that it's not entirely clear that the type of an object uniquely determines whether it's before or after data. This might be an emergent property of the object sorting rules, but there is certainly not anything positively guaranteeing that the dependency-driven topological sort will produce such a result, and especially not that that will always be true in the future. So the approach seems a bit fragile. We could perhaps get rid of that problem, as well as the need to implement object-type-determination logic, if we were to make RestoreArchive define the groupings according to position in the TocEntry list: everything before the first TABLE DATA or BLOB (and BLOB COMMENT?) entry is "before" data, everything after the last one is "after" data, everything in between is data. Then we only need to identify object types that are considered "data", which we already have a rule for (whether hadDumper is true). This is pretty attractive until you stop to consider the possibility that there aren't any data entries in an archive (ie, it was made with --schema-only): then there's no way to identify the boundary points. We could solve that problem by inserting a "dummy data" TOC entry where the data would have appeared, but this will only work in new archive files. With an implementation like this, pg_restore with --schema-before-data or --schema-after-data won't behave very nicely on a pre-8.4 --schema-only archive file. (Presumably it would act as though all the objects were "before" data.) Is that a small enough corner case to live with in order to gain implementation simplicity and robustness? BTW, another incomplete item is that pg_dumpall should probably be taught to accept and pass down --schema-before-data and --schema-after-data switches. regards, tom lane ------- =_aaaaaaaaaa0 Content-Type: application/octet-stream Content-ID: <2697.1217027098.2@sss.pgh.pa.us> Content-Description: pg_dump_beforeafter.v7.patch.gz Content-Transfer-Encoding: base64 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 S0r4tjTJi/eufy1aEOT/DwpPvsFlwAAA ------- =_aaaaaaaaaa0--