Почему ваш синхронный SQL-commit ждёт поездки через VPN туда и обратно
Синхронная фиксация в группе доступности включает закаливание удалённого журнала. Измерьте этот путь, прежде чем винить пропускную способность или менять режим.
Задержка записи подскочила после переезда реплики на вторую площадку, а туннель — самый новый компонент, поэтому виноватым назначают его. Туннель может быть невиновен: внутри группы доступности с синхронной фиксацией основная реплика не может подтвердить фиксацию, пока не завершится удалённая запись журнала, поэтому каждая транзакция платит поездку туда и обратно, сколько бы мегабит ни несла линия. Пропускная способность измеряет байты в секунду, задержка измеряет, сколько длится один обмен, а фиксации нужен всего один небольшой обмен, чтобы завершиться. Один показатель решает спор: длительность фиксации небольшой транзакции, измеренная внутри базы данных доступности и затем снова напротив локальной таблицы на том же экземпляре.
Чего на самом деле ждёт основная реплика
При синхронной фиксации основная реплика удерживает подтверждение, пока партнёр не подтвердит, что его записи журнала закалены. Закалены означает устойчиво записаны в журнал транзакций вторичной реплики, а не воспроизведены на её страницах данных. Redo может отставать на минуты, не добавляя ни миллисекунды к фиксации основной реплики.
Документация Microsoft о режимах доступности разбирает это рукопожатие и описывает, что делает платформа, когда партнёр выпадает. Реплика, помеченная как синхронная, — это правило об ожидании, а не постоянное обещание, что для каждой фиксации существует здоровая удалённая копия. Отключённый путь определён отдельно, и это не просто отказ фиксации.
Значит, наблюдаемое ожидание — это сумма: передача журнала, планирование на обоих хостах и запись в удалённое хранилище. Вторичная реплика с насыщенным объёмом журнала добавляет время, которого не покажет ни один тест скорости. Этот диск редко измеряют, когда в жалобе упоминают VPN.
Пропускная способность — не задержка поездки туда и обратно
Тест скорости ненадолго заливает путь и сообщает скорость. Фиксация спрашивает о более узком: сколько времени небольшому сообщению нужно, чтобы дойти до другой стороны, сохраниться и вернуться. Длина пути, очереди и потери пакетов определяют это число, и ни одно из них не улучшается, когда провайдер поднимает потолок.
Поэтому «быстрый» туннель может добавить заметный штраф нагрузке, тяжёлой по записи, построенной из множества небольших последовательных транзакций. Тот же объём байтов, разделённый на тысячу фиксаций, платит поездку тысячу раз; одна массовая передача платит её один раз.
Попросите владельца сети измерить задержку и потери на самом маршруте реплики под репрезентативной нагрузкой. Ping с офисного ноутбука до шлюза VPN или тест скорости до ближайшего узла почти ничего не относит к маршруту, по которому журнал действительно идёт. Добейтесь, чтобы окно измерения перекрывалось с часами медленной записи.
Прочитайте состояние реплики, прежде чем что-то менять
Начните с того, что экземпляры сообщают о себе, потому что стороны могут расходиться во мнении о том, насколько здорово партнёрство, и среднее на панели скрывает, какая очередь движется. Запросы ниже отвечают на разные вопросы: один читает состояние репликации по каждой базе, другой читает, как настроена каждая реплика. Выполните оба, прежде чем трогать режим.
SELECT ag.name AS ag_name, drs.database_id, drs.synchronization_state_desc,
drs.log_send_queue_size, drs.redo_queue_size, drs.secondary_lag_seconds
FROM sys.dm_hadr_database_replica_states AS drs
JOIN sys.availability_groups AS ag ON ag.group_id = drs.group_id;
SELECT ar.replica_server_name, ar.availability_mode_desc, ar.failover_mode_desc
FROM sys.availability_replicas AS ar;
Первый результат отделяет передачу журнала от redo. log_send_queue_size растёт, пока redo_queue_size стоит на месте, — журнал не пришёл; обратное означает, что он пришёл, а воспроизведение отстаёт. Только первый случай находится на пути фиксации.
Второй результат подтверждает, какие реплики действительно настроены так, как вы предполагаете, потому что режим, изменённый во время прошлого инцидента, обычно остаётся изменённым и недокументированным. Читайте строку, которая вам важна, а не значение группы по умолчанию: availability_mode_desc и failover_mode_desc задаются для каждой реплики. secondary_lag_seconds существует только в SQL Server 2016 и новее, поэтому старая сборка оставляет вам только столбцы очереди отправки и redo.
Затем измерьте репрезентативную запись вместо того, чтобы доверять среднему с панели. Выполните блок ниже в базе данных доступности, а затем выполните его снова напротив той же формы таблицы в базе вне группы на том же экземпляре. Разница между двумя длительностями — грубая цена удалённого журнала, и в споре с сетевой командой она держится гораздо лучше графика. После этого меняйте по одной переменной за раз, иначе разница перестаёт что-либо значить.
IF OBJECT_ID('dbo.CommitProbe') IS NULL
CREATE TABLE dbo.CommitProbe (probe_id int PRIMARY KEY, touched_at datetime2(3));
IF NOT EXISTS (SELECT 1 FROM dbo.CommitProbe WHERE probe_id = 1)
INSERT INTO dbo.CommitProbe (probe_id) VALUES (1);
SET STATISTICS TIME ON;
BEGIN TRANSACTION;
UPDATE dbo.CommitProbe SET touched_at = SYSUTCDATETIME() WHERE probe_id = 1;
COMMIT TRANSACTION;
SET STATISTICS TIME OFF;
Что покупает асинхронная фиксация и сколько она стоит
При асинхронной фиксации основная реплика перестаёт ждать подтверждения удалённого закаливания, поэтому поездка туда и обратно уходит с пути фиксации. Задержка фиксации падает, а вторичная может свободно отставать на величину, которую никто не контролирует. Это реальное исправление ожидания и реальное изменение обещания.
Цена — решение о точке восстановления. Если основная реплика умирает раньше, чем её журнал дойдёт до цели переключения при сбое, которую вы действительно можете использовать, перенос службы на асинхронную копию отбрасывает транзакции, которые приложение уже сообщило как зафиксированные. Ни одно окно настройки не подаёт это так, потому что это деловой вопрос о допустимой потере, а не параметр производительности. Запишите допустимое окно потерь до инцидента, а не во время него.
Согласуйте режим с владельцем данных письменно, вместе с процедурой переключения при сбое на случай, когда предпочтительная цель недоступна. Синхронность в проектном документе — не оперативное руководство, а асинхронность — не лицензия перестать следить за очередями.
Выберите исправление, которое сможете защитить потом
Есть четыре честных варианта. Сократите избегаемые поездки фиксации туда и обратно там, где семантика приложения допускает пакетирование; исправьте измеренное узкое место передачи или хранения, что может означать более быстрый объём журнала на вторичной вместо трубы побольше; приблизьте реплику, чтобы поездка сократилась; или ослабьте политику защиты и примите более широкое окно потерь. Каждый покупает задержку, тратя что-то другое, а четвёртый тратит долговечность. Назовите трату, прежде чем выбирать.
Решайте, держа перед собой одновременно цель по задержке рабочей нагрузки и требование к её долговечности, потому что оптимизация одного тихо тратит другое. Затем снова выполните ту же транзакцию, которую измерили до изменения. Исправление, которое не может сдвинуть это число, — догадка с билетом на изменение.
Сохраняйте показания до и после в записи об изменении. Иначе следующий человек, увидевший медленную запись, повторит расследование с начала и снова начнёт винить туннель.