Focus On Oracle

Installing, Backup & Recovery, Performance Tuning,
Troubleshooting, Upgrading, Patching

Oracle Engineered System


当前位置: 首页 » 技术文章 » Oracle 12c+

关于max_string_size

在12c之前,数据库中数据类型varchar2和nvarchar2的最大长度为4000,数据类型RAW的最大长度为2000。在12c之后,可以扩展他们的长度,主要有初始化参数MAX_STRING_SIZE控制。我们把列长度大于4000的VARCHAR2和NVARCHAR2列以及列长度大于2000的RAW列称为扩展字符数据类型列。默认情况下MAX_STRING_SIZE的值为STANDARD。
  STANDARD:VARCHAR2,NVARCHAR2的最大长度为4000,RAW的最大长度为2000
  EXTENDED:VARCHAR2,NVARCHAR2,RAW的长度可扩展到32727
注意:我们可以将参数由STANDARD调整为EXTENDED,该操作是不可逆的。
前置条件
初始化参数COMPATIBLE必须是12.0.0.0或以上更高版本
在非容器数据库(NON-CDB)中修改,该方式修改也最简单
  conn / as sysdba
  purge dba_recyclebin;
  shutdown immediate;
  startup upgrade;
  alter system set max_string_size=extended scope=both sid='*';
  @?/rdbms/admin/utl32k.sql
  shutdown immediate;
  startup;
在容器数据库中,修改方式要复杂一些
1.只修改CDB的某个PDB,在这种方式下,我们只需修改该PDB即可。不用修改CDB中的max_string_size,然后再改PDB
2.修改CDB和CDB中所有的PDB

下面的测试,是在19c的RAC+DG的环境下,在单个PDB修改max_string_size参数,扩展varchar2,nvarchar2和raw数据类型长度的操作,属于第一种情况。

在主库上的操作
  1.关闭主库的所有节点,只留一个节点
  2.关闭主库上的要修改的单个pdb
     sqlplus / as sysdba
     show pdbs
     alter pluggable database ppdb02 close immediate;
  3.以upgrade模式打开要修改pdb
     alter pluggable database ppdb02 open upgrade;
  4.切换到要修改的PDB,并修改参数
     alter session set container=ppdb01;
     alter system set max_string_size=extended scope=both sid='*';
  5.执行脚本utl32k.sql
     SQL> @?/rdbms/admin/utl32k.sql
  6.关闭当前PDB
     show pdbs
     shut immediate
  7.重新打开PDB,并查看
     startup
     show parameter max_string_size

在主库上的操作日志



SQL> show pdbs
    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 PPDB01                         READ WRITE NO
         4 PPDB02                         READ WRITE NO
SQL> alter pluggable database ppdb02 close immediate;

Pluggable database altered.

SQL> alter pluggable database ppdb02 open upgrade;

Pluggable database altered.

SQL> alter session set container=ppdb02;

Session altered.

SQL> show parameter max_string_size

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
max_string_size                      string      STANDARD
SQL> alter system set max_string_size=extended scope=both sid='*';

System altered.

SQL> show parameter max_string_size

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
max_string_size                      string      EXTENDED
SQL> @?/rdbms/admin/utl32k.sql

Session altered.

Session altered.
DOC>#######################################################################
DOC>#######################################################################
DOC>   The following statement will cause an "ORA-01722: invalid number"
DOC>   error if the database has not been opened for UPGRADE.
DOC>
DOC>   Perform a "SHUTDOWN ABORT"  and
DOC>   restart using UPGRADE.
DOC>#######################################################################
DOC>#######################################################################
DOC>#

no rows selected

DOC>#######################################################################
DOC>#######################################################################
DOC>   The following statement will cause an "ORA-01722: invalid number"
DOC>   error if the database does not have compatible >= 12.0.0
DOC>
DOC>   Set compatible >= 12.0.0 and retry.
DOC>#######################################################################
DOC>#######################################################################
DOC>#

PL/SQL procedure successfully completed.

Session altered.

0 rows updated.

Commit complete.

System altered.

PL/SQL procedure successfully completed.

Commit complete.

System altered.

Session altered.

Session altered.

Table created.

Table created.

Table created.

Table truncated.

0 rows created.

PL/SQL procedure successfully completed.

STARTTIME
--------------------------------------------------------------------------------
PL/SQL procedure successfully completed.
No errors.
PL/SQL procedure successfully completed.
Session altered.
Session altered.
0 rows created.
no rows selected
no rows selected
DOC>#######################################################################
DOC>#######################################################################
DOC>   The following statement will cause an "ORA-01722: invalid number"
DOC>   error if we encountered an error while modifying a column to
DOC>   account for data type length change as a result of enabling or
DOC>   disabling 32k types.
DOC>
DOC>   Contact Oracle support for assistance.
DOC>#######################################################################
DOC>#######################################################################
DOC>#
PL/SQL procedure successfully completed.
PL/SQL procedure successfully completed.
Commit complete.
Package altered.
Package altered.
Session altered.
SQL>
SQL> show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         4 PPDB02                         MIGRATE    YES
SQL> shut immediate
Pluggable Database closed.
SQL>
SQL> startup
Pluggable Database opened.
SQL>
SQL> show parameter max_string_size
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
max_string_size                      string      EXTENDED

在备库上的操作
 测试的时候,整个CDB是备库的READ ONLY WITH APPLY,ppdb02是刚在主库上建的数据库,在备库是mount状态,打开后,max_string_size参数就自动调整过来了。如果没有修改过来,可以先关闭该pdb,然后重新打开该pdb应该就好了show parameter max_string_size

备库上的操作日志

SQL> conn / as sysdba
Connected.
SQL> show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 PPDB01                         READ ONLY  NO
         4 PPDB02                         MOUNTED
SQL> alter pluggable database ppdb02 open;

Pluggable database altered.

SQL> show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 PPDB01                         READ ONLY  NO
         4 PPDB02                         READ ONLY  NO
SQL> alter session set container=ppdb02;

Session altered.

SQL> show parameter max_string_size

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
max_string_size                      string      EXTENDED
SQL> select open_mode from v$database;

OPEN_MODE
--------------------
READ ONLY WITH APPLY

SQL>

创建带有扩展字符数据类型的表

如果我们仔细查看创建的表,就会发现extended的数据类型,实际上是隐藏了LOB的处理。每个扩展列都包含了一个相关的LOB Segment和LOB Index,以out-of-line的方式存储,在ASSM中默认以SecureFiles的方式存储。关于LOB,可以参考http://www.juliandyke.com/Presentations/LOBInternals.ppt,可通过下面的语句来查看。
   column object_name for a40
   column object_type for a40
   select object_name,object_type from user_objects;

创建表,然后用ALTER TABLE修改列的属性来扩展列的大小,发现并没有新的LOB Segment和Index创建。用这种方式的也能实现,但会出现很多行迁移的情况,因为数据并没有使用LOB的方式,所有的行数据存在块中。

如果要改变上面的方式,可以通过create table as的方式创建新表。创建后,扩展字段的LOB Segment和Index就正常了

修改CDB和CDB中所有的PDB

用sysdba权限连接到CDB
  sqlplus / as sysdba
在CDB$ROOT中修改MAX_STRING_SIZE为EXTENDED
  ALTER SESSION SET CONTAINER=CDB$ROOT;
  ALTER SYSTEM SET max_string_size=extended SCOPE=SPFILE SID='*';

  注意:虽然在这一步在root将参数max_string_size修改为了EXTENDED,但在root中仍然显示为STANDARD。
关闭整个CDB
  shut immediate
重启容器数据库CDB到upgrade模式
  startup upgrade;
通过catcon.pl脚本在ROOT和所有的PDB中运行rdbms/admin/utl32k.sql
  $ cd $ORACLE_HOME/rdbms/admin
  $ mkdir /scratch/mydir/utl32k_cdb_pdbs_output
  $ $ORACLE_HOME/perl/bin/perl $ORACLE_HOME/rdbms/admin/catcon.pl -u SYS --force_pdb_mode 'UPGRADE' -d $ORACLE_HOME/rdbms/admin -l '/scratch/mydir/utl32k_cdb_pdbs_output' -b
  utl32k_cdb_pdbs_output utl32k.sql
用sysdba权限连接到CDB并关闭数据库
  shut immediate
以正常模式重启整个CDB
 startup;
通过catcon.pl脚本在ROOT和所有的PDB运行rdbms/admin/utlrp.sql编译无效对象
  $ cd $ORACLE_HOME/rdbms/admin
  $ mkdir /scratch/mydir/utlrp_cdb_pdbs_output
  $ $ORACLE_HOME/perl/bin/perl $ORACLE_HOME/rdbms/admin/catcon.pl -u SYS --force_pdb_mode 'READ WRITE' -d $ORACLE_HOME/rdbms/admin -l '/scratch/mydir/utlrp_cdb_pdbs_output' -b utlrp_cdb_pdbs_output utlrp.sql
注意:如果是RAC,要关闭所有节点,只留一个节点


Reference
https://docs.oracle.com/database/121/REFRN/GUID-D424D23B-0933-425F-BC69-9C0E6724693C.htm#REFRN10321

https://docs.oracle.com/en/database/oracle/oracle-database/19/refrn/MAX_STRING_SIZE.html#GUID-D424D23B-0933-425F-BC69-9C0E6724693C


关键词:max_string_size 12c 

相关文章

关于max_string_size
在Oracle数据库中使用JSON
保障业务连续性的神器
Oracle事务卫士(Transaction Guard)和应用连续性(Application Continuity)
容器数据库(CDB)和可插拔数据库(PDB)概述
How to generate AWR on PDB and ADG(12.2 afterwards)
在12c上使用wm_concat
Exadata with database 12.2
如何在oracle 12c中正确的应用补丁?
在OEL6.8上安装12.2 RAC
Oracle Database 12.2 Hands-On Lab
How to create single physical standby for RAC
Top