Modern QA2026Анализ коренных причин
Join

Course24 Technical Writing for QA

Foundations · Chapter 24

Анализ коренных причин

Updated Jul 2026

Поиск настоящей причины, а не очевидной

Анализ коренных причин (RCA), который останавливается на первом правдоподобном объяснении, — это не анализ, а догадка. Цель RCA — не найти виноватого или что-то залатать. Цель — понять, почему система позволила произойти сбою, и изменить систему так, чтобы подобные сбои не могли повториться. Разница между командой, у которой постоянно повторяются одни и те же типы инцидентов, и командой, которая действительно улучшается, заключается в качестве их анализа коренных причин.

Фреймворки RCA

Метод «5 Почему»

Простейшая и наиболее широко используемая техника RCA. Начните с проблемы и спрашивайте «почему» повторно, пока не дойдёте до коренной причины, которая является системной, а не симптоматической.

Пример: Продакшен-сбой из-за исчерпания пула соединений с базой данных

Уровень Вопрос Ответ
Проблема Почему приложение упало? Пул соединений с базой данных был исчерпан
Почему 1 Почему пул соединений был исчерпан? Медленный запрос удерживал соединения более 30 секунд
Почему 2 Почему запрос был медленным? Запрос выполнял полный скан таблицы с 50 миллионами строк
Почему 3 Почему был полный скан таблицы? В запросе отсутствовал индекс на колонке created_at
Почему 4 Почему индекс отсутствовал? Миграция, которая должна была добавить индекс, завершилась с ошибкой молча
Почему 5 Почему миграция завершилась молча? Наш инструмент запуска миграций не создаёт алерты при сбоях; он пишет в лог, который никто не мониторит

Коренная причина: Сбои миграций не мониторятся и не создают алерты. Способствующая причина: Нет тестирования производительности запросов, которое ловит медленные запросы до продакшена.

Корректирующие действия:

  1. Добавить алертинг для сбоев миграций (предотвращает этот класс проблем)
  2. Добавить отсутствующий индекс (исправляет конкретную проблему)
  3. Добавить тестирование производительности запросов в CI-пайплайн (ловит медленные запросы раньше)

Типичные ошибки с методом «5 Почему»:

Ошибка Проблема Исправление
Остановка слишком рано «Запрос был медленным» — это симптом, не коренная причина Продолжайте спрашивать «почему» до тех пор, пока не дойдёте до сбоя процесса или системы
Только одна цепочка Сложные инциденты имеют несколько способствующих причин Спрашивайте «почему» от нескольких начальных точек
Приход к человеку «Потому что Алиса не добавила индекс» обвиняет человека, а не систему Спросите, почему система позволила этому произойти
Слишком абстрактно «Потому что наш процесс плохой» слишком расплывчато для действий Будьте конкретны: какой процесс, какой пробел, какое изменение

Диаграмма Исикавы (рыбья кость)

Диаграмма рыбьей кости организует потенциальные причины по категориям, что полезно для сложных инцидентов с множеством способствующих факторов.

                           ┌── Process ──────┐
                           │  No migration    │
                           │  monitoring      │
                           │                  │
              ┌── People ──┤   ┌── Tools ────┤
              │  No query  │   │  No slow     │
              │  review    │   │  query       │
              │  process   │   │  detection   │
              │            │   │              │
Problem: ─────┤            ├───┤              ├───→ Database
Database      │            │   │              │     Outage
Outage        │            │   │              │
              │            │   │              │
              └── Env ─────┤   └── Testing ──┤
                 Staging DB│      No load     │
                 has 1K    │      testing     │
                 rows, not │      with        │
                 50M       │      production  │
                           │      data        │
                           │      volumes     │
                           └─────────────────┘

Стандартные категории диаграммы рыбьей кости (6 М):

  • Methods (Методы): Процессы, процедуры, политики
  • Machines (Оборудование): Инструменты, инфраструктура, среды
  • Materials (Материалы): Данные, входные данные, зависимости
  • Measurements (Измерения): Мониторинг, алертинг, метрики
  • Manpower (Кадры): Навыки, обучение, штат
  • Mother Nature (Внешние факторы): Внешние факторы, сторонние сервисы

Анализ дерева отказов

Анализ дерева отказов работает в обратном направлении от сбоя, используя булеву логику (вентили AND/OR) для определения всех возможных комбинаций причин.

                    Database Outage
                          |
                         AND
                    /           \
          Slow Query          No Connection
          Exists              Pool Recovery
            |                      |
           OR                     AND
         /    \              /          \
   Missing   Unoptimized   No pool     No timeout
   index     query plan    monitoring  configured

Когда использовать анализ дерева отказов: Сложные, критически важные для безопасности системы, где нужно понимать все возможные пути отказа. Распространён в авиации, медицинских устройствах и ядерных системах. Менее распространён в веб-приложениях, но ценен для критической инфраструктуры.

Написание отчётов RCA

Шаблон отчёта RCA

# Root Cause Analysis: [Incident Title]
Date: [Date of incident]
Author: [Name]
Severity: [Sev-1 / Sev-2 / Sev-3]
Status: [Draft / In Review / Final]

## Summary
One paragraph: what happened, when, how long it lasted, what was affected.

## Timeline

| Time (UTC) | Event |
|---|---|
| 14:00 | Monitoring alert: database connection pool at 90% |
| 14:05 | On-call engineer acknowledged alert |
| 14:12 | Database connection pool exhausted; application returning 503 |
| 14:15 | Incident declared; war room opened |
| 14:25 | Slow query identified via database monitoring |
| 14:30 | Query killed manually; connections began recovering |
| 14:35 | Application fully recovered |
| 14:40 | Root cause identified: missing index on orders.created_at |
| 14:45 | Index added to production database |
| 15:00 | Monitoring confirmed stable; incident resolved |

## Impact
- Duration: 23 minutes (14:12 - 14:35)
- Users affected: approximately 3,200 (all users attempting checkout)
- Revenue impact: estimated $8,500 in lost transactions
- Support tickets: 47

## Root Cause
The migration that should have added an index to the `orders.created_at`
column failed silently during the v2.3.0 deployment (2 weeks prior).
Without the index, a new report query introduced in v2.4.0 performed a
full table scan on 50 million rows, consuming database connections
for 30+ seconds each.

## Contributing Factors
1. **Migration monitoring gap:** Migration failures log to a file but
   do not trigger alerts. The team was unaware of the failed migration.
2. **No query performance testing:** The CI pipeline does not test
   query performance against production-scale data volumes.
3. **Staging data mismatch:** Staging has 1,000 rows in the orders
   table; production has 50 million. The query performed well in staging.
4. **No connection pool circuit breaker:** When the pool fills, the
   application queues requests indefinitely instead of failing fast.

## Corrective Actions

| Action | Owner | Priority | Due Date | Status |
|---|---|---|---|---|
| Add alerting for migration failures | DevOps | P1 | 2026-02-21 | In progress |
| Add query performance tests to CI | QA | P2 | 2026-03-07 | Not started |
| Configure connection pool circuit breaker | Backend | P2 | 2026-03-07 | Not started |
| Create staging data seeding script (production-scale) | QA + DevOps | P3 | 2026-03-21 | Not started |
| Add slow query monitoring dashboard | DevOps | P2 | 2026-02-28 | Not started |

## Lessons Learned
- Silent failures are the most dangerous kind. If something can fail,
  the failure must be visible.
- Testing against unrealistic data volumes gives false confidence.
- Connection pool exhaustion cascades: one slow query can take down
  the entire application. Defense in depth (circuit breakers,
  timeouts, connection limits) is essential.

Безобвинительные пост-мортемы

Язык, фокусирующийся на системах, а не на людях

Единственный наиболее важный принцип безобвинительных пост-мортемов: люди не вызывают инциденты; системы позволяют инцидентам произойти. Когда кто-то совершает ошибку, вопрос не «почему он это сделал?», а «почему система сделала эту ошибку лёгкой для совершения и трудной для обнаружения?»

Обвинительный язык Безобвинительный язык
«Алиса забыла добавить индекс» «Миграция, которая должна была добавить индекс, завершилась молча с ошибкой»
«Боб задеплоил без тестирования» «Процесс развёртывания не включал обязательный шаг верификации тестами»
«Разработчик написал плохой запрос» «Запрос не был протестирован на объёмах данных масштаба продакшена»
«QA пропустило этот баг» «Наше тестовое покрытие не включало этот сценарий»
«Дежурный инженер медленно отреагировал» «Маршрутизация алертов не доставила оповещение на телефон дежурного инженера»

Как вести безобвинительный пост-мортем

  1. Задайте тон в начале. «Эта встреча посвящена обучению и улучшению, а не назначению виноватых. Мы предполагаем, что все участники принимали лучшие решения, которые могли, с той информацией, которую имели.»
  2. Фокусируйтесь на хронологии. Пройдите по событиям в хронологическом порядке. Сначала факты, потом анализ.
  3. Спрашивайте «что» и «как», а не «кто». «Что сделало возможным, чтобы это произошло?», а не «Кто это вызвал?»
  4. Отмечайте реагирование. Признайте, что прошло хорошо во время реагирования на инцидент, а не только что пошло не так.
  5. Завершайте действиями, а не оценками. Каждое корректирующее действие должно менять систему или процесс, а не наказывать человека.

Отслеживание корректирующих действий до завершения

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

Система отслеживания

  • Создайте тикеты для каждого корректирующего действия в той же системе, где отслеживается работа по разработке (Jira, Linear, GitHub Issues). Если этого нет в бэклоге, это не будет сделано.
  • Назначьте владельца и дедлайн. «Команда это исправит» означает, что никто это не исправит.
  • Еженедельно проверяйте прогресс на стендапе или на выделенной 15-минутной встрече.
  • Закрывайте RCA только когда все действия выполнены (или явно депроиритизированы с задокументированным обоснованием).

Категории корректирующих действий

Категория Описание Пример
Немедленное исправление Исправляет конкретную проблему, вызвавшую этот инцидент Добавить отсутствующий индекс в базе данных
Улучшение обнаружения Делает подобные проблемы видимыми раньше Добавить алертинг на сбои миграций
Предотвращение Изменяет систему так, чтобы этот класс проблем не мог возникнуть Добавить тесты производительности запросов в CI
Изменение процесса Обновляет процедуру для предотвращения повторения Добавить обязательное ревью медленных запросов для новых запросов
Документация Фиксирует знания для будущего справочника Задокументировать лимиты пула соединений и конфигурацию circuit breaker

Шаблоны RCA с примерами из практики

Пример 1: Продакшен-сбой (Электронная коммерция)

Инцидент: Поток оформления заказа возвращал ошибки 500 в течение 45 минут во время Black Friday.

Коренная причина: Сторонний API платежей изменил лимит запросов с 1,000 до 500 запросов в минуту без уведомления. Приложение не обрабатывало ограничение скорости корректно.

Корректирующие действия:

  1. Добавить обработку ограничения скорости с экспоненциальной задержкой
  2. Реализовать очередь запросов с переливом к альтернативному платёжному провайдеру
  3. Добавить мониторинг и алертинг по лимитам запросов
  4. Согласовать контрактные гарантии лимитов запросов с платёжным провайдером

Пример 2: Утечка данных (SaaS-платформа)

Инцидент: Данные клиентов были доступны через API-эндпоинт без аутентификации.

Коренная причина: Новый API-эндпоинт был добавлен без middleware аутентификации. Код-ревью не поймало это, потому что ревьюер не знал о требовании аутентификации для API-маршрутов.

Корректирующие действия:

  1. Добавить автоматическое сканирование безопасности, отмечающее неаутентифицированные эндпоинты
  2. Обновить чек-лист код-ревью, включив проверку аутентификации
  3. Добавить интеграционные тесты, проверяющие, что все API-эндпоинты требуют аутентификации
  4. Внедрить default-deny: все новые эндпоинты требуют аутентификации, если явно не помечены как публичные

Пример 3: Деградация производительности (Мобильное приложение)

Инцидент: Время запуска приложения деградировало с 2 до 8 секунд за период 3 недели.

Коренная причина: Был добавлен новый SDK аналитики, который выполнял синхронные сетевые вызовы при инициализации приложения. Регрессия производительности была постепенной (добавлена в 3 PR) и оказалась ниже порога любого отдельного теста производительности.

Корректирующие действия:

  1. Добавить бюджет производительности времени запуска в CI (падение, если запуск превышает 3 секунды)
  2. Требовать асинхронную инициализацию для всех сторонних SDK
  3. Добавить мониторинг тренда производительности, обнаруживающий постепенную деградацию
  4. Провести аудит всех существующих инициализаций SDK на синхронные вызовы

Типичные антипаттерны в RCA

Антипаттерн Проблема Лучший подход
Остановка на первом «почему» Исправляется симптом; коренная причина остаётся Продолжайте спрашивать, пока не дойдёте до системной причины
Перекладывание вины «API вендора был плохим» — уход от вопроса, почему у вас не было резервного плана Спросите, почему ваша система была хрупкой к сбою вендора
Исправление симптомов, а не причин Добавление временного исправления без устранения причины его необходимости Исправьте и непосредственную проблему, и системную причину
Паралич анализа Недели на RCA, пока корректирующие действия ждут Ограничьте анализ по времени; внедрите очевидные исправления немедленно
Копипаст RCA Использование одного и того же типового шаблона без адаптации к инциденту Каждый RCA должен быть конкретным, детальным и действенным
Отсутствие доведения до конца Написание отличного RCA и неисполнение действий Отслеживайте действия в бэклоге спринта с владельцами и датами
Героизация «Алиса спасла нас, найдя исправление в 3 ночи» нормализует героизм Спросите, почему система потребовала героизма вместо изящной обработки

Превращение RCA в действия: от анализа к предотвращению

Мерило хорошего RCA — не качество анализа. Это то, прекратил ли такой же тип инцидентов происходить.

Иерархия предотвращения

  1. Устранить: Полностью убрать возможность сбоя (лучший вариант, но часто невозможный)
  2. Автоматизировать обнаружение: Поймать проблему до попадания в продакшен (проверки в CI, автоматические сканы)
  3. Ограничить зону поражения: Если сбой произойдёт, ограничить его влияние (circuit breakers, feature flags, канареечные развёртывания)
  4. Ускорить восстановление: Упростить обнаружение и быстрое восстановление после сбоя (мониторинг, runbooks, автоматический откат)
  5. Задокументировать: Как минимум, задокументировать сбой, чтобы будущие команды могли его распознать (худший вариант, но лучше, чем ничего)

Всегда стремитесь к наивысшему возможному уровню. Если вы можете только задокументировать, ваш RCA не зашёл достаточно далеко.

Практическое упражнение

  1. Возьмите недавний продакшен-инцидент и напишите полный отчёт RCA, используя шаблон выше
  2. Потренируйте технику «5 Почему» на недавнем баге. Вы дошли до системной коренной причины или остановились на симптоме?
  3. Просмотрите прошлый RCA вашей команды. Реализованы ли корректирующие действия? Если нет, почему?
  4. Перепишите прошлый отчёт об инциденте, убрав любой обвинительный язык, используя примеры безобвинительного языка
  5. Создайте диаграмму рыбьей кости для сложного инцидента, категоризируя причины по 6 М