1. sync流程简介
sync行为是由storage向tracker report的时候,响应信息触发为组内每一个storage服务器创建一个同步线程(仅仅一个,单线程同步),并且响应信息还更新线程中storage的状态。同步线程根据storage状态判断工作状态,根据binlog改变实现文件同步。
sync被触发的流程如下,从下而上。
2. storage sync相关源码解析
2.1 sync 触发
sync线程由tracker_merge_servers函数触发。其功能合并storage服务器的状态,触发sync线程,向tracker上报状态不同的storage。
storage/tracker_client_thread.c
static int tracker_merge_servers(ConnectionInfo *pTrackerServer, \
FDFSStorageBrief *briefServers, const int server_count)
{
FDFSStorageBrief *pServer;
FDFSStorageBrief *pEnd;
FDFSStorageServer *pInsertedServer;
FDFSStorageServer **ppFound;
FDFSStorageServer **ppGlobalServer;
FDFSStorageServer **ppGlobalEnd;
FDFSStorageServer targetServer;
FDFSStorageServer *pTargetServer;
FDFSStorageBrief diffServers[FDFS_MAX_SERVERS_EACH_GROUP];
FDFSStorageBrief *pDiffServer;
int res;
int result;
int nDeletedCount;
memset(&targetServer, 0, sizeof(targetServer));
pTargetServer = &targetServer;
nDeletedCount = 0;
pDiffServer = diffServers;
pEnd = briefServers + server_count;
for (pServer=briefServers; pServer<pEnd; pServer++)
{
// 获取输入信息的一个storage信息
memcpy(&(targetServer.server),pServer,sizeof(FDFSStorageBrief));
// 在本地已排序的全局storage服务器列表(g_sorted_storages)查找,是否存在输入的storage信息
ppFound = (FDFSStorageServer **)bsearch(&pTargetServer, \
g_sorted_storages, g_storage_count, \
sizeof(FDFSStorageServer *), storage_cmp_by_server_id);
if (ppFound != NULL) // 存在该storage信息
{
if (g_use_storage_id) // 如果使用id方式,更新g_sorted_storages中该storage ip addr
{
strcpy((*ppFound)->server.ip_addr, pServer->ip_addr);
}
/*
//logInfo("ip_addr=%s, local status: %d, " \
"tracker status: %d", pServer->ip_addr, \
(*ppFound)->server.status, pServer->status);
*/
if ((*ppFound)->server.status == pServer->status)
{ // 如果状态没改变,判断下一个。
continue;
}
// 当输入状态改变为:离线
if (pServer->status == FDFS_STORAGE_STATUS_OFFLINE)
{
if ((*ppFound)->server.status == \
FDFS_STORAGE_STATUS_ACTIVE
|| (*ppFound)->server.status == \
FDFS_STORAGE_STATUS_ONLINE)
{ // 本地状态为:活动或者在线,则改变为离线
(*ppFound)->server.status = \
FDFS_STORAGE_STATUS_OFFLINE;
}
else if ((*ppFound)->server.status != \
FDFS_STORAGE_STATUS_NONE
&& (*ppFound)->server.status != \
FDFS_STORAGE_STATUS_INIT)
{ // 本地状态为:无或者初始化,加入不同状态服务列表,准备告知tracker
// add differ server
memcpy(pDiffServer++, \
&((*ppFound)->server), \
sizeof(FDFSStorageBrief));
}
}
// 当输入状态不为离线
else if ((*ppFound)->server.status == \
FDFS_STORAGE_STATUS_OFFLINE)
{ // 本地状态为:离线,更新本地状态
(*ppFound)->server.status = pServer->status;
}
else if ((*ppFound)->server.status == \
FDFS_STORAGE_STATUS_NONE)
{ // 本地状态:无
if (pServer->status == \
FDFS_STORAGE_STATUS_DELETED \
|| pServer->status == \
FDFS_STORAGE_STATUS_IP_CHANGED)
{ //ignore
// 输入状态:删除,ip改变,直接忽略。
}
else
{
// *** 本地状态为无,变了状态,说明该storage工作了,启动同步线程。
// 备注:storage与storage之间同步线程,是单线程的。
// 仅仅启动一个storage-storage sync线程。
// 注意:函数输入参数为FDFSStorageBrief,指向全局变量g_sorted_storages之中
(*ppFound)->server.status = \
pServer->status;
// start sync threads [ppFound is none, and then change]
if ((result=tracker_start_sync_threads(\
&((*ppFound)->server))) != 0)
{
return result;
}
}
}
else if (((pServer->status == \
FDFS_STORAGE_STATUS_WAIT_SYNC) || \
(pServer->status == \
FDFS_STORAGE_STATUS_SYNCING)) && \
((*ppFound)->server.status > pServer->status))
{
*(pServer->ip_addr + IP_ADDRESS_SIZE - 1) = '\0';
if (is_local_host_ip(pServer->ip_addr) && \
buff2int(pServer->port) == g_server_port)
{
need_rejoin_tracker = true;
logWarning("file: "__FILE__", line: %d, " \
"tracker response status: %d, " \
"local status: %d, need rejoin " \
"tracker server: %s:%d", \
__LINE__, pServer->status, \
(*ppFound)->server.status, \
pTrackerServer->ip_addr,
pTrackerServer->port);
}
// pxxian: add differ server
memcpy(pDiffServer++, &((*ppFound)->server), \
sizeof(FDFSStorageBrief));
}
else
{
(*ppFound)->server.status = pServer->status;
}
} // pxxian: end of if (ppFound != NULL)
else if (pServer->status == FDFS_STORAGE_STATUS_DELETED
|| pServer->status == FDFS_STORAGE_STATUS_IP_CHANGED)
{ //ignore
nDeletedCount++;
}
else
{
/*
//logInfo("ip_addr=%s, tracker status: %d",
pServer->ip_addr, pServer->status);
*/
if ((res=pthread_mutex_lock( \
&reporter_thread_lock)) != 0)
{
logError("file: "__FILE__", line: %d, "\
"call pthread_mutex_lock fail,"\
" errno: %d, error info: %s", \
__LINE__, res, STRERROR(res));
}
// pxxian: add storage server to g_storage_servers and g_sorted_storages
if (g_storag