遭遇MySQL Replication Fatal Error 1236
一套Master-Master Replication的MySQL集群,版本5.1.37。其中一个节点A出现OS异常重启,数据库启动后表现正常。但是没过多久另外一个节点B报错:
091127 21:50:21 [ERROR] Error reading packet from server: Client requested master to start replication from impossible position ( server_errno=1236) 091127 21:50:21 [ERROR] Got fatal error 1236: 'Client requested master to start replication from impossible position' from master when reading data from binary log 091127 21:50:21 [Note] Slave I/O thread exiting, read up to log 'mysql-bin.000535', position 193022771
Slave_IO_Running线程终止。仔细看上面的报错信息,说slave进程试图从mysql-bin.000535日志的position 193022771开始启动恢复,但是该日志中是没有这个position的。
跑到A上通过mysqlbinlog查看该日志,发现最后一个有效position是193009460。而要求的193022771已经大于最后有效的position了。这个原因就搞不明白了,难道是因为A库异常关闭后导致A节点的binlog没有来得及刷到磁盘,而B节点slave已经恢复到前面去了?
$mysqlbinlog mysql-bin.000535 > 1.txt $tail -n 7 1.txt # at 193009460 #091127 20:50:21 server id 1 end_log_pos 193009487 Xid = 194299849 COMMIT/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
尝试将B节点change master到最后一个有效的position处,问题暂时得到解决:
change master to master_log_file='mysql-bin.000535', master_log_pos=193009460
网上搜索了一把,发现logzgh之前也碰到过同样的问题,版本是5.0.51。
使用BBED帮助理解Oracle数据块结构
BBED是Oracle提供的块编辑器,借助BBED,可以帮助我们更好的理解Oracle的Block的结构。当然,反过来说,也只有更加理解块的结构,才能更好的利用BBED完成某些特殊情况下的灾难恢复。
Oracle Data Block的结构简图如下,其中从Data header到Row Data部分合称Data Layer:
--------------------- - Cache Layer - --------------------- - Transaction Layer - --------------------- - Data Header - --------------------- - Table Directory - --------------------- - Row Directory - --------------------- - Free Space - --------------------- - Row Data - --------------------- - Tailchk - ---------------------
通过bbed的map命令,可以看到数据块内部的一些数据结构名:
BBED> map File: /u01/oracle/oradata/dbmon/system.dbf (1) Block: 31729 Dba:0x00407bf1 ------------------------------------------------------------ KTB Data Block (Table/Cluster) struct kcbh, 20 bytes @0 struct ktbbh, 72 bytes @20 struct kdbh, 14 bytes @92 struct kdbt[1], 4 bytes @106 sb2 kdbr[336] @110 ub1 freespace[821] @782 ub1 rowdata[6585] @1603 ub4 tailchk @8188
Cache Layer:Block的第一部分,长度为20字节,内部数据结构名为kcbh,包括
type_kcbh:块类型(table/index,rollback segment,temporary segment等)
frmt_kcbh:块格式(v6,v7,v8)
rdba_kcbh:块地址DBA
bas_kcbh/wrp_kcbh:SCN
seq_kcbh:块的序列号
flg_kcbh:块的标志
BBED> p kcbh struct kcbh, 20 bytes @0 ub1 type_kcbh @0 0x06 ub1 frmt_kcbh @1 0xa2 ub1 spare1_kcbh @2 0x00 ub1 spare2_kcbh @3 0x00 ub4 rdba_kcbh @4 0x00407bf1 ub4 bas_kcbh @8 0xd6449de8 ub2 wrp_kcbh @12 0x0595 ub1 seq_kcbh @14 0x03 ub1 flg_kcbh @15 0x04 (KCBHFCKV) ub2 chkval_kcbh @16 0x9130 ub2 spare3_kcbh @18 0x0000
Transaction Layer:内部结构名kcbbh。分成两部分,第一部分为固定长度,长度为24字节,包含事务相关的一些基本信息。第二部分为可变长度,包含itl,长度根据itl条目的个数变化,每个itl长度为24字节,内部结构名ktbbhitl。
BBED> p ktbbh
struct ktbbh, 72 bytes @20
ub1 ktbbhtyp @20 0x01 (KDDBTDATA)
union ktbbhsid, 4 bytes @24
ub4 ktbbhsg1 @24 0x000050fc
ub4 ktbbhod1 @24 0x000050fc
struct ktbbhcsc, 8 bytes @28
ub4 kscnbas @28 0xd6449de7
ub2 kscnwrp @32 0x0595
b2 ktbbhict @36 2
ub1 ktbbhflg @38 0x02 (NONE)
ub1 ktbbhfsl @39 0x00
ub4 ktbbhfnx @40 0x00000000
struct ktbbhitl[0], 24 bytes @44
struct ktbitxid, 8 bytes @44
ub2 kxidusn @44 0x0008
ub2 kxidslt @46 0x000c
ub4 kxidsqn @48 0x0000e991
struct ktbituba, 8 bytes @52
ub4 kubadba @52 0x0080222e
ub2 kubaseq @56 0x03a4
ub1 kubarec @58 0x22
ub2 ktbitflg @60 0x8000 (KTBFCOM)
union _ktbitun, 2 bytes @62
b2 _ktbitfsc @62 1429
ub2 _ktbitwrp @62 0x0595
ub4 ktbitbas @64 0xd6449de6
struct ktbbhitl[1], 24 bytes @68
struct ktbitxid, 8 bytes @68
ub2 kxidusn @68 0x0008
ub2 kxidslt @70 0x0015
ub4 kxidsqn @72 0x0000e992
struct ktbituba, 8 bytes @76
ub4 kubadba @76 0x0080222e
ub2 kubaseq @80 0x03a4
ub1 kubarec @82 0x23
ub2 ktbitflg @84 0x0001 (NONE)
union _ktbitun, 2 bytes @86
b2 _ktbitfsc @86 0
ub2 _ktbitwrp @86 0x0000
ub4 ktbitbas @88 0x00000000
Data Layer:包括Data Header,Table Directory,Row Directory,Free Space和Row Data。其中
Data Header:长度14字节,内部数据结构名kdbh
BBED> p kdbh struct kdbh, 14 bytes @92 ub1 kdbhflag @92 0x00 (NONE) b1 kdbhntab @93 1 b2 kdbhnrow @94 336 sb2 kdbhfrre @96 -1 sb2 kdbhfsbo @98 690 sb2 kdbhfseo @100 1511 b2 kdbhavsp @102 821 b2 kdbhtosp @104 821
Table Directory: 一般table只有一个条目,cluster则有一个或多个条目。每个条目长4字节,内部数据结构名kdbt。
BBED> p kdbt struct kdbt[0], 4 bytes @106 b2 kdbtoffs @106 0 b2 kdbtnrow @108 336
Row Directory:数目由块中数据的行数决定,每个条目长2字节,内部数据结构名kdbr
BBED> p kdbr sb2 kdbr[0] @110 7998 sb2 kdbr[1] @112 8017 ... sb2 kdbr[335] @780 1511
Free Space:表示数据块中可用空间,内部数据结构名freespace
Row Data:表示实际的数据,内部数据结构名rowdata
Tailchk:保存在块结尾用于校验的数据,长度4个字节,内部结构名tailchk。
BBED>p tailchk ub4 tailchk @8188 0x9de80603
注意到tailchk=bas_kcbh低2字节(9de8)+type_kcbh(06)+seq_kcbh(03)
安装使用BBED
在一次故障处理中,使用到了BBED(Oracle Block Brower and EDitor Tool),这是Oracle一款内部工具,可以直接修改Oracle数据文件块的内容,在一些极端恢复场景下比较有用。该工具不受Oracle支持,所以默认是没有生成可执行文件的,在使用前需要重新连接。
在9i/10g中连接生成bbed:
cd $ORACLE_HOME/rdbms/lib make -f ins_rdbms.mk $ORACLE_HOME/rdbms/lib/bbed
以上生成的bbed可执行文件在$ORACLE_HOME/rdbms/lib目录,可以复制到其他位置或者其他同Oracle版本的机器上运行。也可通过以下命令将bbed生成到$ORACLE_HOME/bin目录
make -f ins_rdbms.mk BBED=$ORACLE_HOME/bin/bbed $ORACLE_HOME/bin/bbed
在11g中生成bbed,需要先从10g中复制如下文件到相应目录,然后再执行上述连接命令:
$ORACLE_HOME/rdbms/lib/ssbbded.o $ORACLE_HOME/rdbms/lib/sbbdpt.o $ORACLE_HOME/rdbms/mesg/bbedus.msb
BBED设置了口令保护,密码为blockedit。BBED的命令行参数:
$bbed help=yes PASSWORD - Required parameter FILENAME - Database file name BLOCKSIZE - Database block size LISTFILE - List file name MODE - [browse/edit] SPOOL - Spool to logfile [no/yes] CMDFILE - BBED command file name LOGFILE - BBED log file name PARFILE - Parameter file name BIFILE - BBED before-image file name REVERT - Rollback changes from BIFILE [no/yes] SILENT - Hide banner [no/yes] HELP - Show all valid parameters [no/yes]
一般将一些常用选项写入到一个parfile中:
blocksize=8192 listfile=filelist.txt mode=edit
其中filelist.txt列出了需要使用BBED编辑的数据文件列表,格式为
文件编号 文件名字 文件大小 1 /u01/oracle/oradata/NinGoo/system.dbf 2097160192 2 /u01/oracle/oradata/NinGoo/test.dbf 2097160192
这里的文件编号不一定要和数据库里的file_id相同,当然最好能设置相同,以免在处理过程中搞混淆了。
$bbed parfile=bbed.par Password: BBED: Release 2.0.0.0.0 - Limited Production on Sun Nov 15 00:26:14 2009 Copyright (c) 1982, 2007, Oracle. All rights reserved. ************* !!! For Oracle Internal Use only !!! *************** BBED> help HELP [| ALL ] BBED> help all SET DBA [ dba | file#, block# ] SET FILENAME 'filename' SET FILE file# SET BLOCK [+/-]block# SET OFFSET [ [+/-]byte offset | symbol | *symbol ] SET BLOCKSIZE bytes SET LIST[FILE] 'filename' SET WIDTH character_count SET COUNT bytes_to_display SET IBASE [ HEX | OCT | DEC ] SET OBASE [ HEX | OCT | DEC ] SET MODE [ BROWSE | EDIT ] SET SPOOL [ Y | N ] SHOW [ | ALL ] INFO MAP[/v] [ DBA | FILENAME | FILE | BLOCK ] DUMP[/v] [ DBA | FILENAME | FILE | BLOCK | OFFSET | COUNT ] PRINT[/x|d|u|o|c] [ DBA | FILE | FILENAME | BLOCK | OFFSET | symbol | *symbol ] EXAMINE[/Nuf] [ DBA | FILE | FILENAME | BLOCK | OFFSET | symbol | *symbol ] : N - a number which specifies a repeat count. u - a letter which specifies a unit size: b - b1, ub1 (byte) h - b2, ub2 (half-word) w - b4, ub4(word) r - Oracle table/index row f - a letter which specifies a display format: x - hexadecimal d - decimal u - unsigned decimal o - octal c - character (native) n - Oracle number t - Oracle date i - Oracle rowid FIND[/x|d|u|o|c] numeric/character string [ TOP | CURR ] COPY [ DBA | FILE | FILENAME | BLOCK ] TO [ DBA | FILE | FILENAME | BLOCK ] MODIFY[/x|d|u|o|c] numeric/character string [ DBA | FILE | FILENAME | BLOCK | OFFSET | symbol | *symbol ] ASSIGN[/x|d|u|o] = : [ DBA | FILE | FILENAME | BLOCK | OFFSET | symbol | *symbol ] : [ value | ] SUM [ DBA | FILE | FILENAME | BLOCK ] [ APPLY ] PUSH [ DBA | FILE | FILENAME | BLOCK | OFFSET ] POP [ALL] REVERT [ DBA | FILE | FILENAME | BLOCK ] UNDO HELP [ | ALL ] VERIFY [ DBA | FILE | FILENAME | BLOCK ] CORRUPT [ DBA | FILE | FILENAME | BLOCK ]
关于bbed的具体用法,这里就不罗嗦了,有兴趣的可以自行学习,下面这篇参考文档非常的详尽:
http://orafaq.com/papers/dissassembling_the_data_block.pdf
Gearman for MySQL
Gearman是一个开源的分布式调度框架,支持多种语言。在分布式环境中,如何管理大量的服务器,将某些任务分发到大量的机器上调度执行,是一个比较大的挑战,Gearman为该类任务提供了一个不错的思路。在未来的MySQL集群环境中,Gearman这类工具应当大有用武之地,所以它也提供了MySQL UDF的支持。

一个Gearman请求的处理过程涉及三个角色:Client -> Job -> Worker。
Client:请求的发起者,可以是 C,PHP,Perl,MySQL UDF 等等。
Job:请求的调度者,用来负责协调把 Client 发出的请求转发给合适的 Worker。
Worker:请求的处理者,可以是 C,PHP,Perl 等等。
因为 Client,Worker 并不限制用一样的语言,所以有利于多语言多系统之间的集成。
常用标签: oracle life MySQL Oracle11g blog dba 新特性 oow2009 oow wordpress
最新评论 | Recent comments
- Cassandra Commitlog on Cassandra存储机制: [...] 上一篇:Cassandra存储机制 [......
- bulletming on 遭遇MySQL Replication Fatal Error 1236: 问题原因我一直觉得就是Master死之前,logbin有用os cache或者本身的cache机制...
- isql on dstat:一款简单直观的os实时监控工具: 可以考虑收费了,呵呵...
- foremire on 如何监控MemCached的状态: 的确,web 方式要直观多...
- bwskyer on dstat:一款简单直观的os实时监控工具: 我倒是觉得Process Monitor蛮不错的...
- P.Linux on dstat:一款简单直观的os实时监控工具: 监控工具整合整合就好了,作成一整套监控系统,现在工具都很分散在各个...
- NinGoo on 使用zlib输出gzip格式的文件: @joey 这个工具已经比较长时间没有更新了,最新的一份代码可以通过这个地...
- joey on 使用zlib输出gzip格式的文件: 希望可以见到最新版本的代码,好好学习学...
- NinGoo on tbstat:实时监控数据库统计状态的小工具: 这个可以使用sprintf函...
- P.Linux on tbstat:实时监控数据库统计状态的小工具: 知道怎么刷新了,用Curses,谢谢宁总。 不过又有新问题用Curses要把输出的...
- Marty on PostgreSQL简介: 还是微软安逸,根本就不支持一致读,省得伤脑...
- NinGoo on PostgreSQL简介: 是的,mvcc不管用什么方式实现,update导致的链表肯定是存在的,否则没法...
- 八神 on PostgreSQL简介: oracle的UNDO方式,对于查询的影响也比较严重,总是要根据ITL事务槽,对应...
- 红唇迷恋 on PostgreSQL安装: 我看到你博客调用twitter,你不怕被墙啊。。...
- NinGoo on tbstat:实时监控数据库统计状态的小工具: @P.Linux:这个你可以去参考一些类似的工具,如innotop/mtop...