大數據“復活”記
919
2025-03-31
用戶的應用程序,調用的ODBC的API,其實是由驅動管理器提供的,這個驅動管理器在微軟上就是odbcad32(.exe/.dll),在Linux上就是UnixODBC。再由它們來調用ODBC的具體驅動(Gauss、Oracle、TD……)。
所以一般問題基本會出在以下幾個方面:
應用加載驅動管理器
驅動管理器加載驅動
驅動連接數據庫
一個典型的用戶應用程序如下:
問題處理
應用程序加載驅動管理器失敗
Windows
Windows由于操作系統實現機制的問題,ODBC屬于操作系統組件的一部分,除非操作系統損壞,一般不會出現應用程序加載驅動管理器失敗;只會出現驅動管理器加載驅動失敗。所以這里不再贅述。
Linux
Linux上應用程序加載驅動管理器,是指的應用程序依賴于UnixODBC的相關動態庫,啟動時要將其加載到自己的進程空間中。加載出現問題多表現為在啟動時找不到libodbc.so.x/libodbcinst.so.x等庫。
解決此問題:
首先確認環境中是否安裝了UnixODBC。如果安裝了,那么至少會有isql/odbcinst等工具可用。例如可使用which?isql這樣的命令來確定安裝路徑。相關的lib庫一般會在which?isql指定的bin目錄的同級目錄下,將其添加到LD_LIBRARY_PATH中重啟應用程序便可。
export?LD_LIBRARY_PATH=/where/unixodbc/installed/lib:$LD_LIBRARY_PATH
特別注意,此語句只影響當前shell會話中的后續命令,其他會話不受影響,特別是后臺啟動的進程。如果是后臺進程,請與應用程序的開發人員確認其運行環境如果修正。
如果確認LD_LIBRARY_PATH已經生效(可以打開/proc/應用程序pid/environ文件確認),依然無法加載libodbc.so.x/libodbcinst.so.x,那么可能是.1或者.2的庫的問題。
歷史原因,一般的開發環境中,UnixODBC提供的庫既可能叫libodbc.so.1也可能叫libodbc.so.2。用戶程序可能依賴了.2,但是環境中只有.1;也有可能是存在.2,但是依賴了.1。
解決此問題,只需要在UnixODBC的lib目錄下,將不存在的版本建立成軟鏈接,保證.1與.2都存在,這樣出問題的機率便會小很多。特別注意,這里強烈建議是建立軟鏈接,而不要拷貝物理文件,不然可能出現一個應用程序進程中,加載了兩個導出函數完全相同的.so,這樣可能會引起一些比較難定位的啟動錯誤,后文中會講到。
驅動管理器加載驅動失敗
Windows
最常見x86與x64架構不同導致的加載失敗;此問題的典型報錯為:
在指定的?DSN?中,驅動程序和應用程序之間的體系結構不匹配
此問題可能的原因:在64位程序中使用了32位驅動,或者相反。
在64位系統上:
C:\Windows\SysWOW64\odbcad32.exe:這是32位ODBC驅動管理器。
C:\Windows\System32\odbcad32.exe:這是64位ODBC驅動管理器。
使用不同架構的應用程序時,請使用不同的驅動管理器;同時安裝不同的驅動類型。
32位系統上只能跑32位程序,也無法安裝64位驅動,所以基本不用區分。
如果是64位系統,那么它既支持32位程序,也支持64位程序;如果不能確定應用程序是32還是64,可以使用以下辦法:
ctrl?+?shift?+?esc?打開任務管理器
查看進程列表中某進程后邊有沒有*32的字樣(有就是32位,沒有就是64位),如下圖:\
Linux
一般這個問題的報錯是
[UnixODBC][Driver?Manager]Can't?open?lib?'xxx/xxx/psqlodbcw.so'?:?file?not?found.
可能的原因有:
odbcinst.ini中配置的路徑不正確,最簡單的辦法是??ls?-l?一下這個報錯的文件,看看這個是不是真的存在,同時具有執行權限。
依賴的庫不存在,此時最簡單的辦法是ldd?一下這個報錯的文件,看看是不是真的缺少庫,如果缺少庫會出現如下問題:
要處理這個問題,需要將unixodbc的安裝目錄下的lib,添加到LD_LIBRARY_PATH里,例如:
export LD_LIBRARY_PATH=/where/unixodbc/installed/lib:$LD_LIBRARY_PATH
同時,在UnixODBC的安裝的lib目錄下,看看libodbcinst.so.x后邊的后綴是.1還是.2。如果是.2,那么請建立一個軟鏈接,鏈接到.1,便可以解決此問題。
如果該目錄下只有.1的庫,沒有.2的庫,也建議建立一個.2的軟鏈接,防止應用程序依賴于.2,我們依賴于.1,引起沖突。
特別注意,當前會話的LD_LIBRARY_PATH不代表應用程序運行時也是同樣的LD_LIBRARY_PATH,必要的時候,與應用程序開發人員對齊。
如果是常駐進程,可以通過如下方法獲取到當前進程的環境變量:
cd /proc/應用程序PID cat environ
打印出來的結果可能比較亂,耐心看一下;如果內容有誤,與應用程序開發人員對齊修改方法。
這種勤快的用戶比較少見,但是一旦出現,很難定位,典型的報錯信息是:
Driver's?SQLAllocHandle?on?SQL_HANDLE_DBC?failed
這種情況這時應用與驅動加載的是不同的物理文件,便會導致兩套完全同名的函數列表,同時出現在同一個可見域里(UnixODBC的libodbc.so.*的函數導出列表完全一致),產生沖突,無法加載數據庫驅動。
解決此問題的辦法也比較簡單,查看LD_LIBRARY_PATH中的第一個unixodbc的lib目錄。在其目錄下,缺少.2或.1,建立對應的.2或.1的軟鏈接便可。
連接問題
服務器不可達
典型報錯:
connect?to?server?failed:?no?such?file?or?directory
此問題可能的原因:
配置了錯誤的/不可達的數據庫地址,或者端口
請檢查數據源配置中的Servername及Port配置項,確認網絡是通達的。
服務器監聽不正確
如果確認Servername及Port配置正確,請根據資料中listen_addresses參數的配置方法,確保數據庫監聽了合適的網卡及端口,特別是Servername中指定的網卡地址及LVS的虛擬IP地址。
修改完記得重啟數據庫,使監聽生效。
防火墻及網閘、流控設備
請確認防火墻設置,將數據庫的通信端口添加到可信端口中。
如果有網閘、流控設備,請確認一下相關的設置。
此問題一般都是第三方商業產品導致,需要咨詢服務/產品提供商相關的策略。
SSL配置不正確
典型報錯1:
The?password-stored?method?is?not?supported.
解決辦法1:
請將數據源配置中的的sslmode調整至allow及以上級別,允許使用SSL連接。
典型報錯2:
Server?common?name?"xxxx"?does?not?match?host?name?"xxxxx"
此問題是由于sslmode中使用了全校驗(verify-full),它不僅會校驗證書,還會校驗證書所在的域名/機器名是否與證書符合,不符合時將報出此問題。
解決辦法2:
重新讓CA機構以新的域名/機器名簽發證書;或者將SSLMODE調整至verify-ca選項或其以下級別(具體級別見產品資料中的說明)。
使用開源驅動連接問題
我們的數據庫是支持低版本及開源驅動的(V1R7C10及以后),所以可以放心使用。
但是偶爾一些從V1R6C10升級上來的數據庫,接受開源驅動連接時,會碰到用戶認證算法不支持的問題,典型報錯如下:
authentication?method?10?not?supported.
此問題機理比較復雜,下面詳細展開,先說解決辦法:
請使用管理新賬號新建一個數據庫的用戶,并給予其相關的訪問權限,使用新用戶連接數據庫。
更改當前業務用戶的密碼,使用新密碼連接數據庫。
解釋一下此問題發生的機理:
我們的數據庫在連接時,是會讓客戶端將認證信息發過來的。但是發過來的信息不會是明文密碼,這是不安全的;客戶端發到數據庫的認證信息一般是經過加鹽后的密碼哈希(md5/sha256算法),迭代次數也非常多。
數據庫本身也并不存儲用戶的明文密碼,存儲的是一個哈希值(所以密碼要是丟了,就真的丟了,只能重置不能找回)。數據庫在校驗這個密碼的時候,是比較哈希的,這就涉及到數據庫中存儲的哈希是使用的什么算法得到的哈希值,常見的是sha256(高斯自研)及MD5(開源)。
V1R7C00及以前,數據庫中只存儲了SHA256的哈希,升級時我們也無法推導用戶原有密碼,所以升級后仍然只有SHA256的哈希;但是開源客戶端只識別MD5的哈希,這就導致數據庫無法認證;數據庫也只會讓客戶端以SHA256的哈希來做認證,這時開源就不識別該認證請求,導致報出如上的錯誤。
在創建用戶和修改用戶密碼時,我們的新版本會同時記錄兩份哈希,所以后續將會同時支持開源及自研的各個版本。
因數據源配置不正確,導致的連接錯誤
典型報錯:
Data?source?name?not?found,?and?no?default?driver?specified
可能原因:
數據源名稱書寫錯誤(或含有特殊符號)
不同的操作系統用戶下,數據源可見性不一樣;
Linux上的數據源配置文件(odbc.ini)位置不正確
解決辦法:
修正數據源名稱.
Windows下,請在當前用戶下打開驅動管理器,查看數據源配置是否正確。
請注意在64位系統上使用正確的數據源管理器:
C:\Windows\SysWOW64\odbcad32.exe:這是32位ODBC驅動管理器。
C:\Windows\System32\odbcad32.exe:這是64位ODBC驅動管理器。
Linux下使用odbcinst?-j?命令,查看當前環境中配置文件的正確路徑,輸出一般如下:
unixODBC 2.3.0 DRIVERS............: /usr/local/etc/odbcinst.ini/odbcinst.ini SYSTEM DATA SOURCES: /usr/local/etc/odbcinst.ini/odbc.ini FILE DATA SOURCES..: /usr/local/etc/odbcinst.ini/ODBCDataSources USER DATA SOURCES..: /usr/local/etc/odbc.ini SQLULEN Size.......: 8 SQLLEN Size........: 8 SQLSETPOSIROW Size.: 8
其中USER?DATA?SOURCES就是用戶數據源,優先生效;SYSTEM?DATA?SOURCES是系統數據源,整個系統可用。請針對這些文件路徑,
注意:有時用戶數據源的配置文件可能是$(HOME)/.odbc.ini
通信協議不匹配問題
典型報錯:
unsupported?frontend?protocol?3.51:?server?supports?1.0?to?3.0
可能原因:
使用了新版本的數據庫驅動連接老版本的數據庫(V1R6C10);
或者使用了我們的驅動,連接到了開源的數據庫上。
解決辦法:
請使用老版本的數據庫驅動連接該數據庫。
我們的數據庫中,默認低版本客戶端可以連接高版本數據庫;使用高版本驅動連接低版本客戶端,不在規格約束范圍內。
這個規格也比較好理解:因為用戶一般是對數據庫集中管理,升級也是有計劃的。但是客戶端驅動可能嵌入到業務中的每一個角落,有時甚至是已經發布的裝備中,升級相對比較困難。
如果是開源服務器:我們的數據庫驅動不支持開源數據庫,無法連接;請使用開源客戶端連接。
其他常見疑問
與開源的區別?
增加了安全性,使用了SHA256算法做認證加密;同時調整密鑰哈希加密次數
提升了批量性能(V1R7C10?2019-4-30及以后版本)
是否可以增加新API?
不可以。
還是基礎知識里那張圖,用戶引用的API是由驅動管理器提供的,我們提供的API只可供驅動管理器使用;新增API無法穿過中間層為用戶提供服務。
是否支持COPY接口?
Copy是PG的特有語法及通信協議;而ODBC是微軟提出的通用調用接口,所以無此特殊接口。
Linux上的驅動管理器有哪些?
驅動管理器在Linux上并不是操作系統的一部分,它也是由其他開源組織開發的。所以并不是只有UnixODBC一種。但是目前使用最廣泛的,其實只有UnixODBC,多數據操作系統安裝時基本都已經自帶了UnixODBC的某個特定版本;除此之外,還有iODBC等,現在已經慢慢退出市場了。
UnixODBC的版本有限制么?
有。我們支持2.3.0及以上版本。
UnixODBC的.1與.2的庫有什么區別?
沒有什么區別。
這個與UnixODBC的歷史有關,歷史上有一段時間提供.1,后來做了一次大升級,動態庫版本也跟著升級了,變成了.2。但是一大批存量業務受制無法運行,就又添加了.1的支持。
.1與.2其實只是UnixODBC的configure配置的一部分,其函數導出,功能完全一致,不必糾結于此。
可以打印日志么?
可以。
一般建議打印驅動管理器的日志,此日志比較清晰,定位問題比較快。操作辦法:
Windows上:
打開驅動管理器,調整到跟蹤頁面,確定日志文件路徑后,點擊開始跟蹤便可,如圖:
Linux上:
打開odbcinst.ini文件(可使用odbcinst?-j?來確定文件路徑),添加以下章節:
[ODBC] Trace=Yes TraceFIle=/tmp/odbc.log
重啟業務便可。
注意:非必要時,請關閉日志,因為每個API都存在寫盤,將會引起性能損失。
查詢結果集過大,內存吃不消怎么辦?
打開UseDclareFetch開關,它將會把查詢包裝成游標操作。對于不支持Cursor?with?hold的版本慎用。同時由于使用了服務器端的游標,游標的前后滾操作也會反饋給數據庫,通信會有所增加,所以性能會有部分下降;可以通過調整Fetch參數來確定每次數據庫向客戶端反饋的數據量大小,來降低該性能影響。
Linux下打開UseDeclareFetch的方法:
在數據源配置項中添加:
UseDeclareFetch=1 Fetch=1000
Windows下打開UseDeclareFetch的方法:
其中的Cache?Size選項,就是Fetch的大小。
有性能基線數據么?
創建連接的性能大體為0.5s內都算正常(一般0.3s左右)
數據插入的話
非批量版本(R7C10以及前)大約為400tps(SSD的測試結果)
批量版本(R8C10及以后)大約為4000tps(SSD服務器),由于數據庫對象差異、網絡、物理硬件等,基本2000tps以上都可以認為是正常
語句出錯怎么排查?
運行過程中出錯,ODBC是不會打屏的。錯誤信息需要業務里獲取錯誤信息(API為:SQLGetDiagField/SQLGetDiagRec)。
如果用戶的業務里有打印具體的錯誤信息,或者業務的錯誤信息不足以定位,請根據3.7中的描述,將ODBC的日志打印出來,在其中找SQL_ERROR相關信息。這里最好能和業務開發人員一起定位,因為API的調用序列是亂序的,由業務決定。
如果ODBC的日志仍然不足以定位支撐,請登錄到連接的目標CN所在的機器,通過以下方法進入CN日志文件目錄:
source ${BIGDATA_HOME}/mppdb/.mppdbgs_profile cd $GAUSSLOG/pg_log/cn_50xx #這里的cn_50xx表示CN編號,根據實際情況修改
找到對應時間點的日志,觀察其中是否有錯誤信息。
我們與Oracle/MYSQL的ODBC有什么關系
ODBC是一套標準,每家數據庫提供自己的驅動文件。就像大家都叫顯卡,每個廠商也都提供自己的驅動,自己的驅動只能驅動自己的顯卡;而顯卡的接口標準是微軟(ODBC也是微軟)制定的,只是大家不接觸,不知道有這樣一套標準而已。
我們的驅動文件叫psqlodbcw.so/psqlodbcw.dll。
支持GBK么?
支持。
但是我們ODBC驅動默認使用utf-8編碼。如果要調整,需要自行在會話開始時設置client_encoding。
但是請注意,請不要在寬字節模式下使用GBK,因為寬字節編碼本身就是UNICODE的一部分(一般為UCS2),此時使用GBK可能導致數據無法顯示,SQL查詢結果不正確等問題。
如果出現此問題,請將VS中的解決方案字符集調整為“多字節”。
文章由博主@歸云原創
想了解GuassDB(DWS)更多信息,歡迎微信搜索“GaussDB DWS”關注微信公眾號,和您分享最新最全的PB級數倉黑科技,后臺還可獲取眾多學習資料哦~
EI企業智能 Gauss AP 數據倉庫服務 GaussDB(DWS) 數據庫
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。