매우 빠른 시간 안에 csv 파일을 db에 import 하기 위한 명령어인 LOAD DATA INFILE 명령어에서 LOCAL 키워드를 붙여야 하는 상황과 붙이지 않아도 되는 상황에 대해서 알아보려고 합니다.
LOCAL 키워드 필요 유무를 알기 위해서는 DB Client와 Server에 대해 숙지하고 있어야 합니다. 본론으로 넘어가기 전에 DB Client/Server의 개념에 대해 간략하게 먼저 설명드리겠습니다.
MariaDB Server/Client
- MariaDB Server: DB를 실제로 실행하고 데이터를 저장/관리하는 프로그램 (mysqld 프로세스)
- MariaDB Client: DB 서버에 접속해서 명령어(SQL)를 보내는 프로그램 (mysql, mariadb, JDBC, Workbench)
mysql -u{username} -p {password} 와 같이 명령을 통해 Server에 접속하기 위한 매개체는 Client가 되고, 실제 서버에서 mysqld 프로세스를 통해 CRUD 쿼리를 날리기 위한 매개체는 Server가 됩니다.
LOAD DATA INFILE과 LOAD DATA LOCAL INFILE은 Client, Server의 역할에 따라 결정됩니다.
MariaDB 공식 문서에 따르면 LOCAL 키워드를 명시하는 경우와 그렇지 않은 경우에 대해 다음과 같이 설명합니다.
(https://dev.mysql.com/doc/refman/8.0/en/load-data.html)
input File Location These rules determine the LOAD DATA input file location:
로컬 키워드를 명시하지 않을 경우 (LOCAL X)
If LOCAL is not specified, the file must be located on the server host. The server reads the file directly, locating it as follows:
If the file name is an absolute path name, the server uses it as given.
If the file name is a relative path name with leading components, the server looks for the file relative to its data directory.
If the file name has no leading components, the server looks for the file in the database directory of the default database.
- 로컬을 명시하지 않으면, 파일은 반드시 DB 서버가 설치된 컴퓨터에 있어야 합니다.
- 파일 경로가 절대 경로라면, 서버가 그 경로를 그대로 접근합니다.
- 파일 경로가 상대 경로고 디렉터리 경로가 포함되어 있다면, 자신의 데이터 디렉터리를 기준으로 경로를 해석합니다.
로컬 키워드를 명시할 경우 (LOCAL O)
If LOCAL is specified, the file must be located on the client host. The client program reads the file, locating it as follows:
If the file name is an absolute path name, the client program uses it as given.
If the file name is a relative path name, the client program looks for the file relative to its invocation directory.
- 클라이언트가 파일을 읽어서 서버로 전송합니다. (client → sever)
- local이 붙으면, 파일은 클라이언트에 있어야 합니다.
LOAD DATA INFILE vs LOAD DATA LOCAL INFILE
- LOAD DATA INFILE: Maria DB 서버가 직접 파일을 읽습니다.
- LOAD DATA LOCAL INFILE: 클라이언트 프로그램이 파일을 읽고, 서버에게 전송합니다.
구분 | 누가 파일을 읽냐 | 파일은 어디에 있어야 하는가 |
LOAD DATA INFILE | 서버(mysqld) | 서버 머신의 디스크 |
LOAD DATA LOCAL INFILE | 클라이언트 (mysql, CLI, 애플리케이션) | 클라이언트의 디스크 |
이제 LOCAL 키워드를 언제 사용해야 하는지에 대한 감은 잡히지만, 실제 사용 여부는 어떤 환경에서 명령을 실행하느냐에 따라 달라질 수 있습니다. 다양한 환경에서의 예를 들어 하나씩 설명드리겠습니다.
1. 서버 안에서 접속해서 실행 (SSH 접속 등) (클라이언트, 서버가 한 머신에 모두 들어간 경우)
ssh로 서버에 접속한 경우, MariaDB-Client, Server가 한 머신에 들어가 있습니다.
[root@localhost project]# rpm -qa | grap -i MariaDB
MariaDB-common-10.3.39-1.el8.x86_64
MariaDB-shared-10.3.39-1.el8.x86_64
MariaDB-client-10.3.39-1.el8.x86_64
MariaDB-server-10.3.39-1.el8.x86_64
ssh ubuntu@서버주소
mysql -u root -p
LOAD DATA INFILE '/path/file.csv' INTO TABLE my_table;
- 파일도 서버에 있으니까 LOCAL 명령어가 필요 없습니다.
- MySQL 클라이언트가 DB 서버와 같은 머신에서 실행되기 때문입니다.
- 클라이언트와 서버가 동일한 환경이기 때문입니다.
- 파일이 서버에 존재하면, LOCAL을 제거해줘도 상관없고, 붙여도 상관없습니다.
- LOCAL 붙일 경우: mysql --local-infile=1 -u root -p (—local-infile=1 옵션 필수)
- 클라이언트가 파일을 읽고 서버로 전송합니다.
2. 로컬 PC에서 실행 (CLI 또는 Workbench, JDBC) (클라이언트, 서버가 한 머신에 모두 들어가 있지 않은 경우)
mysql -h 서버주소 -u user -p
LOAD DATA LOCAL INFILE 'file.csv' INTO TABLE my_table;
- 이때는 클라이언트 = PC가 됩니다.
- 파일도 PC에 있으니까 LOCAL이 반드시 필요합니다.
- 서버에는 파일이 없기 때문에 Local 없이 하면 실패합니다.
- 클라이언트가 파일을 읽어와 서버로 전송합니다.
3. DB Cluster 구조에서 load data 명령어를 사용할 경우 (LOCAL 키워드 사용 권장, ChatGPT 참고)
┌────────────┐ ┌────────────┐
│ App Server │ ─────► │ DB Cluster │
└────────────┘ └────────────┘
▲
┌────────────┴────────────────┐
│DB 1 (Node-1, Primary/Master)│
│DB 2 (Node-2, Replica/Slave) │
│DB 3 (Node-3, Replica/Slave) │ │
└─────────────────────────────┘
[App Server]
│
┌───────▼────────┐
│ DB Cluster │ ← 하나처럼 보이지만 실제론 여러 DB 서버가 동작
└─────┬──────┬───┘
│ │
[Node 1] [Node 2] ← MariaDB/MySQL 서버들 (Primary/Replica 등)
LOAD DATA LOCAL INFILE 'file.csv' INTO TABLE my_table;
- App이 직접 file.csv을 열어서 binary로 파일을 읽은 후 연결된 DB에 전송합니다.
- 클러스터 구조와 무관하게 항상 안전하게 동작합니다.
- 노드 선택 불확실성 제거: LOCAL은 클라이언트가 데이터를 직접 전송하므로 실행 노드가 중요하지 않습니다.
- 클러스터 환경 이식성 확보: App만 있으면, 어떤 노드와 연결되든 성공 가능성이 올라갑니다.
<참고 자료>
LOAD DATA INFILE | MariaDB Documentation
mariadb.com
https://dev.mysql.com/doc/refman/8.0/en/load-data.html
MySQL :: MySQL 8.0 Reference Manual :: 15.2.9 LOAD DATA Statement
15.2.9 LOAD DATA Statement LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name' [REPLACE | IGNORE] INTO TABLE tbl_name [PARTITION (partition_name [, partition_name] ...)] [CHARACTER SET charset_name] [{FIELDS | COLUMNS} [TERMINATED BY 'string'
dev.mysql.com
'Database' 카테고리의 다른 글
[DB] DB 형상관리를 위한 Flyway 적용 (0) | 2025.01.07 |
---|---|
[DB] MySQL Replication, Garela Cluster (0) | 2023.09.21 |
[DB] MariaDB, MySQL 비교 (0) | 2023.09.20 |
[DB] Redis란 무엇인가? (0) | 2023.09.08 |