Мы устраняем неполадки своего рода Sync Framework между двумя базами данных SQL Server на отдельных серверах (как SQL Server 2008 Enterprise 64 бит SP2 - 10.0.4000.0), так и через связанные соединения с сервером, и мы достигли точки, в которой мы "как бы застрял.
Логика для определения записей, которые ожидаются для синхронизации, конечно, основана на значениях ROWVERSION
, включая использование MIN_ACTIVE_ROWVERSION()
, чтобы избежать грязных чтений.
Все операции SELECT
инкапсулируются в SP на каждой стороне "источника". Это схематический пример одного SP:
PROCEDURE LoaderRetrieve(@LastStamp bigint, @Rows int)
BEGIN
...
(vars handling)
...
SET TRANSACTION ISOLATION LEVEL SNAPSHOT
Select TOP (@Rows) Field1, Field2, Field3
FROM Table
WHERE [RowVersion] > @LastStampAsRowVersionDataType
AND [RowVersion] < @MinActiveVersion
Order by [RowVersion]
END
Подход работает очень хорошо, мы обычно синхронизируем записи с ожидаемой скоростью 600k/час (работа каждые 30 секунд, размер партии = 5k), но в какой-то момент процесс синхронизации не находит ни одной записи, которая будет передана, хотя имеется несколько тысяч записей с величиной ROWVERSION
, превышающей параметр @LastStamp
.
При проверке причины мы обнаружили, что значение MIN_ACTIVE_ROWVERSION()
имеет значение меньше (или немного больше, всего 5 или 10 приращений) при поиске @LastStamp
. Это, конечно, не должно быть проблемой, поскольку был введен подход MIN_ACTIVE_ROWVERSION()
, чтобы избежать грязных чтений и задних проблем, НО:
Проблема, которую мы видим в некоторых случаях во время вышеприведенного сценария, заключается в том, что значение для MIN_ACTIVE_ROWVERSION()
не изменяется в течение длительного (очень длительного) периода времени, например 30/40 минут, иногда более одного часа, И это значение намного меньше значения @@DBTS
.
Мы сначала подумали, что это связано с ожидающей транзакции БД, еще не совершенной. В соответствии с определением MSDN о MIN_ACTIVE_ROWVERSION()
(ссылка):
Возвращает самое низкое активное значение rowversion в текущей базе данных. Значение rowversion является активным, если оно используется в транзакции, которая еще не была совершена.
Но при проверке сеансов (sys.sysprocesses
) с open_tran > 0
в течение продолжительности этой проблемы мы не смогли найти какой-либо сеанс с ожиданием больше нескольких секунд, только одно или два появления +/- 5 минут сеансы waittime.
Итак, на данный момент мы пытаемся понять ситуацию: MIN_ACTIVE_ROWVERSION()
не меняется в течение огромного периода времени, и в течение этого периода времени не обнаружены незавершенные транзакции с длинными ожиданиями.
Я не администратор базы данных, и может случиться так, что нам не хватает чего-то на картинке, чтобы проанализировать эту проблему, сделав некоторые исследования на форумах, и блоги не смогли найти никакой другой подсказки. До сих пор open_tran > 0 была веской причиной, но в сложившихся обстоятельствах я понял, что есть что-то еще и не знаю почему.
Любая обратная связь приветствуется.