====== How to Optimize MySQL DB - WAN Keystone ====== ===== Reference ===== * [[https://bugs.launchpad.net/fuel/+bug/1316003 | MySQL is not configured with innodb_file_per_table = 1 ]] * [[https://dev.mysql.com/doc/refman/5.5/en/innodb-parameters.html#sysvar_innodb_file_per_table | nnodb_file_per_table]] * [[https://bugs.launchpad.net/python-keystoneclient/+bug/1195924 | Keystone client BUG #1195924 - expiration check is using different timezone other than UTC ]] ===== PROBLEM ===== After one week of activity the ibdata1 file was 8.1G and... growing root@keystone:~# ls -lh /var/lib/mysql/ibdata1 -rw-rw---- 1 mysql mysql 8.1G May 12 13:01 /var/lib/mysql/ibdata1 This caused a "disk full problem" in LNGS, followed up by a degradation of the DB and the impossibility to restart mysql on the primary node of the cluster, keystone.pd.infn.it # less /var/lib/mysql/keystone.err [...] InnoDB: Your database may be corrupt or you may have copied the InnoDB InnoDB: tablespace but not the InnoDB log files. See InnoDB: http://dev.mysql.com/doc/refman/5.5/en/forcing-innodb-recovery.html InnoDB: for more information. 140509 12:51:34 [ERROR] Slave SQL: Could not execute Write_rows event on table keystone.token; Duplicate entry '494830e055f015b77457cefe1ff2c9cc' for key 'PRIMARY', Error_co de: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log FIRST, end_log_pos 30457, Error_code: 1062 140509 12:51:34 [Warning] WSREP: RBR event 2 Write_rows apply warning: 121, 861859 140509 12:51:34 [Warning] WSREP: Failed to apply app buffer: seqno: 861859, status: 1 at galera/src/replicator_smm.cpp:apply_wscoll():57 Retrying 2th time [...] 140509 12:51:34 [ERROR] Slave SQL: Could not execute Write_rows event on table keystone.token; Duplicate entry '494830e055f015b77457cefe1ff2c9cc' for key 'PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log FIRST, end_log_pos 30457, Error_code: 1062 140509 12:51:34 [Warning] WSREP: RBR event 2 Write_rows apply warning: 121, 861859 140509 12:51:34 [ERROR] WSREP: receiving IST failed, node restart required: Failed to apply trx 861859 10 times 140509 12:51:34 [Note] WSREP: Closing send monitor... 140509 12:51:34 [Note] WSREP: Closed send monitor. 140509 12:51:34 [Note] WSREP: gcomm: terminating thread 140509 12:51:34 [Note] WSREP: gcomm: joining thread 140509 12:51:34 [Note] WSREP: gcomm: closing backend 140509 12:51:34 [Note] WSREP: view(view_id(NON_PRIM,157f634e-d5ce-11e3-b07e-265b1d5e5cf0,1461) memb { dff534f1-d767-11e3-b8c5-ffab4b83e1d2, } joined { } left { } partitioned { 157f634e-d5ce-11e3-b07e-265b1d5e5cf0, 27f583aa-c60a-11e3-af90-6a5bb07181cf, }) 140509 12:51:34 [Note] WSREP: New COMPONENT: primary = no, bootstrap = no, my_idx = 0, memb_num = 1 140509 12:51:34 [Note] WSREP: view((empty)) 140509 12:51:34 [Note] WSREP: gcomm: closed 140509 12:51:34 [Note] WSREP: Flow-control interval: [16, 16] 140509 12:51:34 [Note] WSREP: Received NON-PRIMARY. 140509 12:51:34 [Note] WSREP: Shifting JOINER -> OPEN (TO: 862345) 140509 12:51:34 [Note] WSREP: Received self-leave message. 140509 12:51:34 [Note] WSREP: Flow-control interval: [0, 0] 140509 12:51:34 [Note] WSREP: Received SELF-LEAVE. Closing connection. 140509 12:51:34 [Note] WSREP: Shifting OPEN -> CLOSED (TO: 862345) 140509 12:51:34 [Note] WSREP: RECV thread exiting 0: Success 140509 12:51:34 [Note] WSREP: recv_thread() joined. 140509 12:51:34 [Note] WSREP: Closing replication queue. 140509 12:51:34 [Note] WSREP: Closing slave action queue. 140509 12:51:34 [Note] WSREP: /usr/sbin/mysqld: Terminated. Aborted (core dumped) 140509 12:51:34 mysqld_safe Number of processes running now: 0 140509 12:51:34 mysqld_safe WSREP: not restarting wsrep node automatically 140509 12:51:34 mysqld_safe mysqld from pid file /var/lib/mysql/keystone.pid ended The issue was due to the increased number of tokens, ~20000 in 24h, that are registered in the keystone DB, and not flushed. # mysql -u root x xxxxxx mysql> use keystone; mysql> SELECT COUNT(*) FROM token; +----------+ | COUNT(*) | +----------+ | 18141 | +----------+ ==== SOLUTION ==== In order to reduce the number of tokens registered, to better handle the MySQL DBs it was decided to do the following steps: * configure mysql with "innodb_file_per_table=1" (see reference) * set in Keystone the token expiration to 3h * define a cron, in one of the hosts to flush tokens and optimize the token table in the keystone db **STEPS**: 1. Stop mysql and keystone on all nodes of the cluster 2. Choose one node and do the following steps: * start mysql * mysqldump of all DBs * stop mysql * in my.cnf comment all lines containing wsrep* and add innodb_file_per_table in the [mysqld] section # grep innodb_file_per_table /etc/mysql/my.cnf innodb_file_per_table=1 * start mysql * drop all databases except mysql, information_schema, performance_schema, certs and restore them from the dump previousley done * stop mysql * in my.cnf uncomment all wsrep* previously commented and change the wsrep_cluster_address # grep wsrep_cluster_address /etc/mysql/my.cnf |egrep -v '^ #|^#|^$' wsrep_cluster_address=gcomm:// * due to a bug in Havana (see details bellow and [[expiration check is using different timezone other than UTC | Ref3]]) - in keystone.conf add "expiration = 10800" in the [token] section [token] driver = keystone.token.backends.sql.Token # Amount of time a token should remain valid (in seconds) # expiration = 86400 expiration=10800 * restart mysql * define a cron to execute the following script every 3h: #!/bin/bash /usr/bin/keystone-manage -v -d token_flush /bin/ls -ltr /var/lib/mysql/keystone/token.ibd echo "optimize table token" | /usr/bin/mysql -u root -pxxxxxx keystone /bin/ls -ltr /var/lib/mysql/keystone/token.ibd 3. On the other nodes of the cluster: * stop mysql * in my.cnf comment all lines containing wsrep* * start mysql * drop all databases except mysql, information_schema, performance_schema, certs * stop mysql * in /var/lib/mysql remove galera.cache grastate.dat ibdata1 ib_logfile* wsrep_recovery* # cd /var/lib/mysql # rm galera.cache grastate.dat ibdata1 ib_logfile* wsrep_recovery* * add innodb_file_per_table in the [mysqld] section # grep innodb_file_per_table /etc/mysql/my.cnf innodb_file_per_table=1 * start mysql * stop mysql * in my.cnf uncomment all wsrep* previously commented and change the wsrep_cluster_address # grep wsrep_cluster_address /etc/mysql/my.cnf |egrep -v '^ #|^#|^$' wsrep_cluster_address=gcomm://193.206.210.164,90.147.112.3,90.147.102.131 * start mysql 4. On the "chosen" server, in my.cnf change: wsrep_cluster_address=gcomm:// back to wsrep_cluster_address=gcomm://193.206.210.164,90.147.112.3,90.147.102.131 and restart mysql Now there should be directories for each DB, in particular for keystone: # ls -ltrh /var/lib/mysql/keystone/token.* -rw-rw---- 1 mysql mysql 8.6K May 18 08:00 /var/lib/mysql/keystone/token.frm -rw-rw---- 1 mysql mysql 596M May 18 22:26 /var/lib/mysql/keystone/token.ibd === Details of BUG #1195924 === [[https://bugs.launchpad.net/python-keystoneclient/+bug/1195924 | BUG # 1195924 | expiration check is using different timezone other than UTC ]] * the token are generated with start and expiration hour expresed in UTC, but the client libraries do the verification using the local time (in Italy = UTC +2h) during 1 hour. * the patch was released for/in Icehouse - for which version we can think to leave the tokens duration of 1 h by default and configure the cron to run every hour.