4. 下例说明了 SHOW PROCESSLIST 结果中的 3 个线程是什么样的。这是在 MySQL 4.0.15 及更新上执行
SHOW PROCESSLIST 的结果,State 字段的内容已经比旧版本显示的更有意义了。
在 master 上,SHOW PROCESSLIST 的结果如下:
mysql> SHOW PROCESSLISTG
*************************** 1. row ***************************
Id: 2
User: root
Host: localhost:32931
db: NULL
Command: Binlog Dump
Time: 94
State: Has sent all binlog to slave; waiting for binlog to
be updated
Info: NULL
在这里,线程 2 是为一个 slave 连接创建的。结果表明所有未完成的更新日志已经都发送到 slave 了,master 正等
待新的更新日志发生。
在 slave 上,SHOW PROCESSLIST 的结果如下:
mysql> SHOW PROCESSLISTG
*************************** 1. row ***************************
Id: 10
5. User: system user
Host:
db: NULL
Command: Connect
Time: 11
State: Waiting for master to send event
Info: NULL
*************************** 2. row ***************************
Id: 11
User: system user
Host:
db: NULL
Command: Connect
Time: 11
State: Has read all relay log; waiting for the slave I/O
thread to update it
Info: NULL
这表明线程 10 是 I/O 线程,它正连接到 master 上;线程 11 是 SQL 线程,它执行中继日志中的更新操作。现在,
这 2 个线程都处于空闲状态,正等待新的更新日志。
注意,Time 字段的值告诉我们 slave 上的日志比 master 晚了多久。详情请看"6.9 Replication FAQ"。
6.3.1 Master 同步线程状态
6. 以下列出了 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 后出现的一个短暂的状态。
7. 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 线程先处理
中继日志然后删除它们以释放足够的空间。
8. 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
当前线程停止了,这个时间很短。
SQL 线程的 State 字段有时候也可能是一个 SQL 语句。这意味着它从中继日志中读取到一个事件了,从中提取出
SQL 语句,并执行它。
6.3.4 中继日志及状态文件
默认地,中继日志的名字格式为 `host_name-relay-bin.nnn`,host_name 是服务器的主机名,nnn 是序
号。中继日志是根据顺序的序号来创建的,从 000001 (MySQL 4.0 及更旧是 001 )开始。slave 上用一个索引文
件来跟踪当前正在使用的中继日志。默认的中继日志索引文件名是 `host_name-relay-bin.index`。默认地,
这个文件位于 slave 的数据文件目录下。默认文件名可以根据的系统选项 --relay-log 和 --relay-
log-index 来替换。详情请看"6.8 Replication Startup Options"。
9. 中继日志和二进制日志的格式一样,因此也可以用 mysqlbinlog 来读取。当 SQL 线程读取完中继日志中的全
部事件后就不再需要它了,会自动删除它。中继日志没有显式的删除机制,因为 SQL 线程会自动关注这个。不过,从
MySQL 4.0.14 开始,执行 FLUSH LOGS 的话就会轮转(rotate)中继日志,会让 SQL 线程删除它们。
在下列条件中会创建一个新的中继日志:
• slave 启动后,I/O 线程第一次启动(在 MySQL 5.0 中,每次 I/O 线程启动后都会新建一个中继日志,而不只是第一次
启动时)。
• 刷新日志时;例如,执行 FLUSH LOGS 语句或运行 mysqladmin flush-logs 命令(从 MySQL 4.0.14 开
始才会创建新中继日志)。
• 当前的中继日志大小太大了;"太大了"是这么判断的:
o max_relay_log_size , 如果 max_relay_log_size > 0 的话
o max_binlog_size , 如果 max_relay_log_size = 0 或 MySQL 低于 4.0.14
slave 会在数据文件目录下创建两个额外的文件。它们是状态文件,名字默认为 `master.info` and `relay-
log.info`。它们的内容跟执行 SHOW SLAVE STATUS 语句的结果类似。详情请看"14.6.2 SQL
Statements for Controlling Slave Servers"。由于是磁盘上的文件,它们在 slave 关闭后还会留着。下一次
slave 启动时,就会读取这两个文件来判断从 master 读取到二进制日志的什么位置了,处理中继日志到什么位置了。
`master.info` 文件由来 I/O 线程更新。在 MySQL 4.1 以前,文件的内容和执行 SHOW SLAVE STATUS
语句结果中相对应的字段值一样,如下:
10. Line Description
1 Master_Log_File
2 Read_Master_Log_Pos
3 Master_Host
4 Master_User
5 Password (not shown by SHOW SLAVE STATUS )
6 Master_Port
7 Connect_Retry
从 MySQL 4.1 开始,文件内容还包括了 SSL 选项:
Line Description
1 Number of lines in the file
2 Master_Log_File
3 Read_Master_Log_Pos
4 Master_Host
11. 5 Master_User
6 Password (not shown by SHOW SLAVE STATUS )
7 Master_Port
8 Connect_Retry
9 Master_SSL_Allowed
10 Master_SSL_CA_File
11 Master_SSL_CA_Path
12 Master_SSL_Cert
13 Master_SSL_Cipher
14 Master_SSL_Key
`relay-log.info` 文件由 SQL 线程来更新。文件的内容和执行 SHOW SLAVE STATUS 语句结果中相对
应的字段值一样:
Line Description
1 Relay_Log_File
18. 19.mysql> CHANGE MASTER TO
20. -> MASTER_HOST='master_host_name',
21. -> MASTER_USER='replication_user_name',
22. -> MASTER_PASSWORD='replication_password',
23. -> MASTER_LOG_FILE='recorded_log_file_name',
24. -> MASTER_LOG_POS=recorded_log_position;
下表列出了各个选项字符串的最大长度:
MASTER_HOST 60
MASTER_USER 16
MASTER_PASSWORD 32
MASTER_LOG_FILE 255
25. 启动 slave 线程:
mysql> START SLAVE;
做完上述过程后,slave 应该会连接到 master 上并且捕获所有从取得快照后的更新操作。
如果忘了设置 master 的 server-id 值,那么 slave 就不能连接到 master 上。
如果忘了设置 master 的 server-id 值,那么在错误日志中就会记录如下内容:
Warning: You should set server-id to a non-0 value if master_host is set;
19. we force server id to 2, but this MySQL server will not act as a slave.
如果因为其他原因不能同步的话,错误信息也会记录在 slave 的日志上。
一旦 slave 开始同步了,就能在数据文件目录下找到 2 个文件 `master.info` 和`relay-log.info`。slave
利用这 2 个文件来跟踪处理了多少 master 的二进制日志。
不要删除或者修改这 2 个文件,除非知道怎么改。尽管如此,我们更推荐用 CHANGE MASTER TO 语句来做。
注意:`master.info` 中的内容覆盖了部分命令行中指定的或 `my.cnf` 的选项。详情请看"6.8 Replication
Startup Options"。
只要有了 master 的数据快照,就可以按照上述几个步骤配置其它 slave 了。无需再次取得 master 的数据快照,每
个 slave 都可以用这一份快照来做。
6.5 不同 MySQL 版本之间的同步兼容性
最早的二进制格式是在 MySQL 3.23 中开发出来的。在 MySQL 4.0 中改进了,MySQL 5.0 又改进了。在配置同步
时需要升级服务器的话,它们之间的因果关系在"6.6 Upgrading a Replication Setup"中描述了。
如果只关心同步,任何 MySQL 4.1.x 版本和 MySQL 4.0.x 是一样的,因为它们都使用相同格式的二进制日志。所
以,这些版本是互相兼容的,它们之间可以无缝地运行同步。一个例外的情况是,MySQL 4.0.0 到 4.0.2 由于开发
的较早,无法和后来的版本互相兼容,所以不要使用它们(它们是 4.0 版本的 alpha 系列。它们之间的兼容性在发布
包的手册中均有相关文档)。
20. 下表展示了不同版本的 MySQL 之间的 master/slave 同步兼容性。
Master Master Master
3.23.33 and up 4.0.3 and up or any 4.1.x 5.0.0
Slave 3.23.33 and up yes no no
Slave 4.0.3 and up yes yes no
Slave 5.0.0 yes yes yes
一个通常的规则是,我们建议使用最近的 MySQL 版本,因为同步兼容性一直在改善。我们也建议 master 和 slave
都使用同一个版本。
6.6 升级同步
如果升级服务器时涉及到配置同步,升级设置的步骤跟当前版本以及升级后的版本不同而异。
6.6.1 升级同步到 4.0 或 4.1
本节适用于从 MySQL 3.23 升级到 4.0 或者 4.1 的情况。4.0 的服务器必须是 4.0.3 或者更高,"6.5 Replication
Compatibility Between MySQL Versions"中提到了。
把 master 从 MySQL 3.23 升级到 4.0 或 4.1 时,首先要确认这个 master 的所有 slave 都已经是 4.0 或 4.1 了,
否则的话,要先升级 slave:挨个关闭,升级,重启,重启同步等。
21. 通过以下步骤可以实现安全地升级,假定 master 要升级到 3.23,而 slave 已经是 4.0 或 4.1 了。注意,master 升
级后,不要重启使用任何旧的二进制日志的同步,因为它会干扰到 4.0 或 4.1 slave 的同步。
1. 在 master 上执行 FLUSH TABLES WITH READ LOCK 语句,阻止所有的更新。
2. 等到所有的 slave 都跟上了 master 的数据更新。在 master 上执行 SHOW MASTER STATUS 语句取得二进
制日志以及偏移位置。然后,再 slave 用这些值执行 SELECT MASTER_POS_WAIT() 语句,它会阻止
slave 上的同步且返回它已经同步的偏移位置。然后在 slave 上执行 STOP SLAVE 语句。
3. 关闭 master,将它升级到 MySQL 4.0 或 4.1。
4. 重启 master,记下它的新的二进制文件名。可以在 master 上执行 SHOW MASTER STATUS 语句来取得这
些信息。然后在每个 slave 上都执行如下语句:
5. mysql> CHANGE MASTER TO MASTER_LOG_FILE='binary_log_name',
6. -> MASTER_LOG_POS=4;
mysql> START SLAVE;
6.6.2 升级同步到 5.0
本节适用于从 MySQL 3.23,4.0 或 4.1 升级到 5.0 的情况。4.0 的服务器必须是 4.0.3 或者更高,"6.5
Replication Compatibility Between MySQL Versions"中提到了。
首先,注意到 MySQL 5.0 还是 alpha 发布系列。它在各方面都比旧版本好(更容易升级一些同步中重要的会话变量,
例如 sql_mode ;详情请看"C.1.3 Changes in release 5.0.0 (22 Dec 2003: Alpha")。不过,它还没经过广
泛测试。由于是 alpha 版本,我们不建议用于任何生产环境(现在已经可以用于生产了,译者注)。
35. --
replicat
e-wild-
do-
table= db
_name.tb
l_name
限制 slave 只同步那些匹配指定模式的数据表。模式中可以包含通配符 `%` 和 `_`,它们的含义和 LIKE 模
式一样。想要指定更多的数据表,只需多次使用该选项,每次指定一个数据表。请仔细阅读最后面的注意事项。
例如: --replicate-wild-do-table=foo%.bar% 会同步所有以 foo 开头的数据库下的以
bar 开头的数据表上的更新操作。
如果匹配模式是 % ,则匹配所有的表名,且应用到数据库级语句(CREATE DATABASE , DROP
DATABASE ,和 ALTER DATABASE )。例如,使用 --replicate-wild-do-table=foo%.% 选
项的话,所有匹配 foo% 模式的数据库级操作都会被同步。
如果想要在数据库/表模式中包含原义通配符,需要用反斜杠来转义它们。例如,想要同步 my_own%db 数据库
下的所有表,但是不想同步 my1ownAABCdb 数据库下的表,就需要转义字符 `_`: --replicate-
wild-do-table=my_own%db 。如果是在命令行中使用这个选项,就可能需要两个反斜杠来转义,这
依赖于命令行解释器。例如,在 bash shell 下,就需要输入: --replicate-wild-do-
table=my_own%db 。
--
re
pl
ic
at
e-
36. wi
ld
-
ig
no
re
-
ta
bl
e=
db
_n
am
e.
tb
l_
na
me
限制 slave 不同步那些匹配指定模式的数据表。想要指定更多的数据表,只需多次使用该选项,每次指定一个数据
表。请仔细阅读最后面的注意事项。
例如,--replicate-wild-ignore-table=foo%.bar% 就不会同步所有以 foo 开头的数据库
下的以 bar 开头的数据表上的更新操作。
想要了解匹配模式如何工作的,请查看 --replicate-wild-ignore-table 选项的具体描述。模式中
包含原义通配符的规则和 --replicate-wild-ignore-table 选项一样。
--
replicate
58. 老规矩,先贴上报错
老规矩,先贴上报错信息,mysql 版本,配置等资料。
MySQL 中文网: http://imysql.cn
Google MySQL 中文用户群:http://groups.google.com/group/imysql
给你的祝福,要让你招架不住!
• reply
Sat, 2007/01/27 - 11:11 — 游客 (not verified)
感谢你抽空解答我的
感谢你抽空解答我的问题。下面这些就是版本,错误信息及设置。我刚接触 mysql,请多多指教。
版本:mysql 5.0.20-nt
*.err 的错误信息:
070127 10:25:11 InnoDB: Database was not shut down normally!
InnoDB: Starting crash recovery.
InnoDB: Reading tablespace information from the .ibd files...
InnoDB: Restoring possible half-written data pages from the doublewrite
InnoDB: buffer...
070127 10:26:22 InnoDB: Starting log scan based on checkpoint at
InnoDB: log sequence number 8 3059764932.
InnoDB: Doing recovery: scanned up to log sequence number 8 3065007616
InnoDB: Doing recovery: scanned up to log sequence number 8 3070250496
InnoDB: Doing recovery: scanned up to log sequence number 8 3075493376
59. InnoDB: Doing recovery: scanned up to log sequence number 8 3077233098
070127 10:26:24 InnoDB: Starting an apply batch of log records to the database...
InnoDB: Progress in percents: 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
98 99
InnoDB: Apply batch completed
InnoDB: In a MySQL replication slave the last master binlog file
InnoDB: position 0 47510, file name My binLog.000051
InnoDB: Last MySQL binlog file position 0 319593, file name .My binLog.000001
070127 10:26:29 InnoDB: Started; log sequence number 8 3077233098
070127 10:26:30 [Warning] Neither --relay-log nor --relay-log-index were used; so replication may
break when this MySQL server acts as a slave and has his hostname changed!! Please use '--relay-
log=tests8000-02-relay-bin' to avoid this problem.
070127 10:26:30 [Note] D:GreenampMySQLbinmysqld-nt: ready for connections.
Version: '5.0.20-nt' socket: '' port: 3308 MySQL Community Edition (GPL)
070127 10:26:30 [Note] Slave SQL thread initialized, starting replication in log 'My binLog.000051'
at position 31899609, relay log '.tests8000-02-relay-bin.000029' position: 31890015
070127 10:26:30 [ERROR] Error in Log_event::read_log_event(): 'Event too small', data_len: 0,
event_type: 0
070127 10:26:30 [ERROR] Error reading relay log event: slave SQL thread aborted because of I/O
error
070127 10:26:30 [ERROR] Slave: Could not parse relay log event entry. The possible reasons are:
the master's binary log is corrupted (you can check this by running 'mysqlbinlog' on the binary log),
the slave's relay log is corrupted (you can check this by running 'mysqlbinlog' on the relay log), a
network problem, or a bug in the master's or slave's MySQL code. If you want to check the master's
binary log or slave's relay log, you will be able to know their names by issuing 'SHOW SLAVE
60. STATUS' on this slave. Error_code: 0
070127 10:26:30 [ERROR] Error running query, slave SQL thread aborted. Fix the problem, and
restart the slave SQL thread with "SLAVE START". We stopped at log 'My binLog.000051' position
31899609
070127 10:26:31 [ERROR] Slave I/O thread: error connecting to master 'Ad@localhost:3306':
Error: 'Can't connect to MySQL server on 'localhost' (10061)' errno: 2003 retry-time: 60 retries:
86400
070127 10:27:31 [Note] Slave I/O thread: connected to master 'Ad@localhost:3306', replication
started in log 'My binLog.000051' at position 31899609
但在 slave 端用 show slave status,则显示如下内容:
mysql> show slave statusG
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: localhost
Master_User: Ad
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: My binLog.000052
Read_Master_Log_Pos: 260
Relay_Log_File: tests8000-02-relay-bin.000029
Relay_Log_Pos: 31890015
Relay_Master_Log_File: My binLog.000051
Slave_IO_Running: Yes
Slave_SQL_Running: No
Replicate_Do_DB:
Replicate_Ignore_DB: