2014. 11. 6. 14:28

Windbg 명령어 & 설치


* WinDbg 설치 방법 

OS 버전에 맞는 파일을 받아 설치 합니다. 재부팅이 필요 하네요.




WinDbg 명령어

                                                                                                                                                                                                                                                              출처         

Command

option

usage

Desc

종료

q



디버깅 종료

qd



디버깅 종료;연결해제

디버깅 환경정보

vertarget



타겟 컴퓨터 정보 표시

version



디버그 환경 정보 표시

.lastevent



마지막 디버그 이벤트 정보 표시

||



디버깅 세션 정보 표시

sumble & sorurce

.symfix



MS 심볼경로 설정

.sympath



심볼경로 확인/설정

.sym noisy



심볼파일 검색 과정을 출력

.srcpath



소스경로 설정

.srcnoisy


.srcnoisy 1

소스경로 검색 과정을 출력

모듈

lm


l

로드된 모듈만 표시



m [pattern]

패턴과 일치되는 모듈만 표시



v

모듈 상세정보 표시

!lmi

!lmi ntdll.dll


모듈 상세정보 표시

.reload


/f [m_name]

심볼을 즉시 로드

x

X ntdll!*

X *!*abc*

/v

/t

/n

심볼 타입을 표시.

데이터 타입을 표시

이름순으로 정렬

ln


ln [address]

해당 주소에 근접한 심볼의 정보 표시

레지스터

r



레지스터 정보 표시

r $proc



현재 프로세스의 PEB주소( user-mode)

현재 프로세스의 EPROcESS주소( kernel-mode)

r $thread



현재 스레드의 TEB주소( user-mode)

현재 스레드의 ETHREAD주소( kernel-mode)

r $tpid



현재 프로세스ID(PID)

r $tid



현재 스레드ID(TID)

언어셈블

u


f

b

언어셈블

언어셈블(함수전체)

언어셈블(ip이전의8개 명령어)

콜스택

k


[n]

p

b

n

v

f

콜스택 정보표시

함수정보 출력

인자표시

프레임번호

FPO정보 표시

스택 사용량 표시

break point

bp

bp 0x123456


bp 설정

bl



bp 리스트 출력

bc

bc * | [frame_no]


bp 삭제

bd,be

bc * | [frame_no]


bp disable/enable

bm

bm notepad!*Win*


패턴과 일치하는 모든심볼에 bp설정

bu

bu aaa!bbb


로드되지 않은 심볼에 대한 bp설정

ba



특정 주소에 access bp

지역변수

dv

dv modulr!test*

/i

/V

심볼유형과 인자유형 표시

변수저장 위치 표시( register or address )

데이터유형

dt

df _EPROCESS 0xaddr


주소를 특정 데이터 형으로 변환해서 표시

du



Unicode string 표시

da



Ansi string 표시

dc




db




dy








!address

!address

!address [address]



프로세스 & 스레드 정보

!peb



PEB(Process Environment Block)표시

!teb



TEB(Thread Environment Block) 표시





!gle



API의 마지막 에러코드 표시

실행 제어

t



Trace

~.t



다른 스레드를 중지시킨 상태에서 하나의statementt 실행

g




p



Step Over

gu

gu

~0 gu


현재함수가 복귀할 때 까지 실행

스레드 0을 제외한 모든 스레드를freeze

wt



내부에서 호출된 함수와 함수호출 횟수등의 정보 표시

.cxr



컨텍스트 변경

!ready




.thread




!thread




.trap




.process




!process




ed




eb

eb .-6 90 90 90 90 90 90


6byteNOP(0x90)으로 변경

!error

!error [error code]


에러코드 정보표시


'ETC' 카테고리의 다른 글

SQL Server 2012 Certification upgrade info  (0) 2015.05.20
메모리 dump 분석 예 ( 정확하지 않음 )  (0) 2014.11.06
Window 서비스 등록/삭제 방법  (0) 2011.10.20
Admin::Superdome VS DL580 G7  (0) 2011.01.10
2014. 9. 2. 08:53

배포 메일링 주소 변경

메일링 주소가 변경되었을 때 테이블 내역 수정 하기

 

ReportServiceDB

 

UPDATE SUBSCRIPTIONS

SET EXTENSIONSETTINGS = REPLACE(CONVERT(NVARCHAR(MAX), EXTENSIONSETTINGS), '변경전', '변경후') Collate Latin1_General_CI_AS_KS_WS

WHERE EXTENSIONSETTINGS LIKE '%DL-SEL-DBA@EBAY.COM%'

'Reporting Service' 카테고리의 다른 글

시작시 늦어지는 경우 (Slow StartUP)  (1) 2012.10.09
공유 데이터 원본 Overwrite  (0) 2009.08.04
2014. 8. 21. 10:43

SQL 2012 Intergration Service 구성 항목 설정

1. SQL 2012  Intergration Service 의 경우 원격 인스턴스 접근.. 명명된 인스턴스 등을 사용할 때 구성 파일을 설정해야 한다


도움말 : http://msdn.microsoft.com/ko-kr/library/ms137789.aspx


Integration Services 서비스는 구성 파일을 사용하여 해당 설정을 구성합니다. 기본적으로 이 구성 파일의 이름은 MsDtsSrvr.ini.xml이고 저장 위치는 %ProgramFiles%\Microsoft SQL Server\110\DTS\Binn 폴더입니다.

일반적으로 이 구성 파일이나 이 구성 파일의 위치는 변경하지 않아도 되지만 패키지가 명명된 인스턴스, 데이터베이스 엔진의 원격 인스턴스 또는 여러 데이터베이스 엔진 인스턴스에 저장되는 경우에는 이 구성 파일을 수정해야 합니다. 또한 이 구성 파일을 기본 위치 이외의 다른 위치로 이동할 경우 파일 위치를 지정하는 레지스트리 키도 수정해야 합니다.


파일 구성 내역 

Integration Services를 설치할 때 설치 프로세스는 Integration Services 서비스에 대한 구성 파일을 만들고 설치합니다. 이 구성 파일에는 다음과 같은 설정이 들어 있습니다.

  • 서비스가 중지되면 패키지에 중지 명령이 전송됩니다.

  • SQL Server Management Studio의 개체 탐색기에서 Integration Services에 대해 표시할 루트 폴더는 MSDB와 파일 시스템 폴더입니다.

  • Integration Services 서비스에서 관리하는 파일 시스템의 패키지는 %ProgramFiles%\Microsoft SQL Server\110\DTS\Packages에 있습니다.

이 구성 파일은 Integration Services 서비스에서 관리할 패키지가 들어 있는 msdb 데이터베이스도 지정합니다. 기본적으로 Integration Services 서비스는 Integration Services와 동시에 설치되는 데이터베이스 엔진 인스턴스의 msdb 데이터베이스에 있는 패키지를 관리하도록 구성됩니다. 데이터베이스 엔진 인스턴스가 동시에 설치되지 않는 경우 Integration Services 서비스는 데이터베이스 엔진의 로컬 기본 인스턴스에 있는 msdb 데이터베이스에 저장된 패키지를 관리하도록 구성됩니다


데이터베이스 엔진의 명명된 인스턴스나 원격 인스턴스에 저장된 패키지를 관리하려면 구성 파일을 수정해야 합니다. 구성 파일을 업데이트하지 않는 경우 명명된 인스턴스나 원격 인스턴스의 msdb 데이터베이스에 저장된 패키지를 보기 위해 SQL Server Management Studio에서 개체 탐색기를 사용할 수 없습니다. 개체 탐색기를 사용하여 이러한 패키지를 보려고 하면 다음과 같은 오류 메시지가 나타납니다.



수정 파일 예

<?xml version="1.0" encoding="utf-8"?>

<DtsServiceConfiguration xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

  <StopExecutingPackagesOnShutdown>true</StopExecutingPackagesOnShutdown>

  <TopLevelFolders>

    <Folder xsi:type="SqlServerFolder">

      <Name>MSDB</Name>

      <ServerName>ServerName\InstanceName</ServerName>

    </Folder>

    <Folder xsi:type="FileSystemFolder">

      <Name>File System</Name>

      <StorePath>..\Packages</StorePath>

    </Folder>

  </TopLevelFolders>  

</DtsServiceConfiguration>            



2. 원격 Intergration Service 서버에 연결 

 

SQL Server Management Studio나 다른 관리 응용 프로그램에서 원격 서버의 Integration Services 인스턴스에 연결하려면 응용 프로그램 사용자에게 서버에 대한 특정 권한 집합이 필요합니다.


원격 서비스에 접속시 엑세스가 거부되었다고 하면 권한을 부여 해야 합니다. 


충분한 권한이 없는 사용자가 원격 서버의 Integration Services 인스턴스에 연결하려고 하면 "액세스가 거부되었습니다."라는 오류 메시지가 나타납니다. 사용자에게 필요한 DCOM 권한을 부여하면 이 오류 메시지를 방지할 수 있습니다.

Windows Server 2003 또는 Windows XP에서 원격 사용자의 권한을 구성하려면

  1. 사용자가 로컬 Administrators 그룹의 멤버가 아니면 분산 COM 사용자 그룹에 해당 사용자를 추가합니다. 이 작업은 관리 도구 메뉴에서 액세스할 수 있는 컴퓨터 관리 MMC 스냅인에서 수행할 수 있습니다.

  2. 제어판을 열고 관리 도구를 두 번 클릭한 다음 구성 요소 서비스를 두 번 클릭하여 구성 요소 서비스 MMC 스냅인을 시작합니다.

  3. 콘솔의 왼쪽 창에서 구성 요소 서비스 노드를 확장합니다. 컴퓨터 노드를 확장하고 내 컴퓨터를 확장한 다음 DCOM 구성 노드를 클릭합니다.

  4. DCOM 구성 노드를 선택하고 구성할 수 있는 응용 프로그램 목록에서 SQL Server Integration Services 11.0을 선택합니다.

  5. SQL Server Integration Services 11.0을 마우스 오른쪽 단추로 클릭하고 속성을 선택합니다.

  6. SQL Server Integration Services 11.0 속성 대화 상자에서 보안 탭을 선택합니다.

  7. 시작 및 활성화 권한에서 사용자 지정을 선택하고 편집을 클릭하여 시작 권한 대화 상자를 엽니다.

  8. 시작 권한 대화 상자에서 사용자를 추가하거나 삭제하고 적절한 사용자 및 그룹에 적절한 권한을 할당합니다. 로컬 시작, 원격 시작, 로컬 활성화 및 원격 활성화 권한을 할당할 수 있습니다. 시작 권한은 서비스를 시작 및 중지할 수 있는 권한을 부여하거나 거부하고, 활성화 권한은 서비스에 연결할 수 있는 권한을 부여하거나 거부합니다.

  9. 확인을 클릭하여 대화 상자를 닫습니다.

  10. 액세스 권한에서 7-8단계를 반복하여 적절한 사용자 및 그룹에 적절한 권한을 할당합니다.

  11. MMC 스냅인을 닫습니다.

  12. Integration Services 서비스를 다시 시작합니다.


'Install /Setup' 카테고리의 다른 글

SQL 2008:: 삭제 레지스터리  (0) 2010.08.17
Install Tip  (0) 2010.06.04
SQL Server 수동 시작  (1) 2010.01.22
2014. 8. 19. 10:42

SQL Server Replication Error - The specified LSN for repldone log scan occurs before the current start of replication in the log


원본 : 

http://www.mssqltips.com/sqlservertip/3288/sql-server-replication-error--the-specified-lsn-for-repldone-log-scan-occurs-before-the-current-start-of-replication-in-the-log/?utm_source=dailynewsletter&utm_medium=email&utm_content=headline&utm_campaign=20140815



Problem

When working with SQL Server Replication there are times when you may get critical errors related to the Log Reader Agent. One of these errors is "The specified LSN [xxx] for repldone log scan occurs before the current start of replication in the log [xxx]". In this tip I will show how to deal with this type of error.

Solution

I'll give recommendations on how to fix the replication error and here is an actual error message as an example to help us analyze the issue:

The specified LSN {00000023:000000f8:0003} for repldone log scan occurs before the current 
start of replication in the log {00000023:000000f9:0005}. 

Below we can see what this error looks like using the Replication Monitor within SQL Server Management Studio.

Sessions in the SQL Server Replication Monitor

Note: these errors can be found in the Log Reader Agent history and also using SQL Server's Replication Monitor.

The Log Reader Agent is an executable that continuously reads the Transaction Log of the database configured for transactional replication and copies the transactions marked for replication from the Transaction Log into the msrepl_transactions table in the Distribution database.  It is important to know that when the Log Reader Agent starts it first verifies that the last transaction in the msrepl_transactions table in the Distribution database matches the Last Replicated Transaction in the Transaction Log for the published database (that is, the current start of replication). When this does not occur, an error will appear like shown above. Note that the msrepl_transactions table is a critical table and it must not be modified manually, because the Log Reader agent works based on the data in this table. If some entries are deleted or modified incorrectly then we will get many replication errors and one of them is what we are talking about in this tip.

Analyzing the SQL Server Replication Issue

As per our error message for this example, we can execute DBCC OPENTRAN on the published database to find more details about the opened and active replication transaction:

Replicated Transaction Information:
        Oldest distributed LSN     : (35:249:5)
        Oldest non-distributed LSN : (35:251:1)
DBCC execution completed. If DBCC printed error messages, contact your system administrator.

Note that DBCC OPENTRAN gives us the LSN value in Decimal format and we need to convert the LSN from Decimal to Hexadecimal for further analysis.  Below I have converted the values from decimal to hexadecimal.

Oldest distributed LSN : (35:249:5) --> 00000023:000000f9:0005 (must match last row in msrepl_transactions table) 
Oldest non-distributed LSN : (35:251:1) --> 00000023:000000fb:0001 (oldest LSN in the transaction log)

If we analyze the output again,

The specified LSN {00000023:000000f8:0003} for repldone log scan occurs before the current 
start of replication in the log {00000023:000000f9:0005}. 

we can confirm that the LogReader agent is expecting to find LSN 000000f8 of VLF 00000023 which is currently the last entry in the msrepl_transactions table, but this is not the correct Last Replicated Transaction LSN. For SQL Server the correct Last Replicated Transaction LSN is 000000f9.

Note also that the oldest LSN in the Transaction Log is 000000fb of the same VLF 00000023. This means that the Log Reader is trying to start reading on LSN 000000f8 which is before the current start of replication in the log with LSN 000000f9.

You might be thinking about just moving the Log Reader to start at 000000f9 to fix this error?  The problem is that we do not know exactly how many transactions there are from 000000f8 to 000000f9, so if we move the Log Reader Agent pointer forward then we could miss some transactions and create data inconsistency issues.

Fixing the SQL Server Replication Issue

If you decide to move the Log Reader you can do it by using sp_repldone to mark 00000023:000000f9:0005 as the last replicated transaction, so you can skip and move forward. This can be done as shown below.  Here we are using the values from the error message: {00000023:000000f9:0005} or 00000023000000f90005.  We then flush and restart.

exec sp_repldone @xactid = x00000023000000f90005 , @xact_segno = x00000023000000f90005 
GO
-- releasing article cache...       
exec sp_replflush
GO
--Resetting LogReader to retrieve next transaction... 
--LogReader Agent will start up and begin replicating transactions....
exec sp_replrestart

With the above code, the error will disappear and the LogReader agent should continue running without error. If you want to know more about the LogReader Agent, you can review the links at the end of this tip.

Note: You should use sp_repldone only to troubleshoot specific internal replication errors and not use this as a regular way to fix issues.  In the case where you have more continuous errors like above it is better to recreate the replication publication again by dropping and then recreating.

Use sp_repldone with extreme caution because if you use the incorrect LSN you may skip valid transactions from the replication queue and you can create data inconsistency issues at the subscribers.

Fixing Error After a SQL Server Database Restore

Sometimes this type of error can appear after you restore a database that has publications. In this case an error similar to this will appear:

The specified LSN {00000000:00000000:0000} for repldone log scan occurs before the current 
start of replication in the log {00000023:000000f9:0005}.

You can see that Log Reader wants to start reading at LSN {00000000:00000000:0000} and it is because the msrepl_transactions table is empty. In this specific case you also can run sp_repldone to skip all false pending transactions in the msrepl_transactions table and move forward, so the LogReader ignores the incorrect starting point and can continue working.

exec sp_repldone @xactid=NULL, @xact_segno=NULL, @numtrans=0, @time=0, @reset=1

Note that we use @reset=1 to mark all replicated transactions in the Transaction Log as distributed.

'Replication' 카테고리의 다른 글

복제::스키마 옵션  (0) 2012.01.30
복제::숨겨진 저장프로시저 확인  (0) 2011.01.16
복제::LOB DataType 제한  (0) 2010.06.04
복제::#5 구현&삭제 스크립트  (0) 2010.06.04
2013. 9. 13. 10:27

Tempdb 공간 사용 확인

SQL 2005 이상

 

http://www.madeira.co.il/troubleshooting-tempdb-space-usage/ 발췌

 

Tempdb is a critical resource in SQL Server. It is used internally by the database engine for many operations, and it might consume a lot of disk space. In the past two weeks I encountered 3 different scenarios in which tempdb has grown very large, so I decided to write about troubleshooting such scenarios.
Before I describe the methods for troubleshooting tempdb space usage, let’s begin with an overview of the types of objects that consume space in tempdb. There are 3 types of objects stored in tempdb:

  • User Objects
  • Internal Objects
  • Version Stores 

A user object can be a temporary table, a table variable or a table returned by a table-valued function. It can also be a regular table created in the tempdb database. A common misconception is that table variables (@) do not consume space in tempdb, as opposed to temporary tables (#), because they are only stored in memory. This is not true. But there are two important differences between temporary tables and table variables, when it comes to space usage:

1.     Indexes and statistics on temporary tables also consume space in tempdb, while indexes and statistics on table variables don’t. This is simply because you cannot create indexes or statistics on table variables.

2.     The scope of a temporary table is the session in which it has been created, while the scope of a table variable is the batch in which it has been created. This means that a temporary table consumes space in tempdb as long as the session is still open (or until the table is explicitly dropped), while a table variable’s space in tempdb is deallocated as soon as the batch is ended.

Internal objects are created and managed by SQL Server internally. Their data or metadata cannot be accessed. Here are some examples of internal objects in tempdb:

  • Query Intermediate Results for Hash Operations
  • Sort Intermediate Results
  • Contents of LOB Data Types
  • Query Result of a Static Cursor

Unlike user objects, operations on internal objects in tempdb are not logged, since they do not need to be rolled back. But internal objects do consume space in tempdb. Each internal object occupies at least 9
pages (one IAM page and 8 data pages). tempdb can grow substantially due to internal objects when queries that process large amounts of data are executed on the instance, depending on the nature of the queries.

Version stores are used for storing row versions generated by transactions in any database on the instance. The row versions are required by features such as snapshot isolation, after triggers and online index build. Only when row versioning is required, the row versions will be stored in tempdb.
As long as there are row versions to be stored, a new version store is created in tempdb approximately every minute. These version stores are similar to internal objects in many ways. Their data and metadata cannot be accessed, and operations on them are not logged. The difference is, of-course, the data that is stored in them.

When a transaction that needs to store row versions begins, it stores its row versions in the current version store (the one that has been created in the last minute). This transaction will continue to store row versions in the same version store as long as it’s running, even if it will run for 10 minutes. So the size of each version store is determined by the number and duration of transactions that began in the relevant minute, and also by the amount of data modified by those transactions.

Version stores that are not needed anymore are deallocated periodically by a background process. This process deallocates complete version stores, not individual row versions. So, in some cases, it might take a while till some version store is deallocated.
There are two types of version stores. One type is used to store row versions for tables that undergo online index build operations. The second type is used for all other scenarios.

 

 

 

 

-- 실행되는 구문의 temp page allocate
select task.session_id, ses.host_name, ses.login_name,ses.login_time
       ,(task.internal_alloc + task.oject_alloc) -(task.internal_dealloc +task.oject_delloc) as used
       ,task.internal_alloc,task.internal_dealloc,task.oject_alloc,task.oject_delloc
    ,object_name(qt.objectid, qt.dbid) as 'spname'
    ,req.cpu_time,req.logical_reads,req.reads, req.writes  
    ,substring(qt.text,req.statement_start_offset/2,
        (case when req.statement_end_offset = -1
        then len(convert(nvarchar(max), qt.text)) * 2
        else req.statement_end_offset end - req.statement_start_offset)/2) as query
    ,req.statement_start_offset, req.statement_end_offset, req.plan_handle, req.sql_handle
from 
       (
             select session_id, request_id
                    ,sum (internal_objects_alloc_page_count) /128 as internal_alloc
                    ,sum (internal_objects_dealloc_page_count)/128 as internal_dealloc 
                                 ,sum (user_objects_alloc_page_count ) /128 as oject_alloc
                                 ,sum (user_objects_dealloc_page_count ) /128 as oject_delloc
              from sys.dm_db_task_space_usage  with (nolock)
             group by session_id, request_id
    ) as task
inner join  sys.dm_exec_requests as req  with (nolock) 
       on task.session_id = req.session_id and task.request_id = req.request_id
inner join sys.dm_exec_sessions as ses with(nolock) on req.session_id = ses.session_id
cross apply sys.dm_exec_sql_text(sql_handle) as qt  
order by (task.internal_alloc + task.oject_alloc) -(task.internal_dealloc +task.oject_delloc) desc, cpu_time desc

테이블 변수도 tempdb의 공간을 사용한다고 되어 있습니다. 알아 두세요

--tempdb 사용 Size
select sum( unallocated_extent_page_count
          + user_object_reserved_page_count
          + internal_object_reserved_page_count
          + mixed_extent_page_count
          + version_store_reserved_page_count ) /128 as [TotalTempDBSizeInMB]
   , sum(unallocated_extent_page_count) /128 as [FreeTempDBSpaceInMB]
from sys.dm_db_file_space_usage 

select
   db_name(su.database_id) dbname
   ,mf.physical_name
   ,(su.unallocated_extent_page_count
   + su.user_object_reserved_page_count
   + su.internal_object_reserved_page_count
   + su.mixed_extent_page_count
   + su.version_store_reserved_page_count ) /128 as total_size_mb
   ,su.user_object_reserved_page_count / 128 user_object_size_mb
   ,su.internal_object_reserved_page_count /128 as internal_object_size_mb
   ,su.unallocated_extent_page_count/ 128 unallocated_extent_size_mb
from sys.dm_db_file_space_usage as su
   join sys.master_files as mf on mf.database_id = su.database_id and mf.file_id = su.file_id

2013. 3. 13. 22:13

Database Landscape map – February 2013



펌 : http://blogs.the451group.com/information_management/2013/02/04/updated-database-lanscape-map-february-2013/

   Update 된 Database Map 입니다. 






  

'Common Admin' 카테고리의 다른 글

성능 Counter - Disk Transfers/sec (Disk Reads/sec, Disk Writes/sec)  (1) 2015.12.28
TokenAndPermUserStore  (0) 2015.05.18
SQL Server tempdb 복구  (0) 2013.01.08
tablediff 유틸리티  (0) 2012.11.01
2013. 3. 13. 22:04

detach 한 DB를 다른 서버에서 attach 하면 log 백업 바로 가능 한가?


detach 한 DB를 다른 서버에서 attach 하면 log 백업 바로 가능 한가?

답은 가능 하다 이다. 

DB의 마지막 Last_LSN 정보를 정상적으로 알고 처리 한다. 

즉, FULL 백업은 하지 않아도 된다. 

 


backup_start_date backup_finish_date first_lsn last_lsn
2013-03-13 16:29 2013-03-13 16:29 23000000005400000 23000000008200000
2013-03-13 16:29 2013-03-13 16:29 23000000005400000 23000000009000000
2013-03-13 16:32 2013-03-13 16:32 23000000009000000 23000000010700000
2013-03-13 16:33 2013-03-13 16:33 23000000010700000 23000000011200000
다른 서버로 attach      
2013-03-13 16:45 2013-03-13 16:45 23000000011200000 23000000017700000

'Backup/Restory' 카테고리의 다른 글

BACKUP compression  (0) 2010.06.04
Admin::Recovery Model  (0) 2010.06.04
백업성공보고  (0) 2010.06.03
All DB 백업  (0) 2010.06.03
2013. 3. 13. 21:55

월에 두번째/세번째 요일 구하기.


업무를 하다보면  월 두번째, 세번째 특정 요일을 구해야 하는 경우가 있다. 

여기서는 금요일로 하겠다. 


declare @dt_getdate date

set @dt_getdate = '2013-03-13'

select @dt_getdate

 

select DATEADD(wk, DATEDIFF(wk,0, dateadd(dd,6-datepart(day,@dt_getdate),@dt_getdate) ), 4)


위 쿼리는 해당 월의 첫번째 금요일을 알려준다, 

허나 2013년 3월의 경우  3/1일이 금요일 이긴 하지만 주로 처리 되면 2월의 마지막 주가 되서 3/1일이 아닌 

3/8일이 결과가 나온다. 


이럴 경우, 두번째 금요일, 세번째 금요일도 원하는 결과가 아니다. 



그래서 , 구하려고 하는 달의 다음날 첫 일의 금요일을 찾아 거꾸로 찾는 방법을 택했다. 


-- 다음달의 첫번째 날짜를 구하자.

declare @dt_getdate date , @dt_next_month_day date

set @dt_getdate = '2013-02-13'

--set @dt_getdate = dateadd(mm,1,@dt_getdate)

select @dt_getdate

 

set @dt_next_month_day = CONVERT(VARCHAR(10),DATEADD(dd,-(DAY(DATEADD(mm,1,@dt_getdate))-1),DATEADD(mm,1,@dt_getdate)),121)

select @dt_next_month_day

if Datepart(dw, @dt_next_month_day )= 6

   select dateadd(dd,-21,@dt_next_month_day) as '둘째 ', dateadd(dd,-14, @dt_next_month_day) as '셋째 '

else

   select dateadd(dd,-21,dateadd(dd, 6- datepart(dw,@dt_next_month_day ), @dt_next_month_day) ) as '둘째 ',

               dateadd(dd,-14,dateadd(dd, 6- datepart(dw,@dt_next_month_day ), @dt_next_month_day) ) as '셋째 '





2013. 1. 8. 18:26

SQL Server tempdb 복구

tempdb 복구

tempdb SQL Server에서 정렬, GROUP BY를 사용한 집계, 커서 사용, 임시테이블 및 테

이블변수 사용, 일부 JOIN, SORT_IN_TEMPDB 옵션을 사용한 인덱스 생성, 데이터베이스

의 복구 작업 등에서 사용됩니다. 따라서, 손상 시에는 이와 같은 작업들을 진행할 수 없게

됩니다. tempdb의 손상 시 tempdb를 사용하는 작업은 다음과 같이 913 오류를 발생하며

정상적으로 실행되지 않습니다.

 

또한, tempdb size나 경로를 잘못 설정하여 SQL Server가 시작 시 정상 상태가 아닐 경우도 문제가 발생합니다.

 

tempdb가 주의 대상일 경우 재 시작 만으로 복구되기도 하지만 아닐 경우도 있습니다.

이럴 경우 최소 로그 이면서 tempdb skip 하면서 SQL 서버를 수동으로 시작 해야 합니다.

 

1.     명령 프론트를 실행하고 SQL Sever 실행된 경로로 이동 한다.


2.     tempdb 없이 실행하는 추적플래그 –T3609,  자동으로 실행하는 저장 프로시저를 실행하지 않게 하는 플래그 –T4022로 실행합니다.


3.     경우에 따라 최소 옵션인 –f도 포함합니다. , -m : 단일 사용자 모드  

실행하는 명령창은 닫지 말고 그대로 둡니다.


Sqlservr.exe c –f –m –T3609 –T4022

net start MSSQLSERVER  /f /c /m /T 3609 /T4022

 

4.     경로가 잘 못 되었거나, size가 잘 못 되었을 경우 정보를 Alter database  구문을 통해 수정 합니다.


5.     SQL Server 2000 이하의 경우 주의 대상을 정상 상태로 변경 하기 위해서

exec sp_resetstatus ‘tempdb’

명령으로 강제로 복원 할 수도 있습니다.


6.     3번의 실행 명령창에 Ctrl + c를 입력한 다음 “Y” 키를 눌러 SQL Server를 종료후 정상적으로 서비스를 기동 합니다.


7.     tempdb에 문제가 없는지 확인 합니다

'Common Admin' 카테고리의 다른 글

TokenAndPermUserStore  (0) 2015.05.18
Database Landscape map – February 2013  (0) 2013.03.13
tablediff 유틸리티  (0) 2012.11.01
Admin::2000용 TEST DB 생성.  (0) 2011.10.05
2012. 11. 19. 22:59

파티션 테이블 - 문제점, 주의 사항

Partitioned Tables, Indexes and Execution Plans: a Cautionary Tale
23 October 2012
by 

http://www.simple-talk.com/sql/database-administration/partitioned-tables,-indexes-and-execution-plans-a-cautionary-tale/

 

해당 아티클이 파티션 테이블의 이슈 사항을 잘 정리해 주어서 간단 번역함.

 

 

 

 

SQL Server 2005 에서 Partitioned Tables 기능이 나왔을때 우리는 기대를 했다.
많은 데이터를 최소한의 locking 으로 Switch  할 수 있을 것이라고, 그리고 쿼리 성능에도 좋은 영향을 미칠 것이라고..

그러나 무료 제공하는 점심 같은것은 없었다.  파티션 되면서 더 많은 저장 공간이 요구되었다.

Storage space increase

파티션을에 대한 계획을 할 때 꼭, 클러스터된 인덱스 key가 포함되어야 합니다. 불행이도 파티션되어야 하는 key가 고유한 인덱스가 아닐 수도 있습니다. 이 해결책은 클러스터된 인덱스에 포함시키는 방법입니다.


non-clustered index는 clustered index 의 key point를 가지고 있습니다. 파티션 테이블은 일반적으로 대형이며, 클러스터 된 인덱스 키에 새 열을 추가하면, non-clustered index의 모든 레코드가 증가됩니다.

예를 들어  500,000,000 테이블에  clustered index 에 8 byte 날짜 열이 추가된다고 가정해 보면   
500000000 * 8/1024/1024/1024 =  3.75GB 인덱스당 저장공간이 증가됩니다.

 

이 수치는 스토리지 오버헤드의 저장공간은 포함되지 않습니다.
이 증가된 용량은 백업 시간, 복구 시간도 증가하게되며, 색인 유지 보수 비용도 증가합니다.

불행하게도 이 작업에 대한 해결책은 존재하지 않습니다.

데이터가 13개월을 가지고 있고 12개월 데이터를 select 를 매년 초에 해야 한다고 한다면 당연히 날짜 Data가 파티션 key에 존재해야 하며, 파티션이 슬라이등 되어야 합니다. 그러나, 오히려 작은 단위로 데이터를 삭제 하는것이 더 효율 적입니다.

기존 테이블을 파티션 하기 위해 clustered index에 열을 추가하는 것도 쉽지 않습니다.
그나마 대안으로는 indentity 컬럼이 있을 경우 해당 월이 시작되는 값을 알아내어, 그 key로 파티션 하는 것입니다.
저장 공간 뿐 아니라, 실행계획에 대해서도 살펴봐야 합니다.

 

 

 

Suboptimal execution plans

 

파티셔닝을 구현할 때, 물리적 데이터 레이아웃이 변경됨으로 퀴러의 실행 계획이 예기치 못한 결과를 나타낼 수도 있습니다.
그림 참고)

Listing 1 shows the structure of the Orders table, with clustered index.

USE TestDB
GO
CREATE TABLE dbo.Orders
    
(
      
Id INT NOT NULL ,
      
OrderDate DATETIME NOT NULL ,
      
DateModified DATETIME NOT NULL ,
      
Placeholder CHAR(500)
        NOT NULL
        
CONSTRAINT Def_Data_Placeholder DEFAULT 'Placeholder',
    );
GO

CREATE UNIQUE CLUSTERED INDEX IDX_Orders_Id
ON dbo.Orders(ID);
GO

Listing 1: The Orders table structure

 

Listing 2 inserts 524,288 records into the Orders table and creates a non-clustered index.

DECLARE @StartDate DATETIME = '2012-01-01';

WITH    N1 ( C )
          
AS ( SELECT   0
               
UNION ALL
               
SELECT   0
             
)-- 2 rows
,       N2 ( C )
          
AS ( SELECT   0
               
FROM     N1 AS T1
                        
CROSS JOIN N1 AS T2
             
)-- 4 rows
,       N3 ( C )
          
AS ( SELECT   0
               
FROM     N2 AS T1
                        
CROSS JOIN N2 AS T2
             
)-- 16 rows
,       N4 ( C )
          
AS ( SELECT   0
               
FROM     N3 AS T1
                        
CROSS JOIN N3 AS T2
             
)-- 256 rows
,       N5 ( C )
          
AS ( SELECT   0
               
FROM     N4 AS T1
                        
CROSS JOIN N4 AS T2
             
)-- 65,536 rows
,       N6 ( C )
          
AS ( SELECT   0
               
FROM     N5 AS T1
                        
CROSS JOIN N2 AS T2
                        
CROSS JOIN N1 AS T3
             
)-- 524,288 rows
,       IDs ( ID )
          
AS ( SELECT   ROW_NUMBER() OVER ( ORDER BY ( SELECT NULL
                                                     ) )
               
FROM     N6
             
)
    
INSERT  INTO dbo.Orders
            
( ID ,
              
OrderDate ,
              
DateModified
            
)
            
SELECT  ID ,
                    
DATEADD(second, 35 * ID, @StartDate) ,
                    
CASE WHEN ID % 10 = 0
                     
THEN DATEADD(second,
                                  
24 * 60 * 60 * ( ID % 31 ) + 11200 + ID
                                      
% 59 + 35 * ID, @StartDate)
                         
ELSE DATEADD(second, 35 * ID, @StartDate)
                    
END
            FROM    
IDs;
GO  

CREATE UNIQUE NONCLUSTERED INDEX IDX_Orders_DateModified_Id
ON dbo.Orders(DateModified, Id);

 

DECLARE @LastDateModified DATETIME = '2012-06-25';

SELECT TOP 100
        ID 
,
        
OrderDate ,
        
DateModified ,
        
PlaceHolder
FROM    dbo.Orders
WHERE   DateModified > @LastDateModified
ORDER BY DateModified ,
        
Id;

Listing 3: Query that selects the batch of the records

 

Execution plan for un-partitioned Orders table

 

 

Leaf level of the un-partitioned non-clustered index

 

 

DROP INDEX IDX_Orders_DateModified_Id ON dbo.Orders;
DROP INDEX IDX_Orders_Id ON dbo.Orders;
GO

CREATE PARTITION FUNCTION pfOrders(DATETIME)
AS RANGE RIGHT FOR VALUES 
('2012-02-01', '2012-03-01',
'2012-04-01','2012-05-01','2012-06-01',
'2012-07-01','2012-08-01');
GO

CREATE PARTITION SCHEME psOrders 
AS PARTITION pfOrders
ALL TO ([primary]);
GO

CREATE UNIQUE CLUSTERED INDEX IDX_Orders_OrderDate_Id
ON dbo.Orders(OrderDate,ID)
ON psOrders(OrderDate);
GO

CREATE UNIQUE INDEX IDX_Data_DateModified_Id_OrderDate
ON dbo.Orders(DateModified, ID, OrderDate)
ON psOrders(OrderDate);
GO

Listing 4: Table partitioning code

 

 

 

Leaf level of partitioned non-clustered index

 

 

Ideal execution plan Step 1: select 100 records from each partition

 

 

Top N Sort of selected records

 

 

Figure 6 shows how SQL Server actually processes the query.

Actual execution plan for Listing 3, using the partitioned table


 파티션되지 않은 테이블은 top 100 조회하면 처음 나오는 값 기준으로 정렬없이 100개를 가져오니까 비교적 효율적.
 만약 파티셔닝을 구현 한다며 key가 변경되고 정렬되어 있는 것 중에 모두 데이터를 찾아야 한다. 즉, 파티션이 8개 되었다고 한다면 100의 데이터가 있는지 보다 파티션 별로 데이터를 찾아서 정렬한다.
물론, 힌트로 고정할 수도 있지만 예상치 않은 결과 이다.

 

 

 

 


Fixing the problem

그림 참고)

 

 

ECLARE @LastDateModified DATETIME = '2012-06-25';

SELECT TOP 100
        ID 
,
        
OrderDate ,
        
DateModified ,
        
PlaceHolder
FROM    dbo.Orders
WHERE   DateModified > @LastDateModified
        
AND $partition.pfOrders(OrderDate) = 5
ORDER BY DateModified ,
        
ID;

Execution plan when selecting data from the single partition

 


간혹 이상할 경우 많이 사용하는 방법인데 파티션 범위를 확인하고 지정 파티션을 정해 주는 것이다. (파티션 된 테이블을 조건에 해당하는 데이터를 삭제 할 경우 top 10개로.. 등. 이관시 꼭 실행계획을 확인하고 해당 파티션만 찾게 범위를 지정해 줘야 하는 것이 이 이유이다. )
그러려면 파티션의 총 수를 알아야 한다..  ( ys.partition_range_values)

 

DECLARE @LastDateModified DATETIME = '2012-06-25' ,
    
@BoundaryCount INT; 
   
SELECT  @BoundaryCount = MAX(boundary_id) + 1
FROM    sys.partition_functions pf
        JOIN sys.partition_range_values prf
                  ON pf.function_id = prf.function_id
WHERE   pf.name = 'pfOrders';

WITH    Boundaries ( boundary_id )
          
AS ( SELECT   1
               
UNION ALL
               
SELECT   boundary_id + 1
               
FROM     Boundaries
               
WHERE    boundary_id < @BoundaryCount
             
)
    
SELECT  part.ID ,
            
part.OrderDate ,
            
part.DateModified ,
            
$partition.pfOrders(part.OrderDate) AS [Partition Number]
    
FROM    Boundaries b
            
CROSS APPLY ( SELECT TOP 100
                                    ID 
,
                                    
OrderDate ,
                                    
DateModified
                          
FROM      dbo.Orders
                          
WHERE     DateModified > @LastDateModified
                                    
AND $Partition.pfOrders(OrderDate) =
                                                           
b.boundary_id
                          
ORDER BY  DateModified ,
                                    
ID
                        
) part;

Listing 8: Implementation of Step 1 of "Ideal execution plan"

 


Dealing with Cardinality Estimation Errors


 


윗 부분 처럼하면 경계값 에러가 발생할 수 있다. 개선책.
tempdb를 사용한다.

 

CREATE TABLE #T
    
(
      
ID INT NOT NULL
             
PRIMARY KEY
    
);

DECLARE @LastDateModified DATETIME = '2012-06-25' ,
    
@BoundaryCount INT;

SELECT  @BoundaryCount = MAX(boundary_id) + 1
FROM    sys.partition_functions pf
        JOIN sys.partition_range_values prf
                  ON pf.function_id = prf.function_id
WHERE   pf.name = 'pfOrders';

WITH    Boundaries ( boundary_id )
          
AS ( SELECT   1
               
UNION ALL
               
SELECT   boundary_id + 1
               
FROM     Boundaries
               
WHERE    boundary_id < @BoundaryCount
             
)
    
INSERT  INTO #T
            
( ID
            
)
            
SELECT  boundary_id
            
FROM    Boundaries;
    
WITH    Top100 ( ID, OrderDate, DateModified )
          
AS ( SELECT TOP 100
                        part.ID 
,
                        
part.OrderDate ,
                        
part.DateModified
               
FROM     #T b
                        
CROSS APPLY ( SELECT TOP 100
                                                ID 
,
                                                
OrderDate ,
                                                
DateModified
                                      
FROM      dbo.Orders
                                      
WHERE     DateModified >
                                                   
@LastDateModified
                                     
AND $Partition.pfOrders(OrderDate) =
                                                    
b.id
                                      
ORDER BY  DateModified ,
                                                
ID
                                    
) part
               
ORDER BY part.DateModified ,
                        
part.ID
             
)
    
SELECT  d.Id ,
            
d.OrderDate ,
            
d.DateModified ,
            
d.Placeholder
    
FROM    dbo.Orders d
            
JOIN Top100 t ON d.Id = t.Id
                             
AND d.OrderDate = t.OrderDate
    
ORDER BY d.DateModified ,
            
d.ID;

DROP TABLE #T;

Listing 10: Using a temporary table in order to improve cardinality estimation

Using temporary table in order to improve cardinality estimation

Figure 11: Using temporary table in order to improve cardinality estimation

 

 

Hardcoding the number of Partitions
그림 참고)

 

ECLARE @LastDateModified DATETIME = '2012-06-25';

WITH    Boundaries ( boundary_id )
          
AS ( SELECT V.v
               
FROM   ( VALUES ( 1), ( 2), ( 3), ( 4), ( 5), ( 6), ( 7),
                      ( 
8) ) AS V ( v )
             ),
        
Top100 ( ID, OrderDate, DateModified )
          
AS ( SELECT TOP 100
                        part.ID 
,
                        
part.OrderDate ,
                        
part.DateModified
               
FROM     Boundaries b
                        
CROSS APPLY ( SELECT TOP 100
                                                ID 
,
                                                
OrderDate ,
                                                
DateModified
                                      
FROM      dbo.Orders
                                      
WHERE     DateModified >
                                                   
@LastDateModified
                                     
AND $Partition.pfOrders(OrderDate) =
                                                    
b.boundary_id
                                      
ORDER BY  DateModified ,
                                                
ID
                                    
) part
               
ORDER BY part.DateModified ,
                        
part.ID
             
)
    
SELECT  d.Id ,
            
d.OrderDate ,
            
d.DateModified ,
            
d.Placeholder
    
FROM    dbo.Orders d
            
JOIN Top100 t ON d.Id = t.Id
                             
AND d.OrderDate = t.OrderDate
    
ORDER BY d.DateModified ,
            
d.ID;

Listing 11: Hardcode static number of partitions in order to improve cardinality estimation

Hardcode static number of partitions in order to improve cardinality estimation

Figure 12: Hardcode static number of partitions in order to improve cardinality estimation

 


윗 부분 처럼 하면 사용하고자 하는 메모리보다 더 많은 메모리를 사용하게 된다.  ( 일부 파티션에 데이터가 없는 경우)
파티션 수를 하드 코딩 한다. -> 파티션을 추가 되었을 경우 수정해야 한다.    이론.. ㅜㅜ;;

 

 


Summary

 


테이블 파티셔닝은 다양한 디자인과 성능 문제에 도움을 줄 수 있는 훌륭한 기능이지만, 또한 문제 집합을 만 들 수도 있습니다.
clustered index에 파티션 열을 추가하면 저장공간 및 인덱스 유지 보수 비용이 증가합니다.
다른 물리적 데이터 레이아웃 변경이 될 경우 실행 계획이 변화 될 수 있습니다. 이런 부작용이 있다는것을 알고 적용하기 전에 꼭 Test 해봐야 합니다.

 

==> 그래서 처음 설계 부터 파티션 하게 하거나, 자주 조회되지 않은 과거 테이블이나 이력 테이블을 적용하고 있고
또는 키를 변경하기 보다는 기존 key의 범위로 파티션 key를 사용하고 있다, 물론 조회되는 중요 sp들의 조건 절을 확인한다.
기존 테이블을 파티셔닝 하는것은 항상 조심해야 한다.
 

'Peformance Tuning' 카테고리의 다른 글

Index IGNORE_DUP_KEY 옵션 TEST  (1) 2015.09.14
query plan의 실행 옵션 보기  (0) 2012.01.29
Dynamic Management Views  (0) 2012.01.22
Hash Join 제약.  (0) 2011.10.10
2012. 11. 2. 09:58

T-SQL::동적 PIVOT 생성

원문 : http://www.mssqltips.com/sqlservertip/2783/script-to-create-dynamic-pivot-queries-in-sql-server/

 

 

동적으로 PIVOT을 만들 수 있는 방법입니다.

아직도 case 문이 익숙하긴 하지만, 가끔은 오히려 더 복잡해지는 case 문 때문에 PIVOT을 사용해야 한다고 느껴질 때가 있습니다.

 

아직 PIVOT 익숙하지는 않은데 하다보니 컬럼 고정이 되서 불편한 점이 있는데 이 방법으로 사용하면 좋을 것 같네요.

 

PIVOT 은 행 형태의 반환을 열로 만들어 주는 것입니다.

 

아래로 테스트할 데이터를 생성 합니다.


CREATE TABLE dbo.Products
(
  ProductID INT PRIMARY KEY,
  Name      NVARCHAR(255) NOT NULL UNIQUE
  /* other columns */
);


INSERT dbo.Products VALUES
(1, N'foo'),
(2, N'bar'),
(3, N'kin');


CREATE TABLE dbo.OrderDetails
(
  OrderID INT,
  ProductID INT NOT NULL
    FOREIGN KEY REFERENCES dbo.Products(ProductID),
  Quantity INT
  /* other columns */
);


INSERT dbo.OrderDetails VALUES
(1, 1, 1),
(1, 2, 2),
(2, 1, 1),
(3, 3, 1);

 

SELECT p.Name, Quantity = SUM(o.Quantity)
  FROM dbo.Products AS p
  INNER JOIN dbo.OrderDetails AS o
  ON p.ProductID = o.ProductID
  GROUP BY p.Name;

 

결과는 아래 처럼 행으로 나 옵니다.  그러나 열로 표시하고 싶어요. 하면 PIVOT 처리 합니다.

 

 

 

SELECT p.[foo], p.[bar], p.[kin]
FROM
(
  SELECT p.Name, o.Quantity
   FROM dbo.Products AS p
   INNER JOIN dbo.OrderDetails AS o
   ON p.ProductID = o.ProductID
) AS j
PIVOT
(
  SUM(Quantity) FOR Name IN ([foo],[bar],[kin])
) AS p;

 

 

원하는 결과가 나왔습니다. ~

 

 

다른 데이터를 추가 해 보죠.

INSERT dbo.Products SELECT 4, N'blat';
INSERT dbo.OrderDetails SELECT 4,4,5;

 

그리고 나서 다시 윗 쿼리를 실행 해 보면 결과는 동일하게 3개의 데이터의 집계만 나타납니다.

당연한 결과 입니다. 지금 추가된 blat는 보이지 않습니다. PIVOT는 집계해서 보여줄 컬럼을 명시해야 하기 때문입니다.   쿼리를 그럼 고쳐야 하는데 좀 더 쉽게 동적으로 할 수 있게 아래는 도와 줍니다.

 

DECLARE @columns NVARCHAR(MAX), @sql NVARCHAR(MAX);


SET @columns = N'';

SELECT @columns += N', p.' + QUOTENAME(Name)   -- += 는 컬럼을 합쳐서 한 문자로 만들어 주죠.
FROM (SELECT p.Name FROM dbo.Products AS p
  INNER JOIN dbo.OrderDetails AS o
  ON p.ProductID = o.ProductID
 GROUP BY p.Name) AS x;

print @columns


SET @sql = N'
 SELECT ' + STUFF(@columns, 1, 2, '') + '
 FROM
 (
   SELECT p.Name, o.Quantity
    FROM dbo.Products AS p
    INNER JOIN dbo.OrderDetails AS o
    ON p.ProductID = o.ProductID
 ) AS j
 PIVOT
 (
   SUM(Quantity) FOR Name IN ('
   + STUFF(REPLACE(@columns, ', p.[', ',['), 1, 1, '')
   + ')
 ) AS p;';

PRINT @sql;
EXEC sp_executesql @sql;

 

-- @sql의 문은 컬럼을 만들어서 PIVOT 를 생성해 줍니다.

 

/*결과)
 SELECT p.[foo], p.[bar], p.[kin], p.[blat]
 FROM
 (
   SELECT p.Name, o.Quantity
    FROM dbo.Products AS p
    INNER JOIN dbo.OrderDetails AS o
    ON p.ProductID = o.ProductID
 ) AS j
 PIVOT
 (
   SUM(Quantity) FOR Name IN ([foo],[bar],[kin],[blat])
 ) AS p;

*/

 

원하는 결과가 도출.

 

2012. 11. 1. 23:18

tablediff 유틸리티

SQL SERVER 2005 이상

 

 

와 어찌 하다가 이제서야 알게됨.

TABLEDIFF 유틸..   이름에서도 알 수 있 듯이 테이블 차이점 찾기 유틸입니다.

 

복제되어 있는 곳에서 데이터 불일치 문제를 해결하는데 유용하며,

batch file일 이용해서 사용 할 수 있습니다.

 

  • 복제 게시자 역할을 하는 MicrosoftSQL Server 인스턴스에 있는 원본 테이블과 복제 구독자 역할을 하는 하나 이상의 SQL Server 인스턴스에 있는 대상 테이블을 행 단위로 비교할 수 있습니다.

  • 행 개수와 스키마만 비교하여 비교 작업을 빨리 수행할 수 있습니다.

  • 열 수준에서 비교할 수 있습니다.

  • 대상 서버의 불일치를 해결하는 Transact-SQL 스크립트를 생성하여 원본 테이블과 대상 테이블을 일치시킬 수 있습니다.

  • 결과를 출력 파일이나 대상 데이터베이스의 테이블에 기록할 수 있습니다.

 

 

 

 

데이터 형식이 sql_variant 인 열은 지원하지 않는다.

 

도움말 :http://msdn.microsoft.com/ko-kr/library/ms162843(v=SQL.100).aspx

 

  • 사용권한
 비교할 테이블 개체에 대한 select all 권한이 있어야 함.

-o 또는 -f 옵션을 사용하려면 지정된 파일 디렉터리 위치에 대한 쓰기 권한이 있어야 함.

-et 옵션을 사용하려면 db_owner 고정 데이터베이스 역할의 멤버이거나 적어도 구독 데이터베이스에 대한 CREATE TABLE 권한과 대상 서버의 대상 소유자 스키마에 대한 ALTER 권한이 있어야 함

-dt 옵션을 사용하려면 db_owner 고정 데이터베이스 역할의 멤버이거나 적어도 대상 서버의 대상 소유자 스키마에 대한 ALTER 권한이 있어야 함.

  • 사용 법

 

"C:\Program Files\Microsoft SQL Server\90\COM\tablediff.exe" -sourceserver server1 -sourcedatabase test -sourcetable table1 -destinationserver server1 -destinationdatabase test -destinationtable table2

 

 

  • 결과

Microsoft (R) SQL Server Replication Diff Tool
Copyright (C) 1988-2005 Microsoft Corporation. All rights reserved.

User-specified agent parameter values:
-sourceserver server1
-sourcedatabase test
-sourcetable table1
-destinationserver server2
-destinationdatabase test
-destinationtable table2

Table [test].[dbo].[table1] on server1 and Table [test].[dbo].[table2] on server1 have 3 differences.
Err PersonID
Mismatch 1
Dest. Only 2
Src. Only 3
The requested operation took 0.4375 seconds.

2012. 11. 1. 22:17

Function to return a range of dats - 날짜 범위 펑션

http://www.mssqltips.com/sqlservertip/2800/sql-server-function-to-return-a-range-of-dates/

By:    정리

 

SQL SERVER 2005 이상

 

일자별  sum, max 등의 집계 쿼리를 할 때 일자의 범위가 모두 포함되기어 표현되어지기를 원할 때가 있다.

그러나 실제 데이터는 일자 범위에 데이터가 없을 수도 있고 있을 수도 있다. 이럴때 어떻게 해야 할까??

 

물론, row_number 함수를 사용하여 corss join을 사용하면 가능하다. 그러나 이런 쿼리는 복잡하고 원하는 결과를 나타내지 않을 수도 있다.

 

여기서는 테이블 함수를 사용하는 방법으로 해결 합니다.

이 함수는 CTE를 사용하여 반복적으로 날짜를 반환 해 준다. (@Increment 옵션에 따라서)

 

 

DROP FUNCTION [DateRange]
GO
CREATE FUNCTION [dbo].[DateRange]
(     
      @Increment              CHAR(1),   --  일/주/달 여부
      @StartDate              DATETIME,  -- 시작 날짜
      @EndDate                DATETIME   -- 종료 날짜
)
RETURNS  
@SelectedRange    TABLE 
(IndividualDate DATETIME)
AS
BEGIN
	 ;WITH cteRange (DateRange) AS (
            SELECT @StartDate
            UNION ALL
            SELECT 
                  CASE
                        WHEN @Increment = 'd' THEN DATEADD(dd, 1, DateRange)
                        WHEN @Increment = 'w' THEN DATEADD(ww, 1, DateRange)
                        WHEN @Increment = 'm' THEN DATEADD(mm, 1, DateRange)
                  END
            FROM cteRange
            WHERE DateRange <= 
                  CASE
                        WHEN @Increment = 'd' THEN DATEADD(dd, -1, @EndDate)
                        WHEN @Increment = 'w' THEN DATEADD(ww, -1, @EndDate)
                        WHEN @Increment = 'm' THEN DATEADD(mm, -1, @EndDate)
                  END)
          
      INSERT INTO @SelectedRange (IndividualDate)
      SELECT DateRange
      FROM cteRange
      OPTION (MAXRECURSION 3660);
      RETURN
END
GO

실행을 해 보면 아래와 같다.

SELECT IndividualDate FROM DateRange('d', '2012-11-01', '2012-11-10')
SELECT IndividualDate FROM DateRange('w', '2012-11-01', '2012-11-10')
SELECT IndividualDate FROM DateRange('m', '2012-11-01', '2013-01-10')

 

 

 

 

자 그럼 이제 집계하고자 하는 데이터와 조인해서 사용해 보자

임시 테이블을 사용해서 해당 날짜의 제품이 판매된 정보를 입력 하였다. 아래 데이터에서 봤을 경우 11/1 ~ 11/10 사이에

매출은 이틀만 발생 하였다.

 

CREATE TABLE #temp (orderDate DATETIME, orderInfo VARCHAR(50))
INSERT INTO #temp VALUES ('2012-11-01','2 copies of SQL Server 2008')
INSERT INTO #temp VALUES ('2012-11-05','6 copies of SQL Server 2008 R2')
INSERT INTO #temp VALUES ('2012-11-05','10 copies of SQL Server 2012')


SELECT a.IndividualDate , b.orderDate, b.orderInfo
FROM DateRange('d', '2012-11-01', '2012-11-10') as a
LEFT JOIN #temp as b on a.IndividualDate = b.orderDate


결과에서 알 수 있듯이, 매출이 발생하지 않은 일자도 나열 되어 표시된다. 이럴 경우 매출이 없는 일자를 찾기도 쉽다.

 

 

 

'T-SQL' 카테고리의 다른 글

월에 두번째/세번째 요일 구하기.  (0) 2013.03.13
T-SQL::동적 PIVOT 생성  (3) 2012.11.02
T-SQL:: 인덱스 압축 예상 Size  (0) 2012.07.26
TSQL::월별 누적 건수를 구하기.  (0) 2012.01.29
2012. 10. 9. 15:31

시작시 늦어지는 경우 (Slow StartUP)

문제


SQL Server Reporting Services 2008 (SSRS 2008) 시작하고 일정 시간 지나면 점점 늦어지는 현상을 볼 수 있음. 


해결책 


1. SSRS Configuration 의 Recycle Time 변경

2. Memory Pressure


SSRS Configuration 


  - XML 구성 파일이 존재한다.  Recycle Time (재활용 시간 ??) 은 마지막 으로 SSRS가 사용자가 수동으로 다시 시작 되었을 때 기준으로 분 이다. 

Recycle Time이 발생하면 SSRS내의 유휴 자원이 해지 된다. 

기본으로는 720분 또는 12시간으로 구성 되어 있다. 


C:\Program Files\Microsoft SQL Server\MSRS10.MSSQLSERVER\Reporting Services\ReportServer


rsreportserver.config


‹Service›

   …

   …

   ‹RecycleTime›720‹/RecycleTime›

   …

   …


720분으로 셋팅되어 있기 때문에  초기 사용자는 느린 시작으로 연결이 되고 

720분 다시 발생 할 때까지 잘 사용되다가 720분이 되면 다시 유휴 자원이 이루어지어 느린 응답이 발생한다.


재활용 시간은 마지막 날짜를 사용하는 시간 SSRS은 그 참조 점으로 다시 시작했다.

SSRS은 구성 파일에서 재활용 시간을 예약 ,현재 날짜와 시간을 그 다시 시작 시간을 사용한다.

재활용 시간이 720분로 설정되어 있으며 SSRS이 12:00에 720분 후 다음 자정 0시에서 다시 시작하는 경우

 예를 들어, SSRS 자체를 재활용합니다. 이후 720분 후 자정에 0시의 SSRS 다시 재활용되며, 등등. 

SSRS의 재활용은 자원을 확보하기 위해 무기한 계속됩니다.



SSRS 재활용 시간에 가장 좋은 시간은 각 회사의 사용에 따라 달라진다.  그것은 SSRS가 많이 활용되지 않는 경우 몇 가지 분석을 수행하는 것이 가장 좋을 수 있습니다. 

기본적으로는 12 시간마다 재활용,하지만 요청이 처리되는가보고 있으면 더 기간 동안 SSRS를 운영 중 상태로 

유지하기 더 좋을 수 있다.


여러 지사를 가지고 있는데 시간대가 틀리게 사용되어 진다면, 720분은 많이 사용하는 시간에 유휴자원이 되어 초기화 될 수 있다.



SQL Server Reporting Services Memory Pressure


조직의 크기에 따라 SSRS를 독립적으로 사용하지 않고 SQL Server나 다른 응용프로그램과 같은 컴퓨터에 공용으로 사용할 수 있다. 

이때, 다른 응용 프로그램에서 메모리가 필요하면 Windows는 유휴 상태가 된 메모리를 빼앗는 작업을 하는데 그 피해자의 하나로서 SSRS를 결정한다.  

이 문제의 간단한 해결책은 더 많은 RAM을 추가 하는 것이지만, 대부분 가능한 상황이 아니다. 


이 방법을 해결하는 두번 째 방법은 Memory Pressure 관리할 수 있는 SSRS에 최소한 메모리를 조정하는 것이다. 

혹은 예약된 보고서를 작성하는것이다. 


최소한의 메모리를 조정하는 옵션은 "WorkingSetMinimu" 에 대한 SSRS 구성 파일에 추가하는 것이다. 


‹Service›

   …

   …

   ‹WorkingSetMinimum›250000‹/WorkingSetMinimum›

   …

   …




이 작업은 다른 응용 프로그램에 영향을 미칠 수 있음을 주의해야 하며, 메모리 소비수준을 꼭 모니터링 해서 결정해야 한다. 

오히려 이 수치가 높을 경우 응용프로그램 및 서버 자체가 느리거나 응답 하지 않을 수도 있다. 


'Reporting Service' 카테고리의 다른 글

배포 메일링 주소 변경  (0) 2014.09.02
공유 데이터 원본 Overwrite  (0) 2009.08.04
2012. 8. 23. 17:08

권한 조회

SQL Server 2005 이상


1. 서버 수준 권한

--======================
--1. 서버수준의권한
--======================

select  spr.name, spr.type, spr.type_desc,
             spr.default_database_name, spr.default_language_name,
             spm.class_desc, spm.permission_name, spm.state_desc,
             suser_name(srm.role_principal_id) as server_role_name
from sys.server_principals as spr with (nolock)
       inner join sys.server_permissions as spm (nolock) on spm.grantee_principal_id = spr.principal_id
       left join sys.server_role_members as srm with (nolocK) on spr.name = suser_name(srm.member_principal_id)
where spr.type in ('S','U','K', 'G') --C, R
       --and spr.name = ''  -- 유저로하나찾기
order by spr.type,spr.name

-- 유저하나의role member 보기
select suser_name(role_principal_id), suser_name(member_principal_id)
from sys.server_role_members where member_principal_id = suser_id('')

2. DB 수준 권한


use testdb
go

EXEC sp_dbfixedrolepermission;
GO

SELECT * FROM sys.fn_builtin_permissions(DEFAULT)

SELECT * FROM sys.fn_builtin_permissions(DEFAULT) 
    WHERE permission_name = 'SELECT';


-- 사용자 role 고정 role 권한 정보
SELECT DPR.NAME, IS_FIXED_ROLE
	--,DPR.TYPE_DESC 
	--,USER_NAME(DRM.MEMBER_PRINCIPAL_ID) AS USER_NAME
    ,USER_NAME(DRM.ROLE_PRINCIPAL_ID) AS ROLE_NAME
FROM  SYS.DATABASE_PRINCIPALS AS DPR WITH (NOLOCK)
  LEFT JOIN SYS.DATABASE_ROLE_MEMBERS DRM WITH (NOLOCK)  ON DPR.PRINCIPAL_ID = DRM.MEMBER_PRINCIPAL_ID
WHERE DPR.TYPE ='R'
ORDER BY DPR.NAME

-- role별 사용자 정보
SELECT  USER_NAME(DRM.ROLE_PRINCIPAL_ID) AS 'ROLE_NAME'
	,USER_NAME(DRM.MEMBER_PRINCIPAL_ID) AS 'LOGIN'
FROM SYS.DATABASE_ROLE_MEMBERS  AS DRM WITH(NOLOCK) 
	JOIN SYS.DATABASE_PRINCIPALS AS DPM WITH(NOLOCK) ON DRM.ROLE_PRINCIPAL_ID = DPM.PRINCIPAL_ID
WHERE DPM.TYPE ='R'
	AND DPM.IS_FIXED_ROLE = 0
ORDER BY USER_NAME(DRM.ROLE_PRINCIPAL_ID) 

select dpr.name, dpr.type_desc, dpr.default_schema_name,
       user_name(drm.member_principal_id) as user_name,
       user_name(drm.role_principal_id) as role_name
from  sys.database_principals as dpr with (nolock)
       inner join sys.database_role_members drm with (nolock)  on dpr.principal_id = drm.member_principal_id
--where name = ''  -- role이나 유저정보
order by 1,2


-- DB별로 사용자와 ROLE이 어떤 객체의 권한을 가지고 있는지 여부
select dpr.name, dpr.type_desc, dpr.default_schema_name,
	          dpm.class_desc,
	          case  when dpm.major_id = 0 then 'ALL' else obj.name end as object_name,
             dpm.permission_name, dpm.state_desc
from sys.database_principals as dpr with (nolock)
       left join sys.database_permissions as dpm with (nolock) on dpr.principal_id = dpm.grantee_principal_id
       left outer join sys.all_objects as obj with (nolock) on dpm.major_id = obj.object_id
--where dpr.name = '' -- 하나의유저나 혹은 role 이름이나 모두 가능
order by dpr.type, dpr.name



-- 사용자 role member 상세 보기
select dpr.name, dpr.type_desc, dpr.default_schema_name,
       user_name(drm.member_principal_id) as user_name,
       user_name(drm.role_principal_id) as role_name,
	   case  when dpm.major_id = 0 then 'ALL' else OBJECT_NAME(dpm.major_id)  end as object_name,
             dpm.permission_name, dpm.state_desc
from  sys.database_principals as dpr with (nolock)
       left join sys.database_permissions as dpm with (nolock) on dpr.principal_id = dpm.grantee_principal_id 
       inner join sys.database_role_members drm with (nolock)  on dpr.principal_id = drm.member_principal_id
	   --left outer join sys.all_objects as obj with (nolock) on dpm.major_id = obj.object_id
	   -- 안해도 된다.
--where dpr.type = 'R' -- DATABASE_ROLE 
		--and dpr.name = ''		
	/* S = SQL 사용자
	   U = Windows 사용자
       G = Windows 그룹
       A = 응용 프로그램 역할
       R = 데이터베이스 역할
       C = 인증서로 매핑된 사용자
       K = 비대칭 키로 매핑된 사용자 */
ORDER BY dpr.name, 5

3. 권한 제거 Script 생성


-- object 권한 제거
select schema_name(obj.schema_id) as schema1,
	   case  when dpm.major_id = 0 then 'ALL' else OBJECT_NAME(dpm.major_id)  end as object_name,
       dpm.state_desc, 
     ('REVOKE ' + dpm.permission_name COLLATE  Korean_Wansung_CI_AS
     + ' ON OBJECT::' + schema_name(obj.schema_id)+ '.' + OBJECT_NAME(dpm.major_id) + ' FROM '  + dpr.name ) 
from  sys.database_principals as dpr with (nolock)
       inner join sys.database_permissions as dpm with (nolock) on dpr.principal_id = dpm.grantee_principal_id 
       inner join sys.objects  as obj with (nolock) on dpm.major_id = obj.object_id
where  dpr.name  =''   and  dpm.permission_name = 'EXECUTE'

	  

SQL Server 2000 이상


--==========================
-- 2000용
--==========================
select name, createdate, updatedate, dbname from master..syslogins
where  name != 'sa' and name not like '#%' order by name;

exec sp_helpsrvrolemember

exec sp_helprolemember

-- 객체정보
select distinct table_catalog, grantee, table_name , PRIVILEGE_TYPE
     --('REVOKE ' + PRIVILEGE_TYPE + ' ON ' + table_name+ ' FROM '  + grantee ) 
from INFORMATION_SCHEMA.COLUMN_PRIVILEGES

select grantee, table_catalog, table_schema, table_name, privilege_type, is_grantable
from INFORMATION_SCHEMA.TABLE_PRIVILEGES
where grantee = ''

select specific_catalog, specific_name, * from INFORMATION_SCHEMA.PARAMETERS