【问题标题】:How to copy managed database?如何复制托管数据库?
【发布时间】:2021-06-15 09:32:34
【问题描述】:

AFAIK 没有 REST API 直接提供此功能。因此,我通过Create request 使用还原(还有其他方法,但不能保证事务一致性并且更复杂)。

由于无法关闭短时间备份(保留时间必须至少为 1 天),因此它应该是可靠的。我在请求中使用“properties.restorePointInTime”属性的当前时间。这适用于大多数数据库。但是一个数据库向我返回了这个错误(来自异步操作请求):

"error": {
    "code": "BackupSetNotFound",
    "message": "No backups were found to restore the database to the point in time 6/14/2021 8:20:00 PM (UTC). Please contact support to restore the database."
}

我知道我没有超出范围,因为如果恢复时间早于“earliestRestorePoint”(这可以在托管数据库的 GET 请求中找到),或者将来我会收到“PitrPointInTimeInvalid”错误。尽管如此,我还是发现了一些信息,我不应该使用当前时间,而是使用当前时间 - 最多 6 分钟。如果通过不允许输​​入比当前时间更新的时间 - 6 分钟通过 Azure 门户(它失败并出现相同的错误顺便说一句)完成,这也是正确的。经过几次尝试,我发现当前时间 - 大约 40 分钟开始正常工作。但是 40 分钟太多了,在我尝试等待异步操作的结果之前,我没有找到任何方法来找出什么时间有效。

我的问题是:有没有办法找到最晚的恢复时间?

或者有没有更好的方法来“复制”托管数据库,以保证事务一致性并且相当快?

编辑:
我所描述的问题已报告给 MS。它发生在:

  1. 有自定义时区格式,例如UTC + 1 小时。
  2. 在所需时间点跳过源数据库的备份,因为数据库处于非活动状态(无活动事务)。

这应该从现在(2021 年 8 月 25 日)开始修复,我无法在当前时间 - 10 分钟内重现它。我还被告知应该有新的 API 允许在不使用 PITR 的情况下进行复制(不早于 1Q/22)。

【问题讨论】:

  • 复制的目的是什么?您是否尝试过异地复制/故障转移组?
  • 我需要确保 db 在后续操作期间不会更改(并且不介意它是几分钟的“旧”)。我想通过 sqlpackage 工具进行备份。但我不希望对原始数据库有任何额外负载,并希望保证事务一致性。

标签: azure copy database-restore azure-managed-database


【解决方案1】:

回答您的第一个问题“有没有办法找到可能的最晚恢复时间?”

是的。通过 SQL。找出这一点的唯一方法是使用扩展事件 (XEvent) 会话来监控备份活动。

此处描述了开始记录 backup_restore_progress_trace 扩展事件并报告它的过程https://docs.microsoft.com/en-us/azure/azure-sql/managed-instance/backup-activity-monitor

在此处包含 SQL,以防链接失效。

这是用于存储在环形缓冲区中(最多最后 1000 条记录):

CREATE EVENT SESSION [Verbose backup trace] ON SERVER 
ADD EVENT sqlserver.backup_restore_progress_trace(
    WHERE (
              [operation_type]=(0) AND (
              [trace_message] like '%100 percent%' OR 
              [trace_message] like '%BACKUP DATABASE%' OR [trace_message] like '%BACKUP LOG%'))
       )
ADD TARGET package0.ring_buffer
WITH (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,
       MAX_DISPATCH_LATENCY=30 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,
       TRACK_CAUSALITY=OFF,STARTUP_STATE=ON)

ALTER EVENT SESSION [Verbose backup trace] ON SERVER
STATE = start;

然后查看所有备份事件的输出:

WITH
a AS (SELECT xed = CAST(xet.target_data AS xml)
FROM sys.dm_xe_session_targets AS xet
JOIN sys.dm_xe_sessions AS xe
ON (xe.address = xet.event_session_address)
WHERE xe.name = 'Verbose backup trace'),
b AS(SELECT
d.n.value('(@timestamp)[1]', 'datetime2') AS [timestamp],
ISNULL(db.name, d.n.value('(data[@name="database_name"]/value)[1]', 'varchar(200)')) AS database_name,
d.n.value('(data[@name="trace_message"]/value)[1]', 'varchar(4000)') AS trace_message
FROM a
CROSS APPLY  xed.nodes('/RingBufferTarget/event') d(n)
LEFT JOIN master.sys.databases db
ON db.physical_database_name = d.n.value('(data[@name="database_name"]/value)[1]', 'varchar(200)'))
SELECT * FROM b

注意:当我遇到相同的时间点恢复问题似乎随机失败时,我通过 Microsoft 支持向我提供了此提示。他们没有为日志备份提供任何 SLA。我发现在繁忙的数据库上,日志备份似乎每 5-10 分钟发生一次,但在安静的数据库上每小时发生一次。以这种方式恢复数据库可能会很慢,具体取决于事务日志的数量和要重放的活动量等。(https://docs.microsoft.com/en-us/azure/azure-sql/database/recovery-using-backups)

回答您的第二个问题:“或者有没有更好的方法来‘复制’托管数据库,以保证事务一致性并且相当快?”

我必须同意 Thomas - 如果您想要保证事务一致性和速度,您需要考虑创建故障转移组 https://docs.microsoft.com/en-us/azure/azure-sql/database/auto-failover-group-overview?tabs=azure-powershell#best-practices-for-sql-managed-instancehttps://docs.microsoft.com/en-us/azure/azure-sql/managed-instance/failover-group-add-instance-tutorial?tabs=azure-portal

托管实例的故障转移组将有一个主服务器和故障转移服务器,每个服务器上的相同用户数据库保持同步。

但是是的,这是否适合您的需要取决于 Thomas 提出的副本的目的是什么。

【讨论】:

  • 谢谢!您知道这是否适用于使用服务管理的透明数据加密 (TDE) 加密的数据库吗?
  • 抱歉@robot40q 我不确定。
猜你喜欢
  • 2020-11-30
  • 2011-02-13
  • 2020-06-06
  • 2023-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-22
相关资源
最近更新 更多