2014年9月26日金曜日

MySQL 5.7.5のInnoDB undo log truncationを試してみた

MySQL 5.7.5では、*UNDOログ領域が共有テーブルスペース上になければ* 使っていない領域をシュリンクさせることが出来るようになったらしい。

まずはUNDOログ領域を共有テーブルスペース上から追い出す設定。これは5.6で既に使える。共有テーブルスペースを作る *前に* やっておかないといけないので注意。


$ vim my.cnf
..
innodb-undo-tablespaces= 2
..

とりあえずinnodb-undo-tablespacesを2以上にすればOK。暗黙のデフォルトは0(=共有テーブルスペース上にUNDOテーブルスペースを作る)
1だとUNDOログ領域はibdata1上には作られなくなるものの、今回追加されたシュリンクの機能は使えない。
これで起動すると


# cd /usr/local/mysql
[root@v157-7-154-209 mysql]# ll data
total 652604
-rw-rw---- 1 mysql mysql        56 Sep 22 16:43 auto.cnf
-rw-rw---- 1 mysql mysql     87754 Sep 22 16:43 bin.000001
-rw-rw---- 1 mysql mysql   1230997 Sep 22 16:43 bin.000002
-rw-rw---- 1 mysql mysql  83893472 Sep 22 16:45 bin.000003
-rw-rw---- 1 mysql mysql        39 Sep 22 16:43 bin.index
-rw-rw---- 1 mysql mysql      3260 Sep 22 16:43 error.log
-rw-rw---- 1 mysql mysql  12582912 Sep 22 16:44 ibdata1
-rw-rw---- 1 mysql mysql 268435456 Sep 22 16:45 ib_logfile0
-rw-rw---- 1 mysql mysql 268435456 Sep 22 16:43 ib_logfile1
-rw-rw---- 1 mysql mysql  12582912 Sep 22 16:43 ibtmp1
drwx------ 2 mysql mysql      4096 Sep 22 16:44 mysql
-rw-rw---- 1 root  root          5 Sep 22 16:43 mysqld_safe.pid
-rw-r--r-- 1 root  root          9 Sep 22 16:44 mysql_upgrade_info
drwx------ 2 mysql mysql      4096 Sep 22 16:44 performance_schema
-rw-rw---- 1 mysql mysql       682 Sep 22 16:44 slow.log
drwx------ 2 mysql mysql      4096 Sep 22 16:44 tpcc
-rw-rw---- 1 mysql mysql  10485760 Sep 22 16:44 undo001
-rw-rw---- 1 mysql mysql  10485760 Sep 22 16:44 undo002
-rw-rw---- 1 mysql mysql         5 Sep 22 16:43 hostname.pid

こんなかんじ。$datadir/undo{連番} がUNDOログ領域。何番まで作られるかはinnodb-indo-tablespacesで決まる。
これを肥大化させるようにしばらくトラフィックをかけて


# ll data/undo00*
-rw-rw---- 1 mysql mysql 239075328 Sep 22 17:39 data/undo001
-rw-rw---- 1 mysql mysql 230686720 Sep 22 17:39 data/undo002

これを


mysql> SELECT @@innodb_max_undo_log_size;
+----------------------------+
| @@innodb_max_undo_log_size |
+----------------------------+
|                 1073741824 |
+----------------------------+
1 row in set (0.02 sec)

mysql> SET GLOBAL innodb_max_undo_log_size= 10 * 1024 * 1024;
Query OK, 0 rows affected (0.02 sec)

mysql> SET GLOBAL innodb_undo_log_truncate= 1;
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW GLOBAL VARIABLES LIKE '%undo%';
+--------------------------+----------+
| Variable_name            | Value    |
+--------------------------+----------+
| innodb_max_undo_log_size | 10485760 |
| innodb_undo_directory    | .        |
| innodb_undo_log_truncate | ON       |
| innodb_undo_logs         | 128      |
| innodb_undo_tablespaces  | 2        |
+--------------------------+----------+
5 rows in set (0.00 sec)

こうじゃ!


# ll data/undo00*
-rw-rw---- 1 mysql mysql 239075328 Sep 22 17:40 data/undo001
-rw-rw---- 1 mysql mysql 230686720 Sep 22 17:40 data/undo002

( ゚д゚) ・・・

(つд⊂)ゴシゴシ


# ll data/undo00*
-rw-rw---- 1 mysql mysql 239075328 Sep 22 17:40 data/undo001
-rw-rw---- 1 mysql mysql 230686720 Sep 22 17:40 data/undo002

(;゚д゚) ・・・

(つд⊂)ゴシゴシゴシ


# ll data/undo00*
-rw-rw---- 1 mysql mysql 239075328 Sep 22 17:40 data/undo001
-rw-rw---- 1 mysql mysql 230686720 Sep 22 17:40 data/undo002
_, ._
(;゚ Д゚) …!?


減ってないじゃん。何がいけないんだろう。。
と思ったら、innodb_purge_rseg_truncate_frequencyというパラメーターがあるらしい。n回、undoログのパージが呼ばれるとtruncationが炸裂する、みたいな。


mysql> SELECT @@innodb_purge_rseg_truncate_frequency;
+----------------------------------------+
| @@innodb_purge_rseg_truncate_frequency |
+----------------------------------------+
|                                    128 |
+----------------------------------------+
1 row in set (0.00 sec)

-- tpcc_start

# ll data/undo00*
-rw-rw---- 1 mysql mysql  10485760 Sep 22 17:47 data/undo001
-rw-rw---- 1 mysql mysql 230686720 Sep 22 17:47 data/undo002

# ll data/undo00*
-rw-rw---- 1 mysql mysql 10485760 Sep 22 17:47 data/undo001
-rw-rw---- 1 mysql mysql 10485760 Sep 22 17:47 data/undo002

# ll data/undo00*
-rw-rw---- 1 mysql mysql 10485760 Sep 22 17:47 data/undo001
-rw-rw---- 1 mysql mysql 10485760 Sep 22 17:47 data/undo002


おお、トランザクションをかければパージが呼ばれるようになるので、シュリンクが発動する、みたいな。
innodb_buffer_pool_dump_nowみたいにSET GLOBALしたところからバックグラウンドに処理が始まるわけじゃなくて、常に有効で容量が監視されて超えたらtruncationになるわけか。。

てことはあんまり小さいサイズにすると死ねると。

ともあれちょっと感動した。

0 件のコメント :

コメントを投稿