DB_BLOCK_SIZE创建后不可动态修改,必须在建库前确定;非标准块表空间需预先配置对应DB_nK_CACHE_SIZE参数,否则创建或使用时会报错。
DB_BLOCK_SIZE 设置后不能动态修改
db_block_size 是数据库创建时确定的初始化参数,决定默认数据块大小(如 8192 字节)。它写死在控制文件和数据字典里,启动后无法用 alter system 修改——哪怕你只是想临时调大一点。强行改参数再重启?不行:oracle 会校验所有数据文件头里的块大小是否与 db_block_size 一致,不匹配直接报错 ora-01122、ora-01110,实例起不来。
所以别想着“先建库再调块大小”。真需要非标准块,必须在建库前就规划好,且只适用于后续创建的非标准块表空间,不影响已有对象。
- 建库时通过
DB_BLOCK_SIZE参数指定(常见值:4096、8192、16384、32768) - 若已运行生产库,
DB_BLOCK_SIZE就锁死了,唯一办法是导出/重建库 - 注意:
DB_BLOCK_SIZE不影响 redo log 块大小(由操作系统 I/O 决定)、也不影响 temp 表空间的默认块大小(继承DB_BLOCK_SIZE)
非标准块表空间依赖 DB_nK_CACHE_SIZE 参数
要让 Oracle 接纳非标准块(比如 16KB),光建表空间不够,SGA 里得有对应尺寸的缓存池。否则建表空间时会报 ORA-29339: block size 16384 does not match database standard block size——不是语法错,是内存没配。
必须提前设置对应的缓存池参数,例如建 16KB 表空间,就得设 DB_16K_CACHE_SIZE;建 32KB 的,就得设 DB_32K_CACHE_SIZE。这些参数值不能为 0,也不能太小(至少几 MB,否则分配失败)。
-
DB_2K_CACHE_SIZE、DB_4K_CACHE_SIZE、DB_8K_CACHE_SIZE、DB_16K_CACHE_SIZE、DB_32K_CACHE_SIZE是独立参数,互不覆盖 - 如果
DB_BLOCK_SIZE=8192,那DB_8K_CACHE_SIZE不能设——它由DB_CACHE_SIZE管理 - 修改后需重启实例(这些是静态参数),且总缓存大小不能超过
SGA_TARGET或SGA_MAX_SIZE
CREATE TABLESPACE … BLOCKSIZE 必须匹配已启用的缓存池
建非标准块表空间时,BLOCKSIZE 子句写的值,必须和某个已配置且非零的 DB_nK_CACHE_SIZE 参数完全对应。比如写了 BLOCKSIZE 16384,但 DB_16K_CACHE_SIZE=0,就会报 ORA-29339;写成 BLOCKSIZE 16K 也不行——Oracle 只认数字,不认单位缩写。
另外,非标准块表空间不能存放回滚段、system 表空间对象、或数据字典基表(即不能设为 SYSTEM 或 SYSAUX 的替代品),只能放用户对象。
- 正确写法:
CREATE TABLESPACE tbs_16k DATAFILE '/u01/oradata/tbs16k01.dbf' SIZE 100M BLOCKSIZE 16384; - 错误写法:
BLOCKSIZE 16K、BLOCKSIZE '16384'(引号多余)、BLOCKSIZE 16385(不支持任意值) - 非标准块表空间中的表,其
DBA_TABLES.BLOCK_SIZE显示的是表空间块大小,不是DB_BLOCK_SIZE
非标准块对备份恢复和跨平台迁移的影响
RMAN 备份本身不关心块大小,能正常备份非标准块表空间。但还原到目标库时,目标库必须已配置对应 DB_nK_CACHE_SIZE,否则即使数据文件物理恢复成功,RECOVER 或 ALTER DATABASE OPEN 阶段也会因缓存缺失而失败。
更隐蔽的问题是 Data Pump:如果导出库有非标准块表空间,导入到目标库时,若目标库没开对应缓存池,IMPDP 会跳过这些表空间的对象(不是报错,而是静默忽略),且不会提示警告——日志里只有 ORA-39126 类似信息,容易漏看。
- 使用
EXPDP时加TRANSPORTABLE=ALWAYS要格外小心:目标库必须已存在同名、同块大小的表空间,且缓存池已启用 - 查询
V$DB_CACHE_ADVICE可确认各块尺寸缓存是否生效;查DBA_TABLESPACES.BLOCK_SIZE核对实际值 - 非标准块不会提升单 SQL 性能,反而可能因缓存碎片、管理开销略增——只为满足特定应用(如超大行、LOB 密集)才值得引入
真正麻烦的从来不是怎么建,而是所有人以为“建完就能用”,结果在备份验证、灾备切换、或者三年后第一次做跨库迁移时才发现缓存池根本没配。










