AFAIK没有REST API直接提供此功能。因此,我通过Create请求使用restore(还有其他方法,但这些方法不能保证事务一致性,而且更复杂(。
由于无法关闭短时间备份(保留期必须至少为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分钟。如果通过Azure Portal(它失败并出现相同的错误btw(完成,这也是正确的,因为它不允许输入比当前-6分钟更新的时间。经过几次尝试,我发现目前的时间——大约40分钟——开始正常工作。但40分钟太多了,在我尝试等待异步操作的结果之前,我并没有找到任何方法来确定什么时间有效。
我的问题是:有没有办法找到恢复的最晚时间?
或者,有没有更好的方法来"复制"托管数据库,从而保证事务一致性并相当快速?
编辑:
我所描述的问题已报告给MS。它发生在:
- 有一种自定义时区格式,例如UTC+1小时
- 在所需的时间点跳过源数据库的备份,因为该数据库处于非活动状态(没有活动事务(
截至目前(2021年8月25日(,这应该是固定的,我无法在当前时间-10分钟内复制它。此外,我被告知应该有新的API,它将允许在不使用PITR的情况下进行复制(最早在22年第1季度(。
回答您的第一个问题"有没有办法找到恢复的最晚时间">
是的。通过SQL。找到这一点的唯一方法是使用扩展事件(XEvent(会话来监视备份活动。
此处描述了开始记录backup_restore_progress_trace扩展事件并报告该事件的过程https://learn.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://learn.microsoft.com/en-us/azure/azure-sql/database/recovery-using-backups)
回答你的第二个问题:;或者,有没有更好的方法来"复制"托管数据库,从而保证事务一致性并相当快速">
我不得不同意Thomas的观点——如果你想要有保证的事务一致性和速度,你需要考虑创建一个故障转移组https://learn.microsoft.com/en-us/azure/azure-sql/database/auto-failover-group-overview?tabs=azure-powershell#sql托管实例和https://learn.microsoft.com/en-us/azure/azure-sql/managed-instance/failover-group-add-instance-tutorial?tabs=azure-入口
托管实例的故障转移组将有一个主服务器和故障转移服务器,每个服务器上的相同用户数据库保持同步。
但是的,这是否适合你的需求取决于托马斯问的复制品的目的是什么。