MySQL 主从同步错误(error)解决(转)
sql_slave_skip_counter参数
附:
一些错误信息的处理,主从服务器上的命令,及状态信息。
在从服务器上使用show slave status\G
Slave_IO_Running,为No,
则说明IO_THREAD没有启动,请执行start slave io_thread
Slave_SQL_Running为No
则复制出错,查看Last_error字段排除错误后执行start slave sql_thread
查看Slave_IO_State字段空 //复制没有启动
Connecting to master//没有连接上master
Waiting for master to send event//已经连上
主服务器上的相关命令:
show master status
show slave hosts
show logs
show binlog events
purge logs to 'log_name'
purge logs before 'date'
reset master(老版本flush master)
set sql_log_bin=
从服务器上的相关命令:
slave start
slave stop
SLAVE STOP IO_THREAD //此线程把master段的日志写到本地
SLAVE start IO_THREAD
SLAVE STOP SQL_THREAD //此线程把写到本地的日志应用于数据库
SLAVE start SQL_THREAD
reset slave
SET GLOBAL SQL_SLAVE_SKIP_COUNTER
load data from master
show slave status(SUPER,REPLICATION CLIENT)
CHANGE MASTER TO MASTER_HOST=, MASTER_PORT=,MASTER_USER=, MASTER_PASSWORD= //动态改变master信息
PURGE MASTER [before 'date'] 删除master端已同步过的日志
6.3.1 Master 同步线程状态
以下列出了master的 Binlog Dump 线程 State 字段中最常见的几种状态。如果在master上没有 Binlog Dump 线程,那么同步就没有在运行。
也就是说,没有slave连接上来。
Sending binlog event to slave
事件是由二进制日志构成,一个事件通常由更新语句加上其他信息。线程读取到一个事件并正发送到slave上。
Finished reading one binlog; switching to next binlog
读取完了一个二进制日志,正切换到下一个。
Has sent all binlog to slave; waiting for binlog to be updated
已经读取完全部未完成更新日志,并且全部都发送到slave了。它处于空闲状态,正等待在master上执行新的更新操作以在二进制日志中产生新
的事件,然后读取它们。
Waiting to finalize termination
当前线程停止了,这个时间很短。
6.3.2 Slave的I/O线程状态
以下列出了slave的I/O线程 State 字段中最常见的几种状态。从MySQL 4.1.1开始,这个状态在执行 SHOW SLAVE STATUS 语句结果的
Slave_IO_State 字段也会出现。这意味着可以只执行 SHOW SLAVE STATUS 语句就能了解到更多的信息。
Connecting to master
该线程证尝试连接到master上。
Checking master version
确定连接到master后出现的一个短暂的状态。
Registering slave on master
确定连接到master后出现的一个短暂的状态。
Requesting binlog dump
确定连接到master后出现的一个短暂的状态。该线程向master发送一个请求,告诉它要请求的二进制文件以及开始位置。
Waiting to reconnect after a failed binlog dump request
如果二进制日志转储(binary log dump)请求失败了(由于连接断开),该线程在休眠时进入这个状态,并定期重连。重连的时间间隔由 --
master-connect-retry 选项来指定。
Reconnecting after a failed binlog dump request
该线程正尝试重连到master。
Waiting for master to send event
已经连接到master,正等待它发送二进制日志。如果master闲置时,这个状态可能会持续较长时间,如果它等待超过 slave_read_timeout 秒
,就会发生超时。这时,它就会考虑断开连接,然后尝试重连。
Queueing master event to the relay log
已经读取到一个事件,正把它拷贝到中继日志中以备SQL线程处理。
Waiting to reconnect after a failed master event read
读日志时发生错误(由于连接断开)。该线程在重连之前休眠 master-connect-retry 秒。
Reconnecting after a failed master event read
正尝试重连到master。当连接确定后,状态就变成 Waiting for master to send event。
Waiting for the slave SQL thread to free enough relay log space
relay_log_space_limit 的值非零,中继日志的大小总和超过这个值了。I/O线程等待SQL线程先处理中继日志然后删除它们以释放足够的空间
。
Waiting for slave mutex on exit
当前线程停止了,这个时间很短。
6.3.3 Slave的SQL线程状态
以下列出了slave的SQL线程 State 字段中最常见的几种状态:
Reading event from the relay log
从中继日志里读到一个事件以备执行。
Has read all relay log; waiting for the slave I/O thread to update it
已经处理完中继日志中的全部事件了,正等待I/O线程写入更新的日志。
Waiting for slave mutex on exit
当前线程停止了,这个时间很短。
故障
问题:主从复制不止何故停止了,我该怎么办?
答案:复制错误多半是因为日志错误引起的,所以首先要搞清楚是主日志错误还是中继日志错误,从错误信息里一般就能判断,如果不能可以使用类似下面的mysqlbinlog命令:
shell> mysqlbinlog <MASTER_BINLOG_FILE> > /dev/null
shell> mysqlbinlog <SLAVE_BINLOG_FILE> > /dev/null
如果没有错误,则不会有任何输出,反之如果有错误,则会显示出来。
如果是主日志错误,则需要在从服务器使用SET GLOBAL sql_slave_skip_counter,如下:
mysql> SET GLOBAL sql_slave_skip_counter = 1;
mysql> START SLAVE;
注:如果有多个错误,可能需要执行多次(提醒:主从服务器数据可能因此不一致)。
如果是中继日志错误,只要在从服务器使用SHOW SLAVE STATUS结果中的日志信息重新CHANGE MASTER TO即可,系统会抛弃当前的中继日志,重新下载:
mysql> CHANGE MASTER TO
MASTER_LOG_FILE='<Relay_Master_Log_File>',
MASTER_LOG_POS=<Exec_Master_Log_Pos>;
mysql> START SLAVE;
至于为什么使用的是Relay_Master_Log_File & Exec_Master_Log_Pos,参见概述。
问题:主服务器宕机了,如何把从服务器提升会主服务器?
答案:在一主多从的环境总,需选择数据最新的从服务器做新的主服务器。如下图所示:
提升从服务器为主服务器
在一主(Server1)两从(Server2,、Server3)的环境中,Server1宕机后,等到Server1和Server2把宕机前同步到的日志都执行完,比较Master_Log_File和Read_Master_Log_Pos就可以判断出谁快谁慢,因为Server2从 Server1同步的数据(1582)比Server3从Server1同步的数据(1493)新,所以应该提升Server2为新的主服务器,那么Server3在CHANGE MASTER TO到Server2的时候应该使用什么样的参数呢?1582-1493=89,而Server2的最后的二进制日志位置是8167,所以答案是 8167-89=8078。
技巧
主从服务器中的表可以使用不同的表类型。比如主服务器可以使用InnoDB表类型,提供事务,行锁等高级特性,从服务器可以使用MyISAM表类型,内存消耗少,易备份等优点。还有一个例子,一台主服务器如果同时带很多个从服务器的话,势必会影响其性能,此时可以拿出一台服务器作为从服务器代理,使用BLACKHOLE表类型,只记录日志,不写数据,由它带多台从服务器,从而提升性能。
主从服务器中的表可以使用不同的键类型。比如主服务器用InnoDB,键用VARCHAR的话节省空间,从服务器使用MyISAM,键用CHAR提高速度,因为MyISAM有静态表一说。
主从服务器中的表可以使用不同的索引。主服务器主要用来应付写操作,所以除了主键和唯一索引等保证数据关系的索引一般都可以不加,从服务器一般用来应付读操作,所以可以针对查询特征设置索引,再进一步,不同的从服务器可以针对不同的查询设置不同的索引。
MySQL同步功能由3个线程(master上1个,slave上2个)来实现。执行 DE>START SLAVEDE> 语句后,slave就创建一个I/O线程。I/O线程连接到master上,并请求master发送二进制日志中的语句。master创建一个线程来把日志的内容发送到slave上。这个线程在master上执行 DE>SHOW PROCESSLISTDE> 语句后的结果中的 DE>Binlog DumpDE> 线程便是。slave上的I/O线程读取master的 DE>Binlog DumpDE> 线程发送的语句,并且把它们拷贝到其数据目录下的中继日志(relaylogs)中。第三个是SQL线程,salve用它来读取中继日志,然后执行它们来更新数据。
如上所述,每个master/slave上都有3个线程。每个master上有多个线程,它为每个slave连接都创建一个线程,每个slave只有I/O和SQL线程。
show slave master 用于提供有关从属服务器线程的关键参数的信息
mysql> show slave status \G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.17.2.40
Master_User: photorepl
Master_Port: 4331
Connect_Retry: 60
Master_Log_File: mysql-bin.005502
Read_Master_Log_Pos: 64401238
Relay_Log_File: mysqld-relay-bin.015418
Relay_Log_Pos: 13456757
Relay_Master_Log_File: mysql-bin.005152
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB: mysql
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table: photo.%
Replicate_Wild_Ignore_Table: mysql.%
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 13456620
Relay_Log_Space: 36764898503
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 249904
××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
SHOW SLAVE STATUS会返回以下字段:
? Slave_IO_State
SHOW PROCESSLIST输出的State字段的拷贝。SHOW PROCESSLIST用于从属I/O线程。如果线程正在试图连接到主服务器,正在等待来自主服务器的时间或正在连接到主服务器等,本语句会通知您
? Master_User
被用于连接主服务器的当前用户。
? Master_Port
当前的主服务器接口。
? Connect_Retry
–master-connect-retry选项的当前值
? Master_Log_File
I/O线程当前正在读取的主服务器二进制日志文件的名称。
? Read_Master_Log_Pos
在当前的主服务器二进制日志中,I/O线程已经读取的位置。
? Relay_Log_File
SQL线程当前正在读取和执行的中继日志文件的名称。
? Relay_Log_Pos
在当前的中继日志中,SQL线程已读取和执行的位置。
? Relay_Master_Log_File
由SQL线程执行的包含多数近期事件的主服务器二进制日志文件的名称。
? Slave_IO_Running
I/O线程是否被启动并成功地连接到主服务器上。
? Slave_SQL_Running
SQL线程是否被启动。
? Replicate_Do_DB,Replicate_Ignore_DB
使用–replicate-do-db和–replicate-ignore-db选项指定的数据库清单。
? Replicate_Do_Table,Replicate_Ignore_Table,Replicate_Wild_Do_Table,Replicate_Wild_Ignore_Table
使用–replicate-do-table,–replicate-ignore-table,–replicate-wild-do-table和–replicate-wild-ignore_table选项指定的表清单。
? Last_Errno,Last_Error
被多数最近被执行的查询返回的错误数量和错误消息。错误数量为0并且消息为空字符串意味着“没有错误”。如果Last_Error值不是空值,它也会在从属服务器的错误日志中作为消息显示。
举例说明:
Last_Errno: 1051
Last_Error: error ‘Unknown table ‘z” on query ‘drop table z’
该消息指示,表z曾经存在于在主服务器中并已被取消了,但是它没有在从属服务器中存在过,因此对于从属服务器,DROP TABLE失败。(举例说明,在设置复制时,如果您忘记了把此表拷贝到从属服务器中,则这有可能发生。)
? Skip_Counter
最近被使用的用于SQL_SLAVE_SKIP_COUNTER的值。
? Exec_Master_Log_Pos
来自主服务器的二进制日志的由SQL线程执行的上一个时间的位置(Relay_Master_Log_File)。在主服务器的二进制日志中的(Relay_Master_Log_File, Exec_Master_Log_Pos)对应于在中继日志中的(Relay_Log_File,Relay_Log_Pos)。
? Relay_Log_Space
所有原有的中继日志结合起来的总大小。
? Until_Condition,Until_Log_File,Until_Log_Pos
在START SLAVE语句的UNTIL子句中指定的值。
Until_Condition具有以下值:
o 如果没有指定UNTIL子句,则没有值
o 如果从属服务器正在读取,直到达到主服务器的二进制日志的给定位置为止,则值为Master
o 如果从属服务器正在读取,直到达到其中继日志的给定位置为止,则值为Relay
Until_Log_File和Until_Log_Pos用于指示日志文件名和位置值。日志文件名和位置值定义了SQL线程在哪个点中止执行。
? Master_SSL_Allowed,Master_SSL_CA_File,Master_SSL_CA_Path,Master_SSL_Cert,Master_SSL_Cipher,Master_SSL_Key
这些字段显示了被从属服务器使用的参数。这些参数用于连接主服务器。
Master_SSL_Allowed具有以下值:
o 如果允许对主服务器进行SSL连接,则值为Yes
o 如果不允许对主服务器进行SSL连接,则值为No
o 如果允许SSL连接,但是从属服务器没有让SSL支持被启用,则值为Ignored。
与SSL有关的字段的值对应于–master-ca,–master-capath,–master-cert,–master-cipher和–master-key选项
########################################################################
Replication 延时的类型
1 、 固定性的延时
——Slave 的数据持续性的落后于 Master 并且一直无法与 Master 的数据保持一致。
——Slave 的数据经常在白天落后于 Master ,而在晚上可以赶上并与 Master 的记录保持一致。
这种类型的延时通常是由于 Slave 服务器的负载已经到达了上限或在白天访问量大的时候到达上限造成的。
2 、 非固定性的延时
——Slave 的数据只是短暂的落后于 Master ,可在短时间内恢复 , 这类型的延时通常与批量任务和报表有关,效率差的查询也会导致这类延时 。
Mysql Replication 的限制
Mysql 的 Replication 是单线程的,意味着只能有效的使用一个 CPU 内核和一个磁盘,一条复杂的查询或者事务都导致进程被阻塞,不过现在针对 5.1 版本的多线程 Replication 补丁, http://forge.mysql.com/wiki/ReplicationFeatures/ParallelSlave ,还是 pre 版,有很多限制,感兴趣的可以去看看。
Replication 的容量
1 、 理解什么是 Replication 的容量
可以将 Replication 暂停一个小时,重新启动 Replication 后,观察 Slave 的数据多久可以与 Master 一致。从 Replication 重新启动到和 Master 数据一致所花费的时间与 Replication 暂停的时间的比值就是 Replication 的容量。
2 、 建议保持 Replication 的容量在 3 倍以上, 即延迟一个小时的数据,Slave 只需要 20 分钟就能与 Master 的数据一致。
Replication 的优化
1 、 5.0 的 mysql 中避免类似以下的更新语句
INSERT … SELECT
UPDATE .... WHERE
复杂的查询会导致 Replication 线程阻塞。如果是 insert 或 update 与 select 结合的语句,可以讲 select 单独执行并保存在临时表中,然后再执行 insert 或者 update 。
如果使用的是 5.1 的 mysql ,新功能中的行级 Replication ( RBR )可以解决这个问题。 RBR 可以将在 Master 上通过复杂查询后更新的结果直接传给 Slave , Slave 可以直接将结果更新到数据库中。
2 、 避免大的事务
太大的事务会造成 Replication 长时间阻塞,数据会严重滞后于 Master 。
Slave 服务器的硬件选择
更快的 CPU 内核,对于单线程的 Replication 多核 CPU 是没有任何优势的。更高速的硬盘,包括更高的转速和更好的高速缓存命中率,如果有钱的话上 SSD 吧。
主从结构的扩展性问题
1 、 如何降低写操作的频率
Master 的写操作会扩散到所有的 Slave 上,所以高频率的写操作会降低 Slave 的读操作效率。
至少保持一台 Slave 做全库同步,其他的 Slave 可以只做部分表的同步。当然,这需要 web 应用程序的配合来分配哪些查询读哪些 Slave 。将一些更新操作放到 memcached 中,例如 session 和计数器。 Slave 使用 myisam 引擎,将一些写入量很大的更新操作直接在 slave 上执行,而不通过 Replication 。
2 、 如何更有效的利用 Slave 的硬件资源[变形虫]
使用分区
有选择的对表进行同步
在 Slave 上对数据进行归档。
Session 的持久化
为不同的应用服务器分配不同的 Slave 进行读操作。
或者根据查询类型的不同来分配不同的 Slave 。
3 、 如何使你的程序最大化的利用 Slave
将对数据更新不敏感的查询放到 Slave 上,而需要实时数据的查询则放到 Master 。通过 session 的持久化,让做了修改的用户首先看到修改的内容,其他的用户可以等待 Slave 更新后再查看新内容。
对于某些数据,可以用 memcached 来存放数据的版本号,读 Slave 的程序可以先对比 Slave 的数据和 memcached 数据的版本,如果不一致则去读 master 。用户和博客类的信息可以用这种方法。在查询前可以通过 SHOWSLAVE STATUS 检测 Slave 的状态,然后根据返回的结果进行服务器的选择。
运维网声明
1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网 享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com