17.1
复制在servers之间是基于binary logging 机制。
Mysql 实例在master上的操作(数据改变的源头) 记录updates和changes以events的形式写入到binary log
binary log里存储的信息是不同的日志格式来记录数据库的改变。
Slaves 是配置来读取binary log 从master 然后在slave 数据库上执行binary log里的event
重要的是: 你不能配置使master 只记录某些events
master 在这种场景就哑巴了,当binary logging 被启用,所有的语句都会记录到binary log.
每个slave 收到一份binary log的整个内容。这是slave的责任来决定binary log里哪些语句应该被执行
你不能配置master 只记录某些events.如果你不指定否则,
master所有的evnets 会在slave上执行.如果需要,你可以配置slave只处理应用于数据库或者表的而某些events.
每个slave 不断的记录log写的位置:处理日志的名字和position,
这意味着多个slave可以连接到master 执行同一个binary log的不同的部分。因为slave控制这个进程,
个别的slaves 可以连接和断开不影响master的操作。 由于,每个slave记录了binary log 当前的位置,
有可能slaves会断开,重连 继续处理。
master 和每个slave 必须配置一个唯一的ID(使用server-id)选项。
此外,每个slave 必须配置关于mast的主机名,log file和position
使用CHANGE MASTER TO 语句在slave上。
这个章节描述了 复制环境需要的配置,包括一步一步指令
用于创建一个新的复制环境,这个章节主要的内容是:
1.设置2个或者多个server用于复制,处理系统的配置和提供
在master 和slaves之间复制数据
2.在binary log 记录的events 使用一系列的格式,
这些被称为基于语句的复制 SBR或者 基于行的复制RBR
另外一种方式个混合复制,使用SBR和RBR复制自动的利用了SBR和RBR的好处
17.1.1 如何配置复制
这个章节描述了如何设置完整的MySQL复制环境。有大量的不同的方法来设置复制,
准确的方法是依靠如何设置复制,是否你的master 数据库已经存在数据
有一些通用的任务,是常见的复制设置:
1.在master,你必须启用binary log 配置一个唯一的server ID,这个需要重启server
2.在每个slave上 你需要连接到master,你需要配置一个唯一的server ID. 需要重启server
3.可选的, 创建一个单独的用户在master上用于读取binary log 和复制
4.在创建数据快照和启动复制进程前,你需要记录master binlog的 位置。
你需要这些信息用于slave 作为开始执行events的开始
5.如果你的master已经存在数据库 你需要同步到slave. 你需要创建一个数据快照,
这里有不同的方式来创建数据库快照,取决于你的数据库的大小和文件的位置。
创建快照使用mysqldump 或者直接复制文件
6.配置slave 连接到master,比如host name 登录凭证,binary log 和position
当配置基本的选项后,选择你的场景:
1.设置复制环境,先安装的master和slaves不包含数据的
2.设置环境 master使用已经存在的数据
3.增加复制slaves 到现成的环境
在管理mysql 复制环境前
17.1.1.1 复制环境 Master 设置
复制环境总的master,你必须启用binary logginng ,建立一个唯一的SERVER ID,如果这个没有做,那么需要重启
server。
master binary logging 必须启用,因为binary log 是复制的基础,用于把改变复制到slaves.
如果binary logging 没有期待用,使用log-bin选项,
每个server 在复制环境里必须有一个唯一的server ID,这个ID用于确认唯一的servers
配置binary log和server ID选项,关闭数据库 编辑my.cnf或者my.ini file.
在[mysqld]部分,增加log-bin和server-id选项。如果这些选项已经存在,但是被注释了,
取消该选项注释改变他们,根据你的需要
参数改变后,重启server
注意:
如果你省略server-id(或者明确的设置为默认值0),master 会拒绝slaves的任何连接
为最大可能的耐久性和一致性在复制环境设置里,使用InnoDB事务复制设置
你需要设置 innodb_flush_log_at_trx_commit=1 and sync_binlog=1
mysql> show variables like ‘innodb_flush_log_at_trx_commit’;
+——————————–+——-+
| Variable_name | Value |
+——————————–+——-+
| innodb_flush_log_at_trx_commit | 1 |
+——————————–+——-+
1 row in set (0.00 sec)
mysql> show variables like ‘sync_binlog’;
+—————+——-+
| Variable_name | Value |
+—————+——-+
| sync_binlog | 0 |
+—————+——-+
1 row in set (0.00 sec)
注意:
确认skip-networking option 是不启用的在你的master中 如果网络不可用,
slave 不能连接到master ,复制失败
mysql> show variables like ‘%skip_networking%’;
+—————–+——-+
| Variable_name | Value |
+—————–+——-+
| skip_networking | OFF |
+—————–+——-+
1 row in set (0.00 sec)
17.1.1.2 Setting the Replication Slave Configuration
配置slave
在复制的slave环境,你必须创建一个唯一的server ID,如果这个没有做,这个配置需要重启server
如果slave server ID 没有配置,或者slave的server id 和master server冲突
关闭slave server 编辑[mysqld]部分,比如:
[mysqld]
server-id=2
当改变server id后,重启server
如果你设置多个slaves,每个slave 必须有一个唯一的server-id值 和master 和其他的slaves都不相同
注意:
如果你省略server-id(或者明确的设置为默认值0),slaves 拒绝连接到master
你没有必要启用binary logging 在slaves上,然而,如果你启用了slave的binary log
你可以使用slave的binary log 来进行备份和crash recovery,使用slaves作为更加复杂的复制环境的一部分
比如,这个slave 作为其他slave的master
17.1.1.3 Creating a User for Replication
创建一个用户用于复制
每个slave连接到master 使用一个Mysql的账户和密码,因此必须有一个用户账户在master上用于slave的连接。
任何账户可以用于操作,给它REPLICATION SLAVE权限。
你可以选择创建一个不同的账号用于slave,或者每个slave连接到master使用相同的账户。
尽管你没有必要创建一个专用的账户用于复制, 你需要意识到复制的用户和密码
是藏在纯文本的在master的文件或者表
因此,你需要创建一个单独的账户只有复制的权限,尽可能的最小化
mysql> CREATE USER ‘repl’@’%.mydomain.com’ IDENTIFIED BY ‘slavepass’;
mysql> GRANT REPLICATION SLAVE ON . TO ‘repl’@’%.mydomain.com’;
17.1.1.4 Obtaining the Replication Master Binary Log Coordinates
得到复制需要的master 的binary log的位置
你需要master当前的binary log 的位置用于配置slave来启用复制进程 在正确的结合点
如果 你的master已经存在数据,你需要同步到你的slaves 在启动复制前,
你必须让master停止处理语句,然后得到它的正确的binary log 位置,dump 它的数据,
在允许master 继续执行语句前.如果你不停止执行语句, dump的数据和master的状态信息,你需要使用就会不匹配
你会停止不一致的或者冲突的数据在slaves上。
为了得到master的binary log 位置,依据下面的步骤:
1.,flush 所有的表和阻止写语句通过执行FLUSH TABLES WITH READ LOCK 语句
mysql> FLUSH TABLES WITH READ LOCK;
对于InnoDB 表,FLUSH TABLES WITH READ LOCK also blocks COMMIT operations.
注意:
遗留你执行FLUSH TABLES的客户端,因此read block 仍旧保持生效,如果你退出客户端,锁会被释放
2.开启一个新的session,使用SHOW MASTER STATUS 语句来决定当前的binary log 和 position
mysql > SHOW MASTER STATUS;
+——————+———-+————–+——————+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+——————+———-+————–+——————+
| mysql-bin.000003 | 73 | test | manual,mysql |
+——————+———-+————–+——————+
File 列 先吃了binary log 的文件名字,Posistion 显示了文件的位置
在这个例子中, binary log 是mysql-bin.000003 position 是73
记录这些值,在后面设置复制环境的时候会用到。 他们表明了复制的位置 ,slave开始处理新的更新从master server
如果master 先前运行没有启用binary log, log file 和position 在SHOW MASTER STATUS
显示为空,或者mysqldump –master-data 也会为空。
17.1.1.5 Creating a Data Snapshot Using mysqldump
创建一个数据快照使用mysqldump
一种方式来创建master中已经存在数据的快照是用mysqldump工具来创建一个所有的数据库的dump
一旦dump完成,你然后可以导入到slave中。
下面的例子 显示dump所有的数据到一个文件叫做dbdump.db,包括–master–data 选项
会自动追加CHANGE MASTER TO 语句
shell> mysqldump –all-databases –master-data > dbdump.db
如果你不使用–master-data,那么你需要手动lock 所有的表在一个单独的session
(使用FLUSH TABLE WITH READ LOCK)在运行mysqldump之前, 然后退出运行UNLOCK TABLES 从第二个窗口
来释放locks.你必须得到binary log的position信息来匹配快照,
当你选择了相应的数据库,记住 你需要在每个slave上过滤
17.1.1.6 Creating a Data Snapshot Using Raw Data Files
使用Raw 数据文件创建一个快照数据
如果你的数据库非常大,拷贝raw数据文件相比mysqldump会更加有效率。
这个技术跳过了当使用INSERT语句来更新索引的开销
使用这个方法在存储引擎里的表具有复杂的caching或者登陆算法需要额外的步骤来执行一个完美的
时间点快照,初始化的copy命令可能遗漏了cache信息 和 记录的更新,
即使你有需要一个全局的read lock,然而 存储引擎的响应依赖它的crash recovery能力。
这种方法也并不可靠,如果master和slave 有不同的值关于ft_stopword_file,ft_min_word_len
ft_max_word_len 你拷贝表有全文索引
如果你使用InnoDB表,你可以使用mysqlbackup命令来产生一个一致性的快照。
这个命令记录了日志文件和偏移量相应的快照 后面用于slave
否则,使用一耳光cold backup技术来得到一个可靠的InnoDB的binary 快照,
拷贝所有的数据文件在slow shutdown mysql之后
来创建一个MyISAM表的raw 数据快照,你可以使用准备的cp copy命令,远程的拷贝比如 scp或者rsync
归档工具比如zip或者tar,或者一耳光文件系统快照工具比如dump,
提供你的MySQL 数据文件存在一个单独的系统上。 如果你只复制某些数据库,
只复制那些文件对应的表
你需要特别排除下面的文件
1.和Mysql 数据库相关的文件
2.master 的响应文件
3.master的binary log 文件
4.任何relay log (中继日志)[该文件一般是在mysql slave实例上存在。主要用途是记录主从同步的信息]
17.1.1.7 Setting Up Replication with New Master and Slaves
设置新的复制和slaves环境
在早期的最简单的方式是使用一个新的master和slave servers
你也可以使用这种方法,如果你设置新的servers 但是有一个存在的dump,加载到你的复制环境。
把数据加载到新的master,数据也自动会复制到slaves.
设置复制环境在新的master和slave
1.配置MySQL master 用一些必须的配置选项
2.启动Mysql master
3.创建master上的用户
4.得到状态信息
5.在master上,释放读锁
mysql> UNLOCK TABLES;
6.在slave上,编辑MySQL 配置
7.启动MySQL slave
8.slave上执行一个CHANGE MASTER TO语句
在每个slave上执行步骤:
因为没有数据来加载或者交换 在新的server配置上,你没有必要使用copy或者import 任何信息
17.1.1.8 Setting Up Replication with Existing Data
复制使用存在的数据
当你用存在的数据设置复制环境时,你需要确定最好的方式从master得到数据 导入到slave 在启动复制服务前
基本的处理已经存在数据的步骤是:
1.当Mysql master运行时,创建一个用于slave连接到master的账户,在复制的时候
2.如果你没有设置server-id和启用binary log 在master server上,你需要关闭数据库来配置这些选项
如果你已经关闭了你的master serer,这个是一个好的机会来做一份数据库的快照。
你需要得到master的状态在关闭master 之前,更新配置做一份快照。
3.如果你的master 已经争取配置了,得到它的状态 然后使用mysqldump 来做一个快照
当你已经执行这个过程后,slave可以连接到master,可以捕捉任何自快照以来的改变。
如果你忘记设置master的server-id选项,slaves不能连接
如果你忘记设置slave的server-id,slave会得到下面的错误信息:
Warning: You should set server-id to a non-0 value if master_host
is set; we will force server id to 2, but this MySQL server will
not act as a slave.
你也可以在slave的error log 信息里找到错误,如果不能复制由于其他的原因
slave 使用的信息存储在它的master info 知识库里
slave:/data01/mysql# cat master.info
23
mysql-bin.000010
211505801
120.26.56.85
backup
xxxxxx
3306
60
0
0
1800.000
0
5b4aff83-cf9c-11e4-91fd-00163e002c0d
86400
0
来跟踪 已经出了多少master的binary log.
知识库文件以表或者文件的形式存在,有master-info-repository 值决定
当一个slave 在–master-info-repository=FILE 运行,你可以找到在数据目录下有2个文件
master.info and relay-log.info
If –master-info-repository=TABLE代替,这些信息被保存在mysql数据库的master_slave_info表里
在任何情况下,不要重新移动或者编辑这文件或者表,除非你明确知道你在做什么,完全了解其中的含义。
17.1.1.9 Introducing Additional Slaves to an Existing Replication Environment
介绍额外的slaves 对于已经存在的复制环境
为了添加另外一个salve到已经存在的复制环境,你做这个不需要停止master,代替的是,
设置新的slave通过复制已经存在slave . 你需要给新的slave配置一个不同的server-id值
复制一个已经存在的slave
1.关闭已经存在的slave
shell>mysqladmin shutdown
2.复制 slave的数据目录到新的slave,你可以使用tar或者Winzip 或者执行拷贝,确保你复制了日志文件和relay
log files
这个是通用的遇到的问题,当增加一个新的slaves 新加的slaves 失败失败 一些的waring和错误:
071118 16:44:10 [Warning] Neither –relay-log nor –relay-log-index were used; so
replication may break when this MySQL server acts as a slave and has his hostname
changed!! Please use ‘–relay-log=new_slave_hostname-relay-bin’ to avoid this problem.
071118 16:44:10 [ERROR] Failed to open the relay log ‘./old_slave_hostname-relay-bin.003525’
(relay_log_pos 22940879)
071118 16:44:10 [ERROR] Could not find target log during relay log initialization
071118 16:44:10 [ERROR] Failed to initialize the master info structure
这是由于, 如果–relay-log 选项没有指定,relay-log 文件包含了Hostname 作为file names的一部分
为了避免这个问题,–relay-log使用相同的值在新的slave上(基于存在的slave)
如果这个选项没有被明确的设置在一个存在的slave上,使用existing_slave_hostname-relay-bin.)
如果这个不可行,复制存在的slave的relay log index文件到新的slave ,设置–relay-log-index 选项
在新的slave上来匹配已经存在的slave.(如果这个选项没有被设置,使用existing_slave_hostname-relay-
bin.index)
另外,如果你已经尝试启动新的slave(继本节剩下的步骤)
,已经遇到上面藐视的错误,执行下面的步骤:
a.如果你没有做这些,执行STOP SLAVE 在新的slave上
如果你已经启动了存在的slave,执行stop slave 在存在的slave上
b.复制已经存在的slave的relay log index 文件到新的slave ,确保覆盖文件的任何内容
c.执行这个章节余下的步奏
包含了master的binary log 的当前日志位置和slave的relay log
4.启动存在的slave
17.1.1.10 Setting the Master Configuration on the Slave
在slave上设置Master 配置
设置slave用于和master 连接,你需要告诉slave 相应的连接信息
执行下面的语句在slave上
mysql> CHANGE MASTER TO
-> MASTER_HOST=’master_host_name’,
-> MASTER_USER=’replication_user_name’,
-> MASTER_PASSWORD=’replication_password’,
-> MASTER_LOG_FILE=’recorded_log_file_name’,
-> MASTER_LOG_POS=recorded_log_position;
注意:
复制不能使用Unix sockt 文件,你连接的Master sever必须使用TCP/IP