Re: [HACKERS] [COMMITTERS] pgsql: Add TCP keepalive support to libpq.
On Thu, Jun 24, 2010 at 11:50 PM, Tom Lane t...@sss.pgh.pa.us wrote: Robert Haas robertmh...@gmail.com writes: On Thu, Jun 24, 2010 at 1:38 PM, Simon Riggs si...@2ndquadrant.com wrote: On Thu, 2010-06-24 at 11:15 -0400, Tom Lane wrote: It might be a good idea to add a sentence to the documentation, though, just pointing out that these control client-side keepalive probes rather than server-side. Yes please. I was confused; I think others will be also. Do either of you have any thoughts about where would be the best place to add such a sentence? In the hunk you added to libpq.sgml would be fine by me. Well, the trick is that the hunk that I added is really four separate sections, and adding a whole sentence to each one seems like overkill. Here's an attempt at rewording the sections so that the information is included in each parameter's description without taking up a whole sentence. Thoughts? -- Robert Haas EnterpriseDB: http://www.enterprisedb.com The Enterprise Postgres Company libpq-keepalive-docs.patch Description: Binary data -- 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] pgsql: Add TCP keepalive support to libpq.
Robert Haas robertmh...@gmail.com wrote: Here's an attempt at rewording the sections so that the information is included in each parameter's description without taking up a whole sentence. Thoughts? It makes the point without beating one over the head with it. I particularly like the way this patch moves the main point of the parameter to the front, with all the conditions under which it might be ignored pushed farther back. It reads much better that way, at least for me. -Kevin -- 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] testing plpython3u on 9.0beta2
Peter Eisentraut pete...@gmx.net writes: The problem is apparently that when CREATE LANGUAGE creates a language from a pg_pltemplate entry, it creates the proname from the tmplhandler name, and if it finds a fitting proname entry already, it used that one. So when you create plpython2 first and plpython3 second, the pg_language entries of the latter point to the pg_proc entries of the former. If you fix that up manually (create additional pg_proc entries and fix the pg_language entries to point there), it works better. The fix ought to be to change the function nmes used by plpython3 ... 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
[HACKERS] Re: [COMMITTERS] pgsql: Fix log_temp_files docs and comments to say bytes not kilobytes.
On 25/06/10 16:11, Simon Riggs wrote: Log Message: --- Fix log_temp_files docs and comments to say bytes not kilobytes. stat(2) field st_size returns bytes not kilobytes. Bug found during recent performance tuning for PostgreSQL user. Modified Files: -- pgsql/doc/src/sgml: config.sgml (r1.282 - r1.283) (http://anoncvs.postgresql.org/cvsweb.cgi/pgsql/doc/src/sgml/config.sgml?r1=1.282r2=1.283) pgsql/src/backend/utils/misc: guc.c (r1.556 - r1.557) (http://anoncvs.postgresql.org/cvsweb.cgi/pgsql/src/backend/utils/misc/guc.c?r1=1.556r2=1.557) Hmm, GUC_UNIT_KB doesn't seem appropriate anymore. I'd suggest changing the code to match the documentation instead. Shouldn't this be backpatched, or was this a new bug in 9.0? -- Heikki Linnakangas 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
[HACKERS] Re: [COMMITTERS] pgsql: Fix log_temp_files docs and comments to say bytes not kilobytes.
On Fri, 2010-06-25 at 17:25 +0300, Heikki Linnakangas wrote: On 25/06/10 16:11, Simon Riggs wrote: Log Message: --- Fix log_temp_files docs and comments to say bytes not kilobytes. stat(2) field st_size returns bytes not kilobytes. Bug found during recent performance tuning for PostgreSQL user. Modified Files: -- pgsql/doc/src/sgml: config.sgml (r1.282 - r1.283) (http://anoncvs.postgresql.org/cvsweb.cgi/pgsql/doc/src/sgml/config.sgml?r1=1.282r2=1.283) pgsql/src/backend/utils/misc: guc.c (r1.556 - r1.557) (http://anoncvs.postgresql.org/cvsweb.cgi/pgsql/src/backend/utils/misc/guc.c?r1=1.556r2=1.557) Hmm, GUC_UNIT_KB doesn't seem appropriate anymore. I'd suggest changing the code to match the documentation instead. Well, perhaps it does. Maybe I should fix the report to output KB instead and revert all the comments to kilo Shouldn't this be backpatched, or was this a new bug in 9.0? Spose so. -- Simon Riggs www.2ndQuadrant.com PostgreSQL Development, 24x7 Support, Training and Services -- 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] New PGXN Extension site
On Jun 16, 2010, at 3:37 AM, Dave Page wrote: heh I'm with Robert on that PGXN just sounds and speels weird - PGAN was much easier ;) +1 Seriously? To me, “pee-gan” just didn't sound nice. And the acronym, “PostgreSQL Add-on Network,” wasn't as good, since it's mainly extension-focused. I guess it could be “PostgreSQL Archive Network,” going back to the CPAN example. Downside to that is that it likely won't distribute PostgreSQL itself. I thought “PGXN” sounded more official-ish, less cute. And I don't mind “pixin” as the pronunciation. Perhaps I could get on board with PGAN if we follow Cédric’s example and pronounce it “pe-zhan.” Honestly, I didn't realize anyone was attached to “PGAN.” Frankly, I blame whoever named PostgreSQL itself and came up with the short version, “PG.” Nothing but pigs out of that. Best, David -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
[HACKERS] Streaming Replication: sql error on standby
Hi, Sql query select pg_last_xlog_receive_location(); does not work during startup of standby database. TestScenario; We have a active-standby system with PostgreSQL Streaming Replication beta2. If the active database is up the database is in use (read/write queries will be performed). Then the standby PostgreSQL SR will be started (the complete database from the active side is copied to the standby side; nec. Files for starting streaming replication are created). Directly after the possibility to connect to the standby system, the above given sql query will be executed. To this timepoint the sql query delivers an error. To a later timepoint (all wal segments are completly incooperated) the query delivers a valid result. Question: What is the reason for the error? Exists a command to find out if the standby database is really active to accept/can work with sql commands? BR Ingo Best Regards/mfG Ingo Sander = Nokia Siemens Networks GmbH Co. KG NWS EP CP SVSS Platform Tech Support DE St.-Martin-Str. 76 D-81541 München *Tel.: +49-89-515938390 *ingo.san...@nsn.com Nokia Siemens Networks GmbH Co. KG Sitz der Gesellschaft: München / Registered office: Munich Registergericht: München / Commercial registry: Munich, HRA 88537 WEEE-Reg.-Nr.: DE 52984304 Persönlich haftende Gesellschafterin / General Partner: Nokia Siemens Networks Management GmbH Geschäftsleitung / Board of Directors: Lydia Sommer, Olaf Horsthemke Vorsitzender des Aufsichtsrats / Chairman of supervisory board: Herbert Merz Sitz der Gesellschaft: München / Registered office: Munich Registergericht: München / Commercial registry: Munich, HRB 163416
[HACKERS] GSoC - code of implementation of materialized views
On http://github.com/pbaros/postgres can be seen changes and my attempt to implement materialized views. The first commit to the repository implements following: Materialized view can be created, dropped and used in SELECT statement. CREATE MATERIALIZED VIEW mvname AS SELECT ...; DROP MATERIALIZED VIEW mvname [CASCADE]; SELECT * FROM mvname; also works: COMMENT ON MATERIALIZED VIEW mvname IS 'etc.'; SELECT pg_get_viewdef(mvname); Also, I would like to ask for advise if there are rules about specifying keyword is reserved or unreserved. How I recognize new keywords MATERIALIZED and REFRESH should be reserved or not. thanks Pavel Baros -- 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] Streaming Replication: sql error on standby
On Wed, Jun 23, 2010 at 4:48 AM, Sander, Ingo (NSN - DE/Munich) ingo.san...@nsn.com wrote: Sql query select pg_last_xlog_receive_location(); does not work during startup of standby database. TestScenario; We have a active-standby system with PostgreSQL Streaming Replication beta2. If the active database is up the database is in use (read/write queries will be performed). Then the standby PostgreSQL SR will be started (the complete database from the active side is copied to the standby side; nec. Files for starting streaming replication are created). Directly after the possibility to connect to the standby system, the above given sql query will be executed. To this timepoint the sql query delivers an error. What is the error message? To a later timepoint (all wal segments are completly incooperated) the query delivers a valid result. Question: What is the reason for the error? Exists a command to find out if the standby database is really active to accept/can work with sql commands? -- Robert Haas EnterpriseDB: http://www.enterprisedb.com The Enterprise Postgres 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] pgsql: Add TCP keepalive support to libpq.
Kevin Grittner kevin.gritt...@wicourts.gov writes: Robert Haas robertmh...@gmail.com wrote: Here's an attempt at rewording the sections so that the information is included in each parameter's description without taking up a whole sentence. Thoughts? It makes the point without beating one over the head with it. I particularly like the way this patch moves the main point of the parameter to the front, with all the conditions under which it might be ignored pushed farther back. It reads much better that way, at least for me. Looks good to me too. 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] pgsql: Add TCP keepalive support to libpq.
On Fri, Jun 25, 2010 at 1:02 PM, Tom Lane t...@sss.pgh.pa.us wrote: Kevin Grittner kevin.gritt...@wicourts.gov writes: Robert Haas robertmh...@gmail.com wrote: Here's an attempt at rewording the sections so that the information is included in each parameter's description without taking up a whole sentence. Thoughts? It makes the point without beating one over the head with it. I particularly like the way this patch moves the main point of the parameter to the front, with all the conditions under which it might be ignored pushed farther back. It reads much better that way, at least for me. Looks good to me too. OK, committed. -- Robert Haas EnterpriseDB: http://www.enterprisedb.com The Enterprise Postgres Company -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
[HACKERS] Admission Control
Recent discussions involving the possible benefits of a connection pool for certain users has reminded me of a brief discussion at The Royal Oak last month, where I said I would post a reference a concept which might alleviate the need for external connection pools. For those interested, check out section 2.4 of this document: Joseph M. Hellerstein, Michael Stonebraker and James Hamilton. 2007. Architecture of a Database System. Foundations and Trends(R) in Databases Vol. 1, No. 2 (2007) 141*259. http://db.cs.berkeley.edu/papers/fntdb07-architecture.pdf -Kevin -- 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] Re: [COMMITTERS] pgsql: Fix log_temp_files docs and comments to say bytes not kilobytes.
Shouldn't this be backpatched, or was this a new bug in 9.0? We've always output bytes. I'd have noticed the discrepancy myself if I'd read the actual docs ;-) KB would be more useful. And I don't think people have enough scripts built on this yet to make this break anything. We should backport to 8.4. -- -- Josh Berkus PostgreSQL Experts Inc. http://www.pgexperts.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] testing plpython3u on 9.0beta2
On fre, 2010-06-25 at 10:17 -0400, Tom Lane wrote: Peter Eisentraut pete...@gmx.net writes: The problem is apparently that when CREATE LANGUAGE creates a language from a pg_pltemplate entry, it creates the proname from the tmplhandler name, and if it finds a fitting proname entry already, it used that one. So when you create plpython2 first and plpython3 second, the pg_language entries of the latter point to the pg_proc entries of the former. If you fix that up manually (create additional pg_proc entries and fix the pg_language entries to point there), it works better. The fix ought to be to change the function nmes used by plpython3 ... Right. What shall we do about the catversion? Index: src/include/catalog/pg_pltemplate.h === RCS file: /cvsroot/pgsql/src/include/catalog/pg_pltemplate.h,v retrieving revision 1.13 diff -u -3 -p -r1.13 pg_pltemplate.h --- src/include/catalog/pg_pltemplate.h 22 Jan 2010 15:45:15 - 1.13 +++ src/include/catalog/pg_pltemplate.h 25 Jun 2010 18:46:56 - @@ -74,6 +74,6 @@ DATA(insert ( plperl t t plperl_call DATA(insert ( plperlu f f plperl_call_handler plperl_inline_handler plperl_validator $libdir/plperl _null_ )); DATA(insert ( plpythonu f f plpython_call_handler plpython_inline_handler _null_ $libdir/plpython _null_ )); DATA(insert ( plpython2u f f plpython_call_handler plpython_inline_handler _null_ $libdir/plpython2 _null_ )); -DATA(insert ( plpython3u f f plpython_call_handler plpython_inline_handler _null_ $libdir/plpython3 _null_ )); +DATA(insert ( plpython3u f f plpython3_call_handler plpython3_inline_handler _null_ $libdir/plpython3 _null_ )); #endif /* PG_PLTEMPLATE_H */ Index: src/pl/plpython/plpython.c === RCS file: /cvsroot/pgsql/src/pl/plpython/plpython.c,v retrieving revision 1.144 diff -u -3 -p -r1.144 plpython.c --- src/pl/plpython/plpython.c 10 Jun 2010 04:05:01 - 1.144 +++ src/pl/plpython/plpython.c 25 Jun 2010 18:46:56 - @@ -244,6 +244,12 @@ typedef struct PLyResultObject /* function declarations */ +#if PY_MAJOR_VERSION = 3 +/* Use separate names to avoid clash in pg_pltemplate */ +#define plpython_call_handler plpython3_call_handler +#define plpython_inline_handler plpython3_inline_handler +#endif + /* exported functions */ Datum plpython_call_handler(PG_FUNCTION_ARGS); Datum plpython_inline_handler(PG_FUNCTION_ARGS); -- 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] testing plpython3u on 9.0beta2
Peter Eisentraut pete...@gmx.net writes: On fre, 2010-06-25 at 10:17 -0400, Tom Lane wrote: The fix ought to be to change the function nmes used by plpython3 ... Right. What shall we do about the catversion? You could argue it either way. The number of beta testers with plpython3 installations is probably very small, so I'm kinda leaning to just changing the code without a catversion bump. OTOH, if we want to encourage testing of pg_upgrade ... 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] testing plpython3u on 9.0beta2
You could argue it either way. The number of beta testers with plpython3 installations is probably very small, so I'm kinda leaning to just changing the code without a catversion bump. OTOH, if we want to encourage testing of pg_upgrade ... FWIW, the last bump has led to a lot of testing of pgupgrade. -- -- Josh Berkus PostgreSQL Experts Inc. http://www.pgexperts.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] Admission Control
On Fri, Jun 25, 2010 at 1:33 PM, Kevin Grittner kevin.gritt...@wicourts.gov wrote: Recent discussions involving the possible benefits of a connection pool for certain users has reminded me of a brief discussion at The Royal Oak last month, where I said I would post a reference a concept which might alleviate the need for external connection pools. For those interested, check out section 2.4 of this document: Joseph M. Hellerstein, Michael Stonebraker and James Hamilton. 2007. Architecture of a Database System. Foundations and Trends(R) in Databases Vol. 1, No. 2 (2007) 141*259. http://db.cs.berkeley.edu/papers/fntdb07-architecture.pdf I think a good admission control system for memory would be huge for us. There are innumerable threads on pgsql-performance where we tell people to set work_mem to a tiny value (like 4MB or 16MB) because any higher value risks driving the machine into swap in the event that they get an unusually large number of connections or those connections issue queries that require an unusual number of hashes or sorts. There are also innumerable postings from people complaining that external sorts are way slower than in-memory sorts, and of course a hash join frequently mops the floor with a nested loop with inner index-scan. A really trivial admission control system might let you set a system-wide limit on work_mem. As we build a plan, we could estimate the total amount of work_mem it will require by examining all the sort, hash, and hash aggregate nodes it contains. In shared memory, we keep a total of this value across all back-ends. Just before beginning to execute a plan that uses 0 work_mem, we bump this value up by the value for the current plan, unless that would make us exceed the system-wide limit. In that case, we sleep, and then next person to finish executing (and decrease the value in shared memory) will wake us up to try again. (Ideally, we'd want to make maintenance_work_mem part of this accounting process also; otherwise, a system that was humming along nicely might suddenly start thrashing when a maintenance operation kicks off.) I suppose this would take a good deal of performance testing to see how well it actually works. A refinement might be to try to consider an inferior plan that uses less memory when the system is tight on memory, rather than waiting. But you'd have to be careful about that, because waiting might be better (it's worth waiting 15 s if it means the execution time will decrease by 15 s). The idea of doling out queries to engine processes in an interesting one, but seems very different than our current query execution model. I can't even begin to speculate as to whether there's anything interesting we could do in that area without reading some literature on the topic - got any pointers? But even if we can't or don't want to do that, we already know that limiting the number of backends and round-robining queries among them performs MUCH better that setting max_connections to a large value, and not just because of memory exhaustion. Our answer to that problem is use a connection pooler, but that's not a very good solution even aside from the possible administrative nuisance, because it only solves half the problem. In the general case, the question is not whether we can currently afford to allocate 0 or 1 backends to a given query, but whether we can afford to allocate 0, 1, or 1; furthermore, if we can afford to allocate 1 backend, we'd ideally like to reuse an existing backend rather than starting a new one. I don't think anyone's going to be too happy with a parallel query implementation with a dependency on an external connection poooler. One of the difficulties in reusing an existing backend for a new query, or in maintaining a pool of backends that could be used as workers for parallel queries, is that our current system does not require us to have, nor do we have, a way of resetting a backend to a completely pristine state. DISCARD ALL is probably pretty close, because AIUI that's what connection poolers are using today, and if it didn't work reasonably well, we'd have gotten complaints. But DISCARD ALL will not let you rebind to a different database, for example, which would be a pretty useful thing to do in a pooling environment, so that you needn't maintain separate pools for each database, and it doesn't let you restart the authentication cycle (with no backsies) either. Of course, addressing these problems wouldn't by itself give us a built-in connection pooler or parallel query execution, and there's some danger of destabilizing the code, but possibly it would be a good way to get off the ground. Not sure, though. Thoughts? -- Robert Haas EnterpriseDB: http://www.enterprisedb.com The Enterprise Postgres 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] LLVM / clang
On fre, 2010-06-11 at 07:00 +0300, Peter Eisentraut wrote: The second problem is that the prototype check for accept() fails. This is because glibc defines the second argument to be a transparent union, apparently to make it look like a lot of things at once. clang apparently doesn't understand that. One could address this by checking for the typedef that glibc uses explicitly in the configure check, but that would appear to defeat the point of the *transparent* union. A workaround is to remove -D_GNU_SOURCE from src/template/linux. Predictably, this will make PL/Perl fail to build. Also, it will make src/backend/libpq/auth.c fail to build, because struct ucred is only defined when _GNU_SOURCE is used. This would actually fail to work on GCC as well, so I think we should add an explicit configure check for struct ucred. For the record, here is a patch that would address these issues. At the moment, I'm waiting to get my hands on the new version 2.7 of clang to see if some of these issues have gone away. Considering that clang already helped us find one bug in the code, I think it's worth trying to make this work. diff --git a/configure.in b/configure.in index 0a529fa..bb1d0dd 100644 --- a/configure.in +++ b/configure.in @@ -390,6 +390,11 @@ choke me AC_SUBST(SUN_STUDIO_CC) +# Check if it's Clang, which defines __clang__. +AC_TRY_COMPILE([], [...@%:@ifndef __clang__ +choke me +...@%:@endif], [CLANG=yes], [CLANG=no]) + unset CFLAGS # @@ -1102,7 +1107,7 @@ AC_TYPE_INTPTR_T AC_TYPE_UINTPTR_T AC_TYPE_LONG_LONG_INT -AC_CHECK_TYPES([struct cmsgcred, struct fcred, struct sockcred], [], [], +AC_CHECK_TYPES([struct ucred,struct cmsgcred, struct fcred, struct sockcred], [], [], [#include sys/param.h #include sys/types.h #include sys/socket.h diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c index b06b391..27482bd 100644 --- a/src/backend/libpq/auth.c +++ b/src/backend/libpq/auth.c @@ -1786,7 +1786,7 @@ ident_unix(int sock, char *ident_user) strlcpy(ident_user, pass-pw_name, IDENT_USERNAME_MAX + 1); return true; -#elif defined(SO_PEERCRED) +#elif defined(SO_PEERCRED) defined(HAVE_STRUCT_UCRED) /* Linux style: use getsockopt(SO_PEERCRED) */ struct ucred peercred; ACCEPT_TYPE_ARG3 so_len = sizeof(peercred); diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index fd169b6..8d41549 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -529,6 +529,9 @@ /* Define to 1 if `tm_zone' is member of `struct tm'. */ #undef HAVE_STRUCT_TM_TM_ZONE +/* Define to 1 if the system has the type `struct ucred'. */ +#undef HAVE_STRUCT_UCRED + /* Define to 1 if you have the SupportDefs.h header file. */ #undef HAVE_SUPPORTDEFS_H diff --git a/src/template/linux b/src/template/linux index 68da3bb..aff39e8 100644 --- a/src/template/linux +++ b/src/template/linux @@ -1,7 +1,9 @@ # $PostgreSQL$ # Force _GNU_SOURCE on; plperl is broken with Perl 5.8.0 otherwise -CPPFLAGS=$CPPFLAGS -D_GNU_SOURCE +if test $CLANG != yes; then + CPPFLAGS=$CPPFLAGS -D_GNU_SOURCE +fi # If --enable-profiling is specified, we need -DLINUX_PROFILE PLATFORM_PROFILE_FLAGS=-DLINUX_PROFILE -- 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] Admission Control
Robert Haas robertmh...@gmail.com wrote: Kevin Grittner kevin.gritt...@wicourts.gov wrote: check out section 2.4 of this A really trivial admission control system might let you set a system-wide limit on work_mem. Heck, I think an even *more* trivial admission control policy which limits the number of active database transactions released to execution might solve a lot of problems. Of course, what you propose is more useful, although I'd be inclined to think that we'd want an admission control layer which could be configured so support both of these and much more. Done correctly, it could almost completely eliminate the downward slope after you hit the knee in many performance graphs. A refinement might be to try to consider an inferior plan that uses less memory when the system is tight on memory, rather than waiting. I wouldn't try messing with that until we have the basics down. ;-) It is within the scope of what an execution admission controller is intended to be able to do, though. The idea of doling out queries to engine processes in an interesting one, but seems very different than our current query execution model. That wasn't in section 2.4 itself -- you must have read the whole chapter. I think any discussion of that should spin off a separate thread -- the techniques are really orthogonal. And frankly, that's more ambitious a topic than *I'm* inclined to want to get into at the moment. An execution admission controller that starts simple but leaves room for growth seems within the realm of possibility. -Kevin -- 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] Functional dependencies and GROUP BY
On mån, 2010-06-07 at 21:33 +0300, Peter Eisentraut wrote: I have developed a patch that partially implements the functional dependency feature that allows some columns to be omitted from the GROUP BY clause if it can be shown that the columns are functionally dependent on the columns in the group by clause and therefore guaranteed to be unique per group. Second version: I stripped out all checks except the primary key/unique constraint checks. Views whose existence depends on one of those constraints get a dependency recorded. This depends on the patch currently in the commit fest to record not null constraints in pg_constraint, so that the dependencies on not-null constraints can be recorded. I haven't done any caching of index lookups yet. Some testing with 1600-column tables didn't show any effect. I'll test this a little more. diff --git a/doc/src/sgml/queries.sgml b/doc/src/sgml/queries.sgml index d0c41ce..e40cc4c 100644 --- a/doc/src/sgml/queries.sgml +++ b/doc/src/sgml/queries.sgml @@ -886,10 +886,7 @@ SELECT product_id, p.name, (sum(s.units) * p.price) AS sales In this example, the columns literalproduct_id/literal, literalp.name/literal, and literalp.price/literal must be in the literalGROUP BY/ clause since they are referenced in -the query select list. (Depending on how the products -table is set up, name and price might be fully dependent on the -product ID, so the additional groupings could theoretically be -unnecessary, though this is not implemented.) The column +the query select list (but see below). The column literals.units/ does not have to be in the literalGROUP BY/ list since it is only used in an aggregate expression (literalsum(...)/literal), which represents the sales @@ -898,6 +895,18 @@ SELECT product_id, p.name, (sum(s.units) * p.price) AS sales /para para +If the products table is set up so that, +say, literalproduct_id/literal is the primary key or a +not-null unique constraint, then it would be enough to group +by literalproduct_id/literal in the above example, since name +and price would be firsttermfunctionally +dependent/firsttermindextermprimaryfunctional +dependency/primary/indexterm on the product ID, and so there +would be no ambiguity about which name and price value to return +for each product ID group. + /para + + para In strict SQL, literalGROUP BY/ can only group by columns of the source table but productnamePostgreSQL/productname extends this to also allow literalGROUP BY/ to group by columns in the diff --git a/doc/src/sgml/ref/select.sgml b/doc/src/sgml/ref/select.sgml index 74021e8..1d02472 100644 --- a/doc/src/sgml/ref/select.sgml +++ b/doc/src/sgml/ref/select.sgml @@ -520,8 +520,12 @@ GROUP BY replaceable class=parameterexpression/replaceable [, ...] produces a single value computed across all the selected rows). When literalGROUP BY/literal is present, it is not valid for the commandSELECT/command list expressions to refer to -ungrouped columns except within aggregate functions, since there -would be more than one possible value to return for an ungrouped +ungrouped columns except within aggregate functions or if the +ungrouped column is functionally dependent on the grouped columns, +since there would otherwise be more than one possible value to +return for an ungrouped column. A functional dependency exists if +the grouped columns (or a subset thereof) are the primary key or a +not-null unique constraint of the table containing the ungrouped column. /para /refsect2 diff --git a/src/backend/commands/view.c b/src/backend/commands/view.c index d7a06bc..dae51ea 100644 --- a/src/backend/commands/view.c +++ b/src/backend/commands/view.c @@ -16,6 +16,7 @@ #include access/heapam.h #include access/xact.h +#include catalog/dependency.h #include catalog/namespace.h #include commands/defrem.h #include commands/tablecmds.h @@ -474,6 +475,27 @@ DefineView(ViewStmt *stmt, const char *queryString) */ CommandCounterIncrement(); + if (list_length(viewParse-dependencies) 0) + { + ObjectAddress myself, referenced; + ListCell *lc; + + myself.classId = RelationRelationId; + myself.objectId = viewOid; + myself.objectSubId = 0; + + foreach(lc, viewParse-dependencies) + { + Oid index_relid = lfirst_oid(lc); + + referenced.classId = RelationRelationId; + referenced.objectId = index_relid; + referenced.objectSubId = 0; + + recordDependencyOn(myself, referenced, DEPENDENCY_NORMAL); + } + } + /* * The range table of 'viewParse' does not contain entries for the OLD * and NEW relations. So... add them! diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index e770e89..948df43 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -2253,6 +2253,7 @@ _copyQuery(Query *from) COPY_NODE_FIELD(limitCount);
Re: [HACKERS] Admission Control
On 6/25/10 12:15 PM, Robert Haas wrote: I think a good admission control system for memory would be huge for us. There are innumerable threads on pgsql-performance where we tell people to set work_mem to a tiny value (like 4MB or 16MB) because any higher value risks driving the machine into swap in the event that they get an unusually large number of connections or those connections issue queries that require an unusual number of hashes or sorts. Greenplum did this several years ago with the Bizgres project; it had a resource control manager which was made available for PostgreSQL core. However, it would have required a large and unpredictable amount of work to make it compatible with OLTP workloads. The problem with centralized resource control is the need for centralized locking on requests for resources. That forces transactions to be serialized in order to make sure resources are not double-allocated. This isn't much of a problem in a DW application, but in a web app with thousands of queries per second it's deadly. Performance engineering for PostgreSQL over the last 7 years has been partly about eliminating centralized locking; we don't want to add new locking. That means that a realistic admissions control mechanism would need to operate based on projections and estimates and best effort policies. Not only is this mathematically more complex, it's an open question whether it puts us ahead of where we are now vis-a-vis underallocation of memory. Realistically, a lot of tuning and testing would be required before such a tool was actually an improvement. Or, to put it another way: the poor man's admission control is a waste of time because it doesn't actually help performance. We're basically facing doing the hard version, or not bothering. -- -- Josh Berkus PostgreSQL Experts Inc. http://www.pgexperts.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] Admission Control
Josh Berkus j...@agliodbs.com wrote: Greenplum did this several years ago with the Bizgres project However, it [was not] compatible with OLTP workloads. the poor man's admission control is a waste of time because it doesn't actually help performance. We're basically facing doing the hard version, or not bothering. I think it's premature to assume that without any evidence. I'm sure it's possible to create a policy which does more harm than good for any particular workload; there's no denying that could happen, but things such as limiting open transactions (as just one example) might be accomplished at very low cost. Since I have seen dramatic performance improvements from restricting this through a connection pool, I'm inclined to believe there could be benefit from such a simple policy as this. The total work memory policy Robert proposed sounds likely to more than pay for itself by allowing larger work_mem settings without risking cache flushing or swapping. One thing that seems clear to me is that the admission policy should be configurable, so that it can be tuned base on workload. That would also be consistent with a start simple and expand the capabilities approach. C'mon, don't be such a buzz-kill. Why should Greenplum have all the fun? ;-) -Kevin -- 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] Admission Control
On Fri, Jun 25, 2010 at 4:10 PM, Josh Berkus j...@agliodbs.com wrote: On 6/25/10 12:15 PM, Robert Haas wrote: I think a good admission control system for memory would be huge for us. There are innumerable threads on pgsql-performance where we tell people to set work_mem to a tiny value (like 4MB or 16MB) because any higher value risks driving the machine into swap in the event that they get an unusually large number of connections or those connections issue queries that require an unusual number of hashes or sorts. Greenplum did this several years ago with the Bizgres project; it had a resource control manager which was made available for PostgreSQL core. However, it would have required a large and unpredictable amount of work to make it compatible with OLTP workloads. The problem with centralized resource control is the need for centralized locking on requests for resources. That forces transactions to be serialized in order to make sure resources are not double-allocated. This isn't much of a problem in a DW application, but in a web app with thousands of queries per second it's deadly. Performance engineering for PostgreSQL over the last 7 years has been partly about eliminating centralized locking; we don't want to add new locking. I haven't seen the Greenplum code - how did it actually work? The mechanism I just proposed would (except in the case of an overloaded system) only require holding a lock for long enough to test and update a single integer in shared memory, which doesn't seem like it would cause a serious serialization problem. I might be missing something, or it might suck for lots of other reasons, but if we already know that then let's try to be more specific about what the problems are. That means that a realistic admissions control mechanism would need to operate based on projections and estimates and best effort policies. Not only is this mathematically more complex, it's an open question whether it puts us ahead of where we are now vis-a-vis underallocation of memory. Realistically, a lot of tuning and testing would be required before such a tool was actually an improvement. Before today, that's the only approach I'd ever considered, but this article made me rethink that. If you have a stream of queries that can be run quickly with 1GB of memory and much more slowly with any lesser amount, the only sensible thing to do is wait until there's a GB of memory available for you to grab. What projection or estimate of best effort would arrive at even approximately the same result? Or, to put it another way: the poor man's admission control is a waste of time because it doesn't actually help performance. We're basically facing doing the hard version, or not bothering. I think it's an oversimplification to group all approaches as easy and hard, and even more of an oversimplification to say that all of the easy ones suck. -- Robert Haas EnterpriseDB: http://www.enterprisedb.com The Enterprise Postgres 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] Admission Control
On Fri, Jun 25, 2010 at 3:52 PM, Kevin Grittner kevin.gritt...@wicourts.gov wrote: Heck, I think an even *more* trivial admission control policy which limits the number of active database transactions released to execution might solve a lot of problems. That wouldn't have any benefit over what you can already do with a connection pooler, though, I think. In fact, it would probably be strictly worse, since enlarging the number of backends slows the system down even if they aren't actually doing anything much. Of course, what you propose is more useful, although I'd be inclined to think that we'd want an admission control layer which could be configured so support both of these and much more. Done correctly, it could almost completely eliminate the downward slope after you hit the knee in many performance graphs. And world peace! -- Robert Haas EnterpriseDB: http://www.enterprisedb.com The Enterprise Postgres Company -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
[HACKERS] simplifying emode_for_corrupt_record
On Mon, Jun 14, 2010 at 10:08 AM, Tom Lane t...@sss.pgh.pa.us wrote: Bruce Momjian br...@momjian.us writes: Magnus Hagander wrote: It means that we can't prevent people from configuring their tools to ignore important warning. We can't prevent them rom ignoring ERROR or FATAL either... My point is that most tools are going to look at the tag first to determine the severity of the message, and might even have log_min_messages set to ignore warnings. Why is this discussion based on the idea that we have to cater to incorrectly written log-filtering apps? The correct log level for this message is LOG. End of discussion. I spend a little bit of time analyzing this today and it appears to me that all of the calls to emode_for_corrupt_record() arrive via ReadRecord(), which itself takes an emode argument that is always passed by the caller as either LOG or PANIC. Therefore, the effect of the first if test in emode_for_corrupt_record() is to reduce the logging level of messages coming from SR or the archive from LOG to WARNING. (WARNING would be higher in an interactive session, but not here, per Tom's point.) This seems clearly a bad idea, so I propose to rip it out, which simplifies this function considerably. Proposed patch attached. I wasn't totally sure what to do about the comments. Assuming this change makes sense, there is still the question of bounding the number of retries and eventually falling down hard, but that's really a separate issue and I'll write a separate email about it when I get my thoughts together. -- Robert Haas EnterpriseDB: http://www.enterprisedb.com The Enterprise Postgres Company simplify_emode_for_corrupt_record.patch Description: Binary data -- 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] Admission Control
Robert Haas robertmh...@gmail.com wrote: Kevin Grittner kevin.gritt...@wicourts.gov wrote: Heck, I think an even *more* trivial admission control policy which limits the number of active database transactions released to execution might solve a lot of problems. That wouldn't have any benefit over what you can already do with a connection pooler, though, I think. In fact, it would probably be strictly worse, since enlarging the number of backends slows the system down even if they aren't actually doing anything much. Agreed -- *if* the connection pool is on another computer. Otherwise it'll probably consume about he same resources on the same machine as what I'm proposing, only with more setup and configuration involved. Until we build a connection pooler into the base product, though, you know what an uphill battle it is to get people to control contention that way. We can usually get someone to tweak a GUC when they report a problem, and maybe the tuning tools could start to take core count and effective spindle count into consideration and suggest a good setting for this, if we had it. With the right connection pooler built in to core, though, this one could go right out the window, and they could tune at that layer instead. [thinks] Actually, the transaction count limit doesn't need the planner to run first, so it could be considered part of the first-tier admission control. Essentially, it *would be* a simple but effective built-in connection pooler. I still think an execution admission controller would be worthwhile, but the policy I proposed doesn't belong there; it might be the subject of a pretty simple patch which might solve a lot of performance problems. Gotta sleep on that -Kevin -- 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] GSoC - code of implementation of materialized views
On http://github.com/pbaros/postgres can be seen changes and my attempt to implement materialized views. The first commit to the repository implements following: Materialized view can be created, dropped and used in SELECT statement. CREATE MATERIALIZED VIEW mvname AS SELECT ...; DROP MATERIALIZED VIEW mvname [CASCADE]; SELECT * FROM mvname; also works: COMMENT ON MATERIALIZED VIEW mvname IS 'etc.'; SELECT pg_get_viewdef(mvname); ... also you can look at enclosed patch. *** ./src/backend/access/common/reloptions.c.orig 2010-06-23 16:31:24.0 +0200 --- ./src/backend/access/common/reloptions.c 2010-06-25 13:51:58.0 +0200 *** *** 775,780 --- 775,781 switch (classForm-relkind) { case RELKIND_RELATION: + case RELKIND_MATVIEW: case RELKIND_TOASTVALUE: case RELKIND_UNCATALOGED: options = heap_reloptions(classForm-relkind, datum, false); *** *** 1172,1177 --- 1173,1179 } return (bytea *) rdopts; case RELKIND_RELATION: + case RELKIND_MATVIEW: return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); default: /* sequences, composite types and views are not supported */ *** ./src/backend/access/heap/heapam.c.orig 2010-06-23 16:31:24.0 +0200 --- ./src/backend/access/heap/heapam.c 2010-06-25 13:52:55.0 +0200 *** *** 1877,1883 * Note: below this point, heaptup is the data we actually intend to store * into the relation; tup is the caller's original untoasted data. */ ! if (relation-rd_rel-relkind != RELKIND_RELATION) { /* toast table entries should never be recursively toasted */ Assert(!HeapTupleHasExternal(tup)); --- 1877,1884 * Note: below this point, heaptup is the data we actually intend to store * into the relation; tup is the caller's original untoasted data. */ ! if (relation-rd_rel-relkind != RELKIND_RELATION ! relation-rd_rel-relkind != RELKIND_MATVIEW) { /* toast table entries should never be recursively toasted */ Assert(!HeapTupleHasExternal(tup)); *** ./src/backend/catalog/dependency.c.orig 2010-06-23 16:31:25.0 +0200 --- ./src/backend/catalog/dependency.c 2010-06-25 13:53:46.0 +0200 *** *** 2731,2736 --- 2731,2740 appendStringInfo(buffer, _(view %s), relname); break; + case RELKIND_MATVIEW: + appendStringInfo(buffer, _(materialized view %s), + relname); + break; case RELKIND_COMPOSITE_TYPE: appendStringInfo(buffer, _(composite type %s), relname); *** ./src/backend/catalog/heap.c.orig 2010-06-23 16:31:25.0 +0200 --- ./src/backend/catalog/heap.c 2010-06-25 13:54:25.0 +0200 *** *** 758,763 --- 758,764 case RELKIND_RELATION: case RELKIND_INDEX: case RELKIND_TOASTVALUE: + case RELKIND_MATVIEW: /* The relation is real, but as yet empty */ new_rel_reltup-relpages = 0; new_rel_reltup-reltuples = 0; *** *** 776,782 /* Initialize relfrozenxid */ if (relkind == RELKIND_RELATION || ! relkind == RELKIND_TOASTVALUE) { /* * Initialize to the minimum XID that could put tuples in the table. --- 777,784 /* Initialize relfrozenxid */ if (relkind == RELKIND_RELATION || ! relkind == RELKIND_TOASTVALUE || ! relkind == RELKIND_MATVIEW) { /* * Initialize to the minimum XID that could put tuples in the table. *** *** 1027,1032 --- 1029,1035 */ if (IsUnderPostmaster (relkind == RELKIND_RELATION || relkind == RELKIND_VIEW || + relkind == RELKIND_MATVIEW || relkind == RELKIND_COMPOSITE_TYPE)) new_array_oid = AssignTypeArrayOid(); *** ./src/backend/catalog/system_views.sql.orig 2010-06-23 16:31:25.0 +0200 --- ./src/backend/catalog/system_views.sql 2010-06-25 13:55:24.0 +0200 *** *** 76,82 pg_get_userbyid(C.relowner) AS viewowner, pg_get_viewdef(C.oid) AS definition FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace) ! WHERE C.relkind = 'v'; CREATE VIEW pg_tables AS SELECT --- 76,82 pg_get_userbyid(C.relowner) AS viewowner, pg_get_viewdef(C.oid) AS definition FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace) ! WHERE C.relkind = 'v' OR C.relkind = 'm'; CREATE VIEW pg_tables AS SELECT *** ./src/backend/commands/comment.c.orig 2010-06-23 16:31:25.0 +0200 --- ./src/backend/commands/comment.c 2010-06-25 13:58:10.0 +0200 *** *** 107,112 --- 107,113 case OBJECT_SEQUENCE: case OBJECT_TABLE: case OBJECT_VIEW: + case OBJECT_MATVIEW: CommentRelation(stmt-objtype, stmt-objname, stmt-comment); break; case OBJECT_COLUMN: *** *** 580,585 --- 581,593 errmsg(\%s\ is not a view,
Re: [HACKERS] testing plpython3u on 9.0beta2
On Wednesday 23 June 2010 16:30:54 Tom Lane wrote: Robert Haas robertmh...@gmail.com writes: I can reproduce this, here. The problem seems to be that plpython only build either plpython2.so or plython3.so, but both languages expect a call handler called plython_call_handler. So once we load the shared library for one language, the other language just grabs the same call handler. We had better fix that --- I can definitely foresee installations wanting to use both plpython2 and plpython3. This'd require a change in the default contents of pg_pltemplate, though. Does it seem important enough to bump catversion for? Has anybody actually researched if it is safe to run python2 and python3 in the same address space? I wouldnt be surprised at all if that where problematic. Andres -- 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] testing plpython3u on 9.0beta2
On fre, 2010-06-25 at 23:44 +0200, Andres Freund wrote: Has anybody actually researched if it is safe to run python2 and python3 in the same address space? You can't run plpython2 and plpython3 in the same session, because the libraries are loaded with dlopen(RTLD_GLOBAL) (with RTLD_LOCAL it would apparently work). But you can use them in different sessions on the same database, for example. -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: parallelizing subplan execution (was: [HACKERS] explain and PARAM_EXEC)
Hi all, Sorry for jumping in over 4 months later... On Sat, Feb 20, 2010 at 8:25 PM, Robert Haas robertmh...@gmail.com wrote: On Sat, Feb 20, 2010 at 8:31 AM, Dimitri Fontaine dfonta...@hi-media.com wrote: This is really a topic for another thread, but at 100,000 feet it seems to me that the hardest question is - how will you decide which operations to parallelize in the first place? Actually making it happen is really hard, too, of course, but even to get that that point you have to have some model for what types of operations it makes sense to parallelize and how you're going to decide when it's a win. My naive thoughts would be to add some cost parameters. The fact to fork() another backend first, then model for each supported subplan (we will want to add more, or maybe have a special rendez-vous-materialise node) some idea of the data exchange cost. Now the planner would as usual try to find the less costly plan, and will be able to compare plans with and without distributing the work. Overly naive ? Probably. For one thing, you can't use fork(), because it won't work on Windows. It seems to me that you need to start by thinking about what kinds of queries could be usefully parallelized. What I think you're proposing here, modulo large amounts of hand-waving, is that we should basically find a branch of the query tree, cut it off, and make that branch the responsibility of a subprocess. What kinds of things would be sensible to hand off in this way? Well, you'd want to find nodes that are not likely to be repeatedly re-executed with different parameters, like subplans or inner-indexscans, because otherwise you'll get pipeline stalls handing the new parameters back and forth. And you want to find nodes that are expensive for the same reason. So maybe this would work for something like a merge join on top of two sorts - one backend could perform each sort, and then whichever one was the child would stream the tuples to the parent for the final merge. Of course, this assumes the I/O subsystem can keep up, which is not a given - if both tables are fed by the same, single spindle, it might be worse than if you just did the sorts consecutively. This approach might also benefit queries that are very CPU-intensive, on a multi-core system with spare cycles. Suppose you have a big tall stack of hash joins, each with a small inner rel. The child process does about half the joins and then pipelines the results into the parent, which does the other half and returns the results. But there's at least one other totally different way of thinking about this problem, which is that you might want two processes to cooperate in executing the SAME query node - imagine, for example, a big sequential scan with an expensive but highly selective filter condition, or an enormous sort. You have all the same problems of figuring out when it's actually going to help, of course, but the details will likely be quite different. I'm not really sure which one of these would be more useful in practice - or maybe there are even other strategies. What does $COMPETITOR do? I feel that the answer is it depends. To partially answer what others are doing, I'll present some papers from someone we might recognize as a starting point. :) http://pages.cs.wisc.edu/~dewitt/includes/publications.html Some of these papers aren't the type of parallelism we're talking about here, but the ones that I think are relevant talk mostly about parallelizing hash based joins. I think we might be lacking an operator or two though in order to do some of these things. I'm also ignoring the difficulties of getting hold of a second backend in the right state - same database, same snapshot, etc. It seems to me unlikely that there are a substantial number of real-world applications for which this will not work very well if we have to actually start a new backend every time we want to parallelize a query. IOW, we're going to need, well, a connection pool in core. *ducks, runs for cover* Do we think it's worth proofing that we can execute a plan in parallel? Something simple, if not the best case, say a nested loop join between two tables? Just as a starting point before worrying too much about what is the best thing to parallelize, or how the degree of parallelism will be controller? Regards, Mark -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers