출처: https://speakerdeck.com/vidaisuki/dbagakai-fa-timuniyokuwen-kikarerukoto3xuan-plus-1-mysqlcasualfukuoka-vol-dot-7

데드락이 자주 발생해요….

샘플 코드

샘플 데이터

여기에 데이터를 넣고 싶다

사양

Update가 되지 않으면 갭락을 취한다

다른 쿼리가 같은 Update를 던지면 갭락이 2중으로 잡힌다

(컬럼의 일부)

데이터가 없으므로 Insert가 각각 실행되어 DeadLock 발생

대응

기본적으로 DeadLock은 로직 측에서 고쳐야 하므로 재현 시켜서 애플리케이션 개발자에게 넘겨야 하지만 MySQL의 lcok은 종종 생각지도 않은 곳으로 발생한다.

앞의 lock은 분리 레벨 = Read Comitted에서는 발생하지 않는다.

컬럼을 추가하고 싶어요…

온라인(실행 중)으로 가능하나?

MySQL 5.6에서 ONLINE ALTER TABLE(ALGORITHM=INPLACE)가 있어서 온라인으로 할 수 있다.

단 DDL 실행과 끝에서 MetadataLock을 잡는다. 테이블 재 구축 중으로 부하가 높다.

그러므로 부하가 낮은 시간 대에 실행해야 한다.

어느 정도 부하가 걸리나?

꽤 어려운 질문.

테이블의 데이터 사이즈에 따라서 시간이 변하므로 서비스 버전과 같은 데이터로 테스트

물론 서비스 때와 비슷한 부하에서 테스트 한다.

서비스 버전과 같은 부하를 걸기에는 꽤 까다롭다…

모두가 바라는 Instant Add Column

어쩔 수 없이 MetadataLock 대기는 있음…

애플리케이션 서버를 늘리고 싶어요(연결 수가 늘어나도 괜찮나요?)

MySQL의 메모리 구성

               글 로벌 버퍼                                                                        세션 버퍼

사용 메모리 사이즈 예측

글로벌 버퍼

+ (세션 버퍼 X 연결 수)

+ Cache나 OS가 사용하는 것

세션 버퍼는 설정 값을 full 사이즈로 꼭 확보하는 것은 아니고, 연결 마다 full 사이즈 확보하는 것의 최소 값에서 시작하여 필요에 따라서 최대 값까지 확보 되는 것으로 필요한 상황이 되면 full 사이즈 확보하는 것… 등등 여러가지 패턴이 있다

join_buffer_size

인덱스를 사용하지 않는 JOIN에서 사용된다.

default 값은 256KB(5.6 이후)

설정 값이 32MB 이다.

스레드 마다 실제 소비 메모리 양을 측정

대응

모든 연결이 설정 값을 Full로 사용하면 계산 상 메모리가 넘으므로 연결을 늘리지 않는다. 라는 상황임

설정 값을 적절하게 한다(스레드 버퍼는 너무 늘리지 않도록 한다)

DBA는 보통 무엇을 하나요?

여러가지 하고 있다