运维类问题
如何通过工具或者代码访问数据库?
云数据库 FusionDB 支持多种方式进行实例的连接,主要包含如下方式:
- pgadmin是开源图形化管理工具,可以对监控数据、执行计划等图形化展示;
- psql是一种命令行的连接方式;
- C/C++ 程序可以使用ODBC接口;
- Java程序可以使用JDBC接口;
- Perl脚本语言可以使用DBI连接接口;
-
python通过模块psycopg2来实现; 以psql客户端为例介绍连接实例的方法,其他客户端可参见此方法。
使用 psql 客户端运行如下命令,根据提示输入密码,连接数据库。
psql -U username -h hostname -p port dbname Password for user username: psql (8.3.23) Type “help” for help. dbname=#
参数说明如下:
- username:初始账号用户名
- hostname:实例地址
- port:实例端口号
- dbname:要连接的数据库名称 如:psql -U myuser -h
FusionDB.xxxxxxx.whlocal.com -p 6600 dbname
脚本怎样免密连接数据库实例?
- 在调用脚本的用户的home目录下新建“.pgpass”文件,并写文件内容为:“hostname:port:database:username:password”。
eg: 以work用户调用脚本,则在/home/work/目录下新建“.pgpass”文件,文件内容为:“FusionDB.xxxxxxx.whlocal.com:6600:postgres: myname:bfecnhib578VTF”(如果是相连接不同的数据库,可以写多条,每行一条)。 - 给文件的修改使用权限为0600:chmod 0600 .pgpass。
- 使用“psql -U myuser -h FusionDB.xxxxxxx.whlocal.com -p 6600 dbname”登录数据库不需要输入密码(只有home目录下配有“.pgpass”文件的用户才可以免密码进入)。
如何查看数据库的参数信息?
连接数据库实例后执行SQL语句show all可查看数据库的参数信息。
如何修改参数?
目前,本产品不支持全局地修改参数,但是用户可以在连接内修改参数(具体参考 云数据库 FusionDB 的参数修改限制)。可以使用命令 ALTER ROLE <用户名> SET <参数名> = <参数值> 来修改参数。该参数修改只针对指定的用户生效。
如何查看当前数据库的连接信息?
连接数据库实例后执行SQL语句select * from pg_stat_activity
可查看连接信息,结果集会显示出当前连接的数据库名,用户,IP地址,连接开始时间,查询的语句等。
无法连接云数据库 FusionDB,如何解决?
情况1:
问题描述
连接数据库实例,报错如下: FATAL: remaining connection slots are reserved for non-replication superuser connections
原因
这是由于连接数满了导致。
解决办法
- 查看当前连接数的限制
show max_connections;
- 查看当前数据库的连接
select * from pg_stat_activity;
- 使用如下SQL终止连接
SELECT pg_terminate_backend(pid);
其中pid指进程号,具体是pg_stat_activity视图中pid字段的值。
情况2:
问题描述
连接数据库实例报错如下 psql: FATAL: no pg_hba.conf entry for host “10.94.20.24”, user “xxx”, database “fsgrim”, SSL off
原因
授权问题,未添加ip白名单导致。
解决办法
rds控制台->账号管理中添加ip白名单 10.94.20.24 即可。
如何查看某个database的空间占用?
连接数据库实例后执行以下SQL语句可查看数据库的空间占用情况(单位MB)。
select datname,pg_size_pretty(pg_database_size(datname)) from pg_database;
如何查看某个schema的空间占用?
查询一个Schema下面的所有表的总大小(单位MB,包括索引和数据);
select schemaname ,round(sum(pg_total_relation_size(schemaname||'.'||tablename))/1024/1024) "Size_MB" from pg_tables where schemaname='<schemaname>' group by 1;
如何查看一个表的空间占用?
查询一张非分区表的总大小(单位为MB,包含表的索引和数据): select pg_size_pretty(pg_total_relation_size(‘.’));
查询分区表所有分区的总大小(单位MB,包含表的索引和数据): select schemaname,tablename,round(sum(pg_total_relation_size(schemaname || ‘.’ || partitiontablename))/1024/1024) “MB” from pg_partitions where schemaname=‘’ and tablename=‘’ group by 1,2;
在云数据库 FusionDB 删除数据库时,提示有连接在使用该库,该怎么解决?
问题描述
在云数据库 FusionDB 删除数据库提示如下:
ERROR: database “test” is being accessed by other users DETAIL: There is 1 other session using the database.
原因
这是因为当前有连接在使用该库。
解决办法
在删除数据库之前首先断开所有连接该库的连接。 查看所有连接该库的连接: SELECT * FROM pg_stat_activity WHERE datname = 'db_name';
确定以上的连接是否可以断开,若是则执行: SELECT pg_terminate_backend(pid) FROM (select pid from pg_stat_activity where datname = 'db_name' ) t;
断开所有连接后再执行: drop database db_name;
在云数据库 FusionDB 中运行一个SQL语句,一直不返回结果,运行时间远超预估时间,怎么处理?
分析原因
数据库中更有可能发生死锁。
通过使用以下语句查看系统当前执行语句中是否含有waiting字段为t的语句: SELECT * FROM pg_stat_activity;
更加直观地可以使用 SELECT * FROM pg_stat_activity WHERE waiting = 't';
查询锁状态的执行语句。
解决办法
首先查看数据库当前运行最长时间的任务,看看是否阻塞了其他SQL语句; select * from pg_stat_activity where current_query != ‘’ order by query_start asc limit 1;
如果当前存在大量的任务处于锁状态,应该终止相应的长事务进程: SELECT pg_terminate_backend(pid)
其中pid指进程号,具体是pg_stat_activity视图中pid字段的值。
删除数据后无法释放空间,如何处理?
问题描述
在云数据库 FusionDB 使用delete语句清空表数据或者删除部分数据后,表的大小无变化,所占用的磁盘空间无法释放。 分析原因
在云数据库 FusionDB 中,使用 DELETE 语句并不会真正的删除数据记录,而是简单地将其标记为不可见,并不会释放数据所占用的空间;同样,UPDATE语句也不会真正的修改原数据,而是将原数据标记为不可见,然后将更新后的数据记录插入到表尾。所以频繁进行删除更新操作的表会越来越大。
解决办法
- 如果想清空表数据,建议直接使用TRUNCATE语句实现,该语句会直接删除表的数据文件,所以会马上释放空间;
- 使用VACUUM table_name;回收不可见的空间,但只是简单地回收空间并且令其可以再次使用,空间并不返回到操作系统(在大多数情况下);
- 如果想真正释放不可见的空间,可以使用VACUUM FULL table_name;来实现,但该方法会对表加上排它锁,以及会消耗一部分资源,建议在数据库维护阶段操作。
常见异常问题排查和处理方法
事务被终止
在执行 SQL 时,偶尔会遇到如下错误:
current transaction is aborted,commands ignored until end of transaction block.
该错误表示,当前事务被终止,执行的命令被数据库回滚,一般是事务中有 SQL执行报错,导致当前事务回滚,如果不是 SQL 的问题,可能是网络问题,或者集群中某个节点太慢导致系统不稳定,一般重新运行即可。
网络异常错误
在执行sql时,偶尔会遇到如下错误:
Error on receive from seg2 slice1 yq01-dba-rimgemini-gp-s03.yq01:40001 pid=1987: server closed the connection unexpectedly
子节点执行报错,服务连接异常终止,可以重新运行试试。如果不能解决问题,则可能 segment 上出现了问题,要检查 segment 的日志文件进行问题排查。
内存不足
内存不足报错:
insufficient memory reserved for statement
一般是当前系统运行了太多 SQL,或者是某一个 SQL 消耗太大,占用了大量的内存导致其他 SQL 运行报错,一般的做法是
- 减少并发 SQL 数量,比如从业务层面控制,或者从资源队列的层面控制;
- 查看pg_stat_activity表中哪个 SQL 执行时间比较长,一般消耗资源多的也是执行时间相对比较长的,将找到的 SQL 终止掉。
不能对分布键执行 Update
对表进行 Update 的时候报错:
ERROR: Cannot parallelize an UPDATE statement that updates the distribution columns
分布键不能被更新,因为这会导致数据重分布,如果分布键一定要更新,解决办法就是新建一张表,然后将原始表数据导入到新表(可在导入的时候边导入边处理)中,从而实现 update 的操作。
占用的资源超过了资源队列限制
当用户执行的 SQL 超过了资源队列限制的大小,会报如下的错误:
statement require more resource than resource queue allows
此时 SQL 不能执行,出现这个报错一般是 SQL 写的有问题,检查下是否 SQL 过于复杂,或者产生了笛卡尔积,解决方法如下:
- 增加该用户所在的资源队列的大小限制
- 使用超级用户执行该 SQL,超级用户没有资源队列的限制
- 改写 SQL,将复杂的 SQL 拆分成多个小 SQL 执行,减少一次 SQL 的消耗 检查 SQL 是否正确,优化 SQL 使用更少的资源