Сжатие резервных копий вызывает повреждение в базе данных SQL 2017 TDE

13

На SQL Server 2017 (CU3) всякий раз, когда я включаю сжатие резервных копий в одной из моих баз данных TDE, процесс резервного копирования всегда повреждает определенную страницу в базе данных. Если я запускаю резервную копию без сжатия, она не будет повреждена. Вот шаги, которые я предпринял, чтобы проверить и воспроизвести эту проблему:

  1. Запустите DBCC CheckDB для базы данных "TDE_DB1"; все хорошо, ошибок нет;
  2. Успешное резервное копирование базы данных без сжатия; ВОССТАНОВИТЬ ВЕРИТЕЛЬНО говорит, что все хорошо;
  3. Успешно восстановить базу данных как "TDE_DB2"; все хорошо, DBCC CheckDB не показывает ошибок;
  4. Успешное резервное копирование базы данных «TDE_DB1» СО сжатия; ВОССТАНОВИТЬ ТОЛЬКО ошибки: «Обнаружено повреждение набора резервных копий»;
  5. Попытаться восстановить базу данных как «TDE_DB2»; ошибки, говоря «RESTORE обнаружил ошибку на странице (1: 92454) в базе данных»
  6. Повторите шаги 1-3; все хорошо;
  7. DROP "TDE_DB1" и "TDE_DB2"; Восстановить "TDE_DB1" из резервной копии; все хорошо;
  8. Повторите шаги 1-5; получить те же результаты;

Подводя итог: база данных и обычные резервные копии выглядят нормально, запуск CHECKDB в базе данных и VERIFYONLY в резервных копиях не сообщает об ошибках. Резервное копирование базы данных со сжатием, кажется, вызывает повреждение.

Ниже приведены примеры кода с ошибками. (Примечание: MAXTRANSFERSIZE требуется для использования сжатия с базой данных TDE )

-- Good, completes with no corruption;
BACKUP DATABASE [TDE_DB1] TO DISK = N'E:\MSSQL\Backup\TDE_DB1a.bak' WITH CHECKSUM;
RESTORE VERIFYONLY FROM DISK = N'E:\MSSQL\Backup\TDE_DB1a.bak' WITH CHECKSUM;

RESTORE DATABASE [TDE_DB2]
FROM DISK = 'E:\MSSQL\Backup\TDE_DB1a.bak'
WITH MOVE 'DataFileName' to 'E:\MSSQL\Data\TDE_DB2.mdf'
,MOVE 'LogFileName' to 'F:\MSSQL\Log\TDE_DB2_log.ldf';


-- Bad, I haz corruption;
BACKUP DATABASE [TDE_DB1] TO DISK = N'E:\MSSQL\Backup\TDE_DB1b.bak' WITH CHECKSUM, COMPRESSION, MAXTRANSFERSIZE = 131072;
RESTORE VERIFYONLY FROM DISK = N'E:\MSSQL\Backup\TDE_DB1b.bak' WITH CHECKSUM;
-- ERROR
--Msg 3189, Level 16, State 1, Line 1
--Damage to the backup set was detected.
--Msg 3013, Level 16, State 1, Line 1
--VERIFY DATABASE is terminating abnormally.

RESTORE DATABASE [TDE_DB2]
FROM DISK = 'E:\MSSQL\Backup\TDE_DB1b.bak'
WITH MOVE 'DataFileName' to 'E:\MSSQL\Data\TDE_DB2.mdf'
,MOVE 'LogFileName' to 'F:\MSSQL\Log\TDE_DB2_log.ldf';
-- ERROR
--Msg 3183, Level 16, State 1, Line 7
--RESTORE detected an error on page (1:92454) in database "TDE_DB2" as read from the backup set.
--Msg 3013, Level 16, State 1, Line 7
--RESTORE DATABASE is terminating abnormally.

Затем я попытался проверить страницу, на которой сообщается об ошибке (это всегда одна и та же страница), но DBCC PAGE сообщает, что ObjectId равен 0. Согласно этой статье Пола Рэндала, это означает, что метаданные не были найдены, и Одной из причин может быть то, что сама страница повреждена, и для поиска метаданных использовались неправильные значения. Он советует запустить CHECKDB, чего я не могу сделать, потому что поврежденная резервная копия не будет восстановлена.

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

Это происходит только с одной из моих баз данных TDE. У меня есть 4 другие базы данных TDE на этом же сервере, и у них нет этой проблемы. Это говорит мне о том, что может быть основная проблема с этой конкретной базой данных. Я понимаю, что простое решение состоит в том, чтобы просто не использовать сжатие, но я чувствую, что на самом деле это может быть ранним предупреждением о появлении более крупной проблемы в будущем.

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

ОБНОВЛЕНИЕ 1: Ниже приведены результаты из DBCC PAGE с опцией 0:

Выполнение DBCC завершено. Если DBCC напечатал сообщения об ошибках, обратитесь к системному администратору.

СТРАНИЦА: (1: 92454)

BUFFER:

BUF @ 0x000002187AE55640

bpage = 0x000002184865E000 bhash = 0x0000000000000000
bpageno = (1: 92454) bdbid = 8 брекетов = 0 bcputicks = 563 bsampleCount = 1
bUse1 = 51429 bstat = 0x809 блог = 0x15a
bnext = 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

ЗАГОЛОВОК СТРАНИЦЫ:

Page @ 0x000002184865E000

m_pageId = (1: 92454) m_headerVersion = 111
m_type = 189 m_typeFlagBits = 0x2d m_level = 197
m_flagBits = 0x525e m_objId (AllocUnitId.idObj) = 788815194
m_indexId (AllocUnitId.idInd) = 515 метаданных: AllocUnitId = 145011308798541824 Метаданные: PartitionID = 0 Метаданные: IndexID = -1 Метаданные: ObjectId = 0 m_prevPage = (32842: 1881351155) m_nextPage = (13086: -560562340)
pminlen = 36067 m_slotCnt = 8149 m_freeCnt = 51871 m_freeData = 7295 = 4810 m_reservedCnt m_lsn = (742012401: 720884976: 30191) m_xactReserved = 14755
m_xdesId = (12811: 1559482793) m_ghostRecCnt = 12339
m_tornBits = -1381699202 ID фрагмента БД = 1

Статус распределения

GAM (1: 2) = ВЫДЕЛЕННАЯ SGAM (1: 3) = НЕ ВЫДЕЛЕННАЯ
PFS (1: 88968) = 0x0 0_PCT_FULL DIFF (1: 6) = НЕ ИЗМЕНЕНО
ML (1: 7) = НЕ MIN_LOGGED

Если я пытаюсь запустить DBCC PAGE с другими параметрами, я получаю следующие ошибки:

Страница DBCC с опцией 1: Сообщение 0, Уровень 11, Состояние 0, Строка 0 Произошла серьезная ошибка в текущей команде. Результаты, если таковые имеются, должны быть отброшены.

DBCC PAGE с опцией 3: Сообщение 2514, уровень 16, состояние 5, строка 3 Произошла ошибка DBCC PAGE: неверный тип страницы - стиль дампа 3 невозможен.

ОБНОВЛЕНИЕ 2: Вот некоторые результаты из DMO sys.dm_db_database_page_allocations:

object_id = 75 index_id = 1 rowset_id = 281474981625856 allocation_unit_id = 281474981625856
allocation_unit_type = 1 allocation_unit_type_desc = IN_ROW_DATA extent_file_id = 1 extent_page_id = 92448
allocated_page_iam_file_id = 1 allocated_page_iam_page_id = 104
allocated_page_file_id = 1 allocated_page_page_id = 92454
is_allocated = 0 is_iam_page = 0 is_mixed_page_allocation = 0

Эрик Кобб
источник

Ответы:

8

Похоже, эта проблема связана с базами данных, в которых выполняются операции SHRINK. В моем случае я брал копию одной из наших производственных баз данных на SQL Server 2014 (которая уже зашифрована с помощью TDE), выполнял DBCC SHRINKFILE как для данных, так и для файлов журналов, затем делал резервную копию и восстанавливал ее на моем новом SQL Сервер 2017 года. (Причина сокращения заключалась в уменьшении размера для ускорения передачи резервной копии.)

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

Итак, подведем итог, результаты моего тестирования следующие:

  • Обычные операции резервного копирования / восстановления в этой «усохшей» базе данных TDE работают правильно в SQL 2017
  • Сжатие резервных копий базы данных TDE «shrunken», кажется, вызывает повреждение в таблице sys.sysmultiobjrefs
  • Сжатие резервных копий обычной базы данных TDE (без запуска DBCC SHRINKFILE) работает правильно и не сообщает о повреждении

Я не знаю, является ли это подтвержденной ошибкой в ​​SQL Server 2017, но я отправил свои выводы в Microsoft для их просмотра.

Итак, мораль этой истории такова: НЕ СУШИТЕ СВОИ БАЗЫ ДАННЫХ! КОГДА-ЛИБО! :)

Эрик Кобб
источник