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,要关闭所有节点,只留一个节点
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