MYISAM:MySQL两种常见的存储引擎之一,特点是表数据文件和表索引文件都是独立存放,适合记录少于2000万以下、并发量不是很高的环境,适合简单的查询,不支持事务,容易出现数据丢失,表损坏,经常需要修复,修复往往也导致数据丢失,适合读多写少的环境

INNODB:MySQL两种常见的存储引擎之一,特点是表数据文件和表索引文件是共同一个文件,适合大规模数据,小规模的数据反而效率不高,适合并发量高的环境、复杂的查询,支持事务,支持数据自动修复,保证了数据丢失最少

备份方式

MySQL的常用备份方式可分为三种:

双机热备份
MySQL数据库没有增量备份的机制。当数据量太大的时候备份是一个很大的问题。还好MySQL数据库提供了一种主从备份的机制(也就是双机热备)

优点:适合数据量大的时候。大的互联网公司对于MySQL数据备份,都是采用热机备份。搭建多台数据库服务器,进行主从复制。

实现机制:

对于一个MySQL服务器,一般有两个线程来负责复制和被复制。当开启复制之后:

作为主服务器Master,会把自己的每一次改动都记录到二进制日志 binlog 中。(从服务器会负责来读取这个log,然后在自己那里再执行一遍。)

作为从服务器Slave,会用master上的账号登陆到master上,读取master的binlog,写入到自己的中继日志 Relaylog,然后自己的SQL线程会负责读取这个中继日志,并执行一遍。

在考虑双机热备时,需要注意,一般意义上的双机热备都会有一个切换过程,这个切换过程可能是一分钟左右。在切换过程中,服务是有可能短时间中断的。但是,当切换完成后,服务将正常恢复。因此,双机热备不是无缝、不中断的,但它能够保证在出现系统故障时,能够很快恢复正常的服务,业务不致受到影响。而如果没有双机热备,则一旦出现服务器故障,可能会出现几个小时的服务中断,对业务的影响就可能会造成很严重的损失。

配置步骤

主服务器:
开启二进制日志
配置唯一的server-id
获得master二进制日志文件名及位置
创建一个用于slave和master通信的用户账号

从服务器:**
配置唯一的server-id
使用master分配的用户账号读取master二进制日志
启用slave服务

环境要求
主数据库(Master)IP:10.254.1.248
备份数据库(Slave)IP:10.254.1.249
备份前首先要保证主从数据库一致,再进行同步。

Master端
进入MySQL命令行,创建一个从机访问主机的用户并赋予复制权限,即备份主机使用用户名backup,密码123456就可以连接到主服务器获取要备份的数据。

  1. CREATE USER 'backup'@'%' IDENTIFIED BY '123456';
  2. grant file,select,replication slave on *.* to backup@10.254.1.249 identified by '123456';
  3. flush privileges;

修改配置文件my.cnf[mysqld]:

  1. sevice-id=1
  2. log-bin=mysql-bin --------打开日志开关,二进制日志文件
  3. binlog_format=mixed --------日志模式row levelstatement level的结合
  4. binlog-do-db= aeaiesb --------在aeaiesb库进行的操作记录二进制日志文件,而不是对aeaiesb库的操作
  5. binlog-ignore-db=mysql --------忽略对mysql库的操作,即不记录到日志中
  6. expire_logs_days=7

Slave端
停掉数据库
service mysql stop
修改配置文件my.cnf,添加如下配置

  1. server-id=2
  2. log-bin=mysql-bin --------打开日志开关,二进制日志文件
  3. replicate-do-db=aeaiesb --------同步masteraeaiesb
  4. binlog_format=mixed --------日志模式row levelstatement level的结合
  5. expire_logs_days=7

重启数据库

  1. service mysql start


备份主数据库
mysqldump -u 用户名 -p 数据库名 > 导出的文件名.sql

还原从数据库
mysql -hlocalhost -uroot -p 数据库名 <导出的文件名.sql

查看master状态,会看到master数据库所处的位置

  1. mysql> use mysql;
  2. mysql> show master status;
  3. +----------------------+-----------+--------------------+-------------------+
  4. | File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
  5. +----------------------+-----------+--------------------+-------------------+
  6. | mysql-bin.000013 | 1150 | aeaiesb | mysql |
  7. +----------------------+-----------+--------------------+-------------------+
  8. 1 row in set (0.00 sec)

结果表示现在写日志的文件是mysql-bin.000013,位置是1105,slave端要从这个点开始同步备份aeaiesb

在MySQL命令行, 查看slave状态

  1. mysql> show slave status\G;
  2. *************************** 1. row ***************************

这时 Slave_IO_Running的值是No,I/O线程没有启动,是无法进行同步的处理步骤

需要执行以下命令:

  1. mysql> change master to master_host='10.254.1.248',master_user='backup',master_password='123456',master_log_file='mysql-bin.000014',master_log_pos=1150

重新启动从库:service mysql restart;
查看状态:show slave status\G;

  1. mysql> show slave status\G;
  2. Slave_IO_State: Waiting for master to send event
  3. Master_Host: 10.254.1.248
  4. Master_User: backup
  5. Master_Port: 3306
  6. Connect_Retry: 60
  7. Master_Log_File: mysql-bin.000013
  8. Read_Master_Log_Pos: 1105
  9. Relay_Log_File: localhost-relay-bin.000002
  10. Relay_Log_Pos: 251
  11. Relay_Master_Log_File: mysql-bin.000013S
  12. lave_IO_Running: Yes
  13. Slave_SQL_Running: Yes
  14. Replicate_Do_DB: aeaiesb

这样就可以进行同步了,在master的aeaiesb库中创建表,并插入数据会实时在slave端显示。

如果要再次配置从库访问备库的配置则执行以下命令

  1. 执行:slave stop;
  2. 执行:change master tomaster_host='192.168.1.130', master_port=3306, master_user='test',master_password='123456',master_log_file='mysql-bin.000011', master_log_pos=383
  3. 执行:slave start;

查询slave的状态

  1. mysql> show slavestatus \G;看下slave的状态:
  2. Master_Log_File: mysql-bin.000011 (和主mysql一致)
  3. Read_Master_Log_Pos: 383 (和主mysql一致)
  4. Slave_IO_Running: Yes (读写)
  5. Slave_SQL_Running: Yes (数据库状态)

还要注意状态中是否有error,如果没有的话,就差不多了。

如果Slave复制失败**,你可以根据错误信息进行修正,然后执行
mysql> slave stop;
mysql> slave start;就可以把原来应该复制过来的数据都复制过来

常用命令

  1. Slave start; --启动复制线程
  2. Slave stop; --停止复制线程
  3. Reset slave; --重置复制线程
  4. Show slave status; --显示复制线程的状态
  5. Show slave status\G; --显示复制线程的状态(分行显示)
  6. Show master status\G; --显示主数据库的状态(分行显示)
  7. Show master logs --显示主数据库日志,需在主数据库上运行
  8. Change master to; --动态改变到主数据库的配置
  9. Show processlist --显示有哪些线程在运行

高级优化

由于Mysql的复制都是基于异步进行的,在特殊情况下不能保证数据的成功复制,因此在mysql 5.5之后使用了来自google补丁,可以将Mysql的复制实现半同步模式。所以需要为主服务器加载对应的插件。在Mysql的安装目录下的lib/plugin/目录中具有对应的插件semisync_master.so,semisync_slave.so

在Master和Slave的mysql命令行运行如下命令:

Master:

  1. mysql> install pluginrpl_semi_sync_master soname 'semisync_master.so';
  2. mysql> set globalrpl_semi_sync_master_enabled = 1;
  3. mysql> set globalrpl_semi_sync_master_timeout = 1000;
  4. mysql> show variables like '%semi%';
  5. +------------------------------------+-------+
  6. | Variable_name | Value |
  7. +------------------------------------+-------+
  8. | rpl_semi_sync_master_enabled | ON |
  9. | rpl_semi_sync_master_timeout | 1000 |
  10. | rpl_semi_sync_master_trace_level | 32 |
  11. | rpl_semi_sync_master_wait_no_slave |ON |
  12. +------------------------------------+-------+

Slave:

  1. mysql> install pluginrpl_semi_sync_slave soname 'semisync_slave.so';
  2. mysql> set globalrpl_semi_sync_slave_enabled = 1;
  3. mysql> stop slave;
  4. mysql> start slave;
  5. mysql> show variables like '%semi%';
  6. +---------------------------------+-------+
  7. | Variable_name | Value |
  8. +---------------------------------+-------+
  9. | rpl_semi_sync_slave_enabled | ON |
  10. | rpl_semi_sync_slave_trace_level | 32 |
  11. +---------------------------------+-------+

检查半同步是否生效:
Master:

  1. mysql> show global status like'rpl_semi%';
  2. +--------------------------------------------+-------+
  3. | Variable_name | Value |
  4. +--------------------------------------------+-------+
  5. | Rpl_semi_sync_master_clients | 1 |
  6. |Rpl_semi_sync_master_net_avg_wait_time | 0 |
  7. | Rpl_semi_sync_master_net_wait_time | 0 |
  8. | Rpl_semi_sync_master_net_waits | 0 |
  9. | Rpl_semi_sync_master_no_times | 0 |
  10. | Rpl_semi_sync_master_no_tx | 0 |
  11. | Rpl_semi_sync_master_status | ON |
  12. |Rpl_semi_sync_master_timefunc_failures | 0 |
  13. |Rpl_semi_sync_master_tx_avg_wait_time | 0 |
  14. | Rpl_semi_sync_master_tx_wait_time | 0 |
  15. | Rpl_semi_sync_master_tx_waits | 0 |
  16. |Rpl_semi_sync_master_wait_pos_backtraverse | 0 |
  17. | Rpl_semi_sync_master_wait_sessions | 0 |
  18. | Rpl_semi_sync_master_yes_tx | 0 |
  19. +--------------------------------------------+-------+

说明半同步成功。

让半同步功能在MySQL每次启动都自动生效,在Master和Slave的my.cnf中编辑:
Master:

  1. [mysqld]
  2. rpl_semi_sync_master_enabled=1
  3. rpl_semi_sync_master_timeout=1000 #1秒

Slave:

  1. [mysqld]
  2. rpl_semi_sync_slave_enabled=1

也可通过设置全局变量的方式来设置是否启动半同步插件:
Master:

  1. mysql> set globalrpl_semi_sync_master_enabled=1

取消加载插件

  1. mysql> uninstall pluginrpl_semi_sync_master;

Slave:

  1. mysql> set globalrpl_semi_sync_slave_enabled = 1;
  2. mysql> uninstall pluginrpl_semi_sync_slave;

日志模式

基于SQL语句的复制(statement-based replication, SBR),
基于行的复制(row-based replication, RBR),
混合模式复制(mixed-based replication, MBR)。
对应的,binlog的格式也有三种:STATEMENT,ROW,MIXED

STATEMENT模式(SBR)
每一条会修改数据的sql语句会记录到binlog中。优点是并不需要记录每一条sql语句和每一行的数据变化,减少了binlog日志量,节约IO,提高性能。缺点是由于记录的只是执行语句,为了这些语句能在slave上正确运行,因此还必须记录每条语句在执行的时候的一些相关信息,以保证所有语句能在slave得到和在master端执行时候相同的结果。另外mysql 的复制,像一些特定函数功能,在某些情况下会导致master-slave中的数据不一致(如sleep()函数, last_insert_id(),以及user-defined functions(udf)等会出现问题)
使用以下函数的语句也无法被复制:
LOAD_FILE()
UUID()
USER()
FOUND_ROWS()
SYSDATE() (除非启动时启用了 —sysdate-is-now 选项)
同时在INSERT …SELECT 会产生比 RBR 更多的行级锁

ROW模式(RBR)
不记录每条sql语句的上下文信息,仅需记录哪条数据被修改了,修改成什么样了。而且不会出现某些特定情况下的存储过程、或function、或trigger的调用和触发无法被正确复制的问题。缺点是会产生大量的日志,尤其是alter table的时候,由于表结构修改,每条记录都发生改变,那么该表每一条记录都会记录到日志中会让日志暴涨。

MIXED模式(MBR)
以上两种模式的混合使用,一般的复制使用STATEMENT模式保存binlog,对于STATEMENT模式无法复制的操作使用ROW模式保存binlog,MySQL会根据执行的SQL语句选择日志保存方式。新版本的MySQL中队row level模式也被做了优化,并不是所有的修改都会以row level来记录,像遇到表结构变更的时候就会以statement模式来记录。至于update或者delete等修改数据的语句,还是会记录所有行的变更。