mysql的复制类型:
1.基于语句的复制:主服务器上面执行的语句在从服务器上面再执行一遍,在mysql-3.23版本以后支持
存在的问题:时间上可能不完全同步造成偏差,执行语句的用户也可能是不同一个用户
2.基于行的复制:把主服务器上面改编后的内容直接复制过去,而不关心到底改变该内容是由哪条语句引发的,在mysql-5.0版本以后引入
存在的问题:比如一个工资表中有一万个用户,我们把每个用户的工资+1000,那么基于行的复制则要复制一万行的内容,由此造成的开销比较大,而基于语句的复制仅仅一条语句就可以了
3.混合类型的复制:mysql默认使用基于语句的复制,当基于语句的复制会引发问题的时候就会使用基于行的复制,mysql会自动进行选择
mysql主从复制架构,读操作可以在所有的服务器上面进行,而写操作只能在主服务器上面进行,主从复制架构给读操作提供了扩展,当写操作也比较多,同时多台从服务器还要从主服务器上面同步数据,单主模型的复制中主服务器势必会成为性能瓶颈
主服务器上面的任何修改都会保存在二进制日志Binary log里面,从服务器上面启动一个I/O thread实际上面就是一个主服务器的客户端进程,连接到主服务器上面请求读取二进制日志,然后把读取到的二进制日志写到本地的一个Realy log里面,从服务器上面开启一个SQL thread定时检查Realy log,如果发现有更改立即把更改的内容在本机上面执行一遍
复制通常用来创建主节点的副本,通过添加冗余节点来保证高可用性,当然复制也可以用于其他用途,例如在从节点上进行数据读、分析等等。在横向扩展的业务中,复制很容易实施,主要表现在在利用主节点进行写操作,多个从节点进行读操作,mysql复制的异步性是指:事物首先在主节点上提交,然后复制给从节点并在从节点上应用,这样意味着在同一个时间点主从上的数据可能不一致,异步复制的好处在于它比同步复制要快,如果对数据的一致性要求很高,还是采用同步复制较好。
最简单的复制模式就是一主一从的复制模式了,这样一个简单的架构只需要三个步骤即可完成:
1 建立一个主节点,开启binlog,设置服务器id
2 建立一个从节点,设置服务器id
3 将从节点连接到主节点上
下面我们开始操作,以mysql5.1.61为例,操作系统redhat6.3,master 192.168.0.1 slave 192.168.0.2
tar zxvf mysql-5.0.56.tar.gz -C /usr/local
cd /usr/local
./configure && make && make install
master机器
master上面开启binlog日志,并且设置一个唯一的服务器id,在局域网内这个id必须唯一。二进制的binlog日志记录master上的所有数据库改变,这个日志会被复制到从节点上,并且在从节点上回放。修改my.cnf文件,在mysqld模块下修改如下内容:
[mysqld]
server-id = 100
log_bin = mysql-bin
log_bin设置二进制日志所产生文件的基本名称,二进制日志由一系列文件组成,log_bin的值是可选项,如果没有为log_bin设置值,则默认值是:主机名-bin。如果随便修改主机名,则binlog日志的名称也会被改变的。
server-id是用来唯一标识一个服务器的,每个服务器的server-id都不一样。这样slave连接到master后,会请求master将所有的binlog传递给它,然后将这些binlog在slave上回放。为了防止权限混乱,一般都是建立一个单独用于复制的账户。
create user backup;
grant replication slave on *.* to backup identified by '123456';
binlog是复制过程的关键,它记录了数据库的所有改变,通常即将执行完毕的语句会在binlog日志的末尾写入一条记录,binlog只记录改变数据库的语句,对于不改变数据库的语句则不进行记录。这种情况叫做基于语句的复制,还有一种情况是基于行的复制,两种模式各有各的优缺点。
slave机器
slave机器和master一样,需要一个唯一的server-id
[mysqld]
server-id = 200
连接slave到master
在master和slave都已经配置好后,只需要把slave指向master即可
change master to
master_host='192.168.0.1',master_port=3306,master_user='backup',master_password='123456';
start slave;
接下来在master上做一些针对改变数据库的操作,来观察slave的变化情况。在修改完my.cnf配置重启数据库后,就开始记录binlog了。可以在/usr/local/mysql/var目录下看到一个mysql-bin.000001文件,而且还有一个mysql-bin.index文件,这个mysql-bin.index文件是什么?这个文件保存了所有的binlog文件列表,但是我们在配置文件中并没有设置改值,这个可以通过log_bin_index进行设置,如果没有设置改值,则默认值和log_bin一样。在master上执行show binlog events命令,可以看到第一个binlog文件的内容。
mysql> show binlog events\G
*************************** 1. row ***************************
Log_name: mysql-bin.000001
Pos: 4
Event_type: Format_desc
Server_id: 100
End_log_pos: 106
Info: Server ver: 5.1.61-log, Binlog ver: 4
*************************** 2. row ***************************
Log_name: mysql-bin.000001
Pos: 106
Event_type: Stop
Server_id: 100
End_log_pos: 125
Info:
2 rows in set (0.01 sec)
Log_name 是二进制日志文件的名称,一个事件不能横跨两个文件
Pos 这是该事件在文件中的开始位置
Event_type 事件的类型,事件类型是给slave传递信息的基本方法,每个新的binlog都已Format_desc类型开始,以Rotate类型结束
Server_id 创建该事件的服务器id
End_log_pos 该事件的结束位置,也是下一个事件的开始位置,因此事件范围为Pos~End_log_pos-1
Info 事件信息的可读文本,不同的事件有不同的信息
在master的test库中创建一个t1表,并插入一条记录。
create table t1(name var);
insert into t1 values ("hai");
flush logs;
flush logs命令强制轮转日志,生成一个新的二进制日志,可以通过show binlog events in '***'来查看该二进制日志。可以通过show master status查看当前正在写入的binlog文件。这样就会在slave上执行相应的改变操作。
上面就是最简单的主从复制模式,不过有时候随着时间的推进,binlog会变得非常庞大,如果新增加一台slave,从头开始复制master的binlog文件是非常耗时的,所以我们可以从一个指定的位置开始复制binlog日志,可以通过其他方法把以前的binlog文件进行快速复制,例如copy物理文件。在change master to中有两个参数可以实现该功能,master_log_file和master_log_pos,通过这两个参数指定binlog文件及其位置。我们可以从master上复制也可以从slave上复制,假如我们是从master上复制,具体操作过程如下:
1 为了防止在操作过程中数据更新,导致数据不一致,所以需要先刷新数据并锁定数据库:flush tables with read lock
2 检查当前的binlog文件及其位置:show master status
mysql> show master status;
*************************** 1. row ***************************
File: mysql-bin.000003
Position: 107
Binlog_Do_DB:
Binlog_Ignore_DB:
1 row in set (0.00 sec)
3 通过mysqldump命令创建数据库的逻辑备分:mysqldump --all-databases -hlocalhost -p >back.sql
4 有了master的逻辑备份后,对数据库进行解锁:unlock tables
5 把back.sql复制到新的slave上,执行:mysql -hlocalhost -p <back.sql把master的逻辑备份插入slave的数据库中
6 现在可以把新的slave连接到master上了,只需要在change master to中多设置两个参数
master_log_file='mysql-bin.000003'和master_log_pos='107'即可,然后启slave:start slave,这样slave就可以接着107的位置进行复制了。
有时候master并不能让你锁住表进行复制,因为可能跑一些不间断的服务,如果这时master已经有了一个slave,我们则可以通过这个slave进行再次扩展一个新的slave。原理同在master上进行复制差不多,关键在于找到binlog的位置,你在复制的同时可能该slave也在和master进行同步,操作如下:
1 为了防止数据变动,还是需要停止slave的同步:stop slave
2 然后刷新表,并用mysqldump逻辑备份数据库
3 使用show slave status查看slave的相关信息,记录下两个字段的值Relay_Master_Log_File和
Exec_Master_Log_Pos,这个用来确定从后面哪里开始复制。
4 对slave解锁,把备份的逻辑数据库导入新的slave的数据库中,然后设置change master to,这一步和复制master一样。
转载于:https://blog.51cto.com/loose/1228505