基于ODBC
ODBC
C++ 中可以通过 OTL 模板库来访问不同的数据库,我们推荐使用 OTL+ODBC 的方式访问 AntDB。
OTL 的文档:http://otl.sourceforge.net/otl3.htm
安装和配置 ODBC
安装
安装 ODBC 开发包(下述操作均在 antdb 用户下执行):
sudo yum -y install unixODBC
sudo yum -y install unixODBC-devel
AntDB 的 tar 包安装完成后,数据库程序目录(二进制目录)下应该有以下文件:
[antdb@bogon lib]$ cd /home/antdb/antdb/client_driver/adbodbc/lib
[antdb@bogon lib]$ ll
总用量 4424
-rwxr-xr-x 1 antdb antdb 1359 1月 17 10:34 adbodbca.la
lrwxrwxrwx 1 antdb antdb 14 1月 17 10:34 adbodbca.so -> ./psqlodbca.so
-rwxr-xr-x 1 antdb antdb 1359 1月 17 10:34 adbodbcw.la
lrwxrwxrwx 1 antdb antdb 14 1月 17 10:34 adbodbcw.so -> ./psqlodbcw.so
-rwxr-xr-x 1 antdb antdb 1365 1月 17 10:34 psqlodbca.la
-rwxr-xr-x 1 antdb antdb 2161480 1月 17 10:34 psqlodbca.so
-rwxr-xr-x 1 antdb antdb 1365 1月 17 10:34 psqlodbcw.la
-rwxr-xr-x 1 antdb antdb 2348896 1月 17 10:34 psqlodbcw.so
添加动态库环境变量
sudo vim /etc/profile
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/antdb/antdb/client_driver/adbodbc/lib
# 让配置生效:
source /etc/profile
创建软连接:
sudo ln -s [ODBC安装路径]/lib/adbodbcw.so /usr/local/lib/adbodbcw.so
sudo ln -s [ODBC安装路径]/lib/adbodbcw.so /usr/lib/libadbodbcw.so
配置
查找配置文件的位置
安装完成后可用odbcinst -j
命令查看安装配置文件所在的位置,有两个比较常用的配置:
- ODBC驱动配置文件,默认在
/etc/odbc/odbcinst.ini
(不同系统,路径会有变化,请根据 odbcinst -j 实际运行结果来看) - 系统数据源配置文件,默认在
/etc/odbc/odbc.ini
[antdb@localhost lib]$ odbcinst -j
unixODBC 2.3.11
DRIVERS............: /etc/odbc/odbcinst.ini
SYSTEM DATA SOURCES: /etc/odbc/odbc.ini
FILE DATA SOURCES..: /etc/odbc/ODBCDataSources
USER DATA SOURCES..: /data/antdb/.odbc.ini
SQLULEN Size.......: 8
SQLLEN Size........: 8
SQLSETPOSIROW Size.: 8
根据上面显示的位置下分别修改文件 odbcinst.ini 和 odbc.ini 文件:
配置 ODBC 驱动
修改文件 odbcinst.ini
# 注意:odbcinst.ini 文件路径一定要与 odbcinst -j 运行结果中 odbcinst.ini 路径保持一致
# 如果系统没有/etc/odbc文件夹,请自行创建
[antdb@pg ~]$ sudo vi /etc/odbc/odbcinst.ini
[PostgreSQL]
Description = ODBC for PostgreSQL
Driver = /usr/lib64/psqlodbc.so
#Driver = /usr/lib/psqlodbcw.so
#Setup = /usr/lib/libodbcpsqlS.so
#Driver64 = /usr/lib64/psqlodbcw.so
#Setup64 = /usr/lib64/libodbcpsqlS.so
FileUsage = 1
[ODBC]
Trace = off
TraceFile =
[AntDB Unicode]
Description = AntDB ODBC driver (Unicode version), for regression tests
Driver = [ODBC安装路径]/lib/adbodbcw.so
Debug = 0
CommLog = 0
[AntDB ANSI]
Description = AntDB ODBC driver (ANSI version), for regression tests
Driver = [ODBC安装路径]/lib/adbodbca.so
Debug = 0
CommLog = 0
配置 AntDB 数据源(DSN)
原生的 ODBC 使用 AntDB 客户端就可以利用 libpq 接口进行故障转移。也就是配置客户端连接,数据库的主节点或者备节点出现故障后,也可以保障业务的连续性,但最多只能处理两个实例,无法对配置的多个连接实例进行检验,且不支持负载均衡,导致单个服务器处理压力过大。
考虑以上情况,AntDB 实现了如下改进:在 ODBC 与数据库创建连接的过程中,配置多组连接实例,保证在其中一个实例连接故障后能尝试与另一个实例建立连接,实现故障转移;同时对连接的实例读写类型进行判断,将读和写操作分开,读操作可以从从库获取数据,减少主库的压力,提高系统的并发处理能力,实现负载均衡,将数据访问请求分散到多个数据库服务器上,减轻单个服务器的处理压力。
区别于原生 ODBC,AntDB 对于 ODBC 进行了优化,新增参数 LoadBalance 和 TargetServerType 支持连接节点类型选择和负载均衡。参数配置需要修改 odbc.ini 文件。
具体配置如下:
# 注意,odbc.ini 文件路径一定要与 odbcinst -j 运行结果中 odbc.ini 路径保持一致
# 如果系统没有/etc/odbc文件夹,请自行创建
[antdb@pg ~]$ sudo vi /etc/odbc/odbc.ini
[antdb]
Description = Test to antdb
Driver = AntDB Unicode
Database = antdb
Servername = 10.21.10.241,10.21.10.242
UserName = antdb
Password = XXXXXX
Port = 6655,6656
LoadBalance = false
TargetServerType = primary
参数说明:
参数 | 描述 | 示例 |
---|---|---|
Description | 数据源描述 | Description=psqlodbc regression test DSN |
Driver | 驱动名,对应odbcinst.ini文件的驱动器名称 | Driver =AntDB Unicode |
Database | 数据库名称 | Database=antdb |
Servername | 指定要连接的IP地址,可以设置多个,用逗号分隔 | Servername=127.0.0.1,127.0.0.1 |
Username | 数据库用户名 | Username= antdb |
Password | 数据库密码 | Password= XXXXXX |
Port | 指定要连接的端口号,可以设置多个,用逗号分隔,且必须与Servername中的IP一一对应 | Port= 7631,7633 |
TargetServerType | 指定连接服务器主从类型,取值范围: any:连接任意连接实例 primary:连接读写实例由主库提供读写服务 secondary:指定连接只读端口,从库提供读取数据 preferprimary:优先连接读写实例 prefersecondary:优先连接只读实例 | TargetServerType=primary |
LoadBalance | 指定是否开启负载均衡,取值范围: true :开启负载均衡 false:关闭负载均衡 | LoadBalance=true |
新增参数 LoadBalance 和 TargetServerType 组合使用,产生的连接场景如下表所示:
LoadBalance | TargetServerType | 连接结果 |
---|---|---|
true | primary | 从 Servername 中随机选择一个节点 1、如果连接故障,则重新选择; 2、如果连接成功,如果该节点是主节点,则返回该连接; 3、如果该节点是备节点,则重新从剩余节点中随机选择一个节点连接,直到连接到可用的主节点为止; 4、如果所有主节点都连接故障,则返回错误; |
secondary | 从 Servername 中随机选择一个节点 1、如果连接故障,则重新选择; 2、如果连接成功,如果该节点是备节点,则返回该连接; 3、如果该节点是主节点,则重新从剩余节点中随机选择一个节点连接,直到连接到可用备节点为止 4、如果所有备节点都连接故障,则返回错误; | |
preferprimary | 从 Servername 中随机选择一个节点 1、如果连接故障,则重新选择; 2、如果连接成功,如果该节点是主节点,则返回该连接; 3、如果该节点是备节点,则重新从剩余节点中随机选择一个节点连接,直到连接到可用主节点为止 4、如果所有主节点都连接故障,则选择最后一次连接成功的备节点,返回该连接; 5、如果所有主/备节点都连接故障,则返回错误; | |
prefersecondary | 从 Servername 中随机选择一个节点 1、如果连接故障,则重新选择; 2、如果连接成功,如果该节点是备节点,则返回该连接; 3、如果该节点是主节点,则重新从剩余节点中随机选择一个节点连接,直到连接到可用备节点为止 4、如果所有备节点都连接故障,则选择最后一次连接成功的主节点,返回该连接; 5、如果所有主/备节点都连接故障,则返回错误; | |
any | 从 Servername 中随机选择一个节点 1、如果连接故障,则重新选择; 2、如果连接成功,则返回该连接; 3、如果所有节点都连接故障,则返回错误; | |
false | primary | 在 Servername 中从左到右选择节点,按序连接 1、如果连接故障,则重新选择; 2、如果连接成功,如果该节点是主节点,则返回该连接; 3、如果该节点是备节点,则重新按序连接下一个节点,直到连接到可用的主节点为止; 4、如果所有主节点都连接故障,则返回错误; |
secondary | 在 Servername 中从左到右选择节点,按序连接 1、如果连接故障,则重新选择; 2、如果连接成功,如果该节点是备节点,则返回该连接; 3、如果该节点是主节点,则重新按序连接下一个节点,直到连接到可用备节点为止 4、如果所有备节点都连接故障,则返回错误; | |
preferprimary | 在 Servername 中从左到右选择节点,按序连接 1、如果连接故障,则重新选择; 2、如果连接成功,如果该节点是主节点,则返回该连接; 3、如果该节点是备节点,则重新按序连接下一个节点,直到连接到可用主节点为止 4、如果所有主节点都连接故障,则会选择最后一次连接成功的备节点,返回该连接; 5、如果所有节点都连接故障,则返回错误; | |
prefersecondary | 在 Servername 中从左到右选择节点,按序连接 1、如果连接故障,则重新选择; 2、如果连接成功,如果该节点是备节点,则返回该连接; 3、如果该节点是主节点,则重新按序连接下一个节点,直到连接到可用备节点为止 4、如果所有备节点都连接故障,则会选择最后一次连接成功的主节点,返回该连接; 5、如果所有节点都连接故障,则返回错误; | |
any | 在 Servername 中从左到右选择节点,按序连接 1、如果连接故障,则重新选择; 2、如果连接成功,则返回该连接; 3、如果所有节点都连接故障,则返回错误; |
连接测试
isql 命令格式:
isql DSN [user [password]] [options]
如果配置指定了用户名和密码,连接时指定DSN即可。
[antdb@localhost lib]$ isql antdb -v
+---------------------------------------+
| Connected! |
| |
| sql-statement |
| help [tablename] |
| echo [string] |
| quit |
| |
+---------------------------------------+
SQL> select count(*) from pg_class;
+---------------------+
| count |
+---------------------+
| 443 |
+---------------------+
SQLRowCount returns 1
1 rows fetched
SQL>
如果执行 isql 测试出现如下的错误:
[unixODBC][Driver Manager]Data source name not found, and no default driver specified
首先确认 ODBC 的环境变量,是否正确指向了自己的配置文件,确认方法:
[antdb@adb01 mgr1]$ odbcinst -j
unixODBC 2.3.1
DRIVERS............: /etc/odbc/odbcinst.ini # 确认路径是上面配置odbcinst.ini文件路径
SYSTEM DATA SOURCES: /etc/odbc/odbc.ini # 确认路径是上面配置odbc.ini文件路径
FILE DATA SOURCES..: /etc/odbc/ODBCDataSources
USER DATA SOURCES..: /home/antdb/.odbc.ini
SQLULEN Size.......: 8
SQLLEN Size........: 8
SQLSETPOSIROW Size.: 8
再确认 /etc/odbc/odbc.ini 文件的访问权限,确认执行 isql 的用户有读权限。
故障转移
AntDB 实现了在 ODBC 与数据库创建连接的过程中,配置多组连接实例,保证在其中一个实例连接故障后能尝试与另一个实例建立连接,实现故障转移。
用户在配置文件或者连接字符串中配置多个 IP 地址(Servername)和端口(Port),且 Servername 和 Port 成对配置,一一对应。在创建连接时对服务器的故障情况进行检查排除。驱动程序将尝试按顺序连接服务器,直到连接成功, 如果没有成功,则会引发正常连接异常。
配置示例如下:
# 如下配置文件中,Servername 和 Port 配置了多个连接实例
# 在 LoadBalance 设置为 false 的情况下,会从左到右按序选择服务器建立连接
# 例如下面配置中,Servername 和 Port 配置了三对,先连接 Servername=10.21.10.241 Port=6655
# 如果服务器连接故障或连接服务器与指定类型不符,则按序再连接 Servername=10.21.10.242 Port=6656
[antdb@pg ~]$ sudo vi /etc/odbc/odbc.ini
[antdb]
Description = Test to antdb
Driver = AntDB Unicode
Database = antdb
Servername = 10.21.10.241,10.21.10.242,10.21.10.243
UserName = antdb
Password = XXXXXX
Port = 6655,6656,6657
LoadBalance = false
TargetServerType = primary
# 在 LoadBalance 设置为 true 的情况下,会随机选择服务器建立连接
# 连接成功之后判断该节点类型,节点类型正确则返回该连接
# 如果服务器连接故障或连接服务器与指定类型不符,则重新选择服务器建立连接
[antdb@pg ~]$ sudo vi /etc/odbc/odbc.ini
[antdb]
Description = Test to antdb
Driver = AntDB Unicode
Database = antdb
Servername = 10.21.10.241,10.21.10.242,10.21.10.243
UserName = antdb
Password = XXXXXX
Port = 6655,6656,6657
LoadBalance = true
TargetServerType = primary
指定连接节点类型
在 odbc.ini 配置文件中,配置了多个实例的情况下,可以通过设置参数 TargetServerType 的取值,指定连接节点类型。
TargetServerType 可选值如下:
- any:连接任意连接实例
- primary:连接读写实例由主库提供读写服务
- secondary:指定连接只读端口,从库提供读取数据
- preferprimary:优先连接读写实例(在没有读写实例的情况下才会去连接只读实例)
- prefersecondary:优先连接只读实例(在没有只读实例的情况下才会去连接读写实例)
配置文件示例如下:
# 下述配置中,Servername 和 Port 配置了5对,其中前三个是主库,后两个是备库
[antdb@pg ~]$ sudo vi /etc/odbc/odbc.ini
[antdb]
Description = Test to antdb
Driver = AntDB Unicode
Database = antdb
Servername = 10.21.10.241,10.21.10.242,10.21.10.243,10.21.10.241,10.21.10.243
UserName = antdb
Password = XXXXXX
Port = 6651,6652,6653,6654,6655
LoadBalance = false #LoadBalance 为false,代表按序建连
TargetServerType = primary #如果连接成功,且该节点是主节点,则返回该连接;否则重新按序连接下一个节点
负载均衡
通过设置配置文件 odbc.ini 中 LoadBalance 参数来开启/关闭负载均衡功能。默认为 false 状态,开启后会通过打乱原有候选连接实例的连接顺序,随机连接任意一个指定的读写类型的合适实例。
假设 odbc.ini 配置文件如下所示,不同参数组合下,负载均衡情况如下所示:
[antdb]
Description = Test to antdb
Driver = AntDB Unicode
Database = antdb
Servername = 10.21.10.241,10.21.10.242,10.21.10.243
UserName = antdb
Password = XXXXXX
Port = 6655,6656,6657
LoadBalance = true
TargetServerType = primary
# 1. 假设 Servername 全是主机,且无故障,建立100个连接的情况下
# 根据 LoadBalance = true,随机选择一个服务器建联
# 服务器连接无故障且连接服务器与指定类型(primary)相符的情况下,建连成功并返回;重复该建联操作100次
# 最终三个主机的连接数均匀分布
LoadBalance = true
TargetServerType = primary
# 2. 假设 Servername 为一主二备,且其中一台主机故障,建立100个连接的情况下
# 根据 LoadBalance = true,随机选择一个服务器建联
# 服务器连接无故障的情况下,建连成功并返回;重复该建联操作100次
# 最终除却一台故障主机,另外一主一备两台机器的连接数均匀分布
LoadBalance = true
TargetServerType = any
# 3. 假设 Servername 为一主二备,且无故障,建立100个连接的情况下
# 根据 LoadBalance = true,随机选择一个服务器建联
# 服务器连接无故障且连接服务器与指定类型(secondary)相符的情况下,建连成功并返回;重复该建连操作100次
# 最终两个备节点的连接数均匀分布
LoadBalance = true
TargetServerType = secondary
# 4. 假设 Servername 为二主一备,且无故障,建立100个连接的情况下
# 根据 LoadBalance = true,随机选择一个服务器建联
# 服务器连接无故障且连接服务器与指定类型(primary无故障的情况下优先primary)相符的情况下,建连成功并返回
# 重复该建联操作100次;最终两个主节点的连接数均匀分布
LoadBalance = true
TargetServerType = preferprimary
# 5. 假设 Servername 为一主二备,且主机故障,建立100个连接的情况下
# 根据 LoadBalance = true,随机选择一个服务器建联
# 在所有 primary 有故障的情况下连接类型判断切换为 any
# 建连成功并返回;重复该建联操作100次
# 最终两个备节点的连接数均匀分布
LoadBalance = true
TargetServerType = preferprimary
# 6. 假设 Servername 为一主二备,且无故障,建立100个连接的情况下
# 根据 LoadBalance = true,随机选择一个服务器建联
# 服务器连接无故障且连接服务器与指定类型(secondary无故障的情况下优先secondary)相符的情况下,建连成功并返回
# 重复该建联操作100次;最终两个备节点的连接数均匀分布
LoadBalance = true
TargetServerType = prefersecondary
# 7. 假设 Servername 为二主一备,且备节点故障,建立100个连接的情况下
# 根据 LoadBalance = true,随机选择一个服务器建联
# 在所有 secondary 有故障的情况下连接类型判断切换为 any
# 最终两个主节点的连接数均匀分布
LoadBalance = true
TargetServerType = prefersecondary