|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
[2010-01-18 21:59 UTC] sixd@php.net
[2010-01-19 09:18 UTC] szymon dot latkowski at geomar dot pl
[2010-01-20 19:15 UTC] sixd@php.net
[2010-01-28 01:00 UTC] php-bugs at lists dot php dot net
[2010-04-25 20:25 UTC] felipe@php.net
-Status: No Feedback
+Status: Assigned
-Assigned To:
+Assigned To: sixd
[2010-04-26 00:33 UTC] sixd@php.net
-Status: Assigned
+Status: No Feedback
|
|||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Fri Oct 24 01:00:02 2025 UTC |
Description: ------------ After fetching CLOB field in Oracle XE DB installed on the same PC as PHP and Apache 2.2.14 with OCI_RETURN_LOBS provided as param to oci_fetch_all() and oci_fetch_array() functions, oci8 extension does not properly flush memory reserved for LOB objects. Reproduce code: --------------- <?php $dsn = "VALID_DATA_SOURCE_NAME"; $user = "VALID_USER_NAME"; $pass = "VALID_PASSWORD"; echo "<pre>start\n"; oci_internal_debug(true); $conn = oci_connect($user, $pass, $dsn); // sample table has this schema and has more than one row(s). // CREATE TABLE OWN1.TEST (COLUMN1 CLOB); // COLUMN1 must not be empty - minimum 2 rows are expected $stmt = oci_parse($conn, "SELECT SELECT COLUMN1 FROM OWN1.TEST"); oci_execute($stmt,OCI_DEFAULT); $res = array(); $row = ''; /* while($row = oci_fetch_array($stmt, OCI_ASSOC+OCI_RETURN_NULLS+OCI_RETURN_LOBS)) { $res[] = $row; } */ oci_fetch_all($stmt, $res, $SQL_LIMIT_FROM, $SQL_LIMIT_COUNT, OCI_FETCHSTATEMENT_BY_ROW+OCI_RETURN_LOBS); oci_free_statement($stmt); var_dump($res[0]); oci_close($conn); echo "stop\n</pre>"; ?> Expected result: ---------------- OCIDescriptorFree function should be called during SQL result fetching, not at the end of PHP script. In above script every single call of OCIDescriptorFree should take place before "stop" is printed out. Now only one call of OCIDescriptorFree take place before this piece of code. The expected result should be similar to that described in this article: http://blogs.oracle.com/opal/2008/01/. Actual result: -------------- When I have about 70000 rows in my table, PHP reserves a few MB of memory and releases it at the end of the script consuming 100% of processor and PHP does not release it completely. In our system with hundreds of thousands of client calls it results in Apache crash every hour because of lack of memory and PHP script crashes ocassionaly when it exceeds php.ini "memory_limit" value in single script (with lots of LOB objects fetch). Result of my code from browser: start OCI8 DEBUG: OCINlsEnvironmentVariableGet at (ext\oci8\oci8.c:1764) OCI8 DEBUG L1: Got NO cached connection at (ext\oci8\oci8.c:1809) OCI8 DEBUG L1: using shared pool: (0x5677770) at (ext\oci8\oci8.c:2910) OCI8 DEBUG: OCIHandleAlloc at (ext\oci8\oci8.c:2921) OCI8 DEBUG: OCIHandleAlloc at (ext\oci8\oci8.c:2931) OCI8 DEBUG: OCIAttrGet at (ext\oci8\oci8.c:2964) OCI8 DEBUG: OCIAttrGet at (ext\oci8\oci8.c:2965) OCI8 DEBUG L1: (numopen=0)(numbusy=0) at (ext\oci8\oci8.c:2967) OCI8 DEBUG: OCISessionGet at (ext\oci8\oci8.c:2978) OCI8 DEBUG: OCIAttrGet at (ext\oci8\oci8.c:2993) OCI8 DEBUG: OCIAttrGet at (ext\oci8\oci8.c:2995) OCI8 DEBUG: OCIContextGetValue at (ext\oci8\oci8.c:2997) OCI8 DEBUG: OCIContextGetValue at (ext\oci8\oci8.c:3092) OCI8 DEBUG: OCIMemoryAlloc at (ext\oci8\oci8.c:3099) OCI8 DEBUG: OCIContextSetValue at (ext\oci8\oci8.c:3113) OCI8 DEBUG: OCIAttrSet at (ext\oci8\oci8.c:3023) OCI8 DEBUG L1: New Non-Persistent Connection address: (0x5c1dc40) at (ext\oci8\oci8.c:2035) OCI8 DEBUG L1: num_persistent=(0), num_links=(1) at (ext\oci8\oci8.c:2037) OCI8 DEBUG: OCIHandleAlloc at (ext\oci8\oci8_statement.c:57) OCI8 DEBUG: OCIStmtPrepare2 at (ext\oci8\oci8_statement.c:72) OCI8 DEBUG: OCIAttrSet at (ext\oci8\oci8_statement.c:122) OCI8 DEBUG: OCIAttrGet at (ext\oci8\oci8_statement.c:396) OCI8 DEBUG: OCIStmtExecute at (ext\oci8\oci8_statement.c:420) OCI8 DEBUG: OCIAttrGet at (ext\oci8\oci8_statement.c:449) OCI8 DEBUG: OCIParamGet at (ext\oci8\oci8_statement.c:469) OCI8 DEBUG: OCIAttrGet at (ext\oci8\oci8_statement.c:478) OCI8 DEBUG: OCIAttrGet at (ext\oci8\oci8_statement.c:488) OCI8 DEBUG: OCIAttrGet at (ext\oci8\oci8_statement.c:498) OCI8 DEBUG: OCIAttrGet at (ext\oci8\oci8_statement.c:508) OCI8 DEBUG: OCIAttrGet at (ext\oci8\oci8_statement.c:521) OCI8 DEBUG: OCIAttrGet at (ext\oci8\oci8_statement.c:531) OCI8 DEBUG: OCIAttrGet at (ext\oci8\oci8_statement.c:541) OCI8 DEBUG: OCIDescriptorFree at (ext\oci8\oci8_statement.c:549) OCI8 DEBUG: OCIDefineByPos at (ext\oci8\oci8_statement.c:654) OCI8 DEBUG: OCIDefineDynamic at (ext\oci8\oci8_statement.c:697) OCI8 DEBUG: OCIStmtFetch at (ext\oci8\oci8_statement.c:146) OCI8 DEBUG: OCIDescriptorAlloc at (ext\oci8\oci8_lob.c:75) OCI8 DEBUG: OCILobGetLength at (ext\oci8\oci8_lob.c:127) OCI8 DEBUG: OCILobCharSetId at (ext\oci8\oci8_lob.c:291) OCI8 DEBUG: OCINlsNumericInfoGet at (ext\oci8\oci8_lob.c:305) OCI8 DEBUG: OCILobGetChunkSize at (ext\oci8\oci8_lob.c:209) OCI8 DEBUG: OCILobRead2 at (ext\oci8\oci8_lob.c:348) OCI8 DEBUG: OCILobIsTemporary at (ext\oci8\oci8_lob.c:599) OCI8 DEBUG: OCIStmtFetch at (ext\oci8\oci8_statement.c:146) OCI8 DEBUG: OCIDescriptorAlloc at (ext\oci8\oci8_lob.c:75) OCI8 DEBUG: OCILobGetLength at (ext\oci8\oci8_lob.c:127) OCI8 DEBUG: OCILobCharSetId at (ext\oci8\oci8_lob.c:291) OCI8 DEBUG: OCINlsNumericInfoGet at (ext\oci8\oci8_lob.c:305) OCI8 DEBUG: OCILobGetChunkSize at (ext\oci8\oci8_lob.c:209) OCI8 DEBUG: OCILobRead2 at (ext\oci8\oci8_lob.c:348) OCI8 DEBUG: OCILobIsTemporary at (ext\oci8\oci8_lob.c:599) OCI8 DEBUG: OCIStmtFetch at (ext\oci8\oci8_statement.c:146) OCI8 DEBUG: OCIDescriptorAlloc at (ext\oci8\oci8_lob.c:75) OCI8 DEBUG: OCILobGetLength at (ext\oci8\oci8_lob.c:127) OCI8 DEBUG: OCILobCharSetId at (ext\oci8\oci8_lob.c:291) OCI8 DEBUG: OCINlsNumericInfoGet at (ext\oci8\oci8_lob.c:305) OCI8 DEBUG: OCILobGetChunkSize at (ext\oci8\oci8_lob.c:209) OCI8 DEBUG: OCILobRead2 at (ext\oci8\oci8_lob.c:348) OCI8 DEBUG: OCILobIsTemporary at (ext\oci8\oci8_lob.c:599) OCI8 DEBUG: OCIStmtFetch at (ext\oci8\oci8_statement.c:146) OCI8 DEBUG: OCIStmtRelease at (ext\oci8\oci8_statement.c:723) OCI8 DEBUG: OCIHandleFree at (ext\oci8\oci8_statement.c:731) OCI8 DEBUG: OCILobIsTemporary at (ext\oci8\oci8_lob.c:599) OCI8 DEBUG: OCIDescriptorFree at (ext\oci8\oci8_lob.c:684) array(1) { ["COLUMN1"]=> string(3) "AAA" } stop OCI8 DEBUG: OCILobIsTemporary at (ext\oci8\oci8_lob.c:599) OCI8 DEBUG: OCIDescriptorFree at (ext\oci8\oci8_lob.c:684) OCI8 DEBUG: OCITransRollback at (ext\oci8\oci8.c:2109) OCI8 DEBUG: OCISessionRelease at (ext\oci8\oci8.c:2272) OCI8 DEBUG: OCIHandleFree at (ext\oci8\oci8.c:2156) OCI8 DEBUG: OCIHandleFree at (ext\oci8\oci8.c:2159)