MySQL复制(一) --- 二进制日志干什么的

与小站点相比,大型站点的数据库管理员,需要提前做好以下的事情:

  • 提供灾难发生时核心业务数据的恢复计划。理论上这个过程至少需要执行一次。
  • 通过采集大量用户数据并监控网站各节点的负载,提供优化计划
  • 当用户数量急剧增长时的快速横向扩展计划
对于所有这些事情,提前计划并准备好必要时的快速应对是很重要的。

 

为了保证站点可响应和可用性,需要做两件事:系统的数据备份和冗余。备份可以将节点恢复到它崩溃之前的状态,备份根据需求有几种比如及时恢复(PITR:point-in-time-recovery),在线备份等等;而冗余则保证即使在一个或更多节点停止服务的情况下,站点仍能继续运行,备份一般通过硬件副本来实现,让几个实例并行运行,并通过复制在几个机器上保存相同数据的多个可用副本。复制的主要应用场景:1)针对高读写比的,scale out;2)添加冗余保证高可用性,比如双主配置(dual-master setup)。

 

二进制日志(binlog)

复制过程需要二进制日志。二进制日志的目的是记录数据库中表的更改,然后用于复制和PITR,另外少数审计情况下也会用到。

传统意义上说,MySQL复制记录了产生变化的SQL语句,称为基于语句的复制(statement-based replication)。基于语句的复制的缺点是无法保证所有语句都正确复制。所以在5.1版本中,MySQL还提供了基于行的复制(row-based replication)。

查看二进制日志:

# 强制把缓存的东西刷到LOGS中,并产生一个Rotate事件写入binlog中,后面的写入会写到新的binlog中
FLUSH LOGS;

# 正常使用很久的DB不建议使用这个命令,需要加参数,指定具体的binlog文件名 【IN 'xxxx'】
SHOW BINLOG EVENTS\G

二进制日志中事件所包含的字段:

Event_type: 比如Format_desc, Query, Rotate
Server_id : 创建事件的服务器id
Log_name : 存储事件的文件名,一个事件只能存储在一个文件中
Pos : 事件在文件中的开始位置,及事件的第一个字节
End_log_pos:事件在文件中的结束位置,也就是下一个事件的开始位置
Info : 具体事件的信息,Query的时候就是SQL语句

二进制日志的结构和内容:

二进制日志不是一个的单独的文件,它包括一组存储实际内容的二进制日志文件和一个二进制日志索引文件。每个二进制日志文件都以format description event开始,以rotate event结束。rotate event包含下一个二进制日志文件的名称,以告知二进制日志继续写入哪个文件。因此FLUSH LOGS的时候会新建一个新binlog文件。 

获取当前正在写入的是哪一个二进制日志文件:

SHOW MASTER STATUS\G

RESET MASTER命令删除了所有的二进制日志文件并清空了二进制日志索引文件。RESET SLAVE命令删除了Slave复制所用的所有文件,重新开始。

CHANGE MASTER TO命令用于改变slave连接master的一些参数,其中就包括slave读取master二进制日志文件的参数。比如使用MASTER_LOG_FILE和MASTER_LOG_POS来指定master开始发送事件的binlog位置。

如何建立新Slave

1:配置新的Slave
2:备份Master(或者备份已经复制了Master的Slave)
3:接下该备份相应的binlog位置
4:在新Slave上恢复备份
5:配置Slave从这个binlog位置开始复制

区别就在于第二步,一种是直接从Master进行备份,一种是通过现有Slave备份,下面分别介绍两种。

1:克隆Master:

# 刷新所有的表并锁定数据库,防止在检查binlog位置之前数据库发生改变
FLUSH TABLES WITH READ LOCK

# 获取当前的binlog文件和pos
SHOW MASTER STATUS\G

# 备份master
mysqldump --all-databases --host=master-1 >backup.sql

# 解锁
UNLOCK TABLES;

# 在slave上恢复备份
mysql --host=slave-1 <backup.sql

# 配置slave
CHANGE MASTER TO
MASTER_HOST = 'master-1',
MASTER_PORT = 3306,
MASTER_USER = 'slave-1',
MASTER_PASSWORD = 'xxxx',
MASTER_LOG_FILE = 'master-bin.000042',
MASTER_LOG_POS = 546552;

# 启动slave
START SLAVE;

其实mysqldump命令提供了master_data选项,自动把MASTER_LOG_FILE和MASTER_LOG_POS信息dump到backup.sql中

另外:FLUSH TABLES WITH READ LOCK对于InnoDB是不安全的,因为虽然会锁表,不会产生新事务,但是后台仍然有一些活动在继续进行。

所以安全的创建InnoDB数据表的备份可以使用下面的方法。

1:关闭服务器,然后复制文件。如果数据库很大 ,最好采取这种方法,因为这时使用mysqldump进行数据恢复会很慢

2:执行FLUSH TABLES WITH READ LOCK之后,使用mysqldump

3:执行FLUSH TABLES WITH READ LOCK之后,使用快照的方法,比如LVM(Linux),ZFS(Solaris)快照

 

2:克隆Slave:

# 防止出现不一致的备份映像,备份Slave之前需要先停止replication
STOP SLAVE;

# 确定从哪里开始复制,注意Relay_Master_Log_File和Exec_Master_Log_Pos
SHOW SLAVE STATUS\G

# 配置新的slave,指向master
CHANGE MASTER TO
MASTER_HOST = 'master-1',
MASTER_PORT = 3306,
MASTER_USER = 'slave-1',
MASTER_PASSWORD = 'xxxx',
MASTER_LOG_FILE = 'master-bin.000042',
MASTER_LOG_POS = 546632;

# 启动新的slave
START SLAVE

 

---待续

posted on 2011-10-26 09:54  foxracle  阅读(2712)  评论(1编辑  收藏  举报