mysql 数据库备份和恢复
备份策略:
一,数据库可以关的情况下,直接使用系统的cp命令去拷
二,sql语法备份导出 用于辅助备份
三,mysqldump备份数据库 中小型数据库 备出来的是sql语句,速度慢
四,mysqlhotcopy 备份数据库, 只能是myisam引擎 适合中小型myisam引擎数据库
五,存储层的备份,如lvm(logical volumn management)快照
六,使用二进制日志恢复
七,对innodb的备份,innodb引擎的大数据使用mysqldump备份太慢,mysqlhotcopy又不能备份innodb引擎的数据。可以选用mysql自带的企业级备份工具,或者是xtrabackup开源备份工具
八,使用集群方案,例如AB复制 实时备份,适合大型数据库
1,冷备 (不推荐) 数据库可以关闭的情况下的备份
1,关闭数据库
cp -a 源数据文件 目标数据文件
2,打开数据库
热备 数据库不可以关闭的情况下的备份
---------------------------------
2,sql语法备份
backup table 原理是先锁表,然后拷贝数据文件,拷.frm和.MYD,不拷 .MYI索引文件
[root@li ~]# mkdir /tmp/mysqlbackup --建立一个存放备份的目录
[root@li ~]# chown mysql.mysql /tmp/mysqlbackup/ --改权限
mysql> backup table emp to '/tmp/mysqlbackup'; --备份emp表到/tmp/mysqlbackup目录
+------------+--------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+------------+--------+----------+----------+
| source.emp | backup | status | OK |
+------------+--------+----------+----------+
[root@li ~]# ll /tmp/mysqlbackup/ --查看时只有.frm和.MYD文件
-rw-rw---- 1 mysql mysql 8690 08-14 15:32 emp.frm
-rw-rw---- 1 mysql mysql 512 08-14 15:32 emp.MYD
mysql> restore table emp from '/tmp/mysqlbackup'; --误删表后恢复emp表
+------------+---------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+------------+---------+----------+----------+
| source.emp | restore | status | OK |
+------------+---------+----------+----------+
select xxx into outfile ...
本身是一种数据导出的方法,同时可以用来辅助备份,它可以对一个表的其中一列或者某几列做备份(导出)
mysql> select ename,sal into outfile '/tmp/mysqlbackup/emp_ename_sal.txt' from emp; --把emp表的ename,sal两列数据导出(备份)
------------------------------
3,mysqldump工具备份
导出的是sql语句文件
mysqldump客户端可用来转储数据库或搜集数据库进行备份或将数据转移到另一个SQL服务器(不一定是一个MySQL服务器)。转储包含创建表和/或装载表的SQL语句。
如果你在服务器上进行备份,并且表均为MyISAM表,应考虑使用mysqlhotcopy,因为可以更快地进行备份和恢复
提供三种级别的备份,表级,库级和全库级
shell> mysqldump [options] db_name [tables]
shell> mysqldump [options] ---database DB1 [DB2 DB3...]
shell> mysqldump [options] --all--database
全库级:
[root@li ~]# /usr/local/mysql/bin/mysqldump -p123 --all-database > /all.sql
vim /all.sql 可以看到,全是create和insert数据的sql语句
库级:
[root@li ~]# /usr/local/mysql/bin/mysqldump -p123 --database source > /source.sql
[root@li ~]# /usr/local/mysql/bin/mysql -p123 < /source.sql
表级:
[root@li ~]# /usr/local/mysql/bin/mysqldump -p123 source emp> /emp.sql
表级恢复:
[root@li ~]# /usr/local/mysql/bin/mysql -p123 source < /emp.sql
[root@li ~]# /usr/local/mysql/bin/mysql -p123 -e 'source /emp.sql' source
全库恢复演示: --注意mysqldump的恢复速度较慢,所以数据太大需要的时间较长
rm /data/* -rf
rm /data07/* -rf --前面做了innodb的实验,innodb表的数据在这里,所以也要删除掉
恢复步骤:
1,初始化 /usr/local/mysql/bin/mysql_install_db --datadir=/data --user=mysql
2,把数据库先启起来
3,恢复# /usr/local/mysql/bin/mysql < /tmp/mysqlbackup/all.sql
-----------------------------
4,mysqlhotcopy
是一个perl写的程序,原理先锁表,再拷。只适用于myisam存储引擎
mysqlhotcopy是一个Perl脚本,最初由Tim Bunce编写并提供。它使用LOCK TABLES、FLUSH TABLES和cp或scp来快速备份数据库。它是备份数据库或单个表的最快的途径,但它只能运行在数据库目录所在的机器上。mysqlhotcopy只用于备份MyISAM。它运行在Unix和NetWare中。
shell> mysqlhotcopy db_name [/path/to/new_directory]
shell> mysqlhotcopy db_name_1 ... db_name_n /path/to/new_directory
备份给定数据库中的匹配正则表达式的表:
shell> mysqlhotcopy db_name./regex/
加上发音符(‘~’)前缀,表名的正则表达式可以被否定:
shell> mysqlhotcopy db_name./~regex/
perldoc mysqlhotcopy --用此命令去查看帮助文件
备份库
[root@li ~]# /usr/local/mysql/bin/mysqlhotcopy -p 123 --socket=/var/run/mysqld/mysql5.socket source /tmp/mysqlbackup/
恢复: 拷回去就可以了,包括了db.opt文件
备份表
[root@li ~]# /usr/local/mysql/bin/mysqlhotcopy -p 123 --socket=/var/run/mysqld/mysql5.socket source./emp/ /tmp/mysqlbackup/
--注意: -p 和密码中间要空格
他备份的文件,也有库的目录,没有db.opt文件
恢复:
mysql> restore table emp from '/tmp/mysqlbackup/source';
5,使用二进制日志恢复实现数据0丢失
打开二进制日志的方法
vim /usr/local/mysql/etc/my.cnf
log-bin=li--加上这一句,打开二进制日志功能,这里的li代表二进制文件的头部名
# /etc/init.d/mysql5 restart
[root@li ~]# ll /data |grep li
-rw-rw---- 1 mysql mysql 98 08-15 10:02 li.000001
-rw-rw---- 1 mysql mysql 12 08-15 10:02 li.index
登录数据库做一些操作
mysql> show databases;
mysql> use source;
mysql> select * from emp;
--上面三条都不会记录到binlog中,下面的DML和create语句都会被记录到binlog中
mysql> create table bbb (id int ,name varchar(20));
mysql> insert into bbb values (1,'sfsa');
mysql> insert into bbb values (2,'swrqa');
mysql> insert into bbb values (3,'aooop');
mysql> insert into bbb values (4,'wreqoop');
mysql> update bbb set name='haha' where id='3';
mysql> delete from bbb where id='4';
# /usr/local/mysql/bin/mysqlbinlog /data/li.000001 -d source --这里-d source表示只查看关于source库的操作信息
#100815 10:07:00 server id 1 end_log_pos 403 Query thread_id=1 exec_time=0error_code=0
SET TIMESTAMP=1281838020;
insert into bbb values (2,'swrqa');
# at 403
#100815 10:07:08 server id 1 end_log_pos 502 Query thread_id=1 exec_time=0error_code=0
SET TIMESTAMP=1281838028;
insert into bbb values (3,'aooop');
# at 502
#100815 10:07:16 server id 1 end_log_pos 603 Query thread_id=1 exec_time=0error_code=0
# at 502
#100815 10:07:16 server id 1 end_log_pos 603 Query thread_id=1 exec_time=0error_code=0
SET TIMESTAMP=1281838036;
insert into bbb values (4,'wreqoop');
# at 603
按时间来恢复
# /usr/local/mysql/bin/mysqlbinlog --start-datetime='2010-08-15 10:07:00 ' --stop-datetime='2010-08-15 10:07:16' /data/li.000001 | /usr/local/mysql/bin/mysql -p123
按位置来恢复
# /usr/local/mysql/bin/mysqlbinlog --start-position='304' --stop-position='603' /data/li.000001 | /usr/local/mysql/bin/mysql -p123
可以将mysqlbinlog的输出传到mysql客户端以执行包含在二进制日志中的语句。如果你有一个旧的备份,该选项在崩溃恢复时也很有用(参见5.9.1节,“数据库备份”):
shell> mysqlbinlog hostname-bin.000001 | mysql
或:
shell> mysqlbinlog hostname-bin.[0-9]* | mysql
====================================
AB复制前准备
把两台mysql启起来(要求两台数据一致),/etc/hosts里都加上主机名和IP对应,时间同步好,防火墙检查一下
mysql AB复制开始搭建
1,主从数据必须要同步
2,主:要启用二进制日志 /usr/local/mysql/etc/my.cnf log-bin=xxxxx
3,主和从都要设置 server-id值,并且两边要不一样
4,需要建立一个用来复制的用户,并授于相应权限
master -- slave
2.2.2.36 2.2.2.37
第一步;改配置文件
master的
[mysqld]
log-bin=mysql-bin
server-id=2
slave的
[mysqld]
server-id=3
/etc/init.d/mysql5 重启服务
第二步:授权
master上授权,super和replication slave都是复制要用的权限
mysql> grant super,replication slave on *.* to 'li'@'2.2.2.37' identified by '123';
mysql> flush privileges;
slave上最好使用刚才授权的用户是远程登录一下主
[root@slave src]# /usr/local/mysql/bin/mysql -u li -h 2.2.2.36 -p123
ERROR 1130 (HY000): Host '::ffff:2.2.2.36' is not allowed to connect to this MySQL server
--上面是IPV6所造成的影响,所以要去主上面重新授权
master上重新授权,写上IPv6的形式,或者使用%符号代替所以(但不建设这样做,这样就没有对slave做权限控制)
mysql> grant super,replication slave on *.* to 'li'@'::ffff:2.2.2.36' identified by '123';
mysql> flush privileges;
再验证一下,发现登陆OK
第三步:查看master的正在写的二进制文件名和位置
mysql> flush tables with read lock; --先加锁,防止两边数据不一致
Query OK, 0 rows affected (0.00 sec)
mysql> show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 | 681 | | |
+------------------+----------+--------------+------------------+
二进制文件名 正在写入的位置
slave端量的配置
mysql> slave stop;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> change master to
-> master_user='li',
-> master_password='123',
-> master_host='2.2.2.36', --主的IP
-> master_port=3306, --端口,如果为3307就要换成3307
-> master_log_file='mysql-bin.000001', --主上面查到的文件名
-> master_log_pos=681; --主上面查到的位置号
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 2.2.2.36
Master_User: li
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 681
Relay_Log_File: mysql55-relay-bin.000002
Relay_Log_Pos: 253
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes --这里两个YES,表示两个线程OK
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 681
Relay_Log_Space: 411
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 2
1 row in set (0.00 sec)
...................................
回到master端解锁:
mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)
进行测试:
1,先比较主,从的数据目录文件的不同
[root@master ~]# ls /data/ --主的
ibdata1 mysql performance_schema
ib_logfile0 mysql-bin.000001 test
ib_logfile1 mysql-bin.index
[root@slave ~]# ls /data/ --从的
ibdata1 mysql55-relay-bin.000002
ib_logfile0 mysql55-relay-bin.index
ib_logfile1 performance_schema
master.info relay-log.info
mysql test
mysql55-relay-bin.000001
验证2:只有master写,slave可以看到
slave写,master看不到
如果复制有问题,删除slave端/data/master.info再做
验证3:把从重启后,再上去查看状态,还是连接的,没什么影响
把主重启后,再去slave上去查看状态,发现重试时间为60秒,等60秒后又自动连接OK了