当我在 Azure SQL 数据库上发现一些奇怪的东西时,我正在学习 RCSI。
DMVsys.dm_tran_version_store_space_usage
始终将 0 报告为版本存储使用的空间,即使我之前运行了 CRUD 工作负载。
为了演示这种行为,我创建了一个小测试。
-- Server info
select @@version as sql_version;
-- Database info
select
is_read_committed_snapshot_on,
snapshot_isolation_state_desc
from sys.databases
where database_id = db_id();
-- Just to be sure the current database has its version store empty
select reserved_page_count as pre_workload_space_count
from sys.dm_tran_version_store_space_usage
where database_id = db_id();
-- Test workload
drop table if exists RCSI_TEST;
create table RCSI_TEST (
id uniqueidentifier default newid()
);
go
insert into RCSI_TEST default values;
go 100
update RCSI_TEST
set id = newid();
delete from RCSI_TEST;
-- Metrics
select reserved_page_count as post_workload_page_count
from sys.dm_tran_version_store_space_usage
where database_id = db_id();
waitfor delay '00:01:30'; -- Just to be sure! ;)
select reserved_page_count as post_cleaning_space_count
from sys.dm_tran_version_store_space_usage
where database_id = db_id();
我在 SQL Server 2019 Developer Edition(在 Docker 上)和 Azure SQL 数据库(层 S0、10DTU)上运行了这个脚本,结果如下。
SQL Server 2019
sql_version
Microsoft SQL Server 2019 (RTM-CU8) (KB4577194) - 15.0.4073.23 (X64)Sep 23 2020 16:03:08 Copyright (C) 2019 Microsoft Corporation Developer Edition (64-bit) on Linux (Ubuntu 18.04.5 LTS) <X64>
is_read_committed_snapshot_on snapshot_isolation_state_desc
1 ON
pre_workload_space_count
0
post_workload_page_count
8
post_cleaning_space_count
0
Azure SQL 数据库
sql_version
Microsoft SQL Azure (RTM) - 12.0.2000.8 Oct 1 2020 18:48:35 Copyright (C) 2019 Microsoft Corporation
is_read_committed_snapshot_on snapshot_isolation_state_desc
1 ON
pre_workload_space_count
0
post_workload_page_count
0
post_cleaning_space_count
0
SQL Server 2019 似乎表现正确,在工作负载之后立即在版本存储中报告 8 页的数据,然后在一分钟左右后清理。但是,在 Azure SQL 数据库上,使用的空间始终为零!这是正确的行为吗?这是什么意思?
联机丛书报告此 DMV 与 SQL Server 和 Azure SQL 数据库兼容,但还说“以下查询可用于确定 tempdb 中消耗的空间,按SQL Server 实例中每个数据库的版本存储。 ”。据我所知,Azure SQL 数据库在设计上对其父实例的范围确实有限。这可能是根本原因吗?
我知道 Azure SQL 数据库默认在 RCSI 下运行,并且它们具有基于您获得的层的固定数量的 tempdb 空间,所以我担心用长时间运行的事务或其他进程来填充它,在版本存储太久。但我无法管理我无法衡量的东西,对吧?
Azure SQL 数据库使用加速数据库恢复,因此 RCSI 不使用 TempDb 作为版本存储。相反,版本存储在数据库内部以启用“即时事务回滚”,这在故障转移期间尤为重要:
加速数据库恢复
因此,您应该查看
sys.dm_tran_persistent_version_store_stats
或查看一般管理加速数据库恢复