Zookeeper Server持久化两类数据,Transaction以及Snapshot,logDir存储transaction命令,dataDir存储snap快照,其下子目录名称以version-2命名,子目录内部文件是分别以log.zxid和snapshot. lastProcessedZxid命名,每个目录下可以有很多个这样的文件,
Transaction文件的文件名中zxid是文件中所有命令中zxid最小的zxid,而Snapshot中的lastProcessedZxid是最后一个操作的zxid,一般来讲是最大的zxid。
事务日志记录的是当前要操作的命令以及命令参数,可以认为是动态的,快照记录的是当前的ZK静态数据结构,包括ACL,节点树,session/临时节点对应关系,从下面的结构中可以分析到并没有持久化watch相关数据,watch是怎么搞后面我还得看看。
Transactionlog存储的文件格式:
LogFile:
FileHeader TxnList ZeroPad
FileHeader: {
magic 4bytes (ZKLG)
version 4bytes(2)
dbid 8bytes //该文件所属数据库
}
TxnList:
Txn || Txn TxnList
Txn:
checksum Txnlen TxnHeader Record 0x42
checksum: 8bytes Adler32 is currently used
calculated across payload -- Txnlen, TxnHeader, Record and 0x42
Txnlen:
len 4bytes
TxnHeader: {
sessionid 8bytes
cxid 4bytes//客户端的xid
zxid 8bytes//服务器事务xid
time 8bytes//服务器事务开始时间
type 4bytes//操作的类型
}
Record:
See Jute definition file for details on the various record types
ZeroPad:
0 padded to EOF (filled during preallocation stage)
可以查找最后一个zxid,查找zxid所在的文件,以及删除zxid以后的所有记录和文件。
Snapshot 文件格式:
FileSnap:
FileHeader sessionsData DataTree checksum /[分割线]
FileHeader: {
magic 4bytes (ZKSN)
version 4bytes(2)
dbid 8bytes //该文件所属数据库
}
sessionsData:{
sessioncount 4bytes
sessionList
}
sessionList:
session || session
session:{
id 8bytes //sessionid
timeout 4bytes//过期时间
}
DataTree:
ACLS Nodes
ACLS:
Aclsize acllist
Acllist:
longId acls
Acls:
Perms id{schema,id}
Nodes:
Path node childnodes
Childnoes:
Path node childnodes
Node:
Data[bytes] acl[long] stat[统计信息]
Stat:
Czxid createNode时事务号
mzxid, createNode时与Czxid同,setData时的事务号
ctime 创建节点时间
mtime createNode时与ctime相同,setData时间
version createNode版本为0,setData的数据版本号
cversion createNode版本为0,增加/删除子节点时父节点+1
aversion createNode版本为0,setACL时节点的版本号
ephemeralOwner 临时节点表示sessionid,非临时节点这个值为0
pzxid createNode时与Czxid同,增加/删除子节点时为子节点事务号
FileTxnSnapLog. Restore时会读取snapshot然后根据snapshot中lastProcessedZxid+1后读取命令log重做命令附加到DataTree上。 |