Trying to find out how people do a full backup/restore procedure: The user defined database schema and data can be easily backed up via mysqldump, but what about the master tables and data? i.e. if the server goes completely bananas, how can I rebuild the database, i.e. including all the settings in Mysql? is it just a matter of dumping/importing the information_schema and mysql databases + restore my.cnf ? (innodb or MyISAM, not ISAM)
--
edit: Thanks!
You don't back up information_schema, but otherwise, yes, keep a copy of your my.cnf and a dump of the mysql db tables and log settings. To do this do:
mysqldump -u$user -p$pass --all-databases > db_backup.sql
If you're going to restore to the 100% same version of MySQL, you could also backup by shutting down your server and doing a full copy of the contents of /var/lib/mysql (or wherever your data files are) along with your my.cnf file. Then just drop the copy back in place when you want to go live and turn on your server.
Related
is there a more efficient method to transfer all the databases from phpmyadmin,rather than to create database copies and manually import them on other machines.
Earlier I tried to copy the entire folder and replace the older config.inc.php but I am unable to see all the databases
there are a couple of options which usually depends on your needs/db size/tables engine and so on:
mysqldump + rsync dump + restore (if you do not have a good connection between hosts)
mysqldump | mysql -h H -u -p
If you can't stand with big downtime you can setup replication between two hosts using innodbbackup utility
If you use MyISAM tables you can shutdown MySQL you copy related files to destination datadir. This option will not work for InnoDB tables.
I know, it is really sad trying to export a database just by copying the data folder! But I have a hard disk with an important database inside and I don't know how to export this database onto my actual system (winxp - mysql 5.0.37).
So, i've copied old_harddisk/program/mysql/data/coge2010 to mypc/programs/mysql/data/coge2010
Result:
I see cogemilla (4) on my phpMyAdmin databases summary (it's correct!!! my 4 tables!)
If I click the database, I see just 1 table (oh no!)
On the mysql error log file I find messages like this one: "...[ERROR] Cannot find table coge2010/soci from the internal data dictionary of InnoDB though the .frm file for the table exists. Maybe you have deleted and recreated InnoDB data files but have forgotten to delete the corresponding .frm files of InnoDB tables, or you have moved .frm files to another database? See http://dev.mysql.com/doc/refman/5.0/en/innodb-troubleshooting.html how you can resolve the problem."
Any ideas?
You should create a dump and import it on the new server.
In Command Prompt type the following to create the dumpfile:
mysqldump -h host -u user -p databaseName > dumpFile.sql
To import the database :
mysql -h host -u user -p databaseName < dumpFile.sql
You can only copy InnoDB tables if:
1. Your database is stopped.
2. You copy all InnoDB files (ibdata* ib_logfile* /*.ibd
You could use dump/restore to copy a single table.
You could user 'ALTER TABLE sometable ENGINE=MyISAM' to convert it to MyISAM and then copy the MYI,MYD and FRM.
Percona XtraBackup can do single table restores if you're using Percona Server.
This post may help you.
Another post which may help you.
A mysql table is defined by 3 files (FRM/MYD/MYI). In your case the FRM file is missing into the database folder.
If you can run the mysql server of the old hard disk it is easier to do a dump of your database. The following link shows you how to do this
I am using MySQL in localhost as a "query tool" for performing statistics in R, that is, everytime I run a R script, I create a new database (A), create a new table (B), import the data into B, submit a query to get what I need, and then I drop B and drop A.
It's working fine for me, but I realize that the ibdata file size is increasing rapidly, I stored nothing in MySQL, but the ibdata1 file already exceeded 100 MB.
I am using more or less default MySQL setting for the setup, is there a way for I can automatically shrink/purge the ibdata1 file after a fixed period of time?
That ibdata1 isn't shrinking is a particularly annoying feature of MySQL. The ibdata1 file can't actually be shrunk unless you delete all databases, remove the files and reload a dump.
But you can configure MySQL so that each table, including its indexes, is stored as a separate file. In that way ibdata1 will not grow as large. According to Bill Karwin's comment this is enabled by default as of version 5.6.6 of MySQL.
It was a while ago I did this. However, to setup your server to use separate files for each table you need to change my.cnf in order to enable this:
[mysqld]
innodb_file_per_table=1
https://dev.mysql.com/doc/refman/5.6/en/innodb-file-per-table-tablespaces.html
As you want to reclaim the space from ibdata1 you actually have to delete the file:
Do a mysqldump of all databases, procedures, triggers etc except the mysql and performance_schema databases
Drop all databases except the above 2 databases
Stop mysql
Delete ibdata1 and ib_log files
Start mysql
Restore from dump
When you start MySQL in step 5 the ibdata1 and ib_log files will be recreated.
Now you're fit to go. When you create a new database for analysis, the tables will be located in separate ibd* files, not in ibdata1. As you usually drop the database soon after, the ibd* files will be deleted.
http://dev.mysql.com/doc/refman/5.1/en/drop-database.html
You have probably seen this:
http://bugs.mysql.com/bug.php?id=1341
By using the command ALTER TABLE <tablename> ENGINE=innodb or OPTIMIZE TABLE <tablename> one can extract data and index pages from ibdata1 to separate files. However, ibdata1 will not shrink unless you do the steps above.
Regarding the information_schema, that is not necessary nor possible to drop. It is in fact just a bunch of read-only views, not tables. And there are no files associated with the them, not even a database directory. The informations_schema is using the memory db-engine and is dropped and regenerated upon stop/restart of mysqld. See https://dev.mysql.com/doc/refman/5.7/en/information-schema.html.
Adding to John P's answer,
For a linux system, steps 1-6 can be accomplished with these commands:
mysqldump -u [username] -p[root_password] [database_name] > dumpfilename.sql
mysqladmin -u [username] -p[root_password] drop [database_name]
sudo /etc/init.d/mysqld stop
sudo rm /var/lib/mysql/ibdata1
sudo rm /var/lib/mysql/ib_logfile*
sudo /etc/init.d/mysqld start
mysqladmin -u [username] -p[root_password] create [database_name]
mysql -u [username] -p[root_password] [database_name] < dumpfilename.sql
Warning: these instructions will cause you to lose other databases if you have other databases on this mysql instance. Make sure that steps 1,2 and 6,7 are modified to cover all databases you wish to keep.
When you delete innodb tables, MySQL does not free the space inside the ibdata file, that's why it keeps growing. These files hardly ever shrink.
How to shrink an existing ibdata file:
https://dev.mysql.com/doc/refman/5.6/en/innodb-system-tablespace.html#innodb-resize-system-tablespace
You can script this and schedule the script to run after a fixed period of time, but for the setup described above it seems that multiple tablespaces are an easier solution.
If you use the configuration option innodb_file_per_table, you create multiple tablespaces. That is, MySQL creates separate files for each table instead of one shared file. These separate files a stored in the directory of the database, and they are deleted when you delete this database. This should remove the need to shrink/purge ibdata files in your case.
More information about multiple tablespaces:
https://dev.mysql.com/doc/refman/5.6/en/innodb-file-per-table-tablespaces.html
Quickly scripted the accepted answer's procedure in bash:
#!/usr/bin/env bash
dbs=$(mysql -BNe 'show databases' | grep -vE '^mysql$|^(performance|information)_schema$')
mysqldump --events --triggers --databases $dbs > alldatabases.sql && \
echo "$dbs" | while read -r db; do
mysqladmin drop "$db"
done && \
mysql -e 'SET GLOBAL innodb_fast_shutdown = 0' && \
/etc/init.d/mysql stop && \
rm -f /var/lib/mysql/ib{data1,_logfile*} && \
/etc/init.d/mysql start && \
mysql < alldatabases.sql
Save as purge_binlogs.sh and run as root.
Excludes mysql, information_schema, performance_schema (and binlog directory).
Assumes you have administrator credendials in /root/.my.cnf and that your database lives in default /var/lib/mysql directory.
You can also purge binary logs after running this script to regain more disk space with:
PURGE BINARY LOGS BEFORE CURRENT_TIMESTAMP;
If you use the InnoDB storage engine for (some of) your MySQL tables, you’ve probably already came across a problem with its default configuration. As you may have noticed in your MySQL’s data directory (in Debian/Ubuntu – /var/lib/mysql) lies a file called ‘ibdata1′. It holds almost all the InnoDB data (it’s not a transaction log) of the MySQL instance and could get quite big. By default this file has a initial size of 10Mb and it automatically extends. Unfortunately, by design InnoDB data files cannot be shrinked. That’s why DELETEs, TRUNCATEs, DROPs, etc. will not reclaim the space used by the file.
I think you can find good explanation and solution there :
http://vdachev.net/2007/02/22/mysql-reducing-ibdata1/
If your goal is to monitor MySQL free space and you can't stop MySQL to shrink your ibdata file, then get it through table status commands. Example:
MySQL > 5.1.24:
mysqlshow --status myInnodbDatabase myTable | awk '{print $20}'
MySQL < 5.1.24:
mysqlshow --status myInnodbDatabase myTable | awk '{print $35}'
Then compare this value to your ibdata file:
du -b ibdata1
Source: http://dev.mysql.com/doc/refman/5.1/en/show-table-status.html
In a new version of mysql-server recipes above will crush "mysql" database.
In old version it works. In new some tables switches to table type INNODB, and by doing so you will damage them.
The easiest way is to:
dump all you databases
uninstall mysql-server,
add in remained my.cnf:
[mysqld]
innodb_file_per_table=1
erase all in /var/lib/mysql
install mysql-server
restore users and databases
What nobody seems to mention is the impact innodb_undo_log_truncate setting can have.
After reading Percona's blog post about the topic, I've enabled in my MariaDB 10.6 the truncation of UNDO LOG entries which filled 95% of ibdata1, and, after a complete drop and restore, from that moment on my ibdata1 never grew anymore.
With the default innodb_undo_log_truncate = 0 my ibdata1 easily reached 10% of databases space occupation, aka tens of Gigabytes.
With innodb_undo_log_truncate = 1, ibdata1 it's firm at 76 Mb.
As already noted you can't shrink ibdata1 (to do so you need to dump and rebuild), but there's also often no real need to.
Using autoextend (probably the most common size setting) ibdata1 preallocates storage, growing each time it is nearly full. That makes writes faster as space is already allocated.
When you delete data it doesn't shrink but the space inside the file is marked as unused. Now when you insert new data it'll reuse empty space in the file before growing the file any further.
So it'll only continue to grow if you're actually needing that data. Unless you actually need the space for another application there's probably no reason to shrink it.
I am using MySQL in localhost as a "query tool" for performing statistics in R, that is, everytime I run a R script, I create a new database (A), create a new table (B), import the data into B, submit a query to get what I need, and then I drop B and drop A.
It's working fine for me, but I realize that the ibdata file size is increasing rapidly, I stored nothing in MySQL, but the ibdata1 file already exceeded 100 MB.
I am using more or less default MySQL setting for the setup, is there a way for I can automatically shrink/purge the ibdata1 file after a fixed period of time?
That ibdata1 isn't shrinking is a particularly annoying feature of MySQL. The ibdata1 file can't actually be shrunk unless you delete all databases, remove the files and reload a dump.
But you can configure MySQL so that each table, including its indexes, is stored as a separate file. In that way ibdata1 will not grow as large. According to Bill Karwin's comment this is enabled by default as of version 5.6.6 of MySQL.
It was a while ago I did this. However, to setup your server to use separate files for each table you need to change my.cnf in order to enable this:
[mysqld]
innodb_file_per_table=1
https://dev.mysql.com/doc/refman/5.6/en/innodb-file-per-table-tablespaces.html
As you want to reclaim the space from ibdata1 you actually have to delete the file:
Do a mysqldump of all databases, procedures, triggers etc except the mysql and performance_schema databases
Drop all databases except the above 2 databases
Stop mysql
Delete ibdata1 and ib_log files
Start mysql
Restore from dump
When you start MySQL in step 5 the ibdata1 and ib_log files will be recreated.
Now you're fit to go. When you create a new database for analysis, the tables will be located in separate ibd* files, not in ibdata1. As you usually drop the database soon after, the ibd* files will be deleted.
http://dev.mysql.com/doc/refman/5.1/en/drop-database.html
You have probably seen this:
http://bugs.mysql.com/bug.php?id=1341
By using the command ALTER TABLE <tablename> ENGINE=innodb or OPTIMIZE TABLE <tablename> one can extract data and index pages from ibdata1 to separate files. However, ibdata1 will not shrink unless you do the steps above.
Regarding the information_schema, that is not necessary nor possible to drop. It is in fact just a bunch of read-only views, not tables. And there are no files associated with the them, not even a database directory. The informations_schema is using the memory db-engine and is dropped and regenerated upon stop/restart of mysqld. See https://dev.mysql.com/doc/refman/5.7/en/information-schema.html.
Adding to John P's answer,
For a linux system, steps 1-6 can be accomplished with these commands:
mysqldump -u [username] -p[root_password] [database_name] > dumpfilename.sql
mysqladmin -u [username] -p[root_password] drop [database_name]
sudo /etc/init.d/mysqld stop
sudo rm /var/lib/mysql/ibdata1
sudo rm /var/lib/mysql/ib_logfile*
sudo /etc/init.d/mysqld start
mysqladmin -u [username] -p[root_password] create [database_name]
mysql -u [username] -p[root_password] [database_name] < dumpfilename.sql
Warning: these instructions will cause you to lose other databases if you have other databases on this mysql instance. Make sure that steps 1,2 and 6,7 are modified to cover all databases you wish to keep.
When you delete innodb tables, MySQL does not free the space inside the ibdata file, that's why it keeps growing. These files hardly ever shrink.
How to shrink an existing ibdata file:
https://dev.mysql.com/doc/refman/5.6/en/innodb-system-tablespace.html#innodb-resize-system-tablespace
You can script this and schedule the script to run after a fixed period of time, but for the setup described above it seems that multiple tablespaces are an easier solution.
If you use the configuration option innodb_file_per_table, you create multiple tablespaces. That is, MySQL creates separate files for each table instead of one shared file. These separate files a stored in the directory of the database, and they are deleted when you delete this database. This should remove the need to shrink/purge ibdata files in your case.
More information about multiple tablespaces:
https://dev.mysql.com/doc/refman/5.6/en/innodb-file-per-table-tablespaces.html
Quickly scripted the accepted answer's procedure in bash:
#!/usr/bin/env bash
dbs=$(mysql -BNe 'show databases' | grep -vE '^mysql$|^(performance|information)_schema$')
mysqldump --events --triggers --databases $dbs > alldatabases.sql && \
echo "$dbs" | while read -r db; do
mysqladmin drop "$db"
done && \
mysql -e 'SET GLOBAL innodb_fast_shutdown = 0' && \
/etc/init.d/mysql stop && \
rm -f /var/lib/mysql/ib{data1,_logfile*} && \
/etc/init.d/mysql start && \
mysql < alldatabases.sql
Save as purge_binlogs.sh and run as root.
Excludes mysql, information_schema, performance_schema (and binlog directory).
Assumes you have administrator credendials in /root/.my.cnf and that your database lives in default /var/lib/mysql directory.
You can also purge binary logs after running this script to regain more disk space with:
PURGE BINARY LOGS BEFORE CURRENT_TIMESTAMP;
If you use the InnoDB storage engine for (some of) your MySQL tables, you’ve probably already came across a problem with its default configuration. As you may have noticed in your MySQL’s data directory (in Debian/Ubuntu – /var/lib/mysql) lies a file called ‘ibdata1′. It holds almost all the InnoDB data (it’s not a transaction log) of the MySQL instance and could get quite big. By default this file has a initial size of 10Mb and it automatically extends. Unfortunately, by design InnoDB data files cannot be shrinked. That’s why DELETEs, TRUNCATEs, DROPs, etc. will not reclaim the space used by the file.
I think you can find good explanation and solution there :
http://vdachev.net/2007/02/22/mysql-reducing-ibdata1/
If your goal is to monitor MySQL free space and you can't stop MySQL to shrink your ibdata file, then get it through table status commands. Example:
MySQL > 5.1.24:
mysqlshow --status myInnodbDatabase myTable | awk '{print $20}'
MySQL < 5.1.24:
mysqlshow --status myInnodbDatabase myTable | awk '{print $35}'
Then compare this value to your ibdata file:
du -b ibdata1
Source: http://dev.mysql.com/doc/refman/5.1/en/show-table-status.html
In a new version of mysql-server recipes above will crush "mysql" database.
In old version it works. In new some tables switches to table type INNODB, and by doing so you will damage them.
The easiest way is to:
dump all you databases
uninstall mysql-server,
add in remained my.cnf:
[mysqld]
innodb_file_per_table=1
erase all in /var/lib/mysql
install mysql-server
restore users and databases
What nobody seems to mention is the impact innodb_undo_log_truncate setting can have.
After reading Percona's blog post about the topic, I've enabled in my MariaDB 10.6 the truncation of UNDO LOG entries which filled 95% of ibdata1, and, after a complete drop and restore, from that moment on my ibdata1 never grew anymore.
With the default innodb_undo_log_truncate = 0 my ibdata1 easily reached 10% of databases space occupation, aka tens of Gigabytes.
With innodb_undo_log_truncate = 1, ibdata1 it's firm at 76 Mb.
As already noted you can't shrink ibdata1 (to do so you need to dump and rebuild), but there's also often no real need to.
Using autoextend (probably the most common size setting) ibdata1 preallocates storage, growing each time it is nearly full. That makes writes faster as space is already allocated.
When you delete data it doesn't shrink but the space inside the file is marked as unused. Now when you insert new data it'll reuse empty space in the file before growing the file any further.
So it'll only continue to grow if you're actually needing that data. Unless you actually need the space for another application there's probably no reason to shrink it.
How can I backup my MySQL's databases? I'm using Windows Vista and MySQL 5.1.
I have found the folder "C:\Users\All Users\MySQL\MySQL Server 5.1\data" with all my database files and copy them, but how can I restore them if I need?
Thank you.
You could use the mysqldump tool:
http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html
That way you'd get SQL files that you could just execute.
You can also go surf to localhost/phpmyadmin and go to 'export' and select the databases you want to export.
The backup process does not have anything to do with your operating system. Simply export your databases.
You can back up the database files directly, but this can be dangerous if the database is in active use at the time you do the backup. There's no guarantee that you'll make a consistent and valid backup if a query starts modifying on-disk data. You may end up with broken tables.
The safest route is to use mysqldump to output a set of sql statements which can recreate the database completely (table creation + data) in one go. Should you need to restore from backup, you can simply feed this dump file back to mysql:
mysqldump -p -u username nameofdatabase > backup.sql
and restore via:
mysql -p -u username nameofdatabase < backup.sql
The .sql file is just a plaintext dump of all the queries required to rebuild the table(s) and their data.