2018년 9월 30일 일요일

[SQL Server] 열 나열 데이터를 행 나열 데이터로 변경하기

사소하지만 열로 나열된 데이터를 1개의 행으로 변경하고 싶을 때가 있다.

그럴 때 유용한 팁이다.

해당 쿼리는 MSSQL에서만 작동하며, mysql에서는 되지 않았다.

-- 열로 나열

SELECT name FROM sys.databases


-- 행으로 나열 ,로 데이터 구분
DECLARE @str NVARCHAR(4000= ''
SELECT @str = @str + ',' + name FROM sys.databases
SELECT @str

[SQL Server] Schedulers

Professional SQL Server 2012 Internals and Troubleshooting 내용 정리

Schedulers

각 스레드는 연관된 스케줄러를 가지며 프로세서의 각 스레드에 대한 시간을 스케줄링하는 기능을 갖는다. SQL Server에서 사용할 수있는 스케줄러의 수는 SQL Server에서 사용할 수 있는 논리 프로세서의 수에 DAC (전용 관리자 연결)에 사용할 수있는 프로세서 하나를 더 더한 값과 같다.

SQL Servers의 스케줄러는 

sys.dm_os_schedulers 

DMV를 통해 확인 할 수 있다.


해당 그림은 세션, task, 쓰레드, 스케줄러 사이의 연관관계를 설명한 것이다.

Windows는 범용 운영 체제이며 특히 SQL Server와 같은 서버 기반 응용 프로그램에 최적화되어 있지 않다. 대신 Windows 개발 팀의 목표는 Microsoft 내부 및 외부의 다양한 개발자가 작성한 모든 응용 프로그램이 올바르게 작동하고 우수한 성능을 발휘하도록하는 것이다. Windows는 다양한 시나리오에서 잘 작동해야하기 때문에 개발 팀은 응용 프로그램의 1 % 미만에서만 사용되는 특별한 작업을 수행하지 않는다.

[SQL Server] Execution Model

Professional SQL Server 2012 Internals and Troubleshooting 내용 정리

지금까지이 장에서는 SQLOS의 개념을 추상화하여 너무 많은 접미어를 사용하지 않고 아키텍처를 통한 구성 요소의 흐름을 보다 쉽게 이해할 수 있도록했다. 그러나 SQLOS는 SQL Server 아키텍처의 핵심이므로 SQL Server가 작동하는 방식에 대한 이해를 위해 SQL Server가 존재하는 이유와 그 이유를 이해해야한다.
즉, SQLOS는 SQL Server와 Windows 사이에있는 thin User-mode 계층이다. 스케줄링, I / O 완성, 메모리 관리 및 자원 관리와 같은 저수준 작업에 사용된다. 이것이 의미하는 바가 무엇이고 왜 필요한지 정확히 알아보기 위해서는 먼저 SQL Server의 Execution Model을 이해해야한다.

- Execution Model
어플리케이션 하나가 SQL Server에 연결이 되면 Session이 생성되고 이 Session은 Session_id라는 것으로 구분이 된다. sys.dm_exec_sessions라는 DMV를 통해 확인할 수 있다. 세션 내에서 실행 요청이 이루어지면 SQL Server는 작업을 하나 이상의 작업으로 나눈 다음 해당 기간 동안 각 작업에 작업자 스레드를 연결한다. 각 스레드는 세 가지 상태 중 하나 일 수 있습니다.

   -> Running: 1개의 프로세서는 1개의 작업만 실행될 수 있다. 이 상태는 현재 프로세서가 해당 작업을 수행하고 있음을 의미한다.
   -> Suspended: SQL Server에는 협업 스케줄러가 있다. 실행 중인 스레드가 프로세서를 생성하고 리소스를 기다리는 동안 일시 중단된다. 이것을 우리는 wait 상태라고 한다. 
   -> Runnable: 쓰레드가 Wait 상태가 끝나면 Runnable 상태가 된다. 이것은 다시 실행 할 준비가 되어 있다를 의미한다. 이것을 signal wait(신호대기) 상태라고 한다.

Worker Threads를 사용할 수없고 최대 Worker Threads에 도달하지 않은 경우 SQL Server는 새 Worker Thread를 할당한다. 최대 Worker Threads 수에 도달하면 Threads가 사용 가능해질 때까지 대기 유형 THREADPOOL로 태스크가 대기한다.

최대 Worker Threads의 기본값은 CPU 아키텍처 및 논리 프로세스의 수에 의해 결정된다.
공식은 아래와 같다.

For a 32-bit OS:
-> Total available logical CPUs <= 4
- Max Worker Threads = 256
->Total available logical CPUs > 4
- Max Worker Threads = 256 + ((logical CPUs - 4)*8)
For a 64-bit OS:
->Total available logical CPUs <= 4
- Max Worker Threads = 512
->Total available logical CPUs > 4
- Max Worker Threads = 512 + ((logical CPUs - 4)*16)

DMV를 통해서도 현재 실행 중인 시스템의 max workers를 확인 할 수 있으며 구문은 아래와 같다.

SELECT max_workers_count
FROM sys.dm_os_sys_info

Worker Threads (THREADPOOL 대기 유형)가 부족하면 종종 병렬 실행 계획이 여러 개 발생하는 증상이 나타나거나 (프로세서 당 하나의 스레드가 사용되므로) 서버가 받아들일 수 있는 성능을 넘어서므로 더 많은 프로세서가있는 프로세서를 구입해야한다.

각 Worker Thread가 필요로 하는 Ram의 용량은 64bit OS는 2MB, 32bit OS는 0.5MB를 필요로 하므로 SQL Server는 Thread를 필요에 따라 생성한다. 

SELECT count(*)
FROM sys.dm_os_workers

해당 구문으로 현재 SQL Server에 있는 Threads의 수를 확인 할 수 있다.

Professional SQL Server 2012 Internals and Troubleshooting 22-24p

[SQL Server] Recovery Model

Professional SQL Server 2012 Internals and Troubleshooting 내용 정리

Recovery Models: Recovery Models은 세 종류로 나뉜다. Full, Bulk-Logged, Simple!
트랜잭션 로그의 증가, 백업전략, 복구 옵션에 따라 맞는 복구 모델을 선택하면 된다.

Full: 데이터 베이스의 모든 내용을 트랜잭션 로그에 기록하는 것이다. 해당 모드에서 백업은 트랜잭션 백업과 풀 백업이 같이 이루어 져야한다. SQL Server 2005부터는 전체 백업이 트랜잭션 로그를 자르지 않는다. 이렇게하면 트랜잭션 로그 백업 시퀀스가 손상되지 않으며 Full 백업이 손상된 경우 추가 복구 옵션이 제공된다. 하지만 요즘 거의 2005는 사용하지 않는다. 관리하는 데이터베이스의 가장 높은 복구수준이 Full 모드이다. 

Bulk-Logged: 이것은 특정 벌크 작업을 최소한으로 로깅하여 성능을 향상시키기 위해 일시적으로 만 사용하는 특별한 복구 모델이다. 다른 모든 작업은 Full Recovery 모델처럼 모두가 로깅된다. 트랜잭션을 롤백하는 데 필요한 정보 만 로깅되어 성능이 향상 될 수 있지만 재실행 정보는 기록되지 않으므로 특정 시점 복구 기능도 손실 될 수 있다.
 - Bulk operation의 종류는 다음과 같다
( Bulk Insert, Using the bcp executable, SELECT INTO, CREATE INDEX, ALTER INDEX REBUILD, DROP INDEX)
 Bulk-Logged Mode를 사용하면 대량 로그 작업을 더 빠르게 완료 할 수 있다. 트랜잭션 로그 백업에 필요한 디스크 공간을 줄이지 않는다.

Simple: Simple Mode가 데이터베이스에 설정되면 모든 커밋 된 트랜잭션은 Check Point가 발생할 때마다 트랜잭션 로그에서 삭제된다. 이럴 경우 로그의 크기는 최소로 유지되고 트랜잭션 로그 백업이 필요하지 않게 (또는 가능하게) 된다. 해당 모드가 좋은 것인지 나쁜 것인지 여부는 데이터베이스에 필요한 복구 수준에 따라 다르며, 마지막 Full 백업 또는 차등(Differential)백업 이후 모든 변경 내용을 잃어도 되는 비즈니스 요구 사항을 충족 시킨다면 간단한 복구가 필요할 수 있다.

Professional SQL Server 2012 Internals and Troubleshooting 21-22.p

[SQL Server] Recovery Interval

Professional SQL Server 2012 Internals and Troubleshooting 내용 정리

Recovery Interval: Check point 사이의 시간과 관계 있으며, 시작 시 데이터베이스를 복구하는 데 걸리는 시간, 즉 "Recovery Interval"에 사용할 수있는 서버 구성 옵션이다.
기본적으로 복구 간격은 0으로 설정되며, 이를 통해 SQL Server는 적절한 간격을 선택할 수 있다. 자동 간격은 일반적으로 약 1 분이다. 
 이 값을 0보다 큰 값으로 변경하면 검사 점간에 허용 할 시간 (단위 분)을 나타낸다. 대부분의 경우 이 값을 변경할 필요는 없지만 복구 시간보다 검사 점 프로세스의 오버 헤드가 더 염려되는 경우 옵션을 사용한다.
 대부분 이 옵션은 실제로는 거의 사용하지 않고, 모니터링이나 성능의 이점을 확인하기 위해 극단적으로 높은 값을 두어 Check point를 효과적으로 중지하기 위해 사용한다.
 SQL Server는 디스크 하위 시스템에 큰 영향을 미치지 않도록 체크 포인트 I / O를 조절하는 자체 제어 기능이 있다. 서버에서 SLEEP_BPOOL_FLUSH 대기 유형을 확인 전체 시스템 성능을 유지하기 위해 체크 포인트 I / O가 제한 되었음을 의미한다. "SQL Server의 실행 모델 및 SQLOS"섹션에서 대기 및 대기 유형에 대한 모든 것을 읽을 수 있다.

Professional SQL Server 2012 Internals and Troubleshooting 21p

[SQL Server] Dirty Page & Lazy Writer

Professional SQL Server 2012 Internals and Troubleshooting 내용 정리

- Dirty Page: 페이지가 메모리에 처음 읽어들어오면 우리는 이것을 Clean Page라고 부른다. 그것은 메모리에 있는 데이터 페이지와 디스크에 있는 데이터 페이지의 내용이 동일하기 때문이다. 그러나 페이지가 수정이 되면 메모리의 내용과 디스크의 내용이 달라진다. 이것을 Dirty Page라고 부른다. 

sys.dm_os_buffer_descriptiors를 통해 dirty page를 확인할 수 있다.

SELECT db_name(database_id) AS 'Database',count(page_id) AS 'Dirty Pages'
FROM sys.dm_os_buffer_descriptors
WHERE is_modified =1
GROUP BY db_name(database_id)
ORDER BY count(page_id) DESC

이러한 Dirty page가 디스크에 쓰이는 경우는 free buffer list가 낮거나 checkpoint가 발생했을 경우이다. SQL Server는 일정량의 free page를 유지하여 페이지 할당을 빠르게 하도록 설계 되어 있다. 그리고 이러한 free page에 관한 정보들은 free buffer list가 가지고 있다.  작업 스레드가 읽기 요청을 할 때마다 캐시의 64 페이지 목록을 가져와 사용 가능한 버퍼 목록이 특정 임계 값 미만인지 여부를 확인한다. 만약 임계값 미만일 경우 목록에 있는 Dirty page를 디스크에 기록한다. Lazy writer 또한 Free buffer list의 값이 낮을 때 발생한다. 

- Lazy Writer: Lazy Writer는 Free buffer list를 주기적으로 체크하는 쓰레드이다. Free buffer list의 값이 낮을 때 데이터 캐시에서 Dirty page 들 중에서 오랜시간동안 사용하지 않아 시간제한이 지난 페이즈를 스캔한다. 만약 이러한 Dirty page가 있다면 해당 페이지를 디스크에 flush하고 Free memory를 확보한다. Lazy writer는 OS의 메모리가 부족할 경우 SQL의 메모리를 돌려줄 수 있도록 모니터링도 하고 있다. SQL Server가 사용 중일 때 이용 가능 한 물리적 메모리가 있고 설정한 max memory 임계 값에 도달하지 않은 경우 요구 (따라서 버퍼 풀)를 충족시키기 위해 사용 가능한 버퍼 목록의 크기가 커진다.

- Checkpoint Process: Commit된 트랜잭션들의 변화된 내용에 대해 모두 디스크에 기록했는지 체크하는 프로세스이다. 이 체크포인트는 SQL Server를 복구할 때, 기준점이 된다. Check point는 commit 된 트랜잭션과 연관된 Dirty page를 디스크에 쓰는 것을 보장한다. 또한 Commit되지 않은 Dirty page를 디스크에 flush하여 쓰기를 효율적으로 사용할 수 있다. 그러나 Lazy writer와 달리 Check point는 캐시에서 페이지를 제거하지 않는다. Dirty page가 디스크에 쓰여지면 해당 페이지 헤더에 Dirty page였다는 정보는 없어지고 다시 Clean Page가 된다.
 기본적으로 사용량이 많은 서버에서 SQL Server는 트랜잭션 로그에 표시된 매 분마다 Check point를 발생시킨다. SQL Server 인스턴스나 데이터베이스가 다시 시작될 경우 로그를 읽는 복구 프로세스는 Check point 이전의 로그레코드는 신경쓰지 않아도 되는 기준이 되는 것이다.
 따라서 체크 포인트 사이 시간은 마지막 체크 포인트 이후 발생한 commit 된 트랜잭션을 Roll Forward하고 commit되지 않은 트랜잭션을 Roll Back하기 위해 수행해야하는 작업의 양을 나타낸다. SQL Server는 매분 체크포인트를 지정하여 데이터베이스를 시작할 때 복구 시간을 1 분 미만으로 유지하려고 한다. 그러나 최소 10MB가 해당 시간 내에 로그에 기록되지 않으면 자동으로 체크 포인트를 수행하지 않는다.
 체크포인트는 CHECKPOINT라는 명령어를 통해 수동으로 수행할 수 있다. 그리고 백업과 같은 작업이 이루어 질 때도 체크포인트가 가장 먼저 수행된다. 
 Trace flag 3502를 추가해 두면 체크포인트가 시작되고 중지되는 것을 에러로그에 기록한다. 
Trace flag에 대한 설명은 다음 사이트에서 확인 할 수 있다. 

참고: LSN(LOG Sequence Number): LSN은 트랜잭션 로그의 레코드를 식별하는 데 사용되며 SQL이 실행된 순서로 정렬 된다. SQL Server는 해당 SQL문이 실행된 순서를 알게 되는 것이다. Recovery가 Roll forward 또는 Roll back과 같은 작업을 수행하기 전에 최소 LSN을 계산한다. 이것은 체크 포인트 LSN뿐 아니라 다른 기준도 고려된다. 이것은 Dirty page가 디스크에 쓰이지 않은 경우 Recovery에 대해 Checkpoint 전에 페이지의 데이터에 대해서도 염려해야 하는다는 것을 의미한다. 많은 페이지를 가진 대형 시스템에서 이런 일이 발생할 수 있다.

Professional SQL Server 2012 Internals and Troubleshooting p.18-20

[SQL Server] Recovery

Professional SQL Server 2012 Internals and Troubleshooting 내용 정리

WAL(Write-ahead Logging)은 앞서 소개 했듯이 ACID의 속성 중 어떠한 변화에도 SQL Server의 durability를  유지하기 위한 방법이다. 수정사항이 transaction log에 먼저 쓰인 뒤 변경된 내용이 메모리에 올라가 있는 것이다. 이렇게 하는 이유는 두 가지이다. 첫 번째는 성능 상의 이유 메모리에서 읽어오는 것이 디스크에 변경된 내용을 쓰고 읽어오는 것보다 빠르다는 것은 알것이다. 두번쨰는 어떠한 변경사항이 있어도 트랜잭션로그에 변경된 사항을 가지고 있어 durability를 보장하는 것이다. 이러한 개념을 가지고 Recovery에 활용할 수 있다. 

Professional SQL Server 2012 Internals and Troubleshooting p.18
  

[SQL Server] Simple Update Query Process

Simple Update Query의 내부에서 처리되는 과정을 순서로 만들어 보았다.

Select Query와 다른 부분은 하늘색 으로 표시된 부분을 참고 하면 된다.

중요한 점은 트랜잭션 로그를 쓰는 것, 데이터 파일에 바로 수정사항이 반영되지 않는 다는 것이다.


Professional SQL Server 2012 Internals and Troubleshooting p.15-18

[SQL Server] Simple Update Query

Professional SQL Server 2012 Internals and Troubleshooting 내용 정리

Update query의 실행과정은 Select와 유사하다.

Select와 다른 부분부터 설명해본다.

Update Query는 Access Methods 부분부터 확인하면 된다.

Update라는 것은 이미 존재하고 있는 데이터를 변경하는 것이다.
Access Methods에서 I/O Request가 아닌 디스크에 존재하는 데이터의 변경을 요청 해야 한다. 이 작업을 해주는 것이 바로 Transaction Manager이다.

- Transaction Manager
 Transaction Manager는 Lock Manager와 Log Manager로 다시 나뉜다. Lock Manager는 동시성을 책임지며, 해당 부분에서는 다루지 않는다. Log Manager는 Access Methods가 수정을 요청하는 부분을 log로 만든다. 그리고 해당 로그를 Transaction Log에 쓴다. 이러한 과정을 WAL(Write-ahead Logging)이라고 한다.
Transaction Log에 쓰는 것은 디스크에 쓰는 것이다. CPU, 메모리가 아닌 디!스!크! 이유는 바로 장애에 대비해서 휘발성을 띄고 있는 CPU와 메모리에 쓰지 않는 것이다. 
 데이터가 수정이 되는 것은 Transaction Log에 입력 된 것이 확실 시 되었을 경우에만 쓰인다. Transaction Log의 핵심적인 역할이 바로 이것이다. Transaction Log에 변경 데이터가 기록이 되었으면 Transaction Manager는 해당 내용을 Access Methods에 전달해준다. 그리고 Access Methods는 완료된 해당사항을 Buffer Manager에게 전달한다. 

- Buffer Manager
 캐시에 가지고 있는 페이지는 수정된 데이터를 가지고 있어야한다. 그래서 Buffer Manager는 Access Methods에게 UPDATE가 수행 된 페이지를 요청합니다. 페이지는 캐시에서 수정되어 궁극적으로 Access Methods와 클라이언트에게 다시 보여주는 것이다. 
 여기서 중요한 점은 UPDATE로 변경된 DATA를 디스크가 아닌 Data Cache에 가지고 있는 것이다. 이것은 성능상의 이유로 Data Cache에 가지고 있는 것이며, 이러한 페이지는 Dirty Page라고 부른다. 우리가 기억해야 할 부분은 메모리에 있는 Dirty Page의 내용과 디스크가 가지고 있는 페이지의 내용이 불일치한다는 것이다. 만약 갑작스런 전원공급이 끊겼을 때, RAM에 가지고 있던 내용은 트랜잭션 로그에 남아있기 때문에 변경사항을 다시 작성할 수 있다. 이것이 바로 ACID의 속성인 내구성을 보장하는 방법이다.
 Buffer Manager는 데이터 캐시에 변경된 페이지 파일을 만들고 체인을 다시 구성한다. 

이렇듯 정상적으로 변경이 완료되면 SELECT와 마찬가지 프로세스로 다시 클라이언트에게 전달해준다.
UPDATE 내용 끝

Professional SQL Server 2012 Internals and Troubleshooting p.15-18

[SQL Server] Simple Select Query Process

책을 보고 내용을 잊지 않기 위해서 나름대로 정리한다고 그려본 Simple Select Query가 우리에게 결과를 도출하기 까지의 과정을 그려보았다.

이렇게 정리하고 나니 이해가 좀 된 것 같다.




[SQL Server] Basic Select Query의 작동원리

Professional SQL Server 2012 Internals and Troubleshooting 내용 정리

1. 사용된 네트워크 프로토콜의 종류에 관계없이 서버와 연결이 성립되면 SNI는 서버의 TDS endpoint로 보안된 연결을 생성한다. 이것은 요청을 보내고 응답을 받는데 사용된다. 

* TDS(Tabular Data Stream) Endpoints 
-  SQL서버와 Client 사이를 연결해주는 역할. 예를 들면 Client에서 SELECT 문을 SQL Server로 보내면 TDS message가 TCP/IP Connection을 맺어준다.

* Protocol Layer
 - SQL Server가 TDS 패킷을 수신했을 때 클라이언트가 요구하는 사항을 확인하는 역할을 한다. 이것은 TDS Message로 다시 클라이언트에게 결과와 상태를 전송하는 역할을 한다. TDS 패킷이 풀어져서 SQL Command 라는 것으로 확인이되면 Command Parser로 넘겨주는 역할을 한다. 

* Command Parser
 - Command Parser은 T-SQL 작업을 관리한다. 처음에 SNI를 통해 전달받은 T-SQL의 문법을 체크하여 에러가 있을 경우 다시 클라이언트에게 에러를 내보낸다. 문법이 옳을 경우 해당 명령이 Query Plan을 생성하거나 이전에 존재한 것이 있는지를 찾는다. 쿼리 플랜은 코드를 어떻게 나누어 실행 할지 자세하게 담고있는데 이것을 execution plan이라고 부른다. 쿼리 플랜을 체크한 Command Parser는 이를 Plan Cache에 적절한 플랜이 존재하고 있는지 체크를 한다. Plan Cache는 Buffer Pool에 존재하고 있으며, query plan을 캐쉬하는데 사용된다. 적절한 플랜이 이미 존재하고 있다면, 해당 쿼리문은 실행을 위해 Query Executor로 보내진다. (다음에 설명하는 내용은 해당 실행계획이 없을 경우에 스텝이다.)

* Plan Cache 
 - 실행계획들을 만드는 것은 시간과 자원을 소비하게 되는 것이다. 그래서 SQL은 괜찮은 실행 계획이 있다면 후속 요청들을 생각해서 실행계획 재사용을 시도한다. SQL 서버의 buffer pool에 속하는 Plan cache는 나중에 필요할 것을 생각하여 실행계획을 저장해둔다. Plan Cache에서도 해당 계획을 찾을 수 없을 때 Command Parser는 쿼리 트리를 만들어 낸다. 이것은 Query Optimizer 로 전달 되어진다. 

* Query Optimizer
 - Query Optimizer는 실행 계획을 세울 때, Cost Base로 실행계획을 결정한다. 실행 계획의 방법이 여러 개가 있을 때, 가장 효율적인 계획을 선택한다는 것이다. 이것은 무조건 Best를 선택하는 것이 아니라 Good을 선택할 수도 있다는 것이다. 그 이유는 Best를 찾기 위해 시간을 소비하는 것이 Good을 실행하는 것이 더 효율적일 수도 있다는 것이다. Optimizer는 Good 플랜을 찾으면 해당 작업을 종료하고 다음 단계로 실행을 한다. 

* Query Executor 
- 단순하게 말하면 쿼리를 수행하는 것이다. 쿼리플랜에 의해서 쿼리를 수행한다. SELECT 쿼리는 데이터 검색을 필요로 한다. 그래서 이 요청은 Storage Engine의 Access Methods 에 전달이 된다. 

* Access Methods
- Access Methods는 데이터와 인덱스에 대한 스토리지 구조는 물론 데이터 검색 및 수정을 위한 인터페이스를 제공하는 코드 모음이다. 데이터를 검색하는 모든 코드가 포함되어 있지만 실제로는 작동 자체를 수행하지는 않고, 요청을 Buffer Manager로 전달한다.

* Buffer Manager 
- Buffer Pool을 관리하는 역할을 한다. 페이지에서 일부 행을 읽어야 할 경우 Buffer Manager는 Buffer Pool의 데이터 캐시를 검사하여 이미 페이지가 메모리에 캐시되어 있는지 확인한다. 페이지가 이미 캐시 된 경우 결과는 Access Methods로 다시 전달되지만 페이지가 캐시에 없는 경우 Buffer Manager는 디스크의 데이터베이스에서 페이지를 가져 와서 데이터 캐시에 저장하고 결과를 Access Methods에 전달한다. 여기서 핵심은 Buffer Manager는 오직 메모리에있는 데이터로만 작업한다는 것이다. 새로운 데이터를 요청받으면 디스크에서 처음 읽은 다음 결과 세트로 반환되기 전에 메모리 (데이터 캐시)에 기록된다. 이것은 SQL Server가 메모리의 사용 가능한 페이지를 최소 수준이 유지 되어야 하는 이유이다. 캐시에 처음 읽은 데이터를 넣을 공간이 없으면 새로운 데이터를 읽을 수 없다. Access Methods 코드는 SELECT 쿼리에 단일 페이지가 필요하다다고 확인 되었으면 Buffer Manager에 요청한다. Buffer Manager는 데이터 캐시에 데이터가 있는지 확인 후 데이터를 찾지 못했을 경우 디스크에서 캐시로 로드한다.

* Data Cache
- buffer pool에서 가장 많이 차지하는 부분이다. 메모리 최대 사용자이다. 사용자가 읽기 전에 디스크에서 데이터를 읽어와 기록해둔다. sys.dm_os_buffer_descriptors DMV는 각 데이터베이스가 데이터 캐시에서 사용하는 공간의 양을 확인할 수 있다.
캐시의 각 페이지 Header에는 액세스 되었을 때 세부 정보가 저장되며 캐시를 통한 주기적 스캔은 SQL Server가 일부 캐시를 비워야하는 경우 가장 낮은 카운터가있는 페이지가 먼저 플러시된다. 
Perfmon에서 MSSQL$<instance>:Buffer Manager\Page Life Expectancy 항목은 페이지가 얼마나 오래 캐시에 유지되고 있는지를 확인 할 수 있다. 메모리가 부족하다면 데이터 페이지가 캐시에서 훨씬 더 자주 플러시된다. Page Life Expectancy(PLE)는 최소 300 초 권장하지만 요즘에는 일반적으로 1000 초로 간주한다. 허용되는 임계 값은 데이터 사용량에 따라 달라질 수 있지만 대부분 PLE가 1000 초 미만이거나 300 미만인 경우 메모리 부족 문제를 쉽게 찾을 수 있다.
SELECT 쿼리에 대한 결과 집합이 버퍼 풀의 데이터 캐시에 있고 sys.dm_os_buffer_descriptors DMV에 항목이 있다. Buffer Manager에 결과 집합이 생기면 Access Methods로 전달되어 클라이언트에 전달된다.


위 그림은 SIMPLE SELECT 쿼리가 입력되었을 때 결과를 클라이언트에 도출하기 위한 과정을 보여주는 것이다. 

출처: Professional SQL Server 2012 Internals and Troubleshooting 7-15p.

[SQL Server] SNI 의 종류

Professional SQL Server 2012 Internals and Troubleshooting 정리

SNI (SQL Server Network Interface) : 프로토콜 계층에 속하는 것으로 클라이언트와 서버간의 네트워크 커넥션을 성립시키는 것이다. 여기서 말하는 클라이언트는 단순히 사용자(사람 혹은 어플리케이션)가 아닌 다른 것을 포함한다. 그 이유는 SNI의 종류가 여러가지이며, 각각의 역할이 다르기 때문이다. 또한 우리가 어떤 방식으로 연결할지 직접적인 결정을 하는 것이 아니다. 단지 우리는 네트워크 구성을 할 뿐이다. 

SNI의 종류

1) Shared Memory: 로컬 컴퓨터에 있는 SQL server와 Client를 연결하는 역할이다. 설정 속성이 필요하지 않으며, 로컬 머신에서 항상 먼저 연결 시도 되는 부분이다.

2) TCP/IP: 가장 많이 사용하는 프로토콜, SQL Server에 IP, Port로 연결할 수 있도록 하는 것. 기본 포트는 TCP 1433이고, SQL Browser Service는 UDP 1434를 사용한다. 

3) Named Pipes: 주로 복제시 사용하며, 해당 기능을 사용하기 위해서는 445 Port가 열려 있어야 한다. 해당 기능을 사용하기 위해서는 SQL Configuration Manager에서 Alias 기능을 설정해야 한다. 

4) VIA(Virtual Interface Adapter): 고성능을 가능케 하는 어댑터로 사용을 위해서는 두 시스템 간의 전용 연결이 필요하다. 2012 버전에는 사용되지만 추후 버전에서는 지원하지 않을 예정

출처: Professional SQL Server 2012 Internals and Troubleshooting 7p


[SQL Server] SQL-Server의 구조

Professional SQL Server 2012 Internals and Troubleshooting 정리



이 그림는 SQL Server을 이해하는데 꼭 필요한 그림이다.

SQL Server의 쿼리 라이프 사이클을 이해하기 위해 필요한 그림

주황색 : HDD 혹은 SSD 말 그대로 데이터를 저장하는 곳, MDF, LDF 파일을 저장하는 곳이라고 생각하면 된다.

초록색 : DBMS 부분이다. 우리가 SQL-Server를 설치하면 이렇듯 Relational Engine과 Storage Engine 으로 구분이 된다. 

파란색 : 메모리 영역이다. 이 메모리 영역을 Buffer Pool 이라고 부르는데 이 영영은 Plan cache와 Data Cache로 나뉜다. 

보라색 : 우리가 사용하는 SSMS이다. DBMS에 접속하기 위한 툴이라고 생각하자.


SQL-Server는 두 개의 메인엔진이있다. Relational / Storage 이다.

Relational Engine : Query Processor 라고 부른다. 그것은 이 엔진의 가장 중요한 기능이 쿼리 최적화와 수행이기 때문이다. Command Parser는 쿼리의 문법을 체크하고 쿼리 트리를 준비한다. 모든 DBMS의 핵심인 Query Optimizer, 쿼리 수행을 책임지고 있는 Query Executor가 이 엔진에 포함된다.

Storage Engine : 해당 엔진은 DBMS의 모든 I/O를 관리한다. Access Method Code는 행, 인덱스, 페이지, 할당, 행 버전에 대한 I/O 요청을 처리한다. Buffer Manager는 SQL Server의 메모리 소비 주 고객인 Buffer Pool을 다룬다. Transaction Manager는 격리성을 유지하기 위한 데이터의 잠금과 트랜잭션 로그를 관리하는 역할을 한다.

Buffer Pool : 메모리를 가장 많이 사용하는 주체로 Plan cache와 Data Cache로 나뉘며 해당 부분은 다음 부분에 더 설명하기로 한다.


출처: Professional SQL Server 2012 Internals and Troubleshooting 6p



[SQL Server] 트랜잭션의 종류

Professional SQL Server 2012 Internals and Troubleshooting

현재 읽고 있는 MSSQL 책 내용 잊지 않게 필요한 내용 정리

트랜잭션의 종류에는 두 종류가 있다.
Implicit와 Explicit 로 나뉘는데 해당 트랜잭션의 다른점은 어떻게 생성이 되느냐에 차이에 있다.

1. Implicit Transaction
 - SQL Server 에서 자동으로 생성되는 트랜잭션이다. SQL 서버 자체에서 ACID를 보장하기 위해 만들어진 것이다.  예를 들어 Update 문으로 10 Rows를 수정한다고 했을 때 해당하는 데이터에 대해 ACID를 보장하기 위해 트랜잭션으로 감싼다.

2. Explicit Transaction
- Implicit가 자동이라면 Explicit는 T-SQL Command 로 Begin Transaction - Commit Transaction Or Rollback Transaction 으로 명시적으로 선언한 것이다. 

Explicit Transaction은 그룹으로 묶여 있는 Commit, Rollback으로 비지니스적인 ACID를 보장할 수 있도록 한다. 

출처: Professional SQL Server 2012 Internals and Troubleshooting 5p

[SQL Server] ACID개념 설명

Professional SQL Server 2012 Internals and Troubleshooting

현재 읽고 있는 MSSQL 책 내용 잊지 않게 필요한 내용 정리

ACID : 데이터 베이스 트랜잭션의 특성 4가지

Atomicity: All or Nothing 이라고 생각 하면 된다. 트랜잭션을 하나의 개체로 묶어 성공적으로 끝나지 않았다면 Rollback을 하고 성공하면 작업을 마치는 것이다. 마치 내가 ATM에서 현금을 꺼내는 작업을 했을 때, 내가 현금을 지급받는 일은 내 계좌에 돈이 차감이 되는 것과 함께 발생이 되야한다. 둘 중 하나만 발생하면 Atomicity가 위반된것임.

Consistency: 데이터가 지정한 룰을 위반하지 않아야 한다. 재고의 값이 음수가 허용되지 않은 곳에 음수는 들어가거나, Female 또는 Male 로만 값이 지정되어야 하는데 그 외의 값이 지정되거나 하는 일이 없어야 한다는 것이다. 만약 이러한 제약조건을 위반하는 상황이 발생하면 트랜잭션은 완료 되지 않아야 한다.

Isolation: 현재 작업 중인 데이터를 다른 데이터가 사용할 수 없도록 하는 것이다. Isolation 속성은 각각의 트랜잭션은 완료가 되기 전에 해당 데이터를 다른 트랜잭션에서 읽는 것도 허용을 해서는 안된다는 것이다. 그러나 이 속성은 비즈니스 적인 요소와 적절하게 균형을 맞추는 것이 중요하다.

Durability: 트랜잭션이 완료 되었다면 시스템 장애가 발생했다고 하더라도 완료된 데이터는 보존이 되어있어야 한다. MSSQL에서는 이 속성을 트랜잭션 로그를 통해 구현한다. 트랜잭션이 커밋이 되기 전에 트랜잭션 로그에 해당 액션을 그대로 기록하고 있음으로서 데이터의 보존을 보장하는 것이다.

출처: Professional SQL Server 2012 Internals and Troubleshooting 4-5p

2018년 9월 29일 토요일

[미술-Drawing] 아트섬 아마도 성인 미술교육 수업 - 4

이 글은 저의 취미 생활 중 하나인 미술 교육에 관한 이야기 입니다.

벌써 미술교육 수업도 4주차에 접어 들었습니다. 사실 어제 5주차 수업이 끝났습니다. 4주차 수업이 끝나지 않았기에 우선 4주차 후기를 남겨 보겠습니다. 4주차에는 2주에 걸친 그림 그리기를 하기로 했습니다. 저는 그림그릴 재료로 마커와 색연필을 선택했습니다. 정말 마커 사서 이렇게 뿌듯할 수가 없는 시간 이었습니다. 선생님께서 그리고 싶은 소재가 있는지 이것저것 주셨는데 왠지 끌리지가 않더라구요.

제가 선택한 소재는 남편과 함께 찍은 사진이었습니다. 예전에 부산 여행갔을 때 감천문화마을에서 찍은 사진인데요.


이 사진입니다. 선생님께서 연습을 먼저 해보라고 하셔서 색연필로 먼저 그려봤습니다. 



이렇게 그려보면서 감을 잡았어요. 원본 사진의 찢청이 너무 맘에 들지 않아서... 치마로 변경하기로 했어요. 제 그림이니까 제가 마음이 가는대로 그리기로 했습니다. 이렇게 그려보니 원래 그림을 어떻게 그려야 할 지 감이 오더라구요. 자세같은 거나 어떤 식으로 그려야 할지 내가 무엇을 잘 못하는지 선생님께서 잘 봐주셨어요. 이렇게 그려보고 다시 제가 그릴 도화지에 본격적으로 그려봤습니다. 


이렇게 도화지에 그려봤어요. 제가 처음에 위치를 어떻게 잡아야할지 정말 막막했는데 선생님께서 중심이 되는 선들을 우선 그려보고 하나 씩 그려보라고 하셨어요. 그래서 인물의 머리 다리선 그리고 도로와 벽의 경계를 그어가면서 천천히 그렸어요. 스케치가 끝난 모습입니다. 얼추 사진과 비슷하지 않나요. 


채색 차례입니다. 채색을 할 때 주의할 점은 채색을 하면 지우개 선이 지워지지 않는다는 것입니다. 그래서 채색 전 지우개로 스케치한 선을 지우고 마커로 칠했습니다. 지우개로 지우고 마커를 칠하고 반복했습니다. 채색하면서 얼굴선과 옷의 선을 색연필로 표현했습니다. 오늘 수업은 여기까지였습니다. 

제가 그리는 동안 남편은 영화 속 한장면 그리기를 했어요. 제 그림에 집중하느라 남편의 그림을 잘 확인 하지 못했어요. 정말 자기 그림에만 집중했던 시간이었습니다.


남편이 그린 그림인데 선생님이 많이 도와 주셨다고 해요. 그래도 저보다 더 자세하게 그린다는 건 인정 !!!

이렇게 4주차 수업이 끝났습니다. 나머지는 5주차 수업때 진행하기로 했습니다. 수업을 하면서 느끼는 거지만 제가 조금씩 그림 그리는게 나아지고 있음을 느꼈습니다. 5주차 수업의 마무리가 어떻게 될지 기대됩니다.

아트섬 아마도에 관한 이야기는 아래 링크에서 확인할 수 있습니다.



[SQL Server] Linked Server setting

서버 이관 시 체크해야 할 사항 중의 하나 이다. 기존 서버에 링크드 서버 확인해 보자.

기본적으로 

sp_linkedservers

를 입력하면 해당 인스턴스에 연결된 링크드 서버 정보를 볼 수 있다. 만약 링크드 서버가 없는 인스턴스라면 자기 자신 하나만 나올 것이다.


또한 Linked server의 정보를 정리할 때 다음 쿼리를 통해 정보를 알아 낼 수 있다.


select T1.name, T1.product, T2.remote_name, T2.modify_date
from sys.servers T1
inner join sys.linked_logins T2 on T1.server_id=T2.server_id

sys.servers는 링크드 서버의 정보를 담고 있다.
sys.linked_logins 와 조인하여 해당 링크드 서버가 어떤 계정으로 접속을 하는지 확인 할 수 있다.


[SQL Server] 대용량 데이터 파일로 바로 내보내기

데이터 추출 작업을 진행하다 보면 대용량의 데이터를 파일로 저장 해야 하는 경우가 있다.
데이터가 작다면 즉석에서 복사 붙여넣기가 편하지만 데이터가 많다면 시간이 오래걸리고 메모리가 overflow되어 진행되지 않는다.

이런경우 SQL Server Import and Export Wizard 도구를 활용하여 진행한다.

1. 작업하고자 하는 DB에서 마우스 우클릭 > Tasks > Export Data... 선택 하면 해당 도구가 실행된다.

2. Next 버튼을 클릭

3. Choose a Data Source 메뉴는 데이터를 어디에서 가지고 올것인가를 결정하는 것이다. 
  SQL Server Native Client XX.0을 선택한다.

4. 서버 명 혹은 IP 정보를 입력하고 인증모드를 선택한다 주로 로컬이면 (local)이라고 하면 되고, 인증모드도 해당 SQL 서버에 접속할 때 사용하는 인증모드를 선택해 주면된다.

5. Database 에서 데이터를 가지고 갈 DB를 선택 후 Next> 버튼을 클릭해준다. 

6. 데이터를 어떻게 추출할지 Choose a Destination 화면이 나온다. 원하는 것을 선택해 주면 된다. csv 파일로 내보내는 것을 예로 들면 Destination은 Flat File Destination으로 선택한다.

7. File name 에서 파일이 저장될 곳을 정해서 지정해준다. 이때 저장 옵션을 csv로 선택해주는 것이 중요하며, Unicode  옵션을 설정해주는 것이 대체적으로 데이터가 깨지지 않는다.

8. Column name in the first data row 옵션이 있는데 해당 파일의 첫 행을 컬럼명으로 할 것인지 물어보는 것이다. 체크를 하는 것이 편하다. 나중에 데이터 분석을 할 때 해당 데이터가 어떤 컬럼의 데이터에 해당하는지 명확하게 확인할 수 있다.

9. 이제 전송할 데이터를 어떻게 추출할지 결정한다. Write a query to specify the data to transfer 옵션은 쿼리 작성을 통해 작업을 진행하겠다는 뜻이다. 해당 옵션 선택 후 Next> 버튼을 클릭한다.

10. SQL statement 에서 추출할 대상의 쿼리를 써넣는다.
 ex> select * from tbl_name
 Parse 버튼을 누르면 이 쿼리가 유효한 쿼리인지 다시 확인 해준다. 유효하다면 Next> 버튼을 눌러준다.

11. 이제 텍스트의 행과 열을 구분한다. csv로 선택했다면 Column delimiter 가 Comma {,} 로 될 것이다. 다른 옵션이 필요하다면 선택 가능한다. 이때도 Edit Mappings..를 통해 데이터 매핑을 진행 할 수 있다. 문제가 없다면 Next> 버튼을 클릭한다.

12. Save and Run Package 에서  Run immediately 를 선택하면 바로 실행이 가능하다. Next> 버튼 클릭하면 수행할 동작을 정리한 내용을 보여준다. 진행 작업이 맞다면 Finish>>|를 눌러주면 작업이 진행된다.

13. 성공결과를 확인 하면 원하는 파일을 확인 할 수 있다.

[SQL Server] DB 파일이 차지하는 공간을 알아보자

요즘은 로그 DB 삭제에 대해 많이 찾아 보곤 했는데 관련 내용을 정리해 두고자 한다. 우선 작업이 필요한 DB의 환경은 복구 모델이 simple 이다. 데이터를 삭제하는 작업을 진행할 경우 우선적으로 지우지 않아야 하는 데이터를 지우면 안되기 때문에 항상 신중하게 작업을 할 수 밖에 없다. 해당 DB를 정리하는 목적은 우선적으로 6개월 이상 지난 로그를 사용하지 않고 있기 때문에 데이터를 정리하면서 유휴 공간을 확보하고자 함이다. 

기본적으로 해당 DB의 MDF 파일이 물리적 (실제적)으로 얼마나 큰 공간을 차지하고 있는지를 알아야 한다. 그 때 필요한 명령어가 sp_spaceused 이다

sp_spaceused 를 실행하면 다음과 같은 내용을 확인 할 수 있다.

database_name : 현재 DB의 이름
database_size : 현재 데이터 베이스의 크기(MB) 해당 사이즈에는 데이터 및 로그 파일의 크기가 모두 포함된다. 그러므로 database_size > reserved + unallocated space  이다.
unallocated space : DB 개체용으로 예약 되지 않은 DB 공간
reserved : DB의 개체에 의해 할당된 총 공간
data : 데이터가 사용 중인 공간
index_size : 인덱스가 사용하는 총 공간
unused : DB의 개체에 예약 되었으나 아직 사용되지 않은 총 공간

만약 DB에서 특정 테이블이 차지하는 공간을 알고 싶을 때는

USE DB_Name
Go
exce sp_spaceused N'테이블명'
GO

으로 확인 할 수 있다.
이와 같은 방식으로 로그를 삭제하고 난 후 shrinkfile 작업을 할때 어느 정도의 유휴공간이 있는지를 확인할 수가 있다.


[SQL Server] 관련 프로시저 검색

가끔 프로시저를 검색하는 경우 유용한 쿼리문

USE DBName
GO
 
SELECT distinct object_name(id)
FROM syscomments
WHERE text LIKE '%검색어%'

검색어에 검색하고자 하는 단어를 넣고 찾으면 해당 단어와 관련된 프로시저들의 명을 보여준다.
초보인 나에게 유용하다.
좀 더 자세한 정보는 더 공부한 뒤 수정 및 추가할 예정이다.

[영어원서 읽기 - 1] Magic Tree House #1 Dinosaurs Before Dark

안녕하세요.

최근에 새로 시작한 취미 생활을 공유 합니다.
그건 바로 영어 원서 읽기 인데요. 영포자가 꿈꾸는 영어원서 쉽게 읽기(부경진)를 읽고 실천해 봤습니다. 욕심내지 않고 하루에 한 챕터 씩 읽자는 마음으로 시작해서 한 권을 모두 읽어서 공유 해봅니다.


처음 시작은 어린이들의 동화로 시작했습니다. 전 영어에 있어서는 어린이나 다름 없으니까요. 간략하게 이야기 하면 남매가 우연히 발견한 나무집을 통해 시간여행을 하는 이야기였습니다. 첫 번째 목적지는 백악기 공룡 시대 였어요. 


이렇게 10개의 chapter로 구성되어있습니다. 하루에 하나 씩 욕심내지 말자는 마음으로 시작했습니다. 과연 잘 할 수 있을 까요? 영어원서 쉽게 읽기 책에서 나온 방법을 참고해서 읽었습니다. 각 chapter별로 플래그를 붙여서 구분을 해서 읽엇습니다. 그리고 읽은 날짜를 기억하기 위해서 읽을 때 마다 플래그에 네임펜으로 날짜를 적었습니다.


책을 읽을 때 가장 지켰던 원칙 하나는 절대 모르는 단어를 그냥 넘기지 않았어요. 과거형도 모르면 다 찾아보고, 뜻은 찾았는데 표현이 어색하면 전체 뜻을 검색해보고, 가장 유사한 뜻에 맞게 해석해보면서 읽었습니다. 이 방법은 영어원서 쉽게 읽기에서도 나오는 방법이었는데, 더디기는 하지만 책의 내용을 이해하는데 가장 큰 도움이 되서 실천했습니다. 확실히 이 방법으로 책을 읽으니 책의 내용도 이해하기 쉽고 좋았습니다. 그리고 현재 병행하고 있는 영어단어 암기에도 도움이 됐어요. 새로나온 단어가 겹치기도 했거든요. 

8월 31일에 시작한 Magic Tree House 1권을 9월 13일에 모두 읽었습니다. 부담 갖지 않고 꾸준히 하는데 집중해서 10일이 더 소요되긴 했지만 다 읽었다는데 저는 만족합니다. 영어 원서를 이렇게 끝까지 집중해서 읽은 적은 처음 이거든요. 이전에 선물받은 Present를 대충대충 넘겨가면서 읽었는데 다음에 기회가 된다면 다시 읽어볼 생각입니다.

그리고 어린이 동화책이라고 해서 만만하게 보면 안된다는 걸 알았습니다. 책에 있는 모르는 단어들을 다 읽고 정리하는데 50개 넘는 단어를 모르고 있었다는 걸 알았거든요. 영어 원서 쉽게 읽기에서는 카드에 정리하신다고 하는데 솔직히 거기까지는 자신 없더라구요. 저는 구글 시트에 정리했습니다. 나중에 Flashcards 어플리케이션에 옮겨둘 생각으로 단어/뜻 이렇게 간단히만 정리했습니다.

첫 시작은 동화책이지만 천천히 업그레이드 되는 모습을 기록할 예정이니 지켜봐 주시길 바랍니다. 감사합니다.

Dinosaurs Before Dark (Paperback, 미국판) - 10점
메리 폽 어즈번 지음, 살 머도카 그림/Random House


[SSIS] 패키지 파일 패스워드 확인 쿼리

SSIS의 패키지의 패스워드를 잃어버렸다.
그런데 아무리 머리를 쥐어짜도 모르겠다.

만약 해당 패키지가 Job에 등록 되어있다면 찾을 수 있다.

업무를 인수인계 받았는데 담당자가 부재거나 퇴사 했는데 이런 경우가 발생했다면 정말 난감하다. 애초에 정말 패스워드 관리를 잘해야 하는게 맞지만... 사람 일이 뭐 매번 뜻대로 되는 것은 아니니 빨리 해결할 수 있는 방법을 찾아보자.

조건: 해당 패키지가 SQL 서버에 JOB으로 등록되어 있을 경우이다.

쿼리는 아래와 같다.

USE msdb
GO
-- 패키지 파일 암호 확인 쿼리
DECLARE @jobname VARCHAR(128= NULL
    , @stepname VARCHAR(128= NULL;
SELECT sj.name AS JobName
        , sjs.step_name
        , sjs.subsystem
        , sjs.command
        ,CASE WHEN sjs.command LIKE '%/DECRYPT "\"%' 
                THEN SUBSTRING(sjs.command, CHARINDEX('/DECRYPT "\"',sjs.command,1)+12
                , CHARINDEX('\""',SUBSTRING(sjs.command
                , CHARINDEX('/DECRYPT "\"',sjs.command,1)+12, LEN(sjs.command)),1)-1)
            WHEN sjs.command NOT LIKE '%/DECRYPT "\"%' AND sjs.command LIKE '%/DECRYPT "%'
                THEN SUBSTRING(sjs.command
                , CHARINDEX('/DECRYPT "',sjs.command,1)+10
                , CHARINDEX('"',SUBSTRING(sjs.command
                , CHARINDEX('/DECRYPT "',sjs.command,1)+10, LEN(sjs.command)),1)-1)
            ELSE LTRIM(RTRIM(SUBSTRING(sjs.command,
                CHARINDEX('/DECRYPT', sjs.command, 1+ 9,
                CHARINDEX('/', sjs.command,
                CHARINDEX('/DECRYPT', sjs.command, 1)
                + 1- CHARINDEX('/DECRYPT',
                sjs.command, 1)
                - 9)))
        END AS pkgpassword
    FROM msdb.dbo.sysjobs sj
        INNER JOIN msdb.dbo.sysjobsteps sjs
            ON sj.job_id = sjs.job_id
    WHERE sjs.subsystem = 'SSIS'
        AND sjs.command LIKE '%/DECRYPT%' 
        AND sj.name = ISNULL(@jobname, sj.name)
        AND sjs.step_name = ISNULL(@stepname, sjs.step_name);

해당 쿼리로 암호를 찾을 수 있는 이유는 SQL Server Agent에서 Job을 실행할 때 Command 형태로 명령을 내리는데 이때 패키지 파일의 암호도 옵션으로 들어가 있기 때문이다.

어떻게 보면 보안에 정말 취약한 부분이다.

해당 쿼리는 참고를 통해 내가 관리하는 DB에 맞게 변경한 것이다. 
예외 사항이 있을 수 있겠지만 암호를 확인할 수 있고, sqlcommand 컬럼에서 해당 패키지의 경로, 패스워드, 옵션을 정확하게 확인할 수 있다. 

참고쿼리 <- 출처를 확인 하고 싶으면 클릭하면 된다.

[SSIS] 동적 파일 생성 방법

최근 작업을 하면서 데이터를 추출 해줘야 하는 이슈가 있었다. 데이터의 양도 많고, 월별로 구분을 해줘야 하는 이슈가 있어서 SSIS 패키지를 활용하기로했다. 문제는 해당 데이터를 csv파일로 자동으로 생성을 해주는 기능이 있느냐는 것... filesystemtask에서 하는 것인줄 알았으나 createdir은 있으나 파일을 만드는 것은 없다. 그래서 구글링을 시작했으니 역시 구글은 모든 것을 알고 있다.


1. DataFlow Task 작업을 넣는다.
2. 데이터를 가지고 올 Source를 결정한다. OLEDB, Mysql 등등
3. Flat File Destination 태스크와 source를 연결한다. (나는 csv로 파일을 내보낼 것이므로 해당 Task선택) 
4. 컬럼 명 세팅과 변수 형 등을 세팅한다.
5. 4번작업까지 완료 되었으면 Connection Managers에서 해당 flat file 커넥션을 우클릭해서 properties를 선택
6. 항목에서 Experresions를 선택하면 Property Expressions Editor 창이 뜬다.
7. Property 항목에서 ConnectionString을 선택하고 Expressions를 입력할수 있도록 창을 띄운다.
8. "D:\\"+변수명+"_filename.csv" 로 설정을 하고 세팅을 완료 한다.
9. 파일을 실행 시켜서 해당 파일이 저장되었는지 확인한다.

매일가지고 오는 데이터가 있거나 규칙적으로 처리해야 하는 파일 등이 있을 때 귀찮게 클릭 여러 번 하지말고 SSIS를 활용하면 좋을 것 같다. 실제로 해당 작업을 통해서 3종류의 파일을 모두 가지고 올 수 있었으며 소요 시간은 대략 33초 정도 소요 되었다. 가장 많이 가지고온 row의 수가 100만로우 였으며, loop는 3번 돌았음을 대략적으로 계산해보면 세개의 테이블을 한번 가지고오는데 10초정도 소요되었다고 볼 수 있다. 

[SSIS] Script Task로 mysql server 연결하기

SSIS를 통해 데이터를 가지고 올 때 여러 대의 mysql 서버를 접속해서 데이터를 가지고 오는 경우가 있다. 예를 들면 게임DB가 여러 대 있을 경우 DB만 여러 개이고, 스키마 정보는 동일할 때 사용하기 좋은 방법이다.

여러 방법이 있지만 내가 아는 방법은 foreach문에 script task로 접속 정보 변경을 통해 접근하는 방법이다.

아래 코드에서 __v_dbname, __v_ip, __v_port, userid, password, connection 부분은 자신에게 맞게 수정해야 한다.

SSIS Script Task 
언어: Visual Basic

public sub Main()
        Dim db_connection As String
        Dim strdb_name As String
        Dim strsvr_ip As String
        Dim strsvr_port As String
        Dim FailConn As Boolean
        Dim FireAgain As Boolean
        Dim conn As New MySqlConnection
        FailConn = False
        FireAgain = True
        strdb_name = Dts.Variables("__v_dbname").Value.ToString           'ssis변수에서 받아오는 부분
        strsvr_ip = Dts.Variables("__v_ip").Value.ToString                        'ssis변수에서 받아오는 부분
        Strsvr_port = Dts.Variables("__v_port").Value.ToString                  'ssis변수에서 받아오는 부분
        db_connection = "server =" & strsvr_ip & ";user id=userid;password=password;port=" & Strsvr_port & ";database=" & strdb_name & ";"
        If Not conn Is Nothing Then conn.Close()
        conn.ConnectionString = db_connection
        Try
            Dts.Connections("connection").ConnectionString = db_connection
            conn.Open()
            Dts.TaskResult = ScriptResults.Success
            'MsgBox(db_connection, MsgBoxStyle.Information, db_connection)
        Catch ex As Exception
            'Dts.Events.FireError(0, "My Script Task", "An error occured:" + ex.Message.ToString(), "", 0)
            Dts.TaskResult = ScriptResults.Failure
        End Try
End sub