Last Updated on 7월 15, 2022 by Jade(정현호)
안녕하세요
이번 포스팅은 percona 의 pt-online-schema-change(PT-OSC) 에서 plugin 기능을 이용한 단계별 일시중지 기능에 대해서 확인 해보도록 하겠습니다.
PT-ONLINE-SCHEMA-CHANGE
Percona Toolkit 는 Percona 사에서 개발한 오픈소스 기반의 MySQL/MariaDB 의 유틸리티로 기술지원 시 사용하던 유용한 기능의 유틸리티 도구를 하나로 묶은 패키지 입니다.
이러한 Toolkit은 일일이 수동으로 작업하기 다소 복잡하거나 어려운 작업들을 단순하고 수월하게 할수 있게 도와주는 유용한 도구 입니다.
PT-ONLINE-SCHEMA-CHANGE 는 Percona Toolkit 에 포함된 유틸리티 도구 중 하나로써 많이 Online DDL 작업을 위해서 많이 사용 되는 툴 입니다.
PT-ONLINE-SCHEMA-CHANGE 자체에 대한 내용은 아래 이전 포스팅을 참조하시면 됩니다.
PT-OSC 의 Pause 기능
PT-ONLINE-SCHEMA-CHANGE 는 Online DDL 를 작업 하는 과정에서 여러 가지 좋은 기능을 지원하고 있어서 많이 상요되는 툴 입니다.
아쉬운 기능 중 예를 들어 테이블을 복사가 완료 되고 변경사항이 동기화 되고 있는 상황에서 임시 테이블과 원본 테이블간의 교체(rename) 시기를 나중에 한다던지(원하는 시점에) 또는 원하는 단계에서 잠시 멈추거나 하는 등의 진행에 관해서 컨트롤 하는 것 입니다.
PT-OSC 2.2 버전에서 pause-file 과 plugin 기능이 추가 되면서 위와 같은 기능에 대해서 사용이 가능하게 되었습니다.
pause-file
pause-file 옵션을 확인 해보겠습니다.
해당 옵션은 이 매개변수에 지정한 파일이 존재하는 동안 실행이 일시 중지가 되며 60초 간격으로 파일이 있는지를 체크를 합니다.
파일이 삭제(또는 rename 등) 되었다면 다음 Step 으로 진행되게 됩니다.
먼저 테스트를 위해서 테이블을 하나 생성 하도록 하겠습니다.
mysql> create database test; mysql> use test; mysql> drop table test.tb_test; mysql> create table test.tb_test (col1 int not null auto_increment, col2 int, col3 varchar(100), col4 varchar(100), primary key(col1) ) ENGINE=InnoDB ; mysql> insert into test.tb_test (col2,col3,col4) values(1,'A','B');
* 데이터베이스 명과 테이블명은 테스트 예시 입니다.
테이블이 작아서 바로 종료 될 것임으로 처음 부터 pause-file 대상의 파일을 생성하고 진행하도록 하겠습니다.
-- pasue-file 생성 [root]# touch test123.txt -- pt-osc 수행 [root]# pt-online-schema-change --execute \ --host=localhost \ --defaults-file=/etc/my.cnf \ --chunk-size=1000 \ --chunk-size-limit=1 \ --chunk-index=PRIMARY \ --progress=time,10 \ --port=3306 --charset=UTF8MB4 \ --user=root --ask-pass \ --pause-file=./test123.txt \ --alter "add column col5 varchar(30)" \ D=test,t=tb_test
위의 PT-OSC 실행 시 "--pause-file=./test123.txt" 이라는 옵션을 사용하고 있는 것을 확인 할 수 있습니다.
실행하게 되면 아래와 같이 원본 테이블에 트리거 생성 후 멈추게 됩니다.
Operation, tries, wait: analyze_table, 10, 1 copy_rows, 10, 0.25 create_triggers, 10, 1 drop_triggers, 10, 1 swap_tables, 10, 1 update_foreign_keys, 10, 1 Altering `test`.`tb_test`... Creating new table... Created new table test._tb_test_new OK. Altering new table... Altered `test`.`_tb_test_new` OK. 2021-12-25T16:40:41 Creating triggers... 2021-12-25T16:40:41 Created triggers OK. 2021-12-25T16:40:41 Copying approximately 1 rows... Sleeping 60 seconds because ./test123.txt exists Sleeping 60 seconds because ./test123.txt exists
해당 단계에서 60초 동안 파일이 삭제 되었는지를 계속 체크를 하게 됩니다.
해당 단계에서는 원본테이블에 트리거가 생성이 이미 되어있기 때문에 원본 테이블에 변경사항은 계속 반영이 되고 있는 상태 입니다.
이제 pause 를 위해 생성한 파일을 삭제하면 다음 파일을 체크 시 다시 진행되게 됩니다.
Sleeping 60 seconds because ./test123.txt exists Sleeping 60 seconds because ./test123.txt exists 2021-12-25T17:00:41 Copied rows OK. 2021-12-25T17:00:41 Analyzing new table... 2021-12-25T17:00:41 Swapping tables... 2021-12-25T17:00:41 Swapped original and new tables OK. 2021-12-25T17:00:41 Dropping old table... 2021-12-25T17:00:42 Dropped old table `test`.`_tb_test_old` OK. 2021-12-25T17:00:42 Dropping triggers... 2021-12-25T17:00:42 Dropped triggers OK. Successfully altered `test`.`tb_test`.
테이블의 사이즈를 크게 만들고 확인을 해보면, 진행 중간에 파일을 생성하면 즉시 멈추게 됩니다.
2021-12-25T17:28:58 Creating triggers... 2021-12-25T17:28:58 Created triggers OK. 2021-12-25T17:28:58 Copying approximately 986400 rows... Sleeping 60 seconds because ./test123.txt exists Copying `tdb`.`sbtest1`: 7% 11:57 remain <--- 파일 삭제시 진행 Sleeping 60 seconds because ./test123.txt exists <--- 파일 다시 생성 Copying `tdb`.`sbtest1`: 16% 10:45 remain <--- 파일 삭제시 진행 Copying `tdb`.`sbtest1`: 60% 01:29 remain Sleeping 60 seconds because ./test123.txt exists <--- 파일 다시 생성
이와 같이 필요한 경우 언제든지 단계를 멈추고 다시 진행하고를 할 수 있습니다.
다만 어느 특정 step 에서 멈추고 싶다고 하는 원하는 시점에 대해서는 해당 기능보다는 다음에 확인할 plugin 통해서 사용할 수 있습니다.
plugin
plugin 은 perl 로 작성하는 모듈 파일로 PT-OSC 의 많은 기능에 대해서 hooking(또는 hook) 을 할 수 있으며, 그에 따라서 원하는 기능을 추가/구현 할 수 있는 기능 으로 2.2 버전에서 추가 되었습니다.
hooking 이 가능한 PT-OSC 기능은 아래와 같습니다.
init before_create_new_table after_create_new_table before_alter_new_table after_alter_new_table before_create_triggers after_create_triggers before_copy_rows after_copy_rows before_swap_tables after_swap_tables before_update_foreign_keys after_update_foreign_keys before_drop_old_table after_drop_old_table before_drop_triggers before_exit get_slave_lag
대부분의 단계(또는 기능) 에서 hooking 이 가능 합니다.
그래서 포스팅에서는 복제 테이블을 생성 후(원본 테이블에 트리거 생성전) 에 멈추고, 복제가 완료되어 임시테이블과의 rename 시점 두번에 대해서 멈춤기능을 사용하는 시나리오로 진행하도록 하겠습니다.
작성된 perl 파일은 아래 GitHub 에서 참조하였습니다.
Plugin when executed with your pt-online-schema-change command will pause in the last stage of execution, untill file ./pt_schema_change_wait.txt is deleted.
• 파일명: pt_online_schema_change_plugin.pl
use strict ; use warnings; package pt_online_schema_change_plugin ; sub new { my ($class, %args) = @_; my $self = { %args }; return bless $self, $class; } sub after_alter_new_table { my $pauseFile = './pt_schema_change_wait_1.txt'; if (-e $pauseFile) { #file $pauseFile exist } else { # create file if it does not exist open(my $fh, '>', $pauseFile); print $fh "Please delete this file to allow pt-online-schema-change script to next step \n"; print $fh "this step is [after_alter_new_table] \n"; close $fh; } print "======================================================================================\n"; print "SCRIPT WILL ONLY NEXT STEP IF FILE IS NOT PRESENT $pauseFile\n"; print "======================================================================================\n"; #loop until file deleted while (-e $pauseFile) { print "This Step is [after_alter_new_table] \n"; print "File $pauseFile is present will delay next step by 30 seconds to proceed silmply delete this file\n"; sleep(30); } print "File is $pauseFile NOT present will next step now!\n"; return; } sub before_swap_tables { my $pauseFile = './pt_schema_change_wait_2.txt'; if (-e $pauseFile) { #file $pauseFile exist } else { # create file if it does not exist open(my $fh, '>', $pauseFile); print $fh "Please delete this file to allow pt-online-schema-change script to next step \n"; print $fh "this step is [before_swap_tables] \n"; close $fh; } print "======================================================================================\n"; print "SCRIPT WILL ONLY NEXT STEP IF FILE IS NOT PRESENT $pauseFile\n"; print "======================================================================================\n"; #loop until file deleted while (-e $pauseFile) { print "This Step is [before_swap_tables] \n"; print "File $pauseFile is present will delay next step by 30 seconds to proceed silmply delete this file\n"; sleep(30); } print "File is $pauseFile NOT present will next step now!\n"; return; } 1;
간단하게 설명하면 먼저 2곳에서 멈추게 되며 after_alter_new_table 와 before_swap_tables 에서 멈추게 됩니다.
after_alter_new_table 는 임시테이블 생성 후 원본 테이블에 트리거를 생성하기 전에 멈추게 됩니다.
before_swap_tables 는 복제가 완료된 이후 원본테이블과 임시테이블과 교체(rename) 하기전에 멈추게 됩니다.
그리고 각 멈추는 단계에서는 pause 를 체크할 파일이 있는지 여부를 확인하여 없다면 생성하게 됩니다.
파일명 : pt_schema_change_wait_1.txt 와 pt_schema_change_wait_2.txt
touch pt_schema_change_wait_1.txt touch pt_schema_change_wait_2.txt
즉, 실행 시 파일의 여부와 상관 없이 해당 단계에서는 멈추게 됩니다.
멈추고 나서는 30초마다 파일이 삭제 되었는지를 체크를 하게 됩니다.
해당 시간은 위의 perl 소스에서 sleep(30) 에서 변경 할 수 있습니다.
실행
실행은 아래와 같은 형태로 수행하게 됩니다..
pt-online-schema-change --execute \ --plugin=./pt_online_schema_change_plugin.pl \ <--플러그인 옵션 사용 --host=localhost \ --defaults-file=/etc/my.cnf \ --chunk-size=1000 \ --chunk-size-limit=1 \ --chunk-index=PRIMARY \ --progress=time,10 \ --port=3306 --charset=UTF8MB4 \ --user=root --ask-pass \ --alter "add column col5 varchar(30)" \ D=test,t=tb_test
실행을 하면 아래와 같이 진행되는 것을 확인 할 수 있습니다
after_alter_new_table 에서는 아래와 같이 진행 후 멈추게 됩니다.
Operation, tries, wait: analyze_table, 10, 1 copy_rows, 10, 0.25 create_triggers, 10, 1 drop_triggers, 10, 1 swap_tables, 10, 1 update_foreign_keys, 10, 1 Altering `test`.`tb_test`... Creating new table... Created new table test._tb_test_new OK. Altering new table... Altered `test`.`_tb_test_new` OK. ====================================================================================== SCRIPT WILL ONLY NEXT STEP IF FILE IS NOT PRESENT ./pt_schema_change_wait_1.txt ====================================================================================== This Step is [after_alter_new_table] File ./pt_schema_change_wait_1.txt is present will delay next step by 30 seconds to proceed silmply delete this file File ./pt_schema_change_wait_1.txt is present will delay next step by 30 seconds to proceed silmply delete this file
파일을 삭제 하게 되면 진행 되다가 before_swap_tables 단계에서 멈추게 됩니다.
다시 파일을 삭제하면 아래와 같이 진행되게 됩니다.
2021-12-25T17:51:07 Creating triggers... 2021-12-25T17:51:07 Created triggers OK. 2021-12-25T17:51:07 Copying approximately 1 rows... 2021-12-25T17:51:07 Copied rows OK. ====================================================================================== SCRIPT WILL ONLY NEXT STEP IF FILE IS NOT PRESENT ./pt_schema_change_wait_2.txt ====================================================================================== This Step is [before_swap_tables] File ./pt_schema_change_wait_2.txt is present will delay next step by 30 seconds to proceed silmply delete this file File is ./pt_schema_change_wait_2.txt NOT present will next step now! 2021-12-25T17:51:37 Analyzing new table... 2021-12-25T17:51:37 Swapping tables... 2021-12-25T17:51:37 Swapped original and new tables OK. 2021-12-25T17:51:37 Dropping old table... 2021-12-25T17:51:37 Dropped old table `test`.`_tb_test_old` OK. 2021-12-25T17:51:37 Dropping triggers... 2021-12-25T17:51:37 Dropped triggers OK. Successfully altered `test`.`tb_test`.
2.2 버전부터 추가된 플러그인 기능을 통해서 위와 같이 원하는 단계에서 잠시멈춤을 조절 할 수 있습니다.
위의 perl 파일에서 sub .... { } 을 삭제하고 원하는 단계를 추가해서 원하는 형태로 사용할 수 있습니다.
after_alter_new_table 를 사용한다고 할 경우 상황에 따라서 데이터가 적재나 동기화 되기 전에 복제테이블에 추가로 필요한 트리거를 생성하거나 하는 등으로 사용할 수 있을 것 도 같습니다
before_swap_tables 는 계속 변경 사항을 반영을 하면서 rename 을 잠시 중지 하다가 DB 사용이 적은 시간대에 pause 파일을 삭제하여 rename 을 하는 형태로 사용 할 수 있을 것 같습니다
Reference
Reference Link
• github.com/wasylni
• percona.com/pt-online-schema-change.html#plugin
관련된 다른글
Principal DBA(MySQL, AWS Aurora, Oracle)
핀테크 서비스인 핀다에서 데이터베이스를 운영하고 있어요(at finda.co.kr)
Previous - 당근마켓, 위메프, Oracle Korea ACS / Fedora Kor UserGroup 운영중
Database 외에도 NoSQL , Linux , Python, Cloud, Http/PHP CGI 등에도 관심이 있습니다
purityboy83@gmail.com / admin@hoing.io
오 이런 기능이...!!!!!!! 잘 봤습니다.
안녕하세요~! 재환님
코멘트까지 남겨주시고 감사합니다.
좋은 하루 되세요~