大家好
我是数据库新手,我正在尝试理解一些 Cassandra 命令。我想知道以下命令:
- 节点工具紧凑
- 节点工具清理
- 节点工具修复
- 节点工具垃圾收集
我将不胜感激一些简单而清晰的答案,例如 -> nodetool help :它显示了所有命令及其用法。
我要解决的问题是,在我删除(大量数据)之后,存储空间仍然是满的。我将 gc_grace_seconds 更改为 1 天,但仍然没有。因此,如果我现在需要手动清除空间,我应该运行哪些命令以及以什么顺序运行?
谢谢你的时间
我有一个问题,我的客户抱怨记录被删除,即使我看到该表中的所有 id 都是正确的,只是为了确保一切都像它应该的那样,有没有办法在 postgres 中禁用某个表的删除语句?
介绍
我的应用程序从一个集中的来源收集数据,许多不同的用户可以在其中提交有关其组织和员工的数据。以前,当用户数据与事实来源不再相关时,我们只是硬删除用户数据,因为它曾经是可靠的。
但是对客户使用的某些软件进行更改,一切都会变得混乱。现在,他们每月在提交数据时会多次删除所有数据。这是错误的,并且由于设计糟糕。这意味着他们丢失了我们系统中用户的数据,并且必须重新输入其中的一部分。
他们使用的软件很顽固,不会改变行为。我们已经尝试教育用户如何使用它,但他们没有学习。所以现在最后一个选项是软删除一段时间内的数据。
看过网络上的多个 Stack Overflow 帖子和博客后,我真的不喜欢任何选项,IE。在需要软删除的表中添加一列。我开始寻找是因为这也是我的第一直觉,但我并不真正喜欢它及其含义。
我想知道你是否可以就不同的想法给我一些反馈。我没有维护软删除的经验,我不知道我的想法是否很糟糕。
有一个用户,他们的唯一标识符在多个组织中是相同的。每个用户隶属于一个组织,他们有一些用户信息,如姓名、头衔等。在我们的系统中,他们有一个状态行,因为无论他们选择连接哪个组织,在我们的应用程序中都是相同的。
因此,如果我按照传统方式添加用于软删除的列,我将不得不为每个包含用户数据的唯一表添加一个,因为它们与某个组织的从属关系可能会被删除,但作为用户,它们仍然存在我们的系统来自其他地方。
但是,为了解决所有这些额外的列,我的代码的实质内容似乎很麻烦,而且需要进行大量更改。
主意
在我看来,如果我添加一个包含以下内容的单独表格会更简单:
然后每当我的应用程序请求数据时,api 都会检查新表;“这个人是不是被本组织软删除了?” 如果为真,它们只会阻止请求,直到它们在需要时被恢复,或者它们将一直被删除,直到它们在软删除发生后的 x 小时内被硬删除。
不必到处更改许多查询和逻辑。
附加信息
该 API 使用 EFCore 作为 ORM 来连接到数据库,以防它有助于解决有关其功能集的任何其他智能修复。我曾考虑过创建自定义保存更改逻辑,但除了再次向所有表中添加一列之外,我想不出一个好主意。
如果您需要更多信息,请告诉我。
更新
JD 告诉我行级安全性,这让我环顾四周。它似乎非常有用,它让我对我可以搜索的内容有了更多的了解。
所以我遇到了 EFCore 的全局查询过滤器,这似乎很有希望。它允许上下文对所有查询进行过滤,当您实际上需要忽略此全局过滤器时,您可以简单地逐个查询地执行此操作。
如果您需要为基于连接用户的全局过滤器使用某些东西,它允许依赖注入。我根据这些新信息创建了一个答案
事实证明,我真正想要的是停用该行,直到最终激活或硬删除而不是软删除。我不知道表达自己的正确方式。
我希望从包含 8.89 亿行数据的表中删除旧数据。
我有一个脚本,但我正试图使其更健壮,因为准确地说,删除了大约 4.18 亿行数据。
我在 Postgres 9.6 中运行,带有表格和 FK 约束
Column | Type | Collation | Nullable |
Default
--------------------------+--------------------------+-----------+----------+---
------------------------------------
game_id | integer | | not null | ne
xtval('game_game_id_seq'::regclass)
game_id | integer | | not null |
session_id | integer | | |
game_created_on | timestamp with time zone | | not null |
currency_code | character(3) | | not null |
game_cash_staked | numeric(12,2) | | |
game_cash_won | numeric(12,2) | | |
game_bonus_staked | numeric(12,2) | | |
game_bonus_won | numeric(12,2) | | |
game_created_by_id | integer | | not null |
game_remote_ref | character varying(50) | | |
game_description | text | | |
game_batch_id | integer | | |
game_rejection_code_id | integer | | |
game_rejection_message | character varying(255) | | |
game_transfer_remote_ref | character varying(128) | | |
Indexes:
"game_pkey" PRIMARY KEY, btree (game_id)
"idx_game_created_on_rejection_code" btree (game_created_on) WHERE game_rejection_code_id IS NULL
"idx_game_game_created_on" btree (game_created_on)
"idx_game_session_id" btree (session_id)
"game_idx_01" btree (game_remote_ref)
"game_idx_game_id" btree (game_id)
Foreign-key constraints:
"ref_game_to_currency" FOREIGN KEY (currency_code) REFERENCES currency(currency_code)
"ref_game_to_game" FOREIGN KEY (game_id) REFERENCES game(game_id)
"ref_game_to_game_rejection_code" FOREIGN KEY (game_rejection_code_id) REFERENCES game_rejection_code(game_re
jection_code_id)
Scipt 已经使用:
begin;
CREATE TABLE gamearchived AS
SELECT t.*
FROM game t
where t.game_created_on < NOW() - interval '1 year'; -- this grabs stuff Older than 1 year
delete from game t
where t.game_id in (select gamearchived.game_id from gamearchived);
select count (*) from gamearchived
COMMIT;
我想知道这是否是从主表中删除旧数据或分批执行的最安全方法。另外,我将从中删除数据的当前表具有索引和外键约束,最好在删除之前先删除索引,然后在完成后将它们添加回来。删除的数据量约为 4.5 亿行。
需要保留旧数据,以便可以访问。非常感谢任何建议。
DELETE 之后的别名是什么意思?
例如我有一个查询:
DELETE p1
FROM Person p1, Person p2
WHERE p1.Email = p2.Email AND p2.Id < p1.Id
这是什么意思DELETE p1
?
我理解如下。Person
首先,我们找到表与自身的笛卡尔积。然后我们删除Email
两个表(p1
和p2
)中的所有行不同。Id
然后我们删除fromp2
大于或等于Id
from的所有行p1
。现在我们留下了一些行。我们从左侧行的部分中选择所有Id
s并从初始表中删除所有条目,该表包含在所选择的 s 中。p1
Person
Id
Id
我的理解正确吗?
如果正确,则DELETE p1
意味着删除行的结果部分中Person
where Id
is 中的所有条目。p1
使用 PostgreSQL 11。考虑一个像这样的表
CREATE TABLE "logs"
(
"id" INTEGER NOT NULL,
"userId" INTEGER NOT NULL,
"timestamp" TIMESTAMP NOT NULL,
CONSTRAINT "PK_8d33b9f1a33b412e4865d1e5465" PRIMARY KEY ("id")
)
现在,要求是每个userId
. 如果有更多数据进入,则必须删除最旧的日志。如果在短时间内存储了 101 行,那么这并不是世界末日。如果多余的行在几秒钟的延迟后被删除,那很好。
我无法创建数据库TRIGGER
。所以,我需要编写一个在应用层的日志创建事件上触发的查询。
纯 SQL 优于 plpgsql。
这是我想出的解决方案:
WITH "userLogs" AS (SELECT id, timestamp FROM "logs"
WHERE "userId" = $1
),
"countLogs" AS (SELECT count(id) FROM "userLogs")
DELETE FROM "logs" WHERE id = ANY
(
SELECT id FROM "userLogs"
ORDER BY "timestamp" ASC
LIMIT GREATEST( (SELECT count FROM "countLogs") - 100, 0)
);
想法是:始终运行 a并根据子查询DELETE
实际是否必须删除某些内容来做出决定。LIMIT
如果有超过 100 条日志,子查询将返回最旧的 id 以丢弃。否则,LIMIT
将为 0,子查询不会返回任何内容,也不会删除任何内容。
我现在的问题是:
DELETE
对每个运行查询是否敏感INSERT
- 即使它没有删除任何内容?LOCK
. 在我的测试中,当并行运行 s 时,我无法产生任何意外行为INSERT
,但是是否存在我需要 a 的边缘情况LOCK
?编辑:很难预测INSERT
将针对该表运行多少次。如果一切顺利(业务方面),总共可能每天几千次 - 每个用户每天几十次。
编辑2:timestamp
每个用户的值不一定是唯一的:可以有多个具有相同timestamp
和相同的日志条目userId
。预计该表将获得更多包含实际发生情况的列。
这两个sql都可以执行,第一个删除所有,第二个是逻辑对。
第一个
with d0 as (
delete from seller_create_request
where seller_id in
(
select id
from seller
where email in
('[email protected]')
)
returning seller_create_request.seller_id
)
delete from seller
where id in (select id from d0)
returning seller.id;
第二个
with d0 as (
delete from seller_create_request
where seller_id in
(
select id
from seller
where email in
('[email protected]')
)
returning seller_create_request.seller_id
)
delete from seller
where id in (select d0.seller_id from d0)
returning seller.id
;
第一个select id from d0
似乎等于select id from seller
。我的初衷是select seller_id from d0
拼写错误。它不会导致
column id does not exist
因为它从 d0 开始。
所以我很奇怪为什么 psql 有这种行为,我从简单的理解中遗漏了什么?
四天前,一个用户在一个有 400,000,000 行的表上运行了下面的命令。它仍在运行,并且日志文件的大小正在增加。
delete from [table-name]
该表确实有一个未启用检查的外键约束,我知道另一个表中不存在任何行。
数据库在启用“Is Read Committed Snapshot On”的情况下运行并处于简单恢复模式。
在这运行了几个小时后,我发出了一个 kill session 命令,因为我们的日志文件的磁盘空间不足。我添加了另一个日志文件以允许系统继续运行。
日志文件继续增长,当我使用 statusonly 运行 kill session 时,它返回此消息:
SPID 123: transaction rollback in progress. Estimated rollback completion: 0%. Estimated time remaining: 0 seconds.
我不知道如何处理这个查询以使其回滚,也只是了解发生了什么,有人能建议我看什么吗?
所以我前几天“修复”了一个问题,这导致了新问题的滚雪球(想象一下)。我有一大组表用作流向其他系统的许多导入/导出过程的临时表。每个表都标有“TO_xxxx”。我想清除每个“TO_”表中的所有记录。有没有办法构造一个删除语句来清除“TO_”表中的所有记录?
是不是很简单
Delete from TO_%
还是还有更多?总共大约有 80 个“TO_”表,所以我想在手动完成所有内容之前先在这里发布。如果您能提供帮助,我将不胜感激。谢谢。
系统是 SQL Server 2016。