MariaDB
글
-
MariaDB 소스 파헤치기 1: AI와 함께 소스를 읽는 방법과 분석 지도
MariaDB가 무엇이고 어떻게 동작하며 어디에 쓰는지를 그림과 3분 실습으로 먼저 보고 시작하는, MariaDB 서버 소스 읽기 연재의 첫 글입니다. 어떤 판(main 브랜치, 13.2.0 alpha)을 읽는지와 LTS 판과의 차이, 서브모듈까지 같은 소스를 받아 도커에서 Debug 빌드하는 법(Windows에서 CRLF 때문에 빌드가 깨진 이유 포함), 259만 줄짜리 소스의 폴더 지도, 쿼리 하나가 연결 스레드에서 InnoDB까지 지나는 큰 길을 gdb 백트레이스로 확인한 결과, 그리고 AI가 쓴 노트를 소스로 다시 확인하며 읽는 방법을 정리합니다.
-
MariaDB 소스 파헤치기 2: 전체 지도 — 서버 계층과 스토리지 엔진, 그리고 쿼리 하나의 일생
MariaDB 소스를 처음 여는 중급 개발자를 위한 연재의 지도입니다. 서버 계층(sql/)과 스토리지 엔진(storage/)을 왜 나눴는지, 둘의 경계인 handler(테이블을 연 객체)와 handlerton(엔진마다 하나인 함수 포인터 표)이 어떻게 생겼는지, SELECT 하나가 연결 → THD → 파싱 → 준비 → 최적화 → 실행 → handler → 엔진을 지나 Protocol 로 돌아오는 길, 그리고 그 모든 객체를 문장마다 한꺼번에 치우는 MEM_ROOT 를 실제 소스와 gdb 백트레이스로 확인합니다.
-
MariaDB 소스 파헤치기 3: 기동과 플러그인 — mariadbd가 첫 연결을 받기까지
mariadbd 를 켜면 첫 연결을 받기 전까지 무슨 일이 일어나는지 sql/mysqld.cc 의 mysqld_main() 을 따라 읽습니다. my.cnf 한 줄이 시스템 변수가 되는 길, InnoDB·Aria 같은 엔진까지 전부 플러그인으로 등록하고 초기화하는 plugin_init(), 엔진이 handlerton 을 채우는 ha_initialize_handlerton(), 신호 스레드와 poll() 루프, 그리고 종료가 기동의 거꾸로 일어나는 모습을 오류 로그와 gdb 로 확인합니다.
-
MariaDB 소스 파헤치기 4: 연결과 스레드 — 연결마다 스레드 하나, 그리고 스레드 풀
mariadbd 의 메인 스레드가 poll() 로 접속을 받아 CONNECT 를 만들고, thread_handling 이 고른 스케줄러(함수 포인터 묶음)에 넘기기까지를 소스로 따라갑니다. 연결마다 스레드 하나를 두는 기본 모드와 스레드 캐시, THD 를 만들고 인증하는 로그인 단계, 그리고 스레드 그룹·리스너·워커·timer_thread 로 이루어진 스레드 풀이 놀고 있는 연결을 스레드에서 떼어 내는 방법을 ps·information_schema·gdb 실행 결과로 확인하고, httpd 의 MPM·Tomcat 의 엔드포인트와 비교합니다.
-
MariaDB 소스 파헤치기 5: 프로토콜과 명령 처리 — 패킷 하나가 dispatch_command에 닿기까지
클라이언트가 보낸 바이트가 어떻게 패킷이 되고, 첫 바이트 하나로 COM_QUERY·COM_PING·COM_STMT_EXECUTE가 갈리고, 결과가 다시 패킷이 되어 나가는지를 sql/net_serv.cc, sql_parse.cc의 do_command()·dispatch_command(), protocol.cc로 따라갑니다. bash의 /dev/tcp로 클라이언트 라이브러리 없이 서버와 직접 말을 주고받고, 쿼리 캐시가 왜 파싱보다 먼저 문자열로 찾는지도 실행해서 확인합니다.
-
MariaDB 소스 파헤치기 6: 파서 — SQL 문장이 LEX와 Item 나무가 되기까지
문자열로 들어온 SQL 한 문장이 렉서(Lex_input_stream)에서 토큰이 되고, Bison이 만든 파서(MYSQLparse·ORAparse)의 규칙 액션에서 LEX·SELECT_LEX·TABLE_LIST·Item 나무가 되는 과정을 소스로 따라갑니다. 문법 파일 하나에서 파서 두 개가 생기는 빌드 규칙, 키워드 표와 state_map, "near '...' at line N" 오류가 만들어지는 곳을 보고, Bison 추적과 gdb로 파서가 남긴 나무를 직접 찍어 봅니다.
-
MariaDB 소스 파헤치기 7: 준비 단계 — 권한 확인, 테이블 열기, 이름 찾기
파서가 만든 LEX를 받은 서버가 실행 계획을 세우기 전에 하는 세 가지 일을 소스로 따라갑니다. mysql_execute_command()의 큰 switch에서 check_table_access()로 권한을 보고, open_and_lock_tables()로 메타데이터 잠금을 얻고 TABLE_SHARE와 TABLE을 캐시에서 꺼내고, JOIN::prepare()에서 열 이름을 Field에 잇습니다. 열 권한 오류 1142·1143, Opened_tables와 Table_open_cache_hits의 변화, ALTER TABLE이 열린 트랜잭션 뒤에서 기다리고 그 뒤 SELECT까지 줄을 서는 모습, 1054·1052 오류가 나는 호출 스택을 직접 확인합니다.
-
MariaDB 소스 파헤치기 8: 옵티마이저 — JOIN::optimize와 실행 계획 고르기
EXPLAIN 한 줄이 만들어지기까지 MariaDB 옵티마이저가 하는 일을 소스로 따라갑니다. JOIN::optimize()의 단계(조건 다듬기, 행 수 추정, 범위 분석, 조인 순서 탐색), 1 = 1밀리초로 정한 새 비용 모델, 히스토그램이 계획을 뒤집는 과정, EXPLAIN과 optimizer_trace가 만들어지는 곳을 예제와 gdb로 확인합니다.
-
MariaDB 소스 파헤치기 9: 실행과 handler API — 중첩 루프 조인이 엔진을 부르는 법
옵티마이저가 고른 계획이 실제로 행을 읽어 내는 곳을 소스로 따라갑니다. JOIN::exec()에서 do_select()와 sub_select()·evaluate_join_record()의 중첩 루프로, EXPLAIN의 type마다 정해지는 읽기 함수로, 조인 버퍼로, handler의 ha_ 감싸개를 지나 ha_innobase::rnd_next()와 write_row()까지 내려갑니다. Handler_read_* 상태 변수로 호출 수를 세고, gdb 백트레이스 한 장으로 do_command부터 엔진까지를 확인하고, 엔진을 MEMORY·Aria·BLACKHOLE로 바꿔도 같은 자리를 지나는 것을 봅니다.
-
MariaDB 소스 파헤치기 10: InnoDB 1 — 페이지, 버퍼 풀, B-트리
handler 아래로 내려가 InnoDB가 데이터를 담는 세 가지 그릇을 소스로 읽습니다. 16KB 페이지의 FIL 헤더·페이지 헤더·레코드·페이지 디렉터리, 페이지를 메모리에 붙잡아 두는 버퍼 풀(buf_page_get_gen, LRU의 old 구역, 더티 페이지와 page cleaner), 테이블 그 자체인 클러스터드 인덱스 B-트리(search_leaf, 페이지 분할), 그리고 페이지 잠금과 redo를 묶는 미니 트랜잭션 mtr_t입니다. .ibd 파일을 od로 열어 페이지 머리를 읽고, information_schema로 버퍼 풀 안을 보고, 행을 늘려 B-트리 높이와 분할을 세고, gdb로 SELECT·INSERT가 B-트리에 닿는 길을 확인합니다.
-
MariaDB 소스 파헤치기 11: InnoDB 2 — 트랜잭션, MVCC, undo, 잠금
COMMIT 한 줄이 서버 계층의 ha_commit_trans()에서 InnoDB의 trx_t::commit()까지 가는 길, REPEATABLE READ가 옛 값을 보여 주는 ReadView와 undo 사슬, 아무도 안 보는 옛 판을 치우는 purge, 그리고 행 잠금·갭 잠금·잠금 대기·교착 탐지를 기준 커밋의 소스로 따라갑니다. 두 세션 예제로 스냅샷, 잠금 대기, 교착, history list length를 직접 확인합니다.
-
MariaDB 소스 파헤치기 12: 로그 두 개 — redo 로그와 binlog, 크래시 복구, 그리고 연재를 마치며
COMMIT이 돌아왔을 때 무엇이 디스크에 있다는 뜻인지, InnoDB의 redo 로그(log_sys, LSN, mtr_t::commit, log_write_up_to)와 innodb_flush_log_at_trx_commit이 갈리는 자리, 체크포인트와 ib_logfile0의 배치, kill -9 뒤 redo로 앞으로 가고 undo로 되돌아오는 크래시 복구, 서버 계층의 binlog와 이벤트, 두 로그를 XID로 맞추는 2단계 커밋과 그룹 커밋을 소스로 따라갑니다. DBUG 크래시 지점으로 2단계 커밋의 두 틈에서 서버를 죽여 복구가 무엇을 하는지 직접 확인하고, 연재 열두 편을 정리합니다.