產(chǎn)數(shù)據(jù)庫(kù)達(dá)夢(mèng)DM8實(shí)戰(zhàn):Oracle兼容性、數(shù)據(jù)遷移與運(yùn)維全記錄)
用了多年通用數(shù)據(jù)庫(kù)突然接到一整套“國(guó)產(chǎn)數(shù)據(jù)庫(kù)技術(shù)”課程配套達(dá)夢(mèng) DM8 的學(xué)習(xí)任務(wù)時(shí)我第一反應(yīng)其實(shí)是有點(diǎn)不屑的。畢竟習(xí)慣了成熟生態(tài)的外來(lái)數(shù)據(jù)庫(kù)總覺(jué)得國(guó)產(chǎn)庫(kù)大概率就是改個(gè)殼、抄點(diǎn)語(yǔ)法。真正啃完這套《國(guó)產(chǎn)數(shù)據(jù)庫(kù)技術(shù)》的全程筆記自己動(dòng)手把 DM8 從安裝、建庫(kù)、SQL 適配、應(yīng)用接入一直到備份恢復(fù)全部走了一遍之后我必須承認(rèn)之前那種預(yù)判多少帶點(diǎn)偏見(jiàn)。達(dá)夢(mèng) DM8 在架構(gòu)上是完整的關(guān)系型數(shù)據(jù)庫(kù)并且在 Oracle 兼容性上花了大功夫同時(shí)在 MySQL 遷移、運(yùn)維工具鏈、高可用方案上都有可落地的東西。本文就是我從零開(kāi)始摸 DM8 的完整記錄把每一個(gè)決策背后的邏輯、踩過(guò)的坑、可以直接照抄的命令全部整理出來(lái)給正在評(píng)估國(guó)產(chǎn)數(shù)據(jù)庫(kù)或者要接手 DM8 項(xiàng)目的同行一個(gè)真實(shí)參考。無(wú)論你是 DBA、后端開(kāi)發(fā)還是技術(shù)選型負(fù)責(zé)人這套筆記應(yīng)該都能幫你少走幾天彎路。1. 先看全局達(dá)夢(mèng) DM8 到底是什么樣的數(shù)據(jù)庫(kù)1.1 自研內(nèi)核但兼容性做了雙軌很多人的疑問(wèn)是第一位的達(dá)夢(mèng) DM8 到底是自己寫(xiě)的還是基于某個(gè)開(kāi)源分支改的我在學(xué)習(xí)過(guò)程中查了不少架構(gòu)資料從官方技術(shù)白皮書(shū)和實(shí)際安裝后的文件結(jié)構(gòu)來(lái)判斷DM8 的底層執(zhí)行引擎、存儲(chǔ)管理、事務(wù)處理都是獨(dú)立實(shí)現(xiàn)不是 MySQL 或者 PostgreSQL 的分支產(chǎn)物。這個(gè)判斷層面的問(wèn)題很重要因?yàn)樗鼪Q定了后續(xù)所有操作的思維方式。如果是基于開(kāi)源庫(kù)做的二次開(kāi)發(fā)那我用開(kāi)源社區(qū)的經(jīng)驗(yàn)就能直接套但 DM8 不是所以它的初始化工具、配置文件、系統(tǒng)視圖、備份命令等都有自己的一套命名和邏輯。比如它沒(méi)有 MySQL 那種my.cnf而是用dm.ini作為實(shí)例配置文件默認(rèn)端口是5236管理工具有獨(dú)立的manager圖形界面和disql命令行工具。這些都是自成一體的體系。但兼容性方面它確實(shí)參考了主流數(shù)據(jù)庫(kù)的生態(tài)習(xí)慣。官方文檔里明確提到兼容 Oracle 語(yǔ)法和 MySQL 語(yǔ)法兩種模式實(shí)際體驗(yàn)下來(lái)Oracle 模式的完成度明顯更高。很多 PL/SQL 風(fēng)格的包、存儲(chǔ)過(guò)程、數(shù)據(jù)類型在 DM8 里能找到對(duì)應(yīng)物這對(duì)從 Oracle 遷移過(guò)來(lái)的團(tuán)隊(duì)極其友好。MySQL 模式更多是提供一些常用函數(shù)的別名和系統(tǒng)行為上的模擬畢竟 MySQL 生態(tài)也有大量用戶。1.2 它適合放在什么場(chǎng)景里學(xué)完整個(gè)課程我對(duì) DM8 的定位有了自己的判斷它不是想在所有場(chǎng)景里跟主流數(shù)據(jù)庫(kù)硬碰硬而是重點(diǎn)解決“基礎(chǔ)軟件供應(yīng)鏈安全”環(huán)境下政企、金融、電力、制造等行業(yè)的核心業(yè)務(wù)替換需求。這些場(chǎng)景有個(gè)共同特征并發(fā)事務(wù)量大、數(shù)據(jù)一致性要求高、需要嚴(yán)格的權(quán)限管控和審計(jì)能力。DM8 的行級(jí)鎖、MVCC 機(jī)制、完備的備份恢復(fù)體系、支持共享存儲(chǔ)集群都是沖著這些需求設(shè)計(jì)的。如果你只是做一個(gè)個(gè)人博客或者小網(wǎng)站那它確實(shí)沒(méi)必要但如果你面對(duì)的是一個(gè)需要固定預(yù)算內(nèi)完成國(guó)產(chǎn)化替代的正式項(xiàng)目DM8 是非?,F(xiàn)實(shí)的選擇。我學(xué)習(xí)時(shí)的判斷框架是先看它能不能把原業(yè)務(wù)平滑接住再看運(yùn)維和學(xué)習(xí)成本能不能承受。答案是在兼容層做得足夠好的前提下DM8 的上手難度并沒(méi)有想象中高尤其是有 Oracle 經(jīng)驗(yàn)的人適應(yīng)周期會(huì)非常短。1.3 目錄結(jié)構(gòu)與關(guān)鍵進(jìn)程安裝完 DM8 之后有件事建議第一時(shí)間做把安裝目錄結(jié)構(gòu)和進(jìn)程關(guān)系搞清楚。以我用的 Linux 環(huán)境為例默認(rèn)安裝目錄是/opt/dmdbms。/opt/dmdbms/ ├── bin/ # 可執(zhí)行文件包含 disql、dmserver、dmrman 等 ├── data/ # 默認(rèn)數(shù)據(jù)文件目錄包含實(shí)例目錄 ├── dm.ini # 默認(rèn)實(shí)例配置文件 ├── log/ # 日志目錄 ├── tool/ # 管理工具dmmanger、dmmonitor 等 └── web/ # 部分圖形工具使用啟動(dòng)實(shí)例時(shí)核心進(jìn)程是dmserver它會(huì)讀取dm.ini里的參數(shù)完成初始化。整個(gè)數(shù)據(jù)庫(kù)實(shí)例和一個(gè)操作系統(tǒng)進(jìn)程強(qiáng)綁定這點(diǎn)要記住因?yàn)樽鰡⑼2僮鞯臅r(shí)候經(jīng)常會(huì)需要用到進(jìn)程管理命令來(lái)確認(rèn)狀態(tài)。我習(xí)慣用ps -ef | grep dmserver來(lái)快速判斷實(shí)例是否正常。提示DM8 對(duì)目錄權(quán)限比較較真尤其是數(shù)據(jù)目錄如果使用非 root 用戶安裝務(wù)必保證該用戶對(duì)數(shù)據(jù)目錄有完整權(quán)限否則啟動(dòng)時(shí)會(huì)報(bào)各種奇怪的權(quán)限錯(cuò)誤。2. 環(huán)境搭建與初始化把第一個(gè)實(shí)例跑起來(lái)2.1 安裝前的前置檢查我在這步踩過(guò)一個(gè)典型的坑沒(méi)檢查系統(tǒng)依賴庫(kù)就開(kāi)裝結(jié)果圖形界面起不來(lái)只能重新補(bǔ)包。在 Linux 上安裝 DM8需要先確認(rèn)幾個(gè)基礎(chǔ)條件操作系統(tǒng)架構(gòu)x86_64 還是 ARM不同架構(gòu)要下載對(duì)應(yīng)安裝包。內(nèi)存建議至少 2GB 可用磁盤(pán)預(yù)留 10GB 以上因?yàn)榘惭b包本身和解壓后的文件都不小。需要 glibc 等基礎(chǔ)庫(kù)如果是精簡(jiǎn)版系統(tǒng)建議用ldd檢查一下安裝盤(pán)里的可執(zhí)行文件依賴是否齊全。另外官方有圖形安裝、命令行安裝和靜默安裝三種方式。我在虛擬機(jī)里第一次用的是圖形安裝畢竟交互性強(qiáng)適合學(xué)習(xí)真正要批量部署的時(shí)候靜默安裝才是王道。2.2 靜默安裝其實(shí)更實(shí)用圖形安裝沒(méi)什么好說(shuō)的下一步下一步就行。靜默安裝的好處是參數(shù)化、可重復(fù)適合以后在多臺(tái)機(jī)器上部署。官方提供了一個(gè)配置文件模板我按照模板改了關(guān)鍵路徑和端口后執(zhí)行./DMInstall.bin -q /path/to/install_conf.xml配置模板里核心是這幾個(gè)參數(shù)INSTALL_PATH/opt/dmdbms/INSTALL_PATH INSTALL_TYPEDATABASE/INSTALL_TYPE PORT5236/PORT DB_NAMEDAMENG/DB_NAME DB_INSTANCE_NAMEDMSERVER/DB_INSTANCE_NAME SYSDBA_PWDSYSDBA001/SYSDBA_PWD注意這里的SYSDBA_PWD是數(shù)據(jù)庫(kù)超級(jí)管理員密碼不是操作系統(tǒng)密碼。安裝完成之后一定要立刻改默認(rèn)密碼這屬于最基本的安全習(xí)慣課程里反復(fù)強(qiáng)調(diào)實(shí)際生產(chǎn)也是如此。注意靜默安裝完成后默認(rèn)會(huì)創(chuàng)建一個(gè)名為 DAMENG 的數(shù)據(jù)庫(kù)實(shí)例初始化參數(shù)是默認(rèn)的。如果你對(duì)頁(yè)大小、字符集有特殊要求后面建庫(kù)時(shí)要用工具重新創(chuàng)建實(shí)例。2.3 初始化實(shí)例的關(guān)鍵參數(shù)選擇DM8 的實(shí)例創(chuàng)建可以用圖形化的“數(shù)據(jù)庫(kù)配置助手”也可以用命令行。我更推薦命令行方便記錄和復(fù)現(xiàn)。初始化實(shí)例時(shí)有兩個(gè)參數(shù)必須提前想清楚因?yàn)榻◣?kù)之后很難修改第一個(gè)是PAGE_SIZE頁(yè)大小。DM8 支持 4K、8K、16K、32K 的頁(yè)大小。頁(yè)大小會(huì)直接影響單行最大長(zhǎng)度、表空間文件最大大小以及數(shù)據(jù)庫(kù)的整體 I/O 行為。默認(rèn) 8K 對(duì)絕大多數(shù)業(yè)務(wù)是合適的但如果你的業(yè)務(wù)涉及大字段、超長(zhǎng)字符串建議直接上 16K。我在模擬項(xiàng)目 X 里因?yàn)橐婚_(kāi)始用了默認(rèn) 8K后面設(shè)計(jì)表時(shí)發(fā)現(xiàn)某些 VARCHAR 長(zhǎng)度組合放不下只能重建庫(kù)非常折騰。第二個(gè)是字符集。DM8 默認(rèn)是 GB18030這是在中文 Windows 等環(huán)境下的老傳統(tǒng)但對(duì)現(xiàn)代業(yè)務(wù)來(lái)說(shuō)UTF-8 是更通用且避免亂碼的選擇。我建議直接選UTF-8。命令行方式創(chuàng)建實(shí)例如下cd /opt/dmdbms/bin ./dminit PATH/opt/dmdbms/data DM_INI/opt/dmdbms/data/DAMENG/dm.ini \ PAGE_SIZE16 CHAR_CODEUTF8 CASE_SENSITIVE0這里我額外設(shè)置了CASE_SENSITIVE0意思是標(biāo)識(shí)符大小寫(xiě)不敏感。這個(gè)參數(shù)很影響使用體驗(yàn)。默認(rèn)情況下 DM8 是大小寫(xiě)敏感的如果你從 MySQL 遷過(guò)來(lái)表名字段名習(xí)慣用大寫(xiě)或者小寫(xiě)很容易被這個(gè)坑到。對(duì)大多數(shù)業(yè)務(wù)應(yīng)用關(guān)掉大小寫(xiě)敏感會(huì)更順手。2.4 服務(wù)注冊(cè)與啟停初始化完成后需要把數(shù)據(jù)庫(kù)注冊(cè)成系統(tǒng)服務(wù)或者至少知道怎么手動(dòng)啟停。手動(dòng)方式最簡(jiǎn)單直接調(diào)dmservercd /opt/dmdbms/bin ./dmserver /opt/dmdbms/data/DAMENG/dm.ini前臺(tái)運(yùn)行的方式適合調(diào)試因?yàn)槿罩緯?huì)直接打到終端能第一時(shí)間看到啟動(dòng)錯(cuò)誤。確認(rèn)正常后我習(xí)慣注冊(cè)成服務(wù)用項(xiàng)目里提供的腳本cd /opt/dmdbms/script/root ./dm_service_installer.sh -t dmserver -p DMSERVER -dm_ini /opt/dmdbms/data/DAMENG/dm.ini之后就能用systemctl start DmServiceDMSERVER這類命令管理了。3. 用戶的創(chuàng)建與權(quán)限體系邁過(guò)入門(mén)第一道坎3.1 DM8 的默認(rèn)用戶不能只會(huì)用 SYSDBADM8 安裝后自帶幾個(gè)默認(rèn)用戶這是很多新手最容易懵的地方。默認(rèn)用戶里最重要是下面這幾個(gè)用戶名作用說(shuō)明SYSDBA超級(jí)管理員擁有數(shù)據(jù)庫(kù)幾乎所有權(quán)限SYSSSO安全管理員管理安全策略、審計(jì)SYSAUDITOR審計(jì)員查看審計(jì)記錄SYS系統(tǒng)用戶持有系統(tǒng)表、字典SYSTEM系統(tǒng)用戶部分系統(tǒng)對(duì)象我第一次學(xué)的時(shí)候習(xí)慣性拿 SYSDBA 開(kāi)干所有事后來(lái)課程里特別提醒正式項(xiàng)目不能這么干。DM8 的三權(quán)分立設(shè)計(jì)本質(zhì)是讓 DBA、安全管理員、審計(jì)員角色分離避免一個(gè)人權(quán)力過(guò)大。雖然小項(xiàng)目不一定要分這么細(xì)但至少應(yīng)該給應(yīng)用建獨(dú)立的業(yè)務(wù)賬號(hào)而不是拿 SYSDBA 連接業(yè)務(wù)應(yīng)用。建用戶的標(biāo)準(zhǔn)操作CREATE USER app_user IDENTIFIED BY App123456; GRANT CREATE SESSION, CREATE TABLE TO app_user; GRANT SELECT, INSERT, UPDATE, DELETE ON schema_name.business_table TO app_user;3.2 表空間從創(chuàng)建到配額表空間是數(shù)據(jù)庫(kù)存儲(chǔ)的邏輯單位每個(gè)用戶最好都指定默認(rèn)表空間。我在課程中養(yǎng)成的習(xí)慣是一個(gè)業(yè)務(wù)域一個(gè)表空間數(shù)據(jù)文件獨(dú)立這樣后續(xù)做備份恢復(fù)的粒度會(huì)很清晰。CREATE TABLESPACE TS_APP DATAFILE /opt/dmdbms/data/DAMENG/TS_APP.DBF SIZE 2048 AUTOEXTEND ON NEXT 128 MAXSIZE 8192; ALTER USER app_user DEFAULT TABLESPACE TS_APP;這里要提醒一個(gè)細(xì)節(jié)DM8 表空間數(shù)據(jù)文件大小受頁(yè)大小影響頁(yè)大小 8K 時(shí)單個(gè)數(shù)據(jù)文件最大約 32GB16K 頁(yè)時(shí)最大約 64GB。如果建庫(kù)時(shí)就預(yù)期數(shù)據(jù)量很大直接選 16K 或 32K 頁(yè)后面省心。3.3 角色與最小權(quán)限原則DM8 內(nèi)置了幾種常用角色比如DBA、RESOURCE、CONNECT。這些角色解決的是批量授權(quán)問(wèn)題但我實(shí)際操作后強(qiáng)烈建議寧可多寫(xiě)幾條GRANT語(yǔ)句也不要圖省事直接給業(yè)務(wù)用戶DBA角色。國(guó)產(chǎn)化項(xiàng)目通常對(duì)安全審計(jì)有要求最小權(quán)限原則既是規(guī)范也是自保。課程里有個(gè)生動(dòng)的例子某項(xiàng)目因?yàn)榻o報(bào)表賬號(hào)開(kāi)了 DBA 權(quán)限后來(lái)排查數(shù)據(jù)問(wèn)題時(shí)審計(jì)記錄里分不清是誰(shuí)動(dòng)了表責(zé)任界定的麻煩遠(yuǎn)遠(yuǎn)大于臨時(shí)授權(quán)的便利。4. SQL 實(shí)戰(zhàn)從建表到業(yè)務(wù)邏輯遷移4.1 數(shù)據(jù)類型和建表習(xí)慣DM8 數(shù)據(jù)類型整體上非常接近 OracleNUMBER、VARCHAR2、CLOB、BLOB都能直接用。同時(shí)它也支持 MySQL 風(fēng)格的類型寫(xiě)法比如INT、VARCHAR。這給遷移帶來(lái)了極大的方便但也會(huì)造成一個(gè)問(wèn)題相同名稱的類型底層行為可能不完全一致比如VARCHAR的默認(rèn)長(zhǎng)度單位、是否支持 0 長(zhǎng)度等。我建表時(shí)采用的策略是從 Oracle 遷移的表保持原類型不動(dòng)從 MySQL 遷過(guò)來(lái)的表全部統(tǒng)一改成 DM8 的 Oracle 風(fēng)格類型。雖然前期要花點(diǎn)時(shí)間做轉(zhuǎn)換但這能避免后續(xù) SQL 寫(xiě)法出現(xiàn)隱式行為不一致。一個(gè)典型的建表示例CREATE TABLE T_ORDER ( ORDER_ID NUMBER(18) PRIMARY KEY, ORDER_NO VARCHAR2(32) NOT NULL, CUSTOMER_ID NUMBER(12), ORDER_AMOUNT NUMBER(12,2), STATUS CHAR(1) DEFAULT 0, CREATE_TIME TIMESTAMP DEFAULT CURRENT_TIMESTAMP, REMARK VARCHAR2(500) ); CREATE INDEX IDX_ORDER_CUST ON T_ORDER(CUSTOMER_ID); CREATE INDEX IDX_ORDER_TIME ON T_ORDER(CREATE_TIME);注意DM8 的注釋語(yǔ)句是COMMENT ON COLUMN T_ORDER.ORDER_NO IS 訂單號(hào);和 MySQL 那種行內(nèi)COMMENT 訂單號(hào)不同做遷移腳本的時(shí)候要轉(zhuǎn)換。4.2 常用 SQL 寫(xiě)法差異對(duì)照這部分是干貨中的干貨。我把自己平時(shí)最常用的一些 SQL 寫(xiě)法在 DM8 和其他主流數(shù)據(jù)庫(kù)之間做了對(duì)照功能MySQL/其他寫(xiě)法DM8 寫(xiě)法分頁(yè)查詢LIMIT 10 OFFSET 20SELECT ... LIMIT 10 OFFSET 20; 也支持 ROWNUM 寫(xiě)法字符串拼接CONCAT(a, b) 或當(dāng)前日期NOW()SYSDATE 或 NOW()自增列AUTO_INCREMENTIDENTITY(1,1) 或序列觸發(fā)器空值排序NULLS FIRST/LAST 取決于數(shù)據(jù)庫(kù)默認(rèn) NULL 最大批量插入INSERT INTO ... VALUES (...), (...)支持多表值 INSERT也支持 INSERT ALL實(shí)際操作中分頁(yè)查詢我傾向于直接用LIMIT/OFFSET風(fēng)格因?yàn)楹芏鄰幕ヂ?lián)網(wǎng)業(yè)務(wù)轉(zhuǎn)過(guò)來(lái)的開(kāi)發(fā)熟悉這種寫(xiě)法。但如果 SQL 已經(jīng)用了 Oracle 的ROWNUMDM8 也兼容。4.3 存儲(chǔ)過(guò)程遷移大頭存儲(chǔ)過(guò)程是 DM8 兼容性的主力戰(zhàn)場(chǎng)。我建議拿一個(gè)真實(shí)的存儲(chǔ)過(guò)程做測(cè)試比看十頁(yè)文檔都有效。以我測(cè)試的一個(gè)示例存儲(chǔ)過(guò)程為例CREATE OR REPLACE PROCEDURE P_UPDATE_ORDER_STATUS( v_order_id IN NUMBER, v_new_status IN CHAR ) AS v_cnt NUMBER; BEGIN SELECT COUNT(*) INTO v_cnt FROM T_ORDER WHERE ORDER_ID v_order_id; IF v_cnt 0 THEN RAISE_APPLICATION_ERROR(-20001, 訂單不存在); END IF; UPDATE T_ORDER SET STATUS v_new_status WHERE ORDER_ID v_order_id; COMMIT; EXCEPTION WHEN OTHERS THEN ROLLBACK; RAISE; END;這個(gè)寫(xiě)法從 Oracle 遷移過(guò)來(lái)幾乎不用改。DM8 支持RAISE_APPLICATION_ERROR、EXCEPTION、自治事務(wù)PRAGMA AUTONOMOUS_TRANSACTION等PL/SQL 的大部分能力都有對(duì)應(yīng)實(shí)現(xiàn)。這也是為什么很多 Oracle 背景的項(xiàng)目選擇 DM8 時(shí)存儲(chǔ)過(guò)程遷移成本極低。4.4 數(shù)據(jù)裝載與導(dǎo)出dmfldr 和 disql數(shù)據(jù)遷移繞不開(kāi)批量導(dǎo)入導(dǎo)出。DM8 提供了圖形工具“數(shù)據(jù)遷移工具”可以從其他數(shù)據(jù)庫(kù)直接遷。但我的經(jīng)驗(yàn)是大批量數(shù)據(jù)在場(chǎng)內(nèi)做裝載時(shí)用命令行工具dmfldr更高效。dmfldr的作用類似 Oracle 的sqlldr用法也很直白。假設(shè)我有一個(gè)/tmp/order_data.csv字段之間用逗號(hào)分隔cd /opt/dmdbms/bin ./dmfldr USERIDapp_user/App123456 CONTROL/tmp/load.ctl DATA/tmp/order_data.csv控制文件load.ctl內(nèi)容示例LOAD DATA INTO TABLE T_ORDER FIELDS TERMINATED BY , TRAILING NULLCOLS ( ORDER_ID, ORDER_NO, CUSTOMER_ID, ORDER_AMOUNT, STATUS )這個(gè)工具我實(shí)測(cè)下來(lái)百萬(wàn)行級(jí)別的數(shù)據(jù)導(dǎo)入是分鐘級(jí)比用圖形界面或者逐條 INSERT 好了太多。導(dǎo)出方面dexp和dimp是邏輯備份導(dǎo)入導(dǎo)出工具類似于 Oracle 的exp/imp后面?zhèn)浞菡鹿?jié)會(huì)說(shuō)。5. 備份恢復(fù)與一致性DBA 能力的關(guān)鍵試金石5.1 備份方式全景DM8 的備份體系完整物理備份、邏輯備份都有。我建議按場(chǎng)景區(qū)分使用需求推薦工具說(shuō)明數(shù)據(jù)庫(kù)全量物理備份DMRMAN 或 disql 內(nèi) BACKUP 命令恢復(fù)速度快適合正式環(huán)境增量物理備份DMRMAN可以基于某個(gè)備份集做增量邏輯導(dǎo)出dexp適合遷移、小數(shù)據(jù)量邏輯備份邏輯導(dǎo)入dimp對(duì)應(yīng) dexp 的導(dǎo)入端物理備份推薦用DMRMAN工具這是 DM8 的備份恢復(fù)命令行工具功能比較全。做了全量備份和增量備份之后它能維護(hù)一個(gè)備份集恢復(fù)時(shí)可以基于這個(gè)備份集做完整恢復(fù)。5.2 備份實(shí)操記錄我第一次做備份時(shí)圖形界面點(diǎn)了幾下就完事了后來(lái)發(fā)現(xiàn)命令行下更可控。全量備份命令如下cd /opt/dmdbms/bin ./dmrman CTLFILE/opt/dmdbms/data/DAMENG/dm.ini進(jìn)入 dmrman 交互界面后執(zhí)行BACKUP DATABASE /opt/dmdbms/data/DAMENG/dm.ini FULL BACKUPSET /backup/dm_full_20250101;這條命令生成一個(gè)全量備份集。增量備份則是在全量基礎(chǔ)上執(zhí)行BACKUP DATABASE /opt/dmdbms/data/DAMENG/dm.ini INCREMENT BACKUPSET /backup/dm_inc_20250102;增量備份必須指定在上一次備份之后執(zhí)行DMRMAN 會(huì)自動(dòng)追蹤備份鏈。這里有一個(gè)踩坑記錄備份路徑所在文件系統(tǒng)剩余空間不夠會(huì)導(dǎo)致備份失敗而且 DM8 的報(bào)錯(cuò)提示信息在早期版本里不夠直觀只提示“磁盤(pán)空間不足”。所以做備份前先df -h檢查磁盤(pán)是職業(yè)習(xí)慣。5.3 恢復(fù)流程把實(shí)例恢復(fù)到指定時(shí)間點(diǎn)恢復(fù)的思路是先還原數(shù)據(jù)文件再恢復(fù)日志或增量備份。用 DMRMAN 恢復(fù)到某個(gè)時(shí)間點(diǎn)的操作大致如下RESTORE DATABASE /opt/dmdbms/data/DAMENG/dm.ini FROM BACKUPSET /backup/dm_full_20250101; RECOVER DATABASE /opt/dmdbms/data/DAMENG/dm.ini FROM BACKUPSET /backup/dm_inc_20250102; RECOVER DATABASE /opt/dmdbms/data/DAMENG/dm.ini UPDATE DB_INFO;完整恢復(fù)流程的執(zhí)行順序很重要如果順序反了DMRMAN 會(huì)報(bào)備份集不匹配可能還需要重新還原。我的練習(xí)方法是先備份然后往庫(kù)里塞一堆測(cè)試數(shù)據(jù)再模擬刪庫(kù)最后完整走一遍恢復(fù)流程檢查數(shù)據(jù)是否回到了備份點(diǎn)。這樣整套流程跑順之后心里才真正有底。5.4 高可用主備與共享存儲(chǔ)集群課程里還簡(jiǎn)單介紹了 DM8 的高可用方案。主備架構(gòu)下主庫(kù)負(fù)責(zé)讀寫(xiě)備庫(kù)通過(guò)日志同步保持?jǐn)?shù)據(jù)一致安裝配置比裸跑實(shí)例復(fù)雜一些但核心思想并不難理解。做容災(zāi)演練的時(shí)候我學(xué)到最重要的一句話是“備份是最后一道防線高可用是縮短恢復(fù)時(shí)間的手段兩者不能互相代替?!辈还苡弥鱾溥€是共享集群日常備份都不能省。6. 實(shí)戰(zhàn)中的疑難雜癥與調(diào)優(yōu)記錄6.1 連接不上數(shù)據(jù)庫(kù)先別急著懷疑密碼我一共遇到過(guò)三次連接失敗其中兩次都是實(shí)例沒(méi)起來(lái)。DM8 的dmserver進(jìn)程崩掉或未啟動(dòng)時(shí)客戶端會(huì)報(bào)“網(wǎng)絡(luò)通信異?!钡@容易讓人誤以為 IP、端口或者防火墻問(wèn)題。排查順序建議是ps -ef | grep dmserver ss -lntp | grep 5236先確認(rèn)進(jìn)程和端口都在再去檢查連接串。這個(gè)順序能省大量排查時(shí)間。如果進(jìn)程死掉了去看實(shí)例目錄下的日志重點(diǎn)搜ERROR關(guān)鍵字多半能直接定位問(wèn)題。6.2 中文亂碼字符集不匹配是元兇亂碼問(wèn)題在國(guó)產(chǎn)數(shù)據(jù)庫(kù)課程里幾乎必被提到。根源通常出在兩端數(shù)據(jù)庫(kù)字符集和客戶端字符集不一致。我之前在 DM8 建庫(kù)時(shí)選了 GB18030但應(yīng)用端連接的字符集是 UTF-8插入中文后查詢直接出亂碼。解決方案有兩種第一種最直接重建庫(kù)時(shí)把字符集改成 UTF-8一勞永逸第二種是在 JDBC 連接串上指定encodingGBK或者UTF-8參數(shù)但這是治標(biāo)不治本。涉及多套系統(tǒng)協(xié)作時(shí)標(biāo)準(zhǔn)做法就是全局統(tǒng)一 UTF-8。6.3 慢 SQL 分析與執(zhí)行計(jì)劃DM8 查看執(zhí)行計(jì)劃的方式和 Oracle 很像可以在 disql 里打開(kāi)執(zhí)行計(jì)劃開(kāi)關(guān)SET AUTOTRACE ON; SELECT * FROM T_ORDER WHERE CUSTOMER_ID 12345;也可以在 SQL 前加EXPLAIN關(guān)鍵字查看計(jì)劃。我調(diào)優(yōu)時(shí)最常用的幾個(gè)方向確認(rèn)索引是否被正確使用有沒(méi)有發(fā)生不必要的全表掃描。確認(rèn)條件字段的類型與索引字段類型是否一致類型隱式轉(zhuǎn)換會(huì)導(dǎo)致索引失效。確認(rèn)統(tǒng)計(jì)信息是否過(guò)期。DM8 在某些自動(dòng)更新統(tǒng)計(jì)信息方面沒(méi)有主流數(shù)據(jù)庫(kù)積極大表數(shù)據(jù)量明顯變化后我會(huì)手動(dòng)執(zhí)行DBMS_STATS.GATHER_TABLE_STATS(APP_USER, T_ORDER);來(lái)更新統(tǒng)計(jì)信息。一個(gè)真實(shí)記錄生產(chǎn)環(huán)境某條查詢之前毫秒級(jí)響應(yīng)后來(lái)數(shù)據(jù)量漲了百倍后直接秒級(jí)。排查發(fā)現(xiàn)舊統(tǒng)計(jì)信息里表行數(shù)還停留在一萬(wàn)級(jí)別優(yōu)化器選擇了錯(cuò)誤執(zhí)行計(jì)劃。分析后手動(dòng)收集統(tǒng)計(jì)信息并重建了一個(gè)組合索引查詢恢復(fù)到了 50 毫秒以內(nèi)。6.4 內(nèi)存參數(shù)調(diào)整DM8 實(shí)例的內(nèi)存參數(shù)分成了很多池比如緩沖區(qū)BUFFER_SIZE、日志緩沖區(qū)等。最影響性能的一個(gè)是數(shù)據(jù)緩沖區(qū)BUFFER_SIZE。配置在dm.ini中修改后需要重啟實(shí)例生效。我一般先看監(jiān)控?cái)?shù)據(jù)如果緩沖區(qū)命中率持續(xù)過(guò)低再逐步調(diào)大cd /opt/dmdbms/bin ./disql SYSDBA/SYSDBA001 SQL SELECT name, VALUE FROM V$PARAMETER WHERE NAME LIKE %BUFFER%;調(diào)整策略是讓數(shù)據(jù)庫(kù)整體緩沖區(qū)命中率保持在 95% 以上。如果命中率很低先別急著加內(nèi)存可能更應(yīng)該優(yōu)化 SQL 和索引邏輯。7. 一些值得長(zhǎng)期堅(jiān)持的習(xí)慣整套課程學(xué)完我有一個(gè)很深的體會(huì)達(dá)夢(mèng) DM8 不缺功能缺的是使用者的心態(tài)轉(zhuǎn)換。習(xí)慣了 MySQL 的人會(huì)覺(jué)得它部分系統(tǒng)表的寫(xiě)法別別扭扭習(xí)慣了 Oracle 的人又會(huì)拿它跟正版 Oracle 比較覺(jué)得這里不如那里不熟。但實(shí)際上評(píng)價(jià)一個(gè)國(guó)產(chǎn)數(shù)據(jù)庫(kù)是否可用關(guān)鍵不在它與某一款數(shù)據(jù)庫(kù)的相似度有多高而在于它在你具體的業(yè)務(wù)場(chǎng)景里能不能穩(wěn)定、安全、可控地運(yùn)轉(zhuǎn)。我在學(xué)習(xí)后期的做法是把 DM8 當(dāng)成一個(gè)獨(dú)立產(chǎn)品來(lái)對(duì)待而不是某個(gè)數(shù)據(jù)庫(kù)的仿制品。遇到不熟悉的語(yǔ)法先查官方手冊(cè)遇到遷移問(wèn)題先用小數(shù)據(jù)量測(cè)試遇到性能瓶頸認(rèn)真分析執(zhí)行計(jì)劃而不是盲目加內(nèi)存。數(shù)據(jù)庫(kù)沒(méi)有什么玄學(xué)所有問(wèn)題最后都能落到架構(gòu)、配置、SQL、數(shù)據(jù)分布這幾個(gè)硬因素上。如果你正準(zhǔn)備學(xué) DM8我個(gè)人強(qiáng)烈建議把課程里每一個(gè)練習(xí)都動(dòng)手操作一遍尤其是備份恢復(fù)和權(quán)限管理光看不練容易眼高手低。另外用達(dá)夢(mèng)的遷移工具做一次真實(shí)的業(yè)務(wù)庫(kù)遷移實(shí)驗(yàn)比看十篇對(duì)比文章都管用。這東西說(shuō)到底就是個(gè)工具判斷一個(gè)工具好不好拿起來(lái)干一把活最直接。