pageinspect提供函数可以查看数据库页面的内容,对于问题排查、故障处置都很有用。 所有函数默认只能被超级用户使用。
插件名为 pageinspect
插件版本 V1.7
CREATE EXTENSION pageinspect;
无需配置任何参数。
插件提供以下函数:
get_raw_page(relname text, fork text, blkno int) returns bytea
get_raw_page读取指定关系、指定fork的指定块并以bytea二进制的形式返回页面数据。这允函数可以获得该块在某一时刻一致的副本。fork字符对应关系:'main'对应数据;'fsm'对应FSM空闲空间页面;'vm'对应VM可见性页面;'init'对应初始页面。
get_raw_page(relname text, blkno int) returns bytea
用于读取数据fork的简化版get_raw_page。等效于get_raw_page(relname, 'main', blkno)。
page_header(page bytea) returns record
page_header显示使用标准页面结构的堆表、索引页面的页头信息。传入get_raw_page获得的页面数据作为参数page。
示例
SELECT * FROM page_header(get_raw_page('bmsql_warehouse', 0)); lsn | checksum | flags | lower | upper | special | pagesize | version | prune_xid ------------+----------+-------+-------+--------+---------+----------+---------+----------- 0/4A2D1BB0 | 0 | 5 | 1168 | -32768 | -32768 | -32768 | 5 | 0 (1 row)
返回的列对应页头结构PageHeaderData中的各个成员。
checksum存放页面的校验和,如果页面被损坏它可能是不正确的。如果当前实例没有开启页面校验和,输出的值没有实际意义。
page_checksum(page bytea, blkno int4) returns smallint
page_checksum计算页面的校验和。传入get_raw_page获得的页面数据作为参数page。
示例
SELECT page_checksum(get_raw_page('bmsql_warehouse', 0), 0); page_checksum --------------- -4188 (1 row)
注意校验和的计算和块号相关,因此应该传入和获取的页面的块号(除非在做调试)。
用这个函数计算的校验和可以用来和函数page_header的结果中的checksum进行比较。如果示例开启了页面校验和则两个值应该相等。
fsm_page_contents(page bytea) returns text
fsm_page_contents显示FSM页面的内容和结构,页面中二叉树结构每个节点会输出一行,只有不为0的节点输出。
示例
SELECT fsm_page_contents(get_raw_page('bmsql_warehouse', 'fsm', 0)); fsm_page_contents ------------------- 0: 251 + 1: 251 + 3: 251 + 7: 251 + 15: 251 + 31: 251 + 63: 251 + 127: 251 + 255: 251 + 511: 251 + 1023: 251 + 2047: 251 + 4095: 251 + 8191: 251 + 16383: 251 + fp_next_slot: 0 + (1 row)
heap_page_items(page bytea) returns setof record
heap_page_items显示一个堆表页面上所有的行指针,对于使用中的行指针,元组头部和元组原始数据也会被显示。 不管元组对于拷贝原始页面时的 MVCC 快照是否可见,它们都会被显示。
示例,二进制输出部分使用...省略
SELECT * from heap_page_items(get_raw_page('bmsql_warehouse', 'main', 0)); lp | lp_off | lp_flags | lp_len | t_xmin | t_xmax | t_field3 | t_ctid | t_infomask2 | t_infomask | t_hoff | t_bits | t_oid | t_data ----+--------+----------+--------+------------+--------+----------+--------+-------------+------------+--------+--------+-------+-------- ----------------------------------------------------------------------------------------------------------------------------------------- --------------------------------------------------------------- 1 | 32656 | 1 | 107 | 19554 | 0 | 0 | (0,1) | 9 | 11010 | 24 | | | \x01000 000... 2 | 32528 | 1 | 126 | 1073751330 | 0 | 1 | (0,2) | 9 | 11010 | 24 | | | \x04000 000... 3 | 32416 | 1 | 111 | 19560 | 0 | 0 | (0,3) | 9 | 11010 | 24 | | | \x02000 000... 4 | 32304 | 1 | 112 | 1073751331 | 0 | 0 | (0,4) | 9 | 11010 | 24 | | | \x03000 000... (4 rows)
tuple_data_split(rel_oid oid, t_data bytea, t_infomask integer, t_infomask2 integer, t_bits text [, do_detoast bool]) returns bytea[]
tuple_data_split以和backend内部相同的方式将元组数据分解成属性。用heap_page_items的返回值中的列作为参数传入。
示例
SELECT tuple_data_split('bmsql_warehouse'::regclass, t_data, t_infomask, t_infomask2, t_bits) from heap_page_items(get_raw_page('bmsql_warehouse', 'main', 0)); tuple_data_spli t ----------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------- {"\\x01000000","\\x130181b305b519141e","\\x0b7f82cb04","\\x15534b5446566736326c","\\x194a68376f6a666e49386f54","\\x1f68567546686535507a6 e437a3138","\\x1f4c784951666c76686e41456c4738","\\x074b42","\\x15313438363131313131"} {"\\x04000000","\\x130181e5011e188025","\\x0b7f826307","\\x134139776952324e55","\\x29797a394b3268737573616b396a4468686f4b58","\\x2b61555 0356e53334e75436151744370564856446b","\\x2b6e7531485439564d565a326a4c6e793341745a47","\\x074947","\\x15303438333131313131"} {"\\x02000000","\\x1301819d0283009001","\\x0b7f824a02","\\x1146796663456c6d","\\x21675837683771356d347569664f5134","\\x19436862434e39565 7313158","\\x29624a65364d4853617647325276645a57654331","\\x075a47","\\x15363339393131313131"} {"\\x03000000","\\x1301811e0399158c0a","\\x0b7f826304","\\x156e4c4459476e7a4c58","\\x236670356148667537417053544764555a","\\x1b706239506 e785273657a4166","\\x23523074447376417574496d4146726779","\\x074350","\\x15303132363131313131"} (4 rows)
heap_page_item_attrs(page bytea, rel_oid regclass [, do_detoast bool]) returns setof record
heap_page_item_attrs和heap_page_items效果相同,除了它会把元组的原始数据返回为属性数组,如果设置了do_detoast为true( 默认为false),属性会被反TOAST。
示例
SELECT * FROM heap_page_item_attrs(get_raw_page('bmsql_warehouse', 0), 'bmsql_warehouse'::regclass); lp | lp_off | lp_flags | lp_len | t_xmin | t_xmax | t_field3 | t_ctid | t_infomask2 | t_infomask | t_hoff | t_bits | t_oid | t_attrs ----+--------+----------+--------+------------+--------+----------+--------+-------------+------------+--------+--------+-------+-------- ----------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------- 1 | 32656 | 1 | 107 | 19554 | 0 | 0 | (0,1) | 9 | 11010 | 24 | | | {"\\x01 000000","\\x130181b305b519141e","\\x0b7f82cb04","\\x15534b5446566736326c","\\x194a68376f6a666e49386f54","\\x1f68567546686535507a6e437a313 8","\\x1f4c784951666c76686e41456c4738","\\x074b42","\\x15313438363131313131"} 2 | 32528 | 1 | 126 | 1073751330 | 0 | 1 | (0,2) | 9 | 11010 | 24 | | | {"\\x04 000000","\\x130181e5011e188025","\\x0b7f826307","\\x134139776952324e55","\\x29797a394b3268737573616b396a4468686f4b58","\\x2b615550356e533 34e75436151744370564856446b","\\x2b6e7531485439564d565a326a4c6e793341745a47","\\x074947","\\x15303438333131313131"} 3 | 32416 | 1 | 111 | 19560 | 0 | 0 | (0,3) | 9 | 11010 | 24 | | | {"\\x02 000000","\\x1301819d0283009001","\\x0b7f824a02","\\x1146796663456c6d","\\x21675837683771356d347569664f5134","\\x19436862434e395657313158" ,"\\x29624a65364d4853617647325276645a57654331","\\x075a47","\\x15363339393131313131"} 4 | 32304 | 1 | 112 | 1073751331 | 0 | 0 | (0,4) | 9 | 11010 | 24 | | | {"\\x03 000000","\\x1301811e0399158c0a","\\x0b7f826304","\\x156e4c4459476e7a4c58","\\x236670356148667537417053544764555a","\\x1b706239506e7852736 57a4166","\\x23523074447376417574496d4146726779","\\x074350","\\x15303132363131313131"} (4 rows)
bt_metap(relname text) 返回 record
bt_metap返回B树索引meta页面的信息。
示例
SELECT * FROM bt_metap('bmsql_warehouse_pkey'); magic | version | root | level | fastroot | fastlevel | oldest_xact | last_cleanup_num_tuples --------+---------+------+-------+----------+-----------+-------------+------------------------- 340322 | 4 | 1 | 0 | 1 | 0 | 0 | 4 (1 row)
bt_page_stats(relname text, blkno int) returns record
bt_page_stats返回指定B树索引指定块的页面统计信息。
示例
SELECT * FROM bt_page_stats('bmsql_warehouse_pkey', 1); blkno | type | live_items | dead_items | avg_item_size | page_size | free_size | btpo_prev | btpo_next | btpo | btpo_flags -------+------+------------+------------+---------------+-----------+-----------+-----------+-----------+------+------------ 1 | l | 4 | 0 | 16 | 32768 | 32632 | 0 | 0 | 0 | 3 (1 row)
bt_page_items(relname text, blkno int) returns setof record
bt_page_items返回指定B树索引指定块的页面中的所有索引项。
示例
SELECT * FROM bt_page_items('bmsql_warehouse_pkey', 1); itemoffset | ctid | itemlen | nulls | vars | data ------------+-------+---------+-------+------+------------------------- 1 | (0,1) | 16 | f | f | 01 00 00 00 00 00 00 00 2 | (0,3) | 16 | f | f | 02 00 00 00 00 00 00 00 3 | (0,4) | 16 | f | f | 03 00 00 00 00 00 00 00 4 | (0,2) | 16 | f | f | 04 00 00 00 00 00 00 00 (4 rows)
bt_page_items(page bytea) returns setof record
bt_page_items接收get_raw_page的输出作为参数,返回内容和上面的函数相同。
DROP EXTENSION pageinspect;
通过 ALTER EXTENSION升级插件。
示例,升级到 1.1:
ALTER EXTENSION pageinspect UPDATE TO '1.1';
passwordcheck插件主要用于管理口令复杂度。
口令的复杂度检查是由数据库安全员对口令的最小长度,所包含的数字、英文字母、特殊符号的数目进行设置后,在数据库管理员创建和修改用户时,自动对口令进行相关方面的检查。如果口令不满足指定的条件,那么创建用户将不成功。
KingbaseES通过插件的方式来进行口令的复杂度管理。这种方式更为灵活,当数据库的实用场景需要进行口令的复杂度管理时,加载插件即可。而不需要该功能时,卸载插件即可。
KingbaseES中通过 4 个全局级参数配合插件来实现用户口令复杂度管理。
插件名为 passwordcheck
插件版本 V1.0
在使用 passwordcheck 之前,我们需要将他添加到 kingbase.conf 文件的 shared_preload_libraries 中,并重启 KingbaseES 数据库。
示例:
shared_preload_libraries = 'passwordcheck'
passwordcheck.enable
口令复杂度开关,默认为关闭状态。
passwordcheck.password_length
口令的最小长度,取值范围为[8,63],缺省为 8。
passwordcheck.password_condition_letter
口令至少包含几个字母,取值范围为[2,61],缺省为 2。
passwordcheck.password_condition_digit
口令至少包含几个数字,取值范围为[2,61],缺省为 2。
passwordcheck.password_condition_punct
口令至少包含几个特殊字符,取值范围为[0,59],缺省为0。其中特殊符号为除空白符、英文字母、单引号和数字外的所有可见字符。
加载passwordcheck插件后,在数据库管理员创建和修改用户时,自动对口令进行相关方面的检查。如果口令不满足指定的条件,那么创建用户将不成功。当不需要该功能时,卸载插件即可。
示例:
-- 打开口令复杂度开关 \c test system create extension passwordcheck; CREATE EXTENSION \c test sso show passwordcheck.enable; passwordcheck.enable ---------------------- off (1 行记录) alter system set passwordcheck.enable=on; ALTER SYSTEM select sys_reload_conf(); sys_reload_conf ----------------- t (1 行记录) show passwordcheck.enable; passwordcheck.enable ---------------------- on (1 行记录) -- 修改口令最小长度为10 \c test sso SHOW passwordcheck.password_length; passwordcheck.password_length ------------------------------- 8 (1 row) SET passwordcheck.password_length = 10; SHOW passwordcheck.password_length; passwordcheck.password_length ------------------------------- 10 (1 row) \c test system CREATE USER u_pwd PASSWORD '123ab'; ERROR: password length 5 is too short, should be longer than min password length 10. CREATE USER u_pwd PASSWORD '1234567890ab'; CREATE ROLE -- 修改口令最少包含3个字母 \c test sso SHOW passwordcheck.password_condition_letter; passwordcheck.password_condition_letter ----------------------------------------- 2 (1 row) SET passwordcheck.password_condition_letter = 3; SHOW passwordcheck.password_condition_letter; passwordcheck.password_condition_letter ----------------------------------------- 3 (1 row) \c test system ALTER USER u_pwd PASSWORD '1234567890'; ERROR: Password should contain at least 3 letter and the current number is 0 ALTER USER u_pwd PASSWORD '1234567890ab'; ERROR: Password should contain at least 3 letter and the current number is 2 ALTER USER u_pwd PASSWORD '1234567890abC'; ALTER ROLE -- 修改口令最少包含3个数字 \c test sso SHOW passwordcheck.password_condition_digit; passwordcheck.password_condition_digit ---------------------------------------- 2 (1 row) SET passwordcheck.password_condition_digit = 3; SHOW passwordcheck.password_condition_digit; passwordcheck.password_condition_digit ---------------------------------------- 3 (1 row) \c test system ALTER USER u_pwd PASSWORD 'abcdefghij'; ERROR: Password should contain at least 3 digit and the current number is 0 ALTER USER u_pwd PASSWORD 'abcdefghij123'; ALTER ROLE -- 修改口令最少包含3个特殊字符 \c test sso SHOW passwordcheck.password_condition_punct; passwordcheck.password_condition_punct ---------------------------------------- 0 (1 row) SET passwordcheck.password_condition_punct = 2; SHOW passwordcheck.password_condition_punct; passwordcheck.password_condition_punct ---------------------------------------- 2 (1 row) \c test system ALTER USER u_pwd PASSWORD '1234567890abc.'; ERROR: Password should contain at least 2 punct and the current number is 1 ALTER USER u_pwd PASSWORD '1234567890abc./'; ALTER ROLE
修改 kingbase.conf 文件中shared_preload_libraries参数后重启数据库。
示例:
shared_preload_libraries = ''
passwordcheck扩展插件通常随着KingbaseES安装包一并升级。通常情况下用户无须单独升级插件。
passwordhistory插件主要用于管理口令历史。
口令的历史检查是由数据库管理员对初次设定的口令或更改过的口令使用天数进行设置后,在修改用户口令时,自动对口令已使用天数进行相关方面的检查。如果口令不满足指定的条件,那么更改口令将不成功。
KingbaseES通过插件的方式来进行口令历史管理。这种方式更为灵活,当数据库的实用场景需要进行口令历史管理时,加载插件即可。而不需要该功能时,卸载插件即可。
KingbaseES中通过 2 个全局级参数配合插件来实现用户口令历史管理。
插件名为 passwordhistory
插件版本 V1.0
在使用 passwordhistory 之前,我们需要将他添加到 kingbase.conf 文件的 shared_preload_libraries 中,并重启 KingbaseES 数据库。
示例:
shared_preload_libraries = 'passwordhistory'
passwordhistory.enable
密码历史开关,默认为关闭状态。
passwordhistory.password_time
设定口令历史天数,缺省为 0。
示例:
-- 创建插件并打开口令历史开关 create extension passwordhistory; CREATE EXTENSION show passwordhistory.enable; passwordhistory.enable ------------------------ off (1 行记录) alter system set passwordhistory.enable=on; ALTER SYSTEM select sys_reload_conf(); sys_reload_conf ----------------- t (1 行记录) show passwordhistory.enable; passwordhistory.enable ------------------------ on (1 行记录) -- 设定口令历史天数为2 show passwordhistory.password_time; passwordhistory.password_time ------------------------------- 0 (1 row) SET passwordhistory.password_time = 2; call sys_reload_conf(); sys_reload_conf ----------------- t (1 row) SHOW passwordhistory.password_time; passwordhistory.password_time ------------------------------- 2 (1 row) create user test with password '123'; CREATE ROLE alter user test with password '123'; ERROR: The password has been used recently.
记载passwordhistory插件后,在修改用户口令时,程序会自动对口令已使用天数进行相关方面的检查。如果口令不满足指定的条件,那么更改口令将不成功。
修改 kingbase.conf 文件中 shared_preload_libraries
参数后重启数据库。
示例:
shared_preload_libraries = ''
passwordhistory扩展插件通常随着KingbaseES安装包一并升级。通常情况下用户无须单独升级些插件。