从数据库捕获数据变化(Change Data Capture, CDC)是大多数企业的常见实践。然而,Postgres 的复制设计增加了高可用性(High Availability, HA)限制,并在操作层面引入了耦合,这些方式常常显得不现实。
首先,我们来看一种标准的 Postgres HA 集群拓扑:
pgoutput 从逻辑复制槽(Logical Replication Slot)读取数据;WAL 级别被设为 logical,备用库配置为 synchronous_standby_names = 'ANY 1 (r1, r2)',主库在至少一个 Standby 将变更写入后才会确认提交;逻辑复制槽是一个持久化的、与主库绑定的对象,包含两部分状态:
复制槽的存在会锁定主库上的 WAL 日志,直到 CDC 客户端推进状态。如果客户端延迟,WAL 日志会在主库中积累。这是预期行为。然而问题在于,当尝试实现 HA 时,系统的脆弱性就显现出来了。
Postgres 17 引入了逻辑复制槽故障转移功能,允许将复制槽状态同步到故障转移候选节点(备用库)。但备用库的槽资格有以下限制:
备用库上的逻辑复制槽是否准备好故障转移由以下三条件决定:
synced = true;temporary = false 且 invalidation_reason IS NULL。以下是一些明确的故障场景:
pg_basebackup),计划退役旧备用库。restart_lsn。Postgres 的设计方式使得故障转移非常敏感于复制进度:
pg_replication_slots 中记录,需依赖消费者连接并确认数据才会推进状态。这一设计保留了 CDC 的精准语义,但降低了 HA 的灵活性。
MySQL 的设计显著减少了上述耦合问题:
log_replica_updates=ON,以重新发出应用的事务至其自身 Binlog,从而保持 GTID 的连续性。log_replica_updates=ON。CDC 连接器持久了 GTID 位置,添加 MR3 后同步 GTIDs,即可立即故障转移。CDC 连接器指向任意副本并恢复。无需节点间镜像恢复,设计更灵活。Postgres 的逻辑消费者在高可用性中的脆弱点在于:复制槽进度是单节点关注点,故障转移时需整个集群协调,而槽资格依赖于订阅者的行为且难以控制。相比之下,MySQL 的设计消除了这种耦合,使故障转移灵活性大幅增强,同时提供了更加稳定的 HA 生态。
关注公众号:程序新视界,一个让你软实力、硬技术同步提升的平台
除非注明,否则均为程序新视界原创文章,转载必须以链接形式标明本文链接
]]>今天,我们正式推出了 PlanetScale for Postgres。在过去的数月里,我们持续专注于打造全球最佳的 Postgres 体验,其中包括优化性能。
为了确保我们的数据库性能符合高标准,我们需要采用一种标准化、可复现且公平的方法来测量和比较各种选择。我们开发了一款内部工具——Telescope——作为创建、运行和评估基准测试的主要工具。
凭借 Telescope,我们能够为工程师快速反馈产品性能的演变情况,并在开发和调优过程中确保指标符合预期。现在,我们决定将这项工作成果分享给全世界,同时提供工具让其他人也能复现我们的测试。
如果你想直接查看测试结果,可以点击以下链接:
以下是 PlanetScale 与其他 Postgres 供应商的性能对比简要概览:
性能基准测试的使用方式往往具有误导性,这适用于所有技术,而不仅仅是数据库。
任何形式的基准测试都存在局限性:
你无法仅通过查看一个基准测试结果就准确预测你的工作负载会表现得如何。
然而,高质量的基准测试对于解答以下问题非常有用:
这是我们在进行基准测试时试图回答的问题,并据此选择了三个主要测试工具:
SELECT 1; 语句。简单有效,用于确定基本查询路径延迟。在基准测试过程中,我们将自己的产品与一长名单上的其他云 Postgres 提供商进行了比较。我们力求使比较尽可能公平。
所有公开发布的基准测试均与 PlanetScale 运行在 i8g M-320 实例上的版本进行比较。该实例包括 4vCPUs、32GB 内存 和 937GB NVMe SSD 存储。这一实例规格及集群配置代表了真实生产应用中的典型配置,例如高 QPS,支持几千 QPS,同时保持低延迟和高可用性。
PlanetScale 的默认设置是分布在 3 个可用区(AZs) 中的一个主库和两个副本。多可用区配置对提供高可用数据库至关重要,同时副本可以应对显著的读负载。
我们为每个竞争对手的测试实例匹配或超过了 PlanetScale 主库的 vCPU 和 RAM:
所有被对比产品的底层存储均为 网络附加存储(NAS)。其中一些(如 Aurora、Neon 和 AlloyDB)不支持配置特定的 IOPS,也有一些支持(如 Supabase 和 TigerData),我们为其默认设置增加了 IOPS。
为了实现完全透明,以下是我们基准测试的具体条件:
TABLES=20 和 SCALE=250,生成约 500GB PostgreSQL 数据库。oltp_read_only 基准测试。SELECT 1;,测量每次查询的往返时间。我们的目标并非误导他人,而是向大家展示运行 Postgres 在 PlanetScale Metal 上所能获得的卓越性能。在我们的测试中,PlanetScale Metal 的 Postgres 性能无疑是最优选择。
关注公众号:程序新视界,一个让你软实力、硬技术同步提升的平台
除非注明,否则均为程序新视界原创文章,转载必须以链接形式标明本文链接
]]>本文内容仅适用于 Aurora,而不是 Aurora Serverless。Aurora Serverless 是一种不同的配置,其定价模式与传统 Aurora 有所不同。
Amazon Aurora 是 AWS 上兼容 MySQL 和 PostgreSQL 的数据库平台,可简化创建和管理 MySQL 数据库的过程。它简化了运行生产环境中 MySQL 数据库所需基础设施的配置,同时提供了许多标准 RDS 配置中没有的功能,例如自动故障转移、只读副本,以及在几乎没有停机的情况下扩展计算和存储资源的能力。
尽管如此,其定价结构并不像看上去那样简单清晰。考虑 Aurora 集群的定价时需要评估许多因素,尤其是在运行 MySQL 工作负载时。下面我们具体分析这些因素。
实例类型用于指定分配给底层 MySQL 计算节点的 CPU 和内存资源。
创建 Aurora 集群时,你最先需要选择的就是实例类型。对于没有背景知识的人来说,查看实例类型列表可能会感到困惑。不过,Amazon 采用了一种命名约定,可以用来解读名称的每个部分含义:
Aurora 定价示意图
实例类型的类别和尺寸将对最终费用产生显著影响。例如,下表比较了三个具有相同类别但尺寸不同的实例类型的费用:
| 实例类型 | vCPUs | 内存 (GiB) | 每小时费用 |
| db.x2g.large | 2 | 32 | $0.377 |
| db.x2g.4xlarge | 16 | 256 | $3.016 |
| db.x2g.16xlarge | 64 | 1024 | $12.064 |
Aurora 的实例类型分为两类:可突发和内存优化。可突发实例因日常负载下使用较少资源而有一定的成本优势,但在较高需求出现时可短时间“突发”以提升性能。这与内存优化实例形成了对比,后者性能稳定并一直满足其所宣传的配置。由于可突发实例的性能相较于内存优化实例不够稳定,Amazon 不推荐将其用于生产环境。
另一个需要考虑的因素是预付款购买计算节点的使用时段,称为“预留实例”。如果选择预付款购买 1 年或 3 年的预留实例时段,Amazon 会给予按需定价的折扣。折扣金额取决于合同期限和所选实例类型。若你能预估出需要多少实例以及使用时长,预留实例是一种降低 AWS 账单成本的好方法。
为生产环境数据库至少创建一个副本并将该副本与 Aurora 集群连接(放置在不同的可用区 AZ)是最佳实践。副本能够保证主写节点离线时更快速的故障转移,同时在执行需要重启的更新(如调整实例大小或配置参数)时减少停机时间。
因此,对于关键业务场景(任何停机可能导致显著财务损失或声誉风险),你需要考虑将一个主节点与两个副本放置于不同 AZ 中。然而,这种方案将有效地按副本数量增加你选定实例类型的成本,同时也提高了正确地管理副本位置和故障切换编排的运维工作量。
在 Amazon Aurora 中,存储的工作方式与 RDS 或基于 EC2 配置自己的数据库集群有所不同。后者依赖于底层的 EBS 卷,提供了多种选择。而 Aurora 使用专有存储设备,自动预划分“块”来存储数据,这种方式允许 Amazon 自动调整存储容量,而无需担心空间不足问题。
因此,存储配置选项仅限于标准存储和 I/O 优化存储两种。
选择标准存储时,你将根据使用的存储量和 IOPS 消耗来收费。而选择 I/O 优化存储则会提高实例类型的费用,但不收取 IOPS 费用。如果你的应用程序 I/O 密集型,则选择 I/O 优化存储可能反而降低总体费用。当 I/O 费用超过 Aurora 账单总成本的 25% 时,通常会出现显著节省。要做出最优选择,你需要充分了解应用的 I/O 需求,因为 Amazon 对两种存储配置均未明确推荐。
另一个需要考虑的指标是与你的 Aurora 集群之间传输的数据量。Amazon 会为多种场景中的数据传输收费,包括可用区之间的传输、跨区域的传输甚至向公有互联网进行的数据传输。具体收费金额依赖于使用的服务。
有些场景中 Amazon 不收取数据传输费用,例如在同一区域内进行数据复制或在同一可用区内 Aurora 节点与 EC2 实例之间的数据传输。而大多数其它场景都会产生额外的数据传输费用。确保你的应用程序托管区域与它所使用的副本在同一区域内可以帮助降低数据传输费用。
如果需要跨区域复制数据以接近用户,Global database 是 Aurora 集群的服务名称,它允许在另一个区域创建一个独立的只读 Aurora 集群,进行数据复制。每个区域可以独立扩展,因此根据该区域的计算要求选择合适的实例类型可优化成本。
使用 Global database 还需承担额外费用,首先,你需支付与主区域计算实例和存储相同的费用。此外,Amazon 还会对每 100 万次写操作以及跨区域复制的数据传输收取额外费用。
每个与 MySQL 数据库的连接都将消耗 CPU 和内存资源。
AWS 提供 RDS Proxy 作为数据库客户端与写节点/读节点计算资源之间的轻量代理层。RDS Proxy 不仅能够实现连接池,还可以帮助更高效地管理计算节点所消耗的资源。在节点故障发生时,RDS Proxy 可更快速地检测故障并将流量重定向到另一个节点,而不会断开客户端连接。
RDS Proxy 是 Aurora 的附加服务,因此会在 AWS 账单上出现额外的费用。
对数据库进行的许多更改需要实例重启,此时操作期间将会产生一些停机时间。有些操作,例如调整实例类型,可通过只读副本实现最小的停机时间。
另一个减少停机时间的选项是蓝绿部署(blue/green deployment),即创建一个新的完全相同的环境,在应用变更后将流量重新定向至新环境。Amazon 推荐使用蓝绿部署进行各种数据库配置变更,例如版本更新或架构修改。重新定向流量的过程称为切换(switchover),尽管所有连接仍会在切换期间中断,但与直接操作集群相比停机时间更短。
要了解更多关于蓝绿部署的信息,请查看我们关于 Aurora 和 PlanetScale 分支比较的文章。
创建蓝绿部署时,你将设置一个完全相同的在线环境。这意味着在两个环境在线期间,你的计算成本(选定的实例类型和副本数量)会翻倍。此外,切换完成后 Amazon 不会自动删除旧环境,你必须手动移除它以避免费用异常增加。
备份是灾难恢复计划的重要组成部分,应在数据库定价时优先考虑。通过自动备份功能,你将根据使用的存储量(以 GB 计)收费,并减去数据库最新的大小。因此,你可以免费获得一个完整备份,但对于任何后续增量备份,将会收取费用。你还可以配置备份的保留时长,超出时将被自动删除。
此外,你还可以选择手动创建数据库的快照。这些快照不属于自动化系统,即使数据库被删除,它们仍会保留。手动快照的收费基于快照大小,不包含在免费的自动备份中。
监控 Aurora 数据库可以采用许多不同的解决方案。
默认情况下,Amazon Aurora 每分钟会向 CloudWatch 发送一系列广泛的指标,包括集群和每个单独实例的指标,且不额外收费。指标内容涵盖活动事务数量到副本之间复制时间等信息。所有默认指标过于繁多,详细列表可查看 Amazon 的文档。
如果需要实时信息,可以使用 Enhanced Monitoring 服务作为附加功能。Enhanced Monitoring 使用 CloudWatch Logs,这些日志会根据每月发送到 CloudWatch 的数据量收费。费用可能因集群不同差异显著,但可以提供更为详细的数据分析所需的信息。
此外,Performance Insights 允许从实际的数据库引擎中收集数据,例如数据库负载和查询性能。这项服务的收费基于数据保留时间,最长可保留两年。前七天不额外收费,但针对超过七天的数据保留则会产生费用。
在详细分析创建 Aurora 集群时需考虑的各种成本后,让我们看一下 PlanetScale 如何应对相同领域需求以及其定价方式。
在创建 PlanetScale 数据库时,我们也会要求你选择实例类型。然而,与 Aurora 的复杂选择不同,我们将实例类型的选择显著简化。我们没有可突发与内存优化的概念,同时在选择实例类型时会直接显示 CPU、内存分配和价格。以下是 AWS us-east-1 区域创建 PlanetScale Scaler Pro 数据库的定价表:
PlanetScale 创建数据库的价格表
此外,显示的每种类型实际上都是一个 MySQL 集群的配置。我们遵循所有数据库的最佳实践,包括将你的数据跨三个可用区复制。
PlanetScale 的存储配置也简化了,所有网络连接的实例类型均采用统一存储配置。而在 PlanetScale Metal 配置中,你可以根据具体工作负载选择合适的存储大小。
Metal 的一个最大优势是性能改进。你不需要在 PlanetScale 中购买 Aurora 专属的 I/O 优化计划。Metal 实例默认提供了无限制的 IOPS。此外,与等效的 Aurora I/O 优化工作负载相比,你可能会节约资金。
PlanetScale 不会收取任何数据传输费用。唯一的例外是 PlanetScale Managed 配置,在这种情况下,PlanetScale 会部署在你的 AWS 组织中的子账户中。然后,你将按照 Aurora 数据库的标准支付 AWS 的数据传输费用。
PlanetScale 提供了创建只读区域的功能,可以将数据复制到靠近应用服务器的选定区域。这与 Aurora 的 Global database 非常类似,但无需支付数据传输费用,同时你仍可以获得与所选实例类型完全相同的 MySQL 集群资源。
PlanetScale 的 PostgreSQL 集群使用 PgBouncer 进行连接池管理和自动故障切换。
同时,PlanetScale 提供了完全托管的 Vitess 集群——一种最初由 YouTube 开发的数据库集群系统,用于解决 2010 年的扩展问题。这使得我们能够利用 Vitess 提供的连接池和负载均衡功能。
Vitess 中管理所有 MySQL 集群连接的核心组件是 vtgate,一种轻量级代理,它负责将流量路由到集群中的正确 MySQL 节点。vtgate 类似于 RDS Proxy,能够通过 MySQL 协议与所有节点管理连接,减少每个节点的资源消耗,同时与我们的拓扑服务沟通以确定流量的路由方式。在分片配置中,当查询的目标数据分布在多个分片节点中时,它还将拆分查询并向正确节点发送。
由于 vtgate 是 Vitess 的核心组件,PlanetScale 支持几乎无限数量的连接,同时运行 PlanetScale 数据库的成本中已包含这项服务。
与 Aurora 相比,PlanetScale 的管理显著优化。Aurora 需要你创建蓝绿部署,这增加了复杂度和成本(并且在进行变更时可能导致客户端中断)。PlanetScale 的许多蓝绿部署适用场景均由平台或工程团队自动化处理。
例如,当发布新的 MySQL 版本时,我们的工程师会严格测试版本的稳定性,以确保其能够在 PlanetScale 基础设施上运行。对于实例类型变更,我们利用 Kubernetes 运行的容器化计算节点进行滚动升级,将新的实例类型副本添加至你的集群,完成数据复制并通过 vtgate 重新路由流量。这一流程完全自动化且无需停机。
对于架构更新,PlanetScale 用户可以利用数据库分支(如开发分支)和部署请求机制实现。分支是一个完全隔离的 MySQL 集群,包含上游分支的架构副本。你可以在这个分支上应用并测试架构变更,随后通过合并请求将变更应用到上游分支,而无需离线来完成操作。分支运行时资源消耗非常少,因此不会显著增加运营成本。
通过这种方式,PlanetScale 显著简化了变更和管理流程,同时避免了生产停机。由此造成的成本增加远低于 Aurora 的方案。
Aurora 是一个功能强大的可扩展数据库服务,但其定价结构并不像官方宣传的那样直接明了。创建和运行 Aurora 集群时,有许多需要评估的因素。与 Aurora 相比,PlanetScale 致力于尽可能简化定价流程,同时将部分功能以免费的形式提供。
关注公众号:程序新视界,一个让你软实力、硬技术同步提升的平台
除非注明,否则均为程序新视界原创文章,转载必须以链接形式标明本文链接
]]>选择数据存储是构建软件应用时最关键的决策之一。根据具体应用的需求,您可以选择关系型数据库(如 MySQL 或 Postgres)、非关系型数据库(如 MongoDB 或 CouchDB)、图数据库(如 Neo4j)或其他各种选项。
尽管初始选择数据库时可能适合,现在却发现无法满足应用需求,您可能需要迁移数据库。在本文中,我们探讨如何从 PostgreSQL 迁移到 MySQL。MySQL 和 PostgreSQL 都是关系型数据库,存在许多相似之处,但也有一些显著的差异,使迁移充满挑战。
以下表格列出两者之间的一些关键差异:
| 指标 | PostgreSQL | MySQL |
|---|---|---|
| 许可 | PostgreSQL 自由开源许可(类似 BSD/MIT) | GNU 通用公共许可协议 (GPL) |
| ACID 支持 | 支持 | 支持 |
| 触发器支持 | INSERT/UPDATE/DELETE 有 AFTER/BEFORE/INSTEAD OF 支持 | INSERT/UPDATE/DELETE 仅支持 AFTER/BEFORE |
| 无符号整数支持 | 不支持 | 支持 |
| 物化视图 | 支持 | 不支持 |
| ANSI/ISO SQL 合规性 | 完全合规 | 大致合规 |
| DROP TEMP TABLE 语法 | 不支持 TEMP/TEMPORARY 关键字 | 支持 TEMP/TEMPORARY 关键字 |
| 表分区 | 支持 RANGE/LIST/HASH | 支持 RANGE/COLUMN/LIST/HASH/KEY 等 |
| 这些差异在决定迁移时需要慎重考虑。 |
以下我们手动迁移 PostgreSQL 数据库至 MySQL,探讨迁移的底层考虑:
假设有以下数据库架构:
products 表:
SQLCREATE TABLE products
(
id SERIAL,
name VARCHAR,
description VARCHAR,
price INTEGER
);
products 表迁移至 MySQL:SQLCREATE TABLE products
(
id BIGINT UNSIGNED AUTO_INCREMENT,
name TEXT,
description TEXT,
price INT,
PRIMARY KEY (id)
);
customers 表PostgreSQL 定义如下:
SQLCREATE TABLE customers
(
id SERIAL,
full_name VARCHAR,
address VARCHAR,
location POINT
);
迁移至 MySQL:
SQLCREATE TABLE customers
(
id INT NOT NULL AUTO_INCREMENT,
full_name TEXT,
address TEXT,
location POINT,
PRIMARY KEY (id)
);
注意:
ST_AsText() 解读存储的坐标数据。location_latitude 和 location_longitude。orders 表PostgreSQL 定义如下:
SQLCREATE TABLE orders
(
id UUID default gen_random_uuid(),
customer INTEGER,
products JSONB
);
迁移至 MySQL:
SQLCREATE TABLE orders
(
id VARCHAR(36) DEFAULT UUID(),
customer INT,
products JSON,
PRIMARY KEY (id)
);
注意:
UUID() 函数生成,与 Postgres 的 gen_random_uuid() 类似。在从 PostgreSQL 至 MySQL 迁移时,还需考虑以下因素:
尽管 MySQL 和 Postgres 支持多种传统 SQL 数据类型(如 String、Boolean、Integer、Timestamp),但 Postgres 支持的一些高级类型可能不存在于 MySQL 中。因此在迁移复杂数据结构时可能会遇到问题。
TRUNCATE TABLE 支持 CASCADE、RESTART IDENTITY 等特性,而 MySQL 不支持。从 PostgreSQL 到 MySQL 的迁移并非难以实现,但需要充分了解两者之间的差异,并根据具体的应用场景选择优化的解决方案。
MySQL 在常见场景下通常更具性能优势,同时拥有强大的扩展工具(如 Vitess 和 PlanetScale)来支持大规模数据库。了解两种技术的特点和适配场景,是选择数据库或迁移时最重要的考虑因素。希望本文能帮助您对迁移的过程和细节有更清晰的认知。
关注公众号:程序新视界,一个让你软实力、硬技术同步提升的平台
除非注明,否则均为程序新视界原创文章,转载必须以链接形式标明本文链接
]]>psycopg2.ProgrammingError: execute cannot be used while an asynchronous query is underway 是核心异常。这表明:一个异步数据库查询正在运行,而另一个查询尝试在同一连接或事务中被执行,从而导致冲突。这种情况通常发生在使用 SQLAlchemy 和 psycopg2 驱动的异步操作场景下。
从栈追踪和代码结构分析,可以识别几个潜在问题:
execute cannot be used while an asynchronous query is underway。这通常是因为多个任务或线程共享同一个数据库连接,而其中有异步查询未完成时,另一个查询试图使用这个连接。[Thread-892] 和 [Thread-890] 看起来彼此是并发运行的,它们之间可能共享了同一个数据库会话(Session)或连接池。File "/app/api/.venv/lib/python3.12/site-packages/sqlalchemy/engine/base.py", line 1963, in _exec_single_context
async 和普通 execute 查询,会导致此类冲突。SQL: SELECT end_users.id AS end_users_id ...
asyncpg,也可能导致连接竞争。current_user 的 tenant_id 属性:tenant_id = extract_tenant_id(current_user) return user.tenant_id
tenant_id 属性时,触发 ORM 查询加载属性,该查询被发往数据库时又出现了连接冲突。current_user 在不同线程或异步任务中被共享,而未正确绑定独立事务或连接,会导致此类问题。Session 在任务间隔离:from sqlalchemy.orm import sessionmaker SessionLocal = sessionmaker(bind=engine)
每个线程或异步任务应确保使用独立的会话实例。
asyncpg 驱动替换 psycopg2。from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
engine = create_async_engine("postgresql+asyncpg://user:pass@localhost/dbname")
async_session = sessionmaker(engine, class_=AsyncSession)
contextvars 或类似机制,在异步任务中确保独立的用户上下文:from contextvars import ContextVar
current_user = ContextVar("current_user")
Session 和 engine 的生命周期管理。tenant_id 属性的加载)在正确的上下文中加载。async with async_session() as session:
async with session.begin():
result = await session.execute(statement)
max_overflow 和 pool_size。异常的关键在于多任务间对数据库连接的竞争。一些任务可能执行了长时间挂起的异步查询,而其他任务尝试使用同一连接导致冲突。通过隔离任务间的数据库上下文、优化连接池配置或改为纯异步操作,可以有效解决这些问题。
关注公众号:程序新视界,一个让你软实力、硬技术同步提升的平台
除非注明,否则均为程序新视界原创文章,转载必须以链接形式标明本文链接
]]>psql 中使用元命令如果你是通过 psql 命令行连接到数据库,可以直接使用以下元命令:
\dt
\dt 会列出当前模式中所有的 用户定义的表。 List of relations
Schema | Name | Type | Owner
-------+-------+------+-------
public | table1 | table | postgres
public | table2 | table | postgres
有些表可能存在于不止 public 模式中。如果你想查看所有模式的表,运行以下命令:
\dt *
\dt * 列出所有模式中的表,包括自定义表和 PostgreSQL 的内置系统表。如果不仅仅是查看用户表,而是包括所有对象(如视图、序列等),可以使用:
\dv -- 查看所有视图
\ds -- 查看所有序列
\d -- 查看当前模式中所有对象(表、视图、索引等)
\d * -- 查看所有模式中的所有对象
PostgreSQL 的表和元数据存储在系统表 information_schema 和 pg_catalog 中。你可以通过 SQL 查询获取所有表的列表。
SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'public' AND table_type = 'BASE TABLE';
table_schema = 'public':只列出 public 模式中的表。table_type = 'BASE TABLE':表示只显示基础表(忽略视图和其他对象)。如果想查看所有表,可以去掉 table_schema 的限制条件:
SELECT table_schema, table_name
FROM information_schema.tables
WHERE table_type = 'BASE TABLE';
pg_catalog 查询获取所有表(包括系统表)PostgreSQL 存储表信息的系统表是 pg_tables,可以通过以下 SQL 查询获取表信息:
SELECT *
FROM pg_tables
WHERE schemaname NOT IN ('pg_catalog', 'information_schema');
pg_tables 是 PostgreSQL 内置的系统表。pg_catalog 和 information_schema 模式,这些模式属于系统表和元数据。如果需要查看包括系统表在内的所有表,可以省略过滤条件:
SELECT * FROM pg_tables;
使用 psql 命令中的 \d 来查看表结构:
\d table_name
通过指定 \d * 来依次列出所有表及其结构:
\d *
| 场景 | 命令或 SQL |
|---|---|
查看当前数据库所有用户表 (psql) | \dt |
查看所有模式的表 (psql) | \dt * |
| 通过 SQL 查询当前模式的表 | SELECT table_name FROM information_schema.tables WHERE table_schema = 'public' AND table_type = 'BASE TABLE'; |
| 通过 SQL 查询所有模式的表 | SELECT table_schema, table_name FROM information_schema.tables WHERE table_type = 'BASE TABLE'; |
| 通过 pg_catalog 查询用户表 | SELECT * FROM pg_tables WHERE schemaname NOT IN ('pg_catalog', 'information_schema'); |
| 显示单个表结构 | \d table_name |
关注公众号:程序新视界,一个让你软实力、硬技术同步提升的平台
除非注明,否则均为程序新视界原创文章,转载必须以链接形式标明本文链接
]]>USE <database>)。每次连接都是针对单独的数据库,会话一旦启动,你只能访问连接时指定的数据库。如果需要切换数据库,可以选择以下方法:
psql 命令行中重新连接到新数据库使用 \c 或 \connect 命令可以在 psql 客户端中重新连接到一个新的数据库。
\c <database_name> [<username>]
database_name:要切换的目标数据库名称。[username]:可选参数,指定要使用的 PostgreSQL 用户。如果当前连接到数据库 db1,想切换到 db2,可以输入以下命令:
\c db2
或者指定连接用户(假设用户为 postgres):
\c db2 postgres
切换后,你会看到提示信息,说明已连接到新的数据库:
You are now connected to database "db2" as user "postgres".
如果不是在 psql 交互终端中,你需要通过终端或程序断开当前连接并重新建立新的连接。
psql 中从终端连接:使用 psql 重新连接目标数据库:
psql -U <username> -d <database_name>
示例(连接到数据库 db2,使用用户 postgres):
psql -U postgres -d db2
在代码中,需要关闭当前连接,然后通过新的数据库名称重新建立连接。例如:
conn, err := pgx.Connect(context.Background(), "postgres://user:password@localhost/db2")
conn = psycopg2.connect(database="db2", user="postgres", host="localhost", password="password")
如果需要在多个数据库之间频繁切换,推荐在应用程序中建立多连接池(比如对 db1 和 db2 实例分别创建连接对象),在执行操作时动态选择需要的数据库。
如果需要查询其他数据库中的数据,可以在 PostgreSQL 中使用 dblink 扩展进行跨库查询,而无需切换数据库。
dblink:运行以下 SQL 命令创建 dblink 扩展:
CREATE EXTENSION dblink;
dblink 查询目标数据库:SELECT * FROM dblink('dbname=db2 user=postgres password=your_password',
'SELECT * FROM target_table')
AS t(id INT, name TEXT);
dbname=db2:目标数据库名称。user 和 password:目标数据库的登录凭据。这样可以将结果直接引入到当前会话的数据库中,而无需切换数据库。
如果只是经常切换或访问默认数据库(比如 postgres 数据库),通常直接连接到目标数据库时指定即可:
psql -d postgres
psql 中使用 \c <database>。dblink 扩展处理无需切换的跨库操作。USE <database> 命令,因此切换数据库的方式更依赖客户端或应用程序的连接机制。关注公众号:程序新视界,一个让你软实力、硬技术同步提升的平台
除非注明,否则均为程序新视界原创文章,转载必须以链接形式标明本文链接
]]>运行以下 SQL 查询,统计当前所有连接数:
SELECT COUNT(*) AS total_connections
FROM pg_stat_activity;
pg_stat_activity 是一个系统视图,包含了与 PostgreSQL 数据库实例的所有连接会话的信息。如果想查看每个数据库的连接数,可以分组统计连接会话:
SELECT datname AS database_name, COUNT(*) AS connections
FROM pg_stat_activity
GROUP BY datname;
datname 表示数据库名称。如果想统计每个用户所占连接数,可以使用以下 SQL 查询:
SELECT usename AS username, COUNT(*) AS connections
FROM pg_stat_activity
GROUP BY usename;
usename 表示数据库用户名称。如果关注状态为 idle 的空闲连接(连接已建立,但未执行任何操作),可以运行以下查询:
SELECT state, COUNT(*) AS count
FROM pg_stat_activity
GROUP BY state;
active:正在执行查询的连接。idle:空闲的连接。pgAdmin),可以点击服务器节点下 “Statistics” 或 “Dashboard”,在界面中查看连接会话相关信息。PostgreSQL 通常在默认端口 5432 上运行,你可以使用以下命令通过系统层面查看连接数。
运行以下 netstat 命令,统计当前连接到 PostgreSQL 默认端口的会话:
netstat -an | grep 5432 | wc -l
如果你需要查看具体哪些客户端或 IP 地址连接到了数据库,可以运行以下命令:
netstat -an | grep 5432
PostgreSQL 限制了每个实例的最大连接数,默认情况下为 100。你可以运行以下 SQL 查看当前最大连接数配置:
SHOW max_connections;
postgresql.conf 文件中的 max_connections 参数,并重启数据库。如果发现有大量空闲连接(状态为 idle),可以尝试关闭这些连接。以下 SQL 可以强制关闭所有空闲连接:
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE state = 'idle';
关注公众号:程序新视界,一个让你软实力、硬技术同步提升的平台
除非注明,否则均为程序新视界原创文章,转载必须以链接形式标明本文链接
]]>psql 客户端连接到本地的 PostgreSQL 数据库实例。连接后,可以使用 SQL 查询来查看当前数据库实例的连接数以及其他相关信息。
你可以通过以下方式本地连接到 PostgreSQL:
psql打开终端并执行以下命令:
psql -U <username> -d <dbname>
-U <username>:指定 PostgreSQL 用户名。-d <dbname>:指定要连接的数据库名。如果 PostgreSQL 使用默认配置,连接到本地数据库不需要指定 IP 或端口,默认端口是 5432。例如:
psql -U postgres -d postgres
该命令使用 PostgreSQL 内置的 postgres 用户和连接默认的 postgres 数据库。
如果数据库名和用户名一致,可以省略 -d 参数,例如:
psql -U myuser
连接后,你会进入 PostgreSQL 的交互模式,在提示符 dbname=# 下输入 SQL 和命令。
PostgreSQL 提供内置的系统视图 pg_stat_activity,可以通过以下 SQL 查询查看当前连接数:
SELECT COUNT(*) AS total_connections
FROM pg_stat_activity;
❯ 说明:
pg_stat_activity 是 PostgreSQL 的动态统计视图,列出了当前正在连接的会话信息。如果想根据数据库名称或状态查看连接数细分,可以添加分组条件:
SELECT datname AS database_name, COUNT(*) AS connections
FROM pg_stat_activity
GROUP BY datname;
这里将按照数据库名称 (datname) 对连接数进行统计。
通过以下 SQL 查看 PostgreSQL 配置中的最大连接数:
SHOW max_connections;
如果想统计每个用户的连接数,可以使用以下查询:
SELECT usename AS username, COUNT(*) AS connections
FROM pg_stat_activity
GROUP BY usename;
PostgreSQL 的连接参数通常可以在配置文件 postgresql.conf 中设置。可以通过以下命令查看当前配置文件的位置:
SHOW config_file;
默认情况下,配置文件通常位于 /etc/postgresql/<version>/main/postgresql.conf 或类似路径。
如果需要支持远程连接,需要确保 pg_hba.conf 文件已经允许目标 IP 地址的连接,并且监听地址设置为 * 或特定 IP。
PostgreSQL 中的连接资源是有限的,可以通过调整参数或配置来关闭长时间保持活跃但空闲的连接:
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE state = 'idle';
通过 psql本地连接到 PostgreSQL 后,可以使用 pg_stat_activity 查询具体连接数,以及通过配置和监控查看相关参数(如最大连接数)。这些信息在优化数据库连接和性能时非常重要。
关注公众号:程序新视界,一个让你软实力、硬技术同步提升的平台
除非注明,否则均为程序新视界原创文章,转载必须以链接形式标明本文链接
]]>为了能够熟练运用,特意买书研究,发现这款数据库还真有点意思。汇总一篇文章与大家分享,目的只有一个:让大家多少了解一下这款数据库。
你会发现与Mysql相比,PostgreSQL的社区并不活跃,中文资料可以说是少得可怜,在数据库中排行老四。前三都不一定全用过,谁会去记住老四呢。但下面的数据不得不让我们留意。
下面是DB-Engines数据库流行度排行榜2020年7月份的数据。
在老大老二的评分不断下降的情况下,这么一个没有后台的开源数据库,竟然励精图治,突飞猛进。有没有像春秋战国时的秦国,是时候得留意一下它了。
下面再看看这几年PostgreSQL的增速情况。
图中遥遥领先其他数据库,追赶前三名的数据库,就是PostgreSQL,不少大厂已经在使用了。
PostgreSQL是一款开源的对象关系型数据库,也就是说与Mysql的功能一致。在欧美地区使用比较广泛,因其限制严格、实现严谨,在金融、电信等领域应用比较多。
对照Mysql来了解一下PostgreSQL(以下简称PG):
1、在SQL的标准实现上比MySQL完善,而且功能实现比较严谨;
2、存储过程的功能支持要比MySQL好,具备本地缓存执行计划的能力;
3、PG对表连接支持较完整,优化器的功能较完整,支持的索引类型很多,复杂查询能力较强;
4、PG主表采用堆表存放,MySQL采用索引组织表,能够支持比MySQL更大的数据量。
5、PG的主备复制属于物理复制,相对于MySQL基于binlog的逻辑复制,数据的一致性更加可靠,复制性能更高,对主机性能的影响也更小。
6、MySQL的存储引擎插件化机制,存在锁机制复杂影响并发的问题,而PG不存在。
上面是比较笼统的概述,下面给大家汇总一下读相关书籍发现。
1、数据库、表等操作基本相同,与Mysql不同的是PG的主键自增采用了独立的序列,然后将序列赋值给对应的字段来实现自增。
2、PG的字段级、表级的约束也特别有意思。可以通过CHECK关键字来约束指定字段是否大于或小于某个阈值(仅举例,不限于此)。针对表级别的约束,还可以通过CHECK关键字来约束两个字段之间的关系,比如:CHECK(createtime < parentcreatetime)。是不是非常有意思?
3、数据类型中PG提供了money类型,可基于时区来显示对应的货币格式,如“$1,000.00”。
4、数据类型中支持了丰富的日期时间类型,而还有相应的运算操作,加减乘除应有尽有。
5、数据类型中还支持了点、线、线段、矩形、路径、多边形、圆等几何图形,虽然不会经常用到,有便是一件很Cool的事。当然,也少不了JSON和数组的类型。
6、PG提供了数学函数、字符串函数、二进制字符串函数、数据类型格式化函数、日期和时间函数、位串函数、枚举函数、几何函数、JSON函数、范围函数、数字函数等等,丰富到眼花缭乱。
7、SQL查询中提供了递归查询,内置了大量的窗口函数。
8、索引支持B-tree索引、Hash索引、GiST索引、SP-GiST索引、GIN索引、BRIN索引。足够丰富。
9、视图支持物化视图和普通视图。
10、支持表继承,面向对象编程的朋友是不是对此很亲切。
11、PG支持基本的表分区功能更,PG10之后支持声明式内置表分区功能。该功能支持把大表拆分成更小的物理分片,分别进行独立存储。
12、PG支持在大型事务中通过使用保存点(SAVEPOINT)来回滚部分事务。
13、PG对SQL语句进行了逻辑优化和物理优化。
当然,还有其他很多有意思的功能等待发掘。读完上述内容你是不是也有兴趣了解一下?那这篇文章的目的就达到了。
最后,写这篇文章有两个目的。第一,很明确,给大家介绍一款数据库。第二,是想推广一个学习提升的理念:尽情去去尝试了解新事物,努力突破自己的舒适区,这往往会给自己带来非常大的收获。
关注公众号:程序新视界,一个让你软实力、硬技术同步提升的平台
除非注明,否则均为程序新视界原创文章,转载必须以链接形式标明本文链接
]]>