오픈소스 DBA 정신

Open Source DBA Ethos

좋은 글이 있어 퍼옴

오픈소스 DBA 란..!
1. 데이터베이스 뿐 만 아니라 시스템 전문가가 되어야 함
2. 회사와 커뮤니티에 기여할 수 있는 개발자도 되어야 함
3. 빠르게 움직여야 함
4. 하나의 답에 만족하지 않고 해답을 갈구 해야 함
5. 사내 다른 부서와 커뮤니티의 다른 회사와도 협력할 줄 알아야 함
6. 변화를 주도해나가야 함

  • We are system experts.  Open source DBAs know their operating system.  They are not only focused on the database.
  • We are developers.  We contribute to source code within our enterprises, and in many cases, in the community.  We create meaningful tools for our companies, and help solve problems inherent in “bleeding edge” technologies, making such technologies approachable in the enterprise.  We strive to bring continuous integration and seamless migration into places that are very difficult.
  • We move fast.  Open source DBAs, even in large enterprises, are always “moving the needle” towards higher performance, making changes as fast as our tools, our applications, and our organizations allow.
  • We strive for answers.  Open source DBAs are never satisfied by answers to (even old) questions in our technologies.  “One source of truth” is almost never the case.
  • We are collaborators.  We work together across team lines within our companies, and across companies in the community, to broaden our understanding.  We work across technologies to find the “best solution for the task”.
  • We are facilitators of change, not barriers to change.

MariaDB, MySQL, Percona Server Threadpool 정리

https://mariadb.com/kb/en/mariadb/thread-pool-in-mariadb/
1. 언제 쓰레드풀을 사용하면 효과적인가:
– 짧은 쿼리 위주, CPU바운드의 OLTP 워크로드에 유용

2. 쓰레드풀이 비효율적으로 동작하는 드문 경우들:
– 매우 몰리는 워크로드 (긴 유휴 액티비티와 짧은시간 동안 많이 동작하는 유저 액티비티 혼재)
– 쓰레드 생성 쓰로틀링부터 나오는 딜레이를 감당할 수 없을 때:
이런 경우라도, 쓰레드들을 retire 시키는 방식을 조정해서 성능은 향상될 수 있음
(e.g. MariaDB 의 thread_pool_idle_timeout, MySQL 의 thread_pool_max_unused_threads)
– 동시에 많고 길고, 양보하지 않는 쿼리들이 있을 때:
DW성 작업과 같이 풀을 독점하는 수행시간이 긴 쿼리가 발생할 때 다른 쿼리의 수행을 방해할 수 있음, 딜레이는 오직 지연stall 감지 매커니즘으로 조정할 수 있음
(e.g. thread_pool_stall_limit)
– 데이테베이스가 부하에 무관하게 언제나 빨리 끝나는 심플한 쿼리가 필요할 때:
데이터베이스 로드와 상관없이 심플한 쿼리가 언제나 빨리 수행될 수 있는 건 아님, 쓰레드풀이 다 차있을 때 SELECT 1 과 같은 쿼리도 큐로 들어가거나 나중에 수행되어 쓰레드풀 미사용보다 느려질 수 있음

3. MariaDB 로우레벨 구현 상세 문서에 있는 오라클 쓰레드풀의 단점 (2011년):
http://worklog.askmonty.org/worklog/Server-BackLog/?tid=246
– 리눅스에서만 효율적인 epoll() 을 씀, 다른 OS에서는 poll()을 사용
– 클라이언트 로그인, 로그인이 acceptor 쓰레드를 블락함, 그리고 네트워크 IO 가 싱크방식으로 완료됨, 이는 느린 클라이언트가 다른 클라이언트들의 로그인을 막게 됨
~~~> 요거 5.6.36 에서 어떻게 변했는지 확인 필요
– wait_timeout 기능이 MySQL 엔터프라이즈 쓰레드풀에서 동작하지 않음
– KILL 명령이 높은 오버헤드를 가지고 있고 효율적이지 못한 구현방식때문에 락 발생에 주의가 필요함
– 쓰레드풀에 대한 인터널정보가 information_schema 에 존재

4. MySQL 쓰레드풀에 있는 것:
– 동시 트랜잭션의 숫자를 제한 (부정적 측면의 이야기)
MariaDB 는 일반적으로 하이 큐 우선 구동시킴, MySQL은 (“BEGIN” 구문 이후) 트랜잭션이 한 번 시작하게 되면 커넥션의 우선순위를 낮춤 (로우큐 우선 사용)
아마도 특정 MySQL 버전에서 kernel_mutex 문제가 이 방식으로 해결되는 것일 수 있고, 지금까지는 sysbench 결과를 높이기 위한 트릭일 수 있다고 MariaDB 주장
– 쓰레드풀에 대한 인터널정보가 information_schema 에 존재

http://mikaelronstrom.blogspot.kr/2011/10/mysql-thread-pool-limiting-number-of_21.html
MySQL 쓰레드풀에 대해서는 Mikael Ronstrom 블로그에 나와있는데, MySQL 서버가 동시에 많은 트랜잭션을 핸들링 할 때 부하를 받으며, 너무 많은 트랜잭션이 병렬로 수행되는 상황을 피해야 한다고 함
쓰레드풀은 이미 트랜잭션을 시작했는지 혹은 아닌지에 따라 큐잉하는 쿼리의 우선순위를 핸들링하고
이러한 우선순위화는 너무 긴 트랜잭션이 존재할 때 livelock 이슈를 가지는데 이런 문제를 피하기위해 설정된 시간이 지난 후에 높은 우선순위큐로 쿼리를 이동시킴(thread_pool_prio_kickup_timer)
하지만 짧은 시간동안 너무 많은 이동이 발생되지 않도록, 쓰레드풀은 쓰레드그룹당 10ms 에 한 쿼리를 이동시킴 (초당 100쿼리가 timer에 걸리면 높은 우선순위큐로 이동)
서버에서의 쿼리 수행을 빠르게 하기 위해 유저커넥션을 항상 높은 우선 순위 큐에 존재하도록 설정 가능함

5. DB별 쓰레드풀 파라미터의 차이:
MySQL에만 있는 것//
thread_pool_high_priority_connection # 동시 트랜잭션 수 제한과 관련(기본값은 낮은 우선순위 큐 먼저 사용)
thread_pool_prio_kickup_timer # 동시 트랜잭션 수 제한과 관련(낮은 우선순위 큐에서 높은 우선순위 큐로 이동)
thread_pool_max_unused_threads # MySQL 쓰레드풀만의 쓰레드 종료 로직, MariaDB 에서는 thread_pool_idle_timeout 를 사용
thread_pool_algorithm # 실험적인 변수, 벤치마킹 점수용?

MariaDB에만 있는 것//
thread_pool_max_threads # 풀 내 최대 쓰레드 수 설정, 최대값에 도달하면 추가로 쓰레드가 생성되지 않음, MariaDB 10.2.4 부터 디폴트 65536
thread_pool_idle_timeout # idle worker 쓰레드에 대한 timeout 설정, 기본값은 60
MySQL, MariaDB에 모두 존재하나 동작 방식이 다른 것//
thread_pool_stall_limit  # 큐에서 지연으로 판단하는 임계치, MySQL 쓰레드풀에서는 10 ms 단위로 체크, MariaDB 에서는 1ms 단위로 체크

6. MariaDB 와 Percona 의 차이:
– MariaDB 의 thread_pool_priority=auto,high,low https://mariadb.com/kb/en/mariadb/thread-pool-system-and-status-variables/#thread_pool_priority 는
Percona 의 thread_pool_high_prio_mode=transactions,statements,none https://www.percona.com/doc/percona-server/5.7/performance/threadpool.html#thread_pool_high_prio_mode 와 일치
– Percona 에는 thread_pool_high_prio_tickets 세팅으로 새로운 커넥션 쿼리를 하이 큐에 얼마나 들어오게 할건지 지정 (기본값: 4294967295)
https://www.percona.com/doc/percona-server/5.7/performance/threadpool.html#thread_pool_high_prio_tickets
MariaDB 는 thread_pool_prio_kickup_timer 피쳐가 있음
https://mariadb.com/kb/en/mariadb/thread-pool-system-and-status-variables/#thread_pool_prio_kickup_timer

7. MySQL 쓰레드풀 사용시 쿼리 수행이 지연되는 최악의 케이스 예시
로우큐에 200개 구문이 존재
하이큐에 10개 구문이 존재
thread_pool_prio_kickup_timer=500 (500ms)
thread_pool_stall_limit=30 (300ms)

최악의 케이스로 하이큐에 지속적으로 장시간 수행되는 10개 트랜잭션이 있어 로우큐에서 하이큐로 옮겨갈 수 있는 구문이 없다면,
thread_pool_prio_kickup_timer=500ms 이후, 새로운 구문이 하이큐로 옮겨갈 수 있게 됨
로우큐에서 하이큐로 이동하는 속도는 최대 초당 100개(10ms 당 1개)로 고정되어있어 200개 구문이 모두 하이큐로 옮겨가는데 2초가 걸림
옮겨지는 구문들이 하이큐에 도달했을 때 하이큐에 이미 많은 롱런 구문들이 먼저 존재할 수 있음
이때 모든 구문들이 지연이되고 다음 구문이 하이큐로부터 받기 전 매 구문당 thread_pool_stall_limit=30(300ms)가 걸림
그리하여, 이 시나리오에서 새 구문이 수행을 시작하기 전 토탈..

(하이큐이동대기 100개*2회=1초 + 하이큐이동 100개*2회=2초) + 하이큐 전체가 다 차있어서 이동한 쿼리가 모두 지연되면 200개*300ms=60초 = 63초가 소요 (로우큐에서만 최소 3초가 걸림)

MySQL 5.6.36 Threadpool Fix

http://worklog.askmonty.org/worklog/Server-BackLog/?tid=246
MariaDB 쪽 쓰레드풀 개발 백로그 문서를 보면 오라클이 구현한 쓰레드풀의 단점에 대해서 기록되어있고 acceptor 쓰레드의 블락킹 문제가 언급되어 있음

Comparison with MySQL enterprise threadpool
===========================================
Here are the downsides of Oracle’s implementation.
– MySQL/Oracle is using efficient epoll() on Linux and inefficient poll()
everywhere else.
– Client login. Login just blocks the acceptor thread, and network IO is done
synchronously, which means slow client will prevent logons of other clients.
클라이언트 로그인. 로그인이 acceptor 쓰레드를 블락함, 그리고 네트워크 IO 가 싱크방식으로 완료됨, 이는 느린 클라이언트가 다른 클라이언트들의 로그인을 막게 됨
– wait_timeout does not work with MySQL Enterprise threadpool.
– KILL seems to have a high overhead and require careful locking due to
inefficient implementation.

https://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-36.html
이번 5.6.36 업데이트 에서 쓰레드풀의 acceptor 쓰레드 부분에서 변경이 있는 것으로 보이며 읽기쓰기 워크로드가 들어오는 마스터에서 Threadpool 사용시 로그인할때 심각한 지연을 경험했던 바 테스트가 필요할 것으로 보임

쓰레드 풀//
쓰레드풀 플러그인 퍼포먼스 향상을 위해 커넥션 인증authentication과 초기화initialization 부분이 acceptor 쓰레드에서 클라이언트 커넥션을 핸들링하는 쓰레드풀 worker 쓰레드로 이동되어 짐
acceptor 쓰레드가 감소된 레이턴시로 더 높은 rate 에서 새 커넥션을 핸들링하게 해 줌
커넥션 인증과 초기화에 대해 진행하거나 대기하고 있는 쓰레드의 숫자를 INFORMATION_SCHEMA.TP_THREAD_GROUP_STATE 테이블에 추가된 CONNECT_THREAD_COUNT 컬럼에서 알 수 있음
쓰레드 그룹에서 최대 4개의 worker 쓰레드가 존재할 수 있고; 이 쓰레드들은 얼마간의 미사용 기간이 지나면 만료됨 (Bug #17159742)

그밖의 관심가는 5.6.36 버그 픽스//
– InnoDB: restart 시 st_my_thread_var 구조체를 초기화시키는 백그라운드 쓰레드를 위한 my_thread_init() 와 my_thread_exit() functions 누락으로 server exit 이 발생되었던 것을 픽스 (Bug #25167032)

– InnoDB: row_search_mvcc() function 이 레코드가 트랜잭션 읽기 뷰에 없을 때 range query 에서 불필요하게 전체 테이블을 스캔하는 경우가 있었던 것을 픽스 (Bug #84202, Bug #23481444, Bug #25251375)

– mysqldump 가 덤프를 쓸때 올바르게 어떤 식별자identifiers 에 quote 를 달지 못하는 오류 픽스 (Bug #25717383)

https://bugs.mysql.com/bug.php?id=78777 픽스 후 발생한 사이드이펙트로 P_S 을 쓰지 않을 때 Query state 가 NULL 로 보여지는 문제에 대한 픽스 (Bug #25309017, Bug #84305) https://bugs.mysql.com/bug.php?id=84305

– libmysqlclient 에 링크된 client 가 prepared statement 사용 동안 잘못된 메모리 엑세스를 발생될 수 있었던 문제 픽스 (Bug #25164932)

– WHERE 절에 dependent subquery 가 있는 쿼리에서 테이블이 셀렉트리스트에 있는 컬럼과 서브쿼리에 사용되는 컬럼이 복합으로 구성된 세컨더리 인덱스가 있을 때, GROUP BY 또는 DISTINCT 쿼리가 Loose Index Scan (플랜상 Using index for group-by 로 표기) 을 사용하게 되어 쿼리가 잘못된 결과를 생산할 수 있었던 문제 픽스 https://bugs.mysql.com/bug.php?id=83005

– DISTINCT 와 집계aggregate 함수를 사용하는 쿼리가 잘못된 결과를 생산할 수 있었던 문제 픽스 (Bug #22686994, Bug #80310) https://bugs.mysql.com/bug.php?id=80310

– 빈로그포맷 statement 일 때 서버사이드 prepared statement (useServerPrepStmts=true) 사용 시 빈로그에 fractional part 가 드랍되어 기록됨, 마스터에서는 round 되고 슬레이브에서는 truncate 되어 데이터가 들어가 데이터 정합성이 맞지 않게 되는 문제 픽스 서버사이드 prepared statment 미사용시 timestamp 의 fractional part 가 유지되어 기록됨 (Bug #74550, Bug #19894382, Bug #25187670) https://bugs.mysql.com/bug.php?id=74550

Sysbench 1.0.4

2006년 부터 중단되었던 sysbench 가 2017년 2월 1.0 으로 재탄생 (오늘 1.0.4 가 나옴)

https://fosdem.org/2017/schedule/event/sysbench/

FOSDEM 2017 슬라이드, 비디오 참고

sysbench 가 할 수 있는 일은 ..
– 파일 I/O 성능 측정
– 스케쥴러 성능 측정
– 메모리 할당과 메모리 전송 속도 측정
– POSIX 쓰레드 구현 성능 측정

– 데이터베이스 서버 성능 측정

오랫동안 메인터넌스가 되고 있지 않던 툴인데 이번에 많은 부분에서 향상되었다고 함

– 더 나은 성능과 확장성

LuaJIT+FFI, 한개 이상 쓰레드로 돌릴 수 있음, concurrencykit, 뮤텍스mutex 없음, 공유 카운터 없음
– 커맨드라인 syntax 향상
구버전에서 옵션들이 sysbench 에서 글로벌옵션 형태로 Lua 스크립트로 export 되었으나,
이제 Lua 스크립트 자체에서 옵션들을 정의하고 sysbench 에서 validate 할 수 있음
– Plain Lua가 아니라 LuaJIT+FFI(Foreign Functions Interface)를 써서 순수한 Lua 코드에서 외부 C 함수 호출, C 데이터구조 사용을 허용
– 새로운 SQL API
향상된 성능, 쓰레드당 다중 커넥션 생성, 결과 세트results sets 받아서 추가 처리가 가능해짐
– 레이턴시 히스토그램 표기(–histogram)
– 에러 후킹Error Hook:
구 버전에서 단순히 에러번호 skip 했던 것 외에도 에러코드를 훅킹해서 커넥션을 다시 붙인다던지 하는 로직 처리 가능
– 커스텀 커맨드
prepare, run, cleanup, help 로 고정되어있던 명령어 외 스크립트가 자신만의 커맨드를 선언할 수 있음, 커스텀 커맨드를 병렬 처리 가능
– 커스텀 리포트
CSV, JSON 등으로 아웃풋 찍기, 결과를 Prometheus/Graphite/기타에 저장 연동

아직까지는 안되는 것, 미비한것:
Oracle, Drizzle, libattachsql 드라이버 미지원, PostgreSQL 드라이버 부족함

추가로 개선 예정인 부분들:
문서화, 패키징, syslinkbench, 몽고DB 드라이버, MySQL X Protocol

테스트//
syntax 가 다음과 같이 변경되어 있음

구버전) $ sysbench –test= [options…] command
신버전) $ sysbench [options]… [testname(path)] [command]

번들 제공되는 Lua 스크립트 옵션은 help 명령어로 확인

$ /usr/local/bin/sysbench /usr/local/share/sysbench/oltp_read_write.lua help
sysbench 1.1.0 (using bundled LuaJIT 2.1.0-beta2)

oltp_read_write.lua options:

  –distinct_ranges=N           Number of SELECT DISTINCT queries per transaction [1]
  –sum_ranges=N                Number of SELECT SUM() queries per transaction [1]
  –skip_trx[=on|off]           Don’t start explicit transactions and execute all queries in the AUTOCOMMIT mode [off]
  –secondary[=on|off]          Use a secondary index in place of the PRIMARY KEY [off]
  –create_secondary[=on|off]   Create a secondary index in addition to the PRIMARY KEY [on]
  –index_updates=N             Number of UPDATE index queries per transaction [1]
  –range_size=N                Range size for range SELECT queries [100]
  –auto_inc[=on|off]           Use AUTO_INCREMENT column as Primary Key (for MySQL), or its alternatives in other DBMS. When disabled, use client-generated IDs [on]
  –delete_inserts=N            Number of DELETE/INSERT combination per transaction [1]
  –tables=N                    Number of tables [1]
  –mysql_storage_engine=STRING Storage engine, if MySQL is used [innodb]
  –non_index_updates=N         Number of UPDATE non-index queries per transaction [1]
  –table_size=N                Number of rows per table [10000]
  –pgsql_variant=STRING        Use this PostgreSQL variant when running with the PostgreSQL driver. The only currently supported variant is ‘redshift’. When enabled, create_secondary is automatically disabled, and delete_inserts is set to 0
  –simple_ranges=N             Number of simple range SELECT queries per transaction [1]
  –order_ranges=N              Number of SELECT ORDER BY queries per transaction [1]
  –range_selects[=on|off]      Enable/disable all range SELECT queries [on]

  –point_selects=N             Number of point SELECT queries per transaction [10]

패키지가 없으니 설치는 다음과 같이 진행
automake, libtool, mysql-devel 필요할 수 있음

$ ./autogen.sh
$ ./configure –with-mysql-includes=… –with-mysql-libs=…
$ make

$ make install

예를 들어 번들 OLTP R/W 성능 측정 Lua 스크립트를 돌릴려면 다음과 같이 진행

$ /usr/local/bin/sysbench –mysql-host=localhost –mysql-port=3306 –mysql-socket=/var/run/mysqld/mysql.sock –mysql-user=XXXX –mysql-password=’XXXXX’ –threads=8 –time=300 –warmup-time=10 –report-interval=1 –tables=5 –table_size=1000000 –histogram /usr/local/share/sysbench/oltp_read_write.lua prepare

$ /usr/local/bin/sysbench –mysql-host=localhost –mysql-port=3306 –mysql-socket=/var/run/mysqld/mysql.sock –mysql-user=XXXX –mysql-password=’XXXXX’ –threads=8 –time=300 –warmup-time=10 –report-interval=1 –tables=5 –table_size=1000000 –histogram /usr/local/share/sysbench/oltp_read_write.lua run

$ /usr/local/bin/sysbench –mysql-host=localhost –mysql-port=3306 –mysql-socket=/var/run/mysqld/mysql.sock –mysql-user=XXXX –mysql-password=’XXXXX’ –threads=8 –time=300 –warmup-time=10 –report-interval=1 –tables=5 –table_size=1000000 –histogram /usr/local/share/sysbench/oltp_read_write.lua cleanup

Lua 스크립트 자유롭게 수정해서 나만의 케이스 만들어 볼 수 있겠음

MySQL 5.6.33 to 5.6.35

5.6 의 Bug #76872 로 인해 5.6.33 to 5.6.35 로 업데이트 진행, 그 밖에 많은 치명적 버그에 대한 픽스 반영

#5.6.33
버그:
mysqld_safe 에서 –malloc-lib 에 인자는 /usr/lib, /usr/lib64, /usr/lib/i386-linux-gnu, /usr/lib/x86_64-linux-gnu 중 하나에 존재해야함
추가하여, –mysqld 와 –mysqld-version 은 옵션파일이 아니라 커맨드라인에서만 허용됨 (Bug #24464380)
Bug #24619033, Bug #82920.

#5.6.34
패키징:
RPM 과 Debian 패키지가 /var/lib/mysql-files 디렉토리를 생성

보안:
(비호환) secure_file_priv 에 대한 동작 변경
– secure_file_priv 을 NULL 로 세팅하면 import/export 오퍼레이션을 완전히 끔
– 서버기동시 안전하지 않은 값이면 경고를 로그에 찍음, datadir 이나 그 하위 디렉토리, empty 값, 모든 유저에게 엑세스가 가능한 디렉토리라면 안전하지 않은 경로로 간주. 존재하지 않는 경로라면, 에러로그에 에러메시지 찍고 exit.
– CMake INSTALL_LAYOUT 값에 따라 default secure_file_priv 정해짐, DEB, RPM, SLES, SVR4 는 /var/lib/mysql-files/
– INSTALL_SECURE_FILE_PRIVDIR CMake 옵션사용하여 소스빌드시 secure_file_priv 값 명시할 수 있음

#5.6.35
(비호환) mysqld_safe 에 다음 변경사항이 적용됨

– mysqld_safe 내 안전하지 않은 rm 과 chown 이 비정상적인 권한 확대를 시킴, chown 은 타겟 디렉토리가 /var/log/ 일때만 사용이 가능.
Unix socket 파일을 위한 디렉토리가 존재하지 않는다면 더 더 이상 생성되어지지 않음, 대신 에러가 발생. 이러한 변경점 때문에 솔라리스에서는 mysqld_safe 를 실행시키는데 /bin/bash 가 필요함. 유닉스/리눅스 플랫폼에서는 /bin/sh 을 여전히 사용
– –ledir 옵션은 옵션파일이 아닌 커맨드라인에서만 허용됨
– mysqld_safe 는 현재의 working 디렉토리를 무시함

다른 관련 변경점:

– 초기Initialization 스크립트에서 mysqld_safe 에 –basedir 를 명시적으로 invoke
– 베이스 디렉토리가 /var/log 또는 /var/lib 인 경우에만 초기Initialization 스크립트들이 에러로그 파일을 생성
– 사용되지않는 SLES을 위한 systemd 파일이 제거됨

(Bug #24483092, Bug #25088048, Bug #25378439, Bug #25378565)
References: See also: Bug #24464380, Bug #24388753, Bug #24619033, Bug #82920.

– 연속적으로 커넥션이 실패할 경우 해당 클라이언트에 대해 서버의 응답에 딜레이를 줄 수 있는 Connection-Control 어드민 라이브러리 플러그인 추가

– InnoDB: 기본적으로 InnoDB 는 통계정보를 계산할 때 커밋되지 않은 데이터를 읽지만, 커밋되지 않은 트랜잭션이 테이블을 delete 하는 경우 InnoDB 가 row 평가estimation 와 인덱스 통계를 계산할 때 delete-marked 레코드를 제외하였음, 이는 동시적으로 READ UNCOMMITTED 외 다른 아이솔레이션 레벨을 쓰는 트랜잭션이 돌고 있을 때 최적화되지 않은 실행 계획에서 돌 수 있었음, 이 시나리오를 피하기 위해서 새로운 설정 옵션 innodb_stats_include_delete_marked 를 추가하여 persistent 옵티마이저 통계정보를 계산할 때 확실하게 InnoDB 가 delete-marked 레코드를 포함시킬 수 있도록 함, innodb_stats_include_delete_marked 이 켜져있으면 ANALYZE TABLE 은 통계정보를 갱신할 때 delete-marketd 레코드를 포함시킴, 기본값 OFF (Bug #23333990)

– InnoDB: glibc 버그로, caller 가 pthread_create() 로 부터 리턴값을 받기 전에 짧은시간 붙었다가 떨어진detached 쓰레드가 종료exit되어 서버 크래시를 유발할 수 있었음 Thanks to Laurynas Biveinis for the patch. (Bug #24605956, Bug #82886)
https://bugs.mysql.com/bug.php?id=82886

– InnoDB: SHOW ENGINE INNODB STATUS 시 idle 쓰레드의 상태가 “cleaning up” 으로 보여짐, 쓰레드 상태가 구문 수행 후 리셋되지 않음 (Bug #21974225, Bug #78777)
https://bugs.mysql.com/bug.php?id=78777

– InnoDB: 서버 재기동 이후, AI가 PK로 잡혀있는 한 테이블에 대한 동시 INERT 시 중복 키 에러가 발생, auto_increment_increment 와 auto_increment_offset 세팅 이후 auto-increment 값이 변경되지 않았었음 (Bug #20989615, Bug #76872)
https://bugs.mysql.com/bug.php?id=76872

– 몇몇의 리눅스 기동 스크립트는 datadir 을 제대로 세팅하지 않음 (Bug #25159791)

– CREATE TABLE … SELECT 도중에 발생할 수 있는 warning 이 서버 크래시를 유발 (Bug #24595992)

– .mylogin.cnf 옵션파일이 클라이언트 프로그램에서 사용되어지는 것을 염두해두고 만든 건데 서버도 그 파일을 읽었었음, 더 이상 서버는 이 파일을 읽지 않음 (Bug #24557925)

– union 쿼리의 결과 튜플이 max_join_size 를 넘어서는 경우 서버 크래시를 유발 (Bug #23303485)

– 옵티마이저가 코스트가 높은데도 불구하고, 프라이머리의 range 엑세스가 아니라 세컨더리 인덱스의 ref 억세스를 함 (Bug #23259872, Bug #81341)
https://bugs.mysql.com/bug.php?id=81341

– nested expression 가 심층적으로 들어갈 때 옵티마이저가 스택 오버플로를 감지하는데 실패함, 이는 서버 크래시를 유발 (Bug #23135667)

– 서버가 오프라인될 때 퍼포먼스스키마 내의 race condition 이 서버 크래시를 유발 (Bug #22551677)

– 퍼포먼스스키마의 events_statements_summary_by_digest 테이블이 같은 구문 digest 일 경우 유니크한 row 에 집계되어야하는데 다수의 row 에 집계될 수 있었음 (Bug #22320066, Bug #79533)
https://bugs.mysql.com/bug.php?id=79533

– 많은 동시 서버 커넥션이 있을 때 qsort 에 대한 메모리 계산이 잘못되어 스택 오버플로우 에러를 발생 (Bug #73979, Bug #19678930, Bug #23224078)
https://bugs.mysql.com/bug.php?id=73979

P_S Statement Digest

https://dev.mysql.com/doc/mysql-perfschema-excerpt/5.6/en/statement-summary-tables.html
https://dev.mysql.com/doc/refman/5.6/en/performance-schema-statement-digests.html

기본 구문 이벤트 테이블: events_statements_current, events_statements_history, events_statements_history_long
구문 집계 테이블: events_statements_summary_by_digest

DIGEST_TEXT: 노말라이즈된 구문 요약digest
DIGEST: MD5 해시값

statement_digest P_S 의 consumer가 켜져있으면(setup_consumers 참고), 구문이 끝날때 events_statements_summary_by_digest 집계가 발생
– 막 끝난 구문에 대한 digest 값이 events_statements_summary_by_digest row 에 이미 존재한다면 통계가 그 row 에 집계
– 만약 막 끝난 구문에 대한 digest 값이 있는 row 가 없다면, 그리고 테이블이 full 이 아니라면, 그 구문에 대한 row 가 새로 생성
– 만약 막 끝난 구문에 대한 digest 값이 있는 row 가 없고 테이블이 full 이라면, DIGEST=NULL row 하나에 포함되어 집계

P_S 테이블의 최대 사이즈 때문에 DIGEST=NULL row 가 존재할 수 있음
존재하는 row 와 매칭되지 않는 digest 들은 이 row 에 동일하게 취급되어 카운트됨
COUNT_STAR (집계된 이벤트 숫자) 값이 전체 digest COUNT_STAR 대비 50% 를 넘으면, digest 집계 테이블 정보가 모든 이벤트를 대표한다고 볼 수 없음, 5% 까지 대표한다고 봄

events_statements_summary_by_digest 테이블은 고정된 사이즈를 가짐
사이즈를 늘릴려면 performance_schema_digests_size 시스템변수 값을 조정, 지정하지 않는다면 서버가 알아서 기동시 지정 기본값 -1 (자동)

performance_schema_max_digest_length 시스템 변수는 digest 를 구하기 위한 최대 버퍼 사이즈를 결정
구문 키워드나 리터럴값의 내부 인코딩 때문에 사용 가능한 이 버퍼 사이즈보다 실제 더 길게 digest 가 표기될 수 있음
어플리케이션이 끝부분만 다른 매우 긴 구문을 생성한다면 이 값을 상향하여 집게시 구문을 분리하고 그렇지 않다면 하나의 집계 row에 포함시킬 수 있음
performance_schema_max_digest_length 은 세션별로 메모리가 할당되므로 동시다발적인 많은 센션이 로드를 준다면 높은값은 주의!

https://dev.mysql.com/doc/refman/5.6/en/performance-schema-status-variables.html
– Performance_schema_digest_lost: events_statements_summary_by_digest 테이블에 digest 가 기록되지 못환 횟수, performance_schema_digests_size 가 너무 작아서 발생할 수 있음
– Performance_schema_accounts_lost: accounts 테이블이 full 이라 기록되지 못한 횟수, performance_schema_accounts_size 조정
– Performance_schema_hosts_lost: hosts 테이블이 full 이라 기록되지 못한 횟수, performance_schema_hosts_size 조정

summary 테이블 TRUNCATE 수행 시,
– events_statements_summary_by_digest 는 row 들을 삭제
– account, host, user 로 집계하지않는 다른 summary 테이블들은 row 들을 삭제하는 대신에 summary 컬럼을 0으로 세팅
– account, host, user 로 집계하는 다른 summary 테이블들은 커넥션 이력이 없는 account, host, user 관련 row들을 삭제하고 나머지 존재하는 row 들의 summary 컬럼들을 0으로 세팅
– account, host, user, thread 로 집계되는 각각의 statement summary 테이블들은 연관된 커넥션 테이블(accounts, hosts, users)이나 events_statements_summary_global_by_event_name 의 truncatation 으로 암시적으로 truncate 됨

MySQL PK Constraint symbol

http://dev.mysql.com/doc/refman/5.6/en/create-table.html
MySQL CREATE TABLE 레퍼런스에 보면 PK 도 임의의 이름을 가질 수 있을 것 처럼 해놓음

create_definition:
    col_name column_definition
  | [CONSTRAINT [symbol]] PRIMARY KEY [index_type] (index_col_name,...)
      [index_option] ...

symbol 로 표현할 수 있는데, syntax error 는 발생하지 않지만 I_S 어디에서도 찾을 수 없음
아마 KEY 선언 시 DESC 과 같은 순서 지정이 무시discard 되는 것처럼 요것도 그런게 아닐까 함
레퍼에는 또 친절하게 다음과 같이 쓰여있음- _-)..

  • In MySQL, the name of a PRIMARY KEY is PRIMARY. For other indexes, if you do not assign a name, the index is assigned the same name as the first indexed column, with an optional suffix (_2, _3, ...) to make it unique. You can see index names for a table using SHOW INDEX FROM tbl_name.