Re: [Fwd: Re: [HACKERS] Transactions and temp tables]

2009-01-22 Thread Heikki Linnakangas

Bruce Momjian wrote:

Heikki Linnakangas wrote:
IMHO, this is just getting too kludgey. We came up with pretty good 
ideas on how to handle temp tables properly, by treating the same as 
non-temp tables. That should eliminate all the problems the latest patch 
did, and also the issues with sequences, and allow all access to temp 
tables, not just a limited subset. I don't think it's worthwhile to 
apply the kludge as a stopgap measure, let's do it properly in 8.5.

...


Can someone tell me how this should be worded as a TODO item?


There already is a todo item about this:

Allow prepared transactions with temporary tables created and dropped 
in the same transaction, and when an ON COMMIT DELETE ROWS temporary 
table is accessed 


I added a link to the email describing the most recent idea on how this 
should be implemented.


--
  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: [Fwd: Re: [HACKERS] Transactions and temp tables]

2009-01-21 Thread Bruce Momjian
Heikki Linnakangas wrote:
 Emmanuel Cecchet wrote:
  I just saw that this new patch was not considered because the previous 
  version ended being rejected.
  Note that this version of the patch aims at supporting ONLY temp tables 
  that are created AND dropped in the same transaction. We need to be able 
  to use temp tables in transactions that are doing 2PC, but the temp 
  table lifespan does not need to cross transaction boundaries.
  
  Please let me know if this patch could be integrated in 8.4.
 
 IMHO, this is just getting too kludgey. We came up with pretty good 
 ideas on how to handle temp tables properly, by treating the same as 
 non-temp tables. That should eliminate all the problems the latest patch 
 did, and also the issues with sequences, and allow all access to temp 
 tables, not just a limited subset. I don't think it's worthwhile to 
 apply the kludge as a stopgap measure, let's do it properly in 8.5.
 
 As a workaround, you can use a regular table instead of a temporary one. 
 If you create and drop the regular table in the same transaction (that's 
 the same limitation that latest patch has), you won't end up with a 
 bogus table in your database if the connection is dropped unexpectedly. 
 If your application uses multiple connections simultaenously, you'll 
 need a little bit of code in the application so that you don't try to 
 create a table with the same name in all backends. You could also create 
 a different schema for each connection, and do set 
 search_path='semitempschemaX, public', so that you can use the same 
 table name and still have separate tables for each connections.

Can someone tell me how this should be worded as a TODO item?

-- 
  Bruce Momjian  br...@momjian.ushttp://momjian.us
  EnterpriseDB http://enterprisedb.com

  + If your life is a hard drive, Christ can be your backup. +

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


Re: [Fwd: Re: [HACKERS] Transactions and temp tables]

2008-12-24 Thread Emmanuel Cecchet

Hi Heikki,

The point of using temp tables was performance. Using regular tables in 
our case would hurt performance too much. Well if we cannot get a 
temporary fix in 8.4, we will maintain a separate patch to get that 
functionality just for temp tables that are created and dropped in the 
same transaction. Hopefully we will be able to come up with a working 
solution in 8.5.


Thanks for your help,
Emmanuel


Emmanuel Cecchet wrote:
  

I just saw that this new patch was not considered because the previous
version ended being rejected.
Note that this version of the patch aims at supporting ONLY temp tables
that are created AND dropped in the same transaction. We need to be able
to use temp tables in transactions that are doing 2PC, but the temp
table lifespan does not need to cross transaction boundaries.

Please let me know if this patch could be integrated in 8.4.



IMHO, this is just getting too kludgey. We came up with pretty good
ideas on how to handle temp tables properly, by treating the same as
non-temp tables. That should eliminate all the problems the latest patch
did, and also the issues with sequences, and allow all access to temp
tables, not just a limited subset. I don't think it's worthwhile to
apply the kludge as a stopgap measure, let's do it properly in 8.5.

As a workaround, you can use a regular table instead of a temporary one.
If you create and drop the regular table in the same transaction (that's
the same limitation that latest patch has), you won't end up with a
bogus table in your database if the connection is dropped unexpectedly.
If your application uses multiple connections simultaenously, you'll
need a little bit of code in the application so that you don't try to
create a table with the same name in all backends. You could also create
a different schema for each connection, and do set
search_path='semitempschemaX, public', so that you can use the same
table name and still have separate tables for each connections.

(sorry for the late reply)

--
   Heikki Linnakangas
   EnterpriseDB   http://www.enterprisedb.com
  



--
Emmanuel Cecchet
Aster Data Systems
Web: http://www.asterdata.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: [Fwd: Re: [HACKERS] Transactions and temp tables]

2008-12-23 Thread Heikki Linnakangas

Emmanuel Cecchet wrote:
I just saw that this new patch was not considered because the previous 
version ended being rejected.
Note that this version of the patch aims at supporting ONLY temp tables 
that are created AND dropped in the same transaction. We need to be able 
to use temp tables in transactions that are doing 2PC, but the temp 
table lifespan does not need to cross transaction boundaries.


Please let me know if this patch could be integrated in 8.4.


IMHO, this is just getting too kludgey. We came up with pretty good 
ideas on how to handle temp tables properly, by treating the same as 
non-temp tables. That should eliminate all the problems the latest patch 
did, and also the issues with sequences, and allow all access to temp 
tables, not just a limited subset. I don't think it's worthwhile to 
apply the kludge as a stopgap measure, let's do it properly in 8.5.


As a workaround, you can use a regular table instead of a temporary one. 
If you create and drop the regular table in the same transaction (that's 
the same limitation that latest patch has), you won't end up with a 
bogus table in your database if the connection is dropped unexpectedly. 
If your application uses multiple connections simultaenously, you'll 
need a little bit of code in the application so that you don't try to 
create a table with the same name in all backends. You could also create 
a different schema for each connection, and do set 
search_path='semitempschemaX, public', so that you can use the same 
table name and still have separate tables for each connections.


(sorry for the late reply)

--
  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] Transactions and temp tables

2008-12-03 Thread Heikki Linnakangas

Emmanuel Cecchet wrote:
I think that the Assert in is_temp_rel(Oid) in tablecmds.c should be 
replaced by if (on_commits == NULL) return false;
As the use case below shows, a regular table can be created and hold a 
LOCKTAG_RELATION lock that will trigger the call to is_temp_rel in 
is_preparable_locktag. The assert will break if no temp table was accessed.


Yes, you're right.

--
  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] Transactions and temp tables

2008-12-03 Thread Heikki Linnakangas

Emmanuel Cecchet wrote:
There is a problem with temp tables with on delete rows that are created 
inside a transaction.
Take the 2pc_on_delete_rows_transaction.sql test case and change the 
creation statement, instead of

create temp table foo(x int) on commit delete rows;
try
create temp table foo(x serial primary key) on commit delete rows;

The test will fail. It looks like the onCommit field is not properly 
updated when serial or primary key is used in that context. I did not 
figure out why.


A serial column uses a sequence behind the scenes.

Hmm. Seems like we would need to treat sequences and indexes the same as 
tables with ON COMMIT DELETE ROWS, i.e release the locks early and don't 
error out.


All in all, this is getting pretty messy. My patch felt a bit hackish to 
begin with, and having to add special cases for sequences and indexes 
would make it even more so. And what about temporary views? I'm starting 
to feel that instead of special-casing temp relations, we need to move 
into the opposite direction and make temp relations more like regular 
relations. Unfortunately, that's not going to happen in the 8.4 
timeframe :-(. Let's try the other approach in 8.5.


--
  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] Transactions and temp tables

2008-12-03 Thread Emmanuel Cecchet
I would really like to have support for temp tables at least for the 
case where the table is created and dropped in the same transaction. But 
I guess that the other limitations on index, sequences and views would 
still hold, right?


manu

Heikki Linnakangas wrote:

Emmanuel Cecchet wrote:
There is a problem with temp tables with on delete rows that are 
created inside a transaction.
Take the 2pc_on_delete_rows_transaction.sql test case and change the 
creation statement, instead of

create temp table foo(x int) on commit delete rows;
try
create temp table foo(x serial primary key) on commit delete rows;

The test will fail. It looks like the onCommit field is not properly 
updated when serial or primary key is used in that context. I did not 
figure out why.

A serial column uses a sequence behind the scenes.

Hmm. Seems like we would need to treat sequences and indexes the same 
as tables with ON COMMIT DELETE ROWS, i.e release the locks early and 
don't error out.


All in all, this is getting pretty messy. My patch felt a bit hackish 
to begin with, and having to add special cases for sequences and 
indexes would make it even more so. And what about temporary views? 
I'm starting to feel that instead of special-casing temp relations, we 
need to move into the opposite direction and make temp relations more 
like regular relations. Unfortunately, that's not going to happen in 
the 8.4 timeframe :-(. Let's try the other approach in 8.5.





--
Emmanuel Cecchet
FTO @ Frog Thinker 
Open Source Development  Consulting

--
Web: http://www.frogthinker.org
email: [EMAIL PROTECTED]
Skype: emmanuel_cecchet


--
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] Transactions and temp tables

2008-12-01 Thread Emmanuel Cecchet

Heikki,

I think that the Assert in is_temp_rel(Oid) in tablecmds.c should be 
replaced by if (on_commits == NULL) return false;
As the use case below shows, a regular table can be created and hold a 
LOCKTAG_RELATION lock that will trigger the call to is_temp_rel in 
is_preparable_locktag. The assert will break if no temp table was accessed.


As we were also trying to list potential issues, if the temp table uses 
a SERIAL type, will there be potentially a problem with the sequence at 
prepare time?


Emmanuel


The following test fails with your patch on my system. Could you check 
if you can reproduce?


psql (8.4devel)
Type help for help.

test=# begin;
BEGIN
test=# create table paul(x int);
CREATE TABLE
test=# insert into paul values(1);
INSERT 0 1
test=# prepare transaction 'persistentTableShouldSucceed';
server closed the connection unexpectedly
   This probably means the server terminated abnormally
   before or while processing the request.
The connection to the server was lost. Attempting reset: Failed.

---

LOG:  database system is ready to accept connections
TRAP: FailedAssertion(!(on_commits != ((void *)0)), File: 
tablecmds.c, Line: 7823)

LOG:  server process (PID 15969) was terminated by signal 6: Aborted
LOG:  terminating any other active server processes
FATAL:  the database system is in recovery mode


Thanks,
manu




--
Emmanuel Cecchet
FTO @ Frog Thinker 
Open Source Development  Consulting

--
Web: http://www.frogthinker.org
email: [EMAIL PROTECTED]
Skype: emmanuel_cecchet


--
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] Transactions and temp tables

2008-11-24 Thread Emmanuel Cecchet

Heikki,

The following test fails with your patch on my system. Could you check 
if you can reproduce?


psql (8.4devel)
Type help for help.

test=# begin;
BEGIN
test=# create table paul(x int);
CREATE TABLE
test=# insert into paul values(1);
INSERT 0 1
test=# prepare transaction 'persistentTableShouldSucceed';
server closed the connection unexpectedly
   This probably means the server terminated abnormally
   before or while processing the request.
The connection to the server was lost. Attempting reset: Failed.

---

LOG:  database system is ready to accept connections
TRAP: FailedAssertion(!(on_commits != ((void *)0)), File: 
tablecmds.c, Line: 7823)

LOG:  server process (PID 15969) was terminated by signal 6: Aborted
LOG:  terminating any other active server processes
FATAL:  the database system is in recovery mode


Thanks,
manu

--
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] Transactions and temp tables

2008-11-21 Thread Emmanuel Cecchet

Heikki Linnakangas wrote:

Emmanuel Cecchet wrote:
I still quite did not get what the big deal was if an ON COMMIT 
DELETE ROWS temp table was created inside a transaction.


In case the transaction that created a temp table rolls back, the 
table needs to be removed. Removing a temporary table belonging to 
another backend is problematic; the local buffers in the original 
backend need to be dropped, as well as the entry in the on commit 
actions list.


Why the new checks you are doing in lock.c would not work with 
dropped temp tables? Could it be possible to drop the lock as soon as 
the temp table is dropped inside a transaction?


If you release the lock early on a table that you drop, another 
transactions would be free to access the table, even though it's about 
to be dropped.



I will try to find more time to review the patch tonight.


Thanks!

Thinking about this whole thing yet more, I wonder if we could have a 
more holistic approach and make temporary tables work just like 
regular ones. The problems we've identified this far are:


1. If the prepared transaction keeps the temp table locked, the 
backend can't exit, because the shutdown hook tries to drop all temp 
tables.


2. When a prepared transaction that has deleted a temporary table 
commits (or one that created one aborts), we need to drop all the 
local buffers from the original backend's private buffer cache.


3. When a prepared transaction that has deleted a temporary table 
commits (or one that created one aborts), we need to remove the 
on-commit entry from the original backend's private list.


Is there more? I think we can solve all the above problems:

1. Modify RemoveTempRelations so that it doesn't block if it can't 
immediately acquire lock on the to-be-removed object. That way the 
original backend can exit even if a prepared transaction is holding a 
lock on a temporary object.


To avoid conflict with a new backend that's assigned the same 
backendid, divorce the temporary namespace naming from backendid so 
that the temporary namespace name stays reserved for the prepared 
transaction.
Is that going to cause any problem with DROP CASCADE operations or 
trying to later drop a child table if the parent table is locked? I did 
hit that issue when I tried to modify RemoveTempRelations but I was 
probably not very smart at it.
2. Flush and drop all local buffers on temporary tables that have been 
created or dropped in the transaction at PREPARE TRANSACTION already.
Would there be any issue if someone was trying to use a READ_UNCOMMITTED 
isolation level to access the temp table data?
3. Add on-commit field to pg_class, and only keep a list of temporary 
tables that have been accessed in the current transaction in 
backend-private memory.
Yes, this seems doable. We will certainly have to keep a list per 
transaction id in case multiple prepared but uncommitted transactions 
have accessed different temp table on that backend.


Have you already started to code some of this?
I am looking at adding new tests to check all cases including all types 
of temp tables (normal/on delete/on drop, created inside or outside a 
transaction, prepare/postmaster stop/commit/rollback, 
inherit/index/vaccuum). That should get all the use cases covered.


Let me know what you think.
Thanks,
Emmanuel

--
Emmanuel Cecchet
FTO @ Frog Thinker 
Open Source Development  Consulting

--
Web: http://www.frogthinker.org
email: [EMAIL PROTECTED]
Skype: emmanuel_cecchet


--
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] Transactions and temp tables

2008-11-20 Thread Heikki Linnakangas

Emmanuel Cecchet wrote:
I still quite did not get what the big deal was if an ON COMMIT DELETE 
ROWS temp table was created inside a transaction.


In case the transaction that created a temp table rolls back, the table 
needs to be removed. Removing a temporary table belonging to another 
backend is problematic; the local buffers in the original backend need 
to be dropped, as well as the entry in the on commit actions list.


Why the new checks you are doing in lock.c would not work with dropped 
temp tables? Could it be possible to drop the lock as soon as the temp 
table is dropped inside a transaction?


If you release the lock early on a table that you drop, another 
transactions would be free to access the table, even though it's about 
to be dropped.



I will try to find more time to review the patch tonight.


Thanks!

Thinking about this whole thing yet more, I wonder if we could have a 
more holistic approach and make temporary tables work just like regular 
ones. The problems we've identified this far are:


1. If the prepared transaction keeps the temp table locked, the backend 
can't exit, because the shutdown hook tries to drop all temp tables.


2. When a prepared transaction that has deleted a temporary table 
commits (or one that created one aborts), we need to drop all the local 
buffers from the original backend's private buffer cache.


3. When a prepared transaction that has deleted a temporary table 
commits (or one that created one aborts), we need to remove the 
on-commit entry from the original backend's private list.


Is there more? I think we can solve all the above problems:

1. Modify RemoveTempRelations so that it doesn't block if it can't 
immediately acquire lock on the to-be-removed object. That way the 
original backend can exit even if a prepared transaction is holding a 
lock on a temporary object.


To avoid conflict with a new backend that's assigned the same backendid, 
divorce the temporary namespace naming from backendid so that the 
temporary namespace name stays reserved for the prepared transaction.


2. Flush and drop all local buffers on temporary tables that have been 
created or dropped in the transaction at PREPARE TRANSACTION already.


3. Add on-commit field to pg_class, and only keep a list of temporary 
tables that have been accessed in the current transaction in 
backend-private memory.


--
  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] Transactions and temp tables

2008-11-19 Thread Emmanuel Cecchet

Hi Heikki,

I will try to make more tests.
I still quite did not get what the big deal was if an ON COMMIT DELETE 
ROWS temp table was created inside a transaction.
Why the new checks you are doing in lock.c would not work with dropped 
temp tables? Could it be possible to drop the lock as soon as the temp 
table is dropped inside a transaction?


I will try to find more time to review the patch tonight.

Best,
Emmanuel


Heikki Linnakangas wrote:
Somehow this feels pretty baroque, though. Perhaps a better approach 
would be to add a new AtPrepare_OnCommitActions function to 
tablecmds.c, that gets called before AtPrepare_Locks. It would scan 
through the on_commits list, and release all locks for the 
PREPARE-safe temp tables, and throw the error if necessary. I'll 
try that next.


Here's what I ended up with. I morphed the on commit action 
registration into tracking of all temporary relations.


This only allows access to ON COMMIT DELETE ROWS temp tables. 
Accessing other temporary tables, and creating or dropping tables in 
the transaction is still forbidden.


It took me a couple of iterations to handle toast tables and indexes 
correctly. More testing would be appreciated with more complex cases 
like VACUUM FULL, subtransactions etc.





--
Emmanuel Cecchet
FTO @ Frog Thinker 
Open Source Development  Consulting

--
Web: http://www.frogthinker.org
email: [EMAIL PROTECTED]
Skype: emmanuel_cecchet


--
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] Transactions and temp tables

2008-11-18 Thread Heikki Linnakangas

Emmanuel Cecchet wrote:

Emmanuel Cecchet wrote:
As I have not found yet an elegant solution to deal with the DROP 
CASCADE issue, here is a simpler patch that handles temp tables that 
are dropped at commit time. This is a good first step and we will try 
to elaborate further to support ON COMMIT DELETE ROWS.


The problem with stopping the postmaster seems to still be there..

All the problems are centered around locking. We need to address that 
and decide what is sane locking behavior wrt. temp tables and 2PC.


First, there's the case where a temp table is created and dropped in 
the same transaction. It seems perfectly sane to me to simply drop all 
locks on the dropped table at PREPARE TRANSACTION. Does anyone see a 
problem with that? If not, we might as well do that for all tables, 
not just temporary ones. It seems just as safe for non-temporary tables.
This seems good to me. Any access to the table after PREPARE TRANSACTION 
but before COMMIT on that backend would return a relation not found 
which is what we expect. For  a regular table, I don't know if that 
makes a difference if the prepared transaction rollbacks?


I don't think there's any difference with temp tables and regular ones 
from locking point of view.


Secondly, there's the case of accessing a ON COMMIT DELETE ROWS table. 
There too, could we simply drop the locks at PREPARE TRANSACTION? I 
can't immediately see anything wrong with that.
As there is no data anyway, I don't think the locks are going to change 
anything. But in the most recent stripped-down version of the patch, on 
delete rows is no more supported, I only allow on commit drop. I did not 
find the flag to see if a temp table was created with the on delete rows 
option.


Hmm. I think we can use the on_commits list in tablecmds.c for that.

Do you want me to look at the locking code or will you have time to do 
it? Hints will be welcome if you want me to do it.


I can give it a shot for change. Attached is a patch that allows the ON 
COMMIT DELETE ROWS case. The beef of the patch is:


- An entry is made into the on_commits list in tablecmds.c for all temp 
tables, even if there's no ON COMMIT action
- There's a new function, check_prepare_safe_temp_table(Oid relid) in 
tablecmds.c, that uses the on_commits list to determine if the access to 
the given relation is PREPARE-safe. That is, it's not a temp table, or 
it's an access to an ON COMMIT DELETE ROWS temp table and the temp table 
wasn't created or dropped in the same transaction.
- MyXactMadeTempRelUpdate variable is gone. The check is driven from the 
lock manager again, like it was in 8.1, by calling the new 
check_prepare_sage_temp_table function for all relation locks in 
AtPrepare_Locks().
- changed the on_commits linked list in tablecmds.c into a hash table 
for performance


Somehow this feels pretty baroque, though. Perhaps a better approach 
would be to add a new AtPrepare_OnCommitActions function to tablecmds.c, 
that gets called before AtPrepare_Locks. It would scan through the 
on_commits list, and release all locks for the PREPARE-safe temp 
tables, and throw the error if necessary. I'll try that next.


BTW, there's a very relevant thread here:

http://archives.postgresql.org/pgsql-hackers/2008-03/msg00063.php

if you haven't read it already.

--
  Heikki Linnakangas
  EnterpriseDB   http://www.enterprisedb.com
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index 33d5fab..b94e2bd 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -876,10 +876,6 @@ relation_open(Oid relationId, LOCKMODE lockmode)
 	if (!RelationIsValid(r))
 		elog(ERROR, could not open relation with OID %u, relationId);
 
-	/* Make note that we've accessed a temporary relation */
-	if (r-rd_istemp)
-		MyXactAccessedTempRel = true;
-
 	pgstat_initstats(r);
 
 	return r;
@@ -924,10 +920,6 @@ try_relation_open(Oid relationId, LOCKMODE lockmode)
 	if (!RelationIsValid(r))
 		elog(ERROR, could not open relation with OID %u, relationId);
 
-	/* Make note that we've accessed a temporary relation */
-	if (r-rd_istemp)
-		MyXactAccessedTempRel = true;
-
 	pgstat_initstats(r);
 
 	return r;
@@ -974,10 +966,6 @@ relation_open_nowait(Oid relationId, LOCKMODE lockmode)
 	if (!RelationIsValid(r))
 		elog(ERROR, could not open relation with OID %u, relationId);
 
-	/* Make note that we've accessed a temporary relation */
-	if (r-rd_istemp)
-		MyXactAccessedTempRel = true;
-
 	pgstat_initstats(r);
 
 	return r;
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index b7d1285..c859874 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -67,14 +67,6 @@ int			CommitDelay = 0;	/* precommit delay in microseconds */
 int			CommitSiblings = 5; /* # concurrent xacts needed to sleep */
 
 /*
- * MyXactAccessedTempRel is set when a temporary relation is accessed.
- * We don't allow PREPARE TRANSACTION in that 

Re: [HACKERS] Transactions and temp tables

2008-11-18 Thread Heikki Linnakangas

Heikki Linnakangas wrote:
Somehow this feels pretty baroque, though. Perhaps a better approach 
would be to add a new AtPrepare_OnCommitActions function to tablecmds.c, 
that gets called before AtPrepare_Locks. It would scan through the 
on_commits list, and release all locks for the PREPARE-safe temp 
tables, and throw the error if necessary. I'll try that next.


Here's what I ended up with. I morphed the on commit action registration 
into tracking of all temporary relations.


This only allows access to ON COMMIT DELETE ROWS temp tables. Accessing 
other temporary tables, and creating or dropping tables in the 
transaction is still forbidden.


It took me a couple of iterations to handle toast tables and indexes 
correctly. More testing would be appreciated with more complex cases 
like VACUUM FULL, subtransactions etc.


--
  Heikki Linnakangas
  EnterpriseDB   http://www.enterprisedb.com
*** src/backend/access/heap/heapam.c
--- src/backend/access/heap/heapam.c
***
*** 51,56 
--- 51,57 
  #include access/xlogutils.h
  #include catalog/catalog.h
  #include catalog/namespace.h
+ #include commands/tablecmds.h
  #include miscadmin.h
  #include pgstat.h
  #include storage/bufmgr.h
***
*** 878,884  relation_open(Oid relationId, LOCKMODE lockmode)
  
  	/* Make note that we've accessed a temporary relation */
  	if (r-rd_istemp)
! 		MyXactAccessedTempRel = true;
  
  	pgstat_initstats(r);
  
--- 879,885 
  
  	/* Make note that we've accessed a temporary relation */
  	if (r-rd_istemp)
! 		register_temp_rel_access(relationId);
  
  	pgstat_initstats(r);
  
***
*** 926,932  try_relation_open(Oid relationId, LOCKMODE lockmode)
  
  	/* Make note that we've accessed a temporary relation */
  	if (r-rd_istemp)
! 		MyXactAccessedTempRel = true;
  
  	pgstat_initstats(r);
  
--- 927,933 
  
  	/* Make note that we've accessed a temporary relation */
  	if (r-rd_istemp)
! 		register_temp_rel_access(relationId);
  
  	pgstat_initstats(r);
  
***
*** 976,982  relation_open_nowait(Oid relationId, LOCKMODE lockmode)
  
  	/* Make note that we've accessed a temporary relation */
  	if (r-rd_istemp)
! 		MyXactAccessedTempRel = true;
  
  	pgstat_initstats(r);
  
--- 977,983 
  
  	/* Make note that we've accessed a temporary relation */
  	if (r-rd_istemp)
! 		register_temp_rel_access(relationId);
  
  	pgstat_initstats(r);
  
*** src/backend/access/transam/xact.c
--- src/backend/access/transam/xact.c
***
*** 67,80  int			CommitDelay = 0;	/* precommit delay in microseconds */
  int			CommitSiblings = 5; /* # concurrent xacts needed to sleep */
  
  /*
-  * MyXactAccessedTempRel is set when a temporary relation is accessed.
-  * We don't allow PREPARE TRANSACTION in that case.  (This is global
-  * so that it can be set from heapam.c.)
-  */
- bool		MyXactAccessedTempRel = false;
- 
- 
- /*
   *	transaction states - transaction state from server perspective
   */
  typedef enum TransState
--- 67,72 
***
*** 1467,1473  StartTransaction(void)
  	XactIsoLevel = DefaultXactIsoLevel;
  	XactReadOnly = DefaultXactReadOnly;
  	forceSyncCommit = false;
- 	MyXactAccessedTempRel = false;
  
  	/*
  	 * reinitialize within-transaction counters
--- 1459,1464 
***
*** 1798,1823  PrepareTransaction(void)
  
  	/* NOTIFY and flatfiles will be handled below */
  
- 	/*
- 	 * Don't allow PREPARE TRANSACTION if we've accessed a temporary table
- 	 * in this transaction.  Having the prepared xact hold locks on another
- 	 * backend's temp table seems a bad idea --- for instance it would prevent
- 	 * the backend from exiting.  There are other problems too, such as how
- 	 * to clean up the source backend's local buffers and ON COMMIT state
- 	 * if the prepared xact includes a DROP of a temp table.
- 	 *
- 	 * We must check this after executing any ON COMMIT actions, because
- 	 * they might still access a temp relation.
- 	 *
- 	 * XXX In principle this could be relaxed to allow some useful special
- 	 * cases, such as a temp table created and dropped all within the
- 	 * transaction.  That seems to require much more bookkeeping though.
- 	 */
- 	if (MyXactAccessedTempRel)
- 		ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-  errmsg(cannot PREPARE a transaction that has operated on temporary tables)));
- 
  	/* Prevent cancel/die interrupt while cleaning up */
  	HOLD_INTERRUPTS();
  
--- 1789,1794 
***
*** 1861,1866  PrepareTransaction(void)
--- 1832,1838 
  	AtPrepare_Notify();
  	AtPrepare_UpdateFlatFiles();
  	AtPrepare_Inval();
+ 	AtPrepare_on_commit_actions();
  	AtPrepare_Locks();
  	AtPrepare_PgStat();
  
*** src/backend/catalog/heap.c
--- src/backend/catalog/heap.c
***
*** 39,44 
--- 39,45 
  #include catalog/heap.h
  #include catalog/index.h
  #include catalog/indexing.h
+ #include catalog/namespace.h
  #include catalog/pg_attrdef.h

Re: [HACKERS] Transactions and temp tables

2008-11-17 Thread Heikki Linnakangas

Emmanuel Cecchet wrote:
As I have not found yet an elegant solution to deal with the DROP 
CASCADE issue, here is a simpler patch that handles temp tables that are 
dropped at commit time. This is a good first step and we will try to 
elaborate further to support ON COMMIT DELETE ROWS.


The problem with stopping the postmaster seems to still be there..

All the problems are centered around locking. We need to address that 
and decide what is sane locking behavior wrt. temp tables and 2PC.


First, there's the case where a temp table is created and dropped in the 
same transaction. It seems perfectly sane to me to simply drop all locks 
on the dropped table at PREPARE TRANSACTION. Does anyone see a problem 
with that? If not, we might as well do that for all tables, not just 
temporary ones. It seems just as safe for non-temporary tables.


Secondly, there's the case of accessing a ON COMMIT DELETE ROWS table. 
There too, could we simply drop the locks at PREPARE TRANSACTION? I 
can't immediately see anything wrong with that.


--
  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] Transactions and temp tables

2008-11-17 Thread Emmanuel Cecchet

Hi Heikki,

Emmanuel Cecchet wrote:
As I have not found yet an elegant solution to deal with the DROP 
CASCADE issue, here is a simpler patch that handles temp tables that 
are dropped at commit time. This is a good first step and we will try 
to elaborate further to support ON COMMIT DELETE ROWS.


The problem with stopping the postmaster seems to still be there..

All the problems are centered around locking. We need to address that 
and decide what is sane locking behavior wrt. temp tables and 2PC.


First, there's the case where a temp table is created and dropped in 
the same transaction. It seems perfectly sane to me to simply drop all 
locks on the dropped table at PREPARE TRANSACTION. Does anyone see a 
problem with that? If not, we might as well do that for all tables, 
not just temporary ones. It seems just as safe for non-temporary tables.
This seems good to me. Any access to the table after PREPARE TRANSACTION 
but before COMMIT on that backend would return a relation not found 
which is what we expect. For  a regular table, I don't know if that 
makes a difference if the prepared transaction rollbacks?
Secondly, there's the case of accessing a ON COMMIT DELETE ROWS table. 
There too, could we simply drop the locks at PREPARE TRANSACTION? I 
can't immediately see anything wrong with that.
As there is no data anyway, I don't think the locks are going to change 
anything. But in the most recent stripped-down version of the patch, on 
delete rows is no more supported, I only allow on commit drop. I did not 
find the flag to see if a temp table was created with the on delete rows 
option.


Do you want me to look at the locking code or will you have time to do 
it? Hints will be welcome if you want me to do it.


Thanks,
Emmanuel

--
Emmanuel Cecchet
FTO @ Frog Thinker 
Open Source Development  Consulting

--
Web: http://www.frogthinker.org
email: [EMAIL PROTECTED]
Skype: emmanuel_cecchet


--
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] Transactions and temp tables

2008-11-07 Thread Emmanuel Cecchet

Hi,

As I have not found yet an elegant solution to deal with the DROP 
CASCADE issue, here is a simpler patch that handles temp tables that are 
dropped at commit time. This is a good first step and we will try to 
elaborate further to support ON COMMIT DELETE ROWS.
I have also added a compilation of the tests I have even if some are not 
really relevant anymore without the support for empty temp tables but we 
will probably reuse them later.


Thanks in advance for the feedback,
Emmanuel

Emmanuel Cecchet wrote:

Heikki Linnakangas wrote:
Yes, I was trying to allow also ON COMMIT DROP and ON COMMIT DELETE 
ROW. An empty temp table at PREPARE time would be similar to an ON 
COMMIT DELETE ROW table.
I think you'll want to check explicitly that the table is defined 
with ON COMMIT DELETE ROWS, instead of checking that it's empty.
Where can I find the field containing the CREATE options for the temp 
table?
Yeah, thanks to MVCC, it's possible that the table looks empty to the 
transaction being prepared, using SnapshotNow, but there's some 
tuples that are still visible to other transactions. For example:


CREATE TEMPORARY TABLE foo (id int4);
INSERT INTO foo VALUES (1);
begin;
DELETE FROM foo;
PREPARE TRANSACTION 'foo'; -- doesn't error, because the table is 
empty, according to SnapshotNow
SELECT * FROM foo; -- Still shows the one row, because the deleting 
transaction hasn't committed yet.
Is that a problem? If your transaction isolation level is not 
serializable the SELECT will not block and return the current 
snapshot. From the transaction standpoint, it is fine that the 
transaction can prepare or am I missing something?
Actually, I did a test and if the temp table is created with 'on 
commit delete rows' option, the select blocks until the transaction is 
committed. This seems a normal behavior to me.

I don't think you can just ignore prepared temp relations in
findDependentObjects to avoid the lockup at backend exit. It's also 
used

for DROP CASCADE, for example.
Do you mean that it will break the DROP CASCADE behavior in general, 
or that would break the behavior for master/child temp tables?


For temp tables, I suppose.
I confirm that doing a drop cascade on a master temp table after a 
prepared transaction committed from another backend will not drop the 
children for now.


The hack in findDependentObjects still isn't enough, anyway. If you 
have a prepared transaction that created a temp table, the database 
doesn't shut down:


$ bin/pg_ctl -D data start
server starting
$ LOG:  database system was shut down at 2008-11-04 10:27:27 EST
LOG:  autovacuum launcher started
LOG:  database system is ready to accept connections

$ bin/psql postgres -c begin; CREATE TEMPORARY TABLE temp (id 
integer); PREPARE TRANSACTION 'foo';

PREPARE TRANSACTION
[EMAIL PROTECTED]:~/pgsql.fsmfork$ bin/pg_ctl -D data stop
LOG:  received smart shutdown request
LOG:  autovacuum launcher shutting down
waiting for server to shut 
down... 
failed

pg_ctl: server does not shut down
Interesting case, if the table is created but not accessed it is not 
enlisted and then the shutdown does not catch this dependency. The 
table should be enlisted at CREATE time as well.


The bookkeeping of prepared commit tables is just for the shutdown 
case right now. If you think it is a bad idea altogether to have 
session temp tables (even with delete rows on commit) that can cross 
commit boundaries, then we can remove that second bookkeeping and only 
allow temp tables that have been created withing the scope of the 
transaction.


I fixed the hash_freeze problem but this drop cascade on temp table 
seems to be an issue (if anyone uses that feature).


Emmanuel




--
Emmanuel Cecchet
FTO @ Frog Thinker 
Open Source Development  Consulting

--
Web: http://www.frogthinker.org
email: [EMAIL PROTECTED]
Skype: emmanuel_cecchet

### Eclipse Workspace Patch 1.0
#P Postgres-HEAD
Index: src/backend/access/heap/heapam.c
===
RCS file: /root/cvsrepo/pgsql/src/backend/access/heap/heapam.c,v
retrieving revision 1.268
diff -u -r1.268 heapam.c
--- src/backend/access/heap/heapam.c31 Oct 2008 19:40:26 -  1.268
+++ src/backend/access/heap/heapam.c7 Nov 2008 23:09:11 -
@@ -878,7 +878,7 @@
 
/* Make note that we've accessed a temporary relation */
if (r-rd_istemp)
-   MyXactAccessedTempRel = true;
+   enlistRelationIdFor2PCChecks(relationId);
 
pgstat_initstats(r);
 
@@ -926,7 +926,7 @@
 
/* Make note that we've accessed a temporary relation */
if (r-rd_istemp)
-   MyXactAccessedTempRel = true;
+   enlistRelationIdFor2PCChecks(relationId);
 
pgstat_initstats(r);
 
@@ -976,7 +976,7 @@
 
/* Make note that we've accessed a temporary relation */
if (r-rd_istemp)
-   MyXactAccessedTempRel = 

Re: [HACKERS] Transactions and temp tables

2008-11-04 Thread Heikki Linnakangas

Emmanuel Cecchet wrote:

What's the purpose of checking that a table is empty on prepare? I think
I'd feel more comfortable with the approach of only accepting PREPARE
TRANSACTIOn if the accessed temp tables have been created and destroyed
in the same transaction, to avoid possibly surprising behavior when a
temp table is kept locked by a prepared transaction and you try to drop
it later in the sesssion, but the patch allows more than that. I guess
accessing an existing ON COMMIT DELETE ROWS temp table would also be OK,
Yes, I was trying to allow also ON COMMIT DROP and ON COMMIT DELETE ROW. 
An empty temp table at PREPARE time would be similar to an ON COMMIT 
DELETE ROW table.


I think you'll want to check explicitly that the table is defined with 
ON COMMIT DELETE ROWS, instead of checking that it's empty.



 but checking that there's no visible rows in the table doesn't achieve
that.
If the relation exist but contains no row, is it possible that the table 
is not empty? What would I need to do to ensure that the table is empty?


Yeah, thanks to MVCC, it's possible that the table looks empty to the 
transaction being prepared, using SnapshotNow, but there's some tuples 
that are still visible to other transactions. For example:


CREATE TEMPORARY TABLE foo (id int4);
INSERT INTO foo VALUES (1);
begin;
DELETE FROM foo;
PREPARE TRANSACTION 'foo'; -- doesn't error, because the table is empty, 
according to SnapshotNow
SELECT * FROM foo; -- Still shows the one row, because the deleting 
transaction hasn't committed yet.



I don't think you can just ignore prepared temp relations in
findDependentObjects to avoid the lockup at backend exit. It's also used
for DROP CASCADE, for example.
Do you mean that it will break the DROP CASCADE behavior in general, or 
that would break the behavior for master/child temp tables?


For temp tables, I suppose.

The hack in findDependentObjects still isn't enough, anyway. If you have 
a prepared transaction that created a temp table, the database doesn't 
shut down:


$ bin/pg_ctl -D data start
server starting
$ LOG:  database system was shut down at 2008-11-04 10:27:27 EST
LOG:  autovacuum launcher started
LOG:  database system is ready to accept connections

$ bin/psql postgres -c begin; CREATE TEMPORARY TABLE temp (id integer); 
PREPARE TRANSACTION 'foo';

PREPARE TRANSACTION
[EMAIL PROTECTED]:~/pgsql.fsmfork$ bin/pg_ctl -D data stop
LOG:  received smart shutdown request
LOG:  autovacuum launcher shutting down
waiting for server to shut 
down... failed

pg_ctl: server does not shut down


By the way, 
does Postgres support child temp tables?


Yes.

--
  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] Transactions and temp tables

2008-11-04 Thread Emmanuel Cecchet

Heikki Linnakangas wrote:
Yes, I was trying to allow also ON COMMIT DROP and ON COMMIT DELETE 
ROW. An empty temp table at PREPARE time would be similar to an ON 
COMMIT DELETE ROW table.
I think you'll want to check explicitly that the table is defined with 
ON COMMIT DELETE ROWS, instead of checking that it's empty.

Where can I find the field containing the CREATE options for the temp table?
Yeah, thanks to MVCC, it's possible that the table looks empty to the 
transaction being prepared, using SnapshotNow, but there's some tuples 
that are still visible to other transactions. For example:


CREATE TEMPORARY TABLE foo (id int4);
INSERT INTO foo VALUES (1);
begin;
DELETE FROM foo;
PREPARE TRANSACTION 'foo'; -- doesn't error, because the table is 
empty, according to SnapshotNow
SELECT * FROM foo; -- Still shows the one row, because the deleting 
transaction hasn't committed yet.
Is that a problem? If your transaction isolation level is not 
serializable the SELECT will not block and return the current snapshot. 
From the transaction standpoint, it is fine that the transaction can 
prepare or am I missing something?
Actually, I did a test and if the temp table is created with 'on commit 
delete rows' option, the select blocks until the transaction is 
committed. This seems a normal behavior to me.

I don't think you can just ignore prepared temp relations in
findDependentObjects to avoid the lockup at backend exit. It's also 
used

for DROP CASCADE, for example.
Do you mean that it will break the DROP CASCADE behavior in general, 
or that would break the behavior for master/child temp tables?


For temp tables, I suppose.
I confirm that doing a drop cascade on a master temp table after a 
prepared transaction committed from another backend will not drop the 
children for now.


The hack in findDependentObjects still isn't enough, anyway. If you 
have a prepared transaction that created a temp table, the database 
doesn't shut down:


$ bin/pg_ctl -D data start
server starting
$ LOG:  database system was shut down at 2008-11-04 10:27:27 EST
LOG:  autovacuum launcher started
LOG:  database system is ready to accept connections

$ bin/psql postgres -c begin; CREATE TEMPORARY TABLE temp (id 
integer); PREPARE TRANSACTION 'foo';

PREPARE TRANSACTION
[EMAIL PROTECTED]:~/pgsql.fsmfork$ bin/pg_ctl -D data stop
LOG:  received smart shutdown request
LOG:  autovacuum launcher shutting down
waiting for server to shut 
down... 
failed

pg_ctl: server does not shut down
Interesting case, if the table is created but not accessed it is not 
enlisted and then the shutdown does not catch this dependency. The table 
should be enlisted at CREATE time as well.


The bookkeeping of prepared commit tables is just for the shutdown case 
right now. If you think it is a bad idea altogether to have session temp 
tables (even with delete rows on commit) that can cross commit 
boundaries, then we can remove that second bookkeeping and only allow 
temp tables that have been created withing the scope of the transaction.


I fixed the hash_freeze problem but this drop cascade on temp table 
seems to be an issue (if anyone uses that feature).


Emmanuel

--
Emmanuel Cecchet
FTO @ Frog Thinker 
Open Source Development  Consulting

--
Web: http://www.frogthinker.org
email: [EMAIL PROTECTED]
Skype: emmanuel_cecchet


--
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] Transactions and temp tables

2008-11-03 Thread Heikki Linnakangas

Emmanuel Cecchet wrote:
Here is the latest patch and the regression tests for the temp tables 
and 2PC issue.


This fails:

postgres=# begin;
BEGIN
postgres=# CREATE TEMPORARY TABLE temp1 (id int4);
CREATE TABLE
postgres=# PREPARE TRANSACTION 'foo';
PREPARE TRANSACTION
postgres=# CREATE TEMPORARY TABLE temp2 (id int4);
ERROR:  cannot insert into frozen hashtable accessed temp tables

I don't understand the bookkeeping of accessed and prepared temp tables
in general. What's it for?

The comments on preparedTempRel says that it keeps track of accessed
temporary relations that have been prepared commit but not committed
yet. That's never going to work as a backend-private hash table,
because there's no way to remove entries from it when the prepared
transaction is committed or rolled back from another backend.

What's the purpose of checking that a table is empty on prepare? I think
I'd feel more comfortable with the approach of only accepting PREPARE
TRANSACTIOn if the accessed temp tables have been created and destroyed
in the same transaction, to avoid possibly surprising behavior when a
temp table is kept locked by a prepared transaction and you try to drop
it later in the sesssion, but the patch allows more than that. I guess
accessing an existing ON COMMIT DELETE ROWS temp table would also be OK,
 but checking that there's no visible rows in the table doesn't achieve
that.

I don't think you can just ignore prepared temp relations in
findDependentObjects to avoid the lockup at backend exit. It's also used
for DROP CASCADE, for example.

--
  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] Transactions and temp tables

2008-11-03 Thread Emmanuel Cecchet

Hi Heikki,


Emmanuel Cecchet wrote:
Here is the latest patch and the regression tests for the temp tables 
and 2PC issue.


This fails:

postgres=# begin;
BEGIN
postgres=# CREATE TEMPORARY TABLE temp1 (id int4);
CREATE TABLE
postgres=# PREPARE TRANSACTION 'foo';
PREPARE TRANSACTION
postgres=# CREATE TEMPORARY TABLE temp2 (id int4);
ERROR:  cannot insert into frozen hashtable accessed temp tables

I will address that.

I don't understand the bookkeeping of accessed and prepared temp tables
in general. What's it for?
Right now (in 8.3) the bookkeeping prevents a transaction that has used 
a temp table to prepare commit. As you mentioned earlier 
(http://archives.postgresql.org/pgsql-hackers/2008-02/msg01277.php) we 
should be able to allow CREATE+DROP in the same transaction.

The comments on preparedTempRel says that it keeps track of accessed
temporary relations that have been prepared commit but not committed
yet. That's never going to work as a backend-private hash table,
because there's no way to remove entries from it when the prepared
transaction is committed or rolled back from another backend.
It does not really matter since we only allow empty temp tables at 
prepared time. And the transaction can only be prepared locally. If the 
transaction is committed or rolled back from another backend, the only 
thing that can happen is that tables that were created in the 
transaction will remain in the list. They will be ignored at the next 
prepare since the relation will not exist anymore. Once again, the 
tables remaining in the list after prepare are empty.

What's the purpose of checking that a table is empty on prepare? I think
I'd feel more comfortable with the approach of only accepting PREPARE
TRANSACTIOn if the accessed temp tables have been created and destroyed
in the same transaction, to avoid possibly surprising behavior when a
temp table is kept locked by a prepared transaction and you try to drop
it later in the sesssion, but the patch allows more than that. I guess
accessing an existing ON COMMIT DELETE ROWS temp table would also be OK,
Yes, I was trying to allow also ON COMMIT DROP and ON COMMIT DELETE ROW. 
An empty temp table at PREPARE time would be similar to an ON COMMIT 
DELETE ROW table.

 but checking that there's no visible rows in the table doesn't achieve
that.
If the relation exist but contains no row, is it possible that the table 
is not empty? What would I need to do to ensure that the table is empty?

I don't think you can just ignore prepared temp relations in
findDependentObjects to avoid the lockup at backend exit. It's also used
for DROP CASCADE, for example.
Do you mean that it will break the DROP CASCADE behavior in general, or 
that would break the behavior for master/child temp tables? By the way, 
does Postgres support child temp tables?


Thanks for the feedback. I will address the problem of the frozen hash 
list but let me know what you think of the other potential issues.


Emmanuel

--
Emmanuel Cecchet
FTO @ Frog Thinker 
Open Source Development  Consulting

--
Web: http://www.frogthinker.org
email: [EMAIL PROTECTED]
Skype: emmanuel_cecchet


--
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] Transactions and temp tables

2008-10-14 Thread Emmanuel Cecchet

Emmanuel Cecchet wrote:
Here is the latest patch and the regression tests for the temp tables 
and 2PC issue.

Is there a way to stop and restart postmaster between 2 tests?

Thanks for your feedback,
Emmanuel

I did not get any comment on that one.
How should I proceed so that the patch integration can be considered for 
8.4?


Emmanuel

--
Emmanuel Cecchet
FTO @ Frog Thinker 
Open Source Development  Consulting

--
Web: http://www.frogthinker.org
email: [EMAIL PROTECTED]
Skype: emmanuel_cecchet


--
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] Transactions and temp tables

2008-10-14 Thread Alvaro Herrera
Emmanuel Cecchet wrote:
 Emmanuel Cecchet wrote:
 Here is the latest patch and the regression tests for the temp tables  
 and 2PC issue.
 Is there a way to stop and restart postmaster between 2 tests?

 Thanks for your feedback,
 Emmanuel
 I did not get any comment on that one.
 How should I proceed so that the patch integration can be considered for  
 8.4?

http://wiki.postgresql.org/wiki/Submitting_a_Patch

-- 
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] Transactions and temp tables

2008-10-10 Thread Emmanuel Cecchet

Hi all,

Here is the latest patch and the regression tests for the temp tables 
and 2PC issue.

Is there a way to stop and restart postmaster between 2 tests?

Thanks for your feedback,
Emmanuel

--
Emmanuel Cecchet
FTO @ Frog Thinker 
Open Source Development  Consulting

--
Web: http://www.frogthinker.org
email: [EMAIL PROTECTED]
Skype: emmanuel_cecchet

### Eclipse Workspace Patch 1.0
#P Postgres-HEAD
Index: src/test/regress/parallel_schedule
===
RCS file: /root/cvsrepo/pgsql/src/test/regress/parallel_schedule,v
retrieving revision 1.49
diff -u -r1.49 parallel_schedule
--- src/test/regress/parallel_schedule  4 Oct 2008 21:56:55 -   1.49
+++ src/test/regress/parallel_schedule  10 Oct 2008 18:33:01 -
@@ -90,3 +90,19 @@
 
 # run tablespace by itself
 test: tablespace
+
+# 
+# 2PC related tests
+# 
+test: 2pc_persistent_table 2pc_on_delete_rows_transaction 2pc_on_commit_drop 
2pc_temp_table_transaction 2pc_temp_table_rollback 2pc_temp_table_savepoint 
2pc_temp_table_failure
+test: 2pc_dirty_buffer_check 
+test: 2pc_temp_table_session
+test: 2pc_on_delete_rows_session
+# The following tests must be executing in sequence, 
+# do not alter the order nor try to execute them in parallel
+test: 2pc_temp_table_prepared_not_committed
+test: 2pc_temp_table_commit_prepared
+# This test must be run last to check if the database properly 
+# shutdowns with a prepared transaction that is not committed
+test: 2pc_temp_table_prepared_not_committed
+ 
\ No newline at end of file
Index: src/test/regress/serial_schedule
===
RCS file: /root/cvsrepo/pgsql/src/test/regress/serial_schedule,v
retrieving revision 1.46
diff -u -r1.46 serial_schedule
--- src/test/regress/serial_schedule4 Oct 2008 21:56:55 -   1.46
+++ src/test/regress/serial_schedule10 Oct 2008 18:33:01 -
@@ -118,3 +118,20 @@
 test: xml
 test: stats
 test: tablespace
+test: 2pc_persistent_table
+test: 2pc_on_delete_rows_transaction
+test: 2pc_on_commit_drop
+test: 2pc_temp_table_transaction
+test: 2pc_temp_table_rollback
+test: 2pc_temp_table_savepoint
+test: 2pc_dirty_buffer_check 
+test: 2pc_temp_table_session
+test: 2pc_on_delete_rows_session
+test: 2pc_temp_table_failure
+# The following tests must be executing in sequence, 
+# do not alter the order nor try to execute them in parallel
+test: 2pc_temp_table_prepared_not_committed
+test: 2pc_temp_table_commit_prepared
+# This test must be run last to check if the database properly 
+# shutdowns with a prepared transaction that is not committed
+test: 2pc_temp_table_prepared_not_committed
Index: src/test/regress/expected/2pc_temp_table_failure.out
===
RCS file: src/test/regress/expected/2pc_temp_table_failure.out
diff -N src/test/regress/expected/2pc_temp_table_failure.out
--- /dev/null   1 Jan 1970 00:00:00 -
+++ src/test/regress/expected/2pc_temp_table_failure.out1 Jan 1970 
00:00:00 -
@@ -0,0 +1,8 @@
+-- Existing non-empty temp table at commit time should still fail
+begin;
+create temp table foo(x int);
+insert into foo values(1);
+prepare transaction 'existingTempTableShouldFail';
+ERROR:  cannot PREPARE a transaction that has operated on temporary tables 
that are not empty at commit time
+commit prepared 'existingTempTableShouldFail';
+ERROR:  prepared transaction with identifier existingTempTableShouldFail 
does not exist
Index: src/test/regress/expected/2pc_temp_table_commit_prepared.out
===
RCS file: src/test/regress/expected/2pc_temp_table_commit_prepared.out
diff -N src/test/regress/expected/2pc_temp_table_commit_prepared.out
--- /dev/null   1 Jan 1970 00:00:00 -
+++ src/test/regress/expected/2pc_temp_table_commit_prepared.out1 Jan 
1970 00:00:00 -
@@ -0,0 +1,8 @@
+-- The purpose of this test is to test the proper termination of
+-- a session with a prepared transaction that has accessed a temp table
+--
+-- This test has to be called in sequence after 
2pc_temp_table_prepared_not_committed.sql
+commit prepared 'preparedNonCommittedFoo';
+-- The table should not exist anymore in this session
+drop table foo;
+ERROR:  table foo does not exist
Index: src/test/regress/expected/2pc_on_delete_rows_session.out
===
RCS file: src/test/regress/expected/2pc_on_delete_rows_session.out
diff -N src/test/regress/expected/2pc_on_delete_rows_session.out
--- /dev/null   1 Jan 1970 00:00:00 -
+++ src/test/regress/expected/2pc_on_delete_rows_session.out1 Jan 1970 
00:00:00 -
@@ -0,0 +1,7 @@
+-- Temp table with ON DELETE ROWS option (session scope)
+create temp table foo(x int) on commit delete rows;
+begin;
+insert into foo values(1);
+prepare transaction 'onCommitDeleteRowsTempTableShouldSucceed';
+commit prepared 

Re: [HACKERS] Transactions and temp tables

2008-10-09 Thread Emmanuel Cecchet

Hi,

I am attaching a new patch that deals with the issue of the locks on 
temporary tables that have been accessed in transactions that have been 
prepared but not committed.
I have added another list that keeps track of temp tables accessed by 
transactions that are prepared but not committed. The RemoveTempTable 
callback does not try to acquire locks on these tables. Now postmaster 
can terminate even with transactions in the prepared state that accessed 
temp tables.


Let me know what you think.
manu

Tom Lane wrote:

Emmanuel Cecchet [EMAIL PROTECTED] writes:
  
Ok, so actually I don't see any different behavior between a temp table 
or a regular table. The locking happens the same way and as long as the 
commit prepared happens (potentially in another session), the lock is 
released at commit time which seems to make sense.



Right, the problem is that you can't shut down the original backend
because it'll try to drop the temp table at exit, and then block on
the lock that the prepared xact is holding.  From a database management
standpoint that is unacceptable --- it means for instance that you can't
shut down the database cleanly while such a prepared transaction is
pending.  The difference from a regular table is that no such automatic
action is taken at backend exit for regular tables.

The whole business of having restrictions on temp table access is
annoying; I wish we could get rid of them not add complexity to
enforcing them.  The local-buffer-management end of the issue seems
readily solvable: we need only decree that PREPARE has to flush out any
dirty local buffers (and maybe discard local buffers altogether, not
sure).  But I've not been able to see a decent solution to the lock
behavior.

regards, tom lane

  


### Eclipse Workspace Patch 1.0
#P Postgres-HEAD
Index: src/backend/access/heap/heapam.c
===
RCS file: /root/cvsrepo/pgsql/src/backend/access/heap/heapam.c,v
retrieving revision 1.264
diff -u -r1.264 heapam.c
--- src/backend/access/heap/heapam.c30 Sep 2008 10:52:10 -  1.264
+++ src/backend/access/heap/heapam.c9 Oct 2008 21:44:04 -
@@ -878,7 +878,7 @@
 
/* Make note that we've accessed a temporary relation */
if (r-rd_istemp)
-   MyXactAccessedTempRel = true;
+   enlistRelationIdFor2PCChecks(relationId);
 
pgstat_initstats(r);
 
@@ -926,7 +926,7 @@
 
/* Make note that we've accessed a temporary relation */
if (r-rd_istemp)
-   MyXactAccessedTempRel = true;
+   enlistRelationIdFor2PCChecks(relationId);
 
pgstat_initstats(r);
 
@@ -976,7 +976,7 @@
 
/* Make note that we've accessed a temporary relation */
if (r-rd_istemp)
-   MyXactAccessedTempRel = true;
+   enlistRelationIdFor2PCChecks(relationId);
 
pgstat_initstats(r);
 
Index: src/backend/access/transam/xact.c
===
RCS file: /root/cvsrepo/pgsql/src/backend/access/transam/xact.c,v
retrieving revision 1.265
diff -u -r1.265 xact.c
--- src/backend/access/transam/xact.c   11 Aug 2008 11:05:10 -  1.265
+++ src/backend/access/transam/xact.c   9 Oct 2008 21:44:04 -
@@ -47,6 +47,7 @@
 #include utils/memutils.h
 #include utils/relcache.h
 #include utils/snapmgr.h
+#include utils/tqual.h
 #include utils/xml.h
 #include pg_trace.h
 
@@ -65,13 +66,6 @@
 intCommitDelay = 0;/* precommit delay in 
microseconds */
 intCommitSiblings = 5; /* # concurrent xacts needed to 
sleep */
 
-/*
- * MyXactAccessedTempRel is set when a temporary relation is accessed.
- * We don't allow PREPARE TRANSACTION in that case.  (This is global
- * so that it can be set from heapam.c.)
- */
-bool   MyXactAccessedTempRel = false;
-
 
 /*
  * transaction states - transaction state from server perspective
@@ -209,6 +203,13 @@
  */
 static MemoryContext TransactionAbortContext = NULL;
 
+/* Hash table containing Oids of accessed temporary relations */
+HTAB   *accessedTempRel;
+/* Hash table containing Oids of accessed temporary relations that have been
+ * prepared commit but not committed yet
+ */
+HTAB   *preparedTempRel;
+
 /*
  * List of add-on start- and end-of-xact callbacks
  */
@@ -250,6 +251,7 @@
 SubTransactionId mySubid,
 SubTransactionId parentSubid);
 static void CleanupTransaction(void);
+static void CleanupAccessedTempRel(void);
 static void CommitTransaction(void);
 static TransactionId RecordTransactionAbort(bool isSubXact);
 static void StartTransaction(void);
@@ -624,7 +626,7 @@
 
/* Propagate new command ID into static snapshots */
SnapshotSetCommandId(currentCommandId);
-   
+
/*
 * Make any catalog changes 

Re: [HACKERS] Transactions and temp tables

2008-10-08 Thread Emmanuel Cecchet

Heikki Linnakangas wrote:
I was thinking of a transaction that's just prepared (1st phase), but 
not committed or rolled back:


postgres=# CREATE TEMP TABLE foo (bar int);
CREATE TABLE
postgres=# BEGIN;
BEGIN
postgres=# DROP TABLE foo;
DROP TABLE
postgres=# PREPARE TRANSACTION '2pc';
PREPARE TRANSACTION
postgres=# SELECT * FROM foo;
blocks

Furthermore, it looks like the backend refuses to shut down, even if 
you end the psql session, because RemoveTempRelations() is called on 
backend shutdown and it gets blocked on that lock.
Thanks for the example, I get it now. Does it make sense to allow any 
request execution between PREPARE TRANSACTION and the subsequent COMMIT 
or ROLLBACK?
I did the same experiment with a regular table (not a temp table) and it 
blocks exactly the same way, so I don't think that the problem is 
specific to temp tables.
Once PREPARE has been executed, the transaction state is restored to 
TRANS_DEFAULT, but I wonder if we should not have a specific 
TRANS_PREPARED state in which we can only authorize a COMMIT or a 
ROLLBACK. Is there any reasonable use case where someone would have to 
execute requests between PREPARE and COMMIT/ROLLBACK?


Let me know what you think of the additional TRANS_PREPARED transaction 
state. It looks like the behavior of what happens between PREPARE and 
COMMIT/ROLLBACK is pretty much undefined.


Emmanuel

--
Emmanuel Cecchet
FTO @ Frog Thinker 
Open Source Development  Consulting

--
Web: http://www.frogthinker.org
email: [EMAIL PROTECTED]
Skype: emmanuel_cecchet


--
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] Transactions and temp tables

2008-10-08 Thread Tom Lane
Emmanuel Cecchet [EMAIL PROTECTED] writes:
 Thanks for the example, I get it now. Does it make sense to allow any 
 request execution between PREPARE TRANSACTION and the subsequent COMMIT 
 or ROLLBACK?

Yes.  Don't even think of trying to disallow that.  The COMMIT doesn't
even have to happen in the same session, anyway.

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] Transactions and temp tables

2008-10-08 Thread Heikki Linnakangas

Emmanuel Cecchet wrote:
Also, even if the table is created and dropped in the same 
transaction, a subsequent transaction that tries to create and drop 
the table gets blocked on the lock. I suppose we could just say that 
that's the way it works, but I'm afraid it will come as a nasty 
surprise, making the feature a lot less useful.
I do not get that one, if the table is dropped in the transaction the 
lock is released. Why would another transaction be blocked when trying 
to create/drop another temp table?


I was thinking of a transaction that's just prepared (1st phase), but 
not committed or rolled back:


postgres=# CREATE TEMP TABLE foo (bar int);
CREATE TABLE
postgres=# BEGIN;
BEGIN
postgres=# DROP TABLE foo;
DROP TABLE
postgres=# PREPARE TRANSACTION '2pc';
PREPARE TRANSACTION
postgres=# SELECT * FROM foo;
blocks

Furthermore, it looks like the backend refuses to shut down, even if you 
end the psql session, because RemoveTempRelations() is called on backend 
shutdown and it gets blocked on that lock.


--
  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] Transactions and temp tables

2008-10-08 Thread Emmanuel Cecchet

Tom Lane wrote:

Emmanuel Cecchet [EMAIL PROTECTED] writes:
  
Thanks for the example, I get it now. Does it make sense to allow any 
request execution between PREPARE TRANSACTION and the subsequent COMMIT 
or ROLLBACK?



Yes.  Don't even think of trying to disallow that.  The COMMIT doesn't
even have to happen in the same session, anyway.
  
Ok, so actually I don't see any different behavior between a temp table 
or a regular table. The locking happens the same way and as long as the 
commit prepared happens (potentially in another session), the lock is 
released at commit time which seems to make sense.
The issue that Heikki was mentioning about the server not shutting down 
seems to happen as soon as you have a single transaction that has 
prepared commit but not commit/rollback yet. This seems also independent 
of whether you are using a temp table or not.

It seems that the patch did not alter the behavior of PG in that regard.

What do you think?
Emmanuel

--
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] Transactions and temp tables

2008-10-08 Thread Tom Lane
Emmanuel Cecchet [EMAIL PROTECTED] writes:
 Ok, so actually I don't see any different behavior between a temp table 
 or a regular table. The locking happens the same way and as long as the 
 commit prepared happens (potentially in another session), the lock is 
 released at commit time which seems to make sense.

Right, the problem is that you can't shut down the original backend
because it'll try to drop the temp table at exit, and then block on
the lock that the prepared xact is holding.  From a database management
standpoint that is unacceptable --- it means for instance that you can't
shut down the database cleanly while such a prepared transaction is
pending.  The difference from a regular table is that no such automatic
action is taken at backend exit for regular tables.

The whole business of having restrictions on temp table access is
annoying; I wish we could get rid of them not add complexity to
enforcing them.  The local-buffer-management end of the issue seems
readily solvable: we need only decree that PREPARE has to flush out any
dirty local buffers (and maybe discard local buffers altogether, not
sure).  But I've not been able to see a decent solution to the lock
behavior.

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] Transactions and temp tables

2008-10-07 Thread Heikki Linnakangas

Emmanuel Cecchet wrote:
Instead of relying on a boolean that tells if a temp table was accessed, 
I keep a list of the Oid for the temp tables accessed in the transaction 
and at prepare commit time, I check if the relations are still valid. I 
also added a check to allow empty temp tables at prepare commit time 
(this allows to use temp tables with 'on commit delete rows' options.


I am attaching the patch and the use cases I have been using to test it. 
The test cases try to compile the various use cases that I have seen 
reported on the list.


Thanks for looking into this.

The patch allows preparing any transaction that has dropped the temp 
table, even if it wasn't created in the same transaction. Is that sane?


Also, even if the table is created and dropped in the same transaction, 
a subsequent transaction that tries to create and drop the table gets 
blocked on the lock. I suppose we could just say that that's the way it 
works, but I'm afraid it will come as a nasty surprise, making the 
feature a lot less useful.


The fixed-size array of temp table oids is an unnecessary limitation. A 
list or hash table would be better.


Let me know what you think of the patch and if it 
could be applied to 8.3 and 8.4?


Not to 8.3. We only back-patch bug-fixes, and this isn't one.

--
  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] Transactions and temp tables

2008-10-07 Thread Emmanuel Cecchet

Hi Heikki,

The patch allows preparing any transaction that has dropped the temp 
table, even if it wasn't created in the same transaction. Is that sane?
If you have a temp table created with an 'on commit delete rows' option 
in another transaction, it would be fine to drop it in another 
transaction. If the temp table was created without any on commit option, 
it could only cross prepare commit if it is empty and then it could be 
safely dropped in another transaction. That does not seem to insane for 
me if you need temp tables for a session.
Also, even if the table is created and dropped in the same 
transaction, a subsequent transaction that tries to create and drop 
the table gets blocked on the lock. I suppose we could just say that 
that's the way it works, but I'm afraid it will come as a nasty 
surprise, making the feature a lot less useful.
I do not get that one, if the table is dropped in the transaction the 
lock is released. Why would another transaction be blocked when trying 
to create/drop another temp table?
When I run my test cases (see attached file in previous mail), I 
create/drop multiple times the same temp table in different transactions 
and I do not experience any blocking.
The fixed-size array of temp table oids is an unnecessary limitation. 
A list or hash table would be better.

You are right, I will fix that.
Let me know what you think of the patch and if it could be applied to 
8.3 and 8.4?

Not to 8.3. We only back-patch bug-fixes, and this isn't one.

Ok understood.

Thanks for your feedback and don't hesitate to enlighten me on the 
potential locking issue I did not understand.

Emmanuel

--
Emmanuel Cecchet
FTO @ Frog Thinker 
Open Source Development  Consulting

--
Web: http://www.frogthinker.org
email: [EMAIL PROTECTED]
Skype: emmanuel_cecchet


--
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] Transactions and temp tables

2008-10-07 Thread Emmanuel Cecchet

Heikki,

Here is a new version of the patch using a hash table as you suggested.
I also include the tests that I have added to the regression test suite 
to test the various scenarios.
All patches are based on Postgres 8.3.3, let me know if you want me to 
generate patch for 8.4.


Thanks in advance for your feedback,
Emmanuel


Emmanuel Cecchet wrote:

Hi Heikki,

The patch allows preparing any transaction that has dropped the temp 
table, even if it wasn't created in the same transaction. Is that sane?
If you have a temp table created with an 'on commit delete rows' 
option in another transaction, it would be fine to drop it in another 
transaction. If the temp table was created without any on commit 
option, it could only cross prepare commit if it is empty and then it 
could be safely dropped in another transaction. That does not seem to 
insane for me if you need temp tables for a session.
Also, even if the table is created and dropped in the same 
transaction, a subsequent transaction that tries to create and drop 
the table gets blocked on the lock. I suppose we could just say that 
that's the way it works, but I'm afraid it will come as a nasty 
surprise, making the feature a lot less useful.
I do not get that one, if the table is dropped in the transaction the 
lock is released. Why would another transaction be blocked when trying 
to create/drop another temp table?
When I run my test cases (see attached file in previous mail), I 
create/drop multiple times the same temp table in different 
transactions and I do not experience any blocking.
The fixed-size array of temp table oids is an unnecessary limitation. 
A list or hash table would be better.

You are right, I will fix that.
Let me know what you think of the patch and if it could be applied 
to 8.3 and 8.4?

Not to 8.3. We only back-patch bug-fixes, and this isn't one.

Ok understood.

Thanks for your feedback and don't hesitate to enlighten me on the 
potential locking issue I did not understand.

Emmanuel




--
Emmanuel Cecchet
FTO @ Frog Thinker 
Open Source Development  Consulting

--
Web: http://www.frogthinker.org
email: [EMAIL PROTECTED]
Skype: emmanuel_cecchet


--
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] Transactions and temp tables

2008-10-07 Thread David Fetter
On Tue, Oct 07, 2008 at 04:57:37PM -0400, Emmanuel Cecchet wrote:
 Heikki,

 Here is a new version of the patch using a hash table as you
 suggested.  I also include the tests that I have added to the
 regression test suite  to test the various scenarios.  All patches
 are based on Postgres 8.3.3, let me know if you want me to  generate
 patch for 8.4.

CVS TIP is the only place where new features, like this, go :)

I didn't see the attachment anyhow...

Cheers,
David.
-- 
David Fetter [EMAIL PROTECTED] http://fetter.org/
Phone: +1 415 235 3778  AIM: dfetter666  Yahoo!: dfetter
Skype: davidfetter  XMPP: [EMAIL PROTECTED]

Remember to vote!
Consider donating to Postgres: http://www.postgresql.org/about/donate

-- 
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] Transactions and temp tables

2008-10-07 Thread Emmanuel Cecchet

Hi,


On Tue, Oct 07, 2008 at 04:57:37PM -0400, Emmanuel Cecchet wrote:
  

Heikki,

Here is a new version of the patch using a hash table as you
suggested.  I also include the tests that I have added to the
regression test suite  to test the various scenarios.  All patches
are based on Postgres 8.3.3, let me know if you want me to  generate
patch for 8.4.



CVS TIP is the only place where new features, like this, go :)
  
I looked at the Wiki and it looks like I should add en entry (assuming I 
get a patch for the current CVS HEAD) to CommitFest 2008-11. Is that 
correct?

I didn't see the attachment anyhow...
  

Good point! The same with the attachments now!

Thanks,
manu
### Eclipse Workspace Patch 1.0
#P Postgres-8.3.3
Index: src/include/access/xact.h
===
RCS file: /root/cvsrepo/pgsql/src/include/access/xact.h,v
retrieving revision 1.93.2.1
diff -u -r1.93.2.1 xact.h
--- src/include/access/xact.h   4 Mar 2008 19:54:13 -   1.93.2.1
+++ src/include/access/xact.h   7 Oct 2008 20:29:47 -
@@ -18,6 +18,7 @@
 #include nodes/pg_list.h
 #include storage/relfilenode.h
 #include utils/timestamp.h
+#include postgres_ext.h
 
 
 /*
@@ -44,8 +45,8 @@
 /* Asynchronous commits */
 extern bool XactSyncCommit;
 
-/* Kluge for 2PC support */
-extern bool MyXactAccessedTempRel;
+/* List of temp tables accessed during a transaction for 2PC support */
+extern void enlistRelationIdFor2PCChecks(Oid relationId);
 
 /*
  * start- and end-of-transaction callbacks for dynamically loaded modules
Index: src/backend/access/heap/heapam.c
===
RCS file: /root/cvsrepo/pgsql/src/backend/access/heap/heapam.c,v
retrieving revision 1.249.2.2
diff -u -r1.249.2.2 heapam.c
--- src/backend/access/heap/heapam.c8 Mar 2008 21:58:07 -   
1.249.2.2
+++ src/backend/access/heap/heapam.c7 Oct 2008 20:29:47 -
@@ -870,7 +870,7 @@
 
/* Make note that we've accessed a temporary relation */
if (r-rd_istemp)
-   MyXactAccessedTempRel = true;
+   enlistRelationIdFor2PCChecks(relationId);
 
pgstat_initstats(r);
 
@@ -918,7 +918,7 @@
 
/* Make note that we've accessed a temporary relation */
if (r-rd_istemp)
-   MyXactAccessedTempRel = true;
+   enlistRelationIdFor2PCChecks(relationId);
 
pgstat_initstats(r);
 
@@ -968,7 +968,7 @@
 
/* Make note that we've accessed a temporary relation */
if (r-rd_istemp)
-   MyXactAccessedTempRel = true;
+   enlistRelationIdFor2PCChecks(relationId);
 
pgstat_initstats(r);
 
Index: src/backend/access/transam/xact.c
===
RCS file: /root/cvsrepo/pgsql/src/backend/access/transam/xact.c,v
retrieving revision 1.257.2.2
diff -u -r1.257.2.2 xact.c
--- src/backend/access/transam/xact.c   26 Apr 2008 23:35:33 -  
1.257.2.2
+++ src/backend/access/transam/xact.c   7 Oct 2008 20:29:47 -
@@ -62,13 +62,6 @@
 intCommitDelay = 0;/* precommit delay in 
microseconds */
 intCommitSiblings = 5; /* # concurrent xacts needed to 
sleep */
 
-/*
- * MyXactAccessedTempRel is set when a temporary relation is accessed.
- * We don't allow PREPARE TRANSACTION in that case.  (This is global
- * so that it can be set from heapam.c.)
- */
-bool   MyXactAccessedTempRel = false;
-
 
 /*
  * transaction states - transaction state from server perspective
@@ -206,6 +199,9 @@
  */
 static MemoryContext TransactionAbortContext = NULL;
 
+/* Hash table containing Oids of accessed temporary relations */
+HTAB   *accessedTempRel;
+
 /*
  * List of add-on start- and end-of-xact callbacks
  */
@@ -1512,7 +1508,6 @@
XactIsoLevel = DefaultXactIsoLevel;
XactReadOnly = DefaultXactReadOnly;
forceSyncCommit = false;
-   MyXactAccessedTempRel = false;
 
/*
 * reinitialize within-transaction counters
@@ -1777,6 +1772,35 @@
RESUME_INTERRUPTS();
 }
 
+/* 
+ * enlistRelationIdFor2PCChecks - enlist a relation in the list of
+ * resources to check at PREPARE COMMIT time if we are part of
+ * a 2PC transaction. The resource will be removed from the list
+ * if the table is dropped before commit.
+ * 
+ */
+void
+enlistRelationIdFor2PCChecks(Oid relationId)
+{
+   /*
+* Each time a temporary relation is accessed, it is added to the
+* accessedTempRel list. PREPARE TRANSACTION will fail if any
+* of the accessed relation is still valid (not dropped).  (This is
+* called from from heapam.c.)
+*/
+   if (accessedTempRel == NULL)
+   { // Allocate the list on-demand
+   HASHCTL ctl;
+
+   ctl.keysize = sizeof(Oid);
+   ctl.entrysize = sizeof(Oid);
+   

Re: [HACKERS] Transactions and temp tables

2008-10-07 Thread David Fetter
On Tue, Oct 07, 2008 at 06:12:14PM -0400, Emmanuel Cecchet wrote:
 Hi,

 On Tue, Oct 07, 2008 at 04:57:37PM -0400, Emmanuel Cecchet wrote:
   
 Heikki,

 Here is a new version of the patch using a hash table as you
 suggested.  I also include the tests that I have added to the
 regression test suite  to test the various scenarios.  All patches
 are based on Postgres 8.3.3, let me know if you want me to
 generate patch for 8.4.

 CVS TIP is the only place where new features, like this, go :)
   
 I looked at the Wiki and it looks like I should add en entry
 (assuming I  get a patch for the current CVS HEAD) to CommitFest
 2008-11. Is that  correct?
 
 I didn't see the attachment anyhow...
   
 Good point! The same with the attachments now!

Perhaps we did not make this clear.  The patch is a new feature.  New
features are not going into 8.3, as it has already been released.

Make a patch against CVS TIP aka 8.4, and re-submit.

Cheers,
David
-- 
David Fetter [EMAIL PROTECTED] http://fetter.org/
Phone: +1 415 235 3778  AIM: dfetter666  Yahoo!: dfetter
Skype: davidfetter  XMPP: [EMAIL PROTECTED]

Remember to vote!
Consider donating to Postgres: http://www.postgresql.org/about/donate

-- 
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] Transactions and temp tables

2008-10-07 Thread Emmanuel Cecchet

Hi,

Here are the patches for 8.4 (1 patch for the code and 1 patch for the 
regression tests).


Thanks in advance for your feedback,
Emmanuel

David Fetter wrote:

On Tue, Oct 07, 2008 at 06:12:14PM -0400, Emmanuel Cecchet wrote:
  

Hi,



On Tue, Oct 07, 2008 at 04:57:37PM -0400, Emmanuel Cecchet wrote:
  
  

Heikki,

Here is a new version of the patch using a hash table as you
suggested.  I also include the tests that I have added to the
regression test suite  to test the various scenarios.  All patches
are based on Postgres 8.3.3, let me know if you want me to
generate patch for 8.4.


CVS TIP is the only place where new features, like this, go :)
  
  

I looked at the Wiki and it looks like I should add en entry
(assuming I  get a patch for the current CVS HEAD) to CommitFest
2008-11. Is that  correct?



I didn't see the attachment anyhow...
  
  

Good point! The same with the attachments now!



Perhaps we did not make this clear.  The patch is a new feature.  New
features are not going into 8.3, as it has already been released.

Make a patch against CVS TIP aka 8.4, and re-submit.

Cheers,
David
  


--
Emmanuel Cecchet
FTO @ Frog Thinker 
Open Source Development  Consulting

--
Web: http://www.frogthinker.org
email: [EMAIL PROTECTED]
Skype: emmanuel_cecchet

### Eclipse Workspace Patch 1.0
#P Postgres-HEAD
Index: src/test/regress/parallel_schedule
===
RCS file: /root/cvsrepo/pgsql/src/test/regress/parallel_schedule,v
retrieving revision 1.46
diff -u -r1.46 parallel_schedule
--- src/test/regress/parallel_schedule  24 Nov 2007 19:49:23 -  1.46
+++ src/test/regress/parallel_schedule  7 Oct 2008 23:41:14 -
@@ -90,3 +90,11 @@
 
 # run tablespace by itself
 test: tablespace
+
+# 
+# 2PC related tests
+# 
+test: 2pc_persistent_table 2pc_on_delete_rows_transaction 2pc_on_commit_drop 
2pc_temp_table_transaction 2pc_temp_table_rollback 2pc_temp_table_savepoint 
2pc_temp_table_failure
+test: 2pc_dirty_buffer_check 
+test: 2pc_temp_table_session
+test: 2pc_on_delete_rows_session
\ No newline at end of file
Index: src/test/regress/serial_schedule
===
RCS file: /root/cvsrepo/pgsql/src/test/regress/serial_schedule,v
retrieving revision 1.43
diff -u -r1.43 serial_schedule
--- src/test/regress/serial_schedule24 Nov 2007 20:41:35 -  1.43
+++ src/test/regress/serial_schedule7 Oct 2008 23:41:14 -
@@ -115,3 +115,13 @@
 test: xml
 test: stats
 test: tablespace
+test: 2pc_persistent_table
+test: 2pc_on_delete_rows_transaction
+test: 2pc_on_commit_drop
+test: 2pc_temp_table_transaction
+test: 2pc_temp_table_rollback
+test: 2pc_temp_table_savepoint
+test: 2pc_dirty_buffer_check 
+test: 2pc_temp_table_session
+test: 2pc_on_delete_rows_session
+test: 2pc_temp_table_failure
\ No newline at end of file
Index: src/test/regress/sql/2pc_on_delete_rows_transaction.sql
===
RCS file: src/test/regress/sql/2pc_on_delete_rows_transaction.sql
diff -N src/test/regress/sql/2pc_on_delete_rows_transaction.sql
--- /dev/null   1 Jan 1970 00:00:00 -
+++ src/test/regress/sql/2pc_on_delete_rows_transaction.sql 1 Jan 1970 
00:00:00 -
@@ -0,0 +1,7 @@
+-- Temp table with ON DELETE ROWS option (transaction scope)
+begin;
+create temp table foo(x int) on commit delete rows;
+insert into foo values(1);
+prepare transaction 'onCommitDeleteRowsTempTableShouldSucceed';
+commit prepared 'onCommitDeleteRowsTempTableShouldSucceed';
+drop table foo;
Index: src/test/regress/expected/2pc_on_commit_drop.out
===
RCS file: src/test/regress/expected/2pc_on_commit_drop.out
diff -N src/test/regress/expected/2pc_on_commit_drop.out
--- /dev/null   1 Jan 1970 00:00:00 -
+++ src/test/regress/expected/2pc_on_commit_drop.out1 Jan 1970 00:00:00 
-
@@ -0,0 +1,6 @@
+-- Temp table with ON COMMIT DROP option
+begin;
+create temp table foo(x int) on commit drop;
+insert into foo values(1);
+prepare transaction 'onCommitDropTempTableShouldSucceed';
+commit prepared 'onCommitDropTempTableShouldSucceed';
Index: src/test/regress/expected/2pc_temp_table_transaction.out
===
RCS file: src/test/regress/expected/2pc_temp_table_transaction.out
diff -N src/test/regress/expected/2pc_temp_table_transaction.out
--- /dev/null   1 Jan 1970 00:00:00 -
+++ src/test/regress/expected/2pc_temp_table_transaction.out1 Jan 1970 
00:00:00 -
@@ -0,0 +1,7 @@
+-- Transaction-scope dropped temp table use case
+begin;
+create temp table foo(x int);
+insert into foo values(1);
+drop table foo;
+prepare transaction 'dropTempTableShouldSucceed';
+commit prepared 'dropTempTableShouldSucceed';
Index: src/test/regress/sql/2pc_temp_table_failure.sql

[HACKERS] Transactions and temp tables

2008-10-06 Thread Emmanuel Cecchet

Hi,

I had the same problem as John with could not open relation 
1663/16384/16584: No such file or directory in a specific combination 
of transactions with temp tables 
(http://archives.postgresql.org/pgsql-hackers/2008-02/msg01260.php). As 
Heikki mentioned 
(http://archives.postgresql.org/pgsql-hackers/2008-02/msg01277.php) we 
should be able to allow CREATE+DROP in the same transaction.


I came up with a patch (currently based on 8.3.3) to address that issue. 
Instead of relying on a boolean that tells if a temp table was accessed, 
I keep a list of the Oid for the temp tables accessed in the transaction 
and at prepare commit time, I check if the relations are still valid. I 
also added a check to allow empty temp tables at prepare commit time 
(this allows to use temp tables with 'on commit delete rows' options.


I am attaching the patch and the use cases I have been using to test it. 
The test cases try to compile the various use cases that I have seen 
reported on the list. Let me know what you think of the patch and if it 
could be applied to 8.3 and 8.4?


Thanks in advance for your feedback,
manu

--
Emmanuel Cecchet
FTO @ Frog Thinker 
Open Source Development  Consulting

--
Web: http://www.frogthinker.org
email: [EMAIL PROTECTED]
Skype: emmanuel_cecchet

### Eclipse Workspace Patch 1.0
#P Postgres-8.3.3
Index: src/include/access/xact.h
===
RCS file: /root/cvsrepo/pgsql/src/include/access/xact.h,v
retrieving revision 1.93.2.1
diff -u -r1.93.2.1 xact.h
--- src/include/access/xact.h   4 Mar 2008 19:54:13 -   1.93.2.1
+++ src/include/access/xact.h   6 Oct 2008 20:39:46 -
@@ -18,6 +18,7 @@
 #include nodes/pg_list.h
 #include storage/relfilenode.h
 #include utils/timestamp.h
+#include postgres_ext.h
 
 
 /*
@@ -44,8 +45,8 @@
 /* Asynchronous commits */
 extern bool XactSyncCommit;
 
-/* Kluge for 2PC support */
-extern bool MyXactAccessedTempRel;
+/* List of temp tables accessed during a transaction for 2PC support */
+extern void enlistRelationIdFor2PCChecks(Oid relationId);
 
 /*
  * start- and end-of-transaction callbacks for dynamically loaded modules
Index: src/backend/access/heap/heapam.c
===
RCS file: /root/cvsrepo/pgsql/src/backend/access/heap/heapam.c,v
retrieving revision 1.249.2.2
diff -u -r1.249.2.2 heapam.c
--- src/backend/access/heap/heapam.c8 Mar 2008 21:58:07 -   
1.249.2.2
+++ src/backend/access/heap/heapam.c6 Oct 2008 20:39:46 -
@@ -870,7 +870,7 @@
 
/* Make note that we've accessed a temporary relation */
if (r-rd_istemp)
-   MyXactAccessedTempRel = true;
+   enlistRelationIdFor2PCChecks(relationId);
 
pgstat_initstats(r);
 
@@ -918,7 +918,7 @@
 
/* Make note that we've accessed a temporary relation */
if (r-rd_istemp)
-   MyXactAccessedTempRel = true;
+   enlistRelationIdFor2PCChecks(relationId);
 
pgstat_initstats(r);
 
@@ -968,7 +968,7 @@
 
/* Make note that we've accessed a temporary relation */
if (r-rd_istemp)
-   MyXactAccessedTempRel = true;
+   enlistRelationIdFor2PCChecks(relationId);
 
pgstat_initstats(r);
 
Index: src/backend/access/transam/xact.c
===
RCS file: /root/cvsrepo/pgsql/src/backend/access/transam/xact.c,v
retrieving revision 1.257.2.2
diff -u -r1.257.2.2 xact.c
--- src/backend/access/transam/xact.c   26 Apr 2008 23:35:33 -  
1.257.2.2
+++ src/backend/access/transam/xact.c   6 Oct 2008 20:39:46 -
@@ -62,13 +62,6 @@
 intCommitDelay = 0;/* precommit delay in 
microseconds */
 intCommitSiblings = 5; /* # concurrent xacts needed to 
sleep */
 
-/*
- * MyXactAccessedTempRel is set when a temporary relation is accessed.
- * We don't allow PREPARE TRANSACTION in that case.  (This is global
- * so that it can be set from heapam.c.)
- */
-bool   MyXactAccessedTempRel = false;
-
 
 /*
  * transaction states - transaction state from server perspective
@@ -206,6 +199,10 @@
  */
 static MemoryContext TransactionAbortContext = NULL;
 
+#defineMAX_TEMP_TABLES_IN_A_TX 10
+#defineUNUSED_OID  0
+OidaccessedTempRel[MAX_TEMP_TABLES_IN_A_TX]; /* Oids of accessed 
temporary relations */
+
 /*
  * List of add-on start- and end-of-xact callbacks
  */
@@ -1512,7 +1509,11 @@
XactIsoLevel = DefaultXactIsoLevel;
XactReadOnly = DefaultXactReadOnly;
forceSyncCommit = false;
-   MyXactAccessedTempRel = false;
+   {
+   int i;
+   for (i = 0 ; i  MAX_TEMP_TABLES_IN_A_TX ; i++)
+   accessedTempRel[i] = UNUSED_OID;
+   }
 
/*
 * reinitialize within-transaction counters
@@ -1777,6 +1778,38 @@