我的系统
- 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)