Как-то я опубликовал заметку в нашем блоге журнала "SQL Server Pro" о ложных срабатываниях проверки на повреждения, которые вы гарантированно увидите, если восстановите резервную копию базы master как пользовательскую базу и запустите DBCC CHECKDB на её копии. Это может быть частью переноса проверок целостности на другой сервер или валидации того, что ваши бэкапы корректно восстанавливаются и содержат неповреждённую базу. Впервые увидев такие ложные срабатывания, вы наверняка испугаетесь и решите, что ваш настоящий master повреждён!
Одна из «повреждённых» сущностей появляется из‑за специальной страницы, которая существует только в базе master, — блока CONFIG экземпляра SQL Server. Это страница с номером 10 в файле данных ID 1 базы master. DBCC CHECKDB помечает это как повреждение, если такая страница встречается в любой другой базе, кроме master, потому что в master эта страница помечена как выделенная, но не принадлежит никакому объекту. Это допустимо только в master. Похожие исключения DBCC CHECKDB делает в каждой базе для загрузочной страницы (boot page, страница 9 в файле 1) и для страницы заголовка каждого файла данных и журнала (страница 0 в каждом файле). См. публикации о загрузочной странице и о страницах заголовков файлов.
Что хранит эта специальная страница? На ней записаны все параметры sp_configure для экземпляра SQL Server. Это ещё одна веская причина регулярно делать резервные копии базы master: потеряете master — потеряете все настройки конфигурации данного экземпляра SQL Server.
Изучить содержимое этой страницы можно через DBCC PAGE или через столь же недокументированную, но куда менее известную команду DBCC CONFIG (внутри они используют один и тот же код; обе требуют трассировочный флаг 3604).
Пример с одного из моих ноутбуков:
DBCC TRACEON (3604);
DBCC PAGE ('master', 1, 10, 3);
GO
PAGE: (1:10)
BUFFER:
BUF @0x0000000080FC0AC0
bpage = 0x0000000080572000 bhash = 0x0000000000000000 bpageno = (1:10)
bdbid = 1 breferences = 0 bcputicks = 264
bsampleCount = 1 bUse1 = 23062 bstat = 0xc00009
blog = 0x32159 bnext = 0x0000000000000000
PAGE HEADER:
Page @0x0000000080572000
m_pageId = (1:10) m_headerVersion = 1 m_type = 14
m_typeFlagBits = 0x0 m_level = 0 m_flagBits = 0x200
m_objId (AllocUnitId.idObj) = 99 m_indexId (AllocUnitId.idInd) = 0 Metadata: AllocUnitId = 6488064
Metadata: PartitionId = 0 Metadata: IndexId = 0 Metadata: ObjectId = 99
m_prevPage = (0:0) m_nextPage = (0:0) pminlen = 0
m_slotCnt = 1 m_freeCnt = 0 m_freeData = 8190
m_reservedCnt = 0 m_lsn = (0:0:1) m_xactReserved = 0
m_xdesId = (0:0) m_ghostRecCnt = 0 m_tornBits = -1051583237
Allocation Status
GAM (1:2) = ALLOCATED SGAM (1:3) = NOT ALLOCATED
PFS (1:1) = 0x64 MIXED_EXT ALLOCATED 100_PCT_FULL DIFF (1:6) = CHANGED
ML (1:7) = NOT MIN_LOGGED
Slot 0, Offset 0x60, Length 9, DumpStyle BYTE
Record Type = PRIMARY_RECORD Record Attributes = Record Size = 9
Memory Dump @0x000000001580C060
0000000000000000: 00000800 e2040000 09†††††††††††††††††….â…
DS_CONFIG @0x000000001580C060
cconfsz = 8 cmajor = 9 cminor = 0
crevision = 75 cbootsource = 2 crecinterval = 0
ccatalogupdates = 0 cmbSrvMemMin = 0 cmbSrvMemMax = 2147483647
cusrconnections = 0 cnetworkpcksize = 4096 ckbIndexMem = 0
cfillfactor = 0 ctapreten = 0 cwritestatus = 0
cfgpriorityboost = 0x0 cfgexposeadvparm = 0x0 cfglogintime = 20
cfgpss = 0 cfgpad = 4096 cfgxdes = 16
cfgaffinitymask = 0 cfgaffinitymask64 = 0 cfgIOAffinityMask = 0
cfgIOAffinity64Mask = 0 cfgbuf = 4362 cfgdes = 0
cfglocks = 0 cfgquerytime = 600 cfgcursorthrsh = -1
cfgrmttimeout = 10 cfg_dtc_rpcs = 0 cclkrate = 31250
cfg_max_text_repl_size = 65536 cfgupddate = 41023 cfgupdtime = 14252889
fRemoteAccess = 1 cfgbufminfree = 331 cnestedtriggers = 0x1
cdeflang = 0 cfgTransformNoiseWords = 0x0 cfgPrecomputeRank = 0x0
crossdbownchain = 0 cidCfg = 0x3400d008 cidCfgOld = 0x3400d008
cfgCutoffYear = 2049 cfgLangNeutralFT = 1033 maxworkthreads = 0
minworkthreads = 32 minnetworkthreads = 32 threadtimeout = 15
connectsperthread = 0 cusroptions = 0 exchcostthreshold = 5
maxdop = 0 cpwdpolicyupgrade = 0x1 cfServerTriggerRecursion = 1
cfDisableResultsetsFromTriggers = 0 cfgPHConnectTimeout = 60 CLREnabled = 0
cfgmaxcrawlrange = 4 ftSmallBufMin = 0 ftSmallBufMax = 100
ftLargeBufMin = 0 ftLargeBufMax = 100 RemoteDacEnabled = 0
CommCritComplianceEnabled = 0 EkmEnabled = 0 cUserInstanceTimeout = 0x3c
cfgEnableUserInstances = 0x1 m_BackupCompressionDefault = 0x0 FilestreamAccessLevel = 2
OptimizeForAdhocWorkloads = 0 cchecksum = 1250
DBCC execution completed. If DBCC printed error messages, contact your system administrator.
Видно, что блок CONFIG хранится особым образом: DBCC PAGE сообщает длину записи 9 байт, тогда как сам блок CONFIG — это несколько сотен байт. При старте SQL Server открывает канал непосредственно к MDF базы master, считывает все 8 Кб страницы 10 в память и приводит их к типу внутренней структуры CONFIG. Если блок CONFIG повреждён, сервер не запустится.
Как видно из вывода, далеко не всё, что содержится в блоке CONFIG, доступно наружу или настраивается через sp_configure.
В следующей статье я расскажу, как определить, когда параметры sp_configure обновлялись в последний раз.

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