# 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 错误问题定位的更多相关文章

  1. mysql-5.7.10-winx64 MySQL服务无法启动,服务没有报告任何错误的解决办法

      总结报错原因:在my.init文件下新增data目录(datadir = F:\mysqldata ) 最新解压版本的mysql 解压安装的时候报错D:\mysql\mysql-5.7.10-wi ...

  2. mysql 5.7 非正常安装,无法启动 服务没有报告任何错误

    以前,完整安装mysql5.7程序时,由于程序太大,可以将安装缓存目录中的安装文件(较小)复制出来后,留以后使用. mysql--win32.msi 2 mysql-5.7.17-winx64.msi ...

  3. mysql-5.7.9-winx64 MySQL服务无法启动,服务没有报告任何错误的解决办法

    问题背景 最新解压版本的mysql 解压安装的时候报错 D:\mysql-5.7.9-winx64\bin>net start mysql MySQL 服务正在启动 . MySQL 服务无法启动 ...

  4. SVN中与资源库同步时报告了错误。1 中的 0 个资源已经同步

    SVN中与资源库同步时报告了错误.1 中的 0 个资源已经同步 原因: 文件被lock, 此时再次提交则出错,解决办法就是clean释放锁即可再次提交: 解决方案: 右键项目–>team–> ...

  5. Alpha 冲刺报告(10/10)

    Alpha 冲刺报告(10/10) 队名:洛基小队 峻雄(组长) 已完成:阿尔法版的ppt 明日计划:总结阿尔法版的问题 剩余任务:角色属性脚本的完整版本 困难:缺乏编码经验,编码进度比较慢 ---- ...

  6. Illegal instruction错误的定位---忽略编译期警告的代价

    在原计算机的linux c++程序可以正确跑起来,但是换了一台机器运行时出现致命错误,程序直接当掉,错误提示如下: Illegal instruction (core dumped) 造成改错的主要原 ...

  7. 【mysql】【windows】MySQL 服务无法启动,服务没有报告任何错误,请键入 NET HELPMSG 3534 以获得更多的帮助。

    成功安装以后,启动MySQL,输入: net start mysql 提示: ”MySQL 服务无法启动,服务没有报告任何错误,请键入 NET HELPMSG 3534 以获得更多的帮助.” 查了下, ...

  8. windows的mysql无法启动 服务没有报告任何错误

    相信很多人都遇到过安装Mysql的时候出现各种各样的问题,今天小编就教大家解决window下mysql服务没有报告任何错误的情况下无法启动 的问题.本文所用的mysql版本是5.7以上版本,解决方法: ...

  9. mysql5.7安装中的问题(服务无法启动。服务没有报告任何错误。排查方法)

    1.拒绝访问的问题 权限不够,必须以管理员身份启动命令行 2.MySQL 服务无法启动.服务没有报告任何错误. 进入到你的mysql安装目录,C:\Program Files\MySQL\MySQL ...

随机推荐

  1. Linux libOpenThreads库链接冲突错误

    最近在linux 上安装了3.7.0版本的OpenSceneGraph,而在安装之前没有完全卸载之前安装的3.6.3版本,导致在编译程序链接时出现库引用冲突,在便以后出现以下警告信息: /usr/bi ...

  2. 如何创建linux虚拟机

    一.安装配置linux虚拟机 第1步:运行"Vmware WorkStation",看到主页面. 第2步:创建新的虚拟机,新建虚拟机向导——典型(推荐). 第3步:选择稍后安装操作 ...

  3. JavaScript defineProperties

    function defineProperties(obj, properties) {   function convertToDescriptor(desc)   {     function h ...

  4. 基于dvwa环境下级别为low的SQL手工注入教程

    基于dvwa环境下级别为low的SQL手工注入教程: 首先是进入已搭建好的dvwa环境中去(一定要搭建好dvwa环境才能进行下面的操作),这可能会是一些初学者所面临的的第一个问题,比如我,曾为了寻找这 ...

  5. [未解决]报错: crawlab启动失败

    拉取镜像 docker pull tikazyq/crawlab:latest 一键启动 docker-compose up 报错提示:

  6. luoguP3384 [模板]树链剖分

    luogu P3384 [模板]树链剖分 题目 #include<iostream> #include<cstdlib> #include<cstdio> #inc ...

  7. MongoDB数据库-基础篇

    一使用mongodb 1.常用的命令 show dbs    显示数据库列表 use dbname    进入dbname数据库,大小写敏感,没有这个数据库也不要紧 show collections ...

  8. python学习第三十天函数的形参,实参及函数文档

    python函数的形参是定义函数def 函数名 小括号里面的变量,实参是调用函数时候的值,函数文档是提供函数功能的开发文档,下面 详细说明系列方法 1,函数的形参 def chan(name): pr ...

  9. C中char类型的用法

    代码 /* char类型的用法 */ #include <stdio.h> main(int argc, char *argv[]) { /* 声明字符变量c1 */ char c1 = ...

  10. 20個命令行工具監控 Linux 系統性能

    對於每個系統管理員或網路管理員來說,每天要監控和調試 Linux 系統性能問題都是非常困難的工作.我已經有5年 Linux 管理員的工作經歷,知道如何監控系統使其保持正常運行.為此,我們編寫了對於 L ...