MySQL 同步(五)

6.9 同步 FAQ

: master还在运行中,如何在不停止它的情况下配置slave?


: 需要设计几个选项参数。如果已经有了master的备份并且记录了数据快照二进制日志文件名以及偏移位置(运行 SHOW MASTER STATUS 查看结果),执行以下步骤:


  1. 确定slave指定了一个唯一的服务器编号。

  2. 在slave上执行如下语句,把一些选项值改成实际值:
    mysql> CHANGE MASTER TO
        ->     MASTER_HOST='master_host_name',
        ->     MASTER_USER='master_user_name',
        ->     MASTER_PASSWORD='master_pass',
        ->     MASTER_LOG_FILE='recorded_log_file_name',
        ->     MASTER_LOG_POS=recorded_log_position;  

  3. 在slave上执行 START SLAVE 语句。

如果事先没有备份master的数据,可以用以下方法快速创建一个备份。以下所有的操作都是在master上。



  1. 提交语句:
    mysql> FLUSH TABLES WITH READ LOCK;
    

  2. 确保这个锁一直存在,执行以下命令(或者其他类似的):
    shell> tar zcf /tmp/backup.tar.gz /var/lib/mysql
    

  3. 执行以下语句,记录下输出的结果,后面要用到:
    mysql> SHOW MASTER STATUS;
    

  4. 释放锁:
    mysql> UNLOCK TABLES;

上述步骤的另一个办法是创建master的SQL转储文件。只需在master上执行 mysqldump --master-data 命令,然后将导出来的SQL转储文件载入slave。不过,这么做会制作二进制数据快照的方式慢一点。


无论使用上述两种方法的哪种,最后都能创建master的数据快照然后记录二进制日志文件名以及偏移位置。可以在好几的其他的slave上使用同一个备份的二进制数据快照。得到master的快照后,只要master的二进制日志完好无损,接着就能开始设置slave了。两个决定是否需要等待较长时间的限制是:在master上磁盘空间保存二进制日志,以及slave从master抓取更新事件。


也可以使用 LOAD DATA FROM MASTER。这个语句可以很方便地在slave上取得数据快照并且能立刻调整二进制日志文件名以及偏移位置。在将来,我们推荐用 LOAD DATA FROM MASTER 来设置slave。警告,它只能用于 MyISAM 表,并且可能会保持一个较长时间的读锁。由于它还没达到所期望的高效率,因此如果数据表很大,最好还是在执行完 FLUSH TABLES WITH READ LOCK 后直接制作二进制数据快照。


:是否slave总是需要连接到master?


:不,非必需。slave可以好几小时甚至几天关闭或者不连接master,然后重连再取得更新操作日志。例如,可以在拨号链接上设置一个mater/slave关系,拨号可能只是零星的不定期的连接。这种做法隐含的是,在任何指定的时间里,除非使用特殊的度量标准,否则slave不能保证总是能和master保持同步。在未来,有个选项可以阻止master,除非至少有一个slave在同步中。


:怎么知道比master晚了多少?也就是说,怎么知道slave最后同步的时间?


:如果slave是4.1.1或者更高,只需查看 SHOW SLAVE STATUS 结果中的 Seconds_Behind_Master 字段。对于老版本,可以用以下办法。如果在slave上执行 SHOW PROCESSLIST 语句结果显示SQL线程(对MySQL 3.23则是slave线程)正在运行,这就意味着该线程至少从master读取一个更新操作事件。详情请看"6.3 Replication Implementation Details"。


当SQL线程执行一个master上读取的更新操作事件时,它把自己的时间改成事件的时间(这也就是 TIMESTAMP 也要同步的原因)。在
SHOW PROCESSLIST 结果中的 Time 字段中,slave的SQL线程显示的秒数就是最后一次同步的时间戳和slave本机的实际时间相差秒数。可以根据这个值来判断最后同步的时间。注意,如果slave已经从master断开好几个小时了,然后重新连接,就能看到slave的
SHOW PROCESSLIST 结果中的SQL线程的Time 字段的值类似3600。这是因为slave正在执行一个小时前的语句。


:如何强制master在slave赶上全部更新之前阻止更新操作?


:执行以下步骤:



  1. 在master上,执行以下语句:
    mysql> FLUSH TABLES WITH READ LOCK;
    mysql> SHOW MASTER STATUS;  

    记录下结果中的日志文件名以及偏移位置,它们是同步的坐标值。

  2. 在slave上,提交以下语句,MASTER_POS_WAIT() 函数的参数的值就是前面取得的同步坐标值:
    mysql> SELECT MASTER_POS_WAIT('log_name', log_offset);
    

    SELECT 语句会阻止更新,直到slave同步到了上述日志文件及位置。在这个时候,slave就和master保持同步了,并且这个语句就会返回。

  3. 在master上,执行以下语句允许master重新处理更新操作:
    mysql> UNLOCK TABLES;

:设置一个双向复制时要注意什么问题?


:MySQL同步目前还不支持任何在master和slave上的分布式(跨服务器)更新锁协议以保证操作的原子性。也就是说,存在这样的可能性:客户端A在并存的master 1上做了一个更新,同时,在它同步到并存master 2上之前,客户端B在master 2上可能也做了一个和客户端A在master 1上不同的更新操作。因此,当客户端A所做的更新同步到master 2时,它将产生和master 1上不同的数据表,尽管master 2上的更新操作也全都同步到master 1上去。这意味着除非能确保所有的更新都能以任何顺序安全地执行,否则不要使用双向同步,或者除非注意在客户端程序中的不知原因的无序更新操作。


同时也要意识到在所关心的更新问题上,双向同步实际上并不能很大地改善性能(甚至没有)。两个服务器都需要执行同样数量的更新操作,在一台服务器上也是。唯一区别的是,可能这样做会减少一些锁争夺,因为来自其他服务器的更新操作都会被串行地放到slave线程中。甚至这种好处还可以作为网络延迟的补偿。


:我如何利用同步来提高系统性能?


:需要安装一个服务器作为master并且把所有的写操作直接放在这上面。然后配置多个廉价的使用机架磁盘的slave,把读操作分配给master和slave。还可以在启动slave时使用 --skip-innodb, --skip-bdb, --low-priority-updates,和 --delay-key-write=ALL 选项来提高slave端的性能。这种情况下,slave会使用非事务的 MyISAM 表来代替 InnoDBBDB 表,已取得更快速度。


:如何准备客户端应用程序的代码来适应同步应用?


:如果代码中负责存取数据库的部分已经被合理地抽象化/模块化了,将它们转化成适用运行于同步环境中将会很平滑和简单。只需要修改数据库存取实现部分,把所有的写操作放到master上,把所有的读操作放到master或者slave上。如果你的代码还没达到这个层次的抽象化,那么这将成为整理代码的机会和动机。可以使用类似以下函数创建封装类库或者模块:



  • safe_writer_connect()

  • safe_reader_connect()

  • safe_reader_statement()

  • safe_writer_statement()

每个函数名的 safe_ 表示它们会处理所有的错误情况。可以使用其他函数名。重要的是,要为读连接、写连接、读、写定义好统一的接口。


然后将客户端代码转换成使用封装的类库。已开始可能是很痛苦且麻烦的,不过在将来长期运行中就能得到回报了。所有使用上述方法的应用程序都会在master/slave配置中有优势,即使包含多个slave。这些代码将很容易维护,一些额外的麻烦也会很少。自豪需要修改一个或者两个函数;例如,想要记录每个语句执行了多长时间,或者在上千个语句中哪个出现错误了。


如果已经写了很多代码,你可能想要自动转换它们,那么可以使用MySQL发布的 replace 工具,或者自己写转换脚本。理想地,你的代码已经使用了统一的编程风格。如果不是,最好重写它们,或者可以遍历检查一下,手工规范化一下代码风格。


:MySQL同步何时且有多少能提高系统性能?


:MySQL同步对于频繁读但不频繁写的系统很有好处。理论上来讲,使用单一master/多slave的配置,就可以通过这个方法来衡量系统:增加更多的slave直到用完所有的网络带宽或者master的更新操作增长到了不能再处理的点了。


想要知道增加多少个slave之后得到的性能才能平稳,以及能提高多少性能,就需要知道查询模式,并且根据经验对典型的master和slave做读(每秒读或 max_reads)和写(max_write)基准测试得到它们之间的关系。下例展示了一个理想系统取得的性能的简单计算方法。


设定系统负载由10%写和90%读组成,我们已经通过基准测试确定 max_reads 是1200 - 2 * max_writes。换句话说,系统可以达到每秒做没有写的1200次读操作,写操作平均是读操作的2倍慢,它们之间的关系是线性的。让我们假设master和每个slave都有同样的容量,有一个master和N个slave。每个服务器(master或slave):


reads = 1200 - 2 * writes



reads = 9 * writes / (N + 1) (读是分开的,但是所有写是在所有的服务器上的)



9 * writes / (N + 1) + 2 * writes = 1200



writes = 1200 / (2 + 9/(N+1))


最后的等式说明了N个slave的最大写数量,给它每分钟的最高读频率1200和1次写9次读的机率。


分析结论比率如下:


  • 如果 N = 0(意味着没有同步),系统大致可以处理每秒 1200/11 = 109 次写。

  • 如果 N = 1,增加到每秒 184 次写。
  • 如果 N = 8,增加到每秒 400 次写。

  • 如果 N = 17,增加到每秒 480 次写。

  • 最终,随着N接近无穷大(我们的预算为负无穷大),则可以达到几乎每秒 600 次写,大约提高系统吞吐量 5.5 倍。尽管如此,当有8台服务器时,已经提高了4倍了。

注意,上面的计算是假设了网络带宽无穷大,并且忽略了一些系统中比较大的因素。在很多情况下,当系统增加 N 个同步slave之后,是无法精确计算出上述预计结果的。不过,先看看下列问题将有助于你知道是否有和有多少系统性能上的改善:



  • 系统读/写得比率是多少?

  • 减少读操作后一个服务器能增加处理多少写操作?

  • 你的网络带宽足够给多少slave使用?

:如何利用同步提供冗余/高可用性?


:使用当前已经可用的特性,可以配置一个master和一个(或多个)slave,并且写一个脚本监控master是否运行着。然后通知应用程序和slave在发现错误时修改master。一些建议如下:


  • 使用 CHANGE MASTER TO 语句告诉slave修改master。

  • 一个让应用程序定位master所在主机的办法就是给master使用动态DNS。例如bind就可以用 `nsupdate` 来动态更新DNS。
  • 使用 --log-bin 选项,不使用
    --log-slave-updates 选项来启动slave。这样就能让slave运行 STOP SLAVE; RESET MASTER 语句后随时准备变成master,并且在其他slave上运行
    CHANGE MASTER TO。例如,有以下配置方案:

           WC
            \
             v
     WC----> M
           / | \
          /  |  \
         v   v   v
        S1   S2  S3
    

    M 表示masetr,S 表示slave,WC表示提交读写操作的客户端;只提交读操作的客户端没有表示出来,因为它们无需切换。S1,S2,S3都是使用
    --log-bin 选项,不用 --log-slave-updates 选项运行的slave。由于除非指定 --log-slave-updates 参数,否则从master读到的更新操作都不会记录到二进制日志中,因此每个slave上的二进制日志都是空的。如果因为某些原因 M 不能用了,可以指定一个slave作为master。例如,如果指定S1,则所有的WC都要重定向到S1上,S2和S3都需要从S1上同步。

    确定所有的slave都已经处理完各自的中继日志了。在每个slave上,提交 STOP SLAVE IO_THREAD 语句,然后检查 SHOW PROCESSLIST 的结果直到看到 Has read all relay log 了。当所有的slave都这样子之后,就可以按照新的方案设置了。在slave S1上提交

    STOP SLAVERESET MASTER 语句将其提升为master。

    在其他slave S2和S3上,提交 STOP SLAVECHANGE MASTER
    TO MASTER_HOST='S1'
    ( 'S1' 代表S1的真实主机名) 语句修改master。把S2,S3如何连接到S1的参数(用户,密码,端口等)都附加到 CHANGE MASTER 后面。在
    CHANGE MASTER 中无需指定S1的二进制日志文件名和偏移位置:因为 CHANGE MASTER 默认就是第一个二进制日志和偏移位置4。最后,在S2和S3上提交 START SLAVE 语句。

    然后让所有的WC都把他们的语句重定向到S1上。从这个时候开始,从所有的WC发送到S1上的更新语句都会写到S1的二进制日志中,它们包含了从M死掉之后发送到S1的全部更新语句。

    配置结果如下:

           WC
          /
          |
     WC   |  M(unavailable)
      \   |
       \  |
        v v
         S1<--S2  S3
          ^       |
          +-------+
        

    当M又起来了之后,只需在M上提交和在S2和S3上的一样的 CHANGE MASTER 语句,将它变成一个slave并且读取自从它死掉之后的全部WC提交的更新操作。想要把M重新变成master(例如因为它的性能更好),就执行类似上面的操作,把S1当作失效了,把M提升为新的master。在这个步骤中,别忘了在把S2和S3修改成为M的slave之前在M上运行 RESET MASTER 语句。否则的话,它们会从M开始失效的那个时刻开始读取WC提交的更新操作日志。

现在我们就运行着一个完整的自动选择master的MySQL同步系统,不过在它准备好之前,需要创建自己的监控工具。


6.10 同步疑难解答

如果按照上述步骤设定好同步之后,它不能正常工作的话,首先检查以下内容:


  • 查看一下错入日志信息。不少用户都在这方面做得不够好以至于浪费时间。

  • master是否在记录二进制日志?用 SHOW MASTER STATUS 检查一下状态。如果是,Position 的值不为零;否则,确定master上使用了 log-binserver-id 选项。
  • slave是否运行着?运行 SHOW SLAVE STATUS 语句检查

    Slave_IO_RunningSlave_SQL_Running 的值是否都是。如果不是,确定是否用同步参数启动slave服务器了。

  • 如果slave正在运行,它是否建立了到master的连接?运行
    SHOW PROCESSLIST 语句检查I/O和SQL线程的 State 字段值。详情请看"6.3 Replication Implementation Details"。如果I/O线程状态为 Connecting to master,就检查一下master上同步用户的权限是否正确,master的主机名,DNS设置,master是否确实正在运行着,以及slave是否可连接到master,等等。
  • 如果slave以前运行着,但是现在停止了,原因通常是一些语句在master上能成功但在slave上却失败了。如果salve已经取得了master的全部快照,并且除了slave线程之外不会修改他的数据,那么应该不会发生这样的情形。如果确实发生了,那么可能是一个bug或者你碰到了"6.7 Replication Features and Known Problems"中提到的同步限制之一。如果是一个bug,那么请按照"6.11 Reporting Replication Bugs"的说明报告它。
  • 如果一个语句在master上成功了,但是在slave上却失败了,并且这时不能做一次完整的数据库再同步(也就是删除slave上的数据,重新拷贝master的快照),那么试一下:
    1. 判断slave的数据表是否和master的不一样。试着找到怎么会发生这种情况,然后将slave的表同步成和master一样之后运行 START SLAVE

    2. 如果上述步骤不生效或者没有执行,试着这个语句是否能被手工安全地运行(如果有必要),然后忽略master的下一个语句。
    3. 如果决定要忽略master的下一个语句,只需在slave上提交以下语句:
      mysql> SET GLOBAL SQL_SLAVE_SKIP_COUNTER = n;
      mysql> START SLAVE;

      如果下一个语句没有使用 AUTO_INCREMENTLAST_INSERT_ID(),那么 n 的值应为为 1。否则,它的值为 2。设定为 2 是因为 AUTO_INCREMENTLAST_INSERT_ID() 在master的二进制日志中占用了2条日志。

    4. 如果确定slave精确地同步master了,并且没有除了slave线程之外的对数据表的更新操作,则推断这是因为bug产生的差异。如果是使用最近的版本,请报告这个问题,如果使用的是旧版本,试着升级一下。

6.11 报告同步Bugs

当确定没有包含用户的错误,并且同步还是不能正常工作或者不稳定,就可以报告bug了。我们需要你尽量多的跟踪bug的信息。请花点时间和努力准备一个好的bug报告。


如果有一个演示bug的可重现测试案例的话,请进入我们的bug数据库http://bugs.mysql.com/。如果碰到一个幽灵般的问题(不可重现),请按照如下步骤:



  1. 确定没有包含用户错误。例如,在slave线程以外更新slave的数据,那么数据就会不能保持同步,也可能会导致违反更新时的唯一键问题。这是外部干涉导致同步失败的问题。
  2. 使用 --log-slave-updates--log-bin 选项启动slave。这会导致slave将从master读取的更新操作写到自己的二进制日志中。
  3. 在重设同步状态之前保存所有的证据。如果我们没有任何信息或者只有粗略的信息,这将很难或者不可能追查到这个问题。需要收集以下证据:

    • master上的所有二进制日志
    • slave上的所有二进制日志
    • 发现问题时,在master上执行 SHOW MASTER STATUS 的结果
    • 发现问题时,在master上执行 SHOW SLAVE STATUS 的结果
    • 记录master和slave的错误日志

  4. mysqlbinlog 来检查二进制日志。例如,用以下方法有助于找到有问题的查询:
    shell> mysqlbinlog -j pos_from_slave_status \
               /path/to/log_from_slave_status | head
    

一旦收集好了问题的证据,首先将它隔离到一个独立的测试系统上。然后在我们的bug数据库http://bugs.mysql.com/上进可能详细地报告问题。


评论

你好。
我想咨询一下,在同步的时候,电脑断电了,重新启动电脑后不能再同步,要重新设置MASTER_LOG_FILE和MASTER_LOG_POS值才可以继续同步。
请问有什么设置或者方法可以使同步在电脑突然断电重启后还能正常进行?

感谢你抽空解答我的问题。下面这些就是版本,错误信息及设置。我刚接触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
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:\Greenamp\MySQL\bin\mysqld-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 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 status\G
*************************** 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:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error: 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 STATUS' onthis slave.
Skip_Counter: 0
Exec_Master_Log_Pos: 31899609
Relay_Log_Space: 40845695
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: NULL

master端配置:
[mysqld]

port=3306

server-id=1

default-character-set=latin1

default-storage-engine=INNODB

sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

max_connections=300

back_log=100

query_cache_size=48M

table_cache=320

tmp_table_size=52M

thread_cache_size=10

myisam_max_sort_file_size=100G

myisam_max_extra_sort_file_size=100G

myisam_sort_buffer_size=80M

key_buffer_size=8M

read_buffer_size=64K

read_rnd_buffer_size=256K

sort_buffer_size=256K

innodb_additional_mem_pool_size=6M

innodb_flush_log_at_trx_commit=1

innodb_log_buffer_size=2M

innodb_buffer_pool_size=60M

innodb_log_file_size=16M

innodb_thread_concurrency=100

innodb_file_per_table

innodb_open_files=500

innodb_file_io_threads=20

log-bin=My binLog

max_binlog_size=512M

expire_logs_days=1

slave端配置:
[mysqld]

port=3308

server-id=2

default-character-set=latin1

default-storage-engine=INNODB

sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

max_connections=300

back_log=100

query_cache_size=48M

table_cache=320

tmp_table_size=52M

thread_cache_size=10

myisam_max_sort_file_size=100G

myisam_max_extra_sort_file_size=100G

myisam_sort_buffer_size=80M

key_buffer_size=8M

read_buffer_size=64K
read_rnd_buffer_size=256K

sort_buffer_size=256K

innodb_additional_mem_pool_size=6M

innodb_flush_log_at_trx_commit=1

innodb_log_buffer_size=2M

innodb_buffer_pool_size=60M

innodb_log_file_size=16M

innodb_thread_concurrency=100

innodb_file_per_table

innodb_open_files=500

innodb_file_io_threads=20

看来是你的master或者你的relaylog坏了,需要检查 "My binLog.000051" 或者 "tests8000-02-relay-bin.000029" 这两个log中哪个损坏了,然后根据情况再做分析。
如果是binlog坏了,那么建议略过一部分binlog,修改log_pos,重新继续开始复制。
如果只是relaylog坏了,那删除当前的relaylog,然后修改合适的log_pos,继续开始复制。

MySQL中文网: http://imysql.cn
Google MySQL中文用户群:http://groups.google.com/group/imysql

给你的祝福,要让你招架不住!

谢谢你的回复。
因为我是直接把服务器断电的,也就是非法关机,mysql异常退出的。
我做了两次试验,不能复制后运行
CHANGE MASTER TO
MASTER_LOG_FILE='XXX',
MASTER_LOG_POS=xxx;
就能继续开始复制。
但我想知道能不能通过修改设置或者其它方法,避免mysql异常退出(如突然停电)后出现这种情况呢?

呵呵。我用的操作系统是windows,硬盘就不知道是什么了,我做试验的时候是写了个小程序,每0.1秒写48条记录,而且有blob字段的。按你这样说,mysql出现复制不了,这种情况是避免不了的,是吧?

呵呵,我注册用户了。以后请多多指教。。
^_^

我想问一下,数据库同步需要库中的表结构相同,那么我能不能在Master上的表中的某个字段不设索引,而在slave上建索引?
还有同步会不会将Slave中已经存在的数据删除掉(这些数据的key和Master不同)?

1. 可以
2. 如果master上有删除数据的操作,那么slave也会跟着做的

MySQL方案、培训、支持

给你的祝福,要让你招架不住!

您好,2台linux的mysql同步后,在从mysql上show slave status\g看到下面的错误:
Got fatal error 1236 from master when reading data from binary log: 'Binary log is not open'
主服务器设置为:
server-id=1
log-bin=mysql-bin
主的日志文件貌似没看到创建出来,不清楚什么原因?