如何更改 /etc/security/limits.d/ 中的堆栈深度限制,并使更改在启动时应用于服务

如何更改 /etc/security/limits.d/ 中的堆栈深度限制,并使更改在启动时应用于服务

我的系统

  • Ubuntu 14.04.5 (x86_64) 服务器系列,保持更新
  • 我的应用程序需要增加 postgres 的堆栈深度
  • 我创建了一个文件/etc/security/limits.d/myapplication.conf
  • 我的应用程序配置文件文件有以下行:* - stack 131072
  • 请注意 131072KB == 128MB
  • 做完这个我的应用程序配置文件文件,我的ulimit -s回报:131072
  • 然后我编辑了我的/etc/postgresql/9.3/main/postgresql.conf文件并附加以下行:max_stack_depth = 126MB


我的问题

在启动过程中,会出现以下消息:

 * The PostgreSQL server failed to start. Please check the log output:
2018-01-24 09:27:53 MST LOG:  invalid value for parameter "max_stack_depth": 129024
2018-01-24 09:27:53 MST DETAIL:  "max_stack_depth" must not exceed 7680kB.
2018-01-24 09:27:53 MST HINT:  Increase the platform's stack depth limit via "ulimit -s" or local equivalent.
2018-01-24 09:27:53 MST FATAL:  configuration file "/etc/postgresql/9.3/main/postgresql.conf" contains errors
 * Starting Mount network filesystems                                    [ OK ]
 * Starting PostgreSQL 9.3 database server        * Stopping Mount networ[ OK ]systems
                                                                                             [fail] 

这反过来又导致我的应用程序服务失败,因为我依赖我的数据库。启动后,如果我启动 postgres 服务,那就没问题了:

dev@wipn:~$ sudo service postgresql start
 * Starting PostgreSQL 9.3 database server                                                                                                                                                                                                                                                                             [ OK ] 
dev@wipn:~$ 

我猜测/etc/security/limits.d/myapplication.conf仅在启动过程中的某个阶段应用,即我的系统尝试启动 postgres 之后。因此,也许一个显而易见的解决方案就是在启动 postgres 时进行更改,这很好,我可以处理。


我的问题

有什么方法可以改变内核的堆栈深度,以便我只需要对我的服务器进行最少的改动?

我想要尽可能干净的东西。我希望它能够经受住升级,最好适用于其他发行版。我通过 Ansible 剧本管理我的东西,所以我宁愿为此写一个干净的剧本。

可能只是改变我的服务的启动顺序最好的分辨率。有谁知道其他合适的选择吗?


我尝试过的事情

以下是我尝试过但未成功的一些方法的列表。

/etc/security/limits.d/myapplication.conf

  • postgres - stack 131072
  • * - stack 131072 root - stack 131072

答案1

除非有人能给我一个干净的解决方案,否则这就是我想出的办法,而且很糟糕。我不会接受它作为我问题的答案,但它在这里(令人作呕)。至少它有效。


背景

似乎变成了/etc/security/limits。*不会影响服务,而是影响从 shell 执行的内容。因此,这使得我的更改/etc/security/limits。*毫无意义。(在这里插入脏话)我现在已经删除了我的/etc/security/limits.d/myapplication.conf


更改 postgres 的堆栈大小限制

这是一个垃圾解决方案。我讨厌它。

我已经编辑了我的“/usr/share/postgresql-common/init.d-functions”,特别是开始()函数,显示为:

...
# start all clusters of version $1
# output according to Debian Policy for init scripts
start() {
    ulimit -s 131072    #JTS: To avoid Issue #XYZ 

    # create socket directory
    if [ -d /var/run/postgresql ]; then
        chmod 2775 /var/run/postgresql
    else
    ...

显然我添加了 ulimit 行。修改此文件对我来说很恶心,因为我预计它会因更新而永久更改。至少我有一条 Ansible 规则来强制它存在。


我的 Ansible 解决方案

这是我创建的用于强制执行此配置更改的 Ansible 任务:

- blockinfile:
    dest: /usr/share/postgresql-common/init.d-functions
    block: |
          ulimit -s 131072
    backup: yes
    insertafter: '^start\(\) \{'
    state: present

这个 Ansible 任务产生的函数如下所示:

...
# start all clusters of version $1
# output according to Debian Policy for init scripts
start() {
# BEGIN ANSIBLE MANAGED BLOCK
ulimit -s 131072
# END ANSIBLE MANAGED BLOCK
    # create socket directory
    if [ -d /var/run/postgresql ]; then
       ...


值得注意的是:Upstart Services 忽略/etc/security/limits

似乎/etc/security/limits。*被 Ubuntu 14.04 使用的 Upstart 忽略。我的应用服务实际上使用 upstart,你可以为 upstart 插入一行,如下所示:

limit stack <softlimit> <hardlimit>

Ubuntu 在 14.04 之后切换到 systemd,因此这个新兴的 tid-bit 将逐渐变得不再重要。

这与我的问题无关,因为在 14.04 版中,PostgreSQL不是由新贵管理的。

答案2

所以我来这里遇到了同样的问题,也许你觉得我的做法更容易接受:我的 PostgreSQL 作为 systemd 服务运行。在服务文件中,我从操作系统的角度无限了堆栈:

[Service]
...
LimitSTACK=infinity

然后,在 postgresql.conf 中,我设置以下内容:

max_stack_depth = 100MB

这使得我的错误递归查询可以运行几分钟,而不是一秒钟。

我希望它能对你有所帮助,即使在你提出问题一年半之后。

(Fedora 25 上的 Postgresql 9.5.10)

相关内容