您的位置:首页 > 数据库 > MySQL

Mysql主从

2016-01-19 14:49 555 查看
Mysql主从

原理:

首先必须打开Master端的二进制日志 Binary Log(mysql-bin.xxxxxx)功能,否则无法实现。整个复制过程就是Slave从Master端获取该日志然后在自身上完全按顺序的执行日志中所记录的操作。可以通过在启动Mysql Server的过程中使用“--log-bin”参数选项,或者在my.cnf配置文件中的[mysqld]参数组增加“log-bin”参数项。

(1)    master将数据改变记录到二进制日志(binary log)中(这些记录叫做二进制日志事件,binary log events);

(2)    slave将master的binary log events拷贝到它的中继日志(relay log);

(3)    slave重做中继日志中的事件,将改变反映它自己的数据。



MySQL 复制的基本过程如下:

            1.master记录二进制日志。在每个事务更新数据完成之前,master在二进制日志记录这些改变。MySQL将事务串行的写入二进制日志,即使事务中的语句都是交叉执行的。在事件写入二进制日志完成后,master通知存储引擎提交事务。

            2.slave将master的binary log拷贝到它自己的中继日志。首先,slave开起一个工作线程——I/O线程。I/O线程在master上打开一个普通的连接,并请求从指定日志文件的指定位置(或者从最开始的日志)之后的日志内容,Master 接收到来自 Slave 的 IO 线程的请求后会使得master开起一个线程,通过该负责复制的线程(binlog
dump process)根据请求信息读取master的二进制日志中指定位置之后的日志信息(也就是事件),返回给 Slave 端的 IO 线程。返回信息中除了日志所包含的信息之外,还包括本次返回的信息在 Master 端的 Binary Log 文件的名称以及在 Binary Log 中的位置。

            3.Slave 的 IO 线程接收到信息后,将接收到的日志内容依次写入到 Slave 端的Relay Log文件(mysql-relay-bin.xxxxxx)的最末端(也就是中继日志中),并将读取到的Master端的bin-log的文件名和位置记录到master- info文件中,以便在下一次读取的时候能够清楚的告诉Master要从哪个bin-log的哪个位置开始往后的日志内容读取。如果已经跟上master,它会睡眠并等待master产生新的事件,I/O线程再将这些事件写入中继日志。

            4.slave的SQL线程检测到 Relay Log 中新增加了内容后,会马上解析该 Log 文件中的内容成为在 Master 端真实执行时候的那些可执行的语句,并在自身执行这些语句而更新slave的数据(实际上就是在 Master 端和 Slave 端执行了同样的操作,所以两端的数据是完全一样的。),使其与master中的数据一致。只要该线程与I/O线程保持一致,中继日志通常会位于OS的缓存中,所以中继日志的开销很小。

       *****复制过程有一个很重要的限制——复制在slave上是串行化的,也就是说master上的并行更新操作不能在slave上并行操作。


复制解决的问题

         MySQL复制技术有以下一些特点:

         (1)    数据分布 (Data distribution )

         (2)    负载平衡(load balancing)

         (3)    备份(Backups) 

         (4)    高可用性和容错行 High availability and failover

mysql复制主要有三种方式:基于SQL语句的复制(statement-based replication, SBR),基于行的复制(row-based replication, RBR),混合模式复制(mixed-based replication, MBR)。

(1):基于语句的复制:  在主服务器上执行的SQL语句,在从服务器上执行同样的语句。MySQL默认采用基于语句的复制,效率比较高。  

(2):基于行的复制:把改变的内容复制过去,而不是把命令在从服务器上执行一遍. 从mysql5.0开始支持

(3):混合类型的复制: 默认采用基于语句的复制,一旦发现基于语句的无法精确的复制时,就会采用基于行的复制

安装前的准备:

# yum install gcc gcc-c++ ncurses-devel bison -y

# tar zxf /root/cmake-2.8.4.tar.gz -C /usr/local/src

# tar zxf /root/mysql-5.5.25.tar.gz -C /usr/local/src

 

# cd /usr/local/src/cmake-2.8.4/

# ./configure   //检查安装环境,指定安装选项

# gmake

# make install

 

创建用户

# useradd -s /sbin/nologin mysql

创建保存数据的目录:

# mkdir /data/mysql -pv

# mkdir /data/mysql/binlog/ -pv

# chown mysql.mysql /data/mysql

 

# cd /usr/local/src/mysql-5.5.25

# cmake ./

# make && make install

 

复制启动脚本

# cp /usr/local/src/mysql-5.5.25/support-files/mysql.server /etc/init.d/mysqld

# chmod +x /etc/init.d/mysqld

复制配置文件

# cp /etc/my.cnf /etc/my.cnf.bak

# cp /usr/local/src/mysql-5.5.25/support-files/my-medium.cnf /etc/my.cnf

 

# vim /etc/my.cnf

在[mysqld]下面加入以下内容

user = mysql

basedir = /usr/local/mysql

datadir = /data/mysql/

log-error = /data/mysql/mysql_error.log

pid-file = /data/mysql/mysql.pid

 

 

初始化数据库:

# cd /usr/local/src/mysql-5.5.25/scripts

# chmod +x mysql_install_db

# ./mysql_install_db --user=mysql --basedir=/usr/local/mysql/ --datadir=/data/mysql/

#/etc/init.d/mysqld start

# echo "export PATH=$PATH:/usr/local/mysql/bin " >>/etc/profile

//将mysql的命令所在路径添加到path变量中

# source /etc/profile

# ln -s /usr/local/mysql/bin/mysql /bin/

# chkconfig --add mysqld   

# chkconfig mysqld on                                             (#chkconfig --level 35 mysql on)

 

 

主master配置:

#vim /etc/my.cnf

server-id = 1                       //这个要有了就不用加了

log-bin=/data/mysql/binlog/mysql-binlog                 //这个要有了就不用加了,log-bin:表示开启二进制日志

binlog_format=mixed             ////binlog日志格式,mysql默认采用statement,建议使用mixed    (binlog的格式有3种最下方有详解)

skip-name-resolve                 //grant时,必须使用ip不能使用主机名,快速登录跳过用户解析(最下方有详解)
binlog-do-db = db1             //过滤哪些库需要主从复制,尽量在从库做设置,主库上不做这样的设置
binlog-do-db = db2      

binlog-do-db = db3

*****
在Master的数据库中建立一个备份帐户:每个slave使用标准的MySQL用户名和密码连接master。进行复制操作的用户会授予REPLICATION SLAVE权限。用户名的密码都会存储在文本文件master.info中

mysql>grant replication slave on *.* to slave@10.10.9.242 identified by 'slave';

mysql>flush privileges;

mysql> show master status;

 

***** mysql>flush privileges;

mysql 新设置用户或更改密码后需用flush privileges刷新MySQL的系统权限相关表,否则会出现拒绝访问,还有一种方法,就是重新启动mysql服务器,来使新设置生效。

***** mysql> flush tables with read lock; //给所有的表加上读锁,为了保证数据的一致性

*****mysql> show variables like 'server_id'//查看server_id

*****mysql> set global server_id=2 //此处数值和my.cnf里设置的一样就行

***** # mysqladmin -uroot password '123'   //给root设置密码

******  # mysqladmin -uroot -p123 password '456' //给root重新设置密码

***mysql在启动的时候会查找/etc/my.cnf,DATADIR/my.cnf,USER_HOME/my.cnf

 

从slave配置:

 

# vim /etc/my.cnf 

 

 

server-id = 2                 //把这个变成2,和主库不一样就好

skip-slave-start   //加上这个进程,slave复制进程就不随mysql启动而启动

relay_log=/data/mysql/log/binlog/mysql-realy-binlog //中继日志

replicate-wild-ignore-table=mysql.%          //复制时忽略数据库及表,尽量用这种方式过滤掉不想复制的库及表
replicate-wild-ignore-table=test.%//复制时忽略数据库及表
replicate-wild-ignore-table=information_schema.%  //复制时忽略数据库及表

 

mysql> change master to master_host="10.10.9.241",master_port=3306,master_user="slave",master_password="slave",,master_log_file="mysql-bin.000003",master_log_pos=255;

mysql>slave start;   //开启从服务器

mysql> show slave status\G;    //确保这两行是Yes

    Slave_IO_Running: Yes

    Slave_SQL_Running: Yes

——————————————————————————————————————————————————————

所谓反向解析是这样的:

mysql接收到连接请求后,获得的是客户端的ip,为了更好的匹配mysql.user里的权限记录(某些是用hostname定义的)。

如果mysql服务器设置了dns服务器,并且客户端ip在dns上并没有相应的hostname,那么这个过程很慢,导致连接等待。

添加skip-name-resolve以后就跳过着一个过程了。



——————————————————————————————————————————————————————————

在5.1版本时,为解决中文乱码问题设置默认字符集为utf8时,在my.cnf里的 [mysqld] 项中可以这么写:

     

          default-character-set=utf8  

 

但5.5版本, [mysql] 项内不可以这么写了,而是必须写成:

 

              character-set-server=utf8 

  否则在启动MySQL服务时会错误:Starting MySQL..The server quit without updating PID file ([FAILED]sql/mysql.pid).

——————————————————————————————————————————————————————————

binlog的格式也有三种:STATEMENT,ROW,MIXED。

① STATEMENT模式(SBR)

每一条会修改数据的sql语句会记录到binlog中。优点是并不需要记录每一条sql语句和每一行的数据变化,减少了binlog日志量,节约IO,提高性能。缺点是在某些情况下会导致master-slave中的数据不一致(如sleep()函数, last_insert_id(),以及user-defined functions(udf)等会出现问题)

② ROW模式(RBR)

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

③ MIXED模式(MBR)

以上两种模式的混合使用,一般的复制使用STATEMENT模式保存binlog,对于STATEMENT模式无法复制的操作使用ROW模式保存binlog,MySQL会根据执行的SQL语句选择日志保存方式。
 。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: