华为云用户手册

  • SQLGetData 功能描述 SQLGetData返回结果集中某一列的数据。可以多次调用它来部分地检索不定长度的数据。 原型 1 2 3 4 5 6 SQLRETURN SQLGetData(SQLHSTMT StatementHandle, SQLUSMALLINT Col_or_Param_Num, SQLSMALLINT TargetType, SQLPOINTER TargetValuePtr, SQLLEN BufferLength, SQLLEN *StrLen_or_IndPtr); 参数 表12 SQLGetData参数 关键字 参数说明 StatementHandle 语句句柄,通过SQLAllocHandle获得。 Col_or_Param_Num 要返回数据的列号。结果集的列按增序从1开始编号。书签列的列号为0。 TargetType TargetValuePtr缓冲中的C数据类型的类型标识符。若TargetType为SQL_ARD_TYPE,驱动使用ARD中SQL_DESC_CONCISE_TYPE字段的类型标识符。若为SQL_C_DEFAULT,驱动根据源的SQL数据类型选择缺省的数据类型。 TargetValuePtr 输出参数:指向返回数据所在缓冲区的指针。 BufferLength TargetValuePtr所指向缓冲区的长度。 StrLen_or_IndPtr 输出参数:指向缓冲区的指针,在此缓冲区中返回长度或标识符的值。 SQL_SUC CES S:表示调用正确。 SQL_SUCCESS_WITH_INFO:表示会有一些警告信息。 SQL_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。 SQL_NO_DATA:表示SQL语句不返回结果集。 SQL_INVALID_HANDLE:表示调用无效句柄。其他API的返回值同理。 SQL_STILL_EXECUTING:表示语句正在执行。 注意事项 当调用SQLFetch函数返回SQL_ERROR或SQL_SUCCESS_WITH_INFO时,通过调用SQLGetDiagRec函数,并将HandleType和Handle参数分别设置为SQL_HANDLE_STMT和StatementHandle,可得到一个相关的SQLSTATE值,通过SQLSTATE值可以查出调用此函数的具体信息。 示例 参见:示例
  • SQLExecDirect 功能描述 使用参数的当前值,执行一条准备好的语句。对于一次只执行一条SQL语句,SQLExecDirect是最快的执行方式。 原型 1 2 3 SQLRETURN SQLExecDirect(SQLHSTMT StatementHandle, SQLCHAR *StatementText, SQLINTEGER TextLength); 参数 表7 SQLExecDirect参数 关键字 参数说明 StatementHandle 语句句柄,通过SQLAllocHandle获得。 StatementText 要执行的SQL语句。不支持一次执行多条语句。 TextLength StatementText的长度。 返回值 SQL_SUCCESS:表示调用正确。 SQL_SUCCESS_WITH_INFO:表示会有一些警告信息。 SQL_NEED_DATA:在执行SQL语句前没有提供足够的参数。 SQL_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。 SQL_INVALID_HANDLE:表示调用无效句柄。其他API的返回值同理。 SQL_STILL_EXECUTING:表示语句正在执行。 SQL_NO_DATA:表示SQL语句不返回结果集。 注意事项 当调用SQLExecDirect函数返回SQL_ERROR或SQL_SUCCESS_WITH_INFO时,通过调用SQLGetDiagRec函数,并将HandleType和Handle参数设置为SQL_HANDLE_STMT和StatementHandle,可得到一个相关的SQLSTATE值,通过SQLSTATE值可以查出调用此函数的具体信息。 示例 参见:示例
  • SQLExecute 功能描述 如果语句中存在参数标记的话,SQLExecute函数使用参数标记参数的当前值,执行一条准备好的SQL语句。 原型 1 SQLRETURN SQLExecute(SQLHSTMT StatementHandle); 参数 表8 SQLExecute参数 关键字 参数说明 StatementHandle 要执行语句的语句句柄。 返回值 SQL_SUCCESS:表示调用正确。 SQL_SUCCESS_WITH_INFO:表示会有一些警告信息。 SQL_NEED_DATA:表示在执行SQL语句前没有提供足够的参数。 SQL_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。 SQL_NO_DATA:表示SQL语句不返回结果集。 SQL_INVALID_HANDLE:表示调用无效句柄。其他API的返回值同理。 SQL_STILL_EXECUTING:表示语句正在执行。 注意事项 当SQLExecute函数返回SQL_ERROR或SQL_SUCCESS_WITH_INFO时,可通过调用SQLGetDiagRec函数,并将HandleType和Handle参数设置为SQL_HANDLE_STMT和StatementHandle,可得到一个相关的SQLSTATE值,通过SQLSTATE值可以查出调用此函数的具体信息。 示例 参见:示例
  • SQLAllocHandle 功能描述 分配环境、连接、语句或描述符的句柄,它替代了ODBC 2.x函数SQLAllocEnv、SQLAllocConnect及SQLAllocStmt。 原型 1 2 3 SQLRETURN SQLAllocHandle(SQLSMALLINT HandleType, SQLHANDLE InputHandle, SQLHANDLE *OutputHandlePtr); 参数 表1 SQLAllocHandle参数 关键字 参数说明 HandleType 由SQLAllocHandle分配的句柄类型。必须为下列值之一: SQL_HANDLE_ENV(环境句柄) SQL_HANDLE_DBC(连接句柄) SQL_HANDLE_STMT(语句句柄) SQL_HANDLE_DESC(描述句柄) 申请句柄顺序为,先申请环境句柄,再申请连接句柄,最后申请语句句柄,后申请的句柄都要依赖它前面申请的句柄。 InputHandle 将要分配的新句柄的类型。 如果HandleType为SQL_HANDLE_ENV,则这个值为SQL_NULL_HANDLE。 如果HandleType为SQL_HANDLE_DBC,则这一定是一个环境句柄。 如果HandleType为SQL_HANDLE_STMT或SQL_HANDLE_DESC,则它一定是一个连接句柄。 OutputHandlePtr 输出参数:一个缓冲区的指针,此缓冲区以新分配的数据结构存放返回的句柄。 返回值 SQL_SUCCESS:表示调用正确。 SQL_SUCCESS_WITH_INFO:表示会有一些警告信息。 SQL_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。 SQL_INVALID_HANDLE:表示调用无效句柄。其他API的返回值同理。 注意事项 当分配的句柄并非环境句柄时,如果SQLAllocHandle返回的值为SQL_ERROR,则它会将OutputHandlePtr的值设置为SQL_NULL_HDBC、SQL_NULL_HSTMT或SQL_NULL_HDESC。之后,通过调用带有适当参数的SQLGetDiagRec,其中HandleType和Handle被设置为IntputHandle的值,可得到相关的SQLSTATE值,通过SQLSTATE值可以查出调用此函数的具体信息。 示例 参见:示例
  • 常见问题处理 Server common name "xxxx" does not match host name "xxxxx" 此问题的原因是使用了SSL加密的“verify-full”选项,这时驱动程序会验证证书中的主机名与实际部署数据库的主机名是否一致。碰到此问题可以使用“verify-ca”选项,不再校验主机名;或者重新生成一套与数据库所在主机名相同的CA证书。 connect to server failed: no such file or directory 此问题可能的原因: 配置了错误的/不可达的数据库地址,或者端口 请检查数据源配置中的Servername及Port配置项。 服务器监听不正确 如果确认Servername及Port配置正确,请根据“操作步骤”中数据库服务器的相关配置,确保数据库监听了合适的网卡及端口。 防火墙及网闸设备 请确认防火墙设置,将数据库的通信端口添加到可信端口中。 如果有网闸设备,请确认一下相关的设置。 在指定的DSN中,驱动程序和应用程序之间的体系结构不匹配 此问题可能的原因:在64位程序中使用了32位驱动,或者相反。 C:\Windows\SysWOW64\odbcad32.exe:这是32位ODBC驱动管理器。 C:\Windows\System32\odbcad32.exe:这是64位ODBC驱动管理器。 The password-stored method is not supported. 此问题可能原因: 数据源中未配置sslmode配置项,请调整此项至allow或以上级别,允许SSL连接,此选项的更多说明,请见表1。 authentication method 10 not supported. 使用开源客户端碰到此问题,可能原因: 数据库中存储的口令校验只存储了SHA256格式哈希,而开源客户端只识别MD5校验,双方校验方法不匹配报错。 数据库并不存储用户口令,只存储用户口令的哈希码。 早期版本(V100R002C80SPC300之前的版本)的数据库只存储了SHA256格式的哈希,并未存储MD5的哈希,所以无法使用MD5做用户口令校验。 新版本(V100R002C80SPC300及之后版本)的数据库当用户更新用户口令或者新建用户时,会同时存储两种格式的哈希码,这时将兼容开源的认证协议。 但是当老版本升级到新版本时,由于哈希的不可逆性,所以数据库无法还原用户口令,进而生成新格式的哈希,所以仍然只保留了SHA256格式的哈希,导致仍然无法使用MD5做口令认证。 要解决该问题,参见以下操作: 新建一个数据库用户用于连接,或者重置准备使用的数据库用户的密码。 如果您使用的是管理员账号,参见重置密码。 如果是普通用户,可以先通过其他客户端工具(例如Data Studio)连接数据库后,使用ALTER USER语句来修改密码。 再尝试连接数据库。 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. 或:GSSAPI authentication not supported. 目标CN的pg_hba.conf里配置了当前客户端IP使用“gss”方式来做认证,该认证算法不支持用作客户端的身份认证,请修改到“sha256”后再试。 同时请注意,数据库当前不支持在集群内跨节点连接数据库,如果是在集群内跨节点连接CN出现此问题,请将业务程序调整到集群外后重试。
  • 常见问题处理 [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中;如果是缺少其他库,请将ODBC驱动包中的lib目录添加到LD_LIBRARY_PATH中。或者将psqlodbcw.so的依赖库放到psqlodbcw.so的rpath对应的路径中,通过readelf -d可查看rpath。 [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”选项,不再校验主机名;或者重新生成一套与数据库所在主机名相同的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校验,双方校验方法不匹配报错。 数据库并不存储用户口令,只存储用户口令的哈希码。 早期版本(V100R002C80SPC300之前的版本)的数据库只存储了SHA256格式的哈希,并未存储MD5的哈希,所以无法使用MD5做用户口令校验。 新版本(V100R002C80SPC300及之后版本)的数据库当用户更新用户口令或者新建用户时,会同时存储两种格式的哈希码,这时将兼容开源的认证协议。 但是当老版本升级到新版本时,由于哈希的不可逆性,所以数据库无法还原用户口令,进而生成新格式的哈希,所以仍然只保留了SHA256格式的哈希,导致仍然无法使用MD5做口令认证。 要解决该问题,可以更新用户口令;或者新建一个用户,赋予同等权限,使用新用户连接数据库。 unsupported frontend protocol 3.51: server supports 1.0 to 3.0 目标数据库版本过低,或者目标数据库为开源数据库。请使用对应版本的数据库驱动连接目标数据库。
  • 操作步骤 获取unixODBC源码包。 获取参考地址:https://sourceforge.net/projects/unixodbc/files/unixODBC/2.3.0/unixODBC-2.3.0.tar.gz/download 目前不支持unixODBC-2.2.1版本。以unixODBC-2.3.0版本为例,在客户端执行如下命令安装unixODBC。安装时通过--prefix=[your_path]指定安装目录,生成数据源文件到 “[your_path]/etc”目录下,库文件生成在“[your_path]/lib”目录。 tar zxvf unixODBC-2.3.0.tar.gz cd unixODBC-2.3.0 #修改configure文件(如果不存在,那么请修改configure.ac),找到LIB_VERSION #将它的值修改为"1:0:0",这样将编译出*.so.1的动态库,与psqlodbcw.so的依赖关系相同。 vim configure ./configure --enable-gui=no --prefix=[your_path] #如果要在TaiShan服务器上编译,请追加一个configure参数: --build=aarch64-unknown-linux-gnu make make install 安装unixODBC。如果机器上已经安装了其他版本的unixODBC,可以直接覆盖安装。 替换客户端GaussDB(DWS)驱动程序。 将dws_8.x.x_odbc_driver_for_xxx_xxx.zip解压,在“/dws_8.x.x_odbc_driver_for_xxx_xxx/odbc/lib”目录下得到“psqlodbcw.la”和“psqlodbcw.so”两个文件。 配置数据源。 配置ODBC驱动文件。 在“[your_path]/etc/odbcinst.ini”文件中追加以下内容。 [GaussMPP] Driver64=[your_path]/lib/odbc/psqlodbcw.so setup=[your_path]/lib/odbc/psqlodbcw.so odbcinst.ini文件中的配置参数说明如表1所示。 表1 odbcinst.ini文件配置参数 参数 描述 示例 [DriverName] 驱动器名称,对应数据源DSN中的驱动名。 [DRIVER_N] Driver64 驱动动态库的路径。 Driver64=/xxx/odbc/lib/odbc/psqlodbcw.so setup 驱动安装路径,与Driver64中动态库的路径一致。 setup=/xxx/odbc/lib/odbc/psqlodbcw.so 配置数据源文件。 在“[your_path]/etc/odbc.ini ”文件中追加以下内容。 [MPPODBC] Driver=GaussMPP Servername=10.10.0.13(数据库Server IP) Database=gaussdb (数据库名) Username=dbadmin (数据库用户名) Password= (数据库用户密码) Port=8000 (数据库监听端口) Sslmode=allow odbc.ini文件配置参数说明如表2所示。 表2 odbc.ini文件配置参数 参数 描述 示例 [DSN] 数据源的名称。 [MPPODBC] Driver 驱动名,对应odbcinst.ini中的DriverName。 Driver=DRIVER_N Servername 服务器的IP地址。 Servername=10.145.130.26 Database 要连接的数据库的名称。 Database=gaussdb Username 数据库用户名称。 Username=dbadmin Password 数据库用户密码。 Password= 说明: ODBC驱动本身已经对内存密码进行过清理,以保证用户密码在连接后不会再在内存中保留。 但是如果配置了此参数,由于UnixODBC对数据源文件等进行缓存,可能导致密码长期保留在内存中。 推荐在应用程序连接时,将密码传递给相应API,而非写在数据源配置文件中。同时连接成功后,应当及时清理保存密码的内存段。 Port 服务器的端口号。 Port=8000 Sslmode 开启SSL模式。 Sslmode=allow UseServerSidePrepare 是否开启数据库端扩展查询协议。 可选值0或1,默认为1,表示打开扩展查询协议。 UseServerSidePrepare=1 UseBatchProtocol 是否开启批量查询协议(打开可提高DML性能);可选值0或者1,默认为1。 当此值为0时,不使用批量查询协议(主要用于与早期数据库版本通信兼容)。 当此值为1,并且数据库support_batch_bind参数存在且为on时,将打开批量查询协议。 UseBatchProtocol=1 ConnectionExtraInfo GUC参数connection_info(参见connection_info)中显示驱动部署路径和进程属主用户的开关。 ConnectionExtraInfo=1 说明: 默认值为1。当设置为0时,ODBC驱动会将当前驱动的名称、驱动版本上报到数据库中;当设置为1时,ODBC驱动会将当前驱动的名称、部署路径、进程属主用户上报到数据库中,记录在connection_info参数(参见connection_info)里;同时可以在PG_STAT_ACTIVITY和PGXC_STAT_ACTIVITY中查询到。 ForExtensionConnector ETL工具性能优化参数,可进行内存优化,降低对端的CN内存占用,避免因CN内存使用过多导致系统不稳定。 可选值0或者1,默认为0,表示不开启优化项。 请勿在数据库系统之外的其他业务中配置此参数,以免影响业务的正确性。 ForExtensionConnector=1 KeepDisallowPremature 当UseDeclareFetch=1时,应用程序调用SQLPrepare后调用SQLNumResultCols、SQLDescribeCol或SQLColAttribute获取结果集列信息时,SQL语句中的游标是否具有with hold属性。 可选值0或者1,0表示具有with hold属性,1表示不具有with hold属性,默认为0。 KeepDisallowPremature=1 说明: UseServerSidePrepare=1时,KeepDisallowPremature参数不生效,使用时需要指定UseServerSidePrepare为0,例如:UseDeclareFetch=1 KeepDisallowPremature=1 UseServerSidePrepare=0 其中关于sslmode的选项的允许值,具体信息见下表: 表3 sslmode的可选项及其描述 sslmode 是否会启用SSL加密 描述 disable 否 不使用SSL安全连接。 allow 可能 如果数据库服务器要求使用,则可以使用SSL安全加密连接,但不验证数据库服务器的真实性。 prefer 可能 如果数据库支持,那么首选使用SSL安全加密连接,但不验证数据库服务器的真实性。 require 是 必须使用SSL安全连接,但是只做了 数据加密 ,而并不验证数据库服务器的真实性。 verify-ca 是 必须使用SSL安全连接,并且验证数据库是否具有可信证书机构签发的证书。 verify-full 是 必须使用SSL安全连接,在verify-ca的验证范围之外,同时验证数据库所在主机的主机名是否与证书内容一致。GaussDB(DWS)不支持此模式。 SSL模式 如果需要使用SSL证书连接,那么请将GaussDB(DWS)安装包中的SSLCERT的证书包解压,在shell环境下,执行“source sslcert_env.sh”,即在当前会话完成证书的默认位置的部署。 或者手动声明如下环境变量,同时保证client.key*系列文件为600权限: export PGSSLCERT="/YOUR/PATH/OF/client.crt" #请修改该路径到client.crt的绝对路径 export PGSSLKEY="/YOUR/PATH/OF/client.key" #请修改该路径到client.key的绝对路径 同时将数据源中的Sslmode选项调整至“verify-ca”。 将客户端所在主机的IP网段加入GaussDB(DWS)的安全组规则,确保客户端主机与GaussDB(DWS)网络互通。 配置环境变量。 vim ~/.bashrc 在配置文件中追加以下内容。 export LD_LIBRARY_PATH=[your_path]/lib/:$LD_LIBRARY_PATH export OD BCS YSINI=[your_path]/etc export ODBCINI=[your_path]/etc/odbc.ini 麒麟OS环境中,此处不建议追加LD_LIBRARY_PATH,可能造成libssl.so动态库冲突。集群9.1.0最新版本中已增加rpath,不需要LD_LIBRARY_PATH即可找到依赖。 执行如下命令使设置生效。 source ~/.bashrc
  • 建议3.4 禁止针对普通列存表进行实时INSERT操作 违反规范的影响: 针对普通列存表实时小批量入库会导致小CU膨胀严重,影响存储空间和查询性能。 方案建议: 实时INSERT场景评估单次入库数据量和数据总量,总量小的场景可以改为行存表。 实时INSERT场景前端攒批,保证单次、单表、单分区、单DN入库数据量接近6W,建议最低不少于5K。 实时INSERT场景使用Hstore列存表(8.3.0及以上版本)。
  • 规则3.2 DROP删除对象操作必须明确删除对象范围 违反规范的影响: DROP对象操作(如DATABASE、USER/ROLE、SCHEMA、TABLE、VIEW等对象)存在数据丢失风险,尤其含带CASCADE级联删除场景,会将关联的对象一并删除。 DROP DATABASE:整个DATABASE中所有对象被删除。 DROP USER:USER对象、USER所拥有的SCHEMA、TABLE等对象均被删除。 DROP SCHEMA:整个SCHEMA中的所有对象被删除。 DROP TABLE:TABLE对象,依赖TABLE的INDEX、VIEW等对象均被删除。 方案建议: DROP操作谨慎,操作前考虑数据备份。
  • 建议3.1 DDL操作(CREATE除外)避免在业务高峰期和长事务中执行 违反规范的影响: DDL操作普遍持锁级别高,如ALTER、DROP、TRUNCATE、REINDEX、VACUUM FULL等,执行时会造成业务等锁阻塞。 高峰期执行持锁级别高的DDL操作,造成业务等锁阻塞。 长事务中执行持锁级别高的DDL操作,长时间持锁或等锁,均造成业务等锁阻塞。 方案建议: 根据业务周期,选择低峰期或运维时间窗执行DDL操作,明确DDL执行环境和耗时,避免锁阻塞。
  • 规则2.14 只创建必要的索引,创建索引必须选择合适的列和顺序 违反规范的影响: 冗余索引浪费空间,索引多影响入库效率。 组合索引中列顺序错误,影响查询效率。 最佳实践: 索引的使用需兼顾以下条件: 索引列必须是常用于过滤条件或JOIN关联条件的列。 索引列必须是DISTINCT值多的列。 创建多列组合索引时,DISTINCT值多的列往前放。 单表索引个数控制在5个以内,可通过组合索引控制索引的个数。 数据批量增删改场景,建议先删除索引,完成增删改后再加回索引,提升批量操作性能(实时访问会有影响)。
  • 规则2.9 创建表时必须选择正确的分布方式和分布列 违反规范的影响: 分布式和分布列选择错误,导致表数据存储倾斜,访问性能下降,严重情况会触发存储和计算资源过载。 方案建议: 创建表时通过DISTRIBUT BY显式指定分布方式和分布列,分布列选择原则如下表所示。 表1 分布列选择原则 分布方式 描述 适用场景 Hash 表数据按照分布列生成的hash值与DN实例的映射关系,将数据分布到各DN实例。 优点:每个DN仅包含部分数据,占用整体空间小。 缺点:数据分布的均匀程度强依赖分布列的选择;JOIN关联条件不包含各自分布列的场景存在节点间数据通信的消耗。 大表、事实表。 RoundRobin 表数据按照轮询的方式依次分布到各DN实例。 优点:每个DN仅包含部分数据,占用整体空间小;数据轮询均匀分布,不依赖分布列,不存在数据存储倾斜问题。 缺点:无法通过分布列条件消除和减少节点间通信,此类场景性能不如HASH。 大表、事实表,无合适分布列的表。 Replication 表中的全量数据在集群的每一个DN实例上保留一份。 优点:每个DN上都有此表的全量数据,JOIN操作中可以完全避免节点间数据通信,从而减小网络开销,同时减少了STREAM线程启停开销。 缺点:每个DN都保留了表的完整数据,数据的冗余,占用更多存储空间。 小表、维度表。
  • 规则2.10 创建表时必须选择正确的存储方式 违反规范的影响: 行存表使用不当导致查询场景性能差,资源过载。 列存表使用不当导致CU膨胀,性能差,资源过载。 方案建议: 创建表时通过orientation显式指定表的存储类型,存储类型的选择原则如下表所示。 表2 存储类型选择 存储方式 适用场景 不适用的场景 行存 DML增删改:UPDATE和DELETE操作多的场景 DML查询:点查询(返回记录少,基于索引的简单查询) DML查询:统计分析类查询 (group , join的数据量大的场景)。 注意: 创建行存表(orientation = row)时,禁止指定compress属性,禁止使用行存压缩表。 列存 DML增删改:INSERT批量导入场景(单次单分区入库量接近或大于6w*DN数) DML查询:统计分析类查询 (group , join的数据量大的场景) DML增删改:UPDATE/DELETE多的场景、INSERT小批量插入的场景。 DML查询:高并发的点查询。
  • 建议2.12 表字段的设计要遵循高效、准确原则 违反规范的影响: 存储空间大、查询效率降低。 方案建议: 选择最高效的类型。 如能整型就不用浮点型,能用整型就不用字符型。 使用变长字符类型时根据数据特征指定最大长度。 选择最准确的类型。 使用时间类型存储时间,不使用字符类型存储时间。 使用满足需求的最小数值类型,如果int或smallint够用,就不用bigint而浪费空间。 正确使用约束。 明确不存在NULL值的字段加上NOT NULL约束,优化器会在特定场景下对其进行自动优化。 业务层面能补全的字段,不要使用DEFAULT约束,避免数据加载时产生不符合预期的结果。 避免非必要类型转换。 当多个表存在逻辑关系时,表示同一含义的字段应该使用相同的数据类型。 不同类型的比较操作会导致数据类型转换,可能导致索引和分区剪枝失效,影响查询性能。
  • 规则2.11 创建表时必须选择正确的分区策略 违反规范的影响: 分区的优点如下,如不做分区,其查询性能和 数据治理 效率会下降,数据量越大这种劣化越大。 改善查询性能:对分区对象的查询可以仅搜索自己关心的分区,提高检索效率。 提升数据治理效率:如数据生命周期管理场景,针对历史分区做TRUNCATE/DROP PARTITION,效率和效果远优于DELETE。 方案建议: 针对包含时间类型字段的表设计分区。 表3 分区策略选择 分区策略 描述 适用场景 范围分区(Range Partitioning) 根据分区键值的范围,将数据存储到不同的分区中,分区键范围连续但不重叠。 日期或者时间类的字段作为分区键。 查询中大多包含分区键作为过滤条件。 定期按照分区键清理数据。 列表分区(List Partitioning) 根据分区键值的列表进行分区,各分区的列表值不重复 特定数量的枚举值作为分区键值。 查询中大多包含分区键作为过滤条件。
  • 规则2.3 创建DATABASE时必须选择正确的数据库兼容模式 违反规则的影响: 选错数据库兼容模式,会导致从其他厂商的数据库迁移到GaussDB(DWS)后出现行为不一致问题,且不支持直接修改数据库兼容模式,需重新建库重新导数 方案建议: 根据源库端数据库类型,在GaussDB(DWS)中建库时通过DBCOMPATIBILITY指定兼容模式,当前支持Teradata、Oracle和MySQL等多种兼容模式。
  • 建议4.1 避免使用复杂的存储过程,避免存储过程嵌套 违反规范的影响: 复杂和嵌套的存储过程维护成本高,故障定位难度大,恢复耗时长。 方案建议: 不使用存储过程或只使用一层存储过程,不嵌套。 开发存储过程设计对应的日志表,将关键步骤前后的信息记录到日志表中,操作步骤如下。 保存并查看日志操作步骤 创建日志表。 1 2 3 4 5 6 7 8 9 CREATE TABLE func_exec_log ( id varchar2(32) default lower(sys_guid()), pro_name varchar2(60), exec_times int, log_date date, deal_date date, log_mesage text ); 创建表和导入数据。 1 2 CREATE TABLE demo_table(data_id int, data_number int); INSERT INTO demo_table values(generate_series(1,1000),generate_series(1,1000)); 创建业务存储过程 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 CREATE OR REPLACE FUNCTION demo_table_process(out exe_info text) LANGUAGE plpgsql AS $$ declare v_count int; pro_result text; fun_name text; exec_times int; begin fun_name := 'demo_table_process'; select nvl(max(exec_times), '0') + 1 into exec_times from func_exec_log where pro_name = fun_name; --业务表插入数据 insert into demo_table values (dbms_random.value(1, 1000)::int,generate_series(1, dbms_random.value(10000, 20000)::int)); get diagnostics v_count = ROW_COUNT; exe_info = sysdate || '# step1:insert count:' || v_count || ' rows;'; --删除业务表指定数据 delete from demo_table where data_id = dbms_random.value(1, 1000)::int; get diagnostics v_count = ROW_COUNT; exe_info = exe_info || sysdate || '# step2:delete count:' || v_count || ' rows;'; --更新业务表数据 update demo_table set data_number = dbms_random.value(1, 100)::int where data_id = dbms_random.value(1, 1000)::int; exe_info = exe_info || sysdate || '# step3:update count:' || sql%rowcount || ' rows'; --在整个程序结束前记录日志,也可以在每个步骤结束后分别记录日志,也可以创建记录日志的函数供调用,灵活使用即可 insert into func_exec_log(pro_name, exec_times, log_date, deal_date, log_mesage) values (fun_name,exec_times,sysdate,split_part(regexp_split_to_table(exe_info, ';'), '#', 1),split_part(regexp_split_to_table(exe_info, ';'), '#', 2)); --EXCEPTION用于保证当insert/update/delete等操作步骤异常退出时,也能够正常记录日志 EXCEPTION WHEN OTHERS THEN pro_result := exe_info || sysdate || '# exception error message is: ' || sqlerrm; insert into func_exec_log(pro_name, exec_times, log_date, deal_date, log_mesage) values(fun_name,exec_times,sysdate,split_part(regexp_split_to_table(pro_result, ';'), '#', 1),split_part(regexp_split_to_table(pro_result, ';'), '#', 2)); END; $$; 调用存储过程(正常执行)。 1 SELECT demo_table_process(); 查看日志(确认业务运行情况)。 SELECT * FROM func_exec_log ORDER BY log_date desc,deal_date,log_mesage; 再次调用存储过程(构造执行异常)。 SELECT demo_table_process(); --先删除demo_table的data_number列构造异常,之后再调用 查看日志(确认业务运行情况)。
  • 规则1.5 应用侧使用连接池场景,如使用连接SET设置过参数,当将连接归还连接池前,必须进行参数重置 违反规则的影响: 连接被其他业务复用时,可能会应复用其他业务设置的参数出现业务性能、业务报错等问题。 方案建议: 在将连接归还连接池之前,使用“SET SESSION AUTHORIZATION DEFAULT;RESET ALL;”重置参数。 注意: 在应用侧使用连接池的场景,如果在DWS服务侧通过GS_GUC RELOAD设置了全局的GUC参数,需要重启应用侧连接池才能够享受该参数变化,因为该设置只针对新建的连接生效,针对连接池中已有的老连接不生效。
  • 规则1.3 开启的事务最后必须提交或回滚 违反规则的影响: 事务长时间不提交,持锁阻塞ALTER等操作,进而阻塞所有业务。 大量“idle in transaction”连接,触发连接上限,导致新建连接报错。 方案建议: 默认使用autocommit自动提交方式,如关闭autocommit,则必须手动提交。 显式start transaction开启的事务,执行完相关操作后,必须显式commit/rollback结束事务。
  • javax.sql.ConnectionPoolDataSource javax.sql.ConnectionPoolDataSource是数据源连接池接口。 表9 对javax.sql.ConnectionPoolDataSource的支持情况 方法名 返回值类型 支持JDBC 4 getLoginTimeout() int Yes getLogWriter() PrintWriter Yes getPooledConnection() PooledConnection Yes getPooledConnection(String user,String password) PooledConnection Yes setLoginTimeout(int seconds) void Yes setLogWriter(PrintWriter out) void Yes
  • javax.sql.DataSource javax.sql.DataSource是数据源接口。 表10 对javax.sql.DataSource接口的支持情况 方法名 返回值类型 支持JDBC 4 getConnection() Connection Yes getConnection(String username,String password) Connection Yes getLoginTimeout() int Yes getLogWriter() PrintWriter Yes setLoginTimeout(int seconds) void Yes setLogWriter(PrintWriter out) void Yes
  • CopyManager CopyManager是GaussDB(DWS) JDBC驱动中提供的一个API接口类,用于批量向GaussDB(DWS)集群中导入数据。 CopyManager的继承关系 CopyManager类位于org.postgresql.copy Package中,继承自java.lang.Object类,该类的声明如下: public class CopyManager extends Object 构造方法 public CopyManager(BaseConnection connection) throws SQLException 常用方法 表14 CopyManager常用方法 返回值 方法 描述 throws CopyIn copyIn(String sql) - SQLException long copyIn(String sql, InputStream from) 使用COPY FROM STDIN从InputStream中快速向数据库中的表加载数据。 SQLException,IOException long copyIn(String sql, InputStream from, int bufferSize) 使用COPY FROM STDIN从InputStream中快速向数据库中的表加载数据。 SQLException,IOException long copyIn(String sql, Reader from) 使用COPY FROM STDIN从Reader中快速向数据库中的表加载数据。 SQLException,IOException long copyIn(String sql, Reader from, int bufferSize) 使用COPY FROM STDIN从Reader中快速向数据库中的表加载数据。 SQLException,IOException CopyOut copyOut(String sql) - SQLException long copyOut(String sql, OutputStream to) 将一个COPY TO STDOUT的结果集从数据库发送到OutputStream类中。 SQLException,IOException long copyOut(String sql, Writer to) 将一个COPY TO STDOUT的结果集从数据库发送到Writer类中。 SQLException,IOException
  • java.sql.Statement java.sql.Statement是SQL语句接口。 表8 对java.sql.Statement的支持情况 方法名 返回值类型 支持JDBC 4 close() void Yes execute(String sql) boolean Yes executeQuery(String sql) ResultSet Yes executeUpdate(String sql) int Yes getConnection() Connection Yes getResultSet() ResultSet Yes getQueryTimeout() int Yes getUpdateCount() int Yes isClosed() boolean Yes setQueryTimeout(int seconds) void Yes setFetchSize(int rows) void Yes cancel() void Yes 通过setFetchSize可以减少结果集在客户端的内存占用情况。它的原理是通过将结果集打包成游标,然后分段处理,所以会加大数据库与客户端的通信量,会有性能损耗。 由于数据库游标是事务内有效,所以,在设置setFetchSize的同时,需要将连接设置为非自动提交模式,setAutoCommit(false)。同时在业务数据需要持久化到数据库中时,在连接上执行提交操作。
  • javax.sql.PooledConnection javax.sql.PooledConnection是由连接池创建的连接接口。 表11 对javax.sql.PooledConnection的支持情况 方法名 返回值类型 支持JDBC 4 addConnectionEventListener (ConnectionEventListener listener) void Yes close() void Yes getConnection() Connection Yes removeConnectionEventListener (ConnectionEventListener listener) void Yes addStatementEventListener (StatementEventListener listener) void Yes removeStatementEventListener (StatementEventListener listener) void Yes
  • javax.naming.Context javax.naming.Context是连接配置的上下文接口。 表12 对javax.naming.Context的支持情况 方法名 返回值类型 支持JDBC 4 bind(Name name, Object obj) void Yes bind(String name, Object obj) void Yes lookup(Name name) Object Yes lookup(String name) Object Yes rebind(Name name, Object obj) void Yes rebind(String name, Object obj) void Yes rename(Name oldName, Name newName) void Yes rename(String oldName, String newName) void Yes unbind(Name name) void Yes unbind(String name) void Yes
  • java.sql.ResultSet java.sql.ResultSet是执行结果集接口。 表6 对java.sql.ResultSet的支持情况 方法名 返回值类型 支持JDBC 4 findColumn(String columnLabel) int Yes getBigDecimal(int columnIndex) BigDecimal Yes getBigDecimal(String columnLabel) BigDecimal Yes getBoolean(int columnIndex) boolean Yes getBoolean(String columnLabel) boolean Yes getByte(int columnIndex) byte Yes getBytes(int columnIndex) byte[] Yes getByte(String columnLabel) byte Yes getBytes(String columnLabel) byte[] Yes getDate(int columnIndex) Date Yes getDate(String columnLabel) Date Yes getDouble(int columnIndex) double Yes getDouble(String columnLabel) double Yes getFloat(int columnIndex) float Yes getFloat(String columnLabel) float Yes getInt(int columnIndex) int Yes getInt(String columnLabel) int Yes getLong(int columnIndex) long Yes getLong(String columnLabel) long Yes getShort(int columnIndex) short Yes getShort(String columnLabel) short Yes getString(int columnIndex) String Yes getString(String columnLabel) String Yes getTime(int columnIndex) Time Yes getTime(String columnLabel) Time Yes getTimestamp(int columnIndex) Timestamp Yes getTimestamp(String columnLabel) Timestamp Yes isAfterLast() boolean Yes isBeforeFirst() boolean Yes isFirst() boolean Yes next() boolean Yes 一个Statement不能有多个处于“open”状态的ResultSet。 用于遍历结果集(ResultSet)的游标(Cursor)在被提交后不能保持“open”的状态。
  • java.sql.ResultSetMetaData java.sql.ResultSetMetaData是对ResultSet对象相关信息的具体描述。 表7 对java.sql.ResultSetMetaData的支持情况 方法名 返回值类型 支持JDBC 4 getColumnCount() int Yes getColumnName(int column) String Yes getColumnType(int column) int Yes getColumnTypeName(int column) String Yes
  • java.sql.PreparedStatement java.sql.PreparedStatement是预处理语句接口。 表5 对java.sql.PreparedStatement的支持情况 方法名 返回值类型 支持JDBC 4 clearParameters() void Yes execute() boolean Yes executeQuery() ResultSet Yes executeUpdate() int Yes getMetaData() ResultSetMetaData Yes setBoolean(int parameterIndex, boolean x) void Yes setBigDecimal(int parameterIndex, BigDecimal x) void Yes setByte(int parameterIndex, byte x) void Yes setBytes(int parameterIndex, byte[] x) void Yes setDate(int parameterIndex, Date x) void Yes setDouble(int parameterIndex, double x) void Yes setFloat(int parameterIndex, float x) void Yes setInt(int parameterIndex, int x) void Yes setLong(int parameterIndex, long x) void Yes setNString(int parameterIndex, String value) void Yes setShort(int parameterIndex, short x) void Yes setString(int parameterIndex, String x) void Yes addBatch() void Yes executeBatch() int[] Yes clearBatch() void Yes addBatch()、execute()必须在clearBatch()之后才能执行。 调用executeBatch()方法并不会清除batch。用户必须显式使用clearBatch()清除 。 在添加了一个batch的绑定变量后,用户若想重用这些值(再次添加一个batch),无需再次使用set*()方法 。 以下方法是从java.sql.Statement继承而来:close,execute,executeQuery,executeUpdate,getConnection,getResultSet,getUpdateCount,isClosed,setMaxRows, setFetchSize。
  • java.sql.Driver java.sql.Driver是数据库驱动接口。 表4 对java.sql.Driver的支持情况 方法名 返回值类型 支持JDBC 4 acceptsURL(String url) boolean Yes connect(String url, Properties info) Connection Yes jdbcCompliant() boolean Yes getMajorVersion() int Yes getMinorVersion() int Yes
  • java.sql.DatabaseMetaData java.sql.DatabaseMetaData是数据库对象定义接口。 表3 对java.sql.DatabaseMetaData的支持情况 方法名 返回值类型 支持JDBC 4 getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types) ResultSet Yes getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) ResultSet Yes getTableTypes() ResultSet Yes getUserName() String Yes isReadOnly() boolean Yes nullsAreSortedHigh() boolean Yes nullsAreSortedLow() boolean Yes nullsAreSortedAtStart() boolean Yes nullsAreSortedAtEnd() boolean Yes getDatabaseProductName() String Yes getDatabaseProductVersion() String Yes getDriverName() String Yes getDriverVersion() String Yes getDriverMajorVersion() int Yes getDriverMinorVersion() int Yes usesLocalFiles() boolean Yes usesLocalFilePerTable() boolean Yes supportsMixedCaseIdentifiers() boolean Yes storesUpperCaseIdentifiers() boolean Yes storesLowerCaseIdentifiers() boolean Yes supportsMixedCaseQuotedIdentifiers() boolean Yes storesUpperCaseQuotedIdentifiers() boolean Yes storesLowerCaseQuotedIdentifiers() boolean Yes storesMixedCaseQuotedIdentifiers() boolean Yes supportsAlterTableWithAddColumn() boolean Yes supportsAlterTableWithDropColumn() boolean Yes supportsColumnAliasing() boolean Yes nullPlusNonNullIsNull() boolean Yes supportsConvert() boolean Yes supportsConvert(int fromType, int toType) boolean Yes supportsTableCorrelationNames() boolean Yes supportsDifferentTableCorrelationNames() boolean Yes supportsExpressionsInOrderBy() boolean Yes supportsOrderByUnrelated() boolean Yes supportsGroupBy() boolean Yes supportsGroupByUnrelated() boolean Yes supportsGroupByBeyondSelect() boolean Yes supportsLikeEscapeClause() boolean Yes supportsMultipleResultSets() boolean Yes supportsMultipleTransactions() boolean Yes supportsNonNullableColumns() boolean Yes supportsMinimumSQLGrammar() boolean Yes supportsCoreSQLGrammar() boolean Yes supportsExtendedSQLGrammar() boolean Yes supportsANSI92EntryLevelSQL() boolean Yes supportsANSI92IntermediateSQL() boolean Yes supportsANSI92FullSQL() boolean Yes supportsIntegrityEnhancementFacility() boolean Yes supportsOuterJoins() boolean Yes supportsFullOuterJoins() boolean Yes supportsLimitedOuterJoins() boolean Yes isCatalogAtStart() boolean Yes supportsSchemasInDataManipulation() boolean Yes supportsSavepoints() boolean Yes supportsResultSetHoldability(int holdability) boolean Yes getResultSetHoldability() int Yes getDatabaseMajorVersion() int Yes getDatabaseMinorVersion() int Yes getJDBCMajorVersion() int Yes getJDBCMinorVersion() int Yes
共100000条