Using Blue/Green Deployment For (near) Zero-Downtime Primary Key Updates in RDS MySQL

 

사이즈가 큰 대규모 테이블은 데이터베이스 작업 시 여러가지 문제를 일으킬수 있습니다. 테이블 정의를 수정해야 할 때도 있습니다. 하지만 RDS 복제는 asynchronous 방식을 사용하지 않기 때문에 일반적인 switchover 절차를 사용할 수 없습니다. 그러나 RDS Blue/Green 기능은 asynchronous replication 를 활용하므로, switchover 절차를 통해 사이즈가 큰 대규모 테이블의 정의를 수정할 수 있습니다.

Blue/Green 배포 전략은 애플리케이션을 위한 두 개의 별개이지만 동일한 환경을 생성하는 것이 포함합니다. 애플리케이션이 현재 실행되고 있는 환경을 “Blue” 라고 하며, 수정 사항이나 새로운 버전을 포함하는 환경을 “Green” 이라고 합니다. 이 연속 배포 방법을 사용하면 최소한의 다운타임으로 데이터베이스를 업데이트할 수 있습니다.

이번 게시글에서는 Primary key 값이 최대치에 근접한 테이블을 Blue/Green 환경을 사용해서 수정하는 방법을 보여드리겠습니다.

다음 블로그에서는 아래와 같은 환경을 가정합니다:

앞에서 언급한 환경을 바탕으로 Blue/Green 환경을 생성할 수 있습니다. 이 과정을 통해 production 환경 구조를 복제한 새로운 환경을 구축합니다. Blue/Green 환경을 생성하려면 클러스터 설정의 binlog_format 이 row 로 설정되어 있어야 합니다.

Blue/Green 환경을 생성하려면, 드롭다운 메뉴에서 “Create Blue/Green Deployment” 버튼을 선택하면 됩니다.

배포 식별자를 설정합니다:

Blue/Green 환경을 생성하기 전에 구성을 신중히 검토하세요. 생성 과정에서 Aurora 버전을 변경할 수도 있다는 점을 기억하세요. 이 옵션을 통해 모든 데이터가 Green 환경으로 복제되므로 업그레이드 전에 유효성 검사를 수행할 수 있습니다.

생성이 완료된 후, Green 환경의 모든 노드가 사용 가능 상태가 될 때까지 기다려 주세요.

노드가 사용 가능한 상태가 되면 수정 작업을 시작할 수 있습니다. 그러나 Replica 환경에서 컬럼의 데이터 타입을 변경하면 replication 문제가 발생할 수 있습니다. 이를 방지하기 위해, int 타입에서 bigint 타입으로 데이터 타입을 확장하는 경우 클러스터 파라미터 그룹에서 replica_type_conversions 값을 설정해야 합니다. 이 변수는 ALL_NON_LOSSY 로 설정해야 합니다. (https://dev.mysql.com/doc/mysql-replication-excerpt/8.0/en/replication-features-different-data-types.html)

    * replica_type_conversions=”ALL_NON_LOSSY”

replica_type_conversions 는 복제환경에서 특정 데이터 타입 변환 허용여부를 설정하는 변수

Source 와 Replica 의 데이터 타입이 일치하지 않더라도 복제가 가능

ALL_NON_LOSSY 는 데이터 손실이 발생하지 않는 변환만 허용하는 옵션

데이터 손실이 발생할 수 있는 변환(INT→TINYINT)을 시도할 경우 Replica 가 오류와 함께 중지

또한, unsigned 데이터를 사용할 때 문제가 발생할 수 있는 다음의 버그 리포트(https://bugs.mysql.com/bug.php?id=82599)를 확인하는 것이 중요합니다. 필요한 작업을 모두 완료한 후에 수정 작업을 진행할 수 있습니다.

Stopping the replica:

MySQL - Green > CALL mysql.rds_stop_replication;
+-----------------------------+
| Message |
+-----------------------------+
| Replica is down or disabled |
+-----------------------------+
1 row in set (1.02 sec)
Query OK, 0 rows affected (1.02 sec)

Consider the following table definitions for the changes:

MySQL - Green > SHOW CREATE TABLE joinitG
*************************** 1. row ***************************
Table: joinit
Create Table: CREATE TABLE `joinit` (
`i` int NOT NULL AUTO_INCREMENT,
`s` varchar(64) DEFAULT NULL,
`t` time NOT NULL,
`g` int NOT NULL,
PRIMARY KEY (`i`),
KEY `g_fk` (`g`),
CONSTRAINT `joinit_ibfk_1` FOREIGN KEY (`g`) REFERENCES `joinit_fk` (`i`) ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=4653058 DEFAULT CHARSET=latin1
1 row in set (0.02 sec)

MySQL - Green > SHOW CREATE TABLE joinit_fkG
*************************** 1. row ***************************
Table: joinit_fk
Create Table: CREATE TABLE `joinit_fk` (
`i` int NOT NULL,
PRIMARY KEY (`i`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.01 sec)

Doing the alter change:

MySQL - Green > ALTER TABLE joinit DROP FOREIGN KEY joinit_ibfk_1;
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0

MySQL - Green > ALTER TABLE joinit_fk MODIFY COLUMN i bigint NOT NULL;
Query OK, 60 rows affected (0.09 sec)
Records: 60 Duplicates: 0 Warnings: 0

MySQL - Green > ALTER TABLE joinit ADD CONSTRAINT joinit_ibfk_1 FOREIGN KEY (`g`) REFERENCES `joinit_fk` (`i`) ON DELETE RESTRICT ON UPDATE CASCADE;
Query OK, 4194391 rows affected (1 min 45.66 sec)
Records: 4194391 Duplicates: 0 Warnings: 0

프로세스를 완료한 후, 복제를 시작하고 복제가 동기화될 때까지 기다리면 됩니다.

MySQL - Green > CALL mysql.rds_start_replication;
+---------------------------+
| Message |
+---------------------------+
| Replica running normally. |
+---------------------------+
1 row in set (2.18 sec)
Query OK, 0 rows affected (2.18 sec)

MySQL - Green > SHOW REPLICA STATUSG
*************************** 1. row ***************************
Replica_IO_State: Waiting for source to send event
Source_Host: 10.1.15.0
Source_User: rdsrepladmin
Source_Port: 3306
Connect_Retry: 60
Source_Log_File: mysql-bin-changelog.000004
Read_Source_Log_Pos: 112774
Relay_Log_File: relaylog.000002
Relay_Log_Pos: 82470
Relay_Source_Log_File: mysql-bin-changelog.000004
Replica_IO_Running: Yes
Replica_SQL_Running: Yes
[...]
Seconds_Behind_Source: 0
[...]
1 row in set (0.01 sec)

Replica 를 동기화 상태로 유지하면 switchover 를 진행할 수 있으며, switchover 작업중에 애플리케이션 쓰기 작업은 중지하는 것을 권장합니다.

우측 상단의 action 버튼에서 배포 옵션을 선택하면 switchover 버튼에 접근할 수 있습니다.

클릭하면 switchover 를 진행할 수 있는 패널이 나타납니다.

mysql

이제 switchover 가 완료될 때까지 기다리면 됩니다.

절차가 완료된 후, 컬럼을 변경한 Green 노드가 이제 “new-blue” 로 표시되는 것을 확인할 수 있습니다.

이 노드에는 애플리케이션에서 사용하던 endpoint 를 가지고 있습니다. 기존의 Blue 환경은 이제 “old-blue” 로 변경되었습니다.

모든 작업을 완료 후, 노드를 삭제하기 전에 필요한 검증 작업을 수행할 수 있습니다. 애플리케이션은 이제 정상적인 운영으로 복귀할 수 있으며, 검증 작업이 완료되면 배포 환경과 old-blue 버전을 삭제하면 됩니다.

Conclusion

switchover 절차는 다양한 목적으로 사용되는 일반적인 방법입니다. 하지만 앞서 언급했듯이, 표준 RDS 복제 방식으로는 이 절차를 수행할 수 없습니다. 이는 RDS 복제가 MySQL binary log 의 asynchronous 복제 방식을 사용하지 않기 때문입니다. 따라서 Blue/Green 배포 전략은 이러한 한계를 극복할 수 있는 현실적인 해결책입니다.

Blue/Green 배포에 대한 자세한 내용은 AWS 문서를 참조하세요. (https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/blue-green-deployments.html)

또한, Blue/Green 배포의 제약 사항에 대해서도 숙지하는 것이 중요합니다. 제약 사항은 여기에서 확인할 수 있습니다. (https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/blue-green-deployments-considerations.html)

FAQ

rollback 기능이 있나요?

안타깝게도, Blue/Green 환경에는 내장된 rollback 기능이 없습니다. 그러나 AWS 블로그 포스트에서 설명된 대로 수동으로 rollback 을 수행하는 것이 가능합니다: (https://aws.amazon.com/blogs/database/implement-a-rollback-strategy-after-an-amazon-aurora-mysql-blue-green-deployment-switchover/)

 

MySQL 업그레이드 작업에도 사용할 수 있나요?

네, Blue/Green 환경을 사용하여 MySQL 업그레이드를 수행할 수 있습니다.

 

Replica 에서 error 가 발생하면 어떻게 되나요?

Replica 에서 error 가 발생하면 switchover 가 진행되지 않습니다. 배포의 Log & events 탭에서 다음과 같은 오류 메시지를 확인할 수 있습니다: “Switchover from DB cluster beto-blog to beto-blog-green-usht2d was canceled due to replication errors on beto-blog-green-usht2d. Correct the replication errors and then switch over.” (beto-blog 에서 beto-blog-green-usht2d 로의 switchover 가 beto-blog-green-usht2d 에서 발생한 복제 오류로 인해 취소되었습니다. 복제 오류를 수정한 후 switchover 를 다시 시도하세요.)

 

블로그 원문 : https://www.percona.com/blog/using-blue-green-deployment-for-near-zero-downtime-primary-key-updates-in-rds-mysql/

 

자유롭게 댓글을 달아주세요! 언제나 환영합니다.
기타 문의:  info@neoclova.co.kr
네오클로바 기술블로그 홈 바로가기: https://neoclova.net
네오클로바 홈페이지: http://neoclova.co.kr

 

 

Similar Posts

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다