You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/docs/asciidoc/release_notes.adoc
+98-1Lines changed: 98 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -47,6 +47,18 @@ This fix was backported from Jaybird 6.0.1.
47
47
* Fixed: Fetch response with status=0 (FETCH_OK) and count=0 was logged on DEBUG as an unexpected response (https://github.com/FirebirdSQL/jaybird/issues/848[#848])
48
48
+
49
49
This fix was backported from Jaybird 6.0.1.
50
+
* Improvement: backported performance improvements for blob reading and writing from Jaybird 6 (https://github.com/FirebirdSQL/jaybird/issues/850[#850])
51
+
+
52
+
For details see:
53
+
+
54
+
--
55
+
* <<blob-performance-read>>
56
+
* <<blob-performance-write>>
57
+
* <<blob-performance-min-buf>>
58
+
* <<blob-performance-max-segment>>
59
+
* <<blob-buffer-size>>
60
+
* <<blob-put-segment-limit>>
61
+
--
50
62
51
63
[#jaybird-5-0-6-changelog]
52
64
=== Jaybird 5.0.6
@@ -237,11 +249,12 @@ The major changes and new features in Jaybird 5 are:
237
249
* <<jdbc-url-syntax>>
238
250
* <<local-protocol-removed>>
239
251
* <<stream-blobs-default>>
240
-
* <<generated-keys-parser-replaced>> (back-ported to Jaybird 4.0.8)
252
+
* <<generated-keys-parser-replaced>> (backported to Jaybird 4.0.8)
241
253
* <<server-batch-updates>>
242
254
* <<multirow-returning>>
243
255
* <<embedded-locator-service-provider>>
244
256
* <<table-statistics-manager>>
257
+
* <<blob-performance>> (since Jaybird 5.0.7)
245
258
246
259
Upgrading from Jaybird 4 to 5 should be simple, but please make sure to read <<compatibility-changes>> before using Jaybird 5.
247
260
See also <<upgrading-from-jaybird-4-to-jaybird-5>>.
@@ -774,6 +787,38 @@ Its API may change in point releases, or it may be removed or replaced entirely
774
787
[#blob-performance]
775
788
=== Blob performance improvements
776
789
790
+
[#blob-performance-read]
791
+
==== Reading blobs
792
+
793
+
Added in: Jaybird 5.0.7, backported from Jaybird 6
794
+
795
+
Performance of reading blobs has been improved, especially when using `getBytes` on `ResultSet` or `Blob`, or `getString` on `ResultSet` or `Clob`, or reading from a blob input stream with `read(byte[], int, int)` and similar methods with a byte array and requested length greater than 50% of the configured `blobBufferSize`.
796
+
797
+
Testing on a local network (Wi-Fi) shows an increase in throughput of roughly 50-100% for reading large blobs with the default `blobBufferSize` of 16384.
798
+
799
+
These throughput improvements were only realised in the pure Java protocol, because there we had the opportunity to avoid all additional allocations by writing directly from the network stream into the destination byte array, and this allows us to ignore the configured `blobBufferSize` and use up to the maximum request size of 65535 bytes instead.
800
+
801
+
This is not possible for the JNA-based protocols (native/embedded), as the implementation requires a direct byte buffer to bridge to the native API, and thus we can't ignore the `blobBufferSize`.
802
+
We were able to realise some other optimizations (in both pure Java and JNA), by avoiding allocation of a number of intermediate objects, but this has only marginal effects on the throughput.
803
+
804
+
[#blob-performance-write]
805
+
==== Writing blobs
806
+
807
+
Added in: Jaybird 5.0.7, backported from Jaybird 6
808
+
809
+
Performance of writing blobs was improved, especially when using `setBytes` on `PreparedStatement`, `ResultSet` or `Blob`, or `setString` on `PreparedStatement`, `ResultSet` or `Clob`, or writing to a blob output stream with `write(byte[], int, int)` and similar methods with a byte array larger than the configured `blobBufferSize`.
810
+
A smaller improvement was made when using arrays larger than 50% of the `blobBufferSize`.
811
+
812
+
Testing on a local network (Wi-Fi) shows an increase in throughput of roughly 300-400% for writing large blobs with the default `blobBufferSize` of 16384.
813
+
The improvement is not available for all methods of writing blobs, for example using `ResultSet.setBinaryStream` does not see this improvement, as it relies on the `blobBufferSize` for transferring the blob content.
814
+
815
+
Most of these throughput improvements were only realised in the pure Java protocol, because there we had the opportunity to avoid all additional allocations by writing directly from the source byte array to the network stream, and this allows us to ignore the configured `blobBufferSize` and use up to the maximum segment size of 65535 bytes instead.
816
+
817
+
For the JNA-based protocols (native/embedded) a smaller throughput improvement was realised, by using the maximum segment size for the first roundtrip if the array write used offset `0`.
818
+
If the length is larger than the maximum segment size, or if the offset is non-zero, we need to allocate a buffer (for subsequent segments in case offset is `0`), and thus cannot ignore the `blobBufferSize`.
819
+
820
+
Similar to the improvements for reading, we were also able to realise some other optimizations (in both pure Java and JNA), by avoiding allocation of a number of intermediate objects, but this has only marginal effects on the throughput.
821
+
777
822
[#blob-performance-defer-open]
778
823
==== Deferred blob open
779
824
@@ -789,6 +834,58 @@ This optimization is available for Firebird 2.1 and higher, but formally only su
789
834
790
835
For native connections, a similar optimization -- but only for reading blobs -- is available when using a Firebird 5.0.2 or higher fbclient, independent of the Jaybird version.
791
836
837
+
[#blob-performance-min-buf]
838
+
==== Minimum `blobBufferSize` 512 bytes
839
+
840
+
Added in: Jaybird 5.0.7, backported from Jaybird 6
841
+
842
+
As part of the performance improvements, a minimum `blobBufferSize` of 512 bytes was introduced.
843
+
Configuring values less than 512 will be ignored and use 512 instead.
844
+
845
+
[#blob-performance-max-segment]
846
+
==== Maximum segment size raised
847
+
848
+
Added in: Jaybird 5.0.7, backported from Jaybird 6
849
+
850
+
For connections to Firebird 3.0 and higher, the maximum segment size was raised from 32765 to 65535 bytes to match the maximum segment size supported by Firebird.
851
+
852
+
The maximum segment size is the maximum size for sending segments (_put_) to the server.
853
+
Due to protocol limitations, retrieving segments from the server (_get_) is two bytes (or multiples of two bytes) shorterfootnote:[For _get_ the maximum segment size is actually the maximum buffer size to receive one or more segments which are prefixed with two bytes for the length].
854
+
855
+
[#blob-buffer-size]
856
+
==== Effectiveness of `blobBufferSize` larger than maximum segment size
857
+
858
+
Added in: Jaybird 5.0.7, backported from Jaybird 6
859
+
860
+
Previously, when reading blobs, a `blobBufferSize` larger than the maximum segment size was effectively ignored.
861
+
Now, when reading through an input stream, a `blobBufferSize` larger than the maximum segment size can be used.
862
+
863
+
Jaybird will use one or more roundtrips to fill the buffer.
864
+
To avoid inefficient fetches, a minimum of 90% of the buffer size will be filled up to the `blobBufferSize`.
865
+
This change is not likely to improve performance, but it may allow for optimizations when reading or transferring data in large chunks.
866
+
867
+
In general, setting the `blobBufferSize` larger than 65535 bytes will likely not improve performance.
868
+
869
+
[#blob-put-segment-limit]
870
+
==== Internal API changes for `FbBlob`
871
+
872
+
Added in: Jaybird 5.0.7, backported from Jaybird 6
873
+
874
+
Three new methods were added to `FbBlob`:
875
+
876
+
`int get(byte[] b, int off, int len)`::
877
+
populates the array `b`, starting at `off`, for the requested `len` bytes from the blob, and returns the actual number of bytes read.
878
+
This method will read until `len` bytes have been read, and only return less than `len` when end-of-blob was reached.
879
+
880
+
`int get(byte[] b, int off, int len, float minFillFactor)`::
881
+
populates the array `b`, starting at `off`, for at least `minFillFactor` * `len` bytes (up to `len` bytes) from the blob, and returns the actual number of bytes read.
882
+
883
+
`void put(byte[] b, int off, int len)`::
884
+
sends data from array `b` to the blob, starting at `off`, for the requested `len` bytes.
885
+
886
+
The documentation of method `FbBlob.putSegment(byte[])` contradicted itself, by requiring implementations to batch larger arrays, but also requiring them to throw an exception for larger arrays, and the actual implementations provided by Jaybird threw an exception.
887
+
This contradiction has been removed, and the implementations will now send arrays longer than the maximum segment size to the server in multiple _put_ requests.
0 commit comments