我在繁忙的 postgres 9 数据库前运行 pgBouncer。在大多数情况下,它运行良好。但是每隔几个小时我就会收到一封来自我的应用程序的错误电子邮件,但 psycopg2 除外:
OperationalError('无法连接到服务器:无法分配请求的地址服务器是否在主机“neo-hulk”上运行并接受端口 6432 上的 TCP/IP 连接?')
这是一个 python 应用程序,其中有一堆 celery 工人正在运行任务。当这些错误到达时,我检查 pgbouncer db 并且池大小在限制范围内。经过一些实验,我将池最大大小设置为 400,池大小设置为 200。池模式是“会话”(请求主要是自动提交,几乎没有事务)。
是什么让 pgBouncer 像那样“消失”?它只是在很短的时间内(总的来说,与它处理的大量请求相比,我们谈论的是极少量的请求),但那些失败的请求很重要。
谢谢!
我正在尝试运行一个应该返回大约 2000 行的查询,但是我的 RDS 托管的 PostgreSQL 9.3 数据库给了我错误“内存不足详细信息:请求大小为 2048 时失败。”。
这意味着什么?我的实例有 3GB 的内存,那么什么会限制它足以用这么小的查询耗尽内存?
编辑:
SHOW work_mem;
"1024GB"
Run Code Online (Sandbox Code Playgroud)
我无法显示完整的 SQL,但它正在尝试执行数据透视。我有两个主表library和book,它们指向一条library记录。我的查询尝试为每个图书馆记录查找过去 12 个月中每个月最受欢迎的书,并将它们连接到结果查询集中的一个单独列中,例如:
library_id, month_1_book_id, month_2_book_id, month_3_book_id, ...
Run Code Online (Sandbox Code Playgroud)
Explain 显示了很多循环的结果:
explain
select * from myapp_library_get_monthly_popular
where id in (5495060, 5495059, 5495048)
Nested Loop Left Join (cost=3645798.54..3750412.91 rows=3 width=2980)
-> Nested Loop Left Join (cost=3645798.10..3750388.98 rows=3 width=2994)
-> Nested Loop Left Join (cost=3645797.66..3750365.05 rows=3 width=2976)
-> Nested Loop Left Join (cost=3645797.23..3750341.13 rows=3 width=2958)
-> Nested Loop Left …Run Code Online (Sandbox Code Playgroud) 我们在 Windows 上使用 Postgres 9.2 来存储低频时间序列数据:我们每周 7 天、24 小时每秒插入大约 2000 行,没有停机时间。有一个DELETE每隔 10 分钟左右在桌子上运行一次,以将桌子的长度保持在固定的天数。这最终是一个相当稳定的 9 亿行。(对于那些感兴趣的人,SELECT, INSERT,DELETE都是高性能的)。
因此DELETE,虽然删除行不会释放磁盘空间。为此,我们需要VACUUM运行。
我已经查询过pg_stat_user_tables并且VACUUM似乎从未运行过。
我从各种文档中了解到的(http://www.postgresql.org/docs/9.2/static/routine-vacuuming.html):
FULL,并且不需要对表进行排他锁。有没有人有任何想法为什么自动真空不运行?这纯粹是因为桌子一直很忙吗?
在这种情况下是否值得VACUUM在each之后DELETE运行(每 10 分钟运行一次)?
编辑:
使用以下 SO 链接中的 SQL 进行查询:
-[ RECORD 2 ]---+---------------------------
schemaname | stats
relname | statistic_values_by_sec
last_vacuum |
last_autovacuum |
n_tup | 932,315,264
dead_tup | 940,727,818
av_threshold | 186,463,103
expect_av | …Run Code Online (Sandbox Code Playgroud) 是否有一种直接的方法可以将这些类型的 MySQL 查询调整到 PostgreSQL:
在 MySQL 中设置变量,例如
set @aintconst = -333
set @arealconst = -9.999
Run Code Online (Sandbox Code Playgroud)
似乎不是。
从 SELECT 查询中分配变量并随后在我的 SQL 中使用这些变量,例如:
select @pfID := id from platform where bios like '%INTEL%'
select @clientID := id from client where platformID = @pfID
Run Code Online (Sandbox Code Playgroud)我将非常感谢您的指点,尤其是在 (2) 上。
我正在使用psycopg2数据库 API对 PostgreSQL 9.3 进行一些工作。
我将 DB API 设置为最低隔离级别(“自动提交”模式),并直接通过 SQL 管理我自己的事务。例子:
cur = self.conn.cursor()
cur.execute("BEGIN;")
cur.execute("SELECT dbId, downloadPath, fileName, tags FROM {tableName} WHERE dlState=%s".format(tableName=self.tableName), (2, ))
ret = cur.fetchall()
cur.execute("COMMIT;")
Run Code Online (Sandbox Code Playgroud)
基本上,事务是由cur.execute("BEGIN;")仅限于该游标启动的,还是针对整个连接(self.conn.cursor())?
我正在做的一些更复杂的事情涉及多个单独的数据库操作,我在逻辑上将它们分解为函数。由于这一切都在一个将连接作为成员的类中,因此在每个函数中创建游标要方便得多。但是,我不确定在事务中创建游标是如何工作的。
基本上,如果事务是按连接进行的,我可以在事务中即时创建大量游标。如果它们是每个光标,那意味着我必须到处传递光标。是哪个?
文档没有涉及这一点,尽管您可以调用这一事实connection.commit()使我相当确信事务控制是针对每个连接的。
由于我是一名年轻的开发人员并且不太擅长使用数据库(PostgreSQL 9.3),因此我在项目中遇到了一些问题,我确实需要帮助。
我的项目是关于从设备(最多 1000 个或更多设备)收集数据,其中每个设备每秒发送一个数据块,每小时大约生成 300 万行。
目前我有一张大表,用于存储每个设备的传入数据:
CREATE TABLE data_block(
id bigserial
timestamp timestamp
mac bigint
)
Run Code Online (Sandbox Code Playgroud)
由于数据块可以(或不可以)包含多种类型的数据,因此还有其他表引用该data_block表。
CREATE TABLE dataA(
data_block_id bigserial
data
CONSTRAINT fkey FOREIGN KEY (data_block_id) REFERENCES data_block(id);
);
CREATE TABLE dataB(...);
CREATE TABLE dataC(...);
CREATE INDEX index_dataA_block_id ON dataA (data_block_id DESC);
...
Run Code Online (Sandbox Code Playgroud)
有可能在一个 data_block 中有 3x dataA、1x dataB,但没有 dataC。
数据将保留数周,因此该表中将有大约 50 亿行。目前,我在表中有大约 6 亿行,我的查询需要很长时间。所以我决定在timestampand上做一个索引mac,因为我的 select 语句总是随着时间的推移而查询,而且通常也随着时间+mac。
CREATE INDEX index_ts_mac ON data_block (timestamp DESC, mac);
Run Code Online (Sandbox Code Playgroud)
...但我的查询仍然需要很长时间。比如我查询了一天一台mac的数据:
SELECT * FROM data_block …Run Code Online (Sandbox Code Playgroud) 我在表上添加新列时遇到问题。
我尝试运行了几次,但是运行了 10 多分钟后,由于锁定时间,我决定取消查询。
ALTER TABLE mytable ADD mycolumn VARCHAR(50);
Run Code Online (Sandbox Code Playgroud)
有用的信息:
我发现了有关 PostgreSQL 管理可空列的方式的有趣信息(通过 HeapTupleHeader)。
我的第一个猜测是,因为这个表已经有 32 个 8 位的可空列MAXALIGN, HeapTupleHeader 是 4 字节长度(未验证,我不知道如何这样做)。
因此,添加新的可为空的列可能需要在每一行上更新 HeapTupleHeader 以添加新的 8-bits MAXALIGN,这可能会导致性能问题。
因此,我尝试更改可空列之一(实际上并不是真正可以为空的),以便将可空列的数量减少到 31,以检查我的猜测是否属实。
ALTER TABLE mytable ALTER myothercolumn SET NOT NULL;
Run Code Online (Sandbox Code Playgroud)
不幸的是,这个改动也需要很长时间,超过5分钟,所以我也中止了。
您知道是什么导致了这种性能成本吗?
我不明白 Craig Ringer 在评论时的意思:
如果插入事务回滚,此解决方案可能会丢失更新;没有强制执行 UPDATE 影响任何行的检查。
在/sf/answers/609160401/ 上。请提供一个示例事件序列(例如,线程 1 执行 X,线程 2 执行 Y)以演示丢失更新是如何发生的。
根据克雷格·林格的说法:
虽然在(或包括)引用端外键列上创建索引通常是个好主意,但这不是必需的。您添加的每个索引都会稍微减慢 DML 操作的速度,因此您需要为每个
INSERT,UPDATE或支付性能成本DELETE。如果索引很少使用,它可能不值得拥有。
您如何确定添加索引的收益是否超过其成本?
您是否在添加索引之前/之后分析单元测试并检查整体性能提升?或者,还有更好的方法?
我需要监控我们数据库中用户的活动。我在中设置了以下参数postgresql.conf:
log_min_duration_statement = 0
log_connections = on
log_disconnections = on
log_line_prefix = '%t %a %d %h %u |'
Run Code Online (Sandbox Code Playgroud)
但是,我意识到大多数日志文件都填充了postgres用户执行的语句,这些语句被我为维护任务编写的脚本所使用:重新计算物化视图、pg_dump、pg_restore、将视图提取为列表文件等。结果是每天日志文件大小超过 12 Mb。
有没有办法从日志中排除特定用户的活动?
postgresql ×10
alter-table ×1
concurrency ×1
cte ×1
index ×1
log ×1
mysql ×1
optimization ×1
performance ×1
pgbouncer ×1
python ×1
upsert ×1
vacuum ×1