昨晚有网络活动,他们正在升级服务器交换机。整个网络出现故障,我们作为 DBA 已经准备好禁用数据库服务器上的所有作业以进行复制和备份,但是在活动期间,WSFC(Windows 服务器故障转移集群)之一启动了故障转移,似乎它没有完全成功. 这导致两个节点启动并运行数据库和两台服务器上的所有驱动器,而驱动器和 SQL 服务应该只在其中一个上。
以上导致许多数据库损坏,我在尝试清除损坏方面非常困难。从两个用户数据库开始,后来 tempdb 和 msdb 也损坏了。不得不重新启动 tempdb 的服务,但是对于从上次成功备份恢复的 msdb,一切似乎都恢复了正常运行。
之后,在所有数据库(系统和用户数据库)上执行 dbcc checkdb。系统数据库没有任何问题,但是其中一个用户数据库(关键)出现以下错误:
Command: DBCC CHECKDB ([User_DB_Critical]) WITH NO_INFOMSGS, ALL_ERRORMSGS, DATA_PURITY, MAXDOP = 2
Msg 8914, Level 16, State 1, Server DB_Cluster_Name, Line 1
Incorrect PFS free space information for page (1:1439286) in object ID 526624919, index ID 0, partition ID 72057594055753728, alloc unit ID 72057594056933376 (type In-row data). Expected value 95_PCT_FULL, actual value 80_PCT_FULL.
Msg 8951, Level 16, State 1, Server DB_Cluster_Name, Line 1
Table error: table 'Job_Execution_Log_Table' (ID 526624919). Data row does not have a matching index row in the index 'PK289' (ID 2). Possible missing or invalid keys for the index row matching:
Msg 8955, Level 16, State 1, Server DB_Cluster_Name, Line 1
Data row (1:2224:6) identified by (HEAP RID = (1:2224:6)) with index values 'JOB_NAME = 'populate_Tran_details' and START_TIME = '2019-07-03 03:42:00.323' and HEAP RID = (1:2224:6)'.
Msg 8951, Level 16, State 1, Server DB_Cluster_Name, Line 1
Table error: table 'Job_Execution_Log_Table' (ID 526624919). Data row does not have a matching index row in the index 'PK289' (ID 2). Possible missing or invalid keys for the index row matching:
Msg 8955, Level 16, State 1, Server DB_Cluster_Name, Line 1
Data row (1:1395530:49) identified by (HEAP RID = (1:1395530:49)) with index values 'JOB_NAME = 'populate_Tran_details' and START_TIME = '2019-07-03 03:41:13.480' and HEAP RID = (1:1395530:49)'.
Msg 8951, Level 16, State 1, Server DB_Cluster_Name, Line 1
Table error: table 'Job_Execution_Log_Table' (ID 526624919). Data row does not have a matching index row in the index 'PK289' (ID 2). Possible missing or invalid keys for the index row matching:
Msg 8955, Level 16, State 1, Server DB_Cluster_Name, Line 1
Data row (1:1439286:43) identified by (HEAP RID = (1:1439286:43)) with index values 'JOB_NAME = 'populate_Tran_details' and START_TIME = '2019-07-03 03:45:00.890' and HEAP RID = (1:1439286:43)'.
Msg 8951, Level 16, State 1, Server DB_Cluster_Name, Line 1
Table error: table 'Job_Execution_Log_Table' (ID 526624919). Data row does not have a matching index row in the index 'PK289' (ID 2). Possible missing or invalid keys for the index row matching:
Msg 8955, Level 16, State 1, Server DB_Cluster_Name, Line 1
Data row (1:1439286:44) identified by (HEAP RID = (1:1439286:44)) with index values 'JOB_NAME = 'populate_Tran_details' and START_TIME = '2019-07-03 03:48:00.473' and HEAP RID = (1:1439286:44)'.
Msg 8935, Level 16, State 1, Server DB_Cluster_Name, Line 1
Table error: Object ID 1374679995, index ID 1, partition ID 72057594120962048, alloc unit ID 72057596467675136 (type In-row data). The previous link (1:1685287) on page (1:491016) does not match the previous page (1:1445099) that the parent (1:232830), slot 129 expects for this page.
Msg 8937, Level 16, State 1, Server DB_Cluster_Name, Line 1
Table error: Object ID 1374679995, index ID 1, partition ID 72057594120962048, alloc unit ID 72057596467675136 (type In-row data). B-tree page (1:491016) has two parent nodes (0:1), slot 0 and (1:1591622), slot 138.
Msg 8977, Level 16, State 1, Server DB_Cluster_Name, Line 1
Table error: Object ID 1374679995, index ID 17, partition ID 72057594121093120, alloc unit ID 72057596467806208 (type In-row data). Parent node for page (1:692096) was not encountered.
Msg 8979, Level 16, State 1, Server DB_Cluster_Name, Line 1
Table error: Object ID 1374679995, index ID 17, partition ID 72057594121093120, alloc unit ID 72057596467806208 (type In-row data). Page (1:692097) is missing references from parent (unknown) and previous (page (1:1548068)) nodes. Possible bad root entry in system catalog.
Msg 8978, Level 16, State 1, Server DB_Cluster_Name, Line 1
Table error: Object ID 1374679995, index ID 1, partition ID 72057594120962048, alloc unit ID 72057596467675136 (type In-row data). Page (1:1623651) is missing a reference from previous page (1:491016). Possible chain linkage problem.
CHECKDB found 0 allocation errors and 5 consistency errors in table 'Job_Execution_Log_Table' (object ID 526624919).
CHECKDB found 0 allocation errors and 5 consistency errors in table 'Tran_details_Table' (object ID 1374679995).
CHECKDB found 0 allocation errors and 10 consistency errors in database 'User_DB_Critical'.
repair_allow_data_loss is the minimum repair level for the errors found by DBCC CHECKDB (User_DB_Critical).
桌子尺寸:
我建议我的经理采用以下方法:
- 尝试找到当时插入的行,如果可能,从上面的两个表中删除它们。
- 如果步骤 1 不可行,则重建表上的所有索引。重建需要对表的独占访问权限。
- 如果重建不起作用 - 我们将需要删除并重新创建索引。这需要对表的独占访问。
- 如果第 3 步不起作用,我们将不得不进行修复重建选项。此选项要求整个数据库处于单用户模式——这意味着在此操作进行期间任何人都不应访问数据库。
- 如果第 4 步不起作用——我们将需要选择 repair_allow_data_loss 选项,这很耗时,并且可能会丢失存在一致性问题的数据。这再次要求数据库处于单用户模式,并且没有人应该访问数据库。
我在活动之前进行了数据库完整备份,但是活动计划在 7 月 3 日早上进行,由于所有数据库的问题,当我们所有数据库都没有损坏并且业务开始照常运行时,它变成了早上 6:30。对于 msdb 和一个用户数据库 - 我仅使用以前的备份进行恢复。我在 7 月 3 日下班后运行了 checkdb,这意味着数据库包含一整天的所有数据。因此,如果我们在活动前恢复 7 月 3 日备份,我们将丢失 7 月 3 日白天的所有数据,这对企业来说是不可接受的。
添加有关备份的更多详细信息-目前我正在使用 ola hallengren 脚本进行备份,并且昨晚成功运行了备份。以下是我用于备份的参数:
sqlcmd -E -S $(ESCAPE_SQUOTE(SRVR)) -d DBA_Maintenance -Q "EXECUTE [dbo].[DatabaseBackup] @Databases = 'USER_DATABASES, -One_Heavy_Database', @Directory = N'DB_Backup_Path', @BackupType = 'FULL', @Verify = 'Y', @CleanupTime = 24, @CheckSum = 'Y', @Compress = 'Y', @LogToTable = 'Y'" -b
我正在使用验证和校验和标志来检查备份。差异备份每 2 小时安排一次,日志备份每 15 分钟运行一次(日志传送已配置,但现在已停止),到目前为止,没有任何备份失败或报告任何问题。
在重表上,聚集索引上出现 3 个一致性错误,非聚集索引上出现 2 个一致性错误。对于第一个表,即 Job_Execution_Log_Table 在非聚集索引上存在所有不一致。
我需要关于如何去做的建议,以及解决这个一致性问题的最有效和最省时的工作应该是什么。
目前我正在浏览 Paul Randal 的链接,并试图看看这是否是最好的选择。
编辑:我将备份从主服务器恢复到辅助服务器并运行 checkdb 并发现与主服务器报告的一致性错误相同。删除并重新创建非聚集索引,4 个一致性错误消失了,只剩下一个:
Incorrect PFS free space information for page (1:1439286) in object ID 526624919, index ID 0, partition ID 72057594055753728, alloc unit ID 72057594056933376 (type In-row data). Expected value 95_PCT_FULL, actual value 80_PCT_FULL.
尚未触及大表,因为它在聚集索引中存在问题。并且不知道如何解决这个 PFS 问题。
感谢您的建议。
版本:Microsoft SQL Server 2014 (SP3) (KB4022619) - 12.0.6024.0 (X64) Sep 7 2018 01:37:51 版权所有 (c) Microsoft Corporation Enterprise Edition:Windows NT 6.3 上基于内核的许可(64 位)(内部版本 9600:)(管理程序)
这不是直接的答案,而是一些建议
你没有谈到从备份恢复为什么?你没有干净的备份。活动前是否没有进行完整的用户和系统数据库备份,如果没有,这是一个错误。
如果您有备份,则从服务器上的备份开始恢复(使用不同的名称)并并行查看您是否在步骤 1/2/3 中成功。如果您在一天结束时执行步骤失败,您将准备好数据库,并且可以将应用程序指向此,以避免“管理噪音”。
checkdb 建议
repair_allow_data_loss
作为最小修复,我很少在生产数据库上运行它,因为我知道它可能会删除它喜欢的任何东西,消除业务约束给我的数据库,就业务规则而言,它基本上是无用的。因此,如果您没有备份并且上述所有步骤都失败了,那么只能使用修复,如果您要起诉它,愿上帝与您同在。EIDT:(来自聊天)
感谢您解释,因此数据库当前正在运行,但 checkdb 报告了问题。您必须通知管理层存在腐败,他们迟早会开始面临异常。我认为他们仍然没有遇到这种情况的原因是因为损坏的页面仍未读入内存。
你应该做什么
通知利益相关者存在腐败,向他们展示信息。
从您拥有的任何备份开始恢复,您可能还需要将应用程序设置为只读。看看有多大区别
continue_after_error
如果失败,您是否也可以尝试备份当前损坏的数据库使用情况。如果存在损坏,备份很可能会失败。如果您成功恢复它continue_after_error
并运行 repair_allow_data_loss 以查看您会丢失多少数据。所以你已经确定了 2 个表导致了问题。尝试将数据从这 2 个表移到其他表,看看可以移动多少数据(创建新表,如 old_table_temp)。我要说的是,如果您能够从这两个表中移动大部分数据,并且如果您确定这是受损坏的影响,那么删除这些表并从您刚刚移动到其他表的数据中重新创建它。
在您删除并重新创建表并用新数据填充它之后再次运行 checkdb,看看它是否干净。
从恢复的备份中查看是否可以获取已删除的数据。
如果索引不是聚集索引的聚集索引,则删除和重新创建索引很可能会解决问题,它不会解决问题。
编辑:
哇,您有日志传送并希望数据库处于只读/待机模式,如果这样很好,请立即停止所有 LS 作业。如果它处于恢复模式并且您有企业版,请创建一个快照并在其上运行 checkdb。继续应用程序停机并在辅助数据库上运行 checkdb,如果它恢复正常,将其联机并将应用程序指向该数据库,您可能会侥幸逃脱并获得零数据丢失。
您可以尝试使用 NCI 看看是否可以解决任何问题,但我会依赖辅助数据库并希望不会传播损坏。
我知道这是很多工作,但我相信这会给您带来最少的数据丢失。
祝你好运