출처 : https://www.youtube.com/watch?v=dF8qmCOSE7g
MySQL 8.0
- Redo log 디자인을 변경해서 성능향상
- system mutex 를 최대한 분리해서 IO Capacity 를 충분히 이용하도록 변경
- Information Schema, Performance Schmea 를 조회하는 성능 향상
Memory
- 작업 데이터셋이 innodb buffer pool 에 적합한지 확인
사용 가능한 메모리의 70~80%를 innodb buffer pool 에 할당 할 수 있음
- MySQL 은 Connection 당 메모리 소모, Connection 당 할당되는 메모리는 크게 할당하는것을 권장하지 않는다.
max_allowed_packet, thread_stack, net_buffer_length, max_digest_length
- 디스크 접속을 완하하기 위한 Caching 및 Buffer
Read log/Join/Sorting Buffer 와 Table Cache
Replication 관련 max_binlog_cache_size
- 기타
- OS, FS cache
- temporary tables tmp_table_size
- Performance Schema
- 모니터링 방법: top 명령어로 확인, 전체 메모리의 80% 이하
Monitoring MySQL Memory Usage
- 대부분 메모리 지표는 비활성화 됨
select * from performance_schema_setup_instruments where name like '%memory%';
- performance_schema
memory_summary_global_by_event_name
- sys 스키마
memory_global_by_current_bytes
- 상태값 확인
show global status like 'table_open%';
show global status like 'binlog%';
show global status like 'created_tmp%';
select
substring_index(event_name, '/', 2) as core_area,
format_bytes(sum(current_alloc)) as current_alloc
from sys.x$memory_global_by_current_bytes
group by substring_index(event_name, '/', 2)
order by sum(current_alloc) desc;
Disk
- SSD, NVMe 권장
innodb datadir, tmp 파일, undo 로그 모두 랜덤 IO, 빠른 SSD 권장
inndb_page_size = 4K (디폴트는 16K, 디스크 page 사이즈와 매칭)
innodb_flush_neighbors = 0
- Spinning 디스크는 log (순서 IO)에 여전히 사용할 수 있음
- RAID 디스크를 사용한다면 성능을 위해 RAID 1+0 권장
- FBWC/BBWC (Flash/Battery-Backed Write Cache) 권장
write 성능 향상 및 crash-safe
- 디스크 유형(rpm 지표) 및 부하에 따라 innodb_io_capactiy 설정
디폴트값은 200, 느린 ssd 혹은 일반 하드 디스크에 적합
디스크 성능이 좋다면 200보다 더 큰값을 설정
OS
- 성능만 고려하면 Linux 권장
- MySQL 8.0 인 경우 최신 커널 권장하지
- ext4, xfs 파일 시스템 추천
- ulimit을 사용하여 file/process limits 확장
- MySQL 전용 서버인 경우, innodb_numa-interleave = 1 권장
- Swappiness, 권장 옵션은 (1-6): sysctl - vn.swappinness=1
- InnoDB 데이터 파일은 FS 캐시를 거치지 않음, innodb_flush_method=O_DIRECT
MySQL Configuration
- 8.0 설정 파일 : my.cnf, mysqld-auto.cnf (SET PERSIST 변수로 지정한 값을 mysqld 재기동 후에도 유지)
- 설정값 확인 테이블 추가
- performance_schema.global_variables
- performance_schema.session_variables
- performance_schema.variables_by_thread
- 클라이언트 커넥션 관련 설정
- max_connections 를 필요 이상으로 크게 설정하지 말아야 할 것
- OS limit on file descriptors
- Linux/Solaris : UP to 10,000
- Windows: Up to 16,384
- 응답 시간의 기대치 및 워크로드 감안
- 많은 연결 수가 예상되면 버퍼에 따른 메모리 용량을 확복
- wait_timeout으로 연결을 닫음
- 상태값 확인
- Connections
- Max used connections
- Connection errors max connections
- 커넥션별로 할당되는 버퍼 값은 작게 시작
- sort_buffer_size
- binlog_cache_size
- net_buffer_length ~ max_allowed_packet
- read_buffer_size
- read_rnd_buffer_size
Reusing Threads
- thread_cache_size : 서버가 스레드를 재사용할 수 있도록 저장한 스레드 개수
- 디폴트 값은 자동 설정 : 8 + (max_connections / 100)
- Thread cache hit rate % = 100 - ((Threads_created / Connections) * 100)
- 연관된 상태 값 확인
- Connections
- Threads_connected
- Connections / Uptime
- Threads_created / Uptime
- Uptime_since_flush_status
- Threads_cached
- Threads_running
- thread_pool_size 스레드 풀 성능 튜닝 (엔터프라이즈만 사용가능)
- https://dev.mysql.com/doc/refman/8.0/en/thread-pool-tuning.html
InnoDB Buffer pool
- innodb_buffer_pool_size
- 모든 데이터를 innodb_buffer_pool 에 넣어서 사용하면 이상적이나(이상일 뿐)
- 테이블 및 인덱스 데이터를 캐시한 InnoDB의 메모리 영역, LRU 알고리즘에 의해 관리
- 전용 데이터베이스 서버에서 시스템의 실제 메모리 크기의 70%~80%정도로 설정 할 수 있음
- innodb_buffer_pool_size = N * innodb_buffer_pool_chunk_size * innodb_buffer_pool_instances
- 확인 방법 : SHOW ENGINE INNODB STATUS;
- Total memory allocated
- Buffer pool size
- Free buffers
- Database pages, Old database pages
- Modified db pages
- Pending reads, Pending writes
- Buffer pool hit rate
Innodb redo log (트랜잭션 로그)
- innodb data file에 발생하는 랜덤 io 를 red log file을 사용해서 순차 io 로 변경해서 처리 해줘서 write 성능 향상
- innodb_log_file_size
- write 성능에 유리하지만 복구 시간에 영향 (크래시 리커버는 redo log 기반)
- 총 사이즈(~512G) : innodb_log_file_size * innodb_log_files_in_group (기본값 2)
- 운영 환경에서 최소 512M으로 권장하고, 가능한 충분히 크게 설정할 것 권장
- redo 사용율
- SHOW ENGINE INNODB STATUS 에서 Log sequence number, Last checkpoint at 값을 확인하여 계산
- SELECT NAME, COUNT FROM information_schema.INNODB_METRICS WHERE NAME IN ('log_lsn_current', 'log_lsn_last_checkpoint')
- Used % = (Used log / Total log) * 100
= (log_lsn_current - log_lsn_last_checkpoint / (innodb_log_file_size * innodb_log_files_in_group)) * 100
= (47605855 / 100663296) * 100 = 47.29%
- Used % 가 50% 정도는 괜찮지만 80%정도일 경우 위험함
redo log 가 부족하게 되면 innodb buffer pool flushing 이 발생하는데 이때 대량의 io가 발생하여 성능 저하가 발생한다.
- innodb_log_buffer_size = 16MB
- Redo 로그 I/O를 완화하기 위한 버퍼 영역
- 일반적으로 16MB정도면 충분하지만 트랜잭션 사이즈가 크면 commit 전에 disk IO 가 발생되기에, 따라서 크게 조절할 필요가 있음
- innodb_flush_log_at_trx_commit = 1
- InnoDB가 commit한 트랜젝션에 대해서 언제 flush 할 것인지 결정
- 디폴트값인 1로 권장하지만 다음 상황에서 제외:
- InnoDB가 commit한 트랜젝션에 대해서 언제 flush 할 것인지 결정
- Bulk 데이타 로딩할 경우 2로 설정하거나 8.0 버전에서 redo로그를 비활성화
- 예측하지 못한 peak 부하로 인해 디스크 I/O부하가 심할 경우
- 데이터 로스가 발생하여도 괜찮을 경우
바이너리 로그 성능만-
- binlog_cache_size에 비해 트랜젝션이 너무 크면, 임시 파일에 저장하기에 성능 영향
- 관련된 상태 변수 확인:
- Binlog_cache_use
- Binlog_cache_disk_use
- 캐시 효율성% = (100 - ( Cache Disk Use/Cache Use) * 100)
- 트랜젝션 사이즈를 제어함으로 바이너리 로그 사이즈 제어, 복제 효율성 향상
- DELETE 대신에 DROP TABLE/PARTITION
- DELETE FROM … WHERE … LIMIT 1000;
- binlog_row_image = minimal
- 복제 지연 방지 설정
- binlog_transaction_dependency_tracking = WRITESET
- replica_parallel_type = LOGICAL_CLOCK
- replica-parallel-workers = 16
- binlog_order_commits=OFF
- replica_preserve_commit_order = 1(optional)
https://dev.mysql.com/blog-archive/improving-the-parallel-applier-with-writeset-based-dependency-tracking/
'MySQL' 카테고리의 다른 글
MySQL JSON 사용시 주의사항 (0) | 2022.09.16 |
---|---|
MySQL JSON, Generated Columns (0) | 2022.09.15 |
xtrabackup 8.0 (2) (0) | 2021.07.06 |
xtrabackup 8.0 (1) (0) | 2021.06.30 |
Hash join in MySQL 8 (0) | 2021.06.25 |