我需要从我自己的过程中执行rds_restore_database存储过程,所以我需要在执行后立即获取task_id来执行rds_task_status以等待恢复成功。
我不知道恢复后如何获取变量中的task_id:
exec msdb.dbo.rds_restore_database 'whatever', 'S3_bucket_bak'
而且我不知道如何获取其他变量中的生命周期列来检查恢复状态:
exec [msdb].[dbo].[rds_task_status] @task_id=@mytaskid
我尝试的唯一方法是将结果插入到临时表中:
INSERT INTO #MyTempTable exec @task_id = msdb.dbo.rds_restore_database 'whatever', 'S3_bucket_bak'
但是每当我想检查恢复状态如何时,我都必须重新插入。
还有其他解决办法吗?
我能找到的最佳解决方法:
declare @my_task_id int
select top 1 @my_task_id = task_id from msdb.dbo.rds_fn_task_status(NULL,0) order by task_id desc
select @my_task_id task_id
或者,如果您想要做的与我相同,要停止代码执行直到所有任务完成,则以下操作应该有效:
declare @sec int = 0;
WHILE ((SELECT top 1 lifecycle FROM msdb.dbo.rds_fn_task_status(NULL,0) order by task_id desc) <> 'SUCCESS')
BEGIN
WAITFOR DELAY '00:00:10';
set @sec = @sec + 10
if @sec >= 1800 RAISERROR ('Timout. Copying from S3 to RDS server took more than 30 minutes.',16,1)
END
如果 rds 团队创建的存储过程只返回 task_id,那就好多了。但他们没有,所以..
我不知道表函数 rds_fn_task_status,所以感谢 Tor。然而,我对上述答案有一些小问题,即:它依赖于在运行时在 RDS 实例上启动的其他任务(因此,例如我们在单个实例上运行多个数据库,并且此脚本会导致我们问题)。此外,如果您的任务出错,您将等待整个超时期限,但仍然没有收到出错的指示(只是超时)。
因此我想提出一个小小的修改:
declare @sec int = 0;
declare @taskId int
declare @lifecycle nvarchar(50)
select @taskId = max(task_id) FROM msdb.dbo.rds_fn_task_status(NULL,0)
set @lifecycle = ''
WHILE @lifecycle NOT IN ('SUCCESS', 'ERROR')
BEGIN
SELECT @lifecycle = lifecycle FROM msdb.dbo.rds_fn_task_status(NULL,@taskId)
WAITFOR DELAY '00:00:10';
set @sec = @sec + 10
if @sec >= 1800 RAISERROR ('Timout. Copying from S3 to RDS server took more than 30 minutes.',16,1)
END
if @lifeCycle <> 'SUCCESS'
BEGIN
DECLARE @taskAsStr nvarchar(50)
SET @taskAsStr = CAST(@taskId as nvarchar(50))
RAISERROR (N'Error. Copying from S3 to RDS server raised an unexpected error for task %s',16,1, @taskAsStr)
END