[CONJ-173] [Feature Request] Implement a mechanism to bypass result set caching for streamed results Created: 2015-07-29  Updated: 2017-03-30  Resolved: 2017-03-30

Status: Closed
Project: MariaDB Connector/J
Component/s: Other
Affects Version/s: None
Fix Version/s: N/A

Type: Task Priority: Minor
Reporter: Geoffrey Rutherford Assignee: Diego Dupin
Resolution: Incomplete Votes: 0
Labels: None
Environment:

JDBC


Issue Links:
Duplicate
duplicates CONJ-26 [Feature Request] Implement configura... Closed
duplicates CONJ-125 Optimize cached ResultSet memory foot... Closed

 Description   

The streamed result set feature isn't usable in the MariaDB JDBC driver as it always creates a cached result set which means large result sets could consume large amounts of memory leading to out of memory failures. I've doctored the latest version for my own use to bypass result set caching on demand but it would be good if proper result set streaming was supported.



 Comments   
Comment by Diego Dupin [ 2015-07-29 ]

Hi.
I'm agree with you and it's on the next version roadmap 1.2.1 (CONJ-26 and CONJ-125)
And if you have time, always looking contributor to move faster

Comment by Vladislav Vaintroub [ 2015-07-29 ]

Streaming used to work, without configurable fetch, one row at a time, documented in https://mariadb.com/kb/en/mariadb/about-mariadb-connector-j/#streaming-result-sets.
Is this now broken ?

Comment by Diego Dupin [ 2015-07-29 ]

Vlad, it's working as documented. no problem for that.

Mysql connector is using 2 other parameters : defaultFetchSize and useCursorFetch that permit to use fetch size.
I've not actually check the mysql protocol for handling fetch size, but if mysql connector is using it, there must be some parameters to permit this.

Comment by Vladislav Vaintroub [ 2015-07-29 ]

I think the Geoffrey Rutherford's complaint was that it is not working at all, i.e all result sets are always fully loaded into memory. Glad to know this is not the case, and streaming actually does work.

Arbitrary fetch size (rather than single row or all) could be an improvement in terms of flexibility and should not be too hard to do.

That connectorJ's cursorFetch I believe (did not check) has very special meaning, by far not as broad as fetch size
1 - refers to only prepared statements (in MySQL sense prepared, not emulated like we have here so far)
2 - Read is done with COM_STMT_FETCH command, rather than COM_STMT_EXECUTE. I do not know many cases where this would be preferable to COM_STMT_EXECUTE - the only one case is probably huge result sets that are very slowly read by the client, so that server would go into socket write timeout.

Comment by Diego Dupin [ 2015-07-30 ]

Geoffrey Rutherford will come back if it's not the case, but i've tested different things to check memory for CONJ-170 a few days ago, and there wasn't anything wrong with the current implementation ... if you know that is all or nothing.

I'm just beginning to implement "server" prepared statement, so that will permit to have fetch size on prepared statement.
With orm, most of the prepared statement are ...prepared at application launch, so it make sense to add this.
for example, Spring data for example use a lot of Pageable (i.e. fetch size query) request.

But, it leave 2 questions :
first : for not prepared statement when fetch size is > 1. There is 2 solutions :

  1. leave it as it is
  2. creating a prepared statement , and use COM_STMT_FETCH.
    As it fetch size has been called, better to go to 2nd solution ?

Second : Using rewriteBatchedStatements parameter: the goal is to avoid using network for DB with a big network latency.
So, best to avoid server prepare statement for this case, and so no fetching size for this particular case ? I have to digg a little more on this particular case.

Comment by Vladislav Vaintroub [ 2015-07-30 ]

On server prepared statement, there was some work done last year as part of Summer of Code. Massimo was the mentor, Maybe you can reuse some of that (it is probably here https://code.launchpad.net/~puneetd30/mariadb-java-client/mariaDB_connector_gsoc ), I never have checked the code.

To the questions :

1. fetch size does not actually need server side support like COM_STMT_FETCH.
Instead of reading either one or all rows, you read them in batches of N . And store them in, lets say, linked list of size N (Using an array would be more efficient, but this is just to give an illustration.) And remove the list head whenever ResultSet.next() is called. populate the list again when it gets empty and there are some more rows to read.
Note that COM_STMT_FETCH actually creates more network traffic than COM_STMT_EXECUTE, as client sends multiple fetch requests for COM_STMT_FETCH.

2. Rewrite batch with prepared statements.. There is no fetch size involved. Batch is primarily there for updates, for SELECTs there is no way to read result sets during or after executeBatch()

server prepared statements do not seem to make much sense, because they are not reused.

Comment by Diego Dupin [ 2017-03-30 ]

Hi Geoffrey Rutherford,
i'm closing this task, since streaming has been improved a lot, without any other issues.

Be free to comment that if you have any issues left.

Generated at Thu Feb 08 03:13:43 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.