connect ECONNREFUSED ::1:3306
--------------------
at Protocol.Object.<anonymous>.Protocol._enqueue (node_modules/mysql/lib/protocol/Protocol.js:144:48)
at Protocol.handshake (node_modules/mysql/lib/protocol/Protocol.js:51:23)
at PoolConnection.connect (node_modules/mysql/lib/Connection.js:116:18)
at Pool.Object.<anonymous>.Pool.getConnection (node_modules/mysql/lib/Pool.js:48:16)
at src/driver/mysql/MysqlDriver.ts:1248:18
at MysqlDriver.createPool (src/driver/mysql/MysqlDriver.ts:1245:16)
at MysqlDriver.connect (src/driver/mysql/MysqlDriver.ts:393:36)
at DataSource.initialize (src/data-source/DataSource.ts:243:27)
at Object.initialize (tests/user.test.js:12:20)
Node.js 로 유닛테스트를 만드려고 시도하던 중 위와 같은 에러를 만나게 되었다.
분명 DataSource 를 생성할 때 db 정보를 제대로 입력하고 오타도 없었는데 왜 테스트 코트에서
DB Connection 이 연결되지 않는지 의문점이 생겼다.
.env 와 .env.test 에서 환경변수로 불러오는 값을 확인해 봤다.
그리고 터미널에서 mysql 에 접속해봤다. 정상적으로 접속이 되어서 환경변수와 오타문제는 아니라고
판단하였다.
그러던 중 에러 메세지를 이용해 구글링해서 해결책을 찾았다.
localhost는 루프백 호스팅으로 본인의 컴퓨터를 나타내고 ip로 변환될 때 127.0.0.1(IPv4) 혹은
::1 (IPv6) 로 변환된다.
MySQL 에 연결하는 방법은 두 가지가 있는데
1. 하나는 Unix socket file 을 이용하는 것
2. 하나는 TCP/IP 를 이용하는 것.
Unix Socke file 을 이용하는 방법이 더 빠르지만 DB 와 서버가 같은 컴퓨터 내에 있어야 한다.
MySQL 에서 hostname 을 특정하지 않거나 localhost 를 사용하면 Unix socket file 을 이용해 연결한다.
따라서 이 부분에서 TypeORM 에서 host 를 localhost 로 하였고 socket file path 를 지정하지 않아 생긴 문제였다.
const db = new DataSource({
type : "mysql",
host : "localhost",
port : "3306",
username : "root",
password : "1234",
database : "testDB",
extra : {
socketPath : "/tmp/mysql.sock"
}
})
위 코드와 같이 extra 키 값에 객체 형태로 socketPath 를 지정해주면 된다
Mac 에서는 mysql socke file path 는 /tmp/mysql.sock 이므로 위와 같이 지정해 주었고
mysqladmin -u root -p variables | grep socket
명령어로 socket file path 를 확인 할 수 있다.
::1 은 0.0.0.0.0.1 의 약어이다.
즉 IPv6 형태를 가리키는 숫자이고
IPv6 로 표기된 IP address 의 localhost 는 0.0.0.0.0.1 이고
이걸 축약하여 ::1 로 표현한다.