25.2.26

Как оптимизировать переключение реплик групп доступности SQL Server

Автор: Aaron Bertrand , Serializing Deletes From Clustered Columnstore Indexes

Мы часто выполняем плановые переключения реплик в группах доступности SQL Server для обслуживания, установки исправлений, обновлений и даже ротации оборудования. Обычно наши переключения выполняются быстро, но иногда они занимают больше времени — и не всегда интуитивно понятно почему, поскольку нет очевидной связи со временем суток, размером базы данных или объёмом транзакций.

Сокращение даже нескольких секунд из этого процесса может улучшить взаимодействие с приложением и конечным пользователем; это также может значительно снизить количество оповещений или, по крайней мере, сократить время, в течение которого оповещения должны быть отключены. Существует множество материалов о том, как правильно выполнять переключения в AG (без потери данных), но гораздо меньше тех, которые сосредоточены на сокращении окна прерывания доступности. Разница обычно заключается в некоторой комбинации объёма повторного выполнения (redo), поведения контрольных точек, открытых транзакций и готовности вторичной реплики.

Я хотел поделиться некоторыми методами, которые я использую, чтобы сделать плановые переключения более быстрыми и предсказуемыми. Некоторые из этих методов хорошо документированы, другие выпестованы из реальных шаблонов, которые я наблюдал во многих средах с SQL Server. Я расскажу о том, что я делаю до, во время и после переключения первичной реплики, чтобы минимизировать прерывания работы пользователей и повысить вероятность того, что они не заметят, что что-то произошло.

Как подготовиться к переключению роли в SQL Server: контрольный список

В моём контрольном списке перед переключением есть несколько пунктов, которые могут помочь со временем выполнения этих операций. Некоторые из них являются настройками конфигурации, которые устанавливаются один раз, а некоторые — задачами, выполняемыми однократно.

Разделите ваши группы доступности

Когда у нас были проблемы с переключением, одним из способствующих факторов было слишком много баз данных в AG (почти 400). Когда вы вручную одновременно переключаете реплику (failover) для  400 баз данных, вы создаёте большую нагрузку на будущую первичную реплику, и она не может обработать их все сразу. Базы данных, ожидающие перехода, находятся в подвешенном состоянии и только увеличивают окно прерывания.

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

Msg 35217, Severity 16, State 1
The thread pool for Always On Availability Groups was unable to start a new worker thread because
 there are not enough available worker threads. This may degrade Always On Availability Groups
performance. Use the "max worker threads" configuration option to increase number of allowable
threads.

Это не означает просто увеличить максимальное количество рабочих потоков (max worker threads), что может быть контрпродуктивно, если вы также не увеличите количество процессоров, способных справиться с работой, и каким-то образом не устраните всплески параллелизма.

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

Включите косвенные контрольные точки

Любая контрольная точка (CHECKPOINT) на первичной реплике может сократить время повторного выполнения (REDO), потому что у вторичной реплики будет меньше "грязных" страниц для восстановления. Это не означает, что я могу полностью исключить повторное выполнение, поскольку это зависит от отставания повторного выполнения и того, сколько журнала генерируется во время окна failover.

В зависимости от версии SQL Server и того, где были изначально созданы базы данных, они всё ещё могут быть настроены на использование контрольных точек старого образца. Более новый подход с использованием косвенных контрольных точек может иметь множество преимуществ для производительности, наиболее заметным из которых является более плавный шаблон ввода-вывода. Я рассказываю о некоторых преимуществах в статьях Why Enable SQL Server Indirect Checkpoints и "0 to 60": Switching to indirect checkpoints, и вы можете ознакомиться с объяснением Microsoft изменений в статье Changes in SQL Server 2016 Checkpoint Behavior.

Чтобы найти базы данных, использующие устаревшие контрольные точки:

SELECT name
FROM sys.databases
WHERE target_recovery_time_in_seconds = 0;

Чтобы исправить:

ALTER DATABASE <db name>
SET TARGET_RECOVERY_TIME = 60 SECONDS;

В современных версиях SQL Server я не нашёл убедительных причин сохранять устаревшее поведение контрольных точек.

DECLARE 
    @AGName sysname = N'<ag name>',
    @sql nvarchar(max);

SELECT 
    @sql = STRING_AGG(
        CONVERT(
            nvarchar(max),
            CONCAT(
                N'EXEC ', 
                QUOTENAME(name),
                N'.sys.sp_executesql N''CHECKPOINT'';'
            )
        ),
        CHAR(13) + CHAR(10)
    )
FROM 
    sys.databases AS d
WHERE 
    d.state = 0
    AND EXISTS (
        SELECT 1
        FROM 
            sys.dm_hadr_database_replica_states AS rs
            INNER JOIN sys.availability_groups AS ags
                ON rs.group_id = ags.group_id
        WHERE 
            rs.database_id = d.database_id
            AND ags.name = @AGName
            AND rs.is_local = 1
            AND rs.is_primary_replica = 1
    );

PRINT @sql;
/* EXEC sys.sp_executesql @sql; */

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

Кое-что, что я могу добавить в запрос, чтобы минимизировать разрывы, это ORDER BY для сортировки баз данных, чтобы самые загруженные базы данных выполнялись последними (по крайней мере, когда я знаю или трачу время на определение того, какие базы данных самые загруженные или имеют наибольший оборот страниц).

В нашей основной публичной системе не должно быть сюрпризов, какая база данных является нашей самой загруженной; я запускаю CHECKPOINT в цикле только для этой базы данных, каждые дюжину секунд или около того, вплоть до момента инициирования отказа. Но это в очень специфической, очень загруженной базе данных; когда объём "грязных" страниц уже низок, повторные контрольные точки могут давать убывающую отдачу и, как правило, просто перемещают работу, а не сокращают её.

Отключите долго выполняющиеся процессы

Failover не может завершиться, пока вторичная реплика не применит все записи журнала, отправленные с первичной через очередь отправки. Размер очереди отправки напрямую влияет на время отказа, как документирует Microsoft в статье Мониторинг производительности для групп доступности Always On – вместе с подробным списком операций в процессе синхронизации данных. Даже небольшое отставание замедляет восстановление; снижение числа интенсивных рабочих нагрузок перед failover позволяет очередям очиститься.

Мы отключаем наши задания по резервному копированию журнала незадолго до отказа, чтобы исключить дополнительную генерацию и перемещение журнала. Мы избегаем выполнения failover где-либо рядом с полными или дифференциальными резервными копиями (если они конфликтуют, мы переносим дату начала этих заданий на время, значительно превышающее ожидаемое окончание окна обслуживания). Мы также отключаем любые задания, которые, как известно, выполняют интенсивную запись или долго выполняющиеся транзакции – думайте о заданиях типа ETL и обслуживании индексов, – которые могут увеличить время отмены и повторного выполнения.

Рассмотрите возможность включения ускоренного восстановления базы данных (ADR)

Если вы читаете это сегодня, а ваш failover запланирован на сегодняшний вечер, для этого почти наверняка уже слишком поздно, но ускоренное восстановление базы данных (ADR) — это настройка, которую мы включили везде, и она помогла во многих аспектах – включая отсоединение времени восстановления от длины транзакции (я рассказываю о том, как это помогает, в статье Accelerated Database Recovery in SQL Server 2019).

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

Отключите маршрутизацию только для чтения

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

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

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

Прогрейте вторичную реплику

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

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

Ещё большее преимущество даёт заполнение буферного пула, чтобы пользователи обходили ожидания, связанные с вводом-выводом, пока эти страницы загружаются в память. Чтобы сделать это, я выполняю серию запросов, которые вызывают полное сканирование наших самых больших таблиц и наиболее часто используемых индексов. Мне нравится подход с COUNT_BIG(*), который заставляет выполнить полное сканирование индекса и минимизировать нагрузку на процессор на строку. Я видел в сети такие методы, как CHECKSUM_AGG(CHECKSUM(...)), которые, скорее всего, будут гораздо больше нагружать мои процессоры.

SELECT COUNT_BIG(*)
FROM dbo.<huge table> WITH (INDEX(1));

SELECT COUNT_BIG(*)
FROM <huge table> WITH (INDEX(<heavily used index>));

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

Обратите внимание, что эти параметры невозможны в сценарии обновления; вторичная реплика не будет доступна для чтения после обновления, но до того, как она станет первичной. Microsoft говорит: Доступны для чтения будут только реплики, находящиеся в одной основной сборке SQL Server. В этом сценарии я всё равно могу сделать это сразу после того, как она станет первичной; это, безусловно, лучше для конечного пользователя, если я возьму на себя некоторые из этих проблем с ресурсами вместо них.

Используйте флаги трассировки Query Store

Там, где я использую Query Store, есть два флага трассировки, которые могут помочь сократить время, затрачиваемое во время отказов, перезапусков служб и перезагрузок, особенно если Query Store большой.

1. TF 7745

Это предотвращает сброс данных Query Store на диск во время завершения работы базы данных (ценой потери любых данных, всё ещё находящихся только в памяти, что для меня приемлемо). Эрин Стеллато рассказывает об этом флаге трассировки в статье Query Store Best Practices.

2. TF 7752

До SQL Server 2019 поведением Query Store по умолчанию была синхронная загрузка, блокирующая запросы до полной загрузки (вы можете столкнуться с ожиданиями QDS_LOADDB при запуске). При этом флаге трассировки (и по умолчанию с SQL Server 2019, где флаг трассировки становится ненужным), Query Store загружается асинхронно и доступен только для чтения до завершения загрузки. Эрин также рассказывает об этом поведении как в вышеупомянутой статье, так и в Query Store Trace Flags.

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

Проверьте конфигурации

Перед отказом я убеждаюсь, что объекты на уровне сервера, такие как имена входа и связанные серверы, согласованы и функционируют правильно. Я проверяю, что задания агента SQL Server идентичны и, при необходимости, учитывают первичную/вторичную реплику. Если какие-либо из них настроены неправильно после отказа, они замедлят мою способность вернуться к 100% функциональности, и пользователи могут это заметить.

Проверьте потенциальное время повторного выполнения

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

/* run on primary */
DECLARE 
    @AGName nvarchar(128) = N'agname',
    @DBName nvarchar(128) = NULL;

WITH drs AS
(
    SELECT 
        ag = ag.name,
        [replica] = ar.replica_server_name,
        drs.*
    FROM 
        sys.dm_hadr_database_replica_states AS drs
        INNER JOIN sys.availability_replicas AS ar
            ON drs.replica_id = ar.replica_id
        INNER JOIN sys.availability_groups AS ag
            ON ar.group_id = ag.group_id
    WHERE 
        ag.name = COALESCE(@AGName, ag.name)
        AND drs.database_id = COALESCE(DB_ID(@DBName), drs.database_id)
),
pri AS
(
    SELECT 
        drs.database_id,
        drs.group_id,
        oldest_pri_tran = MIN(t.transaction_begin_time),
        last_pri_commit = MIN(drs.last_commit_time)
    FROM 
        drs
        OUTER APPLY
        (
            SELECT 
                db = dt.database_id,
                t.transaction_begin_time
            FROM 
                sys.dm_tran_database_transactions AS dt
                INNER JOIN sys.dm_tran_active_transactions AS t
                    ON dt.transaction_id = t.transaction_id
            WHERE 
                dt.database_id = drs.database_id
        ) AS t
    WHERE 
        drs.is_local = 1
        AND drs.is_primary_replica = 1
    GROUP BY 
        drs.database_id, 
        drs.group_id
)
SELECT 
    drs.ag,
    [replica] = drs.[replica],
    [database] = DB_NAME(pri.database_id),
    sync_state = drs.synchronization_state_desc,
    health = drs.synchronization_health_desc,
    [susp?] = drs.is_suspended,
    pri.oldest_pri_tran,
    pri.last_pri_commit,
    last_sec_commit = drs.last_commit_time,
    delta = DATEDIFF(MILLISECOND, drs.last_commit_time, pri.last_pri_commit),
    [lag] = drs.secondary_lag_seconds,
    send_kb = drs.log_send_queue_size,
    redo_kb = drs.redo_queue_size,
    drs.redo_rate,
    approx_redo_sec = CONVERT(
        decimal(19,2),
        drs.redo_queue_size * 1.0 / NULLIF(drs.redo_rate, 0)
    )
FROM 
    pri
    CROSS JOIN drs
WHERE 
    pri.group_id = drs.group_id
    AND drs.is_local = 0
    AND drs.is_primary_replica = 0
    AND pri.database_id = drs.database_id
ORDER BY 
    drs.ag,
    [replica],
    [database];

Результаты (с удалёнными датами, чтобы немного сжать):

Only secondaries Oldest transaction and last commit Lag and send queue kb according to DMV
ag replica database sync-state SYNCHRONIZED SYNCHRONIZING
HEALTHY HEALTHY 0 18:56:20.530 18:56:41.430 18:56:39.833
1597 00 27 60.00 0.00 0.00

Они не объединятся, чтобы дать вам волшебный секундомер или булево значение "можно/нельзя", но, если вы будете отслеживать их перед операцией, они должны дать хорошую оценку того, является ли сейчас "подходящим временем". Запрос, возможно, можно упростить, и, вероятно, есть другие столбцы, на которые вы захотите посмотреть: last_sent_time, last_hardened_time, last_redone_time и т.д. Приведённый выше запрос — это то, что я использовал для определения времени моего самого последнего планового отказа.

Что делать во время failover

Как только failover начинается, очень мало что может повлиять на взаимодействие с пользователем. Я всегда ожидаю кратковременного прерывания соединения; всем, кто подключён в момент изменения состояния базы данных, потребуется восстановить соединение. При правильном использовании прослушивателя, логике повторных попыток и строках подключения, включающих MultiSubnetFailover=True, приложения должны быстро восстановиться.

Ускоренное восстановление базы данных (ADR) делает отмену незначительной, так что повторное выполнение — это действительно единственная часть процесса, которая будет изменчивой. Вот почему всё, что уменьшает объём повторного выполнения, напрямую сокращает часть восстановления при отказе. Единственное, что я могу здесь сделать, это переждать.

Что происходит после failover?

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

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

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

Улучшения failover в SQL Server 2025

Хотя сами по себе эти улучшения вряд ли станут единственной причиной для обновления, в SQL Server 2025 появится несколько встроенных улучшений failover, которые не требуют никаких изменений конфигурации, настроек или флагов трассировки, как описано здесь:

  1. Улучшенная производительность повторного выполнения и планирование рабочих процессов
  2. Более быстрая инициализация Query Store
  3. Снижение накладных расходов ADR
  4. Хранилище запросов для вторичных реплик с поддержкой чтения

Эти улучшения предназначены для снижения изменчивости путём повышения эффективности прогрева буферного пула и кэша планов и обеспечения более предсказуемого поведения при навёрстывании отставания.

Тем не менее, SQL Server 2025 более агрессивно переводит базы данных в онлайн, поэтому я ожидаю, что проблемы с ресурсами и параллелизмом будут выше в определённых средах.

Часто задаваемые вопросы:

1. Что такое плановый failover AG в SQL Server?

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

2. Почему failover иногда занимают больше времени?

Продолжительность отказа SQL Server зависит от объёма повторного выполнения, поведения контрольных точек, открытых транзакций и готовности вторичной реплики. Большой объём повторного выполнения или холодные кэши могут увеличить время простоя даже для небольших баз данных.

3. Как я могу ускорить плановые failover?

Ключевые методы ускорения плановых отказов в SQL Server включают:

  1. Косвенные контрольные точки для уменьшения повторного выполнения.
  2. Ручные контрольные точки на загруженных базах данных.
  3. Временное отключение резервного копирования журнала и долго выполняющихся заданий.
  4. Прогрев кэша планов и буферного пула на вторичной реплике.
  5. Проверка конфигураций сервера и заданий перед отказом.

4. Что такое косвенные контрольные точки в SQL Server и почему они важны?

Косвенные контрольные точки делают восстановление более предсказуемым, ограничивая время между появлением "грязных" страниц и их записью на диск. Это сокращает объём повторного выполнения для вторичных реплик, ускоряя отказы.

5. Следует ли разбивать большие SQL Server AG на более мелкие группы?

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

6. Помогает ли отключение маршрутизации только для чтения или резервного копирования журнала?

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

7. Как прогрев вторичной реплики помогает при failover?

Предварительная загрузка кэша планов и буферного пула предотвращает замедления из-за холодного кэша и штормов компиляции запросов, улучшая производительность сразу после failover.

8. Какие функции SQL Server 2025 улучшают failover?

SQL Server 2025 добавляет:

  1. Более быстрое повторное выполнение и планирование рабочих процессов
  2. Более быструю загрузку Query Store
  3. Снижение накладных расходов ADR

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

9. Как я могу оценить продолжительность failover?

Проверьте размеры очередей повторного выполнения/отправки, скорость повторного выполнения и активные транзакции на первичной реплике, чтобы предсказать время отказа SQL Server и выбрать оптимальное окно.

10. Что я должен сделать после отказа SQL Server?

  1. Сверить логины и задания, протестировать связанные серверы 
  2. Снова включить резервное копирование и задания
  3. Прогреть кэш планов и буферный пул при необходимости
  4. Проверить панели мониторинга на предмет статуса новой первичной реплики

✅ Чеклист:

📋 ПЕРЕД FAILOVER'ОМ (Подготовка)

🔹 Долгосрочные настройки (выполнить заранее)

  • Разделить большие группы доступности — если в AG более 100-200 баз данных, разбить на меньшие группы для уменьшения конкуренции за параллельные потоки восстановления.
  • Включить косвенные контрольные точки — проверить и настроить для всех баз данных в AG:
    -- Проверить базы с устаревшими контрольными точками
    SELECT name FROM sys.databases WHERE target_recovery_time_in_seconds = 0;
    
    -- Включить косвенные контрольные точки
    ALTER DATABASE <db_name> SET TARGET_RECOVERY_TIME = 60 SECONDS;
  • Включить ускоренное восстановление базы данных (ADR) — для независимости времени rollback'а от длины транзакции (если версия SQL Server поддерживает).
  • Настроить флаги трассировки Query Store (если используется):
    • TF 7745 — предотвращает сброс данных на диск при завершении работы
    • TF 7752 — асинхронная загрузка Query Store (для версий до SQL Server 2019)

🔹 За несколько часов до failover'а

  • Отключить маршрутизацию только для чтения — чтобы дать приложениям время переключиться и очистить пулы соединений.
  • Отключить задания с интенсивной записью:
    • Резервное копирование журнала
    • Полные/дифференциальные резервные копии (или перенести их расписание)
    • ETL-процессы
    • Обслуживание индексов
    • Любые долго выполняющиеся транзакции
  • Проверить активность на вторичной реплике — убедиться, что количество пользовательских подключений стремится к нулю.

🔹 Непосредственно перед failover'ом

  • Выполнить принудительные контрольные точки для загруженных баз данных:
    -- Сгенерировать скрипт контрольных точек для всех баз в AG
    DECLARE @AGName sysname = N'<имя_AG>', @sql nvarchar(max);
    SELECT @sql = STRING_AGG(
        CONCAT(N'EXEC ', QUOTENAME(name), N'.sys.sp_executesql N''CHECKPOINT'';'),
        char(13)+char(10)
    )
    FROM sys.databases AS d
    WHERE d.state = 0 AND EXISTS (
        SELECT 1 FROM sys.dm_hadr_database_replica_states AS rs
        INNER JOIN sys.availability_groups AS ags ON rs.group_id = ags.group_id
        WHERE rs.database_id = d.database_id
        AND ags.name = @AGName
        AND rs.is_local = 1 AND rs.is_primary_replica = 1
    );
    PRINT @sql;
    -- EXEC sys.sp_executesql @sql;  -- Раскомментировать для выполнения
  • Прогреть вторичную реплику (если она доступна для чтения):
    -- Прогрев буферного пула (полное сканирование больших таблиц)
    SELECT COUNT_BIG(*) FROM dbo.<большая_таблица> WITH (INDEX(1));
    SELECT COUNT_BIG(*) FROM <большая_таблица> WITH (INDEX(<часто_используемый_индекс>));
    
    -- Прогрев кэша планов (выполнить набор характерных SELECT-запросов)
  • Проверить конфигурации сервера:
    • Имена входа (logins) синхронизированы
    • Связанные серверы (linked servers) работают
    • Задания агента SQL Server идентичны и настроены на первичную/вторичную реплику
  • Оценить текущее состояние — проверить очереди и отставание:
    -- Запустить на первичной реплике (см. полный запрос в статье)
    -- Обратить внимание на:
    --   • redo_queue_size
    --   • redo_rate
    --   • secondary_lag_seconds
    --   • возраст активных транзакций

⚡ ВО ВРЕМЯ FAILOVER'А

  • Инициировать плановый failover через:
    • SSMS (гуи)
    • T-SQL: ALTER AVAILABILITY GROUP [имя_AG] FAILOVER;
    • PowerShell
  • Ожидать завершения — на этом этапе мало что можно сделать, кроме мониторинга.
  • Быть готовым к кратковременному прерыванию соединений — при правильных строках подключения приложения должны восстановиться автоматически.

✅ ПОСЛЕ FAILOVER'А

🔹 Немедленные действия

  • Прогреть новую первичную реплику (если не сделали это на вторичной до failover'а):
    -- Выполнить полное сканирование больших таблиц и индексов
    SELECT COUNT_BIG(*) FROM dbo.<большая_таблица1>;
    SELECT COUNT_BIG(*) FROM dbo.<большая_таблица2> WITH (INDEX(<индекс>));
    -- Выполнить набор характерных SELECT-запросов для компиляции планов
  • Проверить функциональность:
    • Подключения работают
    • Запросы выполняются
    • Нет явных блокировок или проблем с производительностью

🔹 Проверка конфигурации

  • Сравнить имена входа (logins) — убедиться, что все необходимые имена входа присутствуют на новой первичной реплике.
  • Проверить связанные серверы (linked servers) — протестировать соединения.
  • Сравнить задания агента SQL Server — убедиться, что они идентичны и настроены правильно.
  • Проверить пользовательские объекты — триггеры, расширенные свойства, пользовательские типы и т.д.

🔹 Восстановление операций

  • Включить маршрутизацию только для чтения (если отключали).
  • Включить задания резервного копирования — журнала, полные, дифференциальные.
  • Включить ETL-процессы и задания обслуживания.

🔹 Мониторинг и наблюдаемость

  • Проверить панели мониторинга — инструменты мониторинга должны распознавать новую первичную реплику и показывать "зелёный" статус.
  • Отслеживать производительность — обратить внимание на:
    • Задержки ввода-вывода
    • Активность повторного выполнения (redo)
    • Ожидания (WRITELOG, PAGEIOLATCH и др.)
    • Использование процессора
  • Масштабировать ресурсы при необходимости — в облаке можно временно увеличить выделенные операции ввода-вывода, если наблюдается отставание.


Комментариев нет:

Отправить комментарий