버전 제어 시스템, 특히 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" 파일이 있습니다. 저장소를 변경합니다. 그리고 수행하면 파일들이 순차적으로 실행되고, 각 파일의 실행 결과(MySQL 명령 종료 코드)가 표시되는 것을 알 수 있다. “4_error_select.sql” 파일에는 구문 오류가 있으므로 실행 결과는 1입니다. git push 마지막으로 데이터베이스에 무엇이 있는지 확인해 보겠습니다. 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 파이프라인을 이것이 당신에게 도움이 될 수 있는지 평가하려면 먼저 스스로에게 질문해 보십시오. 프로덕션에서 직접 코드를 작성하는 빈도는 얼마나 됩니까?