Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix:save points causing server to run out of resources #1409

Merged
merged 10 commits into from
Feb 24, 2019

Conversation

davecramer
Copy link
Member

Fixes #1407

All Submissions:

  • [x ] Have you followed the guidelines in our Contributing document?
  • Have you checked to ensure there aren't other open Pull Requests for the same update/change?

New Feature Submissions:

  1. [X ] Does your submission pass tests?
  2. Does mvn checkstyle:check pass ?

Changes to Existing Features:

  • [NO] Does this break existing behaviour? If so please explain.
  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • [NO] Have you written new tests for your core changes, as applicable?
  • [YES] Have you successfully run tests with your changes locally?

@AppVeyorBot
Copy link

Build pgjdbc 1.0.108 completed (commit 0f0cfc14f8 by @davecramer)

&& getAutoSave() == AutoSave.ALWAYS
&& getTransactionState() == TransactionState.OPEN) {
try {
sendOneQuery(releaseAutoSave, SimpleQuery.NO_PARAMETERS, 1, 0,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@davecramer , does that imply network roundtrip?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm afraid it does. I guess this is why you wanted to do this every 1000 times instead?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exactly

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me see what I can do...

return true;
}
return false;
}

private void releaseSavePoint(boolean autosave, int flags) throws SQLException {
if (autosave
&& (flags & QueryExecutor.QUERY_SUPPRESS_BEGIN) == 1
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After changing the check for the QUERY_SUPPRESS_BEGIN to 0 the changes fix the issue. Otherwise the savepoint is never released

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sadly that doesn't pass the test suite...

@davecramer
Copy link
Member Author

@vlsi so looking at this it appears we send a savepoint before commit which could be removed.

@AppVeyorBot
Copy link

Build pgjdbc 1.0.109 completed (commit 24e8317379 by @davecramer)

@codecov-io
Copy link

codecov-io commented Feb 6, 2019

Codecov Report

Merging #1409 into master will increase coverage by 0.05%.
The diff coverage is 62.79%.

@@             Coverage Diff              @@
##             master    #1409      +/-   ##
============================================
+ Coverage     68.71%   68.76%   +0.05%     
- Complexity     3892     3913      +21     
============================================
  Files           179      179              
  Lines         16397    16436      +39     
  Branches       2668     2676       +8     
============================================
+ Hits          11267    11303      +36     
  Misses         3881     3881              
- Partials       1249     1252       +3

@AppVeyorBot
Copy link

Build pgjdbc 1.0.110 completed (commit 372829a69e by @davecramer)

@fb-datax
Copy link

fb-datax commented Feb 7, 2019

This implementation breaks the whole Savepoint feature for the driver. The PGSQL documentation states "RELEASE SAVEPOINT also destroys all savepoints that were established after the named savepoint was established".

The following test demonstrates the issue:

@Test
public void testPgsqlJdbcSavepoint() throws Exception {
	
	Connection conn = TestUtil.openDB();
	
	BaseConnection baseConnection = conn.unwrap(BaseConnection.class);
	baseConnection.setAutosave(AutoSave.ALWAYS);
	baseConnection.setAutoCommit(false);
	
	TestUtil.createTable(conn, "rollbacktest", "a int, str text");
	
	int iterations = 1000;
	
	for (int i = 0; i < iterations; i++) {
		long startTime = System.nanoTime();
		
		Statement statement = conn.createStatement();
		statement.executeUpdate("insert into rollbacktest(a, str) values (" + i + ", '" + UUID.randomUUID() + "')");
		statement.close();
		
		if (i == 5) {
			Statement savePoint = conn.createStatement();
			savePoint.executeUpdate("SAVEPOINT NEW_SAVEPOINT");
			savePoint.close();
		}
		
		long timeElapsed = System.nanoTime() - startTime;
		System.out.println(i + "/" + iterations + " took " + timeElapsed / 1000000 + "ms ");
	}
	
	Statement savePoint = conn.createStatement();
	savePoint.executeUpdate("ROLLBACK TO NEW_SAVEPOINT");
	savePoint.close();
}

@davecramer
Copy link
Member Author

@fb-datax good catch
So the alternative is an additional round trip per statement.

@fb-datax
Copy link

fb-datax commented Feb 7, 2019

@davecramer
I think that his is the only viable solution. If there are performance concerns, what about making the cleanup optional through a jdbc connection setting?

@bokken
Copy link
Member

bokken commented Feb 7, 2019

What if the approach was to do the "release" /before/ creating the 1000th savepoint?
This wipes out all 1000 savepoints, but that does not really matter as we no longer want to rollback to any of those.

@davecramer
Copy link
Member Author

@bokken Unfortunately releasing all of them also releases SAVEPOINTS set by setSavePoint.

@bokken
Copy link
Member

bokken commented Feb 7, 2019

@davecramer, could we limit to the "auto save" workflow (i.e. no manual calls to setSavePoint)? That really seems to be the problematic workflow. Where a user has auto save, and then proceeds to execute thousands of things in a single transaction.

@davecramer
Copy link
Member Author

@bokken in theory, How do you propose we disable setSavePoint? Throw an exception ?

@AppVeyorBot
Copy link

Build pgjdbc 1.0.111 failed (commit bc23e7cd0a by @davecramer)

@bokken
Copy link
Member

bokken commented Feb 7, 2019

I am not suggesting we disable setSavePoint, I am suggesting that we stop automatically releasing savepoints once setSavePoint has been explicitly called.
Having said that, perhaps the automatic release could just go back to the explicit savepoint as opposed to any automatically created savepoint.

@bokken
Copy link
Member

bokken commented Feb 7, 2019

And perhaps the explicit call to setSavePoint releases any/all automatic savepoints first, giving a clean baseline.

@AppVeyorBot
Copy link

Build pgjdbc 1.0.120 failed (commit cf826a70c0 by @davecramer)

@AppVeyorBot
Copy link

Build pgjdbc 1.0.121 failed (commit 296f436b94 by @davecramer)

@AppVeyorBot
Copy link

Build pgjdbc 1.0.122 failed (commit 3d0c3f23bb by @davecramer)

@AppVeyorBot
Copy link

Build pgjdbc 1.0.123 completed (commit 3003bc1473 by @davecramer)

@davecramer
Copy link
Member Author

And perhaps the explicit call to setSavePoint releases any/all automatic savepoints first, giving a clean baseline.

I think this seems reasonable... I'll work on implementing this.

@AppVeyorBot
Copy link

Build pgjdbc 1.0.124 completed (commit f56a2d4d85 by @davecramer)

@AppVeyorBot
Copy link

Build pgjdbc 1.0.125 failed (commit 2e452067cc by @davecramer)

@AppVeyorBot
Copy link

Build pgjdbc 1.0.126 completed (commit afcc9fc6ff by @davecramer)

@AppVeyorBot
Copy link

Build pgjdbc 1.0.128 completed (commit 11f1b33637 by @davecramer)

@AppVeyorBot
Copy link

Build pgjdbc 1.0.129 completed (commit 0f1f333f86 by @davecramer)

@AppVeyorBot
Copy link

Build pgjdbc 1.0.137 completed (commit 8ca9c98001 by @davecramer)

@AppVeyorBot
Copy link

Build pgjdbc 1.0.138 completed (commit 2338accbdf by @davecramer)

@davecramer davecramer merged commit af8f883 into pgjdbc:master Feb 24, 2019
@@ -111,6 +116,7 @@ public String getSql(ReturnColumns cols) {
}

private final AutoSave autoSave;
private final CleanSavePoint cleanSavePoint;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@davecramer , As far as I can tell, you create a field, but this field seems to be unused.

@vlsi vlsi added triage/needs-review Issue that needs a review - remove label if all is clear probably-invalid-change labels Jun 18, 2019
@davecramer davecramer deleted the fixsafepoints branch December 16, 2019 16:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
probably-invalid-change triage/needs-review Issue that needs a review - remove label if all is clear
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Autosave causes out of shared memory errors
6 participants