首页 > 数据库 >PostgreSQL 存储结构

PostgreSQL 存储结构

时间:2023-09-05 15:07:08浏览次数:57  
标签:存储 PostgreSQL postgres 数据库 oid pg test maleah 结构

存储结构

一、逻辑存储结构

逻辑存储结构通常指表、索引、视图、函数等逻辑对象(也称数据库对象)

PostgreSQL 存储结构_存储结构

创建一个 Database时会为这个Database创建一个名为public的默认Schema。每个Database可以有多个Schema,在这个数据库中创建其他数据库对象时如果没有指定Schema,都会在public这个Schema中。Schema可以理解为一个数据库中的命名空间,在数据库中创建的所有对象都在Schema中创建,一个用户可以从同一个客户端连接中访问不同的Schema。不同的Schema中可以有多个相同名称的Table、Index、View、Sequence,Function等数据库对象。

参考数据库对象

二、物理存储结构

物理存储结构表示数据库在物理层面上是如何存储的。

在初始化initdb数据库集簇(database cluster)时会在指定目录下创建基础目录(即通常所说的数据目录,会被配置到环境变量PGDATA中)。所有相关组成数据库的物理文件的分布:

PostgreSQL 存储结构_存储结构_02

PostgreSQL 存储结构_postgresql_03

子目录/文件

描述

base

默认的数据库目录

global

数据库集簇中的所有表

pg_commmit_ts

事务提交的时间戳目录

pg_dynshmem

动态共享内存目录

pg_logical

逻辑解码的状态数据

pg_multixact

多个事务的状态目录

pg_notify

包含系统发出的 LISTEN/NOTIFY 的目录

pg_replslot

复制槽目录

pg_serial

已提交的可序列化事务的信息目录

pg_snapshots

快照目录(pg_export_snapshot函数导出的快照信息文件)

pg_stat

统计目录

pg_stat_tmp

临时统计目录

pg_subtrans

子事务的状态数据

pg_tblspc

各个用户自建表空间指向的软链接符号目录

pg_twophase

两阶段提交目录

pg_wal

wal segment 目录

pg_xact

事务提交状态的目录

pg_hba.conf

基于主机的认证配置文件,用于配置允许哪些IP的主机通过哪种方式访问数据库

pg_ident.conf

基于主机的映射文件

PG_VERSION

包含PostgreSQL主版本号

postgresql.auto.conf

存储使用 ALTER SYSTEM修改的配置参数

postgresql.conf

默认的数据库参数文件

postmaster.opts

记录服务器上次启动时的使用的命令行参数

postmaster.pid

当前数据库运行的进程文件

下面介绍一些常用的的目录及文件

1、base 目录

1.1 概述

base目录存储用户创建的数据库文件,及隶属于用户数据库的所有关系,比如表、索引等

1.2 一级目录

PostgreSQL 存储结构_存储结构_04

postgres=# SELECT oid,datname from pg_database;
  oid  |  datname
-------+------------
 13892 | postgres
 16385 | maleah_test     -- 自己建的数据库
     1 | template1
 13891 | template0
 16408 | db_new_tsp   -- 在自建的表空间里的数据库(下文有详细介绍)
(5 rows)
1.3 二级文件

存储某个数据库内的所有关系,包括表、索引、视图等。

二级子文件分为三大类:

  • oid命名的主数据文件;
  • _fsm结尾的空闲空间映射文件;
  • _vm结尾的可见性映射文件。
-- 以 上图中的 1247 为例:1247是普通表 pg_type 的oid
postgres=# select oid,relname,relkind from pg_class where oid = 1247;
 oid  | relname | relkind
------+---------+---------
 1247 | pg_type | r
(1 row)
--- relkind 值为 r:表示普通表

pg_class 表参考

  • 主数据文件(具体介绍请看第三节堆表文件的内部布局
  • FSM(FREE SPACE MAP) - 空闲空间映射文件
  • 存储相应表或索引文件中每个页面上的空闲空间信息。hash索引除外
  • 详情可查看src/backend/storage/freespace/README
  • 可使用扩展 pg_freespace 查看特定表或索引上的空闲空间信息。
maleah_test=> \c maleah_test postgres
You are now connected to database "maleah_test" as user "postgres".
maleah_test=# create extension pg_freespacemap ;
CREATE EXTENSION
maleah_test=# create table tab_fsm(id int,name varchar);
CREATE TABLE
maleah_test=# insert into tab_fsm select id,md5(id::varchar) from generate_series(1,10000) as id;
INSERT 0 10000
maleah_test=# select *,round(100*avail/8192 ,2) as "freespace ratio" from pg_freespace('tab_fsm') where avail !=0;
 blkno | avail | freespace ratio
-------+-------+-----------------
    83 |  5440 |           66.00
(1 row)

详情可查看官网:pg_freespacemap扩展

  • VM(VISIBILITY MAP)可见性映射文件
  • 存储页面的可见性信息,包含所有活跃事务的元组,也包含需要冻结的一些元组
  • 可使用扩展 pg_freespace 查看
maleah_test=# create extension pg_visibility ;
CREATE EXTENSION
maleah_test=# create table tab_vm as select * from tab_fsm ;
SELECT 10000
-- 删除前
maleah_test=# select * from pg_visibility_map('tab_vm') where blkno = 0;
 blkno | all_visible | all_frozen
-------+-------------+------------
     0 | t           | f
-- 删除 id<100 的元组
maleah_test=# delete from tab_vm where id<100;
DELETE 99
-- 删除后重新查看:all_visible t-->f,此时元组不可见
maleah_test=# select * from pg_visibility_map('tab_vm') where blkno = 0;
 blkno | all_visible | all_frozen
-------+-------------+------------
     0 | f           | f
(1 row)

详情可查看 pg_visibility扩展

  • 每一个堆元组都存储两位:如果第一位被设置,那么表示页面都是可见的,既然可见,那么该页面不包含任何清理的元组信息。索引扫描可以使用索引元组及逆行查询。如果第二位被设置,那么vacuum将会跳过所有的页面访问,提高vacuum的速度。

/* src/backend/access/heap/visibilitymap.c */

The visibility map is a bitmap with two bits (all-visible and all-frozen)per heap page.

  • A set all-visible bit means that all tuples on the page areknown visible to all transactions, and therefore the page doesn’t need tobe vacuumed.
  • A set all-frozen bit means that all tuples on the page arecompletely frozen, and therefore the page doesn’t need to be vacuumed evenif whole table scanning vacuum is required (e.g. anti-wraparound vacuum).The all-frozen bit must be set only when the page is already all-visible.
  • 索引没有可见性映射文件,只有空闲空间映射文件

2、global 目录

2.1 概述

存储pg_control及数据库集群维度的数据库及其关系,非客户维度的数据

PostgreSQL 存储结构_存储结构_05

maleah_test=# select oid,relname,relkind from pg_class where oid = 6115 ;
 oid  |            relname            | relkind
------+-------------------------------+---------
 6115 | pg_subscription_subname_index | i
(1 row)
2.2 pg_control文件

pg_control文件记录数据库集群控制信息,包括initdb初始化、WAL和checkpoint的信息

3、pg_wal 目录

3.1 概述

pg_wal是WAL机制中的wal日志存储目录

PG 版本

目录名

<10

pg_xlog

>=10

pg_wal

3.2 WAL(write ahead log) 机制

数据库重做日志。从名字上看也可以简单的理解为,在数据写入磁盘前先记录日志。

3.3 文件结构

PostgreSQL 存储结构_postgresql_06

PostgreSQL 存储结构_postgresql_07

  • wal segment 文件(wal段文件)
  • 存储着数据库行记录明细,每一条记录明细都是服务于数据库恢复操作的,确保前后数据一致。首先针对数据的任意一次修改操作均被记录在wal段文件中,包括insert、update和delete,其次系统的一些管理行为也会被记录在wal段文件中,例如事务提交和vacuum等行为。
  • 文件名:26个十六进制数由三部分组成

PostgreSQL 存储结构_postgresql_08

LSN(Log Sequnce Number)日志序列号:记录 wal 日志的绝对位置,是一个不断增长的8字节(64 bit )的长数字

  • 注意区分数据库log日志文件和wal文件。从内容上:数据库日志是记录数据库层面上的操作,比如记录启动数据库等操作(记录日志的内容可自行定义),而 针对数据的任意一次修改操作均被记录在wal段文件中。从作用上:数据库日志-当系统发生错误时可以从 log 中查找 error,并解决问题;而wal日志用于数据库备份恢复及流复制等,与Oracle中的Redo Log功能相同。
  • 文件大小:默认16MB,可以在initdb时通过--wal-segments选项来配置wal文件大小
  • .history
    .history文件内容包括原.history文件,当前时间线切换记录和切换原因,作用于数据库的时间点恢复行为。当数据库引擎从多个时间线的备份中恢复时,数据库从.history文件中找到从pg_control的start_timeline到指定的recovery_target_timeline间的所有wal段文件进行恢复。
  • archive_status 目录
    archive_status是wal段文件的备份目录,包括.ready和.done文件。超出wal_keep_segments数目限制的wal日志会在archive_status目录内被标记,归档操作完成后被进一步移除。
  • .ready
    .ready是同名wal段文件在archive_status目录内的标记文件,代表该wal段文件可被归档。wal段文件在数据目录中的存储文件数量是有上限的,可以通过wal_keep_size 参数来约束,因此数据库引擎在wal段文件个数达到上限后会在archive_status目录内增加可移除的wal段文件的标记文件,文件名是原wal段文件名后增加.ready后缀,等待归档工具进行归档。
  • .done
    .done是同名wal段文件在archive_status目录内的标记文件,代表该wal段文件已被归档,可以被清理。数据库引擎默认通过archive_command命令对.ready文件进行归档,归档成功与否取决于archive_command命令返回true还是false,当archive_command返回true时,代表与.ready文件同名的wal段文件已被归档,引擎再将该文件的扩展名重命名为.done,等待数据库引擎在下一次的checkpoint时进一步清理原wal段文件

4、pg_xact 目录

4.1 概述

事务提交日志存储目录,默认256KB

4.2 commit log

PostgreSQL 存储结构_存储结构_09

事务提交日志存储数据库的单个事务运行状态。Commit Log由共享内存中一组8KB的page组成,每个page包含一列数组,每个数组元素包含XID和该事物的实时状态。当page不足时,创建新的page来存储新的事务。

5、配置文件

  • postgresql.conf
    数据库初始化时默认的配置文件
  • postgresql.auto.conf
    存储使用 ALTER SYSTEM修改的配置参数,优先级别高于postgresql.conf文件
  • pg_hba.conf
    pg_hba.conf文件负责客户端的连接和认证,起到防火墙的作用。格式:TYPE DATABASE USER ADDRESS METHOD

三、表空间的布局

3.1 默认的表空间

在PG中最大的逻辑存储单位是表空间。

数据库默认的表空间由两个:pg_defaultpg_global

pg_default表口昂间的物理文件位置在数据目录的base目录,是template0 和 template1 数据库的默认表空间。

postgres=# select oid,spcname from pg_tablespace;
 oid  |  spcname
------+------------
 1663 | pg_default
 1664 | pg_global
(2 rows)

postgres=# create table tab_default_tsp(id int,name varchar);
CREATE TABLE
-- reltablespace=0,表示使用的是默认表空间
postgres=# select oid,relname,relfilenode,reltablespace from pg_class where relname = 'tab_default_tsp';
  oid  |     relname     | relfilenode | reltablespace
-------+-----------------+-------------+---------------
 16391 | tab_default_tsp |       16391 |             0
(1 row)
  • 所有创建的数据库,如果没有明确指定表空间,那么使用默认的表空间 pg_default。用于管理整个数据库集群的表默认被存储在pg_global表空间中。
create database maleah_test owner maleah;

postgres=# SELECT db.oid,db.datname,tsp.spcname from pg_database db inner join pg_tablespace tsp on db.dattablespace=tsp.oid where db.datname = 'maleah_test';
  oid  | datname  |  spcname
-------+----------+------------
 16385 | maleah_test | pg_default
(1 row)
  • 用于管理整个数据库集群的表(系统表)默认被存储在pg_global表空间中;pg_global表空间的物理位置为$PGDATA\global目录。
  • pg_global不能被当作默认的表空间

3.2 用户创建的表空间

执行CREATE TABLESPACE语句会在指定的目录下创建表空间,在该目录下还会创建版本特定的子目录。版本特定的命名方式为**PG_主版本号_目录版本号**

PostgreSQL 存储结构_postgresql_10

用户创建的表空间对应一个目录

--# 在 /soft/pg14/data6000/maleah_tsp_test 目录下创建了 maleah_tsp_test 表空间
postgres=# create tablespace maleah_tsp_test owner maleah location '/soft/pg14/data6000/maleah_tsp_test';
CREATE TABLESPACE

--# 新建的表空间对应的 oid = 16397
postgres=# select oid,spcname from pg_tablespace;
  oid  |   spcname
-------+--------------
  1663 | pg_default
  1664 | pg_global
 16397 | maleah_tsp_test
(3 rows)

--# 在目录下创建了版本特定的子目录-PG_14_202107181
postgres=# \! ls -l /soft/pg14/data6000/maleah_tsp_test
total 0
drwx------. 2 postgres postgres 6 Jan 20 17:20 PG_14_202107181 

--# $PGDATA/pg_tblspc 目录下有与新建表空间oid相同的符号链接指向实际的表空间目录
postgres=# \! ls -l $PGDATA/pg_tblspc
total 0
lrwxrwxrwx. 1 postgres postgres 32 Jan 20 17:20 16397 -> /soft/pg14/data6000/maleah_tsp_test

--#1. 在新建的表空间 maleah_tsp_test 下创建 tab_new_tsp 表
postgres=# create table tab_new_tsp(id int,name varchar) tablespace maleah_tsp_test;
CREATE TABLE

---# tab_new_tsp 表的所属表空间为 maleah_tsp_test
postgres=# select oid,relname,relfilenode,reltablespace from pg_class where relname = 'tab_new_tsp';
  oid  |   relname   | relfilenode | reltablespace
-------+-------------+-------------+---------------
 16403 | tab_new_tsp |       16403 |         16397
(1 row)

---# 使用 pg_relation_filepath 函数查找该表对应的目录
postgres=# select pg_relation_filepath('tab_new_tsp');
            pg_relation_filepath
---------------------------------------------
 pg_tblspc/16397/PG_14_202107181/13892/16403
(1 row)

--#2. 在新建的表空间 maleah_tsp_test 下创建 db_new_tsp 数据库
create database db_new_tsp owner maleah tablespace maleah_tsp_test;

---# 数据库对应的 oid=16408
postgres=# select oid,datname,datdba,dattablespace from pg_database where datname = 'db_new_tsp';
  oid  |  datname   | datdba | dattablespace
-------+------------+--------+---------------
 16408 | db_new_tsp |  16384 |         16397
(1 row)

---# 在版本特定的子目录下创建相应的数据库目录
postgres=# \! ls -l $PGDATA/maleah_tsp_test/PG_14_202107181 | grep 16408
drwx------. 2 postgres postgres 8192 Jan 20 17:47 16408

四、表和索引相关文件的布局

4.1 数据库相关知识

  • 任何的新初始化数据库都有一个统一的存放目录 base 用来存放默认的数据库:postgres、template1、template0。
postgres=# SELECT oid,datname,datdba from pg_database ;
  oid  |  datname   | datdba
-------+------------+--------
 13892 | postgres   |     10
     1 | template1  |     10
 13891 | template0  |     10
 16408 | db_new_tsp |  16384
(4 rows)

postgres=# \! ls -l $PGDATA/base
total 48
drwx------. 2 postgres postgres 8192 Jan 12 18:02 1
drwx------. 2 postgres postgres 8192 Jan 12 18:02 13891
drwx------. 2 postgres postgres 8192 Jan 20 17:26 13892
  • 当创建数据库时不指定TEMPLATE,将使用默认模板数据库template1
  • 在数据库中有一个特殊的数据类型叫做 oid(object identifier)对象标识符,每个数据库都有对应的唯一的 oid 值。整个数据库结构和数据库对象都是通过 oid来管理的。

4.2 表在数据库中的管理

创建一张表 tab_test,oid=16414

postgres=# \c maleah_test maleah
You are now connected to database "maleah_test" as user "maleah".
maleah_test=> create table tab_test (id int,name varchar);
CREATE TABLE

maleah_test=> select oid,relname,relfilenode from pg_class where relname = 'tab_test';
  oid  | relname  | relfilenode
-------+----------+-------------
 16414 | tab_test |       16414
(1 row)

maleah_test=> select pg_relation_filepath('tab_test');
 pg_relation_filepath
----------------------
 base/16385/16414
(1 row)
  • 默认不会给创建的空表分配空间,只分配一个文件名称
maleah_test=> \! ls -l $PGDATA/base/16385/16414
-rw-------. 1 postgres postgres 0 Jan 20 18:24 /soft/pg14/data6000/base/16385/16414
  • 在第一次执行INSERT操作后,将会分配一个页面的大小(8K)
maleah_test=> insert into tab_test values(1,'maleah');
INSERT 0 1
maleah_test=> \! ls -l $PGDATA/base/16385/16414
-rw-------. 1 postgres postgres 8192 Jan 20 18:32 /soft/pg14/data6000/base/16385/16414
  • 表在内部通过oid管理,外部通过refilenode管理
    注:表的 oid 不一定等于 refilenode,如下
# 对表进行 truncate 操作
maleah_test=> truncate TABLE tab_test ;
TRUNCATE TABLE
# 表的 oid 不等于 filenode,表的 filenode 的值发生改变
maleah_test=> select oid,relname,relfilenode from pg_class where relname = 'tab_test';
  oid  | relname  | relfilenode
-------+----------+-------------
 16414 | tab_test |       16419
(1 row)

# 查询表的存储位置 - 以 filenode 为名的文件
maleah_test=> select pg_relation_filepath('tab_test');
 pg_relation_filepath
----------------------
 base/16385/16419
(1 row)
# 此时表的 oid和 filenode 的目录下的文件都为空
maleah_test=> \! ls -l $PGDATA/base/16385/16414
-rw-------. 1 postgres postgres 0 Jan 20 18:34 /soft/pg14/data6000/base/16385/16414
maleah_test=> \! ls -l $PGDATA/base/16385/16419
-rw-------. 1 postgres postgres 0 Jan 20 18:34 /soft/pg14/data6000/base/16385/16419

# 插入数据
maleah_test=> insert into tab_test values(1,'maleah');
INSERT 0 1

# 以 oid 命名的文件大小仍为0,filenode命名为文件大小为 8K
maleah_test=> \! ls -l $PGDATA/base/16385/16414
-rw-------. 1 postgres postgres 0 Jan 20 18:34 /soft/pg14/data6000/base/16385/16414
maleah_test=> \! ls -l $PGDATA/base/16385/16419
-rw-------. 1 postgres postgres 8192 Jan 20 18:35 /soft/pg14/data6000/base/16385/16419
  • 表默认单个文件大小为1G。如果超过1G,将会使用relfilenode.编号(编号从1开始)来命名新的文件,直到新文件填满1G,以此类推。也可以在编译时使用 --eith-segsize来指定

五、堆表文件的内部布局

在PostgreSQL中,

  • page - 保存在磁盘中的块
  • buffer - 内存中的块
  • relation - 表和索引
  • tuple - 行

数据的读写是以 page为最小单位,每个page默认大小 8kB

5.1 堆表文件的页面布局

PostgreSQL 存储结构_存储结构_11

表的页面包含三种类型的数据:

  • 堆元组(heap tuples) :堆元组就是数据记录本身。它们从页面底部开始依序堆叠
  • 行指针(line pointer):每个行指针占4个字节,保存着指向堆元组的指针。它们也被称为项目指针(item pointer)。行指针简单地组织为一个数组,扮演了元组索引的角色。每个索引项从1开始依次编号,称为偏移号(offset number)。当向页面中添加新元组时,一个相应的新行指针也会被放入数组中,并指向新添加的元组。
  • 首部数据(header data):页面的起始位置分配了由结构PageHeaderData定义的首部数据。它的大小为24个字节,包含关于页面的元数据。该结构的主要成员变量为:

成员变量

描述

pd_lsn

该页面最近一次变更所写入XLOG记录对应的LSN。它是一个8字节无符号整数,62位,保存两个32位的值,高位为xlogid,低位记录偏移量

pd_checksum

页面的校验和

pd_flags

标记位(数据页面中的格式化的空间或未格式化的空间)

pd_lower

空闲空间的起始位置

pd_upper

空间空间的结束位置

pd_special

特殊空间的偏移量

pd_pagesize_version

页面的大小以及页面的版本编号

pd_prune_xid

页面中最老元组的xid

/* @src/include/storage/bufpage.h */

在 bufpage.h 文件中查看标准的页面定义

PostgreSQL 存储结构_存储结构_12

5.2 使用 pg_filedump 工具分析

maleah_test=# select pg_relation_filepath('tab_test');
 pg_relation_filepath
----------------------
 base/16385/16451
(1 row)

PostgreSQL 存储结构_postgresql_13

maleah_test=# select * from tab_test ;
 id |    name
----+------------
  1 | maleah
  1 | PostgreSQL
(2 rows)
-- 显示格式化的块内容转储
[postgres@node1 pg_filedump]$ ./pg_filedump -d $PGDATA/base/16385/16451 | tail -n 10
  1f90: 00000000 00000000 00000000 00000000  ................
  1fa0: 00000000 00000000 00000000 00000000  ................
  1fb0: 00000000 00000000 fd020000 00000000  ................
  1fc0: 00000000 00000000 02000200 02091800  ................
  1fd0: 01000000 17506f73 74677265 53514c00  .....PostgreSQL.
  1fe0: fc020000 00000000 00000000 00000000  ................
  1ff0: 01000200 02091800 01000000 096c6d6a  .............maleah

标签:存储,PostgreSQL,postgres,数据库,oid,pg,test,maleah,结构
From: https://blog.51cto.com/u_13482808/7372211

相关文章

  • postgresql 查看表格占用空间
    http://www.linuxmysql.com/14/2022/1182.htmselectpg_size_pretty(pg_tablespace_size('pg_default'));selectpg_size_pretty(pg_relation_size('account_move_line'));selectsum(t.size)from(SELECTtable_schema||'.'||table_......
  • 华为SAN存储在Red Hat系统下的主机连通性FAQ
    1、建立iSCSI连接后,主机系统无法重启现象主机系统和存储系统建立iSCSI连接后,主机系统重启失败。根因分析主机停止iSCSI服务时,session没有关掉。解决方案主机系统重启前,请先停止iSCSI服务,然后再重启主机。2、替换LUN后无法更新LUN的信息现象当替换LUN的时候(前后两个LUN使......
  • 数据结构复习——王道考研
    数据结构一.绪论1.1基本概念数据元素:数据元素是数据的基本单位,通常作为一个整体进行考虑和处理。一个数据元素可由若干数据项组成,数据项是构成数据元素的不可分割的最小单位。例如,学生记录就是一个数据元素,它由学号、姓名、性别等数据项组成。数据类型:是相互之间存在一种或......
  • nginx负载均衡结构示例
    Linux系统-部署-运维系列导航 使用说明nginx负载均衡需要使用stream模块,支持HTTP与TCP服务。此处仅说明负载均衡的配置结构,具体参数请自行查阅相关资料。 Nginx负载均衡策略nginx自有策略轮询(默认)权重(weight)IP地址哈希(ip_hash)最小连接数(least_conn......
  • 医学影像(PACS)源码,影像的获取、处理、存储、调阅、检索、管理
    医学影像(PACS)系统主要进行病人信息和影像的获取、处理、存储、调阅、检索、管理,并通过网络向全院提供病人检查影像及诊断报告;各影像科室之间共享不同设备的病人检查影像及诊断报告;在诊断工作站上,调阅HIS中病人的其它信息(如:病人信息、病历信息、医嘱、检验信息等)。系统包括:1、预......
  • Redis数据结构
    5种基础数据结构:String(字符串)、List(列表)、Set(集合)、Hash(散列)、Zset(有序集合)。这5种数据结构是直接提供给用户使用的,是数据的保存形式,其底层实现主要依赖这8种数据结构:简单动态字符串(SDS)、LinkedList(双向链表)、HashTable(哈希表)、SkipList(跳跃表)、Intset(整数集合)、ZipLis......
  • js处理树形结构数据过滤
    最近项目经常遇到后台接口返回整个树形结构,而前端展示只需要展示部分类型的数据,需要过滤一下,所以整理了一个过滤方法。非层级结构时过滤非常简单,只需要一层代码就够了exportfunctionfilterTree(tree){returntree.filter(item=>item.type===0)}而要做到子节点也过滤......
  • go channel 内部结构
            参考:https://blog.csdn.net/QiuHaoqian/article/details/108999754......
  • 2.4 PE结构:节表详细解析
    节表(SectionTable)是WindowsPE/COFF格式的可执行文件中一个非常重要的数据结构,它记录了各个代码段、数据段、资源段、重定向表等在文件中的位置和大小信息,是操作系统加载文件时根据节表来进行各个段的映射和初始化的重要依据。节表中的每个记录则被称为IMAGE_SECTION_HEADER,它记......
  • 2023-09-05:请用go语言编写。一个图像有n个像素点,存储在一个长度为n的数组arr里, 每个像
    2023-09-05:请用go语言编写。一个图像有n个像素点,存储在一个长度为n的数组arr里,每个像素点的取值范围[0,s]的整数,请你给图像每个像素点值加上一个整数k(可以是负数),像素值会自动截取到[0,s]范围,当像素值<0,会更改为0,当新像素值>s,会更改为s,这样就可以得到新的arr,想让所有像素点的......