我有一张桌子占用了我们服务器上接近 90% 的高清空间。我决定删除几列以释放空间。但我需要将空间归还给操作系统。但是,问题是我不确定如果我运行 VACUUM FULL 并且没有足够的可用空间来制作表的副本会发生什么。
我知道不应使用 VACUUM FULL,但我认为这是这种情况下的最佳选择。
任何想法,将不胜感激。
我正在使用 PostgreSQL 9.0.6
在使用 mysqldump 之类的东西之前,如何确定或估计 SQL 转储文件的大小?
我有一个数据库,它有一个350 MB 的数据文件(.mdf) 和一个4.9 GB 的日志文件(.ldf)。恢复模式设置为FULL.
当我尝试缩小日志文件时,它并没有缩小。
我知道缩小数据库不好,也不应该这样做。但我仍然试图缩小日志文件。
当我跑
DBCC SQLPerf(logspace)
Run Code Online (Sandbox Code Playgroud)
我发现日志大小为4932 MB,使用的日志空间为98.76%!
然后我尝试了这个命令
USE <databasename>;
DBCC loginfo;
Run Code Online (Sandbox Code Playgroud)
现在几乎所有的 VLF 都是“状态 2”,这意味着都在使用中。
我尝试进行日志备份,然后缩小日志文件。收缩并没有减小尺寸。
我将恢复模型更改为SIMPLE并再次尝试缩小,但这也无济于事。
我检查了未结交易
DBCC opentran (database);
Run Code Online (Sandbox Code Playgroud)
并发现现在没有交易打开。
是什么阻止我缩小日志文件?我该如何解决这个问题?
在 DB2 中,我有一个包含大型二进制数据的表。现在我清除了整个表并运行了 runstats、reorg、runstats,但是占用的磁盘空间量没有改变。这里可能有什么问题?
该表位于我创建的自己的表空间中,如下所示:
CREATE BUFFERPOOL "MY_BP" SIZE 250 AUTOMATIC PAGESIZE 4096;
CREATE LARGE TABLESPACE MY_TBS IN DATABASE PARTITION GROUP IBMDEFAULTGROUP PAGESIZE 4096 MANAGED BY AUTOMATIC STORAGE EXTENTSIZE 64 PREFETCHSIZE 64 BUFFERPOOL MY_BP OVERHEAD 10.500000 TRANSFERRATE 0.140000 FILE SYSTEM CACHING;
Run Code Online (Sandbox Code Playgroud)
我删除/重组如下:
DELETE FROM MY_TBL
RUNSTATS ON TABLE MY_TBL WITH DISTRIBUTION AND DETAILED INDEXES ALL
REORG TABLE MY_TBL
RUNSTATS ON TABLE MY_TABLE WITH DISTRIBUTION AND DETAILED INDEXES ALL
ALTER TABLESPACE MY_TBS REDUCE
Run Code Online (Sandbox Code Playgroud)
表 MY_TBL 在所有这些之前占用了 2.5GB,在删除/重组之后它只使用了3MB。
FWIW:我正在运行 DB2/NT …
我知道如何检查 Postgres 中索引和表的大小(我使用的是 9.4 版):
SELECT
relname AS objectname,
relkind AS objecttype,
reltuples AS "#entries", pg_size_pretty(relpages::bigint*8*1024) AS size
FROM pg_class
WHERE relpages >= 8
ORDER BY relpages DESC;
Run Code Online (Sandbox Code Playgroud)
但这并没有显示物化视图。如何查看它们占用了多少磁盘空间?
假设我有一个包含用户信息的大表和另一个包含多个位置的表。然后我使用另一个包含 user_id 和 location_id 的表。
为了检索数据,我必须使用 Left Join 查询。与将所有内容放在一张桌子中相比,这不是使整个过程更长的检索时间吗?例如,我可以将位置作为文本放在同一张桌子上。
编辑:这是一个例子。
CREATE TABLE `user` (
`id` int(11) NOT NULL,
`name` varchar(45) DEFAULT NULL,
`gender` enum('M','F') DEFAULT NULL
);
CREATE TABLE `user_location` (
`user_id` int(11) NOT NULL,
`location_id` int(11) NOT NULL
);
CREATE TABLE `location` (
`id` int(11) NOT NULL,
`location` varchar(45),
`parent_id` varchar(45)
);
Run Code Online (Sandbox Code Playgroud)
注意:请假设所有相关字段都在它们之间正确索引。
编辑:我目前有一个大型数据库,用户通过如上所述的连接表检索他们的位置。我被要求优化数据库,因为搜索结果很慢。我添加了memcache它并且它有了显着的改进,但现在我只是想知道左连接。
例如,当前查询是这样的:
SELECT * FROM users
LEFT JOIN user_location
ON user_location.user_id = user.id
LEFT JOIN location
ON location.id = user_location.location_id;
Run Code Online (Sandbox Code Playgroud)
这只是为了获取位置。它们还有其他几个通过联结检索的字段,并且都需要它们来查看用户的个人资料。我们的电话号码、地址、密码、出生日期和许多其他信息都在不同的表格中。
为了让我为用户配置文件创建一个页面,我必须向服务器发送一个大型查询。现在在第一次被缓存之后就可以了。但我只是想知道为什么有人会像这样构建他们的数据库?
我正在尝试查找所有 MySQL Workbench 数据库都在使用的硬盘上的总大小。
有谁知道一种简单的方法来解决这个问题?
如果不出意外,默认位置 mysql/workbench 用于在 Windows 机器上保存原始数据?
提前致谢!昆蒂斯
我的问题有两个部分。
我最近从 MSSQL 迁移到 Postgres,我们在 MSSQL 世界中创建数据库时所做的一件事是指定数据库和事务日志的初始大小。这减少了碎片并提高了性能,特别是如果事先知道数据库的“正常”大小。
我的数据库的性能随着大小的增长而下降。例如,我处理的工作负载通常需要 10 分钟。随着数据库的增长,这个时间会增加。执行 VACUUM、VACUUM FULL 和 VACUUM FULL ANALYZE 似乎不能解决问题。解决性能问题的是停止数据库,对驱动器进行碎片整理,然后进行 VACUUM FULL ANALYZE 使我的测试性能恢复到原来的 10 分钟。这让我怀疑是碎片化是导致我痛苦的原因。
我在 Postgres 中找不到任何关于保留表空间/数据库空间的参考。要么我使用了错误的术语,因此一无所获,要么在 Postgres 中有一种不同的方法来减轻文件系统碎片。
任何指针?
解决方案
提供的答案有助于确认我开始怀疑的内容。PostgreSQL 将数据库存储在多个文件中,这使得数据库可以增长而不必担心碎片化。默认行为是将这些文件与表数据一起打包,这对很少更改的表有好处,但对经常更新的表不利。
PostgreSQL 利用MVCC提供对表数据的并发访问。在此方案下,每次更新都会创建已更新行的新版本(这可能是通过时间戳或版本号,谁知道?)。旧数据不会立即删除,而是标记为删除。执行 VACUUM 操作时会发生实际删除。
这与填充因子有什么关系?表默认填充因子 100 完全填充表页,这反过来意味着表页内没有空间来保存更新的行,即更新的行将放置在与原始行不同的表页中。正如我的经验所示,这对性能不利。由于我的汇总表更新非常频繁(高达 1500 行/秒),我选择将填充因子设置为 20,即表的 20% 用于插入行数据,80% 用于更新数据。虽然这可能看起来过多,但为更新行保留的大量空间意味着更新行与原始行保持在同一页内,并且在 autovacuum 守护程序运行以删除过时行时表页未满。
为了“修复”我的数据库,我执行了以下操作。
ALTER TABLE "my_summary_table" SET (fillfactor = 20);重新运行我的测试,即使数据库达到我需要的数百万行,我也没有发现性能下降。
TL;DR …
我有一个 SQL Server 2008 R2 数据库正在被几个部署的程序使用。
问题:有没有一种简单的方法来显示每个表消耗多少空间,对于数据库中的所有表,并区分逻辑空间和磁盘空间?
如果我使用 SSMS (Management Studio),则为数据库显示的存储属性读取 167 MB,其中 3 MB“可用”(大小合适,但我担心 3 MB 可用 - 这是一个需要关注的限制吗? ,假设我知道我有足够的磁盘空间?)
我可以钻进每张桌子,但这需要永远做。
我知道我可以编写自己的查询并进行测试,但我想知道是否已经有一种简单的(内置的?)方法可以做到这一点。
我们的主数据库的大小已经减少了大约 8 GB。这反映在备份以及我们查看可用空间和可用空间时。
一切似乎都在工作,我们找不到任何数据丢失的迹象,但我们以前从未见过这种情况。我们有点担心可能会发生一些不愉快的事情。
谁能告诉我们 8 GB 的数据是如何消失的?如果这是一件正常的事情,我们想了解它是如何发生的,因为能够将数据库备份的大小减半实际上有点有用。
我们在 Windows Server 2019 上运行 SQL Server Enterprise 版本 14.0.3391.2
我们的主数据库每天午夜后备份。备份目标是本地磁盘。每次备份运行时,都会为每个数据库创建一个新文件。我们的恢复模式很简单。备份不会被压缩。至少在过去几年中,每个备份大约为 15 GB。自 6 月 11 日以来,文件大小已缩减至略高于 7 GB。
做一些研究,DBA StackExchange 上的一个线程与不小心在单个文件中创建多个备份的人有关。我RESTORE HEADERONLY FROM DISK对 6 月 10 日(15 GB)和 6 月 11 日(7 GB)的备份进行了测试。两者似乎都包含一个备份。我也没有看到任何其他值得注意的差异。
恢复数据库后,我观察到当前和恢复的数据库的总大小约为 30 GB。当前数据库上的可用空间约为 19 GB,而在恢复的数据库上约为 11 GB。8 GB 的差异,就像备份一样。我们的备份未压缩。
我们没有注意到我们的应用程序中缺少任何我们非常依赖的数据。我已经使用 SSDT 来比较当前数据库和恢复数据库中的架构和数据。
使用此数据库的应用程序正在不断开发中,因此在当前数据库中添加了一些列和表以支持新功能,但没有删除。
同样,在当前数据库中也有一些行被编辑或删除,但关联表在恢复的数据库中所占的比例远低于 100 MB,因此即使它们被完全删除,也不会导致大约 8 GB 的数据消失。
我们有一个人来开发应用程序。数据库管理由那个人和我共享。我们都不相信我们做了任何会导致这种变化的事情。
我们使用数据库的方式没有任何重大变化,如果有的话,备份应该变得更大。
我们是一家小公司,不太可能有人进行过数据清理。这也应该在 SSDT 的数据比较中显示出来。
我在日志文件中没有发现任何表明未经授权访问或备份失败的信息。
我目前正在从 6 月 11 日 (7 GB) 恢复备份,看看这是否能告诉我任何信息,尽管我并不期望从中获得太多见解。
我们不会自动删除备份,而是手动删除,这时我们发现了大小差异。
我不相信任何索引已被删除-有人对最佳检查方法有建议吗?碎片整理似乎是一个完全可能的原因 …
database-size ×10
sql-server ×4
mysql ×3
postgresql ×3
backup ×2
alter-table ×1
db2 ×1
db2-luw ×1
dbcc ×1
delete ×1
disk-space ×1
export ×1
maintenance ×1
mysqldump ×1
shrink ×1
size ×1
ssms ×1
vacuum ×1
windows ×1