:從安裝遷移到備份調(diào)優(yōu)的國產(chǎn)數(shù)據(jù)庫指南)
說實話剛接到要接觸達夢 DM8 的任務(wù)時我心里是打鼓的。國產(chǎn)數(shù)據(jù)庫這幾年呼聲很高但真到自己上手安裝、遷移、調(diào)優(yōu)心里還是有點虛。帶著這種心態(tài)我給自己留了兩周時間白天處理手頭工作晚上在虛擬機里裝環(huán)境、跑遷移、測兼容性最后把一套原本跑在 MySQL 上的模擬業(yè)務(wù)系統(tǒng)完整遷到了 DM8 上。這篇筆記就是這段時間踩坑和實戰(zhàn)的記錄。從安裝部署到 SQL 兼容從備份恢復(fù)到性能調(diào)優(yōu)我會把每一步的決策思路和操作細節(jié)都交代清楚。如果你正在準(zhǔn)備把系統(tǒng)切換到國產(chǎn)數(shù)據(jù)庫或者只是想把達夢 DM8 作為一門技能學(xué)起來這篇文字應(yīng)該能幫你少走不少彎路。1. 學(xué)習(xí) DM8 之前為什么選它、怎么學(xué)1.1 達夢 DM8 的真實定位與選型考量達夢 DM8 是國產(chǎn)關(guān)系型數(shù)據(jù)庫管理系統(tǒng)采用自研內(nèi)核整體架構(gòu)上對 Oracle 的兼容度做得非常高。對國內(nèi)做應(yīng)用開發(fā)的人來說最直觀的感受是它支持很多 Oracle 的習(xí)慣用法比如 dual 表、NVL、DECODE、ROWNUM 這些Oracle DBA 上手幾乎沒有額外成本。為什么國產(chǎn)化替代總是繞不開達夢因為在黨政、金融、能源這些對安全性和自主可控要求很高的行業(yè)里達夢的適配案例和生態(tài)積累都比較靠前很多項目的招標(biāo)條件里直接寫了必須支持國產(chǎn)數(shù)據(jù)庫DM8 自然成了優(yōu)先候選。選型不能只看標(biāo)簽要看具體場景。我從實際體驗出發(fā)的感受是DM8 在 OLTP 場景下的穩(wěn)定性是夠用的工具鏈也相對完整比如 DTS 數(shù)據(jù)遷移工具、dmrman 備份恢復(fù)工具、disql 命令行客戶端能覆蓋從開發(fā)到運維的基本訴求。但它不是一個讓你無腦平替 MySQL 或者 Oracle 的東西使用習(xí)慣上需要做不少調(diào)整。比如它的用戶和表空間模型更接近 Oracle和 MySQL 的那套庫就是 schema的體系有明顯差異。如果團隊里全是 MySQL 背景的開發(fā)前期適配成本要提前算進去。再說一個很多人關(guān)心的點達夢有沒有生態(tài)我的評估是對于一個中小型業(yè)務(wù)系統(tǒng)它該有的功能都有官方文檔也比較細網(wǎng)上能搜到的實戰(zhàn)帖子雖然不算海量但解決 80% 的日常問題已經(jīng)夠了。真正冷門的問題可能需要通過原廠支持來解決。所以選型時還要評估一下團隊里有沒有人能看懂日志、能不能做基礎(chǔ)的問題排查這比數(shù)據(jù)庫本身的特性更重要。1.2 從零開始的整體學(xué)習(xí)路線我一開始也想把官方文檔從頭啃一遍但很快就放棄了。原因很簡單DM8 的文檔體量很大一上來就啃細節(jié)容易迷失方向而且很多內(nèi)容不實際操作根本記不住。我后來采用的學(xué)習(xí)路線是先裝一個能跑的實例再拿自己熟悉的業(yè)務(wù) SQL 去試然后重點過權(quán)限和備份恢復(fù)最后才碰性能調(diào)優(yōu)。這樣安排是有邏輯的。第一步是建立感性認(rèn)識至少要知道安裝包怎么解壓、服務(wù)怎么啟動、disql 怎么登錄。第二步是摸底兼容性用你平時寫的查詢和增刪改語句去測哪些能跑通哪些報錯報錯了再查文檔這種帶著問題去查的效率遠高于盲讀。第三步是運維基本功權(quán)限體系和備份恢復(fù)是生產(chǎn)環(huán)境絕對不能跳過的環(huán)節(jié)哪怕你只是做開發(fā)也要了解賬號怎么建、權(quán)限怎么授、備份怎么做。第四步是性能調(diào)優(yōu)如果沒有真實壓力和監(jiān)控數(shù)據(jù)調(diào)優(yōu)就是空談??偟臅r間安排上我建議第一周解決安裝和基本使用第二周做遷移適配和運維演練。如果項目周期緊可以壓縮到五天但至少要把安裝、建庫、權(quán)限、備份、恢復(fù)這五件事完整走一遍。我的體會是學(xué) DM8 最好的方式不是看視頻而是拿一個具體的應(yīng)用場景來驅(qū)動比如把一個簡單的 Web 系統(tǒng)從 MySQL 換成 DM8跑一遍完整功能。這個過程里遇到的問題比任何課程都值錢。2. 環(huán)境準(zhǔn)備與 DM8 安裝部署全流程實錄2.1 安裝前的軟硬件準(zhǔn)備物料上需要準(zhǔn)備一份 DM8 安裝包可以在達夢官方申請試用授權(quán)同時準(zhǔn)備好操作系統(tǒng)。我用的是某 Linux 發(fā)行版內(nèi)存建議 4GB 以上磁盤至少 20GB。如果條件有限虛擬機也可以但要注意磁盤 IO 不要太差否則后續(xù)初始化實例和備份恢復(fù)會慢得讓人煩躁。這里特別強調(diào)一件事數(shù)據(jù)庫千萬不要用 root 用戶直接安裝和運行。官方也推薦新建一個專用用戶比如 dmdba。原因有兩層第一是安全數(shù)據(jù)庫進程以普通用戶身份運行即使出現(xiàn)安全問題攻擊者也不會直接拿到系統(tǒng)最高權(quán)限第二是文件權(quán)限干凈避免安裝出來的文件只能 root 讀寫后面維護時切換到 dmdba 會到處碰壁。我用下面的命令完成了用戶和環(huán)境準(zhǔn)備groupadd dinstall useradd -g dinstall -m -d /home/dmdba dmdba passwd dmdba cat /etc/security/limits.conf EOF dmdba soft nofile 65536 dmdba hard nofile 65536 dmdba soft stack 10240 dmdba hard stack 10240 EOF這個操作對應(yīng)的是系統(tǒng)層面允許數(shù)據(jù)庫進程打開足夠多的文件、擁有足夠的??臻g。如果不設(shè)置高并發(fā)場景下容易出現(xiàn)打開文件過多或者棧溢出的問題。注意修改 limits.conf 之后最好重新登錄 dmdba 用戶用ulimit -n確認(rèn)生效不要想當(dāng)然。2.2 安裝和建庫實操安裝包上傳到服務(wù)器后一般是一個可執(zhí)行的 .bin 文件??梢宰邎D形界面安裝也可以靜默安裝。我在模擬環(huán)境里用的是命令行方式命令很直接chmod x DMInstall.bin ./DMInstall.bin -q安裝目錄默認(rèn)是/dm/dmdbms我建議保持默認(rèn)。原因是后面各種工具、日志、服務(wù)腳本都會基于這個路徑去查找保留默認(rèn)可以省心不少。安裝完成后重心就轉(zhuǎn)移到建庫上。這里的核心工具是 dminit你可以把它理解為達夢版的CREATE DATABASE命令但需要在實例啟動之前執(zhí)行。我執(zhí)行的一條典型初始化命令是這樣su - dmdba cd /dm/dmdbms/bin ./dminit PATH/dm/data DB_NAMEDMSERVER INSTANCE_NAMEDMSERVER \ PORT_NUM5236 PAGE_SIZE16 EXTENT_SIZE16 CHARSET1 CASE_SENSITIVE0把幾個關(guān)鍵參數(shù)解釋一下。PATH 是數(shù)據(jù)文件存放目錄DB_NAME 是數(shù)據(jù)庫名INSTANCE_NAME 是實例名PORT_NUM 是達夢的服務(wù)端口默認(rèn) 5236。PAGE_SIZE 是頁大小我設(shè)成 16KOLTP 場景下比較穩(wěn)妥同時它也會影響表空間容量上限初始化后再改基本不現(xiàn)實。CHARSET1 表示使用 UTF-8 字符集如果跟現(xiàn)有系統(tǒng)的字符集不一致后續(xù)遷移容易出現(xiàn)亂碼。CASE_SENSITIVE 控制標(biāo)識符是否區(qū)分大小寫默認(rèn)是 1也就是區(qū)分大小寫和 Oracle 行為一致如果將來要從 MySQL 老系統(tǒng)遷移表名一般是小寫初始化為 0 會省很多麻煩。這幾個參數(shù)在初始化之后基本不能動態(tài)修改一定要在動手前想清楚。dminit 執(zhí)行成功后會在 PATH 目錄下生成數(shù)據(jù)庫文件同時在安裝目錄的 bin 下生成一個以實例名命名的服務(wù)腳本比如 DmServiceDMSERVER。這說明實例的骨架已經(jīng)搭好了。2.3 啟動服務(wù)并用 disql 驗證啟動服務(wù)有兩種方式。開發(fā)環(huán)境圖省事直接執(zhí)行服務(wù)腳本/dm/dmdbms/bin/DmServiceDMSERVER start如果想讓數(shù)據(jù)庫開機自啟可以切換到 root 用戶執(zhí)行DmServiceDMSERVER install把它注冊成系統(tǒng)服務(wù)。我在模擬環(huán)境里一般直接 start重啟機器后再手動起畢竟演練環(huán)境沒必要弄得太復(fù)雜。啟動完成后用 disql 登錄驗證命令如下/dm/dmdbms/bin/disql SYSDBA/SYSDBAlocalhost:5236登錄成功后執(zhí)行一句最簡單的SELECT 1;或者SELECT * FROM V$INSTANCE;能正確返回就說明實例正常。這里有一個安全提示首次登錄后必須要立即修改 SYSDBA 的默認(rèn)密碼。默認(rèn)密碼在很多地方都能搜到不修改等于把數(shù)據(jù)庫大門敞開著。修改密碼用ALTER USER SYSDBA IDENTIFIED BY 新密碼;即可。3. 從建庫到遷移DM8 核心功能實操筆記3.1 表空間、用戶與權(quán)限體系實際生產(chǎn)環(huán)境里沒有人會用 SYSDBA 直接跑業(yè)務(wù)。標(biāo)準(zhǔn)做法是先建獨立的表空間再創(chuàng)建業(yè)務(wù)用戶最后按最小權(quán)限原則授權(quán)。我在模擬項目X里是這樣操作的CREATE TABLESPACE TS_APP DATAFILE /dm/data/DMSERVER/TS_APP01.DBF SIZE 1024 AUTOEXTEND ON NEXT 64 MAXSIZE 8192; CREATE USER APP_USER IDENTIFIED BY App123456 DEFAULT TABLESPACE TS_APP; GRANT CREATE SESSION TO APP_USER; GRANT CREATE TABLE TO APP_USER; GRANT SELECT, INSERT, UPDATE, DELETE ON 業(yè)務(wù)表 TO APP_USER;這里涉及達夢一個重要的設(shè)計用戶和模式schema是打通的創(chuàng)建一個用戶會自動生成同名模式表默認(rèn)建在自己的模式下。這個機制和 Oracle 幾乎一樣所以 Oracle 背景的人上手非???。如果團隊原來是 MySQL 背景就要先把這個概念講清楚否則容易產(chǎn)生庫在哪里的困惑。權(quán)限方面我強烈建議不要在非測試環(huán)境直接GRANT DBA TO APP_USER。雖然這樣省事但權(quán)限過大意味著風(fēng)險過高。正確做法是像日常運維那樣按需授權(quán)比如只給 SELECT、INSERT、UPDATE、DELETE。特別是生產(chǎn)環(huán)境最小權(quán)限是底線這個原則和數(shù)據(jù)庫品牌無關(guān)但在達夢上執(zhí)行起來并不復(fù)雜。3.2 SQL 兼容性實測這一節(jié)是我最想分享的內(nèi)容。很多開發(fā)擔(dān)心國產(chǎn)數(shù)據(jù)庫 SQL 不兼容實際測下來達夢對 Oracle 的兼容做得確實用力。我挑了幾個最常用的點驗證過虛擬表 dual 和函數(shù)比如SELECT NVL(NULL, ok) FROM dual;能直接跑。DECODE、ROWNUM 這些 Oracle 常用特性在 DM8 里有對應(yīng)實現(xiàn)。分頁查詢同時支持 MySQL 風(fēng)格的LIMIT和 Oracle 風(fēng)格的ROWNUM。比如SELECT * FROM T ORDER BY ID LIMIT 20,10;可以正常執(zhí)行。序列操作SELECT SEQ_APP_ID.NEXTVAL FROM dual;也能用。這說明什么如果團隊原來基于 Oracle 開發(fā)遷移到 DM8 的成本比想象中低。但如果是 MySQL 背景就需要注意類型體系和使用習(xí)慣的差異。MySQL 的 tinyint、datetime、text 在 DM8 里不一定有完全同名的類型通常需要映射成 INT、TIMESTAMP、CLOB。DTS 遷移工具會自動做一部分映射但映射結(jié)果一定要人工檢查尤其是精度和長度否則很容易埋坑。3.3 從 MySQL 遷移到 DM8 的適配要點我用達夢自帶的 DTS 工具把一套原本跑在 MySQL 上的模擬業(yè)務(wù)系統(tǒng)遷了過去。流程上很簡單選擇源、選擇目標(biāo)、做字段映射、跑遷移、做數(shù)據(jù)校驗。真正花時間的不是搬數(shù)據(jù)而是改 SQL。我遇到的典型問題有三類。第一類是大小寫困惑。如果建庫時選了區(qū)分大小寫MySQL 里的小寫表名到了 DM8 里會被轉(zhuǎn)成大寫程序里動態(tài)拼接 SQL 時特別容易踩空。最穩(wěn)妥的解法是應(yīng)用層統(tǒng)一大寫表名或者在初始化實例時就把 CASE_SENSITIVE 設(shè)為 0。第二類是函數(shù)差異。MySQL 的 IFNULL 達夢支持但 GROUP_CONCAT 這類聚合函數(shù)沒有完全對應(yīng)的同名函數(shù)要改成達夢的 LISTAGG 或者 WM_CONCAT。這個階段最好做一次全量 SQL 掃描把所有 SQL 都過一遍 EXPLAIN提前發(fā)現(xiàn)語法問題。第三類是隱式類型轉(zhuǎn)換。MySQL 對大字段的隱式轉(zhuǎn)換比較寬松達夢偏嚴(yán)格遷移后有些 SQL 會報類型不匹配錯誤解決辦法是寫 SQL 時顯式使用 CAST。另外DTS 遷移完成后一定要做數(shù)據(jù)校驗。不能只看遷移過程報沒報錯有的類型轉(zhuǎn)換會靜默丟失精度。我習(xí)慣隨機抽樣對比源和目標(biāo)的行數(shù)以及關(guān)鍵字段值至少抽 10% 的數(shù)據(jù)核心大表全量比對。這一步雖然繁瑣但能避免很多上線后才發(fā)現(xiàn)的數(shù)據(jù)問題。4. 備份恢復(fù)與性能調(diào)優(yōu)實戰(zhàn)4.1 備份策略與恢復(fù)演練數(shù)據(jù)庫最重要的能力不是性能而是能不能找回數(shù)據(jù)。DM8 提供邏輯備份工具 dexp/dimp也支持物理備份命令 BACKUP/RESTORE以及配套的 dmrman 工具。我個人的建議是生產(chǎn)環(huán)境以物理備份為主邏輯備份作為補充。物理備份可以做全量加增量組合恢復(fù)粒度更細邏輯備份適合導(dǎo)出特定表或者結(jié)構(gòu)定義適合做遷移和歸檔。在 disql 里執(zhí)行一個全量備份最簡單的寫法是BACKUP DATABASE FULL TO FULL_BAK_001 BACKUPSET /dm/backup/full_bak_001;如果習(xí)慣用 dmrman也可以把同樣的命令放到備份工具里執(zhí)行。備份的產(chǎn)物是一個備份集目錄里面包含數(shù)據(jù)文件的可恢復(fù)鏡像。這里我想分享一個很多人忽略的點備份文件一定要存儲到和數(shù)據(jù)庫不同的磁盤最好是異機或者獨立存儲。我聽說過不止一個團隊數(shù)據(jù)庫和備份在同一塊磁盤上磁盤壞了數(shù)據(jù)全沒了備份也沒了。比備份本身更重要的是恢復(fù)演練。我見過太多團隊備份任務(wù)每天都在跑但從沒真正恢復(fù)驗證過。真到了要恢復(fù)的時候才發(fā)現(xiàn)備份集權(quán)限不對、路徑變了、歸檔沒開啟各種意外。所以備份策略里必須包含一項定期恢復(fù)演練。我自己的習(xí)慣是每兩周拿備份在測試環(huán)境做一次完整恢復(fù)確認(rèn)恢復(fù)后的數(shù)據(jù)能正常啟動和查詢?nèi)缓蟀堰@個過程記錄下來。這個習(xí)慣看起來麻煩真到用時能救命。4.2 性能調(diào)優(yōu)的切入點調(diào)優(yōu)這塊我不建議一上來就改一堆參數(shù)先要搞清楚問題到底出在哪里。達夢的動態(tài)視圖體系很接近 Oracle常用的有 V$INSTANCE、V$SESSIONS、V$LOCK、V$BUFFERPOOL、V$SYSSTAT。碰到性能問題先問自己三個問題是某個 SQL 慢還是整個庫都慢是偶發(fā)還是持續(xù)慢的時候系統(tǒng)在做什么有沒有大事務(wù)或者鎖等待如果定位到單個 SQL 慢正確的動作是看執(zhí)行計劃。在 disql 里使用EXPLAIN SELECT ...;就能看到。根據(jù)我的經(jīng)驗最常見的原因是統(tǒng)計信息過期導(dǎo)致達夢選擇了全表掃描或者表的關(guān)聯(lián)順序不合理。解決辦法是收集統(tǒng)計信息CALL DBMS_STATS.GATHER_SCHEMA_STATS(APP_USER);收集完成后很多 SQL 的性能會自動變好。如果依然慢再考慮建立合適的索引或者調(diào)整 SQL 寫法。注意索引不是越多越好每個索引都會拖慢寫入得不償失。如果是全局性的性能問題才需要動 INI 參數(shù)。舉個最典型的例子當(dāng)實例的緩沖池命中率長期偏低時可以適當(dāng)調(diào)大 BUFFER 參數(shù)命令是ALTER SYSTEM SET BUFFER 1024;。但調(diào)完之后要持續(xù)觀察不能今天調(diào)完明天又加。參數(shù)調(diào)整有個原則每次只改一個并且記錄修改前后的監(jiān)控數(shù)據(jù)。否則多個參數(shù)一起改出了問題根本不知道是誰引起的。還有一個和具體參數(shù)無關(guān)的經(jīng)驗不要在業(yè)務(wù)高峰期做大批量數(shù)據(jù)清理或者大事務(wù)操作。長時間未提交的事務(wù)在達夢上對其他會話的影響比某些數(shù)據(jù)庫更明顯。很多性能問題表面上是數(shù)據(jù)庫慢實際上是鎖等待和堵車。5. 常見問題排查與避坑指南5.1 高頻報錯與解決方案這兩周里我實際遇到的高頻問題整理成了一張速查表報錯現(xiàn)象可能原因解決辦法dminit 提示內(nèi)存不足或無法分配共享內(nèi)存系統(tǒng)共享內(nèi)存限制過低或?qū)嵗齾?shù)不匹配檢查 sysctl.conf 的 shmmax、shmall 設(shè)置必要時候重新配置后重啟服務(wù)啟動失敗端口被占用5236 端口被其他進程占用執(zhí)行 netstat -lnp | grep 5236 查看占用進程換端口或釋放端口disql 登錄報認(rèn)證失敗密碼錯誤、賬號被鎖、字符集問題確認(rèn)密碼查看實例日志定位原因必要時通過系統(tǒng)管理員重置建表后應(yīng)用程序找不到表大小寫敏感機制導(dǎo)致表名被轉(zhuǎn)成大寫統(tǒng)一標(biāo)識符大小寫或者建庫時設(shè)置 CASE_SENSITIVE0備份還原后實例無法啟動備份集不完整或參數(shù)文件路徑不一致用 dmrman 校驗備份集檢查 dm.ini 中的路徑配置SQL 報類型不匹配或函數(shù)不存在語法兼容問題對照官方函數(shù)手冊改寫 SQL使用 CAST 顯式轉(zhuǎn)換類型新手遇到問題第一反應(yīng)應(yīng)該是查日志而不是亂試命令。達夢的日志文件在$DM_HOME/log目錄下文件名一般帶實例名內(nèi)容已經(jīng)寫得比較直白。比如登錄失敗日志里會明確記錄是什么原因?qū)е碌恼J(rèn)證失敗這比對著屏幕干瞪眼強得多。5.2 幾個獨家避坑心得先說初始化參數(shù)的問題。頁大小、字符集、大小寫敏感這三個參數(shù)一旦定了后期基本沒法改。特別是大小寫敏感如果建庫前沒想好后面遷移老系統(tǒng)時會非常痛苦。我的做法是在新環(huán)境里先初始化一個測試實例把所有參數(shù)都試明白再決定生產(chǎn)環(huán)境的最終方案寧可多花一小時也不冒險。第二個心得是不要在測試環(huán)境里偷懶。很多人喜歡在測試庫上隨意建用戶、隨意授權(quán)開發(fā)和測試環(huán)境一團糟結(jié)果就是上線前各種權(quán)限問題集中爆發(fā)。測試環(huán)境的表空間、用戶、權(quán)限模型盡量和生產(chǎn)保持一致這樣遷移上線的過程才是平滑的。第三個心得是針對遷移場景的。DTS 遷移完成不等于所有工作都結(jié)束了。我建議遷移后做一次全量回歸尤其是事務(wù)、鎖、并發(fā)場景因為很多問題不是單條 SQL 的語法錯誤而是并發(fā)環(huán)境下才暴露出來的。自動化腳本在這個環(huán)節(jié)很有用把核心業(yè)務(wù)的增刪改查全部跑一遍比自己手工點鼠標(biāo)可靠得多。第四個心得是遇到問題先查官方文檔。達夢的官方文檔其實寫得挺細很多參數(shù)都有解釋和示例。我在調(diào)試過程中發(fā)現(xiàn)網(wǎng)上搜到的碎片化文章有時會互相矛盾反而官方手冊里能查到準(zhǔn)確的說明。所以我的習(xí)慣是先看手冊再看社區(qū)最后才動手改配置。5.3 學(xué)習(xí)建議如果你是在沒有生產(chǎn)壓力的情況下自學(xué) DM8我的建議很簡單找一個具體的應(yīng)用場景來驅(qū)動。光看文檔很容易產(chǎn)生什么都會的錯覺一動手就廢。拉一個虛擬機或者容器把安裝、建庫、遷移、備份、恢復(fù)、調(diào)優(yōu)完整走一遍這個過程比任何課程都有效。剛開始接觸國產(chǎn)數(shù)據(jù)庫難免會拿它和 Oracle 或者 MySQL 做對比。有對比是好事但不要帶著偏見去學(xué)。接受它設(shè)計上的一些差異理解每個選擇的背景才能真正用好。國產(chǎn)數(shù)據(jù)庫這些年進步很明顯但最終拼的還是使用者解決問題的能力而解決問題的能力只能在真實環(huán)境里練出來。這段時間用下來我的總體感受是達夢 DM8 在中小型系統(tǒng)上做核心業(yè)務(wù)支撐是夠用的關(guān)鍵是別拿習(xí)慣的那套思維硬套要理解它自己的設(shè)計取舍。最后再分享一個我自己的小習(xí)慣每次做完備份我都會順手在測試環(huán)境做一次完整恢復(fù)演練再寫一行記錄??雌饋砺闊┑娴匠鍪碌臅r候你會發(fā)現(xiàn)這個習(xí)慣值回所有時間。