Enable and convert MySQL to innodb file per table for Zoneminder

From ZoneMinder Wiki
Jump to navigationJump to search

Enable and convert MySQL to innodb_file_per_table for Zoneminder

Note: You may wish to convert MyISAM tables to InnoDB tables before you proceed. Upgrading Zoneminder to 1.26 or newer should do this for you.

innodb_file_per_table is by default ON Mysql 5.6.6 and onwards. There is plenty of stuff on Google about pros & cons of innodb_file_per_table. This post details how to enable innodb_file_per_table on an existing database. Because innodb_file_per_table affects new tables only, created after innodb_file_per_table is enabled, we need to recreate old databases to force innodb_file_per_table on old tables and reclaim some disk space. This has been tested on Ubuntu 14.04-1 running Zoneminder 1.26.5 and 1/28.0. I converted a database with over 30,000 Zoneminder events and 900 GIG of event files. I was able to reclaim over 500M of drive space!

If you have a new system and have not yet installed Zoneminder, run this procedure then install Zoneminder.

Become root

sudo su

Backup First

Create a dir to take backups:

cd ~

Note: I found it helpful to create a file which contained the MySQL user and password. Otherwise you will have to enter the user and password for every operation.

nano .my.cnf

Enter this content

[client]
user=root
password=mysqlpass

Ctrl+o Enter to save

CTRL+x to exit


Make backup directory

mkdir backup
cd backup

Copy MySQL data files (raw) (If all goes well, we will not need this)

Stop Zoneminder

service zoneminder stop

If you have other services that use MySQL you will want to stop them and possibly Apache.

service mysql stop && cp -ra /var/lib/mysql mysqldata && service mysql start

Take mysqldump As soon as above line completes, take a mysqldump of all databases

mysqldump --routines --events --flush-privileges --all-databases > all-db.sql

Drop Databases Create a sql file to drop all databases EXCEPT mysql database

mysql -e "SELECT DISTINCT CONCAT ('DROP DATABASE ',TABLE_SCHEMA,' ;') FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA <> 'mysql' AND TABLE_SCHEMA <> 'information_schema';" | tail -n+2 > drop.sql

Verify if drop.sql has correct database names and then execute drop.sql queries.

mysql < drop.sql

Verify all InnoDB tables gone

SELECT table_name, table_schema, engine FROM information_schema.tables WHERE engine = 'InnoDB';

Remove InnoDB files Stop mysql server first

service mysql stop

Then

rm /var/lib/mysql/ibdata1 && rm /var/lib/mysql/ib_logfile0 && rm /var/lib/mysql/ib_logfile1

At this point most likely you will have only /var/lib/mysql/mysql directory only.

Enable innodb_file_per_table

Open my.cnf file

nano /etc/mysql/my.cnf

Add following line after [mysqld]

innodb_file_per_table

Ctrl+o Enter to save

CTRL+x to exit

Time to import from mysqldump Start mysql server now

service mysql start

Run mysql import

mysql < all-db.sql

Force mysql_upgrade (to generate performance_schema)

mysql_upgrade --force

That’s All!

Restart Zoneminder (and any other services you have stopped)

service zoneminder start

Check for proper operation and that all your events are present.

When you are satisfied that all is worling well remove the backup directory and password filr=e

cd ~
rm -r backup
rm .my.cnf

You are finished!

This procedure has been adopted from https://rtcamp.com/tutorials/mysql/enable-innodb-file-per-table. Thanks to Rahul Bansal!