具有手动播种的分布式可用性组

Alf*_*f47 11 sql-server sql-server-2017 distributed-availability-groups

我正在寻找有关如何使用手动播种设置分布式可用性组的分步演练。我可以让自动播种工作,但是当我尝试手动播种时,我无法将辅助数据库放入转发器上的 AG。

如果我在尝试将数据库添加到常规 AG 之前将分布式 AG 添加到辅助服务器,则会收到以下消息:

Msg 41190, Level 16, State 7, Line 22
Availability group 'MYDB' failed to process add-database command.  The local availability replica is not in a state that could process the command.  Verify that the availability group is online and that the local availability replica is the primary replica, then retry the command. 
Run Code Online (Sandbox Code Playgroud)

如果我尝试先添加数据库而不加入辅助数据库上的分布式 AG,我会收到以下消息,因为它认为它应该是主数据库:

Msg 927, Level 14, State 2, Line 22
Database 'MYDB' cannot be opened. It is in the middle of a restore.
Run Code Online (Sandbox Code Playgroud)

我对自动播种没有这些问题。一切都神奇地起作用。我在网上找到的所有示例都使用自动播种。

提前致谢

Pet*_*ier 9

特尔;博士:

听起来像在当前的描述和评论,您可能已经加入DAG之前添加数据库到公司的发展。相反,先加入 DAG,然后按以下顺序添加数据库:

  1. 创建AG1
    • 将数据库添加到 AG1
  2. 创建 AG2(无数据库)
  3. 创建 DAG
    • 将 AG 1 和 2 从 AG1 加入到 DAG
    • 将 AG 1 和 2 从 AG2 加入到 DAG
  4. 将数据库添加到 AG2
  5. 利润?

长(er)形式的答案

假设很多事情,比如......

  1. 监听器/集群/实例已经配置
  2. 已经有AG了...
    • PRIMARY和 上FORWARDER
    • 那不是同一个AG
    • 并且都不是另一个 DAG 的成员
    • 并且FORWARDERAG 是空的并准备播种
  3. 您拥有可从两个副本访问的共享存储

... 你可以...以下脚本是sqlcmd格式。

步骤 0. 禁用日志备份|OLD_AG|(可选)

如果出现以下情况,您可以忽略此步骤:

  1. 如果你不介意在过程的最后一个潜在的“移动目标”LSN 或者
  2. 您可以在AG中所有数据库的日志备份窗口内完成整个过程

步骤 1. 创建 DAG

CREATE一次在当前的主要和ALTER ... JOIN潜在的转发器上。作为适当的服务帐户执行,这样您就不会最终获得用户帐户拥有的部分架构。

在当前PRIMARY...

:connect |OLD_AG|.|DOMAIN|
execute as login = 'sa'

-- double check local replica is manual seeding first
alter availability group [|OLD_AG|]
    modify replica on '|THIS_REPLICA|'
    with (seeding_mode = manual);

create availability group [|DAG_X|]
    with (distributed)
    availability group on 
        '|OLD_AG|' with ( 
            listener_url      = 'TCP://|OLD_AG|.|DOMAIN|:|PORT|',
            availability_mode = synchronous_commit,
            failover_mode     = manual,
            seeding_mode      = manual 
        ),
        '|NEW_AG|' with ( 
            listener_url      = 'TCP://|NEW_AG|.|DOMAIN|:|PORT|',
            availability_mode = synchronous_commit,
            failover_mode     = manual,
            seeding_mode      = manual 
        );
go
Run Code Online (Sandbox Code Playgroud)

在前瞻性FORWARDER...

:connect |NEW_AG|.|DOMAIN|
execute as login = 'sa'

alter availability group [|DAG_X|]
    join availability group on 
        '|OLD_AG|' with ( 
            listener_url      = 'TCP://|OLD_AG|.|DOMAIN|:|PORT|',
            availability_mode = synchronous_commit,
            failover_mode     = manual,
            seeding_mode      = manual 
        ),
        '|NEW_AG|' with ( 
            listener_url      = 'TCP://|NEW_AG|.|DOMAIN|:|PORT|',
            availability_mode = synchronous_commit,
            failover_mode     = manual,
            seeding_mode      = manual 
        );
go
Run Code Online (Sandbox Code Playgroud)

步骤 2. 完整备份

你知道吗,你可以追加日志备份copy_only充盈?直到最近我也没有!但是通过使用copy_only这里你可以

  1. 保护您的备份链免受任何迁移错误和
  2. 在过程结束时减少恢复链的长度。

exec as... 这一步不是绝对必要的。

:connect |OLD_AG|.|DOMAIN|

backup database DB1 to disk = N'\\my.shared.storage\backups\DB1.bak' 
    with copy_only, compression;
backup database DB2 to disk = N'\\my.shared.storage\backups\DB2.bak' 
    with copy_only, compression;
go
Run Code Online (Sandbox Code Playgroud)

步骤 3. 恢复

再次作为适当的服务帐户执行。

:connect |NEW_AG|.|DOMAIN|
execute as login = 'sa'

restore database DB1 from disk = N'\\my.shared.storage\backups\DB1.bak' 
    with norecovery;
restore database DB2 from disk = N'\\my.shared.storage\backups\DB2.bak' 
    with norecovery;
go
Run Code Online (Sandbox Code Playgroud)

步骤 3(b)。您是否保留了日志备份?

Nbd,但现在追加它们¯\_(?)_/¯

  1. 作为适当的服务帐户执行
  2. with norecovery

步骤 4. 在 Forwarder 上,将 DB 加入新的 AG

:connect |NEW_AG|.|DOMAIN|
execute as login = 'sa'

alter database DB1 set hadr availability group = [|NEW_AG|];
alter database DB2 set hadr availability group = [|NEW_AG|];
go
Run Code Online (Sandbox Code Playgroud)