Приращение идентификатора прыгает в базе данных SQL Server
в одной из моих таблиц Fee в столбце "ReceiptNo" в SQL Server 2012 приращение идентификатора базы данных внезапно начало прыгать до 100s вместо 1 в зависимости от следующих двух вещей.
если это 1205446 он переходит к 1206306, если это 1206321, он переходит к 1207306 и если это 1207314, он переходит к 1208306. Я хочу обратить ваше внимание на то, что последние три цифры остаются постоянными, т. е. 306, когда происходит переход, как показано ниже изображение.
эта проблема возникает при перезагрузке компьютера

6 ответов:
вы, вероятно, сталкиваетесь с проблемой здесь (wayback machine).
SQL Server 2012 теперь использует размер кэша 1000 при выделении
IDENTITYзначенияintстолбец и перезапуск службы могут "потерять" неиспользуемые значения (размер кэша составляет 10 000 дляbigint/numeric).из данных, которые вы показали, похоже, что это произошло после ввода данных для 22 декабря, а затем, когда он перезапустил SQL Server зарезервировал значения
1206306 - 1207305. После ввод данных за 24-25 декабря был сделан еще один перезапуск и SQL Server зарезервировал следующий диапазон1207306 - 1208305видимый в записях для 28-го.если вы не перезапускаете службу с необычной частотой, любые "потерянные" значения вряд ли сделают какую-либо значительную вмятину в диапазоне значений, разрешенных типом данных, поэтому лучшая политика-не беспокоиться об этом.
если это по какой-то причине реальная проблема, вы видите обходные пути для связанного элемента Connect нитка.
- можно использовать
SEQUENCEвместо столбца идентификаторов и определить меньший размер кэша, например, и использоватьNEXT VALUE FORв столбце по умолчанию.- или применить флаг трассировки 272, который делает
IDENTITYраспределение регистрируется, как и в предыдущих версиях.вы должны знать, что ни один из этих обходных путей не гарантирует никаких пробелов. Это никогда не было гарантировано
IDENTITYКак это было бы возможно только путем сериализации вставок к столу. Если вам нужен беззазорный столбец, вам нужно будет использовать другое решение, чем либоIDENTITYилиSEQUENCE
эта проблема возникает после перезагрузки SQL Server.
решение:
Run диспетчер конфигурации SQL Server.
выберите службы SQL Server.
щелкните правой кнопкой мыши SQL Server и выберите свойства.
В открывшемся окне в разделе запуск Параметры, тип
-T272и нажмите кнопку добавить, нажмите клавишу применить и перезагрузка.
Я знаю, что мой ответ может опоздать на вечеринку. Но я решил по-другому, добавив хранимую процедуру запуска в SQL Server 2012.
создайте следующую хранимую процедуру в главной БД.
USE [master] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER PROCEDURE [dbo].[ResetTableNameIdentityAfterRestart] AS BEGIN begin TRAN declare @id int = 0 SELECT @id = MAX(id) FROM [DatabaseName].dbo.[TableName] --print @id DBCC CHECKIDENT ('[DatabaseName].dbo.[TableName]', reseed, @id) Commit ENDзатем добавьте его для запуска, используя следующий синтаксис.
EXEC sp_procoption 'ResetOrderIdentityAfterRestart', 'startup', 'on';Это хорошая идея, если у вас есть несколько таблиц. но если вам нужно сделать много таблиц, этот способ все еще работает, но не очень хорошая идея.
С
SQL Server 2017+вы могли бы использовать ИЗМЕНИТЬ КОНФИГУРАЦИЮ ОБЛАСТИ ДЕЙСТВИЯ БАЗЫ ДАННЫХ:IDENTITY_CACHE = { ВКЛ / ВЫКЛ }
включает или отключает кэш идентификаторов на уровне базы данных. Неисполнение идет. Кэширование идентификаторов используется для повышения производительности вставки таблицы со столбцами идентификаторов. чтобы избежать пробелов в значениях Столбец идентификаторов в случаях неожиданного перезапуска сервера или не удается перейти к вторичный сервер, отключите параметр IDENTITY_CACHE. Этот параметр аналогичен существующему флагу трассировки SQL Server 272, за исключением того, что он может быть установлен на уровне базы данных, а не только в серверный уровень.
(...)
G. Set IDENTITY_CACHE
в этом примере отключается кэш идентификаторов.
ALTER DATABASE SCOPED CONFIGURATION SET IDENTITY_CACHE=OFF ;
Это все равно очень распространенная проблема среди многих разработчиков и приложений независимо от размера.
к сожалению, приведенные выше предложения не исправляют все сценарии, т. е. общий хостинг, вы не можете полагаться на свой хост, чтобы установить параметр запуска-t272.
кроме того, если у вас есть существующие таблицы, которые используют эти столбцы идентификаторов для первичных ключей, Это огромные усилия, чтобы удалить эти столбцы и воссоздать новые, чтобы использовать обходной путь последовательности BS. Обходной путь последовательности только хорошо, если вы разрабатываете новые таблицы с нуля в SQL 2012+
суть в том, что если вы находитесь на Sql Server 2008R2, то оставайтесь на нем. Серьезно, оставайся на нем. Пока Microsoft не признает, что они ввели огромную ошибку, которая все еще существует даже в Sql Server 2016, тогда мы не должны обновляться, пока они не владеют ею и не исправят ее.
Microsoft прямо ввела критическое изменение, т. е. они сломали рабочий API, который больше не работает так, как задумано, из-за того, что их система забывает их текущую идентичность при перезапуске. Кэш или нет кэша, это неприемлемо, и разработчик Microsoft по имени Брайан должен владеть им, а не рассказывать миру, что это "по дизайну" и "функция". Конечно, кэширование-это функция, но потеря отслеживания того, что должно быть следующим идентификатором, не является функцией. Это чертов Жук!!!
я поделюсь обходным путем, который я использовал, потому что мои БД находятся на серверах общего хостинга, кроме того, я не отбрасываю и не воссоздаю свой Первичные ключевые столбцы, это будет огромная Пита.
вместо этого, это мой позорный хак (но не так позорно, как эта ошибка POS, которую microsoft представила).
Hack / Fix:
перед вашими командами вставки, просто повторно введите свою личность перед каждой вставкой. Это исправление рекомендуется только в том случае, если у вас нет контроля администратора над экземпляром Sql Server, в противном случае я предлагаю повторное заполнение при перезагрузке сервера.
declare @newId int -- where int is the datatype of your PKey or Id column select @newId = max(YourBuggedIdColumn) from YOUR_TABLE_NAME DBCC CheckIdent('YOUR_TABLE_NAME', RESEED, @newId)только эти 3 строки непосредственно перед ваша вставка, и вы должны быть хорошо идти. Это действительно не повлияет на производительность так сильно, т. е. это будет незаметно.
Гудлак.
существует множество возможных причин для перехода значений идентификаторов. Они варьируются от отката вставок до управления удостоверениями для репликации. Что вызывает это в вашем случае я не могу сказать, не тратя некоторое время в вашей системе.
вы должны знать, однако, что ни в коем случае вы не можете считать столбец идентификаторов contiguos. Есть слишком много вещей, которые могут вызвать пробелы.
вы можете найти немного больше информации об этом здесь: http://sqlity.net/en/792/the-gap-in-the-identity-value-sequence/


Comments