MySQL Bugs

MySQL 5.6.37

https://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-37.html
오픈소스 지원한다 말만 하지말고 내용 공개나 제대로 했음 좋겠음, 절반 이상이 내부 트래킹 넘버를 달고 있어서 알 수가 없음.

영향이 있을만한 것들을 나열해보면..

– InnoDB: 테이블 리빌드 오퍼레이션을 위해 불필요하게 메모리 할당을 함 (Bug #25573565, Bug #85043) https://bugs.mysql.com/bug.php?id=85043 (비공개)

– InnoDB: index merge 옵티마이저 스위치 쓸 때, SELECT COUNT(*) 오퍼레이션 결과가 가끔 0을 리턴. 파티셔닝 테이블 코드가 인덱스 read 한 컬럼들 복사하는 대신에 memcpy 를 부정확하게 수행하여 잘못된 레코드가 복사됨. (Bug #25332330, Bug #81031) https://bugs.mysql.com/bug.php?id=81031

– 리플리케이션: 릴레이 로그 인덱스 파일에 존재하지 않는 릴레이 로그가 명시되어있다면 RESET SLAVE ALL 이 때때로 완전히 슬레이브 정보를 클린업하지 못함. (Bug #24901077)

– 리플리케이션: mysqlbinlog 유틸에서 –raw 옵션으로 invoke 되면 프로세스가 종료될 때까지 output 파일을 flush 하지 않았었음. 이제 output 이 매 이벤트 이후 마다 flush 됨. –stop-never 옵션이 같이 invoke 된다면 output 파일로 아무것도 기록되지 않아서 괜찮음. (Bug #24609402)

– 리플리케이션: mysqlbinlog 의 메모리 누수가 픽스됨. fake rotate 이벤트를 수행할 때 또는, –raw 사용하여 도착지 로그 파일이 생성되지 않을때 발생하였음. 메모리 누수는 원격서버로 부터 이벤트를 수행할 때만 발생. 컨트리뷰터 Laurynas Biveinis (Bug #24323288, Bug #82283) https://bugs.mysql.com/bug.php?id=82283

– mysqldump 가 USE 구문에 데이터베이스명을 잘못 기록 할 수 있었음. (Bug #25998635)

– 잘못된 메모리에 대한 엑세스로 서버가 비정상적으로 종료될 수 있었음. (Bug #25501659)

– 섭쿼리 내 UNION 과 GROUP BY 가 포함된 쿼리가 잘못된 결과를 리턴할 수 있었음. (Bug #24595639)

릴리즈 될 때마다 잘 정리해주는 블로그//
http://mysqlentomologist.blogspot.kr/2017/07/fun-with-bugs-54-on-some-bugs-fixed-in.html

Advertisements

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

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

DML Explain Bug

MySQL 5.6 에서부터 DML구문에 대한 실행계획 조회가 가능
https://dev.mysql.com/doc/refman/5.6/en/explain.html

하지만 readonly 서버로 설정이 되어있을 때 ERROR:1290 – The MySQL server is running with the –read-only option so it cannot execute this statement 에러가 발생함

DML Explain 시 com_delete, com_update 등 엔진 내부의 커맨드 수행 카운터가 올라가는 것으로 보아 추측컨데 DB에서 DML 쿼리가 수행(explain 시 반영되지 않음)될 때 서버옵션인 readonly 체크가 사전 동작해서 explain 이 막히는 것 같음

MySQL 버그리포트에 확인됨verified 상태로 오픈되어있으며 MySQL 5.7 에서도 동일 문제 발생하는 것을 확인

Non-critical 레벨로 버그에 대한 이제까지의 오라클의 행태?로 봐서는 언제 fix 될지 의문임
https://bugs.mysql.com/bug.php?id=73258

쿼리를 SELECT 로 바꿔서 참고 해야할 듯

Order By .. Low Limit Bug

MySQL 5.6 에서 ORDER BY (GROUP BY 도 영향이 있는 듯) 와 LIMIT 이 결합되는 쿼리일 때, LIMIT 0, 100 등의 increment 값이 매우 낮게 지정되어있는 경우 ORDER BY 에 적용하는 정렬 인덱스를 옵티마이저가 변경하는 경우가 있음, 본래 row estimation 해서 cost 기반으로 판단하는 것이 성능상에 이득임에도 불구하고 특정 케이스(옵티마이저가 판단하는 row estimation 값 임계치에 부합하면)에서 cost 대신 휴리스틱heuristic 기반으로 사용인덱스가 결정이 됨

optimizer tracing 을 해보면 join optimization 부분에서 recheck_reason 이 low_limit 으로
row count 가 매우 많은 인덱스로 변경하는 것을 확인할 수 있음

5.7.6 에서 cost 기반으로 항상 동작하도록 패치되었으나, 5.6 으로 백포팅 되지 않음..

5.7.6 변경로그//
https://dev.mysql.com/doc/relnotes/mysql/5.7/en/news-5-7-6.html
레퍼런스: 버그 #73837, #19579507, #16522053.

버그리포트//
https://bugs.mysql.com/bug.php?id=74602
https://bugs.mysql.com/bug.php?id=73837
https://bugs.launchpad.net/percona-server/+bug/1362212

5.7패치로그//
http://dev.mysql.com/worklog/task/?id=6986
Make switching of index due to small limit cost-based (WL#6986) : This work by Chaithra Gopalareddy makes the decision in make_join_select() of whether to switch to a new index in order to support “ORDER BY … LIMIT N” cost-based. This work fixes Bug#73837.

예시//
#cost 가 나쁜 const key IDX_BAD 가 후보로 들어감
“rows_estimation”: [
{
“table”: “`HISTORY_TABLE` `A`”,
“const_keys_added”: {
“keys”: [
“IDX_BAD”
],
“cause”: “group_by”
},
“range_analysis”: {
“table_scan”: {
“rows”: 23326957,
“cost”: 5.68e6
},

#cost 좋은 IDX_GOOD 처음에 선택했다가
“chosen_range_access_summary”: {
“range_access_plan”: {
“type”: “range_scan”,
“index”: “IDX_GOOD”,
“rows”: 78210,
“ranges”: [
“2016-08-09 00:00:00 <= COMPLETE_DT <= 2016-08-09 23:59:59”
]
},
“rows_for_plan”: 78210,
“cost_for_plan”: 93853,
“chosen”: true
}

#low_limit 의 이유로 rechecking 이 들어감
“attached_conditions_computation”: [
{
“table”: “`HISTORY_TABLE` `A`”,
“rechecking_index_usage”: {
“recheck_reason”: “low_limit”,
“limit”: 100,
“row_estimate”: 78210
}
}

#인덱스 정렬을 위한 엑세스 방식을 IDX_BAD로 변경
{
“reconsidering_access_paths_for_index_ordering”: {
“clause”: “GROUP BY”,
“index_order_summary”: {
“table”: “`HISTORY_TABLE` `A`”,
“index_provides_order”: true,
“order_direction”: “asc”,
“disabled_pushed_condition_on_old_index”: true,
“index”: “IDX_BAD”,
“plan_changed”: true,
“access_type”: “index_scan”
}
}
}

MySQL 5.6 fsp rounding 문제

https://bugs.mysql.com/bug.php?id=68760
https://bugs.mysql.com/bug.php?id=76948
https://bugs.mysql.com/bug.php?id=82325

5.6 에서 fsp 를 허용하면서 밀리세컨드 부분을 반올림(round)하는 버그가 있다는 리포트들이 있음
실제 지정한 fsp 값을 넘어서는 값을 넣게되면 rounding 함 (5.6.30 에서 테스트)

MySQL 구버전 호환성을 위해 fsp 선언이 생략되면 SQL 표준인 6이 아니라 0으로 디폴트 설정한다고 레퍼런스에 되어 있는데,
If omitted, the default precision is 0. (This differs from the standard SQL default of 6, for compatibility with previous MySQL versions.)
http://dev.mysql.com/doc/refman/5.6/en/fractional-seconds.html

higher precision 값을 lower precision 데이터타입에 집어넣는다면 rounding 하는 것이 SQL의 표준 동작방식이며 따라서 DATETIME(0)=DATETIME 에 DATETIME(1)의 값을 넣는다면 warning 없이 rounding 되는 것이 표준이긴 하다라는 것이 오라클 엔지니어 의견
다만 MySQL 구버전 호환성…을 위해 비표준 디폴트값을 가져가고 있으니 warning 이 발생하도록 조치하는 것을 고려해봐야 한다고 함

[25 Jul 18:50] Roy Lyseng
SQL standard does not require a warning when assigning a value with higher precision to a target with lower precision. Thus, assigning a datetime(1) value like ‘2016-07-22 12:49:07.5’ to a datetime(0) column will cause automatic rounding, and the inserted value should be ‘2016-07-22 12:49:08’, with no warning issued.
However, when doing the comparison, both values are converted to datetime(1), so the comparison is done as ‘2016-07-22 12:49:07.5’ = ‘2016-07-22 12:49:08.0’, which is obviously false.
I would say this is not a bug. We might consider adding a warning for the truncation as part of the assignment, but that would be a feature request.
Note also that the problem is independent of whether rounding or truncation is used.

5.5 에서는 아예 fsp 가 무시되어 truncated 되다보니 이슈가 되나 봄

IN 서브쿼리 SELECT 리플리케이션 시 지연

슬레이브: 5.6, 마스터: 5.5

IN절에 다건을 검색하여 업데이트 하는 쿼리로 5.5 에서는 서브쿼리 처리가 어려워 다음과 같이 풀스캔 실행계획으로 롱런됨
id select_type table type possible_keys key key_len ref rows Extra
—— —————— —————– ————— ——————— ——- ——- —— —— ————-
1 PRIMARY extra ALL (NULL) (NULL) (NULL) (NULL) 985424 Using where
2 DEPENDENT SUBQUERY deal unique_subquery PRIMARY,srl PRIMARY 8 func 1 Using where

IN절 처리가 제대로되는 5.6에서는 실행계획이 괜찮으나,
id select_type table type possible_keys key key_len ref rows Extra
—— ———– —————– —— ——————— ————- ——- ————————– —— ————-
1 SIMPLE deal ref PRIMARY,srl srl 8 const 1 Using index
1 SIMPLE extra eq_ref PRIMARY PRIMARY 8 srl 1 (NULL)

리플리케이션을 받을 때 preparing 상태로 지연이 발생

버그리포트에 IN 서브쿼리 리플리케이션 시 지연되는 리포트가 있으며, 현 버전까지 딱히 fix 가 된 것 같지 않음
Query gets stuck in the “PREPARING” https://bugs.mysql.com/bug.php?id=29423
Subquery keeps the mysqld server in preparing phase https://bugs.mysql.com/bug.php?id=45365

대처는 .. 조인 업데이트 하던지, 로직에서 srl 을 분리 처리하던지