oracle / python-oracledb

Python driver for Oracle Database conforming to the Python DB API 2.0 specification. This is the renamed, new major release of cx_Oracle
https://oracle.github.io/python-oracledb
Other
307 stars 59 forks source link

Deqmany memory leak #340

Closed antoine21c closed 1 week ago

antoine21c commented 1 month ago
  1. What versions are you using? oracledb 2.2.1 Give your database version. Oracle 23c

  2. Is it an error or a hang or a crash? error

  3. What error(s) or behavior you are seeing?

We have a project working with OracleAQ Queues. Python code sample using python-oracledb 2.2.1 can be find below. From a new Python thread, a connection is created from a pool, get 2 queues then try to deqmany (issue is found with any values -- 1000 or 20000). We noticed that the memory is never freed after calling deqmany. Same behavior if the connection is released at each iteration (is it recommended though?).

  1. Does your application call init_oracle_client()? Yes
  2. Include a runnable Python script that shows the problem. queue configuration: `

    queue.deqoptions.wait = oracledb.DEQ_NO_WAIT
    queue.deqoptions.visibility = oracledb.DEQ_ON_COMMIT
    queue.deqoptions.navigation = oracledb.DEQ_FIRST_MSG
    queue.deqoptions.mode = oracledb.DEQ_REMOVE
    queue.deqoptions.delivery = oracledb.MSG_PERSISTENT_OR_BUFFERED

    `

`

        self.db.open_connection_from_pool(self.schema)
        self.db.create_queue(self.schema)
        self.db.create_exception_queue(self.schema)

        db_schema = self.db.get_schema_db(self.schema)
        while True:
            if process_exception_queue is True:
                # dequeue exception queue messages
                messages = self.dequeue_messages(db_schema.exception_queue)
                if messages:
                    self.process_messages(messages)

            # dequeue queue messages
            messages = self.dequeue_messages(db_schema.queue)
            if messages:
                self.process_messages(messages)
                continue

            # no messages -- wait 5 seconds
            time.sleep(5)

`

cjbj commented 1 month ago

Thanks for the report

anthony-tuininga commented 2 weeks ago

See #342. Can you supply a standalone script that demonstrates the issue? Similar code to the code you have supplied has been run without detecting any memory leaks, so it may be a specific configuration. Please also supply the Oracle Client library version that you are using. Thanks.

L-Moron commented 1 week ago

Hello @anthony-tuininga , We are using the version 21.14.0.0.0 of the client. Here is a quick standalone script that correctly replicates the issue on our end.

standalone_script_mem_leak.zip

Please do let me know if you need any other info from us. Thank you.

anthony-tuininga commented 1 week ago

Thanks, @L-Moron, that was helpful. I can replicate the issue. It appears to be an issue with the Oracle Client libraries but that needs to be confirmed. Will get back to you! The size of the leak is directly proportional to the number of elements that you are attempting to dequeue at a time. Reducing that value will mitigate the problem considerably. It also runs considerably faster! On my machine having a length of 10,000 took 25 seconds to run whereas with a length of 100 it took only half a second. Until this issue is resolved I would recommend reducing the size of your array, especially if you know the number of messages is going to be considerably less than that!

anthony-tuininga commented 1 week ago

I have confirmed that this is a problem with the Oracle Client libraries. This has been logged as bug 36741214. A possible fix has also been confirmed. You can follow up with Oracle Support but there is nothing that can be done for this issue in python-oracledb.