Назад | Перейти на главную страницу

Как изменить ограничения глубины стека в /etc/security/limits.d/ и применить изменения к службам при загрузке

Моя система


Моя проблема

Во время загрузки появляется следующее сообщение:

 * 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:

Пока кто-то не может дать мне чистое решение, это то, что я придумал, и это отстой. Я не буду принимать это как ответ на мой вопрос, но вот он (приколы). По крайней мере, это работает.


Задний план

Кажется, что меняется на /etc/security/limits.* никогда не влияет на службы, а скорее на вещи, выполняемые из оболочки. Итак, это вносит мои изменения в /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 игнорируют / etc / security / limits

Кажется, что /etc/security/limits.* игнорируется Upstart, который использует Ubuntu 14.04. Моя служба приложений на самом деле использует выскочку, и можно вставить строку для выскочки, которая выглядит так:

limit stack <softlimit> <hardlimit>

Ubuntu перешла на systemd после 14.04, так что эта выскочка потеряет актуальность.

Это не имеет отношения к моему вопросу, потому что 14.04 postgresql не управляется выскочкой.

Итак, я пришел сюда с той же проблемой, и, возможно, вы найдете то, что я сделал, более приемлемым: мой PostgreSQL работает как служба systemd. В служебном файле я ограничил стек с точки зрения ОС:

[Service]
...
LimitSTACK=infinity

Затем в postgresql.conf я установил следующее:

max_stack_depth = 100MB

Это позволило выполнить мой ошибочный рекурсивный запрос в течение нескольких минут вместо секунды.

Я надеюсь, что это поможет вам, спустя 1,5 года после вашего вопроса.

(Postgresql 9.5.10 в Fedora 25)