작성자 : 전혜경 작성일 : 2016.10.20 21:03:02 댓글수 : 0 조회수 : 4,228
메모리가 적은 32bit 머신에서 SQL Server를 운영할때 가장 빈번하게 발생하는 문제가 MemtoLeave 공간 문제입니다.
(이제 대부분 64bit를 사용할테니 문제는 없을 것으로 보입니다만, 혹시라도 32bit를 사용하신다면 이 문제가 반드시 발생하니 참고하세요~ )
SQL Server는 8KB의 싱글 페이지 단위로 메모리를 할당합니다. 그런데 이기종DB 또는 CLR 쿼리 등에서 8KB보다 큰 단위의 연속된 메모리(멀티 페이지) 공간을 요구하는 경우에, SQL Server는 8KB 단위로만 할당할 수 있는 Buffer cache를 할당하지 못해 어쩔 수 없이 OS 영역의 메모리 영역을 할당받아 사용해야 합니다. 이 공간을 바로 MemtoLeave라고 부르는데요. MemtoLeave는 연속된 메모리를 할당해야하는데 메모리를 사용하다보면 조각화가 발생하기 마련이죠. 그래서 일종의 메모리 누수현상처럼 MemtoLeave 공간에 할당 가능한 연속된 메모리 공간이 줄어들 게 됩니다.
더이상 할당할 수 있는 연속된 메모리 공간이 없으면 SQL Server의 에러 로그에 '연속된 메모리 공간을 할당받을 수 없습니다'라는 에러가 발생하게 되죠...이 경우 해결방법은?
SQL Server 내의 메모리가 아니고 OS의 메모리 공간이니 안타깝게도 OS를 리부팅해야만 해결됩니다....
특히 32bit 머신의 경우는 이 memtoleave 공간 size가 정해져있어서 이런 현상이 자주 나타나는데요.
실제로 이 문제로 1주일에 한번씩 정기 서버 리부팅을 하는 경우를 많이 봤습니다. 아마 이 문제가 SQL Server가 자주 죽는다는 악명에 큰 영향을 끼치지 않았을까 싶습니다. 메모리 여유가 있는 64bit 머신은 주기의 차이가 있을 뿐 근본적인 문제를 해결하지 않는 한 마찬가지입니다.
2012에서는 SQL Server가 single page와 multi page를 선택해서 할당할 수 있도록 메모리 아키텍처를 완전히 변경했다고 하는데,,, 정말 그렇다면 2012에서는 이런 문제는 더이상 없을것으로 보입니다.
다음 쿼리는 MemtoLeave에서 가장 큰 연속된 공간(Max Free Block)을 확인하는 쿼리입니다. 주기적으로 확인한다면 장애가 나기전에 미리 조치를 할 수가 있겠죠.
-- 1. MemToLeave에서 가장 큰 연속된 공간(Max Free Block) 확인
With VASummary(Size, Reserved, Free) AS
(SELECT
Size = VaDump.Size,
Reserved = SUM(CASE(CONVERT(INT, VaDump.Base)^0)
WHEN 0 THEN 0 ELSE 1 END),
Free = SUM(CASE(CONVERT(INT, VaDump.Base)^0)
WHEN 0 THEN 1 ELSE 0 END)
FROM
(
SELECT CONVERT(VARBINARY, SUM(region_size_in_bytes))
AS Size, region_allocation_base_address AS Base
FROM sys.dm_os_virtual_address_dump
WHERE region_allocation_base_address <> 0x0
GROUP BY region_allocation_base_address
UNION
SELECT CONVERT(VARBINARY, region_size_in_bytes), region_allocation_base_address
FROM sys.dm_os_virtual_address_dump
WHERE region_allocation_base_address = 0x0
)
AS VaDump
GROUP BY Size)
SELECT SUM(CONVERT(BIGINT,Size)*Free)/1024 AS [Total avail mem, KB] ,CAST(MAX(Size) AS BIGINT)/1024 AS [Max free size, KB]
FROM VASummary
WHERE Free <> 0
아래는 MemToLeave가 부족할 때 나타아는 에러코드들입니다. 아래 에러 코드 중 연속된 메모리 공간을 할당 할 수 없다는 error 17803 메세지가 뜨기 시작하면 야간에 리부팅 시간을 잡으셔야 합니다. 처음에는 간헐적으로 뜨기 시작하다가 좀 더 지나면 다른 에러들이 발생하며 서비스에 문제가 생길 수 있으니 미리 조치가 필요합니다. 따라서 평소에 숙지해두셨다가 문제가 발생하면 원인찾는 과정 없이 바로 조치가 이루어질 수 있도록 하시기 바랍니다.
--* MemToLeave가 부족할 때 나타나는 증상들
--1. error 17189
--오류: 17189, 심각도: 16, 상태: 1
--SQL Server failed with error code 0xc0000000 to spawn a thread to process a new login or connection. Check the SQL Server error log and the Windows event logs for information about possible related problems. [클라이언트: xxx.xxx.xxx.xxx]
--2. error 18056
--오류: 18056, 심각도: 20, 상태: 29
--The client was unable to reuse a session with SPID 302, which had been reset for connection pooling. This error may have been caused by an earlier operation failing. Check the error logs for failed operations immediately before this error message.
--3. error 17803
--오류: 17803, 심각도: 20, 상태: 5
--사용할 수 있는 메모리가 부족합니다..
--WARNING: Failed to reserve contiguous memory of Size= 65536.
--4. error 512
--Non-interface error: OLE DB provider SQLOLEDB returned an incorrect value for properties changed which should be for schema checking
--Error: 512, Severity: 16, State: 1
--5. login 실패
--SQL Server에서 process_loginread 스레드를 만들 수 없습니다.
--6. 백업 실패
오늘은 여기까지 하고 memtoleave에 대한 내용은 다음에 SQL Server의 메모리 구조에 대한 포스팅에서 좀 더 자세히 올리도록 하겠습니다~ ^^