본문 바로가기

Server Story..../Windows Server

MS SQL 에서 자주 발생 되는 오류

 

 

Administrator 계정의 패스워드를 변경한 뒤 서비스가 시작되지 않는 경우
Administrator 계정의 패스워드를 변경한 뒤 서비스가 시작되지 않는 경우가 종종 발생합니다.
이런 경우 이벤트 뷰어의 시스템 이벤트 로그를 확인합니다.
서비스 로그온 계정의 인증 실패로 인하여 서비스를 시작하지 못했다는 메시지가 기록되어
있는지 확인합니다. 관리 도구에서 서비스를 선택합니다. MSSQLSERVER를 선택하고 더블
클릭하여 서비스의 속성 창을 엽니다.
로그온 탭을 선택하고 [계정 지정]의 암호 칸에 변경된 패스워드를 입력합니다.
SQLSERVERAGENT 서비스뿐만 아니라 서비스의 로그온 계정이 administrator로 지정된 모든 서비스는 위와 같이 패스워드를 변경하고 해당 서비스를 재 시작해야 합니다.
네트워크를 사용한 백업이 실패하는 경우
네트워크 드라이브로의 디스크 백업을 하는 경우 다음과 같은 오류 메시지가 발생하는 경우가 있습니다.

오류 메시지에서 지시하는 대로 SQL Server 오류 로그를 확인하면 운영 체제 오류로 인하여 액세스가 거부되었다는 메시지를 확인할 수 있습니다. 이와 같은 오류는 공유 설정이나 NTFS 파일 시스템의 권한 설정에서 비롯될 수 있습니다. 따라서, SQL Server 서비스의 로그온 계정이 백업 대상 파일 시스템과 공유에 적절한 권한이 있는지 확인합니다. 인증 실패가 원인일 수도 있습니다. 인증이 실패하는 경우에는 해당 파일서버에 동일한 계정의 존재 여부와 패스워드의 일치 여부를 확인해야 합니다. 로그온 계정이 로컬 시스템 계정인 경우에도 네트워크를 통해서 아무런 작업도 할 수 없습니다. 또한, 다음과 같이 네트워크 경로가 잘못 지정되어도 유사한 오류 메시지가 반환됩니다.


이 예제에서는 SQL Server 오류 로그에 네트워크 경로를 찾을 수 없다는 메시지를 확인할 수 있습니다.

다른 서버로 데이터베이스 복구 후 Broken Login 문제
데이터베이스를 다른 서버로 복구한 경우에는 복구한 데이터베이스의 사용자 계정과 연결되는 SQL Server 로그인 계정이 없으므로 동일하게 로그인 계정을 생성해 주어야 합니다.

그러나, 기존의 서버에 있던 사용자 계정과 동일한 이름의 로그인 계정을 생성하더라도 해당 로그인 계정은 해당 데이터베이스에 접속할 수 있는 유효한 사용자 계정이 될 수 없습니다. SQL Server는 서버에 접속할 수 있는 로그인 계정(LoginID)과 각각의 데이터베이스에 접속할 수 있는 데이터베이스 사용자 계정(UserID)으로 2단계에 걸친 인증을 받기 때문에 로그인 계정이 있다고 하더라도 적절한 사용자 계정과 연결이 되지 않은 경우에는 SQL Server에 로그인 하지 못합니다. 연결된 적절한 사용자 계정이 없는 경우에는 Guest 계정을 통해서 해당 데이 터베이스에 연결할 수 있기는 하지만 Guest 계정의 사용은 보안상 취약하므로 사용자 데이터 베이스에서는 사용을 삼가합니다. 2단계에 걸친 인증을 위한 로그인 계정과 각 데이터베이스의 사용자 계정은 로그인 계정을 만들 때 생성된 SID 값으로 연결되어 있습니다.


<다른 서버로 복구된 데이터베이스의 사용자 계정>

위의 그림에서 나타내는 바와 같이, 다른 서버로 복구된 데이터베이스의 사용자 계정에는 기존 서버에서 생성된 로그인 계정의 SID 정보를 sysusers 시스템 테이블에 저장하고 있어서, 이름만 같은 로그인 계정을 생성하더라도 SID가 다르므로 SQL Server는 전혀 별개의 로그인 계정으로 취급합니다.

이와 같은 경우에는 다음과 같은 방법으로 해결할 수 있습니다.


방법① 복구된 데이터베이스의 sysusers 시스템 테이블에서 해당 사용자 계정의 SID 정보를 지정하여 로그인 계정을 생성합니다.




방법② 사용자 계정과 동일한 이름의 로그인 계정을 생성하고 sp_change_users_login 시스템 저장 프로시저를 사용하여 SID 값을 동일하게 변경합니다. 유의할 사항은 이와 같이 조치하면, master.dbo.sysxlogins 시스템 테이블에 저장된 SID값으로 sysusers 시스템 테이블의 SID 컬럼의 값이 변경된다는 점입니다. 따라서, STANDBY 서버의 경우에는, STANDBY 데이터베이스가 읽기 전용 상태이므로 이 방법을 사용할 수 없습니다.


<sp_change_users_login 시스템 저장프로시저를 사용하여 Login 계정의 SID로 사용자 계정의 SID를 변경한 경우>


방법③ 사용자 계정과 동일한 이름의 로그인 계정을 생성하고 master 데이터베이스의 sysxlogins 시스템 테이블의 SID를 복구된 데이터베이스의 sysusers 시스템 테이블의 값으로 JOIN을 사용하여 수정합니다.




방법④ 마이크로소프트 기술 문서에서 제공하는 저장 프로시저를 생성하여 백업한 원본 서버의 SID와 패스워드를 추출하여 로그인을 생성합니다. 먼저 원본 서버의 master 데이터베이스에서 다음 두개의 저장 프로시저를 생성합니다. 이어서 sp_help_revlogin 저장 프로시저를 실행해서 결과창에 나타난 스크립트를 로그인을 옮기고자 하는 서버에서 실행합니다.

[관련 문서]

HOWTO: SQL Server 인스턴스 간의 로그인 및 암호 전송
http://support.microsoft.com/KB/246133

① sp_hexadecimal 저장 프로시저 생성 스크립트
----- Begin Script, Create sp_hexadecimal procedure ----- USE master GO IF OBJECT_ID ('sp_hexadecimal') IS NOT NULL DROP PROCEDURE sp_hexadecimal GO CREATE PROCEDURE sp_hexadecimal @binvalue varbinary(256), @hexvalue varchar(256) OUTPUT AS DECLARE @charvalue varchar(256) DECLARE @i int DECLARE @length int DECLARE @hexstring char(16) SELECT @charvalue = '0x' SELECT @i = 1 SELECT @length = DATALENGTH (@binvalue) SELECT @hexstring = '0123456789ABCDEF' WHILE (@i <= @length) BEGIN DECLARE @tempint int DECLARE @firstint int DECLARE @secondint int SELECT @tempint = CONVERT(int, SUBSTRING(@binvalue,@i,1)) SELECT @firstint = FLOOR(@tempint/16) SELECT @secondint = @tempint - (@firstint*16) SELECT @charvalue = @charvalue + SUBSTRING(@hexstring, @firstint+1, 1) + SUBSTRING(@hexstring, @secondint+1, 1) SELECT @i = @i + 1 END SELECT @hexvalue = @charvalue GO ----- End Script , Create sp_ hexadecimal procedure -----
② sp_help_revlogin 저장 프로시저 생성 스크립트
----- Begin Script, Create sp_help_revlogin procedure ----- USE master GO IF OBJECT_ID ('sp_help_revlogin') IS NOT NULL DROP PROCEDURE sp_help_revlogin GO CREATE PROCEDURE sp_help_revlogin @login_name sysname = NULL AS DECLARE @name sysname DECLARE @xstatus int DECLARE @binpwd varbinary (256) DECLARE @txtpwd sysname DECLARE @tmpstr varchar (256) DECLARE @SID_varbinary varbinary(85) DECLARE @SID_string varchar(256) IF (@login_name IS NULL) DECLARE login_curs CURSOR FOR SELECT sid, name, xstatus, password FROM master..sysxlogins WHERE srvid IS NULL AND name <> 'sa' ELSE DECLARE login_curs CURSOR FOR SELECT sid, name, xstatus, password FROM master..sysxlogins WHERE srvid IS NULL AND name = @login_name OPEN login_curs FETCH NEXT FROM login_curs INTO @SID_varbinary, @name, @xstatus, @binpwd IF (@@fetch_status = -1) BEGIN PRINT 'No login(s) found.' CLOSE login_curs DEALLOCATE login_curs RETURN -1 END SET @tmpstr = '/* sp_help_revlogin script ' PRINT @tmpstr SET @tmpstr = '** Generated ' + CONVERT (varchar, GETDATE()) + ' on ' + @@SERVERNAME + ' */' PRINT @tmpstr PRINT '' PRINT 'DECLARE @pwd sysname' WHILE (@@fetch_status <> -1) BEGIN IF (@@fetch_status <> -2) BEGIN PRINT '' SET @tmpstr = '-- Login: ' + @name PRINT @tmpstr IF (@xstatus & 4) = 4 BEGIN -- NT authenticated account/group IF (@xstatus & 1) = 1 BEGIN -- NT login is denied access SET @tmpstr = 'EXEC master..sp_denylogin ''' + @name + '''' PRINT @tmpstr END ELSE BEGIN -- NT login has access SET @tmpstr = 'EXEC master..sp_grantlogin ''' + @name + '''' PRINT @tmpstr END END ELSE BEGIN -- SQL Server authentication IF (@binpwd IS NOT NULL) BEGIN -- Non-null password EXEC sp_hexadecimal @binpwd, @txtpwd OUT IF (@xstatus & 2048) = 2048 SET @tmpstr = 'SET @pwd = CONVERT (varchar(256), ' + @txtpwd + ')' ELSE SET @tmpstr = 'SET @pwd = CONVERT (varbinary(256), ' + @txtpwd + ')' PRINT @tmpstr EXEC sp_hexadecimal @SID_varbinary,@SID_string OUT SET @tmpstr = 'EXEC master..sp_addlogin ''' + @name + ''', @pwd, @sid = ' + @SID_string + ', @encryptopt = ' END ELSE BEGIN -- Null password EXEC sp_hexadecimal @SID_varbinary,@SID_string OUT SET @tmpstr = 'EXEC master..sp_addlogin ''' + @name + ''', NULL, @sid = ' + @SID_string + ', @encryptopt = ' END IF (@xstatus & 2048) = 2048 -- login upgraded from 6.5 SET @tmpstr = @tmpstr + '''skip_encryption_old''' ELSE SET @tmpstr = @tmpstr + '''skip_encryption''' PRINT @tmpstr END END FETCH NEXT FROM login_curs INTO @SID_varbinary, @name, @xstatus, @binpwd END CLOSE login_curs DEALLOCATE login_curs RETURN 0 GO ----- End Script , Create sp_help_revlogin procedure -----
③ 원본 서버에서 sp_help_revlogin 저장 프로시저를 실행하여 다음과 같이 기존의 SID값과 패스워드가 동일한 로그인을 생성할 수 있는 스크립트를 작성하여 동일한 로그인을 생성 하고자 하는 서버에서 실행합니다.

윈도우즈 2003 서버에서 SQL Server 성능 카운터가 로그에 기록되지 않는 경우
윈도우즈 2003 서버에서 운영되는 SQL Server 성능 모니터링을 위해서 시스템 모니터의 성능 로그를 수집하는 경우 디폴트 상태에서는 SQL Server의 성능 카운터가 기록되지 않습니다. 이런 문제가 발생하는 원인은 윈도우즈 2003 서버의 [Performance Logs and Alerts] 서비스의 로그온 계정이 기본적으로 다음과 같이 [NT Authority\NetworkService] 계정으로 지정되어 있기 때문입니다.



[NT Authority\NetworkService] 계정은 SQL Server의 카운터 로그를 시스템 모니터의 카운터 로그 파일(.blg)에 기록할 수 있는 권한을 가지고 있지 않습니다. 따라서, [Performance Logs and Alerts] 서비스의 로그온 계정을 그림①번의 [로컬 시스템 계정]을 선택하여 변경한 뒤 사용합니다.

[참조 문서]
http://support.microsoft.com/default.aspx?scid=kb;en-us;839506>

SQL Server 성능 카운터가 시스템 모니터에서 보이지 않는 경우
자주 발생하는 경우는 아니지만 시스템 모니터에서 SQL Server 성능 카운터가 보이지 않거나 다음과 같이 성능 카운터 전체가 보이지 않는 경우가 있습니다.



이런 경우 성능 카운터와 관련된 레지스트리 정보나 파일이 손상된 것이 원인인 경우가 많습니다. 다음의 순서로 확인합니다.

① SQL Server 성능 카운터가 보이지 않는 경우 관련 파일을 점검합니다.

“C:\Program Files\Microsoft SQL Server\MSSQL\Binn”폴더의 sqlctr.ini 와 sqlctr80.dll 파일을 점검합니다. 이 파일이 손상된 경우 현재 설치된 SQL Server의 빌드 번호와 동일한 빌드 번호의 SQL Server 프로그램 CD나 서비스 팩 파일에서 복사합니다. sqlctr.ini 파일은 x86\binn 폴더에 sqlctr80.dll 파일은 x86\system 폴더에 있습니다. 그리고 sqlctr.ini 파일이 있는“C:\Program Files\Microsoft SQL Server\MSSQL\Binn”폴더로 이동하여 다음과 같이 lodctr 명령으로 성능 카운터를 로드하고 컴퓨터를 재시작 합니다.



② 윈도우즈 서버의 성능 카운터가 보이지 않는 경우 관련 파일을 점검합니다.

Winnt\system32 또는 Windows\system32 폴더의 Perfc009.dat, Perfh009.dat 파일과 Perfc012.dat, Perfh012.dat 파일을 점검합니다. Perfc009.dat 파일이 손상된 경우에는 처음 그림과 같이 모든 성능 카운터가 나타나지 않게 됩니다. 009나 012는 해당 언어를 표시하며 012로 표시된 파일이 손상되면 성능 카운터 설명 등의 한글 표시가 되지 않습니다. 이와 같은 파일이 삭제되었거나 손상된 경우는 윈도우즈 서버 프로그램 CD의 i386 폴더의 Perfc009.da_, Perfh009.da_, Perfc012.da_, Perfh012.da_ 파일들을 다음과 같이 EXPAND 명령으로 압축을 풀어서 교체합니다.



③ 레지스트리 정보를 점검합니다.

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Perflib에 009와 012 서브키가 존재하는지 확인합니다.
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services 에서 각 서비스 별로 해당 성능관련 서브키가 존재하는지 확인합니다.


<HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Perflib>


<HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MSSQLSERVER>
해당 서브키가 없거나 손상된 경우 시스템 상태 백업이나 레지스트리 편집기에서 내보내기 메뉴로 백업한 파일을 통해서 복원합니다. 시스템 상태 복원이나 레지스트리의 수정은 심각한 문제가 발생할 수 있으며 문제를 해결하기 위해 운영 체제를 다시 설치해야 할 수 있으므로 주의하여 수행해야 합니다.