OGG revisó este gist . Ir a la revisión
1 file changed, 65 insertions, 68 deletions
shp2pgsql_remote.md
| @@ -16,12 +16,13 @@ chmod 600 ~/.pgpass | |||
| 16 | 16 | ```sh | |
| 17 | 17 | #!/bin/bash | |
| 18 | 18 | ||
| 19 | - | HOST="hostName" # 실제 호스트 이름으로 변경 | |
| 20 | - | PORT="portNumber" # 실제 호스트 이름으로 변경 | |
| 21 | - | DB="dbName" # 실제 데이터베이스 이름으로 변경 | |
| 22 | - | USER="postgres" # 실제 PostgreSQL 사용자명으로 변경 | |
| 23 | - | SCHEMA="schemaName" # 스키마 이름 | |
| 24 | - | TABLE="tableName" # 생성할 테이블 이름 | |
| 19 | + | # 설정 변수들 | |
| 20 | + | HOST="localhost" # 실제 호스트 이름으로 변경 | |
| 21 | + | PORT="5432" # 실제 포트 번호로 변경 | |
| 22 | + | DB="postgres" # 실제 데이터베이스 이름으로 변경 | |
| 23 | + | USER="postgres" # 실제 PostgreSQL 사용자명으로 변경 | |
| 24 | + | SCHEMA="public" # 스키마 이름 | |
| 25 | + | TABLE="shp_import" # 생성할 테이블 이름 | |
| 25 | 26 | ||
| 26 | 27 | # 대소문자 구분 문제 해결을 위해 소문자로 변환 | |
| 27 | 28 | SCHEMA_LOWER=$(echo "$SCHEMA" | tr '[:upper:]' '[:lower:]') | |
| @@ -44,11 +45,68 @@ logger() { | |||
| 44 | 45 | echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" | |
| 45 | 46 | } | |
| 46 | 47 | ||
| 48 | + | # job control 함수 정의 | |
| 49 | + | wait_for_jobs() { | |
| 50 | + | while (( $(jobs -rp | wc -l) >= MAX_JOBS )); do | |
| 51 | + | sleep 1 | |
| 52 | + | done | |
| 53 | + | } | |
| 54 | + | ||
| 55 | + | # import_append 함수 정의 | |
| 56 | + | import_append() { | |
| 57 | + | SHP="$1" | |
| 58 | + | BASENAME=$(basename "$SHP") | |
| 59 | + | ||
| 60 | + | # 처리 시작 시간 기록 | |
| 61 | + | FILE_START_TIME=$(date '+%Y-%m-%d %H:%M:%S') | |
| 62 | + | FILE_START_TIMESTAMP=$(date +%s) | |
| 63 | + | ||
| 64 | + | logger "🚀 [시작] $BASENAME 처리 시작: $FILE_START_TIME" | |
| 65 | + | ||
| 66 | + | # 좌표변환 여부에 따라 shp2pgsql 명령어 결정 | |
| 67 | + | if [ "$SRID_NEW" -ne 0 ]; then | |
| 68 | + | OUTPUT=$(shp2pgsql -W "$CHARSET" -s $SRID_ORI:$SRID_NEW -a "$SHP" $SCHEMA_LOWER.$TABLE_LOWER | psql -h $HOST -p $PORT -U "$USER" -d "$DB" 2>&1) | |
| 69 | + | else | |
| 70 | + | OUTPUT=$(shp2pgsql -W "$CHARSET" -s $SRID_ORI -a "$SHP" $SCHEMA_LOWER.$TABLE_LOWER | psql -h $HOST -p $PORT -U "$USER" -d "$DB" 2>&1) | |
| 71 | + | fi | |
| 72 | + | EXIT_CODE=$? | |
| 73 | + | ||
| 74 | + | # 처리 종료 시간 기록 | |
| 75 | + | FILE_END_TIME=$(date '+%Y-%m-%d %H:%M:%S') | |
| 76 | + | FILE_END_TIMESTAMP=$(date +%s) | |
| 77 | + | FILE_DURATION=$((FILE_END_TIMESTAMP - FILE_START_TIMESTAMP)) | |
| 78 | + | ||
| 79 | + | # 파일별 소요시간을 시:분:초 형식으로 변환 | |
| 80 | + | FILE_HOURS=$((FILE_DURATION / 3600)) | |
| 81 | + | FILE_MINUTES=$(((FILE_DURATION % 3600) / 60)) | |
| 82 | + | FILE_SECONDS=$((FILE_DURATION % 60)) | |
| 83 | + | ||
| 84 | + | # 1보다 작으면 0으로 표시 | |
| 85 | + | if [ $FILE_HOURS -lt 1 ]; then FILE_HOURS=0; fi | |
| 86 | + | if [ $FILE_MINUTES -lt 1 ]; then FILE_MINUTES=0; fi | |
| 87 | + | ||
| 88 | + | if [ $EXIT_CODE -eq 0 ]; then | |
| 89 | + | logger "✅ [완료] $BASENAME 처리 완료: $FILE_END_TIME (소요: ${FILE_HOURS}시간 ${FILE_MINUTES}분 ${FILE_SECONDS}초)" | |
| 90 | + | else | |
| 91 | + | logger "❌ [실패] $BASENAME 처리 실패: $FILE_END_TIME (소요: ${FILE_HOURS}시간 ${FILE_MINUTES}분 ${FILE_SECONDS}초)" | |
| 92 | + | ||
| 93 | + | # 오류 메시지만 추출하여 로그에 기록 | |
| 94 | + | ERROR_MSG=$(echo "$OUTPUT" | grep -E "(ERROR|FATAL|WARNING|오류|실패|실패했습니다)" || echo "$OUTPUT") | |
| 95 | + | if [ -n "$ERROR_MSG" ]; then | |
| 96 | + | logger "⚠️ 오류 내용: $ERROR_MSG" | |
| 97 | + | echo "=== $BASENAME 처리 오류 상세 내용 ===" >> "$LOG_FILE" | |
| 98 | + | echo "$OUTPUT" >> "$LOG_FILE" | |
| 99 | + | echo "=====================================" >> "$LOG_FILE" | |
| 100 | + | fi | |
| 101 | + | ||
| 102 | + | logger "🔄 다음 파일 처리를 계속 진행합니다." | |
| 103 | + | fi | |
| 104 | + | } | |
| 105 | + | ||
| 47 | 106 | # 시작 시간 기록 | |
| 48 | 107 | START_TIME=$(date '+%Y-%m-%d %H:%M:%S') | |
| 49 | 108 | START_TIMESTAMP=$(date +%s) | |
| 50 | 109 | ||
| 51 | - | ||
| 52 | 110 | # SHP 디렉토리 및 파일 존재 확인 | |
| 53 | 111 | if [ ! -d "$SHP_DIR" ]; then | |
| 54 | 112 | logger "❌ 오류: SHP 디렉토리가 존재하지 않습니다: $SHP_DIR" | |
| @@ -175,67 +233,6 @@ else | |||
| 175 | 233 | fi | |
| 176 | 234 | fi | |
| 177 | 235 | ||
| 178 | - | # 2. 병렬로 나머지 파일 append (shp2pgsql -a) | |
| 179 | - | function import_append() { | |
| 180 | - | SHP="$1" | |
| 181 | - | BASENAME=$(basename "$SHP") | |
| 182 | - | ||
| 183 | - | # 처리 시작 시간 기록 | |
| 184 | - | FILE_START_TIME=$(date '+%Y-%m-%d %H:%M:%S') | |
| 185 | - | FILE_START_TIMESTAMP=$(date +%s) | |
| 186 | - | ||
| 187 | - | logger "🚀 [시작] $BASENAME 처리 시작: $FILE_START_TIME" | |
| 188 | - | ||
| 189 | - | # 좌표변환 여부에 따라 shp2pgsql 명령어 결정 | |
| 190 | - | if [ "$SRID_NEW" -ne 0 ]; then | |
| 191 | - | OUTPUT=$(shp2pgsql -W "$CHARSET" -s $SRID_ORI:$SRID_NEW -a "$SHP" $SCHEMA_LOWER.$TABLE_LOWER | psql -h $HOST -p $PORT -U "$USER" -d "$DB" 2>&1) | |
| 192 | - | else | |
| 193 | - | OUTPUT=$(shp2pgsql -W "$CHARSET" -s $SRID_ORI -a "$SHP" $SCHEMA_LOWER.$TABLE_LOWER | psql -h $HOST -p $PORT -U "$USER" -d "$DB" 2>&1) | |
| 194 | - | fi | |
| 195 | - | EXIT_CODE=$? | |
| 196 | - | ||
| 197 | - | # 처리 종료 시간 기록 | |
| 198 | - | FILE_END_TIME=$(date '+%Y-%m-%d %H:%M:%S') | |
| 199 | - | FILE_END_TIMESTAMP=$(date +%s) | |
| 200 | - | FILE_DURATION=$((FILE_END_TIMESTAMP - FILE_START_TIMESTAMP)) | |
| 201 | - | ||
| 202 | - | # 파일별 소요시간을 시:분:초 형식으로 변환 | |
| 203 | - | FILE_HOURS=$((FILE_DURATION / 3600)) | |
| 204 | - | FILE_MINUTES=$(((FILE_DURATION % 3600) / 60)) | |
| 205 | - | FILE_SECONDS=$((FILE_DURATION % 60)) | |
| 206 | - | ||
| 207 | - | # 1보다 작으면 0으로 표시 | |
| 208 | - | if [ $FILE_HOURS -lt 1 ]; then FILE_HOURS=0; fi | |
| 209 | - | if [ $FILE_MINUTES -lt 1 ]; then FILE_MINUTES=0; fi | |
| 210 | - | ||
| 211 | - | if [ $EXIT_CODE -eq 0 ]; then | |
| 212 | - | logger "✅ [완료] $BASENAME 처리 완료: $FILE_END_TIME (소요: ${FILE_HOURS}시간 ${FILE_MINUTES}분 ${FILE_SECONDS}초)" | |
| 213 | - | else | |
| 214 | - | logger "❌ [실패] $BASENAME 처리 실패: $FILE_END_TIME (소요: ${FILE_HOURS}시간 ${FILE_MINUTES}분 ${FILE_SECONDS}초)" | |
| 215 | - | ||
| 216 | - | # 오류 메시지만 추출하여 로그에 기록 | |
| 217 | - | ERROR_MSG=$(echo "$OUTPUT" | grep -E "(ERROR|FATAL|WARNING|오류|실패|실패했습니다)" || echo "$OUTPUT") | |
| 218 | - | if [ -n "$ERROR_MSG" ]; then | |
| 219 | - | logger "⚠️ 오류 내용: $ERROR_MSG" | |
| 220 | - | echo "=== $BASENAME 처리 오류 상세 내용 ===" >> "$LOG_FILE" | |
| 221 | - | echo "$OUTPUT" >> "$LOG_FILE" | |
| 222 | - | echo "=====================================" >> "$LOG_FILE" | |
| 223 | - | fi | |
| 224 | - | ||
| 225 | - | logger "🔄 다음 파일 처리를 계속 진행합니다." | |
| 226 | - | fi | |
| 227 | - | } | |
| 228 | - | ||
| 229 | - | # job control 함수 | |
| 230 | - | function wait_for_jobs() { | |
| 231 | - | while (( $(jobs -rp | wc -l) >= MAX_JOBS )); do | |
| 232 | - | sleep 1 | |
| 233 | - | done | |
| 234 | - | } | |
| 235 | - | ||
| 236 | - | # 병렬 처리는 이미 위에서 완료되었습니다. | |
| 237 | - | logger "🔄 병렬 처리 완료" | |
| 238 | - | ||
| 239 | 236 | # 데이터 입력 완료 시간 기록 | |
| 240 | 237 | DATA_END_TIME=$(date '+%Y-%m-%d %H:%M:%S') | |
| 241 | 238 | DATA_END_TIMESTAMP=$(date +%s) | |
OGG revisó este gist . Ir a la revisión
1 file changed, 316 insertions
shp2pgsql_remote.md(archivo creado)
| @@ -0,0 +1,316 @@ | |||
| 1 | + | 원격서버에 적재시 .pgpass파일이 필요 | |
| 2 | + | ```bash | |
| 3 | + | nano ~/.pgpass | |
| 4 | + | ``` | |
| 5 | + | .pgpass파일에 다음 형식으로 작성 | |
| 6 | + | ```pgsql | |
| 7 | + | hostname:port:database:username:password | |
| 8 | + | ``` | |
| 9 | + | 이후 퍼미션 설정 필수 | |
| 10 | + | ```bash | |
| 11 | + | chmod 600 ~/.pgpass | |
| 12 | + | ``` | |
| 13 | + | ||
| 14 | + | ||
| 15 | + | 이후 sh파일 작성 | |
| 16 | + | ```sh | |
| 17 | + | #!/bin/bash | |
| 18 | + | ||
| 19 | + | HOST="hostName" # 실제 호스트 이름으로 변경 | |
| 20 | + | PORT="portNumber" # 실제 호스트 이름으로 변경 | |
| 21 | + | DB="dbName" # 실제 데이터베이스 이름으로 변경 | |
| 22 | + | USER="postgres" # 실제 PostgreSQL 사용자명으로 변경 | |
| 23 | + | SCHEMA="schemaName" # 스키마 이름 | |
| 24 | + | TABLE="tableName" # 생성할 테이블 이름 | |
| 25 | + | ||
| 26 | + | # 대소문자 구분 문제 해결을 위해 소문자로 변환 | |
| 27 | + | SCHEMA_LOWER=$(echo "$SCHEMA" | tr '[:upper:]' '[:lower:]') | |
| 28 | + | TABLE_LOWER=$(echo "$TABLE" | tr '[:upper:]' '[:lower:]') | |
| 29 | + | ||
| 30 | + | SRID_ORI=5186 # 원본 좌표계 | |
| 31 | + | SRID_NEW=0 # 변환 좌표계 (0이면 좌표변환 안함) | |
| 32 | + | CHARSET="UTF-8" # 문자 인코딩 | |
| 33 | + | ||
| 34 | + | SHP_DIR="./" # shp 파일들이 있는 디렉토리 경로 | |
| 35 | + | MAX_JOBS=8 # 병렬 작업 수 (시스템 성능에 따라 조정) | |
| 36 | + | ||
| 37 | + | # 로그 파일 설정 | |
| 38 | + | LOG_DIR="./" # 로그 디렉토리 (필요시 경로 변경) | |
| 39 | + | mkdir -p "$LOG_DIR" # 로그 디렉토리가 없으면 생성 | |
| 40 | + | LOG_FILE="$LOG_DIR/shp_import_$(date '+%Y%m%d_%H%M%S').log" | |
| 41 | + | ||
| 42 | + | # 로그 함수 정의 | |
| 43 | + | logger() { | |
| 44 | + | echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" | |
| 45 | + | } | |
| 46 | + | ||
| 47 | + | # 시작 시간 기록 | |
| 48 | + | START_TIME=$(date '+%Y-%m-%d %H:%M:%S') | |
| 49 | + | START_TIMESTAMP=$(date +%s) | |
| 50 | + | ||
| 51 | + | ||
| 52 | + | # SHP 디렉토리 및 파일 존재 확인 | |
| 53 | + | if [ ! -d "$SHP_DIR" ]; then | |
| 54 | + | logger "❌ 오류: SHP 디렉토리가 존재하지 않습니다: $SHP_DIR" | |
| 55 | + | exit 1 | |
| 56 | + | fi | |
| 57 | + | ||
| 58 | + | SHP_COUNT=$(find "$SHP_DIR" -name "*.shp" | wc -l) | |
| 59 | + | if [ $SHP_COUNT -eq 0 ]; then | |
| 60 | + | logger "❌ 오류: SHP 파일이 없습니다: $SHP_DIR" | |
| 61 | + | exit 1 | |
| 62 | + | fi | |
| 63 | + | logger "📁 발견된 SHP 파일 수: $SHP_COUNT개" | |
| 64 | + | ||
| 65 | + | # 필수 변수 검증 | |
| 66 | + | if [ -z "$DB" ]; then | |
| 67 | + | logger "❌ 오류: DB 변수가 설정되지 않았습니다. 스크립트 상단에서 DB 변수를 설정해주세요." | |
| 68 | + | exit 1 | |
| 69 | + | fi | |
| 70 | + | ||
| 71 | + | if [ -z "$TABLE" ]; then | |
| 72 | + | logger "❌ 오류: TABLE 변수가 설정되지 않았습니다. 스크립트 상단에서 TABLE 변수를 설정해주세요." | |
| 73 | + | exit 1 | |
| 74 | + | fi | |
| 75 | + | ||
| 76 | + | logger "📋 설정된 변수:" | |
| 77 | + | logger " - 데이터베이스: $DB" | |
| 78 | + | logger " - 사용자: $USER" | |
| 79 | + | logger " - 스키마: $SCHEMA" | |
| 80 | + | logger " - 테이블: $TABLE" | |
| 81 | + | ||
| 82 | + | # PostgreSQL 연결 테스트 | |
| 83 | + | if ! psql -h $HOST -p $PORT -U "$USER" -d "$DB" -c "SELECT 1;" >/dev/null 2>&1; then | |
| 84 | + | logger "❌ 오류: PostgreSQL 연결 실패. 데이터베이스 연결을 확인해주세요." | |
| 85 | + | exit 1 | |
| 86 | + | fi | |
| 87 | + | logger "✅ PostgreSQL 연결 성공" | |
| 88 | + | ||
| 89 | + | # 좌표계 설정 확인 및 로깅 | |
| 90 | + | if [ "$SRID_NEW" -ne 0 ]; then | |
| 91 | + | logger "🗺️ 좌표변환 모드: $SRID_ORI → $SRID_NEW" | |
| 92 | + | else | |
| 93 | + | logger "🗺️ 원본좌표계 사용: $SRID_ORI" | |
| 94 | + | fi | |
| 95 | + | ||
| 96 | + | logger "==================================" | |
| 97 | + | logger "🚀 Import 시작: $START_TIME" | |
| 98 | + | logger "==================================" | |
| 99 | + | ||
| 100 | + | # 테이블 존재 여부 확인 | |
| 101 | + | logger "🔍 테이블 존재 여부 확인 중: $SCHEMA_LOWER.$TABLE_LOWER" | |
| 102 | + | ||
| 103 | + | # 테이블 존재 여부를 더 안정적으로 확인 (소문자로 비교) | |
| 104 | + | TABLE_EXISTS=$(psql -h $HOST -p $PORT -U "$USER" -d "$DB" -t -c "SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_schema = '$SCHEMA_LOWER' AND table_name = '$TABLE_LOWER');" 2>/dev/null | xargs) | |
| 105 | + | ||
| 106 | + | logger "🔍 테이블 존재 확인 결과: '$TABLE_EXISTS'" | |
| 107 | + | ||
| 108 | + | # 모든 SHP 파일을 배열로 수집 | |
| 109 | + | SHP_FILES=($(find "$SHP_DIR" -name "*.shp" | sort)) | |
| 110 | + | TOTAL_FILES=${#SHP_FILES[@]} | |
| 111 | + | ||
| 112 | + | if [ "$TABLE_EXISTS" = "t" ]; then | |
| 113 | + | logger "📋 테이블 $SCHEMA_LOWER.$TABLE_LOWER이 이미 존재합니다. Append 모드로 진행합니다." | |
| 114 | + | logger "🔄 총 $TOTAL_FILES개 파일을 append 모드로 처리합니다..." | |
| 115 | + | ||
| 116 | + | # 모든 파일을 append 모드로 처리 | |
| 117 | + | for shp in "${SHP_FILES[@]}"; do | |
| 118 | + | wait_for_jobs | |
| 119 | + | import_append "$shp" & | |
| 120 | + | done | |
| 121 | + | wait | |
| 122 | + | else | |
| 123 | + | logger "📋 테이블 $SCHEMA_LOWER.$TABLE_LOWER이 존재하지 않습니다. 새로 생성합니다." | |
| 124 | + | logger "🔄 총 $TOTAL_FILES개 파일을 처리합니다..." | |
| 125 | + | ||
| 126 | + | # 첫 번째 파일로 테이블 생성 | |
| 127 | + | FIRST_FILE="${SHP_FILES[0]}" | |
| 128 | + | FIRST_BASENAME=$(basename "$FIRST_FILE") | |
| 129 | + | ||
| 130 | + | # 테이블 생성 시작 시간 기록 | |
| 131 | + | TABLE_START_TIME=$(date '+%Y-%m-%d %H:%M:%S') | |
| 132 | + | TABLE_START_TIMESTAMP=$(date +%s) | |
| 133 | + | ||
| 134 | + | logger "🚀 [시작] 테이블 생성 시작: $FIRST_BASENAME - $TABLE_START_TIME" | |
| 135 | + | ||
| 136 | + | # 좌표변환 여부에 따라 shp2pgsql 명령어 결정 | |
| 137 | + | if [ "$SRID_NEW" -ne 0 ]; then | |
| 138 | + | OUTPUT=$(shp2pgsql -W "$CHARSET" -s $SRID_ORI:$SRID_NEW "$FIRST_FILE" $SCHEMA_LOWER.$TABLE_LOWER | psql -h $HOST -p $PORT -U "$USER" -d "$DB" 2>&1) | |
| 139 | + | else | |
| 140 | + | OUTPUT=$(shp2pgsql -W "$CHARSET" -s $SRID_ORI "$FIRST_FILE" $SCHEMA_LOWER.$TABLE_LOWER | psql -h $HOST -p $PORT -U "$USER" -d "$DB" 2>&1) | |
| 141 | + | fi | |
| 142 | + | EXIT_CODE=$? | |
| 143 | + | ||
| 144 | + | # 테이블 생성 종료 시간 기록 | |
| 145 | + | TABLE_END_TIME=$(date '+%Y-%m-%d %H:%M:%S') | |
| 146 | + | TABLE_END_TIMESTAMP=$(date +%s) | |
| 147 | + | TABLE_DURATION=$((TABLE_END_TIMESTAMP - TABLE_START_TIMESTAMP)) | |
| 148 | + | ||
| 149 | + | # 테이블 생성 소요시간을 시:분:초 형식으로 변환 | |
| 150 | + | TABLE_HOURS=$((TABLE_DURATION / 3600)) | |
| 151 | + | TABLE_MINUTES=$(((TABLE_DURATION % 3600) / 60)) | |
| 152 | + | TABLE_SECONDS=$((TABLE_DURATION % 60)) | |
| 153 | + | ||
| 154 | + | # 1보다 작으면 0으로 표시 | |
| 155 | + | if [ $TABLE_HOURS -lt 1 ]; then TABLE_HOURS=0; fi | |
| 156 | + | if [ $TABLE_MINUTES -lt 1 ]; then TABLE_MINUTES=0; fi | |
| 157 | + | ||
| 158 | + | if [ $EXIT_CODE -eq 0 ]; then | |
| 159 | + | logger "✅ [완료] 테이블 생성 완료: $TABLE_END_TIME (소요: ${TABLE_HOURS}시간 ${TABLE_MINUTES}분 ${TABLE_SECONDS}초)" | |
| 160 | + | ||
| 161 | + | # 나머지 파일들을 append 모드로 처리 | |
| 162 | + | if [ $TOTAL_FILES -gt 1 ]; then | |
| 163 | + | logger "🔄 나머지 $((TOTAL_FILES - 1))개 파일을 append 모드로 처리합니다..." | |
| 164 | + | for ((i=1; i<TOTAL_FILES; i++)); do | |
| 165 | + | shp="${SHP_FILES[i]}" | |
| 166 | + | wait_for_jobs | |
| 167 | + | import_append "$shp" & | |
| 168 | + | done | |
| 169 | + | wait | |
| 170 | + | fi | |
| 171 | + | else | |
| 172 | + | logger "❌ [실패] 테이블 생성 실패: $TABLE_END_TIME (소요: ${TABLE_HOURS}시간 ${TABLE_MINUTES}분 ${TABLE_SECONDS}초)" | |
| 173 | + | echo "$OUTPUT" >> "$LOG_FILE" | |
| 174 | + | exit 1 | |
| 175 | + | fi | |
| 176 | + | fi | |
| 177 | + | ||
| 178 | + | # 2. 병렬로 나머지 파일 append (shp2pgsql -a) | |
| 179 | + | function import_append() { | |
| 180 | + | SHP="$1" | |
| 181 | + | BASENAME=$(basename "$SHP") | |
| 182 | + | ||
| 183 | + | # 처리 시작 시간 기록 | |
| 184 | + | FILE_START_TIME=$(date '+%Y-%m-%d %H:%M:%S') | |
| 185 | + | FILE_START_TIMESTAMP=$(date +%s) | |
| 186 | + | ||
| 187 | + | logger "🚀 [시작] $BASENAME 처리 시작: $FILE_START_TIME" | |
| 188 | + | ||
| 189 | + | # 좌표변환 여부에 따라 shp2pgsql 명령어 결정 | |
| 190 | + | if [ "$SRID_NEW" -ne 0 ]; then | |
| 191 | + | OUTPUT=$(shp2pgsql -W "$CHARSET" -s $SRID_ORI:$SRID_NEW -a "$SHP" $SCHEMA_LOWER.$TABLE_LOWER | psql -h $HOST -p $PORT -U "$USER" -d "$DB" 2>&1) | |
| 192 | + | else | |
| 193 | + | OUTPUT=$(shp2pgsql -W "$CHARSET" -s $SRID_ORI -a "$SHP" $SCHEMA_LOWER.$TABLE_LOWER | psql -h $HOST -p $PORT -U "$USER" -d "$DB" 2>&1) | |
| 194 | + | fi | |
| 195 | + | EXIT_CODE=$? | |
| 196 | + | ||
| 197 | + | # 처리 종료 시간 기록 | |
| 198 | + | FILE_END_TIME=$(date '+%Y-%m-%d %H:%M:%S') | |
| 199 | + | FILE_END_TIMESTAMP=$(date +%s) | |
| 200 | + | FILE_DURATION=$((FILE_END_TIMESTAMP - FILE_START_TIMESTAMP)) | |
| 201 | + | ||
| 202 | + | # 파일별 소요시간을 시:분:초 형식으로 변환 | |
| 203 | + | FILE_HOURS=$((FILE_DURATION / 3600)) | |
| 204 | + | FILE_MINUTES=$(((FILE_DURATION % 3600) / 60)) | |
| 205 | + | FILE_SECONDS=$((FILE_DURATION % 60)) | |
| 206 | + | ||
| 207 | + | # 1보다 작으면 0으로 표시 | |
| 208 | + | if [ $FILE_HOURS -lt 1 ]; then FILE_HOURS=0; fi | |
| 209 | + | if [ $FILE_MINUTES -lt 1 ]; then FILE_MINUTES=0; fi | |
| 210 | + | ||
| 211 | + | if [ $EXIT_CODE -eq 0 ]; then | |
| 212 | + | logger "✅ [완료] $BASENAME 처리 완료: $FILE_END_TIME (소요: ${FILE_HOURS}시간 ${FILE_MINUTES}분 ${FILE_SECONDS}초)" | |
| 213 | + | else | |
| 214 | + | logger "❌ [실패] $BASENAME 처리 실패: $FILE_END_TIME (소요: ${FILE_HOURS}시간 ${FILE_MINUTES}분 ${FILE_SECONDS}초)" | |
| 215 | + | ||
| 216 | + | # 오류 메시지만 추출하여 로그에 기록 | |
| 217 | + | ERROR_MSG=$(echo "$OUTPUT" | grep -E "(ERROR|FATAL|WARNING|오류|실패|실패했습니다)" || echo "$OUTPUT") | |
| 218 | + | if [ -n "$ERROR_MSG" ]; then | |
| 219 | + | logger "⚠️ 오류 내용: $ERROR_MSG" | |
| 220 | + | echo "=== $BASENAME 처리 오류 상세 내용 ===" >> "$LOG_FILE" | |
| 221 | + | echo "$OUTPUT" >> "$LOG_FILE" | |
| 222 | + | echo "=====================================" >> "$LOG_FILE" | |
| 223 | + | fi | |
| 224 | + | ||
| 225 | + | logger "🔄 다음 파일 처리를 계속 진행합니다." | |
| 226 | + | fi | |
| 227 | + | } | |
| 228 | + | ||
| 229 | + | # job control 함수 | |
| 230 | + | function wait_for_jobs() { | |
| 231 | + | while (( $(jobs -rp | wc -l) >= MAX_JOBS )); do | |
| 232 | + | sleep 1 | |
| 233 | + | done | |
| 234 | + | } | |
| 235 | + | ||
| 236 | + | # 병렬 처리는 이미 위에서 완료되었습니다. | |
| 237 | + | logger "🔄 병렬 처리 완료" | |
| 238 | + | ||
| 239 | + | # 데이터 입력 완료 시간 기록 | |
| 240 | + | DATA_END_TIME=$(date '+%Y-%m-%d %H:%M:%S') | |
| 241 | + | DATA_END_TIMESTAMP=$(date +%s) | |
| 242 | + | DATA_DURATION=$((DATA_END_TIMESTAMP - START_TIMESTAMP)) | |
| 243 | + | ||
| 244 | + | # 데이터 입력 시간을 시:분:초 형식으로 변환 | |
| 245 | + | DATA_HOURS=$((DATA_DURATION / 3600)) | |
| 246 | + | DATA_MINUTES=$(((DATA_DURATION % 3600) / 60)) | |
| 247 | + | DATA_SECONDS=$((DATA_DURATION % 60)) | |
| 248 | + | ||
| 249 | + | # 1보다 작으면 0으로 표시 | |
| 250 | + | if [ $DATA_HOURS -lt 1 ]; then DATA_HOURS=0; fi | |
| 251 | + | if [ $DATA_MINUTES -lt 1 ]; then DATA_MINUTES=0; fi | |
| 252 | + | ||
| 253 | + | # 3. (선택) 인덱스 재생성 (권장: 한 번에 생성) | |
| 254 | + | INDEX_START_TIME=$(date '+%Y-%m-%d %H:%M:%S') | |
| 255 | + | INDEX_START_TIMESTAMP=$(date +%s) | |
| 256 | + | ||
| 257 | + | logger "🔍 공간 인덱스 생성 시작: $INDEX_START_TIME" | |
| 258 | + | ||
| 259 | + | # 공간 인덱스 생성 (PostGIS 확장이 활성화되어 있어야 함) | |
| 260 | + | INDEX_OUTPUT=$(psql -h $HOST -p $PORT -U "$USER" -d "$DB" -c "CREATE INDEX IF NOT EXISTS ${TABLE_LOWER}_geom_idx ON $SCHEMA_LOWER.$TABLE_LOWER USING GIST (geom);" 2>&1) | |
| 261 | + | INDEX_EXIT_CODE=$? | |
| 262 | + | ||
| 263 | + | if [ $INDEX_EXIT_CODE -eq 0 ]; then | |
| 264 | + | logger "✅ Spatial index created successfully" | |
| 265 | + | else | |
| 266 | + | logger "❌ Failed to create spatial index" | |
| 267 | + | ||
| 268 | + | # 오류 메시지만 추출하여 로그에 기록 | |
| 269 | + | INDEX_ERROR_MSG=$(echo "$INDEX_OUTPUT" | grep -E "(ERROR|FATAL|WARNING|오류|실패|실패했습니다)" || echo "$INDEX_OUTPUT") | |
| 270 | + | if [ -n "$INDEX_ERROR_MSG" ]; then | |
| 271 | + | logger "⚠️ 인덱스 생성 오류 내용: $INDEX_ERROR_MSG" | |
| 272 | + | echo "=== 공간 인덱스 생성 오류 상세 내용 ===" >> "$LOG_FILE" | |
| 273 | + | echo "$INDEX_OUTPUT" >> "$LOG_FILE" | |
| 274 | + | echo "=====================================" >> "$LOG_FILE" | |
| 275 | + | fi | |
| 276 | + | ||
| 277 | + | logger "⚠️ PostGIS 확장이 활성화되어 있는지 확인하세요: CREATE EXTENSION IF NOT EXISTS postgis;" | |
| 278 | + | logger "🔄 인덱스 생성에 실패했지만 스크립트는 계속 진행됩니다." | |
| 279 | + | fi | |
| 280 | + | ||
| 281 | + | # 인덱스 재생성 완료 시간 기록 | |
| 282 | + | INDEX_END_TIME=$(date '+%Y-%m-%d %H:%M:%S') | |
| 283 | + | INDEX_END_TIMESTAMP=$(date +%s) | |
| 284 | + | INDEX_DURATION=$((INDEX_END_TIMESTAMP - INDEX_START_TIMESTAMP)) | |
| 285 | + | ||
| 286 | + | # 인덱스 재생성 시간을 시:분:초 형식으로 변환 | |
| 287 | + | INDEX_HOURS=$((INDEX_DURATION / 3600)) | |
| 288 | + | INDEX_MINUTES=$(((INDEX_DURATION % 3600) / 60)) | |
| 289 | + | INDEX_SECONDS=$((INDEX_DURATION % 60)) | |
| 290 | + | ||
| 291 | + | # 1보다 작으면 0으로 표시 | |
| 292 | + | if [ $INDEX_HOURS -lt 1 ]; then INDEX_HOURS=0; fi | |
| 293 | + | if [ $INDEX_MINUTES -lt 1 ]; then INDEX_MINUTES=0; fi | |
| 294 | + | ||
| 295 | + | logger "==================================" | |
| 296 | + | logger "✅ 작업 완료" | |
| 297 | + | logger "📋 대상테이블: $SCHEMA_LOWER.$TABLE_LOWER" | |
| 298 | + | if [ "$SRID_NEW" -ne 0 ]; then | |
| 299 | + | logger "🗺️ 좌표계: $SRID_ORI → $SRID_NEW (변환됨)" | |
| 300 | + | else | |
| 301 | + | logger "🗺️ 좌표계: $SRID_ORI (원본)" | |
| 302 | + | fi | |
| 303 | + | logger "⏱️ 데이터 입력 소요시간: ${DATA_HOURS}시간 ${DATA_MINUTES}분 ${DATA_SECONDS}초" | |
| 304 | + | logger "⏱️ 공간 인덱스 소요시간: ${INDEX_HOURS}시간 ${INDEX_MINUTES}분 ${INDEX_SECONDS}초" | |
| 305 | + | logger "==================================" | |
| 306 | + | ``` | |
| 307 | + | ||
| 308 | + | 이후 sh파일 퍼미션 설정 | |
| 309 | + | ```bash | |
| 310 | + | chmod +x shp2pgsql.sh | |
| 311 | + | ``` | |
| 312 | + | ||
| 313 | + | sh파일 실행 | |
| 314 | + | ```bash | |
| 315 | + | ./shp2pgsql.sh | |
| 316 | + | ``` | |