配置 UnixODBC

麒麟&达梦适配系列:

1.麒麟服务器上安装 DM8
2.配置 UnixODBC
3.beego-ORM 适配达梦



资源紧张的时候,服务器是大家共用的,上面部署了一堆服务。所以选用docker 进行 unix odbc 的编译和适配。避免牵一发而动全身,影响他人使用。(我不会告诉你其实:是服务器 gcc 版本太低了,编译报错

因为最终,我们是使用 golang 进行开发的。所以基于 golang1.14 镜像来构建。

1 创建 Dockerfile

root@Kylin:/data/liutongtong011# cd /data/liutongtong011
root@Kylin:/data/liutongtong011# touch Dockerfile

Dockerfile 内容:

FROM golang:1.14

RUN apt-get update && \
    apt-get install -y unixodbc-dev unixodbc && \
    go get github.com/alexbrainman/odbc

2 根据 Dockerfile build 镜像

docker build - < Dockerfile -t liutongtong011

3 查看镜像是否存在

docker images | grep liutongtong011

4 启动容器

docker run -it liutongtong011

说明:执行完 docker run 自动就登录到容器内了。如果想要再其他session进入容器,执行以下步骤:

5 查看容器 ID

docker ps | grep liutongtong

说明:第一列即为容器 ID

6 登录容器

docker exec -it 017a0f7a3067 bash

容器启动成功后,在容器内部进行 UnixODBC 的配置:

1 使用 odbcinst -j 命令查看 odbc的配置

root@Kylin:/go# odbcinst -j
unixODBC 2.3.6
DRIVERS............: /etc/odbcinst.ini
SYSTEM DATA SOURCES: /etc/odbc.ini
FILE DATA SOURCES..: /etc/ODBCDataSources
USER DATA SOURCES..: /root/.odbc.ini
SQLULEN Size.......: 8
SQLLEN Size........: 8
SQLSETPOSIROW Size.: 8

2 配置 odbc.ini

[DM8]
Description   = DM ODBC DSN
Driver     = DM8 ODBC DRIVER
SERVER     = 172.0.0.1
UID       = SYSDBA
PWD       = SYSDBA
TCP_PORT   = 5236

说明:为了减少出错的可能,我就直接将 /root/.odbc.ini/etc/odbc.ini 配置成一样的了

3 配置 odbcinst.ini

[DM8 ODBC DRIVER]
Description   = ODBC DRIVER FOR DM8
Driver     = /opt/dmdbms/bin/libdodbc.so
Setup     = /lib/libdmOdbcSetup.so
threading = 0

说明:

  • 这里的 title [DM8 ODBC DRIVER] 必须和 odbc.ini 中的 Driver 保持一致
  • 这里的 /opt/dmdbms/bin/libdodbc.so 是达梦的 so,而非 UnixODBC 自带的

4 使用 isql 登录数据库

root@Kylin:/go# isql -v DM8
+---------------------------------------+
| Connected!                            |
|                                       |
| sql-statement                         |
| help [tablename]                      |
| quit                                  |
|                                       |
+---------------------------------------+

说明:-v 的作用是,一旦报错,可以展示报错详情

5 执行任意 sql 测试

SQL> select * from v$version;
+---------------------------------------------------------------------------------+
| BANNER                                                                          |
+---------------------------------------------------------------------------------+
| DM Database Server 64 V8
                                                       |
| DB Version: 0x7000b                                                             |
+---------------------------------------------------------------------------------+
SQLRowCount returns 2
2 rows fetched

如果 isql 可以成功连接DB,并能执行测试语句,说明 UnixODBC 配置成功。


这里简单介绍几个Docker命令,熟悉Docker的同学可以跳过这一趴:

docker commit e9f39c7081e0 unixodbc001 

说明:

  • e9f39c7081e0: 正在运行的容器ID,可以使用 docker ps 查看
  • unixodbc001:自定义的镜像名称
docker tag unixodbc001 registry.cn-beijing.aliyuncs.com/liutongtong/unixodbc001:V0.1
docker push registry.cn-beijing.aliyuncs.com/liutongtong/unixodbc001:V0.1

说明:像镜像仓库中提交该镜像,以后用的时候,直接拉取即可。



现实往往是残酷的,上面简单的几步中可能会遇到许多问题。

我把自己在安装过程中踩的坑,报的错及解决方案列在下面,供大家参考:

使用源码编译安装UnixODBC:

起初在网上找了达梦大学的官方教程:http://www.dameng.com/teachers_view.aspx?TypeId=183&Id=891&FId=t26:183:26

按照里面的步骤进行源码安装。最先遇到的问题是:



=> configure 时报错:cannot guess build type

./configure
UNAME_MACHINE = aarch64
UNAME_RELEASE = 4.4.131-20200704.kylin.server-generic
UNAME_SYSTEM  = Linux
UNAME_VERSION = #kylin SMP Sat Jul 4 19:29:27 CST 2020
configure: error: cannot guess build type; you must specify one

解决办法:./configure --build=arm



=> 无法编译出 .so文件</font>

即便增加enable-shared也无法解决问题

 ./configure  --build=arm --enable-shared

编译出来的始终是 .a.la 文件。

尝试手动合成 .so

root@greatwall-os:/usr/local/lib# ar -x libodbcinst.a
root@greatwall-os:/usr/local/lib# gcc -shared *.o -o  libodbcinst.so

报错:

/usr/bin/ld: libltdlc_la-ltdl.o: relocation R_AARCH64_ADR_PREL_PG_HI21 against external symbol `__stack_chk_guard@@GLIBC_2.17' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: libltdlc_la-ltdl.o(.text+0x6e4): 无法解决 R_AARCH64_ADR_PREL_PG_HI21 重定向于符号 “__stack_chk_guard@@GLIBC_2.17” 有冲突
/usr/bin/ld: 最后的链结失败: 错误的值
collect2: error: ld returned 1 exit status

解决办法:清除现有 odbc,增加 configure 参数后重新安装

make uninstall && make clean

CFLAGS="-fPIC" ./configure --build=arm 
# 编译出来还是 .a ,但是这回  .a 是可以合并成 .so 的

ar -x /usr/local/lib/libodbc.a
gcc -shared *.o -o libodbc.so



=> could not determine kind of name for C.SQL_WLONGVAR

之前用的UnixODBC2.21版本过低,升级到2.3.2即可解决问题



=> isql 时报 file not found

[root@dameng-test001 dameng]# isql -v DM8 SYSDBA SYSDBA
[01000][unixODBC][Driver Manager]Can't open lib '/home/dmdba/dmdbms/bin/libdodbc.so' : file not found

使用 ls -l /home/dmdba/dmdbms/bin/libdodbc.so 命令可以看到文件存在,且权限为可访问。

使用 ldd 命令查看依赖是否有问题:

[root@dameng-test001 dameng]# ldd /home/dmdba/dmdbms/bin/libdodbc.so
    linux-vdso.so.1 =>  (0x00007fff36943000)
    libdmdpi.so => not found
    libdmfldr.so => not found
    librt.so.1 => /lib64/librt.so.1 (0x00007fbcec98a000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fbcec76e000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00007fbcec56a000)
    libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007fbcec263000)
    libm.so.6 => /lib64/libm.so.6 (0x00007fbcebf61000)
    libc.so.6 => /lib64/libc.so.6 (0x00007fbcebb93000)
    libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fbceb97d000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fbcece44000)

发现是找不到以来的lib

进行全局查找:find / -name "libdmdpi.so" 发现实际上时存在的。路径为:/home/dmdba/dmdbms/bin/
这里路径和之前不一致是因为,为了保证可行性,先在Linux上做了适配

.bash_profile 中配置 LD_LIBRARY_PATH 变量:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/dmdba/dmdbms/bin/



=>[S1000][unixODBC]Encryption module failed to load

这是因为,在DM8中,加密模块已不在libdodbc.so

解决办法:把安装目录 /opt/dmdbms/bin 下的所有 .so 文件都拷贝到 docker 中

for i in  `ls /opt/dmdbms/bin/*.so`; do echo $i ;docker cp $i bed496495fee:/opt/dmdbms/bin/; done



=>[IM004][unixODBC][Driver Manager]Driver's SQLAllocHandle on SQL_HANDLE_HENV failed

odbcinst.ini 中配置的 Driver libdodbc.so 必须得是达梦的,不能是UnixODBC自己生成的


=> cannot find -lodbc

报错详情:

root@Kylin:/Users/liutongtong/go/src/dameng-test/main# go run beego-orm.go
# github.com/alexbrainman/odbc/api
/usr/lib/gcc-cross/arm-linux-gnueabi/8/../../../../arm-linux-gnueabi/bin/ld: cannot find -lodbc
/usr/lib/gcc-cross/arm-linux-gnueabi/8/../../../../arm-linux-gnueabi/bin/ld: cannot find -lodbc

使用 ld 命令查看:

root@Kylin:/Users/liutongtong/go/src/dameng-test/main# ld /usr/local/lib/libodbc.so
ld: warning: cannot find entry symbol _start; not setting start address
ld: /usr/local/lib/libodbc.so: undefined reference to `dlopen'
ld: /usr/local/lib/libodbc.so: undefined reference to `dlclose'
ld: /usr/local/lib/libodbc.so: undefined reference to `dlerror'
ld: /usr/local/lib/libodbc.so: undefined reference to `dlsym'

按照网上搜索来的方法进行尝试:

重新编译:
./configure LIBS=-ldl CFLAGS=-fno-strict-aliasing --build=arm

configure的时候提示:
checking for shl_load... (cached) no
checking for shl_load in -ldld... (cached) no
checking for dld_link in -ldld... no
checking for _ prefix in compiled symbols... no

尝试:
root@Kylin:/usr/local/lib# ar -x libodbcinst.a
root@Kylin:/usr/local/lib# gcc -shared *.o -o libodbcinst.so  -ldl

之后 ld 报错:
root@Kylin:/Users/liutongtong/go/src/dameng-test/main# ld /usr/local/lib/libodbc.so
ld: warning: cannot find entry symbol _start; not setting start address

总之是越做越错,越尝试越绝望。

这个问题后来通过重新拉镜像解决了。原来是我在疯狂的改环境的时候,无意间造成了破坏。

幸好是在 Docker 里,没有对他人造成影响。

这个故事告诉我们:一团乱麻的时候,不妨重新来过

本文章为麒麟&达梦适配系列第二篇。

上一篇:麒麟服务器上安装 DM8
下一篇:beego-ORM 适配达梦

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,258评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,335评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,225评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,126评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,140评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,098评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,018评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,857评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,298评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,518评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,400评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,993评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,638评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,661评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容