2. MySQL State Message 분석
발표자 소개
2003 ~ 2006
방황하던 개발자
Windows + SQL Server 환경
2006 ~ 2014
얼떨결에 된 DBA
MySQL + Oracle 2014 ~
다행히도 아직 DBA
MySQL + Oracle
Nickname : 돌고래 사육사
Blog : seuis398.blog.me
2
3. 배경
MySQL 성능 데이터 수집
1) GLOBAL STATUS (얼마나 많은 일을 했는가?)
Query Type 별 수행 빈도
InnoDB Buffer pool activity (Logical & Physical Read, Dirty Buffer byte)
InnoDB row operations
MySQL Handler status
Sort 및 temporary table(memory, disk) 생성 빈도
2) Performance Schema (일을 얼마나 제대로 했는가?)
statement/* : Query 종류별 수행 통계(execution count), 1분 단위 평균/최대 latency
stage/sql/* : 개별 statement 수행 단계별 1분 단위 평균/최대 latency
wait/io/file/* : 데이터, 인덱스, 로그 파일 등에 대한 IO 이벤트 (빈도, 1분 단위 평균/최대 latency)
wait/io/table/* : MySQL - Storage Engine 간 IO 이벤트 (빈도, 1분 단위 평균/최대 latency)
오늘의 주제!!!
3
MySQL State Message 분석
4. 배경
MySQL State Message
“show processlist” 혹은 “show profile” 커맨드를 통해 확인 가능
performance_schema.events_statements_xxx 테이블에서도 확인 가능
MySQL 5.6 기준 109개, MySQL 5.7 기준 128개의 Message가 정의
4
MySQL State Message 분석
5. 문제 제기
명확하지도 정확하지도 않은 메시지
• starting, init, preparing의 차이는?
• end와 query end의 차이는?
• freeing items와 cleaning up의 차이는?
• update, updating의 차이는?
• MySQL Reference Manual (https://dev.mysql.com/doc/refman/5.7/en/general-thread-states.html)
5
MySQL State Message 분석
6. 문제 제기
MySQL source code를 들여다 보자!!
https://www.github.com/mysql/mysql-server
6
MySQL State Message 분석
7. 문제 제기
유의사항
1) sql parse 단계부터 개별 query handler 까지만 확인하면 된다.
그래도 어렵다. @_@;
2) MySQL 버전에 따라 메시지 발생 위치와 메시지 자체가 조금씩 달라진다.
Writing to net => Sending to client
3) State Message와 관련된 bug도 많다.
5.6 버전 기준 prepared statement 사용시 대부분의 쿼리 처리 단계가 statistics 상태로 보여짐
4) 5.6 소스보다는 5.7 소스가 더 보기 좋다.
전체를 보면 그런 기운이 온다.
목표
개별 State Message가 가지는 대략적인 의미를 이해하고,
State Message가 주는 혼란에 흔들리지 말자.
7
MySQL State Message 분석
11. Query Handler에서 발생하는 Message #1
sql_select.cc
handle_query()
sql_optimizer.cc
JOIN::optimize()
sql_execuor.cc
JOIN::exec()
init
executing
sending data
end
optimizing
statistics
preparing
SELECT
INSERT … SELECT
Multi Table Update
Multi Table Delete
lock.cc
mysql_lock_tables()
system lock
11
MySQL State Message 분석
12. Query Handler에서 발생하는 Message #2
sql_updatet.cc
mysql_update()
sql_delete.cc
mysql_delete()
sql_insert.cc
mysql_insert()
init
update
Single Update
Single Delete
Insert
end
init
updating
end
init
searching rows
for update
end
lock.cc
mysql_lock_tables()
system lock
updating
12
MySQL State Message 분석
13. State Message의 맹점
Fencepost의 함정
• 실제 메시지에 기재된 작업을 하는데 소요된 시간을 측정한 것이 아님
• MySQL code 상에 존재하는 상태 변경 시점에 도달하기까지 소요된 시간
(출처) 전국고속도로 휴게소 맛집 총정리 http://www.wikitree.co.kr/main/news_view.php?id=78452
Oracle - Oracle Wait Interface (OWI)
Class Wait Event Duration
휴게소 금산휴게소_식당 30분
휴게소 함양휴게소_화장실 20분
졸음쉼터 금서졸음쉼터 10분
고속도로 중부고속_추월차선 1시간 30분
고속도로 중부고속_주행차선 3시간 30분
MySQL - State Message
State Duration
서울 1시간 10분
이천 1시간 15분
청원 1시간 00분
금산 2시간 15분
함양 1시간 20분
정확한 지연의 원인을 알 수 없음
13
MySQL State Message 분석
14. State Message의 맹점
Fencepost의 함정
• 예) LOAD DATA 구문을 처리하는 handler(sql_load.cc)에서는 State 변화가 일어나지 않음
mysql> LOAD DATA INFILE '/MYSQL/test.txt' INTO TABLE my_test_table;
Query OK, 1000000 rows affected (35.42 sec)
Records: 1000000 Deleted: 0 Skipped: 0 Warnings: 0
mysql> show profile for query 1;
+------------------------------+-----------+
| Status | Duration |
+------------------------------+-----------+
| starting | 0.000250 |
| checking permissions | 0.000019 |
| Opening tables | 0.000044 |
| System lock | 35.417423 | 어떻게 해석해야 하는가?
| query end | 0.000012 | 1) System Lock(external table lock) 설정에 35초 소요됨
| closing tables | 0.000016 | 2) System lock 상태 변경 시점부터 query end 상태 변경
| freeing items | 0.000035 | 시점까지 35초 소요됨 (실제 데이터 적재 시간)
| cleaning up | 0.000009 |
+------------------------------+-----------+
14
MySQL State Message 분석
15. State Message의 맹점
MySQL Reference Manual에 정의된 내용과 실제 사용과의 간극
• system lock
The thread is going to request or is waiting for an internal or external system lock for the table. If this
state is being caused by requests for external locks and you are not using multiple mysqld servers that are
accessing the same MyISAM tables, you can disable external system locks with the --skip-external-locking
option. However, external locking is disabled by default, so it is likely that this option will have no
effect. For SHOW PROFILE, this state means the thread is requesting the lock (not waiting for it).
• InnoDB는 external locking 처리 자체가 필요없으나, MySQL은 Table 접근 시점에 external locking을 시도함
Storage Engine들은 MySQL에서 요구하는 interface를 필수 구현해야 하며, InnoDB 역시 예외는 아님
mysql_lock_tables() => table_handler->external_lock(thd,locktype)
• 실제 external locking 호출에 따른 처리는 개별 Storage Engine에서 구현하며, 필요없는 경우 bypass 가능
(예) Memory(Heap) Storage Engine – ha_heap.cc
15
MySQL State Message 분석
16. State Message의 맹점
MySQL Reference Manual에 정의된 내용과 실제 사용과의 간극
• 하지만 External locking 기능은 Transaction-aware Storage Engine에서 다른 용도로 사용됨
=> 이런 작업을 진행하는 동안,
MySQL에서는 system lock 상태로
보여짐
16
MySQL State Message 분석
17. 일반적인 DML Query의 State 변화 Review
starting opening tables init system lock
optimizing
statistics
preparing
executing
sending data
searching rows
for update
update
end
updating
query endclosing tablesfreeing items
17
MySQL State Message 분석
cleaning up
18. 일반적인 DML Query의 State 변화 Review
starting opening tables init system lock
optimizing
statistics
preparing
executing
sending data
searching rows
for update
update
end
updating
query endclosing tables
미션 전달
query id 할당
Parser 관련 초기화 작업
query 시작 시각 기록
일부 status 항목 처리 (Questions)
Query cache 히트하는 경우 처리
Statement 타입 별 handler 호출
18
MySQL State Message 분석
freeing items
cleaning up
The thread has processed one command and is preparing
to free memory and reset certain state variables.
======================================================
미션 완료 (세션 정리)
DB 세션에 남아있는 query 관련 정보 삭제 및 메모리 반환
DB 세션 상태 Sleep으로 변경
The thread has executed a command. Some freeing of items done
during this state involves the query cache. This state is
usually followed by cleaning up.
===========================================================
미션 완료 (Parser 정리)
Parser 관련 정보 삭제
※ query cache 관련 처리는 보이지 않음
19. 일반적인 DML Query의 State 변화 Review
starting opening tables init system lock
optimizing
statistics
preparing
executing
sending data
searching rows
for update
update
end
updating
query endclosing tables
19
MySQL State Message 분석
freeing items
cleaning up
The thread is flushing the changed table data to
disk and closing the used tables. This should be a
fast operation. If not, verify that you do not have
a full disk and that the disk is not in very heavy
use.
====================================================
테이블 사용 후 뒷정리
table closing 및 table open cache에 반환
metadata lock 정리
※ closing tables 상태의 지연이 관찰되는 경우
Lock_open mutex 병목 가능성 있음
※ 변경 데이터 flushing은 수행되지 않음
The thread is trying to open a table. This is should be very
fast procedure, unless something prevents opening. For example,
an ALTER TABLE or a LOCK TABLE statement can prevent opening a
table until the statement is finished. It is also worth
checking that your table_open_cache value is large enough.
==============================================================
테이블 사용할 수 있도록 준비
Lock Mode 확인 (DDL, Lock Table인 경우 Metadata Lock 처리 필요)
Metadata version 확인 및 table definition cache 갱신
table open
※ Opening tables 상태의 지연이 관찰되는 경우
MySQL 5.5 버전까지 Lock_open mutex가 table open/close의 병목
table open cache 설정에 문제가 없는 경우, 버전 업그레이드
검토 필요
20. 일반적인 DML Query의 State 변화 Review
starting opening tables init system lock
optimizing
statistics
preparing
executing
sending data
searching rows
for update
update
end
updating
query endclosing tables
20
MySQL State Message 분석
freeing items
cleaning up
This state occurs after processing a query but
before the freeing items state.
==============================================
플랜 정보 삭제
에러 혹은 인터럽트가 있었다면 트랜잭션 롤백 처리
※ 대량 트랜잭션 수행 중 인터럽트 처리하는 경우
장기간 query end 상태로 보여짐. 이는 트랜잭션 롤
백으로 인한 정상적인 상태이며, 롤백 완료 시점은
SHOW ENGINE INNODB STATUS 등에서 undo log record
의 잔량을 통해 확인
21. 일반적인 DML Query의 State 변화 Review
starting opening tables init system lock
optimizing
statistics
preparing
executing
sending data
searching rows
for update
update
end
updating
query endclosing tables
21
MySQL State Message 분석
This occurs at the end but before the cleanup
of ALTER TABLE, CREATE VIEW, DELETE, INSERT,
SELECT, or UPDATE statements.
=============================================
쿼리 핸들러의 종료 지점
Statement 수행 후처리
- query cache invalidation
- binlog writing
※ 5.7 code 기준으로 insert 쿼리의 경우 query
cache invalidation 과 binlog writing이 end
stage 변경 직전 단계인 update 단계에서 수행됨
(feature인지 bug인지 확인 필요)
freeing items
cleaning up
This occurs before the initialization of ALTER TABLE, DELETE, INSERT,
SELECT, or UPDATE statements. Actions taken by the server in this state
include flushing the binary log, the InnoDB log, and some query cache
cleanup operations.
For the end state, the following operations could be happening:
- Removing query cache entries after data in a table is changed
- Writing an event to the binary log
- Freeing memory buffers, including for blobs
==========================================================================
쿼리 핸들러의 시작 지점
개별 쿼리 종류별 전처리 단계
예) 변경을 수행하는 경우, 테이블이 변경 가능한지 확인 (updatable view)
※ 로그 Flushing 등의 로직은 관찰되지 않음
22. 일반적인 DML Query의 State 변화 Review
starting opening tables init system lock
optimizing
statistics
preparing
executing
sending data
searching rows
for update
update
end
updating
query endclosing tables
22
MySQL State Message 분석
freeing items
cleaning up
The thread is going to request or is waiting for an internal or external system
lock for the table. If this state is being caused by requests for external locks
and you are not using multiple mysqld servers that are accessing the same MyISAM
tables, you can disable external system locks with the --skip-external-locking
option. However, external locking is disabled by default, so it is likely that
this option will have no effect. For SHOW PROFILE, this state means the thread is
requesting the lock (not waiting for it).
================================================================================
각 테이블에 external locking 시도
단, Transactional 엔진에서는 다른 동작 수행함
- 엔진에게 새로운 statement가 시작되었다고 통보
- savepoint 지점 등록 등
23. 일반적인 DML Query의 State 변화 Review
starting opening tables init system lock
optimizing
statistics
preparing
executing
sending data
searching rows
for update
update
end
updating
query endclosing tables
23
# Logical transformations:
- Outer to inner joins transformation.
- Equality/constant propagation.
- Partition pruning.
- COUNT(*), MIN(), MAX() constant substitution
in case of implicit grouping.
- ORDER BY optimization.
# Perform cost-based optimization of table order
and access path selection.
# Post-join order optimization:
- Create optimal table conditions from the
where clause and the join conditions.
- Inject outer-join guarding conditions.
- Adjust data access methods after determining
table condition
- Optimize ORDER BY/DISTINCT.
# Code generation
- Set data access functions.
- Try to optimize away sorting/distinct.
- Setup temporary table usage for grouping
and/or sorting.
MySQL State Message 분석
freeing items
cleaning up
The server is performing initial optimizations for a
query.
The server is calculating statistics to develop a
query execution plan. If a thread is in this state
for a long time, the server is probably disk-bound
performing other work.
This state occurs during query optimization.
==================================================
쿼리 Rewrite(Transformation) 및 최적화
Join 및 access path 계산
※ 다량의 조인을 수행하는 SQL이 statistics 상태에서
지연이 관찰된다면, 조인 힌트 등을 사용하여 optimizer
의 부담을 줄여주는 방법을 시도해 볼 수 있다.
24. 일반적인 DML Query의 State 변화 Review
starting opening tables init system lock
optimizing
statistics
preparing
executing
sending data
searching rows
for update
update
end
updating
query endclosing tables
24
MySQL State Message 분석
The thread has begun executing a statement.
freeing items
cleaning up
The thread is reading and processing rows for a
SELECT statement, and sending data to the client.
Because operations occurring during this state
tend to perform large amounts of disk access
(reads), it is often the longest-running state
over the lifetime of a given query.
================================================
조회 결과를 Client에게 보내는 것이 아님
Storage Engine에서 조회 및 Filter 처리 등 데이터
를 실제 처리하는 과정을 의미
25. 일반적인 DML Query의 State 변화 Review
starting opening tables init system lock
optimizing
statistics
preparing
executing
sending data
searching rows
for update
update
end
updating
query endclosing tables
25
MySQL State Message 분석
freeing items
cleaning up
The thread is getting ready to start updating the
table.
==================================================
INSERT 처리를 하는 단계를 의미
update state는 오직 INSERT 쿼리 처리시에만 발생
26. 일반적인 DML Query의 State 변화 Review
starting opening tables init system lock
optimizing
statistics
preparing
executing
sending data
searching rows
for update
update
end
updating
query endclosing tables
26
The thread is doing a first phase to find all
matching rows before updating them. This has to be
done if the UPDATE is changing the index that is
used to find the involved rows.
==================================================
※ searching rows for update state 지연이 관찰된다
면, 인덱스 구성 컬럼이 빈번히 업데이트 되지 않는지
확인한다.
The thread is searching for rows to update and is
updating them.
==================================================
Update 혹은 Delete 등의 처리를 하는 단계를 의미
MySQL State Message 분석
freeing items
cleaning up
27. MySQL State Message 분석
결론
1) State Message는 개별 Statement의 profiling을 위한 유일한 도구이다.
2) 하지만 Message 구조에 대해서 모른다면, 오해의 소지가 될 수 있다.
3) 단순 참고 지표로만 활용하되, 맹신은 하지 말자.
4) Oracle & MySQL community에서 이 부분에 대해 많은 관심을 가졌으면 좋겠다.
(메시지의 세분화도 필요)
27