АйТи Фреш
Главная / Статьи / 1С и базы данных
1С и базы данных

Включил idle_replication_slot_timeout в PostgreSQL 18, а WAL всё равно растёт

Автор: Семёнов Евгений Сергеевич, директор ООО «АйТи-Фреш» · · ~22 мин чтения
Включил idle_replication_slot_timeout в PostgreSQL 18, а WAL всё равно растёт
Иллюстрация к статье «Включил idle_replication_slot_timeout в PostgreSQL 18, а WAL всё равно растёт».

«Обновились на PostgreSQL 18, включили idle_replication_slot_timeout, а pg_wal как ел диск, так и ест». Разбираю, почему таймер простоя не является ограничителем места, чем неактивный слот отличается от отстающего, как читать pg_replication_slots и какой параметр ограничивает WAL, удерживаемый слотами. Внутри — разбор стенда типографии «Печатный дом», 32 рабочих места, проверенные запросы и пороги мониторинга.

Слот бывает неактивным, а бывает отстающим — это разные состояния

Звонок в среду вечером: на primary осталось 6 % свободного места, каталог pg_wal занял 340 ГБ и продолжал расти. Администратор клиента ещё в понедельник добавил в postgresql.conf значение idle_replication_slot_timeout, увидел строку в файле и решил, что вопрос закрыт. Слот не двигался, WAL копился, а параметр казался сломанным. На самом деле он решает другую задачу: удаляет по таймауту именно неактивные слоты, а не ограничивает их отставание в байтах.

В документации PostgreSQL 18 слово inactive определено вполне строго: слот не используется подключением репликации. Важен сам факт replication connection. Если потребитель подключён, но обрабатывает поток медленнее, чем primary генерирует WAL, слот остаётся активным. Объём отставания, скорость декодирования и свободное место файловой системы для idle-таймера значения не имеют.

Поэтому я сначала развожу три ситуации, которые в аварийном чате обычно называют одним словом «висит». Первая: к слоту никто не подключён, active имеет значение false, active_pid пуст, а inactive_since содержит время перехода в неактивное состояние. Вторая: соединение есть, но новых изменений почти нет; слот активен, и большой объём WAL сам по себе не образуется. Третья: соединение есть, однако потребитель не успевает подтверждать обработку данных; active остаётся true, а restart_lsn всё дальше отстаёт от текущего LSN.

Именно третий случай чаще всего заполняет диски на системах с CDC. Его можно получить с Debezium, встроенной логической репликацией или собственным потребителем. Пока walsender использует слот, inactive_since равен NULL. Отсчёт простоя не начинается, поэтому idle_replication_slot_timeout такой слот не инвалидирует — даже если отставание измеряется сотнями гигабайт.

Есть ещё полезное различие: active показывает использование слота сейчас, а restart_lsn — самую старую позицию WAL, которая ещё может понадобиться этому слоту. Для логического слота confirmed_flush_lsn показывает позицию, получение которой подтвердил потребитель. Эти поля отвечают на разные вопросы, и одно нельзя подменять другим.

Если pg_wal растёт при active = true, настройка idle_replication_slot_timeout проблему не решит. Проверяйте расстояние от текущего LSN до restart_lsn, состояние потребителя и свободное место файловой системы.
Памятка: Слот бывает неактивным, а бывает отстающим — это разные состояния — схема
Памятка: Слот бывает неактивным, а бывает отстающим — это разные состояния. Открыть схему в полном размере

Как работает таймаут: секунды, reload, checkpoint и inactive_since

В PostgreSQL 18 значение idle_replication_slot_timeout по умолчанию равно 0, то есть автоматическая инвалидация по простою выключена. Значение без единицы трактуется как секунды. Я всё равно указываю единицу явно: запись 24h читается однозначнее, чем 86400, особенно когда конфигурацию через несколько месяцев открывает другой инженер.

Параметр задаётся в postgresql.conf или в командной строке сервера. Он имеет контекст SIGHUP, поэтому перезапуск PostgreSQL не требуется. Важно править именно активный файл конфигурации: его путь лучше получить у самого сервера, потому что config_file может указывать не на файл в каталоге данных. Перечитать конфигурацию можно через pg_ctl или функцией pg_reload_conf(), для которой по умолчанию требуются права суперпользователя либо отдельно выданный EXECUTE.

# Активный postgresql.conf
idle_replication_slot_timeout = 24h  # значение 0 по умолчанию отключает механизм
max_slot_wal_keep_size = -1          # -1 по умолчанию: лимита удержания слотами нет
checkpoint_timeout = 5min            # значение PostgreSQL по умолчанию
SHOW config_file;
SELECT pg_reload_conf();
SHOW idle_replication_slot_timeout;
SHOW max_slot_wal_keep_size;
SHOW checkpoint_timeout;
pg_ctl reload

После reload я не ограничиваюсь результатом pg_reload_conf(). Значение true говорит, что сигнал отправлен, но не доказывает отсутствие ошибки в файле. Фактическое значение проверяю через SHOW, а ошибки разбора — через журнал сервера и представление pg_file_settings. Если в файле опечатка или недопустимое значение, PostgreSQL при SIGHUP оставит прежнюю настройку и запишет проблему в лог.

Инвалидация происходит во время checkpoint, а не отдельным таймерным процессом в момент истечения срока. Поэтому между достижением лимита и изменением состояния слота есть задержка до следующего checkpoint. checkpoint_timeout задаёт максимальный интервал между автоматическими checkpoints и по умолчанию равен 5min; допустимый диапазон в PostgreSQL 18 — от 30 секунд до одного дня. Checkpoint также может начаться раньше по другим причинам.

Для проверки можно принудительно вызвать checkpoint, но я не превращаю это в штатную периодическую команду: CHECKPOINT вызывает немедленный сброс данных и может создать заметный всплеск I/O. Выполнять его может суперпользователь или участник предопределённой роли pg_checkpoint.

CHECKPOINT;

Возраст простоя берётся из pg_replication_slots.inactive_since. Механизм не применяется к слотам, которые не резервируют WAL, и к синхронизируемым с primary слотам на standby, у которых synced имеет значение true. Такие synchronized slots считаются неактивными, потому что не выполняют логическое декодирование на standby; применение обычного idle-таймаута сломало бы их назначение.

Отдельная ловушка осталась в истории PostgreSQL 18 beta. Изначально базовой единицей параметра были минуты. В июле 2025 года пользователь сообщил, что тестовое значение 30s округлялось до нуля и фактически отключало механизм. До финального релиза единицу изменили на секунды. В выпущенном PostgreSQL 18 корректна именно секундная семантика; переносить поведение beta-сборок на релиз нельзя.

Наличие параметра в файле ничего не доказывает. Проверяйте активный config_file, результат разбора в pg_file_settings и фактическое значение, которое показывает сервер после reload.
Включил idle_replication_slot_timeout в PostgreSQL 18, а WAL всё равно растёт — схема
Схема к статье. Открыть схему в полном размере

Диагностика: что смотреть в pg_replication_slots

Когда место заканчивается, первым делом я снимаю состояние всех слотов одним запросом. Разность двух значений pg_lsn возвращает число байт между позициями. Это оценка диапазона WAL от restart_lsn до текущей позиции, а не точный размер файлов, физически лежащих в pg_wal: каталог может дополнительно содержать сегменты для checkpoint, архивирования, wal_keep_size и других нужд.

Запрос ниже предназначен для primary на PostgreSQL 18. Он не падает на слотах с restart_lsn или safe_wal_size, равными NULL, и явно отправляет такие restart_lsn в конец результата. Для логического слота полезно смотреть одновременно restart_lsn и confirmed_flush_lsn: второй показывает подтверждение потребителя, а первый определяет нижнюю границу WAL, который слот ещё может потребовать.

SELECT slot_name,
       slot_type,
       active,
       active_pid,
       restart_lsn,
       confirmed_flush_lsn,
       wal_status,
       invalidation_reason,
       synced,
       inactive_since,
       CASE
         WHEN restart_lsn IS NULL THEN NULL
         ELSE pg_size_pretty(pg_current_wal_lsn() - restart_lsn)
       END AS retained_from_restart,
       CASE
         WHEN safe_wal_size IS NULL THEN NULL
         ELSE pg_size_pretty(safe_wal_size)
       END AS safe_left
FROM pg_replication_slots
ORDER BY restart_lsn NULLS LAST;

Если active имеет значение false, я выясняю владельца слота и причину остановки потребителя. Если active равно true, связываю active_pid с pg_stat_replication или pg_stat_activity и проверяю, двигаются ли LSN во времени. Один снимок показывает размер отставания, но не скорость: два или три измерения с интервалом позволяют понять, догоняет потребитель primary или разрыв увеличивается.

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

Размер самого каталога лучше контролировать средствами операционной системы либо функцией pg_ls_waldir(), доступной суперпользователю и участникам pg_monitor. При этом сумма разностей LSN по слотам не равна размеру pg_wal: несколько слотов могут удерживать один и тот же диапазон сегментов. Для оценки общей причины важнее самый старый restart_lsn, а не сумма retained по строкам.

Не складывайте retained по всем слотам: один WAL-сегмент может одновременно удерживаться несколькими слотами. Ищите самый старый restart_lsn и сопоставляйте его с реальным размером pg_wal.

Разбор: типография «Печатный дом», 32 рабочих места

Исходные данные: типография «Печатный дом», 32 рабочих места, учётная система, склад и внутренний портал. PostgreSQL 18 работал на Debian 13 в виртуальной машине с 8 vCPU и 48 ГБ RAM. Том с данными имел объём 1,2 ТБ, а pg_wal находился на той же файловой системе. Было три слота: physical для горячего standby, logical debezium_prod для передачи изменений в аналитику и logical bi_export — остаток закрытого полгода назад пилота BI.

За 11 дней pg_wal вырос с 12 до 340 ГБ. Администратор записал таймаут 3600 секунд, подождал сутки и передал задачу нам. По снимку pg_replication_slots стало видно, что bi_export неактивен с 14 марта и удерживает диапазон около 318 ГБ. У активного debezium_prod отставание составляло 21 ГБ, у физического standby — около 900 МБ. Округлённо забытый bi_export объяснял 94 % занятого диапазона.

Причин, по которым ожидаемая уборка не произошла, оказалось две. Во-первых, файл изменили, но конфигурацию не перечитали: фактическое значение idle_replication_slot_timeout оставалось равным 0. Во-вторых, первоначальную проверку сделали через 15 минут при checkpoint_timeout, настроенном на 30min. Даже после корректного reload PostgreSQL не обязан инвалидировать слот до следующего checkpoint.

После проверки владельца мы перечитали конфигурацию, убедились, что сервер принял ненулевой таймаут, и в согласованное окно выполнили принудительный checkpoint. У bi_export появился invalidation_reason со значением idle_timeout, а слот стал непригоден для использования. По мере последующего удаления или переработки ненужных WAL-сегментов размер pg_wal снизился с 340 до 26 ГБ примерно за 40 минут. Эти 40 минут — наблюдение конкретного стенда, а не обещанный PostgreSQL срок освобождения места.

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

SELECT pg_drop_replication_slot('bi_export');

Глобальное значение таймаута после инцидента увеличили до рабочего окна, принятого для всех потребителей. У параметра нет настройки на отдельный слот: нельзя включить его для bi_export и одновременно исключить debezium_prod. Пока debezium_prod подключён, таймаут его не касается; если он отключится дольше общего лимита, слот также будет инвалидирован.

Для pg_wal выделили отдельный том на 200 ГБ и настроили контроль свободного места. Это полезная изоляция I/O и защита основной файловой системы от разрастания WAL, но не способ сохранить работу PostgreSQL при заполнении самого WAL-тома. Официальная документация прямо предупреждает: если файловая система с WAL заполнится, возможны PANIC и последующая остановка сервера. Поэтому отдельный том работает только вместе с алертами, резервом ёмкости и ограничением причин роста.

Отдельный том под pg_wal не превращает остановку базы в безобидное отставание интеграции. Он изолирует место и нагрузку, но заполнение WAL-тома всё равно может привести к PANIC и shutdown.
Цифры и версии: Разбор: типография «Печатный дом», 32 рабочих места — схема
Цифры и версии: Разбор: типография «Печатный дом», 32 рабочих места. Открыть схему в полном размере

Что ограничивает удержание слотами: max_slot_wal_keep_size

Если задача звучит как «не позволить слотам бесконечно удерживать WAL», нужен max_slot_wal_keep_size. Он задаёт максимальный размер WAL-файлов, который replication slots разрешено удерживать в pg_wal во время checkpoint. Значение по умолчанию — -1, то есть ограничения нет. Если единица не указана, PostgreSQL трактует число как мегабайты. Параметр применяется после SIGHUP без перезапуска.

Это не жёсткая квота на весь каталог pg_wal. Параметр ограничивает только удержание, вызванное replication slots, и оценивается на checkpoint. Общий размер каталога может быть больше из-за интенсивной генерации WAL, checkpoint-цикла, wal_keep_size или неуспевающего архивирования. Кроме того, пересечение лимита не означает, что байты исчезнут в ту же миллисекунду.

Когда restart_lsn отстаёт от текущего LSN больше разрешённого размера, слот перестаёт гарантированно удерживать нужные сегменты. В pg_replication_slots он может перейти в состояние unreserved; часть WAL будет удалена на следующем checkpoint. Пока нужные файлы фактически не исчезли, состояние способно вернуться в reserved или extended. Состояние lost означает, что слот уже непригоден.

Поэтому фраза «при превышении лимита слот сразу становится lost» неточна. Между превышением, состоянием unreserved, удалением сегментов и окончательной потерей может быть больше одного checkpoint. На эту переходную фазу и должен реагировать мониторинг — до того, как потребитель запросит отсутствующий WAL.

SELECT slot_name,
       wal_status,
       invalidation_reason,
       CASE
         WHEN safe_wal_size IS NULL THEN NULL
         ELSE pg_size_pretty(safe_wal_size)
       END AS safe_left
FROM pg_replication_slots
ORDER BY safe_wal_size NULLS LAST;

safe_wal_size показывает, сколько байт можно записать в WAL до риска перехода слота в lost. Значение равно NULL для уже потерянного слота и при max_slot_wal_keep_size = -1. NULL в последнем случае не означает бесконечный физический диск — лишь отсутствие настроенного ограничения со стороны этого параметра.

Цена ограничения зависит от потребителя. Для логического слота удалённые WAL нельзя получить обратно простым переименованием или пересозданием слота. Debezium может потребовать контролируемую повторную инициализацию или snapshot в соответствии с его конфигурацией и сохранёнными offsets. Встроенную логическую подписку тоже приходится восстанавливать по процедуре, исключающей пропуск изменений. Для физического standby наличие полного и исправного WAL-архива иногда позволяет продолжить восстановление без новой base backup, но инвалидированный слот всё равно надо корректно заменить; без доступного WAL обычно требуется новая базовая копия.

Сам max_slot_wal_keep_size глобален для кластера, а не настраивается по слотам. Если одному потребителю допустимо отстать на 20 ГБ, а другому нужны 500 ГБ, единый кластерный лимит должен учитывать более требовательный сценарий. Иногда правильнее разделить интеграции, ускорить потребителя или обеспечить дополнительную ёмкость, чем ставить слишком маленький общий порог.

max_slot_wal_keep_size ограничивает удержание WAL слотами, а не весь pg_wal. Маленький лимит защищает ёмкость ценой возможной повторной инициализации потребителя; выставлять его без измерений нельзя.

Мониторинг PostgreSQL 18 и совместимость со старыми версиями

Оба механизма действуют отложенно, поэтому конфигурация без мониторинга оставляет дежурного в неведении до заполнения диска или остановки интеграции. На primary я снимаю состояние слотов, максимальный удерживаемый диапазон, возраст неактивности и фактический размер файловой системы. Для чтения системной статистики использую отдельную учётную запись с pg_monitor; права суперпользователя для обычного сбора метрик не нужны.

Для PostgreSQL 18 агрегированный запрос выглядит так. Фильтр restart_lsn IS NOT NULL не даёт слотам без зарезервированной позиции искажать расчёт. Отдельные строки по слотам всё равно сохраняю: агрегат нужен для триггера, а детализация — для расследования.

SELECT count(*) FILTER (
         WHERE wal_status IN ('unreserved', 'lost')
       ) AS danger_slots,
       count(*) FILTER (
         WHERE invalidation_reason IS NOT NULL
       ) AS invalidated_slots,
       coalesce(
         max(pg_current_wal_lsn() - restart_lsn)
           FILTER (WHERE restart_lsn IS NOT NULL),
         0
       ) AS max_retained_bytes,
       coalesce(
         max(extract(epoch FROM now() - inactive_since))
           FILTER (WHERE NOT active AND inactive_since IS NOT NULL),
         0
       )::bigint AS max_idle_sec
FROM pg_replication_slots;

На разноверсионном парке нельзя отправлять этот текст на PostgreSQL 14–16. Колонки inactive_since и invalidation_reason появились в PostgreSQL 17. Проверка версии внутри CASE не поможет: сервер разбирает имена колонок до выполнения выражения и завершит запрос ошибкой. Версию надо определить отдельным запросом, после чего система мониторинга выбирает подходящий заранее подготовленный SQL.

SELECT current_setting('server_version_num')::integer AS server_version_num;

Для PostgreSQL 14–16 оставляю совместимый вариант без отсутствующих колонок. Возраст простоя на этих версиях приходится получать из состояния внешнего потребителя, журналов или истории самого мониторинга: системное представление его не предоставляет.

SELECT count(*) FILTER (
         WHERE wal_status IN ('unreserved', 'lost')
       ) AS danger_slots,
       coalesce(
         max(pg_current_wal_lsn() - restart_lsn)
           FILTER (WHERE restart_lsn IS NOT NULL),
         0
       ) AS max_retained_bytes
FROM pg_replication_slots;

Порог по retained я связываю с ёмкостью и скоростью заполнения, а не с универсальным числом гигабайт. На стенде типографии первым уровнем служит снижение свободного места до 25 %, вторым — прогноз исчерпания раньше согласованного времени реакции. Для постоянно подключённых боевых слотов отдельно тревожит сам переход active из true в false; ожидание 24 часов здесь слишком медленное.

Состояние extended полезно как ранний сигнал, что слот уже удерживает WAL сверх обычного max_wal_size, но оно само по себе не означает близкий lost. Риск оцениваю по safe_wal_size и скорости генерации WAL. unreserved требует немедленного разбора, а lost и любое ненулевое invalidation_reason — это уже событие восстановления, а не обычный тренд.

Наконец, слоты — не единственная причина роста pg_wal. Я также проверяю pg_stat_archiver и журнал ошибок: неработающий archive_command или archive_library заставляет PostgreSQL накапливать готовые сегменты. max_wal_size является мягким, а не абсолютным пределом и может быть превышен при интенсивной нагрузке, проблемах архивации и других условиях.

Выбирайте версионный запрос до отправки SQL серверу. CASE с проверкой server_version_num не скрывает от парсера ссылку на отсутствующую колонку.

Как я настраиваю защиту: последовательность действий

Начинаю не с таймаута, а с инвентаризации. По каждому слоту должен быть владелец, назначение, допустимый простой и понятная процедура восстановления. Если владельца нет, слот не удаляю вслепую: сначала проверяю конфигурации подписок, Debezium и standby, затем согласую удаление. Автоматический таймер полезен как страховка от будущего мусора, но не заменяет этот реестр.

Следом считаю скорость генерации WAL и пиковое отставание хотя бы за 2–4 недели. Для короткого таймаута без статистики есть неприятный сценарий: обычное обслуживание потребителя или сетевая авария превращается в необратимую инвалидацию рабочего слота. Мои стартовые значения 24h для постоянно подключённых потребителей и 72h для ежедневных выгрузок — эксплуатационные ориентиры, а не рекомендации проекта PostgreSQL.

Лимит max_slot_wal_keep_size выбираю по реальному пику, времени реакции и скорости повторной инициализации. Запас в два-три раза над наблюдаемым пиком — удобная отправная точка, но не формула. Для источника на 800 ГБ новый snapshot может занять ночь, а последствия пропущенных событий — ещё дольше. Для маленькой базы восстановление дешевле, и ограничение можно сделать жёстче.

Отдельное размещение pg_wal имеет смысл для изоляции I/O и ёмкости. Официальная документация разрешает перенести каталог при остановленном сервере и оставить символическую ссылку из каталога данных. Я делаю это только в окне обслуживания, с проверенной резервной копией, корректными владельцем и правами, а после запуска проверяю запись WAL и мониторинг. Горячее перемещение работающего pg_wal недопустимо.

Архивирование WAL решает другую задачу. Исправный архив помогает физическому standby получить сегмент, которого уже нет на primary, и нужен для PITR. Он не отменяет необходимость следить за слотами и сам может стать причиной роста pg_wal, если archive_command или archive_library перестали успешно обрабатывать сегменты. Для потерянного логического слота архив не является кнопкой восстановления прежней позиции декодирования.

Подбирать checkpoint_timeout ради более быстрого idle-таймера обычно не стоит. Уменьшение интервала влияет на I/O и объём full-page images, а принудительный CHECKPOINT предназначен для административных случаев, не для постоянной уборки. Намного полезнее ранний сигнал о неактивном слоте и регламент реакции до истечения таймаута.

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

Порядок важнее красивых значений в postgresql.conf: сначала владельцы и наблюдаемость, затем таймаут, измерение лага и только после этого ограничение удержания.
Порядок действий: Как я настраиваю защиту: последовательность действий — схема
Порядок действий: Как я настраиваю защиту: последовательность действий. Открыть схему в полном размере

Частые вопросы

Почему слот не инвалидируется, хотя таймаут уже истёк?

Проверьте фактическое значение параметра после SIGHUP, а не только строку в файле. Затем посмотрите active: подключённый слот не считается неактивным, даже если сильно отстаёт. Инвалидация выполняется во время checkpoint. Наконец, механизм не применяется к слотам без резервирования WAL и к synced-слотам standby.

Освободит ли idle_replication_slot_timeout место на диске?

Только если WAL удерживает неактивный брошенный слот. Подключённого, но медленного потребителя таймер не затронет. Для ограничения удержания слотами применяется max_slot_wal_keep_size, однако и он не является квотой на весь pg_wal.

Нужен ли перезапуск PostgreSQL после изменения параметров?

Нет. idle_replication_slot_timeout и max_slot_wal_keep_size применяются после SIGHUP. Конфигурацию можно перечитать через pg_ctl reload либо pg_reload_conf(), если у вызывающей роли есть права. После этого проверьте фактические значения и ошибки pg_file_settings или журнала сервера.

Слот получил invalidation_reason = idle_timeout. Что делать?

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

Чем idle_replication_slot_timeout отличается от max_slot_wal_keep_size?

Первый смотрит на длительность отсутствия replication connection и инвалидирует неактивные слоты. Второй ограничивает объём WAL, удерживаемый слотами на checkpoint, поэтому способен затронуть и активного отстающего потребителя. Оба параметра глобальны для кластера.

Слот с wal_status = unreserved уже потерян?

Не обязательно. В этом состоянии слот больше не гарантирует удержание нужных файлов, и часть WAL должна быть удалена на следующем checkpoint, но состояние ещё может вернуться в reserved или extended, пока файлы доступны. lost означает окончательную непригодность.

Защитит ли отдельный том под pg_wal от остановки базы?

Нет. Отдельный носитель изолирует WAL от файловой системы с основными данными и может улучшить I/O, но при заполнении самого WAL-тома PostgreSQL способен завершиться с PANIC. Нужны мониторинг свободного места, контроль скорости заполнения и устранение причины удержания.

Какие значения ставить по умолчанию?

Универсального рабочего значения нет. На практике я начинаю с 24h для постоянно подключённых потребителей или 72h для ежедневных выгрузок, но сверяю это с допустимым временем простоя. max_slot_wal_keep_size задаю только после 2–4 недель наблюдений за лагом, с учётом скорости WAL, ёмкости диска и стоимости повторной инициализации.

Столкнулись с похожей задачей? Обращайтесь — решим

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

Возьмёмся и за разовую задачу, и за постоянное обслуживание. Первичная консультация — бесплатно и без обязательств.

📞 +7 903 729-62-41 💬 MAX: +7 903 729-62-41 ✈ Telegram @ITfresh_Boss

С уважением, Семёнов Евгений Сергеевич, директор «АйТи Фреш» — IT-аутсорсинг для компаний до 50 рабочих мест, 15+ лет практики

Источники

© ООО «АйТи-Фреш» · Москва · Все статьи