Eug*_*kov 11 t-sql sql-server azure
我们有在Azure SQL表中写入日志的应用程序.该表的结构如下.
CREATE TABLE [dbo].[xyz_event_history]
(
[event_history_id] [uniqueidentifier] NOT NULL,
[event_date_time] [datetime] NOT NULL,
[instance_id] [uniqueidentifier] NOT NULL,
[scheduled_task_id] [int] NOT NULL,
[scheduled_start_time] [datetime] NULL,
[actual_start_time] [datetime] NULL,
[actual_end_time] [datetime] NULL,
[status] [int] NOT NULL,
[log] [nvarchar](max) NULL,
CONSTRAINT [PK__crg_scheduler_event_history] PRIMARY KEY NONCLUSTERED
(
[event_history_id] ASC
)
)
Run Code Online (Sandbox Code Playgroud)
表按scheduled_task_id列存储为聚簇索引(非唯一).
CREATE CLUSTERED INDEX [IDX__xyz_event_history__scheduled_task_id] ON [dbo].[xyz_event_history]
(
[scheduled_task_id] ASC
)
Run Code Online (Sandbox Code Playgroud)
该event_history_id应用程序生成的,它是随机的(不是连续的)GUID.应用程序可以从表中创建,更新和删除旧实体.该log列通常包含2-10 KB的数据,但在某些情况下它可以增长到5-10 MB.这些项目通常由PK(event_history_id)访问,最常见的排序顺序是event_date_time desc.
我们将Azure SQL的性能层降低到"S3"(100 DTU)后看到的问题是跨越事务日志速率限制.可以在sys.dm_exec_requests表中清楚地看到 - 将有等待类型LOG_RATE_GOVERNOR(msdn)的记录.
DB等待配额写入日志时发生.
我注意到对日志速率造成重大影响的操作是列的删除 xyz_event_history和更新log.更新以下列方式进行.
UPDATE xyz_event_history
SET [log] = COALESCE([log], '') + @log_to_append
WHERE event_history_id = @id
Run Code Online (Sandbox Code Playgroud)
Azure SQL数据库的恢复模型是FULL且无法更改.
这是物理索引统计信息 - 有许多页面每行限制超过8K.
TableName AllocUnitTp PgCt AvgPgSpcUsed RcdCt MinRcdSz MaxRcdSz xyz_event_history IN_ROW_DATA 4145 47.6372868791698 43771 102 7864 xyz_event_history IN_ROW_DATA 59 18.1995058067705 4145 11 19 xyz_event_history IN_ROW_DATA 4 3.75277983691623 59 11 19 xyz_event_history IN_ROW_DATA 1 0.914257474672597 4 11 19 xyz_event_history LOB_DATA 168191 97.592290585619 169479 38 8068 xyz_event_history IN_ROW_DATA 7062 3.65090190264393 43771 38 46 xyz_event_history IN_ROW_DATA 99 22.0080800593032 7062 23 23 xyz_event_history IN_ROW_DATA 1 30.5534964170991 99 23 23 xyz_event_history IN_ROW_DATA 2339 9.15620212503089 43771 16 38 xyz_event_history IN_ROW_DATA 96 8.70488015814184 2339 27 27 xyz_event_history IN_ROW_DATA 1 34.3711391153941 96 27 27 xyz_event_history IN_ROW_DATA 1054 26.5034840622683 43771 28 50 xyz_event_history IN_ROW_DATA 139 3.81632073140598 1054 39 39 xyz_event_history IN_ROW_DATA 1 70.3854707190511 139 39 39
更新(4月20日):
我已经在答案中做了一些实验和建议,并且对于差异INSERT而不是UPDATE制造印象深刻.
按照以下关于SQL Server事务日志内部的msdn文章(https://technet.microsoft.com/en-us/library/jj835093(v=sql.110).aspx):
数据修改的日志记录记录所执行的逻辑操作,或者记录修改数据的前后图像.前映像是执行操作之前的数据副本; 后图像是执行操作后的数据副本.
这会自动使场景在事务日志使用方面UPDATE ... SET X = X + 'more' 效率极低 - 它需要"在映像之前"捕获.
我创建了简单的测试套件来测试向"log"列添加数据的原始方式,而不是我们只是将新数据插入新表的方式.结果我非常惊讶(至少对我来说,对SQL Server的人不太熟悉).
测试很简单:5'000次添加1'024个字符长的日志部分 - 结果只有5MB的文本(不像人们想象的那么糟糕).
FULL recovery mode, SQL Server 2014, Windows 10, SSD
UPDATE INSERT
Duration 07:48 (!) 00:02
Data file grow ~8MB ~8MB
Tran. Log grow ~218MB (!) 0MB (why?!)
只增加1KB数据的5000个更新可以挂出SQL Server 8分钟(哇!) - 我没想到!
我认为原始问题已在此时得到解决,但提出了以下问题:
FULL恢复模式呢?更新(4月21日).
DBCC LOGINFO输出用于INSERT- 之前和之后的情况.日志文件的物理大小与输出匹配 - 磁盘上恰好为1,048,576字节.为什么事务日志仍然存在?
RecoveryUnitId FileId FileSize StartOffset FSeqNo Status Parity CreateLSN 0 2 253952 8192 131161 0 64 0 0 2 253952 262144 131162 2 64 0 0 2 253952 516096 131159 0 128 0 0 2 278528 770048 131160 0 128 0
RecoveryUnitId FileId FileSize StartOffset FSeqNo Status Parity CreateLSN 0 2 253952 8192 131221 0 128 0 0 2 253952 262144 131222 0 128 0 0 2 253952 516096 131223 2 128 0 0 2 278528 770048 131224 2 128 0
对于那些感兴趣的人我使用进程监视器记录了"sqlserv.exe"活动- 我可以看到该文件被一次又一次地覆盖 - 看起来SQL Server将旧日志项视为由于某种原因不再需要:https:// dl .dropboxusercontent.com/u/1323651/stackoverflow-sql-server-transaction-log.pml.
更新(4月24日).似乎我终于开始了解那里发生了什么,并希望与您分享.上面的推理一般都是正确的,但有一个严重的警告,也产生了与INSERTs的奇怪的事务日志重用的混淆.
数据库将在SIMPLE恢复模式下运行,直到第一次完全备份(即使它处于完全恢复模式).
我们可以把数字和图表上方的有效期为SIMPLE恢复模式,我要重做我测量实际 FULL -他们更惊人.
UPDATE INSERT
Duration 13:20 (!) 00:02
Data file grow 8MB 11MB
Tran. log grow 55.2GB (!) 14MB
小智 3
您违反了日志字段正常形式的基本租户之一。日志字段接缝保存着与主数据库相关的附加信息序列。解决方法是停止这样做。
1 创建一个表。xyz_event_history_LOG(event_history_id,log_sequence#,日志)
2 停止对 [xyz_event_history] 中的日志字段进行更新,而是对 xyz_event_history_LOG 进行插入
事务日志中的数据量将大大减少。
| 归档时间: |
|
| 查看次数: |
969 次 |
| 最近记录: |