이 두 SQL Server 롤백은 어떻게 다릅니 까?


13

SQL Server 2008 R2에서이 두 롤백은 어떻게 다른가요?

  1. ALTER몇 분 동안 명령문을 실행 한 다음 'Execceling Executing'을 누르십시오. 완전히 롤백하는 데 몇 분이 걸립니다.

  2. 동일한 ALTER명령문을 실행 하지만 LDF파일이 성공적으로 완료되기에 충분히 크지 않은지 확인하십시오 . 한때 LDF제한이 충족되고 더 '자동 증가'가 허용되지 않습니다, 쿼리 실행이 즉시 중단 (또는 롤백이 발생)이 오류 메시지와 함께 :

The statement has been terminated.
Msg 9002, Level 17, State 4, Line 1
The transaction log for database 'SampleDB' is full. 
To find out why space in the log cannot be reused, see the 
log_reuse_wait_desc column in sys.databases

다음 두 가지 점에서이 두 가지는 어떻게 다른가요?

  1. 두 번째 '롤백'이 순간적인 이유는 무엇입니까? 롤백이라고 할 수 있는지 확실하지 않습니다. 내 생각에, 실행이 진행됨에 따라 트랜잭션 로그가 작성되고 작업을 완전히 완료하기에 충분한 공간이 없다는 것을 알게되면 커밋없이 '종료'메시지로 중지됩니다.

  2. 첫 번째 롤백에 너무 많은 시간이 걸리면 어떻게됩니까 (롤백 단일 스레드)?
    2.1. SQL Server가 LDF파일 에서 작성된 항목으로 돌아가서 실행 취소 합니까?
    2.2. LDF파일 크기 (에서 롤백의 끝에서 작아진다 DBCC SQLPERF(LOGSPACE))

  3. 한 가지 추가 질문 : 두 번째 시나리오에서 SQL Server는 LDF파일을 매우 빨리 사용하기 시작 합니다. 필자의 경우 처음 몇 분 (4 분 미만) 동안 사용량이 18 %에서 90 %로 증가했습니다. 그러나 99 %에 도달하면 추가로 8 분 동안 머무르고 사용량은 99.1 %에서 99.8 % 사이로 변동합니다. 오류가 발생하기 전에 몇 번 증가 (99.8 %) 및 감소 (99.2 %) 및 다시 증가 (99.7 %) 및 감소 (99.5 %)됩니다. 무대 뒤에서 무슨 일이 일어나고 있습니까?

이것을 더 설명 할 수있는 모든 MSDN 링크가 높이 평가됩니다.

Ali Razeghi 제안에서 perfmon을 추가하고 있습니다. Disk Bytes/sec

시나리오 1 :

시나리오 1

시나리오 2 :

시나리오 2


간단한 설명 : 파일 크기! = 파일 내에서 사용 된 공간.
Aaron Bertrand

@Aaron 그렇습니다. DBCC SQLPERF (LOGSPACE)를 사용하여 사용량을 측정했습니다. 파일 크기를 10GB로 제한했기 때문에 LDF 파일은 전체 기간 동안 동일하게 유지되었습니다. 내부 사용법은 다양합니다.
ToC

1
롤백이 완료된 오류가보고되므로 두 번째 롤백 순간적으로 나타납니다 . 이것은 LDF 사용량이 거의 일정하게 유지되는 3 분의 8 분입니다.
mustaccio

@mustaccio 나는 당신에게 동의하지만 유물은 다른 방향을 가리키고 있습니다. 실제로 롤백이 발생한 경우 로그 파일 사용량은 더 작은 숫자로 다시 되돌려 져야합니다. 오류 메시지가 표시 될 때 99.3 %를 유지하지 마십시오.
ToC

1
롤백에는 로그 공간이 필요합니다. 롤백 중에 로그가 가득 차면 DB가 의심됩니다. 더 이상 건드리지 않습니다. 이것은 즉각적인 롤백처럼 보이지만 사용 가능한 디스크 공간이있을 때 데이터베이스를 온라인으로 되돌릴 수있을 때까지 롤백이 지연되었습니다.; 또한 로그가 가득 차면 SQL Server는 IO 활동의 급증을 설명 할 수있는 검사 점을 통해 공간을 확보하려고 할 수 있습니다.
usr

답변:


1

위에 표시된 것처럼 더 많은 테스트를 실행 한 후 계산 된 결론에 도달했습니다. 여기에 모두 블로그 게시물 로 요약 했지만 일부 내용은이 게시물에 복사하여 사후에 게시하겠습니다.

추측 (일부 테스트 기준)

현재로서는 왜 그런지에 대한 명확한 설명이 없습니다. 그러나 다음은 테스트 중에 수집 된 인공물을 기반으로 한 나의 추정입니다.

롤백은 시나리오 에서 모두 발생합니다 . 하나는 명시적인 롤백 (사용자가 취소 버튼을 눌렀 음)이고 다른 하나는 암시 적입니다 (Sql 서버가 내부적으로 결정을 내림).

두 시나리오에서 로그 파일로 이동하는 트래픽은 일관됩니다. 아래 이미지를보십시오 :

시나리오 1 :

시나리오 1 :

시나리오 2 :

시나리오 2

  • 이 사고 방식을 강화한 한 가지 인공물은 두 시나리오 모두에서 Sql Trace를 캡처하는 것입니다.

    • 시나리오 1은 '취소'를 누르면 자명합니다. 롤백됩니다.
    • 시나리오 2에서는 '롤백'을 암시 적으로 수행 한 후 오류 메시지가 표시됩니다. Sql Trace에서 메시지가 화면에 표시되기 오래 전에 "데이터베이스 'SampleDB'에 대한 트랜잭션 로그가 가득 찼습니다"라는 오류 메시지가 표시됩니다. 따라서 두 시나리오에서 롤백이 발생하지만 롤백을 성공적으로 완료 한 후 시나리오 2가 표시된다는 오류 메시지가 표시됩니다.
  • 시나리오 2가 진행 될수록 시간이 오래 걸리는 것처럼 보이므로 롤백 시간이 더 오래 걸립니다.

설명 할 수없는 행동 :

  • 로그 파일 사용법이 왜 그렇게 다양합니까?
    • 90 %까지 증가한 다음 85 %까지 감소한 다음 최대 99 %까지 증가하여 오랫동안이 위치를 이동합니다. 99.2 %, 99.8 %, 99.1 %, 99.7 %와 같이 여러 번 위아래로 움직이는 것을 봅니다. 왜 이런 일이 발생합니까?
    • 가능한 한 가지 설명은 몇 분마다 로그 파일을 정리하는 백그라운드 프로세스 (Log Flush와 같은 것)가있을 수 있다는 것입니다. 그리고 시작될 때마다 일부 항목이 지워져 사용 가능한 여유 공간이 늘어납니다.

더 나은 방식으로이 동작을 설명하는 데 도움이되는 아이디어는 언제든지 환영합니다.


2
Paul Randal을 확인한 결과, 올바른 결론에 도달 했음을 확인했습니다 . 두 경우 모두 롤백이 동일합니다.
Paul White 9

0

나는 다음 실험을 시도하고 비슷한 결과를 얻었습니다. 두 경우 모두 fn_dblog ()는 롤백이 발생하고 시나리오 1에서보다 시나리오 1에서 더 빨리 발생하는 것으로 보입니다.

그건 그렇고, MDF와 LDF를 동일한 단일 외부 (USB 2.0) 디스크에 배치했습니다.

필자의 초기 결론은이 경우 롤백 작동에 차이가 없으며 아마도 명백한 속도 차이는 I / O 하위 시스템과 관련이 있다는 것입니다. 그것은 현재 나의 작업 가설입니다.

시나리오 1 :

  • 1MB에서 시작하고 4MB 청크 단위로 커지며 최대 크기가 100MB 인 로그 파일로 데이터베이스를 작성하십시오.
  • 명시 적 트랜잭션을 열고 10 초 동안 실행 한 다음 SSMS 내에서 수동으로 취소하십시오.
  • fn_dblog () 수와 로그 예약 크기를보고 DBCC SQLPERF (LOGSPACE)를 확인하십시오.

시나리오 2 :

  • 1MB에서 시작하고 4MB 청크 단위로 커지며 최대 크기가 100MB 인 로그 파일로 데이터베이스를 작성하십시오.
  • 명시 적 트랜잭션을 열고 로그가 가득 찼을 때까지 실행하십시오. 오류가 표시됩니다.
  • fn_dblog () 수와 로그 예약 크기를보고 DBCC SQLPERF (LOGSPACE)를 확인하십시오.

성능 모니터 결과 :

시나리오 1 : *** 시나리오 1 ***

시나리오 2 : *** 시나리오 2 ***

암호:

사용 [마스터];
가다

IF DATABASEPROPERTYEX (N'SampleDB ', N'Version')> 0 인 경우
시작
    ALTER DATABASE [SampleDB] SET SINGLE_USER
        롤백 즉시;
    DROP DATABASE [SampleDB];
종료;
가다

기본 데이터베이스 생성 [SampleDB] 
( 
      이름 = N'SampleDB '
    , FILENAME = N'E : \ data \ SampleDB.mdf ' 
    , 크기 = 3MB 
    , FILEGROWTH = 1MB 
)
로그온 
( 
      NAME = N'SampleDB_log '
    , FILENAME = N'E : \ data \ SampleDB_log.ldf '
    , 크기 = 1MB 
    , MAXSIZE = 100MB 
    , FILEGROWTH = 4MB 
);
가다

사용 [SampleDB];
가다

-테이블 추가
테이블 만들기 dbo.test
(
    c1 CHAR (8000) NOT NULL DEFAULT REPLICATE ( 'a', 8000)
) ON [1 차];
가다

-의사 단순 복구 모델이 아닌지 확인
백업 데이터베이스 SampleDB
디스크 = 'NUL';
가다

-로그 파일 백업
백업 로그 SampleDB
디스크 = 'NUL';
가다

-사용 된 로그 공간을 체크
DBCC SQLPERF (로그 스페이스);
가다

-fn_dblog ()로 몇 개의 레코드를 볼 수 있습니까?
SELECT * FROM fn_dblog (NULL, NULL); -내 경우에는 약 9

/ *************************************
             시나리오 1
************************************* /
-새 거래를 연 다음 롤백
거래 시작

    dbo.test에 삽입 기본 값;
    GO 10000-10 초 동안 실행 한 다음 SSMS 쿼리 창에서 취소를 누르십시오.

    -거래 취소
    -완료하는 데 몇 초가 걸립니다


-취소가 이미 처리했기 때문에 트랜잭션을 롤백 할 필요가 없습니다.
-- 그냥 시도 해 봐. 이 오류가 발생합니다
-메시지 3903, 수준 16, 상태 1, 줄 1
-ROLLBACK TRANSACTION 요청에 해당하는 BEGIN TRANSACTION이 없습니다.
롤백 거래;

-사용 된 로그 공간은 무엇입니까? 100 % 이상
DBCC SQLPERF (로그 스페이스);
가다

-fn_dblog ()로 몇 개의 레코드를 볼 수 있습니까?
고르다 * 
Ffn fn_dblog (NULL, NULL); -내 경우에는 약 91,926

-fn_dblog ()로 표시된 총 로그 예약?
[총 로그 예약]으로 SUM ([로그 예약]) 선택
Ffn fn_dblog (NULL, NULL); -약 88.72MB


/ *************************************
             시나리오 2
************************************* /
-DB를 날려 버리고 다시 시작하십시오.
사용 [마스터];
가다

IF DATABASEPROPERTYEX (N'SampleDB ', N'Version')> 0 인 경우
시작
    ALTER DATABASE [SampleDB] SET SINGLE_USER
        롤백 즉시;
    DROP DATABASE [SampleDB];
종료;
가다

기본 데이터베이스 생성 [SampleDB] 
( 
      이름 = N'SampleDB '
    , FILENAME = N'E : \ data \ SampleDB.mdf ' 
    , 크기 = 3MB 
    , FILEGROWTH = 1MB 
)
로그온 
( 
      NAME = N'SampleDB_log '
    , FILENAME = N'E : \ data \ SampleDB_log.ldf '
    , 크기 = 1MB 
    , MAXSIZE = 100MB 
    , FILEGROWTH = 4MB 
);
가다

사용 [SampleDB];
가다

-테이블 추가
테이블 만들기 dbo.test
(
    c1 CHAR (8000) NOT NULL DEFAULT REPLICATE ( 'a', 8000)
) ON [1 차];
가다

-의사 단순 복구 모델이 아닌지 확인
백업 데이터베이스 SampleDB
디스크 = 'NUL';
가다

-로그 파일 백업
백업 로그 SampleDB
디스크 = 'NUL';
가다

이제 트랜잭션 내에서 로그 파일을 정리해 봅시다
거래 시작
    dbo.test에 삽입 기본 값;
    GO 10000

-롤백이 발생하지 않습니다. 시도 해봐. 오류가 발생합니다.
-메시지 3903, 수준 16, 상태 1, 줄 1
-ROLLBACK TRANSACTION 요청에 해당하는 BEGIN TRANSACTION이 없습니다.
롤백 거래;

-로그 파일이 100 % 가득 찼습니까? 
DBCC SQLPERF (로그 스페이스);

-fn_dblog ()로 몇 개의 레코드를 볼 수 있습니까?
고르다 * 
Ffn fn_dblog (NULL, NULL); -내 경우에는 약 91,926
가다

-fn_dblog ()로 표시된 총 로그 예약?
[총 로그 예약]으로 SUM ([로그 예약]) 선택
Ffn fn_dblog (NULL, NULL); -88.72MB
가다

자세한 테스트에 감사드립니다. 더 많은 테스트를 실행 한 후에도 비슷한 결론에 도달하여 블로그 게시물을 작성했습니다 . 나를 위해 시나리오 2에서 수행 된 작업량이 Sqlario가 롤백의 필요성을 시나리오 1 이상으로 인식하기 전에 시나리오 2에서 롤백하는 데 시간이 오래 걸립니다.
ToC
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.