2007년 12월 21일 금요일

gmail 을 이용한 메일 발송 (.NET 2.0)

무료로 smtp와 pop 기능을 제공해 주기 때문에 gmail 많이 사용하실 텐데요.

 

.Net 2.0 으로 gmail 이용해서 메일 보내는 기능 구현하다가 뜻하지 않게 좀 헤맸습니다.

 

다른 분들은 헤매시지 마셨으면 해서 소심하게 올려봅니다.

 

 

SmtpClient sc = new SmtpClient("smtp.gmail.com", 587);                      // port 번호가 587 입니다. 465 아니예요.        

sc.Credentials = new NetworkCredential("id@gmail.com", "password");  // id만 쓰시면 안되고 뒤에 @gmail.com 붙이셔야 되요.

sc.EnableSsl = true;                                                                          // ssl 사용하여야 함.

sc.Send(m);                                                                                     // m은 MailMessage 객체

 

 

왜 닷넷2.0 은 포트 번호를 587 을 써야 되는지 잘 모르겠습니다.

그 전 닷넷 버전은 원래대로 465 쓰시면 됩니다.

 

 

port 번호를 465 말고 587로 쓴다는 것만 아시면 헤맬 일 없으실 겁니다.

 

참조 : http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=18&MAEULNO=8&no=1220&page=3

2007년 11월 12일 월요일

PHP와 COM

출처 : http://www.php.net

PHP는 Win32 플랫폼의 COM과 DCOM 객체에 접근할수 있습니다.

  1. 어떤것을 계산하는 DLL을 빌드했습니다. PHP상에서 이 DLL을 실행시킬수 있는 방법 이 있습니까?
  2. 'Unsupported variant type: xxxx (0xxxxx)'은 무엇을 의미합니까?
  3. PHP에서 비주얼한 객체(visual object)를 조작할수 있습니까?
  4. 세션안에 COM 객체를 저장할 수 있습니까?
  5. COM 에러를 어떻게 추적할 수 있습니까?
  6. 펄에서 쓰던 방법으로 PHP 스크립트에서 DLL 파일을 만들수 있습니까?
  7. 'Unable to obtain IDispatch interface for CLSID {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}'의 의미는 무엇입니까?
  8. 원격 서버에서 COM 객체를 어떻게 실행할수 있습니까?
  9. 'DCOM is disabled in C:\path...\scriptname.php on line 6'라는 메시지를 봤습니다. 어떻게 해야 하나요?
  10. PHP에서 ActiveX 객체를 부르거나/변경할수 있습니까?
  11. 특정 컴포넌트에서 실행중인 인스턴스에 접근 가능합니까?
  12. COM 객체로부터 받은 이벤트를 제어할 방법이 있습니까?
  13. 하나 이상의 인터페이스를 갖는 COM 객체의 메쏘드를 불러 들이려고 하는데 문제에 봉착했습니다. 어떻게 해야 합니까?
  14. 그래서 PHP와 COM이 작동하는군요. COM+는 어떤가요?
  15. PHP가 COM 객체를 다룰수있다면, PHP로 컴포넌트 자원을 관리하는 MTS를 쓸수있지 않을까요?

어떤것을 계산하는 DLL을 빌드했습니다. PHP상에서 이 DLL을 실행시킬수 있는 방법 이 있습니까?

간단한 DLL이라도 PHP에서 실행할 방법은 아직 없습니다. 접근가능한 COM서버를 포함하는 DLL이고, IDispatch 인터페이스로 구현되어있다면 가능할수도 있습니다.

'Unsupported variant type: xxxx (0xxxxx)'은 무엇을 의미합니까?

몇가지의 VARIANT 타입과 그 타입간의 조합이 가능합니다. 그들 대부분은 거의 지원이 되고있지만 일부가 아직 구현되어있지 않습니다. 배열은 완전히 지원되지 않습니다. 오직 1차원 배열만이 PHP와 COM사이에서 전달이 가능합니다. 지원되지 않는 다른 타입을 발견했다면 그 타입을 버그 레포트로 알려주기랍니다 (아직 보고되지 않는것들이라면) 그리고 더 자세한 정보도 함께 제공해주십시오.

PHP에서 비주얼한 객체(visual object)를 조작할수 있습니까?

가능합니다. 하지만 PHP는 대부분 웹서버의 환경에서 웹 스크립트 언어로서 이용되고 있습니다. 따라서 서버가 비주얼 객체를 보여주지는 않을것입니다. 응용프로그램 스크립트를 위한 PHP(PHP-GTK같은)를 사용한다면 COM을 통해서 비주얼 객체(visual object)에 접근하고 조작하는데 아무 제한이 없습니다.

세션안에 COM 객체를 저장할 수 있습니까?

그건 안됩니다. COM 인스턴스는 리소스로 취급되므로 오직 단일 스크립트의 문맥에서만 가용한것입니다.

COM 에러를 어떻게 추적할 수 있습니까?

PHP 5에서, COM 확장은 com_exception 예외를 발생합니다. 이를 잡아서 code 멤버를 조사함으로써 다음에 취할 행동을 결정할 수 있습니다.

PHP 4에서는 COM 오류를 PHP 자체에서 제공하는 방법(@, track_errors, ..)으로 추적할 수 없습니다.

펄에서 쓰던 방법으로 PHP 스크립트에서 DLL 파일을 만들수 있습니까?

만들수 없습니다. 재수없게도 PHP를 위해 그런 툴이 존재하지 않습니다.

'Unable to obtain IDispatch interface for CLSID {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}'의 의미는 무엇입니까?

이 에러는 다음과 같은 원인일수 있습니다.

  • CLSID가 잘못되었다
  • 필요한 DLL이 존재하지 않는다
  • 필요한 컴포넌트가 IDispatch 인터페이스로 구현되지 않았다

원격 서버에서 COM 객체를 어떻게 실행할수 있습니까?

로컬 객체를 실행시키는것과 완전히 똑같습니다. 단지 COM 생성자의 두번째 인수에 다른 서버의 IP를 넘겨주면 됩니다.

php.ini에서 com.allow_dcom=TRUE로 설정해야 합니다.

'DCOM is disabled in C:\path...\scriptname.php on line 6'라는 메시지를 봤습니다. 어떻게 해야 하나요?

php.ini를 수정하여 com.allow_dcom=TRUE로 설정합니다.

PHP에서 ActiveX 객체를 부르거나/변경할수 있습니까?

이것은 PHP에서 할일이 아닙니다. HTML 문서에서 ActiveX 객체가 포함되있으면 클라이언트 단에서 그 코드를 처리하는 것입니다. PHP 스크립트와는 전혀 관련이 없고 따라서 서버단과는 직접적인 관련이 없습니다.

특정 컴포넌트에서 실행중인 인스턴스에 접근 가능합니까?

모니커(monikers)의 도움으로 가능합니다. 하나의 워드 인스턴스로 다방향 레퍼런스를 얻고 싶다면 다음처럼 그 인스턴스를 만들 수 있습니다.

<?php
$word
= new COM("C:\docs\word.doc");
?>

위처럼 하면 실행중인 인스턴스가 없을 때에는 새로운 인스턴스를 만들수 있고, 실행중인 인스턴스가 이미 존재하면 그 핸들을 넘겨주게 됩니다.

COM 객체로부터 받은 이벤트를 제어할 방법이 있습니까?

com_event_sink()를 사용하여 이벤트 싱크와 바인드를 정의할 수 있습니다. PHP가 이벤트 싱크 클래스의 뼈대을 생성하게 하기 위하여 com_print_typeinfo()를 사용할 수 있습니다.

하나 이상의 인터페이스를 갖는 COM 객체의 메쏘드를 불러 들이려고 하는데 문제에 봉착했습니다. 어떻게 해야 합니까?

답은 불만스럽겠지만 간단합니다. 확실치는 않지만 당신은 아무것도 할수없습니다. 어떤사람은 이 문제와 관련된 정보를 가지고 있습니다. » 저에게 알려주시라 :)

그래서 PHP와 COM이 작동하는군요. COM+는 어떤가요?

MTS와 MTMQ를 통해서 컴포넌트를 관리하는 프레임워크가 추가되면서 COM에서 COM+로 발전된것입니다. 그런데 PHP는 그런 컴포넌트를 지원하지 않습니다.

PHP가 COM 객체를 다룰수있다면, PHP로 컴포넌트 자원을 관리하는 MTS를 쓸수있지 않을까요?

PHP 자체로는 아직 트랜젝션을 관리할수 없습니다. 따라서 에러가 발생하더라도 롤백으로 초기화되지않습니다. 트랜젝션을 지원하는 컴포넌트를 사용한다면 트랜젝션 관리를 구현해서 써야합니다.

2007년 10월 15일 월요일

SQL DBA 가이드 (문제 점검 및 해결)

사용자 데이터베이스가 suspect로 표시된 경우에 문제 해결하기

Northwind 데이터베이스의 status 컬럼이 suspect로 설정된 경우를 예를 들어 설명합니다.

[주의] sp_resetstatus SP는 아래와 같은 문제 해결을 위해서만 사용해야 하며, 사용 시 주의를 요합니다.

[참고] SQL Server Errorlog 파일에 "Bypassing recovery for database 'Northwind' because it is marked SUSPECT." 와 같은 메시지가 기록됩니다.

[따라하기]

1. sp_resetstatus가 없으면 생성합니다.
USE master
GO
EXEC sp_configure 'allow updates', 1 
RECONFIGURE WITH OVERRIDE 
GO 
CREATE PROCEDURE sp_resetstatus @dbname varchar(30) 
AS
DECLARE @msg varchar(80)
IF @@trancount > 0
BEGIN
    PRINT 'Can''t run sp_resetstatus from within a transaction.'
    RETURN (1)
END
IF suser_id() != 1
BEGIN
    SELECT @msg = 'You must be the System Administrator (SA)'
    SELECT @msg = @msg + ' to execute this procedure.'
    RETURN (1)
END
IF (SELECT COUNT(*) FROM master..sysdatabases WHERE name = @dbname) != 1
BEGIN
    SELECT @msg = 'Database ' + @dbname + ' does not exist!'
    PRINT @msg
    RETURN (1)
END
IF (SELECT COUNT(*) FROM master..sysdatabases 
WHERE name = @dbname AND status & 256 = 256) != 1
BEGIN
    PRINT 'sp_resetstatus can only be run on suspect databases.'
    RETURN (1)
END
BEGIN TRAN
    UPDATE master..sysdatabases SET status = status ^ 256
    WHERE name = @dbname
    IF @@error != 0 OR @@rowcount != 1
        ROLLBACK TRAN
    ELSE 
    BEGIN
        COMMIT TRAN
        SELECT @msg = 'Database ' + @dbname + ' status reset!'
        PRINT @msg
        PRINT ''
        PRINT 'WARNING: You must reboot SQL Server prior to  '
        PRINT '         accessing this database!'
        PRINT ''
    END
GO
EXEC sp_configure 'allow updates', 0
RECONFIGURE WITH OVERRIDE 
GO
2. Suspect 상태가 된 데이터베이스에 대하여 sp_resetstatus를 실행합니다.
EXEC sp_resetstatus Northwind
GO

3. ALTER DATABASE를 사용하여 Northwind 데이터베이스에 파일을 추가하여 여유 공간을 확보해 줍니다.

4. SQL Server를 중지하고 다시 시작합니다.

 

Tempdb가 suspect 상태가 된 경우의 문제 해결하기

Tempdb가 suspect 상태가 된 경우에 문제를 해결하는 방법을 설명합니다. 참고로 tempdb가 suspect 상태가 되면 SQL Server 서비스 시작이 실패할 수도 있습니다.

[참고] SQL Server Errorlog 파일에 "Database 'tempdb' cannot be opened. It has been marked SUSPECT by recovery." 와 같은 메시지가 기록됩니다.

[따라하기]

1. tempdb.mdf 파일과 tempdb.ldf 파일이 있는지 확인하고, 만약 있으면 파일들의 이름을 변경합니다.

2. 다음과 같은 명령어를 사용하여 명령 프롬프트 상에서 SQL Server를 시작합니다. 명명된 인스턴스인 경우에는 -s 매개변수를 지정합니다.

sqlservr -c -f -T3608 -T4022

[주의] 명령 프롬프트 창이 열린 채로 두어야 합니다. 명령 프롬프트 창을 닫으면 SQL Server 프로세스가 중지됩니다.

3. 쿼리 분석기에서 sp_resetstatus를 수행하여 tempdb의 suspect 상태를 해제합니다.

EXEC master..sp_resetstatus Tempdb

4. 명령 프롬프트 찾에서 키를 눌러 SQL Server 서비스를 중지합니다.

5. SQL Server 서비스를 시작합니다. 이렇게 작업하면 Tempdb 데이터베이스 파일들이 새로 생성되며 tempdb가 정상적으로 복구됩니다.

 

손상된 데이터베이스 복구하기 (DBCC CHECKDB를 사용하여 오류 복구하기)

DBCC CHECKDB 명령어를 사용하면 특정 데이터베이스의 일관성(consistency)를 점검할 수 있습니다. DBCC CHECKDB 명령어는 데이터베이스 손상을 점검하는 주요 수단이며, 다음과 같은 사항들을 점검합니다.

- 인덱스 페이지와 데이터 페이지들이 제대로 연결되어 있는가
- 인덱스가 최신 상태이고, 제대로 정렬되어 있는가
- 포인트들이 일관성이 있는가 (Consistent)
- 각 페이지 상의 데이터가 최신 상태인가
- 페이지 오프셋이 최신 상태인가

[구문]
DBCC CHECKDB
     ( 'database_name'
             [ , NOINDEX
                 | { REPAIR_ALLOW_DATA_LOSS
                     | REPAIR_FAST
                     | REPAIR_REBUILD
                    } ] 
    )     [ WITH { [ ALL_ERRORMSGS ]
                    [ , [ NO_INFOMSGS ] ]
                     [ , [ TABLOCK ] ]
                     [ , [ ESTIMATEONLY ] ] 
                    [ , [ PHYSICAL_ONLY ] ] 
                    } 
        ] 

[사전지식]
DBCC CHECKDB나 DBCC CHECKTABLE에 REPAIR 옵션을 지정하여 수행하고자 하는 경우에는 SQL Server를 단일 사용자 모드로 시작해서는 안되고 해당 데이터베이스를 단일 사용자 모드(single user mode)로 설정해야 합니다
.

[참고] 데이터베이스를 단일 사용자 모드로 설정하는 방법 세 가지
  • 엔터프라이즈 관리자에서 설정하기
    1. 해당 데이터베이스에서 마우스의 오른쪽 버튼을 클릭한 다음에 [속성]을 선택합니다.
    2. 속성 창에서 [옵션] 탭을 선택합니다.
    3. "액세스 제한" checkbox를 선택한 다음에 "단일 사용자"를 선택하고 [확인] 버튼을 클릭합니다.
  • 쿼리 분석기에서 sp_dboption을 사용하여 설정하기
    USE master
    GO
    EXEC sp_dboption db_name, single, true
    GO
    
  • 쿼리 분석기에서 ALTER DATABASE를 사용하여 설정하기 (작업단계)
    1. 지정한 시간이 경과한 후에 완료되지 않은 트랜잭션들을 롤백하고 단일 사용자 모드로 변경하고자 하는 경우
    2. 완료되지 않은 트랜잭션들을 즉시 롤백하고 단일 사용자 모드로 변경하고자 하는 경우
[참고] 복구 옵션에 대하여 이해하기
  • REPAIR_FAST 옵션 : 사소한 손상을 복구하는 작업을 수행하며 수행 시간되 빠르고 데이터 유실도 유발하지 않습니다.
  • REPAIR_REBUILD 옵션 : comprehensive error checking and correction 을 수행하며, 소요 시간이 길고 데이터 유실도 발생하지 않습니다.
  • REPAIR_ALLOW_DATA_LOSS 옵션 : REPAIR_REBUILD가 수행하는 모든 작업들을 동일하게 수행하며, 데이터 유실이 발생할 수 있는 작업을 추가로 수행합니다. 구조적인 문제와 페이지 오류를 정정하고 손상된 텍스트 오브젝트를 삭제하는 작업을 수행하기 때문에 데이터 유실이 발생할 수도 있습니다.

[참고] 복구 작업 단계

  1. 해당 데이터베이스를 단일 사용자 모드로 변경합니다.
  2. REPAIR 옵션을 지정하여 DBCC CHECKDB를 수행합니다.
    2-1. 먼저 REPAIR_FAST 나 REPAIR_REBUILD 옵션을 지정하여 문제 해결을 시도합니다.
    2-2. REPAIR_FAST 나 REPAIR_REBUILD 옵션으로 문제가 해결되지 않으면 REPAIR_ALLOW_DATA_LOSS 옵션을 사용합니다.
    [주의] REPAIR_ALLOW_DATA_LOSS 옵션을 사용하면 데이터의 유실이 발생할 수 있다는 점을 명심하기 바랍니다.
    [권고사항] REPAIR_ALLOW_DATA_LOSS 옵션을 사용하는 경우에는 명령어 수행 후에 다시 원래 상태로 복구할 수 있도록 하기 위해서 트랜잭션 내부에서 DBCC 명령어를 수행할 것을 권고합니다. 이와 같이 작업하면 복구 작업을 수행하고 결과를 확인한 다음에 필요한 경우에 롤백이 가능해집니다.
  3. 복구가 완료되면 데이터베이스를 백업합니다.
[따라하기]
SELECT DATABASEPROPERTYEX ('Northwind', 'UserAccess')
GO
/* 결과:
MULTI_USER
*/

ALTER DATABASE Northwind 
SET SINGLE_USER 
WITH ROLLBACK AFTER 10 --10초 후에 완료되지 않은 트랜잭션들을 롤백
GO

SELECT DATABASEPROPERTYEX ('Northwind', 'UserAccess')
GO
/* 결과:
SINGLE_USER
*/

DBCC CHECKDB ('Northwind', REPAIR_FAST)
GO

ALTER DATABASE Northwind 
SET MULTI_USER 
GO

 

손상된 테이블 복구하기 (DBCC CHECKTABLE을 사용하여 오류 복구하기)

개별 테이블의 문제를 복구하고자 하는 경우에는 DBCC CHECKTABLE 명령어를 사용하면 됩니다.

[구문]
DBCC CHECKTABLE
( 'table_name' | 'view_name'
      	   [ , NOINDEX
   | index_id
   | { REPAIR_ALLOW_DATA_LOSS
                | REPAIR_FAST
         | REPAIR_REBUILD }
           ] 
    	)     [ WITH { [ ALL_ERRORMSGS | NO_INFOMSGS ]
                    [ , [ TABLOCK ] ]
                    [ , [ ESTIMATEONLY ] ] 
                    [ , [ PHYSICAL_ONLY ] ] } 
       	       ] 
[따라하기]
SELECT DATABASEPROPERTYEX ('Northwind', 'UserAccess')
GO
/* 결과:
MULTI_USER
*/

ALTER DATABASE Northwind 
SET SINGLE_USER 
-- 10초 후에 완료되지 않은 트랜잭션들을 롤백
WITH ROLLBACK AFTER 10 
GO

SELECT DATABASEPROPERTYEX ('Northwind', 'UserAccess')
GO
/* 결과:
SINGLE_USER
*/

USE Northwind
GO
DBCC CHECKTABLE (Orders, REPAIR_FAST)
GO

ALTER DATABASE Northwind 
SET MULTI_USER 
GO

-- EXEC sp_dboption 'Northwind', 'single user', 'FALSE'
-- GO

 

단일 로그 파일로 구성된 데이터베이스의 새로운 로그 파일 생성하기

[주의] 로그 파일이 오직 하나인 데이터베이스에 대해서만 사용할 수 있습니다.

[따라하기] 단일 로그 파일을 가지는 'TestDB'의 로그 파일이 유실/손상된 경우에 새로운 로그 파일을 생성하는 방법

EXEC sp_detach_db 'TestDB'
GO
EXEC sp_attach_single_file_db 'TestDB', 'E:\DBdata\TestDB_dat.mdf'
GO

 

DBCC REBUILD_LOG를 사용하여 새로운 로그 파일 생성하기

DBCC REBUILD_LOG는, 데이터베이스의 트랜잭션 로그 파일을 사용할 수 없는 경우에 새로운 로그를 재구축하는데 사용되는 명령어입니다.
예를 들어, 하드웨어의 장애로 인하여 로그 파일이 손상되거나 실수로 로그 파일을 삭제하여 기존의 로그 파일을 액세스할 수 없어서 데이터베이스를 사용할 수 없는 경우에 DBCC REBUILD_LOG를 사용하여 로그를 재구축할 수 있습니다. 로그 파일이 하나인 경우에는 먼저 위의 해결 방법을 적용해 본 다음에 실패하면 이 방법을 사용하기 바랍니다.
그러나, 이 명령어를 사용하면 로그에 반영되지 않은 유실된 트랜잭션들의 발생으로 데이터베이스의 일관성이 손상될 가능성이 매우 높다는 점을 유의해야 합니다. 문제가 발생하면 일단 다른 방법 (예를 들어, sp_attach_single_file_db)을 동원하여 문제 해결을 시도하고, 도저히 다른 방법으로는 데이터베이스를 복구할 수 없는 경우에 이 명령어를 사용하기 바랍니다. 이 명령어를 수행하면 로그에 반영되지 않는 트랜잭션의 발생으로 인하여 데이터 무결성이 손상될 가능성이 높기 때문입니다. 이 명령어는 문서로 제공되지 않는 명령어이며 마이크로소프트 고객 지원 서비스의 지원 하에서 사용하는 것이 원칙이지만, 고객 지원 서비스를 받을 수 없는 경우의 응급 복구 작업에 참고하시라고 알려 드립니다. 또한, 하드웨어 장애와 같은 문제가 발생한 경우에는 트랜잭션 로그 파일 뿐만 아니라 데이터까지 손상시켰을 가능성이 높으므로, DBCC REBUILD_LOG가 성공적으로 완료된 이후에 단일 사용자 모드에서 DBCC CHECKDB를 수행하여 데이터의 일관성 (Consistency) 을 확인하는 작업이 반드시 필요합니다.

[구문] DBCC REBUILD_LOG('db_name','log_filename')

db_name : 문제가 발생한 데이터베이스의 이름
log_filename : 새로운 로그 파일에 대한 완전한 물리적 경로

[주의] 이 방법을 사용하면 데이터 일관성이 손상될 가능성이 매우 높으므로 다른 방법으로는 도저히 데이터베이스를 복구할 수 없는 경우에 최후의 방법으로서 사용해야 하며, 매우 신중하게 작업해야 하며, 이 명령어는 문서로 제공되지 않는 명령어로서 마이크로소프트 제품 고객 지원 서비스의 지원 하에서 사용해야 합니다.

[오류 발생]
로그 파일이 유실 또는 손상된 경우에는 그 데이터베이스는 엔터프라이즈 관리자에 "주의 대상" (suspect)로 표시되며, 쿼리 분석기나 엔터프라이즈 관리자에서 주의
대상 상태가 된 데이터베이스를 액세스하려고 하면 다음과 같은 오류가 발생합니다

서버: 메시지 945, 수준 14, 상태 2, 줄 1
파일을 액세스할 수 없거나 메모리 또는 디스크 공간이 부족하여 'RebuildLogTest' 데이터베이스를 열 수 없습니다. 자세한 내용은 SQL Server 오류 로그를 참조하십시오.

그리고 SQL Server를 재시작하면 ERRORLOG 파일에 다음과 같은 오류 메시지가 기록됩니다.

2005-01-12 14:51:56.72 spid11 'RebuildLogTest' 데이터베이스를 시작하는 중입니다.
2005-01-12 14:51:57.24 spid11 장치 활성화 오류입니다. 물리적 파일 이름 'C:\Program Files\Microsoft SQL Server\MSSQL\data\RebuildLogTest_log.LDF'이(가) 잘못된 것 같습니다.

이와 같은 오류가 발생하고 데이터베이스에 연결할 수 없는 경우에 다음과 같은 작업 단계로 복구 작업을 수행하면 로그를 재구축할 수 있습니다.

[예제] 다음은 RebuildLogTest라는 데이터베이스를 복구하는 예제입니다.

  1. 설정된 옵션들을 확인합니다.
    EXEC sp_dboption RebuildLogTest
    GO
    
  2. 시스템 테이블에 대한 직접적인 업데이트가 가능하도록 변경합니다.
    EXEC sp_configure 'allow updates', 1
    RECONFIGURE WITH OVERRIDE
    GO
    
  3. 문제가 발생한 데이터베이스를 응급 모드(bypass recovery)로 설정합니다
    UPDATE master..sysdatabases SET status = 32768 
    WHERE name = 'RebuildLogTest'
    GO
    
  4. SQL Server 서비스를 중지하고 다시 시작합니다.
  5. DBCC REBUILD_LOG를 수행합니다. 이 때 로그 파일의 이름에는 로그 파일이 저장될 경로까지 전체 이름을 기술해야 하며, 로그 파일은 기존에 존재하지 않는 이름을 지정해야 합니다.
    USE master
    GO
    DBCC REBUILD_LOG('rebuildlogtest','C:\Program Files\Microsoft SQL Server\MSSQL\data\RebuildLogTest_log.LDF')
    GO

    [참고]
    이 명령어가 정상적으로 수행되면 결과창에 다음과 같은 메시지가 반환되며, 데이터베이스는 'dbo use only' 모드가 됩니다. 이전의 status 값과 무관하게 sysdatabases 테이블의 status 값이 2048로 설정됩니다. sp_dboption이나 엔터프라이즈 관리자를 사용하여 status 값을 원하는 값으로 변경하면 됩니다.

    경고: 'RebuildLogTest' 데이터베이스에 대한 로그가 다시 작성되었습니다. 트랜잭션에 일관성이 없습니다. 물리적 일관성을 검사하려면 DBCC CHECKDB를 실행해야 합니다. 데이터베이스 옵션을 원래대로 설정하고 다른 로그 파일을 삭제해야 합니다.

    DBCC 실행이 완료되었습니다. DBCC에서 오류 메시지를 출력하면 시스템 관리자에게 문의하십시오.

    만약 이미 있는 파일 이름을 지정한 경우에는 다음과 같은 오류 메시지가 반환됩니다.

    서버: 메시지 5025, 수준 16, 상태 1, 줄 2
    'C:\Program Files\Microsoft SQL Server\MSSQL\data\RebuildLogTest_log.LDF' 파일이 이미 있습니다. 새 로그 파일을 만들려면 이 파일의 이름을 바꾸거나 삭제해야 합니다.

    DBCC 실행이 완료되었습니다. DBCC에서 오류 메시지를 출력하면 시스템 관리자에게 문의하십시오.

  6. 시스템 테이블을 직접 업데이트할 수 없도록 원래 값으로 변경합니다.
    EXEC sp_configure 'allow updates', 0
    RECONFIGURE WITH OVERRIDE
    GO
    
  7. 데이터베이스를 단일 사용자 모드로 변경하고 DBCC CHECKDB를 수행하여 일관성을 점검합니다. 데이터베이스를 단일 사용자 모드로 변경하는 보다 자세한 방법은 "손상된 데이터베이스 복구하기" 를 참조하기 바랍니다.
    EXEC sp_dboption ' RebuildLogTest ', 'single user', 'true'
    DBCC CHECKDB('RebuildLogTest')
    GO
    
  8. DBCC CHECKDB를 수행한 결과 문제가 없으면, 그 데이터베이스를 정상적으로 사용할 수 있습니다. 그러나 롤백되어야 할 트랜잭션이 롤백되지 않거나, 데이터에 반영되어야 할 수정 작업이 반영되지 않는 문제가 발생할 수 있으므로, 논리적인 데이터의 무결성은 별도의 점검이 필요합니다.
  9. 데이터베이스 옵션을 원래대로 설정하고, 로그 파일의 크기도 원래 크기로 확장합니다. 로그파일을 재구축하면, 504KB의 작은 크기의 로그 파일이 생성됩니다.

교착상태(Deadlock) 발생 시 교착상태 추적하기

추적 플래그 1204를 사용하면 교착상태(Deadlock)에 대한 내용을 확인하는 것이 가능합니다. 명령 프롬프트에서 추적 플래그를 추가하여 SQL Server 서비스를 시작할 수도 있고, 엔터프라이즈 관리자에서 SQL Server 시작 매개 변수에서 추적 플래그를 추가할 수도 있습니다.

  • 명령 프롬프트에서 추적 플래그를 지정하는 방법

    [따라하기]

    1. SQL Server 서비스를 중지해도 되는 시점에 SQL Server 서비스를 중지합니다.
    2. 다음과 같이 추적 플래그를 추가하고 SQL Server 서비스를 시작합니다.
      [주의] SQL Server 서비스를 시작한 명령 프롬프트의 창은 그대로 두어야 합니다. 명령프롬프트 창을 닫거나, 를 입력하면 SQL Server 서비스가 중지됩니다. [참고] sqlservr.exe 파일은 SQL Server 설치 폴더의 하위 폴더 중 하나인 binn에 있습니다.

      [예] 추적 플래그를 추가하여 디폴트 인스턴스 SQL Server 서비스를 시작하는 예제 (SQL Server 2000 서비스 팩3부터는 -T3605를 추가하지 않아도 ERRORLOG에 추적결과가 기록됩니다.)
      sqlservr -c -T1204  -T3605
      
    3. 위와 같이 작업하면 교착상태 추적 결과가 SQL Server 서비스가 시작된 콘솔 화면과 ERRORLOG 파일로 기록됩니다.

  • 엔터프라이즈 관리자에서 추적 플래그를 지정하는 방법
    1. 엔터프라이즈 관리자에서 [속성] → [시작 매개 변수] "매개 변수"에 -T1204와 -T3605를 입력하고 [추가] 버튼을 클릭한 다음에 [확인] 버튼을 클릭합니다.
    2. SQL Server 서비스를 중지하고 재시작 합니다.
    3. 교착상태가 발생하면 교착상태 추적 결과가 ERRORLOG 파일로 기록됩니다.

    [교착상태에 대한 추적결과 예]
    추적 플래그 1204를 추가하고 SQL Server 서비스를 시작하면 교착상태에 대한 추적결과가 다음과 같은 형태로 반환 또는 기록됩니다.

    2003-02-25 05:12:55.13 spid4
    Deadlock encountered .... Printing deadlock information
    2003-02-25 05:12:55.13 spid4
    2003-02-25 05:12:55.13 spid4 Wait-for graph
    2003-02-25 05:12:55.13 spid4
    2003-02-25 05:12:55.13 spid4 Node:1
    2003-02-25 05:12:55.14 spid4 RID: 2:1:15:0     CleanCnt:1 Mode: X Flags: 0x2
    2003-02-25 05:12:55.14 spid4 Grant List 0::
    2003-02-25 05:12:55.14 spid4 Owner:0x192e32e0 Mode: X  Flg:0x0 Ref:0 Life:02000000 SPID:52 ECID:0
    2003-02-25 05:12:55.15 spid4 SPID: 52 ECID: 0 Statement Type: DELETE Line #: 1
    2003-02-25 05:12:55.15 spid4 Input Buf: Language Event: delete deadt2

    2003-02-25 05:12:55.15 spid4 Requested By:
    2003-02-25 05:12:55.15 spid4 ResType:LockOwner Stype:'OR' Mode: U SPID:51 ECID:0 Ec:(0x19CA3500) Value:0x192e3340 Cost:(0/98)
    2003-02-25 05:12:55.16 spid4
    2003-02-25 05:12:55.16 spid4 Node:2
    2003-02-25 05:12:55.16 spid4 RID: 2:1:28:0     CleanCnt:1 Mode: X Flags: 0x2
    2003-02-25 05:12:55.17 spid4 Grant List 0::
    2003-02-25 05:12:55.17 spid4 Owner:0x192e3400 Mode: X   Flg:0x0 Ref:0 Life:02000000 SPID:51 ECID:0
    2003-02-25 05:12:55.17 spid4 SPID: 51 ECID: 0 Statement Type: DELETE Line #: 1
    2003-02-25 05:12:55.18 spid4 Input Buf: Language Event: delete deadt1

    2003-02-25 05:12:55.18 spid4 Requested By:
    2003-02-25 05:12:55.18 spid4 ResType:LockOwner Stype:'OR' Mode: U SPID:52 ECID:0 Ec:(0x19AB9508) Value:0x192e3300 Cost:(0/98)
    2003-02-25 05:12:55.19 spid4 Victim Resource Owner:
    2003-02-25 05:12:55.19 spid4 ResType:LockOwner Stype:'OR' Mode: U SPID:52 ECID:0 Ec:(0x19AB9508) Value:0x192e3300 Cost:(0/98)


    블로킹 발생 시 원인 추적하기

  • 다음에 소개하는 저장 프로시저들은 블로킹을 점검하는데 유용하게 사용할 수 있는 저장 프로시저들입니다. 다음의 저장 프로시저들은 master 데이터베이스에 생성해 두고 블로킹 발생 시에 활용하실 것을 권고합니다.

    • sp_blocker_pss80
      블로킹에 관한 전반적인 정보를 수집할 수 있는 매우 유용한 저장 프로시저입니다. Microsoft 웹사이트의 다음 아티클에 sp_blocker_pss80 저장 프로시저 생성 스크립트가 있으므로 활용하시기 바랍니다.
      http://support.microsoft.com/default.aspx?scid=kb;ko-kr;271509
      (아티클 제목 : How to monitor SQL Server 2000 blocking)
    • sp_leadblocker, sp_blockinglocks
      Inside SQL Server 책에 있는 스크립트로서, 블로킹 발생의 원인이 되는 프로세스에 대한 정보와, 블로킹에 관련되는 잠금에 대한 정보를 제공하는 저장 프로시저입니다.
    [따라하기]
    1. 블로킹 추적에 유용한 저장 프로시저들을 생성합니다. (sp_blocker_pss80, sp_leadblocker, sp_blockinglocks)
      USE master
      GO
      CREATE PROCEDURE sp_leadblocker  AS  
      IF EXISTS  
          (SELECT * FROM master.dbo.sysprocesses  
          WHERE spid IN (SELECT blocked FROM master.dbo.sysprocesses))  
          SELECT   
              spid, status, loginame=SUBSTRING(SUSER_SNAME(sid), 1, 12),  
              hostname=substring(hostname, 1, 12),  
                  blk=CONVERT(char(3), blocked),  
              dbname=substring(db_name(dbid),1,10),cmd, waittype  
          FROM master.dbo.sysprocesses  
          WHERE spid IN (SELECT blocked FROM master.dbo.sysprocesses)  
          AND blocked=0  
      ELSE  
      SELECT 'No blocking processes found!'
      GO
      CREATE PROCEDURE sp_blockinglocks AS
      SET NOCOUNT ON  
      SELECT  DISTINCT CONVERT (SMALLINT, L1.req_spid) AS SPID,   
        L1.rsc_dbid AS DBID,   
        L1.rsc_objid AS OBJID,  
        L1.rsc_indid AS INDID,  
        SUBSTRING (V.name, 1, 4) AS TYPE,  
        SUBSTRING (L1.rsc_text, 1, 16) AS RESOURCE,  
        SUBSTRING (U.name, 1, 8) AS MODE,  
        SUBSTRING (X.name, 1, 5) AS STATUS  
      FROM  master.dbo.syslockinfo L1,  
          master.dbo.syslockinfo L2,  
        master.dbo.spt_values V,  
        master.dbo.spt_values X,  
        master.dbo.spt_values U  
      WHERE L1.rsc_type = V.number  
         AND V.type = 'LR'  
         AND L1.req_status = X.number  
         AND X.type = 'LS'  
         AND L1.req_mode + 1 = U.number  
         AND U.type = 'L'  
         AND L1.rsc_type <>2 /* 2 : DB LOCK */  
         AND L1.rsc_dbid = L2.rsc_dbid  
         AND L1.rsc_bin = L2.rsc_bin  
         AND L1.rsc_objid = L2.rsc_objid   
         AND L1.rsc_indid = L2.rsc_indid   
         AND L1.req_spid <> L2.req_spid  
         AND L1.req_status <> L2.req_status  
        --AND(L1.req_spid IN (SELECT BLOCKED FROM master..SYSPROCESSES)  
        -- OR L2.req_spid IN (SELECT BLOCKED FROM master..SYSPROCESSES))  
      ORDER BY SUBSTRING (L1.rsc_text, 1, 16), SUBSTRING (X.name, 1, 5)   
      RETURN (0) 
      GO
      
    2. 시스템 SP 및 DBCC 명령어와 작업 단계 1에서 추가한 SP를 수행하여 그 결과를 분석합니다.
      2-1. sp_blocker_pss80 활용예
      WHILE 1=1
      BEGIN
         		EXEC master.dbo.sp_blocker_pss80
         		-- Or for fast mode
         		-- EXEC master.dbo.sp_blocker_pss80 @fast=1
         		-- Or for latch mode
         		-- EXEC master.dbo.sp_blocker_pss80 @latch=1
         		WAITFOR DELAY '00:00:15'
      END
      GO
      
      2-2. sp_leadblocker, sp_blockinglocks 활용예
      EXEC sp_leadblocker
      EXEC sp_blockinglocks
      GO
      
      2-3. 블로킹을 유발하는 프로세스에 대하여 sp_lock, sp_who2, sp_who 등의 시스템 SP를 수행하면 잠금과 프로세스에 대한 보다 자세한 내용을 별도로 점검할 수 있습니다.
      	EXEC sp_who2 53
      	EXEC sp_lock 53
      	GO
      
      2-4. 트랜잭션을 오픈한 채로 있는 프로세스가 블로킹을 유발하는 경우에는 DBCC OPENTRAN을 사용하여 특정 데이터베이스에서 가장 오래된 활성 트랜잭션에 대한 정보를 점검할 수 있습니다. 참고로, 트랜잭션에 트랜잭션 이름을 기술하면 문제가 있는 트랜잭션을 확인하는 작업이 용이해집니다.
      	USE pubs
      	DBCC OPENTRAN 
      	GO
      	-- 또는
      	DBCC OPENTRAN ('pubs')
      	GO
      

    대기(wait) 점검하기

    [따라하기]
    1. wait 정보를 저장할 데이터베이스를 생성합니다.
      USE master
      GO
      CREATE DATABASE DBAdmin 
      ON (
      NAME = DBAdmin_dat, 
      FILENAME = 'D:\DBdata\DBAdmin_dat.mdf'
      SIZE = 500 MB, 
      MAXSIZE = 1 GB, 
      FILEGROWTH = 100 MB) 
      LOG ON (
      NAME = DBAdmin_log, 
      FILENAME = 'D:\ DBData\DBAdmin_log.ldf', 
      SIZE = 100 MB, 
      MAXSIZE = 500 MB, 
      FILEGROWTH = 100 MB) 
      GO
      
    2. wait 정보를 추적할 저장 프로시저를 생성합니다.
      USE DBAdmin
      GO
      CREATE PROCEDURE get_waitstats
      AS
      -- This stored procedure is provided "AS IS" with no warranties,
      -- and confers no rights.
      -- Use of included script samples are subject to the terms specified at
      -- http://www.microsoft.com/info/cpyright.htm
      -- this proc will create waitstats report listing wait types by percentage
      -- can be run when track_waitstats is executing
      SET NOCOUNT ON

      DECLARE @now datetime, @totalwait numeric(20,1)
      ,@endtime datetime,@begintime datetime
      ,@hr int, @min int, @sec int

      SELECT @now=max(now),@begintime=min(now),@endtime=max(now)
      FROM waitstats WHERE [wait type] = 'Total'

      -- subtract waitfor, sleep, and resource_queue from Total
      SELECT @totalwait = sum([wait time]) + 1
      FROM waitstats
      WHERE [wait type] not in
      ('WAITFOR','SLEEP','RESOURCE_QUEUE', 'Total', '***total***')
      AND now = @now

      -- insert adjusted totals, rank by percentage descending
      DELETE waitstats WHERE [wait type] = '***total***' and now = @now
      INSERT INTO waitstats select '***total***',0,@totalwait,@totalwait,@now

      SELECT [wait type],[wait time]
      ,percentage=cast (100*[wait time]/@totalwait as numeric(20,1))
      FROM waitstats
      WHERE [wait type] not in
      ('WAITFOR','SLEEP','RESOURCE_QUEUE','Total')
      AND now = @now
      ORDER BY percentage DESC
      GO

      CREATE PROCEDURE track_waitstats (@num_samples int=10,@delaynum int=1,@delaytype nvarchar(10)='minutes')
      AS
      -- T. Davidson
      -- This stored procedure is provided "AS IS" with no warranties,
      -- and confers no rights.
      -- Use of included script samples are subject to the terms specified at
      -- http://www.microsoft.com/info/cpyright.htm
      -- @num_samples is the number of times to capture waitstats,
      -- default is 10 times. default delay interval is 1 minute
      -- delaynum is the delay interval.
      -- delaytype specifies whether the delay interval is minutes or seconds
      -- create waitstats table if it doesn't exist,
      -- otherwise truncate
      SET NOCOUNT ON
      IF NOT EXISTS (SELECT 1 FROM sysobjects WHERE name = 'waitstats')
      CREATE TABLE waitstats ([wait type] varchar(80),
      requests numeric(20,1),
      [wait time] numeric (20,1),
      [signal wait time] numeric(20,1),
      now datetime default getdate())
      ELSE TRUNCATE TABLE waitstats

      DBCC SQLPERF (waitstats,clear) -- clear out waitstats
      DECLARE @i int,@delay varchar(8),@dt varchar(3)
      , @now datetime, @totalwait numeric(20,1)
      ,@endtime datetime,@begintime datetime
      ,@hr int, @min int, @sec int
      SELECT @i = 1
      SELECT @dt = CASE lower(@delaytype)
      WHEN 'minutes' THEN 'm'
      WHEN 'minute' THEN 'm'
      WHEN 'min' THEN 'm'
      WHEN 'mm' THEN 'm'
      WHEN 'mi' THEN 'm'
      WHEN 'm' THEN 'm'
      WHEN 'seconds' THEN 's'
      WHEN 'second' THEN 's'
      WHEN 'sec' THEN 's'
      WHEN 'ss' THEN 's'
      WHEN 's' THEN 's'
      ELSE @delaytype
      END
      IF @dt not in ('s','m')
      BEGIN
      PRINT 'please supply delay type e.g. seconds or minutes'
      RETURN
      END

      IF @dt = 's'
      BEGIN
      SELECT @sec = @delaynum % 60
      SELECT @min = cast((@delaynum / 60) as int)
      SELECT @hr = cast((@min / 60) as int)
      SELECT @min = @min % 60
      END
      IF @dt = 'm'
      BEGIN
      SELECT @sec = 0
      SELECT @min = @delaynum % 60
      SELECT @hr = cast((@delaynum / 60) as int)
      END
      SELECT @delay= right('0'+ convert(varchar(2),@hr),2) + ':' +
      + right('0'+convert(varchar(2),@min),2) + ':' +
      + right('0'+convert(varchar(2),@sec),2)
      IF @hr > 23 or @min > 59 or @sec > 59
      BEGIN
      SELECT 'hh:mm:ss delay time cannot > 23:59:59'
      SELECT 'delay interval and type: ' + convert (varchar(10),@delaynum)
      + ',' + @delaytype + ' converts to ' + @delay
      RETURN
      END
      WHILE (@i <= @num_samples)
      BEGIN
      INSERT INTO waitstats ([wait type], requests, [wait time],[signal wait time])
      EXEC ('DBCC SQLPERF(WAITSTATS)')
      SELECT @i = @i + 1
      WAITFOR DELAY @delay
      END
      --- create waitstats report
      EXEC get_waitstats
      GO

    3. 수집 간격과 반복 실행 횟수를 지정하여 대기 정보를 수집합니다.
      -- 2초 간격으로 10번 반복 수행 예제
      USE DBAdmin
      EXEC Track_waitstats @num_samples=10,@delaynum=2,@delaytype='seconds'
      GO
      SELECT * FROM waitstats
      GO
      -- 실행 예제 : 디폴트 ( 실행 소요 시간 : 10분 ) 
      USE DBAdmin
      EXEC Track_waitstats
      GO
      


  • 출처 : http://blog.naver.com/ngmaster/120038831061

    2007년 10월 5일 금요일

    복원의 새로운 점

    온라인 복원
    SQL Server 2005 엔터프라이즈 에디션에는 백업으로부터 온라인상에서 복원할 수 있는 새로운 기술을 장착했습니다. 이러한 기능은 2000에서는 모든 파일이 복원이 되어야 서비스가 되었던 것에 비해 서비스 중지시간을 줄일 수 있습니다. (단 전체복구 모델과 대량복구모델에 대해서만 가능합니다.)

     가능환경
    1. 엔터프라이즈 에디션과 디벨로퍼 에디션에서만 지원합니다.
    2. 다수의 파일그룹을 가지고 있는 데이터베이스에 해당됩니다.
    3. Secondary 파일그룹이 복원되는 동안만 접근이 불가능합니다.
    4. 파일그룹이 복원될 때, 모든 파일그룹이 복원이 되어야만 데이터베이스의 일관성이 유지됩니다.

    2000와 마찬가지로 2005에서 오프라인 복원작업을 그대로 하실 수 있습니다. 또한 SQL Server Management Studio를 이용해서 데이터베이스와 로그를 복원하실 수 있습니다.

    2005에서는 2000 및 7.0에서 백업사본에 대해서는 오프라인 복원만 지원합니다. 온라인 복원을 수행하기 위해서는 2005에서 백업된 소스를 이용해야 합니다.

    2005의 RESTORE 명령어는 새로운 옵션 RESTRICTED_USER을 포함하고 있습니다. 이 옵션은 복원된 데이터베이스에 db_owner, dbcreator, sysadmin 역할을 가진 구성원에게 제한적으로 접근을 하게 합니다.

    온라인 복원은 두 가지 레벨로 지원됩니다.

     Page Online Restore(페이지단위 온라인 복원)
    온라인 복원의 특징은 문제가 있는 페이지를 고립시켜서 이 문제된 페이지가 다른 정상적인 데이터베이스를 복원하는데 있어 그 영향을 거의 주지 않는 다는 것입니다. 손상된 페이지는 데이터베이스로그에 남겨지게 됩니다.

    손상된 페이지에 접근을 하면 에러가 발생 할 것이며 에러로그에 그 결과가 남게 될 것입니다. 이렇게 얻어진 정보를 통해서 페이지의 위치를 알아내고 유용한 백업자료에서 복원을 하게 됩니다.

    [페이지 복원 절차] 

    --1) 손상된 페이지의 ID를 찾아냅니다.
    SELECT * FROM msdb..suspect_page_table

    --2) 트랜잭션로그의 진행중인 부분을 백업합니다.
    BACKUP LOG AdventureWorks
    TO DISK =‘ Active_Log.bak’WITH NO_TRUNCATE

    --3) 가장 최근의 전체 백업이나 차등백업으로부터 손상된 페이지를 복원합니다.
    RESTORE DATABASE AdventureWorks PAGE =‘ 3:3241’
    FROM DISK =‘ ...’WITH NORECOVERY

    --4) 로그백업을 수행하고 데이터베이스를 복원합니다.
    RESTORE LOG AdventureWorks
    FROM DISK =‘ ...’WITH NORECOVERY
    .
    .
    .
    RESTORE LOG AdventureWorks
    FROM DISK =‘ ...’WITH RECOVERY

    --5) 수행중인 로그백업을 사용해서 복원합니다.
    RESTORE LOG AdventureWorks
    FROM DISK =‘ Active_Log.bak’
    WITH RECOVERY

     파일 단위 온라인 복원
    데이터베이스의 파일그룹에서 어느 한 파일이라도 복원 중에 있다면 전체 파일 그룹은 오프라인 상태에 있게 됩니다. 그래서 주 파일그룹에 있는 하나의 파일이라도 복원 중이면 전체 데이터베이스는 오프라인상태가 됩니다. 하지만 주파일 그룹의 복구가 끝나면 데이터베이스는 온라인상태가 되며 각각의 이차파일그룹(Secondary filegroup)이 복원이 되면 해당 파일 그룹은 자동으로 온라인이 됩니다.

    [파일단위 복원 절차]

    --1) 활성중인 트랜잭션로그 백업하기
    BACKUP LOG AdventureWorks
    TO DISK =‘ Active_Log.bak’WITH NO_TRUNCATE

    --2) 손상된 파일 복원하기
    RESTORE DATABASE AdventureWorks FILE =‘ Logical_Damaged_Filename’
    FROM DISK =‘ ...’WITH NORECOVERY

    --3) 트랜잭션 로그 복원하기
    RESTORE LOG AdventureWorks
    FROM DISK =‘ ...’WITH NORECOVERY

    --4) 활성중인 트랜잭션 로그를 복원하고 해당 데이터베이스 복구하기.
    RESTORE LOG AdventureWorks
    FROM DISK =‘ Active_Log.bak’
    WITH RECOVERY


    Piecemeal 복원
    2005 엔터프라이즈 에디션에서는 Piecemeal 복원을 지원합니다. 이 복원은 파일그룹단위로 복원을 진행합니다. 이때 복원되는 그룹단위로 온라인 상태로 됩니다. 이전 버전에서는 모든 파일 그룹이 복원이 되기 때문에 우선적으로 온라인 상태가 되어야 하는 경우 복원시간이 많이 소요되었습니다. 예를 들어 파일그룹하나에 문제가 있는 경우 다른 파일그룹에까지 영향을 미치게 되어 복원에 문제가 발생할 수 있습니다.

    2005에서 이 Piecemeal 복원을 이용하면 중요도 높은 파일 그룹부터 복원하고 서비스를 할 수 있게 됩니다.


    [따라하기] Piecemeal 복원 

    USE master
    GO
    DROP DATABASE piecemealTest
    GO
    -- 테스트용데이터베이스생성
    CREATE DATABASE [piecemealTest] ON PRIMARY
    ( NAME = N’piecemealTest’, FILENAME = N’c:₩temp₩piecemealTest.mdf’,
    SIZE = 3MB , FILEGROWTH = 10%),
    FILEGROUP [second]
    ( NAME = N’second’, FILENAME = N’c:₩temp₩second.ndf’, SIZE = 3MB ,
    FILEGROWTH = 10%),
    FILEGROUP [third]
    ( NAME = N’third’, FILENAME = N’c:₩temp₩third.ndf’, SIZE = 3MB ,
    FILEGROWTH = 10%)
    LOG ON
    ( NAME = N’ piecemealTest_log’ , FILENAME = N’ c:₩ temp
    ₩piecemealTest_log.ldf’, SIZE = 1024KB , FILEGROWTH = 1024KB )
    GO
    USE piecemealTest
    GO

    -- 데이터베이스의기본파일그룹을변경합니다.
    ALTER DATABASE piecemealTest
    modify FILEGROUP second default
    GO

    -- od라는테이블을northwind 데이터베이스에있는order details 테이블을이용하여만듭니다.
    SELECT TOP 100
    productid, quantity
    INTO od
    FROM northwind..biGOd
    GO

    -- 주파일그룹에테이블odonPrimary를생성합니다.
    CREATE table odonPrimary
    (productID int
    ,quantity int
    ) on [primary]
    GO

    -- 세번째파일그룹에테이블od3rd를생성합니다.
    CREATE table od3rd
    (productID int
    ,quantity int
    ) on THIRD
    GO

    -- 위에서생성한테이블에값을넣습니다.
    INSERT INTO od3rd
          SELECT productID, quantity FROM od
    INSERT INTO odOnPrimary
          SELECT productID, quantity FROM od
    GO

    -- 백업장치dumpPiece와dumpPieceLog를생성합니다.
    exec sp_addumpdevice’disk’,’dumpPiece’,’c:₩temp₩dumpPiece.bak’
    exec sp_addumpdevice’disk’,’dumpPieceLog’,’c:₩temp₩dumpPieceLog.bak’
    GO
    -- 생성확인을합니다.
    sp_helpdevice

    SELECT TOP 100 * FROM od

    -- od 테이블(second file group)에값을변경합니다.
    update od -- second group
    set quantity=2000
    where productID=11
    GO

    -- od3rd 테이블(third file group)에값을변경합니다.
    update od3rd --third group
    set quantity=3000
    where productID=11
    GO

    -- odOnPrimary 테이블(Primary file group)에값을변경합니다.
    update odOnPrimary -- Primary group
    set quantity=1000
    where productID=11
    GO

    -- 전체백업을수행합니다.
    BACKUP DATABASE piecemealTest to dumpPiece WITH init
    GO
    -- 로그백업을수행합니다.
    BACKUP log piecemealTest to dumpPiecelog WITH init
    GO

    USE master
    GO

    RESTORE DATABASE piecemealTest
    FILEGROUP=’Primary’--FILEGROUP=’Primary’
    FROM dumpPiece WITH partial,norecovery,replace

    RESTORE DATABASE piecemealTest
    FROM dumpPiece WITH partial,norecovery,replace

    RESTORE log piecemealTest FROM dumpPieceLog
    GO

    USE piecemealTest
    GO
    SELECT * FROM odOnPrimary
    GO
    SELECT * FROM od
    GO
    SELECT * FROM od3rd
    GO
    --결과메시지
    --복원은Primary 에서이루어졌기때문에
    --Second에있는od 테이블과third에있는od3rd는온라인상태가 되지못했다.
    (100개행적용됨)
    메시지8653, 수준16, 상태1, 줄1
    테이블’od’이(가) 온라인상태가아닌파일그룹에있어서쿼리프로세서에서이테이블또는뷰에대한계획을생성할수없습니다.

    메시지8653, 수준16, 상태1, 줄1
    테이블’od3rd’이(가) 온라인상태가아닌파일그룹에있어서쿼리프로세서에서이테이블또는뷰에대한계획을생성할수없습니다.

    SQL 2000에서는 위까지의 과정을 수행하면 모든 파일이 복구 됩니다.

    USE master
    GO
    BACKUP log piecemealTest to disk =‘ c:₩temp₩log1’WITH no_truncate, init

    -- 이번에는Second 그룹에있는파일을복원합니다.
    RESTORE DATABASE piecemealTest
    FILEGROUP=’SECOND’
    FROM dumpPiece
    WITH partial,norecovery
    GO
    RESTORE log piecemealTest FROM dumpPieceLog

    USE piecemealTest
    GO
    SELECT * FROM odOnPrimary
    GO
    SELECT * FROM od
    GO
    SELECT * FROM od3rd
    GO
    -- 결과에서Primary 그룹과Second 그룹은복원이되었고
    -- third 그룹은 아직접근할수없다.
    (100개행적용됨)

    (100개행적용됨)
    메시지8653, 수준16, 상태1, 줄1
    테이블’od3rd’이(가) 온라인상태가아닌파일그룹에있어서쿼리프로세서에서이테이블또는뷰에대한계획을생성할수없습니다.


    응급데이터베이스 상태
    백업매체의 문제로 인한 복원의 실패나 문제가 있는 데이터베이스를 복구하려 할 때 ALTER DATABASE 명령문에 EMERGENCY 문을 추가해서 데이터베이스를 응급상태로 전환 시킬 수 있습니다.

    데이터베이스가 주의상태로 표시된다면 데이터베이스의 상태를 응급으로 변경할 수 있습니다. 이렇게 변경을 하면 데이터베이스는 읽기전용으로 바꾸거나 데이터베이스를 분리할 수 있습니다.

    응급상태로 전환을 하게되면 데이터베이스는 단독접근(Single user)이 되고 sysadmin 서버 역할을 가진 로그인만 접속 가능합니다. 그리고, 읽기전용데이터베이스가 됩니다. 이런 상태에서 데이터베이스의 복구를 가능하게 합니다.

    [따라하기] AdventureWorks 데이터베이스 응급상태로 전환하기

    USE master
    go

    ALTER DATABASE AdventureWorks
    SET EMERGENCY
    GO

     

    -- 데이터베이스의 특성을 살펴봅니다.
    SELECT DATABASEPROPERTYEX‘( AdventureWorks’,‘ Status’)
    SELECT name, state, state_desc FROM sys.databases

     

    USE AdventureWorks
    GO

    SELECT * FROM sales.Store

    BEGIN TRAN
    Go

    --아래의문장은실패합니다.
    UPDATE sales.Store SET name =‘ X’+name
    go

    ROLLBACK

    메시지3908, 수준16, 상태1, 줄3
    데이터베이스’adventureworks’은(는) 복구무시모드이므로BEGIN TRANSACTION을 실행할 수 없습니다.
    문이 종료되었습니다.

    메시지3903, 수준16, 상태1, 줄2

    --아래의 쿼리도 실패합니다.
    BACKUP DATABASE AdventureWorks TO DISK=’c:₩temp₩AWBACK.bak’
    GO

    메시지3033, 수준16, 상태0, 줄3
    응급모드에서 열린 데이터베이스에서는BACKUP DATABASE를 사용할 수 없습니다.
    메시지3013, 수준16, 상태1, 줄3
    BACKUP DATABASE이(가) 비정상적으로 종료됩니다.

    데이터베이스의 상태를 정상적으로 복구합니다.
    use master
    go
    ALTER DATABASE AdventureWorks SET ONLINE
    GO


    출처 : http://blog.naver.com/oyukihana/60024046150
    ATTACH_REBUILD_LOG 절
    OLTP환경에서 대용량 데이터베이스를 가지고 있다고 생각해봅시다. 이 데이터베이스를 다른 서버에 읽기위주의 용도로 옮긴다고 생각을 하면 단지 데이터파일만 옮기면 됩니다. 그러기 위해서는 서비스를 중단시키고 .mdf 파일과 .ndf 파일을 복사해서 옮깁니다. 그 후 CREATE DATABASE 명령어에서 ATTACH_REBUILD_LOG 절을 추가하여 수행합니다. 이렇게 하면 SQL Server는 데이터베이스를 연결하면서 새롭게 로그를 생성합니다.

    완벽하게 수행하기 위해서는 이 작업이 끝난 뒤 바로 전체 백업을 수행해야 합니다. 이전 버전의 sp_attach_single_file_db 저장 프로시저는 호환성을 위해서만 사용됩니다.

    2005에서는CREATE DATABASE 문장에 ATTACH_REBUILD_LOG을 사용할 것을 권장합니다.

    문법은 그 예제는 다음과 같습니다.
    CREATE DATABASE database_name
    ON <filespec> [ ,...n ]
    FOR { ATTACH [ WITH <service_broker_option> ]
    | ATTACH_REBUILD_LOG }

    예제)
    CREATE DATABASE AdventureWorks
    FOR ATTACH_REBUILD_LOG
    데이터베이스 스냅숏에는 ATTACH_REBUILD_LOG옵션을 사용할 수 없습니다.

    2007년 7월 16일 월요일

    Windows Mobile 6 SDK 개발환경 만들기

    운영체제로는

    Windows 2003 sp2

    Windows XP sp2

    Windows Vista

    가 필요하다.

     

    IDE로는

    Visual Studio 2005 sp1(이하 VS2005)가 있어야 된다.

    VS2005는 버젼이 여러개 있는데 standard이상의 버젼이 필요하다.

    Visual Studio 2005로도 가능하다고 마이크로소프트 홈페이지에 되어있지만,

    아무래도 최신 버젼으로 프로그래밍하는게 좋겠지?

    서비스 팩이 필요한사람은 http://www.microsoft.com/downloads/로 들어가서
    'Visual Studio® 2005 Team Suite SP1'를 찾는다.

    ' '로 처리된 부분은 위 링크에서 검색해서 다운받으면 된다.

    반드시 서비스 팩의 언어와 VS2005의 언어가 같아야 한다.

    난 VS2005를 한글로 깔고 SP1를 영문으로 받고 깔려다가 안깔려서 한참동안 삽질을 했다--;

     그리고 반드시 Visual Studio 2005에서 '스마트 장치 프로그래밍 기능'이 설치 되어야 한다,
     이것을 확인하려면 설치CD를 넣고 'Visual Studio 2005변경 또는 제거'에서 '기능 추가/제거'로 들어가면
    확인이 가능하다. 맨 처음 설치할때 전체설치를 했다면 설치가 되어있을것이다.

     

    다음엔 Microsoft .NET Compact Framework v2 SP1를 깔아야된다.

    '.NET Compact Framework 2.0 Service Pack 2 Redistributable' 가 최신버젼이다.

     

    그다음엔 가장 중요한 SDK를 깔면 된다.

    'Windows Mobile 6 Software Development Kits (Standard and Professional)'

    Pocket PC프로그래밍을 할 사람은 Professional버젼을 받아야한다.

    Standard버젼은 Smartphone프로그래밍할 사람이 쓰면 된다.

     근데 Smartphone OS로 Microsoft껄 쓴 건 본적이 없다--;

    아마 핸드폰에 MS OS가 들어가면 가끔 포멧도 해주고 프로그램 깔때마다 재부팅을 해줘야 할 것 같은

    느낌이 든다.

     

    그리고 PDA를 가지고 있는 사람은 Active Sync최신버젼을 깔자. ('ActiveSync 4.5')
    나중에 컴파일을 하면 자동으로 PDA로 깔린다음 실행이 된다고 한다.
    나는 PDA가 없어서 설치를 안했다.

     

     여기까지 왔다면 다 된것이다. VS2005에 들어가서 새로만들기->프로젝트로 들어간다.
    그럼 여러가지 템플릿이 나올것이다. 거기에서 'Win32 스마트 장치 프로젝트'와
    'MFC 스마트 장치 응용 프로그램'이 보이면 성공이다!!

     

     이제 프로그래밍만 하면 된다. SDK안에 에뮬레이터가 있기 때문에 PDA가 없어도 실행해볼 수 있다.

    Windows Mobile 6.0에서 API와 MFC는 Win32 API와 유사하니 전에 윈도우 프로그래밍을 해본 사람은

    굉장히 익숙할 것 같다.

     



    참조 : http://blog.naver.com/spdkng/10015575188

    2007년 3월 27일 화요일

    aspnet_merge.exe 명령을 사용하여 배포용으로 precompile

    출처: MSDN

     

    aspnet_merge.exe 명령을 사용하여 배포용으로 미리 컴파일된 ASP.NET 출력 관리

    Microsoft Corporation

    2005년 11월

    소개

    ASP.NET 2.0에서는 aspnet_compiler.exe 명령줄 도구를 사용하여 웹 사이트를 미리 컴파일하고, 서버로 배포할 수 있는 웹 사이트 버전을 만들 수 있습니다. 이 도구는 페이지, 사용자 정의 컨트롤, 리소스, 유틸리티 클래스, 기타 파일 등의 소스 파일을 어셈블리로 컴파일합니다.

    기본적으로 컴파일러는 여러 소스 파일의 출력이 파일 형식, 파일 종속성 및 기타 조건에 따라 단일 어셈블리로 컴파일되는 "일괄 처리 모드"로 작동합니다. 결과적으로 대상 사이트에는 원래 소스 파일용 실행 코드와 함께 어셈블리 집합이 포함됩니다.

    일괄 컴파일로 만든 어셈블리가 프로덕션 서버로 웹 사이트를 배포하는 데 적합하지 않은 경우도 있습니다. 어셈블리 이름은 컴파일러에 의해 자동으로 생성되므로 어떤 어셈블리가 어떤 소스 파일에 매핑되는지 명확히 알 수는 없습니다. 컴파일러가 실행될 때마다 새 이름이 만들어지기 때문에 매 컴파일 후 어셈블리 이름이 다를 수 있습니다. 또한 소스 파일이 변경되면 컴파일러에서 소스 파일을 다른 방식으로 일괄 처리할 수 있습니다. 즉, 결과 어셈블리가 동일한 소스 파일을 나타내지 않을 수 있습니다. 배포된 웹 사이트를 유지 관리하면서 최신 변경 내용이 있을 때만 어셈블리를 업데이트하려는 경우에는 일괄 컴파일의 출력으로 인해 작업이 더 복잡해질 수 있습니다.

    이러한 상황에서 편리하게 작업을 진행할 수 있도록 aspnet_compiler.exe에서는 패키지 및 릴리스 관리용으로 특수하게 고안된 -fixednames 옵션을 지원합니다. 이 옵션을 사용하면 두 가지 이점을 제공하는 컴파일러 출력을 만들 수 있습니다. 첫 번째 이점은 컴파일러로 생성된 어셈블리의 이름이 컴파일할 때마다 동일하다는 것이고, 두 번째는 어셈블리가 매번 동일한 입력 파일을 기반으로 한다는 것입니다.

    그러나 -fixednames 옵션을 사용해도 결과 어셈블리 이름이 여전히 복잡한 경우가 있을 수 있습니다. 더욱이 fixednames 옵션을 사용할 때 컴파일러는 컴파일된 각 소스 파일에 대해 하나씩, 많은 수의 어셈블리를 만들 수 있습니다.

    대규모 웹 사이트에서 작업하는 개발자가 배포 가능한 웹 응용 프로그램을 만들 경우에는 다음과 같은 기능이 필요합니다.

    • 출력 어셈블리 및 파일을 관리하는 기능. Visual Studio .NET 2003에서 빌드 작업을 수행하면 단일 어셈블리가 생성되므로 어셈블리를 비교적 간단히 배포할 수 있습니다. 그러나 웹 UI 콘텐츠 파일(ASP.NET 페이지 및 사용자 정의 컨트롤)은 서버에서 여전히 동적으로 컴파일되며 배포가 필요합니다. Visual Studio .NET 2003에서 빌드 출력을 "단일 어셈블리"라는 용어로 지칭하는 것은 완전히 정확하다고는 할 수 없습니다. 코드 숨김 파일은 단일 어셈블리로 컴파일되지만 페이지 어셈블리는 여전히 동적으로 생성되며 일괄 컴파일되거나 개별적으로 컴파일되기 때문입니다.
    • 자동으로 생성되는 어셈블리 이름을 그대로 사용하지 않고 결과 출력 어셈블리의 이름을 명시적으로 지정하는 기능
    • 릴리스 관리 및 배포 프로세스를 능률화하기 위해 빌드를 보다 쉽게 비교("diff")하는 기능

    ASP.NET 2.0 컴파일러에서 -fixednames 옵션을 사용하면 이러한 기능 중 일부가 지원되기는 하나 사용자는 결과 어셈블리의 이름을 지정할 수 없으며 하나 또는 소수의 어셈블리만 만들 수도 없습니다.

    이러한 문제를 해결하기 위해 aspnet_merge.exe라는 새로운 병합 유틸리티가 개발되었습니다. 이 유틸리티를 사용하면 컴파일러에서 생성한 어셈블리를 결합하여 관리할 수 있습니다. 병합 도구와 사용 방법은 이 기사에 설명되어 있습니다.

    웹 사이트 예제

    컴파일러와 병합 도구가 어떻게 함께 작동하는지 설명하기 위해 Visual Studio 2005에서 Personal Web Starter Kit를 사용하여 웹 사이트를 만들었다고 가정해 봅시다. 이 사이트의 파일 구조는 그림 1에 나와 있습니다.

    그림 1. Visual Studio 2005를 사용하여 만든 개인 웹 사이트 예제

    사이트 콘텐츠 및 레이아웃에 대한 다음 내용을 참고하십시오.

    • 웹 UI 콘텐츠 파일(.aspx 파일, .master 파일 및 .ascx 컨트롤)은 응용 프로그램의 여러 폴더에 있습니다.
    • 사이트에는 .jpg 및 .css 파일과 같은 정적 콘텐츠가 있습니다.
    • 유틸리티 클래스는 App_Code 폴더에 정의되어 있습니다.

    이와 같은 웹 사이트의 일반적인 개발 주기는 다음 단계에 따라 진행됩니다.

    • 디자인 및 개발 디자이너와 개발자가 Visual Studio 2005를 사용하여 웹 사이트를 만들고 반복해서 테스트 및 수정 작업을 수행합니다. 이 단계에서 Visual Studio 2005 및 ASP.NET 2.0에서 사용되는 동적 컴파일은 Visual Studio 2003 및 ASP.NET 1.1과 비교할 때 개발 프로세스의 속도를 한층 향상시킵니다.
    • 빌드 응용 프로그램을 소스 제어로 체크 인하고 빌드 서버를 통해 동기화할 수 있습니다. 개발자는 사용자 지정 빌드 스크립트를 만들어서 aspnet_compiler.exe 및 aspnet_merge.exe와 기타 도구를 실행할 수 있습니다. 또한 배포 업무를 담당하는 개발자는 이 기사의 뒷부분에 나오는 "Visual Studio 2005 웹 배포 프로젝트" 섹션에 설명된 것처럼 새 웹 배포 프로젝트를 사용하여 MSBuild 프로젝트를 만들 수 있습니다. 빌드 스크립트를 통해 배포 가능한 대상 또는 패키지된 대상을 만들 수 있습니다.
    • 배포 스크립트 또는 MSBuild 프로젝트를 통해 준비 또는 프로덕션/릴리스 서버로 이동되는 배포 가능한 웹 사이트를 만들 수도 있습니다.
    • 테스트 팀에서 준비 서버를 사용하여 응용 프로그램을 테스트합니다.
    • 프로덕션/릴리스 준비된 빌드가 프로덕션/릴리스 서버로 이동됩니다.
    • 유지 관리 팀 차원에서 준비 또는 프로덕션/릴리스 서버로 변경 내용을 전파하는 프로세스를 실행합니다.
    • 이 프로세스가 가장 이상적이기는 하나 설치 파일(.msi 파일)을 만들거나 증분 업데이트를 관리하고, 매일 수행한 빌드를 저장하고, 릴리스 관리 프로세스를 구현하는 프로세스를 만드는 등 다양한 방식으로 이 작업을 수행할 수 있습니다. 이러한 모든 시나리오에서 aspnet_compiler.exe 및 aspnet_merge.exe 도구는 웹 사이트 개발 프로세스에서 핵심적인 역할을 합니다. Visual Studio 2005 웹 배포 프로젝트를 사용하면 빌드, 병합 및 배포 프로세스의 여러 측면을 좀 더 향상시킬 수 있습니다.

    이 기사에서는 이러한 프로세스에 대해 자세히 설명하지는 않으며, 빌드 서버에서 또는 Visual Studio 2005 웹 배포 프로젝트를 통해 사용할 수 있는 aspnet_compiler.exe는 물론 특히 중요한 aspnet_merge.exe 도구를 중점적으로 다룹니다.

    이 기사에 제공된 예제에 대한 참고 사항

    이 기사에 제공된 예제에서는 해당 사이트가 IIS의 응용 프로그램으로 구성되어 있다고 가정하고 -v 옵션을 지정하여 aspnet_compiler.exe를 사용하는 방법을 보여 줍니다. 그러나 컴파일러는 -p 옵션으로 지정된 실제 경로를 사용할 수 있습니다. -p 옵션을 사용하면 aspnet_compiler.exe는 루트 아래의 모든 하위 폴더를 루트 웹 사이트에 속하는 폴더로 취급합니다. 이로 인해 해당 폴더가 독자적인 웹 사이트인 경우 컴파일 오류가 발생할 수 있습니다. -p 옵션을 지정하지 않고 -v 옵션을 사용하면 aspnet_compiler.exe는 어떤 하위 폴더가 루트 응용 프로그램에 속하는지 확인할 수 있습니다.

    -p 옵션을 사용할 경우 -v 옵션은 ~ 연산자의 위치를 확인하거나 설치 디렉터리 아래의 Temporary ASP.NET Files 폴더에 폴더를 제공하는 등 다양한 용도로 사용됩니다.

    모든 예제 명령은 예제 웹 사이트 루트 폴더에서 실행된다고 가정합니다.

    미리 컴파일 개요

    새 병합 도구를 살펴보기 전에 ASP.NET 2.0 컴파일러(aspnet_compiler.exe)의 기능을 검토하는 것이 도움이 될 수 있습니다. 이 컴파일러는 .NET Framework 버전 2.0과 함께 제공되며 .NET Framework 설치 폴더(일반적으로 %windir%\Microsoft.NET\Framwork\version) 또는 Visual Studio 2005 Professional Edition이나 Visual Studio 2005 Enterprise Edition에서 실행할 수 있습니다.

    ASP.NET 컴파일러를 사용하면 웹 응용 프로그램을 여러 배포 형식으로 미리 컴파일할 수 있습니다. 이러한 각 배포 형식은 웹 응용 프로그램에서 소스 코드를 제거합니다. 또한 이 컴파일러는 필요에 따라 웹 UI 콘텐츠 페이지(.aspx, .master 및 .ascx 파일)를 제거할 수 있습니다.

    aspnet_compiler.exe 및 aspnet_merge.exe 도구 설명에는 다음 두 어셈블리 그룹이 사용됩니다.

    • 웹 UI 콘텐츠 어셈블리 웹 UI 콘텐츠 자체(.aspx, .master 및 .ascx 파일과 관련된 코드 파일)에 대해 생성되는 어셈블리입니다.
    • 최상위 수준 어셈블리 App_Code, App_GlobalResources 및 App_WebReferences와 같은 특수 목적 폴더로부터 Global.asax 같은 특수 파일에 대해 컴파일러에서 생성되는 어셈블리입니다.

    aspnet_compiler.exe 명령은 소스 사이트를 미러링하는 레이아웃 구조로 이루어진 출력을 생성합니다. 이 경우 컴파일된 개체 코드는 대상 응용 프로그램의 Bin 폴더에 배치됩니다.

    이 컴파일러는 배포용 출력 및 현재 위치에서 출력이라는 두 가지 출력 유형을 제공하는 미리 컴파일을 지원합니다.

    배포용 미리 컴파일

    배포용으로 미리 컴파일을 수행하면 서버에 작업 웹 응용 프로그램으로 배포할 수 있는 파일 집합이 생성됩니다. 배포용으로 미리 컴파일할 경우 다음과 같은 두 가지 유형의 출력을 만들 수 있습니다.

    • 업데이트가 불가능하도록 배포용으로 미리 컴파일은 대상에서 소스 코드뿐만 아니라 모든 태그를 제거합니다. 이 옵션을 사용할 경우 최상위 수준 어셈블리 및 웹 UI 콘텐츠 파일에 대한 모든 소스가 프로덕션 환경에서 제거됩니다. 이러한 특성은 웹 UI 콘텐츠 파일이 항상 동적으로 컴파일되는 ASP.NET 1.1과는 대조됩니다.
    • 업데이트가 가능하도록 배포용으로 미리 컴파일은 웹 UI 콘텐츠 페이지의 태그를 유지하며 Visual Studio .NET 2003에서 생성된 사이트와 비슷한 대상 사이트를 만듭니다.

    이 컴파일러의 -fixednames 옵션은 두 가지 형식의 배포용 미리 컴파일 모두에 영향을 줍니다. 이 옵션을 지정하면 컴파일 중에 특정(고정) 이름을 갖는 어셈블리가 생성되고 웹 UI 콘텐츠 파일마다 단일 어셈블리가 생성됩니다.

    현재 위치에서 미리 컴파일

    현재 위치에서 미리 컴파일할 경우 소스 사이트에 직접 어셈블리를 만들고 새 대상 레이아웃은 생성하지 않는 일괄 컴파일이 수행됩니다. 현재 위치에서 미리 컴파일하려면 웹 사이트 가상 디렉터리를 참조하는 -v 옵션을 사용하거나(컴퓨터에 IIS가 설치된 경우) 실제 소스 경로를 참조하는 -p 옵션을 사용하여 컴파일러를 실행합니다.

    여기서는 모든 내용을 빠짐없이 설명하기 위해 현재 위치에서 미리 컴파일 기능을 언급했지만 이 기능을 사용할 경우 빌드 시스템에서 aspnet_merge.exe를 통해 결합할 수 있는 출력이 생성되지 않습니다. 현재 위치에서 미리 컴파일할 경우 모든 소스 코드가 유지되는 프로덕션 웹 사이트를 만들 수 있지만 웹 사이트에 대한 첫 번째 요청으로 인해 야기될 수 있는 "컴파일 패널티"는 나타나지 않습니다.

    미리 컴파일 - 코드 및 태그 제거

    웹 사이트 예제로 돌아가서 그림 2의 명령을 사용하여 배포용으로 웹 사이트를 미리 컴파일하여 업데이트가 불가능한 출력을 만든다고 가정해 봅시다. 이 명령은 웹 사이트에 대한 psw라는 가상 경로를 사용하고 pswcompile이라는 출력 폴더를 지정합니다.

    그림 2. aspnet_compiler.exe 실행 시 -v 옵션 지정

    컴파일러는 그림 3과 4처럼 대상 사이트(pswcompile)를 생성합니다. 그림 3에서는 소스 웹 사이트 구조가 유지되는 것을 확인할 수 있습니다. 예를 들어 Admin 폴더는 유지되고 Welcome.html과 같은 기타 정적 웹 UI 콘텐츠는 그대로 pswcompile 폴더에 복사됩니다. .aspx 파일은 복사된 것처럼 보이지만 자세히 살펴보면 이 파일이 실제로는 더미 태그 파일이며 해당 내용은 문자열 값에 불과하다는 것을 알 수 있습니다. 이 경우에는 모든 태그(HTML 및 웹 서버 컨트롤)가 제거되었습니다.

    그림 4처럼 대상 웹 사이트에는 소스 파일이 전혀 포함되어 있지 않으며 웹 UI 콘텐츠 어셈블리가 Bin 폴더에 생성되었습니다. aspnet_compiler.exe 명령은 Bin 폴더에 .compiled 파일을 만듭니다. 이 파일은 특정 페이지나 특정 가상 경로에 대한 요청이 있을 때 인스턴스화할 클래스를 ASP.NET에 알려줍니다.

    메모장과 같은 텍스트 편집기에서 .compiled 파일을 열면 컴파일된 페이지에 대한 참조가 포함되어 있음을 알 수 있습니다. 이 참조를 통해 ASP.NET에서 파일 구조의 원래 페이지 위치를 결정할 수 있습니다. 또한 .compiled 파일에서 페이지 결과로 컴파일된 출력을 포함하는 어셈블리 이름을 확인할 수 있습니다. 컴파일러는 고유한 어셈블리 이름을 자동으로 생성합니다.

    참고 배포용으로 미리 컴파일할 경우 항상 새 빌드가 수행되며 aspnet_compiler.exe는 매번 다른 어셈블리 이름을 만듭니다. 또한 어셈블리의 소스로 사용되는 파일은 빌드마다 다를 수 있으므로 릴리스 관리 시 변경에 의해 어떤 어셈블리가 생성되었는지 일관적으로 파악하는 것이 어려울 수 있습니다. 이러한 이유 때문에 -fixednames 옵션을 사용합니다.

    그림 3. pswcompile 폴더의 미리 컴파일된 출력

    그림 4. pswcompile\Bin 폴더의 미리 컴파일된 출력

    고정 이름을 사용한 미리 컴파일

    그림 5처럼 -fixednames 옵션을 사용하여 웹 사이트를 컴파일한다고 가정해 봅시다.

    그림 5. -fixednames 옵션을 사용한 컴파일

    -fixednames 옵션을 사용하면 그림 6처럼 pswcompile\Bin 폴더에 더 많은 어셈블리가 생성됩니다. 각 어셈블리는 하나의 페이지, 사용자 정의 컨트롤 또는 마스터 페이지를 나타냅니다. 옵션 이름에서도 알 수 있듯이 어셈블리 이름은 빌드에 관계없이 동일합니다. 어셈블리 이름은 App_Web_filetype.nnnn.dll 형식으로 지정됩니다. 여기서 nnnn은 해시 값을 나타냅니다.

    그림 6. -fixednames 옵션을 사용하여 컴파일한 후 pswcompile\Bin 폴더에 생성되는 미리 컴파일된 출력

    미리 컴파일 - 코드만 제거

    배포 가능한 대상 디렉터리(예제의 pswcompile)에 웹 UI 콘텐츠 페이지의 태그가 유지되도록 웹 사이트를 미리 컴파일할 수 있습니다. 그림 7에서는 배포용으로 미리 컴파일된 웹 사이트를 생성하는 aspnet_compiler.exe 명령 예제를 보여 줍니다. 그런 다음 사이트에서 사이트 페이지를 제한적으로 수정할 수 있습니다. 이 경우 레이아웃은 변경할 수 있지만 이벤트 핸들러처럼 코드가 필요한 새 컨트롤이나 컨트롤 ID는 변경할 수 없습니다.

    그림 7. aspnet_compiler.exe 실행 시 ASP.NET 페이지 및 사용자 정의 컨트롤의 태그 유지

    그림 8과 9에서는 pswcompile 폴더와 Bin 폴더의 결과를 보여 줍니다.

    그림 8. pswcompile 폴더의 미리 컴파일된 출력

    그림 9. pswcompile\Bin 폴더의 미리 컴파일된 출력

    그림 8에서는 앞에 나온 컴파일처럼 웹 사이트 구조가 유지되고 Welcome.html과 같은 정적 웹 UI 콘텐츠가 pswcompile 폴더에 복사되었음을 보여 줍니다. 그림 9에서는 웹 UI 콘텐츠 어셈블리와 App_Code.dll 같은 최상위 수준 어셈블리가 pswcompile\Bin 폴더에 생성되었음을 보여 줍니다.

    웹 UI 콘텐츠 페이지를 확인해 보면 이 미리 컴파일 형식의 차이점을 알 수 있습니다. 그림 9를 보면 pswcompile\Bin 폴더에 .compiled 파일이 더 포함되어 있지 않다는 것을 알 수 있습니다. 이것은 웹 UI 콘텐츠 페이지 자체가 유지되기 때문입니다. .aspx 페이지는 앞에 나온 컴파일과 같이 더미 파일로 작동하지 않으며 그림 10처럼 다른 어셈블리에서 상속하도록 수정됩니다. 미리 컴파일 후에 이 페이지는 Bin 폴더에 있는 어셈블리에서 상속하며 이전 codeFile 참조는 모두 제거됩니다.

    그림 10. 미리 컴파일된 .aspx 파일의 수정된 inherits 특성

    고정 이름을 사용한 미리 컴파일

    그림 11의 구문을 사용하면 태그를 유지하고 고정 이름을 사용하도록 사이트를 미리 컴파일할 수 있습니다. 앞의 경우처럼 -fixednames옵션을 사용하면 Bin 디렉터리에 더 많은 어셈블리가 생성됩니다.

    그림 11. aspnet_compiler.exe 실행 시 웹 UI 콘텐츠 태그를 유지하고 고정 어셈블리 이름 사용

    aspnet_merge.exe를 사용하여 어셈블리 병합

    앞에서 살펴보았듯이 aspnet_compiler.exe는 기본적으로 일괄 처리 모드로 출력 어셈블리를 생성하거나 컴파일된 각 파일에 대해 고정 이름을 갖는 어셈블리를 만들어 출력 어셈블리를 생성합니다. 이러한 경우 배포 및 릴리스 관리 계획과 웹 사이트의 특징에 따라 엔터프라이즈 개발자에게 몇 가지 이점이 있습니다.

    그러나 출력이 너무 많거나 어셈블리의 이름이 작업 용도에 맞게 지정되지 않는 경우도 있습니다. aspnet_merge.exe 명령을 사용하여 이러한 문제를 보다 쉽게 해결할 수 있습니다.

    aspnet_merge.exe 도구는 컴파일러에서 생성된 어셈블리를 결합합니다. 병합 도구를 사용하면 다음과 같이 어셈블리를 결합할 수 있습니다.

    • 사전 컴파일된 웹 사이트에서 ASP.NET에 의해 생성된 모든 어셈블리(사용자 지정 어셈블리 제외)를 단일 명명 어셈블리로 결합할 수 있습니다.
    • 모든 웹 UI 콘텐츠 어셈블리를 단일 명명 어셈블리로 결합할 수 있습니다.
    • 웹 UI 콘텐츠 어셈블리를 웹 사이트의 각 폴더에 대한 어셈블리로 결합할 수 있습니다.
    참고 Visual Studio .NET 2003에서 프로젝트를 빌드하면 코드 숨김 파일과 기타 클래스 파일이 웹 사이트용 어셈블리로 빌드됩니다. 소스 코드를 배포하지 않고도 이 어셈블리를 프로덕션 서버로 배포할 수 있습니다. 프로덕션 서버로 모든 태그 페이지도 배포해야 합니다. 증분 업데이트를 사용하여 사이트를 업데이트하려면 코드 숨김 어셈블리 및 관련 태그 페이지를 다시 배포합니다. 그러나 단일 어셈블리에는 단점이 있습니다. 어셈블리를 빌드하는 데는 시간이 많이 걸리므로 배포 중에 F5 키나 Ctrl+F5를 누르면 시간이 많이 지연될 수 있습니다. 뿐만 아니라 코드 숨김 클래스 파일을 변경한 경우에는 전체 어셈블리를 다시 빌드해야 합니다. 테스트를 수행할 경우 새 어셈블리를 만들면 웹 사이트의 모든 페이지가 기술적으로 무효화되므로 모든 페이지를 다시 테스트해야 할 수 있습니다.

    이제 ASP.NET 2.0에서는 동적 컴파일, aspnet_compiler.exe를 사용한 미리 컴파일 및 aspnet_merge.exe를 사용한 병합을 조합하여 개발 및 배포 요구를 최대한 충족시킬 수 있습니다. 다음 표에서는 각 컴파일 유형 및 병합 유틸리티를 사용해야 하는 경우를 보여 줍니다.

    시나리오참고 사항
    개발 중: 동적 컴파일 사용Visual Studio 2005 및 ASP.NET 2.0의 동적 컴파일을 사용합니다.

    이렇게 하면 F5 키나 Ctrl+F5를 누를 때 전체 빌드가 수행되지 않도록 프로젝트를 구성할 수 있으므로 개발 작업을 빠르게 진행할 수 있습니다. 실제로 빌드를 완전히 비활성화할 수도 있습니다. 이러한 경우 Visual Studio 2005에서 작업 중인 페이지를 실행할 때 페이지와 해당 종속성이 ASP.NET 2.0에 의해 동적으로 컴파일됩니다. 따라서 특정 페이지에 오류가 있어도 다른 페이지를 개발하고 디버깅할 수 있습니다.

    Visual Studio 2005에서는 ASP.NET 컴파일을 사용하므로 IDE의 모든 코드 오류와 구문 분석 시간 오류를 비롯하여 Visual Studio 컴파일과 ASP.NET 컴파일이 정확하게 일치합니다. 또한 ASP.NET 2.0 동적 컴파일은 편집기에서 사용자 지정 IntelliSense 기능을 제공합니다.
    배포: 각 웹 UI 콘텐츠 파일에 대한 단일 어셈블리 만들기-fixednames 옵션으로 미리 컴파일하여 각 파일에 대한 웹 UI 콘텐츠 어셈블리가 있는 대상을 생성합니다.

    이 시나리오에서는 다른 페이지에 영향을 거의 주지 않고 웹 페이지 수준까지 증분 업데이트를 수행할 수 있으므로 보다 세분화된 릴리스 관리가 가능합니다. 이 옵션을 사용하면 업데이트 가능한 미리 컴파일된 웹 사이트와 업데이트 불가능한 미리 컴파일된 웹 사이트를 모두 만들 수 있습니다.

    대규모 사이트의 경우 많은 어셈블리가 생성되므로 확장성 문제가 발생할 수 있습니다.

    어셈블리는 암호화 방식으로 명명되지만 페이지와 .compiled 파일을 함께 사용하면 어떤 파일이 어떤 어셈블리를 생성하는지 파악할 수 있습니다.

    정적 웹 콘텐츠 및 사용자 지정 어셈블리는 영향을 받지 않습니다.
    배포: 각 웹 UI 콘텐츠 폴더에 대한 어셈블리 만들기미리 컴파일을 하고 aspnet_merge.exe를 사용하여 웹 UI 콘텐츠가 들어 있는 각 폴더에 대해 별도의 어셈블리를 만듭니다.

    웹 UI 콘텐츠 폴더별로 어셈블리를 따로 만들면 어셈블리 수가 많아집니다. 컴파일할 때 -u 옵션을 생략하면 어셈블리와 더미 페이지만 배포하는 웹 사이트를 만들어 배포된 웹 사이트에서 태그가 제거되도록 할 수 있습니다.

    폴더 내의 파일을 변경한 경우 폴더 어셈블리와 수정된 페이지를 다시 배포해야 합니다. 해당 폴더에 대해서만 테스트 프로세스를 수행할 수 있으면 다른 폴더는 여전히 유효하다고 간주해도 됩니다. 그러나 실제로 이 웹 사이트에 태그 페이지가 유지될 경우 Bin 폴더에 새 어셈블리를 추가하면 모든 페이지가 다시 컴파일됩니다.

    기본적으로 어셈블리 이름은 폴더 이름을 기반으로 하지만 어셈블리에 사용자 지정 이름을 접두사로 붙일 수 있습니다. 최상위 수준 어셈블리는 이 옵션을 사용해도 영향을 받지 않으며 정적 웹 UI 콘텐츠 및 사용자 지정 어셈블리에도 영향이 없습니다.

    배포: 모든 웹 UI 콘텐츠 파일에 대한 단일 어셈블리 만들기사이트를 미리 컴파일한 후 aspnet_merge.exe를 사용하여 전체 웹 사이트에 대한 단일 웹 UI 콘텐츠 어셈블리를 생성합니다.

    웹 UI 콘텐츠에 대한 단일 어셈블리가 있으면 Visual Studio .NET 2003에서 생성된 출력과 비슷한 배포 가능한 웹 사이트를 만들 수 있습니다. 컴파일할 때
    -u 옵션을 생략하면 옵션을 생략하면 어셈블리와 더미 페이지만 배포하는 웹 사이트를 만들어 배포된 웹 사이트에서 태그가 제거되도록 할 수 있습니다.

    배포된 웹 사이트를 업데이트하려는 경우 다시 컴파일한 어셈블리와 수정된 웹 UI 콘텐츠 파일을 배포할 수 있습니다.

    웹 UI 콘텐츠 파일을 변경할 경우 관련 .compiled 페이지 및 .aspx 페이지와 함께 전체 어셈블리를 다시 배포해야 합니다. 프로덕션 서버에 태그 페이지는 유지되지만 동적으로 다시 컴파일되므로 해당 페이지에 대한 테스트 프로세스 결과가 무효화될 수 있습니다.

    병합 프로세스 중에 어셈블리에 사용자 지정 이름을 할당할 수 있습니다. 최상위 수준 어셈블리는 이 옵션을 사용해도 영향을 받지 않으며 정적 웹 UI 콘텐츠 및 사용자 지정 어셈블리에도 영향이 없습니다.
    배포: 전체 웹 사이트에 대한 어셈블리 만들기미리 컴파일을 하고 aspnet_merge.exe를 사용하여 웹 UI 콘텐츠 어셈블리와 최상위 수준 어셈블리를 결합하는 단일 어셈블리를 생성합니다.

    전체 웹 사이트에 대한 단일 어셈블리를 만들어 릴리스 프로세스를 쉽게 관리할 수 있습니다. 단일 어셈블리와 업데이트된 웹 UI 콘텐츠 파일을 배포할 수 있습니다. 컴파일할 때
    -u 옵션을 생략하면 어셈블리와 더미 페이지만 포함하는 웹 사이트를 만들고 배포된 웹 사이트에서 태그가 제거되도록 할 수 있습니다.

    웹 사이트의 파일을 변경한 경우 어셈블리 및 더미 페이지까지 다시 배포해야 하므로 전체 웹 사이트에 대한 테스트 프로세스 결과가 무효화될 수 있습니다.

    어셈블리에 사용자 지정 이름을 할당할 수 있습니다. 정적 웹 UI 콘텐츠 및 사용자 지정 어셈블리는 영향을 받지 않습니다.

    Aspnet_merge.exe는 미리 컴파일된 웹 사이트의 어셈블리만 병합하며 미리 컴파일된 알려진 어셈블리에만 사용할 수 있습니다. 이 도구는 사용자 지정 어셈블리나 Bin 폴더에 있는 App_licenses.dll 어셈블리는 수정하지 않습니다.

    참고 Aspnet_merge.exe는 현재 위치에서 병합을 수행합니다. 미리 컴파일된 웹 사이트는 수정되고 결합된 어셈블리는 제거됩니다. 소스 파일에 대해 aspnet_compiler.exe를 다시 실행하는 것이 여의치 않으면 병합 전에 미리 컴파일된 사이트를 백업하십시오.

    각 폴더에 대한 콘텐츠 어셈블리 병합

    대상 폴더 이름만 지정하고 다른 옵션 없이 aspnet_merge.exe를 실행하면 각 웹 UI 콘텐츠 폴더에 대한 출력 어셈블리가 생성됩니다. 이 병합 유형의 구문은 그림 12에 나와 있습니다.

    그림 12. 옵션 없이 aspnet_merge.exe 실행

    이 기본 병합 작업을 수행하면 컴파일러 -fixednames 옵션에 의해 생성된 어셈블리 수보다 적은 어셈블리가 생성됩니다. 이러한 형식의 병합은 프로덕션 서버에 증분 업데이트를 배포하려는 경우에 유용할 수 있습니다.

    업데이트 불가능한 미리 컴파일된 웹 사이트에서 병합

    그림 13에서는 업데이트 불가능한 미리 컴파일된 사이트에 대해 옵션을 지정하지 않고 aspnet_merge.exe를 실행할 경우의 결과를 보여 줍니다. 이 그림에서는 그림 2의 미리 컴파일된 출력을 병합한 결과를 보여 줍니다. 어셈블리 이름은 폴더 이름(App_Web_filetype.nnnn.dll)을 포함하도록 다시 지정됩니다. 또한 웹 사이트의 폴더를 병합하면 Root.dll 및 Admin.dll(빨간색 원으로 표시)이라는 어셈블리 두 개가 생성됩니다. 이 두 어셈블리는 각각 루트 폴더의 웹 UI 콘텐츠와 psw\Admin 하위 폴더의 웹 UI 콘텐츠에서 생성된 것입니다. Bin 폴더에는 App_Code.dll과 같은 최상위 수준 어셈블리가 계속 포함되어 있는 상태이며 테마도 컴파일된 후 단일 Themes.dll 어셈블리(파란색 원으로 표시)에 병합되었습니다.

    aspnet_compiler.exe 명령의 -fixednames 옵션 지정 여부와는 관계없이 생성된 어셈블리에 Aspnet_merge.exe를 사용할 수 있습니다. 이 도구는 특정 폴더에 대한 어셈블리 병합을 자동으로 처리합니다.

    그림 13. 업데이트 불가능한 미리 컴파일된 웹 사이트의 웹 UI 콘텐츠 폴더를 병합한 결과

    업데이트 불가능한 미리 컴파일된 웹 사이트의 경우 컴파일러는 .aspx 파일에 대해 .compiled 파일을 만듭니다. ASP.NET은 .compiled 파일을 사용하여 웹 요청에 맞는 유형을 인스턴스화합니다. 병합 도구는 새로 병합된 어셈블리가 대신 참조되도록 이러한 파일을 업데이트합니다. 그림 14에서는 병합 후 .compiled 파일이 어떻게 달라졌는지 보여 줍니다.

    그림 14. 병합 작업 이후 수정된 .compiled 파일

    병합된 어셈블리를 식별하는 데는 폴더 이름이 사용되므로 웹 사이트의 웹 UI 콘텐츠 파일 집합에 대한 어셈블리를 비교적 쉽게 확인할 수 있습니다. 그러나 사용자가 원하는 명명 규칙을 사용하려는 경우도 있을 수 있으므로 aspnet_merge.exe로 그림 15처럼 -prefix 옵션을 사용하여 이러한 어셈블리에 대해 접두사를 지정할 수 있습니다.

    그림 15. aspnet_merge.exe 실행 시 -prefix 옵션 지정

    그림 16 에서는 -prefix 옵션으로 병합을 수행하여 생성된 어셈블리를 보여 줍니다. Root.dll은 Contoso.dll로, Admin.dll은 Contoso.Admin.dll로 이름이 바뀌었음을 알 수 있습니다.

    그림 16. -prefix 옵션을 지정하여 업데이트 불가능한 미리 컴파일된 웹 사이트를 병합한 결과

    참고 로컬 리소스가 있는 웹 사이트에서 로컬 리소스는 일반적으로 웹 UI 콘텐츠로 취급됩니다. 그러나 병합 도구는 로컬 리소스를 처리하지 않습니다. 로컬 리소스는 이미 폴더가 지정되어 있기 때문입니다.

    업데이트 가능한 미리 컴파일된 웹 사이트에서 병합

    업데이트 가능한 미리 컴파일된 웹 사이트의 어셈블리를 병합할 경우 업데이트 불가능한 웹 사이트에서 병합했을 때와 동일한 병합된 출력이 생성됩니다. 단, aspnet_merge.exe는 병합된 어셈블리를 가리키도록 .aspx 페이지 같은 태그 페이지를 수정한다는 점이 다릅니다. 업데이트 불가능한 사이트와 마찬가지로 각 폴더에 대해 어셈블리가 생성되며 병합 도구는 동일한 명명 규칙을 적용합니다. 그림 17에서는 병합 후 예제 사이트의 Bin 폴더를 보여 줍니다. 이 폴더에는 웹 UI 콘텐츠에 대한 어셈블리인 Root.dll(루트 psw 폴더의 웹 UI 콘텐츠에서 생성)과 Admin.dll(psw\Admin 하위 폴더의 웹 UI 콘텐츠에서 생성)이 있습니다.

    그림 17. 업데이트 가능한 미리 컴파일된 웹 사이트의 웹 UI 콘텐츠 폴더를 병합한 결과

    그러나 업데이트 가능한 미리 컴파일된 웹 사이트에서 병합 기능을 사용할 경우에는 약간의 차이가 있습니다. 업데이트 가능한 미리 컴파일된 웹 사이트에서는 테마가 컴파일되지 않으므로 테마는 원래 상태로 유지됩니다. 마찬가지로 로컬 리소스도 웹 UI 콘텐츠로 간주되어 수정될 수 있으므로 원래 상태로 유지됩니다. 컴파일러는 .aspx, .master 및 .ascx 파일에 대해서는 .compiled 파일을 생성하지 않습니다. 이러한 파일은 응용 프로그램에 그대로 남아 있지만 그림 18처럼 병합 과정에서 새로 병합된 어셈블리를 가리키도록 수정됩니다.

    그림 18. 병합 작업 이후 수정된 .aspx 파일

    미리 컴파일된 웹 UI 콘텐츠를 단일 어셈블리로 병합

    각 웹 UI 콘텐츠 폴더에 대해 개별적으로 어셈블리를 배포하지 않고 aspnet_merge.exe를 사용하여 모든 웹 UI 콘텐츠에 대한 단일 어셈블리를 만들 수 있습니다. 이 경우 웹 UI 콘텐츠에 대한 어셈블리를 하나의 단위로 관리할 수 있고 병합된 어셈블리의 이름을 지정할 수도 있습니다. 그림 19에서는 모든 웹 UI 콘텐츠에 대한 단일 어셈블리를 만드는 구문을 보여 줍니다.

    그림 19. aspnet_merge.exe 실행 시 모든 웹 UI 콘텐츠에 대한 단일 어셈블리 만들기

    그림 19의 명령은 모든 웹 UI 콘텐츠에 대해 Contoso.dll이라는 단일 어셈블리를 생성하여 Bin 폴더에 넣습니다. 최상위 수준 어셈블리는 그대로 유지됩니다. 모든 .compiled 파일 또는 모든 .aspx, .master 및 .ascx 파일은 이 단일 어셈블리를 참조하도록 수정됩니다.

    그림 20에서는 업데이트 불가능한 미리 컴파일된 웹 사이트에서 웹 UI 콘텐츠를 단일 어셈블리로 병합할 경우 pswcompile\Bin 폴더의 변경된 내용을 보여 줍니다.

    그림 20. 업데이트 불가능한 미리 컴파일된 웹 사이트의 웹 UI 콘텐츠 폴더를 병합할 경우 pswcompile\Bin 폴더의 변경된 내용

    미리 컴파일된 웹 UI 콘텐츠 및 최상위 수준 어셈블리 결합

    지금까지 웹 UI 콘텐츠 어셈블리의 병합 결과를 살펴보았습니다. 그러나 aspnet_compiler.exe는 웹 사이트의 일부로 여러 다른 어셈블리를 생성합니다. 이 중에는 App_Code 폴더 및 기타 특수 폴더의 내용을 컴파일할 때 생성되는 최상위 수준 어셈블리가 있습니다.

    미리 컴파일된 웹 사이트에서 이러한 어셈블리의 이름에는 소스 폴더의 이름이 사용됩니다. 즉, 어셈블리가 이미 폴더 수준으로 컴파일되었음을 의미합니다. 파일이 변경되면 이러한 어셈블리에도 영향이 있으므로 웹 UI 콘텐츠 파일이 변경되지 않았어도 다시 컴파일해야 합니다. 릴리스 관리 프로세스에서는 이 점을 주의해야 합니다.

    Aspnet_merge.exe를 사용하면 최상위 수준 어셈블리와 웹 UI 콘텐츠 어셈블리를 결합하는 단일 어셈블리로 최상위 수준 어셈블리를 병합할 수 있습니다. 웹 사이트에 대해 병합된 단일 어셈블리를 만들려면 병합 명령에 -o 옵션을 추가하고 어셈블리 이름을 지정하십시오. 그림 21에서는 구문의 예를 보여 줍니다.

    그림 21. aspnet_merge.exe 실행 시 최상위 수준 및 웹 UI 콘텐츠 어셈블리에서 단일 어셈블리 만들기

    그림 22에서는 그림 2의 파일 작업 시 -o 옵션을 지정하여 병합할 경우의 결과를 보여 줍니다. 이러한 유형의 병합에서 aspnet_merge.exe를 실행할 때는 단일 파일의 이름을 지정하는 데 사용되는 출력 어셈블리 이름(Contoso.dll)을 지정해야 합니다. 이 병합 작업에서 다른 어셈블리는 생성되지 않습니다.

    그림 22. -o 옵션을 사용하여 모든 어셈블리를 병합한 결과

    원본 사이트에 로컬 리소스가 포함되어 있을 경우 큰 리소스 어셈블리로 로컬 리소스를 병합할 수 없으므로 병합이 진행되어도 로컬 리소스는 그대로 남아 있습니다. 마찬가지로 전역 리소스도 병합되지 않습니다.

    병합된 어셈블리의 어셈블리 특성

    aspnet_merge.exe를 사용하여 어셈블리를 결합할 때 기본적으로 이 도구는 병합된 집합의 초기 소스 어셈블리의 어셈블리 특성을 병합된 최종 어셈블리로 전달합니다. 소스 어셈블리에 다른 특성을 지정할 수도 있으므로 병합된 어셈블리에 어떤 특성이 적용되었는지 확인하는 것은 쉽지 않습니다.

    병합된 어셈블리에 지정된 특성을 명확히 알 수 있도록 App_Code 어셈블리에 대해 정의된 어셈블리 특성을 소스 특성 집합으로 사용하거나 지정된 어셈블리를 특성 정의 어셈블리로 사용하도록 aspnet_merge.exe에 설정할 수 있습니다.

    예를 들어 그림 23에서는 그림 1에 나와 있는 웹 사이트의 App_Code 디렉터리에 추가할 수 있는 Assemblyinfo.cs 파일을 보여 줍니다.

    그림 23. App_Code 폴더에 추가된 Assemblyinfo.cs 파일

    어셈블리를 병합하지 않으면 App_Code 어셈블리에만 이러한 특성이 지정됩니다. Ildasm.exe와 같은 도구를 사용하여 어셈블리의 특성을 확인할 수 있습니다. App_Code 어셈블리에 대해 정의된 특성을 병합된 어셈블리에 지정하려면 그림 24처럼 -copyattrs 옵션을 사용합니다.

    그림 24. aspnet_merge.exe 실행 시 App_Code 어셈블리에 대해 정의된 특성을 병합된 최종 어셈블리에 사용

    -copyattrs 옵션을 지정하면 최상위 수준 어셈블리인 App_Code.dll이 병합에 포함되지 않은 경우에도 App_Code 어셈블리에 대한 특성이 사용됩니다. 웹 UI 콘텐츠 어셈블리만 병합하는 경우가 이러한 경우에 해당됩니다. 다음 목록에서는 그림 23의 명령으로 생성된 Contoso.dll 어셈블리에 대한 IL의 매니페스트 조각을 보여 줍니다.

    .assembly Contoso { .... AssemblyFileVersionAttribute:.. = // ...1.0.4567.0.. .... AssemblyDescriptionAttribute:.. = // ...Contoso 웹 사이트.. .... AssemblyProductAttribute:.. = // ...Contoso.Web.. .... AssemblyCompanyAttribute:.. = // ...Contoso.. .. .ver 1:4000:0:0 }

    App_Code 어셈블리를 제외한 다른 어셈블리의 특성을 지정하려면 -copyattrs 옵션으로 어셈블리 이름을 제공합니다. 이 옵션으로 AssemblyInfo.cs 또는 AssemblyInfo.vb 파일에서 어셈블리를 만들어 병합된 어셈블리에 특성을 지정하는 데만 사용할 수 있습니다.

    병합된 어셈블리에 서명

    개발 팀의 경우 다음과 같은 이유로 미리 컴파일된 응용 프로그램에 서명하려고 할 수 있습니다.

    • 특정 개발 팀에서 어셈블리가 제작되었음을 확인할 수 있게 하려는 경우. 서명이나 키는 해당 조직에서만 사용할 수 있으므로 이를 통해 어셈블리가 특정 회사에서 제작되었는지에 대해 어느 정도 신뢰성을 부여할 수 있습니다.
    • 알려진 키로 서명된 어셈블리만 신뢰할 수 있도록 하고, 인식할 수 없는 키로 서명되었거나 키가 없는 어셈블리에 대한 실행 권한은 허용하지 않도록 프로덕션 컴퓨터를 잠그려는 경우

    병합되고 서명된 웹 사이트 어셈블리를 응용 프로그램 간에 공유하도록 GAC에 추가할 수 있습니다. 그러나 이렇게 할 경우 이미지 같은 리소스 URL 기준 지정 시 문제가 발생할 수 있습니다. 일반적으로 GAC에 미리 컴파일되었거나 병합된 어셈블리를 추가하지 않는 것이 좋습니다. 외부 리소스를 참조하지 않는 사용자 정의 컨트롤에서 생성된 어셈블리와 같이 일부 제한된 상황에서만 병합 및 서명된 어셈블리를 GAC에 추가할 수 있습니다.

    aspnet_compiler.exe를 사용하여 미리 컴파일된 사이트의 어셈블리에 서명할 수 있습니다. 그러나 어셈블리를 병합할 경우에는 병합 도구를 사용하여 어셈블리에 서명해야 합니다.

    미리 컴파일된 웹 사이트를 병합할 경우 어셈블리의 서명이 연기되었거나 aspnet_compiler.exe를 사용하여 서명되었을 수 있습니다. 병합 중에 미리 서명된 비트 또는 서명되지 않은 비트를 사용하여 병합된 어셈블리에 서명할 수 있습니다. 병합된 결과 어셈블리에 서명하려는 경우 aspnet_merge.exe와 함께 옵션 -keyfile, -keyContainer 또는 -delaysign을 사용할 수 있습니다. aspnet_merge.exe를 실행하여 미리 서명된 어셈블리를 병합할 때 이러한 서명 옵션 중 어느 것도 지정하지 않으면 결과 어셈블리가 서명되지 않습니다.

    다음 명령은 미리 컴파일된 어셈블리를 Contoso.dll이라는 단일 어셈블리로 병합한 후 Aspnet_merge.exe를 사용하여 어셈블리에 서명하는 방법을 보여 줍니다.

    1. 공개 키 및 개인 키를 사용하여 키 파일을 만듭니다. sn -k contoso.snk
    2. 서명하지 않고 웹 사이트를 미리 컴파일합니다. aspnet_compiler -v psw pswcompile
    3. 웹 응용 프로그램을 병합하고 서명합니다. aspnet_merge pswcompile -keyfile contoso.snk -o Contoso

    병합된 어셈블리 서명 연기

    Aspnet_merge.exe를 사용하여 서명을 연기하는 방법은 다음과 같습니다.

    1. 공개 키와 개인 키를 사용하여 키 파일을 만듭니다. 일반적으로 공개 키와 개인 키는 제한된 사용자만 액세스할 수 있는 안전한 위치에 보관해야 합니다. 구문은 다음과 같습니다. sn -k contoso.snk
    2. 해당 파일의 공개 키를 다른 키 파일로 추출합니다. sn -p contoso.snk contosopublicKey.snk
    3. 서명하지 않고 웹 사이트를 미리 컴파일합니다. aspnet_compiler -v psw pswcompile
    4. -delaysign 및 -keyfile 옵션을 지정하여 어셈블리를 병합한 후 서명을 연기합니다. aspnet_merge pswcompile -delaysign -keyfile contosopublicKey.snk -o Contoso

    병합된 어셈블리에 APTCA 적용

    미리 컴파일한 웹 사이트가 완전 신뢰 이외의 보안 수준에서 작동하면 aspnet_compile.exe에 -aptca(Allow Partially Trusted Callers Attribute) 옵션을 지정하여 어셈블리를 미리 컴파일해야 합니다. 이렇게 하면 해당하는 어셈블리 수준의 특성이 컴파일된 어셈블리에 추가됩니다. 이 특성은 aspnet_merge.exe에 의해 병합된 어셈블리에 유지됩니다.

    참고 소스 어셈블리의 일부에만 APTCA(AllowPartiallyTrustedCallersAttribute)가 지정된 경우 aspnet_merge.exe는 소스 어셈블리 특성을 전달하지 않고 대신 예외를 발생시킵니다. 따라서 병합된 어셈블리의 코드가 원래 의도된 것과 다른 신뢰 수준으로 제공되는 경우는 없습니다. 단순히 병합하거나 -a 옵션을 지정하여 병합하기 전에 모든 어셈블리에 APTCA를 지정하여 이 동작을 바꿀 수 있습니다. 그러나 병합할 때 -a 옵션을 사용하면 이전에는 APTCA가 지정되지 않았던 어셈블리에 이 특성이 지정될 수 있습니다. 따라서 이전에는 가능하지 않았지만 이제는 부분적으로 신뢰할 수 있는 코드에서 어셈블리를 호출하도록 할 수 있습니다.

    APTCA를 적용하는 단계는 다음과 같습니다.

    1. -aptca 옵션을 지정하여 사이트를 미리 컴파일합니다. aspnet_compiler -v psw pswcompile -aptca
    2. 어셈블리를 병합합니다. aspnet_merge pswcompile -o Contoso

    병합된 어셈블리 버전 관리

    미리 컴파일된 웹 사이트에 대해 생성된 어셈블리에 버전 정보를 추가하려는 경우 다음을 수행할 수 있습니다.

    • App_Code 폴더에 AssemblyInfo.cs 파일이나 AssemblyInfo.vb 파일을 추가합니다. 이렇게 하면 App_Code 폴더에 대해 생성된 어셈블리의 버전이 관리됩니다. 또한 페이지 및 사용자 정의 컨트롤에 대한 코드 숨김 파일에도 버전 특성을 추가할 수 있습니다. 그러나 개별 파일에 일일이 버전 특성을 추가하는 것은 지루한 작업이므로 업데이트 가능한 미리 컴파일 레이아웃의 코드 숨김 파일에만 버전 특성을 추가합니다.
    • Web.config 파일에 포함된 <compiler> 요소의 compilerOptions 특성에 AssemblyInfo.cs 또는 AssemblyInfo.vb 파일에 대한 참조를 추가합니다. 이렇게 하면 웹 사이트에 대해 생성된 모든 어셈블리의 버전 관리 정보를 추가할 수 있습니다. 이 경우 ASP.NET에서 WSDL 같은 비코드 유형 파일에 대한 컴파일러를 선택할 수 있으므로 프록시를 컴파일할 때 C# 컴파일러와 Visual Basic 컴파일러를 모두 포함시켜야 합니다.

    Aspnet_merge.exe는 App_Code 어셈블리에서 특성을 복사하거나 -copyattrs 옵션으로 지정한 특정 어셈블리에서 특성을 복사하여, 만드는 어셈블리의 버전을 관리할 수 있습니다. 따라서 이러한 특성은 다른 어셈블리 특성과 마찬가지로 취급됩니다. 병합된 어셈블리에 대한 특성을 지정하는 데 이러한 옵션을 사용할 경우 파일 버전, 어셈블리 버전 및 작업에 필요한 기타 어셈블리 특성을 비롯한 모든 버전 특성을 정의할 수 있습니다.

    그림 25에서는 그림 1의 웹 사이트를 사용하여 App_Code 어셈블리의 특성을 적용하는 데 사용되는 병합 명령을 보여 줍니다. 그림 22의 AssemblyInfo.cs 파일은 웹 사이트의 App_Code 폴더에 추가되었습니다.

    그림 25. aspnet_merge.exe 실행 시 App_Code 어셈블리에 대해 정의된 특성을 병합된 최종 어셈블리에 사용

    다음 목록에서는 앞의 명령을 실행할 때 Contoso.dll에 적용되는 전체 메타데이터 중 일부를 보여 줍니다.

    .assembly Contoso { .... AssemblyFileVersionAttribute:.. = // ...1.0.4567.. .... AssemblyDescriptionAttribute:.. = // ..!Contoso Personal Web // 사이트 시작 키트.. .... AssemblyProductAttribute:.. = // ...Contoso.Web.. .... AssemblyCompanyAttribute:.. = // ...Contoso.. .. .ver 1:0:4000:0

    .dll 파일에 대한 속성을 살펴보면 적용된 특성을 알 수 있습니다.

    그림 26. Contoso.dll 어셈블리 특성 및 속성

    병합된 어셈블리에 대한 디버그 출력 만들기

    컴파일 중에 디버그 출력 파일(.pdb 파일)을 만들 수 있습니다. 기본적으로 aspnet_compiler.exe는 정식 버전 출력을 만들고 Web.config 파일이나 .aspx 페이지, master 페이지 또는 사용자 정의 컨트롤에 포함되어 있는 다른 디버그 옵션은 무시합니다. 디버그 출력을 만들려면 그림 27처럼 컴파일할 때 -d 옵션을 사용합니다.

    그림 27. aspnet_compiler.exe 실행 시 -d 옵션을 지정하여 디버그 출력 만들기

    디버그 출력 파일을 병합하려면 aspnet_merge.exe 실행 시 -debug 옵션을 지정합니다. -debug 옵션을 지정하지 않으면 병합 과정에서 웹 사이트의 모든 디버그 출력이 제거됩니다. 디버그 출력을 포함하는 사이트를 병합하고 -o 옵션을 사용하여 단일 어셈블리를 만들 경우 pswcompile\Bin 폴더에 병합된 단일 .pdb 파일이 포함됨을 알 수 있습니다. 그림 28에서는 디버그 출력을 만들기 위한 aspnet_merge.exe 명령을 보여 주고, 그림 29에서는 Bin 폴더에 포함되는 결과 출력을 보여 줍니다.

    그림 28. aspnet_merge.exe 실행 시 전체 사이트에 대한 디버그 출력 병합

    그림 29. 전체 웹 사이트에 대한 디버그 출력을 병합한 결과

    빌드 환경에서 aspnet_compiler.exe 및 aspnet_merge.exe 사용

    Visual Studio 2005 Professional Edition 및 Visual Studio 2005 Enterprise Edition에는 미리 컴파일을 수행하기 위한 메뉴 명령(빌드 > 웹 게시)이 포함되어 있습니다. Visual Studio 2005에서는 배포용으로 미리 컴파일할 수 있지만 기본적으로 웹 사이트 프로젝트에 직접 빌드 전 작업이나 빌드 후 작업을 추가할 수는 없습니다. 따라서 Visual Studio 2005에서 빌드에 병합 명령을 추가하는 것은 쉽지 않습니다.

    이러한 요구를 해결하기 위해 다운로드하여 별도로 설치할 수 있는 새로운 웹 배포 프로젝트 기능을 사용할 수 있습니다. Visual Studio 2005 웹 배포 프로젝트 설치에는 aspnet_merge.exe 도구도 포함되어 있습니다. 웹 배포 프로젝트가 있으면 명령줄 도구를 실행하거나 빌드 관련 파일을 수동으로 편집해야만 사용할 수 있는 기능을 Visual Studio 2005 내에서 사용할 수 있습니다.

    개발 팀은 빌드 시 다음 방법을 사용할 수 있습니다.

    • 사용자 지정 빌드 작업에서 aspnet_compiler.exe와 aspnet_merge.exe를 순서대로 사용. 일반적으로 엔터프라이즈 개발 팀에서는 자체 빌드 서버 시나리오에 맞는 사용자 지정 빌드 스크립트를 작성합니다.
    • 수동으로 만든 MSBuild 파일에 aspnet_compiler.exe 및 aspnet_mer叿䉍/᠀젇ࠁࠂ詀.㷞ɀĀ＀?ÿ氀䀧洀작업을 수동으로 추가한 후 빌드 서버에서 실행할 수 있습니다.
    • Visual Studio 2005에서 웹 사이트와 연결된 웹 배포 프로젝트를 통해 aspnet_compiler.exe 및 aspnet_merge.exe 도구 사용. 이 방법을 사용하면 많은 기능에 UI가 제공되며 MSBuild를 통해 이 작업을 실행할 수도 있습니다.

    Visual Studio 2005 웹 배포 프로젝트

    웹 배포 프로젝트를 사용하여 빌드용 어셈블리를 제어하고 배포 가능한 웹 사이트를 만드는 데 필요한 추가 작업을 관리할 수 있습니다. 웹 프로젝트가 포함된 솔루션에 새 웹 배포 프로젝트를 추가하여 해당 웹 배포 프로젝트를 사용자의 웹 사이트에 연결할 수 있습니다. 그림 30에서는 웹 사이트 C:\work\psw와 연결된 웹 배포 프로젝트 psw_deploy를 보여 줍니다.

    그림 30. 솔루션 탐색기의 Visual Studio 2005 웹 배포 프로젝트 노드

    Visual Studio 2005를 열고 웹 사이트를 만든 후에는 솔루션 탐색기에서 웹 사이트 노드를 마우스 오른쪽 단추로 클릭하고 Add Web Deployment Project(웹 배포 프로젝트 추가)를 선택하여 웹 배포 프로젝트를 솔루션에 추가할 수 있습니다. 솔루션 탐색기에서 웹 배포 프로젝트를 마우스 오른쪽 단추로 클릭한 다음 여러 배포 설정을 구성할 수 있는 속성 페이지를 표시할 수 있습니다. Visual Studio 2005 웹 배포 프로젝트를 사용하면 다음 작업을 수행할 수 있습니다.

    • aspnet_compiler.exe 옵션을 사용하여 디버그, 릴리스 또는 준비 빌드 등의 여러 빌드 작업을 구성합니다.
    • 해당 구성에서 병합 작업을 구성합니다.
    • 버전 관리 및 서명을 처리합니다.
    • 병합 중에 어셈블리 이름을 조작합니다.
    • Web.config 파일을 수정하는 등의 추가 작업을 배포 프로세스의 일부로 정의합니다.
    • 다양한 사용자 지정 시나리오에 적용할 수 있게 프로젝트 파일을 직접 수정합니다.
    • 개발 타임에 프로젝트의 빌드를 비활성화하거나 배포 대상을 만들 때 웹 사이트 자체의 빌드를 비활성화합니다.

    또한 프로젝트 파일을 수동으로 편집하고 사용자 지정 작업 또는 동작을 빌드 전 작업 및 빌드 후 작업으로 추가할 수 있습니다. 자세한 내용은 MSDN 웹 사이트의 Using Web Deployment Projects with Visual Studio 2005 (영문) 기사를 참조하십시오.

    그림 31에서는 출력 어셈블리에 대한 옵션을 설정하기 위한 속성 페이지를 보여 줍니다.

    더 큰 이미지를 보려면 여기를 클릭하십시오.

    그림 31. Visual Studio 2005 웹 배포 프로젝트용 출력 어셈블리 속성 페이지

    이 페이지에서 aspnet_merge.exe 도구에 사용할 수 있는 몇 가지 옵션을 확인할 수 있습니다.

    Aspnet_merge.exe 도움말

    이 기사에서는 다양한 aspnet_merge.exe 옵션을 설명합니다. -? 옵션을 지정하여 aspnet_merge.exe를 실행하면 이러한 옵션은 물론 여기에 나와 있는 다른 옵션에 대한 추가 도움말을 볼 수 있습니다.

    요약

    Aspnet_merge.exe는 웹 사이트 프로덕션 환경을 관리하는 데 사용할 수 있는 새로운 유틸리티입니다. 이 병합 도구는 웹 사이트를 미리 컴파일할 때 ASP.NET 컴파일러 aspnet_compiler.exe에 의해 생성되는 많은 수의 어셈블리를 결합합니다. 이를 통해 ASP.NET 컴파일러에 의해 생성된 출력을 사용하는 게시 프로세스나 릴리스 관리 프로세스를 보다 쉽게 관리할 수 있습니다.

    이 기사에서는 병합 도구와 함께 사용할 수 있는 다양한 옵션과 웹 사이트 미리 컴파일 시 이 병합 도구를 사용하는 방법에 대해 설명합니다. 이 기사의 예제에서는 사용자 지정 빌드 모델에 통합할 수 있는 명령을 보여 줍니다.

    Aspnet_merge.exe는 새로운 Visual Studio 2005용 웹 배포 프로젝트 추가 기능과 함께 설치됩니다. 이 추가 기능은 aspnet_compiler.exe 및 aspnet_merge.exe 도구 옵션을 관리하기 위한 포괄적인 UI를 제공하며 Visual Studio 내에서 배포 가능한 웹 사이트를 만드는 작업을 관리할 수 있도록 합니다. 웹 배포 프로젝트에는 웹 사이트 배포 관리에 필요한 빌드 전 단계와 빌드 후 단계를 추가하기 위한 기능도 포함되어 있습니다.