Issue Information
| Issue Number | 701515a |
| Issue | 1. When two rows share the same content in a DEDUPLICATE LOB column, trimming the LOB column of one row with TRIM(0) does not update that row's LOB column. Its length does not become 0, and it continues to reference the shared data. If the row is subsequently deleted, the data referenced by the other row is reclaimed, corrupting its contents. 2. After the shared reference count of a DEDUPLICATE LOB becomes 0 and deduplication is disabled (for example, after TRIM), performing WRITEAPPEND on the row again causes the "Row containing LOB column is not locked" (TBR-26007) error, making it permanently impossible to write to. 3. When data is written with a nonzero offset to an unallocated page of an encrypted (ENCRYPT) LOB, the data is written at the beginning of the block instead of at the specified position, which remains filled with blanks. This issue does not appear during sequential append operations. 4. When the compression unit (CU) number of a compressed (COMPRESS) LOB exceeds 65,536 due to the 16-bit limit, the numbers overlap, and the 65,537th CU is written to the location of the first CU, corrupting the contents. With the default settings, this occurs at approximately 254 GB or more. 5. When data is appended to a compressed LOB whose length exactly matches a CU boundary, the system attempts to read a nonexistent CU, causing an error that disconnects the session. 6. When an in-row compressed LOB is trimmed, the system attempts to clean up a CU that does not exist in the LOB segment, causing the session to be disconnected due to an internal server error. The same error occurs when TRIM(0) is performed on an empty LOB. 7. During LOB writes, the maximum length check allows a very large offset (near 2^64 or in the approximately 35 TB range) to pass without rejecting it, resulting in a bulk write that fills empty blocks, including truncated page numbers. 8. When PSM (DBMS_LOB.WRITEAPPEND) is used on a compressed LOB to append data to the same variable two or more consecutive times, the second call reports the length as 0 and attempts to write at offset 0, causing the session to be disconnected due to an internal server error. This occurs both when creating a new LOB and with a reopened in-row LOB. |
| Cause | 1. Trimming a DEDUPLICATE LOB to a length of 0 changes it to an empty LOB. Empty LOBs are excluded from row updates, so the row continues to point to the shared data while only the reference count is reduced. 2. When deduplication is disabled because the shared reference count of a DEDUPLICATE LOB becomes 0, the row's LOB column is not updated, leaving the deduplication flag in place. Subsequent writes then fail due to the inconsistent state. 3. When writing to a new block of an encrypted LOB, the starting position (offset) within the block is ignored, and the data is always copied to the beginning of the block. 4. The compression unit (CU) number is handled as a 16-bit value, so when it exceeds 65,536, the number starts again from 0. 5. When the length exactly matches a CU boundary, an append attempts to read the next CU, which has not yet been written, as existing data. 6. An in-row compressed LOB has no CU in the LOB segment, but TRIM attempts to clean up the segment's CU without checking this condition. 7. The write length limit is checked by adding the offset and length, so the sum overflows for very large values and passes the check. In addition, the limit itself is set higher than the maximum size that can actually be stored. 8. The length lookup for a compressed LOB returns only the length written to disk and subtracts the data remaining in the compression buffer, causing the second WRITEAPPEND to report the length as 0 and write at the beginning. |
| Solutions | 1. Update the row's LOB column even when an empty LOB is created by a TRIM operation with a length of 0. 2. Update the row's LOB column when deduplication is disabled to remove the deduplication flag. 3. Copy data to the specified starting position in a new block. 4. Extend the CU number to 32 bits. 5. Do not read a CU that has not yet been written; append directly to a new CU. 6. If the compressed LOB is small enough to be stored in the table row, update only its length during a TRIM operation without cleaning up the segment CU. 7. Change the limit check to a subtraction-based method that does not overflow, and adjust the limit to the maximum size that can actually be stored. 8. Include the data remaining in the compression buffer when retrieving the length. |
| Occurrence Date | 26.10.06. |
| Versions Requiring the Patch | 6FS07PS 7FS02PS |
Patch Information
| Patch Name | FS02PS_701515a |
| Major Version | 7 |
| Minor Version | FS02PS |
| Version Title | Fixes for LOB Errors Found During Advanced LOB Development |
| Available for Deployment | 26.11.10. |
| Compatibility | • TAC rolling patch: Yes • TSC rolling patch: Yes • Backup data compatibility: Yes • Protocol compatibility: Yes • Data format compatibility: Yes |
| AP Impact | • Plan change: No • Result value change: No • SQL syntax change: No • System object change: No • Existing functionality change: No |
| Parameters | - |
| Workaround | - |