Есть СКЛ Сервер 2000 (или МСДЕ 2000 результат один и тот же).
Параметры:
Microsoft SQL Server 2000 — 8.00.384 (Intel X86) May 23 2001 00:02:52 Copyright (c) 1988-2000 Microsoft Corporation Desktop Engine on Windows NT 5.0 (Build 2195: Service Pack 3)
Он стоит на ХР винде, там же я с ним и работаю.
Есть программа, которая через ОДБС гоняет селекты к нему.
Программа является очень критичной к потребляемым ресурсам, так как должна работать без перезагрузки долгие месяцы. Однако, обнаружилось, что на вторые сутки работы сам СКЛ Сервер съедает 500 М памяти и вся система просто вешается..
Причем ест он память очень быстро..
В результате долгой отладки на причину таких утечек был найден селект (селекты), который при своейм выполнении съедает каждый раз по 40 К памяти и назад её не отдает.
Затем эта ситуация была проверена на QA — результат тот же — память растет.
Я так понимаю работу СКЛ Сервера. Он выполняет запрос — выбирает данные. И одновременно кэширует какую-то часть информации по какому-то своему алгоритму. Чтобы если следующая выборка попадет в эти данные, то он не будет обращаться к диску, а сразу возьмет все из памяти. Это все ок — из-за этого память может немного скушаться. НО размер этого кэша ведь должен быть фиксированным. Т.е. не может же быть так, что программа выполняет 10 000 селектов и каждый из них кэшируется... Ну вот я тоже думаю, что не может такого быть.
Далее был проведен эксперимент. В самих настройках СКЛ Сервера было указано, чтобы он не ел всю доступную память, а ограничился скажем 25 метрами. Результат был таким. Он дорос до указанного предела. поработал некоторое время, а затем стал выдавать на каждый запрос к нему, будь то селект или попытка установить соединение, что вся свободная память кончилась и мол — отвали.
Итак. Возможно я сумбурно описал ситуацию — просто указал, все что делалось.
Резюме такое. Есть некий селект, который при своем выполнении каждый раз отхватывает от СКЛ Сервера по 40 К. Этих селектов за сутки проходит туча. В результате я теряю всю свободную память. Самое интересное то, что даже если все таблицы, по которым работает этот селект полностью пустые — результат будет тем же.
CREATE TABLE OUT_REPLICA_LOG (
IID NUMERIC(38) NOT NULL IDENTITY (1,1),
REPLICA_GUID uniqueidentifier NOT NULL ,
DB_ID NUMERIC(38) NOT NULL ,
STATUS_ID NUMERIC(38) NOT NULL ,
DESCRIPTION_ VARCHAR(4000) NOT NULL ,
DATE_ DATETIME NOT NULL DEFAULT GETDATE ( ) ,
PRIMARY KEY (IID, REPLICA_GUID),
FOREIGN KEY (REPLICA_GUID) REFERENCES OUT_REPLICA_PROPERTY);
CREATE TABLE OUT_REPLICA_DB_MAP (
REPLICA_GUID uniqueidentifier NOT NULL ,
DB_ID int NOT NULL ,
CHANNEL_ID int NOT NULL ,
RECV_STATUS bit NULL ,
FILL_STATUS bit NULL,
FOREIGN KEY (REPLICA_GUID) REFERENCES OUT_REPLICA_PROPERTY );
Большая просьба создайте их через QA, а затем сразу выполните след. селект
SELECT DISTINCT
MAP.DB_ID
FROM
OUT_REPLICA_PROPERTY AS PROPERTY,
OUT_REPLICA_DB_MAP AS MAP,
OUT_REPLICA_LOG AS LOG
WHERE
PROPERTY.REPLICA_GUID = MAP.REPLICA_GUID
AND
LOG.REPLICA_GUID = MAP.REPLICA_GUID
AND
PROPERTY.REPLICA_TYPE = 0
AND
(MAP.FILL_STATUS IS NULL OR MAP.FILL_STATUS = 0)
AND
MAP.DB_ID in (2)
AND
LOG.IID < ( SELECT MIN (IID) FROM OUT_REPLICA_LOG WHERE REPLICA_GUID = '3FD1F219-7B00-4E79-86A1-8B6F783C610B')
И при этом обратите внимание на расход памяти в диспетчере задач. И ещё такой момент. В селекте указан ГУИД '3FD1F219-7B00-4E79-86A1-8B6F783C610B'. От запроса к запросу его нужно менять (например первую цифру), т.е. чтобы выборка не повторялась. Тогда память начнет течь.
Буду очень признателен, если общественность внимательно прочтет это сообщение, "въедет" в его смысл и посоветует мне хоть что-нибудь.. — проект горит, его инсталлировать нужно, а он фактически не может работать, т.к. СКЛ ест всю доступную память.