View Issue Details

IDProjectCategoryView StatusLast Update
0000462Pgpool-IIBugpublic2019-02-07 15:49
ReporterjpedersenAssigned Tot-ishii 
PrioritynormalSeveritymajorReproducibilityalways
Status resolvedResolutionopen 
Product Version3.7.7 
Target Version3.7.8Fixed in Version 
Summary0000462: ERROR: invalid memory alloc request size 1073742608
DescriptionHi,

When selecting more than 1 Gb of data $SUBJECT happens.

The Java application will show the issue, and has the following output:

5432 true: Success
5432 false: Success
9999 true: Failure
9999 false: Success

So, accessing PostgreSQL in both cases works.
Steps To ReproduceUse the Java application after its hard coded parameters have been changed.
TagsNo tags attached.

Activities

jpedersen

2019-01-31 23:18

reporter  

Test.java (2,393 bytes)

jpedersen

2019-02-01 03:17

reporter   ~0002358

In order to get TRACE from the JDBC driver the following is added to the URL: ?loggerLevel=TRACE&loggerFile=pgjdbc.log

jpedersen

2019-02-01 03:39

reporter   ~0002359

PostgreSQL: As compared to AutoCommit(true) the AutoCommit(false) case issues

FINEST: <=BE PortalSuspended
FINEST: <=BE ReadyForQuery(T)
FINEST: FE=> Execute(portal=C_1,limit=100)
FINEST: FE=> Sync

per 100 rows. See postgresql-diff.log.gz for the diffs between the interaction.

postgresql-diff.log.gz (1,055,909 bytes)

jpedersen

2019-02-01 04:14

reporter   ~0002360

I'm seeing the same interaction from Test.java's PoV for the query

PostgreSQL:
FINEST: simple execute, handler=org.postgresql.jdbc.PgStatement$StatementResultHandler@30946e09, maxRows=0, fetchSize=100, flags=17
FINEST: FE=> Parse(stmt=null,query="SELECT * FROM mytable",oids={})
FINEST: FE=> Bind(stmt=null,portal=null)
FINEST: FE=> Describe(portal=null)
FINEST: FE=> Execute(portal=null,limit=0)
FINEST: FE=> Sync
FINEST: <=BE ParseComplete [null]
FINEST: <=BE BindComplete [unnamed]
FINEST: <=BE RowDescription(3)
FINEST: Field(id_column,TEXT,65535,T)
FINEST: Field(data_column,BYTEA,65535,T)
FINEST: Field(timestamp_column,INT8,8,T)
FINEST: <=BE DataRow(len=574)
...

pgpool:
FINEST: simple execute, handler=org.postgresql.jdbc.PgStatement$StatementResultHandler@30946e09, maxRows=0, fetchSize=100, flags=17
FINEST: FE=> Parse(stmt=null,query="SELECT * FROM mytable",oids={})
FINEST: FE=> Bind(stmt=null,portal=null)
FINEST: FE=> Describe(portal=null)
FINEST: FE=> Execute(portal=null,limit=0)
FINEST: FE=> Sync
FINEST: <=BE ErrorMessage(ERROR: invalid memory alloc request size 1073742608

I can provide additional logs, if needed.

t-ishii

2019-02-05 15:52

developer   ~0002366

Can you share the table dump so that I could load the data before running your test program?

t-ishii

2019-02-05 21:16

developer   ~0002367

I have created a patch for this. Can you please try it out?

fixbug462.diff (6,411 bytes)
diff --git a/src/context/pool_session_context.c b/src/context/pool_session_context.c
index 3e04ea6e..06072921 100644
--- a/src/context/pool_session_context.c
+++ b/src/context/pool_session_context.c
@@ -6,7 +6,7 @@
  * pgpool: a language independent connection pool server for PostgreSQL 
  * written by Tatsuo Ishii
  *
- * Copyright (c) 2003-2017	PgPool Global Development Group
+ * Copyright (c) 2003-2019	PgPool Global Development Group
  *
  * Permission to use, copy, modify, and distribute this software and
  * its documentation for any purpose and without fee is hereby
@@ -134,6 +134,9 @@ void pool_init_session_context(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *
 	/* Backends have not ignored messages yet */
 	pool_unset_ignore_till_sync();
 
+	/* Unset suspend reading from frontend flag */
+	pool_unset_suspend_reading_from_frontend();
+
 	/* Initialize where to send map for PREPARE statements */
 #ifdef NOT_USED
 	memset(&session_context->prep_where, 0, sizeof(session_context->prep_where));
@@ -1621,6 +1624,33 @@ int pool_get_minor_version(void)
 	return 0;
 }
 
+/*
+ * Is suspend_reading_from_frontend flag set?
+ */
+bool
+pool_is_suspend_reading_from_frontend(void)
+{
+	return session_context->suspend_reading_from_frontend;
+}
+
+/*
+ * Set suspend_reading_from_frontend flag.
+ */
+void
+pool_set_suspend_reading_from_frontend(void)
+{
+	session_context->suspend_reading_from_frontend = true;
+}
+
+/*
+ * Unset suspend_reading_from_frontend flag.
+ */
+void
+pool_unset_suspend_reading_from_frontend(void)
+{
+	session_context->suspend_reading_from_frontend = false;
+}
+
 #ifdef NOT_USED
 /*
  * Set preferred "master" node id.
diff --git a/src/include/context/pool_session_context.h b/src/include/context/pool_session_context.h
index 98745d52..00a53906 100644
--- a/src/include/context/pool_session_context.h
+++ b/src/include/context/pool_session_context.h
@@ -6,7 +6,7 @@
  * pgpool: a language independent connection pool server for PostgreSQL 
  * written by Tatsuo Ishii
  *
- * Copyright (c) 2003-2018	PgPool Global Development Group
+ * Copyright (c) 2003-2019	PgPool Global Development Group
  *
  * Permission to use, copy, modify, and distribute this software and
  * its documentation for any purpose and without fee is hereby
@@ -240,6 +240,16 @@ typedef struct {
 	int major;
 	/* Protocol minor version number */
 	int minor;
+
+	/*
+	 * Do not read messages from frontend. Used in extended protocol +
+	 * streaming replication.  If sync message is received from frontend, this
+	 * flag prevent from reading any message from frontend until read for
+	 * query message arrives from backend.
+	 */
+	bool		suspend_reading_from_frontend;
+
+>>>>>>> 51e3562f... Reduce memory usage when large data set is returned from backend.
 #ifdef NOT_USED
 	/* Preferred "master" node id. Only used for SimpleForwardToFrontend. */
 	int preferred_master_node_id;
@@ -312,6 +322,9 @@ extern void dump_pending_message(void);
 extern void pool_set_major_version(int major);
 extern void pool_set_minor_version(int minor);
 extern int pool_get_minor_version(void);
+extern bool pool_is_suspend_reading_from_frontend(void);
+extern void pool_set_suspend_reading_from_frontend(void);
+extern void pool_unset_suspend_reading_from_frontend(void);
 #ifdef NOT_USED
 extern void pool_set_preferred_master_node_id(int node_id);
 extern int pool_get_preferred_master_node_id(void);
diff --git a/src/protocol/pool_proto_modules.c b/src/protocol/pool_proto_modules.c
index f601b3ff..6bc25e26 100644
--- a/src/protocol/pool_proto_modules.c
+++ b/src/protocol/pool_proto_modules.c
@@ -5,7 +5,7 @@
  * pgpool: a language independent connection pool server for PostgreSQL
  * written by Tatsuo Ishii
  *
- * Copyright (c) 2003-2018	PgPool Global Development Group
+ * Copyright (c) 2003-2019	PgPool Global Development Group
  *
  * Permission to use, copy, modify, and distribute this software and
  * its documentation for any purpose and without fee is hereby
@@ -96,9 +96,10 @@ static char *
 flatten_set_variable_args(const char *name, List *args);
 static bool
 process_pg_terminate_backend_func(POOL_QUERY_CONTEXT *query_context);
-static void pool_wait_till_ready_for_query(POOL_CONNECTION_POOL *backend);
 static void pool_discard_except_sync_and_ready_for_query(POOL_CONNECTION *frontend,
 														 POOL_CONNECTION_POOL *backend);
+static void pool_discard_except_sync_and_ready_for_query(POOL_CONNECTION * frontend,
+											 POOL_CONNECTION_POOL * backend);
 
 /*
  * This is the workhorse of processing the pg_terminate_backend function to
@@ -2297,6 +2298,10 @@ POOL_STATUS ProcessFrontendResponse(POOL_CONNECTION *frontend,
 	if (pool_read_buffer_is_empty(frontend) && frontend->no_forward != 0)
 		return POOL_CONTINUE;
 
+	/* Are we suspending reading from frontend? */
+	if (pool_is_suspend_reading_from_frontend())
+		return POOL_CONTINUE;
+
 	pool_read(frontend, &fkind, 1);
 
 	ereport(DEBUG1,
@@ -2435,8 +2440,11 @@ POOL_STATUS ProcessFrontendResponse(POOL_CONNECTION *frontend,
 
 			if (SL_MODE)
 			{
-				/* Wait till Ready for query received */
-				pool_wait_till_ready_for_query(backend);
+				/*
+				 * From now on suspend to read from frontend until we receive
+				 * ready for query message from backend.
+				 */
+				pool_set_suspend_reading_from_frontend();
 			}
 			break;
 
@@ -2571,6 +2579,7 @@ POOL_STATUS ProcessBackendResponse(POOL_CONNECTION *frontend,
 				ereport(DEBUG1,
 					(errmsg("processing backend response"),
 						 errdetail("Ready For Query received")));
+				pool_unset_suspend_reading_from_frontend();
 				status = ReadyForQuery(frontend, backend, true, true);
 #ifdef DEBUG
 				extern bool stop_now;
@@ -2653,6 +2662,7 @@ POOL_STATUS ProcessBackendResponse(POOL_CONNECTION *frontend,
 				{
 					pool_set_ignore_till_sync();
 					pool_unset_query_in_progress();
+					pool_unset_suspend_reading_from_frontend();
 					if (SL_MODE)
 						pool_discard_except_sync_and_ready_for_query(frontend, backend);
 				}
@@ -3504,6 +3514,7 @@ flatten_set_variable_args(const char *name, List *args)
 	return buf.data;
 }
 
+#ifdef NOT_USED
 /* Called when sync message is received.
  * Wait till ready for query received.
  */
@@ -3545,6 +3556,7 @@ static void pool_wait_till_ready_for_query(POOL_CONNECTION_POOL *backend)
 		}
 	}
 }
+#endif
 
 /*
  * Called when error response received in streaming replication mode and doing
fixbug462.diff (6,411 bytes)

jpedersen

2019-02-05 21:43

reporter   ~0002368

I have updated the test client to use a pgbench based setup

Test-2.java (2,411 bytes)

jpedersen

2019-02-05 21:45

reporter   ~0002369

Verified V3_7_STABLE (576d1b0877e5405) after removing

src/include/context/pool_session_context.h
+>>>>>>> 51e3562f... Reduce memory usage when large data set is returned from backend.

Test 9999 true: Success
Test 9999 false: Success

t-ishii

2019-02-06 07:38

developer   ~0002371

Oops. Sorry for the mistake. I have pushed a fix.

BTW for the record, here is the commit URL to explain the reasoning of the fix:
https://git.postgresql.org/gitweb/?p=pgpool2.git;a=commit;h=8640abfc41ff06b1e6d31315239292f4d3d4191d

jpedersen

2019-02-06 21:20

reporter   ~0002374

Did you push ? I don't see it on the branch yet.

You probably meant: https://git.postgresql.org/gitweb/?p=pgpool2.git;a=commit;h=51e3562f95b5d61f985142da5b5095d44d35ef29

t-ishii

2019-02-06 21:39

developer   ~0002377

> Did you push ? I don't see it on the branch yet.
Sorry, pushed now. Thanks for reminding me.

> You probably meant: https://git.postgresql.org/gitweb/?p=pgpool2.git;a=commit;h=51e3562f95b5d61f985142da5b5095d44d35ef29
Again, thanks for pointing it out. Yes, this one.

jpedersen

2019-02-06 21:41

reporter   ~0002378

Thanks, you can resolve the issue :)

t-ishii

2019-02-07 15:49

developer   ~0002380

Got it. Thanks!

Issue History

Date Modified Username Field Change
2019-01-31 23:18 jpedersen New Issue
2019-01-31 23:18 jpedersen File Added: Test.java
2019-02-01 03:17 jpedersen Note Added: 0002358
2019-02-01 03:39 jpedersen File Added: postgresql-diff.log.gz
2019-02-01 03:39 jpedersen Note Added: 0002359
2019-02-01 04:14 jpedersen Note Added: 0002360
2019-02-01 11:03 administrator Assigned To => t-ishii
2019-02-01 11:03 administrator Status new => assigned
2019-02-05 15:52 t-ishii Note Added: 0002366
2019-02-05 15:52 t-ishii Status assigned => feedback
2019-02-05 21:16 t-ishii File Added: fixbug462.diff
2019-02-05 21:16 t-ishii Note Added: 0002367
2019-02-05 21:43 jpedersen File Added: Test-2.java
2019-02-05 21:43 jpedersen Note Added: 0002368
2019-02-05 21:43 jpedersen Status feedback => assigned
2019-02-05 21:45 jpedersen Note Added: 0002369
2019-02-06 07:38 t-ishii Note Added: 0002371
2019-02-06 21:20 jpedersen Note Added: 0002374
2019-02-06 21:39 t-ishii Note Added: 0002377
2019-02-06 21:41 jpedersen Note Added: 0002378
2019-02-07 15:49 t-ishii Note Added: 0002380
2019-02-07 15:49 t-ishii Status assigned => resolved
2019-02-07 15:49 t-ishii Target Version => 3.7.8