2009-10-08 73 views
13

SQL Server 2008的鏈接服務器和特設的INSERT引起快速內存泄漏,最終導致服務器無響應,並與下面的錯誤結束系統內存不足:有一個在資源池「內部」

Msg 701, Level 17, State 123, Server BRECK-PC\SQLEXPRESS, Line 2 
There is insufficient system memory in resource pool 'internal' to run this 
query. 

Location:  qxcntxt.cpp:1052 
Expression:  cref == 0 
SPID:   51 
Process ID:  1880 

在SQL Server重新啓動之前,服務器保持不響應狀態。

軟件使用:

  • Windows Vista旗艦版的64位版本6001 SP1

  • 的Microsoft SQL Server 2008(SP1) - 10.0.2734.0(X64)2009年9月11日14時30分58秒版權所有(c)在Windows NT 6.0 1988-2008微軟公司Express Edition與高級服務(64位)(建設6001:Service Pack 1的)

  • SAOLEDB.11從SQL Anywhere的驅動11.0.1.2276

將最大服務器內存(MB)設置爲2048並沒有幫助。

將各種-g值(例如-g256;)添加到服務器啓動參數沒有幫助。

使用DBCC FREESYSTEMCACHE('ALL'),DBCC FREESESSIONCACHE和DBCC FREEPROCCACHE沒有幫助。

即使它包含對涉及鏈接服務器使用情況的內存泄漏症狀的修復,也無濟於事,將SQL Server 2008 Service Pack 1的排列更新程序包4安裝不起作用。

分隔SELECT ... ROW_NUMBER()OVER ... INSERT中的查詢沒有幫助。實驗表明,複雜的SELECT不會導致內存泄漏,INSERT也會這樣做。

更改代碼以使用臨時「INSERT INTO OPENROWSET」語法而不是鏈接服務器沒有幫助;以下代碼顯示了鏈接的服務器使用情況。

sysinternals.com進程瀏覽實用程序顯示內存使用量與sqlserver.exe相關,而不是SQL Anywhere OLEDB驅動程序SAOLEDB.11使用的DLL。

請注意,SQL Anywhere版本的鏈接服務器(代理表)工作正常,可在單個事務中將SQL Server 2008表中的190萬行「拉」到SQL Anywhere 11數據庫。這裏顯示的邏輯是嘗試使用鏈接服務器功能來「推」行;相同的方向,不同的語法。

代碼如下;內存4G是後EXECUTE copy_mss_t2三個或四個執行耗盡:

EXEC sys.sp_configure 
    N'show advanced options', 
    N'1' 
GO 

RECONFIGURE WITH OVERRIDE 
GO 

EXEC sys.sp_configure 
    N'max server memory (MB)', 
    N'2048' 
GO 

RECONFIGURE WITH OVERRIDE 
GO 

EXEC sys.sp_configure 
    N'show advanced options', 
    N'0' 
GO 

RECONFIGURE WITH OVERRIDE 
GO 
EXEC master.dbo.sp_MSset_oledb_prop 
    N'SAOLEDB.11', 
    N'AllowInProcess', 
    1 
GO 

sp_addlinkedserver 
    @server = 'mem', 
    @srvproduct = 'SQL Anywhere OLE DB Provider', 
    @provider = 'SAOLEDB.11', 
    @datasrc = 'mem_PAVILION2' 
GO 

EXEC master.dbo.sp_serveroption 
    @server=N'mem', 
    @optname=N'rpc', 
    @optvalue=N'true' 
GO 

EXEC master.dbo.sp_serveroption 
    @server=N'mem', 
    @optname=N'rpc out', 
    @optvalue=N'true' 
GO 

sp_addlinkedsrvlogin 
    @rmtsrvname = 'mem', 
    @useself = 'false', 
    @locallogin = NULL, 
    @rmtuser = 'dba', 
    @rmtpassword = 'sql' 
GO 

CREATE PROCEDURE copy_mss_t2 
    @from_row   BIGINT, 
    @to_row    BIGINT, 
    @rows_copied_count BIGINT OUTPUT 
AS 

    SELECT * 
    INTO #t 
    FROM (SELECT *, 
        ROW_NUMBER() 
         OVER (ORDER BY sample_set_number, 
             connection_number) 
        AS t2_row_number 
      FROM mss_t2) AS ordered_mss_t2 
    WHERE ordered_mss_t2.t2_row_number BETWEEN @from_row AND @to_row; 

    SELECT @rows_copied_count = COUNT(*) 
    FROM #t; 

INSERT INTO mem..dba.sa_t2 
SELECT sampling_id, 
     sample_set_number, 
     connection_number, 
     blocker_owner_table_name, 
     blocker_lock_type, 
     blocker_owner_name, 
     blocker_table_name, 
     blocker_reason, 
     blocker_row_identifier, 
     current_engine_version, 
     page_size, 
     ApproximateCPUTime, 
     BlockedOn, 
     BytesReceived, 
     BytesSent, 
     CacheHits, 
     CacheRead, 
    "Commit", 
    DiskRead, 
    DiskWrite, 
    FullCompare, 
    IndAdd, 
    IndLookup, 
    Isolation_level, 
    LastReqTime, 
    LastStatement, 
    LockCount, 
    LockName, 
    LockTableOID, 
    LoginTime, 
    LogWrite, 
    Name, 
    NodeAddress, 
    Prepares, 
    PrepStmt, 
    QueryLowMemoryStrategy, 
    QueryOptimized, 
    QueryReused, 
    ReqCountActive, 
    ReqCountBlockContention, 
    ReqCountBlockIO, 
    ReqCountBlockLock, 
    ReqCountUnscheduled, 
    ReqStatus, 
    ReqTimeActive, 
    ReqTimeBlockContention, 
    ReqTimeBlockIO, 
    ReqTimeBlockLock, 
    ReqTimeUnscheduled, 
    ReqType, 
    RequestsReceived, 
    Rlbk, 
    RollbackLogPages, 
    TempFilePages, 
    TransactionStartTime, 
    UncommitOp, 
    Userid, 
    previous_ApproximateCPUTime, 
    interval_ApproximateCPUTime, 
    previous_Commit, 
    interval_Commit, 
    previous_Rlbk, 
    interval_Rlbk 
    FROM #t; 

GO 

DECLARE @rows_copied_count BIGINT 
EXECUTE copy_mss_t2 1110001, 1120000, @rows_copied_count OUTPUT 
SELECT @rows_copied_count 
GO 

EXECUTE create_linked_server 
GO 

DECLARE @rows_copied_count BIGINT 
EXECUTE copy_mss_t2 1120001, 1130000, @rows_copied_count OUTPUT 
SELECT @rows_copied_count 
GO 

EXECUTE create_linked_server 
GO 

這裏是SQL Server源表,包含有關數據的1G的190萬行:

CREATE TABLE mss_t2 (
    sampling_id      BIGINT NOT NULL, 
    sample_set_number     BIGINT NOT NULL, 
    connection_number     BIGINT NOT NULL, 
    blocker_owner_table_name   VARCHAR (257) NULL, 
    blocker_lock_type     VARCHAR (32) NULL, 
    blocker_owner_name    VARCHAR (128) NULL, 
    blocker_table_name    VARCHAR (128) NULL, 
    blocker_reason     TEXT NULL, 
    blocker_row_identifier   VARCHAR (32) NULL, 
    current_engine_version   TEXT NOT NULL, 
    page_size       INTEGER NOT NULL, 
    ApproximateCPUTime    DECIMAL (30, 6) NULL, 
    BlockedOn       BIGINT NULL, 
    BytesReceived      BIGINT NULL, 
    BytesSent       BIGINT NULL, 
    CacheHits       BIGINT NULL, 
    CacheRead       BIGINT NULL, 
    "Commit"       BIGINT NULL, 
    DiskRead       BIGINT NULL, 
    DiskWrite       BIGINT NULL, 
    FullCompare      BIGINT NULL, 
    IndAdd       BIGINT NULL, 
    IndLookup       BIGINT NULL, 
    Isolation_level     BIGINT NULL, 
    LastReqTime      TEXT NOT NULL DEFAULT '1900-01-01', 
    LastStatement      TEXT NULL, 
    LockCount       BIGINT NULL, 
    LockName       BIGINT NULL, 
    LockTableOID      BIGINT NULL, 
    LoginTime       TEXT NOT NULL DEFAULT '1900-01-01', 
    LogWrite       BIGINT NULL, 
    Name        VARCHAR (128) NULL, 
    NodeAddress      TEXT NULL, 
    Prepares       BIGINT NULL, 
    PrepStmt       BIGINT NULL, 
    QueryLowMemoryStrategy   BIGINT NULL, 
    QueryOptimized     BIGINT NULL, 
    QueryReused      BIGINT NULL, 
    ReqCountActive     BIGINT NULL, 
    ReqCountBlockContention   BIGINT NULL, 
    ReqCountBlockIO     BIGINT NULL, 
    ReqCountBlockLock     BIGINT NULL, 
    ReqCountUnscheduled    BIGINT NULL, 
    ReqStatus       TEXT NULL, 
    ReqTimeActive      DECIMAL (30, 6) NULL, 
    ReqTimeBlockContention   DECIMAL (30, 6) NULL, 
    ReqTimeBlockIO     DECIMAL (30, 6) NULL, 
    ReqTimeBlockLock     DECIMAL (30, 6) NULL, 
    ReqTimeUnscheduled    DECIMAL (30, 6) NULL, 
    ReqType       TEXT NULL, 
    RequestsReceived     BIGINT NULL, 
    Rlbk        BIGINT NULL, 
    RollbackLogPages     BIGINT NULL, 
    TempFilePages      BIGINT NULL, 
    TransactionStartTime    TEXT NOT NULL DEFAULT '1900-01-01', 
    UncommitOp      BIGINT NULL, 
    Userid       VARCHAR (128) NULL, 
    previous_ApproximateCPUTime  DECIMAL (30, 6) NOT NULL DEFAULT 0.0, 
    interval_ApproximateCPUTime  AS (COALESCE ("ApproximateCPUTime", 0) - previous_ApproximateCPUTime), 
    previous_Commit     BIGINT NOT NULL DEFAULT 0, 
    interval_Commit     AS (COALESCE ("Commit", 0) - previous_Commit), 
    previous_Rlbk      BIGINT NOT NULL DEFAULT 0, 
    interval_Rlbk      AS (COALESCE (Rlbk, 0) - previous_Rlbk)) 

這裏是SQL Anywhere 11中的目標表:

CREATE TABLE sa_t2 (
    sampling_id      BIGINT NOT NULL, 
    sample_set_number     BIGINT NOT NULL, 
    connection_number     BIGINT NOT NULL, 
    blocker_owner_table_name   VARCHAR (257) NULL, 
    blocker_lock_type     VARCHAR (32) NULL, 
    blocker_owner_name    VARCHAR (128) NULL, 
    blocker_table_name    VARCHAR (128) NULL, 
    blocker_reason     TEXT NULL, 
    blocker_row_identifier   VARCHAR (32) NULL, 
    current_engine_version   TEXT NOT NULL, 
    page_size       INTEGER NOT NULL, 
    ApproximateCPUTime    DECIMAL (30, 6) NULL, 
    BlockedOn       BIGINT NULL, 
    BytesReceived      BIGINT NULL, 
    BytesSent       BIGINT NULL, 
    CacheHits       BIGINT NULL, 
    CacheRead       BIGINT NULL, 
    "Commit"       BIGINT NULL, 
    DiskRead       BIGINT NULL, 
    DiskWrite       BIGINT NULL, 
    FullCompare      BIGINT NULL, 
    IndAdd       BIGINT NULL, 
    IndLookup       BIGINT NULL, 
    Isolation_level     BIGINT NULL, 
    LastReqTime      TEXT NOT NULL DEFAULT '1900-01-01', 
    LastStatement      TEXT NULL, 
    LockCount       BIGINT NULL, 
    LockName       BIGINT NULL, 
    LockTableOID      BIGINT NULL, 
    LoginTime       TEXT NOT NULL DEFAULT '1900-01-01', 
    LogWrite       BIGINT NULL, 
    Name        VARCHAR (128) NULL, 
    NodeAddress      TEXT NULL, 
    Prepares       BIGINT NULL, 
    PrepStmt       BIGINT NULL, 
    QueryLowMemoryStrategy   BIGINT NULL, 
    QueryOptimized     BIGINT NULL, 
    QueryReused      BIGINT NULL, 
    ReqCountActive     BIGINT NULL, 
    ReqCountBlockContention   BIGINT NULL, 
    ReqCountBlockIO     BIGINT NULL, 
    ReqCountBlockLock     BIGINT NULL, 
    ReqCountUnscheduled    BIGINT NULL, 
    ReqStatus       TEXT NULL, 
    ReqTimeActive      DECIMAL (30, 6) NULL, 
    ReqTimeBlockContention   DECIMAL (30, 6) NULL, 
    ReqTimeBlockIO     DECIMAL (30, 6) NULL, 
    ReqTimeBlockLock     DECIMAL (30, 6) NULL, 
    ReqTimeUnscheduled    DECIMAL (30, 6) NULL, 
    ReqType       TEXT NULL, 
    RequestsReceived     BIGINT NULL, 
    Rlbk        BIGINT NULL, 
    RollbackLogPages     BIGINT NULL, 
    TempFilePages      BIGINT NULL, 
    TransactionStartTime    TEXT NOT NULL DEFAULT '1900-01-01', 
    UncommitOp      BIGINT NULL, 
    Userid       VARCHAR (128) NULL, 
    previous_ApproximateCPUTime  DECIMAL (30, 6) NOT NULL DEFAULT 0.0, 
    interval_ApproximateCPUTime  DECIMAL (30, 6) NOT NULL COMPUTE (COALESCE ("ApproximateCPUTime", 0) - previous_ApproximateCPUTime), 
    previous_Commit     BIGINT NOT NULL DEFAULT 0, 
    interval_Commit     BIGINT NOT NULL COMPUTE (COALESCE ("Commit", 0) - previous_Commit), 
    previous_Rlbk      BIGINT NOT NULL DEFAULT 0, 
    interval_Rlbk      BIGINT NOT NULL COMPUTE (COALESCE (Rlbk, 0) - previous_Rlbk), 
    PRIMARY KEY (sample_set_number, connection_number)); 
+0

我已經添加源和目標表的CREATE TABLE語句。進一步的實驗表明,各種數據類型可能是內存泄漏的原因;例如多個TEXT列,30位DECIMAL,計算的AS列等等。我從原始問題陳述中刪除DDL的PROFOUND APOLOGIES ...有點不公平。 – 2009-10-11 14:01:58

+0

初步跡象表明,在源表中有多個TEXT列導致SQL Server內存泄漏。將除TEXT列之外的所有列都更改爲VARCHAR似乎有訣竅。完整測試高達250,000行,增加零內存;我會等待它完成,然後放置一個小的可重複性。 – 2009-10-11 15:10:41

回答

7

您是否需要在每次迭代後清空臨時表#t?即在程序結束時添加TRUNCATE TABLE #t?我認爲臨時表#t存在,直到您的會話結束,直到存儲過程結束。 SELECT INTO只是附加到現有的#t,但不會替代它。

另一件事將是使用永久表,而不是存儲在tempdb #tables中的東西。

+0

出色的觀察! FWIW所有190萬行所需的總空間約爲1G,而在處理了幾千行之後內存泄露佔用了幾G的內存......所以我不希望它與臨時表有任何關係(在第一次注意到內存泄漏之後,它被添加*)。但是,就像我之前所說的那樣,在這一點上,歡迎任何和所有的建議。 – 2009-10-11 13:52:07

+0

在所有的答案中,包括被刪除的答案,我最喜歡你的,所以我給你獎金。 – 2009-10-12 15:16:32

+0

當然,這不是*真實*答案(請參閱下面的答案),但提供獎金,讓所有人都對我的問題感興趣,然後將獎金抽出來,實在太傻了! – 2009-10-12 15:19:08

0

您可以嘗試一次運行插入批處理而不是整個數據集。

+0

「您可以嘗試批量運行插入,而不是一次運行整個數據集。」 - 這正是代碼的作用,一次只複製10,000行的批次:EXECUTE copy_mss_t2 1110001,1120000,... - 這就是爲什麼使用複雜的SELECT來收集小批量數據的原因。我曾考慮編寫單行FETCH和INSERT循環,但Kludge Faktor相當極端...關係數據庫應該處理集合。 – 2009-10-08 14:21:58

+0

嘗試一個較小的批次,而不是所有的方式。繼續降低批量,直到它工作。 或者也可以嘗試通過SSIS包而不是鏈接服務器移動記錄。 – HLGEM 2009-10-08 14:35:26

+0

實驗顯示內存泄漏與批量大小無關;特別是,內存泄漏比正在傳輸的數據量大幾個數量級。此外,此代碼的全部用途是使用鏈接的服務器功能,用於有關該主題的文章。感謝關於SSIS的建議,我會放棄它(但是,不幸的是,「在SQL Server Express中,保存嚮導創建的包的選項不可用。」) – 2009-10-10 17:33:56

0

而不是使用臨時表,你可以嘗試使用變量表?

例如。

DECLARE @ResultTable TABLE (TableId INT PRIMARY KEY, ... etc) 

INSERT INTO @ResultTable 
SELECT TableId, .... 
FROM mss_t2 

... etc. ... 
+0

臨時表是在內存泄漏第一次出現之後引入的...它是作爲解決方法嘗試添加的。實驗表明,直到臨時表填充後,纔會開始向鏈接服務器表的INSERT,泄漏纔會發生。 但是,在這一點上,任何事情都值得嘗試!謝謝! – 2009-10-11 13:41:07

2

問題是通過SQL使用鏈接的服務器Anywhere的11.0.1提供商SAOLEDB.11將數據插入到聲明爲比VARCHAR(8000)大的目標列。下面是一個簡化重複性:

-- Overview: SQL Server 2008 suffers from a fatal memory leak 
-- if an attempt is made to use a linked server and the 
-- SAOLEDB.11 provicer to copy data from SQL Server 
-- to a SQL Anywhere 11.0.1 table that contains a single column 
-- larger than VARCHAR (8000); i.e, a VARCHAR (8000) target 
-- column is OK but VARCHAR (8001) is not. The actual string 
-- length is not an issue, nor is the fact that the SQL Server 
-- column is declared as TEXT. The memory leak is faster if 
-- there is more than one target column larger than VARCHAR (8000). 
-- The server computer freezes and must be rebooted. 
-- Msg 701, Level 17, State 123, Server BRECK-PC\SQLEXPRESS, Line 2 
-- There is insufficient system memory in resource pool 'internal' to run this 
-- query. 
-- Location:  qxcntxt.cpp:1052 
-- Expression:  cref == 0 
-- SPID:   52 
-- Process ID:  2044 

--------------------------------------------------------- 
-- SQL ANYWHERE 11 on target computer 
--------------------------------------------------------- 

-- Target: 
-- HP Pavilion laptop, 4GHz Pentium 4, 2G RAM 
-- Windows XP SP2 
-- SQL Anywhere 11.0.1.2276 

--------------------------------------------------------- 
-- Windows commands used to create and start in-memory database 

/* 
"%SQLANY11%\bin32\dbinit.exe"^ 
    mem.db 

"%SQLANY11%\bin32\dbspawn.exe" -f^ 
    "%SQLANY11%\bin32\dbsrv11.exe"^ 
    -im nw^ 
    -o dbsrv11_log.txt^ 
    mem.db 

"%SQLANY11%\bin32\dbisql.com"^ 
    -c "ENG=mem;DBN=mem;UID=dba;PWD=sql;CON=mem-1" 
*/ 

--------------------------------------------------------- 
-- Create target table with one single "long" column. 

BEGIN 
    DROP TABLE sa_target; 
    EXCEPTION WHEN OTHERS THEN 
END; 

CREATE TABLE sa_target (
    primary_key  INTEGER NOT NULL PRIMARY KEY, 
    string_column_1 VARCHAR (8001) NOT NULL); 

--------------------------------------------------------- 
--- SQL SERVER 2008 on source (server) computer 
--------------------------------------------------------- 

-- Server: 
-- Desktop with Intel Core 2 Quad Q9450 2.66Ghz 4G RAM 
-- Windows Vista Ultimate 64 bit build 6001 SP1 
-- SQL Server 2008 Express 64 Service Pack 1 with cumulative update package 4: 
-- Microsoft SQL Server 2008 (SP1) - 10.0.2734.0 (X64) Sep 11 2009 14:30:58 
-- Copyright (c) 1988-2008 Microsoft Corporation Express Edition with  
-- Advanced Services (64-bit) on Windows NT 6.0 <X64>  
-- (Build 6001: Service Pack 1) 
-- SAOLEDB.11 driver from SQL Anywhere 11.0.1.2276 

--------------------------------------------------------- 
-- Windows command used to start osql.exe 

/* 
"c:\Program Files\Microsoft SQL Server\100\Tools\Binn\osql.exe"^ 
    -d main^ 
    -I^ 
    -l 10^ 
    -P j68Fje9#fyu489^ 
    -S BRECK-PC\SQLEXPRESS^ 
    -U sa 
*/ 

--------------------------------------------------------- 
-- Create database. 

USE master 
GO 

BEGIN TRY 
    DROP DATABASE main; 
END TRY 
BEGIN CATCH 
END CATCH; 
GO 

CREATE DATABASE main 
ON PRIMARY 
(NAME = main_dat, 
    FILENAME = 'E:\data\main\main.mdf', 
    SIZE = 2GB, 
    FILEGROWTH = 200MB) 
LOG ON 
(NAME = 'main_log', 
    FILENAME = 'E:\data\main\main.ldf', 
    SIZE = 2GB, 
    FILEGROWTH = 200MB) 
GO 

---------------------------------------------------------------------------- 
-- Configure SAOLEDB.11 provider. 

USE master 
go 

-- SAOLEDB.11 provider dlls registered via these Windows commands: 
-- regsvr32 dboledb11.dll 
-- regsvr32 dboledba11.dll 

EXEC master.dbo.sp_MSset_oledb_prop N'SAOLEDB.11', N'AllowInProcess', 1 
GO 

-- If the following statement produces this message, it probably means 
-- that 'DisallowAdHocAccess' is already set to zero for SAOLEDB.11: 
-- 
-- RegDeleteValue() returned error 2, 'The system cannot find the file specified.' 

EXEC master.dbo.sp_MSset_oledb_prop N'SAOLEDB.11', N'DisallowAdHocAccess', 0 
GO 

---------------------------------------------------------------------------- 
-- THIS SECTION WAS NOT RUN. 
-- Set up for OPENROWSET usage. 
-- NOT REQUIRED for required for Linked Server usage. 

USE master 
GO 

sp_configure 'show advanced options', 1 
GO 

RECONFIGURE 
GO 

sp_configure 'Ad Hoc Distributed Queries', 1 
GO 

RECONFIGURE 
GO 

---------------------------------------------------------------------------- 
-- Set up Linked Server usage. 

USE main 
GO 

BEGIN TRY 
    EXEC sp_droplinkedsrvlogin 
     @rmtsrvname = 'mem', 
     @locallogin = NULL 
END TRY 
BEGIN CATCH 
END CATCH 
GO 

BEGIN TRY 
    EXEC sp_dropserver 
     @server = 'mem' 
END TRY 
BEGIN CATCH 
END CATCH 
GO 

EXEC sp_addlinkedserver 
    @server = 'mem', 
    @srvproduct = 'SQL Anywhere OLE DB Provider', 
    @provider = 'SAOLEDB.11', 
    @datasrc = 'mem_PAVILION2' 
GO 

EXEC master.dbo.sp_serveroption 
    @server=N'mem', 
    @optname=N'rpc', 
    @optvalue=N'true' 
GO 

EXEC master.dbo.sp_serveroption 
    @server=N'mem', 
    @optname=N'rpc out', 
    @optvalue=N'true' 
GO 

EXEC sp_addlinkedsrvlogin 
    @rmtsrvname = 'mem', 
    @useself = 'false', 
    @locallogin = NULL, 
    @rmtuser = 'dba', 
    @rmtpassword = 'sql' 
GO 

---------------------------------------------------------------------------- 
-- Create and fill source table with 1 million rows. 

USE main 
GO 

BEGIN TRY 
    DROP TABLE mss_source; 
END TRY 
BEGIN CATCH 
END CATCH 
GO 

CREATE TABLE mss_source ( 
    primary_key  INTEGER NOT NULL PRIMARY KEY, 
    string_column_1 TEXT NOT NULL) 
GO 

BEGIN 
    DECLARE @primary_key INTEGER 
    SELECT @primary_key = 1 
    BEGIN TRANSACTION 
    WHILE @primary_key <= 1000000 
    BEGIN 
     INSERT mss_source VALUES (
     @primary_key, 
     REPLICATE ('Some test data. ', 2)) 
     SELECT @primary_key = @primary_key + 1 
    END 
    COMMIT 
END 
GO 

SELECT COUNT(*) FROM mss_source 
GO 

-- 1000000 

--------------------------------------------------------- 
-- Copy data to target table. 

SELECT CURRENT_TIMESTAMP 
GO 

INSERT INTO mem..dba.sa_target 
SELECT * 
    FROM mss_source 
GO 

SELECT CURRENT_TIMESTAMP 
GO 

--------------------------------------------------------- 
-- Test 1 - Code as shown above. 
-- FAILED 
-- 
-- Started at 2009-10-12 10:06:33.393 
-- 
-- A slow server memory leak began immediately. 
-- The initial target insert rate was about 2000 rows per second. 
-- Server RAM usage reached 3.82 GB, Physical Memory: 95%, Page File 16236M/16288M 
-- The server display became frozen. 
-- The server became unresponsive to mouse input. 
-- The target insert rate dropped below 1000 rows per second, but inserts continued. 
-- The copy process reached 937,817 rows inserted on the target. 
-- This dialog box appeared on the server: "Your computer is low on memory" 
-- Eventually, the process failed, and this message appeared in the osql.exe window: 
-- 
-- Msg 701, Level 17, State 123, Server BRECK-PC\SQLEXPRESS, Line 2 
-- There is insufficient system memory in resource pool 'internal' to run this 
-- query. 
-- Location:  qxcntxt.cpp:1052 
-- Expression:  cref == 0 
-- SPID:   52 
-- Process ID:  2044 
-- 
-- Failed at 2009-10-12 10:22:21.817 
-- The server disk I/O light remained lit without interruption. 
-- The server required a hard reboot. 

--------------------------------------------------------- 
-- Test 2 - Code as shown above, except for VARCHAR (8000). 
-- SUCCESSFUL 

BEGIN 
    DROP TABLE sa_target; 
    EXCEPTION WHEN OTHERS THEN 
END; 

CREATE TABLE sa_target (
    primary_key  INTEGER NOT NULL PRIMARY KEY, 
    string_column_1 VARCHAR (8000) NOT NULL); 

-- Started at 2009-10-12 10:41:46.427 
-- There was some slight initial growth in RAM usage on the server. 
-- Server RAM usage stabilized at 1.40 GB, Physical Memory: 35%, Page File 1560M/8352M 
-- The target insert rate remained about 2000 rows per second throughout. 
-- Finished OK at 2009-10-12 10:50:52.240 

--------------------------------------------------------- 
-- Test 3 - Repeat Test 2 
-- SUCCESSFUL 

-- Started at 2009-10-12 10:53:38.350 
-- No further RAM usage growth on the server. 
-- Finished OK at 2009-10-12 11:02:10.457 
0

我有一個類似的問題,我的代碼包含在一個循環的簡單#TEMP表,導致這和我有一個永久表替換使用。

似乎工作。

感謝 納文

相關問題