MySQL General

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초가 걸림)

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.

MySQL 8.0(5.8)

Percona Live 2016 가 진행중인데 5.8 (8.0?) 에 대한 트윗이 Percona 쪽에서 올라옴
https://www.percona.com/about-percona/team/david-bennett

8h8 hours ago
MySQL 5.8 will be called MySQL 8.0 5.8 버전은 8.0 으로 불리게 될 것

8h8 hours ago
MySQL 8.0 Data Dictionary. No more FRM files, separate DDL log for changes, Atomic DDL changes.
메타데이터를 저장하던 FRM 파일이 없어짐, 변경을 위한 DDL 로그가 분할됨, DDL 변경을 atomic 한 단위로 진행

8h8 hours ago
MySQL 8.0 can be completely MyISAM free.
완전히 MyISAM 을 버리게 됨

7h7 hours ago
MySQL 8.0 virtual indexes can ref JSON doc arrays.
가상컬럼이 JSON 다큐먼트 어레이를 참조할 수 있음

7h7 hours ago
MySQL 8.0 optimizer will consider memory, SSD, HDD in query plan.
옵티마이저는 이제 실행계획에서 H/W 에 대한 부분-memory, SSD, HDD-에 대해 고려함

sys schema 1.5.1 (updated)

https://github.com/mysql/mysql-sys

performance_schema, information_schema 를 좀 더 쉽게, 유저 친화적으로 집계해주는 뷰와 간단한 함수, 프로시져의 모음

현재 MySQL Workbench 에서 설치가능한 Helper 는 sys schema 1.4 버전으로 MySQL 5.7.9 부터는 sys schema 1.5 가 탑재됨, 5.6은 github 에서 받아서 설치
현 버전 1.5.1

1.테이블
sys_config 주로 SYS 루틴에 대한 옵션 설정2.뷰
version SYS 버전
ps_check_lost_instrumentation P_S 집계 빠지는lost instrument 와 개수
metrics 서버 수치, P_S 의 global_status, I_S 의 INNODB_METRICS, P_S memory instrumentation 에 기반한 현재, 총 메모리 할당, 스냅샷 시간 합침–세션/쓰레드
processlist 백그라운드 쓰레드 포함 넌블락킹 프로세스리스트
session 유저 넌블락킹 프로세스리스트
session_ssl_status 커넥션 ssl 정보 (n/a)
schema_table_lock_waits 메타데이터락을 위해 대기하는 세션 (n/a)
innodb_lock_waits InnoDB 락 스냅샷 정보
io_by_thread_by_latency 쓰레드별 I/O 소비
latest_file_io 파일,쓰레드별 가장 최근의 I/O (NULL)

–스키마
schema_auto_increment_column 전체 AI 정보 조회 (00s+)
schema_index_statistics 전체 인덱스 정보 조회 (5s+)
schema_unused_indexes 집계이후 사용되지 않는 인덱스
schema_redundant_indexes 도미넌트 인덱스와 중복되는 인덱스 (3s+)
schema_object_overview 데이터베이스별 오브젝트 숫자
schema_table_statistics 테이블 스키마 통계
schema_table_statistics_with_buffer 버퍼풀 포함한 테이블 스키마 통계 (3m+)
schema_tables_with_full_table_scans 테이블별 풀스캔 레코드, 지연

–호스트
host_summary 호스트별 구문 액티비티, 파일 I/O, 커넥션 집계 (5.7이면 메모리사용)
host_summary_by_stages 호스트별 구문 스테이지 (NULL)
host_summary_by_file_io_type 호스트,이벤트별 파일 I/O
host_summary_by_statement_latency 호스트별 구문 통계
host_summary_by_statement_type 호스트,구문별 수행 통계
waits_by_host_by_latency 호스트별 지연

–구문
statement_analysis 구문 집계 통계, P_S의 events_statements_summary_by_digest
statements_with_errors_or_warnings 에러와 경고를 발생시킨 구문
statements_with_full_table_scans 풀스캔이 된 구문
statements_with_runtimes_in_95th_percentile 높은 평균 수행시간을 가지는 구문
statements_with_sorting 정렬이 진행된 구문
statements_with_temp_tables 임시테이블 사용한 구문

–파일
io_global_by_file_by_bytes 파일,바이트별 글로벌 I/O 소비 (5s+)
io_global_by_file_by_latency 파일,지연별 글로벌 I/O 소비 (5s+)
io_global_by_wait_by_bytes 바이트별 글로벌 I/O 소비
io_global_by_wait_by_latency 지연별 글로벌 I/O 소비

–유저/이벤트
user_summary 유저 구문, 커넥션 활동
user_summary_by_file_io 유저별 파일 I/O
user_summary_by_file_io_type 유저별,이벤트별 파일 I/O
user_summary_by_stages 유저별 스테이지 이벤트 (NULL)
user_summary_by_statement_latency 유저별 구문 통계
user_summary_by_statement_type 유저별,구문별 수행된 구문
waits_by_user_by_latency 유저별,이벤트별 지연
wait_classes_global_by_avg_latency 이벤트별 평균 지연
waits_global_by_latency 이벤트별 지연

–메모리
innodb_buffer_stats_by_schema 스키마별 버퍼 정보 (00s+)
innodb_buffer_stats_by_table 스키마,테이블별 버퍼 정보 (00s+)
memory_by_host_by_current_bytes 호스트별 메모리사용 (5.7)
memory_by_thread_by_current_bytes 쓰레드별 메모리사용 (5.7)
memory_by_user_by_current_bytes 유저별 메모리사용 (5.7)
memory_global_by_current_bytes 할당 타입별 메모리사용 (5.7)
memory_global_total 총 메모리사용 (5.7)

3. 프로시져
create_synonym_db() 지정한 데이터베이스의 synonym 스키마 생성 내부에 테이블들을 view 로 가지고 있음
diagnostics() 진단 목적으로 현재의 서버 현황 리포트를 생성
execute_prepared_stmt() prepared statement 로 쿼리를 수행
ps_setup_disable_background_threads() P_S의 모든 백그라운드 쓰레드를 비활성화
ps_setup_disable_consumer() 주어진 이름을 가진 P_S의 consumer를 비활성화
ps_setup_disable_instrument() 주어진 이름을 가진 P_S의 instrument를 비활성화
ps_setup_disable_thread() 주어진 커넥션ID에 대한 P_S instrument를 비활성화
ps_setup_enable_background_threads() P_S의 모든 백그라운드 쓰레드를 활성화
ps_setup_enable_consumer() 주어진 이름을 가진 P_S consumer를 활성화
ps_setup_enable_instrument() 주어진 이름을 가진 P_S instrument를 활성화
ps_setup_enable_thread() 주어진 커넥션ID에 대한 P_S instrument를 활성화
ps_setup_reload_saved() 같은 세션내 ps_setup_save()로 저장한 P_S설정을 복구
ps_setup_reset_to_default() P_S 설정을 디폴트세팅으로 리셋
ps_setup_save() 디버깅이나 다른 목적으로 설정을 ALTER 전, 현재상태의 P_S 설정을 저장
ps_setup_show_disabled() 현재 비활성화된 모든 P_S 설정을 보여줌
ps_setup_show_disabled_consumers() 현재 비활성화된 모든 consumer를 보여줌
ps_setup_show_disabled_instruments() 현재 비활성화된 모든 instrument를 보여줌, 결과가 길 수 있음
ps_setup_show_enabled() 현재 활성화된 P_S 설정을 보여줌 configuration.
ps_setup_show_enabled_consumers() 현재 활성화된 모든 consumer를 보여줌
ps_setup_show_enabled_instruments() 현재 활성화된 모든 instrument를 보여줌, 결과가 길 수 있음
ps_statement_avg_latency_histogram() P_S events_statements_summary_by_digest의 노말라이즈쿼리 평균지연시간을 보여주는 히스토그래프
ps_trace_statement_digest() 주어진 statement digest(MD5값)에 대해 모든 P_S instrumentation을 트레이싱
ps_trace_thread() P_S 데이터를 .dot 포맷의 그래프파일로 덤프
ps_truncate_all_tables() P_S 써머리 테이블을 truncate, 모든 집계된 instrumentation 을 리셋
statement_performance_analyzer() 서버에서 수행되고있는 구문들의 리포트를 생성
table_exists() 주어진 이름의 일반테이블/임시테이블/뷰가 존재하는지 확인

4. 뷰
extract_schema_from_file_name() 파일 경로에서 데이터베이스 명을 추출
extract_table_from_file_name() 파일 경로에서 테이블 명을 추출
format_bytes() byte 값을 가독성이 높은 units 단위 값(KiB, MiB, GiB, TiB ..)으로 변환
format_path() 파일 경로를 @@datadir, @@tmpdir 등 내부적으로 알려진 경로명으로 대체하여 줄임
format_statement() 긴 구문을 statement_truncate_len 에 설정된 고정된 길이로 truncate, 길면 생략문자(…)가 들어감
format_time() P_S 지연에 대한 picoseconds 값을 가독성이 높은 units 단위 값(ns, us, ms, s, m, h, d, w)으로 변환
list_add() 리스트에 아이템을 추가
list_drop() 리스트에서 아이템을 제거
ps_is_account_enabled() 인자로 주어진 account 를 위한 instrumentation 이 활성화되어있는지 여부 리턴
ps_is_consumer_enabled() 인자로 주어진 P_S consumer 가 활성화인지 여부 리턴
ps_is_instrument_default_enabled() 인자로 주어진 P_S instrument 가 기본적으로 활성화인지
ps_is_instrument_default_timed() 인자로 주어진 P_S instrument 가 기본적으로 timed 인지 여부
ps_is_thread_instrumented() 인자로 주어진 커넥션ID에 대해 P_S instrumentation이 켜져있는지 여부
ps_thread_account() 인자로 주어진 쓰레드ID에 대해 쓰레드와 연관된 user_name@host_name을 리턴
ps_thread_id() 커넥션ID에 대한 내부 쓰레드ID를 리턴
ps_thread_stack() 주어진 쓰레드ID에 대해 모든 구문, 스테이지, 이벤트의 스택정보를 JSON 포맷으로 리턴
ps_thread_trx_info() 주어진 쓰레드ID에 대한 정보를 JSON 포맷으로 리턴, P_S events_transactions_current, events_statements_history
quote_identifier() 인자로 주어진 스트링을 `식별자`로 리턴
sys_get_config() 설정 옵션 파일명을 인자로 받아 sys_config 테이블에서 옵션 값 리턴
version_major() MySQL 서버 메이저 버전 넘버 리턴
version_minor() MySQL 서버 마이너 버전 넘버 리턴
version_patch() MySQL 서버 패치 릴리즈 버전 넘버 리턴

MySQL 함수 사용 시 NAME_CONST 변환

프로덕션에서 character set 관련 변수들이 모두 utf8 임에도 불구하고 쿼리 내 함수 수행 시 입력 변수 부분에 NAME_CONST latin1 이 붙는 현상

select if( NAME_CONST(‘s_date’,_latin1’2016-03-29 17:36:10′ COLLATE ‘latin1_swedish_ci’) < NAME_CONST(‘c_date’,_latin1’2016-03-22′ COLLATE ‘latin1_swedish_ci’) , datediff( NAME_CONST(‘c_date’,_latin1’2016-03-22′ COLLATE ‘latin1_swedish_ci’), NAME_CONST(‘s_date’,_latin1’2016-03-29 17:36:10′ COLLATE ‘latin1_swedish_ci’)) – dbtest.fn_count( NAME_CONST(‘s_date’,_latin1’2016-03-29 17:36:10′ COLLATE ‘latin1_swedish_ci’), NAME_CONST(‘c_date’,_latin1’2016-03-22′ COLLATE ‘latin1_swedish_ci’)) , datediff( NAME_CONST(‘c_date’,_latin1’2016-03-22′ COLLATE ‘latin1_swedish_ci’), NAME_CONST(‘s_date’,_latin1’2016-03-29 17:36:10′ COLLATE ‘latin1_swedish_ci’)) + dbtest.fn_count( NAME_CONST(‘c_date’,_latin1’2016-03-22′ COLLATE ‘latin1_swedish_ci’), NAME_CONST(‘s_date’,_latin1’2016-03-29 17:36:10′ COLLATE ‘latin1_swedish_ci’)) ) into diffdays

+————————–+—————————-+
| Variable_name | Value |
+————————–+—————————-+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+————————–+—————————-+

http://www.justincarmony.com/blog/2011/02/02/mysql-stored-procedure-name_const-and-character-sets/

위 블로그에서는 @variable 을 설정하여 NAME_CONST 변환을 우회하여 속도 향상을 시켰다고 함
(utf8 에서 latin1 으로 변경), 적용 시 개선 확인이 어려웠음

MySQL 에서 MariaDB 로 마이그레이션 해야할 10가지 이유

MySQL 에서 MariaDB 로 마이그레이션 해야할 10가지 이유
https://seravo.fi/2015/10-reasons-to-migrate-to-mariadb-if-still-using-mysql
2015년 초 글, 아직까지 지켜봐야할 것 같지만:-)

1) MariaDB 개발이 좀 더 개방적이고 활발함
– MySQL 5.7 커밋 로그엔 컨트리뷰터들이 @oracle.com
https://github.com/mysql/mysql-server/
– MariaDB 는 공개 메일링 리스트와 버그트래커가 있고 완전히 공개된 소스코드 리파지토리가 있음
https://launchpad.net/~maria-developers
https://jira.mariadb.org/secure/Dashboard.jspa
https://github.com/MariaDB/server
– MariaDB 가 github 에 컨트리뷰터 수가 많음
– 래드햇 배포본 등에도 MariaDB 가 들어감
– 문서화에 더 열심인 걸로 보임
– MySQL 에 현재 큰 모멘텀 있고 커뮤니티가 여전히 많지만 MariaDB 중심으로 새 움직임이 있음

2) 빠르고 투명한 보안패치 릴리즈
– 오라클은 3개월 주기로 보안패치를 적용 (MySQL 은 2개월 주기)
– 간혹 보안 정보와 업그레이드가 싱크가 맞지 않는 경우가 발생함
– MySQL 은 릴리즈노트에 CVE 식별번호가 모두 리스트업 되지 않음
– 이슈와 픽스에 대한 확인이 모호하여 불만들이 많음
https://lists.launchpad.net/maria-discuss/msg00514.html
– 백포팅이 불가능하게 함, 최신의 MySQL 릴리즈로 업그레이드 할 수 밖에 없는 상황이 있음
– MariaDB 는 CVE 식별번호를 명시하고 이슈 관리를 잘함

3) 좀 더 다듬어진 기능들
– MySQL 5.7 에서 GIS 지원 하지만 MariaDB 는 더 많은 기능들 포함
https://mariadb.com/kb/en/mariadb/mariadb-vs-mysql-features/
https://mariadb.com/products/mariadb#highlight2-wrapper
– 예를 들어 GIS 는 MariaDB 5.3 에서 이미 소개되었음
– MariaDB 는 Dynamic 컬럼 지원

4) 더 많은 스토리지 엔진
– Connect 와 Cassandra, 샤딩을 위한 Spider, 프랙탈 인덱스의 TokuDB
– MySQL 에서도 써드파티 플러그인 형태로 사용은 가능하나 MariaDB 는 공식 릴리즈에 포함시켜 사용이 쉬움

5) 나은 성능
– MariaDB 옵티마이저 성능이 향상되었다고 주장하고 벤치 결과도 나와 있음
– 하지만 이것은 환경에 따라 실제와 좀 다를 수 있음, 아티클엔 3-5% 차이라고 언급

6) Galera 액티브-액티브 마스터 클러스터링
– 2007에 개발을 시작했지만 Percona 와 MariaDB 에서 도입한 이후에도 오라클 MySQL 에 공식적으로 포함되지 않았음
http://galeracluster.com/

7) 오라클 관리하의 불확실성
– 많은 사람들이 MySQL 을 살려두는 오라클의 본 목적을 의심함
– 오라클은 처음에 EU 반독점규제로 썬을 합병할 수 없었는데 MySQL을 살리는 것으로 합병을 승인했다고 함
http://www.oracle.com/us/corporate/press/042364
– 문서에 존속에 대한 만기가 2014년말로 되어있고 이미 지났음
– 아마 오라클 경영진들은 MySQL의 미래에 대해 생각하고 있을 것임
– 오라클이 미묘한 방법으로 벌써 MySQL 약화를 진행하고 있다는 논쟁도 있었음 (2번 참조)
https://lists.launchpad.net/maria-discuss/msg00514.html
– 하지만 오라클 MySQL 활동이 리브레오피스나 젠킨스로 빠르게 포크된 이후 사장된 오픈오피스나 허드슨에 비해 훨씬 성공적이라는 것은 참고할 만함
– 반면에 오라클과 참된 오픈소스 프로젝트 간에 선택이 주어질 때 소프트웨어 자유와 협력 개발의 이점을 잘 알고 있는 사람이라면 선택이 어렵지 않을 것임

8) 유명세가 높아지고 있음
– 2013년 위키피디아 마이그레이션
http://www.infoworld.com/article/2614268/open-source-software/wikipedia-dumps-mysql–hooks-up-with-mariadb.html
– 2013년 구글의 MariaDB 사용
http://www.zdnet.com/article/google-quietly-dumps-oracle-mysql-for-mariadb/
– WordPress, booking.com, Craiglist 의 서포트
https://mariadb.org/about/supporters/
– 페도라, OpenSUSE 의 기본 데이터베이스, RHEL7, SUSE Enterprise 12 부터 MySQL 대신 MariaDB 5.5 탑재, Ubuntu 14.04

9) 호환성과 쉬운 마이그레이션
– MariaDB 5.5 는 바이너리 교체로 MySQL 5.5 를 완전히 대체할 수 있음

10) 15년 이후에는 마이그레이션이 어려울 수 있음
– MariaDB 10.0 과 MySQL 5.6 에서 분기하기 시작했으나 어려움없이 전환이 가능함
– MariaDB 10.1 과 MySQL 5.7 에서는 어려울 수도 있으며 덤프 후 새 데이터베이스에 밀어넣어야 할 수 있음