Skip to content

Performance degradation in multi-threaded application on RHEL 8 #603

Open
@fv-mf

Description

@fv-mf
  1. What versions are you using?
DB: Oracle Database 12c Standard Edition Release 12.1.0.2.0
platform.platform: Linux-4.18.0-348.12.2.el8_5.x86_64-x86_64-with-glibc2.28
sys.maxsize > 2**32: True
platform.python_version: 3.10.0
cx_Oracle.version: 8.3.0
cx_Oracle.clientversion: (18, 5, 0, 0, 0)
  1. Describe the problem

After we performed an upgrade to various software because of a switch from python 2.7 to 3.X we noticed that under heavy load in a multi-threaded application we were having a lot more active connections and increased execution time.

Eliminating our application from the equation shows slowdown when going from single-threaded to multi-threaded with a simple python script (below)

The following are some rough timings on RHEL 8.5 with python 3.10 and cxOracle 8.3.0 when performing 100k queries on a single thread vs distributed on 10 threads (10k per thread)

time /tmp/cx.py -t 1 -r 100000

real    1m35.427s
user    0m59.392s
sys     0m7.678s

time /tmp/cx.py -t 10 -r 10000

real    4m10.947s
user    3m26.608s
sys     5m30.610s

The table used here isn't anything special. There are about 200 entries only in it so most of the queries will return None anyway.

If I run the script on a RHEL 7.2 server (and target the same DB) I get better results compared to RHEL 8.

time /tmp/cx.py -t 10 -r 10000

real    1m46.939s
user    1m18.926s
sys     1m26.848s

Before this we were not seeing any problems with python 2.7 / cxOracle 7.3.0 under RHEL 6.X or 7.X.

If you need other data from our env to help narrow things down let me know (@mariustantareanu can also respond to questions if I am not available)

  1. Include a runnable Python script that shows the problem.

As I said, the table itself doesn't really matter. I used the following python script (with some strings for custom paths and user/passwords removed)

import os
import threading
import sys
import argparse


os.environ['TNS_ADMIN'] = '<>'
os.environ['ORA_TZFILE'] = '<>'
os.environ['ORA_NLS10'] = '<>'


import cx_Oracle

def f(con, start_id, num_reqs):
  for i in range(num_reqs):
    x = start_id + i
    cursor = con.cursor()
    try:
      cursor.execute('select * from devices where dvc_id = :dvcId', dvcId=x)
      d = cursor.fetchone()
    finally:
      cursor.close()


parser = argparse.ArgumentParser()
parser.add_argument('-t', '--threads', help='Number of threads', type=int, required=True)
parser.add_argument('-r', '--requests', help='Number of requests per thread', type=int, required=True)
parser.add_argument('-u', '--username', default='<>')
parser.add_argument('-p', '--password', default='<>')
parser.add_argument('-d', '--dbname', default='<>')

args = parser.parse_args()
connect_string = '%s/%s@%s' % (args.username, args.password, args.dbname)

print("pid=%d" % os.getpid())

con_ts = []
for i in range(args.threads):
  con = cx_Oracle.Connection(connect_string, threaded=True)
  t = threading.Thread(target=f, args=(con, i * args.requests, args.requests))
  con_ts.append((con, t))

for _, t in con_ts:
  t.start()

for _, t in con_ts:
  t.join()

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions