GA

2014/05/20

MySQL 5.6.4で実装されたinnodb-sort-buffer-sizeの値

InnoDBのオンラインALTER TABLEの時に使われるパラメーター。
セッション変数のsort_buffer_sizeのように使われて、これをあふれたぶんだけsort_merge_passes相当の処理が走るので重くなる。

http://dev.mysql.com/doc/refman/5.6/en/innodb-parameters.html#sysvar_innodb_sort_buffer_size

最大値が6.7GBに見えたけど全くの空目で、最大値は64Mと小さめ。暗黙のデフォルトは1M。

実際どれくらい違うのか。ざっくりテスト。


$ perl -e 'use Digest::MD5 qw/md5_hex/; open($fh, ">/data/tmp/md5.tsv"); for ($n= 1; $n<= 10000000; $n++) {printf($fh "%d\t%s\n", $n, md5_hex($n));}'

$ cat /data/tmp/md5.sql
SELECT @@innodb_sort_buffer_size;

use d1

DROP TABLE IF EXISTS t1;

CREATE TABLE t1 (num int unsigned, val varchar(32), upd datetime default current_timestamp);

LOAD DATA INFILE '/data/tmp/md5.tsv' INTO TABLE t1(num, val);

ALTER TABLE t1 ADD KEY (val, upd), ADD KEY (upd);

DROP TABLE t1;


mysql> source /data/tmp/md5.sql
+---------------------------+
| @@innodb_sort_buffer_size |
+---------------------------+
|                   1048576 |
+---------------------------+
1 row in set (0.00 sec)

Database changed
Query OK, 0 rows affected (0.03 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 10000000 rows affected (1 min 3.48 sec)
Records: 10000000  Deleted: 0  Skipped: 0  Warnings: 0

Query OK, 0 rows affected (2 min 8.53 sec)
Records: 0  Duplicates: 0  Warnings: 0

Query OK, 0 rows affected (0.70 sec)


mysql> source /data/tmp/md5.sql
+---------------------------+
| @@innodb_sort_buffer_size |
+---------------------------+
|                  16777216 |
+---------------------------+
1 row in set (0.00 sec)

Database changed
Query OK, 0 rows affected, 1 warning (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 10000000 rows affected (59.01 sec)
Records: 10000000  Deleted: 0  Skipped: 0  Warnings: 0

Query OK, 0 rows affected (2 min 8.33 sec)
Records: 0  Duplicates: 0  Warnings: 0

Query OK, 0 rows affected (0.62 sec)


mysql> source /data/tmp/md5.sql
+---------------------------+
| @@innodb_sort_buffer_size |
+---------------------------+
|                  67108864 |
+---------------------------+
1 row in set (0.00 sec)

Database changed
Query OK, 0 rows affected, 1 warning (0.00 sec)

Query OK, 0 rows affected (0.01 sec)

Query OK, 10000000 rows affected (1 min 0.29 sec)
Records: 10000000  Deleted: 0  Skipped: 0  Warnings: 0

Query OK, 0 rows affected (1 min 48.68 sec)
Records: 0  Duplicates: 0  Warnings: 0

Query OK, 0 rows affected (0.71 sec)

オンラインALTER TABLE用のパラメーターなので、ALTER TABLE .., ALGORITHM= COPYの場合はもちろん効かなかった。これを約10秒/GBの減少とみるか(ロード後で.ibdファイルは1.7GBくらい)、15%の減少とみるか。

グローバルで64Mなら、最初から最大値にしておいてもいいかな。


【2014/07/03 12:15】
実際には1つのADD KEYに対してinnodb-sort-buffer-sizeの4倍のメモリーを使うので注意。。

日々の覚書: MySQL 5.6のオンラインALTER TABLEとinnodb-sort-buffer-sizeに関する考察 

2014/05/19

Percona XtraBackupの圧縮メモ

innobackupexのオプションごとにどれくらいかメモ。
主にファイルサイズと処理時間を比べたいだけなので、MySQLは起動しておれどトラフィックはなし。tpcc-mysqlのWH= 100をロードしただけ。


$ du -sh /data/mysql
14G     /data/mysql

データファイル意外と小さかった。。RESET MASTERしたのでバイナリーログは当然含まず。


tarボールストリーム圧縮なし

$ time innobackupex /data/mysql --stream=tar | ssh mysql@backup-server "cat - > /data/tmp/xtrabackup.tar"
..
real    4m53.213s
user    4m13.456s
sys     0m37.721s

$ ls -lh xtrabackup*
-rw-rw-r--  1 mysql mysql 8.5G May 19 16:35 xtrabackup.tar

$ mkdir xtrabackup

$ time tar ixf xtrabackup.tar -C xtrabackup

real    0m16.243s
user    0m0.163s
sys     0m16.073s

$ time innobackupex --apply-log xtrabackup
..
real    0m45.953s
user    0m0.297s
sys     0m5.908s


tarボールgzip圧縮

$ time innobackupex /data/mysql --stream=tar | gzip -c | ssh mysql@backup-server "cat - > /data/tmp/xtrabackup.tar.gz"
..
real    13m2.701s
user    15m19.741s
sys     0m28.345s

$ ls -lh xtrabackup*
-rw-rw-r-- 1 mysql mysql 4.8G May 19 16:58 xtrabackup.tar.gz

$ mkdir xtrabackup

$ time tar ixf xtrabackup.tar.gz -C xtrabackup

real    1m37.648s
user    1m31.823s
sys     0m21.962s

$ time innobackupex --apply-log xtrabackup
..
real    0m44.944s
user    0m0.277s
sys     0m6.055s


tarボールpbzip2圧縮(8並列)

$ time innobackupex /data/mysql --stream=tar | pbzip2 -p8 -c | ssh backup-server "cat - > /data/tmp/xtrabackup.tar.bz2"
..
real    3m11.137s
user    27m21.804s
sys     0m30.629s

$ ls -lh xtrabackup*
-rw-rw-r-- 1 mysql mysql 4.3G May 19 17:09 xtrabackup.tar.bz2

$ mkdir xtrabackup

$ time pbzip2 -p8 -dc xtrabackup.tar.bz2 | tar ix -C xtrabackup
tar: Read 2560 bytes from -

real    1m24.567s
user    11m18.711s
sys     0m30.188s

$ time innobackupex --apply-log xtrabackup
..
real    0m43.918s
user    0m0.291s
sys     0m6.073s


xbstream圧縮なし(1並列)

$ time innobackupex /data/mysql --stream=xbstream | ssh backup-server "cat - > /data/tmp/xtrabackup.xb"
..
real    5m17.412s
user    4m36.084s
sys     0m38.236s

$ ll -h xtrabackup.*
-rw-rw-r-- 1 mysql mysql 8.5G May 19 17:54 xtrabackup.xb

$ mkdir xtrabackup

$ time xbstream -x -C xtrabackup < xtrabackup.xb

real    1m32.016s
user    0m18.126s
sys     0m27.725s

$ time innobackupex --apply-log xtrabackup
..
real    0m47.103s
user    0m0.297s
sys     0m6.376s
xbstream圧縮あり(1並列)
$ time innobackupex /data/mysql --stream=xbstream --compress | ssh backup-server "cat - > /data/tmp/xtrabackup.xb"
..
real    5m44.481s
user    4m59.169s
sys     0m29.153s

$ ll -h xtrabackup.*
-rw-rw-r-- 1 mysql mysql 6.7G May 19 18:13 xtrabackup.xb

$ mkdir xtrabackup

$ time xbstream -x -C xtrabackup < xtrabackup.xb

real    1m11.434s
user    0m14.041s
sys     0m21.624s

$ time innobackupex --decompress xtrabackup/
..
real    1m54.178s
user    1m31.540s
sys     0m24.585s

$ time innobackupex --apply-log xtrabackup
..
real    0m45.782s
user    0m0.263s
sys     0m5.995s
xbstream圧縮あり(8並列)
$ time innobackupex /data/mysql --stream=xbstream --compress --compress-thread=8 --parallel=8 | ssh backup-server "cat - > /data/tmp/xtrabackup.xb"
..
real    3m40.315s
user    5m0.383s
sys     0m26.421s

$ ll -h xtrabackup.*

$ time xbstream -x -C xtrabackup < xtrabackup.xb
real    1m12.859s
user    0m13.734s
sys     0m20.157s

$ time innobackupex --decompress --parallel=8 xtrabackup/
..
real    2m16.178s
user    1m30.866s
sys     0m24.585s

$ time innobackupex --apply-log xtrabackup
..
real    0m45.722s
user    0m0.289s
sys     0m5.997s
decompress、多重化したらむしろ遅くなっててしょぼん。 tarボール無圧縮、--compact
$ time innobackupex /data/mysql --stream=tar --compact | ssh mysql@backup-server "cat - > /data/tmp/xtrabackup.tar"
..
real    4m50.256s
user    4m5.120s
sys     0m38.300s

$ ll -h xtrabackup.*
-rw-rw-r-- 1 mysql mysql 8.5G May 19 18:53 xtrabackup.tar

$ time tar ixf xtrabackup.tar -C xtrabackup

real    0m14.358s
user    0m0.209s
sys     0m13.879s

$ time innobackupex --apply-log xtrabackup
..
real    3m54.054s
user    0m24.002s
sys     0m41.084s
--stream=tarでは--parallelが効かないので、ごりごりやって良いなら--stream=xbstreamでいきたいところ。 容量面でcompactが全然効いた気配がないのに、--apply-logではちゃんとExpandingになって時間がかかってなんだかなぁ。 --rebuild-threads=8とかすれば多少速くなるのかも知れないけどそこまで試すアレなし。 ところでこの--compact(セカンダリーインデックスのそぎ落とし)が効かないのって、 tpcc_loadかましたあとにALTER TABLEでインデックスつけてるのがいけないような気がしてきた。
mysql> SHOW CREATE TABLE stock\G
*************************** 1. row ***************************
       Table: stock
Create Table: CREATE TABLE `stock` (
  `s_i_id` int(11) NOT NULL,
  `s_w_id` smallint(6) NOT NULL,
  `s_quantity` smallint(6) DEFAULT NULL,
  `s_dist_01` char(24) DEFAULT NULL,
  `s_dist_02` char(24) DEFAULT NULL,
  `s_dist_03` char(24) DEFAULT NULL,
  `s_dist_04` char(24) DEFAULT NULL,
  `s_dist_05` char(24) DEFAULT NULL,
  `s_dist_06` char(24) DEFAULT NULL,
  `s_dist_07` char(24) DEFAULT NULL,
  `s_dist_08` char(24) DEFAULT NULL,
  `s_dist_09` char(24) DEFAULT NULL,
  `s_dist_10` char(24) DEFAULT NULL,
  `s_ytd` decimal(8,0) DEFAULT NULL,
  `s_order_cnt` smallint(6) DEFAULT NULL,
  `s_remote_cnt` smallint(6) DEFAULT NULL,
  `s_data` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`s_w_id`,`s_i_id`),
  KEY `fkey_stock_2` (`s_i_id`),
  CONSTRAINT `fkey_stock_1` FOREIGN KEY (`s_w_id`) REFERENCES `warehouse` (`w_id`),
  CONSTRAINT `fkey_stock_2` FOREIGN KEY (`s_i_id`) REFERENCES `item` (`i_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

mysql> SHOW TABLE STATUS LIKE 'stock'\G
*************************** 1. row ***************************
           Name: stock
         Engine: InnoDB
        Version: 10
     Row_format: Compact
           Rows: 9793316
 Avg_row_length: 354
    Data_length: 3469737984
Max_data_length: 0
   Index_length: 0
      Data_free: 0
 Auto_increment: NULL
    Create_time: 2014-05-19 15:51:37
    Update_time: NULL
     Check_time: NULL
      Collation: utf8_general_ci
       Checksum: NULL
 Create_options:
        Comment:
1 row in set (0.00 sec)

$ mysql-5.7.4-m14-linux-glibc2.5-x86_64/bin/innochecksum -S /data/tmp/mysql/tpcc/stock.ibd
File::/data/tmp/mysql/tpcc/stock.ibd
================PAGE TYPE SUMMARY==============
#PAGE_COUNT     PAGE_TYPE
===============================================
  224349        Index page
       0        Undo log page
       1        Inode page
       0        Insert buffer free list page
    1158        Freshly allocated page
      14        Insert buffer bitmap
       0        System page
       0        Transaction system page
       1        File Space Header
      13        Extent descriptor page
       0        BLOB page
       0        Compressed BLOB page
       0        Other type of page
===============================================
Additional information:
Undo page type: 0 insert, 0 update, 0 other
Undo page state: 0 active, 0 cached, 0 to_free, 0 to_purge, 0 prepared, 0 other

なぜかindex_lengthに計上されない謎。このあたりなのかなぁ?
【2014/05/20 15:59】 計上されないのはたぶん関係ない ⇒ 日々の覚書: InnoDBオンラインALTER TABLEではIndex_lengthが更新されない

5.7.4のinnochecksumでも、セカンダリーインデックスなのかクラスターインデックス(=データページ)なのかは分けられないのかー。

取り敢えずマシンパワーがあるのあらxbstream+ pbzip2, ほそぼそやるならxbstream+ compressでいいかな。

MariaDB 10.0.5で実装されたROLEを試す

MariaDBで実装されるという噂だったROLE、まだだと思っていたらもうあったんですね。ということでさっくり試してみる。10.0.5から実装されたらしいけど、試したバージョンは10.0.11。

オリジナルのドキュメントはこちら。 https://mariadb.com/kb/en/roles-overview/

まずはROLEを作成してみる。mysqlスキーマに対してSELECTのみの権限を持つsys_selectロールを作成して、yoku0825ユーザーに割り当てる。

MariaDB [mysql]> CREATE ROLE sys_select;
Query OK, 0 rows affected (0.00 sec)

MariaDB [mysql]> GRANT SELECT ON mysql.* TO sys_select;
Query OK, 0 rows affected (0.00 sec)

MariaDB [mysql]> GRANT sys_select TO yoku0825;
Query OK, 0 rows affected (0.00 sec)

MariaDB [mysql]> GRANT USAGE ON *.* TO yoku0825;
Query OK, 0 rows affected (0.00 sec)

…あれ、GRANT .. ON .. TO ..って、これ、sys_select@%ユーザーが出来ちゃうんじゃね?;


MariaDB [mysql]> SELECT user, host, password FROM user ORDER BY 1, 2;
+------------+-----------------+----------+
| user       | host            | password |
+------------+-----------------+----------+
| root       | 127.0.0.1       |          |
| root       | ::1             |          |
| root       | ip-172-31-0-135 |          |
| root       | localhost       |          |
| sys_select |                 |          |
| yoku0825   | %               |          |
+------------+-----------------+----------+
6 rows in set (0.00 sec)

出来てるっぽいけど、hostが空欄だ。


# bin/mysql -usys_select
ERROR 1045 (28000): Access denied for user 'sys_select'@'localhost' (using password: NO)

ログインはできない。


MariaDB [mysql]> SELECT user, host, password, is_role FROM user ORDER BY 1, 2;
+------------+-----------------+----------+---------+
| user       | host            | password | is_role |
+------------+-----------------+----------+---------+
| root       | 127.0.0.1       |          | N       |
| root       | ::1             |          | N       |
| root       | ip-172-31-0-135 |          | N       |
| root       | localhost       |          | N       |
| sys_select |                 |          | Y       |
| yoku0825   | %               |          | N       |
+------------+-----------------+----------+---------+
6 rows in set (0.01 sec)

よく見てみると、mysql.userテーブルにis_roleというカラムが追加されてて、これで制御されてるっぽい。


MariaDB [mysql]> SELECT * FROM roles_mapping;
+-----------+----------+------------+--------------+
| Host      | User     | Role       | Admin_option |
+-----------+----------+------------+--------------+
| %         | yoku0825 | sys_select | N            |
| localhost | root     | sys_select | Y            |
+-----------+----------+------------+--------------+
2 rows in set (0.00 sec)

割り当てたロールはmysql.roles_mappingテーブルに格納されている。
じゃあ早速yoku0825ユーザーでログインしなおして、mysqlスキーマにアクセスを試す。


MariaDB [(none)]> SELECT current_user();
+----------------+
| current_user() |
+----------------+
| yoku0825@%     |
+----------------+
1 row in set (0.00 sec)

MariaDB [(none)]> SELECT user, host FROM mysql.user;
ERROR 1142 (42000): SELECT command denied to user 'yoku0825'@'localhost' for table 'user'

Σ(゚д゚lll) ダメじゃん。
と思ったら、ROLEはログインした後明示的に変更しないといけないぽい。


MariaDB [(none)]> SELECT current_role();
+----------------+
| current_role() |
+----------------+
| NULL           |
+----------------+
1 row in set (0.00 sec)

MariaDB [(none)]> SET ROLE sys_select;
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> SELECT current_role();
+----------------+
| current_role() |
+----------------+
| sys_select     |
+----------------+
1 row in set (0.00 sec)

MariaDB [(none)]> SELECT user, host FROM mysql.user;
+------------+-----------------+
| user       | host            |
+------------+-----------------+
| sys_select |                 |
| yoku0825   | %               |
| root       | 127.0.0.1       |
| root       | ::1             |
| root       | ip-172-31-0-135 |
| root       | localhost       |
+------------+-----------------+
6 rows in set (0.00 sec)

sudoっぽい感じ。でもどうやって戻るんだかよくわからない。


MariaDB [(none)]> CREATE ROLE sys_insert;
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> GRANT INSERT ON mysql.* TO sys_insert;
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> GRANT sys_insert TO yoku0825;
Query OK, 0 rows affected (0.01 sec)

MariaDB [(none)]> SELECT current_role();
+----------------+
| current_role() |
+----------------+
| NULL           |
+----------------+
1 row in set (0.00 sec)

MariaDB [(none)]> SET ROLE sys_select;
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> SELECT current_role();
+----------------+
| current_role() |
+----------------+
| sys_select     |
+----------------+
1 row in set (0.00 sec)

MariaDB [(none)]> SET ROLE sys_insert;
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> SELECT current_role();
+----------------+
| current_role() |
+----------------+
| sys_insert     |
+----------------+
1 row in set (0.00 sec)

MariaDB [(none)]> SELECT user, host FROM mysql.user;
ERROR 1142 (42000): SELECT command denied to user 'yoku0825'@'localhost' for table 'user'

SET ROLEで上書きすると、それまでのROLEの権限は使えなくなる。


MariaDB [(none)]> GRANT ALL ON d1.* TO yoku0825;
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> SELECT current_user();
+----------------+
| current_user() |
+----------------+
| yoku0825@%     |
+----------------+
1 row in set (0.00 sec)

MariaDB [(none)]> CREATE DATABASE d1;
Query OK, 1 row affected (0.00 sec)

MariaDB [(none)]> DROP DATABASE d1;
Query OK, 0 rows affected (0.01 sec)

MariaDB [(none)]> SET ROLE sys_select;
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> CREATE DATABASE d1;
Query OK, 1 row affected (0.00 sec)

MariaDB [(none)]> DROP DATABASE d1;
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> SHOW GRANTS;
+--------------------------------------------------+
| Grants for yoku0825@%                            |
+--------------------------------------------------+
| GRANT sys_select TO 'yoku0825'@'%'               |
| GRANT sys_insert TO 'yoku0825'@'%'               |
| GRANT USAGE ON *.* TO 'yoku0825'@'%'             |
| GRANT ALL PRIVILEGES ON `d1`.* TO 'yoku0825'@'%' |
| GRANT USAGE ON *.* TO 'sys_select'               |
| GRANT SELECT ON `mysql`.* TO 'sys_select'        |
+--------------------------------------------------+
6 rows in set (0.00 sec)

SET ROLESしても、予め与えられていた権限が上乗せされるわけではなくて、和になる。当然か。
SHOW GRANTSで見るとわかりやすげ。

もっとグループパーミッション的なものを想像していたけど、"sudoっぽい"ということで、取り敢えずそんなかんじ。


【2014/05/19 13:55】
DEFAULT ROLEが実装されればもう少し変わるんだろうけど、これは10.1での実装予定となっております。
https://mariadb.atlassian.net/browse/MDEV-5210

2014/05/15

pt-table-checksumでレプリケーション不整合を確認する

わたしはレプリケーション(と、バイナリーログ)フィルターが嫌いです。

フィルターが評価されるルール が理解されないまま運用されてカレントデータベースがNULLのままUPDATEを実行したりする人がいたりするので嫌なんですが、ストレージとかスレーブの性能とかネットワークの帯域とかで使わなければならないことも多々あります。

そんな時によく使う、 pt-table-checksum のメモ。

$ pt-table-checksum --socket /usr/mysql/5.6.17/data/mysql.sock --user root --password xxxx --tables d1.t1,d1.t2,d2.t1 --replicate test.pt-tcs --create-replicate-table
            TS ERRORS  DIFFS     ROWS  CHUNKS SKIPPED    TIME TABLE
05-15T17:36:00      0      0    39028       4       0   0.289 d1.t1
05-15T17:36:01      0      0   173469       4       0   0.239 d1.t2
05-15T17:36:14      0      0  5105937      15       0   7.264 d2.t1

こんなふうにマスターで流すと、


# at 108042433
#140515 17:36:00 server id 33597  end_log_pos 108043217 CRC32 0x0ca8897e        Query   thread_id=420836        exec_time=0
     error_code=0
use `test`/*!*/;
SET TIMESTAMP=1400142960/*!*/;
CREATE TABLE IF NOT EXISTS `test`.`pt-tcs` (
     db             char(64)     NOT NULL,
     tbl            char(64)     NOT NULL,
     chunk          int          NOT NULL,
     chunk_time     float            NULL,
     chunk_index    varchar(200)     NULL,
     lower_boundary text             NULL,
     upper_boundary text             NULL,
     this_crc       char(40)     NOT NULL,
     this_cnt       int          NOT NULL,
     master_crc     char(40)         NULL,
     master_cnt     int              NULL,
     ts             timestamp    NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
     PRIMARY KEY (db, tbl, chunk),
     INDEX ts_db_tbl (ts, db, tbl)
  ) ENGINE=InnoDB
/*!*/;
..
# at 108043627
#140515 17:36:00 server id 33597  end_log_pos 108044746 CRC32 0x0a0d40d3        Query   thread_id=420836        exec_time=0
     error_code=0
SET TIMESTAMP=1400142960/*!*/;
REPLACE INTO `test`.`pt-tcs` (db, tbl, chunk, chunk_index, lower_boundary, upper_boundary, this_cnt, this_crc) SELECT 'd1', 't1', '1', 'PRIMARY', '1', '1000', COUNT(*) AS cnt, COALESCE(LOWER(CONV(BIT_XOR(CAST(CRC32(CONCAT_WS('#', `column1`, `column2`, ..,)) AS UNSIGNED)), 10, 16)), 0) AS crc FROM `d1`.`t1` FORCE INDEX(`PRIMARY`) WHERE ((`column1` >= '1')) AND ((`column1` <= '1000')) /*checksum chunk*/
/*!*/;
..
# at 108044864
#140515 17:36:00 server id 33597  end_log_pos 108045097 CRC32 0x4799fdd5        Query   thread_id=420836        exec_time=0
     error_code=0
SET TIMESTAMP=1400142960/*!*/;
UPDATE `test`.`pt-tcs` SET chunk_time = '0.011250', master_crc = '4173135a', master_cnt = '1000' WHERE db = 'd1' AND tbl = 't1' AND chunk = '1'
/*!*/;
..

とまあこんな感じで、チェック対象のテーブルに入っている値をハッシュ計算してテーブルに入れ込んでくれます。

このREPLACE INTOやUPDATEはスレーブにも伝播され、スレーブ側で再実行(スレーブのテーブルに本当に入っている値をハッシュ計算してテーブルに入れ込む)されるので、スクリプトが流れ終わったあとにマスターとスレーブのこのテーブル(test.pt-tcs)の中身を比較してやれば、同じデータが入っているであろうことが判断できます。

pt-tcsを実行するサーバーからログインできるユーザーがいれば、pt-tcsの中でも直接比較してexit codeとかに反映してくれるようなことも書いてありますし、PMPを入れ込めば、この値に差分がないかどうかを定期的にNagiosから確認できたりもするようです。

http://www.percona.com/doc/percona-monitoring-plugins/1.1/nagios/pmp-check-pt-table-checksum.html


弱点は、RBRの環境下では使えないこと。マスターで計算されたハッシュ値がそのままスレーブに渡されてしまうので、意味を為さなくなってしまう。

が、PXC(Galera Cluster)でも使えるようなことが書いてあって、どうやって計算しているのだろう。SET SESSION binlog_format= STATEMENTを押し込むのかな?

2014/04/23

EC2のインスタンスでおもむろにGithubからcloneできなくなった

いつもテキトーにインスタンスを立てては、Githubのリポジトリーに突っ込んであったシェルスクリプトを落としてきてセットアップしているんだけれど。

# yum install -y git
..

# git clone https://github.com/yoku0825/my_setup
Cloning into 'my_setup'...

# echo $?
128

あれ?;
よくわからないけど、

# curl https://github.com/yoku0825/my_setup
Illegal instruction

# curl https://www.google.co.jp/
Illegal instruction

# curl http://www.google.co.jp/
..

なので、curlが悪そう。

# yum install -y curl
..

# git clone http://github.com/yoku0825/my_setup
Cloning into 'my_setup'...
remote: Reusing existing pack: 117, done.
remote: Total 117 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (117/117), 16.05 KiB | 0 bytes/s, done.
Resolving deltas: 100% (68/68), done.

できた。なんだったんだ。

2014/04/18

MySQL 5.5.36+ TokuDB 7.1.5のパラメーター斜め読み

TokuDB v7.1.5 with Fractal Tree Indexing for MySQL v5.5.36 User's Guide for linux の4章斜め読みメモ。
  • tokudb_commit_sync
    • InnoDBでいうinnodb-flush-log-at-trx-commitに相当する セッション変数
    • ON, OFFだけで2に相当するようなものは(この変数には)ない
  • tokudb_read_block_size
    • 1回の読み込みブロックのサイズ(解凍後のサイズ) セッション変数。
    • 値を小さくすると、狭いレンジスキャンのreadの性能が上がる(I/Oが減らせる)けど、広いレンジスキャンのread性能は落ちるよ、だそう。
    • 暗黙のデフォルトは64KB
  • tokudb_loader_memory_size
    • バルクロード(LOAD DATA INFILE)の時に使うらしい。サーバー変数。
    • 暗黙のデフォルトは100MB
    • バルクロード時に tokudb_cache_size から切り出されるから注意してね、らしい
  • tokudb_fsync_log_period
    • tokudb_commit_syncと関係なく、一定時間ごとにTokuDBログをfsyncするためのサーバー変数。
    • 暗黙のデフォルトは0。単位はミリ秒。
    • tokudb_commit_sync= 0 && tokudb_fsync_log_period= 1000でinnodb-flush-log-at-trx-commit= 2っぽい感じになるか。
  • tokudb_cache_size
    • InnoDBでいうinnodb-buffer-pool-sizeに相当。サーバー変数。
    • 暗黙のデフォルトは 物理メモリーの50%
    • tokudb_directioを使うならメモリーの80%くらい振るのがオススメ って書いてある
  • tokudb_directio
    • InnoDBでいうinnodb_flush_method= O_DIRECT
    • 暗黙のデフォルトはOFF
  • tokudb_lock_timeout
    • innodb_lock_wait_timeoutに相当するセッション変数。
    • 暗黙のデフォルトは4000(ms)。単位がmsなので注意。
  • tokudb_checkpointing_period
    • チェックポイント(TokuDBログファイルからTokuDBデータファイル(という呼び方で良いのかどうかは知らない)へのマージ)間隔
    • 暗黙のデフォルトは60で単位は秒。
    • いじらない方がいいよって書いてある。
  • tokudb_fs_reserve_percent
    • ファイルシステムにn%以上の空きがない場合、INSERTを許可しない…みたいに読める。
    • 暗黙のデフォルトは5、単位はパーセント。
    • この設定を使って、少なくとも物理メモリーの半分はリザーブしとけよ、って書いてある。

ちなみにtokudb_fs_reserve_percentを割り込んだ空き容量(75を設定して、利用率30%くらい)で何か操作をすると、

mysql> CREATE TABLE t2 (num serial) Engine= TokuDB;
ERROR 1030 (HY000): Got error 28 from storage engine

$ perror 28
OS error code  28:  No space left on device

ほほぅ。なるほど。

2014/04/15

Percona Server 5.6 with TokuDB Betaのインストール

社内で検証する人がいるらしいのでメモ書き風に。

MySQL Performance Blogでのリリースはここ。
Percona Server 5.6.16-64.2 with TokuDB engine Beta is now available


バイナリー(.tar.gz版)を落としてくる。サーバー本体(Percona Server)とプラグイン(TokuDB Storage Engine Plugin)でそれぞれDLする。

$ wget http://www.percona.com/redir/downloads/TESTING/Percona-5.6-TokuDB/beta/538/binary/tarball/release/percona-server-5.6.16-64.2-tokudb-7.1.5.el5.x86_64-server.tar.gz
$ wget http://www.percona.com/redir/downloads/TESTING/Percona-5.6-TokuDB/beta/538/binary/tarball/release/percona-server-5.6.16-64.2-tokudb-7.1.5.el5.x86_64-plugin.tar.gz
$ tar xzf percona-server-5.6.16-64.2-tokudb-7.1.5.el5.x86_64-server.tar.gz
$ tar xzf percona-server-5.6.16-64.2-tokudb-7.1.5.el5.x86_64-plugin.tar.gz

同じディレクトリで解凍すれば、ちゃんと./percona-server-5.6.16-64.2-tokudb-7.1.5.el5.x86_64 のlib/mysql/pluginとか mysql-test とかの下に入ってくれる。

CentOS(RHEL互換)の6.xの場合、transparent_hugepageを無効化する必要がある。

$ echo never > /sys/kernel/mm/transparent_hugepage/enabled
$ echo never > /sys/kernel/mm/transparent_hugepage/defrag

去年ハマってたやつ。 http://yoku0825.blogspot.jp/2013/07/tokudbcentos-63.html

mysql_install_dbで初期化して一度MySQL起動。
INSTALL PLUGIN的なことをやってくれるsqlファイルがあるのでそれを食わせる。

$ bin/mysql mysql < share/tokudb_engine_install.sql

これ、INSTALL PLUGIN叩いてくれるのかと思ったら、なぜかテンポラリーテーブルに一覧を作ってからmysql.pluginにINSERTする作りになっているので、デフォルトデータベースを指定しないと通らない。どうしてこうなった。

手でINSTALL PLUGINを叩くならこちらを参考に。 http://www.percona.com/doc/percona-server/5.6/tokudb/tokudb_installation.html

my.cnfにTokuDB関連の設定を追加。INSTALL PLUGIN(じゃないけど)前にTokuDB関連の値を設定すると、当然Unknown Variableでmysqldが起動してくれないので注意。looseつけとくか。

$ vim ./my.cnf
loose-tokudb_cache_size= 24G

とはいえまだ真面目にベンチマークしてないのでこれくらいしかわからない。
tokudb_cache_sizeはInnoDBでいうinnodb_buffer_pool_sizeのようなもの。本家のクイックスタートガイドでは、"物理メモリーの50%くらい割り当てたまえ"と書いてある。
(PDFです) http://www.tokutek.com/wp-content/uploads/2014/03/QuickStartGuide-7.1.5.pdf

InnoDBと一緒に使うと、コイツらでメモリーの割り当てを奪い合うことになりそうなので、できればTokuDBを使うところはTokuDB一本でいきたいところ。

ここでmysqldを再起動すれば、さっきのスクリプトでINSERTされたmysql.pluginが読み取られるので、次に起動してきたときにはTokuDBが有効になって起動してきます。


7/11のMySQL Casual TalksはTokuDBで行こうかと思っているので、カブる方はご連絡ください :)