[데이터베이스] MySQL Space Amplification 측정해보기

kothe·2022년 11월 6일
0

데이터베이스

목록 보기
7/8
post-thumbnail

Space amplification

  • Disk에 있는 데이터크기와 실제 DB 사이즈의 비율
    만약 DB에 10MB를 넣었는데 100MB의 디스크 공간을 사용했다면 이때 space amplification은 10이다.

1. Load & Run TPC-C data

  • 먼저 tpcc data를 load하기 위해서 tpcc-mysql폴더에 있는 load.sh파일을 수정해준다. (LD_LIBRARY_PATH와 password를 바꿔주면 됨.)
$ cd tpcc-mysql
$ vi load.sh

export LD_LIBRARY_PATH=/home/koh/mysql-5.7.33/lib
DBNAME=$1
WH=$2
HOST=127.0.0.1
STEP=100

./tpcc_load -h $HOST -d $DBNAME -u root -p "yourPassword" -P3306 -w $WH -l 1 -m 1 -n $WH >> 1.out &
x=1

while [ $x -le $WH ]
do
 echo $x $(( $x + $STEP - 1 ))
./tpcc_load -h $HOST -d $DBNAME -u root -p "yourPassword" -P3306 -w $WH -l 2 -m $x -n $(( $x + $STEP - 1 ))  >> 2_$x.out &
./tpcc_load -h $HOST -d $DBNAME -u root -p "yourPassword" -P3306 -w $WH -l 3 -m $x -n $(( $x + $STEP - 1 ))  >> 3_$x.out &
./tpcc_load -h $HOST -d $DBNAME -u root -p "yourPassword" -P3306 -w $WH -l 4 -m $x -n $(( $x + $STEP - 1 ))  >> 4_$x.out &
 x=$(( $x + $STEP ))
done

for pid in `jobs -p`
do
	echo wait for $pid
	wait $pid
done

$ sudo chmod 777 load.sh
  • tpcc데이터를 load
$ ./load.sh tpcc 20
  • TPC-C benchmark 돌리기
./tpcc_start -h 127.0.0.1 -S /tmp/mysql.sock -d tpcc -u root -p "yourPassword" -w 20 -c 8 -r 10 -l 1200

benchmark 파라미터 값의 의미는 다음과 같다.
Host: 127.0.0.1
MySQL Socket: /tmp/mysql.sock
DB: tpcc
User: root
Password: yourPassword
Warehouse: 20
Connection: 8
Rampup time: 10 (sec)
Measure: 1200 (sec)

2. Calculate User Data size in B+tree nodes
tpcc benchmark가 끝난 후에, 다음 command를 쳐준다.

$ innodb_space -f /path/to/test_data/tpcc/history.ibd space-index-pages-summary | tee innodb_space.txt

innodb_space : InnoDB의 extent, 파일 segment 및 free space 관리 구조 확인 (innodb_ruby 설치해야함)
/path/to/test_data/tpcc/history.ibd : test_data 디렉토리에 저장되어있는 history.idb table (tpcc benchmark 후 생김)
space-index-pages-summary : 이 모드를 사용하면 모든 index 페이지의 공간 사용관련 데이터를 볼 수 있음.
tee innodb_space.txt : txt파일로 저장

  • innodb_space.txt
    ...

총 11773개의 page에 대한 데이터를 볼 수 있다.


여기서 space amplification = tpcc DB size / user data size로 구할 수 있다.

tpcc DB size : innoDB의 page는 16KB로 설정되어있으므로 16 * 11773 = 188,368KB
user data size : txt 파일에서 아래 awk명령어로 data 총 합을 구해준다. 143,128,979 ≅ 143,129KB

단순 계산으로 45,239KB가 낭비되고있고,
Space amplification 은 188,368 / 143,129 ≅ 1.316이다.

++ space amplification이 발생하는 이유는?

InnoDB는 B+ tree기반 자료 구조를 사용해 인덱스 페이지를 관리한다.
Leaf 노드페이지에 많은 업데이트가 발생하게 되면 분할 현상이 발생하여 space amplification이 발생한다. 분할 현상이 많이 발생하면 page 수가 늘어나기 때문에 해당 페이지를 모두 사용하지 않아 공간을 낭비할 확률이 높아진다.

그렇다면 분할 현상이 왜 발생할까?
OLTP 벤치마크인 TPC-C는 order-deliverystock-exchange 같은 트랜잭션을 logging하는데 별도의 테이블(History, Orders, Order-Line 등등)을 사용한다.
이 중 Order-Line 테이블은 전체 DB 용량 중 많은 비중을 차지하기 때문에 OLTP성능에 많은 영향을 미친다.

Order-Line 테이블의 리프노드 분할은 주로 new-order, delivery 트랜잭션에 의해 발생한다.
new-order transaction은 Order-Line 테이블에 61바이트 튜플을 삽입하고,
delivery transaction은 Order-Line 테이블의 datatime 튜플을 업데이트한다.

TPC-C 벤치마크 수행 시, new-order transaction으로는 튜플이 순차적으로 삽입되기 때문에 분할이 발생하지 않는다. 하지만 delivery 트랜잭션 수행 시엔 페이지마다 미리 부여된 여유공간(default로 6.25%가 부여돼있다.)이 부족해 페이지 분할이 발생한다.

이렇게 분할 된 페이지 중 왼쪽 리프 페이지는 더이상 업데이트가 발생하지 않아 frozen 페이지가 되고, 약 50%만 차 있는 상태로 space amplification이 발생하는 것이다.

그렇기 때문에 B+tree의 리프노드에 여유공간을 미리 추가적으로 할당해, 트랜잭션 수행 시 불필요한 분할 발생은 없애는 것이 좋은 해결책이 될 수 있다.

Reference

profile
천천히 꾸준히

0개의 댓글