Untitled Post - 163
vim可以通过scp来编辑远程文件,大约是这个样子:
1 | $ vim scp://user@host/path/to/file |
很神奇的样子。此功能依赖于netrw.vim,vim已经在发行中集成。
vim可以通过scp来编辑远程文件,大约是这个样子:
1 | $ vim scp://user@host/path/to/file |
很神奇的样子。此功能依赖于netrw.vim,vim已经在发行中集成。
psql 提供变量替换特性,类似于shell的变量。
psql的变量就是简单的名字/值对,名字只能有字母、数字和下划线组成。
使用\set命令来设置变量:
1 | => \\set foo bar |
这样设置了变量foo,其值为bar。这样来显示变量的值:
1 | => \\echo :foo |
使用\set只指定变量名,不指定值时,会设置该变量,只不过其值为空。
使用\unset命令来销毁变量:
1 | => \\unset foo |
使用\set命令,不提供任何参数,显示全部的变量。
下面展示的是系统预置的变量:
1 | => \\set |
查看PostgreSQL版本
因此获取postgresql版本就有了另外一种方法:
1 | => \\echo :VERSION |
另一种方法是:
1 | => SELECT VERSION(); |
二者结果是一样的。
===
[erq]
psql启动时会先读取系统范围的psqlrc文件,然后读取用户主目录下的.psqlrc文件
下面是一个简单的配置:
1 | -- 静默模式 |
自动提交事务
AUTOCOMMIT是默认打开的,当命令执行成功时会自动进行提交。在自动提交事务打开时,如果要显式手动提交,那么必须在执行命令或命令块之前执行BEGIN或START TRANSACTION命令执行完命令后再执行END或COMMIT来手动提交事务。
当关闭自动提交时,命令执行成功后需要手动END或COMMIT来提交。
关闭自动提交时,系统默默的在任何没有开启事务的语句前自动添加BEGIN或START TRANSACTION等事务开始语句。
自动提交关闭时,要用ABORT或ROLLBACK显式的撤销回滚事务,如果没有提交退出当前会话,则未提交事务会自动回滚。
**注意:**这里有一个坑,当关闭事务自动提交时,使用psql导入数据库时,可能会因为sql文件中没有提交语句而最后回滚,但没有错误提示,只是没有什么数据也没导入而已.比如,pg_dump/pg_dumpall导出的sql脚本文件就没有COMMIT语句,从而导入不会成功.
提示符变量
%[
和 %]
之间的字符解释为终端控制字符序列。
%digits
转换为八进制字符序列,比如 %033
转换为 \033
,所以 %033[
正好转换为终端转义控制序列起始字符 \033[
,后面紧跟的正是终端转义控制序列,可以指定字体的颜色,粗细等等属性。
设置图形模式的终端转义序列的结束字符为m,所以,\033[与m之间的字符为真正的终端转义控制序列,这语法真的很@&^*(#!%
其实 \033[
即 Esc[
完整详细的终端转义控制序列参见[4]
postgresql支持的提示符变量参见[1]
References:
[1]psql
[2]An Explained psqlrc
[3]psqlrc
[4]ANSI Escape sequences
===
[erq]
postgresql支持在表和文件之间拷贝数据,可以使用PostgreSQL扩展的SQL函数COPY或者psql内部命令\copy来做这件事。
导出数据的格式:
1 | COPY table_name (query) TO 'filename' PROGRAM 'command' STDOUT \[ WITH OPTIONS \]; |
导入数据的格式:
1 | COPY table_name (query) FROM 'filename' PROGRAM 'command' STDIN \[ WITH OPTIONS \]; |
更详细的格式描述见[1]
COPY函数
COPY函数在服务器上执行,如果输出到文件,要注意postgresql服务器进程有没有对指定目录的执行权限,比如:
1 | =# COPY (SELECT * FROM base.tb_dictionary WHERE ...) TO '/tmp/designusage.csv' WITH CSV DELIMITER ','; |
将查询结果输出到临时目录下的指定文件。debian系统postgresql系统进程用户postgres的主目录是/var/lib/postgresql,也可以将文件输出到此目录。
如无写权限,会提示:
1 | ERROR: could not open file "..." for writing: Permission denied |
\copy命令
psql命令\copy在客户端执行,如果输出到文件是输出到客户端的文件系统,要注意当前执行psql的用户权限。比如:
1 | =# \\copy (SELECT * FROM base.tb_dictionary WHERE ...) TO '/tmp/designusage.csv' WITH CSV DELIMITER ',' |
如果要输出列名,可以指定HEADER选项,HEADER只用于CSV格式。
可以写到临时目录,也可以写到当前用户的主目录。
其实\copy命令实际上是使用了COPY FROM STDIN或者COPY TO STDOUT,然会通过STDIN或STDOUT与文件交互。
所以可以这样:
1 | $ psql -c "COPY (SELECT * FROM base.tb_dictionary WHERE ...) TO STDOUT WITH CSV DELIMITER ',' " -U role -h host dbname > export.csv |
使用COPY函数输出到STDOUT,然后重定向到文件。
References:
[1]copy data between a file and a table
[2]Outputting to CSV in Postgresql
===
[erq]
一个小坑,windows计划任务执行的命令或脚本,以及嵌套调用的命令或脚本,其路径名中不能包含括号,不能包含括号,不能包含括号。不然只会告诉你执行失败,退出码0x1,别无其他可用信息。
pandoc是一款强悍的文档的转换工具,支持绝大多数文档格式之间的相互转换,而且具有强大的控制能力。
安装
1 | # apt install texlive-xetex pandoc |
转换markdown
默认latex引擎pdflatex不支持中文,需要使用xelatex引擎,并且要指定中文字体
可以这样查看系统中文字体:
1 | $ fc-list :lang=zh |
然后mkd转换到pdf:
1 | $ pandoc foo.mkd --latex-engine=xelatex -V CJKmainfont="Noto Sans CJK SC" -o foo.pdf |
然而对中文的支持还是有些问题,这样会把较长的文本行截断,需要定制template来解决此问题。
先导出pandoc默认模板:
1 | $ pandoc -D latex > mytemplate.tex |
在生成的模板文件mytemplate.tex文件的第一行后面添加如下行:
1 | \\XeTeXlinebreaklocale "zh" |
将模板文件mytemplate.lex置于~/.pandoc/templates/路径下,或者置于转换命令当前目录下。
然后这样转换:
1 | $ pandoc manual.mkd --latex-engine=xelatex -V CJKmainfont="Noto Sans CJK SC" -o manual.pdf --template=mytemplate.tex |
还有一个小问题,默认生成的pdf边距比较大,可以通过geometry参数来控制边距。
所以最后的命令行大约是这个样子的:
1 | $ pandoc manual.mkd --latex-engine=xelatex -V CJKmainfont="Noto Sans CJK SC" -o manual.pdf -V geometry:"top=2cm, bottom=1.5cm, left=1cm, right=1cm" --template=mytemplate.tex |
可以用模板文件指定使用的字体,模板文件可以很复杂,嗯,latex太复杂了。
pandoc转换markdown时,对两个tab缩进支持不好,还没找到好的解决办法。
Mac OS X
安装pandoc和mactex
1 | $ brew install pandoc |
中文字体可以使用苹方简体中文 “PingFang SC”
References:
[1]Pandoc With Chinese (简体中文)
[2]pandoc faqs
[3]Pandoc: Markdown to PDF, without cutting off code block lines that are too long
[4]纯文本做笔记 — 使用 Pandoc 与 Markdown 生成 PDF 文件
[5]使用xelatex生成中文pdf
[6]使用pandoc转换md为PDF并添加中文支持
===
[erq]
tomcat自身支持会话复制的集群。
此post主要讲使用memcached存储会话,使用msm(memcached-session-manager)来管理会话复制。
通过配置共享会话的tomcat集群,可以提高服务的高可用性,并可以做到不停机连续更新应用程序。
示例配置采用两台机器,ip分别为10.100.0.20和10.100.0.21。每台机器分别部署nginx,tomcat和memcached。两个tomcat实例和两个memcached实例通过msm组成一个会话共享集群,前端由nginx做负载均衡。
还可以在nginx之前做DNS负载均衡。
nginx配置
1 |
|
nginx会将客户请求分发到后端服务器组
memcached配置
安装
1 | # apt install memcached |
memcached默认安装只监听本地回环地址,更改/etc/memcached.conf,注释掉下面的行:
1 | #-l 127.0.0.1 |
重启memcached服务会监听所有本地接口。
msm和tomcat配置
kiro序列化性能较高,因此这里使用kiro序列化器。
将msm基础包memcached-session-manager-${version}.jar,memcached-session-manager-tc8-${version}.jar和spymemcached-2.11.1.jar,以及kryo序列化支持jar包拷贝到$CATALINA_HOME/lib/目录。
debian系统中tomcat8的lib目录位于/usr/share/tomcat8/lib/
还有一个包Objenesis也需要下载安装到此目录中。
sticky sessions + kryo配置
/etc/tomcat8/context.xml文件中context一节最后添加:
1 | <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager" |
msm默认处于sticky模式,因此不用显式指定sticky参数。failoverNodes参数指定本机memcached节点名称,这样正常情况下msm会存储会话到其他memcached节点,当没有其他节点可用时才会使用failoverNodes。
non-sticky sessions + kryo配置
/etc/tomcat8/context.xml文件中context一节最后添加:
1 | <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager" |
这里明确指定sticky参数为false,注意不要设置requestUriIgnorePattern参数,否则当前配置下会出现问题,无法完成session共享。
sticky会话模式就是将用户“粘”在某一个服务器节点上,即同一个会话中的请求必须被转发到同一个节点上,除非该节点宕机才转发到故障转移节点。
non-sticky会话模式则是每一次请求都可能转发到不同节点。
sticky会话模式性能更好。
References:
[1]SetupAndConfiguration
[2]分布式session
===
[erq]
设置NAT内部服务器,并且设置了端口回流,内网可以正常通过公网ip访问内部服务。
但是当通过外网访问该服务时,从服务器上观察,TCP连接的源地址也被替换成了防火墙的内网接口地址,不过访问一切正常。
经排查,是因为设置端口回流时,在内网接口的ACL条目中未指定source,类似如下:
1 | rule 216 permit ip destination 10.100.0.31 0 |
导致防火墙将所有访问NAT服务的源地址全部替换成了防火墙的内网接口地址(内网接口优先级高,且不区分内外网网络地址???)。
通过指定哪些内网段访问NAT服务器时可以通过内网接口,可以只替换这些网段的源地址。
1 | rule 226 permit ip source 192.168.1.0 0.0.0.255 destination 10.100.0.31 0 |
这样以来,外网访问时,源地址没有被替换,但acl rule未指定的其他内网地址段将不能通过公网ip访问NAT服务。
===
[erq]
rman备份脚本出现错误提示:
1 | RMAN-06207: WARNING: 380 objects could not be deleted for DISK channel(s) due |
然后手动执行crosscheck并重新删除:
1 | RMAN> crosscheck archivelog all; |
提示由于恢复目录中没有归档日志的信息,无法删除。列出的归档日志是早已经物理删除掉、无用的日志。
1 | RMAN> delete expired archivelog all; |
也无法删除
最后,强制删除废弃的归档日志,force
关键字会忽略掉错误将其干掉。
1 | RAMN> delete force obsolete; |
删除成功。
===
[erq]