1. 程式人生 > >linux系統中 修改oracle資料庫字符集問題

linux系統中 修改oracle資料庫字符集問題

今天在往linux系統下的oracle資料庫中匯入dmp資料庫的資料的時候,出現一些問題,經過多次調整和嘗試,最終將資料庫調整好,特此記錄。

首先,在匯出本地的資料庫的時候,由於本地的資料庫中有建 dblink連線,在用exp命令匯出資料的時候,命令列提示  大概  是連線失敗的意思,但是看著又不像是資料庫使用者本身連線失敗,經過百度查詢知道是因為該使用者下存在dblink連線,資料庫伺服器的版本(11.2.0.4.0 - 64bit)比我本地的客戶端的版本(11.2.0.1.0- 64bit)高,百度上說如果使用同樣高版本的客戶端應該可以順利匯出帶有dblink的使用者下的資料為dmp,幾經周折,也不想將本地的資料庫拆除重灌,最後確認dblink沒有其他用處,索性直接將3個dblink備份sql並刪除掉了,刪除掉之後,資料庫就順利匯出資料了。其實這裡還有一種不用刪除dblink也能將資料庫匯出為dmp檔案的方式,那就是直接在plsql上匯出(只是這種方式匯出資料的速度比exp命令匯出資料庫的速度慢很多)。

順利匯出資料庫以為就可以將資料順利匯入到另外一臺linux服務的資料庫中,當匯入資料的時候,問題又來了!匯入資料的時候,日誌中報錯:沒有相應的表空間。導致很多相關的表都匯入失敗,於是drop掉這個user,重新建user和表空間,並授權給擴充套件該表空間的授權給新建的使用者。具體步驟如下:

1、drop掉原來的使用者

sqlplus登陸資料庫

sqllus /nolong;

conn system/manager as sysdba;

drop user user_name cascade;

2、新建表空間

create tablespace tablespace_name
datafile '/data/oracle/tablespace_name.dbf'
size 50m
autoextend on
next 50m maxsize 20480m
extent management local;

關於上面新建表空間的時候 datafile 想要放的地方,建議放在和 USERS 表空間同一目錄下,如果不知道在哪個路徑下,可以使用sql查詢

SELECT * FROM Dba_Data_Files ddf WHERE ddf.tablespace_name = 'USERS';

查詢結果中的file_name欄位即是表空間所在的路徑

3、新建使用者並做授權

create user user_name identified by password;
grant connect,resource,dba to user_name;

alter user user_name quota unlimited on tablespace_name;

4、重新匯入資料庫dmp檔案

imp user_name/password file=/home/oracle/dmp/dmp_file.dmp log=/home/oracle/dmp/log_name.log FULL=y;

這次看日誌,應該是順利匯入大部分表資料了,當興沖沖的登上plsql檢視資料的時候,發現中文都是亂碼的資料,問題又來了!

這不用說,一定是匯出dmp檔案的資料庫伺服器的字元編碼(ZHS16GBK)和匯入的資料庫的伺服器的字符集編碼(AL16UTF16)是不一致導致的。

無奈!繼續drop使用者cascade   並修改匯入的資料庫伺服器的字符集編碼格式。具體步驟如下:

1、檢視兩邊資料庫的字符集編碼

select * from nls_instance_parameters where parameter='NLS_LANGUAGE';

2、修改字符集編碼

2.1.以sysdba的身份登入上去 conn /as sysdba

2.2.關閉資料庫shutdown immediate;

2.3.以mount打來資料庫,startup mount

2.4設定session

SQL>ALTER SYSTEM ENABLE RESTRICTED SESSION;
SQL> ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0;
SQL> ALTER SYSTEM SET AQ_TM_PROCESSES=0;

2.5.啟動資料庫

alter database open;

2.6.修改字符集

ALTER DATABASE CHARACTER SET ZHS16GBK;

這會可能會報錯,提示我們的字符集:新字符集必須為舊字符集的超集,這時我們可以跳過超集的檢查做更改:

ALTER DATABASE character set INTERNAL_USE ZHS16GBK;

這條語句就可以了,TERNAL_USE提供的幫助就會使oracle繞過了子集與超集的驗證,這條語句和上面的語句內部操作時完全相同的。

2.7.關閉,重新啟動

SQL>shutdown immediate;
SQL> startup

當然字符集最好不要輕易修改,因為這會對資料庫的資料有直接的影響,如果是生產環境的話,可能會造成不可估計得損失。

3、重新刪除使用者並重建user並授權。

4、重新匯入dmp資料。

匯入資料之後,在sqlus中查詢相關表資料都是正常的,以為大功告成了。可是問題又來了,plsql連不上資料庫了,報錯:TNS:ORA-12514     我很難受!!!

經過百度查詢,嘗試如下辦法,問題解決:

首先,要找到 新生成的listener.ora檔案所在的位置,可以通過 

cd $ORACLE_HOME命令 找到  oracle_home 所在的位置,然通過
lsnrctl命令stop  之後  start監聽,日誌中會打印出listener檔案所在的位置
[[email protected] ~]$ cd $ORACLE_HOME
[[email protected] dbhome_1]$ lsnrctl

LSNRCTL for Linux: Version 11.2.0.4.0 - Production on 23-DEC-2018 23:39:53

Copyright (c) 1991, 2013, Oracle.  All rights reserved.

Welcome to LSNRCTL, type "help" for information.

LSNRCTL> stop
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=ps-server5)(PORT=8083)))
The command completed successfully
LSNRCTL> start
Starting /u01/app/oracle/product/11.2.0/dbhome_1/bin/tnslsnr: please wait...

TNSLSNR for Linux: Version 11.2.0.4.0 - Production
System parameter file is /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/listener.ora
Log messages written to /u01/app/diag/tnslsnr/ps-server5/listener/alert/log.xml
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=8083)))
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC8083)))

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=ps-server5)(PORT=8083)))
STATUS of the LISTENER
------------------------
Alias                     LISTENER
Version                   TNSLSNR for Linux: Version 11.2.0.4.0 - Production
Start Date                23-DEC-2018 23:40:15
Uptime                    0 days 0 hr. 0 min. 5 sec
Trace Level               off
Security                  ON: Local OS Authentication
SNMP                      OFF
Listener Parameter File   /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/listener.ora
Listener Log File         /u01/app/diag/tnslsnr/ps-server5/listener/alert/log.xml
Listening Endpoints Summary...
  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=8083)))
  (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC8083)))
Services Summary...
Service "ocp" has 1 instance(s).
  Instance "ocp", status UNKNOWN, has 1 handler(s) for this service...
The command completed successfully
LSNRCTL> 

找到新的listener的位置,之後做如下操作:

1. 修改listener.ora檔案

預設情況下該檔案內容:

LISTENER =

(DESCRIPTION_LIST =

  (DESCRIPTION =

   (ADDRESS = (PROTOCOL = TCP)(HOST = 你的伺服器IP地址)(PORT = 1521))

   (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))

      ))

出現ORA-12514的問題時候,我們需要增加的服務配置:

 

SID_LIST_LISTENER = 

  (SID_LIST =

  (SID_DESC =

    GLOBAL_DBNAME =  一般和sid是一樣的 )

     (ORACLE_HOME = /u01/app/oracle/product/11.2.0/dbhome_1)

     (SID_NAME = 自己的sid))

  )

2. 啟動相關資料庫和監聽服務

進入 sqlplus 控制檯:sqlplus /nolog

connect / as sysdba

關閉資料庫:shutdown immediate

 開啟資料庫:startup;

退出sqlplus控制檯:exit

重啟oracle監聽,重新用plsql連線資料庫,連線成功,大功告成!