我正在使用带有psycopg2的Python,并且我试图VACUUM在每日操作后运行一个完整的插入数千行.问题是,当我尝试VACUUM在我的代码中运行命令时,我收到以下错误:
psycopg2.InternalError: VACUUM cannot run inside a transaction block
Run Code Online (Sandbox Code Playgroud)
如何从事务块外部的代码运行它?
如果它有所不同,我有一个简单的DB抽象类,下面显示了一个子集用于上下文(不是runnable,省略了异常处理和docstrings以及进行了行跨越调整):
class db(object):
def __init__(dbname, host, port, user, password):
self.conn = psycopg2.connect("dbname=%s host=%s port=%s \
user=%s password=%s" \
% (dbname, host, port, user, password))
self.cursor = self.conn.cursor()
def _doQuery(self, query):
self.cursor.execute(query)
self.conn.commit()
def vacuum(self):
query = "VACUUM FULL"
self._doQuery(query)
Run Code Online (Sandbox Code Playgroud) 正如这个Firefox bug所引用的那样,真空吸尘数据库的行为是什么?所有现代数据库软件或仅某些数据库软件是否支持此操作?
我想知道如何真空sqlite数据库.我从命令提示符处为整个数据库尝试了语法MANUAL VACUUM命令:
$sqlite3 database_name "VACUUM;";
Run Code Online (Sandbox Code Playgroud)
但它给出的错误是:
near "database_name": syntax error.
Run Code Online (Sandbox Code Playgroud)
还有AUTO VACUUM:
PRAGMA auto_vacuum = INCREMENTAL;
Run Code Online (Sandbox Code Playgroud)
并尝试将其用于特定的表格:
VACUUM table_name;
Run Code Online (Sandbox Code Playgroud)
但没有结果.
我正在使用Postgres 9.4.
我刚跑完真空.我读到了真空和真空之间的差异,如果我应该使用真空或真空吸尘器,我会考虑很多.据我所知,我需要真空充满,我的数据库大小从48 GB下降到24 GB.
在真空充满后,旧指数会变得过时,我是否需要运行reindex?
我运行了"真空全冗余分析",因此分析完成了真空.
我在几个地方看过,对于Postgres> 9.0,真空充满后我不需要重新索引,但我想确定是这样的.
我对PostgreSQL比MySQL更熟悉.使用PostgreSQL数据库遇到过环绕ID失败一次,然后了解数据库中吸尘的重要性.实际上,这是一个如此庞大的开销工作(并且它是旧版本的7.4.3,几个月后更新以获得autovacuum).将MySQL与PostgreSQL进行比较时,假设MySQL不必处理PostgreSQL中的真空等开销.这个假设是对的吗?
还有为什么MySQL与PostgreSQL相比不需要真空?对于MySQL dbs,是否存在类似于vacuum的其他优化替代方案?
在pgAdmin中,只要表的统计信息已过期,它就会提示:
建议运行VACUUM
表schema.table上的估计rowcount与实际rowcount明显不同.您应该在此表上运行VACUUM ANALYZE.
我用pgAdmin 3和Postgres 8.4.4测试了它,autovacuum = off.每当我单击已更改的表时,会立即显示提示.
假设我正在用Java创建一个基于Web的系统,如何检测表是否已过时,以便我可以在pgAdmin中显示提示?
由于我的应用程序的性质,这里有一些我必须遵循的规则:
我想知道pg_stats和pg_statistic中某个表的统计信息是否是最新的.
我无法在postgresql.conf中设置autovacuum标志.(换句话说,autovacuum标志可以打开或关闭.我无法控制它.我需要判断统计数据是否是最新的autovacuum标志是打开还是关闭.)
我无法每次都进行真空/分析以使其保持最新状态.
当用户选择一个表时,我需要在pg_stats和pg_statistic中没有反映此表的任何更新(例如drop,insert和update)时显示表已过时的提示.
通过分析pg_catalog.pg_stat_all_tables中的时间戳,似乎不可行.当然,如果以前没有分析过某个表,我可以检查它是否在last_analyze中有一个时间戳,以确定该表是否是最新的.但是,使用此方法,当已经有时间戳时,我无法检测表是否是最新的.换句话说,无论我向表中添加多少行,pg_stat_all_tables中的last_analyze时间戳总是用于第一次分析(假设autovacuum标志已关闭).因此,我只能首次显示"正在运行VACUUM"提示.
通过将last_analyze时间戳与当前时间戳进行比较,这也是不可行的.几天内可能没有对表格进行任何更新.一小时内可能会有大量的更新.
鉴于这种情况,我怎样才能始终判断表的统计信息是否是最新的?
来自关于完全真空的 PostgreSQL 10.4 手册:
请注意,它们还会临时使用大约等于表大小的额外磁盘空间,因为在新表和索引完成之前无法释放表和索引的旧副本
我在很多不同的地方读过这篇文章,并以各种方式表达过。一些表明所需的空间最多等于真空表的大小。暗示它可能只需要足够的空间来存储生成的真空表,即大小在 [0-size_of_original_table] 范围内,具体取决于表中有多少死行。
我的问题是:对表进行完全真空是否总是需要等于原始表大小的空间,还是取决于表中的活动行数?
我正在使用PostgreSQL 8.4.13数据库.
最近我在一张桌子里有大约8650万条记录.我删除了几乎所有这些 - 只剩下5000条记录.我跑了
reindex
Run Code Online (Sandbox Code Playgroud)
和
vacuum analyze
Run Code Online (Sandbox Code Playgroud)
删除行后.但我仍然看到该表占用了大量的磁盘空间:
jbossql=> SELECT pg_size_pretty(pg_total_relation_size('my_table'));
pg_size_pretty
----------------
7673 MB
Run Code Online (Sandbox Code Playgroud)
此外,剩余行的索引值仍然很高 - 就像在百万范围内一样.我想在吸尘和重新索引之后,剩余行的索引将从1开始.
我阅读了文档,很清楚我对重新索引的理解是不正确的.
但是,我的目的是减少删除操作后的表大小并降低索引值,以便表中的read operations(SELECT)不会花费那么长时间 - 目前我需要大约40秒来从我的内容中检索一条记录表.
谢谢欧文.我已经更正了pg版本号.
vacuum full
Run Code Online (Sandbox Code Playgroud)
为我工作.我在这里有一个跟进问题:
删除大部分大表后重新启动现有行的主键号
我有一个:
VACUUM无法在事务块内运行
Redshift中SQLWorkbenchJ上的错误,但我之前已经提交了所有事务.
根据设计,Core Data不会向其SQLite数据库发出VACUUM SQL命令,如此处所述.我正在创建一个Core Data应用程序,它将在SQLite数据库中存储并稍后删除大型二进制文件(大小为2-10MB).随着时间的推移,这将导致碎片化和大于必要的SQLite数据库.我想在我运行的清理操作期间定期发出VACUUM命令.
vacuum ×10
postgresql ×6
sqlite ×2
analyzer ×1
core-data ×1
database ×1
mysql ×1
psycopg2 ×1
python ×1
sql ×1
statistics ×1
terminology ×1