0%

CPU负载居高不下,可以从这几方面入手查找原因,一个比较大的可能是有查询在长期占用CPU资源。

查看当前连接数

1
2
=> SELECT count(*) FROM pg_stat_activity;
=> select client_addr, count(*) from pg_stat_activity group by client_addr;

可以查看总的连接数,以及每个客户端的连接数,判断是否有客户端泄露连接。

查看连接状态

1
=> SELECT state, count(*) FROM pg_stat_activity GROUP BY state;

连接有以下几种状态:

  • idle
    连接对应的后端进程处于空闲状态
  • actvie
    连接对应的后端进程正在执行查询
  • idle in transaction
    连接对应的后端进程在一个事务中,但当前并没有执行查询
  • idle in transaction (aborted)
    在一个事务中,但是事务中的语句出现了错误,事务没有正确回滚
  • fastpath function call
    正在执行fastpath函数调用
  • disabled
    后端进程被配置为禁止跟踪

等待锁的连接

1
=> SELECT count(distinct pid) FROM pg_locks WHERE granted = false;

查看是否有连接在等待排它锁导致效率低下

查看事务最大执行时间

1
=> SELECT max(now() -xact_start) FROM pg_stat_activity WHERE state IN ('idle in transaction','active'); 

查看当前所有事务中最长事务的执行时间,一般来讲事务应该在数秒内结束,数分钟已经是很长的事务了。如果有事务的执行时间达到了小时的级别,那一定是出现了错误,但是事务还在占用系统资源,应该将其干掉。

查看事务执行时间

1
=> SELECT pid, xact_start FROM pg_stat_activity ORDER BY xact_start ASC;

以事务的起始时间为顺序,如果某事务的运行时间过长,比如达到了小时级别,应该查清原因,然后搞掉它。

杀掉后端进程

1
=> SELECT pg_cancel_backend(1234);

1234就是pg_stat_activity表里的pid,也是postgres进程的系统进程pid,不要用操作系统命令去搞死进程,要用postgresql提供的命令。

References:
[1]28.2. The Statistics Collector
[2]Debug Slow Performance & High Resource Utilisation Issue in PostgreSQL
[3]Find and Kill Long Running Process in PostgreSQL

===
[erq]

fork之后上游可能又有了一些更新,在提交pull request之前最好重新同步一下上游主干,解决可能存在的冲突之后再发起pull request

步骤如下:

1
2
3
4
5
$ git remote add upstream https://github.com/jiangwen365/pypyodbc # 添加上游仓库
$ git fetch upstream # 获取上游最新更新
$ git checkout master # 切换到本地需要更新的分支头,master或者其他名字的分子都行,看需要
$ git merge upstream/master # 合并上游master分支到本地master分支,分支名字根据需要指定,rebase亦可
$ git push # 将更新后的本地分支推送到github

简单明了。

===
[erq]

pypyodbc

pypyodbc是一个使用纯python实现的跨平台odbc模块,其利用了ctypes来访问底层的odbc驱动,支持python2和python3。
虽然跨平台,但其对linux/mac平台上的unixODBC支持存在问题,无法正确显示中文字段名和字段值。

unixODBC

unixODBC有几个函数的ansi版本和宽字符版本返回信息比较古怪。

首先说SQLDescribeCol,其ansi版本,也就是不带后缀W的版本,无论本地locale为何皆直接返回utf-8编码的字符,但是SQLDescribeColW版本在mac平台上返回utf-16编码的字符,linux平台对于中文字符返回的是用zero填充了每一个utf-8编码字节的神一样的编码

如下面所示:

1
'\\xe5\\x00\\x9b\\x00\\xbe\\x00\\xe5\\x00\\xb9\\x00\\x85\\x00\\xe5\\x00\\x8f\\x00\\xb7\\x00\\x00\\x00'

正确的应该是长这样的:

1
'\\xe5\\x9b\\xbe\\xe5\\xb9\\x85\\xe5\\x8f\\xb7\\x00

以utf-8解码后对应的中文字符是”图幅号”

而英文字符返回的是这样的:

1
'B\\x00u\\x00i\\x00l\\x00d\\x00G\\x00e\\x00o\\x00C\\x00o\\x00d\\x00e\\x00\\x00'

仔细看,这串字符实际上就是”BuildGeoCode”,当然也是utf-8编码无疑。返回的编码以’\x00\x00’作为结束符,它是utf-16吗?它是utf-8吗?
这都算天坑了吧,没这样玩的。

SqlGetData则只有一个版本,无论locale为何都是返回utf-8编码的字符。

针对这几点问题制作了一个补丁,放在了github上,准备给原作者发一个pull request。修改后的版本,connect函数无论unicode_results为True或False都可以正确的返回中文字符。

还有一个函数SQLGetInfo(W),当使用SQL_DRIVER_NAME(值为6)调用时,无论调用哪个版本,都返回SQL_ERROR(值为-1)。

mdbtools
mdbtools是unixODBC上的mdb driver,当前只支持读操作,查询数据时尙不支持group by字句,select得到结果后自行排序吧。

UPDATE:
补丁已经迅速进入官方主线

===
[erq]

utf-16(utf-16-be,utf-16-le)是ucs-2的超集,python3中支持的编码格式没有ucs-2,如需处理ucs-2,直接使用utf-16编码即可。

dpkg -s --status package_name显示包的详细信息,或者执行dpkg-query -s --status package_name

运行locate libodbc命令时,提示“locate: warning: database ‘/var/cache/locate/locatedb’ is more than 8 days old (actual age is 22.3 days)”,运行sudo updatedb更新一下数据库即可。

sed的s命令通常使用/作为分隔符,其实并不是只有/可以做分隔符,s命令紧邻其后的任意一个字符都可以作为分隔符,因此如果pattern或repacement中有/,所以可以这样sed 's,bin/bash,,' 也可以这样sed "s@bin/bash@@"

k8s就是指kubernetes,就像i18n是internationalization的缩写一样。

sierra的terminal里,vim输入中文乱码了,百思不得其解,苦苦搜索后,发现一个线索,terminal的preferences- Profile - advanced - Input - Escape non-ASCII input with Control-V不要勾选,果然此选项被勾选了,去掉勾选汉字输入正常了. but,这选项不是我开启的啊~~~

Console Vim uses whatever font the console/terminal is using. Changing the font in your terminal is done differently depending on your system and the terminal in use.