PostgreSQL备份
PostgreSQL也支持逻辑备库和物理备份两种方式。物理备份可以和Oracle一样实现联机热备份,并且同样也需要将数据库设置为归档模式。
逻辑备份
PostgreSQL提供了pg_dump/pg_dumpall两个程序可以用来将数据dump成文本文件,实现数据的逻辑备份。使用不同的参数,可以将数据dump成PostgreSQL专用的数据格式(生成copy语句)或者标准SQL语句(生成insert语句)格式。恢复只需要简单的使用psql将文件执行一遍即可。另外也可以使用pg_restore工具来恢复数据。
利用pg_dump备份test数据库(只有一张test表),包括重建表的DDL语句,授权语句等所有信息,生成copy格式的文件:
$ ./pg_dump test
--
-- PostgreSQL database dump
--
SET statement_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = off;
SET check_function_bodies = false;
SET client_min_messages = warning;
SET escape_string_warning = off;
SET search_path = public, pg_catalog;
SET default_tablespace = '';
SET default_with_oids = false;
--
-- Name: test; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
--
CREATE TABLE test (
i integer
);
ALTER TABLE public.test OWNER TO postgres;
--
-- Data for Name: test; Type: TABLE DATA; Schema: public; Owner: postgres
--
COPY test (i) FROM stdin;
1
2
\.
--
-- Name: public; Type: ACL; Schema: -; Owner: postgres
--
REVOKE ALL ON SCHEMA public FROM PUBLIC;
REVOKE ALL ON SCHEMA public FROM postgres;
GRANT ALL ON SCHEMA public TO postgres;
GRANT ALL ON SCHEMA public TO PUBLIC;
--
-- PostgreSQL database dump complete
--
利用pg_dump备份test库,只保存数据,insert语句格式:
[postgres@dbconsole bin]$ ./pg_dump --inserts -a test -- -- PostgreSQL database dump -- SET statement_timeout = 0; SET client_encoding = 'UTF8'; SET standard_conforming_strings = off; SET check_function_bodies = false; SET client_min_messages = warning; SET escape_string_warning = off; SET search_path = public, pg_catalog; -- -- Data for Name: test; Type: TABLE DATA; Schema: public; Owner: postgres -- INSERT INTO test VALUES (1); INSERT INTO test VALUES (2); -- -- PostgreSQL database dump complete --
物理备份
和Oracle一样,物理备份可以分为冷备份和热备份。冷备份就是将数据库实例关闭,然后直接复制data目录的所有文件,恢复时只需要将文件copy到data目录,无须利用日志(WAL–Write-Ahead Logging)进行恢复。而热备份,则需要利用日志将数据库恢复到一致状态,因此需要先将数据库置于归档模式。
PostgreSQL归档模式使用参数archive_mode控制,这是一个静态参数,修改postgresql.conf文件,加入如下参数,然后重启生效:
archive_mode = on archive_command = 'cp "%p" /u01/postgresql/arch/"%f"' archive_timeout = 600
postgres=# show archive_mode; archive_mode -------------- on (1 row)
由于postgresql没有归档进程,因此归档是通过外部命令(OS)完成的,archive_command用于指定该外部命令,具体格式请参考文档。如果是linux归档到本地,使用cp即可,如果是到远程,则可以使用scp或者rsync。archive_timeout强制N秒以后进行一次归档,这个和Oracle的archive_lag_target参数的作用一样。当然也可以手工进行日志切换:
postgres=# select pg_switch_xlog(); pg_switch_xlog ---------------- 0/7000000 (1 row)
热备份前,需要先将数据库置于备份状态,这一点和Oracle的手工也备份也是一样的。该命令会导致一次checkpoint,可能在业务高峰期会带来一些压力和风险,因此备份还是需要安排在业务低谷期间执行比较稳妥。
postgres=# select pg_start_backup('test_backup');
pg_start_backup
-----------------
0/8000020
(1 row)
然后在os层面将data目录进行复制备份。完成后,再取消备份状态,该命令同时会执行一次日志切换,并进行归档,以保证热备份期间的日志都已经归档,保证恢复数据库到一致状态的所有日志都能从归档中找到:
postgres=# select pg_stop_backup(); pg_stop_backup ---------------- 0/8000088 (1 row)
备份完成后,可以在归档目录找到一个记录了本次备份信息的文件:
$ more 000000010000000000000008.00000020.backup START WAL LOCATION: 0/8000020 (file 000000010000000000000008) STOP WAL LOCATION: 0/8000088 (file 000000010000000000000008) CHECKPOINT LOCATION: 0/8000020 START TIME: 2010-02-03 12:24:57 CST LABEL: test_backup STOP TIME: 2010-02-03 12:24:59 CST
PostgreSQL官方并没有提供和Oracle的rman一样的备份工具,不过因为PostgreSQL是开源的数据库,因此也有一个开源的工具pg_rman可以使用,从命令行来看功能已经非常强大,暂时还没有测试,有兴趣的可以研究一下。
pg_rman [ OPTIONS ] { init | backup | restore | show [ DATE | timeline ] |
validate [ DATE ] | delete DATE }
PostgreSQL安装
PostgreSQL8.x版本的安装已经非常的简单了。EnterpriseDB制作了一键安装的版本,包括FreeBSD/Linux/Mac OS X/Solaris/Windows平台都有。不过即使使用源码编译,也非常的简单。各个版本的源码可以点这里下载。
创建os用户
#useradd -g dba postgres #su - postgres
编译
$tar -zxvf postgresql-8.4.2.tar.gz $cd postgresql-8.4.2 $./configure --prefix=/OPT/postgresql --enable-profiling --with-blocksize=8 --with-wal-blocksize=8 $make && make install
其中with-blocksize指定数据块大小,默认8k,with-wal-blocksize指定日志块大小,默认也是8k。更多编译配置选项,可以通过./configure –help查看。
初始化database,注意PostgreSQL在服务端不支持GBK编码。
$cd /opt/postgresql/bin
$ ./initdb --encoding=utf8 -D /opt/postgresql/data
The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.
The database cluster will be initialized with locale en_US.UTF-8.
The default text search configuration will be set to "english".
creating directory /opt/postgresql/data ... ok
creating subdirectories ... ok
selecting default max_connections ... 100
selecting default shared_buffers ... 32MB
creating configuration files ... ok
creating template1 database in /opt/postgresql/data/base/1 ... ok
initializing pg_authid ... ok
initializing dependencies ... ok
creating system views ... ok
loading system objects' descriptions ... ok
creating conversions ... ok
creating dictionaries ... ok
setting privileges on built-in objects ... ok
creating information schema ... ok
vacuuming database template1 ... ok
copying template1 to template0 ... ok
copying template1 to postgres ... ok
WARNING: enabling "trust" authentication for local connections
You can change this by editing pg_hba.conf or using the -A option the
next time you run initdb.
Success. You can now start the database server using:
./postgres -D /opt/postgresql/data
or
./pg_ctl -D /opt/postgresql/data -l logfile start
初始化完成后,会在 /opt/postgresql/data目录生成数据库的文件,至此,软件安装完毕,数据库创建完毕。
启动数据库
./pg_ctl -D /opt/postgresql/data/ -l /opt/postgresql/log/alert.log start
启动后,可以发现PostgreSQL实例一共运行了5个进程
$ ps -ef | grep postgres postgres 17572 1 0 16:41 pts/2 00:00:00 /opt/postgresql/bin/postgres -D /opt/postgresql/data postgres 17574 17572 0 16:41 ? 00:00:00 postgres: writer process postgres 17575 17572 0 16:41 ? 00:00:00 postgres: wal writer process postgres 17576 17572 0 16:41 ? 00:00:00 postgres: autovacuum launcher process postgres 17577 17572 0 16:41 ? 00:00:00 postgres: stats collector process postgres 18679 20791 0 16:47 pts/2 00:00:00 grep postgres
其中wal writer process是日志写进程。
PostgreSQL简介
上个周末,无聊的时候关注了一下PostgreSQL。第一次尝试去安装PostgreSQL,还是好几年前的事了,那是8.0版本刚出来,终于开始原生的支持windows了,所以在自己电脑上折腾了一个。不过那时候也仅限于安装了一次而已,甚至psql的命令行都不知道怎么用。
同样作为开源关系型数据库,MySQL在这几年获得了更多的关注。大量的互联网公司都基于MySQL来构架系统,也导致MySQL DBA开始火热,一大堆年轻有为的同学投入到其中,渐成燎原之势。MySQL数据库火热了,MySQL AB公司却被sun收购,现在又随着sun要投入Oracle的怀抱,而且欧盟已经无条件批准这个收购,只剩下中国和俄罗斯,大局已定。作为商业数据库的绝对老大,Oracle的这次收购,让MySQL的支持者感到了威胁,其创始人甚至发起了一场保护MySQL(有墙),阻击Oracle收购的运动。
这也是PostgreSQL的机会,最近PostgreSQL的开发节奏很快,8.5已经连续出到了alpha3版,在这个版本中,最吸引我的是hot standby,类似于Oracle11g的active data guard,hot standby也可以在恢复的同时提供读服务,而以往版本,PostgreSQL的物理备库warm standby,则只能处于恢复状态,一旦open,则需要重做,比较痛苦。PostgreSQL的很多特性,都和Oracle相当的类似,甚至有一家商业化的公司EnterpriseDB,在致力于将PostgreSQL打包,使得应用程序从Oracle迁移到PostgreSQL更方便,据说80%的Oracle应用代码甚至不需要做修改就能在PostgreSQL运行。因此,我在twitter上说,如果PostgreSQL在人机交互的工具和配置部分,能够更加友好一点,完全是一个影子版本的Oracle。
PostgreSQL也支持mvcc多版本一致性控制。不过其实现的机制和Oracle的不一样。Oracle是将变化的前映像记录到单独的undo段中,而PostgreSQL则只是将前映像(Tuples)上做个标记,如果是delete,则相当于是逻辑删除,实际的数据还是在原来的段中,如果是insert,相当于先delete,再insert,而且会在原来的记录上加一条指向新记录的指针,形成一个链表,查询的时候需要沿着这个链表找到一致的数据。这样会造成一个问题,一段时间以后,dml操作使得数据段和索引段中都有大量的前映像信息存在,会严重影响数据查询的效率。PostgreSQL的mvcc的这种实现方式,带来的一个好处是回滚非常快,只需要修改前映像上的几个标志位即可,而不像oracle需要从undo段将前映像再复制回来。但是,这种方便回滚,却会损失查询性能的设计思路,真的比较诡异。PostgreSQL中有一个专门用来清理这些旧版本数据的程序,叫做vacuum。在以前的版本中,需要定期执行vacuum来优化数据存储结构。这对于DBA来说,无疑是一件痛苦的事情。直到8.1版本,引入了autovacuum,系统可以自动来进行这些清理工作,终于人性化了一点点。
在8.3版本,引入了一个新的特性HOT(Heap Only Tuples),主要的目的是努力避免update造成的性能低下的问题。其实这个HOT,说白了很简单,对于update,要实现mvcc,其机制还是一样的,区别在于select,在沿着链表找一致性数据的过程中,如果发现这个检查过的版本已经没有任何事物在引用了,就会顺便把清理工作做掉,而不是像以前要等vacuum来做。因此这会加大一点select的压力,但前人栽树,后人乘凉,接下来需要访问这些数据的其他select就会快很多了,这和Oracle的延迟块清除其实有些类似的,当然两者的设计目的并不一样。
tbstat:实时监控数据库统计状态的小工具
用perl写了一个简单的工具,用于实时查看数据库的统计状态信息,展现信息主要来源于Oracle数据字典中v$systat和v$system_event。写这个工具的初衷,是因为目前我们对于数据库的监控,更多的是分钟级别抽样的数据来绘制的图形,粒度相对还比较粗,有一些比较深的问题,需要更加细粒度的数据。而如果把监控的粒度做到秒级,则收集的数据量就会非常大,因此需要一个平衡,平时采用分钟级别的抽样数据已经足够用于预警,而秒级的则用于某个具体问题的分析。
当前tbstat功能还比较简单,类似于iostat/vmstat等os工具,tbstat可以通过指定抽样间隔和抽样次数,来循环抓取Oracle的统计状态信息。tbstat支持三个参数 -i 表示间隔时间 -c 表示循环次数 -n 表示需要查看的统计信息的名字(使用前后%的like来查询)
- tbstat -i 2 -c 10 表示间隔时间2s,循环次数10次,展示经过人工筛选的36项统计信息
- tbstat -i 2 -c 10 -n parse 表示间隔时间2s,循环次数10次,展示所有名字包含parse的统计信息
- tbstat -i 2 -c 10 -n all 表示间隔时间2s,循环次数10次,展示所有不为零的统计信息
也可以使用简化的参数输入方法,第一位表示间隔时间,第二位表示循环次数,第三位表示统计信息名。直接敲入tbstat,则默认的参数为间隔时间10s,次数无限,经过挑选过滤的一些常用的v$sysstat中的统计信息。如果name参数传入的值是event,则展示v$system_event中的等待事件的信息。
$tbstat 1 0
--------------------------------------------------------------------------
-- tbstat v0.3.3 --- a tool for oracle system statistics and event.
-- Powered by NinGoo.net
--------------------------------------------------------------------------
CPU used by this session: 40 CR blocks created: 5
DBWR checkpoint buffers written: 569 DBWR undo block writes: 64
bytes received via SQL*Net from client: 314297 bytes sent via SQL*Net to client: 2761660
cleanouts only - consistent read gets: 4 consistent gets: 48855
db block changes: 2122 db block gets: 3714
enqueue requests: 900 enqueue waits: 7
execute count: 3145 free buffer requested: 1402
index crx upgrade (positioned): 3 index fast full scans (full): 0
leaf node 90-10 splits: 0 leaf node splits: 0
logons cumulative: 1 parse count (failures): 0
parse count (hard): 0 physical reads: 1546
physical reads cache prefetch: 0 physical writes: 603
redo size: 618436 redo synch time: 16
redo synch writes: 181 redo write time: 15
redo writes: 174 rollbacks only - consistent read gets: 0
sorts (disk): 0 sorts (memory): 259
table scans (long tables): 0 table scans (short tables): 9
transaction rollbacks: 0 user commits: 182
$tbstat 1 0 event
-------------------------------------------------------------------------------
-- tbstat v0.3.3 --- a tool for oracle system statistics and event.
-- Powered by NinGoo.net
-------------------------------------------------------------------------------
Event Name: waits time Event Name: waits time
--------------------------------------------------------------------------------------------
LGWR wait for redo copy: 1 0.01 SQL*Net more data from client: 151 19.95
SQL*Net more data to client: 1218 0.01 buffer busy waits: 2 0.01
control file parallel write: 1 0.51 control file sequential read: 1 0.26
cursor: pin S: 0 0.00 cursor: pin S wait on X: 0 0.00
db file parallel read: 0 0.00 db file parallel write: 0 0.00
db file scattered read: 0 0.00 db file sequential read: 2040 3.43
direct path read: 269 0.71 direct path read temp: 0 0.00
direct path write: 23 0.26 direct path write temp: 0 0.00
enq: CF - contention: 0 0.00 enq: HW - contention: 7 9.00
enq: SQ - contention: 0 0.00 enq: TX - allocate ITL entry: 0 0.00
enq: TX - index contention: 0 0.00 enq: TX - row lock contention: 0 0.00
latch free: 0 0.00 latch: cache buffers chains: 0 0.00
latch: library cache: 0 0.00 latch: redo writing: 0 0.00
latch: session allocation: 0 0.00 library cache lock: 0 0.00
log buffer space: 0 0.00 log file parallel write: 145 0.60
log file sequential read: 145 0.53 log file switch completion: 0 0.00
log file sync: 147 0.78 os thread startup: 0 0.00
read by other session: 0 0.00 row cache lock: 0 0.00
undo segment extension: 0 0.00
如果输入的name是精确匹配到只有一条统计信息的,会在后面打印出间隔时间内排名前10的sid的值。利用此功能,可以很方便的抓到造成某些统计信息异常的会话和SQL语句,会话和SQL信息是通过关联v$session来获取的。因此需要注意,如果统计信息对应的事件持续时间很短,从v$session里抓取到的sql可能并不是造成统计信息升高的罪魁祸首,但是sid一般来说还是准确的,因为应用采用的大多是连接池来连接数据库的,因此还是可以更具sid和machine信息来看看造成异常的是哪个具体的应用。
例如,全表扫描一般会导致physical reads cache prefetch等待事件,因此可以通过查看该事件对应的top sid来获得具体的语句,当然,不是所有的physical reads cache prefetch都是全表扫描导致的,因此对于获得的结果,还需要DBA根据具体情况做进一步分析:
$tbstat 1 0 'physical reads cache prefetch'
-------------------------------------------------------------------------------
-- tbstat v0.3.3 --- a tool for oracle system statistics and event.
-- Powered by NinGoo.net
-------------------------------------------------------------------------------
physical reads cache prefetch: 526
sid value % machine sql_id
---------- ----------- ----- ------------------- --------------
2928 302 69.7 test11 79db58a3dg921
4902 67 15.5 test71 79db58a3dg921
4821 64 14.8 test33 3afdq50xt03ch
4544 0 0.0 test54 3afdq50xt03ch
1801 0 0.0 test06 79db58a3dg921
2830 0 0.0 test12 79db58a3dg921
898 0 0.0 test09 4n7675hwwcndc
1031 0 0.0 test16 79db58a3dg921
463 0 0.0 test04 3afdq50xt03ch
1364 0 0.0 test08 cq749u66x06uj
1408 0 0.0 test27 39rbqj3ck76w3
722 0 0.0 test37 26hdkf07336uf
当然,tbstat只是一个用于抽取统计状态的小工具而已,如果要用于故障诊断,则还是要求DBA对于v$systat和v$system_event中各种统计和事件非常的熟悉。tbstat使用了DBD::Oracle以sysdba身份来连接数据库,因此需要为Perl安装DBI和DBD::Oracle模块,并且在数据库服务器本机上执行。如果你对于这个工具有兴趣,可以在这里下载源代码,使用过程中,如果有什么建议和需求,欢迎告诉我。
常用标签: oracle MySQL Oracle11g dba blog 新特性 oow oow2009 wordpress ASM
最新评论 | Recent comments
- seonaut: 好文章,强烈支持! 欢迎交换友情...
- left: 博主你好,请问现在还有合租计划么...
- 深入浅出Flashcache(五): [...] 实际上,不同版本的Flashcache,输...
- RedhatLinux网卡配置与绑定 | 51NOC无忧网管中心: [...] 地址: http://www.ningoo.net/html/2007/r...
- yangdehua: write backup: 先写入到cahce,然后cache中...
- fxw1989311: 谢...
- 好看的电影: 呵呵,轻轻的,来看看你,我会回来...
- anymouse: mongodb是用的AGPL许可证。不适合商业...
- hoterran: 期待,学习...
- 深入浅出Flashcache(三): [...] 前文简单介绍了block device和device ...
- 深入浅出Flashcache(三): [...] 前文简单介绍了block device和device ...
- zhuanke: 偶然路过,先从第一篇看看,:...
- lee325: I subscribed to this community forum a while ago ...
- jack.buptsse: 好期待呀!NinGoo十分期待您的FlashCache...
- Nedleprortall: ChrisTV Online! Free / Premium - Программ...
