Обновление Discourse продолжает не удаваться

Сниппет дампа памяти и сообщение об ошибочной инструкции указывают на то, что на низком уровне (процессор, память) происходит сбой.

Я не эксперт в области аппаратного обеспечения, но этот процессор появился на рынке 12 лет назад, и я подозреваю, что он может быть слишком старым (то есть он пытается выполнить скомпилированный код, рассчитанный на более новый процессор).

Мы думали об этом, но учитывая, что всё работало исправно последние три года, что именно в стеке могло измениться и вдруг потребовать новую инструкцию? (Кроме того, какая именно инструкция?)

Может ли ФУНКЦИЯ: Добавлена поддержка параметра clear_every в бэкенде Redis (#309) · discourse/message_bus@1baa1ea · GitHub вызывать иное поведение в Redis? :thinking:

Хочу также добавить, что в прошлую пятницу обновление до основной версии прошло без сбоев, и система работала всю неделю без единой проблемы. Даже в воскресенье я успешно выполнил обновление. Если причиной является процессор, что вполне понятно, то эта ошибка проявилась бы при обновлении до основной версии.

Но, возможно, с понедельника что-то изменилось…

Это вполне может быть так, он падает в процедуре парсинга JSON в коде message_bus, хотя упомянутое вами изменение было внесено более 4 месяцев назад.

-- Информация о трассировке стека на уровне C -------------------------------------------
/usr/local/lib/libruby.so.2.7(rb_vm_bugreport+0x50a) [0x7f30fc64839a] vm_dump.c:755
[0x7f30fc4b9b47]
/usr/local/lib/libruby.so.2.7(sigill+0x3b) [0x7f30fc5c4f0b] signal.c:962
/lib/x86_64-linux-gnu/libc.so.6(0x7f30fc283d60) [0x7f30fc283d60]
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/oj-3.13.15/lib/oj/oj.so(oj_parse2+0x4f9) [0x7f30f3a68339] /usr/lib/gcc/x86_64-linux-gnu/10/include/smmintrin.h:649

I, [2022-07-05T10:03:30.513303 #1]  INFO -- : > cd /var/www/discourse && su discourse -c 'bundle exec rake db:migrate'
/var/www/discourse/vendor/bundle/ruby/2.7.0/gems/message_bus-4.2.0/lib/message_bus/codec/json.rb:11: [BUG] Недопустимая инструкция по адресу 0x00007f30f3a68339
ruby 2.7.6p219 (2022-04-12 revision c9c2245c0a) [x86_64-linux]

-- Информация о кадре управления -----------------------------------------------
c:0030 p:---- s:0162 e:000161 CFUNC  :parse
c:0029 p:0013 s:0157 e:000156 METHOD /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/message_bus-4.2.0/lib/message_bus/codec/json.rb:11
c:0028 p:0037 s:0152 e:000151 METHOD /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/message_bus-4.2.0/lib/message_bus.rb:648
c:0027 p:0020 s:0144 e:000143 BLOCK  /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/message_bus-4.2.0/lib/message_bus.rb:766
c:0026 p:0082 s:0135 e:000134 BLOCK  /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/message_bus-4.2.0/lib/message_bus/backends/redis.rb:330
c:0025 p:0024 s:0130 e:000129 BLOCK  /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.5.1/lib/redis/subscribe.rb:46
c:0024 p:0034 s:0124 e:000123 BLOCK  /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.5.1/lib/redis/client.rb:183 [FINISH]

Да… значит, оно уже должно было быть в воскресенье. :pensive:

Просматривая логи, я заметил, что, похоже, уже запущен другой экземпляр Redis, когда система пытается его запустить.
Может ли это быть причиной проблемы?

102:C 05 Jul 2022 09:53:34.597 # oO0OoO0OoO0Oo Redis запускается oO0OoO0OoO0Oo
102:C 05 Jul 2022 09:53:34.597 # Версия Redis=6.2.6, разрядность=64, коммит=00000000, изменено=0, pid=102, только что запущен
102:C 05 Jul 2022 09:53:34.597 # Конфигурация загружена
102:M 05 Jul 2022 09:53:34.598 * Монохронные часы: POSIX clock_gettime
102:M 05 Jul 2022 09:53:34.599 * Режим работы=standalone, порт=6379.
102:M 05 Jul 2022 09:53:34.599 # Сервер инициализирован
102:M 05 Jul 2022 09:53:34.599 # ПРЕДУПРЕЖДЕНИЕ: overcommit_memory установлен в 0! Фоновое сохранение может завершиться неудачей при нехватке памяти. Чтобы исправить эту проблему, добавьте 'vm.overcommit_memory = 1' в файл /etc/sysctl.conf, затем перезагрузите систему или выполните команду 'sysctl vm.overcommit_memory=1', чтобы изменения вступили в силу.
102:M 05 Jul 2022 09:53:34.599 * Загрузка RDB, созданного в версии 6.2.6
102:M 05 Jul 2022 09:53:34.599 * Возраст RDB: 1972 секунд
102:M 05 Jul 2022 09:53:34.599 * Использование памяти RDB при создании: 60.60 Мб
102:M 05 Jul 2022 09:53:34.949 # Загрузка RDB завершена, загружено ключей: 8005, истекших ключей: 9.
102:M 05 Jul 2022 09:53:34.950 * База данных загружена с диска за 0.351 секунды
102:M 05 Jul 2022 09:53:34.950 * Готов к принятию подключений
129:C 05 Jul 2022 09:53:45.056 # oO0OoO0OoO0Oo Redis запускается oO0OoO0OoO0Oo
129:C 05 Jul 2022 09:53:45.056 # Версия Redis=6.2.6, разрядность=64, коммит=00000000, изменено=0, pid=129, только что запущен
129:C 05 Jul 2022 09:53:45.056 # Конфигурация загружена
129:M 05 Jul 2022 09:53:45.057 * Монохронные часы: POSIX clock_gettime
129:M 05 Jul 2022 09:53:45.057 # Предупреждение: Не удалось создать TCP-сокет для прослушивания сервера *:6379: bind: Адрес уже используется
129:M 05 Jul 2022 09:53:45.057 # Не удалось начать прослушивание порта 6379 (TCP), прерывание.
102:signal-handler (1657015415) Получен сигнал SIGTERM, планирование завершения работы...
102:M 05 Jul 2022 10:03:35.245 # Пользователь запросил завершение работы...
102:M 05 Jul 2022 10:03:35.245 * Сохранение финального снимка RDB перед выходом.
102:M 05 Jul 2022 10:03:39.882 * База данных сохранена на диск
102:M 05 Jul 2022 10:03:39.882 # Redis теперь готов к выходу, пока...

Это вполне нормально для launcher rebuild app — это ни на что не влияет (насколько мне известно, по крайней мере…).

Пути выполнения кода также могут срабатывать при наличии или отсутствии определённых данных. Возможно, проблемный код уже присутствовал, но не выполнялся.

Я попробую применить квази-бисекцию к последнему набору коммитов и посмотрю, смогу ли я сузить круг до конкретного недавнего изменения. Это займет «некоторое время»… :sweat_smile:

Редактирование:

Хорошо, первый проблемный коммит с ошибкой недопустимой инструкции — это Build(deps): Bump oj from 3.13.14 to 3.13.15 (#17309) · discourse/discourse@4c69619 · GitHub, который связан с Fix NaN object dump issue · ohler55/oj@f0122cf · GitHub

Некоторые предыдущие коммиты также не собираются, но с другой ошибкой (которая, похоже, тоже может быть временной…):

I, [2022-07-05T12:14:35.377926 #1]  INFO -- : > cd /var/www/discourse && su discourse -c 'bundle exec rake db:migrate'                                                          
102:M 05 Jul 2022 12:14:44.308 * 100 изменений за 300 секунд. Сохранение...                                                                                                          
102:M 05 Jul 2022 12:14:44.312 * Фоновое сохранение запущено процессом с PID 709                                                                                                           
709:C 05 Jul 2022 12:14:45.166 * База данных сохранена на диск                                                                                                                               
709:C 05 Jul 2022 12:14:45.169 * RDB: 1 МБ памяти использовано при копировании при записи                                                                                                      
102:M 05 Jul 2022 12:14:45.217 * Фоновое сохранение завершено успешно                                                                                                      
I, [2022-07-05T12:14:46.192386 #1]  INFO -- :                                                                                                                                   
I, [2022-07-05T12:14:46.193317 #1]  INFO -- : > cd /var/www/discourse && su discourse -c 'bundle exec rake themes:update assets:precompile'                                     
                                                                                                                                                                                
Отсутствуют пакеты yarn:                                                                                                                                                          
Пакет: ember-cli-deprecation-workflow                                                                                                                                         
  * Указан: ^2.1.0                                                                                                                                                           
  * Установлен: (не установлен)                                                                                                                                                  
                                                                                                                                                                                
Запустите `yarn` для установки отсутствующих зависимостей.                                                                                                                                     
                                                                                                                                                                                
                                                                                                                                                                                
                                                                                                                                                                                
Стек вызовов и отчёт об ошибке: /tmp/error.dump.ccfa3d8342a442ee6860db37ce7c7330.log                                                                                              
Произошла ошибка в конструкторе для ember-cli-dependency-checker в /var/www/discourse/app/assets/javascripts/node_modules/ember-cli-dependency-checker                    
                                                                                                                                                                                
error Command failed with exit code 1.

Хорошее замечание, действительно происходит сбой в геме oj.

Версия 3.13.15 также включает этот коммит, который переключается на использование инструкций SSE 4.2 для повышения производительности. Однако они не поддерживаются процессорами AMD Opteron 41xx.

Таким образом, мы возвращаемся к

По моему мнению, это плохо, что автор гема решил сделать это компиляционным выбором.

Отлично. Ещё одно изменение, не упомянутое в журнале изменений oj… :grin:

Итак, если при установке гема не выполняется его нативная компиляция (что теоретически позволяет заставить его работать через OJ_USE_SSE4_2), похоже, потребуется перенос сервера… :expressionless:

Редактирование: сам гем не распространяет никаких предварительно скомпилированных объектов, так что это должно быть выполнимо. Следующий вопрос: почему он компилируется с SSE4.2 на системе, которая его не поддерживает.

Наш текущий базовый образ использует версию 3.13.14, поэтому компиляция выполняется на вашей системе.

Попробуйте воспроизвести ошибку с помощью скрипта бенчмарка из этого коммита:

○ → docker run --rm -it -u discourse discourse/base:2.0.20220621-0049 bash
discourse@313d7af3be39:/$ cd
discourse@313d7af3be39:~$ gem install --user pry benchmark-ips oj
…
Successfully installed oj-3.13.15
5 gems installed
discourse@313d7af3be39:~$ /home/discourse/.local/share/gem/ruby/2.7.0/bin/pry
[1] pry(main)> require 'benchmark/ips'
require 'oj'

def json(string)
  "\"#{string}\""
end

Benchmark.ips do |x|
  x.warmup = 5
  x.time = 20

  json_0   = json('a' *   0)
  json_64  = json('a' *  64)
  json_128 = json('a' * 128)

  x.report('Oj.load   [0]') { Oj.load(json_0) }
  x.report('Oj.load  [64]') { Oj.load(json_64) }
  x.report('Oj.load [128]') { Oj.load(json_128) }
end;

Также можно проверить, была ли компиляция выполнена с использованием проблемной инструкции, следующим образом:

discourse@313d7af3be39:~$ objdump -d /home/discourse/.local/share/gem/ruby/2.7.0/gems/oj-3.13.15/lib/oj/oj.so | grep -C3 pcmpestri
   2e32b:	0f 82 b5 03 00 00    	jb     2e6e6 <oj_parse2+0x8a6>
   2e331:	66 0f 6f 05 77 d6 01 	movdqa 0x1d677(%rip),%xmm0        # 4b9b0 <exp_plus+0x330>
   2e338:	00 
   2e339:	66 0f 3a 61 07 00    	pcmpestri $0x0,(%rdi),%xmm0
   2e33f:	83 f9 10             	cmp    $0x10,%ecx
   2e342:	74 dc                	je     2e320 <oj_parse2+0x4e0>
   2e344:	48 63 c9             	movslq %ecx,%rcx

Если это так, то, вероятно, стоит сообщить об этом в проект gem oj.

Я действительно хочу ещё немного изучить этот вопрос, но: 1) я хочу избежать дополнительного простоя (по крайней мере, какое-то время; я понимаю, что вышеупомянутое не связано с простоем, но меня может возникнуть соблазн попробовать другие решения) и 2) когда произойдёт следующее изменение:

на 3.13.15, и базовый образ Discourse унаследует те же требования к микроархитектуре процессора, то текущий сервер всё равно станет непригодным для использования (если только не найдётся способ обойти это ограничение, например, установкой gem отдельно, скажем, в рамках предкомпиляционного хука, но я также предполагаю, что для большинства людей это будет довольно хлопотно).

Это также поднимает вопрос о том, какой должна быть разумная дата прекращения поддержки оборудования; ожидать поддержки 32-битных процессоров уже неразумно, поэтому, возможно, SSE4.2 станет разумным «новым минимумом» для современного программного обеспечения.

Действительно, я уже поднял этот вопрос внутри компании.

:+1:

Привет!

Спасибо, что уделили внимание этому вопросу. У меня возникает та же проблема на процессоре Intel Atom N2800 (конец 2011 года).
Как вы думаете, есть ли способ обойти эту проблему, или пока единственное решение — перейти на новое оборудование?

Спасибо,

Теперь мой форум полностью обездвижен после обновления, которое мне предложили сегодня. Я не видел никаких предупреждений о грядущем устаревании каких-либо процессоров, и то, что это произошло внезапно, — это… плохо. Все доступные серверы имеют одинаковую конфигурацию для обеспечения согласованности и используют один и тот же процессор.

AMD Athlon™ II X2 B22 Processor

Непрактично бегать и покупать новый сервер, настраивать его и т. д. в нынешней экономической ситуации, даже если бы было время.

Как я могу откатить это обновление, пока ситуация не станет более понятной? Я даже не могу связаться с пользователями прямо сейчас, так как форум не работает. Спасибо.

Если вы используете метод развёртывания через Docker, у вас может быть старый контейнер, который можно перезапустить (проверьте, например, docker images и/или docker ps -a).

Также вы можете переопределить коммит, использованный для сборки экземпляра Discourse, отредактировав файл app.yml и установив версию на коммит, предшествующий изменению, а затем пересобрав:

params:
  version: adb7fa5e2fc51308efc9fc4ee57ecb1c15a85cfa

Discourse снова сломается, если вы обновитесь после этого, что не идеально, учитывая обновление безопасности, выпущенное с тех пор (хотя потенциал эксплуатации для большинства экземпляров кажется довольно ограниченным).

Один из вариантов (который я ещё не пробовал) — установить gem oj отдельно и надеяться, что компиляция запустится с правильными возможностями процессора (или без них).

Я планировал попробовать это в app.yml:

hooks:
  before_code:
    - exec:
        cmd:
          - gem install oj

но у меня нет возможности позволить себе ещё одно простое время простоя форума.

Мне кажется, что это конкретное обновление безопасности не имеет отношения к моей ситуации, так как я не использую среду совместного хостинга. Я не совсем уверен, как интерпретировать информацию о Docker. Вот вывод команды ps:

37c258b23221 local_discourse/app “/sbin/boot” 3 месяца назад Завершено (7) 3 часа назад

А вот список образов:

REPOSITORY            TAG                 IMAGE ID       СОЗДАН         РАЗМЕР
discourse/base        2.0.20220621-0049   a44ca4f67972   3 недели назад     2.65GB
local_discourse/app   latest              b5f2a8a39709   3 месяца назад    3.53GB
discourse/base        2.0.20220413-0411   ab71a5d97460   3 месяца назад    2.81GB
<none>                <none>              58ba7d1c8d7a   3 месяца назад    3.74GB
discourse/base        2.0.20220224-2005   cd112601450a   4 месяца назад    2.84GB
<none>                <none>              d9cf1feb92fd   6 месяцев назад    3.19GB
<none>                <none>              d53ee33f6fe1   6 месяцев назад    3.19GB
<none>                <none>              14f79500c49c   6 месяцев назад    3.19GB
<none>                <none>              edff9b614f46   6 месяцев назад    3.19GB
<none>                <none>              e2348b41f937   6 месяцев назад    3.19GB
<none>                <none>              42f6511b414c   6 месяцев назад    3.19GB
<none>                <none>              3086f92af2fe   6 месяцев назад    3.19GB
<none>                <none>              6ada029723ba   6 месяцев назад    3.19GB
<none>                <none>              ca61149580d4   6 месяцев назад    3.19GB
<none>                <none>              ce5ae3bb62ac   6 месяцев назад    3.19GB
<none>                <none>              e9a5c1b1aed4   6 месяцев назад    3.19GB
<none>                <none>              6bb94ce1e01f   6 месяцев назад    3.19GB
<none>                <none>              e1df4acbd927   6 месяцев назад    3.19GB
<none>                <none>              7e05a0b160c5   6 месяцев назад    3.19GB
<none>                <none>              979926f28a73   6 месяцев назад    3.19GB
<none>                <none>              d055f9b01556   6 месяцев назад    3.19GB
<none>                <none>              aa0c779093dc   6 месяцев назад    3.19GB
discourse/base        2.0.20211118-0105   b6cc7cf8974a   7 месяцев назад    2.58GB
discourse/base        2.0.20210528-1735   482386bf57af   13 месяцев назад   2.36GB
<none>                <none>              e6011d2b206c   14 месяцев назад   2.69GB
discourse/base        2.0.20210415-1332   30e4746e631e   15 месяцев назад   2.23GB
<none>                <none>              8066ac13b8c3   17 месяцев назад   2.45GB
discourse/base        2.0.20201221-2020   c0704d4ce2b4   18 месяцев назад   2.11GB
<none>                <none>              043da6b3335d   2 года назад     2.4GB
discourse/base        2.0.20200429-2110   dc919e1dae2c   2 года назад     2.13GB
<none>                <none>              ff15472f4794   2 года назад     2.79GB
discourse/base        2.0.20191013-2320   09725007dc9e   2 года назад     2.3GB
<none>                <none>              f65391a062f0   2 года назад     2.62GB
discourse/base        2.0.20190901-2315   10f636afbeaf   2 года назад     2.29GB
<none>                <none>              6944d06786b4   2 года назад     2.31GB
discourse/base        2.0.20190625-0946   2b3a5b47565f   3 года назад     1.93GB
<none>                <none>              60b39deba7d2   3 года назад     2.3GB
discourse/base        2.0.20190505-2322   ed87227f60d2   3 года назад     1.91GB
<none>                <none>              cc5c0e56298c   3 года назад     2.38GB
discourse/base        2.0.20190321-0122   7db99586b5b5   3 года назад     1.97GB
<none>                <none>              b19f9a483788   3 года назад     2.27GB
discourse/base        2.0.20190217        9c24db193c37   3 года назад     1.92GB
hello-world           latest              fce289e99eb9   3 года назад     1.84kB
<none>                <none>              614db6988e9c   3 года назад     2.25GB
<none>                <none>              729b196da862   3 года назад     2.25GB
<none>                <none>              80584ec5ec01   3 года назад     2.25GB
<none>                <none>              0e2481aefed8   3 года назад     2.25GB
<none>                <none>              725d0c17a6bb   3 года назад     2.25GB
<none>                <none>              220bed95d236   3 года назад     2.25GB
<none>                <none>              fca469dba597   3 года назад     2.25GB
<none>                <none>              edab31d0ffce   3 года назад     2.25GB
<none>                <none>              dbacaff2d35e   3 года назад     2.25GB
<none>                <none>              3d6a0453da1d   3 года назад     2.25GB
<none>                <none>              fbf0529eb303   3 года назад     2.25GB
<none>                <none>              7a45443ae44c   3 года назад     2.25GB
<none>                <none>              ad90d7f42416   3 года назад     2.25GB
<none>                <none>              d61ea07d6084   3 года назад     2.25GB
<none>                <none>              d393fd8b4de0   3 года назад     2.25GB
discourse/base        2.0.20181031        ea31cd77735a   3 года назад     1.88GB


Можете попробовать ./launcher start app?