Upload
saeed-meethal
View
17
Download
0
Embed Size (px)
Citation preview
23
3. Managing MySQL users and privileges
3.1 MySQL security model
Each MySQL server installation has a seed database “mysql”, which stores the MySQLdatabases information on the local machine, the users and their privilegesinformations. The access to this database has to be secured, since if someone is ableto login without a password as “root” user to this database, he can overwrite userprivileges or create a rogue user.
The tables in the “mysql” database are the following:
# mysql -u root mysql
Reading table information for completion of table and column namesYou can turn off this feature to get a quicker startup with -A
Welcome to the MySQL monitor. Commands end with ; or \g.Your MySQL connection id is 3 to server version: 4.0.22-Yahoo-SMP-log
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql> show tables;
+------------------------+| Tables_in_mysql |+------------------------+| columns_priv || db || func || host || tables_priv || user |+------------------------+
6 rows in set (0.00 sec)
columns_priv table stores all the column privileges granted to users
MySQL Administration How-To
24
mysql> desc columns_priv;
+---------------------+--------------------------------------------------------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+---------------------+--------------------------------------------------------------+------+-----+---------+-------+| Host | char(60) binary | | PRI | | || Db | char(64) binary | | PRI | | || User | char(16) binary | | PRI | | || Table_name | char(64) binary | | PRI | | || Column_name | char(64) binary | | PRI | | || Timestamp | timestamp(14) |YES | | NULL | | Column_priv | set('Select','Insert','Update','References') | | | | |+----------------------+---------------------------------------------------------------+----+-----+---------+-------+
7 rows in set (0.00 sec)
db table stores all user privileges for any MySQL database he has acces to:
mysql> desc db;
+---------------------------------+------------------------+------+-------+-----------+---------+| Field | Type | Null | Key | Default | Extra |+---------------------------------+------------------------+-------+------+-----------+---------+| Host | char(60) binary | | PRI | | || Db | char(64) binary | | PRI | | || User | char(16) binary | | PRI | | || Select_priv | enum('N','Y') | | | N | || Insert_priv | enum('N','Y') | | | N | || Update_priv | enum('N','Y') | | | N | || Delete_priv | enum('N','Y') | | | N | || Create_priv | enum('N','Y') | | | N | || Drop_priv | enum('N','Y') | | | N | || Grant_priv | enum('N','Y') | | | N | || References_priv | enum('N','Y') | | | N | || Index_priv | enum('N','Y') | | | N | || Alter_priv | enum('N','Y') | | | N | || Create_tmp_table_priv | enum('N','Y') | | | N | || Lock_tables_priv | enum('N','Y') | | | N | |+---------------------------------+------------------------+---------+------+----------+--------+
15 rows in set (0.00 sec)
mysql> select * from db where user = 'ritzy'\G
Host: a-int.corp.yahoo.com Db: TESTDB
MySQL Administration How-To
25
User: ritzy Select_priv: Y Insert_priv: Y Update_priv: Y Delete_priv: Y Create_priv: Y Drop_priv: Y Grant_priv: N References_priv: Y Index_priv: Y Alter_priv: YCreate_tmp_table_priv: Y Lock_tables_priv: Y
*************************** 2. row *************************** Host: % Db: TESTDB User: ritzy Select_priv: Y Insert_priv: Y Update_priv: Y Delete_priv: Y Create_priv: Y Drop_priv: Y Grant_priv: N References_priv: Y Index_priv: Y Alter_priv: YCreate_tmp_table_priv: Y Lock_tables_priv: Y
2 rows in set (0.02 sec)
host table stores all host privileges for any MySQL database this host has acces to:
mysql> desc host;
+-----------------------+-----------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+-----------------------+-----------------+------+-----+---------+-------+| Host | char(60) binary | | PRI | | || Db | char(64) binary | | PRI | | || Select_priv | enum('N','Y') | | | N | || Insert_priv | enum('N','Y') | | | N | || Update_priv | enum('N','Y') | | | N | || Delete_priv | enum('N','Y') | | | N | || Create_priv | enum('N','Y') | | | N | |
MySQL Administration How-To
26
| Drop_priv | enum('N','Y') | | | N | || Grant_priv | enum('N','Y') | | | N | || References_priv | enum('N','Y') | | | N | || Index_priv | enum('N','Y') | | | N | || Alter_priv | enum('N','Y') | | | N | || Create_tmp_table_priv | enum('N','Y') | | | N | || Lock_tables_priv | enum('N','Y') | | | N | |+-----------------------+-----------------+------+-----+---------+-------+
user table stores all user privileges for any MySQL database he has acces to:
mysql> desc user ;
+-----------------------+-----------------------------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+-----------------------+-----------------------------------+------+-----+---------+-------+| Host | varchar(60) binary | | PRI | | || User | varchar(16) binary | | PRI | | || Password | varchar(16) binary | | | | || Select_priv | enum('N','Y') | | | N | || Insert_priv | enum('N','Y') | | | N | || Update_priv | enum('N','Y') | | | N | || Delete_priv | enum('N','Y') | | | N | || Create_priv | enum('N','Y') | | | N | || Drop_priv | enum('N','Y') | | | N | || Reload_priv | enum('N','Y') | | | N | || Shutdown_priv | enum('N','Y') | | | N | || Process_priv | enum('N','Y') | | | N | || File_priv | enum('N','Y') | | | N | || Grant_priv | enum('N','Y') | | | N | || References_priv | enum('N','Y') | | | N | || Index_priv | enum('N','Y') | | | N | || Alter_priv | enum('N','Y') | | | N | || Show_db_priv | enum('N','Y') | | | N | || Super_priv | enum('N','Y') | | | N | || Create_tmp_table_priv | enum('N','Y') | | | N | || Lock_tables_priv | enum('N','Y') | | | N | || Execute_priv | enum('N','Y') | | | N | || Repl_slave_priv | enum('N','Y') | | | N | || Repl_client_priv | enum('N','Y') | | | N | || ssl_type | enum('','ANY','X509','SPECIFIED') | | | | || ssl_cipher | blob | | | | || x509_issuer | blob | | | | || x509_subject | blob | | | | || max_questions | int(11) unsigned | | | 0 | || max_updates | int(11) unsigned | | | 0 | || max_connections | int(11) unsigned | | | 0 | |+-----------------------+-----------------------------------+------+-----+---------+-------+
MySQL Administration How-To
27
3.2 Creating MySQL users and granting privileges
To create a new user and also grant privileges in the same time, we can use theGRANT command:
mysql> grant shutdown on *.* to test@localhost identified by 'testpass';Query OK, 0 rows affected (0.02 sec)
mysql> select * from user where user = 'test'\G
Host: localhost User: test Password: 7dcda0d57290b453 Select_priv: N Insert_priv: N Update_priv: N Delete_priv: N Create_priv: N Drop_priv: N Reload_priv: N Shutdown_priv: Y Process_priv: N File_priv: N Grant_priv: N References_priv: N Index_priv: N Alter_priv: N Show_db_priv: N Super_priv: NCreate_tmp_table_priv: N Lock_tables_priv: N Execute_priv: N Repl_slave_priv: N Repl_client_priv: N ssl_type: ssl_cipher: x509_issuer: x509_subject: max_questions: 0 max_updates: 0 max_connections: 01 row in set (0.00 sec)
mysql> grant drop on TESTDB.* to test@localhost;Query OK, 0 rows affected (0.01 sec)
MySQL Administration How-To
28
mysql> select * from db where user = 'test'\G
Host: localhost Db: TESTDB User: test Select_priv: N Insert_priv: N Update_priv: N Delete_priv: N Create_priv: N Drop_priv: Y Grant_priv: N References_priv: N Index_priv: N Alter_priv: NCreate_tmp_table_priv: N Lock_tables_priv: N1 row in set (0.00 sec)
HOST, USER, and DB table are very closely connected - if an authorized USER attempts an SQL request from an unauthorized HOST, it is denied. If a request froman authorized HOST is not an authorized USER, it is denied. If a globally authorizedUSER does not have rights to a certain DB, it is denied.
MySQL Administration How-To
29
For the GRANT and REVOKE statements, priv_type can be specified as any of thefollowing:
Privilege Meaning
ALL [PRIVILEGES] Sets all simple privileges except GRANT OPTION
ALTER Allows use of ALTER TABLE
CREATE Allows use of CREATE TABLE
CREATETEMPORARYTABLES
Allows use of CREATE TEMPORARY TABLE
CREATE VIEW Allows use of CREATE VIEW
DELETE Allows use of DELETE
DROP Allows use of DROP TABLE
EXECUTE Allows the user to run stored procedures (MySQL 5.0)
FILE Allows use of SELECT ... INTO OUTFILE and LOAD DATA INFILE
INDEX Allows use of CREATE INDEX and DROP INDEX
INSERT Allows use of INSERT
LOCK TABLES Allows use of LOCK TABLES on tables for which you have the SELECTprivilege
PROCESS Allows use of SHOW FULL PROCESSLIST
REFERENCES Not yet implemented
RELOAD Allows use of FLUSH
REPLICATIONCLIENT
Allows the user to ask where the slave or master servers are
REPLICATIONSLAVE
Needed for replication slaves (to read binary log events from themaster)
SELECT Allows use of SELECT
SHOWDATABASES
SHOW DATABASES shows all databases
SHOW VIEW Allows use of SHOW CREATE VIEW
SHUTDOWN Allows use of mysqladmin shutdown
SUPER Allows use of CHANGE MASTER, KILL, PURGE MASTER LOGS, and SETGLOBAL statements, the mysqladmin debug command; allows you toconnect (once) even if max_connections is reached
UPDATE Allows use of UPDATE
USAGE Synonym for ``no privileges''
GRANT OPTION Allows privileges to be granted
MySQL Administration How-To
30
Not all privileges can be granted with the “GRANT” command. Some of the privilegeshas to be granted by directly updating the “user” table. For example:
mysql> grant delete_priv on TESTDB.* to test@localhost;
ERROR 1064: You have an error in your SQL syntax. Check the manual thatcorresponds to your MySQL server version for the right syntax to use near'delete_priv on TESTDB.* to test@localhost' at line 1
mysql> update db set Delete_priv = 'Y' where user = 'test' and db = 'TESTDB';
Query OK, 1 row affected (0.00 sec)Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from db where user = 'test'\G
Host: localhost Db: TESTDB User: test Select_priv: N Insert_priv: N Update_priv: N Delete_priv: Y Create_priv: N Drop_priv: Y Grant_priv: N References_priv: N Index_priv: N Alter_priv: NCreate_tmp_table_priv: N Lock_tables_priv: N1 row in set (0.00 sec)
When mysqld starts, all grant table contents are read into memory and becomeeffective for access control at that point.
When the server reloads the grant tables, privileges for existing client connections areaffected as follows:
• Table and column privilege changes take effect with the client's next request. • Database privilege changes take effect at the next USE db_name statement. • Changes to global privileges and passwords take effect the next time the client
connects.
If you modify the grant tables using GRANT, REVOKE, or SET PASSWORD, the servernotices these changes and reloads the grant tables into memory again immediately.
If you modify the grant tables directly using statements such as INSERT, UPDATE, orDELETE, your changes have no effect on privilege checking until you either restartthe server or tell it to reload the tables. To reload the grant tables manually, issue a
MySQL Administration How-To
32
FLUSH PRIVILEGES statement or execute a mysqladmin flush-privileges ormysqladmin reload command.
The privilege grants doesn't take effect until MySQL server reads the grant tablesfrom the “mysql” database. You can force this by executing the following commands:
mysql> show grants for 'test'@'localhost';
+---------------------------------------------------------------------------------------+| Grants for test@localhost |+---------------------------------------------------------------------------------------+| GRANT SHUTDOWN ON *.* TO 'test'@'localhost' IDENTIFIED BY PASSWORD'7dcda0d57290b453' || GRANT DROP ON `TESTDB`.* TO 'test'@'localhost' |+---------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)
mysql> flush privileges;Query OK, 0 rows affected (0.00 sec)
mysql> show grants for 'test'@'localhost';
+---------------------------------------------------------------------------------------+| Grants for test@localhost |+---------------------------------------------------------------------------------------+| GRANT SHUTDOWN ON *.* TO 'test'@'localhost' IDENTIFIED BY PASSWORD '7dcda0d57290b453' || GRANT DELETE, DROP ON `TESTDB`.* TO 'test'@'localhost' |+---------------------------------------------------------------------------------------+2 rows in set (0.00 sec)
# mysqladmin -u root flush-privileges
# mysqladmin -u root reload
To revoke privileges from a user one can use the REVOKE command:
mysql> revoke drop on TESTDB.* from 'test'@'localhost';Query OK, 0 rows affected (0.01 sec)
MySQL Administration How-To
33
mysql> select * from db where user = 'test'\G
Host: localhost Db: TESTDB User: test Select_priv: N Insert_priv: N Update_priv: N Delete_priv: Y Create_priv: N Drop_priv: N Grant_priv: N References_priv: N Index_priv: N Alter_priv: NCreate_tmp_table_priv: N Lock_tables_priv: N1 row in set (0.01 sec)
To change user password use:
For older versions of MySQL the syntax of updating the password was:
mysql> update user set password = 'testpass1' where user = 'test';Query OK, 1 row affected (0.01 sec)Rows matched: 1 Changed: 1 Warnings: 0
mysql> select user, host, password from user where user = 'test';
+------+-----------+-----------+| user | host | password |+------+-----------+-----------+| test | localhost | testpass1 |+------+-----------+-----------+
1 row in set (0.00 sec)
On versions 4.0.x you can use only the statement below, which is equivalent on theabove statement:
mysql> update user set password = PASSWORD('testpass1') where user ='test';Query OK, 1 row affected (0.00 sec)Rows matched: 1 Changed: 1 Warnings: 0
MySQL Administration How-To
34
mysql> flush privileges;Query OK, 0 rows affected (0.00 sec)
mysql> select user, host, password from user where user = 'test';
+------+-------------+-------------------------------+| user | host | password |+------+--------------+------------------------------+| test | localhost | 306c24f613692c49 |+------+--------------+------------------------------+
1 row in set (0.00 sec)
mysql> set password for test = password('testpass2');Query OK, 0 rows affected (0.02 sec)
mysql> select user, host, password from user where user = 'test';
+------+--------------+-------------------------------+| user | host | password |+------+--------------+-------------------------------+| test | localhost | 306c2763136928b6 |+------+--------------+-------------------------------+
1 row in set (0.00 sec)
To grant user access to remote users you have to specify the remote host:
mysql> grant shutdown on *.* to trifon@'wine.corp.yahoo.com';Query OK, 0 rows affected (0.01 sec)
mysql> grant shutdown on *.* to trifon@'%.corp.yahoo.com';Query OK, 0 rows affected (0.00 sec)
mysql> grant shutdown on *.* to trifon@'216.145.53.%';Query OK, 0 rows affected (0.00 sec)
You can also group privileges together:
mysql> grant drop, select, insert on TESTDB.* to trifon@'216.145.53.%';Query OK, 0 rows affected (0.00 sec)
MySQL Administration How-To
35
To remove user from MySQL:
mysql> delete from user where user='username';
mysql> FLUSH PRIVILEGES;
More examples of adding a new user with different level of privileges:
dummy: A user who can connect without a password, but only from the local host.
mysql> GRANT USAGE ON *.* TO dummy@localhost;
myUser: A full superuser who can connect to the server from anywhere, but whomust use a password 'pass' to do so. GRANT statements should be for bothmyUser@localhost and myUser@"%". to prevent the anonymous user entry forlocalhost take precedence.
mysql> GRANT ALL PRIVILEGES ON *.* TO myUser@localhost IDENTIFIED BY 'pass' WITH GRANT OPTION;
mysql> GRANT ALL PRIVILEGES ON *.* TO myUser@"%" IDENTIFIED BY 'some_pass' WITH GRANT OPTION;
“%" - is a wildcard in MySQL. If you are defining your DB table and in the 'host' field enter '%', that means that any host can access that database (Of course, that host must also have a valid db user).
admin: A user who can connect from localhost without a password and who isgranted the RELOAD and PROCESS administrative privileges. No database-relatedprivileges are granted.
mysql> GRANT RELOAD,PROCESS ON *.* TO admin@localhost;
Add a user that has full rights to his database only but cannot see other database:
mysql> GRANT USAGE ON *.* TO 'user'@'host' GRANT Select, Insert, Update, Delete, Create, Drop ON `database`.* TO 'user'@'host' FLUSH PRIVELEGS;
MySQL Administration How-To
36
The FILE privelege and WITH GRANT OPTION may not be the best way to include, itis only in case of creating another superuser with full set of privileges or givingprivileges to load data using mysql command INLOAD DATA.
Summary of the ways to change the user passwords in MySQL:
- from Unix:
# mysql -u username -h hostname -p password
mysql> SET PASSWORD FOR username@localhost=PASSWORD('new_password');
- directly manipulate the privilege tables:
# mysql -u username -h host -u username -p
mysql> UPDATE user SET Password=PASSWORD('new_password') WHERE user='root';
mysql> FLUSH PRIVILEGES;
- using the mysqladmin command:
# mysqladmin -u username password new_password
3.3 Useful MySQL build-in functions
mysql> select user();
+----------------+| user() |+----------------+| root@localhost |+----------------+
1 row in set (0.00 sec)
MySQL Administration How-To
37
mysql> select database();
+------------+| database() |+------------+| mysql |+------------+
1 row in set (0.00 sec)
mysql> select curtime();
+-----------+| curtime() |+-----------+| 15:08:13 |+-----------+1 row in set (0.02 sec)
mysql> select curdate();
+------------+| curdate() |+------------+| 2004-09-27 |+------------+
1 row in set (0.00 sec)
4. Backups of MySQL tables and databases
4.1 Manual backup by using the OS utilities (cp, tar)
MySQL tables are stored as files, so to do a backup we have to make a copies of thetable data files. To get a consistent backup, do a LOCK TABLES on the relevanttables, followed by FLUSH TABLES for the tables.
The LOCK TABLES is placing a read lock on the tables. This allows other clients tocontinue to query the tables while you are making a copy of the files in the databasedirectory.
The FLUSH TABLES statement is needed to ensure that the all active index pagesare written to disk before you start the backup.
MySQL Administration How-To
38
mysql> show tables;
+----------------------------+
| Tables_in_TESTDB |
+----------------------------+
| test1 |
+----------------------------+
1 row in set (0.00 sec)
The following command places a read lock on the “test1” table:
mysql> lock tables test1 read;
Query OK, 0 rows affected (0.07 sec)
The following command will flush all the table data from the memory cache to thedisk:
mysql> flush tables;
Query OK, 0 rows affected (0.01 sec)
From another terminal session:
# ls -la /home/y/var/mysql/data/TESTDB
-rw-rw---- 1 mysql users 80 Sep 21 11:40 test1.MYD
-rw-rw---- 1 mysql users 1024 Sep 21 11:57 test1.MYI
-rw-rw---- 1 mysql users 8614 Sep 21 11:23 test1.frm
# tar cvf TESTDB-backup.tar ./test1
*
./test1.MYD
./test1.MYI
./test1.frm
MySQL Administration How-To
39
# ls -la /home/y/var/mysql/data/TESTDB
-rw-r--r-- 1 root users 20480 Sep 27 17:28 TESTDB-backup.tar
-rw-rw---- 1 mysql users 80 Sep 21 11:40 test1.MYD
-rw-rw---- 1 mysql users 1024 Sep 21 11:57 test1.MYI
-rw-rw---- 1 mysql users 8614 Sep 21 11:23 test1.frm
mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)
You can also use the following command to btain a read lock on the tables and flushthem to the disk:
mysql> flush tables with read lock;
Query OK, 0 rows affected (0.00 sec)
Then again we make a copy of the MySQL data files and unlock the tables:
mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)
4.2 SQL level backup
If you want to make an SQL level backup of a table, you can use SELECT INTO ...OUTFILE to dump the table. For SELECT INTO ... OUTFILE, the output file cannotalready exist.
The restore method is with LOAD DATA INFILE 'file_name' REPLACE ... To avoidduplicate records, the table must have a primary key or a unique index. TheREPLACE keyword causes old records to be replaced with new ones when a newrecord duplicates an old record on a unique key value.
In this example, we will do SQL level backup of “test1” table:
mysql> select * into outfile '/tmp/TESTDB-backup.sql' from test1;
Query OK, 4 rows affected (0.00 sec)
MySQL Administration How-To
40
# cat /tmp/TESTDB-backup.sql
100 \N \N
101 \N \N
102 \N \N
103 \N \N
To restore the table we can use the LOAD DATA INFILE command:
mysql> create table test2 as select * from test1 where 1 = 2;
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> load data infile '/tmp/TESTDB-backup.sql' into table test2;
Query OK, 4 rows affected (0.02 sec)
Records: 4 Deleted: 0 Skipped: 0 Warnings: 0
mysql> select * from test2;
+------+------------+-------------------+
| id | salary | department |
+------+------------+-------------------+
| 100 | NULL | NULL |
| 101 | NULL | NULL |
| 102 | NULL | NULL |
| 103 | NULL | NULL |
+------+------------+-------------------+
4 rows in set (0.00 sec)
You can also do a selecting backups by using the WHERE predicate in the SELECTINTO OUTFILE command:
mysql> select * into outfile '/tmp/TESTDB-backup.sql' from test1 where id <103;
MySQL Administration How-To
41
For a SQL level backup of a table you can also use the BACKUP TABLE command.The command to restore the backup taken with the BACKUP TABLE command isRESTORE TABLE. The syntax of both commands is provided below:
mysql> BACKUP TABLE tbl_name[,tbl_name...] TO '/path/to/backup/directory';
Copies to the backup directory the minimum number of table files needed to restorethe table, after flushing any buffered changes to disk.
mysql> RESTORE TABLE tbl_name[,tbl_name...] FROM '/path/to/backup/directory';
Restores the table(s) from the backup that was made with BACKUP TABLE. Existingtables will not be overwritten; if you try to restore over an existing table, you will getan error. Restoring will take longer than backing up due to the need to rebuild theindex. The more keys you have, the longer it will take. Just as BACKUP TABLE,RESTORE TABLE currently works only for MyISAM tables !!
mysql> backup table test2 to '/home/tmp/';
+--------------+--------+----------+----------+| Table | Op | Msg_type | Msg_text |+--------------+--------+----------+----------+| TESTDB.test2 | backup | status | OK |+--------------+--------+----------+----------+1 row in set (0.01 sec)
# ls -la | grep test2-rw-rw---- 1 mysql wheel 80 Sep 27 17:55 test2.MYD-rw-rw---- 1 mysql wheel 8614 Sep 27 17:55 test2.frm
4.3 MySQL backup using mysqldump and mysqlhotcopy commands
Another way to back up a database is to use the mysqldump program or themysqlhotcopy scripts. mysqlhotcopy command is a PERL wrapper to the MySQLcommands (you can review the source code freely), so to make this command to workyou have to make sure you have the PERL package and the following PERL modulesinstalled:
MySQL Administration How-To
42
ypan/perl-DBD-mysql
ypan/perl-DBI
To check this run these commands:
$ yinst list mysql_client
$ yinst list mysql_server
$ yinst list ypan/perl-DBD-mysql
$ yinst list perl
$ yinst list ypan/perl-DBI
To do a full backup of your database:
# mysqldump -u user_name -p --tab=/path/to/some/dir --opt db_name
or
# mysqlhotcopy -u user_name -p db_name /path/to/some/dir
You can also simply copy all table files (`*.frm', `*.MYD', and `*.MYI' files) as long asthe server isn't updating anything. The mysqlhotcopy script uses this method. (Butnote that these methods will not work if your database contains InnoDB tables.InnoDB does not store table contents in database directories, and mysqlhotcopy worksonly for MyISAM and ISAM tables.)
The following example backups the TESTDB MySQL database:
# mysqldump --add-locks --extended-insert --flush-logs --lock-tables --quickTESTDB > /tmp/TESTDB-backup.sql
# ls -la | grep TESTDB
-rw-rw-rw- 1 mysql wheel 817 Sep 27 17:44 TESTDB-backup.sql
The backup file contains the SQL statements required to restore the tables:
# cat /tmp/TESTDB-backup.sql
MySQL Administration How-To
43
-- MySQL dump 9.11
--
-- Host: localhost Database: TESTDB
-- ------------------------------------------------------
-- Server version 4.0.22-Yahoo-SMP-log
--
-- Table structure for table `test1`
--
CREATE TABLE test1 (
id int(11) default NULL,
salary int(11) default NULL,
department text
) TYPE=MyISAM;
--
-- Dumping data for table `test1`
--
LOCK TABLES test1 WRITE;
INSERT INTO test1 VALUES (100,NULL,NULL),(101,NULL,NULL),(102,NULL,NULL),(103,NULL,NULL);
UNLOCK TABLES;
--
-- Table structure for table `test2`
--
CREATE TABLE test2 (
id int(11) default NULL,
salary int(11) default NULL,
department text
) TYPE=MyISAM;
MySQL Administration How-To
44
--
-- Dumping data for table `test2`
--
LOCK TABLES test2 WRITE;
INSERT INTO test2 VALUES (100,NULL,NULL),(101,NULL,NULL),(102,NULL,NULL),(103,NULL,NULL);
UNLOCK TABLES;
The backup command for TESTDB using “mysqlhotcopy” would looks like:
# mysqlhotcopy -u root TESTDB > /tmp/TESTDB-hotcopy.sql
4.4 Backing Up and Recovering an InnoDB Database
The key to safe database management is taking regular backups. InnoDB Hot Backup is an online backup tool you can use to backup your InnoDBdatabase while it is running. InnoDB Hot Backup does not require you to shut downyour database and it does not set any locks or disturb your normal databaseprocessing.
InnoDB Hot Backup is a non-free (commercial) additional tool whose annual licensefee is 390 euros per computer where the MySQL server is run. See the InnoDB HotBackup home page for detailed information and screenshots. If you are able to shutdown your MySQL server, you can make a ``binary'' backup that consists of all filesused by InnoDB to manage its tables.
Use the following procedure:
1. Shut down your MySQL server and make sure that it shuts down without errors.2. Copy all your data files into a safe place. 3. Copy all your InnoDB log files to a safe place. 4. Copy your `my.cnf' configuration file or files to a safe place. 5. Copy all the `.frm' files for your InnoDB tables to a safe place.
Replication works with InnoDB type tables, so you can use MySQL replicationcapabilities to keep a copy of your database at database sites requiring highavailability.
In addition to taking binary backups as just described, you should also regularly takedumps of your tables with mysqldump. The reason for this is that a binary file mightbe corrupted without you noticing it. Dumped tables are stored into text files that arehuman-readable, so spotting table corruption becomes easier.
MySQL Administration How-To
45
Also, since the format is simpler, the chance for serious data corruption is smaller.mysqldump also has a --single-transaction option that you can use to take a consistentsnapshot without locking out other clients.
To be able to recover your InnoDB database to the present from the binary backupdescribed above, you have to run your MySQL server with binary logging turned on.
Then you can apply the binary log to the backup database to achieve point-in-timerecovery:
# mysqlbinlog yourhostname-bin.123 | mysql
To recover from a crash of your MySQL server process, the only thing you have to dois to restart it. InnoDB will automatically check the logs and perform a roll-forward ofthe database to the present. InnoDB will automatically roll back uncommittedtransactions that were present at the time of the crash.
During recovery, mysqld will display output something like this:
InnoDB: Database was not shut down normally.InnoDB: Starting recovery from log files...InnoDB: Starting log scan based on checkpoint atInnoDB: log sequence number 0 13674004InnoDB: Doing recovery: scanned up to log sequence number 0 13739520InnoDB: Doing recovery: scanned up to log sequence number 0 13805056InnoDB: Doing recovery: scanned up to log sequence number 0 13870592InnoDB: Doing recovery: scanned up to log sequence number 0 13936128...InnoDB: Doing recovery: scanned up to log sequence number 0 20555264InnoDB: Doing recovery: scanned up to log sequence number 0 20620800InnoDB: Doing recovery: scanned up to log sequence number 0 20664692InnoDB: 1 uncommitted transaction(s) which must be rolled backInnoDB: Starting rollback of uncommitted transactionsInnoDB: Rolling back trx no 16745InnoDB: Rolling back of trx no 16745 completedInnoDB: Rollback of uncommitted transactions completedInnoDB: Starting an apply batch of log records to the database...InnoDB: Apply batch completedInnoDB: Startedmysqld: ready for connections
If your database gets corrupted or your disk fails, you have to do the recovery from abackup. In the case of corruption, you should first find a backup that is not corrupted.After restoring the base backup, do the recovery from the binary log files.
In some cases of database corruption it is enough just to dump, drop, and re-createone or a few corrupt tables. You can use the CHECK TABLE SQL statement to checkwhether a table is corrupt, although CHECK TABLE naturally cannot detect everypossible kind of corruption.
MySQL Administration How-To
46
You can use innodb_tablespace_monitor to check the integrity of the file spacemanagement inside the tablespace files. In some cases, apparent database pagecorruption is actually due to the operating system corrupting its own file cache, andthe data on disk may be okay. It is best first to try restarting your computer. It mayeliminate errors that appeared to be database page corruption.
5. MySQL Master – Slave Replication
Set up an account on the master server that the slave server can use to connect. Thisaccount must be given the REPLICATION SLAVE privilege. If the account is used onlyfor replication (which is recommended), you don't need to grant any additionalprivileges. Suppose that your domain is mydomain.com and you want to create anaccount with a username of repl such that slave servers can use the account toaccess the master server from any host in your domain using a password ofslavepass. To create the account, this use GRANT statement:
mysql> grant replication slave on *.* TO 'repl'@'p-int.corp.yahoo.com'IDENTIFIED BY 'repl';Query OK, 0 rows affected (0.00 sec)
mysql> select * from user where user = 'repl'\G
Host: p-int.corp.yahoo.com User: repl Password: 5ec3db8f603fcb03 Select_priv: N Insert_priv: N Update_priv: N Delete_priv: N Create_priv: N Drop_priv: N Reload_priv: N Shutdown_priv: N Process_priv: N File_priv: N Grant_priv: N References_priv: N Index_priv: N Alter_priv: N Show_db_priv: N Super_priv: NCreate_tmp_table_priv: N Lock_tables_priv: N Execute_priv: N Repl_slave_priv: Y Repl_client_priv: N
MySQL Administration How-To
47
Shutdown the master and enable the replication by setting up these parameters in /etc/my.cnf file:
## Uncomment these if this server will be a master.
log-binserver-id = 1
The log-bin parameter enables MySQL to dump all commited transactions into abinary logs, which are then pulled from the slaves and applied to keep the slaves insync with the master MySQL database.
We also assign an unique ID for the master. We will have number the slavesaccordingly as server-id=2 for the first slave, server-id=2 for the second slave, etc.
Once we change the values in the /etc/my.cnf we have to restart the MySQL server.The binary logs then will be generated in the MySQL data directory - /home/y/var/mysql/data:
# ls -la /home/y/var/mysql/data | grep bin
-rw-rw---- 1 mysql users 929 Sep 16 11:16 a-int-bin.001-rw-rw---- 1 mysql users 311 Sep 16 15:14 a-int-bin.002-rw-rw---- 1 mysql users 11582 Sep 21 11:56 a-int-bin.003-rw-rw---- 1 mysql users 79 Sep 21 11:58 a-int-bin.004-rw-rw---- 1 mysql users 79 Sep 21 12:02 a-int-bin.005-rw-rw---- 1 mysql users 79 Sep 21 17:18 a-int-bin.006-rw-rw---- 1 mysql users 79 Sep 21 17:33 a-int-bin.007-rw-rw---- 1 mysql users 1140 Sep 27 16:04 a-int-bin.008-rw-rw---- 1 mysql users 128 Sep 22 11:59 a-int-bin.index
The binary files are generated and numbered automatically and the list of all binarylog files is kept in the *bin.index file:
#cat /home/y/var/mysql/data/a-int-bin.index
./a-int-bin.001
./a-int-bin.002
./a-int-bin.003
./a-int-bin.004
./a-int-bin.005
./a-int-bin.006
./a-int-bin.007
./a-int-bin.008
MySQL Administration How-To
48
DBA can purge all of the replication binary logs except the currently used:
1. On each slave server, use SHOW SLAVE STATUS to check which log it is reading. 2. Obtain a listing of the logs on the master server with SHOW MASTER LOGS. 3. Determine the earliest log among all the slaves. This is the target log. If all theslaves are up to date, this will be the last log on the list. 4. Make a backup of all the logs you are about to delete. (The step is optional, but agood idea.) 5. Purge all logs up to but not including the target log.
Once you identify what is the latest binary log each slave is reading from, you canpurge the binary logs on the master:
PURGE MASTER LOGS TO 'a-int-bin.007';
Once you do that, the the index file for the binary logs will be updated:
# cat /home/y/var/mysql/data/a-int-bin.index
./a-int-bin.008
On the master database dump the database so we can copy it to the slave:
# mysqldump -u root -p --add-locks --extended-insert --flush-logs --lock-tables--quick --databases TESTDB > /var/tmp/TESTDB-backup.sql
Check which is the latest binary log generated after the “mysqldump” command. Thiswill be the starting point for the slave replication:
# ls -la /home/y/var/mysql/data | grep bin
-rw-rw---- 1 mysql users 929 Sep 16 11:16 a-int-bin.001-rw-rw---- 1 mysql users 311 Sep 16 15:14 a-int-bin.002-rw-rw---- 1 mysql users 11582 Sep 21 11:56 a-int-bin.003-rw-rw---- 1 mysql users 79 Sep 21 11:58 a-int-bin.004-rw-rw---- 1 mysql users 79 Sep 21 12:02 a-int-bin.005-rw-rw---- 1 mysql users 79 Sep 21 17:18 a-int-bin.006-rw-rw---- 1 mysql users 79 Sep 21 17:33 a-int-bin.007-rw-rw---- 1 mysql users 1140 Sep 27 16:04 a-int-bin.008-rw-rw---- 1 mysql users 4 Sep 27 16:31 a-int-bin.009-rw-rw---- 1 mysql users 128 Sep 22 11:59 a-int-bin.index
MySQL Administration How-To
49
In this case this is the a-int-bin.009 file.
Copy the TESTDB database dump on the slave machine:
# scp awacs-backup.sql [email protected]:/var/tmp
On the slave machine we have to create the TESTDB database first, so we can restorethe initial backup from the master machine:
# mysqladmin create TESTDB
- edit the /etc/my.cnf
## Uncomment these if this server will be a master.
log-binserver-id = 2
## Replication
master-host = a-int.corp.yahoo.commaster-user = replmaster-password = replmaster-port = 3306
Restart the MySQL slave server:
# yinst stop mysql_serveryinst: mysql_server-4.0.22_1: stopping ...
# yinst start mysql_serveryinst: mysql_server-4.0.22_1: starting ...
Now we have to fix the replication starting point. Since we already changed the /etc/my.cnf file and added the master replication details, the replication is started:
mysql> stop slave;Query OK, 0 rows affected (0.00 sec)
mysql> change master to master_log_file='a-int-bin.009', master_log_pos=4;Query OK, 0 rows affected (0.00 sec)
MySQL Administration How-To
50
Now we can start the replication and check it's status:
mysql> start slave;Query OK, 0 rows affected (0.00 sec)
mysql> show slave status;
In the output from the above command if the master-slave replication is running, weshould see the following parameters as:
Slave_IO_Running: Yes Slave_SQL_Running: Yes
These parameters show the status of the two threads involved in the MySQLreplication. The Slave_IO thread is pulling the changes from the master binary logsand updates the binary logs on the slave machine. The Slave_SQL thread reads thecommitted transactions from the binary log and applies them on the slave server.
The entries in the binary logs looks like:
^@^@^@^A^@^@^@^E^@^@mysql^@grant shutdown on *.* totrifon@'wine.corp.yahoo.com'G\x9aXA^B^A^@^@^@V^@^@^@^O^C^@^@^@^@^@^@^@^@^@^@^@^E^@^@mysql^@grant shutdown on *.* to trifon@'%.corp.yahoo.com'd\x9aXA^B^A^@^@^@R^@^@^@e^C^@^@^@^@^@^@^@^@^@^@^@^E^@^@mysql^@grant shutdown on *.* totrifon@'216.145.53.%'\xa0\x9aXA^B^A^@^@^@c^@^@^@\xb7^C^@^@^@^@^@^@^@^@^@^@^@^E^@^@mysql^@grant drop, select, insert on TESTDB.* totrifon@'216.145.53.%'o\x9cXA^B^A^@^@^@Z^@^@^@^Z^D^@^@^@^@^@^@^@^@^@^@^@^E^@^@mysql^@SET PASSWORD FOR"test"@"localhost"="306c2763136928b6"\xa9\xa4XA^B^A^@^@^@x^@^@^@t^D^@^@^@^@^K^@^@^@^@^@^@^@^E^@^@mysql^@grant replication slaveon *.* TO 'repl'@'p-int.corp.yahoo.com' IDENTIFIED BY 'repl'
MySQL Administration How-To