因为项目要求,需要在linux平台上连接oracle数据库。因为之前使用的是oci8,所以面对的问题就是oci8在centos上的移植问题。下面记录一下在centos下安装,使用oci8时遇到的一些问题。
一、版本及安装包
1、centos 版本:CentOS Linux release 7.6.1810 (Core)
2、oci客户端版本:instantclient-basic-linux.x64-12.2.0.1.0.zip
、instantclient-sdk-linux.x64-12.2.0.1.0.zip
3、pkg-config
二、安装oracle客户端及配置
1、安装pkg-config
执行指令:yum install pkgconfig
安装pkg-config
配置环境变量:
打开~/.bash_profile
,在最后添加下面几行:
# pkg-config 的配置
PKG_CONFIG_PATH=/usr/lib64/pkgconfig/
LD_LIBRARY_PATH=/usr/lib64/pkgconfig/
export PKG_CONFIG_PATH
export LD_LIBRARY_PATH
执行sourcec ~/.bash_profile
使其生效。
2、下载oracle客户端
在 客户端下载地址 选择:
经过一系列的跳转,下载instantclient-basic-linux.x64-12.2.0.1.0.zip
和instantclient-sdk-linux.x64-12.2.0.1.0.zip
,图例版本是10.1.0.5,选择咱们的额12版本:
下载之后得到两个zip包,先解压instantclient-basic-linux.x64-12.2.0.1.0.zip
,然后解压instantclient-sdk-linux.x64-12.2.0.1.0.zip
:
执行下面指令:
cp libclntsh.so.12.1 libclntsh.so
ln libclntsh.so /usr/lib/libclntsh.so
ln libocci.so.12.1 /usr/lib/libocci.so
ln libociei.so /usr/lib/libociei.so
ln libnnz12.so /usr/lib/libnnz12.so
3、配置oci8.pc
打开第一步目录下的oci8.pc
,根据自己instantclient_x_x
的安装目录填写配置,我的配置如下:
注意前三行,需要根据自己情况填写。
到目前我们已经完成了配置,简单测试一下:
pkg-config --modversion oci8
pkg-config oci8
pkg-config --libs oci8
符合我们的预期,下一步我们开始编译golang代码,准备连接oracle数据库。
三、编译
package main
import (
"fmt"
_ "github.com/mattn/go-oci8"
"database/sql"
)
func main() {
db, err := sql.Open("oci8", "username/pwd@ip:1521/dbname")
if err != nil {
fmt.Println("abc", 123, err)
return
}
defer db.Close()
if err = db.Ping(); err != nil {
fmt.Printf("Error connecting to the database: %s\n", err)
return
}
rows, err := db.Query("select 2+2 from dual")
if err != nil {
fmt.Println("Error fetching addition")
fmt.Println(err)
return
}
defer rows.Close()
for rows.Next() {
var sum int
rows.Scan(&sum)
fmt.Printf("2 + 2 always equals: %d\n", sum)
}
}
1、正常情况下
执行编译指令编译编译完成。
2、不正常情况下
执行编译指令发现一堆报错,大致如下:
这种问题很叫人头大,怎么办?一步一步来定位问题在哪~
1)上图第三行说not found,那我们就看看这个libmql1.so的依赖。
执行find / -name libmql1.so
找到这个文件所在的目录,其实就是instantclient_x_x
,执行ldd libmql1.so
:
发现libipc1.so
未找到?怎么可能,明显instantclient_x_x
当前目录下就有,为什么会没找到呢?是因为链接不到当前目录,需要手动指定。
2)指定链接地址有两种方式
a.程序链接时指定链接库的位置,就是使用-wl,-rpath=<link_path>参数,<link_path>就是链接库的路径,例如:
gcc -o foo foo.c -L$(prefix)/lib -lfoo -Wl,-rpath=$(prefix)/lib
但是我们调用golang,编译都是由他自己处理的,这种方式可能不太合适或者说我的姿势不对,换另一种。
b.打开centos中/etc/ld.so.conf.d/
目录:
vim oci8.conf
将instantclient_x_x
的目录/oracle-client/12_2/instantclient_12_2
写进入,保存退出。执行ldconfig
让配置文件生效
经过指定链接后,再次编译时直接通过。
参考链接:
https://www.jianshu.com/p/bb02b541f7b2
https://blog.csdn.net/furzoom/article/details/70843664