sdb报告-10 错误问题定位
# sdb报告-10 错误问题定位
在sdb 的集群环境中,如果面对的是一个高并发的操作场景,有时候会莫名其妙地报告 -10 错误。
在 sdb 的错误列表中,-10 错误代表:系统错误。
这是一个笼统的错误描述,也是一个让人迷惑的错误描述。"系统错误"?什么鬼的系统错误,究竟是什么地方导致了系统错误?
作者通过分析大量的 -10 错误案例,发现大部分情况下,都是由于线程创建失败。
一般抛出 -10 错误的都是数据节点,并且一般数据节点的 diaglog 日志关键的错误信息如下
```
Failed to create new agent: boost::thread_resource_error: Resource temporaily unavailable
Failed to create new agent, probe = 30
Failed to create subagent thread, rc = -10
Failed to start session EDU, rc = -10
```
# linux 线程创建失败,原因分析
一般操作linux 系统在创建线程时,会受限于哪些参数呢,主要有两个
* 文件句柄数限制
* 内存资源
## 系统句柄
我们先来介绍文件句柄数
在linux 操作系统中,号称一切皆为文件,无论是进程、线程、socket 还是其他,最终都会被操作系统归为文件操作。操作系统或者进程,每申请一个资源,例如线程、socket,都会打开一个文件,那么这个文件打开状态,就可以简单理解为文件句柄。
那么句柄数限制又是什么呢?其实就是操作系统,或者某个进程所能够打开的最多文件的数量的限制。
大家有了这个概念后,我们再来看操作系统是如何对文件句柄数进行限制的。
在操作系统中,有一个神奇的命令 -- ulimit ,专门设置这些奇奇怪怪的限制值,进程最大文件句柄数和用户最大进程数就是其中的设置。
### 进程最大文件句柄数
例如我们可以查看 root 用户的 ulimit 输出, -n open file = 1024 就是root 用户允许一个进程打开的最大文件句柄数。
这里有一个小细节需要大家注意的。
由于root 用户是linux 中的管理员用户,所以如果root 用户的 ulimit open file 设置成 1024, 那么其他的用户,例如:test、mysql 用户等,想将 ulimit opon file 设置成 大于 1024,是不允许的。
这个大家一定要知道,如果希望将普通用户的 ulimit 值修改得很大,一定要先修改 root 用户的值。
### 用户最大进程数
一个系统用户,也有它最大的进程数,参数为 ulimit -u 命令。
该参数的官方解释如下:
```
Linux itself has a Max Processes per user limit. This feature allows us to control the number of processes an existing user on the server may be authorized to have
```
虽然解释是一个用户的进程限制,但是从使用效果分析,对线程数也有明显限制效果,毕竟线程是从进程中派生出来的资源。
一个用户的进程数限制,修改的方式和 ulimit -n 的方式一样。
### 系统总句柄限制
另外,关于句柄数的限制,还不单单是进程中和一个用户的句柄数限制,还有整个操作系统的句柄数限制,因为一个操作系统,总不能无限地打开句柄的。所以又引入另外一个设置,操作系统最大打开的句柄数限制。
以 centos 7 系统为例,该参数是被保存在 /proc/sys/fs/file-max 文件中
如果操作系统总的句柄数已经达到上限,那么即使进程还没有启动几个线程,也会出现句柄不够的情况。
如果希望临时修改操作系统最大句柄数的设置,可以直接执行
```
echo 2000000 > /proc/sys/fs/file-max
```
如果希望永久修改操作系统最大句柄数的设置,可以编辑 /etc/sysctl.conf 文件,增加 fs.file-max = 2000000 内容,然后在root 用户中执行
```
sysctl -p
```
## 系统内存
我们接着来介绍内存资源
因为在创建线程时,在linux 中,是需要给它预先分配内存的 – 也叫栈大小,用来存储线程中数据的值。
这里再科普另外一个知识,一个程序中,内存主要分为两个大的部分,一个称为 “堆”,一个称为“栈”。“堆”是程序用来保存常量和变量名字的,“栈”则是程序来用保存具体的变量数字的。
好,背景知识介绍完毕后,开始进入正题。
### 线程栈大小影响
开始时说到,如果系统内存资源不足,也是无法创建线程的。这个原因就是在于创建线程时,操作系统需要分配一块内存给线程,这个内存是多大呢,就是 ulimit 中 -s stack size 的大小。如果操作系统连 stack size 大小的内存都无法 malloc 了,创建线程就会失败。
有一些读者可能会奇怪,为啥这么一点内存都没有了?
其实如果仔细查看操作系统,你就会发现,那么多进程,每个进程又是那么多线程在运行,每个线程都在申请内存(注意,这块的内存是虚拟内存),内存不足正常的很。这个也容易让人联想到JVM 的OOM ,但是他们真的不是一回事,大家千万不要误会。
要解决这个问题也比较简单 –- 简单粗暴?就是将 ulimit 中 -s stack size 调小一点,每个线程不要申请那么多内存了,操作系统的内存资源就会更加的充裕。毕竟进程、线程这些,都是用完就完了,不可能都永久占用内存的。
在centos 7 的系统中,默认的 stack size 是8MB,一般使用默认值,都不会出现 "创建线程" 的错误,只有当极限情况才会对用户造成影响。
### 内存地址检查
在linux 系统中,内存管理是一个细致活。
其实在linux 的系统内存管理中,有两层
* 物理内存
* 虚拟内存
物理内存很好理解,就是用户为操作系统配置的RAM 大小,也是人们日常所说的服务器内存大小。
虚拟内存,是操作系统为了更好管理物理内存而设计出来的一层虚拟资源。因为操作系统在运行过程中,很多进程都在使用、释放内存,真实 free 的物理内存必然是不连续的。
所以操作系统为了让程序在使用内存时,更加方便的使用物理内存,构造了一层虚拟内存。
进程在向操作系统 malloc 一段连续的内存时,实际从虚拟内存中申请了一段连续的地址。在操作系统的内存映射表中,记录了虚拟内存地址指向真实的物理内存地址。
同时,即使程序 malloc 了内存,但实际上在 malloc 后,并不会真的立马占用了物理内存,只有当真正开始保存数据时,才会实际使用物理内存。
介绍到这里,读者们可能就对内存 malloc 有所了解了。
提问:如果操作系统真的是没有内存了而导致无法创建新的线程,那么如何定位这个问题呢?
在linux 操作系统中,实际上时刻都在记录内存的使用情况。
用户可以通过以下命令获得重要信息
```
cat /proc/meminfo | grep Commit
```
该命令将打印两个重要的数值
* CommitLimit
* Committed_AS
CommitLimit 参数,是操作系统最大可以 malloc 的内存的大小。
Committed_AS 参数,是操作系统当前已经被 malloc 了的内存的大小。
所以简单的总结,就是当 Committed_AS 参数的值无限接近 CommitLimit 参数的值时,证明当前的操作系统,真的没有太多可用内存可以继续给 malloc 了。
### 内核参数中的内存管理
针对linux 系统的内存控制,实际上真的是一个细致活。
它对内存的管理,各种参数有着交叉互相影响关系,作者在这里尝试使用毕生功力,尽量为读者解释明白。读者如果还有疑问,请咨询谷姐和度娘,作者本人可能会对大家热情的提问,累觉不爱
sdb报告-10 错误问题定位的更多相关文章
- mysql-5.7.10-winx64 MySQL服务无法启动,服务没有报告任何错误的解决办法
总结报错原因:在my.init文件下新增data目录(datadir = F:\mysqldata ) 最新解压版本的mysql 解压安装的时候报错D:\mysql\mysql-5.7.10-wi ...
- mysql 5.7 非正常安装,无法启动 服务没有报告任何错误
以前,完整安装mysql5.7程序时,由于程序太大,可以将安装缓存目录中的安装文件(较小)复制出来后,留以后使用. mysql--win32.msi 2 mysql-5.7.17-winx64.msi ...
- mysql-5.7.9-winx64 MySQL服务无法启动,服务没有报告任何错误的解决办法
问题背景 最新解压版本的mysql 解压安装的时候报错 D:\mysql-5.7.9-winx64\bin>net start mysql MySQL 服务正在启动 . MySQL 服务无法启动 ...
- SVN中与资源库同步时报告了错误。1 中的 0 个资源已经同步
SVN中与资源库同步时报告了错误.1 中的 0 个资源已经同步 原因: 文件被lock, 此时再次提交则出错,解决办法就是clean释放锁即可再次提交: 解决方案: 右键项目–>team–> ...
- Alpha 冲刺报告(10/10)
Alpha 冲刺报告(10/10) 队名:洛基小队 峻雄(组长) 已完成:阿尔法版的ppt 明日计划:总结阿尔法版的问题 剩余任务:角色属性脚本的完整版本 困难:缺乏编码经验,编码进度比较慢 ---- ...
- Illegal instruction错误的定位---忽略编译期警告的代价
在原计算机的linux c++程序可以正确跑起来,但是换了一台机器运行时出现致命错误,程序直接当掉,错误提示如下: Illegal instruction (core dumped) 造成改错的主要原 ...
- 【mysql】【windows】MySQL 服务无法启动,服务没有报告任何错误,请键入 NET HELPMSG 3534 以获得更多的帮助。
成功安装以后,启动MySQL,输入: net start mysql 提示: ”MySQL 服务无法启动,服务没有报告任何错误,请键入 NET HELPMSG 3534 以获得更多的帮助.” 查了下, ...
- windows的mysql无法启动 服务没有报告任何错误
相信很多人都遇到过安装Mysql的时候出现各种各样的问题,今天小编就教大家解决window下mysql服务没有报告任何错误的情况下无法启动 的问题.本文所用的mysql版本是5.7以上版本,解决方法: ...
- mysql5.7安装中的问题(服务无法启动。服务没有报告任何错误。排查方法)
1.拒绝访问的问题 权限不够,必须以管理员身份启动命令行 2.MySQL 服务无法启动.服务没有报告任何错误. 进入到你的mysql安装目录,C:\Program Files\MySQL\MySQL ...
随机推荐
- 使用pycharm调试远程服务器上的程序
一.PyCharm实现远程调试代码 1. 和远程服务器建立连接,tools àDeploymentàConfiguration 2. 点击“+”号,按照远程服务器信息配置信息 点击“Advanced ...
- Python 学习笔记19 安装robot Framework
因为项目组要做自动化测试,本人其实很希望能够使用 MStest + unit + C#来实现. 毕竟产品是基于.net 环境,并且使用C#环境开发的,适用性比较好,一些开发代码可以复用. 但是领导基于 ...
- Django Rest Framewoek
1 什么是RESTful REST 指的是一种软件架构风格.设计风格,而不是标准,只是提供了一组设计原则和约束条件.满足这些约束条件和原则的应用程序或设计就是 RESTful. 2 RESTful设计 ...
- Thinkphp在nginx设置同域名二级目录访问
Thinkphp在nginx设置同域名二级目录访问,是因为最近弄一个小程序项目,要https,但是只有单个域名,不能通配域名,所有只好用二级目录,thinkphp二级目录访问要怎么设置呢 下面是ngi ...
- Crash的数字表格(莫比乌斯反演)
Crash的数字表格 Description 今天的数学课上,Crash小朋友学习了最小公倍数(Least Common Multiple).对于两个正整数a和b,LCM(a, b)表示能同时被a和b ...
- 在Intellij上开发项目发布到tomcat时,同一个局域网内的其他机子访问不到自己电脑上tomcat中的项目,只能本机访问
在Intellij上开发项目发布到tomcat时,同一个局域网内的其他机子访问不到自己电脑上tomcat中的项目,只能本机访问 问题描述:在Intellij上开发项目发布到tomcat时,同一个局域网 ...
- MySQL语句优化方法(简单版)
基础回顾: sql语句是怎么样运行的? 一般来说,客户端发送sql语句到数据库服务器——数据库服务器进行运算并返回结果——客户端显示sql语句运行结果. 在本地运行时以workbench为例,客户端为 ...
- shell变量的声明和使用
- 93-基于ATOM E3825的3U PXIe 主板控制器
基于ATOM E3825的3U PXIe 主板控制器 一.板卡概述: 本主板采用intel ATOM 处理器 E3825 设计主板控制器,是一种低成本.低功耗解决方案.板卡采用Intel Bay Tr ...
- BZOJ4386 [POI2015]Wycieczki 矩阵+倍增
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4386 题解 一眼就可以看出来是邻接矩阵快速幂. 可是这里的边权不为 \(1\).不过可以发现, ...