因为项目要求,需要在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: %sn", 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: %dn", 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=参数,就是链接库的路径,例如:

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让配置文件生效

经过指定链接后,再次编译时直接通过。