一、MySQL的备份简介
根据不同的分类标准可以分为冷备,热备,温备:完全备份,部分备份:增量,差异,全备份等等,我们需要根据不同的需要,备份策略等选择不同的备份方法和工具
二、常用的备份工具的使用方法:
1. mysqldump 比较常用的,比较适合备份少量数据。可以实现远程备份表,数据库。使用方法
Usage: mysqldump [OPTIONS] database [tables] OR mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...] OR mysqldump [OPTIONS] --all-databases [OPTIONS]
例如:我们把数据库中个的hellodb备份到root家目录下,然后恢复为hellodb2。注意:备份的前要加锁,放置备份过程有用户写入数据(记得备份完成后检查是否成功)
手动添加锁的方法
Mysql> FLUSH TABLES WITH READ LOCK; Mysql> FLUSH LOGS; # mysqldump hellodb > /tmp/helllodb.sql Mysql> unlock tables;
当然mysqldump也支持自动加锁备份
[root@stu20 ~]# mysqldump -uroot -hlocalhost -p --lock-all-tables hellodb> /root/hellodb.sql [root@stu20 ~]# mysql -uroot -hlocalhost -p hellodb2< /root/hellodb.sql
这里可以用多个选项:
--all-databases;备份所以库
--databases db1 db2 指定多个库
--lock-all-tables;备份前锁定所有表,可以对不支持事务的myisam和aria做温备
--single-transaction:如果引擎是innodb,直接用此选项不用锁表也可
2. 实现二进制完成增量恢复
假如我们备份过后有删除或者添加了表之后数据库出故障了。此时就要用到二进制来做恢复了
a) 首先让服务器离线
b) 把二进制日志关闭
c) 导出进二进制日志中查看服务器正常总之的最后一刻
d) 利用二进制日志恢复
mysql> show master status; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000007 | 8730 | | | +------------------+----------+--------------+------------------+ 1 row in set (0.00 sec) mysql> use hellodb Database changed mysql> create table binbin(name int); Query OK, 0 rows affected (0.48 sec) mysql> show master status; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000007 | 8825 | | | +------------------+----------+--------------+------------------+ 1 row in set (0.00 sec) mysql> drop database hellodb; Query OK, 9 rows affected (0.23 sec) mysql> show master status; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000007 | 8912 | | | +------------------+----------+--------------+------------------+ 1 row in set (0.00 sec)
此时的位置已经到了8912了,我们应该恢复到8825这个位置。
新建数据库
mysql> create database hellodb; 导入表 [root@stu20 ~]# mysql hellodb < hellodb.sql [root@stu20 ~]# mysqlbinlog --start-position=8730 --stop-position=8825 /mydata/data/mysql-bin.000007 > /tmp/hdb.sql
此时我们关闭二进制日志
mysql> set session sql_log_bin=0; mysql> source /tmp/hdb.sql mysql> show tables; +-------------------+ | Tables_in_hellodb | +-------------------+ | binbin |
此时我们的新建的表又出现了。
3. 基于逻辑卷的备份
a) 注意数据和二进制日志都要放在逻辑卷上
b) 创建逻辑卷快照
c) 恢复的时候注意查看需要恢复的二进制文件的起始和结束位置
d) 请求全局锁
e) 细节同上,这里没有给出过多演示
4. 好用的xtrabackup备份工具的使用
a) Xtrabackup是percona公司开发的一个方便的备份工具,开源,热备,无阻塞。实现快速安全无阻塞,节约网络带,备份过程不打断正在执行的事务,自动检测备份的数据能否得到回复。
b) 安装xtrabackup工具并实现恢复
i. 去percona官网下载包,http://www.percona.com/software/percona-xtrabackup。直接yum安装
ii. 安装好了就可以使用了,xtrabackup备份工具会把备份的内容以时间命名放在一个文件中。我们可以穿件一个文件夹存放其备份数据,另外注意二进制日志不要和数据放在同一个文件中。。
iii. 基于安全考虑,可以创建一个最小权限用户进行备份,这里不在演示。
iv. 完全备份,备份完成后会生成各个数据库的文件和跟备份相关的数据
[root@localhost data]# mkdir /mybackups [root@localhost data]# innobackupex --user=root /mybackups/ [root@localhost ~]# ls /mybackups/2014-04-13_00-26-51/ backup-my.cnf performance_schema xtrabackup_checkpoints hellodb test xtrabackup_logfile ibdata1 xtrabackup_binary mysql xtrabackup_binlog_info
v. 还原数据的时候要对备份进行整理。一般情况下,在备份完成后,数据尚且不能用于恢复操作,因为备份的数据中可能会包含尚未提交的事务或已经提交但尚未同步至数据文件中的事务。
1. [root@localhost ~]# innobackupex --apply-log /mybackups/2014-04-13_00-26-51/
vi. 检查完后进行恢复,恢复的时候不需启动mysql,而且恢复的时候xtrabackup会自动判断原始数据存在的目录。
[root@localhost data]# innobackupex --copy-back /mybackups/2014-04-13_00-26-51/
vii. 增量备份及其恢复
[root@localhost data]# innobackupex --incremental /mybackups --incremental-basedir=/mybackups/2014-04-13_00-26-51/
恢复前准备的阶段有别与全备份,应该和并所以增量备份然后恢复合并后的全备份。
[root@localhost ~]# innobackupex --apply-log --read-only /mybackups/2014-04-13_01-49-50/ --incremental-dir=/mybackups/2014-04-13_00-26-51/
三、主从复制
1. myslq的复制原理:mysql会把操作记录到二进制日志,从服务器不停的向主服务器3306端口请求二进制日志,然后从服务器会把二进制保存为中继日志,一条一条写进自己文件中(异步)
2. 怎么实现读写分离:
用算法决定访问哪个mysql服务器,但是这种方法使得前后端耦合度过与紧密,所以需要前后端加一个调度器,使得前端程序开发不需要依赖后端硬件的变动
算法:a.使用hash编码delect语句进行计算,讲结合与服务器个数取余数,余数结果就决定了使用哪个服务器,这样就保证了同一条语句会发往同一个服务器,提高命中率。 b.使用环。 c.虚拟环。
使用中间分发器;
amoeba(阿米巴,国内)
mysql-proxy:(需要二次开发保证其更安全)
3. 配置过程
a) 修改主配置文件使其适应
[root@localhost ~]# vim /etc/my.cnf log-bin=/mydata/binlogs/master-bin---改变二进制文件存放位置,放置丢失 server-id = 1------------------------------修改serverID完成身份区别
b) 主服务器授权一个具有复制帐号的用户
MariaDB [(none)]> grant replication slave,replication client on *.* TO 'xuxu'@'172.16.%.%' identified by 'xuxu';
c) 修改从服务器配置文件并连接主服务器
[root@localhost ~]# vim /etc/my.cnf Log-bin=OFF------关闭二进制日志 Server-id=2----- relay-log =/mydata/relaylogs/relay-bin---启用中继日志并改变存放位置 连接主服务器 MariaDB [(none)]> change master to master_host='172.16.20.65',master_user='xuxu',master_password='xuxu';
d) 手动启动从服务器线程
MariaDB [(none)]> start slave;
e) OK,现在在主服务器做操作从服务器就可以实现同步了。次日如果停止slave关闭mysql,下次重启从服务器会自动启动slave
f) 假如我们的主服务器中已经有大量的数据了,此时如果从0开始复制,会消耗很长时间,这是我们就可以从半道开始复制。首先备份主服务器数据,讲数据发送到从服务器中,然后把备份数据导入到从服务器,然后连接的时候指定开始复制的位置即可。
i. 主服务器
[root@localhost ~]# mysqldump --all-databases --flush-logs --master-data=2 --lock-all-tables > all.sql [root@localhost ~]# scp all.sql [email protected]:/root/ 此时查看二进制日志位置 MariaDB [(none)]> show master status; +-------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +-------------------+----------+--------------+------------------+ | master-bin.000004 | 367 | | | +-------------------+----------+--------------+------------------+ 再插入一些数据 MariaDB [(none)]> create databases test2 MariaDB [(none)]> show master status; +-------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +-------------------+----------+--------------+------------------+ | master-bin.000004 | 490 | | | +-------------------+----------+--------------+------------------+ 1 row in set (0.00 sec) ii. 从服务器 [root@localhost ~]# mysql < all.sql MariaDB [(none)]> change master TO master_host='172.16.20.65',master_user='xuxu',master_password='xuxu',MASTER_LOG_FILE='master-bin.000004', MASTER_LOG_POS=327; MariaDB [(none)]> show databases; +--------------------+ | Database | +--------------------+ | hellodb | | information_schema | | mysql | | performance_schema | | test | +--------------------+ (此时新创建的数据库test2还没有恢复) 启动slave开始同步 MariaDB [(none)]> start slave; Query OK, 0 rows affected (0.01 sec) MariaDB [(none)]> show databases; +--------------------+ | Database | +--------------------+ | hellodb | | information_schema | | mysql | | performance_schema | | test | | test2 | +--------------------+ 6 rows in set (0.00 sec)
好了,已经成功同步完成。
4. 为了避免主从服务器的安全性和数据的同步性,设定一些服务器的工作特性是很有必要的
a) 保证两个服务器的时间要同步,可以通过定义一个crontab来自动完成去一个时间服务器中自动同步时间
b) 另外,如果我们如果不小心向我们的从服务器写数据了,会造成数据不一致。为了避免这种情况我们可以在从服务器中定义禁止写和删除的操作。
在从服务器配置文件中定义read-only=ON (只能限制非super用户的写权限)
MariaDB [(none)]> show global variables like '%read_only%'; +------------------+-------+ | Variable_name | Value | +------------------+-------+ | innodb_read_only | OFF | | read_only | ON | | tx_read_only | OFF | +------------------+-------+ MariaDB [(none)]> create database test2; ERROR 1290 (HY000): The MariaDB server is running with the --read-only option so it cannot execute this statement
5. 半同步复制
a) 实现半同步复制(插件工作模式)google贡献(当有多个从时,主服务器等待一个从反馈复制完成就OK,不用等待所以都ok)
b) 插件位置/usr/loca/mysql/lib/plugin
c) 主节点安装(会自动去mysql/plugin/ 目录下查找相应插件)
d) mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME'semissc_master.so'
e) mysql> SHOW GLOBAL VARIABLES LIKE '%semi%';
f)
g) 调整第一个参数为ON,和time_out 时间
h) 从节点安装
i)
k) 在主服务器验证半同步复制是否生效
l) 卸载插件:mysql> uninstall ...
m) 几个常用变量
o) 缺点:一旦某次等待超时,会自动降级为异步,(可以使用监控来实现一旦降级运行自动脚本重新变为同步)
6 . 复制过滤器(对服务器上对二进制日志做过滤)
在主服务器上做过滤优点:节约带宽,日志。缺点:恢复的时候由于二进制不完整不能实现即使点还原。所以一般不采用。
服务器过滤方法(永久有效保存到配置文件)
master;(只能过滤到库级别) binlog_do_db= binlog_ignore_db= slave:(可以过滤数据库或者表) replicate_do_db= replicate_ignore_db= replicate_do_table=db_name.table_name(基于表做过滤) replicate_ignore_table= replicate_wild_do_table= replicate_wild_ignore_table=
7. 多主模型(互为主从)
在两台服务器上各自建立一个具有复制权限的用户;
修改配置文件:
# 主服务器上 [mysqld] server-id = 10 log-bin = mysql-bin relay-log = relay-mysql relay-log-index = relay-mysql.index auto-increment-increment = 2 auto-increment-offset = 1 # 从服务器上 [mysqld] server-id = 20 log-bin = mysql-bin relay-log = relay-mysql relay-log-index = relay-mysql.index auto-increment-increment = 2 auto-increment-offset = 2
然后各服务器接下来指定对另一台服务器为自己的主服务器即可:
server1|mysql> CHANGE MASTER TO ...,MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=811 server2|mysql> CHANGE MASTER TO ...,MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=710