在安装了 SQL Server 2019 标准版的服务器上,我们的数据库都没有启用加速数据库恢复,但当我运行 DMV - 时sys.dm_db_index_physical_stats
,该列version_record_count
显示非零值。
问题是,如果禁用此功能,那么为什么 DMV 告诉我为每个数据库中的表保留行版本?
有问题的数据库正在使用快照隔离,但我本以为版本将存储在 tempdb 中。
在安装了 SQL Server 2019 标准版的服务器上,我们的数据库都没有启用加速数据库恢复,但当我运行 DMV - 时sys.dm_db_index_physical_stats
,该列version_record_count
显示非零值。
问题是,如果禁用此功能,那么为什么 DMV 告诉我为每个数据库中的表保留行版本?
有问题的数据库正在使用快照隔离,但我本以为版本将存储在 tempdb 中。
我正在运行下面的查询来查找数据超出配置的保留深度的 CDC 表:
SELECT DB_ID() AS database_id, ct.capture_instance, object_id, source_object_id
, rcounts.source_table_rows
, rcounts.ct_table_rows
, ct_pstats.used_page_count
, source_pstats.used_page_count
, sys.fn_cdc_map_lsn_to_time(sys.fn_cdc_get_min_lsn(ct.capture_instance))
from cdc.change_tables AS ct
outer apply
(
select source_table_rows = (SELECT SUM(rows) FROM sys.partitions AS p WHERE p.object_id = ct.source_object_id AND p.index_id <= 1)
, ct_table_rows = (SELECT SUM(rows) FROM sys.partitions AS p WHERE p.object_id = ct.object_id AND p.index_id <= 1)
) as rcounts
outer apply
(
select used_page_count = SUM(used_page_count)
from sys.dm_db_partition_stats AS ps
where ps.object_id = ct.object_id
) AS ct_pstats
outer apply
(
select used_page_count = SUM(used_page_count)
from sys.dm_db_partition_stats AS ps
where ps.object_id = ct.source_object_id
) AS source_pstats
outer apply
(
select *
from msdb.dbo.cdc_jobs
where job_type = 'cleanup'
and database_id = DB_ID()
) as cleanup
WHERE DATEADD(minute, 60*25, sys.fn_cdc_map_lsn_to_time(sys.fn_cdc_get_min_lsn(ct.capture_instance))) < DATEADD(minute, -cleanup.retention, GETDATE())
这会返回大量结果,其中最短 lsn 时间与配置的 CDC 保留时间之间的差距超过 25 小时。
配置的保留时间为 5000 分钟,在撰写本文时,最小 lsn 时间超过 5800 分钟。
为了尝试解决这个问题,我手动执行了该cdc.cleanup
作业。它已成功完成,但没有进行任何更改。
sp_cdc_cleanup_change_table
然后,我手动执行每个捕获实例的过程,它们成功完成,但同样没有进行任何更改。
EXEC sys.sp_cdc_cleanup_change_table @capture_instance = '...', @low_water_mark = NULL, @threshold = 5000;
我们怀疑此问题与大约在同一时间发生的故障转移有关,但从那时起我们已经故障转移回原始主副本。
谁能建议如何解决清理中的延迟问题,而无需禁用并重新启用 CDC?
谢谢
环境详情:
我的程序如下:
set [tb1].[SLD_VAR] = case when [CalendarDate] = [tb1].[FileDate] and ([tb2].[SLD] - [tb2].[LAG_SLD])/([tb2].[SLD]+1) >= 0.15 then 1 else 0 end,
[tb1].[StartingDate_VAR] = case when [CalendarDate] = [tb1].[FileDate] and [tb2].[StartingDate] <> [tb2].[LAG_StartingDate] then 1 else 0 end,
[tb1].[ClosingDate_VAR] = case when [CalendarDate] = [tb1].[FileDate] and [tb2].[ClosingDate] <> [tb2].[LAG_ClosingDate] then 1 else 0 end,
[tb1].[CurrentStatus_VAR] = case when [CalendarDate] = [tb1].[FileDate] and [tb2].[CurrentStatus] <> [tb2].[LAG_CurrentStatus] then 1 else 0 end,
[tb1].[Rate_VAR] = case when [CalendarDate] = [tb1].[FileDate] and [tb2].[Rate] <> [tb2].[LAG_Rate] then 1 else 0 end,
[tb1].[COF_VAR] = case when [CalendarDate] = [tb1].[FileDate] and [tb2].[COF] <> [tb2].[LAG_COF] then 1 else 0 end,
[tb1].[Term_VAR] = case when [CalendarDate] = [tb1].[FileDate] and [tb2].[Term] <> [tb2].[LAG_Term] then 1 else 0 end,
[tb1].[Term_GT_VAR] = case when [CalendarDate] = [tb1].[FileDate] and [tb2].[Term_GT] <> [tb2].[LAG_Term_GT] then 1 else 0 end
from [DataTable] as [tb1]
left join (
select [Filedate]
,cast([Deal] as inT) as [Deal]
,[SLD]
,[CurrentStatus]
,[StartingDate]
,[ClosingDate]
,[Rate]
,[COF]
,[Term],
DATEDIFF(dd,[ApplicationDate],[ClosingDate]) as [Term_GT],
LAG([StartingDate],1) over (partition BY [Deal] order by [FileDate]) as [LAG_StartingDate],
LAG([ClosingDate],1) over (partition BY [Deal] order by [FileDate]) as [LAG_ClosingDate],
LAG([CurrentStatus],1) over (partition BY [Deal] order by [FileDate]) as [LAG_CurrentStatus],
LAG([Rate],1) over (partition BY [Deal] order by [FileDate]) as [LAG_Rate],
LAG([COF],1) over (partition BY [Deal] order by [FileDate]) as [LAG_COF],
LAG([SLD],1) over (partition BY [Deal] order by [FileDate]) as [LAG_SLD],
LAG([Term],1) over (partition BY [Deal] order by [FileDate]) as [LAG_Term],
LAG(DATEDIFF(dd,[ApplicationDate],[ClosingDate]),1) over (partition BY [Deal] order by [FileDate]) as [LAG_Term_GT]
from [DataTable]
where [FileDate] >= DATEADD( day, -14, @Date)
) as [tb2]
on [tb1].[Filedate] = [tb2].[Filedate]
and [tb1].[Deal] = [tb2].[Deal]
where [tb1].[CalendarDate] >= @DateProd
end
将CalendarDate
和Deal
一起作为 PrimaryKey,我创建了一些索引,但仍然需要相当长的时间来执行,并且我需要每周运行此过程。请帮助我制定一些优化策略。
我有一个 SQL Server 代理作业,旨在重新配置自身以响应作业启动时的条件。
因此,本质上,第一步更新了第二步。这种情况是正确的,但 SQL Server 代理进程似乎不知道第二步已更新,并运行了步骤 2 命令的旧缓存副本。我尝试添加sp_update_job
到第一步,试图让代理进程更新其缓存,但并不高兴。
这是一个mcve供您欣赏:
BEGIN TRANSACTION
DECLARE @ReturnCode INT
SELECT @ReturnCode = 0
IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name=N'[Uncategorized (Local)]' AND category_class=1)
BEGIN
EXEC @ReturnCode = msdb.dbo.sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'[Uncategorized (Local)]'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
END
DECLARE @jobId BINARY(16)
EXEC @ReturnCode = msdb.dbo.sp_add_job @job_name=N'Test self-updating job',
@enabled=1,
@notify_level_eventlog=0,
@notify_level_email=0,
@notify_level_netsend=0,
@notify_level_page=0,
@delete_level=0,
@description=N'No description available.',
@category_name=N'[Uncategorized (Local)]',
@owner_login_name=N'sa', @job_id = @jobId OUTPUT
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'step 1 - update step 2',
@step_id=1,
@cmdexec_success_code=0,
@on_success_action=3,
@on_success_step_id=0,
@on_fail_action=2,
@on_fail_step_id=0,
@retry_attempts=0,
@retry_interval=0,
@os_run_priority=0, @subsystem=N'TSQL',
@command=N'USE [msdb];
GO
DECLARE @job_name sysname = N''Test self-updating job'';
DECLARE @command nvarchar(max);
IF EXISTS
(
SELECT 1
FROM [msdb].[dbo].[sysjobsteps] [sjs]
INNER JOIN [msdb].[dbo].[sysjobs] [sj] ON [sjs].[job_id] = [sj].[job_id]
WHERE [sj].[name] = N''Test self-updating job''
AND [sjs].[step_id] = 2
AND [sjs].[command] = N''PRINT N''''A'''';''
)
BEGIN
SET @command = N''PRINT N''''B'''';'';
END
ELSE
BEGIN
SET @command = N''PRINT N''''A'''';'';
END;
EXEC [msdb].[dbo].[sp_update_jobstep] @job_name = @job_name, @step_id = 2, @command = @command;
EXEC [msdb].[dbo].[sp_update_job] @job_name = @job_name, @automatic_post = 1;
',
@database_name=N'master',
@flags=0
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'step 2 - do the work',
@step_id=2,
@cmdexec_success_code=0,
@on_success_action=1,
@on_success_step_id=0,
@on_fail_action=2,
@on_fail_step_id=0,
@retry_attempts=0,
@retry_interval=0,
@os_run_priority=0, @subsystem=N'TSQL',
@command=N'PRINT N''A'';',
@database_name=N'master',
@flags=0
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId, @start_step_id = 1
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N'(local)'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
COMMIT TRANSACTION
GOTO EndSave
QuitWithRollback:
IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION
EndSave:
GO
测试作业从第二步开始,在打印A
或B
每次运行之间交替。即第一次运行时,应该打印B
,然后下次运行时应该打印A
,然后下次运行时,应该打印,B
依此类推。
运行作业并检查作业历史记录显示输出为A
,但是检查第二步的命令显示输出为PRINT N'B';
。因此,步骤命令正在更新,但代理实际上正在运行旧的预更新步骤代码。
有没有办法让 SQL Server 代理运行步骤 2 中更新的代码而不是旧的过时代码?
在实际工作中,第二步是使用代理运行的 cmdExec 命令,因此我不能仅在一步中使用动态 SQL。
复制在其他服务器上工作正常,但是在 DB_B 上存在一些问题;它无法接收档案。
有人可以帮我吗?如果我遗漏了任何参数,请告诉我。
编辑:主要是 DB_A,DR 是 DB_B
主节点上的配置
NAME TYPE VALUE
------------------ ------ -------------------------------------------------------------------------------------
log_archive_dest_5 string service=DB_B ASYNC valid_for=(online_logfile,all_roles) db_unique_name=DB_B
NAME TYPE VALUE
---------- ------ ----------------------------------
fal_client string DB_A
fal_server string DB_C, DB_D, DB_E, DB_B
NAME TYPE VALUE
------------------ ------ ---------------------------------------------------
log_archive_config string DG_CONFIG=(DB_C,DB_D,DB_E,DB_B,DB_A)
TNSPing 也成功
关于灾难恢复
NAME TYPE VALUE
------------------------------------ ----------- --------------------------------
fal_client string DB_B
fal_server string DB_C, DB_D, DB_E, DB_A
NAME TYPE VALUE
------------------------------------ ----------- --------------------------------------------------
log_archive_config string dg_config=(DB_C,DB_A,DB_E,DB_D,DB_B)
我刚刚要求基础设施向 sql server 盒子添加内存,现在总内存为 16Gb
我已将sql server中的最大内存设置为12GB。
当我运行下面的内存查询时:
SELECT [ServerName]=@@servername,
[Setting Name]=name,
value,
value_in_use,
[Value (GB)]=CONVERT(decimal(12,2),CONVERT(decimal(12,2), value_in_use)/1024.00),
[description]
FROM master.sys.configurations with(nolock)
WHERE name like '%server memory%'
ORDER BY name OPTION (RECOMPILE);
--Msg 260, Level 16, State 3, Line 12
--Disallowed implicit conversion from data type sql_variant to data type numeric,
--table 'master.sys.configurations', column 'value_in_use'.
--Use the CONVERT function to run this query.
SELECT
CONVERT(decimal(12,2),physical_memory_in_use_kb/1024.00/1024.00 ) AS sql_physical_memory_in_use_GB,
CONVERT(decimal(12,2),large_page_allocations_kb/1024.00/1024.00) AS sql_large_page_allocations_GB,
CONVERT(decimal(12,2),locked_page_allocations_kb/1024.00/1024.00) AS sql_locked_page_allocations_GB,
CONVERT(decimal(12,2),virtual_address_space_reserved_kb/1024.00/1024.00) AS sql_VAS_reserved_GB,
CONVERT(decimal(12,2),virtual_address_space_committed_kb/1024.00/1024.00) AS sql_VAS_committed_GB,
CONVERT(decimal(12,2),virtual_address_space_available_kb/1024.00/1024.00) AS sql_VAS_available_GB,
REPLACE(CONVERT(VARCHAR(50),CAST(page_fault_count AS MONEY),1), '.00','') AS page_fault_count,
memory_utilization_percentage AS sql_memory_utilization_percentage,
CASE WHEN process_physical_memory_low = 1 THEN 'Yes' ELSE 'No' END AS sql_process_physical_memory_low,
CASE WHEN process_virtual_memory_low = 1 THEN 'Yes' ELSE 'No' END AS sql_process_virtual_memory_low
FROM sys.dm_os_process_memory;
SELECT CONVERT(decimal(12,2),committed_kb/1024.00/1024.00 ) AS [SQL Server Committed Memory in GB],
CONVERT(decimal(12,2),committed_target_kb/1024.00/1024.00 ) AS [SQL Server Target Committed Memory in GB],
CONVERT(decimal(12,2),physical_memory_kb/1024.00/1024.00 ) AS [Server Physical Memory in GB],
sql_memory_model_desc
FROM sys.dm_os_sys_info;
我明白了:
问题:
为什么sql server内存不是12GB?
表达用户与其直接经理之间关系的正确句子是什么:
我认为第二个选项是正确的句子,因为它建议在用户表中使用类型引用(外键)的字段来建立用户与其经理之间的直接关系
我已经为 MS SQL Server 2022 设置了差异备份,并且想知道数据库中的每个表对差异备份大小的贡献有多大。
下面的页面显示了如何获取数据库级别的信息,但我想查看自上次完整备份以来每个表级别的更改范围百分比。
有没有办法做到这一点?
我想知道哪些表正在更新以及它们为差异备份贡献了多少字节。当然,这个数字会随着时间的推移而增长,直到进行新的完整备份。
这是停车场面试问题的一部分,要求候选人设计停车场系统。停车场的设计实体是一个值得讨论的问题。但我被困在我们必须为车辆分配停车位的部分。
假设我们正在使用外部数据存储来实现停车场问题。并且有很多并发请求,请求停车位。最基本的实现是,
为每个停车位创建单独的数据库行,列可用性为真/假。
每当车辆到来时,找到一个可用的插槽(假设插槽 ID X)
使用乐观锁定将 DB 的可用性更新为 false(即,如果 slotid=X 且可用性 =false 则更新)
上述方法在高并发场景中效果不佳,因为可能会为多个车辆分配相同的槽位,并且步骤 3 对于所有这些车辆都会失败,我们必须从步骤 2 再次重试。
为了最佳地处理这个问题,我应该合并步骤 2、3 并将分配卸载到数据库本身。新流程应如下所示
在 SQl DB 中可以这样做吗?是否有其他方法来实现此功能。