CHECK TABLE 语句
ClickHouse 中的 CHECK TABLE
查询用于对特定表或其分区执行验证检查。它通过验证校验和和其他内部数据结构来确保数据的完整性。
特别是,它将实际文件大小与服务器上存储的预期值进行比较。如果文件大小与存储的值不匹配,则表示数据已损坏。例如,这可能是由查询执行期间的系统崩溃引起的。
CHECK TABLE
查询可能会读取表中的所有数据并占用一些资源,使其成为资源密集型操作。在执行此查询之前,请考虑对性能和资源利用率的潜在影响。
语法
查询的基本语法如下
CHECK TABLE table_name [PARTITION partition_expression | PART part_name] [FORMAT format] [SETTINGS check_query_single_value_result = (0|1) [, other_settings]]
table_name
:指定要检查的表的名称。partition_expression
:(可选)如果要检查表的特定分区,可以使用此表达式指定分区。part_name
:(可选)如果要检查表中的特定部分,可以添加字符串文字以指定部件名称。FORMAT format
:(可选)允许您指定结果的输出格式。SETTINGS
:(可选)允许其他设置。check_query_single_value_result
:(可选)此设置允许您在详细结果 (0
) 或摘要结果 (1
) 之间切换。- 也可以应用其他设置。如果您不需要结果的确定性顺序,可以将 max_threads 设置为大于 1 的值以加快查询速度。
查询响应取决于包含 check_query_single_value_result
设置的值。如果 check_query_single_value_result = 1
,则仅返回包含单行的 result
列。如果完整性检查通过,则此行中的值为 1
,如果数据已损坏,则为 0
。
当 check_query_single_value_result = 0
时,查询返回以下列
part_path
:指示数据部件或文件名的路径。is_passed
:如果此部件的检查成功,则返回 1,否则返回 0。message
:与检查相关的任何其他消息,例如错误或成功消息。
CHECK TABLE
查询支持以下表引擎
对使用其他表引擎的表执行会导致 NOT_IMPLEMENTED
异常。
来自 *Log
系列的引擎在失败时不会提供自动数据恢复。使用 CHECK TABLE
查询及时跟踪数据丢失。
示例
默认情况下,CHECK TABLE
查询显示常规表检查状态
CHECK TABLE test_table;
┌─result─┐
│ 1 │
└────────┘
如果您想查看每个单独数据部件的检查状态,您可以使用 check_query_single_value_result
设置。
此外,要检查表的特定分区,可以使用 PARTITION
关键字。
CHECK TABLE t0 PARTITION ID '201003'
FORMAT PrettyCompactMonoBlock
SETTINGS check_query_single_value_result = 0
输出
┌─part_path────┬─is_passed─┬─message─┐
│ 201003_7_7_0 │ 1 │ │
│ 201003_3_3_0 │ 1 │ │
└──────────────┴───────────┴─────────┘
同样,您可以使用 PART
关键字检查表的特定部分。
CHECK TABLE t0 PART '201003_7_7_0'
FORMAT PrettyCompactMonoBlock
SETTINGS check_query_single_value_result = 0
输出
┌─part_path────┬─is_passed─┬─message─┐
│ 201003_7_7_0 │ 1 │ │
└──────────────┴───────────┴─────────┘
请注意,当部件不存在时,查询会返回错误
CHECK TABLE t0 PART '201003_111_222_0'
DB::Exception: No such data part '201003_111_222_0' to check in table 'default.t0'. (NO_SUCH_DATA_PART)
接收到“已损坏”的结果
免责声明:此处描述的过程,包括手动操作或直接从数据目录中删除文件,仅适用于实验或开发环境。不要在生产服务器上尝试此操作,因为它可能导致数据丢失或其他意外后果。
删除现有的校验和文件
rm /var/lib/clickhouse-server/data/default/t0/201003_3_3_0/checksums.txt
CHECK TABLE t0 PARTITION ID '201003'
FORMAT PrettyCompactMonoBlock
SETTINGS check_query_single_value_result = 0
Output:
```text
┌─part_path────┬─is_passed─┬─message──────────────────────────────────┐
│ 201003_7_7_0 │ 1 │ │
│ 201003_3_3_0 │ 1 │ Checksums recounted and written to disk. │
└──────────────┴───────────┴──────────────────────────────────────────┘
如果 checksums.txt 文件丢失,可以恢复它。它将在执行特定分区的 CHECK TABLE 命令期间重新计算和重写,并且状态仍将报告为“is_passed = 1”。
您可以使用 CHECK ALL TABLES
查询一次检查所有现有的 (Replicated)MergeTree
表。
CHECK ALL TABLES
FORMAT PrettyCompactMonoBlock
SETTINGS check_query_single_value_result = 0
┌─database─┬─table────┬─part_path───┬─is_passed─┬─message─┐
│ default │ t2 │ all_1_95_3 │ 1 │ │
│ db1 │ table_01 │ all_39_39_0 │ 1 │ │
│ default │ t1 │ all_39_39_0 │ 1 │ │
│ db1 │ t1 │ all_39_39_0 │ 1 │ │
│ db1 │ table_01 │ all_1_6_1 │ 1 │ │
│ default │ t1 │ all_1_6_1 │ 1 │ │
│ db1 │ t1 │ all_1_6_1 │ 1 │ │
│ db1 │ table_01 │ all_7_38_2 │ 1 │ │
│ db1 │ t1 │ all_7_38_2 │ 1 │ │
│ default │ t1 │ all_7_38_2 │ 1 │ │
└──────────┴──────────┴─────────────┴───────────┴─────────┘
如果数据已损坏
如果表已损坏,您可以将未损坏的数据复制到另一个表。为此:
- 创建一个与损坏表结构相同的新表。为此,执行查询
CREATE TABLE <new_table_name> AS <damaged_table_name>
。 - 将
max_threads
值设置为 1,以在单个线程中处理下一个查询。为此,运行查询SET max_threads = 1
。 - 执行查询
INSERT INTO <new_table_name> SELECT * FROM <damaged_table_name>
。此请求将未损坏的数据从损坏的表复制到另一个表。只会复制损坏部分之前的数据。 - 重启
clickhouse-client
以重置max_threads
值。