-
高性能Mysql主从架构的复制原理及配置详解
2012-03-06 07:46:32温习《高性能MySQL》的复制篇. 1 复制概述 Mysql内建的复制功能是构建大型,高性能应用程序的基础。将Mysql的数据分布到多个系统上去,这种分布的机制,是通过将Mysql的某一台主机的数据复制到其它主机(slaves)...温习《高性能MySQL》的复制篇.
1 复制概述
Mysql内建的复制功能是构建大型,高性能应用程序的基础。将Mysql的数据分布到多个系统上去,这种分布的机制,是通过将Mysql的某一台主机的数据复制到其它主机(slaves)上,并重新执行一遍来实现的。复制过程中一个服务器充当主服务器,而一个或多个其它服务器充当从服务器。主服务器将更新写入二进制日志文件,并维护文件的一个索引以跟踪日志循环。这些日志可以记录发送到从服务器的更新。当一个从服务器连接主服务器时,它通知主服务器从服务器在日志中读取的最后一次成功更新的位置。从服务器接收从那时起发生的任何更新,然后封锁并等待主服务器通知新的更新。
请注意当你进行复制时,所有对复制中的表的更新必须在主服务器上进行。否则,你必须要小心,以避免用户对主服务器上的表进行的更新与对从服务器上的表所进行的更新之间的冲突。
1.1 mysql支持的复制类型:
(1):基于语句的复制: 在主服务器上执行的SQL语句,在从服务器上执行同样的语句。MySQL默认采用基于语句的复制,效率比较高。
一旦发现没法精确复制时, 会自动选着基于行的复制。
(2):基于行的复制:把改变的内容复制过去,而不是把命令在从服务器上执行一遍. 从mysql5.0开始支持
(3):混合类型的复制: 默认采用基于语句的复制,一旦发现基于语句的无法精确的复制时,就会采用基于行的复制。1.2 . 复制解决的问题
MySQL复制技术有以下一些特点:
(1) 数据分布 (Data distribution )
(2) 负载平衡(load balancing)
(3) 备份(Backups)
(4) 高可用性和容错行 High availability and failover1.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数据库服务器Master和slave,Master为主服务器,slave为从服务器,初始状态时,Master和slave中的数据信息相同,当Master中的数据发生变化时,slave也跟着发生相应的变化,使得master和slave的数据信息同步,达到备份的目的。
要点:
负责在主、从服务器传输各种修改动作的媒介是主服务器的二进制变更日志,这个日志记载着需要传输给从服务器的各种修改动作。因此,主服务器必须激活二进制日志功能。从服务器必须具备足以让它连接主服务器并请求主服务器把二进制变更日志传输给它的权限。
环境:
Master和slave的MySQL数据库版本同为5.0.18
IP地址:10.100.0.1002.1、创建复制帐号
1、在Master的数据库中建立一个备份帐户:每个slave使用标准的MySQL用户名和密码连接master。进行复制操作的用户会授予REPLICATION SLAVE权限。用户名的密码都会存储在文本文件master.info中
命令如下:
mysql > GRANT REPLICATION SLAVE,RELOAD,SUPER ON *.*
TO backup@’10.100.0.200’
IDENTIFIED BY ‘1234’;建立一个帐户backup,并且只能允许从10.100.0.200这个地址上来登陆,密码是1234。
(如果因为mysql版本新旧密码算法不同,可以设置:set password for 'backup'@'10.100.0.200'=old_password('1234'))
2.2、拷贝数据
(假如是你完全新安装mysql主从服务器,这个一步就不需要。因为新安装的master和slave有相同的数据)
关停Master服务器,将Master中的数据拷贝到B服务器中,使得Master和slave中的数据同步,并且确保在全部设置操作结束前,禁止在Master和slave服务器中进行写操作,使得两数据库中的数据一定要相同!
2.3、配置master
接下来对master进行配置,包括打开二进制日志,指定唯一的servr ID。例如,在配置文件加入如下值:
server-id=1
log-bin=mysql-binserver-id:为主服务器A的ID值
log-bin:二进制变更日值重启master,运行SHOW MASTER STATUS,输出如下:
2.4、配置slave
Slave的配置与master类似,你同样需要重启slave的MySQL。如下:
log_bin = mysql-bin
server_id = 2
relay_log = mysql-relay-bin
log_slave_updates = 1
read_only = 1
server_id:是必须的,而且唯一。log_bin:slave没有必要开启二进制日志bin_log,但是在一些情况下,必须设置,例如,如果slave为其它slave的master,必须设置bin_log。在这里,我们开启了二进制日志,而且显示的命名(默认名称为hostname,但是,如果hostname改变则会出现问题)。
relay_log:配置中继日志,log_slave_updates表示slave将复制事件写进自己的二进制日志(后面会看到它的用处)。
有些人开启了slave的二进制日志,却没有设置log_slave_updates,然后查看slave的数据是否改变,这是一种错误的配置。read_only:尽量使用read_only,它防止改变数据(除了特殊的线程)。但是,read_only并是很实用,特别是那些需要在slave上创建表的应用。
2.5、启动slave
接下来就是让slave连接master,并开始重做master二进制日志中的事件。你不应该用配置文件进行该操作,而应该使用CHANGE MASTER TO语句,该语句可以完全取代对配置文件的修改,而且它可以为slave指定不同的master,而不需要停止服务器。如下:
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=Yesslave的I/O和SQL线程都已经开始运行,而且Seconds_Behind_Master不再是NULL。日志的位置增加了,意味着一些事件被获取并执行了。如果你在master上进行修改,你可以在slave上看到各种日志文件的位置的变化,同样,你也可以看到数据库中数据的变化。
你可查看master和slave上线程的状态。在master上,你可以看到slave的I/O线程创建的连接:
在master上输入show processlist\G;
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线程的连接。
在slave服务器上运行该语句:
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)
行1为I/O线程状态,行2为SQL线程状态。
2.5、添加新slave服务器
假如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拷贝,即使服务器正在运行。
(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)
MySQL 5.0及之前的版本仅支持基于语句的复制(也叫做逻辑复制,logical replication),这在数据库并不常见。master记录下改变数据的查询,然后,slave从中继日志中读取事件,并执行它,这些SQL语句与master执行的语句一样。
这种方式的优点就是实现简单。此外,基于语句的复制的二进制日志可以很好的进行压缩,而且日志的数据量也较小,占用带宽少——例如,一个更新GB的数据的查询仅需要几十个字节的二进制日志。而mysqlbinlog对于基于语句的日志处理十分方便。
但是,基于语句的复制并不是像它看起来那么简单,因为一些查询语句依赖于master的特定条件,例如,master与slave可能有不同的时间。所以,MySQL的二进制日志的格式不仅仅是查询语句,还包括一些元数据信息,例如,当前的时间戳。即使如此,还是有一些语句,比如,CURRENT USER函数,不能正确的进行复制。此外,存储过程和触发器也是一个问题。
另外一个问题就是基于语句的复制必须是串行化的。这要求大量特殊的代码,配置,例如InnoDB的next-key锁等。并不是所有的存储引擎都支持基于语句的复制。3.2、基于记录的复制(Row-Based Replication)
MySQL增加基于记录的复制,在二进制日志中记录下实际数据的改变,这与其它一些DBMS的实现方式类似。这种方式有优点,也有缺点。优点就是可以对任何语句都能正确工作,一些语句的效率更高。主要的缺点就是二进制日志可能会很大,而且不直观,所以,你不能使用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
服务器一旦开启二进制日志,会产生一个与二日志文件同名,但是以.index结尾的文件。它用于跟踪磁盘上存在哪些二进制日志文件。MySQL用它来定位二进制日志文件。它的内容如下(我的机器上):
(2)mysql-relay-bin.index
该文件的功能与mysql-bin.index类似,但是它是针对中继日志,而不是二进制日志。内容如下:
.\mysql-02-relay-bin.000017
.\mysql-02-relay-bin.000018(3)master.info
保存master的相关信息。不要删除它,否则,slave重启后不能连接master。内容如下(我的机器上):
I/O线程更新master.info文件,内容如下(我的机器上):
.\mysql-02-relay-bin.000019
254
mysql-01-bin.000010
286
0
52813
(4)relay-log.info
包含slave中当前二进制日志和中继日志的信息。
3.4、发送复制事件到其它slave
当设置log_slave_updates时,你可以让slave扮演其它slave的master。此时,slave把SQL线程执行的事件写进行自己的二进制日志(binary log),然后,它的slave可以获取这些事件并执行它。如下:
3.5、复制过滤(Replication Filters)
复制过滤可以让你只复制服务器中的一部分数据,有两种复制过滤:在master上过滤二进制日志中的事件;在slave上过滤中继日志中的事件。如下:
4、复制的常用拓扑结构
复制的体系结构有以下一些基本原则:
(1) 每个slave只能有一个master;
(2) 每个slave只能有一个唯一的服务器ID;
(3) 每个master可以有很多slave;
(4) 如果你设置log_slave_updates,slave可以是其它slave的master,从而扩散master的更新。MySQL不支持多主服务器复制(Multimaster Replication)——即一个slave可以有多个master。但是,通过一些简单的组合,我们却可以建立灵活而强大的复制体系结构。
4.1、单一master和多slave
由一个master和一个slave组成复制系统是最简单的情况。Slave之间并不相互通信,只能与master进行通信。
在实际应用场景中,MySQL复制90%以上都是一个Master复制到一个或者多个Slave的架构模式,主要用于读压力比较大的应用的数据库端廉价扩展解决方案。因为只要Master和Slave的压力不是太大(尤其是Slave端压力)的话,异步复制的延时一般都很少很少。尤其是自从Slave端的复制方式改成两个线程处理之后,更是减小了Slave端的延时问题。而带来的效益是,对于数据实时性要求不是特别Critical的应用,只需要通过廉价的pcserver来扩展Slave的数量,将读压力分散到多台Slave的机器上面,即可通过分散单台数据库服务器的读压力来解决数据库端的读性能瓶颈,毕竟在大多数数据库应用系统中的读压力还是要比写压力大很多。这在很大程度上解决了目前很多中小型网站的数据库压力瓶颈问题,甚至有些大型网站也在使用类似方案解决数据库瓶颈。
如下:
如果写操作较少,而读操作很时,可以采取这种结构。你可以将读操作分布到其它的slave,从而减小master的压力。但是,当slave增加到一定数量时,slave对master的负载以及网络带宽都会成为一个严重的问题。
这种结构虽然简单,但是,它却非常灵活,足够满足大多数应用需求。一些建议:
(1) 不同的slave扮演不同的作用(例如使用不同的索引,或者不同的存储引擎);
(2) 用一个slave作为备用master,只进行复制;
(3) 用一个远程的slave,用于灾难恢复;大家应该都比较清楚,从一个Master节点可以复制出多个Slave节点,可能有人会想,那一个Slave节点是否可以从多个Master节点上面进行复制呢?至少在目前来看,MySQL是做不到的,以后是否会支持就不清楚了。
MySQL不支持一个Slave节点从多个Master节点来进行复制的架构,主要是为了避免冲突的问题,防止多个数据源之间的数据出现冲突,而造成最后数据的不一致性。不过听说已经有人开发了相关的patch,让MySQL支持一个Slave节点从多个Master结点作为数据源来进行复制,这也正是MySQL开源的性质所带来的好处。
4.2、主动模式的Master-Master(Master-Master in Active-Active Mode)
Master-Master复制的两台服务器,既是master,又是另一台服务器的slave。这样,任何一方所做的变更,都会通过复制应用到另外一方的数据库中。
可能有些读者朋友会有一个担心,这样搭建复制环境之后,难道不会造成两台MySQL之间的循环复制么?实际上MySQL自己早就想到了这一点,所以在MySQL的BinaryLog中记录了当前MySQL的server-id,而且这个参数也是我们搭建MySQLReplication的时候必须明确指定,而且Master和Slave的server-id参数值比需要不一致才能使MySQLReplication搭建成功。一旦有了server-id的值之后,MySQL就很容易判断某个变更是从哪一个MySQLServer最初产生的,所以就很容易避免出现循环复制的情况。而且,如果我们不打开记录Slave的BinaryLog的选项(--log-slave-update)的时候,MySQL根本就不会记录复制过程中的变更到BinaryLog中,就更不用担心可能会出现循环复制的情形了。
如图:
主动的Master-Master复制有一些特殊的用处。例如,地理上分布的两个部分都需要自己的可写的数据副本。这种结构最大的问题就是更新冲突。假设一个表只有一行(一列)的数据,其值为1,如果两个服务器分别同时执行如下语句:
在第一个服务器上执行:
mysql> UPDATE tbl SET col=col + 1;
在第二个服务器上执行:
mysql> UPDATE tbl SET col=col * 2;
那么结果是多少呢?一台服务器是4,另一个服务器是3,但是,这并不会产生错误。
实际上,MySQL并不支持其它一些DBMS支持的多主服务器复制(Multimaster Replication),这是MySQL的复制功能很大的一个限制(多主服务器的难点在于解决更新冲突),但是,如果你实在有这种需求,你可以采用MySQL Cluster,以及将Cluster和Replication结合起来,可以建立强大的高性能的数据库平台。但是,可以通过其它一些方式来模拟这种多主服务器的复制。4.3、主动-被动模式的Master-Master(Master-Master in Active-Passive Mode)
这是master-master结构变化而来的,它避免了M-M的缺点,实际上,这是一种具有容错和高可用性的系统。它的不同点在于其中一个服务只能进行只读操作。如图:
4.4 级联复制架构 Master –Slaves - Slaves
在有些应用场景中,可能读写压力差别比较大,读压力特别的大,一个Master可能需要上10台甚至更多的Slave才能够支撑注读的压力。这时候,Master就会比较吃力了,因为仅仅连上来的SlaveIO线程就比较多了,这样写的压力稍微大一点的时候,Master端因为复制就会消耗较多的资源,很容易造成复制的延时。
遇到这种情况如何解决呢?这时候我们就可以利用MySQL可以在Slave端记录复制所产生变更的BinaryLog信息的功能,也就是打开—log-slave-update选项。然后,通过二级(或者是更多级别)复制来减少Master端因为复制所带来的压力。也就是说,我们首先通过少数几台MySQL从Master来进行复制,这几台机器我们姑且称之为第一级Slave集群,然后其他的Slave再从第一级Slave集群来进行复制。从第一级Slave进行复制的Slave,我称之为第二级Slave集群。如果有需要,我们可以继续往下增加更多层次的复制。这样,我们很容易就控制了每一台MySQL上面所附属Slave的数量。这种架构我称之为Master-Slaves-Slaves架构
这种多层级联复制的架构,很容易就解决了Master端因为附属Slave太多而成为瓶颈的风险。下图展示了多层级联复制的Replication架构。
当然,如果条件允许,我更倾向于建议大家通过拆分成多个Replication集群来解决
上述瓶颈问题。毕竟Slave并没有减少写的量,所有Slave实际上仍然还是应用了所有的数据变更操作,没有减少任何写IO。相反,Slave越多,整个集群的写IO总量也就会越多,我们没有非常明显的感觉,仅仅只是因为分散到了多台机器上面,所以不是很容易表现出来。
此外,增加复制的级联层次,同一个变更传到最底层的Slave所需要经过的MySQL也会更多,同样可能造成延时较长的风险。
而如果我们通过分拆集群的方式来解决的话,可能就会要好很多了,当然,分拆集群也需要更复杂的技术和更复杂的应用系统架构。
4.5、带从服务器的Master-Master结构(Master-Master with Slaves)
这种结构的优点就是提供了冗余。在地理上分布的复制结构,它不存在单一节点故障问题,而且还可以将读密集型的请求放到slave上。
级联复制在一定程度上面确实解决了Master因为所附属的Slave过多而成为瓶颈的问题,但是他并不能解决人工维护和出现异常需要切换后可能存在重新搭建Replication的问题。这样就很自然的引申出了DualMaster与级联复制结合的Replication架构,我称之为Master-Master-Slaves架构
和Master-Slaves-Slaves架构相比,区别仅仅只是将第一级Slave集群换成了一台单独的Master,作为备用Master,然后再从这个备用的Master进行复制到一个Slave集群。
这种DualMaster与级联复制结合的架构,最大的好处就是既可以避免主Master的写入操作不会受到Slave集群的复制所带来的影响,同时主Master需要切换的时候也基本上不会出现重搭Replication的情况。但是,这个架构也有一个弊端,那就是备用的Master有可能成为瓶颈,因为如果后面的Slave集群比较大的话,备用Master可能会因为过多的SlaveIO线程请求而成为瓶颈。当然,该备用Master不提供任何的读服务的时候,瓶颈出现的可能性并不是特别高,如果出现瓶颈,也可以在备用Master后面再次进行级联复制,架设多层Slave集群。当然,级联复制的级别越多,Slave集群可能出现的数据延时也会更为明显,所以考虑使用多层级联复制之前,也需要评估数据延时对应用系统的影响。
5、复制的常见问题
错误一:change master导致的:
Last_IO_Error: error connecting to master 'repl1@IP:3306' - retry-time: 60 retries错误二:在没有解锁的情况下停止slave进程:
mysql> stop slave;
ERROR 1192 (HY000): Can't execute the given command because you have active locked tables or an active transaction错误三:在没有停止slave进程的情况下change master
mysql> change master to master_host=‘IP', master_user='USER', master_password='PASSWD', master_log_file='mysql-bin.000001',master_log_pos=106;
ERROR 1198 (HY000): This operation cannot be performed with a running slave; run STOP SLAVE first错误四:A B的server-id相同:
Last_IO_Error: Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids;
these ids must be different for replication to work (or the --replicate-same-server-id option must be used on
slave but this does not always make sense; please check the manual before using it).
查看server-id
mysql> show variables like 'server_id';
手动修改server-id
mysql> set global server_id=2; #此处的数值和my.cnf里设置的一样就行
mysql> slave start;错误五:change master之后,查看slave的状态,发现slave_IO_running 仍为NO
需要注意的是,上述几个错误做完操作之后要重启mysql进程,slave_IO_running 变为Yes错误六:MySQL主从同步异常Client requested master to start replication from position > file size
字面理解:从库的读取binlog的位置大于主库当前binglog的值
这一般是主库重启导致的问题,主库从参数sync_binlog默认为1000,即主库的数据是先缓存到1000条后统一fsync到磁盘的binlog文件中。
当主库重启的时候,从库直接读取主库接着之前的位点重新拉binlog,但是主库由于没有fsync最后的binlog,所以会返回1236 的错误。
正常建议配置sync_binlog=1 也就是每个事务都立即写入到binlog文件中。1、在从库检查slave状态:
偏移量为4063315
2、在主库检查mysql-bin.001574的偏移量位置
mysqlbinlog mysql-bin.001574 > ./mysql-bin.001574.bak
tail -10 ./mysql-bin.001574.bak
mysql-bin.001574文件最后几行 发现最后偏移量是4059237,从库偏移量的4063315远大主库的偏移量4059237,也就是参数sync_binlog=1000导致的。
3、重新设置salve
mysql> stop slave;
mysql> change master to master_log_file='mysql-bin.001574' ,master_log_pos=4059237;
mysql> start slave;
错误8:数据同步异常情况
第一种:在master上删除一条记录,而slave上找不到。
Last_Error: Could not execute Delete_rows event on table market_edu.tl_player_task; Can't find record in 'tl_player_task', Error_code: 1032; handler error HA_ERR_KEY_NOT_FOUND; the event's master log mysql-bin.002094, end_log_pos 286434186
解决方法:由于master要删除一条记录,而slave上找不到故报错,这种情况主上都将其删除了,那么从机可以直接跳过。
可用命令:stop slave; set global sql_slave_skip_counter=1; start slave;
第二种:主键重复。在slave已经有该记录,又在master上插入了同一条记录。
Last_SQL_Error: Could not execute Write_rows event on table hcy.t1;
Duplicate entry '2' for key 'PRIMARY',
Error_code: 1062;
handler error HA_ERR_FOUND_DUPP_KEY; the event's master log mysql-bin.000006, end_log_pos 924解决方法:在slave删除重复的主键
第三种:在master上更新一条记录,而slave上找不到,丢失了数据。
Last_SQL_Error: Could not execute Update_rows event on table hcy.t1;
Can't find record in 't1',
Error_code: 1032;
handler error HA_ERR_KEY_NOT_FOUND; the event's master log mysql-bin.000010, end_log_pos 263解决方法:把丢失的数据在slave上填补,然后跳过报错即可。
insert into t1 values (2,'BTV');
stop slave ;set global sql_slave_skip_counter=1;start slave;
-
python 使用shutil copyfile 复制文件 反思总结
2019-04-19 17:32:43特别是,提供了支持文件复制和删除的功能。 文件复制到其他文件夹操作 shutil.copyfile(src, dst):将名为src的文件的内容(无元数据)复制到名为dst的文件中 。 dst必须是完整的目标文件名 注意:所谓完整目标文件名...shutil - 高级文件操作
该shutil模块对文件和文件集合提供了许多高级操作。特别是,提供了支持文件复制和删除的功能。
文件复制到其他文件夹操作
shutil.copyfile(src, dst)
:将名为src的文件的内容(无元数据)复制到名为dst的文件中 。 dst必须是完整的目标文件名
注意:所谓完整目标文件名包含了两层含义:- dst(destination)必须含有你复制过去的文件路径,创建路径时需要检查文件夹是否存在。
- dst中必须包含你想要创建的文件名。
简单来说,它其实是将源数据复制到在目标文件夹的文件中!,所有如果没有文件路径时,需要你先通过os.mkdir("path")
创建路径,然后在此路径下给出你想要的文件名。
一般情况下,我们应该会遇到这种问题,我们想直接将文件复制过去(类似Ctrl+C,Ctrl+V的操作),而在python中你需要进行以下操作:
- 先获取源文件的文件名(包括后缀),将此名给dst,才算创建好dst。
- 再进行copyfile操作
实例(部分代码)
argetdir_path = 'W:\Solar Radiation\Data\Data_original\Temp_data\梯度塔结果\\' + upfile Targetfile_path = 'W:\Solar Radiation\Data\Data_original\Temp_data\梯度塔结果\\' + upfile + '\\' + data_name if not os.path.exists(Targetdir_path): os.mkdir(Targetdir_path) shutil.copyfile(file, Targetfile_path)
-
linux复制/剪切文件到另一个文件夹
2018-10-31 11:27:50复制/拷贝: cp 文件名 路径 cphello.csv ./python/ml:把当前目录的hello.csv拷贝到当前目的python文件夹里的ml文件夹里 cp 源文件名 新文件名 cp hello.txt world.txt:复制并改名,并存放在当前目录下 cp file1...复制/拷贝:
cp 文件名 路径 cp hello.csv ./python/ml:把当前目录的hello.csv拷贝到当前目的python文件夹里的ml文件夹里
cp 源文件名 新文件名 cp hello.txt world.txt:复制并改名,并存放在当前目录下
cp file1 file2 复制一个文件
cp dir/* . 复制一个目录下的所有文件到当前工作目录
cp -a /tmp/dir1 . 复制一个目录到当前工作目录
cp -a dir1 dir2 复制一个目录剪切/移动:
mv 文件名 路径
mv hello.csv ./python:把当前目录的hello.csv剪切到当前目的python文件夹里
mv hello.txt ../java/ 把当前目录下的文件hello.txt剪切到上一级目录的子目录java目录里
mv hello.txt .. 把文件hello.txt移动到上一级目录
扫描下方二维码关注领取程序员必备千套ppt模板,300本精选好书,丰富面经。:
有酒有风 -
像中文的罗马音字体复制_罗马音字体大全可复制
2020-12-20 21:33:15罗马音字体大全可复制app免费版是一专门为有游戏id所取名字的工具软件,它可以让你的名字变成各种各样的特色字体亦或者是花纹,用户输入文字即可自动生成,直接复制就可以使用了,想让自己的游戏id有所不同的小伙伴...罗马音字体大全可复制app免费版是一专门为有游戏id所取名字的工具软件,它可以让你的名字变成各种各样的特色字体亦或者是花纹,用户输入文字即可自动生成,直接复制就可以使用了,想让自己的游戏id有所不同的小伙伴就赶紧来下载罗马音字体大全可复制app免费版吧!
罗马音字体大全可复制app免费版特色
1、这是一款能生成一个字id的游戏辅助软件,韩文、罗马音、繁体字均支持;
2、生成的字符还支持复制,想要让自己的游戏id与众不同吗?快来下载试试吧;
罗马音字体大全可复制app免费版怎样
1、这里整理了超多有趣的字体,喜欢的小伙伴可以来这里轻松下载感受哦,让你的玩机生活更加快乐;
2、不仅如此,后续也会一直不断的更新,而且这里有多重风格任你选择;
3、你喜欢的话都是可以轻松下载感受哦,都是可以免费体验的。
罗马音字体大全可复制app免费版点评
1、从动漫用语到热门话题,云端超转换内有200万以上丰富的日文单词转换;
2、可以直接定制相应的主题皮肤,生成的文字多样,还可以去自定义风格;
3、能够正确快速地输入平常不太会使用到的常用语,不管是学习还是工作都很有用;
4、软件还支持语音输入,输入的语音自动转换为文字,将文字转换成罗马音式的汉字。
-
mysql复制--主从复制配置
2018-04-12 00:04:36复制功能: 数据分布 负载均衡(读) 备份 高可用和故障切换 MySQL升级测试 复制方式: 主–从复制 主–主复制 半同步复制 复制原理: Mysql中有一种日志叫做bin日志(二进制... -
Vim中如何全选复制粘贴、批量注释
2015-07-30 16:37:47Vim中如何全选并复制? (区分大小写!!!) 全部删除:按esc键后,先按gg(到达顶部),然后dG 全部复制:按esc键后,先按gg,然后ggyG 全选高亮显示:按esc键后,先按gg,然后ggvG或者ggVG 单行复制:按esc... -
C语言中的复制函数(strcpy和memcpy)
2016-05-14 17:15:27PS:初学算法,开始刷leetcode,Rotate array的预备知识(写...这个不陌生,大一学C语言讲过,其一般形式为strcpy(字符数组1,字符串2)作用是将字符串2复制到字符数组1中去。 EX: strncpy(str1,str2,2);作用是将st -
像中文的罗马音字体复制_罗马音字体复制大全
2020-12-30 10:55:57罗马音字体复制大全是一款非常好用的特殊文字管理软件,罗马音字体复制大全可以为用户提供各种奇特的文字和符号,各种稀奇古怪的文字都可以生成,绝对是你取ID取网名的神器,让自己成为人群中的焦点,赶快来下载吧!... -
IDEA快捷键设置复制上一行
2017-10-28 16:14:56之前用习惯了eclipse的“ctrl+向下箭头”,复制一行,如何设置idea里这个快捷键呢 File->settings->keymap->搜索duplicate ->双击Duplicate Entire Lines 设置一下,搞定,又可以很爽... -
ID卡复制教程(使用T5577卡复制4100卡)
2017-07-16 12:58:14为了复制普通ID卡,通常采用T5577 或 EM4305卡(俗称ID白卡),其特点是内部EEPROM可读可写,修改卡内EEPROM的内容即可修改卡片对外的ID号,达到复制普通ID卡的目的。 本文以T5577卡复制普通EM4100卡。读者需具备... -
javascript 数组以及对象的深拷贝(复制数组或复制对象)的方法
2017-02-08 19:12:05javascript 数组以及对象的深拷贝(复制数组或复制对象)的方法前言在js中,数组和对象的复制如果使用=号来进行复制,那只是浅拷贝。如下图演示: 如上,arr的修改,会影响arr2的值,这显然在绝大多数情况下,并... -
虚拟机(复制网卡配置)
2020-09-09 20:06:58虚拟机(复制网卡配置) 前言 第一篇虚拟机博客啦~ 提示:以下均是个人瞎琢磨,有错望指出来,谢谢!!! 二、步骤(第一种方式:配置文件向识别的网卡兼容) 1、通过一个主机复制出多个主机 2、开启复制的主机,... -
Linux将一个文件夹或文件夹下的所有内容复制到另一个文件夹
2019-05-22 22:51:401、将一个文件夹下的所有内容复制到另一个文件夹下 cp -r /home/packageA/* /home/cp/packageB/ 或 cp -r /home/packageA/. /home/cp/packageB/ 这两种方法效果是一样的。 方法示例: 2、将一个文件夹复制到另一... -
MongoDB4.2.8副本集(复制集)环境搭建
2020-06-28 14:15:01大多数原则,即1/2原则,一个复制集集群中,如果有大于等于1/2的节点不可用的话,那么整个进群将不可写,只可读(注:实际上应该是投票权重的1/2。 3)从库无法写入 从库无法写入,使用root权限也不行,这一点与... -
最新!有道文档翻译免费获取方法,有道翻译文档复制方法,解决有道文档翻译不能复制问题
2019-03-21 11:15:47通过浏览器的 F12 开发者工具可以看到现在翻译后的内容是通过图片展示的,而之前是文字只是把复制功能禁用了而已,所以现在不管怎么处理也不能进行复制了。 这种情况下要想进行复制就需要使用图像识别功能了。 最新... -
罗马音平假字复制_罗马音平假名可复制吊字
2020-12-20 20:35:01罗马音平假名可复制吊字是一款游戏昵称生成器软件,用户可以使用这款软件来作出一些十分稀有的游戏id,有了全新的id之后你在游戏就能够瞬间变得更加的有个性,能够和别人与众不同,能够让对手和队友都羡慕不已,可以... -
cp命令——复制当前目录、复制文件夹
2019-08-09 09:59:35复制当前目录. 当前目录下既有文件夹也有文件: 当~/cptest这个文件夹已创建时,使用命令cp -r . ~/cptest/或cp -r . ~/cptest会将当前目录下的所有文件夹和文件复制到~/cptest目录下。 当~/cptest这个文件夹还未被... -
C++深复制和浅复制
2014-04-09 10:22:30对象的复制;复制构造函数;浅复制和深复制;再一个深复制的例子 -
C# 内存复制和数组复制示例
2018-03-22 16:55:54内存复制-Marshal.Copy: // 复制当前传入的数据 byte[] pcm_src = new byte[len]; // 复制数据到二进制数组 Marshal.Copy(pcm, pcm_src, 0, len);数组复制-Array.Copy:// 复制当前传入的数据 byte[] pcm_src = ... -
postgresql流复制原理、流复制和逻辑复制的区别
2019-07-19 15:21:11流复制的原理: 物理复制也叫流复制,流复制的原理是主库把预写WAL文件发送给备库,备库接收WAL文件后,根据这些WAL文件进行重放。 复制的原理: 逻辑复制也是基于WAL文件,在逻辑复制中把主库称为源端库,备库称为... -
svn可以复制文件,不可以复制文件夹!svn可以复制文件,不可以复制文件夹!
2015-09-10 23:37:53svn可以复制文件,不可以复制文件夹!svn可以复制文件,不可以复制文件夹! -
【C++】vector拷贝使用总结(深复制、浅复制)
2019-03-26 09:12:06文章目录利用赋值操作符(浅复制)利用``swap()``函数(移除复制)利用``assign()``函数(深复制)利用初始化拷贝(深复制) 利用赋值操作符(浅复制) vector<int> array{3,5,2,6,4}; vector<int> ... -
如何复制网页上不能复制的文字——三种解决方案
2020-06-11 09:44:19想必很多小伙伴遇到过这样的情况,在网上查找很多的资料,但是因为网页本身的限制不允许复制或者需要付费: 遇到这种情况应该怎么办呢?接下来,就和大家分享下如何免费复制网页上不能复制的文字! 解决方法一:... -
巧妙复制网页中的文本——复制网页上不能复制的文字
2019-02-16 09:24:53找到这篇文章的部分,把它复制下来(在这里复制是不受任何限制的) 然后在Dreamweaver CC中新建一个html文件,把刚才复制的那段粘贴到&amp;amp;lt;body&amp;amp;gt;中间 在实时视图中可以看到原... -
MySQL 8 复制(七)——组复制基本原理
2019-07-09 16:41:35一、MySQL复制技术 1. 主从复制 2. 组复制 二、组复制使用场景 三、组复制相关服务 1. 故障检测 2. 组成员服务 3. 容错 四、组复制技术细节 1. 组复制插件体系结构 2. 复制组 3. 数据操作语言(Data ... -
java语言复制数组的四种方法
2016-08-28 13:47:01JAVA语言的下面几种数组复制方法中,哪个效率最高? A.for循环逐一复制 B.System.arraycopy C.System.copyof D.使用clone方法 效率:System.arraycopy > clone > Arrays.copyOf > for循环 1、System.arraycopy... -
vim 复制一整行和复制多行
2019-08-23 13:30:21一、复制 单行复制 在命令模式下,将光标移动到将要复制的行处,按“yy”进行复制; 多行复制 在命令模式下,将光标移动到将要复制的首行处,按“nyy”复制n行;其中n为1、2、3…… 二、粘贴 在命令模式下,将... -
poi操作excel,复制sheet,复制行,复制单元格
2018-08-23 10:43:12项目中,我们经常使用Poi来操作excel,但是经常碰到一个不方便的地方,不如最简单常用的,在两个excel之间复制sheet,复制行,复制单元格等。 源码如下: public class POIUtils { // /** // * 把一个excel中的... -
mysql复制表以及复制数据库
2017-08-09 11:46:40(一)将旧表复制到新表 1、CREATE TABLE新表 SELECT* FROM旧表; 该语句只是复制表结构以及数据,它不会复制与表关联的其他数据库对象,如索引,主键约束,外键约束,触发器等。 CREATE TABLE if not exists ... -
MySQL主从复制(异步复制与半同步复制)
2019-03-19 19:08:55MySQL主从复制 原理:将主服务器的binlog日志复制到从服务器上执行一遍,达到主从数据的一致状态。 过程:从库开启一个I/O线程,向主库请求Binlog日志。主节点开启一个binlog dump线程,检查自己的二进制日志,...