1 概念说明
The maximum size of the VARCHAR2, NVARCHAR2, and RAW data types has been increased from 4,000 to 32,767 bytes.
Increasing the allotted size for these data types allows users to store more information in character data types before switching to large objects (LOBs). This is especially useful for brief textual data types and the capabilities to build indexes on these types of columns.
VARCHAR2、NVARCHAR2和原始数据类型的最大大小从4,000增加到32,767字节。
增加这些数据类型的分配大小允许用户在切换到大型对象(lob)之前存储更多字符数据类型的信息。这对于简短的文本数据类型和在这些类型的列上构建索引的功能特别有用。
Beginning with Oracle Database 12c, you can specify a maximum size of 32767 bytes for the VARCHAR2, NVARCHAR2, and RAW data types. You can control whether your database supports this new maximum size by setting the initialization parameter MAX_STRING_SIZE as follows:
If MAX_STRING_SIZE = STANDARD, then the size limits for releases prior to Oracle Database 12c apply: 4000 bytes for the VARCHAR2 and NVARCHAR2 data types, and 2000 bytes for the RAW data type. This is the default.
If MAX_STRING_SIZE = EXTENDED, then the size limit is 32767 bytes for the VARCHAR2, NVARCHAR2, and RAW data types.
从Oracle Database 12c开始,您可以为VARCHAR2、NVARCHAR2和原始数据类型指定最大大小为32767字节。您可以通过设置初始化参数MAX_STRING_SIZE来控制数据库是否支持这个新的最大大小:
如果MAX_STRING_SIZE = STANDARD,那么在Oracle数据库12c之前释放的大小限制适用于:VARCHAR2和NVARCHAR2数据类型的4000字节,以及原始数据类型的2000字节。这是默认的。
如果MAX_STRING_SIZE = EXTENDED,那么大小限制为VARCHAR2、NVARCHAR2和原始数据类型的32767字节。
MAX_STRING_SIZE
Property |
Description |
Parameter type |
String |
Syntax |
MAX_STRING_SIZE = { STANDARD | EXTENDED } |
Default value
|
STANDARD |
Modifiable |
ALTER SYSTEM ... SID='*'Foot 1 |
Modifiable in a PDB
|
Yes |
Basic |
No |
Oracle RAC |
Multiple instances must use the same value. |
Use ALTER SYSTEM only when the database is in UPGRADE mode, and run the utl32k.sql script afterward, as explained in this section.
MAX_STRING_SIZE controls the maximum size of VARCHAR2, NVARCHAR2, and RAW data types in SQL.
STANDARD means that the length limits for Oracle Database releases prior to Oracle Database 12c apply (for example, 4000 bytes for VARCHAR2 and NVARCHAR2, and 2000 bytes for RAW).
EXTENDED means that the 32767 byte limit introduced in Oracle Database 12c applies.
The COMPATIBLE initialization parameter must be set to 12.0.0.0 or higher to set MAX_STRING_SIZE = EXTENDED.
You can change the value of MAX_STRING_SIZE from STANDARD to EXTENDED. However, you cannot change the value of MAX_STRING_SIZE from EXTENDED to STANDARD.
By setting MAX_STRING_SIZE = EXTENDED, users are taking an explicit action that could introduce application incompatibility in their database. Applications that do not want to use the expanded data types can be rewritten for compatibility with either setting; for example, these applications could use explicit CASTs to fix the length of VARCHAR2 expressions during CREATE TABLE AS SELECT.
Altering MAX_STRING_SIZE will update database objects and possibly invalidate them, as follows:
• Tables with virtual columns will be updated with new data type metadata for virtual columns of VARCHAR2(4000), 4000-byte NVARCHAR2, or RAW(2000) type.
• Functional indexes will become unusable if a change to their associated virtual columns causes the index key to exceed index key length limits. Attempts to rebuild such indexes will fail with ORA-01450: maximum key length exceeded.
• Views will be invalidated if they contain VARCHAR2(4000), 4000-byte NVARCHAR2, or RAW(2000) typed expression columns.
• Materialized views will be updated with new metadata VARCHAR2(4000), 4000-byte NVARCHAR2, and RAW(2000) typed expression columns
仅当数据库处于升级模式并运行utl32k时才使用ALTER SYSTEM。之后的sql脚本,如本节所述。
MAX_STRING_SIZE控制SQL中VARCHAR2、NVARCHAR2和原始数据类型的最大大小。
标准的意思是在Oracle数据库12c之前,Oracle数据库发布的长度限制(例如,VARCHAR2和NVARCHAR2的4000字节,原始的2000字节)。
扩展意味着Oracle Database 12c中引入的32767字节限制适用。
兼容的初始化参数必须设置为12.0.0.0或更高,以设置MAX_STRING_SIZE = EXTENDED。
您可以将MAX_STRING_SIZE的值从标准更改为扩展。但是,不能将MAX_STRING_SIZE的值从扩展到标准。
通过设置MAX_STRING_SIZE = EXTENDED,用户将采取明确的操作,从而在数据库中引入应用程序的不兼容性。不希望使用扩展的数据类型的应用程序可以被重写,以便与设置兼容;例如,这些应用程序可以使用显式类型转换来在CREATE TABLE AS SELECT中选择VARCHAR2表达式的长度。
更改MAX_STRING_SIZE将更新数据库对象,并可能使其失效,如下:
使用虚拟列的表将更新为VARCHAR2(4000)、4000byte NVARCHAR2或RAW(2000)类型的虚拟列的新数据类型元数据。
如果对关联的虚拟列的更改导致索引键超过索引键长度限制,则功能索引将无法使用。试图重建这些索引将以ora - 01450失败:超过了最大键长度。
如果视图包含VARCHAR2(4000)、4000byte NVARCHAR2或RAW(2000)类型的表达式列,视图将失效。
物化视图将使用新的元数据VARCHAR2(4000)、400 - byte NVARCHAR2和原始(2000)类型的表达式列进行更新
在CDB中增加VARCHAR2、NVARCHAR2和原始列的最大大小
2 实验
在CDB中增加VARCHAR2、NVARCHAR2和原始列的最大大小
2.1 sysdba 登陆
[oracle@dg1 admin]$ sqlplus "/as sysdba"
SQL*Plus: Release 12.2.0.1.0 Production on Mon Jul 31 16:52:11 2017
Copyright (c) 1982, 2016, Oracle. All rights reserved.
Connected to:
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
2.2 更改参数
SQL> ALTER SESSION SET CONTAINER=CDB$ROOT;
Session altered.
SQL> ALTER SYSTEM SET max_string_size=extended SCOPE=SPFILE;
System altered.
2.3 关闭数据库
SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
2.4 以upgrade模式启动数据库
SQL> startup upgrade
ORACLE instance started.
Total System Global Area 1426063360 bytes
Fixed Size 8792776 bytes
Variable Size 889193784 bytes
Database Buffers 520093696 bytes
Redo Buffers 7983104 bytes
Database mounted.
Database opened.
2.5 升级模式open 所有PDB
SQL> ALTER PLUGGABLE DATABASE ALL OPEN UPGRADE;
Pluggable database altered.
SQL> exit;
2.6 执行rdbms/admin/utl32k.sql 脚本
Disconnected from Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
[oracle@dg1 ~]$ cd $ORACLE_HOME/rdbms/admin
在PDB中增加VARCHAR2、NVARCHAR2和原始列的最大大小
[oracle@dg1 admin]$ sqlplus "/as sysdba"
SQL*Plus: Release 12.2.0.1.0 Production on Mon Jul 31 16:52:11 2017
Copyright (c) 1982, 2016, Oracle. All rights reserved.
Connected to:
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
SQL> @?/rdbms/admin/utl32k.sql
SP2-0042: unknown command "aRem" - rest of line ignored.
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
--------------------------------------------------------------------------------
07/31/2017 16:52:14.219846000
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.
2.7 关闭数据库
SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
2.8 重启数据库
SQL> startup
ORACLE instance started.
Total System Global Area 1426063360 bytes
Fixed Size 8792776 bytes
Variable Size 889193784 bytes
Database Buffers 520093696 bytes
Redo Buffers 7983104 bytes
Database mounted.
Database opened.
2.9 读写模式启动所有PDB
SQL> ALTER PLUGGABLE DATABASE ALL OPEN READ WRITE;
ALTER PLUGGABLE DATABASE ALL OPEN READ WRITE
*
ERROR at line 1:
ORA-14696: MAX_STRING_SIZE migration is incomplete for pluggable database
PDBCNDBA
提示:脚本需要在PDB 环境下执行。参考链接:
http://www.cndba.cn/leo1990/article/2032
2.10 执行脚本rdbms/admin/utlrp.sql
SQL> conn /as sysdba
Connected.
SQL> @?/rdbms/admin/utlrp.sql
TIMESTAMP
--------------------------------------------------------------------------------
COMP_TIMESTAMP UTLRP_BGN 2017-07-31 17:55:53
DOC> The following PL/SQL block invokes UTL_RECOMP to recompile invalid
DOC> objects in the database. Recompilation time is proportional to the
DOC> number of invalid objects in the database, so this command may take
DOC> a long time to execute on a database with a large number of invalid
DOC> objects.
DOC>
DOC> Use the following queries to track recompilation progress:
DOC>
DOC> 1. Query returning the number of invalid objects remaining. This
DOC> number should decrease with time.
DOC> SELECT COUNT(*) FROM obj$ WHERE status IN (4, 5, 6);
DOC>
DOC> 2. Query returning the number of objects compiled so far. This number
DOC> should increase with time.
DOC> SELECT COUNT(*) FROM UTL_RECOMP_COMPILED;
DOC>
DOC> This script automatically chooses serial or parallel recompilation
DOC> based on the number of CPUs available (parameter cpu_count) multiplied
DOC> by the number of threads per CPU (parameter parallel_threads_per_cpu).
DOC> On RAC, this number is added across all RAC nodes.
DOC>
DOC> UTL_RECOMP uses DBMS_SCHEDULER to create jobs for parallel
DOC> recompilation. Jobs are created without instance affinity so that they
DOC> can migrate across RAC nodes. Use the following queries to verify
DOC> whether UTL_RECOMP jobs are being created and run correctly:
DOC>
DOC> 1. Query showing jobs created by UTL_RECOMP
DOC> SELECT job_name FROM dba_scheduler_jobs
DOC> WHERE job_name like 'UTL_RECOMP_SLAVE_%';
DOC>
DOC> 2. Query showing UTL_RECOMP jobs that are running
DOC> SELECT job_name FROM dba_scheduler_running_jobs
DOC> WHERE job_name like 'UTL_RECOMP_SLAVE_%';
DOC>#
PL/SQL procedure successfully completed.
TIMESTAMP
--------------------------------------------------------------------------------
COMP_TIMESTAMP UTLRP_END 2017-07-31 17:55:58
DOC> The following query reports the number of invalid objects.
DOC>
DOC> If the number is higher than expected, please examine the error
DOC> messages reported with each object (using SHOW ERRORS) to see if they
DOC> point to system misconfiguration or resource constraints that must be
DOC> fixed before attempting to recompile these objects.
DOC>#
OBJECTS WITH ERRORS
-------------------
0
DOC> The following query reports the number of exceptions caught during
DOC> recompilation. If this number is non-zero, please query the error
DOC> messages in the table UTL_RECOMP_ERRORS to see if any of these errors
DOC> are due to misconfiguration or resource constraints that must be
DOC> fixed before objects can compile successfully.
DOC> Note: Typical compilation errors (due to coding errors) are not
DOC> logged into this table: they go into DBA_ERRORS instead.
DOC>#
ERRORS DURING RECOMPILATION
---------------------------
0
Function created.
PL/SQL procedure successfully completed.
Function dropped.
PL/SQL procedure successfully completed.
2.11 验证
SQL> show parameter MAX_STRING_SIZE
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
max_string_size string EXTENDED
SQL> CREATE TABLE cndba(id NUMBER,str VARCHAR2(32767));
Table created.
SQL> desc cndba
Name Null? Type
----------------------------------------- -------- ----------------------------
ID NUMBER
STR VARCHAR2(32767)
SQL> CREATE TABLE cndba2(id NUMBER,str VARCHAR2(32768));
CREATE TABLE cndba2(id NUMBER,str VARCHAR2(32768))
*
ERROR at line 1:
ORA-00910: specified length too long for its datatype