我有一个关于XTP_CHECKPOINT.
我使用的是 SQL Server 2014。我有一个处于 SIMPLE 恢复模式模式的数据库。它也在被复制。
没有未结交易。我跑了DBCC OPENTRAN,它返回:
“没有活跃的未结交易。”
但是每当我尝试创建或删除表或删除数据时,我都会收到此消息:(
我已将实际数据库名称替换为单词database_name)
“由于 'XTP_CHECKPOINT',数据库 'database_name' 的事务日志已满”
有谁知道为什么会发生这种情况,更重要的是,我怎样才能让它停止?
是的,数据库确实处于 SIMPLE 恢复模式模式。即事务日志应自动截断。
顺便说一句,我在完全恢复模式下的另一个数据库做了同样的事情,开始返回相同的错误:
由于“XTP_CHECKPOINT”,数据库“database_name”的事务日志已满
我试图将日志增长设置更改为无限增长,但它不会让我返回相同的错误。
除了文件组之外,我可以在没有任何 XTP 内容的情况下重现该问题。方法如下:http : //pastebin.com/jWSiEU9U
sql-server transaction-log sql-server-2014 memory-optimized-tables
我们已启用 sp_configure 'tempdb metadata memory-optimized' = 1,现在 tempdb 元数据在我们的一台服务器上占用了 400 GB 以上,并且还在继续增长。内存使用量有所下降,但通常它的内存使用量会不断增加。我们已经有几次服务器实际上崩溃了,因为其他系统进程没有足够的内存来修改 tempdb,这导致整个服务器宕机。
如何防止 SQL Server 内存中优化的 tempdb 元数据不断增长并使我的服务器崩溃?如果有的话,我可以查看哪些其他信息来找到消耗如此多内存的内容?
以下查询当前返回 438 GB。
SELECT SUM(domc.pages_kb / 1024.0 / 1024.0) AS pages_gb
FROM sys.dm_os_memory_clerks AS domc
WHERE domc.type LIKE 'MEMORYCLERK_XTP'
Run Code Online (Sandbox Code Playgroud)
以下查询提供的数据是内存的最大使用量(290 GB)是 memory_consumer_id 为 113 - 'LOB Page Allocator'。它没有object_id 或xtp_object_id,所以我猜它是一个数据库范围的对象。
SELECT ddxmc.memory_consumer_id
, ddxmc.memory_consumer_type_desc
, ddxmc.memory_consumer_desc
, ddxmc.object_id
, ddxmc.xtp_object_id
, ddxmc.used_bytes / 1024.0 / 1024.0 / 1024.0 AS used_gb
FROM sys.dm_db_xtp_memory_consumers AS ddxmc
ORDER BY ddxmc.allocated_bytes …Run Code Online (Sandbox Code Playgroud) sql-server memory tempdb memory-optimized-tables sql-server-2019
我正在研究从 MS SQL 2012 升级到 2014 的好处。SQL 2014 的一大卖点是内存优化表,这显然使查询速度超快。
我发现内存优化表有一些限制,例如:
(max)大小的字段timestamp字段UNIQUE限制这些都属于麻烦事,但如果我真的想解决这些问题以获得性能优势,我可以制定计划。
真正的问题是您无法运行ALTER TABLE语句,并且每次向索引列表添加字段时都必须经历这些繁琐INCLUDE的过程。此外,您似乎必须将用户拒之门外,才能对实时数据库上的 MO 表进行任何架构更改。
我觉得这简直太离谱了,以至于我实际上无法相信 Microsoft 会在此功能上投入如此多的开发资金,却让其维护起来如此不切实际。这使我得出结论,我一定是拿错了棍子的一端;我一定误解了内存优化表的某些内容,这让我相信维护它们比实际困难得多。
那么,我误解了什么?你用过MO表吗?是否有某种秘密开关或过程使它们易于使用和维护?
index sql-server alter-table sql-server-2014 memory-optimized-tables
请查看以下 SQL 查询:
CREATE TYPE dbo.IN_MEMORY_TABLE_TYPE AS TABLE
(
source_col INT NULL,
target_col INT not NULL
INDEX ix_InMemoryTable NONCLUSTERED (target_col)
)
WITH (MEMORY_OPTIMIZED = ON)
GO
DECLARE
@t dbo.IN_MEMORY_TABLE_TYPE
INSERT @t
(
source_col,
target_col
)
VALUES
(10, 0),
(0, 0)
UPDATE r1
SET
target_col = -1
FROM @t r1
WHERE EXISTS
(
SELECT *
FROM @t r2
WHERE r2.source_col > 0
)
SELECT *
FROM @t
GO
DROP TYPE dbo.IN_MEMORY_TABLE_TYPE
Run Code Online (Sandbox Code Playgroud)
在 SQL Server 2014 (12.0.4100.1 X64) 上执行UPDATE时,查询按预期执行,并返回以下有效结果:
source_col …
我的 SQL Server 版本是 SQL Server 2019 (RTM-CU18)。以下重现代码要求创建内存中文件组。对于后续操作的任何人,请记住,内存中的文件组一旦创建就无法从数据库中删除。
我有一个简单的内存表,在其中插入 1 - 1200 之间的整数:
DROP TABLE IF EXISTS [dbo].[InMem];
CREATE TABLE [dbo].[InMem] (
i [int] NOT NULL,
CONSTRAINT [PK_InMem] PRIMARY KEY NONCLUSTERED (i ASC)
) WITH ( MEMORY_OPTIMIZED = ON , DURABILITY = SCHEMA_ONLY );
INSERT INTO [dbo].[InMem]
SELECT TOP (1200) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;
Run Code Online (Sandbox Code Playgroud)
我还有以下本机编译的存储过程:
GO
CREATE OR ALTER PROCEDURE p1
WITH NATIVE_COMPILATION, SCHEMABINDING
AS
BEGIN ATOMIC WITH (TRANSACTION ISOLATION LEVEL …Run Code Online (Sandbox Code Playgroud) sql-server stored-procedures memory-optimized-tables table-valued-parameters
我在 SQL Server 2014 中有一个表,如下所示:
CREATE TABLE dbo.MyTable
(
[id1] [bigint] NOT NULL,
[id2] [bigint] NOT NULL,
[col1] [int] NOT NULL default(0),
[col2] [int] NOT NULL default(0)
)
Run Code Online (Sandbox Code Playgroud)
(id1,id2) 是 PK。基本上,id1 是一个标识符,用于对一组结果(id2、col1、col2)进行分组,其 pk 是 id2。
我正在尝试使用内存表来摆脱现有的基于磁盘的表,这是我的瓶颈。
对该表执行的查询如下:
-- INSERT (can vary from 10s to 10,000s of records):
INSERT INTO MyTable
SELECT @fixedValue, id2, col1, col2 FROM AnotherTable
-- READ:
SELECT id2, col1
FROM MyTable INNER JOIN OtherTbl ON MyTable.id2 = OtherTbl.pk
WHERE …Run Code Online (Sandbox Code Playgroud) 描述:
RocksDB 是一个键值存储,因此我们可以简单地序列化对象列表并存储与键对应的值。如果列表中的数据足够小,这将是可以的。
但是如果列表很大并且大小不断增加,那么我们需要对数据进行分页。因此,在这种情况下,存储与单个键对应的整个序列化列表数据不是一个好主意;因为会存在性能问题,因为每次将新数据插入列表时,这个非常大的值也需要在读取期间读取和更新,当向用户显示列表时,将检索整个值,而只有一部分是用户需要。
例如:假设我们想将用户下的订单存储在 RocksDB 中。然后我们可以在 RockDB “u:1:li:o” 中以下列方式存储这个订单数据:Serialised([O1{}, O2{},....On{}])。但是如果用户下的订单数以千计,我们想以页面的形式检索订单(一次 10 或 20 条记录)。因此,在同一个键中存储数千个订单并从该键中检索整个数据然后提供所需的 10-20 条记录并不是一个好主意。此外,用户向同一键添加新订单将影响上述性能。
所以我正在努力设计模式以在 RocksDB 中有效地存储和检索如此大的列表。
如果您能就架构设计提出您的建议,那将会很棒且非常有帮助。
nosql embedded database-design in-memory-database memory-optimized-tables
从 BOL 来看,我的理解是 DBA 不需要管理为内存优化表创建的 DLL 或本机编译的存储过程,因为它们会在 SQL Server 服务启动时自动重新编译,并在不再需要时删除。但我亲眼目睹,即使在删除内存优化表并重新启动服务之后,DLL 仍然存在于文件系统中,并且仍然加载到 SQL 内存中并附加到进程中。这可以通过以下事实来证明:它们在 sys_dm_os_loaded_modules 中仍然可见,并且在 SQL 服务运行时如果您尝试删除它们,它们会被锁定在文件系统中。
这是一个错误吗?或者他们会在以后清理?如果在以后的日期,如果不是实例重启,是什么触发了清理?
我们最近将表转换为内存优化数据。我们的备份已经全部膨胀(3x300GB 文件到 3x600GB 的完整文件,3x50GB 到 3x250GB 的差异文件),并且启动越来越慢。
为了避免这些问题,我们将有问题的表转换为 SCHEMA_ONLY 持久性,但现在数据库不会离开“恢复中”状态。
错误日志最初每 20 秒更新一次恢复状态,预测分析需要大约 9 天才能完成,但是大约一个小时后,更新停止了。
SP_WHO2 显示只有一个进程使用命令访问有问题的数据库XTP_DB_RECOVERY,但不SELECT * FROM sys.dm_db_xtp_checkpoint_files返回任何行。
我有什么办法吗?或者如何查看此XTP_DB_RECOVERY命令的估计剩余时间?
重现问题的步骤
创建具有内存优化文件组和容器的数据库 使用非集群 pk 创建仅模式内存表 模拟插入和删除活动。我的结果是我有高索引未使用的内存,不会下降。
USE master
go
DROP DATABASE IF EXISTS MemoryOptimizedTest
CREATE DATABASE MemoryOptimizedTest
GO
USE MemoryOptimizedTest
GO
ALTER DATABASE MemoryOptimizedTest
ADD FILEGROUP imoltp_mod CONTAINS MEMORY_OPTIMIZED_DATA
GO
ALTER DATABASE MemoryOptimizedTest ADD FILE (name='imoltp_mod1', filename='c:\imoltp_mod1') TO FILEGROUP imoltp_mod
GO
DROP TABLE IF EXISTS dbo.MyCache
CREATE TABLE dbo.MyCache
(
PK int NOT NULL,
SecondInt int NOT NULL,
ThirdInt int NOT NULL,
CONSTRAINT PK_MyCache PRIMARY KEY NONCLUSTERED (PK)
) WITH (MEMORY_OPTIMIZED = ON, DURABILITY = SCHEMA_ONLY)
go
/* Generate activity …Run Code Online (Sandbox Code Playgroud)