firebird icon indicating copy to clipboard operation
firebird copied to clipboard

Server does not release memory after DDL statements.

Open ant-zuev opened this issue 3 years ago • 0 comments

Create new issue instead https://github.com/FirebirdSQL/firebird/issues/7309 because memory leak is present in both FB4 and FB5.

The problem can be reproduced by a follow script with defined LD_LIBRARY_PATH variable containing path to file libfbclient.so. Script checks memory consumption of the server process after each thousand of CREATE TABLE-DROP TABLE queries and outputs intermediate results. Variable ARCH defines a required architecture of the server. Server must be started with defined architecture before running the script.

#!/usr/bin/python2

import os
import sys
import fdb
import psutil
import argparse

PROC_NAME = 'firebird'
TEST_DB = '/tmp/test_mem.fdb'
ARCH = 'CS'

parser = argparse.ArgumentParser(description='Check memory consumption')
parser.add_argument("-a", "--arch", default=ARCH, choices=['CS', 'cs', 'SS', 'ss'])

args = parser.parse_args()
test_arch = args.arch

main_proc = None
for proc in psutil.process_iter():
    if proc.name() == PROC_NAME:
        main_proc = psutil.Process(proc.pid)
        break

if not main_proc:
    sys.exit("Firebird process not found")

if os.path.isfile(TEST_DB):
    os.remove(TEST_DB)

conn = fdb.create_database(dsn='localhost:%s'%TEST_DB, user='sysdba', password='masterkey')
cur = conn.cursor()
cur.execute('create table mem(str varchar(20))')
conn.commit()

if test_arch == 'CS':
    server = None
    for proc in psutil.process_iter():
        if (proc.name() == PROC_NAME) and (proc.pid != main_proc.pid):
            server = psutil.Process(proc.pid)
            break
    if not server:
        sys.exit("Attachment process not found")
else:
    server = main_proc

prev_used = server.memory_info().rss/1024                   # convert to kB

for i in range(1000):
    for j in range(1000):
        tmp_table = "test"
        cur.execute("create table %s(id int)"%tmp_table)
        conn.commit()
        cur.execute("drop table %s"%tmp_table)
        conn.commit()
    print('After %d queries:'%((i+1)*1000))
    result = server.memory_info().rss/1024                  # convert to kB
    diff = (result - prev_used)
    prev_used = result
    print('Used:        %d kB'%result)
    print('Difference:  %d kB'%diff)
    print('-'*25)

ant-zuev avatar Sep 26 '22 11:09 ant-zuev