云服务器内容精选

  • 约束和限制 尽量避免所有业务使用同一个数据库用户运行,按业务模块规划不同数据库用户。 不建议使用系统管理员用户跑业务,不同模块业务请通过多用户和权限进行访问控制。 不建议业务直连单CN,需配置负载均衡保证各CN连接均衡。 连接数据库完成所需操作后,要及时关闭数据库连接,避免空闲连接持续占位,消耗连接和公共资源。 使用数据库连接池的场景,在业务中通过SET语句进行数据库GUC参数设置后,归还连接池前必须通过RESET还原参数设置。 更多开发设计规范参见总体开发设计规范。
  • psycopg2连接集群不支持CN Retry特性的问题说明 GaussDB (DWS)支持在SQL语句执行出错时的自动重试功能(简称CN Retry)。CN Retry对于客户端和驱动发送的SQL语句在执行失败时可以自动识别错误类型,并进行重试,详情请参见SQL语句出错自动重试。但使用psycopg2默认连接方式创建的连接在语句执行失败时没有自动重试,会直接报错退出。如常见的主备切换场景下,未自动重试会报如下错误,但在自动重试期间完成主备切换,则会返回正确结果。 1 psycopg2.errors.ConnectionFailure: pooler: failed to create 1 connections, Error Message: remote node dn_6003_6004, detail: could not connect to server: Operation now in progress 报错原因: psycopg2在发送SQL语句前先发送了BEGIN语句开启事务。 CN Retry不支持事务块中的语句是特性约束。 解决方案: 在同步方式连接时,可以通过主动结束驱动开启的事务。 1234 cursor = conn.cursor()# 增加end语句主动结束驱动开启的事务cursor.execute("end; select * from test order by 1;") rows = cursor.fetchall() 使用异步连接方式主动开启事务,异步连接介绍具体请参见pyscopg官网:https://www.psycopg.org/docs/advanced.html?highlight=async。 1 2 3 4 5 6 7 8 910111213141516171819202122232425262728293031323334353637383940414243 #!/usr/bin/env python3# _*_ encoding=utf-8 _*_ import psycopg2import select # psycopg2官方提供的异步连接方式时的wait函数# 详见https://www.psycopg.org/docs/advanced.html?highlight=asyncdef wait(conn): while True: state = conn.poll() if state == psycopg2.extensions.POLL_OK: break elif state == psycopg2.extensions.POLL_WRITE: select.select([], [conn.fileno()], []) elif state == psycopg2.extensions.POLL_READ: select.select([conn.fileno()], [], []) else: raise psycopg2.OperationalError("poll() returned %s" % state) def psycopg2_cnretry_sync(): # 创建连接 conn = psycopg2.connect(host='10.154.70.231', port='8000', database='gaussdb', # 需要连接的database user='dbadmin', password='password', # 数据库用户密码 async=1) # 使用异步方式连接 wait(conn) # 执行查询 cursor = conn.cursor() cursor.execute("select * from test order by 1;") wait(conn) rows = cursor.fetchall() for row in rows: print(row[0], row[1]) # 关闭连接 conn.close() if __name__ == '__main__': psycopg2_cnretry_async()
  • 在Linux环境使用psycopg2第三方库连接集群 以root用户登录Linux环境。 执行以下命令创建python_dws.py文件。 vi python_dws.py 请复制粘贴以下内容放入python_dws.py文件中: 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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99100101102103104105106107108 #!/usr/bin/python# -*- coding: UTF-8 -*- from __future__ import print_function import psycopg2 def create_table(connection): print("Begin to create table") try: cursor = connection.cursor() cursor.execute("drop table if exists test;" "create table test(id int, name text);") connection.commit() except psycopg2.ProgrammingError as e: print(e) else: print("Table created successfully") cursor.close() def insert_data(connection): print("Begin to insert data") try: cursor = connection.cursor() cursor.execute("insert into test values(1,'number1');") cursor.execute("insert into test values(2,'number2');") cursor.execute("insert into test values(3,'number3');") connection.commit() except psycopg2.ProgrammingError as e: print(e) else: print("Insert data successfully") cursor.close() def update_data(connection): print("Begin to update data") try: cursor = connection.cursor() cursor.execute("update test set name = 'numberupdated' where id=1;") connection.commit() print("Total number of rows updated :", cursor.rowcount) cursor.execute("select * from test order by 1;") rows = cursor.fetchall() for row in rows: print("id = ", row[0]) print("name = ", row[1], "\n") except psycopg2.ProgrammingError as e: print(e) else: print("After Update, Operation done successfully") def delete_data(connection): print("Begin to delete data") try: cursor = connection.cursor() cursor.execute("delete from test where id=3;") connection.commit() print("Total number of rows deleted :", cursor.rowcount) cursor.execute("select * from test order by 1;") rows = cursor.fetchall() for row in rows: print("id = ", row[0]) print("name = ", row[1], "\n") except psycopg2.ProgrammingError as e: print(e) else: print("After Delete,Operation done successfully") def select_data(connection): print("Begin to select data") try: cursor = connection.cursor() cursor.execute("select * from test order by 1;") rows = cursor.fetchall() for row in rows: print("id = ", row[0]) print("name = ", row[1], "\n") except psycopg2.ProgrammingError as e: print(e) print("select failed") else: print("Operation done successfully") cursor.close() if __name__ == '__main__': try: conn = psycopg2.connect(host='10.154.70.231', port='8000', database='gaussdb', # 需要连接的database user='dbadmin', password='password') # 数据库用户密码 except psycopg2.DatabaseError as ex: print(ex) print("Connect database failed") else: print("Opened database successfully") create_table(conn) insert_data(conn) select_data(conn) update_data(conn) delete_data(conn) conn.close() 按照实际集群信息,修改python_dws.py文件中的集群公网访问地址、集群端口号、数据库名称、数据库用户名、数据库密码。 psycopg2接口不提供重试连接的能力,您需要在业务代码中实现重试处理。 12345 conn = psycopg2.connect(host='10.154.70.231', port='8000', database='gaussdb', # 需要连接的database user='dbadmin', password='password') # 数据库用户密码 执行以下命令,使用psycopg第三方库连接集群。 python python_dws.py
  • 版本说明 由于GaussDB(DWS)集群、Python、psycopg2的版本较多,下方表格仅列举出当前主流版本的支持情况。 表1 psycopg2版本 Python版本 GaussDB(DWS)集群版本 2.7.x 3.8.x 8.1.3及以上 3.9.x 8.1.3及以上 2.8.x 3.8.x 8.1.3及以上 3.9.x 8.1.3及以上 2.9.x 3.8.x 8.1.3及以上 3.9.x 8.1.3及以上
  • 连接集群前的准备 GaussDB(DWS)集群已绑定弹性IP。 已获取GaussDB(DWS)集群的数据库管理员用户名和密码。 请注意,由于MD5算法已经被证实存在碰撞可能,已严禁将之用于密码校验算法。当前GaussDB(DWS)采用默认安全设计,默认禁止MD5算法的密码校验,可能导致开源客户端无法正常连接的问题。建议先检查数据库参数password_encryption_type参数是否为1,如果取值不为1,需要修改,修改方法参见修改GaussDB(DWS)集群GUC参数;然后修改一次准备使用的数据库用户的密码。 当前GaussDB(DWS)出于安全考虑,已经默认不再使用MD5存储密码摘要了,这将导致使用开源驱动或者客户端无法正常连接数据库。需要您调整密码策略后再创建一个新用户或者对老用户做一次密码修改,方可使用开源协议中的MD5认证算法。 数据库中是不会存储用户的密码原文,而是存储密码的HASH摘要,在密码校验时与客户端发来的密码摘要进行比对(中间会有加盐操作)。故当您改变了密码算法策略时,数据库也是无法还原您的密码,再生成新的HASH算法的摘要值的。必须您手动修改一次密码或者创建一个新用户,这时新的密码将会采用您设置的HASH算法进行摘要存储,用于下次连接认证。 已获取GaussDB(DWS)集群的公网访问地址,含IP地址和端口。具体请参见获取GaussDB(DWS)集群连接地址。 已安装psycopg2第三方库。下载地址:https://pypi.org/project/psycopg2/,安装部署操作请参见:https://www.psycopg.org/install/。 CentOS、Redhat等操作系统中使用yum命令安装,命令为: 1 yum install python-psycopg2 psycopg2的使用依赖于PostgreSQL的libpq动态库(32位的psycopg2需要对应32位的libpq;64位的psycopg2对应64位的libpq),Linux中可以依赖yum命令解决。在Windows系统使用psycopg2需要先安装libpq,主要方式有两种: 安装PostgreSQL,并配置libpq、ssl、crypto动态库位置到环境变量PATH中。 安装psqlodbc,使用PostgreSQL ODBC驱动携带的libpq、ssl、crypto动态库。
  • 使用约束 由于psycopg2是基于PostgreSQL的客户端接口,它的功能GaussDB(DWS)并不能完全支持。具体支持情况请见下表2。 以下接口支持情况是基于Python 3.8.5及psycopg 2.9.1版本。 表2 DWS对psycopg2主要接口支持情况 类名 功能描述 函数/成员变量 支持 备注 connections basic cursor(name=None, cursor_factory=None, scrollable=None, withhold=False) Y - commit() Y - rollback() Y - close() Y - Two-phase commit support methods xid(format_id, gtrid, bqual) Y - tpc_begin(xid) Y - tpc_prepare() N 内核不支持显式prepare transaction。 tpc_commit([xid]) Y - tpc_rollback([xid]) Y - tpc_recover() Y - closed Y - cancel() Y - reset() N 不支持DISCARD ALL。 dsn Y - Transaction control methods and attributes. set_session(isolation_level=None, readonly=None, deferrable=None, autocommit=None) Y 数据库不支持session中设置default_transaction_read_only。 autocommit Y - isolation_level Y - readonly N 数据库不支持session中设置default_transaction_read_only。 deferrable Y - set_isolation_level(level) Y - encoding Y - set_client_encoding(enc) Y - notices N 数据库不支持listen/notify。 notifies Y - cursor_factory Y - info Y - status Y - lobject N 数据库不支持大对象相关操作。 Methods related to asynchronous support poll() Y - fileno() Y - isexecuting() Y - Interoperation with other C API modules pgconn_ptr Y - get_native_connection() Y - informative methods of the native connection get_transaction_status() Y - protocol_version Y - server_version Y - get_backend_pid() Y 获取到的不是后台的pid,是逻辑连接的id号。 get_parameter_status(parameter) Y - get_dsn_parameters() Y - cursor basic description Y - close() Y - closed Y - connection Y - name Y - scrollable N 数据库不支持SCROLL CURSOR。 withhold N withhold cursor在commit前需要关闭。 Commands execution methods execute(query, vars=None) Y - executemany(query, vars_list) Y - callproc(procname[, parameters]) Y - mogrify(operation[, parameters]) Y - setinputsizes(sizes) Y - fetchone() Y - fetchmany([size=cursor.arraysize]) Y - fetchall() Y - scroll(value[, mode='relative']) N 数据库不支持SCROLL CURSOR。 arraysize Y - itersize Y - rowcount Y - rownumber Y - lastrowid Y - query Y - statusmessage Y - cast(oid, s) Y - tzinfo_factory Y - nextset() Y - setoutputsize(size[, column]) Y - COPY-related methods copy_from(file, table, sep='\\t', null='\\\\N', size=8192, columns=None) Y - copy_to(file, table, sep='\\t', null='\\\\N', columns=None) Y - copy_expert(sql, file, size=8192) Y - Interoperation with other C API modules pgresult_ptr Y -
  • 约束与限制 自定义登录限制: 新增数据源选择不同的集群,然后输入用户名和密码,测试连接后可以打开集群数据连接。 登录时最好勾选记住密码,如果不填数据库默认是gaussdb数据库。 自定义连接根据租户+用户做了用户权限隔离,不同的子用户看到的连接不同,每个用户只能看到自己创建的连接。 IAM 用户登录限制: 需要IAM用户并且已授权DWS Database Access角色权限才能登录,否则编辑面板置灰,无法编辑。此时需联系有“DWS Administrator”权限的用户在当前页面完成对GaussDB(DWS)的委托授权。 IAM用户目前登录DWS集群数据库后没有任何权限,需要在用户管理界面对给IAM用户赋权才能操作。 连接超时限制: 后台设置了连接的超时时间,如果超时30分钟没有任何操作,则需要重新登录。 连接采用“用户登录ID+DATABASE”的方式做唯一缓存,保证每个用户连接每个数据库使用一个连接,保证每次操作在一个连接上进行执行。 针对一个数据源下的同一个数据库,不建议开多个窗口执行SQL命令,因为同一个数据库下建立的是同一个连接,开多个窗口也需等待前面SQL执行完后才会继续执行。
  • (可选)准备E CS 作为gsql客户端主机 购买弹性云服务器的操作步骤,请参见《弹性云服务器快速入门》中的购买并登录Linux弹性云服务器章节。 创建的弹性云服务器需要满足如下要求: 弹性云服务器需要与GaussDB(DWS)集群在相同的区域、可用分区。 如果使用GaussDB(DWS)提供的gsql命令行客户端连接GaussDB(DWS)集群,弹性云服务器的镜像必须满足如下要求: 镜像的操作系统必须是gsql客户端所支持的下列Linux操作系统: “Redhat x86_64”客户端工具支持在以下系统中使用: RHEL 6.4~7.6 CentOS 6.4~7.4 EulerOS 2.3 “SUSE x86_64”客户端工具支持在以下系统中使用: SLES 11.1~11.4 SLES 12.0~12.3 “Euler Kunpeng_64”客户端工具支持在以下系统中使用: EulerOS 2.8 “Stream Euler X86_64”客户端工具支持在以下系统中使用: EulerOS 2.2 “Stream Euler Kunpeng_64”客户端工具支持在以下系统中使用: EulerOS 2.8 如果客户端通过内网地址访问集群,请确保创建的弹性云服务器与GaussDB(DWS)集群在同一虚拟私有云里。 虚拟私有云相关操作请参见《虚拟私有云用户指南》中虚拟私有云和子网章节。 如果客户端通过公网地址访问集群,请确保创建的弹性云服务器和GaussDB(DWS)集群都要有弹性IP。 购买弹性云服务器时,参数“弹性公网IP”需选择“现在购买”或“使用已有”。 弹性云服务器对应的安全组规则需要确保能与GaussDB(DWS)集群提供服务的端口网络互通。 安全组相关操作请参见《虚拟私有云用户指南》中安全组章节。 请确认弹性云服务器的安全组中存在符合如下要求的规则,如果不存在,请在弹性云服务器的安全组中添加相应的规则: 方向:出方向。 协议:必须包含TCP。例如TCP、全部。 端口:需要包含GaussDB(DWS)集群提供服务的数据库端口,例如,设置为“1-65535”或者具体的GaussDB(DWS)数据库端口。 目的地址:设置的IP地址需要包含所要连接的GaussDB(DWS)集群的连接地址。其中0.0.0.0/0表示任意地址。 图1 出方向的规则 GaussDB(DWS)集群的安全组规则需要确保GaussDB(DWS)能接收来自客户端的网络访问。 请确认GaussDB(DWS)集群的安全组中存在符合如下要求的规则,如果不存在,请在GaussDB(DWS)集群的安全组中添加相应的规则。 方向:入方向。 协议:必须包含TCP。例如,TCP、全部。 端口:设置为GaussDB(DWS)集群提供服务的数据库端口。例如,“8000”。 源地址:设置的IP地址需要包含GaussDB(DWS)客户端主机的IP地址。例如,“192.168.0.10/32”。 图2 入方向的规则