備庫(kù)查詢被中止
1、問(wèn)題現(xiàn)象
部署流復(fù)制環(huán)境后,備庫(kù)可提供只讀操作,通常會(huì)將一些執(zhí)行時(shí)間較長(zhǎng)的分析任務(wù)、統(tǒng)計(jì)SQL跑在備庫(kù)上,從而減輕主庫(kù)壓力,在備庫(kù)上執(zhí)行一些長(zhǎng)時(shí)間SQL時(shí),可能會(huì)出現(xiàn)以下錯(cuò)誤并被中止:
ERROR: canceling statement due to conflict with recovery
DETAIL: User query might have needed to see row versions that must be removed.
根據(jù)報(bào)錯(cuò)信息,在備庫(kù)上執(zhí)行長(zhǎng)時(shí)間查詢過(guò)程中,由于此查詢涉及的記錄有可能在主庫(kù)上被更新或刪除,根據(jù)瀚高數(shù)據(jù)庫(kù)的 mvcc 機(jī)制,更新或刪除的數(shù)據(jù)不是立即從物理塊上刪除,而是之后 autovacuum 進(jìn)程對(duì)老版本數(shù)據(jù)進(jìn)行 vacuum,主庫(kù)上對(duì)更新或刪除數(shù)據(jù)的老版本進(jìn)行 vacuum 后,從庫(kù)上也會(huì)執(zhí)行此操作,從而與從庫(kù)當(dāng)前查詢產(chǎn)生沖突,導(dǎo)致查詢被中斷并拋出以上錯(cuò)誤。
2、解決方案
通過(guò)配置參數(shù)可減少或避免這種查詢?nèi)∠那闆r:
- 可能與正在應(yīng)用的WAL發(fā)生沖突,此查詢?nèi)?0秒沒(méi)有執(zhí)行完成則被中止,注意30秒不是備庫(kù)上單個(gè)查詢?cè)试S的最大執(zhí)行時(shí)間,是指當(dāng)備庫(kù)上應(yīng)用WAL時(shí)允許的最大WAL延遲應(yīng)用時(shí)間,因此備庫(kù)上查詢的執(zhí)行時(shí)間有可能達(dá)不到這個(gè)參數(shù)設(shè)置的值就被中止,此參數(shù)可設(shè)置成-1,表示當(dāng)從庫(kù)上的WAL應(yīng)用進(jìn)程與從庫(kù)上執(zhí)行的查詢沖突時(shí),WAL 應(yīng)用進(jìn)程一直等待直到從庫(kù)查詢執(zhí)行完成。
- hot_standby_feedback = on,默認(rèn)情況下從庫(kù)執(zhí)行查詢時(shí)并不會(huì)通知主庫(kù),設(shè)置此參數(shù)為on后從庫(kù)執(zhí)行查詢時(shí)會(huì)通知主庫(kù),當(dāng)從庫(kù)執(zhí)行查詢過(guò)程中,主庫(kù)不會(huì)清理從庫(kù)需要的數(shù)據(jù)行老版本,因此備用服務(wù)器上的查詢能夠可靠地完成,查詢不會(huì)被中止,這種方法同時(shí)也會(huì)導(dǎo)致主庫(kù)上的表可能出現(xiàn)膨脹,主庫(kù)表的膨脹程度與表上的寫(xiě)事務(wù)和從庫(kù)上大查詢的執(zhí)行時(shí)間有關(guān),此參數(shù)默認(rèn)為off。