Oracle-MySQL透明網關配置中關於Driver的坑

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"當數據存儲在不同種類的數據庫中,我們便會面臨異類數據訪問的問題。Oracle數據庫網關提供了在Oracle環境中透明地訪問異構數據庫的能力,這個特性可以減少應用程序定製化開發工作提升應用程序的可移植性,也可以用於異構數據庫間的數據訪問及數據遷移。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本文將介紹Oracle-MySQL透明網關的配置方法及odbc.ini中Driver選擇帶來的影響。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"一、 Oracle數據庫ODBC網關概述"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"透明網關技術由異構服務和Oracle數據庫ODBC網關兩部分組成,二者共同支持從Oracle環境對非Oracle系統的透明訪問。異構服務是數據庫的集成組件,提供了連接到非Oracle系統的通用技術。Oracle ODBC網關包括SQL映射、數據類型轉換等能力,通過動態查詢功能訪問與ODBC標準兼容的數據源。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Oracle Gateway for ODBC架構(Oracle與異構數據庫部署在不同主機上): "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/f6\/f6120fc2eef17e7af198f667b38e6db6.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在以上架構中:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"numberedlist","attrs":{"start":null,"normalizeStart":1},"content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"客戶端通過Oracle Net連接到Oracle數據庫;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"異構服務(Heterogeneous Services)組件通過Oracle Net連接到Oracle ODBC 網關;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","text":"網關與ODBC driver manager和ODBC driver通信;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":4,"align":null,"origin":null},"content":[{"type":"text","text":"當用戶會話第一次使用dblink連接到非Oracle系統時會產生一個專用的代理進程,每個用戶會話接收自己的代理進程。當用戶會話終止代理進程也終止。"}]}]}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"二、Oracle-MySQL透明網關配置方法"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"1、環境及版本"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本文主要介紹Oracle-MySQL透明網管的配置,涉及的服務器環境及操作系統數據庫版本如下:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"服務器1(OS RHEL7.3):Oracle 11.2.0.4"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"服務器2(OS RHEL7.7):MySQL 8.0"}]}]}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"2、配置步驟"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Oracle-MySQL透明網關的工作方式可簡述爲:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Oracle數據庫 --> DBLINK --> TNS別名 --> Listener監聽 --> ODBC --> MySQL connector --> MySQL監聽 --> MySQL數據庫。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Gateway配置主要包括以下步驟(在Oracle服務器上進行):"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"1)驗證Oracle透明網關已安裝"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Oracle 11.2.0.4默認安裝了odbc透明網關dg4odbc,驗證:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/98\/9821b167d32de8e0b547a554684922ed.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"2)安裝Driver Manager"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Driver Manager負責管理應用程序和驅動程序間的通信,包括:解析DSN (數據源名稱,ODBC的數據源名稱在ODBC.INI文件中配置),加載和卸載驅動程序,處理ODBC調用,將其傳遞給驅動程序。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"root用戶安裝Driver Manager ,本案例使用unixODBC:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"[root@MySQL-Test-1 ]# yum install unixODBC*\n[root@MySQL-Test-1 ]#rpm -qa |grep unixODBC\nunixODBC-devel-2.3.1-11.el7.x86_64\nunixODBC-2.3.1-11.el7.x86_64\n[root@MySQL-Test-1 ~]#"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"覈查安裝情況:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/0e\/0e3d12cf4711ebe323437ae41c99a22b.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"3)安裝mysql odbc驅動"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Connector\/ODBC(MyODBC驅動程序)實現ODBC API所提供的功能,它負責處理ODBC函數調用,將SQL請求提交給MySQL服務器,並將結果返回給應用程序。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"mysql-connector-odbc rpm包:mysql-connector-odbc-8.0.19-1.el7.x86_64.rpm"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Rpm包下載地址:https:\/\/dev.mysql.com\/downloads\/connector\/odbc\/"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"[root@MySQL-Test-1 ]# rpm -ivh mysql-connector-odbc-8.0.19-1.el7.x86_64.rpm"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"4)odbc.ini配置"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"ODBC.INI是ODBC配置文件,記錄了連接到服務器所需的驅動信息和數據庫信息。Driver Manager將使用它來確定加載哪個驅動程序(使用數據源名DSN)。驅動程序將根據指定的DSN來讀取連接參數。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在\/etc\/odbc.ini文件中定義DSN(數據源名稱,如mysql_ iom86),配置數據源信息(驅動、IP、端口、用戶名、口令、庫名等):"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"[oracle@MySQL-Test-1 etc]$ more odbc.ini\n[mysql_iom86]\nDescription = ODBC for MySQL\nDriver = \/usr\/lib64\/libmyodbc8w.so\nServer = xx.xx.xx.86\nPort = 3306\nUser = username\nPassword = password\nDatabase = test\nCHARSET = utf8\n[root@MySQL-Test-1 etc]# "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"5)測試mysql odbc是否配置成功"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"用isql測試mysql odbc是否配置成功,isql是unixODBC帶的一個ODBC客戶端訪問工具,可使用isql +數據源名來訪問目標數據庫。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/fb\/fbe5554db19ab8a9f64536ff8f024027.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"6)hs透明網關配置"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在\"ORACLE_HOME\\hs\\admin\"目錄下,默認存在名爲\"initdg4odbc.ora\"的文件,每個使用DG4ODBC的實例,都必須對應一個\"init*.ora\"文件,文件命名規則:init++.ora,文件主要參數:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"HS_FDS_CONNECT_INFO:ODBC數據源管理中的DSN名稱"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"HS_FDS_TRACE_LEVEL:追蹤級別參數,出於性能影響一般不配置或者配置爲\"OFF\",若遇到網關問題需要跟蹤日誌,則配置爲\"Debug\""}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"[oracle@MySQL-Test-1 admin]$ more initdg4mysql86.ora\n##HS Configuration\nHS_FDS_CONNECT_INFO = mysql_iom86\nHS_FDS_TRACE_LEVEL = OFF\nHS_FDS_SHAREABLE_NAME = \/usr\/lib64\/libodbc.so\nHS_LANGUAGE=AMERICAN_AMERICA.zhs16gbk\nHS_NLS_NCHAR = UCS2\nHS_FDS_FETCH_ROWS=1000\nHS_RPC_FETCH_REBLOCKING=OFF\n##ODBC Configuration\nset ODBCINI=\/etc\/odbc.ini\n[oracle@MySQL-Test-1 admin]$"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"7)網關監聽配置"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在listener.ora中增加如下配置,sid_name要與上面hs網關配置的網關sid一致(dg4mysql86):"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"SID_LIST_LISTENER =\n(SID_LIST =\n (SID_DESC=\n (SID_NAME=dg4mysql86)\n (ORACLE_HOME=\/oracle\/app\/product\/11.2.0\/dbhome_1)\n (PROGRAM=dg4odbc)\n )\n)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"8)tns配置"}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"ADDRESS:填寫透明網關的IP地址和端口"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"SID:指定連接網關的SID"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"HS:指定連接的是非ORACLE數據庫"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在tnsnames.ora中配置:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"Mysql86 =\n (DESCRIPTION =\n (ADDRESS_LIST =\n (ADDRESS = (PROTOCOL = TCP)(HOST = localhost )(PORT = 1521))\n )\n (CONNECT_DATA =\n (SID = dg4mysql86)\n )\n (HS = OK)\n )"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"9)dblink創建以及透明網關測試"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"SQL> create DATABASE LINK link_mysql86 connect to \"username\" identified by \"password\" using 'mysql86';"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"測試在Oracle端通過透明網關訪問MySQL庫數據並建表(8千萬+記錄,2.5G數據量,約4分鐘,等待事件多爲:“HS message to agent”):"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/d4\/d4b925e446394a44fc25cc6e3bc985bc.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"三、 Where條件子句未傳到MySQL端的問題"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"透明網關的配置本身比較簡單,但是在使用時也容易遇到一些意想不到問題,比如“SQL語句中的where條件未傳到MySQL端導致全表掃描”的問題。"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"1、問題描述"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在使用透明網關過程中發現當通過透明網關訪問MySQL數據庫中某張千萬級大表時,SQL語句中雖然包含了有索引字段的where條件,執行時卻不能較快返回結果(而這種情況並不是在所有SQL中都會發生),如:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"select SERIAL_NUMBER from  \"to_b_olcomwork\"@link_mysql86 where SERIAL_NUMBER='18602031223';"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"語句在MySQL中執行按索引掃描,很快返回結果:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/a1\/a1312149dd8d3b8f86c3a9ba06f78f95.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但通過透明網關執行較長時間後因網絡中斷報錯:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"SQL> select SERIAL_NUMBER from  \"to_b_olcomwork\"@link_mysql86 where SERIAL_NUMBER='18602031223';"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"ERROR at line 1:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"ORA-03113: end-of-file on communication channel"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Process ID: 20130"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Session ID: 956 Serial number: 12917"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Elapsed: 00:07:54.49"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"SQL> "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"覈查MySQL中發現傳入的語句沒有where條件,做全表掃描:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"MySQL [iom]> show full processlist;\n+--------+-------------+---------------------+------+---------+------+-----------+----------------------------------------------+\n| Id | User | Host | db | Command | Time | State | Info |\n+--------+-------------+---------------------+------+---------+------+-----------+----------------------------------------------+\n| 191413 | qyr_iom0020 | unicom86:40251 | iom | Query | 0 | starting | show full processlist |\n| 191472 | qyr_iom0020 | 132.121.26.26:42444 | iom | Sleep | 59 | | NULL |\n| 191473 | qyr_iom0020 | 132.98.26.17:40979 | iom | Query | 24 | executing | SELECT `SERIAL_NUMBER` FROM `to_b_olcomwork` |\n+--------+-------------+---------------------+------+---------+------+-----------+----------------------------------------------+\n3 rows in set (0.00 sec)\nMySQL [iom]>"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在Oracle端查看執行計劃也可見是將所有數據取到本地後再進行條件過濾:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/ef\/efd21de17441c3e99aca839bae28947c.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"2、問題分析及解決"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"誠然我們可以通過DBMS_HS_PASSTHROUGH包將原始的完整SQL直接傳遞到MySQL端執行,但這並未從根本上解決問題。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"筆者針對這個問題在MOS上開了SR,在與後臺支持工程師一同進行了數輪測試及trace跟蹤(比如調整HS_FDS_FETCH_ROWS,HS_RPC_FETCH_REBLOCKING的設置、針對不同版本的MySQL庫及不同的表測試等)後,最終定位這個問題與我們在odbc.ini中設置的Driver有關:當設置Driver = \/usr\/lib64\/libmyodbc8a.so (而不是\/usr\/lib64\/libmyodbc8w.so)時,之前的問題SQL可傳送where條件到MySQL端。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"進一步研究,MySQL 有兩個ODBC driver:libmyodbc8a.so 是ANSI ODBC driver,libmyodbc8w.so 是UNICODE ODBC driver,二者描述解析數據的方式是有不同的:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用SQL_C_CHAR檢索SQL_CHAR\/SQL_VARCHAR的數據,這意味着數據將位於non-Unicode連接字符集中,並映射爲Oracle的CHAR\/ VARCHAR2類型;"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用SQL_C_WCHAR檢索SQL_WCHAR\/SQL_WVARCHAR的數據,這意味着數據將位於Unicode連接字符集中,並映射爲Oracle的NHCHAR\/ NVARCHAR2類型。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"所以當使用\"libmyodbc8w.so\" UNICODE driver運行問題SQL時,將使用SQL_C_WCHAR檢索列並映射爲Oracle的NHCHAR\/ NVARCHAR2類型,而基於N*CHAR列的where子句會被從SELECT語句中drop掉再發送到外部數據庫;而當使用\" libmyodbc8a.so \" ANSI driver時,基於CHAR\/VARCHAR列的where子句則不會被中drop掉。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"由於SERIAL_NUMBER字段是varchar類型,使用\"libmyodbc8w.so\"UNICODE driver時,where子句被drop掉了,但改爲\" libmyodbc8a.so \" ANSI driver時,where子句則被傳到了遠端MySQL庫中,如下:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/3d\/3dad8f149eab42b5ac0f7f66a9836e74.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這一點我們在網關的trace文件中也可以看到,如:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用\"libmyodbc8w.so\" UNICODE driver:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"=> dg4mysql86w_agt_630.trc\n--------------------------------------\nEntered hgopcda at 2020\/09\/30-17:54:30\nColumn:9(SERIAL_NUMBER): dtype:-9 (WVARCHAR), prc\/scl:50\/0, nullbl:1, octet:450, sign:1, radix:10\nExiting hgopcda, rc=0 at 2020\/09\/30-17:54:30\n:\nEntered hgopars, cursor id 1 at 2020\/09\/30-17:54:30\ntype:0\nSQL text from hgopars, id=1, len=44 ...\n00: 53454C45 43542060 53455249 414C5F4E [SELECT `SERIAL_N]\n10: 554D4245 52602046 524F4D20 60746F5F [UMBER` FROM `to_]\n20: 625F6F6C 636F6D77 6F726B60 [b_olcomwork`]"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用\" libmyodbc8a.so \" ANSI driver:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"=> dg4mysql86a_agt_32490.trc\n----------------------------------------------------\nEntered hgopcda at 2020\/09\/30-17:53:06\nColumn:9(SERIAL_NUMBER): dtype:12 (VARCHAR), prc\/scl:50\/0, nullbl:1, octet:450, sign:1, radix:10\nExiting hgopcda, rc=0 at 2020\/09\/30-17:53:06\n:\nEntered hgopars, cursor id 1 at 2020\/09\/30-17:53:06\ntype:0\nSQL text from hgopars, id=1, len=89 ...\n00: 53454C45 43542041 312E6053 45524941 [SELECT A1.`SERIA]\n10: 4C5F4E55 4D424552 60204652 4F4D2060 [L_NUMBER` FROM `]\n20: 746F5F62 5F6F6C63 6F6D776F 726B6020 [to_b_olcomwork` ]\n30: 41312057 48455245 2041312E 60534552 [A1 WHERE A1.`SER]\n40: 49414C5F 4E554D42 4552603D 27313836 [IAL_NUMBER`='186]\n50: 30323033 31323233 27 [02031223']"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"因此,在這個case中,我們使用ANSI ODBC Driver \"libmyodbc8a.so\"可以解決where條件子句問題。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"四、小結"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Oracle數據庫網關提供了在Oracle環境中透明地訪問異構數據庫的能力,可以用於異構數據庫間的數據訪問及數據遷移。本文介紹了Oracle-MySQL透明網關的配置方法,也記錄了在使用透明網關過程中遇到的“Where條件子句未傳到MySQL端”問題以及解決過程,講述了ODBC Driver選擇帶來的影響,希望在此分享給有需要的同學。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"作者介紹:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"張憶蔚,廣東聯通數字與智能化創新中心DBA。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本文轉載自:dbaplus社羣(ID:dbaplus)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"原文鏈接:"},{"type":"link","attrs":{"href":"https:\/\/mp.weixin.qq.com\/s\/iKUgfTOF51HU_Kyf7EnRbA","title":"xxx","type":null},"content":[{"type":"text","text":"Oracle-MySQL透明網關配置中關於Driver的坑"}]}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章