注册
初始化参数的相关测试
专栏/技术分享/ 文章详情 /

初始化参数的相关测试

雾岛听风 2026/09/04 100 0 0
摘要

DM 数据库初始化参数测试过程结果

目录

  1. 测试环境准备
  2. 测试一:页大小(PAGE_SIZE)对行长度限制的影响
  3. 测试二:字符集 UTF8 与 GB18030 对存储的影响
  4. 测试三:大小写敏感(CASE_SENSITIVE)的影响
  5. 测试四:空格填充模式(BLANK_PAD_MODE)的影响
  6. 测试五:参数可修改性分类
  7. 附录:测试汇总表

1. 测试环境准备

1.1 环境要求

项目 要求
操作系统 VMware Workstation (kylin10)
数据库版本 DM8
管理工具 dminit(命令行初始化工具)、disql(命令行查询工具)、
磁盘空间 ≥ 40 GB

1.2 环境变量确认

# 确认 DM 安装路径 echo $DM_HOME /opt/dmdbms # 确认 dminit 与 disql 可用

1.3 初始化命令模板

# 通用的 dminit 命令模板 $DM_HOME/bin/dminit \ PATH=/dm/data/<实例名> \ # 数据文件存放路径 DB_NAME=<数据库名> \ # 数据库名 INSTANCE_NAME=<实例名> \ # 实例名 PORT_NUM=<端口> \ # 监听端口(不同实例使用不同端口) PAGE_SIZE=<页大小> \ # 页大小 4/8/16/32 EXTENT_SIZE=16 \ # 簇大小 CHARSET=<字符集编码> \ # 0=GB18030, 1=UTF-8 CASE_SENSITIVE=<Y/N> \ # 大小写敏感 LENGTH_IN_CHAR=1 \ # VARCHAR 长度以字符为单位 BLANK_PAD_MODE=<0/1> \ # 空格填充模式(部分版本支持) UNICODE_FLAG=<0/1> \ # 0=GB18030, 1=UTF-8(与 CHARSET 等效) SYSDBA_PWD=<密码> \ # SYSDBA 密码 SYSAUDITOR_PWD=<密码> \ # SYSAUDITOR 密码

2. 测试一:页大小(PAGE_SIZE)对行长度限制的影响

2.1 测试目标

验证 4 种 PAGE_SIZE(4K / 8K / 16K / 32K)下:

  • 单行最大长度限制
  • 表结构差异(最大列数限制)
  • 存储空间差异(相同数据在不同页大小下的占用)

2.2 初始化四个实例(需要的磁盘空间太大,这里选择挂载一个100G的磁盘放在/test目录下 已设置开机自动挂载)

./dminit path=/dmdata/data PAGE_SIZE=32 EXTENT_SIZE=32 CASE_SENSITIVE=y CHARSET=1 DB_NAME=DMTEST INSTANCE_NAME= PORT_NUM=5236 SYSDBA_PWD=****** SYSAUDITOR_PWD=******

说明:PAGE_SIZE 初始化后不可更改,必须新建实例。

# 实例 1:PAGE_SIZE=4 /opt/dmdbms/bin/dminit PATH=/test/DMpage4k PAGE_SIZE=4 EXTENT_SIZE=32 CHARSET=1 CASE_SENSITIVE=1 DB_NAME=DMTEST4K INSTANCE_NAME=DMTEST4K PORT_NUM=5237 SYSDBA_PWD=Sysdba123. SYSAUDITOR_PWD=Sysauditor123. # 实例 2:PAGE_SIZE=8 /opt/dmdbms/bin/dminit PATH=/test/DMpage8k PAGE_SIZE=8 EXTENT_SIZE=32 CHARSET=1 CASE_SENSITIVE=1 DB_NAME=DMTEST8K INSTANCE_NAME=DMTEST8K PORT_NUM=5238 SYSDBA_PWD=Sysdba123. SYSAUDITOR_PWD=Sysauditor123. # 实例 3:PAGE_SIZE=16(默认值) /opt/dmdbms/bin/dminit PATH=/test/DMpage16k PAGE_SIZE=16 EXTENT_SIZE=32 CHARSET=1 CASE_SENSITIVE=1 DB_NAME=DMTEST16K INSTANCE_NAME=DMTEST16K PORT_NUM=5239 SYSDBA_PWD=Sysdba123. SYSAUDITOR_PWD=Sysauditor123. # 实例 4:PAGE_SIZE=32 /opt/dmdbms/bin/dminit PATH=/test/DMpage32k PAGE_SIZE=32 EXTENT_SIZE=32 CHARSET=1 CASE_SENSITIVE=1 DB_NAME=DMTEST32K INSTANCE_NAME=DMTEST32K PORT_NUM=5240 SYSDBA_PWD=Sysdba123. SYSAUDITOR_PWD=Sysauditor123. BUFFER=1563 # 加一个限制buffer池大小 否则page_size=32太大会导致系统分配BUFFER时太大导致启动实例失败 #原因 OOM [root@localhost ~]# dmesg -T | grep -i oom [四 8 月 6 13:20:02 2026] gmain invoked oom-killer: gfp_mask=0x6200ca (GFP_HIGHUSER_MOVABLE), order=0, oom_score_adj=0 [四 8 月 6 13:20:02 2026] oom_kill_process+0xd1/0x100 [四 8 月 6 13:20:02 2026] [ pid ] uid tgid total_vm rss pgtables_bytes swapents oom_score_adj name [四 8 月 6 13:20:02 2026] oom-kill:constraint=CONSTRAINT_NONE,nodemask=(null),cpuset=/,mems_allowed=0,global_oom,task_memcg=/user.slice/user-1001.slice/session-2.scope,task=dmserver,pid=3414,uid=1001 [四 8 月 6 13:20:02 2026] oom_reaper: reaped process 3414 (dmserver), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB

pm7gfr6.png

2.3 启动四个实例

# 注册服务后通过服务启动 #DMTEST4K /opt/dmdbms/script/root/dm_service_installer.sh -t dmserver -dm_ini /test/DMpage4k/DMTEST4K/dm.ini -p DMTEST4K #DMTEST8K /opt/dmdbms/script/root/dm_service_installer.sh -t dmserver -dm_ini /test/DMpage8k/DMTEST8K/dm.ini -p DMTEST8K #DMTEST16K /opt/dmdbms/script/root/dm_service_installer.sh -t dmserver -dm_ini /test/DMpage16k/DMTEST16K/dm.ini -p DMTEST16K #DMTEST32K /opt/dmdbms/script/root/dm_service_installer.sh -t dmserver -dm_ini /test/DMpage32k/DMTEST32K/dm.ini -p DMTEST32K

pm7gHGd.png

2.4 测试 SQL(在每个实例上分别执行)

2.4.1 查询当前页大小

-- 连接到对应实例 -- disql SYSDBA/Sysdba123.@localhost:5237 (4K) -- disql SYSDBA/Sysdba123.@localhost:5238 (8K) -- disql SYSDBA/Sysdba123.@localhost:5239 (16K) -- disql SYSDBA/Sysdba123.@localhost:5240 (32K) -- 查看页大小 SELECT PARA_VALUE FROM V$DM_INI WHERE PARA_NAME='GLOBAL_PAGE_SIZE';

2.4.2 测试单行最大长度 —— 逐步逼近法

-- ===================================================== -- 测试方法:逐步创建更宽的 VARCHAR 表,直到建表失败 public static void main(String[] args) { Connection conn = null; try { // 加载达梦驱动 Class.forName("dm.jdbc.driver.DmDriver"); conn = DriverManager.getConnection(URL, USER, PASSWORD); System.out.println("数据库连接成功\n"); int low = 1; int high = 100000; // 搜索上界,足够大 int best = 0; // 二分查找 while (low <= high) { int mid = (low + high) / 2; boolean ok = tryCreateTable(conn, mid); if (ok) { best = mid; low = mid + 1; } else { high = mid - 1; } } System.out.println("====================探测结果===================="); System.out.println("当前库VARCHAR最大可定义长度:" + best); System.out.printf("VARCHAR(%d) 建表成功;VARCHAR(%d) 报-6121数据精度超出范围%n", best, best + 1); } catch (Exception e) { e.printStackTrace(); } finally { close(conn); } }

pm7gXsP.png

pm7gOMt.png

2.4.3 测试多列场景下的行长度限制

-- 创建 N 个 VARCHAR(100) 的列,测试最大列数 -- 例如 PAGE_SIZE=4 时: List<Result> results = new ArrayList<>(); for (String[] cfg : DB_CONFIGS) { String label = cfg[0], url = cfg[1], user = cfg[2], pass = cfg[3]; System.out.println(); System.out.println(repeat('=', 60)); System.out.println(" " + label + " (" + url + ")"); System.out.println(repeat('=', 60)); Result r = new Result(); r.label = label; try (Connection conn = DriverManager.getConnection(url, user, pass)) { conn.setAutoCommit(true); r.pageSize = queryPageSize(conn); System.out.printf(" 实际 PAGE_SIZE = %d 字节%n%n", r.pageSize); // ── DDL: 最多多少列 ── System.out.print(" [DDL] VARCHAR(100) 最多列数: "); r.maxCols100 = findMaxColumns(conn, DDL_COL_WIDTH); System.out.printf("%d 列%n", r.maxCols100); // ── DML: 单列最大数据 ── System.out.print(" [DML] 1列最大数据字节: "); r.dmlSingleCol = findMaxRowBytes(conn, 1); System.out.printf("%d 字节 (利用率 %.1f%%)%n", r.dmlSingleCol, 100.0 * r.dmlSingleCol / r.pageSize); // ── DML: 多列最大数据 ── System.out.printf(" [DML] %d列最大数据字节: ", DML_COL_COUNT); r.dmlMultiCol = findMaxRowBytes(conn, DML_COL_COUNT); r.perColOverhead = (r.dmlSingleCol - r.dmlMultiCol) / (DML_COL_COUNT - 1); r.rowBaseOverhead = r.pageSize - r.dmlSingleCol - r.perColOverhead; System.out.printf("%d 字节 (每列开销≈%d字节)%n", r.dmlMultiCol, r.perColOverhead); -- 记录最大列数

pm7gqxI.png

2.4.4 查询理论限制值

-- DM 中行长度限制与页大小的关系: -- 理论最大行长 ≈ PAGE_SIZE / 2(但需减去行头开销) -- 查询每个实例的 VARCHAR 最大长度 SELECT PARA_NAME, PARA_VALUE FROM V$DM_INI WHERE PARA_NAME IN ('GLOBAL_PAGE_SIZE', 'MAX_ROW_SIZE');

pm7gbRA.png

2.4.5 对比存储空间

-- 在每个实例上创建相同的表并插入相同数据 -- 插入 10000 行数据 -- 查看表占用空间 /* static void createAndInsert(Connection conn) throws SQLException { try { execute(conn, "DROP TABLE IF EXISTS " + TEST_TABLE + " CASCADE"); } catch (Exception ignored) {} execute(conn, "CREATE TABLE " + TEST_TABLE + " (" + " ID INT PRIMARY KEY, " + " C_NAME VARCHAR(50), " + " C_CODE VARCHAR(20), " + " C_DESC VARCHAR(200), " + " AMOUNT DECIMAL(12,2), " + " QTY INT, " + " C_DATE DATE, " + " C_TIME TIMESTAMP, " + " STATUS CHAR(1), " + " REMARK VARCHAR(500) " + ")"); String sql = "INSERT INTO " + TEST_TABLE + " VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; try (PreparedStatement ps = conn.prepareStatement(sql)) { for (int i = 1; i <= ROW_COUNT; i++) { ps.setInt(1, i); ps.setString(2, "名称_" + i); ps.setString(3, "CODE_" + String.format("%06d", i)); ps.setString(4, "描述文本用于占空间测试_" + i + "_存储对比"); ps.setBigDecimal(5, new java.math.BigDecimal(5000 + i % 50000)); ps.setInt(6, i % 1000 + 1); ps.setDate(7, java.sql.Date.valueOf("2024-01-01")); ps.setTimestamp(8, new java.sql.Timestamp(System.currentTimeMillis())); ps.setString(9, i % 3 == 0 ? "A" : (i % 3 == 1 ? "B" : "C")); ps.setString(10, "备注信息_" + i + "_用于填充字符以测试不同PAGE_SIZE下空间差异"); ps.addBatch(); if (i % 1000 == 0) ps.executeBatch(); } ps.executeBatch(); } } // ==================== 空间查询 ==================== static void queryStorage(Connection conn, StorageResult r) throws SQLException { // 查询表段大小 try (Statement st = conn.createStatement()) { // 方式1: USER_SEGMENTS(DBA 权限可用) ResultSet rs = st.executeQuery( "SELECT BYTES, BLOCKS FROM USER_SEGMENTS " + "WHERE SEGMENT_NAME = '" + TEST_TABLE + "' AND SEGMENT_TYPE = 'TABLE'"); if (rs.next()) { r.tableBytes = rs.getLong("BYTES"); r.blocks = rs.getInt("BLOCKS"); } rs.close(); // 索引段大小 rs = st.executeQuery( "SELECT COALESCE(SUM(BYTES), 0) FROM USER_SEGMENTS " + "WHERE SEGMENT_NAME IN " + "(SELECT INDEX_NAME FROM USER_INDEXES WHERE TABLE_NAME = '" + TEST_TABLE + "')"); if (rs.next()) r.indexBytes = rs.getLong(1); rs.close(); } catch (SQLException e) { // USER_SEGMENTS 不可用时,用函数备选 try (Statement st = conn.createStatement()) { ResultSet rs = st.executeQuery( "SELECT TABLE_USED_SPACE('SYSDBA', '" + TEST_TABLE + "') AS BYTES, " + " TABLE_USED_PAGES('SYSDBA', '" + TEST_TABLE + "') AS BLOCKS " + "FROM DUAL"); if (rs.next()) { r.tableBytes = rs.getLong("BYTES"); r.blocks = rs.getInt("BLOCKS"); } rs.close(); rs = st.executeQuery( "SELECT NVL(INDEX_USED_SPACE(0, 'SYSDBA', '" + TEST_TABLE + "'), 0) FROM DUAL"); if (rs.next()) r.indexBytes = rs.getLong(1); rs.close(); } } r.totalBytes = r.tableBytes + r.indexBytes; } */

image-20260807135837812

2.5 结果与记录模板

测试项 PAGE_SIZE=4K PAGE_SIZE=8K PAGE_SIZE=16K PAGE_SIZE=32K
单列最大 VARCHAR 长度 32767字符 32767字符 32767字符 32767字符
最大列数(VARCHAR(100) x N) 2048列 2048列 2048列 2048列
10000 行表占用空间(MB) 2.25MB 2.25MB 2.50MB 3.00MB
索引最大键长度 1024字节 2048字节 4096 字节 8192字节

3. 测试二:字符集 UTF-8 与 GB18030 对存储的影响

3.1 测试目标

对比 UTF-8 和 GB18030 字符集下:

  • 数字(0-9)的存储字节数
  • 英文字母(A-Z, a-z)的存储字节数
  • 中文字符的存储字节数
  • 混合字符场景的实际存储差异

3.2 初始化两个实例

# 实例 A:UTF-8 字符集 /opt/dmdbms/bin/dminit PATH=/test/DM_utf8 PAGE_SIZE=8 EXTENT_SIZE=32 CHARSET=1 CASE_SENSITIVE=1 DB_NAME=DMTEST_UTF8 INSTANCE_NAME=DMTEST_UTF8 PORT_NUM=5241 SYSDBA_PWD=Sysdba123. SYSAUDITOR_PWD=Sysauditor123. /opt/dmdbms/script/root/dm_service_installer.sh -t dmserver -dm_ini /test/DM_utf8/DMTEST_UTF8/dm.ini -p DMTEST_UTF8 # 实例 B:GB18030 字符集 /opt/dmdbms/bin/dminit PATH=/test/DM_gb18030 PAGE_SIZE=8 EXTENT_SIZE=32 CHARSET=0 CASE_SENSITIVE=1 DB_NAME=DMTEST_GB18030 INSTANCE_NAME=DMTEST_GB18030 PORT_NUM=5242 SYSDBA_PWD=Sysdba123. SYSAUDITOR_PWD=Sysauditor123. /opt/dmdbms/script/root/dm_service_installer.sh -t dmserver -dm_ini /test/DM_gb18030/DMTEST_GB18030/dm.ini -p DMTEST_GB18030

3.3 测试 SQL

3.3.1 查询当前字符集

-- 连接 UTF-8 实例:disql SYSDBA/Dameng123@localhost:5241 -- 连接 GB18030 实例:disql SYSDBA/Dameng123@localhost:5242 SELECT UNICODE FROM V$DATABASE; -- 0=GB18030, 1=UTF-8

3.3.2 测试各类型字符的字节长度

-- ===================================================== -- 在两个实例上分别执行以下测试 -- 创建测试表 CREATE TABLE T_CHARSET_TEST ( ID INT, DIGIT_CHAR CHAR(10), -- 纯数字 ENG_CHAR CHAR(10), -- 纯英文 CN_CHAR CHAR(30), -- 纯中文 MIXED_CHAR VARCHAR(100) -- 混合字符 ); -- 插入测试数据 INSERT INTO T_CHARSET_TEST VALUES ( 1, '0123456789', -- 10 个数字 'ABCDEFGHIJ', -- 10 个英文字母 '这是测试字符串', -- 7 个中文字符 'Hello世界123测试ABC' -- 混合字符 ); COMMIT; -- 使用 LENGTHB 和 LENGTH 函数对比字节 vs 字符 SELECT ID, -- 数字字段 DIGIT_CHAR AS DIGIT_VALUE, LENGTH(DIGIT_CHAR) AS DIGIT_CHAR_LEN, -- 字符长度 LENGTHB(DIGIT_CHAR) AS DIGIT_BYTE_LEN, -- 字节长度 -- 英文字段 ENG_CHAR AS ENG_VALUE, LENGTH(ENG_CHAR) AS ENG_CHAR_LEN, LENGTHB(ENG_CHAR) AS ENG_BYTE_LEN, -- 中文字段 CN_CHAR AS CN_VALUE, LENGTH(CN_CHAR) AS CN_CHAR_LEN, LENGTHB(CN_CHAR) AS CN_BYTE_LEN, -- 混合字段 MIXED_CHAR AS MIXED_VALUE, LENGTH(MIXED_CHAR) AS MIXED_CHAR_LEN, LENGTHB(MIXED_CHAR) AS MIXED_BYTE_LEN FROM T_CHARSET_TEST;

image-20260806144528576

image-20260806145107703

3.3结果记录

字符类型 UTF-8 每字符字节数 GB18030 每字符字节数
数字 (0-9) 1 字节 1 字节
英文 (A-Z, a-z) 1 字节 1 字节
中文 (汉字) 3 字节 2 字节

3.4 分析要点

  • UTF-8:ASCII 字符(数字/英文)1 字节,中文通常 3 字节
  • GB18030:ASCII 字符 1 字节,中文 2 字节
  • 纯中文场景 GB18030 更省空间(每个汉字省 1 字节)
  • 纯英文/数字场景两者无差异

4. 测试三:大小写敏感(CASE_SENSITIVE)的影响

4.1 测试目标

验证 CASE_SENSITIVE=Y 和 CASE_SENSITIVE=N 两种模式下:

  • 对数据库对象(表名、列名、模式名)的查询差异
  • 对数据(字符串值)查询的差异
  • 实际场景中的注意事项

4.2 初始化两个实例

# 实例 A:大小写敏感 /opt/dmdbms/bin/dminit PATH=/test/DM_cs_y PAGE_SIZE=8 EXTENT_SIZE=32 CHARSET=1 CASE_SENSITIVE=y DB_NAME=DMTEST_CSY INSTANCE_NAME=DMTEST_CSY PORT_NUM=5243 SYSDBA_PWD=Sysdba123. SYSAUDITOR_PWD=Sysauditor123. /opt/dmdbms/script/root/dm_service_installer.sh -t dmserver -dm_ini /test/DM_cs_y/DMTEST_CSY/dm.ini -p DMTEST_CSY # 实例 B:大小写不敏感 /opt/dmdbms/bin/dminit PATH=/test/DM_cs_n PAGE_SIZE=8 EXTENT_SIZE=32 CHARSET=1 CASE_SENSITIVE=n DB_NAME=DMTEST_CSN INSTANCE_NAME=DMTEST_CSN PORT_NUM=5244 SYSDBA_PWD=Sysdba123. SYSAUDITOR_PWD=Sysauditor123. /opt/dmdbms/script/root/dm_service_installer.sh -t dmserver -dm_ini /test/DM_cs_n/DMTEST_CSN/dm.ini -p DMTEST_CSN

4.3 测试 SQL

4.3.1 查询当前大小写设置

-- 查看大小写敏感设置 SELECT CASE_SENSITIVE FROM V$DATABASE;

image-20260806154343809

4.3.2 测试对象名的大小写 —— CASE_SENSITIVE=Y

-- ===================================================== -- 在 CASE_SENSITIVE=Y 实例上执行(端口 5243) -- ===================================================== SELECT CASE_SENSITIVE FROM V$DATABASE; -- 1. 创建带有大小写的表名 CREATE TABLE "MyTable" ( "MyID" INT PRIMARY KEY, "MyName" VARCHAR(50) ); INSERT INTO "MyTable" VALUES (1, 'Alice'); INSERT INTO "MyTable" VALUES (2, 'Bob'); COMMIT; -- 2. 正确引用(带引号,大小写匹配) SELECT * FROM "MyTable"; -- ✅ 成功 -- 3. 不带引号(自动转大写 MyTable → MYTABLE) SELECT * FROM MyTable; -- ❌ 失败(表不存在,因为实际表名是 MyTable) -- 4. 全大写引用 SELECT * FROM MYTABLE; -- ❌ 失败 -- 5. 查看数据库中实际的对象名 SELECT TABLE_NAME FROM USER_TABLES; -- 输出:MyTable(注意大小写)

image-20260806154638637

4.3.3 测试对象名的大小写 —— CASE_SENSITIVE=N

-- ===================================================== -- 在 CASE_SENSITIVE=N 实例上执行(端口 5244) -- ===================================================== SELECT CASE_SENSITIVE FROM V$DATABASE; -- 1. 创建表 CREATE TABLE "MyTable" ( "MyID" INT PRIMARY KEY, "MyName" VARCHAR(50) ); INSERT INTO "MyTable" VALUES (1, 'Alice'); INSERT INTO "MyTable" VALUES (2, 'Bob'); COMMIT; -- 2. 查看实际存储的表名 SELECT TABLE_NAME FROM USER_TABLES; -- 输出:MyTable(保留了原始大小写) -- 3. 不带引号查询(自动转大写 → MYTABLE) SELECT * FROM MyTable; -- ✅ 成功!自动匹配到 MyTable -- 4. 全大写引用 SELECT * FROM MYTABLE; -- ✅ 成功 -- 5. 带引号的小写引用 SELECT * FROM "mytable"; -- ✅ 成功 -- 6. 带引号的正确大小写引用 SELECT * FROM "MyTable"; -- ✅ 成功 SELECT * FROM "MYTABLE"; -- ✅ 成功

image-20260806155007767

4.3.4 测试列名的大小写行为

-- CASE_SENSITIVE=Y 实例 SELECT CASE_SENSITIVE FROM V$DATABASE; -- 创建表,列名混合大小写 CREATE TABLE T_COL_CASE ( "EmpID" INT, "FirstName" VARCHAR(50), "LastName" VARCHAR(50) ); -- 查询时必须加引号且大小写匹配 SELECT "EmpID", "FirstName" FROM T_COL_CASE; -- ✅ 成功 SELECT EmpID, FirstName FROM T_COL_CASE; -- ❌ 失败(自动大写为 EMPID) SELECT "empid", "firstname" FROM T_COL_CASE; -- ❌ 失败 -- CASE_SENSITIVE=N 实例 SELECT CASE_SENSITIVE FROM V$DATABASE; -- 同样创建表 CREATE TABLE T_COL_CASE ( "EmpID" INT, "FirstName" VARCHAR(50), "LastName" VARCHAR(50) ); -- 不带引号时全部可以(自动转大写后匹配) SELECT EmpID, FirstName FROM T_COL_CASE; -- ✅ 成功 SELECT EMPID, FIRSTNAME FROM T_COL_CASE; -- ✅ 成功

image-20260806155631111

4.3.5 测试数据值的大小写比较

-- ===================================================== -- 核心测试:CASE_SENSITIVE 参数只影响对象名,不影响数据! -- 数据比较由 NLS_COMP/NLS_SORT 或 COLLATE 子句控制 -- ===================================================== -- 在两个实例上分别执行 SELECT CASE_SENSITIVE FROM V$DATABASE; CREATE TABLE T_DATA_CASE ( ID INT PRIMARY KEY, NAME VARCHAR(50) ); INSERT INTO T_DATA_CASE VALUES (1, 'Alice'); INSERT INTO T_DATA_CASE VALUES (2, 'alice'); INSERT INTO T_DATA_CASE VALUES (3, 'ALICE'); COMMIT; -- 在 CASE_SENSITIVE=Y 实例上执行(端口 5243) SELECT * FROM T_DATA_CASE WHERE NAME = 'Alice'; -- 返回 ID=1 SELECT * FROM T_DATA_CASE WHERE NAME = 'alice'; -- 返回 ID=2 SELECT * FROM T_DATA_CASE WHERE NAME = 'ALICE'; -- 返回 ID=3 -- 在 CASE_SENSITIVE=N 实例上执行(端口 5244) -- 精确查询(等值匹配) SELECT * FROM T_DATA_CASE WHERE NAME = 'Alice'; -- 返回 ID=1,2,3 SELECT * FROM T_DATA_CASE WHERE NAME = 'alice'; -- 返回 ID=1,2,3 SELECT * FROM T_DATA_CASE WHERE NAME = 'ALICE'; -- 返回 ID=1,2,3 -- ⚠️ 两种情况结果不相同,在实例端口为5243中,对于大小写是敏感的,在通过数据值查询时也对数据值敏感;但是在实例端口为5244中,其对于大小写不敏感,通过数据值查询的时候也不对数据值敏感 -- 如需大小写不敏感的数据比较,使用函数 SELECT * FROM T_DATA_CASE WHERE UPPER(NAME) = 'ALICE'; -- 返回 ID=1,2,3

image-20260806160715942

4.4 总结对比表

场景 CASE_SENSITIVE=Y CASE_SENSITIVE=N
不带引号建表 名称转大写存储 名称转大写存储
带引号建表 “Tbl” 保留原始大小写 “Tbl” 保留原始大小写 “Tbl”
不带引号查表 MyTable 查找 MYTABLE(失败) 查找 MYTABLE,自动匹配 MyTable(成功)
带引号查表 “MyTable” 精确匹配 “MyTable”(成功) 精确匹配 “MyTable”(成功)
数据值比较 大小写敏感 大小写不敏感
Oracle 兼容性 推荐 Y
MySQL 兼容性 推荐 N

4.5 迁移建议

  • 从 Oracle 迁移:CASE_SENSITIVE=Y(Oracle 默认大小写敏感)
  • 从 MySQL 迁移:CASE_SENSITIVE=N(MySQL 默认大小写不敏感,表名不区分大小写)

5. 测试四:空格填充模式(BLANK_PAD_MODE)的影响

5.1 测试目标

验证 BLANK_PAD_MODE=0(NO_PAD)和 BLANK_PAD_MODE=1(PAD)两种模式下:

  • 等值查询(=)的尾部空格处理差异
  • LIKE 查询的尾部空格处理差异
  • 对主键约束和唯一约束的影响

5.2 初始化两个实例

注意:BLANK_PAD_MODE 在 DM9 版本中不可通过 sp_set_para_value 动态修改。

# 实例 A:BLANK_PAD_MODE=1(PAD,忽略尾部空格) /opt/dmdbms/bin/dminit PATH=/test/DM_pad1 PAGE_SIZE=8 EXTENT_SIZE=32 CHARSET=1 CASE_SENSITIVE=1 BLANK_PAD_MODE=1 DB_NAME=DMTEST_PAD1 INSTANCE_NAME=DMTEST_PAD1 PORT_NUM=5245 SYSDBA_PWD=Sysdba123. SYSAUDITOR_PWD=Sysauditor123. /opt/dmdbms/script/root/dm_service_installer.sh -t dmserver -dm_ini /test/DM_pad1/DMTEST_PAD1/dm.ini -p DMTEST_PAD1 # 实例 B:BLANK_PAD_MODE=0(NO_PAD,不忽略尾部空格) /opt/dmdbms/bin/dminit PATH=/test/DM_pad0 PAGE_SIZE=8 EXTENT_SIZE=32 CHARSET=1 CASE_SENSITIVE=1 BLANK_PAD_MODE=0 DB_NAME=DMTEST_PAD0 INSTANCE_NAME=DMTEST_PAD0 PORT_NUM=5246 SYSDBA_PWD=Sysdba123. SYSAUDITOR_PWD=Sysauditor123. /opt/dmdbms/script/root/dm_service_installer.sh -t dmserver -dm_ini /test/DM_pad0/DMTEST_PAD0/dm.ini -p DMTEST_PAD0

5.3 测试 SQL

5.3.1 查询当前 BLANK_PAD_MODE

SELECT PARA_VALUE FROM V$DM_INI WHERE PARA_NAME='BLANK_PAD_MODE';

5.3.2 等值查询测试(=)

-- ===================================================== -- 在 BLANK_PAD_MODE=1 实例上执行(端口 5245) -- ===================================================== CREATE TABLE T_PAD_EQUAL (ID INT, NAME VARCHAR(20)); INSERT INTO T_PAD_EQUAL VALUES (1, 'ABC'); INSERT INTO T_PAD_EQUAL VALUES (2, 'ABC '); INSERT INTO T_PAD_EQUAL VALUES (3, 'ABC '); COMMIT; -- 等值查询 SELECT * FROM T_PAD_EQUAL WHERE NAME = 'ABC'; -- 返回 ID=1 SELECT * FROM T_PAD_EQUAL WHERE NAME = 'ABC '; -- 返回 ID=2 SELECT * FROM T_PAD_EQUAL WHERE NAME = 'ABC '; -- 返回 ID=3 -- 使用 TRIM 后查询 SELECT * FROM T_PAD_EQUAL WHERE TRIM(NAME) = 'ABC'; -- 返回 ID=1,2,3 -- ===================================================== -- 在 BLANK_PAD_MODE=0 实例上执行(端口 5246) -- ===================================================== CREATE TABLE T_PAD_EQUAL (ID INT, NAME VARCHAR(20)); INSERT INTO T_PAD_EQUAL VALUES (1, 'ABC'); INSERT INTO T_PAD_EQUAL VALUES (2, 'ABC '); INSERT INTO T_PAD_EQUAL VALUES (3, 'ABC '); COMMIT; -- 等值查询 SELECT * FROM T_PAD_EQUAL WHERE NAME = 'ABC'; -- 返回 ID=1,2,3 SELECT * FROM T_PAD_EQUAL WHERE NAME = 'ABC '; -- 返回 ID=1,2,3 SELECT * FROM T_PAD_EQUAL WHERE NAME = 'ABC '; -- 返回 ID=1,2,3

image-20260806164705832

5.3.3 主键与唯一约束测试

-- ===================================================== -- BLANK_PAD_MODE=1 实例 -- ===================================================== SELECT PARA_VALUE FROM V$DM_INI WHERE PARA_NAME='BLANK_PAD_MODE'; CREATE TABLE T_PK_PAD1 ( ID INT PRIMARY KEY, CODE VARCHAR(10) UNIQUE ); INSERT INTO T_PK_PAD1 VALUES (1, 'ABC'); -- ✅ 成功 INSERT INTO T_PK_PAD1 VALUES (2, 'ABC '); -- ✅ 成功 INSERT INTO T_PK_PAD1 VALUES (3, 'ABC '); -- ✅ 成功 COMMIT; SELECT ID, '[' || CODE || ']' AS CODE_PADDED FROM T_PK_PAD1; -- 输出:1 [ABC] / 2 [ABC ] / 3 [ABC ] -- ===================================================== -- BLANK_PAD_MODE=0 实例 -- ===================================================== SELECT PARA_VALUE FROM V$DM_INI WHERE PARA_NAME='BLANK_PAD_MODE'; CREATE TABLE T_PK_PAD0 ( ID INT PRIMARY KEY, CODE VARCHAR(10) UNIQUE ); INSERT INTO T_PK_PAD0 VALUES (1, 'ABC'); INSERT INTO T_PK_PAD0 VALUES (2, 'ABC '); -- ❌ 失败!违反唯一约束(视为与 'ABC' 相同) INSERT INTO T_PK_PAD0 VALUES (3, 'ABC '); -- ❌ 失败!违反唯一约束 COMMIT; SELECT ID, '[' || CODE || ']' AS CODE_PADDED FROM T_PK_PAD0; -- 输出:1 [ABC]

image-20260806170325434

5.3.4 LIKE 查询测试

-- 在两个实例上分别执行 SELECT PARA_VALUE FROM V$DM_INI WHERE PARA_NAME='BLANK_PAD_MODE'; SELECT ID, '[' || NAME || ']' AS NAME_PADDED FROM T_PAD_EQUAL WHERE NAME LIKE 'ABC%'; -- 结果:BLANK_PAD_MODE=0 和 BLANK_PAD_MODE=1 都返回 ID=1,2,3 -- 因为 LIKE 'ABC%' 匹配以 ABC 开头的所有字符串 -- 细化测试 -- 在BLANK_PAD_MODE=1的实例中 SELECT * FROM T_PAD_EQUAL WHERE NAME LIKE 'ABC'; -- 只返回 ID=1(精确长度匹配) SELECT * FROM T_PAD_EQUAL WHERE NAME LIKE 'ABC '; -- 只返回 ID=3 SELECT * FROM T_PAD_EQUAL WHERE NAME LIKE 'ABC '; -- 只返回 ID=2 -- 在BLANK_PAD_MODE=0的实例中 SELECT * FROM T_PAD_EQUAL WHERE NAME LIKE 'ABC'; -- 返回 ID=1,2,3(精确长度匹配) SELECT * FROM T_PAD_EQUAL WHERE NAME LIKE 'ABC '; -- 返回 ID=1,2,3 SELECT * FROM T_PAD_EQUAL WHERE NAME LIKE 'ABC '; -- 返回 ID=1,2,3

image-20260806172225262

5.4 迁移建议

  • MySQL 迁移:BLANK_PAD_MODE=1(MySQL 默认 VARCHAR 比较时忽略尾部空格,类似 PAD 语义)
  • Oracle 迁移:BLANK_PAD_MODE=0
  • 如果在唯一约束列上可能出现仅有尾部空格差异的业务数据,使用 BLANK_PAD_MODE=0

6. 测试五:参数可修改性分类

6.1 测试目标

梳理 DM 初始化参数中哪些初始化后可以修改,哪些不能修改。

6.2 不可修改的参数(初始化后固化)

参数 说明 原因
PAGE_SIZE 页大小(4/8/16/32 KB) 决定了数据文件的物理存储结构
CHARSET / UNICODE_FLAG 字符集(0=GB18030, 1=UTF-8,2=EUC-KR) 决定了数据存储的编码方式
CASE_SENSITIVE 大小写敏感(Y/N) 决定了系统表的字典序存储方式
LENGTH_IN_CHAR VARCHAR 长度以字符为单位(0/1) 影响数据字典中列的定义方式
EXTENT_SIZE 簇大小(16/32/64) 物理存储分配的基本单位
BLANK_PAD_MODE 空格填充模式 固化在数据文件元数据中,直接决定字符串索引、唯一约束的底层比较逻辑

6.3 可修改的参数(初始化后可调整)

6.3.1 通过 dm.ini 修改(重启生效)

# 编辑 dm.ini 文件 vi /test/DMpage4k/DMTEST4K/dm.ini # 可修改的参数示例: # COMPATIBLE_MODE = 0 # 兼容模式 # ENABLE_ENCRYPT = 0 # 加密开关 # MAX_SESSIONS = 100 # 运行参数 # BUFFER = 4000 # ... 等大量运行时可调参数

6.3.2 通过 sp_set_para_value 在线修改(重启生效)

-- 查看可在线修改的参数 SELECT * FROM V$DM_INI WHERE PARA_TYPE = 'IN FILE'; -- 动态修改参数(示例) -- 修改 COMPATIBLE_MODE 为 Oracle 兼容模式 SELECT PARA_VALUE FROM V$DM_INI WHERE PARA_NAME='COMPATIBLE_MODE'; SP_SET_PARA_VALUE(2, 'COMPATIBLE_MODE', 2); -- 修改后查询确认 SELECT PARA_NAME, PARA_VALUE FROM V$DM_INI WHERE PARA_NAME = 'COMPATIBLE_MODE'; -- 结果: /* SQL> SELECT PARA_VALUE FROM V$DM_INI WHERE PARA_NAME='COMPATIBLE_MODE'; 行号 PARA_VALUE ---------- ---------- 1 0 已用时间: 23.669(毫秒). 执行号:4001. SQL> SP_SET_PARA_VALUE(2, 'COMPATIBLE_MODE', 2); DMSQL 过程已成功完成 已用时间: 42.771(毫秒). 执行号:4002. SQL> SELECT PARA_NAME, PARA_VALUE FROM V$DM_INI WHERE PARA_NAME = 'COMPATIBLE_MODE'; 行号 PARA_NAME PARA_VALUE ---------- --------------- ---------- 1 COMPATIBLE_MODE 0 已用时间: 22.693(毫秒). 执行号:4003. SQL> exit [dmdba@localhost bin]$ ./DmS DmServiceDMSERVER DmServiceDMTEST4K DmServiceDMTEST_CSY DmServiceDMTEST_PAD1 DmServiceDMTEST16K DmServiceDMTEST8K DmServiceDMTEST_GB18030 DmServiceDMTEST_UTF8 DmServiceDMTEST32K DmServiceDMTEST_CSN DmServiceDMTEST_PAD0 DmSingleRowMaxTester.java [dmdba@localhost bin]$ ./DmServiceDMTEST4K restart Stopping DmServiceDMTEST4K: [ OK ] Starting DmServiceDMTEST4K: [ OK ] [dmdba@localhost bin]$ ./disql SYSDBA/Sysdba123.@127.0.0.1:5237 服务器[127.0.0.1:5237]:处于普通打开状态 登录使用时间 : 12.348(ms) disql V8 SQL> SELECT PARA_VALUE FROM V$DM_INI WHERE PARA_NAME='COMPATIBLE_MODE'; 行号 PARA_VALUE ---------- ---------- 1 2 已用时间: 37.586(毫秒). 执行号:501. */

image-20260807111443232

6.3.3 验证不可修改参数

-- 方法一:通过 ALTER SYSTEM SET -- 尝试修改 BLANK_PAD_MODE(失败) SELECT PARA_VALUE FROM V$DM_INI WHERE PARA_NAME='BLANK_PAD_MODE'; /* SQL> SELECT PARA_VALUE FROM V$DM_INI WHERE PARA_NAME='BLANK_PAD_MODE'; 行号 PARA_VALUE ---------- ---------- 1 0 已用时间: 41.399(毫秒). 执行号:3103. */ ALTER SYSTEM SET 'BLANK_PAD_MODE' = 1; -- 结果:报错,该参数不可修改 /* SQL> ALTER SYSTEM SET 'BLANK_PAD_MODE' = 1; ALTER SYSTEM SET 'BLANK_PAD_MODE' = 1; [-836]:不可修改的配置参数. 已用时间: 10.068(毫秒). 执行号:0. */ -- 尝试修改LENGTH_IN_CHAR(失败) SELECT PARA_VALUE FROM V$DM_INI WHERE PARA_NAME='LENGTH_IN_CHAR'; /* SQL> SELECT PARA_VALUE FROM V$DM_INI WHERE PARA_NAME='LENGTH_IN_CHAR'; 行号 PARA_VALUE ---------- ---------- 1 0 已用时间: 25.098(毫秒). 执行号:3107. */ ALTER SYSTEM SET 'LENGTH_IN_CHAR' = 1; -- 结果:报错,该参数不可修改 /* SQL> ALTER SYSTEM SET 'LENGTH_IN_CHAR' = 1; ALTER SYSTEM SET 'LENGTH_IN_CHAR' = 1; [-836]:不可修改的配置参数. 已用时间: 2.007(毫秒). 执行号:0. */ -- 方法二:查询参数类型 SELECT PARA_NAME, PARA_TYPE, PARA_VALUE, CASE PARA_TYPE WHEN 'READ ONLY' THEN '只读,不可修改' WHEN 'IN FILE' THEN '静态参数,修改后需重启' WHEN 'SYS' THEN '动态参数,可在线修改' WHEN 'SESSION' THEN '会话级参数' ELSE PARA_TYPE END AS MODIFIABLE FROM V$DM_INI WHERE PARA_NAME IN ( 'PAGE_SIZE', 'CHARSET', 'CASE_SENSITIVE', 'LENGTH_IN_CHAR', 'EXTENT_SIZE', 'BLANK_PAD_MODE', 'COMPATIBLE_MODE', 'MAX_SESSIONS', 'BUFFER' ) ORDER BY PARA_NAME; -- 结果: 行号 PARA_NAME PARA_TYPE PARA_VALUE MODIFIABLE ---------- --------------- --------- ---------- --------------------------------- 1 BLANK_PAD_MODE READ ONLY 0 只读,不可修改 2 BUFFER IN FILE 4000 静态参数,修改后需重启 3 COMPATIBLE_MODE IN FILE 0 静态参数,修改后需重启 4 LENGTH_IN_CHAR READ ONLY 0 只读,不可修改 5 MAX_SESSIONS IN FILE 10000 静态参数,修改后需重启 -- 此处不显示PAGE_SIZE、CHARSET、CASE_SENSITIVE、EXTENT_SIZE这几个参数是因为它们属于建库参数,不在dm.ini里,所以查不到

image-20260807105606931

image-20260807103742069

6.4 参数可修改性汇总表

参数 分类 是否可修改 修改方式 版本说明
PAGE_SIZE 物理结构 ❌ 不可修改 需重建实例
CHARSET 编码方式 ❌ 不可修改 需重建实例
CASE_SENSITIVE 字典序 ❌ 不可修改 需重建实例
LENGTH_IN_CHAR 元数据定义 ❌ 不可修改 需重建实例
EXTENT_SIZE 物理存储 ❌ 不可修改 需重建实例
BLANK_PAD_MODE 比较语义 ❌ 不可修改 需重建实例
COMPATIBLE_MODE 兼容模式 ✅ 可修改 dm.ini(重启生效)
MAX_SESSIONS 运行参数 ✅ 可修改 dm.ini(重启生效)
BUFFER 缓存参数 ✅ 可修改 dm.ini(重启生效)
ENABLE_ENCRYPT 加密开关 ✅ 可修改 dm.ini(重启生效)

6.5 验证方法

-- 在已初始化的任意实例中执行此脚本,确认各个参数的 PARA_TYPE SELECT PARA_NAME AS "参数名", PARA_VALUE AS "当前值", PARA_TYPE AS "参数类型", DESCRIPTION AS "说明" FROM V$DM_INI WHERE PARA_NAME IN ( 'GLOBAL_PAGE_SIZE', 'CHARSET', 'CASE_SENSITIVE', 'LENGTH_IN_CHAR', 'BLANK_PAD_MODE', 'EXTENT_SIZE', 'COMPATIBLE_MODE', 'MAX_SESSIONS', 'BUFFER', 'ENABLE_ENCRYPT', 'CTAB_SEL', 'PK_WITH_CLUSTER' ) ORDER BY PARA_TYPE, PARA_NAME; /* SQL> SELECT PARA_NAME AS "参数名", PARA_VALUE AS "当前值", PARA_TYPE AS "参数类型", DESCRIPTION AS "说明" FROM V$DM_INI WHERE PARA_NAME IN ( 'GLOBAL_PAGE_SIZE', 'CHARSET', 'CASE_SENSITIVE', 'LENGTH_IN_CHAR', 'BLANK_PAD_MODE', 'EXTENT_SIZE', 'COMPATIBLE_MODE', 'MAX_SESSIONS', 'BUFFER', 'ENABLE_ENCRYPT', 'CTAB_SEL', 'PK_WITH_CLUSTER' ) ORDER BY PARA_TYPE, PARA_NAME;2 3 4 5 6 7 8 9 10 11 12 13 行号 参数名 当前值 参数类型 说明 ---------- ---------------- --------- ------------ --------------------------------------------------------------------------------------------------------------------------------------------------------- 1 BUFFER 4000 IN FILE Initial System Buffer Size In Megabytes 2 COMPATIBLE_MODE 0 IN FILE Server compatible mode, 0:none, 1:SQL92, 2:Oracle, 3:MS SQL Server, 4:MySQL, 5:DM6, 6:Teradata, 7:PG, 8:DB2 3 ENABLE_ENCRYPT 0 IN FILE Encrypt Mode For Communication, 0: Without Encryption; 1: SSL Encryption and Authentication; 2: Only SSL Authentication; 3: GmSSL; 4: Only SSL Encryption 4 MAX_SESSIONS 10000 IN FILE Maximum number of concurrent sessions 5 BLANK_PAD_MODE 0 READ ONLY blank_pad_mode 6 GLOBAL_PAGE_SIZE 4096 READ ONLY global_page_size 7 LENGTH_IN_CHAR 0 READ ONLY Column max length in CHAR or BYTE, 0: in BYTE, 1: in CHAR 8 PK_WITH_CLUSTER 0 SESSION Default Flag For Primary Key With Cluster, 0: Non-Cluster; 1: Cluster 8 rows got 已用时间: 21.782(毫秒). 执行号:3701. */

image-20260807140903383


7. 附录:测试汇总表

7.1 实例清单

编号 实例名 端口 测试主题 PAGE_SIZE CHARSET CASE_SENSITIVE BLANK_PAD_MODE
1 DMTEST4K 5237 页大小 4K UTF-8 Y 1
2 DMTEST8K 5238 页大小 8K UTF-8 Y 1
3 DMTEST16K 5239 页大小 16K UTF-8 Y 1
4 DMTEST32K 5240 页大小 32K UTF-8 Y 1
5 DMTEST_UTF8 5241 字符集 8K UTF-8 Y 1
6 DMTEST_GB18030 5242 字符集 8K GB18030 Y 1
7 DMTEST_CSY 5243 大小写 8K UTF-8 Y 1
8 DMTEST_CSN 5244 大小写 8K UTF-8 N 1
9 DMTEST_PAD1 5245 空格填充 8K UTF-8 Y 1
10 DMTEST_PAD0 5246 空格填充 8K UTF-8 Y 0

7.2 测试执行顺序

第 1 步:初始化实例 1 ~ 4(页大小测试)并完成测试
第 2 步:初始化实例 5 ~ 6(字符集测试)并完成测试
第 3 步:初始化实例 7 ~ 8(大小写测试)并完成测试
第 4 步:初始化实例 9 ~ 10(空格填充测试)并完成测试
第 5 步:在任意实例(1)中执行参数可修改性查询

https://eco.dameng.com

评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服