MySQL 8.0.30 Dynamic InnoDB Redo Log

Share

Last Updated on 5월 12, 2024 by Jade(정현호)

안녕하세요 
이번 포스팅에서는 MySQL 8.0.30에서 추가된 온라인 중에 Redo Log 크기 변경에 관련된 "Dynamic InnoDB Redo Log" 와 추가로 변경된 점에 대해서 살펴보려고 합니다.     

Dynamic InnoDB Redo Log

MySQL 8.0.30 버전 부터는 Dynamic InnoDB Redo Log 라는 기능이 추가되었으며, 사용자는 MySQL 서버의 재시작 없이 Online 중에 즉시 Redo 로그 파일의 크기를 조정할 수 있는 새로운 기능입니다.

이는 변경 사항을 적용하기 위해 리두 로그 파일의 크기를 수동으로 조정하고 데이터베이스를 다시 시작해야 했던 이전 버전의 MySQL에 비해 크게 향상된 것입니다.

크기가 작은 Redo Log Capacity는 문제가 있으며 성능 문제로 이어질 수 있습니다.
그러나 Redo Log의 크기를 무조건 늘리는 것도 권장하지 않습니다.

큰 리두 로그 파일은 디스크 공간을 상대적으로 더 많이 소비하고 재시작(innodb_fast_shutdown=1 인 환경) 또는 갑작스러운 충돌 시 복구 시간을 늘립니다. 또한 innodb_fast_shutdown=0일 때는 종료 속도가 느려집니다.

이제 더 이상 Redo Log에 대한 파일 크기 및 파일 수(그룹수)에 대해서 지정할 필요가 업습니다.
또한 InnoDB Redo Logs 파일의 크기를 늘리거나 줄이려는 경우 MySQL을 다시 시작할 필요가 없습니다.


해당 기능은 8.0.30 버전에서 추가되었으나 InnoDB Online DDL ADD/DROP Column Instant 관련 이슈로 포스팅에서는 MySQL 8.0.31 버전을 사용하였습니다.


관련 포스팅

           

새로운 리두 로그 아키텍처

MySQL 8.0.30 버전에서는 새로운 리두 로그 아키텍처의 적용에 따른 몇 가지의 변화가 있습니다.


사이즈 지정

새로운 리두 로그 크기는 하나의 단일 변수 innodb_redo_log_capacity(바이트)로 정의됩니다. 기본값은 100MB 이며, 최대 설정은 128GB입니다.


예를 들어 다음 SQL 문을 사용하여 Redo Log 용량을 200MB로 변경할 수 있습니다.

mysql> set global innodb_redo_log_capacity=200*1024*1024;
Query OK, 0 rows affected (0.99 sec)


mysql> show variables like 'innodb_redo_log_capacity%';
+--------------------------+-----------+
| Variable_name            | Value     |
+--------------------------+-----------+
| innodb_redo_log_capacity | 209715200 |
+--------------------------+-----------+
1 row in set (0.00 sec)


MySQL 8.0.30 버전 부터는 innodb_redo_log_capacity 시스템 변수는 innodb_log_files_in_group 및 innodb_log_file_size 시스템 변수를 대체합니다.

innodb_redo_log_capacity 설정이 정의되면 innodb_log_files_in_group 및 innodb_log_file_size 설정이 무시됩니다.

그렇지 않으면 이러한 설정은 innodb_redo_log_capacity 설정을 계산하는 데 사용됩니다. (innodb_log_files_in_group * innodb_log_file_size = innodb_redo_log_capacity)

이러한 변수가 설정되지 않은 경우 리두 로그 용량은 innodb_redo_log_capacity 기본값(100MB)으로 설정됩니다.


MySQL 8.0.30 이전 버전에서는 InnoDB의 기본 설정은 data directory 에 5MB 리두 로그 파일을 2개(파일명 : ib_logfile0 , ib_logfile1)를 생성하였습니다.
 - 관련 시스템 변수: innodb_log_files_in_group , innodb_log_file_size


Redo Log 파일 저장 위치

8.0.30 버전 부터 리두 로그 파일은 datadir 디렉토리 아래에 전용 디렉토리인 #innodb_redo 디렉토리32개 파일을 생성합니다.

innodb_log_group_home_dir 시스템 변수와 연관되어 있으며 innodb_log_group_home_dir 시스템 변수를 별도로 지정하지 않는다면 datadir 디렉토리 아래에 전용 디렉토리인 #innodb_redo 디렉토리에 생성됩니다.

해당 디렉토리 내에서 두 가지 유형의 파일을 찾을 수 있습니다.

  • #ib_redoXXX(여기서 XXX는 file_id, 시퀀스 번호): 활성 리두 로그 파일입니다.
  • #ib_redoXXX_tmp: 예비 리두 로그 파일입니다.


현재 테스트 시스템에서는 innodb_log_group_home_dir 변수가 별도로 지정된 것이 없는 기본 값 상태의 조회 내역입니다.

• data 디렉토리내 새로운 redo log 파일 전용 디렉토리 확인

# pwd
/usr/local/mysql-8.0.31-linux-glibc2.12-x86_64/data

# ls -al | grep redo
drwxr-x---.  2 mysql mysql       4096  1월  7 14:57 #innodb_redo


• 디렉토리내 파일 확인

# cd \#innodb_redo

# ls -lh
합계 100M
-rw-r-----. 1 mysql mysql 3.2M  1월  7 15:14 '#ib_redo2334'
-rw-r-----. 1 mysql mysql 3.2M  1월  7 14:56 '#ib_redo2335_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  7 14:56 '#ib_redo2336_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  7 14:56 '#ib_redo2337_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  7 14:56 '#ib_redo2338_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  7 14:56 '#ib_redo2339_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  7 14:56 '#ib_redo2340_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  7 14:56 '#ib_redo2341_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  7 14:56 '#ib_redo2342_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  7 14:56 '#ib_redo2343_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  7 14:56 '#ib_redo2344_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  7 14:56 '#ib_redo2345_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  7 14:56 '#ib_redo2346_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  7 14:56 '#ib_redo2347_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  7 14:56 '#ib_redo2348_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  7 14:56 '#ib_redo2349_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  7 14:56 '#ib_redo2350_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  7 14:56 '#ib_redo2351_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  7 14:57 '#ib_redo2352_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  7 14:57 '#ib_redo2353_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  7 14:57 '#ib_redo2354_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  7 14:57 '#ib_redo2355_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  7 14:57 '#ib_redo2356_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  7 14:57 '#ib_redo2357_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  7 14:57 '#ib_redo2358_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  7 14:57 '#ib_redo2359_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  7 14:57 '#ib_redo2360_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  7 14:57 '#ib_redo2361_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  7 14:57 '#ib_redo2362_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  7 14:57 '#ib_redo2363_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  7 14:57 '#ib_redo2364_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  7 14:57 '#ib_redo2365_tmp'

InnoDB는 각 파일이 1/32 * innodb_redo_log_capacity 와 같은 32개의 리두 로그 파일을 유지하려고 시도합니다.

InnoDB 는 이렇게 32개의 파일을 균등하게 유지하려고 시도하며, 이렇게 하면 크기를 조정하고 싶을 때 하나씩 회수할 수 있습니다.


위의 설명을 다음과 같이 표현할 수 있습니다.

checkpoint_lsn (Innodb_redo_log_checkpoint_lsn): 페이지에 대한 모든 변경 사항이 이미 작성되고 테이블스페이스 파일에 다시 fsynced되도록 보장되는 LSN 지점 – 기본적으로 여전히 필요한 리두 로그 부분이 여기에서 시작됩니다.

current_lsn (Innodb_redo_log_current_lsn): 리두 로그의 마지막 기록 위치. 해당 쓰기는 여전히 MySQL 프로세스 버퍼 내부에 버퍼링될 수 있습니다.

flushed_to_disk_lsn (Innodb_redo_log_flushed_to_disk_lsn): InnoDB가 디스크로 플러시된 리두 로그의 마지막 위치.

이제 31번째 파일(90%)이 끝나면 로그 파일 관리자가 일부 정리를 수행하고 더 이상 필요하지 않은 일부 활성 파일이 새로운 예비(spare) 파일이 되게 됩니다. 
             

백그라운드 스레드가 로그 파일을 왼쪽에서 제거하여 오른쪽에 배치할 수 없는 경우, 사용자 트랜잭션은 디스크에 REDO 버퍼가 기록될 때까지 대기하게 됩니다.
이런 상황이 될 경우 DBA는 오류 로그에서 InnoDB Redo 로그 용량을 늘리라는 경고를 받게 됩니다.

[Warning] [MY-013865] [InnoDB] Redo log writer is waiting for a new redo log file.
Consider increasing innodb_redo_log_capacity.

            

Checkpoint(체크포인트)

먼저 Redo Log의 역할이 무엇인지 요약해 보겠습니다. 

이미 알고 계시겠지만 InnoDB에서 데이터가 변경될 때마다 데이터가 포함된 페이지가 메모리(InnoDB Buffer Pool)에서 수정됩니다. 해당 페이지는 dirty 로 표시됩니다.

갑작스러운 충돌(crash)이 발생할 경우 모든 변경 사항을 잃어버리지는 않지만, 메모리의 데이터는 사라집니다. 이것이 페이지의 diff 데이터도 리두 로그에 기록되는 이유입니다. (기본적으로 디스크에 플러시됨)

이러한 로그의 데이터는 일반적으로 InnoDB 복구의 경우에만 읽히게 됩니다. 이 과정에서 수정된 페이지는 수정된 데이터로 재구성됩니다.

InnoDB는 버퍼 풀(메모리)에서 tablespaces(디스크)으로 더티 페이지를 단계별로 작은 배치로 플러시합니다. 이 작업을 Fuzzy Checkpointing 이라고 합니다.

페이지가 디스크의 데이터 파일(InnoDB Tablespaces)에 기록되면 Redo Log의 해당 항목은 더 이상 필요하지 않습니다.
InnoDB가 디스크에 데이터를 기록한 위치는 Innodb_redo_log_checkpoint_lsn 값입니다.

InnoDB 체크포인트는 적응형(adaptive)입니다. 이는 체크포인트 수명(log_lsn_checkpoint_age)을 고려하여 InnoDB가 플러시를 덜 또는 더 공격적으로 결정한다는 것을 의미합니다.

adaptive 플러시에 대한 메뉴얼은 아래 링크에서 확인하시면 됩니다.


관련된 이전 포스팅 내용은 아래 링크에서 확인하시면 됩니다.



참고로 log_lsn_checkpoint_age 와 inndob_redo_log_logical_size 는 거의 동일합니다.

mysql> select concat(count, " (", format_bytes(count), ")") log_lsn_checkpoint_age,
       concat(variable_value, " (", format_bytes(variable_value),")")
             innodb_redo_log_logical_size 
 from information_schema.innodb_metrics 
 join performance_schema.global_status 
where variable_name like 'innodb_redo_log_logical_size' 
      and name like 'log_lsn_checkpoint_age';

+------------------------+------------------------------+
| log_lsn_checkpoint_age | innodb_redo_log_logical_size |
+------------------------+------------------------------+
| 14154645 (13.50 MiB)   | 14155264 (13.50 MiB)         |
+------------------------+------------------------------+


이와 같은 일관된 결과를 얻으려면 InnoDB Metrics를 활성화해야 합니다.

메트릭을 활성화하지 않으면 다음과 같은 이상하고 잘못된 결과가 나올 수 있습니다. 아래 결과는 단지 잘못된 것입니다.
이 경우에는 log_lsn_checkpoint_age 가 0 이어야 합니다.

+------------------------+------------------------------+
| log_lsn_checkpoint_age | innodb_redo_log_logical_size |
+------------------------+------------------------------+
| 5976089 (5.70 MiB)     | 512 ( 512 bytes)             |
+------------------------+------------------------------+


다음 쿼리를 통해 필수 지표가 활성화되었는지 확인할 수 있습니다.

mysql> select status from information_schema.innodb_metrics
where name like 'log_lsn_checkpoint_age';
+---------+
| status  |
+---------+
| enabled |
+---------+

또는

+----------+
| status   |
+----------+
| disabled |
+----------+


status 가 disabled 라면 innodb_monitor_enable 시스템 변수 값을 확인해 보시기 바랍니다.
포스팅 시스템에서는 innodb_monitor_enable=all 로 설정되어 있는 상태입니다.
        

Instrumentation

새로운 리두 로그에 대한 정보는 Performance_Schema.innodb_redo_log_files 에서 확인할 수 있습니다.

mysql> select *
from Performance_Schema.innodb_redo_log_files;
+---------+-----------------------------+------------+------------+---------------+---------+----------------+
| FILE_ID | FILE_NAME                   | START_LSN  | END_LSN    | SIZE_IN_BYTES | IS_FULL | CONSUMER_LEVEL |
+---------+-----------------------------+------------+------------+---------------+---------+----------------+
|    2357 | ./#innodb_redo/#ib_redo2357 | 8161859072 | 8165133824 |       3276800 |       1 |              0 |
|    2358 | ./#innodb_redo/#ib_redo2358 | 8165133824 | 8168408576 |       3276800 |       1 |              0 |
|    2359 | ./#innodb_redo/#ib_redo2359 | 8168408576 | 8171683328 |       3276800 |       1 |              0 |
|    2360 | ./#innodb_redo/#ib_redo2360 | 8171683328 | 8174958080 |       3276800 |       1 |              0 |
|    2361 | ./#innodb_redo/#ib_redo2361 | 8174958080 | 8178232832 |       3276800 |       1 |              0 |
|    2362 | ./#innodb_redo/#ib_redo2362 | 8178232832 | 8181507584 |       3276800 |       1 |              0 |
|    2363 | ./#innodb_redo/#ib_redo2363 | 8181507584 | 8184782336 |       3276800 |       1 |              0 |
|    2364 | ./#innodb_redo/#ib_redo2364 | 8184782336 | 8188057088 |       3276800 |       1 |              0 |
|    2365 | ./#innodb_redo/#ib_redo2365 | 8188057088 | 8191331840 |       3276800 |       1 |              0 |
|    2366 | ./#innodb_redo/#ib_redo2366 | 8191331840 | 8194606592 |       3276800 |       1 |              0 |
|    2367 | ./#innodb_redo/#ib_redo2367 | 8194606592 | 8197881344 |       3276800 |       0 |              0 |
+---------+-----------------------------+------------+------------+---------------+---------+----------------+
11 rows in set (0.00 sec)

위의 결과는 11개의 활성 리두 로그 파일과 21(32-11)개의 예비 파일(_tmp)이 있음을 의미합니다.

실제로 Redo Log 디렉토리에서 파일을 조회해보면 아래와 같이 동일한 정보를 확인할 수 있습니다.

# ls -lh
합계 100M
-rw-r-----. 1 mysql mysql 3.2M  1월  8 11:09 '#ib_redo2357'   <-1
-rw-r-----. 1 mysql mysql 3.2M  1월  8 11:08 '#ib_redo2358'     2
-rw-r-----. 1 mysql mysql 3.2M  1월  8 11:08 '#ib_redo2359'     3
-rw-r-----. 1 mysql mysql 3.2M  1월  8 11:09 '#ib_redo2360'     4
-rw-r-----. 1 mysql mysql 3.2M  1월  8 11:09 '#ib_redo2361'     5
-rw-r-----. 1 mysql mysql 3.2M  1월  8 11:09 '#ib_redo2362'     6
-rw-r-----. 1 mysql mysql 3.2M  1월  8 11:09 '#ib_redo2363'     7
-rw-r-----. 1 mysql mysql 3.2M  1월  8 11:09 '#ib_redo2364'     8
-rw-r-----. 1 mysql mysql 3.2M  1월  8 11:09 '#ib_redo2365'     9
-rw-r-----. 1 mysql mysql 3.2M  1월  8 11:09 '#ib_redo2366'     10
-rw-r-----. 1 mysql mysql 3.2M  1월  8 11:09 '#ib_redo2367'   <-11
-rw-r-----. 1 mysql mysql 3.2M  1월  8 10:55 '#ib_redo2368_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  8 10:55 '#ib_redo2369_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  8 10:55 '#ib_redo2370_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  8 10:55 '#ib_redo2371_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  8 10:55 '#ib_redo2372_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  8 10:55 '#ib_redo2373_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  8 10:55 '#ib_redo2374_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  8 10:55 '#ib_redo2375_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  8 11:08 '#ib_redo2376_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  8 11:08 '#ib_redo2377_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  8 11:08 '#ib_redo2378_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  8 11:08 '#ib_redo2379_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  8 11:08 '#ib_redo2380_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  8 11:08 '#ib_redo2381_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  8 11:08 '#ib_redo2382_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  8 11:08 '#ib_redo2383_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  8 11:08 '#ib_redo2384_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  8 11:08 '#ib_redo2385_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  8 11:08 '#ib_redo2386_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  8 11:08 '#ib_redo2387_tmp'
-rw-r-----. 1 mysql mysql 3.2M  1월  8 11:08 '#ib_redo2388_tmp'



모든 파일은 Performance_Schema의 file instance 테이블(file_instances 및 file_summary_by_instance)에도 확인할 수 있습니다.

mysql> select * 
from Performance_Schema.file_instances
where file_name like '%#innodb_redo/%'
order by 1;

+-----------------------------------------------------------------------------------+-------------------------------------+------------+
| FILE_NAME                                                                         | EVENT_NAME                          | OPEN_COUNT |
+-----------------------------------------------------------------------------------+-------------------------------------+------------+
| /usr/local/mysql-8.0.31-linux-glibc2.12-x86_64/data/#innodb_redo/#ib_redo2357     | wait/io/file/innodb/innodb_log_file |          5 |
| /usr/local/mysql-8.0.31-linux-glibc2.12-x86_64/data/#innodb_redo/#ib_redo2358     | wait/io/file/innodb/innodb_log_file |          4 |
| /usr/local/mysql-8.0.31-linux-glibc2.12-x86_64/data/#innodb_redo/#ib_redo2359     | wait/io/file/innodb/innodb_log_file |          4 |
| /usr/local/mysql-8.0.31-linux-glibc2.12-x86_64/data/#innodb_redo/#ib_redo2360     | wait/io/file/innodb/innodb_log_file |          5 |
| /usr/local/mysql-8.0.31-linux-glibc2.12-x86_64/data/#innodb_redo/#ib_redo2361     | wait/io/file/innodb/innodb_log_file |          4 |
| /usr/local/mysql-8.0.31-linux-glibc2.12-x86_64/data/#innodb_redo/#ib_redo2362     | wait/io/file/innodb/innodb_log_file |          5 |
| /usr/local/mysql-8.0.31-linux-glibc2.12-x86_64/data/#innodb_redo/#ib_redo2363     | wait/io/file/innodb/innodb_log_file |          5 |
| /usr/local/mysql-8.0.31-linux-glibc2.12-x86_64/data/#innodb_redo/#ib_redo2364     | wait/io/file/innodb/innodb_log_file |          5 |
| /usr/local/mysql-8.0.31-linux-glibc2.12-x86_64/data/#innodb_redo/#ib_redo2365     | wait/io/file/innodb/innodb_log_file |          4 |
| /usr/local/mysql-8.0.31-linux-glibc2.12-x86_64/data/#innodb_redo/#ib_redo2366     | wait/io/file/innodb/innodb_log_file |         18 |
| /usr/local/mysql-8.0.31-linux-glibc2.12-x86_64/data/#innodb_redo/#ib_redo2367     | wait/io/file/innodb/innodb_log_file |          7 |
| /usr/local/mysql-8.0.31-linux-glibc2.12-x86_64/data/#innodb_redo/#ib_redo2368_tmp | wait/io/file/innodb/innodb_log_file |          4 |
| /usr/local/mysql-8.0.31-linux-glibc2.12-x86_64/data/#innodb_redo/#ib_redo2369_tmp | wait/io/file/innodb/innodb_log_file |          4 |
| /usr/local/mysql-8.0.31-linux-glibc2.12-x86_64/data/#innodb_redo/#ib_redo2370_tmp | wait/io/file/innodb/innodb_log_file |          4 |
| /usr/local/mysql-8.0.31-linux-glibc2.12-x86_64/data/#innodb_redo/#ib_redo2371_tmp | wait/io/file/innodb/innodb_log_file |          5 |
| /usr/local/mysql-8.0.31-linux-glibc2.12-x86_64/data/#innodb_redo/#ib_redo2372_tmp | wait/io/file/innodb/innodb_log_file |          5 |
| /usr/local/mysql-8.0.31-linux-glibc2.12-x86_64/data/#innodb_redo/#ib_redo2373_tmp | wait/io/file/innodb/innodb_log_file |          4 |
| /usr/local/mysql-8.0.31-linux-glibc2.12-x86_64/data/#innodb_redo/#ib_redo2374_tmp | wait/io/file/innodb/innodb_log_file |          4 |
| /usr/local/mysql-8.0.31-linux-glibc2.12-x86_64/data/#innodb_redo/#ib_redo2375_tmp | wait/io/file/innodb/innodb_log_file |          5 |
| /usr/local/mysql-8.0.31-linux-glibc2.12-x86_64/data/#innodb_redo/#ib_redo2376_tmp | wait/io/file/innodb/innodb_log_file |          6 |
| /usr/local/mysql-8.0.31-linux-glibc2.12-x86_64/data/#innodb_redo/#ib_redo2377_tmp | wait/io/file/innodb/innodb_log_file |          4 |
| /usr/local/mysql-8.0.31-linux-glibc2.12-x86_64/data/#innodb_redo/#ib_redo2378_tmp | wait/io/file/innodb/innodb_log_file |          4 |
| /usr/local/mysql-8.0.31-linux-glibc2.12-x86_64/data/#innodb_redo/#ib_redo2379_tmp | wait/io/file/innodb/innodb_log_file |          5 |
| /usr/local/mysql-8.0.31-linux-glibc2.12-x86_64/data/#innodb_redo/#ib_redo2380_tmp | wait/io/file/innodb/innodb_log_file |          4 |
| /usr/local/mysql-8.0.31-linux-glibc2.12-x86_64/data/#innodb_redo/#ib_redo2381_tmp | wait/io/file/innodb/innodb_log_file |          4 |
| /usr/local/mysql-8.0.31-linux-glibc2.12-x86_64/data/#innodb_redo/#ib_redo2382_tmp | wait/io/file/innodb/innodb_log_file |          4 |
| /usr/local/mysql-8.0.31-linux-glibc2.12-x86_64/data/#innodb_redo/#ib_redo2383_tmp | wait/io/file/innodb/innodb_log_file |          4 |
| /usr/local/mysql-8.0.31-linux-glibc2.12-x86_64/data/#innodb_redo/#ib_redo2384_tmp | wait/io/file/innodb/innodb_log_file |          4 |
| /usr/local/mysql-8.0.31-linux-glibc2.12-x86_64/data/#innodb_redo/#ib_redo2385_tmp | wait/io/file/innodb/innodb_log_file |          4 |
| /usr/local/mysql-8.0.31-linux-glibc2.12-x86_64/data/#innodb_redo/#ib_redo2386_tmp | wait/io/file/innodb/innodb_log_file |          4 |
| /usr/local/mysql-8.0.31-linux-glibc2.12-x86_64/data/#innodb_redo/#ib_redo2387_tmp | wait/io/file/innodb/innodb_log_file |          4 |
| /usr/local/mysql-8.0.31-linux-glibc2.12-x86_64/data/#innodb_redo/#ib_redo2388_tmp | wait/io/file/innodb/innodb_log_file |          4 |
+-----------------------------------------------------------------------------------+-------------------------------------+------------+



평소와 같이 status variables 와 InnoDB Metrics 에는 "flushpointing" 작업에 대한 정보를 제공하는 항목이 있습니다.

• global_status

mysql> select variable_name, variable_value
from performance_schema.global_status
where variable_name like 'Innodb_redo_log%';

+-------------------------------------+----------------+
| variable_name                       | variable_value |
+-------------------------------------+----------------+
| Innodb_redo_log_read_only           | OFF            |
| Innodb_redo_log_uuid                | 1075899837     |
| Innodb_redo_log_checkpoint_lsn      | 8197441071     |
| Innodb_redo_log_current_lsn         | 8197441071     |
| Innodb_redo_log_flushed_to_disk_lsn | 8197441071     |
| Innodb_redo_log_logical_size        | 512            |
| Innodb_redo_log_physical_size       | 36044800       |
| Innodb_redo_log_capacity_resized    | 104857600      |
| Innodb_redo_log_resize_status       | OK             |
| Innodb_redo_log_enabled             | ON             |
+-------------------------------------+----------------+


• innodb_metrics

mysql> select name,count
from information_schema.innodb_metrics
where name like '%lsn%';
+--------------------------------+------------+
| name                           | count      |
+--------------------------------+------------+
| buffer_flush_lsn_avg_rate      |      33365 |
| buffer_flush_pct_for_lsn       |         16 |
| log_lsn_last_flush             | 8197441071 |
| log_lsn_last_checkpoint        | 8197441071 |
| log_lsn_current                | 8197441071 |
| log_lsn_archived               |          0 |
| log_lsn_checkpoint_age         |          0 |
| log_lsn_buf_dirty_pages_added  | 8197441071 |
| log_lsn_buf_pool_oldest_approx |          0 |
| log_lsn_buf_pool_oldest_lwm    |          0 |
| log_flush_lsn_avg_rate         |     426725 |
+--------------------------------+------------+

             

Redo Log 와 lsn

새로운 Redo Log Architecture는 db의 변경 내역에 대해서 정상적으로 복구에 대응하기 위해서 파일간의 서로 연속적으로 연결되어 있습니다.

오른쪽 끝에서 두 번째 redo log file 끝에 도달하면 InnoDB는 더 이상 필요하지 않은 redo log file를 왼쪽에서 가져와 오른쪽에 배치합니다.
모든 redo log file은 항상 32개 입니다.

활성화된 Redo log file 수는 길어지거나 줄어들 수 있습니다.

InnoDB가 Buffer Pool에서 데이터 파일로 더티 페이지를 플러시 할 때 리두 로그 정보는 필요하지 않으며, checkpoint_lsn 도 오른쪽으로 이동합니다.

Redo의 왼쪽에 남아 있는 정보는 오래된 정보를 담고 있습니다.

아래 예시를 통해서 몇 가지 내용을 살펴보도록 하겠습니다.


예제 1 – 부하가 없는 상황(no load)

mysql> select file_id, start_lsn, end_lsn, 
       if(is_full=1,'100%',
          concat(round((((
               select variable_value 
                 from performance_schema.global_status 
                where variable_name='innodb_redo_log_current_lsn'
               )-start_lsn)/(end_lsn-start_lsn)*100),2),'%')) full,
          concat(format_bytes(size_in_bytes)," / " ,
          format_bytes(@@innodb_redo_log_capacity) ) file_size, 
      (select variable_value from performance_schema.global_status 
        where variable_name='innodb_redo_log_checkpoint_lsn') checkpoint_lsn,
      (select variable_value from performance_schema.global_status 
        where variable_name='innodb_redo_log_current_lsn') current_lsn, 
      (select variable_value from performance_schema.global_status 
        where variable_name='innodb_redo_log_flushed_to_disk_lsn') flushed_to_disk_lsn,
      (select count from information_schema.innodb_metrics 
        where name like 'log_lsn_checkpoint_age') checkpoint_age 
from performance_schema.innodb_redo_log_files;

+---------+------------+------------+--------+-----------------------+----------------+-------------+---------------------+----------------+
| file_id | start_lsn  | end_lsn    | full   | file_size             | checkpoint_lsn | current_lsn | flushed_to_disk_lsn | checkpoint_age |
+---------+------------+------------+--------+-----------------------+----------------+-------------+---------------------+----------------+
|    2357 | 8161859072 | 8165133824 | 100%   | 3.12 MiB / 100.00 MiB | 8197441223     | 8197441223  | 8197441223          |              0 |
|    2358 | 8165133824 | 8168408576 | 100%   | 3.12 MiB / 100.00 MiB | 8197441223     | 8197441223  | 8197441223          |              0 |
|    2359 | 8168408576 | 8171683328 | 100%   | 3.12 MiB / 100.00 MiB | 8197441223     | 8197441223  | 8197441223          |              0 |
|    2360 | 8171683328 | 8174958080 | 100%   | 3.12 MiB / 100.00 MiB | 8197441223     | 8197441223  | 8197441223          |              0 |
|    2361 | 8174958080 | 8178232832 | 100%   | 3.12 MiB / 100.00 MiB | 8197441223     | 8197441223  | 8197441223          |              0 |
|    2362 | 8178232832 | 8181507584 | 100%   | 3.12 MiB / 100.00 MiB | 8197441223     | 8197441223  | 8197441223          |              0 |
|    2363 | 8181507584 | 8184782336 | 100%   | 3.12 MiB / 100.00 MiB | 8197441223     | 8197441223  | 8197441223          |              0 |
|    2364 | 8184782336 | 8188057088 | 100%   | 3.12 MiB / 100.00 MiB | 8197441223     | 8197441223  | 8197441223          |              0 |
|    2365 | 8188057088 | 8191331840 | 100%   | 3.12 MiB / 100.00 MiB | 8197441223     | 8197441223  | 8197441223          |              0 |
|    2366 | 8191331840 | 8194606592 | 100%   | 3.12 MiB / 100.00 MiB | 8197441223     | 8197441223  | 8197441223          |              0 |
|    2367 | 8194606592 | 8197881344 | 86.56% | 3.12 MiB / 100.00 MiB | 8197441223     | 8197441223  | 8197441223          |              0 |
+---------+------------+------------+--------+-----------------------+----------------+-------------+---------------------+----------------+

            

위의 조회 결과에서 current_lsn, checkpoint_lsn 및 flushed_to_disk_lsn의 값이 같은 것을 볼 수 있습니다.
이들은 모두 마지막 활성 로그 file_id 2367에 있습니다.

file_id 2367 에 해당하는 lsn 인 8194606592 ~ 8197881344 사이에 있음을 의미하는 것입니다.
현재 상태는 트랜잭션이 없는 상태입니다.

Innodb_redo_log_logical_size 의 최소 크기는 512 bytes 이며, 이 경우 checkpoint age 는 0 입니다.

mysql> select concat(count, " (", format_bytes(count), ")") log_lsn_checkpoint_age,
       concat(variable_value, " (", format_bytes(variable_value),")")
             innodb_redo_log_logical_size 
 from information_schema.innodb_metrics 
 join performance_schema.global_status 
where variable_name like 'innodb_redo_log_logical_size' 
      and name like 'log_lsn_checkpoint_age';

+------------------------+------------------------------+
| log_lsn_checkpoint_age | innodb_redo_log_logical_size |
+------------------------+------------------------------+
| 0 (   0 bytes)         | 512 ( 512 bytes)             |
+------------------------+------------------------------+



예제 2 – 부하가 있는 상황(load)

mysql> select file_id, start_lsn, end_lsn, 
       if(is_full=1,'100%',
          concat(round((((
               select variable_value 
                 from performance_schema.global_status 
                where variable_name='innodb_redo_log_current_lsn'
               )-start_lsn)/(end_lsn-start_lsn)*100),2),'%')) full,
          concat(format_bytes(size_in_bytes)," / " ,
          format_bytes(@@innodb_redo_log_capacity) ) file_size, 
      (select variable_value from performance_schema.global_status 
        where variable_name='innodb_redo_log_checkpoint_lsn') checkpoint_lsn,
      (select variable_value from performance_schema.global_status 
        where variable_name='innodb_redo_log_current_lsn') current_lsn, 
      (select variable_value from performance_schema.global_status 
        where variable_name='innodb_redo_log_flushed_to_disk_lsn') flushed_to_disk_lsn,
      (select count from information_schema.innodb_metrics 
        where name like 'log_lsn_checkpoint_age') checkpoint_age 
from performance_schema.innodb_redo_log_files;

+---------+------------+------------+--------+-----------------------+----------------+-------------+---------------------+----------------+
| file_id | start_lsn  | end_lsn    | full   | file_size             | checkpoint_lsn | current_lsn | flushed_to_disk_lsn | checkpoint_age |
+---------+------------+------------+--------+-----------------------+----------------+-------------+---------------------+----------------+
|    2370 | 8204430848 | 8207705600 | 100%   | 3.12 MiB / 100.00 MiB | 8283867074     | 8295666962  | 8295666962          |       11799888 |
|    2371 | 8207705600 | 8210980352 | 100%   | 3.12 MiB / 100.00 MiB | 8283867074     | 8295666962  | 8295666962          |       11799888 |
|    2372 | 8210980352 | 8214255104 | 100%   | 3.12 MiB / 100.00 MiB | 8283867074     | 8295666962  | 8295666962          |       11799888 |
|    2373 | 8214255104 | 8217529856 | 100%   | 3.12 MiB / 100.00 MiB | 8283867074     | 8295666962  | 8295666962          |       11799888 |
|    2374 | 8217529856 | 8220804608 | 100%   | 3.12 MiB / 100.00 MiB | 8283867074     | 8295666962  | 8295666962          |       11799888 |
|    2375 | 8220804608 | 8224079360 | 100%   | 3.12 MiB / 100.00 MiB | 8283867074     | 8295666962  | 8295666962          |       11799888 |
|    2376 | 8224079360 | 8227354112 | 100%   | 3.12 MiB / 100.00 MiB | 8283867074     | 8295666962  | 8295666962          |       11799888 |
|    2377 | 8227354112 | 8230628864 | 100%   | 3.12 MiB / 100.00 MiB | 8283867074     | 8295666962  | 8295666962          |       11799888 |
|    2378 | 8230628864 | 8233903616 | 100%   | 3.12 MiB / 100.00 MiB | 8283867074     | 8295666962  | 8295666962          |       11799888 |
|    2379 | 8233903616 | 8237178368 | 100%   | 3.12 MiB / 100.00 MiB | 8283867074     | 8295666962  | 8295666962          |       11799888 |
|    2380 | 8237178368 | 8240453120 | 100%   | 3.12 MiB / 100.00 MiB | 8283867074     | 8295666962  | 8295666962          |       11799888 |
|    2381 | 8240453120 | 8243727872 | 100%   | 3.12 MiB / 100.00 MiB | 8283867074     | 8295666962  | 8295666962          |       11799888 |
|    2382 | 8243727872 | 8247002624 | 100%   | 3.12 MiB / 100.00 MiB | 8283867074     | 8295666962  | 8295666962          |       11799888 |
|    2383 | 8247002624 | 8250277376 | 100%   | 3.12 MiB / 100.00 MiB | 8283867074     | 8295666962  | 8295666962          |       11799888 |
|    2384 | 8250277376 | 8253552128 | 100%   | 3.12 MiB / 100.00 MiB | 8283867074     | 8295666962  | 8295666962          |       11799888 |
|    2385 | 8253552128 | 8256826880 | 100%   | 3.12 MiB / 100.00 MiB | 8283867074     | 8295666962  | 8295666962          |       11799888 |
|    2386 | 8256826880 | 8260101632 | 100%   | 3.12 MiB / 100.00 MiB | 8283867074     | 8295666962  | 8295666962          |       11799888 |
|    2387 | 8260101632 | 8263376384 | 100%   | 3.12 MiB / 100.00 MiB | 8283867074     | 8295666962  | 8295666962          |       11799888 |
|    2388 | 8263376384 | 8266651136 | 100%   | 3.12 MiB / 100.00 MiB | 8283867074     | 8295666962  | 8295666962          |       11799888 |
|    2389 | 8266651136 | 8269925888 | 100%   | 3.12 MiB / 100.00 MiB | 8283867074     | 8295666962  | 8295666962          |       11799888 |
|    2390 | 8269925888 | 8273200640 | 100%   | 3.12 MiB / 100.00 MiB | 8283867074     | 8295666962  | 8295666962          |       11799888 |
|    2391 | 8273200640 | 8276475392 | 100%   | 3.12 MiB / 100.00 MiB | 8283867074     | 8295666962  | 8295666962          |       11799888 |
|    2392 | 8276475392 | 8279750144 | 100%   | 3.12 MiB / 100.00 MiB | 8283867074     | 8295666962  | 8295666962          |       11799888 |
|    2393 | 8279750144 | 8283024896 | 100%   | 3.12 MiB / 100.00 MiB | 8283867074     | 8295666962  | 8295666962          |       11799888 |
|    2394 | 8283024896 | 8286299648 | 100%   | 3.12 MiB / 100.00 MiB | 8283867074     | 8295666962  | 8295666962          |       11799888 |
|    2395 | 8286299648 | 8289574400 | 100%   | 3.12 MiB / 100.00 MiB | 8283867074     | 8295666962  | 8295666962          |       11799888 |
|    2396 | 8289574400 | 8292849152 | 100%   | 3.12 MiB / 100.00 MiB | 8283867074     | 8295666962  | 8295666962          |       11799888 |
|    2397 | 8292849152 | 8296123904 | 86.05% | 3.12 MiB / 100.00 MiB | 8283867074     | 8295666962  | 8295666962          |       11799888 |
+---------+------------+------------+--------+-----------------------+----------------+-------------+---------------------+----------------+

          

위의 내용에서는 Redo Log에 여전히 충분한 공간이 있음을 알 수 있습니다. 필요한 경우(파일이 끝에서 두 번째 90%에 도달할 때), 오래된 정보를 담고 있는 더 이상 필요하지 않은 파일은 새로운 예비(spare) 파일로 재사용 됩니다.
           

유용한 쿼리

위의 예제에서 조회한 쿼리 이외에 Redo log 와 관련된 유용한 쿼리에 대한 정보입니다.

• 최적의 InnoDB Redo Log 용량 계산
피크 트래픽 시간 동안 아래 쿼리를 실행하여 Redo 로그 용량 크기에 필요한 양을 추정할 수 있습니다.

select VARIABLE_VALUE from performance_schema.global_status 
 where VARIABLE_NAME='Innodb_redo_log_current_lsn' into @a;select sleep(60) into @garb ;select 
       VARIABLE_VALUE from performance_schema.global_status 
 where VARIABLE_NAME='Innodb_redo_log_current_lsn' into @b;select 
 format_bytes(abs(@a - @b)) per_min, format_bytes(abs(@a - @b)*60) per_hour;

주요한 내용은 Redo Log Capacity가 최소 1시간의 로그를 보유할 수 있을 만큼 충분히 크게 만드는 것입니다. 적절한 Redo Log Capacity 사이즈는 InnoDB가 더티 페이지를 너무 자주 덤프하지 않게 하도록 할 수 있습니다.


• Redo Log 사용량 보기

select concat(variable_value, " (", 
              format_bytes(variable_value),")") innodb_redo_log_logical_size,
       concat(round(count*8/7), " (", 
              format_bytes(round(count*8/7)), ")") soft_logical_capacity,
       concat(round(@@innodb_redo_log_capacity*29.8/32), " (",
              format_bytes(round(@@innodb_redo_log_capacity*29.8/32)) ,")") hard_logical_capacity,
       concat(@@innodb_redo_log_capacity, " (",
              format_bytes(@@innodb_redo_log_capacity) ,")") redo_log_capacity,              
       concat(round(variable_value / (count*8/7)*100,2), "%") logical_used,
       concat(round(variable_value / (@@innodb_redo_log_capacity*29.8/32)*100,2), "%") hard_used  
  from performance_schema.global_status 
  join information_schema.innodb_metrics 
 where variable_name like 'innodb_redo_log_logical_size' 
   and name like 'log_max_modified_age_async';

적절한 InnoDB Metrics가 활성화되면 Redo Log의 사용량에 대한 개요를 얻고 Soft 및 Hard Redo Log 논리적 용량과 관련하여 현재 위치를 확인할 수도 있습니다.


이번 글은 8.0.30 버전에서 추가된 "Dynamic InnoDB Redo Log" 기능과 관련된 내용을 살펴보았으며, 포스팅은 여기에서 마무리하도록 하겠습니다.

             

Reference

Reference URL
blogs.oracle.com/dynamic-innodb-redo-log
dev.mysql.com/innodb_redo_log_capacity


연관된 다른 글

 

 

 

 

 

              

0
글에 대한 당신의 생각을 기다립니다. 댓글 의견 주세요!x