backend crash with certain statements/tables

Started by Jeff Bohmerabout 22 years ago5 messagesbugs
Jump to latest
#1Jeff Bohmer
bohmer@visionlink.org

Reproduced in PG 7.4.1 on ...

OS X Server 10.2.8
OS X 10.2.8
RHL 9 (2.4.20-30.9)

Running any of these statements on my database causes the backend to
crash (example from PG log below):

create temp table foo as select * from server_prefs limit 1;
create table foo as select * from server_prefs limit 1;
create temp table foo as select * from agency_dbs limit 1;
create table foo as select * from agency_dbs limit 1;

All of these statements produce expected results (no crash):

create temp table foo as select * from c_group limit 1;
create table foo as select * from c_group limit 1;
create table foo as select * from server_prefs;
create table foo as select * from agency_dbs;
select * from server_prefs limit 1;
select * from agency_dbs limit 1;

Attached is a file that creates a database and only the server_prefs
table and then reproduces the crash for me on both OS X and Linux
when I run it like:

psql -d template1 -U postgres -f pg_crash

Thanks,
- Jeff

2004-03-01 10:32:24 [471] LOG: connection received: host=[local] port=
2004-03-01 10:32:24 [471] LOG: connection authorized: user=username
database=cos
2004-03-01 10:32:34 [471] LOG: statement: create temp table foo as
select * from server_prefs limit 1;
2004-03-01 10:32:35 [19913] LOG: server process (PID 471) was
terminated by signal 10
2004-03-01 10:32:35 [19913] LOG: terminating any other active server processes
2004-03-01 10:32:35 [429] WARNING: terminating connection because of
crash of another server process
DETAIL: The postmaster has commanded this server process to roll
back the current transaction and exit, because another server process
exited abnormally and possibly corrupted shared memory.
HINT: In a moment you should be able to reconnect to the database
and repeat your command.
2004-03-01 10:32:35 [474] LOG: connection received: host=[local] port=
2004-03-01 10:32:35 [474] FATAL: the database system is in recovery mode
2004-03-01 10:32:35 [19913] LOG: all server processes terminated;
reinitializing
2004-03-01 10:32:35 [475] LOG: database system was interrupted at
2004-03-01 10:27:58 MST
2004-03-01 10:32:35 [475] LOG: checkpoint record is at 5/1350BF6C
2004-03-01 10:32:35 [475] LOG: redo record is at 5/1350BF6C; undo
record is at 0/0; shutdown TRUE
2004-03-01 10:32:35 [475] LOG: next transaction ID: 374025; next OID: 46414656
2004-03-01 10:32:35 [475] LOG: database system was not properly shut
down; automatic recovery in progress
2004-03-01 10:32:35 [475] LOG: redo starts at 5/1350BFAC
2004-03-01 10:32:35 [475] LOG: unexpected pageaddr 5/9570000 in log
file 5, segment 19, offset 5701632
2004-03-01 10:32:35 [475] LOG: redo done at 5/1356EB8C
2004-03-01 10:32:38 [475] LOG: database system is ready

Attachments:

pg_crash.gzapplication/mac-binhex40; name=pg_crash.gzDownload+2-4
#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Jeff Bohmer (#1)
Re: backend crash with certain statements/tables

Jeff Bohmer <bohmer@visionlink.org> writes:

Running any of these statements on my database causes the backend to
crash (example from PG log below):

Crash confirmed here. Seems to be a side-effect of the 7.4 optimization
that tries to avoid "unnecessary" projection steps. In the "SELECT *
FROM foo LIMIT" case, the scan plan decides it need not do projection,
but actually one must occur (else heap_insert will scribble on the
source table :-(). The junkfilter code in execMain.c is supposed to
catch this situation, but it's fooled by the presence of a LIMIT step.
There may be some related cases, need to think more.

I should have a patch later today.

regards, tom lane

#3Jeff Bohmer
bohmer@visionlink.org
In reply to: Tom Lane (#2)
Re: backend crash with certain statements/tables

I should have a patch later today.

Great! I'd like to try out the patch when it's ready.

Thanks,
- Jeff
--

Jeff Bohmer
VisionLink, Inc.
_________________________________
303.402.0170
www.visionlink.org
_________________________________
People. Tools. Change. Community.

#4Tom Lane
tgl@sss.pgh.pa.us
In reply to: Jeff Bohmer (#3)
Re: backend crash with certain statements/tables

Jeff Bohmer <bohmer@visionlink.org> writes:

Great! I'd like to try out the patch when it's ready.

Here ya go.

regards, tom lane

Index: src/backend/executor/execAmi.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/executor/execAmi.c,v
retrieving revision 1.75.4.1
diff -c -r1.75.4.1 execAmi.c
*** src/backend/executor/execAmi.c	18 Dec 2003 20:21:53 -0000	1.75.4.1
--- src/backend/executor/execAmi.c	2 Mar 2004 18:52:18 -0000
***************
*** 348,350 ****
--- 348,415 ----
  			return false;
  	}
  }
+ 
+ /*
+  * ExecMayReturnRawTuples
+  *		Check whether a plan tree may return "raw" disk tuples (that is,
+  *		pointers to original data in disk buffers, as opposed to temporary
+  *		tuples constructed by projection steps).  In the case of Append,
+  *		some subplans may return raw tuples and others projected tuples;
+  *		we return "true" if any of the returned tuples could be raw.
+  *
+  * This must be passed an already-initialized planstate tree, because we
+  * need to look at the results of ExecAssignScanProjectionInfo().
+  */
+ bool
+ ExecMayReturnRawTuples(PlanState *node)
+ {
+ 	/*
+ 	 * At a table scan node, we check whether ExecAssignScanProjectionInfo
+ 	 * decided to do projection or not.  Most non-scan nodes always project
+ 	 * and so we can return "false" immediately.  For nodes that don't
+ 	 * project but just pass up input tuples, we have to recursively
+ 	 * examine the input plan node.
+ 	 *
+ 	 * Note: Hash and Material are listed here because they sometimes
+ 	 * return an original input tuple, not a copy.  But Sort and SetOp
+ 	 * never return an original tuple, so they can be treated like
+ 	 * projecting nodes.
+ 	 */
+ 	switch (nodeTag(node))
+ 	{
+ 		/* Table scan nodes */
+ 		case T_SeqScanState:
+ 		case T_IndexScanState:
+ 		case T_TidScanState:
+ 		case T_SubqueryScanState:
+ 		case T_FunctionScanState:
+ 			if (node->ps_ProjInfo == NULL)
+ 				return true;
+ 			break;
+ 
+ 		/* Non-projecting nodes */
+ 		case T_HashState:
+ 		case T_MaterialState:
+ 		case T_UniqueState:
+ 		case T_LimitState:
+ 			return ExecMayReturnRawTuples(node->lefttree);
+ 
+ 		case T_AppendState:
+ 		{
+ 			AppendState *appendstate = (AppendState *) node;
+ 			int			j;
+ 
+ 			for (j = 0; j < appendstate->as_nplans; j++)
+ 			{
+ 				if (ExecMayReturnRawTuples(appendstate->appendplans[j]))
+ 					return true;
+ 			}
+ 			break;
+ 		}
+ 
+ 		/* All projecting node types come here */
+ 		default:
+ 			break;
+ 	}
+ 	return false;
+ }
Index: src/backend/executor/execMain.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/executor/execMain.c,v
retrieving revision 1.220.2.1
diff -c -r1.220.2.1 execMain.c
*** src/backend/executor/execMain.c	22 Jan 2004 02:23:35 -0000	1.220.2.1
--- src/backend/executor/execMain.c	2 Mar 2004 18:52:18 -0000
***************
*** 665,674 ****
  	/*
  	 * Initialize the junk filter if needed.  SELECT and INSERT queries
  	 * need a filter if there are any junk attrs in the tlist.	INSERT and
! 	 * SELECT INTO also need a filter if the top plan node is a scan node
! 	 * that's not doing projection (else we'll be scribbling on the scan
! 	 * tuple!)	UPDATE and DELETE always need a filter, since there's
! 	 * always a junk 'ctid' attribute present --- no need to look first.
  	 */
  	{
  		bool		junk_filter_needed = false;
--- 665,674 ----
  	/*
  	 * Initialize the junk filter if needed.  SELECT and INSERT queries
  	 * need a filter if there are any junk attrs in the tlist.	INSERT and
! 	 * SELECT INTO also need a filter if the plan may return raw disk tuples
! 	 * (else heap_insert will be scribbling on the source relation!).
! 	 * UPDATE and DELETE always need a filter, since there's always a junk
! 	 * 'ctid' attribute present --- no need to look first.
  	 */
  	{
  		bool		junk_filter_needed = false;
***************
*** 689,706 ****
  					}
  				}
  				if (!junk_filter_needed &&
! 					(operation == CMD_INSERT || do_select_into))
! 				{
! 					if (IsA(planstate, SeqScanState) ||
! 						IsA(planstate, IndexScanState) ||
! 						IsA(planstate, TidScanState) ||
! 						IsA(planstate, SubqueryScanState) ||
! 						IsA(planstate, FunctionScanState))
! 					{
! 						if (planstate->ps_ProjInfo == NULL)
! 							junk_filter_needed = true;
! 					}
! 				}
  				break;
  			case CMD_UPDATE:
  			case CMD_DELETE:
--- 689,697 ----
  					}
  				}
  				if (!junk_filter_needed &&
! 					(operation == CMD_INSERT || do_select_into) &&
! 					ExecMayReturnRawTuples(planstate))
! 					junk_filter_needed = true;
  				break;
  			case CMD_UPDATE:
  			case CMD_DELETE:
Index: src/include/executor/executor.h
===================================================================
RCS file: /cvsroot/pgsql-server/src/include/executor/executor.h,v
retrieving revision 1.102.2.2
diff -c -r1.102.2.2 executor.h
*** src/include/executor/executor.h	22 Jan 2004 02:23:35 -0000	1.102.2.2
--- src/include/executor/executor.h	2 Mar 2004 18:52:19 -0000
***************
*** 36,41 ****
--- 36,42 ----
  extern void ExecRestrPos(PlanState *node);
  extern bool ExecSupportsMarkRestore(NodeTag plantype);
  extern bool ExecSupportsBackwardScan(Plan *node);
+ extern bool ExecMayReturnRawTuples(PlanState *node);

/*
* prototypes from functions in execGrouping.c

#5Jeff Bohmer
bohmer@visionlink.org
In reply to: Tom Lane (#4)
Re: backend crash with certain statements/tables

Jeff Bohmer <bohmer@visionlink.org> writes:

Great! I'd like to try out the patch when it's ready.

Here ya go.

Works for me on OS X and Linux.

Thank you very much!

- Jeff
--

Jeff Bohmer
VisionLink, Inc.
_________________________________
303.402.0170
www.visionlink.org
_________________________________
People. Tools. Change. Community.