无法镜像数据库 SQL Server 2012

Bil*_*ill 11 sql-server t-sql alter-database

尝试使用以下命令镜像数据库时

ALTER AVAILABILITY GROUP SQLAlwaysonGroup ADD DATABASE test0916aj8CJ
Run Code Online (Sandbox Code Playgroud)

我收到以下错误

消息 1475,级别 16,状态 105,第 1 行
数据库“test0916aj8CJ”可能包含尚未备份的批量记录更改。在主体数据库或主数据库上进行日志备份。然后在镜像数据库上还原此备份以启用数据库镜像,或在每个辅助数据库上还原此备份以使其能够加入可用性组。

这可以在不支持数据库的情况下完成吗?或者我应该备份然后丢弃备份。它用于新创建的数据库,因此此时我不需要备份。

我尝试了以下...

BACKUP
DATABASE [test0916aj8CJ] TO DISK = N’NUL’
WITH COPY_ONLY, NOFORMAT, INIT,
NAME = N’test-Full Database Backup’,
SKIP, NOREWIND, NOUNLOAD
GO
Run Code Online (Sandbox Code Playgroud)

但上述方法也不起作用。

谢谢

Kin*_*hah 15

很容易重现你得到的错误

  • 在主数据库上以完全恢复模式创建数据库。
  • 在辅助中以完全恢复模式创建数据库。
  • 启动 GUI 并尝试在主要和次要之间配置镜像。

以下是您将得到的错误:

数据库“test_mirroring_kin”可能包含尚未备份的批量记录更改。在主体数据库或主数据库上进行日志备份。然后在镜像数据库上还原此备份以启用数据库镜像或在每个辅助数据库上还原此备份以使其能够加入可用性组。(Microsoft SQL Server,错误:1475)

在此处输入图片说明

让我们了解该错误是什么:

您将数据库配置为完全恢复模式,并认为数据库确实处于完全恢复模式。

以上是不正确的。创建数据库后,如果不做FULL备份,即使数据库处于FULL恢复模式,也是pseudo-SIMPLE恢复

您可以使用dbcc dbinfo--> dbi_dbbackupLSNhas value of 0:0:0(0x00000000:00000000:0000)or using Paul Randal's script轻松验证它

dbcc traceon (3604)
go
dbcc dbinfo('test_mirroring_kin') with tableresults
go
dbcc traceoff (3604)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

编辑:即使使用COPY_ONLY选项进行第一次完整备份也不会建立备份链

backup database test_mirroring_kin
to disk = 'D:\test_mirroring_kin_FULL.bak'
with init, stats=10, COPY_ONLY
Run Code Online (Sandbox Code Playgroud)

dbcc dbinfo-->dbi_dbbackupLSN仍然具有0:0:0(0x00000000:00000000:0000). 这意味着数据库仍处于伪简单恢复模式。

您需要做什么来解决上述错误?

您需要在主数据库上进行完整备份 + 一个事务日志备份,然后在辅助数据库上还原with norecovery,然后将数据库加入 AG 组或镜像。

作为旁注和完整性,为了您的脚本backup to NUL,请阅读 Gail Shaw 的这篇博文。


Jul*_*eur 6

为什么TO DISK = N’NUL’

我不明白你为什么使用TO DISK = N’NUL’

BACKUP
DATABASE [test0916aj8CJ] TO DISK = N’NUL’
Run Code Online (Sandbox Code Playgroud)

如果这样做,备份将保存到NUL,(即 = 无处/无)并且无法使用,因为其文件不存在。

虽然NUL也可以用作 LOG 备份的目的地,但也不应该使用它,尤其是在 Prod 服务器上,因为 LOG 将丢失并且备份链将被破坏。(~ 类似于SHRINKFILE)

日志备份

在向组中添加 DB 之前,您必须对其进行准备。当您要准备辅助 DB 时,必须进行至少 1 个事务日志备份并还原。镜像使用它来确定哪些事务已在辅助数据库上同步,哪些事务尚未与主数据库同步。

因此,您必须备份主数据库上的事务日志:

BACKUP LOG [test0916aj8CJ] TO  DISK = N'....bak' 
WITH  COPY_ONLY, FORMAT, INIT,  NAME = N'test0916aj8CJ-Transaction Log  Backup', STATS = 10
Run Code Online (Sandbox Code Playgroud)

COPY_ONLY必须使用该选项。它确保在日志备份结束时日志不会被截断。

主数据库备份链

但是,您不能单独恢复日志备份,这意味着没有备份链(也请参阅 Kin 的回答)。这意味着事务日志备份必须在完整数据库备份(如果需要的话,+ 一个可选的差异)完成后进行。

由于该COPY_ONLY选项不会破坏备份链,因此它也不会创建备份链。该COPY_ONLY选项不能用于数据库备份。

按顺序备份:

  • 没有COPY_ONLY选项的完整数据库备份
  • 可选差异备份
  • 1 个带COPY_ONLY选项的日志备份
  • 如有必要,另一个(或更多)日志备份...

恢复辅助数据库

然后必须在辅助数据库上还原(+ 差异)数据库备份。

它必须使用该NORECOVERY选项进行恢复,因为您还希望在恢复完整备份后恢复 LOG 备份。

最后,您将恢复日志备份。您仍然需要使用该NORECOVERY选项,因为一旦到位,镜像将继续恢复事务。

  • 使用NORECOVERY选项恢复完整备份
  • 使用NORECOVERY选项恢复 DIFF 备份
  • 使用该NORECOVERY选项按顺序恢复所有 LOG 备份

让我们把它们放在一起(使其适应您的环境)

  • 在主服务器上运行:

    USE master
    Go
    BACKUP DATABASE [test0916aj8CJ] TO DISK = N'....bak'
    WITH FORMAT, INIT, NAME = N'test0916aj8CJ-Full Database Backup', STATS = 10
    GO
    BACKUP LOG [test0916aj8CJ] TO DISK = N'....bak' 
    WITH COPY_ONLY, FORMAT, INIT, NAME = N'test0916aj8CJ-Transaction Log Backup', STATS = 10
    GO
    
    Run Code Online (Sandbox Code Playgroud)
  • 在辅助服务器上运行:

    USE master
    Go
    RESTORE DATABASE [test0916aj8CJ] FROM DISK = N'....bak' 
    WITH FILE = 1, NORECOVERY, NOUNLOAD, REPLACE, STATS = 10
    GO
    RESTORE LOG [test0916aj8CJ] FROM DISK = N'....bak' 
    WITH FILE = 1, NORECOVERY, NOUNLOAD, STATS = 10
    
    Run Code Online (Sandbox Code Playgroud)
  • 然后,您可以继续将新的辅助数据库添加到可用性组...

可选操作

  • 最好将 DISK 选项设置为可从主服务器和辅助服务器使用的共享文件夹。
  • 最好将 DB 文件存储在主服务器和辅助服务器上类似的磁盘和位置上。