达梦数据库-linux环境下断网后连接卡住问题解决

本文主要是介绍达梦数据库-linux环境下断网后连接卡住问题解决,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

问题描述

应用:x86 centos7

数据库:1-2-128-22.08.12-166927-20005-ENT

测试数据库有两个相互隔离的IP,应用可通过两个IP连接数据库,当断开正在连接的一个网卡后,不能立即切换,程序卡住时间过长问题。应用部署于windows时正常。

如上图所示客户端初始连接ip为192.168.44.130 当关闭改网卡后程序卡住12分钟。

问题原因分析

        通过设置连接超时等参数均未解决,通过咨询专家提供TCP/IP连接排查方向。通过程序跟踪,确定确为与TCP连接相关,测试修改TCP相关内核参数,最终确定与linux tcp 断网重连net.ipv4.tcp_retries2参数相关

具体分析过程

  • 创建测试用户和表
CREATE USER "USER01" IDENTIFIED BY "Dameng88.";
CREATE TABLE "USER01"."TAB02"
(
"C1" INT,
"C2" VARCHAR(50));
  • 配置服务名连接
vim /etc/dm_svc.config
TIME_ZONE=(480)
LANGUAGE=(cn)
DMTEST=(192.168.183.128:5236,192.168.44.128:5236)[DMTEST]
AUTO_RECONNECT=(1)
CONNECT_TIMEOUT=(500)
  • 编写DCI测试用例
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#include <unistd.h>
#include "DCI.h"
/* 声明句柄 */
OCIEnv* envhp; /* 环境句柄 */
OCISvcCtx* svchp; /* 服务环境句柄 */
OCIServer* srvhp; /* 服务器句柄 */
OCISession* authp; /* 会话句柄 */
OCIStmt* stmthp; /* 语句句柄 */
OCIDescribe* dschp; /* 描述句柄 */
OCIError* errhp; /* 错误句柄 */
OCIDefine* defhp[3]; /* 定义句柄 */
OCIBind* bidhp[4]; /* 绑定句柄 */
sb2 ind[3]; /* 指示符变量 */
/* 绑定select结果集的参数 */
int szc1; /* 存储personid列 */
text szc2[30]; /* 存储sex列 */
char sql[256]; /* 存储执行的sql语句*/void connDB(){char strServerName[50];char strUserName[50];char strPassword[50];int ret;text errbuf[100];/* 设置服务器,用户名和密码 */strcpy(strServerName, "DMTEST");strcpy(strUserName, "SYSDBA");strcpy(strPassword, "SYSDBA");/* 初始化OCI应用环境*/OCIInitialize(OCI_DEFAULT, NULL, NULL, NULL, NULL);/* 初始化环境句柄 */OCIEnvInit(&envhp, OCI_DEFAULT, 0, 0);/* 分配句柄 */OCIHandleAlloc(envhp, (dvoid**)&svchp, OCI_HTYPE_SVCCTX, 0, 0); /*服务器环境句柄*/OCIHandleAlloc(envhp, (dvoid**)&srvhp, OCI_HTYPE_SERVER, 0, 0); /* 服务器句柄*/OCIHandleAlloc(envhp, (dvoid**)&authp, OCI_HTYPE_SESSION, 0, 0); /* 会话句柄 */OCIHandleAlloc(envhp, (dvoid**)&errhp, OCI_HTYPE_ERROR, 0, 0); /* 错误句柄 */OCIHandleAlloc(envhp, (dvoid**)&dschp, OCI_HTYPE_DESCRIBE, 0, 0); /*描述符句柄*//* 连接服务器 */OCIServerAttach(srvhp, errhp, (text*)strServerName, (sb4)strlen(strServerName), OCI_DEFAULT);/* 设置用户名和密码 */OCIAttrSet(authp, OCI_HTYPE_SESSION, (text*)strUserName, (ub4)strlen(strUserName), OCI_ATTR_USERNAME, errhp);OCIAttrSet(authp, OCI_HTYPE_SESSION, (text*)strPassword, (ub4)strlen(strPassword), OCI_ATTR_PASSWORD, errhp);/* 设置服务器环境句柄属性 */OCIAttrSet((dvoid*)svchp, (ub4)OCI_HTYPE_SVCCTX,(dvoid*)srvhp, (ub4)0, OCI_ATTR_SERVER, errhp);OCIAttrSet(svchp, OCI_HTYPE_SVCCTX, (dvoid*)authp,0, OCI_ATTR_SESSION, errhp);/* 创建并开始一个用户会话 */ret=OCISessionBegin(svchp, errhp, authp, OCI_CRED_RDBMS, OCI_DEFAULT);while(ret != 0){OCIErrorGet(errhp, 1, NULL, &ret, (OraText*)errbuf, sizeof(errbuf), OCI_HTYPE_ERROR);printf("\n%d,%s\n",ret,errbuf);sleep(2);ret=OCIServerAttach(srvhp, errhp, (text*)strServerName, (sb4)strlen(strServerName), OCI_DEFAULT);}}void closeDB(){//结束会话OCISessionEnd(svchp, errhp, authp, (ub4)0);//断开与数据库的连接OCIServerDetach(srvhp, errhp, OCI_DEFAULT);//释放OCI句柄OCIHandleFree((dvoid*)dschp, OCI_HTYPE_DESCRIBE);OCIHandleFree((dvoid*)stmthp, OCI_HTYPE_STMT);OCIHandleFree((dvoid*)errhp, OCI_HTYPE_ERROR);OCIHandleFree((dvoid*)authp, OCI_HTYPE_SESSION);OCIHandleFree((dvoid*)svchp, OCI_HTYPE_SVCCTX);OCIHandleFree((dvoid*)srvhp, OCI_HTYPE_SERVER);
}int main(int argc, char* argv[])
{char strServerName[50];char strUserName[50];char strPassword[50];int ret;text errbuf[100];connDB();       int i=1;for(i=1;i<100;i++){/* 分配和初始化句柄 */ret=OCIHandleAlloc(envhp, (dvoid**)&stmthp, OCI_HTYPE_STMT, 0, 0);if (ret != 0){OCIErrorGet(errhp, 1, NULL, &ret, (OraText*)errbuf, sizeof(errbuf), OCI_HTYPE_ERROR);printf("\n%d,%s\n",ret,errbuf);OCISessionEnd(svchp, errhp, authp, (ub4)0);sleep(2);closeDB();connDB();ret=OCIHandleAlloc(envhp, (dvoid**)&stmthp, OCI_HTYPE_STMT, 0, 0);}memset(sql, 0, sizeof(sql));strcpy(sql, "delete from user01.tab02");// 准备SQL语句OCIStmtPrepare(stmthp, errhp, (text*)sql, strlen(sql), OCI_NTV_SYNTAX, OCI_DEFAULT);// 执行SQL语句ret = OCIStmtExecute(svchp, stmthp, errhp, (ub4)1, (ub4)0, (CONST OCISnapshot*) 0, (OCISnapshot*)0, (ub4)OCI_DEFAULT);if (ret != 0){OCIErrorGet(errhp, 1, NULL, &ret, (OraText*)errbuf, sizeof(errbuf), OCI_HTYPE_ERROR);printf("\n%s\n", errbuf);sleep(2);continue;}else{//提交到数据库OCITransCommit(svchp, errhp, OCI_DEFAULT);printf("Delete OK!\n");}memset(sql, 0, sizeof(sql));printf("Insert ...\n");strcpy(sql,"insert into user01.tab02 values(1,'test'||sysdate)");OCIStmtPrepare(stmthp, errhp, (text*)sql, strlen(sql), OCI_NTV_SYNTAX, OCI_DEFAULT);ret=OCIStmtExecute(svchp, stmthp, errhp, (ub4)1, (ub4)0, (CONST OCISnapshot*) 0, (OCISnapshot*)0, (ub4)OCI_DEFAULT);if(ret!=0){OCIErrorGet(errhp, 1, NULL, &ret, (OraText*)errbuf, sizeof(errbuf), OCI_HTYPE_ERROR);printf("\n%s\n", errbuf);sleep(2);continue;}else{// 提交到数据库OCITransCommit(svchp, errhp, OCI_DEFAULT);printf("Insert ok!\n");}///************************************************************************////* 查询表 *////************************************************************************/memset(sql, 0, sizeof(sql));printf("Select ...\n");strcpy(sql, "select C1,C2 from USER01.TAB02 union select SESS_ID as C1,CLNT_IP AS C2 from v$sessions where state='ACTIVE'");/* 准备SQL语句 */OCIStmtPrepare(stmthp, errhp, (text*)sql, strlen(sql), OCI_NTV_SYNTAX, OCI_DEFAULT);/* 绑定输出列 */OCIDefineByPos(stmthp, &defhp[0], errhp, 1, &szc1,sizeof(szc1), SQLT_INT, &ind[0], 0, 0,OCI_DEFAULT);OCIDefineByPos(stmthp, &defhp[1], errhp, 2, (ub1*)szc2,sizeof(szc2), SQLT_STR, &ind[1], 0, 0, OCI_DEFAULT);//OCIDefineByPos(stmthp, &defhp[2], errhp, 3, (ub1*)szphone,sizeof(szphone), SQLT_STR, &ind[2], 0, 0, OCI_DEFAULT);/* 执行SQL语句 */ret = OCIStmtExecute(svchp, stmthp, errhp, (ub4)0, 0, NULL, NULL, OCI_DEFAULT);if (ret != 0){OCIErrorGet(errhp, 1, NULL, &ret, (OraText*)errbuf, sizeof(errbuf), OCI_HTYPE_ERROR);printf("%s\n", errbuf);sleep(2);continue;}else{printf("%-10s%-10s\n", "C1", "C2");while ((OCIStmtFetch(stmthp, errhp, 1, OCI_FETCH_NEXT, OCI_DEFAULT)) != OCI_NO_DATA){printf("%-8d", szc1);printf("%s\n", szc2);//       printf("%-10s\n", szphone);}printf("\nSelect ok!\n");}sleep(2);}//结束循环closeDB();return 0;
  • 编译脚本并运行
[root@test OCI]# g++ -o testOci testOci.cpp -I/home/dmdba/dmdbms/include -L/home/dmdba/dmdbms/bin -ldmoci执行
./testOci
  • 断网卡住后进行跟踪

pstack查看

通过跟踪发现tcp连接已建立,但一直未断开

 

 解决办法

修改应用端内核参数

vim /etc/sysctl.confnet.ipv4.tcp_retries2=3

修改后sysctl -p生效

再次执行脚本,断网测试,时间缩短为12s,确定断网程序卡住时间过长是因为内核参数导致

tcp_retries2 :INTEGER

默认值为15

在丢弃激活(已建立通讯状况)的TCP连接之前﹐需要进行多少次重试。默认值为15,根据RTO的值来决定,相当于13-30分钟(RFC1122规定,必须大于100秒).

更多问题可访问达梦社区:

达梦数据库 - 新一代大型通用关系型数据库 | 达梦云适配中心

这篇关于达梦数据库-linux环境下断网后连接卡住问题解决的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/748751

相关文章

Android 12解决push framework.jar无法开机的方法小结

《Android12解决pushframework.jar无法开机的方法小结》:本文主要介绍在Android12中解决pushframework.jar无法开机的方法,包括编译指令、框架层和s... 目录1. android 编译指令1.1 framework层的编译指令1.2 替换framework.ja

MySQL主从同步延迟问题的全面解决方案

《MySQL主从同步延迟问题的全面解决方案》MySQL主从同步延迟是分布式数据库系统中的常见问题,会导致从库读取到过期数据,影响业务一致性,下面我将深入分析延迟原因并提供多层次的解决方案,需要的朋友可... 目录一、同步延迟原因深度分析1.1 主从复制原理回顾1.2 延迟产生的关键环节二、实时监控与诊断方案

Android开发环境配置避坑指南

《Android开发环境配置避坑指南》本文主要介绍了Android开发环境配置过程中遇到的问题及解决方案,包括VPN注意事项、工具版本统一、Gerrit邮箱配置、Git拉取和提交代码、MergevsR... 目录网络环境:VPN 注意事项工具版本统一:android Studio & JDKGerrit的邮

SQLyog中DELIMITER执行存储过程时出现前置缩进问题的解决方法

《SQLyog中DELIMITER执行存储过程时出现前置缩进问题的解决方法》在SQLyog中执行存储过程时出现的前置缩进问题,实际上反映了SQLyog对SQL语句解析的一个特殊行为,本文给大家介绍了详... 目录问题根源正确写法示例永久解决方案为什么命令行不受影响?最佳实践建议问题根源SQLyog的语句分

Java NoClassDefFoundError运行时错误分析解决

《JavaNoClassDefFoundError运行时错误分析解决》在Java开发中,NoClassDefFoundError是一种常见的运行时错误,它通常表明Java虚拟机在尝试加载一个类时未能... 目录前言一、问题分析二、报错原因三、解决思路检查类路径配置检查依赖库检查类文件调试类加载器问题四、常见

MySQL数据库约束深入详解

《MySQL数据库约束深入详解》:本文主要介绍MySQL数据库约束,在MySQL数据库中,约束是用来限制进入表中的数据类型的一种技术,通过使用约束,可以确保数据的准确性、完整性和可靠性,需要的朋友... 目录一、数据库约束的概念二、约束类型三、NOT NULL 非空约束四、DEFAULT 默认值约束五、UN

windows和Linux使用命令行计算文件的MD5值

《windows和Linux使用命令行计算文件的MD5值》在Windows和Linux系统中,您可以使用命令行(终端或命令提示符)来计算文件的MD5值,文章介绍了在Windows和Linux/macO... 目录在Windows上:在linux或MACOS上:总结在Windows上:可以使用certuti

MySQL 多表连接操作方法(INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL OUTER JOIN)

《MySQL多表连接操作方法(INNERJOIN、LEFTJOIN、RIGHTJOIN、FULLOUTERJOIN)》多表连接是一种将两个或多个表中的数据组合在一起的SQL操作,通过连接,... 目录一、 什么是多表连接?二、 mysql 支持的连接类型三、 多表连接的语法四、实战示例 数据准备五、连接的性

解决IDEA报错:编码GBK的不可映射字符问题

《解决IDEA报错:编码GBK的不可映射字符问题》:本文主要介绍解决IDEA报错:编码GBK的不可映射字符问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录IDEA报错:编码GBK的不可映射字符终端软件问题描述原因分析解决方案方法1:将命令改为方法2:右下jav

MySQL中的分组和多表连接详解

《MySQL中的分组和多表连接详解》:本文主要介绍MySQL中的分组和多表连接的相关操作,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录mysql中的分组和多表连接一、MySQL的分组(group javascriptby )二、多表连接(表连接会产生大量的数据垃圾)MySQL中的