mysql

17th December
2009
written by Chris

The following command will optimize all databases in mysql (excpect those that don't support it due to their storage engine).

mysqlcheck -Aao

You can throw the

--auto-repair

flag in if you are brave.

Tags: ,
12th December
2009
written by Chris

If you need to change the TTLs on all domains in Plesk at once, you can massage the database with the following command:

mysql> UPDATE `dns_zone` SET `ttl` = '300', `ttl_unit` = '60' WHERE `id` >1;

Substitute the TTL values for what you need. Since the flat files are still used by named to provide DNS resolution, those will need to be updated as well. This command will do the trick:

mysql -Ns -uadmin -p`cat /etc/psa/.psa.shadow` -D psa -e 'select name from domains' | awk '{print "/usr/local/psa/admin/sbin/dnsmng update " $1 }' | sh
Tags: ,
31st July
2009
written by Chris

On more than one occasion I have had to figure out how to restore data from a mysql-binlog and I do it so infrequently that I decided to put the command here so I know where to find it in the future. The first thing to do is to export the binlog. Since it is in binary, you will need to use the mysqlbinlog command.

Let's assume we have a file called mysql-binlog.000111. There are a number of ways this can be exported, based on your needs, and those choices are available via command line flags (man mysqlbinlog for details). Let's say you need data from a certain start time up to a certain end time. This can be specified on the command line. You can also specify the database that you wish to export the data for. This is because if you run multiple databases, they are all logged to the same set of binlogs. A command to do all of this would look like (it doesn't show, but the flags are all preceeded by double dashes):

mysqlbinlog –start-datetime="2009-07-31 05:00:00" –stop-datetime="2009-07-31 10:05:00" –database mydatabase mysql-binlog.000111 > output.txt

That command says pull all of the transactions from the mysql-binlog.000111 file for the 'mydatabase' database starting from 7-31-2009 at 5am up until 7-31-2009 at 10:05am and output them to the output.txt file.

This file can simply be input directly into the database using the following command:

mysql < output.txt

Some notes here. First, there is a 'use ' statement in the output file. If you are restoring a database to a backup database and not the original you will want to remove the 'use' statement from that file (or all of the use statements if there is more than one). Otherwise, you will run the binlog right into the original database. One easy way to do this is run grep -v and remove any line that starts with use, outputting that to a new file.

grep -v ^use output.txt >newout.txt

Finally, you would modify your mysql statement to use the backup database name and the file without the 'use' statements.

mysql backupdatabase < newout.txt

Assuming no errors, this will run all of your queries into the database.

Final notes: This binlog replay assumes that you have restored the original database up until the 5am time from some backup file you had. The binlog will then recreate all of the transactions from the time the backup ends until 10:05am. If you try to replay from the binlog and there is already data in the database for those transactions, you could potentially run into duplicate key errors, etc.

19th April
2009
written by Chris

Here is a handy little snippet for deleting all the tables in a database. Replace 'uname' and 'dbname' as required.

mysql -u uname dbname -e "show tables" | grep -v Tables_in | grep -v "+"  | gawk '{print "drop table " $1 ";"}' | mysql -u uname dbname
Tags: ,
19th April
2009
written by Chris

If your .FRM file gets hosed up, you'll need to repair it or your database(s) will be worthless. You'll still need to make sure you make regular backups of your databases so you can use them to rebuild the .FRM file.

1. Get last good backup of database (assumes the backup is an .sql formatted single file).

2. Grep out the schema from the .sql file (grep -v 'INSERT INTO' [.sql file] > somefile.sql)

3. Locate the schema for the broken table.

4. Go into a mysql shell and create a new table with a different name and same schema as the broken table (located in step 3) in the affected database.

5. Stop mysqld.

6. Copy the [newtable].frm file in /var/lib/mysql/[database] to the [brokentable].frm, overwriting [brokentable].frm

7. Remove the [newtable].MYI/.MYD files from /var/lib/mysql/[database].

8. Start mysqld.

9. Run on a count on the newly fixed table and make sure there are records.

10. Run a mysqldump of the database and make sure it completes successfully.

11. Clean up any unneeded files created in the process of the fix.

Tags: ,