mySql 主从复制linux配置
Posted mfmdaoyou
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mySql 主从复制linux配置相关的知识,希望对你有一定的参考价值。
总结:
[mysqld]
log-bin=mysql-bin
server-id=1
[mysqld]
log-bin=mysql-bin
server-id=2
TO backup@’192.168.1.254’
IDENTIFIED BY ‘1234’;
MariaDB [test]> change master to master_host=\'192.168.1.251\',
-> master_user=\'backup\',
-> master_password=\'1234\',
-> master_log_file=\'mysql-bin.000001\',
-> master_log_pos=0;
Query OK, 0 rows affected (0.02 sec)
MariaDB [test]> show slave status;
MariaDB [test]> START SLAVE;
Query OK, 0 rows affected (0.00 sec)
1 复制概述
Mysql内建的复制功能是构建大型,高性能应用程序的基础。将Mysql的数据分布到多个系统上去,这样的分布的机制,是通过将Mysql的某一台主机的数据拷贝到其他主机(slaves)上,并又一次运行一遍来实现的。复制过程中一个server充当主server。而一个或多个其他server充当从server。
主server将更新写入二进制日志文件,并维护文件的一个索引以跟踪日志循环。这些日志能够记录发送到从server的更新。当一个从server连接主server时。它通知主server从server在日志中读取的最后一次成功更新的位置。从server接收从那时起发生的不论什么更新,然后封锁并等待主server通知新的更新。
请注意当你进行复制时。全部对复制中的表的更新必须在主server上进行。否则,你必需要小心,以避免用户对主server上的表进行的更新与对从server上的表所进行的更新之间的冲突。
1.1 mysql支持的复制类型:
(1):基于语句的复制: 在主server上运行的SQL语句。在从server上运行相同的语句。
MySQL默认採用基于语句的复制,效率比較高。
一旦发现没法精确复制时, 会自己主动选着基于行的复制。
(2):基于行的复制:把改变的内容复制过去,而不是把命令在从server上运行一遍. 从mysql5.0開始支持
(3):混合类型的复制: 默认採用基于语句的复制,一旦发现基于语句的无法精确的复制时。就会採用基于行的复制。
1.2 . 复制解决的问题
MySQL复制技术有下面一些特点:
(1) 数据分布 (Data distribution )
(2) 负载平衡(load balancing)
(3) 备份(Backups)
(4) 高可用性和容错行 High availability and failover
1.3 复制怎样工作
总体上来说。复制有3个步骤:
(1) master将改变记录到二进制日志(binary log)中(这些记录叫做二进制日志事件。binary log events);
(2) slave将master的binary log events复制到它的中继日志(relay log)。
(3) slave重做中继日志中的事件,将改变反映它自己的数据。
下图描写叙述了复制的过程:
该过程的第一部分就是master记录二进制日志。在每一个事务更新数据完毕之前,master在二日志记录这些改变。MySQL将事务串行的写入二进制日志,即使事务中的语句都是交叉运行的。
在事件写入二进制日志完毕后,master通知存储引擎提交事务。
下一步就是slave将master的binary log复制到它自己的中继日志。首先,slave開始一个工作线程——I/O线程。I/O线程在master上打开一个普通的连接,然后開始binlog dump process。Binlog dump process从master的二进制日志中读取事件,假设已经跟上master,它会睡眠并等待master产生新的事件。
I/O线程将这些事件写入中继日志。
SQL slave thread(SQL从线程)处理该过程的最后一步。SQL线程从中继日志读取事件,并重放当中的事件而更新slave的数据。使其与master中的数据一致。仅仅要该线程与I/O线程保持一致。中继日志一般会位于OS的缓存中。所以中继日志的开销非常小。
此外。在master中也有一个工作线程:和其他MySQL的连接一样。slave在master中打开一个连接也会使得master開始一个线程。
复制过程有一个非常重要的限制——复制在slave上是串行化的,也就是说master上的并行更新操作不能在slave上并行操作。
2 .复制配置
有两台MySQL数据库serverMaster和slave,Master为主server,slave为从server。初始状态时。Master和slave中的数据信息同样,当Master中的数据发生变化时,slave也跟着发生对应的变化。使得master和slave的数据信息同步,达到备份的目的。
要点:
负责在主、从server传输各种修修改作的媒介是主server的二进制变更日志。这个日志记载着须要传输给从server的各种修修改作。
因此。主server必须激活二进制日志功能。
从server必须具备足以让它连接主server并请求主server把二进制变更日志传输给它的权限。
环境:
Master和slave的MySQL数据库版本号同为5.0.18
操作系统:unbuntu 11.10
IP地址:10.100.0.100
2.1、创建复制帐号
1、在Master的数据库中建立一个备份帐户:每一个slave使用标准的MySQLusername和password连接master。进行复制操作的用户会授予REPLICATION SLAVE权限。username的password都会存储在文本文件master.info中
命令例如以下:
mysql > GRANT REPLICATION SLAVE,RELOAD,SUPER ON *.*
TO backup@’10.100.0.200’
IDENTIFIED BY ‘1234’;
建立一个帐户backup,而且仅仅能同意从10.100.0.200这个地址上来登陆,password是1234。
(假设由于mysql版本号新旧密码算法不同。能够设置:set password for \'backup\'@\'10.100.0.200\'=old_password(\'1234\'))
2.2、拷贝数据
(假如是你全然新安装mysql主从server,这个一步就不须要。由于新安装的master和slave有同样的数据)
关停Masterserver,将Master中的数据复制到Bserver中,使得Master和slave中的数据同步,而且确保在所有设置操作结束前,禁止在Master和slaveserver中进行写操作。使得两数据库中的数据一定要同样。
2.3、配置master
接下来对master进行配置。包含打开二进制日志。指定唯一的servr ID。
比如。在配置文件增加例如以下值:
server-id=1
log-bin=mysql-bin
server-id:为主服务器A的ID值
log-bin:二进制变更日值
重新启动master,执行SHOW MASTER STATUS,输出例如以下:
2.4、配置slave
log_bin = mysql-bin
server_id = 2
relay_log = mysql-relay-bin
log_slave_updates = 1
read_only = 1
server_id是必须的,并且唯一。slave没有必要开启二进制日志。可是在一些情况下,必须设置,比如。假设slave为其他slave的master。必须设置bin_log。在这里,我们开启了二进制日志,并且显示的命名(默认名称为hostname,可是。假设hostname改变则会出现故障)。
relay_log配置中继日志,log_slave_updates表示slave将复制事件写进自己的二进制日志(后面会看到它的用处)。
有些人开启了slave的二进制日志。却没有设置log_slave_updates,然后查看slave的数据是否改变,这是一种错误的配置。
所以,尽量使用read_only,它防止改变数据(除了特殊的线程)。可是,read_only并是非常有用。特别是那些须要在slave上创建表的应用。
2.5、启动slave
接下来就是让slave连接master,并開始重做master二进制日志中的事件。你不应该用配置文件进行该操作,而应该使用CHANGE MASTER TO语句,该语句能够全然代替对配置文件的改动。并且它能够为slave指定不同的master。而不须要停止server。例如以下:
mysql> CHANGE MASTER TO MASTER_HOST=\'server1\',
-> MASTER_USER=\'repl\',
-> MASTER_PASSWORD=\'p4ssword\',
-> MASTER_LOG_FILE=\'mysql-bin.000001\',
-> MASTER_LOG_POS=0;
MASTER_LOG_POS的值为0,由于它是日志的開始位置。
你能够用SHOW SLAVE STATUS语句查看slave的设置是否正确:
mysql> SHOW SLAVE STATUS\\G
*************************** 1. row ***************************
Slave_IO_State:
Master_Host: server1
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 4
Relay_Log_File: mysql-relay-bin.000001
Relay_Log_Pos: 4
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: No
Slave_SQL_Running: No
...omitted...
Seconds_Behind_Master: NULL
Slave_IO_State, Slave_IO_Running, 和Slave_SQL_Running是No
表明slave还没有開始复制过程。
日志的位置为4而不是0,这是由于0仅仅是日志文件的開始位置,并非日志位置。实际上,MySQL知道的第一个事件的位置是4。
为了開始复制。你能够执行:
mysql> START SLAVE;
执行SHOW SLAVE STATUS查看输出结果:
mysql> SHOW SLAVE STATUS\\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: server1
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 164
Relay_Log_File: mysql-relay-bin.000001
Relay_Log_Pos: 164
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
...omitted...
Seconds_Behind_Master: 0
Slave_IO_Running=Yes
Slave_SQL_Running=Yes
slave的I/O和SQL线程都已经開始执行,并且Seconds_Behind_Master不再是NULL。日志的位置添加了,意味着一些事件被获取并执行了。
假设你在master上进行改动,你能够在slave上看到各种日志文件的位置的变化,相同,你也能够看到数据库中数据的变化。
你可查看master和slave上线程的状态。在master上,你能够看到slave的I/O线程创建的连接:
mysql> show processlist \\G *************************** 1. row *************************** Id: 1 User: root Host: localhost:2096 db: test Command: Query Time: 0 State: NULL Info: show processlist *************************** 2. row *************************** Id: 2 User: repl Host: localhost:2144 db: NULL Command: Binlog Dump Time: 1838 State: Has sent all binlog to slave; waiting for binlog to be updated Info: NULL 2 rows in set (0.00 sec) |
行2为处理slave的I/O线程的连接。
在slaveserver上执行该语句:
mysql> show processlist \\G *************************** 1. row *************************** Id: 1 User: system user Host: db: NULL Command: Connect Time: 2291 State: Waiting for master to send event Info: NULL *************************** 2. row *************************** Id: 2 User: system user Host: db: NULL Command: Connect Time: 1852 State: Has read all relay log; waiting for the slave I/O thread to update it Info: NULL *************************** 3. row *************************** Id: 5 User: root Host: localhost:2152 db: test Command: Query Time: 0 State: NULL Info: show processlist 3 rows in set (0.00 sec) |
2.5、加入新slaveserver
假如master已经执行非常久了,想对新安装的slave进行数据同步,甚至它没有master的数据。
此时,有几种方法能够使slave从还有一个服务開始,比如。从master拷贝数据,从还有一个slave克隆。从近期的备份開始一个slave。
Slave与master同步时,须要三样东西:
(1)master的某个时刻的数据快照;
(2)master当前的日志文件、以及生成快照时的字节偏移。这两个值能够叫做日志文件坐标(log file coordinate),由于它们确定了一个二进制日志的位置,你能够用SHOW MASTER STATUS命令找到日志文件的坐标。
(3)master的二进制日志文件。
能够通过下面几中方法来克隆一个slave:
(1) 冷拷贝(cold copy)
停止master。将master的文件复制到slave。然后重新启动master。缺点非常明显。
(2) 热拷贝(warm copy)
假设你仅使用MyISAM表,你能够使用mysqlhotcopy拷贝。即使server正在执行。
(3) 使用mysqldump
使用mysqldump来得到一个数据快照可分为下面几步:
<1>锁表:假设你还没有锁表,你应该对表加锁,防止其他连接改动数据库,否则。你得到的数据能够是不一致的。例如以下:
mysql> FLUSH TABLES WITH READ LOCK;
<2>在还有一个连接用mysqldump创建一个你想进行复制的数据库的转储:
shell> mysqldump --all-databases --lock-all-tables >dbdump.db
<3>对表释放锁。
mysql> UNLOCK TABLES;
3、深入了解复制
3.1、基于语句的复制(Statement-Based Replication)
master记录下改变数据的查询,然后,slave从中继日志中读取事件,并运行它,这些SQL语句与master运行的语句一样。
这样的方式的长处就是实现简单。
此外,基于语句的复制的二进制日志能够非常好的进行压缩。并且日志的数据量也较小,占用带宽少——比如,一个更新GB的数据的查询仅须要几十个字节的二进制日志。而mysqlbinlog对于基于语句的日志处理十分方便。
可是。基于语句的复制并非像它看起来那么简单,由于一些查询语句依赖于master的特定条件,比如。master与slave可能有不同的时间。所以,MySQL的二进制日志的格式不不过查询语句,还包含一些元数据信息。比如,当前的时间戳。
即使如此,还是有一些语句,比方,CURRENT USER函数。不能正确的进行复制。
此外。存储过程和触发器也是一个问题。
另外一个问题就是基于语句的复制必须是串行化的。
这要求大量特殊的代码。配置,比如InnoDB的next-key锁等。并非全部的存储引擎都支持基于语句的复制。
3.2、基于记录的复制(Row-Based Replication)
这样的方式有长处,也有缺点。长处就是能够对不论什么语句都能正确工作。一些语句的效率更高。基本的缺点就是二进制日志可能会非常大,并且不直观,所以。你不能使用mysqlbinlog来查看二进制日志。
对于一些语句。基于记录的复制可以更有效的工作,如:
mysql> INSERT INTO summary_table(col1, col2, sum_col3)
-> SELECT col1, col2, sum(col3)
-> FROM enormous_table
-> GROUP BY col1, col2;
如果,仅仅有三种唯一的col1和col2的组合。可是。该查询会扫描原表的很多行。却仅返回三条记录。
此时,基于记录的复制效率更高。
还有一方面。以下的语句,基于语句的复制更有效:
mysql> UPDATE enormous_table SET col1 = 0;
此时使用基于记录的复制代价会非常高。因为两种方式不能对全部情况都能非常好的处理,所以,MySQL 5.1支持在基于语句的复制和基于记录的复制之前动态交换。你能够通过设置session变量binlog_format来进行控制。
3.3、复制相关的文件
(1)mysql-bin.index
它用于跟踪磁盘上存在哪些二进制日志文件。MySQL用它来定位二进制日志文件。它的内容例如以下(我的机器上):
(2)mysql-relay-bin.index
内容例如以下:
.\\mysql-02-relay-bin.000017
.\\mysql-02-relay-bin.000018
(3)master.info
不要删除它,否则,slave重新启动后不能连接master。内容例如以下(我的机器上):
MySQL的主从复制