跳转至

01 达梦连接数问题

达梦连接数问题

背景

如果代码运行异常等, 或者连接没有再代码里面关闭, 会导致连接数达到上限; 会导致数据库进入只读情况

解决思路

  • 修改连接数(临时解决)
  • 调整代码(长期解决)

修改连接数

1、 查看最大连接数

$ select SF_GET_PARA_VALUE(2,'MAX_SESSIONS');

2、 查看当前连接数

### ACTIVE 表示目前存活的连接数
$ select count(*) from v$sessions where state=ACTIVE;
### 总的连接数
$ select count(*) from v$sessions ;
### 可删除的连接数
$ select count(*) from v$sessions where state=IDEL;

3、 修改最大连接数

### 将最大连接数修改至1000
$ ALTER SYSTEM SET MAX_SESSIONS =1000 spfile;

4、 也可以通过修改dm.ini 来修改最大连接数

### cat dm.ini
MAX_SESSIONS=1000

5、 修改之后, 就需要重启dm 服务

### 如果直接安装再系统上, 服务名称不定; 主要看服务是否起的dm 数据库, 暂定服务名称为DmServiceDMSERVER.service
$ systemctl status DmServiceDMSERVER.service
$ systemctl restart DmServiceDMSERVER.service && systemctl status DmServiceDMSERVER.service

代码问题

联系开发调整代码; 添加回收数据库连接操作。

手动删除idle 的连接

对应的sql 语句如下所示, 可以清除掉状态为idle 的连接

begin
for rec in
(select * from v$sessions where state='IDLE')
loop
sp_close_session (rec.sess_id);
end loop;
end;

对应的python 脚本如下

import os
import logging
from sqlalchemy import create_engine, text

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') # noqa

dm_url = os.environ.get('DM_CONF')
engine = create_engine(dm_url)
clean_session_threshold = os.environ.get('CLEAN_SESSION_THRESHOLD', 1000)

SESSION_COUNT_SQL = """
select count(*) from v$sessions;"""

CLEAN_IDLE_SESSION_SQL = """
begin
for rec in
(select * from v$sessions where state='IDLE')
loop
sp_close_session (rec.sess_id);
end loop;
end;"""


def get_session_count():
    return engine.execute(text(SESSION_COUNT_SQL)).fetchone()[0]


def clean_idle_session():
    engine.execute(text(CLEAN_IDLE_SESSION_SQL))


def main():
    if not dm_url:
        logging.warning("dm_url is not set")
        return
    session_count = get_session_count()
    logging.info("session count: %s", session_count)
    if session_count > clean_session_threshold:
        clean_idle_session()
        logging.info("cleaned idle session, session count: %s", get_session_count()) # noqa
    else:
        logging.info("no need to clean idle session")


if __name__ == '__main__':
    main()