버전 제어 시스템, 특히 Git은 코드 변경 사항을 추적하고, 팀과 협력하고, 코드베이스의 안정성을 보장하는 데 필수적인 도구입니다. Git은 주로 소스 코드용으로 설계되었지만 버전 제어 및 스키마 변경 관리를 위해 MySQL 데이터베이스와 함께 사용할 수도 있습니다.
이 기사에서는 가이드 형식의 구체적인 예와 함께 Git 후크를 사용하여 버전 제어를 위해 Git을 MySQL과 통합하는 방법을 살펴보겠습니다. 목록에 제공된 모든 스크립트는 완벽하게 작동하고 완전합니다. 테스트 환경에서 순차적으로 재현할 수 있습니다.
먼저 테스트 데이터베이스와 사용자를 생성해 보겠습니다.
create database testdb_remote; create user 'user_remote'@'localhost' identified WITH mysql_native_password by 'remote123'; grant all on testdb_remote.* to 'user_remote'@'localhost';
다음으로 원격 저장소를 생성하겠습니다. 이는 모든 원격 서버의 저장소가 될 수 있지만 단순화를 위해 로컬로 생성하겠습니다. 명령 실행의 편의를 위해 git bash를 사용합니다. 내 로컬 컴퓨터에는 이미 git 폴더가 있으므로 이를 사용합니다.
cd /c/git mkdir testdb.remote cd testdb.remote git init --bare
그리고 원격 저장소의 복제본으로 로컬 저장소를 만듭니다.
cd /c/git git clone /c/git/testdb.remote testdb.local cd testdb.local git ls-files
저장소에 파일이 없습니다. 하나를 만들고 변경 사항을 원격 저장소에 푸시해 보겠습니다.
echo "Test DB repo" > readme.md git status git add . git commit -m "1st commit" git push
원격 저장소의 내용을 확인해 보겠습니다.
cd /c/git/testdb.remote git ls-tree --full-tree -r HEAD
원격 저장소에는 후크 폴더가 있으며 여기에는 예제와 함께 여러 파일이 포함되어 있습니다.
ls -1 /c/git/testdb.remote/hooks
후크는 특정 이벤트가 발생할 때 실행되는 스크립트입니다. Git에는 클라이언트측 후크와 서버측 후크가 있습니다. 클라이언트 측 후크는 커밋 및 병합과 같은 작업에 의해 트리거됩니다. 서버 측 후크는 푸시된 커밋 수신과 같은 네트워크 작업에서 실행됩니다. 후크에 대한 자세한 내용은 여기 에 설명되어 있습니다. 로직을 구현하는 데는 다양한 옵션이 있습니다. 수신 후 서버 측 후크를 사용하는 예를 들어 보겠습니다.
후크 폴더에서 "post-receive"라는 파일을 생성해야 합니다. 이는 일반 bash 스크립트입니다.
#!/bin/sh while read oval nval ref do echo List of files changed in the commit: git diff --name-only $oval $nval done
위 스크립트는 푸시가 성공적으로 완료될 때마다 서버에서 실행되어 수정된 파일 목록을 출력합니다. readme.md에 한 줄을 추가하고 변경 사항을 원격 저장소에 푸시하여 어떻게 작동하는지 확인해 보겠습니다.
cd /c/git/testdb.local echo "New line" >> readme.md git add . git commit -m "Line added" git push
git push 명령을 실행할 때 이제 출력에 remote:
- 이것은 서버에서 실행된 수신 후 스크립트의 출력입니다.
기본 변경 사항에 대해 말하자면, 파일을 추가, 수정, 삭제할 수 있습니다. 이러한 변경 사항을 데이터베이스에 적용하는 방법에 대해 다양한 접근 방식을 취할 수 있습니다.
두 번째 옵션을 선택했다고 가정하면 추가되거나 변경된 파일을 실행해야 합니다. --diff-filter=AM
매개변수를 추가하여 여기에 설명된 대로 이러한 파일을 필터링할 수 있습니다.
#!/bin/sh while read oval nval ref do echo List of files added or changed in the commit: git diff --name-only --diff-filter=AM $oval $nval done
몇 가지 파일을 추가하고 readme.md도 다시 변경하세요.
echo "SELECT 1;" > test1.sql echo "SELECT 2;" > test2.sql echo "SELECT 3;" > test3.sql echo "New line 2" >> readme.md git add . git commit -m "New files" git push
후크 스크립트의 출력에는 다음 4개의 파일이 포함됩니다.
test1.sql 및 readme.md 파일을 편집하고 test2.sql을 삭제한 후 다른 파일을 추가합니다.
echo "SELECT 11;" > test1.sql echo "New line 2" >> readme.md rm test2.sql echo "SELECT 4;" > test4.sql git add . git commit -m "Modify, remove and add" git push
수정되고 추가된 파일만 표시됩니다.
우리의 목표는 푸시가 성공할 때마다 SQL 스크립트를 실행하는 것이므로 이 유형의 파일만 필터링해야 합니다. 우리의 경우에는 모두 ".sql" 확장자를 가져야 한다는 요구 사항을 설정하겠습니다. 필터링하려면 git diff
명령에 -- "*.sql"
매개변수를 추가하세요.
#!/bin/sh while read oval nval ref do echo List of files added or changed in the commit: git diff --name-only --diff-filter=AM $oval $nval -- "*.sql" done
스크립트를 실행하려면 데이터베이스에도 연결할 수 있어야 합니다. 이를 위해 자격 증명을 만들고 연결을 테스트합니다.
mysql_config_editor set --login-path=testdb_remote --host=localhost --port=3306 --user=user_remote --password mysql --login-path=testdb_remote --database=testdb_remote
".sql" 파일을 반복하고, 각 파일을 실행하고, 결과를 확인하도록 스크립트를 수정하세요. 또한 필요한 순서로 파일을 실행하려면 목록 출력을 정렬해야 합니다. git show 명령을 사용하여 SQL 스크립트의 내용을 표시하고 MySQL에서 실행할 수 있도록 파이프를 통해 전달합니다.
변수 "$?" SQL 스크립트가 성공적으로 실행되면 0이 포함되고 오류가 있으면 다른 값이 포함됩니다.
#!/bin/sh while read oval nval ref do echo List of files added or changed in the commit: for file in $(git diff --name-only --diff-filter=AM $oval $nval -- "*.sql" | sort); do git show master:${file} | mysql --login-path=testdb_remote --database=testdb_remote echo "FILE: ${file} - result $?" done done
한 번 더 테스트를 수행합니다. 이전에 생성된 모든 ".sql" 파일을 삭제하고 다음에 대한 스크립트를 생성합니다.
또한 원하는 파일 실행 순서를 보장하려면 각 파일 이름에 접두사(1_, 2_ 등)를 추가해야 합니다.
rm *.sql echo "DB Initialization" >> readme.md echo " DROP TABLE IF EXISTS customers; CREATE TABLE customers ( id int UNSIGNED NOT NULL AUTO_INCREMENT, name varchar(255) DEFAULT NULL, PRIMARY KEY (id) ); " > 1_customers.sql echo " INSERT INTO customers (id, name) VALUES (1, 'John Doe'), (2, 'Jane Smith') AS new ON DUPLICATE KEY UPDATE customers.name = new.name; " > 2_customers_init.sql echo " DROP PROCEDURE IF EXISTS get_customer; DELIMITER $$ CREATE PROCEDURE get_customer(IN customer_id int UNSIGNED) BEGIN SELECT c.id, c.name FROM customers c WHERE c.id = customer_id; END $$ " > 3_get_customer.sql echo "SELECT FROM customers;" > 4_error_select.sql ls -1
따라서 실행해야 하는 4개의 ".sql" 파일이 있습니다.
저장소를 변경합니다.
그리고 git push
수행하면 파일들이 순차적으로 실행되고, 각 파일의 실행 결과(MySQL 명령 종료 코드)가 표시되는 것을 알 수 있다. “4_error_select.sql” 파일에는 구문 오류가 있으므로 실행 결과는 1입니다.
마지막으로 데이터베이스에 무엇이 있는지 확인해 보겠습니다.
mysql --login-path=testdb_remote --database=testdb_remote show tables; call get_customer(1); call get_customer(2);
보시다시피 테이블과 프로시저가 원격 데이터베이스에 생성되었습니다. 프로시저가 성공적으로 실행되고 데이터를 반환합니다.
후크 스크립트 출력의 가독성을 높이려면 MySQL CLI 출력을 억제하거나 로그 파일로 리디렉션할 수 있습니다. 또한 MySQL 명령 실행 결과를 분석하고 후크 스크립트에 더 많은 로직을 추가할 수도 있습니다.
예를 들어, 테스트 데이터베이스에서 SQL 스크립트를 실행한 다음 여기 에서 설명한 대로 몇 가지 테스트를 실행할 수 있습니다. 테스트 데이터베이스에서 테스트가 성공적으로 완료되면 프로덕션 데이터베이스에서 SQL 스크립트를 실행하고 아마도 일부 테스트도 실행할 수 있습니다.
각 단계의 결과를 분석하여 모든 구성의 파이프라인을 생성할 수 있습니다.
물론 각 접근 방식에는 여러 가지 장점과 한계가 있습니다. 두 번째 접근 방식에서는 예를 들어 테이블이 생성될 때까지 테이블에 데이터를 삽입할 수 없기 때문에 스크립트가 실행되는 순서를 보장해야 합니다. 또한 스크립트를 다시 실행할 수 있는지 확인해야 합니다. 즉, 생성 중인 개체가 이미 데이터베이스에 있거나 데이터베이스에 추가할 데이터가 이미 포함되어 있는 경우 상황을 올바르게 처리할 수 있는지 확인해야 합니다.
버전 관리 시스템을 사용할 경우 미리 정해진 형식의 스크립트에 대한 변경 사항을 추가로 형식화해야 하므로 개발 프로세스가 조금 더 복잡해집니다. 그러나 설치 파일을 사용하면 어느 정도 유연성을 얻을 수 있습니다.
설명된 기술의 주요 장점은 CI/CD 파이프라인을 구현하는 기능뿐만 아니라 매우 적은 노력으로 데이터베이스에 버전 관리를 구현한다는 것입니다.
이것이 당신에게 도움이 될 수 있는지 평가하려면 먼저 스스로에게 질문해 보십시오. 프로덕션에서 직접 코드를 작성하는 빈도는 얼마나 됩니까?