- previleged 모드
: MYSQL 실행하는데 디렉토리 못만든다고 에러떠서 넣고 실행 (도커의 권한문제인듯)
- 도커 컨테이너를 구동시키는 호스트의 ip : inspect키워드로 확인
- 도커를 돌리는호스트의 포트번호 열려있으면 해당 포트 충돌나니까 안쓰는 포트로 포트포워딩 하기
- my.cnf설정하기
- previleged 모드
: MYSQL 실행하는데 디렉토리 못만든다고 에러떠서 넣고 실행 (도커의 권한문제인듯)
- 도커 컨테이너를 구동시키는 호스트의 ip : inspect키워드로 확인
- 도커를 돌리는호스트의 포트번호 열려있으면 해당 포트 충돌나니까 안쓰는 포트로 포트포워딩 하기
- my.cnf설정하기
1. 트랜잭션이란
- a unit of work
- 일련의 작업단위
- 생명주기 : begin ~ commit
- commit : 메모리에 있던 데이터들이 disk로 flush 되는 것
- commit 이전에 crash 하면 -> rollback
- commit 도중에 crash 하면 -> rollback
- commit 은 디스크에 쓰는과정이라 느릴 수 있다
- 롤백은 메모리를 샷 없에는거라서 빠르다
- 존재하는 데이터- 하나의 스냅샷을 본다
2. atomicity
- cannot be splited
- 1개라도 실패하면 -> failure -> rollback 되어야 한다
- DB 는 트랜잭션이 crash 했는지를 알아차리고 restart 했을때 rollback 전부 해야한다
- lack of atomicity는 inconsistent 한 데이터로 이어지게 된다
1. Transaction Isolation level
- read uncommited : 커밋이안된것도 읽을 수 있다 dirty read발생
- read commited : 커밋된 것만 본다 . 하나의 트랜잭션 안에서 repeatable read발생 . 하나의 트랜잭션안에서 다른 update된 데이터 보는것이 가능함
- repeatable read : 트랜잭션에 각각 id를 부여하여 본인 트랜잭션 id보다 적은 id의 데이터만 읽을 수 있다 . phantom read발생 (insert는 허용하기 때문에)
- serializable: 가장 엄격한 수준의 트랜잭션 그러나 성능 하락 심각
2. index사용과 lock
- 인덱스 사용 -> examined되는 row의 수 감소 -> lock카운트를 감소시킬 수있다
- lock은 buffer pool 영역에 저장된다
3. information schema
- 트랜잭션관련 정보 볼수있다
1. 쿼리튜닝 어디서 시작할까?
-> explain analyze
- 갑자기 time이 점프하는 지점에 주목하라
2. 인덱스
- 클러스터링 인덱스 : 물리적으로 모여있다
- primary key = 클러스터링 인덱스
- secondary index : primary키를 가리킨다
따라서 secondary 인덱스로 search하면 일단 secondary 인덱스 접근해서 -> primary key를 찾고 -> 실제 데이터의 물리적인 위치로 간다
3. 클러스터링 인덱스는- 물리적으로 모여있기 때문에. 어떤 키를 primary key로 하는가가 중요하다
- auto-increment로 primary key 잡으면. 그냥 넣는 순서대로 sequential하게 들어가므로 insert할때 비용이 적게 든다
- 만약에 uuid같은 값을 primary key로 잡으면. 넣을때마다 데이터 순서의 조정이 필요하고. 페이지사이즈(MySQL의 경우, 16kb) 안에 넣기 위한 물리적인 조정이 계속필요하게 됨
- 데이터 분산이 일어나고, random I/O를 높여 read할때에도 성능이 떨어지게 된다.
4. secondary index왜 필요한가?
- examined되는 쿼리 양을 줄이기 위하여
- sort비용을 줄이기 위하여
- find max/min비용을 줄이기 위하여등등.
1. performance_schema 에서 알아내면 좋은 것들
- statement summary digest
- I/O 관련 지표들
- error일으킨것 없는지 (데드락)
2. 쿼리 플랜
- 옵티마이저: 쿼리 플랜을 짠 후 실행한다
- full scan: 바로 데이터 fetch. 작은 테이블인경우 유리
- covering index : 인덱스 탄 후 데이터 가져온다.
- 통계를 통해서 cost를 계산한다.
3. explain
- explain명령어 사용하여 해당 쿼리의 실행계획을 알아볼 수 있다
- format 옵션 = json사용하면 가장 자세하게 살펴볼 수 있다
- explain : 실행 계획을 추정한 결과치를 출력
- explain analyze : 실제로 실행한후 결과치를 출력
- 쿼리 성능최적화를 위한 단계별 전략!!
- 먼저 - 왜 쿼리 수행해서 response주기까지 시간이 걸리는지? 생각해보아야 한다.
- 어디에서 시간이 소요되는지 정보를 먼저 수집하는 것이다!
- 어떤 쿼리에서 시간이 많이 소요되는지를 performance_schema 에서 확인할 수 있다!!
- 잘모르겠을땐 일단 sum timer wait 기준으로 top 10 함 뽑아보면서 분석해보는 것이다.
- 아 이쿼리를 수행하기위하여. 이 만큼이나 많이 기다렷군!! 하고 되짚어볼수있게 된다.
1. MySQL은 세개의 레이어로 구성되어있다.
1) Utility Layer
- SQL문법에 어긋난것이 없는지 검사한다.
- 해당 테이블이나 컬럼이 실제로 존재하는지 체크한다.
- 쿼리를 실행하는 유저의 권한을 체크한다.
2) SQL Layer
- 쿼리 실행 최적의 계획을 계산한다.
- 옵티마이저의 영역!!
- 쿼리실행 통계를 구하고 cost가 낮은 계획을 선택, 실행할 쿼리를 조정한다.
3) Storage Engine Layer
- 실제로 쿼리를 실행한다.
- 스토리지 엔진에는 여러 종류가 있으며, 가장 general하게 사용되는 것은 InnoDB엔진이다.
- InnoDB엔진은 동시성제어에 뛰어난 가장 보편적인 MySQL엔진이다.
- 엔진의 종류는 쿼리실행에 영향을 미칠 수 있다. 특화된 다른 엔진들도 존재하지만 역시 보통은 InnoDB를 많이들 쓴다.
2. MySQL 쿼리는 결과를 바로바로 유저에게 쓰는것이아니라,일단 버퍼에 담아둔다음에 보낸다. 이것이 성능의 병목이 될수도 있다.
1. homebrew install mariadb
2 . 초기의 경우 공백의 패스워드로 접근 가능
mysql.server start
한후
mysql -u root -p
로 접속하고 그냥 패스워드는 앤터
3. 패스워드 재설정
set password for 'root'@'localhost' = password('새로운 패스워드');
4. select host, user, authentication_string from user;
하면 패스워드가 암호화되어 들어가있는것확인할수있음!
1. 직접 막바로 파라메터를 날리는 것 X
2 . 바인드 파라메터 , 마이바티스로 치면 {#파라메터}를 사용한다
3. SQL은 각각 하나하나가 키가 된다.
select * from emp , SELECT * from emp 는 다른 SQL이다. 의미적으로는 같지만 - 자바의 메소드 처럼 이름을 따로 가지고 있지 않고, 그자체로 그냥 하나의 키가 된다. 조금의 변경사항이 반영되면 또 다른 SQL이 되고, 그때마다 파싱 및 옵티마이저의 비용계산과 로우소스생성이 이루어진다.
4. I/O란 ? = 잠. sleep.
디스크 i/o가 발생하면, 프로세스는 하던 일을 멈추고 대기큐에 들어가서 쉬고있는다. (디스크 i/o작업이 완료될때까지. ) 그래서 만약 i/o요청이 많이 들어오면 - 프로세스는 그만큼 쿨쿨 대기큐에서 잠을 자게 되므로, 성능이 느려질 수밖에 없다.
5. 데이터베이스 저장 방식
테이블 스페이스 -> 세그먼트 (인덱스 , LOB, 테이블 등) -> 익스텐트(데이터가 더 필요할시 확장해주는 단위) -> 블록 (하나의 테이블이라고 이해해도 무방. )
하지만 물리적으로는 쪼개어서 데이터 파일에 저장될 수 있다.
1. SQL 처리과정
1) SQL 파싱 : 문법에 틀린것이 없는지. 없는 테이블을 액세스하라는 것은 아닌지 검사한다.
2) 실행계획 : 옵티마이저가 가능한 경로중에서 비용이 적은 것을 선택한다.
3) 처리 : 로우레벨의 언어로 SQL을 변환하여 실행한다.
2. OLTP : 온라인 트랜잭션 시스템(프로그램) : 데이터를 컴퓨터를 이용하여 처리하는 것을 의미한다.
3. 실행계획의 어려움 : 비용을 산정하여 비용이 가장 적은 것을 선택한다.
이 비용산정에는 다양한 요소들이 고려되게 된다...
- 이를테면, 인덱스 스캔을 할지 풀스캔을할지. 인덱스를 쓴다면 어떤 인덱스를 쓸것인지 조인순서. 조인방법. CPU성능. IO방법. 지금까지의 통계치 등등. 아무리 알고리즘이 발달했다고는 하지만? 이러한 실행계획을 매번매번 짜는것은 옵티마이저에게 엄청난 고통이다. ㅜㅜ. 5개 테이블 조인한다고 생각했을때 조인순서만 고려해도 5팩토리얼개의 경우의 수이다....
-> 그래서 사용하는 것이 캐싱!
4. 캐시 히트 했을경우 소프트파싱 / 캐시실패했을 경우 하드파싱이라고 한다.
5. 글로벌 영역에 캐싱해두었다가, 이것을 가져와서 실행하면 실행계획을 다시짜지않아도 되므로 훨씬 효율적이라고 할 수 있다.
6. 힌트를 사용하여 옵티마이저에게 명시적으로 이렇게 수행해!! 라고 명령할 수 있다. 기본적으로 SQL은 질의언어 - 선언적 성격이기 때문에 그 방식(method)를 유저가 직접명령하지 않는다. 옵티마이저가 알아서 짜준다. 근데 넘 어려우니까.. 유저가 알고있는 요소를 옵티마이저에게 전달하여 좀더 효율적인 실행계획을 수행하도록 도와줄 수 있다는 것이다.
1. 하드디스크를 붙인다. 2. fdisk -l로 하드디스크를 확인한다. - interactiive한 커맨드모드 사용하여 (m) 붙인 하드디스크의 파티셔닝을 한다. - 마지막에 w를 해야 실제로 반영이 된다. 3. mkfs를 하여 어떤 파일시스...