達(dá)夢參數(shù)

插入報(bào)錯(cuò) SQLAllocHandle {HY000}

問題場景

應(yīng)用使用 ORM 開啟事務(wù),批量插入語句,起初正常,一定條數(shù)之后開始報(bào)錯(cuò):

SQLAllocHandle: {HY000} Stmt handle to the limit the number of statements or system of memory
解決方案

首先查看下報(bào)錯(cuò)中提到的兩個(gè)相關(guān)參數(shù) statementsmemory 的當(dāng)前值:

SQL> select name,type,value,description  from v$parameter where name in ('memory_pool', 'max_session_statement');
+------------------------+--------------+--------------+--------------------------------------------------------+
| name                   | TYPE         | VALUE        | description                                            |
+------------------------+--------------+--------------+--------------------------------------------------------+
| MEMORY_POOL            | IN FILE      | 200          | Memory Pool Size In Megabyte                           |
| MAX_SESSION_STATEMENT  | SYS          | 100          | Maximum number of statement handles for each session   |
+------------------------+--------------+--------------+--------------------------------------------------------+
SQLRowCount returns 2
2 rows fetched

可以看到 memory pool 只有 200M,session statement 也只有 100 條,都太小了,我們擴(kuò)大這兩個(gè)參數(shù)。

達(dá)夢中的參數(shù)類型(type)說明

IN FILE:靜態(tài)參數(shù)。只能修改 ini 文件,修改后重啟DB才能生效,為系統(tǒng)級參數(shù),生效后會影響所有的會話。

SYSSESSION:ini 文件和內(nèi)存同時(shí)可修改,修改后即時(shí)生效。其中,SYS為系統(tǒng)級參數(shù),修改后會影響所有的會話;SESSION 為會話級參數(shù),服務(wù)器運(yùn)行過程中被修改時(shí),之前創(chuàng)建的會話不受影響,只有新創(chuàng)建的會話使用新的參數(shù)值。

READ ONLY:DB在運(yùn)行過程中,手動(dòng)參數(shù)不能被修改,靜態(tài)和動(dòng)態(tài)參數(shù)可以修改。

可以看出 memory pool 必須通過 ini 文件 修改,而要讓 session statement 永久生效(不要在重啟后就又變回去)也要在 ini 文件 中修改,所以我們找到文件所在路徑,備份后修改這兩個(gè)參數(shù)為自己需要的值:

root@Kylin:/opt/dmdbms/data/tinaliu# cat /opt/dmdbms/data/tinaliu/dm.ini | grep -E "MEMORY_POOL|MAX_SESSION_STATEMENT"
       MEMORY_POOL                     = 4096                   #Memory Pool Size In Megabyte
       MAX_SESSION_STATEMENT           = 5000                   #Maximum number of statement handles for each session

順便說一句,如果只修改 session statement 是可以使用語句直接操作的:

SQL> alter system set 'max_session_statement' = 5000;
SQLRowCount returns 0

測試發(fā)現(xiàn):本次卡住我們的,正是參數(shù) max_session_statement。那為什么我們的程序,要由這么多的句柄支撐呢?

我們改小句柄數(shù)(100),分別對以下語句進(jìn)行測試:

  1. 普通插入:insert ???? ??
  2. 查詢 last_insert_id:select scope_identity() ???? ??(第101條報(bào)錯(cuò))
  3. 普通查詢:select * from test.tbl_test; ???? ?? (第101條報(bào)錯(cuò))

經(jīng)過簡單的測試,我們可以初步判斷:句柄數(shù)max_session_statement是用于限制查詢結(jié)果集的。

那么這個(gè)限制在什么維度生效?

我們進(jìn)行以下測試:

  1. 同一個(gè)session中,執(zhí)行200條查詢語句,每條單獨(dú)提交??????
  2. 同一個(gè)事務(wù)中,執(zhí)行200條查詢語句,統(tǒng)一提交 ??????(第101條報(bào)錯(cuò))

經(jīng)過測試,我們可以得出結(jié)論:句柄數(shù)max_session_statement是用于限制在一個(gè)事務(wù)中查詢結(jié)果集個(gè)數(shù)的。

我們將此參數(shù)修改為 5000。畢竟,再大些的事務(wù),就一定要拆分了。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容