
# Linux下配置数据源
将GaussDB提供的ODBC DRIVER（psqlodbcw.so）配置到数据源中便可使用。配置数据源需要配置"odbc.ini"和"odbcinst.ini"两个文件（在编译安装unixODBC过程中生成且默认放在"/usr/local/etc"目录下），并在服务器端进行配置。
#### 操作步骤
1. 获取unixODBC源码包。 
   获取参考地址：<https://www.unixodbc.org/unixODBC-2.3.7.tar.gz>。
   下载后请先按照社区提供的完整性校验算法进行完整性校验。
   
   
2. 安装unixODBC。如果机器上已经安装了其他版本的unixODBC，可以直接覆盖安装。下载<https://www.unixodbc.org/unixODBC-2.3.7.tar.gz.md5>，查看MD5值，对比MD5值是否与源码包一致。
   
   以unixODBC-2.3.7版本为例，在客户端执行如下命令安装unixODBC。
   ```
   tar zxvf unixODBC-2.3.7.tar.gz
   cd unixODBC-2.3.7
   ./configure --enable-gui=no #如果要在ARM服务器上编译，请追加一个configure参数： --build=aarch64-unknown-linux-gnu 
   make
   #安装可能需要root权限
   make install
   ```
   ![](https://support.huaweicloud.com/distributed-devg-v2-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
   - 目前不支持unixODBC-2.2.1版本。
   
   - 默认安装到"/usr/local"目录下，生成数据源文件到 "/usr/local/etc"目录下，库文件生成在"/usr/local/lib"目录。
   
   - 通过编译带有--enable-fastvalidate=yes选项的unixODBC来获得更高性能。但此选项可能会导致向ODBC API传递无效句柄的应用程序发生故障，而不是返回SQL_INVALID_HANDLE错误。
    
   
   
3. 替换客户端GaussDB驱动程序。 
   将GaussDB-Kernel_VxxxRxxxCxx-xxxxx-64bit-Odbc.tar.gz解压。解压后会得到两个文件夹：lib与odbc，在odbc文件夹中还会有一个lib文件夹。将解压后得到的/lib文件夹与/odbc/lib文件夹中的所有动态库都拷贝到"/usr/local/lib"目录下。
   
   
4. 配置数据源。 
   1. 配置ODBC驱动文件。 在"/usr/local/etc/odbcinst.ini"文件中追加以下内容。
      ```
      [GaussMPP]
      Driver64=/usr/local/lib/psqlodbcw.so
      setup=/usr/local/lib/psqlodbcw.so
      ```
      odbcinst.ini文件中的配置参数说明如[表1]所示。
       表1odbcinst.ini文件配置参数 
      | **参数**         | **描述**                     | **示例**                               |
      |:---|:---|:---|
      | \[DriverName\] | 驱动器名称，对应数据源DSN中的驱动名。       | \[DRIVER_N\]                         |
      | Driver64       | 驱动动态库的路径。                  | Driver64=/usr/local/lib/psqlodbcw.so |
      | setup          | 驱动安装路径，与Driver64中动态库的路径一致。 | setup=/usr/local/lib/psqlodbcw.so    |
         
      
   
   2. 配置数据源文件。 在"/usr/local/etc/odbc.ini "文件中追加以下内容。
      ```
      [gaussdb]
      Driver=GaussMPP
      Servername=127.0.0.1（数据库Server IP）
      Database=postgres  （数据库名）
      Username=omm  （数据库用户名）
      Password=  （数据库用户密码）
      Port=8000 （数据库侦听端口）
      Sslmode=allow
      ```
      odbc.ini文件配置参数说明如[表2]所示。
       表2odbc.ini文件配置参数 
      | **参数**                | **描述**                                                                                                                                                                                                                                                                            | **示例**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
      |:---|:---|:---|
      | \[DSN\]               | 数据源的名称。                                                                                                                                                                                                                                                                           | \[gaussdb\]                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
      | Driver                | 驱动名，对应odbcinst.ini中的DriverName。                                                                                                                                                                                                                                                   | Driver=DRIVER_N                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
      | Servername            | 服务器的IP地址。可配置多个IP地址。                                                                                                                                                                                                                                                               | Servername=127.0.0.1                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
      | Database              | 要连接的数据库的名称。                                                                                                                                                                                                                                                                       | Database=postgres                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
      | Username              | 数据库用户名称。                                                                                                                                                                                                                                                                          | Username=omm                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
      | Password              | 数据库用户密码。                                                                                                                                                                                                                                                                          | Password= 说明： ODBC驱动本身已经对内存密码进行过清理，以保证用户密码在连接后不会再在内存中保留。 但是如果配置了此参数，由于UnixODBC对数据源文件等进行缓存，可能导致密码长期保留在内存中。 推荐在应用程序连接时，将密码传递给相应API，而非写在数据源配置文件中。同时连接成功后，应当及时清理保存密码的内存段。 注意： 配置文件中填写密码时，需要遵循http规则： 1. 字符应当采用URL编码规范，如"!"应写作"%21"，"%"应写作"%25"，因此应当注意特殊处理%。  2. "+"会被替换为空格" "。   |
      | Port                  | 服务器的端口号。当开启负载均衡时，可配置多个端口号，且需与配置的多IP一一对应。如果开启负载均衡配置多个IP时，仍只配置一个端口号，则默认所有IP共用同一个端口号，即为配置的端口号。                                                                                                                                                                                       | Port=8000                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
      | Sslmode               | 开启SSL模式                                                                                                                                                                                                                                                                           | Sslmode=allow                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
      | Debug                 | 设置为1时，将会打印psqlodbc驱动的mylog，日志生成目录为/tmp/。设置为0时则不会生成。                                                                                                                                                                                                                               | Debug=1                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
      | UseServerSidePrepare  | 是否开启数据库端扩展查询协议。 可选值0或1，默认为1，表示打开扩展查询协议。                                                                                                                                                              | UseServerSidePrepare=1                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
      | UseBatchProtocol      | 是否开启批量查询协议（打开可提高DML性能）；可选值0或者1，默认为1。 当此值为0时，不使用批量查询协议（主要用于与早期数据库版本通信兼容）。 当此值为1，并且数据库support_batch_bind参数存在且为on时，将打开批量查询协议。 | UseBatchProtocol=1                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
      | ForExtensionConnector | 这个开关控制着savepoint是否发送，savepoint相关问题可以注意这个开关，默认值为1。取值为0，发送savepoint，取值为1，不发送savepoint。                                                                                                                                                                                              | ForExtensionConnector=1                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
      | ConnectionExtraInfo   | GUC参数connection_info中显示驱动部署路径和进程属主用户的开关。                                                                                                                                                                                                                                          | ConnectionExtraInfo=1 说明： 默认值为0。当设置为1时，ODBC驱动会将当前驱动的部署路径、进程属主用户上报到数据库中，记录在connection_info参数里；同时可以在[PG_STAT_ACTIVITY](https://support.huaweicloud.com/distributed-devg-v2-gaussdb/gaussdb-12-0788.html#ZH-CN_TOPIC_0000002222774953)和[PGXC_STAT_ACTIVITY](https://support.huaweicloud.com/distributed-devg-v2-gaussdb/gaussdb-12-0837.html#ZH-CN_TOPIC_0000002222889429)中查询到。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
      | BoolsAsChar           | 设置为Yes，Bools值将会映射为SQL_CHAR。如不设置将会映射为SQL_BIT。默认值为Yes。                                                                                                                                                                                                                              | BoolsAsChar = Yes                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
      | RowVersioning         | 当尝试更新一行数据时，设置为Yes会允许应用检测数据有没有被其他用户进行修改。默认值为No。                                                                                                                                                                                                                                    | RowVersioning=Yes                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
      | ShowSystemTables      | 设置为Yes，驱动将默认系统表格视为普通SQL表格。默认值为No。                                                                                                                                                                                                                                                 | ShowSystemTables=Yes                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
      | AutoBalance           | ODBC控制负载均衡的开关，默认值为0，0为关闭，1为开启。即为除1以外均不生效。                                                                                                                                                                                                                                         | AutoBalance=1                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
      | RefreshCNListTime     | 开启负载均衡时可配置该参数，该值为刷新CN列表的时间，默认值为10，整数型，单位秒。                                                                                                                                                                                                                                        | RefreshCNListTime=5                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
      | Priority              | 开启负载均衡时可配置该参数，默认值为0，0为关闭，1为开启。即除1以外均不生效。当Priority开启时，应用程序发起的所有连接优先发送到配置文件中配置的CN上，当配置的CN全部不可用时，连接才会发送到剩余的CN上。                                                                                                                                                                      | Priority=1                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
      | UsingEip              | 开启负载均衡时可配置该参数，默认值为0，0为关闭，1为开启。即除1以外均不生效。 此值用于控制是否使用内网地址做负载均衡。当UsingEip开启时，表示使用内网地址做负载均衡；关闭表示使用数据IP做负载均衡。                                                                                             | UsingEip=1                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
      | TcpUserTimeout        | 在支持TCP_USER_TIMEOUT套接字选项的操作系统上，指定传输的数据在TCP连接被强制关闭之前可以保持未确认状态的最大时长。0值表示使用系统缺省。通过UNIX域套接字做的链接忽略这个参数。单位为毫秒，默认为0。                                                                                                                                                                     | TcpUserTimeout=5000                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
         
      其中关于Sslmode的选项的允许值，具体信息见下表：
       表3sslmode的可选项及其描述 
      | sslmode     | 是否会启用SSL加密 | 描述                                                                                                                                                                                                                                                                                                                          |
      |:---|:---|:---|
      | disable     | 否          | 不使用SSL安全连接。                                                                                                                                                                                                                                                                                                                 |
      | allow       | 可能         | 如果数据库服务器要求使用，则可以使用SSL安全加密连接，但不验证数据库服务器的真实性。                                                                                                                                                                                                                                                                                 |
      | prefer      | 可能         | 如果数据库支持，那么首选使用SSL安全加密连接，但不验证数据库服务器的真实性。                                                                                                                                                                                                                                                                                     |
      | require     | 是          | 必须使用SSL安全连接，但是只做了数据加密，而并不验证数据库服务器的真实性。                                                                                                                                                                                                                                                                                      |
      | verify-ca   | 是          | 必须使用SSL安全连接，并且验证数据库是否具有可信证书机构签发的证书。                                                                                                                                                                                                                                                                                         |
      | verify-full | 是          | 必须使用SSL安全连接，在verify-ca的验证范围之外，同时验证数据库所在主机的主机名是否与证书内容一致。如果不一致，需要使用root用户修改/etc/hosts文件，将连接的数据库节点的IP地址和主机名加入。 说明： 此模式不支持产品默认证书，生成证书请联系管理员处理。 |
         
      
   
   
   
   
5. SSL模式。具体操作请联系管理员处理。
6. 配置数据库服务器。具体操作请联系管理员处理。
7. 配置环境变量。 
   ```
   vim ~/.bashrc
   ```
   在配置文件中追加以下内容。
   ```
   export LD_LIBRARY_PATH=/usr/local/lib/:$LD_LIBRARY_PATH
   export ODBCSYSINI=/usr/local/etc
   export ODBCINI=/usr/local/etc/odbc.ini
   ```
   
   
8. 执行如下命令使设置生效。 
   ```
   source ~/.bashrc
   ```
   
   
 
#### 测试数据源配置
安装后/usr/bin下面会存放生成的二进制，可执行isql -v gaussdb(数据源名称)命令。
- 如果显示如下信息，表明配置正确，连接成功。
  ```
  +---------------------------------------+
  | Connected!                            |
  |                                       |
  | sql-statement                         |
  | help [tablename]                      |
  | quit                                  |
  |                                       |
  +---------------------------------------+
  ```
  
- 若显示ERROR信息，则表明配置错误。请检查上述配置是否正确。
- 若是集群环境，需要在所有机器上都拷贝配置一份unixODBC。
![](https://support.huaweicloud.com/distributed-devg-v2-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
目前通过ODBC连接数据库时，会如下设置内核参数：
```
SET extra_float_digits = 2;
SET DateStyle = 'ISO';
```
这些参数可能会导致ODBC客户端的行为与gsql客户端的行为不一致，例如，Date数据显示方式、浮点数精度表示。如果实际期望和这些配置不符，建议在ODBC应用代码中显式设定这些参数。
#### 常见问题处理
- \[UnixODBC\]\[Driver Manager\]Can't open lib 'xxx/xxx/psqlodbcw.so' : file not found. 此问题的可能原因：
  - odbcinst.ini文件中配置的路径不正确 确认的方法：使用ls命令查看错误信息中的路径，以确保该psqlodbcw.so文件存在，同时具有执行权限。
    
  
  - psqlodbcw.so的依赖库不存在，或者不在系统环境变量中 确认的办法：使用ldd查看错误信息中的路径，如果是缺少libodbc.so.1等UnixODBC的库，那么按照"操作步骤"中的方法重新配置UnixODBC，并确保它的安装路径下的lib目录添加到了LD_LIBRARY_PATH中；如果重装仍无法解决，可以手动将数据库安装包下的unixodbc/lib下的内容拷贝到UnixODBC的安装路径下的lib目录；如果是缺少其他库，请将ODBC驱动包中的lib目录添加到LD_LIBRARY_PATH中。如果缺少其他标准库，请自行安装。
    
   
- \[UnixODBC\]connect to server failed: no such file or directory 此问题可能的原因：
  - 配置了错误的/不可达的数据库地址，或者端口 请检查数据源配置中的Servername及Port配置项。
    
  
  - 服务器侦听不正确 如果确认Servername及Port配置正确，请根据"操作步骤"中数据库服务器的相关配置，确保数据库侦听了合适的网卡及端口。
    
  
  - 防火墙及网闸设备 请确认防火墙设置，将数据库的通信端口添加到可信端口中。
    如果有网闸设备，请确认相关的设置。
    
   
- \[unixODBC\]The password-stored method is not supported. 此问题可能原因：
  数据源中未配置sslmode配置项。
  解决办法：
  请配置该选项至allow或以上选项。此配置的更多信息，见[表3]。
  
- Server common name "xxxx" does not match host name "xxxxx" 此问题的原因：
  使用了SSL加密的"verify-full"选项，驱动程序会验证证书中的主机名与实际部署数据库的主机名是否一致。
  解决办法：
  碰到此问题可以使用"verify-ca"选项，不再校验主机名；或者重新生成一套与数据库所在主机名相同的服务端证书。
  
- Driver's SQLAllocHandle on SQL_HANDLE_DBC failed 此问题的可能原因：
  可执行文件（比如UnixODBC的isql，以下都以isql为例）与数据库驱动（psqlodbcw.so）依赖于不同的odbc的库版本：libodbc.so.1或者libodbc.so.2。此问题可以通过如下方式确认：
  ```
  ldd `which isql` | grep odbc
  ldd psqlodbcw.so | grep odbc
  ```
  这时，如果输出的libodbc.so最后的后缀数字不同或者指向不同的磁盘物理文件，那么基本就可以断定是此问题。isql与psqlodbcw.so都会要求加载libodbc.so，这时如果它们加载的是不同的物理文件，便会导致两套完全同名的函数列表，同时出现在同一个可见域里（UnixODBC的libodbc.so.\*的函数导出列表完全一致），产生冲突，无法加载数据库驱动。
  解决办法：
  确定一个要使用的UnixODBC，然后卸载另外一个（比如卸载库版本号为.so.2的UnixODBC），然后将剩下的.so.1的库，新建一个同名但是后缀为.so.2的软链接，便可解决此问题。
  
- FATAL: Forbid remote connection with trust method! 由于安全原因，数据库CN禁止集群内部其他节点无认证接入。
  如果要在集群内部访问CN，请将ODBC程序部署在CN所在机器，服务器地址使用"127.0.0.1"。建议业务系统单独部署在集群外部，否则可能会影响数据库运行性能。
  
- \[unixODBC\]\[Driver Manager\]Invalid attribute value 在使用SQL on other GaussDB功能时碰到此问题，有可能是unixODBC的版本并非推荐版本，建议通过"odbcinst --version"命令排查环境中的unixODBC版本。
  
- authentication method 10 not supported. 使用开源客户端碰到此问题，可能原因：
  数据库中存储的口令校验只存储了SHA256格式哈希，而开源客户端只识别MD5校验，双方校验方法不匹配报错。
  ![](https://support.huaweicloud.com/distributed-devg-v2-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
  - 数据库并不存储用户口令，只存储用户口令的哈希码。
  
  - 数据库当用户更新用户口令或者新建用户时，会同时存储两种格式的哈希码，这时将兼容开源的认证协议。
  
  - 但是当老版本升级到新版本时，由于哈希的不可逆性，所以数据库无法还原用户口令，进而生成新格式的哈希，所以仍然只保留了SHA256格式的哈希，导致仍然无法使用MD5做口令认证。
  
  - MD5加密算法安全性低，存在安全风险，建议使用更安全的加密算法。
   
  要解决该问题，可以更新用户口令（参见[ALTER USER](https://support.huaweicloud.com/distributed-devg-v2-gaussdb/gaussdb-12-0343.html#ZH-CN_TOPIC_0000002187528376)）；或者新建一个用户（参见[CREATE USER](https://support.huaweicloud.com/distributed-devg-v2-gaussdb/gaussdb-12-0384.html#ZH-CN_TOPIC_0000002222774445)），赋予同等权限，使用新用户连接数据库。
  
- unsupported frontend protocol 3.51: server supports 1.0 to 3.0 目标数据库版本过低，或者目标数据库为开源数据库。请使用对应版本的数据库驱动连接目标数据库。
  
- FATAL: GSS authentication method is not allowed because XXXX user password is not disabled. 目标CN的pg_hba.conf里配置了当前客户端IP使用"gss"方式来做认证，该认证算法不支持用作客户端的身份认证，请修改到"sha256"后再试。配置方法见[6]。
  
- isql：error while loading shared libraries:xxx 环境缺少该动态库，需要自行安装对应的库。
  
 
