completely delete sonar project [duplicate] - mysql
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.
Related
MySQL: error collation "in use" and table could not be loaded
I have my VPS installed cPanel. Today it suddenly not work, all of Wordpress websites on VPS show the error: This webpage has a redirect loop ERR_TOO_MANY_REDIRECTS and auto redirect to wp-admin/install.php. I log in to phpmyadmin then see some tables have collation "in use" (not "utf8_general_ci" such as normally). Can't be loaded because of error: #1286 - Unknown storage engine 'InnoDB'". So how to fix this error? Thanks for help me!
I faced the same issue, this issue raised up because your innoDB got corrupted and all your databases using innoDB tables are showing in-use. To fix this issue you need to follow the below steps To get 100% clean tablespace you need to start MySQL with innodb_force_recovery=4, take mysqldump and restore it on a fresh instance of InnoDB (by fresh I mean you have to delete ibdata1, and all databases directories). UPDATE: At this point MySQL is started with innodb_force_recovery=x (x != 0) Take dump of all databases: mysqldump --skip-lock-tables -A > alldb.sql Check where MySQL keeps its files(in my case it's /var/lib/mysql/): mysql -NBe "SELECT ##datadir" /var/lib/mysql/ Stop MySQL mysqladmin shut Move old MySQL files to safe place mv /var/lib/mysql /var/lib/mysql.old Create new system database mkdir /var/lib/mysql mysql_install_db Start MySQL /etc/init.d/mysql start Restore the dump mysql < alldb.sql Restore may take long time if the database is big. Another trick may work in that case. Run ALTER TABLE ... ENGINE INNODB on each InnoDB table. It will rebuild all InnoDB indexes and thus the errors will go away. +++++++++++++++++++++++++++++++++++++++++++++++++ Another solution to this is restoring the databases from backup. For this first you need to remove ibdata1 file cd /var/lib/mysql rm -f ibdata1 Then restore all the databases one by one using below command mysql -u username -p databasename < backupfile.sql ++++++++++++++++++++++++++++++++++++++++++++++++++
Incremental backup with rollforward logs: How to get the logs with MySQL commands?
I have a MySQL database with activated binary logging (i.e. rollforward logs). The logs are located (by default) in /var/log/mysql which is accessible by the users mysql and root only. I make (full) backups every Sunday with a cronjob like this: mysqldump -u root --flush-logs $database > $database.sql mysql -u root -e 'purge binary logs before now();' # or "reset master", which is the same I know that mysqldump has no option for incremental backups and the binary logs actually are the incremental backup -- or at least can bee seen as such. So every Wednesday I make an incremental backup by flushing and copying the binlog files: mysql -u root -e 'flush binary logs;' cp /var/log/mysql/mysql-bin.* $some_backup_path (Code to sort out the current binlog omitted here.) There are various commands to inspect the binlog files, like show binary logs; -- display flush binary logs; -- start a new one reset master; -- delete all and start over purge binary logs before $some_date; -- delete older logs However, there seems to be no MySQL command to fetch them. The only way seems to copy them with "regular" Unix commands, like cp or rsync as user root. Is that true? I know there are other ways to make backups, such as the MySQL Enterprise stuff or simply backing up the /var/lib/mysql directory. I'm just curious.
You can use mysqlbinlog utility to administer binary log files, including copying them to another location. Within mysql you can use show binlog events command to access most of the contents within a binary log.
Mysql Innodb Optimize table
I have a 100Gb innodb table on C:\ drive and the C:\ drive is out of space now.I deleted many rows but the the ibd file did not shrink. I have more than 200Gb available on D:\drive and subsequently configured tmpdir to be in d:\drive and tried to optimize table .But when I optimize table it is taking up whatever space is left on c:\ drive and not using d:\ What parameter should I change?
You cannot shrink the innodb data file (default name is ibdata1) without deleting it :S . Using innodb engine you should use innodb_file_per_table=1 To solve you space issue you should: 1) Execute a full database backup: mysqldump -u root -pMyPassword -R --all-databases > full.sql 2) Stop mysql service 3) Add (or change value of) the parameter innodb_file_per_table=1 4) Drop the existing innodb data file (/$mysqldir/ibdata1) 5) Start mysql service 6) Restore the backup: mylsql -u root -pMyPassword mysql < full.sql Now the innodb data file will not growth too much anymore, and an optimize table will allow you to shrink the involve table data file since now each table will amnage it's own data file. Using symbolic links (at least under Linux), it allows you to locate databases on different disks.
There is tmpdir parameter for that. And I think you can set that with SET GLOBAL tmpdir = D:/temp before any optimization operation or add following under mysld set-variable = tmpdir=/var/tmp As a bonus I strongly suggest you to use innodb_file_per_table=1 to have separate file for each table if of course you have innodb tables. And also using compressed data will reduce your disk usage.
MySql backup and restoration
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.
How to shrink/purge ibdata1 file in MySQL
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.