Re: [HACKERS] patch: Add columns via CREATE OR REPLACE VIEW

2008-08-08 Thread Asko Oja
ALTER VIEW does not sound useful for me.
CREATE OR REPLACE VIEW should create or replace view and only thing that
should be same is the name of the view. It's up to Postgres to invalidate
all plans and up to developer to make sure that all places where his view is
used will stay still working. All this discussion about matching up columns
and AI seems totally useless to me :)

On Fri, Aug 8, 2008 at 4:41 AM, Robert Haas [EMAIL PROTECTED] wrote:

  Well, my feeling is that if we are inventing a new feature we ought not
  paint ourselves into a corner by failing to consider what will happen
  when obvious extensions to the feature are attempted.  Whether the
  present patch is self-consistent is not the question --- the question
  is do we have a self-consistent vision of how we will later do the
  other stuff like renaming, changing column type, etc.

 If we can work out that design, I think that's great.  However, it
 doesn't actually 100% matter whether we know the one true way that we
 will definitely implement those features - it only matters that none
 of the things we might choose are inconsistent with what we're doing
 now.

 In order to avoid being AI-complete, REPLACE VIEW needs some kind of
 straightforward algorithm for matching up the old and new target
 lists.  AFAICS, the only thing to decide here is what you want to use
 as the key.  There are three possibilities that I can think of: [1]
 name, [2] position, [3] both name and position.

 It's axiomatic that REPLACE VIEW can't be given the capability to make
 any modification that involves changing the key field, so in [1] you
 can't rename columns, in [2] you can't reorder columns, and in [3] you
 can't do either.  Furthermore, in [2], you also can't support dropping
 columns, because a drop is indistinguishable from renaming and
 retyping every column from the point of the drop onwards.  Therefore,
 the maximum set of operations REPLACE VIEW can potentially support in
 each scenario are:

 [1] add column, change type, drop column, reorder columns
 [2] add column, change type, rename
 [3] add column, change type, drop column

 The actual set of operations supported may be less either because of
 implementation limitations or because you don't want to provide users
 with a foot-gun.  ISTM that allowing REPLACE VIEW to do renames in
 scenario [2] can be pretty much rejected outright as a violation of
 the principle of least surprise - there is an enormous danger of
 someone simultaneously renaming and retyping a whole series of columns
 when they instead intended to drop a column.  Similarly, in scenario
 [1] or [3], ISTM that allowing someone to drop columns using REPLACE
 VIEW is something of a foot-gun unless we are in scenario [1] and
 reordering columns is also implemented, because users who don't RTFM
 will try to reorder columns and it will succeed and fail erratically
 according to whether there are dependencies that prevent dropping and
 re-adding whatever subset of columns need to be shuffled to create the
 same effect as would be produced by reordering.  However, in any
 scenario, I can't see how adding columns or changing column types is
 likely to produce any confusion or user-unexpected behavior.  Perhaps
 I'm missing something?

 Personally, I favor scenario [1].  I hardly ever rename database
 columns, and I don't mind needing to ALTER VIEW RENAME COLUMN on those
 rare occasions when I do, but I add new columns to my tables (which
 then also need to be added to my views) on a regular basis.  If I
 could keep groups of related columns together in the table and view
 definitions without having to drop and recreate the objects, that
 would be awesome.  But I'm not sure it's worth the amount of
 implementation that would be required to get there, especially if all
 of that implementation would need to be done by me (and
 double-especially if none of it would likely be included in -core).

 Of course, as I said before, nothing we do in REPLACE VIEW precludes
 having a powerful implementation of ALTER VIEW.  But I think the
 coding to make ALTER VIEW do these operations is a lot trickier,
 because you have to deal with modifying the query that's already in
 place piecemeal as you make your changes to the view.  It's not that
 it can't be done, but I doubt it can be done in an 8K patch, and as
 mentioned upthread, it certainly can't be done in a fully general
 way... you will still frequently need to CREATE OR REPLACE VIEW
 afterwards.  To put that another way, ALTER TABLE is a complicated
 beast because you have to worry about how you're going to handle the
 existing data, and ALTER VIEW will be a complicated beast for the
 analogous reason that you need to worry about handing the existing
 rewrite rule.  But at the moment when a REPLACE VIEW command is
 executed, that problem goes away, because now you have the query in
 your hand and just need to make the relation match it without breaking
 any of the dependencies.

 ...Robert

 --

Re: [HACKERS] Parsing of pg_hba.conf and authentication inconsistencies

2008-08-08 Thread Magnus Hagander
Stephen Frost wrote:
 Magnus,
 
 * Magnus Hagander ([EMAIL PROTECTED]) wrote:
 I thought of another issue with this. My grand plan includes being
 able to do username mapping (per pg_ident.conf) for other authentication
 methods than ident. Specifically this would be interesting for all
 external methods, like gssapi/sspi/kerberos/ldap. I was originally
 planning to allow each row in pg_hba to specify it's own pg_ident.conf
 if necessary (so you could map LDAP and GSSAPI differently, for example,
 or map two different kerberos realms differently). To be able to load
 these, the postmaster would need to know about them, which means it'd
 have to parse that data out anyway.
 
 I certainly like the concept of having them be in seperate files.
 
 The other way to do that is to simply say that all external mapping will
 use pg_ident.conf, and the only thing you can specify on a per-row basis
 is use map: yes or no. This decreases the flexibility, but would not
 require the postmaster to do the parsing.
 
 I don't think it makes sense to have multiple different auth types using
 the same mappings...  For Kerberos, as an example, we should support
 [EMAIL PROTECTED] as an option for the mapping, but that might not make sense
 for LDAP, which might have cn=User,ou=people,dc=example,dc=com, and
 neither of those really make sense for ident.  Mashing all of those
 together would make each auth type supporting the mapping have to search
 through the list trying to make sense of some mappings and throwing away
 others, just ugly all around..

Yeah. I think the question there is just - how likely is it that the
same installation actually uses 1 authentication method. Personally, I
think it's not very uncommon at all, but fact remains that as long as
you only use one of them at a time, using a shared file doesn't matter.


 What do people think about these? I know Stephen for example really want
 that feature so - would that restriction make it a lot less useful for you?
 
 If we really wanted to keep it to a single *file*, then I think there
 should be a way to key rows in the pg_hba.conf to sets-of-rows in the
 mapping file.  eg: have an option of 'mapkey=xyz' in pg_hba, and then
 'xyz' as the first column of the mapping file, with it being repeated
 across rows to form that mapping table.

Yuck. Honestly, that seems even uglier :-)


 It wouldn't be very easy/clean to do that w/o breaking the existing
 structure of pg_ident though, which makes me feel like using seperate
 files is probably the way to go.

Yeah, thats my feeling as well. Now, can someone figure out a way to do
that without parsing the file in the postmaster? (And if we do parse it,
there's no point in not storing the parsed version, IMHO). And if not,
the question it comes down to is which is most important - keeping the
parsing away, or being able to do this ;-)


//Magnus

-- 
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] patch: Add columns via CREATE OR REPLACE VIEW

2008-08-08 Thread Zeugswetter Andreas OSB sIT

 If you accept the idea that column identity should be based on column
 name, then the only two operations that are really necessary are
 CREATE OR REPLACE VIEW and ALTER VIEW RENAME COLUMN, and it is
 100% clear what the semantics of those operations should be.

+1

I think this would be an easily useable and understandable concept.
I also fully support Robert's reasoning in his next reply to Tom,
detailing why his patch's provided functionality is acceptable.

Andreas

PS: alter view in O does not change the base definition,
it only allows modifying view constraints.

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


[HACKERS] Oprofile with postgresql

2008-08-08 Thread [EMAIL PROTECTED]
Hi all:

  Recently i do a test of postgresql. To get more information of the
functions in PostgreSQL, i use

opgprof and opannotate, which are two tools in Oprofile. But i can't work
with the tools correctly.

PostgreSQL is compiled with -g option and the errors are like this:

 opgprof error: parse_filename() invalid filename:
/var/lib/oprofile/samples/current/{root}/var/lib/oprofile/samples/current/{root}/home/ubuntu/tpcc-uva/bin/tm/{dep}/{anon:[vdso]}/7208.0x7fff7a972000.0x7fff7a974000/CPU_CLK_UNHALTED.9.0.all.all.all/{dep}/{root}/var/lib/oprofile/samples/current/{root}/home/ubuntu/tpcc-uva/bin/tm/{dep}/{anon:[vdso]}/7208.0x7fff7a972000.0x7fff7a974000/CPU_CLK_UNHALTED.9.0.all.all.all/{cg}/{root}/usr/bin/oprofiled/CPU_CLK_UNHALTED.9.0.all.all.all

and opannotate

warning: [heap] (tgid:7302 range:0x8e7000-0xa18000) could not be found.
warning: [vdso] (tgid:7295 range:0x7fff3ddfe000-0x7fff3de0) could not be
found.
warning: [vdso] (tgid:7296 range:0x7fff3ddfe000-0x7fff3de0) could not be
found.
warning: [vdso] (tgid:7297 range:0x7fff3ddfe000-0x7fff3de0) could not be
found.
warning: [vdso] (tgid:7298 range:0x7fff3ddfe000-0x7fff3de0) could not be
found.
warning: [vdso] (tgid:7299 range:0x7fff3ddfe000-0x7fff3de0) could not be
found.
warning: [vdso] (tgid:7300 range:0x7fff3ddfe000-0x7fff3de0) could not be
found.
warning: [vdso] (tgid:7301 range:0x7fff3ddfe000-0x7fff3de0) could not be
found.
warning: [vdso] (tgid:7302 range:0x7fff3ddfe000-0x7fff3de0) could not be
found.
opannotate (warning): unable to open for reading: aset.c
opannotate (warning): unable to open for reading: heaptuple.c
opannotate (warning): unable to open for reading: bufmgr.c
opannotate (warning): unable to open for reading: execQual.c
opannotate (warning): unable to open for reading: list.c
opannotate (warning): unable to open for reading: nbtree.c
opannotate (warning): unable to open for reading: fmgr.c
opannotate (warning): unable to open for reading: catcache.c
opannotate (warning): unable to open for reading: nodeIndexscan.c
opannotate (warning): unable to open for reading: clauses.c
opannotate (warning): unable to open for reading: ri_triggers.c
opannotate (warning): unable to open for reading: lock.c
opannotate (warning): unable to open for reading: planner.c
opannotate (warning): unable to open for reading: selfuncs.c
opannotate (warning): unable to open for reading: postgres.c
opannotate (warning): unable to open for reading: trigger.c
...


if i want to use the two tools on PostgreSQL , what should i do?


Best wishes

  Yyan


Re: [HACKERS] For what should pg_stop_backup wait?

2008-08-08 Thread Simon Riggs

On Fri, 2008-08-08 at 11:47 +0900, Fujii Masao wrote:
 On Thu, Aug 7, 2008 at 11:34 PM, Simon Riggs [EMAIL PROTECTED] wrote:
 

 In this situation, the history file (00010004.0020.backup)
 is behind the stoppoint (00010004) in the alphabetic order.
 So, pg_stop_backup should wait for both the stoppoint and the history
 file, I think.

OK, I see that now.

 
  !   while (!XLogArchiveCheckDone(stopxlogfilename, false))
 
 If a concurrent checkpoint removes the status file before 
 XLogArchiveCheckDone,
 pg_stop_backup continues waiting forever. This is undesirable behavior.

I think it will only get removed by the second checkpoint, not the
first. So the risk of that happening seems almost certainly impossible.
But we'll put in a check just in case.

 Yes, statement_timeout may help. But, I don't want to use it, because the
 *successful* backup is canceled.
 
 How about checking whether the stoppoint was archived by comparing with
 the last WAL archived. The archiver process can tell the last WAL archived.
 Or, we can calculate it from the status file.

I think its easier to test whether the stopxlogfilename still exists in
pg_xlog. If not, we know it has been archived away. We can add that as
an extra condition inside the loop.

So thinking we should test XLogArchiveCheckDone() for both
stopxlogfilename and history file and then stat for the stop WAL file:



BackupHistoryFileName(histfilepath, ThisTimeLineID, _logId, _logSeg,
  startpoint.xrecoff % 
XLogSegSize);

seconds_before_warning = 60;
waits = 0;

while (!XLogArchiveCheckDone(histfilepath, false) || 
   !XLogArchiveCheckDone(stopxlogfilename, false))
{
struct stat stat_buf;
charxlogpath[MAXPGPATH];

/*
 * Check to see if file has already been archived and WAL file
 * removed by a concurrent checkpoint
 */
snprintf(xlogpath, MAXPGPATH, XLOGDIR /%s, stopxlogfilename);
if (XLogArchiveCheckDone(histfilepath, false) 
stat(xlogpath, stat_buf) != 0)
break;

CHECK_FOR_INTERRUPTS();

pg_usleep(100L);

if (++waits = seconds_before_warning)
{
seconds_before_warning *= 2; /* This wraps in 10 
years... */
elog(WARNING, pg_stop_backup() waiting for archive to 
complete  
(%d seconds delay), 
waits);
}
}


-- 
 Simon Riggs   www.2ndQuadrant.com
 PostgreSQL Training, Services and Support


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


[HACKERS] Verbosity of Function Return Type Checks

2008-08-08 Thread Volkan YAZICI
Hi,

Yesterday I needed to fiddle with PostgreSQL internals to be able to
debug a PL/pgSQL procedure returning a set of records. I attached the
patch I used to increase the verbosity of error messages related with
function return type checks. I'll be appreciated if any developer could
commit this patch (or a similar one) into the core.


Regards.

Index: src/pl/plpgsql/src/pl_exec.c
===
RCS file: /projects/cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v
retrieving revision 1.216
diff -u -r1.216 pl_exec.c
--- src/pl/plpgsql/src/pl_exec.c	16 May 2008 18:34:51 -	1.216
+++ src/pl/plpgsql/src/pl_exec.c	8 Aug 2008 11:52:02 -
@@ -190,7 +190,7 @@
 	   Oid reqtype, int32 reqtypmod,
 	   bool isnull);
 static void exec_init_tuple_store(PLpgSQL_execstate *estate);
-static bool compatible_tupdesc(TupleDesc td1, TupleDesc td2);
+static void validate_tupdesc_compat(TupleDesc td1, TupleDesc td2);
 static void exec_set_found(PLpgSQL_execstate *estate, bool state);
 static void plpgsql_create_econtext(PLpgSQL_execstate *estate);
 static void free_var(PLpgSQL_var *var);
@@ -386,11 +386,12 @@
 			{
 case TYPEFUNC_COMPOSITE:
 	/* got the expected result rowtype, now check it */
-	if (estate.rettupdesc == NULL ||
-		!compatible_tupdesc(estate.rettupdesc, tupdesc))
+	if (!estate.rettupdesc)
 		ereport(ERROR,
 (errcode(ERRCODE_DATATYPE_MISMATCH),
- errmsg(returned record type does not match expected record type)));
+ errmsg(returned record type does not match 
+		expected record type)));
+	validate_tupdesc_compat(tupdesc, estate.rettupdesc);
 	break;
 case TYPEFUNC_RECORD:
 
@@ -707,11 +708,8 @@
 		rettup = NULL;
 	else
 	{
-		if (!compatible_tupdesc(estate.rettupdesc,
-trigdata-tg_relation-rd_att))
-			ereport(ERROR,
-	(errcode(ERRCODE_DATATYPE_MISMATCH),
-	 errmsg(returned tuple structure does not match table of trigger event)));
+		validate_tupdesc_compat(trigdata-tg_relation-rd_att,
+estate.rettupdesc);
 		/* Copy tuple to upper executor memory */
 		rettup = SPI_copytuple((HeapTuple) DatumGetPointer(estate.retval));
 	}
@@ -2202,10 +2200,7 @@
 		   errmsg(record \%s\ is not assigned yet,
   rec-refname),
 		   errdetail(The tuple structure of a not-yet-assigned record is indeterminate.)));
-	if (!compatible_tupdesc(tupdesc, rec-tupdesc))
-		ereport(ERROR,
-(errcode(ERRCODE_DATATYPE_MISMATCH),
-		errmsg(wrong record type supplied in RETURN NEXT)));
+	validate_tupdesc_compat(rec-tupdesc, tupdesc);
 	tuple = rec-tup;
 }
 break;
@@ -2311,10 +2306,7 @@
 		   stmt-params);
 	}
 
-	if (!compatible_tupdesc(estate-rettupdesc, portal-tupDesc))
-		ereport(ERROR,
-(errcode(ERRCODE_DATATYPE_MISMATCH),
-		  errmsg(structure of query does not match function result type)));
+	validate_tupdesc_compat(portal-tupDesc, estate-rettupdesc);
 
 	while (true)
 	{
@@ -5138,23 +5130,32 @@
 }
 
 /*
- * Check two tupledescs have matching number and types of attributes
+ * Validates compatibility of supplied TupleDesc's by checking # and type of
+ * available arguments.
  */
-static bool
-compatible_tupdesc(TupleDesc td1, TupleDesc td2)
+static void
+validate_tupdesc_compat(TupleDesc td1, TupleDesc td2)
 {
-	int			i;
+	int i;
 
 	if (td1-natts != td2-natts)
-		return false;
+		ereport(ERROR,
+(errcode(ERRCODE_DATATYPE_MISMATCH),
+ errmsg(Number of returned columns (%d) does not match 
+		expected column count (%d).,
+	td1-natts, td2-natts)));
 
 	for (i = 0; i  td1-natts; i++)
-	{
 		if (td1-attrs[i]-atttypid != td2-attrs[i]-atttypid)
-			return false;
-	}
-
-	return true;
+			ereport(ERROR,
+	(errcode(ERRCODE_DATATYPE_MISMATCH),
+	 errmsg(Returned record type (%s) does not match 
+			expected record type (%s) in column %d (%s).,
+			format_type_with_typemod(td1-attrs[i]-atttypid,
+ td1-attrs[i]-atttypmod),
+			format_type_with_typemod(td2-attrs[i]-atttypid,
+	 td2-attrs[i]-atttypmod),
+			(1+i), NameStr(td2-attrs[i]-attname;
 }
 
 /* --

-- 
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] patch: Add columns via CREATE OR REPLACE VIEW

2008-08-08 Thread Tom Lane
Zeugswetter Andreas OSB sIT [EMAIL PROTECTED] writes:
 If you accept the idea that column identity should be based on column
 name, then the only two operations that are really necessary are
 CREATE OR REPLACE VIEW and ALTER VIEW RENAME COLUMN, and it is
 100% clear what the semantics of those operations should be.

 +1

It's nice, it's simple, and it's unimplementable.  At least not without
huge changes in the representation of stored views, which would likely
lead to failure to follow spec-required behavior in other ways.  Other
views are going to refer to the columns of this one by *number*, not
name, and it's not clear to me how you're going to preserve column
number identity with this approach.

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] For what should pg_stop_backup wait?

2008-08-08 Thread Simon Riggs

On Fri, 2008-08-08 at 12:57 +0100, Simon Riggs wrote:

  Yes, statement_timeout may help. But, I don't want to use it, because the
  *successful* backup is canceled.
  
  How about checking whether the stoppoint was archived by comparing with
  the last WAL archived. The archiver process can tell the last WAL archived.
  Or, we can calculate it from the status file.
 
 I think its easier to test whether the stopxlogfilename still exists in
 pg_xlog. If not, we know it has been archived away. We can add that as
 an extra condition inside the loop.
 
 So thinking we should test XLogArchiveCheckDone() for both
 stopxlogfilename and history file and then stat for the stop WAL file:

This seems better.

-- 
 Simon Riggs   www.2ndQuadrant.com
 PostgreSQL Training, Services and Support
Index: src/backend/access/transam/xlog.c
===
RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/backend/access/transam/xlog.c,v
retrieving revision 1.316
diff -c -r1.316 xlog.c
*** src/backend/access/transam/xlog.c	13 Jul 2008 20:45:47 -	1.316
--- src/backend/access/transam/xlog.c	8 Aug 2008 13:56:40 -
***
*** 1165,1170 
--- 1165,1184 
  	/* Retry creation of the .ready file */
  	if (create_if_missing)
  		XLogArchiveNotify(xlog);
+ 	else
+ 	{
+ 		char xlogpath[MAXPGPATH];
+ 
+ 		snprintf(xlogpath, MAXPGPATH, XLOGDIR /%s, xlog);
+ 
+ 		/*
+ 		 * Check to see if the WAL file has been removed by checkpoint, 
+ 		 * which implies it has already been archived, and explains why we
+ 		 * can't see a status file for it.
+ 		 */
+ 		if (stat(xlogpath, stat_buf) != 0)
+ 			return true;
+ 	}
  
  	return false;
  }
***
*** 6721,6735 
  	CleanupBackupHistory();
  
  	/*
! 	 * Wait until the history file has been archived. We assume that the 
! 	 * alphabetic sorting property of the WAL files ensures the last WAL
! 	 * file is guaranteed archived by the time the history file is archived.
  	 *
  	 * We wait forever, since archive_command is supposed to work and
  	 * we assume the admin wanted his backup to work completely. If you 
  	 * don't wish to wait, you can SET statement_timeout = xx;
  	 *
! 	 * If the status file is missing, we assume that is because it was
  	 * set to .ready before we slept, then while asleep it has been set
  	 * to .done and then removed by a concurrent checkpoint.
  	 */
--- 6735,6748 
  	CleanupBackupHistory();
  
  	/*
! 	 * Wait until both the last WAL file filled during backup and the
! 	 * history file have been archived.
  	 *
  	 * We wait forever, since archive_command is supposed to work and
  	 * we assume the admin wanted his backup to work completely. If you 
  	 * don't wish to wait, you can SET statement_timeout = xx;
  	 *
! 	 * If the status files are missing, we assume that is because it was
  	 * set to .ready before we slept, then while asleep it has been set
  	 * to .done and then removed by a concurrent checkpoint.
  	 */
***
*** 6739,6745 
  	seconds_before_warning = 60;
  	waits = 0;
  
! 	while (!XLogArchiveCheckDone(histfilepath, false))
  	{
  		CHECK_FOR_INTERRUPTS();
  
--- 6752,6759 
  	seconds_before_warning = 60;
  	waits = 0;
  
! 	while (!XLogArchiveCheckDone(histfilepath, false) || 
! 		   !XLogArchiveCheckDone(stopxlogfilename, false))
  	{
  		CHECK_FOR_INTERRUPTS();
  

-- 
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] Oprofile with postgresql

2008-08-08 Thread Tom Lane
=?GB2312?B?tN7R0mNjdWl5eWFuQHNpbmEuY29t?= [EMAIL PROTECTED] writes:
 Hi all:
   Recently i do a test of postgresql. To get more information of the
 functions in PostgreSQL, i use

 opgprof and opannotate, which are two tools in Oprofile. But i can't work
 with the tools correctly.

I think you need to read the oprofile documentation a bit more and
possibly contact an oprofile mailing list for help.  This isn't a
Postgres-related question.

FWIW, I've used oprofile many times with postgres; it works as expected.
I'd be the first to agree it's got a steep learning curve though.

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] Parsing of pg_hba.conf and authentication inconsistencies

2008-08-08 Thread Stephen Frost
Magnus,

* Magnus Hagander ([EMAIL PROTECTED]) wrote:
 Yeah. I think the question there is just - how likely is it that the
 same installation actually uses 1 authentication method. Personally, I
 think it's not very uncommon at all, but fact remains that as long as
 you only use one of them at a time, using a shared file doesn't matter.

We use multiple authentication types *alot*..  ident, md5, kerberos, and
gssapi are all currently in use on our systems.  ident for local unix
logins, md5 for 'role' accounts and software the doesn't understand
kerberos, kerberos/gssapi depending on the age of the client library
connecting.  Oh, and we use pam too..  We use some mappings now with
ident, which I'd expect to continue to do, and I've got definite plans
for mappings under Kerberos/GSSAPI once it's supported..

  It wouldn't be very easy/clean to do that w/o breaking the existing
  structure of pg_ident though, which makes me feel like using seperate
  files is probably the way to go.
 
 Yeah, thats my feeling as well. Now, can someone figure out a way to do
 that without parsing the file in the postmaster? (And if we do parse it,
 there's no point in not storing the parsed version, IMHO). And if not,
 the question it comes down to is which is most important - keeping the
 parsing away, or being able to do this ;-)

I don't have an answer wrt the parsing issue, but I definitely want to
be able to do this. :)

Thanks,

Stephen


signature.asc
Description: Digital signature


Re: [HACKERS] Verbosity of Function Return Type Checks

2008-08-08 Thread Alvaro Herrera
Volkan YAZICI wrote:

 Yesterday I needed to fiddle with PostgreSQL internals to be able to
 debug a PL/pgSQL procedure returning a set of records. I attached the
 patch I used to increase the verbosity of error messages related with
 function return type checks. I'll be appreciated if any developer could
 commit this patch (or a similar one) into the core.

I think this is a good idea, but the new error messages need more work.
Have a look at the message style guidelines please,
http://www.postgresql.org/docs/8.3/static/error-style-guide.html

Particularly I think you need to keep the original errmsg() and add the
new messages as errdetail().  (I notice that there's the slight problem
that the error messages are different for the different callers.)

Also, please use context diffs.

-- 
Alvaro Herrerahttp://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support

-- 
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] CommitFest July Over

2008-08-08 Thread Josh Berkus

Markus,

Maybe it's just me, but I don't quite understand the concept of RRR. If 
I get some spare cycles to review patches, I certainly want to choose 
mysqlf which patch I'm going to review. Why is the CF Manager doing any 
assignment of patches?


This was actually by request of several reviewers, who said they could 
do something but didn't have a preference which patch to review.


--Josh


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


[HACKERS] autovacuum and TOAST tables

2008-08-08 Thread Alvaro Herrera
Hi,

Here's a patch to make autovacuum process TOAST tables separately from
main tables.

The most important change is that when called from autovac, vacuum does
not process the TOAST table at all.  It will only do so when the stats
for the TOAST table say that it needs vacuuming.  (A user-invoked vacuum
still processes TOAST tables normally.)

Per previous discussion, the autovac code is now doing two passes over
pg_class.

There's two things I'm not happy about in this patch:

1. it uses a List to keep the mapping of heap-toast Oids.  This is
needed to be able to fetch the main rel's pg_autovacuum entry to process
the toast table.  This incurs in O(n^2) behavior.

2. the expected relkind business is gone; it's not easy to pass the
correct relkind down from autovac, and at the same time have a
reasonable thing to pass down from user-invoked vacuum.  Right now what
the patch does is check that the rel to vacuum is either
RELKIND_RELATION or _TOASTVALUE.

(I admit that my unhappiness about the second is mild, though.)

-- 
Alvaro Herrerahttp://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support
Index: src/backend/commands/vacuum.c
===
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/commands/vacuum.c,v
retrieving revision 1.375
diff -c -p -r1.375 vacuum.c
*** src/backend/commands/vacuum.c	5 Jun 2008 15:47:32 -	1.375
--- src/backend/commands/vacuum.c	8 Aug 2008 16:42:02 -
*** static BufferAccessStrategy vac_strategy
*** 213,220 
  static List *get_rel_oids(Oid relid, const RangeVar *vacrel,
  			 const char *stmttype);
  static void vac_truncate_clog(TransactionId frozenXID);
! static void vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind,
! 	   bool for_wraparound);
  static void full_vacuum_rel(Relation onerel, VacuumStmt *vacstmt);
  static void scan_heap(VRelStats *vacrelstats, Relation onerel,
  		  VacPageList vacuum_pages, VacPageList fraged_pages);
--- 213,220 
  static List *get_rel_oids(Oid relid, const RangeVar *vacrel,
  			 const char *stmttype);
  static void vac_truncate_clog(TransactionId frozenXID);
! static void vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast,
! 		   bool for_wraparound);
  static void full_vacuum_rel(Relation onerel, VacuumStmt *vacstmt);
  static void scan_heap(VRelStats *vacrelstats, Relation onerel,
  		  VacPageList vacuum_pages, VacPageList fraged_pages);
*** static Size PageGetFreeSpaceWithFillFact
*** 268,273 
--- 268,276 
   * OID to be processed, and vacstmt-relation is ignored.  (The non-invalid
   * case is currently only used by autovacuum.)
   *
+  * do_toast is passed as FALSE by autovacuum, because it processes TOAST
+  * tables separately.
+  *
   * for_wraparound is used by autovacuum to let us know when it's forcing
   * a vacuum for wraparound, which should not be auto-cancelled.
   *
*** static Size PageGetFreeSpaceWithFillFact
*** 281,287 
   * at transaction commit.
   */
  void
! vacuum(VacuumStmt *vacstmt, Oid relid,
  	   BufferAccessStrategy bstrategy, bool for_wraparound, bool isTopLevel)
  {
  	const char *stmttype = vacstmt-vacuum ? VACUUM : ANALYZE;
--- 284,290 
   * at transaction commit.
   */
  void
! vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast,
  	   BufferAccessStrategy bstrategy, bool for_wraparound, bool isTopLevel)
  {
  	const char *stmttype = vacstmt-vacuum ? VACUUM : ANALYZE;
*** vacuum(VacuumStmt *vacstmt, Oid relid,
*** 433,439 
  			Oid			relid = lfirst_oid(cur);
  
  			if (vacstmt-vacuum)
! vacuum_rel(relid, vacstmt, RELKIND_RELATION, for_wraparound);
  
  			if (vacstmt-analyze)
  			{
--- 436,442 
  			Oid			relid = lfirst_oid(cur);
  
  			if (vacstmt-vacuum)
! vacuum_rel(relid, vacstmt, do_toast, for_wraparound);
  
  			if (vacstmt-analyze)
  			{
*** vac_truncate_clog(TransactionId frozenXI
*** 975,982 
   *		At entry and exit, we are not inside a transaction.
   */
  static void
! vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind,
! 		   bool for_wraparound)
  {
  	LOCKMODE	lmode;
  	Relation	onerel;
--- 978,984 
   *		At entry and exit, we are not inside a transaction.
   */
  static void
! vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound)
  {
  	LOCKMODE	lmode;
  	Relation	onerel;
*** vacuum_rel(Oid relid, VacuumStmt *vacstm
*** 1013,1020 
  		 * by autovacuum; it's used to avoid cancelling a vacuum that was
  		 * invoked in an emergency.
  		 *
! 		 * Note: this flag remains set until CommitTransaction or
! 		 * AbortTransaction.  We don't want to clear it until we reset
  		 * MyProc-xid/xmin, else OldestXmin might appear to go backwards,
  		 * which is probably Not Good.
  		 */
--- 1015,1022 
  		 * by autovacuum; it's used to avoid cancelling a vacuum that was
  

Re: [HACKERS] Proposal of SE-PostgreSQL patches [try#2]

2008-08-08 Thread Josh Berkus

KaiGai Kohei wrote:

On the WiKi of CommitFest:Sep,
  http://wiki.postgresql.org/wiki/CommitFest:2008-09

The entry of SE-PostgreSQL points a message when I submitted older version
of our patch set. But the latest ones are listed on another message.

Please add a link to the following message for our convenience:
  http://archives.postgresql.org/pgsql-hackers/2008-07/msg01365.php


Hey, given the amount of work still to go on this, don't you think you 
should get a wiki account so that you can add comments yourself?


--Josh

--
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] Avoiding Application Re-test

2008-08-08 Thread chris
[EMAIL PROTECTED] (Simon Riggs) writes:
 Every time we introduce a feature that changes output, we just put an if
 test in saying sql_compatibility = X, (the release we added feature).

 Straightforward, futureproof. Cool.

This is somewhat like the way that some shells try to emulate others;
for instance, zsh tries to emulate sh or ksh when invoked by those
names.

There are two problems with this:

   a) The conspicuous phrase, try to emulate

  Which leaves open several questions:

   - What if we can't?

   - What about when we don't want to (e.g. - because the new
 version has a new behaviour that we *DO* want)?

   - What if some semantic change takes place that we didn't
 realize should have been open to the try to emulate?  
 Such as, where there's an ordering change...

   b) It requires adding a new, not-previous-existant effort to
  classify changes and put in logic to allow controlling whether we
  use legacy logic or new logic.

  That seems likely to get mighty messy to me, requiring
  blabbering control code throughout the code base.

I don't think we actually get the future proofness that you're
suggesting.  It would be nice if we could, but that seems unrealistic.
-- 
let name=cbbrowne and tld=linuxdatabases.info in String.concat @ 
[name;tld];;
http://linuxfinances.info/info/spiritual.html
Rules of the Evil Overlord #204. I will hire an entire squad of blind
guards.   Not only  is this  in  keeping with  my status  as an  equal
opportunity employer, but it will  come in handy when the hero becomes
invisible or douses my only light source.
http://www.eviloverlord.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] autovacuum and TOAST tables

2008-08-08 Thread Tom Lane
Alvaro Herrera [EMAIL PROTECTED] writes:
 There's two things I'm not happy about in this patch:

 1. it uses a List to keep the mapping of heap-toast Oids.  This is
 needed to be able to fetch the main rel's pg_autovacuum entry to process
 the toast table.  This incurs in O(n^2) behavior.

Use a dynahash table instead?

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] Replay attack of query cancel

2008-08-08 Thread Heikki Linnakangas
It occurred to me a while ago that our query cancel messages are sent 
unencrypted, even when SSL is otherwise used. That's not a big issue on 
its own, because the cancellation message only contains the backend PID 
and the cancellation key, but it does open us to a replay attack. After 
the first query in a connection has been cancelled, an eavesdropper can 
reuse the backend PID and cancellation key to cancel subsequent queries 
on the same connection.


We discussed this on the security list, and the consensus was that this 
isn't worth a quick fix and a security release, because

- it only affects applications that use query cancel, which is rare
- it only affects SSL encrypted connections (the point is moot 
non-encrypted connections, as you can just snatch the cancel key from 
the initial message)

- it only let's you cancel queries, IOW it's only a DOS attack.
- there's no simple fix.

However, it is something to keep in mind, and perhaps fix for the next 
release.


One idea for fixing this is to make cancellation keys disposable, and 
automatically issue a new one through the main connection when one is 
used, but that's not completely trivial, and requires a change in both 
the clients and the server. Another idea is to send the query cancel 
message only after SSL authentication, but that is impractical for libpq 
because we PQcancel needs to be callable from a signal handler.


--
  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


Re: [HACKERS] Replay attack of query cancel

2008-08-08 Thread Alvaro Herrera
Heikki Linnakangas wrote:

 One idea for fixing this is to make cancellation keys disposable, and  
 automatically issue a new one through the main connection when one is  
 used, but that's not completely trivial, and requires a change in both  
 the clients and the server. Another idea is to send the query cancel  
 message only after SSL authentication, but that is impractical for libpq  
 because we PQcancel needs to be callable from a signal handler.

I wonder if we can do something diffie-hellman'ish, where we have a
parameter exchanged in the initial SSL'ed handshake, which is later used
to generate new cancel keys each time the previous one is used.

-- 
Alvaro Herrerahttp://www.CommandPrompt.com/
The PostgreSQL Company - Command Prompt, Inc.

-- 
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] IN vs EXISTS equivalence

2008-08-08 Thread Tom Lane
Kevin Grittner [EMAIL PROTECTED] writes:
 I'm adding some NOT EXISTS examples to the thread for completeness
 of what someone might want to address while working on it.  For two
 queries which can easily be shown (to a human viewer, anyway) to
 return identical results, I see performance differences of over
 five orders of magnitude.

I've been looking at this a bit and have an action plan worked out.

I believe that the optimizable cases for EXISTS are those where the
EXISTS() is either at the top level of WHERE, or just underneath a NOT,
and the contained subselect:

* has no set operations (UNION etc), grouping, set-returning functions
in the SELECT list, LIMIT, or a few other funny cases

* references outer-level variables only in its WHERE clause.

Given these conditions, an EXISTS is equivalent to a standard semijoin
between the outer relations used in its WHERE clause and the sub-select
with the WHERE removed, where the join condition is just the WHERE
clause.  (A semijoin returns one copy of each LHS row for which there
exists at least one RHS row satisfying the join condition.)

Similarly, a NOT EXISTS is equivalent to a standard anti-semijoin.
(An anti-semijoin returns one copy of each LHS row for which there
exists no RHS row satisfying the join condition.)

So what I think we should do is implement JOIN_SEMI and JOIN_ANTI
as variant outer-join types in the planner and executor, and convert
EXISTS into those.  JOIN_SEMI would replace the existing JOIN_IN support.
(It's effectively the same thing so far as the executor is concerned,
but there are some places in the planner that assume an IN join condition
consists of one or more btree equality operators.  I'm envisioning folding
the current planner support for IN into the more general outer-join
planning infrastructure, and fixing it so that it doesn't assume the
join clause must be of that form.)

Explicit support for JOIN_ANTI is probably not strictly necessary:
we could represent it using the LEFT JOIN WHERE rhs-variable IS NULL
hack.  However this only works if the join's ON-condition can be proved
strict for at least one RHS variable, which is an assumption I'd rather
not require for optimizing EXISTS.  Also, the planner should be able to
make much better estimates of the size of an antijoin result if it has an
explicit concept that that's what's happening.  (The existing kluge in
nulltestsel() is not only ugly but has little hope of ever giving an
accurate estimate.)  So I'd prefer to go the other way: make the planner
recognize the IS NULL trick and remove the IS NULL clause in favor of
marking the LEFT JOIN as being really an antijoin.

As far as IN goes: IN at the top level of WHERE can still be optimized
to a semijoin under the same conditions as now.  NOT IN is a lot trickier,
for the same reason that typically trips up novices who try to use it:
if any row of the subselect produces a NULL comparison result, then it is
impossible for the NOT IN to result in TRUE, which means that it does not
function as a standard antijoin.  I thought about optimizing it only in
the case where we can prove that the subselect outputs and the compared-to
values are known NOT NULL (which in typical cases we could prove by
looking for NOT NULL constraints on those table columns).  The trouble
with this is that that's not a sufficient condition: you must also assume
that the comparison operator involved never yields NULL for non-null
inputs.  That might be okay for btree comparison functions but it's not a
very comfy assumption in general; we certainly haven't got any explicit
knowledge that any functions are guaranteed to act that way.  So this
case might be worth doing later but I'm not feeling excited about it.
We generally tell people to avoid NOT IN and I'm happy to keep on
saying that.

Comments?

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] Replay attack of query cancel

2008-08-08 Thread Tom Lane
Alvaro Herrera [EMAIL PROTECTED] writes:
 I wonder if we can do something diffie-hellman'ish, where we have a
 parameter exchanged in the initial SSL'ed handshake, which is later used
 to generate new cancel keys each time the previous one is used.

Seems like the risk of getting out of sync would outweigh any benefits.
Lose one cancel message in the network, you have no hope of getting any
more accepted.

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] Replay attack of query cancel

2008-08-08 Thread Magnus Hagander
Alvaro Herrera wrote:
 Heikki Linnakangas wrote:
 
 One idea for fixing this is to make cancellation keys disposable, and  
 automatically issue a new one through the main connection when one is  
 used, but that's not completely trivial, and requires a change in both  
 the clients and the server. Another idea is to send the query cancel  
 message only after SSL authentication, but that is impractical for libpq  
 because we PQcancel needs to be callable from a signal handler.
 
 I wonder if we can do something diffie-hellman'ish, where we have a
 parameter exchanged in the initial SSL'ed handshake, which is later used
 to generate new cancel keys each time the previous one is used.

Seems much more complex than needed.

IIRC, the protocol allows us (at least does not explicitly forbid) to
issue new cancel keys at any time. And libpq will, again IIRC, accept
them. So we could just change the server to issue a new cancel key
whenever it has used the previous one (since the new key will then be
sent over the encrypted channel, we're safe).

The problem was (third IIRC here :-P) in other clients, such as the JDBC
driver (I think that one was checked specifically) which currently only
accept the BackendKeyData message during startup. All drivers not based
on libpq would have to be checked and potentially updated, but it's
sitll a lot easier than DHing or so.

//Magnus

-- 
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] Replay attack of query cancel

2008-08-08 Thread Tom Lane
Magnus Hagander [EMAIL PROTECTED] writes:
 The problem was (third IIRC here :-P) in other clients, such as the JDBC
 driver (I think that one was checked specifically) which currently only
 accept the BackendKeyData message during startup. All drivers not based
 on libpq would have to be checked and potentially updated, but it's
 sitll a lot easier than DHing or so.

The other problem was getting the new cancel key from the postmaster to
the backend and thence to the client (hopefully in a timely manner),
recognizing that (a) we don't want the postmaster touching shared memory
very much, and certainly not engaging in any locking behavior; (b)
backends feel free to ignore SIGINT when they're not doing anything.

Certainly the prospect of a de facto protocol change is the bigger
problem, but there are nontrivial implementation issues in the server
too.

If we were going to make it a de jure protocol change (ie new version
number) instead of just hoping nobody notices the behavioral difference,
I'd be inclined to think about widening the cancel key, too.  32 bits
ain't that much randomness anymore.

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] IN vs EXISTS equivalence

2008-08-08 Thread Kevin Grittner
 Tom Lane [EMAIL PROTECTED] wrote: 
 
 I believe that the optimizable cases for EXISTS are those where the
 EXISTS() is either at the top level of WHERE, or just underneath a
NOT,
 
The rest of the plan makes sense to me, but this part seems narrow. 
There's probably a good reason for that which is beyond my depth, but
attached is a view that is used for calculating statistics for a
database which is primarily used for case management purposes.  If
EXISTS could also be optimized in the contexts used there, it would be
great.
 
For context, this view references three other non-trivial views
(MatterHistSearch, MatterHistStage,  MatterHistStatus), and does
perform acceptably, so it's not a matter of complaining if it can't
work here, just providing a real-world example of other useful
contexts for EXISTS which might be worth covering if possible.
 
This view is used in a large number of queries, mostly either
selecting a single date with other selection criteria or counting rows
which match a set of matterNo values selected on complex criteria.
 
By the way, this view was totally unusable under 8.2.  Showing how it
worked under 8.3 was all it took to get them to expedite the upgrade. 
These views, possible because of improvements in 8.3, saved countless
programmer days (to quote one of the programmers).
 
-Kevin
CREATE VIEW MatterDateStat AS
SELECT
S.matterNo,
CAST(D.date AS DateT) AS date,
S.newStageCode AS stage,
CAST(COALESCE(O.newStatusCode, 'OP') AS MatterStatusCodeT) AS 
status,
(
  EXISTS
  (
SELECT *
  FROM MatterHistSearch MHS1
  JOIN MatterEventCode MEC1
ON (MEC1.matterEventCode = MHS1.matterEventCode)
  WHERE MHS1.matterNo = S.matterNo
AND MHS1.date = D.date
AND MEC1.newMaintCode = 'INA'
AND NOT EXISTS
(
  SELECT *
FROM MatterHistSearch MHS2
JOIN MatterEventCode MEC2
  ON (MEC2.matterEventCode = MHS2.matterEventCode)
WHERE MHS2.matterNo = S.matterNo
  AND MHS2.date = D.date
  AND (MHS2.date, MHS2.matterHistRowOrder)  
(MHS1.date, MHS1.matterHistRowOrder)
  AND MEC2.removeMaintCode = 'INA'
)
  )
) AS isOnHold,
S.parentMatter,
S.matterHistSeqNo,  -- NULL means that the stage is defaulting from the 
matter filing date.
S.areaOfLawCode,
S.county,
S.enteredDate,
S.filedDate,
S.grievInvestigator,
S.intakeInvestigator,
S.isSelfNotification,
S.litigationMatterNo,
S.matterType,
S.oldMatterNo,
S.reportMethodCode,
S.respondent,
S.sccaCaseNo,
S.takenBy,
L.isPublic,
L.matterDispoCode,
L.matterDispoDate
  -- Oldest filedDate for a matter in the database is used.  (Older ones not 
likely to appear now.)
  FROM (SELECT DATE '1974-05-15' + generate_series(0, (CURRENT_DATE - DATE 
'1974-05-15')) AS date) D
  JOIN MatterHistStage S
ON ( S.date = D.date
 AND NOT EXISTS
 (
   SELECT * FROM MatterHistStage S2
 WHERE S2.matterNo = S.matterNo
   AND S2.date = D.date
   AND (S2.date, S2.matterHistRowOrder)  (S.date, 
S.matterHistRowOrder)
 )
   )
  JOIN Matter L  -- Litigation matter, if present; otherwise the original 
matter.
ON (L.matterNo = COALESCE(S.litigationMatterNo, S.matterNo))
  LEFT JOIN MatterHistStatus O
ON ( O.matterNo = S.matterNo
 AND O.date = D.date
 AND NOT EXISTS
 (
   SELECT * FROM MatterHistStatus O2
 WHERE O2.matterNo = O.matterNo
   AND O2.date = D.date
   AND (O2.date, O2.matterHistRowOrder)  (O.date, 
O.matterHistRowOrder)
 )
   )
  WHERE COALESCE(O.newStatusCode, 'OP')  'CL'
;

-- 
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] autovacuum and TOAST tables

2008-08-08 Thread Alvaro Herrera
Tom Lane wrote:
 Alvaro Herrera [EMAIL PROTECTED] writes:
  There's two things I'm not happy about in this patch:
 
  1. it uses a List to keep the mapping of heap-toast Oids.  This is
  needed to be able to fetch the main rel's pg_autovacuum entry to process
  the toast table.  This incurs in O(n^2) behavior.
 
 Use a dynahash table instead?

Right, the attached patch does that.

Note that this patch allows a toast table to be vacuumed by the user:

alvherre=# vacuum pg_toast.pg_toast_39970;
VACUUM

I don't have a problem with that, but if anyone thinks this is not a
good idea, please speak up.

-- 
Alvaro Herrerahttp://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support
Index: src/backend/commands/vacuum.c
===
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/commands/vacuum.c,v
retrieving revision 1.375
diff -c -p -r1.375 vacuum.c
*** src/backend/commands/vacuum.c	5 Jun 2008 15:47:32 -	1.375
--- src/backend/commands/vacuum.c	8 Aug 2008 16:42:02 -
*** static BufferAccessStrategy vac_strategy
*** 213,220 
  static List *get_rel_oids(Oid relid, const RangeVar *vacrel,
  			 const char *stmttype);
  static void vac_truncate_clog(TransactionId frozenXID);
! static void vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind,
! 	   bool for_wraparound);
  static void full_vacuum_rel(Relation onerel, VacuumStmt *vacstmt);
  static void scan_heap(VRelStats *vacrelstats, Relation onerel,
  		  VacPageList vacuum_pages, VacPageList fraged_pages);
--- 213,220 
  static List *get_rel_oids(Oid relid, const RangeVar *vacrel,
  			 const char *stmttype);
  static void vac_truncate_clog(TransactionId frozenXID);
! static void vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast,
! 		   bool for_wraparound);
  static void full_vacuum_rel(Relation onerel, VacuumStmt *vacstmt);
  static void scan_heap(VRelStats *vacrelstats, Relation onerel,
  		  VacPageList vacuum_pages, VacPageList fraged_pages);
*** static Size PageGetFreeSpaceWithFillFact
*** 268,273 
--- 268,276 
   * OID to be processed, and vacstmt-relation is ignored.  (The non-invalid
   * case is currently only used by autovacuum.)
   *
+  * do_toast is passed as FALSE by autovacuum, because it processes TOAST
+  * tables separately.
+  *
   * for_wraparound is used by autovacuum to let us know when it's forcing
   * a vacuum for wraparound, which should not be auto-cancelled.
   *
*** static Size PageGetFreeSpaceWithFillFact
*** 281,287 
   * at transaction commit.
   */
  void
! vacuum(VacuumStmt *vacstmt, Oid relid,
  	   BufferAccessStrategy bstrategy, bool for_wraparound, bool isTopLevel)
  {
  	const char *stmttype = vacstmt-vacuum ? VACUUM : ANALYZE;
--- 284,290 
   * at transaction commit.
   */
  void
! vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast,
  	   BufferAccessStrategy bstrategy, bool for_wraparound, bool isTopLevel)
  {
  	const char *stmttype = vacstmt-vacuum ? VACUUM : ANALYZE;
*** vacuum(VacuumStmt *vacstmt, Oid relid,
*** 433,439 
  			Oid			relid = lfirst_oid(cur);
  
  			if (vacstmt-vacuum)
! vacuum_rel(relid, vacstmt, RELKIND_RELATION, for_wraparound);
  
  			if (vacstmt-analyze)
  			{
--- 436,442 
  			Oid			relid = lfirst_oid(cur);
  
  			if (vacstmt-vacuum)
! vacuum_rel(relid, vacstmt, do_toast, for_wraparound);
  
  			if (vacstmt-analyze)
  			{
*** vac_truncate_clog(TransactionId frozenXI
*** 975,982 
   *		At entry and exit, we are not inside a transaction.
   */
  static void
! vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind,
! 		   bool for_wraparound)
  {
  	LOCKMODE	lmode;
  	Relation	onerel;
--- 978,984 
   *		At entry and exit, we are not inside a transaction.
   */
  static void
! vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound)
  {
  	LOCKMODE	lmode;
  	Relation	onerel;
*** vacuum_rel(Oid relid, VacuumStmt *vacstm
*** 1013,1020 
  		 * by autovacuum; it's used to avoid cancelling a vacuum that was
  		 * invoked in an emergency.
  		 *
! 		 * Note: this flag remains set until CommitTransaction or
! 		 * AbortTransaction.  We don't want to clear it until we reset
  		 * MyProc-xid/xmin, else OldestXmin might appear to go backwards,
  		 * which is probably Not Good.
  		 */
--- 1015,1022 
  		 * by autovacuum; it's used to avoid cancelling a vacuum that was
  		 * invoked in an emergency.
  		 *
! 		 * Note: these flags remain set until CommitTransaction or
! 		 * AbortTransaction.  We don't want to clear them until we reset
  		 * MyProc-xid/xmin, else OldestXmin might appear to go backwards,
  		 * which is probably Not Good.
  		 */
*** vacuum_rel(Oid relid, VacuumStmt *vacstm
*** 1087,1096 
  	}
  
  	/*
! 	 * Check that it's a plain table; we used to do this 

Re: [HACKERS] autovacuum and TOAST tables

2008-08-08 Thread Tom Lane
Alvaro Herrera [EMAIL PROTECTED] writes:
 Note that this patch allows a toast table to be vacuumed by the user:
 I don't have a problem with that, but if anyone thinks this is not a
 good idea, please speak up.

The permissions on pg_toast will prevent anyone but a superuser from
doing that anyway, so it's no big deal.

Possibly more interesting is what happens if someone drops the parent
table while VACUUM is working independently on the toast table.  Does
DROP take exclusive lock on a toast table?  Probably, but it needs
to be checked.  I think preventing that scenario was one reason why
the vacuuming was tied together way back when.

(The same goes for any other parent-table DDL action that would affect
the toast table; CLUSTER or TRUNCATE for instance.)

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] Visibility Groups

2008-08-08 Thread daveg
On Thu, Aug 07, 2008 at 01:30:27PM +0100, Gregory Stark wrote:
 Simon Riggs [EMAIL PROTECTED] writes:
 
  Currently, we calculate a single OldestXmin across all snapshots on the
  assumption that any transaction might access any table.
 
  I propose creating Visibility Groups that *explicitly* limit the
  ability of a transaction to access data outside its visibility group(s).
  By default, visibility_groups would be NULL, implying potential access
  to all tables.
 
  Once set, any attempt to lock an object outside of a transactions
  defined visibility_groups will result in an error:
ERROR attempt to lock table outside of visibility group(s): foo
HINT you need to set a different value for visibility_groups
  A transaction can only ever reduce or restrict its visibility_groups, it
  cannot reset or add visibility groups.
 
 Hm, so backing up a bit from the specific proposed interface, the key here is
 being able to explicitly mark which tables your transaction will need in the
 future?
 
 Is it always just a handful of heavily updated tables that you want to
 protect? In that case we could have a lock type which means I'll never need
 to lock this object. Then a session could issue LOCK TABLE foo IN
 INACCESSIBLE MODE or something like that. That requires people to hack up
 their pg_dump or replication script though which might be awkward.
 
 Perhaps the way to do that would be to preemptively take locks on all the
 objects that you'll need, then have a command to indicate you won't need any
 further objects beyond those. 

+1

-dg
-- 
David Gould   [EMAIL PROTECTED]  510 536 1443510 282 0869
If simplicity worked, the world would be overrun with insects.

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