진행 알림과 사용자 응답
이행 진행 알림과 텔레그램 명령 제어, 실패 시 버튼 응답 및 환경 변수 토큰 관리와 장애 시나리오
#핵심 요약
실습 도구의 텔레그램 봇은 이행 시작, 25%, 50%, 75%, 100%, 끝을 보고하고, 문제가 생기면 버튼으로 어떻게 할지 묻음
봇 코드는 추가 설치 없이 Python 표준 라이브러리 urllib만으로 만듦
토큰은 봇의 비밀번호와 같음
실습에서는 토큰과 chat_id를 사용자 환경 변수 TG_BOT_TOKEN, TG_CHAT_ID에 두고 프로그램이 읽게 함
테이블 하나가 COPY 트랜잭션 하나라서, 중단하면 적재 중이던 테이블만 롤백되고 끝난 테이블은 남음(시나리오 B)
#개념과 동작 원리
| 원래 파일 | 맡은 일 |
|---|---|
telegram_bot.py |
보고, 질문, 명령 받기 표준 라이브러리만 사용 |
tg_check.py |
토큰 확인, 봇에게 말을 건 사람(chat_id) 찾기, 테스트 메시지 |
app.py |
④ 이행 화면에 텔레그램 칸 추가 |
| 이행 중 사용자가 보내는 말 | 실습 동작 |
|---|---|
상태 |
지금 테이블, 전체 %, 속도, 남은 시간 |
멈춰 |
다음 배치에서 멈춤 적재 트랜잭션은 열린 채로 기다림 |
계속 |
멈춘 곳부터 이어서 진행 |
중단 |
확인 버튼을 한 번 더 묻고, 적재 중이던 테이블은 롤백, 끝난 테이블은 남김 2분 안에 답이 없으면 계속 진행 |
| 봇이 먼저 묻는 경우 | 버튼 | 답이 없으면 |
|---|---|---|
| 테이블 적재 실패(연결 끊김 등) | 다시 시도, 건너뛰고 계속, 이행 중단 | 화면에서 고른 기본값 실습 대화는 5분 |
| 제약조건, 인덱스 일부 실패 | 계속 만들기, 여기서 멈춤 | 계속 만들기 |
봇은 등록한 chat_id가 아닌 대화의 말과 버튼은 반영하지 않음
텔레그램을 끄면 실패는 화면에서 고른 기본값대로 처리됨
#필수 명령어 또는 SQL
#봇 만들기
텔레그램은 휴대폰 번호로만 가입되므로 휴대폰 앱을 먼저 설치, 가입하고, PC 앱은 휴대폰 앱의 설정 → 기기에서 QR을 찍어 로그인함
PC 텔레그램에서 파란 공식 인증 표시가 있는 @BotFather를 골라 /newbot을 보내고, 봇 이름과 bot으로 끝나는 봇 아이디를 보내면 토큰이 옴
그다음 새 봇의 대화방을 열고 시작을 눌러야 봇이 사용자에게 먼저 말을 걸 수 있음
#토큰 저장과 연결 점검
cd C:\work\mini_migrator; $t = Read-Host "새 봇 토큰 붙여넣기" -AsSecureString; $env:TG_BOT_TOKEN = [Net.NetworkCredential]::new('', $t).Password; [Environment]::SetEnvironmentVariable('TG_BOT_TOKEN', $env:TG_BOT_TOKEN, 'User'); python tg_check.py결과 해석: Read-Host -AsSecureString으로 받아 붙여넣은 토큰이 화면에 보이지 않음
같은 값을 사용자 환경 변수로 저장해 새 창에서도 남게 함tg_check.py가 토큰 확인 OK, chat_id, 테스트 메시지 OK를 차례로 출력하면 성공임Unauthorized나 Not Found면 토큰이 잘못 붙여넣어진 것이고, 사람을 찾지 못하면 새 봇에게 시작을 누르지 않은 것임Read-Host는 PowerShell 문법이라 Anaconda Prompt(cmd)에서는 안 되고, 일반 PowerShell에서는 Anaconda의 python을 찾지 못해 Anaconda PowerShell Prompt를 씀
[Environment]::SetEnvironmentVariable('TG_CHAT_ID', '<CHAT_ID>', 'User')결과 해석: 성공하면 출력이 없음
이후 화면 ④의 텔레그램 칸에 토큰과 chat_id가 저절로 채워짐
#시나리오 결과
연습 설정은 배치 크기 1000, 보고 간격 10초임
| 시나리오 | 사용자 동작 | 실습 결과 |
|---|---|---|
| A 멈춰, 상태, 계속 | 25% 보고 뒤 멈춰 → 상태 → 계속 | 496,000행에서 멈추고, 계속을 보내자 그 위치부터 이어서 1,100,000행 완료, 18.5초 |
| B 중단 | 25% 보고 뒤 멈춰 → 상태 → 중단 → 중단 버튼 | CUST 100,000 남고 ORDERS 0건으로 롤백 제약조건, 뷰, 권한 생성은 건너뜀 |
| C 연결 끊김 | 25% 보고 직후 서버에서 COPY 세션 강제 종료 → 다시 시도 버튼 | the connection is lost 질문, 다시 연결 후 ORDERS를 처음부터 다시 적재, 최종 CUST 100,000 / ORDERS 1,000,000 |
시나리오 C에서 수업 자료가 일부러 세션을 끊은 명령:
sudo -u postgres psql -c "select pid, pg_terminate_backend(pid) from pg_stat_activity where datname = '<DB_NAME>' and usename = '<USERNAME>' and query ilike 'copy%';"결과 해석: t가 나오면 그 세션을 끊은 것이고, (0 rows)면 COPY가 이미 끝났거나 아직 시작하지 않은 것임
프로그램에는 the connection is lost로 보이며, 실습에서는 네트워크 단절이나 DB 재시작과 같은 상황이라고 설명함
장애 재현용이므로 실습 DB에서만 씀
세션 종료 자체는 세션 종료와 영향에 있음
중단, 재시도 뒤 건수 확인:
psql -h localhost -U <USERNAME> <DB_NAME> -c "select (select count(*) from <SCHEMA>.cust) as cust, (select count(*) from <SCHEMA>.orders) as orders;"결과 해석: 개별 실행 출력은 기재 없음
#사용 조건과 주의사항
토큰이 노출되면 BotFather에서 /revoke로 새 토큰을 받고 저장 명령을 다시 실행함
한 봇의 메시지는 먼저 가져간 프로그램 하나만 받음
다른 프로그램과 같은 봇을 쓰면 명령이 가끔 먹히지 않으므로 이행 전용 봇을 만듦
멈춤은 적재 트랜잭션을 연 채로 기다림
오래 멈출 일이면 중단하고 나중에 다시 이행함
열린 트랜잭션이 대상 DB에 주는 영향은 기재 없음
실습 시나리오의 끝 보고는 DDL 성공 6/6인데, 실습에서는 이것이 권한 이행을 넣기 전 기록이고 권한까지 옮기면 16/16이라고 밝혔음
시나리오 A의 ORDERS 적재 시간(17.2초)은 4단계(3.8초)보다 긺
연습 설정의 배치 크기와 중간 멈춤이 달라서이며 두 값을 같은 조건의 성능으로 비교하지 않음