MergeServerLogic.lua 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910
  1. --合服逻辑
  2. --[=[
  3. 0.一般在跨服上进行合服, 所以需要把merge目录下用到文件更新到跨服上
  4. 1.更新MergeServerDefine.MERGE_DB_TB中要合并的数据库, 并备份数据库, 方法见 MergeServerDefine
  5. 2.[可选] 先执行一次start.sh, 再杀掉所有游戏服的进程。因为重启游戏服时会根据条件删除一些数据, 这样合服时要处理的数据就少了一些。
  6. 比较前面的游戏服的邮件数据可能有异常, 可先执行/server/cleanExpireMail.sh清理下异常的邮件(需要修改脚本中数据库范围)
  7. 3.将跨服的bin*文件 的/script 目录下的启动文件Main.lua暂时改为其他名字, MainMerger改为Main.lua,合服完毕后再改回来。
  8. 4.检查MergeServerDefine中的MERGE_DB_TB数据库名是否正确, 如果正确则和正常启动游戏一样启动游戏服, 开始进行合服
  9. 5.查看日志oss_merge, 是否有报错, 如果有报错则还原数据, 恢复见方法见 MergeServerDefine
  10. 6.修改mysql区服列表的 port, dbName, megre_server字段, 被合服的 port 和 dbname 要改为目标服一样, 被合服的 megre_server字段更新为宿主服的sid。
  11. sql见sdk数据库下查询中的updateMergeServerData(需要修改数据库范围)
  12. 7.修改linux上被合服的bin*文件名, 防止 start.sh 启动时会把被合服也启动起来。脚本见/server/changebinName.sh (需要修改脚本中范围)
  13. 8.合服完毕, 将步骤3修过的文件名改回原来的名字, 执行start.sh 启动游戏服。
  14. ]=]
  15. local LuaMongo = _G.lua_mongo
  16. local Config = require("Config")
  17. local Log = require("common.Log")
  18. local MergeServerDefine = require("merge.MergeServerDefine")
  19. local MoZhuExcel = require("excel.mozhu")
  20. local MailExcel = require("excel.mail")
  21. local TowerConfig = require("excel.huanjingTower").huanjingTower
  22. local Util = require("common.Util")
  23. local ItemDefine = require("bag.ItemDefine")
  24. local HuanJingTowerLogic = require("huanjingTower.HuanjingTowerLogic")
  25. local GodsAreaConfig = require("excel.godsArea")
  26. local primaryKeyTable = {}
  27. --重复_id缓存表
  28. local repeatIdTb = {}
  29. --目标服和被合服所有玩家的名字缓存表
  30. local allNameTb = {}
  31. --同名数据
  32. local repeatName2Data = {}
  33. local num = 0
  34. --次元魔珠数据缓存表
  35. local mozhuDbCache = { roleList = {}, unionList = {}}
  36. --烟花加成时间
  37. local firesTimeCache = 0
  38. --恶魔之塔最高层数
  39. local towerMaxLevel = 0
  40. local towerHeadCache = {}
  41. local TOWER_LV_HEAD_MAX = HuanJingTowerLogic.TOWER_LV_HEAD_MAX
  42. --创建一个mongo连接实例
  43. local function clientMongoDb(addr)
  44. addr = addr or Config.DB_IP
  45. LuaMongo.client(addr)
  46. end
  47. --切换数据库
  48. local function chooseMongoDb(dbName)
  49. if not dbName or dbName == "" then
  50. print(string.format("数据库名错误, dbName = %s\n", dbName))
  51. return
  52. end
  53. LuaMongo.auth(dbName, Config.DB_USER, Config.DB_PASS)
  54. end
  55. --生成新的 _id
  56. local function generateNewId()
  57. local newId = LuaMongo.id()
  58. return newId
  59. end
  60. --清理部分缓存数据
  61. local function cleanCache()
  62. primaryKeyTable = {}
  63. repeatIdTb = {}
  64. allNameTb = {}
  65. repeatName2Data = {}
  66. mozhuDbCache = { roleList = {}, unionList = {}}
  67. firesTimeCache = 0
  68. towerHeadCache = {}
  69. end
  70. --写日志
  71. local function writeLog(tag, targetDb, sourceDb, sourceColl, info1, info2, docId, errInfo)
  72. local logInfo = string.format("tag: %s, targetDb: %s, sourceDb: %s, sourceColl: %s, info1: %s, info2: %s, docId: %s, errInfo: %s",
  73. tag, targetDb, sourceDb, sourceColl, info1, info2, docId, errInfo)
  74. Log.write(Log.LOGID_OSS_MERGE, logInfo)
  75. end
  76. local function writeLog2(logStr)
  77. Log.write(Log.LOGID_OSS_MERGE, logStr)
  78. end
  79. -------------------------------------------------------------需要单独处理的部分数据---------------------------------------------------------------------
  80. ---------------------------------次元魔蛛/梼杌------------------------------------
  81. local MozhuQueryFiles = { [MergeServerDefine.KEY_CIYUAN_MOZHU] = 1}
  82. --读取
  83. local function loadMoZhuDB(sourceDb, collectionName)
  84. local targetCollection = sourceDb .. collectionName
  85. LuaMongo.find(targetCollection, nil, MozhuQueryFiles)
  86. local data = {}
  87. if not LuaMongo.next(data) then
  88. return nil
  89. end
  90. local targetMoZhuData = data.ciyuanMoZhu
  91. for uuid, roleData in pairs(targetMoZhuData.role or {}) do
  92. mozhuDbCache.roleList[uuid] = roleData
  93. end
  94. for uuid, unionData in pairs(targetMoZhuData.union or {}) do
  95. mozhuDbCache.unionList[uuid] = unionData
  96. num = num + 1
  97. end
  98. end
  99. --随机词条
  100. local function randomCiTiao(data)
  101. local weekTime = Util.getWeekStartTime(os.time())
  102. -- if data.citiaoTime and data.citiaoTime == weekTime then
  103. -- return
  104. -- end
  105. data.citiao = {}
  106. local citiao_rare_max
  107. if not citiao_rare_max then
  108. -- 防止策划删减 词条
  109. citiao_rare_max = 0
  110. for k, v in pairs(MoZhuExcel.citiao) do
  111. if v then
  112. citiao_rare_max = citiao_rare_max + v.quanzhong
  113. end
  114. end
  115. end
  116. local getRare = 0
  117. for i=1, 1 do
  118. local random = math.random(1, citiao_rare_max - getRare)
  119. for k, v in pairs(MoZhuExcel.citiao) do
  120. if not data.citiao[k] and random <= v.quanzhong then
  121. data.citiao[k] = i
  122. getRare = getRare + v.quanzhong
  123. break
  124. elseif not data.citiao[k] then
  125. -- 防止循环最后一个是 已经随机过的 导致 随机不出来
  126. random = random - v.quanzhong
  127. end
  128. end
  129. end
  130. data.citiaoTime = weekTime
  131. end
  132. --初始化魔珠db
  133. local function initMoZhuDB(data)
  134. data.time = os.time()
  135. data.unionRank = {}
  136. data.roleRank = {}
  137. data.role = {}
  138. data.union= {}
  139. --词条
  140. randomCiTiao(data)
  141. end
  142. --插入
  143. local function updateTargetMoZhuDB(targetDb)
  144. local collectionName = MergeServerDefine.COLLECTIONS[3]
  145. local targetCollection = targetDb .. collectionName
  146. LuaMongo.find(targetCollection, nil, MozhuQueryFiles)
  147. local data = {}
  148. if not LuaMongo.next(data) then
  149. return
  150. end
  151. if not data.ciyuanMoZhu then
  152. data.ciyuanMoZhu = {}
  153. initMoZhuDB(data.ciyuanMoZhu)
  154. end
  155. local targetMoZhuData = data.ciyuanMoZhu
  156. local roleRankLen = #targetMoZhuData.roleRank
  157. local unionRankLen = #targetMoZhuData.unionRank
  158. --玩家
  159. for uuid, roleData in pairs(mozhuDbCache.roleList) do
  160. targetMoZhuData.role[uuid] = roleData
  161. roleRankLen = roleRankLen + 1
  162. targetMoZhuData.roleRank[roleRankLen] = uuid
  163. end
  164. --公会
  165. for uuid, unionData in pairs(mozhuDbCache.unionList) do
  166. targetMoZhuData.union[uuid] = unionData
  167. unionRankLen = unionRankLen + 1
  168. targetMoZhuData.unionRank[unionRankLen] = uuid
  169. end
  170. --排序
  171. table.sort(targetMoZhuData.roleRank, function(a, b)
  172. local roleA = targetMoZhuData.role[a]
  173. local roleB = targetMoZhuData.role[b]
  174. return roleA.hurt > roleB.hurt
  175. end)
  176. table.sort(targetMoZhuData.unionRank, function(a, b)
  177. local unionA = targetMoZhuData.union[a]
  178. local unionB = targetMoZhuData.union[b]
  179. if unionA.hurt > unionB.hurt then
  180. return true
  181. elseif unionA.hurt == unionB.hurt then
  182. return unionA.time < unionB.time
  183. end
  184. return false
  185. end)
  186. --更新
  187. LuaMongo.update(targetCollection, {}, {
  188. ["$set"] = {
  189. [MergeServerDefine.KEY_CIYUAN_MOZHU] = targetMoZhuData
  190. },
  191. })
  192. mozhuDbCache = nil
  193. end
  194. ----------------------------------烟花加成时间------------------------------------
  195. local FireQueryFiles = { [MergeServerDefine.KEY_FIREWORKBONUS_TIME] = 1}
  196. --读取
  197. local function loadFireTimeData(sourceDb, collectionName)
  198. local targetCollection = sourceDb .. collectionName
  199. LuaMongo.find(targetCollection, nil, FireQueryFiles)
  200. local data = {}
  201. if not LuaMongo.next(data) then
  202. return nil
  203. end
  204. local now = os.time()
  205. local ti = data.fireWorksBonusTime
  206. if ti and ti > now then
  207. firesTimeCache = firesTimeCache + (ti - now)
  208. end
  209. end
  210. --更新目标库
  211. local function updateTargetFireTimeDB(targetDb)
  212. if firesTimeCache > 0 then
  213. local collectionName = MergeServerDefine.COLLECTIONS[3]
  214. local targetCollection = targetDb .. collectionName
  215. LuaMongo.find(targetCollection, nil, FireQueryFiles)
  216. local data = {}
  217. if not LuaMongo.next(data) then
  218. return
  219. end
  220. local now = os.time()
  221. local ti = data.fireWorksBonusTime
  222. if not ti or ti < now then
  223. ti = now + firesTimeCache
  224. else
  225. ti = ti + firesTimeCache
  226. end
  227. local maxTime = now + MergeServerDefine.FIRE_MAX_TIME
  228. ti = math.min(ti, maxTime)
  229. --更新
  230. LuaMongo.update(targetCollection, {}, {
  231. ["$set"] = {
  232. [MergeServerDefine.KEY_FIREWORKBONUS_TIME] = ti
  233. },
  234. })
  235. end
  236. end
  237. ----------------------------------恶魔之塔------------------------------------
  238. local queryTowerByLv = { lv = nil }
  239. local queryTowerFiles = { headList = 1 }
  240. local function calcTblLen(tb)
  241. local len = 0
  242. for _,_ in pairs(tb) do
  243. len = len + 1
  244. end
  245. return len
  246. end
  247. --加载目标库中tower集合中所有文档的headList
  248. local function loadTowerHeadData(targetDb)
  249. local collectionName = MergeServerDefine.COLLECTIONS[16]
  250. local targetCollection = targetDb .. collectionName
  251. towerMaxLevel = #TowerConfig
  252. for i=1,towerMaxLevel do
  253. queryTowerByLv.lv = i
  254. LuaMongo.find(targetCollection, queryTowerByLv, queryTowerFiles) -- 后续优化: 一次全部读取或者批量读取
  255. local data = {}
  256. if LuaMongo.next(data) then
  257. towerHeadCache[i] = {
  258. subNum = TOWER_LV_HEAD_MAX,
  259. headList = data.headList
  260. }
  261. if data.headList and next(data.headList) then
  262. local len = calcTblLen(data.headList)
  263. if len < TOWER_LV_HEAD_MAX then
  264. towerHeadCache[i].subNum = TOWER_LV_HEAD_MAX - len
  265. end
  266. end
  267. end
  268. end
  269. end
  270. -- 把源库tower集合中的headList插入到目标库的headList中
  271. local function insertTargetTowerHeadCache(sourceDb, coll)
  272. local targetCollection = sourceDb .. coll
  273. for i=1,towerMaxLevel do
  274. towerHeadCache[i] = towerHeadCache[i] or {subNum = TOWER_LV_HEAD_MAX, headList = {}}
  275. local subNum = towerHeadCache[i] and towerHeadCache[i].subNum or 0
  276. if subNum > 0 then
  277. queryTowerByLv.lv = i
  278. LuaMongo.find(targetCollection, queryTowerByLv, queryTowerFiles)
  279. local data = {}
  280. if LuaMongo.next(data) then
  281. local headData = data.headList
  282. if headData and next(headData) then
  283. towerHeadCache[i].headList = towerHeadCache[i].headList or {}
  284. local targetHeadList = towerHeadCache[i].headList
  285. for k,v in pairs(headData) do
  286. targetHeadList[k] = v
  287. subNum = subNum - 1
  288. if subNum <= 0 then
  289. break
  290. end
  291. end
  292. towerHeadCache[i].subNum = subNum
  293. towerHeadCache[i].isChange = true
  294. end
  295. end
  296. end
  297. end
  298. end
  299. --更新目标库的headList
  300. local function updateTargetTowerHeadDB(targetDb)
  301. local collectionName = MergeServerDefine.COLLECTIONS[16]
  302. local targetCollection = targetDb .. collectionName
  303. for i=1,#towerHeadCache do
  304. local data = towerHeadCache[i]
  305. if data.isChange then
  306. --更新
  307. queryTowerByLv.lv = i
  308. LuaMongo.update(targetCollection, queryTowerByLv, { ["$set"] = { headList = data.headList }})
  309. end
  310. end
  311. end
  312. ---------------------------------------玩家同名------------------------------
  313. local NameQueryFiles = { ["name"] = 1 }
  314. --加载目标库所有玩家的名字
  315. local function loadTargetCharName(targetDb)
  316. local collectionName = MergeServerDefine.COLLECTIONS[1]
  317. local targetCollection = targetDb .. collectionName
  318. LuaMongo.find(targetCollection, nil, NameQueryFiles)
  319. while true do
  320. local data = {}
  321. if not LuaMongo.next(data) then
  322. break
  323. end
  324. allNameTb[data.name] = '1'
  325. end
  326. end
  327. --得到一个邮件数据
  328. local mailConfig = MailExcel.mail[MergeServerDefine.MAIL_ID]
  329. local function frontMail(receiverUuid)
  330. local mail = {}
  331. mail.type = 1
  332. mail.receiverUuid = receiverUuid
  333. mail.title = mailConfig.title
  334. mail.content = mailConfig.content
  335. mail.read = nil
  336. mail.senderName = mailConfig.title
  337. mail.head = 0
  338. mail.fbTime = nil
  339. mail.fbContent = nil
  340. mail.time = os.time()
  341. mail.get = nil
  342. mail.flag = 1
  343. mail.items = { { ItemDefine.ITEM_ZUANSHI_ID, MergeServerDefine.MAIL_NUM } }
  344. return mail
  345. end
  346. --给因同名而修改名字的玩家发送补偿邮件
  347. local function sendRepeatNameMail(targetDb)
  348. local coll = MergeServerDefine.COLLECTIONS[2]
  349. local targetCollection = targetDb .. coll
  350. for oldName, v in pairs(repeatName2Data) do
  351. local mail = frontMail(v.uuid)
  352. local _, err = pcall(LuaMongo.insert, targetCollection, mail)
  353. writeLog(MergeServerDefine.CHANGENAME_TAG, targetDb, v.sourceDb, coll, oldName, v.newName, v.uuid, err or "")
  354. end
  355. end
  356. --------------------------------更新合服时间------------------------------------
  357. local function updateMergeTime(targetDb)
  358. local targetCollection = targetDb .. MergeServerDefine.COLLECTIONS[3]
  359. local now = os.time()
  360. LuaMongo.update(targetCollection, {}, {
  361. ["$set"] = {
  362. [MergeServerDefine.KEY_MERGE_TIME] = now
  363. },
  364. })
  365. end
  366. --------------------------------诸神圣域-----------------------------------------
  367. -- 删掉诸神圣域称号
  368. local function deleteGodsAreaChenghao(db)
  369. local chenghaoId = 0
  370. for _, rankCfg in ipairs(GodsAreaConfig.rankList) do
  371. if db.chenghaoList and db.chenghaoList[rankCfg.chenghaoID] then
  372. chenghaoId = rankCfg.chenghaoID
  373. break
  374. end
  375. end
  376. if chenghaoId ~= 0 then
  377. db.chenghaoList[chenghaoId] = nil
  378. if db.chenghao and db.chenghao == chenghaoId then
  379. db.chenghao = nil
  380. end
  381. local logStr = string.format("删除诸神圣域称号, 玩家newUniqueTag: %s, chenghaoId: %d", db.newUniqueTag, chenghaoId)
  382. writeLog2(logStr)
  383. end
  384. end
  385. -------------------------------------------------------------------------------------
  386. -----------------------------------------------------char集合中_id的重复检测和处理-------------------------------------------------
  387. --用于检测不同数据库的char集合中的_id是否有重复, 一般来说通过mongo生成的_id基本不会重复(暂时不用)
  388. local function primaryKeyRepeatCheck()
  389. print("================================检查char集合_id的重复性开始=======================================\n")
  390. local collectionName = MergeServerDefine.COLLECTIONS[1]
  391. for k, dbName in ipairs(MergeServerDefine.MERGE_DB_TB) do
  392. local targetCollection = dbName .. collectionName
  393. LuaMongo.find(targetCollection, nil, nil, {_id = 1})
  394. while true do
  395. local data = {}
  396. if not LuaMongo.next(data) then
  397. break
  398. end
  399. if k ~= 1 then
  400. if primaryKeyTable[data._id] then
  401. repeatIdTb[data._id] = generateNewId()
  402. Log.write(Log.LOGID_OSS_MERGE, string.format("result: %s, targetColl: %s, repeatId: %s, newId: %s",
  403. "Repeat", targetCollection, data._id, repeatIdTb[data._id]))
  404. else
  405. primaryKeyTable[data._id] = '1'
  406. end
  407. else
  408. primaryKeyTable[data._id] = '1'
  409. end
  410. end
  411. end
  412. print("================================检查char集合_id的重复性结束=======================================\n")
  413. end
  414. --好友集合
  415. local function handleFriend(data)
  416. if repeatIdTb[data.uuid1] then
  417. data.uuid1 = repeatIdTb[data.uuid1]
  418. end
  419. if repeatIdTb[data.uuid2] then
  420. data.uuid2 = repeatIdTb[data.uuid2]
  421. end
  422. end
  423. --邮件集合
  424. local function handleMail(data)
  425. if repeatIdTb[data.receiverUuid] then
  426. data.receiverUuid = repeatIdTb[data.receiverUuid]
  427. end
  428. end
  429. --公会集合
  430. local function handleUnion(data)
  431. local tb = {}
  432. for id, v in pairs(data.member) do
  433. if repeatIdTb[id] then
  434. tb[id] = v
  435. end
  436. end
  437. for id, v in pairs(tb) do
  438. data.member[id] = nil
  439. data.member[repeatIdTb[id]] = v
  440. end
  441. tb = {}
  442. for id, v in pairs(data.apply) do
  443. if repeatIdTb[id] then
  444. tb[id] = v
  445. end
  446. end
  447. for id, v in pairs(tb) do
  448. data.apply[id] = nil
  449. data.apply[repeatIdTb[id]] = v
  450. end
  451. if data.presidentUuid and repeatIdTb[data.presidentUuid] then
  452. data.presidentUuid = repeatIdTb[data.presidentUuid]
  453. end
  454. end
  455. --星空争霸集合
  456. local function handleStar(data)
  457. if repeatIdTb[data.uuid] then
  458. data.uuid = repeatIdTb[data.uuid]
  459. end
  460. end
  461. --单人竞技场集合
  462. local function handleJJC(data)
  463. if not data.monsterOutID and repeatIdTb[data._id] then
  464. data._id = repeatIdTb[data._id]
  465. end
  466. end
  467. --战斗视频集合
  468. local function handleVideo(data)
  469. local uuid = data.combatInfo.attacker.uuid
  470. if repeatIdTb[uuid] then
  471. data.combatInfo.attacker.uuid = repeatIdTb[uuid]
  472. end
  473. end
  474. ----------------------------------------------------合并数据----------------------------------------------------------
  475. local function dbCheck()
  476. if #MergeServerDefine.MERGE_DB_TB ~= #MergeServerDefine.MERGE_CHECK_TB then
  477. print("=================数据异常=============")
  478. return
  479. end
  480. for idx, dbArray in ipairs(MergeServerDefine.MERGE_DB_TB) do
  481. local checkArray = MergeServerDefine.MERGE_CHECK_TB[idx]
  482. if not checkArray or #checkArray ~= #dbArray then
  483. print(string.format("数据库数量与检查数量不相同"))
  484. return
  485. end
  486. for i, dbName in ipairs(dbArray) do
  487. local chackTb = checkArray[i]
  488. if not chackTb then
  489. print(string.format("检查表中缺失数据, idx1: %d, idx2: %d", idx, i))
  490. return
  491. end
  492. local channelId = chackTb[1]
  493. local serverId = chackTb[2]
  494. local opType = chackTb[3]
  495. if i == 1 and opType ~= 0 then
  496. print(string.format("检查表错误, idx1: %d, idx2: %d", idx, i))
  497. return
  498. end
  499. if i > 1 and opType == 0 then
  500. print(string.format("检查表错误, idx1: %d, idx2: %d", idx, i))
  501. return
  502. end
  503. local dbNameNum = (MergeServerDefine.CHANNEL_2_DBNUMBER[channelId] or 0) + serverId
  504. local correctDBName = MergeServerDefine.DB_NAME_STR .. dbNameNum
  505. if dbName ~= correctDBName then
  506. print(string.format("数据库名错误, idx1: %d, idx2: %d", idx, i))
  507. return
  508. end
  509. end
  510. end
  511. return true
  512. end
  513. local writeQueue = {}
  514. local function flushWriteQueue()
  515. for _, task in ipairs(writeQueue) do
  516. local ok, err = pcall(LuaMongo.insert, task.collection, task.data)
  517. if not ok then
  518. Log.write(Log.LOGID_OSS_MERGE, task.collection, err)
  519. end
  520. end
  521. writeQueue = {}
  522. end
  523. -- 每积累100条数据批量写入
  524. local function bufferedInsert(collection, data)
  525. table.insert(writeQueue, {collection=collection, data=data})
  526. if #writeQueue >= 100 then
  527. flushWriteQueue()
  528. end
  529. end
  530. local function processCollection(sourceDb, targetDb, coll)
  531. local sourceCollection = sourceDb .. coll
  532. local targetCollection = targetDb .. coll
  533. local errNum = 0
  534. local allNum = 0
  535. LuaMongo.find(sourceCollection, nil, {})
  536. while true do
  537. local data = {}
  538. if not LuaMongo.next(data) then
  539. break
  540. end
  541. --直接插入目标库
  542. local ok, err = pcall(LuaMongo.insert, targetCollection, data)
  543. if not ok then
  544. errNum = errNum + 1
  545. writeLog(MergeServerDefine.ERR_TAG, targetDb, sourceDb, coll, 1, 1, data._id, err)
  546. end
  547. allNum = allNum + 1
  548. end
  549. writeLog(MergeServerDefine.SUCC_TAG, targetDb, sourceDb, coll, allNum, errNum, "", "")
  550. end
  551. --合并char集合
  552. local function processCharColl(sourceDb, targetDb, coll, sourceDbTp)
  553. local sourceCollection = sourceDb .. coll
  554. local targetCollection = targetDb .. coll
  555. local errNum = 0
  556. local allNum = 0
  557. LuaMongo.find(sourceCollection, nil, {})
  558. while true do
  559. local data = {}
  560. if not LuaMongo.next(data) then
  561. break
  562. end
  563. --同名检测
  564. if allNameTb[data.name] then
  565. num = num + 1
  566. local newName = MergeServerDefine.NEW_NAME .. num
  567. --统计数据
  568. repeatName2Data[data.name] = {
  569. uuid = data._id,
  570. newName = newName,
  571. sourceDb = sourceDb,
  572. }
  573. --改名
  574. data.name = newName
  575. end
  576. allNameTb[data.name] = '1'
  577. -- 诸神圣域称号处理
  578. if sourceDbTp == 2 then
  579. deleteGodsAreaChenghao(data)
  580. end
  581. --插入目标库
  582. local ok, err = pcall(LuaMongo.insert, targetCollection, data)
  583. if not ok then
  584. errNum = errNum + 1
  585. writeLog(MergeServerDefine.ERR_TAG, targetDb, sourceDb, coll, 1, 1, data._id, err)
  586. end
  587. allNum = allNum + 1
  588. end
  589. writeLog(MergeServerDefine.SUCC_TAG, targetDb, sourceDb, coll, allNum, errNum, "", "")
  590. end
  591. local function startMergeServer(dbArray)
  592. assert(dbArray and next(dbArray), "====数据错误====")
  593. cleanCache()
  594. --目标集合数据库名
  595. local targetDb = dbArray[1][1]
  596. loadTargetCharName(targetDb)
  597. loadTowerHeadData(targetDb)
  598. for i = 2, #dbArray do
  599. -- local moveOhtherCS = false
  600. -- local checkTb = MergeServerDefine.MERGE_CHECK_TB[idx][i]
  601. -- if checkTb[3] == 2 then
  602. -- moveOhtherCS = true
  603. -- end
  604. local sourceDb = dbArray[i][1]
  605. local opType = dbArray[i][2]
  606. LuaMongo.auth(sourceDb, Config.DB_USER, Config.DB_PASS)
  607. for _, coll in ipairs(MergeServerDefine.COLLECTIONS) do
  608. if not MergeServerDefine.NO_INSERT_COLLECTIONS[coll] then
  609. print(string.format("=============开始合并集合, 目标数据库: %s, 源数据库:%s, 集合:%s\n", targetDb, sourceDb, coll))
  610. if coll == MergeServerDefine.COLLECTIONS[1] then
  611. processCharColl(sourceDb, targetDb, coll, opType)
  612. elseif coll == MergeServerDefine.COLLECTIONS[3] then
  613. loadMoZhuDB(sourceDb, coll)
  614. loadFireTimeData(sourceDb, coll)
  615. elseif coll == MergeServerDefine.COLLECTIONS[16] then
  616. insertTargetTowerHeadCache(sourceDb, coll)
  617. else
  618. processCollection(sourceDb, targetDb, coll)
  619. end
  620. -- _G.collectgarbage("collect")
  621. end
  622. end
  623. end
  624. --处理那些需要单独处理的数据
  625. updateTargetMoZhuDB(targetDb)
  626. updateTargetFireTimeDB(targetDb)
  627. sendRepeatNameMail(targetDb)
  628. updateTargetTowerHeadDB(targetDb)
  629. updateMergeTime(targetDb)
  630. end
  631. local function getDBInfo()
  632. for _, chanelId in ipairs(Config.SVR_CHANEL) do
  633. if MergeServerDefine.MERGE_CHECK_TB[chanelId] then
  634. return MergeServerDefine.MERGE_CHECK_TB[chanelId]
  635. end
  636. end
  637. end
  638. local concatTb = { [1] = MergeServerDefine.DB_NAME_STR }
  639. local function generateDBName(dbInfo)
  640. local channelId = dbInfo[1]
  641. local serverId = dbInfo[2]
  642. local opType = dbInfo[3]
  643. local dbName_Number = MergeServerDefine.CHANNEL_2_DBNUMBER[channelId] + serverId
  644. concatTb[2] = dbName_Number
  645. local finalName = table.concat(concatTb)
  646. print("======generateDBName:", finalName, opType)
  647. return finalName, opType
  648. end
  649. local function generateDBArray()
  650. local dbBaseInfo = getDBInfo()
  651. if not dbBaseInfo or not next(dbBaseInfo) then
  652. return
  653. end
  654. local dbNameTb = {}
  655. for k, infoArray in ipairs(dbBaseInfo) do
  656. dbNameTb[k] = dbNameTb[k] or {}
  657. local dbTb = dbNameTb[k]
  658. for _, dbInfo in ipairs(infoArray) do
  659. local dbName, opType = generateDBName(dbInfo)
  660. if not dbName or not opType then
  661. return
  662. end
  663. dbTb[#dbTb+1] = {dbName, opType}
  664. end
  665. end
  666. return dbNameTb
  667. end
  668. --合服开始函数
  669. function Start()
  670. -- if not dbCheck() then
  671. -- return
  672. -- end
  673. local dbArray = generateDBArray()
  674. if not dbArray or not next(dbArray) then
  675. print("生成合服数据库列表失败")
  676. return
  677. end
  678. --创建mongo连接实例
  679. clientMongoDb()
  680. --检查char集合_id的重复性
  681. --primaryKeyRepeatCheck()
  682. print("========================合服开始=====================")
  683. -- for i, dbList in ipairs(MergeServerDefine.MERGE_DB_TB) do
  684. -- startMergeServer(dbList, i)
  685. -- end
  686. for _, dbList in ipairs(dbArray) do
  687. startMergeServer(dbList)
  688. end
  689. print("========================合服结束=====================")
  690. end