Server Development 2008. 1. 21. 09:31
반응형
1. AutoMemoryLeak.h
 => #include "AutoMemoryLeak.h" 를 해주기만 하면 출력창에 누수가 난곳을 출력해준다.



#if
!defined (__AutoDetectMemoryLeak_h__)
#define __AutoDetectMemoryLeak_h__

#if defined(_MSC_VER) && defined (_DEBUG)
#define _CRTDBG_MAP_ALLOC // 메모리 누수를 탐지하기 위해 선언 해주어야 한다.
#include <crtdbg.h>
#if !defined (_CONSOLE)
#include <cstdlib> // for Consol Application
#endif

class __AutoDetectMemoryLeak
{
public:
    __AutoDetectMemoryLeak ()
    {
        _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF |
            _CRTDBG_LEAK_CHECK_DF);

        // Consol Application인 경우
#if defined (_CONSOLE)
        // Send all reports to STDOUT
        _CrtSetReportMode( _CRT_WARN,  
            _CRTDBG_MODE_FILE   );
        _CrtSetReportFile( _CRT_WARN,  
            _CRTDBG_FILE_STDOUT );
        _CrtSetReportMode( _CRT_ERROR, 
            _CRTDBG_MODE_FILE   );
        _CrtSetReportFile( _CRT_ERROR, 
            _CRTDBG_FILE_STDOUT );
        _CrtSetReportMode( _CRT_ASSERT,
            _CRTDBG_MODE_FILE   );
        _CrtSetReportFile( _CRT_ASSERT,
            _CRTDBG_FILE_STDOUT );


        /* new로 할당된 메모리에 누수가 있을 경우 소스상의
        정확한 위치를 덤프해준다.
        *  ※ _AFXDLL을 사용할때는 자동으로 되지만 CONSOLE
        모드에서 아래처럼
        * 재정의를 해주어야만 합니다.
        *    date: 2000-12-05
        */

#define DEBUG_NORMALBLOCK   new ( _NORMAL_BLOCK, __FILE__, __LINE__ )
#ifdef new
#undef new
#endif
#define new DEBUG_NORMALBLOCK

#else

        // Send all reports to DEBUG window
        _CrtSetReportMode( _CRT_WARN,  
            _CRTDBG_MODE_DEBUG  );
        _CrtSetReportMode( _CRT_ERROR, 
            _CRTDBG_MODE_DEBUG  );
        _CrtSetReportMode( _CRT_ASSERT,
            _CRTDBG_MODE_DEBUG  );

#endif

#ifdef malloc
#undef malloc
#endif
        /*
        * malloc으로 할당된 메모리에 누수가 있을 경우 위치
        를 덤프
        * CONSOLE 모드일 경우 crtdbg.h에 malloc이 정의되어
        있지만,
        * _AXFDLL 모드일 경우에는 약간 다른방식으로 덤프 하
        게된다.
        * date: 2001-01-30
        */

#define malloc(s) (_malloc_dbg( s, _NORMAL_BLOCK, __FILE__, __LINE__ ))
    }
};

// 몇 가지 초기화를 생성자를 통해 자동으로 해주기 위해 전역으로 선언한다.
static __AutoDetectMemoryLeak __autoDetectMemoryLeak;

#endif // if defined(_MSC_VER) && defined (_DEBUG)

#endif // __AutoDetectMemoryLeak_h__
반응형
posted by choiwonwoo
:
Server Development 2008. 1. 21. 09:20
반응형
1. MiniDump.h
#pragma once

class CMiniDump
{
public:
    static BOOL Begin(VOID);
    static BOOL End(VOID);
};

2. MiniDump.cpp
#include "stdafx.h"
#include "MiniDump.h"
#include <DbgHelp.h>


typedef BOOL (WINAPI *MINIDUMPWRITEDUMP)( // Callback 함수의 원형
    HANDLE hProcess,
    DWORD dwPid,
    HANDLE hFile,
    MINIDUMP_TYPE DumpType,
    CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
    CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
    CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam);

LPTOP_LEVEL_EXCEPTION_FILTER PreviousExceptionFilter = NULL;

LONG WINAPI UnHandledExceptionFilter(struct _EXCEPTION_POINTERS *exceptionInfo)
{
    HMODULE    DllHandle        = NULL;

    // Windows 2000 이전에는 따로 DBGHELP를 배포해서 설정해 주어야 한다.
    DllHandle                = LoadLibrary(_T("DBGHELP.DLL"));

    if (DllHandle)
    {
        MINIDUMPWRITEDUMP Dump = (MINIDUMPWRITEDUMP) GetProcAddress(DllHandle, "MiniDumpWriteDump");

        if (Dump)
        {
            TCHAR        DumpPath[MAX_PATH] = {0,};
            SYSTEMTIME    SystemTime;

            GetLocalTime(&SystemTime);

            _sntprintf(DumpPath, MAX_PATH, _T("%d-%d-%d %d_%d_%d.dmp"),
                SystemTime.wYear,
                SystemTime.wMonth,
                SystemTime.wDay,
                SystemTime.wHour,
                SystemTime.wMinute,
                SystemTime.wSecond);
           
            HANDLE FileHandle = CreateFile(
                DumpPath,
                GENERIC_WRITE,
                FILE_SHARE_WRITE,
                NULL, CREATE_ALWAYS,
                FILE_ATTRIBUTE_NORMAL,
                NULL);

            if (FileHandle != INVALID_HANDLE_VALUE)
            {
                _MINIDUMP_EXCEPTION_INFORMATION MiniDumpExceptionInfo;
               
                MiniDumpExceptionInfo.ThreadId            = GetCurrentThreadId();
                MiniDumpExceptionInfo.ExceptionPointers    = exceptionInfo;
                MiniDumpExceptionInfo.ClientPointers    = NULL;

                BOOL Success = Dump(
                    GetCurrentProcess(),
                    GetCurrentProcessId(),
                    FileHandle,
                    MiniDumpNormal,
                    &MiniDumpExceptionInfo,
                    NULL,
                    NULL);

                if (Success)
                {
                    CloseHandle(FileHandle);

                    return EXCEPTION_EXECUTE_HANDLER;
                }
            }

            CloseHandle(FileHandle);
        }
    }

    return EXCEPTION_CONTINUE_SEARCH;
}

BOOL CMiniDump::Begin(VOID)
{
    SetErrorMode(SEM_FAILCRITICALERRORS);

    PreviousExceptionFilter = SetUnhandledExceptionFilter(UnHandledExceptionFilter);

    return true;
}

BOOL CMiniDump::End(VOID)
{
    SetUnhandledExceptionFilter(PreviousExceptionFilter);

    return true;
}

3. 사용예제
class MyObject
{
public:
    BOOL mIsOpened;
};
//////////////////////////////////////////////////////////////////////
    CMiniDump::Begin();

    MyObject* Test = new MyObject;
    Test = NULL;
    Test->mIsOpened = TRUE;    

    CMiniDump::End();
//////////////////////////////////////////////////////////////////////
// 1. 디버그모드로 생성된 exe를 실행시 dmp 파일이 생성된다.!!
// 2. 2007-11-7 23_22_39.dmp ( Crash Dump File ) 이 생성된다.
// 3. vc80.pdb ( Program Debug Database ) 가 같은 폴더내에 있어야 에러위치를 볼수 있다.
// 4. dmp 파일을 실행시킨후 디버깅 해주면 에러난곳에 멈춘다.
//////////////////////////////////////////////////////////////////////
반응형
posted by choiwonwoo
:
DataBase/TIP 2008. 1. 9. 13:41
반응형
1.사용법

--Usage:
select dbo.udf_CheckFileSize (''c:\choiwonwoo.txt'')
select dbo.udf_CheckFileSize (''d:\sqldumps\msdbx.bak'')
select dbo.udf_CheckFileSize (''x:\sqldumpsmsd.bak'')

--Results
145920 bytes
23092736 bytes
-1 means File not found or path not found
-2 error during FSO process


2. script
Create function udf_CheckFileSize (@filename varchar(1000))
returns bigint
as
--Created by : MAK
--Date: Dec 5, 2004
--Objective: To display the size of the given file
BEGIN
DECLARE @FS int
DECLARE  @OLEResult int
DECLARE  @FileID int
DECLARE @Size bigint
DECLARE @Flag bigint
set @size =0
set @Flag =0
EXECUTE @OLEResult = sp_OACreate 'Scripting.FileSystemObject', @FS OUT
EXECUTE @OLEResult = sp_OAMethod @FS, 'GetFile', @FileID OUT,@filename
IF @OLEResult <> 0  
begin
set @Flag =-1
end
else
begin
EXECUTE @OLEResult = sp_OAGetProperty @FileId,'Size', @Size OUT
IF @OLEResult <> 0  
begin
set @Flag =-2
end
end

EXECUTE @OLEResult = sp_OADestroy @FileID
EXECUTE @OLEResult = sp_OADestroy @FS
if @flag <> -1 and @flag <> -2 
begin 
set @flag = @size
end
return @flag
END

반응형
posted by choiwonwoo
:
DataBase/Advance 2008. 1. 2. 16:52
반응형

“equal to 연산의 데이터 정렬 충돌을 해결할 수 없습니다” 라는 오류 해결.

보통 조인되는 두 컬럼의 정렬이 틀리게 되어 있어 나타는 현상이다.

정렬 형식은 sp_help 테이블명 하면 collation 항목에 나타난다.

이럴때는 EM의 테이블 디자인에서나 Alter Table 구문으로 정렬 형식을 맞춰 주면 된다.

Alter table tbMembers
Alter column hakbun varchar(8) collate Korean_Wansung_CI_AS


cheers

반응형
posted by choiwonwoo
:
DataBase/Query 2007. 12. 27. 14:50
반응형
다음의 예를 보자

1) where name like 'choi%'

2) where name like '%choi'

3) where substring(name,1,3) = 'choi'


(결과)
모두 결과는 같다.
그러나 성능에 차이가 난다.

1번예는 인덱스를 탄다.

2번예는 인덱스를 타지 않는다.

3번예는 인덱스를 타지 않는다.

==> 원칙적으로 lvalue즉 colum에는 절대로 변형을 가하지 말라.
반응형
posted by choiwonwoo
:
DataBase/Query 2007. 12. 27. 14:22
반응형

EXISTS 및 NOT EXISTS로 시작하는 하위 쿼리는 교집합과 차집합이라는 두 집합 이론 작업에 사용할 수 있습니다. 두 집합의 교집합은 두 가지 원래 집합에 모두 속하는 요소를 포함하고, 차집합은 두 집합 중 첫 번째 집합에만 속하는 요소를 포함합니다.

city 열에 대해 authorspublishers 의 교집합은 저자와 출판사가 모두 있는 도시의 집합입니다.

USE pubs
SELECT DISTINCT city
FROM authors
WHERE EXISTS
   (SELECT *
   FROM publishers
   WHERE authors.city = publishers.city)

결과 집합은 다음과 같습니다.

city
--------
Berkeley

(1  적용됨)

단순 조인을 사용하여 작성할 수도 있습니다.

USE pubs
SELECT DISTINCT authors.city
FROM authors INNER JOIN publishers
ON authors.city = publishers.city

city 열에 대해 authorspublishers 의 차집합은 저자가 거주하지만 출판사는 없는 도시의 집합으로서 Berkeley를 제외한 모든 도시가 됩니다.

USE pubs
SELECT DISTINCT city
FROM authors
WHERE NOT EXISTS
   (SELECT *
   FROM publishers
   WHERE authors.city = publishers.city)

위의 쿼리는 다음과 같이 작성할 수도 있습니다.

USE pubs
SELECT DISTINCT city
FROM authors
WHERE city NOT IN
   (SELECT city 
   FROM publishers)
반응형
posted by choiwonwoo
:
DataBase/Query 2007. 12. 27. 13:48
반응형

Sub Query를 작성하다보면 이런 에러 메시지를 만나게 되는 경우가 있다.

(sample )
SELECT E.DateBegin, E.DateEnd
FROM dbo.[Event] AS E
WHERE E.EventID =( SELECT ESF.EventID
     FROM DBO.STAFF AS SF,dbo.EventStaff AS ESF
     WHERE SF.staffid = ESF.staffid )

(error)
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.

==> 위의 subquery에서 값을 비교하므로 rvalue자체가 스칼라 값이어야만 한다. 그런데 위의 rvalue는 scalar값이 아니다. 이런 경우는 아래와 같이 하면 된다.

(solution)
SELECT E.DateBegin, E.DateEnd
FROM dbo.[Event] AS E
WHERE E.EventID IN ( SELECT ESF.EventID
     FROM DBO.STAFF AS SF,dbo.EventStaff AS ESF
     WHERE SF.staffid = ESF.staffid )


반응형
posted by choiwonwoo
:
Heart to Heart 2007. 12. 18. 14:02
반응형

정정당당하게 싸워야만 하는 상황에 빠졌다면
계획을 제대로 세우지 않은게 틀림없다
If you're in a fair fight, you didn't plan it properly.

- 시코르스키 항공 수석 R&D 조종사, Nick Lappos -

반응형
posted by choiwonwoo
:
DataBase/Advance 2007. 12. 18. 12:12
반응형

=========================================================================================

A-SQLServer SQL Server에 존재하는 Migrate 데이터베이스를 B-SQLServer SQL Server로 동일한 데이터베이스명으로 이관하고 사용자(MigDBUser)가 접근 할 수 있도록 권한 처리를 한다.

   

  • 이관하려는 데이터베이스를 백업
    • 데이터베이스 백업
      • Microsoft SQL Server Management Studio 실행
      • A-SQLServer 서버에 연결한다.
      • Migrate 데이터베이스를 좌측 개체 탐색기에서 선택 후 우측 마우스 버튼 클릭
      • [작업] - [백업] 선택
      • 데이터베이스 백업 대화상자가 열린다.
      • [일반] 페이지 - [대상] Section 의 추가, 제거 버튼을 클릭하여 백업할 위치지정 (파일명 예: Migrate.bak)
      • [확인] 버튼을 클릭

           

  • 백업 데이터베이스 확인
    • Migrate.bak 파일이 생성되었는지 확인한다.

         

  • B-SQLServer 서버에 데이터베이스 이관
    • Migrate.bak 파일을 이관 B-SQLServer가 존재하는 PC 로컬 디스크에 복사 한다
    • Microsoft SQL Server Management Studio에서 B-SQLServer 서버 연결
    • 좌측 개체 탐색기에 존재하는 DB중 아무거나 선택하고 우측 마우스 버튼을 클릭
    • [작업] - [복원] - [데이터베이스]를 선택
    • 데이터베이스 복원 대화상자가 열린다.
    • [일반] 페이지 - [복원에 사용할 원본] Section의 라디오 버튼 중(데이터베이스, 장치) 장치를 선택하고 우측의 버튼을 클릭한다.
    • 백업 지정 대화상자가 열린다.
    • 백업 위치 영역 우측의 버튼 중 "추가"(맨 위) 버튼을 클릭한다.
    • Migrate.bak 파일을 찾아 선택하고 확인 버튼을 클릭한다.
    • 백업 지정 대화상자의 확인 버튼을 클릭하여 지정을 완료한다.
    • 장치 지정이 이뤄지면 복원에 사용할 백업 세트 선택 영역에 복원 대상 목록이 표현된다.
    • 최근 버전에 해당하는 데이터베이스 좌측의 체크박스를 선택한다.
    • [일반]페이지 - [복원 대상] Section의 데이터베이스를 Migrate (생성하려는 데이터베이스명)로 지정한다.
    • [옵션]페이지 - [복원 옵션] Section의 데이터베이스 복원 위치를 지정한다.
      • Mdf(데이터베이스 파일), ldf(로그 파일) 의 위치 및 파일명을 선택한다.
    • 이전에 존재하는 데이터베이스 일 경우, [옵션] 페이지 - [복원 옵션] Section의 최상위 체크 박스인 기존 데이터베이스 덮어쓰기를 선택한다.
    • 위의 설정을 수행하고 확인 버튼을 클릭한다.
    • 데이터베이스의 용량에 따라 수초에서 수분이 걸릴 수 있다.
    • 작업이 완료되면 생성되었다는 메시지가 뜬다.

         

  • 권한 설정 (삭제)
    • 이관한 데이터베이스는 시스템이 틀리므로 이름이 동일하더라도 내부적으로 가지고 있는 SID값이 틀려 프로그램으로 접근이 불가능 하다.
      • SELECT * FROM maste..syslogins, SELECT * From Migrate..sysusers
      • 위의 쿼리를 입력하면 틀린 SID값을 확인할 수 있다.
    • 먼저 이관한 데이터베이스의 전체 권한을 제거한다.
      • 권한 제거는 다른 UI에서 처리할 수가 없으며, 쿼리를 수행하여 삭제할 수 있다.
        • sp_dropuser 'MigDBUser'
    • 좌측 개체 탐색기에서 이관한 데이터베이스를 선택하고 우측 마우스 버튼을 클릭한다.
    • [속성]을 선택한다.
    • 데이터베이스 속성대화상자가 열린다.
    • [사용 권한] 페이지 선택을 클릭한다.
    • [사용자 또는 역할] 영역에 MigDBUser가 삭제되었는지 확인하고, 기타 다른 계정도 2) 항목과 같이 삭제 처리한다.

         

  • 권한 설정 (추가)
    • 좌측 개체 탐색기에서 [보안] - [로그인]을 선택하고 우측 마우스 버튼을 클릭한다.
    • [새 로그인]을 선택한다.
    • 로그인 - 신규 대화상자가 열린다.
    • [일반] 페이지 선택을 클릭하고 로그인 이름에 MigDBUser를 입력한다.
    • SQL Server 인증으로 체크하고 암호를 입력한다.
    • 암호 정책 강제 적용 등 옵션을 선택하고 기본 데이터베이스(Migrate)를 지정, 기본 언어 선택을 한다
    • [사용자 매핑] 페이지 선택을 클릭하고 우측에 접근할 데이터베이스 체크한다.
    • [데이터베이스 역할 맴버 자격] Section에서 db_datareader, db_owner등 권한에 맞도록 체크를 한다.
    • [확인] 버튼을 클릭하여 계정 생성을 완료한다.
      =========================================================================================


      MSSQL2000 에서 백업 받은 DB를 다른 서버에 있는 MSSQL2000 에 복원 시켰을때 해당 DB의 사용자가 있는데 로그인 이름이 없어 로그인이 안되는 문제가 있다.

      이 문제는 해당 DB를 사용하는 사용자의 GUID가 syslogins.sid 테이블에 있는 것돠 다르기때문이다.

      EM에서 사용자에 가 보면 사용자 이름은 있는데 로그인 이름은 비어 있을 것이다.이것을 해결하기 위해서는 새 서버의 로그인 계정과 복원한 DB의 사용자 를 연결해야 한다.

      먼저 쿼리매니저에서 연결되지 않은 계정을 확인한다.

      sp_change_users_login 'Report'
      go;

      하면 사용자는 있는데 연결되지 않은 사용자의 아이디가 나온다.

      나오는 이름을 확인하고

      sp_change_users_login 'Update_one', 'username', 'username'

      go;

      를 하면 연결 작업이 끝난다. EM에서 사용자를 보면 로그인 이름이 생겨있다.


      이제 DB에 해당 사용자로 연결이 되는지 확인하면 된다.

      http://www.baragi.pe.kr/

반응형
posted by choiwonwoo
:
DataBase/TIP 2007. 12. 18. 11:59
반응형


요즘 신변 잡기성 포스트를 너무 많이 올리는 것 같아 간만에 밥벌이 관련 포스트, 컴퓨터 관련 공돌이가 아닌 분들은 지루 하실지도 모르니 살포시 패스 해주시기 바란다.

프로그램 소개에 앞서, 잡설로 일 이야기를 조금 하자면, 본인이 다니고 있는 회사는 작은 온라인 게임 개발사다. 일반적인 온라인 게임과 달리 실제 서울을 배경하고 있기에 다른 게임 보다 개발에 보다 많은 리소스가 필요하게 된다. 그러다 보니 대용량 스토리지는 필수적인 요소가 되었고, 올 초에 1.7 TB 짜리 스토리지를 도입하였다.

300G HDD 12개를 사용하기에 실제로는 3.6TB 이지만 내결함성 보장을 위해서 RAID 10 로 구축을 했기에 1.7TB 를 사용중이다. 이중에서 매일매일 백업 서서버로 옮겨야 하는 데이터가 약 300GB 정도이다. 상황이 이러하다 보니 백업 자체가 엄청나게 빡센 작업이 되고 말았다.

초기에는 Backup Agent 를 직접 개발하여 사용하였으나, 기능의 추가나 다양한 요구를 받아 드리는 작업에 시간이 소모 됨에 따라, 보다 원활한 백업을 위하여 백업 전용 프로그램을 모색하게 되었다.

백업 프로그램으로 유명한 회사 제품을 여러개 사용 해 보았으나, 데이터 백업만을 목적으로 하는 우리기에는 필요하지 않은 기능이 많이 있다. 이 필요하지 않는 기능으로 인해서 상대적으로 고가가 되어 버린 S/W 가격또한 마음에 걸리는 것이고..

그러던 중에 우리 입맞에 딱 맞은 프로그램을 찾게 되었는데 바로 Cobian Backup !!!
프로그램의 대략적인 특징을 살펴 보면 다음과 같다.

1. 기업에서 마음대로 사용 할 수 있는 Freeware.
2. Windows 서비스로 상주하면서 스케줄링을 통한 백업 가능.
3. Network & FTP 등의 데이터도 백업 가능.
4. 백업데이터의 압축 및 암호화가 가능.
5. 백업 결과를 로그로 작성 가능하며, 작업 결과를 메일로 받아 볼 수 있음.
6. 풀, 증분 백업등 다양한 백업을 지원.

혹시나 데이터 백업을 주기적으로 하고 싶은 사람이나, 대용량의 데이터를 증분 백업 하려는 경우에는 유용 할 듯 하다. 첨부된 이미지는 회사에서 실제 사용중인 Cobian Backup의 스크린 샷.

# Link 00 - http://www.cobian.se/ (Official Site)
# Link 01 - http://www.atfile.com/pds_leaf.asp?pg_code=3500&pv_code=3 (Download - Atfile.com)

<출처:http://wowhoon.egloos.com>

반응형
posted by choiwonwoo
: