(MSSQL) BACKUP LOG cannot be performed because there is no current database backup

IT/Programming/MSSQL 2016. 4. 27. 12:25

MSSQL 에서 백업 미디어를 데이터베이스로 복원하려할 때 아래와 같은 오류가 발생한다면, 해당 데이터베이스에 단 한번도 로그를 백업하지 않아 발생하는 현상이다. 임의로 로그를 백업시키고 시도해보면 제대로 복원이 이루어진다.

 

BACKUP LOG cannot be performed because there is no current database backup

 

아래의 같이 명령을 실행한 후 복원을 다시 시도해보자.

 

BACKUP DATABASE [데이터베이스명] TO DISK = N'D:\DB.bak'
GO


BACKUP LOG [데이터베이스명] TO DISK = N'D:\DB.bak'
GO

 

 

 

설정

트랙백

댓글

(MSSQL) 이번 주 월요일, 다음 주 월요일 구하기

IT/Programming/MSSQL 2016. 1. 18. 12:30

 DECLARE @now datetime;
 DECLARE @next_week_monday_00 datetime
 DECLARE @this_week_monday_00 datetime

 SET @now = '2016-01-17'
 IF 1 = DATEPART(WEEKDAY, @now)
  SET @this_week_monday_00 = DATEADD(DAY, DATEDIFF(DAY, 0, DATEADD(DAY, -6, @now)), 0)
 ELSE
  SET @this_week_monday_00 = DATEADD(DAY, DATEDIFF(DAY, 0, DATEADD(DAY, DATEPART(WEEKDAY, @now) * -1 + 2, @now)), 0)
 SET @next_week_monday_00 = DATEADD(DAY, 7, @this_week_monday_00) 

 

설정

트랙백

댓글

(MSSQL) 모든 테이블 인덱스 재생성 쿼리

IT/Programming/MSSQL 2016. 1. 17. 18:45

DECLARE @i int, @sql varchar(1000)
DECLARE @tablename varchar(1000),@ownerName  varchar(1000)

SET @i = 1

DECLARE DB_Cursor CURSOR FOR
 SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES  WHERE TABLE_TYPE = 'BASE TABLE' ORDER BY TABLE_SCHEMA, TABLE_NAME
OPEN DB_Cursor

FETCH NEXT FROM DB_Cursor
INTO @ownerName, @tablename
WHILE @@FETCH_STATUS = 0
BEGIN

 SET @sql = 'ALTER INDEX ALL ON ' + @ownerName + '.' + @tablename + ' REBUILD WITH (PAD_INDEX = ON, FILLFACTOR = 90) '
 EXEC (@sql)

 PRINT CONVERT(VARCHAR, @i) + '__' + @ownerName + '.' + @tablename + '............ OK'
 SET @i = @i + 1

 FETCH NEXT FROM DB_Cursor
 INTO @ownerName, @tablename

END

CLOSE DB_Cursor
DEALLOCATE DB_Cursor

 

출처: http://text.zpne.net/6

설정

트랙백

댓글

(MSSQL) 현재 데이터베이스에 사용자 그룹 또는 역할 이(가) 이미 있습니다

IT/Programming/MSSQL 2015. 6. 25. 17:40

보통 이러한 오류는 MSSQL 에서 데이터베이스 파일(mdf, ldf) 를 연결/복원을 하고, 명령을 실행하려 할 때 발생한다.

 

데이터베이스를 연결/복원한 후, 데이터베이스를 올바르게 구동시키기 위해 기존 데이터베이스에서 사용하던 유저를 생성하여 명령을 실행시켰을 때

 

현재 데이터베이스에 사용자 그룹 또는 역할  <유저 이름> 이(가) 이미 있습니다

 

와 같은 오류가 발생한다. 유저가 이미 있다니? 이게 무슨 말일까?

 

이는 기존의 데이터베이스에 존재하는 유저의 이름과 새로 생성한 유저의 이름은 같지만 서로의 고유 번호인 SID(보안 ID)가 서로 달라서 생기는 문제다. 이름은 같지만 보안 ID가 달라 다른 유저로 인식하는데, 새로 생성한 유저로 명령을 실행하려니 기존에 똑같은 이름의 유저가 존재하여 위와 같은 오류를 발생시키는 것이다.

 

이를 해결하기 위해서는 유저를 매핑하는 프로시저인 sp_change_users_login 프로시저 또는 ALTER USER 명령을 사용하면 된다. 이 명령을 사용하게 되면 기존 데이터베이스 사용자를 SQL Server 로그인에 매핑하게 된다.

 

기존 데이터베이스에 존재하는 유저의 ID가 TestUser, 데이터베이스 세팅을 위해서 새로 생성한 유저의 ID도 TestUser일 경우 쿼리는 다음과 같다.

EXEC sp_change_users_login 'update_one', 'TestUser', 'TestUser'

또는

ALTER USER TestUser WITH LOGIN = TestUser

 

물론, 기존의 데이터베이스가 여러개 존재할 경우, 기존의 각 데이터베이스에 등록된 유저 정보를 모두 매핑해야하므로 각 데이터베이스마다 모두 위의 명령을 한차례씩 실행시켜주어야 한다.

 

MSDN에 따르면, SQL Server 2014 까지는 sp_change_users_login 프로시저가 지원되고 있지만 이 프로시저는 언젠가 삭제될 예정이라고 한다. 이 명령을 사용하고 있는 응용 프로그램이 있다면 위에 기술한 ALTER USER 명령을 사용하는 것을 권고한다.

 

참고 : https://msdn.microsoft.com/ko-kr/library/ms174378(v=sql.120).aspx

 

설정

트랙백

댓글

유용한 DMV

IT/Programming/MSSQL 2015. 5. 12. 10:42
   -- Top SPs By Execution Count (SQL 2008)
    SELECT TOP (100) p.name AS 'SP Name', qs.execution_count,
    ISNULL(qs.execution_count/DATEDIFF(Second, qs.cached_time, GetDate()), 0) AS 'Calls/Second',
    qs.total_worker_time/qs.execution_count AS 'AvgWorkerTime', qs.total_worker_time AS 'TotalWorkerTime', 
    qs.total_elapsed_time, qs.total_elapsed_time/qs.execution_count AS 'avg_elapsed_time', qs.last_elapsed_time,
    qs.cached_time, qs.last_execution_time
    FROM sys.procedures AS p
    INNER JOIN sys.dm_exec_procedure_stats AS qs
    ON p.object_id = qs.object_id
    ORDER BY qs.execution_count DESC;
   
    -- Top SPs By Execution Count (SQL 2005)
    SELECT TOP (100) qt.text AS 'SP Name', qs.execution_count AS 'Execution Count', 
    qs.execution_count/DATEDIFF(Second, qs.creation_time, GetDate()) AS 'Calls/Second',
    qs.total_worker_time/qs.execution_count AS 'AvgWorkerTime',
    qs.total_worker_time AS 'TotalWorkerTime',
    qs.total_elapsed_time/qs.execution_count AS 'AvgElapsedTime',
    qs.max_logical_reads, qs.max_logical_writes, qs.total_physical_reads,
    DATEDIFF(Minute, qs.creation_time, GetDate()) AS 'Age in Cache'
    FROM sys.dm_exec_query_stats AS qs
    CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt
    WHERE qt.dbid = db_id() -- Filter by current database
    ORDER BY qs.execution_count DESC

 

 

설정

트랙백

댓글

로그 테이블 설계 원칙

IT/Programming/MSSQL 2015. 2. 25. 19:55

1년정도 지표처리 작업을 해오면서 느꼈던 나만의 로그 테이블 설계 원칙을 작성해본다.

 

1. LogDB에는 2차 가공 데이터는 없어야 한다.

-> DB에 박혀있는 값을 가공하여 DB에 INSERT 하는 것은 삼가야 한다.

-> 추가적인 가공이 필요한 데이터는 Tool 에서 진행하도록 한다.

 

2. 알아보기 쉽게. 간단하게 작성되어야 한다. 그렇지만 운영상에 필요한 정보는 반드시 존재하여야 한다.

-> 개발자가 LogDB를 SELECT 하는 것 만으로도 해당 로그가 어떠한 이유에서 발생한 것인지를 명확하게 알 수 있어야 한다.

-> 개발자가 생각하기에 비교적 필요없는 정보라고 할지라도, 운영상에 필요한 정보라면 반드시 남기도록 한다.

-> 특히나, 운영상에 필요한 정보가 Tool 에서 자주 요청되는 정보의 성격이라면 타협의 여지 없이 DB에 남겨야한다.

 

3. 공통 로그 포맷은 죄악이다.

-> 개발의 편의성을 위하여 모든 로그에 대해서 공통된 포맷을 사용하는 경우가 왕왕있다. 공통된 로그 포맷으로도 완벽히 제어할 수 있다면 문제는 없지만, 보통 그렇지 않다. 필요한 칼럼이 있으면 억지로 구겨넣지 말고 늘려야 한다.

 

4. 하나의 칼럼에는 하나의 정보만을 담는다.

-> 로그 시스템이 DW 이상급의 크기를 갖추지 않는다는 전제 하에, 하나의 칼럼에는 하나의 정보만을 담는 것이 좋다.

-> 개발자가 SELECT 하였을 때 WHERE 절로 바로 검색가능한 로그 포맷이어야 한다.

 

설정

트랙백

댓글