2021-01-28-TIL
과제: Docker로 MySQL 설치하기
DB 설치하기
- 가상 환경을 위해서 docker를 설치한다.
- docker 기반으로 mysql server 5.7 버전을 설치한다.
- docker 명령으로 mysql 컨테이너를 실행한다.
- docker 명령으로 mysql 컨테이너에 bash로 접속한다.
- 셸 환경변수와 locale 설정을 하고, mysql config를 latin1에서 utf8로 변경한다.
- SQL 문법을 학습하고 DDL(Data Definition Language)과 DQL(Data Query Language) 예제를 연습한다.
- docker 기반으로 mysql을 설치했는지 여부를 확인할 수 있도록 터미널 또는 GUI로 접속한 화면 캡처하고 gist에 함께 저장한다.
DB 요구사항
- Database 이름을 정하고 Database를 생성한다.
- DB에 프로그램에서 연결할 User를 정하고 생성한다. 접속 권한을 설정한다.
MySQL 컨테이너 실행
순서대로 Docker 버전을 확인하고, MySQL 5.7 이미지를 받고, 받은 이미지를 확인한 뒤 컨테이너를 띄운다.
1
docker --version
1
docker pull mysql/mysql-server:5.7
1
docker images
1
docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=password --name mysql-5.7 -v /Users/ham/db_data:/var/lib/mysql mysql/mysql-server:5.7
-e MYSQL_ROOT_PASSWORD는 root 비밀번호를 지정하는 환경 변수이고, -v /Users/ham/db_data:/var/lib/mysql은 호스트 디렉터리를 컨테이너 안의 /var/lib/mysql에 마운트한다. Docker Hub의 MySQL 이미지 문서는 /var/lib/mysql이 MySQL이 기본으로 데이터 파일을 쓰는 위치라고 설명한다.
이미지 이름 뒤에 붙인 옵션은 mysqld에 그대로 전달된다. 그래서 설정 파일 없이도 아래 옵션으로 기본 인코딩과 콜레이션을 utf8mb4로 바꿀 수 있다.
1
--character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
1
docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=password --name mysql-5.7 -v /Users/ham/db_data:/var/lib/mysql mysql/mysql-server:5.7 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
컨테이너에 bash로 들어가거나, 바로 mysql 클라이언트로 접속한다.
1
docker exec -it mysql-5.7 /bin/bash
1
docker exec -it mysql-5.7 mysql -uroot -p
Q) 도커를 stop하고 이미지 삭제 후 다시 설치했는데, mysql에 이전에 생성한 DB가 그대로 있습니다. 어째서 남아있는건지 모르겠습니다.
위 docker run에는 -v /Users/ham/db_data:/var/lib/mysql이 들어 있다. Docker 문서에 따르면 바인드 마운트는 호스트의 파일이나 디렉터리를 컨테이너에 마운트하는 방식이라, 데이터 파일은 컨테이너나 이미지가 아니라 호스트의 /Users/ham/db_data에 남는다. 새 컨테이너가 같은 디렉터리를 다시 마운트했기 때문에 이전 DB가 그대로 보인 것이다.
문자셋을 UTF-8로 바꾸기
ALTER DATABASE PCbang CHARACTER SET utf8 COLLATE utf8mb4_general_ci;
CREATE DATABASE PCbang default CHARACTER SET UTF8;
SHOW DATABASES;
MySQL에서 콜레이션 이름은 연결된 문자셋 이름으로 시작한다(utf8mb4_unicode_ci는 utf8mb4의 콜레이션이다). 그래서 첫 번째 ALTER DATABASE처럼 문자셋 utf8에 utf8mb4_general_ci 콜레이션을 붙이면 둘이 맞지 않는다. 문자셋과 콜레이션은 같은 계열로 맞춰야 한다.
컨테이너 안의 설정 파일로 서버, 클라이언트, mysqldump의 기본 문자셋을 한 번에 바꾸는 방법도 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ sudo -i #root
$ cat /etc/mysql/my.cnf
$ cat << 'EOF' > /etc/my.cnf
# for utf8 characterset
[client]
default-character-set = utf8
[mysqld]
init_connect = SET collation_connection = utf8_general_ci
init_connect = SET NAMES utf8
character-set-server = utf8
collation-server = utf8_general_ci
[mysqldump]
default-character-set = utf8
[mysql]
default-character-set = utf8
EOF
사용자, 테이블, 데이터
GRANT ALL PRIVILEGES ON PCbang.* TO august@localhost IDENTIFIED BY 'password';
EXIT;
docker exec -it mysql-5.7 -u august -p
USE PCbang;
블록의 마지막 줄 docker exec -it mysql-5.7 -u august -p는 실행할 명령(mysql)이 빠져 있다. 위에서 root로 접속할 때처럼 docker exec -it mysql-5.7 mysql -u august -p로 써야 새 사용자로 접속된다.
CREATE TABLE user_log (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(32) NOT NULL,
nickname VARCHAR(64) NOT NULL,
money DECIMAL(10, 2),
last_visit DATETIME,
phone VARCHAR(12)
) ENGINE=INNODB;
ENGINE=INNODB는 테이블의 스토리지 엔진을 InnoDB로 지정한다. MySQL 문서에 따르면 InnoDB는 기본 스토리지 엔진이라 ENGINE 절 없이 CREATE TABLE을 해도 InnoDB 테이블이 만들어지고, ACID 트랜잭션(커밋, 롤백, 크래시 복구)과 행 단위 잠금을 제공한다.
INSERT INTO user_log (name, nickname, money, last_visit, phone) VALUES('Jacob', 'August', 10080.23, '2021-01-28', '01112345678');
테이블과 컬럼 이름 규칙은 SQL 이름 규칙 글을 참고했다.
Docker와 가상화
도커로 감싸서 보내면 실행되는 걸 보냈다는 증거이기 때문에, 운영자 탓을 할 수 있다.
실제로는 물리적으로 하나씩 있는 하드웨어 자원이 OS를 통해서 가상화되어 마치 여러 개 있는 것처럼 사용할 수 있게 된다.
Red Hat의 설명에서 하이퍼바이저는 물리 자원을 나눠 가상 머신들이 쓰게 하는 소프트웨어다. 반면 Docker 컨테이너는 호스트 OS 위에서 애플리케이션 단위로 동작하며 OS 커널을 공유한다. Docker는 컨테이너마다 PID, NET 같은 커널 네임스페이스를 만들어 격리하고, cgroup으로 컨테이너가 쓸 수 있는 자원을 제한한다.
44BITS 글은 도커를 써야 하는 이유로 눈송이 서버(snowflake server)를 든다. 같은 일을 하는 서버라도 운영 기록이 서로 달라 상태를 재현하기 어려운데, 컨테이너 이미지로 환경을 고정하면 이 문제를 줄일 수 있다는 설명이다.
No hard PC bang
Docker 정리 명령
1
2
3
4
5
6
7
docker stop $(docker ps -a -q) ;
docker rm $(docker ps -a -q) ;
docker rmi $(docker images -q) --force ;
docker system prune;
docker system prune --volumes;
kill -kill `lsof -t -i tcp:3000`
모든 컨테이너를 멈추고 지운 뒤 이미지를 강제로 지우고, docker system prune으로 남은 리소스를 정리하는 명령이다. 마지막 줄은 3000번 포트를 쓰는 프로세스를 찾아 종료한다.
Monolithic Architecture
모놀리식 아키텍처는 하나의 서비스나 애플리케이션을 하나의 덩어리로 만들어 배포하는 구조다. 함께 본 우아콘 2020 발표 「배달의민족 마이크로서비스 여행기」가 이 주제와 이어진다.
Java 메모
콘솔 진행 표시줄
System.out.print()로 진행률을 찍고 끝에 캐리지 리턴(\r)을 붙이면 커서가 줄 앞으로 돌아가므로, 같은 줄을 덮어쓰며 진행 상태를 보여 줄 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class ConsoleProgressBar {
public static void main(String[] args) {
char[] animationChars = new char[]{'|', '/', '-', '\\'};
for (int i = 0; i <= 100; i++) {
System.out.print("Processing: " + i + "% " + animationChars[i % 4] + "\r");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Processing: Done! ");
}
}
한 달 전 날짜와 Calendar 필드
Calendar에서는 add(Calendar.MONTH, -1)처럼 음수를 더해 한 달 전 날짜를 구한다. Calendar.DATE와 Calendar.DAY_OF_MONTH는 Javadoc에서 서로의 동의어로 정의된 같은 필드다. Java 8 이후라면 LocalDate.minusMonths(1)을 쓸 수 있고, 3월 31일에서 한 달을 빼면 존재하지 않는 2월 31일 대신 그 달의 마지막 유효한 날짜로 맞춰 준다.
랜덤 문자열 생성
Generate Random String in Java
그 밖의 메모
Boxer 에뮬레이터
페르시아 왕자 개발일지 - iphone ebook 살아서 움직임
Linux version check command
JUnit 설정
cheat sheet만 모아놓은 사이트?
참고한 자료외부 출처 37
외부 출처
- Notion 메모 1
- Notion 메모 2
- mysql/mysql-server
- mysql - Official Image
- Get started
- Docker를 통한 MySQL 설치하기.기억하기 위한 개발노트
- kjwsx23 383번 글현재 열리지 않는다
- ghojeong/gonggam-blog
- Bind mounts
- Docker Mysql 인코딩 해결
- Collation Naming Conventions
- Database Character Set and Collation
- How I Write SQL, Part 1: Naming ConventionsLaunch by Lunch
- What does the code Engine=InnoDB mean in MySql when creating a fact table?
- Introduction to InnoDB
- (MySQL) 1장 시작하기. (DB 생성, 테이블 생성, SELECT)미래학자
- Understanding the Docker Internals
- 네이버 블로그 complusblog 글제목을 확인하지 못했다
- Docker and HyperVisorcorona-world: 원제는 “Docker란 ? VM과 차이, Docker 설치 및 기본 명령어를 중심으로”
- What is virtualization? (by RedHat)Red Hat
- What is virtualization? (by opensource.com)
- 가상화 기술 및 가상 머신의 정의현재 열리지 않는다
- 왜 굳이 도커(컨테이너)를 써야 하나요?
- Benefits of Using DockerMicro Focus
- PC방 노하드(VOG포함)란 무엇인가요
- Monolithicjins-dev: 원제는 URL 기준 “전통의 소프트웨어 아키텍처 모델 모놀리식(Monolithic) 아키텍처”, 현재 열리지 않는다
- [우아콘2020] 배달의민족 마이크로서비스 여행기
- How do I create a console progress bar?Kode Java
- How to reduce one month from current date and stored in date variable using java?
- [java] 한달 전 날짜구하기
- What’s the difference from Calendar.DATE and Calendar.DAY_OF_MONTH?
- Calendar (Java Platform SE 8)
- LocalDate (Java Platform SE 8)minusMonths
- [JAVA] 랜덤 문자열 생성 방법needneo
- [Linux] CentOS, Ubuntu 등 OS 버전을 확인하는 명령어
- 리눅스에서 OS버전 확인하기.전기먹는 친구들: 현재 열리지 않는다
- JUnit 설정해보기제목은 URL 기준
댓글
아직 댓글이 없습니다