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