TiDB
MySQL Compatible Distributed NewSQL Database
MySQL 호환 분산 NewSQL 데이터베이스입니다. HTAP(Hybrid Transactional/Analytical Processing)을 지원하여 하나의 데이터베이스에서 OLTP와 OLAP 워크로드를 동시에 처리합니다.
MySQL Compatible Distributed NewSQL Database
MySQL 호환 분산 NewSQL 데이터베이스입니다. HTAP(Hybrid Transactional/Analytical Processing)을 지원하여 하나의 데이터베이스에서 OLTP와 OLAP 워크로드를 동시에 처리합니다.
TiDB는 PingCAP에서 개발한 오픈소스 분산 SQL 데이터베이스입니다. Google의 Spanner와 F1 논문에서 영감을 받아 설계되었으며, MySQL 프로토콜을 완벽히 지원하여 기존 MySQL 애플리케이션을 그대로 마이그레이션할 수 있습니다.
HTAP (Hybrid Transactional/Analytical Processing): TiDB의 핵심 차별점입니다. TiKV(행 저장소)로 OLTP 처리, TiFlash(컬럼 저장소)로 OLAP 처리를 동시에 수행합니다. 실시간 분석이 필요한 서비스에서 별도의 데이터 웨어하우스 없이 즉시 분석 쿼리를 실행할 수 있습니다.
수평 확장(Horizontal Scaling): 노드를 추가하면 자동으로 데이터가 분산되고 처리량이 증가합니다. 수 TB에서 수백 TB까지 확장 가능하며, 쓰기/읽기 모두 선형적으로 확장됩니다.
강력한 일관성: Raft 합의 알고리즘을 사용하여 분산 환경에서도 강력한 일관성을 보장합니다. 기본적으로 Snapshot Isolation을 제공하며, Pessimistic/Optimistic 트랜잭션 모드를 선택할 수 있습니다.
클라우드 네이티브: Kubernetes 위에서 TiDB Operator를 통해 자동화된 배포, 스케일링, 백업/복구가 가능합니다. TiDB Cloud를 통해 완전 관리형 서비스도 제공됩니다.
-- TiDB SQL 예제 (MySQL 호환)
-- ============================================
-- 기본 테이블 생성 (MySQL과 동일)
-- ============================================
CREATE DATABASE ecommerce;
USE ecommerce;
-- 사용자 테이블
CREATE TABLE users (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
email VARCHAR(255) UNIQUE NOT NULL,
name VARCHAR(100) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
-- 샤딩 힌트 (선택적)
INDEX idx_email (email)
) ENGINE=InnoDB;
-- 주문 테이블 (파티셔닝 예시)
CREATE TABLE orders (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
user_id BIGINT NOT NULL,
total_amount DECIMAL(15,2) NOT NULL,
status ENUM('pending', 'paid', 'shipped', 'delivered') DEFAULT 'pending',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_user_id (user_id),
INDEX idx_created_at (created_at)
) ENGINE=InnoDB
-- TiDB에서 Range 파티셔닝 (대용량 테이블 최적화)
PARTITION BY RANGE (YEAR(created_at)) (
PARTITION p2022 VALUES LESS THAN (2023),
PARTITION p2023 VALUES LESS THAN (2024),
PARTITION p2024 VALUES LESS THAN (2025),
PARTITION pmax VALUES LESS THAN MAXVALUE
);
-- ============================================
-- HTAP: TiFlash 컬럼 저장소 설정
-- ============================================
-- TiFlash 레플리카 추가 (실시간 분석용)
ALTER TABLE orders SET TIFLASH REPLICA 1;
ALTER TABLE users SET TIFLASH REPLICA 1;
-- TiFlash 동기화 상태 확인
SELECT * FROM information_schema.tiflash_replica;
-- ============================================
-- HTAP 쿼리 예시
-- ============================================
-- OLTP: 단순 조회 (TiKV 자동 사용)
SELECT * FROM orders WHERE user_id = 12345 LIMIT 10;
-- OLAP: 분석 쿼리 (TiFlash 자동 사용)
SELECT
DATE_FORMAT(created_at, '%Y-%m') AS month,
COUNT(*) AS order_count,
SUM(total_amount) AS total_sales,
AVG(total_amount) AS avg_order_value
FROM orders
WHERE created_at >= '2024-01-01'
GROUP BY month
ORDER BY month;
-- 강제로 TiFlash 사용 (힌트)
SELECT /*+ READ_FROM_STORAGE(TIFLASH[orders]) */
status, COUNT(*) AS cnt
FROM orders
GROUP BY status;
-- 강제로 TiKV 사용 (힌트)
SELECT /*+ READ_FROM_STORAGE(TIKV[orders]) */
* FROM orders WHERE id = 1;
-- ============================================
-- 분산 트랜잭션
-- ============================================
-- Pessimistic 트랜잭션 (기본값, MySQL과 동일)
START TRANSACTION;
UPDATE accounts SET balance = balance - 100
WHERE id = 'acc-001';
UPDATE accounts SET balance = balance + 100
WHERE id = 'acc-002';
-- 제약조건 확인
SELECT balance FROM accounts WHERE id = 'acc-001';
COMMIT;
-- ============================================
-- 유용한 시스템 쿼리
-- ============================================
-- 클러스터 상태 확인
SELECT * FROM information_schema.cluster_info;
-- 느린 쿼리 확인
SELECT * FROM information_schema.slow_query
ORDER BY query_time DESC LIMIT 10;
-- 리전 분포 확인
SELECT * FROM information_schema.tikv_region_status
WHERE table_name = 'orders';
-- 실행 계획 (분산 처리 확인)
EXPLAIN ANALYZE
SELECT * FROM orders WHERE user_id = 12345;
# TiDB + Python (mysql-connector 또는 pymysql)
import mysql.connector
from mysql.connector import pooling
from decimal import Decimal
from contextlib import contextmanager
# ============================================
# 연결 설정
# ============================================
# TiDB 연결 풀 (MySQL 드라이버 그대로 사용)
db_config = {
'host': 'tidb-host.example.com',
'port': 4000, # TiDB 기본 포트
'user': 'root',
'password': 'your_password',
'database': 'ecommerce',
'pool_name': 'tidb_pool',
'pool_size': 10,
'autocommit': False,
}
connection_pool = mysql.connector.pooling.MySQLConnectionPool(**db_config)
@contextmanager
def get_connection():
conn = connection_pool.get_connection()
try:
yield conn
finally:
conn.close()
# ============================================
# CRUD 작업
# ============================================
class OrderService:
def create_order(self, user_id: int, items: list) -> dict:
"""주문 생성 - 분산 트랜잭션"""
with get_connection() as conn:
cursor = conn.cursor(dictionary=True)
try:
# TiDB는 기본적으로 Pessimistic 트랜잭션
total = sum(item['price'] * item['quantity'] for item in items)
# 주문 생성
cursor.execute("""
INSERT INTO orders (user_id, total_amount, status)
VALUES (%s, %s, 'pending')
""", (user_id, total))
order_id = cursor.lastrowid
# 주문 아이템 생성
for item in items:
cursor.execute("""
INSERT INTO order_items (order_id, product_id, quantity, price)
VALUES (%s, %s, %s, %s)
""", (order_id, item['product_id'], item['quantity'], item['price']))
# 재고 차감
cursor.execute("""
UPDATE products
SET stock = stock - %s
WHERE id = %s AND stock >= %s
""", (item['quantity'], item['product_id'], item['quantity']))
if cursor.rowcount == 0:
raise ValueError(f"재고 부족: {item['product_id']}")
conn.commit()
return {'order_id': order_id, 'total': total}
except Exception as e:
conn.rollback()
raise e
def get_sales_analytics(self, start_date: str, end_date: str) -> list:
"""매출 분석 - TiFlash OLAP 쿼리"""
with get_connection() as conn:
cursor = conn.cursor(dictionary=True)
# TiFlash 힌트로 컬럼 저장소 강제 사용
cursor.execute("""
SELECT /*+ READ_FROM_STORAGE(TIFLASH[orders, order_items]) */
DATE_FORMAT(o.created_at, '%%Y-%%m-%%d') AS date,
COUNT(DISTINCT o.id) AS order_count,
SUM(o.total_amount) AS total_sales,
COUNT(oi.id) AS item_count
FROM orders o
JOIN order_items oi ON o.id = oi.order_id
WHERE o.created_at BETWEEN %s AND %s
GROUP BY date
ORDER BY date
""", (start_date, end_date))
return cursor.fetchall()
# ============================================
# 재시도 로직 (분산 트랜잭션 충돌 대비)
# ============================================
import time
import random
def execute_with_retry(fn, max_retries=3):
"""트랜잭션 충돌 시 재시도"""
for attempt in range(max_retries):
try:
return fn()
except mysql.connector.Error as e:
# TiDB 트랜잭션 충돌 에러 코드
if e.errno in (9007, 8028) and attempt < max_retries - 1:
# 지수 백오프 + 지터
wait_time = (2 ** attempt) + random.uniform(0, 1)
print(f"재시도 {attempt + 1}/{max_retries}: {wait_time:.2f}초 대기")
time.sleep(wait_time)
continue
raise
# ============================================
# 사용 예시
# ============================================
order_service = OrderService()
# OLTP: 주문 생성
result = execute_with_retry(
lambda: order_service.create_order(
user_id=12345,
items=[
{'product_id': 1, 'quantity': 2, 'price': Decimal('10000')},
{'product_id': 2, 'quantity': 1, 'price': Decimal('25000')}
]
)
)
print(f"주문 생성: {result}")
# OLAP: 실시간 분석 (TiFlash)
analytics = order_service.get_sales_analytics('2024-01-01', '2024-12-31')
print(f"매출 분석: {analytics}")
# TiDB CLI 및 운영 명령어
# ============================================
# TiUP으로 로컬 설치 (개발/테스트)
# ============================================
# TiUP 설치 (TiDB 패키지 매니저)
curl --proto '=https' --tlsv1.2 -sSf https://tiup-mirrors.pingcap.com/install.sh | sh
# 환경변수 적용
source ~/.bashrc
# 로컬 클러스터 실행 (TiDB + TiKV + PD + TiFlash)
tiup playground --db 1 --kv 3 --pd 1 --tiflash 1
# MySQL 클라이언트로 접속
mysql -h 127.0.0.1 -P 4000 -u root
# ============================================
# 프로덕션 클러스터 배포
# ============================================
# 클러스터 배포 설정 파일 (topology.yaml)
cat > topology.yaml << 'EOF'
global:
user: "tidb"
ssh_port: 22
deploy_dir: "/tidb-deploy"
data_dir: "/tidb-data"
server_configs:
tidb:
log.slow-threshold: 300
pd_servers:
- host: 10.0.1.1
- host: 10.0.1.2
- host: 10.0.1.3
tidb_servers:
- host: 10.0.1.4
- host: 10.0.1.5
tikv_servers:
- host: 10.0.1.6
- host: 10.0.1.7
- host: 10.0.1.8
tiflash_servers:
- host: 10.0.1.9
EOF
# 클러스터 배포
tiup cluster deploy tidb-prod v7.5.0 ./topology.yaml --user root -p
# 클러스터 시작
tiup cluster start tidb-prod
# 클러스터 상태 확인
tiup cluster display tidb-prod
# ============================================
# 클러스터 관리
# ============================================
# 노드 스케일 아웃 (TiKV 추가)
tiup cluster scale-out tidb-prod scale-out.yaml
# 노드 스케일 인 (TiKV 제거)
tiup cluster scale-in tidb-prod --node 10.0.1.8:20160
# 설정 변경
tiup cluster edit-config tidb-prod
# 롤링 업그레이드
tiup cluster upgrade tidb-prod v7.6.0
# ============================================
# 백업 및 복구 (BR 도구)
# ============================================
# 전체 백업 (S3)
tiup br backup full \
--pd "10.0.1.1:2379" \
--storage "s3://bucket/backup" \
--s3.region "ap-northeast-2"
# 데이터베이스 백업
tiup br backup db \
--pd "10.0.1.1:2379" \
--db "ecommerce" \
--storage "s3://bucket/backup"
# 복구
tiup br restore full \
--pd "10.0.1.1:2379" \
--storage "s3://bucket/backup"
# ============================================
# 데이터 마이그레이션 (MySQL -> TiDB)
# ============================================
# TiDB Data Migration (DM) 설정
tiup dmctl --master-addr 10.0.1.1:8261 \
operate-source create ./source.yaml
# 마이그레이션 태스크 시작
tiup dmctl --master-addr 10.0.1.1:8261 \
start-task ./task.yaml
# ============================================
# 모니터링 (Grafana/Prometheus)
# ============================================
# TiDB Dashboard 접속 (기본 포트)
# http://PD_IP:2379/dashboard
# Grafana 접속 (TiUP으로 설치 시)
# http://GRAFANA_IP:3000
# 느린 쿼리 로그 확인
tiup ctl:v7.5.0 pd -u http://10.0.1.1:2379 log slow-query
"실시간 대시보드 때문에 MySQL에서 분석 쿼리 돌리면 서비스 영향 있잖아요. TiDB로 가면 TiFlash가 분석 쿼리 처리해서 운영 DB 부하 없이 실시간 분석 가능해요. ETL 파이프라인 없이요."
"TiDB는 MySQL 프로토콜 완벽 호환이라 드라이버 변경 없이 연결 문자열만 바꾸면 돼요. DM 도구로 MySQL 실시간 동기화하면서 점진적으로 옮길 수 있고요. 다만 일부 MySQL 전용 함수는 체크해봐야 해요."
"이 분석 쿼리가 TiKV로 가서 느린 것 같아요. TiFlash 레플리카 설정했는지 확인하고, 힌트로 강제 지정해보세요. information_schema.tiflash_replica에서 동기화 상태도 체크해보시고요."
AUTO_INCREMENT는 순차적이라 핫스팟 발생 가능. AUTO_RANDOM 또는 SHARD_ROW_ID_BITS 사용을 권장합니다.
TiFlash는 비동기 복제라 최신 데이터가 지연될 수 있습니다. 실시간성이 중요하면 TiKV 힌트를 사용하세요.
저장 프로시저, 트리거, 일부 함수는 제한적입니다. 마이그레이션 전 호환성 체크 도구로 검증하세요.
대용량 테이블에 TiFlash 레플리카, AUTO_RANDOM으로 핫스팟 방지, 정기적 ANALYZE, PD 3노드 이상 구성.