制表實(shí)戰(zhàn):從虛擬表到落地副本的完整指南)
做 SAP HANA 數(shù)據(jù)集成這幾年我見(jiàn)過(guò)最多的一種誤會(huì)就是以為在 HANA 里建了虛擬表就等于把數(shù)據(jù)拿過(guò)來(lái)了。業(yè)務(wù)同事跑過(guò)來(lái)問(wèn)為什么我在 HANA 里查表報(bào)表還是 20 秒起步一看后臺(tái)查的根本不是本地表SQL 被推到了遠(yuǎn)端源執(zhí)行。真正想解決這類(lèi)問(wèn)題你得把遠(yuǎn)端表變成一份可落地的數(shù)據(jù)副本這就是 SAP HANA 里經(jīng)常提到的 Replica Tables。這篇文章我把遠(yuǎn)端表、虛擬表、復(fù)制表的關(guān)系講透再給一套從初始化到刷新的實(shí)操路徑適合正在做 SAP HANA 數(shù)據(jù)同步、數(shù)倉(cāng)集成或者剛開(kāi)始接觸 SDA/SDI 的讀者。內(nèi)容不繞彎子直接按實(shí)際干活的經(jīng)驗(yàn)來(lái)。1. 先搞清楚虛擬表為什么不夠用1.1 虛擬表不只是“連接”而是一條遠(yuǎn)程執(zhí)行的 SQL 鏈很多剛接觸 SDASmart Data Access的同學(xué)建完 Remote Source 再創(chuàng)建 Virtual Table看到 HANA Catalog 里出現(xiàn)了一張表就以為數(shù)據(jù)已經(jīng)在 HANA 里了。這個(gè)誤解是后面所有性能問(wèn)題的根源。虛擬表的本質(zhì)是一段“查詢(xún)轉(zhuǎn)發(fā)規(guī)則”。你在 HANA 里執(zhí)行SELECT * FROM VT_ORDERSHANA 并不會(huì)把整張表拉回來(lái)而是把這個(gè) SQL 拆解、改寫(xiě)盡量下推給遠(yuǎn)端的源數(shù)據(jù)庫(kù)執(zhí)行。遠(yuǎn)端算完后把結(jié)果集通過(guò)網(wǎng)絡(luò)傳回 HANAHANA 只負(fù)責(zé)最終展示或者做二次加工。這個(gè)過(guò)程很像你電腦上放著某個(gè)網(wǎng)盤(pán)的快捷方式圖標(biāo)看起來(lái)像一個(gè)文件雙擊后其實(shí)還是從遠(yuǎn)端拉內(nèi)容。網(wǎng)盤(pán)里的文件如果很大、網(wǎng)絡(luò)又一般打開(kāi)速度自然感人。虛擬表也這樣它把“計(jì)算壓力”扔給遠(yuǎn)端源把“網(wǎng)絡(luò)壓力”留給自己。對(duì)幾百行的小表問(wèn)題不大一旦源表幾百萬(wàn)行報(bào)表查詢(xún)里又帶 JOIN 和 GROUP BY遠(yuǎn)端源和網(wǎng)絡(luò)的瓶頸馬上暴露出來(lái)。還有個(gè)容易忽略的點(diǎn)虛擬表能不能在 HANA 端做索引、分區(qū)、壓縮都不行。因?yàn)閿?shù)據(jù)根本不在 HANA 里HANA 只是“代轉(zhuǎn)”SQL 的角色。你給虛擬表建索引系統(tǒng)會(huì)直接拒絕想都不要想。1.2 復(fù)制表與虛擬表的本質(zhì)差異存儲(chǔ)換性能理解了虛擬表是“快捷方式”那復(fù)制表就很好解釋了復(fù)制表是把遠(yuǎn)端的數(shù)據(jù)實(shí)際拉下來(lái)在 HANA 本地真實(shí)落盤(pán)存儲(chǔ)形成一份獨(dú)立的、可查詢(xún)、可建索引、可分區(qū)的數(shù)據(jù)副本。它和虛擬表最大的差異只有一個(gè)數(shù)據(jù)到底放在哪。維度虛擬表復(fù)制表/落地副本數(shù)據(jù)存儲(chǔ)位置遠(yuǎn)端源數(shù)據(jù)庫(kù)HANA 本地查詢(xún)執(zhí)行位置遠(yuǎn)端為主HANA 組裝結(jié)果全部在 HANA 本地實(shí)時(shí)性接近實(shí)時(shí)受網(wǎng)絡(luò)和源端負(fù)載影響取決于刷新策略有延遲本地索引/分區(qū)/壓縮不支持完全支持對(duì)遠(yuǎn)端可用性的依賴(lài)每次查詢(xún)都依賴(lài)只在刷新時(shí)依賴(lài)資源消耗網(wǎng)絡(luò)帶寬、遠(yuǎn)端 CPU/IOHANA 本地內(nèi)存和 CPU適用場(chǎng)景小表、低頻查詢(xún)、實(shí)時(shí)訪問(wèn)大表、分析型查詢(xún)、高頻訪問(wèn)一句話總結(jié)復(fù)制表是用 HANA 的存儲(chǔ)空間換查詢(xún)性能。副本一旦建好日常查詢(xún)完全不需要再跑去遠(yuǎn)端拉數(shù)據(jù)也不怕源庫(kù)臨時(shí)抖動(dòng)、連接斷開(kāi)甚至在源庫(kù)維護(hù)窗口期報(bào)表照樣能跑。不過(guò)代價(jià)也很直白HANA 是內(nèi)存數(shù)據(jù)庫(kù)本地副本會(huì)真實(shí)占用內(nèi)存資源同步延遲需要靠刷新頻率控制運(yùn)維上多了一套刷新的監(jiān)控任務(wù)。這也是為什么我標(biāo)題里強(qiáng)調(diào)的是“可落地的數(shù)據(jù)副本”——落地的意思就是真正放進(jìn)了 HANA 的內(nèi)存和磁盤(pán)體系里不再是個(gè)“虛擬映射”。2. 復(fù)制表是怎么工作的什么時(shí)候該用2.1 一條數(shù)據(jù)從遠(yuǎn)端到本地的完整路徑復(fù)制表不是憑空出現(xiàn)的它背后是一條清晰的數(shù)據(jù)鏈路。用我實(shí)際項(xiàng)目里最常見(jiàn)的一條鏈路來(lái)走一遍第一步創(chuàng)建 Remote Source也就是配置遠(yuǎn)端數(shù)據(jù)庫(kù)的連接信息。HANA 通過(guò)這個(gè)連接去和遠(yuǎn)端數(shù)據(jù)庫(kù)建立會(huì)話。第二步在遠(yuǎn)端 Source 上創(chuàng)建 Virtual Table作為取數(shù)的“管道”HANA 要能先“看到”遠(yuǎn)端表的結(jié)構(gòu)和字段。第三步本地建一張目標(biāo)表將虛擬表里的數(shù)據(jù)初始化填入這是副本誕生的關(guān)鍵一步。第四步按照設(shè)定的刷新周期把源端新增或變更的數(shù)據(jù)同步到本地表。第五步業(yè)務(wù)查詢(xún)直接打本地表。你注意看整個(gè)鏈路里虛擬表承擔(dān)的角色很微妙它不是終點(diǎn)而是“取數(shù)的中間層”。建復(fù)制表的時(shí)候?qū)嶋H上還是通過(guò)虛擬表去遠(yuǎn)端取數(shù)據(jù)只不過(guò)取完之后在本地落了地。有人會(huì)問(wèn)能不能直接用一張本地表和遠(yuǎn)端建復(fù)制關(guān)系不建虛擬表在我的經(jīng)驗(yàn)里不建議這樣裸操作。虛擬表充當(dāng)了一個(gè)“結(jié)構(gòu)驗(yàn)證器”你能提前確認(rèn)字段映射、類(lèi)型轉(zhuǎn)換、訪問(wèn)權(quán)限都OK了再?zèng)Q定初始化出問(wèn)題也好排查。2.2 三種同步刷新方式一次性、定時(shí)全量、持續(xù)增量講刷新方式之前先明確一件事復(fù)制表默認(rèn)不會(huì)自動(dòng)更新。你復(fù)制一份副本出來(lái)它就定格在那一刻后續(xù)源表怎么變和它沒(méi)關(guān)系。要讓它保持新鮮必須梳理清楚刷新策略。我習(xí)慣把刷新方式分成三檔第一檔是一次性快照。用CREATE TABLE AS SELECT把數(shù)據(jù)復(fù)制過(guò)來(lái)常用于初始化、測(cè)試環(huán)境搭建、或者遷移臨時(shí)數(shù)據(jù)。它是一次性的跑完就結(jié)束不涉及后續(xù)任務(wù)調(diào)度。第二檔是定時(shí)全量刷新。對(duì)增量控制不敏感的小表比如幾萬(wàn)到幾十萬(wàn)行的維度表就非常合適。每到凌晨或者每小時(shí)把目標(biāo)表清空再重新從虛擬表全量拉一遍。優(yōu)點(diǎn)是邏輯簡(jiǎn)單不容易出錯(cuò)缺點(diǎn)是數(shù)據(jù)量大時(shí)耗時(shí)較長(zhǎng)頻繁全量刷新會(huì)給源庫(kù)增加壓力。第三檔是持續(xù)增量同步。源表有明確的更新時(shí)間戳并且業(yè)務(wù)上有新增和修改就可以按時(shí)間戳做增量。更復(fù)雜的場(chǎng)景比如源表沒(méi)有時(shí)間戳、卻有大量 update 操作那就要靠 SAP HANA SDISmart Data Integration的復(fù)制任務(wù)基于數(shù)據(jù)庫(kù)日志做 CDC 捕獲把數(shù)據(jù)變更實(shí)時(shí)或準(zhǔn)實(shí)時(shí)地同步到 HANA。這三檔沒(méi)有絕對(duì)的好壞我的原則是能用增量不輕易做全量能做全量不勉強(qiáng)設(shè)計(jì) CDC。增量同步是省資源但設(shè)計(jì)不好容易漏數(shù)據(jù)后面第 4 部分我會(huì)專(zhuān)門(mén)講這個(gè)坑。2.3 怎么判斷一張表適不適合落地副本不是什么表都值得做成 Replica Table。我在項(xiàng)目上吃過(guò)虧一開(kāi)始圖省事把業(yè)務(wù)庫(kù)里的核心大表都復(fù)制了一份結(jié)果內(nèi)存吃緊最后還得清理。現(xiàn)在我會(huì)按一套判斷標(biāo)準(zhǔn)來(lái)篩選適合做復(fù)制表的通常是這幾類(lèi)報(bào)表和 BI 場(chǎng)景的底層數(shù)據(jù)表分析查詢(xún)多而且 SQL 復(fù)雜跨庫(kù) JOIN 頻繁每次查詢(xún)都要多次經(jīng)過(guò)網(wǎng)絡(luò)往返性能不可控源庫(kù)是傳統(tǒng)業(yè)務(wù)庫(kù)白天高負(fù)載不希望報(bào)表查詢(xún)?cè)偃D占它的資源表數(shù)據(jù)量在一定可控范圍內(nèi)且 HANA 側(cè)有明確內(nèi)存預(yù)算。不適合做復(fù)制表的我也列一下偶爾才查一次一次查幾行的主數(shù)據(jù)表沒(méi)必要落地需要秒級(jí)看到遠(yuǎn)端最新?tīng)顟B(tài)的實(shí)時(shí)查詢(xún)場(chǎng)景復(fù)制表刷新再快也有延遲數(shù)據(jù)量極大比如幾百億行HANA 內(nèi)存根本放不下源端表結(jié)構(gòu)頻繁變更復(fù)制任務(wù)維護(hù)成本遠(yuǎn)大于收益。我常用的做法是先在虛擬表上做一輪性能測(cè)試打開(kāi)執(zhí)行計(jì)劃看算子是 Pushdown 還是本地處理。如果大部分過(guò)濾和聚合都被下推到遠(yuǎn)端執(zhí)行而且單次查詢(xún)還要等幾秒甚至幾十秒那這張表就值得評(píng)估落地副本。反過(guò)來(lái)如果查詢(xún)本身很簡(jiǎn)單數(shù)據(jù)量又小虛擬表的延遲可以接受就完全沒(méi)必要折騰復(fù)制表。3. 實(shí)操手把手把遠(yuǎn)端表變成 HANA 落地副本3.1 第一步創(chuàng)建 Remote Source先把通道打通不管用 SDA 還是 SDI第一步都是先創(chuàng)建 Remote Source。HANA 的語(yǔ)法大同小異以最常見(jiàn)的 HANA 到 HANA 遠(yuǎn)端源為例CREATE REMOTE SOURCE S4H_SOURCE ADAPTER hdb CONFIGURATION ServerNode10.10.10.20:30015 WITH CREDENTIAL TYPE PASSWORD USING userREPL_USER;password******;如果遠(yuǎn)端是 Oracle、SQL Server、Kafka 這類(lèi)系統(tǒng)需要換對(duì)應(yīng)的 Adapter 和配置參數(shù)。比如連 Oracle 要用ora適配器連 SQL Server 要用sapodbc或sqlserver具體可以在 HANA 的ADAPTERS系統(tǒng)視圖中查到。創(chuàng)建完成后先別急著建表確認(rèn)連接狀態(tài)正常??梢圆橐幌孪到y(tǒng)視圖SELECT * FROM M_REMOTE_SOURCES; SELECT * FROM M_REMOTE_SOURCE_STATUS;確認(rèn)源連接處于正常狀態(tài)后再繼續(xù)下一步。這個(gè)步驟很多人會(huì)跳過(guò)結(jié)果后面建虛擬表時(shí)報(bào)一堆連接錯(cuò)誤來(lái)回折騰。另外權(quán)限方面要注意創(chuàng)建 Remote Source 需要CREATE REMOTE SOURCE權(quán)限使用遠(yuǎn)端連接還需要對(duì)應(yīng)的 Schema 訪問(wèn)權(quán)限。如果建完以后查詢(xún)提示無(wú)權(quán)限優(yōu)先檢查源端數(shù)據(jù)庫(kù)給 REPL_USER 授權(quán)是否到位。3.2 第二步建虛擬表驗(yàn)證遠(yuǎn)端數(shù)據(jù)能查出來(lái)通道打通后創(chuàng)建虛擬表。假設(shè)遠(yuǎn)端源里有一張CONFIG.ORDERS我習(xí)慣在 HANA 這邊的集成 Schema 下建一個(gè)對(duì)應(yīng)的虛擬表CREATE VIRTUAL TABLE INT.VT_ORDERS AT S4H_SOURCE.CONFIG.ORDERS;建完后跑幾個(gè)查詢(xún)做驗(yàn)證。先看數(shù)量SELECT COUNT(*) FROM INT.VT_ORDERS;再看幾條數(shù)據(jù)長(zhǎng)什么樣SELECT * FROM INT.VT_ORDERS LIMIT 100;這里要特別強(qiáng)調(diào)驗(yàn)證查詢(xún)能跑通不代表性能好。我建議順手用 EXPLAIN PLAN 看一下執(zhí)行計(jì)劃EXPLAIN PLAN FOR SELECT REGION, SUM(AMOUNT) FROM INT.VT_ORDERS GROUP BY REGION;如果執(zhí)行計(jì)劃里出現(xiàn)了 Remote、Pushdown 相關(guān)算子說(shuō)明查詢(xún)確實(shí)是下推到遠(yuǎn)端執(zhí)行的。這塊內(nèi)容先記錄下來(lái)后面做性能對(duì)比時(shí)要用。3.3 第三步用 CREATE TABLE AS SELECT 初始化副本虛擬表驗(yàn)證沒(méi)問(wèn)題就可以初始化本地副本了。我平時(shí)最常用的方式就是這條 SQLCREATE TABLE INT.ORDERS_COPY AS (SELECT * FROM INT.VT_ORDERS);這條語(yǔ)句會(huì)創(chuàng)建一張本地表并把虛擬表當(dāng)前的數(shù)據(jù)批量寫(xiě)入。如果實(shí)例默認(rèn)的表類(lèi)型是列存這張副本表就是列存表直接享受 HANA 的壓縮和列式掃描優(yōu)勢(shì)。如果想更穩(wěn)妥地控制表類(lèi)型可以拆成兩步用CREATE COLUMN TABLE手動(dòng)建表結(jié)構(gòu)再用INSERT INTO ... SELECT ...灌數(shù)據(jù)。初始化完成后驗(yàn)證一下表的數(shù)據(jù)量和字段是否和源端對(duì)齊SELECT COUNT(*) FROM INT.ORDERS_COPY; SELECT COLUMN_NAME, DATA_TYPE_NAME FROM TABLE_COLUMNS WHERE SCHEMA_NAME INT AND TABLE_NAME ORDERS_COPY;這一步我建議做一下數(shù)據(jù)比對(duì)別只看行數(shù)。選幾個(gè)關(guān)鍵字段做 SUM 或者 HASH 比對(duì)確保復(fù)制過(guò)程中沒(méi)有類(lèi)型截?cái)嗷蛘呔葋G損。3.4 第四步刷新策略增量還是全量初始化只是開(kāi)始刷新策略決定副本能不能長(zhǎng)期可用。對(duì)小的維度表我直接走全量刷新TRUNCATE TABLE INT.ORDERS_COPY; INSERT INTO INT.ORDERS_COPY SELECT * FROM INT.VT_ORDERS; COMMIT;這里要注意TRUNCATE 之后如果刷新失敗表就是空的業(yè)務(wù)查詢(xún)會(huì)直接受影響。穩(wěn)妥的做法是先 INSERT 到一張臨時(shí)表校驗(yàn)通過(guò)后再切換或者至少把刷新任務(wù)放在業(yè)務(wù)低峰期并做好失敗告警。對(duì)帶時(shí)間戳的大表我做增量刷新最經(jīng)典的是這種寫(xiě)法INSERT INTO INT.ORDERS_COPY SELECT * FROM INT.VT_ORDERS WHERE CREATE_AT ( SELECT COALESCE(MAX(CREATE_AT), TO_TIMESTAMP(1970-01-01 00:00:00, YYYY-MM-DD HH24:MI:SS)) FROM INT.ORDERS_COPY ); COMMIT;如果源表存在 update 操作而不是純追加那 INSERT 會(huì)漏掉修改過(guò)的老數(shù)據(jù)。這種情況我改用 UPSERT 或 MERGE 處理HANA 里 UPSERT 的寫(xiě)法相對(duì)簡(jiǎn)潔UPSERT INT.ORDERS_COPY SELECT * FROM INT.VT_ORDERS WHERE MODIFIED_AT ( SELECT COALESCE(MAX(MODIFIED_AT), TO_TIMESTAMP(1970-01-01 00:00:00, YYYY-MM-DD HH24:MI:SS)) FROM INT.ORDERS_COPY );不過(guò) UPSERT 要求目標(biāo)表必須有明確的主鍵否則 HANA 沒(méi)辦法判斷該插入還是更新。建表的時(shí)候如果忘了定義主鍵這里會(huì)吃不少苦頭。至于調(diào)度方式可以交給 HANA 自身的調(diào)度器、外部 cron 定期調(diào) hdbsql、或 SAP BW 流程鏈觸發(fā)。我的建議是刷新任務(wù)必須帶日志至少記錄開(kāi)始時(shí)間、結(jié)束時(shí)間、影響行數(shù)。否則哪天數(shù)據(jù)對(duì)不上你只能干瞪眼。3.5 第五步驗(yàn)證本地副本查詢(xún)性能和容量副本建好、刷新跑通最后做兩件事性能驗(yàn)證和容量監(jiān)控。性能驗(yàn)證很簡(jiǎn)單拿同一套復(fù)雜 SQL分別跑虛擬表和副本表對(duì)比執(zhí)行時(shí)間。我在項(xiàng)目里見(jiàn)過(guò)一個(gè)典型的例子一個(gè)帶三張表 JOIN 的報(bào)表查詢(xún)虛擬表要跑 25 秒副本表落地后 1.2 秒就出結(jié)果差距快 20 倍。原因很簡(jiǎn)單本地列存表不需要網(wǎng)絡(luò)往返也不依賴(lài)源庫(kù)當(dāng)時(shí)的負(fù)載。容量監(jiān)控方面HANA 是內(nèi)存數(shù)據(jù)庫(kù)我得時(shí)刻關(guān)心副本表占了多少內(nèi)存??梢赃@樣查SELECT SCHEMA_NAME, TABLE_NAME, ESTIMATED_MEMORY_SIZE_IN_TOTAL / 1024 / 1024 AS SIZE_MB FROM M_CS_TABLES WHERE SCHEMA_NAME INT AND TABLE_NAME ORDERS_COPY;如果發(fā)現(xiàn)副本表越來(lái)越多內(nèi)存快撐不住了第一件事就是清理不再需要的副本而不是盲目加內(nèi)存。我見(jiàn)過(guò)太多項(xiàng)目HANA 內(nèi)存告警排查下來(lái)全是冗余副本表。4. 常見(jiàn)問(wèn)題與避坑經(jīng)驗(yàn)4.1 類(lèi)型映射不對(duì)復(fù)制出來(lái)的數(shù)據(jù)缺字段、報(bào)精度錯(cuò)誤HANA 建虛擬表時(shí)會(huì)嘗試把遠(yuǎn)端字段類(lèi)型自動(dòng)映射到本地類(lèi)型。但這個(gè)自動(dòng)映射不是萬(wàn)能的尤其是遇到 Oracle 的 NUMBER、SQL Server 的 DATETIME2、或者一些自定義類(lèi)型時(shí)很容易出現(xiàn)映射異常。比如源表里有個(gè)字段是VARCHAR2(4000)HANA 側(cè)映射成NVARCHAR(5000)一般沒(méi)啥問(wèn)題。但如果源表是RAW、BLOB映射到 HANA 后查詢(xún)可能直接報(bào)錯(cuò)。更隱蔽的是精度問(wèn)題DECIMAL(20, 8)源數(shù)據(jù)復(fù)制到 HANA 變成DECIMAL(18, 4)小數(shù)位直接被截?cái)鄨?bào)表數(shù)字對(duì)不上業(yè)務(wù)方找上門(mén)才發(fā)現(xiàn)。我的規(guī)避辦法是在虛擬表和副本表之間加一層 SQL 視圖做顯式類(lèi)型轉(zhuǎn)換。比如CREATE VIEW INT.V_ORDERS_CAST AS SELECT ORDER_ID, CAST(AMOUNT AS DECIMAL(20, 8)) AS AMOUNT, TO_TIMESTAMP(CREATE_AT) AS CREATE_AT FROM INT.VT_ORDERS;然后基于視圖去初始化副本表。這樣類(lèi)型、精度都在自己的掌控里不會(huì)出莫名其妙的截?cái)鄦?wèn)題。4.2 源表沒(méi)有時(shí)間戳增量同步怎么破這是項(xiàng)目里最頭疼的問(wèn)題。源表設(shè)計(jì)得比較老壓根沒(méi)有CREATE_AT、MODIFIED_AT這類(lèi)字段你又想只同步變化的數(shù)據(jù)怎么辦我試過(guò)的可行方案有三種。第一種是直接放棄增量全量刷新前提是表數(shù)據(jù)量不大。第二種是跟源庫(kù)開(kāi)發(fā)團(tuán)隊(duì)溝通在表上加維護(hù)字段由應(yīng)用層在寫(xiě)入時(shí)維護(hù)MODIFIED_AT實(shí)踐中還算靠譜。第三種就是上 SDI 的基于日志的 CDC讓 HANA 直接讀取源庫(kù)的 redo log 或者歸檔日志來(lái)捕獲數(shù)據(jù)變更不依賴(lài)業(yè)務(wù)字段。我個(gè)人不太推薦“靠主鍵自增 ID 做增量”的做法。主鍵最大 ID 只能捕獲新增完全覆蓋不了 update 和 delete 場(chǎng)景。你以為同步很正常結(jié)果數(shù)據(jù)永遠(yuǎn)是舊的那一版報(bào)表不準(zhǔn)還很難發(fā)現(xiàn)。4.3 復(fù)制任務(wù)失敗先查這三個(gè)地方復(fù)制表刷新任務(wù)掛掉先別慌按順序排查。第一個(gè)查 Remote Source 本身。遠(yuǎn)端數(shù)據(jù)庫(kù)是不是重啟了賬號(hào)密碼是不是過(guò)期了網(wǎng)絡(luò)有沒(méi)有抖動(dòng)。我遇到過(guò)好幾次源庫(kù)做了一次密碼輪換復(fù)制任務(wù)直接失敗日志里還報(bào)Connection refused一看密碼早過(guò)期了。第二個(gè)查目標(biāo)表狀態(tài)。副本表是不是被其他事務(wù)鎖住了或者被 DBA 意外 DROP 了又或者分區(qū)結(jié)構(gòu)被修改過(guò)。刷新腳本里如果有 TRUNCATE表結(jié)構(gòu)一變很容易報(bào)錯(cuò)。第三個(gè)查數(shù)據(jù)本身。增量同步時(shí)源端突然出現(xiàn)一條違反主鍵約束的數(shù)據(jù)或者某個(gè)字段長(zhǎng)度爆掉都可能讓整個(gè)批量 INSERT 中斷。這種情況我建議把刷新腳本拆小批次或者把異常數(shù)據(jù)先抓出來(lái)而不是讓一整批任務(wù)全部滾回去。4.4 副本表悄悄吃掉內(nèi)存容量規(guī)劃要趁早HANA 的容量規(guī)劃里副本表占比經(jīng)常被低估。很多人想的是源表庫(kù)里 500GB壓縮后放 HANA 50GB 總行了吧。實(shí)際上壓縮比取決于數(shù)據(jù)特征寬表、隨機(jī)字符串多的表壓縮比可能只有 2:1而不像數(shù)字型列存那樣能壓到 10:1。我的經(jīng)驗(yàn)是每張副本表在落地前先做一個(gè)采樣壓縮比測(cè)試在 HANA 里建臨時(shí)表灌 100 萬(wàn)行看M_CS_TABLES里的估算內(nèi)存再換算整體容量。千萬(wàn)別等上線了再補(bǔ)救。另外副本表建議按業(yè)務(wù)模塊統(tǒng)一命名比如REP_ORDERS、REP_CUSTOMER集中放在一個(gè) Schema后續(xù)做容量清理時(shí)一眼就能分辨哪張表是副本、哪張表是業(yè)務(wù)表。我見(jiàn)過(guò)生產(chǎn)環(huán)境里副本表和業(yè)務(wù)表混在一起DBA 想清理都不太敢下手。我的個(gè)人體會(huì)復(fù)制表聽(tīng)起來(lái)只是“建個(gè)表灌數(shù)據(jù)”這么簡(jiǎn)單實(shí)際操作里考驗(yàn)人的是刷新策略和容災(zāi)意識(shí)。虛擬表是外聯(lián)副本表是內(nèi)儲(chǔ)兩者互補(bǔ)不是一個(gè)淘汰一個(gè)。我現(xiàn)在的習(xí)慣是任何遠(yuǎn)端表接入 HANA先建虛擬表做評(píng)估確認(rèn)查詢(xún)模式和性能瓶頸再?zèng)Q定要不要轉(zhuǎn)成落地副本。真心建議你也保持這個(gè)節(jié)奏不會(huì)過(guò)度設(shè)計(jì)也不會(huì)漏掉真正需要落地的表。