1.SQL调整
PostgreSQL 11 新特性学习-架构调整、SQL、PL/pgSQL功能增强
本节介绍与 SQL 语句相关的新功能。
1.1.ALTER TABLE
现在可以更改某些系统目录的属性。
postgres=# ALTER TABLE pg_attribute SET (autovacuum_vacuum_scale_factor=0) ; ALTER TABLE
复制
1.2.ALTER TYPE ADD VALUE
ALTER TYPE ADD VALUE 语句现在在事务块中可用。但是添加的值不能在事务块中使用。
postgres=# create table t_mood (c1 mood); CREATE TABLE postgres=# begin; BEGIN postgres=# ALTER TYPE mood ADD VALUE 'angry'; ALTER TYPE postgres=# insert into t_mood values('happy'); INSERT 0 1 postgres=# insert into t_mood values('sad'); INSERT 0 1 postgres=# insert into t_mood values('angry'); ERROR: unsafe use of new value "angry" of enum type mood LINE 1: insert into t_mood values('angry'); ^ HINT: New enum values must be committed before they can be used. postgres=# commit; ROLLBACK postgres=# select * from t_mood; c1 ---- (0 rows)
复制
1.3.COMMIT/ROLLBACK AND CHAIN
可以添加 CHAIN 子句,该子句在提交或丢弃 (ROLLBACK) 事务后立即启动新事务。在 COMMIT 语句或 ROLLBACK 语句中指定 AND CHAIN 子句。指定 “AND NO CHAIN” 以显式拒绝 CHAIN 子句。这些语句也可以在使用 PL/pgSQL 的 PROCEDURE 中使用。
postgres=# create table t_chain(id int); CREATE TABLE postgres=# begin; BEGIN postgres=# insert into t_chain values(1); INSERT 0 1 postgres=# commit and chain; COMMIT postgres=# insert into t_chain values(2); INSERT 0 1 postgres=# rollback and chain; ROLLBACK postgres=# insert into t_chain values(3); INSERT 0 1 postgres=# commit; COMMIT postgres=# select * from t_chain; id ---- 1 3 (2 rows)
复制
在以 CHAIN 子句启动的事务中,事务隔离级别等属性与前一个事务保持一致。
postgres=# BEGIN ISOLATION LEVEL SERIALIZABLE ; BEGIN postgres=# COMMIT AND CHAIN ; COMMIT postgres=# SHOW transaction_isolation ; transaction_isolation ----------------------- serializable (1 row) postgres=# COMMIT ; COMMIT postgres=# SHOW transaction_isolation ; transaction_isolation ----------------------- read committed (1 row)
复制
1.4.COPY
对 COPY 语句进行了以下增强。
- COPY FROM
现在可以只存储与 COPY FROM 语句中指定的条件匹配的表数据。
$ echo "id,name,age,department,salary 1,John,28,HR,50000 2,Jane,34,IT,60000 3,Mark,25,HR,45000 4,Lisa,41,IT,80000 5,Paul,38,Finance,75000 6,Susan,32,Finance,72000">employees.csv postgres=# CREATE TABLE employees ( postgres(# id SERIAL PRIMARY KEY, postgres(# name VARCHAR(100), postgres(# age INT, postgres(# department VARCHAR(50), postgres(# salary INT postgres(# ); CREATE TABLE postgres=# COPY employees(id, name, age, department, salary) FROM /var/lib/postgresql/employees.csv' WITH (FORMAT CSV, HEADER TRUE, DELIMITER ',') WHERE age > 30; COPY 4 postgres=# select * from employees; id | name | age | department | salary ----+-------+-----+------------+-------- 2 | Jane | 34 | IT | 60000 4 | Lisa | 41 | IT | 80000 5 | Paul | 38 | Finance | 75000 6 | Susan | 32 | Finance | 72000 (4 rows)
复制
它可以通过 psql 命令的 \copy 命令类似地执行。
postgres=# \copy employees FROM '/var/lib/postgresql/employees.csv' WITH (FORMAT CSV, HEADER TRUE, DELIMITER ',') WHERE age <=30; COPY 2 postgres=# select * from employees; id | name | age | department | salary ----+-------+-----+------------+-------- 2 | Jane | 34 | IT | 60000 4 | Lisa | 41 | IT | 80000 5 | Paul | 38 | Finance | 75000 6 | Susan | 32 | Finance | 72000 1 | John | 28 | HR | 50000 3 | Mark | 25 | HR | 45000 (6 rows)
复制
- COPY FREEZE
对分区表执行 COPY FREEZE 语句会导致错误。此规范也适用于 PostgreSQL 11.2 及更高版本。
-- 非分区表 postgres=# begin; BEGIN postgres=# CREATE TABLE employees ( id SERIAL PRIMARY KEY, name VARCHAR(100), age INT, department VARCHAR(50), salary INT ); CREATE TABLE postgres=# copy employees FROM '/var/lib/postgresql/employees.csv' WITH (FORMAT CSV, HEADER TRUE, DELIMITER ',',freeze true); COPY 6 --分区表 postgres=# CREATE TABLE part1(c1 NUMERIC, c2 VARCHAR(10)) PARTITION postgres-# BY RANGE(c1) ; CREATE TABLE postgres=# CREATE TABLE part1v1 PARTITION OF part1 FOR VALUES FROM postgres-# (0) TO (100) ; CREATE TABLE postgres=# CREATE TABLE part1v2 PARTITION OF part1 FOR VALUES FROM postgres-# (100) TO (200) ; CREATE TABLE postgres=# COPY part1 FROM '/var/lib/postgresql/employees.csv' CSV FREEZE ; ERROR: cannot perform COPY FREEZE on a partitioned table
复制
1.5.CREATE AGGREGATE
能够在 CREATE AGGREGATE 语句中使用 OR REPLACE 子句。
postgres=# CREATE OR REPLACE AGGREGATE sum_ints(int) ( sfunc = int4pl, -- Function to accumulate sum (addition) stype = int4 -- State type is integer ); CREATE AGGREGATE postgres=# CREATE TABLE test_numbers ( num int ); CREATE TABLE INSERT INTO test_numbers (num) VALUES (1), (2), (3), (4), (5); INSERT 0 5 postgres=# SELECT sum_ints(num) FROM test_numbers; sum_ints ---------- 15 (1 row)
复制
1.6.CREATE COLLATION
可以将 DETERMINISTIC 指定为 CREATE COLLATION 语句中的附加选项。此参数的默认值为 TRUE。
postgres=# CREATE COLLATION my_collation ( postgres(# LC_COLLATE = 'en_US.UTF-8', postgres(# LC_CTYPE = 'en_US.UTF-8', postgres(# PROVIDER = 'icu', postgres(# DETERMINISTIC = TRUE, postgres(# VERSION = '1.0' postgres(# ); WARNING: collation "my_collation" has version mismatch DETAIL: The collation in the database was created using version 1.0, but the operating system provides version 153.120. HINT: Rebuild all objects affected by this collation and run ALTER COLLATION public.my_collation REFRESH VERSION, or build PostgreSQL with the right library version. CREATE COLLATION postgres=# \dO List of collations Schema | Name | Collate | Ctype | Provider | Deterministic? --------+--------------+-------------+-------------+----------+---------------- public | my_collation | en_US.UTF-8 | en_US.UTF-8 | icu | yes (1 row)
复制
1.7.CREATE INDEX
- 创建 GiST 索引
include 现在可用于 GiST 索引。
postgres=# CREATE TABLE data2(c1 INT, c2 box, c3 VARCHAR(10)) ; CREATE TABLE postgres=# CREATE INDEX idx1_data2 ON data2 USING gist (c2) INCLUDE (c1) ; CREATE INDEX postgres=# \d data2 Table "public.data2" Column | Type | Collation | Nullable | Default --------+-----------------------+-----------+----------+--------- c1 | integer | | | c2 | box | | | c3 | character varying(10) | | | Indexes: "idx1_data2" gist (c2) INCLUDE (c1)
复制
- GiST 索引和 VACUUM
空闲页面在 VACUUM 后可以重用。
- 创建 GIN 索引时的 WAL
创建GIN 索引时的 WAL 使用量显著减少。
1.8.CREATE STATISTICS
mcv 子句可以在 CREATE STATISTICS 语句中使用。此值表示多变量最常见值 (MCV)。它扩展常规 MCV 列表并跟踪最频繁的值组合。获取的统计信息存储在 pg_statistic_ext_data 目录的 stxmcv 列中。
postgres=# CREATE TABLE stat1 (c1 NUMERIC, c2 NUMERIC, c3 postgres(# VARCHAR(10)) ; CREATE TABLE postgres=# CREATE STATISTICS mcv_stat1(mcv) ON c1, c2 FROM postgres-# stat1 ; CREATE STATISTICS postgres=# insert into stat1 values(1,1,'a'); INSERT 0 1 postgres=# insert into stat1 values(2,2,'b'); INSERT 0 1 postgres=# analyze stat1; ANALYZE postgres=# select * from pg_statistic_ext_data\gx -[ RECORD 1 ]----+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- stxoid | 57387 stxdndistinct | stxddependencies | stxdmcv | \xc251a6e101000000020000000200a4060000a4060000020000001000000010000000ffffffff00000000020000001000000010000000ffffffff0000000004000000008001000400000000800200040000000080010004000000008002000000000000000000e03f000000000000d03f000000000000000000000000e03f000000000000d03f01000100
复制
1.9.CREATE TABLE
对 CREATE TABLE 语句进行了以下增强。
- GENERATED 列
生成列是根据表的计算结果定义为列的值。列定义时指定 GENERATED ALWAYS AS (calculation expression) STORED 语句。
postgres=# CREATE TABLE gen1(c1 VARCHAR(10), c2 VARCHAR(10), c3 VARCHAR(20) GENERATED ALWAYS AS (c1 || c2) stored); CREATE TABLE postgres=# \d gen1 Table "public.gen1" Column | Type | Collation | Nullable | Default --------+-----------------------+-----------+----------+------------------------------------------------------- c1 | character varying(10) | | | c2 | character varying(10) | | | c3 | character varying(20) | | | generated always as (((c1::text || c2::text))) stored
复制
不能直接在 INSERT 和 UPDATE 语句中为生成的列指定值。只有 DEFAULT 子句有效。
postgres=# insert into gen1 values('a','d'); INSERT 0 1 postgres=# insert into gen1 values('b','e','a'); ERROR: cannot insert into column "c3" DETAIL: Column "c3" is a generated column. postgres=# insert into gen1 values('b','e',default); INSERT 0 1 postgres=# select * from gen1; c1 | c2 | c3 ----+----+---- a | d | ad b | e | be (2 rows)
复制
生成的列值是在执行 INSERT 或 UPDATE 语句时计算的,计算的值是物理存储的。
postgres=# create extension pageinspect; CREATE EXTENSION postgres=# SELECT heap_page_items(get_raw_page('gen1', 0)) ; heap_page_items --------------------------------------------------------------- (1,8160,1,31,551,0,0,"(0,1)",3,2306,24,,,"\\x05610564076164") (2,8128,1,31,552,0,0,"(0,2)",3,2306,24,,,"\\x05620565076265") (3,8096,1,31,553,0,0,"(0,3)",3,2306,24,,,"\\x05620565076265") (3 rows)
复制
在上面的示例中,对于第一行显示 c1 列是 ‘a’ (= 0x61),c2 列是 ‘b’ (= 0x64),c3 列是 ‘ABCD’ (= 0x6164)。通过pg_attribute 字典的 attgenerated 列中显示 “s” 可以找到生成列。此外information_schema.column_column_usage 表是新添加的。
postgres=# SELECT attname, attgenerated FROM pg_attribute WHERE attrelid='gen1'::regclass and attname IN ('c1', 'c2', 'c3') ; attname | attgenerated ---------+-------------- c1 | c2 | c3 | s (3 rows) postgres=# SELECT * FROM information_schema.column_column_usage ; table_catalog | table_schema | table_name | column_name | dependent_column ---------------+--------------+------------+-------------+------------------ postgres | public | gen1 | c1 | c3 postgres | public | gen1 | c2 | c3 (2 rows)
复制
不能将生成列指定为分区键。并且无法定义依赖于其他生成列的生成列。
postgres=# CREATE TABLE pgen1(c1 INT, c2 INT, c3 INT GENERATED ALWAYS AS (c1 + c2) STORED) PARTITION BY RANGE(c3) ; ERROR: cannot use generated column in partition key LINE 1: ...NERATED ALWAYS AS (c1 + c2) STORED) PARTITION BY RANGE(c3) ; ^ DETAIL: Column "c3" is a generated column. postgres=# CREATE TABLE gen2 (c1 INT, c2 INT GENERATED ALWAYS AS (c1*2) STORED, c3 INT GENERATED ALWAYS AS (c2*2) STORED) ; ERROR: cannot use generated column "c2" in column generation expression LINE 1: ...AYS AS (c1*2) STORED, c3 INT GENERATED ALWAYS AS (c2*2) STOR... ^ DETAIL: A generated column cannot reference another generated column.
复制
- 分区表定义的 TABLESPACE 子句
现在,在创建分区表时启用 TABLESPACE 子句。在以前的版本中忽略了 TABLESPACE 子句。分区表的 TABLESPACE 子句的值在分区创建时成为默认表空间。
postgres=# create tablespace ts1 location '/var/lib/postgresql/ts1'; CREATE TABLESPACE postgres=# CREATE TABLE parttbs(c1 NUMERIC, c2 VARCHAR(10)) PARTITION BY LIST(c1) TABLESPACE ts1 ; CREATE TABLE postgres=# CREATE TABLE parttbsv1 PARTITION OF parttbs FOR VALUES IN (100) ; CREATE TABLE postgres=# \d+ parttbs Partitioned table "public.parttbs" Column | Type | Collation | Nullable | Default | Storage | Stats target | Description --------+-----------------------+-----------+----------+---------+----------+--------------+------------- c1 | numeric | | | | main | | c2 | character varying(10) | | | | extended | | Partition key: LIST (c1) Partitions: parttbsv1 FOR VALUES IN ('100') Tablespace: "ts1" postgres=# \d+ parttbsv1 Table "public.parttbsv1" Column | Type | Collation | Nullable | Default | Storage | Stats target | Description --------+-----------------------+-----------+----------+---------+----------+--------------+------------- c1 | numeric | | | | main | | c2 | character varying(10) | | | | extended | | Partition of: parttbs FOR VALUES IN ('100') Partition constraint: ((c1 IS NOT NULL) AND (c1 = '100'::numeric)) Tablespace: "ts1" Access method: heap
复制
- 分区表的 FOR VALUES 子句
现在可以在分区的 FOR VALUES 子句中指定公式或函数,而不仅是文本值。执行 CREATE TABLE 语句时,指定的公式只执行一次,计算值存储在表定义中。
postgres=# CREATE TABLE parttbsv2 PARTITION OF parttbs FOR VALUES IN (power(2,3)) ; CREATE TABLE postgres=# \d+ parttbsv2 Table "public.parttbsv2" Column | Type | Collation | Nullable | Default | Storage | Stats target | Description --------+-----------------------+-----------+----------+---------+----------+--------------+------------- c1 | numeric | | | | main | | c2 | character varying(10) | | | | extended | | Partition of: parttbs FOR VALUES IN ('8') Partition constraint: ((c1 IS NOT NULL) AND (c1 = '8'::numeric)) Tablespace: "ts1" Access method: heap
复制
- 对分区表的外键引用
分区表可以作为外键引用。
postgres=# CREATE TABLE fkey1(c1 INT PRIMARY KEY, c2 VARCHAR(10)) PARTITION BY RANGE(c1) ; CREATE TABLE postgres=# CREATE TABLE fkey1v1 PARTITION OF fkey1 FOR VALUES FROM (0) TO (1000000) ; CREATE TABLE postgres=# CREATE TABLE fkey1v2 PARTITION OF fkey1 FOR VALUES FROM (1000000) TO (2000000) ; CREATE TABLE postgres=# CREATE TABLE ref1(c1 INT REFERENCES fkey1(c1), c2 VARCHAR(10)) ; CREATE TABLE
复制
在 PostgreSQL 11 中,尝试创建 ref1 表时,出现 “ERROR: foreign key constraints are not supported on partitioned tables “错误。
- 索引的 VACUUM 处理
通过在 WITH 子句中指定 VACUUM_INDEX_CLEANUP = OFF,它将能够禁用索引的 VACUUM 进程。默认值为 ‘ON’,VACUUM 将像以前一样执行。指定 TOAST。对于 TOAST 表,VACUUM_INDEX_CLEANUP = OFF。
postgres=# CREATE TABLE vacuum1(c1 INT, c2 VARCHAR(10)) WITH (VACUUM_INDEX_CLEANUP = OFF) ; CREATE TABLE postgres=# insert into vacuum1 values(1,'a'); INSERT 0 1 postgres=# insert into vacuum1 values(2,'b'); INSERT 0 1 postgres=# insert into vacuum1 values(3,'c'); INSERT 0 1 postgres=# \d+ vacuum1 Table "public.vacuum1" Column | Type | Collation | Nullable | Default | Storage | Stats target | Description --------+-----------------------+-----------+----------+---------+----------+--------------+------------- c1 | integer | | | | plain | | c2 | character varying(10) | | | | extended | | Access method: heap Options: vacuum_index_cleanup=off postgres=# delete from vacuum1 where c1 in(1,2); DELETE 2 -- 创建表设置为 vacuum_index_cleanup=off,所以索引数据未清理 postgres=# vacuum vacuum1; VACUUM postgres=# select lp, t_xmin, t_xmax, t_ctid, infomask(t_infomask, 1) as infomask, infomask(t_infomask2, 2) as infomask2 from heap_page_items(get_raw_page('vacuum1', 0)); lp | t_xmin | t_xmax | t_ctid | infomask | infomask2 ----+--------+--------+--------+-----------------------------------------+----------- 1 | | | | | 2 | | | | | 3 | 568 | 0 | (0,3) | XMAX_INVALID|XMIN_COMMITTED|HASVARWIDTH | (3 rows) postgres=# SELECT * FROM bt_page_items('vacuum1_c1_idx', 1); itemoffset | ctid | itemlen | nulls | vars | data ------------+-------+---------+-------+------+------------------------- 1 | (0,1) | 16 | f | f | 01 00 00 00 00 00 00 00 2 | (0,2) | 16 | f | f | 02 00 00 00 00 00 00 00 3 | (0,3) | 16 | f | f | 03 00 00 00 00 00 00 00 (3 rows) -- vacuum 时添加选择index_cleanup on,索引数据被清理 postgres=# VACUUM (INDEX_CLEANUP on) vacuum1; VACUUM postgres=# SELECT * FROM bt_page_items('vacuum1_c1_idx', 1); itemoffset | ctid | itemlen | nulls | vars | data ------------+-------+---------+-------+------+------------------------- 1 | (0,3) | 16 | f | f | 03 00 00 00 00 00 00 00 (1 row) postgres=# select lp, t_xmin, t_xmax, t_ctid, postgres-# infomask(t_infomask, 1) as infomask, postgres-# infomask(t_infomask2, 2) as infomask2 postgres-# from heap_page_items(get_raw_page('vacuum1', 0)); lp | t_xmin | t_xmax | t_ctid | infomask | infomask2 ----+--------+--------+--------+-----------------------------------------+----------- 1 | | | | | 2 | | | | | 3 | 568 | 0 | (0,3) | XMAX_INVALID|XMIN_COMMITTED|HASVARWIDTH | (3 rows)
复制
- 截断表末尾的空块
VACUUM_TRUNCATE 已添加到表的属性中。确定在执行 VACUUM 时是否释放表末尾的截断空块。默认值为 ‘ON’,它像以前一样截断空白区域。当指定为 ‘OFF’ 时,不执行此操作。
postgres=# CREATE TABLE vacuum2(c1 INT, c2 VARCHAR(10)) WITH (VACUUM_TRUNCATE = OFF) ; CREATE TABLE postgres=# insert into vacuum2 values(1,'a'); INSERT 0 1 postgres=# insert into vacuum2 values(2,'b'); INSERT 0 1 postgres=# insert into vacuum2 values(3,'c'); INSERT 0 1 postgres=# select * from vacuum2; c1 | c2 ----+---- 1 | a 2 | b 3 | c (3 rows) postgres=# select lp, t_xmin, t_xmax, t_ctid, infomask(t_infomask, 1) as infomask, infomask(t_infomask2, 2) as infomask2 from heap_page_items(get_raw_page('vacuum2', 1)); ERROR: block number 1 is out of range for relation "vacuum2" postgres=# select lp, t_xmin, t_xmax, t_ctid, infomask(t_infomask, 1) as infomask, infomask(t_infomask2, 2) as infomask2 from heap_page_items(get_raw_page('vacuum2', 0)); lp | t_xmin | t_xmax | t_ctid | infomask | infomask2 ----+--------+--------+--------+-----------------------------------------+----------- 1 | 605 | 0 | (0,1) | XMAX_INVALID|XMIN_COMMITTED|HASVARWIDTH | 2 | 606 | 0 | (0,2) | XMAX_INVALID|XMIN_COMMITTED|HASVARWIDTH | 3 | 607 | 0 | (0,3) | XMAX_INVALID|XMIN_COMMITTED|HASVARWIDTH | (3 rows) postgres=# \d+ vacuum2 Table "public.vacuum2" Column | Type | Collation | Nullable | Default | Storage | Stats target | Description --------+-----------------------+-----------+----------+---------+----------+--------------+------------- c1 | integer | | | | plain | | c2 | character varying(10) | | | | extended | | Access method: heap Options: vacuum_truncate=off postgres=# delete from vacuum2; DELETE 3 postgres=# select lp, t_xmin, t_xmax, t_ctid, infomask(t_infomask, 1) as infomask, infomask(t_infomask2, 2) as infomask2 from heap_page_items(get_raw_page('vacuum2', 0)); lp | t_xmin | t_xmax | t_ctid | infomask | infomask2 ----+--------+--------+--------+----------------------------+-------------------- 1 | 605 | 608 | (0,1) | XMIN_COMMITTED|HASVARWIDTH | UPDATE_KEY_REVOKED 2 | 606 | 608 | (0,2) | XMIN_COMMITTED|HASVARWIDTH | UPDATE_KEY_REVOKED 3 | 607 | 608 | (0,3) | XMIN_COMMITTED|HASVARWIDTH | UPDATE_KEY_REVOKED (3 rows) postgres=# select * from vacuum2; c1 | c2 ----+---- (0 rows) postgres=# select lp, t_xmin, t_xmax, t_ctid, infomask(t_infomask, 1) as infomask, infomask(t_infomask2, 2) as infomask2 from heap_page_items(get_raw_page('vacuum2', 0)); lp | t_xmin | t_xmax | t_ctid | infomask | infomask2 ----+--------+--------+--------+-------------------------------------------+-------------------- 1 | 605 | 608 | (0,1) | XMAX_COMMITTED|XMIN_COMMITTED|HASVARWIDTH | UPDATE_KEY_REVOKED 2 | 606 | 608 | (0,2) | XMAX_COMMITTED|XMIN_COMMITTED|HASVARWIDTH | UPDATE_KEY_REVOKED 3 | 607 | 608 | (0,3) | XMAX_COMMITTED|XMIN_COMMITTED|HASVARWIDTH | UPDATE_KEY_REVOKED (3 rows) -- 表选项 VACUUM_TRUNCATE = OFF,表未截断空快 postgres=# vacuum vacuum2; VACUUM postgres=# select lp, t_xmin, t_xmax, t_ctid, infomask(t_infomask, 1) as infomask, infomask(t_infomask2, 2) as infomask2 from heap_page_items(get_raw_page('vacuum2', 0)); lp | t_xmin | t_xmax | t_ctid | infomask | infomask2 ----+--------+--------+--------+----------+----------- 1 | | | | | 2 | | | | | 3 | | | | | (3 rows) -- vacuum指定truncate选项后,表末尾空快被截断 postgres=# vacuum (truncate) vacuum2; VACUUM postgres=# select lp, t_xmin, t_xmax, t_ctid, infomask(t_infomask, 1) as infomask, infomask(t_infomask2, 2) as infomask2 from heap_page_items(get_raw_page('vacuum2', 0)); ERROR: block number 0 is out of range for relation "vacuum2"
复制
1.10.EXPLAIN
现在可以在 EXPLAIN 语句中指定 SETTINGS ON 选项。此选项输出与正在从默认值更改的执行计划相关的参数的信息。
postgres=# SET random_page_cost = 1.0 ; SET ^ postgres=# \d data1 Table "public.data1" Column | Type | Collation | Nullable | Default --------+---------+-----------+----------+----------------------------------- id | integer | | not null | nextval('data1_id_seq'::regclass) col1 | bytea | | | Indexes: "data1_pkey" PRIMARY KEY, btree (id) postgres=# postgres=# EXPLAIN (SETTINGS ON) SELECT * FROM data1 WHERE id=100 ; QUERY PLAN ------------------------------------------------------------------------- Index Scan using data1_pkey on data1 (cost=0.15..2.17 rows=1 width=36) Index Cond: (id = 100) Settings: random_page_cost = '1' (3 rows)
复制
1.11.REINDEX CONCURRENTLY
现在可以将 CONCURRENTLY 选项添加到 REINDEX 语句中。通过减小锁定范围,可以使应用程序操作与重新索引共存。此功能是通过临时创建新索引 ({index_name}_ccnew) 并将其替换为旧索引来实现的。
postgres=# REINDEX (VERBOSE) TABLE CONCURRENTLY data1; INFO: index "public.data1_pkey" was reindexed INFO: index "pg_toast.pg_toast_40966_index" was reindexed INFO: table "public.data1" was reindexed DETAIL: CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.17 s. REINDEX
复制
根据 REINDEX 语句的更改,reindexdb 命令中也添加了 --concurrently 选项。
$ reindexdb --dbname postgres --echo --concurrently SELECT pg_catalog.set_config('search_path', '', false); REINDEX DATABASE CONCURRENTLY postgres; WARNING: cannot reindex system catalogs concurrently, skipping al
复制
1.12.PL/pgSQL 附加检查
现在可以为参数 plpgsql.extra_warnings 指定以下值都可以在执行函数时输出其他警告或错误。
- 指定值为 strict_multi_assignment
当 SELECT INTO 语句输出的列数与输入变量数不匹配时,会发出警告。在下面的示例中,函数中出现两个警告。
postgres=# SET plpgsql.extra_warnings = 'strict_multi_assignment'; SET postgres=# CREATE OR REPLACE FUNCTION strict1() postgres-# RETURNS void postgres-# LANGUAGE plpgsql postgres-# AS $$ postgres$# DECLARE postgres$# x INTEGER ; postgres$# y INTEGER ; postgres$# BEGIN postgres$# SELECT 1 INTO x, y ; postgres$# SELECT 1, 2, 3 INTO x, y ; postgres$# END ; postgres$# $$ ; CREATE FUNCTION postgres=# SELECT strict1() ; WARNING: number of source and target fields in assignment does not match DETAIL: strict_multi_assignment check of extra_warnings is active. HINT: Make sure the query returns the exact list of columns. WARNING: number of source and target fields in assignment does not match DETAIL: strict_multi_assignment check of extra_warnings is active. HINT: Make sure the query returns the exact list of columns. strict1 --------- (1 row)
复制
- 指定值为 too_many_rows
当 SELECT INTO 语句返回多条记录时,将生成错误,并且该过程的执行将停止。
postgres=# SET plpgsql.extra_errors to 'too_many_rows' ; SET postgres=# DO $$ DECLARE x INTEGER ; BEGIN SELECT generate_series(1,2) INTO x ; RAISE NOTICE 'test output' ; END ; $$ ; ERROR: query returned more than one row HINT: Make sure the query returns a single row, or use LIMIT 1. CONTEXT: PL/pgSQL function inline_code_block line 4 at SQL statement
复制
1.13.VACUUM / ANALYZE
VACUUM 和 ANALYZE 语句中添加了以下功能。
- SKIP_LOCKED
在锁定的表上执行 VACUUM 或 ANALYZE 语句时,它一直在等待释放锁定。在 PostgreSQL 12 中,添加了一个选项 SKIP_LOCKED 子句来跳过锁定的表。跳过处理时,将输出 WARNING 级别(自动 VACUUM 的 LOG 级别)日志。即使跳过 SQLSTATE,也被视为成功。
--SESSION 1 postgres=# begin; BEGIN postgres=# LOCK TABLE data1 IN EXCLUSIVE MODE ; LOCK TABLE --SESSION 2 postgres=# VACUUM (SKIP_LOCKED) data1; WARNING: skipping vacuum of "data1" --- lock not available VACUUM postgres=# \echo :SQLSTATE 00000
复制
- 选项规范语法
在 VACUUM 语句和 ANALYZE 语句中,现在可以指定使用 TRUE/FALSE 或 ON/OFF 执行的操作。
postgres=# VACUUM (VERBOSE OFF, FULL ON, ANALYZE ON) data1 ; VACUUM postgres=# VACUUM (VERBOSE TRUE, FULL TRUE, ANALYZE FALSE) data1 ; INFO: vacuuming "public.data1" INFO: "data1": found 0 removable, 2 nonremovable row versions in 1 pages DETAIL: 0 dead row versions cannot be removed yet. CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s. VACUUM
复制
- 将 VACUUM 作为索引选项
通过在 VACUUM 语句中指定 OFF to INDEX_CLEANUP 子句,将能够抑制索引的 VACUUM 进程。如果省略此规范,则操作取决于 table 的 VACUUM_INDEX_CLEANUP 属性。
postgres=# VACUUM (VERBOSE ON, INDEX_CLEANUP OFF) data1 ; INFO: vacuuming "public.data1" INFO: "data1": found 2 removable, 0 nonremovable row versions in 1 out of 1 pages DETAIL: 0 dead row versions cannot be removed yet, oldest xmin: 754 There were 0 unused item identifiers. Skipped 0 pages due to buffer pins, 0 frozen pages. 0 pages are entirely empty. CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s. INFO: vacuuming "pg_toast.pg_toast_40966" INFO: "pg_toast_40966": found 0 removable, 0 nonremovable row versions in 0 out of 0 pages DETAIL: 0 dead row versions cannot be removed yet, oldest xmin: 755 There were 0 unused item identifiers. Skipped 0 pages due to buffer pins, 0 frozen pages. 0 pages are entirely empty. CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s. VACUUM
复制
- 在表末尾禁止进行自由页截断处理
TRUNCATE 子句已添加到 VACUUM 语句中。通过为此属性指定 OFF,可以在表的末尾禁止自由页删除处理。如果省略,则取决于 table 的 VACUUM_TRUNCATE 属性。
postgres=# VACUUM (VERBOSE ON, TRUNCATE OFF) vacuum2; INFO: vacuuming "public.vacuum2" INFO: "vacuum2": removed 90 row versions in 1 pages INFO: "vacuum2": found 90 removable, 678 nonremovable row versions in 4 out of 4 pages DETAIL: 0 dead row versions cannot be removed yet, oldest xmin: 768 There were 0 unused item identifiers. Skipped 0 pages due to buffer pins, 0 frozen pages. 0 pages are entirely empty. CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s. VACUUM postgres=# postgres=# postgres=# VACUUM (VERBOSE ON, TRUNCATE on) vacuum2; INFO: vacuuming "public.vacuum2" INFO: "vacuum2": found 0 removable, 678 nonremovable row versions in 4 out of 4 pages DETAIL: 0 dead row versions cannot be removed yet, oldest xmin: 768 There were 90 unused item identifiers. Skipped 0 pages due to buffer pins, 0 frozen pages. 0 pages are entirely empty. CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s. INFO: "vacuum2": truncated 4 to 3 pages DETAIL: CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s VACUUM
复制
1.14.WITH SELECT
之前版本中 WITH 子句中指定的公共表表达式 (CTE) 都是 MATERIALIZED。在 PostgreSQL 12 中,默认行为已更改为 NOT MATERIALIZED。为了更改这些行为,可以在 WITH 子句中指定 MATERIALIZED 或 NOT MATERIALIZED。指定 NOT MATERIALIZED 子句允许将 WHERE 子句的规范下推到 WITH 子句中。在下面的示例中,使用 NOT MATERIALIZED 子句表明选择了索引搜索,并且成本降低了。
-- WITH NOT MATERIALIZED postgres=# EXPLAIN analyze WITH s AS NOT MATERIALIZED (SELECT * FROM data1) SELECT * FROM s WHERE id=100 ; QUERY PLAN ------------------------------------------------------------------------------------------------------------------- Index Scan using data1_pkey on data1 (cost=0.29..8.30 rows=1 width=36) (actual time=0.016..0.017 rows=1 loops=1) Index Cond: (id = 100) Planning Time: 0.061 ms Execution Time: 0.028 ms (4 rows) -- WITH MATERIALIZED postgres=# EXPLAIN analyze WITH s AS MATERIALIZED (SELECT * FROM data1) SELECT * FROM s WHERE id=100 ; QUERY PLAN ---------------------------------------------------------------------------------------------------------------- CTE Scan on s (cost=130.00..332.50 rows=45 width=36) (actual time=0.028..2.136 rows=1 loops=1) Filter: (id = 100) Rows Removed by Filter: 8999 CTE s -> Seq Scan on data1 (cost=0.00..130.00 rows=9000 width=36) (actual time=0.011..0.801 rows=9000 loops=1) Planning Time: 0.055 ms Execution Time: 2.296 ms (7 rows)
复制
1.15.Functions
添加/增强了以下功能。
- SQL/JSON
提供了 SQL 2016 标准中提出的一些与 SQL/JSON 相关的功能。
jsonb_path_query_array
postgres=# SELECT jsonb_path_query_array('{"a":[1,2,3,4,5]}','$.a[*] ? (@ >= $min && @ <= $max)', '{"min":2,"max":4}') ; jsonb_path_query_array ------------------------ [2, 3, 4] (1 row)
复制
添加了以下函数。
JSON/SQL 函数
函数名称 | 描述 |
---|---|
jsonb_path_exists | Checks whether the JSON path returns any item for the specified JSON value. |
jsonb_path_match | Returns JSON path predicate result for the specified JSON value. Only the first result item is taken into account. |
jsonb_path_query | Gets all JSON items returned by JSON path for the specified JSON value. |
jsonb_path_query_array | Gets all JSON items returned by JSON path for the specified JSON value and wraps result into an array. |
jsonb_path_query_first | Gets the first JSON item returned by JSON path for the specified JSON value. |
- pg_partition_tree
pg_partition_tree 是显示分区表的树状结构的功能。它还支持分层分区结构。在参数中指定分区表。指定分区表或分区以外的对象名称将返回 NULL。
postgres=# SELECT * FROM pg_partition_tree('part1') ; relid | parentrelid | isleaf | level ---------+-------------+--------+------- part1 | | f | 0 part1v1 | part1 | t | 1 part1v2 | part1 | t | 1 (3 rows) postgres=# SELECT * FROM pg_partition_tree('part1v1') ; relid | parentrelid | isleaf | level ---------+-------------+--------+------- part1v1 | part1 | t | 0 (1 row) postgres=# SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total FROM pg_partition_tree('part1') ; total ------- 32 kB (1 row) postgres=# SELECT * FROM pg_partition_tree('data1') ; relid | parentrelid | isleaf | level -------+-------------+--------+------- (0 rows)
复制
- pg_partition_root
pg_partition_root 是一个函数,用于返回指定分区的顶级分区表名称。在以下示例中,创建了一个子分区并执行了 pg_partition_root 函数。
postgres=# CREATE TABLE part2(c1 NUMERIC, c2 NUMERIC, c3 VARCHAR(10)) PARTITION BY LIST(c1) ; CREATE TABLE postgres=# CREATE TABLE part2v1 PARTITION OF part2 FOR VALUES IN (100) PARTITION BY LIST (c2) ; CREATE TABLE postgres=# CREATE TABLE part2v1v1 PARTITION OF part2v1 FOR VALUES IN (200) ; CREATE TABLE postgres=# SELECT pg_partition_root('part2v1v1') ; pg_partition_root ------------------- part2 (1 row)
复制
- pg_partition_ancestors
pg_partition_ancestors 函数将列表打印到包含指定分区的分区表的父级。
postgres=# CREATE TABLE part3(c1 NUMERIC, c2 VARCHAR(10)) PARTITION BY LIST(c1) ; CREATE TABLE ^ postgres=# CREATE TABLE part3v1 PARTITION OF part3 FOR VALUES IN (100) ; CREATE TABLE postgres=# SELECT pg_partition_ancestors('part3v1') ; pg_partition_ancestors ------------------------ part3v1 part3 (2 rows)
复制
- pg_promote
此函数将备用实例提升为主实例。以前需要执行 pg_ctl promote 命令。设置是否等待的参数(默认为 true)和等待的秒数(默认为 60 秒)。如果处理失败或未在等待时间内完成提升主库,则此函数返回 false,否则返回 true。
-- 只能在recovery的库执行 postgres=# SELECT pg_promote(true, 90) ; pg_promote ------------ t (1 row)
复制
- pg_ls_tmpdir
添加了 pg_ls_tmpdir 函数,以返回已保存临时数据的文件名列表。在参数中指定 TABLESPACE 的 OID。如果省略,则假定指定了 pg_default。此功能需要 SUPERUSER 权限或 pg_monitor 角色。
postgres=# SELECT * FROM pg_ls_tmpdir() ; name | size | modification ------------------+-----------+------------------------ pgsql_tmp36911.6 | 148955136 | 2024-10-04 11:57:36-04 pgsql_tmp37050.0 | 139722752 | 2024-10-04 11:57:36-04 pgsql_tmp37051.0 | 138403840 | 2024-10-04 11:57:36-04 (3 rows)
复制
- pg_ls_archive_statusdir
新增 pg_ls_archive_statusdir 功能,用于获取归档文件的状态。此函数搜索 ${PGDATA}/pg_wal/archive_status 目录,并输出文件名、大小和修改日期。它不会输出存档的 WAL 文件的实际信息。此功能需要 SUPERUSER 权限或 pg_monitor 角色。
postgres=# SELECT * FROM pg_ls_archive_statusdir() ; name | size | modification -------------------------------+------+------------------------ 00000001000000000000000D.done | 00000001000000000000000E.done | 00000001000000000000000F.done | (3 rows)
复制
- date_trunc
此函数现在可以设置 Timezone。
postgres=# SELECT date_trunc('hour', TIMESTAMP WITH TIME ZONE '2025-01-24 20:38:40+00', 'Asia/Tokyo') ; date_trunc ------------------------ 2025-01-24 20:00:00+00 (1 row)
复制
- unnest
unnest 函数新增了support属性,优化器可以更准确的预估行。
PostgreSQL 11
postgres=# explain analyze select * from unnest(array[1,2,3]); QUERY PLAN ------------------------------------------------------------------------------------------------------- Function Scan on unnest (cost=0.00..1.00 rows=100 width=4) (actual time=0.043..0.043 rows=3 loops=1) Planning Time: 0.154 ms Execution Time: 0.080 ms (3 rows)
复制
PostgreSQL 12
postgres=# explain analyze select * from unnest(array[1,2,3]); QUERY PLAN ----------------------------------------------------------------------------------------------------- Function Scan on unnest (cost=0.00..0.03 rows=3 width=4) (actual time=0.004..0.005 rows=3 loops=1) Planning Time: 0.029 ms Execution Time: 0.013 ms (3 rows) postgres=# \sf unnest(anyarray); ERROR: expected a right parenthesis postgres=# \sf unnest(anyarray) CREATE OR REPLACE FUNCTION pg_catalog.unnest(anyarray) RETURNS SETOF anyelement LANGUAGE internal IMMUTABLE PARALLEL SAFE STRICT ROWS 100 SUPPORT array_unnest_support AS $function$array_unnest$function$
复制
- 双曲函数
添加了 SQL:standards 2016 中包含的以下双曲函数
函数名称 | 描述 |
---|---|
log10 | base 10 logarithm |
sinh | hyperbolic sine |
cosh | hyperbolic cosine |
tanh | hyperbolic tangent |
asinh | inverse hyperbolic sine |
acosh | inverse hyperbolic cosine |
atanh | inverse hyperbolic tangent |
postgres=# SELECT log10(100), sinh(1) ; log10 | sinh -------+-------------------- 2 | 1.1752011936438014 (1 row)
复制
- 拷贝复制槽
提供了创建现有复制槽副本的函数。pg_copy_physical_replication_slot 函数和 pg_copy_logical_replication_slot 函数根据复制槽的类型提供。使用的复制槽才能创建副本。
postgres=# SELECT pg_create_physical_replication_slot('slot_1') ; pg_create_physical_replication_slot ------------------------------------- (slot_1,) (1 row) postgres=# SELECT pg_copy_physical_replication_slot('slot_1','slot_c') ; ERROR: cannot copy a replication slot that doesn't reserve WAL
复制
2.配置参数
在 PostgreSQL 12 中以下参数已更改。
2.1.增加参数
参数名称 | 描述 | 默认值 |
---|---|---|
archive_cleanup_command | Migrate from recovery.conf (sighup) | - |
data_sync_retry (Also added to 11.2) | Behavior when fsync system call fails (postmaster) | off |
default_table_access_method | Default storage engine name (user) | heap |
log_statement_sample_rate | Rate of output of SQL statement to log (superuser) | 1 |
plan_cache_mode | Changed the behavior of caching execution plans (user) | auto |
primary_conninfo | Migration from recovery.conf file (postmaster) | - |
primary_slot_name | Migrate from recovery.conf (postmaster) | - |
promote_trigger_file | Migrate from recovery.conf (sighup) | - |
recovery_end_command | Migrate from recovery.conf (sighup) | - |
recovery_min_apply_delay | Migrate from recovery.conf (sighup) | 0 |
recovery_target | Migrate from recovery.conf (postmaster) | - |
recovery_target_action | Migrate from recovery.conf (postmaster) | pause |
recovery_target_inclusive | Migrate from recovery.conf (postmaster) | on |
recovery_target_lsn | Migrate from recovery.conf (postmaster) | - |
recovery_target_name | Migrate from recovery.conf (postmaster) | - |
recovery_target_time | Migrate from recovery.conf (postmaster) | - |
recovery_target_timeline | Migrate from recovery.conf (postmaster) | latest |
recovery_target_xid | Migrate from recovery.conf (postmaster) | - |
restore_comand | Migrate from recovery.conf (postmaster) | - |
shared_memory_type | Type of shared memory (postmaster) | OS depend |
ssl_library | Name of library providing SSL function (internal) | - |
ssl_max_protocol_version | Maximum version of SSL protocol to support | - |
ssl_min_protocol_version | Minimum version of SSL protocol to support (sighup) | TLSv1 |
tcp_user_timeout | TCP timeout specification (user) | 0 |
wal_init_zero | Fill-in WAL file to zero (superuser) | on |
wal_recycle | Recycle WAL File (superuser) | on |
- primary_conninfo
指定主实例的连接字符串。之前是在 recovery.conf 文件中指定的。application_name 项的默认值通常是 “walreceiver”,但是当指定 cluster_name 参数时,cluster_name的值已更改为默认值。pg_stat_replication 中 application_name 列的值将更改。
- ssl_library
此参数指示提供 SSL 功能的库的名称。在 Red Hat Enterprise Linux 环境中执行 configure 命令时,如果指定了 --with-openssl,则参数值为 “OpenSSL”。
postgres=# show ssl_library ; ssl_library ------------- OpenSSL (1 row)
复制
- shared_memory_type
此参数指定共享内存的类型(例如 shared_buffers)。
参数名称 | 描述 | 默认值 |
---|---|---|
mmap | Use an anonymous memory map. | mmap |
sysv | Use System V shared memory. | shmget |
windows | Use Windows shared memory. | CreateFileMapping |
此参数在 Linux 上的默认值为 mmap。这与 PostgreSQL 9.3 及更高版本的行为相同。非常小的 System V 共享内存和大多数共享内存是使用内存映射文件 (mmap) 配置的。将此参数设置为 sysv 允许您恢复到 PostgreSQL 9.2 之前的行为。在这种情况下,请使用 System V 共享内存配置所有共享内存。
- plan_cache_mode
此参数设置缓存准备好的语句(由 PREPARE 语句创建)的执行计划的方法。默认值为 auto,这与以前的版本的行为相同。通常,每次 EXECUTE 语句执行 PREPARE 语句创建的 SQL 语句时,都会生成一个执行计划。在下面的示例中,可以看到执行计划根据 EXECUTE 语句中指定的参数而变化。它表示存储在 C2 列中的数据不均匀,plan0 数据很少(执行索引搜索),并且 plan1 数据很多(搜索整个表)。
postgres=> PREPARE sel1(VARCHAR) AS SELECT * FROM plan1 WHERE c2=$1 ; PREPARE postgres=> EXPLAIN EXECUTE sel1('plan0') ; QUERY PLAN ----------------------------------------------------------------------- Index Scan using idx1_plan1 on plan1 (cost=0.42..4.44 rows=1 width=12) Index Cond: ((c2)::text = 'plan0'::text) (2 rows) postgres=> EXPLAIN EXECUTE sel1('plan1') ; QUERY PLAN ---------------------------------------------------------------- Seq Scan on plan1 (cost=0.00..17906.01 rows=1000001 width=12) Filter: ((c2)::text = 'plan1'::text) (2 rows)
复制
如果执行相同的 SQL 语句 5 次或更多次,则可能会缓存执行计划,即使下次更改参数,也可以使用缓存的执行计划(通用执行计划)。在下面的示例中,执行计划中的显示在执行第 6 个 EXPLAIN 语句时从文本值更改为 $1。
postgres=> EXPLAIN ANALYZE EXECUTE sel1('plan1') ; --执行5次 QUERY PLAN ---------------------------------------------------------------- Seq Scan on plan1 (cost=0.00..23311.01 rows=1000001 width=12) Filter: ((c2)::text = 'plan1'::text) (2 rows) postgres=> EXPLAIN ANALYZE EXECUTE sel1('plan1') ; --第5次 QUERY PLAN ---------------------------------------------------------------- Seq Scan on plan1 (cost=0.00..23311.01 rows=1000001 width=12) Filter: ((c2)::text = ($1)::text) (2 rows)
复制
新添加的参数 plan_cache_mode 会更改此行为。将参数值设置为 “force_custom_plan” 会关闭执行计划缓存。另一方面,将参数值设置为 “force_generic_plan” 会立即启用执行计划缓存。
postgres=> EXPLAIN ANALYZE EXECUTE sel1('plan1') ; -- Repeat 5 times QUERY PLAN ---------------------------------------------------------------- Seq Scan on plan1 (cost=0.00..23311.01 rows=1000001 width=12) Filter: ((c2)::text = 'plan1'::text) (2 rows) postgres=> EXPLAIN ANALYZE EXECUTE sel1('plan1') ; -- Sixth (execution plan changed) QUERY PLAN ---------------------------------------------------------------- Seq Scan on plan1 (cost=0.00..23311.01 rows=1000001 width=12) Filter: ((c2)::text = ($1)::text) (2 rows)
复制
- data_sync_retry
此参数确定在检查点期间发出的 fsync 系统调用失败时会发生什么情况。在以前的版本中,fsync 函数被重新执行 (data_sync_retry = “on”),如果 fsync 系统调用失败,新版本的默认行为 (data_sync_retry = “off”) 会导致实例因 PANIC 而停止。此参数是从 PostgreSQL 11.2 开始添加的。
2.2.修改参数
更改了以下配置参数的设置范围和选项。
参数名称 | 描述 |
---|---|
client_min_messages | It is no longer possible to set it to a higher level than ERROR. |
dynamic_shared_memory_type | The setting value “none” has been deleted. |
log_autovacuum_min_duration | Log output contents now change according to VACUUM execution status. |
log_connections | Application_name information has been added to the log. |
plpgsql.extra_warnings | The following parameter values have been added: |
-too_many_rows | |
-strict_multi_assignme | |
trace_sort | The log output message has been changed. |
wal_level | It is now checked for proper level at startup. |
wal_sender_timeout | The context has been changed from sighup to user. |
default_with_oids | It cannot be set to “on”. |
recovery_target_timeline | “Current” has been added as a setting value, the default value has been changed to “latest”. |
autovacuum_vacuum_cost_delay | Data type changed from integer to real. |
不能从 pg_settings 目录中引用 default_with_oids 参数。
postgres=# show default_with_oids; default_with_oids ------------------- off (1 row) postgres=# select * from pg_settings where name ~'default_with_oids'\gx (0 rows) postgres=# alter system set default_with_oids='on'; ERROR: tables declared WITH OIDS are not supported
复制
- wal_sender_timeout
用户可以按会话更改此参数。这允许在流复制环境中基于每个连接更改从库的参数。
PostgreSQL 11
postgres=# set wal_sender_timeout to '2min'; ERROR: parameter "wal_sender_timeout" cannot be changed now
复制
PostgreSQL 12
postgres=# set wal_sender_timeout to '2min'; SET
复制
$ grep primary_conninfo data/postgresql.conf primary_conninfo = 'host=host1 port=5432 user=postgres password=password options=''-c wal_sender_timeout=5000'''
复制
- log_connections
当此参数设置为 ‘on’ 时,application_name 参数的值将添加到输出的日志中。
Connection from psql command LOG: connection authorized: user=postgres database=postgres application_name=psql Connection from pg_basebackup command LOG: replication connection authorized: user=postgres application_name=pg_baseback Connection from Streaming Replication slave instance LOG: replication connection authorized: user=postgres application_name=walreceiver
复制
- trace_sort
当此参数设置为 ‘on’ 时,输出日志格式已更改。
PostgreSQL 11
LOG: -1 switching to external sort with 16 tapes: CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s LOG: -1 using 3951 KB of memory for read buffers among 15 input tapes LOG: performsort of -1 done (except 15-way final merge): CPU: user: 0.15 s, system: 0.01 s, elapsed: 0.16 s
复制
PostgreSQL 12
LOG: performsort of worker -1 starting: CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s LOG: internal sort of worker -1 ended, 25 KB used: CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s
复制
- wal_level
使用复制槽时,需要检查 wal_level 参数在实例启动期间是否为适当的值。如果未设置需要的级别,实例启动将失败。
在 Logical Replication 环境中更改wal_level 为 “minimal”,并重新启动实例报错:
postgres=# ALTER SYSTEM SET wal_level=minimal ; ALTER SYSTEM postgres=# \q $ $ pg_ctl -D data restart waiting for server to shut down.... done server stopped waiting for server to start....2025-02-04 00:52:19.890 EDT [22682] FATAL: WAL archival cannot be enabled when wal_level is "minimal" stopped waiting pg_ctl: could not start server Examine the log output. $
复制
2.3.参数默认值修改
以下配置参数的默认值已更改。
参数名称 | PostgreSQL 11 | PostgreSQL 12 | 备注 |
---|---|---|---|
autovacuum_vacuum_cost_delay | 20 | 2 | |
extra_float_digits | 0 | 1 | |
jit | off | on | |
recovery_target_timeline | current | latest | |
server_version | 11.22 | 12.22 | |
server_version_num | 110022 | 120020 |
参考
《PostgreSQL_12_GA_New_Features_en_20191011-1》