su - oracle报错su: cannot set user id: Resource temporarily unavailable

简介: 今天上线服务器连接数较多,我们知道ORACLE是多进程数据库,那么一个session 往往对应了一个OS的process,今天使用root进行切换的时候居然报错。 在测试上模拟再现 [root@testmy proc]# su - oracle su: can...
今天上线服务器连接数较多,我们知道ORACLE是多进程数据库,那么一个session
往往对应了一个OS的process,今天使用root进行切换的时候居然报错。

在测试上模拟再现
[root@testmy proc]# su - oracle
su: cannot set user id: Resource temporarily unavailable
出现这个这个错误当然第一反应是查看ulimit -a,如果真是资源不够了卧槽就悲剧

我使用开始连接好的进行查看:
[oracle@testmy ~]$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 31501
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 65535
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 16384
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited


一般我们需要关注
max user processes              (-u) 16384
open files                      (-n) 65535

用户可以打开的最大进程数和每个进程可以打开的最大文件数量,当然这个限制是hard限制。
不管怎么样明显没有超出,因为我的进程总数才1000多个,而且数据库日志没有任何报错,如
果资源不够那么就会出现比如fork进程失败的报错,或者超过最大文件数的报错,但是这里
没有,松了一口气。那么为什么出现这样的情况。查了一会资料发现没什么鸟用,那么我只
有自己找原因了。
首先明确问题:
1、ORACLE用户进程的总数没有超过hard限制,ORACLE没有任何问题
2、su - oracle报资源错误 Resource temporarily unavailable

那么我们只能从su - oracle做了什么入手了,首先要明确su - oracle到底做了什么实际上就是
bash(23799)───su(23819)───bash(23820)

bash fork 一个进程进行 su命名执行然后 su fork 一个进程出来 跑bash进程。好那么我们进行
strace:
strace -o strace.log -f -ff   su - oracle
-f表示trace fork出来的子进程 -ff表示在strace.log后面加上进程的pid
出来如下:
-rw-r--r--  1 root root      3330 Jan  4 08:52 strace.log.4804
-rw-r--r--  1 root root     40230 Jan  4 08:52 strace.log.4803
首先看一下strace.log.4804
找到重点:
setgroups(2, [501, 502])                = 0
setgid(501)                             = 0
setuid(502)                             = -1 EAGAIN (Resource temporarily unavailable)
setuid(502)的时候返回-1 报错并且设置errno为EAGAIN并且报错了Resource temporarily unavailable
( #define    EWOULDBLOCK    EAGAIN    /* Operation would block */)
setuid系统调用就是用于改变其有效userid的,那么我们看看setuid的返回值
RETURN VALUE
       On success, zero is returned.  On error, -1 is returned, and errno is set appropriately.

ERRORS
       EAGAIN The uid does not match the current uid and uid brings process over its RLIMIT_NPROC resource limit.

       EPERM  The user is not privileged (Linux: does not have the CAP_SETUID capability) and uid does not match the real UID or saved  set-user-ID  of
              the calling process.

显然这里我们可能的原因就是over its RLIMIT_NPROC resource limit,RLIMIT_NPROC位用户允许的最大进程数,
       RLIMIT_NPROC
              The  maximum  number of processes (or, more precisely on Linux, threads) that can be created for the real user ID of the calling process.
              Upon encountering this limit, fork(2) fails with the error EAGAIN.

那么ORACLE允许的进程数hard限制为16384明显没有超出,那么只可能是超过了其soft限制看看另外一个文件找到关键

setrlimit(RLIMIT_NPROC, {rlim_cur=1024, rlim_max=16*1024}) = 0

这里的rlim_cur为soft限制,为1024个,结构体如下:
          struct rlimit {
               rlim_t rlim_cur;  /* Soft limit */
               rlim_t rlim_max;  /* Hard limit (ceiling for rlim_cur) */
           };

卧槽原因找到了,然后就要找到为什么是1024查看/etc/security/limits.conf
设置为:
* soft nproc 16384
* hard nproc 16384
* soft nofile 65535
* hard nofile 65535

也不是1024啊,然后查看/etc/security/limits.d/90-nproc.conf 
*          soft    nproc     1024
root       soft    nproc     unlimited

这里出现了1024,应该就是使用的这里的1024,然后修改后
*          soft    nproc     16384


切换成功再次查看
setrlimit(RLIMIT_NPROC, {rlim_cur=16*1024, rlim_max=16*1024}) = 0 
看到这里rlim_cur设置为了16*1024也就是16384.看来su 的时候确实是使用
的nproc的soft限制,那么这里涉及2个文件
/etc/security/limits.d/90-nproc.conf 
/etc/security/limits.conf
我们在上面的案例中看到当设置为
*          soft    nproc     1024这种的时候
90-nproc.conf 的优先级大于limits.conf,
但是经过我测试如果limits.conf 中如果指定用户
如:
oracle        soft    nproc     16384
会高于90-nproc.conf 。
同时要注意一下 90-nproc.conf这个文件生效的范围:
The issue starts only after upgrading the kernel later to 2.6.32-431.el6.x86_64

最后总结一下:
1、su -的时候使用的是soft限制
2、为了保证没有问题请这样设置
/etc/security/limits.conf
* soft nproc 16384
* hard nproc 16384
* soft nofile 65535
* hard nofile 65535
同时设置/etc/security/limits.d/90-nproc.conf 

*          soft    nproc     16384
设置profile也是:
if [ $USER = "oracle" ] || [ $USER = "grid" ]; then
        if [ $SHELL = "/bin/ksh" ]; then
              ulimit -u 16384
              ulimit -n 65535
        else
              ulimit -u 16384 -n 65535
        fi
        umask 022
fi

当然这里的设置为你实际的大小比如你的数据库最大会话数都超过了16384当然 nproc要设置得更大
相关文章
|
11月前
|
Java 数据库连接
nacos2.0.3报错No Datasource Set
nacos2.0.3报错No Datasource Set com.mysql.cj.exceptions.CJException: Public Key Retrieval is not allowed
nacos2.0.3报错No Datasource Set
|
2月前
|
Oracle 关系型数据库 数据库
数据库数据恢复—服务器异常断电导致Oracle数据库报错的数据恢复案例
Oracle数据库故障: 某公司一台服务器上部署Oracle数据库。服务器意外断电导致数据库报错,报错内容为“system01.dbf需要更多的恢复来保持一致性”。该Oracle数据库没有备份,仅有一些断断续续的归档日志。 Oracle数据库恢复流程: 1、检测数据库故障情况; 2、尝试挂起并修复数据库; 3、解析数据库文件; 4、导出并验证恢复的数据库文件。
|
6月前
|
Oracle 关系型数据库 MySQL
【YashanDB知识库】oracle dblink varchar类型查询报错记录
这篇文章主要介绍了 Oracle DBLINK 查询崖山 DB 报错的相关内容,包括 ODBC 安装配置、数据源配置、dblink 环境配置、问题原因分析及规避方法。问题原因是 dblink 连接其他数据库时 varchar 类型转换导致的,还介绍了 long 类型限制、char 等类型区别,规避方法是修改参数 MAX_STRING_SIZE 支持 32K。
|
8月前
|
Oracle 关系型数据库 数据库
【YashanDB知识库】oracle dblink varchar类型查询报错记录
在使用Oracle DBLink查询VARCHAR类型数据时,可能会遇到多种报错。通过了解常见错误原因,采取合适的解决方法,可以有效避免和处理这些错误。希望本文提供的分析和示例能帮助你在实际工作中更好地处理DBLink查询问题。
221 10
|
9月前
|
Java Maven Spring
【SpringBug】lombok插件失效,但是没有报错信息,@Data不能生成get和set方法
解决写了@Data注解,但是在测试文件中生成的反编译target文件Us二Info中没有get和set方法
799 16
|
10月前
|
JSON Java 关系型数据库
Java更新数据库报错:Data truncation: Cannot create a JSON value from a string with CHARACTER SET 'binary'.
在Java中,使用mybatis-plus更新实体类对象到mysql,其中一个字段对应数据库中json数据类型,更新时报错:Data truncation: Cannot create a JSON value from a string with CHARACTER SET 'binary'.
1090 4
Java更新数据库报错:Data truncation: Cannot create a JSON value from a string with CHARACTER SET 'binary'.
|
JavaScript 前端开发
15 Uncaught TypeError: Cannot set properties of null (setting ‘onclick‘)
这篇文章解释了在HTML文档中因JavaScript代码在页面元素加载之前执行导致的"Cannot set properties of null (setting ‘onclick’)"错误,并提供了将JavaScript代码置于`<body>`标签内或使用`window.onload`事件确保DOM完全加载后再绑定事件处理器的解决办法。
15 Uncaught TypeError: Cannot set properties of null (setting ‘onclick‘)
|
2月前
|
存储 缓存 JavaScript
Set和Map有什么区别?
Set和Map有什么区别?
246 1
|
3月前
|
存储 JavaScript 前端开发
for...of循环在遍历Set和Map时的注意事项有哪些?
for...of循环在遍历Set和Map时的注意事项有哪些?
256 121
|
6月前
|
编译器 C++ 容器
【c++丨STL】基于红黑树模拟实现set和map(附源码)
本文基于红黑树的实现,模拟了STL中的`set`和`map`容器。通过封装同一棵红黑树并进行适配修改,实现了两种容器的功能。主要步骤包括:1) 修改红黑树节点结构以支持不同数据类型;2) 使用仿函数适配键值比较逻辑;3) 实现双向迭代器支持遍历操作;4) 封装`insert`、`find`等接口,并为`map`实现`operator[]`。最终,通过测试代码验证了功能的正确性。此实现减少了代码冗余,展示了模板与仿函数的强大灵活性。
172 2