본문 바로가기
다른 DBMS/MySQL&MariaDB

InnoDB Redo Log

by 취미툰 2021. 1. 15.
반응형

▶Redo Log?

리두 로그는 crash recovery 중 불완전한 트랜잭션에 의해 변경된 데이터를 수정하기 위해 사용되는디스크 기반 데이터 구조입니다.

 

default로 리두 로그는 ib_logfile0,ib_logfile1로 이름된 두개의 파일이 물리적으로 존재합니다.

$ ls -alh ib_logfile*
-rw-r-----. 1 mysql mysql 48M Jan 12 02:49 ib_logfile0
-rw-r-----. 1 mysql mysql 48M Dec 14 02:19 ib_logfile1

 

MySQL은 순환방식으로 리두 로그 파일을 씁니다. 리두 로그는 계속 증가하는 LSN값으로 표시됩니다.(순환로그이기 때문에 다시 순환될때 데이터가 덮어쓰여져 기존에 데이터가 없어지게 됩니다.)

 

- Redo log 사이즈 변경과 수 변경


1.MySQL을 정지하고 오류없이 정지되었는지 확인합니다.

2.my.cnf 파일을 수정합니다.

사이즈 변경을 위해서는 이 파라미터를 설정합니다.

innodb_log_file_size

리두 로그 수 변경을 위해서는 이 파라미터를 설정합니다.

innodb_log_files_in_group

3.MySQL을 시작합니다.

 

 

테스트 - 리두 로그의 수를 3개로 늘리기

 

--수정 전 확인
mysql> show variables like 'innodb_log_files_in_group';
+---------------------------+-------+
| Variable_name             | Value |
+---------------------------+-------+
| innodb_log_files_in_group | 2     |
+---------------------------+-------+
1 row in set (0.00 sec)


--DB Stop

systemctl stop mysql.server


--my.cnf 수정
vi /etc/my.cnf

innodb_log_files_in_group=3 
추가


--DB Start
systemctl start mysql.server


--수정 후 확인

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

--실제파일 확인
ls -al ib_logfile*
-rw-r----- 1 mysql mysql 50331648 Jan 13 19:43 ib_logfile0
-rw-r----- 1 mysql mysql 50331648 Jan 13 19:43 ib_logfile1
-rw-r----- 1 mysql mysql 50331648 Jan 13 19:43 ib_logfile2

 

만약 InnoDB가 innodb_log_file_size의 값과 리두로그 파일의 사이즈가 다른것을 발견한다면, checkpoint를 쓰고 이전 로그 파일을 사용못하게 닫은 후 제거합니다. 그리고 요구된 사이즈로 새 로그파일을 생성하고 사용가능하게 Open합니다.

 

 

- Group Commit for Redo Log Flushing

InnoDB는 트랜잭션이 커밋되기 전에 트랜잭션의 리두 로그를 flush합니다.

InnoDB는 기능적으로 group commit을 사용하여 각 커밋마다 하나의 flush를 피하고 여러 flush 요청을 그룹화하여 사용합니다.

 

Group Commit을 통해 InnoDB는 거의 동시에 커밋되는 여러 사용자의 트랜잭션들에 대해 한번의 커밋으로 수행하여 처리량이 크게 향상됩니다.

 

-Redo Log Archiving

리두 로그 레코드를 복사하는 백업 유틸리티가 때로는 리두 로그 생성 속도를 유지하지 못할 수 있습니다. 백업작업이 진행중일때 리두 로그가 순환되어 다시 쓰여진다면 덮어쓰게 되는 것이므로 리두 로그 레코드가 손실됩니다.

이 문제는 백업작업 중 MySQL 서버에 작업이 많을때 자주 발생합니다.

백업 저장 매체보다 리두 로그 파일 저장은 빠르게 이루어지게 됩니다. 

MySQL 8.0.17부터 소개된 리두 로그 아카이빙기능은 리두로그 파일의 리두 로그 레코드를 순차적으로 아카이브파일로 만들어서 이 문제를 해결합니다.

백업 유틸리티는 필요한경우  아카이브파일로부터 리두 로그 레코드를 복사할 수 있으며, 잠재적인 데이터 손실을 방지할 수 있습니다.

 

서버에서 리두 로그 아카이빙이 구성된다면 MySQL Enterprise Edition과 함께 사용가능한 MySQL Enterprise Backup기능을 사용하여 MySQL 서버를 백업할 때 리두 로그 아카이빙 기능을 사용합니다.

 

innodb_redo_log_archive_dirs 파라미터를 설정하여 리두 로그 아카이빙 기능을 활성화할 수 있습니다.

lebel:directory 형식으로 값이 작성됩니다. default는 NULL이며 비활성화되어 있습니다.

 

사용 예시

mysql> SET GLOBAL innodb_redo_log_archive_dirs='label1:directory_path1[;label2:directory_path2;…]';

lebel은 아카이브 디렉토리에 대한 임의의 식별자입니다. 빈 label로 가능합니다 하지만 ':'은 필요합니다.

directory는 반드시 지정되야 합니다. 리두 로그 아카이빙이 활성화 된 경우, 설정된 디렉토리에 아카이브 파일이 있어야 합니다. 그렇지 않으면 오류가 반환됩니다. 경로는 ':'을 포함할 수는 있지만 ';'은 포함할 수 없습니다.

 

**

지정하는 아카이브 디렉토리는 다음 요구사항을 충족해야합니다.

- 디렉토리가 존재해야합니다. (MySQL은 디렉토리를 생성해주지 않습니다. 디렉토리가 없으면 에러를 반환합니다)

ERROR 3844 (HY000): Redo log archive directory  'directory_path1' does not exist or is not a directory

 

- 디렉토리는 접근권한이 설정되어 있어야합니다. 시스템의 권한이 없는 유저에게 리두 로그 데이터가 노출됩니다. 그렇지 않으면 아래 에러를 반환합니다.

ERROR 3846 (HY000): Redo log archive directory  'directory_path1' is accessible to all OS users

 

- 디렉토리는 datadir, innodb_data_home_dir, innodb_directories, innodb_log_group_home_dir, innodb_temp_tablespaces_dir, innodb_temp_tablespaces_dir, innodb_tmpdir,innodb_undo_directory,secure_file_priv 이 파라미터에 설정된 디렉토리나 하위디렉토리가 될 수 없습니다. 즉 다른 디렉토리에 저장되야 합니다.

ERROR 3845 (HY000): Redo log archive directory  'directory_path1' is in, under, or over server directory  'datadir' - '/path/to/data_directory'

 

리두 로그 아카이브를 지원하는 백업 유틸리티가 백업을 시작하면 백업 유틸리티가 리두를 활성화합니다.

innodb_redo_log_archive_start() 사용자 정의 함수를 호출하여 아카이브를 기록합니다.

 

리두 로그 아카이브를 지원하는 백업 유틸리티를 사용하지 않는 경우, 리두 로그 아카이브는 수동으로 활성화 할수도 있습니다.

 

SELECT innodb_redo_log_archive_start('label', 'subdir'); or DO innodb_redo_log_archive_start('label', 'subdir');

**

innodb_redo_log_archive_start() 를 사용해서 리두 로그 아카이빙을 활성화하는동안 세션은 열려있어야 합니다.

같은 세션에서 반드시 리두 로그 아카이빙을 비활성화(innodb_redo_log_archive_stop())해야 합니다.

만약 리두로그 아카이빙을 명시적으로 비활성화하기 전에 세션이 종료된다면, 리두로그 아카이브 파일은 자동적으로 삭제되고 로그파일이 남지 않습니다.

**

 

label은 innodb_redo_log_archive_dirs에 정의된 레이블입니다. subdir은 옵션입니다. 아카이브 파일을 저장하기 위해 레이블로 식별하되 디렉토리의 하위 디렉토리를 지정하기 위한것입니다.

subdir은 비어있거나 NULL이거나 생략할 수 있습니다.

 

INNODB_REDO_LOG_ARCHIVE 권한을 가진 유저만 리두 로그 아카이빙을 활성화/비활성화할 수 있습니다.

백업 유틸리티를 실행하는 MySQL 사용자 또는 리두 로그 아카이빙을 수동으로 활성화/비활성화하는 MySQL유저는 반드시 이 권한이 있어야합니다.

 

리두 로그 아카이브 파일의 경로는 /디렉토리경로/[subdir/]/archive.serverUUID.000001.log 형식으로 저장됩니다.

 

백업 유틸리티가 InnoDB 데이터 파일 복사를 완료하면 innodb_redo_log_archive_stop()을 호출하여 비활성화합니다.

리두 로그 아카이브를 지원하는 백업 유틸리티를 사용하지 않는 경우, 리두 로그 아카이브는 수동으로 비활성화 할수도 있습니다.

SELECT innodb_redo_log_archive_stop(); or DO innodb_redo_log_archive_stop();

비활성화 기능이 완료되면, 백업 유틸리티는 리두 로그와 아카이브 파일의 리두로그 데이터와 관련된 섹션을 찾습니다. 

 

백업 유틸리티가 리두 로그 데이터 복사를 완료하고 더 이상 리두 로그 아카이브 파일이 필요하지 않으면 아카이브 파일을 삭제합니다.

 

정상적인 상황에서 아카이브 파일의 삭제는 백업 유틸리티의 책임입니다. 아카이브 작업이 비정상적으로 종료되면 MySQL서버가 파일을 삭제합니다.

 

 

- Performance Considerations

리두 로그 아카이브를 활성화하면 일반적으로 추가적인 활동으로인해 성능 비용이 발생하게 됩니다.

UNIX 및 UNIX와 유사한 운영체제에서의 성능 영향은 일반적으로 미미합니다. 윈도우에서의 성능영향이 일반적으로 똑같거나 약간 더 높습니다.

 

리두 로그 파일과 같은 스토리지에 저장되는 아카이브파일의 경우 복합적인 쓰기 작업으로 인해 성능에 미치는 영향이 더 클 수 있습니다.

리두 로그파일이 아카이브 파일보다 느린 스토리지에 저장되는 경우에는 성능이 제멋대로일 수 있습니다.

 

리두 로그 아카이브 파일을 쓰는 것은 다음과 같은 경우를 제외하고는 정상적인 트랜잭션 로깅을 방해하지 않습니다.

- 리두로그 아카이브 파일 스토리지가 리두로그 파일 스토리지보다 느린 스토리지 일때

- 리두 로그 아카이브 파일에 쓰여지기를 기다리는 많은 리두로그 블록이 기다리고 있을때

 

이 경우 트랜잭션 로깅 속도는 리두 로그 파카이브 파일이 있는 더 느린 스토리지에서 관리할 수 있는 수준으로 감소합니다.

 

 

테스트

--적용 전 
mysql> show variables like 'innodb_redo_log_archive_dirs';
+------------------------------+-------+
| Variable_name                | Value |
+------------------------------+-------+
| innodb_redo_log_archive_dirs |       |
+------------------------------+-------+
1 row in set (0.00 sec)


mkdir /arch
mkdir -p /arch/aa
  
mysql> set GLOBAL innodb_redo_log_archive_dirs='bae:/arch';
Query OK, 0 rows affected (0.00 sec)


mysql> show variables like 'innodb_redo_log_archive_dirs';
+------------------------------+-----------+
| Variable_name                | Value     |
+------------------------------+-----------+
| innodb_redo_log_archive_dirs | bae:/arch |
+------------------------------+-----------+
1 row in set (0.00 sec)


--백업 시작
mysql> select innodb_redo_log_archive_start('bae','aa');
+-------------------------------------------+
| innodb_redo_log_archive_start('bae','aa') |
+-------------------------------------------+
|                                         0 |
+-------------------------------------------+
1 row in set (0.05 sec)

--확인
 ls -al
total 4
-r--r----- 1 mysql mysql 4096 Jan 13 21:53 archive.05d88a11-343b-11eb-bcf1-080027dd785f.000001.log



--백업 정지
mysql> select innodb_redo_log_archive_stop();
+--------------------------------+
| innodb_redo_log_archive_stop() |
+--------------------------------+
|                              0 |
+--------------------------------+
1 row in set (0.00 sec)


 

트러블 슈팅

ERROR 3846 (HY000): Redo log archive directory '/arch/subdir' is accessible to all OS users

해결 : chown mysql:mysql 디렉토리명으로 해서 소유자를 mysql만 사용할 수 있게 변경해주어야 합니다.

 

 

drwx------   2 root root    6 Jan 13 21:31 aa

chown -R mysql:mysql aa

drwx------   2 mysql mysql    6 Jan 13 21:31 aa

 

소유자문제가 아니라 권한범위의 문제인줄 알고 chmod 700부터 시작해서 다양하게 권한부여를 해보았는데, 

ERROR 3847 (HY000): Cannot create redo log archive file '/arch/aa/archive.05d88a11-343b-11eb-bcf1-080027dd785f.000001.log' (OS errno: 13 - Permission denied) 에러와 번갈아가면서 났었습니다.. 결론은 소유자 문제 에러였습니다.

 

 

 

-Disabling Redo Logging

 

8.0.21부터 ALTER INSTANCE DISABLE INNODB REDO_LOG 문을 사용해서 리두 로깅을 비활성화할 수 있습니다.

이 기능은 새 MySQL 인스턴스에 데이터를 로드하기 위한 것입니다.

리두 로깅을 비활성화로 설정하면 리두 로그 쓰기와 doublewrite buffering을 방지하여 데이터 로드 속도가 빨라집니다.

 

**주의**

이 기능은 새 MySQL 인스턴스에 데이터를 로드하는 용도로만 사용됩니다.

절대 운영시스템에서 사용하면 안됩니다. 리두 로깅이 비활성화된 상태에서 서버를 종료하고 다시 시작할 수 있지만 리두 로깅이 비활성화된 상태에서 예기치 않게 서버가 중지되면 데이터 손실 및 인스턴스 손상이 발생할 수 있습니다.

 

리두 로깅이 비활성화를 하는 동안 예기치 않은 서버 중지 후 서버를 재시작하려는 시도는 다음 오류와 함께 거부됩니다.

[ERROR] [MY-013578] [InnoDB] Server was killed when Innodb Redo logging was disabled. Data files could be corrupt. You can try to restart the database with innodb_force_recovery=6

 

해당 기능을 활성화/비활성화를 하기 위해서는 INNODB_REDO_LOG_ENABLE 권한이 필요합니다.

innodb_redo_log_enabled 상태 변수를 사용하면 리두 로깅 상태를 모니터링할 수 있습니다.

리두 로깅이 비활성화되어 있는 동안에는 복제작업 밒 리두 로그 아카이브가 허용되지 않습니다.

 

ALTER INSTANCE [ENABLE|DISABLE] INNODB REDO_LOG작업에는 다른 ALTER INSTANCE작업이 동시에 실행되지 않도록 하는 배타적인 백업 메타데이터 LOCK이 필요합니다. 다른 ALTER INSTANCE 작업은 실행 전에 LOCK이 해제될 때까지 기다려야 합니다.

 

새 MySQL 인스턴스에서 리두 로그 비활성화하는 방법입니다.

 

1.새 MySQL 인스턴스에서, INNODB_REDO_LOG_ENABLE 권한을 유저에게 부여합니다.(data_load_admin 유저에게 권한을 부여했습니다)

mysql> GRANT INNODB_REDO_LOG_ENABLE ON *.* to 'data_load_admin';

 

2. 리두 로그를 비황성화합니다.

mysql> ALTER INSTANCE DISABLE INNODB REDO_LOG;

 

3.비활성화되었는지 확인합니다.

 

mysql> SHOW GLOBAL STATUS LIKE 'Innodb_redo_log_enabled';
+-------------------------+-------+
| Variable_name | Value |
+-------------------------+-------+
| Innodb_redo_log_enabled | OFF |
+-------------------------+-------+

 

4.데이터 import 작업을 수행합니다.

 

5.활성화를 합니다.

mysql> ALTER INSTANCE ENABLE INNODB REDO_LOG;

 

6.활성화되었는지 확인합니다.

 

mysql> SHOW GLOBAL STATUS LIKE 'Innodb_redo_log_enabled';
+-------------------------+-------+
| Variable_name | Value |
+-------------------------+-------+
| Innodb_redo_log_enabled | ON |
+-------------------------+-------+

반응형

'다른 DBMS > MySQL&MariaDB' 카테고리의 다른 글

InnoDB Locking  (0) 2021.01.18
InnoDB Undo Log  (0) 2021.01.16
InnoDB Doublewrite Buffer  (0) 2021.01.14
InnoDB On-Disk Structures  (0) 2021.01.13
InnoDB IN-MEMORY Structures  (0) 2021.01.12

댓글